From a7d85be9a88cc7300c3e3b29ac26415ac92a60de Mon Sep 17 00:00:00 2001 From: "Michael R. Crusoe" Date: Sat, 23 Jan 2021 19:15:11 +0000 Subject: [PATCH] Import solvespace_3.0.rc2+repack1.orig.tar.xz [dgit import orig solvespace_3.0.rc2+repack1.orig.tar.xz] --- .clang-format | 41 + CHANGELOG.md | 275 + CMakeLists.txt | 397 + CONTRIBUTING.md | 291 + COPYING.txt | 675 + README.md | 257 + THIRD_PARTIES.txt | 50 + bench/CMakeLists.txt | 17 + bench/harness.cpp | 78 + cmake/AddVendoredSubdirectory.cmake | 10 + cmake/DisableWarnings.cmake | 15 + cmake/FindSpaceWare.cmake | 28 + cmake/FindVendoredPackage.cmake | 56 + cmake/GetGitCommitHash.cmake | 35 + cmake/MacOSXBundleInfo.plist.in | 49 + cmake/Toolchain-mingw32.cmake | 15 + cmake/Toolchain-mingw64.cmake | 15 + cmake/c_flag_overrides.cmake | 6 + cmake/cxx_flag_overrides.cmake | 6 + developer_docs/Solver_Transforms.txt | 154 + exposed/CDemo.c | 269 + exposed/CMakeLists.txt | 8 + exposed/DOC.txt | 467 + exposed/VbDemo.vb | 1252 + extlib/libdxfrw/CMakeLists.txt | 75 + extlib/libdxfrw/drw_base.h | 493 + extlib/libdxfrw/drw_classes.cpp | 115 + extlib/libdxfrw/drw_classes.h | 58 + extlib/libdxfrw/drw_entities.cpp | 3073 +++ extlib/libdxfrw/drw_entities.h | 1572 ++ extlib/libdxfrw/drw_header.cpp | 2480 ++ extlib/libdxfrw/drw_header.h | 107 + extlib/libdxfrw/drw_interface.h | 191 + extlib/libdxfrw/drw_objects.cpp | 1235 + extlib/libdxfrw/drw_objects.h | 772 + extlib/libdxfrw/intern/drw_cptable932.h | 7812 ++++++ extlib/libdxfrw/intern/drw_cptable936.h | 21943 ++++++++++++++++ extlib/libdxfrw/intern/drw_cptable949.h | 17199 ++++++++++++ extlib/libdxfrw/intern/drw_cptable950.h | 13654 ++++++++++ extlib/libdxfrw/intern/drw_cptables.h | 1330 + extlib/libdxfrw/intern/drw_dbg.cpp | 164 + extlib/libdxfrw/intern/drw_dbg.h | 61 + extlib/libdxfrw/intern/drw_textcodec.cpp | 536 + extlib/libdxfrw/intern/drw_textcodec.h | 91 + extlib/libdxfrw/intern/dwgbuffer.cpp | 923 + extlib/libdxfrw/intern/dwgbuffer.h | 155 + extlib/libdxfrw/intern/dwgreader.cpp | 1294 + extlib/libdxfrw/intern/dwgreader.h | 203 + extlib/libdxfrw/intern/dwgreader15.cpp | 198 + extlib/libdxfrw/intern/dwgreader15.h | 47 + extlib/libdxfrw/intern/dwgreader18.cpp | 594 + extlib/libdxfrw/intern/dwgreader18.h | 99 + extlib/libdxfrw/intern/dwgreader21.cpp | 487 + extlib/libdxfrw/intern/dwgreader21.h | 65 + extlib/libdxfrw/intern/dwgreader24.cpp | 43 + extlib/libdxfrw/intern/dwgreader24.h | 56 + extlib/libdxfrw/intern/dwgreader27.cpp | 43 + extlib/libdxfrw/intern/dwgreader27.h | 55 + extlib/libdxfrw/intern/dwgutil.cpp | 694 + extlib/libdxfrw/intern/dwgutil.h | 91 + extlib/libdxfrw/intern/dxfreader.cpp | 263 + extlib/libdxfrw/intern/dxfreader.h | 99 + extlib/libdxfrw/intern/dxfwriter.cpp | 269 + extlib/libdxfrw/intern/dxfwriter.h | 64 + extlib/libdxfrw/intern/rscodec.cpp | 401 + extlib/libdxfrw/intern/rscodec.h | 69 + extlib/libdxfrw/libdwgr.cpp | 237 + extlib/libdxfrw/libdwgr.h | 50 + extlib/libdxfrw/libdxfrw.cpp | 2773 ++ extlib/libdxfrw/libdxfrw.h | 148 + extlib/mimalloc/.gitattributes | 10 + extlib/mimalloc/.gitignore | 8 + extlib/mimalloc/CMakeLists.txt | 361 + extlib/mimalloc/LICENSE | 21 + extlib/mimalloc/azure-pipelines.yml | 131 + .../cmake/mimalloc-config-version.cmake | 16 + extlib/mimalloc/cmake/mimalloc-config.cmake | 2 + .../ide/vs2017/mimalloc-override-test.vcxproj | 190 + .../mimalloc-override-test.vcxproj.filters | 22 + .../ide/vs2017/mimalloc-override.vcxproj | 254 + .../vs2017/mimalloc-override.vcxproj.filters | 80 + .../ide/vs2017/mimalloc-test-stress.vcxproj | 159 + .../mimalloc-test-stress.vcxproj.filters | 22 + .../mimalloc/ide/vs2017/mimalloc-test.vcxproj | 158 + .../ide/vs2017/mimalloc-test.vcxproj.filters | 22 + extlib/mimalloc/ide/vs2017/mimalloc.sln | 71 + extlib/mimalloc/ide/vs2017/mimalloc.vcxproj | 260 + .../ide/vs2017/mimalloc.vcxproj.filters | 83 + .../ide/vs2019/mimalloc-override-test.vcxproj | 190 + .../ide/vs2019/mimalloc-override.vcxproj | 257 + .../vs2019/mimalloc-override.vcxproj.filters | 81 + .../ide/vs2019/mimalloc-test-api.vcxproj | 155 + .../ide/vs2019/mimalloc-test-stress.vcxproj | 159 + .../mimalloc/ide/vs2019/mimalloc-test.vcxproj | 158 + extlib/mimalloc/ide/vs2019/mimalloc.sln | 81 + extlib/mimalloc/ide/vs2019/mimalloc.vcxproj | 253 + .../ide/vs2019/mimalloc.vcxproj.filters | 84 + extlib/mimalloc/include/mimalloc-atomic.h | 294 + extlib/mimalloc/include/mimalloc-internal.h | 748 + extlib/mimalloc/include/mimalloc-new-delete.h | 52 + extlib/mimalloc/include/mimalloc-override.h | 66 + extlib/mimalloc/include/mimalloc-types.h | 480 + extlib/mimalloc/include/mimalloc.h | 426 + extlib/mimalloc/readme.md | 583 + extlib/mimalloc/src/alloc-aligned.c | 205 + extlib/mimalloc/src/alloc-override-osx.c | 260 + extlib/mimalloc/src/alloc-override.c | 214 + extlib/mimalloc/src/alloc-posix.c | 155 + extlib/mimalloc/src/alloc.c | 857 + extlib/mimalloc/src/arena.c | 357 + extlib/mimalloc/src/bitmap.inc.c | 240 + extlib/mimalloc/src/heap.c | 555 + extlib/mimalloc/src/init.c | 572 + extlib/mimalloc/src/options.c | 518 + extlib/mimalloc/src/os.c | 1176 + extlib/mimalloc/src/page-queue.c | 368 + extlib/mimalloc/src/page.c | 847 + extlib/mimalloc/src/random.c | 328 + extlib/mimalloc/src/region.c | 498 + extlib/mimalloc/src/segment.c | 1343 + extlib/mimalloc/src/static.c | 38 + extlib/mimalloc/src/stats.c | 532 + extlib/mimalloc/test/CMakeLists.txt | 46 + extlib/mimalloc/test/main-override-static.c | 123 + extlib/mimalloc/test/main-override.c | 30 + extlib/mimalloc/test/main-override.cpp | 209 + extlib/mimalloc/test/main.c | 46 + extlib/mimalloc/test/readme.md | 16 + extlib/mimalloc/test/test-api.c | 249 + extlib/mimalloc/test/test-stress.c | 329 + include/slvs.h | 404 + pkg/flatpak/.gitignore | 4 + pkg/flatpak/build.sh | 4 + pkg/flatpak/com.solvespace.SolveSpace.json | 141 + pkg/snap/.gitignore | 3 + pkg/snap/build.sh | 12 + pkg/snap/snap/snapcraft.yaml | 80 + res/CMakeLists.txt | 296 + res/banner.txt | 1 + res/cocoa/AppIcon.iconset/icon_128x128.png | Bin 0 -> 891 bytes res/cocoa/AppIcon.iconset/icon_128x128@2x.png | Bin 0 -> 1303 bytes res/cocoa/AppIcon.iconset/icon_16x16.png | Bin 0 -> 586 bytes res/cocoa/AppIcon.iconset/icon_16x16@2x.png | Bin 0 -> 626 bytes res/cocoa/AppIcon.iconset/icon_256x256.png | Bin 0 -> 1303 bytes res/cocoa/AppIcon.iconset/icon_256x256@2x.png | Bin 0 -> 2506 bytes res/cocoa/AppIcon.iconset/icon_32x32.png | Bin 0 -> 626 bytes res/cocoa/AppIcon.iconset/icon_32x32@2x.png | Bin 0 -> 746 bytes res/cocoa/AppIcon.iconset/icon_512x512.png | Bin 0 -> 2506 bytes res/cocoa/AppIcon.iconset/icon_512x512@2x.png | Bin 0 -> 6490 bytes res/cocoa/MainMenu.xib | 65 + res/cocoa/SaveFormatAccessory.xib | 51 + res/fonts/BitstreamVeraSans-Roman-builtin.ttf | Bin 0 -> 54524 bytes res/fonts/private/0-check-false.png | Bin 0 -> 218 bytes res/fonts/private/1-check-true.png | Bin 0 -> 243 bytes res/fonts/private/2-radio-false.png | Bin 0 -> 228 bytes res/fonts/private/3-radio-true.png | Bin 0 -> 231 bytes res/fonts/private/4-stipple-dot.png | Bin 0 -> 936 bytes res/fonts/private/5-stipple-dash-long.png | Bin 0 -> 932 bytes res/fonts/private/6-stipple-dash.png | Bin 0 -> 932 bytes res/fonts/private/7-stipple-zigzag.png | Bin 0 -> 950 bytes res/fonts/unicode.lff.gz | Bin 0 -> 475974 bytes res/freedesktop/solvespace-16x16.png | Bin 0 -> 336 bytes res/freedesktop/solvespace-16x16.xpm | 27 + res/freedesktop/solvespace-24x24.png | Bin 0 -> 338 bytes res/freedesktop/solvespace-24x24.xpm | 35 + res/freedesktop/solvespace-32x32.png | Bin 0 -> 348 bytes res/freedesktop/solvespace-32x32.xpm | 43 + res/freedesktop/solvespace-48x48.png | Bin 0 -> 352 bytes res/freedesktop/solvespace-48x48.xpm | 59 + res/freedesktop/solvespace-flatpak-mime.xml | 8 + res/freedesktop/solvespace-flatpak.desktop.in | 10 + res/freedesktop/solvespace-mime.xml | 8 + res/freedesktop/solvespace-scalable.svg | 12 + res/freedesktop/solvespace-snap.desktop | 10 + res/freedesktop/solvespace.desktop.in | 10 + res/icons/graphics-window/angle.png | Bin 0 -> 819 bytes res/icons/graphics-window/arc.png | Bin 0 -> 686 bytes res/icons/graphics-window/assemble.png | Bin 0 -> 454 bytes res/icons/graphics-window/bezier.png | Bin 0 -> 710 bytes res/icons/graphics-window/circle.png | Bin 0 -> 801 bytes res/icons/graphics-window/construction.png | Bin 0 -> 739 bytes res/icons/graphics-window/equal.png | Bin 0 -> 920 bytes res/icons/graphics-window/extrude.png | Bin 0 -> 620 bytes res/icons/graphics-window/helix.png | Bin 0 -> 664 bytes res/icons/graphics-window/horiz.png | Bin 0 -> 418 bytes res/icons/graphics-window/image.png | Bin 0 -> 1025 bytes res/icons/graphics-window/in3d.png | Bin 0 -> 512 bytes res/icons/graphics-window/lathe.png | Bin 0 -> 401 bytes res/icons/graphics-window/length.png | Bin 0 -> 480 bytes res/icons/graphics-window/line.png | Bin 0 -> 511 bytes res/icons/graphics-window/ontoworkplane.png | Bin 0 -> 412 bytes res/icons/graphics-window/other-supp.png | Bin 0 -> 916 bytes res/icons/graphics-window/parallel.png | Bin 0 -> 531 bytes res/icons/graphics-window/perpendicular.png | Bin 0 -> 427 bytes res/icons/graphics-window/point.png | Bin 0 -> 394 bytes res/icons/graphics-window/pointonx.png | Bin 0 -> 596 bytes res/icons/graphics-window/rectangle.png | Bin 0 -> 418 bytes res/icons/graphics-window/ref.png | Bin 0 -> 413 bytes res/icons/graphics-window/revolve.png | Bin 0 -> 680 bytes .../graphics-window/same-orientation.png | Bin 0 -> 673 bytes res/icons/graphics-window/sketch-in-3d.png | Bin 0 -> 597 bytes res/icons/graphics-window/sketch-in-plane.png | Bin 0 -> 507 bytes res/icons/graphics-window/step-rotate.png | Bin 0 -> 871 bytes res/icons/graphics-window/step-translate.png | Bin 0 -> 411 bytes res/icons/graphics-window/symmetric.png | Bin 0 -> 515 bytes res/icons/graphics-window/tangent-arc.png | Bin 0 -> 666 bytes res/icons/graphics-window/text.png | Bin 0 -> 784 bytes res/icons/graphics-window/trim.png | Bin 0 -> 575 bytes res/icons/graphics-window/vert.png | Bin 0 -> 515 bytes res/icons/text-window/constraint.png | Bin 0 -> 557 bytes res/icons/text-window/construction.png | Bin 0 -> 739 bytes res/icons/text-window/edges.png | Bin 0 -> 703 bytes res/icons/text-window/faces.png | Bin 0 -> 683 bytes res/icons/text-window/mesh.png | Bin 0 -> 1169 bytes res/icons/text-window/normal.png | Bin 0 -> 639 bytes res/icons/text-window/occluded-invisible.png | Bin 0 -> 345 bytes res/icons/text-window/occluded-stippled.png | Bin 0 -> 539 bytes res/icons/text-window/occluded-visible.png | Bin 0 -> 365 bytes res/icons/text-window/outlines.png | Bin 0 -> 733 bytes res/icons/text-window/point.png | Bin 0 -> 394 bytes res/icons/text-window/shaded.png | Bin 0 -> 403 bytes res/icons/text-window/workplane.png | Bin 0 -> 462 bytes res/locales.txt | 8 + res/locales/de_DE.po | 2324 ++ res/locales/en_US.po | 2171 ++ res/locales/fr_FR.po | 2262 ++ res/locales/ru_RU.po | 2247 ++ res/locales/uk_UA.po | 1934 ++ res/locales/zh_CN.po | 2019 ++ res/messages.pot | 1887 ++ res/shaders/edge.frag | 35 + res/shaders/edge.vert | 41 + res/shaders/imesh.frag | 12 + res/shaders/imesh.vert | 13 + res/shaders/imesh_point.frag | 15 + res/shaders/imesh_point.vert | 33 + res/shaders/imesh_tex.frag | 15 + res/shaders/imesh_tex.vert | 17 + res/shaders/imesh_texa.frag | 13 + res/shaders/mesh.frag | 26 + res/shaders/mesh.vert | 21 + res/shaders/mesh_fill.frag | 12 + res/shaders/mesh_fill.vert | 13 + res/shaders/outline.vert | 60 + res/threejs/SolveSpaceControls.js | 536 + res/threejs/hammer-2.0.8.js.gz | Bin 0 -> 17503 bytes res/win32/icon.ico | Bin 0 -> 29926 bytes res/win32/manifest.xml | 28 + res/win32/versioninfo.rc.in | 29 + src/CMakeLists.txt | 417 + src/bsp.cpp | 729 + src/clipboard.cpp | 519 + src/config.h.in | 18 + src/confscreen.cpp | 578 + src/constraint.cpp | 791 + src/constrainteq.cpp | 843 + src/describescreen.cpp | 537 + src/draw.cpp | 938 + src/drawconstraint.cpp | 1249 + src/drawentity.cpp | 791 + src/dsc.h | 722 + src/entity.cpp | 984 + src/export.cpp | 1264 + src/exportstep.cpp | 411 + src/exportvector.cpp | 1347 + src/expr.cpp | 921 + src/expr.h | 140 + src/file.cpp | 1007 + src/generate.cpp | 568 + src/graphicswin.cpp | 1384 + src/group.cpp | 1174 + src/groupmesh.cpp | 799 + src/importdxf.cpp | 1199 + src/importidf.cpp | 521 + src/lib.cpp | 254 + src/mesh.cpp | 1217 + src/modify.cpp | 745 + src/mouse.cpp | 1586 ++ src/platform/entrycli.cpp | 387 + src/platform/entrygui.cpp | 42 + src/platform/gui.cpp | 134 + src/platform/gui.h | 390 + src/platform/guigtk.cpp | 1497 ++ src/platform/guimac.mm | 1497 ++ src/platform/guinone.cpp | 145 + src/platform/guiwin.cpp | 1712 ++ src/platform/platform.cpp | 715 + src/platform/platform.h | 85 + src/polygon.cpp | 921 + src/polygon.h | 420 + src/polyline.cpp | 243 + src/render/gl3shader.cpp | 1071 + src/render/gl3shader.h | 266 + src/render/render.cpp | 459 + src/render/render.h | 385 + src/render/render2d.cpp | 413 + src/render/rendercairo.cpp | 173 + src/render/rendergl1.cpp | 852 + src/render/rendergl3.cpp | 1102 + src/request.cpp | 247 + src/resource.cpp | 1583 ++ src/resource.h | 112 + src/sketch.h | 987 + src/solvespace.cpp | 1118 + src/solvespace.h | 825 + src/srf/boolean.cpp | 1046 + src/srf/curve.cpp | 880 + src/srf/merge.cpp | 128 + src/srf/ratpoly.cpp | 701 + src/srf/raycast.cpp | 615 + src/srf/surface.cpp | 1102 + src/srf/surface.h | 439 + src/srf/surfinter.cpp | 597 + src/srf/triangulate.cpp | 734 + src/style.cpp | 872 + src/system.cpp | 579 + src/textscreens.cpp | 873 + src/textwin.cpp | 1168 + src/toolbar.cpp | 241 + src/ttf.cpp | 431 + src/ttf.h | 50 + src/ui.h | 842 + src/undoredo.cpp | 154 + src/util.cpp | 1072 + src/view.cpp | 122 + test/CMakeLists.txt | 138 + test/Gentium-R.ttf | Bin 0 -> 362644 bytes test/analysis/contour_area/normal.png | Bin 0 -> 4818 bytes test/analysis/contour_area/normal.slvs | 512 + test/analysis/contour_area/test.cpp | 7 + test/commit.sh | 9 + test/constraint/angle/free_in_3d.png | Bin 0 -> 4763 bytes test/constraint/angle/free_in_3d.slvs | 355 + test/constraint/angle/free_in_3d_v20.slvs | 355 + test/constraint/angle/free_in_3d_v22.slvs | 355 + test/constraint/angle/normal.png | Bin 0 -> 4882 bytes test/constraint/angle/normal.slvs | 352 + test/constraint/angle/normal_v20.slvs | 352 + test/constraint/angle/normal_v22.slvs | 352 + test/constraint/angle/reference.png | Bin 0 -> 5239 bytes test/constraint/angle/reference.slvs | 366 + .../constraint/angle/reference_free_in_3d.png | Bin 0 -> 4857 bytes .../angle/reference_free_in_3d.slvs | 355 + .../angle/reference_free_in_3d_v20.slvs | 355 + .../angle/reference_free_in_3d_v22.slvs | 355 + test/constraint/angle/reference_v20.slvs | 366 + test/constraint/angle/reference_v22.slvs | 366 + test/constraint/angle/skew.png | Bin 0 -> 4867 bytes test/constraint/angle/skew.slvs | 340 + test/constraint/angle/skew_v22.slvs | 340 + test/constraint/angle/test.cpp | 70 + test/constraint/arc_line_tangent/normal.png | Bin 0 -> 5100 bytes test/constraint/arc_line_tangent/normal.slvs | 450 + .../arc_line_tangent/normal_v20.slvs | 450 + .../arc_line_tangent/normal_v22.slvs | 450 + test/constraint/arc_line_tangent/test.cpp | 17 + .../at_midpoint/line_plane_free_in_3d.png | Bin 0 -> 4333 bytes .../at_midpoint/line_plane_free_in_3d.slvs | 290 + .../line_plane_free_in_3d_v20.slvs | 288 + .../line_plane_free_in_3d_v22.slvs | 290 + .../at_midpoint/line_plane_normal.png | Bin 0 -> 4333 bytes .../at_midpoint/line_plane_normal.slvs | 289 + .../at_midpoint/line_plane_normal_v20.slvs | 287 + .../at_midpoint/line_plane_normal_v22.slvs | 289 + .../at_midpoint/line_pt_free_in_3d.png | Bin 0 -> 4298 bytes .../at_midpoint/line_pt_free_in_3d.slvs | 315 + .../at_midpoint/line_pt_free_in_3d_v20.slvs | 313 + .../at_midpoint/line_pt_free_in_3d_v22.slvs | 315 + .../constraint/at_midpoint/line_pt_normal.png | Bin 0 -> 4298 bytes .../at_midpoint/line_pt_normal.slvs | 313 + .../at_midpoint/line_pt_normal_v20.slvs | 311 + .../at_midpoint/line_pt_normal_v22.slvs | 313 + test/constraint/at_midpoint/test.cpp | 65 + test/constraint/comment/normal.png | Bin 0 -> 4314 bytes test/constraint/comment/normal.slvs | 240 + test/constraint/comment/normal_v20.slvs | 238 + test/constraint/comment/normal_v22.slvs | 240 + test/constraint/comment/test.cpp | 17 + .../cubic_line_tangent/free_in_3d.png | Bin 0 -> 5073 bytes .../cubic_line_tangent/free_in_3d.slvs | 397 + .../cubic_line_tangent/free_in_3d_v20.slvs | 392 + .../cubic_line_tangent/free_in_3d_v22.slvs | 392 + test/constraint/cubic_line_tangent/normal.png | Bin 0 -> 5220 bytes .../constraint/cubic_line_tangent/normal.slvs | 446 + .../cubic_line_tangent/normal_v20.slvs | 446 + .../cubic_line_tangent/normal_v22.slvs | 446 + test/constraint/cubic_line_tangent/test.cpp | 33 + .../curve_curve_tangent/arc_arc.png | Bin 0 -> 5027 bytes .../curve_curve_tangent/arc_arc.slvs | 406 + .../curve_curve_tangent/arc_arc_v20.slvs | 404 + .../curve_curve_tangent/arc_arc_v22.slvs | 406 + .../curve_curve_tangent/arc_cubic.png | Bin 0 -> 5201 bytes .../curve_curve_tangent/arc_cubic.slvs | 506 + .../curve_curve_tangent/arc_cubic_v20.slvs | 506 + .../curve_curve_tangent/arc_cubic_v22.slvs | 506 + test/constraint/curve_curve_tangent/test.cpp | 33 + test/constraint/diameter/normal.png | Bin 0 -> 5024 bytes test/constraint/diameter/normal.slvs | 296 + test/constraint/diameter/normal_v20.slvs | 294 + test/constraint/diameter/normal_v22.slvs | 296 + test/constraint/diameter/reference.png | Bin 0 -> 5101 bytes test/constraint/diameter/reference.slvs | 296 + test/constraint/diameter/reference_v20.slvs | 296 + test/constraint/diameter/reference_v22.slvs | 296 + test/constraint/diameter/test.cpp | 33 + test/constraint/eq_len_pt_line_d/normal.png | Bin 0 -> 4407 bytes test/constraint/eq_len_pt_line_d/normal.slvs | 364 + .../eq_len_pt_line_d/normal_v20.slvs | 362 + .../eq_len_pt_line_d/normal_v22.slvs | 364 + test/constraint/eq_len_pt_line_d/test.cpp | 17 + test/constraint/eq_pt_ln_distances/normal.png | Bin 0 -> 4363 bytes .../constraint/eq_pt_ln_distances/normal.slvs | 389 + .../eq_pt_ln_distances/normal_v20.slvs | 387 + .../eq_pt_ln_distances/normal_v22.slvs | 389 + test/constraint/eq_pt_ln_distances/test.cpp | 17 + test/constraint/equal_angle/normal.png | Bin 0 -> 5267 bytes test/constraint/equal_angle/normal.slvs | 463 + test/constraint/equal_angle/normal_v20.slvs | 461 + test/constraint/equal_angle/normal_v22.slvs | 463 + test/constraint/equal_angle/other.png | Bin 0 -> 4914 bytes test/constraint/equal_angle/other.slvs | 463 + test/constraint/equal_angle/other_v20.slvs | 463 + test/constraint/equal_angle/other_v22.slvs | 463 + test/constraint/equal_angle/test.cpp | 33 + test/constraint/equal_length_lines/normal.png | Bin 0 -> 4341 bytes .../constraint/equal_length_lines/normal.slvs | 339 + .../equal_length_lines/normal_v20.slvs | 337 + .../equal_length_lines/normal_v22.slvs | 339 + test/constraint/equal_length_lines/test.cpp | 17 + test/constraint/equal_line_arc_len/normal.png | Bin 0 -> 4564 bytes .../constraint/equal_line_arc_len/normal.slvs | 367 + .../equal_line_arc_len/normal_v20.slvs | 367 + .../equal_line_arc_len/normal_v22.slvs | 367 + test/constraint/equal_line_arc_len/pi.png | Bin 0 -> 4667 bytes test/constraint/equal_line_arc_len/pi.slvs | 367 + test/constraint/equal_line_arc_len/tau.png | Bin 0 -> 4963 bytes test/constraint/equal_line_arc_len/tau.slvs | 367 + test/constraint/equal_line_arc_len/test.cpp | 27 + test/constraint/equal_radius/normal.png | Bin 0 -> 5258 bytes test/constraint/equal_radius/normal.slvs | 349 + test/constraint/equal_radius/normal_v20.slvs | 347 + test/constraint/equal_radius/normal_v22.slvs | 349 + test/constraint/equal_radius/test.cpp | 17 + test/constraint/horizontal/line.png | Bin 0 -> 4274 bytes test/constraint/horizontal/line.slvs | 288 + test/constraint/horizontal/line_v20.slvs | 286 + test/constraint/horizontal/line_v22.slvs | 288 + test/constraint/horizontal/pt_pt.png | Bin 0 -> 4268 bytes test/constraint/horizontal/pt_pt.slvs | 287 + test/constraint/horizontal/pt_pt_v20.slvs | 287 + test/constraint/horizontal/pt_pt_v22.slvs | 287 + test/constraint/horizontal/test.cpp | 33 + test/constraint/length_difference/normal.png | Bin 0 -> 4462 bytes test/constraint/length_difference/normal.slvs | 341 + .../length_difference/normal_v22.slvs | 341 + .../length_difference/reference.png | Bin 0 -> 4542 bytes .../length_difference/reference.slvs | 341 + .../length_difference/reference_v22.slvs | 341 + test/constraint/length_difference/test.cpp | 23 + test/constraint/length_ratio/normal.png | Bin 0 -> 4546 bytes test/constraint/length_ratio/normal.slvs | 342 + test/constraint/length_ratio/normal_v20.slvs | 340 + test/constraint/length_ratio/normal_v22.slvs | 342 + test/constraint/length_ratio/reference.png | Bin 0 -> 4616 bytes test/constraint/length_ratio/reference.slvs | 342 + .../length_ratio/reference_v20.slvs | 342 + .../length_ratio/reference_v22.slvs | 342 + test/constraint/length_ratio/test.cpp | 33 + test/constraint/parallel/free_in_3d.png | Bin 0 -> 4304 bytes test/constraint/parallel/free_in_3d.slvs | 295 + test/constraint/parallel/free_in_3d_v20.slvs | 290 + test/constraint/parallel/free_in_3d_v22.slvs | 290 + test/constraint/parallel/normal.png | Bin 0 -> 4686 bytes test/constraint/parallel/normal.slvs | 339 + test/constraint/parallel/normal_v20.slvs | 337 + test/constraint/parallel/normal_v22.slvs | 339 + test/constraint/parallel/test.cpp | 33 + test/constraint/perpendicular/normal.png | Bin 0 -> 4910 bytes test/constraint/perpendicular/normal.slvs | 339 + test/constraint/perpendicular/normal_v20.slvs | 337 + test/constraint/perpendicular/normal_v22.slvs | 339 + test/constraint/perpendicular/test.cpp | 17 + .../points_coincident/free_in_3d.png | Bin 0 -> 4241 bytes .../points_coincident/free_in_3d.slvs | 288 + .../points_coincident/free_in_3d_v20.slvs | 288 + .../points_coincident/free_in_3d_v22.slvs | 288 + test/constraint/points_coincident/normal.png | Bin 0 -> 4241 bytes test/constraint/points_coincident/normal.slvs | 287 + .../points_coincident/normal_v20.slvs | 287 + .../points_coincident/normal_v22.slvs | 287 + test/constraint/points_coincident/test.cpp | 33 + test/constraint/proj_pt_distance/normal.png | Bin 0 -> 4518 bytes test/constraint/proj_pt_distance/normal.slvs | 290 + .../proj_pt_distance/normal_v20.slvs | 293 + .../proj_pt_distance/normal_v22.slvs | 290 + .../constraint/proj_pt_distance/reference.png | Bin 0 -> 4566 bytes .../proj_pt_distance/reference.slvs | 290 + .../proj_pt_distance/reference_v20.slvs | 292 + .../proj_pt_distance/reference_v22.slvs | 290 + test/constraint/proj_pt_distance/test.cpp | 33 + test/constraint/pt_face_distance/normal.png | Bin 0 -> 4314 bytes test/constraint/pt_face_distance/normal.slvs | 713 + .../pt_face_distance/normal_v20.slvs | 712 + .../pt_face_distance/normal_v22.slvs | 681 + .../constraint/pt_face_distance/reference.png | Bin 0 -> 4378 bytes .../pt_face_distance/reference.slvs | 713 + .../pt_face_distance/reference_v20.slvs | 712 + .../pt_face_distance/reference_v22.slvs | 681 + test/constraint/pt_face_distance/test.cpp | 33 + test/constraint/pt_in_plane/normal.png | Bin 0 -> 4228 bytes test/constraint/pt_in_plane/normal.slvs | 261 + test/constraint/pt_in_plane/normal_v20.slvs | 259 + test/constraint/pt_in_plane/normal_v22.slvs | 261 + test/constraint/pt_in_plane/test.cpp | 17 + test/constraint/pt_line_distance/extended.png | Bin 0 -> 4527 bytes .../constraint/pt_line_distance/extended.slvs | 316 + .../pt_line_distance/free_in_3d.png | Bin 0 -> 4403 bytes .../pt_line_distance/free_in_3d.slvs | 316 + .../pt_line_distance/free_in_3d_v20.slvs | 314 + .../pt_line_distance/free_in_3d_v22.slvs | 316 + test/constraint/pt_line_distance/normal.png | Bin 0 -> 4403 bytes test/constraint/pt_line_distance/normal.slvs | 314 + .../pt_line_distance/normal_v20.slvs | 314 + .../pt_line_distance/normal_v22.slvs | 314 + .../constraint/pt_line_distance/reference.png | Bin 0 -> 4475 bytes .../pt_line_distance/reference.slvs | 314 + .../pt_line_distance/reference_v20.slvs | 314 + .../pt_line_distance/reference_v22.slvs | 314 + test/constraint/pt_line_distance/test.cpp | 54 + .../constraint/pt_on_circle/negative_dia.slvs | 364 + test/constraint/pt_on_circle/normal.png | Bin 0 -> 4884 bytes test/constraint/pt_on_circle/normal.slvs | 318 + test/constraint/pt_on_circle/normal_v20.slvs | 318 + test/constraint/pt_on_circle/normal_v22.slvs | 318 + test/constraint/pt_on_circle/test.cpp | 23 + test/constraint/pt_on_face/normal.png | Bin 0 -> 4662 bytes test/constraint/pt_on_face/normal.slvs | 703 + test/constraint/pt_on_face/normal_v20.slvs | 670 + test/constraint/pt_on_face/normal_v22.slvs | 687 + test/constraint/pt_on_face/test.cpp | 17 + .../constraint/pt_on_line/free_in_3d_v20.slvs | 315 + .../constraint/pt_on_line/free_in_3d_v22.slvs | 315 + .../constraint/pt_on_line/left_free_in_3d.png | Bin 0 -> 4319 bytes .../pt_on_line/left_free_in_3d.slvs | 320 + test/constraint/pt_on_line/normal.png | Bin 0 -> 4324 bytes test/constraint/pt_on_line/normal.slvs | 318 + test/constraint/pt_on_line/normal_v20.slvs | 315 + test/constraint/pt_on_line/normal_v22.slvs | 313 + .../pt_on_line/right_free_in_3d.png | Bin 0 -> 4316 bytes .../pt_on_line/right_free_in_3d.slvs | 320 + test/constraint/pt_on_line/test.cpp | 39 + test/constraint/pt_plane_distance/normal.png | Bin 0 -> 4345 bytes test/constraint/pt_plane_distance/normal.slvs | 264 + .../pt_plane_distance/normal_v20.slvs | 262 + .../pt_plane_distance/normal_v22.slvs | 264 + .../pt_plane_distance/reference.png | Bin 0 -> 4417 bytes .../pt_plane_distance/reference.slvs | 264 + .../pt_plane_distance/reference_v20.slvs | 264 + .../pt_plane_distance/reference_v22.slvs | 264 + test/constraint/pt_plane_distance/test.cpp | 33 + test/constraint/pt_pt_distance/free_in_3d.png | Bin 0 -> 4462 bytes .../constraint/pt_pt_distance/free_in_3d.slvs | 289 + .../pt_pt_distance/free_in_3d_v20.slvs | 289 + .../pt_pt_distance/free_in_3d_v22.slvs | 289 + test/constraint/pt_pt_distance/normal.png | Bin 0 -> 4467 bytes test/constraint/pt_pt_distance/normal.slvs | 289 + .../constraint/pt_pt_distance/normal_v20.slvs | 287 + .../constraint/pt_pt_distance/normal_v22.slvs | 289 + test/constraint/pt_pt_distance/reference.png | Bin 0 -> 4539 bytes test/constraint/pt_pt_distance/reference.slvs | 289 + .../pt_pt_distance/reference_v20.slvs | 289 + .../pt_pt_distance/reference_v22.slvs | 289 + test/constraint/pt_pt_distance/test.cpp | 49 + test/constraint/same_orientation/normal.png | Bin 0 -> 4472 bytes test/constraint/same_orientation/normal.slvs | 309 + .../same_orientation/normal_v20.slvs | 302 + .../same_orientation/normal_v22.slvs | 304 + .../same_orientation/same_group.png | Bin 0 -> 4376 bytes .../same_orientation/same_group.slvs | 379 + test/constraint/same_orientation/test.cpp | 23 + test/constraint/symmetric/free_in_3d.png | Bin 0 -> 4378 bytes test/constraint/symmetric/free_in_3d.slvs | 289 + test/constraint/symmetric/free_in_3d_v20.slvs | 287 + test/constraint/symmetric/free_in_3d_v22.slvs | 289 + test/constraint/symmetric/normal.png | Bin 0 -> 4362 bytes test/constraint/symmetric/normal.slvs | 288 + test/constraint/symmetric/normal_v20.slvs | 288 + test/constraint/symmetric/normal_v22.slvs | 288 + test/constraint/symmetric/test.cpp | 33 + test/constraint/symmetric_horiz/normal.png | Bin 0 -> 4362 bytes test/constraint/symmetric_horiz/normal.slvs | 287 + .../symmetric_horiz/normal_v20.slvs | 285 + .../symmetric_horiz/normal_v22.slvs | 287 + test/constraint/symmetric_horiz/test.cpp | 17 + test/constraint/symmetric_line/normal.png | Bin 0 -> 4431 bytes test/constraint/symmetric_line/normal.slvs | 338 + .../constraint/symmetric_line/normal_v20.slvs | 336 + .../constraint/symmetric_line/normal_v22.slvs | 338 + test/constraint/symmetric_line/test.cpp | 17 + test/constraint/symmetric_vert/normal.png | Bin 0 -> 4378 bytes test/constraint/symmetric_vert/normal.slvs | 287 + .../constraint/symmetric_vert/normal_v20.slvs | 285 + .../constraint/symmetric_vert/normal_v22.slvs | 287 + test/constraint/symmetric_vert/test.cpp | 17 + test/constraint/vertical/line.png | Bin 0 -> 4331 bytes test/constraint/vertical/line.slvs | 288 + test/constraint/vertical/line_v20.slvs | 290 + test/constraint/vertical/line_v22.slvs | 288 + test/constraint/vertical/pt_pt.png | Bin 0 -> 4258 bytes test/constraint/vertical/pt_pt.slvs | 287 + test/constraint/vertical/pt_pt_v20.slvs | 285 + test/constraint/vertical/pt_pt_v22.slvs | 287 + test/constraint/vertical/test.cpp | 33 + test/constraint/where_dragged/free_in_3d.png | Bin 0 -> 4257 bytes test/constraint/where_dragged/free_in_3d.slvs | 261 + .../where_dragged/free_in_3d_v20.slvs | 261 + .../where_dragged/free_in_3d_v22.slvs | 261 + test/constraint/where_dragged/normal.png | Bin 0 -> 4257 bytes test/constraint/where_dragged/normal.slvs | 262 + test/constraint/where_dragged/normal_v20.slvs | 260 + test/constraint/where_dragged/normal_v22.slvs | 262 + test/constraint/where_dragged/test.cpp | 33 + test/core/expr/test.cpp | 112 + test/core/locale/test.cpp | 8 + test/core/path/test.cpp | 246 + test/debugtool.cpp | 31 + test/group/link/normal.png | Bin 0 -> 4151 bytes test/group/link/normal.slvs | 465 + test/group/link/normal_v20.slvs | 463 + test/group/link/normal_v22.slvs | 465 + test/group/link/rect_v20.slvs | 510 + test/group/link/test.cpp | 17 + test/group/translate_asy/normal.png | Bin 0 -> 8508 bytes test/group/translate_asy/normal.slvs | 2088 ++ test/group/translate_asy/normal_v22.slvs | 2088 ++ test/group/translate_asy/test.cpp | 29 + test/group/translate_nd/normal.png | Bin 0 -> 4983 bytes test/group/translate_nd/normal.slvs | 8316 ++++++ test/group/translate_nd/normal_v22.slvs | 8316 ++++++ test/group/translate_nd/test.cpp | 12 + test/harness.cpp | 413 + test/harness.h | 75 + test/request/arc_of_circle/normal.png | Bin 0 -> 4560 bytes test/request/arc_of_circle/normal.slvs | 306 + test/request/arc_of_circle/normal_v20.slvs | 306 + test/request/arc_of_circle/normal_v22.slvs | 306 + test/request/arc_of_circle/test.cpp | 17 + test/request/circle/free_in_3d.png | Bin 0 -> 4796 bytes test/request/circle/free_in_3d.slvs | 294 + test/request/circle/free_in_3d_dof.png | Bin 0 -> 7195 bytes test/request/circle/free_in_3d_v20.slvs | 292 + test/request/circle/free_in_3d_v22.slvs | 294 + test/request/circle/normal.png | Bin 0 -> 4796 bytes test/request/circle/normal.slvs | 283 + test/request/circle/normal_dof.png | Bin 0 -> 4830 bytes test/request/circle/normal_v20.slvs | 283 + test/request/circle/normal_v22.slvs | 283 + test/request/circle/test.cpp | 45 + test/request/cubic/normal.png | Bin 0 -> 4949 bytes test/request/cubic/normal.slvs | 348 + test/request/cubic/normal_v20.slvs | 348 + test/request/cubic/normal_v22.slvs | 348 + test/request/cubic/test.cpp | 17 + test/request/cubic_periodic/normal.png | Bin 0 -> 5225 bytes test/request/cubic_periodic/normal.slvs | 316 + test/request/cubic_periodic/normal_v20.slvs | 314 + test/request/cubic_periodic/normal_v22.slvs | 316 + test/request/cubic_periodic/test.cpp | 17 + test/request/datum_point/normal.png | Bin 0 -> 4205 bytes test/request/datum_point/normal.slvs | 252 + test/request/datum_point/normal_v20.slvs | 250 + test/request/datum_point/normal_v22.slvs | 252 + test/request/datum_point/test.cpp | 17 + test/request/image/drawing.png | Bin 0 -> 8565 bytes test/request/image/linked.slvs | 430 + test/request/image/normal.slvs | 319 + test/request/image/test.cpp | 14 + test/request/line_segment/normal.png | Bin 0 -> 4246 bytes test/request/line_segment/normal.slvs | 278 + test/request/line_segment/normal_v20.slvs | 278 + test/request/line_segment/normal_v22.slvs | 278 + test/request/line_segment/test.cpp | 17 + test/request/ttf_text/normal.png | Bin 0 -> 6158 bytes test/request/ttf_text/normal.slvs | 329 + test/request/ttf_text/normal_v20.slvs | 290 + test/request/ttf_text/normal_v22.slvs | 292 + test/request/ttf_text/test.cpp | 17 + test/request/workplane/normal.png | Bin 0 -> 5612 bytes test/request/workplane/normal.slvs | 293 + test/request/workplane/normal_v20.slvs | 291 + test/request/workplane/normal_v22.slvs | 293 + test/request/workplane/test.cpp | 17 + wishlist.txt | 19 + 693 files changed, 273416 insertions(+) create mode 100644 .clang-format create mode 100644 CHANGELOG.md create mode 100644 CMakeLists.txt create mode 100644 CONTRIBUTING.md create mode 100644 COPYING.txt create mode 100644 README.md create mode 100644 THIRD_PARTIES.txt create mode 100644 bench/CMakeLists.txt create mode 100644 bench/harness.cpp create mode 100644 cmake/AddVendoredSubdirectory.cmake create mode 100644 cmake/DisableWarnings.cmake create mode 100644 cmake/FindSpaceWare.cmake create mode 100644 cmake/FindVendoredPackage.cmake create mode 100644 cmake/GetGitCommitHash.cmake create mode 100644 cmake/MacOSXBundleInfo.plist.in create mode 100644 cmake/Toolchain-mingw32.cmake create mode 100644 cmake/Toolchain-mingw64.cmake create mode 100644 cmake/c_flag_overrides.cmake create mode 100644 cmake/cxx_flag_overrides.cmake create mode 100644 developer_docs/Solver_Transforms.txt create mode 100644 exposed/CDemo.c create mode 100644 exposed/CMakeLists.txt create mode 100644 exposed/DOC.txt create mode 100644 exposed/VbDemo.vb create mode 100644 extlib/libdxfrw/CMakeLists.txt create mode 100644 extlib/libdxfrw/drw_base.h create mode 100644 extlib/libdxfrw/drw_classes.cpp create mode 100644 extlib/libdxfrw/drw_classes.h create mode 100644 extlib/libdxfrw/drw_entities.cpp create mode 100644 extlib/libdxfrw/drw_entities.h create mode 100644 extlib/libdxfrw/drw_header.cpp create mode 100644 extlib/libdxfrw/drw_header.h create mode 100644 extlib/libdxfrw/drw_interface.h create mode 100644 extlib/libdxfrw/drw_objects.cpp create mode 100644 extlib/libdxfrw/drw_objects.h create mode 100644 extlib/libdxfrw/intern/drw_cptable932.h create mode 100644 extlib/libdxfrw/intern/drw_cptable936.h create mode 100644 extlib/libdxfrw/intern/drw_cptable949.h create mode 100644 extlib/libdxfrw/intern/drw_cptable950.h create mode 100644 extlib/libdxfrw/intern/drw_cptables.h create mode 100644 extlib/libdxfrw/intern/drw_dbg.cpp create mode 100644 extlib/libdxfrw/intern/drw_dbg.h create mode 100644 extlib/libdxfrw/intern/drw_textcodec.cpp create mode 100644 extlib/libdxfrw/intern/drw_textcodec.h create mode 100644 extlib/libdxfrw/intern/dwgbuffer.cpp create mode 100644 extlib/libdxfrw/intern/dwgbuffer.h create mode 100644 extlib/libdxfrw/intern/dwgreader.cpp create mode 100644 extlib/libdxfrw/intern/dwgreader.h create mode 100644 extlib/libdxfrw/intern/dwgreader15.cpp create mode 100644 extlib/libdxfrw/intern/dwgreader15.h create mode 100644 extlib/libdxfrw/intern/dwgreader18.cpp create mode 100644 extlib/libdxfrw/intern/dwgreader18.h create mode 100644 extlib/libdxfrw/intern/dwgreader21.cpp create mode 100644 extlib/libdxfrw/intern/dwgreader21.h create mode 100644 extlib/libdxfrw/intern/dwgreader24.cpp create mode 100644 extlib/libdxfrw/intern/dwgreader24.h create mode 100644 extlib/libdxfrw/intern/dwgreader27.cpp create mode 100644 extlib/libdxfrw/intern/dwgreader27.h create mode 100644 extlib/libdxfrw/intern/dwgutil.cpp create mode 100644 extlib/libdxfrw/intern/dwgutil.h create mode 100644 extlib/libdxfrw/intern/dxfreader.cpp create mode 100644 extlib/libdxfrw/intern/dxfreader.h create mode 100644 extlib/libdxfrw/intern/dxfwriter.cpp create mode 100644 extlib/libdxfrw/intern/dxfwriter.h create mode 100644 extlib/libdxfrw/intern/rscodec.cpp create mode 100644 extlib/libdxfrw/intern/rscodec.h create mode 100644 extlib/libdxfrw/libdwgr.cpp create mode 100644 extlib/libdxfrw/libdwgr.h create mode 100644 extlib/libdxfrw/libdxfrw.cpp create mode 100644 extlib/libdxfrw/libdxfrw.h create mode 100644 extlib/mimalloc/.gitattributes create mode 100644 extlib/mimalloc/.gitignore create mode 100644 extlib/mimalloc/CMakeLists.txt create mode 100644 extlib/mimalloc/LICENSE create mode 100644 extlib/mimalloc/azure-pipelines.yml create mode 100644 extlib/mimalloc/cmake/mimalloc-config-version.cmake create mode 100644 extlib/mimalloc/cmake/mimalloc-config.cmake create mode 100644 extlib/mimalloc/ide/vs2017/mimalloc-override-test.vcxproj create mode 100644 extlib/mimalloc/ide/vs2017/mimalloc-override-test.vcxproj.filters create mode 100644 extlib/mimalloc/ide/vs2017/mimalloc-override.vcxproj create mode 100644 extlib/mimalloc/ide/vs2017/mimalloc-override.vcxproj.filters create mode 100644 extlib/mimalloc/ide/vs2017/mimalloc-test-stress.vcxproj create mode 100644 extlib/mimalloc/ide/vs2017/mimalloc-test-stress.vcxproj.filters create mode 100644 extlib/mimalloc/ide/vs2017/mimalloc-test.vcxproj create mode 100644 extlib/mimalloc/ide/vs2017/mimalloc-test.vcxproj.filters create mode 100644 extlib/mimalloc/ide/vs2017/mimalloc.sln create mode 100644 extlib/mimalloc/ide/vs2017/mimalloc.vcxproj create mode 100644 extlib/mimalloc/ide/vs2017/mimalloc.vcxproj.filters create mode 100644 extlib/mimalloc/ide/vs2019/mimalloc-override-test.vcxproj create mode 100644 extlib/mimalloc/ide/vs2019/mimalloc-override.vcxproj create mode 100644 extlib/mimalloc/ide/vs2019/mimalloc-override.vcxproj.filters create mode 100644 extlib/mimalloc/ide/vs2019/mimalloc-test-api.vcxproj create mode 100644 extlib/mimalloc/ide/vs2019/mimalloc-test-stress.vcxproj create mode 100644 extlib/mimalloc/ide/vs2019/mimalloc-test.vcxproj create mode 100644 extlib/mimalloc/ide/vs2019/mimalloc.sln create mode 100644 extlib/mimalloc/ide/vs2019/mimalloc.vcxproj create mode 100644 extlib/mimalloc/ide/vs2019/mimalloc.vcxproj.filters create mode 100644 extlib/mimalloc/include/mimalloc-atomic.h create mode 100644 extlib/mimalloc/include/mimalloc-internal.h create mode 100644 extlib/mimalloc/include/mimalloc-new-delete.h create mode 100644 extlib/mimalloc/include/mimalloc-override.h create mode 100644 extlib/mimalloc/include/mimalloc-types.h create mode 100644 extlib/mimalloc/include/mimalloc.h create mode 100644 extlib/mimalloc/readme.md create mode 100644 extlib/mimalloc/src/alloc-aligned.c create mode 100644 extlib/mimalloc/src/alloc-override-osx.c create mode 100644 extlib/mimalloc/src/alloc-override.c create mode 100644 extlib/mimalloc/src/alloc-posix.c create mode 100644 extlib/mimalloc/src/alloc.c create mode 100644 extlib/mimalloc/src/arena.c create mode 100644 extlib/mimalloc/src/bitmap.inc.c create mode 100644 extlib/mimalloc/src/heap.c create mode 100644 extlib/mimalloc/src/init.c create mode 100644 extlib/mimalloc/src/options.c create mode 100644 extlib/mimalloc/src/os.c create mode 100644 extlib/mimalloc/src/page-queue.c create mode 100644 extlib/mimalloc/src/page.c create mode 100644 extlib/mimalloc/src/random.c create mode 100644 extlib/mimalloc/src/region.c create mode 100644 extlib/mimalloc/src/segment.c create mode 100644 extlib/mimalloc/src/static.c create mode 100644 extlib/mimalloc/src/stats.c create mode 100644 extlib/mimalloc/test/CMakeLists.txt create mode 100644 extlib/mimalloc/test/main-override-static.c create mode 100644 extlib/mimalloc/test/main-override.c create mode 100644 extlib/mimalloc/test/main-override.cpp create mode 100644 extlib/mimalloc/test/main.c create mode 100644 extlib/mimalloc/test/readme.md create mode 100644 extlib/mimalloc/test/test-api.c create mode 100644 extlib/mimalloc/test/test-stress.c create mode 100644 include/slvs.h create mode 100644 pkg/flatpak/.gitignore create mode 100755 pkg/flatpak/build.sh create mode 100644 pkg/flatpak/com.solvespace.SolveSpace.json create mode 100644 pkg/snap/.gitignore create mode 100755 pkg/snap/build.sh create mode 100644 pkg/snap/snap/snapcraft.yaml create mode 100644 res/CMakeLists.txt create mode 100644 res/banner.txt create mode 100644 res/cocoa/AppIcon.iconset/icon_128x128.png create mode 100644 res/cocoa/AppIcon.iconset/icon_128x128@2x.png create mode 100644 res/cocoa/AppIcon.iconset/icon_16x16.png create mode 100644 res/cocoa/AppIcon.iconset/icon_16x16@2x.png create mode 100644 res/cocoa/AppIcon.iconset/icon_256x256.png create mode 100644 res/cocoa/AppIcon.iconset/icon_256x256@2x.png create mode 100644 res/cocoa/AppIcon.iconset/icon_32x32.png create mode 100644 res/cocoa/AppIcon.iconset/icon_32x32@2x.png create mode 100644 res/cocoa/AppIcon.iconset/icon_512x512.png create mode 100644 res/cocoa/AppIcon.iconset/icon_512x512@2x.png create mode 100644 res/cocoa/MainMenu.xib create mode 100644 res/cocoa/SaveFormatAccessory.xib create mode 100644 res/fonts/BitstreamVeraSans-Roman-builtin.ttf create mode 100644 res/fonts/private/0-check-false.png create mode 100644 res/fonts/private/1-check-true.png create mode 100644 res/fonts/private/2-radio-false.png create mode 100644 res/fonts/private/3-radio-true.png create mode 100644 res/fonts/private/4-stipple-dot.png create mode 100644 res/fonts/private/5-stipple-dash-long.png create mode 100644 res/fonts/private/6-stipple-dash.png create mode 100644 res/fonts/private/7-stipple-zigzag.png create mode 100644 res/fonts/unicode.lff.gz create mode 100644 res/freedesktop/solvespace-16x16.png create mode 100644 res/freedesktop/solvespace-16x16.xpm create mode 100644 res/freedesktop/solvespace-24x24.png create mode 100644 res/freedesktop/solvespace-24x24.xpm create mode 100644 res/freedesktop/solvespace-32x32.png create mode 100644 res/freedesktop/solvespace-32x32.xpm create mode 100644 res/freedesktop/solvespace-48x48.png create mode 100644 res/freedesktop/solvespace-48x48.xpm create mode 100644 res/freedesktop/solvespace-flatpak-mime.xml create mode 100644 res/freedesktop/solvespace-flatpak.desktop.in create mode 100644 res/freedesktop/solvespace-mime.xml create mode 100644 res/freedesktop/solvespace-scalable.svg create mode 100644 res/freedesktop/solvespace-snap.desktop create mode 100644 res/freedesktop/solvespace.desktop.in create mode 100644 res/icons/graphics-window/angle.png create mode 100644 res/icons/graphics-window/arc.png create mode 100644 res/icons/graphics-window/assemble.png create mode 100644 res/icons/graphics-window/bezier.png create mode 100644 res/icons/graphics-window/circle.png create mode 100644 res/icons/graphics-window/construction.png create mode 100644 res/icons/graphics-window/equal.png create mode 100644 res/icons/graphics-window/extrude.png create mode 100644 res/icons/graphics-window/helix.png create mode 100644 res/icons/graphics-window/horiz.png create mode 100644 res/icons/graphics-window/image.png create mode 100644 res/icons/graphics-window/in3d.png create mode 100644 res/icons/graphics-window/lathe.png create mode 100644 res/icons/graphics-window/length.png create mode 100644 res/icons/graphics-window/line.png create mode 100644 res/icons/graphics-window/ontoworkplane.png create mode 100644 res/icons/graphics-window/other-supp.png create mode 100644 res/icons/graphics-window/parallel.png create mode 100644 res/icons/graphics-window/perpendicular.png create mode 100644 res/icons/graphics-window/point.png create mode 100644 res/icons/graphics-window/pointonx.png create mode 100644 res/icons/graphics-window/rectangle.png create mode 100644 res/icons/graphics-window/ref.png create mode 100644 res/icons/graphics-window/revolve.png create mode 100644 res/icons/graphics-window/same-orientation.png create mode 100644 res/icons/graphics-window/sketch-in-3d.png create mode 100644 res/icons/graphics-window/sketch-in-plane.png create mode 100644 res/icons/graphics-window/step-rotate.png create mode 100644 res/icons/graphics-window/step-translate.png create mode 100644 res/icons/graphics-window/symmetric.png create mode 100644 res/icons/graphics-window/tangent-arc.png create mode 100644 res/icons/graphics-window/text.png create mode 100644 res/icons/graphics-window/trim.png create mode 100644 res/icons/graphics-window/vert.png create mode 100644 res/icons/text-window/constraint.png create mode 100644 res/icons/text-window/construction.png create mode 100644 res/icons/text-window/edges.png create mode 100644 res/icons/text-window/faces.png create mode 100644 res/icons/text-window/mesh.png create mode 100644 res/icons/text-window/normal.png create mode 100644 res/icons/text-window/occluded-invisible.png create mode 100644 res/icons/text-window/occluded-stippled.png create mode 100644 res/icons/text-window/occluded-visible.png create mode 100644 res/icons/text-window/outlines.png create mode 100644 res/icons/text-window/point.png create mode 100644 res/icons/text-window/shaded.png create mode 100644 res/icons/text-window/workplane.png create mode 100644 res/locales.txt create mode 100644 res/locales/de_DE.po create mode 100644 res/locales/en_US.po create mode 100644 res/locales/fr_FR.po create mode 100644 res/locales/ru_RU.po create mode 100644 res/locales/uk_UA.po create mode 100644 res/locales/zh_CN.po create mode 100644 res/messages.pot create mode 100644 res/shaders/edge.frag create mode 100644 res/shaders/edge.vert create mode 100644 res/shaders/imesh.frag create mode 100644 res/shaders/imesh.vert create mode 100644 res/shaders/imesh_point.frag create mode 100644 res/shaders/imesh_point.vert create mode 100644 res/shaders/imesh_tex.frag create mode 100644 res/shaders/imesh_tex.vert create mode 100644 res/shaders/imesh_texa.frag create mode 100644 res/shaders/mesh.frag create mode 100644 res/shaders/mesh.vert create mode 100644 res/shaders/mesh_fill.frag create mode 100644 res/shaders/mesh_fill.vert create mode 100644 res/shaders/outline.vert create mode 100644 res/threejs/SolveSpaceControls.js create mode 100644 res/threejs/hammer-2.0.8.js.gz create mode 100644 res/win32/icon.ico create mode 100644 res/win32/manifest.xml create mode 100644 res/win32/versioninfo.rc.in create mode 100644 src/CMakeLists.txt create mode 100644 src/bsp.cpp create mode 100644 src/clipboard.cpp create mode 100644 src/config.h.in create mode 100644 src/confscreen.cpp create mode 100644 src/constraint.cpp create mode 100644 src/constrainteq.cpp create mode 100644 src/describescreen.cpp create mode 100644 src/draw.cpp create mode 100644 src/drawconstraint.cpp create mode 100644 src/drawentity.cpp create mode 100644 src/dsc.h create mode 100644 src/entity.cpp create mode 100644 src/export.cpp create mode 100644 src/exportstep.cpp create mode 100644 src/exportvector.cpp create mode 100644 src/expr.cpp create mode 100644 src/expr.h create mode 100644 src/file.cpp create mode 100644 src/generate.cpp create mode 100644 src/graphicswin.cpp create mode 100644 src/group.cpp create mode 100644 src/groupmesh.cpp create mode 100644 src/importdxf.cpp create mode 100644 src/importidf.cpp create mode 100644 src/lib.cpp create mode 100644 src/mesh.cpp create mode 100644 src/modify.cpp create mode 100644 src/mouse.cpp create mode 100644 src/platform/entrycli.cpp create mode 100644 src/platform/entrygui.cpp create mode 100644 src/platform/gui.cpp create mode 100644 src/platform/gui.h create mode 100644 src/platform/guigtk.cpp create mode 100644 src/platform/guimac.mm create mode 100644 src/platform/guinone.cpp create mode 100644 src/platform/guiwin.cpp create mode 100644 src/platform/platform.cpp create mode 100644 src/platform/platform.h create mode 100644 src/polygon.cpp create mode 100644 src/polygon.h create mode 100644 src/polyline.cpp create mode 100644 src/render/gl3shader.cpp create mode 100644 src/render/gl3shader.h create mode 100644 src/render/render.cpp create mode 100644 src/render/render.h create mode 100644 src/render/render2d.cpp create mode 100644 src/render/rendercairo.cpp create mode 100644 src/render/rendergl1.cpp create mode 100644 src/render/rendergl3.cpp create mode 100644 src/request.cpp create mode 100644 src/resource.cpp create mode 100644 src/resource.h create mode 100644 src/sketch.h create mode 100644 src/solvespace.cpp create mode 100644 src/solvespace.h create mode 100644 src/srf/boolean.cpp create mode 100644 src/srf/curve.cpp create mode 100644 src/srf/merge.cpp create mode 100644 src/srf/ratpoly.cpp create mode 100644 src/srf/raycast.cpp create mode 100644 src/srf/surface.cpp create mode 100644 src/srf/surface.h create mode 100644 src/srf/surfinter.cpp create mode 100644 src/srf/triangulate.cpp create mode 100644 src/style.cpp create mode 100644 src/system.cpp create mode 100644 src/textscreens.cpp create mode 100644 src/textwin.cpp create mode 100644 src/toolbar.cpp create mode 100644 src/ttf.cpp create mode 100644 src/ttf.h create mode 100644 src/ui.h create mode 100644 src/undoredo.cpp create mode 100644 src/util.cpp create mode 100644 src/view.cpp create mode 100644 test/CMakeLists.txt create mode 100644 test/Gentium-R.ttf create mode 100644 test/analysis/contour_area/normal.png create mode 100644 test/analysis/contour_area/normal.slvs create mode 100644 test/analysis/contour_area/test.cpp create mode 100755 test/commit.sh create mode 100644 test/constraint/angle/free_in_3d.png create mode 100644 test/constraint/angle/free_in_3d.slvs create mode 100644 test/constraint/angle/free_in_3d_v20.slvs create mode 100644 test/constraint/angle/free_in_3d_v22.slvs create mode 100644 test/constraint/angle/normal.png create mode 100644 test/constraint/angle/normal.slvs create mode 100644 test/constraint/angle/normal_v20.slvs create mode 100644 test/constraint/angle/normal_v22.slvs create mode 100644 test/constraint/angle/reference.png create mode 100644 test/constraint/angle/reference.slvs create mode 100644 test/constraint/angle/reference_free_in_3d.png create mode 100644 test/constraint/angle/reference_free_in_3d.slvs create mode 100644 test/constraint/angle/reference_free_in_3d_v20.slvs create mode 100644 test/constraint/angle/reference_free_in_3d_v22.slvs create mode 100644 test/constraint/angle/reference_v20.slvs create mode 100644 test/constraint/angle/reference_v22.slvs create mode 100644 test/constraint/angle/skew.png create mode 100644 test/constraint/angle/skew.slvs create mode 100644 test/constraint/angle/skew_v22.slvs create mode 100644 test/constraint/angle/test.cpp create mode 100644 test/constraint/arc_line_tangent/normal.png create mode 100644 test/constraint/arc_line_tangent/normal.slvs create mode 100644 test/constraint/arc_line_tangent/normal_v20.slvs create mode 100644 test/constraint/arc_line_tangent/normal_v22.slvs create mode 100644 test/constraint/arc_line_tangent/test.cpp create mode 100644 test/constraint/at_midpoint/line_plane_free_in_3d.png create mode 100644 test/constraint/at_midpoint/line_plane_free_in_3d.slvs create mode 100644 test/constraint/at_midpoint/line_plane_free_in_3d_v20.slvs create mode 100644 test/constraint/at_midpoint/line_plane_free_in_3d_v22.slvs create mode 100644 test/constraint/at_midpoint/line_plane_normal.png create mode 100644 test/constraint/at_midpoint/line_plane_normal.slvs create mode 100644 test/constraint/at_midpoint/line_plane_normal_v20.slvs create mode 100644 test/constraint/at_midpoint/line_plane_normal_v22.slvs create mode 100644 test/constraint/at_midpoint/line_pt_free_in_3d.png create mode 100644 test/constraint/at_midpoint/line_pt_free_in_3d.slvs create mode 100644 test/constraint/at_midpoint/line_pt_free_in_3d_v20.slvs create mode 100644 test/constraint/at_midpoint/line_pt_free_in_3d_v22.slvs create mode 100644 test/constraint/at_midpoint/line_pt_normal.png create mode 100644 test/constraint/at_midpoint/line_pt_normal.slvs create mode 100644 test/constraint/at_midpoint/line_pt_normal_v20.slvs create mode 100644 test/constraint/at_midpoint/line_pt_normal_v22.slvs create mode 100644 test/constraint/at_midpoint/test.cpp create mode 100644 test/constraint/comment/normal.png create mode 100644 test/constraint/comment/normal.slvs create mode 100644 test/constraint/comment/normal_v20.slvs create mode 100644 test/constraint/comment/normal_v22.slvs create mode 100644 test/constraint/comment/test.cpp create mode 100644 test/constraint/cubic_line_tangent/free_in_3d.png create mode 100644 test/constraint/cubic_line_tangent/free_in_3d.slvs create mode 100644 test/constraint/cubic_line_tangent/free_in_3d_v20.slvs create mode 100644 test/constraint/cubic_line_tangent/free_in_3d_v22.slvs create mode 100644 test/constraint/cubic_line_tangent/normal.png create mode 100644 test/constraint/cubic_line_tangent/normal.slvs create mode 100644 test/constraint/cubic_line_tangent/normal_v20.slvs create mode 100644 test/constraint/cubic_line_tangent/normal_v22.slvs create mode 100644 test/constraint/cubic_line_tangent/test.cpp create mode 100644 test/constraint/curve_curve_tangent/arc_arc.png create mode 100644 test/constraint/curve_curve_tangent/arc_arc.slvs create mode 100644 test/constraint/curve_curve_tangent/arc_arc_v20.slvs create mode 100644 test/constraint/curve_curve_tangent/arc_arc_v22.slvs create mode 100644 test/constraint/curve_curve_tangent/arc_cubic.png create mode 100644 test/constraint/curve_curve_tangent/arc_cubic.slvs create mode 100644 test/constraint/curve_curve_tangent/arc_cubic_v20.slvs create mode 100644 test/constraint/curve_curve_tangent/arc_cubic_v22.slvs create mode 100644 test/constraint/curve_curve_tangent/test.cpp create mode 100644 test/constraint/diameter/normal.png create mode 100644 test/constraint/diameter/normal.slvs create mode 100644 test/constraint/diameter/normal_v20.slvs create mode 100644 test/constraint/diameter/normal_v22.slvs create mode 100644 test/constraint/diameter/reference.png create mode 100644 test/constraint/diameter/reference.slvs create mode 100644 test/constraint/diameter/reference_v20.slvs create mode 100644 test/constraint/diameter/reference_v22.slvs create mode 100644 test/constraint/diameter/test.cpp create mode 100644 test/constraint/eq_len_pt_line_d/normal.png create mode 100644 test/constraint/eq_len_pt_line_d/normal.slvs create mode 100644 test/constraint/eq_len_pt_line_d/normal_v20.slvs create mode 100644 test/constraint/eq_len_pt_line_d/normal_v22.slvs create mode 100644 test/constraint/eq_len_pt_line_d/test.cpp create mode 100644 test/constraint/eq_pt_ln_distances/normal.png create mode 100644 test/constraint/eq_pt_ln_distances/normal.slvs create mode 100644 test/constraint/eq_pt_ln_distances/normal_v20.slvs create mode 100644 test/constraint/eq_pt_ln_distances/normal_v22.slvs create mode 100644 test/constraint/eq_pt_ln_distances/test.cpp create mode 100644 test/constraint/equal_angle/normal.png create mode 100644 test/constraint/equal_angle/normal.slvs create mode 100644 test/constraint/equal_angle/normal_v20.slvs create mode 100644 test/constraint/equal_angle/normal_v22.slvs create mode 100644 test/constraint/equal_angle/other.png create mode 100644 test/constraint/equal_angle/other.slvs create mode 100644 test/constraint/equal_angle/other_v20.slvs create mode 100644 test/constraint/equal_angle/other_v22.slvs create mode 100644 test/constraint/equal_angle/test.cpp create mode 100644 test/constraint/equal_length_lines/normal.png create mode 100644 test/constraint/equal_length_lines/normal.slvs create mode 100644 test/constraint/equal_length_lines/normal_v20.slvs create mode 100644 test/constraint/equal_length_lines/normal_v22.slvs create mode 100644 test/constraint/equal_length_lines/test.cpp create mode 100644 test/constraint/equal_line_arc_len/normal.png create mode 100644 test/constraint/equal_line_arc_len/normal.slvs create mode 100644 test/constraint/equal_line_arc_len/normal_v20.slvs create mode 100644 test/constraint/equal_line_arc_len/normal_v22.slvs create mode 100644 test/constraint/equal_line_arc_len/pi.png create mode 100644 test/constraint/equal_line_arc_len/pi.slvs create mode 100644 test/constraint/equal_line_arc_len/tau.png create mode 100644 test/constraint/equal_line_arc_len/tau.slvs create mode 100644 test/constraint/equal_line_arc_len/test.cpp create mode 100644 test/constraint/equal_radius/normal.png create mode 100644 test/constraint/equal_radius/normal.slvs create mode 100644 test/constraint/equal_radius/normal_v20.slvs create mode 100644 test/constraint/equal_radius/normal_v22.slvs create mode 100644 test/constraint/equal_radius/test.cpp create mode 100644 test/constraint/horizontal/line.png create mode 100644 test/constraint/horizontal/line.slvs create mode 100644 test/constraint/horizontal/line_v20.slvs create mode 100644 test/constraint/horizontal/line_v22.slvs create mode 100644 test/constraint/horizontal/pt_pt.png create mode 100644 test/constraint/horizontal/pt_pt.slvs create mode 100644 test/constraint/horizontal/pt_pt_v20.slvs create mode 100644 test/constraint/horizontal/pt_pt_v22.slvs create mode 100644 test/constraint/horizontal/test.cpp create mode 100644 test/constraint/length_difference/normal.png create mode 100644 test/constraint/length_difference/normal.slvs create mode 100644 test/constraint/length_difference/normal_v22.slvs create mode 100644 test/constraint/length_difference/reference.png create mode 100644 test/constraint/length_difference/reference.slvs create mode 100644 test/constraint/length_difference/reference_v22.slvs create mode 100644 test/constraint/length_difference/test.cpp create mode 100644 test/constraint/length_ratio/normal.png create mode 100644 test/constraint/length_ratio/normal.slvs create mode 100644 test/constraint/length_ratio/normal_v20.slvs create mode 100644 test/constraint/length_ratio/normal_v22.slvs create mode 100644 test/constraint/length_ratio/reference.png create mode 100644 test/constraint/length_ratio/reference.slvs create mode 100644 test/constraint/length_ratio/reference_v20.slvs create mode 100644 test/constraint/length_ratio/reference_v22.slvs create mode 100644 test/constraint/length_ratio/test.cpp create mode 100644 test/constraint/parallel/free_in_3d.png create mode 100644 test/constraint/parallel/free_in_3d.slvs create mode 100644 test/constraint/parallel/free_in_3d_v20.slvs create mode 100644 test/constraint/parallel/free_in_3d_v22.slvs create mode 100644 test/constraint/parallel/normal.png create mode 100644 test/constraint/parallel/normal.slvs create mode 100644 test/constraint/parallel/normal_v20.slvs create mode 100644 test/constraint/parallel/normal_v22.slvs create mode 100644 test/constraint/parallel/test.cpp create mode 100644 test/constraint/perpendicular/normal.png create mode 100644 test/constraint/perpendicular/normal.slvs create mode 100644 test/constraint/perpendicular/normal_v20.slvs create mode 100644 test/constraint/perpendicular/normal_v22.slvs create mode 100644 test/constraint/perpendicular/test.cpp create mode 100644 test/constraint/points_coincident/free_in_3d.png create mode 100644 test/constraint/points_coincident/free_in_3d.slvs create mode 100644 test/constraint/points_coincident/free_in_3d_v20.slvs create mode 100644 test/constraint/points_coincident/free_in_3d_v22.slvs create mode 100644 test/constraint/points_coincident/normal.png create mode 100644 test/constraint/points_coincident/normal.slvs create mode 100644 test/constraint/points_coincident/normal_v20.slvs create mode 100644 test/constraint/points_coincident/normal_v22.slvs create mode 100644 test/constraint/points_coincident/test.cpp create mode 100644 test/constraint/proj_pt_distance/normal.png create mode 100644 test/constraint/proj_pt_distance/normal.slvs create mode 100644 test/constraint/proj_pt_distance/normal_v20.slvs create mode 100644 test/constraint/proj_pt_distance/normal_v22.slvs create mode 100644 test/constraint/proj_pt_distance/reference.png create mode 100644 test/constraint/proj_pt_distance/reference.slvs create mode 100644 test/constraint/proj_pt_distance/reference_v20.slvs create mode 100644 test/constraint/proj_pt_distance/reference_v22.slvs create mode 100644 test/constraint/proj_pt_distance/test.cpp create mode 100644 test/constraint/pt_face_distance/normal.png create mode 100644 test/constraint/pt_face_distance/normal.slvs create mode 100644 test/constraint/pt_face_distance/normal_v20.slvs create mode 100644 test/constraint/pt_face_distance/normal_v22.slvs create mode 100644 test/constraint/pt_face_distance/reference.png create mode 100644 test/constraint/pt_face_distance/reference.slvs create mode 100644 test/constraint/pt_face_distance/reference_v20.slvs create mode 100644 test/constraint/pt_face_distance/reference_v22.slvs create mode 100644 test/constraint/pt_face_distance/test.cpp create mode 100644 test/constraint/pt_in_plane/normal.png create mode 100644 test/constraint/pt_in_plane/normal.slvs create mode 100644 test/constraint/pt_in_plane/normal_v20.slvs create mode 100644 test/constraint/pt_in_plane/normal_v22.slvs create mode 100644 test/constraint/pt_in_plane/test.cpp create mode 100644 test/constraint/pt_line_distance/extended.png create mode 100644 test/constraint/pt_line_distance/extended.slvs create mode 100644 test/constraint/pt_line_distance/free_in_3d.png create mode 100644 test/constraint/pt_line_distance/free_in_3d.slvs create mode 100644 test/constraint/pt_line_distance/free_in_3d_v20.slvs create mode 100644 test/constraint/pt_line_distance/free_in_3d_v22.slvs create mode 100644 test/constraint/pt_line_distance/normal.png create mode 100644 test/constraint/pt_line_distance/normal.slvs create mode 100644 test/constraint/pt_line_distance/normal_v20.slvs create mode 100644 test/constraint/pt_line_distance/normal_v22.slvs create mode 100644 test/constraint/pt_line_distance/reference.png create mode 100644 test/constraint/pt_line_distance/reference.slvs create mode 100644 test/constraint/pt_line_distance/reference_v20.slvs create mode 100644 test/constraint/pt_line_distance/reference_v22.slvs create mode 100644 test/constraint/pt_line_distance/test.cpp create mode 100644 test/constraint/pt_on_circle/negative_dia.slvs create mode 100644 test/constraint/pt_on_circle/normal.png create mode 100644 test/constraint/pt_on_circle/normal.slvs create mode 100644 test/constraint/pt_on_circle/normal_v20.slvs create mode 100644 test/constraint/pt_on_circle/normal_v22.slvs create mode 100644 test/constraint/pt_on_circle/test.cpp create mode 100644 test/constraint/pt_on_face/normal.png create mode 100644 test/constraint/pt_on_face/normal.slvs create mode 100644 test/constraint/pt_on_face/normal_v20.slvs create mode 100644 test/constraint/pt_on_face/normal_v22.slvs create mode 100644 test/constraint/pt_on_face/test.cpp create mode 100644 test/constraint/pt_on_line/free_in_3d_v20.slvs create mode 100644 test/constraint/pt_on_line/free_in_3d_v22.slvs create mode 100644 test/constraint/pt_on_line/left_free_in_3d.png create mode 100644 test/constraint/pt_on_line/left_free_in_3d.slvs create mode 100644 test/constraint/pt_on_line/normal.png create mode 100644 test/constraint/pt_on_line/normal.slvs create mode 100644 test/constraint/pt_on_line/normal_v20.slvs create mode 100644 test/constraint/pt_on_line/normal_v22.slvs create mode 100644 test/constraint/pt_on_line/right_free_in_3d.png create mode 100644 test/constraint/pt_on_line/right_free_in_3d.slvs create mode 100644 test/constraint/pt_on_line/test.cpp create mode 100644 test/constraint/pt_plane_distance/normal.png create mode 100644 test/constraint/pt_plane_distance/normal.slvs create mode 100644 test/constraint/pt_plane_distance/normal_v20.slvs create mode 100644 test/constraint/pt_plane_distance/normal_v22.slvs create mode 100644 test/constraint/pt_plane_distance/reference.png create mode 100644 test/constraint/pt_plane_distance/reference.slvs create mode 100644 test/constraint/pt_plane_distance/reference_v20.slvs create mode 100644 test/constraint/pt_plane_distance/reference_v22.slvs create mode 100644 test/constraint/pt_plane_distance/test.cpp create mode 100644 test/constraint/pt_pt_distance/free_in_3d.png create mode 100644 test/constraint/pt_pt_distance/free_in_3d.slvs create mode 100644 test/constraint/pt_pt_distance/free_in_3d_v20.slvs create mode 100644 test/constraint/pt_pt_distance/free_in_3d_v22.slvs create mode 100644 test/constraint/pt_pt_distance/normal.png create mode 100644 test/constraint/pt_pt_distance/normal.slvs create mode 100644 test/constraint/pt_pt_distance/normal_v20.slvs create mode 100644 test/constraint/pt_pt_distance/normal_v22.slvs create mode 100644 test/constraint/pt_pt_distance/reference.png create mode 100644 test/constraint/pt_pt_distance/reference.slvs create mode 100644 test/constraint/pt_pt_distance/reference_v20.slvs create mode 100644 test/constraint/pt_pt_distance/reference_v22.slvs create mode 100644 test/constraint/pt_pt_distance/test.cpp create mode 100644 test/constraint/same_orientation/normal.png create mode 100644 test/constraint/same_orientation/normal.slvs create mode 100644 test/constraint/same_orientation/normal_v20.slvs create mode 100644 test/constraint/same_orientation/normal_v22.slvs create mode 100644 test/constraint/same_orientation/same_group.png create mode 100644 test/constraint/same_orientation/same_group.slvs create mode 100644 test/constraint/same_orientation/test.cpp create mode 100644 test/constraint/symmetric/free_in_3d.png create mode 100644 test/constraint/symmetric/free_in_3d.slvs create mode 100644 test/constraint/symmetric/free_in_3d_v20.slvs create mode 100644 test/constraint/symmetric/free_in_3d_v22.slvs create mode 100644 test/constraint/symmetric/normal.png create mode 100644 test/constraint/symmetric/normal.slvs create mode 100644 test/constraint/symmetric/normal_v20.slvs create mode 100644 test/constraint/symmetric/normal_v22.slvs create mode 100644 test/constraint/symmetric/test.cpp create mode 100644 test/constraint/symmetric_horiz/normal.png create mode 100644 test/constraint/symmetric_horiz/normal.slvs create mode 100644 test/constraint/symmetric_horiz/normal_v20.slvs create mode 100644 test/constraint/symmetric_horiz/normal_v22.slvs create mode 100644 test/constraint/symmetric_horiz/test.cpp create mode 100644 test/constraint/symmetric_line/normal.png create mode 100644 test/constraint/symmetric_line/normal.slvs create mode 100644 test/constraint/symmetric_line/normal_v20.slvs create mode 100644 test/constraint/symmetric_line/normal_v22.slvs create mode 100644 test/constraint/symmetric_line/test.cpp create mode 100644 test/constraint/symmetric_vert/normal.png create mode 100644 test/constraint/symmetric_vert/normal.slvs create mode 100644 test/constraint/symmetric_vert/normal_v20.slvs create mode 100644 test/constraint/symmetric_vert/normal_v22.slvs create mode 100644 test/constraint/symmetric_vert/test.cpp create mode 100644 test/constraint/vertical/line.png create mode 100644 test/constraint/vertical/line.slvs create mode 100644 test/constraint/vertical/line_v20.slvs create mode 100644 test/constraint/vertical/line_v22.slvs create mode 100644 test/constraint/vertical/pt_pt.png create mode 100644 test/constraint/vertical/pt_pt.slvs create mode 100644 test/constraint/vertical/pt_pt_v20.slvs create mode 100644 test/constraint/vertical/pt_pt_v22.slvs create mode 100644 test/constraint/vertical/test.cpp create mode 100644 test/constraint/where_dragged/free_in_3d.png create mode 100644 test/constraint/where_dragged/free_in_3d.slvs create mode 100644 test/constraint/where_dragged/free_in_3d_v20.slvs create mode 100644 test/constraint/where_dragged/free_in_3d_v22.slvs create mode 100644 test/constraint/where_dragged/normal.png create mode 100644 test/constraint/where_dragged/normal.slvs create mode 100644 test/constraint/where_dragged/normal_v20.slvs create mode 100644 test/constraint/where_dragged/normal_v22.slvs create mode 100644 test/constraint/where_dragged/test.cpp create mode 100644 test/core/expr/test.cpp create mode 100644 test/core/locale/test.cpp create mode 100644 test/core/path/test.cpp create mode 100644 test/debugtool.cpp create mode 100644 test/group/link/normal.png create mode 100644 test/group/link/normal.slvs create mode 100644 test/group/link/normal_v20.slvs create mode 100644 test/group/link/normal_v22.slvs create mode 100644 test/group/link/rect_v20.slvs create mode 100644 test/group/link/test.cpp create mode 100644 test/group/translate_asy/normal.png create mode 100644 test/group/translate_asy/normal.slvs create mode 100644 test/group/translate_asy/normal_v22.slvs create mode 100644 test/group/translate_asy/test.cpp create mode 100644 test/group/translate_nd/normal.png create mode 100644 test/group/translate_nd/normal.slvs create mode 100644 test/group/translate_nd/normal_v22.slvs create mode 100644 test/group/translate_nd/test.cpp create mode 100644 test/harness.cpp create mode 100644 test/harness.h create mode 100644 test/request/arc_of_circle/normal.png create mode 100644 test/request/arc_of_circle/normal.slvs create mode 100644 test/request/arc_of_circle/normal_v20.slvs create mode 100644 test/request/arc_of_circle/normal_v22.slvs create mode 100644 test/request/arc_of_circle/test.cpp create mode 100644 test/request/circle/free_in_3d.png create mode 100644 test/request/circle/free_in_3d.slvs create mode 100644 test/request/circle/free_in_3d_dof.png create mode 100644 test/request/circle/free_in_3d_v20.slvs create mode 100644 test/request/circle/free_in_3d_v22.slvs create mode 100644 test/request/circle/normal.png create mode 100644 test/request/circle/normal.slvs create mode 100644 test/request/circle/normal_dof.png create mode 100644 test/request/circle/normal_v20.slvs create mode 100644 test/request/circle/normal_v22.slvs create mode 100644 test/request/circle/test.cpp create mode 100644 test/request/cubic/normal.png create mode 100644 test/request/cubic/normal.slvs create mode 100644 test/request/cubic/normal_v20.slvs create mode 100644 test/request/cubic/normal_v22.slvs create mode 100644 test/request/cubic/test.cpp create mode 100644 test/request/cubic_periodic/normal.png create mode 100644 test/request/cubic_periodic/normal.slvs create mode 100644 test/request/cubic_periodic/normal_v20.slvs create mode 100644 test/request/cubic_periodic/normal_v22.slvs create mode 100644 test/request/cubic_periodic/test.cpp create mode 100644 test/request/datum_point/normal.png create mode 100644 test/request/datum_point/normal.slvs create mode 100644 test/request/datum_point/normal_v20.slvs create mode 100644 test/request/datum_point/normal_v22.slvs create mode 100644 test/request/datum_point/test.cpp create mode 100644 test/request/image/drawing.png create mode 100644 test/request/image/linked.slvs create mode 100644 test/request/image/normal.slvs create mode 100644 test/request/image/test.cpp create mode 100644 test/request/line_segment/normal.png create mode 100644 test/request/line_segment/normal.slvs create mode 100644 test/request/line_segment/normal_v20.slvs create mode 100644 test/request/line_segment/normal_v22.slvs create mode 100644 test/request/line_segment/test.cpp create mode 100644 test/request/ttf_text/normal.png create mode 100644 test/request/ttf_text/normal.slvs create mode 100644 test/request/ttf_text/normal_v20.slvs create mode 100644 test/request/ttf_text/normal_v22.slvs create mode 100644 test/request/ttf_text/test.cpp create mode 100644 test/request/workplane/normal.png create mode 100644 test/request/workplane/normal.slvs create mode 100644 test/request/workplane/normal_v20.slvs create mode 100644 test/request/workplane/normal_v22.slvs create mode 100644 test/request/workplane/test.cpp create mode 100644 wishlist.txt diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..5cb786f --- /dev/null +++ b/.clang-format @@ -0,0 +1,41 @@ +--- +# Things explicitly enumerated in CONTRIBUTING.md +IndentWidth: 4 +UseTab: Never +SpaceBeforeParens: Never +BreakBeforeBraces: Attach +ColumnLimit: 100 +# Docs say 100, but some places look more like 80. +#ColumnLimit: 80 + +# Based on minimizing diff when applying clang-format +AccessModifierOffset: -4 +AlignConsecutiveAssignments: true +AlignEscapedNewlines: DontAlign +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: true +AllowShortLoopsOnASingleLine: false +AlwaysBreakTemplateDeclarations: Yes # MultiLine +BreakConstructorInitializers: BeforeColon +DerivePointerAlignment: true +FixNamespaceComments: true +IndentPPDirectives: AfterHash +MaxEmptyLinesToKeep: 2 +NamespaceIndentation: Inner +SpaceAfterTemplateKeyword: false + +# No way to remove all space around operators as seen in much of the code I looked at. +#SpaceBeforeAssignmentOperators: false + +# Only seen some of the time (mostly just variables, not functions) +# but clang-format only has a true/false +#AlignConsecutiveDeclarations: true + + +# Would be nice to turn on eventually, maybe? +SortIncludes: false +SortUsingDeclarations: false + +# Hard to tell what the desired config here was. +# AllowShortFunctionsOnASingleLine: Inline +AllowShortFunctionsOnASingleLine: None diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8447d0e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,275 @@ +Changelog +========= + +3.0 +--- + +New sketch features: + * New intersection boolean operation for solid models. + * New groups, revolution and helical extrusion. + * Extrude, lathe, translate and rotate groups can use the "assembly" + boolean operation, to increase performance. + * The solid model of extrude and lathe groups can be suppressed, + for splitting a single model in multiple parts to export, + or if only the generated entities are desired, without the mesh. + * Translate and rotate groups can create n-dimensional arrays using + the "difference" and "assembly" boolean operations. + * A new sketch in workplane group can be created based on existing workplane. + * TTF text request has two additional points on the right side, which allow + constraining the width of text. + * Image requests can now be created, similar to TTF text requests. + This replaces the "style → background image" feature. + * Irrelevant points (e.g. arc center point) are not counted when estimating + the bounding box used to compute chord tolerance. + * When adding a constraint which has a label and is redundant with another + constraint, the constraint is added as a reference, avoiding an error. + * Datum points can be copied and pasted. + * "Split Curves at Intersection" can now split curves at point lying on curve, + not just at intersection of two curves. + * Property browser now shows amount of degrees of freedom in group list. + It also shows a yellow "err" if the sketch has problems (e.g. self + intersecting) that would propagate in subsequent groups. + +New constraint features: + * When dragging an arc or rectangle point, it will be automatically + constrained to other points with a click. + * When selecting a constraint, the requests it constraints can be selected + in the text window. + * When selecting an entity, the constraints applied to it can be selected + in the text window. + * Distance constraint labels can now be formatted to use SI prefixes. + Values are edited in the configured unit regardless of label format. + * When creating a constraint, if an exactly identical constraint already + exists, it is now selected instead of adding a redundant constraint. + * It is now possible to turn off automatic creation of horizontal/vertical + constraints on line segments. + * Automatic creation of constraints no longer happens if the constraint + would have been redundant with other ones. + * New option to open the constraint editor for newly created constraints + with a value. + +New export/import features: + * Link IDF circuit boards in an assembly (.emn files) + * Three.js: allow configuring projection for exported model, and initially + use the current viewport projection. + * Wavefront OBJ: a material file is exported alongside the model, containing + mesh color information. + * DXF/DWG: 3D DXF files are imported as construction entities, in 3d. + * [ADDED 2019-02-25](https://github.com/solvespace/solvespace/pull/384) and [REMOVED 2020-11-13](https://github.com/solvespace/solvespace/issues/795): + Q3D: [Q3D](https://github.com/q3k/q3d/) triangle meshes can now be + exported. This format allows to easily hack on triangle mesh data created + in SolveSpace, supports colour information and is more space efficient than + most other formats. + * VRML (WRL) triangle meshes can now be exported, useful for e.g. [KiCAD](http://kicad.org). + * Export 2d section: custom styled entities that lie in the same + plane as the exported section are included. + +New rendering features: + * The "Show/hide hidden lines" button is now a tri-state button that allows + showing all lines (on top of shaded mesh), stippling occluded lines + or not drawing them at all. + * The "Show/hide outlines" button is now independent from "Show/hide edges". + +New measurement/analysis features: + * New choice for base unit, meters. + * New command for measuring total length of selected entities, + "Analyze → Measure Perimeter". + * New command for measuring center of mass, with live updates as the sketch + changes, "Analyze → Center of Mass". + * New option for displaying areas of closed contours. + * When calculating volume of the mesh, volume of the solid from the current + group is now shown alongside total volume of all solids. + * When calculating area, and faces are selected, calculate area of those faces + instead of the closed contour in the sketch. + * When selecting a point and a line, projected distance to current + workplane is displayed. + +Other new features: + * Added ExportBackgroundColor in configuration for EPS, PDF, and SVG files. + * Improvements to the text window for selected entities and constraints. + * Ambient light source added in text window to allow flat shaded renderings. + * New command-line interface, for batch exporting and more. + * The graphical interface now supports HiDPI screens on every OS. + * New option to lock Z axis to be always vertical, like in SketchUp. + * New button to hide all construction entities. + * New link to match the on-screen size of the sketch with its actual size, + "view → set to full scale". + * When zooming to fit, constraints are also considered. + * Ctrl-clicking entities now deselects them, as the inverse of clicking. + * When clicking on an entity that shares a place with other entities, + the entity from the current group is selected. + * When dragging an entity that shares a place with other entities, + the entity from a request is selected. For example, dragging a point on + a face of an extrusion coincident with the source sketch plane will + drag the point from the source sketch. + * The default font for TTF text is now Bitstream Vera Sans, which is + included in the resources such that it is available on any OS. + * In expressions, numbers can contain the digit group separator, "_". + * The "=" key is bound to "Zoom In", like "+" key. + * The numpad decimal separator key is bound to "." regardless of locale. + * On Windows, full-screen mode is implemented. + * On Linux, native file chooser dialog can be used. + * New edit menu items "Line Styles", "View Projection" and "Configuration" + that are shortcuts to the respective configuration screens. + * New cmake build options using -DENABLE_OPENMP=yes and -DENABLE_LTO=yes + to enable support for multi-threading and link-time optimization. + * "Shift+Scroll" for ten times finer zoom. + +Bugs fixed: + * Fixed broken --view options for command line thumbnail image creation. + * Some errors in Triangulation of surfaces. + * Some NURNS boolean operations that failed particularly on surfaces + created with Lathe, Revolve, or Helix. + * Segfault in Remove Spline Point context menu. + * A point in 3d constrained to any line whose length is free no longer + causes the line length to collapse. + * Curve-line constraints (in 3d), parallel constraints (in 3d), and + same orientation constraints are more robust. + * Adding some constraints (vertical, midpoint, etc) twice errors out + immediately, instead of later and in a confusing way. + * Constraining a newly placed point to a hovered entity does not cause + spurious changes in the sketch. + * Points highlighted with "Analyze → Show Degrees of Freedom" are drawn + on top of all other geometry. + * A step rotate/translate group using a group forced to triangle mesh + as a source group also gets forced to triangle mesh. + * Paste Transformed with a negative scale does not invert arcs. + * The tangent arc now modifies the original entities instead of deleting + them, such that their constraints are retained. + * When linking a sketch file, missing custom styles are now imported from + the linked file. + * 3Dconnexion SpaceMouse should now work (on Windows and macOS X). + * Improved NURBS boolean operations on curved surfaces in some cases. + * Show only usable fonts in the font selector. + +2.x +--- + +Bug fixes: + * Do not crash when changing an unconstrained lathe group between + union and difference modes. + +2.3 +--- + +Bug fixes: + * Do not crash when applying a symmetry constraint to two points. + * Fix TTF font metrics again (properly this time). + * Fix the "draw back faces in red" option. + * Fix export of wireframe as 3D DXF. + * Various minor crashes. + +2.2 +--- + +Other new features: + * OS X: support 3Dconnexion devices (SpaceMouse, SpaceNavigator, etc). + * GTK: files with uppercase extensions can be opened. + +Bug fixes: + * Do not remove autosaves after successfully opening a file, preventing + data loss in case of two abnormal terminations in a row. + * Do not crash when changing autosave interval. + * Unbreak the "Show degrees of freedom" command. + * Three.js: correctly respond to controls when browser zoom is used. + * OS X: do not completely hide main window when defocused. + * GTK: unbreak 3Dconnexion support. + * When pasting transformed entities, multiply constraint values by scale. + * Fix TTF font metrics (restore the behavior from version 2.0). + * Forcibly show the current group once we start a drawing operation. + * DXF export: always declare layers before using them. + * Do not truncate operations on selections to first 32 selected entities. + * Translate and rotate groups inherit the "suppress solid model" setting. + * DXF: files with paths containing non-ASCII or spaces can be exported + or imported. + * Significantly improved performance when dragging an entity. + * Various crashes and minor glitches. + +2.1 +--- + +New sketch features: + * Lathe groups create circle and face entities. + * New toolbar button for creating lathe groups. + * Chord tolerance is separated into two: display chord tolerance (specified + in percents, relative to model bounding box), and export chord tolerance + (specified in millimeters as absolute value). + * Bezier spline points can be added and removed after the spline is created. + * When an unconstrained extrusion is switched between "union" and + "difference", its normal is flipped. + * Groups can be added in the middle of the stack. Note that this results + in files incompatible with version 2.0. + * Active group can be removed. + * Removing an imported group does not cause all subsequent groups to also + be removed. + * When a new group with a solid is created, the color is taken from + a previous group with a solid, if any. + * Entities in a newly active group do not become visible. + * When entities are selected, "Zoom to fit" zooms to fit only these + entities and not the entire sketch. + * Zero-length edges are reported with a "zero-length error", not + "points not all coplanar". + +New constraint features: + * Height of the font used for drawing constraint labels can be changed. + * New constraint, length difference, placed with J. + (Patch by Peter Ruevski) + * Horizontal/vertical constraints are automatically added if a line segment + is close enough to being horizontal/vertical. This can be disabled by + holding Ctrl. + * Reference dimensions and angles can be placed with Shift+D and Shift+N. + * Copying and pasting entities duplicates any constraints that only involve + entities in the clipboard, as well as selected comments. + * Diameter constraints can be shown as radius. + * The "pi" identifier can be used in expressions. + * Constraint labels can be snapped to grid. + * Integer angles are displayed without trailing zeroes. + * Angle constraints have proper reference lines and arrowheads. + * Extension lines are drawn for point-line distance constraints. + +New solver features: + * Sketches with redundant and unsolvable constraints are distinguished. + * New group setting, "allow redundant constraints". Note that it makes + the solver less stable. + +New rendering and styling features: + * New line style parameter: stippling, based on ISO 128. + * Outlines of solids can be drawn in a particular style (by default, thick + lines) controlled by the "Show outline of solid model" button. + * Occluded edges can be drawn in a particular style (by default, stippled + with short dashes) controlled by the "Show hidden lines" button. + * Solids can be made transparent. + +New export/import features: + * The old "import" command (for .slvs files) is renamed to "link". + * If a linked .slvs file is not found, first the relative path recorded + in the .slvs file is checked and then the absolute path; this is + an inversion of the previously used order. If it is still not found, + a dialog appears offering to locate it. + * DXF and DWG files can be imported, with point-coincident, horizontal and + vertical constraints automatically inferred from geometry, and distance + and angle constraints created when a dimension placed against geometry + exists. + * Triangle mesh can be exported for viewing in the browser through WebGL. + * Export dialogs remember the last file format used, and preselect it. + * Exported DXF files have exact circles, arcs and splines instead of + a piecewise linear approximation (unless hidden line removal was needed). + * Exported DXF files preserve color and line thickness. + * In exported DXF files, constraints are represented as DXF dimensions, + instead of piecewise linear geometry. + * When exporting 2d views, overlapping lines are removed. + +Other new features: + * Native Linux (GTK 2 and GTK 3) and Mac OS X ports. + * Automatically save and then restore sketches if SolveSpace crashes. + (Patch by Marc Britten) + * Unicode is supported everywhere (filenames, group names, TTF text, + comments), although RTL scripts and scripts making heavy use of ligatures + are not rendered correctly. + * The vector font is grid-fitted when rendered on screen to make it easier + to read regardless of its size. + +2.0 +--- + +Initial public release. diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..1294878 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,397 @@ +# cmake configuration + +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) + message(FATAL_ERROR + "In-tree builds are not supported; please perform an out-of-tree build:\n" + " rm -rf CMakeCache.txt CMakeFiles/\n" + " mkdir build && cd build && cmake ..") +endif() + +cmake_minimum_required(VERSION 3.7.2 FATAL_ERROR) +if(NOT CMAKE_VERSION VERSION_LESS 3.11.0) + cmake_policy(VERSION 3.11.0) +endif() +if(NOT CMAKE_VERSION VERSION_LESS 3.9) + # LTO/IPO with non-Intel compilers on Linux requires policy CMP0069 to be set to NEW. + # Set it explicitly until cmake_minimum_required is raised to >= 3.9. + cmake_policy(SET CMP0069 NEW) +endif() +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} + "${CMAKE_SOURCE_DIR}/cmake/") +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED YES) + +# for /MT on MSVC +set(CMAKE_USER_MAKE_RULES_OVERRIDE + "${CMAKE_SOURCE_DIR}/cmake/c_flag_overrides.cmake") +set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX + "${CMAKE_SOURCE_DIR}/cmake/cxx_flag_overrides.cmake") + +if(APPLE OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") +endif() + +# project + +# NOTE TO PACKAGERS: The embedded git commit hash is critical for rapid bug triage when the builds +# can come from a variety of sources. If you are mirroring the sources or otherwise build when +# the .git directory is not present, please comment the following line: +include(GetGitCommitHash) +# and instead uncomment the following, adding the complete git hash of the checkout you are using: +# set(GIT_COMMIT_HASH 0000000000000000000000000000000000000000) + +project(solvespace) +set(solvespace_VERSION_MAJOR 3) +set(solvespace_VERSION_MINOR 0) +string(SUBSTRING "${GIT_COMMIT_HASH}" 0 8 solvespace_GIT_HASH) + +set(ENABLE_GUI ON CACHE BOOL + "Whether the graphical interface is enabled") +set(ENABLE_CLI ON CACHE BOOL + "Whether the command line interface is enabled") +set(ENABLE_TESTS ON CACHE BOOL + "Whether the test suite will be built and run") +set(ENABLE_COVERAGE OFF CACHE BOOL + "Whether code coverage information will be collected") +set(ENABLE_SANITIZERS OFF CACHE BOOL + "Whether to enable Clang's AddressSanitizer and UndefinedBehaviorSanitizer") +set(ENABLE_OPENMP OFF CACHE BOOL + "Whether geometric operations will be parallelized using OpenMP") +set(ENABLE_LTO OFF CACHE BOOL + "Whether interprocedural (global) optimizations are enabled") + +set(OPENGL 3 CACHE STRING "OpenGL version to use (one of: 1 3)") + +set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) +set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin) +if("${CMAKE_GENERATOR}" STREQUAL "Xcode") + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $<1:${CMAKE_BINARY_DIR}/bin>) +endif() + +if(NOT CMAKE_C_COMPILER_ID STREQUAL CMAKE_CXX_COMPILER_ID) + message(FATAL_ERROR "C and C++ compilers should be supplied by the same vendor") +endif() + +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) + # GCC 4.8/4.9 ship with broken but present . meh. + message(FATAL_ERROR "GCC 5.0+ is required") + endif() +endif() + +# common compiler flags +include(CheckCXXCompilerFlag) + +set(FILE_PREFIX_MAP "-ffile-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=.") +check_cxx_compiler_flag("${FILE_PREFIX_MAP}" HAS_FILE_PREFIX_MAP) +if(HAS_FILE_PREFIX_MAP) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FILE_PREFIX_MAP}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FILE_PREFIX_MAP}") +endif() + +if(MINGW) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") +endif() + +# Ensure that all platforms use 64-bit IEEE floating point operations for consistency; +# this is most important for the testsuite, which compares savefiles directly +# and depends on consistent rounding of intermediate results. +if(CMAKE_SYSTEM_PROCESSOR STREQUAL "i686" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "X86") + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set(FLOAT_FLAGS "-mfpmath=sse -msse2") + elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(FLOAT_FLAGS "-msse2") + endif() + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLOAT_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLOAT_FLAGS}") +endif() + +if(ENABLE_LTO) + include(CheckIPOSupported) + check_ipo_supported() + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) +endif() + +if(ENABLE_OPENMP) + find_package( OpenMP REQUIRED ) + if(OPENMP_FOUND) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + message(STATUS "found OpenMP, compiling with flags: " ${OpenMP_CXX_FLAGS} ) + endif() +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + set(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed ${CMAKE_EXE_LINKER_FLAGS}") +endif() + +if(ENABLE_SANITIZERS) + if(NOT SANITIZERS) + set(SANITIZERS "address;undefined") + endif() + + if("thread" IN_LIST SANITIZERS) + list(REMOVE_ITEM SANITIZERS "thread") + list(APPEND SANITIZE_OPTIONS thread) + endif() + if("address" IN_LIST SANITIZERS) + list(REMOVE_ITEM SANITIZERS "address") + list(APPEND SANITIZE_OPTIONS address) + endif() + if("undefined" IN_LIST SANITIZERS) + list(REMOVE_ITEM SANITIZERS "undefined") + list(APPEND SANITIZE_OPTIONS alignment bounds) + list(APPEND SANITIZE_OPTIONS shift signed-integer-overflow integer-divide-by-zero) + list(APPEND SANITIZE_OPTIONS null bool enum) + list(APPEND SANITIZE_OPTIONS return) + endif() + if(SANITIZERS) + message(FATAL_ERROR "Unknown sanitizer(s) ${SANITIZERS}") + else() + message(STATUS "Using sanitizer options ${SANITIZE_OPTIONS}") + endif() + + string(REPLACE ";" "," SANITIZE_OPTIONS "${SANITIZE_OPTIONS}") + + if (NOT APPLE) + set(SANITIZE_FLAGS "-O1 -fsanitize=${SANITIZE_OPTIONS} -fno-sanitize-recover=address,undefined") + else() + set(SANITIZE_FLAGS "-O1 -fsanitize=${SANITIZE_OPTIONS}") + endif() + + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls") + elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fuse-ld=gold") + else() + message(FATAL_ERROR "Sanitizers are only available when using GCC or Clang") + endif() + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZE_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS}") +endif() + +# common dependencies + +if(APPLE) + set(CMAKE_FIND_FRAMEWORK LAST) +endif() + +message(STATUS "Using in-tree libdxfrw") +add_subdirectory(extlib/libdxfrw) + +message(STATUS "Using in-tree mimalloc") +set(MI_OVERRIDE OFF CACHE BOOL "") +set(MI_BUILD_SHARED OFF CACHE BOOL "") +set(MI_BUILD_OBJECT OFF CACHE BOOL "") +set(MI_BUILD_TESTS OFF CACHE BOOL "") +add_subdirectory(extlib/mimalloc EXCLUDE_FROM_ALL) +set(MIMALLOC_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/extlib/mimalloc/include) + +if(WIN32 OR APPLE) + # On Win32 and macOS we use vendored packages, since there is little to no benefit + # to trying to find system versions. In particular, trying to link to libraries from + # Homebrew or macOS system libraries into the .app file is highly likely to result + # in incompatibilities after upgrades. + + include(FindVendoredPackage) + include(AddVendoredSubdirectory) + + set(FORCE_VENDORED_ZLIB ON) + set(FORCE_VENDORED_PNG ON) + set(FORCE_VENDORED_Freetype ON) + + find_vendored_package(ZLIB zlib + ZLIB_LIBRARY zlibstatic + ZLIB_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/extlib/zlib) + list(APPEND ZLIB_INCLUDE_DIR ${CMAKE_BINARY_DIR}/extlib/zlib) + + find_vendored_package(PNG libpng + SKIP_INSTALL_ALL ON + PNG_LIBRARY png_static + PNG_PNG_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/extlib/libpng) + list(APPEND PNG_PNG_INCLUDE_DIR ${CMAKE_BINARY_DIR}/extlib/libpng) + + find_vendored_package(Freetype freetype + WITH_ZLIB OFF + WITH_BZip2 OFF + WITH_PNG OFF + WITH_HarfBuzz OFF + FREETYPE_LIBRARY freetype + FREETYPE_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extlib/freetype/include) + + message(STATUS "Using in-tree pixman") + add_vendored_subdirectory(extlib/pixman) + set(PIXMAN_FOUND YES) + set(PIXMAN_LIBRARY pixman) + set(PIXMAN_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extlib/pixman/pixman) + list(APPEND PIXMAN_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/extlib/pixman/pixman) + + message(STATUS "Using in-tree cairo") + add_vendored_subdirectory(extlib/cairo) + set(CAIRO_FOUND YES) + set(CAIRO_LIBRARIES cairo) + set(CAIRO_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extlib/cairo/src) + list(APPEND CAIRO_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/extlib/cairo/src) +else() + # On Linux and BSDs we're a good citizen and link to system libraries. + find_package(Backtrace) + find_package(PkgConfig REQUIRED) + find_package(ZLIB REQUIRED) + find_package(PNG REQUIRED) + find_package(Freetype REQUIRED) + pkg_check_modules(CAIRO REQUIRED cairo) +endif() + +# GUI dependencies + +if(ENABLE_GUI) + if(WIN32) + if(OPENGL STREQUAL "3") + message(STATUS "Using in-tree ANGLE") + set(ANGLE_STATIC ON CACHE INTERNAL "") + set(ANGLE_ENABLE_D3D9 ON CACHE INTERNAL "") + set(ANGLE_ENABLE_D3D11 ON CACHE INTERNAL "") + set(ANGLE_ENABLE_OPENGL ON CACHE INTERNAL "") + set(ANGLE_ENABLE_ESSL ON CACHE INTERNAL "") + set(ANGLE_ENABLE_GLSL ON CACHE INTERNAL "") + set(ANGLE_ENABLE_HLSL ON CACHE INTERNAL "") + add_vendored_subdirectory(extlib/angle) + set(OPENGL_LIBRARIES EGL GLESv2) + set(OPENGL_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/extlib/angle/include) + else() + find_package(OpenGL REQUIRED) + endif() + + if(MSVC AND ${CMAKE_SIZEOF_VOID_P} EQUAL 4) + message(STATUS "Using prebuilt SpaceWare") + set(SPACEWARE_FOUND TRUE) + set(SPACEWARE_INCLUDE_DIR + "${CMAKE_SOURCE_DIR}/extlib/si") + set(SPACEWARE_LIBRARIES + "${CMAKE_SOURCE_DIR}/extlib/si/siapp.lib") + endif() + elseif(APPLE) + find_package(OpenGL REQUIRED) + find_library(APPKIT_LIBRARY AppKit REQUIRED) + else() + find_package(OpenGL REQUIRED) + find_package(SpaceWare) + pkg_check_modules(FONTCONFIG REQUIRED fontconfig) + pkg_check_modules(JSONC REQUIRED json-c) + pkg_check_modules(GTKMM REQUIRED gtkmm-3.0>=3.18 pangomm-1.4 x11) + endif() +endif() + +# code coverage + +if(ENABLE_COVERAGE) + if(CMAKE_CXX_COMPILER_ID STREQUAL GNU) + find_program(GCOV gcov) + elseif(CMAKE_CXX_COMPILER_ID MATCHES Clang) + find_program(LLVM_COV llvm-cov) + + if(LLVM_COV) + set(GCOV ${CMAKE_CURRENT_BINARY_DIR}/llvm-gcov.sh) + file(WRITE ${GCOV} "#!/bin/sh -e\n${LLVM_COV} gcov $*") + execute_process(COMMAND chmod +x ${GCOV}) + endif() + endif() + + find_program(LCOV lcov) + find_program(GENHTML genhtml) + if(NOT GCOV OR NOT LCOV OR NOT GENHTML) + message(FATAL_ERROR "gcov/llvm-cov and lcov are required for producing coverage reports") + endif() +endif() + +# translations + +find_program(XGETTEXT xgettext) +find_program(MSGINIT msginit) +find_program(MSGMERGE msgmerge) +if(XGETTEXT AND MSGINIT AND MSGMERGE) + set(HAVE_GETTEXT TRUE) +else() + message(WARNING "Gettext not found, translations will not be updated") + set(HAVE_GETTEXT FALSE) +endif() + +# solvespace-only compiler flags + +if(WIN32) + add_definitions( + -D_CRT_SECURE_NO_DEPRECATE + -D_CRT_SECURE_NO_WARNINGS + -D_SCL_SECURE_NO_WARNINGS + -DWINVER=0x0501 + -D_WIN32_WINNT=0x0501 + -D_WIN32_IE=_WIN32_WINNT + -DISOLATION_AWARE_ENABLED + -DWIN32 + -DWIN32_LEAN_AND_MEAN + -DUNICODE + -D_UNICODE + -DNOMINMAX + -D_USE_MATH_DEFINES) +endif() + +if(MSVC) + # Many versions of MSVC do not have the (C99) inline keyword, instead + # they have their own __inline; this breaks `static inline` functions. + # We do not want to care and so we fix this with a definition. + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Dinline=__inline") + # Same for the (C99) __func__ special variable; we use it only in C++ code. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D__func__=__FUNCTION__") + + # We rely on these /we flags. They correspond to the GNU-style flags below as + # follows: /w4062=-Wswitch + set(WARNING_FLAGS "${WARNING_FLAGS} /we4062") +endif() + +if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(WARNING_FLAGS "-Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers") + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(WARNING_FLAGS "${WARNING_FLAGS} -Wfloat-conversion") + endif() + # We rely on these -Werror flags. + set(WARNING_FLAGS "${WARNING_FLAGS} -Werror=switch") +endif() + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}") + +if(WIN32) + set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -l0") +endif() + +if(ENABLE_COVERAGE) + if(NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR + CMAKE_CXX_COMPILER_ID MATCHES "Clang")) + message(FATAL_ERROR "Code coverage is only available on GCC and Clang") + endif() + + if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + message(FATAL_ERROR "Code coverage produces reliable results only on Debug builds") + endif() + + # With -fexceptions, every call becomes a branch. While technically accurate, + # this is not useful for us. + set(COVERAGE_FLAGS -fno-exceptions --coverage) + set(COVERAGE_LIBRARY --coverage) +endif() + +# application components + +add_subdirectory(res) +add_subdirectory(src) +add_subdirectory(exposed) +if(ENABLE_TESTS) + add_subdirectory(test) +endif() +if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + add_subdirectory(bench) +else() + message(STATUS "Benchmarking disabled in debug builds.") +endif() diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..aee8bb5 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,291 @@ +Contributing to SolveSpace +========================== + +Contributing bug reports +------------------------ + +Bug reports are always welcome! When reporting a bug, please include the following: + + * The version of SolveSpace (use Help → About...); + * The operating system; + * The save file that reproduces the incorrect behavior, or, if trivial or impossible, + instructions for reproducing it. + +GitHub does not allow attaching `*.slvs` files, but it does allow attaching `*.zip` files, +so any savefiles should first be archived. + +Licensing +--------------- + +SolveSpace is licensed under the GPLv3 and any contributions must be made available +under the terms of that license. + +Contributing translations +------------------------- + +To contribute a translation, not a lot is necessary—at a minimum, you need to be able +to edit .po files with a tool such as [poedit](https://poedit.net/). Once you have +such a tool installed, take `res/messages.pot` and start translating! + +However, if you want to see your translation in action, a little more work is necessary. +First, you need to be able to build SolveSpace; see [README](README.md). After that: + + * Copy `res/messages.pot` to `res/locales/xx_YY.po`, where `xx` is an ISO 639-1 + country code, and `YY` is an ISO 3166-1 language code. + * Add a line `xx-YY,LCID,Name` to `res/locales.txt`, where `xx-YY` have the same + meaning as above, `LCID` is a Windows Language Code Identifier ([MS-LCID][] + has a complete list), and `Name` is the full name of your locale in your language. + * Add `locales/xx_YY.po` in `res/CMakeLists.txt`—search for `locales/en_US.po` + to see where it should be added. + +You're done! Recompile SolveSpace and you should be able to select your translation +via Help → Language. + +[MS-LCID]: https://msdn.microsoft.com/en-us/library/cc233965.aspx + +Contributing code +----------------- + +SolveSpace is written in C++, and currently targets all compilers compliant with C++11. +This includes GCC 5 and later, Clang 3.3 and later, and Visual Studio 12 (2013) and later. + +### High-level conventions + +#### Portability + +SolveSpace aims to consist of two general parts: a fully portable core, and platform-specific +UI and support code. Anything outside of `src/platform/` should only use standard C++11, +and rely on `src/platform/unixutil.cpp` and `src/platform/w32util.cpp` to interact with +the OS where this cannot be done through the C++11 standard library. + +#### Libraries + +SolveSpace primarily relies on the C++11 STL. STL has well-known drawbacks, but is also +widely supported, used, and understood. SolveSpace also includes a fair amount of use of +bespoke containers List and IdList; these provide STL iterators, and can be used when +convenient, such as when reusing other code. + +One notable departure here is the STL I/O threads. SolveSpace does not use STL I/O threads +for two reasons: (i) the interface is borderline unusable, and (ii) on Windows it is not +possible to open files with Unicode paths through STL. + +When using external libraries (other than to access platform features), the libraries +should satisfy the following conditions: + + * Portable, and preferably not interacting with the platform at all; + * Can be included as a CMake subproject, to facilitate Windows, Android, etc. builds; + * Use a license less restrictive than GPL (BSD/MIT, Apache2, MPL, etc.) + +#### String encoding + +Internally, SolveSpace exclusively stores and uses UTF-8 for all purposes; any `std::string` +may be assumed to be encoded in UTF-8. On Windows, UTF-8 strings are converted to and from +wide strings at the boundary; see [UTF-8 Everywhere][utf8] for details. + +[utf8]: http://utf8everywhere.org/ + +#### String formatting + +For string formatting, a wrapper around `sprintf`, `ssprintf`, is used. A notable +pitfall when using it is trying to pass an `std::string` argument without first converting +it to a C string with `.c_str()`. + +#### Filesystem access + +For filesystem access, the C standard library is used. The `ssfopen` and `ssremove` +wrappers are provided that accept UTF-8 encoded paths. + +#### Assertions + +To ensure that internal invariants hold, the `ssassert` function is used, e.g. +`ssassert(!isFoo, "Unexpected foo condition");`. Unlike the standard `assert` function, +the `ssassert` function is always enabled, even in release builds. It is more valuable +to discover a bug through a crash than to silently generate incorrect results, and crashes +do not result in losing more than a few minutes of work thanks to the autosave feature. + +### Use of C++ features + +The conventions described in this section should be used for all new code, but there is a lot +of existing code in SolveSpace that does not use them. This is fine; don't touch it if it works, +but if you need to modify it anyway, might as well modernize it. + +#### Exceptions + +Exceptions are not used primarily because SolveSpace's testsuite uses measurement +of branch coverage, important for the critical parts such as the geometric kernel. +Every function call with exceptions enabled introduces a branch, making branch coverage +measurement useless. + +#### Operator overloading + +Operator overloading is not used primarily for historical reasons. Instead, method such +as `Plus` are used. + +#### Member visibility + +Member visibility is not used for implementation hiding. Every member field and function +is `public`. + +#### Constructors + +Constructors are not used for initialization, chiefly because indicating an error +in a constructor would require throwing an exception, nor does it use constructors for +blanket zero-initialization because of the performance impact of doing this for common +POD classes like `Vector`. + +Instances can be zero-initialized using the aggregate-initialization syntax, e.g. `Foo foo = {};`. +This zero-initializes the POD members and default-initializes the non-POD members, generally +being an equivalent of `memset(&foo, 0, sizeof(foo));` but compatible with STL containers. + +#### Input- and output-arguments + +Functions accepting an input argument take it either by-value (`Vector v`) or +by-const-reference (`const Vector &v`). Generally, passing by-value is safer as the value +cannot be aliased by something else, but passing by-const-reference is faster, as a copy is +eliminated. Small values should always be passed by-value, and otherwise functions that do not +capture pointers into their arguments should take them by-const-reference. Use your judgement. + +Functions accepting an output argument always take it by-pointer (`Vector *v`). This makes +it immediately visible at the call site as it is seen that the address is taken. Arguments +are never passed by-reference, except when needed for interoperability with STL, etc. + +#### Iteration + +`foreach`-style iteration is preferred for both STL and `List`/`IdList` containers as it indicates +intent clearly, as opposed to `for`-style. + +#### Const correctness + +Functions that do not mutate `this` should be marked as `const`; when iterating a collection +without mutating any of its elements, `for(const Foo &elem : collection)` is preferred to indicate +the intent. + +### Coding style + +Code is formatted by the following rules: + + * Code is indented using 4 spaces, with no trailing spaces, and lines are wrapped + at 100 columns; + * Braces are placed at the end of the line with the declaration or control flow statement; + * Braces are used with every control flow statement, even if there is only one statement + in the body; + * There is no space after control flow keywords (`if`, `while`, etc.); + * Identifiers are formatted in camel case; variables start with a lowercase letter + (`exampleVariable`) and functions start with an uppercase letter (`ExampleFunction`). + +For example: + +```c++ +std::string SolveSpace::Dirname(std::string filename) { + int slash = filename.rfind(PATH_SEP); + if(slash >= 0) { + return filename.substr(0, slash); + } + + return ""; +} +``` + +If you install [clang-format][], this style can be automatically applied by staging your changes +with `git add -u`, running `git clang-format`, and staging any changes it made again. + +[clang-format]: https://clang.llvm.org/docs/ClangFormat.html + +Debugging code +-------------- + +SolveSpace releases are thoroughly tested but sometimes they contain crash +bugs anyway. The reason for such crashes can be determined only if the executable +was built with debug information. + +### Debugging a released version + +The Linux distributions usually include separate debug information packages. +On a Debian derivative (e.g. Ubuntu), these can be installed with: + + apt-get install solvespace-dbg + +The macOS releases include the debug information, and no further action +is needed. + +The Windows releases include the debug information on the GitHub +[release downloads page](https://github.com/solvespace/solvespace/releases). + +### Debugging a custom build + +If you are building SolveSpace yourself on macOS, use the XCode +CMake generator, then open the project in XCode as usual, select +the Debug build scheme, and build the project: + + cd build + cmake .. -G Xcode [other cmake args...] + +If you are building SolveSpace yourself on any Unix-like platform, +configure or re-configure SolveSpace to produce a debug build, and +then build it: + + cd build + cmake .. -DCMAKE_BUILD_TYPE=Debug [other cmake args...] + make + +If you are building SolveSpace yourself using the Visual Studio IDE, +select Debug from the Solution Configurations list box on the toolbar, +and build the solution. + +### Debugging with gdb + +gdb is a debugger that is mostly used on Linux. First, run SolveSpace +under debugging: + + gdb [path to solvespace executable] + (gdb) run + +Then, reproduce the crash. After the crash, attach the output in +the console, as well as output of the following gdb commands to +a bug report: + + (gdb) backtrace + (gdb) info locals + +If the crash is not easy to reproduce, please generate a core file, +which you can use to resume the debugging session later, and provide +any other information that is requested: + + (gdb) generate-core-file + +This will generate a large file called like `core.1234` in the current +directory; it can be later re-loaded using `gdb --core core.1234`. + +### Debugging with lldb + +lldb is a debugger that is mostly used on macOS. First, run SolveSpace +under debugging: + + lldb [path to solvespace executable] + (lldb) run + +Then, reproduce the crash. After the crash, attach the output in +the console, as well as output of the following gdb commands to +a bug report: + + (lldb) backtrace all + (lldb) frame variable + +If the crash is not easy to reproduce, please generate a core file, +which you can use to resume the debugging session later, and provide +any other information that is requested: + + (lldb) process save-core "core" + +This will generate a large file called `core` in the current +directory; it can be later re-loaded using `lldb -c core`. + +### Debugging GUI-related bugs on Linux + +There are several environment variables available that make crashes +earlier and errors more informative. Before running SolveSpace, run +the following commands in your shell: + + export G_DEBUG=fatal_warnings + export LIBGL_DEBUG=1 + export MESA_DEBUG=1 diff --git a/COPYING.txt b/COPYING.txt new file mode 100644 index 0000000..a737dcf --- /dev/null +++ b/COPYING.txt @@ -0,0 +1,675 @@ + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md new file mode 100644 index 0000000..6e575a5 --- /dev/null +++ b/README.md @@ -0,0 +1,257 @@ +SolveSpace Logo + +SolveSpace +========== +[![Build Status](https://github.com/solvespace/solvespace/workflows/CD/badge.svg)](https://github.com/solvespace/solvespace/actions) +[![solvespace](https://snapcraft.io/solvespace/badge.svg)](https://snapcraft.io/solvespace) +[![solvespace](https://snapcraft.io/solvespace/trending.svg?name=0)](https://snapcraft.io/solvespace) + +This repository contains the source code of [SolveSpace][], a parametric +2d/3d CAD. + +[solvespace]: http://solvespace.com + +Community +--------- + +The official SolveSpace [website][sswebsite] has [tutorials][sstutorial], +[reference manual][ssref] and a [forum][ssforum]; there is also an official +IRC channel [#solvespace at irc.freenode.net][ssirc]. + +[sswebsite]: http://solvespace.com/ +[ssref]: http://solvespace.com/ref.pl +[sstutorial]: http://solvespace.com/tutorial.pl +[ssforum]: http://solvespace.com/forum.pl +[ssirc]: https://webchat.freenode.net/?channels=solvespace + +Installation +------------ + +### Via official binary packages + +_Official_ release binary packages for macOS (>=10.6 64-bit) and Windows (>=Vista 32-bit) are +available via [GitHub releases][rel]. These packages are automatically built by +the SolveSpace maintainers for each stable release. + +[rel]: https://github.com/solvespace/solvespace/releases + +### Via Snap Store + +Builds from master are automatically released to the `edge` channel in the Snap Store. Those packages contain the latest improvements, but receive less testing than release builds. + +Future official releases will appear in the `stable` channel. + +[![Get it from the Snap Store](https://snapcraft.io/static/images/badges/en/snap-store-black.svg)](https://snapcraft.io/solvespace) + +Or install from a terminal: + +``` +snap install --edge solvespace +``` + +### Via third-party binary packages + +_Third-party_ nightly binary packages for Debian and Ubuntu are available +via [notesalexp.org][notesalexp]. These packages are automatically built from non-released +source code. The SolveSpace maintainers do not control the contents of these packages +and cannot guarantee their functionality. + +[notesalexp]: https://notesalexp.org/packages/en/source/solvespace/ + +### Via source code + +See below. + +Building on Linux +----------------- + +### Building for Linux + +You will need the usual build tools, CMake, zlib, libpng, cairo, freetype. +To build the GUI, you will need fontconfig, gtkmm 3.0 (version 3.16 or later), pangomm 1.4, +OpenGL and OpenGL GLU, and optionally, the Space Navigator client library. +On a Debian derivative (e.g. Ubuntu) these can be installed with: + + sudo apt install git build-essential cmake zlib1g-dev libpng-dev \ + libcairo2-dev libfreetype6-dev libjson-c-dev \ + libfontconfig1-dev libgtkmm-3.0-dev libpangomm-1.4-dev \ + libgl-dev libglu-dev libspnav-dev + +On a Redhat derivative (e.g. Fedora) the dependencies can be installed with: + + sudo dnf install git gcc-c++ cmake zlib-devel libpng-devel \ + cairo-devel freetype-devel json-c-devel \ + fontconfig-devel gtkmm30-devel pangomm-devel \ + mesa-libGL-devel mesa-libGLU-devel libspnav-devel + +Before building, check out the project and the necessary submodules: + + git clone https://github.com/solvespace/solvespace + cd solvespace + git submodule update --init extlib/libdxfrw extlib/mimalloc + +After that, build SolveSpace as following: + + mkdir build + cd build + cmake .. -DCMAKE_BUILD_TYPE=Release + make + sudo make install + +The graphical interface is built as `build/bin/solvespace`, and the command-line interface +is built as `build/bin/solvespace-cli`. It is possible to build only the command-line interface +by passing the `-DENABLE_GUI=OFF` flag to the cmake invocation. + +### Building for Windows + +Ubuntu will require 20.04 or above. Cross-compiling with WSL is also confirmed to work. + +You will need the usual build tools, CMake, a Windows cross-compiler, and flatc. On a Debian derivative (e.g. Ubuntu) these can be installed with: + + apt-get install git build-essential cmake mingw-w64 + +Before building, check out the project and the necessary submodules: + + git clone https://github.com/solvespace/solvespace + cd solvespace + git submodule update --init + +Build 64-bit SolveSpace with the following: + + mkdir build + cd build + cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw64.cmake \ + -DCMAKE_BUILD_TYPE=Release \ + -DFLATC=$(which flatc) + make + +The graphical interface is built as `build/bin/solvespace.exe`, and the command-line interface +is built as `build/bin/solvespace-cli.exe`. + +Space Navigator support will not be available. + +If using Ubuntu to cross-compile, Ubuntu 17.10 or newer (or, alternatively, MinGW from the Ubuntu +17.10 repositories) is required. + +Building on macOS +----------------- + +You will need git, XCode tools and CMake. Git and CMake can be installed +via [Homebrew][]: + + brew install git cmake + +XCode has to be installed via AppStore or [the Apple website][appledeveloper]; +it requires a free Apple ID. + +Before building, check out the project and the necessary submodules: + + git clone https://github.com/solvespace/solvespace + cd solvespace + git submodule update --init + +After that, build SolveSpace as following: + + mkdir build + cd build + cmake .. -DCMAKE_BUILD_TYPE=Release + make + +Alternatively, generate an XCode project, open it, and build the "Release" scheme: + + mkdir build + cd build + cmake .. -G Xcode + +The application is built in `build/bin/SolveSpace.app`, the graphical interface executable +is `build/bin/SolveSpace.app/Contents/MacOS/SolveSpace`, and the command-line interface executable +is `build/bin/SolveSpace.app/Contents/MacOS/solvespace-cli`. + +[homebrew]: https://brew.sh/ +[appledeveloper]: https://developer.apple.com/download/ + +Building on OpenBSD +------------------- + +You will need git, cmake, libexecinfo, libpng, gtk3mm and pangomm. +These can be installed from the ports tree: + + pkg_add -U git cmake libexecinfo png json-c gtk3mm pangomm + +Before building, check out the project and the necessary submodules: + + git clone https://github.com/solvespace/solvespace + cd solvespace + git submodule update --init extlib/libdxfrw extlib/mimalloc + +After that, build SolveSpace as following: + + mkdir build + cd build + cmake .. -DCMAKE_BUILD_TYPE=Release + make + +Unfortunately, on OpenBSD, the produced executables are not filesystem location independent +and must be installed before use. By default, the graphical interface is installed to +`/usr/local/bin/solvespace`, and the command-line interface is built as +`/usr/local/bin/solvespace-cli`. It is possible to build only the command-line interface +by passing the `-DENABLE_GUI=OFF` flag to the cmake invocation. + +Building on Windows +------------------- + +You will need [git][gitwin], [cmake][cmakewin] and a C++ compiler +(either Visual C++ or MinGW). If using Visual C++, Visual Studio 2015 +or later is required. + +### Building with Visual Studio IDE + +Check out the git submodules. Create a directory `build` in +the source tree and point cmake-gui to the source tree and that directory. +Press "Configure" and "Generate", then open `build\solvespace.sln` with +Visual C++ and build it. + +### Building with Visual Studio in a command prompt + +First, ensure that git and cl (the Visual C++ compiler driver) are in your +`%PATH%`; the latter is usually done by invoking `vcvarsall.bat` from your +Visual Studio install. Then, run the following in cmd or PowerShell: + + git clone https://github.com/solvespace/solvespace + cd solvespace + git submodule update --init + mkdir build + cd build + cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release + nmake + +### Building with MinGW + +It is also possible to build SolveSpace using [MinGW][mingw], though +Space Navigator support will be disabled. + +First, ensure that git and gcc are in your `$PATH`. Then, run the following +in bash: + + git clone https://github.com/solvespace/solvespace + cd solvespace + git submodule update --init + mkdir build + cd build + cmake .. -DCMAKE_BUILD_TYPE=Release + make + +[gitwin]: https://git-scm.com/download/win +[cmakewin]: http://www.cmake.org/download/#latest +[mingw]: http://www.mingw.org/ + +Contributing +------------ + +See the [guide for contributors](CONTRIBUTING.md) for the best way to file issues, contribute code, +and debug SolveSpace. + +License +------- + +SolveSpace is distributed under the terms of the [GPL v3 license](COPYING.txt). diff --git a/THIRD_PARTIES.txt b/THIRD_PARTIES.txt new file mode 100644 index 0000000..ad04bf6 --- /dev/null +++ b/THIRD_PARTIES.txt @@ -0,0 +1,50 @@ +This file outlines third party licenses that apply to the files and resources +listed with them. All file paths are relative to the SolveSpace project root. + +When redistributing SolveSpace, make sure to also reproduce this file such that +the paths indicating the scope of each license remain intact. +================================================================================ + + Bitstream Vera, ./res/fonts/BitstreamVeraSans-Roman-builtin.ttf + ~ +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is a +trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +the fonts accompanying this license (“Fonts”) and associated documentation files +(the “Font Software”), to reproduce and distribute the Font Software, including +without limitation the rights to use, copy, merge, publish, distribute, and/or +sell copies of the Font Software, and to permit persons to whom the Font +Software is furnished to do so, subject to the following conditions: + +The above copyright and trademark notices and this permission notice shall be +included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular the +designs of glyphs or characters in the Fonts may be modified and additional +glyphs or characters may be added to the Fonts, only if the fonts are renamed to +names not containing either the words “Bitstream” or the word “Vera”. + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the “Bitstream Vera” +names. + +The Font Software may be sold as part of a larger software package but no copy +of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR +OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME FOUNDATION BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, +INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR +FROM OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the names of GNOME, the GNOME Foundation, +and Bitstream Inc., shall not be used in advertising or otherwise to promote the +sale, use or other dealings in this Font Software without prior written +authorization from the GNOME Foundation or Bitstream Inc., respectively. For +further information, contact: fonts at gnome dot org. + + ----------- diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt new file mode 100644 index 0000000..26172f1 --- /dev/null +++ b/bench/CMakeLists.txt @@ -0,0 +1,17 @@ +# benchmark runner + +foreach(pkg_config_lib CAIRO) + include_directories(${${pkg_config_lib}_INCLUDE_DIRS}) + link_directories(${${pkg_config_lib}_LIBRARY_DIRS}) +endforeach() + +add_executable(solvespace-benchmark + harness.cpp + $) + +target_link_libraries(solvespace-benchmark + solvespace-core + solvespace-headless) + +add_dependencies(solvespace-benchmark + resources) diff --git a/bench/harness.cpp b/bench/harness.cpp new file mode 100644 index 0000000..4180558 --- /dev/null +++ b/bench/harness.cpp @@ -0,0 +1,78 @@ +//----------------------------------------------------------------------------- +// Our harness for running benchmarks. +// +// Copyright 2016 whitequark +//----------------------------------------------------------------------------- +#include "solvespace.h" + +static bool RunBenchmark(std::function setupFn, + std::function benchFn, + std::function teardownFn, + size_t minIter = 5, double minTime = 5.0) { + // Warmup + setupFn(); + if(!benchFn()) { + fprintf(stderr, "Benchmark failed\n"); + return false; + } + teardownFn(); + + // Benchmark + size_t iter = 0; + double time = 0.0; + while(iter < minIter || time < minTime) { + setupFn(); + auto testStartTime = std::chrono::steady_clock::now(); + benchFn(); + auto testEndTime = std::chrono::steady_clock::now(); + teardownFn(); + + std::chrono::duration testTime = testEndTime - testStartTime; + time += testTime.count(); + iter += 1; + } + + // Report + fprintf(stdout, "Iterations: %zd\n", iter); + fprintf(stdout, "Time: %.3f s\n", time); + fprintf(stdout, "Per iter.: %.3f s\n", time / (double)iter); + + return true; +} + +int main(int argc, char **argv) { + std::vector args = Platform::InitCli(argc, argv); + + std::string mode; + Platform::Path filename; + if(args.size() == 3) { + mode = args[1]; + filename = Platform::Path::From(args[2]); + } else { + fprintf(stderr, "Usage: %s [mode] [filename]\n", args[0].c_str()); + fprintf(stderr, "Mode can be one of: load.\n"); + return 1; + } + + bool result = false; + if(mode == "load") { + result = RunBenchmark( + [] { + SS.Init(); + }, + [&] { + if(!SS.LoadFromFile(filename)) + return false; + SS.AfterNewFile(); + return true; + }, + [] { + SK.Clear(); + SS.Clear(); + }); + } else { + fprintf(stderr, "Unknown mode \"%s\"\n", mode.c_str()); + } + + return (result == true ? 0 : 1); +} diff --git a/cmake/AddVendoredSubdirectory.cmake b/cmake/AddVendoredSubdirectory.cmake new file mode 100644 index 0000000..9d2edf6 --- /dev/null +++ b/cmake/AddVendoredSubdirectory.cmake @@ -0,0 +1,10 @@ +# Equivalent to add_subdirectory(... EXCLUDE_FROM_ALL), but also disables +# all warnings. + +include(DisableWarnings) + +function(add_vendored_subdirectory PATH) + disable_warnings() + + add_subdirectory(${PATH} EXCLUDE_FROM_ALL) +endfunction() diff --git a/cmake/DisableWarnings.cmake b/cmake/DisableWarnings.cmake new file mode 100644 index 0000000..b79ef9c --- /dev/null +++ b/cmake/DisableWarnings.cmake @@ -0,0 +1,15 @@ +# Disables all warnings on MSVC and GNU-compatible compilers. + +function(disable_warnings) + if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w" PARENT_SCOPE) + elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W0" PARENT_SCOPE) + endif() + + if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w" PARENT_SCOPE) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W0" PARENT_SCOPE) + endif() +endfunction() diff --git a/cmake/FindSpaceWare.cmake b/cmake/FindSpaceWare.cmake new file mode 100644 index 0000000..fb6073c --- /dev/null +++ b/cmake/FindSpaceWare.cmake @@ -0,0 +1,28 @@ +# Find the libspnav library and header. +# +# Sets the usual variables expected for find_package scripts: +# +# SPACEWARE_INCLUDE_DIR - header location +# SPACEWARE_LIBRARIES - library to link against +# SPACEWARE_FOUND - true if libspnav was found. + +if(UNIX) + + find_path(SPACEWARE_INCLUDE_DIR + spnav.h) + + find_library(SPACEWARE_LIBRARY + NAMES spnav libspnav) + + # Support the REQUIRED and QUIET arguments, and set SPACEWARE_FOUND if found. + include(FindPackageHandleStandardArgs) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(SPACEWARE DEFAULT_MSG + SPACEWARE_LIBRARY SPACEWARE_INCLUDE_DIR) + + if(SPACEWARE_FOUND) + set(SPACEWARE_LIBRARIES ${SPACEWARE_LIBRARY}) + endif() + + mark_as_advanced(SPACEWARE_LIBRARY SPACEWARE_INCLUDE_DIR) + +endif() diff --git a/cmake/FindVendoredPackage.cmake b/cmake/FindVendoredPackage.cmake new file mode 100644 index 0000000..6227f6c --- /dev/null +++ b/cmake/FindVendoredPackage.cmake @@ -0,0 +1,56 @@ +# Find the given library in the system locations, or build in-tree if not found. +# +# Arguments: +# PKG_NAME - name of the package as passed to find_package +# PKG_PATH - name of the source tree relative to extlib/ +# +# The rest of the arguments are VARIABLE VALUE pairs. If the library is not found, +# every VARIABLE will be set to VALUE and find_package will be rerun with the REQUIRED flag. +# Regardless of where the library was found, only the specified VARIABLEs that start with +# ${PKG_NAME} will be set in the parent scope. +# +# All warnings in the in-tree package are disabled. + +include(DisableWarnings) + +function(find_vendored_package PKG_NAME PKG_PATH) + if(NOT FORCE_VENDORED_${PKG_NAME}) + find_package(${PKG_NAME}) + endif() + + set(cfg_name) + foreach(item ${ARGN}) + if(NOT cfg_name) + set(cfg_name ${item}) + else() + set(${cfg_name} ${item} CACHE INTERNAL "") + set(cfg_name) + endif() + endforeach() + + disable_warnings() + + string(TOUPPER ${PKG_NAME} VAR_NAME) + if(NOT ${VAR_NAME}_FOUND) + message(STATUS "Using in-tree ${PKG_PATH}") + set(${VAR_NAME}_IN_TREE YES CACHE INTERNAL "") + + add_subdirectory(extlib/${PKG_PATH} EXCLUDE_FROM_ALL) + find_package(${PKG_NAME} REQUIRED) + elseif(${VAR_NAME}_IN_TREE) + add_subdirectory(extlib/${PKG_PATH} EXCLUDE_FROM_ALL) + endif() + + # Now put everything we just discovered into the cache. + set(cfg_name) + foreach(item ${ARGN} ${VAR_NAME}_FOUND) + if(NOT cfg_name) + set(cfg_name ${item}) + else() + if(cfg_name MATCHES "^${VAR_NAME}") + set(${cfg_name} "${${cfg_name}}" CACHE INTERNAL "") + endif() + set(cfg_name) + endif() + endforeach() +endfunction() diff --git a/cmake/GetGitCommitHash.cmake b/cmake/GetGitCommitHash.cmake new file mode 100644 index 0000000..f67a844 --- /dev/null +++ b/cmake/GetGitCommitHash.cmake @@ -0,0 +1,35 @@ +function(get_git_commit_hash) + get_filename_component(GIT_DESCRIBE_CMAKE_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) + get_filename_component(GIT_ROOT ${GIT_DESCRIBE_CMAKE_DIR} PATH) + set(GIT_DIR "${GIT_ROOT}/.git") + + # Add a CMake configure dependency to the currently checked out revision. + set(GIT_DEPENDS ${GIT_DIR}/HEAD) + file(READ ${GIT_DIR}/HEAD HEAD_REF) + if(HEAD_REF MATCHES "ref: (.+)\n") + set(HEAD_REF ${CMAKE_MATCH_1}) + if(EXISTS "${GIT_DIR}/${HEAD_REF}") + list(APPEND GIT_DEPENDS ${GIT_DIR}/${HEAD_REF}) + file(READ ${GIT_DIR}/${HEAD_REF} HEAD_REF) + elseif(EXISTS "${GIT_DIR}/packed-refs") + list(APPEND GIT_DEPENDS ${GIT_DIR}/packed-refs) + file(READ "${GIT_DIR}/packed-refs" PACKED_REFS) + if(${PACKED_REFS} MATCHES "([0-9a-z]*) ${HEAD_REF}") + set(HEAD_REF ${CMAKE_MATCH_1}) + else() + set(HEAD_REF "") + endif() + else() + set(HEAD_REF "") + endif() + endif() + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${GIT_DEPENDS}) + + string(STRIP ${HEAD_REF} HEAD_REF) + if(HEAD_REF STREQUAL "") + message(WARNING "Cannot determine git HEAD") + else() + set(GIT_COMMIT_HASH ${HEAD_REF} PARENT_SCOPE) + endif() +endfunction() +get_git_commit_hash() diff --git a/cmake/MacOSXBundleInfo.plist.in b/cmake/MacOSXBundleInfo.plist.in new file mode 100644 index 0000000..668d1f7 --- /dev/null +++ b/cmake/MacOSXBundleInfo.plist.in @@ -0,0 +1,49 @@ + + + + + CFBundleIdentifier + com.solvespace + CFBundleDevelopmentRegion + English + CFBundleExecutable + SolveSpace + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + SolveSpace + CFBundlePackageType + APPL + CFBundleVersion + ${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}~${solvespace_GIT_HASH} + CFBundleShortVersionString + ${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR} + NSHumanReadableCopyright + © 2008-2016 Jonathan Westhues and other authors + NSPrincipalClass + NSApplication + NSMainNibFile + MainMenu + CFBundleIconFile + AppIcon + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + slvs + + CFBundleTypeIconFile + AppIcon.icns + CFBundleTypeName + SolveSpace sketch + CFBundleTypeOSTypes + + slvs + + CFBundleTypeRole + Editor + + + + diff --git a/cmake/Toolchain-mingw32.cmake b/cmake/Toolchain-mingw32.cmake new file mode 100644 index 0000000..a8767fd --- /dev/null +++ b/cmake/Toolchain-mingw32.cmake @@ -0,0 +1,15 @@ +set(CMAKE_SYSTEM_NAME Windows) + +set(TRIPLE i686-w64-mingw32) + +set(CMAKE_C_COMPILER ${TRIPLE}-gcc) +set(CMAKE_CXX_COMPILER ${TRIPLE}-g++) +set(CMAKE_RC_COMPILER ${TRIPLE}-windres) + +set(CMAKE_FIND_ROOT_PATH /usr/${TRIPLE}) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(ENV{PKG_CONFIG_LIBDIR} /usr/${TRIPLE}/lib/pkgconfig) diff --git a/cmake/Toolchain-mingw64.cmake b/cmake/Toolchain-mingw64.cmake new file mode 100644 index 0000000..7f85f35 --- /dev/null +++ b/cmake/Toolchain-mingw64.cmake @@ -0,0 +1,15 @@ +set(CMAKE_SYSTEM_NAME Windows) + +set(TRIPLE x86_64-w64-mingw32) + +set(CMAKE_C_COMPILER ${TRIPLE}-gcc) +set(CMAKE_CXX_COMPILER ${TRIPLE}-g++) +set(CMAKE_RC_COMPILER ${TRIPLE}-windres) + +set(CMAKE_FIND_ROOT_PATH /usr/${TRIPLE}) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +set(ENV{PKG_CONFIG_LIBDIR} /usr/${TRIPLE}/lib/pkgconfig) diff --git a/cmake/c_flag_overrides.cmake b/cmake/c_flag_overrides.cmake new file mode 100644 index 0000000..b21f00e --- /dev/null +++ b/cmake/c_flag_overrides.cmake @@ -0,0 +1,6 @@ +if(MSVC) + set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") + set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") + set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") + set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") +endif() \ No newline at end of file diff --git a/cmake/cxx_flag_overrides.cmake b/cmake/cxx_flag_overrides.cmake new file mode 100644 index 0000000..67e0043 --- /dev/null +++ b/cmake/cxx_flag_overrides.cmake @@ -0,0 +1,6 @@ +if(MSVC) + set(CMAKE_CXX_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1") + set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG") + set(CMAKE_CXX_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG") +endif() diff --git a/developer_docs/Solver_Transforms.txt b/developer_docs/Solver_Transforms.txt new file mode 100644 index 0000000..1ea3ae5 --- /dev/null +++ b/developer_docs/Solver_Transforms.txt @@ -0,0 +1,154 @@ + +CREATING NEW GROUPS in 3D +================================= + +New Transformed Entity Types: +----------------------------- +New construction tools may require new transformations of entities - Points, +Normals, and Faces. A number of "Types" exist to transform an entity to a new +location. The term "Type" refers to the type of transformation an entity was +created from, and should not be confused with the 3 kinds of Entity (there are +other entities but they rely on others of the 3 base types for position and +orientation information, so they don't directly transform). A list of +Types is at the top of the EntityBase class definition: + + enum class Type : uint32_t { + POINT_IN_3D = 2000, + POINT_IN_2D = 2001, + POINT_N_TRANS = 2010, + POINT_N_ROT_TRANS = 2011, + POINT_N_COPY = 2012, + POINT_N_ROT_AA = 2013, + POINT_N_ROT_AXIS_TRANS = 2014, + + NORMAL_IN_3D = 3000, + NORMAL_IN_2D = 3001, + NORMAL_N_COPY = 3010, + NORMAL_N_ROT = 3011, + NORMAL_N_ROT_AA = 3012, + + FACE_NORMAL_PT = 5000, + FACE_XPROD = 5001, + FACE_N_ROT_TRANS = 5002, + FACE_N_TRANS = 5003, + FACE_N_ROT_AA = 5004, + +Some of the point definitions with _N_ in the name are points defined by +N application of a transformation. The number of times a particular entity +is transformed is given in the member variable "timesApplied". The following +is a dectription of the various transformation Types. + +POINT_N_TRANS: Translates a point by a vector defined by param[0],param[1],param[2] + the vector is multiplied by timesApplied. + +POINT_N_ROT_TRANS: Rotates a point via quaternion param[3],param[4],param[5],param[6] + and then translates it by vector param[0],param[1],param[2] + +POINT_N_COPY: A non-transformed copy of a point - numeric copy? + +POINT_N_ROT_AA: A point rotated arount point param[0],param[1],param[2] Where the + angle is given by param[3]*timesApplied (times 2?) and the axis + of rotation defined by param[4],param[5],param[6] + +POINT_N_ROT_AXIS_TRANS: Same as POINT_N_ROT_AA but after rotation, the point is + translated along the rotation axis by distance param[7]. + +NORMAL_N_COPY A non-transformed copy of a normal - numeric copy? + +NORMAL_N_ROT: A normal rotated by a quaternion defeined by param[0],param[1],param[2],param[3] + +NORMAL_N_ROT_AA A normal rotated by timesApplied*param[0] around the axis + specified by param[1],param[2],parma[3] + +FACE_N_ROT_TRANS A face rotated then translated. Rotation is defined by + quaternion param[3],param[4],param[5],param[6]. The translation + is defined by param[0],param[1],param[2]. + +FACE_N_TRANS: Translates a face by a vector defined by param[0],param[1],param[2] + faces are defined by a point and a normal, so this just moves the point. + +FACE_N_ROT_AA Face rotated about point param[0],param[1],param[2]. The axis + is param[4],param[5],param[6]. Angle is timesApplied*param[3]. + + +All entities are copied by the function Group::CopyEntity() which has a CopyAs +parameter to indicate which kind of copy is to be made. The mapping from CopyAs to +Entity Types can be found in that function. Most point types get copied the same +way depending on CopyAs. Several of the normals get copied to the same new +entity Type because they are unaffected by translation - you don't care if CopyAs +specified a translation with rotation or just a rotation, a normal is affected the +same in either case. The mapping from entity type to new entity type has to be +decoded from the cases and if-else logic in that function. + +It is important that a transformation be properly applied to all three of the +fundamental entities - points, normals, and surfaces. + +FUNCTIONS THAT MAY NEED TO BE EXTENDED when new entity types are defined: + +These functions have default cases, so they only need to be extended to return True: +EntityBase::IsPoint() +EntityBase::IsNormal() +EntityBAse::IsFace() + +For new normal transforms the following should be filled in: +Quaternion EntityBase::NormalGetNum() +void EntityBase::NormalForceTo(Quaternion q) +ExprQuaternion EntityBase::NormalGetExprs() + +For points: +Vector EntityBase::PointGetNum() +void EntityBase::PointForceTo(Vector p) +ExprVector EntityBase::PointGetExprs() + +For Faces: +ExprVector EntityBase::FaceGetNormalExprs() +Vector EntityBase::FaceGetNormalNum() +ExprVector EntityBase::FaceGetPointExprs() +Vector EntityBase::FaceGetPointNum() + +The basic model for these transformed entities is that the group containing them +will have parameters that define the transformed entity in terms of the one it +was copied from. For example, in PointGetNum() under the case POINT_N_TRANS we see: + + Vector trans = Vector::From(param[0], param[1], param[2]); + p = numPoint.Plus(trans.ScaledBy(timesApplied)); + break; + +This take the original "numPoint" and adds a vector created from 3 parameters and +multiplied by "timesApplied". This is used in the step-translating groups. It's also +used in extrude groups where there are constraints on the 3 parameters to keep the +vector perpendicular to the sketch it was extruded from. This function returns a +numerical version of the copied point, hence "GetNum" in the name. + +Another function PointGetExprs() returns the same coordinates of the point but +returns an expression vector. When the user applies a constraint to a point, this +function is called to get algebraic expressions for the point that are suitable for +use in the solver. Most points will not be constrained directly, so expressions +are not needed for them. It is also notable that the expressions are not part of +the entity itself. + +The ForceTo() functions are shortcuts for using the solver. They are passed the +desired location of a point (or orientation of a normal...) and have the opportunity +to back-calculate what the group parameters should be to place it there. This is +used for mouse dragging of copied entites. It is notable that the constraints will +still be applied afterward, but this is a good shortcut. + +When creating a new entity transformation, the first thing to do is define the +numerical copy (xxxGetNum). That should allow display. Dragging will not work +until ForceTo is implemented, and user constraints will not work until GetExprs() +is completed. Most of these functions have an assert that will fire if the required +new case is missing. This is may not be a complete list of everything you need to +make new entity transformations. + +One thing of note, parameters in both entities and groups are stored by their handle. +An entity can have up to 8 parameters to define how it is transformed from another +entity. By convention this array of parameter handles matches that of the group but +this is probably not strictly necessary. + +ADDING GROUP CONSTRAINTS: +The example above where a point is copied via POINT_N_TRANS for both EXTRUDE and +STEP TRANSLATING groups is a good example here. For the EXTRUDE case, two constraint +equations are added to keep the offset vector perpendicular to the sketch. These +equations are created in Group::GenerateEquations() and are nothing more than an +expression which is implicitly set equal to zero in the solver. + diff --git a/exposed/CDemo.c b/exposed/CDemo.c new file mode 100644 index 0000000..cf6107e --- /dev/null +++ b/exposed/CDemo.c @@ -0,0 +1,269 @@ +/*----------------------------------------------------------------------------- + * Some sample code for slvs.dll. We draw some geometric entities, provide + * initial guesses for their positions, and then constrain them. The solver + * calculates their new positions, in order to satisfy the constraints. + * + * Copyright 2008-2013 Jonathan Westhues. + *---------------------------------------------------------------------------*/ +#ifdef WIN32 +# include +#endif +#include +#include +#include +#include + +#include + +static Slvs_System sys; + +static void *CheckMalloc(size_t n) +{ + void *r = malloc(n); + if(!r) { + printf("out of memory!\n"); + exit(-1); + } + return r; +} + +/*----------------------------------------------------------------------------- + * An example of a constraint in 3d. We create a single group, with some + * entities and constraints. + *---------------------------------------------------------------------------*/ +void Example3d() +{ + /* This will contain a single group, which will arbitrarily number 1. */ + Slvs_hGroup g = 1; + + /* A point, initially at (x y z) = (10 10 10) */ + sys.param[sys.params++] = Slvs_MakeParam(1, g, 10.0); + sys.param[sys.params++] = Slvs_MakeParam(2, g, 10.0); + sys.param[sys.params++] = Slvs_MakeParam(3, g, 10.0); + sys.entity[sys.entities++] = Slvs_MakePoint3d(101, g, 1, 2, 3); + /* and a second point at (20 20 20) */ + sys.param[sys.params++] = Slvs_MakeParam(4, g, 20.0); + sys.param[sys.params++] = Slvs_MakeParam(5, g, 20.0); + sys.param[sys.params++] = Slvs_MakeParam(6, g, 20.0); + sys.entity[sys.entities++] = Slvs_MakePoint3d(102, g, 4, 5, 6); + /* and a line segment connecting them. */ + sys.entity[sys.entities++] = Slvs_MakeLineSegment(200, g, + SLVS_FREE_IN_3D, 101, 102); + + /* The distance between the points should be 30.0 units. */ + sys.constraint[sys.constraints++] = Slvs_MakeConstraint( + 1, g, + SLVS_C_PT_PT_DISTANCE, + SLVS_FREE_IN_3D, + 30.0, + 101, 102, 0, 0); + + /* Let's tell the solver to keep the second point as close to constant + * as possible, instead moving the first point. */ + sys.dragged[0] = 4; + sys.dragged[1] = 5; + sys.dragged[2] = 6; + + /* Now that we have written our system, we solve. */ + Slvs_Solve(&sys, g); + + if(sys.result == SLVS_RESULT_OKAY) { + printf("okay; now at (%.3f %.3f %.3f)\n" + " (%.3f %.3f %.3f)\n", + sys.param[0].val, sys.param[1].val, sys.param[2].val, + sys.param[3].val, sys.param[4].val, sys.param[5].val); + printf("%d DOF\n", sys.dof); + } else { + printf("solve failed"); + } +} + +/*----------------------------------------------------------------------------- + * An example of a constraint in 2d. In our first group, we create a workplane + * along the reference frame's xy plane. In a second group, we create some + * entities in that group and dimension them. + *---------------------------------------------------------------------------*/ +void Example2d() +{ + Slvs_hGroup g; + double qw, qx, qy, qz; + + g = 1; + /* First, we create our workplane. Its origin corresponds to the origin + * of our base frame (x y z) = (0 0 0) */ + sys.param[sys.params++] = Slvs_MakeParam(1, g, 0.0); + sys.param[sys.params++] = Slvs_MakeParam(2, g, 0.0); + sys.param[sys.params++] = Slvs_MakeParam(3, g, 0.0); + sys.entity[sys.entities++] = Slvs_MakePoint3d(101, g, 1, 2, 3); + /* and it is parallel to the xy plane, so it has basis vectors (1 0 0) + * and (0 1 0). */ + Slvs_MakeQuaternion(1, 0, 0, + 0, 1, 0, &qw, &qx, &qy, &qz); + sys.param[sys.params++] = Slvs_MakeParam(4, g, qw); + sys.param[sys.params++] = Slvs_MakeParam(5, g, qx); + sys.param[sys.params++] = Slvs_MakeParam(6, g, qy); + sys.param[sys.params++] = Slvs_MakeParam(7, g, qz); + sys.entity[sys.entities++] = Slvs_MakeNormal3d(102, g, 4, 5, 6, 7); + + sys.entity[sys.entities++] = Slvs_MakeWorkplane(200, g, 101, 102); + + /* Now create a second group. We'll solve group 2, while leaving group 1 + * constant; so the workplane that we've created will be locked down, + * and the solver can't move it. */ + g = 2; + /* These points are represented by their coordinates (u v) within the + * workplane, so they need only two parameters each. */ + sys.param[sys.params++] = Slvs_MakeParam(11, g, 10.0); + sys.param[sys.params++] = Slvs_MakeParam(12, g, 20.0); + sys.entity[sys.entities++] = Slvs_MakePoint2d(301, g, 200, 11, 12); + + sys.param[sys.params++] = Slvs_MakeParam(13, g, 20.0); + sys.param[sys.params++] = Slvs_MakeParam(14, g, 10.0); + sys.entity[sys.entities++] = Slvs_MakePoint2d(302, g, 200, 13, 14); + + /* And we create a line segment with those endpoints. */ + sys.entity[sys.entities++] = Slvs_MakeLineSegment(400, g, + 200, 301, 302); + + /* Now three more points. */ + sys.param[sys.params++] = Slvs_MakeParam(15, g, 100.0); + sys.param[sys.params++] = Slvs_MakeParam(16, g, 120.0); + sys.entity[sys.entities++] = Slvs_MakePoint2d(303, g, 200, 15, 16); + + sys.param[sys.params++] = Slvs_MakeParam(17, g, 120.0); + sys.param[sys.params++] = Slvs_MakeParam(18, g, 110.0); + sys.entity[sys.entities++] = Slvs_MakePoint2d(304, g, 200, 17, 18); + + sys.param[sys.params++] = Slvs_MakeParam(19, g, 115.0); + sys.param[sys.params++] = Slvs_MakeParam(20, g, 115.0); + sys.entity[sys.entities++] = Slvs_MakePoint2d(305, g, 200, 19, 20); + + /* And arc, centered at point 303, starting at point 304, ending at + * point 305. */ + sys.entity[sys.entities++] = Slvs_MakeArcOfCircle(401, g, 200, 102, + 303, 304, 305); + + /* Now one more point, and a distance */ + sys.param[sys.params++] = Slvs_MakeParam(21, g, 200.0); + sys.param[sys.params++] = Slvs_MakeParam(22, g, 200.0); + sys.entity[sys.entities++] = Slvs_MakePoint2d(306, g, 200, 21, 22); + + sys.param[sys.params++] = Slvs_MakeParam(23, g, 30.0); + sys.entity[sys.entities++] = Slvs_MakeDistance(307, g, 200, 23); + + /* And a complete circle, centered at point 306 with radius equal to + * distance 307. The normal is 102, the same as our workplane. */ + sys.entity[sys.entities++] = Slvs_MakeCircle(402, g, 200, + 306, 102, 307); + + + /* The length of our line segment is 30.0 units. */ + sys.constraint[sys.constraints++] = Slvs_MakeConstraint( + 1, g, + SLVS_C_PT_PT_DISTANCE, + 200, + 30.0, + 301, 302, 0, 0); + + /* And the distance from our line segment to the origin is 10.0 units. */ + sys.constraint[sys.constraints++] = Slvs_MakeConstraint( + 2, g, + SLVS_C_PT_LINE_DISTANCE, + 200, + 10.0, + 101, 0, 400, 0); + /* And the line segment is vertical. */ + sys.constraint[sys.constraints++] = Slvs_MakeConstraint( + 3, g, + SLVS_C_VERTICAL, + 200, + 0.0, + 0, 0, 400, 0); + /* And the distance from one endpoint to the origin is 15.0 units. */ + sys.constraint[sys.constraints++] = Slvs_MakeConstraint( + 4, g, + SLVS_C_PT_PT_DISTANCE, + 200, + 15.0, + 301, 101, 0, 0); +#if 0 + /* And same for the other endpoint; so if you add this constraint then + * the sketch is overconstrained and will signal an error. */ + sys.constraint[sys.constraints++] = Slvs_MakeConstraint( + 5, g, + SLVS_C_PT_PT_DISTANCE, + 200, + 18.0, + 302, 101, 0, 0); +#endif /* 0 */ + + /* The arc and the circle have equal radius. */ + sys.constraint[sys.constraints++] = Slvs_MakeConstraint( + 6, g, + SLVS_C_EQUAL_RADIUS, + 200, + 0.0, + 0, 0, 401, 402); + /* The arc has radius 17.0 units. */ + sys.constraint[sys.constraints++] = Slvs_MakeConstraint( + 7, g, + SLVS_C_DIAMETER, + 200, + 17.0*2, + 0, 0, 401, 0); + + /* If the solver fails, then ask it to report which constraints caused + * the problem. */ + sys.calculateFaileds = 1; + + /* And solve. */ + Slvs_Solve(&sys, g); + + if(sys.result == SLVS_RESULT_OKAY) { + printf("solved okay\n"); + printf("line from (%.3f %.3f) to (%.3f %.3f)\n", + sys.param[7].val, sys.param[8].val, + sys.param[9].val, sys.param[10].val); + + printf("arc center (%.3f %.3f) start (%.3f %.3f) finish (%.3f %.3f)\n", + sys.param[11].val, sys.param[12].val, + sys.param[13].val, sys.param[14].val, + sys.param[15].val, sys.param[16].val); + + printf("circle center (%.3f %.3f) radius %.3f\n", + sys.param[17].val, sys.param[18].val, + sys.param[19].val); + printf("%d DOF\n", sys.dof); + } else { + int i; + printf("solve failed: problematic constraints are:"); + for(i = 0; i < sys.faileds; i++) { + printf(" %d", sys.failed[i]); + } + printf("\n"); + if(sys.result == SLVS_RESULT_INCONSISTENT) { + printf("system inconsistent\n"); + } else { + printf("system nonconvergent\n"); + } + } +} + +int main() +{ + sys.param = CheckMalloc(50*sizeof(sys.param[0])); + sys.entity = CheckMalloc(50*sizeof(sys.entity[0])); + sys.constraint = CheckMalloc(50*sizeof(sys.constraint[0])); + + sys.failed = CheckMalloc(50*sizeof(sys.failed[0])); + sys.faileds = 50; + + /*Example3d();*/ + for(;;) { + Example2d(); + sys.params = sys.constraints = sys.entities = 0; + break; + } + return 0; +} + diff --git a/exposed/CMakeLists.txt b/exposed/CMakeLists.txt new file mode 100644 index 0000000..bdc3fc3 --- /dev/null +++ b/exposed/CMakeLists.txt @@ -0,0 +1,8 @@ +include_directories( + ${CMAKE_SOURCE_DIR}/include) + +add_executable(CDemo + CDemo.c) + +target_link_libraries(CDemo + slvs) diff --git a/exposed/DOC.txt b/exposed/DOC.txt new file mode 100644 index 0000000..f64f3ac --- /dev/null +++ b/exposed/DOC.txt @@ -0,0 +1,467 @@ + +INTRODUCTION +============ + +A sketch in SolveSpace consists of three basic elements: parameters, +entities, and constraints. + +A parameter (Slvs_Param) is a single real number, represented internally +by a double-precision floating point variable. The parameters are unknown +variables that the solver modifies in order to satisfy the constraints. + +An entity (Slvs_Entity) is a geometric thing, like a point or a line +segment or a circle. Entities are defined in terms of parameters, +and in terms of other entities. For example, a point in three-space +is represented by three parameters, corresponding to its x, y, and z +coordinates in our base coordinate frame. A line segment is represented +by two point entities, corresponding to its endpoints. + +A constraint (Slvs_Constraint) is a geometric property of an entity, +or a relationship among multiple entities. For example, a point-point +distance constraint will set the distance between two point entities. + +Parameters, entities, and constraints are typically referenced by their +handles (Slvs_hParam, Slvs_hEntity, Slvs_hConstraint). These handles are +32-bit integer values starting from 1. The zero handle is reserved. Each +object has a unique handle within its type (but it's acceptable, for +example to have a constraint with an Slvs_hConstraint of 7, and also to +have an entity with an Slvs_hEntity of 7). The use of handles instead +of pointers helps to avoid memory corruption. + +Entities and constraints are assigned into groups. A group is a set of +entities and constraints that is solved simultaneously. In a parametric +CAD system, a single group would typically correspond to a single sketch. +Constraints within a group may refer to entities outside that group, +but only the entities within that group will be modified by the solver. + +Consider point A in group 1, and point B in group 2. We have a constraint +in group 2 that makes the points coincident. When we solve group 2, the +solver is allowed to move point B to place it on top of point A. It is +not allowed to move point A to put it on top of point B, because point +A is outside the group being solved. + +This corresponds to the typical structure of a parametric CAD system. In a +later sketch, we may constrain our entities against existing geometry from +earlier sketches. The constraints will move the entities in our current +sketch, but will not change the geometry from the earlier sketches. + +To use the solver, we first define a set of parameters, entities, and +constraints. We provide an initial guess for each parameter; this is +necessary to achieve convergence, and also determines which solution +gets chosen when (finitely many) multiple solutions exist. Typically, +these initial guesses are provided by the initial configuration in which +the user drew the entities before constraining them. + +We then run the solver for a given group. The entities within that group +are modified in an attempt to satisfy the constraints. + +After running the solver, there are three possible outcomes: + + * All constraints were satisfied to within our numerical + tolerance (i.e., success). The result is equal to SLVS_RESULT_OKAY, + and the parameters in param[] have been updated. + + * The solver can prove that two constraints are inconsistent (for + example, if a line with nonzero length is constrained both + horizontal and vertical). In that case, a list of inconsistent + constraints is generated in failed[]. + + * The solver cannot prove that two constraints are inconsistent, but + it cannot find a solution. In that case, the list of unsatisfied + constraints is generated in failed[]. + + +TYPES OF ENTITIES +================= + +SLVS_E_POINT_IN_3D + + A point in 3d. Defined by three parameters: + + param[0] the point's x coordinate + param[1] y + param[1] z + + +SLVS_E_POINT_IN_2D + + A point within a workplane. Defined by the workplane + + wrkpl + + and by two parameters + + param[0] the point's u coordinate + param[1] v + + within the coordinate system of the workplane. For example, if the + workplane is the zx plane, then u = z and v = x. If the workplane is + parallel to the zx plane, but translated so that the workplane's + origin is (3, 4, 5), then u = z - 5 and v = x - 3. + + +SLVS_E_NORMAL_IN_3D + + A normal. In SolveSpace, "normals" represent a 3x3 rotation matrix + from our base coordinate system to a new frame. Defined by the + unit quaternion + + param[0] w + param[1] x + param[2] y + param[3] z + + where the quaternion is given by w + x*i + y*j + z*k. + + It is useful to think of this quaternion as representing a plane + through the origin. This plane has three associated vectors: basis + vectors U, V that lie within the plane, and normal N that is + perpendicular to it. This means that + + [ U V N ]' + + defines a 3x3 rotation matrix. So U, V, and N all have unit length, + and are orthogonal so that + + U cross V = N + V cross N = U + N cross U = V + + Convenience functions (Slvs_Quaternion*) are provided to convert + between this representation as vectors U, V, N and the unit + quaternion. + + A unit quaternion has only 3 degrees of freedom, but is specified in + terms of 4 parameters. An extra constraint is therefore generated + implicitly, that + + w^2 + x^2 + y^2 + z^2 = 1 + + +SLVS_E_NORMAL_IN_2D + + A normal within a workplane. This is identical to the workplane's + normal, so it is simply defined by + + wrkpl + + This entity type is used, for example, to define a circle that lies + within a workplane. The circle's normal is the same as the workplane's + normal, so we can use an SLVS_E_NORMAL_IN_2D to copy the workplane's + normal. + + +SLVS_E_DISTANCE + + A distance. This entity is used to define the radius of a circle, by + a single parameter + + param[0] r + + +SLVS_E_WORKPLANE + + An oriented plane, somewhere in 3d. This entity therefore has 6 + degrees of freedom: three translational, and three rotational. It is + specified in terms of its origin + + point[0] origin + + and a normal + + normal + + The normal describes three vectors U, V, N, as discussed in the + documentation for SLVS_E_NORMAL_IN_3D. The plane is therefore given + by the equation + + p = origin + s*U + t*V + + for any scalar s and t. + + +SLVS_E_LINE_SEGMENT + + A line segment between two endpoints + + point[0] + point[1] + + +SLVS_E_CUBIC + + A nonrational cubic Bezier segment + + point[0] starting point P0 + point[1] control point P1 + point[2] control point P2 + point[3] ending point P3 + + The curve then has equation + + p(t) = P0*(1 - t)^3 + 3*P1*(1 - t)^2*t + 3*P2*(1 - t)*t^2 + P3*t^3 + + as t goes from 0 to 1. + + +SLVS_E_CIRCLE + + A complete circle. The circle lies within a plane with normal + + normal + + The circle is centered at + + point[0] + + The circle's radius is + + distance + + +SLVS_E_ARC_OF_CIRCLE + + An arc of a circle. An arc must always lie within a workplane; it + cannot be free in 3d. So it is specified with a workplane + + wrkpl + + It is then defined by three points + + point[0] center of the circle + point[1] beginning of the arc + point[2] end of the arc + + and its normal + + normal identical to the normal of the workplane + + The arc runs counter-clockwise from its beginning to its end (with + the workplane's normal pointing towards the viewer). If the beginning + and end of the arc are coincident, then the arc is considered to + represent a full circle. + + This representation has an extra degree of freedom. An extra + constraint is therefore generated implicitly, so that + + distance(center, beginning) = distance(center, end) + + +TYPES OF CONSTRAINTS +==================== + +Many constraints can apply either in 3d, or in a workplane. This is +determined by the wrkpl member of the constraint. If that member is set +to SLVS_FREE_IN_3D, then the constraint applies in 3d. If that member +is set equal to a workplane, the constraint applies projected into that +workplane. (For example, a constraint on the distance between two points +actually applies to the projected distance). + +Constraints that may be used in 3d or projected into a workplane are +marked with a single star (*). Constraints that must always be used with +a workplane are marked with a double star (**). Constraints that ignore +the wrkpl member are marked with no star. + +SLVS_C_PT_PT_DISTANCE* + + The distance between points ptA and ptB is equal to valA. This is an + unsigned distance, so valA must always be positive. + +SLVS_C_PROJ_PT_DISTANCE + + The distance between points ptA and ptB, as projected along the line + or normal entityA, is equal to valA. This is a signed distance. + +SLVS_C_POINTS_COINCIDENT* + + Points ptA and ptB are coincident (i.e., exactly on top of each + other). + +SLVS_C_PT_PLANE_DISTANCE + + The distance from point ptA to workplane entityA is equal to + valA. This is a signed distance; positive versus negative valA + correspond to a point that is above vs. below the plane. + +SLVS_C_PT_LINE_DISTANCE* + + The distance from point ptA to line segment entityA is equal to valA. + + If the constraint is projected, then valA is a signed distance; + positive versus negative valA correspond to a point that is above + vs. below the line. + + If the constraint applies in 3d, then valA must always be positive. + +SLVS_C_PT_IN_PLANE + + The point ptA lies in plane entityA. + +SLVS_C_PT_ON_LINE* + + The point ptA lies on the line entityA. + + Note that this constraint removes one degree of freedom when projected + in to the plane, but two degrees of freedom in 3d. + +SLVS_C_EQUAL_LENGTH_LINES* + + The lines entityA and entityB have equal length. + +SLVS_C_LENGTH_RATIO* + + The length of line entityA divided by the length of line entityB is + equal to valA. + +SLVS_C_LENGTH_DIFFERENCE* + + The lengths of line entityA and line entityB differ by valA. + +SLVS_C_EQ_LEN_PT_LINE_D* + + The length of the line entityA is equal to the distance from point + ptA to line entityB. + +SLVS_C_EQ_PT_LN_DISTANCES* + + The distance from the line entityA to the point ptA is equal to the + distance from the line entityB to the point ptB. + +SLVS_C_EQUAL_ANGLE* + + The angle between lines entityA and entityB is equal to the angle + between lines entityC and entityD. + + If other is true, then the angles are supplementary (i.e., theta1 = + 180 - theta2) instead of equal. + +SLVS_C_EQUAL_LINE_ARC_LEN* + + The length of the line entityA is equal to the length of the circular + arc entityB. + +SLVS_C_SYMMETRIC* + + The points ptA and ptB are symmetric about the plane entityA. This + means that they are on opposite sides of the plane and at equal + distances from the plane, and that the line connecting ptA and ptB + is normal to the plane. + +SLVS_C_SYMMETRIC_HORIZ +SLVS_C_SYMMETRIC_VERT** + + The points ptA and ptB are symmetric about the horizontal or vertical + axis of the specified workplane. + +SLVS_C_SYMMETRIC_LINE** + + The points ptA and ptB are symmetric about the line entityA. + +SLVS_C_AT_MIDPOINT* + + The point ptA lies at the midpoint of the line entityA. + +SLVS_C_HORIZONTAL +SLVS_C_VERTICAL** + + The line connecting points ptA and ptB is horizontal or vertical. Or, + the line segment entityA is horizontal or vertical. If points are + specified then the line segment should be left zero, and if a line + is specified then the points should be left zero. + +SLVS_C_DIAMETER + + The diameter of circle or arc entityA is equal to valA. + +SLVS_C_PT_ON_CIRCLE + + The point ptA lies on the right cylinder obtained by extruding circle + or arc entityA normal to its plane. + +SLVS_C_SAME_ORIENTATION + + The normals entityA and entityB describe identical rotations. This + constraint therefore restricts three degrees of freedom. + +SLVS_C_ANGLE* + + The angle between lines entityA and entityB is equal to valA, where + valA is specified in degrees. This constraint equation is written + in the form + + (A dot B)/(|A||B|) = cos(valA) + + where A and B are vectors in the directions of lines A and B. This + equation does not specify the angle unambiguously; for example, + note that valA = +/- 90 degrees will produce the same equation. + + If other is true, then the constraint is instead that + + (A dot B)/(|A||B|) = -cos(valA) + +SLVS_C_PERPENDICULAR* + + Identical to SLVS_C_ANGLE with valA = 90 degrees. + +SLVS_C_PARALLEL* + + Lines entityA and entityB are parallel. + + Note that this constraint removes one degree of freedom when projected + in to the plane, but two degrees of freedom in 3d. + +SLVS_C_ARC_LINE_TANGENT** + + The arc entityA is tangent to the line entityB. If other is false, + then the arc is tangent at its beginning (point[1]). If other is true, + then the arc is tangent at its end (point[2]). + +SLVS_C_CUBIC_LINE_TANGENT* + + The cubic entityA is tangent to the line entityB. The variable + other indicates: + + if false: the cubic is tangent at its beginning + if true: the cubic is tangent at its end + + The beginning of the cubic is point[0], and the end is point[3]. + +SLVS_C_CURVE_CURVE_TANGENT** + + The two entities entityA and entityB are tangent. These entities can + each be either an arc or a cubic, in any combination. The flags + other and other2 indicate which endpoint of the curve is tangent, + for entityA and entityB respectively: + + if false: the entity is tangent at its beginning + if true: the entity is tangent at its end + + For cubics, point[0] is the beginning, and point[3] is the end. For + arcs, point[1] is the beginning, and point[2] is the end. + +SLVS_C_EQUAL_RADIUS + + The circles or arcs entityA and entityB have equal radius. + +SLVS_C_WHERE_DRAGGED* + + The point ptA is locked at its initial numerical guess, and cannot + be moved. This constrains two degrees of freedom in a workplane, + and three in free space. It's therefore possible for this constraint + to overconstrain the sketch, for example if it's applied to a point + with one remaining degree of freedom. + + +USING THE SOLVER +================ + +The solver is provided as a DLL, and will be usable with most +Windows-based development tools. Examples are provided: + + in C/C++ - CDemo.c + + in VB.NET - VbDemo.vb + + +Copyright 2009-2013 Jonathan Westhues. + diff --git a/exposed/VbDemo.vb b/exposed/VbDemo.vb new file mode 100644 index 0000000..e702957 --- /dev/null +++ b/exposed/VbDemo.vb @@ -0,0 +1,1252 @@ +'----------------------------------------------------------------------------- +' Some sample code for slvs.dll. We draw some geometric entities, provide +' initial guesses for their positions, and then constrain them. The solver +' calculates their new positions, in order to satisfy the constraints. +' +' The library is distributed as a DLL, but the functions are designed to +' be usable from .net languages through a P/Invoke. This file contains an +' example of that process, and a wrapper class around those P/Invoke'd +' functions that you may wish to use a starting point in your own +' application. +' +' Copyright 2008-2013 Jonathan Westhues. +'----------------------------------------------------------------------------- + +Imports System.Runtime.InteropServices + +Module VbDemo + + ' Call our example functions, which set up some kind of sketch, solve + ' it, and then print the result. + Sub Main() + Console.WriteLine("EXAMPLE IN 3d (by objects):") + Example3dWithObjects() + Console.WriteLine("") + + Console.WriteLine("EXAMPLE IN 2d (by objects):") + Example2dWithObjects() + Console.WriteLine("") + + Console.WriteLine("EXAMPLE IN 3d (by handles):") + Example3dWithHandles() + Console.WriteLine("") + + Console.WriteLine("EXAMPLE IN 2d (by handles):") + Example2dWithHandles() + Console.WriteLine("") + End Sub + + + ''''''''''''''''''''''''''''''' + ' This is the simplest way to use the library. A set of wrapper + ' classes allow us to represent entities (e.g., lines and points) + ' as .net objects. So we create an Slvs object, which will contain + ' the entire sketch, with all the entities and constraints. + ' + ' We then create entity objects (for example, points and lines) + ' associated with that sketch, indicating the initial positions of + ' those entities and any hierarchical relationships among them (e.g., + ' defining a line entity in terms of endpoint entities). We also add + ' constraints associated with those entities. + ' + ' Finally, we solve, and print the new positions of the entities. If the + ' solution succeeded, then the entities will satisfy the constraints. If + ' not, then the solver will suggest problematic constraints that, if + ' removed, would render the sketch solvable. + + Sub Example3dWithObjects() + Dim g As UInteger + Dim slv As New Slvs + + ' This will contain a single group, which will arbitrarily number 1. + g = 1 + + Dim p1, p2 As Slvs.Point3d + ' A point, initially at (x y z) = (10 10 10) + p1 = slv.NewPoint3d(g, 10.0, 10.0, 10.0) + ' and a second point at (20 20 20) + p2 = slv.NewPoint3d(g, 20.0, 20.0, 20.0) + + Dim ln As Slvs.LineSegment + ' and a line segment connecting them. + ln = slv.NewLineSegment(g, slv.FreeIn3d(), p1, p2) + + ' The distance between the points should be 30.0 units. + slv.AddConstraint(1, g, Slvs.SLVS_C_PT_PT_DISTANCE, _ + slv.FreeIn3d(), 30.0, p1, p2, Nothing, Nothing) + + ' Let's tell the solver to keep the second point as close to constant + ' as possible, instead moving the first point. + slv.Solve(g, p2, True) + + If (slv.GetResult() = Slvs.SLVS_RESULT_OKAY) Then + ' We call the GetX(), GetY(), and GetZ() functions to see + ' where the solver moved our points to. + Console.WriteLine(String.Format( _ + "okay; now at ({0:F3}, {1:F3}, {2:F3})", _ + p1.GetX(), p1.GetY(), p1.GetZ())) + Console.WriteLine(String.Format( _ + " ({0:F3}, {1:F3}, {2:F3})", _ + p2.GetX(), p2.GetY(), p2.GetZ())) + Console.WriteLine(slv.GetDof().ToString() + " DOF") + Else + Console.WriteLine("solve failed") + End If + End Sub + + Sub Example2dWithObjects() + Dim g As UInteger + Dim slv As New Slvs + + g = 1 + + ' First, we create our workplane. Its origin corresponds to the origin + ' of our base frame (x y z) = (0 0 0) + Dim origin As Slvs.Point3d + origin = slv.NewPoint3d(g, 0.0, 0.0, 0.0) + ' and it is parallel to the xy plane, so it has basis vectors (1 0 0) + ' and (0 1 0). + Dim normal As Slvs.Normal3d + normal = slv.NewNormal3d(g, 1.0, 0.0, 0.0, _ + 0.0, 1.0, 0.0) + + Dim wrkpl As Slvs.Workplane + wrkpl = slv.NewWorkplane(g, origin, normal) + + ' Now create a second group. We'll solve group 2, while leaving group 1 + ' constant; so the workplane that we've created will be locked down, + ' and the solver can't move it. + g = 2 + ' These points are represented by their coordinates (u v) within the + ' workplane, so they need only two parameters each. + Dim pl1, pl2 As Slvs.Point2d + pl1 = slv.NewPoint2d(g, wrkpl, 10.0, 20.0) + pl2 = slv.NewPoint2d(g, wrkpl, 20.0, 10.0) + + ' And we create a line segment with those endpoints. + Dim ln As Slvs.LineSegment + ln = slv.NewLineSegment(g, wrkpl, pl1, pl2) + + ' Now three more points. + Dim pc, ps, pf As Slvs.Point2d + pc = slv.NewPoint2d(g, wrkpl, 100.0, 120.0) + ps = slv.NewPoint2d(g, wrkpl, 120.0, 110.0) + pf = slv.NewPoint2d(g, wrkpl, 115.0, 115.0) + + ' And arc, centered at point pc, starting at point ps, ending at + ' point pf. + Dim arc As Slvs.ArcOfCircle + arc = slv.NewArcOfCircle(g, wrkpl, normal, pc, ps, pf) + + ' Now one more point, and a distance + Dim pcc As Slvs.Point2d + pcc = slv.NewPoint2d(g, wrkpl, 200.0, 200.0) + Dim r As Slvs.Distance + r = slv.NewDistance(g, wrkpl, 30.0) + + ' And a complete circle, centered at point pcc with radius equal to + ' distance r. The normal is the same as for our workplane. + Dim circle As Slvs.Circle + circle = slv.NewCircle(g, wrkpl, pcc, normal, r) + + ' The length of our line segment is 30.0 units. + slv.AddConstraint(1, g, Slvs.SLVS_C_PT_PT_DISTANCE, _ + wrkpl, 30.0, pl1, pl2, Nothing, Nothing) + + ' And the distance from our line segment to the origin is 10.0 units. + slv.AddConstraint(2, g, Slvs.SLVS_C_PT_LINE_DISTANCE, _ + wrkpl, 10.0, origin, Nothing, ln, Nothing) + + ' And the line segment is vertical. + slv.AddConstraint(3, g, Slvs.SLVS_C_VERTICAL, _ + wrkpl, 0.0, Nothing, Nothing, ln, Nothing) + + ' And the distance from one endpoint to the origin is 15.0 units. + slv.AddConstraint(4, g, Slvs.SLVS_C_PT_PT_DISTANCE, _ + wrkpl, 15.0, pl1, origin, Nothing, Nothing) + + ' And same for the other endpoint; so if you add this constraint then + ' the sketch is overconstrained and will signal an error. + 'slv.AddConstraint(5, g, Slvs.SLVS_C_PT_PT_DISTANCE, _ + ' wrkpl, 18.0, pl2, origin, Nothing, Nothing) + + ' The arc and the circle have equal radius. + slv.AddConstraint(6, g, Slvs.SLVS_C_EQUAL_RADIUS, _ + wrkpl, 0.0, Nothing, Nothing, arc, circle) + + ' The arc has radius 17.0 units. + slv.AddConstraint(7, g, Slvs.SLVS_C_DIAMETER, _ + wrkpl, 2 * 17.0, Nothing, Nothing, arc, Nothing) + + ' If the solver fails, then ask it to report which constraints caused + ' the problem. + slv.Solve(g, True) + + If (slv.GetResult() = Slvs.SLVS_RESULT_OKAY) Then + Console.WriteLine("solved okay") + ' We call the GetU(), GetV(), and GetDistance() functions to + ' see where the solver moved our points and distances to. + Console.WriteLine(String.Format( _ + "line from ({0:F3} {1:F3}) to ({2:F3} {3:F3})", _ + pl1.GetU(), pl1.GetV(), _ + pl2.GetU(), pl2.GetV())) + Console.WriteLine(String.Format( _ + "arc center ({0:F3} {1:F3}) start ({2:F3} {3:F3}) " + _ + "finish ({4:F3} {5:F3})", _ + pc.GetU(), pc.GetV(), _ + ps.GetU(), ps.GetV(), _ + pf.GetU(), pf.GetV())) + Console.WriteLine(String.Format( _ + "circle center ({0:F3} {1:F3}) radius {2:F3}", _ + pcc.GetU(), pcc.GetV(), _ + r.GetDistance())) + + Console.WriteLine(slv.GetDof().ToString() + " DOF") + Else + Console.Write("solve failed; problematic constraints are:") + Dim t As UInteger + For Each t In slv.GetFaileds() + Console.Write(" " + t.ToString()) + Next + Console.WriteLine("") + If (slv.GetResult() = Slvs.SLVS_RESULT_INCONSISTENT) Then + Console.WriteLine("system inconsistent") + Else + Console.WriteLine("system nonconvergent") + End If + End If + + End Sub + + + ''''''''''''''''''''''''''''''' + ' This is a lower-level way to use the library. Internally, the library + ' represents parameters, entities, and constraints by integer handles. + ' Here, those handles are assigned manually, and not by the wrapper + ' classes. + + Sub Example3dWithHandles() + Dim g As UInteger + Dim slv As New Slvs + + ' This will contain a single group, which will arbitrarily number 1. + g = 1 + + ' A point, initially at (x y z) = (10 10 10) + slv.AddParam(1, g, 10.0) + slv.AddParam(2, g, 10.0) + slv.AddParam(3, g, 10.0) + slv.AddPoint3d(101, g, 1, 2, 3) + + ' and a second point at (20 20 20) + slv.AddParam(4, g, 20.0) + slv.AddParam(5, g, 20.0) + slv.AddParam(6, g, 20.0) + slv.AddPoint3d(102, g, 4, 5, 6) + + ' and a line segment connecting them. + slv.AddLineSegment(200, g, Slvs.SLVS_FREE_IN_3D, 101, 102) + + ' The distance between the points should be 30.0 units. + slv.AddConstraint(1, g, Slvs.SLVS_C_PT_PT_DISTANCE, _ + Slvs.SLVS_FREE_IN_3D, 30.0, 101, 102, 0, 0) + + ' Let's tell the solver to keep the second point as close to constant + ' as possible, instead moving the first point. That's parameters + ' 4, 5, and 6. + slv.Solve(g, 4, 5, 6, 0, True) + + If (slv.GetResult() = Slvs.SLVS_RESULT_OKAY) Then + ' Note that we are referring to the parameters by their handles, + ' and not by their index in the list. This is a difference from + ' the C example. + Console.WriteLine(String.Format( _ + "okay; now at ({0:F3}, {1:F3}, {2:F3})", _ + slv.GetParamByHandle(1), slv.GetParamByHandle(2), _ + slv.GetParamByHandle(3))) + Console.WriteLine(String.Format( _ + " ({0:F3}, {1:F3}, {2:F3})", _ + slv.GetParamByHandle(4), slv.GetParamByHandle(5), _ + slv.GetParamByHandle(6))) + Console.WriteLine(slv.GetDof().ToString() + " DOF") + Else + Console.WriteLine("solve failed") + End If + End Sub + + + Sub Example2dWithHandles() + Dim g As UInteger + Dim qw, qx, qy, qz As Double + + Dim slv As New Slvs + + g = 1 + + ' First, we create our workplane. Its origin corresponds to the origin + ' of our base frame (x y z) = (0 0 0) + slv.AddParam(1, g, 0.0) + slv.AddParam(2, g, 0.0) + slv.AddParam(3, g, 0.0) + slv.AddPoint3d(101, g, 1, 2, 3) + ' and it is parallel to the xy plane, so it has basis vectors (1 0 0) + ' and (0 1 0). + slv.MakeQuaternion(1, 0, 0, _ + 0, 1, 0, qw, qx, qy, qz) + slv.AddParam(4, g, qw) + slv.AddParam(5, g, qx) + slv.AddParam(6, g, qy) + slv.AddParam(7, g, qz) + slv.AddNormal3d(102, g, 4, 5, 6, 7) + + slv.AddWorkplane(200, g, 101, 102) + + ' Now create a second group. We'll solve group 2, while leaving group 1 + ' constant; so the workplane that we've created will be locked down, + ' and the solver can't move it. + g = 2 + ' These points are represented by their coordinates (u v) within the + ' workplane, so they need only two parameters each. + slv.AddParam(11, g, 10.0) + slv.AddParam(12, g, 20.0) + slv.AddPoint2d(301, g, 200, 11, 12) + + slv.AddParam(13, g, 20.0) + slv.AddParam(14, g, 10.0) + slv.AddPoint2d(302, g, 200, 13, 14) + + ' And we create a line segment with those endpoints. + slv.AddLineSegment(400, g, 200, 301, 302) + + ' Now three more points. + slv.AddParam(15, g, 100.0) + slv.AddParam(16, g, 120.0) + slv.AddPoint2d(303, g, 200, 15, 16) + + slv.AddParam(17, g, 120.0) + slv.AddParam(18, g, 110.0) + slv.AddPoint2d(304, g, 200, 17, 18) + + slv.AddParam(19, g, 115.0) + slv.AddParam(20, g, 115.0) + slv.AddPoint2d(305, g, 200, 19, 20) + + ' And arc, centered at point 303, starting at point 304, ending at + ' point 305. + slv.AddArcOfCircle(401, g, 200, 102, 303, 304, 305) + + ' Now one more point, and a distance + slv.AddParam(21, g, 200.0) + slv.AddParam(22, g, 200.0) + slv.AddPoint2d(306, g, 200, 21, 22) + + slv.AddParam(23, g, 30.0) + slv.AddDistance(307, g, 200, 23) + + ' And a complete circle, centered at point 306 with radius equal to + ' distance 307. The normal is 102, the same as our workplane. + slv.AddCircle(402, g, 200, 306, 102, 307) + + ' The length of our line segment is 30.0 units. + slv.AddConstraint(1, g, Slvs.SLVS_C_PT_PT_DISTANCE, _ + 200, 30.0, 301, 302, 0, 0) + + ' And the distance from our line segment to the origin is 10.0 units. + slv.AddConstraint(2, g, Slvs.SLVS_C_PT_LINE_DISTANCE, _ + 200, 10.0, 101, 0, 400, 0) + + ' And the line segment is vertical. + slv.AddConstraint(3, g, Slvs.SLVS_C_VERTICAL, _ + 200, 0.0, 0, 0, 400, 0) + + ' And the distance from one endpoint to the origin is 15.0 units. + slv.AddConstraint(4, g, Slvs.SLVS_C_PT_PT_DISTANCE, _ + 200, 15.0, 301, 101, 0, 0) + + ' And same for the other endpoint; so if you add this constraint then + ' the sketch is overconstrained and will signal an error. + 'slv.AddConstraint(5, g, Slvs.SLVS_C_PT_PT_DISTANCE, _ + ' 200, 18.0, 302, 101, 0, 0) + + ' The arc and the circle have equal radius. + slv.AddConstraint(6, g, Slvs.SLVS_C_EQUAL_RADIUS, _ + 200, 0.0, 0, 0, 401, 402) + + ' The arc has radius 17.0 units. + slv.AddConstraint(7, g, Slvs.SLVS_C_DIAMETER, _ + 200, 2 * 17.0, 0, 0, 401, 0) + + ' If the solver fails, then ask it to report which constraints caused + ' the problem. + slv.Solve(g, 0, 0, 0, 0, True) + + If (slv.GetResult() = Slvs.SLVS_RESULT_OKAY) Then + Console.WriteLine("solved okay") + ' Note that we are referring to the parameters by their handles, + ' and not by their index in the list. This is a difference from + ' the C example. + Console.WriteLine(String.Format( _ + "line from ({0:F3} {1:F3}) to ({2:F3} {3:F3})", _ + slv.GetParamByHandle(11), slv.GetParamByHandle(12), _ + slv.GetParamByHandle(13), slv.GetParamByHandle(14))) + Console.WriteLine(String.Format( _ + "arc center ({0:F3} {1:F3}) start ({2:F3} {3:F3}) " + _ + "finish ({4:F3} {5:F3})", _ + slv.GetParamByHandle(15), slv.GetParamByHandle(16), _ + slv.GetParamByHandle(17), slv.GetParamByHandle(18), _ + slv.GetParamByHandle(19), slv.GetParamByHandle(20))) + Console.WriteLine(String.Format( _ + "circle center ({0:F3} {1:F3}) radius {2:F3}", _ + slv.GetParamByHandle(21), slv.GetParamByHandle(22), _ + slv.GetParamByHandle(23))) + + Console.WriteLine(slv.GetDof().ToString() + " DOF") + Else + Console.Write("solve failed; problematic constraints are:") + Dim t As UInteger + For Each t In slv.GetFaileds() + Console.Write(" " + t.ToString()) + Next + Console.WriteLine("") + If (slv.GetResult() = Slvs.SLVS_RESULT_INCONSISTENT) Then + Console.WriteLine("system inconsistent") + Else + Console.WriteLine("system nonconvergent") + End If + End If + + End Sub + + + ''''''''''''''''''''''''''''''' + ' The interface to the library, and the wrapper functions around + ' that interface, follow. + + ' These are the core functions imported from the DLL + _ + Public Sub Slvs_Solve(ByVal sys As IntPtr, ByVal hg As UInteger) + End Sub + + _ + Public Sub Slvs_MakeQuaternion( + ByVal ux As Double, ByVal uy As Double, ByVal uz As Double, + ByVal vx As Double, ByVal vy As Double, ByVal vz As Double, + ByRef qw As Double, ByRef qx As Double, ByRef qy As Double, + ByRef qz As Double) + End Sub + + ' And this is a thin wrapper around those functions, which provides + ' convenience functions similar to those provided in slvs.h for the C API. + Public Class Slvs + + Public Structure Slvs_Param + Public h As UInteger + Public group As UInteger + Public val As Double + End Structure + + Public Const SLVS_FREE_IN_3D As Integer = 0 + + Public Const SLVS_E_POINT_IN_3D As Integer = 50000 + Public Const SLVS_E_POINT_IN_2D As Integer = 50001 + Public Const SLVS_E_NORMAL_IN_3D As Integer = 60000 + Public Const SLVS_E_NORMAL_IN_2D As Integer = 60001 + Public Const SLVS_E_DISTANCE As Integer = 70000 + Public Const SLVS_E_WORKPLANE As Integer = 80000 + Public Const SLVS_E_LINE_SEGMENT As Integer = 80001 + Public Const SLVS_E_CUBIC As Integer = 80002 + Public Const SLVS_E_CIRCLE As Integer = 80003 + Public Const SLVS_E_ARC_OF_CIRCLE As Integer = 80004 + + Public Structure Slvs_Entity + Public h As UInteger + Public group As UInteger + + Public type As Integer + + Public wrkpl As UInteger + Public point0 As UInteger + Public point1 As UInteger + Public point2 As UInteger + Public point3 As UInteger + Public normal As UInteger + Public distance As UInteger + + Public param0 As UInteger + Public param1 As UInteger + Public param2 As UInteger + Public param3 As UInteger + End Structure + + Public Const SLVS_C_POINTS_COINCIDENT As Integer = 100000 + Public Const SLVS_C_PT_PT_DISTANCE As Integer = 100001 + Public Const SLVS_C_PT_PLANE_DISTANCE As Integer = 100002 + Public Const SLVS_C_PT_LINE_DISTANCE As Integer = 100003 + Public Const SLVS_C_PT_FACE_DISTANCE As Integer = 100004 + Public Const SLVS_C_PT_IN_PLANE As Integer = 100005 + Public Const SLVS_C_PT_ON_LINE As Integer = 100006 + Public Const SLVS_C_PT_ON_FACE As Integer = 100007 + Public Const SLVS_C_EQUAL_LENGTH_LINES As Integer = 100008 + Public Const SLVS_C_LENGTH_RATIO As Integer = 100009 + Public Const SLVS_C_EQ_LEN_PT_LINE_D As Integer = 100010 + Public Const SLVS_C_EQ_PT_LN_DISTANCES As Integer = 100011 + Public Const SLVS_C_EQUAL_ANGLE As Integer = 100012 + Public Const SLVS_C_EQUAL_LINE_ARC_LEN As Integer = 100013 + Public Const SLVS_C_SYMMETRIC As Integer = 100014 + Public Const SLVS_C_SYMMETRIC_HORIZ As Integer = 100015 + Public Const SLVS_C_SYMMETRIC_VERT As Integer = 100016 + Public Const SLVS_C_SYMMETRIC_LINE As Integer = 100017 + Public Const SLVS_C_AT_MIDPOINT As Integer = 100018 + Public Const SLVS_C_HORIZONTAL As Integer = 100019 + Public Const SLVS_C_VERTICAL As Integer = 100020 + Public Const SLVS_C_DIAMETER As Integer = 100021 + Public Const SLVS_C_PT_ON_CIRCLE As Integer = 100022 + Public Const SLVS_C_SAME_ORIENTATION As Integer = 100023 + Public Const SLVS_C_ANGLE As Integer = 100024 + Public Const SLVS_C_PARALLEL As Integer = 100025 + Public Const SLVS_C_PERPENDICULAR As Integer = 100026 + Public Const SLVS_C_ARC_LINE_TANGENT As Integer = 100027 + Public Const SLVS_C_CUBIC_LINE_TANGENT As Integer = 100028 + Public Const SLVS_C_EQUAL_RADIUS As Integer = 100029 + Public Const SLVS_C_PROJ_PT_DISTANCE As Integer = 100030 + Public Const SLVS_C_WHERE_DRAGGED As Integer = 100031 + Public Const SLVS_C_CURVE_CURVE_TANGENT As Integer = 100032 + Public Const SLVS_C_LENGTH_DIFFERENCE As Integer = 100033 + + Public Structure Slvs_Constraint + Public h As UInteger + Public group As UInteger + + Public type As Integer + + Public wrkpl As UInteger + + Public valA As Double + Public ptA As UInteger + Public ptB As UInteger + Public entityA As UInteger + Public entityB As UInteger + Public entityC As UInteger + Public entityD As UInteger + + Public other As Integer + Public other2 As Integer + End Structure + + Public Const SLVS_RESULT_OKAY As Integer = 0 + Public Const SLVS_RESULT_INCONSISTENT As Integer = 1 + Public Const SLVS_RESULT_DIDNT_CONVERGE As Integer = 2 + Public Const SLVS_RESULT_TOO_MANY_UNKNOWNS As Integer = 3 + + Public Structure Slvs_System + Public param As IntPtr + Public params As Integer + Public entity As IntPtr + Public entities As Integer + Public constraint As IntPtr + Public constraints As Integer + + Public dragged0 As UInteger + Public dragged1 As UInteger + Public dragged2 As UInteger + Public dragged3 As UInteger + + Public calculatedFaileds As Integer + + Public failed As IntPtr + Public faileds As Integer + + Public dof As Integer + + Public result As Integer + End Structure + + Dim Params As New List(Of Slvs_Param) + Dim Entities As New List(Of Slvs_Entity) + Dim Constraints As New List(Of Slvs_Constraint) + + Dim Faileds As New List(Of UInteger) + + Dim Result As Integer + Dim Dof As Integer + + ' Return the value of a parameter, by its handle. This function + ' may be used, for example, to obtain the new values of the + ' parameters after a call to Solve(). + Public Function GetParamByHandle(ByVal h As UInteger) As Double + Dim t As Slvs_Param + For Each t In Params + If (t.h = h) Then + Return t.val + End If + Next + Throw New Exception("Invalid parameter handle.") + End Function + + ' Return the value of a parameter, by its index in the list (where + ' that index is determined by the order in which the parameters + ' were inserted with AddParam(), not by its handle). + Public Function GetParamByIndex(ByVal i As Integer) As Double + Return Params(i).val + End Function + + ' Get the result after a call to Solve(). This may be + ' SLVS_RESULT_OKAY - it worked + ' SLVS_RESULT_INCONSISTENT - failed, inconsistent + ' SLVS_RESULT_DIDNT_CONVERGE - consistent, but still failed + ' SLVS_RESULT_TOO_MANY_UNKNOWNS - too many parameters in one group + Public Function GetResult() As Integer + Return Result + End Function + + ' After a call to Solve(), this returns the number of unconstrained + ' degrees of freedom for the sketch. + Public Function GetDof() As Integer + Return Dof + End Function + + ' After a failing call to Solve(), this returns the list of + ' constraints, identified by their handle, that would fix the + ' system if they were deleted. This list will be populated only + ' if calculateFaileds is True in the Solve() call. + Public Function GetFaileds() As List(Of UInteger) + Return Faileds + End Function + + ' Clear our lists of entities, constraints, and parameters. + Public Sub ResetAll() + Params.Clear() + Entities.Clear() + Constraints.Clear() + End Sub + + + ''''''''''''''''''''''''''''''' + ' These functions are broadly similar to the Slvs_Make... + ' functions in slvs.h. See the file DOC.txt accompanying the + ' library for details. + + Public Sub AddParam(ByVal h As UInteger, ByVal group As UInteger, + ByVal val As Double) + Dim p As Slvs_Param + p.h = h + p.group = group + p.val = val + Params.Add(p) + End Sub + + Public Sub AddPoint2d(ByVal h As UInteger, ByVal group As UInteger, + ByVal wrkpl As UInteger, + ByVal u As UInteger, ByVal v As UInteger) + Dim e As Slvs_Entity + e.h = h + e.group = group + e.type = SLVS_E_POINT_IN_2D + e.wrkpl = wrkpl + e.param0 = u + e.param1 = v + Entities.Add(e) + End Sub + + Public Sub AddPoint3d(ByVal h As UInteger, ByVal group As UInteger, + ByVal x As UInteger, ByVal y As UInteger, ByVal z As UInteger) + Dim e As Slvs_Entity + e.h = h + e.group = group + e.type = SLVS_E_POINT_IN_3D + e.wrkpl = SLVS_FREE_IN_3D + e.param0 = x + e.param1 = y + e.param2 = z + Entities.Add(e) + End Sub + + Public Sub AddNormal3d(ByVal h As UInteger, ByVal group As UInteger, + ByVal qw As UInteger, ByVal qx As UInteger, + ByVal qy As UInteger, ByVal qz As UInteger) + Dim e As Slvs_Entity + e.h = h + e.group = group + e.type = SLVS_E_NORMAL_IN_3D + e.wrkpl = SLVS_FREE_IN_3D + e.param0 = qw + e.param1 = qx + e.param2 = qy + e.param3 = qz + Entities.Add(e) + End Sub + + Public Sub AddNormal2d(ByVal h As UInteger, ByVal group As UInteger, + ByVal wrkpl As UInteger) + Dim e As Slvs_Entity + e.h = h + e.group = group + e.type = SLVS_E_NORMAL_IN_2D + e.wrkpl = wrkpl + Entities.Add(e) + End Sub + + Public Sub AddDistance(ByVal h As UInteger, ByVal group As UInteger, + ByVal wrkpl As UInteger, ByVal d As UInteger) + Dim e As Slvs_Entity + e.h = h + e.group = group + e.type = SLVS_E_DISTANCE + e.wrkpl = wrkpl + e.param0 = d + Entities.Add(e) + End Sub + + Public Sub AddLineSegment(ByVal h As UInteger, ByVal group As UInteger, + ByVal wrkpl As UInteger, + ByVal ptA As UInteger, ByVal ptB As UInteger) + Dim e As Slvs_Entity + e.h = h + e.group = group + e.type = SLVS_E_LINE_SEGMENT + e.wrkpl = wrkpl + e.point0 = ptA + e.point1 = ptB + Entities.Add(e) + End Sub + + Public Sub AddCubic(ByVal h As UInteger, ByVal group As UInteger, + ByVal wrkpl As UInteger, + ByVal pt0 As UInteger, ByVal pt1 As UInteger, + ByVal pt2 As UInteger, ByVal pt3 As UInteger) + Dim e As Slvs_Entity + e.h = h + e.group = group + e.type = SLVS_E_CUBIC + e.wrkpl = wrkpl + e.point0 = pt0 + e.point1 = pt1 + e.point2 = pt2 + e.point3 = pt3 + Entities.Add(e) + End Sub + + Public Sub AddArcOfCircle(ByVal h As UInteger, ByVal group As UInteger, + ByVal wrkpl As UInteger, + ByVal normal As UInteger, + ByVal center As UInteger, + ByVal pstart As UInteger, + ByVal pend As UInteger) + Dim e As Slvs_Entity + e.h = h + e.group = group + e.type = SLVS_E_ARC_OF_CIRCLE + e.wrkpl = wrkpl + e.normal = normal + e.point0 = center + e.point1 = pstart + e.point2 = pend + Entities.Add(e) + End Sub + + Public Sub AddCircle(ByVal h As UInteger, ByVal group As UInteger, + ByVal wrkpl As UInteger, + ByVal center As UInteger, ByVal normal As UInteger, + ByVal radius As UInteger) + Dim e As Slvs_Entity + e.h = h + e.group = group + e.type = SLVS_E_CIRCLE + e.wrkpl = wrkpl + e.point0 = center + e.normal = normal + e.distance = radius + Entities.Add(e) + End Sub + + Public Sub AddWorkplane(ByVal h As UInteger, ByVal group As UInteger, + ByVal origin As UInteger, + ByVal normal As UInteger) + Dim e As Slvs_Entity + e.h = h + e.group = group + e.type = SLVS_E_WORKPLANE + e.wrkpl = SLVS_FREE_IN_3D + e.point0 = origin + e.normal = normal + Entities.Add(e) + End Sub + + Public Sub AddConstraint(ByVal h As UInteger, + ByVal group As UInteger, + ByVal type As Integer, + ByVal wrkpl As UInteger, + ByVal valA As Double, + ByVal ptA As UInteger, + ByVal ptB As UInteger, + ByVal entityA As UInteger, + ByVal entityB As UInteger) + Dim c As Slvs_Constraint + c.h = h + c.group = group + c.type = type + c.wrkpl = wrkpl + c.valA = valA + c.ptA = ptA + c.ptB = ptB + c.entityA = entityA + c.entityB = entityB + Constraints.Add(c) + End Sub + + ' Solve the system. The geometry of the system must already have + ' been specified through the Add...() calls. The result of the + ' solution process may be obtained by calling GetResult(), + ' GetFaileds(), GetDof(), and GetParamByXXX(). + ' + ' The parameters draggedx (indicated by their handles) will be held + ' as close as possible to their original positions, even if this + ' results in large moves for other parameters. This feature may be + ' useful if, for example, the user is dragging the point whose + ' location is defined by those parameters. Unused draggedx + ' parameters may be specified as zero. + Public Sub Solve(ByVal group As UInteger, + ByVal dragged0 As UInteger, ByVal dragged1 As UInteger, + ByVal dragged2 As UInteger, ByVal dragged3 As UInteger, + ByVal calculateFaileds As Boolean) + Dim i As Integer + + Dim pp, p(Params.Count()) As Slvs_Param + i = 0 + For Each pp In Params + p(i) = pp + i += 1 + Next + + Dim ee, e(Entities.Count()) As Slvs_Entity + i = 0 + For Each ee In Entities + e(i) = ee + i += 1 + Next + + Dim cc, c(Constraints.Count()) As Slvs_Constraint + i = 0 + For Each cc In Constraints + c(i) = cc + i += 1 + Next + Dim f(Constraints.Count()) As UInteger + + Dim sys As Slvs_System + + Dim pgc, egc, cgc As GCHandle + pgc = GCHandle.Alloc(p, GCHandleType.Pinned) + sys.param = pgc.AddrOfPinnedObject() + sys.params = Params.Count() + egc = GCHandle.Alloc(e, GCHandleType.Pinned) + sys.entity = egc.AddrOfPinnedObject() + sys.entities = Entities.Count() + cgc = GCHandle.Alloc(c, GCHandleType.Pinned) + sys.constraint = cgc.AddrOfPinnedObject() + sys.constraints = Constraints.Count() + + sys.dragged0 = dragged0 + sys.dragged1 = dragged1 + sys.dragged2 = dragged2 + sys.dragged3 = dragged3 + + Dim fgc As GCHandle + fgc = GCHandle.Alloc(f, GCHandleType.Pinned) + If calculateFaileds Then + sys.calculatedFaileds = 1 + Else + sys.calculatedFaileds = 0 + End If + sys.faileds = Constraints.Count() + sys.failed = fgc.AddrOfPinnedObject() + + Dim sysgc As GCHandle + sysgc = GCHandle.Alloc(sys, GCHandleType.Pinned) + + Slvs_Solve(sysgc.AddrOfPinnedObject(), group) + + sys = sysgc.Target + + For i = 0 To Params.Count() - 1 + Params(i) = p(i) + Next + + Faileds.Clear() + For i = 0 To sys.faileds - 1 + Faileds.Add(f(i)) + Next + + sysgc.Free() + fgc.Free() + pgc.Free() + egc.Free() + cgc.Free() + + Result = sys.result + Dof = sys.dof + End Sub + ' A simpler version of the function, if the parameters being dragged + ' correspond to a single point. + Public Sub Solve(ByVal group As UInteger, ByVal dragged As Point, + ByVal calculatedFaileds As Boolean) + If TypeOf dragged Is Point2d Then + Dim p As Point2d + p = dragged + Solve(group, p.up.H, p.vp.H, 0, 0, calculatedFaileds) + ElseIf TypeOf dragged Is Point3d Then + Dim p As Point3d + p = dragged + Solve(group, p.xp.H, p.yp.H, p.zp.H, 0, calculatedFaileds) + Else + Throw New Exception("Can't get dragged params for point.") + End If + End Sub + ' or if it's a single distance (e.g., the radius of a circle) + Public Sub Solve(ByVal group As UInteger, ByVal dragged As Distance, + ByVal calculatedFaileds As Boolean) + Solve(group, dragged.dp.H, 0, 0, 0, calculatedFaileds) + End Sub + ' or if it's nothing. + Public Sub Solve(ByVal group As UInteger, + ByVal calculateFaileds As Boolean) + Solve(group, 0, 0, 0, 0, calculateFaileds) + End Sub + + ' Return the quaternion in (qw, qx, qy, qz) that represents a + ' rotation from the base frame to a coordinate system with the + ' specified basis vectors u and v. For example, u = (0, 1, 0) + ' and v = (0, 0, 1) specifies the yz plane, such that a point with + ' (u, v) = (7, 12) has (x, y, z) = (0, 7, 12). + Public Sub MakeQuaternion( + ByVal ux As Double, ByVal uy As Double, ByVal uz As Double, + ByVal vx As Double, ByVal vy As Double, ByVal vz As Double, + ByRef qw As Double, ByRef qx As Double, ByRef qy As Double, + ByRef qz As Double) + Slvs_MakeQuaternion(ux, uy, uz, _ + vx, vy, vz, _ + qw, qx, qy, qz) + End Sub + + Public Function FreeIn3d() + Return New Workplane(Me) + End Function + + + ''''''''''''''''''''''''''''''' + ' Functions to create the object-oriented wrappers defined below. + + Public Function NewParam(ByVal group As UInteger, ByVal val As Double) + Return New Param(Me, group, val) + End Function + Public Function NewPoint2d(ByVal group As UInteger, + ByVal wrkpl As Workplane, + ByVal u As Double, ByVal v As Double) + Return New Point2d(Me, group, wrkpl, u, v) + End Function + Public Function NewPoint2d(ByVal group As UInteger, + ByVal wrkpl As Workplane, + ByVal u As Param, ByVal v As Param) + Return New Point2d(Me, group, wrkpl, u, v) + End Function + Public Function NewPoint3d(ByVal group As UInteger, + ByVal x As Double, + ByVal y As Double, + ByVal z As Double) + Return New Point3d(Me, group, x, y, z) + End Function + Public Function NewPoint3d(ByVal group As UInteger, + ByVal x As Param, + ByVal y As Param, + ByVal z As Param) + Return New Point3d(Me, group, x, y, z) + End Function + Public Function NewNormal3d(ByVal group As UInteger, + ByVal ux As Double, ByVal uy As Double, ByVal uz As Double, + ByVal vx As Double, ByVal vy As Double, ByVal vz As Double) + Return New Normal3d(Me, group, ux, uy, uz, vx, vy, vz) + End Function + Public Function NewNormal3d(ByVal group As UInteger, + ByVal qw As Param, ByVal qx As Param, + ByVal qy As Param, ByVal qz As Param) + Return New Normal3d(Me, group, qw, qx, qy, qz) + End Function + Public Function NewNormal2d(ByVal group As UInteger, + ByVal wrkpl As Workplane) + Return New Normal2d(Me, group, wrkpl) + End Function + Public Function NewDistance(ByVal group As UInteger, + ByVal wrkpl As Workplane, ByVal d As Double) + Return New Distance(Me, group, wrkpl, d) + End Function + Public Function NewDistance(ByVal group As UInteger, + ByVal wrkpl As Workplane, ByVal d As Param) + Return New Distance(Me, group, wrkpl, d) + End Function + Public Function NewLineSegment(ByVal group As UInteger, + ByVal wrkpl As Workplane, + ByVal ptA As Point, ByVal ptB As Point) + Return New LineSegment(Me, group, wrkpl, ptA, ptB) + End Function + Public Function NewArcOfCircle(ByVal group As UInteger, + ByVal wrkpl As Workplane, + ByVal normal As Normal, + ByVal center As Point, + ByVal pstart As Point, + ByVal pend As Point) + Return New ArcOfCircle(Me, group, wrkpl, normal, _ + center, pstart, pend) + End Function + Public Function NewCircle(ByVal group As UInteger, + ByVal wrkpl As Workplane, + ByVal center As Point, + ByVal normal As Normal, + ByVal radius As Distance) + Return New Circle(Me, group, wrkpl, center, normal, radius) + End Function + Public Function NewWorkplane(ByVal group As UInteger, + ByVal origin As Point, + ByVal normal As Normal) + Return New Workplane(Me, group, origin, normal) + End Function + + Public Sub AddConstraint(ByVal H As UInteger, ByVal group As UInteger, + ByVal type As Integer, + ByVal wrkpl As Workplane, + ByVal valA As Double, + ByVal ptA As Point, ByVal ptB As Point, + ByVal entityA As Entity, + ByVal entityB As Entity) + AddConstraint(H, group, type, _ + If(IsNothing(wrkpl), 0, wrkpl.H), _ + valA, _ + If(IsNothing(ptA), 0, ptA.H), _ + If(IsNothing(ptB), 0, ptB.H), _ + If(IsNothing(entityA), 0, entityA.H), _ + If(IsNothing(entityB), 0, entityB.H)) + End Sub + + + ''''''''''''''''''''''''''''''' + ' The object-oriented wrapper classes themselves, to allow the + ' representation of entities and constraints as .net objects, not + ' integer handles. These don't do any work themselves, beyond + ' allocating and storing a unique integer handle. + ' + ' These functions will assign parameters and entities with + ' consecutive handles starting from 1. If they are intermixed + ' with parameters and entities with user-specified handles, then + ' those handles must be chosen not to conflict, e.g. starting + ' from 100 000 or another large number. + + Public Class Param + Public Slv As Slvs + Public H As UInteger + + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal val As Double) + Slv = s + H = Slv.Params.Count() + 1 + Slv.AddParam(H, group, val) + End Sub + End Class + + Public MustInherit Class Entity + Public Slv As Slvs + Public H As UInteger + + Public Sub New(ByVal s As Slvs) + Slv = s + H = Slv.Entities.Count() + 1 + End Sub + End Class + + Public MustInherit Class Point + Inherits Entity + Public Sub New(ByVal s As Slvs) + MyBase.New(s) + End Sub + End Class + + Public MustInherit Class Normal + Inherits Entity + Public Sub New(ByVal s As Slvs) + MyBase.New(s) + End Sub + End Class + + Public Class Point2d + Inherits Point + Public up, vp As Param + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal wrkpl As Workplane, + ByVal u As Double, ByVal v As Double) + MyBase.New(s) + up = New Param(Slv, group, u) + vp = New Param(Slv, group, v) + Slv.AddPoint2d(H, group, wrkpl.H, up.H, vp.H) + End Sub + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal wrkpl As Workplane, + ByVal u As Param, ByVal v As Param) + MyBase.New(s) + Slv.AddPoint2d(H, group, wrkpl.H, u.H, v.H) + up = u + vp = v + End Sub + Function GetU() + Return Slv.GetParamByHandle(up.H) + End Function + Function GetV() + Return Slv.GetParamByHandle(vp.H) + End Function + End Class + + Public Class Point3d + Inherits Point + Public xp, yp, zp As Param + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal x As Double, ByVal y As Double, + ByVal z As Double) + MyBase.New(s) + xp = New Param(Slv, group, x) + yp = New Param(Slv, group, y) + zp = New Param(Slv, group, z) + Slv.AddPoint3d(H, group, xp.H, yp.H, zp.H) + End Sub + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal x As Param, ByVal y As Param, ByVal z As Param) + MyBase.New(s) + Slv.AddPoint3d(H, group, x.H, y.H, z.H) + xp = x + yp = y + zp = z + End Sub + Function GetX() + Return Slv.GetParamByHandle(xp.H) + End Function + Function GetY() + Return Slv.GetParamByHandle(yp.H) + End Function + Function GetZ() + Return Slv.GetParamByHandle(zp.H) + End Function + End Class + + Public Class Normal3d + Inherits Normal + Dim qwp, qxp, qyp, qzp As Param + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal ux As Double, ByVal uy As Double, ByVal uz As Double, + ByVal vx As Double, ByVal vy As Double, ByVal vz As Double) + MyBase.New(s) + Dim qw, qx, qy, qz As Double + Slv.MakeQuaternion(ux, uy, uz, vx, vy, vz, qw, qx, qy, qz) + qwp = New Param(Slv, group, qw) + qxp = New Param(Slv, group, qx) + qyp = New Param(Slv, group, qy) + qzp = New Param(Slv, group, qz) + Slv.AddNormal3d(H, group, qwp.H, qxp.H, qyp.H, qzp.H) + End Sub + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal qw As Param, ByVal qx As Param, + ByVal qy As Param, ByVal qz As Param) + MyBase.New(s) + Slv.AddNormal3d(H, group, qw.H, qx.H, qy.H, qz.H) + qwp = qw + qxp = qx + qyp = qy + qzp = qz + End Sub + End Class + + Public Class Normal2d + Inherits Normal + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal wrkpl As Workplane) + MyBase.New(s) + Slv.AddNormal2d(H, group, wrkpl.H) + End Sub + End Class + + Public Class Distance + Inherits Entity + Public dp As Param + + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal wrkpl As Workplane, ByVal d As Double) + MyBase.New(s) + dp = New Param(Slv, group, d) + Slv.AddDistance(H, group, wrkpl.H, dp.H) + End Sub + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal wrkpl As Workplane, ByVal d As Param) + MyBase.New(s) + Slv.AddDistance(H, group, wrkpl.H, d.H) + dp = d + End Sub + Function GetDistance() As Double + Return Slv.GetParamByHandle(dp.H) + End Function + End Class + + Public Class LineSegment + Inherits Entity + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal wrkpl As Workplane, + ByVal ptA As Point, ByVal ptB As Point) + MyBase.New(s) + Slv.AddLineSegment(H, group, wrkpl.H, ptA.H, ptB.H) + End Sub + End Class + + Public Class Cubic + Inherits Entity + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal wrkpl As Workplane, + ByVal pt0 As Point, ByVal pt1 As Point, + ByVal pt2 As Point, ByVal pt3 As Point) + MyBase.New(s) + Slv.AddCubic(H, group, wrkpl.H, pt0.H, pt1.H, pt2.H, pt3.H) + End Sub + End Class + + Public Class ArcOfCircle + Inherits Entity + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal wrkpl As Workplane, ByVal normal As Normal, + ByVal center As Point, ByVal pstart As Point, + ByVal pend As Point) + MyBase.New(s) + Slv.AddArcOfCircle(H, group, wrkpl.H, normal.H, _ + center.H, pstart.H, pend.H) + End Sub + End Class + + Public Class Circle + Inherits Entity + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal wrkpl As Workplane, ByVal center As Point, + ByVal normal As Normal, ByVal radius As Distance) + MyBase.New(s) + Slv.AddCircle(H, group, wrkpl.H, center.H, normal.H, radius.H) + End Sub + End Class + + Public Class Workplane + Inherits Entity + Public Sub New(ByVal s As Slvs) + MyBase.New(s) + H = SLVS_FREE_IN_3D + End Sub + Public Sub New(ByVal s As Slvs, ByVal group As UInteger, + ByVal origin As Point, ByVal normal As Normal) + MyBase.New(s) + Slv.AddWorkplane(H, group, origin.H, normal.H) + End Sub + End Class + + End Class + +End Module + diff --git a/extlib/libdxfrw/CMakeLists.txt b/extlib/libdxfrw/CMakeLists.txt new file mode 100644 index 0000000..564e91a --- /dev/null +++ b/extlib/libdxfrw/CMakeLists.txt @@ -0,0 +1,75 @@ +if(MSVC) + # Disable some overly strict MSVC warnings. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -wd4244 -wd4800 -wd4805") +endif() + +set(intern_HEADERS + intern/drw_cptable932.h + intern/drw_cptable936.h + intern/drw_cptable949.h + intern/drw_cptable950.h + intern/drw_cptables.h + intern/drw_dbg.h + intern/drw_textcodec.h + intern/dwgbuffer.h + intern/dwgreader15.h + intern/dwgreader18.h + intern/dwgreader21.h + intern/dwgreader24.h + intern/dwgreader27.h + intern/dwgreader.h + intern/dwgutil.h + intern/dxfreader.h + intern/dxfwriter.h + intern/rscodec.h) + +set(intern_SOURCES + intern/drw_dbg.cpp + intern/drw_textcodec.cpp + intern/dwgbuffer.cpp + intern/dwgreader15.cpp + intern/dwgreader18.cpp + intern/dwgreader21.cpp + intern/dwgreader24.cpp + intern/dwgreader27.cpp + intern/dwgreader.cpp + intern/dwgutil.cpp + intern/dxfreader.cpp + intern/dxfwriter.cpp + intern/rscodec.cpp) + +set(libdxfrw_HEADERS + drw_base.h + drw_interface.h + drw_header.h + drw_classes.h + drw_entities.h + drw_objects.h + libdxfrw.h) + +set(libdxfrw_SOURCES + drw_header.cpp + drw_classes.cpp + drw_entities.cpp + drw_objects.cpp + libdxfrw.cpp) + +set(libdwgr_HEADERS + libdwgr.h) + +set(libdwgr_SOURCES + libdwgr.cpp) + +add_library(dxfrw STATIC + ${intern_HEADERS} + ${intern_SOURCES} + ${libdxfrw_HEADERS} + ${libdxfrw_SOURCES} + ${libdwgr_HEADERS} + ${libdwgr_SOURCES}) + +target_include_directories(dxfrw PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/intern/) + +target_include_directories(dxfrw PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/) diff --git a/extlib/libdxfrw/drw_base.h b/extlib/libdxfrw/drw_base.h new file mode 100644 index 0000000..87fc11f --- /dev/null +++ b/extlib/libdxfrw/drw_base.h @@ -0,0 +1,493 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DRW_BASE_H +#define DRW_BASE_H + +#define DRW_VERSION "0.6.3" + +#include +#include +#include + +#ifdef DRW_ASSERTS +# define drw_assert(a) assert(a) +#else +# define drw_assert(a) +#endif + +#define UTF8STRING std::string +#define DRW_UNUSED(x) (void)x + +#if defined(WIN64) || defined(_WIN64) || defined(__WIN64__) +# define DRW_WIN +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +# define DRW_WIN +#elif defined(__MWERKS__) && defined(__INTEL__) +# define DRW_WIN +#else +# define DRW_POSIX +#endif + +#ifndef M_PI + #define M_PI 3.141592653589793238462643 +#endif +#ifndef M_PI_2 + #define M_PI_2 1.57079632679489661923 +#endif +#define M_PIx2 6.283185307179586 // 2*PI +#define ARAD 57.29577951308232 + +typedef signed char dint8; /* 8 bit signed */ +typedef signed short dint16; /* 16 bit signed */ +typedef signed int dint32; /* 32 bit signed */ +typedef long long int dint64; /* 64 bit signed */ + +typedef unsigned char duint8; /* 8 bit unsigned */ +typedef unsigned short duint16; /* 16 bit unsigned */ +typedef unsigned int duint32; /* 32 bit unsigned */ +typedef unsigned long long int duint64; /* 64 bit unsigned */ + +typedef float dfloat32; /* 32 bit floating point */ +typedef double ddouble64; /* 64 bit floating point */ +typedef long double ddouble80; /* 80 bit floating point */ + + +namespace DRW { + +//! Version numbers for the DXF Format. +enum Version { + UNKNOWNV, /*!< UNKNOWN VERSION. */ + AC1006, /*!< R10. */ + AC1009, /*!< R11 & R12. */ + AC1012, /*!< R13. */ + AC1014, /*!< R14. */ + AC1015, /*!< ACAD 2000. */ + AC1018, /*!< ACAD 2004. */ + AC1021, /*!< ACAD 2007. */ + AC1024, /*!< ACAD 2010. */ + AC1027 /*!< ACAD 2013. */ +}; + +enum error { +BAD_NONE, /*!< No error. */ +BAD_UNKNOWN, /*!< UNKNOWN. */ +BAD_OPEN, /*!< error opening file. */ +BAD_VERSION, /*!< unsupported version. */ +BAD_READ_METADATA, /*!< error reading matadata. */ +BAD_READ_FILE_HEADER, /*!< error in file header read process. */ +BAD_READ_HEADER, /*!< error in header vars read process. */ +BAD_READ_HANDLES, /*!< error in object map read process. */ +BAD_READ_CLASSES, /*!< error in classes read process. */ +BAD_READ_TABLES, /*!< error in tables read process. */ +BAD_READ_BLOCKS, /*!< error in block read process. */ +BAD_READ_ENTITIES, /*!< error in entities read process. */ +BAD_READ_OBJECTS /*!< error in objects read process. */ +}; + +enum DBG_LEVEL { + NONE, + DEBUG +}; + +//! Special codes for colors +enum ColorCodes { + ColorByBlock = 0, + Red = 1, + Yellow = 2, + Green = 3, + Cyan = 4, + Blue = 5, + Magenta = 6, + White = 7, + Gray = 8, + Brown = 15, + LRed = 23, + LGreen = 121, + LCyan = 131, + LBlue = 163, + LMagenta = 221, + Black = 250, + LGray = 252, + ColorByLayer = 256, + +}; + +//! Spaces +enum Space { + ModelSpace = 0, + PaperSpace = 1 +}; + +//! Special kinds of handles +enum HandleCodes { + NoHandle = 0 +}; + +//! Shadow mode +enum ShadowMode { + CastAndReceieveShadows = 0, + CastShadows = 1, + ReceiveShadows = 2, + IgnoreShadows = 3 +}; + +//! Special kinds of materials +enum MaterialCodes { + MaterialByLayer = 0 +}; + +//! Special kinds of plot styles +enum PlotStyleCodes { + DefaultPlotStyle = 0 +}; + +//! Special kinds of transparencies +enum TransparencyCodes { + Opaque = 0, + Transparent = -1 +}; + +} // namespace DRW + +//! Class to handle 3D coordinate point +/*! +* Class to handle 3D coordinate point +* @author Rallaz +*/ +class DRW_Coord { +public: + DRW_Coord() = default; + DRW_Coord(double ix, double iy, double iz) { + x = ix; y = iy; z = iz; + } + +/*!< convert to unitary vector */ + void unitize(){ + double dist; + dist = sqrt(x*x + y*y + z*z); + if (dist > 0.0) { + x= x/dist; + y= y/dist; + z= z/dist; + } + } + +public: + double x = 0; + double y = 0; + double z = 0; +}; + + +//! Class to handle vertex +/*! +* Class to handle vertex for lwpolyline entity +* @author Rallaz +*/ +class DRW_Vertex2D { +public: + DRW_Vertex2D() { +// eType = DRW::LWPOLYLINE; + stawidth = endwidth = bulge = 0; + } + DRW_Vertex2D(double sx, double sy, double b) { + stawidth = endwidth = 0; + x = sx; + y =sy; + bulge = b; + } + +public: + double x; /*!< x coordinate, code 10 */ + double y; /*!< y coordinate, code 20 */ + double stawidth; /*!< Start width, code 40 */ + double endwidth; /*!< End width, code 41 */ + double bulge; /*!< bulge, code 42 */ +}; + + +//! Class to handle header vars +/*! +* Class to handle header vars +* @author Rallaz +*/ +class DRW_Variant { +public: + enum TYPE { + STRING, + INTEGER, + DOUBLE, + COORD, + INVALID + }; +//TODO: add INT64 support + DRW_Variant() { + type = INVALID; + } + + DRW_Variant(int c, dint32 i) { + code = c; addInt(i); + } + DRW_Variant(int c, duint32 i) { + code = c; addInt(static_cast(i));//RLZ: verify if worrk with big numbers + } + DRW_Variant(int c, double d) { + code = c; addDouble(d); + } + DRW_Variant(int c, UTF8STRING s) { + code = c; addString(s); + } + DRW_Variant(int c, DRW_Coord crd) { + code = c; addCoord(crd); + } + DRW_Variant(const DRW_Variant& d) { + code = d.code; + type = d.type; + content = d.content; + if (d.type == COORD) { + vdata = d.vdata; + content.v = &vdata; + } + if (d.type == STRING) { + sdata = d.sdata; + content.s = &sdata; + } + } + + ~DRW_Variant() { + } + + void addString(UTF8STRING s) {setType(STRING); sdata = s; content.s = &sdata;} + void addInt(int i) {setType(INTEGER); content.i = i;} + void addDouble(double d) {setType(DOUBLE); content.d = d;} + void addCoord() {setType(COORD); vdata.x=0.0; vdata.y=0.0; vdata.z=0.0; content.v = &vdata;} + void addCoord(DRW_Coord v) {setType(COORD); vdata = v; content.v = &vdata;} + void setType(enum TYPE t) { type = t;} + void setCoordX(double d) { if (type == COORD) vdata.x = d;} + void setCoordY(double d) { if (type == COORD) vdata.y = d;} + void setCoordZ(double d) { if (type == COORD) vdata.z = d;} + +private: + typedef union { + UTF8STRING *s; + dint32 i; + double d; + DRW_Coord *v; + } DRW_VarContent; + +public: + DRW_VarContent content; + enum TYPE type; + int code; /*!< dxf code of this value*/ + +private: + std::string sdata; + DRW_Coord vdata; +}; + +//! Class to handle dwg handles +/*! +* Class to handle dwg handles +* @author Rallaz +*/ +class dwgHandle{ +public: + dwgHandle(){ + code=0; + size=0; + ref=0; + } + ~dwgHandle(){} + duint8 code; + duint8 size; + duint32 ref; +}; + +//! Class to convert between line width and integer +/*! +* Class to convert between line width and integer +* verifing valid values, if value is not valid +* returns widthDefault. +* @author Rallaz +*/ +class DRW_LW_Conv{ +public: + enum lineWidth { + width00 = 0, /*!< 0.00mm (dxf 0)*/ + width01 = 1, /*!< 0.05mm (dxf 5)*/ + width02 = 2, /*!< 0.09mm (dxf 9)*/ + width03 = 3, /*!< 0.13mm (dxf 13)*/ + width04 = 4, /*!< 0.15mm (dxf 15)*/ + width05 = 5, /*!< 0.18mm (dxf 18)*/ + width06 = 6, /*!< 0.20mm (dxf 20)*/ + width07 = 7, /*!< 0.25mm (dxf 25)*/ + width08 = 8, /*!< 0.30mm (dxf 30)*/ + width09 = 9, /*!< 0.35mm (dxf 35)*/ + width10 = 10, /*!< 0.40mm (dxf 40)*/ + width11 = 11, /*!< 0.50mm (dxf 50)*/ + width12 = 12, /*!< 0.53mm (dxf 53)*/ + width13 = 13, /*!< 0.60mm (dxf 60)*/ + width14 = 14, /*!< 0.70mm (dxf 70)*/ + width15 = 15, /*!< 0.80mm (dxf 80)*/ + width16 = 16, /*!< 0.90mm (dxf 90)*/ + width17 = 17, /*!< 1.00mm (dxf 100)*/ + width18 = 18, /*!< 1.06mm (dxf 106)*/ + width19 = 19, /*!< 1.20mm (dxf 120)*/ + width20 = 20, /*!< 1.40mm (dxf 140)*/ + width21 = 21, /*!< 1.58mm (dxf 158)*/ + width22 = 22, /*!< 2.00mm (dxf 200)*/ + width23 = 23, /*!< 2.11mm (dxf 211)*/ + widthByLayer = 29, /*!< by layer (dxf -1) */ + widthByBlock = 30, /*!< by block (dxf -2) */ + widthDefault = 31 /*!< by default (dxf -3) */ + }; + + static int lineWidth2dxfInt(enum lineWidth lw){ + switch (lw){ + case widthByLayer: + return -1; + case widthByBlock: + return -2; + case widthDefault: + return -3; + case width00: + return 0; + case width01: + return 5; + case width02: + return 9; + case width03: + return 13; + case width04: + return 15; + case width05: + return 18; + case width06: + return 20; + case width07: + return 25; + case width08: + return 30; + case width09: + return 35; + case width10: + return 40; + case width11: + return 50; + case width12: + return 53; + case width13: + return 60; + case width14: + return 70; + case width15: + return 80; + case width16: + return 90; + case width17: + return 100; + case width18: + return 106; + case width19: + return 120; + case width20: + return 140; + case width21: + return 158; + case width22: + return 200; + case width23: + return 211; + default: + break; + } + return -3; + } + + static int lineWidth2dwgInt(enum lineWidth lw){ + return static_cast (lw); + } + + static enum lineWidth dxfInt2lineWidth(int i){ + if (i<0) { + if (i==-1) + return widthByLayer; + else if (i==-2) + return widthByBlock; + else if (i==-3) + return widthDefault; + } else if (i<3) { + return width00; + } else if (i<7) { + return width01; + } else if (i<11) { + return width02; + } else if (i<14) { + return width03; + } else if (i<16) { + return width04; + } else if (i<19) { + return width05; + } else if (i<22) { + return width06; + } else if (i<27) { + return width07; + } else if (i<32) { + return width08; + } else if (i<37) { + return width09; + } else if (i<45) { + return width10; + } else if (i<52) { + return width11; + } else if (i<57) { + return width12; + } else if (i<65) { + return width13; + } else if (i<75) { + return width14; + } else if (i<85) { + return width15; + } else if (i<95) { + return width16; + } else if (i<103) { + return width17; + } else if (i<112) { + return width18; + } else if (i<130) { + return width19; + } else if (i<149) { + return width20; + } else if (i<180) { + return width21; + } else if (i<205) { + return width22; + } else { + return width23; + } + //default by default + return widthDefault; + } + + static enum lineWidth dwgInt2lineWidth(int i){ + if ( (i>-1 && i<24) || (i>28 && i<32) ) { + return static_cast (i); + } + //default by default + return widthDefault; + } +}; + +#endif + +// EOF diff --git a/extlib/libdxfrw/drw_classes.cpp b/extlib/libdxfrw/drw_classes.cpp new file mode 100644 index 0000000..02eb01d --- /dev/null +++ b/extlib/libdxfrw/drw_classes.cpp @@ -0,0 +1,115 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include "drw_classes.h" +#include "intern/dxfreader.h" +#include "intern/dxfwriter.h" +#include "intern/dwgbuffer.h" +#include "intern/drw_dbg.h" + +void DRW_Class::parseCode(int code, dxfReader *reader){ + switch (code) { + case 1: + recName = reader->getUtf8String(); + break; + case 2: + className = reader->getUtf8String(); + break; + case 3: + appName = reader->getUtf8String(); + break; + case 90: + proxyFlag = reader->getInt32(); + break; + case 91: + instanceCount = reader->getInt32(); + break; + case 280: + wasaProxyFlag = reader->getInt32(); + break; + case 281: + entityFlag = reader->getInt32(); + break; + default: + break; + } +} + +bool DRW_Class::parseDwg(DRW::Version version, dwgBuffer *buf, dwgBuffer *strBuf){ + DRW_DBG("\n***************************** parsing Class *********************************************\n"); + + classNum = buf->getBitShort(); + DRW_DBG("Class number: "); DRW_DBG(classNum); + proxyFlag = buf->getBitShort(); //in dwg specs says "version" + + appName = strBuf->getVariableText(version, false); + className = strBuf->getVariableText(version, false); + recName = strBuf->getVariableText(version, false); + + DRW_DBG("\napp name: "); DRW_DBG(appName.c_str()); + DRW_DBG("\nclass name: "); DRW_DBG(className.c_str()); + DRW_DBG("\ndxf rec name: "); DRW_DBG(recName.c_str()); + wasaProxyFlag = buf->getBit(); //in dwg says wasazombie + entityFlag = buf->getBitShort(); + entityFlag = entityFlag == 0x1F2 ? 1: 0; + + DRW_DBG("\nProxy capabilities flag: "); DRW_DBG(proxyFlag); + DRW_DBG(", proxy flag (280): "); DRW_DBG(wasaProxyFlag); + DRW_DBG(", entity flag: "); DRW_DBGH(entityFlag); + + if (version > DRW::AC1015) {//2004+ + instanceCount = buf->getBitLong(); + DRW_DBG("\nInstance Count: "); DRW_DBG(instanceCount); + duint32 dwgVersion = buf->getBitLong(); + DRW_DBG("\nDWG version: "); DRW_DBG(dwgVersion); + DRW_DBG("\nmaintenance version: "); DRW_DBG(buf->getBitLong()); + DRW_DBG("\nunknown 1: "); DRW_DBG(buf->getBitLong()); + DRW_DBG("\nunknown 2: "); DRW_DBG(buf->getBitLong()); + } + DRW_DBG("\n"); + toDwgType(); + return buf->isGood(); +} + +void DRW_Class::write(dxfWriter *writer, DRW::Version ver){ + if (ver > DRW::AC1009) { + writer->writeString(0, "CLASS"); + writer->writeString(1, recName); + writer->writeString(2, className); + writer->writeString(3, appName); + writer->writeInt32(90, proxyFlag); + if (ver > DRW::AC1015) { //2004+ + writer->writeInt32(91, instanceCount); + } + writer->writeInt16(280, wasaProxyFlag); + writer->writeInt16(281, entityFlag); + } +} + +void DRW_Class::toDwgType(){ + if (recName == "LWPOLYLINE") + dwgType = 77; + else if (recName == "HATCH") + dwgType = 78; + else if (recName == "GROUP") + dwgType = 72; +/* else if (recName == "GROUP") + dwgType = 72;*/ + else if (recName == "LAYOUT") + dwgType = 82; + else if (recName == "IMAGE") + dwgType = 101; + else if (recName == "IMAGEDEF") + dwgType = 102; + else + dwgType =0; +} diff --git a/extlib/libdxfrw/drw_classes.h b/extlib/libdxfrw/drw_classes.h new file mode 100644 index 0000000..84ea32d --- /dev/null +++ b/extlib/libdxfrw/drw_classes.h @@ -0,0 +1,58 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DRW_CLASSES_H +#define DRW_CLASSES_H + + +#include "drw_base.h" +//#include "libdwgr.h" + +class dxfReader; +class dxfWriter; +class dwgBuffer; + +//! Class to handle classes entries +/*! +* Class to handle classes table entries +* TODO: verify the dxf read/write part +* @author Rallaz +*/ +class DRW_Class { +public: + DRW_Class() { + } + ~DRW_Class() { + } + + void parseCode(int code, dxfReader *reader); + void write(dxfWriter *writer, DRW::Version ver); + bool parseDwg(DRW::Version version, dwgBuffer *buf, dwgBuffer *strBuf); + +private: + void toDwgType(); +public: + UTF8STRING recName; /*!< record name, code 1 */ + UTF8STRING className; /*!< C++ class name, code 2 */ + UTF8STRING appName; /*!< app name, code 3 */ + int proxyFlag; /*!< Proxy capabilities flag, code 90 */ + int instanceCount; /*!< number of instances for a custom class, code 91*/ + int wasaProxyFlag; /*!< proxy flag (app loaded on save), code 280 */ + int entityFlag; /*!< entity flag, code 281 (0 object, 1 entity)*/ +public: //only for read dwg + duint16 classNum; + int dwgType; +}; + +#endif + +// EOF diff --git a/extlib/libdxfrw/drw_entities.cpp b/extlib/libdxfrw/drw_entities.cpp new file mode 100644 index 0000000..33b9735 --- /dev/null +++ b/extlib/libdxfrw/drw_entities.cpp @@ -0,0 +1,3073 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include +#include "drw_entities.h" +#include "intern/dxfreader.h" +#include "intern/dwgbuffer.h" +#include "intern/drw_dbg.h" + + +//! Calculate arbitrary axis +/*! +* Calculate arbitrary axis for apply extrusions +* @author Rallaz +*/ +void DRW_Entity::calculateAxis(DRW_Coord extPoint){ + //Follow the arbitrary DXF definitions for extrusion axes. + if (fabs(extPoint.x) < 0.015625 && fabs(extPoint.y) < 0.015625) { + //If we get here, implement Ax = Wy x N where Wy is [0,1,0] per the DXF spec. + //The cross product works out to Wy.y*N.z-Wy.z*N.y, Wy.z*N.x-Wy.x*N.z, Wy.x*N.y-Wy.y*N.x + //Factoring in the fixed values for Wy gives N.z,0,-N.x + extAxisX.x = extPoint.z; + extAxisX.y = 0; + extAxisX.z = -extPoint.x; + } else { + //Otherwise, implement Ax = Wz x N where Wz is [0,0,1] per the DXF spec. + //The cross product works out to Wz.y*N.z-Wz.z*N.y, Wz.z*N.x-Wz.x*N.z, Wz.x*N.y-Wz.y*N.x + //Factoring in the fixed values for Wz gives -N.y,N.x,0. + extAxisX.x = -extPoint.y; + extAxisX.y = extPoint.x; + extAxisX.z = 0; + } + + extAxisX.unitize(); + + //Ay = N x Ax + extAxisY.x = (extPoint.y * extAxisX.z) - (extAxisX.y * extPoint.z); + extAxisY.y = (extPoint.z * extAxisX.x) - (extAxisX.z * extPoint.x); + extAxisY.z = (extPoint.x * extAxisX.y) - (extAxisX.x * extPoint.y); + + extAxisY.unitize(); +} + +//! Extrude a point using arbitrary axis +/*! +* apply extrusion in a point using arbitrary axis (previous calculated) +* @author Rallaz +*/ +void DRW_Entity::extrudePoint(DRW_Coord extPoint, DRW_Coord *point){ + double px, py, pz; + px = (extAxisX.x*point->x)+(extAxisY.x*point->y)+(extPoint.x*point->z); + py = (extAxisX.y*point->x)+(extAxisY.y*point->y)+(extPoint.y*point->z); + pz = (extAxisX.z*point->x)+(extAxisY.z*point->y)+(extPoint.z*point->z); + + point->x = px; + point->y = py; + point->z = pz; +} + +bool DRW_Entity::parseCode(int code, dxfReader *reader){ + switch (code) { + case 5: + handle = reader->getHandleString(); + break; + case 330: + parentHandle = reader->getHandleString(); + break; + case 8: + layer = reader->getUtf8String(); + break; + case 6: + lineType = reader->getUtf8String(); + break; + case 62: + color = reader->getInt32(); + break; + case 370: + lWeight = DRW_LW_Conv::dxfInt2lineWidth(reader->getInt32()); + break; + case 48: + ltypeScale = reader->getDouble(); + break; + case 60: + visible = reader->getBool(); + break; + case 420: + color24 = reader->getInt32(); + break; + case 430: + colorName = reader->getString(); + break; + case 67: + space = static_cast(reader->getInt32()); + break; + case 102: + parseDxfGroups(code, reader); + break; + case 1000: + case 1001: + case 1002: + case 1003: + case 1004: + case 1005: + extData.push_back(new DRW_Variant(code, reader->getString())); + break; + case 1010: + case 1011: + case 1012: + case 1013: + curr = new DRW_Variant(); + curr->addCoord(); + curr->setCoordX(reader->getDouble()); + curr->code = code; + extData.push_back(curr); + break; + case 1020: + case 1021: + case 1022: + case 1023: + if (curr) + curr->setCoordY(reader->getDouble()); + break; + case 1030: + case 1031: + case 1032: + case 1033: + if (curr) + curr->setCoordZ(reader->getDouble()); + curr=NULL; + break; + case 1040: + case 1041: + case 1042: + extData.push_back(new DRW_Variant(code, reader->getDouble() )); + break; + case 1070: + case 1071: + extData.push_back(new DRW_Variant(code, reader->getInt32() )); + break; + default: + break; + } + return true; +} + +//parses dxf 102 groups to read entity +bool DRW_Entity::parseDxfGroups(int code, dxfReader *reader){ + std::list ls; + DRW_Variant curr; + int nc; + std::string appName= reader->getString(); + if (!appName.empty() && appName.at(0)== '{'){ + curr.addString(appName.substr(1, (int) appName.size()-1)); + curr.code = code; + ls.push_back(curr); + while (code !=102 && appName.at(0)== '}'){ + reader->readRec(&nc); + curr.code = code; + if (code == 330 || code == 360) + curr.addInt(reader->getHandleString()); + else { + switch (reader->type) { + case dxfReader::STRING: + curr.addString(reader->getString()); + break; + case dxfReader::INT32: + case dxfReader::INT64: + curr.addInt(reader->getInt32()); + break; + case dxfReader::DOUBLE: + curr.addDouble(reader->getDouble()); + break; + case dxfReader::BOOL: + curr.addInt(reader->getInt32()); + break; + default: + break; + } + } + ls.push_back(curr); + } + } + + appData.push_back(ls); + return true; +} + +bool DRW_Entity::parseDwg(DRW::Version version, dwgBuffer *buf, dwgBuffer* strBuf, duint32 bs){ + objSize=0; + DRW_DBG("\n***************************** parsing entity *********************************************\n"); + oType = buf->getObjType(version); + DRW_DBG("Object type: "); DRW_DBG(oType); DRW_DBG(", "); DRW_DBGH(oType); + + if (version > DRW::AC1014 && version < DRW::AC1024) {//2000 & 2004 + objSize = buf->getRawLong32(); //RL 32bits object size in bits + DRW_DBG(" Object size: "); DRW_DBG(objSize); DRW_DBG("\n"); + } + if (version > DRW::AC1021) {//2010+ + duint32 ms = buf->size(); + objSize = ms*8 - bs; + DRW_DBG(" Object size: "); DRW_DBG(objSize); DRW_DBG("\n"); + } + + if (strBuf != NULL && version > DRW::AC1018) {//2007+ + strBuf->moveBitPos(objSize-1); + DRW_DBG(" strBuf strbit pos 2007: "); DRW_DBG(strBuf->getPosition()); DRW_DBG(" strBuf bpos 2007: "); DRW_DBG(strBuf->getBitPos()); DRW_DBG("\n"); + if (strBuf->getBit() == 1){ + DRW_DBG("DRW_TableEntry::parseDwg string bit is 1\n"); + strBuf->moveBitPos(-17); + duint16 strDataSize = strBuf->getRawShort16(); + DRW_DBG("\nDRW_TableEntry::parseDwg string strDataSize: "); DRW_DBGH(strDataSize); DRW_DBG("\n"); + if ( (strDataSize& 0x8000) == 0x8000){ + DRW_DBG("\nDRW_TableEntry::parseDwg string 0x8000 bit is set"); + strBuf->moveBitPos(-33);//RLZ pending to verify + duint16 hiSize = strBuf->getRawShort16(); + strDataSize = ((strDataSize&0x7fff) | (hiSize<<15)); + } + strBuf->moveBitPos( -strDataSize -16); //-14 + DRW_DBG("strBuf start strDataSize pos 2007: "); DRW_DBG(strBuf->getPosition()); DRW_DBG(" strBuf bpos 2007: "); DRW_DBG(strBuf->getBitPos()); DRW_DBG("\n"); + } else + DRW_DBG("\nDRW_TableEntry::parseDwg string bit is 0"); + DRW_DBG("strBuf start pos 2007: "); DRW_DBG(strBuf->getPosition()); DRW_DBG(" strBuf bpos 2007: "); DRW_DBG(strBuf->getBitPos()); DRW_DBG("\n"); + } + + dwgHandle ho = buf->getHandle(); + handle = ho.ref; + DRW_DBG("Entity Handle: "); DRW_DBGHL(ho.code, ho.size, ho.ref); + dint16 extDataSize = buf->getBitShort(); //BS + DRW_DBG(" ext data size: "); DRW_DBG(extDataSize); + while (extDataSize>0 && buf->isGood()) { + /* RLZ: TODO */ + dwgHandle ah = buf->getHandle(); + DRW_DBG("App Handle: "); DRW_DBGHL(ah.code, ah.size, ah.ref); + duint8 *tmpExtData = new duint8[extDataSize]; + buf->getBytes(tmpExtData, extDataSize); + dwgBuffer tmpExtDataBuf(tmpExtData, extDataSize, buf->decoder); + + duint8 dxfCode = tmpExtDataBuf.getRawChar8(); + DRW_DBG(" dxfCode: "); DRW_DBG(dxfCode); + switch (dxfCode){ + case 0:{ + duint8 strLength = tmpExtDataBuf.getRawChar8(); + DRW_DBG(" strLength: "); DRW_DBG(strLength); + duint16 cp = tmpExtDataBuf.getBERawShort16(); + DRW_DBG(" str codepage: "); DRW_DBG(cp); + for (int i=0;i< strLength+1;i++) {//string length + null terminating char + duint8 dxfChar = tmpExtDataBuf.getRawChar8(); + DRW_DBG(" dxfChar: "); DRW_DBG(dxfChar); + } + break; + } + default: + /* RLZ: TODO */ + break; + } + delete[]tmpExtData; + extDataSize = buf->getBitShort(); //BS + DRW_DBG(" ext data size: "); DRW_DBG(extDataSize); + } //end parsing extData (EED) + duint8 graphFlag = buf->getBit(); //B + DRW_DBG(" graphFlag: "); DRW_DBG(graphFlag); DRW_DBG("\n"); + if (graphFlag) { + duint32 graphDataSize = buf->getRawLong32(); //RL 32bits + DRW_DBG("graphData in bytes: "); DRW_DBG(graphDataSize); DRW_DBG("\n"); +// RLZ: TODO + //skip graphData bytes + duint8 *tmpGraphData = new duint8[graphDataSize]; + buf->getBytes(tmpGraphData, graphDataSize); + dwgBuffer tmpGraphDataBuf(tmpGraphData, graphDataSize, buf->decoder); + DRW_DBG("graph data remaining bytes: "); DRW_DBG(tmpGraphDataBuf.numRemainingBytes()); DRW_DBG("\n"); + delete[]tmpGraphData; + } + if (version < DRW::AC1015) {//14- + objSize = buf->getRawLong32(); //RL 32bits object size in bits + DRW_DBG(" Object size in bits: "); DRW_DBG(objSize); DRW_DBG("\n"); + } + + duint8 entmode = buf->get2Bits(); //BB + if (entmode == 0) + ownerHandle= true; +// entmode = 2; + else if(entmode ==2) + entmode = 0; + space = (DRW::Space)entmode; //RLZ verify cast values + DRW_DBG("entmode: "); DRW_DBG(entmode); + numReactors = buf->getBitShort(); //BS + DRW_DBG(", numReactors: "); DRW_DBG(numReactors); + + if (version < DRW::AC1015) {//14- + if(buf->getBit()) {//is bylayer line type + lineType = "BYLAYER"; + ltFlags = 0; + } else { + lineType = ""; + ltFlags = 3; + } + DRW_DBG(" lineType: "); DRW_DBG(lineType.c_str()); + DRW_DBG(" ltFlags: "); DRW_DBG(ltFlags); + } + if (version > DRW::AC1015) {//2004+ + xDictFlag = buf->getBit(); + DRW_DBG(" xDictFlag: "); DRW_DBG(xDictFlag); DRW_DBG("\n"); + } + + if (version > DRW::AC1024 || version < DRW::AC1018) { + haveNextLinks = buf->getBit(); //aka nolinks //B + DRW_DBG(", haveNextLinks (0 yes, 1 prev next): "); DRW_DBG(haveNextLinks); DRW_DBG("\n"); + } else { + haveNextLinks = 1; //aka nolinks //B + DRW_DBG(", haveNextLinks (forced): "); DRW_DBG(haveNextLinks); DRW_DBG("\n"); + } +//ENC color + color = buf->getEnColor(version); //BS or CMC //ok for R14 or negate + ltypeScale = buf->getBitDouble(); //BD + DRW_DBG(" entity color: "); DRW_DBG(color); + DRW_DBG(" ltScale: "); DRW_DBG(ltypeScale); DRW_DBG("\n"); + if (version > DRW::AC1014) {//2000+ + UTF8STRING plotStyleName; + for (duint8 i = 0; i<2;++i) { //two flags in one + plotFlags = buf->get2Bits(); //BB + if (plotFlags == 1) + plotStyleName = "byblock"; + else if (plotFlags == 2) + plotStyleName = "continuous"; + else if (plotFlags == 0) + plotStyleName = "bylayer"; + else //handle at end + plotStyleName = ""; + if (i == 0) { + ltFlags = plotFlags; + lineType = plotStyleName; //RLZ: howto solve? if needed plotStyleName; + DRW_DBG("ltFlags: "); DRW_DBG(ltFlags); + DRW_DBG(" lineType: "); DRW_DBG(lineType.c_str()); + } else { + DRW_DBG(", plotFlags: "); DRW_DBG(plotFlags); + } + } + } + if (version > DRW::AC1018) {//2007+ + materialFlag = buf->get2Bits(); //BB + DRW_DBG("materialFlag: "); DRW_DBG(materialFlag); + shadowFlag = buf->getRawChar8(); //RC + DRW_DBG("shadowFlag: "); DRW_DBG(shadowFlag); DRW_DBG("\n"); + } + if (version > DRW::AC1021) {//2010+ + duint8 visualFlags = buf->get2Bits(); //full & face visual style + DRW_DBG("shadowFlag 2: "); DRW_DBG(visualFlags); DRW_DBG("\n"); + duint8 unk = buf->getBit(); //edge visual style + DRW_DBG("unknown bit: "); DRW_DBG(unk); DRW_DBG("\n"); + } + dint16 invisibleFlag = buf->getBitShort(); //BS + DRW_DBG(" invisibleFlag: "); DRW_DBG(invisibleFlag); + if (version > DRW::AC1014) {//2000+ + lWeight = DRW_LW_Conv::dwgInt2lineWidth( buf->getRawChar8() ); //RC + DRW_DBG(" lwFlag (lWeight): "); DRW_DBG(lWeight); DRW_DBG("\n"); + } + //Only in blocks ???????? +// if (version > DRW::AC1018) {//2007+ +// duint8 unk = buf->getBit(); +// DRW_DBG("unknown bit: "); DRW_DBG(unk); DRW_DBG("\n"); +// } + return buf->isGood(); +} + +bool DRW_Entity::parseDwgEntHandle(DRW::Version version, dwgBuffer *buf){ + if (version > DRW::AC1018) {//2007+ skip string area + buf->setPosition(objSize >> 3); + buf->setBitPos(objSize & 7); + } + + if(ownerHandle){//entity are in block or in a polyline + dwgHandle ownerH = buf->getOffsetHandle(handle); + DRW_DBG("owner (parent) Handle: "); DRW_DBGHL(ownerH.code, ownerH.size, ownerH.ref); DRW_DBG("\n"); + DRW_DBG(" Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + parentHandle = ownerH.ref; + DRW_DBG("Block (parent) Handle: "); DRW_DBGHL(ownerH.code, ownerH.size, parentHandle); DRW_DBG("\n"); + } else + DRW_DBG("NO Block (parent) Handle\n"); + + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + for (int i=0; i< numReactors;++i) { + dwgHandle reactorsH = buf->getHandle(); + DRW_DBG(" reactorsH control Handle: "); DRW_DBGHL(reactorsH.code, reactorsH.size, reactorsH.ref); DRW_DBG("\n"); + } + if (xDictFlag !=1){//linetype in 2004 seems not have XDicObjH or NULL handle + dwgHandle XDicObjH = buf->getHandle(); + DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); + } + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + + if (version < DRW::AC1015) {//R14- + //layer handle + layerH = buf->getOffsetHandle(handle); + DRW_DBG(" layer Handle: "); DRW_DBGHL(layerH.code, layerH.size, layerH.ref); DRW_DBG("\n"); + DRW_DBG(" Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + //lineType handle + if(ltFlags == 3){ + lTypeH = buf->getOffsetHandle(handle); + DRW_DBG("linetype Handle: "); DRW_DBGHL(lTypeH.code, lTypeH.size, lTypeH.ref); DRW_DBG("\n"); + DRW_DBG(" Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } + } + if (version < DRW::AC1018) {//2000+ + if (haveNextLinks == 0) { + dwgHandle nextLinkH = buf->getOffsetHandle(handle); + DRW_DBG(" prev nextLinkers Handle: "); DRW_DBGHL(nextLinkH.code, nextLinkH.size, nextLinkH.ref); DRW_DBG("\n"); + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + prevEntLink = nextLinkH.ref; + nextLinkH = buf->getOffsetHandle(handle); + DRW_DBG(" next nextLinkers Handle: "); DRW_DBGHL(nextLinkH.code, nextLinkH.size, nextLinkH.ref); DRW_DBG("\n"); + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + nextEntLink = nextLinkH.ref; + } else { + nextEntLink = handle+1; + prevEntLink = handle-1; + } + } + if (version > DRW::AC1015) {//2004+ + //Parses Bookcolor handle + } + if (version > DRW::AC1014) {//2000+ + //layer handle + layerH = buf->getOffsetHandle(handle); + DRW_DBG(" layer Handle: "); DRW_DBGHL(layerH.code, layerH.size, layerH.ref); DRW_DBG("\n"); + DRW_DBG(" Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + //lineType handle + if(ltFlags == 3){ + lTypeH = buf->getOffsetHandle(handle); + DRW_DBG("linetype Handle: "); DRW_DBGHL(lTypeH.code, lTypeH.size, lTypeH.ref); DRW_DBG("\n"); + DRW_DBG(" Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } + } + if (version > DRW::AC1014) {//2000+ + if (version > DRW::AC1018) {//2007+ + if (materialFlag == 3) { + dwgHandle materialH = buf->getOffsetHandle(handle); + DRW_DBG(" material Handle: "); DRW_DBGHL(materialH.code, materialH.size, materialH.ref); DRW_DBG("\n"); + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } + if (shadowFlag == 3) { + dwgHandle shadowH = buf->getOffsetHandle(handle); + DRW_DBG(" shadow Handle: "); DRW_DBGHL(shadowH.code, shadowH.size, shadowH.ref); DRW_DBG("\n"); + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } + } + if (plotFlags == 3) { + dwgHandle plotStyleH = buf->getOffsetHandle(handle); + DRW_DBG(" plot style Handle: "); DRW_DBGHL(plotStyleH.code, plotStyleH.size, plotStyleH.ref); DRW_DBG("\n"); + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } + } + DRW_DBG("\n DRW_Entity::parseDwgEntHandle Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + return buf->isGood(); +} + +void DRW_Point::parseCode(int code, dxfReader *reader){ + switch (code) { + case 10: + basePoint.x = reader->getDouble(); + break; + case 20: + basePoint.y = reader->getDouble(); + break; + case 30: + basePoint.z = reader->getDouble(); + break; + case 39: + thickness = reader->getDouble(); + break; + case 210: + haveExtrusion = true; + extPoint.x = reader->getDouble(); + break; + case 220: + extPoint.y = reader->getDouble(); + break; + case 230: + extPoint.z = reader->getDouble(); + break; + default: + DRW_Entity::parseCode(code, reader); + break; + } +} + +bool DRW_Point::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + bool ret = DRW_Entity::parseDwg(version, buf, NULL, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing point *********************************************\n"); + + basePoint.x = buf->getBitDouble(); + basePoint.y = buf->getBitDouble(); + basePoint.z = buf->getBitDouble(); + DRW_DBG("point: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); + thickness = buf->getThickness(version > DRW::AC1014);//BD + DRW_DBG("\nthickness: "); DRW_DBG(thickness); + extPoint = buf->getExtrusion(version > DRW::AC1014); + DRW_DBG(", Extrusion: "); DRW_DBGPT(extPoint.x, extPoint.y, extPoint.z); + + double x_axis = buf->getBitDouble();//BD + DRW_DBG("\n x_axis: ");DRW_DBG(x_axis);DRW_DBG("\n"); + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; + // RS crc; //RS */ + + return buf->isGood(); +} + +void DRW_Line::parseCode(int code, dxfReader *reader){ + switch (code) { + case 11: + secPoint.x = reader->getDouble(); + break; + case 21: + secPoint.y = reader->getDouble(); + break; + case 31: + secPoint.z = reader->getDouble(); + break; + default: + DRW_Point::parseCode(code, reader); + break; + } +} + +bool DRW_Line::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + bool ret = DRW_Entity::parseDwg(version, buf, NULL, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing line *********************************************\n"); + + if (version < DRW::AC1015) {//14- + basePoint.x = buf->getBitDouble(); + basePoint.y = buf->getBitDouble(); + basePoint.z = buf->getBitDouble(); + secPoint.x = buf->getBitDouble(); + secPoint.y = buf->getBitDouble(); + secPoint.z = buf->getBitDouble(); + } + if (version > DRW::AC1014) {//2000+ + bool zIsZero = buf->getBit(); //B + basePoint.x = buf->getRawDouble();//RD + secPoint.x = buf->getDefaultDouble(basePoint.x);//DD + basePoint.y = buf->getRawDouble();//RD + secPoint.y = buf->getDefaultDouble(basePoint.y);//DD + if (!zIsZero) { + basePoint.z = buf->getRawDouble();//RD + secPoint.z = buf->getDefaultDouble(basePoint.z);//DD + } + } + DRW_DBG("start point: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); + DRW_DBG("\nend point: "); DRW_DBGPT(secPoint.x, secPoint.y, secPoint.z); + thickness = buf->getThickness(version > DRW::AC1014);//BD + DRW_DBG("\nthickness: "); DRW_DBG(thickness); + extPoint = buf->getExtrusion(version > DRW::AC1014); + DRW_DBG(", Extrusion: "); DRW_DBGPT(extPoint.x, extPoint.y, extPoint.z);DRW_DBG("\n"); + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; +// RS crc; //RS */ + return buf->isGood(); +} + +bool DRW_Ray::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + bool ret = DRW_Entity::parseDwg(version, buf, NULL, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing ray/xline *********************************************\n"); + basePoint.x = buf->getBitDouble(); + basePoint.y = buf->getBitDouble(); + basePoint.z = buf->getBitDouble(); + secPoint.x = buf->getBitDouble(); + secPoint.y = buf->getBitDouble(); + secPoint.z = buf->getBitDouble(); + DRW_DBG("start point: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); + DRW_DBG("\nvector: "); DRW_DBGPT(secPoint.x, secPoint.y, secPoint.z); + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; +// RS crc; //RS */ + return buf->isGood(); +} + +void DRW_Circle::applyExtrusion(){ + if (haveExtrusion) { + //NOTE: Commenting these out causes the the arcs being tested to be located + //on the other side of the y axis (all x dimensions are negated). + calculateAxis(extPoint); + extrudePoint(extPoint, &basePoint); + } +} + +void DRW_Circle::parseCode(int code, dxfReader *reader){ + switch (code) { + case 40: + radious = reader->getDouble(); + break; + default: + DRW_Point::parseCode(code, reader); + break; + } +} + +bool DRW_Circle::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + bool ret = DRW_Entity::parseDwg(version, buf, NULL, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing circle *********************************************\n"); + + basePoint.x = buf->getBitDouble(); + basePoint.y = buf->getBitDouble(); + basePoint.z = buf->getBitDouble(); + DRW_DBG("center: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); + radious = buf->getBitDouble(); + DRW_DBG("\nradius: "); DRW_DBG(radious); + + thickness = buf->getThickness(version > DRW::AC1014); + DRW_DBG(" thickness: "); DRW_DBG(thickness); + extPoint = buf->getExtrusion(version > DRW::AC1014); + DRW_DBG("\nextrusion: "); DRW_DBGPT(extPoint.x, extPoint.y, extPoint.z); DRW_DBG("\n"); + + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; +// RS crc; //RS */ + return buf->isGood(); +} + +void DRW_Arc::applyExtrusion(){ + DRW_Circle::applyExtrusion(); + + if(haveExtrusion){ + // If the extrusion vector has a z value less than 0, the angles for the arc + // have to be mirrored since DXF files use the right hand rule. + // Note that the following code only handles the special case where there is a 2D + // drawing with the z axis heading into the paper (or rather screen). An arbitrary + // extrusion axis (with x and y values greater than 1/64) may still have issues. + if (fabs(extPoint.x) < 0.015625 && fabs(extPoint.y) < 0.015625 && extPoint.z < 0.0) { + staangle=M_PI-staangle; + endangle=M_PI-endangle; + + double temp = staangle; + staangle=endangle; + endangle=temp; + } + } +} + +void DRW_Arc::parseCode(int code, dxfReader *reader){ + switch (code) { + case 50: + staangle = reader->getDouble()/ ARAD; + break; + case 51: + endangle = reader->getDouble()/ ARAD; + break; + default: + DRW_Circle::parseCode(code, reader); + break; + } +} + +bool DRW_Arc::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + bool ret = DRW_Entity::parseDwg(version, buf, NULL, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing circle arc *********************************************\n"); + + basePoint.x = buf->getBitDouble(); + basePoint.y = buf->getBitDouble(); + basePoint.z = buf->getBitDouble(); + DRW_DBG("center point: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); + + radious = buf->getBitDouble(); + DRW_DBG("\nradius: "); DRW_DBG(radious); + thickness = buf->getThickness(version > DRW::AC1014); + DRW_DBG(" thickness: "); DRW_DBG(thickness); + extPoint = buf->getExtrusion(version > DRW::AC1014); + DRW_DBG("\nextrusion: "); DRW_DBGPT(extPoint.x, extPoint.y, extPoint.z); + staangle = buf->getBitDouble(); + DRW_DBG("\nstart angle: "); DRW_DBG(staangle); + endangle = buf->getBitDouble(); + DRW_DBG(" end angle: "); DRW_DBG(endangle); DRW_DBG("\n"); + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; + return buf->isGood(); +} + +void DRW_Ellipse::parseCode(int code, dxfReader *reader){ + switch (code) { + case 40: + ratio = reader->getDouble(); + break; + case 41: + staparam = reader->getDouble(); + break; + case 42: + endparam = reader->getDouble(); + break; + default: + DRW_Line::parseCode(code, reader); + break; + } +} + +void DRW_Ellipse::applyExtrusion(){ + if (haveExtrusion) { + calculateAxis(extPoint); + extrudePoint(extPoint, &secPoint); + double intialparam = staparam; + if (extPoint.z < 0.){ + staparam = M_PIx2 - endparam; + endparam = M_PIx2 - intialparam; + } + } +} + +//if ratio > 1 minor axis are greather than major axis, correct it +void DRW_Ellipse::correctAxis(){ + bool complete = false; + if (staparam == endparam) { + staparam = 0.0; + endparam = M_PIx2; //2*M_PI; + complete = true; + } + if (ratio > 1){ + if ( fabs(endparam - staparam - M_PIx2) < 1.0e-10) + complete = true; + double incX = secPoint.x; + secPoint.x = -(secPoint.y * ratio); + secPoint.y = incX*ratio; + ratio = 1/ratio; + if (!complete){ + if (staparam < M_PI_2) + staparam += M_PI *2; + if (endparam < M_PI_2) + endparam += M_PI *2; + endparam -= M_PI_2; + staparam -= M_PI_2; + } + } +} + +bool DRW_Ellipse::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + bool ret = DRW_Entity::parseDwg(version, buf, NULL, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing ellipse *********************************************\n"); + + basePoint =buf->get3BitDouble(); + DRW_DBG("center: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); + secPoint =buf->get3BitDouble(); + DRW_DBG(", axis: "); DRW_DBGPT(secPoint.x, secPoint.y, secPoint.z); DRW_DBG("\n"); + extPoint =buf->get3BitDouble(); + DRW_DBG("Extrusion: "); DRW_DBGPT(extPoint.x, extPoint.y, extPoint.z); + ratio = buf->getBitDouble();//BD + DRW_DBG("\nratio: "); DRW_DBG(ratio); + staparam = buf->getBitDouble();//BD + DRW_DBG(" start param: "); DRW_DBG(staparam); + endparam = buf->getBitDouble();//BD + DRW_DBG(" end param: "); DRW_DBG(endparam); DRW_DBG("\n"); + + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; +// RS crc; //RS */ + return buf->isGood(); +} + +//parts are the number of vertex to split polyline, default 128 +void DRW_Ellipse::toPolyline(DRW_Polyline *pol, int parts){ + double radMajor, radMinor, cosRot, sinRot, incAngle, curAngle; + double cosCurr, sinCurr; + radMajor = sqrt(secPoint.x*secPoint.x + secPoint.y*secPoint.y); + radMinor = radMajor*ratio; + //calculate sin & cos of included angle + incAngle = atan2(secPoint.y, secPoint.x); + cosRot = cos(incAngle); + sinRot = sin(incAngle); + incAngle = M_PIx2 / parts; + curAngle = staparam; + int i = static_cast(curAngle / incAngle); + do { + if (curAngle > endparam) { + curAngle = endparam; + i = parts+2; + } + cosCurr = cos(curAngle); + sinCurr = sin(curAngle); + double x = basePoint.x + (cosCurr*cosRot*radMajor) - (sinCurr*sinRot*radMinor); + double y = basePoint.y + (cosCurr*sinRot*radMajor) + (sinCurr*cosRot*radMinor); + pol->addVertex( DRW_Vertex(x, y, 0.0, 0.0)); + curAngle = (++i)*incAngle; + } while (iflags = 1; + } + pol->layer = this->layer; + pol->lineType = this->lineType; + pol->color = this->color; + pol->lWeight = this->lWeight; + pol->extPoint = this->extPoint; +} + +void DRW_Trace::applyExtrusion(){ + if (haveExtrusion) { + calculateAxis(extPoint); + extrudePoint(extPoint, &basePoint); + extrudePoint(extPoint, &secPoint); + extrudePoint(extPoint, &thirdPoint); + extrudePoint(extPoint, &fourPoint); + } +} + +void DRW_Trace::parseCode(int code, dxfReader *reader){ + switch (code) { + case 12: + thirdPoint.x = reader->getDouble(); + break; + case 22: + thirdPoint.y = reader->getDouble(); + break; + case 32: + thirdPoint.z = reader->getDouble(); + break; + case 13: + fourPoint.x = reader->getDouble(); + break; + case 23: + fourPoint.y = reader->getDouble(); + break; + case 33: + fourPoint.z = reader->getDouble(); + break; + default: + DRW_Line::parseCode(code, reader); + break; + } +} + +bool DRW_Trace::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + bool ret = DRW_Entity::parseDwg(version, buf, NULL, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing Trace *********************************************\n"); + + thickness = buf->getThickness(version>DRW::AC1014); + basePoint.z = buf->getBitDouble(); + basePoint.x = buf->getRawDouble(); + basePoint.y = buf->getRawDouble(); + secPoint.x = buf->getRawDouble(); + secPoint.y = buf->getRawDouble(); + secPoint.z = basePoint.z; + thirdPoint.x = buf->getRawDouble(); + thirdPoint.y = buf->getRawDouble(); + thirdPoint.z = basePoint.z; + fourPoint.x = buf->getRawDouble(); + fourPoint.y = buf->getRawDouble(); + fourPoint.z = basePoint.z; + extPoint = buf->getExtrusion(version>DRW::AC1014); + + DRW_DBG(" - base "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); + DRW_DBG("\n - sec "); DRW_DBGPT(secPoint.x, secPoint.y, secPoint.z); + DRW_DBG("\n - third "); DRW_DBGPT(thirdPoint.x, thirdPoint.y, thirdPoint.z); + DRW_DBG("\n - fourth "); DRW_DBGPT(fourPoint.x, fourPoint.y, fourPoint.z); + DRW_DBG("\n - extrusion: "); DRW_DBGPT(extPoint.x, extPoint.y, extPoint.z); + DRW_DBG("\n - thickness: "); DRW_DBG(thickness); DRW_DBG("\n"); + + /* Common Entity Handle Data */ + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; + + /* CRC X --- */ + return buf->isGood(); +} + + +void DRW_Solid::parseCode(int code, dxfReader *reader){ + DRW_Trace::parseCode(code, reader); +} + +bool DRW_Solid::parseDwg(DRW::Version v, dwgBuffer *buf, duint32 bs){ + DRW_DBG("\n***************************** parsing Solid *********************************************\n"); + return DRW_Trace::parseDwg(v, buf, bs); +} + +void DRW_3Dface::parseCode(int code, dxfReader *reader){ + switch (code) { + case 70: + invisibleflag = reader->getInt32(); + break; + default: + DRW_Trace::parseCode(code, reader); + break; + } +} + +bool DRW_3Dface::parseDwg(DRW::Version v, dwgBuffer *buf, duint32 bs){ + bool ret = DRW_Entity::parseDwg(v, buf, NULL, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing 3Dface *********************************************\n"); + + if ( v < DRW::AC1015 ) {// R13 & R14 + basePoint.x = buf->getBitDouble(); + basePoint.y = buf->getBitDouble(); + basePoint.z = buf->getBitDouble(); + secPoint.x = buf->getBitDouble(); + secPoint.y = buf->getBitDouble(); + secPoint.z = buf->getBitDouble(); + thirdPoint.x = buf->getBitDouble(); + thirdPoint.y = buf->getBitDouble(); + thirdPoint.z = buf->getBitDouble(); + fourPoint.x = buf->getBitDouble(); + fourPoint.y = buf->getBitDouble(); + fourPoint.z = buf->getBitDouble(); + invisibleflag = buf->getBitShort(); + } else { // 2000+ + bool has_no_flag = buf->getBit(); + bool z_is_zero = buf->getBit(); + basePoint.x = buf->getRawDouble(); + basePoint.y = buf->getRawDouble(); + basePoint.z = z_is_zero ? 0.0 : buf->getRawDouble(); + secPoint.x = buf->getDefaultDouble(basePoint.x); + secPoint.y = buf->getDefaultDouble(basePoint.y); + secPoint.z = buf->getDefaultDouble(basePoint.z); + thirdPoint.x = buf->getDefaultDouble(secPoint.x); + thirdPoint.y = buf->getDefaultDouble(secPoint.y); + thirdPoint.z = buf->getDefaultDouble(secPoint.z); + fourPoint.x = buf->getDefaultDouble(thirdPoint.x); + fourPoint.y = buf->getDefaultDouble(thirdPoint.y); + fourPoint.z = buf->getDefaultDouble(thirdPoint.z); + invisibleflag = has_no_flag ? (int)NoEdge : buf->getBitShort(); + } + drw_assert(invisibleflag>=NoEdge); + drw_assert(invisibleflag<=AllEdges); + + DRW_DBG(" - base "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); DRW_DBG("\n"); + DRW_DBG(" - sec "); DRW_DBGPT(secPoint.x, secPoint.y, secPoint.z); DRW_DBG("\n"); + DRW_DBG(" - third "); DRW_DBGPT(thirdPoint.x, thirdPoint.y, thirdPoint.z); DRW_DBG("\n"); + DRW_DBG(" - fourth "); DRW_DBGPT(fourPoint.x, fourPoint.y, fourPoint.z); DRW_DBG("\n"); + DRW_DBG(" - Invisibility mask: "); DRW_DBG(invisibleflag); DRW_DBG("\n"); + + /* Common Entity Handle Data */ + ret = DRW_Entity::parseDwgEntHandle(v, buf); + if (!ret) + return ret; + return buf->isGood(); +} + +void DRW_Block::parseCode(int code, dxfReader *reader){ + switch (code) { + case 2: + name = reader->getUtf8String(); + break; + case 70: + flags = reader->getInt32(); + break; + default: + DRW_Point::parseCode(code, reader); + break; + } +} + +bool DRW_Block::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_Entity::parseDwg(version, buf, sBuf, bs); + if (!ret) + return ret; + if (!isEnd){ + DRW_DBG("\n***************************** parsing block *********************************************\n"); + name = sBuf->getVariableText(version, false); + DRW_DBG("Block name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); + } else { + DRW_DBG("\n***************************** parsing end block *********************************************\n"); + } + if (version > DRW::AC1018) {//2007+ + duint8 unk = buf->getBit(); + DRW_DBG("unknown bit: "); DRW_DBG(unk); DRW_DBG("\n"); + } +// X handleAssoc; //X + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; +// RS crc; //RS */ + return buf->isGood(); +} + +void DRW_Insert::parseCode(int code, dxfReader *reader){ + switch (code) { + case 2: + name = reader->getUtf8String(); + break; + case 41: + xscale = reader->getDouble(); + break; + case 42: + yscale = reader->getDouble(); + break; + case 43: + zscale = reader->getDouble(); + break; + case 50: + angle = reader->getDouble(); + angle = angle/ARAD; //convert to radian + break; + case 70: + colcount = reader->getInt32(); + break; + case 71: + rowcount = reader->getInt32(); + break; + case 44: + colspace = reader->getDouble(); + break; + case 45: + rowspace = reader->getDouble(); + break; + default: + DRW_Point::parseCode(code, reader); + break; + } +} + +bool DRW_Insert::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dint32 objCount = 0; + bool ret = DRW_Entity::parseDwg(version, buf, NULL, bs); + if (!ret) + return ret; + DRW_DBG("\n************************** parsing insert/minsert *****************************************\n"); + basePoint.x = buf->getBitDouble(); + basePoint.y = buf->getBitDouble(); + basePoint.z = buf->getBitDouble(); + DRW_DBG("insertion point: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); DRW_DBG("\n"); + if (version < DRW::AC1015) {//14- + xscale = buf->getBitDouble(); + yscale = buf->getBitDouble(); + zscale = buf->getBitDouble(); + } else { + duint8 dataFlags = buf->get2Bits(); + if (dataFlags == 3){ + //none default value 1,1,1 + } else if (dataFlags == 1){ //x default value 1, y & z can be x value + yscale = buf->getDefaultDouble(xscale); + zscale = buf->getDefaultDouble(xscale); + } else if (dataFlags == 2){ + xscale = buf->getRawDouble(); + yscale = zscale = xscale; + } else { //dataFlags == 0 + xscale = buf->getRawDouble(); + yscale = buf->getDefaultDouble(xscale); + zscale = buf->getDefaultDouble(xscale); + } + } + angle = buf->getBitDouble(); + DRW_DBG("scale : "); DRW_DBGPT(xscale, yscale, zscale); DRW_DBG(", angle: "); DRW_DBG(angle); + extPoint = buf->getExtrusion(false); //3BD R14 style + DRW_DBG("\nextrusion: "); DRW_DBGPT(extPoint.x, extPoint.y, extPoint.z); + + bool hasAttrib = buf->getBit(); + DRW_DBG(" has Attrib: "); DRW_DBG(hasAttrib); + + if (hasAttrib && version > DRW::AC1015) {//2004+ + objCount = buf->getBitLong(); + DRW_UNUSED(objCount); + DRW_DBG(" objCount: "); DRW_DBG(objCount); DRW_DBG("\n"); + } + if (oType == 8) {//entity are minsert + colcount = buf->getBitShort(); + rowcount = buf->getBitShort(); + colspace = buf->getBitDouble(); + rowspace = buf->getBitDouble(); + } + DRW_DBG(" Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + ret = DRW_Entity::parseDwgEntHandle(version, buf); + blockRecH = buf->getHandle(); /* H 2 BLOCK HEADER (hard pointer) */ + DRW_DBG("BLOCK HEADER Handle: "); DRW_DBGHL(blockRecH.code, blockRecH.size, blockRecH.ref); DRW_DBG("\n"); + DRW_DBG(" Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + + /*attribs follows*/ + if (hasAttrib) { + if (version < DRW::AC1018) {//2000- + dwgHandle attH = buf->getHandle(); /* H 2 BLOCK HEADER (hard pointer) */ + DRW_DBG("first attrib Handle: "); DRW_DBGHL(attH.code, attH.size, attH.ref); DRW_DBG("\n"); + attH = buf->getHandle(); /* H 2 BLOCK HEADER (hard pointer) */ + DRW_DBG("second attrib Handle: "); DRW_DBGHL(attH.code, attH.size, attH.ref); DRW_DBG("\n"); + } else { + for (duint8 i=0; i< objCount; ++i){ + dwgHandle attH = buf->getHandle(); /* H 2 BLOCK HEADER (hard pointer) */ + DRW_DBG("attrib Handle #"); DRW_DBG(i); DRW_DBG(": "); DRW_DBGHL(attH.code, attH.size, attH.ref); DRW_DBG("\n"); + } + } + seqendH = buf->getHandle(); /* H 2 BLOCK HEADER (hard pointer) */ + DRW_DBG("seqendH Handle: "); DRW_DBGHL(seqendH.code, seqendH.size, seqendH.ref); DRW_DBG("\n"); + } + DRW_DBG(" Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + + if (!ret) + return ret; +// RS crc; //RS */ + return buf->isGood(); +} + +void DRW_LWPolyline::applyExtrusion(){ + if (haveExtrusion) { + calculateAxis(extPoint); + for (unsigned int i=0; ix, vert->y, elevation); + extrudePoint(extPoint, &v); + vert->x = v.x; + vert->y = v.y; + } + } +} + +void DRW_LWPolyline::parseCode(int code, dxfReader *reader){ + switch (code) { + case 10: { + vertex = new DRW_Vertex2D(); + vertlist.push_back(vertex); + vertex->x = reader->getDouble(); + break; } + case 20: + if(vertex != NULL) + vertex->y = reader->getDouble(); + break; + case 40: + if(vertex != NULL) + vertex->stawidth = reader->getDouble(); + break; + case 41: + if(vertex != NULL) + vertex->endwidth = reader->getDouble(); + break; + case 42: + if(vertex != NULL) + vertex->bulge = reader->getDouble(); + break; + case 38: + elevation = reader->getDouble(); + break; + case 39: + thickness = reader->getDouble(); + break; + case 43: + width = reader->getDouble(); + break; + case 70: + flags = reader->getInt32(); + break; + case 90: + vertexnum = reader->getInt32(); + vertlist.reserve(vertexnum); + break; + case 210: + haveExtrusion = true; + extPoint.x = reader->getDouble(); + break; + case 220: + extPoint.y = reader->getDouble(); + break; + case 230: + extPoint.z = reader->getDouble(); + break; + default: + DRW_Entity::parseCode(code, reader); + break; + } +} + +bool DRW_LWPolyline::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + bool ret = DRW_Entity::parseDwg(version, buf, NULL, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing LWPolyline *******************************************\n"); + + flags = buf->getBitShort(); + DRW_DBG("flags value: "); DRW_DBG(flags); + if (flags & 4) + width = buf->getBitDouble(); + if (flags & 8) + elevation = buf->getBitDouble(); + if (flags & 2) + thickness = buf->getBitDouble(); + if (flags & 1) + extPoint = buf->getExtrusion(false); + vertexnum = buf->getBitLong(); + vertlist.reserve(vertexnum); + unsigned int bulgesnum = 0; + if (flags & 16) + bulgesnum = buf->getBitLong(); + int vertexIdCount = 0; + if (version > DRW::AC1021) {//2010+ + if (flags & 1024) + vertexIdCount = buf->getBitLong(); + } + + unsigned int widthsnum = 0; + if (flags & 32) + widthsnum = buf->getBitLong(); + DRW_DBG("\nvertex num: "); DRW_DBG(vertexnum); DRW_DBG(" bulges num: "); DRW_DBG(bulgesnum); + DRW_DBG(" vertexIdCount: "); DRW_DBG(vertexIdCount); DRW_DBG(" widths num: "); DRW_DBG(widthsnum); + //clear all bit except 128 = plinegen and set 1 to open/close //RLZ:verify plinegen & open + //dxf: plinegen 128 & open 1 + flags = (flags & 512)? (flags | 1):(flags | 0); + flags &= 129; + DRW_DBG("end flags value: "); DRW_DBG(flags); + + if (vertexnum > 0) { //verify if is lwpol without vertex (empty) + // add vertexs + vertex = new DRW_Vertex2D(); + vertex->x = buf->getRawDouble(); + vertex->y = buf->getRawDouble(); + vertlist.push_back(vertex); + DRW_Vertex2D* pv = vertex; + for (int i = 1; i< vertexnum; i++){ + vertex = new DRW_Vertex2D(); + if (version < DRW::AC1015) {//14- + vertex->x = buf->getRawDouble(); + vertex->y = buf->getRawDouble(); + } else { +// DRW_Vertex2D *pv = vertlist.back(); + vertex->x = buf->getDefaultDouble(pv->x); + vertex->y = buf->getDefaultDouble(pv->y); + } + pv = vertex; + vertlist.push_back(vertex); + } + //add bulges + for (unsigned int i = 0; i < bulgesnum; i++){ + double bulge = buf->getBitDouble(); + if (vertlist.size()> i) + vertlist.at(i)->bulge = bulge; + } + //add vertexId + if (version > DRW::AC1021) {//2010+ + for (int i = 0; i < vertexIdCount; i++){ + dint32 vertexId = buf->getBitLong(); + //TODO implement vertexId, do not exist in dxf + DRW_UNUSED(vertexId); +// if (vertlist.size()< i) +// vertlist.at(i)->vertexId = vertexId; + } + } + //add widths + for (unsigned int i = 0; i < widthsnum; i++){ + double staW = buf->getBitDouble(); + double endW = buf->getBitDouble(); + if (vertlist.size()< i) { + vertlist.at(i)->stawidth = staW; + vertlist.at(i)->endwidth = endW; + } + } + } + if (DRW_DBGGL == DRW_dbg::DEBUG){ + DRW_DBG("\nVertex list: "); + for (std::vector::iterator it = vertlist.begin() ; it != vertlist.end(); ++it){ + DRW_Vertex2D* pv = *it; + DRW_DBG("\n x: "); DRW_DBG(pv->x); DRW_DBG(" y: "); DRW_DBG(pv->y); DRW_DBG(" bulge: "); DRW_DBG(pv->bulge); + DRW_DBG(" stawidth: "); DRW_DBG(pv->stawidth); DRW_DBG(" endwidth: "); DRW_DBG(pv->endwidth); + } + } + + DRW_DBG("\n"); + /* Common Entity Handle Data */ + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; + /* CRC X --- */ + return buf->isGood(); +} + + +void DRW_Text::parseCode(int code, dxfReader *reader){ + switch (code) { + case 40: + height = reader->getDouble(); + break; + case 41: + widthscale = reader->getDouble(); + break; + case 50: + angle = reader->getDouble(); + break; + case 51: + oblique = reader->getDouble(); + break; + case 71: + textgen = reader->getInt32(); + break; + case 72: + alignH = (HAlign)reader->getInt32(); + break; + case 73: + alignV = (VAlign)reader->getInt32(); + break; + case 1: + text = reader->getUtf8String(); + break; + case 7: + style = reader->getUtf8String(); + break; + default: + DRW_Line::parseCode(code, reader); + break; + } +} + +bool DRW_Text::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_Entity::parseDwg(version, buf, sBuf, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing text *********************************************\n"); + + // DataFlags RC Used to determine presence of subsequent data, set to 0xFF for R14- + duint8 data_flags = 0x00; + if (version > DRW::AC1014) {//2000+ + data_flags = buf->getRawChar8(); /* DataFlags RC Used to determine presence of subsequent data */ + DRW_DBG("data_flags: "); DRW_DBG(data_flags); DRW_DBG("\n"); + if ( !(data_flags & 0x01) ) { /* Elevation RD --- present if !(DataFlags & 0x01) */ + basePoint.z = buf->getRawDouble(); + } + } else {//14- + basePoint.z = buf->getBitDouble(); /* Elevation BD --- */ + } + basePoint.x = buf->getRawDouble(); /* Insertion pt 2RD 10 */ + basePoint.y = buf->getRawDouble(); + DRW_DBG("Insert point: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); DRW_DBG("\n"); + if (version > DRW::AC1014) {//2000+ + if ( !(data_flags & 0x02) ) { /* Alignment pt 2DD 11 present if !(DataFlags & 0x02), use 10 & 20 values for 2 default values.*/ + secPoint.x = buf->getDefaultDouble(basePoint.x); + secPoint.y = buf->getDefaultDouble(basePoint.y); + } else { + secPoint = basePoint; + } + } else {//14- + secPoint.x = buf->getRawDouble(); /* Alignment pt 2RD 11 */ + secPoint.y = buf->getRawDouble(); + } + secPoint.z = basePoint.z; + DRW_DBG("Alignment: "); DRW_DBGPT(secPoint.x, secPoint.y, basePoint.z); DRW_DBG("\n"); + extPoint = buf->getExtrusion(version > DRW::AC1014); + DRW_DBG("Extrusion: "); DRW_DBGPT(extPoint.x, extPoint.y, extPoint.z); DRW_DBG("\n"); + thickness = buf->getThickness(version > DRW::AC1014); /* Thickness BD 39 */ + + if (version > DRW::AC1014) {//2000+ + if ( !(data_flags & 0x04) ) { /* Oblique ang RD 51 present if !(DataFlags & 0x04) */ + oblique = buf->getRawDouble(); + } + if ( !(data_flags & 0x08) ) { /* Rotation ang RD 50 present if !(DataFlags & 0x08) */ + angle = buf->getRawDouble(); + } + height = buf->getRawDouble(); /* Height RD 40 */ + if ( !(data_flags & 0x10) ) { /* Width factor RD 41 present if !(DataFlags & 0x10) */ + widthscale = buf->getRawDouble(); + } + } else {//14- + oblique = buf->getBitDouble(); /* Oblique ang BD 51 */ + angle = buf->getBitDouble(); /* Rotation ang BD 50 */ + height = buf->getBitDouble(); /* Height BD 40 */ + widthscale = buf->getBitDouble(); /* Width factor BD 41 */ + } + DRW_DBG("thickness: "); DRW_DBG(thickness); DRW_DBG(", Oblique ang: "); DRW_DBG(oblique); DRW_DBG(", Width: "); + DRW_DBG(widthscale); DRW_DBG(", Rotation: "); DRW_DBG(angle); DRW_DBG(", height: "); DRW_DBG(height); DRW_DBG("\n"); + text = sBuf->getVariableText(version, false); /* Text value TV 1 */ + DRW_DBG("text string: "); DRW_DBG(text.c_str());DRW_DBG("\n"); + //textgen, alignH, alignV always present in R14-, data_flags set in initialisation + if ( !(data_flags & 0x20) ) { /* Generation BS 71 present if !(DataFlags & 0x20) */ + textgen = buf->getBitShort(); + DRW_DBG("textgen: "); DRW_DBG(textgen); + } + if ( !(data_flags & 0x40) ) { /* Horiz align. BS 72 present if !(DataFlags & 0x40) */ + alignH = (HAlign)buf->getBitShort(); + DRW_DBG(", alignH: "); DRW_DBG(alignH); + } + if ( !(data_flags & 0x80) ) { /* Vert align. BS 73 present if !(DataFlags & 0x80) */ + alignV = (VAlign)buf->getBitShort(); + DRW_DBG(", alignV: "); DRW_DBG(alignV); + } + DRW_DBG("\n"); + + /* Common Entity Handle Data */ + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; + + styleH = buf->getHandle(); /* H 7 STYLE (hard pointer) */ + DRW_DBG("text style Handle: "); DRW_DBGHL(styleH.code, styleH.size, styleH.ref); DRW_DBG("\n"); + + /* CRC X --- */ + return buf->isGood(); +} + +void DRW_MText::parseCode(int code, dxfReader *reader){ + switch (code) { + case 1: + text += reader->getString(); + text = reader->toUtf8String(text); + break; + case 11: + haveXAxis = true; + DRW_Text::parseCode(code, reader); + break; + case 3: + text += reader->getString(); + break; + case 44: + interlin = reader->getDouble(); + break; + case 71: { + // Attachment point + Attach a = (Attach)reader->getInt32(); + + switch(a) { + case TopLeft: + alignV = VTop; + alignH = HLeft; + break; + case TopCenter: + alignV = VTop; + alignH = HCenter; + break; + case TopRight: + alignV = VTop; + alignH = HRight; + break; + case MiddleLeft: + alignV = VMiddle; + alignH = HLeft; + break; + case MiddleCenter: + alignV = VMiddle; + alignH = HCenter; + break; + case MiddleRight: + alignV = VMiddle; + alignH = HRight; + break; + case BottomLeft: + alignV = VBottom; + alignH = HLeft; + break; + case BottomCenter: + alignV = VBottom; + alignH = HCenter; + break; + case BottomRight: + alignV = VBottom; + alignH = HRight; + break; + } + } break; + case 72: + // To prevent redirection to DRW_Text::parseCode. + // This code meaning is different for MTEXT. + // Actually: Drawing direction + break; + case 73: + // To prevent redirection to DRW_Text::parseCode. + // This code meaning is different for MTEXT. + // Actually: Mtext line spacing style + break; + default: + DRW_Text::parseCode(code, reader); + break; + } +} + +bool DRW_MText::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_Entity::parseDwg(version, buf, sBuf, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing mtext *********************************************\n"); + + basePoint = buf->get3BitDouble(); /* Insertion pt 3BD 10 - First picked point. */ + DRW_DBG("Insertion: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); DRW_DBG("\n"); + extPoint = buf->get3BitDouble(); /* Extrusion 3BD 210 Undocumented; */ + secPoint = buf->get3BitDouble(); /* X-axis dir 3BD 11 */ + updateAngle(); + widthscale = buf->getBitDouble(); /* Rect width BD 41 */ + if (version > DRW::AC1018) {//2007+ + /* Rect height BD 46 Reference rectangle height. */ + /** @todo */buf->getBitDouble(); + } + height = buf->getBitDouble();/* Text height BD 40 Undocumented */ + textgen = buf->getBitShort(); /* Attachment BS 71 Similar to justification; */ + /* Drawing dir BS 72 Left to right, etc.; see DXF doc */ + dint16 draw_dir = buf->getBitShort(); + DRW_UNUSED(draw_dir); + /* Extents ht BD Undocumented and not present in DXF or entget */ + double ext_ht = buf->getBitDouble(); + DRW_UNUSED(ext_ht); + /* Extents wid BD Undocumented and not present in DXF or entget The extents + rectangle, when rotated the same as the text, fits the actual text image on + the screen (although we've seen it include an extra row of text in height). */ + double ext_wid = buf->getBitDouble(); + DRW_UNUSED(ext_wid); + /* Text TV 1 All text in one long string (without '\n's 3 for line wrapping). + ACAD seems to add braces ({ }) and backslash-P's to indicate paragraphs + based on the "\r\n"'s found in the imported file. But, all the text is in + this one long string -- not broken into 1- and 3-groups as in DXF and + entget. ACAD's entget breaks this string into 250-char pieces (not 255 as + doc'd) – even if it's mid-word. The 1-group always gets the tag end; + therefore, the 3's are always 250 chars long. */ + text = sBuf->getVariableText(version, false); /* Text value TV 1 */ + if (version > DRW::AC1014) {//2000+ + buf->getBitShort();/* Linespacing Style BS 73 */ + buf->getBitDouble();/* Linespacing Factor BD 44 */ + buf->getBit();/* Unknown bit B */ + } + if (version > DRW::AC1015) {//2004+ + /* Background flags BL 0 = no background, 1 = background fill, 2 =background + fill with drawing fill color. */ + dint32 bk_flags = buf->getBitLong(); /** @todo add to DRW_MText */ + if ( bk_flags == 1 ) { + /* Background scale factor BL Present if background flags = 1, default = 1.5*/ + buf->getBitLong(); + /* Background color CMC Present if background flags = 1 */ + buf->getCmColor(version); //RLZ: warning CMC or ENC + /** @todo buf->getCMC */ + /* Background transparency BL Present if background flags = 1 */ + buf->getBitLong(); + } + } + + /* Common Entity Handle Data */ + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; + + styleH = buf->getHandle(); /* H 7 STYLE (hard pointer) */ + DRW_DBG("text style Handle: "); DRW_DBG(styleH.code); DRW_DBG("."); + DRW_DBG(styleH.size); DRW_DBG("."); DRW_DBG(styleH.ref); DRW_DBG("\n"); + + /* CRC X --- */ + return buf->isGood(); +} + +void DRW_MText::updateAngle(){ + if (haveXAxis) { + angle = atan2(secPoint.y, secPoint.x)*180/M_PI; + } +} + +void DRW_Polyline::parseCode(int code, dxfReader *reader){ + switch (code) { + case 70: + flags = reader->getInt32(); + break; + case 40: + defstawidth = reader->getDouble(); + break; + case 41: + defendwidth = reader->getDouble(); + break; + case 71: + vertexcount = reader->getInt32(); + break; + case 72: + facecount = reader->getInt32(); + break; + case 73: + smoothM = reader->getInt32(); + break; + case 74: + smoothN = reader->getInt32(); + break; + case 75: + curvetype = reader->getInt32(); + break; + default: + DRW_Point::parseCode(code, reader); + break; + } +} + +//0x0F polyline 2D bit 4(8) & 5(16) NOT set +//0x10 polyline 3D bit 4(8) set +//0x1D PFACE bit 5(16) set +bool DRW_Polyline::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + bool ret = DRW_Entity::parseDwg(version, buf, NULL, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing polyline *********************************************\n"); + + dint32 ooCount = 0; + if (oType == 0x0F) { //pline 2D + flags = buf->getBitShort(); + DRW_DBG("flags value: "); DRW_DBG(flags); + curvetype = buf->getBitShort(); + defstawidth = buf->getBitDouble(); + defendwidth = buf->getBitDouble(); + thickness = buf->getThickness(version > DRW::AC1014); + basePoint = DRW_Coord(0,0,buf->getBitDouble()); + extPoint = buf->getExtrusion(version > DRW::AC1014); + } else if (oType == 0x10) { //pline 3D + duint8 tmpFlag = buf->getRawChar8(); + DRW_DBG("flags 1 value: "); DRW_DBG(tmpFlag); + if (tmpFlag & 1) + curvetype = 5; + else if (tmpFlag & 2) + curvetype = 6; + if (tmpFlag & 3) { + curvetype = 8; + flags |= 4; + } + tmpFlag = buf->getRawChar8(); + if (tmpFlag & 1) + flags |= 1; + flags |= 8; //indicate 3DPOL + DRW_DBG("flags 2 value: "); DRW_DBG(tmpFlag); + } else if (oType == 0x1D) { //PFACE + flags = 64; + vertexcount = buf->getBitShort(); + DRW_DBG("vertex count: "); DRW_DBG(vertexcount); + facecount = buf->getBitShort(); + DRW_DBG("face count: "); DRW_DBG(facecount); + DRW_DBG("flags value: "); DRW_DBG(flags); + } + if (version > DRW::AC1015){ //2004+ + ooCount = buf->getBitLong(); + } + + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; + + if (version < DRW::AC1018){ //2000- + dwgHandle objectH = buf->getOffsetHandle(handle); + firstEH = objectH.ref; + DRW_DBG(" first Vertex Handle: "); DRW_DBGHL(objectH.code, objectH.size, objectH.ref); DRW_DBG("\n"); + objectH = buf->getOffsetHandle(handle); + lastEH = objectH.ref; + DRW_DBG(" last Vertex Handle: "); DRW_DBGHL(objectH.code, objectH.size, objectH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } else { + for (dint32 i = 0; i < ooCount; ++i){ + dwgHandle objectH = buf->getOffsetHandle(handle); + hadlesList.push_back (objectH.ref); + DRW_DBG(" Vertex Handle: "); DRW_DBGHL(objectH.code, objectH.size, objectH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } + } + seqEndH = buf->getOffsetHandle(handle); + DRW_DBG(" SEQEND Handle: "); DRW_DBGHL(seqEndH.code, seqEndH.size, seqEndH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + +// RS crc; //RS */ + return buf->isGood(); +} + +void DRW_Vertex::parseCode(int code, dxfReader *reader){ + switch (code) { + case 70: + flags = reader->getInt32(); + break; + case 40: + stawidth = reader->getDouble(); + break; + case 41: + endwidth = reader->getDouble(); + break; + case 42: + bulge = reader->getDouble(); + break; + case 50: + tgdir = reader->getDouble(); + break; + case 71: + vindex1 = reader->getInt32(); + break; + case 72: + vindex2 = reader->getInt32(); + break; + case 73: + vindex3 = reader->getInt32(); + break; + case 74: + vindex4 = reader->getInt32(); + break; + case 91: + identifier = reader->getInt32(); + break; + default: + DRW_Point::parseCode(code, reader); + break; + } +} + +//0x0A vertex 2D +//0x0B vertex 3D +//0x0C MESH +//0x0D PFACE +//0x0E PFACE FACE +bool DRW_Vertex::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs, double el){ + bool ret = DRW_Entity::parseDwg(version, buf, NULL, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing pline Vertex *********************************************\n"); + + if (oType == 0x0A) { //pline 2D, needed example + flags = buf->getRawChar8(); //RLZ: EC unknown type + DRW_DBG("flags value: "); DRW_DBG(flags); + basePoint = buf->get3BitDouble(); + basePoint.z = el; + DRW_DBG("basePoint: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); + stawidth = buf->getBitDouble(); + if (stawidth < 0) + endwidth = stawidth = fabs(stawidth); + else + endwidth = buf->getBitDouble(); + bulge = buf->getBitDouble(); + if (version > DRW::AC1021) //2010+ + DRW_DBG("Vertex ID: "); DRW_DBG(buf->getBitLong()); + tgdir = buf->getBitDouble(); + } else if (oType == 0x0B || oType == 0x0C || oType == 0x0D) { //PFACE + flags = buf->getRawChar8(); //RLZ: EC unknown type + DRW_DBG("flags value: "); DRW_DBG(flags); + basePoint = buf->get3BitDouble(); + DRW_DBG("basePoint: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); + } else if (oType == 0x0E) { //PFACE FACE + vindex1 = buf->getBitShort(); + vindex2 = buf->getBitShort(); + vindex3 = buf->getBitShort(); + vindex4 = buf->getBitShort(); + } + + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; +// RS crc; //RS */ + return buf->isGood(); +} + +void DRW_Hatch::parseCode(int code, dxfReader *reader){ + switch (code) { + case 2: + name = reader->getUtf8String(); + break; + case 70: + solid = reader->getInt32(); + break; + case 71: + associative = reader->getInt32(); + break; + case 72: /*edge type*/ + if (ispol){ //if is polyline is a as_bulge flag + break; + } else if (reader->getInt32() == 1){ //line + addLine(); + } else if (reader->getInt32() == 2){ //arc + addArc(); + } else if (reader->getInt32() == 3){ //elliptic arc + addEllipse(); + } else if (reader->getInt32() == 4){ //spline + addSpline(); + } + break; + case 10: + if (pt) pt->basePoint.x = reader->getDouble(); + else if (pline) { + plvert = pline->addVertex(); + plvert->x = reader->getDouble(); + } + break; + case 20: + if (pt) pt->basePoint.y = reader->getDouble(); + else if (plvert) plvert ->y = reader->getDouble(); + break; + case 11: + if (line) line->secPoint.x = reader->getDouble(); + else if (ellipse) ellipse->secPoint.x = reader->getDouble(); + break; + case 21: + if (line) line->secPoint.y = reader->getDouble(); + else if (ellipse) ellipse->secPoint.y = reader->getDouble(); + break; + case 40: + if (arc) arc->radious = reader->getDouble(); + else if (ellipse) ellipse->ratio = reader->getDouble(); + break; + case 41: + scale = reader->getDouble(); + break; + case 42: + if (plvert) plvert ->bulge = reader->getDouble(); + break; + case 50: + if (arc) arc->staangle = reader->getDouble()/ARAD; + else if (ellipse) ellipse->staparam = reader->getDouble()/ARAD; + break; + case 51: + if (arc) arc->endangle = reader->getDouble()/ARAD; + else if (ellipse) ellipse->endparam = reader->getDouble()/ARAD; + break; + case 52: + angle = reader->getDouble(); + break; + case 73: + if (arc) arc->isccw = reader->getInt32(); + else if (pline) pline->flags = reader->getInt32(); + break; + case 75: + hstyle = reader->getInt32(); + break; + case 76: + hpattern = reader->getInt32(); + break; + case 77: + doubleflag = reader->getInt32(); + break; + case 78: + deflines = reader->getInt32(); + break; + case 91: + loopsnum = reader->getInt32(); + looplist.reserve(loopsnum); + break; + case 92: + loop = new DRW_HatchLoop(reader->getInt32()); + looplist.push_back(loop); + if (reader->getInt32() & 2) { + ispol = true; + clearEntities(); + pline = new DRW_LWPolyline; + loop->objlist.push_back(pline); + } else ispol = false; + break; + case 93: + if (pline) pline->vertexnum = reader->getInt32(); + else loop->numedges = reader->getInt32();//aqui reserve + break; + case 98: //seed points ?? + clearEntities(); + break; + default: + DRW_Point::parseCode(code, reader); + break; + } +} + +bool DRW_Hatch::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + duint32 totalBoundItems = 0; + bool havePixelSize = false; + + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_Entity::parseDwg(version, buf, sBuf, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing hatch *********************************************\n"); + + //Gradient data, RLZ: is ok or if grad > 0 continue read ? + if (version > DRW::AC1015) { //2004+ + dint32 isGradient = buf->getBitLong(); + DRW_DBG("is Gradient: "); DRW_DBG(isGradient); + dint32 res = buf->getBitLong(); + DRW_DBG(" reserved: "); DRW_DBG(res); + double gradAngle = buf->getBitDouble(); + DRW_DBG(" Gradient angle: "); DRW_DBG(gradAngle); + double gradShift = buf->getBitDouble(); + DRW_DBG(" Gradient shift: "); DRW_DBG(gradShift); + dint32 singleCol = buf->getBitLong(); + DRW_DBG("\nsingle color Grad: "); DRW_DBG(singleCol); + double gradTint = buf->getBitDouble(); + DRW_DBG(" Gradient tint: "); DRW_DBG(gradTint); + dint32 numCol = buf->getBitLong(); + DRW_DBG(" num colors: "); DRW_DBG(numCol); + for (dint32 i = 0 ; i < numCol; ++i){ + double unkDouble = buf->getBitDouble(); + DRW_DBG("\nunkDouble: "); DRW_DBG(unkDouble); + duint16 unkShort = buf->getBitShort(); + DRW_DBG(" unkShort: "); DRW_DBG(unkShort); + dint32 rgbCol = buf->getBitLong(); + DRW_DBG(" rgb color: "); DRW_DBG(rgbCol); + duint8 ignCol = buf->getRawChar8(); + DRW_DBG(" ignored color: "); DRW_DBG(ignCol); + } + UTF8STRING gradName = sBuf->getVariableText(version, false); + DRW_DBG("\ngradient name: "); DRW_DBG(gradName.c_str()); DRW_DBG("\n"); + } + basePoint.z = buf->getBitDouble(); + extPoint = buf->get3BitDouble(); + DRW_DBG("base point: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); + DRW_DBG("\nextrusion: "); DRW_DBGPT(extPoint.x, extPoint.y, extPoint.z); + name = sBuf->getVariableText(version, false); + DRW_DBG("\nhatch pattern name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); + solid = buf->getBit(); + associative = buf->getBit(); + loopsnum = buf->getBitLong(); + + //read loops + for (dint32 i = 0 ; i < loopsnum; ++i){ + loop = new DRW_HatchLoop(buf->getBitLong()); + havePixelSize |= loop->type & 4; + if (!(loop->type & 2)){ //Not polyline + dint32 numPathSeg = buf->getBitLong(); + for (dint32 j = 0; jgetRawChar8(); + if (typePath == 1){ //line + addLine(); + line->basePoint = buf->get2RawDouble(); + line->secPoint = buf->get2RawDouble(); + } else if (typePath == 2){ //circle arc + addArc(); + arc->basePoint = buf->get2RawDouble(); + arc->radious = buf->getBitDouble(); + arc->staangle = buf->getBitDouble(); + arc->endangle = buf->getBitDouble(); + arc->isccw = buf->getBit(); + } else if (typePath == 3){ //ellipse arc + addEllipse(); + ellipse->basePoint = buf->get2RawDouble(); + ellipse->secPoint = buf->get2RawDouble(); + ellipse->ratio = buf->getBitDouble(); + ellipse->staparam = buf->getBitDouble(); + ellipse->endparam = buf->getBitDouble(); + ellipse->isccw = buf->getBit(); + } else if (typePath == 4){ //spline + addSpline(); + spline->degree = buf->getBitLong(); + bool isRational = buf->getBit(); + spline->flags |= (isRational << 2); //rational + spline->flags |= (buf->getBit() << 1); //periodic + spline->nknots = buf->getBitLong(); + spline->knotslist.reserve(spline->nknots); + for (dint32 j = 0; j < spline->nknots;++j){ + spline->knotslist.push_back (buf->getBitDouble()); + } + spline->ncontrol = buf->getBitLong(); + spline->controllist.reserve(spline->ncontrol); + for (dint32 j = 0; j < spline->ncontrol;++j){ + DRW_Coord* crd = new DRW_Coord(buf->get3BitDouble()); + if(isRational) + crd->z = buf->getBitDouble(); //RLZ: investigate how store weight + spline->controllist.push_back(crd); + } + if (version > DRW::AC1021) { //2010+ + spline->nfit = buf->getBitLong(); + spline->fitlist.reserve(spline->nfit); + for (dint32 j = 0; j < spline->nfit;++j){ + DRW_Coord* crd = new DRW_Coord(buf->get3BitDouble()); + spline->fitlist.push_back (crd); + } + spline->tgStart = buf->get2RawDouble(); + spline->tgEnd = buf->get2RawDouble(); + } + } + } + } else { //end not pline, start polyline + pline = new DRW_LWPolyline; + bool asBulge = buf->getBit(); + pline->flags = buf->getBit();//closed bit + dint32 numVert = buf->getBitLong(); + for (dint32 j = 0; jgetRawDouble(); + v.y = buf->getRawDouble(); + if (asBulge) + v.bulge = buf->getBitDouble(); + pline->addVertex(v); + } + loop->objlist.push_back(pline); + }//end polyline + loop->update(); + looplist.push_back(loop); + totalBoundItems += buf->getBitLong(); + DRW_DBG(" totalBoundItems: "); DRW_DBG(totalBoundItems); + } //end read loops + + hstyle = buf->getBitShort(); + hpattern = buf->getBitShort(); + DRW_DBG("\nhatch style: "); DRW_DBG(hstyle); DRW_DBG(" pattern type"); DRW_DBG(hpattern); + if (!solid){ + angle = buf->getBitDouble(); + scale = buf->getBitDouble(); + doubleflag = buf->getBit(); + deflines = buf->getBitShort(); + for (dint32 i = 0 ; i < deflines; ++i){ + DRW_Coord ptL, offL; + double angleL = buf->getBitDouble(); + ptL.x = buf->getBitDouble(); + ptL.y = buf->getBitDouble(); + offL.x = buf->getBitDouble(); + offL.y = buf->getBitDouble(); + duint16 numDashL = buf->getBitShort(); + DRW_DBG("\ndef line: "); DRW_DBG(angleL); DRW_DBG(","); DRW_DBG(ptL.x); DRW_DBG(","); DRW_DBG(ptL.y); + DRW_DBG(","); DRW_DBG(offL.x); DRW_DBG(","); DRW_DBG(offL.y); DRW_DBG(","); DRW_DBG(angleL); + for (duint16 i = 0 ; i < numDashL; ++i){ + double lengthL = buf->getBitDouble(); + DRW_DBG(","); DRW_DBG(lengthL); + } + }//end deflines + } //end not solid + + if (havePixelSize){ + ddouble64 pixsize = buf->getBitDouble(); + DRW_DBG("\npixel size: "); DRW_DBG(pixsize); + } + dint32 numSeedPoints = buf->getBitLong(); + DRW_DBG("\nnum Seed Points "); DRW_DBG(numSeedPoints); + //read Seed Points + DRW_Coord seedPt; + for (dint32 i = 0 ; i < numSeedPoints; ++i){ + seedPt.x = buf->getRawDouble(); + seedPt.y = buf->getRawDouble(); + DRW_DBG("\n "); DRW_DBG(seedPt.x); DRW_DBG(","); DRW_DBG(seedPt.y); + } + + DRW_DBG("\n"); + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + + for (duint32 i = 0 ; i < totalBoundItems; ++i){ + dwgHandle biH = buf->getHandle(); + DRW_DBG("Boundary Items Handle: "); DRW_DBGHL(biH.code, biH.size, biH.ref); + } + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); +// RS crc; //RS */ + return buf->isGood(); +} + +void DRW_Spline::parseCode(int code, dxfReader *reader){ + switch (code) { + case 210: + normalVec.x = reader->getDouble(); + break; + case 220: + normalVec.y = reader->getDouble(); + break; + case 230: + normalVec.z = reader->getDouble(); + break; + case 12: + tgStart.x = reader->getDouble(); + break; + case 22: + tgStart.y = reader->getDouble(); + break; + case 32: + tgStart.z = reader->getDouble(); + break; + case 13: + tgEnd.x = reader->getDouble(); + break; + case 23: + tgEnd.y = reader->getDouble(); + break; + case 33: + tgEnd.z = reader->getDouble(); + break; + case 70: + flags = reader->getInt32(); + break; + case 71: + degree = reader->getInt32(); + break; + case 72: + nknots = reader->getInt32(); + break; + case 73: + ncontrol = reader->getInt32(); + break; + case 74: + nfit = reader->getInt32(); + break; + case 42: + tolknot = reader->getDouble(); + break; + case 43: + tolcontrol = reader->getDouble(); + break; + case 44: + tolfit = reader->getDouble(); + break; + case 10: { + controlpoint = new DRW_Coord(); + controllist.push_back(controlpoint); + controlpoint->x = reader->getDouble(); + break; } + case 20: + if(controlpoint != NULL) + controlpoint->y = reader->getDouble(); + break; + case 30: + if(controlpoint != NULL) + controlpoint->z = reader->getDouble(); + break; + case 11: { + fitpoint = new DRW_Coord(); + fitlist.push_back(fitpoint); + fitpoint->x = reader->getDouble(); + break; } + case 21: + if(fitpoint != NULL) + fitpoint->y = reader->getDouble(); + break; + case 31: + if(fitpoint != NULL) + fitpoint->z = reader->getDouble(); + break; + case 40: + knotslist.push_back(reader->getDouble()); + break; + case 41: + weightlist.push_back(reader->getDouble()); + break; + default: + DRW_Entity::parseCode(code, reader); + break; + } +} + +bool DRW_Spline::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + bool ret = DRW_Entity::parseDwg(version, buf, NULL, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing spline *********************************************\n"); + duint8 weight = 0; // RLZ ??? flags, weight, code 70, bit 4 (16) + + dint32 scenario = buf->getBitLong(); + DRW_DBG("scenario: "); DRW_DBG(scenario); + if (version > DRW::AC1024) { + dint32 splFlag1 = buf->getBitLong(); + if (splFlag1 & 1) + scenario = 2; + dint32 knotParam = buf->getBitLong(); + DRW_DBG("2013 splFlag1: "); DRW_DBG(splFlag1); DRW_DBG(" 2013 knotParam: "); + DRW_DBG(knotParam); +// DRW_DBG("unk bit: "); DRW_DBG(buf->getBit()); + } + degree = buf->getBitLong(); //RLZ: code 71, verify with dxf + DRW_DBG(" degree: "); DRW_DBG(degree); DRW_DBG("\n"); + if (scenario == 2) { + flags = 8;//scenario 2 = not rational & planar + tolfit = buf->getBitDouble();//BD + DRW_DBG("flags: "); DRW_DBG(flags); DRW_DBG(" tolfit: "); DRW_DBG(tolfit); + tgStart =buf->get3BitDouble(); + DRW_DBG(" Start Tangent: "); DRW_DBGPT(tgStart.x, tgStart.y, tgStart.z); + tgEnd =buf->get3BitDouble(); + DRW_DBG("\nEnd Tangent: "); DRW_DBGPT(tgEnd.x, tgEnd.y, tgEnd.z); + nfit = buf->getBitLong(); + DRW_DBG("\nnumber of fit points: "); DRW_DBG(nfit); + } else if (scenario == 1) { + flags = 8;//scenario 1 = rational & planar + flags |= buf->getBit() << 2; //flags, rational, code 70, bit 2 (4) + flags |= buf->getBit(); //flags, closed, code 70, bit 0 (1) + flags |= buf->getBit() << 1; //flags, periodic, code 70, bit 1 (2) + tolknot = buf->getBitDouble(); + tolcontrol = buf->getBitDouble(); + DRW_DBG("flags: "); DRW_DBG(flags); DRW_DBG(" knot tolerance: "); DRW_DBG(tolknot); + DRW_DBG(" control point tolerance: "); DRW_DBG(tolcontrol); + nknots = buf->getBitLong(); + ncontrol = buf->getBitLong(); + weight = buf->getBit(); // RLZ ??? flags, weight, code 70, bit 4 (16) + DRW_DBG("\nnum of knots: "); DRW_DBG(nknots); DRW_DBG(" num of control pt: "); + DRW_DBG(ncontrol); DRW_DBG(" weight bit: "); DRW_DBG(weight); + } else { + DRW_DBG("\ndwg Ellipse, unknouwn scenario\n"); + return false; //RLZ: from doc only 1 or 2 are ok ? + } + + knotslist.reserve(nknots); + for (dint32 i= 0; igetBitDouble()); + } + controllist.reserve(ncontrol); + for (dint32 i= 0; iget3BitDouble()); + controllist.push_back(crd); + if (weight){ + DRW_DBG("\n w: "); DRW_DBG(buf->getBitDouble()); //RLZ Warning: D (BD or RD) + } + } + fitlist.reserve(nfit); + for (dint32 i= 0; iget3BitDouble()); + fitlist.push_back (crd); + } + if (DRW_DBGGL == DRW_dbg::DEBUG){ + DRW_DBG("\nknots list: "); + for (std::vector::iterator it = knotslist.begin() ; it != knotslist.end(); ++it){ + DRW_DBG("\n"); DRW_DBG(*it); + } + DRW_DBG("\ncontrol point list: "); + for (std::vector::iterator it = controllist.begin() ; it != controllist.end(); ++it){ + DRW_DBG("\n"); DRW_DBGPT((*it)->x,(*it)->y,(*it)->z); + } + DRW_DBG("\nfit point list: "); + for (std::vector::iterator it = fitlist.begin() ; it != fitlist.end(); ++it){ + DRW_DBG("\n"); DRW_DBGPT((*it)->x,(*it)->y,(*it)->z); + } + } + + /* Common Entity Handle Data */ + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; +// RS crc; //RS */ + return buf->isGood(); +} + +void DRW_Image::parseCode(int code, dxfReader *reader){ + switch (code) { + case 12: + vVector.x = reader->getDouble(); + break; + case 22: + vVector.y = reader->getDouble(); + break; + case 32: + vVector.z = reader->getDouble(); + break; + case 13: + sizeu = reader->getDouble(); + break; + case 23: + sizev = reader->getDouble(); + break; + case 340: + ref = reader->getHandleString(); + break; + case 280: + clip = reader->getInt32(); + break; + case 281: + brightness = reader->getInt32(); + break; + case 282: + contrast = reader->getInt32(); + break; + case 283: + fade = reader->getInt32(); + break; + default: + DRW_Line::parseCode(code, reader); + break; + } +} + +bool DRW_Image::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_Entity::parseDwg(version, buf, sBuf, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing image *********************************************\n"); + + dint32 classVersion = buf->getBitLong(); + DRW_DBG("class Version: "); DRW_DBG(classVersion); + basePoint = buf->get3BitDouble(); + DRW_DBG("\nbase point: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); + secPoint = buf->get3BitDouble(); + DRW_DBG("\nU vector: "); DRW_DBGPT(secPoint.x, secPoint.y, secPoint.z); + vVector = buf->get3BitDouble(); + DRW_DBG("\nV vector: "); DRW_DBGPT(vVector.x, vVector.y, vVector.z); + sizeu = buf->getRawDouble(); + sizev = buf->getRawDouble(); + DRW_DBG("\nsize U: "); DRW_DBG(sizeu); DRW_DBG("\nsize V: "); DRW_DBG(sizev); + duint16 displayProps = buf->getBitShort(); + (void)displayProps; + clip = buf->getBit(); + brightness = buf->getRawChar8(); + contrast = buf->getRawChar8(); + fade = buf->getRawChar8(); + if (version > DRW::AC1021){ //2010+ + bool clipMode = buf->getBit(); + (void)clipMode; + } + duint16 clipType = buf->getBitShort(); + if (clipType == 1){ + buf->get2RawDouble(); + buf->get2RawDouble(); + } else { //clipType == 2 + dint32 numVerts = buf->getBitLong(); + for (int i= 0; i< numVerts;++i) + buf->get2RawDouble(); + } + + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + + dwgHandle biH = buf->getHandle(); + DRW_DBG("ImageDef Handle: "); DRW_DBGHL(biH.code, biH.size, biH.ref); + ref = biH.ref; + biH = buf->getHandle(); + DRW_DBG("ImageDefReactor Handle: "); DRW_DBGHL(biH.code, biH.size, biH.ref); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); +// RS crc; //RS */ + return buf->isGood(); +} + +void DRW_Dimension::parseCode(int code, dxfReader *reader){ + switch (code) { + case 1: + text = reader->getUtf8String(); + break; + case 2: + name = reader->getString(); + break; + case 3: + style = reader->getUtf8String(); + break; + case 70: + type = reader->getInt32(); + break; + case 71: + align = reader->getInt32(); + break; + case 72: + linesty = reader->getInt32(); + break; + case 10: + defPoint.x = reader->getDouble(); + break; + case 20: + defPoint.y = reader->getDouble(); + break; + case 30: + defPoint.z = reader->getDouble(); + break; + case 11: + textPoint.x = reader->getDouble(); + break; + case 21: + textPoint.y = reader->getDouble(); + break; + case 31: + textPoint.z = reader->getDouble(); + break; + case 12: + clonePoint.x = reader->getDouble(); + break; + case 22: + clonePoint.y = reader->getDouble(); + break; + case 32: + clonePoint.z = reader->getDouble(); + break; + case 13: + def1.x = reader->getDouble(); + break; + case 23: + def1.y = reader->getDouble(); + break; + case 33: + def1.z = reader->getDouble(); + break; + case 14: + def2.x = reader->getDouble(); + break; + case 24: + def2.y = reader->getDouble(); + break; + case 34: + def2.z = reader->getDouble(); + break; + case 15: + circlePoint.x = reader->getDouble(); + break; + case 25: + circlePoint.y = reader->getDouble(); + break; + case 35: + circlePoint.z = reader->getDouble(); + break; + case 16: + arcPoint.x = reader->getDouble(); + break; + case 26: + arcPoint.y = reader->getDouble(); + break; + case 36: + arcPoint.z = reader->getDouble(); + break; + case 41: + linefactor = reader->getDouble(); + break; + case 42: + actual = reader->getDouble(); + hasActual = (actual != 0.0); + break; + case 53: + rot = reader->getDouble(); + break; + case 50: + angle = reader->getDouble(); + break; + case 52: + oblique = reader->getDouble(); + break; + case 40: + length = reader->getDouble(); + break; + case 51: + hdir = reader->getDouble(); + break; + case 210: + extPoint.x = reader->getDouble(); + break; + case 220: + extPoint.y = reader->getDouble(); + break; + case 230: + extPoint.z = reader->getDouble(); + break; + default: + DRW_Entity::parseCode(code, reader); + break; + } +} + +bool DRW_Dimension::parseDwg(DRW::Version version, dwgBuffer *buf, dwgBuffer *sBuf){ + DRW_DBG("\n***************************** parsing dimension *********************************************"); + if (version > DRW::AC1021) { //2010+ + duint8 dimVersion = buf->getRawChar8(); + DRW_DBG("\ndimVersion: "); DRW_DBG(dimVersion); + } + extPoint = buf->getExtrusion(version > DRW::AC1014); + DRW_DBG("\nextPoint: "); DRW_DBGPT(extPoint.x, extPoint.y, extPoint.z); + if (version > DRW::AC1014) { //2000+ + DRW_DBG("\nFive unknown bits: "); DRW_DBG(buf->getBit()); DRW_DBG(buf->getBit()); + DRW_DBG(buf->getBit()); DRW_DBG(buf->getBit()); DRW_DBG(buf->getBit()); + } + textPoint.x = buf->getRawDouble(); + textPoint.y = buf->getRawDouble(); + textPoint.z = buf->getBitDouble(); + DRW_DBG("\ntextPoint: "); DRW_DBGPT(textPoint.x, textPoint.y, textPoint.z); + type = buf->getRawChar8(); + DRW_DBG("\ntype (70) read: "); DRW_DBG(type); + type = (type & 1) ? type & 0x7F : type | 0x80; //set bit 7 + type = (type & 2) ? type | 0x20 : type & 0xDF; //set bit 5 + DRW_DBG(" type (70) set: "); DRW_DBG(type); + //clear last 3 bits to set integer dim type + type &= 0xF8; + text = sBuf->getVariableText(version, false); + DRW_DBG("\nforced dim text: "); DRW_DBG(text.c_str()); + rot = buf->getBitDouble(); + hdir = buf->getBitDouble(); + DRW_Coord inspoint = buf->get3BitDouble(); + DRW_DBG("\ninspoint: "); DRW_DBGPT(inspoint.x, inspoint.y, inspoint.z); + double insRot_code54 = buf->getBitDouble(); //RLZ: unknown, investigate + DRW_DBG(" insRot_code54: "); DRW_DBG(insRot_code54); + if (version > DRW::AC1014) { //2000+ + align = buf->getBitShort(); + linesty = buf->getBitShort(); + linefactor = buf->getBitDouble(); + double actMeas = buf->getBitDouble(); + DRW_DBG("\n actMeas_code42: "); DRW_DBG(actMeas); + if (version > DRW::AC1018) { //2007+ + bool unk = buf->getBit(); + bool flip1 = buf->getBit(); + bool flip2 = buf->getBit(); + DRW_DBG("\n2007, unk, flip1, flip2: "); DRW_DBG(unk); DRW_DBG(flip1); DRW_DBG(flip2); + } + } + clonePoint.x = buf->getRawDouble(); + clonePoint.y = buf->getRawDouble(); + DRW_DBG("\nclonePoint: "); DRW_DBGPT(clonePoint.x, clonePoint.y, clonePoint.z); + + return buf->isGood(); +} + +bool DRW_DimAligned::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_Entity::parseDwg(version, buf, sBuf, bs); + if (!ret) + return ret; + ret = DRW_Dimension::parseDwg(version, buf, sBuf); + if (!ret) + return ret; + if (oType == 0x15) + DRW_DBG("\n***************************** parsing dim linear *********************************************\n"); + else + DRW_DBG("\n***************************** parsing dim aligned *********************************************\n"); + DRW_Coord pt = buf->get3BitDouble(); + setPt3(pt); //def1 + DRW_DBG("def1: "); DRW_DBGPT(pt.x, pt.y, pt.z); + pt = buf->get3BitDouble(); + setPt4(pt); + DRW_DBG("\ndef2: "); DRW_DBGPT(pt.x, pt.y, pt.z); + pt = buf->get3BitDouble(); + setDefPoint(pt); + DRW_DBG("\ndefPoint: "); DRW_DBGPT(pt.x, pt.y, pt.z); + setOb52(buf->getBitDouble()); + if (oType == 0x15) + setAn50(buf->getBitDouble() * ARAD); + else + type |= 1; + DRW_DBG("\n type (70) final: "); DRW_DBG(type); DRW_DBG("\n"); + + ret = DRW_Entity::parseDwgEntHandle(version, buf); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + if (!ret) + return ret; + dimStyleH = buf->getHandle(); + DRW_DBG("dim style Handle: "); DRW_DBGHL(dimStyleH.code, dimStyleH.size, dimStyleH.ref); DRW_DBG("\n"); + blockH = buf->getHandle(); /* H 7 STYLE (hard pointer) */ + DRW_DBG("anon block Handle: "); DRW_DBGHL(blockH.code, blockH.size, blockH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + + // RS crc; //RS */ + return buf->isGood(); + } + + bool DRW_DimRadial::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_Entity::parseDwg(version, buf, sBuf, bs); + if (!ret) + return ret; + ret = DRW_Dimension::parseDwg(version, buf, sBuf); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing dim radial *********************************************\n"); + DRW_Coord pt = buf->get3BitDouble(); + setDefPoint(pt); //code 10 + DRW_DBG("defPoint: "); DRW_DBGPT(pt.x, pt.y, pt.z); + pt = buf->get3BitDouble(); + setPt5(pt); //center pt code 15 + DRW_DBG("\ncenter point: "); DRW_DBGPT(pt.x, pt.y, pt.z); + setRa40(buf->getBitDouble()); //leader length code 40 + DRW_DBG("\nleader length: "); DRW_DBG(getRa40()); + type |= 4; + DRW_DBG("\n type (70) final: "); DRW_DBG(type); DRW_DBG("\n"); + + ret = DRW_Entity::parseDwgEntHandle(version, buf); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + if (!ret) + return ret; + dimStyleH = buf->getHandle(); + DRW_DBG("dim style Handle: "); DRW_DBGHL(dimStyleH.code, dimStyleH.size, dimStyleH.ref); DRW_DBG("\n"); + blockH = buf->getHandle(); /* H 7 STYLE (hard pointer) */ + DRW_DBG("anon block Handle: "); DRW_DBGHL(blockH.code, blockH.size, blockH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + + // RS crc; //RS */ + return buf->isGood(); + } + + bool DRW_DimDiametric::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_Entity::parseDwg(version, buf, sBuf, bs); + if (!ret) + return ret; + ret = DRW_Dimension::parseDwg(version, buf, sBuf); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing dim diametric *********************************************\n"); + DRW_Coord pt = buf->get3BitDouble(); + setPt5(pt); //center pt code 15 + DRW_DBG("center point: "); DRW_DBGPT(pt.x, pt.y, pt.z); + pt = buf->get3BitDouble(); + setDefPoint(pt); //code 10 + DRW_DBG("\ndefPoint: "); DRW_DBGPT(pt.x, pt.y, pt.z); + setRa40(buf->getBitDouble()); //leader length code 40 + DRW_DBG("\nleader length: "); DRW_DBG(getRa40()); + type |= 3; + DRW_DBG("\n type (70) final: "); DRW_DBG(type); DRW_DBG("\n"); + + ret = DRW_Entity::parseDwgEntHandle(version, buf); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + if (!ret) + return ret; + dimStyleH = buf->getHandle(); + DRW_DBG("dim style Handle: "); DRW_DBGHL(dimStyleH.code, dimStyleH.size, dimStyleH.ref); DRW_DBG("\n"); + blockH = buf->getHandle(); /* H 7 STYLE (hard pointer) */ + DRW_DBG("anon block Handle: "); DRW_DBGHL(blockH.code, blockH.size, blockH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + + // RS crc; //RS */ + return buf->isGood(); + } + +bool DRW_DimAngular::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_Entity::parseDwg(version, buf, sBuf, bs); + if (!ret) + return ret; + ret = DRW_Dimension::parseDwg(version, buf, sBuf); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing dim angular *********************************************\n"); + DRW_Coord pt; + pt.x = buf->getRawDouble(); + pt.y = buf->getRawDouble(); + setPt6(pt); //code 16 + DRW_DBG("arc Point: "); DRW_DBGPT(pt.x, pt.y, pt.z); + pt = buf->get3BitDouble(); + setPt3(pt); //def1 code 13 + DRW_DBG("\ndef1: "); DRW_DBGPT(pt.x, pt.y, pt.z); + pt = buf->get3BitDouble(); + setPt4(pt); //def2 code 14 + DRW_DBG("\ndef2: "); DRW_DBGPT(pt.x, pt.y, pt.z); + pt = buf->get3BitDouble(); + setPt5(pt); //center pt code 15 + DRW_DBG("\ncenter point: "); DRW_DBGPT(pt.x, pt.y, pt.z); + pt = buf->get3BitDouble(); + setDefPoint(pt); //code 10 + DRW_DBG("\ndefPoint: "); DRW_DBGPT(pt.x, pt.y, pt.z); + type |= 0x02; + DRW_DBG("\n type (70) final: "); DRW_DBG(type); DRW_DBG("\n"); + + ret = DRW_Entity::parseDwgEntHandle(version, buf); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + if (!ret) + return ret; + dimStyleH = buf->getHandle(); + DRW_DBG("dim style Handle: "); DRW_DBGHL(dimStyleH.code, dimStyleH.size, dimStyleH.ref); DRW_DBG("\n"); + blockH = buf->getHandle(); /* H 7 STYLE (hard pointer) */ + DRW_DBG("anon block Handle: "); DRW_DBGHL(blockH.code, blockH.size, blockH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + + // RS crc; //RS */ + return buf->isGood(); +} + +bool DRW_DimAngular3p::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_Entity::parseDwg(version, buf, sBuf, bs); + if (!ret) + return ret; + ret = DRW_Dimension::parseDwg(version, buf, sBuf); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing dim angular3p *********************************************\n"); + DRW_Coord pt = buf->get3BitDouble(); + setDefPoint(pt); //code 10 + DRW_DBG("defPoint: "); DRW_DBGPT(pt.x, pt.y, pt.z); + pt = buf->get3BitDouble(); + setPt3(pt); //def1 code 13 + DRW_DBG("\ndef1: "); DRW_DBGPT(pt.x, pt.y, pt.z); + pt = buf->get3BitDouble(); + setPt4(pt); //def2 code 14 + DRW_DBG("\ndef2: "); DRW_DBGPT(pt.x, pt.y, pt.z); + pt = buf->get3BitDouble(); + setPt5(pt); //center pt code 15 + DRW_DBG("\ncenter point: "); DRW_DBGPT(pt.x, pt.y, pt.z); + type |= 0x05; + DRW_DBG("\n type (70) final: "); DRW_DBG(type); DRW_DBG("\n"); + + ret = DRW_Entity::parseDwgEntHandle(version, buf); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + if (!ret) + return ret; + dimStyleH = buf->getHandle(); + DRW_DBG("dim style Handle: "); DRW_DBGHL(dimStyleH.code, dimStyleH.size, dimStyleH.ref); DRW_DBG("\n"); + blockH = buf->getHandle(); /* H 7 STYLE (hard pointer) */ + DRW_DBG("anon block Handle: "); DRW_DBGHL(blockH.code, blockH.size, blockH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + + // RS crc; //RS */ + return buf->isGood(); +} + +bool DRW_DimOrdinate::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_Entity::parseDwg(version, buf, sBuf, bs); + if (!ret) + return ret; + ret = DRW_Dimension::parseDwg(version, buf, sBuf); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing dim ordinate *********************************************\n"); + DRW_Coord pt = buf->get3BitDouble(); + setDefPoint(pt); + DRW_DBG("defPoint: "); DRW_DBGPT(pt.x, pt.y, pt.z); + pt = buf->get3BitDouble(); + setPt3(pt); //def1 + DRW_DBG("\ndef1: "); DRW_DBGPT(pt.x, pt.y, pt.z); + pt = buf->get3BitDouble(); + setPt4(pt); + DRW_DBG("\ndef2: "); DRW_DBGPT(pt.x, pt.y, pt.z); + duint8 type2 = buf->getRawChar8();//RLZ: correct this + DRW_DBG("type2 (70) read: "); DRW_DBG(type2); + type = (type2 & 1) ? type | 0x80 : type & 0xBF; //set bit 6 + DRW_DBG(" type (70) set: "); DRW_DBG(type); + type |= 6; + DRW_DBG("\n type (70) final: "); DRW_DBG(type); + + ret = DRW_Entity::parseDwgEntHandle(version, buf); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + if (!ret) + return ret; + dimStyleH = buf->getHandle(); + DRW_DBG("dim style Handle: "); DRW_DBGHL(dimStyleH.code, dimStyleH.size, dimStyleH.ref); DRW_DBG("\n"); + blockH = buf->getHandle(); /* H 7 STYLE (hard pointer) */ + DRW_DBG("anon block Handle: "); DRW_DBGHL(blockH.code, blockH.size, blockH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + + // RS crc; //RS */ + return buf->isGood(); +} + +void DRW_Leader::parseCode(int code, dxfReader *reader){ + switch (code) { + case 3: + style = reader->getUtf8String(); + break; + case 71: + arrow = reader->getInt32(); + break; + case 72: + leadertype = reader->getInt32(); + break; + case 73: + flag = reader->getInt32(); + break; + case 74: + hookline = reader->getInt32(); + break; + case 75: + hookflag = reader->getInt32(); + break; + case 76: + vertnum = reader->getInt32(); + break; + case 77: + coloruse = reader->getInt32(); + break; + case 40: + textheight = reader->getDouble(); + break; + case 41: + textwidth = reader->getDouble(); + break; + case 10: { + vertexpoint = new DRW_Coord(); + vertexlist.push_back(vertexpoint); + vertexpoint->x = reader->getDouble(); + break; } + case 20: + if(vertexpoint != NULL) + vertexpoint->y = reader->getDouble(); + break; + case 30: + if(vertexpoint != NULL) + vertexpoint->z = reader->getDouble(); + break; + case 340: + annotHandle = reader->getHandleString(); + break; + case 210: + extrusionPoint.x = reader->getDouble(); + break; + case 220: + extrusionPoint.y = reader->getDouble(); + break; + case 230: + extrusionPoint.z = reader->getDouble(); + break; + case 211: + horizdir.x = reader->getDouble(); + break; + case 221: + horizdir.y = reader->getDouble(); + break; + case 231: + horizdir.z = reader->getDouble(); + break; + case 212: + offsetblock.x = reader->getDouble(); + break; + case 222: + offsetblock.y = reader->getDouble(); + break; + case 232: + offsetblock.z = reader->getDouble(); + break; + case 213: + offsettext.x = reader->getDouble(); + break; + case 223: + offsettext.y = reader->getDouble(); + break; + case 233: + offsettext.z = reader->getDouble(); + break; + default: + DRW_Entity::parseCode(code, reader); + break; + } +} + +bool DRW_Leader::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_Entity::parseDwg(version, buf, sBuf, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing leader *********************************************\n"); + DRW_DBG("unknown bit "); DRW_DBG(buf->getBit()); + DRW_DBG(" annot type "); DRW_DBG(buf->getBitShort()); + DRW_DBG(" Path type "); DRW_DBG(buf->getBitShort()); + dint32 nPt = buf->getBitLong(); + DRW_DBG(" Num pts "); DRW_DBG(nPt); + + // add vertexs + for (int i = 0; i< nPt; i++){ + DRW_Coord* vertex = new DRW_Coord(buf->get3BitDouble()); + vertexlist.push_back(vertex); + DRW_DBG("\nvertex "); DRW_DBGPT(vertex->x, vertex->y, vertex->z); + } + DRW_Coord Endptproj = buf->get3BitDouble(); + DRW_DBG("\nEndptproj "); DRW_DBGPT(Endptproj.x, Endptproj.y, Endptproj.z); + extrusionPoint = buf->getExtrusion(version > DRW::AC1014); + DRW_DBG("\nextrusionPoint "); DRW_DBGPT(extrusionPoint.x, extrusionPoint.y, extrusionPoint.z); + if (version > DRW::AC1014) { //2000+ + DRW_DBG("\nFive unknown bits: "); DRW_DBG(buf->getBit()); DRW_DBG(buf->getBit()); + DRW_DBG(buf->getBit()); DRW_DBG(buf->getBit()); DRW_DBG(buf->getBit()); + } + horizdir = buf->get3BitDouble(); + DRW_DBG("\nhorizdir "); DRW_DBGPT(horizdir.x, horizdir.y, horizdir.z); + offsetblock = buf->get3BitDouble(); + DRW_DBG("\noffsetblock "); DRW_DBGPT(offsetblock.x, offsetblock.y, offsetblock.z); + if (version > DRW::AC1012) { //R14+ + DRW_Coord unk = buf->get3BitDouble(); + DRW_DBG("\nunknown "); DRW_DBGPT(unk.x, unk.y, unk.z); + } + if (version < DRW::AC1015) { //R14 - + DRW_DBG("\ndimgap "); DRW_DBG(buf->getBitDouble()); + } + if (version < DRW::AC1024) { //2010- + textheight = buf->getBitDouble(); + textwidth = buf->getBitDouble(); + DRW_DBG("\ntextheight "); DRW_DBG(textheight); DRW_DBG(" textwidth "); DRW_DBG(textwidth); + } + hookline = buf->getBit(); + arrow = buf->getBit(); + DRW_DBG(" hookline "); DRW_DBG(hookline); DRW_DBG(" arrow flag "); DRW_DBG(arrow); + + if (version < DRW::AC1015) { //R14 - + DRW_DBG("\nArrow head type "); DRW_DBG(buf->getBitShort()); + DRW_DBG("dimasz "); DRW_DBG(buf->getBitDouble()); + DRW_DBG("\nunk bit "); DRW_DBG(buf->getBit()); + DRW_DBG(" unk bit "); DRW_DBG(buf->getBit()); + DRW_DBG(" unk short "); DRW_DBG(buf->getBitShort()); + DRW_DBG(" byBlock color "); DRW_DBG(buf->getBitShort()); + DRW_DBG(" unk bit "); DRW_DBG(buf->getBit()); + DRW_DBG(" unk bit "); DRW_DBG(buf->getBit()); + } else { //R2000+ + DRW_DBG("\nunk short "); DRW_DBG(buf->getBitShort()); + DRW_DBG(" unk bit "); DRW_DBG(buf->getBit()); + DRW_DBG(" unk bit "); DRW_DBG(buf->getBit()); + } + DRW_DBG("\n"); + ret = DRW_Entity::parseDwgEntHandle(version, buf); + if (!ret) + return ret; + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + AnnotH = buf->getHandle(); + annotHandle = AnnotH.ref; + DRW_DBG("annot block Handle: "); DRW_DBGHL(AnnotH.code, AnnotH.size, dimStyleH.ref); DRW_DBG("\n"); + dimStyleH = buf->getHandle(); /* H 7 STYLE (hard pointer) */ + DRW_DBG("dim style Handle: "); DRW_DBGHL(dimStyleH.code, dimStyleH.size, dimStyleH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); +// RS crc; //RS */ + return buf->isGood(); +} + +void DRW_Viewport::parseCode(int code, dxfReader *reader){ + switch (code) { + case 40: + pswidth = reader->getDouble(); + break; + case 41: + psheight = reader->getDouble(); + break; + case 68: + vpstatus = reader->getInt32(); + break; + case 69: + vpID = reader->getInt32(); + break; + case 12: { + centerPX = reader->getDouble(); + break; } + case 22: + centerPY = reader->getDouble(); + break; + default: + DRW_Point::parseCode(code, reader); + break; + } +} +//ex 22 dec 34 +bool DRW_Viewport::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_Entity::parseDwg(version, buf, sBuf, bs); + if (!ret) + return ret; + DRW_DBG("\n***************************** parsing viewport *****************************************\n"); + basePoint.x = buf->getBitDouble(); + basePoint.y = buf->getBitDouble(); + basePoint.z = buf->getBitDouble(); + DRW_DBG("center "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); + pswidth = buf->getBitDouble(); + psheight = buf->getBitDouble(); + DRW_DBG("\nWidth: "); DRW_DBG(pswidth); DRW_DBG(", Height: "); DRW_DBG(psheight); DRW_DBG("\n"); + //RLZ TODO: complete in dxf + if (version > DRW::AC1014) {//2000+ + viewTarget.x = buf->getBitDouble(); + viewTarget.y = buf->getBitDouble(); + viewTarget.z = buf->getBitDouble(); + DRW_DBG("view Target "); DRW_DBGPT(viewTarget.x, viewTarget.y, viewTarget.z); + viewDir.x = buf->getBitDouble(); + viewDir.y = buf->getBitDouble(); + viewDir.z = buf->getBitDouble(); + DRW_DBG("\nview direction "); DRW_DBGPT(viewDir.x, viewDir.y, viewDir.z); + twistAngle = buf->getBitDouble(); + DRW_DBG("\nView twist Angle: "); DRW_DBG(twistAngle); + viewHeight = buf->getBitDouble(); + DRW_DBG("\nview Height: "); DRW_DBG(viewHeight); + viewLength = buf->getBitDouble(); + DRW_DBG(" Lens Length: "); DRW_DBG(viewLength); + frontClip = buf->getBitDouble(); + DRW_DBG("\nfront Clip Z: "); DRW_DBG(frontClip); + backClip = buf->getBitDouble(); + DRW_DBG(" back Clip Z: "); DRW_DBG(backClip); + snapAngle = buf->getBitDouble(); + DRW_DBG("\n snap Angle: "); DRW_DBG(snapAngle); + centerPX = buf->getRawDouble(); + centerPY = buf->getRawDouble(); + DRW_DBG("\nview center X: "); DRW_DBG(centerPX); DRW_DBG(", Y: "); DRW_DBG(centerPX); + snapPX = buf->getRawDouble(); + snapPY = buf->getRawDouble(); + DRW_DBG("\nSnap base point X: "); DRW_DBG(snapPX); DRW_DBG(", Y: "); DRW_DBG(snapPY); + snapSpPX = buf->getRawDouble(); + snapSpPY = buf->getRawDouble(); + DRW_DBG("\nSnap spacing X: "); DRW_DBG(snapSpPX); DRW_DBG(", Y: "); DRW_DBG(snapSpPY); + //RLZ: need to complete + DRW_DBG("\nGrid spacing X: "); DRW_DBG(buf->getRawDouble()); DRW_DBG(", Y: "); DRW_DBG(buf->getRawDouble());DRW_DBG("\n"); + DRW_DBG("Circle zoom?: "); DRW_DBG(buf->getBitShort()); DRW_DBG("\n"); + } + if (version > DRW::AC1018) {//2007+ + DRW_DBG("Grid major?: "); DRW_DBG(buf->getBitShort()); DRW_DBG("\n"); + } + if (version > DRW::AC1014) {//2000+ + frozenLyCount = buf->getBitLong(); + DRW_DBG("Frozen Layer count?: "); DRW_DBG(frozenLyCount); DRW_DBG("\n"); + DRW_DBG("Status Flags?: "); DRW_DBG(buf->getBitLong()); DRW_DBG("\n"); + //RLZ: Warning needed separate string buffer + DRW_DBG("Style sheet?: "); DRW_DBG(sBuf->getVariableText(version, false)); DRW_DBG("\n"); + DRW_DBG("Render mode?: "); DRW_DBG(buf->getRawChar8()); DRW_DBG("\n"); + DRW_DBG("UCS OMore...: "); DRW_DBG(buf->getBit()); DRW_DBG("\n"); + DRW_DBG("UCS VMore...: "); DRW_DBG(buf->getBit()); DRW_DBG("\n"); + DRW_DBG("UCS OMore...: "); DRW_DBGPT(buf->getBitDouble(), buf->getBitDouble(), buf->getBitDouble()); DRW_DBG("\n"); + DRW_DBG("ucs XAMore...: "); DRW_DBGPT(buf->getBitDouble(), buf->getBitDouble(), buf->getBitDouble()); DRW_DBG("\n"); + DRW_DBG("UCS YMore....: "); DRW_DBGPT(buf->getBitDouble(), buf->getBitDouble(), buf->getBitDouble()); DRW_DBG("\n"); + DRW_DBG("UCS EMore...: "); DRW_DBG(buf->getBitDouble()); DRW_DBG("\n"); + DRW_DBG("UCS OVMore...: "); DRW_DBG(buf->getBitShort()); DRW_DBG("\n"); + } + if (version > DRW::AC1015) {//2004+ + DRW_DBG("ShadePlot Mode...: "); DRW_DBG(buf->getBitShort()); DRW_DBG("\n"); + } + if (version > DRW::AC1018) {//2007+ + DRW_DBG("Use def Light...: "); DRW_DBG(buf->getBit()); DRW_DBG("\n"); + DRW_DBG("Def light type?: "); DRW_DBG(buf->getRawChar8()); DRW_DBG("\n"); + DRW_DBG("Brightness: "); DRW_DBG(buf->getBitDouble()); DRW_DBG("\n"); + DRW_DBG("Contrast: "); DRW_DBG(buf->getBitDouble()); DRW_DBG("\n"); +// DRW_DBG("Ambient Cmc or Enc: "); DRW_DBG(buf->getCmColor(version)); DRW_DBG("\n"); + DRW_DBG("Ambient (Cmc or Enc?), Enc: "); DRW_DBG(buf->getEnColor(version)); DRW_DBG("\n"); + } + ret = DRW_Entity::parseDwgEntHandle(version, buf); + + dwgHandle someHdl; + if (version < DRW::AC1015) {//R13 & R14 only + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + someHdl = buf->getHandle(); + DRW_DBG("ViewPort ent header: "); DRW_DBGHL(someHdl.code, someHdl.size, someHdl.ref); DRW_DBG("\n"); + } + if (version > DRW::AC1014) {//2000+ + for (duint8 i=0; i < frozenLyCount; ++i){ + someHdl = buf->getHandle(); + DRW_DBG("Frozen layer handle "); DRW_DBG(i); DRW_DBG(": "); DRW_DBGHL(someHdl.code, someHdl.size, someHdl.ref); DRW_DBG("\n"); + } + someHdl = buf->getHandle(); + DRW_DBG("Clip bpundary handle: "); DRW_DBGHL(someHdl.code, someHdl.size, someHdl.ref); DRW_DBG("\n"); + if (version == DRW::AC1015) {//2000 only + someHdl = buf->getHandle(); + DRW_DBG("ViewPort ent header: "); DRW_DBGHL(someHdl.code, someHdl.size, someHdl.ref); DRW_DBG("\n"); + } + someHdl = buf->getHandle(); + DRW_DBG("Named ucs handle: "); DRW_DBGHL(someHdl.code, someHdl.size, someHdl.ref); DRW_DBG("\n"); + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + someHdl = buf->getHandle(); + DRW_DBG("base ucs handle: "); DRW_DBGHL(someHdl.code, someHdl.size, someHdl.ref); DRW_DBG("\n"); + } + if (version > DRW::AC1018) {//2007+ + someHdl = buf->getHandle(); + DRW_DBG("background handle: "); DRW_DBGHL(someHdl.code, someHdl.size, someHdl.ref); DRW_DBG("\n"); + someHdl = buf->getHandle(); + DRW_DBG("visual style handle: "); DRW_DBGHL(someHdl.code, someHdl.size, someHdl.ref); DRW_DBG("\n"); + someHdl = buf->getHandle(); + DRW_DBG("shadeplot ID handle: "); DRW_DBGHL(someHdl.code, someHdl.size, someHdl.ref); DRW_DBG("\n"); + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + someHdl = buf->getHandle(); + DRW_DBG("SUN handle: "); DRW_DBGHL(someHdl.code, someHdl.size, someHdl.ref); DRW_DBG("\n"); + } + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + + if (!ret) + return ret; + return buf->isGood(); +} diff --git a/extlib/libdxfrw/drw_entities.h b/extlib/libdxfrw/drw_entities.h new file mode 100644 index 0000000..ba98527 --- /dev/null +++ b/extlib/libdxfrw/drw_entities.h @@ -0,0 +1,1572 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DRW_ENTITIES_H +#define DRW_ENTITIES_H + + +#include +#include +#include +#include "drw_base.h" + +class dxfReader; +class dwgBuffer; +class DRW_Polyline; + +namespace DRW { + + //! Entity's type. + enum ETYPE { + E3DFACE, +// E3DSOLID, //encripted propietry data +// ACAD_PROXY_ENTITY, + ARC, +// ATTDEF, +// ATTRIB, + BLOCK,// and ENDBLK +// BODY, //encripted propietry data + CIRCLE, + DIMENSION, + DIMALIGNED, + DIMLINEAR, + DIMRADIAL, + DIMDIAMETRIC, + DIMANGULAR, + DIMANGULAR3P, + DIMORDINATE, + ELLIPSE, + HATCH, +// HELIX, + IMAGE, + INSERT, + LEADER, +// LIGHT, + LINE, + LWPOLYLINE, +// MESH, +// MLINE, +// MLEADERSTYLE, +// MLEADER, + MTEXT, +// OLEFRAME, +// OLE2FRAME, + POINT, + POLYLINE, + RAY, +// REGION, //encripted propietry data +// SECTION, +// SEQEND,//not needed?? used in polyline and insert/attrib and dwg +// SHAPE, + SOLID, + SPLINE, +// SUN, +// SURFACE, //encripted propietry data can be four types +// TABLE, + TEXT, +// TOLERANCE, + TRACE, + UNDERLAY, + VERTEX, + VIEWPORT, +// WIPEOUT, //WIPEOUTVARIABLE + XLINE, + UNKNOWN + }; + +} +//only in DWG: MINSERT, 5 types of vertex, 4 types of polylines: 2d, 3d, pface & mesh +//shape, dictionary, MLEADER, MLEADERSTYLE + +#define SETENTFRIENDS friend class dxfRW; \ + friend class dwgReader; + +//! Base class for entities +/*! +* Base class for entities +* @author Rallaz +*/ +class DRW_Entity { + SETENTFRIENDS +public: + //initializes default values + DRW_Entity() { + eType = DRW::UNKNOWN; + handle = parentHandle = DRW::NoHandle; //no handle (0) + lineType = "BYLAYER"; + color = DRW::ColorByLayer; // default BYLAYER (256) + ltypeScale = 1.0; + visible = true; + layer = "0"; + lWeight = DRW_LW_Conv::widthByLayer; // default BYLAYER (dxf -1, dwg 29) + space = DRW::ModelSpace; // default ModelSpace (0) + haveExtrusion = false; + color24 = -1; //default -1 not set + numProxyGraph = 0; + shadow = DRW::CastAndReceieveShadows; + material = DRW::MaterialByLayer; + plotStyle = DRW::DefaultPlotStyle; + transparency = DRW::Opaque; + nextEntLink = prevEntLink = 0; + numReactors = xDictFlag = 0; + curr = NULL; + ownerHandle= false; + } + + DRW_Entity(const DRW_Entity& e) { + eType = e.eType; + handle = e.handle; + parentHandle = e.parentHandle; //no handle (0) + lineType = e.lineType; + color = e.color; // default BYLAYER (256) + ltypeScale = e.ltypeScale; + visible = e.visible; + layer = e.layer; + lWeight = e.lWeight; + space = e.space; + haveExtrusion = e.haveExtrusion; + color24 = e.color24; //default -1 not set + numProxyGraph = e.numProxyGraph; + shadow = e.shadow; + material = e.material; + plotStyle = e.plotStyle; + transparency = e.transparency; + nextEntLink = e.nextEntLink; + prevEntLink = e.prevEntLink; + numReactors = e.numReactors; + xDictFlag = e.xDictFlag; + curr = NULL; + ownerHandle= false; +// curr = e.curr; + for (std::vector::const_iterator it=e.extData.begin(); it!=e.extData.end(); ++it){ + extData.push_back(new DRW_Variant(*(*it))); + } + } + + virtual ~DRW_Entity() { + for (std::vector::iterator it=extData.begin(); it!=extData.end(); ++it) + delete *it; + + extData.clear(); + } + + void reset(){ + for (std::vector::iterator it=extData.begin(); it!=extData.end(); ++it) + delete *it; + extData.clear(); + } + + virtual void applyExtrusion() = 0; + + void setWidthMm(double millimeters) { + if(millimeters < 0.0) { + lWeight = DRW_LW_Conv::widthByLayer; + return; + } + if(millimeters > 2.11) millimeters = 2.11; + lWeight = DRW_LW_Conv::dxfInt2lineWidth(int(floor(millimeters * 100.0))); + } + +protected: + //parses dxf pair to read entity + bool parseCode(int code, dxfReader *reader); + //calculates extrusion axis (normal vector) + void calculateAxis(DRW_Coord extPoint); + //apply extrusion to @extPoint and return data in @point + void extrudePoint(DRW_Coord extPoint, DRW_Coord *point); + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0)=0; + //parses dwg common start part to read entity + bool parseDwg(DRW::Version version, dwgBuffer *buf, dwgBuffer* strBuf, duint32 bs=0); + //parses dwg common handles part to read entity + bool parseDwgEntHandle(DRW::Version version, dwgBuffer *buf); + + //parses dxf 102 groups to read entity + bool parseDxfGroups(int code, dxfReader *reader); + +public: + enum DRW::ETYPE eType; /*!< enum: entity type, code 0 */ + duint32 handle; /*!< entity identifier, code 5 */ + std::list > appData; /*!< list of application data, code 102 */ + duint32 parentHandle; /*!< Soft-pointer ID/handle to owner BLOCK_RECORD object, code 330 */ + DRW::Space space; /*!< space indicator, code 67*/ + UTF8STRING layer; /*!< layer name, code 8 */ + UTF8STRING lineType; /*!< line type, code 6 */ + duint32 material; /*!< hard pointer id to material object, code 347 */ + int color; /*!< entity color, code 62 */ + enum DRW_LW_Conv::lineWidth lWeight; /*!< entity lineweight, code 370 */ + double ltypeScale; /*!< linetype scale, code 48 */ + bool visible; /*!< entity visibility, code 60 */ + int numProxyGraph; /*!< Number of bytes in proxy graphics, code 92 */ + std::string proxyGraphics; /*!< proxy graphics bytes, code 310 */ + int color24; /*!< 24-bit color, code 420 */ + std::string colorName; /*!< color name, code 430 */ + int transparency; /*!< transparency, code 440 */ + int plotStyle; /*!< hard pointer id to plot style object, code 390 */ + DRW::ShadowMode shadow; /*!< shadow mode, code 284 */ + bool haveExtrusion; /*!< set to true if the entity have extrusion*/ + std::vector extData; /*!< FIFO list of extended data, codes 1000 to 1071*/ + +protected: //only for read dwg + duint8 haveNextLinks; //aka nolinks //B + duint8 plotFlags; //presence of plot style //BB + duint8 ltFlags; //presence of linetype handle //BB + duint8 materialFlag; //presence of material handle //BB + duint8 shadowFlag; //presence of shadow handle ?? (in dwg may be plotflag)//RC + dwgHandle lTypeH; + dwgHandle layerH; + duint32 nextEntLink; + duint32 prevEntLink; + bool ownerHandle; + + duint8 xDictFlag; + dint32 numReactors; // + duint32 objSize; //RL 32bits object data size in bits + dint16 oType; + +private: + DRW_Coord extAxisX; + DRW_Coord extAxisY; + DRW_Variant* curr; +}; + + +//! Class to handle point entity +/*! +* Class to handle point entity +* @author Rallaz +*/ +class DRW_Point : public DRW_Entity { + SETENTFRIENDS +public: + DRW_Point() { + eType = DRW::POINT; + basePoint.z = extPoint.x = extPoint.y = 0; + extPoint.z = 1; + thickness = 0; + } + + virtual void applyExtrusion(){} + +protected: + void parseCode(int code, dxfReader *reader); + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: + DRW_Coord basePoint; /*!< base point, code 10, 20 & 30 */ + double thickness; /*!< thickness, code 39 */ + DRW_Coord extPoint; /*!< Dir extrusion normal vector, code 210, 220 & 230 */ + // TNick: we're not handling code 50 - Angle of the X axis for + // the UCS in effect when the point was drawn +}; + +//! Class to handle line entity +/*! +* Class to handle line entity +* @author Rallaz +*/ +class DRW_Line : public DRW_Point { + SETENTFRIENDS +public: + DRW_Line() { + eType = DRW::LINE; + secPoint.z = 0; + } + + virtual void applyExtrusion(){} + +protected: + void parseCode(int code, dxfReader *reader); + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: + DRW_Coord secPoint; /*!< second point, code 11, 21 & 31 */ +}; + +//! Class to handle ray entity +/*! +* Class to handle ray entity +* @author Rallaz +*/ +class DRW_Ray : public DRW_Line { + SETENTFRIENDS +public: + DRW_Ray() { + eType = DRW::RAY; + } +protected: + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); +}; + +//! Class to handle xline entity +/*! +* Class to handle xline entity +* @author Rallaz +*/ +class DRW_Xline : public DRW_Ray { +public: + DRW_Xline() { + eType = DRW::XLINE; + } +}; + +//! Class to handle circle entity +/*! +* Class to handle circle entity +* @author Rallaz +*/ +class DRW_Circle : public DRW_Point { + SETENTFRIENDS +public: + DRW_Circle() { + eType = DRW::CIRCLE; + } + + virtual void applyExtrusion(); + +protected: + void parseCode(int code, dxfReader *reader); + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: + double radious; /*!< radius, code 40 */ +}; + +//! Class to handle arc entity +/*! +* Class to handle arc entity +* @author Rallaz +*/ +class DRW_Arc : public DRW_Circle { + SETENTFRIENDS +public: + DRW_Arc() { + eType = DRW::ARC; + isccw = 1; + } + + virtual void applyExtrusion(); + + //! center point in OCS + const DRW_Coord & center() { return basePoint; } + //! the radius of the circle + double radius() { return radious; } + //! start angle in radians + double startAngle() { return staangle; } + //! end angle in radians + double endAngle() { return endangle; } + //! thickness + double thick() { return thickness; } + //! extrusion + const DRW_Coord & extrusion() { return extPoint; } + +protected: + //! interpret code in dxf reading process or dispatch to inherited class + void parseCode(int code, dxfReader *reader); + //! interpret dwg data (was already determined to be part of this object) + virtual bool parseDwg(DRW::Version v, dwgBuffer *buf, duint32 bs=0); + +public: + double staangle; /*!< start angle, code 50 in radians*/ + double endangle; /*!< end angle, code 51 in radians */ + int isccw; /*!< is counter clockwise arc?, only used in hatch, code 73 */ +}; + +//! Class to handle ellipse entity +/*! +* Class to handle ellipse and elliptic arc entity +* Note: start/end parameter are in radians for ellipse entity but +* for hatch boundary are in degrees +* @author Rallaz +*/ +class DRW_Ellipse : public DRW_Line { + SETENTFRIENDS +public: + DRW_Ellipse() { + eType = DRW::ELLIPSE; + isccw = 1; + } + + void toPolyline(DRW_Polyline *pol, int parts = 128); + virtual void applyExtrusion(); + +protected: + //! interpret code in dxf reading process or dispatch to inherited class + void parseCode(int code, dxfReader *reader); + //! interpret dwg data (was already determined to be part of this object) + virtual bool parseDwg(DRW::Version v, dwgBuffer *buf, duint32 bs=0); + +private: + void correctAxis(); + +public: + double ratio; /*!< ratio, code 40 */ + double staparam; /*!< start parameter, code 41, 0.0 for full ellipse*/ + double endparam; /*!< end parameter, code 42, 2*PI for full ellipse */ + int isccw; /*!< is counter clockwise arc?, only used in hatch, code 73 */ +}; + +//! Class to handle trace entity +/*! +* Class to handle trace entity +* @author Rallaz +*/ +class DRW_Trace : public DRW_Line { + SETENTFRIENDS +public: + DRW_Trace() { + eType = DRW::TRACE; + thirdPoint.z = 0; + fourPoint.z = 0; + } + + virtual void applyExtrusion(); + +protected: + void parseCode(int code, dxfReader *reader); + virtual bool parseDwg(DRW::Version v, dwgBuffer *buf, duint32 bs=0); + +public: + DRW_Coord thirdPoint; /*!< third point, code 12, 22 & 32 */ + DRW_Coord fourPoint; /*!< four point, code 13, 23 & 33 */ +}; + +//! Class to handle solid entity +/*! +* Class to handle solid entity +* @author Rallaz +*/ +class DRW_Solid : public DRW_Trace { + SETENTFRIENDS +public: + DRW_Solid() { + eType = DRW::SOLID; + } + +protected: + //! interpret code in dxf reading process or dispatch to inherited class + void parseCode(int code, dxfReader *reader); + //! interpret dwg data (was already determined to be part of this object) + virtual bool parseDwg(DRW::Version v, dwgBuffer *buf, duint32 bs=0); + +public: + //! first corner (2D) + const DRW_Coord & firstCorner() { return basePoint; } + //! second corner (2D) + const DRW_Coord & secondCorner() { return secPoint; } + //! third corner (2D) + const DRW_Coord & thirdCorner() { return thirdPoint; } + //! fourth corner (2D) + const DRW_Coord & fourthCorner() { return thirdPoint; } + //! thickness + double thick() { return thickness; } + //! elevation + double elevation() { return basePoint.z; } + //! extrusion + const DRW_Coord & extrusion() { return extPoint; } + +}; + +//! Class to handle 3dface entity +/*! +* Class to handle 3dface entity +* @author Rallaz +*/ +class DRW_3Dface : public DRW_Trace { + SETENTFRIENDS +public: + enum InvisibleEdgeFlags { + NoEdge = 0x00, + FirstEdge = 0x01, + SecodEdge = 0x02, + ThirdEdge = 0x04, + FourthEdge = 0x08, + AllEdges = 0x0F + }; + + DRW_3Dface() { + eType = DRW::E3DFACE; + invisibleflag = 0; + } + + virtual void applyExtrusion(){} + + //! first corner in WCS + const DRW_Coord & firstCorner() { return basePoint; } + //! second corner in WCS + const DRW_Coord & secondCorner() { return secPoint; } + //! third corner in WCS + const DRW_Coord & thirdCorner() { return thirdPoint; } + //! fourth corner in WCS + const DRW_Coord & fourthCorner() { return fourPoint; } + //! edge visibility flags + InvisibleEdgeFlags edgeFlags() { return (InvisibleEdgeFlags)invisibleflag; } + +protected: + //! interpret code in dxf reading process or dispatch to inherited class + void parseCode(int code, dxfReader *reader); + //! interpret dwg data (was already determined to be part of this object) + virtual bool parseDwg(DRW::Version v, dwgBuffer *buf, duint32 bs=0); + +public: + int invisibleflag; /*!< invisible edge flag, code 70 */ + +}; + +//! Class to handle block entries +/*! +* Class to handle block entries +* @author Rallaz +*/ +class DRW_Block : public DRW_Point { + SETENTFRIENDS +public: + DRW_Block() { + eType = DRW::BLOCK; + layer = "0"; + flags = 0; + name = "*U0"; + isEnd = false; + } + + virtual void applyExtrusion(){} + +protected: + void parseCode(int code, dxfReader *reader); + virtual bool parseDwg(DRW::Version v, dwgBuffer *buf, duint32 bs=0); + +public: + UTF8STRING name; /*!< block name, code 2 */ + int flags; /*!< block type, code 70 */ +private: + bool isEnd; //for dwg parsing +}; + + +//! Class to handle insert entries +/*! +* Class to handle insert entries +* @author Rallaz +*/ +class DRW_Insert : public DRW_Point { + SETENTFRIENDS +public: + DRW_Insert() { + eType = DRW::INSERT; + xscale = 1; + yscale = 1; + zscale = 1; + angle = 0; + colcount = 1; + rowcount = 1; + colspace = 0; + rowspace = 0; + } + + virtual void applyExtrusion(){DRW_Point::applyExtrusion();} + +protected: + void parseCode(int code, dxfReader *reader); + virtual bool parseDwg(DRW::Version v, dwgBuffer *buf, duint32 bs=0); + +public: + UTF8STRING name; /*!< block name, code 2 */ + double xscale; /*!< x scale factor, code 41 */ + double yscale; /*!< y scale factor, code 42 */ + double zscale; /*!< z scale factor, code 43 */ + double angle; /*!< rotation angle in radians, code 50 */ + int colcount; /*!< column count, code 70 */ + int rowcount; /*!< row count, code 71 */ + double colspace; /*!< column space, code 44 */ + double rowspace; /*!< row space, code 45 */ +public: //only for read dwg + dwgHandle blockRecH; + dwgHandle seqendH; //RLZ: on implement attrib remove this handle from obj list (see pline/vertex code) +}; + +//! Class to handle lwpolyline entity +/*! +* Class to handle lwpolyline entity +* @author Rallaz +*/ +class DRW_LWPolyline : public DRW_Entity { + SETENTFRIENDS +public: + DRW_LWPolyline() { + eType = DRW::LWPOLYLINE; + elevation = thickness = width = 0.0; + flags = 0; + extPoint.x = extPoint.y = 0; + extPoint.z = 1; + vertex = NULL; + } + + DRW_LWPolyline(const DRW_LWPolyline& p):DRW_Entity(p){ + this->eType = DRW::LWPOLYLINE; + this->elevation = p.elevation; + this->thickness = p.thickness; + this->width = p.width; + this->flags = p.flags; + this->extPoint = p.extPoint; + this->vertex = NULL; + for (unsigned i=0; ivertlist.push_back( new DRW_Vertex2D( *(p.vertlist.at(i)) ) ); + + this->vertex = NULL; + } + + ~DRW_LWPolyline() { + for(DRW_Vertex2D *item : vertlist) delete item; + } + virtual void applyExtrusion(); + void addVertex (DRW_Vertex2D v) { + DRW_Vertex2D *vert = new DRW_Vertex2D(); + vert->x = v.x; + vert->y = v.y; + vert->stawidth = v.stawidth; + vert->endwidth = v.endwidth; + vert->bulge = v.bulge; + vertlist.push_back(vert); + } + DRW_Vertex2D *addVertex () { + DRW_Vertex2D *vert = new DRW_Vertex2D(); + vert->stawidth = 0; + vert->endwidth = 0; + vert->bulge = 0; + vertlist.push_back(vert); + return vert; + } + +protected: + void parseCode(int code, dxfReader *reader); + bool parseDwg(DRW::Version v, dwgBuffer *buf, duint32 bs=0); + +public: + int vertexnum; /*!< number of vertex, code 90 */ + int flags; /*!< polyline flag, code 70, default 0 */ + double width; /*!< constant width, code 43 */ + double elevation; /*!< elevation, code 38 */ + double thickness; /*!< thickness, code 39 */ + DRW_Coord extPoint; /*!< Dir extrusion normal vector, code 210, 220 & 230 */ + DRW_Vertex2D *vertex; /*!< current vertex to add data */ + std::vector vertlist; /*!< vertex list */ +}; + +//! Class to handle insert entries +/*! +* Class to handle insert entries +* @author Rallaz +*/ +class DRW_Text : public DRW_Line { + SETENTFRIENDS +public: + //! Vertical alignments. + enum VAlign { + VBaseLine = 0, /*!< Top = 0 */ + VBottom, /*!< Bottom = 1 */ + VMiddle, /*!< Middle = 2 */ + VTop /*!< Top = 3 */ + }; + + //! Horizontal alignments. + enum HAlign { + HLeft = 0, /*!< Left = 0 */ + HCenter, /*!< Centered = 1 */ + HRight, /*!< Right = 2 */ + HAligned, /*!< Aligned = 3 (if VAlign==0) */ + HMiddle, /*!< middle = 4 (if VAlign==0) */ + HFit /*!< fit into point = 5 (if VAlign==0) */ + }; + + DRW_Text() { + eType = DRW::TEXT; + angle = 0; + widthscale = 1; + oblique = 0; + style = "STANDARD"; + textgen = 0; + alignH = HLeft; + alignV = VBaseLine; + } + + virtual void applyExtrusion(){} //RLZ TODO + +protected: + void parseCode(int code, dxfReader *reader); + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: + double height; /*!< height text, code 40 */ + UTF8STRING text; /*!< text string, code 1 */ + double angle; /*!< rotation angle in degrees (360), code 50 */ + double widthscale; /*!< width factor, code 41 */ + double oblique; /*!< oblique angle, code 51 */ + UTF8STRING style; /*!< style name, code 7 */ + int textgen; /*!< text generation, code 71 */ + enum HAlign alignH; /*!< horizontal align, code 72 */ + enum VAlign alignV; /*!< vertical align, code 73 */ + dwgHandle styleH; /*!< handle for text style */ +}; + +//! Class to handle insert entries +/*! +* Class to handle insert entries +* @author Rallaz +*/ +class DRW_MText : public DRW_Text { + SETENTFRIENDS +public: + //! Attachments. + enum Attach { + TopLeft = 1, + TopCenter, + TopRight, + MiddleLeft, + MiddleCenter, + MiddleRight, + BottomLeft, + BottomCenter, + BottomRight + }; + + DRW_MText() { + eType = DRW::MTEXT; + interlin = 1; + alignV = (VAlign)TopLeft; + textgen = 1; + haveXAxis = false; //if true needed to recalculate angle + } + +protected: + void parseCode(int code, dxfReader *reader); + void updateAngle(); //recalculate angle if 'haveXAxis' is true + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: + double interlin; /*!< width factor, code 44 */ +private: + bool haveXAxis; +}; + +//! Class to handle vertex +/*! +* Class to handle vertex for polyline entity +* @author Rallaz +*/ +class DRW_Vertex : public DRW_Point { + SETENTFRIENDS +public: + DRW_Vertex() { + eType = DRW::VERTEX; + stawidth = endwidth = bulge = 0; + vindex1 = vindex2 = vindex3 = vindex4 = 0; + flags = identifier = 0; + } + DRW_Vertex(double sx, double sy, double sz, double b) { + stawidth = endwidth = 0; + vindex1 = vindex2 = vindex3 = vindex4 = 0; + flags = identifier = 0; + basePoint.x = sx; + basePoint.y =sy; + basePoint.z =sz; + bulge = b; + } + +protected: + void parseCode(int code, dxfReader *reader); + bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0, double el=0); + virtual bool parseDwg(DRW::Version version, dwgBuffer* buf, duint32 bs=0){ + DRW_UNUSED(version); DRW_UNUSED(buf); DRW_UNUSED(bs); return true;} + +public: + double stawidth; /*!< Start width, code 40 */ + double endwidth; /*!< End width, code 41 */ + double bulge; /*!< bulge, code 42 */ + + int flags; /*!< vertex flag, code 70, default 0 */ + double tgdir; /*!< curve fit tangent direction, code 50 */ + int vindex1; /*!< polyface mesh vertex index, code 71, default 0 */ + int vindex2; /*!< polyface mesh vertex index, code 72, default 0 */ + int vindex3; /*!< polyface mesh vertex index, code 73, default 0 */ + int vindex4; /*!< polyface mesh vertex index, code 74, default 0 */ + int identifier; /*!< vertex identifier, code 91, default 0 */ +}; + +//! Class to handle polyline entity +/*! +* Class to handle polyline entity +* @author Rallaz +*/ +class DRW_Polyline : public DRW_Point { + SETENTFRIENDS +public: + DRW_Polyline() { + eType = DRW::POLYLINE; + defstawidth = defendwidth = 0.0; + basePoint.x = basePoint.y = 0.0; + flags = vertexcount = facecount = 0; + smoothM = smoothN = curvetype = 0; + } + + DRW_Polyline(const DRW_Polyline& p) : DRW_Point(p) { + flags = p.flags ; + defstawidth = p.defstawidth; + defendwidth = p.defendwidth; + vertexcount = p.vertexcount; + facecount = p.facecount ; + smoothM = p.smoothM ; + smoothN = p.smoothN ; + curvetype = p.curvetype ; + for (unsigned i=0; ivertlist.push_back( new DRW_Vertex( *(p.vertlist.at(i)) ) ); + } + + ~DRW_Polyline() { + for(DRW_Vertex *item : vertlist) delete item; + } + void addVertex (DRW_Vertex v) { + DRW_Vertex *vert = new DRW_Vertex(); + vert->basePoint.x = v.basePoint.x; + vert->basePoint.y = v.basePoint.y; + vert->basePoint.z = v.basePoint.z; + vert->stawidth = v.stawidth; + vert->endwidth = v.endwidth; + vert->bulge = v.bulge; + vertlist.push_back(vert); + } + void appendVertex (DRW_Vertex *v) { + vertlist.push_back(v); + } + +protected: + void parseCode(int code, dxfReader *reader); + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: + int flags; /*!< polyline flag, code 70, default 0 */ + double defstawidth; /*!< Start width, code 40, default 0 */ + double defendwidth; /*!< End width, code 41, default 0 */ + int vertexcount; /*!< polygon mesh M vertex or polyface vertex num, code 71, default 0 */ + int facecount; /*!< polygon mesh N vertex or polyface face num, code 72, default 0 */ + int smoothM; /*!< smooth surface M density, code 73, default 0 */ + int smoothN; /*!< smooth surface M density, code 74, default 0 */ + int curvetype; /*!< curves & smooth surface type, code 75, default 0 */ + + std::vector vertlist; /*!< vertex list */ + +private: + std::listhadlesList; //list of handles, only in 2004+ + duint32 firstEH; //handle of first entity, only in pre-2004 + duint32 lastEH; //handle of last entity, only in pre-2004 + dwgHandle seqEndH; //handle of SEQEND entity +}; + + +//! Class to handle spline entity +/*! +* Class to handle spline entity +* @author Rallaz +*/ +class DRW_Spline : public DRW_Entity { + SETENTFRIENDS +public: + DRW_Spline() { + eType = DRW::SPLINE; + flags = nknots = ncontrol = nfit = 0; + tolknot = tolcontrol = tolfit = 0.0000001; + + } + + DRW_Spline(const DRW_Spline& p):DRW_Entity(p){ + eType = DRW::SPLINE; + normalVec = p.normalVec ; + tgStart = p.tgStart ; + tgEnd = p.tgEnd ; + flags = p.flags ; + degree = p.degree ; + nknots = p.nknots ; + ncontrol = p.ncontrol ; + nfit = p.nfit ; + tolknot = p.tolknot ; + tolcontrol = p.tolcontrol; + tolfit = p.tolfit ; + + for(double v : p.knotslist) knotslist.push_back(v); + for(double v : p.weightlist) weightlist.push_back(v); + for(DRW_Coord *v : p.controllist) controllist.push_back(new DRW_Coord(*v)); + for(DRW_Coord *v : p.fitlist) fitlist.push_back(new DRW_Coord(*v)); + } + + ~DRW_Spline() { + for(DRW_Coord *item : controllist) delete item; + for(DRW_Coord *item : fitlist) delete item; + } + virtual void applyExtrusion(){} + +protected: + void parseCode(int code, dxfReader *reader); + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: +// double ex; /*!< normal vector x coordinate, code 210 */ +// double ey; /*!< normal vector y coordinate, code 220 */ +// double ez; /*!< normal vector z coordinate, code 230 */ + DRW_Coord normalVec; /*!< normal vector, code 210, 220, 230 */ + DRW_Coord tgStart; /*!< start tangent, code 12, 22, 32 */ +// double tgsx; /*!< start tangent x coordinate, code 12 */ +// double tgsy; /*!< start tangent y coordinate, code 22 */ +// double tgsz; /*!< start tangent z coordinate, code 32 */ + DRW_Coord tgEnd; /*!< end tangent, code 13, 23, 33 */ +// double tgex; /*!< end tangent x coordinate, code 13 */ +// double tgey; /*!< end tangent y coordinate, code 23 */ +// double tgez; /*!< end tangent z coordinate, code 33 */ + int flags; /*!< spline flag, code 70 */ + int degree; /*!< degree of the spline, code 71 */ + dint32 nknots; /*!< number of knots, code 72, default 0 */ + dint32 ncontrol; /*!< number of control points, code 73, default 0 */ + dint32 nfit; /*!< number of fit points, code 74, default 0 */ + double tolknot; /*!< knot tolerance, code 42, default 0.0000001 */ + double tolcontrol; /*!< control point tolerance, code 43, default 0.0000001 */ + double tolfit; /*!< fit point tolerance, code 44, default 0.0000001 */ + + std::vector knotslist; /*!< knots list, code 40 */ + std::vector weightlist; /*!< weight list, code 41 */ + std::vector controllist; /*!< control points list, code 10, 20 & 30 */ + std::vector fitlist; /*!< fit points list, code 11, 21 & 31 */ + +private: + DRW_Coord *controlpoint; /*!< current control point to add data */ + DRW_Coord *fitpoint; /*!< current fit point to add data */ +}; + +//! Class to handle hatch loop +/*! +* Class to handle hatch loop +* @author Rallaz +*/ +class DRW_HatchLoop { +public: + DRW_HatchLoop(int t) { + type = t; + numedges = 0; + } + + ~DRW_HatchLoop() { + // for(DRW_LWPolyline *item : pollist) delete item; + for(DRW_Entity *item : objlist) delete item; + } + + void update() { + numedges = (int)objlist.size(); + } + +public: + int type; /*!< boundary path type, code 92, polyline=2, default=0 */ + int numedges; /*!< number of edges (if not a polyline), code 93 */ +//TODO: store lwpolylines as entities +// std::vector pollist; /*!< polyline list */ + std::vector objlist; /*!< entities list */ +}; + +//! Class to handle hatch entity +/*! +* Class to handle hatch entity +* @author Rallaz +*/ +//TODO: handle lwpolylines, splines and ellipses +class DRW_Hatch : public DRW_Point { + SETENTFRIENDS +public: + DRW_Hatch() { + eType = DRW::HATCH; + angle = scale = 0.0; + basePoint.x = basePoint.y = basePoint.z = 0.0; + loopsnum = hstyle = associative = 0; + solid = hpattern = 1; + deflines = doubleflag = 0; + loop = NULL; + clearEntities(); + } + + ~DRW_Hatch() { + for(DRW_HatchLoop *item : looplist) delete item; + } + + void appendLoop (DRW_HatchLoop *v) { + looplist.push_back(v); + } + + virtual void applyExtrusion(){} + +protected: + void parseCode(int code, dxfReader *reader); + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: + UTF8STRING name; /*!< hatch pattern name, code 2 */ + int solid; /*!< solid fill flag, code 70, solid=1, pattern=0 */ + int associative; /*!< associativity, code 71, associatve=1, non-assoc.=0 */ + int hstyle; /*!< hatch style, code 75 */ + int hpattern; /*!< hatch pattern type, code 76 */ + int doubleflag; /*!< hatch pattern double flag, code 77, double=1, single=0 */ + int loopsnum; /*!< namber of boundary paths (loops), code 91 */ + double angle; /*!< hatch pattern angle, code 52 */ + double scale; /*!< hatch pattern scale, code 41 */ + int deflines; /*!< number of pattern definition lines, code 78 */ + + std::vector looplist; /*!< polyline list */ + +private: + void clearEntities(){ + pt = line = NULL; + pline = NULL; + arc = NULL; + ellipse = NULL; + spline = NULL; + plvert = NULL; + } + + void addLine() { + clearEntities(); + if (loop) { + pt = line = new DRW_Line; + loop->objlist.push_back(line); + } + } + + void addArc() { + clearEntities(); + if (loop) { + pt = arc = new DRW_Arc; + loop->objlist.push_back(arc); + } + } + + void addEllipse() { + clearEntities(); + if (loop) { + pt = ellipse = new DRW_Ellipse; + loop->objlist.push_back(ellipse); + } + } + + void addSpline() { + clearEntities(); + if (loop) { + pt = NULL; + spline = new DRW_Spline; + loop->objlist.push_back(spline); + } + } + + DRW_HatchLoop *loop; /*!< current loop to add data */ + DRW_Line *line; + DRW_Arc *arc; + DRW_Ellipse *ellipse; + DRW_Spline *spline; + DRW_LWPolyline *pline; + DRW_Point *pt; + DRW_Vertex2D *plvert; + bool ispol; +}; + +//! Class to handle image entity +/*! +* Class to handle image entity +* @author Rallaz +*/ +class DRW_Image : public DRW_Line { + SETENTFRIENDS +public: + DRW_Image() { + eType = DRW::IMAGE; + fade = clip = 0; + brightness = contrast = 50; + } + +protected: + void parseCode(int code, dxfReader *reader); + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: + duint32 ref; /*!< Hard reference to imagedef object, code 340 */ + DRW_Coord vVector; /*!< V-vector of single pixel, x coordinate, code 12, 22 & 32 */ +// double vx; /*!< V-vector of single pixel, x coordinate, code 12 */ +// double vy; /*!< V-vector of single pixel, y coordinate, code 22 */ +// double vz; /*!< V-vector of single pixel, z coordinate, code 32 */ + double sizeu; /*!< image size in pixels, U value, code 13 */ + double sizev; /*!< image size in pixels, V value, code 23 */ + double dz; /*!< z coordinate, code 33 */ + int clip; /*!< Clipping state, code 280, 0=off 1=on */ + int brightness; /*!< Brightness value, code 281, (0-100) default 50 */ + int contrast; /*!< Brightness value, code 282, (0-100) default 50 */ + int fade; /*!< Brightness value, code 283, (0-100) default 0 */ + +}; + + +//! Base class for dimension entity +/*! +* Base class for dimension entity +* @author Rallaz +*/ +class DRW_Dimension : public DRW_Entity { + SETENTFRIENDS +public: + DRW_Dimension() { + eType = DRW::DIMENSION; + type = 0; + linesty = 1; + linefactor = extPoint.z = 1.0; + angle = oblique = rot = 0.0; + align = 5; + style = "STANDARD"; + defPoint.z = extPoint.x = extPoint.y = 0; + textPoint.z = rot = 0; + clonePoint.x = clonePoint.y = clonePoint.z = 0; + length = 0.0; + hasActual = false; + actual = 0.0; + } + + DRW_Dimension(const DRW_Dimension& d): DRW_Entity(d) { + eType = DRW::DIMENSION; + type =d.type; + name = d.name; + defPoint = d.defPoint; + textPoint = d.textPoint; + text = d.text; + style = d.style; + align = d.align; + linesty = d.linesty; + linefactor = d.linefactor; + rot = d.rot; + extPoint = d.extPoint; + clonePoint = d.clonePoint; + def1 = d.def1; + def2 = d.def2; + angle = d.angle; + oblique = d.oblique; + arcPoint = d.arcPoint; + circlePoint = d.circlePoint; + length = d.length; + hasActual = d.hasActual; + actual = d.actual; + //RLZ needed a def value for this: hdir = ??? + } + virtual ~DRW_Dimension() {} + + virtual void applyExtrusion(){} + +protected: + void parseCode(int code, dxfReader *reader); + bool parseDwg(DRW::Version version, dwgBuffer *buf, dwgBuffer *sBuf); + virtual bool parseDwg(DRW::Version version, dwgBuffer* buf, duint32 bs=0){ + DRW_UNUSED(version); DRW_UNUSED(buf); DRW_UNUSED(bs); return true;} + +public: + DRW_Coord getDefPoint() const {return defPoint;} /*!< Definition point, code 10, 20 & 30 */ + void setDefPoint(const DRW_Coord p) {defPoint =p;} + DRW_Coord getTextPoint() const {return textPoint;} /*!< Middle point of text, code 11, 21 & 31 */ + void setTextPoint(const DRW_Coord p) {textPoint =p;} + std::string getStyle() const {return style;} /*!< Dimension style, code 3 */ + void setStyle(const std::string s) {style = s;} + int getAlign() const { return align;} /*!< attachment point, code 71 */ + void setAlign(const int a) { align = a;} + int getTextLineStyle() const { return linesty;} /*!< Dimension text line spacing style, code 72, default 1 */ + void setTextLineStyle(const int l) { linesty = l;} + std::string getText() const {return text;} /*!< Dimension text explicitly entered by the user, code 1 */ + void setText(const std::string t) {text = t;} + double getTextLineFactor() const { return linefactor;} /*!< Dimension text line spacing factor, code 41, default 1? */ + void setTextLineFactor(const double l) { linefactor = l;} + double getDir() const { return rot;} /*!< rotation angle of the dimension text, code 53 (optional) default 0 */ + void setDir(const double d) { rot = d;} + + DRW_Coord getExtrusion() const {return extPoint;} /*!< extrusion, code 210, 220 & 230 */ + void setExtrusion(const DRW_Coord p) {extPoint =p;} + std::string getName() const {return name;} /*!< Name of the block that contains the entities, code 2 */ + void setName(const std::string s) {name = s;} +// int getType(){ return type;} /*!< Dimension type, code 70 */ + bool hasActualMeasurement() const { return hasActual; } + void setActualMeasurement(double value) { hasActual = true; actual = value; } + double getActualMeasurement() const { return actual; } + +protected: + DRW_Coord getPt2() const {return clonePoint;} + void setPt2(const DRW_Coord p) {clonePoint= p;} + DRW_Coord getPt3() const {return def1;} + void setPt3(const DRW_Coord p) {def1= p;} + DRW_Coord getPt4() const {return def2;} + void setPt4(const DRW_Coord p) {def2= p;} + DRW_Coord getPt5() const {return circlePoint;} + void setPt5(const DRW_Coord p) {circlePoint= p;} + DRW_Coord getPt6() const {return arcPoint;} + void setPt6(const DRW_Coord p) {arcPoint= p;} + double getAn50() const {return angle;} /*!< Angle of rotated, horizontal, or vertical dimensions, code 50 */ + void setAn50(const double d) {angle = d;} + double getOb52() const {return oblique;} /*!< oblique angle, code 52 */ + void setOb52(const double d) {oblique = d;} + double getRa40() const {return length;} /*!< Leader length, code 40 */ + void setRa40(const double d) {length = d;} +public: + int type; /*!< Dimension type, code 70 */ +private: + std::string name; /*!< Name of the block that contains the entities, code 2 */ + DRW_Coord defPoint; /*!< definition point, code 10, 20 & 30 (WCS) */ + DRW_Coord textPoint; /*!< Middle point of text, code 11, 21 & 31 (OCS) */ + UTF8STRING text; /*!< Dimension text explicitly entered by the user, code 1 */ + UTF8STRING style; /*!< Dimension style, code 3 */ + int align; /*!< attachment point, code 71 */ + int linesty; /*!< Dimension text line spacing style, code 72, default 1 */ + double linefactor; /*!< Dimension text line spacing factor, code 41, default 1? (value range 0.25 to 4.00*/ + double rot; /*!< rotation angle of the dimension text, code 53 */ + DRW_Coord extPoint; /*!< extrusion normal vector, code 210, 220 & 230 */ + + double hdir; /*!< horizontal direction for the dimension, code 51, default ? */ + DRW_Coord clonePoint; /*!< Insertion point for clones (Baseline & Continue), code 12, 22 & 32 (OCS) */ + DRW_Coord def1; /*!< Definition point 1for linear & angular, code 13, 23 & 33 (WCS) */ + DRW_Coord def2; /*!< Definition point 2, code 14, 24 & 34 (WCS) */ + double angle; /*!< Angle of rotated, horizontal, or vertical dimensions, code 50 */ + double oblique; /*!< oblique angle, code 52 */ + + DRW_Coord circlePoint; /*!< Definition point for diameter, radius & angular dims code 15, 25 & 35 (WCS) */ + DRW_Coord arcPoint; /*!< Point defining dimension arc, x coordinate, code 16, 26 & 36 (OCS) */ + double length; /*!< Leader length, code 40 */ + bool hasActual; /*!< Actual measurement has been read, code 42 */ + double actual; /*!< Actual measurement (optional; read-only value), code 42 */ + +protected: + dwgHandle dimStyleH; + dwgHandle blockH; +}; + + +//! Class to handle aligned dimension entity +/*! +* Class to handle aligned dimension entity +* @author Rallaz +*/ +class DRW_DimAligned : public DRW_Dimension { + SETENTFRIENDS +public: + DRW_DimAligned(){ + eType = DRW::DIMALIGNED; + type = 1; + } + DRW_DimAligned(const DRW_Dimension& d): DRW_Dimension(d) { + eType = DRW::DIMALIGNED; + } + + DRW_Coord getClonepoint() const {return getPt2();} /*!< Insertion for clones (Baseline & Continue), 12, 22 & 32 */ + void setClonePoint(DRW_Coord c){setPt2(c);} + + DRW_Coord getDimPoint() const {return getDefPoint();} /*!< dim line location point, code 10, 20 & 30 */ + void setDimPoint(const DRW_Coord p){setDefPoint(p);} + DRW_Coord getDef1Point() const {return getPt3();} /*!< Definition point 1, code 13, 23 & 33 */ + void setDef1Point(const DRW_Coord p) {setPt3(p);} + DRW_Coord getDef2Point() const {return getPt4();} /*!< Definition point 2, code 14, 24 & 34 */ + void setDef2Point(const DRW_Coord p) {setPt4(p);} + +protected: + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); +}; + +//! Class to handle linear or rotated dimension entity +/*! +* Class to handle linear or rotated dimension entity +* @author Rallaz +*/ +class DRW_DimLinear : public DRW_DimAligned { +public: + DRW_DimLinear() { + eType = DRW::DIMLINEAR; + type = 0; + } + DRW_DimLinear(const DRW_Dimension& d): DRW_DimAligned(d) { + eType = DRW::DIMLINEAR; + } + + double getAngle() const {return getAn50();} /*!< Angle of rotated, horizontal, or vertical dimensions, code 50 */ + void setAngle(const double d) {setAn50(d);} + double getOblique() const {return getOb52();} /*!< oblique angle, code 52 */ + void setOblique(const double d) {setOb52(d);} +}; + +//! Class to handle radial dimension entity +/*! +* Class to handle aligned, linear or rotated dimension entity +* @author Rallaz +*/ +class DRW_DimRadial : public DRW_Dimension { + SETENTFRIENDS +public: + DRW_DimRadial() { + eType = DRW::DIMRADIAL; + type = 4; + } + DRW_DimRadial(const DRW_Dimension& d): DRW_Dimension(d) { + eType = DRW::DIMRADIAL; + } + + DRW_Coord getCenterPoint() const {return getDefPoint();} /*!< center point, code 10, 20 & 30 */ + void setCenterPoint(const DRW_Coord p){setDefPoint(p);} + DRW_Coord getDiameterPoint() const {return getPt5();} /*!< Definition point for radius, code 15, 25 & 35 */ + void setDiameterPoint(const DRW_Coord p){setPt5(p);} + double getLeaderLength() const {return getRa40();} /*!< Leader length, code 40 */ + void setLeaderLength(const double d) {setRa40(d);} + +protected: + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); +}; + +//! Class to handle radial dimension entity +/*! +* Class to handle aligned, linear or rotated dimension entity +* @author Rallaz +*/ +class DRW_DimDiametric : public DRW_Dimension { + SETENTFRIENDS +public: + DRW_DimDiametric() { + eType = DRW::DIMDIAMETRIC; + type = 3; + } + DRW_DimDiametric(const DRW_Dimension& d): DRW_Dimension(d) { + eType = DRW::DIMDIAMETRIC; + } + + DRW_Coord getDiameter1Point() const {return getPt5();} /*!< First definition point for diameter, code 15, 25 & 35 */ + void setDiameter1Point(const DRW_Coord p){setPt5(p);} + DRW_Coord getDiameter2Point() const {return getDefPoint();} /*!< Opposite point for diameter, code 10, 20 & 30 */ + void setDiameter2Point(const DRW_Coord p){setDefPoint(p);} + double getLeaderLength() const {return getRa40();} /*!< Leader length, code 40 */ + void setLeaderLength(const double d) {setRa40(d);} + +protected: + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); +}; + +//! Class to handle angular dimension entity +/*! +* Class to handle angular dimension entity +* @author Rallaz +*/ +class DRW_DimAngular : public DRW_Dimension { + SETENTFRIENDS +public: + DRW_DimAngular() { + eType = DRW::DIMANGULAR; + type = 2; + } + DRW_DimAngular(const DRW_Dimension& d): DRW_Dimension(d) { + eType = DRW::DIMANGULAR; + } + + DRW_Coord getFirstLine1() const {return getPt3();} /*!< Definition point line 1-1, code 13, 23 & 33 */ + void setFirstLine1(const DRW_Coord p) {setPt3(p);} + DRW_Coord getFirstLine2() const {return getPt4();} /*!< Definition point line 1-2, code 14, 24 & 34 */ + void setFirstLine2(const DRW_Coord p) {setPt4(p);} + DRW_Coord getSecondLine1() const {return getPt5();} /*!< Definition point line 2-1, code 15, 25 & 35 */ + void setSecondLine1(const DRW_Coord p) {setPt5(p);} + DRW_Coord getSecondLine2() const {return getDefPoint();} /*!< Definition point line 2-2, code 10, 20 & 30 */ + void setSecondLine2(const DRW_Coord p){setDefPoint(p);} + DRW_Coord getDimPoint() const {return getPt6();} /*!< Dimension definition point, code 16, 26 & 36 */ + void setDimPoint(const DRW_Coord p) {setPt6(p);} + +protected: + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); +}; + + +//! Class to handle angular 3p dimension entity +/*! +* Class to handle angular 3p dimension entity +* @author Rallaz +*/ +class DRW_DimAngular3p : public DRW_Dimension { + SETENTFRIENDS +public: + DRW_DimAngular3p() { + eType = DRW::DIMANGULAR3P; + type = 5; + } + DRW_DimAngular3p(const DRW_Dimension& d): DRW_Dimension(d) { + eType = DRW::DIMANGULAR3P; + } + + DRW_Coord getFirstLine() const {return getPt3();} /*!< Definition point line 1, code 13, 23 & 33 */ + void setFirstLine(const DRW_Coord p) {setPt3(p);} + DRW_Coord getSecondLine() const {return getPt4();} /*!< Definition point line 2, code 14, 24 & 34 */ + void setSecondLine(const DRW_Coord p) {setPt4(p);} + DRW_Coord getVertexPoint() const {return getPt5();} /*!< Vertex point, code 15, 25 & 35 */ + void SetVertexPoint(const DRW_Coord p) {setPt5(p);} + DRW_Coord getDimPoint() const {return getDefPoint();} /*!< Dimension definition point, code 10, 20 & 30 */ + void setDimPoint(const DRW_Coord p) {setDefPoint(p);} + +protected: + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); +}; + +//! Class to handle ordinate dimension entity +/*! +* Class to handle ordinate dimension entity +* @author Rallaz +*/ +class DRW_DimOrdinate : public DRW_Dimension { + SETENTFRIENDS +public: + DRW_DimOrdinate() { + eType = DRW::DIMORDINATE; + type = 6; + } + DRW_DimOrdinate(const DRW_Dimension& d): DRW_Dimension(d) { + eType = DRW::DIMORDINATE; + } + + DRW_Coord getOriginPoint() const {return getDefPoint();} /*!< Origin definition point, code 10, 20 & 30 */ + void setOriginPoint(const DRW_Coord p) {setDefPoint(p);} + DRW_Coord getFirstLine() const {return getPt3();} /*!< Feature location point, code 13, 23 & 33 */ + void setFirstLine(const DRW_Coord p) {setPt3(p);} + DRW_Coord getSecondLine() const {return getPt4();} /*!< Leader end point, code 14, 24 & 34 */ + void setSecondLine(const DRW_Coord p) {setPt4(p);} + +protected: + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); +}; + + +//! Class to handle leader entity +/*! +* Class to handle leader entity +* @author Rallaz +*/ +class DRW_Leader : public DRW_Entity { + SETENTFRIENDS +public: + DRW_Leader() { + eType = DRW::LEADER; + flag = 3; + hookflag = vertnum = leadertype = 0; + extrusionPoint.x = extrusionPoint.y = 0.0; + arrow = 1; + extrusionPoint.z = 1.0; + } + ~DRW_Leader() { + for(DRW_Coord *item : vertexlist) delete item; + } + + virtual void applyExtrusion(){} + +protected: + void parseCode(int code, dxfReader *reader); + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: + UTF8STRING style; /*!< Dimension style name, code 3 */ + int arrow; /*!< Arrowhead flag, code 71, 0=Disabled; 1=Enabled */ + int leadertype; /*!< Leader path type, code 72, 0=Straight line segments; 1=Spline */ + int flag; /*!< Leader creation flag, code 73, default 3 */ + int hookline; /*!< Hook line direction flag, code 74, default 1 */ + int hookflag; /*!< Hook line flag, code 75 */ + double textheight; /*!< Text annotation height, code 40 */ + double textwidth; /*!< Text annotation width, code 41 */ + int vertnum; /*!< Number of vertices, code 76 */ + int coloruse; /*!< Color to use if leader's DIMCLRD = BYBLOCK, code 77 */ + duint32 annotHandle; /*!< Hard reference to associated annotation, code 340 */ + DRW_Coord extrusionPoint; /*!< Normal vector, code 210, 220 & 230 */ + DRW_Coord horizdir; /*!< "Horizontal" direction for leader, code 211, 221 & 231 */ + DRW_Coord offsetblock; /*!< Offset of last leader vertex from block, code 212, 222 & 232 */ + DRW_Coord offsettext; /*!< Offset of last leader vertex from annotation, code 213, 223 & 233 */ + + std::vector vertexlist; /*!< vertex points list, code 10, 20 & 30 */ + +private: + DRW_Coord *vertexpoint; /*!< current control point to add data */ + dwgHandle dimStyleH; + dwgHandle AnnotH; +}; + +//! Class to handle viewport entity +/*! +* Class to handle viewport entity +* @author Rallaz +*/ +class DRW_Viewport : public DRW_Point { + SETENTFRIENDS +public: + DRW_Viewport() { + eType = DRW::VIEWPORT; + vpstatus = 0; + pswidth = 205; + psheight = 156; + centerPX = 128.5; + centerPY = 97.5; + } + + virtual void applyExtrusion(){} + +protected: + void parseCode(int code, dxfReader *reader); + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: + double pswidth; /*!< Width in paper space units, code 40 */ + double psheight; /*!< Height in paper space units, code 41 */ + int vpstatus; /*!< Viewport status, code 68 */ + int vpID; /*!< Viewport ID, code 69 */ + double centerPX; /*!< view center point X, code 12 */ + double centerPY; /*!< view center point Y, code 22 */ + double snapPX; /*!< Snap base point X, code 13 */ + double snapPY; /*!< Snap base point Y, code 23 */ + double snapSpPX; /*!< Snap spacing X, code 14 */ + double snapSpPY; /*!< Snap spacing Y, code 24 */ + //TODO: complete in dxf + DRW_Coord viewDir; /*!< View direction vector, code 16, 26 & 36 */ + DRW_Coord viewTarget; /*!< View target point, code 17, 27, 37 */ + double viewLength; /*!< Perspective lens length, code 42 */ + double frontClip; /*!< Front clip plane Z value, code 43 */ + double backClip; /*!< Back clip plane Z value, code 44 */ + double viewHeight; /*!< View height in model space units, code 45 */ + double snapAngle; /*!< Snap angle, code 50 */ + double twistAngle; /*!< view twist angle, code 51 */ + +private: + duint32 frozenLyCount; +};//RLZ: missing 15,25, 72, 331, 90, 340, 1, 281, 71, 74, 110, 120, 130, 111, 121,131, 112,122, 132, 345,346, and more... + +//used //DRW_Coord basePoint; /*!< base point, code 10, 20 & 30 */ + +//double thickness; /*!< thickness, code 39 */ +//DRW_Coord extPoint; /*!< Dir extrusion normal vector, code 210, 220 & 230 */ +//enum DRW::ETYPE eType; /*!< enum: entity type, code 0 */ +//duint32 handle; /*!< entity identifier, code 5 */ +//std::list > appData; /*!< list of application data, code 102 */ +//duint32 parentHandle; /*!< Soft-pointer ID/handle to owner BLOCK_RECORD object, code 330 */ +//DRW::Space space; /*!< space indicator, code 67*/ +//UTF8STRING layer; /*!< layer name, code 8 */ +//UTF8STRING lineType; /*!< line type, code 6 */ +//duint32 material; /*!< hard pointer id to material object, code 347 */ +//int color; /*!< entity color, code 62 */ +//enum DRW_LW_Conv::lineWidth lWeight; /*!< entity lineweight, code 370 */ +//double ltypeScale; /*!< linetype scale, code 48 */ +//bool visible; /*!< entity visibility, code 60 */ +//int numProxyGraph; /*!< Number of bytes in proxy graphics, code 92 */ +//std::string proxyGraphics; /*!< proxy graphics bytes, code 310 */ +//int color24; /*!< 24-bit color, code 420 */ +//std::string colorName; /*!< color name, code 430 */ +//int transparency; /*!< transparency, code 440 */ +//int plotStyle; /*!< hard pointer id to plot style object, code 390 */ +//DRW::ShadowMode shadow; /*!< shadow mode, code 284 */ +//bool haveExtrusion; /*!< set to true if the entity have extrusion*/ + +#endif + +// EOF diff --git a/extlib/libdxfrw/drw_header.cpp b/extlib/libdxfrw/drw_header.cpp new file mode 100644 index 0000000..882752d --- /dev/null +++ b/extlib/libdxfrw/drw_header.cpp @@ -0,0 +1,2480 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include "drw_header.h" +#include "intern/dxfreader.h" +#include "intern/dxfwriter.h" +#include "intern/drw_dbg.h" +#include "intern/dwgbuffer.h" + +DRW_Header::DRW_Header() { + linetypeCtrl = layerCtrl = styleCtrl = dimstyleCtrl = appidCtrl = 0; + blockCtrl = viewCtrl = ucsCtrl = vportCtrl = vpEntHeaderCtrl = 0; + version = DRW::AC1021; +} + +void DRW_Header::addComment(std::string c){ + if (!comments.empty()) + comments += '\n'; + comments += c; +} + +void DRW_Header::parseCode(int code, dxfReader *reader){ + switch (code) { + case 9: + curr = new DRW_Variant(); + name = reader->getString(); + if (version < DRW::AC1015 && name == "$DIMUNIT") + name="$DIMLUNIT"; + vars[name]=curr; + break; + case 1: + curr->addString(reader->getUtf8String()); + if (name =="$ACADVER") { + reader->setVersion(curr->content.s, true); + version = reader->getVersion(); + } + curr->code = code; + break; + case 2: + curr->addString(reader->getUtf8String()); + curr->code = code; + break; + case 3: + curr->addString(reader->getUtf8String()); + if (name =="$DWGCODEPAGE") { + reader->setCodePage(curr->content.s); + curr->addString(reader->getCodePage()); + } + curr->code = code; + break; + case 6: + curr->addString(reader->getUtf8String()); + curr->code = code; + break; + case 7: + curr->addString(reader->getUtf8String()); + curr->code = code; + break; + case 8: + curr->addString(reader->getUtf8String()); + curr->code = code; + break; + case 10: + curr->addCoord(); + curr->setCoordX(reader->getDouble()); + curr->code = code; + break; + case 20: + curr->setCoordY(reader->getDouble()); + break; + case 30: + curr->setCoordZ(reader->getDouble()); + curr->code = code; + break; + case 40: + curr->addDouble(reader->getDouble()); + curr->code = code; + break; + case 50: + curr->addDouble(reader->getDouble()); + curr->code = code; + break; + case 62: + curr->addInt(reader->getInt32()); + curr->code = code; + break; + case 70: + curr->addInt(reader->getInt32()); + curr->code = code; + break; + case 280: + curr->addInt(reader->getInt32()); + curr->code = code; + break; + case 290: + curr->addInt(reader->getInt32()); + curr->code = code; + break; + case 370: + curr->addInt(reader->getInt32()); + curr->code = code; + break; + case 380: + curr->addInt(reader->getInt32()); + curr->code = code; + break; + case 390: + curr->addString(reader->getUtf8String()); + curr->code = code; + break; + default: + break; + } +} + +void DRW_Header::write(dxfWriter *writer, DRW::Version ver){ +/*RLZ: TODO complete all vars to AC1024*/ + double varDouble; + int varInt; + std::string varStr; + DRW_Coord varCoord; + writer->writeString(2, "HEADER"); + writer->writeString(9, "$ACADVER"); + switch (ver) { + case DRW::AC1006: //unsupported version acad 10 + case DRW::AC1009: //acad 11 & 12 + varStr = "AC1009"; + break; + case DRW::AC1012: //unsupported version acad 13 + case DRW::AC1014: //acad 14 + varStr = "AC1014"; + break; + case DRW::AC1015: //acad 2000 + varStr = "AC1015"; + break; + case DRW::AC1018: //acad 2004 + varStr = "AC1018"; + break; +/* case DRW::AC1021: //acad 2007 + varStr = "AC1021"; + break;*/ + case DRW::AC1024: //acad 2010 + varStr = "AC1024"; + break; + case DRW::AC1027: //acad 2013 + varStr = "AC1027"; + break; + default: //acad 2007 default version + varStr = "AC1021"; + break; + } + writer->writeString(1, varStr); + writer->setVersion(&varStr, true); + + getStr("$ACADVER", &varStr); + getStr("$ACADMAINTVER", &varStr); + + if (!getStr("$DWGCODEPAGE", &varStr)) { + varStr = "ANSI_1252"; + } + writer->writeString(9, "$DWGCODEPAGE"); + writer->setCodePage(&varStr); + writer->writeString(3, writer->getCodePage() ); + writer->writeString(9, "$INSBASE"); + if (getCoord("$INSBASE", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$EXTMIN"); + if (getCoord("$EXTMIN", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 1.0000000000000000E+020); + writer->writeDouble(20, 1.0000000000000000E+020); + writer->writeDouble(30, 1.0000000000000000E+020); + } + writer->writeString(9, "$EXTMAX"); + if (getCoord("$EXTMAX", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, -1.0000000000000000E+020); + writer->writeDouble(20, -1.0000000000000000E+020); + writer->writeDouble(30, -1.0000000000000000E+020); + } + writer->writeString(9, "$LIMMIN"); + if (getCoord("$LIMMIN", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + } + writer->writeString(9, "$LIMMAX"); + if (getCoord("$LIMMAX", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + } else { + writer->writeDouble(10, 420.0); + writer->writeDouble(20, 297.0); + } + writer->writeString(9, "$ORTHOMODE"); + if (getInt("$ORTHOMODE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$REGENMODE"); + if (getInt("$REGENMODE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 1); + writer->writeString(9, "$FILLMODE"); + if (getInt("$FILLMODE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 1); + writer->writeString(9, "$QTEXTMODE"); + if (getInt("$QTEXTMODE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$MIRRTEXT"); + if (getInt("$MIRRTEXT", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + if (ver == DRW::AC1009){ + writer->writeString(9, "$DRAGMODE"); + if (getInt("$DRAGMODE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 2); + } + writer->writeString(9, "$LTSCALE"); + if (getDouble("$LTSCALE", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 1.0); + if (ver == DRW::AC1009){ + writer->writeString(9, "$OSMODE"); + if (getInt("$OSMODE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + } + writer->writeString(9, "$ATTMODE"); + if (getInt("$ATTMODE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$TEXTSIZE"); + if (getDouble("$TEXTSIZE", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 2.5); + writer->writeString(9, "$TRACEWID"); + if (getDouble("$TRACEWID", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 15.68); + writer->writeString(9, "$TEXTSTYLE"); + if (getStr("$TEXTSTYLE", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(7, varStr); + else + writer->writeUtf8String(7, varStr); + else + writer->writeString(7, "STANDARD"); + writer->writeString(9, "$CLAYER"); + if (getStr("$CLAYER", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(8, varStr); + else + writer->writeUtf8String(8, varStr); + else + writer->writeString(8, "0"); + writer->writeString(9, "$CELTYPE"); + if (getStr("$CELTYPE", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(6, varStr); + else + writer->writeUtf8String(6, varStr); + else + writer->writeString(6, "BYLAYER"); + writer->writeString(9, "$CECOLOR"); + if (getInt("$CECOLOR", &varInt)) + writer->writeInt16(62, varInt); + else + writer->writeInt16(62, 256); + if (ver > DRW::AC1009){ + writer->writeString(9, "$CELTSCALE"); + if (getDouble("$CELTSCALE", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 1.0); + writer->writeString(9, "$DISPSILH"); + if (getInt("$DISPSILH", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + } + + writer->writeString(9, "$DIMSCALE"); + if (getDouble("$DIMSCALE", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 1.0); + writer->writeString(9, "$DIMASZ"); + if (getDouble("$DIMASZ", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 2.5); + writer->writeString(9, "$DIMEXO"); + if (getDouble("$DIMEXO", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.625); + writer->writeString(9, "$DIMDLI"); + if (getDouble("$DIMDLI", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 3.75); + writer->writeString(9, "$DIMRND"); + if (getDouble("$DIMRND", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$DIMDLE"); + if (getDouble("$DIMDLE", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$DIMEXE"); + if (getDouble("$DIMEXE", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 1.25); + writer->writeString(9, "$DIMTP"); + if (getDouble("$DIMTP", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$DIMTM"); + if (getDouble("$DIMTM", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$DIMTXT"); + if (getDouble("$DIMTXT", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 2.5); + writer->writeString(9, "$DIMCEN"); + if (getDouble("$DIMCEN", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 2.5); + writer->writeString(9, "$DIMTSZ"); + if (getDouble("$DIMTSZ", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$DIMTOL"); + if (getInt("$DIMTOL", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMLIM"); + if (getInt("$DIMLIM", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMTIH"); + if (getInt("$DIMTIH", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMTOH"); + if (getInt("$DIMTOH", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMSE1"); + if (getInt("$DIMSE1", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMSE2"); + if (getInt("$DIMSE2", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMTAD"); + if (getInt("$DIMTAD", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 1); + writer->writeString(9, "$DIMZIN"); + if (getInt("$DIMZIN", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 8); + writer->writeString(9, "$DIMBLK"); + if (getStr("$DIMBLK", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(1, varStr); + else + writer->writeUtf8String(1, varStr); + else + writer->writeString(1, ""); + writer->writeString(9, "$DIMASO"); + if (getInt("$DIMASO", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 1); + writer->writeString(9, "$DIMSHO"); + if (getInt("$DIMSHO", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 1); + writer->writeString(9, "$DIMPOST"); + if (getStr("$DIMPOST", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(1, varStr); + else + writer->writeUtf8String(1, varStr); + else + writer->writeString(1, ""); + writer->writeString(9, "$DIMAPOST"); + if (getStr("$DIMAPOST", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(1, varStr); + else + writer->writeUtf8String(1, varStr); + else + writer->writeString(1, ""); + writer->writeString(9, "$DIMALT"); + if (getInt("$DIMALT", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMALTD"); + if (getInt("$DIMALTD", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 3); + writer->writeString(9, "$DIMALTF"); + if (getDouble("$DIMALTF", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.03937); + writer->writeString(9, "$DIMLFAC"); + if (getDouble("$DIMLFAC", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 1.0); + writer->writeString(9, "$DIMTOFL"); + if (getInt("$DIMTOFL", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 1); + writer->writeString(9, "$DIMTVP"); + if (getDouble("$DIMTVP", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$DIMTIX"); + if (getInt("$DIMTIX", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMSOXD"); + if (getInt("$DIMSOXD", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMSAH"); + if (getInt("$DIMSAH", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMBLK1"); + if (getStr("$DIMBLK1", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(1, varStr); + else + writer->writeUtf8String(1, varStr); + else + writer->writeString(1, ""); + writer->writeString(9, "$DIMBLK2"); + if (getStr("$DIMBLK2", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(1, varStr); + else + writer->writeUtf8String(1, varStr); + else + writer->writeString(1, ""); + writer->writeString(9, "$DIMSTYLE"); + if (getStr("$DIMSTYLE", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(2, varStr); + else + writer->writeUtf8String(2, varStr); + else + writer->writeString(2, "STANDARD"); + writer->writeString(9, "$DIMCLRD"); + if (getInt("$DIMCLRD", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMCLRE"); + if (getInt("$DIMCLRE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMCLRT"); + if (getInt("$DIMCLRT", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMTFAC"); + if (getDouble("$DIMTFAC", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 1.0); + writer->writeString(9, "$DIMGAP"); + if (getDouble("$DIMGAP", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.625); + //post r12 dim vars + if (ver > DRW::AC1009) { + writer->writeString(9, "$DIMJUST"); + if (getInt("$DIMJUST", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMSD1"); + if (getInt("$DIMSD1", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMSD2"); + if (getInt("$DIMSD2", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMTOLJ"); + if (getInt("$DIMTOLJ", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMTZIN"); + if (getInt("$DIMTZIN", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 8); + writer->writeString(9, "$DIMALTZ"); + if (getInt("$DIMALTZ", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMALTTZ"); + if (getInt("$DIMALTTZ", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMUPT"); + if (getInt("$DIMUPT", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMDEC"); + if (getInt("$DIMDEC", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 2); + writer->writeString(9, "$DIMTDEC"); + if (getInt("$DIMTDEC", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 2); + writer->writeString(9, "$DIMALTU"); + if (getInt("$DIMALTU", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 2); + writer->writeString(9, "$DIMALTTD"); + if (getInt("$DIMALTTD", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 3); + writer->writeString(9, "$DIMTXSTY"); + if (getStr("$DIMTXSTY", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(7, varStr); + else + writer->writeUtf8String(7, varStr); + else + writer->writeString(7, "STANDARD"); + writer->writeString(9, "$DIMAUNIT"); + if (getInt("$DIMAUNIT", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMADEC"); + if (getInt("$DIMADEC", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMALTRND"); + if (getDouble("$DIMALTRND", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$DIMAZIN"); + if (getInt("$DIMAZIN", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMDSEP"); + if (getInt("$DIMDSEP", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 44); + writer->writeString(9, "$DIMATFIT"); + if (getInt("$DIMATFIT", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 3); + writer->writeString(9, "$DIMFRAC"); + if (getInt("$DIMFRAC", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMLDRBLK"); + if (getStr("$DIMLDRBLK", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(1, varStr); + else + writer->writeUtf8String(1, varStr); + else + writer->writeString(1, "STANDARD"); + //verify if exist "$DIMLUNIT" or obsolete "$DIMUNIT" (pre v2000) + if ( !getInt("$DIMLUNIT", &varInt) ){ + if (!getInt("$DIMUNIT", &varInt)) + varInt = 2; + } + //verify valid values from 1 to 6 + if (varInt<1 || varInt>6) + varInt = 2; + if (ver > DRW::AC1014) { + writer->writeString(9, "$DIMLUNIT"); + writer->writeInt16(70, varInt); + } else { + writer->writeString(9, "$DIMUNIT"); + writer->writeInt16(70, varInt); + } + writer->writeString(9, "$DIMLWD"); + if (getInt("$DIMLWD", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, -2); + writer->writeString(9, "$DIMLWE"); + if (getInt("$DIMLWE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, -2); + writer->writeString(9, "$DIMTMOVE"); + if (getInt("$DIMTMOVE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + + if (ver > DRW::AC1018) {// and post v2004 dim vars + writer->writeString(9, "$DIMFXL"); + if (getDouble("$DIMFXL", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 1.0); + writer->writeString(9, "$DIMFXLON"); + if (getInt("$DIMFXLON", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMJOGANG"); + if (getDouble("$DIMJOGANG", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.7854); + writer->writeString(9, "$DIMTFILL"); + if (getInt("$DIMTFILL", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMTFILLCLR"); + if (getInt("$DIMTFILLCLR", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMARCSYM"); + if (getInt("$DIMARCSYM", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$DIMLTYPE"); + if (getStr("$DIMLTYPE", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(6, varStr); + else + writer->writeUtf8String(6, varStr); + else + writer->writeString(6, ""); + writer->writeString(9, "$DIMLTEX1"); + if (getStr("$DIMLTEX1", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(6, varStr); + else + writer->writeUtf8String(6, varStr); + else + writer->writeString(6, ""); + writer->writeString(9, "$DIMLTEX2"); + if (getStr("$DIMLTEX2", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(6, varStr); + else + writer->writeUtf8String(6, varStr); + else + writer->writeString(6, ""); + if (ver > DRW::AC1021) {// and post v2007 dim vars + writer->writeString(9, "$DIMTXTDIRECTION"); + if (getInt("$DIMTXTDIRECTION", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + } + }// end post v2004 dim vars + }//end post r12 dim vars + + writer->writeString(9, "$LUNITS"); + if (getInt("$LUNITS", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 2); + writer->writeString(9, "$LUPREC"); + if (getInt("$LUPREC", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 4); + writer->writeString(9, "$SKETCHINC"); + if (getDouble("$SKETCHINC", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 1.0); + writer->writeString(9, "$FILLETRAD"); + if (getDouble("$FILLETRAD", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$AUNITS"); + if (getInt("$AUNITS", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$AUPREC"); + if (getInt("$AUPREC", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 2); + writer->writeString(9, "$MENU"); + if (getStr("$MENU", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(1, varStr); + else + writer->writeUtf8String(1, varStr); + else + writer->writeString(1, "."); + writer->writeString(9, "$ELEVATION"); + if (getDouble("$ELEVATION", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$PELEVATION"); + if (getDouble("$PELEVATION", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$THICKNESS"); + if (getDouble("$THICKNESS", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$LIMCHECK"); + if (getInt("$LIMCHECK", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + if (ver < DRW::AC1015) { + writer->writeString(9, "$BLIPMODE"); + if (getInt("$BLIPMODE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + } + writer->writeString(9, "$CHAMFERA"); + if (getDouble("$CHAMFERA", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$CHAMFERB"); + if (getDouble("$CHAMFERB", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + if (ver > DRW::AC1009) { + writer->writeString(9, "$CHAMFERC"); + if (getDouble("$CHAMFERC", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$CHAMFERD"); + if (getDouble("$CHAMFERD", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + } + writer->writeString(9, "$SKPOLY"); + if (getInt("$SKPOLY", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 0); + //rlz: todo, times + writer->writeString(9, "$USRTIMER"); + if (getInt("$USRTIMER", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 1); + writer->writeString(9, "$ANGBASE"); + if (getDouble("$ANGBASE", &varDouble)) + writer->writeDouble(50, varDouble); + else + writer->writeDouble(50, 0.0); + writer->writeString(9, "$ANGDIR"); + if (getInt("$ANGDIR", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 0); + writer->writeString(9, "$PDMODE"); + if (getInt("$PDMODE", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 34); + writer->writeString(9, "$PDSIZE"); + if (getDouble("$PDSIZE", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$PLINEWID"); + if (getDouble("$PLINEWID", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + if (ver < DRW::AC1012) { + writer->writeString(9, "$COORDS"); + if (getInt("$COORDS", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 2); + } + writer->writeString(9, "$SPLFRAME"); + if (getInt("$SPLFRAME", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 0); + writer->writeString(9, "$SPLINETYPE"); + if (getInt("$SPLINETYPE", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 2); + writer->writeString(9, "$SPLINESEGS"); + if (getInt("$SPLINESEGS", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 8); + if (ver < DRW::AC1012) { + writer->writeString(9, "$ATTDIA"); + if (getInt("$ATTDIA", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 1); + writer->writeString(9, "$ATTREQ"); + if (getInt("$ATTREQ", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 1); + writer->writeString(9, "$HANDLING"); + if (getInt("$HANDLING", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 1); + } + writer->writeString(9, "$HANDSEED"); + //RLZ dxfHex(5, 0xFFFF); + writer->writeString(5, "20000"); + writer->writeString(9, "$SURFTAB1"); + if (getInt("$SURFTAB1", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 6); + writer->writeString(9, "$SURFTAB2"); + if (getInt("$SURFTAB2", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 6); + writer->writeString(9, "$SURFTYPE"); + if (getInt("$SURFTYPE", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 6); + writer->writeString(9, "$SURFU"); + if (getInt("$SURFU", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 6); + writer->writeString(9, "$SURFV"); + if (getInt("$SURFV", &varInt)) { + writer->writeInt16(70, varInt); + } else + writer->writeInt16(70, 6); + if (getStr("$TDCREATE", &varStr)) { + writer->writeString(9, "$TDCREATE"); + writer->writeString(40, varStr); + } + if (ver > DRW::AC1009) { + writer->writeString(9, "$UCSBASE"); + if (getStr("$UCSBASE", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(2, varStr); + else + writer->writeUtf8String(2, varStr); + else + writer->writeString(2, ""); +} + writer->writeString(9, "$UCSNAME"); + if (getStr("$UCSNAME", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(2, varStr); + else + writer->writeUtf8String(2, varStr); + else + writer->writeString(2, ""); + writer->writeString(9, "$UCSORG"); + if (getCoord("$UCSORG", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$UCSXDIR"); + if (getCoord("$UCSXDIR", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 1.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$UCSYDIR"); + if (getCoord("$UCSYDIR", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 1.0); + writer->writeDouble(30, 0.0); + } + if (ver > DRW::AC1009) { //begin post r12 UCS vars + writer->writeString(9, "$UCSORTHOREF"); + if (getStr("$UCSORTHOREF", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(2, varStr); + else + writer->writeUtf8String(2, varStr); + else + writer->writeString(2, ""); + writer->writeString(9, "$UCSORTHOVIEW"); + if (getInt("$UCSORTHOVIEW", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$UCSORGTOP"); + if (getCoord("$UCSORGTOP", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$UCSORGBOTTOM"); + if (getCoord("$UCSORGBOTTOM", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$UCSORGLEFT"); + if (getCoord("$UCSORGLEFT", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$UCSORGRIGHT"); + if (getCoord("$UCSORGRIGHT", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$UCSORGFRONT"); + if (getCoord("$UCSORGFRONT", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$UCSORGBACK"); + if (getCoord("$UCSORGBACK", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$PUCSBASE"); + if (getStr("$PUCSBASE", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(2, varStr); + else + writer->writeUtf8String(2, varStr); + else + writer->writeString(2, ""); + } //end post r12 UCS vars + writer->writeString(9, "$PUCSNAME"); + if (getStr("$PUCSNAME", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(2, varStr); + else + writer->writeUtf8String(2, varStr); + else + writer->writeString(2, ""); + writer->writeString(9, "$PUCSORG"); + if (getCoord("$PUCSORG", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$PUCSXDIR"); + if (getCoord("$PUCSXDIR", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 1.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$PUCSYDIR"); + if (getCoord("$PUCSYDIR", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 1.0); + writer->writeDouble(30, 0.0); + } + if (ver > DRW::AC1009) { //begin post r12 PUCS vars + writer->writeString(9, "$PUCSORTHOREF"); + if (getStr("$PUCSORTHOREF", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(2, varStr); + else + writer->writeUtf8String(2, varStr); + else + writer->writeString(2, ""); + writer->writeString(9, "$PUCSORTHOVIEW"); + if (getInt("$PUCSORTHOVIEW", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$PUCSORGTOP"); + if (getCoord("$PUCSORGTOP", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$PUCSORGBOTTOM"); + if (getCoord("$PUCSORGBOTTOM", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$PUCSORGLEFT"); + if (getCoord("$PUCSORGLEFT", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$PUCSORGRIGHT"); + if (getCoord("$PUCSORGRIGHT", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$PUCSORGFRONT"); + if (getCoord("$PUCSORGFRONT", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$PUCSORGBACK"); + if (getCoord("$PUCSORGBACK", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + } //end post r12 PUCS vars + + writer->writeString(9, "$USERI1"); + if (getInt("$USERI1", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$USERI2"); + if (getInt("$USERI2", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$USERI3"); + if (getInt("$USERI3", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$USERI4"); + if (getInt("$USERI4", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$USERI5"); + if (getInt("$USERI5", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$USERR1"); + if (getDouble("$USERR1", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$USERR2"); + if (getDouble("$USERR2", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$USERR3"); + if (getDouble("$USERR3", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$USERR4"); + if (getDouble("$USERR4", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$USERR5"); + if (getDouble("$USERR5", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$WORLDVIEW"); + if (getInt("$WORLDVIEW", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 1); + writer->writeString(9, "$SHADEDGE"); + if (getInt("$SHADEDGE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 3); + writer->writeString(9, "$SHADEDIF"); + if (getInt("$SHADEDIF", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 70); + writer->writeString(9, "$TILEMODE"); + if (getInt("$TILEMODE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 1); + writer->writeString(9, "$MAXACTVP"); + if (getInt("$MAXACTVP", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 64); + if (ver > DRW::AC1009) { //begin post r12 PUCS vars + writer->writeString(9, "$PINSBASE"); + if (getCoord("$PINSBASE", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + } + writer->writeString(9, "$PLIMCHECK"); + if (getInt("$PLIMCHECK", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$PEXTMIN"); + if (getCoord("$PEXTMIN", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + writer->writeString(9, "$PEXTMAX"); + if (getCoord("$PEXTMAX", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + writer->writeDouble(30, varCoord.z); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + } + +/* RLZ: moved to active VPORT, but can write in header if present*/ + if (getInt("$GRIDMODE", &varInt)) { + writer->writeString(9, "$GRIDMODE"); + writer->writeInt16(70, varInt); + } + if (getInt("$SNAPSTYLE", &varInt)) { + writer->writeString(9, "$SNAPSTYLE"); + writer->writeInt16(70, varInt); + } + if (getCoord("$GRIDUNIT", &varCoord)) { + writer->writeString(9, "$GRIDUNIT"); + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + } + if (getCoord("$VIEWCTR", &varCoord)) { + writer->writeString(9, "$VIEWCTR"); + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + } +/* RLZ: moved to active VPORT, but can write in header if present*/ + + writer->writeString(9, "$PLIMMIN"); + if (getCoord("$PLIMMIN", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + } else { + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + } + writer->writeString(9, "$PLIMMAX"); + if (getCoord("$PLIMMAX", &varCoord)) { + writer->writeDouble(10, varCoord.x); + writer->writeDouble(20, varCoord.y); + } else { + writer->writeDouble(10, 297.0); + writer->writeDouble(20, 210.0); + } + writer->writeString(9, "$UNITMODE"); + if (getInt("$UNITMODE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$VISRETAIN"); + if (getInt("$VISRETAIN", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 1); + writer->writeString(9, "$PLINEGEN"); + if (getInt("$PLINEGEN", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$PSLTSCALE"); + if (getInt("$PSLTSCALE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 1); + if (ver > DRW::AC1009){//start port r12 vars + writer->writeString(9, "$TREEDEPTH"); + if (getInt("$TREEDEPTH", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 3020); + writer->writeString(9, "$CMLSTYLE"); + if (getStr("$CMLSTYLE", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(2, varStr); + else + writer->writeUtf8String(2, varStr); + else + writer->writeString(2, "Standard"); + writer->writeString(9, "$CMLJUST"); + if (getInt("$CMLJUST", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + writer->writeString(9, "$CMLSCALE"); + if (getDouble("$CMLSCALE", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 20.0); + writer->writeString(9, "$PROXYGRAPHICS"); + if (getInt("$PROXYGRAPHICS", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 1); + writer->writeString(9, "$MEASUREMENT"); + if (getInt("$MEASUREMENT", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 1); + writer->writeString(9, "$CELWEIGHT"); + if (getInt("$CELWEIGHT", &varInt)) + writer->writeInt16(370, varInt); + else + writer->writeInt16(370, -1); + writer->writeString(9, "$ENDCAPS"); + if (getInt("$ENDCAPS", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 0); + writer->writeString(9, "$JOINSTYLE"); + if (getInt("$JOINSTYLE", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 0); + writer->writeString(9, "$LWDISPLAY"); //RLZ bool flag, verify in bin version + if (getInt("$LWDISPLAY", &varInt)) + writer->writeInt16(290, varInt); + else + writer->writeInt16(290, 0); + if (ver > DRW::AC1014) { + writer->writeString(9, "$INSUNITS"); + if (getInt("$INSUNITS", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 0); + } + writer->writeString(9, "$HYPERLINKBASE"); + if (getStr("$HYPERLINKBASE", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(1, varStr); + else + writer->writeUtf8String(1, varStr); + else + writer->writeString(1, ""); + writer->writeString(9, "$STYLESHEET"); + if (getStr("$STYLESHEET", &varStr)) + if (ver == DRW::AC1009) + writer->writeUtf8Caps(1, varStr); + else + writer->writeUtf8String(1, varStr); + else + writer->writeString(1, ""); + writer->writeString(9, "$XEDIT"); //RLZ bool flag, verify in bin version + if (getInt("$XEDIT", &varInt)) + writer->writeInt16(290, varInt); + else + writer->writeInt16(290, 1); + writer->writeString(9, "$CEPSNTYPE"); + if (getInt("$CEPSNTYPE", &varInt)) + writer->writeInt16(380, varInt); + else + writer->writeInt16(380, 0); + writer->writeString(9, "$PSTYLEMODE"); //RLZ bool flag, verify in bin version + if (getInt("$PSTYLEMODE", &varInt)) + writer->writeInt16(290, varInt); + else + writer->writeInt16(290, 1); +//RLZ: here $FINGERPRINTGUID and $VERSIONGUID, do not add? + writer->writeString(9, "$EXTNAMES"); //RLZ bool flag, verify in bin version + if (getInt("$EXTNAMES", &varInt)) + writer->writeInt16(290, varInt); + else + writer->writeInt16(290, 1); + writer->writeString(9, "$PSVPSCALE"); + if (getDouble("$PSVPSCALE", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$OLESTARTUP"); //RLZ bool flag, verify in bin version + if (getInt("$OLESTARTUP", &varInt)) + writer->writeInt16(290, varInt); + else + writer->writeInt16(290, 0); + } + if (ver > DRW::AC1015) {// and post v2004 vars + writer->writeString(9, "$SORTENTS"); + if (getInt("$SORTENTS", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 127); + writer->writeString(9, "$INDEXCTL"); + if (getInt("$INDEXCTL", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 0); + writer->writeString(9, "$HIDETEXT"); + if (getInt("$HIDETEXT", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 1); + writer->writeString(9, "$XCLIPFRAME"); //RLZ bool flag, verify in bin version + if (ver > DRW::AC1021) { + if (getInt("$XCLIPFRAME", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 0); + } else { + if (getInt("$XCLIPFRAME", &varInt)) + writer->writeInt16(290, varInt); + else + writer->writeInt16(290, 0); + } + writer->writeString(9, "$HALOGAP"); + if (getInt("$HALOGAP", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 0); + writer->writeString(9, "$OBSCOLOR"); + if (getInt("$OBSCOLOR", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 257); + writer->writeString(9, "$OBSLTYPE"); + if (getInt("$OBSLTYPE", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 0); + writer->writeString(9, "$INTERSECTIONDISPLAY"); + if (getInt("$INTERSECTIONDISPLAY", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 0); + writer->writeString(9, "$INTERSECTIONCOLOR"); + if (getInt("$INTERSECTIONCOLOR", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 257); + writer->writeString(9, "$DIMASSOC"); + if (getInt("$DIMASSOC", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 1); + writer->writeString(9, "$PROJECTNAME"); + if (getStr("$PROJECTNAME", &varStr)) + writer->writeUtf8String(1, varStr); + else + writer->writeString(1, ""); + } + if (ver > DRW::AC1018) {// and post v2007 vars + writer->writeString(9, "$CAMERADISPLAY"); //RLZ bool flag, verify in bin version + if (getInt("$CAMERADISPLAY", &varInt)) + writer->writeInt16(290, varInt); + else + writer->writeInt16(290, 0); + writer->writeString(9, "$LENSLENGTH"); + if (getDouble("$LENSLENGTH", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 50.0); + writer->writeString(9, "$CAMERAHEIGHT"); + if (getDouble("$CAMERAHEIGHT", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$STEPSPERSEC"); + if (getDouble("$STEPSPERSEC", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 2.0); + writer->writeString(9, "$STEPSIZE"); + if (getDouble("$STEPSIZE", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 50.0); + writer->writeString(9, "$3DDWFPREC"); + if (getDouble("$3DDWFPREC", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 2.0); + writer->writeString(9, "$PSOLWIDTH"); + if (getDouble("$PSOLWIDTH", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 5.0); + writer->writeString(9, "$PSOLHEIGHT"); + if (getDouble("$PSOLHEIGHT", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 80.0); + writer->writeString(9, "$LOFTANG1"); + if (getDouble("$LOFTANG1", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, M_PI_2); + writer->writeString(9, "$LOFTANG2"); + if (getDouble("$LOFTANG2", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, M_PI_2); + writer->writeString(9, "$LOFTMAG1"); + if (getDouble("$LOFTMAG1", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$LOFTMAG2"); + if (getDouble("$LOFTMAG2", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$LOFTPARAM"); + if (getInt("$LOFTPARAM", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, 7); + writer->writeString(9, "$LOFTNORMALS"); + if (getInt("$LOFTNORMALS", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 1); + writer->writeString(9, "$LATITUDE"); + if (getDouble("$LATITUDE", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 1.0); + writer->writeString(9, "$LONGITUDE"); + if (getDouble("$LONGITUDE", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 1.0); + writer->writeString(9, "$NORTHDIRECTION"); + if (getDouble("$LONGITUDE", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + writer->writeString(9, "$TIMEZONE"); + if (getInt("$TIMEZONE", &varInt)) + writer->writeInt16(70, varInt); + else + writer->writeInt16(70, -8000); + writer->writeString(9, "$LIGHTGLYPHDISPLAY"); + if (getInt("$LIGHTGLYPHDISPLAY", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 1); + writer->writeString(9, "$TILEMODELIGHTSYNCH"); + if (getInt("$TILEMODELIGHTSYNCH", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 1); + //$CMATERIAL is a handle + writer->writeString(9, "$SOLIDHIST"); + if (getInt("$SOLIDHIST", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 1); + writer->writeString(9, "$SHOWHIST"); + if (getInt("$SHOWHIST", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 1); + writer->writeString(9, "$DWFFRAME"); + if (getInt("$DWFFRAME", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 2); + writer->writeString(9, "$DGNFRAME"); + if (getInt("$DGNFRAME", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 0); + writer->writeString(9, "$REALWORLDSCALE"); //RLZ bool flag, verify in bin version + if (getInt("$REALWORLDSCALE", &varInt)) + writer->writeInt16(290, varInt); + else + writer->writeInt16(290, 1); + writer->writeString(9, "$INTERFERECOLOR"); + if (getInt("$INTERFERECOLOR", &varInt)) + writer->writeInt16(62, varInt); + else + writer->writeInt16(62, 1); + //$INTERFEREOBJVS is a handle + //$INTERFEREVPVS is a handle + writer->writeString(9, "$CSHADOW"); + if (getInt("$CSHADOW", &varInt)) + writer->writeInt16(280, varInt); + else + writer->writeInt16(280, 0); + writer->writeString(9, "$SHADOWPLANELOCATION"); + if (getDouble("$SHADOWPLANELOCATION", &varDouble)) + writer->writeDouble(40, varDouble); + else + writer->writeDouble(40, 0.0); + } + +#ifdef DRW_DBG + std::map::const_iterator it; + for ( it=vars.begin() ; it != vars.end(); ++it ){ + DRW_DBG((*it).first); DRW_DBG("\n"); + } +#endif +} + +void DRW_Header::addDouble(std::string key, double value, int code){ + curr = new DRW_Variant(); + curr->addDouble( value ); + curr->code = code; + vars[key] =curr; +} + +void DRW_Header::addInt(std::string key, int value, int code){ + curr = new DRW_Variant(); + curr->addInt( value ); + curr->code = code; + vars[key] =curr; +} + +void DRW_Header::addStr(std::string key, std::string value, int code){ + curr = new DRW_Variant(); + curr->addString( value ); + curr->code = code; + vars[key] =curr; +} + +void DRW_Header::addCoord(std::string key, DRW_Coord value, int code){ + curr = new DRW_Variant(); + curr->addCoord( value ); + curr->code = code; + vars[key] =curr; +} + +bool DRW_Header::getDouble(std::string key, double *varDouble){ + bool result = false; + std::map::iterator it; + it=vars.find( key); + if (it != vars.end()) { + DRW_Variant *var = (*it).second; + if (var->type == DRW_Variant::DOUBLE) { + *varDouble = var->content.d; + result = true; + } + delete var; + vars.erase (it); + } + return result; +} + +bool DRW_Header::getInt(std::string key, int *varInt){ + bool result = false; + std::map::iterator it; + it=vars.find( key); + if (it != vars.end()) { + DRW_Variant *var = (*it).second; + if (var->type == DRW_Variant::INTEGER) { + *varInt = var->content.i; + result = true; + } + delete var; + vars.erase (it); + } + return result; +} + +bool DRW_Header::getStr(std::string key, std::string *varStr){ + bool result = false; + std::map::iterator it; + it=vars.find( key); + if (it != vars.end()) { + DRW_Variant *var = (*it).second; + if (var->type == DRW_Variant::STRING) { + *varStr = *var->content.s; + result = true; + } + delete var; + vars.erase (it); + } + return result; +} + +bool DRW_Header::getCoord(std::string key, DRW_Coord *varCoord){ + bool result = false; + std::map::iterator it; + it=vars.find( key); + if (it != vars.end()) { + DRW_Variant *var = (*it).second; + if (var->type == DRW_Variant::COORD) { + *varCoord = *var->content.v; + result = true; + } + delete var; + vars.erase (it); + } + return result; +} + +bool DRW_Header::parseDwg(DRW::Version version, dwgBuffer *buf, dwgBuffer *hBbuf, duint8 mv){ + bool result = true; + duint32 size = buf->getRawLong32(); + duint32 bitSize = 0; + duint32 endBitPos = 160; //start bit: 16 sentinel + 4 size + DRW_DBG("\nbyte size of data: "); DRW_DBG(size); + if (version > DRW::AC1021 && mv > 3) { //2010+ + duint32 hSize = buf->getRawLong32(); + endBitPos += 32; //start bit: + 4 height size + DRW_DBG("\n2010+ & MV> 3, height 32b: "); DRW_DBG(hSize); + } +//RLZ TODO add $ACADVER var & $DWGCODEPAGE & $MEASUREMENT +//RLZ TODO EN 2000 falta $CELWEIGHT, $ENDCAPS, $EXTNAMES $JOINSTYLE $LWDISPLAY $PSTYLEMODE $TDUCREATE $TDUUPDATE $XEDIT + + //bit size of data needed to locate start of string stream in 2007+ + //and mark the start of handle stream + //header is one object reads data and continue read strings ??? + if (version > DRW::AC1018) {//2007+ + bitSize = buf->getRawLong32(); + DRW_DBG("\nsize in bits: "); DRW_DBG(bitSize); + endBitPos += bitSize; + hBbuf->setPosition(endBitPos >>3); + hBbuf->setBitPos(endBitPos&7); + } + + if (version > DRW::AC1024) {//2013+ + duint64 requiredVersions = buf->getBitLongLong(); + DRW_DBG("\nREQUIREDVERSIONS var: "); DRW_DBG(requiredVersions); + } + DRW_DBG("\nUnknown1: "); DRW_DBG(buf->getBitDouble()); + DRW_DBG("\nUnknown2: "); DRW_DBG(buf->getBitDouble()); + DRW_DBG("\nUnknown3: "); DRW_DBG(buf->getBitDouble()); + DRW_DBG("\nUnknown4: "); DRW_DBG(buf->getBitDouble()); + if (version < DRW::AC1021) {//2007- + DRW_DBG("\nUnknown text1: "); DRW_DBG(buf->getCP8Text()); + DRW_DBG("\nUnknown text2: "); DRW_DBG(buf->getCP8Text()); + DRW_DBG("\nUnknown text3: "); DRW_DBG(buf->getCP8Text()); + DRW_DBG("\nUnknown text4: "); DRW_DBG(buf->getCP8Text()); + } + DRW_DBG("\nUnknown long1 (24L): "); DRW_DBG(buf->getBitLong()); + DRW_DBG("\nUnknown long2 (0L): "); DRW_DBG(buf->getBitLong()); + if (version < DRW::AC1015) {//pre 2000 + DRW_DBG("\nUnknown short (0): "); DRW_DBG(buf->getBitShort()); + } + if (version < DRW::AC1018) {//pre 2004 + dwgHandle hcv = hBbuf->getHandle(); + DRW_DBG("\nhandle of current view: "); DRW_DBGHL(hcv.code, hcv.size, hcv.ref); + } + vars["DIMASO"]=new DRW_Variant(70, buf->getBit()); + vars["DIMSHO"]=new DRW_Variant(70, buf->getBit()); + if (version < DRW::AC1015) {//pre 2000 + vars["DIMSAV"]=new DRW_Variant(70, buf->getBit()); + } + vars["PLINEGEN"]=new DRW_Variant(70, buf->getBit()); + vars["ORTHOMODE"]=new DRW_Variant(70, buf->getBit()); + vars["REGENMODE"]=new DRW_Variant(70, buf->getBit()); + vars["FILLMODE"]=new DRW_Variant(70, buf->getBit()); + vars["QTEXTMODE"]=new DRW_Variant(70, buf->getBit()); + vars["PSLTSCALE"]=new DRW_Variant(70, buf->getBit()); + vars["LIMCHECK"]=new DRW_Variant(70, buf->getBit()); + if (version < DRW::AC1015) {//pre 2000 + vars["BLIPMODE"]=new DRW_Variant(70, buf->getBit()); + } + if (version > DRW::AC1015) {//2004+ + DRW_DBG("\nUndocumented: "); DRW_DBG(buf->getBit()); + } + vars["USRTIMER"]=new DRW_Variant(70, buf->getBit()); + vars["SKPOLY"]=new DRW_Variant(70, buf->getBit()); + vars["ANGDIR"]=new DRW_Variant(70, buf->getBit()); + vars["SPLFRAME"]=new DRW_Variant(70, buf->getBit()); + if (version < DRW::AC1015) {//pre 2000 + vars["ATTREQ"]=new DRW_Variant(70, buf->getBit()); + vars["ATTDIA"]=new DRW_Variant(70, buf->getBit()); + } + vars["MIRRTEXT"]=new DRW_Variant(70, buf->getBit()); + vars["WORLDVIEW"]=new DRW_Variant(70, buf->getBit()); + if (version < DRW::AC1015) {//pre 2000 + vars["WIREFRAME"]=new DRW_Variant(70, buf->getBit()); + } + vars["TILEMODE"]=new DRW_Variant(70, buf->getBit()); + vars["PLIMCHECK"]=new DRW_Variant(70, buf->getBit()); + vars["VISRETAIN"]=new DRW_Variant(70, buf->getBit()); + if (version < DRW::AC1015) {//pre 2000 + vars["DELOBJ"]=new DRW_Variant(70, buf->getBit()); + } + vars["DISPSILH"]=new DRW_Variant(70, buf->getBit()); + vars["PELLIPSE"]=new DRW_Variant(70, buf->getBit()); + vars["PROXIGRAPHICS"]=new DRW_Variant(70, buf->getBitShort());//RLZ short or bit?? + if (version < DRW::AC1015) {//pre 2000 + vars["DRAGMODE"]=new DRW_Variant(70, buf->getBitShort());//RLZ short or bit?? + } + vars["TREEDEPTH"]=new DRW_Variant(70, buf->getBitShort());//RLZ short or bit?? + vars["LUNITS"]=new DRW_Variant(70, buf->getBitShort()); + vars["LUPREC"]=new DRW_Variant(70, buf->getBitShort()); + vars["AUNITS"]=new DRW_Variant(70, buf->getBitShort()); + vars["AUPREC"]=new DRW_Variant(70, buf->getBitShort()); + if (version < DRW::AC1015) {//pre 2000 + vars["OSMODE"]=new DRW_Variant(70, buf->getBitShort()); + } + vars["ATTMODE"]=new DRW_Variant(70, buf->getBitShort()); + if (version < DRW::AC1015) {//pre 2000 + vars["COORDS"]=new DRW_Variant(70, buf->getBitShort()); + } + vars["PDMODE"]=new DRW_Variant(70, buf->getBitShort()); + if (version < DRW::AC1015) {//pre 2000 + vars["PICKSTYLE"]=new DRW_Variant(70, buf->getBitShort()); + } + if (version > DRW::AC1015) {//2004+ + DRW_DBG("\nUnknown long 1: "); DRW_DBG(buf->getBitLong()); + DRW_DBG("\nUnknown long 2: "); DRW_DBG(buf->getBitLong()); + DRW_DBG("\nUnknown long 3: "); DRW_DBG(buf->getBitLong()); + } + vars["USERI1"]=new DRW_Variant(70, buf->getBitShort()); + vars["USERI2"]=new DRW_Variant(70, buf->getBitShort()); + vars["USERI3"]=new DRW_Variant(70, buf->getBitShort()); + vars["USERI4"]=new DRW_Variant(70, buf->getBitShort()); + vars["USERI5"]=new DRW_Variant(70, buf->getBitShort()); + vars["SPLINESEGS"]=new DRW_Variant(70, buf->getBitShort()); + vars["SURFU"]=new DRW_Variant(70, buf->getBitShort()); + vars["SURFV"]=new DRW_Variant(70, buf->getBitShort()); + vars["SURFTYPE"]=new DRW_Variant(70, buf->getBitShort()); + vars["SURFTAB1"]=new DRW_Variant(70, buf->getBitShort()); + vars["SURFTAB2"]=new DRW_Variant(70, buf->getBitShort()); + vars["SPLINETYPE"]=new DRW_Variant(70, buf->getBitShort()); + vars["SHADEDGE"]=new DRW_Variant(70, buf->getBitShort()); + vars["SHADEDIF"]=new DRW_Variant(70, buf->getBitShort()); + vars["UNITMODE"]=new DRW_Variant(70, buf->getBitShort()); + vars["MAXACTVP"]=new DRW_Variant(70, buf->getBitShort()); + vars["ISOLINES"]=new DRW_Variant(70, buf->getBitShort());////////////////// + vars["CMLJUST"]=new DRW_Variant(70, buf->getBitShort()); + vars["TEXTQLTY"]=new DRW_Variant(70, buf->getBitShort());///////////////////// + vars["LTSCALE"]=new DRW_Variant(40, buf->getBitDouble()); + vars["TEXTSIZE"]=new DRW_Variant(40, buf->getBitDouble()); + vars["TRACEWID"]=new DRW_Variant(40, buf->getBitDouble()); + vars["SKETCHINC"]=new DRW_Variant(40, buf->getBitDouble()); + vars["FILLETRAD"]=new DRW_Variant(40, buf->getBitDouble()); + vars["THICKNESS"]=new DRW_Variant(40, buf->getBitDouble()); + vars["ANGBASE"]=new DRW_Variant(50, buf->getBitDouble()); + vars["PDSIZE"]=new DRW_Variant(40, buf->getBitDouble()); + vars["PLINEWID"]=new DRW_Variant(40, buf->getBitDouble()); + vars["USERR1"]=new DRW_Variant(40, buf->getBitDouble()); + vars["USERR2"]=new DRW_Variant(40, buf->getBitDouble()); + vars["USERR3"]=new DRW_Variant(40, buf->getBitDouble()); + vars["USERR4"]=new DRW_Variant(40, buf->getBitDouble()); + vars["USERR5"]=new DRW_Variant(40, buf->getBitDouble()); + vars["CHAMFERA"]=new DRW_Variant(40, buf->getBitDouble()); + vars["CHAMFERB"]=new DRW_Variant(40, buf->getBitDouble()); + vars["CHAMFERC"]=new DRW_Variant(40, buf->getBitDouble()); + vars["CHAMFERD"]=new DRW_Variant(40, buf->getBitDouble()); + vars["FACETRES"]=new DRW_Variant(40, buf->getBitDouble());///////////////////////// + vars["CMLSCALE"]=new DRW_Variant(40, buf->getBitDouble()); + vars["CELTSCALE"]=new DRW_Variant(40, buf->getBitDouble()); + if (version < DRW::AC1021) {//2004- + vars["MENU"]=new DRW_Variant(1, buf->getCP8Text()); + } + ddouble64 msec, day; + day = buf->getBitLong(); + msec = buf->getBitLong(); + while (msec > 0) + msec /=10; + vars["TDCREATE"]=new DRW_Variant(40, day+msec);//RLZ: TODO convert to day.msec +// vars["TDCREATE"]=new DRW_Variant(40, buf->getBitLong());//RLZ: TODO convert to day.msec +// vars["TDCREATE"]=new DRW_Variant(40, buf->getBitLong()); + day = buf->getBitLong(); + msec = buf->getBitLong(); + while (msec > 0) + msec /=10; + vars["TDUPDATE"]=new DRW_Variant(40, day+msec);//RLZ: TODO convert to day.msec +// vars["TDUPDATE"]=new DRW_Variant(40, buf->getBitLong());//RLZ: TODO convert to day.msec +// vars["TDUPDATE"]=new DRW_Variant(40, buf->getBitLong()); + if (version > DRW::AC1015) {//2004+ + DRW_DBG("\nUnknown long 4: "); DRW_DBG(buf->getBitLong()); + DRW_DBG("\nUnknown long 5: "); DRW_DBG(buf->getBitLong()); + DRW_DBG("\nUnknown long 6: "); DRW_DBG(buf->getBitLong()); + } + day = buf->getBitLong(); + msec = buf->getBitLong(); + while (msec > 0) + msec /=10; + vars["TDINDWG"]=new DRW_Variant(40, day+msec);//RLZ: TODO convert to day.msec +// vars["TDINDWG"]=new DRW_Variant(40, buf->getBitLong());//RLZ: TODO convert to day.msec +// vars["TDINDWG"]=new DRW_Variant(40, buf->getBitLong());//RLZ: TODO convert to day.msec + day = buf->getBitLong(); + msec = buf->getBitLong(); + while (msec > 0) + msec /=10; + vars["TDUSRTIMER"]=new DRW_Variant(40, day+msec);//RLZ: TODO convert to day.msec +// vars["TDUSRTIMER"]=new DRW_Variant(40, buf->getBitLong());//RLZ: TODO convert to day.msec +// vars["TDUSRTIMER"]=new DRW_Variant(40, buf->getBitLong());//RLZ: TODO convert to day.msec + vars["CECOLOR"]=new DRW_Variant(62, buf->getCmColor(version));//RLZ: TODO read CMC or EMC color + dwgHandle HANDSEED = buf->getHandle();//always present in data stream + DRW_DBG("\nHANDSEED: "); DRW_DBGHL(HANDSEED.code, HANDSEED.size, HANDSEED.ref); + dwgHandle CLAYER = hBbuf->getHandle(); + DRW_DBG("\nCLAYER: "); DRW_DBGHL(CLAYER.code, CLAYER.size, CLAYER.ref); + dwgHandle TEXTSTYLE = hBbuf->getHandle(); + DRW_DBG("\nTEXTSTYLE: "); DRW_DBGHL(TEXTSTYLE.code, TEXTSTYLE.size, TEXTSTYLE.ref); + dwgHandle CELTYPE = hBbuf->getHandle(); + DRW_DBG("\nCELTYPE: "); DRW_DBGHL(CELTYPE.code, CELTYPE.size, CELTYPE.ref); + if (version > DRW::AC1018) {//2007+ + dwgHandle CMATERIAL = hBbuf->getHandle(); + DRW_DBG("\nCMATERIAL: "); DRW_DBGHL(CMATERIAL.code, CMATERIAL.size, CMATERIAL.ref); + } + dwgHandle DIMSTYLE = hBbuf->getHandle(); + DRW_DBG("\nDIMSTYLE: "); DRW_DBGHL(DIMSTYLE.code, DIMSTYLE.size, DIMSTYLE.ref); + dwgHandle CMLSTYLE = hBbuf->getHandle(); + DRW_DBG("\nCMLSTYLE: "); DRW_DBGHL(CMLSTYLE.code, CMLSTYLE.size, CMLSTYLE.ref); + if (version > DRW::AC1014) {//2000+ + vars["PSVPSCALE"]=new DRW_Variant(40, buf->getBitDouble()); + } + vars["PINSBASE"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["PEXTMIN"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["PEXTMAX"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["PLIMMIN"]=new DRW_Variant(10, buf->get2RawDouble()); + vars["PLIMMAX"]=new DRW_Variant(10, buf->get2RawDouble()); + vars["PELEVATION"]=new DRW_Variant(40, buf->getBitDouble()); + vars["PUCSORG"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["PUCSXDIR"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["PUCSYDIR"]=new DRW_Variant(10, buf->get3BitDouble()); + dwgHandle PUCSNAME = hBbuf->getHandle(); + DRW_DBG("\nPUCSNAME: "); DRW_DBGHL(PUCSNAME.code, PUCSNAME.size, PUCSNAME.ref); + if (version > DRW::AC1014) {//2000+ + dwgHandle PUCSORTHOREF = hBbuf->getHandle(); + DRW_DBG("\nPUCSORTHOREF: "); DRW_DBGHL(PUCSORTHOREF.code, PUCSORTHOREF.size, PUCSORTHOREF.ref); + vars["PUCSORTHOVIEW"]=new DRW_Variant(70, buf->getBitShort()); + dwgHandle PUCSBASE = hBbuf->getHandle(); + DRW_DBG("\nPUCSBASE: "); DRW_DBGHL(PUCSBASE.code, PUCSBASE.size, PUCSBASE.ref); + vars["PUCSORGTOP"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["PUCSORGBOTTOM"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["PUCSORGLEFT"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["PUCSORGRIGHT"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["PUCSORGFRONT"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["PUCSORGBACK"]=new DRW_Variant(10, buf->get3BitDouble()); + } + vars["INSBASE"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["EXTMIN"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["EXTMAX"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["LIMMIN"]=new DRW_Variant(10, buf->get2RawDouble()); + vars["LIMMAX"]=new DRW_Variant(10, buf->get2RawDouble()); + vars["ELEVATION"]=new DRW_Variant(40, buf->getBitDouble()); + vars["UCSORG"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["UCSXDIR"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["UCSYDIR"]=new DRW_Variant(10, buf->get3BitDouble()); + dwgHandle UCSNAME = hBbuf->getHandle(); + DRW_DBG("\nUCSNAME: "); DRW_DBGHL(UCSNAME.code, UCSNAME.size, UCSNAME.ref); + if (version > DRW::AC1014) {//2000+ + dwgHandle UCSORTHOREF = hBbuf->getHandle(); + DRW_DBG("\nUCSORTHOREF: "); DRW_DBGHL(UCSORTHOREF.code, UCSORTHOREF.size, UCSORTHOREF.ref); + vars["UCSORTHOVIEW"]=new DRW_Variant(70, buf->getBitShort()); + dwgHandle UCSBASE = hBbuf->getHandle(); + DRW_DBG("\nUCSBASE: "); DRW_DBGHL(UCSBASE.code, UCSBASE.size, UCSBASE.ref); + vars["UCSORGTOP"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["UCSORGBOTTOM"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["UCSORGLEFT"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["UCSORGRIGHT"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["UCSORGFRONT"]=new DRW_Variant(10, buf->get3BitDouble()); + vars["UCSORGBACK"]=new DRW_Variant(10, buf->get3BitDouble()); + if (version < DRW::AC1021) {//2004- + vars["DIMPOST"]=new DRW_Variant(1, buf->getCP8Text()); + vars["DIMAPOST"]=new DRW_Variant(1, buf->getCP8Text()); + } + } + if (version < DRW::AC1015) {//r14- + vars["DIMTOL"]=new DRW_Variant(70, buf->getBit()); + vars["DIMLIM"]=new DRW_Variant(70, buf->getBit()); + vars["DIMTIH"]=new DRW_Variant(70, buf->getBit()); + vars["DIMTOH"]=new DRW_Variant(70, buf->getBit()); + vars["DIMSE1"]=new DRW_Variant(70, buf->getBit()); + vars["DIMSE2"]=new DRW_Variant(70, buf->getBit()); + vars["DIMALT"]=new DRW_Variant(70, buf->getBit()); + vars["DIMTOFL"]=new DRW_Variant(70, buf->getBit()); + vars["DIMSAH"]=new DRW_Variant(70, buf->getBit()); + vars["DIMTIX"]=new DRW_Variant(70, buf->getBit()); + vars["DIMSOXD"]=new DRW_Variant(70, buf->getBit()); + vars["DIMALTD"]=new DRW_Variant(70, buf->getRawChar8()); + vars["DIMZIN"]=new DRW_Variant(70, buf->getRawChar8()); + vars["DIMSD1"]=new DRW_Variant(70, buf->getBit()); + vars["DIMSD2"]=new DRW_Variant(70, buf->getBit()); + vars["DIMTOLJ"]=new DRW_Variant(70, buf->getRawChar8()); + vars["DIMJUST"]=new DRW_Variant(70, buf->getRawChar8()); + vars["DIMFIT"]=new DRW_Variant(70, buf->getRawChar8());/////////// + vars["DIMUPT"]=new DRW_Variant(70, buf->getBit()); + vars["DIMTZIN"]=new DRW_Variant(70, buf->getRawChar8()); + vars["DIMALTZ"]=new DRW_Variant(70, buf->getRawChar8()); + vars["DIMALTTZ"]=new DRW_Variant(70, buf->getRawChar8()); + vars["DIMTAD"]=new DRW_Variant(70, buf->getRawChar8()); + vars["DIMUNIT"]=new DRW_Variant(70, buf->getBitShort());/////////// + vars["DIMAUNIT"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMDEC"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMTDEC"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMALTU"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMALTTD"]=new DRW_Variant(70, buf->getBitShort()); + dwgHandle DIMTXSTY = hBbuf->getHandle(); + DRW_DBG("\nDIMTXSTY: "); DRW_DBGHL(DIMTXSTY.code, DIMTXSTY.size, DIMTXSTY.ref); + } + vars["DIMSCALE"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMASZ"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMEXO"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMDLI"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMEXE"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMRND"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMDLE"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMTP"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMTM"]=new DRW_Variant(40, buf->getBitDouble()); + if (version > DRW::AC1018) {//2007+ + vars["DIMFXL"]=new DRW_Variant(40, buf->getBitDouble());////////////////// + vars["DIMJOGANG"]=new DRW_Variant(40, buf->getBitDouble());/////////////// + vars["DIMTFILL"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMTFILLCLR"]=new DRW_Variant(62, buf->getCmColor(version)); + } + if (version > DRW::AC1014) {//2000+ + vars["DIMTOL"]=new DRW_Variant(70, buf->getBit()); + vars["DIMLIM"]=new DRW_Variant(70, buf->getBit()); + vars["DIMTIH"]=new DRW_Variant(70, buf->getBit()); + vars["DIMTOH"]=new DRW_Variant(70, buf->getBit()); + vars["DIMSE1"]=new DRW_Variant(70, buf->getBit()); + vars["DIMSE2"]=new DRW_Variant(70, buf->getBit()); + vars["DIMTAD"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMZIN"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMAZIN"]=new DRW_Variant(70, buf->getBitShort()); + } + if (version > DRW::AC1018) {//2007+ + vars["DIMARCSYM"]=new DRW_Variant(70, buf->getBitShort()); + } + vars["DIMTXT"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMCEN"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMTSZ"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMALTF"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMLFAC"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMTVP"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMTFAC"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMGAP"]=new DRW_Variant(40, buf->getBitDouble()); + if (version < DRW::AC1015) {//r14- + vars["DIMPOST"]=new DRW_Variant(1, buf->getCP8Text()); + vars["DIMAPOST"]=new DRW_Variant(1, buf->getCP8Text()); + vars["DIMBLK"]=new DRW_Variant(1, buf->getCP8Text()); + vars["DIMBLK1"]=new DRW_Variant(1, buf->getCP8Text()); + vars["DIMBLK2"]=new DRW_Variant(1, buf->getCP8Text()); + } + if (version > DRW::AC1014) {//2000+ + vars["DIMALTRND"]=new DRW_Variant(40, buf->getBitDouble()); + vars["DIMALT"]=new DRW_Variant(70, buf->getBit()); + vars["DIMALTD"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMTOFL"]=new DRW_Variant(70, buf->getBit()); + vars["DIMSAH"]=new DRW_Variant(70, buf->getBit()); + vars["DIMTIX"]=new DRW_Variant(70, buf->getBit()); + vars["DIMSOXD"]=new DRW_Variant(70, buf->getBit()); + } + vars["DIMCLRD"]=new DRW_Variant(70, buf->getCmColor(version));//RLZ: TODO read CMC or EMC color + vars["DIMCLRE"]=new DRW_Variant(70, buf->getCmColor(version));//RLZ: TODO read CMC or EMC color + vars["DIMCLRT"]=new DRW_Variant(70, buf->getCmColor(version));//RLZ: TODO read CMC or EMC color + if (version > DRW::AC1014) {//2000+ + vars["DIAMDEC"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMDEC"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMTDEC"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMALTU"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMALTTD"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMAUNIT"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMFAC"]=new DRW_Variant(70, buf->getBitShort());///////////////// DIMFAC O DIMFRAC + vars["DIMLUNIT"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMDSEP"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMTMOVE"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMJUST"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMSD1"]=new DRW_Variant(70, buf->getBit()); + vars["DIMSD2"]=new DRW_Variant(70, buf->getBit()); + vars["DIMTOLJ"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMTZIN"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMALTZ"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMALTTZ"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMUPT"]=new DRW_Variant(70, buf->getBit()); + vars["DIMATFIT"]=new DRW_Variant(70, buf->getBitShort()); + } + if (version > DRW::AC1018) {//2007+ + vars["DIMFXLON"]=new DRW_Variant(70, buf->getBit());//////////////// + } + if (version > DRW::AC1021) {//2010+ + vars["DIMTXTDIRECTION"]=new DRW_Variant(70, buf->getBit());//////////////// + vars["DIMALTMZF"]=new DRW_Variant(40, buf->getBitDouble());//////////////// + vars["DIMMZF"]=new DRW_Variant(40, buf->getBitDouble());//////////////// + } + if (version > DRW::AC1014) {//2000+ + dwgHandle DIMTXSTY = hBbuf->getHandle(); + DRW_DBG("\nDIMTXSTY: "); DRW_DBGHL(DIMTXSTY.code, DIMTXSTY.size, DIMTXSTY.ref); + dwgHandle DIMLDRBLK = hBbuf->getHandle(); + DRW_DBG("\nDIMLDRBLK: "); DRW_DBGHL(DIMLDRBLK.code, DIMLDRBLK.size, DIMLDRBLK.ref); + dwgHandle DIMBLK = hBbuf->getHandle(); + DRW_DBG("\nDIMBLK: "); DRW_DBGHL(DIMBLK.code, DIMBLK.size, DIMBLK.ref); + dwgHandle DIMBLK1 = hBbuf->getHandle(); + DRW_DBG("\nDIMBLK1: "); DRW_DBGHL(DIMBLK1.code, DIMBLK1.size, DIMBLK1.ref); + dwgHandle DIMBLK2 = hBbuf->getHandle(); + DRW_DBG("\nDIMBLK2: "); DRW_DBGHL(DIMBLK2.code, DIMBLK2.size, DIMBLK2.ref); + } + if (version > DRW::AC1018) {//2007+ + dwgHandle DIMLTYPE = hBbuf->getHandle(); + DRW_DBG("\nDIMLTYPE: "); DRW_DBGHL(DIMLTYPE.code, DIMLTYPE.size, DIMLTYPE.ref); + dwgHandle DIMLTEX1 = hBbuf->getHandle(); + DRW_DBG("\nDIMLTEX1: "); DRW_DBGHL(DIMLTEX1.code, DIMLTEX1.size, DIMLTEX1.ref); + dwgHandle DIMLTEX2 = hBbuf->getHandle(); + DRW_DBG("\nDIMLTEX2: "); DRW_DBGHL(DIMLTEX2.code, DIMLTEX2.size, DIMLTEX2.ref); + } + if (version > DRW::AC1014) {//2000+ + vars["DIMLWD"]=new DRW_Variant(70, buf->getBitShort()); + vars["DIMLWE"]=new DRW_Variant(70, buf->getBitShort()); + } + dwgHandle CONTROL = hBbuf->getHandle(); + DRW_DBG("\nBLOCK CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + blockCtrl = CONTROL.ref; + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nLAYER CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + layerCtrl = CONTROL.ref; + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nSTYLE CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + styleCtrl = CONTROL.ref; + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nLINETYPE CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + linetypeCtrl = CONTROL.ref; + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nVIEW CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + viewCtrl = CONTROL.ref; + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nUCS CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + ucsCtrl = CONTROL.ref; + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nVPORT CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + vportCtrl = CONTROL.ref; + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nAPPID CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + appidCtrl = CONTROL.ref; + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nDIMSTYLE CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + dimstyleCtrl = CONTROL.ref; + if (version < DRW::AC1018) {//r2000- + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nVIEWPORT ENTITY HEADER CONTROL: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + vpEntHeaderCtrl = CONTROL.ref; //RLZ: only in R13-R15 ???? + } + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nDICT ACAD_GROUP: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nDICT ACAD_MLINESTYLE: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nDICT NAMED OBJS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + + if (version > DRW::AC1014) {//2000+ + vars["TSTACKALIGN"]=new DRW_Variant(70, buf->getBitShort()); + vars["TSTACKSIZE"]=new DRW_Variant(70, buf->getBitShort()); + if (version < DRW::AC1021) {//2004- + vars["HYPERLINKBASE"]=new DRW_Variant(1, buf->getCP8Text()); + vars["STYLESHEET"]=new DRW_Variant(1, buf->getCP8Text()); + } + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nDICT LAYOUTS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nDICT PLOTSETTINGS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nDICT PLOTSTYLES: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + } + if (version > DRW::AC1015) {//2004+ + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nDICT MATERIALS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nDICT COLORS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + } + if (version > DRW::AC1018) {//2007+ + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nDICT VISUALSTYLE: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + } + if (version > DRW::AC1024) {//2013+ + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nUNKNOWN HANDLE: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + } + if (version > DRW::AC1014) {//2000+ + DRW_DBG("\nFlags: "); DRW_DBGH(buf->getBitLong());//RLZ TODO change to 8 vars + vars["INSUNITS"]=new DRW_Variant(70, buf->getBitShort()); + duint16 cepsntype = buf->getBitShort(); + vars["CEPSNTYPE"]=new DRW_Variant(70, cepsntype); + if (cepsntype == 3){ + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nCPSNID HANDLE: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + } + if (version < DRW::AC1021) {//2004- + vars["FINGERPRINTGUID"]=new DRW_Variant(1, buf->getCP8Text()); + vars["VERSIONGUID"]=new DRW_Variant(1, buf->getCP8Text()); + } + } + if (version > DRW::AC1015) {//2004+ + vars["SORTENTS"]=new DRW_Variant(70, buf->getRawChar8()); + vars["INDEXCTL"]=new DRW_Variant(70, buf->getRawChar8()); + vars["HIDETEXT"]=new DRW_Variant(70, buf->getRawChar8()); + vars["XCLIPFRAME"]=new DRW_Variant(70, buf->getRawChar8()); + vars["DIMASSOC"]=new DRW_Variant(70, buf->getRawChar8()); + vars["HALOGAP"]=new DRW_Variant(70, buf->getRawChar8()); + vars["OBSCUREDCOLOR"]=new DRW_Variant(70, buf->getBitShort()); + vars["INTERSECTIONCOLOR"]=new DRW_Variant(70, buf->getBitShort()); + vars["OBSCUREDLTYPE"]=new DRW_Variant(70, buf->getRawChar8()); + vars["INTERSECTIONDISPLAY"]=new DRW_Variant(70, buf->getRawChar8()); + if (version < DRW::AC1021) {//2004- + vars["PROJECTNAME"]=new DRW_Variant(1, buf->getCP8Text()); + } + } + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nBLOCK PAPER_SPACE: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nBLOCK MODEL_SPACE: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nLTYPE BYLAYER: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nLTYPE BYBLOCK: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nLTYPE CONTINUOUS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + if (version > DRW::AC1018) {//2007+ + vars["CAMERADISPLAY"]=new DRW_Variant(70, buf->getBit()); + DRW_DBG("\nUnknown 2007+ long1: "); DRW_DBG(buf->getBitLong()); + DRW_DBG("\nUnknown 2007+ long2: "); DRW_DBG(buf->getBitLong()); + DRW_DBG("\nUnknown 2007+ double2: "); DRW_DBG(buf->getBitDouble()); + vars["STEPSPERSEC"]=new DRW_Variant(40, buf->getBitDouble()); + vars["STEPSIZE"]=new DRW_Variant(40, buf->getBitDouble()); + vars["3DDWFPREC"]=new DRW_Variant(40, buf->getBitDouble()); + vars["LENSLENGTH"]=new DRW_Variant(40, buf->getBitDouble()); + vars["CAMERAHEIGHT"]=new DRW_Variant(40, buf->getBitDouble()); + vars["SOLIDHIST"]=new DRW_Variant(70, buf->getRawChar8()); + vars["SHOWHIST"]=new DRW_Variant(70, buf->getRawChar8()); + vars["PSOLWIDTH"]=new DRW_Variant(40, buf->getBitDouble()); + vars["PSOLHEIGHT"]=new DRW_Variant(40, buf->getBitDouble()); + vars["LOFTANG1"]=new DRW_Variant(40, buf->getBitDouble()); + vars["LOFTANG2"]=new DRW_Variant(40, buf->getBitDouble()); + vars["LOFTMAG1"]=new DRW_Variant(40, buf->getBitDouble()); + vars["LOFTMAG2"]=new DRW_Variant(40, buf->getBitDouble()); + vars["LOFTPARAM"]=new DRW_Variant(70, buf->getBitShort()); + vars["LOFTNORMALS"]=new DRW_Variant(40, buf->getRawChar8()); + vars["LATITUDE"]=new DRW_Variant(40, buf->getBitDouble()); + vars["LONGITUDE"]=new DRW_Variant(40, buf->getBitDouble()); + vars["NORTHDIRECTION"]=new DRW_Variant(40, buf->getBitDouble()); + vars["TIMEZONE"]=new DRW_Variant(70, buf->getBitLong()); + vars["LIGHTGLYPHDISPLAY"]=new DRW_Variant(70, buf->getRawChar8()); + vars["TILEMODELIGHTSYNCH"]=new DRW_Variant(70, buf->getRawChar8()); + vars["DWFFRAME"]=new DRW_Variant(70, buf->getRawChar8()); + vars["DGNFRAME"]=new DRW_Variant(70, buf->getRawChar8()); + DRW_DBG("\nUnknown 2007+ BIT: "); DRW_DBG(buf->getBit()); + vars["INTERFERECOLOR"]=new DRW_Variant(70, buf->getCmColor(version)); + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nINTERFEREOBJVS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nINTERFEREVPVS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + CONTROL = hBbuf->getHandle(); + DRW_DBG("\nDRAGVS: "); DRW_DBGHL(CONTROL.code, CONTROL.size, CONTROL.ref); + vars["CSHADOW"]=new DRW_Variant(70, buf->getRawChar8()); + DRW_DBG("\nUnknown 2007+ double2: "); DRW_DBG(buf->getBitDouble()); + } + if (version > DRW::AC1012) {//R14+ + DRW_DBG("\nUnknown R14+ short1: "); DRW_DBG(buf->getBitShort()); + DRW_DBG("\nUnknown R14+ short2: "); DRW_DBG(buf->getBitShort()); + DRW_DBG("\nUnknown R14+ short3: "); DRW_DBG(buf->getBitShort()); + DRW_DBG("\nUnknown R14+ short4: "); DRW_DBG(buf->getBitShort()); + } + + DRW_DBG("\nbuf position: "); DRW_DBG(buf->getPosition()); + DRW_DBG(" buf bit position: "); DRW_DBG(buf->getBitPos()); + + + /**** RLZ: disabled, pending to read all data ***/ + //Start reading string stream for 2007 and further + if (version > DRW::AC1018) {//2007+ + duint32 strStartPos = endBitPos -1; + buf->setPosition(strStartPos >>3); + buf->setBitPos(strStartPos&7); + if (buf->getBit() == 1){ + strStartPos -= 16; + buf->setPosition(strStartPos >>3); + buf->setBitPos(strStartPos&7); + duint32 strDataSize = buf->getRawShort16(); + if (strDataSize & 0x8000) { + strStartPos -= 16;//decrement 16 bits + strDataSize &= 0x7FFF; //strip 0x8000; + buf->setPosition(strStartPos >> 3); + buf->setBitPos(strStartPos & 7); + duint32 hiSize = buf->getRawShort16(); + strDataSize |= (hiSize << 15); + } + strStartPos -= strDataSize; + buf->setPosition(strStartPos >> 3); + buf->setBitPos(strStartPos & 7); + + DRW_DBG("\nstring buf position: "); DRW_DBG(buf->getPosition()); + DRW_DBG("\nstring buf bit position: "); DRW_DBG(buf->getBitPos()); + } + DRW_DBG("\nUnknown text1: "); DRW_DBG(buf->getUCSText(false)); + DRW_DBG("\nUnknown text2: "); DRW_DBG(buf->getUCSText(false)); + DRW_DBG("\nUnknown text3: "); DRW_DBG(buf->getUCSText(false)); + DRW_DBG("\nUnknown text4: "); DRW_DBG(buf->getUCSText(false)); + vars["MENU"]=new DRW_Variant(1, buf->getUCSText(false)); + vars["DIMPOST"]=new DRW_Variant(1, buf->getUCSText(false)); + vars["DIMAPOST"]=new DRW_Variant(1, buf->getUCSText(false)); + if (version > DRW::AC1021) {//2010+ + vars["DIMALTMZS"]=new DRW_Variant(70, buf->getUCSText(false));//RLZ: pending to verify////////////// + vars["DIMMZS"]=new DRW_Variant(70, buf->getUCSText(false));//RLZ: pending to verify////////////// + } + vars["HYPERLINKBASE"]=new DRW_Variant(1, buf->getUCSText(false)); + vars["STYLESHEET"]=new DRW_Variant(1, buf->getUCSText(false)); + vars["FINGERPRINTGUID"]=new DRW_Variant(1, buf->getUCSText(false)); + DRW_DBG("\nstring buf position: "); DRW_DBG(buf->getPosition()); + DRW_DBG(" string buf bit position: "); DRW_DBG(buf->getBitPos()); + vars["VERSIONGUID"]=new DRW_Variant(1, buf->getUCSText(false)); + DRW_DBG("\nstring buf position: "); DRW_DBG(buf->getPosition()); + DRW_DBG(" string buf bit position: "); DRW_DBG(buf->getBitPos()); + vars["PROJECTNAME"]=new DRW_Variant(1, buf->getUCSText(false)); + } +/*** ****/ + DRW_DBG("\nstring buf position: "); DRW_DBG(buf->getPosition()); + DRW_DBG(" string buf bit position: "); DRW_DBG(buf->getBitPos()); + + if (DRW_DBGGL == DRW_dbg::DEBUG){ + for (std::map::iterator it=vars.begin(); it!=vars.end(); ++it){ + DRW_DBG("\n"); DRW_DBG(it->first); DRW_DBG(": "); + switch (it->second->type){ + case DRW_Variant::INTEGER: + DRW_DBG(it->second->content.i); + break; + case DRW_Variant::DOUBLE: + DRW_DBG(it->second->content.d); + break; + case DRW_Variant::STRING: + DRW_DBG(it->second->content.s->c_str()); + break; + case DRW_Variant::COORD: + DRW_DBG("x= "); DRW_DBG(it->second->content.v->x); + DRW_DBG(", y= "); DRW_DBG(it->second->content.v->y); + DRW_DBG(", z= "); DRW_DBG(it->second->content.v->z); + break; + default: + break; + } + DRW_DBG(" code: ");DRW_DBG(it->second->code); + } + } + + buf->setPosition(size+16+4); //read size +16 start sentinel + 4 size + if (version > DRW::AC1021 && mv > 3) { //2010+ + buf->getRawLong32();//advance 4 bytes (hisize) + } + DRW_DBG("\nseting position to: "); DRW_DBG(buf->getPosition()); + DRW_DBG("\nHeader CRC: "); DRW_DBGH(buf->getRawShort16()); + DRW_DBG("\nbuf position: "); DRW_DBG(buf->getPosition()); + DRW_DBG("\ndwg header end sentinel= "); + for (int i=0; i<16;i++) { + DRW_DBGH(buf->getRawChar8()); DRW_DBG(" "); + } + + //temporary code to show header end sentinel + duint64 sz= buf->size()-1; + if (version < DRW::AC1018) {//pre 2004 + sz= buf->size()-16; + buf->setPosition(sz); + DRW_DBG("\nseting position to: "); DRW_DBG(buf->getPosition()); + DRW_DBG("\ndwg header end sentinel= "); + for (int i=0; i<16;i++) { + DRW_DBGH(buf->getRawChar8()); DRW_DBG(" "); + } + } else if (version == DRW::AC1018) {//2004 +// sz= buf->size()-132; +// buf->setPosition(sz); + buf->moveBitPos(-128); + DRW_DBG("\nseting position to: "); DRW_DBG(buf->getPosition()); + DRW_DBG("\ndwg header end sentinel= "); + for (int i=0; i<16;i++) { + DRW_DBGH(buf->getRawChar8()); DRW_DBG(" "); + } + } else if (version == DRW::AC1021) {//2007 + sz= buf->size()-16; + buf->setPosition(sz); + DRW_DBG("\nseting position to: "); DRW_DBG(buf->getPosition()); + DRW_DBG("\ndwg header end sentinel= "); + for (int i=0; i<16;i++) { + DRW_DBGH(buf->getRawChar8()); DRW_DBG(" "); + } + } else if (version == DRW::AC1024) {//2010 +// sz= buf->size()-93; +// buf->setPosition(sz); + buf->moveBitPos(-128); + DRW_DBG("\nseting position to: "); DRW_DBG(buf->getPosition()); + DRW_DBG("\ndwg header end sentinel= "); + for (int i=0; i<16;i++) { + DRW_DBGH(buf->getRawChar8()); DRW_DBG(" "); + } + } else if (version == DRW::AC1027) {//2013 +// sz= buf->size()-76; +// buf->setPosition(sz); + buf->moveBitPos(-128); + DRW_DBG("\nseting position to: "); DRW_DBG(buf->getPosition()); + DRW_DBG("\ndwg header end sentinel= "); + for (int i=0; i<16;i++) { + DRW_DBGH(buf->getRawChar8()); DRW_DBG(" "); + } + } + + return result; +} diff --git a/extlib/libdxfrw/drw_header.h b/extlib/libdxfrw/drw_header.h new file mode 100644 index 0000000..a8fdc8e --- /dev/null +++ b/extlib/libdxfrw/drw_header.h @@ -0,0 +1,107 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DRW_HEADER_H +#define DRW_HEADER_H + + +#include +#include "drw_base.h" + +class dxfReader; +class dxfWriter; +class dwgBuffer; + +#define SETHDRFRIENDS friend class dxfRW; \ + friend class dwgReader; + +//! Class to handle header entries +/*! +* Class to handle header vars, to read iterate over "std::map vars" +* to write add a DRW_Variant* into "std::map vars" (do not delete it, are cleared in dtor) +* or use add* helper functions. +* @author Rallaz +*/ +class DRW_Header { + SETHDRFRIENDS +public: + DRW_Header(); + ~DRW_Header() { + clearVars(); + } + + DRW_Header(const DRW_Header& h){ + this->version = h.version; + this->comments = h.comments; + for (std::map::const_iterator it=h.vars.begin(); it!=h.vars.end(); ++it){ + this->vars[it->first] = new DRW_Variant( *(it->second) ); + } + this->curr = NULL; + } + DRW_Header& operator=(const DRW_Header &h) { + if(this != &h) { + clearVars(); + this->version = h.version; + this->comments = h.comments; + for (std::map::const_iterator it=h.vars.begin(); it!=h.vars.end(); ++it){ + this->vars[it->first] = new DRW_Variant( *(it->second) ); + } + } + return *this; + } + + void addDouble(std::string key, double value, int code); + void addInt(std::string key, int value, int code); + void addStr(std::string key, std::string value, int code); + void addCoord(std::string key, DRW_Coord value, int code); + std::string getComments() const {return comments;} + void write(dxfWriter *writer, DRW::Version ver); + void addComment(std::string c); + +protected: + void parseCode(int code, dxfReader *reader); + bool parseDwg(DRW::Version version, dwgBuffer *buf, dwgBuffer *hBbuf, duint8 mv=0); +private: + bool getDouble(std::string key, double *varDouble); + bool getInt(std::string key, int *varInt); + bool getStr(std::string key, std::string *varStr); + bool getCoord(std::string key, DRW_Coord *varStr); + void clearVars(){ + for (std::map::iterator it=vars.begin(); it!=vars.end(); ++it) + delete it->second; + + vars.clear(); + } + +public: + std::map vars; +private: + std::string comments; + std::string name; + DRW_Variant* curr; + int version; //to use on read + + duint32 linetypeCtrl; + duint32 layerCtrl; + duint32 styleCtrl; + duint32 dimstyleCtrl; + duint32 appidCtrl; + duint32 blockCtrl; + duint32 viewCtrl; + duint32 ucsCtrl; + duint32 vportCtrl; + duint32 vpEntHeaderCtrl; +}; + +#endif + +// EOF diff --git a/extlib/libdxfrw/drw_interface.h b/extlib/libdxfrw/drw_interface.h new file mode 100644 index 0000000..1b1577e --- /dev/null +++ b/extlib/libdxfrw/drw_interface.h @@ -0,0 +1,191 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DRW_INTERFACE_H +#define DRW_INTERFACE_H + +#include + +#include "drw_entities.h" +#include "drw_objects.h" +#include "drw_header.h" + +/** + * Abstract class (interface) for comunicate dxfReader with the application. + * Inherit your class which takes care of the entities in the + * processed DXF file from this interface. + * + * @author Rallaz + */ +class DRW_Interface { +public: + DRW_Interface() { + } + virtual ~DRW_Interface() { + } + + /** Called when header is parsed. */ + virtual void addHeader(const DRW_Header *) { } + + /** Called for every line Type. */ + virtual void addLType(const DRW_LType &) { } + /** Called for every layer. */ + virtual void addLayer(const DRW_Layer &) { } + /** Called for every dim style. */ + virtual void addDimStyle(const DRW_Dimstyle &) { } + /** Called for every VPORT table. */ + virtual void addVport(const DRW_Vport &) { } + /** Called for every text style. */ + virtual void addTextStyle(const DRW_Textstyle &) { } + /** Called for every AppId entry. */ + virtual void addAppId(const DRW_AppId &) { } + + /** + * Called for every block. Note: all entities added after this + * command go into this block until endBlock() is called. + * + * @see endBlock() + */ + virtual void addBlock(const DRW_Block &) { } + + /** Called to end the current block */ + virtual void endBlock() { } + + /** Called for every point */ + virtual void addPoint(const DRW_Point &) { } + + /** Called for every line */ + virtual void addLine(const DRW_Line &) { } + + /** Called for every ray */ + virtual void addRay(const DRW_Ray &) { } + + /** Called for every xline */ + virtual void addXline(const DRW_Xline &) { } + + /** Called for every arc */ + virtual void addArc(const DRW_Arc &) { } + + /** Called for every circle */ + virtual void addCircle(const DRW_Circle &) { } + + /** Called for every ellipse */ + virtual void addEllipse(const DRW_Ellipse &) { } + + /** Called for every lwpolyline */ + virtual void addLWPolyline(const DRW_LWPolyline &) { } + + /** Called for every polyline start */ + virtual void addPolyline(const DRW_Polyline &) { } + + /** Called for every spline */ + virtual void addSpline(const DRW_Spline *) { } + + /** Called for every spline knot value */ + virtual void addKnot(const DRW_Entity &) { } + + /** Called for every insert. */ + virtual void addInsert(const DRW_Insert &) { } + + /** Called for every trace start */ + virtual void addTrace(const DRW_Trace &) { } + + /** Called for every 3dface start */ + virtual void add3dFace(const DRW_3Dface &) { } + + /** Called for every solid start */ + virtual void addSolid(const DRW_Solid &) { } + + + /** Called for every Multi Text entity. */ + virtual void addMText(const DRW_MText &) { } + + /** Called for every Text entity. */ + virtual void addText(const DRW_Text &) { } + + /** + * Called for every aligned dimension entity. + */ + virtual void addDimAlign(const DRW_DimAligned *) { } + /** + * Called for every linear or rotated dimension entity. + */ + virtual void addDimLinear(const DRW_DimLinear *) { } + + /** + * Called for every radial dimension entity. + */ + virtual void addDimRadial(const DRW_DimRadial *) { } + + /** + * Called for every diametric dimension entity. + */ + virtual void addDimDiametric(const DRW_DimDiametric *) { } + + /** + * Called for every angular dimension (2 lines version) entity. + */ + virtual void addDimAngular(const DRW_DimAngular *) { } + + /** + * Called for every angular dimension (3 points version) entity. + */ + virtual void addDimAngular3P(const DRW_DimAngular3p *) { } + + /** + * Called for every ordinate dimension entity. + */ + virtual void addDimOrdinate(const DRW_DimOrdinate *) { } + + /** + * Called for every leader start. + */ + virtual void addLeader(const DRW_Leader *) { } + + /** + * Called for every hatch entity. + */ + virtual void addHatch(const DRW_Hatch *) { } + + /** + * Called for every viewport entity. + */ + virtual void addViewport(const DRW_Viewport &) { } + + /** + * Called for every image entity. + */ + virtual void addImage(const DRW_Image *) { } + + /** + * Called for every image definition. + */ + virtual void linkImage(const DRW_ImageDef *) { } + + /** + * Called for every comment in the DXF file (code 999). + */ + virtual void addComment(const char *) { } + + virtual void writeHeader(DRW_Header &) { } + virtual void writeBlocks() { } + virtual void writeBlockRecords() { } + virtual void writeEntities() { } + virtual void writeLTypes() { } + virtual void writeLayers() { } + virtual void writeTextstyles() { } + virtual void writeVports() { } + virtual void writeDimstyles() { } + virtual void writeAppId() { } +}; + +#endif diff --git a/extlib/libdxfrw/drw_objects.cpp b/extlib/libdxfrw/drw_objects.cpp new file mode 100644 index 0000000..e453a90 --- /dev/null +++ b/extlib/libdxfrw/drw_objects.cpp @@ -0,0 +1,1235 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include +#include +#include "drw_objects.h" +#include "intern/dxfreader.h" +#include "intern/dxfwriter.h" +#include "intern/dwgbuffer.h" +#include "intern/drw_dbg.h" +#include "intern/dwgutil.h" + +//! Base class for tables entries +/*! +* Base class for tables entries +* @author Rallaz +*/ +void DRW_TableEntry::parseCode(int code, dxfReader *reader){ + switch (code) { + case 5: + handle = reader->getHandleString(); + break; + case 330: + parentHandle = reader->getHandleString(); + break; + case 2: + name = reader->getUtf8String(); + break; + case 70: + flags = reader->getInt32(); + break; + case 1000: + case 1001: + case 1002: + case 1003: + case 1004: + case 1005: + extData.push_back(new DRW_Variant(code, reader->getString())); + break; + case 1010: + case 1011: + case 1012: + case 1013: + curr = new DRW_Variant(); + curr->addCoord(); + curr->setCoordX(reader->getDouble()); + curr->code = code; + extData.push_back(curr); + break; + case 1020: + case 1021: + case 1022: + case 1023: + if (curr) + curr->setCoordY(reader->getDouble()); + break; + case 1030: + case 1031: + case 1032: + case 1033: + if (curr) + curr->setCoordZ(reader->getDouble()); + curr=NULL; + break; + case 1040: + case 1041: + case 1042: + extData.push_back(new DRW_Variant(code, reader->getDouble())); + break; + case 1070: + case 1071: + extData.push_back(new DRW_Variant(code, reader->getInt32() )); + break; + default: + break; + } +} + +bool DRW_TableEntry::parseDwg(DRW::Version version, dwgBuffer *buf, dwgBuffer *strBuf, duint32 bs){ +DRW_DBG("\n***************************** parsing table entry *********************************************\n"); + objSize=0; + oType = buf->getObjType(version); + DRW_DBG("Object type: "); DRW_DBG(oType); DRW_DBG(", "); DRW_DBGH(oType); + if (version > DRW::AC1014 && version < DRW::AC1024) {//2000 to 2007 + objSize = buf->getRawLong32(); //RL 32bits object size in bits + DRW_DBG(" Object size: "); DRW_DBG(objSize); DRW_DBG("\n"); + } + if (version > DRW::AC1021) {//2010+ + duint32 ms = buf->size(); + objSize = ms*8 - bs; + DRW_DBG(" Object size: "); DRW_DBG(objSize); DRW_DBG("\n"); + } + if (strBuf != NULL && version > DRW::AC1018) {//2007+ + strBuf->moveBitPos(objSize-1); + DRW_DBG(" strBuf strbit pos 2007: "); DRW_DBG(strBuf->getPosition()); DRW_DBG(" strBuf bpos 2007: "); DRW_DBG(strBuf->getBitPos()); DRW_DBG("\n"); + if (strBuf->getBit() == 1){ + DRW_DBG("DRW_TableEntry::parseDwg string bit is 1\n"); + strBuf->moveBitPos(-17); + duint16 strDataSize = strBuf->getRawShort16(); + DRW_DBG("\nDRW_TableEntry::parseDwg string strDataSize: "); DRW_DBGH(strDataSize); DRW_DBG("\n"); + if ( (strDataSize& 0x8000) == 0x8000){ + DRW_DBG("\nDRW_TableEntry::parseDwg string 0x8000 bit is set"); + strBuf->moveBitPos(-33);//RLZ pending to verify + duint16 hiSize = strBuf->getRawShort16(); + strDataSize = ((strDataSize&0x7fff) | (hiSize<<15)); + } + strBuf->moveBitPos( -strDataSize -16); //-14 + DRW_DBG("strBuf start strDataSize pos 2007: "); DRW_DBG(strBuf->getPosition()); DRW_DBG(" strBuf bpos 2007: "); DRW_DBG(strBuf->getBitPos()); DRW_DBG("\n"); + } else + DRW_DBG("\nDRW_TableEntry::parseDwg string bit is 0"); + DRW_DBG("strBuf start pos 2007: "); DRW_DBG(strBuf->getPosition()); DRW_DBG(" strBuf bpos 2007: "); DRW_DBG(strBuf->getBitPos()); DRW_DBG("\n"); + } + + dwgHandle ho = buf->getHandle(); + handle = ho.ref; + DRW_DBG("TableEntry Handle: "); DRW_DBGHL(ho.code, ho.size, ho.ref); + dint16 extDataSize = buf->getBitShort(); //BS + DRW_DBG(" ext data size: "); DRW_DBG(extDataSize); + while (extDataSize>0 && buf->isGood()) { + /* RLZ: TODO */ + dwgHandle ah = buf->getHandle(); + DRW_DBG("App Handle: "); DRW_DBGHL(ah.code, ah.size, ah.ref); + duint8 *tmpExtData = new duint8[extDataSize]; + buf->getBytes(tmpExtData, extDataSize); + dwgBuffer tmpExtDataBuf(tmpExtData, extDataSize, buf->decoder); + int pos = tmpExtDataBuf.getPosition(); + int bpos = tmpExtDataBuf.getBitPos(); + DRW_DBG("ext data pos: "); DRW_DBG(pos); DRW_DBG("."); DRW_DBG(bpos); DRW_DBG("\n"); + duint8 dxfCode = tmpExtDataBuf.getRawChar8(); + DRW_DBG(" dxfCode: "); DRW_DBG(dxfCode); + switch (dxfCode){ + case 0:{ + duint8 strLength = tmpExtDataBuf.getRawChar8(); + DRW_DBG(" strLength: "); DRW_DBG(strLength); + duint16 cp = tmpExtDataBuf.getBERawShort16(); + DRW_DBG(" str codepage: "); DRW_DBG(cp); + for (int i=0;i< strLength+1;i++) {//string length + null terminating char + duint8 dxfChar = tmpExtDataBuf.getRawChar8(); + DRW_DBG(" dxfChar: "); DRW_DBG(dxfChar); + } + break; + } + default: + /* RLZ: TODO */ + break; + } + DRW_DBG("ext data pos: "); DRW_DBG(tmpExtDataBuf.getPosition()); DRW_DBG("."); DRW_DBG(tmpExtDataBuf.getBitPos()); DRW_DBG("\n"); + delete[]tmpExtData; + extDataSize = buf->getBitShort(); //BS + DRW_DBG(" ext data size: "); DRW_DBG(extDataSize); + } //end parsing extData (EED) + if (version < DRW::AC1015) {//14- + objSize = buf->getRawLong32(); //RL 32bits size in bits + } + DRW_DBG(" objSize in bits: "); DRW_DBG(objSize); + + numReactors = buf->getBitLong(); //BL + DRW_DBG(", numReactors: "); DRW_DBG(numReactors); DRW_DBG("\n"); + if (version > DRW::AC1015) {//2004+ + xDictFlag = buf->getBit(); + DRW_DBG("xDictFlag: "); DRW_DBG(xDictFlag); + } + if (version > DRW::AC1024) {//2013+ + duint8 bd = buf->getBit(); + DRW_DBG(" Have binary data: "); DRW_DBG(bd); DRW_DBG("\n"); + } + return buf->isGood(); +} + +//! Class to handle dimstyle entries +/*! +* Class to handle ldim style symbol table entries +* @author Rallaz +*/ +void DRW_Dimstyle::parseCode(int code, dxfReader *reader){ + switch (code) { + case 105: + handle = reader->getHandleString(); + break; + case 3: + dimpost = reader->getUtf8String(); + break; + case 4: + dimapost = reader->getUtf8String(); + break; + case 5: + dimblk = reader->getUtf8String(); + break; + case 6: + dimblk1 = reader->getUtf8String(); + break; + case 7: + dimblk2 = reader->getUtf8String(); + break; + case 40: + dimscale = reader->getDouble(); + break; + case 41: + dimasz = reader->getDouble(); + break; + case 42: + dimexo = reader->getDouble(); + break; + case 43: + dimdli = reader->getDouble(); + break; + case 44: + dimexe = reader->getDouble(); + break; + case 45: + dimrnd = reader->getDouble(); + break; + case 46: + dimdle = reader->getDouble(); + break; + case 47: + dimtp = reader->getDouble(); + break; + case 48: + dimtm = reader->getDouble(); + break; + case 49: + dimfxl = reader->getDouble(); + break; + case 140: + dimtxt = reader->getDouble(); + break; + case 141: + dimcen = reader->getDouble(); + break; + case 142: + dimtsz = reader->getDouble(); + break; + case 143: + dimaltf = reader->getDouble(); + break; + case 144: + dimlfac = reader->getDouble(); + break; + case 145: + dimtvp = reader->getDouble(); + break; + case 146: + dimtfac = reader->getDouble(); + break; + case 147: + dimgap = reader->getDouble(); + break; + case 148: + dimaltrnd = reader->getDouble(); + break; + case 71: + dimtol = reader->getInt32(); + break; + case 72: + dimlim = reader->getInt32(); + break; + case 73: + dimtih = reader->getInt32(); + break; + case 74: + dimtoh = reader->getInt32(); + break; + case 75: + dimse1 = reader->getInt32(); + break; + case 76: + dimse2 = reader->getInt32(); + break; + case 77: + dimtad = reader->getInt32(); + break; + case 78: + dimzin = reader->getInt32(); + break; + case 79: + dimazin = reader->getInt32(); + break; + case 170: + dimalt = reader->getInt32(); + break; + case 171: + dimaltd = reader->getInt32(); + break; + case 172: + dimtofl = reader->getInt32(); + break; + case 173: + dimsah = reader->getInt32(); + break; + case 174: + dimtix = reader->getInt32(); + break; + case 175: + dimsoxd = reader->getInt32(); + break; + case 176: + dimclrd = reader->getInt32(); + break; + case 177: + dimclre = reader->getInt32(); + break; + case 178: + dimclrt = reader->getInt32(); + break; + case 179: + dimadec = reader->getInt32(); + break; + case 270: + dimunit = reader->getInt32(); + break; + case 271: + dimdec = reader->getInt32(); + break; + case 272: + dimtdec = reader->getInt32(); + break; + case 273: + dimaltu = reader->getInt32(); + break; + case 274: + dimalttd = reader->getInt32(); + break; + case 275: + dimaunit = reader->getInt32(); + break; + case 276: + dimfrac = reader->getInt32(); + break; + case 277: + dimlunit = reader->getInt32(); + break; + case 278: + dimdsep = reader->getInt32(); + break; + case 279: + dimtmove = reader->getInt32(); + break; + case 280: + dimjust = reader->getInt32(); + break; + case 281: + dimsd1 = reader->getInt32(); + break; + case 282: + dimsd2 = reader->getInt32(); + break; + case 283: + dimtolj = reader->getInt32(); + break; + case 284: + dimtzin = reader->getInt32(); + break; + case 285: + dimaltz = reader->getInt32(); + break; + case 286: + dimaltttz = reader->getInt32(); + break; + case 287: + dimfit = reader->getInt32(); + break; + case 288: + dimupt = reader->getInt32(); + break; + case 289: + dimatfit = reader->getInt32(); + break; + case 290: + dimfxlon = reader->getInt32(); + break; + case 340: + dimtxsty = reader->getUtf8String(); + break; + case 341: + dimldrblk = reader->getUtf8String(); + break; + case 342: + dimblk = reader->getUtf8String(); + break; + case 343: + dimblk1 = reader->getUtf8String(); + break; + case 344: + dimblk2 = reader->getUtf8String(); + break; + default: + DRW_TableEntry::parseCode(code, reader); + break; + } +} + +bool DRW_Dimstyle::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); + DRW_DBG("\n***************************** parsing dimension style **************************************\n"); + if (!ret) + return ret; + name = sBuf->getVariableText(version, false); + DRW_DBG("dimension style name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); + +// handleObj = shpControlH.ref; + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + // RS crc; //RS */ + return buf->isGood(); +} + + +//! Class to handle line type entries +/*! +* Class to handle line type symbol table entries +* @author Rallaz +*/ +void DRW_LType::parseCode(int code, dxfReader *reader){ + switch (code) { + case 3: + desc = reader->getUtf8String(); + break; + case 73: + size = reader->getInt32(); + path.reserve(size); + break; + case 40: + length = reader->getDouble(); + break; + case 49: + path.push_back(reader->getDouble()); + pathIdx++; + break; +/* case 74: + haveShape = reader->getInt32(); + break;*/ + default: + DRW_TableEntry::parseCode(code, reader); + break; + } +} + +//! Update line type +/*! +* Update the size and length of line type according to the path +* @author Rallaz +*/ +/*TODO: control max length permited */ +void DRW_LType::update(){ + double d =0; + size = (int)path.size(); + for (int i = 0; i< size; i++){ + d += fabs(path.at(i)); + } + length = d; +} + +bool DRW_LType::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); + DRW_DBG("\n***************************** parsing line type *********************************************\n"); + if (!ret) + return ret; + name = sBuf->getVariableText(version, false); + DRW_DBG("linetype name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); + flags = buf->getBit()<< 6; + DRW_DBG("flags: "); DRW_DBG(flags); + if (version > DRW::AC1018) {//2007+ + } else {//2004- //RLZ: verify in 2004, 2010 &2013 + dint16 xrefindex = buf->getBitShort(); + DRW_DBG(" xrefindex: "); DRW_DBG(xrefindex); + } + duint8 xdep = buf->getBit(); + DRW_DBG(" xdep: "); DRW_DBG(xdep); + flags |= xdep<< 4; + DRW_DBG(" flags: "); DRW_DBG(flags); + desc = sBuf->getVariableText(version, false); + DRW_DBG(" desc: "); DRW_DBG(desc.c_str()); + length = buf->getBitDouble(); + DRW_DBG(" pattern length: "); DRW_DBG(length); + char align = buf->getRawChar8(); + DRW_DBG(" align: "); DRW_DBG(std::string(&align, 1)); + size = buf->getRawChar8(); + DRW_DBG(" num dashes, size: "); DRW_DBG(size); + DRW_DBG("\n dashes:\n"); + bool haveStrArea = false; + for (int i=0; i< size; i++){ + path.push_back(buf->getBitDouble()); + /*int bs1 =*/ buf->getBitShort(); + /*double d1= */buf->getRawDouble(); + /*double d2=*/ buf->getRawDouble(); + /*double d3= */buf->getBitDouble(); + /*double d4= */buf->getBitDouble(); + int bs2 = buf->getBitShort(); + if((bs2 & 2) !=0) haveStrArea = true; + } + for (unsigned i=0; inumRemainingBytes()); DRW_DBG("\n"); + if (version < DRW::AC1021) { //2004- + duint8 strarea[256]; + buf->getBytes(strarea, 256); + DRW_DBG("string area 256 bytes:\n"); DRW_DBG(reinterpret_cast(strarea)); DRW_DBG("\n"); + } else { //2007+ + //first verify flag + if (haveStrArea) { + duint8 strarea[512]; + buf->getBytes(strarea, 512); + DRW_DBG("string area 512 bytes:\n"); DRW_DBG(reinterpret_cast(strarea)); DRW_DBG("\n"); + } else + DRW_DBG("string area 512 bytes not present\n"); + } + + if (version > DRW::AC1021) {//2007+ skip string area + DRW_DBG(" ltype end of object data pos 2010: "); DRW_DBG(buf->getPosition()); DRW_DBG(" strBuf bpos 2007: "); DRW_DBG(buf->getBitPos()); DRW_DBG("\n"); + } + if (version > DRW::AC1018) {//2007+ skip string area + buf->setPosition(objSize >> 3); + buf->setBitPos(objSize & 7); + } + + if (version > DRW::AC1021) {//2007+ skip string area + DRW_DBG(" ltype start of handles data pos 2010: "); DRW_DBG(buf->getPosition()); DRW_DBG(" strBuf bpos 2007: "); DRW_DBG(buf->getBitPos()); DRW_DBG("\n"); + } + + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + dwgHandle ltControlH = buf->getHandle(); + DRW_DBG("linetype control Handle: "); DRW_DBGHL(ltControlH.code, ltControlH.size, ltControlH.ref); + parentHandle = ltControlH.ref; + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + for (int i=0; i< numReactors;++i) { + dwgHandle reactorsH = buf->getHandle(); + DRW_DBG(" reactorsH control Handle: "); DRW_DBGHL(reactorsH.code, reactorsH.size, reactorsH.ref); DRW_DBG("\n"); + } + if (xDictFlag !=1){//linetype in 2004 seems not have XDicObjH or NULL handle + dwgHandle XDicObjH = buf->getHandle(); + DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } + if(size>0){ + dwgHandle XRefH = buf->getHandle(); + DRW_DBG(" XRefH control Handle: "); DRW_DBGHL(XRefH.code, XRefH.size, XRefH.ref); DRW_DBG("\n"); + dwgHandle shpHandle = buf->getHandle(); + DRW_DBG(" shapeFile Handle: "); DRW_DBGHL(shpHandle.code, shpHandle.size, shpHandle.ref); + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } + dwgHandle shpHandle = buf->getHandle(); + DRW_DBG(" shapeFile +1 Handle ??: "); DRW_DBGHL(shpHandle.code, shpHandle.size, shpHandle.ref); DRW_DBG("\n"); + + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); +// RS crc; //RS */ + return buf->isGood(); +} + +//! Class to handle layer entries +/*! +* Class to handle layer symbol table entries +* @author Rallaz +*/ +void DRW_Layer::parseCode(int code, dxfReader *reader){ + switch (code) { + case 6: + lineType = reader->getUtf8String(); + break; + case 62: + color = reader->getInt32(); + break; + case 290: + plotF = reader->getBool(); + break; + case 370: + lWeight = DRW_LW_Conv::dxfInt2lineWidth(reader->getInt32()); + break; + case 390: + handlePlotS = reader->getString(); + break; + case 347: + handleMaterialS = reader->getString(); + break; + case 420: + color24 = reader->getInt32(); + break; + default: + DRW_TableEntry::parseCode(code, reader); + break; + } +} + +bool DRW_Layer::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); + DRW_DBG("\n***************************** parsing layer *********************************************\n"); + if (!ret) + return ret; + name = sBuf->getVariableText(version, false); + DRW_DBG("layer name: "); DRW_DBG(name.c_str()); + + flags |= buf->getBit()<< 6;//layer have entity + if (version < DRW::AC1021) {//2004- + DRW_DBG(", xrefindex = "); DRW_DBG(buf->getBitShort()); DRW_DBG("\n"); + //dint16 xrefindex = buf->getBitShort(); + } + flags |= buf->getBit() << 4;//is refx dependent + if (version < DRW::AC1015) {//14- + flags |= buf->getBit(); //layer frozen + /*flags |=*/ buf->getBit(); //unused, negate the color + flags |= buf->getBit() << 1;//frozen in new + flags |= buf->getBit()<< 3;//locked + } + if (version > DRW::AC1014) {//2000+ + dint16 f = buf->getSBitShort();//bit2 are layer on + DRW_DBG(", flags 2000+: "); DRW_DBG(f); DRW_DBG("\n"); + flags |= f & 0x0001; //layer frozen + flags |= ( f>> 1) & 0x0002;//frozen in new + flags |= ( f>> 1) & 0x0004;//locked + plotF = ( f>> 4) & 0x0001; + lWeight = DRW_LW_Conv::dwgInt2lineWidth( (f & 0x03E0) >> 5 ); + } + color = buf->getCmColor(version); //BS or CMC //ok for R14 or negate + DRW_DBG(", entity color: "); DRW_DBG(color); DRW_DBG("\n"); + + if (version > DRW::AC1018) {//2007+ skip string area + buf->setPosition(objSize >> 3); + buf->setBitPos(objSize & 7); + } + dwgHandle layerControlH = buf->getHandle(); + DRW_DBG("layer control Handle: "); DRW_DBGHL(layerControlH.code, layerControlH.size, layerControlH.ref); + parentHandle = layerControlH.ref; + + if (xDictFlag !=1){//linetype in 2004 seems not have XDicObjH or NULL handle + dwgHandle XDicObjH = buf->getHandle(); + DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); + } + dwgHandle XRefH = buf->getHandle(); + DRW_DBG(" XRefH control Handle: "); DRW_DBGHL(XRefH.code, XRefH.size, XRefH.ref); DRW_DBG("\n"); + if (version > DRW::AC1014) {//2000+ + dwgHandle plotStyH = buf->getHandle(); + DRW_DBG(" PLot style control Handle: "); DRW_DBGHL(plotStyH.code, plotStyH.size, plotStyH.ref); DRW_DBG("\n"); + handlePlotS = DRW::toHexStr(plotStyH.ref);// std::string(plotStyH.ref);//RLZ: verify conversion + } + if (version > DRW::AC1018) {//2007+ + dwgHandle materialH = buf->getHandle(); + DRW_DBG(" Material control Handle: "); DRW_DBGHL(materialH.code, materialH.size, materialH.ref); DRW_DBG("\n"); + handleMaterialS = DRW::toHexStr(materialH.ref);//RLZ: verify conversion + } + //lineType handle + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + lTypeH = buf->getHandle(); + DRW_DBG("line type Handle: "); DRW_DBGHL(lTypeH.code, lTypeH.size, lTypeH.ref); + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); +// RS crc; //RS */ + return buf->isGood(); +} + +bool DRW_Block_Record::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); + DRW_DBG("\n***************************** parsing block record ******************************************\n"); + if (!ret) + return ret; + duint32 insertCount = 0;//only 2000+ + duint32 objectCount = 0; //only 2004+ + + name = sBuf->getVariableText(version, false); + DRW_DBG("block record name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); + + flags |= buf->getBit()<< 6;//referenced external reference, block code 70, bit 7 (64) + if (version > DRW::AC1018) {//2007+ + } else {//2004- //RLZ: verify in 2004, 2010 &2013 + dint16 xrefindex = buf->getBitShort(); + DRW_DBG(" xrefindex: "); DRW_DBG(xrefindex); DRW_DBG("\n"); + } + flags |= buf->getBit() << 4;//is refx dependent, block code 70, bit 5 (16) + flags |= buf->getBit(); //if is anonimous block (*U) block code 70, bit 1 (1) + flags |= buf->getBit() << 1; //if block contains attdefs, block code 70, bit 2 (2) + bool blockIsXref = buf->getBit(); //if is a Xref, block code 70, bit 3 (4) + bool xrefOverlaid = buf->getBit(); //if is a overlaid Xref, block code 70, bit 4 (8) + flags |= blockIsXref << 2; //if is a Xref, block code 70, bit 3 (4) + flags |= xrefOverlaid << 3; //if is a overlaid Xref, block code 70, bit 4 (8) + if (version > DRW::AC1014) {//2000+ + flags |= buf->getBit() << 5; //if is a loaded Xref, block code 70, bit 6 (32) + } + DRW_DBG("flags: "); DRW_DBG(flags); DRW_DBG(", "); + if (version > DRW::AC1015) {//2004+ fails in 2007 + objectCount = buf->getBitLong(); //Number of objects owned by this block + entMap.reserve(objectCount); + } + basePoint.x = buf->getBitDouble(); + basePoint.y = buf->getBitDouble(); + basePoint.z = buf->getBitDouble(); + DRW_DBG("insertion point: "); DRW_DBGPT(basePoint.x, basePoint.y, basePoint.z); DRW_DBG("\n"); + UTF8STRING path = sBuf->getVariableText(version, false); + DRW_DBG("XRef path name: "); DRW_DBG(path.c_str()); DRW_DBG("\n"); + + if (version > DRW::AC1014) {//2000+ + insertCount = 0; + while (duint8 i = buf->getRawChar8() != 0) + insertCount +=i; + UTF8STRING bkdesc = sBuf->getVariableText(version, false); + DRW_DBG("Block description: "); DRW_DBG(bkdesc.c_str()); DRW_DBG("\n"); + + duint32 prevData = buf->getBitLong(); + for (unsigned int j= 0; j < prevData; ++j) + buf->getRawChar8(); + } + if (version > DRW::AC1018) {//2007+ + duint16 insUnits = buf->getBitShort(); + bool canExplode = buf->getBit(); //if block can be exploded + duint8 bkScaling = buf->getRawChar8(); + + DRW_UNUSED(insUnits); + DRW_UNUSED(canExplode); + DRW_UNUSED(bkScaling); + } + + if (version > DRW::AC1018) {//2007+ skip string area + buf->setPosition(objSize >> 3); + buf->setBitPos(objSize & 7); + } + + dwgHandle blockControlH = buf->getHandle(); + DRW_DBG("block control Handle: "); DRW_DBGHL(blockControlH.code, blockControlH.size, blockControlH.ref); DRW_DBG("\n"); + parentHandle = blockControlH.ref; + + for (int i=0; igetHandle(); + DRW_DBG(" reactor Handle #"); DRW_DBG(i); DRW_DBG(": "); DRW_DBGHL(reactorH.code, reactorH.size, reactorH.ref); DRW_DBG("\n"); + } + if (xDictFlag !=1) {//R14+ //seems present in 2000 + dwgHandle XDicObjH = buf->getHandle(); + DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); + } + if (version != DRW::AC1021) {//2007+ XDicObjH or NullH not present + } + dwgHandle NullH = buf->getHandle(); + DRW_DBG(" NullH control Handle: "); DRW_DBGHL(NullH.code, NullH.size, NullH.ref); DRW_DBG("\n"); + dwgHandle blockH = buf->getOffsetHandle(handle); + DRW_DBG(" blockH Handle: "); DRW_DBGHL(blockH.code, blockH.size, blockH.ref); DRW_DBG("\n"); + block = blockH.ref; + + if (version > DRW::AC1015) {//2004+ + for (unsigned int i=0; i< objectCount; i++){ + dwgHandle entityH = buf->getHandle(); + DRW_DBG(" entityH Handle #"); DRW_DBG(i); DRW_DBG(": "); DRW_DBGHL(entityH.code, entityH.size, entityH.ref); DRW_DBG("\n"); + entMap.push_back(entityH.ref); + } + } else {//2000- + if(!blockIsXref && !xrefOverlaid){ + dwgHandle firstH = buf->getHandle(); + DRW_DBG(" firstH entity Handle: "); DRW_DBGHL(firstH.code, firstH.size, firstH.ref); DRW_DBG("\n"); + firstEH = firstH.ref; + dwgHandle lastH = buf->getHandle(); + DRW_DBG(" lastH entity Handle: "); DRW_DBGHL(lastH.code, lastH.size, lastH.ref); DRW_DBG("\n"); + lastEH = lastH.ref; + } + } + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + dwgHandle endBlockH = buf->getOffsetHandle(handle); + DRW_DBG(" endBlockH Handle: "); DRW_DBGHL(endBlockH.code, endBlockH.size, endBlockH.ref); DRW_DBG("\n"); + endBlock = endBlockH.ref; + + if (version > DRW::AC1014) {//2000+ + for (unsigned int i=0; i< insertCount; i++){ + dwgHandle insertsH = buf->getHandle(); + DRW_DBG(" insertsH Handle #"); DRW_DBG(i); DRW_DBG(": "); DRW_DBGHL(insertsH.code, insertsH.size, insertsH.ref); DRW_DBG("\n"); + } + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + dwgHandle layoutH = buf->getHandle(); + DRW_DBG(" layoutH Handle: "); DRW_DBGHL(layoutH.code, layoutH.size, layoutH.ref); DRW_DBG("\n"); + } + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n\n"); +// RS crc; //RS */ + return buf->isGood(); +} + +//! Class to handle text style entries +/*! +* Class to handle text style symbol table entries +* @author Rallaz +*/ +void DRW_Textstyle::parseCode(int code, dxfReader *reader){ + switch (code) { + case 3: + font = reader->getUtf8String(); + break; + case 4: + bigFont = reader->getUtf8String(); + break; + case 40: + height = reader->getDouble(); + break; + case 41: + width = reader->getDouble(); + break; + case 50: + oblique = reader->getDouble(); + break; + case 42: + lastHeight = reader->getDouble(); + break; + case 71: + genFlag = reader->getInt32(); + break; + case 1071: + fontFamily = reader->getInt32(); + break; + default: + DRW_TableEntry::parseCode(code, reader); + break; + } +} + +bool DRW_Textstyle::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); + DRW_DBG("\n***************************** parsing text style *********************************************\n"); + if (!ret) + return ret; + name = sBuf->getVariableText(version, false); + DRW_DBG("text style name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); + flags |= buf->getBit()<< 6;//style are referenced for a entity, style code 70, bit 7 (64) + /*dint16 xrefindex =*/ buf->getBitShort(); + flags |= buf->getBit() << 4; //is refx dependent, style code 70, bit 5 (16) + flags |= buf->getBit() << 2; //vertical text, stile code 70, bit 3 (4) + flags |= buf->getBit(); //if is a shape file instead of text, style code 70, bit 1 (1) + height = buf->getBitDouble(); + width = buf->getBitDouble(); + oblique = buf->getBitDouble(); + genFlag = buf->getRawChar8(); + lastHeight = buf->getBitDouble(); + font = sBuf->getVariableText(version, false); + bigFont = sBuf->getVariableText(version, false); + if (version > DRW::AC1018) {//2007+ skip string area + buf->setPosition(objSize >> 3); + buf->setBitPos(objSize & 7); + } + dwgHandle shpControlH = buf->getHandle(); + DRW_DBG(" parentControlH Handle: "); DRW_DBGHL(shpControlH.code, shpControlH.size, shpControlH.ref); DRW_DBG("\n"); + parentHandle = shpControlH.ref; + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + if (xDictFlag !=1){//linetype in 2004 seems not have XDicObjH or NULL handle + dwgHandle XDicObjH = buf->getHandle(); + DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } +/*RLZ: fails verify this part*/ dwgHandle XRefH = buf->getHandle(); + DRW_DBG(" XRefH control Handle: "); DRW_DBGHL(XRefH.code, XRefH.size, XRefH.ref); DRW_DBG("\n"); + + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n\n"); + // RS crc; //RS */ + return buf->isGood(); +} + +//! Class to handle vport entries +/*! +* Class to handle vport symbol table entries +* @author Rallaz +*/ +void DRW_Vport::parseCode(int code, dxfReader *reader){ + switch (code) { + case 10: + lowerLeft.x = reader->getDouble(); + break; + case 20: + lowerLeft.y = reader->getDouble(); + break; + case 11: + UpperRight.x = reader->getDouble(); + break; + case 21: + UpperRight.y = reader->getDouble(); + break; + case 12: + center.x = reader->getDouble(); + break; + case 22: + center.y = reader->getDouble(); + break; + case 13: + snapBase.x = reader->getDouble(); + break; + case 23: + snapBase.y = reader->getDouble(); + break; + case 14: + snapSpacing.x = reader->getDouble(); + break; + case 24: + snapSpacing.y = reader->getDouble(); + break; + case 15: + gridSpacing.x = reader->getDouble(); + break; + case 25: + gridSpacing.y = reader->getDouble(); + break; + case 16: + viewDir.x = reader->getDouble(); + break; + case 26: + viewDir.y = reader->getDouble(); + break; + case 36: + viewDir.z = reader->getDouble(); + break; + case 17: + viewTarget.x = reader->getDouble(); + break; + case 27: + viewTarget.y = reader->getDouble(); + break; + case 37: + viewTarget.z = reader->getDouble(); + break; + case 40: + height = reader->getDouble(); + break; + case 41: + ratio = reader->getDouble(); + break; + case 42: + lensHeight = reader->getDouble(); + break; + case 43: + frontClip = reader->getDouble(); + break; + case 44: + backClip = reader->getDouble(); + break; + case 50: + snapAngle = reader->getDouble(); + break; + case 51: + twistAngle = reader->getDouble(); + break; + case 71: + viewMode = reader->getInt32(); + break; + case 72: + circleZoom = reader->getInt32(); + break; + case 73: + fastZoom = reader->getInt32(); + break; + case 74: + ucsIcon = reader->getInt32(); + break; + case 75: + snap = reader->getInt32(); + break; + case 76: + grid = reader->getInt32(); + break; + case 77: + snapStyle = reader->getInt32(); + break; + case 78: + snapIsopair = reader->getInt32(); + break; + default: + DRW_TableEntry::parseCode(code, reader); + break; + } +} + +bool DRW_Vport::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); + DRW_DBG("\n***************************** parsing VPort ************************************************\n"); + if (!ret) + return ret; + name = sBuf->getVariableText(version, false); + DRW_DBG("vport name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); + flags |= buf->getBit()<< 6;// code 70, bit 7 (64) + if (version < DRW::AC1021) { //2004- + /*dint16 xrefindex =*/ buf->getBitShort(); + } + flags |= buf->getBit() << 4; //is refx dependent, style code 70, bit 5 (16) + height = buf->getBitDouble(); + ratio = buf->getBitDouble(); + DRW_DBG("flags: "); DRW_DBG(flags); DRW_DBG(" height: "); DRW_DBG(height); + DRW_DBG(" ratio: "); DRW_DBG(ratio); + center = buf->get2RawDouble(); + DRW_DBG("\nview center: "); DRW_DBGPT(center.x, center.y, center.z); + viewTarget.x = buf->getBitDouble(); + viewTarget.y = buf->getBitDouble(); + viewTarget.z = buf->getBitDouble(); + DRW_DBG("\nview target: "); DRW_DBGPT(viewTarget.x, viewTarget.y, viewTarget.z); + viewDir.x = buf->getBitDouble(); + viewDir.y = buf->getBitDouble(); + viewDir.z = buf->getBitDouble(); + DRW_DBG("\nview dir: "); DRW_DBGPT(viewDir.x, viewDir.y, viewDir.z); + twistAngle = buf->getBitDouble(); + lensHeight = buf->getBitDouble(); + frontClip = buf->getBitDouble(); + backClip = buf->getBitDouble(); + DRW_DBG("\ntwistAngle: "); DRW_DBG(twistAngle); DRW_DBG(" lensHeight: "); DRW_DBG(lensHeight); + DRW_DBG(" frontClip: "); DRW_DBG(frontClip); DRW_DBG(" backClip: "); DRW_DBG(backClip); + viewMode = buf->getBit(); //view mode, code 71, bit 0 (1) + viewMode |= buf->getBit() << 1; //view mode, code 71, bit 1 (2) + viewMode |= buf->getBit() << 2; //view mode, code 71, bit 2 (4) + viewMode |= buf->getBit() << 4; //view mode, code 71, bit 4 (16) + if (version > DRW::AC1014) { //2000+ + //duint8 renderMode = buf->getRawChar8(); + DRW_DBG("\n renderMode: "); DRW_DBG(buf->getRawChar8()); + if (version > DRW::AC1018) { //2007+ + DRW_DBG("\n use default lights: "); DRW_DBG(buf->getBit()); + DRW_DBG(" default lighting type: "); DRW_DBG(buf->getRawChar8()); + DRW_DBG(" brightness: "); DRW_DBG(buf->getBitDouble()); + DRW_DBG("\n contrast: "); DRW_DBG(buf->getBitDouble()); DRW_DBG("\n"); + DRW_DBG(" ambient color CMC: "); DRW_DBG(buf->getCmColor(version)); + } + } + lowerLeft = buf->get2RawDouble(); + DRW_DBG("\nlowerLeft: "); DRW_DBGPT(lowerLeft.x, lowerLeft.y, lowerLeft.z); + UpperRight = buf->get2RawDouble(); + DRW_DBG("\nUpperRight: "); DRW_DBGPT(UpperRight.x, UpperRight.y, UpperRight.z); + viewMode |= buf->getBit() << 3; //UCSFOLLOW, view mode, code 71, bit 3 (8) + circleZoom = buf->getBitShort(); + fastZoom = buf->getBit(); + DRW_DBG("\nviewMode: "); DRW_DBG(viewMode); DRW_DBG(" circleZoom: "); + DRW_DBG(circleZoom); DRW_DBG(" fastZoom: "); DRW_DBG(fastZoom); + ucsIcon = buf->getBit(); //ucs Icon, code 74, bit 0 (1) + ucsIcon |= buf->getBit() << 1; //ucs Icon, code 74, bit 1 (2) + grid = buf->getBit(); + DRW_DBG("\nucsIcon: "); DRW_DBG(ucsIcon); DRW_DBG(" grid: "); DRW_DBG(grid); + gridSpacing = buf->get2RawDouble(); + DRW_DBG("\ngrid Spacing: "); DRW_DBGPT(gridSpacing.x, gridSpacing.y, gridSpacing.z); + snap = buf->getBit(); + snapStyle = buf->getBit(); + DRW_DBG("\nsnap on/off: "); DRW_DBG(snap); DRW_DBG(" snap Style: "); DRW_DBG(snapStyle); + snapIsopair = buf->getBitShort(); + snapAngle = buf->getBitDouble(); + DRW_DBG("\nsnap Isopair: "); DRW_DBG(snapIsopair); DRW_DBG(" snap Angle: "); DRW_DBG(snapAngle); + snapBase = buf->get2RawDouble(); + DRW_DBG("\nsnap Base: "); DRW_DBGPT(snapBase.x, snapBase.y, snapBase.z); + snapSpacing = buf->get2RawDouble(); + DRW_DBG("\nsnap Spacing: "); DRW_DBGPT(snapSpacing.x, snapSpacing.y, snapSpacing.z); + if (version > DRW::AC1014) { //2000+ + DRW_DBG("\n Unknown: "); DRW_DBG(buf->getBit()); + DRW_DBG(" UCS per Viewport: "); DRW_DBG(buf->getBit()); + DRW_DBG("\nUCS origin: "); DRW_DBGPT(buf->getBitDouble(), buf->getBitDouble(), buf->getBitDouble()); + DRW_DBG("\nUCS X Axis: "); DRW_DBGPT(buf->getBitDouble(), buf->getBitDouble(), buf->getBitDouble()); + DRW_DBG("\nUCS Y Axis: "); DRW_DBGPT(buf->getBitDouble(), buf->getBitDouble(), buf->getBitDouble()); + DRW_DBG("\nUCS elevation: "); DRW_DBG(buf->getBitDouble()); + DRW_DBG(" UCS Orthographic type: "); DRW_DBG(buf->getBitShort()); + if (version > DRW::AC1018) { //2007+ + gridBehavior = buf->getBitShort(); + DRW_DBG(" gridBehavior (flags): "); DRW_DBG(gridBehavior); + DRW_DBG(" Grid major: "); DRW_DBG(buf->getBitShort()); + } + } + + //common handles + if (version > DRW::AC1018) {//2007+ skip string area + buf->setPosition(objSize >> 3); + buf->setBitPos(objSize & 7); + } + dwgHandle vpControlH = buf->getHandle(); + DRW_DBG("\n parentControlH Handle: "); DRW_DBGHL(vpControlH.code, vpControlH.size, vpControlH.ref); DRW_DBG("\n"); + parentHandle = vpControlH.ref; + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + if (xDictFlag !=1){ + dwgHandle XDicObjH = buf->getHandle(); + DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } +/*RLZ: fails verify this part*/ dwgHandle XRefH = buf->getHandle(); + DRW_DBG(" XRefH control Handle: "); DRW_DBGHL(XRefH.code, XRefH.size, XRefH.ref); + + if (version > DRW::AC1014) { //2000+ + DRW_DBG("\nRemaining bytes: "); DRW_DBG(buf->numRemainingBytes()); + if (version > DRW::AC1018) { //2007+ + dwgHandle bkgrdH = buf->getHandle(); + DRW_DBG(" background Handle: "); DRW_DBGHL(bkgrdH.code, bkgrdH.size, bkgrdH.ref); + DRW_DBG("\nRemaining bytes: "); DRW_DBG(buf->numRemainingBytes()); + dwgHandle visualStH = buf->getHandle(); + DRW_DBG(" visual style Handle: "); DRW_DBGHL(visualStH.code, visualStH.size, visualStH.ref); + DRW_DBG("\nRemaining bytes: "); DRW_DBG(buf->numRemainingBytes()); + dwgHandle sunH = buf->getHandle(); + DRW_DBG(" sun Handle: "); DRW_DBGHL(sunH.code, sunH.size, sunH.ref); + DRW_DBG("\nRemaining bytes: "); DRW_DBG(buf->numRemainingBytes()); + } + dwgHandle namedUCSH = buf->getHandle(); + DRW_DBG(" named UCS Handle: "); DRW_DBGHL(namedUCSH.code, namedUCSH.size, namedUCSH.ref); + DRW_DBG("\nRemaining bytes: "); DRW_DBG(buf->numRemainingBytes()); + dwgHandle baseUCSH = buf->getHandle(); + DRW_DBG(" base UCS Handle: "); DRW_DBGHL(baseUCSH.code, baseUCSH.size, baseUCSH.ref); + } + + DRW_DBG("\n Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + // RS crc; //RS */ + return buf->isGood(); +} + +void DRW_ImageDef::parseCode(int code, dxfReader *reader){ + switch (code) { + case 1: + name = reader->getUtf8String(); + break; + case 5: + handle = reader->getHandleString(); + break; + case 10: + u = reader->getDouble(); + break; + case 20: + v = reader->getDouble(); + break; + case 11: + up = reader->getDouble(); + break; + case 12: + vp = reader->getDouble(); + break; + case 21: + vp = reader->getDouble(); + break; + case 280: + loaded = reader->getInt32(); + break; + case 281: + resolution = reader->getInt32(); + break; + default: + break; + } +} + +bool DRW_ImageDef::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); + DRW_DBG("\n***************************** parsing Image Def *********************************************\n"); + if (!ret) + return ret; + dint32 imgVersion = buf->getBitLong(); + DRW_DBG("class Version: "); DRW_DBG(imgVersion); + DRW_Coord size = buf->get2RawDouble(); + (void)size; + name = sBuf->getVariableText(version, false); + DRW_DBG("appId name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); + loaded = buf->getBit(); + resolution = buf->getRawChar8(); + up = buf->getRawDouble(); + vp = buf->getRawDouble(); + + dwgHandle parentH = buf->getHandle(); + DRW_DBG(" parentH Handle: "); DRW_DBGHL(parentH.code, parentH.size, parentH.ref); DRW_DBG("\n"); + parentHandle = parentH.ref; + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + //RLZ: Reactors handles + if (xDictFlag !=1){ + dwgHandle XDicObjH = buf->getHandle(); + DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } +/*RLZ: fails verify this part*/ dwgHandle XRefH = buf->getHandle(); + DRW_DBG(" XRefH control Handle: "); DRW_DBGHL(XRefH.code, XRefH.size, XRefH.ref); DRW_DBG("\n"); + + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n\n"); + // RS crc; //RS */ + return buf->isGood(); +} + +bool DRW_AppId::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ + dwgBuffer sBuff = *buf; + dwgBuffer *sBuf = buf; + if (version > DRW::AC1018) {//2007+ + sBuf = &sBuff; //separate buffer for strings + } + bool ret = DRW_TableEntry::parseDwg(version, buf, sBuf, bs); + DRW_DBG("\n***************************** parsing app Id *********************************************\n"); + if (!ret) + return ret; + name = sBuf->getVariableText(version, false); + DRW_DBG("appId name: "); DRW_DBG(name.c_str()); DRW_DBG("\n"); + flags |= buf->getBit()<< 6;// code 70, bit 7 (64) + /*dint16 xrefindex =*/ buf->getBitShort(); + flags |= buf->getBit() << 4; //is refx dependent, style code 70, bit 5 (16) + duint8 unknown = buf->getRawChar8(); // unknown code 71 + DRW_DBG("unknown code 71: "); DRW_DBG(unknown); DRW_DBG("\n"); + if (version > DRW::AC1018) {//2007+ skip string area + buf->setPosition(objSize >> 3); + buf->setBitPos(objSize & 7); + } + dwgHandle appIdControlH = buf->getHandle(); + DRW_DBG(" parentControlH Handle: "); DRW_DBGHL(appIdControlH.code, appIdControlH.size, appIdControlH.ref); DRW_DBG("\n"); + parentHandle = appIdControlH.ref; + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + if (xDictFlag !=1){//linetype in 2004 seems not have XDicObjH or NULL handle + dwgHandle XDicObjH = buf->getHandle(); + DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } +/*RLZ: fails verify this part*/ dwgHandle XRefH = buf->getHandle(); + DRW_DBG(" XRefH control Handle: "); DRW_DBGHL(XRefH.code, XRefH.size, XRefH.ref); DRW_DBG("\n"); + + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n\n"); + // RS crc; //RS */ + return buf->isGood(); +} diff --git a/extlib/libdxfrw/drw_objects.h b/extlib/libdxfrw/drw_objects.h new file mode 100644 index 0000000..0a872d0 --- /dev/null +++ b/extlib/libdxfrw/drw_objects.h @@ -0,0 +1,772 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DRW_OBJECTS_H +#define DRW_OBJECTS_H + + +#include +#include +#include +#include "drw_base.h" + +class dxfReader; +class dxfWriter; +class dwgBuffer; + +namespace DRW { + +//! Table entries type. + enum TTYPE { + UNKNOWNT, + LTYPE, + LAYER, + STYLE, + DIMSTYLE, + VPORT, + BLOCK_RECORD, + APPID, + IMAGEDEF + }; + +//pending VIEW, UCS, APPID, VP_ENT_HDR, GROUP, MLINESTYLE, LONG_TRANSACTION, XRECORD, +//ACDBPLACEHOLDER, VBA_PROJECT, ACAD_TABLE, CELLSTYLEMAP, DBCOLOR, DICTIONARYVAR, +//DICTIONARYWDFLT, FIELD, IDBUFFER, IMAGEDEF, IMAGEDEFREACTOR, LAYER_INDEX, LAYOUT +//MATERIAL, PLACEHOLDER, PLOTSETTINGS, RASTERVARIABLES, SCALE, SORTENTSTABLE, +//SPATIAL_INDEX, SPATIAL_FILTER, TABLEGEOMETRY, TABLESTYLES,VISUALSTYLE, +} + +#define SETOBJFRIENDS friend class dxfRW; \ + friend class dwgReader; + +//! Base class for tables entries +/*! +* Base class for tables entries +* @author Rallaz +*/ +class DRW_TableEntry { +public: + //initializes default values + DRW_TableEntry() { + tType = DRW::UNKNOWNT; + flags = 0; + numReactors = xDictFlag = 0; + parentHandle = 0; + curr = NULL; + } + + virtual~DRW_TableEntry() { + for (std::vector::iterator it=extData.begin(); it!=extData.end(); ++it) + delete *it; + + extData.clear(); + } + + DRW_TableEntry(const DRW_TableEntry& e) { + tType = e.tType; + handle = e.handle; + parentHandle = e.parentHandle; + name = e.name; + flags = e.flags; + numReactors = e.numReactors; + xDictFlag = e.xDictFlag; + curr = e.curr; + for (std::vector::const_iterator it=e.extData.begin(); it!=e.extData.end(); ++it){ + extData.push_back(new DRW_Variant(*(*it))); + } + } + +protected: + void parseCode(int code, dxfReader *reader); + virtual bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0) = 0; + bool parseDwg(DRW::Version version, dwgBuffer *buf, dwgBuffer* strBuf, duint32 bs=0); + void reset(){ + flags =0; + for (std::vector::iterator it=extData.begin(); it!=extData.end(); ++it) + delete *it; + extData.clear(); + } + +public: + enum DRW::TTYPE tType; /*!< enum: entity type, code 0 */ + duint32 handle; /*!< entity identifier, code 5 */ + int parentHandle; /*!< Soft-pointer ID/handle to owner object, code 330 */ + UTF8STRING name; /*!< entry name, code 2 */ + int flags; /*!< Flags relevant to entry, code 70 */ + std::vector extData; /*!< FIFO list of extended data, codes 1000 to 1071*/ + +private: + DRW_Variant* curr; + + //***** dwg parse ********/ +protected: + dint16 oType; + duint8 xDictFlag; + dint32 numReactors; // + duint32 objSize; //RL 32bits object data size in bits +}; + + +//! Class to handle dimstyle entries +/*! +* Class to handle dim style symbol table entries +* @author Rallaz +*/ +class DRW_Dimstyle : public DRW_TableEntry { + SETOBJFRIENDS +public: + DRW_Dimstyle() { reset();} + + void reset(){ + tType = DRW::DIMSTYLE; + dimasz = dimtxt = dimcen = 2.5; + dimexe = 1.25; + dimexo = dimgap = 0.625; + dimtxsty = ""; + dimscale = dimlfac = dimtfac = dimfxl = 1.0; + dimdli = 3.75; + dimrnd = dimdle = dimtp = dimtm = dimtsz = dimtvp = 0.0; + dimaltf = 1.0 / 25.4; + dimtol = dimlim = dimse1 = dimse2 = 0; + dimtad = 1; + dimzin = 8; + dimtoh = dimtolj = 0; + dimalt = dimsah = dimtix = dimsoxd = dimfxlon = 0; + dimtofl = 1; + dimunit = dimaltu = dimlunit = 2; + dimaltd = dimalttd = 3; + dimclrd = dimclre = dimclrt = dimjust = dimupt = 0; + dimtzin = 8; + dimazin = dimaltz = dimaltttz = dimfrac = 0; + dimtih = dimadec = dimaunit = dimsd1 = dimsd2 = dimtmove = 0; + dimaltrnd = 0.0; + dimdec = dimtdec = 2; + dimfit = dimatfit = 3; + dimdsep = ','; + dimlwd = dimlwe = -2; + DRW_TableEntry::reset(); + } + +protected: + void parseCode(int code, dxfReader *reader); + bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: + //V12 + UTF8STRING dimpost; /*!< code 3 */ + UTF8STRING dimapost; /*!< code 4 */ +/* handle are code 105 */ + UTF8STRING dimblk; /*!< code 5, code 342 V2000+ */ + UTF8STRING dimblk1; /*!< code 6, code 343 V2000+ */ + UTF8STRING dimblk2; /*!< code 7, code 344 V2000+ */ + double dimscale; /*!< code 40 */ + double dimasz; /*!< code 41 */ + double dimexo; /*!< code 42 */ + double dimdli; /*!< code 43 */ + double dimexe; /*!< code 44 */ + double dimrnd; /*!< code 45 */ + double dimdle; /*!< code 46 */ + double dimtp; /*!< code 47 */ + double dimtm; /*!< code 48 */ + double dimfxl; /*!< code 49 V2007+ */ + double dimtxt; /*!< code 140 */ + double dimcen; /*!< code 141 */ + double dimtsz; /*!< code 142 */ + double dimaltf; /*!< code 143 */ + double dimlfac; /*!< code 144 */ + double dimtvp; /*!< code 145 */ + double dimtfac; /*!< code 146 */ + double dimgap; /*!< code 147 */ + double dimaltrnd; /*!< code 148 V2000+ */ + int dimtol; /*!< code 71 */ + int dimlim; /*!< code 72 */ + int dimtih; /*!< code 73 */ + int dimtoh; /*!< code 74 */ + int dimse1; /*!< code 75 */ + int dimse2; /*!< code 76 */ + int dimtad; /*!< code 77 */ + int dimzin; /*!< code 78 */ + int dimazin; /*!< code 79 V2000+ */ + int dimalt; /*!< code 170 */ + int dimaltd; /*!< code 171 */ + int dimtofl; /*!< code 172 */ + int dimsah; /*!< code 173 */ + int dimtix; /*!< code 174 */ + int dimsoxd; /*!< code 175 */ + int dimclrd; /*!< code 176 */ + int dimclre; /*!< code 177 */ + int dimclrt; /*!< code 178 */ + int dimadec; /*!< code 179 V2000+ */ + int dimunit; /*!< code 270 R13+ (obsolete 2000+, use dimlunit & dimfrac) */ + int dimdec; /*!< code 271 R13+ */ + int dimtdec; /*!< code 272 R13+ */ + int dimaltu; /*!< code 273 R13+ */ + int dimalttd; /*!< code 274 R13+ */ + int dimaunit; /*!< code 275 R13+ */ + int dimfrac; /*!< code 276 V2000+ */ + int dimlunit; /*!< code 277 V2000+ */ + int dimdsep; /*!< code 278 V2000+ */ + int dimtmove; /*!< code 279 V2000+ */ + int dimjust; /*!< code 280 R13+ */ + int dimsd1; /*!< code 281 R13+ */ + int dimsd2; /*!< code 282 R13+ */ + int dimtolj; /*!< code 283 R13+ */ + int dimtzin; /*!< code 284 R13+ */ + int dimaltz; /*!< code 285 R13+ */ + int dimaltttz; /*!< code 286 R13+ */ + int dimfit; /*!< code 287 R13+ (obsolete 2000+, use dimatfit & dimtmove)*/ + int dimupt; /*!< code 288 R13+ */ + int dimatfit; /*!< code 289 V2000+ */ + int dimfxlon; /*!< code 290 V2007+ */ + UTF8STRING dimtxsty; /*!< code 340 R13+ */ + UTF8STRING dimldrblk; /*!< code 341 V2000+ */ + int dimlwd; /*!< code 371 V2000+ */ + int dimlwe; /*!< code 372 V2000+ */ +}; + + +//! Class to handle line type entries +/*! +* Class to handle line type symbol table entries +* @author Rallaz +*/ +/*TODO: handle complex lineType*/ +class DRW_LType : public DRW_TableEntry { + SETOBJFRIENDS +public: + DRW_LType() { reset();} + + void reset(){ + tType = DRW::LTYPE; + desc = ""; + size = 0; + length = 0.0; + pathIdx = 0; + DRW_TableEntry::reset(); + } + +protected: + void parseCode(int code, dxfReader *reader); + bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + void update(); + +public: + UTF8STRING desc; /*!< descriptive string, code 3 */ +// int align; /*!< align code, always 65 ('A') code 72 */ + int size; /*!< element number, code 73 */ + double length; /*!< total length of pattern, code 40 */ +// int haveShape; /*!< complex linetype type, code 74 */ + std::vector path; /*!< trace, point or space length sequence, code 49 */ +private: + int pathIdx; +}; + + +//! Class to handle layer entries +/*! +* Class to handle layer symbol table entries +* @author Rallaz +*/ +class DRW_Layer : public DRW_TableEntry { + SETOBJFRIENDS +public: + DRW_Layer() { reset();} + + void reset() { + tType = DRW::LAYER; + lineType = "CONTINUOUS"; + color = 7; // default BYLAYER (256) + plotF = true; // default TRUE (plot yes) + lWeight = DRW_LW_Conv::widthDefault; // default BYDEFAULT (dxf -3, dwg 31) + color24 = -1; //default -1 not set + DRW_TableEntry::reset(); + } + +protected: + void parseCode(int code, dxfReader *reader); + bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: + UTF8STRING lineType; /*!< line type, code 6 */ + int color; /*!< layer color, code 62 */ + int color24; /*!< 24-bit color, code 420 */ + bool plotF; /*!< Plot flag, code 290 */ + enum DRW_LW_Conv::lineWidth lWeight; /*!< layer lineweight, code 370 */ + std::string handlePlotS; /*!< Hard-pointer ID/handle of plotstyle, code 390 */ + std::string handleMaterialS; /*!< Hard-pointer ID/handle of materialstyle, code 347 */ +/*only used for read dwg*/ + dwgHandle lTypeH; +}; + +//! Class to handle block record entries +/*! +* Class to handle block record table entries +* @author Rallaz +*/ +class DRW_Block_Record : public DRW_TableEntry { + SETOBJFRIENDS +public: + DRW_Block_Record() { reset();} + void reset() { + tType = DRW::BLOCK_RECORD; + flags = 0; + firstEH = lastEH = DRW::NoHandle; + DRW_TableEntry::reset(); + } + +protected: +// void parseCode(int code, dxfReader *reader); + bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: +//Note: int DRW_TableEntry::flags; contains code 70 of block + int insUnits; /*!< block insertion units, code 70 of block_record*/ + DRW_Coord basePoint; /*!< block insertion base point dwg only */ +protected: + //dwg parser +private: + duint32 block; //handle for block entity + duint32 endBlock;//handle for end block entity + duint32 firstEH; //handle of first entity, only in pre-2004 + duint32 lastEH; //handle of last entity, only in pre-2004 + std::vectorentMap; +}; + +//! Class to handle text style entries +/*! +* Class to handle text style symbol table entries +* @author Rallaz +*/ +class DRW_Textstyle : public DRW_TableEntry { + SETOBJFRIENDS +public: + DRW_Textstyle() { reset();} + + void reset(){ + tType = DRW::STYLE; + height = oblique = 0.0; + width = lastHeight = 1.0; + font="txt"; + genFlag = 0; //2= X mirror, 4= Y mirror + fontFamily = 0; + DRW_TableEntry::reset(); + } + +protected: + void parseCode(int code, dxfReader *reader); + bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: + double height; /*!< Fixed text height (0 not set), code 40 */ + double width; /*!< Width factor, code 41 */ + double oblique; /*!< Oblique angle, code 50 */ + int genFlag; /*!< Text generation flags, code 71 */ + double lastHeight; /*!< Last height used, code 42 */ + UTF8STRING font; /*!< primary font file name, code 3 */ + UTF8STRING bigFont; /*!< bigfont file name or blank if none, code 4 */ + int fontFamily; /*!< ttf font family, italic and bold flags, code 1071 */ +}; + +//! Class to handle vport entries +/*! +* Class to handle vport symbol table entries +* @author Rallaz +*/ +class DRW_Vport : public DRW_TableEntry { + SETOBJFRIENDS +public: + DRW_Vport() { reset();} + + void reset(){ + tType = DRW::VPORT; + UpperRight.x = UpperRight.y = 1.0; + snapSpacing.x = snapSpacing.y = 10.0; + gridSpacing = snapSpacing; + center.x = 0.651828; + center.y = -0.16; + viewDir.z = 1; + height = 5.13732; + ratio = 2.4426877; + lensHeight = 50; + frontClip = backClip = snapAngle = twistAngle = 0.0; + viewMode = snap = grid = snapStyle = snapIsopair = 0; + fastZoom = 1; + circleZoom = 100; + ucsIcon = 3; + gridBehavior = 7; + DRW_TableEntry::reset(); + } + +protected: + void parseCode(int code, dxfReader *reader); + bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: + DRW_Coord lowerLeft; /*!< Lower left corner, code 10 & 20 */ + DRW_Coord UpperRight; /*!< Upper right corner, code 11 & 21 */ + DRW_Coord center; /*!< center point in WCS, code 12 & 22 */ + DRW_Coord snapBase; /*!< snap base point in DCS, code 13 & 23 */ + DRW_Coord snapSpacing; /*!< snap Spacing, code 14 & 24 */ + DRW_Coord gridSpacing; /*!< grid Spacing, code 15 & 25 */ + DRW_Coord viewDir; /*!< view direction from target point, code 16, 26 & 36 */ + DRW_Coord viewTarget; /*!< view target point, code 17, 27 & 37 */ + double height; /*!< view height, code 40 */ + double ratio; /*!< viewport aspect ratio, code 41 */ + double lensHeight; /*!< lens height, code 42 */ + double frontClip; /*!< front clipping plane, code 43 */ + double backClip; /*!< back clipping plane, code 44 */ + double snapAngle; /*!< snap rotation angle, code 50 */ + double twistAngle; /*!< view twist angle, code 51 */ + int viewMode; /*!< view mode, code 71 */ + int circleZoom; /*!< circle zoom percent, code 72 */ + int fastZoom; /*!< fast zoom setting, code 73 */ + int ucsIcon; /*!< UCSICON setting, code 74 */ + int snap; /*!< snap on/off, code 75 */ + int grid; /*!< grid on/off, code 76 */ + int snapStyle; /*!< snap style, code 77 */ + int snapIsopair; /*!< snap isopair, code 78 */ + int gridBehavior; /*!< grid behavior, code 60, undocummented */ + /** code 60, bit coded possible value are + * bit 1 (1) show out of limits + * bit 2 (2) adaptive grid + * bit 3 (4) allow subdivision + * bit 4 (8) follow dynamic SCP + **/ +}; + + +//! Class to handle imagedef entries +/*! +* Class to handle image definitions object entries +* @author Rallaz +*/ +class DRW_ImageDef : public DRW_TableEntry {// + SETOBJFRIENDS +public: + DRW_ImageDef() { + reset(); + } + + void reset(){ + tType = DRW::IMAGEDEF; + imgVersion = 0; + DRW_TableEntry::reset(); + } + +protected: + void parseCode(int code, dxfReader *reader); + bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + +public: +// std::string handle; /*!< entity identifier, code 5 */ + UTF8STRING name; /*!< File name of image, code 1 */ + int imgVersion; /*!< class version, code 90, 0=R14 version */ + double u; /*!< image size in pixels U value, code 10 */ + double v; /*!< image size in pixels V value, code 20 */ + double up; /*!< default size of one pixel U value, code 11 */ + double vp; /*!< default size of one pixel V value, code 12 really is 21*/ + int loaded; /*!< image is loaded flag, code 280, 0=unloaded, 1=loaded */ + int resolution; /*!< resolution units, code 281, 0=no, 2=centimeters, 5=inch */ + + std::map reactors; +}; + +//! Class to handle AppId entries +/*! +* Class to handle AppId symbol table entries +* @author Rallaz +*/ +class DRW_AppId : public DRW_TableEntry { + SETOBJFRIENDS +public: + DRW_AppId() { reset();} + + void reset(){ + tType = DRW::APPID; + flags = 0; + name = ""; + } + +protected: + void parseCode(int code, dxfReader *reader){DRW_TableEntry::parseCode(code, reader);} + bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); +}; + +namespace DRW { + +// Extended color palette: +// The first entry is only for direct indexing starting with [1] +// Color 1 is red (1,0,0) +const unsigned char dxfColors[][3] = { + { 0, 0, 0}, // unused + {255, 0, 0}, // 1 red + {255,255, 0}, // 2 yellow + { 0,255, 0}, // 3 green + { 0,255,255}, // 4 cyan + { 0, 0,255}, // 5 blue + {255, 0,255}, // 6 magenta + { 0, 0, 0}, // 7 black or white + {128,128,128}, // 8 50% gray + {192,192,192}, // 9 75% gray + {255, 0, 0}, // 10 + {255,127,127}, + {204, 0, 0}, + {204,102,102}, + {153, 0, 0}, + {153, 76, 76}, // 15 + {127, 0, 0}, + {127, 63, 63}, + { 76, 0, 0}, + { 76, 38, 38}, + {255, 63, 0}, // 20 + {255,159,127}, + {204, 51, 0}, + {204,127,102}, + {153, 38, 0}, + {153, 95, 76}, // 25 + {127, 31, 0}, + {127, 79, 63}, + { 76, 19, 0}, + { 76, 47, 38}, + {255,127, 0}, // 30 + {255,191,127}, + {204,102, 0}, + {204,153,102}, + {153, 76, 0}, + {153,114, 76}, // 35 + {127, 63, 0}, + {127, 95, 63}, + { 76, 38, 0}, + { 76, 57, 38}, + {255,191, 0}, // 40 + {255,223,127}, + {204,153, 0}, + {204,178,102}, + {153,114, 0}, + {153,133, 76}, // 45 + {127, 95, 0}, + {127,111, 63}, + { 76, 57, 0}, + { 76, 66, 38}, + {255,255, 0}, // 50 + {255,255,127}, + {204,204, 0}, + {204,204,102}, + {153,153, 0}, + {153,153, 76}, // 55 + {127,127, 0}, + {127,127, 63}, + { 76, 76, 0}, + { 76, 76, 38}, + {191,255, 0}, // 60 + {223,255,127}, + {153,204, 0}, + {178,204,102}, + {114,153, 0}, + {133,153, 76}, // 65 + { 95,127, 0}, + {111,127, 63}, + { 57, 76, 0}, + { 66, 76, 38}, + {127,255, 0}, // 70 + {191,255,127}, + {102,204, 0}, + {153,204,102}, + { 76,153, 0}, + {114,153, 76}, // 75 + { 63,127, 0}, + { 95,127, 63}, + { 38, 76, 0}, + { 57, 76, 38}, + { 63,255, 0}, // 80 + {159,255,127}, + { 51,204, 0}, + {127,204,102}, + { 38,153, 0}, + { 95,153, 76}, // 85 + { 31,127, 0}, + { 79,127, 63}, + { 19, 76, 0}, + { 47, 76, 38}, + { 0,255, 0}, // 90 + {127,255,127}, + { 0,204, 0}, + {102,204,102}, + { 0,153, 0}, + { 76,153, 76}, // 95 + { 0,127, 0}, + { 63,127, 63}, + { 0, 76, 0}, + { 38, 76, 38}, + { 0,255, 63}, // 100 + {127,255,159}, + { 0,204, 51}, + {102,204,127}, + { 0,153, 38}, + { 76,153, 95}, // 105 + { 0,127, 31}, + { 63,127, 79}, + { 0, 76, 19}, + { 38, 76, 47}, + { 0,255,127}, // 110 + {127,255,191}, + { 0,204,102}, + {102,204,153}, + { 0,153, 76}, + { 76,153,114}, // 115 + { 0,127, 63}, + { 63,127, 95}, + { 0, 76, 38}, + { 38, 76, 57}, + { 0,255,191}, // 120 + {127,255,223}, + { 0,204,153}, + {102,204,178}, + { 0,153,114}, + { 76,153,133}, // 125 + { 0,127, 95}, + { 63,127,111}, + { 0, 76, 57}, + { 38, 76, 66}, + { 0,255,255}, // 130 + {127,255,255}, + { 0,204,204}, + {102,204,204}, + { 0,153,153}, + { 76,153,153}, // 135 + { 0,127,127}, + { 63,127,127}, + { 0, 76, 76}, + { 38, 76, 76}, + { 0,191,255}, // 140 + {127,223,255}, + { 0,153,204}, + {102,178,204}, + { 0,114,153}, + { 76,133,153}, // 145 + { 0, 95,127}, + { 63,111,127}, + { 0, 57, 76}, + { 38, 66, 76}, + { 0,127,255}, // 150 + {127,191,255}, + { 0,102,204}, + {102,153,204}, + { 0, 76,153}, + { 76,114,153}, // 155 + { 0, 63,127}, + { 63, 95,127}, + { 0, 38, 76}, + { 38, 57, 76}, + { 0, 66,255}, // 160 + {127,159,255}, + { 0, 51,204}, + {102,127,204}, + { 0, 38,153}, + { 76, 95,153}, // 165 + { 0, 31,127}, + { 63, 79,127}, + { 0, 19, 76}, + { 38, 47, 76}, + { 0, 0,255}, // 170 + {127,127,255}, + { 0, 0,204}, + {102,102,204}, + { 0, 0,153}, + { 76, 76,153}, // 175 + { 0, 0,127}, + { 63, 63,127}, + { 0, 0, 76}, + { 38, 38, 76}, + { 63, 0,255}, // 180 + {159,127,255}, + { 50, 0,204}, + {127,102,204}, + { 38, 0,153}, + { 95, 76,153}, // 185 + { 31, 0,127}, + { 79, 63,127}, + { 19, 0, 76}, + { 47, 38, 76}, + {127, 0,255}, // 190 + {191,127,255}, + {102, 0,204}, + {153,102,204}, + { 76, 0,153}, + {114, 76,153}, // 195 + { 63, 0,127}, + { 95, 63,127}, + { 38, 0, 76}, + { 57, 38, 76}, + {191, 0,255}, // 200 + {223,127,255}, + {153, 0,204}, + {178,102,204}, + {114, 0,153}, + {133, 76,153}, // 205 + { 95, 0,127}, + {111, 63,127}, + { 57, 0, 76}, + { 66, 38, 76}, + {255, 0,255}, // 210 + {255,127,255}, + {204, 0,204}, + {204,102,204}, + {153, 0,153}, + {153, 76,153}, // 215 + {127, 0,127}, + {127, 63,127}, + { 76, 0, 76}, + { 76, 38, 76}, + {255, 0,191}, // 220 + {255,127,223}, + {204, 0,153}, + {204,102,178}, + {153, 0,114}, + {153, 76,133}, // 225 + {127, 0, 95}, + {127, 63, 11}, + { 76, 0, 57}, + { 76, 38, 66}, + {255, 0,127}, // 230 + {255,127,191}, + {204, 0,102}, + {204,102,153}, + {153, 0, 76}, + {153, 76,114}, // 235 + {127, 0, 63}, + {127, 63, 95}, + { 76, 0, 38}, + { 76, 38, 57}, + {255, 0, 63}, // 240 + {255,127,159}, + {204, 0, 51}, + {204,102,127}, + {153, 0, 38}, + {153, 76, 95}, // 245 + {127, 0, 31}, + {127, 63, 79}, + { 76, 0, 19}, + { 76, 38, 47}, + { 51, 51, 51}, // 250 + { 91, 91, 91}, + {132,132,132}, + {173,173,173}, + {214,214,214}, + {255,255,255} // 255 +}; + +} + +#endif + +// EOF diff --git a/extlib/libdxfrw/intern/drw_cptable932.h b/extlib/libdxfrw/intern/drw_cptable932.h new file mode 100644 index 0000000..a85f3ca --- /dev/null +++ b/extlib/libdxfrw/intern/drw_cptable932.h @@ -0,0 +1,7812 @@ +#ifndef DRW_CPTABLE932_H +#define DRW_CPTABLE932_H + +//Japanese + +//first entry in this table are 0xA1 +#define CPOFFSET932 0xFEC0 +//#define CP1LENGHT932 63 +#define CPLENGTH932 7724 +#define NOTFOUND932 0x30FB + +//Table 932 one byte are +//from 0xA1 -> 0xFF61 +//to 0xDF .> 0xFF9F +static const int DRW_Table932[1] = { +}; + +//Table 932 lead byte +//pairs of start/end in DRW_DoubleTable932 +static const int DRW_LeadTable932[] = { + 0, //1 #DBCS LEAD BYTE 0x81 + 147, //2 #DBCS LEAD BYTE 0x82 + 292, //3 #DBCS LEAD BYTE 0x83 + 426, //4 #DBCS LEAD BYTE 0x84 + 524, //5 #DBCS LEAD BYTE 0x85, empty + 524, //6 #DBCS LEAD BYTE 0x86, empty + 524, //7 #DBCS LEAD BYTE 0x87 + 607, //8 #DBCS LEAD BYTE 0x88 + 701, //9 #DBCS LEAD BYTE 0x89 + 889, //10 #DBCS LEAD BYTE 0x8A + 1077, //11 #DBCS LEAD BYTE 0x8B + 1265, //12 #DBCS LEAD BYTE 0x8C + 1453, //13 #DBCS LEAD BYTE 0x8D + 1641, //14 #DBCS LEAD BYTE 0x8E + 1829, //15 #DBCS LEAD BYTE 0x8F + 2017, //16 #DBCS LEAD BYTE 0x90 + 2205, //17 #DBCS LEAD BYTE 0x91 + 2393, //18 #DBCS LEAD BYTE 0x92 + 2581, //19 #DBCS LEAD BYTE 0x93 + 2769, //20 #DBCS LEAD BYTE 0x94 + 2957, //21 #DBCS LEAD BYTE 0x95 + 3145, //22 #DBCS LEAD BYTE 0x96 + 3333, //23 #DBCS LEAD BYTE 0x97 + 3521, //24 #DBCS LEAD BYTE 0x98 + 3666, //25 #DBCS LEAD BYTE 0x99 + 3854, //26 #DBCS LEAD BYTE 0x9A + 4042, //27 #DBCS LEAD BYTE 0x9B + 4230, //28 #DBCS LEAD BYTE 0x9C + 4418, //29 #DBCS LEAD BYTE 0x9D + 4606, //30 #DBCS LEAD BYTE 0x9E + 4794, //31 #DBCS LEAD BYTE 0x9F +//0xA0 to 0xDF are empty + 4982, //32 #DBCS LEAD BYTE 0xE0 + 5170, //33 #DBCS LEAD BYTE 0xE1 + 5358, //34 #DBCS LEAD BYTE 0xE2 + 5546, //35 #DBCS LEAD BYTE 0xE3 + 5734, //36 #DBCS LEAD BYTE 0xE4 + 5922, //37 #DBCS LEAD BYTE 0xE5 + 6110, //38 #DBCS LEAD BYTE 0xE6 + 6298, //39 #DBCS LEAD BYTE 0xE7 + 6486, //40 #DBCS LEAD BYTE 0xE8 + 6674, //41 #DBCS LEAD BYTE 0xE9 + 6862, //42 #DBCS LEAD BYTE 0xEA + 6962, //43 #DBCS LEAD BYTE 0xEB, empty + 6962, //44 #DBCS LEAD BYTE 0xEC, empty + 6962, //45 #DBCS LEAD BYTE 0xED + 7150, //46 #DBCS LEAD BYTE 0xEE + 7336, //47 #DBCS LEAD BYTE 0xEF, empty + 7336, //48 #DBCS LEAD BYTE 0xF0, empty + 7336, //49 #DBCS LEAD BYTE 0xF1, empty + 7336, //50 #DBCS LEAD BYTE 0xF2, empty + 7336, //51 #DBCS LEAD BYTE 0xF3, empty + 7336, //52 #DBCS LEAD BYTE 0xF4, empty + 7336, //53 #DBCS LEAD BYTE 0xF5, empty + 7336, //54 #DBCS LEAD BYTE 0xF6, empty + 7336, //55 #DBCS LEAD BYTE 0xF7, empty + 7336, //56 #DBCS LEAD BYTE 0xF8, empty + 7336, //57 #DBCS LEAD BYTE 0xF9, empty + 7336, //58 #DBCS LEAD BYTE 0xFA + 7524, //59 #DBCS LEAD BYTE 0xFB + 7712, //60 #DBCS LEAD BYTE 0xFC + 7724 //61 #END OF TABLE 0xFD +}; + +//Table 932 tail byte +static const int DRW_DoubleTable932[][2] = { + {0x8140, 0x3000}, //1 #IDEOGRAPHIC SPACE + {0x8141, 0x3001}, //2 #IDEOGRAPHIC COMMA + {0x8142, 0x3002}, //3 #IDEOGRAPHIC FULL STOP + {0x8143, 0xFF0C}, //4 #FULLWIDTH COMMA + {0x8144, 0xFF0E}, //5 #FULLWIDTH FULL STOP + {0x8145, 0x30FB}, //6 #KATAKANA MIDDLE DOT + {0x8146, 0xFF1A}, //7 #FULLWIDTH COLON + {0x8147, 0xFF1B}, //8 #FULLWIDTH SEMICOLON + {0x8148, 0xFF1F}, //9 #FULLWIDTH QUESTION MARK + {0x8149, 0xFF01}, //10 #FULLWIDTH EXCLAMATION MARK + {0x814A, 0x309B}, //11 #KATAKANA-HIRAGANA VOICED SOUND MARK + {0x814B, 0x309C}, //12 #KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0x814C, 0x00B4}, //13 #ACUTE ACCENT + {0x814D, 0xFF40}, //14 #FULLWIDTH GRAVE ACCENT + {0x814E, 0x00A8}, //15 #DIAERESIS + {0x814F, 0xFF3E}, //16 #FULLWIDTH CIRCUMFLEX ACCENT + {0x8150, 0xFFE3}, //17 #FULLWIDTH MACRON + {0x8151, 0xFF3F}, //18 #FULLWIDTH LOW LINE + {0x8152, 0x30FD}, //19 #KATAKANA ITERATION MARK + {0x8153, 0x30FE}, //20 #KATAKANA VOICED ITERATION MARK + {0x8154, 0x309D}, //21 #HIRAGANA ITERATION MARK + {0x8155, 0x309E}, //22 #HIRAGANA VOICED ITERATION MARK + {0x8156, 0x3003}, //23 #DITTO MARK + {0x8157, 0x4EDD}, //24 #CJK UNIFIED IDEOGRAPH + {0x8158, 0x3005}, //25 #IDEOGRAPHIC ITERATION MARK + {0x8159, 0x3006}, //26 #IDEOGRAPHIC CLOSING MARK + {0x815A, 0x3007}, //27 #IDEOGRAPHIC NUMBER ZERO + {0x815B, 0x30FC}, //28 #KATAKANA-HIRAGANA PROLONGED SOUND MARK + {0x815C, 0x2015}, //29 #HORIZONTAL BAR + {0x815D, 0x2010}, //30 #HYPHEN + {0x815E, 0xFF0F}, //31 #FULLWIDTH SOLIDUS + {0x815F, 0xFF3C}, //32 #FULLWIDTH REVERSE SOLIDUS + {0x8160, 0xFF5E}, //33 #FULLWIDTH TILDE + {0x8161, 0x2225}, //34 #PARALLEL TO + {0x8162, 0xFF5C}, //35 #FULLWIDTH VERTICAL LINE + {0x8163, 0x2026}, //36 #HORIZONTAL ELLIPSIS + {0x8164, 0x2025}, //37 #TWO DOT LEADER + {0x8165, 0x2018}, //38 #LEFT SINGLE QUOTATION MARK + {0x8166, 0x2019}, //39 #RIGHT SINGLE QUOTATION MARK + {0x8167, 0x201C}, //40 #LEFT DOUBLE QUOTATION MARK + {0x8168, 0x201D}, //41 #RIGHT DOUBLE QUOTATION MARK + {0x8169, 0xFF08}, //42 #FULLWIDTH LEFT PARENTHESIS + {0x816A, 0xFF09}, //43 #FULLWIDTH RIGHT PARENTHESIS + {0x816B, 0x3014}, //44 #LEFT TORTOISE SHELL BRACKET + {0x816C, 0x3015}, //45 #RIGHT TORTOISE SHELL BRACKET + {0x816D, 0xFF3B}, //46 #FULLWIDTH LEFT SQUARE BRACKET + {0x816E, 0xFF3D}, //47 #FULLWIDTH RIGHT SQUARE BRACKET + {0x816F, 0xFF5B}, //48 #FULLWIDTH LEFT CURLY BRACKET + {0x8170, 0xFF5D}, //49 #FULLWIDTH RIGHT CURLY BRACKET + {0x8171, 0x3008}, //50 #LEFT ANGLE BRACKET + {0x8172, 0x3009}, //51 #RIGHT ANGLE BRACKET + {0x8173, 0x300A}, //52 #LEFT DOUBLE ANGLE BRACKET + {0x8174, 0x300B}, //53 #RIGHT DOUBLE ANGLE BRACKET + {0x8175, 0x300C}, //54 #LEFT CORNER BRACKET + {0x8176, 0x300D}, //55 #RIGHT CORNER BRACKET + {0x8177, 0x300E}, //56 #LEFT WHITE CORNER BRACKET + {0x8178, 0x300F}, //57 #RIGHT WHITE CORNER BRACKET + {0x8179, 0x3010}, //58 #LEFT BLACK LENTICULAR BRACKET + {0x817A, 0x3011}, //59 #RIGHT BLACK LENTICULAR BRACKET + {0x817B, 0xFF0B}, //60 #FULLWIDTH PLUS SIGN + {0x817C, 0xFF0D}, //61 #FULLWIDTH HYPHEN-MINUS + {0x817D, 0x00B1}, //62 #PLUS-MINUS SIGN + {0x817E, 0x00D7}, //63 #MULTIPLICATION SIGN + {0x8180, 0x00F7}, //64 #DIVISION SIGN + {0x8181, 0xFF1D}, //65 #FULLWIDTH EQUALS SIGN + {0x8182, 0x2260}, //66 #NOT EQUAL TO + {0x8183, 0xFF1C}, //67 #FULLWIDTH LESS-THAN SIGN + {0x8184, 0xFF1E}, //68 #FULLWIDTH GREATER-THAN SIGN + {0x8185, 0x2266}, //69 #LESS-THAN OVER EQUAL TO + {0x8186, 0x2267}, //70 #GREATER-THAN OVER EQUAL TO + {0x8187, 0x221E}, //71 #INFINITY + {0x8188, 0x2234}, //72 #THEREFORE + {0x8189, 0x2642}, //73 #MALE SIGN + {0x818A, 0x2640}, //74 #FEMALE SIGN + {0x818B, 0x00B0}, //75 #DEGREE SIGN + {0x818C, 0x2032}, //76 #PRIME + {0x818D, 0x2033}, //77 #DOUBLE PRIME + {0x818E, 0x2103}, //78 #DEGREE CELSIUS + {0x818F, 0xFFE5}, //79 #FULLWIDTH YEN SIGN + {0x8190, 0xFF04}, //80 #FULLWIDTH DOLLAR SIGN + {0x8191, 0xFFE0}, //81 #FULLWIDTH CENT SIGN + {0x8192, 0xFFE1}, //82 #FULLWIDTH POUND SIGN + {0x8193, 0xFF05}, //83 #FULLWIDTH PERCENT SIGN + {0x8194, 0xFF03}, //84 #FULLWIDTH NUMBER SIGN + {0x8195, 0xFF06}, //85 #FULLWIDTH AMPERSAND + {0x8196, 0xFF0A}, //86 #FULLWIDTH ASTERISK + {0x8197, 0xFF20}, //87 #FULLWIDTH COMMERCIAL AT + {0x8198, 0x00A7}, //88 #SECTION SIGN + {0x8199, 0x2606}, //89 #WHITE STAR + {0x819A, 0x2605}, //90 #BLACK STAR + {0x819B, 0x25CB}, //91 #WHITE CIRCLE + {0x819C, 0x25CF}, //92 #BLACK CIRCLE + {0x819D, 0x25CE}, //93 #BULLSEYE + {0x819E, 0x25C7}, //94 #WHITE DIAMOND + {0x819F, 0x25C6}, //95 #BLACK DIAMOND + {0x81A0, 0x25A1}, //96 #WHITE SQUARE + {0x81A1, 0x25A0}, //97 #BLACK SQUARE + {0x81A2, 0x25B3}, //98 #WHITE UP-POINTING TRIANGLE + {0x81A3, 0x25B2}, //99 #BLACK UP-POINTING TRIANGLE + {0x81A4, 0x25BD}, //100 #WHITE DOWN-POINTING TRIANGLE + {0x81A5, 0x25BC}, //101 #BLACK DOWN-POINTING TRIANGLE + {0x81A6, 0x203B}, //102 #REFERENCE MARK + {0x81A7, 0x3012}, //103 #POSTAL MARK + {0x81A8, 0x2192}, //104 #RIGHTWARDS ARROW + {0x81A9, 0x2190}, //105 #LEFTWARDS ARROW + {0x81AA, 0x2191}, //106 #UPWARDS ARROW + {0x81AB, 0x2193}, //107 #DOWNWARDS ARROW + {0x81AC, 0x3013}, //108 #GETA MARK + {0x81B8, 0x2208}, //109 #ELEMENT OF + {0x81B9, 0x220B}, //110 #CONTAINS AS MEMBER + {0x81BA, 0x2286}, //111 #SUBSET OF OR EQUAL TO + {0x81BB, 0x2287}, //112 #SUPERSET OF OR EQUAL TO + {0x81BC, 0x2282}, //113 #SUBSET OF + {0x81BD, 0x2283}, //114 #SUPERSET OF + {0x81BE, 0x222A}, //115 #UNION + {0x81BF, 0x2229}, //116 #INTERSECTION + {0x81C8, 0x2227}, //117 #LOGICAL AND + {0x81C9, 0x2228}, //118 #LOGICAL OR + {0x81CA, 0xFFE2}, //119 #FULLWIDTH NOT SIGN + {0x81CB, 0x21D2}, //120 #RIGHTWARDS DOUBLE ARROW + {0x81CC, 0x21D4}, //121 #LEFT RIGHT DOUBLE ARROW + {0x81CD, 0x2200}, //122 #FOR ALL + {0x81CE, 0x2203}, //123 #THERE EXISTS + {0x81DA, 0x2220}, //124 #ANGLE + {0x81DB, 0x22A5}, //125 #UP TACK + {0x81DC, 0x2312}, //126 #ARC + {0x81DD, 0x2202}, //127 #PARTIAL DIFFERENTIAL + {0x81DE, 0x2207}, //128 #NABLA + {0x81DF, 0x2261}, //129 #IDENTICAL TO + {0x81E0, 0x2252}, //130 #APPROXIMATELY EQUAL TO OR THE IMAGE OF + {0x81E1, 0x226A}, //131 #MUCH LESS-THAN + {0x81E2, 0x226B}, //132 #MUCH GREATER-THAN + {0x81E3, 0x221A}, //133 #SQUARE ROOT + {0x81E4, 0x223D}, //134 #REVERSED TILDE + {0x81E5, 0x221D}, //135 #PROPORTIONAL TO + {0x81E6, 0x2235}, //136 #BECAUSE + {0x81E7, 0x222B}, //137 #INTEGRAL + {0x81E8, 0x222C}, //138 #DOUBLE INTEGRAL + {0x81F0, 0x212B}, //139 #ANGSTROM SIGN + {0x81F1, 0x2030}, //140 #PER MILLE SIGN + {0x81F2, 0x266F}, //141 #MUSIC SHARP SIGN + {0x81F3, 0x266D}, //142 #MUSIC FLAT SIGN + {0x81F4, 0x266A}, //143 #EIGHTH NOTE + {0x81F5, 0x2020}, //144 #DAGGER + {0x81F6, 0x2021}, //145 #DOUBLE DAGGER + {0x81F7, 0x00B6}, //146 #PILCROW SIGN + {0x81FC, 0x25EF}, //147 #LARGE CIRCLE + {0x824F, 0xFF10}, //148 #FULLWIDTH DIGIT ZERO + {0x8250, 0xFF11}, //149 #FULLWIDTH DIGIT ONE + {0x8251, 0xFF12}, //150 #FULLWIDTH DIGIT TWO + {0x8252, 0xFF13}, //151 #FULLWIDTH DIGIT THREE + {0x8253, 0xFF14}, //152 #FULLWIDTH DIGIT FOUR + {0x8254, 0xFF15}, //153 #FULLWIDTH DIGIT FIVE + {0x8255, 0xFF16}, //154 #FULLWIDTH DIGIT SIX + {0x8256, 0xFF17}, //155 #FULLWIDTH DIGIT SEVEN + {0x8257, 0xFF18}, //156 #FULLWIDTH DIGIT EIGHT + {0x8258, 0xFF19}, //157 #FULLWIDTH DIGIT NINE + {0x8260, 0xFF21}, //158 #FULLWIDTH LATIN CAPITAL LETTER A + {0x8261, 0xFF22}, //159 #FULLWIDTH LATIN CAPITAL LETTER B + {0x8262, 0xFF23}, //160 #FULLWIDTH LATIN CAPITAL LETTER C + {0x8263, 0xFF24}, //161 #FULLWIDTH LATIN CAPITAL LETTER D + {0x8264, 0xFF25}, //162 #FULLWIDTH LATIN CAPITAL LETTER E + {0x8265, 0xFF26}, //163 #FULLWIDTH LATIN CAPITAL LETTER F + {0x8266, 0xFF27}, //164 #FULLWIDTH LATIN CAPITAL LETTER G + {0x8267, 0xFF28}, //165 #FULLWIDTH LATIN CAPITAL LETTER H + {0x8268, 0xFF29}, //166 #FULLWIDTH LATIN CAPITAL LETTER I + {0x8269, 0xFF2A}, //167 #FULLWIDTH LATIN CAPITAL LETTER J + {0x826A, 0xFF2B}, //168 #FULLWIDTH LATIN CAPITAL LETTER K + {0x826B, 0xFF2C}, //169 #FULLWIDTH LATIN CAPITAL LETTER L + {0x826C, 0xFF2D}, //170 #FULLWIDTH LATIN CAPITAL LETTER M + {0x826D, 0xFF2E}, //171 #FULLWIDTH LATIN CAPITAL LETTER N + {0x826E, 0xFF2F}, //172 #FULLWIDTH LATIN CAPITAL LETTER O + {0x826F, 0xFF30}, //173 #FULLWIDTH LATIN CAPITAL LETTER P + {0x8270, 0xFF31}, //174 #FULLWIDTH LATIN CAPITAL LETTER Q + {0x8271, 0xFF32}, //175 #FULLWIDTH LATIN CAPITAL LETTER R + {0x8272, 0xFF33}, //176 #FULLWIDTH LATIN CAPITAL LETTER S + {0x8273, 0xFF34}, //177 #FULLWIDTH LATIN CAPITAL LETTER T + {0x8274, 0xFF35}, //178 #FULLWIDTH LATIN CAPITAL LETTER U + {0x8275, 0xFF36}, //179 #FULLWIDTH LATIN CAPITAL LETTER V + {0x8276, 0xFF37}, //180 #FULLWIDTH LATIN CAPITAL LETTER W + {0x8277, 0xFF38}, //181 #FULLWIDTH LATIN CAPITAL LETTER X + {0x8278, 0xFF39}, //182 #FULLWIDTH LATIN CAPITAL LETTER Y + {0x8279, 0xFF3A}, //183 #FULLWIDTH LATIN CAPITAL LETTER Z + {0x8281, 0xFF41}, //184 #FULLWIDTH LATIN SMALL LETTER A + {0x8282, 0xFF42}, //185 #FULLWIDTH LATIN SMALL LETTER B + {0x8283, 0xFF43}, //186 #FULLWIDTH LATIN SMALL LETTER C + {0x8284, 0xFF44}, //187 #FULLWIDTH LATIN SMALL LETTER D + {0x8285, 0xFF45}, //188 #FULLWIDTH LATIN SMALL LETTER E + {0x8286, 0xFF46}, //189 #FULLWIDTH LATIN SMALL LETTER F + {0x8287, 0xFF47}, //190 #FULLWIDTH LATIN SMALL LETTER G + {0x8288, 0xFF48}, //191 #FULLWIDTH LATIN SMALL LETTER H + {0x8289, 0xFF49}, //192 #FULLWIDTH LATIN SMALL LETTER I + {0x828A, 0xFF4A}, //193 #FULLWIDTH LATIN SMALL LETTER J + {0x828B, 0xFF4B}, //194 #FULLWIDTH LATIN SMALL LETTER K + {0x828C, 0xFF4C}, //195 #FULLWIDTH LATIN SMALL LETTER L + {0x828D, 0xFF4D}, //196 #FULLWIDTH LATIN SMALL LETTER M + {0x828E, 0xFF4E}, //197 #FULLWIDTH LATIN SMALL LETTER N + {0x828F, 0xFF4F}, //198 #FULLWIDTH LATIN SMALL LETTER O + {0x8290, 0xFF50}, //199 #FULLWIDTH LATIN SMALL LETTER P + {0x8291, 0xFF51}, //200 #FULLWIDTH LATIN SMALL LETTER Q + {0x8292, 0xFF52}, //201 #FULLWIDTH LATIN SMALL LETTER R + {0x8293, 0xFF53}, //202 #FULLWIDTH LATIN SMALL LETTER S + {0x8294, 0xFF54}, //203 #FULLWIDTH LATIN SMALL LETTER T + {0x8295, 0xFF55}, //204 #FULLWIDTH LATIN SMALL LETTER U + {0x8296, 0xFF56}, //205 #FULLWIDTH LATIN SMALL LETTER V + {0x8297, 0xFF57}, //206 #FULLWIDTH LATIN SMALL LETTER W + {0x8298, 0xFF58}, //207 #FULLWIDTH LATIN SMALL LETTER X + {0x8299, 0xFF59}, //208 #FULLWIDTH LATIN SMALL LETTER Y + {0x829A, 0xFF5A}, //209 #FULLWIDTH LATIN SMALL LETTER Z + {0x829F, 0x3041}, //210 #HIRAGANA LETTER SMALL A + {0x82A0, 0x3042}, //211 #HIRAGANA LETTER A + {0x82A1, 0x3043}, //212 #HIRAGANA LETTER SMALL I + {0x82A2, 0x3044}, //213 #HIRAGANA LETTER I + {0x82A3, 0x3045}, //214 #HIRAGANA LETTER SMALL U + {0x82A4, 0x3046}, //215 #HIRAGANA LETTER U + {0x82A5, 0x3047}, //216 #HIRAGANA LETTER SMALL E + {0x82A6, 0x3048}, //217 #HIRAGANA LETTER E + {0x82A7, 0x3049}, //218 #HIRAGANA LETTER SMALL O + {0x82A8, 0x304A}, //219 #HIRAGANA LETTER O + {0x82A9, 0x304B}, //220 #HIRAGANA LETTER KA + {0x82AA, 0x304C}, //221 #HIRAGANA LETTER GA + {0x82AB, 0x304D}, //222 #HIRAGANA LETTER KI + {0x82AC, 0x304E}, //223 #HIRAGANA LETTER GI + {0x82AD, 0x304F}, //224 #HIRAGANA LETTER KU + {0x82AE, 0x3050}, //225 #HIRAGANA LETTER GU + {0x82AF, 0x3051}, //226 #HIRAGANA LETTER KE + {0x82B0, 0x3052}, //227 #HIRAGANA LETTER GE + {0x82B1, 0x3053}, //228 #HIRAGANA LETTER KO + {0x82B2, 0x3054}, //229 #HIRAGANA LETTER GO + {0x82B3, 0x3055}, //230 #HIRAGANA LETTER SA + {0x82B4, 0x3056}, //231 #HIRAGANA LETTER ZA + {0x82B5, 0x3057}, //232 #HIRAGANA LETTER SI + {0x82B6, 0x3058}, //233 #HIRAGANA LETTER ZI + {0x82B7, 0x3059}, //234 #HIRAGANA LETTER SU + {0x82B8, 0x305A}, //235 #HIRAGANA LETTER ZU + {0x82B9, 0x305B}, //236 #HIRAGANA LETTER SE + {0x82BA, 0x305C}, //237 #HIRAGANA LETTER ZE + {0x82BB, 0x305D}, //238 #HIRAGANA LETTER SO + {0x82BC, 0x305E}, //239 #HIRAGANA LETTER ZO + {0x82BD, 0x305F}, //240 #HIRAGANA LETTER TA + {0x82BE, 0x3060}, //241 #HIRAGANA LETTER DA + {0x82BF, 0x3061}, //242 #HIRAGANA LETTER TI + {0x82C0, 0x3062}, //243 #HIRAGANA LETTER DI + {0x82C1, 0x3063}, //244 #HIRAGANA LETTER SMALL TU + {0x82C2, 0x3064}, //245 #HIRAGANA LETTER TU + {0x82C3, 0x3065}, //246 #HIRAGANA LETTER DU + {0x82C4, 0x3066}, //247 #HIRAGANA LETTER TE + {0x82C5, 0x3067}, //248 #HIRAGANA LETTER DE + {0x82C6, 0x3068}, //249 #HIRAGANA LETTER TO + {0x82C7, 0x3069}, //250 #HIRAGANA LETTER DO + {0x82C8, 0x306A}, //251 #HIRAGANA LETTER NA + {0x82C9, 0x306B}, //252 #HIRAGANA LETTER NI + {0x82CA, 0x306C}, //253 #HIRAGANA LETTER NU + {0x82CB, 0x306D}, //254 #HIRAGANA LETTER NE + {0x82CC, 0x306E}, //255 #HIRAGANA LETTER NO + {0x82CD, 0x306F}, //256 #HIRAGANA LETTER HA + {0x82CE, 0x3070}, //257 #HIRAGANA LETTER BA + {0x82CF, 0x3071}, //258 #HIRAGANA LETTER PA + {0x82D0, 0x3072}, //259 #HIRAGANA LETTER HI + {0x82D1, 0x3073}, //260 #HIRAGANA LETTER BI + {0x82D2, 0x3074}, //261 #HIRAGANA LETTER PI + {0x82D3, 0x3075}, //262 #HIRAGANA LETTER HU + {0x82D4, 0x3076}, //263 #HIRAGANA LETTER BU + {0x82D5, 0x3077}, //264 #HIRAGANA LETTER PU + {0x82D6, 0x3078}, //265 #HIRAGANA LETTER HE + {0x82D7, 0x3079}, //266 #HIRAGANA LETTER BE + {0x82D8, 0x307A}, //267 #HIRAGANA LETTER PE + {0x82D9, 0x307B}, //268 #HIRAGANA LETTER HO + {0x82DA, 0x307C}, //269 #HIRAGANA LETTER BO + {0x82DB, 0x307D}, //270 #HIRAGANA LETTER PO + {0x82DC, 0x307E}, //271 #HIRAGANA LETTER MA + {0x82DD, 0x307F}, //272 #HIRAGANA LETTER MI + {0x82DE, 0x3080}, //273 #HIRAGANA LETTER MU + {0x82DF, 0x3081}, //274 #HIRAGANA LETTER ME + {0x82E0, 0x3082}, //275 #HIRAGANA LETTER MO + {0x82E1, 0x3083}, //276 #HIRAGANA LETTER SMALL YA + {0x82E2, 0x3084}, //277 #HIRAGANA LETTER YA + {0x82E3, 0x3085}, //278 #HIRAGANA LETTER SMALL YU + {0x82E4, 0x3086}, //279 #HIRAGANA LETTER YU + {0x82E5, 0x3087}, //280 #HIRAGANA LETTER SMALL YO + {0x82E6, 0x3088}, //281 #HIRAGANA LETTER YO + {0x82E7, 0x3089}, //282 #HIRAGANA LETTER RA + {0x82E8, 0x308A}, //283 #HIRAGANA LETTER RI + {0x82E9, 0x308B}, //284 #HIRAGANA LETTER RU + {0x82EA, 0x308C}, //285 #HIRAGANA LETTER RE + {0x82EB, 0x308D}, //286 #HIRAGANA LETTER RO + {0x82EC, 0x308E}, //287 #HIRAGANA LETTER SMALL WA + {0x82ED, 0x308F}, //288 #HIRAGANA LETTER WA + {0x82EE, 0x3090}, //289 #HIRAGANA LETTER WI + {0x82EF, 0x3091}, //290 #HIRAGANA LETTER WE + {0x82F0, 0x3092}, //291 #HIRAGANA LETTER WO + {0x82F1, 0x3093}, //292 #HIRAGANA LETTER N + {0x8340, 0x30A1}, //293 #KATAKANA LETTER SMALL A + {0x8341, 0x30A2}, //294 #KATAKANA LETTER A + {0x8342, 0x30A3}, //295 #KATAKANA LETTER SMALL I + {0x8343, 0x30A4}, //296 #KATAKANA LETTER I + {0x8344, 0x30A5}, //297 #KATAKANA LETTER SMALL U + {0x8345, 0x30A6}, //298 #KATAKANA LETTER U + {0x8346, 0x30A7}, //299 #KATAKANA LETTER SMALL E + {0x8347, 0x30A8}, //300 #KATAKANA LETTER E + {0x8348, 0x30A9}, //301 #KATAKANA LETTER SMALL O + {0x8349, 0x30AA}, //302 #KATAKANA LETTER O + {0x834A, 0x30AB}, //303 #KATAKANA LETTER KA + {0x834B, 0x30AC}, //304 #KATAKANA LETTER GA + {0x834C, 0x30AD}, //305 #KATAKANA LETTER KI + {0x834D, 0x30AE}, //306 #KATAKANA LETTER GI + {0x834E, 0x30AF}, //307 #KATAKANA LETTER KU + {0x834F, 0x30B0}, //308 #KATAKANA LETTER GU + {0x8350, 0x30B1}, //309 #KATAKANA LETTER KE + {0x8351, 0x30B2}, //310 #KATAKANA LETTER GE + {0x8352, 0x30B3}, //311 #KATAKANA LETTER KO + {0x8353, 0x30B4}, //312 #KATAKANA LETTER GO + {0x8354, 0x30B5}, //313 #KATAKANA LETTER SA + {0x8355, 0x30B6}, //314 #KATAKANA LETTER ZA + {0x8356, 0x30B7}, //315 #KATAKANA LETTER SI + {0x8357, 0x30B8}, //316 #KATAKANA LETTER ZI + {0x8358, 0x30B9}, //317 #KATAKANA LETTER SU + {0x8359, 0x30BA}, //318 #KATAKANA LETTER ZU + {0x835A, 0x30BB}, //319 #KATAKANA LETTER SE + {0x835B, 0x30BC}, //320 #KATAKANA LETTER ZE + {0x835C, 0x30BD}, //321 #KATAKANA LETTER SO + {0x835D, 0x30BE}, //322 #KATAKANA LETTER ZO + {0x835E, 0x30BF}, //323 #KATAKANA LETTER TA + {0x835F, 0x30C0}, //324 #KATAKANA LETTER DA + {0x8360, 0x30C1}, //325 #KATAKANA LETTER TI + {0x8361, 0x30C2}, //326 #KATAKANA LETTER DI + {0x8362, 0x30C3}, //327 #KATAKANA LETTER SMALL TU + {0x8363, 0x30C4}, //328 #KATAKANA LETTER TU + {0x8364, 0x30C5}, //329 #KATAKANA LETTER DU + {0x8365, 0x30C6}, //330 #KATAKANA LETTER TE + {0x8366, 0x30C7}, //331 #KATAKANA LETTER DE + {0x8367, 0x30C8}, //332 #KATAKANA LETTER TO + {0x8368, 0x30C9}, //333 #KATAKANA LETTER DO + {0x8369, 0x30CA}, //334 #KATAKANA LETTER NA + {0x836A, 0x30CB}, //335 #KATAKANA LETTER NI + {0x836B, 0x30CC}, //336 #KATAKANA LETTER NU + {0x836C, 0x30CD}, //337 #KATAKANA LETTER NE + {0x836D, 0x30CE}, //338 #KATAKANA LETTER NO + {0x836E, 0x30CF}, //339 #KATAKANA LETTER HA + {0x836F, 0x30D0}, //340 #KATAKANA LETTER BA + {0x8370, 0x30D1}, //341 #KATAKANA LETTER PA + {0x8371, 0x30D2}, //342 #KATAKANA LETTER HI + {0x8372, 0x30D3}, //343 #KATAKANA LETTER BI + {0x8373, 0x30D4}, //344 #KATAKANA LETTER PI + {0x8374, 0x30D5}, //345 #KATAKANA LETTER HU + {0x8375, 0x30D6}, //346 #KATAKANA LETTER BU + {0x8376, 0x30D7}, //347 #KATAKANA LETTER PU + {0x8377, 0x30D8}, //348 #KATAKANA LETTER HE + {0x8378, 0x30D9}, //349 #KATAKANA LETTER BE + {0x8379, 0x30DA}, //350 #KATAKANA LETTER PE + {0x837A, 0x30DB}, //351 #KATAKANA LETTER HO + {0x837B, 0x30DC}, //352 #KATAKANA LETTER BO + {0x837C, 0x30DD}, //353 #KATAKANA LETTER PO + {0x837D, 0x30DE}, //354 #KATAKANA LETTER MA + {0x837E, 0x30DF}, //355 #KATAKANA LETTER MI + {0x8380, 0x30E0}, //356 #KATAKANA LETTER MU + {0x8381, 0x30E1}, //357 #KATAKANA LETTER ME + {0x8382, 0x30E2}, //358 #KATAKANA LETTER MO + {0x8383, 0x30E3}, //359 #KATAKANA LETTER SMALL YA + {0x8384, 0x30E4}, //360 #KATAKANA LETTER YA + {0x8385, 0x30E5}, //361 #KATAKANA LETTER SMALL YU + {0x8386, 0x30E6}, //362 #KATAKANA LETTER YU + {0x8387, 0x30E7}, //363 #KATAKANA LETTER SMALL YO + {0x8388, 0x30E8}, //364 #KATAKANA LETTER YO + {0x8389, 0x30E9}, //365 #KATAKANA LETTER RA + {0x838A, 0x30EA}, //366 #KATAKANA LETTER RI + {0x838B, 0x30EB}, //367 #KATAKANA LETTER RU + {0x838C, 0x30EC}, //368 #KATAKANA LETTER RE + {0x838D, 0x30ED}, //369 #KATAKANA LETTER RO + {0x838E, 0x30EE}, //370 #KATAKANA LETTER SMALL WA + {0x838F, 0x30EF}, //371 #KATAKANA LETTER WA + {0x8390, 0x30F0}, //372 #KATAKANA LETTER WI + {0x8391, 0x30F1}, //373 #KATAKANA LETTER WE + {0x8392, 0x30F2}, //374 #KATAKANA LETTER WO + {0x8393, 0x30F3}, //375 #KATAKANA LETTER N + {0x8394, 0x30F4}, //376 #KATAKANA LETTER VU + {0x8395, 0x30F5}, //377 #KATAKANA LETTER SMALL KA + {0x8396, 0x30F6}, //378 #KATAKANA LETTER SMALL KE + {0x839F, 0x0391}, //379 #GREEK CAPITAL LETTER ALPHA + {0x83A0, 0x0392}, //380 #GREEK CAPITAL LETTER BETA + {0x83A1, 0x0393}, //381 #GREEK CAPITAL LETTER GAMMA + {0x83A2, 0x0394}, //382 #GREEK CAPITAL LETTER DELTA + {0x83A3, 0x0395}, //383 #GREEK CAPITAL LETTER EPSILON + {0x83A4, 0x0396}, //384 #GREEK CAPITAL LETTER ZETA + {0x83A5, 0x0397}, //385 #GREEK CAPITAL LETTER ETA + {0x83A6, 0x0398}, //386 #GREEK CAPITAL LETTER THETA + {0x83A7, 0x0399}, //387 #GREEK CAPITAL LETTER IOTA + {0x83A8, 0x039A}, //388 #GREEK CAPITAL LETTER KAPPA + {0x83A9, 0x039B}, //389 #GREEK CAPITAL LETTER LAMDA + {0x83AA, 0x039C}, //390 #GREEK CAPITAL LETTER MU + {0x83AB, 0x039D}, //391 #GREEK CAPITAL LETTER NU + {0x83AC, 0x039E}, //392 #GREEK CAPITAL LETTER XI + {0x83AD, 0x039F}, //393 #GREEK CAPITAL LETTER OMICRON + {0x83AE, 0x03A0}, //394 #GREEK CAPITAL LETTER PI + {0x83AF, 0x03A1}, //395 #GREEK CAPITAL LETTER RHO + {0x83B0, 0x03A3}, //396 #GREEK CAPITAL LETTER SIGMA + {0x83B1, 0x03A4}, //397 #GREEK CAPITAL LETTER TAU + {0x83B2, 0x03A5}, //398 #GREEK CAPITAL LETTER UPSILON + {0x83B3, 0x03A6}, //399 #GREEK CAPITAL LETTER PHI + {0x83B4, 0x03A7}, //400 #GREEK CAPITAL LETTER CHI + {0x83B5, 0x03A8}, //401 #GREEK CAPITAL LETTER PSI + {0x83B6, 0x03A9}, //402 #GREEK CAPITAL LETTER OMEGA + {0x83BF, 0x03B1}, //403 #GREEK SMALL LETTER ALPHA + {0x83C0, 0x03B2}, //404 #GREEK SMALL LETTER BETA + {0x83C1, 0x03B3}, //405 #GREEK SMALL LETTER GAMMA + {0x83C2, 0x03B4}, //406 #GREEK SMALL LETTER DELTA + {0x83C3, 0x03B5}, //407 #GREEK SMALL LETTER EPSILON + {0x83C4, 0x03B6}, //408 #GREEK SMALL LETTER ZETA + {0x83C5, 0x03B7}, //409 #GREEK SMALL LETTER ETA + {0x83C6, 0x03B8}, //410 #GREEK SMALL LETTER THETA + {0x83C7, 0x03B9}, //411 #GREEK SMALL LETTER IOTA + {0x83C8, 0x03BA}, //412 #GREEK SMALL LETTER KAPPA + {0x83C9, 0x03BB}, //413 #GREEK SMALL LETTER LAMDA + {0x83CA, 0x03BC}, //414 #GREEK SMALL LETTER MU + {0x83CB, 0x03BD}, //415 #GREEK SMALL LETTER NU + {0x83CC, 0x03BE}, //416 #GREEK SMALL LETTER XI + {0x83CD, 0x03BF}, //417 #GREEK SMALL LETTER OMICRON + {0x83CE, 0x03C0}, //418 #GREEK SMALL LETTER PI + {0x83CF, 0x03C1}, //419 #GREEK SMALL LETTER RHO + {0x83D0, 0x03C3}, //420 #GREEK SMALL LETTER SIGMA + {0x83D1, 0x03C4}, //421 #GREEK SMALL LETTER TAU + {0x83D2, 0x03C5}, //422 #GREEK SMALL LETTER UPSILON + {0x83D3, 0x03C6}, //423 #GREEK SMALL LETTER PHI + {0x83D4, 0x03C7}, //424 #GREEK SMALL LETTER CHI + {0x83D5, 0x03C8}, //425 #GREEK SMALL LETTER PSI + {0x83D6, 0x03C9}, //426 #GREEK SMALL LETTER OMEGA + {0x8440, 0x0410}, //427 #CYRILLIC CAPITAL LETTER A + {0x8441, 0x0411}, //428 #CYRILLIC CAPITAL LETTER BE + {0x8442, 0x0412}, //429 #CYRILLIC CAPITAL LETTER VE + {0x8443, 0x0413}, //430 #CYRILLIC CAPITAL LETTER GHE + {0x8444, 0x0414}, //431 #CYRILLIC CAPITAL LETTER DE + {0x8445, 0x0415}, //432 #CYRILLIC CAPITAL LETTER IE + {0x8446, 0x0401}, //433 #CYRILLIC CAPITAL LETTER IO + {0x8447, 0x0416}, //434 #CYRILLIC CAPITAL LETTER ZHE + {0x8448, 0x0417}, //435 #CYRILLIC CAPITAL LETTER ZE + {0x8449, 0x0418}, //436 #CYRILLIC CAPITAL LETTER I + {0x844A, 0x0419}, //437 #CYRILLIC CAPITAL LETTER SHORT I + {0x844B, 0x041A}, //438 #CYRILLIC CAPITAL LETTER KA + {0x844C, 0x041B}, //439 #CYRILLIC CAPITAL LETTER EL + {0x844D, 0x041C}, //440 #CYRILLIC CAPITAL LETTER EM + {0x844E, 0x041D}, //441 #CYRILLIC CAPITAL LETTER EN + {0x844F, 0x041E}, //442 #CYRILLIC CAPITAL LETTER O + {0x8450, 0x041F}, //443 #CYRILLIC CAPITAL LETTER PE + {0x8451, 0x0420}, //444 #CYRILLIC CAPITAL LETTER ER + {0x8452, 0x0421}, //445 #CYRILLIC CAPITAL LETTER ES + {0x8453, 0x0422}, //446 #CYRILLIC CAPITAL LETTER TE + {0x8454, 0x0423}, //447 #CYRILLIC CAPITAL LETTER U + {0x8455, 0x0424}, //448 #CYRILLIC CAPITAL LETTER EF + {0x8456, 0x0425}, //449 #CYRILLIC CAPITAL LETTER HA + {0x8457, 0x0426}, //450 #CYRILLIC CAPITAL LETTER TSE + {0x8458, 0x0427}, //451 #CYRILLIC CAPITAL LETTER CHE + {0x8459, 0x0428}, //452 #CYRILLIC CAPITAL LETTER SHA + {0x845A, 0x0429}, //453 #CYRILLIC CAPITAL LETTER SHCHA + {0x845B, 0x042A}, //454 #CYRILLIC CAPITAL LETTER HARD SIGN + {0x845C, 0x042B}, //455 #CYRILLIC CAPITAL LETTER YERU + {0x845D, 0x042C}, //456 #CYRILLIC CAPITAL LETTER SOFT SIGN + {0x845E, 0x042D}, //457 #CYRILLIC CAPITAL LETTER E + {0x845F, 0x042E}, //458 #CYRILLIC CAPITAL LETTER YU + {0x8460, 0x042F}, //459 #CYRILLIC CAPITAL LETTER YA + {0x8470, 0x0430}, //460 #CYRILLIC SMALL LETTER A + {0x8471, 0x0431}, //461 #CYRILLIC SMALL LETTER BE + {0x8472, 0x0432}, //462 #CYRILLIC SMALL LETTER VE + {0x8473, 0x0433}, //463 #CYRILLIC SMALL LETTER GHE + {0x8474, 0x0434}, //464 #CYRILLIC SMALL LETTER DE + {0x8475, 0x0435}, //465 #CYRILLIC SMALL LETTER IE + {0x8476, 0x0451}, //466 #CYRILLIC SMALL LETTER IO + {0x8477, 0x0436}, //467 #CYRILLIC SMALL LETTER ZHE + {0x8478, 0x0437}, //468 #CYRILLIC SMALL LETTER ZE + {0x8479, 0x0438}, //469 #CYRILLIC SMALL LETTER I + {0x847A, 0x0439}, //470 #CYRILLIC SMALL LETTER SHORT I + {0x847B, 0x043A}, //471 #CYRILLIC SMALL LETTER KA + {0x847C, 0x043B}, //472 #CYRILLIC SMALL LETTER EL + {0x847D, 0x043C}, //473 #CYRILLIC SMALL LETTER EM + {0x847E, 0x043D}, //474 #CYRILLIC SMALL LETTER EN + {0x8480, 0x043E}, //475 #CYRILLIC SMALL LETTER O + {0x8481, 0x043F}, //476 #CYRILLIC SMALL LETTER PE + {0x8482, 0x0440}, //477 #CYRILLIC SMALL LETTER ER + {0x8483, 0x0441}, //478 #CYRILLIC SMALL LETTER ES + {0x8484, 0x0442}, //479 #CYRILLIC SMALL LETTER TE + {0x8485, 0x0443}, //480 #CYRILLIC SMALL LETTER U + {0x8486, 0x0444}, //481 #CYRILLIC SMALL LETTER EF + {0x8487, 0x0445}, //482 #CYRILLIC SMALL LETTER HA + {0x8488, 0x0446}, //483 #CYRILLIC SMALL LETTER TSE + {0x8489, 0x0447}, //484 #CYRILLIC SMALL LETTER CHE + {0x848A, 0x0448}, //485 #CYRILLIC SMALL LETTER SHA + {0x848B, 0x0449}, //486 #CYRILLIC SMALL LETTER SHCHA + {0x848C, 0x044A}, //487 #CYRILLIC SMALL LETTER HARD SIGN + {0x848D, 0x044B}, //488 #CYRILLIC SMALL LETTER YERU + {0x848E, 0x044C}, //489 #CYRILLIC SMALL LETTER SOFT SIGN + {0x848F, 0x044D}, //490 #CYRILLIC SMALL LETTER E + {0x8490, 0x044E}, //491 #CYRILLIC SMALL LETTER YU + {0x8491, 0x044F}, //492 #CYRILLIC SMALL LETTER YA + {0x849F, 0x2500}, //493 #BOX DRAWINGS LIGHT HORIZONTAL + {0x84A0, 0x2502}, //494 #BOX DRAWINGS LIGHT VERTICAL + {0x84A1, 0x250C}, //495 #BOX DRAWINGS LIGHT DOWN AND RIGHT + {0x84A2, 0x2510}, //496 #BOX DRAWINGS LIGHT DOWN AND LEFT + {0x84A3, 0x2518}, //497 #BOX DRAWINGS LIGHT UP AND LEFT + {0x84A4, 0x2514}, //498 #BOX DRAWINGS LIGHT UP AND RIGHT + {0x84A5, 0x251C}, //499 #BOX DRAWINGS LIGHT VERTICAL AND RIGHT + {0x84A6, 0x252C}, //500 #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + {0x84A7, 0x2524}, //501 #BOX DRAWINGS LIGHT VERTICAL AND LEFT + {0x84A8, 0x2534}, //502 #BOX DRAWINGS LIGHT UP AND HORIZONTAL + {0x84A9, 0x253C}, //503 #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + {0x84AA, 0x2501}, //504 #BOX DRAWINGS HEAVY HORIZONTAL + {0x84AB, 0x2503}, //505 #BOX DRAWINGS HEAVY VERTICAL + {0x84AC, 0x250F}, //506 #BOX DRAWINGS HEAVY DOWN AND RIGHT + {0x84AD, 0x2513}, //507 #BOX DRAWINGS HEAVY DOWN AND LEFT + {0x84AE, 0x251B}, //508 #BOX DRAWINGS HEAVY UP AND LEFT + {0x84AF, 0x2517}, //509 #BOX DRAWINGS HEAVY UP AND RIGHT + {0x84B0, 0x2523}, //510 #BOX DRAWINGS HEAVY VERTICAL AND RIGHT + {0x84B1, 0x2533}, //511 #BOX DRAWINGS HEAVY DOWN AND HORIZONTAL + {0x84B2, 0x252B}, //512 #BOX DRAWINGS HEAVY VERTICAL AND LEFT + {0x84B3, 0x253B}, //513 #BOX DRAWINGS HEAVY UP AND HORIZONTAL + {0x84B4, 0x254B}, //514 #BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL + {0x84B5, 0x2520}, //515 #BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT + {0x84B6, 0x252F}, //516 #BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY + {0x84B7, 0x2528}, //517 #BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT + {0x84B8, 0x2537}, //518 #BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY + {0x84B9, 0x253F}, //519 #BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY + {0x84BA, 0x251D}, //520 #BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY + {0x84BB, 0x2530}, //521 #BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT + {0x84BC, 0x2525}, //522 #BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY + {0x84BD, 0x2538}, //523 #BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT + {0x84BE, 0x2542}, //524 #BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT + {0x8740, 0x2460}, //525 #CIRCLED DIGIT ONE + {0x8741, 0x2461}, //526 #CIRCLED DIGIT TWO + {0x8742, 0x2462}, //527 #CIRCLED DIGIT THREE + {0x8743, 0x2463}, //528 #CIRCLED DIGIT FOUR + {0x8744, 0x2464}, //529 #CIRCLED DIGIT FIVE + {0x8745, 0x2465}, //530 #CIRCLED DIGIT SIX + {0x8746, 0x2466}, //531 #CIRCLED DIGIT SEVEN + {0x8747, 0x2467}, //532 #CIRCLED DIGIT EIGHT + {0x8748, 0x2468}, //533 #CIRCLED DIGIT NINE + {0x8749, 0x2469}, //534 #CIRCLED NUMBER TEN + {0x874A, 0x246A}, //535 #CIRCLED NUMBER ELEVEN + {0x874B, 0x246B}, //536 #CIRCLED NUMBER TWELVE + {0x874C, 0x246C}, //537 #CIRCLED NUMBER THIRTEEN + {0x874D, 0x246D}, //538 #CIRCLED NUMBER FOURTEEN + {0x874E, 0x246E}, //539 #CIRCLED NUMBER FIFTEEN + {0x874F, 0x246F}, //540 #CIRCLED NUMBER SIXTEEN + {0x8750, 0x2470}, //541 #CIRCLED NUMBER SEVENTEEN + {0x8751, 0x2471}, //542 #CIRCLED NUMBER EIGHTEEN + {0x8752, 0x2472}, //543 #CIRCLED NUMBER NINETEEN + {0x8753, 0x2473}, //544 #CIRCLED NUMBER TWENTY + {0x8754, 0x2160}, //545 #ROMAN NUMERAL ONE + {0x8755, 0x2161}, //546 #ROMAN NUMERAL TWO + {0x8756, 0x2162}, //547 #ROMAN NUMERAL THREE + {0x8757, 0x2163}, //548 #ROMAN NUMERAL FOUR + {0x8758, 0x2164}, //549 #ROMAN NUMERAL FIVE + {0x8759, 0x2165}, //550 #ROMAN NUMERAL SIX + {0x875A, 0x2166}, //551 #ROMAN NUMERAL SEVEN + {0x875B, 0x2167}, //552 #ROMAN NUMERAL EIGHT + {0x875C, 0x2168}, //553 #ROMAN NUMERAL NINE + {0x875D, 0x2169}, //554 #ROMAN NUMERAL TEN + {0x875F, 0x3349}, //555 #SQUARE MIRI + {0x8760, 0x3314}, //556 #SQUARE KIRO + {0x8761, 0x3322}, //557 #SQUARE SENTI + {0x8762, 0x334D}, //558 #SQUARE MEETORU + {0x8763, 0x3318}, //559 #SQUARE GURAMU + {0x8764, 0x3327}, //560 #SQUARE TON + {0x8765, 0x3303}, //561 #SQUARE AARU + {0x8766, 0x3336}, //562 #SQUARE HEKUTAARU + {0x8767, 0x3351}, //563 #SQUARE RITTORU + {0x8768, 0x3357}, //564 #SQUARE WATTO + {0x8769, 0x330D}, //565 #SQUARE KARORII + {0x876A, 0x3326}, //566 #SQUARE DORU + {0x876B, 0x3323}, //567 #SQUARE SENTO + {0x876C, 0x332B}, //568 #SQUARE PAASENTO + {0x876D, 0x334A}, //569 #SQUARE MIRIBAARU + {0x876E, 0x333B}, //570 #SQUARE PEEZI + {0x876F, 0x339C}, //571 #SQUARE MM + {0x8770, 0x339D}, //572 #SQUARE CM + {0x8771, 0x339E}, //573 #SQUARE KM + {0x8772, 0x338E}, //574 #SQUARE MG + {0x8773, 0x338F}, //575 #SQUARE KG + {0x8774, 0x33C4}, //576 #SQUARE CC + {0x8775, 0x33A1}, //577 #SQUARE M SQUARED + {0x877E, 0x337B}, //578 #SQUARE ERA NAME HEISEI + {0x8780, 0x301D}, //579 #REVERSED DOUBLE PRIME QUOTATION MARK + {0x8781, 0x301F}, //580 #LOW DOUBLE PRIME QUOTATION MARK + {0x8782, 0x2116}, //581 #NUMERO SIGN + {0x8783, 0x33CD}, //582 #SQUARE KK + {0x8784, 0x2121}, //583 #TELEPHONE SIGN + {0x8785, 0x32A4}, //584 #CIRCLED IDEOGRAPH HIGH + {0x8786, 0x32A5}, //585 #CIRCLED IDEOGRAPH CENTRE + {0x8787, 0x32A6}, //586 #CIRCLED IDEOGRAPH LOW + {0x8788, 0x32A7}, //587 #CIRCLED IDEOGRAPH LEFT + {0x8789, 0x32A8}, //588 #CIRCLED IDEOGRAPH RIGHT + {0x878A, 0x3231}, //589 #PARENTHESIZED IDEOGRAPH STOCK + {0x878B, 0x3232}, //590 #PARENTHESIZED IDEOGRAPH HAVE + {0x878C, 0x3239}, //591 #PARENTHESIZED IDEOGRAPH REPRESENT + {0x878D, 0x337E}, //592 #SQUARE ERA NAME MEIZI + {0x878E, 0x337D}, //593 #SQUARE ERA NAME TAISYOU + {0x878F, 0x337C}, //594 #SQUARE ERA NAME SYOUWA + {0x8790, 0x2252}, //595 #APPROXIMATELY EQUAL TO OR THE IMAGE OF + {0x8791, 0x2261}, //596 #IDENTICAL TO + {0x8792, 0x222B}, //597 #INTEGRAL + {0x8793, 0x222E}, //598 #CONTOUR INTEGRAL + {0x8794, 0x2211}, //599 #N-ARY SUMMATION + {0x8795, 0x221A}, //600 #SQUARE ROOT + {0x8796, 0x22A5}, //601 #UP TACK + {0x8797, 0x2220}, //602 #ANGLE + {0x8798, 0x221F}, //603 #RIGHT ANGLE + {0x8799, 0x22BF}, //604 #RIGHT TRIANGLE + {0x879A, 0x2235}, //605 #BECAUSE + {0x879B, 0x2229}, //606 #INTERSECTION + {0x879C, 0x222A}, //607 #UNION + {0x889F, 0x4E9C}, //608 #CJK UNIFIED IDEOGRAPH + {0x88A0, 0x5516}, //609 #CJK UNIFIED IDEOGRAPH + {0x88A1, 0x5A03}, //610 #CJK UNIFIED IDEOGRAPH + {0x88A2, 0x963F}, //611 #CJK UNIFIED IDEOGRAPH + {0x88A3, 0x54C0}, //612 #CJK UNIFIED IDEOGRAPH + {0x88A4, 0x611B}, //613 #CJK UNIFIED IDEOGRAPH + {0x88A5, 0x6328}, //614 #CJK UNIFIED IDEOGRAPH + {0x88A6, 0x59F6}, //615 #CJK UNIFIED IDEOGRAPH + {0x88A7, 0x9022}, //616 #CJK UNIFIED IDEOGRAPH + {0x88A8, 0x8475}, //617 #CJK UNIFIED IDEOGRAPH + {0x88A9, 0x831C}, //618 #CJK UNIFIED IDEOGRAPH + {0x88AA, 0x7A50}, //619 #CJK UNIFIED IDEOGRAPH + {0x88AB, 0x60AA}, //620 #CJK UNIFIED IDEOGRAPH + {0x88AC, 0x63E1}, //621 #CJK UNIFIED IDEOGRAPH + {0x88AD, 0x6E25}, //622 #CJK UNIFIED IDEOGRAPH + {0x88AE, 0x65ED}, //623 #CJK UNIFIED IDEOGRAPH + {0x88AF, 0x8466}, //624 #CJK UNIFIED IDEOGRAPH + {0x88B0, 0x82A6}, //625 #CJK UNIFIED IDEOGRAPH + {0x88B1, 0x9BF5}, //626 #CJK UNIFIED IDEOGRAPH + {0x88B2, 0x6893}, //627 #CJK UNIFIED IDEOGRAPH + {0x88B3, 0x5727}, //628 #CJK UNIFIED IDEOGRAPH + {0x88B4, 0x65A1}, //629 #CJK UNIFIED IDEOGRAPH + {0x88B5, 0x6271}, //630 #CJK UNIFIED IDEOGRAPH + {0x88B6, 0x5B9B}, //631 #CJK UNIFIED IDEOGRAPH + {0x88B7, 0x59D0}, //632 #CJK UNIFIED IDEOGRAPH + {0x88B8, 0x867B}, //633 #CJK UNIFIED IDEOGRAPH + {0x88B9, 0x98F4}, //634 #CJK UNIFIED IDEOGRAPH + {0x88BA, 0x7D62}, //635 #CJK UNIFIED IDEOGRAPH + {0x88BB, 0x7DBE}, //636 #CJK UNIFIED IDEOGRAPH + {0x88BC, 0x9B8E}, //637 #CJK UNIFIED IDEOGRAPH + {0x88BD, 0x6216}, //638 #CJK UNIFIED IDEOGRAPH + {0x88BE, 0x7C9F}, //639 #CJK UNIFIED IDEOGRAPH + {0x88BF, 0x88B7}, //640 #CJK UNIFIED IDEOGRAPH + {0x88C0, 0x5B89}, //641 #CJK UNIFIED IDEOGRAPH + {0x88C1, 0x5EB5}, //642 #CJK UNIFIED IDEOGRAPH + {0x88C2, 0x6309}, //643 #CJK UNIFIED IDEOGRAPH + {0x88C3, 0x6697}, //644 #CJK UNIFIED IDEOGRAPH + {0x88C4, 0x6848}, //645 #CJK UNIFIED IDEOGRAPH + {0x88C5, 0x95C7}, //646 #CJK UNIFIED IDEOGRAPH + {0x88C6, 0x978D}, //647 #CJK UNIFIED IDEOGRAPH + {0x88C7, 0x674F}, //648 #CJK UNIFIED IDEOGRAPH + {0x88C8, 0x4EE5}, //649 #CJK UNIFIED IDEOGRAPH + {0x88C9, 0x4F0A}, //650 #CJK UNIFIED IDEOGRAPH + {0x88CA, 0x4F4D}, //651 #CJK UNIFIED IDEOGRAPH + {0x88CB, 0x4F9D}, //652 #CJK UNIFIED IDEOGRAPH + {0x88CC, 0x5049}, //653 #CJK UNIFIED IDEOGRAPH + {0x88CD, 0x56F2}, //654 #CJK UNIFIED IDEOGRAPH + {0x88CE, 0x5937}, //655 #CJK UNIFIED IDEOGRAPH + {0x88CF, 0x59D4}, //656 #CJK UNIFIED IDEOGRAPH + {0x88D0, 0x5A01}, //657 #CJK UNIFIED IDEOGRAPH + {0x88D1, 0x5C09}, //658 #CJK UNIFIED IDEOGRAPH + {0x88D2, 0x60DF}, //659 #CJK UNIFIED IDEOGRAPH + {0x88D3, 0x610F}, //660 #CJK UNIFIED IDEOGRAPH + {0x88D4, 0x6170}, //661 #CJK UNIFIED IDEOGRAPH + {0x88D5, 0x6613}, //662 #CJK UNIFIED IDEOGRAPH + {0x88D6, 0x6905}, //663 #CJK UNIFIED IDEOGRAPH + {0x88D7, 0x70BA}, //664 #CJK UNIFIED IDEOGRAPH + {0x88D8, 0x754F}, //665 #CJK UNIFIED IDEOGRAPH + {0x88D9, 0x7570}, //666 #CJK UNIFIED IDEOGRAPH + {0x88DA, 0x79FB}, //667 #CJK UNIFIED IDEOGRAPH + {0x88DB, 0x7DAD}, //668 #CJK UNIFIED IDEOGRAPH + {0x88DC, 0x7DEF}, //669 #CJK UNIFIED IDEOGRAPH + {0x88DD, 0x80C3}, //670 #CJK UNIFIED IDEOGRAPH + {0x88DE, 0x840E}, //671 #CJK UNIFIED IDEOGRAPH + {0x88DF, 0x8863}, //672 #CJK UNIFIED IDEOGRAPH + {0x88E0, 0x8B02}, //673 #CJK UNIFIED IDEOGRAPH + {0x88E1, 0x9055}, //674 #CJK UNIFIED IDEOGRAPH + {0x88E2, 0x907A}, //675 #CJK UNIFIED IDEOGRAPH + {0x88E3, 0x533B}, //676 #CJK UNIFIED IDEOGRAPH + {0x88E4, 0x4E95}, //677 #CJK UNIFIED IDEOGRAPH + {0x88E5, 0x4EA5}, //678 #CJK UNIFIED IDEOGRAPH + {0x88E6, 0x57DF}, //679 #CJK UNIFIED IDEOGRAPH + {0x88E7, 0x80B2}, //680 #CJK UNIFIED IDEOGRAPH + {0x88E8, 0x90C1}, //681 #CJK UNIFIED IDEOGRAPH + {0x88E9, 0x78EF}, //682 #CJK UNIFIED IDEOGRAPH + {0x88EA, 0x4E00}, //683 #CJK UNIFIED IDEOGRAPH + {0x88EB, 0x58F1}, //684 #CJK UNIFIED IDEOGRAPH + {0x88EC, 0x6EA2}, //685 #CJK UNIFIED IDEOGRAPH + {0x88ED, 0x9038}, //686 #CJK UNIFIED IDEOGRAPH + {0x88EE, 0x7A32}, //687 #CJK UNIFIED IDEOGRAPH + {0x88EF, 0x8328}, //688 #CJK UNIFIED IDEOGRAPH + {0x88F0, 0x828B}, //689 #CJK UNIFIED IDEOGRAPH + {0x88F1, 0x9C2F}, //690 #CJK UNIFIED IDEOGRAPH + {0x88F2, 0x5141}, //691 #CJK UNIFIED IDEOGRAPH + {0x88F3, 0x5370}, //692 #CJK UNIFIED IDEOGRAPH + {0x88F4, 0x54BD}, //693 #CJK UNIFIED IDEOGRAPH + {0x88F5, 0x54E1}, //694 #CJK UNIFIED IDEOGRAPH + {0x88F6, 0x56E0}, //695 #CJK UNIFIED IDEOGRAPH + {0x88F7, 0x59FB}, //696 #CJK UNIFIED IDEOGRAPH + {0x88F8, 0x5F15}, //697 #CJK UNIFIED IDEOGRAPH + {0x88F9, 0x98F2}, //698 #CJK UNIFIED IDEOGRAPH + {0x88FA, 0x6DEB}, //699 #CJK UNIFIED IDEOGRAPH + {0x88FB, 0x80E4}, //700 #CJK UNIFIED IDEOGRAPH + {0x88FC, 0x852D}, //701 #CJK UNIFIED IDEOGRAPH + {0x8940, 0x9662}, //702 #CJK UNIFIED IDEOGRAPH + {0x8941, 0x9670}, //703 #CJK UNIFIED IDEOGRAPH + {0x8942, 0x96A0}, //704 #CJK UNIFIED IDEOGRAPH + {0x8943, 0x97FB}, //705 #CJK UNIFIED IDEOGRAPH + {0x8944, 0x540B}, //706 #CJK UNIFIED IDEOGRAPH + {0x8945, 0x53F3}, //707 #CJK UNIFIED IDEOGRAPH + {0x8946, 0x5B87}, //708 #CJK UNIFIED IDEOGRAPH + {0x8947, 0x70CF}, //709 #CJK UNIFIED IDEOGRAPH + {0x8948, 0x7FBD}, //710 #CJK UNIFIED IDEOGRAPH + {0x8949, 0x8FC2}, //711 #CJK UNIFIED IDEOGRAPH + {0x894A, 0x96E8}, //712 #CJK UNIFIED IDEOGRAPH + {0x894B, 0x536F}, //713 #CJK UNIFIED IDEOGRAPH + {0x894C, 0x9D5C}, //714 #CJK UNIFIED IDEOGRAPH + {0x894D, 0x7ABA}, //715 #CJK UNIFIED IDEOGRAPH + {0x894E, 0x4E11}, //716 #CJK UNIFIED IDEOGRAPH + {0x894F, 0x7893}, //717 #CJK UNIFIED IDEOGRAPH + {0x8950, 0x81FC}, //718 #CJK UNIFIED IDEOGRAPH + {0x8951, 0x6E26}, //719 #CJK UNIFIED IDEOGRAPH + {0x8952, 0x5618}, //720 #CJK UNIFIED IDEOGRAPH + {0x8953, 0x5504}, //721 #CJK UNIFIED IDEOGRAPH + {0x8954, 0x6B1D}, //722 #CJK UNIFIED IDEOGRAPH + {0x8955, 0x851A}, //723 #CJK UNIFIED IDEOGRAPH + {0x8956, 0x9C3B}, //724 #CJK UNIFIED IDEOGRAPH + {0x8957, 0x59E5}, //725 #CJK UNIFIED IDEOGRAPH + {0x8958, 0x53A9}, //726 #CJK UNIFIED IDEOGRAPH + {0x8959, 0x6D66}, //727 #CJK UNIFIED IDEOGRAPH + {0x895A, 0x74DC}, //728 #CJK UNIFIED IDEOGRAPH + {0x895B, 0x958F}, //729 #CJK UNIFIED IDEOGRAPH + {0x895C, 0x5642}, //730 #CJK UNIFIED IDEOGRAPH + {0x895D, 0x4E91}, //731 #CJK UNIFIED IDEOGRAPH + {0x895E, 0x904B}, //732 #CJK UNIFIED IDEOGRAPH + {0x895F, 0x96F2}, //733 #CJK UNIFIED IDEOGRAPH + {0x8960, 0x834F}, //734 #CJK UNIFIED IDEOGRAPH + {0x8961, 0x990C}, //735 #CJK UNIFIED IDEOGRAPH + {0x8962, 0x53E1}, //736 #CJK UNIFIED IDEOGRAPH + {0x8963, 0x55B6}, //737 #CJK UNIFIED IDEOGRAPH + {0x8964, 0x5B30}, //738 #CJK UNIFIED IDEOGRAPH + {0x8965, 0x5F71}, //739 #CJK UNIFIED IDEOGRAPH + {0x8966, 0x6620}, //740 #CJK UNIFIED IDEOGRAPH + {0x8967, 0x66F3}, //741 #CJK UNIFIED IDEOGRAPH + {0x8968, 0x6804}, //742 #CJK UNIFIED IDEOGRAPH + {0x8969, 0x6C38}, //743 #CJK UNIFIED IDEOGRAPH + {0x896A, 0x6CF3}, //744 #CJK UNIFIED IDEOGRAPH + {0x896B, 0x6D29}, //745 #CJK UNIFIED IDEOGRAPH + {0x896C, 0x745B}, //746 #CJK UNIFIED IDEOGRAPH + {0x896D, 0x76C8}, //747 #CJK UNIFIED IDEOGRAPH + {0x896E, 0x7A4E}, //748 #CJK UNIFIED IDEOGRAPH + {0x896F, 0x9834}, //749 #CJK UNIFIED IDEOGRAPH + {0x8970, 0x82F1}, //750 #CJK UNIFIED IDEOGRAPH + {0x8971, 0x885B}, //751 #CJK UNIFIED IDEOGRAPH + {0x8972, 0x8A60}, //752 #CJK UNIFIED IDEOGRAPH + {0x8973, 0x92ED}, //753 #CJK UNIFIED IDEOGRAPH + {0x8974, 0x6DB2}, //754 #CJK UNIFIED IDEOGRAPH + {0x8975, 0x75AB}, //755 #CJK UNIFIED IDEOGRAPH + {0x8976, 0x76CA}, //756 #CJK UNIFIED IDEOGRAPH + {0x8977, 0x99C5}, //757 #CJK UNIFIED IDEOGRAPH + {0x8978, 0x60A6}, //758 #CJK UNIFIED IDEOGRAPH + {0x8979, 0x8B01}, //759 #CJK UNIFIED IDEOGRAPH + {0x897A, 0x8D8A}, //760 #CJK UNIFIED IDEOGRAPH + {0x897B, 0x95B2}, //761 #CJK UNIFIED IDEOGRAPH + {0x897C, 0x698E}, //762 #CJK UNIFIED IDEOGRAPH + {0x897D, 0x53AD}, //763 #CJK UNIFIED IDEOGRAPH + {0x897E, 0x5186}, //764 #CJK UNIFIED IDEOGRAPH + {0x8980, 0x5712}, //765 #CJK UNIFIED IDEOGRAPH + {0x8981, 0x5830}, //766 #CJK UNIFIED IDEOGRAPH + {0x8982, 0x5944}, //767 #CJK UNIFIED IDEOGRAPH + {0x8983, 0x5BB4}, //768 #CJK UNIFIED IDEOGRAPH + {0x8984, 0x5EF6}, //769 #CJK UNIFIED IDEOGRAPH + {0x8985, 0x6028}, //770 #CJK UNIFIED IDEOGRAPH + {0x8986, 0x63A9}, //771 #CJK UNIFIED IDEOGRAPH + {0x8987, 0x63F4}, //772 #CJK UNIFIED IDEOGRAPH + {0x8988, 0x6CBF}, //773 #CJK UNIFIED IDEOGRAPH + {0x8989, 0x6F14}, //774 #CJK UNIFIED IDEOGRAPH + {0x898A, 0x708E}, //775 #CJK UNIFIED IDEOGRAPH + {0x898B, 0x7114}, //776 #CJK UNIFIED IDEOGRAPH + {0x898C, 0x7159}, //777 #CJK UNIFIED IDEOGRAPH + {0x898D, 0x71D5}, //778 #CJK UNIFIED IDEOGRAPH + {0x898E, 0x733F}, //779 #CJK UNIFIED IDEOGRAPH + {0x898F, 0x7E01}, //780 #CJK UNIFIED IDEOGRAPH + {0x8990, 0x8276}, //781 #CJK UNIFIED IDEOGRAPH + {0x8991, 0x82D1}, //782 #CJK UNIFIED IDEOGRAPH + {0x8992, 0x8597}, //783 #CJK UNIFIED IDEOGRAPH + {0x8993, 0x9060}, //784 #CJK UNIFIED IDEOGRAPH + {0x8994, 0x925B}, //785 #CJK UNIFIED IDEOGRAPH + {0x8995, 0x9D1B}, //786 #CJK UNIFIED IDEOGRAPH + {0x8996, 0x5869}, //787 #CJK UNIFIED IDEOGRAPH + {0x8997, 0x65BC}, //788 #CJK UNIFIED IDEOGRAPH + {0x8998, 0x6C5A}, //789 #CJK UNIFIED IDEOGRAPH + {0x8999, 0x7525}, //790 #CJK UNIFIED IDEOGRAPH + {0x899A, 0x51F9}, //791 #CJK UNIFIED IDEOGRAPH + {0x899B, 0x592E}, //792 #CJK UNIFIED IDEOGRAPH + {0x899C, 0x5965}, //793 #CJK UNIFIED IDEOGRAPH + {0x899D, 0x5F80}, //794 #CJK UNIFIED IDEOGRAPH + {0x899E, 0x5FDC}, //795 #CJK UNIFIED IDEOGRAPH + {0x899F, 0x62BC}, //796 #CJK UNIFIED IDEOGRAPH + {0x89A0, 0x65FA}, //797 #CJK UNIFIED IDEOGRAPH + {0x89A1, 0x6A2A}, //798 #CJK UNIFIED IDEOGRAPH + {0x89A2, 0x6B27}, //799 #CJK UNIFIED IDEOGRAPH + {0x89A3, 0x6BB4}, //800 #CJK UNIFIED IDEOGRAPH + {0x89A4, 0x738B}, //801 #CJK UNIFIED IDEOGRAPH + {0x89A5, 0x7FC1}, //802 #CJK UNIFIED IDEOGRAPH + {0x89A6, 0x8956}, //803 #CJK UNIFIED IDEOGRAPH + {0x89A7, 0x9D2C}, //804 #CJK UNIFIED IDEOGRAPH + {0x89A8, 0x9D0E}, //805 #CJK UNIFIED IDEOGRAPH + {0x89A9, 0x9EC4}, //806 #CJK UNIFIED IDEOGRAPH + {0x89AA, 0x5CA1}, //807 #CJK UNIFIED IDEOGRAPH + {0x89AB, 0x6C96}, //808 #CJK UNIFIED IDEOGRAPH + {0x89AC, 0x837B}, //809 #CJK UNIFIED IDEOGRAPH + {0x89AD, 0x5104}, //810 #CJK UNIFIED IDEOGRAPH + {0x89AE, 0x5C4B}, //811 #CJK UNIFIED IDEOGRAPH + {0x89AF, 0x61B6}, //812 #CJK UNIFIED IDEOGRAPH + {0x89B0, 0x81C6}, //813 #CJK UNIFIED IDEOGRAPH + {0x89B1, 0x6876}, //814 #CJK UNIFIED IDEOGRAPH + {0x89B2, 0x7261}, //815 #CJK UNIFIED IDEOGRAPH + {0x89B3, 0x4E59}, //816 #CJK UNIFIED IDEOGRAPH + {0x89B4, 0x4FFA}, //817 #CJK UNIFIED IDEOGRAPH + {0x89B5, 0x5378}, //818 #CJK UNIFIED IDEOGRAPH + {0x89B6, 0x6069}, //819 #CJK UNIFIED IDEOGRAPH + {0x89B7, 0x6E29}, //820 #CJK UNIFIED IDEOGRAPH + {0x89B8, 0x7A4F}, //821 #CJK UNIFIED IDEOGRAPH + {0x89B9, 0x97F3}, //822 #CJK UNIFIED IDEOGRAPH + {0x89BA, 0x4E0B}, //823 #CJK UNIFIED IDEOGRAPH + {0x89BB, 0x5316}, //824 #CJK UNIFIED IDEOGRAPH + {0x89BC, 0x4EEE}, //825 #CJK UNIFIED IDEOGRAPH + {0x89BD, 0x4F55}, //826 #CJK UNIFIED IDEOGRAPH + {0x89BE, 0x4F3D}, //827 #CJK UNIFIED IDEOGRAPH + {0x89BF, 0x4FA1}, //828 #CJK UNIFIED IDEOGRAPH + {0x89C0, 0x4F73}, //829 #CJK UNIFIED IDEOGRAPH + {0x89C1, 0x52A0}, //830 #CJK UNIFIED IDEOGRAPH + {0x89C2, 0x53EF}, //831 #CJK UNIFIED IDEOGRAPH + {0x89C3, 0x5609}, //832 #CJK UNIFIED IDEOGRAPH + {0x89C4, 0x590F}, //833 #CJK UNIFIED IDEOGRAPH + {0x89C5, 0x5AC1}, //834 #CJK UNIFIED IDEOGRAPH + {0x89C6, 0x5BB6}, //835 #CJK UNIFIED IDEOGRAPH + {0x89C7, 0x5BE1}, //836 #CJK UNIFIED IDEOGRAPH + {0x89C8, 0x79D1}, //837 #CJK UNIFIED IDEOGRAPH + {0x89C9, 0x6687}, //838 #CJK UNIFIED IDEOGRAPH + {0x89CA, 0x679C}, //839 #CJK UNIFIED IDEOGRAPH + {0x89CB, 0x67B6}, //840 #CJK UNIFIED IDEOGRAPH + {0x89CC, 0x6B4C}, //841 #CJK UNIFIED IDEOGRAPH + {0x89CD, 0x6CB3}, //842 #CJK UNIFIED IDEOGRAPH + {0x89CE, 0x706B}, //843 #CJK UNIFIED IDEOGRAPH + {0x89CF, 0x73C2}, //844 #CJK UNIFIED IDEOGRAPH + {0x89D0, 0x798D}, //845 #CJK UNIFIED IDEOGRAPH + {0x89D1, 0x79BE}, //846 #CJK UNIFIED IDEOGRAPH + {0x89D2, 0x7A3C}, //847 #CJK UNIFIED IDEOGRAPH + {0x89D3, 0x7B87}, //848 #CJK UNIFIED IDEOGRAPH + {0x89D4, 0x82B1}, //849 #CJK UNIFIED IDEOGRAPH + {0x89D5, 0x82DB}, //850 #CJK UNIFIED IDEOGRAPH + {0x89D6, 0x8304}, //851 #CJK UNIFIED IDEOGRAPH + {0x89D7, 0x8377}, //852 #CJK UNIFIED IDEOGRAPH + {0x89D8, 0x83EF}, //853 #CJK UNIFIED IDEOGRAPH + {0x89D9, 0x83D3}, //854 #CJK UNIFIED IDEOGRAPH + {0x89DA, 0x8766}, //855 #CJK UNIFIED IDEOGRAPH + {0x89DB, 0x8AB2}, //856 #CJK UNIFIED IDEOGRAPH + {0x89DC, 0x5629}, //857 #CJK UNIFIED IDEOGRAPH + {0x89DD, 0x8CA8}, //858 #CJK UNIFIED IDEOGRAPH + {0x89DE, 0x8FE6}, //859 #CJK UNIFIED IDEOGRAPH + {0x89DF, 0x904E}, //860 #CJK UNIFIED IDEOGRAPH + {0x89E0, 0x971E}, //861 #CJK UNIFIED IDEOGRAPH + {0x89E1, 0x868A}, //862 #CJK UNIFIED IDEOGRAPH + {0x89E2, 0x4FC4}, //863 #CJK UNIFIED IDEOGRAPH + {0x89E3, 0x5CE8}, //864 #CJK UNIFIED IDEOGRAPH + {0x89E4, 0x6211}, //865 #CJK UNIFIED IDEOGRAPH + {0x89E5, 0x7259}, //866 #CJK UNIFIED IDEOGRAPH + {0x89E6, 0x753B}, //867 #CJK UNIFIED IDEOGRAPH + {0x89E7, 0x81E5}, //868 #CJK UNIFIED IDEOGRAPH + {0x89E8, 0x82BD}, //869 #CJK UNIFIED IDEOGRAPH + {0x89E9, 0x86FE}, //870 #CJK UNIFIED IDEOGRAPH + {0x89EA, 0x8CC0}, //871 #CJK UNIFIED IDEOGRAPH + {0x89EB, 0x96C5}, //872 #CJK UNIFIED IDEOGRAPH + {0x89EC, 0x9913}, //873 #CJK UNIFIED IDEOGRAPH + {0x89ED, 0x99D5}, //874 #CJK UNIFIED IDEOGRAPH + {0x89EE, 0x4ECB}, //875 #CJK UNIFIED IDEOGRAPH + {0x89EF, 0x4F1A}, //876 #CJK UNIFIED IDEOGRAPH + {0x89F0, 0x89E3}, //877 #CJK UNIFIED IDEOGRAPH + {0x89F1, 0x56DE}, //878 #CJK UNIFIED IDEOGRAPH + {0x89F2, 0x584A}, //879 #CJK UNIFIED IDEOGRAPH + {0x89F3, 0x58CA}, //880 #CJK UNIFIED IDEOGRAPH + {0x89F4, 0x5EFB}, //881 #CJK UNIFIED IDEOGRAPH + {0x89F5, 0x5FEB}, //882 #CJK UNIFIED IDEOGRAPH + {0x89F6, 0x602A}, //883 #CJK UNIFIED IDEOGRAPH + {0x89F7, 0x6094}, //884 #CJK UNIFIED IDEOGRAPH + {0x89F8, 0x6062}, //885 #CJK UNIFIED IDEOGRAPH + {0x89F9, 0x61D0}, //886 #CJK UNIFIED IDEOGRAPH + {0x89FA, 0x6212}, //887 #CJK UNIFIED IDEOGRAPH + {0x89FB, 0x62D0}, //888 #CJK UNIFIED IDEOGRAPH + {0x89FC, 0x6539}, //889 #CJK UNIFIED IDEOGRAPH + {0x8A40, 0x9B41}, //890 #CJK UNIFIED IDEOGRAPH + {0x8A41, 0x6666}, //891 #CJK UNIFIED IDEOGRAPH + {0x8A42, 0x68B0}, //892 #CJK UNIFIED IDEOGRAPH + {0x8A43, 0x6D77}, //893 #CJK UNIFIED IDEOGRAPH + {0x8A44, 0x7070}, //894 #CJK UNIFIED IDEOGRAPH + {0x8A45, 0x754C}, //895 #CJK UNIFIED IDEOGRAPH + {0x8A46, 0x7686}, //896 #CJK UNIFIED IDEOGRAPH + {0x8A47, 0x7D75}, //897 #CJK UNIFIED IDEOGRAPH + {0x8A48, 0x82A5}, //898 #CJK UNIFIED IDEOGRAPH + {0x8A49, 0x87F9}, //899 #CJK UNIFIED IDEOGRAPH + {0x8A4A, 0x958B}, //900 #CJK UNIFIED IDEOGRAPH + {0x8A4B, 0x968E}, //901 #CJK UNIFIED IDEOGRAPH + {0x8A4C, 0x8C9D}, //902 #CJK UNIFIED IDEOGRAPH + {0x8A4D, 0x51F1}, //903 #CJK UNIFIED IDEOGRAPH + {0x8A4E, 0x52BE}, //904 #CJK UNIFIED IDEOGRAPH + {0x8A4F, 0x5916}, //905 #CJK UNIFIED IDEOGRAPH + {0x8A50, 0x54B3}, //906 #CJK UNIFIED IDEOGRAPH + {0x8A51, 0x5BB3}, //907 #CJK UNIFIED IDEOGRAPH + {0x8A52, 0x5D16}, //908 #CJK UNIFIED IDEOGRAPH + {0x8A53, 0x6168}, //909 #CJK UNIFIED IDEOGRAPH + {0x8A54, 0x6982}, //910 #CJK UNIFIED IDEOGRAPH + {0x8A55, 0x6DAF}, //911 #CJK UNIFIED IDEOGRAPH + {0x8A56, 0x788D}, //912 #CJK UNIFIED IDEOGRAPH + {0x8A57, 0x84CB}, //913 #CJK UNIFIED IDEOGRAPH + {0x8A58, 0x8857}, //914 #CJK UNIFIED IDEOGRAPH + {0x8A59, 0x8A72}, //915 #CJK UNIFIED IDEOGRAPH + {0x8A5A, 0x93A7}, //916 #CJK UNIFIED IDEOGRAPH + {0x8A5B, 0x9AB8}, //917 #CJK UNIFIED IDEOGRAPH + {0x8A5C, 0x6D6C}, //918 #CJK UNIFIED IDEOGRAPH + {0x8A5D, 0x99A8}, //919 #CJK UNIFIED IDEOGRAPH + {0x8A5E, 0x86D9}, //920 #CJK UNIFIED IDEOGRAPH + {0x8A5F, 0x57A3}, //921 #CJK UNIFIED IDEOGRAPH + {0x8A60, 0x67FF}, //922 #CJK UNIFIED IDEOGRAPH + {0x8A61, 0x86CE}, //923 #CJK UNIFIED IDEOGRAPH + {0x8A62, 0x920E}, //924 #CJK UNIFIED IDEOGRAPH + {0x8A63, 0x5283}, //925 #CJK UNIFIED IDEOGRAPH + {0x8A64, 0x5687}, //926 #CJK UNIFIED IDEOGRAPH + {0x8A65, 0x5404}, //927 #CJK UNIFIED IDEOGRAPH + {0x8A66, 0x5ED3}, //928 #CJK UNIFIED IDEOGRAPH + {0x8A67, 0x62E1}, //929 #CJK UNIFIED IDEOGRAPH + {0x8A68, 0x64B9}, //930 #CJK UNIFIED IDEOGRAPH + {0x8A69, 0x683C}, //931 #CJK UNIFIED IDEOGRAPH + {0x8A6A, 0x6838}, //932 #CJK UNIFIED IDEOGRAPH + {0x8A6B, 0x6BBB}, //933 #CJK UNIFIED IDEOGRAPH + {0x8A6C, 0x7372}, //934 #CJK UNIFIED IDEOGRAPH + {0x8A6D, 0x78BA}, //935 #CJK UNIFIED IDEOGRAPH + {0x8A6E, 0x7A6B}, //936 #CJK UNIFIED IDEOGRAPH + {0x8A6F, 0x899A}, //937 #CJK UNIFIED IDEOGRAPH + {0x8A70, 0x89D2}, //938 #CJK UNIFIED IDEOGRAPH + {0x8A71, 0x8D6B}, //939 #CJK UNIFIED IDEOGRAPH + {0x8A72, 0x8F03}, //940 #CJK UNIFIED IDEOGRAPH + {0x8A73, 0x90ED}, //941 #CJK UNIFIED IDEOGRAPH + {0x8A74, 0x95A3}, //942 #CJK UNIFIED IDEOGRAPH + {0x8A75, 0x9694}, //943 #CJK UNIFIED IDEOGRAPH + {0x8A76, 0x9769}, //944 #CJK UNIFIED IDEOGRAPH + {0x8A77, 0x5B66}, //945 #CJK UNIFIED IDEOGRAPH + {0x8A78, 0x5CB3}, //946 #CJK UNIFIED IDEOGRAPH + {0x8A79, 0x697D}, //947 #CJK UNIFIED IDEOGRAPH + {0x8A7A, 0x984D}, //948 #CJK UNIFIED IDEOGRAPH + {0x8A7B, 0x984E}, //949 #CJK UNIFIED IDEOGRAPH + {0x8A7C, 0x639B}, //950 #CJK UNIFIED IDEOGRAPH + {0x8A7D, 0x7B20}, //951 #CJK UNIFIED IDEOGRAPH + {0x8A7E, 0x6A2B}, //952 #CJK UNIFIED IDEOGRAPH + {0x8A80, 0x6A7F}, //953 #CJK UNIFIED IDEOGRAPH + {0x8A81, 0x68B6}, //954 #CJK UNIFIED IDEOGRAPH + {0x8A82, 0x9C0D}, //955 #CJK UNIFIED IDEOGRAPH + {0x8A83, 0x6F5F}, //956 #CJK UNIFIED IDEOGRAPH + {0x8A84, 0x5272}, //957 #CJK UNIFIED IDEOGRAPH + {0x8A85, 0x559D}, //958 #CJK UNIFIED IDEOGRAPH + {0x8A86, 0x6070}, //959 #CJK UNIFIED IDEOGRAPH + {0x8A87, 0x62EC}, //960 #CJK UNIFIED IDEOGRAPH + {0x8A88, 0x6D3B}, //961 #CJK UNIFIED IDEOGRAPH + {0x8A89, 0x6E07}, //962 #CJK UNIFIED IDEOGRAPH + {0x8A8A, 0x6ED1}, //963 #CJK UNIFIED IDEOGRAPH + {0x8A8B, 0x845B}, //964 #CJK UNIFIED IDEOGRAPH + {0x8A8C, 0x8910}, //965 #CJK UNIFIED IDEOGRAPH + {0x8A8D, 0x8F44}, //966 #CJK UNIFIED IDEOGRAPH + {0x8A8E, 0x4E14}, //967 #CJK UNIFIED IDEOGRAPH + {0x8A8F, 0x9C39}, //968 #CJK UNIFIED IDEOGRAPH + {0x8A90, 0x53F6}, //969 #CJK UNIFIED IDEOGRAPH + {0x8A91, 0x691B}, //970 #CJK UNIFIED IDEOGRAPH + {0x8A92, 0x6A3A}, //971 #CJK UNIFIED IDEOGRAPH + {0x8A93, 0x9784}, //972 #CJK UNIFIED IDEOGRAPH + {0x8A94, 0x682A}, //973 #CJK UNIFIED IDEOGRAPH + {0x8A95, 0x515C}, //974 #CJK UNIFIED IDEOGRAPH + {0x8A96, 0x7AC3}, //975 #CJK UNIFIED IDEOGRAPH + {0x8A97, 0x84B2}, //976 #CJK UNIFIED IDEOGRAPH + {0x8A98, 0x91DC}, //977 #CJK UNIFIED IDEOGRAPH + {0x8A99, 0x938C}, //978 #CJK UNIFIED IDEOGRAPH + {0x8A9A, 0x565B}, //979 #CJK UNIFIED IDEOGRAPH + {0x8A9B, 0x9D28}, //980 #CJK UNIFIED IDEOGRAPH + {0x8A9C, 0x6822}, //981 #CJK UNIFIED IDEOGRAPH + {0x8A9D, 0x8305}, //982 #CJK UNIFIED IDEOGRAPH + {0x8A9E, 0x8431}, //983 #CJK UNIFIED IDEOGRAPH + {0x8A9F, 0x7CA5}, //984 #CJK UNIFIED IDEOGRAPH + {0x8AA0, 0x5208}, //985 #CJK UNIFIED IDEOGRAPH + {0x8AA1, 0x82C5}, //986 #CJK UNIFIED IDEOGRAPH + {0x8AA2, 0x74E6}, //987 #CJK UNIFIED IDEOGRAPH + {0x8AA3, 0x4E7E}, //988 #CJK UNIFIED IDEOGRAPH + {0x8AA4, 0x4F83}, //989 #CJK UNIFIED IDEOGRAPH + {0x8AA5, 0x51A0}, //990 #CJK UNIFIED IDEOGRAPH + {0x8AA6, 0x5BD2}, //991 #CJK UNIFIED IDEOGRAPH + {0x8AA7, 0x520A}, //992 #CJK UNIFIED IDEOGRAPH + {0x8AA8, 0x52D8}, //993 #CJK UNIFIED IDEOGRAPH + {0x8AA9, 0x52E7}, //994 #CJK UNIFIED IDEOGRAPH + {0x8AAA, 0x5DFB}, //995 #CJK UNIFIED IDEOGRAPH + {0x8AAB, 0x559A}, //996 #CJK UNIFIED IDEOGRAPH + {0x8AAC, 0x582A}, //997 #CJK UNIFIED IDEOGRAPH + {0x8AAD, 0x59E6}, //998 #CJK UNIFIED IDEOGRAPH + {0x8AAE, 0x5B8C}, //999 #CJK UNIFIED IDEOGRAPH + {0x8AAF, 0x5B98}, //1000 #CJK UNIFIED IDEOGRAPH + {0x8AB0, 0x5BDB}, //1001 #CJK UNIFIED IDEOGRAPH + {0x8AB1, 0x5E72}, //1002 #CJK UNIFIED IDEOGRAPH + {0x8AB2, 0x5E79}, //1003 #CJK UNIFIED IDEOGRAPH + {0x8AB3, 0x60A3}, //1004 #CJK UNIFIED IDEOGRAPH + {0x8AB4, 0x611F}, //1005 #CJK UNIFIED IDEOGRAPH + {0x8AB5, 0x6163}, //1006 #CJK UNIFIED IDEOGRAPH + {0x8AB6, 0x61BE}, //1007 #CJK UNIFIED IDEOGRAPH + {0x8AB7, 0x63DB}, //1008 #CJK UNIFIED IDEOGRAPH + {0x8AB8, 0x6562}, //1009 #CJK UNIFIED IDEOGRAPH + {0x8AB9, 0x67D1}, //1010 #CJK UNIFIED IDEOGRAPH + {0x8ABA, 0x6853}, //1011 #CJK UNIFIED IDEOGRAPH + {0x8ABB, 0x68FA}, //1012 #CJK UNIFIED IDEOGRAPH + {0x8ABC, 0x6B3E}, //1013 #CJK UNIFIED IDEOGRAPH + {0x8ABD, 0x6B53}, //1014 #CJK UNIFIED IDEOGRAPH + {0x8ABE, 0x6C57}, //1015 #CJK UNIFIED IDEOGRAPH + {0x8ABF, 0x6F22}, //1016 #CJK UNIFIED IDEOGRAPH + {0x8AC0, 0x6F97}, //1017 #CJK UNIFIED IDEOGRAPH + {0x8AC1, 0x6F45}, //1018 #CJK UNIFIED IDEOGRAPH + {0x8AC2, 0x74B0}, //1019 #CJK UNIFIED IDEOGRAPH + {0x8AC3, 0x7518}, //1020 #CJK UNIFIED IDEOGRAPH + {0x8AC4, 0x76E3}, //1021 #CJK UNIFIED IDEOGRAPH + {0x8AC5, 0x770B}, //1022 #CJK UNIFIED IDEOGRAPH + {0x8AC6, 0x7AFF}, //1023 #CJK UNIFIED IDEOGRAPH + {0x8AC7, 0x7BA1}, //1024 #CJK UNIFIED IDEOGRAPH + {0x8AC8, 0x7C21}, //1025 #CJK UNIFIED IDEOGRAPH + {0x8AC9, 0x7DE9}, //1026 #CJK UNIFIED IDEOGRAPH + {0x8ACA, 0x7F36}, //1027 #CJK UNIFIED IDEOGRAPH + {0x8ACB, 0x7FF0}, //1028 #CJK UNIFIED IDEOGRAPH + {0x8ACC, 0x809D}, //1029 #CJK UNIFIED IDEOGRAPH + {0x8ACD, 0x8266}, //1030 #CJK UNIFIED IDEOGRAPH + {0x8ACE, 0x839E}, //1031 #CJK UNIFIED IDEOGRAPH + {0x8ACF, 0x89B3}, //1032 #CJK UNIFIED IDEOGRAPH + {0x8AD0, 0x8ACC}, //1033 #CJK UNIFIED IDEOGRAPH + {0x8AD1, 0x8CAB}, //1034 #CJK UNIFIED IDEOGRAPH + {0x8AD2, 0x9084}, //1035 #CJK UNIFIED IDEOGRAPH + {0x8AD3, 0x9451}, //1036 #CJK UNIFIED IDEOGRAPH + {0x8AD4, 0x9593}, //1037 #CJK UNIFIED IDEOGRAPH + {0x8AD5, 0x9591}, //1038 #CJK UNIFIED IDEOGRAPH + {0x8AD6, 0x95A2}, //1039 #CJK UNIFIED IDEOGRAPH + {0x8AD7, 0x9665}, //1040 #CJK UNIFIED IDEOGRAPH + {0x8AD8, 0x97D3}, //1041 #CJK UNIFIED IDEOGRAPH + {0x8AD9, 0x9928}, //1042 #CJK UNIFIED IDEOGRAPH + {0x8ADA, 0x8218}, //1043 #CJK UNIFIED IDEOGRAPH + {0x8ADB, 0x4E38}, //1044 #CJK UNIFIED IDEOGRAPH + {0x8ADC, 0x542B}, //1045 #CJK UNIFIED IDEOGRAPH + {0x8ADD, 0x5CB8}, //1046 #CJK UNIFIED IDEOGRAPH + {0x8ADE, 0x5DCC}, //1047 #CJK UNIFIED IDEOGRAPH + {0x8ADF, 0x73A9}, //1048 #CJK UNIFIED IDEOGRAPH + {0x8AE0, 0x764C}, //1049 #CJK UNIFIED IDEOGRAPH + {0x8AE1, 0x773C}, //1050 #CJK UNIFIED IDEOGRAPH + {0x8AE2, 0x5CA9}, //1051 #CJK UNIFIED IDEOGRAPH + {0x8AE3, 0x7FEB}, //1052 #CJK UNIFIED IDEOGRAPH + {0x8AE4, 0x8D0B}, //1053 #CJK UNIFIED IDEOGRAPH + {0x8AE5, 0x96C1}, //1054 #CJK UNIFIED IDEOGRAPH + {0x8AE6, 0x9811}, //1055 #CJK UNIFIED IDEOGRAPH + {0x8AE7, 0x9854}, //1056 #CJK UNIFIED IDEOGRAPH + {0x8AE8, 0x9858}, //1057 #CJK UNIFIED IDEOGRAPH + {0x8AE9, 0x4F01}, //1058 #CJK UNIFIED IDEOGRAPH + {0x8AEA, 0x4F0E}, //1059 #CJK UNIFIED IDEOGRAPH + {0x8AEB, 0x5371}, //1060 #CJK UNIFIED IDEOGRAPH + {0x8AEC, 0x559C}, //1061 #CJK UNIFIED IDEOGRAPH + {0x8AED, 0x5668}, //1062 #CJK UNIFIED IDEOGRAPH + {0x8AEE, 0x57FA}, //1063 #CJK UNIFIED IDEOGRAPH + {0x8AEF, 0x5947}, //1064 #CJK UNIFIED IDEOGRAPH + {0x8AF0, 0x5B09}, //1065 #CJK UNIFIED IDEOGRAPH + {0x8AF1, 0x5BC4}, //1066 #CJK UNIFIED IDEOGRAPH + {0x8AF2, 0x5C90}, //1067 #CJK UNIFIED IDEOGRAPH + {0x8AF3, 0x5E0C}, //1068 #CJK UNIFIED IDEOGRAPH + {0x8AF4, 0x5E7E}, //1069 #CJK UNIFIED IDEOGRAPH + {0x8AF5, 0x5FCC}, //1070 #CJK UNIFIED IDEOGRAPH + {0x8AF6, 0x63EE}, //1071 #CJK UNIFIED IDEOGRAPH + {0x8AF7, 0x673A}, //1072 #CJK UNIFIED IDEOGRAPH + {0x8AF8, 0x65D7}, //1073 #CJK UNIFIED IDEOGRAPH + {0x8AF9, 0x65E2}, //1074 #CJK UNIFIED IDEOGRAPH + {0x8AFA, 0x671F}, //1075 #CJK UNIFIED IDEOGRAPH + {0x8AFB, 0x68CB}, //1076 #CJK UNIFIED IDEOGRAPH + {0x8AFC, 0x68C4}, //1077 #CJK UNIFIED IDEOGRAPH + {0x8B40, 0x6A5F}, //1078 #CJK UNIFIED IDEOGRAPH + {0x8B41, 0x5E30}, //1079 #CJK UNIFIED IDEOGRAPH + {0x8B42, 0x6BC5}, //1080 #CJK UNIFIED IDEOGRAPH + {0x8B43, 0x6C17}, //1081 #CJK UNIFIED IDEOGRAPH + {0x8B44, 0x6C7D}, //1082 #CJK UNIFIED IDEOGRAPH + {0x8B45, 0x757F}, //1083 #CJK UNIFIED IDEOGRAPH + {0x8B46, 0x7948}, //1084 #CJK UNIFIED IDEOGRAPH + {0x8B47, 0x5B63}, //1085 #CJK UNIFIED IDEOGRAPH + {0x8B48, 0x7A00}, //1086 #CJK UNIFIED IDEOGRAPH + {0x8B49, 0x7D00}, //1087 #CJK UNIFIED IDEOGRAPH + {0x8B4A, 0x5FBD}, //1088 #CJK UNIFIED IDEOGRAPH + {0x8B4B, 0x898F}, //1089 #CJK UNIFIED IDEOGRAPH + {0x8B4C, 0x8A18}, //1090 #CJK UNIFIED IDEOGRAPH + {0x8B4D, 0x8CB4}, //1091 #CJK UNIFIED IDEOGRAPH + {0x8B4E, 0x8D77}, //1092 #CJK UNIFIED IDEOGRAPH + {0x8B4F, 0x8ECC}, //1093 #CJK UNIFIED IDEOGRAPH + {0x8B50, 0x8F1D}, //1094 #CJK UNIFIED IDEOGRAPH + {0x8B51, 0x98E2}, //1095 #CJK UNIFIED IDEOGRAPH + {0x8B52, 0x9A0E}, //1096 #CJK UNIFIED IDEOGRAPH + {0x8B53, 0x9B3C}, //1097 #CJK UNIFIED IDEOGRAPH + {0x8B54, 0x4E80}, //1098 #CJK UNIFIED IDEOGRAPH + {0x8B55, 0x507D}, //1099 #CJK UNIFIED IDEOGRAPH + {0x8B56, 0x5100}, //1100 #CJK UNIFIED IDEOGRAPH + {0x8B57, 0x5993}, //1101 #CJK UNIFIED IDEOGRAPH + {0x8B58, 0x5B9C}, //1102 #CJK UNIFIED IDEOGRAPH + {0x8B59, 0x622F}, //1103 #CJK UNIFIED IDEOGRAPH + {0x8B5A, 0x6280}, //1104 #CJK UNIFIED IDEOGRAPH + {0x8B5B, 0x64EC}, //1105 #CJK UNIFIED IDEOGRAPH + {0x8B5C, 0x6B3A}, //1106 #CJK UNIFIED IDEOGRAPH + {0x8B5D, 0x72A0}, //1107 #CJK UNIFIED IDEOGRAPH + {0x8B5E, 0x7591}, //1108 #CJK UNIFIED IDEOGRAPH + {0x8B5F, 0x7947}, //1109 #CJK UNIFIED IDEOGRAPH + {0x8B60, 0x7FA9}, //1110 #CJK UNIFIED IDEOGRAPH + {0x8B61, 0x87FB}, //1111 #CJK UNIFIED IDEOGRAPH + {0x8B62, 0x8ABC}, //1112 #CJK UNIFIED IDEOGRAPH + {0x8B63, 0x8B70}, //1113 #CJK UNIFIED IDEOGRAPH + {0x8B64, 0x63AC}, //1114 #CJK UNIFIED IDEOGRAPH + {0x8B65, 0x83CA}, //1115 #CJK UNIFIED IDEOGRAPH + {0x8B66, 0x97A0}, //1116 #CJK UNIFIED IDEOGRAPH + {0x8B67, 0x5409}, //1117 #CJK UNIFIED IDEOGRAPH + {0x8B68, 0x5403}, //1118 #CJK UNIFIED IDEOGRAPH + {0x8B69, 0x55AB}, //1119 #CJK UNIFIED IDEOGRAPH + {0x8B6A, 0x6854}, //1120 #CJK UNIFIED IDEOGRAPH + {0x8B6B, 0x6A58}, //1121 #CJK UNIFIED IDEOGRAPH + {0x8B6C, 0x8A70}, //1122 #CJK UNIFIED IDEOGRAPH + {0x8B6D, 0x7827}, //1123 #CJK UNIFIED IDEOGRAPH + {0x8B6E, 0x6775}, //1124 #CJK UNIFIED IDEOGRAPH + {0x8B6F, 0x9ECD}, //1125 #CJK UNIFIED IDEOGRAPH + {0x8B70, 0x5374}, //1126 #CJK UNIFIED IDEOGRAPH + {0x8B71, 0x5BA2}, //1127 #CJK UNIFIED IDEOGRAPH + {0x8B72, 0x811A}, //1128 #CJK UNIFIED IDEOGRAPH + {0x8B73, 0x8650}, //1129 #CJK UNIFIED IDEOGRAPH + {0x8B74, 0x9006}, //1130 #CJK UNIFIED IDEOGRAPH + {0x8B75, 0x4E18}, //1131 #CJK UNIFIED IDEOGRAPH + {0x8B76, 0x4E45}, //1132 #CJK UNIFIED IDEOGRAPH + {0x8B77, 0x4EC7}, //1133 #CJK UNIFIED IDEOGRAPH + {0x8B78, 0x4F11}, //1134 #CJK UNIFIED IDEOGRAPH + {0x8B79, 0x53CA}, //1135 #CJK UNIFIED IDEOGRAPH + {0x8B7A, 0x5438}, //1136 #CJK UNIFIED IDEOGRAPH + {0x8B7B, 0x5BAE}, //1137 #CJK UNIFIED IDEOGRAPH + {0x8B7C, 0x5F13}, //1138 #CJK UNIFIED IDEOGRAPH + {0x8B7D, 0x6025}, //1139 #CJK UNIFIED IDEOGRAPH + {0x8B7E, 0x6551}, //1140 #CJK UNIFIED IDEOGRAPH + {0x8B80, 0x673D}, //1141 #CJK UNIFIED IDEOGRAPH + {0x8B81, 0x6C42}, //1142 #CJK UNIFIED IDEOGRAPH + {0x8B82, 0x6C72}, //1143 #CJK UNIFIED IDEOGRAPH + {0x8B83, 0x6CE3}, //1144 #CJK UNIFIED IDEOGRAPH + {0x8B84, 0x7078}, //1145 #CJK UNIFIED IDEOGRAPH + {0x8B85, 0x7403}, //1146 #CJK UNIFIED IDEOGRAPH + {0x8B86, 0x7A76}, //1147 #CJK UNIFIED IDEOGRAPH + {0x8B87, 0x7AAE}, //1148 #CJK UNIFIED IDEOGRAPH + {0x8B88, 0x7B08}, //1149 #CJK UNIFIED IDEOGRAPH + {0x8B89, 0x7D1A}, //1150 #CJK UNIFIED IDEOGRAPH + {0x8B8A, 0x7CFE}, //1151 #CJK UNIFIED IDEOGRAPH + {0x8B8B, 0x7D66}, //1152 #CJK UNIFIED IDEOGRAPH + {0x8B8C, 0x65E7}, //1153 #CJK UNIFIED IDEOGRAPH + {0x8B8D, 0x725B}, //1154 #CJK UNIFIED IDEOGRAPH + {0x8B8E, 0x53BB}, //1155 #CJK UNIFIED IDEOGRAPH + {0x8B8F, 0x5C45}, //1156 #CJK UNIFIED IDEOGRAPH + {0x8B90, 0x5DE8}, //1157 #CJK UNIFIED IDEOGRAPH + {0x8B91, 0x62D2}, //1158 #CJK UNIFIED IDEOGRAPH + {0x8B92, 0x62E0}, //1159 #CJK UNIFIED IDEOGRAPH + {0x8B93, 0x6319}, //1160 #CJK UNIFIED IDEOGRAPH + {0x8B94, 0x6E20}, //1161 #CJK UNIFIED IDEOGRAPH + {0x8B95, 0x865A}, //1162 #CJK UNIFIED IDEOGRAPH + {0x8B96, 0x8A31}, //1163 #CJK UNIFIED IDEOGRAPH + {0x8B97, 0x8DDD}, //1164 #CJK UNIFIED IDEOGRAPH + {0x8B98, 0x92F8}, //1165 #CJK UNIFIED IDEOGRAPH + {0x8B99, 0x6F01}, //1166 #CJK UNIFIED IDEOGRAPH + {0x8B9A, 0x79A6}, //1167 #CJK UNIFIED IDEOGRAPH + {0x8B9B, 0x9B5A}, //1168 #CJK UNIFIED IDEOGRAPH + {0x8B9C, 0x4EA8}, //1169 #CJK UNIFIED IDEOGRAPH + {0x8B9D, 0x4EAB}, //1170 #CJK UNIFIED IDEOGRAPH + {0x8B9E, 0x4EAC}, //1171 #CJK UNIFIED IDEOGRAPH + {0x8B9F, 0x4F9B}, //1172 #CJK UNIFIED IDEOGRAPH + {0x8BA0, 0x4FA0}, //1173 #CJK UNIFIED IDEOGRAPH + {0x8BA1, 0x50D1}, //1174 #CJK UNIFIED IDEOGRAPH + {0x8BA2, 0x5147}, //1175 #CJK UNIFIED IDEOGRAPH + {0x8BA3, 0x7AF6}, //1176 #CJK UNIFIED IDEOGRAPH + {0x8BA4, 0x5171}, //1177 #CJK UNIFIED IDEOGRAPH + {0x8BA5, 0x51F6}, //1178 #CJK UNIFIED IDEOGRAPH + {0x8BA6, 0x5354}, //1179 #CJK UNIFIED IDEOGRAPH + {0x8BA7, 0x5321}, //1180 #CJK UNIFIED IDEOGRAPH + {0x8BA8, 0x537F}, //1181 #CJK UNIFIED IDEOGRAPH + {0x8BA9, 0x53EB}, //1182 #CJK UNIFIED IDEOGRAPH + {0x8BAA, 0x55AC}, //1183 #CJK UNIFIED IDEOGRAPH + {0x8BAB, 0x5883}, //1184 #CJK UNIFIED IDEOGRAPH + {0x8BAC, 0x5CE1}, //1185 #CJK UNIFIED IDEOGRAPH + {0x8BAD, 0x5F37}, //1186 #CJK UNIFIED IDEOGRAPH + {0x8BAE, 0x5F4A}, //1187 #CJK UNIFIED IDEOGRAPH + {0x8BAF, 0x602F}, //1188 #CJK UNIFIED IDEOGRAPH + {0x8BB0, 0x6050}, //1189 #CJK UNIFIED IDEOGRAPH + {0x8BB1, 0x606D}, //1190 #CJK UNIFIED IDEOGRAPH + {0x8BB2, 0x631F}, //1191 #CJK UNIFIED IDEOGRAPH + {0x8BB3, 0x6559}, //1192 #CJK UNIFIED IDEOGRAPH + {0x8BB4, 0x6A4B}, //1193 #CJK UNIFIED IDEOGRAPH + {0x8BB5, 0x6CC1}, //1194 #CJK UNIFIED IDEOGRAPH + {0x8BB6, 0x72C2}, //1195 #CJK UNIFIED IDEOGRAPH + {0x8BB7, 0x72ED}, //1196 #CJK UNIFIED IDEOGRAPH + {0x8BB8, 0x77EF}, //1197 #CJK UNIFIED IDEOGRAPH + {0x8BB9, 0x80F8}, //1198 #CJK UNIFIED IDEOGRAPH + {0x8BBA, 0x8105}, //1199 #CJK UNIFIED IDEOGRAPH + {0x8BBB, 0x8208}, //1200 #CJK UNIFIED IDEOGRAPH + {0x8BBC, 0x854E}, //1201 #CJK UNIFIED IDEOGRAPH + {0x8BBD, 0x90F7}, //1202 #CJK UNIFIED IDEOGRAPH + {0x8BBE, 0x93E1}, //1203 #CJK UNIFIED IDEOGRAPH + {0x8BBF, 0x97FF}, //1204 #CJK UNIFIED IDEOGRAPH + {0x8BC0, 0x9957}, //1205 #CJK UNIFIED IDEOGRAPH + {0x8BC1, 0x9A5A}, //1206 #CJK UNIFIED IDEOGRAPH + {0x8BC2, 0x4EF0}, //1207 #CJK UNIFIED IDEOGRAPH + {0x8BC3, 0x51DD}, //1208 #CJK UNIFIED IDEOGRAPH + {0x8BC4, 0x5C2D}, //1209 #CJK UNIFIED IDEOGRAPH + {0x8BC5, 0x6681}, //1210 #CJK UNIFIED IDEOGRAPH + {0x8BC6, 0x696D}, //1211 #CJK UNIFIED IDEOGRAPH + {0x8BC7, 0x5C40}, //1212 #CJK UNIFIED IDEOGRAPH + {0x8BC8, 0x66F2}, //1213 #CJK UNIFIED IDEOGRAPH + {0x8BC9, 0x6975}, //1214 #CJK UNIFIED IDEOGRAPH + {0x8BCA, 0x7389}, //1215 #CJK UNIFIED IDEOGRAPH + {0x8BCB, 0x6850}, //1216 #CJK UNIFIED IDEOGRAPH + {0x8BCC, 0x7C81}, //1217 #CJK UNIFIED IDEOGRAPH + {0x8BCD, 0x50C5}, //1218 #CJK UNIFIED IDEOGRAPH + {0x8BCE, 0x52E4}, //1219 #CJK UNIFIED IDEOGRAPH + {0x8BCF, 0x5747}, //1220 #CJK UNIFIED IDEOGRAPH + {0x8BD0, 0x5DFE}, //1221 #CJK UNIFIED IDEOGRAPH + {0x8BD1, 0x9326}, //1222 #CJK UNIFIED IDEOGRAPH + {0x8BD2, 0x65A4}, //1223 #CJK UNIFIED IDEOGRAPH + {0x8BD3, 0x6B23}, //1224 #CJK UNIFIED IDEOGRAPH + {0x8BD4, 0x6B3D}, //1225 #CJK UNIFIED IDEOGRAPH + {0x8BD5, 0x7434}, //1226 #CJK UNIFIED IDEOGRAPH + {0x8BD6, 0x7981}, //1227 #CJK UNIFIED IDEOGRAPH + {0x8BD7, 0x79BD}, //1228 #CJK UNIFIED IDEOGRAPH + {0x8BD8, 0x7B4B}, //1229 #CJK UNIFIED IDEOGRAPH + {0x8BD9, 0x7DCA}, //1230 #CJK UNIFIED IDEOGRAPH + {0x8BDA, 0x82B9}, //1231 #CJK UNIFIED IDEOGRAPH + {0x8BDB, 0x83CC}, //1232 #CJK UNIFIED IDEOGRAPH + {0x8BDC, 0x887F}, //1233 #CJK UNIFIED IDEOGRAPH + {0x8BDD, 0x895F}, //1234 #CJK UNIFIED IDEOGRAPH + {0x8BDE, 0x8B39}, //1235 #CJK UNIFIED IDEOGRAPH + {0x8BDF, 0x8FD1}, //1236 #CJK UNIFIED IDEOGRAPH + {0x8BE0, 0x91D1}, //1237 #CJK UNIFIED IDEOGRAPH + {0x8BE1, 0x541F}, //1238 #CJK UNIFIED IDEOGRAPH + {0x8BE2, 0x9280}, //1239 #CJK UNIFIED IDEOGRAPH + {0x8BE3, 0x4E5D}, //1240 #CJK UNIFIED IDEOGRAPH + {0x8BE4, 0x5036}, //1241 #CJK UNIFIED IDEOGRAPH + {0x8BE5, 0x53E5}, //1242 #CJK UNIFIED IDEOGRAPH + {0x8BE6, 0x533A}, //1243 #CJK UNIFIED IDEOGRAPH + {0x8BE7, 0x72D7}, //1244 #CJK UNIFIED IDEOGRAPH + {0x8BE8, 0x7396}, //1245 #CJK UNIFIED IDEOGRAPH + {0x8BE9, 0x77E9}, //1246 #CJK UNIFIED IDEOGRAPH + {0x8BEA, 0x82E6}, //1247 #CJK UNIFIED IDEOGRAPH + {0x8BEB, 0x8EAF}, //1248 #CJK UNIFIED IDEOGRAPH + {0x8BEC, 0x99C6}, //1249 #CJK UNIFIED IDEOGRAPH + {0x8BED, 0x99C8}, //1250 #CJK UNIFIED IDEOGRAPH + {0x8BEE, 0x99D2}, //1251 #CJK UNIFIED IDEOGRAPH + {0x8BEF, 0x5177}, //1252 #CJK UNIFIED IDEOGRAPH + {0x8BF0, 0x611A}, //1253 #CJK UNIFIED IDEOGRAPH + {0x8BF1, 0x865E}, //1254 #CJK UNIFIED IDEOGRAPH + {0x8BF2, 0x55B0}, //1255 #CJK UNIFIED IDEOGRAPH + {0x8BF3, 0x7A7A}, //1256 #CJK UNIFIED IDEOGRAPH + {0x8BF4, 0x5076}, //1257 #CJK UNIFIED IDEOGRAPH + {0x8BF5, 0x5BD3}, //1258 #CJK UNIFIED IDEOGRAPH + {0x8BF6, 0x9047}, //1259 #CJK UNIFIED IDEOGRAPH + {0x8BF7, 0x9685}, //1260 #CJK UNIFIED IDEOGRAPH + {0x8BF8, 0x4E32}, //1261 #CJK UNIFIED IDEOGRAPH + {0x8BF9, 0x6ADB}, //1262 #CJK UNIFIED IDEOGRAPH + {0x8BFA, 0x91E7}, //1263 #CJK UNIFIED IDEOGRAPH + {0x8BFB, 0x5C51}, //1264 #CJK UNIFIED IDEOGRAPH + {0x8BFC, 0x5C48}, //1265 #CJK UNIFIED IDEOGRAPH + {0x8C40, 0x6398}, //1266 #CJK UNIFIED IDEOGRAPH + {0x8C41, 0x7A9F}, //1267 #CJK UNIFIED IDEOGRAPH + {0x8C42, 0x6C93}, //1268 #CJK UNIFIED IDEOGRAPH + {0x8C43, 0x9774}, //1269 #CJK UNIFIED IDEOGRAPH + {0x8C44, 0x8F61}, //1270 #CJK UNIFIED IDEOGRAPH + {0x8C45, 0x7AAA}, //1271 #CJK UNIFIED IDEOGRAPH + {0x8C46, 0x718A}, //1272 #CJK UNIFIED IDEOGRAPH + {0x8C47, 0x9688}, //1273 #CJK UNIFIED IDEOGRAPH + {0x8C48, 0x7C82}, //1274 #CJK UNIFIED IDEOGRAPH + {0x8C49, 0x6817}, //1275 #CJK UNIFIED IDEOGRAPH + {0x8C4A, 0x7E70}, //1276 #CJK UNIFIED IDEOGRAPH + {0x8C4B, 0x6851}, //1277 #CJK UNIFIED IDEOGRAPH + {0x8C4C, 0x936C}, //1278 #CJK UNIFIED IDEOGRAPH + {0x8C4D, 0x52F2}, //1279 #CJK UNIFIED IDEOGRAPH + {0x8C4E, 0x541B}, //1280 #CJK UNIFIED IDEOGRAPH + {0x8C4F, 0x85AB}, //1281 #CJK UNIFIED IDEOGRAPH + {0x8C50, 0x8A13}, //1282 #CJK UNIFIED IDEOGRAPH + {0x8C51, 0x7FA4}, //1283 #CJK UNIFIED IDEOGRAPH + {0x8C52, 0x8ECD}, //1284 #CJK UNIFIED IDEOGRAPH + {0x8C53, 0x90E1}, //1285 #CJK UNIFIED IDEOGRAPH + {0x8C54, 0x5366}, //1286 #CJK UNIFIED IDEOGRAPH + {0x8C55, 0x8888}, //1287 #CJK UNIFIED IDEOGRAPH + {0x8C56, 0x7941}, //1288 #CJK UNIFIED IDEOGRAPH + {0x8C57, 0x4FC2}, //1289 #CJK UNIFIED IDEOGRAPH + {0x8C58, 0x50BE}, //1290 #CJK UNIFIED IDEOGRAPH + {0x8C59, 0x5211}, //1291 #CJK UNIFIED IDEOGRAPH + {0x8C5A, 0x5144}, //1292 #CJK UNIFIED IDEOGRAPH + {0x8C5B, 0x5553}, //1293 #CJK UNIFIED IDEOGRAPH + {0x8C5C, 0x572D}, //1294 #CJK UNIFIED IDEOGRAPH + {0x8C5D, 0x73EA}, //1295 #CJK UNIFIED IDEOGRAPH + {0x8C5E, 0x578B}, //1296 #CJK UNIFIED IDEOGRAPH + {0x8C5F, 0x5951}, //1297 #CJK UNIFIED IDEOGRAPH + {0x8C60, 0x5F62}, //1298 #CJK UNIFIED IDEOGRAPH + {0x8C61, 0x5F84}, //1299 #CJK UNIFIED IDEOGRAPH + {0x8C62, 0x6075}, //1300 #CJK UNIFIED IDEOGRAPH + {0x8C63, 0x6176}, //1301 #CJK UNIFIED IDEOGRAPH + {0x8C64, 0x6167}, //1302 #CJK UNIFIED IDEOGRAPH + {0x8C65, 0x61A9}, //1303 #CJK UNIFIED IDEOGRAPH + {0x8C66, 0x63B2}, //1304 #CJK UNIFIED IDEOGRAPH + {0x8C67, 0x643A}, //1305 #CJK UNIFIED IDEOGRAPH + {0x8C68, 0x656C}, //1306 #CJK UNIFIED IDEOGRAPH + {0x8C69, 0x666F}, //1307 #CJK UNIFIED IDEOGRAPH + {0x8C6A, 0x6842}, //1308 #CJK UNIFIED IDEOGRAPH + {0x8C6B, 0x6E13}, //1309 #CJK UNIFIED IDEOGRAPH + {0x8C6C, 0x7566}, //1310 #CJK UNIFIED IDEOGRAPH + {0x8C6D, 0x7A3D}, //1311 #CJK UNIFIED IDEOGRAPH + {0x8C6E, 0x7CFB}, //1312 #CJK UNIFIED IDEOGRAPH + {0x8C6F, 0x7D4C}, //1313 #CJK UNIFIED IDEOGRAPH + {0x8C70, 0x7D99}, //1314 #CJK UNIFIED IDEOGRAPH + {0x8C71, 0x7E4B}, //1315 #CJK UNIFIED IDEOGRAPH + {0x8C72, 0x7F6B}, //1316 #CJK UNIFIED IDEOGRAPH + {0x8C73, 0x830E}, //1317 #CJK UNIFIED IDEOGRAPH + {0x8C74, 0x834A}, //1318 #CJK UNIFIED IDEOGRAPH + {0x8C75, 0x86CD}, //1319 #CJK UNIFIED IDEOGRAPH + {0x8C76, 0x8A08}, //1320 #CJK UNIFIED IDEOGRAPH + {0x8C77, 0x8A63}, //1321 #CJK UNIFIED IDEOGRAPH + {0x8C78, 0x8B66}, //1322 #CJK UNIFIED IDEOGRAPH + {0x8C79, 0x8EFD}, //1323 #CJK UNIFIED IDEOGRAPH + {0x8C7A, 0x981A}, //1324 #CJK UNIFIED IDEOGRAPH + {0x8C7B, 0x9D8F}, //1325 #CJK UNIFIED IDEOGRAPH + {0x8C7C, 0x82B8}, //1326 #CJK UNIFIED IDEOGRAPH + {0x8C7D, 0x8FCE}, //1327 #CJK UNIFIED IDEOGRAPH + {0x8C7E, 0x9BE8}, //1328 #CJK UNIFIED IDEOGRAPH + {0x8C80, 0x5287}, //1329 #CJK UNIFIED IDEOGRAPH + {0x8C81, 0x621F}, //1330 #CJK UNIFIED IDEOGRAPH + {0x8C82, 0x6483}, //1331 #CJK UNIFIED IDEOGRAPH + {0x8C83, 0x6FC0}, //1332 #CJK UNIFIED IDEOGRAPH + {0x8C84, 0x9699}, //1333 #CJK UNIFIED IDEOGRAPH + {0x8C85, 0x6841}, //1334 #CJK UNIFIED IDEOGRAPH + {0x8C86, 0x5091}, //1335 #CJK UNIFIED IDEOGRAPH + {0x8C87, 0x6B20}, //1336 #CJK UNIFIED IDEOGRAPH + {0x8C88, 0x6C7A}, //1337 #CJK UNIFIED IDEOGRAPH + {0x8C89, 0x6F54}, //1338 #CJK UNIFIED IDEOGRAPH + {0x8C8A, 0x7A74}, //1339 #CJK UNIFIED IDEOGRAPH + {0x8C8B, 0x7D50}, //1340 #CJK UNIFIED IDEOGRAPH + {0x8C8C, 0x8840}, //1341 #CJK UNIFIED IDEOGRAPH + {0x8C8D, 0x8A23}, //1342 #CJK UNIFIED IDEOGRAPH + {0x8C8E, 0x6708}, //1343 #CJK UNIFIED IDEOGRAPH + {0x8C8F, 0x4EF6}, //1344 #CJK UNIFIED IDEOGRAPH + {0x8C90, 0x5039}, //1345 #CJK UNIFIED IDEOGRAPH + {0x8C91, 0x5026}, //1346 #CJK UNIFIED IDEOGRAPH + {0x8C92, 0x5065}, //1347 #CJK UNIFIED IDEOGRAPH + {0x8C93, 0x517C}, //1348 #CJK UNIFIED IDEOGRAPH + {0x8C94, 0x5238}, //1349 #CJK UNIFIED IDEOGRAPH + {0x8C95, 0x5263}, //1350 #CJK UNIFIED IDEOGRAPH + {0x8C96, 0x55A7}, //1351 #CJK UNIFIED IDEOGRAPH + {0x8C97, 0x570F}, //1352 #CJK UNIFIED IDEOGRAPH + {0x8C98, 0x5805}, //1353 #CJK UNIFIED IDEOGRAPH + {0x8C99, 0x5ACC}, //1354 #CJK UNIFIED IDEOGRAPH + {0x8C9A, 0x5EFA}, //1355 #CJK UNIFIED IDEOGRAPH + {0x8C9B, 0x61B2}, //1356 #CJK UNIFIED IDEOGRAPH + {0x8C9C, 0x61F8}, //1357 #CJK UNIFIED IDEOGRAPH + {0x8C9D, 0x62F3}, //1358 #CJK UNIFIED IDEOGRAPH + {0x8C9E, 0x6372}, //1359 #CJK UNIFIED IDEOGRAPH + {0x8C9F, 0x691C}, //1360 #CJK UNIFIED IDEOGRAPH + {0x8CA0, 0x6A29}, //1361 #CJK UNIFIED IDEOGRAPH + {0x8CA1, 0x727D}, //1362 #CJK UNIFIED IDEOGRAPH + {0x8CA2, 0x72AC}, //1363 #CJK UNIFIED IDEOGRAPH + {0x8CA3, 0x732E}, //1364 #CJK UNIFIED IDEOGRAPH + {0x8CA4, 0x7814}, //1365 #CJK UNIFIED IDEOGRAPH + {0x8CA5, 0x786F}, //1366 #CJK UNIFIED IDEOGRAPH + {0x8CA6, 0x7D79}, //1367 #CJK UNIFIED IDEOGRAPH + {0x8CA7, 0x770C}, //1368 #CJK UNIFIED IDEOGRAPH + {0x8CA8, 0x80A9}, //1369 #CJK UNIFIED IDEOGRAPH + {0x8CA9, 0x898B}, //1370 #CJK UNIFIED IDEOGRAPH + {0x8CAA, 0x8B19}, //1371 #CJK UNIFIED IDEOGRAPH + {0x8CAB, 0x8CE2}, //1372 #CJK UNIFIED IDEOGRAPH + {0x8CAC, 0x8ED2}, //1373 #CJK UNIFIED IDEOGRAPH + {0x8CAD, 0x9063}, //1374 #CJK UNIFIED IDEOGRAPH + {0x8CAE, 0x9375}, //1375 #CJK UNIFIED IDEOGRAPH + {0x8CAF, 0x967A}, //1376 #CJK UNIFIED IDEOGRAPH + {0x8CB0, 0x9855}, //1377 #CJK UNIFIED IDEOGRAPH + {0x8CB1, 0x9A13}, //1378 #CJK UNIFIED IDEOGRAPH + {0x8CB2, 0x9E78}, //1379 #CJK UNIFIED IDEOGRAPH + {0x8CB3, 0x5143}, //1380 #CJK UNIFIED IDEOGRAPH + {0x8CB4, 0x539F}, //1381 #CJK UNIFIED IDEOGRAPH + {0x8CB5, 0x53B3}, //1382 #CJK UNIFIED IDEOGRAPH + {0x8CB6, 0x5E7B}, //1383 #CJK UNIFIED IDEOGRAPH + {0x8CB7, 0x5F26}, //1384 #CJK UNIFIED IDEOGRAPH + {0x8CB8, 0x6E1B}, //1385 #CJK UNIFIED IDEOGRAPH + {0x8CB9, 0x6E90}, //1386 #CJK UNIFIED IDEOGRAPH + {0x8CBA, 0x7384}, //1387 #CJK UNIFIED IDEOGRAPH + {0x8CBB, 0x73FE}, //1388 #CJK UNIFIED IDEOGRAPH + {0x8CBC, 0x7D43}, //1389 #CJK UNIFIED IDEOGRAPH + {0x8CBD, 0x8237}, //1390 #CJK UNIFIED IDEOGRAPH + {0x8CBE, 0x8A00}, //1391 #CJK UNIFIED IDEOGRAPH + {0x8CBF, 0x8AFA}, //1392 #CJK UNIFIED IDEOGRAPH + {0x8CC0, 0x9650}, //1393 #CJK UNIFIED IDEOGRAPH + {0x8CC1, 0x4E4E}, //1394 #CJK UNIFIED IDEOGRAPH + {0x8CC2, 0x500B}, //1395 #CJK UNIFIED IDEOGRAPH + {0x8CC3, 0x53E4}, //1396 #CJK UNIFIED IDEOGRAPH + {0x8CC4, 0x547C}, //1397 #CJK UNIFIED IDEOGRAPH + {0x8CC5, 0x56FA}, //1398 #CJK UNIFIED IDEOGRAPH + {0x8CC6, 0x59D1}, //1399 #CJK UNIFIED IDEOGRAPH + {0x8CC7, 0x5B64}, //1400 #CJK UNIFIED IDEOGRAPH + {0x8CC8, 0x5DF1}, //1401 #CJK UNIFIED IDEOGRAPH + {0x8CC9, 0x5EAB}, //1402 #CJK UNIFIED IDEOGRAPH + {0x8CCA, 0x5F27}, //1403 #CJK UNIFIED IDEOGRAPH + {0x8CCB, 0x6238}, //1404 #CJK UNIFIED IDEOGRAPH + {0x8CCC, 0x6545}, //1405 #CJK UNIFIED IDEOGRAPH + {0x8CCD, 0x67AF}, //1406 #CJK UNIFIED IDEOGRAPH + {0x8CCE, 0x6E56}, //1407 #CJK UNIFIED IDEOGRAPH + {0x8CCF, 0x72D0}, //1408 #CJK UNIFIED IDEOGRAPH + {0x8CD0, 0x7CCA}, //1409 #CJK UNIFIED IDEOGRAPH + {0x8CD1, 0x88B4}, //1410 #CJK UNIFIED IDEOGRAPH + {0x8CD2, 0x80A1}, //1411 #CJK UNIFIED IDEOGRAPH + {0x8CD3, 0x80E1}, //1412 #CJK UNIFIED IDEOGRAPH + {0x8CD4, 0x83F0}, //1413 #CJK UNIFIED IDEOGRAPH + {0x8CD5, 0x864E}, //1414 #CJK UNIFIED IDEOGRAPH + {0x8CD6, 0x8A87}, //1415 #CJK UNIFIED IDEOGRAPH + {0x8CD7, 0x8DE8}, //1416 #CJK UNIFIED IDEOGRAPH + {0x8CD8, 0x9237}, //1417 #CJK UNIFIED IDEOGRAPH + {0x8CD9, 0x96C7}, //1418 #CJK UNIFIED IDEOGRAPH + {0x8CDA, 0x9867}, //1419 #CJK UNIFIED IDEOGRAPH + {0x8CDB, 0x9F13}, //1420 #CJK UNIFIED IDEOGRAPH + {0x8CDC, 0x4E94}, //1421 #CJK UNIFIED IDEOGRAPH + {0x8CDD, 0x4E92}, //1422 #CJK UNIFIED IDEOGRAPH + {0x8CDE, 0x4F0D}, //1423 #CJK UNIFIED IDEOGRAPH + {0x8CDF, 0x5348}, //1424 #CJK UNIFIED IDEOGRAPH + {0x8CE0, 0x5449}, //1425 #CJK UNIFIED IDEOGRAPH + {0x8CE1, 0x543E}, //1426 #CJK UNIFIED IDEOGRAPH + {0x8CE2, 0x5A2F}, //1427 #CJK UNIFIED IDEOGRAPH + {0x8CE3, 0x5F8C}, //1428 #CJK UNIFIED IDEOGRAPH + {0x8CE4, 0x5FA1}, //1429 #CJK UNIFIED IDEOGRAPH + {0x8CE5, 0x609F}, //1430 #CJK UNIFIED IDEOGRAPH + {0x8CE6, 0x68A7}, //1431 #CJK UNIFIED IDEOGRAPH + {0x8CE7, 0x6A8E}, //1432 #CJK UNIFIED IDEOGRAPH + {0x8CE8, 0x745A}, //1433 #CJK UNIFIED IDEOGRAPH + {0x8CE9, 0x7881}, //1434 #CJK UNIFIED IDEOGRAPH + {0x8CEA, 0x8A9E}, //1435 #CJK UNIFIED IDEOGRAPH + {0x8CEB, 0x8AA4}, //1436 #CJK UNIFIED IDEOGRAPH + {0x8CEC, 0x8B77}, //1437 #CJK UNIFIED IDEOGRAPH + {0x8CED, 0x9190}, //1438 #CJK UNIFIED IDEOGRAPH + {0x8CEE, 0x4E5E}, //1439 #CJK UNIFIED IDEOGRAPH + {0x8CEF, 0x9BC9}, //1440 #CJK UNIFIED IDEOGRAPH + {0x8CF0, 0x4EA4}, //1441 #CJK UNIFIED IDEOGRAPH + {0x8CF1, 0x4F7C}, //1442 #CJK UNIFIED IDEOGRAPH + {0x8CF2, 0x4FAF}, //1443 #CJK UNIFIED IDEOGRAPH + {0x8CF3, 0x5019}, //1444 #CJK UNIFIED IDEOGRAPH + {0x8CF4, 0x5016}, //1445 #CJK UNIFIED IDEOGRAPH + {0x8CF5, 0x5149}, //1446 #CJK UNIFIED IDEOGRAPH + {0x8CF6, 0x516C}, //1447 #CJK UNIFIED IDEOGRAPH + {0x8CF7, 0x529F}, //1448 #CJK UNIFIED IDEOGRAPH + {0x8CF8, 0x52B9}, //1449 #CJK UNIFIED IDEOGRAPH + {0x8CF9, 0x52FE}, //1450 #CJK UNIFIED IDEOGRAPH + {0x8CFA, 0x539A}, //1451 #CJK UNIFIED IDEOGRAPH + {0x8CFB, 0x53E3}, //1452 #CJK UNIFIED IDEOGRAPH + {0x8CFC, 0x5411}, //1453 #CJK UNIFIED IDEOGRAPH + {0x8D40, 0x540E}, //1454 #CJK UNIFIED IDEOGRAPH + {0x8D41, 0x5589}, //1455 #CJK UNIFIED IDEOGRAPH + {0x8D42, 0x5751}, //1456 #CJK UNIFIED IDEOGRAPH + {0x8D43, 0x57A2}, //1457 #CJK UNIFIED IDEOGRAPH + {0x8D44, 0x597D}, //1458 #CJK UNIFIED IDEOGRAPH + {0x8D45, 0x5B54}, //1459 #CJK UNIFIED IDEOGRAPH + {0x8D46, 0x5B5D}, //1460 #CJK UNIFIED IDEOGRAPH + {0x8D47, 0x5B8F}, //1461 #CJK UNIFIED IDEOGRAPH + {0x8D48, 0x5DE5}, //1462 #CJK UNIFIED IDEOGRAPH + {0x8D49, 0x5DE7}, //1463 #CJK UNIFIED IDEOGRAPH + {0x8D4A, 0x5DF7}, //1464 #CJK UNIFIED IDEOGRAPH + {0x8D4B, 0x5E78}, //1465 #CJK UNIFIED IDEOGRAPH + {0x8D4C, 0x5E83}, //1466 #CJK UNIFIED IDEOGRAPH + {0x8D4D, 0x5E9A}, //1467 #CJK UNIFIED IDEOGRAPH + {0x8D4E, 0x5EB7}, //1468 #CJK UNIFIED IDEOGRAPH + {0x8D4F, 0x5F18}, //1469 #CJK UNIFIED IDEOGRAPH + {0x8D50, 0x6052}, //1470 #CJK UNIFIED IDEOGRAPH + {0x8D51, 0x614C}, //1471 #CJK UNIFIED IDEOGRAPH + {0x8D52, 0x6297}, //1472 #CJK UNIFIED IDEOGRAPH + {0x8D53, 0x62D8}, //1473 #CJK UNIFIED IDEOGRAPH + {0x8D54, 0x63A7}, //1474 #CJK UNIFIED IDEOGRAPH + {0x8D55, 0x653B}, //1475 #CJK UNIFIED IDEOGRAPH + {0x8D56, 0x6602}, //1476 #CJK UNIFIED IDEOGRAPH + {0x8D57, 0x6643}, //1477 #CJK UNIFIED IDEOGRAPH + {0x8D58, 0x66F4}, //1478 #CJK UNIFIED IDEOGRAPH + {0x8D59, 0x676D}, //1479 #CJK UNIFIED IDEOGRAPH + {0x8D5A, 0x6821}, //1480 #CJK UNIFIED IDEOGRAPH + {0x8D5B, 0x6897}, //1481 #CJK UNIFIED IDEOGRAPH + {0x8D5C, 0x69CB}, //1482 #CJK UNIFIED IDEOGRAPH + {0x8D5D, 0x6C5F}, //1483 #CJK UNIFIED IDEOGRAPH + {0x8D5E, 0x6D2A}, //1484 #CJK UNIFIED IDEOGRAPH + {0x8D5F, 0x6D69}, //1485 #CJK UNIFIED IDEOGRAPH + {0x8D60, 0x6E2F}, //1486 #CJK UNIFIED IDEOGRAPH + {0x8D61, 0x6E9D}, //1487 #CJK UNIFIED IDEOGRAPH + {0x8D62, 0x7532}, //1488 #CJK UNIFIED IDEOGRAPH + {0x8D63, 0x7687}, //1489 #CJK UNIFIED IDEOGRAPH + {0x8D64, 0x786C}, //1490 #CJK UNIFIED IDEOGRAPH + {0x8D65, 0x7A3F}, //1491 #CJK UNIFIED IDEOGRAPH + {0x8D66, 0x7CE0}, //1492 #CJK UNIFIED IDEOGRAPH + {0x8D67, 0x7D05}, //1493 #CJK UNIFIED IDEOGRAPH + {0x8D68, 0x7D18}, //1494 #CJK UNIFIED IDEOGRAPH + {0x8D69, 0x7D5E}, //1495 #CJK UNIFIED IDEOGRAPH + {0x8D6A, 0x7DB1}, //1496 #CJK UNIFIED IDEOGRAPH + {0x8D6B, 0x8015}, //1497 #CJK UNIFIED IDEOGRAPH + {0x8D6C, 0x8003}, //1498 #CJK UNIFIED IDEOGRAPH + {0x8D6D, 0x80AF}, //1499 #CJK UNIFIED IDEOGRAPH + {0x8D6E, 0x80B1}, //1500 #CJK UNIFIED IDEOGRAPH + {0x8D6F, 0x8154}, //1501 #CJK UNIFIED IDEOGRAPH + {0x8D70, 0x818F}, //1502 #CJK UNIFIED IDEOGRAPH + {0x8D71, 0x822A}, //1503 #CJK UNIFIED IDEOGRAPH + {0x8D72, 0x8352}, //1504 #CJK UNIFIED IDEOGRAPH + {0x8D73, 0x884C}, //1505 #CJK UNIFIED IDEOGRAPH + {0x8D74, 0x8861}, //1506 #CJK UNIFIED IDEOGRAPH + {0x8D75, 0x8B1B}, //1507 #CJK UNIFIED IDEOGRAPH + {0x8D76, 0x8CA2}, //1508 #CJK UNIFIED IDEOGRAPH + {0x8D77, 0x8CFC}, //1509 #CJK UNIFIED IDEOGRAPH + {0x8D78, 0x90CA}, //1510 #CJK UNIFIED IDEOGRAPH + {0x8D79, 0x9175}, //1511 #CJK UNIFIED IDEOGRAPH + {0x8D7A, 0x9271}, //1512 #CJK UNIFIED IDEOGRAPH + {0x8D7B, 0x783F}, //1513 #CJK UNIFIED IDEOGRAPH + {0x8D7C, 0x92FC}, //1514 #CJK UNIFIED IDEOGRAPH + {0x8D7D, 0x95A4}, //1515 #CJK UNIFIED IDEOGRAPH + {0x8D7E, 0x964D}, //1516 #CJK UNIFIED IDEOGRAPH + {0x8D80, 0x9805}, //1517 #CJK UNIFIED IDEOGRAPH + {0x8D81, 0x9999}, //1518 #CJK UNIFIED IDEOGRAPH + {0x8D82, 0x9AD8}, //1519 #CJK UNIFIED IDEOGRAPH + {0x8D83, 0x9D3B}, //1520 #CJK UNIFIED IDEOGRAPH + {0x8D84, 0x525B}, //1521 #CJK UNIFIED IDEOGRAPH + {0x8D85, 0x52AB}, //1522 #CJK UNIFIED IDEOGRAPH + {0x8D86, 0x53F7}, //1523 #CJK UNIFIED IDEOGRAPH + {0x8D87, 0x5408}, //1524 #CJK UNIFIED IDEOGRAPH + {0x8D88, 0x58D5}, //1525 #CJK UNIFIED IDEOGRAPH + {0x8D89, 0x62F7}, //1526 #CJK UNIFIED IDEOGRAPH + {0x8D8A, 0x6FE0}, //1527 #CJK UNIFIED IDEOGRAPH + {0x8D8B, 0x8C6A}, //1528 #CJK UNIFIED IDEOGRAPH + {0x8D8C, 0x8F5F}, //1529 #CJK UNIFIED IDEOGRAPH + {0x8D8D, 0x9EB9}, //1530 #CJK UNIFIED IDEOGRAPH + {0x8D8E, 0x514B}, //1531 #CJK UNIFIED IDEOGRAPH + {0x8D8F, 0x523B}, //1532 #CJK UNIFIED IDEOGRAPH + {0x8D90, 0x544A}, //1533 #CJK UNIFIED IDEOGRAPH + {0x8D91, 0x56FD}, //1534 #CJK UNIFIED IDEOGRAPH + {0x8D92, 0x7A40}, //1535 #CJK UNIFIED IDEOGRAPH + {0x8D93, 0x9177}, //1536 #CJK UNIFIED IDEOGRAPH + {0x8D94, 0x9D60}, //1537 #CJK UNIFIED IDEOGRAPH + {0x8D95, 0x9ED2}, //1538 #CJK UNIFIED IDEOGRAPH + {0x8D96, 0x7344}, //1539 #CJK UNIFIED IDEOGRAPH + {0x8D97, 0x6F09}, //1540 #CJK UNIFIED IDEOGRAPH + {0x8D98, 0x8170}, //1541 #CJK UNIFIED IDEOGRAPH + {0x8D99, 0x7511}, //1542 #CJK UNIFIED IDEOGRAPH + {0x8D9A, 0x5FFD}, //1543 #CJK UNIFIED IDEOGRAPH + {0x8D9B, 0x60DA}, //1544 #CJK UNIFIED IDEOGRAPH + {0x8D9C, 0x9AA8}, //1545 #CJK UNIFIED IDEOGRAPH + {0x8D9D, 0x72DB}, //1546 #CJK UNIFIED IDEOGRAPH + {0x8D9E, 0x8FBC}, //1547 #CJK UNIFIED IDEOGRAPH + {0x8D9F, 0x6B64}, //1548 #CJK UNIFIED IDEOGRAPH + {0x8DA0, 0x9803}, //1549 #CJK UNIFIED IDEOGRAPH + {0x8DA1, 0x4ECA}, //1550 #CJK UNIFIED IDEOGRAPH + {0x8DA2, 0x56F0}, //1551 #CJK UNIFIED IDEOGRAPH + {0x8DA3, 0x5764}, //1552 #CJK UNIFIED IDEOGRAPH + {0x8DA4, 0x58BE}, //1553 #CJK UNIFIED IDEOGRAPH + {0x8DA5, 0x5A5A}, //1554 #CJK UNIFIED IDEOGRAPH + {0x8DA6, 0x6068}, //1555 #CJK UNIFIED IDEOGRAPH + {0x8DA7, 0x61C7}, //1556 #CJK UNIFIED IDEOGRAPH + {0x8DA8, 0x660F}, //1557 #CJK UNIFIED IDEOGRAPH + {0x8DA9, 0x6606}, //1558 #CJK UNIFIED IDEOGRAPH + {0x8DAA, 0x6839}, //1559 #CJK UNIFIED IDEOGRAPH + {0x8DAB, 0x68B1}, //1560 #CJK UNIFIED IDEOGRAPH + {0x8DAC, 0x6DF7}, //1561 #CJK UNIFIED IDEOGRAPH + {0x8DAD, 0x75D5}, //1562 #CJK UNIFIED IDEOGRAPH + {0x8DAE, 0x7D3A}, //1563 #CJK UNIFIED IDEOGRAPH + {0x8DAF, 0x826E}, //1564 #CJK UNIFIED IDEOGRAPH + {0x8DB0, 0x9B42}, //1565 #CJK UNIFIED IDEOGRAPH + {0x8DB1, 0x4E9B}, //1566 #CJK UNIFIED IDEOGRAPH + {0x8DB2, 0x4F50}, //1567 #CJK UNIFIED IDEOGRAPH + {0x8DB3, 0x53C9}, //1568 #CJK UNIFIED IDEOGRAPH + {0x8DB4, 0x5506}, //1569 #CJK UNIFIED IDEOGRAPH + {0x8DB5, 0x5D6F}, //1570 #CJK UNIFIED IDEOGRAPH + {0x8DB6, 0x5DE6}, //1571 #CJK UNIFIED IDEOGRAPH + {0x8DB7, 0x5DEE}, //1572 #CJK UNIFIED IDEOGRAPH + {0x8DB8, 0x67FB}, //1573 #CJK UNIFIED IDEOGRAPH + {0x8DB9, 0x6C99}, //1574 #CJK UNIFIED IDEOGRAPH + {0x8DBA, 0x7473}, //1575 #CJK UNIFIED IDEOGRAPH + {0x8DBB, 0x7802}, //1576 #CJK UNIFIED IDEOGRAPH + {0x8DBC, 0x8A50}, //1577 #CJK UNIFIED IDEOGRAPH + {0x8DBD, 0x9396}, //1578 #CJK UNIFIED IDEOGRAPH + {0x8DBE, 0x88DF}, //1579 #CJK UNIFIED IDEOGRAPH + {0x8DBF, 0x5750}, //1580 #CJK UNIFIED IDEOGRAPH + {0x8DC0, 0x5EA7}, //1581 #CJK UNIFIED IDEOGRAPH + {0x8DC1, 0x632B}, //1582 #CJK UNIFIED IDEOGRAPH + {0x8DC2, 0x50B5}, //1583 #CJK UNIFIED IDEOGRAPH + {0x8DC3, 0x50AC}, //1584 #CJK UNIFIED IDEOGRAPH + {0x8DC4, 0x518D}, //1585 #CJK UNIFIED IDEOGRAPH + {0x8DC5, 0x6700}, //1586 #CJK UNIFIED IDEOGRAPH + {0x8DC6, 0x54C9}, //1587 #CJK UNIFIED IDEOGRAPH + {0x8DC7, 0x585E}, //1588 #CJK UNIFIED IDEOGRAPH + {0x8DC8, 0x59BB}, //1589 #CJK UNIFIED IDEOGRAPH + {0x8DC9, 0x5BB0}, //1590 #CJK UNIFIED IDEOGRAPH + {0x8DCA, 0x5F69}, //1591 #CJK UNIFIED IDEOGRAPH + {0x8DCB, 0x624D}, //1592 #CJK UNIFIED IDEOGRAPH + {0x8DCC, 0x63A1}, //1593 #CJK UNIFIED IDEOGRAPH + {0x8DCD, 0x683D}, //1594 #CJK UNIFIED IDEOGRAPH + {0x8DCE, 0x6B73}, //1595 #CJK UNIFIED IDEOGRAPH + {0x8DCF, 0x6E08}, //1596 #CJK UNIFIED IDEOGRAPH + {0x8DD0, 0x707D}, //1597 #CJK UNIFIED IDEOGRAPH + {0x8DD1, 0x91C7}, //1598 #CJK UNIFIED IDEOGRAPH + {0x8DD2, 0x7280}, //1599 #CJK UNIFIED IDEOGRAPH + {0x8DD3, 0x7815}, //1600 #CJK UNIFIED IDEOGRAPH + {0x8DD4, 0x7826}, //1601 #CJK UNIFIED IDEOGRAPH + {0x8DD5, 0x796D}, //1602 #CJK UNIFIED IDEOGRAPH + {0x8DD6, 0x658E}, //1603 #CJK UNIFIED IDEOGRAPH + {0x8DD7, 0x7D30}, //1604 #CJK UNIFIED IDEOGRAPH + {0x8DD8, 0x83DC}, //1605 #CJK UNIFIED IDEOGRAPH + {0x8DD9, 0x88C1}, //1606 #CJK UNIFIED IDEOGRAPH + {0x8DDA, 0x8F09}, //1607 #CJK UNIFIED IDEOGRAPH + {0x8DDB, 0x969B}, //1608 #CJK UNIFIED IDEOGRAPH + {0x8DDC, 0x5264}, //1609 #CJK UNIFIED IDEOGRAPH + {0x8DDD, 0x5728}, //1610 #CJK UNIFIED IDEOGRAPH + {0x8DDE, 0x6750}, //1611 #CJK UNIFIED IDEOGRAPH + {0x8DDF, 0x7F6A}, //1612 #CJK UNIFIED IDEOGRAPH + {0x8DE0, 0x8CA1}, //1613 #CJK UNIFIED IDEOGRAPH + {0x8DE1, 0x51B4}, //1614 #CJK UNIFIED IDEOGRAPH + {0x8DE2, 0x5742}, //1615 #CJK UNIFIED IDEOGRAPH + {0x8DE3, 0x962A}, //1616 #CJK UNIFIED IDEOGRAPH + {0x8DE4, 0x583A}, //1617 #CJK UNIFIED IDEOGRAPH + {0x8DE5, 0x698A}, //1618 #CJK UNIFIED IDEOGRAPH + {0x8DE6, 0x80B4}, //1619 #CJK UNIFIED IDEOGRAPH + {0x8DE7, 0x54B2}, //1620 #CJK UNIFIED IDEOGRAPH + {0x8DE8, 0x5D0E}, //1621 #CJK UNIFIED IDEOGRAPH + {0x8DE9, 0x57FC}, //1622 #CJK UNIFIED IDEOGRAPH + {0x8DEA, 0x7895}, //1623 #CJK UNIFIED IDEOGRAPH + {0x8DEB, 0x9DFA}, //1624 #CJK UNIFIED IDEOGRAPH + {0x8DEC, 0x4F5C}, //1625 #CJK UNIFIED IDEOGRAPH + {0x8DED, 0x524A}, //1626 #CJK UNIFIED IDEOGRAPH + {0x8DEE, 0x548B}, //1627 #CJK UNIFIED IDEOGRAPH + {0x8DEF, 0x643E}, //1628 #CJK UNIFIED IDEOGRAPH + {0x8DF0, 0x6628}, //1629 #CJK UNIFIED IDEOGRAPH + {0x8DF1, 0x6714}, //1630 #CJK UNIFIED IDEOGRAPH + {0x8DF2, 0x67F5}, //1631 #CJK UNIFIED IDEOGRAPH + {0x8DF3, 0x7A84}, //1632 #CJK UNIFIED IDEOGRAPH + {0x8DF4, 0x7B56}, //1633 #CJK UNIFIED IDEOGRAPH + {0x8DF5, 0x7D22}, //1634 #CJK UNIFIED IDEOGRAPH + {0x8DF6, 0x932F}, //1635 #CJK UNIFIED IDEOGRAPH + {0x8DF7, 0x685C}, //1636 #CJK UNIFIED IDEOGRAPH + {0x8DF8, 0x9BAD}, //1637 #CJK UNIFIED IDEOGRAPH + {0x8DF9, 0x7B39}, //1638 #CJK UNIFIED IDEOGRAPH + {0x8DFA, 0x5319}, //1639 #CJK UNIFIED IDEOGRAPH + {0x8DFB, 0x518A}, //1640 #CJK UNIFIED IDEOGRAPH + {0x8DFC, 0x5237}, //1641 #CJK UNIFIED IDEOGRAPH + {0x8E40, 0x5BDF}, //1642 #CJK UNIFIED IDEOGRAPH + {0x8E41, 0x62F6}, //1643 #CJK UNIFIED IDEOGRAPH + {0x8E42, 0x64AE}, //1644 #CJK UNIFIED IDEOGRAPH + {0x8E43, 0x64E6}, //1645 #CJK UNIFIED IDEOGRAPH + {0x8E44, 0x672D}, //1646 #CJK UNIFIED IDEOGRAPH + {0x8E45, 0x6BBA}, //1647 #CJK UNIFIED IDEOGRAPH + {0x8E46, 0x85A9}, //1648 #CJK UNIFIED IDEOGRAPH + {0x8E47, 0x96D1}, //1649 #CJK UNIFIED IDEOGRAPH + {0x8E48, 0x7690}, //1650 #CJK UNIFIED IDEOGRAPH + {0x8E49, 0x9BD6}, //1651 #CJK UNIFIED IDEOGRAPH + {0x8E4A, 0x634C}, //1652 #CJK UNIFIED IDEOGRAPH + {0x8E4B, 0x9306}, //1653 #CJK UNIFIED IDEOGRAPH + {0x8E4C, 0x9BAB}, //1654 #CJK UNIFIED IDEOGRAPH + {0x8E4D, 0x76BF}, //1655 #CJK UNIFIED IDEOGRAPH + {0x8E4E, 0x6652}, //1656 #CJK UNIFIED IDEOGRAPH + {0x8E4F, 0x4E09}, //1657 #CJK UNIFIED IDEOGRAPH + {0x8E50, 0x5098}, //1658 #CJK UNIFIED IDEOGRAPH + {0x8E51, 0x53C2}, //1659 #CJK UNIFIED IDEOGRAPH + {0x8E52, 0x5C71}, //1660 #CJK UNIFIED IDEOGRAPH + {0x8E53, 0x60E8}, //1661 #CJK UNIFIED IDEOGRAPH + {0x8E54, 0x6492}, //1662 #CJK UNIFIED IDEOGRAPH + {0x8E55, 0x6563}, //1663 #CJK UNIFIED IDEOGRAPH + {0x8E56, 0x685F}, //1664 #CJK UNIFIED IDEOGRAPH + {0x8E57, 0x71E6}, //1665 #CJK UNIFIED IDEOGRAPH + {0x8E58, 0x73CA}, //1666 #CJK UNIFIED IDEOGRAPH + {0x8E59, 0x7523}, //1667 #CJK UNIFIED IDEOGRAPH + {0x8E5A, 0x7B97}, //1668 #CJK UNIFIED IDEOGRAPH + {0x8E5B, 0x7E82}, //1669 #CJK UNIFIED IDEOGRAPH + {0x8E5C, 0x8695}, //1670 #CJK UNIFIED IDEOGRAPH + {0x8E5D, 0x8B83}, //1671 #CJK UNIFIED IDEOGRAPH + {0x8E5E, 0x8CDB}, //1672 #CJK UNIFIED IDEOGRAPH + {0x8E5F, 0x9178}, //1673 #CJK UNIFIED IDEOGRAPH + {0x8E60, 0x9910}, //1674 #CJK UNIFIED IDEOGRAPH + {0x8E61, 0x65AC}, //1675 #CJK UNIFIED IDEOGRAPH + {0x8E62, 0x66AB}, //1676 #CJK UNIFIED IDEOGRAPH + {0x8E63, 0x6B8B}, //1677 #CJK UNIFIED IDEOGRAPH + {0x8E64, 0x4ED5}, //1678 #CJK UNIFIED IDEOGRAPH + {0x8E65, 0x4ED4}, //1679 #CJK UNIFIED IDEOGRAPH + {0x8E66, 0x4F3A}, //1680 #CJK UNIFIED IDEOGRAPH + {0x8E67, 0x4F7F}, //1681 #CJK UNIFIED IDEOGRAPH + {0x8E68, 0x523A}, //1682 #CJK UNIFIED IDEOGRAPH + {0x8E69, 0x53F8}, //1683 #CJK UNIFIED IDEOGRAPH + {0x8E6A, 0x53F2}, //1684 #CJK UNIFIED IDEOGRAPH + {0x8E6B, 0x55E3}, //1685 #CJK UNIFIED IDEOGRAPH + {0x8E6C, 0x56DB}, //1686 #CJK UNIFIED IDEOGRAPH + {0x8E6D, 0x58EB}, //1687 #CJK UNIFIED IDEOGRAPH + {0x8E6E, 0x59CB}, //1688 #CJK UNIFIED IDEOGRAPH + {0x8E6F, 0x59C9}, //1689 #CJK UNIFIED IDEOGRAPH + {0x8E70, 0x59FF}, //1690 #CJK UNIFIED IDEOGRAPH + {0x8E71, 0x5B50}, //1691 #CJK UNIFIED IDEOGRAPH + {0x8E72, 0x5C4D}, //1692 #CJK UNIFIED IDEOGRAPH + {0x8E73, 0x5E02}, //1693 #CJK UNIFIED IDEOGRAPH + {0x8E74, 0x5E2B}, //1694 #CJK UNIFIED IDEOGRAPH + {0x8E75, 0x5FD7}, //1695 #CJK UNIFIED IDEOGRAPH + {0x8E76, 0x601D}, //1696 #CJK UNIFIED IDEOGRAPH + {0x8E77, 0x6307}, //1697 #CJK UNIFIED IDEOGRAPH + {0x8E78, 0x652F}, //1698 #CJK UNIFIED IDEOGRAPH + {0x8E79, 0x5B5C}, //1699 #CJK UNIFIED IDEOGRAPH + {0x8E7A, 0x65AF}, //1700 #CJK UNIFIED IDEOGRAPH + {0x8E7B, 0x65BD}, //1701 #CJK UNIFIED IDEOGRAPH + {0x8E7C, 0x65E8}, //1702 #CJK UNIFIED IDEOGRAPH + {0x8E7D, 0x679D}, //1703 #CJK UNIFIED IDEOGRAPH + {0x8E7E, 0x6B62}, //1704 #CJK UNIFIED IDEOGRAPH + {0x8E80, 0x6B7B}, //1705 #CJK UNIFIED IDEOGRAPH + {0x8E81, 0x6C0F}, //1706 #CJK UNIFIED IDEOGRAPH + {0x8E82, 0x7345}, //1707 #CJK UNIFIED IDEOGRAPH + {0x8E83, 0x7949}, //1708 #CJK UNIFIED IDEOGRAPH + {0x8E84, 0x79C1}, //1709 #CJK UNIFIED IDEOGRAPH + {0x8E85, 0x7CF8}, //1710 #CJK UNIFIED IDEOGRAPH + {0x8E86, 0x7D19}, //1711 #CJK UNIFIED IDEOGRAPH + {0x8E87, 0x7D2B}, //1712 #CJK UNIFIED IDEOGRAPH + {0x8E88, 0x80A2}, //1713 #CJK UNIFIED IDEOGRAPH + {0x8E89, 0x8102}, //1714 #CJK UNIFIED IDEOGRAPH + {0x8E8A, 0x81F3}, //1715 #CJK UNIFIED IDEOGRAPH + {0x8E8B, 0x8996}, //1716 #CJK UNIFIED IDEOGRAPH + {0x8E8C, 0x8A5E}, //1717 #CJK UNIFIED IDEOGRAPH + {0x8E8D, 0x8A69}, //1718 #CJK UNIFIED IDEOGRAPH + {0x8E8E, 0x8A66}, //1719 #CJK UNIFIED IDEOGRAPH + {0x8E8F, 0x8A8C}, //1720 #CJK UNIFIED IDEOGRAPH + {0x8E90, 0x8AEE}, //1721 #CJK UNIFIED IDEOGRAPH + {0x8E91, 0x8CC7}, //1722 #CJK UNIFIED IDEOGRAPH + {0x8E92, 0x8CDC}, //1723 #CJK UNIFIED IDEOGRAPH + {0x8E93, 0x96CC}, //1724 #CJK UNIFIED IDEOGRAPH + {0x8E94, 0x98FC}, //1725 #CJK UNIFIED IDEOGRAPH + {0x8E95, 0x6B6F}, //1726 #CJK UNIFIED IDEOGRAPH + {0x8E96, 0x4E8B}, //1727 #CJK UNIFIED IDEOGRAPH + {0x8E97, 0x4F3C}, //1728 #CJK UNIFIED IDEOGRAPH + {0x8E98, 0x4F8D}, //1729 #CJK UNIFIED IDEOGRAPH + {0x8E99, 0x5150}, //1730 #CJK UNIFIED IDEOGRAPH + {0x8E9A, 0x5B57}, //1731 #CJK UNIFIED IDEOGRAPH + {0x8E9B, 0x5BFA}, //1732 #CJK UNIFIED IDEOGRAPH + {0x8E9C, 0x6148}, //1733 #CJK UNIFIED IDEOGRAPH + {0x8E9D, 0x6301}, //1734 #CJK UNIFIED IDEOGRAPH + {0x8E9E, 0x6642}, //1735 #CJK UNIFIED IDEOGRAPH + {0x8E9F, 0x6B21}, //1736 #CJK UNIFIED IDEOGRAPH + {0x8EA0, 0x6ECB}, //1737 #CJK UNIFIED IDEOGRAPH + {0x8EA1, 0x6CBB}, //1738 #CJK UNIFIED IDEOGRAPH + {0x8EA2, 0x723E}, //1739 #CJK UNIFIED IDEOGRAPH + {0x8EA3, 0x74BD}, //1740 #CJK UNIFIED IDEOGRAPH + {0x8EA4, 0x75D4}, //1741 #CJK UNIFIED IDEOGRAPH + {0x8EA5, 0x78C1}, //1742 #CJK UNIFIED IDEOGRAPH + {0x8EA6, 0x793A}, //1743 #CJK UNIFIED IDEOGRAPH + {0x8EA7, 0x800C}, //1744 #CJK UNIFIED IDEOGRAPH + {0x8EA8, 0x8033}, //1745 #CJK UNIFIED IDEOGRAPH + {0x8EA9, 0x81EA}, //1746 #CJK UNIFIED IDEOGRAPH + {0x8EAA, 0x8494}, //1747 #CJK UNIFIED IDEOGRAPH + {0x8EAB, 0x8F9E}, //1748 #CJK UNIFIED IDEOGRAPH + {0x8EAC, 0x6C50}, //1749 #CJK UNIFIED IDEOGRAPH + {0x8EAD, 0x9E7F}, //1750 #CJK UNIFIED IDEOGRAPH + {0x8EAE, 0x5F0F}, //1751 #CJK UNIFIED IDEOGRAPH + {0x8EAF, 0x8B58}, //1752 #CJK UNIFIED IDEOGRAPH + {0x8EB0, 0x9D2B}, //1753 #CJK UNIFIED IDEOGRAPH + {0x8EB1, 0x7AFA}, //1754 #CJK UNIFIED IDEOGRAPH + {0x8EB2, 0x8EF8}, //1755 #CJK UNIFIED IDEOGRAPH + {0x8EB3, 0x5B8D}, //1756 #CJK UNIFIED IDEOGRAPH + {0x8EB4, 0x96EB}, //1757 #CJK UNIFIED IDEOGRAPH + {0x8EB5, 0x4E03}, //1758 #CJK UNIFIED IDEOGRAPH + {0x8EB6, 0x53F1}, //1759 #CJK UNIFIED IDEOGRAPH + {0x8EB7, 0x57F7}, //1760 #CJK UNIFIED IDEOGRAPH + {0x8EB8, 0x5931}, //1761 #CJK UNIFIED IDEOGRAPH + {0x8EB9, 0x5AC9}, //1762 #CJK UNIFIED IDEOGRAPH + {0x8EBA, 0x5BA4}, //1763 #CJK UNIFIED IDEOGRAPH + {0x8EBB, 0x6089}, //1764 #CJK UNIFIED IDEOGRAPH + {0x8EBC, 0x6E7F}, //1765 #CJK UNIFIED IDEOGRAPH + {0x8EBD, 0x6F06}, //1766 #CJK UNIFIED IDEOGRAPH + {0x8EBE, 0x75BE}, //1767 #CJK UNIFIED IDEOGRAPH + {0x8EBF, 0x8CEA}, //1768 #CJK UNIFIED IDEOGRAPH + {0x8EC0, 0x5B9F}, //1769 #CJK UNIFIED IDEOGRAPH + {0x8EC1, 0x8500}, //1770 #CJK UNIFIED IDEOGRAPH + {0x8EC2, 0x7BE0}, //1771 #CJK UNIFIED IDEOGRAPH + {0x8EC3, 0x5072}, //1772 #CJK UNIFIED IDEOGRAPH + {0x8EC4, 0x67F4}, //1773 #CJK UNIFIED IDEOGRAPH + {0x8EC5, 0x829D}, //1774 #CJK UNIFIED IDEOGRAPH + {0x8EC6, 0x5C61}, //1775 #CJK UNIFIED IDEOGRAPH + {0x8EC7, 0x854A}, //1776 #CJK UNIFIED IDEOGRAPH + {0x8EC8, 0x7E1E}, //1777 #CJK UNIFIED IDEOGRAPH + {0x8EC9, 0x820E}, //1778 #CJK UNIFIED IDEOGRAPH + {0x8ECA, 0x5199}, //1779 #CJK UNIFIED IDEOGRAPH + {0x8ECB, 0x5C04}, //1780 #CJK UNIFIED IDEOGRAPH + {0x8ECC, 0x6368}, //1781 #CJK UNIFIED IDEOGRAPH + {0x8ECD, 0x8D66}, //1782 #CJK UNIFIED IDEOGRAPH + {0x8ECE, 0x659C}, //1783 #CJK UNIFIED IDEOGRAPH + {0x8ECF, 0x716E}, //1784 #CJK UNIFIED IDEOGRAPH + {0x8ED0, 0x793E}, //1785 #CJK UNIFIED IDEOGRAPH + {0x8ED1, 0x7D17}, //1786 #CJK UNIFIED IDEOGRAPH + {0x8ED2, 0x8005}, //1787 #CJK UNIFIED IDEOGRAPH + {0x8ED3, 0x8B1D}, //1788 #CJK UNIFIED IDEOGRAPH + {0x8ED4, 0x8ECA}, //1789 #CJK UNIFIED IDEOGRAPH + {0x8ED5, 0x906E}, //1790 #CJK UNIFIED IDEOGRAPH + {0x8ED6, 0x86C7}, //1791 #CJK UNIFIED IDEOGRAPH + {0x8ED7, 0x90AA}, //1792 #CJK UNIFIED IDEOGRAPH + {0x8ED8, 0x501F}, //1793 #CJK UNIFIED IDEOGRAPH + {0x8ED9, 0x52FA}, //1794 #CJK UNIFIED IDEOGRAPH + {0x8EDA, 0x5C3A}, //1795 #CJK UNIFIED IDEOGRAPH + {0x8EDB, 0x6753}, //1796 #CJK UNIFIED IDEOGRAPH + {0x8EDC, 0x707C}, //1797 #CJK UNIFIED IDEOGRAPH + {0x8EDD, 0x7235}, //1798 #CJK UNIFIED IDEOGRAPH + {0x8EDE, 0x914C}, //1799 #CJK UNIFIED IDEOGRAPH + {0x8EDF, 0x91C8}, //1800 #CJK UNIFIED IDEOGRAPH + {0x8EE0, 0x932B}, //1801 #CJK UNIFIED IDEOGRAPH + {0x8EE1, 0x82E5}, //1802 #CJK UNIFIED IDEOGRAPH + {0x8EE2, 0x5BC2}, //1803 #CJK UNIFIED IDEOGRAPH + {0x8EE3, 0x5F31}, //1804 #CJK UNIFIED IDEOGRAPH + {0x8EE4, 0x60F9}, //1805 #CJK UNIFIED IDEOGRAPH + {0x8EE5, 0x4E3B}, //1806 #CJK UNIFIED IDEOGRAPH + {0x8EE6, 0x53D6}, //1807 #CJK UNIFIED IDEOGRAPH + {0x8EE7, 0x5B88}, //1808 #CJK UNIFIED IDEOGRAPH + {0x8EE8, 0x624B}, //1809 #CJK UNIFIED IDEOGRAPH + {0x8EE9, 0x6731}, //1810 #CJK UNIFIED IDEOGRAPH + {0x8EEA, 0x6B8A}, //1811 #CJK UNIFIED IDEOGRAPH + {0x8EEB, 0x72E9}, //1812 #CJK UNIFIED IDEOGRAPH + {0x8EEC, 0x73E0}, //1813 #CJK UNIFIED IDEOGRAPH + {0x8EED, 0x7A2E}, //1814 #CJK UNIFIED IDEOGRAPH + {0x8EEE, 0x816B}, //1815 #CJK UNIFIED IDEOGRAPH + {0x8EEF, 0x8DA3}, //1816 #CJK UNIFIED IDEOGRAPH + {0x8EF0, 0x9152}, //1817 #CJK UNIFIED IDEOGRAPH + {0x8EF1, 0x9996}, //1818 #CJK UNIFIED IDEOGRAPH + {0x8EF2, 0x5112}, //1819 #CJK UNIFIED IDEOGRAPH + {0x8EF3, 0x53D7}, //1820 #CJK UNIFIED IDEOGRAPH + {0x8EF4, 0x546A}, //1821 #CJK UNIFIED IDEOGRAPH + {0x8EF5, 0x5BFF}, //1822 #CJK UNIFIED IDEOGRAPH + {0x8EF6, 0x6388}, //1823 #CJK UNIFIED IDEOGRAPH + {0x8EF7, 0x6A39}, //1824 #CJK UNIFIED IDEOGRAPH + {0x8EF8, 0x7DAC}, //1825 #CJK UNIFIED IDEOGRAPH + {0x8EF9, 0x9700}, //1826 #CJK UNIFIED IDEOGRAPH + {0x8EFA, 0x56DA}, //1827 #CJK UNIFIED IDEOGRAPH + {0x8EFB, 0x53CE}, //1828 #CJK UNIFIED IDEOGRAPH + {0x8EFC, 0x5468}, //1829 #CJK UNIFIED IDEOGRAPH + {0x8F40, 0x5B97}, //1830 #CJK UNIFIED IDEOGRAPH + {0x8F41, 0x5C31}, //1831 #CJK UNIFIED IDEOGRAPH + {0x8F42, 0x5DDE}, //1832 #CJK UNIFIED IDEOGRAPH + {0x8F43, 0x4FEE}, //1833 #CJK UNIFIED IDEOGRAPH + {0x8F44, 0x6101}, //1834 #CJK UNIFIED IDEOGRAPH + {0x8F45, 0x62FE}, //1835 #CJK UNIFIED IDEOGRAPH + {0x8F46, 0x6D32}, //1836 #CJK UNIFIED IDEOGRAPH + {0x8F47, 0x79C0}, //1837 #CJK UNIFIED IDEOGRAPH + {0x8F48, 0x79CB}, //1838 #CJK UNIFIED IDEOGRAPH + {0x8F49, 0x7D42}, //1839 #CJK UNIFIED IDEOGRAPH + {0x8F4A, 0x7E4D}, //1840 #CJK UNIFIED IDEOGRAPH + {0x8F4B, 0x7FD2}, //1841 #CJK UNIFIED IDEOGRAPH + {0x8F4C, 0x81ED}, //1842 #CJK UNIFIED IDEOGRAPH + {0x8F4D, 0x821F}, //1843 #CJK UNIFIED IDEOGRAPH + {0x8F4E, 0x8490}, //1844 #CJK UNIFIED IDEOGRAPH + {0x8F4F, 0x8846}, //1845 #CJK UNIFIED IDEOGRAPH + {0x8F50, 0x8972}, //1846 #CJK UNIFIED IDEOGRAPH + {0x8F51, 0x8B90}, //1847 #CJK UNIFIED IDEOGRAPH + {0x8F52, 0x8E74}, //1848 #CJK UNIFIED IDEOGRAPH + {0x8F53, 0x8F2F}, //1849 #CJK UNIFIED IDEOGRAPH + {0x8F54, 0x9031}, //1850 #CJK UNIFIED IDEOGRAPH + {0x8F55, 0x914B}, //1851 #CJK UNIFIED IDEOGRAPH + {0x8F56, 0x916C}, //1852 #CJK UNIFIED IDEOGRAPH + {0x8F57, 0x96C6}, //1853 #CJK UNIFIED IDEOGRAPH + {0x8F58, 0x919C}, //1854 #CJK UNIFIED IDEOGRAPH + {0x8F59, 0x4EC0}, //1855 #CJK UNIFIED IDEOGRAPH + {0x8F5A, 0x4F4F}, //1856 #CJK UNIFIED IDEOGRAPH + {0x8F5B, 0x5145}, //1857 #CJK UNIFIED IDEOGRAPH + {0x8F5C, 0x5341}, //1858 #CJK UNIFIED IDEOGRAPH + {0x8F5D, 0x5F93}, //1859 #CJK UNIFIED IDEOGRAPH + {0x8F5E, 0x620E}, //1860 #CJK UNIFIED IDEOGRAPH + {0x8F5F, 0x67D4}, //1861 #CJK UNIFIED IDEOGRAPH + {0x8F60, 0x6C41}, //1862 #CJK UNIFIED IDEOGRAPH + {0x8F61, 0x6E0B}, //1863 #CJK UNIFIED IDEOGRAPH + {0x8F62, 0x7363}, //1864 #CJK UNIFIED IDEOGRAPH + {0x8F63, 0x7E26}, //1865 #CJK UNIFIED IDEOGRAPH + {0x8F64, 0x91CD}, //1866 #CJK UNIFIED IDEOGRAPH + {0x8F65, 0x9283}, //1867 #CJK UNIFIED IDEOGRAPH + {0x8F66, 0x53D4}, //1868 #CJK UNIFIED IDEOGRAPH + {0x8F67, 0x5919}, //1869 #CJK UNIFIED IDEOGRAPH + {0x8F68, 0x5BBF}, //1870 #CJK UNIFIED IDEOGRAPH + {0x8F69, 0x6DD1}, //1871 #CJK UNIFIED IDEOGRAPH + {0x8F6A, 0x795D}, //1872 #CJK UNIFIED IDEOGRAPH + {0x8F6B, 0x7E2E}, //1873 #CJK UNIFIED IDEOGRAPH + {0x8F6C, 0x7C9B}, //1874 #CJK UNIFIED IDEOGRAPH + {0x8F6D, 0x587E}, //1875 #CJK UNIFIED IDEOGRAPH + {0x8F6E, 0x719F}, //1876 #CJK UNIFIED IDEOGRAPH + {0x8F6F, 0x51FA}, //1877 #CJK UNIFIED IDEOGRAPH + {0x8F70, 0x8853}, //1878 #CJK UNIFIED IDEOGRAPH + {0x8F71, 0x8FF0}, //1879 #CJK UNIFIED IDEOGRAPH + {0x8F72, 0x4FCA}, //1880 #CJK UNIFIED IDEOGRAPH + {0x8F73, 0x5CFB}, //1881 #CJK UNIFIED IDEOGRAPH + {0x8F74, 0x6625}, //1882 #CJK UNIFIED IDEOGRAPH + {0x8F75, 0x77AC}, //1883 #CJK UNIFIED IDEOGRAPH + {0x8F76, 0x7AE3}, //1884 #CJK UNIFIED IDEOGRAPH + {0x8F77, 0x821C}, //1885 #CJK UNIFIED IDEOGRAPH + {0x8F78, 0x99FF}, //1886 #CJK UNIFIED IDEOGRAPH + {0x8F79, 0x51C6}, //1887 #CJK UNIFIED IDEOGRAPH + {0x8F7A, 0x5FAA}, //1888 #CJK UNIFIED IDEOGRAPH + {0x8F7B, 0x65EC}, //1889 #CJK UNIFIED IDEOGRAPH + {0x8F7C, 0x696F}, //1890 #CJK UNIFIED IDEOGRAPH + {0x8F7D, 0x6B89}, //1891 #CJK UNIFIED IDEOGRAPH + {0x8F7E, 0x6DF3}, //1892 #CJK UNIFIED IDEOGRAPH + {0x8F80, 0x6E96}, //1893 #CJK UNIFIED IDEOGRAPH + {0x8F81, 0x6F64}, //1894 #CJK UNIFIED IDEOGRAPH + {0x8F82, 0x76FE}, //1895 #CJK UNIFIED IDEOGRAPH + {0x8F83, 0x7D14}, //1896 #CJK UNIFIED IDEOGRAPH + {0x8F84, 0x5DE1}, //1897 #CJK UNIFIED IDEOGRAPH + {0x8F85, 0x9075}, //1898 #CJK UNIFIED IDEOGRAPH + {0x8F86, 0x9187}, //1899 #CJK UNIFIED IDEOGRAPH + {0x8F87, 0x9806}, //1900 #CJK UNIFIED IDEOGRAPH + {0x8F88, 0x51E6}, //1901 #CJK UNIFIED IDEOGRAPH + {0x8F89, 0x521D}, //1902 #CJK UNIFIED IDEOGRAPH + {0x8F8A, 0x6240}, //1903 #CJK UNIFIED IDEOGRAPH + {0x8F8B, 0x6691}, //1904 #CJK UNIFIED IDEOGRAPH + {0x8F8C, 0x66D9}, //1905 #CJK UNIFIED IDEOGRAPH + {0x8F8D, 0x6E1A}, //1906 #CJK UNIFIED IDEOGRAPH + {0x8F8E, 0x5EB6}, //1907 #CJK UNIFIED IDEOGRAPH + {0x8F8F, 0x7DD2}, //1908 #CJK UNIFIED IDEOGRAPH + {0x8F90, 0x7F72}, //1909 #CJK UNIFIED IDEOGRAPH + {0x8F91, 0x66F8}, //1910 #CJK UNIFIED IDEOGRAPH + {0x8F92, 0x85AF}, //1911 #CJK UNIFIED IDEOGRAPH + {0x8F93, 0x85F7}, //1912 #CJK UNIFIED IDEOGRAPH + {0x8F94, 0x8AF8}, //1913 #CJK UNIFIED IDEOGRAPH + {0x8F95, 0x52A9}, //1914 #CJK UNIFIED IDEOGRAPH + {0x8F96, 0x53D9}, //1915 #CJK UNIFIED IDEOGRAPH + {0x8F97, 0x5973}, //1916 #CJK UNIFIED IDEOGRAPH + {0x8F98, 0x5E8F}, //1917 #CJK UNIFIED IDEOGRAPH + {0x8F99, 0x5F90}, //1918 #CJK UNIFIED IDEOGRAPH + {0x8F9A, 0x6055}, //1919 #CJK UNIFIED IDEOGRAPH + {0x8F9B, 0x92E4}, //1920 #CJK UNIFIED IDEOGRAPH + {0x8F9C, 0x9664}, //1921 #CJK UNIFIED IDEOGRAPH + {0x8F9D, 0x50B7}, //1922 #CJK UNIFIED IDEOGRAPH + {0x8F9E, 0x511F}, //1923 #CJK UNIFIED IDEOGRAPH + {0x8F9F, 0x52DD}, //1924 #CJK UNIFIED IDEOGRAPH + {0x8FA0, 0x5320}, //1925 #CJK UNIFIED IDEOGRAPH + {0x8FA1, 0x5347}, //1926 #CJK UNIFIED IDEOGRAPH + {0x8FA2, 0x53EC}, //1927 #CJK UNIFIED IDEOGRAPH + {0x8FA3, 0x54E8}, //1928 #CJK UNIFIED IDEOGRAPH + {0x8FA4, 0x5546}, //1929 #CJK UNIFIED IDEOGRAPH + {0x8FA5, 0x5531}, //1930 #CJK UNIFIED IDEOGRAPH + {0x8FA6, 0x5617}, //1931 #CJK UNIFIED IDEOGRAPH + {0x8FA7, 0x5968}, //1932 #CJK UNIFIED IDEOGRAPH + {0x8FA8, 0x59BE}, //1933 #CJK UNIFIED IDEOGRAPH + {0x8FA9, 0x5A3C}, //1934 #CJK UNIFIED IDEOGRAPH + {0x8FAA, 0x5BB5}, //1935 #CJK UNIFIED IDEOGRAPH + {0x8FAB, 0x5C06}, //1936 #CJK UNIFIED IDEOGRAPH + {0x8FAC, 0x5C0F}, //1937 #CJK UNIFIED IDEOGRAPH + {0x8FAD, 0x5C11}, //1938 #CJK UNIFIED IDEOGRAPH + {0x8FAE, 0x5C1A}, //1939 #CJK UNIFIED IDEOGRAPH + {0x8FAF, 0x5E84}, //1940 #CJK UNIFIED IDEOGRAPH + {0x8FB0, 0x5E8A}, //1941 #CJK UNIFIED IDEOGRAPH + {0x8FB1, 0x5EE0}, //1942 #CJK UNIFIED IDEOGRAPH + {0x8FB2, 0x5F70}, //1943 #CJK UNIFIED IDEOGRAPH + {0x8FB3, 0x627F}, //1944 #CJK UNIFIED IDEOGRAPH + {0x8FB4, 0x6284}, //1945 #CJK UNIFIED IDEOGRAPH + {0x8FB5, 0x62DB}, //1946 #CJK UNIFIED IDEOGRAPH + {0x8FB6, 0x638C}, //1947 #CJK UNIFIED IDEOGRAPH + {0x8FB7, 0x6377}, //1948 #CJK UNIFIED IDEOGRAPH + {0x8FB8, 0x6607}, //1949 #CJK UNIFIED IDEOGRAPH + {0x8FB9, 0x660C}, //1950 #CJK UNIFIED IDEOGRAPH + {0x8FBA, 0x662D}, //1951 #CJK UNIFIED IDEOGRAPH + {0x8FBB, 0x6676}, //1952 #CJK UNIFIED IDEOGRAPH + {0x8FBC, 0x677E}, //1953 #CJK UNIFIED IDEOGRAPH + {0x8FBD, 0x68A2}, //1954 #CJK UNIFIED IDEOGRAPH + {0x8FBE, 0x6A1F}, //1955 #CJK UNIFIED IDEOGRAPH + {0x8FBF, 0x6A35}, //1956 #CJK UNIFIED IDEOGRAPH + {0x8FC0, 0x6CBC}, //1957 #CJK UNIFIED IDEOGRAPH + {0x8FC1, 0x6D88}, //1958 #CJK UNIFIED IDEOGRAPH + {0x8FC2, 0x6E09}, //1959 #CJK UNIFIED IDEOGRAPH + {0x8FC3, 0x6E58}, //1960 #CJK UNIFIED IDEOGRAPH + {0x8FC4, 0x713C}, //1961 #CJK UNIFIED IDEOGRAPH + {0x8FC5, 0x7126}, //1962 #CJK UNIFIED IDEOGRAPH + {0x8FC6, 0x7167}, //1963 #CJK UNIFIED IDEOGRAPH + {0x8FC7, 0x75C7}, //1964 #CJK UNIFIED IDEOGRAPH + {0x8FC8, 0x7701}, //1965 #CJK UNIFIED IDEOGRAPH + {0x8FC9, 0x785D}, //1966 #CJK UNIFIED IDEOGRAPH + {0x8FCA, 0x7901}, //1967 #CJK UNIFIED IDEOGRAPH + {0x8FCB, 0x7965}, //1968 #CJK UNIFIED IDEOGRAPH + {0x8FCC, 0x79F0}, //1969 #CJK UNIFIED IDEOGRAPH + {0x8FCD, 0x7AE0}, //1970 #CJK UNIFIED IDEOGRAPH + {0x8FCE, 0x7B11}, //1971 #CJK UNIFIED IDEOGRAPH + {0x8FCF, 0x7CA7}, //1972 #CJK UNIFIED IDEOGRAPH + {0x8FD0, 0x7D39}, //1973 #CJK UNIFIED IDEOGRAPH + {0x8FD1, 0x8096}, //1974 #CJK UNIFIED IDEOGRAPH + {0x8FD2, 0x83D6}, //1975 #CJK UNIFIED IDEOGRAPH + {0x8FD3, 0x848B}, //1976 #CJK UNIFIED IDEOGRAPH + {0x8FD4, 0x8549}, //1977 #CJK UNIFIED IDEOGRAPH + {0x8FD5, 0x885D}, //1978 #CJK UNIFIED IDEOGRAPH + {0x8FD6, 0x88F3}, //1979 #CJK UNIFIED IDEOGRAPH + {0x8FD7, 0x8A1F}, //1980 #CJK UNIFIED IDEOGRAPH + {0x8FD8, 0x8A3C}, //1981 #CJK UNIFIED IDEOGRAPH + {0x8FD9, 0x8A54}, //1982 #CJK UNIFIED IDEOGRAPH + {0x8FDA, 0x8A73}, //1983 #CJK UNIFIED IDEOGRAPH + {0x8FDB, 0x8C61}, //1984 #CJK UNIFIED IDEOGRAPH + {0x8FDC, 0x8CDE}, //1985 #CJK UNIFIED IDEOGRAPH + {0x8FDD, 0x91A4}, //1986 #CJK UNIFIED IDEOGRAPH + {0x8FDE, 0x9266}, //1987 #CJK UNIFIED IDEOGRAPH + {0x8FDF, 0x937E}, //1988 #CJK UNIFIED IDEOGRAPH + {0x8FE0, 0x9418}, //1989 #CJK UNIFIED IDEOGRAPH + {0x8FE1, 0x969C}, //1990 #CJK UNIFIED IDEOGRAPH + {0x8FE2, 0x9798}, //1991 #CJK UNIFIED IDEOGRAPH + {0x8FE3, 0x4E0A}, //1992 #CJK UNIFIED IDEOGRAPH + {0x8FE4, 0x4E08}, //1993 #CJK UNIFIED IDEOGRAPH + {0x8FE5, 0x4E1E}, //1994 #CJK UNIFIED IDEOGRAPH + {0x8FE6, 0x4E57}, //1995 #CJK UNIFIED IDEOGRAPH + {0x8FE7, 0x5197}, //1996 #CJK UNIFIED IDEOGRAPH + {0x8FE8, 0x5270}, //1997 #CJK UNIFIED IDEOGRAPH + {0x8FE9, 0x57CE}, //1998 #CJK UNIFIED IDEOGRAPH + {0x8FEA, 0x5834}, //1999 #CJK UNIFIED IDEOGRAPH + {0x8FEB, 0x58CC}, //2000 #CJK UNIFIED IDEOGRAPH + {0x8FEC, 0x5B22}, //2001 #CJK UNIFIED IDEOGRAPH + {0x8FED, 0x5E38}, //2002 #CJK UNIFIED IDEOGRAPH + {0x8FEE, 0x60C5}, //2003 #CJK UNIFIED IDEOGRAPH + {0x8FEF, 0x64FE}, //2004 #CJK UNIFIED IDEOGRAPH + {0x8FF0, 0x6761}, //2005 #CJK UNIFIED IDEOGRAPH + {0x8FF1, 0x6756}, //2006 #CJK UNIFIED IDEOGRAPH + {0x8FF2, 0x6D44}, //2007 #CJK UNIFIED IDEOGRAPH + {0x8FF3, 0x72B6}, //2008 #CJK UNIFIED IDEOGRAPH + {0x8FF4, 0x7573}, //2009 #CJK UNIFIED IDEOGRAPH + {0x8FF5, 0x7A63}, //2010 #CJK UNIFIED IDEOGRAPH + {0x8FF6, 0x84B8}, //2011 #CJK UNIFIED IDEOGRAPH + {0x8FF7, 0x8B72}, //2012 #CJK UNIFIED IDEOGRAPH + {0x8FF8, 0x91B8}, //2013 #CJK UNIFIED IDEOGRAPH + {0x8FF9, 0x9320}, //2014 #CJK UNIFIED IDEOGRAPH + {0x8FFA, 0x5631}, //2015 #CJK UNIFIED IDEOGRAPH + {0x8FFB, 0x57F4}, //2016 #CJK UNIFIED IDEOGRAPH + {0x8FFC, 0x98FE}, //2017 #CJK UNIFIED IDEOGRAPH + {0x9040, 0x62ED}, //2018 #CJK UNIFIED IDEOGRAPH + {0x9041, 0x690D}, //2019 #CJK UNIFIED IDEOGRAPH + {0x9042, 0x6B96}, //2020 #CJK UNIFIED IDEOGRAPH + {0x9043, 0x71ED}, //2021 #CJK UNIFIED IDEOGRAPH + {0x9044, 0x7E54}, //2022 #CJK UNIFIED IDEOGRAPH + {0x9045, 0x8077}, //2023 #CJK UNIFIED IDEOGRAPH + {0x9046, 0x8272}, //2024 #CJK UNIFIED IDEOGRAPH + {0x9047, 0x89E6}, //2025 #CJK UNIFIED IDEOGRAPH + {0x9048, 0x98DF}, //2026 #CJK UNIFIED IDEOGRAPH + {0x9049, 0x8755}, //2027 #CJK UNIFIED IDEOGRAPH + {0x904A, 0x8FB1}, //2028 #CJK UNIFIED IDEOGRAPH + {0x904B, 0x5C3B}, //2029 #CJK UNIFIED IDEOGRAPH + {0x904C, 0x4F38}, //2030 #CJK UNIFIED IDEOGRAPH + {0x904D, 0x4FE1}, //2031 #CJK UNIFIED IDEOGRAPH + {0x904E, 0x4FB5}, //2032 #CJK UNIFIED IDEOGRAPH + {0x904F, 0x5507}, //2033 #CJK UNIFIED IDEOGRAPH + {0x9050, 0x5A20}, //2034 #CJK UNIFIED IDEOGRAPH + {0x9051, 0x5BDD}, //2035 #CJK UNIFIED IDEOGRAPH + {0x9052, 0x5BE9}, //2036 #CJK UNIFIED IDEOGRAPH + {0x9053, 0x5FC3}, //2037 #CJK UNIFIED IDEOGRAPH + {0x9054, 0x614E}, //2038 #CJK UNIFIED IDEOGRAPH + {0x9055, 0x632F}, //2039 #CJK UNIFIED IDEOGRAPH + {0x9056, 0x65B0}, //2040 #CJK UNIFIED IDEOGRAPH + {0x9057, 0x664B}, //2041 #CJK UNIFIED IDEOGRAPH + {0x9058, 0x68EE}, //2042 #CJK UNIFIED IDEOGRAPH + {0x9059, 0x699B}, //2043 #CJK UNIFIED IDEOGRAPH + {0x905A, 0x6D78}, //2044 #CJK UNIFIED IDEOGRAPH + {0x905B, 0x6DF1}, //2045 #CJK UNIFIED IDEOGRAPH + {0x905C, 0x7533}, //2046 #CJK UNIFIED IDEOGRAPH + {0x905D, 0x75B9}, //2047 #CJK UNIFIED IDEOGRAPH + {0x905E, 0x771F}, //2048 #CJK UNIFIED IDEOGRAPH + {0x905F, 0x795E}, //2049 #CJK UNIFIED IDEOGRAPH + {0x9060, 0x79E6}, //2050 #CJK UNIFIED IDEOGRAPH + {0x9061, 0x7D33}, //2051 #CJK UNIFIED IDEOGRAPH + {0x9062, 0x81E3}, //2052 #CJK UNIFIED IDEOGRAPH + {0x9063, 0x82AF}, //2053 #CJK UNIFIED IDEOGRAPH + {0x9064, 0x85AA}, //2054 #CJK UNIFIED IDEOGRAPH + {0x9065, 0x89AA}, //2055 #CJK UNIFIED IDEOGRAPH + {0x9066, 0x8A3A}, //2056 #CJK UNIFIED IDEOGRAPH + {0x9067, 0x8EAB}, //2057 #CJK UNIFIED IDEOGRAPH + {0x9068, 0x8F9B}, //2058 #CJK UNIFIED IDEOGRAPH + {0x9069, 0x9032}, //2059 #CJK UNIFIED IDEOGRAPH + {0x906A, 0x91DD}, //2060 #CJK UNIFIED IDEOGRAPH + {0x906B, 0x9707}, //2061 #CJK UNIFIED IDEOGRAPH + {0x906C, 0x4EBA}, //2062 #CJK UNIFIED IDEOGRAPH + {0x906D, 0x4EC1}, //2063 #CJK UNIFIED IDEOGRAPH + {0x906E, 0x5203}, //2064 #CJK UNIFIED IDEOGRAPH + {0x906F, 0x5875}, //2065 #CJK UNIFIED IDEOGRAPH + {0x9070, 0x58EC}, //2066 #CJK UNIFIED IDEOGRAPH + {0x9071, 0x5C0B}, //2067 #CJK UNIFIED IDEOGRAPH + {0x9072, 0x751A}, //2068 #CJK UNIFIED IDEOGRAPH + {0x9073, 0x5C3D}, //2069 #CJK UNIFIED IDEOGRAPH + {0x9074, 0x814E}, //2070 #CJK UNIFIED IDEOGRAPH + {0x9075, 0x8A0A}, //2071 #CJK UNIFIED IDEOGRAPH + {0x9076, 0x8FC5}, //2072 #CJK UNIFIED IDEOGRAPH + {0x9077, 0x9663}, //2073 #CJK UNIFIED IDEOGRAPH + {0x9078, 0x976D}, //2074 #CJK UNIFIED IDEOGRAPH + {0x9079, 0x7B25}, //2075 #CJK UNIFIED IDEOGRAPH + {0x907A, 0x8ACF}, //2076 #CJK UNIFIED IDEOGRAPH + {0x907B, 0x9808}, //2077 #CJK UNIFIED IDEOGRAPH + {0x907C, 0x9162}, //2078 #CJK UNIFIED IDEOGRAPH + {0x907D, 0x56F3}, //2079 #CJK UNIFIED IDEOGRAPH + {0x907E, 0x53A8}, //2080 #CJK UNIFIED IDEOGRAPH + {0x9080, 0x9017}, //2081 #CJK UNIFIED IDEOGRAPH + {0x9081, 0x5439}, //2082 #CJK UNIFIED IDEOGRAPH + {0x9082, 0x5782}, //2083 #CJK UNIFIED IDEOGRAPH + {0x9083, 0x5E25}, //2084 #CJK UNIFIED IDEOGRAPH + {0x9084, 0x63A8}, //2085 #CJK UNIFIED IDEOGRAPH + {0x9085, 0x6C34}, //2086 #CJK UNIFIED IDEOGRAPH + {0x9086, 0x708A}, //2087 #CJK UNIFIED IDEOGRAPH + {0x9087, 0x7761}, //2088 #CJK UNIFIED IDEOGRAPH + {0x9088, 0x7C8B}, //2089 #CJK UNIFIED IDEOGRAPH + {0x9089, 0x7FE0}, //2090 #CJK UNIFIED IDEOGRAPH + {0x908A, 0x8870}, //2091 #CJK UNIFIED IDEOGRAPH + {0x908B, 0x9042}, //2092 #CJK UNIFIED IDEOGRAPH + {0x908C, 0x9154}, //2093 #CJK UNIFIED IDEOGRAPH + {0x908D, 0x9310}, //2094 #CJK UNIFIED IDEOGRAPH + {0x908E, 0x9318}, //2095 #CJK UNIFIED IDEOGRAPH + {0x908F, 0x968F}, //2096 #CJK UNIFIED IDEOGRAPH + {0x9090, 0x745E}, //2097 #CJK UNIFIED IDEOGRAPH + {0x9091, 0x9AC4}, //2098 #CJK UNIFIED IDEOGRAPH + {0x9092, 0x5D07}, //2099 #CJK UNIFIED IDEOGRAPH + {0x9093, 0x5D69}, //2100 #CJK UNIFIED IDEOGRAPH + {0x9094, 0x6570}, //2101 #CJK UNIFIED IDEOGRAPH + {0x9095, 0x67A2}, //2102 #CJK UNIFIED IDEOGRAPH + {0x9096, 0x8DA8}, //2103 #CJK UNIFIED IDEOGRAPH + {0x9097, 0x96DB}, //2104 #CJK UNIFIED IDEOGRAPH + {0x9098, 0x636E}, //2105 #CJK UNIFIED IDEOGRAPH + {0x9099, 0x6749}, //2106 #CJK UNIFIED IDEOGRAPH + {0x909A, 0x6919}, //2107 #CJK UNIFIED IDEOGRAPH + {0x909B, 0x83C5}, //2108 #CJK UNIFIED IDEOGRAPH + {0x909C, 0x9817}, //2109 #CJK UNIFIED IDEOGRAPH + {0x909D, 0x96C0}, //2110 #CJK UNIFIED IDEOGRAPH + {0x909E, 0x88FE}, //2111 #CJK UNIFIED IDEOGRAPH + {0x909F, 0x6F84}, //2112 #CJK UNIFIED IDEOGRAPH + {0x90A0, 0x647A}, //2113 #CJK UNIFIED IDEOGRAPH + {0x90A1, 0x5BF8}, //2114 #CJK UNIFIED IDEOGRAPH + {0x90A2, 0x4E16}, //2115 #CJK UNIFIED IDEOGRAPH + {0x90A3, 0x702C}, //2116 #CJK UNIFIED IDEOGRAPH + {0x90A4, 0x755D}, //2117 #CJK UNIFIED IDEOGRAPH + {0x90A5, 0x662F}, //2118 #CJK UNIFIED IDEOGRAPH + {0x90A6, 0x51C4}, //2119 #CJK UNIFIED IDEOGRAPH + {0x90A7, 0x5236}, //2120 #CJK UNIFIED IDEOGRAPH + {0x90A8, 0x52E2}, //2121 #CJK UNIFIED IDEOGRAPH + {0x90A9, 0x59D3}, //2122 #CJK UNIFIED IDEOGRAPH + {0x90AA, 0x5F81}, //2123 #CJK UNIFIED IDEOGRAPH + {0x90AB, 0x6027}, //2124 #CJK UNIFIED IDEOGRAPH + {0x90AC, 0x6210}, //2125 #CJK UNIFIED IDEOGRAPH + {0x90AD, 0x653F}, //2126 #CJK UNIFIED IDEOGRAPH + {0x90AE, 0x6574}, //2127 #CJK UNIFIED IDEOGRAPH + {0x90AF, 0x661F}, //2128 #CJK UNIFIED IDEOGRAPH + {0x90B0, 0x6674}, //2129 #CJK UNIFIED IDEOGRAPH + {0x90B1, 0x68F2}, //2130 #CJK UNIFIED IDEOGRAPH + {0x90B2, 0x6816}, //2131 #CJK UNIFIED IDEOGRAPH + {0x90B3, 0x6B63}, //2132 #CJK UNIFIED IDEOGRAPH + {0x90B4, 0x6E05}, //2133 #CJK UNIFIED IDEOGRAPH + {0x90B5, 0x7272}, //2134 #CJK UNIFIED IDEOGRAPH + {0x90B6, 0x751F}, //2135 #CJK UNIFIED IDEOGRAPH + {0x90B7, 0x76DB}, //2136 #CJK UNIFIED IDEOGRAPH + {0x90B8, 0x7CBE}, //2137 #CJK UNIFIED IDEOGRAPH + {0x90B9, 0x8056}, //2138 #CJK UNIFIED IDEOGRAPH + {0x90BA, 0x58F0}, //2139 #CJK UNIFIED IDEOGRAPH + {0x90BB, 0x88FD}, //2140 #CJK UNIFIED IDEOGRAPH + {0x90BC, 0x897F}, //2141 #CJK UNIFIED IDEOGRAPH + {0x90BD, 0x8AA0}, //2142 #CJK UNIFIED IDEOGRAPH + {0x90BE, 0x8A93}, //2143 #CJK UNIFIED IDEOGRAPH + {0x90BF, 0x8ACB}, //2144 #CJK UNIFIED IDEOGRAPH + {0x90C0, 0x901D}, //2145 #CJK UNIFIED IDEOGRAPH + {0x90C1, 0x9192}, //2146 #CJK UNIFIED IDEOGRAPH + {0x90C2, 0x9752}, //2147 #CJK UNIFIED IDEOGRAPH + {0x90C3, 0x9759}, //2148 #CJK UNIFIED IDEOGRAPH + {0x90C4, 0x6589}, //2149 #CJK UNIFIED IDEOGRAPH + {0x90C5, 0x7A0E}, //2150 #CJK UNIFIED IDEOGRAPH + {0x90C6, 0x8106}, //2151 #CJK UNIFIED IDEOGRAPH + {0x90C7, 0x96BB}, //2152 #CJK UNIFIED IDEOGRAPH + {0x90C8, 0x5E2D}, //2153 #CJK UNIFIED IDEOGRAPH + {0x90C9, 0x60DC}, //2154 #CJK UNIFIED IDEOGRAPH + {0x90CA, 0x621A}, //2155 #CJK UNIFIED IDEOGRAPH + {0x90CB, 0x65A5}, //2156 #CJK UNIFIED IDEOGRAPH + {0x90CC, 0x6614}, //2157 #CJK UNIFIED IDEOGRAPH + {0x90CD, 0x6790}, //2158 #CJK UNIFIED IDEOGRAPH + {0x90CE, 0x77F3}, //2159 #CJK UNIFIED IDEOGRAPH + {0x90CF, 0x7A4D}, //2160 #CJK UNIFIED IDEOGRAPH + {0x90D0, 0x7C4D}, //2161 #CJK UNIFIED IDEOGRAPH + {0x90D1, 0x7E3E}, //2162 #CJK UNIFIED IDEOGRAPH + {0x90D2, 0x810A}, //2163 #CJK UNIFIED IDEOGRAPH + {0x90D3, 0x8CAC}, //2164 #CJK UNIFIED IDEOGRAPH + {0x90D4, 0x8D64}, //2165 #CJK UNIFIED IDEOGRAPH + {0x90D5, 0x8DE1}, //2166 #CJK UNIFIED IDEOGRAPH + {0x90D6, 0x8E5F}, //2167 #CJK UNIFIED IDEOGRAPH + {0x90D7, 0x78A9}, //2168 #CJK UNIFIED IDEOGRAPH + {0x90D8, 0x5207}, //2169 #CJK UNIFIED IDEOGRAPH + {0x90D9, 0x62D9}, //2170 #CJK UNIFIED IDEOGRAPH + {0x90DA, 0x63A5}, //2171 #CJK UNIFIED IDEOGRAPH + {0x90DB, 0x6442}, //2172 #CJK UNIFIED IDEOGRAPH + {0x90DC, 0x6298}, //2173 #CJK UNIFIED IDEOGRAPH + {0x90DD, 0x8A2D}, //2174 #CJK UNIFIED IDEOGRAPH + {0x90DE, 0x7A83}, //2175 #CJK UNIFIED IDEOGRAPH + {0x90DF, 0x7BC0}, //2176 #CJK UNIFIED IDEOGRAPH + {0x90E0, 0x8AAC}, //2177 #CJK UNIFIED IDEOGRAPH + {0x90E1, 0x96EA}, //2178 #CJK UNIFIED IDEOGRAPH + {0x90E2, 0x7D76}, //2179 #CJK UNIFIED IDEOGRAPH + {0x90E3, 0x820C}, //2180 #CJK UNIFIED IDEOGRAPH + {0x90E4, 0x8749}, //2181 #CJK UNIFIED IDEOGRAPH + {0x90E5, 0x4ED9}, //2182 #CJK UNIFIED IDEOGRAPH + {0x90E6, 0x5148}, //2183 #CJK UNIFIED IDEOGRAPH + {0x90E7, 0x5343}, //2184 #CJK UNIFIED IDEOGRAPH + {0x90E8, 0x5360}, //2185 #CJK UNIFIED IDEOGRAPH + {0x90E9, 0x5BA3}, //2186 #CJK UNIFIED IDEOGRAPH + {0x90EA, 0x5C02}, //2187 #CJK UNIFIED IDEOGRAPH + {0x90EB, 0x5C16}, //2188 #CJK UNIFIED IDEOGRAPH + {0x90EC, 0x5DDD}, //2189 #CJK UNIFIED IDEOGRAPH + {0x90ED, 0x6226}, //2190 #CJK UNIFIED IDEOGRAPH + {0x90EE, 0x6247}, //2191 #CJK UNIFIED IDEOGRAPH + {0x90EF, 0x64B0}, //2192 #CJK UNIFIED IDEOGRAPH + {0x90F0, 0x6813}, //2193 #CJK UNIFIED IDEOGRAPH + {0x90F1, 0x6834}, //2194 #CJK UNIFIED IDEOGRAPH + {0x90F2, 0x6CC9}, //2195 #CJK UNIFIED IDEOGRAPH + {0x90F3, 0x6D45}, //2196 #CJK UNIFIED IDEOGRAPH + {0x90F4, 0x6D17}, //2197 #CJK UNIFIED IDEOGRAPH + {0x90F5, 0x67D3}, //2198 #CJK UNIFIED IDEOGRAPH + {0x90F6, 0x6F5C}, //2199 #CJK UNIFIED IDEOGRAPH + {0x90F7, 0x714E}, //2200 #CJK UNIFIED IDEOGRAPH + {0x90F8, 0x717D}, //2201 #CJK UNIFIED IDEOGRAPH + {0x90F9, 0x65CB}, //2202 #CJK UNIFIED IDEOGRAPH + {0x90FA, 0x7A7F}, //2203 #CJK UNIFIED IDEOGRAPH + {0x90FB, 0x7BAD}, //2204 #CJK UNIFIED IDEOGRAPH + {0x90FC, 0x7DDA}, //2205 #CJK UNIFIED IDEOGRAPH + {0x9140, 0x7E4A}, //2206 #CJK UNIFIED IDEOGRAPH + {0x9141, 0x7FA8}, //2207 #CJK UNIFIED IDEOGRAPH + {0x9142, 0x817A}, //2208 #CJK UNIFIED IDEOGRAPH + {0x9143, 0x821B}, //2209 #CJK UNIFIED IDEOGRAPH + {0x9144, 0x8239}, //2210 #CJK UNIFIED IDEOGRAPH + {0x9145, 0x85A6}, //2211 #CJK UNIFIED IDEOGRAPH + {0x9146, 0x8A6E}, //2212 #CJK UNIFIED IDEOGRAPH + {0x9147, 0x8CCE}, //2213 #CJK UNIFIED IDEOGRAPH + {0x9148, 0x8DF5}, //2214 #CJK UNIFIED IDEOGRAPH + {0x9149, 0x9078}, //2215 #CJK UNIFIED IDEOGRAPH + {0x914A, 0x9077}, //2216 #CJK UNIFIED IDEOGRAPH + {0x914B, 0x92AD}, //2217 #CJK UNIFIED IDEOGRAPH + {0x914C, 0x9291}, //2218 #CJK UNIFIED IDEOGRAPH + {0x914D, 0x9583}, //2219 #CJK UNIFIED IDEOGRAPH + {0x914E, 0x9BAE}, //2220 #CJK UNIFIED IDEOGRAPH + {0x914F, 0x524D}, //2221 #CJK UNIFIED IDEOGRAPH + {0x9150, 0x5584}, //2222 #CJK UNIFIED IDEOGRAPH + {0x9151, 0x6F38}, //2223 #CJK UNIFIED IDEOGRAPH + {0x9152, 0x7136}, //2224 #CJK UNIFIED IDEOGRAPH + {0x9153, 0x5168}, //2225 #CJK UNIFIED IDEOGRAPH + {0x9154, 0x7985}, //2226 #CJK UNIFIED IDEOGRAPH + {0x9155, 0x7E55}, //2227 #CJK UNIFIED IDEOGRAPH + {0x9156, 0x81B3}, //2228 #CJK UNIFIED IDEOGRAPH + {0x9157, 0x7CCE}, //2229 #CJK UNIFIED IDEOGRAPH + {0x9158, 0x564C}, //2230 #CJK UNIFIED IDEOGRAPH + {0x9159, 0x5851}, //2231 #CJK UNIFIED IDEOGRAPH + {0x915A, 0x5CA8}, //2232 #CJK UNIFIED IDEOGRAPH + {0x915B, 0x63AA}, //2233 #CJK UNIFIED IDEOGRAPH + {0x915C, 0x66FE}, //2234 #CJK UNIFIED IDEOGRAPH + {0x915D, 0x66FD}, //2235 #CJK UNIFIED IDEOGRAPH + {0x915E, 0x695A}, //2236 #CJK UNIFIED IDEOGRAPH + {0x915F, 0x72D9}, //2237 #CJK UNIFIED IDEOGRAPH + {0x9160, 0x758F}, //2238 #CJK UNIFIED IDEOGRAPH + {0x9161, 0x758E}, //2239 #CJK UNIFIED IDEOGRAPH + {0x9162, 0x790E}, //2240 #CJK UNIFIED IDEOGRAPH + {0x9163, 0x7956}, //2241 #CJK UNIFIED IDEOGRAPH + {0x9164, 0x79DF}, //2242 #CJK UNIFIED IDEOGRAPH + {0x9165, 0x7C97}, //2243 #CJK UNIFIED IDEOGRAPH + {0x9166, 0x7D20}, //2244 #CJK UNIFIED IDEOGRAPH + {0x9167, 0x7D44}, //2245 #CJK UNIFIED IDEOGRAPH + {0x9168, 0x8607}, //2246 #CJK UNIFIED IDEOGRAPH + {0x9169, 0x8A34}, //2247 #CJK UNIFIED IDEOGRAPH + {0x916A, 0x963B}, //2248 #CJK UNIFIED IDEOGRAPH + {0x916B, 0x9061}, //2249 #CJK UNIFIED IDEOGRAPH + {0x916C, 0x9F20}, //2250 #CJK UNIFIED IDEOGRAPH + {0x916D, 0x50E7}, //2251 #CJK UNIFIED IDEOGRAPH + {0x916E, 0x5275}, //2252 #CJK UNIFIED IDEOGRAPH + {0x916F, 0x53CC}, //2253 #CJK UNIFIED IDEOGRAPH + {0x9170, 0x53E2}, //2254 #CJK UNIFIED IDEOGRAPH + {0x9171, 0x5009}, //2255 #CJK UNIFIED IDEOGRAPH + {0x9172, 0x55AA}, //2256 #CJK UNIFIED IDEOGRAPH + {0x9173, 0x58EE}, //2257 #CJK UNIFIED IDEOGRAPH + {0x9174, 0x594F}, //2258 #CJK UNIFIED IDEOGRAPH + {0x9175, 0x723D}, //2259 #CJK UNIFIED IDEOGRAPH + {0x9176, 0x5B8B}, //2260 #CJK UNIFIED IDEOGRAPH + {0x9177, 0x5C64}, //2261 #CJK UNIFIED IDEOGRAPH + {0x9178, 0x531D}, //2262 #CJK UNIFIED IDEOGRAPH + {0x9179, 0x60E3}, //2263 #CJK UNIFIED IDEOGRAPH + {0x917A, 0x60F3}, //2264 #CJK UNIFIED IDEOGRAPH + {0x917B, 0x635C}, //2265 #CJK UNIFIED IDEOGRAPH + {0x917C, 0x6383}, //2266 #CJK UNIFIED IDEOGRAPH + {0x917D, 0x633F}, //2267 #CJK UNIFIED IDEOGRAPH + {0x917E, 0x63BB}, //2268 #CJK UNIFIED IDEOGRAPH + {0x9180, 0x64CD}, //2269 #CJK UNIFIED IDEOGRAPH + {0x9181, 0x65E9}, //2270 #CJK UNIFIED IDEOGRAPH + {0x9182, 0x66F9}, //2271 #CJK UNIFIED IDEOGRAPH + {0x9183, 0x5DE3}, //2272 #CJK UNIFIED IDEOGRAPH + {0x9184, 0x69CD}, //2273 #CJK UNIFIED IDEOGRAPH + {0x9185, 0x69FD}, //2274 #CJK UNIFIED IDEOGRAPH + {0x9186, 0x6F15}, //2275 #CJK UNIFIED IDEOGRAPH + {0x9187, 0x71E5}, //2276 #CJK UNIFIED IDEOGRAPH + {0x9188, 0x4E89}, //2277 #CJK UNIFIED IDEOGRAPH + {0x9189, 0x75E9}, //2278 #CJK UNIFIED IDEOGRAPH + {0x918A, 0x76F8}, //2279 #CJK UNIFIED IDEOGRAPH + {0x918B, 0x7A93}, //2280 #CJK UNIFIED IDEOGRAPH + {0x918C, 0x7CDF}, //2281 #CJK UNIFIED IDEOGRAPH + {0x918D, 0x7DCF}, //2282 #CJK UNIFIED IDEOGRAPH + {0x918E, 0x7D9C}, //2283 #CJK UNIFIED IDEOGRAPH + {0x918F, 0x8061}, //2284 #CJK UNIFIED IDEOGRAPH + {0x9190, 0x8349}, //2285 #CJK UNIFIED IDEOGRAPH + {0x9191, 0x8358}, //2286 #CJK UNIFIED IDEOGRAPH + {0x9192, 0x846C}, //2287 #CJK UNIFIED IDEOGRAPH + {0x9193, 0x84BC}, //2288 #CJK UNIFIED IDEOGRAPH + {0x9194, 0x85FB}, //2289 #CJK UNIFIED IDEOGRAPH + {0x9195, 0x88C5}, //2290 #CJK UNIFIED IDEOGRAPH + {0x9196, 0x8D70}, //2291 #CJK UNIFIED IDEOGRAPH + {0x9197, 0x9001}, //2292 #CJK UNIFIED IDEOGRAPH + {0x9198, 0x906D}, //2293 #CJK UNIFIED IDEOGRAPH + {0x9199, 0x9397}, //2294 #CJK UNIFIED IDEOGRAPH + {0x919A, 0x971C}, //2295 #CJK UNIFIED IDEOGRAPH + {0x919B, 0x9A12}, //2296 #CJK UNIFIED IDEOGRAPH + {0x919C, 0x50CF}, //2297 #CJK UNIFIED IDEOGRAPH + {0x919D, 0x5897}, //2298 #CJK UNIFIED IDEOGRAPH + {0x919E, 0x618E}, //2299 #CJK UNIFIED IDEOGRAPH + {0x919F, 0x81D3}, //2300 #CJK UNIFIED IDEOGRAPH + {0x91A0, 0x8535}, //2301 #CJK UNIFIED IDEOGRAPH + {0x91A1, 0x8D08}, //2302 #CJK UNIFIED IDEOGRAPH + {0x91A2, 0x9020}, //2303 #CJK UNIFIED IDEOGRAPH + {0x91A3, 0x4FC3}, //2304 #CJK UNIFIED IDEOGRAPH + {0x91A4, 0x5074}, //2305 #CJK UNIFIED IDEOGRAPH + {0x91A5, 0x5247}, //2306 #CJK UNIFIED IDEOGRAPH + {0x91A6, 0x5373}, //2307 #CJK UNIFIED IDEOGRAPH + {0x91A7, 0x606F}, //2308 #CJK UNIFIED IDEOGRAPH + {0x91A8, 0x6349}, //2309 #CJK UNIFIED IDEOGRAPH + {0x91A9, 0x675F}, //2310 #CJK UNIFIED IDEOGRAPH + {0x91AA, 0x6E2C}, //2311 #CJK UNIFIED IDEOGRAPH + {0x91AB, 0x8DB3}, //2312 #CJK UNIFIED IDEOGRAPH + {0x91AC, 0x901F}, //2313 #CJK UNIFIED IDEOGRAPH + {0x91AD, 0x4FD7}, //2314 #CJK UNIFIED IDEOGRAPH + {0x91AE, 0x5C5E}, //2315 #CJK UNIFIED IDEOGRAPH + {0x91AF, 0x8CCA}, //2316 #CJK UNIFIED IDEOGRAPH + {0x91B0, 0x65CF}, //2317 #CJK UNIFIED IDEOGRAPH + {0x91B1, 0x7D9A}, //2318 #CJK UNIFIED IDEOGRAPH + {0x91B2, 0x5352}, //2319 #CJK UNIFIED IDEOGRAPH + {0x91B3, 0x8896}, //2320 #CJK UNIFIED IDEOGRAPH + {0x91B4, 0x5176}, //2321 #CJK UNIFIED IDEOGRAPH + {0x91B5, 0x63C3}, //2322 #CJK UNIFIED IDEOGRAPH + {0x91B6, 0x5B58}, //2323 #CJK UNIFIED IDEOGRAPH + {0x91B7, 0x5B6B}, //2324 #CJK UNIFIED IDEOGRAPH + {0x91B8, 0x5C0A}, //2325 #CJK UNIFIED IDEOGRAPH + {0x91B9, 0x640D}, //2326 #CJK UNIFIED IDEOGRAPH + {0x91BA, 0x6751}, //2327 #CJK UNIFIED IDEOGRAPH + {0x91BB, 0x905C}, //2328 #CJK UNIFIED IDEOGRAPH + {0x91BC, 0x4ED6}, //2329 #CJK UNIFIED IDEOGRAPH + {0x91BD, 0x591A}, //2330 #CJK UNIFIED IDEOGRAPH + {0x91BE, 0x592A}, //2331 #CJK UNIFIED IDEOGRAPH + {0x91BF, 0x6C70}, //2332 #CJK UNIFIED IDEOGRAPH + {0x91C0, 0x8A51}, //2333 #CJK UNIFIED IDEOGRAPH + {0x91C1, 0x553E}, //2334 #CJK UNIFIED IDEOGRAPH + {0x91C2, 0x5815}, //2335 #CJK UNIFIED IDEOGRAPH + {0x91C3, 0x59A5}, //2336 #CJK UNIFIED IDEOGRAPH + {0x91C4, 0x60F0}, //2337 #CJK UNIFIED IDEOGRAPH + {0x91C5, 0x6253}, //2338 #CJK UNIFIED IDEOGRAPH + {0x91C6, 0x67C1}, //2339 #CJK UNIFIED IDEOGRAPH + {0x91C7, 0x8235}, //2340 #CJK UNIFIED IDEOGRAPH + {0x91C8, 0x6955}, //2341 #CJK UNIFIED IDEOGRAPH + {0x91C9, 0x9640}, //2342 #CJK UNIFIED IDEOGRAPH + {0x91CA, 0x99C4}, //2343 #CJK UNIFIED IDEOGRAPH + {0x91CB, 0x9A28}, //2344 #CJK UNIFIED IDEOGRAPH + {0x91CC, 0x4F53}, //2345 #CJK UNIFIED IDEOGRAPH + {0x91CD, 0x5806}, //2346 #CJK UNIFIED IDEOGRAPH + {0x91CE, 0x5BFE}, //2347 #CJK UNIFIED IDEOGRAPH + {0x91CF, 0x8010}, //2348 #CJK UNIFIED IDEOGRAPH + {0x91D0, 0x5CB1}, //2349 #CJK UNIFIED IDEOGRAPH + {0x91D1, 0x5E2F}, //2350 #CJK UNIFIED IDEOGRAPH + {0x91D2, 0x5F85}, //2351 #CJK UNIFIED IDEOGRAPH + {0x91D3, 0x6020}, //2352 #CJK UNIFIED IDEOGRAPH + {0x91D4, 0x614B}, //2353 #CJK UNIFIED IDEOGRAPH + {0x91D5, 0x6234}, //2354 #CJK UNIFIED IDEOGRAPH + {0x91D6, 0x66FF}, //2355 #CJK UNIFIED IDEOGRAPH + {0x91D7, 0x6CF0}, //2356 #CJK UNIFIED IDEOGRAPH + {0x91D8, 0x6EDE}, //2357 #CJK UNIFIED IDEOGRAPH + {0x91D9, 0x80CE}, //2358 #CJK UNIFIED IDEOGRAPH + {0x91DA, 0x817F}, //2359 #CJK UNIFIED IDEOGRAPH + {0x91DB, 0x82D4}, //2360 #CJK UNIFIED IDEOGRAPH + {0x91DC, 0x888B}, //2361 #CJK UNIFIED IDEOGRAPH + {0x91DD, 0x8CB8}, //2362 #CJK UNIFIED IDEOGRAPH + {0x91DE, 0x9000}, //2363 #CJK UNIFIED IDEOGRAPH + {0x91DF, 0x902E}, //2364 #CJK UNIFIED IDEOGRAPH + {0x91E0, 0x968A}, //2365 #CJK UNIFIED IDEOGRAPH + {0x91E1, 0x9EDB}, //2366 #CJK UNIFIED IDEOGRAPH + {0x91E2, 0x9BDB}, //2367 #CJK UNIFIED IDEOGRAPH + {0x91E3, 0x4EE3}, //2368 #CJK UNIFIED IDEOGRAPH + {0x91E4, 0x53F0}, //2369 #CJK UNIFIED IDEOGRAPH + {0x91E5, 0x5927}, //2370 #CJK UNIFIED IDEOGRAPH + {0x91E6, 0x7B2C}, //2371 #CJK UNIFIED IDEOGRAPH + {0x91E7, 0x918D}, //2372 #CJK UNIFIED IDEOGRAPH + {0x91E8, 0x984C}, //2373 #CJK UNIFIED IDEOGRAPH + {0x91E9, 0x9DF9}, //2374 #CJK UNIFIED IDEOGRAPH + {0x91EA, 0x6EDD}, //2375 #CJK UNIFIED IDEOGRAPH + {0x91EB, 0x7027}, //2376 #CJK UNIFIED IDEOGRAPH + {0x91EC, 0x5353}, //2377 #CJK UNIFIED IDEOGRAPH + {0x91ED, 0x5544}, //2378 #CJK UNIFIED IDEOGRAPH + {0x91EE, 0x5B85}, //2379 #CJK UNIFIED IDEOGRAPH + {0x91EF, 0x6258}, //2380 #CJK UNIFIED IDEOGRAPH + {0x91F0, 0x629E}, //2381 #CJK UNIFIED IDEOGRAPH + {0x91F1, 0x62D3}, //2382 #CJK UNIFIED IDEOGRAPH + {0x91F2, 0x6CA2}, //2383 #CJK UNIFIED IDEOGRAPH + {0x91F3, 0x6FEF}, //2384 #CJK UNIFIED IDEOGRAPH + {0x91F4, 0x7422}, //2385 #CJK UNIFIED IDEOGRAPH + {0x91F5, 0x8A17}, //2386 #CJK UNIFIED IDEOGRAPH + {0x91F6, 0x9438}, //2387 #CJK UNIFIED IDEOGRAPH + {0x91F7, 0x6FC1}, //2388 #CJK UNIFIED IDEOGRAPH + {0x91F8, 0x8AFE}, //2389 #CJK UNIFIED IDEOGRAPH + {0x91F9, 0x8338}, //2390 #CJK UNIFIED IDEOGRAPH + {0x91FA, 0x51E7}, //2391 #CJK UNIFIED IDEOGRAPH + {0x91FB, 0x86F8}, //2392 #CJK UNIFIED IDEOGRAPH + {0x91FC, 0x53EA}, //2393 #CJK UNIFIED IDEOGRAPH + {0x9240, 0x53E9}, //2394 #CJK UNIFIED IDEOGRAPH + {0x9241, 0x4F46}, //2395 #CJK UNIFIED IDEOGRAPH + {0x9242, 0x9054}, //2396 #CJK UNIFIED IDEOGRAPH + {0x9243, 0x8FB0}, //2397 #CJK UNIFIED IDEOGRAPH + {0x9244, 0x596A}, //2398 #CJK UNIFIED IDEOGRAPH + {0x9245, 0x8131}, //2399 #CJK UNIFIED IDEOGRAPH + {0x9246, 0x5DFD}, //2400 #CJK UNIFIED IDEOGRAPH + {0x9247, 0x7AEA}, //2401 #CJK UNIFIED IDEOGRAPH + {0x9248, 0x8FBF}, //2402 #CJK UNIFIED IDEOGRAPH + {0x9249, 0x68DA}, //2403 #CJK UNIFIED IDEOGRAPH + {0x924A, 0x8C37}, //2404 #CJK UNIFIED IDEOGRAPH + {0x924B, 0x72F8}, //2405 #CJK UNIFIED IDEOGRAPH + {0x924C, 0x9C48}, //2406 #CJK UNIFIED IDEOGRAPH + {0x924D, 0x6A3D}, //2407 #CJK UNIFIED IDEOGRAPH + {0x924E, 0x8AB0}, //2408 #CJK UNIFIED IDEOGRAPH + {0x924F, 0x4E39}, //2409 #CJK UNIFIED IDEOGRAPH + {0x9250, 0x5358}, //2410 #CJK UNIFIED IDEOGRAPH + {0x9251, 0x5606}, //2411 #CJK UNIFIED IDEOGRAPH + {0x9252, 0x5766}, //2412 #CJK UNIFIED IDEOGRAPH + {0x9253, 0x62C5}, //2413 #CJK UNIFIED IDEOGRAPH + {0x9254, 0x63A2}, //2414 #CJK UNIFIED IDEOGRAPH + {0x9255, 0x65E6}, //2415 #CJK UNIFIED IDEOGRAPH + {0x9256, 0x6B4E}, //2416 #CJK UNIFIED IDEOGRAPH + {0x9257, 0x6DE1}, //2417 #CJK UNIFIED IDEOGRAPH + {0x9258, 0x6E5B}, //2418 #CJK UNIFIED IDEOGRAPH + {0x9259, 0x70AD}, //2419 #CJK UNIFIED IDEOGRAPH + {0x925A, 0x77ED}, //2420 #CJK UNIFIED IDEOGRAPH + {0x925B, 0x7AEF}, //2421 #CJK UNIFIED IDEOGRAPH + {0x925C, 0x7BAA}, //2422 #CJK UNIFIED IDEOGRAPH + {0x925D, 0x7DBB}, //2423 #CJK UNIFIED IDEOGRAPH + {0x925E, 0x803D}, //2424 #CJK UNIFIED IDEOGRAPH + {0x925F, 0x80C6}, //2425 #CJK UNIFIED IDEOGRAPH + {0x9260, 0x86CB}, //2426 #CJK UNIFIED IDEOGRAPH + {0x9261, 0x8A95}, //2427 #CJK UNIFIED IDEOGRAPH + {0x9262, 0x935B}, //2428 #CJK UNIFIED IDEOGRAPH + {0x9263, 0x56E3}, //2429 #CJK UNIFIED IDEOGRAPH + {0x9264, 0x58C7}, //2430 #CJK UNIFIED IDEOGRAPH + {0x9265, 0x5F3E}, //2431 #CJK UNIFIED IDEOGRAPH + {0x9266, 0x65AD}, //2432 #CJK UNIFIED IDEOGRAPH + {0x9267, 0x6696}, //2433 #CJK UNIFIED IDEOGRAPH + {0x9268, 0x6A80}, //2434 #CJK UNIFIED IDEOGRAPH + {0x9269, 0x6BB5}, //2435 #CJK UNIFIED IDEOGRAPH + {0x926A, 0x7537}, //2436 #CJK UNIFIED IDEOGRAPH + {0x926B, 0x8AC7}, //2437 #CJK UNIFIED IDEOGRAPH + {0x926C, 0x5024}, //2438 #CJK UNIFIED IDEOGRAPH + {0x926D, 0x77E5}, //2439 #CJK UNIFIED IDEOGRAPH + {0x926E, 0x5730}, //2440 #CJK UNIFIED IDEOGRAPH + {0x926F, 0x5F1B}, //2441 #CJK UNIFIED IDEOGRAPH + {0x9270, 0x6065}, //2442 #CJK UNIFIED IDEOGRAPH + {0x9271, 0x667A}, //2443 #CJK UNIFIED IDEOGRAPH + {0x9272, 0x6C60}, //2444 #CJK UNIFIED IDEOGRAPH + {0x9273, 0x75F4}, //2445 #CJK UNIFIED IDEOGRAPH + {0x9274, 0x7A1A}, //2446 #CJK UNIFIED IDEOGRAPH + {0x9275, 0x7F6E}, //2447 #CJK UNIFIED IDEOGRAPH + {0x9276, 0x81F4}, //2448 #CJK UNIFIED IDEOGRAPH + {0x9277, 0x8718}, //2449 #CJK UNIFIED IDEOGRAPH + {0x9278, 0x9045}, //2450 #CJK UNIFIED IDEOGRAPH + {0x9279, 0x99B3}, //2451 #CJK UNIFIED IDEOGRAPH + {0x927A, 0x7BC9}, //2452 #CJK UNIFIED IDEOGRAPH + {0x927B, 0x755C}, //2453 #CJK UNIFIED IDEOGRAPH + {0x927C, 0x7AF9}, //2454 #CJK UNIFIED IDEOGRAPH + {0x927D, 0x7B51}, //2455 #CJK UNIFIED IDEOGRAPH + {0x927E, 0x84C4}, //2456 #CJK UNIFIED IDEOGRAPH + {0x9280, 0x9010}, //2457 #CJK UNIFIED IDEOGRAPH + {0x9281, 0x79E9}, //2458 #CJK UNIFIED IDEOGRAPH + {0x9282, 0x7A92}, //2459 #CJK UNIFIED IDEOGRAPH + {0x9283, 0x8336}, //2460 #CJK UNIFIED IDEOGRAPH + {0x9284, 0x5AE1}, //2461 #CJK UNIFIED IDEOGRAPH + {0x9285, 0x7740}, //2462 #CJK UNIFIED IDEOGRAPH + {0x9286, 0x4E2D}, //2463 #CJK UNIFIED IDEOGRAPH + {0x9287, 0x4EF2}, //2464 #CJK UNIFIED IDEOGRAPH + {0x9288, 0x5B99}, //2465 #CJK UNIFIED IDEOGRAPH + {0x9289, 0x5FE0}, //2466 #CJK UNIFIED IDEOGRAPH + {0x928A, 0x62BD}, //2467 #CJK UNIFIED IDEOGRAPH + {0x928B, 0x663C}, //2468 #CJK UNIFIED IDEOGRAPH + {0x928C, 0x67F1}, //2469 #CJK UNIFIED IDEOGRAPH + {0x928D, 0x6CE8}, //2470 #CJK UNIFIED IDEOGRAPH + {0x928E, 0x866B}, //2471 #CJK UNIFIED IDEOGRAPH + {0x928F, 0x8877}, //2472 #CJK UNIFIED IDEOGRAPH + {0x9290, 0x8A3B}, //2473 #CJK UNIFIED IDEOGRAPH + {0x9291, 0x914E}, //2474 #CJK UNIFIED IDEOGRAPH + {0x9292, 0x92F3}, //2475 #CJK UNIFIED IDEOGRAPH + {0x9293, 0x99D0}, //2476 #CJK UNIFIED IDEOGRAPH + {0x9294, 0x6A17}, //2477 #CJK UNIFIED IDEOGRAPH + {0x9295, 0x7026}, //2478 #CJK UNIFIED IDEOGRAPH + {0x9296, 0x732A}, //2479 #CJK UNIFIED IDEOGRAPH + {0x9297, 0x82E7}, //2480 #CJK UNIFIED IDEOGRAPH + {0x9298, 0x8457}, //2481 #CJK UNIFIED IDEOGRAPH + {0x9299, 0x8CAF}, //2482 #CJK UNIFIED IDEOGRAPH + {0x929A, 0x4E01}, //2483 #CJK UNIFIED IDEOGRAPH + {0x929B, 0x5146}, //2484 #CJK UNIFIED IDEOGRAPH + {0x929C, 0x51CB}, //2485 #CJK UNIFIED IDEOGRAPH + {0x929D, 0x558B}, //2486 #CJK UNIFIED IDEOGRAPH + {0x929E, 0x5BF5}, //2487 #CJK UNIFIED IDEOGRAPH + {0x929F, 0x5E16}, //2488 #CJK UNIFIED IDEOGRAPH + {0x92A0, 0x5E33}, //2489 #CJK UNIFIED IDEOGRAPH + {0x92A1, 0x5E81}, //2490 #CJK UNIFIED IDEOGRAPH + {0x92A2, 0x5F14}, //2491 #CJK UNIFIED IDEOGRAPH + {0x92A3, 0x5F35}, //2492 #CJK UNIFIED IDEOGRAPH + {0x92A4, 0x5F6B}, //2493 #CJK UNIFIED IDEOGRAPH + {0x92A5, 0x5FB4}, //2494 #CJK UNIFIED IDEOGRAPH + {0x92A6, 0x61F2}, //2495 #CJK UNIFIED IDEOGRAPH + {0x92A7, 0x6311}, //2496 #CJK UNIFIED IDEOGRAPH + {0x92A8, 0x66A2}, //2497 #CJK UNIFIED IDEOGRAPH + {0x92A9, 0x671D}, //2498 #CJK UNIFIED IDEOGRAPH + {0x92AA, 0x6F6E}, //2499 #CJK UNIFIED IDEOGRAPH + {0x92AB, 0x7252}, //2500 #CJK UNIFIED IDEOGRAPH + {0x92AC, 0x753A}, //2501 #CJK UNIFIED IDEOGRAPH + {0x92AD, 0x773A}, //2502 #CJK UNIFIED IDEOGRAPH + {0x92AE, 0x8074}, //2503 #CJK UNIFIED IDEOGRAPH + {0x92AF, 0x8139}, //2504 #CJK UNIFIED IDEOGRAPH + {0x92B0, 0x8178}, //2505 #CJK UNIFIED IDEOGRAPH + {0x92B1, 0x8776}, //2506 #CJK UNIFIED IDEOGRAPH + {0x92B2, 0x8ABF}, //2507 #CJK UNIFIED IDEOGRAPH + {0x92B3, 0x8ADC}, //2508 #CJK UNIFIED IDEOGRAPH + {0x92B4, 0x8D85}, //2509 #CJK UNIFIED IDEOGRAPH + {0x92B5, 0x8DF3}, //2510 #CJK UNIFIED IDEOGRAPH + {0x92B6, 0x929A}, //2511 #CJK UNIFIED IDEOGRAPH + {0x92B7, 0x9577}, //2512 #CJK UNIFIED IDEOGRAPH + {0x92B8, 0x9802}, //2513 #CJK UNIFIED IDEOGRAPH + {0x92B9, 0x9CE5}, //2514 #CJK UNIFIED IDEOGRAPH + {0x92BA, 0x52C5}, //2515 #CJK UNIFIED IDEOGRAPH + {0x92BB, 0x6357}, //2516 #CJK UNIFIED IDEOGRAPH + {0x92BC, 0x76F4}, //2517 #CJK UNIFIED IDEOGRAPH + {0x92BD, 0x6715}, //2518 #CJK UNIFIED IDEOGRAPH + {0x92BE, 0x6C88}, //2519 #CJK UNIFIED IDEOGRAPH + {0x92BF, 0x73CD}, //2520 #CJK UNIFIED IDEOGRAPH + {0x92C0, 0x8CC3}, //2521 #CJK UNIFIED IDEOGRAPH + {0x92C1, 0x93AE}, //2522 #CJK UNIFIED IDEOGRAPH + {0x92C2, 0x9673}, //2523 #CJK UNIFIED IDEOGRAPH + {0x92C3, 0x6D25}, //2524 #CJK UNIFIED IDEOGRAPH + {0x92C4, 0x589C}, //2525 #CJK UNIFIED IDEOGRAPH + {0x92C5, 0x690E}, //2526 #CJK UNIFIED IDEOGRAPH + {0x92C6, 0x69CC}, //2527 #CJK UNIFIED IDEOGRAPH + {0x92C7, 0x8FFD}, //2528 #CJK UNIFIED IDEOGRAPH + {0x92C8, 0x939A}, //2529 #CJK UNIFIED IDEOGRAPH + {0x92C9, 0x75DB}, //2530 #CJK UNIFIED IDEOGRAPH + {0x92CA, 0x901A}, //2531 #CJK UNIFIED IDEOGRAPH + {0x92CB, 0x585A}, //2532 #CJK UNIFIED IDEOGRAPH + {0x92CC, 0x6802}, //2533 #CJK UNIFIED IDEOGRAPH + {0x92CD, 0x63B4}, //2534 #CJK UNIFIED IDEOGRAPH + {0x92CE, 0x69FB}, //2535 #CJK UNIFIED IDEOGRAPH + {0x92CF, 0x4F43}, //2536 #CJK UNIFIED IDEOGRAPH + {0x92D0, 0x6F2C}, //2537 #CJK UNIFIED IDEOGRAPH + {0x92D1, 0x67D8}, //2538 #CJK UNIFIED IDEOGRAPH + {0x92D2, 0x8FBB}, //2539 #CJK UNIFIED IDEOGRAPH + {0x92D3, 0x8526}, //2540 #CJK UNIFIED IDEOGRAPH + {0x92D4, 0x7DB4}, //2541 #CJK UNIFIED IDEOGRAPH + {0x92D5, 0x9354}, //2542 #CJK UNIFIED IDEOGRAPH + {0x92D6, 0x693F}, //2543 #CJK UNIFIED IDEOGRAPH + {0x92D7, 0x6F70}, //2544 #CJK UNIFIED IDEOGRAPH + {0x92D8, 0x576A}, //2545 #CJK UNIFIED IDEOGRAPH + {0x92D9, 0x58F7}, //2546 #CJK UNIFIED IDEOGRAPH + {0x92DA, 0x5B2C}, //2547 #CJK UNIFIED IDEOGRAPH + {0x92DB, 0x7D2C}, //2548 #CJK UNIFIED IDEOGRAPH + {0x92DC, 0x722A}, //2549 #CJK UNIFIED IDEOGRAPH + {0x92DD, 0x540A}, //2550 #CJK UNIFIED IDEOGRAPH + {0x92DE, 0x91E3}, //2551 #CJK UNIFIED IDEOGRAPH + {0x92DF, 0x9DB4}, //2552 #CJK UNIFIED IDEOGRAPH + {0x92E0, 0x4EAD}, //2553 #CJK UNIFIED IDEOGRAPH + {0x92E1, 0x4F4E}, //2554 #CJK UNIFIED IDEOGRAPH + {0x92E2, 0x505C}, //2555 #CJK UNIFIED IDEOGRAPH + {0x92E3, 0x5075}, //2556 #CJK UNIFIED IDEOGRAPH + {0x92E4, 0x5243}, //2557 #CJK UNIFIED IDEOGRAPH + {0x92E5, 0x8C9E}, //2558 #CJK UNIFIED IDEOGRAPH + {0x92E6, 0x5448}, //2559 #CJK UNIFIED IDEOGRAPH + {0x92E7, 0x5824}, //2560 #CJK UNIFIED IDEOGRAPH + {0x92E8, 0x5B9A}, //2561 #CJK UNIFIED IDEOGRAPH + {0x92E9, 0x5E1D}, //2562 #CJK UNIFIED IDEOGRAPH + {0x92EA, 0x5E95}, //2563 #CJK UNIFIED IDEOGRAPH + {0x92EB, 0x5EAD}, //2564 #CJK UNIFIED IDEOGRAPH + {0x92EC, 0x5EF7}, //2565 #CJK UNIFIED IDEOGRAPH + {0x92ED, 0x5F1F}, //2566 #CJK UNIFIED IDEOGRAPH + {0x92EE, 0x608C}, //2567 #CJK UNIFIED IDEOGRAPH + {0x92EF, 0x62B5}, //2568 #CJK UNIFIED IDEOGRAPH + {0x92F0, 0x633A}, //2569 #CJK UNIFIED IDEOGRAPH + {0x92F1, 0x63D0}, //2570 #CJK UNIFIED IDEOGRAPH + {0x92F2, 0x68AF}, //2571 #CJK UNIFIED IDEOGRAPH + {0x92F3, 0x6C40}, //2572 #CJK UNIFIED IDEOGRAPH + {0x92F4, 0x7887}, //2573 #CJK UNIFIED IDEOGRAPH + {0x92F5, 0x798E}, //2574 #CJK UNIFIED IDEOGRAPH + {0x92F6, 0x7A0B}, //2575 #CJK UNIFIED IDEOGRAPH + {0x92F7, 0x7DE0}, //2576 #CJK UNIFIED IDEOGRAPH + {0x92F8, 0x8247}, //2577 #CJK UNIFIED IDEOGRAPH + {0x92F9, 0x8A02}, //2578 #CJK UNIFIED IDEOGRAPH + {0x92FA, 0x8AE6}, //2579 #CJK UNIFIED IDEOGRAPH + {0x92FB, 0x8E44}, //2580 #CJK UNIFIED IDEOGRAPH + {0x92FC, 0x9013}, //2581 #CJK UNIFIED IDEOGRAPH + {0x9340, 0x90B8}, //2582 #CJK UNIFIED IDEOGRAPH + {0x9341, 0x912D}, //2583 #CJK UNIFIED IDEOGRAPH + {0x9342, 0x91D8}, //2584 #CJK UNIFIED IDEOGRAPH + {0x9343, 0x9F0E}, //2585 #CJK UNIFIED IDEOGRAPH + {0x9344, 0x6CE5}, //2586 #CJK UNIFIED IDEOGRAPH + {0x9345, 0x6458}, //2587 #CJK UNIFIED IDEOGRAPH + {0x9346, 0x64E2}, //2588 #CJK UNIFIED IDEOGRAPH + {0x9347, 0x6575}, //2589 #CJK UNIFIED IDEOGRAPH + {0x9348, 0x6EF4}, //2590 #CJK UNIFIED IDEOGRAPH + {0x9349, 0x7684}, //2591 #CJK UNIFIED IDEOGRAPH + {0x934A, 0x7B1B}, //2592 #CJK UNIFIED IDEOGRAPH + {0x934B, 0x9069}, //2593 #CJK UNIFIED IDEOGRAPH + {0x934C, 0x93D1}, //2594 #CJK UNIFIED IDEOGRAPH + {0x934D, 0x6EBA}, //2595 #CJK UNIFIED IDEOGRAPH + {0x934E, 0x54F2}, //2596 #CJK UNIFIED IDEOGRAPH + {0x934F, 0x5FB9}, //2597 #CJK UNIFIED IDEOGRAPH + {0x9350, 0x64A4}, //2598 #CJK UNIFIED IDEOGRAPH + {0x9351, 0x8F4D}, //2599 #CJK UNIFIED IDEOGRAPH + {0x9352, 0x8FED}, //2600 #CJK UNIFIED IDEOGRAPH + {0x9353, 0x9244}, //2601 #CJK UNIFIED IDEOGRAPH + {0x9354, 0x5178}, //2602 #CJK UNIFIED IDEOGRAPH + {0x9355, 0x586B}, //2603 #CJK UNIFIED IDEOGRAPH + {0x9356, 0x5929}, //2604 #CJK UNIFIED IDEOGRAPH + {0x9357, 0x5C55}, //2605 #CJK UNIFIED IDEOGRAPH + {0x9358, 0x5E97}, //2606 #CJK UNIFIED IDEOGRAPH + {0x9359, 0x6DFB}, //2607 #CJK UNIFIED IDEOGRAPH + {0x935A, 0x7E8F}, //2608 #CJK UNIFIED IDEOGRAPH + {0x935B, 0x751C}, //2609 #CJK UNIFIED IDEOGRAPH + {0x935C, 0x8CBC}, //2610 #CJK UNIFIED IDEOGRAPH + {0x935D, 0x8EE2}, //2611 #CJK UNIFIED IDEOGRAPH + {0x935E, 0x985B}, //2612 #CJK UNIFIED IDEOGRAPH + {0x935F, 0x70B9}, //2613 #CJK UNIFIED IDEOGRAPH + {0x9360, 0x4F1D}, //2614 #CJK UNIFIED IDEOGRAPH + {0x9361, 0x6BBF}, //2615 #CJK UNIFIED IDEOGRAPH + {0x9362, 0x6FB1}, //2616 #CJK UNIFIED IDEOGRAPH + {0x9363, 0x7530}, //2617 #CJK UNIFIED IDEOGRAPH + {0x9364, 0x96FB}, //2618 #CJK UNIFIED IDEOGRAPH + {0x9365, 0x514E}, //2619 #CJK UNIFIED IDEOGRAPH + {0x9366, 0x5410}, //2620 #CJK UNIFIED IDEOGRAPH + {0x9367, 0x5835}, //2621 #CJK UNIFIED IDEOGRAPH + {0x9368, 0x5857}, //2622 #CJK UNIFIED IDEOGRAPH + {0x9369, 0x59AC}, //2623 #CJK UNIFIED IDEOGRAPH + {0x936A, 0x5C60}, //2624 #CJK UNIFIED IDEOGRAPH + {0x936B, 0x5F92}, //2625 #CJK UNIFIED IDEOGRAPH + {0x936C, 0x6597}, //2626 #CJK UNIFIED IDEOGRAPH + {0x936D, 0x675C}, //2627 #CJK UNIFIED IDEOGRAPH + {0x936E, 0x6E21}, //2628 #CJK UNIFIED IDEOGRAPH + {0x936F, 0x767B}, //2629 #CJK UNIFIED IDEOGRAPH + {0x9370, 0x83DF}, //2630 #CJK UNIFIED IDEOGRAPH + {0x9371, 0x8CED}, //2631 #CJK UNIFIED IDEOGRAPH + {0x9372, 0x9014}, //2632 #CJK UNIFIED IDEOGRAPH + {0x9373, 0x90FD}, //2633 #CJK UNIFIED IDEOGRAPH + {0x9374, 0x934D}, //2634 #CJK UNIFIED IDEOGRAPH + {0x9375, 0x7825}, //2635 #CJK UNIFIED IDEOGRAPH + {0x9376, 0x783A}, //2636 #CJK UNIFIED IDEOGRAPH + {0x9377, 0x52AA}, //2637 #CJK UNIFIED IDEOGRAPH + {0x9378, 0x5EA6}, //2638 #CJK UNIFIED IDEOGRAPH + {0x9379, 0x571F}, //2639 #CJK UNIFIED IDEOGRAPH + {0x937A, 0x5974}, //2640 #CJK UNIFIED IDEOGRAPH + {0x937B, 0x6012}, //2641 #CJK UNIFIED IDEOGRAPH + {0x937C, 0x5012}, //2642 #CJK UNIFIED IDEOGRAPH + {0x937D, 0x515A}, //2643 #CJK UNIFIED IDEOGRAPH + {0x937E, 0x51AC}, //2644 #CJK UNIFIED IDEOGRAPH + {0x9380, 0x51CD}, //2645 #CJK UNIFIED IDEOGRAPH + {0x9381, 0x5200}, //2646 #CJK UNIFIED IDEOGRAPH + {0x9382, 0x5510}, //2647 #CJK UNIFIED IDEOGRAPH + {0x9383, 0x5854}, //2648 #CJK UNIFIED IDEOGRAPH + {0x9384, 0x5858}, //2649 #CJK UNIFIED IDEOGRAPH + {0x9385, 0x5957}, //2650 #CJK UNIFIED IDEOGRAPH + {0x9386, 0x5B95}, //2651 #CJK UNIFIED IDEOGRAPH + {0x9387, 0x5CF6}, //2652 #CJK UNIFIED IDEOGRAPH + {0x9388, 0x5D8B}, //2653 #CJK UNIFIED IDEOGRAPH + {0x9389, 0x60BC}, //2654 #CJK UNIFIED IDEOGRAPH + {0x938A, 0x6295}, //2655 #CJK UNIFIED IDEOGRAPH + {0x938B, 0x642D}, //2656 #CJK UNIFIED IDEOGRAPH + {0x938C, 0x6771}, //2657 #CJK UNIFIED IDEOGRAPH + {0x938D, 0x6843}, //2658 #CJK UNIFIED IDEOGRAPH + {0x938E, 0x68BC}, //2659 #CJK UNIFIED IDEOGRAPH + {0x938F, 0x68DF}, //2660 #CJK UNIFIED IDEOGRAPH + {0x9390, 0x76D7}, //2661 #CJK UNIFIED IDEOGRAPH + {0x9391, 0x6DD8}, //2662 #CJK UNIFIED IDEOGRAPH + {0x9392, 0x6E6F}, //2663 #CJK UNIFIED IDEOGRAPH + {0x9393, 0x6D9B}, //2664 #CJK UNIFIED IDEOGRAPH + {0x9394, 0x706F}, //2665 #CJK UNIFIED IDEOGRAPH + {0x9395, 0x71C8}, //2666 #CJK UNIFIED IDEOGRAPH + {0x9396, 0x5F53}, //2667 #CJK UNIFIED IDEOGRAPH + {0x9397, 0x75D8}, //2668 #CJK UNIFIED IDEOGRAPH + {0x9398, 0x7977}, //2669 #CJK UNIFIED IDEOGRAPH + {0x9399, 0x7B49}, //2670 #CJK UNIFIED IDEOGRAPH + {0x939A, 0x7B54}, //2671 #CJK UNIFIED IDEOGRAPH + {0x939B, 0x7B52}, //2672 #CJK UNIFIED IDEOGRAPH + {0x939C, 0x7CD6}, //2673 #CJK UNIFIED IDEOGRAPH + {0x939D, 0x7D71}, //2674 #CJK UNIFIED IDEOGRAPH + {0x939E, 0x5230}, //2675 #CJK UNIFIED IDEOGRAPH + {0x939F, 0x8463}, //2676 #CJK UNIFIED IDEOGRAPH + {0x93A0, 0x8569}, //2677 #CJK UNIFIED IDEOGRAPH + {0x93A1, 0x85E4}, //2678 #CJK UNIFIED IDEOGRAPH + {0x93A2, 0x8A0E}, //2679 #CJK UNIFIED IDEOGRAPH + {0x93A3, 0x8B04}, //2680 #CJK UNIFIED IDEOGRAPH + {0x93A4, 0x8C46}, //2681 #CJK UNIFIED IDEOGRAPH + {0x93A5, 0x8E0F}, //2682 #CJK UNIFIED IDEOGRAPH + {0x93A6, 0x9003}, //2683 #CJK UNIFIED IDEOGRAPH + {0x93A7, 0x900F}, //2684 #CJK UNIFIED IDEOGRAPH + {0x93A8, 0x9419}, //2685 #CJK UNIFIED IDEOGRAPH + {0x93A9, 0x9676}, //2686 #CJK UNIFIED IDEOGRAPH + {0x93AA, 0x982D}, //2687 #CJK UNIFIED IDEOGRAPH + {0x93AB, 0x9A30}, //2688 #CJK UNIFIED IDEOGRAPH + {0x93AC, 0x95D8}, //2689 #CJK UNIFIED IDEOGRAPH + {0x93AD, 0x50CD}, //2690 #CJK UNIFIED IDEOGRAPH + {0x93AE, 0x52D5}, //2691 #CJK UNIFIED IDEOGRAPH + {0x93AF, 0x540C}, //2692 #CJK UNIFIED IDEOGRAPH + {0x93B0, 0x5802}, //2693 #CJK UNIFIED IDEOGRAPH + {0x93B1, 0x5C0E}, //2694 #CJK UNIFIED IDEOGRAPH + {0x93B2, 0x61A7}, //2695 #CJK UNIFIED IDEOGRAPH + {0x93B3, 0x649E}, //2696 #CJK UNIFIED IDEOGRAPH + {0x93B4, 0x6D1E}, //2697 #CJK UNIFIED IDEOGRAPH + {0x93B5, 0x77B3}, //2698 #CJK UNIFIED IDEOGRAPH + {0x93B6, 0x7AE5}, //2699 #CJK UNIFIED IDEOGRAPH + {0x93B7, 0x80F4}, //2700 #CJK UNIFIED IDEOGRAPH + {0x93B8, 0x8404}, //2701 #CJK UNIFIED IDEOGRAPH + {0x93B9, 0x9053}, //2702 #CJK UNIFIED IDEOGRAPH + {0x93BA, 0x9285}, //2703 #CJK UNIFIED IDEOGRAPH + {0x93BB, 0x5CE0}, //2704 #CJK UNIFIED IDEOGRAPH + {0x93BC, 0x9D07}, //2705 #CJK UNIFIED IDEOGRAPH + {0x93BD, 0x533F}, //2706 #CJK UNIFIED IDEOGRAPH + {0x93BE, 0x5F97}, //2707 #CJK UNIFIED IDEOGRAPH + {0x93BF, 0x5FB3}, //2708 #CJK UNIFIED IDEOGRAPH + {0x93C0, 0x6D9C}, //2709 #CJK UNIFIED IDEOGRAPH + {0x93C1, 0x7279}, //2710 #CJK UNIFIED IDEOGRAPH + {0x93C2, 0x7763}, //2711 #CJK UNIFIED IDEOGRAPH + {0x93C3, 0x79BF}, //2712 #CJK UNIFIED IDEOGRAPH + {0x93C4, 0x7BE4}, //2713 #CJK UNIFIED IDEOGRAPH + {0x93C5, 0x6BD2}, //2714 #CJK UNIFIED IDEOGRAPH + {0x93C6, 0x72EC}, //2715 #CJK UNIFIED IDEOGRAPH + {0x93C7, 0x8AAD}, //2716 #CJK UNIFIED IDEOGRAPH + {0x93C8, 0x6803}, //2717 #CJK UNIFIED IDEOGRAPH + {0x93C9, 0x6A61}, //2718 #CJK UNIFIED IDEOGRAPH + {0x93CA, 0x51F8}, //2719 #CJK UNIFIED IDEOGRAPH + {0x93CB, 0x7A81}, //2720 #CJK UNIFIED IDEOGRAPH + {0x93CC, 0x6934}, //2721 #CJK UNIFIED IDEOGRAPH + {0x93CD, 0x5C4A}, //2722 #CJK UNIFIED IDEOGRAPH + {0x93CE, 0x9CF6}, //2723 #CJK UNIFIED IDEOGRAPH + {0x93CF, 0x82EB}, //2724 #CJK UNIFIED IDEOGRAPH + {0x93D0, 0x5BC5}, //2725 #CJK UNIFIED IDEOGRAPH + {0x93D1, 0x9149}, //2726 #CJK UNIFIED IDEOGRAPH + {0x93D2, 0x701E}, //2727 #CJK UNIFIED IDEOGRAPH + {0x93D3, 0x5678}, //2728 #CJK UNIFIED IDEOGRAPH + {0x93D4, 0x5C6F}, //2729 #CJK UNIFIED IDEOGRAPH + {0x93D5, 0x60C7}, //2730 #CJK UNIFIED IDEOGRAPH + {0x93D6, 0x6566}, //2731 #CJK UNIFIED IDEOGRAPH + {0x93D7, 0x6C8C}, //2732 #CJK UNIFIED IDEOGRAPH + {0x93D8, 0x8C5A}, //2733 #CJK UNIFIED IDEOGRAPH + {0x93D9, 0x9041}, //2734 #CJK UNIFIED IDEOGRAPH + {0x93DA, 0x9813}, //2735 #CJK UNIFIED IDEOGRAPH + {0x93DB, 0x5451}, //2736 #CJK UNIFIED IDEOGRAPH + {0x93DC, 0x66C7}, //2737 #CJK UNIFIED IDEOGRAPH + {0x93DD, 0x920D}, //2738 #CJK UNIFIED IDEOGRAPH + {0x93DE, 0x5948}, //2739 #CJK UNIFIED IDEOGRAPH + {0x93DF, 0x90A3}, //2740 #CJK UNIFIED IDEOGRAPH + {0x93E0, 0x5185}, //2741 #CJK UNIFIED IDEOGRAPH + {0x93E1, 0x4E4D}, //2742 #CJK UNIFIED IDEOGRAPH + {0x93E2, 0x51EA}, //2743 #CJK UNIFIED IDEOGRAPH + {0x93E3, 0x8599}, //2744 #CJK UNIFIED IDEOGRAPH + {0x93E4, 0x8B0E}, //2745 #CJK UNIFIED IDEOGRAPH + {0x93E5, 0x7058}, //2746 #CJK UNIFIED IDEOGRAPH + {0x93E6, 0x637A}, //2747 #CJK UNIFIED IDEOGRAPH + {0x93E7, 0x934B}, //2748 #CJK UNIFIED IDEOGRAPH + {0x93E8, 0x6962}, //2749 #CJK UNIFIED IDEOGRAPH + {0x93E9, 0x99B4}, //2750 #CJK UNIFIED IDEOGRAPH + {0x93EA, 0x7E04}, //2751 #CJK UNIFIED IDEOGRAPH + {0x93EB, 0x7577}, //2752 #CJK UNIFIED IDEOGRAPH + {0x93EC, 0x5357}, //2753 #CJK UNIFIED IDEOGRAPH + {0x93ED, 0x6960}, //2754 #CJK UNIFIED IDEOGRAPH + {0x93EE, 0x8EDF}, //2755 #CJK UNIFIED IDEOGRAPH + {0x93EF, 0x96E3}, //2756 #CJK UNIFIED IDEOGRAPH + {0x93F0, 0x6C5D}, //2757 #CJK UNIFIED IDEOGRAPH + {0x93F1, 0x4E8C}, //2758 #CJK UNIFIED IDEOGRAPH + {0x93F2, 0x5C3C}, //2759 #CJK UNIFIED IDEOGRAPH + {0x93F3, 0x5F10}, //2760 #CJK UNIFIED IDEOGRAPH + {0x93F4, 0x8FE9}, //2761 #CJK UNIFIED IDEOGRAPH + {0x93F5, 0x5302}, //2762 #CJK UNIFIED IDEOGRAPH + {0x93F6, 0x8CD1}, //2763 #CJK UNIFIED IDEOGRAPH + {0x93F7, 0x8089}, //2764 #CJK UNIFIED IDEOGRAPH + {0x93F8, 0x8679}, //2765 #CJK UNIFIED IDEOGRAPH + {0x93F9, 0x5EFF}, //2766 #CJK UNIFIED IDEOGRAPH + {0x93FA, 0x65E5}, //2767 #CJK UNIFIED IDEOGRAPH + {0x93FB, 0x4E73}, //2768 #CJK UNIFIED IDEOGRAPH + {0x93FC, 0x5165}, //2769 #CJK UNIFIED IDEOGRAPH + {0x9440, 0x5982}, //2770 #CJK UNIFIED IDEOGRAPH + {0x9441, 0x5C3F}, //2771 #CJK UNIFIED IDEOGRAPH + {0x9442, 0x97EE}, //2772 #CJK UNIFIED IDEOGRAPH + {0x9443, 0x4EFB}, //2773 #CJK UNIFIED IDEOGRAPH + {0x9444, 0x598A}, //2774 #CJK UNIFIED IDEOGRAPH + {0x9445, 0x5FCD}, //2775 #CJK UNIFIED IDEOGRAPH + {0x9446, 0x8A8D}, //2776 #CJK UNIFIED IDEOGRAPH + {0x9447, 0x6FE1}, //2777 #CJK UNIFIED IDEOGRAPH + {0x9448, 0x79B0}, //2778 #CJK UNIFIED IDEOGRAPH + {0x9449, 0x7962}, //2779 #CJK UNIFIED IDEOGRAPH + {0x944A, 0x5BE7}, //2780 #CJK UNIFIED IDEOGRAPH + {0x944B, 0x8471}, //2781 #CJK UNIFIED IDEOGRAPH + {0x944C, 0x732B}, //2782 #CJK UNIFIED IDEOGRAPH + {0x944D, 0x71B1}, //2783 #CJK UNIFIED IDEOGRAPH + {0x944E, 0x5E74}, //2784 #CJK UNIFIED IDEOGRAPH + {0x944F, 0x5FF5}, //2785 #CJK UNIFIED IDEOGRAPH + {0x9450, 0x637B}, //2786 #CJK UNIFIED IDEOGRAPH + {0x9451, 0x649A}, //2787 #CJK UNIFIED IDEOGRAPH + {0x9452, 0x71C3}, //2788 #CJK UNIFIED IDEOGRAPH + {0x9453, 0x7C98}, //2789 #CJK UNIFIED IDEOGRAPH + {0x9454, 0x4E43}, //2790 #CJK UNIFIED IDEOGRAPH + {0x9455, 0x5EFC}, //2791 #CJK UNIFIED IDEOGRAPH + {0x9456, 0x4E4B}, //2792 #CJK UNIFIED IDEOGRAPH + {0x9457, 0x57DC}, //2793 #CJK UNIFIED IDEOGRAPH + {0x9458, 0x56A2}, //2794 #CJK UNIFIED IDEOGRAPH + {0x9459, 0x60A9}, //2795 #CJK UNIFIED IDEOGRAPH + {0x945A, 0x6FC3}, //2796 #CJK UNIFIED IDEOGRAPH + {0x945B, 0x7D0D}, //2797 #CJK UNIFIED IDEOGRAPH + {0x945C, 0x80FD}, //2798 #CJK UNIFIED IDEOGRAPH + {0x945D, 0x8133}, //2799 #CJK UNIFIED IDEOGRAPH + {0x945E, 0x81BF}, //2800 #CJK UNIFIED IDEOGRAPH + {0x945F, 0x8FB2}, //2801 #CJK UNIFIED IDEOGRAPH + {0x9460, 0x8997}, //2802 #CJK UNIFIED IDEOGRAPH + {0x9461, 0x86A4}, //2803 #CJK UNIFIED IDEOGRAPH + {0x9462, 0x5DF4}, //2804 #CJK UNIFIED IDEOGRAPH + {0x9463, 0x628A}, //2805 #CJK UNIFIED IDEOGRAPH + {0x9464, 0x64AD}, //2806 #CJK UNIFIED IDEOGRAPH + {0x9465, 0x8987}, //2807 #CJK UNIFIED IDEOGRAPH + {0x9466, 0x6777}, //2808 #CJK UNIFIED IDEOGRAPH + {0x9467, 0x6CE2}, //2809 #CJK UNIFIED IDEOGRAPH + {0x9468, 0x6D3E}, //2810 #CJK UNIFIED IDEOGRAPH + {0x9469, 0x7436}, //2811 #CJK UNIFIED IDEOGRAPH + {0x946A, 0x7834}, //2812 #CJK UNIFIED IDEOGRAPH + {0x946B, 0x5A46}, //2813 #CJK UNIFIED IDEOGRAPH + {0x946C, 0x7F75}, //2814 #CJK UNIFIED IDEOGRAPH + {0x946D, 0x82AD}, //2815 #CJK UNIFIED IDEOGRAPH + {0x946E, 0x99AC}, //2816 #CJK UNIFIED IDEOGRAPH + {0x946F, 0x4FF3}, //2817 #CJK UNIFIED IDEOGRAPH + {0x9470, 0x5EC3}, //2818 #CJK UNIFIED IDEOGRAPH + {0x9471, 0x62DD}, //2819 #CJK UNIFIED IDEOGRAPH + {0x9472, 0x6392}, //2820 #CJK UNIFIED IDEOGRAPH + {0x9473, 0x6557}, //2821 #CJK UNIFIED IDEOGRAPH + {0x9474, 0x676F}, //2822 #CJK UNIFIED IDEOGRAPH + {0x9475, 0x76C3}, //2823 #CJK UNIFIED IDEOGRAPH + {0x9476, 0x724C}, //2824 #CJK UNIFIED IDEOGRAPH + {0x9477, 0x80CC}, //2825 #CJK UNIFIED IDEOGRAPH + {0x9478, 0x80BA}, //2826 #CJK UNIFIED IDEOGRAPH + {0x9479, 0x8F29}, //2827 #CJK UNIFIED IDEOGRAPH + {0x947A, 0x914D}, //2828 #CJK UNIFIED IDEOGRAPH + {0x947B, 0x500D}, //2829 #CJK UNIFIED IDEOGRAPH + {0x947C, 0x57F9}, //2830 #CJK UNIFIED IDEOGRAPH + {0x947D, 0x5A92}, //2831 #CJK UNIFIED IDEOGRAPH + {0x947E, 0x6885}, //2832 #CJK UNIFIED IDEOGRAPH + {0x9480, 0x6973}, //2833 #CJK UNIFIED IDEOGRAPH + {0x9481, 0x7164}, //2834 #CJK UNIFIED IDEOGRAPH + {0x9482, 0x72FD}, //2835 #CJK UNIFIED IDEOGRAPH + {0x9483, 0x8CB7}, //2836 #CJK UNIFIED IDEOGRAPH + {0x9484, 0x58F2}, //2837 #CJK UNIFIED IDEOGRAPH + {0x9485, 0x8CE0}, //2838 #CJK UNIFIED IDEOGRAPH + {0x9486, 0x966A}, //2839 #CJK UNIFIED IDEOGRAPH + {0x9487, 0x9019}, //2840 #CJK UNIFIED IDEOGRAPH + {0x9488, 0x877F}, //2841 #CJK UNIFIED IDEOGRAPH + {0x9489, 0x79E4}, //2842 #CJK UNIFIED IDEOGRAPH + {0x948A, 0x77E7}, //2843 #CJK UNIFIED IDEOGRAPH + {0x948B, 0x8429}, //2844 #CJK UNIFIED IDEOGRAPH + {0x948C, 0x4F2F}, //2845 #CJK UNIFIED IDEOGRAPH + {0x948D, 0x5265}, //2846 #CJK UNIFIED IDEOGRAPH + {0x948E, 0x535A}, //2847 #CJK UNIFIED IDEOGRAPH + {0x948F, 0x62CD}, //2848 #CJK UNIFIED IDEOGRAPH + {0x9490, 0x67CF}, //2849 #CJK UNIFIED IDEOGRAPH + {0x9491, 0x6CCA}, //2850 #CJK UNIFIED IDEOGRAPH + {0x9492, 0x767D}, //2851 #CJK UNIFIED IDEOGRAPH + {0x9493, 0x7B94}, //2852 #CJK UNIFIED IDEOGRAPH + {0x9494, 0x7C95}, //2853 #CJK UNIFIED IDEOGRAPH + {0x9495, 0x8236}, //2854 #CJK UNIFIED IDEOGRAPH + {0x9496, 0x8584}, //2855 #CJK UNIFIED IDEOGRAPH + {0x9497, 0x8FEB}, //2856 #CJK UNIFIED IDEOGRAPH + {0x9498, 0x66DD}, //2857 #CJK UNIFIED IDEOGRAPH + {0x9499, 0x6F20}, //2858 #CJK UNIFIED IDEOGRAPH + {0x949A, 0x7206}, //2859 #CJK UNIFIED IDEOGRAPH + {0x949B, 0x7E1B}, //2860 #CJK UNIFIED IDEOGRAPH + {0x949C, 0x83AB}, //2861 #CJK UNIFIED IDEOGRAPH + {0x949D, 0x99C1}, //2862 #CJK UNIFIED IDEOGRAPH + {0x949E, 0x9EA6}, //2863 #CJK UNIFIED IDEOGRAPH + {0x949F, 0x51FD}, //2864 #CJK UNIFIED IDEOGRAPH + {0x94A0, 0x7BB1}, //2865 #CJK UNIFIED IDEOGRAPH + {0x94A1, 0x7872}, //2866 #CJK UNIFIED IDEOGRAPH + {0x94A2, 0x7BB8}, //2867 #CJK UNIFIED IDEOGRAPH + {0x94A3, 0x8087}, //2868 #CJK UNIFIED IDEOGRAPH + {0x94A4, 0x7B48}, //2869 #CJK UNIFIED IDEOGRAPH + {0x94A5, 0x6AE8}, //2870 #CJK UNIFIED IDEOGRAPH + {0x94A6, 0x5E61}, //2871 #CJK UNIFIED IDEOGRAPH + {0x94A7, 0x808C}, //2872 #CJK UNIFIED IDEOGRAPH + {0x94A8, 0x7551}, //2873 #CJK UNIFIED IDEOGRAPH + {0x94A9, 0x7560}, //2874 #CJK UNIFIED IDEOGRAPH + {0x94AA, 0x516B}, //2875 #CJK UNIFIED IDEOGRAPH + {0x94AB, 0x9262}, //2876 #CJK UNIFIED IDEOGRAPH + {0x94AC, 0x6E8C}, //2877 #CJK UNIFIED IDEOGRAPH + {0x94AD, 0x767A}, //2878 #CJK UNIFIED IDEOGRAPH + {0x94AE, 0x9197}, //2879 #CJK UNIFIED IDEOGRAPH + {0x94AF, 0x9AEA}, //2880 #CJK UNIFIED IDEOGRAPH + {0x94B0, 0x4F10}, //2881 #CJK UNIFIED IDEOGRAPH + {0x94B1, 0x7F70}, //2882 #CJK UNIFIED IDEOGRAPH + {0x94B2, 0x629C}, //2883 #CJK UNIFIED IDEOGRAPH + {0x94B3, 0x7B4F}, //2884 #CJK UNIFIED IDEOGRAPH + {0x94B4, 0x95A5}, //2885 #CJK UNIFIED IDEOGRAPH + {0x94B5, 0x9CE9}, //2886 #CJK UNIFIED IDEOGRAPH + {0x94B6, 0x567A}, //2887 #CJK UNIFIED IDEOGRAPH + {0x94B7, 0x5859}, //2888 #CJK UNIFIED IDEOGRAPH + {0x94B8, 0x86E4}, //2889 #CJK UNIFIED IDEOGRAPH + {0x94B9, 0x96BC}, //2890 #CJK UNIFIED IDEOGRAPH + {0x94BA, 0x4F34}, //2891 #CJK UNIFIED IDEOGRAPH + {0x94BB, 0x5224}, //2892 #CJK UNIFIED IDEOGRAPH + {0x94BC, 0x534A}, //2893 #CJK UNIFIED IDEOGRAPH + {0x94BD, 0x53CD}, //2894 #CJK UNIFIED IDEOGRAPH + {0x94BE, 0x53DB}, //2895 #CJK UNIFIED IDEOGRAPH + {0x94BF, 0x5E06}, //2896 #CJK UNIFIED IDEOGRAPH + {0x94C0, 0x642C}, //2897 #CJK UNIFIED IDEOGRAPH + {0x94C1, 0x6591}, //2898 #CJK UNIFIED IDEOGRAPH + {0x94C2, 0x677F}, //2899 #CJK UNIFIED IDEOGRAPH + {0x94C3, 0x6C3E}, //2900 #CJK UNIFIED IDEOGRAPH + {0x94C4, 0x6C4E}, //2901 #CJK UNIFIED IDEOGRAPH + {0x94C5, 0x7248}, //2902 #CJK UNIFIED IDEOGRAPH + {0x94C6, 0x72AF}, //2903 #CJK UNIFIED IDEOGRAPH + {0x94C7, 0x73ED}, //2904 #CJK UNIFIED IDEOGRAPH + {0x94C8, 0x7554}, //2905 #CJK UNIFIED IDEOGRAPH + {0x94C9, 0x7E41}, //2906 #CJK UNIFIED IDEOGRAPH + {0x94CA, 0x822C}, //2907 #CJK UNIFIED IDEOGRAPH + {0x94CB, 0x85E9}, //2908 #CJK UNIFIED IDEOGRAPH + {0x94CC, 0x8CA9}, //2909 #CJK UNIFIED IDEOGRAPH + {0x94CD, 0x7BC4}, //2910 #CJK UNIFIED IDEOGRAPH + {0x94CE, 0x91C6}, //2911 #CJK UNIFIED IDEOGRAPH + {0x94CF, 0x7169}, //2912 #CJK UNIFIED IDEOGRAPH + {0x94D0, 0x9812}, //2913 #CJK UNIFIED IDEOGRAPH + {0x94D1, 0x98EF}, //2914 #CJK UNIFIED IDEOGRAPH + {0x94D2, 0x633D}, //2915 #CJK UNIFIED IDEOGRAPH + {0x94D3, 0x6669}, //2916 #CJK UNIFIED IDEOGRAPH + {0x94D4, 0x756A}, //2917 #CJK UNIFIED IDEOGRAPH + {0x94D5, 0x76E4}, //2918 #CJK UNIFIED IDEOGRAPH + {0x94D6, 0x78D0}, //2919 #CJK UNIFIED IDEOGRAPH + {0x94D7, 0x8543}, //2920 #CJK UNIFIED IDEOGRAPH + {0x94D8, 0x86EE}, //2921 #CJK UNIFIED IDEOGRAPH + {0x94D9, 0x532A}, //2922 #CJK UNIFIED IDEOGRAPH + {0x94DA, 0x5351}, //2923 #CJK UNIFIED IDEOGRAPH + {0x94DB, 0x5426}, //2924 #CJK UNIFIED IDEOGRAPH + {0x94DC, 0x5983}, //2925 #CJK UNIFIED IDEOGRAPH + {0x94DD, 0x5E87}, //2926 #CJK UNIFIED IDEOGRAPH + {0x94DE, 0x5F7C}, //2927 #CJK UNIFIED IDEOGRAPH + {0x94DF, 0x60B2}, //2928 #CJK UNIFIED IDEOGRAPH + {0x94E0, 0x6249}, //2929 #CJK UNIFIED IDEOGRAPH + {0x94E1, 0x6279}, //2930 #CJK UNIFIED IDEOGRAPH + {0x94E2, 0x62AB}, //2931 #CJK UNIFIED IDEOGRAPH + {0x94E3, 0x6590}, //2932 #CJK UNIFIED IDEOGRAPH + {0x94E4, 0x6BD4}, //2933 #CJK UNIFIED IDEOGRAPH + {0x94E5, 0x6CCC}, //2934 #CJK UNIFIED IDEOGRAPH + {0x94E6, 0x75B2}, //2935 #CJK UNIFIED IDEOGRAPH + {0x94E7, 0x76AE}, //2936 #CJK UNIFIED IDEOGRAPH + {0x94E8, 0x7891}, //2937 #CJK UNIFIED IDEOGRAPH + {0x94E9, 0x79D8}, //2938 #CJK UNIFIED IDEOGRAPH + {0x94EA, 0x7DCB}, //2939 #CJK UNIFIED IDEOGRAPH + {0x94EB, 0x7F77}, //2940 #CJK UNIFIED IDEOGRAPH + {0x94EC, 0x80A5}, //2941 #CJK UNIFIED IDEOGRAPH + {0x94ED, 0x88AB}, //2942 #CJK UNIFIED IDEOGRAPH + {0x94EE, 0x8AB9}, //2943 #CJK UNIFIED IDEOGRAPH + {0x94EF, 0x8CBB}, //2944 #CJK UNIFIED IDEOGRAPH + {0x94F0, 0x907F}, //2945 #CJK UNIFIED IDEOGRAPH + {0x94F1, 0x975E}, //2946 #CJK UNIFIED IDEOGRAPH + {0x94F2, 0x98DB}, //2947 #CJK UNIFIED IDEOGRAPH + {0x94F3, 0x6A0B}, //2948 #CJK UNIFIED IDEOGRAPH + {0x94F4, 0x7C38}, //2949 #CJK UNIFIED IDEOGRAPH + {0x94F5, 0x5099}, //2950 #CJK UNIFIED IDEOGRAPH + {0x94F6, 0x5C3E}, //2951 #CJK UNIFIED IDEOGRAPH + {0x94F7, 0x5FAE}, //2952 #CJK UNIFIED IDEOGRAPH + {0x94F8, 0x6787}, //2953 #CJK UNIFIED IDEOGRAPH + {0x94F9, 0x6BD8}, //2954 #CJK UNIFIED IDEOGRAPH + {0x94FA, 0x7435}, //2955 #CJK UNIFIED IDEOGRAPH + {0x94FB, 0x7709}, //2956 #CJK UNIFIED IDEOGRAPH + {0x94FC, 0x7F8E}, //2957 #CJK UNIFIED IDEOGRAPH + {0x9540, 0x9F3B}, //2958 #CJK UNIFIED IDEOGRAPH + {0x9541, 0x67CA}, //2959 #CJK UNIFIED IDEOGRAPH + {0x9542, 0x7A17}, //2960 #CJK UNIFIED IDEOGRAPH + {0x9543, 0x5339}, //2961 #CJK UNIFIED IDEOGRAPH + {0x9544, 0x758B}, //2962 #CJK UNIFIED IDEOGRAPH + {0x9545, 0x9AED}, //2963 #CJK UNIFIED IDEOGRAPH + {0x9546, 0x5F66}, //2964 #CJK UNIFIED IDEOGRAPH + {0x9547, 0x819D}, //2965 #CJK UNIFIED IDEOGRAPH + {0x9548, 0x83F1}, //2966 #CJK UNIFIED IDEOGRAPH + {0x9549, 0x8098}, //2967 #CJK UNIFIED IDEOGRAPH + {0x954A, 0x5F3C}, //2968 #CJK UNIFIED IDEOGRAPH + {0x954B, 0x5FC5}, //2969 #CJK UNIFIED IDEOGRAPH + {0x954C, 0x7562}, //2970 #CJK UNIFIED IDEOGRAPH + {0x954D, 0x7B46}, //2971 #CJK UNIFIED IDEOGRAPH + {0x954E, 0x903C}, //2972 #CJK UNIFIED IDEOGRAPH + {0x954F, 0x6867}, //2973 #CJK UNIFIED IDEOGRAPH + {0x9550, 0x59EB}, //2974 #CJK UNIFIED IDEOGRAPH + {0x9551, 0x5A9B}, //2975 #CJK UNIFIED IDEOGRAPH + {0x9552, 0x7D10}, //2976 #CJK UNIFIED IDEOGRAPH + {0x9553, 0x767E}, //2977 #CJK UNIFIED IDEOGRAPH + {0x9554, 0x8B2C}, //2978 #CJK UNIFIED IDEOGRAPH + {0x9555, 0x4FF5}, //2979 #CJK UNIFIED IDEOGRAPH + {0x9556, 0x5F6A}, //2980 #CJK UNIFIED IDEOGRAPH + {0x9557, 0x6A19}, //2981 #CJK UNIFIED IDEOGRAPH + {0x9558, 0x6C37}, //2982 #CJK UNIFIED IDEOGRAPH + {0x9559, 0x6F02}, //2983 #CJK UNIFIED IDEOGRAPH + {0x955A, 0x74E2}, //2984 #CJK UNIFIED IDEOGRAPH + {0x955B, 0x7968}, //2985 #CJK UNIFIED IDEOGRAPH + {0x955C, 0x8868}, //2986 #CJK UNIFIED IDEOGRAPH + {0x955D, 0x8A55}, //2987 #CJK UNIFIED IDEOGRAPH + {0x955E, 0x8C79}, //2988 #CJK UNIFIED IDEOGRAPH + {0x955F, 0x5EDF}, //2989 #CJK UNIFIED IDEOGRAPH + {0x9560, 0x63CF}, //2990 #CJK UNIFIED IDEOGRAPH + {0x9561, 0x75C5}, //2991 #CJK UNIFIED IDEOGRAPH + {0x9562, 0x79D2}, //2992 #CJK UNIFIED IDEOGRAPH + {0x9563, 0x82D7}, //2993 #CJK UNIFIED IDEOGRAPH + {0x9564, 0x9328}, //2994 #CJK UNIFIED IDEOGRAPH + {0x9565, 0x92F2}, //2995 #CJK UNIFIED IDEOGRAPH + {0x9566, 0x849C}, //2996 #CJK UNIFIED IDEOGRAPH + {0x9567, 0x86ED}, //2997 #CJK UNIFIED IDEOGRAPH + {0x9568, 0x9C2D}, //2998 #CJK UNIFIED IDEOGRAPH + {0x9569, 0x54C1}, //2999 #CJK UNIFIED IDEOGRAPH + {0x956A, 0x5F6C}, //3000 #CJK UNIFIED IDEOGRAPH + {0x956B, 0x658C}, //3001 #CJK UNIFIED IDEOGRAPH + {0x956C, 0x6D5C}, //3002 #CJK UNIFIED IDEOGRAPH + {0x956D, 0x7015}, //3003 #CJK UNIFIED IDEOGRAPH + {0x956E, 0x8CA7}, //3004 #CJK UNIFIED IDEOGRAPH + {0x956F, 0x8CD3}, //3005 #CJK UNIFIED IDEOGRAPH + {0x9570, 0x983B}, //3006 #CJK UNIFIED IDEOGRAPH + {0x9571, 0x654F}, //3007 #CJK UNIFIED IDEOGRAPH + {0x9572, 0x74F6}, //3008 #CJK UNIFIED IDEOGRAPH + {0x9573, 0x4E0D}, //3009 #CJK UNIFIED IDEOGRAPH + {0x9574, 0x4ED8}, //3010 #CJK UNIFIED IDEOGRAPH + {0x9575, 0x57E0}, //3011 #CJK UNIFIED IDEOGRAPH + {0x9576, 0x592B}, //3012 #CJK UNIFIED IDEOGRAPH + {0x9577, 0x5A66}, //3013 #CJK UNIFIED IDEOGRAPH + {0x9578, 0x5BCC}, //3014 #CJK UNIFIED IDEOGRAPH + {0x9579, 0x51A8}, //3015 #CJK UNIFIED IDEOGRAPH + {0x957A, 0x5E03}, //3016 #CJK UNIFIED IDEOGRAPH + {0x957B, 0x5E9C}, //3017 #CJK UNIFIED IDEOGRAPH + {0x957C, 0x6016}, //3018 #CJK UNIFIED IDEOGRAPH + {0x957D, 0x6276}, //3019 #CJK UNIFIED IDEOGRAPH + {0x957E, 0x6577}, //3020 #CJK UNIFIED IDEOGRAPH + {0x9580, 0x65A7}, //3021 #CJK UNIFIED IDEOGRAPH + {0x9581, 0x666E}, //3022 #CJK UNIFIED IDEOGRAPH + {0x9582, 0x6D6E}, //3023 #CJK UNIFIED IDEOGRAPH + {0x9583, 0x7236}, //3024 #CJK UNIFIED IDEOGRAPH + {0x9584, 0x7B26}, //3025 #CJK UNIFIED IDEOGRAPH + {0x9585, 0x8150}, //3026 #CJK UNIFIED IDEOGRAPH + {0x9586, 0x819A}, //3027 #CJK UNIFIED IDEOGRAPH + {0x9587, 0x8299}, //3028 #CJK UNIFIED IDEOGRAPH + {0x9588, 0x8B5C}, //3029 #CJK UNIFIED IDEOGRAPH + {0x9589, 0x8CA0}, //3030 #CJK UNIFIED IDEOGRAPH + {0x958A, 0x8CE6}, //3031 #CJK UNIFIED IDEOGRAPH + {0x958B, 0x8D74}, //3032 #CJK UNIFIED IDEOGRAPH + {0x958C, 0x961C}, //3033 #CJK UNIFIED IDEOGRAPH + {0x958D, 0x9644}, //3034 #CJK UNIFIED IDEOGRAPH + {0x958E, 0x4FAE}, //3035 #CJK UNIFIED IDEOGRAPH + {0x958F, 0x64AB}, //3036 #CJK UNIFIED IDEOGRAPH + {0x9590, 0x6B66}, //3037 #CJK UNIFIED IDEOGRAPH + {0x9591, 0x821E}, //3038 #CJK UNIFIED IDEOGRAPH + {0x9592, 0x8461}, //3039 #CJK UNIFIED IDEOGRAPH + {0x9593, 0x856A}, //3040 #CJK UNIFIED IDEOGRAPH + {0x9594, 0x90E8}, //3041 #CJK UNIFIED IDEOGRAPH + {0x9595, 0x5C01}, //3042 #CJK UNIFIED IDEOGRAPH + {0x9596, 0x6953}, //3043 #CJK UNIFIED IDEOGRAPH + {0x9597, 0x98A8}, //3044 #CJK UNIFIED IDEOGRAPH + {0x9598, 0x847A}, //3045 #CJK UNIFIED IDEOGRAPH + {0x9599, 0x8557}, //3046 #CJK UNIFIED IDEOGRAPH + {0x959A, 0x4F0F}, //3047 #CJK UNIFIED IDEOGRAPH + {0x959B, 0x526F}, //3048 #CJK UNIFIED IDEOGRAPH + {0x959C, 0x5FA9}, //3049 #CJK UNIFIED IDEOGRAPH + {0x959D, 0x5E45}, //3050 #CJK UNIFIED IDEOGRAPH + {0x959E, 0x670D}, //3051 #CJK UNIFIED IDEOGRAPH + {0x959F, 0x798F}, //3052 #CJK UNIFIED IDEOGRAPH + {0x95A0, 0x8179}, //3053 #CJK UNIFIED IDEOGRAPH + {0x95A1, 0x8907}, //3054 #CJK UNIFIED IDEOGRAPH + {0x95A2, 0x8986}, //3055 #CJK UNIFIED IDEOGRAPH + {0x95A3, 0x6DF5}, //3056 #CJK UNIFIED IDEOGRAPH + {0x95A4, 0x5F17}, //3057 #CJK UNIFIED IDEOGRAPH + {0x95A5, 0x6255}, //3058 #CJK UNIFIED IDEOGRAPH + {0x95A6, 0x6CB8}, //3059 #CJK UNIFIED IDEOGRAPH + {0x95A7, 0x4ECF}, //3060 #CJK UNIFIED IDEOGRAPH + {0x95A8, 0x7269}, //3061 #CJK UNIFIED IDEOGRAPH + {0x95A9, 0x9B92}, //3062 #CJK UNIFIED IDEOGRAPH + {0x95AA, 0x5206}, //3063 #CJK UNIFIED IDEOGRAPH + {0x95AB, 0x543B}, //3064 #CJK UNIFIED IDEOGRAPH + {0x95AC, 0x5674}, //3065 #CJK UNIFIED IDEOGRAPH + {0x95AD, 0x58B3}, //3066 #CJK UNIFIED IDEOGRAPH + {0x95AE, 0x61A4}, //3067 #CJK UNIFIED IDEOGRAPH + {0x95AF, 0x626E}, //3068 #CJK UNIFIED IDEOGRAPH + {0x95B0, 0x711A}, //3069 #CJK UNIFIED IDEOGRAPH + {0x95B1, 0x596E}, //3070 #CJK UNIFIED IDEOGRAPH + {0x95B2, 0x7C89}, //3071 #CJK UNIFIED IDEOGRAPH + {0x95B3, 0x7CDE}, //3072 #CJK UNIFIED IDEOGRAPH + {0x95B4, 0x7D1B}, //3073 #CJK UNIFIED IDEOGRAPH + {0x95B5, 0x96F0}, //3074 #CJK UNIFIED IDEOGRAPH + {0x95B6, 0x6587}, //3075 #CJK UNIFIED IDEOGRAPH + {0x95B7, 0x805E}, //3076 #CJK UNIFIED IDEOGRAPH + {0x95B8, 0x4E19}, //3077 #CJK UNIFIED IDEOGRAPH + {0x95B9, 0x4F75}, //3078 #CJK UNIFIED IDEOGRAPH + {0x95BA, 0x5175}, //3079 #CJK UNIFIED IDEOGRAPH + {0x95BB, 0x5840}, //3080 #CJK UNIFIED IDEOGRAPH + {0x95BC, 0x5E63}, //3081 #CJK UNIFIED IDEOGRAPH + {0x95BD, 0x5E73}, //3082 #CJK UNIFIED IDEOGRAPH + {0x95BE, 0x5F0A}, //3083 #CJK UNIFIED IDEOGRAPH + {0x95BF, 0x67C4}, //3084 #CJK UNIFIED IDEOGRAPH + {0x95C0, 0x4E26}, //3085 #CJK UNIFIED IDEOGRAPH + {0x95C1, 0x853D}, //3086 #CJK UNIFIED IDEOGRAPH + {0x95C2, 0x9589}, //3087 #CJK UNIFIED IDEOGRAPH + {0x95C3, 0x965B}, //3088 #CJK UNIFIED IDEOGRAPH + {0x95C4, 0x7C73}, //3089 #CJK UNIFIED IDEOGRAPH + {0x95C5, 0x9801}, //3090 #CJK UNIFIED IDEOGRAPH + {0x95C6, 0x50FB}, //3091 #CJK UNIFIED IDEOGRAPH + {0x95C7, 0x58C1}, //3092 #CJK UNIFIED IDEOGRAPH + {0x95C8, 0x7656}, //3093 #CJK UNIFIED IDEOGRAPH + {0x95C9, 0x78A7}, //3094 #CJK UNIFIED IDEOGRAPH + {0x95CA, 0x5225}, //3095 #CJK UNIFIED IDEOGRAPH + {0x95CB, 0x77A5}, //3096 #CJK UNIFIED IDEOGRAPH + {0x95CC, 0x8511}, //3097 #CJK UNIFIED IDEOGRAPH + {0x95CD, 0x7B86}, //3098 #CJK UNIFIED IDEOGRAPH + {0x95CE, 0x504F}, //3099 #CJK UNIFIED IDEOGRAPH + {0x95CF, 0x5909}, //3100 #CJK UNIFIED IDEOGRAPH + {0x95D0, 0x7247}, //3101 #CJK UNIFIED IDEOGRAPH + {0x95D1, 0x7BC7}, //3102 #CJK UNIFIED IDEOGRAPH + {0x95D2, 0x7DE8}, //3103 #CJK UNIFIED IDEOGRAPH + {0x95D3, 0x8FBA}, //3104 #CJK UNIFIED IDEOGRAPH + {0x95D4, 0x8FD4}, //3105 #CJK UNIFIED IDEOGRAPH + {0x95D5, 0x904D}, //3106 #CJK UNIFIED IDEOGRAPH + {0x95D6, 0x4FBF}, //3107 #CJK UNIFIED IDEOGRAPH + {0x95D7, 0x52C9}, //3108 #CJK UNIFIED IDEOGRAPH + {0x95D8, 0x5A29}, //3109 #CJK UNIFIED IDEOGRAPH + {0x95D9, 0x5F01}, //3110 #CJK UNIFIED IDEOGRAPH + {0x95DA, 0x97AD}, //3111 #CJK UNIFIED IDEOGRAPH + {0x95DB, 0x4FDD}, //3112 #CJK UNIFIED IDEOGRAPH + {0x95DC, 0x8217}, //3113 #CJK UNIFIED IDEOGRAPH + {0x95DD, 0x92EA}, //3114 #CJK UNIFIED IDEOGRAPH + {0x95DE, 0x5703}, //3115 #CJK UNIFIED IDEOGRAPH + {0x95DF, 0x6355}, //3116 #CJK UNIFIED IDEOGRAPH + {0x95E0, 0x6B69}, //3117 #CJK UNIFIED IDEOGRAPH + {0x95E1, 0x752B}, //3118 #CJK UNIFIED IDEOGRAPH + {0x95E2, 0x88DC}, //3119 #CJK UNIFIED IDEOGRAPH + {0x95E3, 0x8F14}, //3120 #CJK UNIFIED IDEOGRAPH + {0x95E4, 0x7A42}, //3121 #CJK UNIFIED IDEOGRAPH + {0x95E5, 0x52DF}, //3122 #CJK UNIFIED IDEOGRAPH + {0x95E6, 0x5893}, //3123 #CJK UNIFIED IDEOGRAPH + {0x95E7, 0x6155}, //3124 #CJK UNIFIED IDEOGRAPH + {0x95E8, 0x620A}, //3125 #CJK UNIFIED IDEOGRAPH + {0x95E9, 0x66AE}, //3126 #CJK UNIFIED IDEOGRAPH + {0x95EA, 0x6BCD}, //3127 #CJK UNIFIED IDEOGRAPH + {0x95EB, 0x7C3F}, //3128 #CJK UNIFIED IDEOGRAPH + {0x95EC, 0x83E9}, //3129 #CJK UNIFIED IDEOGRAPH + {0x95ED, 0x5023}, //3130 #CJK UNIFIED IDEOGRAPH + {0x95EE, 0x4FF8}, //3131 #CJK UNIFIED IDEOGRAPH + {0x95EF, 0x5305}, //3132 #CJK UNIFIED IDEOGRAPH + {0x95F0, 0x5446}, //3133 #CJK UNIFIED IDEOGRAPH + {0x95F1, 0x5831}, //3134 #CJK UNIFIED IDEOGRAPH + {0x95F2, 0x5949}, //3135 #CJK UNIFIED IDEOGRAPH + {0x95F3, 0x5B9D}, //3136 #CJK UNIFIED IDEOGRAPH + {0x95F4, 0x5CF0}, //3137 #CJK UNIFIED IDEOGRAPH + {0x95F5, 0x5CEF}, //3138 #CJK UNIFIED IDEOGRAPH + {0x95F6, 0x5D29}, //3139 #CJK UNIFIED IDEOGRAPH + {0x95F7, 0x5E96}, //3140 #CJK UNIFIED IDEOGRAPH + {0x95F8, 0x62B1}, //3141 #CJK UNIFIED IDEOGRAPH + {0x95F9, 0x6367}, //3142 #CJK UNIFIED IDEOGRAPH + {0x95FA, 0x653E}, //3143 #CJK UNIFIED IDEOGRAPH + {0x95FB, 0x65B9}, //3144 #CJK UNIFIED IDEOGRAPH + {0x95FC, 0x670B}, //3145 #CJK UNIFIED IDEOGRAPH + {0x9640, 0x6CD5}, //3146 #CJK UNIFIED IDEOGRAPH + {0x9641, 0x6CE1}, //3147 #CJK UNIFIED IDEOGRAPH + {0x9642, 0x70F9}, //3148 #CJK UNIFIED IDEOGRAPH + {0x9643, 0x7832}, //3149 #CJK UNIFIED IDEOGRAPH + {0x9644, 0x7E2B}, //3150 #CJK UNIFIED IDEOGRAPH + {0x9645, 0x80DE}, //3151 #CJK UNIFIED IDEOGRAPH + {0x9646, 0x82B3}, //3152 #CJK UNIFIED IDEOGRAPH + {0x9647, 0x840C}, //3153 #CJK UNIFIED IDEOGRAPH + {0x9648, 0x84EC}, //3154 #CJK UNIFIED IDEOGRAPH + {0x9649, 0x8702}, //3155 #CJK UNIFIED IDEOGRAPH + {0x964A, 0x8912}, //3156 #CJK UNIFIED IDEOGRAPH + {0x964B, 0x8A2A}, //3157 #CJK UNIFIED IDEOGRAPH + {0x964C, 0x8C4A}, //3158 #CJK UNIFIED IDEOGRAPH + {0x964D, 0x90A6}, //3159 #CJK UNIFIED IDEOGRAPH + {0x964E, 0x92D2}, //3160 #CJK UNIFIED IDEOGRAPH + {0x964F, 0x98FD}, //3161 #CJK UNIFIED IDEOGRAPH + {0x9650, 0x9CF3}, //3162 #CJK UNIFIED IDEOGRAPH + {0x9651, 0x9D6C}, //3163 #CJK UNIFIED IDEOGRAPH + {0x9652, 0x4E4F}, //3164 #CJK UNIFIED IDEOGRAPH + {0x9653, 0x4EA1}, //3165 #CJK UNIFIED IDEOGRAPH + {0x9654, 0x508D}, //3166 #CJK UNIFIED IDEOGRAPH + {0x9655, 0x5256}, //3167 #CJK UNIFIED IDEOGRAPH + {0x9656, 0x574A}, //3168 #CJK UNIFIED IDEOGRAPH + {0x9657, 0x59A8}, //3169 #CJK UNIFIED IDEOGRAPH + {0x9658, 0x5E3D}, //3170 #CJK UNIFIED IDEOGRAPH + {0x9659, 0x5FD8}, //3171 #CJK UNIFIED IDEOGRAPH + {0x965A, 0x5FD9}, //3172 #CJK UNIFIED IDEOGRAPH + {0x965B, 0x623F}, //3173 #CJK UNIFIED IDEOGRAPH + {0x965C, 0x66B4}, //3174 #CJK UNIFIED IDEOGRAPH + {0x965D, 0x671B}, //3175 #CJK UNIFIED IDEOGRAPH + {0x965E, 0x67D0}, //3176 #CJK UNIFIED IDEOGRAPH + {0x965F, 0x68D2}, //3177 #CJK UNIFIED IDEOGRAPH + {0x9660, 0x5192}, //3178 #CJK UNIFIED IDEOGRAPH + {0x9661, 0x7D21}, //3179 #CJK UNIFIED IDEOGRAPH + {0x9662, 0x80AA}, //3180 #CJK UNIFIED IDEOGRAPH + {0x9663, 0x81A8}, //3181 #CJK UNIFIED IDEOGRAPH + {0x9664, 0x8B00}, //3182 #CJK UNIFIED IDEOGRAPH + {0x9665, 0x8C8C}, //3183 #CJK UNIFIED IDEOGRAPH + {0x9666, 0x8CBF}, //3184 #CJK UNIFIED IDEOGRAPH + {0x9667, 0x927E}, //3185 #CJK UNIFIED IDEOGRAPH + {0x9668, 0x9632}, //3186 #CJK UNIFIED IDEOGRAPH + {0x9669, 0x5420}, //3187 #CJK UNIFIED IDEOGRAPH + {0x966A, 0x982C}, //3188 #CJK UNIFIED IDEOGRAPH + {0x966B, 0x5317}, //3189 #CJK UNIFIED IDEOGRAPH + {0x966C, 0x50D5}, //3190 #CJK UNIFIED IDEOGRAPH + {0x966D, 0x535C}, //3191 #CJK UNIFIED IDEOGRAPH + {0x966E, 0x58A8}, //3192 #CJK UNIFIED IDEOGRAPH + {0x966F, 0x64B2}, //3193 #CJK UNIFIED IDEOGRAPH + {0x9670, 0x6734}, //3194 #CJK UNIFIED IDEOGRAPH + {0x9671, 0x7267}, //3195 #CJK UNIFIED IDEOGRAPH + {0x9672, 0x7766}, //3196 #CJK UNIFIED IDEOGRAPH + {0x9673, 0x7A46}, //3197 #CJK UNIFIED IDEOGRAPH + {0x9674, 0x91E6}, //3198 #CJK UNIFIED IDEOGRAPH + {0x9675, 0x52C3}, //3199 #CJK UNIFIED IDEOGRAPH + {0x9676, 0x6CA1}, //3200 #CJK UNIFIED IDEOGRAPH + {0x9677, 0x6B86}, //3201 #CJK UNIFIED IDEOGRAPH + {0x9678, 0x5800}, //3202 #CJK UNIFIED IDEOGRAPH + {0x9679, 0x5E4C}, //3203 #CJK UNIFIED IDEOGRAPH + {0x967A, 0x5954}, //3204 #CJK UNIFIED IDEOGRAPH + {0x967B, 0x672C}, //3205 #CJK UNIFIED IDEOGRAPH + {0x967C, 0x7FFB}, //3206 #CJK UNIFIED IDEOGRAPH + {0x967D, 0x51E1}, //3207 #CJK UNIFIED IDEOGRAPH + {0x967E, 0x76C6}, //3208 #CJK UNIFIED IDEOGRAPH + {0x9680, 0x6469}, //3209 #CJK UNIFIED IDEOGRAPH + {0x9681, 0x78E8}, //3210 #CJK UNIFIED IDEOGRAPH + {0x9682, 0x9B54}, //3211 #CJK UNIFIED IDEOGRAPH + {0x9683, 0x9EBB}, //3212 #CJK UNIFIED IDEOGRAPH + {0x9684, 0x57CB}, //3213 #CJK UNIFIED IDEOGRAPH + {0x9685, 0x59B9}, //3214 #CJK UNIFIED IDEOGRAPH + {0x9686, 0x6627}, //3215 #CJK UNIFIED IDEOGRAPH + {0x9687, 0x679A}, //3216 #CJK UNIFIED IDEOGRAPH + {0x9688, 0x6BCE}, //3217 #CJK UNIFIED IDEOGRAPH + {0x9689, 0x54E9}, //3218 #CJK UNIFIED IDEOGRAPH + {0x968A, 0x69D9}, //3219 #CJK UNIFIED IDEOGRAPH + {0x968B, 0x5E55}, //3220 #CJK UNIFIED IDEOGRAPH + {0x968C, 0x819C}, //3221 #CJK UNIFIED IDEOGRAPH + {0x968D, 0x6795}, //3222 #CJK UNIFIED IDEOGRAPH + {0x968E, 0x9BAA}, //3223 #CJK UNIFIED IDEOGRAPH + {0x968F, 0x67FE}, //3224 #CJK UNIFIED IDEOGRAPH + {0x9690, 0x9C52}, //3225 #CJK UNIFIED IDEOGRAPH + {0x9691, 0x685D}, //3226 #CJK UNIFIED IDEOGRAPH + {0x9692, 0x4EA6}, //3227 #CJK UNIFIED IDEOGRAPH + {0x9693, 0x4FE3}, //3228 #CJK UNIFIED IDEOGRAPH + {0x9694, 0x53C8}, //3229 #CJK UNIFIED IDEOGRAPH + {0x9695, 0x62B9}, //3230 #CJK UNIFIED IDEOGRAPH + {0x9696, 0x672B}, //3231 #CJK UNIFIED IDEOGRAPH + {0x9697, 0x6CAB}, //3232 #CJK UNIFIED IDEOGRAPH + {0x9698, 0x8FC4}, //3233 #CJK UNIFIED IDEOGRAPH + {0x9699, 0x4FAD}, //3234 #CJK UNIFIED IDEOGRAPH + {0x969A, 0x7E6D}, //3235 #CJK UNIFIED IDEOGRAPH + {0x969B, 0x9EBF}, //3236 #CJK UNIFIED IDEOGRAPH + {0x969C, 0x4E07}, //3237 #CJK UNIFIED IDEOGRAPH + {0x969D, 0x6162}, //3238 #CJK UNIFIED IDEOGRAPH + {0x969E, 0x6E80}, //3239 #CJK UNIFIED IDEOGRAPH + {0x969F, 0x6F2B}, //3240 #CJK UNIFIED IDEOGRAPH + {0x96A0, 0x8513}, //3241 #CJK UNIFIED IDEOGRAPH + {0x96A1, 0x5473}, //3242 #CJK UNIFIED IDEOGRAPH + {0x96A2, 0x672A}, //3243 #CJK UNIFIED IDEOGRAPH + {0x96A3, 0x9B45}, //3244 #CJK UNIFIED IDEOGRAPH + {0x96A4, 0x5DF3}, //3245 #CJK UNIFIED IDEOGRAPH + {0x96A5, 0x7B95}, //3246 #CJK UNIFIED IDEOGRAPH + {0x96A6, 0x5CAC}, //3247 #CJK UNIFIED IDEOGRAPH + {0x96A7, 0x5BC6}, //3248 #CJK UNIFIED IDEOGRAPH + {0x96A8, 0x871C}, //3249 #CJK UNIFIED IDEOGRAPH + {0x96A9, 0x6E4A}, //3250 #CJK UNIFIED IDEOGRAPH + {0x96AA, 0x84D1}, //3251 #CJK UNIFIED IDEOGRAPH + {0x96AB, 0x7A14}, //3252 #CJK UNIFIED IDEOGRAPH + {0x96AC, 0x8108}, //3253 #CJK UNIFIED IDEOGRAPH + {0x96AD, 0x5999}, //3254 #CJK UNIFIED IDEOGRAPH + {0x96AE, 0x7C8D}, //3255 #CJK UNIFIED IDEOGRAPH + {0x96AF, 0x6C11}, //3256 #CJK UNIFIED IDEOGRAPH + {0x96B0, 0x7720}, //3257 #CJK UNIFIED IDEOGRAPH + {0x96B1, 0x52D9}, //3258 #CJK UNIFIED IDEOGRAPH + {0x96B2, 0x5922}, //3259 #CJK UNIFIED IDEOGRAPH + {0x96B3, 0x7121}, //3260 #CJK UNIFIED IDEOGRAPH + {0x96B4, 0x725F}, //3261 #CJK UNIFIED IDEOGRAPH + {0x96B5, 0x77DB}, //3262 #CJK UNIFIED IDEOGRAPH + {0x96B6, 0x9727}, //3263 #CJK UNIFIED IDEOGRAPH + {0x96B7, 0x9D61}, //3264 #CJK UNIFIED IDEOGRAPH + {0x96B8, 0x690B}, //3265 #CJK UNIFIED IDEOGRAPH + {0x96B9, 0x5A7F}, //3266 #CJK UNIFIED IDEOGRAPH + {0x96BA, 0x5A18}, //3267 #CJK UNIFIED IDEOGRAPH + {0x96BB, 0x51A5}, //3268 #CJK UNIFIED IDEOGRAPH + {0x96BC, 0x540D}, //3269 #CJK UNIFIED IDEOGRAPH + {0x96BD, 0x547D}, //3270 #CJK UNIFIED IDEOGRAPH + {0x96BE, 0x660E}, //3271 #CJK UNIFIED IDEOGRAPH + {0x96BF, 0x76DF}, //3272 #CJK UNIFIED IDEOGRAPH + {0x96C0, 0x8FF7}, //3273 #CJK UNIFIED IDEOGRAPH + {0x96C1, 0x9298}, //3274 #CJK UNIFIED IDEOGRAPH + {0x96C2, 0x9CF4}, //3275 #CJK UNIFIED IDEOGRAPH + {0x96C3, 0x59EA}, //3276 #CJK UNIFIED IDEOGRAPH + {0x96C4, 0x725D}, //3277 #CJK UNIFIED IDEOGRAPH + {0x96C5, 0x6EC5}, //3278 #CJK UNIFIED IDEOGRAPH + {0x96C6, 0x514D}, //3279 #CJK UNIFIED IDEOGRAPH + {0x96C7, 0x68C9}, //3280 #CJK UNIFIED IDEOGRAPH + {0x96C8, 0x7DBF}, //3281 #CJK UNIFIED IDEOGRAPH + {0x96C9, 0x7DEC}, //3282 #CJK UNIFIED IDEOGRAPH + {0x96CA, 0x9762}, //3283 #CJK UNIFIED IDEOGRAPH + {0x96CB, 0x9EBA}, //3284 #CJK UNIFIED IDEOGRAPH + {0x96CC, 0x6478}, //3285 #CJK UNIFIED IDEOGRAPH + {0x96CD, 0x6A21}, //3286 #CJK UNIFIED IDEOGRAPH + {0x96CE, 0x8302}, //3287 #CJK UNIFIED IDEOGRAPH + {0x96CF, 0x5984}, //3288 #CJK UNIFIED IDEOGRAPH + {0x96D0, 0x5B5F}, //3289 #CJK UNIFIED IDEOGRAPH + {0x96D1, 0x6BDB}, //3290 #CJK UNIFIED IDEOGRAPH + {0x96D2, 0x731B}, //3291 #CJK UNIFIED IDEOGRAPH + {0x96D3, 0x76F2}, //3292 #CJK UNIFIED IDEOGRAPH + {0x96D4, 0x7DB2}, //3293 #CJK UNIFIED IDEOGRAPH + {0x96D5, 0x8017}, //3294 #CJK UNIFIED IDEOGRAPH + {0x96D6, 0x8499}, //3295 #CJK UNIFIED IDEOGRAPH + {0x96D7, 0x5132}, //3296 #CJK UNIFIED IDEOGRAPH + {0x96D8, 0x6728}, //3297 #CJK UNIFIED IDEOGRAPH + {0x96D9, 0x9ED9}, //3298 #CJK UNIFIED IDEOGRAPH + {0x96DA, 0x76EE}, //3299 #CJK UNIFIED IDEOGRAPH + {0x96DB, 0x6762}, //3300 #CJK UNIFIED IDEOGRAPH + {0x96DC, 0x52FF}, //3301 #CJK UNIFIED IDEOGRAPH + {0x96DD, 0x9905}, //3302 #CJK UNIFIED IDEOGRAPH + {0x96DE, 0x5C24}, //3303 #CJK UNIFIED IDEOGRAPH + {0x96DF, 0x623B}, //3304 #CJK UNIFIED IDEOGRAPH + {0x96E0, 0x7C7E}, //3305 #CJK UNIFIED IDEOGRAPH + {0x96E1, 0x8CB0}, //3306 #CJK UNIFIED IDEOGRAPH + {0x96E2, 0x554F}, //3307 #CJK UNIFIED IDEOGRAPH + {0x96E3, 0x60B6}, //3308 #CJK UNIFIED IDEOGRAPH + {0x96E4, 0x7D0B}, //3309 #CJK UNIFIED IDEOGRAPH + {0x96E5, 0x9580}, //3310 #CJK UNIFIED IDEOGRAPH + {0x96E6, 0x5301}, //3311 #CJK UNIFIED IDEOGRAPH + {0x96E7, 0x4E5F}, //3312 #CJK UNIFIED IDEOGRAPH + {0x96E8, 0x51B6}, //3313 #CJK UNIFIED IDEOGRAPH + {0x96E9, 0x591C}, //3314 #CJK UNIFIED IDEOGRAPH + {0x96EA, 0x723A}, //3315 #CJK UNIFIED IDEOGRAPH + {0x96EB, 0x8036}, //3316 #CJK UNIFIED IDEOGRAPH + {0x96EC, 0x91CE}, //3317 #CJK UNIFIED IDEOGRAPH + {0x96ED, 0x5F25}, //3318 #CJK UNIFIED IDEOGRAPH + {0x96EE, 0x77E2}, //3319 #CJK UNIFIED IDEOGRAPH + {0x96EF, 0x5384}, //3320 #CJK UNIFIED IDEOGRAPH + {0x96F0, 0x5F79}, //3321 #CJK UNIFIED IDEOGRAPH + {0x96F1, 0x7D04}, //3322 #CJK UNIFIED IDEOGRAPH + {0x96F2, 0x85AC}, //3323 #CJK UNIFIED IDEOGRAPH + {0x96F3, 0x8A33}, //3324 #CJK UNIFIED IDEOGRAPH + {0x96F4, 0x8E8D}, //3325 #CJK UNIFIED IDEOGRAPH + {0x96F5, 0x9756}, //3326 #CJK UNIFIED IDEOGRAPH + {0x96F6, 0x67F3}, //3327 #CJK UNIFIED IDEOGRAPH + {0x96F7, 0x85AE}, //3328 #CJK UNIFIED IDEOGRAPH + {0x96F8, 0x9453}, //3329 #CJK UNIFIED IDEOGRAPH + {0x96F9, 0x6109}, //3330 #CJK UNIFIED IDEOGRAPH + {0x96FA, 0x6108}, //3331 #CJK UNIFIED IDEOGRAPH + {0x96FB, 0x6CB9}, //3332 #CJK UNIFIED IDEOGRAPH + {0x96FC, 0x7652}, //3333 #CJK UNIFIED IDEOGRAPH + {0x9740, 0x8AED}, //3334 #CJK UNIFIED IDEOGRAPH + {0x9741, 0x8F38}, //3335 #CJK UNIFIED IDEOGRAPH + {0x9742, 0x552F}, //3336 #CJK UNIFIED IDEOGRAPH + {0x9743, 0x4F51}, //3337 #CJK UNIFIED IDEOGRAPH + {0x9744, 0x512A}, //3338 #CJK UNIFIED IDEOGRAPH + {0x9745, 0x52C7}, //3339 #CJK UNIFIED IDEOGRAPH + {0x9746, 0x53CB}, //3340 #CJK UNIFIED IDEOGRAPH + {0x9747, 0x5BA5}, //3341 #CJK UNIFIED IDEOGRAPH + {0x9748, 0x5E7D}, //3342 #CJK UNIFIED IDEOGRAPH + {0x9749, 0x60A0}, //3343 #CJK UNIFIED IDEOGRAPH + {0x974A, 0x6182}, //3344 #CJK UNIFIED IDEOGRAPH + {0x974B, 0x63D6}, //3345 #CJK UNIFIED IDEOGRAPH + {0x974C, 0x6709}, //3346 #CJK UNIFIED IDEOGRAPH + {0x974D, 0x67DA}, //3347 #CJK UNIFIED IDEOGRAPH + {0x974E, 0x6E67}, //3348 #CJK UNIFIED IDEOGRAPH + {0x974F, 0x6D8C}, //3349 #CJK UNIFIED IDEOGRAPH + {0x9750, 0x7336}, //3350 #CJK UNIFIED IDEOGRAPH + {0x9751, 0x7337}, //3351 #CJK UNIFIED IDEOGRAPH + {0x9752, 0x7531}, //3352 #CJK UNIFIED IDEOGRAPH + {0x9753, 0x7950}, //3353 #CJK UNIFIED IDEOGRAPH + {0x9754, 0x88D5}, //3354 #CJK UNIFIED IDEOGRAPH + {0x9755, 0x8A98}, //3355 #CJK UNIFIED IDEOGRAPH + {0x9756, 0x904A}, //3356 #CJK UNIFIED IDEOGRAPH + {0x9757, 0x9091}, //3357 #CJK UNIFIED IDEOGRAPH + {0x9758, 0x90F5}, //3358 #CJK UNIFIED IDEOGRAPH + {0x9759, 0x96C4}, //3359 #CJK UNIFIED IDEOGRAPH + {0x975A, 0x878D}, //3360 #CJK UNIFIED IDEOGRAPH + {0x975B, 0x5915}, //3361 #CJK UNIFIED IDEOGRAPH + {0x975C, 0x4E88}, //3362 #CJK UNIFIED IDEOGRAPH + {0x975D, 0x4F59}, //3363 #CJK UNIFIED IDEOGRAPH + {0x975E, 0x4E0E}, //3364 #CJK UNIFIED IDEOGRAPH + {0x975F, 0x8A89}, //3365 #CJK UNIFIED IDEOGRAPH + {0x9760, 0x8F3F}, //3366 #CJK UNIFIED IDEOGRAPH + {0x9761, 0x9810}, //3367 #CJK UNIFIED IDEOGRAPH + {0x9762, 0x50AD}, //3368 #CJK UNIFIED IDEOGRAPH + {0x9763, 0x5E7C}, //3369 #CJK UNIFIED IDEOGRAPH + {0x9764, 0x5996}, //3370 #CJK UNIFIED IDEOGRAPH + {0x9765, 0x5BB9}, //3371 #CJK UNIFIED IDEOGRAPH + {0x9766, 0x5EB8}, //3372 #CJK UNIFIED IDEOGRAPH + {0x9767, 0x63DA}, //3373 #CJK UNIFIED IDEOGRAPH + {0x9768, 0x63FA}, //3374 #CJK UNIFIED IDEOGRAPH + {0x9769, 0x64C1}, //3375 #CJK UNIFIED IDEOGRAPH + {0x976A, 0x66DC}, //3376 #CJK UNIFIED IDEOGRAPH + {0x976B, 0x694A}, //3377 #CJK UNIFIED IDEOGRAPH + {0x976C, 0x69D8}, //3378 #CJK UNIFIED IDEOGRAPH + {0x976D, 0x6D0B}, //3379 #CJK UNIFIED IDEOGRAPH + {0x976E, 0x6EB6}, //3380 #CJK UNIFIED IDEOGRAPH + {0x976F, 0x7194}, //3381 #CJK UNIFIED IDEOGRAPH + {0x9770, 0x7528}, //3382 #CJK UNIFIED IDEOGRAPH + {0x9771, 0x7AAF}, //3383 #CJK UNIFIED IDEOGRAPH + {0x9772, 0x7F8A}, //3384 #CJK UNIFIED IDEOGRAPH + {0x9773, 0x8000}, //3385 #CJK UNIFIED IDEOGRAPH + {0x9774, 0x8449}, //3386 #CJK UNIFIED IDEOGRAPH + {0x9775, 0x84C9}, //3387 #CJK UNIFIED IDEOGRAPH + {0x9776, 0x8981}, //3388 #CJK UNIFIED IDEOGRAPH + {0x9777, 0x8B21}, //3389 #CJK UNIFIED IDEOGRAPH + {0x9778, 0x8E0A}, //3390 #CJK UNIFIED IDEOGRAPH + {0x9779, 0x9065}, //3391 #CJK UNIFIED IDEOGRAPH + {0x977A, 0x967D}, //3392 #CJK UNIFIED IDEOGRAPH + {0x977B, 0x990A}, //3393 #CJK UNIFIED IDEOGRAPH + {0x977C, 0x617E}, //3394 #CJK UNIFIED IDEOGRAPH + {0x977D, 0x6291}, //3395 #CJK UNIFIED IDEOGRAPH + {0x977E, 0x6B32}, //3396 #CJK UNIFIED IDEOGRAPH + {0x9780, 0x6C83}, //3397 #CJK UNIFIED IDEOGRAPH + {0x9781, 0x6D74}, //3398 #CJK UNIFIED IDEOGRAPH + {0x9782, 0x7FCC}, //3399 #CJK UNIFIED IDEOGRAPH + {0x9783, 0x7FFC}, //3400 #CJK UNIFIED IDEOGRAPH + {0x9784, 0x6DC0}, //3401 #CJK UNIFIED IDEOGRAPH + {0x9785, 0x7F85}, //3402 #CJK UNIFIED IDEOGRAPH + {0x9786, 0x87BA}, //3403 #CJK UNIFIED IDEOGRAPH + {0x9787, 0x88F8}, //3404 #CJK UNIFIED IDEOGRAPH + {0x9788, 0x6765}, //3405 #CJK UNIFIED IDEOGRAPH + {0x9789, 0x83B1}, //3406 #CJK UNIFIED IDEOGRAPH + {0x978A, 0x983C}, //3407 #CJK UNIFIED IDEOGRAPH + {0x978B, 0x96F7}, //3408 #CJK UNIFIED IDEOGRAPH + {0x978C, 0x6D1B}, //3409 #CJK UNIFIED IDEOGRAPH + {0x978D, 0x7D61}, //3410 #CJK UNIFIED IDEOGRAPH + {0x978E, 0x843D}, //3411 #CJK UNIFIED IDEOGRAPH + {0x978F, 0x916A}, //3412 #CJK UNIFIED IDEOGRAPH + {0x9790, 0x4E71}, //3413 #CJK UNIFIED IDEOGRAPH + {0x9791, 0x5375}, //3414 #CJK UNIFIED IDEOGRAPH + {0x9792, 0x5D50}, //3415 #CJK UNIFIED IDEOGRAPH + {0x9793, 0x6B04}, //3416 #CJK UNIFIED IDEOGRAPH + {0x9794, 0x6FEB}, //3417 #CJK UNIFIED IDEOGRAPH + {0x9795, 0x85CD}, //3418 #CJK UNIFIED IDEOGRAPH + {0x9796, 0x862D}, //3419 #CJK UNIFIED IDEOGRAPH + {0x9797, 0x89A7}, //3420 #CJK UNIFIED IDEOGRAPH + {0x9798, 0x5229}, //3421 #CJK UNIFIED IDEOGRAPH + {0x9799, 0x540F}, //3422 #CJK UNIFIED IDEOGRAPH + {0x979A, 0x5C65}, //3423 #CJK UNIFIED IDEOGRAPH + {0x979B, 0x674E}, //3424 #CJK UNIFIED IDEOGRAPH + {0x979C, 0x68A8}, //3425 #CJK UNIFIED IDEOGRAPH + {0x979D, 0x7406}, //3426 #CJK UNIFIED IDEOGRAPH + {0x979E, 0x7483}, //3427 #CJK UNIFIED IDEOGRAPH + {0x979F, 0x75E2}, //3428 #CJK UNIFIED IDEOGRAPH + {0x97A0, 0x88CF}, //3429 #CJK UNIFIED IDEOGRAPH + {0x97A1, 0x88E1}, //3430 #CJK UNIFIED IDEOGRAPH + {0x97A2, 0x91CC}, //3431 #CJK UNIFIED IDEOGRAPH + {0x97A3, 0x96E2}, //3432 #CJK UNIFIED IDEOGRAPH + {0x97A4, 0x9678}, //3433 #CJK UNIFIED IDEOGRAPH + {0x97A5, 0x5F8B}, //3434 #CJK UNIFIED IDEOGRAPH + {0x97A6, 0x7387}, //3435 #CJK UNIFIED IDEOGRAPH + {0x97A7, 0x7ACB}, //3436 #CJK UNIFIED IDEOGRAPH + {0x97A8, 0x844E}, //3437 #CJK UNIFIED IDEOGRAPH + {0x97A9, 0x63A0}, //3438 #CJK UNIFIED IDEOGRAPH + {0x97AA, 0x7565}, //3439 #CJK UNIFIED IDEOGRAPH + {0x97AB, 0x5289}, //3440 #CJK UNIFIED IDEOGRAPH + {0x97AC, 0x6D41}, //3441 #CJK UNIFIED IDEOGRAPH + {0x97AD, 0x6E9C}, //3442 #CJK UNIFIED IDEOGRAPH + {0x97AE, 0x7409}, //3443 #CJK UNIFIED IDEOGRAPH + {0x97AF, 0x7559}, //3444 #CJK UNIFIED IDEOGRAPH + {0x97B0, 0x786B}, //3445 #CJK UNIFIED IDEOGRAPH + {0x97B1, 0x7C92}, //3446 #CJK UNIFIED IDEOGRAPH + {0x97B2, 0x9686}, //3447 #CJK UNIFIED IDEOGRAPH + {0x97B3, 0x7ADC}, //3448 #CJK UNIFIED IDEOGRAPH + {0x97B4, 0x9F8D}, //3449 #CJK UNIFIED IDEOGRAPH + {0x97B5, 0x4FB6}, //3450 #CJK UNIFIED IDEOGRAPH + {0x97B6, 0x616E}, //3451 #CJK UNIFIED IDEOGRAPH + {0x97B7, 0x65C5}, //3452 #CJK UNIFIED IDEOGRAPH + {0x97B8, 0x865C}, //3453 #CJK UNIFIED IDEOGRAPH + {0x97B9, 0x4E86}, //3454 #CJK UNIFIED IDEOGRAPH + {0x97BA, 0x4EAE}, //3455 #CJK UNIFIED IDEOGRAPH + {0x97BB, 0x50DA}, //3456 #CJK UNIFIED IDEOGRAPH + {0x97BC, 0x4E21}, //3457 #CJK UNIFIED IDEOGRAPH + {0x97BD, 0x51CC}, //3458 #CJK UNIFIED IDEOGRAPH + {0x97BE, 0x5BEE}, //3459 #CJK UNIFIED IDEOGRAPH + {0x97BF, 0x6599}, //3460 #CJK UNIFIED IDEOGRAPH + {0x97C0, 0x6881}, //3461 #CJK UNIFIED IDEOGRAPH + {0x97C1, 0x6DBC}, //3462 #CJK UNIFIED IDEOGRAPH + {0x97C2, 0x731F}, //3463 #CJK UNIFIED IDEOGRAPH + {0x97C3, 0x7642}, //3464 #CJK UNIFIED IDEOGRAPH + {0x97C4, 0x77AD}, //3465 #CJK UNIFIED IDEOGRAPH + {0x97C5, 0x7A1C}, //3466 #CJK UNIFIED IDEOGRAPH + {0x97C6, 0x7CE7}, //3467 #CJK UNIFIED IDEOGRAPH + {0x97C7, 0x826F}, //3468 #CJK UNIFIED IDEOGRAPH + {0x97C8, 0x8AD2}, //3469 #CJK UNIFIED IDEOGRAPH + {0x97C9, 0x907C}, //3470 #CJK UNIFIED IDEOGRAPH + {0x97CA, 0x91CF}, //3471 #CJK UNIFIED IDEOGRAPH + {0x97CB, 0x9675}, //3472 #CJK UNIFIED IDEOGRAPH + {0x97CC, 0x9818}, //3473 #CJK UNIFIED IDEOGRAPH + {0x97CD, 0x529B}, //3474 #CJK UNIFIED IDEOGRAPH + {0x97CE, 0x7DD1}, //3475 #CJK UNIFIED IDEOGRAPH + {0x97CF, 0x502B}, //3476 #CJK UNIFIED IDEOGRAPH + {0x97D0, 0x5398}, //3477 #CJK UNIFIED IDEOGRAPH + {0x97D1, 0x6797}, //3478 #CJK UNIFIED IDEOGRAPH + {0x97D2, 0x6DCB}, //3479 #CJK UNIFIED IDEOGRAPH + {0x97D3, 0x71D0}, //3480 #CJK UNIFIED IDEOGRAPH + {0x97D4, 0x7433}, //3481 #CJK UNIFIED IDEOGRAPH + {0x97D5, 0x81E8}, //3482 #CJK UNIFIED IDEOGRAPH + {0x97D6, 0x8F2A}, //3483 #CJK UNIFIED IDEOGRAPH + {0x97D7, 0x96A3}, //3484 #CJK UNIFIED IDEOGRAPH + {0x97D8, 0x9C57}, //3485 #CJK UNIFIED IDEOGRAPH + {0x97D9, 0x9E9F}, //3486 #CJK UNIFIED IDEOGRAPH + {0x97DA, 0x7460}, //3487 #CJK UNIFIED IDEOGRAPH + {0x97DB, 0x5841}, //3488 #CJK UNIFIED IDEOGRAPH + {0x97DC, 0x6D99}, //3489 #CJK UNIFIED IDEOGRAPH + {0x97DD, 0x7D2F}, //3490 #CJK UNIFIED IDEOGRAPH + {0x97DE, 0x985E}, //3491 #CJK UNIFIED IDEOGRAPH + {0x97DF, 0x4EE4}, //3492 #CJK UNIFIED IDEOGRAPH + {0x97E0, 0x4F36}, //3493 #CJK UNIFIED IDEOGRAPH + {0x97E1, 0x4F8B}, //3494 #CJK UNIFIED IDEOGRAPH + {0x97E2, 0x51B7}, //3495 #CJK UNIFIED IDEOGRAPH + {0x97E3, 0x52B1}, //3496 #CJK UNIFIED IDEOGRAPH + {0x97E4, 0x5DBA}, //3497 #CJK UNIFIED IDEOGRAPH + {0x97E5, 0x601C}, //3498 #CJK UNIFIED IDEOGRAPH + {0x97E6, 0x73B2}, //3499 #CJK UNIFIED IDEOGRAPH + {0x97E7, 0x793C}, //3500 #CJK UNIFIED IDEOGRAPH + {0x97E8, 0x82D3}, //3501 #CJK UNIFIED IDEOGRAPH + {0x97E9, 0x9234}, //3502 #CJK UNIFIED IDEOGRAPH + {0x97EA, 0x96B7}, //3503 #CJK UNIFIED IDEOGRAPH + {0x97EB, 0x96F6}, //3504 #CJK UNIFIED IDEOGRAPH + {0x97EC, 0x970A}, //3505 #CJK UNIFIED IDEOGRAPH + {0x97ED, 0x9E97}, //3506 #CJK UNIFIED IDEOGRAPH + {0x97EE, 0x9F62}, //3507 #CJK UNIFIED IDEOGRAPH + {0x97EF, 0x66A6}, //3508 #CJK UNIFIED IDEOGRAPH + {0x97F0, 0x6B74}, //3509 #CJK UNIFIED IDEOGRAPH + {0x97F1, 0x5217}, //3510 #CJK UNIFIED IDEOGRAPH + {0x97F2, 0x52A3}, //3511 #CJK UNIFIED IDEOGRAPH + {0x97F3, 0x70C8}, //3512 #CJK UNIFIED IDEOGRAPH + {0x97F4, 0x88C2}, //3513 #CJK UNIFIED IDEOGRAPH + {0x97F5, 0x5EC9}, //3514 #CJK UNIFIED IDEOGRAPH + {0x97F6, 0x604B}, //3515 #CJK UNIFIED IDEOGRAPH + {0x97F7, 0x6190}, //3516 #CJK UNIFIED IDEOGRAPH + {0x97F8, 0x6F23}, //3517 #CJK UNIFIED IDEOGRAPH + {0x97F9, 0x7149}, //3518 #CJK UNIFIED IDEOGRAPH + {0x97FA, 0x7C3E}, //3519 #CJK UNIFIED IDEOGRAPH + {0x97FB, 0x7DF4}, //3520 #CJK UNIFIED IDEOGRAPH + {0x97FC, 0x806F}, //3521 #CJK UNIFIED IDEOGRAPH + {0x9840, 0x84EE}, //3522 #CJK UNIFIED IDEOGRAPH + {0x9841, 0x9023}, //3523 #CJK UNIFIED IDEOGRAPH + {0x9842, 0x932C}, //3524 #CJK UNIFIED IDEOGRAPH + {0x9843, 0x5442}, //3525 #CJK UNIFIED IDEOGRAPH + {0x9844, 0x9B6F}, //3526 #CJK UNIFIED IDEOGRAPH + {0x9845, 0x6AD3}, //3527 #CJK UNIFIED IDEOGRAPH + {0x9846, 0x7089}, //3528 #CJK UNIFIED IDEOGRAPH + {0x9847, 0x8CC2}, //3529 #CJK UNIFIED IDEOGRAPH + {0x9848, 0x8DEF}, //3530 #CJK UNIFIED IDEOGRAPH + {0x9849, 0x9732}, //3531 #CJK UNIFIED IDEOGRAPH + {0x984A, 0x52B4}, //3532 #CJK UNIFIED IDEOGRAPH + {0x984B, 0x5A41}, //3533 #CJK UNIFIED IDEOGRAPH + {0x984C, 0x5ECA}, //3534 #CJK UNIFIED IDEOGRAPH + {0x984D, 0x5F04}, //3535 #CJK UNIFIED IDEOGRAPH + {0x984E, 0x6717}, //3536 #CJK UNIFIED IDEOGRAPH + {0x984F, 0x697C}, //3537 #CJK UNIFIED IDEOGRAPH + {0x9850, 0x6994}, //3538 #CJK UNIFIED IDEOGRAPH + {0x9851, 0x6D6A}, //3539 #CJK UNIFIED IDEOGRAPH + {0x9852, 0x6F0F}, //3540 #CJK UNIFIED IDEOGRAPH + {0x9853, 0x7262}, //3541 #CJK UNIFIED IDEOGRAPH + {0x9854, 0x72FC}, //3542 #CJK UNIFIED IDEOGRAPH + {0x9855, 0x7BED}, //3543 #CJK UNIFIED IDEOGRAPH + {0x9856, 0x8001}, //3544 #CJK UNIFIED IDEOGRAPH + {0x9857, 0x807E}, //3545 #CJK UNIFIED IDEOGRAPH + {0x9858, 0x874B}, //3546 #CJK UNIFIED IDEOGRAPH + {0x9859, 0x90CE}, //3547 #CJK UNIFIED IDEOGRAPH + {0x985A, 0x516D}, //3548 #CJK UNIFIED IDEOGRAPH + {0x985B, 0x9E93}, //3549 #CJK UNIFIED IDEOGRAPH + {0x985C, 0x7984}, //3550 #CJK UNIFIED IDEOGRAPH + {0x985D, 0x808B}, //3551 #CJK UNIFIED IDEOGRAPH + {0x985E, 0x9332}, //3552 #CJK UNIFIED IDEOGRAPH + {0x985F, 0x8AD6}, //3553 #CJK UNIFIED IDEOGRAPH + {0x9860, 0x502D}, //3554 #CJK UNIFIED IDEOGRAPH + {0x9861, 0x548C}, //3555 #CJK UNIFIED IDEOGRAPH + {0x9862, 0x8A71}, //3556 #CJK UNIFIED IDEOGRAPH + {0x9863, 0x6B6A}, //3557 #CJK UNIFIED IDEOGRAPH + {0x9864, 0x8CC4}, //3558 #CJK UNIFIED IDEOGRAPH + {0x9865, 0x8107}, //3559 #CJK UNIFIED IDEOGRAPH + {0x9866, 0x60D1}, //3560 #CJK UNIFIED IDEOGRAPH + {0x9867, 0x67A0}, //3561 #CJK UNIFIED IDEOGRAPH + {0x9868, 0x9DF2}, //3562 #CJK UNIFIED IDEOGRAPH + {0x9869, 0x4E99}, //3563 #CJK UNIFIED IDEOGRAPH + {0x986A, 0x4E98}, //3564 #CJK UNIFIED IDEOGRAPH + {0x986B, 0x9C10}, //3565 #CJK UNIFIED IDEOGRAPH + {0x986C, 0x8A6B}, //3566 #CJK UNIFIED IDEOGRAPH + {0x986D, 0x85C1}, //3567 #CJK UNIFIED IDEOGRAPH + {0x986E, 0x8568}, //3568 #CJK UNIFIED IDEOGRAPH + {0x986F, 0x6900}, //3569 #CJK UNIFIED IDEOGRAPH + {0x9870, 0x6E7E}, //3570 #CJK UNIFIED IDEOGRAPH + {0x9871, 0x7897}, //3571 #CJK UNIFIED IDEOGRAPH + {0x9872, 0x8155}, //3572 #CJK UNIFIED IDEOGRAPH + {0x989F, 0x5F0C}, //3573 #CJK UNIFIED IDEOGRAPH + {0x98A0, 0x4E10}, //3574 #CJK UNIFIED IDEOGRAPH + {0x98A1, 0x4E15}, //3575 #CJK UNIFIED IDEOGRAPH + {0x98A2, 0x4E2A}, //3576 #CJK UNIFIED IDEOGRAPH + {0x98A3, 0x4E31}, //3577 #CJK UNIFIED IDEOGRAPH + {0x98A4, 0x4E36}, //3578 #CJK UNIFIED IDEOGRAPH + {0x98A5, 0x4E3C}, //3579 #CJK UNIFIED IDEOGRAPH + {0x98A6, 0x4E3F}, //3580 #CJK UNIFIED IDEOGRAPH + {0x98A7, 0x4E42}, //3581 #CJK UNIFIED IDEOGRAPH + {0x98A8, 0x4E56}, //3582 #CJK UNIFIED IDEOGRAPH + {0x98A9, 0x4E58}, //3583 #CJK UNIFIED IDEOGRAPH + {0x98AA, 0x4E82}, //3584 #CJK UNIFIED IDEOGRAPH + {0x98AB, 0x4E85}, //3585 #CJK UNIFIED IDEOGRAPH + {0x98AC, 0x8C6B}, //3586 #CJK UNIFIED IDEOGRAPH + {0x98AD, 0x4E8A}, //3587 #CJK UNIFIED IDEOGRAPH + {0x98AE, 0x8212}, //3588 #CJK UNIFIED IDEOGRAPH + {0x98AF, 0x5F0D}, //3589 #CJK UNIFIED IDEOGRAPH + {0x98B0, 0x4E8E}, //3590 #CJK UNIFIED IDEOGRAPH + {0x98B1, 0x4E9E}, //3591 #CJK UNIFIED IDEOGRAPH + {0x98B2, 0x4E9F}, //3592 #CJK UNIFIED IDEOGRAPH + {0x98B3, 0x4EA0}, //3593 #CJK UNIFIED IDEOGRAPH + {0x98B4, 0x4EA2}, //3594 #CJK UNIFIED IDEOGRAPH + {0x98B5, 0x4EB0}, //3595 #CJK UNIFIED IDEOGRAPH + {0x98B6, 0x4EB3}, //3596 #CJK UNIFIED IDEOGRAPH + {0x98B7, 0x4EB6}, //3597 #CJK UNIFIED IDEOGRAPH + {0x98B8, 0x4ECE}, //3598 #CJK UNIFIED IDEOGRAPH + {0x98B9, 0x4ECD}, //3599 #CJK UNIFIED IDEOGRAPH + {0x98BA, 0x4EC4}, //3600 #CJK UNIFIED IDEOGRAPH + {0x98BB, 0x4EC6}, //3601 #CJK UNIFIED IDEOGRAPH + {0x98BC, 0x4EC2}, //3602 #CJK UNIFIED IDEOGRAPH + {0x98BD, 0x4ED7}, //3603 #CJK UNIFIED IDEOGRAPH + {0x98BE, 0x4EDE}, //3604 #CJK UNIFIED IDEOGRAPH + {0x98BF, 0x4EED}, //3605 #CJK UNIFIED IDEOGRAPH + {0x98C0, 0x4EDF}, //3606 #CJK UNIFIED IDEOGRAPH + {0x98C1, 0x4EF7}, //3607 #CJK UNIFIED IDEOGRAPH + {0x98C2, 0x4F09}, //3608 #CJK UNIFIED IDEOGRAPH + {0x98C3, 0x4F5A}, //3609 #CJK UNIFIED IDEOGRAPH + {0x98C4, 0x4F30}, //3610 #CJK UNIFIED IDEOGRAPH + {0x98C5, 0x4F5B}, //3611 #CJK UNIFIED IDEOGRAPH + {0x98C6, 0x4F5D}, //3612 #CJK UNIFIED IDEOGRAPH + {0x98C7, 0x4F57}, //3613 #CJK UNIFIED IDEOGRAPH + {0x98C8, 0x4F47}, //3614 #CJK UNIFIED IDEOGRAPH + {0x98C9, 0x4F76}, //3615 #CJK UNIFIED IDEOGRAPH + {0x98CA, 0x4F88}, //3616 #CJK UNIFIED IDEOGRAPH + {0x98CB, 0x4F8F}, //3617 #CJK UNIFIED IDEOGRAPH + {0x98CC, 0x4F98}, //3618 #CJK UNIFIED IDEOGRAPH + {0x98CD, 0x4F7B}, //3619 #CJK UNIFIED IDEOGRAPH + {0x98CE, 0x4F69}, //3620 #CJK UNIFIED IDEOGRAPH + {0x98CF, 0x4F70}, //3621 #CJK UNIFIED IDEOGRAPH + {0x98D0, 0x4F91}, //3622 #CJK UNIFIED IDEOGRAPH + {0x98D1, 0x4F6F}, //3623 #CJK UNIFIED IDEOGRAPH + {0x98D2, 0x4F86}, //3624 #CJK UNIFIED IDEOGRAPH + {0x98D3, 0x4F96}, //3625 #CJK UNIFIED IDEOGRAPH + {0x98D4, 0x5118}, //3626 #CJK UNIFIED IDEOGRAPH + {0x98D5, 0x4FD4}, //3627 #CJK UNIFIED IDEOGRAPH + {0x98D6, 0x4FDF}, //3628 #CJK UNIFIED IDEOGRAPH + {0x98D7, 0x4FCE}, //3629 #CJK UNIFIED IDEOGRAPH + {0x98D8, 0x4FD8}, //3630 #CJK UNIFIED IDEOGRAPH + {0x98D9, 0x4FDB}, //3631 #CJK UNIFIED IDEOGRAPH + {0x98DA, 0x4FD1}, //3632 #CJK UNIFIED IDEOGRAPH + {0x98DB, 0x4FDA}, //3633 #CJK UNIFIED IDEOGRAPH + {0x98DC, 0x4FD0}, //3634 #CJK UNIFIED IDEOGRAPH + {0x98DD, 0x4FE4}, //3635 #CJK UNIFIED IDEOGRAPH + {0x98DE, 0x4FE5}, //3636 #CJK UNIFIED IDEOGRAPH + {0x98DF, 0x501A}, //3637 #CJK UNIFIED IDEOGRAPH + {0x98E0, 0x5028}, //3638 #CJK UNIFIED IDEOGRAPH + {0x98E1, 0x5014}, //3639 #CJK UNIFIED IDEOGRAPH + {0x98E2, 0x502A}, //3640 #CJK UNIFIED IDEOGRAPH + {0x98E3, 0x5025}, //3641 #CJK UNIFIED IDEOGRAPH + {0x98E4, 0x5005}, //3642 #CJK UNIFIED IDEOGRAPH + {0x98E5, 0x4F1C}, //3643 #CJK UNIFIED IDEOGRAPH + {0x98E6, 0x4FF6}, //3644 #CJK UNIFIED IDEOGRAPH + {0x98E7, 0x5021}, //3645 #CJK UNIFIED IDEOGRAPH + {0x98E8, 0x5029}, //3646 #CJK UNIFIED IDEOGRAPH + {0x98E9, 0x502C}, //3647 #CJK UNIFIED IDEOGRAPH + {0x98EA, 0x4FFE}, //3648 #CJK UNIFIED IDEOGRAPH + {0x98EB, 0x4FEF}, //3649 #CJK UNIFIED IDEOGRAPH + {0x98EC, 0x5011}, //3650 #CJK UNIFIED IDEOGRAPH + {0x98ED, 0x5006}, //3651 #CJK UNIFIED IDEOGRAPH + {0x98EE, 0x5043}, //3652 #CJK UNIFIED IDEOGRAPH + {0x98EF, 0x5047}, //3653 #CJK UNIFIED IDEOGRAPH + {0x98F0, 0x6703}, //3654 #CJK UNIFIED IDEOGRAPH + {0x98F1, 0x5055}, //3655 #CJK UNIFIED IDEOGRAPH + {0x98F2, 0x5050}, //3656 #CJK UNIFIED IDEOGRAPH + {0x98F3, 0x5048}, //3657 #CJK UNIFIED IDEOGRAPH + {0x98F4, 0x505A}, //3658 #CJK UNIFIED IDEOGRAPH + {0x98F5, 0x5056}, //3659 #CJK UNIFIED IDEOGRAPH + {0x98F6, 0x506C}, //3660 #CJK UNIFIED IDEOGRAPH + {0x98F7, 0x5078}, //3661 #CJK UNIFIED IDEOGRAPH + {0x98F8, 0x5080}, //3662 #CJK UNIFIED IDEOGRAPH + {0x98F9, 0x509A}, //3663 #CJK UNIFIED IDEOGRAPH + {0x98FA, 0x5085}, //3664 #CJK UNIFIED IDEOGRAPH + {0x98FB, 0x50B4}, //3665 #CJK UNIFIED IDEOGRAPH + {0x98FC, 0x50B2}, //3666 #CJK UNIFIED IDEOGRAPH + {0x9940, 0x50C9}, //3667 #CJK UNIFIED IDEOGRAPH + {0x9941, 0x50CA}, //3668 #CJK UNIFIED IDEOGRAPH + {0x9942, 0x50B3}, //3669 #CJK UNIFIED IDEOGRAPH + {0x9943, 0x50C2}, //3670 #CJK UNIFIED IDEOGRAPH + {0x9944, 0x50D6}, //3671 #CJK UNIFIED IDEOGRAPH + {0x9945, 0x50DE}, //3672 #CJK UNIFIED IDEOGRAPH + {0x9946, 0x50E5}, //3673 #CJK UNIFIED IDEOGRAPH + {0x9947, 0x50ED}, //3674 #CJK UNIFIED IDEOGRAPH + {0x9948, 0x50E3}, //3675 #CJK UNIFIED IDEOGRAPH + {0x9949, 0x50EE}, //3676 #CJK UNIFIED IDEOGRAPH + {0x994A, 0x50F9}, //3677 #CJK UNIFIED IDEOGRAPH + {0x994B, 0x50F5}, //3678 #CJK UNIFIED IDEOGRAPH + {0x994C, 0x5109}, //3679 #CJK UNIFIED IDEOGRAPH + {0x994D, 0x5101}, //3680 #CJK UNIFIED IDEOGRAPH + {0x994E, 0x5102}, //3681 #CJK UNIFIED IDEOGRAPH + {0x994F, 0x5116}, //3682 #CJK UNIFIED IDEOGRAPH + {0x9950, 0x5115}, //3683 #CJK UNIFIED IDEOGRAPH + {0x9951, 0x5114}, //3684 #CJK UNIFIED IDEOGRAPH + {0x9952, 0x511A}, //3685 #CJK UNIFIED IDEOGRAPH + {0x9953, 0x5121}, //3686 #CJK UNIFIED IDEOGRAPH + {0x9954, 0x513A}, //3687 #CJK UNIFIED IDEOGRAPH + {0x9955, 0x5137}, //3688 #CJK UNIFIED IDEOGRAPH + {0x9956, 0x513C}, //3689 #CJK UNIFIED IDEOGRAPH + {0x9957, 0x513B}, //3690 #CJK UNIFIED IDEOGRAPH + {0x9958, 0x513F}, //3691 #CJK UNIFIED IDEOGRAPH + {0x9959, 0x5140}, //3692 #CJK UNIFIED IDEOGRAPH + {0x995A, 0x5152}, //3693 #CJK UNIFIED IDEOGRAPH + {0x995B, 0x514C}, //3694 #CJK UNIFIED IDEOGRAPH + {0x995C, 0x5154}, //3695 #CJK UNIFIED IDEOGRAPH + {0x995D, 0x5162}, //3696 #CJK UNIFIED IDEOGRAPH + {0x995E, 0x7AF8}, //3697 #CJK UNIFIED IDEOGRAPH + {0x995F, 0x5169}, //3698 #CJK UNIFIED IDEOGRAPH + {0x9960, 0x516A}, //3699 #CJK UNIFIED IDEOGRAPH + {0x9961, 0x516E}, //3700 #CJK UNIFIED IDEOGRAPH + {0x9962, 0x5180}, //3701 #CJK UNIFIED IDEOGRAPH + {0x9963, 0x5182}, //3702 #CJK UNIFIED IDEOGRAPH + {0x9964, 0x56D8}, //3703 #CJK UNIFIED IDEOGRAPH + {0x9965, 0x518C}, //3704 #CJK UNIFIED IDEOGRAPH + {0x9966, 0x5189}, //3705 #CJK UNIFIED IDEOGRAPH + {0x9967, 0x518F}, //3706 #CJK UNIFIED IDEOGRAPH + {0x9968, 0x5191}, //3707 #CJK UNIFIED IDEOGRAPH + {0x9969, 0x5193}, //3708 #CJK UNIFIED IDEOGRAPH + {0x996A, 0x5195}, //3709 #CJK UNIFIED IDEOGRAPH + {0x996B, 0x5196}, //3710 #CJK UNIFIED IDEOGRAPH + {0x996C, 0x51A4}, //3711 #CJK UNIFIED IDEOGRAPH + {0x996D, 0x51A6}, //3712 #CJK UNIFIED IDEOGRAPH + {0x996E, 0x51A2}, //3713 #CJK UNIFIED IDEOGRAPH + {0x996F, 0x51A9}, //3714 #CJK UNIFIED IDEOGRAPH + {0x9970, 0x51AA}, //3715 #CJK UNIFIED IDEOGRAPH + {0x9971, 0x51AB}, //3716 #CJK UNIFIED IDEOGRAPH + {0x9972, 0x51B3}, //3717 #CJK UNIFIED IDEOGRAPH + {0x9973, 0x51B1}, //3718 #CJK UNIFIED IDEOGRAPH + {0x9974, 0x51B2}, //3719 #CJK UNIFIED IDEOGRAPH + {0x9975, 0x51B0}, //3720 #CJK UNIFIED IDEOGRAPH + {0x9976, 0x51B5}, //3721 #CJK UNIFIED IDEOGRAPH + {0x9977, 0x51BD}, //3722 #CJK UNIFIED IDEOGRAPH + {0x9978, 0x51C5}, //3723 #CJK UNIFIED IDEOGRAPH + {0x9979, 0x51C9}, //3724 #CJK UNIFIED IDEOGRAPH + {0x997A, 0x51DB}, //3725 #CJK UNIFIED IDEOGRAPH + {0x997B, 0x51E0}, //3726 #CJK UNIFIED IDEOGRAPH + {0x997C, 0x8655}, //3727 #CJK UNIFIED IDEOGRAPH + {0x997D, 0x51E9}, //3728 #CJK UNIFIED IDEOGRAPH + {0x997E, 0x51ED}, //3729 #CJK UNIFIED IDEOGRAPH + {0x9980, 0x51F0}, //3730 #CJK UNIFIED IDEOGRAPH + {0x9981, 0x51F5}, //3731 #CJK UNIFIED IDEOGRAPH + {0x9982, 0x51FE}, //3732 #CJK UNIFIED IDEOGRAPH + {0x9983, 0x5204}, //3733 #CJK UNIFIED IDEOGRAPH + {0x9984, 0x520B}, //3734 #CJK UNIFIED IDEOGRAPH + {0x9985, 0x5214}, //3735 #CJK UNIFIED IDEOGRAPH + {0x9986, 0x520E}, //3736 #CJK UNIFIED IDEOGRAPH + {0x9987, 0x5227}, //3737 #CJK UNIFIED IDEOGRAPH + {0x9988, 0x522A}, //3738 #CJK UNIFIED IDEOGRAPH + {0x9989, 0x522E}, //3739 #CJK UNIFIED IDEOGRAPH + {0x998A, 0x5233}, //3740 #CJK UNIFIED IDEOGRAPH + {0x998B, 0x5239}, //3741 #CJK UNIFIED IDEOGRAPH + {0x998C, 0x524F}, //3742 #CJK UNIFIED IDEOGRAPH + {0x998D, 0x5244}, //3743 #CJK UNIFIED IDEOGRAPH + {0x998E, 0x524B}, //3744 #CJK UNIFIED IDEOGRAPH + {0x998F, 0x524C}, //3745 #CJK UNIFIED IDEOGRAPH + {0x9990, 0x525E}, //3746 #CJK UNIFIED IDEOGRAPH + {0x9991, 0x5254}, //3747 #CJK UNIFIED IDEOGRAPH + {0x9992, 0x526A}, //3748 #CJK UNIFIED IDEOGRAPH + {0x9993, 0x5274}, //3749 #CJK UNIFIED IDEOGRAPH + {0x9994, 0x5269}, //3750 #CJK UNIFIED IDEOGRAPH + {0x9995, 0x5273}, //3751 #CJK UNIFIED IDEOGRAPH + {0x9996, 0x527F}, //3752 #CJK UNIFIED IDEOGRAPH + {0x9997, 0x527D}, //3753 #CJK UNIFIED IDEOGRAPH + {0x9998, 0x528D}, //3754 #CJK UNIFIED IDEOGRAPH + {0x9999, 0x5294}, //3755 #CJK UNIFIED IDEOGRAPH + {0x999A, 0x5292}, //3756 #CJK UNIFIED IDEOGRAPH + {0x999B, 0x5271}, //3757 #CJK UNIFIED IDEOGRAPH + {0x999C, 0x5288}, //3758 #CJK UNIFIED IDEOGRAPH + {0x999D, 0x5291}, //3759 #CJK UNIFIED IDEOGRAPH + {0x999E, 0x8FA8}, //3760 #CJK UNIFIED IDEOGRAPH + {0x999F, 0x8FA7}, //3761 #CJK UNIFIED IDEOGRAPH + {0x99A0, 0x52AC}, //3762 #CJK UNIFIED IDEOGRAPH + {0x99A1, 0x52AD}, //3763 #CJK UNIFIED IDEOGRAPH + {0x99A2, 0x52BC}, //3764 #CJK UNIFIED IDEOGRAPH + {0x99A3, 0x52B5}, //3765 #CJK UNIFIED IDEOGRAPH + {0x99A4, 0x52C1}, //3766 #CJK UNIFIED IDEOGRAPH + {0x99A5, 0x52CD}, //3767 #CJK UNIFIED IDEOGRAPH + {0x99A6, 0x52D7}, //3768 #CJK UNIFIED IDEOGRAPH + {0x99A7, 0x52DE}, //3769 #CJK UNIFIED IDEOGRAPH + {0x99A8, 0x52E3}, //3770 #CJK UNIFIED IDEOGRAPH + {0x99A9, 0x52E6}, //3771 #CJK UNIFIED IDEOGRAPH + {0x99AA, 0x98ED}, //3772 #CJK UNIFIED IDEOGRAPH + {0x99AB, 0x52E0}, //3773 #CJK UNIFIED IDEOGRAPH + {0x99AC, 0x52F3}, //3774 #CJK UNIFIED IDEOGRAPH + {0x99AD, 0x52F5}, //3775 #CJK UNIFIED IDEOGRAPH + {0x99AE, 0x52F8}, //3776 #CJK UNIFIED IDEOGRAPH + {0x99AF, 0x52F9}, //3777 #CJK UNIFIED IDEOGRAPH + {0x99B0, 0x5306}, //3778 #CJK UNIFIED IDEOGRAPH + {0x99B1, 0x5308}, //3779 #CJK UNIFIED IDEOGRAPH + {0x99B2, 0x7538}, //3780 #CJK UNIFIED IDEOGRAPH + {0x99B3, 0x530D}, //3781 #CJK UNIFIED IDEOGRAPH + {0x99B4, 0x5310}, //3782 #CJK UNIFIED IDEOGRAPH + {0x99B5, 0x530F}, //3783 #CJK UNIFIED IDEOGRAPH + {0x99B6, 0x5315}, //3784 #CJK UNIFIED IDEOGRAPH + {0x99B7, 0x531A}, //3785 #CJK UNIFIED IDEOGRAPH + {0x99B8, 0x5323}, //3786 #CJK UNIFIED IDEOGRAPH + {0x99B9, 0x532F}, //3787 #CJK UNIFIED IDEOGRAPH + {0x99BA, 0x5331}, //3788 #CJK UNIFIED IDEOGRAPH + {0x99BB, 0x5333}, //3789 #CJK UNIFIED IDEOGRAPH + {0x99BC, 0x5338}, //3790 #CJK UNIFIED IDEOGRAPH + {0x99BD, 0x5340}, //3791 #CJK UNIFIED IDEOGRAPH + {0x99BE, 0x5346}, //3792 #CJK UNIFIED IDEOGRAPH + {0x99BF, 0x5345}, //3793 #CJK UNIFIED IDEOGRAPH + {0x99C0, 0x4E17}, //3794 #CJK UNIFIED IDEOGRAPH + {0x99C1, 0x5349}, //3795 #CJK UNIFIED IDEOGRAPH + {0x99C2, 0x534D}, //3796 #CJK UNIFIED IDEOGRAPH + {0x99C3, 0x51D6}, //3797 #CJK UNIFIED IDEOGRAPH + {0x99C4, 0x535E}, //3798 #CJK UNIFIED IDEOGRAPH + {0x99C5, 0x5369}, //3799 #CJK UNIFIED IDEOGRAPH + {0x99C6, 0x536E}, //3800 #CJK UNIFIED IDEOGRAPH + {0x99C7, 0x5918}, //3801 #CJK UNIFIED IDEOGRAPH + {0x99C8, 0x537B}, //3802 #CJK UNIFIED IDEOGRAPH + {0x99C9, 0x5377}, //3803 #CJK UNIFIED IDEOGRAPH + {0x99CA, 0x5382}, //3804 #CJK UNIFIED IDEOGRAPH + {0x99CB, 0x5396}, //3805 #CJK UNIFIED IDEOGRAPH + {0x99CC, 0x53A0}, //3806 #CJK UNIFIED IDEOGRAPH + {0x99CD, 0x53A6}, //3807 #CJK UNIFIED IDEOGRAPH + {0x99CE, 0x53A5}, //3808 #CJK UNIFIED IDEOGRAPH + {0x99CF, 0x53AE}, //3809 #CJK UNIFIED IDEOGRAPH + {0x99D0, 0x53B0}, //3810 #CJK UNIFIED IDEOGRAPH + {0x99D1, 0x53B6}, //3811 #CJK UNIFIED IDEOGRAPH + {0x99D2, 0x53C3}, //3812 #CJK UNIFIED IDEOGRAPH + {0x99D3, 0x7C12}, //3813 #CJK UNIFIED IDEOGRAPH + {0x99D4, 0x96D9}, //3814 #CJK UNIFIED IDEOGRAPH + {0x99D5, 0x53DF}, //3815 #CJK UNIFIED IDEOGRAPH + {0x99D6, 0x66FC}, //3816 #CJK UNIFIED IDEOGRAPH + {0x99D7, 0x71EE}, //3817 #CJK UNIFIED IDEOGRAPH + {0x99D8, 0x53EE}, //3818 #CJK UNIFIED IDEOGRAPH + {0x99D9, 0x53E8}, //3819 #CJK UNIFIED IDEOGRAPH + {0x99DA, 0x53ED}, //3820 #CJK UNIFIED IDEOGRAPH + {0x99DB, 0x53FA}, //3821 #CJK UNIFIED IDEOGRAPH + {0x99DC, 0x5401}, //3822 #CJK UNIFIED IDEOGRAPH + {0x99DD, 0x543D}, //3823 #CJK UNIFIED IDEOGRAPH + {0x99DE, 0x5440}, //3824 #CJK UNIFIED IDEOGRAPH + {0x99DF, 0x542C}, //3825 #CJK UNIFIED IDEOGRAPH + {0x99E0, 0x542D}, //3826 #CJK UNIFIED IDEOGRAPH + {0x99E1, 0x543C}, //3827 #CJK UNIFIED IDEOGRAPH + {0x99E2, 0x542E}, //3828 #CJK UNIFIED IDEOGRAPH + {0x99E3, 0x5436}, //3829 #CJK UNIFIED IDEOGRAPH + {0x99E4, 0x5429}, //3830 #CJK UNIFIED IDEOGRAPH + {0x99E5, 0x541D}, //3831 #CJK UNIFIED IDEOGRAPH + {0x99E6, 0x544E}, //3832 #CJK UNIFIED IDEOGRAPH + {0x99E7, 0x548F}, //3833 #CJK UNIFIED IDEOGRAPH + {0x99E8, 0x5475}, //3834 #CJK UNIFIED IDEOGRAPH + {0x99E9, 0x548E}, //3835 #CJK UNIFIED IDEOGRAPH + {0x99EA, 0x545F}, //3836 #CJK UNIFIED IDEOGRAPH + {0x99EB, 0x5471}, //3837 #CJK UNIFIED IDEOGRAPH + {0x99EC, 0x5477}, //3838 #CJK UNIFIED IDEOGRAPH + {0x99ED, 0x5470}, //3839 #CJK UNIFIED IDEOGRAPH + {0x99EE, 0x5492}, //3840 #CJK UNIFIED IDEOGRAPH + {0x99EF, 0x547B}, //3841 #CJK UNIFIED IDEOGRAPH + {0x99F0, 0x5480}, //3842 #CJK UNIFIED IDEOGRAPH + {0x99F1, 0x5476}, //3843 #CJK UNIFIED IDEOGRAPH + {0x99F2, 0x5484}, //3844 #CJK UNIFIED IDEOGRAPH + {0x99F3, 0x5490}, //3845 #CJK UNIFIED IDEOGRAPH + {0x99F4, 0x5486}, //3846 #CJK UNIFIED IDEOGRAPH + {0x99F5, 0x54C7}, //3847 #CJK UNIFIED IDEOGRAPH + {0x99F6, 0x54A2}, //3848 #CJK UNIFIED IDEOGRAPH + {0x99F7, 0x54B8}, //3849 #CJK UNIFIED IDEOGRAPH + {0x99F8, 0x54A5}, //3850 #CJK UNIFIED IDEOGRAPH + {0x99F9, 0x54AC}, //3851 #CJK UNIFIED IDEOGRAPH + {0x99FA, 0x54C4}, //3852 #CJK UNIFIED IDEOGRAPH + {0x99FB, 0x54C8}, //3853 #CJK UNIFIED IDEOGRAPH + {0x99FC, 0x54A8}, //3854 #CJK UNIFIED IDEOGRAPH + {0x9A40, 0x54AB}, //3855 #CJK UNIFIED IDEOGRAPH + {0x9A41, 0x54C2}, //3856 #CJK UNIFIED IDEOGRAPH + {0x9A42, 0x54A4}, //3857 #CJK UNIFIED IDEOGRAPH + {0x9A43, 0x54BE}, //3858 #CJK UNIFIED IDEOGRAPH + {0x9A44, 0x54BC}, //3859 #CJK UNIFIED IDEOGRAPH + {0x9A45, 0x54D8}, //3860 #CJK UNIFIED IDEOGRAPH + {0x9A46, 0x54E5}, //3861 #CJK UNIFIED IDEOGRAPH + {0x9A47, 0x54E6}, //3862 #CJK UNIFIED IDEOGRAPH + {0x9A48, 0x550F}, //3863 #CJK UNIFIED IDEOGRAPH + {0x9A49, 0x5514}, //3864 #CJK UNIFIED IDEOGRAPH + {0x9A4A, 0x54FD}, //3865 #CJK UNIFIED IDEOGRAPH + {0x9A4B, 0x54EE}, //3866 #CJK UNIFIED IDEOGRAPH + {0x9A4C, 0x54ED}, //3867 #CJK UNIFIED IDEOGRAPH + {0x9A4D, 0x54FA}, //3868 #CJK UNIFIED IDEOGRAPH + {0x9A4E, 0x54E2}, //3869 #CJK UNIFIED IDEOGRAPH + {0x9A4F, 0x5539}, //3870 #CJK UNIFIED IDEOGRAPH + {0x9A50, 0x5540}, //3871 #CJK UNIFIED IDEOGRAPH + {0x9A51, 0x5563}, //3872 #CJK UNIFIED IDEOGRAPH + {0x9A52, 0x554C}, //3873 #CJK UNIFIED IDEOGRAPH + {0x9A53, 0x552E}, //3874 #CJK UNIFIED IDEOGRAPH + {0x9A54, 0x555C}, //3875 #CJK UNIFIED IDEOGRAPH + {0x9A55, 0x5545}, //3876 #CJK UNIFIED IDEOGRAPH + {0x9A56, 0x5556}, //3877 #CJK UNIFIED IDEOGRAPH + {0x9A57, 0x5557}, //3878 #CJK UNIFIED IDEOGRAPH + {0x9A58, 0x5538}, //3879 #CJK UNIFIED IDEOGRAPH + {0x9A59, 0x5533}, //3880 #CJK UNIFIED IDEOGRAPH + {0x9A5A, 0x555D}, //3881 #CJK UNIFIED IDEOGRAPH + {0x9A5B, 0x5599}, //3882 #CJK UNIFIED IDEOGRAPH + {0x9A5C, 0x5580}, //3883 #CJK UNIFIED IDEOGRAPH + {0x9A5D, 0x54AF}, //3884 #CJK UNIFIED IDEOGRAPH + {0x9A5E, 0x558A}, //3885 #CJK UNIFIED IDEOGRAPH + {0x9A5F, 0x559F}, //3886 #CJK UNIFIED IDEOGRAPH + {0x9A60, 0x557B}, //3887 #CJK UNIFIED IDEOGRAPH + {0x9A61, 0x557E}, //3888 #CJK UNIFIED IDEOGRAPH + {0x9A62, 0x5598}, //3889 #CJK UNIFIED IDEOGRAPH + {0x9A63, 0x559E}, //3890 #CJK UNIFIED IDEOGRAPH + {0x9A64, 0x55AE}, //3891 #CJK UNIFIED IDEOGRAPH + {0x9A65, 0x557C}, //3892 #CJK UNIFIED IDEOGRAPH + {0x9A66, 0x5583}, //3893 #CJK UNIFIED IDEOGRAPH + {0x9A67, 0x55A9}, //3894 #CJK UNIFIED IDEOGRAPH + {0x9A68, 0x5587}, //3895 #CJK UNIFIED IDEOGRAPH + {0x9A69, 0x55A8}, //3896 #CJK UNIFIED IDEOGRAPH + {0x9A6A, 0x55DA}, //3897 #CJK UNIFIED IDEOGRAPH + {0x9A6B, 0x55C5}, //3898 #CJK UNIFIED IDEOGRAPH + {0x9A6C, 0x55DF}, //3899 #CJK UNIFIED IDEOGRAPH + {0x9A6D, 0x55C4}, //3900 #CJK UNIFIED IDEOGRAPH + {0x9A6E, 0x55DC}, //3901 #CJK UNIFIED IDEOGRAPH + {0x9A6F, 0x55E4}, //3902 #CJK UNIFIED IDEOGRAPH + {0x9A70, 0x55D4}, //3903 #CJK UNIFIED IDEOGRAPH + {0x9A71, 0x5614}, //3904 #CJK UNIFIED IDEOGRAPH + {0x9A72, 0x55F7}, //3905 #CJK UNIFIED IDEOGRAPH + {0x9A73, 0x5616}, //3906 #CJK UNIFIED IDEOGRAPH + {0x9A74, 0x55FE}, //3907 #CJK UNIFIED IDEOGRAPH + {0x9A75, 0x55FD}, //3908 #CJK UNIFIED IDEOGRAPH + {0x9A76, 0x561B}, //3909 #CJK UNIFIED IDEOGRAPH + {0x9A77, 0x55F9}, //3910 #CJK UNIFIED IDEOGRAPH + {0x9A78, 0x564E}, //3911 #CJK UNIFIED IDEOGRAPH + {0x9A79, 0x5650}, //3912 #CJK UNIFIED IDEOGRAPH + {0x9A7A, 0x71DF}, //3913 #CJK UNIFIED IDEOGRAPH + {0x9A7B, 0x5634}, //3914 #CJK UNIFIED IDEOGRAPH + {0x9A7C, 0x5636}, //3915 #CJK UNIFIED IDEOGRAPH + {0x9A7D, 0x5632}, //3916 #CJK UNIFIED IDEOGRAPH + {0x9A7E, 0x5638}, //3917 #CJK UNIFIED IDEOGRAPH + {0x9A80, 0x566B}, //3918 #CJK UNIFIED IDEOGRAPH + {0x9A81, 0x5664}, //3919 #CJK UNIFIED IDEOGRAPH + {0x9A82, 0x562F}, //3920 #CJK UNIFIED IDEOGRAPH + {0x9A83, 0x566C}, //3921 #CJK UNIFIED IDEOGRAPH + {0x9A84, 0x566A}, //3922 #CJK UNIFIED IDEOGRAPH + {0x9A85, 0x5686}, //3923 #CJK UNIFIED IDEOGRAPH + {0x9A86, 0x5680}, //3924 #CJK UNIFIED IDEOGRAPH + {0x9A87, 0x568A}, //3925 #CJK UNIFIED IDEOGRAPH + {0x9A88, 0x56A0}, //3926 #CJK UNIFIED IDEOGRAPH + {0x9A89, 0x5694}, //3927 #CJK UNIFIED IDEOGRAPH + {0x9A8A, 0x568F}, //3928 #CJK UNIFIED IDEOGRAPH + {0x9A8B, 0x56A5}, //3929 #CJK UNIFIED IDEOGRAPH + {0x9A8C, 0x56AE}, //3930 #CJK UNIFIED IDEOGRAPH + {0x9A8D, 0x56B6}, //3931 #CJK UNIFIED IDEOGRAPH + {0x9A8E, 0x56B4}, //3932 #CJK UNIFIED IDEOGRAPH + {0x9A8F, 0x56C2}, //3933 #CJK UNIFIED IDEOGRAPH + {0x9A90, 0x56BC}, //3934 #CJK UNIFIED IDEOGRAPH + {0x9A91, 0x56C1}, //3935 #CJK UNIFIED IDEOGRAPH + {0x9A92, 0x56C3}, //3936 #CJK UNIFIED IDEOGRAPH + {0x9A93, 0x56C0}, //3937 #CJK UNIFIED IDEOGRAPH + {0x9A94, 0x56C8}, //3938 #CJK UNIFIED IDEOGRAPH + {0x9A95, 0x56CE}, //3939 #CJK UNIFIED IDEOGRAPH + {0x9A96, 0x56D1}, //3940 #CJK UNIFIED IDEOGRAPH + {0x9A97, 0x56D3}, //3941 #CJK UNIFIED IDEOGRAPH + {0x9A98, 0x56D7}, //3942 #CJK UNIFIED IDEOGRAPH + {0x9A99, 0x56EE}, //3943 #CJK UNIFIED IDEOGRAPH + {0x9A9A, 0x56F9}, //3944 #CJK UNIFIED IDEOGRAPH + {0x9A9B, 0x5700}, //3945 #CJK UNIFIED IDEOGRAPH + {0x9A9C, 0x56FF}, //3946 #CJK UNIFIED IDEOGRAPH + {0x9A9D, 0x5704}, //3947 #CJK UNIFIED IDEOGRAPH + {0x9A9E, 0x5709}, //3948 #CJK UNIFIED IDEOGRAPH + {0x9A9F, 0x5708}, //3949 #CJK UNIFIED IDEOGRAPH + {0x9AA0, 0x570B}, //3950 #CJK UNIFIED IDEOGRAPH + {0x9AA1, 0x570D}, //3951 #CJK UNIFIED IDEOGRAPH + {0x9AA2, 0x5713}, //3952 #CJK UNIFIED IDEOGRAPH + {0x9AA3, 0x5718}, //3953 #CJK UNIFIED IDEOGRAPH + {0x9AA4, 0x5716}, //3954 #CJK UNIFIED IDEOGRAPH + {0x9AA5, 0x55C7}, //3955 #CJK UNIFIED IDEOGRAPH + {0x9AA6, 0x571C}, //3956 #CJK UNIFIED IDEOGRAPH + {0x9AA7, 0x5726}, //3957 #CJK UNIFIED IDEOGRAPH + {0x9AA8, 0x5737}, //3958 #CJK UNIFIED IDEOGRAPH + {0x9AA9, 0x5738}, //3959 #CJK UNIFIED IDEOGRAPH + {0x9AAA, 0x574E}, //3960 #CJK UNIFIED IDEOGRAPH + {0x9AAB, 0x573B}, //3961 #CJK UNIFIED IDEOGRAPH + {0x9AAC, 0x5740}, //3962 #CJK UNIFIED IDEOGRAPH + {0x9AAD, 0x574F}, //3963 #CJK UNIFIED IDEOGRAPH + {0x9AAE, 0x5769}, //3964 #CJK UNIFIED IDEOGRAPH + {0x9AAF, 0x57C0}, //3965 #CJK UNIFIED IDEOGRAPH + {0x9AB0, 0x5788}, //3966 #CJK UNIFIED IDEOGRAPH + {0x9AB1, 0x5761}, //3967 #CJK UNIFIED IDEOGRAPH + {0x9AB2, 0x577F}, //3968 #CJK UNIFIED IDEOGRAPH + {0x9AB3, 0x5789}, //3969 #CJK UNIFIED IDEOGRAPH + {0x9AB4, 0x5793}, //3970 #CJK UNIFIED IDEOGRAPH + {0x9AB5, 0x57A0}, //3971 #CJK UNIFIED IDEOGRAPH + {0x9AB6, 0x57B3}, //3972 #CJK UNIFIED IDEOGRAPH + {0x9AB7, 0x57A4}, //3973 #CJK UNIFIED IDEOGRAPH + {0x9AB8, 0x57AA}, //3974 #CJK UNIFIED IDEOGRAPH + {0x9AB9, 0x57B0}, //3975 #CJK UNIFIED IDEOGRAPH + {0x9ABA, 0x57C3}, //3976 #CJK UNIFIED IDEOGRAPH + {0x9ABB, 0x57C6}, //3977 #CJK UNIFIED IDEOGRAPH + {0x9ABC, 0x57D4}, //3978 #CJK UNIFIED IDEOGRAPH + {0x9ABD, 0x57D2}, //3979 #CJK UNIFIED IDEOGRAPH + {0x9ABE, 0x57D3}, //3980 #CJK UNIFIED IDEOGRAPH + {0x9ABF, 0x580A}, //3981 #CJK UNIFIED IDEOGRAPH + {0x9AC0, 0x57D6}, //3982 #CJK UNIFIED IDEOGRAPH + {0x9AC1, 0x57E3}, //3983 #CJK UNIFIED IDEOGRAPH + {0x9AC2, 0x580B}, //3984 #CJK UNIFIED IDEOGRAPH + {0x9AC3, 0x5819}, //3985 #CJK UNIFIED IDEOGRAPH + {0x9AC4, 0x581D}, //3986 #CJK UNIFIED IDEOGRAPH + {0x9AC5, 0x5872}, //3987 #CJK UNIFIED IDEOGRAPH + {0x9AC6, 0x5821}, //3988 #CJK UNIFIED IDEOGRAPH + {0x9AC7, 0x5862}, //3989 #CJK UNIFIED IDEOGRAPH + {0x9AC8, 0x584B}, //3990 #CJK UNIFIED IDEOGRAPH + {0x9AC9, 0x5870}, //3991 #CJK UNIFIED IDEOGRAPH + {0x9ACA, 0x6BC0}, //3992 #CJK UNIFIED IDEOGRAPH + {0x9ACB, 0x5852}, //3993 #CJK UNIFIED IDEOGRAPH + {0x9ACC, 0x583D}, //3994 #CJK UNIFIED IDEOGRAPH + {0x9ACD, 0x5879}, //3995 #CJK UNIFIED IDEOGRAPH + {0x9ACE, 0x5885}, //3996 #CJK UNIFIED IDEOGRAPH + {0x9ACF, 0x58B9}, //3997 #CJK UNIFIED IDEOGRAPH + {0x9AD0, 0x589F}, //3998 #CJK UNIFIED IDEOGRAPH + {0x9AD1, 0x58AB}, //3999 #CJK UNIFIED IDEOGRAPH + {0x9AD2, 0x58BA}, //4000 #CJK UNIFIED IDEOGRAPH + {0x9AD3, 0x58DE}, //4001 #CJK UNIFIED IDEOGRAPH + {0x9AD4, 0x58BB}, //4002 #CJK UNIFIED IDEOGRAPH + {0x9AD5, 0x58B8}, //4003 #CJK UNIFIED IDEOGRAPH + {0x9AD6, 0x58AE}, //4004 #CJK UNIFIED IDEOGRAPH + {0x9AD7, 0x58C5}, //4005 #CJK UNIFIED IDEOGRAPH + {0x9AD8, 0x58D3}, //4006 #CJK UNIFIED IDEOGRAPH + {0x9AD9, 0x58D1}, //4007 #CJK UNIFIED IDEOGRAPH + {0x9ADA, 0x58D7}, //4008 #CJK UNIFIED IDEOGRAPH + {0x9ADB, 0x58D9}, //4009 #CJK UNIFIED IDEOGRAPH + {0x9ADC, 0x58D8}, //4010 #CJK UNIFIED IDEOGRAPH + {0x9ADD, 0x58E5}, //4011 #CJK UNIFIED IDEOGRAPH + {0x9ADE, 0x58DC}, //4012 #CJK UNIFIED IDEOGRAPH + {0x9ADF, 0x58E4}, //4013 #CJK UNIFIED IDEOGRAPH + {0x9AE0, 0x58DF}, //4014 #CJK UNIFIED IDEOGRAPH + {0x9AE1, 0x58EF}, //4015 #CJK UNIFIED IDEOGRAPH + {0x9AE2, 0x58FA}, //4016 #CJK UNIFIED IDEOGRAPH + {0x9AE3, 0x58F9}, //4017 #CJK UNIFIED IDEOGRAPH + {0x9AE4, 0x58FB}, //4018 #CJK UNIFIED IDEOGRAPH + {0x9AE5, 0x58FC}, //4019 #CJK UNIFIED IDEOGRAPH + {0x9AE6, 0x58FD}, //4020 #CJK UNIFIED IDEOGRAPH + {0x9AE7, 0x5902}, //4021 #CJK UNIFIED IDEOGRAPH + {0x9AE8, 0x590A}, //4022 #CJK UNIFIED IDEOGRAPH + {0x9AE9, 0x5910}, //4023 #CJK UNIFIED IDEOGRAPH + {0x9AEA, 0x591B}, //4024 #CJK UNIFIED IDEOGRAPH + {0x9AEB, 0x68A6}, //4025 #CJK UNIFIED IDEOGRAPH + {0x9AEC, 0x5925}, //4026 #CJK UNIFIED IDEOGRAPH + {0x9AED, 0x592C}, //4027 #CJK UNIFIED IDEOGRAPH + {0x9AEE, 0x592D}, //4028 #CJK UNIFIED IDEOGRAPH + {0x9AEF, 0x5932}, //4029 #CJK UNIFIED IDEOGRAPH + {0x9AF0, 0x5938}, //4030 #CJK UNIFIED IDEOGRAPH + {0x9AF1, 0x593E}, //4031 #CJK UNIFIED IDEOGRAPH + {0x9AF2, 0x7AD2}, //4032 #CJK UNIFIED IDEOGRAPH + {0x9AF3, 0x5955}, //4033 #CJK UNIFIED IDEOGRAPH + {0x9AF4, 0x5950}, //4034 #CJK UNIFIED IDEOGRAPH + {0x9AF5, 0x594E}, //4035 #CJK UNIFIED IDEOGRAPH + {0x9AF6, 0x595A}, //4036 #CJK UNIFIED IDEOGRAPH + {0x9AF7, 0x5958}, //4037 #CJK UNIFIED IDEOGRAPH + {0x9AF8, 0x5962}, //4038 #CJK UNIFIED IDEOGRAPH + {0x9AF9, 0x5960}, //4039 #CJK UNIFIED IDEOGRAPH + {0x9AFA, 0x5967}, //4040 #CJK UNIFIED IDEOGRAPH + {0x9AFB, 0x596C}, //4041 #CJK UNIFIED IDEOGRAPH + {0x9AFC, 0x5969}, //4042 #CJK UNIFIED IDEOGRAPH + {0x9B40, 0x5978}, //4043 #CJK UNIFIED IDEOGRAPH + {0x9B41, 0x5981}, //4044 #CJK UNIFIED IDEOGRAPH + {0x9B42, 0x599D}, //4045 #CJK UNIFIED IDEOGRAPH + {0x9B43, 0x4F5E}, //4046 #CJK UNIFIED IDEOGRAPH + {0x9B44, 0x4FAB}, //4047 #CJK UNIFIED IDEOGRAPH + {0x9B45, 0x59A3}, //4048 #CJK UNIFIED IDEOGRAPH + {0x9B46, 0x59B2}, //4049 #CJK UNIFIED IDEOGRAPH + {0x9B47, 0x59C6}, //4050 #CJK UNIFIED IDEOGRAPH + {0x9B48, 0x59E8}, //4051 #CJK UNIFIED IDEOGRAPH + {0x9B49, 0x59DC}, //4052 #CJK UNIFIED IDEOGRAPH + {0x9B4A, 0x598D}, //4053 #CJK UNIFIED IDEOGRAPH + {0x9B4B, 0x59D9}, //4054 #CJK UNIFIED IDEOGRAPH + {0x9B4C, 0x59DA}, //4055 #CJK UNIFIED IDEOGRAPH + {0x9B4D, 0x5A25}, //4056 #CJK UNIFIED IDEOGRAPH + {0x9B4E, 0x5A1F}, //4057 #CJK UNIFIED IDEOGRAPH + {0x9B4F, 0x5A11}, //4058 #CJK UNIFIED IDEOGRAPH + {0x9B50, 0x5A1C}, //4059 #CJK UNIFIED IDEOGRAPH + {0x9B51, 0x5A09}, //4060 #CJK UNIFIED IDEOGRAPH + {0x9B52, 0x5A1A}, //4061 #CJK UNIFIED IDEOGRAPH + {0x9B53, 0x5A40}, //4062 #CJK UNIFIED IDEOGRAPH + {0x9B54, 0x5A6C}, //4063 #CJK UNIFIED IDEOGRAPH + {0x9B55, 0x5A49}, //4064 #CJK UNIFIED IDEOGRAPH + {0x9B56, 0x5A35}, //4065 #CJK UNIFIED IDEOGRAPH + {0x9B57, 0x5A36}, //4066 #CJK UNIFIED IDEOGRAPH + {0x9B58, 0x5A62}, //4067 #CJK UNIFIED IDEOGRAPH + {0x9B59, 0x5A6A}, //4068 #CJK UNIFIED IDEOGRAPH + {0x9B5A, 0x5A9A}, //4069 #CJK UNIFIED IDEOGRAPH + {0x9B5B, 0x5ABC}, //4070 #CJK UNIFIED IDEOGRAPH + {0x9B5C, 0x5ABE}, //4071 #CJK UNIFIED IDEOGRAPH + {0x9B5D, 0x5ACB}, //4072 #CJK UNIFIED IDEOGRAPH + {0x9B5E, 0x5AC2}, //4073 #CJK UNIFIED IDEOGRAPH + {0x9B5F, 0x5ABD}, //4074 #CJK UNIFIED IDEOGRAPH + {0x9B60, 0x5AE3}, //4075 #CJK UNIFIED IDEOGRAPH + {0x9B61, 0x5AD7}, //4076 #CJK UNIFIED IDEOGRAPH + {0x9B62, 0x5AE6}, //4077 #CJK UNIFIED IDEOGRAPH + {0x9B63, 0x5AE9}, //4078 #CJK UNIFIED IDEOGRAPH + {0x9B64, 0x5AD6}, //4079 #CJK UNIFIED IDEOGRAPH + {0x9B65, 0x5AFA}, //4080 #CJK UNIFIED IDEOGRAPH + {0x9B66, 0x5AFB}, //4081 #CJK UNIFIED IDEOGRAPH + {0x9B67, 0x5B0C}, //4082 #CJK UNIFIED IDEOGRAPH + {0x9B68, 0x5B0B}, //4083 #CJK UNIFIED IDEOGRAPH + {0x9B69, 0x5B16}, //4084 #CJK UNIFIED IDEOGRAPH + {0x9B6A, 0x5B32}, //4085 #CJK UNIFIED IDEOGRAPH + {0x9B6B, 0x5AD0}, //4086 #CJK UNIFIED IDEOGRAPH + {0x9B6C, 0x5B2A}, //4087 #CJK UNIFIED IDEOGRAPH + {0x9B6D, 0x5B36}, //4088 #CJK UNIFIED IDEOGRAPH + {0x9B6E, 0x5B3E}, //4089 #CJK UNIFIED IDEOGRAPH + {0x9B6F, 0x5B43}, //4090 #CJK UNIFIED IDEOGRAPH + {0x9B70, 0x5B45}, //4091 #CJK UNIFIED IDEOGRAPH + {0x9B71, 0x5B40}, //4092 #CJK UNIFIED IDEOGRAPH + {0x9B72, 0x5B51}, //4093 #CJK UNIFIED IDEOGRAPH + {0x9B73, 0x5B55}, //4094 #CJK UNIFIED IDEOGRAPH + {0x9B74, 0x5B5A}, //4095 #CJK UNIFIED IDEOGRAPH + {0x9B75, 0x5B5B}, //4096 #CJK UNIFIED IDEOGRAPH + {0x9B76, 0x5B65}, //4097 #CJK UNIFIED IDEOGRAPH + {0x9B77, 0x5B69}, //4098 #CJK UNIFIED IDEOGRAPH + {0x9B78, 0x5B70}, //4099 #CJK UNIFIED IDEOGRAPH + {0x9B79, 0x5B73}, //4100 #CJK UNIFIED IDEOGRAPH + {0x9B7A, 0x5B75}, //4101 #CJK UNIFIED IDEOGRAPH + {0x9B7B, 0x5B78}, //4102 #CJK UNIFIED IDEOGRAPH + {0x9B7C, 0x6588}, //4103 #CJK UNIFIED IDEOGRAPH + {0x9B7D, 0x5B7A}, //4104 #CJK UNIFIED IDEOGRAPH + {0x9B7E, 0x5B80}, //4105 #CJK UNIFIED IDEOGRAPH + {0x9B80, 0x5B83}, //4106 #CJK UNIFIED IDEOGRAPH + {0x9B81, 0x5BA6}, //4107 #CJK UNIFIED IDEOGRAPH + {0x9B82, 0x5BB8}, //4108 #CJK UNIFIED IDEOGRAPH + {0x9B83, 0x5BC3}, //4109 #CJK UNIFIED IDEOGRAPH + {0x9B84, 0x5BC7}, //4110 #CJK UNIFIED IDEOGRAPH + {0x9B85, 0x5BC9}, //4111 #CJK UNIFIED IDEOGRAPH + {0x9B86, 0x5BD4}, //4112 #CJK UNIFIED IDEOGRAPH + {0x9B87, 0x5BD0}, //4113 #CJK UNIFIED IDEOGRAPH + {0x9B88, 0x5BE4}, //4114 #CJK UNIFIED IDEOGRAPH + {0x9B89, 0x5BE6}, //4115 #CJK UNIFIED IDEOGRAPH + {0x9B8A, 0x5BE2}, //4116 #CJK UNIFIED IDEOGRAPH + {0x9B8B, 0x5BDE}, //4117 #CJK UNIFIED IDEOGRAPH + {0x9B8C, 0x5BE5}, //4118 #CJK UNIFIED IDEOGRAPH + {0x9B8D, 0x5BEB}, //4119 #CJK UNIFIED IDEOGRAPH + {0x9B8E, 0x5BF0}, //4120 #CJK UNIFIED IDEOGRAPH + {0x9B8F, 0x5BF6}, //4121 #CJK UNIFIED IDEOGRAPH + {0x9B90, 0x5BF3}, //4122 #CJK UNIFIED IDEOGRAPH + {0x9B91, 0x5C05}, //4123 #CJK UNIFIED IDEOGRAPH + {0x9B92, 0x5C07}, //4124 #CJK UNIFIED IDEOGRAPH + {0x9B93, 0x5C08}, //4125 #CJK UNIFIED IDEOGRAPH + {0x9B94, 0x5C0D}, //4126 #CJK UNIFIED IDEOGRAPH + {0x9B95, 0x5C13}, //4127 #CJK UNIFIED IDEOGRAPH + {0x9B96, 0x5C20}, //4128 #CJK UNIFIED IDEOGRAPH + {0x9B97, 0x5C22}, //4129 #CJK UNIFIED IDEOGRAPH + {0x9B98, 0x5C28}, //4130 #CJK UNIFIED IDEOGRAPH + {0x9B99, 0x5C38}, //4131 #CJK UNIFIED IDEOGRAPH + {0x9B9A, 0x5C39}, //4132 #CJK UNIFIED IDEOGRAPH + {0x9B9B, 0x5C41}, //4133 #CJK UNIFIED IDEOGRAPH + {0x9B9C, 0x5C46}, //4134 #CJK UNIFIED IDEOGRAPH + {0x9B9D, 0x5C4E}, //4135 #CJK UNIFIED IDEOGRAPH + {0x9B9E, 0x5C53}, //4136 #CJK UNIFIED IDEOGRAPH + {0x9B9F, 0x5C50}, //4137 #CJK UNIFIED IDEOGRAPH + {0x9BA0, 0x5C4F}, //4138 #CJK UNIFIED IDEOGRAPH + {0x9BA1, 0x5B71}, //4139 #CJK UNIFIED IDEOGRAPH + {0x9BA2, 0x5C6C}, //4140 #CJK UNIFIED IDEOGRAPH + {0x9BA3, 0x5C6E}, //4141 #CJK UNIFIED IDEOGRAPH + {0x9BA4, 0x4E62}, //4142 #CJK UNIFIED IDEOGRAPH + {0x9BA5, 0x5C76}, //4143 #CJK UNIFIED IDEOGRAPH + {0x9BA6, 0x5C79}, //4144 #CJK UNIFIED IDEOGRAPH + {0x9BA7, 0x5C8C}, //4145 #CJK UNIFIED IDEOGRAPH + {0x9BA8, 0x5C91}, //4146 #CJK UNIFIED IDEOGRAPH + {0x9BA9, 0x5C94}, //4147 #CJK UNIFIED IDEOGRAPH + {0x9BAA, 0x599B}, //4148 #CJK UNIFIED IDEOGRAPH + {0x9BAB, 0x5CAB}, //4149 #CJK UNIFIED IDEOGRAPH + {0x9BAC, 0x5CBB}, //4150 #CJK UNIFIED IDEOGRAPH + {0x9BAD, 0x5CB6}, //4151 #CJK UNIFIED IDEOGRAPH + {0x9BAE, 0x5CBC}, //4152 #CJK UNIFIED IDEOGRAPH + {0x9BAF, 0x5CB7}, //4153 #CJK UNIFIED IDEOGRAPH + {0x9BB0, 0x5CC5}, //4154 #CJK UNIFIED IDEOGRAPH + {0x9BB1, 0x5CBE}, //4155 #CJK UNIFIED IDEOGRAPH + {0x9BB2, 0x5CC7}, //4156 #CJK UNIFIED IDEOGRAPH + {0x9BB3, 0x5CD9}, //4157 #CJK UNIFIED IDEOGRAPH + {0x9BB4, 0x5CE9}, //4158 #CJK UNIFIED IDEOGRAPH + {0x9BB5, 0x5CFD}, //4159 #CJK UNIFIED IDEOGRAPH + {0x9BB6, 0x5CFA}, //4160 #CJK UNIFIED IDEOGRAPH + {0x9BB7, 0x5CED}, //4161 #CJK UNIFIED IDEOGRAPH + {0x9BB8, 0x5D8C}, //4162 #CJK UNIFIED IDEOGRAPH + {0x9BB9, 0x5CEA}, //4163 #CJK UNIFIED IDEOGRAPH + {0x9BBA, 0x5D0B}, //4164 #CJK UNIFIED IDEOGRAPH + {0x9BBB, 0x5D15}, //4165 #CJK UNIFIED IDEOGRAPH + {0x9BBC, 0x5D17}, //4166 #CJK UNIFIED IDEOGRAPH + {0x9BBD, 0x5D5C}, //4167 #CJK UNIFIED IDEOGRAPH + {0x9BBE, 0x5D1F}, //4168 #CJK UNIFIED IDEOGRAPH + {0x9BBF, 0x5D1B}, //4169 #CJK UNIFIED IDEOGRAPH + {0x9BC0, 0x5D11}, //4170 #CJK UNIFIED IDEOGRAPH + {0x9BC1, 0x5D14}, //4171 #CJK UNIFIED IDEOGRAPH + {0x9BC2, 0x5D22}, //4172 #CJK UNIFIED IDEOGRAPH + {0x9BC3, 0x5D1A}, //4173 #CJK UNIFIED IDEOGRAPH + {0x9BC4, 0x5D19}, //4174 #CJK UNIFIED IDEOGRAPH + {0x9BC5, 0x5D18}, //4175 #CJK UNIFIED IDEOGRAPH + {0x9BC6, 0x5D4C}, //4176 #CJK UNIFIED IDEOGRAPH + {0x9BC7, 0x5D52}, //4177 #CJK UNIFIED IDEOGRAPH + {0x9BC8, 0x5D4E}, //4178 #CJK UNIFIED IDEOGRAPH + {0x9BC9, 0x5D4B}, //4179 #CJK UNIFIED IDEOGRAPH + {0x9BCA, 0x5D6C}, //4180 #CJK UNIFIED IDEOGRAPH + {0x9BCB, 0x5D73}, //4181 #CJK UNIFIED IDEOGRAPH + {0x9BCC, 0x5D76}, //4182 #CJK UNIFIED IDEOGRAPH + {0x9BCD, 0x5D87}, //4183 #CJK UNIFIED IDEOGRAPH + {0x9BCE, 0x5D84}, //4184 #CJK UNIFIED IDEOGRAPH + {0x9BCF, 0x5D82}, //4185 #CJK UNIFIED IDEOGRAPH + {0x9BD0, 0x5DA2}, //4186 #CJK UNIFIED IDEOGRAPH + {0x9BD1, 0x5D9D}, //4187 #CJK UNIFIED IDEOGRAPH + {0x9BD2, 0x5DAC}, //4188 #CJK UNIFIED IDEOGRAPH + {0x9BD3, 0x5DAE}, //4189 #CJK UNIFIED IDEOGRAPH + {0x9BD4, 0x5DBD}, //4190 #CJK UNIFIED IDEOGRAPH + {0x9BD5, 0x5D90}, //4191 #CJK UNIFIED IDEOGRAPH + {0x9BD6, 0x5DB7}, //4192 #CJK UNIFIED IDEOGRAPH + {0x9BD7, 0x5DBC}, //4193 #CJK UNIFIED IDEOGRAPH + {0x9BD8, 0x5DC9}, //4194 #CJK UNIFIED IDEOGRAPH + {0x9BD9, 0x5DCD}, //4195 #CJK UNIFIED IDEOGRAPH + {0x9BDA, 0x5DD3}, //4196 #CJK UNIFIED IDEOGRAPH + {0x9BDB, 0x5DD2}, //4197 #CJK UNIFIED IDEOGRAPH + {0x9BDC, 0x5DD6}, //4198 #CJK UNIFIED IDEOGRAPH + {0x9BDD, 0x5DDB}, //4199 #CJK UNIFIED IDEOGRAPH + {0x9BDE, 0x5DEB}, //4200 #CJK UNIFIED IDEOGRAPH + {0x9BDF, 0x5DF2}, //4201 #CJK UNIFIED IDEOGRAPH + {0x9BE0, 0x5DF5}, //4202 #CJK UNIFIED IDEOGRAPH + {0x9BE1, 0x5E0B}, //4203 #CJK UNIFIED IDEOGRAPH + {0x9BE2, 0x5E1A}, //4204 #CJK UNIFIED IDEOGRAPH + {0x9BE3, 0x5E19}, //4205 #CJK UNIFIED IDEOGRAPH + {0x9BE4, 0x5E11}, //4206 #CJK UNIFIED IDEOGRAPH + {0x9BE5, 0x5E1B}, //4207 #CJK UNIFIED IDEOGRAPH + {0x9BE6, 0x5E36}, //4208 #CJK UNIFIED IDEOGRAPH + {0x9BE7, 0x5E37}, //4209 #CJK UNIFIED IDEOGRAPH + {0x9BE8, 0x5E44}, //4210 #CJK UNIFIED IDEOGRAPH + {0x9BE9, 0x5E43}, //4211 #CJK UNIFIED IDEOGRAPH + {0x9BEA, 0x5E40}, //4212 #CJK UNIFIED IDEOGRAPH + {0x9BEB, 0x5E4E}, //4213 #CJK UNIFIED IDEOGRAPH + {0x9BEC, 0x5E57}, //4214 #CJK UNIFIED IDEOGRAPH + {0x9BED, 0x5E54}, //4215 #CJK UNIFIED IDEOGRAPH + {0x9BEE, 0x5E5F}, //4216 #CJK UNIFIED IDEOGRAPH + {0x9BEF, 0x5E62}, //4217 #CJK UNIFIED IDEOGRAPH + {0x9BF0, 0x5E64}, //4218 #CJK UNIFIED IDEOGRAPH + {0x9BF1, 0x5E47}, //4219 #CJK UNIFIED IDEOGRAPH + {0x9BF2, 0x5E75}, //4220 #CJK UNIFIED IDEOGRAPH + {0x9BF3, 0x5E76}, //4221 #CJK UNIFIED IDEOGRAPH + {0x9BF4, 0x5E7A}, //4222 #CJK UNIFIED IDEOGRAPH + {0x9BF5, 0x9EBC}, //4223 #CJK UNIFIED IDEOGRAPH + {0x9BF6, 0x5E7F}, //4224 #CJK UNIFIED IDEOGRAPH + {0x9BF7, 0x5EA0}, //4225 #CJK UNIFIED IDEOGRAPH + {0x9BF8, 0x5EC1}, //4226 #CJK UNIFIED IDEOGRAPH + {0x9BF9, 0x5EC2}, //4227 #CJK UNIFIED IDEOGRAPH + {0x9BFA, 0x5EC8}, //4228 #CJK UNIFIED IDEOGRAPH + {0x9BFB, 0x5ED0}, //4229 #CJK UNIFIED IDEOGRAPH + {0x9BFC, 0x5ECF}, //4230 #CJK UNIFIED IDEOGRAPH + {0x9C40, 0x5ED6}, //4231 #CJK UNIFIED IDEOGRAPH + {0x9C41, 0x5EE3}, //4232 #CJK UNIFIED IDEOGRAPH + {0x9C42, 0x5EDD}, //4233 #CJK UNIFIED IDEOGRAPH + {0x9C43, 0x5EDA}, //4234 #CJK UNIFIED IDEOGRAPH + {0x9C44, 0x5EDB}, //4235 #CJK UNIFIED IDEOGRAPH + {0x9C45, 0x5EE2}, //4236 #CJK UNIFIED IDEOGRAPH + {0x9C46, 0x5EE1}, //4237 #CJK UNIFIED IDEOGRAPH + {0x9C47, 0x5EE8}, //4238 #CJK UNIFIED IDEOGRAPH + {0x9C48, 0x5EE9}, //4239 #CJK UNIFIED IDEOGRAPH + {0x9C49, 0x5EEC}, //4240 #CJK UNIFIED IDEOGRAPH + {0x9C4A, 0x5EF1}, //4241 #CJK UNIFIED IDEOGRAPH + {0x9C4B, 0x5EF3}, //4242 #CJK UNIFIED IDEOGRAPH + {0x9C4C, 0x5EF0}, //4243 #CJK UNIFIED IDEOGRAPH + {0x9C4D, 0x5EF4}, //4244 #CJK UNIFIED IDEOGRAPH + {0x9C4E, 0x5EF8}, //4245 #CJK UNIFIED IDEOGRAPH + {0x9C4F, 0x5EFE}, //4246 #CJK UNIFIED IDEOGRAPH + {0x9C50, 0x5F03}, //4247 #CJK UNIFIED IDEOGRAPH + {0x9C51, 0x5F09}, //4248 #CJK UNIFIED IDEOGRAPH + {0x9C52, 0x5F5D}, //4249 #CJK UNIFIED IDEOGRAPH + {0x9C53, 0x5F5C}, //4250 #CJK UNIFIED IDEOGRAPH + {0x9C54, 0x5F0B}, //4251 #CJK UNIFIED IDEOGRAPH + {0x9C55, 0x5F11}, //4252 #CJK UNIFIED IDEOGRAPH + {0x9C56, 0x5F16}, //4253 #CJK UNIFIED IDEOGRAPH + {0x9C57, 0x5F29}, //4254 #CJK UNIFIED IDEOGRAPH + {0x9C58, 0x5F2D}, //4255 #CJK UNIFIED IDEOGRAPH + {0x9C59, 0x5F38}, //4256 #CJK UNIFIED IDEOGRAPH + {0x9C5A, 0x5F41}, //4257 #CJK UNIFIED IDEOGRAPH + {0x9C5B, 0x5F48}, //4258 #CJK UNIFIED IDEOGRAPH + {0x9C5C, 0x5F4C}, //4259 #CJK UNIFIED IDEOGRAPH + {0x9C5D, 0x5F4E}, //4260 #CJK UNIFIED IDEOGRAPH + {0x9C5E, 0x5F2F}, //4261 #CJK UNIFIED IDEOGRAPH + {0x9C5F, 0x5F51}, //4262 #CJK UNIFIED IDEOGRAPH + {0x9C60, 0x5F56}, //4263 #CJK UNIFIED IDEOGRAPH + {0x9C61, 0x5F57}, //4264 #CJK UNIFIED IDEOGRAPH + {0x9C62, 0x5F59}, //4265 #CJK UNIFIED IDEOGRAPH + {0x9C63, 0x5F61}, //4266 #CJK UNIFIED IDEOGRAPH + {0x9C64, 0x5F6D}, //4267 #CJK UNIFIED IDEOGRAPH + {0x9C65, 0x5F73}, //4268 #CJK UNIFIED IDEOGRAPH + {0x9C66, 0x5F77}, //4269 #CJK UNIFIED IDEOGRAPH + {0x9C67, 0x5F83}, //4270 #CJK UNIFIED IDEOGRAPH + {0x9C68, 0x5F82}, //4271 #CJK UNIFIED IDEOGRAPH + {0x9C69, 0x5F7F}, //4272 #CJK UNIFIED IDEOGRAPH + {0x9C6A, 0x5F8A}, //4273 #CJK UNIFIED IDEOGRAPH + {0x9C6B, 0x5F88}, //4274 #CJK UNIFIED IDEOGRAPH + {0x9C6C, 0x5F91}, //4275 #CJK UNIFIED IDEOGRAPH + {0x9C6D, 0x5F87}, //4276 #CJK UNIFIED IDEOGRAPH + {0x9C6E, 0x5F9E}, //4277 #CJK UNIFIED IDEOGRAPH + {0x9C6F, 0x5F99}, //4278 #CJK UNIFIED IDEOGRAPH + {0x9C70, 0x5F98}, //4279 #CJK UNIFIED IDEOGRAPH + {0x9C71, 0x5FA0}, //4280 #CJK UNIFIED IDEOGRAPH + {0x9C72, 0x5FA8}, //4281 #CJK UNIFIED IDEOGRAPH + {0x9C73, 0x5FAD}, //4282 #CJK UNIFIED IDEOGRAPH + {0x9C74, 0x5FBC}, //4283 #CJK UNIFIED IDEOGRAPH + {0x9C75, 0x5FD6}, //4284 #CJK UNIFIED IDEOGRAPH + {0x9C76, 0x5FFB}, //4285 #CJK UNIFIED IDEOGRAPH + {0x9C77, 0x5FE4}, //4286 #CJK UNIFIED IDEOGRAPH + {0x9C78, 0x5FF8}, //4287 #CJK UNIFIED IDEOGRAPH + {0x9C79, 0x5FF1}, //4288 #CJK UNIFIED IDEOGRAPH + {0x9C7A, 0x5FDD}, //4289 #CJK UNIFIED IDEOGRAPH + {0x9C7B, 0x60B3}, //4290 #CJK UNIFIED IDEOGRAPH + {0x9C7C, 0x5FFF}, //4291 #CJK UNIFIED IDEOGRAPH + {0x9C7D, 0x6021}, //4292 #CJK UNIFIED IDEOGRAPH + {0x9C7E, 0x6060}, //4293 #CJK UNIFIED IDEOGRAPH + {0x9C80, 0x6019}, //4294 #CJK UNIFIED IDEOGRAPH + {0x9C81, 0x6010}, //4295 #CJK UNIFIED IDEOGRAPH + {0x9C82, 0x6029}, //4296 #CJK UNIFIED IDEOGRAPH + {0x9C83, 0x600E}, //4297 #CJK UNIFIED IDEOGRAPH + {0x9C84, 0x6031}, //4298 #CJK UNIFIED IDEOGRAPH + {0x9C85, 0x601B}, //4299 #CJK UNIFIED IDEOGRAPH + {0x9C86, 0x6015}, //4300 #CJK UNIFIED IDEOGRAPH + {0x9C87, 0x602B}, //4301 #CJK UNIFIED IDEOGRAPH + {0x9C88, 0x6026}, //4302 #CJK UNIFIED IDEOGRAPH + {0x9C89, 0x600F}, //4303 #CJK UNIFIED IDEOGRAPH + {0x9C8A, 0x603A}, //4304 #CJK UNIFIED IDEOGRAPH + {0x9C8B, 0x605A}, //4305 #CJK UNIFIED IDEOGRAPH + {0x9C8C, 0x6041}, //4306 #CJK UNIFIED IDEOGRAPH + {0x9C8D, 0x606A}, //4307 #CJK UNIFIED IDEOGRAPH + {0x9C8E, 0x6077}, //4308 #CJK UNIFIED IDEOGRAPH + {0x9C8F, 0x605F}, //4309 #CJK UNIFIED IDEOGRAPH + {0x9C90, 0x604A}, //4310 #CJK UNIFIED IDEOGRAPH + {0x9C91, 0x6046}, //4311 #CJK UNIFIED IDEOGRAPH + {0x9C92, 0x604D}, //4312 #CJK UNIFIED IDEOGRAPH + {0x9C93, 0x6063}, //4313 #CJK UNIFIED IDEOGRAPH + {0x9C94, 0x6043}, //4314 #CJK UNIFIED IDEOGRAPH + {0x9C95, 0x6064}, //4315 #CJK UNIFIED IDEOGRAPH + {0x9C96, 0x6042}, //4316 #CJK UNIFIED IDEOGRAPH + {0x9C97, 0x606C}, //4317 #CJK UNIFIED IDEOGRAPH + {0x9C98, 0x606B}, //4318 #CJK UNIFIED IDEOGRAPH + {0x9C99, 0x6059}, //4319 #CJK UNIFIED IDEOGRAPH + {0x9C9A, 0x6081}, //4320 #CJK UNIFIED IDEOGRAPH + {0x9C9B, 0x608D}, //4321 #CJK UNIFIED IDEOGRAPH + {0x9C9C, 0x60E7}, //4322 #CJK UNIFIED IDEOGRAPH + {0x9C9D, 0x6083}, //4323 #CJK UNIFIED IDEOGRAPH + {0x9C9E, 0x609A}, //4324 #CJK UNIFIED IDEOGRAPH + {0x9C9F, 0x6084}, //4325 #CJK UNIFIED IDEOGRAPH + {0x9CA0, 0x609B}, //4326 #CJK UNIFIED IDEOGRAPH + {0x9CA1, 0x6096}, //4327 #CJK UNIFIED IDEOGRAPH + {0x9CA2, 0x6097}, //4328 #CJK UNIFIED IDEOGRAPH + {0x9CA3, 0x6092}, //4329 #CJK UNIFIED IDEOGRAPH + {0x9CA4, 0x60A7}, //4330 #CJK UNIFIED IDEOGRAPH + {0x9CA5, 0x608B}, //4331 #CJK UNIFIED IDEOGRAPH + {0x9CA6, 0x60E1}, //4332 #CJK UNIFIED IDEOGRAPH + {0x9CA7, 0x60B8}, //4333 #CJK UNIFIED IDEOGRAPH + {0x9CA8, 0x60E0}, //4334 #CJK UNIFIED IDEOGRAPH + {0x9CA9, 0x60D3}, //4335 #CJK UNIFIED IDEOGRAPH + {0x9CAA, 0x60B4}, //4336 #CJK UNIFIED IDEOGRAPH + {0x9CAB, 0x5FF0}, //4337 #CJK UNIFIED IDEOGRAPH + {0x9CAC, 0x60BD}, //4338 #CJK UNIFIED IDEOGRAPH + {0x9CAD, 0x60C6}, //4339 #CJK UNIFIED IDEOGRAPH + {0x9CAE, 0x60B5}, //4340 #CJK UNIFIED IDEOGRAPH + {0x9CAF, 0x60D8}, //4341 #CJK UNIFIED IDEOGRAPH + {0x9CB0, 0x614D}, //4342 #CJK UNIFIED IDEOGRAPH + {0x9CB1, 0x6115}, //4343 #CJK UNIFIED IDEOGRAPH + {0x9CB2, 0x6106}, //4344 #CJK UNIFIED IDEOGRAPH + {0x9CB3, 0x60F6}, //4345 #CJK UNIFIED IDEOGRAPH + {0x9CB4, 0x60F7}, //4346 #CJK UNIFIED IDEOGRAPH + {0x9CB5, 0x6100}, //4347 #CJK UNIFIED IDEOGRAPH + {0x9CB6, 0x60F4}, //4348 #CJK UNIFIED IDEOGRAPH + {0x9CB7, 0x60FA}, //4349 #CJK UNIFIED IDEOGRAPH + {0x9CB8, 0x6103}, //4350 #CJK UNIFIED IDEOGRAPH + {0x9CB9, 0x6121}, //4351 #CJK UNIFIED IDEOGRAPH + {0x9CBA, 0x60FB}, //4352 #CJK UNIFIED IDEOGRAPH + {0x9CBB, 0x60F1}, //4353 #CJK UNIFIED IDEOGRAPH + {0x9CBC, 0x610D}, //4354 #CJK UNIFIED IDEOGRAPH + {0x9CBD, 0x610E}, //4355 #CJK UNIFIED IDEOGRAPH + {0x9CBE, 0x6147}, //4356 #CJK UNIFIED IDEOGRAPH + {0x9CBF, 0x613E}, //4357 #CJK UNIFIED IDEOGRAPH + {0x9CC0, 0x6128}, //4358 #CJK UNIFIED IDEOGRAPH + {0x9CC1, 0x6127}, //4359 #CJK UNIFIED IDEOGRAPH + {0x9CC2, 0x614A}, //4360 #CJK UNIFIED IDEOGRAPH + {0x9CC3, 0x613F}, //4361 #CJK UNIFIED IDEOGRAPH + {0x9CC4, 0x613C}, //4362 #CJK UNIFIED IDEOGRAPH + {0x9CC5, 0x612C}, //4363 #CJK UNIFIED IDEOGRAPH + {0x9CC6, 0x6134}, //4364 #CJK UNIFIED IDEOGRAPH + {0x9CC7, 0x613D}, //4365 #CJK UNIFIED IDEOGRAPH + {0x9CC8, 0x6142}, //4366 #CJK UNIFIED IDEOGRAPH + {0x9CC9, 0x6144}, //4367 #CJK UNIFIED IDEOGRAPH + {0x9CCA, 0x6173}, //4368 #CJK UNIFIED IDEOGRAPH + {0x9CCB, 0x6177}, //4369 #CJK UNIFIED IDEOGRAPH + {0x9CCC, 0x6158}, //4370 #CJK UNIFIED IDEOGRAPH + {0x9CCD, 0x6159}, //4371 #CJK UNIFIED IDEOGRAPH + {0x9CCE, 0x615A}, //4372 #CJK UNIFIED IDEOGRAPH + {0x9CCF, 0x616B}, //4373 #CJK UNIFIED IDEOGRAPH + {0x9CD0, 0x6174}, //4374 #CJK UNIFIED IDEOGRAPH + {0x9CD1, 0x616F}, //4375 #CJK UNIFIED IDEOGRAPH + {0x9CD2, 0x6165}, //4376 #CJK UNIFIED IDEOGRAPH + {0x9CD3, 0x6171}, //4377 #CJK UNIFIED IDEOGRAPH + {0x9CD4, 0x615F}, //4378 #CJK UNIFIED IDEOGRAPH + {0x9CD5, 0x615D}, //4379 #CJK UNIFIED IDEOGRAPH + {0x9CD6, 0x6153}, //4380 #CJK UNIFIED IDEOGRAPH + {0x9CD7, 0x6175}, //4381 #CJK UNIFIED IDEOGRAPH + {0x9CD8, 0x6199}, //4382 #CJK UNIFIED IDEOGRAPH + {0x9CD9, 0x6196}, //4383 #CJK UNIFIED IDEOGRAPH + {0x9CDA, 0x6187}, //4384 #CJK UNIFIED IDEOGRAPH + {0x9CDB, 0x61AC}, //4385 #CJK UNIFIED IDEOGRAPH + {0x9CDC, 0x6194}, //4386 #CJK UNIFIED IDEOGRAPH + {0x9CDD, 0x619A}, //4387 #CJK UNIFIED IDEOGRAPH + {0x9CDE, 0x618A}, //4388 #CJK UNIFIED IDEOGRAPH + {0x9CDF, 0x6191}, //4389 #CJK UNIFIED IDEOGRAPH + {0x9CE0, 0x61AB}, //4390 #CJK UNIFIED IDEOGRAPH + {0x9CE1, 0x61AE}, //4391 #CJK UNIFIED IDEOGRAPH + {0x9CE2, 0x61CC}, //4392 #CJK UNIFIED IDEOGRAPH + {0x9CE3, 0x61CA}, //4393 #CJK UNIFIED IDEOGRAPH + {0x9CE4, 0x61C9}, //4394 #CJK UNIFIED IDEOGRAPH + {0x9CE5, 0x61F7}, //4395 #CJK UNIFIED IDEOGRAPH + {0x9CE6, 0x61C8}, //4396 #CJK UNIFIED IDEOGRAPH + {0x9CE7, 0x61C3}, //4397 #CJK UNIFIED IDEOGRAPH + {0x9CE8, 0x61C6}, //4398 #CJK UNIFIED IDEOGRAPH + {0x9CE9, 0x61BA}, //4399 #CJK UNIFIED IDEOGRAPH + {0x9CEA, 0x61CB}, //4400 #CJK UNIFIED IDEOGRAPH + {0x9CEB, 0x7F79}, //4401 #CJK UNIFIED IDEOGRAPH + {0x9CEC, 0x61CD}, //4402 #CJK UNIFIED IDEOGRAPH + {0x9CED, 0x61E6}, //4403 #CJK UNIFIED IDEOGRAPH + {0x9CEE, 0x61E3}, //4404 #CJK UNIFIED IDEOGRAPH + {0x9CEF, 0x61F6}, //4405 #CJK UNIFIED IDEOGRAPH + {0x9CF0, 0x61FA}, //4406 #CJK UNIFIED IDEOGRAPH + {0x9CF1, 0x61F4}, //4407 #CJK UNIFIED IDEOGRAPH + {0x9CF2, 0x61FF}, //4408 #CJK UNIFIED IDEOGRAPH + {0x9CF3, 0x61FD}, //4409 #CJK UNIFIED IDEOGRAPH + {0x9CF4, 0x61FC}, //4410 #CJK UNIFIED IDEOGRAPH + {0x9CF5, 0x61FE}, //4411 #CJK UNIFIED IDEOGRAPH + {0x9CF6, 0x6200}, //4412 #CJK UNIFIED IDEOGRAPH + {0x9CF7, 0x6208}, //4413 #CJK UNIFIED IDEOGRAPH + {0x9CF8, 0x6209}, //4414 #CJK UNIFIED IDEOGRAPH + {0x9CF9, 0x620D}, //4415 #CJK UNIFIED IDEOGRAPH + {0x9CFA, 0x620C}, //4416 #CJK UNIFIED IDEOGRAPH + {0x9CFB, 0x6214}, //4417 #CJK UNIFIED IDEOGRAPH + {0x9CFC, 0x621B}, //4418 #CJK UNIFIED IDEOGRAPH + {0x9D40, 0x621E}, //4419 #CJK UNIFIED IDEOGRAPH + {0x9D41, 0x6221}, //4420 #CJK UNIFIED IDEOGRAPH + {0x9D42, 0x622A}, //4421 #CJK UNIFIED IDEOGRAPH + {0x9D43, 0x622E}, //4422 #CJK UNIFIED IDEOGRAPH + {0x9D44, 0x6230}, //4423 #CJK UNIFIED IDEOGRAPH + {0x9D45, 0x6232}, //4424 #CJK UNIFIED IDEOGRAPH + {0x9D46, 0x6233}, //4425 #CJK UNIFIED IDEOGRAPH + {0x9D47, 0x6241}, //4426 #CJK UNIFIED IDEOGRAPH + {0x9D48, 0x624E}, //4427 #CJK UNIFIED IDEOGRAPH + {0x9D49, 0x625E}, //4428 #CJK UNIFIED IDEOGRAPH + {0x9D4A, 0x6263}, //4429 #CJK UNIFIED IDEOGRAPH + {0x9D4B, 0x625B}, //4430 #CJK UNIFIED IDEOGRAPH + {0x9D4C, 0x6260}, //4431 #CJK UNIFIED IDEOGRAPH + {0x9D4D, 0x6268}, //4432 #CJK UNIFIED IDEOGRAPH + {0x9D4E, 0x627C}, //4433 #CJK UNIFIED IDEOGRAPH + {0x9D4F, 0x6282}, //4434 #CJK UNIFIED IDEOGRAPH + {0x9D50, 0x6289}, //4435 #CJK UNIFIED IDEOGRAPH + {0x9D51, 0x627E}, //4436 #CJK UNIFIED IDEOGRAPH + {0x9D52, 0x6292}, //4437 #CJK UNIFIED IDEOGRAPH + {0x9D53, 0x6293}, //4438 #CJK UNIFIED IDEOGRAPH + {0x9D54, 0x6296}, //4439 #CJK UNIFIED IDEOGRAPH + {0x9D55, 0x62D4}, //4440 #CJK UNIFIED IDEOGRAPH + {0x9D56, 0x6283}, //4441 #CJK UNIFIED IDEOGRAPH + {0x9D57, 0x6294}, //4442 #CJK UNIFIED IDEOGRAPH + {0x9D58, 0x62D7}, //4443 #CJK UNIFIED IDEOGRAPH + {0x9D59, 0x62D1}, //4444 #CJK UNIFIED IDEOGRAPH + {0x9D5A, 0x62BB}, //4445 #CJK UNIFIED IDEOGRAPH + {0x9D5B, 0x62CF}, //4446 #CJK UNIFIED IDEOGRAPH + {0x9D5C, 0x62FF}, //4447 #CJK UNIFIED IDEOGRAPH + {0x9D5D, 0x62C6}, //4448 #CJK UNIFIED IDEOGRAPH + {0x9D5E, 0x64D4}, //4449 #CJK UNIFIED IDEOGRAPH + {0x9D5F, 0x62C8}, //4450 #CJK UNIFIED IDEOGRAPH + {0x9D60, 0x62DC}, //4451 #CJK UNIFIED IDEOGRAPH + {0x9D61, 0x62CC}, //4452 #CJK UNIFIED IDEOGRAPH + {0x9D62, 0x62CA}, //4453 #CJK UNIFIED IDEOGRAPH + {0x9D63, 0x62C2}, //4454 #CJK UNIFIED IDEOGRAPH + {0x9D64, 0x62C7}, //4455 #CJK UNIFIED IDEOGRAPH + {0x9D65, 0x629B}, //4456 #CJK UNIFIED IDEOGRAPH + {0x9D66, 0x62C9}, //4457 #CJK UNIFIED IDEOGRAPH + {0x9D67, 0x630C}, //4458 #CJK UNIFIED IDEOGRAPH + {0x9D68, 0x62EE}, //4459 #CJK UNIFIED IDEOGRAPH + {0x9D69, 0x62F1}, //4460 #CJK UNIFIED IDEOGRAPH + {0x9D6A, 0x6327}, //4461 #CJK UNIFIED IDEOGRAPH + {0x9D6B, 0x6302}, //4462 #CJK UNIFIED IDEOGRAPH + {0x9D6C, 0x6308}, //4463 #CJK UNIFIED IDEOGRAPH + {0x9D6D, 0x62EF}, //4464 #CJK UNIFIED IDEOGRAPH + {0x9D6E, 0x62F5}, //4465 #CJK UNIFIED IDEOGRAPH + {0x9D6F, 0x6350}, //4466 #CJK UNIFIED IDEOGRAPH + {0x9D70, 0x633E}, //4467 #CJK UNIFIED IDEOGRAPH + {0x9D71, 0x634D}, //4468 #CJK UNIFIED IDEOGRAPH + {0x9D72, 0x641C}, //4469 #CJK UNIFIED IDEOGRAPH + {0x9D73, 0x634F}, //4470 #CJK UNIFIED IDEOGRAPH + {0x9D74, 0x6396}, //4471 #CJK UNIFIED IDEOGRAPH + {0x9D75, 0x638E}, //4472 #CJK UNIFIED IDEOGRAPH + {0x9D76, 0x6380}, //4473 #CJK UNIFIED IDEOGRAPH + {0x9D77, 0x63AB}, //4474 #CJK UNIFIED IDEOGRAPH + {0x9D78, 0x6376}, //4475 #CJK UNIFIED IDEOGRAPH + {0x9D79, 0x63A3}, //4476 #CJK UNIFIED IDEOGRAPH + {0x9D7A, 0x638F}, //4477 #CJK UNIFIED IDEOGRAPH + {0x9D7B, 0x6389}, //4478 #CJK UNIFIED IDEOGRAPH + {0x9D7C, 0x639F}, //4479 #CJK UNIFIED IDEOGRAPH + {0x9D7D, 0x63B5}, //4480 #CJK UNIFIED IDEOGRAPH + {0x9D7E, 0x636B}, //4481 #CJK UNIFIED IDEOGRAPH + {0x9D80, 0x6369}, //4482 #CJK UNIFIED IDEOGRAPH + {0x9D81, 0x63BE}, //4483 #CJK UNIFIED IDEOGRAPH + {0x9D82, 0x63E9}, //4484 #CJK UNIFIED IDEOGRAPH + {0x9D83, 0x63C0}, //4485 #CJK UNIFIED IDEOGRAPH + {0x9D84, 0x63C6}, //4486 #CJK UNIFIED IDEOGRAPH + {0x9D85, 0x63E3}, //4487 #CJK UNIFIED IDEOGRAPH + {0x9D86, 0x63C9}, //4488 #CJK UNIFIED IDEOGRAPH + {0x9D87, 0x63D2}, //4489 #CJK UNIFIED IDEOGRAPH + {0x9D88, 0x63F6}, //4490 #CJK UNIFIED IDEOGRAPH + {0x9D89, 0x63C4}, //4491 #CJK UNIFIED IDEOGRAPH + {0x9D8A, 0x6416}, //4492 #CJK UNIFIED IDEOGRAPH + {0x9D8B, 0x6434}, //4493 #CJK UNIFIED IDEOGRAPH + {0x9D8C, 0x6406}, //4494 #CJK UNIFIED IDEOGRAPH + {0x9D8D, 0x6413}, //4495 #CJK UNIFIED IDEOGRAPH + {0x9D8E, 0x6426}, //4496 #CJK UNIFIED IDEOGRAPH + {0x9D8F, 0x6436}, //4497 #CJK UNIFIED IDEOGRAPH + {0x9D90, 0x651D}, //4498 #CJK UNIFIED IDEOGRAPH + {0x9D91, 0x6417}, //4499 #CJK UNIFIED IDEOGRAPH + {0x9D92, 0x6428}, //4500 #CJK UNIFIED IDEOGRAPH + {0x9D93, 0x640F}, //4501 #CJK UNIFIED IDEOGRAPH + {0x9D94, 0x6467}, //4502 #CJK UNIFIED IDEOGRAPH + {0x9D95, 0x646F}, //4503 #CJK UNIFIED IDEOGRAPH + {0x9D96, 0x6476}, //4504 #CJK UNIFIED IDEOGRAPH + {0x9D97, 0x644E}, //4505 #CJK UNIFIED IDEOGRAPH + {0x9D98, 0x652A}, //4506 #CJK UNIFIED IDEOGRAPH + {0x9D99, 0x6495}, //4507 #CJK UNIFIED IDEOGRAPH + {0x9D9A, 0x6493}, //4508 #CJK UNIFIED IDEOGRAPH + {0x9D9B, 0x64A5}, //4509 #CJK UNIFIED IDEOGRAPH + {0x9D9C, 0x64A9}, //4510 #CJK UNIFIED IDEOGRAPH + {0x9D9D, 0x6488}, //4511 #CJK UNIFIED IDEOGRAPH + {0x9D9E, 0x64BC}, //4512 #CJK UNIFIED IDEOGRAPH + {0x9D9F, 0x64DA}, //4513 #CJK UNIFIED IDEOGRAPH + {0x9DA0, 0x64D2}, //4514 #CJK UNIFIED IDEOGRAPH + {0x9DA1, 0x64C5}, //4515 #CJK UNIFIED IDEOGRAPH + {0x9DA2, 0x64C7}, //4516 #CJK UNIFIED IDEOGRAPH + {0x9DA3, 0x64BB}, //4517 #CJK UNIFIED IDEOGRAPH + {0x9DA4, 0x64D8}, //4518 #CJK UNIFIED IDEOGRAPH + {0x9DA5, 0x64C2}, //4519 #CJK UNIFIED IDEOGRAPH + {0x9DA6, 0x64F1}, //4520 #CJK UNIFIED IDEOGRAPH + {0x9DA7, 0x64E7}, //4521 #CJK UNIFIED IDEOGRAPH + {0x9DA8, 0x8209}, //4522 #CJK UNIFIED IDEOGRAPH + {0x9DA9, 0x64E0}, //4523 #CJK UNIFIED IDEOGRAPH + {0x9DAA, 0x64E1}, //4524 #CJK UNIFIED IDEOGRAPH + {0x9DAB, 0x62AC}, //4525 #CJK UNIFIED IDEOGRAPH + {0x9DAC, 0x64E3}, //4526 #CJK UNIFIED IDEOGRAPH + {0x9DAD, 0x64EF}, //4527 #CJK UNIFIED IDEOGRAPH + {0x9DAE, 0x652C}, //4528 #CJK UNIFIED IDEOGRAPH + {0x9DAF, 0x64F6}, //4529 #CJK UNIFIED IDEOGRAPH + {0x9DB0, 0x64F4}, //4530 #CJK UNIFIED IDEOGRAPH + {0x9DB1, 0x64F2}, //4531 #CJK UNIFIED IDEOGRAPH + {0x9DB2, 0x64FA}, //4532 #CJK UNIFIED IDEOGRAPH + {0x9DB3, 0x6500}, //4533 #CJK UNIFIED IDEOGRAPH + {0x9DB4, 0x64FD}, //4534 #CJK UNIFIED IDEOGRAPH + {0x9DB5, 0x6518}, //4535 #CJK UNIFIED IDEOGRAPH + {0x9DB6, 0x651C}, //4536 #CJK UNIFIED IDEOGRAPH + {0x9DB7, 0x6505}, //4537 #CJK UNIFIED IDEOGRAPH + {0x9DB8, 0x6524}, //4538 #CJK UNIFIED IDEOGRAPH + {0x9DB9, 0x6523}, //4539 #CJK UNIFIED IDEOGRAPH + {0x9DBA, 0x652B}, //4540 #CJK UNIFIED IDEOGRAPH + {0x9DBB, 0x6534}, //4541 #CJK UNIFIED IDEOGRAPH + {0x9DBC, 0x6535}, //4542 #CJK UNIFIED IDEOGRAPH + {0x9DBD, 0x6537}, //4543 #CJK UNIFIED IDEOGRAPH + {0x9DBE, 0x6536}, //4544 #CJK UNIFIED IDEOGRAPH + {0x9DBF, 0x6538}, //4545 #CJK UNIFIED IDEOGRAPH + {0x9DC0, 0x754B}, //4546 #CJK UNIFIED IDEOGRAPH + {0x9DC1, 0x6548}, //4547 #CJK UNIFIED IDEOGRAPH + {0x9DC2, 0x6556}, //4548 #CJK UNIFIED IDEOGRAPH + {0x9DC3, 0x6555}, //4549 #CJK UNIFIED IDEOGRAPH + {0x9DC4, 0x654D}, //4550 #CJK UNIFIED IDEOGRAPH + {0x9DC5, 0x6558}, //4551 #CJK UNIFIED IDEOGRAPH + {0x9DC6, 0x655E}, //4552 #CJK UNIFIED IDEOGRAPH + {0x9DC7, 0x655D}, //4553 #CJK UNIFIED IDEOGRAPH + {0x9DC8, 0x6572}, //4554 #CJK UNIFIED IDEOGRAPH + {0x9DC9, 0x6578}, //4555 #CJK UNIFIED IDEOGRAPH + {0x9DCA, 0x6582}, //4556 #CJK UNIFIED IDEOGRAPH + {0x9DCB, 0x6583}, //4557 #CJK UNIFIED IDEOGRAPH + {0x9DCC, 0x8B8A}, //4558 #CJK UNIFIED IDEOGRAPH + {0x9DCD, 0x659B}, //4559 #CJK UNIFIED IDEOGRAPH + {0x9DCE, 0x659F}, //4560 #CJK UNIFIED IDEOGRAPH + {0x9DCF, 0x65AB}, //4561 #CJK UNIFIED IDEOGRAPH + {0x9DD0, 0x65B7}, //4562 #CJK UNIFIED IDEOGRAPH + {0x9DD1, 0x65C3}, //4563 #CJK UNIFIED IDEOGRAPH + {0x9DD2, 0x65C6}, //4564 #CJK UNIFIED IDEOGRAPH + {0x9DD3, 0x65C1}, //4565 #CJK UNIFIED IDEOGRAPH + {0x9DD4, 0x65C4}, //4566 #CJK UNIFIED IDEOGRAPH + {0x9DD5, 0x65CC}, //4567 #CJK UNIFIED IDEOGRAPH + {0x9DD6, 0x65D2}, //4568 #CJK UNIFIED IDEOGRAPH + {0x9DD7, 0x65DB}, //4569 #CJK UNIFIED IDEOGRAPH + {0x9DD8, 0x65D9}, //4570 #CJK UNIFIED IDEOGRAPH + {0x9DD9, 0x65E0}, //4571 #CJK UNIFIED IDEOGRAPH + {0x9DDA, 0x65E1}, //4572 #CJK UNIFIED IDEOGRAPH + {0x9DDB, 0x65F1}, //4573 #CJK UNIFIED IDEOGRAPH + {0x9DDC, 0x6772}, //4574 #CJK UNIFIED IDEOGRAPH + {0x9DDD, 0x660A}, //4575 #CJK UNIFIED IDEOGRAPH + {0x9DDE, 0x6603}, //4576 #CJK UNIFIED IDEOGRAPH + {0x9DDF, 0x65FB}, //4577 #CJK UNIFIED IDEOGRAPH + {0x9DE0, 0x6773}, //4578 #CJK UNIFIED IDEOGRAPH + {0x9DE1, 0x6635}, //4579 #CJK UNIFIED IDEOGRAPH + {0x9DE2, 0x6636}, //4580 #CJK UNIFIED IDEOGRAPH + {0x9DE3, 0x6634}, //4581 #CJK UNIFIED IDEOGRAPH + {0x9DE4, 0x661C}, //4582 #CJK UNIFIED IDEOGRAPH + {0x9DE5, 0x664F}, //4583 #CJK UNIFIED IDEOGRAPH + {0x9DE6, 0x6644}, //4584 #CJK UNIFIED IDEOGRAPH + {0x9DE7, 0x6649}, //4585 #CJK UNIFIED IDEOGRAPH + {0x9DE8, 0x6641}, //4586 #CJK UNIFIED IDEOGRAPH + {0x9DE9, 0x665E}, //4587 #CJK UNIFIED IDEOGRAPH + {0x9DEA, 0x665D}, //4588 #CJK UNIFIED IDEOGRAPH + {0x9DEB, 0x6664}, //4589 #CJK UNIFIED IDEOGRAPH + {0x9DEC, 0x6667}, //4590 #CJK UNIFIED IDEOGRAPH + {0x9DED, 0x6668}, //4591 #CJK UNIFIED IDEOGRAPH + {0x9DEE, 0x665F}, //4592 #CJK UNIFIED IDEOGRAPH + {0x9DEF, 0x6662}, //4593 #CJK UNIFIED IDEOGRAPH + {0x9DF0, 0x6670}, //4594 #CJK UNIFIED IDEOGRAPH + {0x9DF1, 0x6683}, //4595 #CJK UNIFIED IDEOGRAPH + {0x9DF2, 0x6688}, //4596 #CJK UNIFIED IDEOGRAPH + {0x9DF3, 0x668E}, //4597 #CJK UNIFIED IDEOGRAPH + {0x9DF4, 0x6689}, //4598 #CJK UNIFIED IDEOGRAPH + {0x9DF5, 0x6684}, //4599 #CJK UNIFIED IDEOGRAPH + {0x9DF6, 0x6698}, //4600 #CJK UNIFIED IDEOGRAPH + {0x9DF7, 0x669D}, //4601 #CJK UNIFIED IDEOGRAPH + {0x9DF8, 0x66C1}, //4602 #CJK UNIFIED IDEOGRAPH + {0x9DF9, 0x66B9}, //4603 #CJK UNIFIED IDEOGRAPH + {0x9DFA, 0x66C9}, //4604 #CJK UNIFIED IDEOGRAPH + {0x9DFB, 0x66BE}, //4605 #CJK UNIFIED IDEOGRAPH + {0x9DFC, 0x66BC}, //4606 #CJK UNIFIED IDEOGRAPH + {0x9E40, 0x66C4}, //4607 #CJK UNIFIED IDEOGRAPH + {0x9E41, 0x66B8}, //4608 #CJK UNIFIED IDEOGRAPH + {0x9E42, 0x66D6}, //4609 #CJK UNIFIED IDEOGRAPH + {0x9E43, 0x66DA}, //4610 #CJK UNIFIED IDEOGRAPH + {0x9E44, 0x66E0}, //4611 #CJK UNIFIED IDEOGRAPH + {0x9E45, 0x663F}, //4612 #CJK UNIFIED IDEOGRAPH + {0x9E46, 0x66E6}, //4613 #CJK UNIFIED IDEOGRAPH + {0x9E47, 0x66E9}, //4614 #CJK UNIFIED IDEOGRAPH + {0x9E48, 0x66F0}, //4615 #CJK UNIFIED IDEOGRAPH + {0x9E49, 0x66F5}, //4616 #CJK UNIFIED IDEOGRAPH + {0x9E4A, 0x66F7}, //4617 #CJK UNIFIED IDEOGRAPH + {0x9E4B, 0x670F}, //4618 #CJK UNIFIED IDEOGRAPH + {0x9E4C, 0x6716}, //4619 #CJK UNIFIED IDEOGRAPH + {0x9E4D, 0x671E}, //4620 #CJK UNIFIED IDEOGRAPH + {0x9E4E, 0x6726}, //4621 #CJK UNIFIED IDEOGRAPH + {0x9E4F, 0x6727}, //4622 #CJK UNIFIED IDEOGRAPH + {0x9E50, 0x9738}, //4623 #CJK UNIFIED IDEOGRAPH + {0x9E51, 0x672E}, //4624 #CJK UNIFIED IDEOGRAPH + {0x9E52, 0x673F}, //4625 #CJK UNIFIED IDEOGRAPH + {0x9E53, 0x6736}, //4626 #CJK UNIFIED IDEOGRAPH + {0x9E54, 0x6741}, //4627 #CJK UNIFIED IDEOGRAPH + {0x9E55, 0x6738}, //4628 #CJK UNIFIED IDEOGRAPH + {0x9E56, 0x6737}, //4629 #CJK UNIFIED IDEOGRAPH + {0x9E57, 0x6746}, //4630 #CJK UNIFIED IDEOGRAPH + {0x9E58, 0x675E}, //4631 #CJK UNIFIED IDEOGRAPH + {0x9E59, 0x6760}, //4632 #CJK UNIFIED IDEOGRAPH + {0x9E5A, 0x6759}, //4633 #CJK UNIFIED IDEOGRAPH + {0x9E5B, 0x6763}, //4634 #CJK UNIFIED IDEOGRAPH + {0x9E5C, 0x6764}, //4635 #CJK UNIFIED IDEOGRAPH + {0x9E5D, 0x6789}, //4636 #CJK UNIFIED IDEOGRAPH + {0x9E5E, 0x6770}, //4637 #CJK UNIFIED IDEOGRAPH + {0x9E5F, 0x67A9}, //4638 #CJK UNIFIED IDEOGRAPH + {0x9E60, 0x677C}, //4639 #CJK UNIFIED IDEOGRAPH + {0x9E61, 0x676A}, //4640 #CJK UNIFIED IDEOGRAPH + {0x9E62, 0x678C}, //4641 #CJK UNIFIED IDEOGRAPH + {0x9E63, 0x678B}, //4642 #CJK UNIFIED IDEOGRAPH + {0x9E64, 0x67A6}, //4643 #CJK UNIFIED IDEOGRAPH + {0x9E65, 0x67A1}, //4644 #CJK UNIFIED IDEOGRAPH + {0x9E66, 0x6785}, //4645 #CJK UNIFIED IDEOGRAPH + {0x9E67, 0x67B7}, //4646 #CJK UNIFIED IDEOGRAPH + {0x9E68, 0x67EF}, //4647 #CJK UNIFIED IDEOGRAPH + {0x9E69, 0x67B4}, //4648 #CJK UNIFIED IDEOGRAPH + {0x9E6A, 0x67EC}, //4649 #CJK UNIFIED IDEOGRAPH + {0x9E6B, 0x67B3}, //4650 #CJK UNIFIED IDEOGRAPH + {0x9E6C, 0x67E9}, //4651 #CJK UNIFIED IDEOGRAPH + {0x9E6D, 0x67B8}, //4652 #CJK UNIFIED IDEOGRAPH + {0x9E6E, 0x67E4}, //4653 #CJK UNIFIED IDEOGRAPH + {0x9E6F, 0x67DE}, //4654 #CJK UNIFIED IDEOGRAPH + {0x9E70, 0x67DD}, //4655 #CJK UNIFIED IDEOGRAPH + {0x9E71, 0x67E2}, //4656 #CJK UNIFIED IDEOGRAPH + {0x9E72, 0x67EE}, //4657 #CJK UNIFIED IDEOGRAPH + {0x9E73, 0x67B9}, //4658 #CJK UNIFIED IDEOGRAPH + {0x9E74, 0x67CE}, //4659 #CJK UNIFIED IDEOGRAPH + {0x9E75, 0x67C6}, //4660 #CJK UNIFIED IDEOGRAPH + {0x9E76, 0x67E7}, //4661 #CJK UNIFIED IDEOGRAPH + {0x9E77, 0x6A9C}, //4662 #CJK UNIFIED IDEOGRAPH + {0x9E78, 0x681E}, //4663 #CJK UNIFIED IDEOGRAPH + {0x9E79, 0x6846}, //4664 #CJK UNIFIED IDEOGRAPH + {0x9E7A, 0x6829}, //4665 #CJK UNIFIED IDEOGRAPH + {0x9E7B, 0x6840}, //4666 #CJK UNIFIED IDEOGRAPH + {0x9E7C, 0x684D}, //4667 #CJK UNIFIED IDEOGRAPH + {0x9E7D, 0x6832}, //4668 #CJK UNIFIED IDEOGRAPH + {0x9E7E, 0x684E}, //4669 #CJK UNIFIED IDEOGRAPH + {0x9E80, 0x68B3}, //4670 #CJK UNIFIED IDEOGRAPH + {0x9E81, 0x682B}, //4671 #CJK UNIFIED IDEOGRAPH + {0x9E82, 0x6859}, //4672 #CJK UNIFIED IDEOGRAPH + {0x9E83, 0x6863}, //4673 #CJK UNIFIED IDEOGRAPH + {0x9E84, 0x6877}, //4674 #CJK UNIFIED IDEOGRAPH + {0x9E85, 0x687F}, //4675 #CJK UNIFIED IDEOGRAPH + {0x9E86, 0x689F}, //4676 #CJK UNIFIED IDEOGRAPH + {0x9E87, 0x688F}, //4677 #CJK UNIFIED IDEOGRAPH + {0x9E88, 0x68AD}, //4678 #CJK UNIFIED IDEOGRAPH + {0x9E89, 0x6894}, //4679 #CJK UNIFIED IDEOGRAPH + {0x9E8A, 0x689D}, //4680 #CJK UNIFIED IDEOGRAPH + {0x9E8B, 0x689B}, //4681 #CJK UNIFIED IDEOGRAPH + {0x9E8C, 0x6883}, //4682 #CJK UNIFIED IDEOGRAPH + {0x9E8D, 0x6AAE}, //4683 #CJK UNIFIED IDEOGRAPH + {0x9E8E, 0x68B9}, //4684 #CJK UNIFIED IDEOGRAPH + {0x9E8F, 0x6874}, //4685 #CJK UNIFIED IDEOGRAPH + {0x9E90, 0x68B5}, //4686 #CJK UNIFIED IDEOGRAPH + {0x9E91, 0x68A0}, //4687 #CJK UNIFIED IDEOGRAPH + {0x9E92, 0x68BA}, //4688 #CJK UNIFIED IDEOGRAPH + {0x9E93, 0x690F}, //4689 #CJK UNIFIED IDEOGRAPH + {0x9E94, 0x688D}, //4690 #CJK UNIFIED IDEOGRAPH + {0x9E95, 0x687E}, //4691 #CJK UNIFIED IDEOGRAPH + {0x9E96, 0x6901}, //4692 #CJK UNIFIED IDEOGRAPH + {0x9E97, 0x68CA}, //4693 #CJK UNIFIED IDEOGRAPH + {0x9E98, 0x6908}, //4694 #CJK UNIFIED IDEOGRAPH + {0x9E99, 0x68D8}, //4695 #CJK UNIFIED IDEOGRAPH + {0x9E9A, 0x6922}, //4696 #CJK UNIFIED IDEOGRAPH + {0x9E9B, 0x6926}, //4697 #CJK UNIFIED IDEOGRAPH + {0x9E9C, 0x68E1}, //4698 #CJK UNIFIED IDEOGRAPH + {0x9E9D, 0x690C}, //4699 #CJK UNIFIED IDEOGRAPH + {0x9E9E, 0x68CD}, //4700 #CJK UNIFIED IDEOGRAPH + {0x9E9F, 0x68D4}, //4701 #CJK UNIFIED IDEOGRAPH + {0x9EA0, 0x68E7}, //4702 #CJK UNIFIED IDEOGRAPH + {0x9EA1, 0x68D5}, //4703 #CJK UNIFIED IDEOGRAPH + {0x9EA2, 0x6936}, //4704 #CJK UNIFIED IDEOGRAPH + {0x9EA3, 0x6912}, //4705 #CJK UNIFIED IDEOGRAPH + {0x9EA4, 0x6904}, //4706 #CJK UNIFIED IDEOGRAPH + {0x9EA5, 0x68D7}, //4707 #CJK UNIFIED IDEOGRAPH + {0x9EA6, 0x68E3}, //4708 #CJK UNIFIED IDEOGRAPH + {0x9EA7, 0x6925}, //4709 #CJK UNIFIED IDEOGRAPH + {0x9EA8, 0x68F9}, //4710 #CJK UNIFIED IDEOGRAPH + {0x9EA9, 0x68E0}, //4711 #CJK UNIFIED IDEOGRAPH + {0x9EAA, 0x68EF}, //4712 #CJK UNIFIED IDEOGRAPH + {0x9EAB, 0x6928}, //4713 #CJK UNIFIED IDEOGRAPH + {0x9EAC, 0x692A}, //4714 #CJK UNIFIED IDEOGRAPH + {0x9EAD, 0x691A}, //4715 #CJK UNIFIED IDEOGRAPH + {0x9EAE, 0x6923}, //4716 #CJK UNIFIED IDEOGRAPH + {0x9EAF, 0x6921}, //4717 #CJK UNIFIED IDEOGRAPH + {0x9EB0, 0x68C6}, //4718 #CJK UNIFIED IDEOGRAPH + {0x9EB1, 0x6979}, //4719 #CJK UNIFIED IDEOGRAPH + {0x9EB2, 0x6977}, //4720 #CJK UNIFIED IDEOGRAPH + {0x9EB3, 0x695C}, //4721 #CJK UNIFIED IDEOGRAPH + {0x9EB4, 0x6978}, //4722 #CJK UNIFIED IDEOGRAPH + {0x9EB5, 0x696B}, //4723 #CJK UNIFIED IDEOGRAPH + {0x9EB6, 0x6954}, //4724 #CJK UNIFIED IDEOGRAPH + {0x9EB7, 0x697E}, //4725 #CJK UNIFIED IDEOGRAPH + {0x9EB8, 0x696E}, //4726 #CJK UNIFIED IDEOGRAPH + {0x9EB9, 0x6939}, //4727 #CJK UNIFIED IDEOGRAPH + {0x9EBA, 0x6974}, //4728 #CJK UNIFIED IDEOGRAPH + {0x9EBB, 0x693D}, //4729 #CJK UNIFIED IDEOGRAPH + {0x9EBC, 0x6959}, //4730 #CJK UNIFIED IDEOGRAPH + {0x9EBD, 0x6930}, //4731 #CJK UNIFIED IDEOGRAPH + {0x9EBE, 0x6961}, //4732 #CJK UNIFIED IDEOGRAPH + {0x9EBF, 0x695E}, //4733 #CJK UNIFIED IDEOGRAPH + {0x9EC0, 0x695D}, //4734 #CJK UNIFIED IDEOGRAPH + {0x9EC1, 0x6981}, //4735 #CJK UNIFIED IDEOGRAPH + {0x9EC2, 0x696A}, //4736 #CJK UNIFIED IDEOGRAPH + {0x9EC3, 0x69B2}, //4737 #CJK UNIFIED IDEOGRAPH + {0x9EC4, 0x69AE}, //4738 #CJK UNIFIED IDEOGRAPH + {0x9EC5, 0x69D0}, //4739 #CJK UNIFIED IDEOGRAPH + {0x9EC6, 0x69BF}, //4740 #CJK UNIFIED IDEOGRAPH + {0x9EC7, 0x69C1}, //4741 #CJK UNIFIED IDEOGRAPH + {0x9EC8, 0x69D3}, //4742 #CJK UNIFIED IDEOGRAPH + {0x9EC9, 0x69BE}, //4743 #CJK UNIFIED IDEOGRAPH + {0x9ECA, 0x69CE}, //4744 #CJK UNIFIED IDEOGRAPH + {0x9ECB, 0x5BE8}, //4745 #CJK UNIFIED IDEOGRAPH + {0x9ECC, 0x69CA}, //4746 #CJK UNIFIED IDEOGRAPH + {0x9ECD, 0x69DD}, //4747 #CJK UNIFIED IDEOGRAPH + {0x9ECE, 0x69BB}, //4748 #CJK UNIFIED IDEOGRAPH + {0x9ECF, 0x69C3}, //4749 #CJK UNIFIED IDEOGRAPH + {0x9ED0, 0x69A7}, //4750 #CJK UNIFIED IDEOGRAPH + {0x9ED1, 0x6A2E}, //4751 #CJK UNIFIED IDEOGRAPH + {0x9ED2, 0x6991}, //4752 #CJK UNIFIED IDEOGRAPH + {0x9ED3, 0x69A0}, //4753 #CJK UNIFIED IDEOGRAPH + {0x9ED4, 0x699C}, //4754 #CJK UNIFIED IDEOGRAPH + {0x9ED5, 0x6995}, //4755 #CJK UNIFIED IDEOGRAPH + {0x9ED6, 0x69B4}, //4756 #CJK UNIFIED IDEOGRAPH + {0x9ED7, 0x69DE}, //4757 #CJK UNIFIED IDEOGRAPH + {0x9ED8, 0x69E8}, //4758 #CJK UNIFIED IDEOGRAPH + {0x9ED9, 0x6A02}, //4759 #CJK UNIFIED IDEOGRAPH + {0x9EDA, 0x6A1B}, //4760 #CJK UNIFIED IDEOGRAPH + {0x9EDB, 0x69FF}, //4761 #CJK UNIFIED IDEOGRAPH + {0x9EDC, 0x6B0A}, //4762 #CJK UNIFIED IDEOGRAPH + {0x9EDD, 0x69F9}, //4763 #CJK UNIFIED IDEOGRAPH + {0x9EDE, 0x69F2}, //4764 #CJK UNIFIED IDEOGRAPH + {0x9EDF, 0x69E7}, //4765 #CJK UNIFIED IDEOGRAPH + {0x9EE0, 0x6A05}, //4766 #CJK UNIFIED IDEOGRAPH + {0x9EE1, 0x69B1}, //4767 #CJK UNIFIED IDEOGRAPH + {0x9EE2, 0x6A1E}, //4768 #CJK UNIFIED IDEOGRAPH + {0x9EE3, 0x69ED}, //4769 #CJK UNIFIED IDEOGRAPH + {0x9EE4, 0x6A14}, //4770 #CJK UNIFIED IDEOGRAPH + {0x9EE5, 0x69EB}, //4771 #CJK UNIFIED IDEOGRAPH + {0x9EE6, 0x6A0A}, //4772 #CJK UNIFIED IDEOGRAPH + {0x9EE7, 0x6A12}, //4773 #CJK UNIFIED IDEOGRAPH + {0x9EE8, 0x6AC1}, //4774 #CJK UNIFIED IDEOGRAPH + {0x9EE9, 0x6A23}, //4775 #CJK UNIFIED IDEOGRAPH + {0x9EEA, 0x6A13}, //4776 #CJK UNIFIED IDEOGRAPH + {0x9EEB, 0x6A44}, //4777 #CJK UNIFIED IDEOGRAPH + {0x9EEC, 0x6A0C}, //4778 #CJK UNIFIED IDEOGRAPH + {0x9EED, 0x6A72}, //4779 #CJK UNIFIED IDEOGRAPH + {0x9EEE, 0x6A36}, //4780 #CJK UNIFIED IDEOGRAPH + {0x9EEF, 0x6A78}, //4781 #CJK UNIFIED IDEOGRAPH + {0x9EF0, 0x6A47}, //4782 #CJK UNIFIED IDEOGRAPH + {0x9EF1, 0x6A62}, //4783 #CJK UNIFIED IDEOGRAPH + {0x9EF2, 0x6A59}, //4784 #CJK UNIFIED IDEOGRAPH + {0x9EF3, 0x6A66}, //4785 #CJK UNIFIED IDEOGRAPH + {0x9EF4, 0x6A48}, //4786 #CJK UNIFIED IDEOGRAPH + {0x9EF5, 0x6A38}, //4787 #CJK UNIFIED IDEOGRAPH + {0x9EF6, 0x6A22}, //4788 #CJK UNIFIED IDEOGRAPH + {0x9EF7, 0x6A90}, //4789 #CJK UNIFIED IDEOGRAPH + {0x9EF8, 0x6A8D}, //4790 #CJK UNIFIED IDEOGRAPH + {0x9EF9, 0x6AA0}, //4791 #CJK UNIFIED IDEOGRAPH + {0x9EFA, 0x6A84}, //4792 #CJK UNIFIED IDEOGRAPH + {0x9EFB, 0x6AA2}, //4793 #CJK UNIFIED IDEOGRAPH + {0x9EFC, 0x6AA3}, //4794 #CJK UNIFIED IDEOGRAPH + {0x9F40, 0x6A97}, //4795 #CJK UNIFIED IDEOGRAPH + {0x9F41, 0x8617}, //4796 #CJK UNIFIED IDEOGRAPH + {0x9F42, 0x6ABB}, //4797 #CJK UNIFIED IDEOGRAPH + {0x9F43, 0x6AC3}, //4798 #CJK UNIFIED IDEOGRAPH + {0x9F44, 0x6AC2}, //4799 #CJK UNIFIED IDEOGRAPH + {0x9F45, 0x6AB8}, //4800 #CJK UNIFIED IDEOGRAPH + {0x9F46, 0x6AB3}, //4801 #CJK UNIFIED IDEOGRAPH + {0x9F47, 0x6AAC}, //4802 #CJK UNIFIED IDEOGRAPH + {0x9F48, 0x6ADE}, //4803 #CJK UNIFIED IDEOGRAPH + {0x9F49, 0x6AD1}, //4804 #CJK UNIFIED IDEOGRAPH + {0x9F4A, 0x6ADF}, //4805 #CJK UNIFIED IDEOGRAPH + {0x9F4B, 0x6AAA}, //4806 #CJK UNIFIED IDEOGRAPH + {0x9F4C, 0x6ADA}, //4807 #CJK UNIFIED IDEOGRAPH + {0x9F4D, 0x6AEA}, //4808 #CJK UNIFIED IDEOGRAPH + {0x9F4E, 0x6AFB}, //4809 #CJK UNIFIED IDEOGRAPH + {0x9F4F, 0x6B05}, //4810 #CJK UNIFIED IDEOGRAPH + {0x9F50, 0x8616}, //4811 #CJK UNIFIED IDEOGRAPH + {0x9F51, 0x6AFA}, //4812 #CJK UNIFIED IDEOGRAPH + {0x9F52, 0x6B12}, //4813 #CJK UNIFIED IDEOGRAPH + {0x9F53, 0x6B16}, //4814 #CJK UNIFIED IDEOGRAPH + {0x9F54, 0x9B31}, //4815 #CJK UNIFIED IDEOGRAPH + {0x9F55, 0x6B1F}, //4816 #CJK UNIFIED IDEOGRAPH + {0x9F56, 0x6B38}, //4817 #CJK UNIFIED IDEOGRAPH + {0x9F57, 0x6B37}, //4818 #CJK UNIFIED IDEOGRAPH + {0x9F58, 0x76DC}, //4819 #CJK UNIFIED IDEOGRAPH + {0x9F59, 0x6B39}, //4820 #CJK UNIFIED IDEOGRAPH + {0x9F5A, 0x98EE}, //4821 #CJK UNIFIED IDEOGRAPH + {0x9F5B, 0x6B47}, //4822 #CJK UNIFIED IDEOGRAPH + {0x9F5C, 0x6B43}, //4823 #CJK UNIFIED IDEOGRAPH + {0x9F5D, 0x6B49}, //4824 #CJK UNIFIED IDEOGRAPH + {0x9F5E, 0x6B50}, //4825 #CJK UNIFIED IDEOGRAPH + {0x9F5F, 0x6B59}, //4826 #CJK UNIFIED IDEOGRAPH + {0x9F60, 0x6B54}, //4827 #CJK UNIFIED IDEOGRAPH + {0x9F61, 0x6B5B}, //4828 #CJK UNIFIED IDEOGRAPH + {0x9F62, 0x6B5F}, //4829 #CJK UNIFIED IDEOGRAPH + {0x9F63, 0x6B61}, //4830 #CJK UNIFIED IDEOGRAPH + {0x9F64, 0x6B78}, //4831 #CJK UNIFIED IDEOGRAPH + {0x9F65, 0x6B79}, //4832 #CJK UNIFIED IDEOGRAPH + {0x9F66, 0x6B7F}, //4833 #CJK UNIFIED IDEOGRAPH + {0x9F67, 0x6B80}, //4834 #CJK UNIFIED IDEOGRAPH + {0x9F68, 0x6B84}, //4835 #CJK UNIFIED IDEOGRAPH + {0x9F69, 0x6B83}, //4836 #CJK UNIFIED IDEOGRAPH + {0x9F6A, 0x6B8D}, //4837 #CJK UNIFIED IDEOGRAPH + {0x9F6B, 0x6B98}, //4838 #CJK UNIFIED IDEOGRAPH + {0x9F6C, 0x6B95}, //4839 #CJK UNIFIED IDEOGRAPH + {0x9F6D, 0x6B9E}, //4840 #CJK UNIFIED IDEOGRAPH + {0x9F6E, 0x6BA4}, //4841 #CJK UNIFIED IDEOGRAPH + {0x9F6F, 0x6BAA}, //4842 #CJK UNIFIED IDEOGRAPH + {0x9F70, 0x6BAB}, //4843 #CJK UNIFIED IDEOGRAPH + {0x9F71, 0x6BAF}, //4844 #CJK UNIFIED IDEOGRAPH + {0x9F72, 0x6BB2}, //4845 #CJK UNIFIED IDEOGRAPH + {0x9F73, 0x6BB1}, //4846 #CJK UNIFIED IDEOGRAPH + {0x9F74, 0x6BB3}, //4847 #CJK UNIFIED IDEOGRAPH + {0x9F75, 0x6BB7}, //4848 #CJK UNIFIED IDEOGRAPH + {0x9F76, 0x6BBC}, //4849 #CJK UNIFIED IDEOGRAPH + {0x9F77, 0x6BC6}, //4850 #CJK UNIFIED IDEOGRAPH + {0x9F78, 0x6BCB}, //4851 #CJK UNIFIED IDEOGRAPH + {0x9F79, 0x6BD3}, //4852 #CJK UNIFIED IDEOGRAPH + {0x9F7A, 0x6BDF}, //4853 #CJK UNIFIED IDEOGRAPH + {0x9F7B, 0x6BEC}, //4854 #CJK UNIFIED IDEOGRAPH + {0x9F7C, 0x6BEB}, //4855 #CJK UNIFIED IDEOGRAPH + {0x9F7D, 0x6BF3}, //4856 #CJK UNIFIED IDEOGRAPH + {0x9F7E, 0x6BEF}, //4857 #CJK UNIFIED IDEOGRAPH + {0x9F80, 0x9EBE}, //4858 #CJK UNIFIED IDEOGRAPH + {0x9F81, 0x6C08}, //4859 #CJK UNIFIED IDEOGRAPH + {0x9F82, 0x6C13}, //4860 #CJK UNIFIED IDEOGRAPH + {0x9F83, 0x6C14}, //4861 #CJK UNIFIED IDEOGRAPH + {0x9F84, 0x6C1B}, //4862 #CJK UNIFIED IDEOGRAPH + {0x9F85, 0x6C24}, //4863 #CJK UNIFIED IDEOGRAPH + {0x9F86, 0x6C23}, //4864 #CJK UNIFIED IDEOGRAPH + {0x9F87, 0x6C5E}, //4865 #CJK UNIFIED IDEOGRAPH + {0x9F88, 0x6C55}, //4866 #CJK UNIFIED IDEOGRAPH + {0x9F89, 0x6C62}, //4867 #CJK UNIFIED IDEOGRAPH + {0x9F8A, 0x6C6A}, //4868 #CJK UNIFIED IDEOGRAPH + {0x9F8B, 0x6C82}, //4869 #CJK UNIFIED IDEOGRAPH + {0x9F8C, 0x6C8D}, //4870 #CJK UNIFIED IDEOGRAPH + {0x9F8D, 0x6C9A}, //4871 #CJK UNIFIED IDEOGRAPH + {0x9F8E, 0x6C81}, //4872 #CJK UNIFIED IDEOGRAPH + {0x9F8F, 0x6C9B}, //4873 #CJK UNIFIED IDEOGRAPH + {0x9F90, 0x6C7E}, //4874 #CJK UNIFIED IDEOGRAPH + {0x9F91, 0x6C68}, //4875 #CJK UNIFIED IDEOGRAPH + {0x9F92, 0x6C73}, //4876 #CJK UNIFIED IDEOGRAPH + {0x9F93, 0x6C92}, //4877 #CJK UNIFIED IDEOGRAPH + {0x9F94, 0x6C90}, //4878 #CJK UNIFIED IDEOGRAPH + {0x9F95, 0x6CC4}, //4879 #CJK UNIFIED IDEOGRAPH + {0x9F96, 0x6CF1}, //4880 #CJK UNIFIED IDEOGRAPH + {0x9F97, 0x6CD3}, //4881 #CJK UNIFIED IDEOGRAPH + {0x9F98, 0x6CBD}, //4882 #CJK UNIFIED IDEOGRAPH + {0x9F99, 0x6CD7}, //4883 #CJK UNIFIED IDEOGRAPH + {0x9F9A, 0x6CC5}, //4884 #CJK UNIFIED IDEOGRAPH + {0x9F9B, 0x6CDD}, //4885 #CJK UNIFIED IDEOGRAPH + {0x9F9C, 0x6CAE}, //4886 #CJK UNIFIED IDEOGRAPH + {0x9F9D, 0x6CB1}, //4887 #CJK UNIFIED IDEOGRAPH + {0x9F9E, 0x6CBE}, //4888 #CJK UNIFIED IDEOGRAPH + {0x9F9F, 0x6CBA}, //4889 #CJK UNIFIED IDEOGRAPH + {0x9FA0, 0x6CDB}, //4890 #CJK UNIFIED IDEOGRAPH + {0x9FA1, 0x6CEF}, //4891 #CJK UNIFIED IDEOGRAPH + {0x9FA2, 0x6CD9}, //4892 #CJK UNIFIED IDEOGRAPH + {0x9FA3, 0x6CEA}, //4893 #CJK UNIFIED IDEOGRAPH + {0x9FA4, 0x6D1F}, //4894 #CJK UNIFIED IDEOGRAPH + {0x9FA5, 0x884D}, //4895 #CJK UNIFIED IDEOGRAPH + {0x9FA6, 0x6D36}, //4896 #CJK UNIFIED IDEOGRAPH + {0x9FA7, 0x6D2B}, //4897 #CJK UNIFIED IDEOGRAPH + {0x9FA8, 0x6D3D}, //4898 #CJK UNIFIED IDEOGRAPH + {0x9FA9, 0x6D38}, //4899 #CJK UNIFIED IDEOGRAPH + {0x9FAA, 0x6D19}, //4900 #CJK UNIFIED IDEOGRAPH + {0x9FAB, 0x6D35}, //4901 #CJK UNIFIED IDEOGRAPH + {0x9FAC, 0x6D33}, //4902 #CJK UNIFIED IDEOGRAPH + {0x9FAD, 0x6D12}, //4903 #CJK UNIFIED IDEOGRAPH + {0x9FAE, 0x6D0C}, //4904 #CJK UNIFIED IDEOGRAPH + {0x9FAF, 0x6D63}, //4905 #CJK UNIFIED IDEOGRAPH + {0x9FB0, 0x6D93}, //4906 #CJK UNIFIED IDEOGRAPH + {0x9FB1, 0x6D64}, //4907 #CJK UNIFIED IDEOGRAPH + {0x9FB2, 0x6D5A}, //4908 #CJK UNIFIED IDEOGRAPH + {0x9FB3, 0x6D79}, //4909 #CJK UNIFIED IDEOGRAPH + {0x9FB4, 0x6D59}, //4910 #CJK UNIFIED IDEOGRAPH + {0x9FB5, 0x6D8E}, //4911 #CJK UNIFIED IDEOGRAPH + {0x9FB6, 0x6D95}, //4912 #CJK UNIFIED IDEOGRAPH + {0x9FB7, 0x6FE4}, //4913 #CJK UNIFIED IDEOGRAPH + {0x9FB8, 0x6D85}, //4914 #CJK UNIFIED IDEOGRAPH + {0x9FB9, 0x6DF9}, //4915 #CJK UNIFIED IDEOGRAPH + {0x9FBA, 0x6E15}, //4916 #CJK UNIFIED IDEOGRAPH + {0x9FBB, 0x6E0A}, //4917 #CJK UNIFIED IDEOGRAPH + {0x9FBC, 0x6DB5}, //4918 #CJK UNIFIED IDEOGRAPH + {0x9FBD, 0x6DC7}, //4919 #CJK UNIFIED IDEOGRAPH + {0x9FBE, 0x6DE6}, //4920 #CJK UNIFIED IDEOGRAPH + {0x9FBF, 0x6DB8}, //4921 #CJK UNIFIED IDEOGRAPH + {0x9FC0, 0x6DC6}, //4922 #CJK UNIFIED IDEOGRAPH + {0x9FC1, 0x6DEC}, //4923 #CJK UNIFIED IDEOGRAPH + {0x9FC2, 0x6DDE}, //4924 #CJK UNIFIED IDEOGRAPH + {0x9FC3, 0x6DCC}, //4925 #CJK UNIFIED IDEOGRAPH + {0x9FC4, 0x6DE8}, //4926 #CJK UNIFIED IDEOGRAPH + {0x9FC5, 0x6DD2}, //4927 #CJK UNIFIED IDEOGRAPH + {0x9FC6, 0x6DC5}, //4928 #CJK UNIFIED IDEOGRAPH + {0x9FC7, 0x6DFA}, //4929 #CJK UNIFIED IDEOGRAPH + {0x9FC8, 0x6DD9}, //4930 #CJK UNIFIED IDEOGRAPH + {0x9FC9, 0x6DE4}, //4931 #CJK UNIFIED IDEOGRAPH + {0x9FCA, 0x6DD5}, //4932 #CJK UNIFIED IDEOGRAPH + {0x9FCB, 0x6DEA}, //4933 #CJK UNIFIED IDEOGRAPH + {0x9FCC, 0x6DEE}, //4934 #CJK UNIFIED IDEOGRAPH + {0x9FCD, 0x6E2D}, //4935 #CJK UNIFIED IDEOGRAPH + {0x9FCE, 0x6E6E}, //4936 #CJK UNIFIED IDEOGRAPH + {0x9FCF, 0x6E2E}, //4937 #CJK UNIFIED IDEOGRAPH + {0x9FD0, 0x6E19}, //4938 #CJK UNIFIED IDEOGRAPH + {0x9FD1, 0x6E72}, //4939 #CJK UNIFIED IDEOGRAPH + {0x9FD2, 0x6E5F}, //4940 #CJK UNIFIED IDEOGRAPH + {0x9FD3, 0x6E3E}, //4941 #CJK UNIFIED IDEOGRAPH + {0x9FD4, 0x6E23}, //4942 #CJK UNIFIED IDEOGRAPH + {0x9FD5, 0x6E6B}, //4943 #CJK UNIFIED IDEOGRAPH + {0x9FD6, 0x6E2B}, //4944 #CJK UNIFIED IDEOGRAPH + {0x9FD7, 0x6E76}, //4945 #CJK UNIFIED IDEOGRAPH + {0x9FD8, 0x6E4D}, //4946 #CJK UNIFIED IDEOGRAPH + {0x9FD9, 0x6E1F}, //4947 #CJK UNIFIED IDEOGRAPH + {0x9FDA, 0x6E43}, //4948 #CJK UNIFIED IDEOGRAPH + {0x9FDB, 0x6E3A}, //4949 #CJK UNIFIED IDEOGRAPH + {0x9FDC, 0x6E4E}, //4950 #CJK UNIFIED IDEOGRAPH + {0x9FDD, 0x6E24}, //4951 #CJK UNIFIED IDEOGRAPH + {0x9FDE, 0x6EFF}, //4952 #CJK UNIFIED IDEOGRAPH + {0x9FDF, 0x6E1D}, //4953 #CJK UNIFIED IDEOGRAPH + {0x9FE0, 0x6E38}, //4954 #CJK UNIFIED IDEOGRAPH + {0x9FE1, 0x6E82}, //4955 #CJK UNIFIED IDEOGRAPH + {0x9FE2, 0x6EAA}, //4956 #CJK UNIFIED IDEOGRAPH + {0x9FE3, 0x6E98}, //4957 #CJK UNIFIED IDEOGRAPH + {0x9FE4, 0x6EC9}, //4958 #CJK UNIFIED IDEOGRAPH + {0x9FE5, 0x6EB7}, //4959 #CJK UNIFIED IDEOGRAPH + {0x9FE6, 0x6ED3}, //4960 #CJK UNIFIED IDEOGRAPH + {0x9FE7, 0x6EBD}, //4961 #CJK UNIFIED IDEOGRAPH + {0x9FE8, 0x6EAF}, //4962 #CJK UNIFIED IDEOGRAPH + {0x9FE9, 0x6EC4}, //4963 #CJK UNIFIED IDEOGRAPH + {0x9FEA, 0x6EB2}, //4964 #CJK UNIFIED IDEOGRAPH + {0x9FEB, 0x6ED4}, //4965 #CJK UNIFIED IDEOGRAPH + {0x9FEC, 0x6ED5}, //4966 #CJK UNIFIED IDEOGRAPH + {0x9FED, 0x6E8F}, //4967 #CJK UNIFIED IDEOGRAPH + {0x9FEE, 0x6EA5}, //4968 #CJK UNIFIED IDEOGRAPH + {0x9FEF, 0x6EC2}, //4969 #CJK UNIFIED IDEOGRAPH + {0x9FF0, 0x6E9F}, //4970 #CJK UNIFIED IDEOGRAPH + {0x9FF1, 0x6F41}, //4971 #CJK UNIFIED IDEOGRAPH + {0x9FF2, 0x6F11}, //4972 #CJK UNIFIED IDEOGRAPH + {0x9FF3, 0x704C}, //4973 #CJK UNIFIED IDEOGRAPH + {0x9FF4, 0x6EEC}, //4974 #CJK UNIFIED IDEOGRAPH + {0x9FF5, 0x6EF8}, //4975 #CJK UNIFIED IDEOGRAPH + {0x9FF6, 0x6EFE}, //4976 #CJK UNIFIED IDEOGRAPH + {0x9FF7, 0x6F3F}, //4977 #CJK UNIFIED IDEOGRAPH + {0x9FF8, 0x6EF2}, //4978 #CJK UNIFIED IDEOGRAPH + {0x9FF9, 0x6F31}, //4979 #CJK UNIFIED IDEOGRAPH + {0x9FFA, 0x6EEF}, //4980 #CJK UNIFIED IDEOGRAPH + {0x9FFB, 0x6F32}, //4981 #CJK UNIFIED IDEOGRAPH + {0x9FFC, 0x6ECC}, //4982 #CJK UNIFIED IDEOGRAPH + {0xE040, 0x6F3E}, //4983 #CJK UNIFIED IDEOGRAPH + {0xE041, 0x6F13}, //4984 #CJK UNIFIED IDEOGRAPH + {0xE042, 0x6EF7}, //4985 #CJK UNIFIED IDEOGRAPH + {0xE043, 0x6F86}, //4986 #CJK UNIFIED IDEOGRAPH + {0xE044, 0x6F7A}, //4987 #CJK UNIFIED IDEOGRAPH + {0xE045, 0x6F78}, //4988 #CJK UNIFIED IDEOGRAPH + {0xE046, 0x6F81}, //4989 #CJK UNIFIED IDEOGRAPH + {0xE047, 0x6F80}, //4990 #CJK UNIFIED IDEOGRAPH + {0xE048, 0x6F6F}, //4991 #CJK UNIFIED IDEOGRAPH + {0xE049, 0x6F5B}, //4992 #CJK UNIFIED IDEOGRAPH + {0xE04A, 0x6FF3}, //4993 #CJK UNIFIED IDEOGRAPH + {0xE04B, 0x6F6D}, //4994 #CJK UNIFIED IDEOGRAPH + {0xE04C, 0x6F82}, //4995 #CJK UNIFIED IDEOGRAPH + {0xE04D, 0x6F7C}, //4996 #CJK UNIFIED IDEOGRAPH + {0xE04E, 0x6F58}, //4997 #CJK UNIFIED IDEOGRAPH + {0xE04F, 0x6F8E}, //4998 #CJK UNIFIED IDEOGRAPH + {0xE050, 0x6F91}, //4999 #CJK UNIFIED IDEOGRAPH + {0xE051, 0x6FC2}, //5000 #CJK UNIFIED IDEOGRAPH + {0xE052, 0x6F66}, //5001 #CJK UNIFIED IDEOGRAPH + {0xE053, 0x6FB3}, //5002 #CJK UNIFIED IDEOGRAPH + {0xE054, 0x6FA3}, //5003 #CJK UNIFIED IDEOGRAPH + {0xE055, 0x6FA1}, //5004 #CJK UNIFIED IDEOGRAPH + {0xE056, 0x6FA4}, //5005 #CJK UNIFIED IDEOGRAPH + {0xE057, 0x6FB9}, //5006 #CJK UNIFIED IDEOGRAPH + {0xE058, 0x6FC6}, //5007 #CJK UNIFIED IDEOGRAPH + {0xE059, 0x6FAA}, //5008 #CJK UNIFIED IDEOGRAPH + {0xE05A, 0x6FDF}, //5009 #CJK UNIFIED IDEOGRAPH + {0xE05B, 0x6FD5}, //5010 #CJK UNIFIED IDEOGRAPH + {0xE05C, 0x6FEC}, //5011 #CJK UNIFIED IDEOGRAPH + {0xE05D, 0x6FD4}, //5012 #CJK UNIFIED IDEOGRAPH + {0xE05E, 0x6FD8}, //5013 #CJK UNIFIED IDEOGRAPH + {0xE05F, 0x6FF1}, //5014 #CJK UNIFIED IDEOGRAPH + {0xE060, 0x6FEE}, //5015 #CJK UNIFIED IDEOGRAPH + {0xE061, 0x6FDB}, //5016 #CJK UNIFIED IDEOGRAPH + {0xE062, 0x7009}, //5017 #CJK UNIFIED IDEOGRAPH + {0xE063, 0x700B}, //5018 #CJK UNIFIED IDEOGRAPH + {0xE064, 0x6FFA}, //5019 #CJK UNIFIED IDEOGRAPH + {0xE065, 0x7011}, //5020 #CJK UNIFIED IDEOGRAPH + {0xE066, 0x7001}, //5021 #CJK UNIFIED IDEOGRAPH + {0xE067, 0x700F}, //5022 #CJK UNIFIED IDEOGRAPH + {0xE068, 0x6FFE}, //5023 #CJK UNIFIED IDEOGRAPH + {0xE069, 0x701B}, //5024 #CJK UNIFIED IDEOGRAPH + {0xE06A, 0x701A}, //5025 #CJK UNIFIED IDEOGRAPH + {0xE06B, 0x6F74}, //5026 #CJK UNIFIED IDEOGRAPH + {0xE06C, 0x701D}, //5027 #CJK UNIFIED IDEOGRAPH + {0xE06D, 0x7018}, //5028 #CJK UNIFIED IDEOGRAPH + {0xE06E, 0x701F}, //5029 #CJK UNIFIED IDEOGRAPH + {0xE06F, 0x7030}, //5030 #CJK UNIFIED IDEOGRAPH + {0xE070, 0x703E}, //5031 #CJK UNIFIED IDEOGRAPH + {0xE071, 0x7032}, //5032 #CJK UNIFIED IDEOGRAPH + {0xE072, 0x7051}, //5033 #CJK UNIFIED IDEOGRAPH + {0xE073, 0x7063}, //5034 #CJK UNIFIED IDEOGRAPH + {0xE074, 0x7099}, //5035 #CJK UNIFIED IDEOGRAPH + {0xE075, 0x7092}, //5036 #CJK UNIFIED IDEOGRAPH + {0xE076, 0x70AF}, //5037 #CJK UNIFIED IDEOGRAPH + {0xE077, 0x70F1}, //5038 #CJK UNIFIED IDEOGRAPH + {0xE078, 0x70AC}, //5039 #CJK UNIFIED IDEOGRAPH + {0xE079, 0x70B8}, //5040 #CJK UNIFIED IDEOGRAPH + {0xE07A, 0x70B3}, //5041 #CJK UNIFIED IDEOGRAPH + {0xE07B, 0x70AE}, //5042 #CJK UNIFIED IDEOGRAPH + {0xE07C, 0x70DF}, //5043 #CJK UNIFIED IDEOGRAPH + {0xE07D, 0x70CB}, //5044 #CJK UNIFIED IDEOGRAPH + {0xE07E, 0x70DD}, //5045 #CJK UNIFIED IDEOGRAPH + {0xE080, 0x70D9}, //5046 #CJK UNIFIED IDEOGRAPH + {0xE081, 0x7109}, //5047 #CJK UNIFIED IDEOGRAPH + {0xE082, 0x70FD}, //5048 #CJK UNIFIED IDEOGRAPH + {0xE083, 0x711C}, //5049 #CJK UNIFIED IDEOGRAPH + {0xE084, 0x7119}, //5050 #CJK UNIFIED IDEOGRAPH + {0xE085, 0x7165}, //5051 #CJK UNIFIED IDEOGRAPH + {0xE086, 0x7155}, //5052 #CJK UNIFIED IDEOGRAPH + {0xE087, 0x7188}, //5053 #CJK UNIFIED IDEOGRAPH + {0xE088, 0x7166}, //5054 #CJK UNIFIED IDEOGRAPH + {0xE089, 0x7162}, //5055 #CJK UNIFIED IDEOGRAPH + {0xE08A, 0x714C}, //5056 #CJK UNIFIED IDEOGRAPH + {0xE08B, 0x7156}, //5057 #CJK UNIFIED IDEOGRAPH + {0xE08C, 0x716C}, //5058 #CJK UNIFIED IDEOGRAPH + {0xE08D, 0x718F}, //5059 #CJK UNIFIED IDEOGRAPH + {0xE08E, 0x71FB}, //5060 #CJK UNIFIED IDEOGRAPH + {0xE08F, 0x7184}, //5061 #CJK UNIFIED IDEOGRAPH + {0xE090, 0x7195}, //5062 #CJK UNIFIED IDEOGRAPH + {0xE091, 0x71A8}, //5063 #CJK UNIFIED IDEOGRAPH + {0xE092, 0x71AC}, //5064 #CJK UNIFIED IDEOGRAPH + {0xE093, 0x71D7}, //5065 #CJK UNIFIED IDEOGRAPH + {0xE094, 0x71B9}, //5066 #CJK UNIFIED IDEOGRAPH + {0xE095, 0x71BE}, //5067 #CJK UNIFIED IDEOGRAPH + {0xE096, 0x71D2}, //5068 #CJK UNIFIED IDEOGRAPH + {0xE097, 0x71C9}, //5069 #CJK UNIFIED IDEOGRAPH + {0xE098, 0x71D4}, //5070 #CJK UNIFIED IDEOGRAPH + {0xE099, 0x71CE}, //5071 #CJK UNIFIED IDEOGRAPH + {0xE09A, 0x71E0}, //5072 #CJK UNIFIED IDEOGRAPH + {0xE09B, 0x71EC}, //5073 #CJK UNIFIED IDEOGRAPH + {0xE09C, 0x71E7}, //5074 #CJK UNIFIED IDEOGRAPH + {0xE09D, 0x71F5}, //5075 #CJK UNIFIED IDEOGRAPH + {0xE09E, 0x71FC}, //5076 #CJK UNIFIED IDEOGRAPH + {0xE09F, 0x71F9}, //5077 #CJK UNIFIED IDEOGRAPH + {0xE0A0, 0x71FF}, //5078 #CJK UNIFIED IDEOGRAPH + {0xE0A1, 0x720D}, //5079 #CJK UNIFIED IDEOGRAPH + {0xE0A2, 0x7210}, //5080 #CJK UNIFIED IDEOGRAPH + {0xE0A3, 0x721B}, //5081 #CJK UNIFIED IDEOGRAPH + {0xE0A4, 0x7228}, //5082 #CJK UNIFIED IDEOGRAPH + {0xE0A5, 0x722D}, //5083 #CJK UNIFIED IDEOGRAPH + {0xE0A6, 0x722C}, //5084 #CJK UNIFIED IDEOGRAPH + {0xE0A7, 0x7230}, //5085 #CJK UNIFIED IDEOGRAPH + {0xE0A8, 0x7232}, //5086 #CJK UNIFIED IDEOGRAPH + {0xE0A9, 0x723B}, //5087 #CJK UNIFIED IDEOGRAPH + {0xE0AA, 0x723C}, //5088 #CJK UNIFIED IDEOGRAPH + {0xE0AB, 0x723F}, //5089 #CJK UNIFIED IDEOGRAPH + {0xE0AC, 0x7240}, //5090 #CJK UNIFIED IDEOGRAPH + {0xE0AD, 0x7246}, //5091 #CJK UNIFIED IDEOGRAPH + {0xE0AE, 0x724B}, //5092 #CJK UNIFIED IDEOGRAPH + {0xE0AF, 0x7258}, //5093 #CJK UNIFIED IDEOGRAPH + {0xE0B0, 0x7274}, //5094 #CJK UNIFIED IDEOGRAPH + {0xE0B1, 0x727E}, //5095 #CJK UNIFIED IDEOGRAPH + {0xE0B2, 0x7282}, //5096 #CJK UNIFIED IDEOGRAPH + {0xE0B3, 0x7281}, //5097 #CJK UNIFIED IDEOGRAPH + {0xE0B4, 0x7287}, //5098 #CJK UNIFIED IDEOGRAPH + {0xE0B5, 0x7292}, //5099 #CJK UNIFIED IDEOGRAPH + {0xE0B6, 0x7296}, //5100 #CJK UNIFIED IDEOGRAPH + {0xE0B7, 0x72A2}, //5101 #CJK UNIFIED IDEOGRAPH + {0xE0B8, 0x72A7}, //5102 #CJK UNIFIED IDEOGRAPH + {0xE0B9, 0x72B9}, //5103 #CJK UNIFIED IDEOGRAPH + {0xE0BA, 0x72B2}, //5104 #CJK UNIFIED IDEOGRAPH + {0xE0BB, 0x72C3}, //5105 #CJK UNIFIED IDEOGRAPH + {0xE0BC, 0x72C6}, //5106 #CJK UNIFIED IDEOGRAPH + {0xE0BD, 0x72C4}, //5107 #CJK UNIFIED IDEOGRAPH + {0xE0BE, 0x72CE}, //5108 #CJK UNIFIED IDEOGRAPH + {0xE0BF, 0x72D2}, //5109 #CJK UNIFIED IDEOGRAPH + {0xE0C0, 0x72E2}, //5110 #CJK UNIFIED IDEOGRAPH + {0xE0C1, 0x72E0}, //5111 #CJK UNIFIED IDEOGRAPH + {0xE0C2, 0x72E1}, //5112 #CJK UNIFIED IDEOGRAPH + {0xE0C3, 0x72F9}, //5113 #CJK UNIFIED IDEOGRAPH + {0xE0C4, 0x72F7}, //5114 #CJK UNIFIED IDEOGRAPH + {0xE0C5, 0x500F}, //5115 #CJK UNIFIED IDEOGRAPH + {0xE0C6, 0x7317}, //5116 #CJK UNIFIED IDEOGRAPH + {0xE0C7, 0x730A}, //5117 #CJK UNIFIED IDEOGRAPH + {0xE0C8, 0x731C}, //5118 #CJK UNIFIED IDEOGRAPH + {0xE0C9, 0x7316}, //5119 #CJK UNIFIED IDEOGRAPH + {0xE0CA, 0x731D}, //5120 #CJK UNIFIED IDEOGRAPH + {0xE0CB, 0x7334}, //5121 #CJK UNIFIED IDEOGRAPH + {0xE0CC, 0x732F}, //5122 #CJK UNIFIED IDEOGRAPH + {0xE0CD, 0x7329}, //5123 #CJK UNIFIED IDEOGRAPH + {0xE0CE, 0x7325}, //5124 #CJK UNIFIED IDEOGRAPH + {0xE0CF, 0x733E}, //5125 #CJK UNIFIED IDEOGRAPH + {0xE0D0, 0x734E}, //5126 #CJK UNIFIED IDEOGRAPH + {0xE0D1, 0x734F}, //5127 #CJK UNIFIED IDEOGRAPH + {0xE0D2, 0x9ED8}, //5128 #CJK UNIFIED IDEOGRAPH + {0xE0D3, 0x7357}, //5129 #CJK UNIFIED IDEOGRAPH + {0xE0D4, 0x736A}, //5130 #CJK UNIFIED IDEOGRAPH + {0xE0D5, 0x7368}, //5131 #CJK UNIFIED IDEOGRAPH + {0xE0D6, 0x7370}, //5132 #CJK UNIFIED IDEOGRAPH + {0xE0D7, 0x7378}, //5133 #CJK UNIFIED IDEOGRAPH + {0xE0D8, 0x7375}, //5134 #CJK UNIFIED IDEOGRAPH + {0xE0D9, 0x737B}, //5135 #CJK UNIFIED IDEOGRAPH + {0xE0DA, 0x737A}, //5136 #CJK UNIFIED IDEOGRAPH + {0xE0DB, 0x73C8}, //5137 #CJK UNIFIED IDEOGRAPH + {0xE0DC, 0x73B3}, //5138 #CJK UNIFIED IDEOGRAPH + {0xE0DD, 0x73CE}, //5139 #CJK UNIFIED IDEOGRAPH + {0xE0DE, 0x73BB}, //5140 #CJK UNIFIED IDEOGRAPH + {0xE0DF, 0x73C0}, //5141 #CJK UNIFIED IDEOGRAPH + {0xE0E0, 0x73E5}, //5142 #CJK UNIFIED IDEOGRAPH + {0xE0E1, 0x73EE}, //5143 #CJK UNIFIED IDEOGRAPH + {0xE0E2, 0x73DE}, //5144 #CJK UNIFIED IDEOGRAPH + {0xE0E3, 0x74A2}, //5145 #CJK UNIFIED IDEOGRAPH + {0xE0E4, 0x7405}, //5146 #CJK UNIFIED IDEOGRAPH + {0xE0E5, 0x746F}, //5147 #CJK UNIFIED IDEOGRAPH + {0xE0E6, 0x7425}, //5148 #CJK UNIFIED IDEOGRAPH + {0xE0E7, 0x73F8}, //5149 #CJK UNIFIED IDEOGRAPH + {0xE0E8, 0x7432}, //5150 #CJK UNIFIED IDEOGRAPH + {0xE0E9, 0x743A}, //5151 #CJK UNIFIED IDEOGRAPH + {0xE0EA, 0x7455}, //5152 #CJK UNIFIED IDEOGRAPH + {0xE0EB, 0x743F}, //5153 #CJK UNIFIED IDEOGRAPH + {0xE0EC, 0x745F}, //5154 #CJK UNIFIED IDEOGRAPH + {0xE0ED, 0x7459}, //5155 #CJK UNIFIED IDEOGRAPH + {0xE0EE, 0x7441}, //5156 #CJK UNIFIED IDEOGRAPH + {0xE0EF, 0x745C}, //5157 #CJK UNIFIED IDEOGRAPH + {0xE0F0, 0x7469}, //5158 #CJK UNIFIED IDEOGRAPH + {0xE0F1, 0x7470}, //5159 #CJK UNIFIED IDEOGRAPH + {0xE0F2, 0x7463}, //5160 #CJK UNIFIED IDEOGRAPH + {0xE0F3, 0x746A}, //5161 #CJK UNIFIED IDEOGRAPH + {0xE0F4, 0x7476}, //5162 #CJK UNIFIED IDEOGRAPH + {0xE0F5, 0x747E}, //5163 #CJK UNIFIED IDEOGRAPH + {0xE0F6, 0x748B}, //5164 #CJK UNIFIED IDEOGRAPH + {0xE0F7, 0x749E}, //5165 #CJK UNIFIED IDEOGRAPH + {0xE0F8, 0x74A7}, //5166 #CJK UNIFIED IDEOGRAPH + {0xE0F9, 0x74CA}, //5167 #CJK UNIFIED IDEOGRAPH + {0xE0FA, 0x74CF}, //5168 #CJK UNIFIED IDEOGRAPH + {0xE0FB, 0x74D4}, //5169 #CJK UNIFIED IDEOGRAPH + {0xE0FC, 0x73F1}, //5170 #CJK UNIFIED IDEOGRAPH + {0xE140, 0x74E0}, //5171 #CJK UNIFIED IDEOGRAPH + {0xE141, 0x74E3}, //5172 #CJK UNIFIED IDEOGRAPH + {0xE142, 0x74E7}, //5173 #CJK UNIFIED IDEOGRAPH + {0xE143, 0x74E9}, //5174 #CJK UNIFIED IDEOGRAPH + {0xE144, 0x74EE}, //5175 #CJK UNIFIED IDEOGRAPH + {0xE145, 0x74F2}, //5176 #CJK UNIFIED IDEOGRAPH + {0xE146, 0x74F0}, //5177 #CJK UNIFIED IDEOGRAPH + {0xE147, 0x74F1}, //5178 #CJK UNIFIED IDEOGRAPH + {0xE148, 0x74F8}, //5179 #CJK UNIFIED IDEOGRAPH + {0xE149, 0x74F7}, //5180 #CJK UNIFIED IDEOGRAPH + {0xE14A, 0x7504}, //5181 #CJK UNIFIED IDEOGRAPH + {0xE14B, 0x7503}, //5182 #CJK UNIFIED IDEOGRAPH + {0xE14C, 0x7505}, //5183 #CJK UNIFIED IDEOGRAPH + {0xE14D, 0x750C}, //5184 #CJK UNIFIED IDEOGRAPH + {0xE14E, 0x750E}, //5185 #CJK UNIFIED IDEOGRAPH + {0xE14F, 0x750D}, //5186 #CJK UNIFIED IDEOGRAPH + {0xE150, 0x7515}, //5187 #CJK UNIFIED IDEOGRAPH + {0xE151, 0x7513}, //5188 #CJK UNIFIED IDEOGRAPH + {0xE152, 0x751E}, //5189 #CJK UNIFIED IDEOGRAPH + {0xE153, 0x7526}, //5190 #CJK UNIFIED IDEOGRAPH + {0xE154, 0x752C}, //5191 #CJK UNIFIED IDEOGRAPH + {0xE155, 0x753C}, //5192 #CJK UNIFIED IDEOGRAPH + {0xE156, 0x7544}, //5193 #CJK UNIFIED IDEOGRAPH + {0xE157, 0x754D}, //5194 #CJK UNIFIED IDEOGRAPH + {0xE158, 0x754A}, //5195 #CJK UNIFIED IDEOGRAPH + {0xE159, 0x7549}, //5196 #CJK UNIFIED IDEOGRAPH + {0xE15A, 0x755B}, //5197 #CJK UNIFIED IDEOGRAPH + {0xE15B, 0x7546}, //5198 #CJK UNIFIED IDEOGRAPH + {0xE15C, 0x755A}, //5199 #CJK UNIFIED IDEOGRAPH + {0xE15D, 0x7569}, //5200 #CJK UNIFIED IDEOGRAPH + {0xE15E, 0x7564}, //5201 #CJK UNIFIED IDEOGRAPH + {0xE15F, 0x7567}, //5202 #CJK UNIFIED IDEOGRAPH + {0xE160, 0x756B}, //5203 #CJK UNIFIED IDEOGRAPH + {0xE161, 0x756D}, //5204 #CJK UNIFIED IDEOGRAPH + {0xE162, 0x7578}, //5205 #CJK UNIFIED IDEOGRAPH + {0xE163, 0x7576}, //5206 #CJK UNIFIED IDEOGRAPH + {0xE164, 0x7586}, //5207 #CJK UNIFIED IDEOGRAPH + {0xE165, 0x7587}, //5208 #CJK UNIFIED IDEOGRAPH + {0xE166, 0x7574}, //5209 #CJK UNIFIED IDEOGRAPH + {0xE167, 0x758A}, //5210 #CJK UNIFIED IDEOGRAPH + {0xE168, 0x7589}, //5211 #CJK UNIFIED IDEOGRAPH + {0xE169, 0x7582}, //5212 #CJK UNIFIED IDEOGRAPH + {0xE16A, 0x7594}, //5213 #CJK UNIFIED IDEOGRAPH + {0xE16B, 0x759A}, //5214 #CJK UNIFIED IDEOGRAPH + {0xE16C, 0x759D}, //5215 #CJK UNIFIED IDEOGRAPH + {0xE16D, 0x75A5}, //5216 #CJK UNIFIED IDEOGRAPH + {0xE16E, 0x75A3}, //5217 #CJK UNIFIED IDEOGRAPH + {0xE16F, 0x75C2}, //5218 #CJK UNIFIED IDEOGRAPH + {0xE170, 0x75B3}, //5219 #CJK UNIFIED IDEOGRAPH + {0xE171, 0x75C3}, //5220 #CJK UNIFIED IDEOGRAPH + {0xE172, 0x75B5}, //5221 #CJK UNIFIED IDEOGRAPH + {0xE173, 0x75BD}, //5222 #CJK UNIFIED IDEOGRAPH + {0xE174, 0x75B8}, //5223 #CJK UNIFIED IDEOGRAPH + {0xE175, 0x75BC}, //5224 #CJK UNIFIED IDEOGRAPH + {0xE176, 0x75B1}, //5225 #CJK UNIFIED IDEOGRAPH + {0xE177, 0x75CD}, //5226 #CJK UNIFIED IDEOGRAPH + {0xE178, 0x75CA}, //5227 #CJK UNIFIED IDEOGRAPH + {0xE179, 0x75D2}, //5228 #CJK UNIFIED IDEOGRAPH + {0xE17A, 0x75D9}, //5229 #CJK UNIFIED IDEOGRAPH + {0xE17B, 0x75E3}, //5230 #CJK UNIFIED IDEOGRAPH + {0xE17C, 0x75DE}, //5231 #CJK UNIFIED IDEOGRAPH + {0xE17D, 0x75FE}, //5232 #CJK UNIFIED IDEOGRAPH + {0xE17E, 0x75FF}, //5233 #CJK UNIFIED IDEOGRAPH + {0xE180, 0x75FC}, //5234 #CJK UNIFIED IDEOGRAPH + {0xE181, 0x7601}, //5235 #CJK UNIFIED IDEOGRAPH + {0xE182, 0x75F0}, //5236 #CJK UNIFIED IDEOGRAPH + {0xE183, 0x75FA}, //5237 #CJK UNIFIED IDEOGRAPH + {0xE184, 0x75F2}, //5238 #CJK UNIFIED IDEOGRAPH + {0xE185, 0x75F3}, //5239 #CJK UNIFIED IDEOGRAPH + {0xE186, 0x760B}, //5240 #CJK UNIFIED IDEOGRAPH + {0xE187, 0x760D}, //5241 #CJK UNIFIED IDEOGRAPH + {0xE188, 0x7609}, //5242 #CJK UNIFIED IDEOGRAPH + {0xE189, 0x761F}, //5243 #CJK UNIFIED IDEOGRAPH + {0xE18A, 0x7627}, //5244 #CJK UNIFIED IDEOGRAPH + {0xE18B, 0x7620}, //5245 #CJK UNIFIED IDEOGRAPH + {0xE18C, 0x7621}, //5246 #CJK UNIFIED IDEOGRAPH + {0xE18D, 0x7622}, //5247 #CJK UNIFIED IDEOGRAPH + {0xE18E, 0x7624}, //5248 #CJK UNIFIED IDEOGRAPH + {0xE18F, 0x7634}, //5249 #CJK UNIFIED IDEOGRAPH + {0xE190, 0x7630}, //5250 #CJK UNIFIED IDEOGRAPH + {0xE191, 0x763B}, //5251 #CJK UNIFIED IDEOGRAPH + {0xE192, 0x7647}, //5252 #CJK UNIFIED IDEOGRAPH + {0xE193, 0x7648}, //5253 #CJK UNIFIED IDEOGRAPH + {0xE194, 0x7646}, //5254 #CJK UNIFIED IDEOGRAPH + {0xE195, 0x765C}, //5255 #CJK UNIFIED IDEOGRAPH + {0xE196, 0x7658}, //5256 #CJK UNIFIED IDEOGRAPH + {0xE197, 0x7661}, //5257 #CJK UNIFIED IDEOGRAPH + {0xE198, 0x7662}, //5258 #CJK UNIFIED IDEOGRAPH + {0xE199, 0x7668}, //5259 #CJK UNIFIED IDEOGRAPH + {0xE19A, 0x7669}, //5260 #CJK UNIFIED IDEOGRAPH + {0xE19B, 0x766A}, //5261 #CJK UNIFIED IDEOGRAPH + {0xE19C, 0x7667}, //5262 #CJK UNIFIED IDEOGRAPH + {0xE19D, 0x766C}, //5263 #CJK UNIFIED IDEOGRAPH + {0xE19E, 0x7670}, //5264 #CJK UNIFIED IDEOGRAPH + {0xE19F, 0x7672}, //5265 #CJK UNIFIED IDEOGRAPH + {0xE1A0, 0x7676}, //5266 #CJK UNIFIED IDEOGRAPH + {0xE1A1, 0x7678}, //5267 #CJK UNIFIED IDEOGRAPH + {0xE1A2, 0x767C}, //5268 #CJK UNIFIED IDEOGRAPH + {0xE1A3, 0x7680}, //5269 #CJK UNIFIED IDEOGRAPH + {0xE1A4, 0x7683}, //5270 #CJK UNIFIED IDEOGRAPH + {0xE1A5, 0x7688}, //5271 #CJK UNIFIED IDEOGRAPH + {0xE1A6, 0x768B}, //5272 #CJK UNIFIED IDEOGRAPH + {0xE1A7, 0x768E}, //5273 #CJK UNIFIED IDEOGRAPH + {0xE1A8, 0x7696}, //5274 #CJK UNIFIED IDEOGRAPH + {0xE1A9, 0x7693}, //5275 #CJK UNIFIED IDEOGRAPH + {0xE1AA, 0x7699}, //5276 #CJK UNIFIED IDEOGRAPH + {0xE1AB, 0x769A}, //5277 #CJK UNIFIED IDEOGRAPH + {0xE1AC, 0x76B0}, //5278 #CJK UNIFIED IDEOGRAPH + {0xE1AD, 0x76B4}, //5279 #CJK UNIFIED IDEOGRAPH + {0xE1AE, 0x76B8}, //5280 #CJK UNIFIED IDEOGRAPH + {0xE1AF, 0x76B9}, //5281 #CJK UNIFIED IDEOGRAPH + {0xE1B0, 0x76BA}, //5282 #CJK UNIFIED IDEOGRAPH + {0xE1B1, 0x76C2}, //5283 #CJK UNIFIED IDEOGRAPH + {0xE1B2, 0x76CD}, //5284 #CJK UNIFIED IDEOGRAPH + {0xE1B3, 0x76D6}, //5285 #CJK UNIFIED IDEOGRAPH + {0xE1B4, 0x76D2}, //5286 #CJK UNIFIED IDEOGRAPH + {0xE1B5, 0x76DE}, //5287 #CJK UNIFIED IDEOGRAPH + {0xE1B6, 0x76E1}, //5288 #CJK UNIFIED IDEOGRAPH + {0xE1B7, 0x76E5}, //5289 #CJK UNIFIED IDEOGRAPH + {0xE1B8, 0x76E7}, //5290 #CJK UNIFIED IDEOGRAPH + {0xE1B9, 0x76EA}, //5291 #CJK UNIFIED IDEOGRAPH + {0xE1BA, 0x862F}, //5292 #CJK UNIFIED IDEOGRAPH + {0xE1BB, 0x76FB}, //5293 #CJK UNIFIED IDEOGRAPH + {0xE1BC, 0x7708}, //5294 #CJK UNIFIED IDEOGRAPH + {0xE1BD, 0x7707}, //5295 #CJK UNIFIED IDEOGRAPH + {0xE1BE, 0x7704}, //5296 #CJK UNIFIED IDEOGRAPH + {0xE1BF, 0x7729}, //5297 #CJK UNIFIED IDEOGRAPH + {0xE1C0, 0x7724}, //5298 #CJK UNIFIED IDEOGRAPH + {0xE1C1, 0x771E}, //5299 #CJK UNIFIED IDEOGRAPH + {0xE1C2, 0x7725}, //5300 #CJK UNIFIED IDEOGRAPH + {0xE1C3, 0x7726}, //5301 #CJK UNIFIED IDEOGRAPH + {0xE1C4, 0x771B}, //5302 #CJK UNIFIED IDEOGRAPH + {0xE1C5, 0x7737}, //5303 #CJK UNIFIED IDEOGRAPH + {0xE1C6, 0x7738}, //5304 #CJK UNIFIED IDEOGRAPH + {0xE1C7, 0x7747}, //5305 #CJK UNIFIED IDEOGRAPH + {0xE1C8, 0x775A}, //5306 #CJK UNIFIED IDEOGRAPH + {0xE1C9, 0x7768}, //5307 #CJK UNIFIED IDEOGRAPH + {0xE1CA, 0x776B}, //5308 #CJK UNIFIED IDEOGRAPH + {0xE1CB, 0x775B}, //5309 #CJK UNIFIED IDEOGRAPH + {0xE1CC, 0x7765}, //5310 #CJK UNIFIED IDEOGRAPH + {0xE1CD, 0x777F}, //5311 #CJK UNIFIED IDEOGRAPH + {0xE1CE, 0x777E}, //5312 #CJK UNIFIED IDEOGRAPH + {0xE1CF, 0x7779}, //5313 #CJK UNIFIED IDEOGRAPH + {0xE1D0, 0x778E}, //5314 #CJK UNIFIED IDEOGRAPH + {0xE1D1, 0x778B}, //5315 #CJK UNIFIED IDEOGRAPH + {0xE1D2, 0x7791}, //5316 #CJK UNIFIED IDEOGRAPH + {0xE1D3, 0x77A0}, //5317 #CJK UNIFIED IDEOGRAPH + {0xE1D4, 0x779E}, //5318 #CJK UNIFIED IDEOGRAPH + {0xE1D5, 0x77B0}, //5319 #CJK UNIFIED IDEOGRAPH + {0xE1D6, 0x77B6}, //5320 #CJK UNIFIED IDEOGRAPH + {0xE1D7, 0x77B9}, //5321 #CJK UNIFIED IDEOGRAPH + {0xE1D8, 0x77BF}, //5322 #CJK UNIFIED IDEOGRAPH + {0xE1D9, 0x77BC}, //5323 #CJK UNIFIED IDEOGRAPH + {0xE1DA, 0x77BD}, //5324 #CJK UNIFIED IDEOGRAPH + {0xE1DB, 0x77BB}, //5325 #CJK UNIFIED IDEOGRAPH + {0xE1DC, 0x77C7}, //5326 #CJK UNIFIED IDEOGRAPH + {0xE1DD, 0x77CD}, //5327 #CJK UNIFIED IDEOGRAPH + {0xE1DE, 0x77D7}, //5328 #CJK UNIFIED IDEOGRAPH + {0xE1DF, 0x77DA}, //5329 #CJK UNIFIED IDEOGRAPH + {0xE1E0, 0x77DC}, //5330 #CJK UNIFIED IDEOGRAPH + {0xE1E1, 0x77E3}, //5331 #CJK UNIFIED IDEOGRAPH + {0xE1E2, 0x77EE}, //5332 #CJK UNIFIED IDEOGRAPH + {0xE1E3, 0x77FC}, //5333 #CJK UNIFIED IDEOGRAPH + {0xE1E4, 0x780C}, //5334 #CJK UNIFIED IDEOGRAPH + {0xE1E5, 0x7812}, //5335 #CJK UNIFIED IDEOGRAPH + {0xE1E6, 0x7926}, //5336 #CJK UNIFIED IDEOGRAPH + {0xE1E7, 0x7820}, //5337 #CJK UNIFIED IDEOGRAPH + {0xE1E8, 0x792A}, //5338 #CJK UNIFIED IDEOGRAPH + {0xE1E9, 0x7845}, //5339 #CJK UNIFIED IDEOGRAPH + {0xE1EA, 0x788E}, //5340 #CJK UNIFIED IDEOGRAPH + {0xE1EB, 0x7874}, //5341 #CJK UNIFIED IDEOGRAPH + {0xE1EC, 0x7886}, //5342 #CJK UNIFIED IDEOGRAPH + {0xE1ED, 0x787C}, //5343 #CJK UNIFIED IDEOGRAPH + {0xE1EE, 0x789A}, //5344 #CJK UNIFIED IDEOGRAPH + {0xE1EF, 0x788C}, //5345 #CJK UNIFIED IDEOGRAPH + {0xE1F0, 0x78A3}, //5346 #CJK UNIFIED IDEOGRAPH + {0xE1F1, 0x78B5}, //5347 #CJK UNIFIED IDEOGRAPH + {0xE1F2, 0x78AA}, //5348 #CJK UNIFIED IDEOGRAPH + {0xE1F3, 0x78AF}, //5349 #CJK UNIFIED IDEOGRAPH + {0xE1F4, 0x78D1}, //5350 #CJK UNIFIED IDEOGRAPH + {0xE1F5, 0x78C6}, //5351 #CJK UNIFIED IDEOGRAPH + {0xE1F6, 0x78CB}, //5352 #CJK UNIFIED IDEOGRAPH + {0xE1F7, 0x78D4}, //5353 #CJK UNIFIED IDEOGRAPH + {0xE1F8, 0x78BE}, //5354 #CJK UNIFIED IDEOGRAPH + {0xE1F9, 0x78BC}, //5355 #CJK UNIFIED IDEOGRAPH + {0xE1FA, 0x78C5}, //5356 #CJK UNIFIED IDEOGRAPH + {0xE1FB, 0x78CA}, //5357 #CJK UNIFIED IDEOGRAPH + {0xE1FC, 0x78EC}, //5358 #CJK UNIFIED IDEOGRAPH + {0xE240, 0x78E7}, //5359 #CJK UNIFIED IDEOGRAPH + {0xE241, 0x78DA}, //5360 #CJK UNIFIED IDEOGRAPH + {0xE242, 0x78FD}, //5361 #CJK UNIFIED IDEOGRAPH + {0xE243, 0x78F4}, //5362 #CJK UNIFIED IDEOGRAPH + {0xE244, 0x7907}, //5363 #CJK UNIFIED IDEOGRAPH + {0xE245, 0x7912}, //5364 #CJK UNIFIED IDEOGRAPH + {0xE246, 0x7911}, //5365 #CJK UNIFIED IDEOGRAPH + {0xE247, 0x7919}, //5366 #CJK UNIFIED IDEOGRAPH + {0xE248, 0x792C}, //5367 #CJK UNIFIED IDEOGRAPH + {0xE249, 0x792B}, //5368 #CJK UNIFIED IDEOGRAPH + {0xE24A, 0x7940}, //5369 #CJK UNIFIED IDEOGRAPH + {0xE24B, 0x7960}, //5370 #CJK UNIFIED IDEOGRAPH + {0xE24C, 0x7957}, //5371 #CJK UNIFIED IDEOGRAPH + {0xE24D, 0x795F}, //5372 #CJK UNIFIED IDEOGRAPH + {0xE24E, 0x795A}, //5373 #CJK UNIFIED IDEOGRAPH + {0xE24F, 0x7955}, //5374 #CJK UNIFIED IDEOGRAPH + {0xE250, 0x7953}, //5375 #CJK UNIFIED IDEOGRAPH + {0xE251, 0x797A}, //5376 #CJK UNIFIED IDEOGRAPH + {0xE252, 0x797F}, //5377 #CJK UNIFIED IDEOGRAPH + {0xE253, 0x798A}, //5378 #CJK UNIFIED IDEOGRAPH + {0xE254, 0x799D}, //5379 #CJK UNIFIED IDEOGRAPH + {0xE255, 0x79A7}, //5380 #CJK UNIFIED IDEOGRAPH + {0xE256, 0x9F4B}, //5381 #CJK UNIFIED IDEOGRAPH + {0xE257, 0x79AA}, //5382 #CJK UNIFIED IDEOGRAPH + {0xE258, 0x79AE}, //5383 #CJK UNIFIED IDEOGRAPH + {0xE259, 0x79B3}, //5384 #CJK UNIFIED IDEOGRAPH + {0xE25A, 0x79B9}, //5385 #CJK UNIFIED IDEOGRAPH + {0xE25B, 0x79BA}, //5386 #CJK UNIFIED IDEOGRAPH + {0xE25C, 0x79C9}, //5387 #CJK UNIFIED IDEOGRAPH + {0xE25D, 0x79D5}, //5388 #CJK UNIFIED IDEOGRAPH + {0xE25E, 0x79E7}, //5389 #CJK UNIFIED IDEOGRAPH + {0xE25F, 0x79EC}, //5390 #CJK UNIFIED IDEOGRAPH + {0xE260, 0x79E1}, //5391 #CJK UNIFIED IDEOGRAPH + {0xE261, 0x79E3}, //5392 #CJK UNIFIED IDEOGRAPH + {0xE262, 0x7A08}, //5393 #CJK UNIFIED IDEOGRAPH + {0xE263, 0x7A0D}, //5394 #CJK UNIFIED IDEOGRAPH + {0xE264, 0x7A18}, //5395 #CJK UNIFIED IDEOGRAPH + {0xE265, 0x7A19}, //5396 #CJK UNIFIED IDEOGRAPH + {0xE266, 0x7A20}, //5397 #CJK UNIFIED IDEOGRAPH + {0xE267, 0x7A1F}, //5398 #CJK UNIFIED IDEOGRAPH + {0xE268, 0x7980}, //5399 #CJK UNIFIED IDEOGRAPH + {0xE269, 0x7A31}, //5400 #CJK UNIFIED IDEOGRAPH + {0xE26A, 0x7A3B}, //5401 #CJK UNIFIED IDEOGRAPH + {0xE26B, 0x7A3E}, //5402 #CJK UNIFIED IDEOGRAPH + {0xE26C, 0x7A37}, //5403 #CJK UNIFIED IDEOGRAPH + {0xE26D, 0x7A43}, //5404 #CJK UNIFIED IDEOGRAPH + {0xE26E, 0x7A57}, //5405 #CJK UNIFIED IDEOGRAPH + {0xE26F, 0x7A49}, //5406 #CJK UNIFIED IDEOGRAPH + {0xE270, 0x7A61}, //5407 #CJK UNIFIED IDEOGRAPH + {0xE271, 0x7A62}, //5408 #CJK UNIFIED IDEOGRAPH + {0xE272, 0x7A69}, //5409 #CJK UNIFIED IDEOGRAPH + {0xE273, 0x9F9D}, //5410 #CJK UNIFIED IDEOGRAPH + {0xE274, 0x7A70}, //5411 #CJK UNIFIED IDEOGRAPH + {0xE275, 0x7A79}, //5412 #CJK UNIFIED IDEOGRAPH + {0xE276, 0x7A7D}, //5413 #CJK UNIFIED IDEOGRAPH + {0xE277, 0x7A88}, //5414 #CJK UNIFIED IDEOGRAPH + {0xE278, 0x7A97}, //5415 #CJK UNIFIED IDEOGRAPH + {0xE279, 0x7A95}, //5416 #CJK UNIFIED IDEOGRAPH + {0xE27A, 0x7A98}, //5417 #CJK UNIFIED IDEOGRAPH + {0xE27B, 0x7A96}, //5418 #CJK UNIFIED IDEOGRAPH + {0xE27C, 0x7AA9}, //5419 #CJK UNIFIED IDEOGRAPH + {0xE27D, 0x7AC8}, //5420 #CJK UNIFIED IDEOGRAPH + {0xE27E, 0x7AB0}, //5421 #CJK UNIFIED IDEOGRAPH + {0xE280, 0x7AB6}, //5422 #CJK UNIFIED IDEOGRAPH + {0xE281, 0x7AC5}, //5423 #CJK UNIFIED IDEOGRAPH + {0xE282, 0x7AC4}, //5424 #CJK UNIFIED IDEOGRAPH + {0xE283, 0x7ABF}, //5425 #CJK UNIFIED IDEOGRAPH + {0xE284, 0x9083}, //5426 #CJK UNIFIED IDEOGRAPH + {0xE285, 0x7AC7}, //5427 #CJK UNIFIED IDEOGRAPH + {0xE286, 0x7ACA}, //5428 #CJK UNIFIED IDEOGRAPH + {0xE287, 0x7ACD}, //5429 #CJK UNIFIED IDEOGRAPH + {0xE288, 0x7ACF}, //5430 #CJK UNIFIED IDEOGRAPH + {0xE289, 0x7AD5}, //5431 #CJK UNIFIED IDEOGRAPH + {0xE28A, 0x7AD3}, //5432 #CJK UNIFIED IDEOGRAPH + {0xE28B, 0x7AD9}, //5433 #CJK UNIFIED IDEOGRAPH + {0xE28C, 0x7ADA}, //5434 #CJK UNIFIED IDEOGRAPH + {0xE28D, 0x7ADD}, //5435 #CJK UNIFIED IDEOGRAPH + {0xE28E, 0x7AE1}, //5436 #CJK UNIFIED IDEOGRAPH + {0xE28F, 0x7AE2}, //5437 #CJK UNIFIED IDEOGRAPH + {0xE290, 0x7AE6}, //5438 #CJK UNIFIED IDEOGRAPH + {0xE291, 0x7AED}, //5439 #CJK UNIFIED IDEOGRAPH + {0xE292, 0x7AF0}, //5440 #CJK UNIFIED IDEOGRAPH + {0xE293, 0x7B02}, //5441 #CJK UNIFIED IDEOGRAPH + {0xE294, 0x7B0F}, //5442 #CJK UNIFIED IDEOGRAPH + {0xE295, 0x7B0A}, //5443 #CJK UNIFIED IDEOGRAPH + {0xE296, 0x7B06}, //5444 #CJK UNIFIED IDEOGRAPH + {0xE297, 0x7B33}, //5445 #CJK UNIFIED IDEOGRAPH + {0xE298, 0x7B18}, //5446 #CJK UNIFIED IDEOGRAPH + {0xE299, 0x7B19}, //5447 #CJK UNIFIED IDEOGRAPH + {0xE29A, 0x7B1E}, //5448 #CJK UNIFIED IDEOGRAPH + {0xE29B, 0x7B35}, //5449 #CJK UNIFIED IDEOGRAPH + {0xE29C, 0x7B28}, //5450 #CJK UNIFIED IDEOGRAPH + {0xE29D, 0x7B36}, //5451 #CJK UNIFIED IDEOGRAPH + {0xE29E, 0x7B50}, //5452 #CJK UNIFIED IDEOGRAPH + {0xE29F, 0x7B7A}, //5453 #CJK UNIFIED IDEOGRAPH + {0xE2A0, 0x7B04}, //5454 #CJK UNIFIED IDEOGRAPH + {0xE2A1, 0x7B4D}, //5455 #CJK UNIFIED IDEOGRAPH + {0xE2A2, 0x7B0B}, //5456 #CJK UNIFIED IDEOGRAPH + {0xE2A3, 0x7B4C}, //5457 #CJK UNIFIED IDEOGRAPH + {0xE2A4, 0x7B45}, //5458 #CJK UNIFIED IDEOGRAPH + {0xE2A5, 0x7B75}, //5459 #CJK UNIFIED IDEOGRAPH + {0xE2A6, 0x7B65}, //5460 #CJK UNIFIED IDEOGRAPH + {0xE2A7, 0x7B74}, //5461 #CJK UNIFIED IDEOGRAPH + {0xE2A8, 0x7B67}, //5462 #CJK UNIFIED IDEOGRAPH + {0xE2A9, 0x7B70}, //5463 #CJK UNIFIED IDEOGRAPH + {0xE2AA, 0x7B71}, //5464 #CJK UNIFIED IDEOGRAPH + {0xE2AB, 0x7B6C}, //5465 #CJK UNIFIED IDEOGRAPH + {0xE2AC, 0x7B6E}, //5466 #CJK UNIFIED IDEOGRAPH + {0xE2AD, 0x7B9D}, //5467 #CJK UNIFIED IDEOGRAPH + {0xE2AE, 0x7B98}, //5468 #CJK UNIFIED IDEOGRAPH + {0xE2AF, 0x7B9F}, //5469 #CJK UNIFIED IDEOGRAPH + {0xE2B0, 0x7B8D}, //5470 #CJK UNIFIED IDEOGRAPH + {0xE2B1, 0x7B9C}, //5471 #CJK UNIFIED IDEOGRAPH + {0xE2B2, 0x7B9A}, //5472 #CJK UNIFIED IDEOGRAPH + {0xE2B3, 0x7B8B}, //5473 #CJK UNIFIED IDEOGRAPH + {0xE2B4, 0x7B92}, //5474 #CJK UNIFIED IDEOGRAPH + {0xE2B5, 0x7B8F}, //5475 #CJK UNIFIED IDEOGRAPH + {0xE2B6, 0x7B5D}, //5476 #CJK UNIFIED IDEOGRAPH + {0xE2B7, 0x7B99}, //5477 #CJK UNIFIED IDEOGRAPH + {0xE2B8, 0x7BCB}, //5478 #CJK UNIFIED IDEOGRAPH + {0xE2B9, 0x7BC1}, //5479 #CJK UNIFIED IDEOGRAPH + {0xE2BA, 0x7BCC}, //5480 #CJK UNIFIED IDEOGRAPH + {0xE2BB, 0x7BCF}, //5481 #CJK UNIFIED IDEOGRAPH + {0xE2BC, 0x7BB4}, //5482 #CJK UNIFIED IDEOGRAPH + {0xE2BD, 0x7BC6}, //5483 #CJK UNIFIED IDEOGRAPH + {0xE2BE, 0x7BDD}, //5484 #CJK UNIFIED IDEOGRAPH + {0xE2BF, 0x7BE9}, //5485 #CJK UNIFIED IDEOGRAPH + {0xE2C0, 0x7C11}, //5486 #CJK UNIFIED IDEOGRAPH + {0xE2C1, 0x7C14}, //5487 #CJK UNIFIED IDEOGRAPH + {0xE2C2, 0x7BE6}, //5488 #CJK UNIFIED IDEOGRAPH + {0xE2C3, 0x7BE5}, //5489 #CJK UNIFIED IDEOGRAPH + {0xE2C4, 0x7C60}, //5490 #CJK UNIFIED IDEOGRAPH + {0xE2C5, 0x7C00}, //5491 #CJK UNIFIED IDEOGRAPH + {0xE2C6, 0x7C07}, //5492 #CJK UNIFIED IDEOGRAPH + {0xE2C7, 0x7C13}, //5493 #CJK UNIFIED IDEOGRAPH + {0xE2C8, 0x7BF3}, //5494 #CJK UNIFIED IDEOGRAPH + {0xE2C9, 0x7BF7}, //5495 #CJK UNIFIED IDEOGRAPH + {0xE2CA, 0x7C17}, //5496 #CJK UNIFIED IDEOGRAPH + {0xE2CB, 0x7C0D}, //5497 #CJK UNIFIED IDEOGRAPH + {0xE2CC, 0x7BF6}, //5498 #CJK UNIFIED IDEOGRAPH + {0xE2CD, 0x7C23}, //5499 #CJK UNIFIED IDEOGRAPH + {0xE2CE, 0x7C27}, //5500 #CJK UNIFIED IDEOGRAPH + {0xE2CF, 0x7C2A}, //5501 #CJK UNIFIED IDEOGRAPH + {0xE2D0, 0x7C1F}, //5502 #CJK UNIFIED IDEOGRAPH + {0xE2D1, 0x7C37}, //5503 #CJK UNIFIED IDEOGRAPH + {0xE2D2, 0x7C2B}, //5504 #CJK UNIFIED IDEOGRAPH + {0xE2D3, 0x7C3D}, //5505 #CJK UNIFIED IDEOGRAPH + {0xE2D4, 0x7C4C}, //5506 #CJK UNIFIED IDEOGRAPH + {0xE2D5, 0x7C43}, //5507 #CJK UNIFIED IDEOGRAPH + {0xE2D6, 0x7C54}, //5508 #CJK UNIFIED IDEOGRAPH + {0xE2D7, 0x7C4F}, //5509 #CJK UNIFIED IDEOGRAPH + {0xE2D8, 0x7C40}, //5510 #CJK UNIFIED IDEOGRAPH + {0xE2D9, 0x7C50}, //5511 #CJK UNIFIED IDEOGRAPH + {0xE2DA, 0x7C58}, //5512 #CJK UNIFIED IDEOGRAPH + {0xE2DB, 0x7C5F}, //5513 #CJK UNIFIED IDEOGRAPH + {0xE2DC, 0x7C64}, //5514 #CJK UNIFIED IDEOGRAPH + {0xE2DD, 0x7C56}, //5515 #CJK UNIFIED IDEOGRAPH + {0xE2DE, 0x7C65}, //5516 #CJK UNIFIED IDEOGRAPH + {0xE2DF, 0x7C6C}, //5517 #CJK UNIFIED IDEOGRAPH + {0xE2E0, 0x7C75}, //5518 #CJK UNIFIED IDEOGRAPH + {0xE2E1, 0x7C83}, //5519 #CJK UNIFIED IDEOGRAPH + {0xE2E2, 0x7C90}, //5520 #CJK UNIFIED IDEOGRAPH + {0xE2E3, 0x7CA4}, //5521 #CJK UNIFIED IDEOGRAPH + {0xE2E4, 0x7CAD}, //5522 #CJK UNIFIED IDEOGRAPH + {0xE2E5, 0x7CA2}, //5523 #CJK UNIFIED IDEOGRAPH + {0xE2E6, 0x7CAB}, //5524 #CJK UNIFIED IDEOGRAPH + {0xE2E7, 0x7CA1}, //5525 #CJK UNIFIED IDEOGRAPH + {0xE2E8, 0x7CA8}, //5526 #CJK UNIFIED IDEOGRAPH + {0xE2E9, 0x7CB3}, //5527 #CJK UNIFIED IDEOGRAPH + {0xE2EA, 0x7CB2}, //5528 #CJK UNIFIED IDEOGRAPH + {0xE2EB, 0x7CB1}, //5529 #CJK UNIFIED IDEOGRAPH + {0xE2EC, 0x7CAE}, //5530 #CJK UNIFIED IDEOGRAPH + {0xE2ED, 0x7CB9}, //5531 #CJK UNIFIED IDEOGRAPH + {0xE2EE, 0x7CBD}, //5532 #CJK UNIFIED IDEOGRAPH + {0xE2EF, 0x7CC0}, //5533 #CJK UNIFIED IDEOGRAPH + {0xE2F0, 0x7CC5}, //5534 #CJK UNIFIED IDEOGRAPH + {0xE2F1, 0x7CC2}, //5535 #CJK UNIFIED IDEOGRAPH + {0xE2F2, 0x7CD8}, //5536 #CJK UNIFIED IDEOGRAPH + {0xE2F3, 0x7CD2}, //5537 #CJK UNIFIED IDEOGRAPH + {0xE2F4, 0x7CDC}, //5538 #CJK UNIFIED IDEOGRAPH + {0xE2F5, 0x7CE2}, //5539 #CJK UNIFIED IDEOGRAPH + {0xE2F6, 0x9B3B}, //5540 #CJK UNIFIED IDEOGRAPH + {0xE2F7, 0x7CEF}, //5541 #CJK UNIFIED IDEOGRAPH + {0xE2F8, 0x7CF2}, //5542 #CJK UNIFIED IDEOGRAPH + {0xE2F9, 0x7CF4}, //5543 #CJK UNIFIED IDEOGRAPH + {0xE2FA, 0x7CF6}, //5544 #CJK UNIFIED IDEOGRAPH + {0xE2FB, 0x7CFA}, //5545 #CJK UNIFIED IDEOGRAPH + {0xE2FC, 0x7D06}, //5546 #CJK UNIFIED IDEOGRAPH + {0xE340, 0x7D02}, //5547 #CJK UNIFIED IDEOGRAPH + {0xE341, 0x7D1C}, //5548 #CJK UNIFIED IDEOGRAPH + {0xE342, 0x7D15}, //5549 #CJK UNIFIED IDEOGRAPH + {0xE343, 0x7D0A}, //5550 #CJK UNIFIED IDEOGRAPH + {0xE344, 0x7D45}, //5551 #CJK UNIFIED IDEOGRAPH + {0xE345, 0x7D4B}, //5552 #CJK UNIFIED IDEOGRAPH + {0xE346, 0x7D2E}, //5553 #CJK UNIFIED IDEOGRAPH + {0xE347, 0x7D32}, //5554 #CJK UNIFIED IDEOGRAPH + {0xE348, 0x7D3F}, //5555 #CJK UNIFIED IDEOGRAPH + {0xE349, 0x7D35}, //5556 #CJK UNIFIED IDEOGRAPH + {0xE34A, 0x7D46}, //5557 #CJK UNIFIED IDEOGRAPH + {0xE34B, 0x7D73}, //5558 #CJK UNIFIED IDEOGRAPH + {0xE34C, 0x7D56}, //5559 #CJK UNIFIED IDEOGRAPH + {0xE34D, 0x7D4E}, //5560 #CJK UNIFIED IDEOGRAPH + {0xE34E, 0x7D72}, //5561 #CJK UNIFIED IDEOGRAPH + {0xE34F, 0x7D68}, //5562 #CJK UNIFIED IDEOGRAPH + {0xE350, 0x7D6E}, //5563 #CJK UNIFIED IDEOGRAPH + {0xE351, 0x7D4F}, //5564 #CJK UNIFIED IDEOGRAPH + {0xE352, 0x7D63}, //5565 #CJK UNIFIED IDEOGRAPH + {0xE353, 0x7D93}, //5566 #CJK UNIFIED IDEOGRAPH + {0xE354, 0x7D89}, //5567 #CJK UNIFIED IDEOGRAPH + {0xE355, 0x7D5B}, //5568 #CJK UNIFIED IDEOGRAPH + {0xE356, 0x7D8F}, //5569 #CJK UNIFIED IDEOGRAPH + {0xE357, 0x7D7D}, //5570 #CJK UNIFIED IDEOGRAPH + {0xE358, 0x7D9B}, //5571 #CJK UNIFIED IDEOGRAPH + {0xE359, 0x7DBA}, //5572 #CJK UNIFIED IDEOGRAPH + {0xE35A, 0x7DAE}, //5573 #CJK UNIFIED IDEOGRAPH + {0xE35B, 0x7DA3}, //5574 #CJK UNIFIED IDEOGRAPH + {0xE35C, 0x7DB5}, //5575 #CJK UNIFIED IDEOGRAPH + {0xE35D, 0x7DC7}, //5576 #CJK UNIFIED IDEOGRAPH + {0xE35E, 0x7DBD}, //5577 #CJK UNIFIED IDEOGRAPH + {0xE35F, 0x7DAB}, //5578 #CJK UNIFIED IDEOGRAPH + {0xE360, 0x7E3D}, //5579 #CJK UNIFIED IDEOGRAPH + {0xE361, 0x7DA2}, //5580 #CJK UNIFIED IDEOGRAPH + {0xE362, 0x7DAF}, //5581 #CJK UNIFIED IDEOGRAPH + {0xE363, 0x7DDC}, //5582 #CJK UNIFIED IDEOGRAPH + {0xE364, 0x7DB8}, //5583 #CJK UNIFIED IDEOGRAPH + {0xE365, 0x7D9F}, //5584 #CJK UNIFIED IDEOGRAPH + {0xE366, 0x7DB0}, //5585 #CJK UNIFIED IDEOGRAPH + {0xE367, 0x7DD8}, //5586 #CJK UNIFIED IDEOGRAPH + {0xE368, 0x7DDD}, //5587 #CJK UNIFIED IDEOGRAPH + {0xE369, 0x7DE4}, //5588 #CJK UNIFIED IDEOGRAPH + {0xE36A, 0x7DDE}, //5589 #CJK UNIFIED IDEOGRAPH + {0xE36B, 0x7DFB}, //5590 #CJK UNIFIED IDEOGRAPH + {0xE36C, 0x7DF2}, //5591 #CJK UNIFIED IDEOGRAPH + {0xE36D, 0x7DE1}, //5592 #CJK UNIFIED IDEOGRAPH + {0xE36E, 0x7E05}, //5593 #CJK UNIFIED IDEOGRAPH + {0xE36F, 0x7E0A}, //5594 #CJK UNIFIED IDEOGRAPH + {0xE370, 0x7E23}, //5595 #CJK UNIFIED IDEOGRAPH + {0xE371, 0x7E21}, //5596 #CJK UNIFIED IDEOGRAPH + {0xE372, 0x7E12}, //5597 #CJK UNIFIED IDEOGRAPH + {0xE373, 0x7E31}, //5598 #CJK UNIFIED IDEOGRAPH + {0xE374, 0x7E1F}, //5599 #CJK UNIFIED IDEOGRAPH + {0xE375, 0x7E09}, //5600 #CJK UNIFIED IDEOGRAPH + {0xE376, 0x7E0B}, //5601 #CJK UNIFIED IDEOGRAPH + {0xE377, 0x7E22}, //5602 #CJK UNIFIED IDEOGRAPH + {0xE378, 0x7E46}, //5603 #CJK UNIFIED IDEOGRAPH + {0xE379, 0x7E66}, //5604 #CJK UNIFIED IDEOGRAPH + {0xE37A, 0x7E3B}, //5605 #CJK UNIFIED IDEOGRAPH + {0xE37B, 0x7E35}, //5606 #CJK UNIFIED IDEOGRAPH + {0xE37C, 0x7E39}, //5607 #CJK UNIFIED IDEOGRAPH + {0xE37D, 0x7E43}, //5608 #CJK UNIFIED IDEOGRAPH + {0xE37E, 0x7E37}, //5609 #CJK UNIFIED IDEOGRAPH + {0xE380, 0x7E32}, //5610 #CJK UNIFIED IDEOGRAPH + {0xE381, 0x7E3A}, //5611 #CJK UNIFIED IDEOGRAPH + {0xE382, 0x7E67}, //5612 #CJK UNIFIED IDEOGRAPH + {0xE383, 0x7E5D}, //5613 #CJK UNIFIED IDEOGRAPH + {0xE384, 0x7E56}, //5614 #CJK UNIFIED IDEOGRAPH + {0xE385, 0x7E5E}, //5615 #CJK UNIFIED IDEOGRAPH + {0xE386, 0x7E59}, //5616 #CJK UNIFIED IDEOGRAPH + {0xE387, 0x7E5A}, //5617 #CJK UNIFIED IDEOGRAPH + {0xE388, 0x7E79}, //5618 #CJK UNIFIED IDEOGRAPH + {0xE389, 0x7E6A}, //5619 #CJK UNIFIED IDEOGRAPH + {0xE38A, 0x7E69}, //5620 #CJK UNIFIED IDEOGRAPH + {0xE38B, 0x7E7C}, //5621 #CJK UNIFIED IDEOGRAPH + {0xE38C, 0x7E7B}, //5622 #CJK UNIFIED IDEOGRAPH + {0xE38D, 0x7E83}, //5623 #CJK UNIFIED IDEOGRAPH + {0xE38E, 0x7DD5}, //5624 #CJK UNIFIED IDEOGRAPH + {0xE38F, 0x7E7D}, //5625 #CJK UNIFIED IDEOGRAPH + {0xE390, 0x8FAE}, //5626 #CJK UNIFIED IDEOGRAPH + {0xE391, 0x7E7F}, //5627 #CJK UNIFIED IDEOGRAPH + {0xE392, 0x7E88}, //5628 #CJK UNIFIED IDEOGRAPH + {0xE393, 0x7E89}, //5629 #CJK UNIFIED IDEOGRAPH + {0xE394, 0x7E8C}, //5630 #CJK UNIFIED IDEOGRAPH + {0xE395, 0x7E92}, //5631 #CJK UNIFIED IDEOGRAPH + {0xE396, 0x7E90}, //5632 #CJK UNIFIED IDEOGRAPH + {0xE397, 0x7E93}, //5633 #CJK UNIFIED IDEOGRAPH + {0xE398, 0x7E94}, //5634 #CJK UNIFIED IDEOGRAPH + {0xE399, 0x7E96}, //5635 #CJK UNIFIED IDEOGRAPH + {0xE39A, 0x7E8E}, //5636 #CJK UNIFIED IDEOGRAPH + {0xE39B, 0x7E9B}, //5637 #CJK UNIFIED IDEOGRAPH + {0xE39C, 0x7E9C}, //5638 #CJK UNIFIED IDEOGRAPH + {0xE39D, 0x7F38}, //5639 #CJK UNIFIED IDEOGRAPH + {0xE39E, 0x7F3A}, //5640 #CJK UNIFIED IDEOGRAPH + {0xE39F, 0x7F45}, //5641 #CJK UNIFIED IDEOGRAPH + {0xE3A0, 0x7F4C}, //5642 #CJK UNIFIED IDEOGRAPH + {0xE3A1, 0x7F4D}, //5643 #CJK UNIFIED IDEOGRAPH + {0xE3A2, 0x7F4E}, //5644 #CJK UNIFIED IDEOGRAPH + {0xE3A3, 0x7F50}, //5645 #CJK UNIFIED IDEOGRAPH + {0xE3A4, 0x7F51}, //5646 #CJK UNIFIED IDEOGRAPH + {0xE3A5, 0x7F55}, //5647 #CJK UNIFIED IDEOGRAPH + {0xE3A6, 0x7F54}, //5648 #CJK UNIFIED IDEOGRAPH + {0xE3A7, 0x7F58}, //5649 #CJK UNIFIED IDEOGRAPH + {0xE3A8, 0x7F5F}, //5650 #CJK UNIFIED IDEOGRAPH + {0xE3A9, 0x7F60}, //5651 #CJK UNIFIED IDEOGRAPH + {0xE3AA, 0x7F68}, //5652 #CJK UNIFIED IDEOGRAPH + {0xE3AB, 0x7F69}, //5653 #CJK UNIFIED IDEOGRAPH + {0xE3AC, 0x7F67}, //5654 #CJK UNIFIED IDEOGRAPH + {0xE3AD, 0x7F78}, //5655 #CJK UNIFIED IDEOGRAPH + {0xE3AE, 0x7F82}, //5656 #CJK UNIFIED IDEOGRAPH + {0xE3AF, 0x7F86}, //5657 #CJK UNIFIED IDEOGRAPH + {0xE3B0, 0x7F83}, //5658 #CJK UNIFIED IDEOGRAPH + {0xE3B1, 0x7F88}, //5659 #CJK UNIFIED IDEOGRAPH + {0xE3B2, 0x7F87}, //5660 #CJK UNIFIED IDEOGRAPH + {0xE3B3, 0x7F8C}, //5661 #CJK UNIFIED IDEOGRAPH + {0xE3B4, 0x7F94}, //5662 #CJK UNIFIED IDEOGRAPH + {0xE3B5, 0x7F9E}, //5663 #CJK UNIFIED IDEOGRAPH + {0xE3B6, 0x7F9D}, //5664 #CJK UNIFIED IDEOGRAPH + {0xE3B7, 0x7F9A}, //5665 #CJK UNIFIED IDEOGRAPH + {0xE3B8, 0x7FA3}, //5666 #CJK UNIFIED IDEOGRAPH + {0xE3B9, 0x7FAF}, //5667 #CJK UNIFIED IDEOGRAPH + {0xE3BA, 0x7FB2}, //5668 #CJK UNIFIED IDEOGRAPH + {0xE3BB, 0x7FB9}, //5669 #CJK UNIFIED IDEOGRAPH + {0xE3BC, 0x7FAE}, //5670 #CJK UNIFIED IDEOGRAPH + {0xE3BD, 0x7FB6}, //5671 #CJK UNIFIED IDEOGRAPH + {0xE3BE, 0x7FB8}, //5672 #CJK UNIFIED IDEOGRAPH + {0xE3BF, 0x8B71}, //5673 #CJK UNIFIED IDEOGRAPH + {0xE3C0, 0x7FC5}, //5674 #CJK UNIFIED IDEOGRAPH + {0xE3C1, 0x7FC6}, //5675 #CJK UNIFIED IDEOGRAPH + {0xE3C2, 0x7FCA}, //5676 #CJK UNIFIED IDEOGRAPH + {0xE3C3, 0x7FD5}, //5677 #CJK UNIFIED IDEOGRAPH + {0xE3C4, 0x7FD4}, //5678 #CJK UNIFIED IDEOGRAPH + {0xE3C5, 0x7FE1}, //5679 #CJK UNIFIED IDEOGRAPH + {0xE3C6, 0x7FE6}, //5680 #CJK UNIFIED IDEOGRAPH + {0xE3C7, 0x7FE9}, //5681 #CJK UNIFIED IDEOGRAPH + {0xE3C8, 0x7FF3}, //5682 #CJK UNIFIED IDEOGRAPH + {0xE3C9, 0x7FF9}, //5683 #CJK UNIFIED IDEOGRAPH + {0xE3CA, 0x98DC}, //5684 #CJK UNIFIED IDEOGRAPH + {0xE3CB, 0x8006}, //5685 #CJK UNIFIED IDEOGRAPH + {0xE3CC, 0x8004}, //5686 #CJK UNIFIED IDEOGRAPH + {0xE3CD, 0x800B}, //5687 #CJK UNIFIED IDEOGRAPH + {0xE3CE, 0x8012}, //5688 #CJK UNIFIED IDEOGRAPH + {0xE3CF, 0x8018}, //5689 #CJK UNIFIED IDEOGRAPH + {0xE3D0, 0x8019}, //5690 #CJK UNIFIED IDEOGRAPH + {0xE3D1, 0x801C}, //5691 #CJK UNIFIED IDEOGRAPH + {0xE3D2, 0x8021}, //5692 #CJK UNIFIED IDEOGRAPH + {0xE3D3, 0x8028}, //5693 #CJK UNIFIED IDEOGRAPH + {0xE3D4, 0x803F}, //5694 #CJK UNIFIED IDEOGRAPH + {0xE3D5, 0x803B}, //5695 #CJK UNIFIED IDEOGRAPH + {0xE3D6, 0x804A}, //5696 #CJK UNIFIED IDEOGRAPH + {0xE3D7, 0x8046}, //5697 #CJK UNIFIED IDEOGRAPH + {0xE3D8, 0x8052}, //5698 #CJK UNIFIED IDEOGRAPH + {0xE3D9, 0x8058}, //5699 #CJK UNIFIED IDEOGRAPH + {0xE3DA, 0x805A}, //5700 #CJK UNIFIED IDEOGRAPH + {0xE3DB, 0x805F}, //5701 #CJK UNIFIED IDEOGRAPH + {0xE3DC, 0x8062}, //5702 #CJK UNIFIED IDEOGRAPH + {0xE3DD, 0x8068}, //5703 #CJK UNIFIED IDEOGRAPH + {0xE3DE, 0x8073}, //5704 #CJK UNIFIED IDEOGRAPH + {0xE3DF, 0x8072}, //5705 #CJK UNIFIED IDEOGRAPH + {0xE3E0, 0x8070}, //5706 #CJK UNIFIED IDEOGRAPH + {0xE3E1, 0x8076}, //5707 #CJK UNIFIED IDEOGRAPH + {0xE3E2, 0x8079}, //5708 #CJK UNIFIED IDEOGRAPH + {0xE3E3, 0x807D}, //5709 #CJK UNIFIED IDEOGRAPH + {0xE3E4, 0x807F}, //5710 #CJK UNIFIED IDEOGRAPH + {0xE3E5, 0x8084}, //5711 #CJK UNIFIED IDEOGRAPH + {0xE3E6, 0x8086}, //5712 #CJK UNIFIED IDEOGRAPH + {0xE3E7, 0x8085}, //5713 #CJK UNIFIED IDEOGRAPH + {0xE3E8, 0x809B}, //5714 #CJK UNIFIED IDEOGRAPH + {0xE3E9, 0x8093}, //5715 #CJK UNIFIED IDEOGRAPH + {0xE3EA, 0x809A}, //5716 #CJK UNIFIED IDEOGRAPH + {0xE3EB, 0x80AD}, //5717 #CJK UNIFIED IDEOGRAPH + {0xE3EC, 0x5190}, //5718 #CJK UNIFIED IDEOGRAPH + {0xE3ED, 0x80AC}, //5719 #CJK UNIFIED IDEOGRAPH + {0xE3EE, 0x80DB}, //5720 #CJK UNIFIED IDEOGRAPH + {0xE3EF, 0x80E5}, //5721 #CJK UNIFIED IDEOGRAPH + {0xE3F0, 0x80D9}, //5722 #CJK UNIFIED IDEOGRAPH + {0xE3F1, 0x80DD}, //5723 #CJK UNIFIED IDEOGRAPH + {0xE3F2, 0x80C4}, //5724 #CJK UNIFIED IDEOGRAPH + {0xE3F3, 0x80DA}, //5725 #CJK UNIFIED IDEOGRAPH + {0xE3F4, 0x80D6}, //5726 #CJK UNIFIED IDEOGRAPH + {0xE3F5, 0x8109}, //5727 #CJK UNIFIED IDEOGRAPH + {0xE3F6, 0x80EF}, //5728 #CJK UNIFIED IDEOGRAPH + {0xE3F7, 0x80F1}, //5729 #CJK UNIFIED IDEOGRAPH + {0xE3F8, 0x811B}, //5730 #CJK UNIFIED IDEOGRAPH + {0xE3F9, 0x8129}, //5731 #CJK UNIFIED IDEOGRAPH + {0xE3FA, 0x8123}, //5732 #CJK UNIFIED IDEOGRAPH + {0xE3FB, 0x812F}, //5733 #CJK UNIFIED IDEOGRAPH + {0xE3FC, 0x814B}, //5734 #CJK UNIFIED IDEOGRAPH + {0xE440, 0x968B}, //5735 #CJK UNIFIED IDEOGRAPH + {0xE441, 0x8146}, //5736 #CJK UNIFIED IDEOGRAPH + {0xE442, 0x813E}, //5737 #CJK UNIFIED IDEOGRAPH + {0xE443, 0x8153}, //5738 #CJK UNIFIED IDEOGRAPH + {0xE444, 0x8151}, //5739 #CJK UNIFIED IDEOGRAPH + {0xE445, 0x80FC}, //5740 #CJK UNIFIED IDEOGRAPH + {0xE446, 0x8171}, //5741 #CJK UNIFIED IDEOGRAPH + {0xE447, 0x816E}, //5742 #CJK UNIFIED IDEOGRAPH + {0xE448, 0x8165}, //5743 #CJK UNIFIED IDEOGRAPH + {0xE449, 0x8166}, //5744 #CJK UNIFIED IDEOGRAPH + {0xE44A, 0x8174}, //5745 #CJK UNIFIED IDEOGRAPH + {0xE44B, 0x8183}, //5746 #CJK UNIFIED IDEOGRAPH + {0xE44C, 0x8188}, //5747 #CJK UNIFIED IDEOGRAPH + {0xE44D, 0x818A}, //5748 #CJK UNIFIED IDEOGRAPH + {0xE44E, 0x8180}, //5749 #CJK UNIFIED IDEOGRAPH + {0xE44F, 0x8182}, //5750 #CJK UNIFIED IDEOGRAPH + {0xE450, 0x81A0}, //5751 #CJK UNIFIED IDEOGRAPH + {0xE451, 0x8195}, //5752 #CJK UNIFIED IDEOGRAPH + {0xE452, 0x81A4}, //5753 #CJK UNIFIED IDEOGRAPH + {0xE453, 0x81A3}, //5754 #CJK UNIFIED IDEOGRAPH + {0xE454, 0x815F}, //5755 #CJK UNIFIED IDEOGRAPH + {0xE455, 0x8193}, //5756 #CJK UNIFIED IDEOGRAPH + {0xE456, 0x81A9}, //5757 #CJK UNIFIED IDEOGRAPH + {0xE457, 0x81B0}, //5758 #CJK UNIFIED IDEOGRAPH + {0xE458, 0x81B5}, //5759 #CJK UNIFIED IDEOGRAPH + {0xE459, 0x81BE}, //5760 #CJK UNIFIED IDEOGRAPH + {0xE45A, 0x81B8}, //5761 #CJK UNIFIED IDEOGRAPH + {0xE45B, 0x81BD}, //5762 #CJK UNIFIED IDEOGRAPH + {0xE45C, 0x81C0}, //5763 #CJK UNIFIED IDEOGRAPH + {0xE45D, 0x81C2}, //5764 #CJK UNIFIED IDEOGRAPH + {0xE45E, 0x81BA}, //5765 #CJK UNIFIED IDEOGRAPH + {0xE45F, 0x81C9}, //5766 #CJK UNIFIED IDEOGRAPH + {0xE460, 0x81CD}, //5767 #CJK UNIFIED IDEOGRAPH + {0xE461, 0x81D1}, //5768 #CJK UNIFIED IDEOGRAPH + {0xE462, 0x81D9}, //5769 #CJK UNIFIED IDEOGRAPH + {0xE463, 0x81D8}, //5770 #CJK UNIFIED IDEOGRAPH + {0xE464, 0x81C8}, //5771 #CJK UNIFIED IDEOGRAPH + {0xE465, 0x81DA}, //5772 #CJK UNIFIED IDEOGRAPH + {0xE466, 0x81DF}, //5773 #CJK UNIFIED IDEOGRAPH + {0xE467, 0x81E0}, //5774 #CJK UNIFIED IDEOGRAPH + {0xE468, 0x81E7}, //5775 #CJK UNIFIED IDEOGRAPH + {0xE469, 0x81FA}, //5776 #CJK UNIFIED IDEOGRAPH + {0xE46A, 0x81FB}, //5777 #CJK UNIFIED IDEOGRAPH + {0xE46B, 0x81FE}, //5778 #CJK UNIFIED IDEOGRAPH + {0xE46C, 0x8201}, //5779 #CJK UNIFIED IDEOGRAPH + {0xE46D, 0x8202}, //5780 #CJK UNIFIED IDEOGRAPH + {0xE46E, 0x8205}, //5781 #CJK UNIFIED IDEOGRAPH + {0xE46F, 0x8207}, //5782 #CJK UNIFIED IDEOGRAPH + {0xE470, 0x820A}, //5783 #CJK UNIFIED IDEOGRAPH + {0xE471, 0x820D}, //5784 #CJK UNIFIED IDEOGRAPH + {0xE472, 0x8210}, //5785 #CJK UNIFIED IDEOGRAPH + {0xE473, 0x8216}, //5786 #CJK UNIFIED IDEOGRAPH + {0xE474, 0x8229}, //5787 #CJK UNIFIED IDEOGRAPH + {0xE475, 0x822B}, //5788 #CJK UNIFIED IDEOGRAPH + {0xE476, 0x8238}, //5789 #CJK UNIFIED IDEOGRAPH + {0xE477, 0x8233}, //5790 #CJK UNIFIED IDEOGRAPH + {0xE478, 0x8240}, //5791 #CJK UNIFIED IDEOGRAPH + {0xE479, 0x8259}, //5792 #CJK UNIFIED IDEOGRAPH + {0xE47A, 0x8258}, //5793 #CJK UNIFIED IDEOGRAPH + {0xE47B, 0x825D}, //5794 #CJK UNIFIED IDEOGRAPH + {0xE47C, 0x825A}, //5795 #CJK UNIFIED IDEOGRAPH + {0xE47D, 0x825F}, //5796 #CJK UNIFIED IDEOGRAPH + {0xE47E, 0x8264}, //5797 #CJK UNIFIED IDEOGRAPH + {0xE480, 0x8262}, //5798 #CJK UNIFIED IDEOGRAPH + {0xE481, 0x8268}, //5799 #CJK UNIFIED IDEOGRAPH + {0xE482, 0x826A}, //5800 #CJK UNIFIED IDEOGRAPH + {0xE483, 0x826B}, //5801 #CJK UNIFIED IDEOGRAPH + {0xE484, 0x822E}, //5802 #CJK UNIFIED IDEOGRAPH + {0xE485, 0x8271}, //5803 #CJK UNIFIED IDEOGRAPH + {0xE486, 0x8277}, //5804 #CJK UNIFIED IDEOGRAPH + {0xE487, 0x8278}, //5805 #CJK UNIFIED IDEOGRAPH + {0xE488, 0x827E}, //5806 #CJK UNIFIED IDEOGRAPH + {0xE489, 0x828D}, //5807 #CJK UNIFIED IDEOGRAPH + {0xE48A, 0x8292}, //5808 #CJK UNIFIED IDEOGRAPH + {0xE48B, 0x82AB}, //5809 #CJK UNIFIED IDEOGRAPH + {0xE48C, 0x829F}, //5810 #CJK UNIFIED IDEOGRAPH + {0xE48D, 0x82BB}, //5811 #CJK UNIFIED IDEOGRAPH + {0xE48E, 0x82AC}, //5812 #CJK UNIFIED IDEOGRAPH + {0xE48F, 0x82E1}, //5813 #CJK UNIFIED IDEOGRAPH + {0xE490, 0x82E3}, //5814 #CJK UNIFIED IDEOGRAPH + {0xE491, 0x82DF}, //5815 #CJK UNIFIED IDEOGRAPH + {0xE492, 0x82D2}, //5816 #CJK UNIFIED IDEOGRAPH + {0xE493, 0x82F4}, //5817 #CJK UNIFIED IDEOGRAPH + {0xE494, 0x82F3}, //5818 #CJK UNIFIED IDEOGRAPH + {0xE495, 0x82FA}, //5819 #CJK UNIFIED IDEOGRAPH + {0xE496, 0x8393}, //5820 #CJK UNIFIED IDEOGRAPH + {0xE497, 0x8303}, //5821 #CJK UNIFIED IDEOGRAPH + {0xE498, 0x82FB}, //5822 #CJK UNIFIED IDEOGRAPH + {0xE499, 0x82F9}, //5823 #CJK UNIFIED IDEOGRAPH + {0xE49A, 0x82DE}, //5824 #CJK UNIFIED IDEOGRAPH + {0xE49B, 0x8306}, //5825 #CJK UNIFIED IDEOGRAPH + {0xE49C, 0x82DC}, //5826 #CJK UNIFIED IDEOGRAPH + {0xE49D, 0x8309}, //5827 #CJK UNIFIED IDEOGRAPH + {0xE49E, 0x82D9}, //5828 #CJK UNIFIED IDEOGRAPH + {0xE49F, 0x8335}, //5829 #CJK UNIFIED IDEOGRAPH + {0xE4A0, 0x8334}, //5830 #CJK UNIFIED IDEOGRAPH + {0xE4A1, 0x8316}, //5831 #CJK UNIFIED IDEOGRAPH + {0xE4A2, 0x8332}, //5832 #CJK UNIFIED IDEOGRAPH + {0xE4A3, 0x8331}, //5833 #CJK UNIFIED IDEOGRAPH + {0xE4A4, 0x8340}, //5834 #CJK UNIFIED IDEOGRAPH + {0xE4A5, 0x8339}, //5835 #CJK UNIFIED IDEOGRAPH + {0xE4A6, 0x8350}, //5836 #CJK UNIFIED IDEOGRAPH + {0xE4A7, 0x8345}, //5837 #CJK UNIFIED IDEOGRAPH + {0xE4A8, 0x832F}, //5838 #CJK UNIFIED IDEOGRAPH + {0xE4A9, 0x832B}, //5839 #CJK UNIFIED IDEOGRAPH + {0xE4AA, 0x8317}, //5840 #CJK UNIFIED IDEOGRAPH + {0xE4AB, 0x8318}, //5841 #CJK UNIFIED IDEOGRAPH + {0xE4AC, 0x8385}, //5842 #CJK UNIFIED IDEOGRAPH + {0xE4AD, 0x839A}, //5843 #CJK UNIFIED IDEOGRAPH + {0xE4AE, 0x83AA}, //5844 #CJK UNIFIED IDEOGRAPH + {0xE4AF, 0x839F}, //5845 #CJK UNIFIED IDEOGRAPH + {0xE4B0, 0x83A2}, //5846 #CJK UNIFIED IDEOGRAPH + {0xE4B1, 0x8396}, //5847 #CJK UNIFIED IDEOGRAPH + {0xE4B2, 0x8323}, //5848 #CJK UNIFIED IDEOGRAPH + {0xE4B3, 0x838E}, //5849 #CJK UNIFIED IDEOGRAPH + {0xE4B4, 0x8387}, //5850 #CJK UNIFIED IDEOGRAPH + {0xE4B5, 0x838A}, //5851 #CJK UNIFIED IDEOGRAPH + {0xE4B6, 0x837C}, //5852 #CJK UNIFIED IDEOGRAPH + {0xE4B7, 0x83B5}, //5853 #CJK UNIFIED IDEOGRAPH + {0xE4B8, 0x8373}, //5854 #CJK UNIFIED IDEOGRAPH + {0xE4B9, 0x8375}, //5855 #CJK UNIFIED IDEOGRAPH + {0xE4BA, 0x83A0}, //5856 #CJK UNIFIED IDEOGRAPH + {0xE4BB, 0x8389}, //5857 #CJK UNIFIED IDEOGRAPH + {0xE4BC, 0x83A8}, //5858 #CJK UNIFIED IDEOGRAPH + {0xE4BD, 0x83F4}, //5859 #CJK UNIFIED IDEOGRAPH + {0xE4BE, 0x8413}, //5860 #CJK UNIFIED IDEOGRAPH + {0xE4BF, 0x83EB}, //5861 #CJK UNIFIED IDEOGRAPH + {0xE4C0, 0x83CE}, //5862 #CJK UNIFIED IDEOGRAPH + {0xE4C1, 0x83FD}, //5863 #CJK UNIFIED IDEOGRAPH + {0xE4C2, 0x8403}, //5864 #CJK UNIFIED IDEOGRAPH + {0xE4C3, 0x83D8}, //5865 #CJK UNIFIED IDEOGRAPH + {0xE4C4, 0x840B}, //5866 #CJK UNIFIED IDEOGRAPH + {0xE4C5, 0x83C1}, //5867 #CJK UNIFIED IDEOGRAPH + {0xE4C6, 0x83F7}, //5868 #CJK UNIFIED IDEOGRAPH + {0xE4C7, 0x8407}, //5869 #CJK UNIFIED IDEOGRAPH + {0xE4C8, 0x83E0}, //5870 #CJK UNIFIED IDEOGRAPH + {0xE4C9, 0x83F2}, //5871 #CJK UNIFIED IDEOGRAPH + {0xE4CA, 0x840D}, //5872 #CJK UNIFIED IDEOGRAPH + {0xE4CB, 0x8422}, //5873 #CJK UNIFIED IDEOGRAPH + {0xE4CC, 0x8420}, //5874 #CJK UNIFIED IDEOGRAPH + {0xE4CD, 0x83BD}, //5875 #CJK UNIFIED IDEOGRAPH + {0xE4CE, 0x8438}, //5876 #CJK UNIFIED IDEOGRAPH + {0xE4CF, 0x8506}, //5877 #CJK UNIFIED IDEOGRAPH + {0xE4D0, 0x83FB}, //5878 #CJK UNIFIED IDEOGRAPH + {0xE4D1, 0x846D}, //5879 #CJK UNIFIED IDEOGRAPH + {0xE4D2, 0x842A}, //5880 #CJK UNIFIED IDEOGRAPH + {0xE4D3, 0x843C}, //5881 #CJK UNIFIED IDEOGRAPH + {0xE4D4, 0x855A}, //5882 #CJK UNIFIED IDEOGRAPH + {0xE4D5, 0x8484}, //5883 #CJK UNIFIED IDEOGRAPH + {0xE4D6, 0x8477}, //5884 #CJK UNIFIED IDEOGRAPH + {0xE4D7, 0x846B}, //5885 #CJK UNIFIED IDEOGRAPH + {0xE4D8, 0x84AD}, //5886 #CJK UNIFIED IDEOGRAPH + {0xE4D9, 0x846E}, //5887 #CJK UNIFIED IDEOGRAPH + {0xE4DA, 0x8482}, //5888 #CJK UNIFIED IDEOGRAPH + {0xE4DB, 0x8469}, //5889 #CJK UNIFIED IDEOGRAPH + {0xE4DC, 0x8446}, //5890 #CJK UNIFIED IDEOGRAPH + {0xE4DD, 0x842C}, //5891 #CJK UNIFIED IDEOGRAPH + {0xE4DE, 0x846F}, //5892 #CJK UNIFIED IDEOGRAPH + {0xE4DF, 0x8479}, //5893 #CJK UNIFIED IDEOGRAPH + {0xE4E0, 0x8435}, //5894 #CJK UNIFIED IDEOGRAPH + {0xE4E1, 0x84CA}, //5895 #CJK UNIFIED IDEOGRAPH + {0xE4E2, 0x8462}, //5896 #CJK UNIFIED IDEOGRAPH + {0xE4E3, 0x84B9}, //5897 #CJK UNIFIED IDEOGRAPH + {0xE4E4, 0x84BF}, //5898 #CJK UNIFIED IDEOGRAPH + {0xE4E5, 0x849F}, //5899 #CJK UNIFIED IDEOGRAPH + {0xE4E6, 0x84D9}, //5900 #CJK UNIFIED IDEOGRAPH + {0xE4E7, 0x84CD}, //5901 #CJK UNIFIED IDEOGRAPH + {0xE4E8, 0x84BB}, //5902 #CJK UNIFIED IDEOGRAPH + {0xE4E9, 0x84DA}, //5903 #CJK UNIFIED IDEOGRAPH + {0xE4EA, 0x84D0}, //5904 #CJK UNIFIED IDEOGRAPH + {0xE4EB, 0x84C1}, //5905 #CJK UNIFIED IDEOGRAPH + {0xE4EC, 0x84C6}, //5906 #CJK UNIFIED IDEOGRAPH + {0xE4ED, 0x84D6}, //5907 #CJK UNIFIED IDEOGRAPH + {0xE4EE, 0x84A1}, //5908 #CJK UNIFIED IDEOGRAPH + {0xE4EF, 0x8521}, //5909 #CJK UNIFIED IDEOGRAPH + {0xE4F0, 0x84FF}, //5910 #CJK UNIFIED IDEOGRAPH + {0xE4F1, 0x84F4}, //5911 #CJK UNIFIED IDEOGRAPH + {0xE4F2, 0x8517}, //5912 #CJK UNIFIED IDEOGRAPH + {0xE4F3, 0x8518}, //5913 #CJK UNIFIED IDEOGRAPH + {0xE4F4, 0x852C}, //5914 #CJK UNIFIED IDEOGRAPH + {0xE4F5, 0x851F}, //5915 #CJK UNIFIED IDEOGRAPH + {0xE4F6, 0x8515}, //5916 #CJK UNIFIED IDEOGRAPH + {0xE4F7, 0x8514}, //5917 #CJK UNIFIED IDEOGRAPH + {0xE4F8, 0x84FC}, //5918 #CJK UNIFIED IDEOGRAPH + {0xE4F9, 0x8540}, //5919 #CJK UNIFIED IDEOGRAPH + {0xE4FA, 0x8563}, //5920 #CJK UNIFIED IDEOGRAPH + {0xE4FB, 0x8558}, //5921 #CJK UNIFIED IDEOGRAPH + {0xE4FC, 0x8548}, //5922 #CJK UNIFIED IDEOGRAPH + {0xE540, 0x8541}, //5923 #CJK UNIFIED IDEOGRAPH + {0xE541, 0x8602}, //5924 #CJK UNIFIED IDEOGRAPH + {0xE542, 0x854B}, //5925 #CJK UNIFIED IDEOGRAPH + {0xE543, 0x8555}, //5926 #CJK UNIFIED IDEOGRAPH + {0xE544, 0x8580}, //5927 #CJK UNIFIED IDEOGRAPH + {0xE545, 0x85A4}, //5928 #CJK UNIFIED IDEOGRAPH + {0xE546, 0x8588}, //5929 #CJK UNIFIED IDEOGRAPH + {0xE547, 0x8591}, //5930 #CJK UNIFIED IDEOGRAPH + {0xE548, 0x858A}, //5931 #CJK UNIFIED IDEOGRAPH + {0xE549, 0x85A8}, //5932 #CJK UNIFIED IDEOGRAPH + {0xE54A, 0x856D}, //5933 #CJK UNIFIED IDEOGRAPH + {0xE54B, 0x8594}, //5934 #CJK UNIFIED IDEOGRAPH + {0xE54C, 0x859B}, //5935 #CJK UNIFIED IDEOGRAPH + {0xE54D, 0x85EA}, //5936 #CJK UNIFIED IDEOGRAPH + {0xE54E, 0x8587}, //5937 #CJK UNIFIED IDEOGRAPH + {0xE54F, 0x859C}, //5938 #CJK UNIFIED IDEOGRAPH + {0xE550, 0x8577}, //5939 #CJK UNIFIED IDEOGRAPH + {0xE551, 0x857E}, //5940 #CJK UNIFIED IDEOGRAPH + {0xE552, 0x8590}, //5941 #CJK UNIFIED IDEOGRAPH + {0xE553, 0x85C9}, //5942 #CJK UNIFIED IDEOGRAPH + {0xE554, 0x85BA}, //5943 #CJK UNIFIED IDEOGRAPH + {0xE555, 0x85CF}, //5944 #CJK UNIFIED IDEOGRAPH + {0xE556, 0x85B9}, //5945 #CJK UNIFIED IDEOGRAPH + {0xE557, 0x85D0}, //5946 #CJK UNIFIED IDEOGRAPH + {0xE558, 0x85D5}, //5947 #CJK UNIFIED IDEOGRAPH + {0xE559, 0x85DD}, //5948 #CJK UNIFIED IDEOGRAPH + {0xE55A, 0x85E5}, //5949 #CJK UNIFIED IDEOGRAPH + {0xE55B, 0x85DC}, //5950 #CJK UNIFIED IDEOGRAPH + {0xE55C, 0x85F9}, //5951 #CJK UNIFIED IDEOGRAPH + {0xE55D, 0x860A}, //5952 #CJK UNIFIED IDEOGRAPH + {0xE55E, 0x8613}, //5953 #CJK UNIFIED IDEOGRAPH + {0xE55F, 0x860B}, //5954 #CJK UNIFIED IDEOGRAPH + {0xE560, 0x85FE}, //5955 #CJK UNIFIED IDEOGRAPH + {0xE561, 0x85FA}, //5956 #CJK UNIFIED IDEOGRAPH + {0xE562, 0x8606}, //5957 #CJK UNIFIED IDEOGRAPH + {0xE563, 0x8622}, //5958 #CJK UNIFIED IDEOGRAPH + {0xE564, 0x861A}, //5959 #CJK UNIFIED IDEOGRAPH + {0xE565, 0x8630}, //5960 #CJK UNIFIED IDEOGRAPH + {0xE566, 0x863F}, //5961 #CJK UNIFIED IDEOGRAPH + {0xE567, 0x864D}, //5962 #CJK UNIFIED IDEOGRAPH + {0xE568, 0x4E55}, //5963 #CJK UNIFIED IDEOGRAPH + {0xE569, 0x8654}, //5964 #CJK UNIFIED IDEOGRAPH + {0xE56A, 0x865F}, //5965 #CJK UNIFIED IDEOGRAPH + {0xE56B, 0x8667}, //5966 #CJK UNIFIED IDEOGRAPH + {0xE56C, 0x8671}, //5967 #CJK UNIFIED IDEOGRAPH + {0xE56D, 0x8693}, //5968 #CJK UNIFIED IDEOGRAPH + {0xE56E, 0x86A3}, //5969 #CJK UNIFIED IDEOGRAPH + {0xE56F, 0x86A9}, //5970 #CJK UNIFIED IDEOGRAPH + {0xE570, 0x86AA}, //5971 #CJK UNIFIED IDEOGRAPH + {0xE571, 0x868B}, //5972 #CJK UNIFIED IDEOGRAPH + {0xE572, 0x868C}, //5973 #CJK UNIFIED IDEOGRAPH + {0xE573, 0x86B6}, //5974 #CJK UNIFIED IDEOGRAPH + {0xE574, 0x86AF}, //5975 #CJK UNIFIED IDEOGRAPH + {0xE575, 0x86C4}, //5976 #CJK UNIFIED IDEOGRAPH + {0xE576, 0x86C6}, //5977 #CJK UNIFIED IDEOGRAPH + {0xE577, 0x86B0}, //5978 #CJK UNIFIED IDEOGRAPH + {0xE578, 0x86C9}, //5979 #CJK UNIFIED IDEOGRAPH + {0xE579, 0x8823}, //5980 #CJK UNIFIED IDEOGRAPH + {0xE57A, 0x86AB}, //5981 #CJK UNIFIED IDEOGRAPH + {0xE57B, 0x86D4}, //5982 #CJK UNIFIED IDEOGRAPH + {0xE57C, 0x86DE}, //5983 #CJK UNIFIED IDEOGRAPH + {0xE57D, 0x86E9}, //5984 #CJK UNIFIED IDEOGRAPH + {0xE57E, 0x86EC}, //5985 #CJK UNIFIED IDEOGRAPH + {0xE580, 0x86DF}, //5986 #CJK UNIFIED IDEOGRAPH + {0xE581, 0x86DB}, //5987 #CJK UNIFIED IDEOGRAPH + {0xE582, 0x86EF}, //5988 #CJK UNIFIED IDEOGRAPH + {0xE583, 0x8712}, //5989 #CJK UNIFIED IDEOGRAPH + {0xE584, 0x8706}, //5990 #CJK UNIFIED IDEOGRAPH + {0xE585, 0x8708}, //5991 #CJK UNIFIED IDEOGRAPH + {0xE586, 0x8700}, //5992 #CJK UNIFIED IDEOGRAPH + {0xE587, 0x8703}, //5993 #CJK UNIFIED IDEOGRAPH + {0xE588, 0x86FB}, //5994 #CJK UNIFIED IDEOGRAPH + {0xE589, 0x8711}, //5995 #CJK UNIFIED IDEOGRAPH + {0xE58A, 0x8709}, //5996 #CJK UNIFIED IDEOGRAPH + {0xE58B, 0x870D}, //5997 #CJK UNIFIED IDEOGRAPH + {0xE58C, 0x86F9}, //5998 #CJK UNIFIED IDEOGRAPH + {0xE58D, 0x870A}, //5999 #CJK UNIFIED IDEOGRAPH + {0xE58E, 0x8734}, //6000 #CJK UNIFIED IDEOGRAPH + {0xE58F, 0x873F}, //6001 #CJK UNIFIED IDEOGRAPH + {0xE590, 0x8737}, //6002 #CJK UNIFIED IDEOGRAPH + {0xE591, 0x873B}, //6003 #CJK UNIFIED IDEOGRAPH + {0xE592, 0x8725}, //6004 #CJK UNIFIED IDEOGRAPH + {0xE593, 0x8729}, //6005 #CJK UNIFIED IDEOGRAPH + {0xE594, 0x871A}, //6006 #CJK UNIFIED IDEOGRAPH + {0xE595, 0x8760}, //6007 #CJK UNIFIED IDEOGRAPH + {0xE596, 0x875F}, //6008 #CJK UNIFIED IDEOGRAPH + {0xE597, 0x8778}, //6009 #CJK UNIFIED IDEOGRAPH + {0xE598, 0x874C}, //6010 #CJK UNIFIED IDEOGRAPH + {0xE599, 0x874E}, //6011 #CJK UNIFIED IDEOGRAPH + {0xE59A, 0x8774}, //6012 #CJK UNIFIED IDEOGRAPH + {0xE59B, 0x8757}, //6013 #CJK UNIFIED IDEOGRAPH + {0xE59C, 0x8768}, //6014 #CJK UNIFIED IDEOGRAPH + {0xE59D, 0x876E}, //6015 #CJK UNIFIED IDEOGRAPH + {0xE59E, 0x8759}, //6016 #CJK UNIFIED IDEOGRAPH + {0xE59F, 0x8753}, //6017 #CJK UNIFIED IDEOGRAPH + {0xE5A0, 0x8763}, //6018 #CJK UNIFIED IDEOGRAPH + {0xE5A1, 0x876A}, //6019 #CJK UNIFIED IDEOGRAPH + {0xE5A2, 0x8805}, //6020 #CJK UNIFIED IDEOGRAPH + {0xE5A3, 0x87A2}, //6021 #CJK UNIFIED IDEOGRAPH + {0xE5A4, 0x879F}, //6022 #CJK UNIFIED IDEOGRAPH + {0xE5A5, 0x8782}, //6023 #CJK UNIFIED IDEOGRAPH + {0xE5A6, 0x87AF}, //6024 #CJK UNIFIED IDEOGRAPH + {0xE5A7, 0x87CB}, //6025 #CJK UNIFIED IDEOGRAPH + {0xE5A8, 0x87BD}, //6026 #CJK UNIFIED IDEOGRAPH + {0xE5A9, 0x87C0}, //6027 #CJK UNIFIED IDEOGRAPH + {0xE5AA, 0x87D0}, //6028 #CJK UNIFIED IDEOGRAPH + {0xE5AB, 0x96D6}, //6029 #CJK UNIFIED IDEOGRAPH + {0xE5AC, 0x87AB}, //6030 #CJK UNIFIED IDEOGRAPH + {0xE5AD, 0x87C4}, //6031 #CJK UNIFIED IDEOGRAPH + {0xE5AE, 0x87B3}, //6032 #CJK UNIFIED IDEOGRAPH + {0xE5AF, 0x87C7}, //6033 #CJK UNIFIED IDEOGRAPH + {0xE5B0, 0x87C6}, //6034 #CJK UNIFIED IDEOGRAPH + {0xE5B1, 0x87BB}, //6035 #CJK UNIFIED IDEOGRAPH + {0xE5B2, 0x87EF}, //6036 #CJK UNIFIED IDEOGRAPH + {0xE5B3, 0x87F2}, //6037 #CJK UNIFIED IDEOGRAPH + {0xE5B4, 0x87E0}, //6038 #CJK UNIFIED IDEOGRAPH + {0xE5B5, 0x880F}, //6039 #CJK UNIFIED IDEOGRAPH + {0xE5B6, 0x880D}, //6040 #CJK UNIFIED IDEOGRAPH + {0xE5B7, 0x87FE}, //6041 #CJK UNIFIED IDEOGRAPH + {0xE5B8, 0x87F6}, //6042 #CJK UNIFIED IDEOGRAPH + {0xE5B9, 0x87F7}, //6043 #CJK UNIFIED IDEOGRAPH + {0xE5BA, 0x880E}, //6044 #CJK UNIFIED IDEOGRAPH + {0xE5BB, 0x87D2}, //6045 #CJK UNIFIED IDEOGRAPH + {0xE5BC, 0x8811}, //6046 #CJK UNIFIED IDEOGRAPH + {0xE5BD, 0x8816}, //6047 #CJK UNIFIED IDEOGRAPH + {0xE5BE, 0x8815}, //6048 #CJK UNIFIED IDEOGRAPH + {0xE5BF, 0x8822}, //6049 #CJK UNIFIED IDEOGRAPH + {0xE5C0, 0x8821}, //6050 #CJK UNIFIED IDEOGRAPH + {0xE5C1, 0x8831}, //6051 #CJK UNIFIED IDEOGRAPH + {0xE5C2, 0x8836}, //6052 #CJK UNIFIED IDEOGRAPH + {0xE5C3, 0x8839}, //6053 #CJK UNIFIED IDEOGRAPH + {0xE5C4, 0x8827}, //6054 #CJK UNIFIED IDEOGRAPH + {0xE5C5, 0x883B}, //6055 #CJK UNIFIED IDEOGRAPH + {0xE5C6, 0x8844}, //6056 #CJK UNIFIED IDEOGRAPH + {0xE5C7, 0x8842}, //6057 #CJK UNIFIED IDEOGRAPH + {0xE5C8, 0x8852}, //6058 #CJK UNIFIED IDEOGRAPH + {0xE5C9, 0x8859}, //6059 #CJK UNIFIED IDEOGRAPH + {0xE5CA, 0x885E}, //6060 #CJK UNIFIED IDEOGRAPH + {0xE5CB, 0x8862}, //6061 #CJK UNIFIED IDEOGRAPH + {0xE5CC, 0x886B}, //6062 #CJK UNIFIED IDEOGRAPH + {0xE5CD, 0x8881}, //6063 #CJK UNIFIED IDEOGRAPH + {0xE5CE, 0x887E}, //6064 #CJK UNIFIED IDEOGRAPH + {0xE5CF, 0x889E}, //6065 #CJK UNIFIED IDEOGRAPH + {0xE5D0, 0x8875}, //6066 #CJK UNIFIED IDEOGRAPH + {0xE5D1, 0x887D}, //6067 #CJK UNIFIED IDEOGRAPH + {0xE5D2, 0x88B5}, //6068 #CJK UNIFIED IDEOGRAPH + {0xE5D3, 0x8872}, //6069 #CJK UNIFIED IDEOGRAPH + {0xE5D4, 0x8882}, //6070 #CJK UNIFIED IDEOGRAPH + {0xE5D5, 0x8897}, //6071 #CJK UNIFIED IDEOGRAPH + {0xE5D6, 0x8892}, //6072 #CJK UNIFIED IDEOGRAPH + {0xE5D7, 0x88AE}, //6073 #CJK UNIFIED IDEOGRAPH + {0xE5D8, 0x8899}, //6074 #CJK UNIFIED IDEOGRAPH + {0xE5D9, 0x88A2}, //6075 #CJK UNIFIED IDEOGRAPH + {0xE5DA, 0x888D}, //6076 #CJK UNIFIED IDEOGRAPH + {0xE5DB, 0x88A4}, //6077 #CJK UNIFIED IDEOGRAPH + {0xE5DC, 0x88B0}, //6078 #CJK UNIFIED IDEOGRAPH + {0xE5DD, 0x88BF}, //6079 #CJK UNIFIED IDEOGRAPH + {0xE5DE, 0x88B1}, //6080 #CJK UNIFIED IDEOGRAPH + {0xE5DF, 0x88C3}, //6081 #CJK UNIFIED IDEOGRAPH + {0xE5E0, 0x88C4}, //6082 #CJK UNIFIED IDEOGRAPH + {0xE5E1, 0x88D4}, //6083 #CJK UNIFIED IDEOGRAPH + {0xE5E2, 0x88D8}, //6084 #CJK UNIFIED IDEOGRAPH + {0xE5E3, 0x88D9}, //6085 #CJK UNIFIED IDEOGRAPH + {0xE5E4, 0x88DD}, //6086 #CJK UNIFIED IDEOGRAPH + {0xE5E5, 0x88F9}, //6087 #CJK UNIFIED IDEOGRAPH + {0xE5E6, 0x8902}, //6088 #CJK UNIFIED IDEOGRAPH + {0xE5E7, 0x88FC}, //6089 #CJK UNIFIED IDEOGRAPH + {0xE5E8, 0x88F4}, //6090 #CJK UNIFIED IDEOGRAPH + {0xE5E9, 0x88E8}, //6091 #CJK UNIFIED IDEOGRAPH + {0xE5EA, 0x88F2}, //6092 #CJK UNIFIED IDEOGRAPH + {0xE5EB, 0x8904}, //6093 #CJK UNIFIED IDEOGRAPH + {0xE5EC, 0x890C}, //6094 #CJK UNIFIED IDEOGRAPH + {0xE5ED, 0x890A}, //6095 #CJK UNIFIED IDEOGRAPH + {0xE5EE, 0x8913}, //6096 #CJK UNIFIED IDEOGRAPH + {0xE5EF, 0x8943}, //6097 #CJK UNIFIED IDEOGRAPH + {0xE5F0, 0x891E}, //6098 #CJK UNIFIED IDEOGRAPH + {0xE5F1, 0x8925}, //6099 #CJK UNIFIED IDEOGRAPH + {0xE5F2, 0x892A}, //6100 #CJK UNIFIED IDEOGRAPH + {0xE5F3, 0x892B}, //6101 #CJK UNIFIED IDEOGRAPH + {0xE5F4, 0x8941}, //6102 #CJK UNIFIED IDEOGRAPH + {0xE5F5, 0x8944}, //6103 #CJK UNIFIED IDEOGRAPH + {0xE5F6, 0x893B}, //6104 #CJK UNIFIED IDEOGRAPH + {0xE5F7, 0x8936}, //6105 #CJK UNIFIED IDEOGRAPH + {0xE5F8, 0x8938}, //6106 #CJK UNIFIED IDEOGRAPH + {0xE5F9, 0x894C}, //6107 #CJK UNIFIED IDEOGRAPH + {0xE5FA, 0x891D}, //6108 #CJK UNIFIED IDEOGRAPH + {0xE5FB, 0x8960}, //6109 #CJK UNIFIED IDEOGRAPH + {0xE5FC, 0x895E}, //6110 #CJK UNIFIED IDEOGRAPH + {0xE640, 0x8966}, //6111 #CJK UNIFIED IDEOGRAPH + {0xE641, 0x8964}, //6112 #CJK UNIFIED IDEOGRAPH + {0xE642, 0x896D}, //6113 #CJK UNIFIED IDEOGRAPH + {0xE643, 0x896A}, //6114 #CJK UNIFIED IDEOGRAPH + {0xE644, 0x896F}, //6115 #CJK UNIFIED IDEOGRAPH + {0xE645, 0x8974}, //6116 #CJK UNIFIED IDEOGRAPH + {0xE646, 0x8977}, //6117 #CJK UNIFIED IDEOGRAPH + {0xE647, 0x897E}, //6118 #CJK UNIFIED IDEOGRAPH + {0xE648, 0x8983}, //6119 #CJK UNIFIED IDEOGRAPH + {0xE649, 0x8988}, //6120 #CJK UNIFIED IDEOGRAPH + {0xE64A, 0x898A}, //6121 #CJK UNIFIED IDEOGRAPH + {0xE64B, 0x8993}, //6122 #CJK UNIFIED IDEOGRAPH + {0xE64C, 0x8998}, //6123 #CJK UNIFIED IDEOGRAPH + {0xE64D, 0x89A1}, //6124 #CJK UNIFIED IDEOGRAPH + {0xE64E, 0x89A9}, //6125 #CJK UNIFIED IDEOGRAPH + {0xE64F, 0x89A6}, //6126 #CJK UNIFIED IDEOGRAPH + {0xE650, 0x89AC}, //6127 #CJK UNIFIED IDEOGRAPH + {0xE651, 0x89AF}, //6128 #CJK UNIFIED IDEOGRAPH + {0xE652, 0x89B2}, //6129 #CJK UNIFIED IDEOGRAPH + {0xE653, 0x89BA}, //6130 #CJK UNIFIED IDEOGRAPH + {0xE654, 0x89BD}, //6131 #CJK UNIFIED IDEOGRAPH + {0xE655, 0x89BF}, //6132 #CJK UNIFIED IDEOGRAPH + {0xE656, 0x89C0}, //6133 #CJK UNIFIED IDEOGRAPH + {0xE657, 0x89DA}, //6134 #CJK UNIFIED IDEOGRAPH + {0xE658, 0x89DC}, //6135 #CJK UNIFIED IDEOGRAPH + {0xE659, 0x89DD}, //6136 #CJK UNIFIED IDEOGRAPH + {0xE65A, 0x89E7}, //6137 #CJK UNIFIED IDEOGRAPH + {0xE65B, 0x89F4}, //6138 #CJK UNIFIED IDEOGRAPH + {0xE65C, 0x89F8}, //6139 #CJK UNIFIED IDEOGRAPH + {0xE65D, 0x8A03}, //6140 #CJK UNIFIED IDEOGRAPH + {0xE65E, 0x8A16}, //6141 #CJK UNIFIED IDEOGRAPH + {0xE65F, 0x8A10}, //6142 #CJK UNIFIED IDEOGRAPH + {0xE660, 0x8A0C}, //6143 #CJK UNIFIED IDEOGRAPH + {0xE661, 0x8A1B}, //6144 #CJK UNIFIED IDEOGRAPH + {0xE662, 0x8A1D}, //6145 #CJK UNIFIED IDEOGRAPH + {0xE663, 0x8A25}, //6146 #CJK UNIFIED IDEOGRAPH + {0xE664, 0x8A36}, //6147 #CJK UNIFIED IDEOGRAPH + {0xE665, 0x8A41}, //6148 #CJK UNIFIED IDEOGRAPH + {0xE666, 0x8A5B}, //6149 #CJK UNIFIED IDEOGRAPH + {0xE667, 0x8A52}, //6150 #CJK UNIFIED IDEOGRAPH + {0xE668, 0x8A46}, //6151 #CJK UNIFIED IDEOGRAPH + {0xE669, 0x8A48}, //6152 #CJK UNIFIED IDEOGRAPH + {0xE66A, 0x8A7C}, //6153 #CJK UNIFIED IDEOGRAPH + {0xE66B, 0x8A6D}, //6154 #CJK UNIFIED IDEOGRAPH + {0xE66C, 0x8A6C}, //6155 #CJK UNIFIED IDEOGRAPH + {0xE66D, 0x8A62}, //6156 #CJK UNIFIED IDEOGRAPH + {0xE66E, 0x8A85}, //6157 #CJK UNIFIED IDEOGRAPH + {0xE66F, 0x8A82}, //6158 #CJK UNIFIED IDEOGRAPH + {0xE670, 0x8A84}, //6159 #CJK UNIFIED IDEOGRAPH + {0xE671, 0x8AA8}, //6160 #CJK UNIFIED IDEOGRAPH + {0xE672, 0x8AA1}, //6161 #CJK UNIFIED IDEOGRAPH + {0xE673, 0x8A91}, //6162 #CJK UNIFIED IDEOGRAPH + {0xE674, 0x8AA5}, //6163 #CJK UNIFIED IDEOGRAPH + {0xE675, 0x8AA6}, //6164 #CJK UNIFIED IDEOGRAPH + {0xE676, 0x8A9A}, //6165 #CJK UNIFIED IDEOGRAPH + {0xE677, 0x8AA3}, //6166 #CJK UNIFIED IDEOGRAPH + {0xE678, 0x8AC4}, //6167 #CJK UNIFIED IDEOGRAPH + {0xE679, 0x8ACD}, //6168 #CJK UNIFIED IDEOGRAPH + {0xE67A, 0x8AC2}, //6169 #CJK UNIFIED IDEOGRAPH + {0xE67B, 0x8ADA}, //6170 #CJK UNIFIED IDEOGRAPH + {0xE67C, 0x8AEB}, //6171 #CJK UNIFIED IDEOGRAPH + {0xE67D, 0x8AF3}, //6172 #CJK UNIFIED IDEOGRAPH + {0xE67E, 0x8AE7}, //6173 #CJK UNIFIED IDEOGRAPH + {0xE680, 0x8AE4}, //6174 #CJK UNIFIED IDEOGRAPH + {0xE681, 0x8AF1}, //6175 #CJK UNIFIED IDEOGRAPH + {0xE682, 0x8B14}, //6176 #CJK UNIFIED IDEOGRAPH + {0xE683, 0x8AE0}, //6177 #CJK UNIFIED IDEOGRAPH + {0xE684, 0x8AE2}, //6178 #CJK UNIFIED IDEOGRAPH + {0xE685, 0x8AF7}, //6179 #CJK UNIFIED IDEOGRAPH + {0xE686, 0x8ADE}, //6180 #CJK UNIFIED IDEOGRAPH + {0xE687, 0x8ADB}, //6181 #CJK UNIFIED IDEOGRAPH + {0xE688, 0x8B0C}, //6182 #CJK UNIFIED IDEOGRAPH + {0xE689, 0x8B07}, //6183 #CJK UNIFIED IDEOGRAPH + {0xE68A, 0x8B1A}, //6184 #CJK UNIFIED IDEOGRAPH + {0xE68B, 0x8AE1}, //6185 #CJK UNIFIED IDEOGRAPH + {0xE68C, 0x8B16}, //6186 #CJK UNIFIED IDEOGRAPH + {0xE68D, 0x8B10}, //6187 #CJK UNIFIED IDEOGRAPH + {0xE68E, 0x8B17}, //6188 #CJK UNIFIED IDEOGRAPH + {0xE68F, 0x8B20}, //6189 #CJK UNIFIED IDEOGRAPH + {0xE690, 0x8B33}, //6190 #CJK UNIFIED IDEOGRAPH + {0xE691, 0x97AB}, //6191 #CJK UNIFIED IDEOGRAPH + {0xE692, 0x8B26}, //6192 #CJK UNIFIED IDEOGRAPH + {0xE693, 0x8B2B}, //6193 #CJK UNIFIED IDEOGRAPH + {0xE694, 0x8B3E}, //6194 #CJK UNIFIED IDEOGRAPH + {0xE695, 0x8B28}, //6195 #CJK UNIFIED IDEOGRAPH + {0xE696, 0x8B41}, //6196 #CJK UNIFIED IDEOGRAPH + {0xE697, 0x8B4C}, //6197 #CJK UNIFIED IDEOGRAPH + {0xE698, 0x8B4F}, //6198 #CJK UNIFIED IDEOGRAPH + {0xE699, 0x8B4E}, //6199 #CJK UNIFIED IDEOGRAPH + {0xE69A, 0x8B49}, //6200 #CJK UNIFIED IDEOGRAPH + {0xE69B, 0x8B56}, //6201 #CJK UNIFIED IDEOGRAPH + {0xE69C, 0x8B5B}, //6202 #CJK UNIFIED IDEOGRAPH + {0xE69D, 0x8B5A}, //6203 #CJK UNIFIED IDEOGRAPH + {0xE69E, 0x8B6B}, //6204 #CJK UNIFIED IDEOGRAPH + {0xE69F, 0x8B5F}, //6205 #CJK UNIFIED IDEOGRAPH + {0xE6A0, 0x8B6C}, //6206 #CJK UNIFIED IDEOGRAPH + {0xE6A1, 0x8B6F}, //6207 #CJK UNIFIED IDEOGRAPH + {0xE6A2, 0x8B74}, //6208 #CJK UNIFIED IDEOGRAPH + {0xE6A3, 0x8B7D}, //6209 #CJK UNIFIED IDEOGRAPH + {0xE6A4, 0x8B80}, //6210 #CJK UNIFIED IDEOGRAPH + {0xE6A5, 0x8B8C}, //6211 #CJK UNIFIED IDEOGRAPH + {0xE6A6, 0x8B8E}, //6212 #CJK UNIFIED IDEOGRAPH + {0xE6A7, 0x8B92}, //6213 #CJK UNIFIED IDEOGRAPH + {0xE6A8, 0x8B93}, //6214 #CJK UNIFIED IDEOGRAPH + {0xE6A9, 0x8B96}, //6215 #CJK UNIFIED IDEOGRAPH + {0xE6AA, 0x8B99}, //6216 #CJK UNIFIED IDEOGRAPH + {0xE6AB, 0x8B9A}, //6217 #CJK UNIFIED IDEOGRAPH + {0xE6AC, 0x8C3A}, //6218 #CJK UNIFIED IDEOGRAPH + {0xE6AD, 0x8C41}, //6219 #CJK UNIFIED IDEOGRAPH + {0xE6AE, 0x8C3F}, //6220 #CJK UNIFIED IDEOGRAPH + {0xE6AF, 0x8C48}, //6221 #CJK UNIFIED IDEOGRAPH + {0xE6B0, 0x8C4C}, //6222 #CJK UNIFIED IDEOGRAPH + {0xE6B1, 0x8C4E}, //6223 #CJK UNIFIED IDEOGRAPH + {0xE6B2, 0x8C50}, //6224 #CJK UNIFIED IDEOGRAPH + {0xE6B3, 0x8C55}, //6225 #CJK UNIFIED IDEOGRAPH + {0xE6B4, 0x8C62}, //6226 #CJK UNIFIED IDEOGRAPH + {0xE6B5, 0x8C6C}, //6227 #CJK UNIFIED IDEOGRAPH + {0xE6B6, 0x8C78}, //6228 #CJK UNIFIED IDEOGRAPH + {0xE6B7, 0x8C7A}, //6229 #CJK UNIFIED IDEOGRAPH + {0xE6B8, 0x8C82}, //6230 #CJK UNIFIED IDEOGRAPH + {0xE6B9, 0x8C89}, //6231 #CJK UNIFIED IDEOGRAPH + {0xE6BA, 0x8C85}, //6232 #CJK UNIFIED IDEOGRAPH + {0xE6BB, 0x8C8A}, //6233 #CJK UNIFIED IDEOGRAPH + {0xE6BC, 0x8C8D}, //6234 #CJK UNIFIED IDEOGRAPH + {0xE6BD, 0x8C8E}, //6235 #CJK UNIFIED IDEOGRAPH + {0xE6BE, 0x8C94}, //6236 #CJK UNIFIED IDEOGRAPH + {0xE6BF, 0x8C7C}, //6237 #CJK UNIFIED IDEOGRAPH + {0xE6C0, 0x8C98}, //6238 #CJK UNIFIED IDEOGRAPH + {0xE6C1, 0x621D}, //6239 #CJK UNIFIED IDEOGRAPH + {0xE6C2, 0x8CAD}, //6240 #CJK UNIFIED IDEOGRAPH + {0xE6C3, 0x8CAA}, //6241 #CJK UNIFIED IDEOGRAPH + {0xE6C4, 0x8CBD}, //6242 #CJK UNIFIED IDEOGRAPH + {0xE6C5, 0x8CB2}, //6243 #CJK UNIFIED IDEOGRAPH + {0xE6C6, 0x8CB3}, //6244 #CJK UNIFIED IDEOGRAPH + {0xE6C7, 0x8CAE}, //6245 #CJK UNIFIED IDEOGRAPH + {0xE6C8, 0x8CB6}, //6246 #CJK UNIFIED IDEOGRAPH + {0xE6C9, 0x8CC8}, //6247 #CJK UNIFIED IDEOGRAPH + {0xE6CA, 0x8CC1}, //6248 #CJK UNIFIED IDEOGRAPH + {0xE6CB, 0x8CE4}, //6249 #CJK UNIFIED IDEOGRAPH + {0xE6CC, 0x8CE3}, //6250 #CJK UNIFIED IDEOGRAPH + {0xE6CD, 0x8CDA}, //6251 #CJK UNIFIED IDEOGRAPH + {0xE6CE, 0x8CFD}, //6252 #CJK UNIFIED IDEOGRAPH + {0xE6CF, 0x8CFA}, //6253 #CJK UNIFIED IDEOGRAPH + {0xE6D0, 0x8CFB}, //6254 #CJK UNIFIED IDEOGRAPH + {0xE6D1, 0x8D04}, //6255 #CJK UNIFIED IDEOGRAPH + {0xE6D2, 0x8D05}, //6256 #CJK UNIFIED IDEOGRAPH + {0xE6D3, 0x8D0A}, //6257 #CJK UNIFIED IDEOGRAPH + {0xE6D4, 0x8D07}, //6258 #CJK UNIFIED IDEOGRAPH + {0xE6D5, 0x8D0F}, //6259 #CJK UNIFIED IDEOGRAPH + {0xE6D6, 0x8D0D}, //6260 #CJK UNIFIED IDEOGRAPH + {0xE6D7, 0x8D10}, //6261 #CJK UNIFIED IDEOGRAPH + {0xE6D8, 0x9F4E}, //6262 #CJK UNIFIED IDEOGRAPH + {0xE6D9, 0x8D13}, //6263 #CJK UNIFIED IDEOGRAPH + {0xE6DA, 0x8CCD}, //6264 #CJK UNIFIED IDEOGRAPH + {0xE6DB, 0x8D14}, //6265 #CJK UNIFIED IDEOGRAPH + {0xE6DC, 0x8D16}, //6266 #CJK UNIFIED IDEOGRAPH + {0xE6DD, 0x8D67}, //6267 #CJK UNIFIED IDEOGRAPH + {0xE6DE, 0x8D6D}, //6268 #CJK UNIFIED IDEOGRAPH + {0xE6DF, 0x8D71}, //6269 #CJK UNIFIED IDEOGRAPH + {0xE6E0, 0x8D73}, //6270 #CJK UNIFIED IDEOGRAPH + {0xE6E1, 0x8D81}, //6271 #CJK UNIFIED IDEOGRAPH + {0xE6E2, 0x8D99}, //6272 #CJK UNIFIED IDEOGRAPH + {0xE6E3, 0x8DC2}, //6273 #CJK UNIFIED IDEOGRAPH + {0xE6E4, 0x8DBE}, //6274 #CJK UNIFIED IDEOGRAPH + {0xE6E5, 0x8DBA}, //6275 #CJK UNIFIED IDEOGRAPH + {0xE6E6, 0x8DCF}, //6276 #CJK UNIFIED IDEOGRAPH + {0xE6E7, 0x8DDA}, //6277 #CJK UNIFIED IDEOGRAPH + {0xE6E8, 0x8DD6}, //6278 #CJK UNIFIED IDEOGRAPH + {0xE6E9, 0x8DCC}, //6279 #CJK UNIFIED IDEOGRAPH + {0xE6EA, 0x8DDB}, //6280 #CJK UNIFIED IDEOGRAPH + {0xE6EB, 0x8DCB}, //6281 #CJK UNIFIED IDEOGRAPH + {0xE6EC, 0x8DEA}, //6282 #CJK UNIFIED IDEOGRAPH + {0xE6ED, 0x8DEB}, //6283 #CJK UNIFIED IDEOGRAPH + {0xE6EE, 0x8DDF}, //6284 #CJK UNIFIED IDEOGRAPH + {0xE6EF, 0x8DE3}, //6285 #CJK UNIFIED IDEOGRAPH + {0xE6F0, 0x8DFC}, //6286 #CJK UNIFIED IDEOGRAPH + {0xE6F1, 0x8E08}, //6287 #CJK UNIFIED IDEOGRAPH + {0xE6F2, 0x8E09}, //6288 #CJK UNIFIED IDEOGRAPH + {0xE6F3, 0x8DFF}, //6289 #CJK UNIFIED IDEOGRAPH + {0xE6F4, 0x8E1D}, //6290 #CJK UNIFIED IDEOGRAPH + {0xE6F5, 0x8E1E}, //6291 #CJK UNIFIED IDEOGRAPH + {0xE6F6, 0x8E10}, //6292 #CJK UNIFIED IDEOGRAPH + {0xE6F7, 0x8E1F}, //6293 #CJK UNIFIED IDEOGRAPH + {0xE6F8, 0x8E42}, //6294 #CJK UNIFIED IDEOGRAPH + {0xE6F9, 0x8E35}, //6295 #CJK UNIFIED IDEOGRAPH + {0xE6FA, 0x8E30}, //6296 #CJK UNIFIED IDEOGRAPH + {0xE6FB, 0x8E34}, //6297 #CJK UNIFIED IDEOGRAPH + {0xE6FC, 0x8E4A}, //6298 #CJK UNIFIED IDEOGRAPH + {0xE740, 0x8E47}, //6299 #CJK UNIFIED IDEOGRAPH + {0xE741, 0x8E49}, //6300 #CJK UNIFIED IDEOGRAPH + {0xE742, 0x8E4C}, //6301 #CJK UNIFIED IDEOGRAPH + {0xE743, 0x8E50}, //6302 #CJK UNIFIED IDEOGRAPH + {0xE744, 0x8E48}, //6303 #CJK UNIFIED IDEOGRAPH + {0xE745, 0x8E59}, //6304 #CJK UNIFIED IDEOGRAPH + {0xE746, 0x8E64}, //6305 #CJK UNIFIED IDEOGRAPH + {0xE747, 0x8E60}, //6306 #CJK UNIFIED IDEOGRAPH + {0xE748, 0x8E2A}, //6307 #CJK UNIFIED IDEOGRAPH + {0xE749, 0x8E63}, //6308 #CJK UNIFIED IDEOGRAPH + {0xE74A, 0x8E55}, //6309 #CJK UNIFIED IDEOGRAPH + {0xE74B, 0x8E76}, //6310 #CJK UNIFIED IDEOGRAPH + {0xE74C, 0x8E72}, //6311 #CJK UNIFIED IDEOGRAPH + {0xE74D, 0x8E7C}, //6312 #CJK UNIFIED IDEOGRAPH + {0xE74E, 0x8E81}, //6313 #CJK UNIFIED IDEOGRAPH + {0xE74F, 0x8E87}, //6314 #CJK UNIFIED IDEOGRAPH + {0xE750, 0x8E85}, //6315 #CJK UNIFIED IDEOGRAPH + {0xE751, 0x8E84}, //6316 #CJK UNIFIED IDEOGRAPH + {0xE752, 0x8E8B}, //6317 #CJK UNIFIED IDEOGRAPH + {0xE753, 0x8E8A}, //6318 #CJK UNIFIED IDEOGRAPH + {0xE754, 0x8E93}, //6319 #CJK UNIFIED IDEOGRAPH + {0xE755, 0x8E91}, //6320 #CJK UNIFIED IDEOGRAPH + {0xE756, 0x8E94}, //6321 #CJK UNIFIED IDEOGRAPH + {0xE757, 0x8E99}, //6322 #CJK UNIFIED IDEOGRAPH + {0xE758, 0x8EAA}, //6323 #CJK UNIFIED IDEOGRAPH + {0xE759, 0x8EA1}, //6324 #CJK UNIFIED IDEOGRAPH + {0xE75A, 0x8EAC}, //6325 #CJK UNIFIED IDEOGRAPH + {0xE75B, 0x8EB0}, //6326 #CJK UNIFIED IDEOGRAPH + {0xE75C, 0x8EC6}, //6327 #CJK UNIFIED IDEOGRAPH + {0xE75D, 0x8EB1}, //6328 #CJK UNIFIED IDEOGRAPH + {0xE75E, 0x8EBE}, //6329 #CJK UNIFIED IDEOGRAPH + {0xE75F, 0x8EC5}, //6330 #CJK UNIFIED IDEOGRAPH + {0xE760, 0x8EC8}, //6331 #CJK UNIFIED IDEOGRAPH + {0xE761, 0x8ECB}, //6332 #CJK UNIFIED IDEOGRAPH + {0xE762, 0x8EDB}, //6333 #CJK UNIFIED IDEOGRAPH + {0xE763, 0x8EE3}, //6334 #CJK UNIFIED IDEOGRAPH + {0xE764, 0x8EFC}, //6335 #CJK UNIFIED IDEOGRAPH + {0xE765, 0x8EFB}, //6336 #CJK UNIFIED IDEOGRAPH + {0xE766, 0x8EEB}, //6337 #CJK UNIFIED IDEOGRAPH + {0xE767, 0x8EFE}, //6338 #CJK UNIFIED IDEOGRAPH + {0xE768, 0x8F0A}, //6339 #CJK UNIFIED IDEOGRAPH + {0xE769, 0x8F05}, //6340 #CJK UNIFIED IDEOGRAPH + {0xE76A, 0x8F15}, //6341 #CJK UNIFIED IDEOGRAPH + {0xE76B, 0x8F12}, //6342 #CJK UNIFIED IDEOGRAPH + {0xE76C, 0x8F19}, //6343 #CJK UNIFIED IDEOGRAPH + {0xE76D, 0x8F13}, //6344 #CJK UNIFIED IDEOGRAPH + {0xE76E, 0x8F1C}, //6345 #CJK UNIFIED IDEOGRAPH + {0xE76F, 0x8F1F}, //6346 #CJK UNIFIED IDEOGRAPH + {0xE770, 0x8F1B}, //6347 #CJK UNIFIED IDEOGRAPH + {0xE771, 0x8F0C}, //6348 #CJK UNIFIED IDEOGRAPH + {0xE772, 0x8F26}, //6349 #CJK UNIFIED IDEOGRAPH + {0xE773, 0x8F33}, //6350 #CJK UNIFIED IDEOGRAPH + {0xE774, 0x8F3B}, //6351 #CJK UNIFIED IDEOGRAPH + {0xE775, 0x8F39}, //6352 #CJK UNIFIED IDEOGRAPH + {0xE776, 0x8F45}, //6353 #CJK UNIFIED IDEOGRAPH + {0xE777, 0x8F42}, //6354 #CJK UNIFIED IDEOGRAPH + {0xE778, 0x8F3E}, //6355 #CJK UNIFIED IDEOGRAPH + {0xE779, 0x8F4C}, //6356 #CJK UNIFIED IDEOGRAPH + {0xE77A, 0x8F49}, //6357 #CJK UNIFIED IDEOGRAPH + {0xE77B, 0x8F46}, //6358 #CJK UNIFIED IDEOGRAPH + {0xE77C, 0x8F4E}, //6359 #CJK UNIFIED IDEOGRAPH + {0xE77D, 0x8F57}, //6360 #CJK UNIFIED IDEOGRAPH + {0xE77E, 0x8F5C}, //6361 #CJK UNIFIED IDEOGRAPH + {0xE780, 0x8F62}, //6362 #CJK UNIFIED IDEOGRAPH + {0xE781, 0x8F63}, //6363 #CJK UNIFIED IDEOGRAPH + {0xE782, 0x8F64}, //6364 #CJK UNIFIED IDEOGRAPH + {0xE783, 0x8F9C}, //6365 #CJK UNIFIED IDEOGRAPH + {0xE784, 0x8F9F}, //6366 #CJK UNIFIED IDEOGRAPH + {0xE785, 0x8FA3}, //6367 #CJK UNIFIED IDEOGRAPH + {0xE786, 0x8FAD}, //6368 #CJK UNIFIED IDEOGRAPH + {0xE787, 0x8FAF}, //6369 #CJK UNIFIED IDEOGRAPH + {0xE788, 0x8FB7}, //6370 #CJK UNIFIED IDEOGRAPH + {0xE789, 0x8FDA}, //6371 #CJK UNIFIED IDEOGRAPH + {0xE78A, 0x8FE5}, //6372 #CJK UNIFIED IDEOGRAPH + {0xE78B, 0x8FE2}, //6373 #CJK UNIFIED IDEOGRAPH + {0xE78C, 0x8FEA}, //6374 #CJK UNIFIED IDEOGRAPH + {0xE78D, 0x8FEF}, //6375 #CJK UNIFIED IDEOGRAPH + {0xE78E, 0x9087}, //6376 #CJK UNIFIED IDEOGRAPH + {0xE78F, 0x8FF4}, //6377 #CJK UNIFIED IDEOGRAPH + {0xE790, 0x9005}, //6378 #CJK UNIFIED IDEOGRAPH + {0xE791, 0x8FF9}, //6379 #CJK UNIFIED IDEOGRAPH + {0xE792, 0x8FFA}, //6380 #CJK UNIFIED IDEOGRAPH + {0xE793, 0x9011}, //6381 #CJK UNIFIED IDEOGRAPH + {0xE794, 0x9015}, //6382 #CJK UNIFIED IDEOGRAPH + {0xE795, 0x9021}, //6383 #CJK UNIFIED IDEOGRAPH + {0xE796, 0x900D}, //6384 #CJK UNIFIED IDEOGRAPH + {0xE797, 0x901E}, //6385 #CJK UNIFIED IDEOGRAPH + {0xE798, 0x9016}, //6386 #CJK UNIFIED IDEOGRAPH + {0xE799, 0x900B}, //6387 #CJK UNIFIED IDEOGRAPH + {0xE79A, 0x9027}, //6388 #CJK UNIFIED IDEOGRAPH + {0xE79B, 0x9036}, //6389 #CJK UNIFIED IDEOGRAPH + {0xE79C, 0x9035}, //6390 #CJK UNIFIED IDEOGRAPH + {0xE79D, 0x9039}, //6391 #CJK UNIFIED IDEOGRAPH + {0xE79E, 0x8FF8}, //6392 #CJK UNIFIED IDEOGRAPH + {0xE79F, 0x904F}, //6393 #CJK UNIFIED IDEOGRAPH + {0xE7A0, 0x9050}, //6394 #CJK UNIFIED IDEOGRAPH + {0xE7A1, 0x9051}, //6395 #CJK UNIFIED IDEOGRAPH + {0xE7A2, 0x9052}, //6396 #CJK UNIFIED IDEOGRAPH + {0xE7A3, 0x900E}, //6397 #CJK UNIFIED IDEOGRAPH + {0xE7A4, 0x9049}, //6398 #CJK UNIFIED IDEOGRAPH + {0xE7A5, 0x903E}, //6399 #CJK UNIFIED IDEOGRAPH + {0xE7A6, 0x9056}, //6400 #CJK UNIFIED IDEOGRAPH + {0xE7A7, 0x9058}, //6401 #CJK UNIFIED IDEOGRAPH + {0xE7A8, 0x905E}, //6402 #CJK UNIFIED IDEOGRAPH + {0xE7A9, 0x9068}, //6403 #CJK UNIFIED IDEOGRAPH + {0xE7AA, 0x906F}, //6404 #CJK UNIFIED IDEOGRAPH + {0xE7AB, 0x9076}, //6405 #CJK UNIFIED IDEOGRAPH + {0xE7AC, 0x96A8}, //6406 #CJK UNIFIED IDEOGRAPH + {0xE7AD, 0x9072}, //6407 #CJK UNIFIED IDEOGRAPH + {0xE7AE, 0x9082}, //6408 #CJK UNIFIED IDEOGRAPH + {0xE7AF, 0x907D}, //6409 #CJK UNIFIED IDEOGRAPH + {0xE7B0, 0x9081}, //6410 #CJK UNIFIED IDEOGRAPH + {0xE7B1, 0x9080}, //6411 #CJK UNIFIED IDEOGRAPH + {0xE7B2, 0x908A}, //6412 #CJK UNIFIED IDEOGRAPH + {0xE7B3, 0x9089}, //6413 #CJK UNIFIED IDEOGRAPH + {0xE7B4, 0x908F}, //6414 #CJK UNIFIED IDEOGRAPH + {0xE7B5, 0x90A8}, //6415 #CJK UNIFIED IDEOGRAPH + {0xE7B6, 0x90AF}, //6416 #CJK UNIFIED IDEOGRAPH + {0xE7B7, 0x90B1}, //6417 #CJK UNIFIED IDEOGRAPH + {0xE7B8, 0x90B5}, //6418 #CJK UNIFIED IDEOGRAPH + {0xE7B9, 0x90E2}, //6419 #CJK UNIFIED IDEOGRAPH + {0xE7BA, 0x90E4}, //6420 #CJK UNIFIED IDEOGRAPH + {0xE7BB, 0x6248}, //6421 #CJK UNIFIED IDEOGRAPH + {0xE7BC, 0x90DB}, //6422 #CJK UNIFIED IDEOGRAPH + {0xE7BD, 0x9102}, //6423 #CJK UNIFIED IDEOGRAPH + {0xE7BE, 0x9112}, //6424 #CJK UNIFIED IDEOGRAPH + {0xE7BF, 0x9119}, //6425 #CJK UNIFIED IDEOGRAPH + {0xE7C0, 0x9132}, //6426 #CJK UNIFIED IDEOGRAPH + {0xE7C1, 0x9130}, //6427 #CJK UNIFIED IDEOGRAPH + {0xE7C2, 0x914A}, //6428 #CJK UNIFIED IDEOGRAPH + {0xE7C3, 0x9156}, //6429 #CJK UNIFIED IDEOGRAPH + {0xE7C4, 0x9158}, //6430 #CJK UNIFIED IDEOGRAPH + {0xE7C5, 0x9163}, //6431 #CJK UNIFIED IDEOGRAPH + {0xE7C6, 0x9165}, //6432 #CJK UNIFIED IDEOGRAPH + {0xE7C7, 0x9169}, //6433 #CJK UNIFIED IDEOGRAPH + {0xE7C8, 0x9173}, //6434 #CJK UNIFIED IDEOGRAPH + {0xE7C9, 0x9172}, //6435 #CJK UNIFIED IDEOGRAPH + {0xE7CA, 0x918B}, //6436 #CJK UNIFIED IDEOGRAPH + {0xE7CB, 0x9189}, //6437 #CJK UNIFIED IDEOGRAPH + {0xE7CC, 0x9182}, //6438 #CJK UNIFIED IDEOGRAPH + {0xE7CD, 0x91A2}, //6439 #CJK UNIFIED IDEOGRAPH + {0xE7CE, 0x91AB}, //6440 #CJK UNIFIED IDEOGRAPH + {0xE7CF, 0x91AF}, //6441 #CJK UNIFIED IDEOGRAPH + {0xE7D0, 0x91AA}, //6442 #CJK UNIFIED IDEOGRAPH + {0xE7D1, 0x91B5}, //6443 #CJK UNIFIED IDEOGRAPH + {0xE7D2, 0x91B4}, //6444 #CJK UNIFIED IDEOGRAPH + {0xE7D3, 0x91BA}, //6445 #CJK UNIFIED IDEOGRAPH + {0xE7D4, 0x91C0}, //6446 #CJK UNIFIED IDEOGRAPH + {0xE7D5, 0x91C1}, //6447 #CJK UNIFIED IDEOGRAPH + {0xE7D6, 0x91C9}, //6448 #CJK UNIFIED IDEOGRAPH + {0xE7D7, 0x91CB}, //6449 #CJK UNIFIED IDEOGRAPH + {0xE7D8, 0x91D0}, //6450 #CJK UNIFIED IDEOGRAPH + {0xE7D9, 0x91D6}, //6451 #CJK UNIFIED IDEOGRAPH + {0xE7DA, 0x91DF}, //6452 #CJK UNIFIED IDEOGRAPH + {0xE7DB, 0x91E1}, //6453 #CJK UNIFIED IDEOGRAPH + {0xE7DC, 0x91DB}, //6454 #CJK UNIFIED IDEOGRAPH + {0xE7DD, 0x91FC}, //6455 #CJK UNIFIED IDEOGRAPH + {0xE7DE, 0x91F5}, //6456 #CJK UNIFIED IDEOGRAPH + {0xE7DF, 0x91F6}, //6457 #CJK UNIFIED IDEOGRAPH + {0xE7E0, 0x921E}, //6458 #CJK UNIFIED IDEOGRAPH + {0xE7E1, 0x91FF}, //6459 #CJK UNIFIED IDEOGRAPH + {0xE7E2, 0x9214}, //6460 #CJK UNIFIED IDEOGRAPH + {0xE7E3, 0x922C}, //6461 #CJK UNIFIED IDEOGRAPH + {0xE7E4, 0x9215}, //6462 #CJK UNIFIED IDEOGRAPH + {0xE7E5, 0x9211}, //6463 #CJK UNIFIED IDEOGRAPH + {0xE7E6, 0x925E}, //6464 #CJK UNIFIED IDEOGRAPH + {0xE7E7, 0x9257}, //6465 #CJK UNIFIED IDEOGRAPH + {0xE7E8, 0x9245}, //6466 #CJK UNIFIED IDEOGRAPH + {0xE7E9, 0x9249}, //6467 #CJK UNIFIED IDEOGRAPH + {0xE7EA, 0x9264}, //6468 #CJK UNIFIED IDEOGRAPH + {0xE7EB, 0x9248}, //6469 #CJK UNIFIED IDEOGRAPH + {0xE7EC, 0x9295}, //6470 #CJK UNIFIED IDEOGRAPH + {0xE7ED, 0x923F}, //6471 #CJK UNIFIED IDEOGRAPH + {0xE7EE, 0x924B}, //6472 #CJK UNIFIED IDEOGRAPH + {0xE7EF, 0x9250}, //6473 #CJK UNIFIED IDEOGRAPH + {0xE7F0, 0x929C}, //6474 #CJK UNIFIED IDEOGRAPH + {0xE7F1, 0x9296}, //6475 #CJK UNIFIED IDEOGRAPH + {0xE7F2, 0x9293}, //6476 #CJK UNIFIED IDEOGRAPH + {0xE7F3, 0x929B}, //6477 #CJK UNIFIED IDEOGRAPH + {0xE7F4, 0x925A}, //6478 #CJK UNIFIED IDEOGRAPH + {0xE7F5, 0x92CF}, //6479 #CJK UNIFIED IDEOGRAPH + {0xE7F6, 0x92B9}, //6480 #CJK UNIFIED IDEOGRAPH + {0xE7F7, 0x92B7}, //6481 #CJK UNIFIED IDEOGRAPH + {0xE7F8, 0x92E9}, //6482 #CJK UNIFIED IDEOGRAPH + {0xE7F9, 0x930F}, //6483 #CJK UNIFIED IDEOGRAPH + {0xE7FA, 0x92FA}, //6484 #CJK UNIFIED IDEOGRAPH + {0xE7FB, 0x9344}, //6485 #CJK UNIFIED IDEOGRAPH + {0xE7FC, 0x932E}, //6486 #CJK UNIFIED IDEOGRAPH + {0xE840, 0x9319}, //6487 #CJK UNIFIED IDEOGRAPH + {0xE841, 0x9322}, //6488 #CJK UNIFIED IDEOGRAPH + {0xE842, 0x931A}, //6489 #CJK UNIFIED IDEOGRAPH + {0xE843, 0x9323}, //6490 #CJK UNIFIED IDEOGRAPH + {0xE844, 0x933A}, //6491 #CJK UNIFIED IDEOGRAPH + {0xE845, 0x9335}, //6492 #CJK UNIFIED IDEOGRAPH + {0xE846, 0x933B}, //6493 #CJK UNIFIED IDEOGRAPH + {0xE847, 0x935C}, //6494 #CJK UNIFIED IDEOGRAPH + {0xE848, 0x9360}, //6495 #CJK UNIFIED IDEOGRAPH + {0xE849, 0x937C}, //6496 #CJK UNIFIED IDEOGRAPH + {0xE84A, 0x936E}, //6497 #CJK UNIFIED IDEOGRAPH + {0xE84B, 0x9356}, //6498 #CJK UNIFIED IDEOGRAPH + {0xE84C, 0x93B0}, //6499 #CJK UNIFIED IDEOGRAPH + {0xE84D, 0x93AC}, //6500 #CJK UNIFIED IDEOGRAPH + {0xE84E, 0x93AD}, //6501 #CJK UNIFIED IDEOGRAPH + {0xE84F, 0x9394}, //6502 #CJK UNIFIED IDEOGRAPH + {0xE850, 0x93B9}, //6503 #CJK UNIFIED IDEOGRAPH + {0xE851, 0x93D6}, //6504 #CJK UNIFIED IDEOGRAPH + {0xE852, 0x93D7}, //6505 #CJK UNIFIED IDEOGRAPH + {0xE853, 0x93E8}, //6506 #CJK UNIFIED IDEOGRAPH + {0xE854, 0x93E5}, //6507 #CJK UNIFIED IDEOGRAPH + {0xE855, 0x93D8}, //6508 #CJK UNIFIED IDEOGRAPH + {0xE856, 0x93C3}, //6509 #CJK UNIFIED IDEOGRAPH + {0xE857, 0x93DD}, //6510 #CJK UNIFIED IDEOGRAPH + {0xE858, 0x93D0}, //6511 #CJK UNIFIED IDEOGRAPH + {0xE859, 0x93C8}, //6512 #CJK UNIFIED IDEOGRAPH + {0xE85A, 0x93E4}, //6513 #CJK UNIFIED IDEOGRAPH + {0xE85B, 0x941A}, //6514 #CJK UNIFIED IDEOGRAPH + {0xE85C, 0x9414}, //6515 #CJK UNIFIED IDEOGRAPH + {0xE85D, 0x9413}, //6516 #CJK UNIFIED IDEOGRAPH + {0xE85E, 0x9403}, //6517 #CJK UNIFIED IDEOGRAPH + {0xE85F, 0x9407}, //6518 #CJK UNIFIED IDEOGRAPH + {0xE860, 0x9410}, //6519 #CJK UNIFIED IDEOGRAPH + {0xE861, 0x9436}, //6520 #CJK UNIFIED IDEOGRAPH + {0xE862, 0x942B}, //6521 #CJK UNIFIED IDEOGRAPH + {0xE863, 0x9435}, //6522 #CJK UNIFIED IDEOGRAPH + {0xE864, 0x9421}, //6523 #CJK UNIFIED IDEOGRAPH + {0xE865, 0x943A}, //6524 #CJK UNIFIED IDEOGRAPH + {0xE866, 0x9441}, //6525 #CJK UNIFIED IDEOGRAPH + {0xE867, 0x9452}, //6526 #CJK UNIFIED IDEOGRAPH + {0xE868, 0x9444}, //6527 #CJK UNIFIED IDEOGRAPH + {0xE869, 0x945B}, //6528 #CJK UNIFIED IDEOGRAPH + {0xE86A, 0x9460}, //6529 #CJK UNIFIED IDEOGRAPH + {0xE86B, 0x9462}, //6530 #CJK UNIFIED IDEOGRAPH + {0xE86C, 0x945E}, //6531 #CJK UNIFIED IDEOGRAPH + {0xE86D, 0x946A}, //6532 #CJK UNIFIED IDEOGRAPH + {0xE86E, 0x9229}, //6533 #CJK UNIFIED IDEOGRAPH + {0xE86F, 0x9470}, //6534 #CJK UNIFIED IDEOGRAPH + {0xE870, 0x9475}, //6535 #CJK UNIFIED IDEOGRAPH + {0xE871, 0x9477}, //6536 #CJK UNIFIED IDEOGRAPH + {0xE872, 0x947D}, //6537 #CJK UNIFIED IDEOGRAPH + {0xE873, 0x945A}, //6538 #CJK UNIFIED IDEOGRAPH + {0xE874, 0x947C}, //6539 #CJK UNIFIED IDEOGRAPH + {0xE875, 0x947E}, //6540 #CJK UNIFIED IDEOGRAPH + {0xE876, 0x9481}, //6541 #CJK UNIFIED IDEOGRAPH + {0xE877, 0x947F}, //6542 #CJK UNIFIED IDEOGRAPH + {0xE878, 0x9582}, //6543 #CJK UNIFIED IDEOGRAPH + {0xE879, 0x9587}, //6544 #CJK UNIFIED IDEOGRAPH + {0xE87A, 0x958A}, //6545 #CJK UNIFIED IDEOGRAPH + {0xE87B, 0x9594}, //6546 #CJK UNIFIED IDEOGRAPH + {0xE87C, 0x9596}, //6547 #CJK UNIFIED IDEOGRAPH + {0xE87D, 0x9598}, //6548 #CJK UNIFIED IDEOGRAPH + {0xE87E, 0x9599}, //6549 #CJK UNIFIED IDEOGRAPH + {0xE880, 0x95A0}, //6550 #CJK UNIFIED IDEOGRAPH + {0xE881, 0x95A8}, //6551 #CJK UNIFIED IDEOGRAPH + {0xE882, 0x95A7}, //6552 #CJK UNIFIED IDEOGRAPH + {0xE883, 0x95AD}, //6553 #CJK UNIFIED IDEOGRAPH + {0xE884, 0x95BC}, //6554 #CJK UNIFIED IDEOGRAPH + {0xE885, 0x95BB}, //6555 #CJK UNIFIED IDEOGRAPH + {0xE886, 0x95B9}, //6556 #CJK UNIFIED IDEOGRAPH + {0xE887, 0x95BE}, //6557 #CJK UNIFIED IDEOGRAPH + {0xE888, 0x95CA}, //6558 #CJK UNIFIED IDEOGRAPH + {0xE889, 0x6FF6}, //6559 #CJK UNIFIED IDEOGRAPH + {0xE88A, 0x95C3}, //6560 #CJK UNIFIED IDEOGRAPH + {0xE88B, 0x95CD}, //6561 #CJK UNIFIED IDEOGRAPH + {0xE88C, 0x95CC}, //6562 #CJK UNIFIED IDEOGRAPH + {0xE88D, 0x95D5}, //6563 #CJK UNIFIED IDEOGRAPH + {0xE88E, 0x95D4}, //6564 #CJK UNIFIED IDEOGRAPH + {0xE88F, 0x95D6}, //6565 #CJK UNIFIED IDEOGRAPH + {0xE890, 0x95DC}, //6566 #CJK UNIFIED IDEOGRAPH + {0xE891, 0x95E1}, //6567 #CJK UNIFIED IDEOGRAPH + {0xE892, 0x95E5}, //6568 #CJK UNIFIED IDEOGRAPH + {0xE893, 0x95E2}, //6569 #CJK UNIFIED IDEOGRAPH + {0xE894, 0x9621}, //6570 #CJK UNIFIED IDEOGRAPH + {0xE895, 0x9628}, //6571 #CJK UNIFIED IDEOGRAPH + {0xE896, 0x962E}, //6572 #CJK UNIFIED IDEOGRAPH + {0xE897, 0x962F}, //6573 #CJK UNIFIED IDEOGRAPH + {0xE898, 0x9642}, //6574 #CJK UNIFIED IDEOGRAPH + {0xE899, 0x964C}, //6575 #CJK UNIFIED IDEOGRAPH + {0xE89A, 0x964F}, //6576 #CJK UNIFIED IDEOGRAPH + {0xE89B, 0x964B}, //6577 #CJK UNIFIED IDEOGRAPH + {0xE89C, 0x9677}, //6578 #CJK UNIFIED IDEOGRAPH + {0xE89D, 0x965C}, //6579 #CJK UNIFIED IDEOGRAPH + {0xE89E, 0x965E}, //6580 #CJK UNIFIED IDEOGRAPH + {0xE89F, 0x965D}, //6581 #CJK UNIFIED IDEOGRAPH + {0xE8A0, 0x965F}, //6582 #CJK UNIFIED IDEOGRAPH + {0xE8A1, 0x9666}, //6583 #CJK UNIFIED IDEOGRAPH + {0xE8A2, 0x9672}, //6584 #CJK UNIFIED IDEOGRAPH + {0xE8A3, 0x966C}, //6585 #CJK UNIFIED IDEOGRAPH + {0xE8A4, 0x968D}, //6586 #CJK UNIFIED IDEOGRAPH + {0xE8A5, 0x9698}, //6587 #CJK UNIFIED IDEOGRAPH + {0xE8A6, 0x9695}, //6588 #CJK UNIFIED IDEOGRAPH + {0xE8A7, 0x9697}, //6589 #CJK UNIFIED IDEOGRAPH + {0xE8A8, 0x96AA}, //6590 #CJK UNIFIED IDEOGRAPH + {0xE8A9, 0x96A7}, //6591 #CJK UNIFIED IDEOGRAPH + {0xE8AA, 0x96B1}, //6592 #CJK UNIFIED IDEOGRAPH + {0xE8AB, 0x96B2}, //6593 #CJK UNIFIED IDEOGRAPH + {0xE8AC, 0x96B0}, //6594 #CJK UNIFIED IDEOGRAPH + {0xE8AD, 0x96B4}, //6595 #CJK UNIFIED IDEOGRAPH + {0xE8AE, 0x96B6}, //6596 #CJK UNIFIED IDEOGRAPH + {0xE8AF, 0x96B8}, //6597 #CJK UNIFIED IDEOGRAPH + {0xE8B0, 0x96B9}, //6598 #CJK UNIFIED IDEOGRAPH + {0xE8B1, 0x96CE}, //6599 #CJK UNIFIED IDEOGRAPH + {0xE8B2, 0x96CB}, //6600 #CJK UNIFIED IDEOGRAPH + {0xE8B3, 0x96C9}, //6601 #CJK UNIFIED IDEOGRAPH + {0xE8B4, 0x96CD}, //6602 #CJK UNIFIED IDEOGRAPH + {0xE8B5, 0x894D}, //6603 #CJK UNIFIED IDEOGRAPH + {0xE8B6, 0x96DC}, //6604 #CJK UNIFIED IDEOGRAPH + {0xE8B7, 0x970D}, //6605 #CJK UNIFIED IDEOGRAPH + {0xE8B8, 0x96D5}, //6606 #CJK UNIFIED IDEOGRAPH + {0xE8B9, 0x96F9}, //6607 #CJK UNIFIED IDEOGRAPH + {0xE8BA, 0x9704}, //6608 #CJK UNIFIED IDEOGRAPH + {0xE8BB, 0x9706}, //6609 #CJK UNIFIED IDEOGRAPH + {0xE8BC, 0x9708}, //6610 #CJK UNIFIED IDEOGRAPH + {0xE8BD, 0x9713}, //6611 #CJK UNIFIED IDEOGRAPH + {0xE8BE, 0x970E}, //6612 #CJK UNIFIED IDEOGRAPH + {0xE8BF, 0x9711}, //6613 #CJK UNIFIED IDEOGRAPH + {0xE8C0, 0x970F}, //6614 #CJK UNIFIED IDEOGRAPH + {0xE8C1, 0x9716}, //6615 #CJK UNIFIED IDEOGRAPH + {0xE8C2, 0x9719}, //6616 #CJK UNIFIED IDEOGRAPH + {0xE8C3, 0x9724}, //6617 #CJK UNIFIED IDEOGRAPH + {0xE8C4, 0x972A}, //6618 #CJK UNIFIED IDEOGRAPH + {0xE8C5, 0x9730}, //6619 #CJK UNIFIED IDEOGRAPH + {0xE8C6, 0x9739}, //6620 #CJK UNIFIED IDEOGRAPH + {0xE8C7, 0x973D}, //6621 #CJK UNIFIED IDEOGRAPH + {0xE8C8, 0x973E}, //6622 #CJK UNIFIED IDEOGRAPH + {0xE8C9, 0x9744}, //6623 #CJK UNIFIED IDEOGRAPH + {0xE8CA, 0x9746}, //6624 #CJK UNIFIED IDEOGRAPH + {0xE8CB, 0x9748}, //6625 #CJK UNIFIED IDEOGRAPH + {0xE8CC, 0x9742}, //6626 #CJK UNIFIED IDEOGRAPH + {0xE8CD, 0x9749}, //6627 #CJK UNIFIED IDEOGRAPH + {0xE8CE, 0x975C}, //6628 #CJK UNIFIED IDEOGRAPH + {0xE8CF, 0x9760}, //6629 #CJK UNIFIED IDEOGRAPH + {0xE8D0, 0x9764}, //6630 #CJK UNIFIED IDEOGRAPH + {0xE8D1, 0x9766}, //6631 #CJK UNIFIED IDEOGRAPH + {0xE8D2, 0x9768}, //6632 #CJK UNIFIED IDEOGRAPH + {0xE8D3, 0x52D2}, //6633 #CJK UNIFIED IDEOGRAPH + {0xE8D4, 0x976B}, //6634 #CJK UNIFIED IDEOGRAPH + {0xE8D5, 0x9771}, //6635 #CJK UNIFIED IDEOGRAPH + {0xE8D6, 0x9779}, //6636 #CJK UNIFIED IDEOGRAPH + {0xE8D7, 0x9785}, //6637 #CJK UNIFIED IDEOGRAPH + {0xE8D8, 0x977C}, //6638 #CJK UNIFIED IDEOGRAPH + {0xE8D9, 0x9781}, //6639 #CJK UNIFIED IDEOGRAPH + {0xE8DA, 0x977A}, //6640 #CJK UNIFIED IDEOGRAPH + {0xE8DB, 0x9786}, //6641 #CJK UNIFIED IDEOGRAPH + {0xE8DC, 0x978B}, //6642 #CJK UNIFIED IDEOGRAPH + {0xE8DD, 0x978F}, //6643 #CJK UNIFIED IDEOGRAPH + {0xE8DE, 0x9790}, //6644 #CJK UNIFIED IDEOGRAPH + {0xE8DF, 0x979C}, //6645 #CJK UNIFIED IDEOGRAPH + {0xE8E0, 0x97A8}, //6646 #CJK UNIFIED IDEOGRAPH + {0xE8E1, 0x97A6}, //6647 #CJK UNIFIED IDEOGRAPH + {0xE8E2, 0x97A3}, //6648 #CJK UNIFIED IDEOGRAPH + {0xE8E3, 0x97B3}, //6649 #CJK UNIFIED IDEOGRAPH + {0xE8E4, 0x97B4}, //6650 #CJK UNIFIED IDEOGRAPH + {0xE8E5, 0x97C3}, //6651 #CJK UNIFIED IDEOGRAPH + {0xE8E6, 0x97C6}, //6652 #CJK UNIFIED IDEOGRAPH + {0xE8E7, 0x97C8}, //6653 #CJK UNIFIED IDEOGRAPH + {0xE8E8, 0x97CB}, //6654 #CJK UNIFIED IDEOGRAPH + {0xE8E9, 0x97DC}, //6655 #CJK UNIFIED IDEOGRAPH + {0xE8EA, 0x97ED}, //6656 #CJK UNIFIED IDEOGRAPH + {0xE8EB, 0x9F4F}, //6657 #CJK UNIFIED IDEOGRAPH + {0xE8EC, 0x97F2}, //6658 #CJK UNIFIED IDEOGRAPH + {0xE8ED, 0x7ADF}, //6659 #CJK UNIFIED IDEOGRAPH + {0xE8EE, 0x97F6}, //6660 #CJK UNIFIED IDEOGRAPH + {0xE8EF, 0x97F5}, //6661 #CJK UNIFIED IDEOGRAPH + {0xE8F0, 0x980F}, //6662 #CJK UNIFIED IDEOGRAPH + {0xE8F1, 0x980C}, //6663 #CJK UNIFIED IDEOGRAPH + {0xE8F2, 0x9838}, //6664 #CJK UNIFIED IDEOGRAPH + {0xE8F3, 0x9824}, //6665 #CJK UNIFIED IDEOGRAPH + {0xE8F4, 0x9821}, //6666 #CJK UNIFIED IDEOGRAPH + {0xE8F5, 0x9837}, //6667 #CJK UNIFIED IDEOGRAPH + {0xE8F6, 0x983D}, //6668 #CJK UNIFIED IDEOGRAPH + {0xE8F7, 0x9846}, //6669 #CJK UNIFIED IDEOGRAPH + {0xE8F8, 0x984F}, //6670 #CJK UNIFIED IDEOGRAPH + {0xE8F9, 0x984B}, //6671 #CJK UNIFIED IDEOGRAPH + {0xE8FA, 0x986B}, //6672 #CJK UNIFIED IDEOGRAPH + {0xE8FB, 0x986F}, //6673 #CJK UNIFIED IDEOGRAPH + {0xE8FC, 0x9870}, //6674 #CJK UNIFIED IDEOGRAPH + {0xE940, 0x9871}, //6675 #CJK UNIFIED IDEOGRAPH + {0xE941, 0x9874}, //6676 #CJK UNIFIED IDEOGRAPH + {0xE942, 0x9873}, //6677 #CJK UNIFIED IDEOGRAPH + {0xE943, 0x98AA}, //6678 #CJK UNIFIED IDEOGRAPH + {0xE944, 0x98AF}, //6679 #CJK UNIFIED IDEOGRAPH + {0xE945, 0x98B1}, //6680 #CJK UNIFIED IDEOGRAPH + {0xE946, 0x98B6}, //6681 #CJK UNIFIED IDEOGRAPH + {0xE947, 0x98C4}, //6682 #CJK UNIFIED IDEOGRAPH + {0xE948, 0x98C3}, //6683 #CJK UNIFIED IDEOGRAPH + {0xE949, 0x98C6}, //6684 #CJK UNIFIED IDEOGRAPH + {0xE94A, 0x98E9}, //6685 #CJK UNIFIED IDEOGRAPH + {0xE94B, 0x98EB}, //6686 #CJK UNIFIED IDEOGRAPH + {0xE94C, 0x9903}, //6687 #CJK UNIFIED IDEOGRAPH + {0xE94D, 0x9909}, //6688 #CJK UNIFIED IDEOGRAPH + {0xE94E, 0x9912}, //6689 #CJK UNIFIED IDEOGRAPH + {0xE94F, 0x9914}, //6690 #CJK UNIFIED IDEOGRAPH + {0xE950, 0x9918}, //6691 #CJK UNIFIED IDEOGRAPH + {0xE951, 0x9921}, //6692 #CJK UNIFIED IDEOGRAPH + {0xE952, 0x991D}, //6693 #CJK UNIFIED IDEOGRAPH + {0xE953, 0x991E}, //6694 #CJK UNIFIED IDEOGRAPH + {0xE954, 0x9924}, //6695 #CJK UNIFIED IDEOGRAPH + {0xE955, 0x9920}, //6696 #CJK UNIFIED IDEOGRAPH + {0xE956, 0x992C}, //6697 #CJK UNIFIED IDEOGRAPH + {0xE957, 0x992E}, //6698 #CJK UNIFIED IDEOGRAPH + {0xE958, 0x993D}, //6699 #CJK UNIFIED IDEOGRAPH + {0xE959, 0x993E}, //6700 #CJK UNIFIED IDEOGRAPH + {0xE95A, 0x9942}, //6701 #CJK UNIFIED IDEOGRAPH + {0xE95B, 0x9949}, //6702 #CJK UNIFIED IDEOGRAPH + {0xE95C, 0x9945}, //6703 #CJK UNIFIED IDEOGRAPH + {0xE95D, 0x9950}, //6704 #CJK UNIFIED IDEOGRAPH + {0xE95E, 0x994B}, //6705 #CJK UNIFIED IDEOGRAPH + {0xE95F, 0x9951}, //6706 #CJK UNIFIED IDEOGRAPH + {0xE960, 0x9952}, //6707 #CJK UNIFIED IDEOGRAPH + {0xE961, 0x994C}, //6708 #CJK UNIFIED IDEOGRAPH + {0xE962, 0x9955}, //6709 #CJK UNIFIED IDEOGRAPH + {0xE963, 0x9997}, //6710 #CJK UNIFIED IDEOGRAPH + {0xE964, 0x9998}, //6711 #CJK UNIFIED IDEOGRAPH + {0xE965, 0x99A5}, //6712 #CJK UNIFIED IDEOGRAPH + {0xE966, 0x99AD}, //6713 #CJK UNIFIED IDEOGRAPH + {0xE967, 0x99AE}, //6714 #CJK UNIFIED IDEOGRAPH + {0xE968, 0x99BC}, //6715 #CJK UNIFIED IDEOGRAPH + {0xE969, 0x99DF}, //6716 #CJK UNIFIED IDEOGRAPH + {0xE96A, 0x99DB}, //6717 #CJK UNIFIED IDEOGRAPH + {0xE96B, 0x99DD}, //6718 #CJK UNIFIED IDEOGRAPH + {0xE96C, 0x99D8}, //6719 #CJK UNIFIED IDEOGRAPH + {0xE96D, 0x99D1}, //6720 #CJK UNIFIED IDEOGRAPH + {0xE96E, 0x99ED}, //6721 #CJK UNIFIED IDEOGRAPH + {0xE96F, 0x99EE}, //6722 #CJK UNIFIED IDEOGRAPH + {0xE970, 0x99F1}, //6723 #CJK UNIFIED IDEOGRAPH + {0xE971, 0x99F2}, //6724 #CJK UNIFIED IDEOGRAPH + {0xE972, 0x99FB}, //6725 #CJK UNIFIED IDEOGRAPH + {0xE973, 0x99F8}, //6726 #CJK UNIFIED IDEOGRAPH + {0xE974, 0x9A01}, //6727 #CJK UNIFIED IDEOGRAPH + {0xE975, 0x9A0F}, //6728 #CJK UNIFIED IDEOGRAPH + {0xE976, 0x9A05}, //6729 #CJK UNIFIED IDEOGRAPH + {0xE977, 0x99E2}, //6730 #CJK UNIFIED IDEOGRAPH + {0xE978, 0x9A19}, //6731 #CJK UNIFIED IDEOGRAPH + {0xE979, 0x9A2B}, //6732 #CJK UNIFIED IDEOGRAPH + {0xE97A, 0x9A37}, //6733 #CJK UNIFIED IDEOGRAPH + {0xE97B, 0x9A45}, //6734 #CJK UNIFIED IDEOGRAPH + {0xE97C, 0x9A42}, //6735 #CJK UNIFIED IDEOGRAPH + {0xE97D, 0x9A40}, //6736 #CJK UNIFIED IDEOGRAPH + {0xE97E, 0x9A43}, //6737 #CJK UNIFIED IDEOGRAPH + {0xE980, 0x9A3E}, //6738 #CJK UNIFIED IDEOGRAPH + {0xE981, 0x9A55}, //6739 #CJK UNIFIED IDEOGRAPH + {0xE982, 0x9A4D}, //6740 #CJK UNIFIED IDEOGRAPH + {0xE983, 0x9A5B}, //6741 #CJK UNIFIED IDEOGRAPH + {0xE984, 0x9A57}, //6742 #CJK UNIFIED IDEOGRAPH + {0xE985, 0x9A5F}, //6743 #CJK UNIFIED IDEOGRAPH + {0xE986, 0x9A62}, //6744 #CJK UNIFIED IDEOGRAPH + {0xE987, 0x9A65}, //6745 #CJK UNIFIED IDEOGRAPH + {0xE988, 0x9A64}, //6746 #CJK UNIFIED IDEOGRAPH + {0xE989, 0x9A69}, //6747 #CJK UNIFIED IDEOGRAPH + {0xE98A, 0x9A6B}, //6748 #CJK UNIFIED IDEOGRAPH + {0xE98B, 0x9A6A}, //6749 #CJK UNIFIED IDEOGRAPH + {0xE98C, 0x9AAD}, //6750 #CJK UNIFIED IDEOGRAPH + {0xE98D, 0x9AB0}, //6751 #CJK UNIFIED IDEOGRAPH + {0xE98E, 0x9ABC}, //6752 #CJK UNIFIED IDEOGRAPH + {0xE98F, 0x9AC0}, //6753 #CJK UNIFIED IDEOGRAPH + {0xE990, 0x9ACF}, //6754 #CJK UNIFIED IDEOGRAPH + {0xE991, 0x9AD1}, //6755 #CJK UNIFIED IDEOGRAPH + {0xE992, 0x9AD3}, //6756 #CJK UNIFIED IDEOGRAPH + {0xE993, 0x9AD4}, //6757 #CJK UNIFIED IDEOGRAPH + {0xE994, 0x9ADE}, //6758 #CJK UNIFIED IDEOGRAPH + {0xE995, 0x9ADF}, //6759 #CJK UNIFIED IDEOGRAPH + {0xE996, 0x9AE2}, //6760 #CJK UNIFIED IDEOGRAPH + {0xE997, 0x9AE3}, //6761 #CJK UNIFIED IDEOGRAPH + {0xE998, 0x9AE6}, //6762 #CJK UNIFIED IDEOGRAPH + {0xE999, 0x9AEF}, //6763 #CJK UNIFIED IDEOGRAPH + {0xE99A, 0x9AEB}, //6764 #CJK UNIFIED IDEOGRAPH + {0xE99B, 0x9AEE}, //6765 #CJK UNIFIED IDEOGRAPH + {0xE99C, 0x9AF4}, //6766 #CJK UNIFIED IDEOGRAPH + {0xE99D, 0x9AF1}, //6767 #CJK UNIFIED IDEOGRAPH + {0xE99E, 0x9AF7}, //6768 #CJK UNIFIED IDEOGRAPH + {0xE99F, 0x9AFB}, //6769 #CJK UNIFIED IDEOGRAPH + {0xE9A0, 0x9B06}, //6770 #CJK UNIFIED IDEOGRAPH + {0xE9A1, 0x9B18}, //6771 #CJK UNIFIED IDEOGRAPH + {0xE9A2, 0x9B1A}, //6772 #CJK UNIFIED IDEOGRAPH + {0xE9A3, 0x9B1F}, //6773 #CJK UNIFIED IDEOGRAPH + {0xE9A4, 0x9B22}, //6774 #CJK UNIFIED IDEOGRAPH + {0xE9A5, 0x9B23}, //6775 #CJK UNIFIED IDEOGRAPH + {0xE9A6, 0x9B25}, //6776 #CJK UNIFIED IDEOGRAPH + {0xE9A7, 0x9B27}, //6777 #CJK UNIFIED IDEOGRAPH + {0xE9A8, 0x9B28}, //6778 #CJK UNIFIED IDEOGRAPH + {0xE9A9, 0x9B29}, //6779 #CJK UNIFIED IDEOGRAPH + {0xE9AA, 0x9B2A}, //6780 #CJK UNIFIED IDEOGRAPH + {0xE9AB, 0x9B2E}, //6781 #CJK UNIFIED IDEOGRAPH + {0xE9AC, 0x9B2F}, //6782 #CJK UNIFIED IDEOGRAPH + {0xE9AD, 0x9B32}, //6783 #CJK UNIFIED IDEOGRAPH + {0xE9AE, 0x9B44}, //6784 #CJK UNIFIED IDEOGRAPH + {0xE9AF, 0x9B43}, //6785 #CJK UNIFIED IDEOGRAPH + {0xE9B0, 0x9B4F}, //6786 #CJK UNIFIED IDEOGRAPH + {0xE9B1, 0x9B4D}, //6787 #CJK UNIFIED IDEOGRAPH + {0xE9B2, 0x9B4E}, //6788 #CJK UNIFIED IDEOGRAPH + {0xE9B3, 0x9B51}, //6789 #CJK UNIFIED IDEOGRAPH + {0xE9B4, 0x9B58}, //6790 #CJK UNIFIED IDEOGRAPH + {0xE9B5, 0x9B74}, //6791 #CJK UNIFIED IDEOGRAPH + {0xE9B6, 0x9B93}, //6792 #CJK UNIFIED IDEOGRAPH + {0xE9B7, 0x9B83}, //6793 #CJK UNIFIED IDEOGRAPH + {0xE9B8, 0x9B91}, //6794 #CJK UNIFIED IDEOGRAPH + {0xE9B9, 0x9B96}, //6795 #CJK UNIFIED IDEOGRAPH + {0xE9BA, 0x9B97}, //6796 #CJK UNIFIED IDEOGRAPH + {0xE9BB, 0x9B9F}, //6797 #CJK UNIFIED IDEOGRAPH + {0xE9BC, 0x9BA0}, //6798 #CJK UNIFIED IDEOGRAPH + {0xE9BD, 0x9BA8}, //6799 #CJK UNIFIED IDEOGRAPH + {0xE9BE, 0x9BB4}, //6800 #CJK UNIFIED IDEOGRAPH + {0xE9BF, 0x9BC0}, //6801 #CJK UNIFIED IDEOGRAPH + {0xE9C0, 0x9BCA}, //6802 #CJK UNIFIED IDEOGRAPH + {0xE9C1, 0x9BB9}, //6803 #CJK UNIFIED IDEOGRAPH + {0xE9C2, 0x9BC6}, //6804 #CJK UNIFIED IDEOGRAPH + {0xE9C3, 0x9BCF}, //6805 #CJK UNIFIED IDEOGRAPH + {0xE9C4, 0x9BD1}, //6806 #CJK UNIFIED IDEOGRAPH + {0xE9C5, 0x9BD2}, //6807 #CJK UNIFIED IDEOGRAPH + {0xE9C6, 0x9BE3}, //6808 #CJK UNIFIED IDEOGRAPH + {0xE9C7, 0x9BE2}, //6809 #CJK UNIFIED IDEOGRAPH + {0xE9C8, 0x9BE4}, //6810 #CJK UNIFIED IDEOGRAPH + {0xE9C9, 0x9BD4}, //6811 #CJK UNIFIED IDEOGRAPH + {0xE9CA, 0x9BE1}, //6812 #CJK UNIFIED IDEOGRAPH + {0xE9CB, 0x9C3A}, //6813 #CJK UNIFIED IDEOGRAPH + {0xE9CC, 0x9BF2}, //6814 #CJK UNIFIED IDEOGRAPH + {0xE9CD, 0x9BF1}, //6815 #CJK UNIFIED IDEOGRAPH + {0xE9CE, 0x9BF0}, //6816 #CJK UNIFIED IDEOGRAPH + {0xE9CF, 0x9C15}, //6817 #CJK UNIFIED IDEOGRAPH + {0xE9D0, 0x9C14}, //6818 #CJK UNIFIED IDEOGRAPH + {0xE9D1, 0x9C09}, //6819 #CJK UNIFIED IDEOGRAPH + {0xE9D2, 0x9C13}, //6820 #CJK UNIFIED IDEOGRAPH + {0xE9D3, 0x9C0C}, //6821 #CJK UNIFIED IDEOGRAPH + {0xE9D4, 0x9C06}, //6822 #CJK UNIFIED IDEOGRAPH + {0xE9D5, 0x9C08}, //6823 #CJK UNIFIED IDEOGRAPH + {0xE9D6, 0x9C12}, //6824 #CJK UNIFIED IDEOGRAPH + {0xE9D7, 0x9C0A}, //6825 #CJK UNIFIED IDEOGRAPH + {0xE9D8, 0x9C04}, //6826 #CJK UNIFIED IDEOGRAPH + {0xE9D9, 0x9C2E}, //6827 #CJK UNIFIED IDEOGRAPH + {0xE9DA, 0x9C1B}, //6828 #CJK UNIFIED IDEOGRAPH + {0xE9DB, 0x9C25}, //6829 #CJK UNIFIED IDEOGRAPH + {0xE9DC, 0x9C24}, //6830 #CJK UNIFIED IDEOGRAPH + {0xE9DD, 0x9C21}, //6831 #CJK UNIFIED IDEOGRAPH + {0xE9DE, 0x9C30}, //6832 #CJK UNIFIED IDEOGRAPH + {0xE9DF, 0x9C47}, //6833 #CJK UNIFIED IDEOGRAPH + {0xE9E0, 0x9C32}, //6834 #CJK UNIFIED IDEOGRAPH + {0xE9E1, 0x9C46}, //6835 #CJK UNIFIED IDEOGRAPH + {0xE9E2, 0x9C3E}, //6836 #CJK UNIFIED IDEOGRAPH + {0xE9E3, 0x9C5A}, //6837 #CJK UNIFIED IDEOGRAPH + {0xE9E4, 0x9C60}, //6838 #CJK UNIFIED IDEOGRAPH + {0xE9E5, 0x9C67}, //6839 #CJK UNIFIED IDEOGRAPH + {0xE9E6, 0x9C76}, //6840 #CJK UNIFIED IDEOGRAPH + {0xE9E7, 0x9C78}, //6841 #CJK UNIFIED IDEOGRAPH + {0xE9E8, 0x9CE7}, //6842 #CJK UNIFIED IDEOGRAPH + {0xE9E9, 0x9CEC}, //6843 #CJK UNIFIED IDEOGRAPH + {0xE9EA, 0x9CF0}, //6844 #CJK UNIFIED IDEOGRAPH + {0xE9EB, 0x9D09}, //6845 #CJK UNIFIED IDEOGRAPH + {0xE9EC, 0x9D08}, //6846 #CJK UNIFIED IDEOGRAPH + {0xE9ED, 0x9CEB}, //6847 #CJK UNIFIED IDEOGRAPH + {0xE9EE, 0x9D03}, //6848 #CJK UNIFIED IDEOGRAPH + {0xE9EF, 0x9D06}, //6849 #CJK UNIFIED IDEOGRAPH + {0xE9F0, 0x9D2A}, //6850 #CJK UNIFIED IDEOGRAPH + {0xE9F1, 0x9D26}, //6851 #CJK UNIFIED IDEOGRAPH + {0xE9F2, 0x9DAF}, //6852 #CJK UNIFIED IDEOGRAPH + {0xE9F3, 0x9D23}, //6853 #CJK UNIFIED IDEOGRAPH + {0xE9F4, 0x9D1F}, //6854 #CJK UNIFIED IDEOGRAPH + {0xE9F5, 0x9D44}, //6855 #CJK UNIFIED IDEOGRAPH + {0xE9F6, 0x9D15}, //6856 #CJK UNIFIED IDEOGRAPH + {0xE9F7, 0x9D12}, //6857 #CJK UNIFIED IDEOGRAPH + {0xE9F8, 0x9D41}, //6858 #CJK UNIFIED IDEOGRAPH + {0xE9F9, 0x9D3F}, //6859 #CJK UNIFIED IDEOGRAPH + {0xE9FA, 0x9D3E}, //6860 #CJK UNIFIED IDEOGRAPH + {0xE9FB, 0x9D46}, //6861 #CJK UNIFIED IDEOGRAPH + {0xE9FC, 0x9D48}, //6862 #CJK UNIFIED IDEOGRAPH + {0xEA40, 0x9D5D}, //6863 #CJK UNIFIED IDEOGRAPH + {0xEA41, 0x9D5E}, //6864 #CJK UNIFIED IDEOGRAPH + {0xEA42, 0x9D64}, //6865 #CJK UNIFIED IDEOGRAPH + {0xEA43, 0x9D51}, //6866 #CJK UNIFIED IDEOGRAPH + {0xEA44, 0x9D50}, //6867 #CJK UNIFIED IDEOGRAPH + {0xEA45, 0x9D59}, //6868 #CJK UNIFIED IDEOGRAPH + {0xEA46, 0x9D72}, //6869 #CJK UNIFIED IDEOGRAPH + {0xEA47, 0x9D89}, //6870 #CJK UNIFIED IDEOGRAPH + {0xEA48, 0x9D87}, //6871 #CJK UNIFIED IDEOGRAPH + {0xEA49, 0x9DAB}, //6872 #CJK UNIFIED IDEOGRAPH + {0xEA4A, 0x9D6F}, //6873 #CJK UNIFIED IDEOGRAPH + {0xEA4B, 0x9D7A}, //6874 #CJK UNIFIED IDEOGRAPH + {0xEA4C, 0x9D9A}, //6875 #CJK UNIFIED IDEOGRAPH + {0xEA4D, 0x9DA4}, //6876 #CJK UNIFIED IDEOGRAPH + {0xEA4E, 0x9DA9}, //6877 #CJK UNIFIED IDEOGRAPH + {0xEA4F, 0x9DB2}, //6878 #CJK UNIFIED IDEOGRAPH + {0xEA50, 0x9DC4}, //6879 #CJK UNIFIED IDEOGRAPH + {0xEA51, 0x9DC1}, //6880 #CJK UNIFIED IDEOGRAPH + {0xEA52, 0x9DBB}, //6881 #CJK UNIFIED IDEOGRAPH + {0xEA53, 0x9DB8}, //6882 #CJK UNIFIED IDEOGRAPH + {0xEA54, 0x9DBA}, //6883 #CJK UNIFIED IDEOGRAPH + {0xEA55, 0x9DC6}, //6884 #CJK UNIFIED IDEOGRAPH + {0xEA56, 0x9DCF}, //6885 #CJK UNIFIED IDEOGRAPH + {0xEA57, 0x9DC2}, //6886 #CJK UNIFIED IDEOGRAPH + {0xEA58, 0x9DD9}, //6887 #CJK UNIFIED IDEOGRAPH + {0xEA59, 0x9DD3}, //6888 #CJK UNIFIED IDEOGRAPH + {0xEA5A, 0x9DF8}, //6889 #CJK UNIFIED IDEOGRAPH + {0xEA5B, 0x9DE6}, //6890 #CJK UNIFIED IDEOGRAPH + {0xEA5C, 0x9DED}, //6891 #CJK UNIFIED IDEOGRAPH + {0xEA5D, 0x9DEF}, //6892 #CJK UNIFIED IDEOGRAPH + {0xEA5E, 0x9DFD}, //6893 #CJK UNIFIED IDEOGRAPH + {0xEA5F, 0x9E1A}, //6894 #CJK UNIFIED IDEOGRAPH + {0xEA60, 0x9E1B}, //6895 #CJK UNIFIED IDEOGRAPH + {0xEA61, 0x9E1E}, //6896 #CJK UNIFIED IDEOGRAPH + {0xEA62, 0x9E75}, //6897 #CJK UNIFIED IDEOGRAPH + {0xEA63, 0x9E79}, //6898 #CJK UNIFIED IDEOGRAPH + {0xEA64, 0x9E7D}, //6899 #CJK UNIFIED IDEOGRAPH + {0xEA65, 0x9E81}, //6900 #CJK UNIFIED IDEOGRAPH + {0xEA66, 0x9E88}, //6901 #CJK UNIFIED IDEOGRAPH + {0xEA67, 0x9E8B}, //6902 #CJK UNIFIED IDEOGRAPH + {0xEA68, 0x9E8C}, //6903 #CJK UNIFIED IDEOGRAPH + {0xEA69, 0x9E92}, //6904 #CJK UNIFIED IDEOGRAPH + {0xEA6A, 0x9E95}, //6905 #CJK UNIFIED IDEOGRAPH + {0xEA6B, 0x9E91}, //6906 #CJK UNIFIED IDEOGRAPH + {0xEA6C, 0x9E9D}, //6907 #CJK UNIFIED IDEOGRAPH + {0xEA6D, 0x9EA5}, //6908 #CJK UNIFIED IDEOGRAPH + {0xEA6E, 0x9EA9}, //6909 #CJK UNIFIED IDEOGRAPH + {0xEA6F, 0x9EB8}, //6910 #CJK UNIFIED IDEOGRAPH + {0xEA70, 0x9EAA}, //6911 #CJK UNIFIED IDEOGRAPH + {0xEA71, 0x9EAD}, //6912 #CJK UNIFIED IDEOGRAPH + {0xEA72, 0x9761}, //6913 #CJK UNIFIED IDEOGRAPH + {0xEA73, 0x9ECC}, //6914 #CJK UNIFIED IDEOGRAPH + {0xEA74, 0x9ECE}, //6915 #CJK UNIFIED IDEOGRAPH + {0xEA75, 0x9ECF}, //6916 #CJK UNIFIED IDEOGRAPH + {0xEA76, 0x9ED0}, //6917 #CJK UNIFIED IDEOGRAPH + {0xEA77, 0x9ED4}, //6918 #CJK UNIFIED IDEOGRAPH + {0xEA78, 0x9EDC}, //6919 #CJK UNIFIED IDEOGRAPH + {0xEA79, 0x9EDE}, //6920 #CJK UNIFIED IDEOGRAPH + {0xEA7A, 0x9EDD}, //6921 #CJK UNIFIED IDEOGRAPH + {0xEA7B, 0x9EE0}, //6922 #CJK UNIFIED IDEOGRAPH + {0xEA7C, 0x9EE5}, //6923 #CJK UNIFIED IDEOGRAPH + {0xEA7D, 0x9EE8}, //6924 #CJK UNIFIED IDEOGRAPH + {0xEA7E, 0x9EEF}, //6925 #CJK UNIFIED IDEOGRAPH + {0xEA80, 0x9EF4}, //6926 #CJK UNIFIED IDEOGRAPH + {0xEA81, 0x9EF6}, //6927 #CJK UNIFIED IDEOGRAPH + {0xEA82, 0x9EF7}, //6928 #CJK UNIFIED IDEOGRAPH + {0xEA83, 0x9EF9}, //6929 #CJK UNIFIED IDEOGRAPH + {0xEA84, 0x9EFB}, //6930 #CJK UNIFIED IDEOGRAPH + {0xEA85, 0x9EFC}, //6931 #CJK UNIFIED IDEOGRAPH + {0xEA86, 0x9EFD}, //6932 #CJK UNIFIED IDEOGRAPH + {0xEA87, 0x9F07}, //6933 #CJK UNIFIED IDEOGRAPH + {0xEA88, 0x9F08}, //6934 #CJK UNIFIED IDEOGRAPH + {0xEA89, 0x76B7}, //6935 #CJK UNIFIED IDEOGRAPH + {0xEA8A, 0x9F15}, //6936 #CJK UNIFIED IDEOGRAPH + {0xEA8B, 0x9F21}, //6937 #CJK UNIFIED IDEOGRAPH + {0xEA8C, 0x9F2C}, //6938 #CJK UNIFIED IDEOGRAPH + {0xEA8D, 0x9F3E}, //6939 #CJK UNIFIED IDEOGRAPH + {0xEA8E, 0x9F4A}, //6940 #CJK UNIFIED IDEOGRAPH + {0xEA8F, 0x9F52}, //6941 #CJK UNIFIED IDEOGRAPH + {0xEA90, 0x9F54}, //6942 #CJK UNIFIED IDEOGRAPH + {0xEA91, 0x9F63}, //6943 #CJK UNIFIED IDEOGRAPH + {0xEA92, 0x9F5F}, //6944 #CJK UNIFIED IDEOGRAPH + {0xEA93, 0x9F60}, //6945 #CJK UNIFIED IDEOGRAPH + {0xEA94, 0x9F61}, //6946 #CJK UNIFIED IDEOGRAPH + {0xEA95, 0x9F66}, //6947 #CJK UNIFIED IDEOGRAPH + {0xEA96, 0x9F67}, //6948 #CJK UNIFIED IDEOGRAPH + {0xEA97, 0x9F6C}, //6949 #CJK UNIFIED IDEOGRAPH + {0xEA98, 0x9F6A}, //6950 #CJK UNIFIED IDEOGRAPH + {0xEA99, 0x9F77}, //6951 #CJK UNIFIED IDEOGRAPH + {0xEA9A, 0x9F72}, //6952 #CJK UNIFIED IDEOGRAPH + {0xEA9B, 0x9F76}, //6953 #CJK UNIFIED IDEOGRAPH + {0xEA9C, 0x9F95}, //6954 #CJK UNIFIED IDEOGRAPH + {0xEA9D, 0x9F9C}, //6955 #CJK UNIFIED IDEOGRAPH + {0xEA9E, 0x9FA0}, //6956 #CJK UNIFIED IDEOGRAPH + {0xEA9F, 0x582F}, //6957 #CJK UNIFIED IDEOGRAPH + {0xEAA0, 0x69C7}, //6958 #CJK UNIFIED IDEOGRAPH + {0xEAA1, 0x9059}, //6959 #CJK UNIFIED IDEOGRAPH + {0xEAA2, 0x7464}, //6960 #CJK UNIFIED IDEOGRAPH + {0xEAA3, 0x51DC}, //6961 #CJK UNIFIED IDEOGRAPH + {0xEAA4, 0x7199}, //6962 #CJK UNIFIED IDEOGRAPH + {0xED40, 0x7E8A}, //6963 #CJK UNIFIED IDEOGRAPH + {0xED41, 0x891C}, //6964 #CJK UNIFIED IDEOGRAPH + {0xED42, 0x9348}, //6965 #CJK UNIFIED IDEOGRAPH + {0xED43, 0x9288}, //6966 #CJK UNIFIED IDEOGRAPH + {0xED44, 0x84DC}, //6967 #CJK UNIFIED IDEOGRAPH + {0xED45, 0x4FC9}, //6968 #CJK UNIFIED IDEOGRAPH + {0xED46, 0x70BB}, //6969 #CJK UNIFIED IDEOGRAPH + {0xED47, 0x6631}, //6970 #CJK UNIFIED IDEOGRAPH + {0xED48, 0x68C8}, //6971 #CJK UNIFIED IDEOGRAPH + {0xED49, 0x92F9}, //6972 #CJK UNIFIED IDEOGRAPH + {0xED4A, 0x66FB}, //6973 #CJK UNIFIED IDEOGRAPH + {0xED4B, 0x5F45}, //6974 #CJK UNIFIED IDEOGRAPH + {0xED4C, 0x4E28}, //6975 #CJK UNIFIED IDEOGRAPH + {0xED4D, 0x4EE1}, //6976 #CJK UNIFIED IDEOGRAPH + {0xED4E, 0x4EFC}, //6977 #CJK UNIFIED IDEOGRAPH + {0xED4F, 0x4F00}, //6978 #CJK UNIFIED IDEOGRAPH + {0xED50, 0x4F03}, //6979 #CJK UNIFIED IDEOGRAPH + {0xED51, 0x4F39}, //6980 #CJK UNIFIED IDEOGRAPH + {0xED52, 0x4F56}, //6981 #CJK UNIFIED IDEOGRAPH + {0xED53, 0x4F92}, //6982 #CJK UNIFIED IDEOGRAPH + {0xED54, 0x4F8A}, //6983 #CJK UNIFIED IDEOGRAPH + {0xED55, 0x4F9A}, //6984 #CJK UNIFIED IDEOGRAPH + {0xED56, 0x4F94}, //6985 #CJK UNIFIED IDEOGRAPH + {0xED57, 0x4FCD}, //6986 #CJK UNIFIED IDEOGRAPH + {0xED58, 0x5040}, //6987 #CJK UNIFIED IDEOGRAPH + {0xED59, 0x5022}, //6988 #CJK UNIFIED IDEOGRAPH + {0xED5A, 0x4FFF}, //6989 #CJK UNIFIED IDEOGRAPH + {0xED5B, 0x501E}, //6990 #CJK UNIFIED IDEOGRAPH + {0xED5C, 0x5046}, //6991 #CJK UNIFIED IDEOGRAPH + {0xED5D, 0x5070}, //6992 #CJK UNIFIED IDEOGRAPH + {0xED5E, 0x5042}, //6993 #CJK UNIFIED IDEOGRAPH + {0xED5F, 0x5094}, //6994 #CJK UNIFIED IDEOGRAPH + {0xED60, 0x50F4}, //6995 #CJK UNIFIED IDEOGRAPH + {0xED61, 0x50D8}, //6996 #CJK UNIFIED IDEOGRAPH + {0xED62, 0x514A}, //6997 #CJK UNIFIED IDEOGRAPH + {0xED63, 0x5164}, //6998 #CJK UNIFIED IDEOGRAPH + {0xED64, 0x519D}, //6999 #CJK UNIFIED IDEOGRAPH + {0xED65, 0x51BE}, //7000 #CJK UNIFIED IDEOGRAPH + {0xED66, 0x51EC}, //7001 #CJK UNIFIED IDEOGRAPH + {0xED67, 0x5215}, //7002 #CJK UNIFIED IDEOGRAPH + {0xED68, 0x529C}, //7003 #CJK UNIFIED IDEOGRAPH + {0xED69, 0x52A6}, //7004 #CJK UNIFIED IDEOGRAPH + {0xED6A, 0x52C0}, //7005 #CJK UNIFIED IDEOGRAPH + {0xED6B, 0x52DB}, //7006 #CJK UNIFIED IDEOGRAPH + {0xED6C, 0x5300}, //7007 #CJK UNIFIED IDEOGRAPH + {0xED6D, 0x5307}, //7008 #CJK UNIFIED IDEOGRAPH + {0xED6E, 0x5324}, //7009 #CJK UNIFIED IDEOGRAPH + {0xED6F, 0x5372}, //7010 #CJK UNIFIED IDEOGRAPH + {0xED70, 0x5393}, //7011 #CJK UNIFIED IDEOGRAPH + {0xED71, 0x53B2}, //7012 #CJK UNIFIED IDEOGRAPH + {0xED72, 0x53DD}, //7013 #CJK UNIFIED IDEOGRAPH + {0xED73, 0xFA0E}, //7014 #CJK COMPATIBILITY IDEOGRAPH + {0xED74, 0x549C}, //7015 #CJK UNIFIED IDEOGRAPH + {0xED75, 0x548A}, //7016 #CJK UNIFIED IDEOGRAPH + {0xED76, 0x54A9}, //7017 #CJK UNIFIED IDEOGRAPH + {0xED77, 0x54FF}, //7018 #CJK UNIFIED IDEOGRAPH + {0xED78, 0x5586}, //7019 #CJK UNIFIED IDEOGRAPH + {0xED79, 0x5759}, //7020 #CJK UNIFIED IDEOGRAPH + {0xED7A, 0x5765}, //7021 #CJK UNIFIED IDEOGRAPH + {0xED7B, 0x57AC}, //7022 #CJK UNIFIED IDEOGRAPH + {0xED7C, 0x57C8}, //7023 #CJK UNIFIED IDEOGRAPH + {0xED7D, 0x57C7}, //7024 #CJK UNIFIED IDEOGRAPH + {0xED7E, 0xFA0F}, //7025 #CJK COMPATIBILITY IDEOGRAPH + {0xED80, 0xFA10}, //7026 #CJK COMPATIBILITY IDEOGRAPH + {0xED81, 0x589E}, //7027 #CJK UNIFIED IDEOGRAPH + {0xED82, 0x58B2}, //7028 #CJK UNIFIED IDEOGRAPH + {0xED83, 0x590B}, //7029 #CJK UNIFIED IDEOGRAPH + {0xED84, 0x5953}, //7030 #CJK UNIFIED IDEOGRAPH + {0xED85, 0x595B}, //7031 #CJK UNIFIED IDEOGRAPH + {0xED86, 0x595D}, //7032 #CJK UNIFIED IDEOGRAPH + {0xED87, 0x5963}, //7033 #CJK UNIFIED IDEOGRAPH + {0xED88, 0x59A4}, //7034 #CJK UNIFIED IDEOGRAPH + {0xED89, 0x59BA}, //7035 #CJK UNIFIED IDEOGRAPH + {0xED8A, 0x5B56}, //7036 #CJK UNIFIED IDEOGRAPH + {0xED8B, 0x5BC0}, //7037 #CJK UNIFIED IDEOGRAPH + {0xED8C, 0x752F}, //7038 #CJK UNIFIED IDEOGRAPH + {0xED8D, 0x5BD8}, //7039 #CJK UNIFIED IDEOGRAPH + {0xED8E, 0x5BEC}, //7040 #CJK UNIFIED IDEOGRAPH + {0xED8F, 0x5C1E}, //7041 #CJK UNIFIED IDEOGRAPH + {0xED90, 0x5CA6}, //7042 #CJK UNIFIED IDEOGRAPH + {0xED91, 0x5CBA}, //7043 #CJK UNIFIED IDEOGRAPH + {0xED92, 0x5CF5}, //7044 #CJK UNIFIED IDEOGRAPH + {0xED93, 0x5D27}, //7045 #CJK UNIFIED IDEOGRAPH + {0xED94, 0x5D53}, //7046 #CJK UNIFIED IDEOGRAPH + {0xED95, 0xFA11}, //7047 #CJK COMPATIBILITY IDEOGRAPH + {0xED96, 0x5D42}, //7048 #CJK UNIFIED IDEOGRAPH + {0xED97, 0x5D6D}, //7049 #CJK UNIFIED IDEOGRAPH + {0xED98, 0x5DB8}, //7050 #CJK UNIFIED IDEOGRAPH + {0xED99, 0x5DB9}, //7051 #CJK UNIFIED IDEOGRAPH + {0xED9A, 0x5DD0}, //7052 #CJK UNIFIED IDEOGRAPH + {0xED9B, 0x5F21}, //7053 #CJK UNIFIED IDEOGRAPH + {0xED9C, 0x5F34}, //7054 #CJK UNIFIED IDEOGRAPH + {0xED9D, 0x5F67}, //7055 #CJK UNIFIED IDEOGRAPH + {0xED9E, 0x5FB7}, //7056 #CJK UNIFIED IDEOGRAPH + {0xED9F, 0x5FDE}, //7057 #CJK UNIFIED IDEOGRAPH + {0xEDA0, 0x605D}, //7058 #CJK UNIFIED IDEOGRAPH + {0xEDA1, 0x6085}, //7059 #CJK UNIFIED IDEOGRAPH + {0xEDA2, 0x608A}, //7060 #CJK UNIFIED IDEOGRAPH + {0xEDA3, 0x60DE}, //7061 #CJK UNIFIED IDEOGRAPH + {0xEDA4, 0x60D5}, //7062 #CJK UNIFIED IDEOGRAPH + {0xEDA5, 0x6120}, //7063 #CJK UNIFIED IDEOGRAPH + {0xEDA6, 0x60F2}, //7064 #CJK UNIFIED IDEOGRAPH + {0xEDA7, 0x6111}, //7065 #CJK UNIFIED IDEOGRAPH + {0xEDA8, 0x6137}, //7066 #CJK UNIFIED IDEOGRAPH + {0xEDA9, 0x6130}, //7067 #CJK UNIFIED IDEOGRAPH + {0xEDAA, 0x6198}, //7068 #CJK UNIFIED IDEOGRAPH + {0xEDAB, 0x6213}, //7069 #CJK UNIFIED IDEOGRAPH + {0xEDAC, 0x62A6}, //7070 #CJK UNIFIED IDEOGRAPH + {0xEDAD, 0x63F5}, //7071 #CJK UNIFIED IDEOGRAPH + {0xEDAE, 0x6460}, //7072 #CJK UNIFIED IDEOGRAPH + {0xEDAF, 0x649D}, //7073 #CJK UNIFIED IDEOGRAPH + {0xEDB0, 0x64CE}, //7074 #CJK UNIFIED IDEOGRAPH + {0xEDB1, 0x654E}, //7075 #CJK UNIFIED IDEOGRAPH + {0xEDB2, 0x6600}, //7076 #CJK UNIFIED IDEOGRAPH + {0xEDB3, 0x6615}, //7077 #CJK UNIFIED IDEOGRAPH + {0xEDB4, 0x663B}, //7078 #CJK UNIFIED IDEOGRAPH + {0xEDB5, 0x6609}, //7079 #CJK UNIFIED IDEOGRAPH + {0xEDB6, 0x662E}, //7080 #CJK UNIFIED IDEOGRAPH + {0xEDB7, 0x661E}, //7081 #CJK UNIFIED IDEOGRAPH + {0xEDB8, 0x6624}, //7082 #CJK UNIFIED IDEOGRAPH + {0xEDB9, 0x6665}, //7083 #CJK UNIFIED IDEOGRAPH + {0xEDBA, 0x6657}, //7084 #CJK UNIFIED IDEOGRAPH + {0xEDBB, 0x6659}, //7085 #CJK UNIFIED IDEOGRAPH + {0xEDBC, 0xFA12}, //7086 #CJK COMPATIBILITY IDEOGRAPH + {0xEDBD, 0x6673}, //7087 #CJK UNIFIED IDEOGRAPH + {0xEDBE, 0x6699}, //7088 #CJK UNIFIED IDEOGRAPH + {0xEDBF, 0x66A0}, //7089 #CJK UNIFIED IDEOGRAPH + {0xEDC0, 0x66B2}, //7090 #CJK UNIFIED IDEOGRAPH + {0xEDC1, 0x66BF}, //7091 #CJK UNIFIED IDEOGRAPH + {0xEDC2, 0x66FA}, //7092 #CJK UNIFIED IDEOGRAPH + {0xEDC3, 0x670E}, //7093 #CJK UNIFIED IDEOGRAPH + {0xEDC4, 0xF929}, //7094 #CJK COMPATIBILITY IDEOGRAPH + {0xEDC5, 0x6766}, //7095 #CJK UNIFIED IDEOGRAPH + {0xEDC6, 0x67BB}, //7096 #CJK UNIFIED IDEOGRAPH + {0xEDC7, 0x6852}, //7097 #CJK UNIFIED IDEOGRAPH + {0xEDC8, 0x67C0}, //7098 #CJK UNIFIED IDEOGRAPH + {0xEDC9, 0x6801}, //7099 #CJK UNIFIED IDEOGRAPH + {0xEDCA, 0x6844}, //7100 #CJK UNIFIED IDEOGRAPH + {0xEDCB, 0x68CF}, //7101 #CJK UNIFIED IDEOGRAPH + {0xEDCC, 0xFA13}, //7102 #CJK COMPATIBILITY IDEOGRAPH + {0xEDCD, 0x6968}, //7103 #CJK UNIFIED IDEOGRAPH + {0xEDCE, 0xFA14}, //7104 #CJK COMPATIBILITY IDEOGRAPH + {0xEDCF, 0x6998}, //7105 #CJK UNIFIED IDEOGRAPH + {0xEDD0, 0x69E2}, //7106 #CJK UNIFIED IDEOGRAPH + {0xEDD1, 0x6A30}, //7107 #CJK UNIFIED IDEOGRAPH + {0xEDD2, 0x6A6B}, //7108 #CJK UNIFIED IDEOGRAPH + {0xEDD3, 0x6A46}, //7109 #CJK UNIFIED IDEOGRAPH + {0xEDD4, 0x6A73}, //7110 #CJK UNIFIED IDEOGRAPH + {0xEDD5, 0x6A7E}, //7111 #CJK UNIFIED IDEOGRAPH + {0xEDD6, 0x6AE2}, //7112 #CJK UNIFIED IDEOGRAPH + {0xEDD7, 0x6AE4}, //7113 #CJK UNIFIED IDEOGRAPH + {0xEDD8, 0x6BD6}, //7114 #CJK UNIFIED IDEOGRAPH + {0xEDD9, 0x6C3F}, //7115 #CJK UNIFIED IDEOGRAPH + {0xEDDA, 0x6C5C}, //7116 #CJK UNIFIED IDEOGRAPH + {0xEDDB, 0x6C86}, //7117 #CJK UNIFIED IDEOGRAPH + {0xEDDC, 0x6C6F}, //7118 #CJK UNIFIED IDEOGRAPH + {0xEDDD, 0x6CDA}, //7119 #CJK UNIFIED IDEOGRAPH + {0xEDDE, 0x6D04}, //7120 #CJK UNIFIED IDEOGRAPH + {0xEDDF, 0x6D87}, //7121 #CJK UNIFIED IDEOGRAPH + {0xEDE0, 0x6D6F}, //7122 #CJK UNIFIED IDEOGRAPH + {0xEDE1, 0x6D96}, //7123 #CJK UNIFIED IDEOGRAPH + {0xEDE2, 0x6DAC}, //7124 #CJK UNIFIED IDEOGRAPH + {0xEDE3, 0x6DCF}, //7125 #CJK UNIFIED IDEOGRAPH + {0xEDE4, 0x6DF8}, //7126 #CJK UNIFIED IDEOGRAPH + {0xEDE5, 0x6DF2}, //7127 #CJK UNIFIED IDEOGRAPH + {0xEDE6, 0x6DFC}, //7128 #CJK UNIFIED IDEOGRAPH + {0xEDE7, 0x6E39}, //7129 #CJK UNIFIED IDEOGRAPH + {0xEDE8, 0x6E5C}, //7130 #CJK UNIFIED IDEOGRAPH + {0xEDE9, 0x6E27}, //7131 #CJK UNIFIED IDEOGRAPH + {0xEDEA, 0x6E3C}, //7132 #CJK UNIFIED IDEOGRAPH + {0xEDEB, 0x6EBF}, //7133 #CJK UNIFIED IDEOGRAPH + {0xEDEC, 0x6F88}, //7134 #CJK UNIFIED IDEOGRAPH + {0xEDED, 0x6FB5}, //7135 #CJK UNIFIED IDEOGRAPH + {0xEDEE, 0x6FF5}, //7136 #CJK UNIFIED IDEOGRAPH + {0xEDEF, 0x7005}, //7137 #CJK UNIFIED IDEOGRAPH + {0xEDF0, 0x7007}, //7138 #CJK UNIFIED IDEOGRAPH + {0xEDF1, 0x7028}, //7139 #CJK UNIFIED IDEOGRAPH + {0xEDF2, 0x7085}, //7140 #CJK UNIFIED IDEOGRAPH + {0xEDF3, 0x70AB}, //7141 #CJK UNIFIED IDEOGRAPH + {0xEDF4, 0x710F}, //7142 #CJK UNIFIED IDEOGRAPH + {0xEDF5, 0x7104}, //7143 #CJK UNIFIED IDEOGRAPH + {0xEDF6, 0x715C}, //7144 #CJK UNIFIED IDEOGRAPH + {0xEDF7, 0x7146}, //7145 #CJK UNIFIED IDEOGRAPH + {0xEDF8, 0x7147}, //7146 #CJK UNIFIED IDEOGRAPH + {0xEDF9, 0xFA15}, //7147 #CJK COMPATIBILITY IDEOGRAPH + {0xEDFA, 0x71C1}, //7148 #CJK UNIFIED IDEOGRAPH + {0xEDFB, 0x71FE}, //7149 #CJK UNIFIED IDEOGRAPH + {0xEDFC, 0x72B1}, //7150 #CJK UNIFIED IDEOGRAPH + {0xEE40, 0x72BE}, //7151 #CJK UNIFIED IDEOGRAPH + {0xEE41, 0x7324}, //7152 #CJK UNIFIED IDEOGRAPH + {0xEE42, 0xFA16}, //7153 #CJK COMPATIBILITY IDEOGRAPH + {0xEE43, 0x7377}, //7154 #CJK UNIFIED IDEOGRAPH + {0xEE44, 0x73BD}, //7155 #CJK UNIFIED IDEOGRAPH + {0xEE45, 0x73C9}, //7156 #CJK UNIFIED IDEOGRAPH + {0xEE46, 0x73D6}, //7157 #CJK UNIFIED IDEOGRAPH + {0xEE47, 0x73E3}, //7158 #CJK UNIFIED IDEOGRAPH + {0xEE48, 0x73D2}, //7159 #CJK UNIFIED IDEOGRAPH + {0xEE49, 0x7407}, //7160 #CJK UNIFIED IDEOGRAPH + {0xEE4A, 0x73F5}, //7161 #CJK UNIFIED IDEOGRAPH + {0xEE4B, 0x7426}, //7162 #CJK UNIFIED IDEOGRAPH + {0xEE4C, 0x742A}, //7163 #CJK UNIFIED IDEOGRAPH + {0xEE4D, 0x7429}, //7164 #CJK UNIFIED IDEOGRAPH + {0xEE4E, 0x742E}, //7165 #CJK UNIFIED IDEOGRAPH + {0xEE4F, 0x7462}, //7166 #CJK UNIFIED IDEOGRAPH + {0xEE50, 0x7489}, //7167 #CJK UNIFIED IDEOGRAPH + {0xEE51, 0x749F}, //7168 #CJK UNIFIED IDEOGRAPH + {0xEE52, 0x7501}, //7169 #CJK UNIFIED IDEOGRAPH + {0xEE53, 0x756F}, //7170 #CJK UNIFIED IDEOGRAPH + {0xEE54, 0x7682}, //7171 #CJK UNIFIED IDEOGRAPH + {0xEE55, 0x769C}, //7172 #CJK UNIFIED IDEOGRAPH + {0xEE56, 0x769E}, //7173 #CJK UNIFIED IDEOGRAPH + {0xEE57, 0x769B}, //7174 #CJK UNIFIED IDEOGRAPH + {0xEE58, 0x76A6}, //7175 #CJK UNIFIED IDEOGRAPH + {0xEE59, 0xFA17}, //7176 #CJK COMPATIBILITY IDEOGRAPH + {0xEE5A, 0x7746}, //7177 #CJK UNIFIED IDEOGRAPH + {0xEE5B, 0x52AF}, //7178 #CJK UNIFIED IDEOGRAPH + {0xEE5C, 0x7821}, //7179 #CJK UNIFIED IDEOGRAPH + {0xEE5D, 0x784E}, //7180 #CJK UNIFIED IDEOGRAPH + {0xEE5E, 0x7864}, //7181 #CJK UNIFIED IDEOGRAPH + {0xEE5F, 0x787A}, //7182 #CJK UNIFIED IDEOGRAPH + {0xEE60, 0x7930}, //7183 #CJK UNIFIED IDEOGRAPH + {0xEE61, 0xFA18}, //7184 #CJK COMPATIBILITY IDEOGRAPH + {0xEE62, 0xFA19}, //7185 #CJK COMPATIBILITY IDEOGRAPH + {0xEE63, 0xFA1A}, //7186 #CJK COMPATIBILITY IDEOGRAPH + {0xEE64, 0x7994}, //7187 #CJK UNIFIED IDEOGRAPH + {0xEE65, 0xFA1B}, //7188 #CJK COMPATIBILITY IDEOGRAPH + {0xEE66, 0x799B}, //7189 #CJK UNIFIED IDEOGRAPH + {0xEE67, 0x7AD1}, //7190 #CJK UNIFIED IDEOGRAPH + {0xEE68, 0x7AE7}, //7191 #CJK UNIFIED IDEOGRAPH + {0xEE69, 0xFA1C}, //7192 #CJK COMPATIBILITY IDEOGRAPH + {0xEE6A, 0x7AEB}, //7193 #CJK UNIFIED IDEOGRAPH + {0xEE6B, 0x7B9E}, //7194 #CJK UNIFIED IDEOGRAPH + {0xEE6C, 0xFA1D}, //7195 #CJK COMPATIBILITY IDEOGRAPH + {0xEE6D, 0x7D48}, //7196 #CJK UNIFIED IDEOGRAPH + {0xEE6E, 0x7D5C}, //7197 #CJK UNIFIED IDEOGRAPH + {0xEE6F, 0x7DB7}, //7198 #CJK UNIFIED IDEOGRAPH + {0xEE70, 0x7DA0}, //7199 #CJK UNIFIED IDEOGRAPH + {0xEE71, 0x7DD6}, //7200 #CJK UNIFIED IDEOGRAPH + {0xEE72, 0x7E52}, //7201 #CJK UNIFIED IDEOGRAPH + {0xEE73, 0x7F47}, //7202 #CJK UNIFIED IDEOGRAPH + {0xEE74, 0x7FA1}, //7203 #CJK UNIFIED IDEOGRAPH + {0xEE75, 0xFA1E}, //7204 #CJK COMPATIBILITY IDEOGRAPH + {0xEE76, 0x8301}, //7205 #CJK UNIFIED IDEOGRAPH + {0xEE77, 0x8362}, //7206 #CJK UNIFIED IDEOGRAPH + {0xEE78, 0x837F}, //7207 #CJK UNIFIED IDEOGRAPH + {0xEE79, 0x83C7}, //7208 #CJK UNIFIED IDEOGRAPH + {0xEE7A, 0x83F6}, //7209 #CJK UNIFIED IDEOGRAPH + {0xEE7B, 0x8448}, //7210 #CJK UNIFIED IDEOGRAPH + {0xEE7C, 0x84B4}, //7211 #CJK UNIFIED IDEOGRAPH + {0xEE7D, 0x8553}, //7212 #CJK UNIFIED IDEOGRAPH + {0xEE7E, 0x8559}, //7213 #CJK UNIFIED IDEOGRAPH + {0xEE80, 0x856B}, //7214 #CJK UNIFIED IDEOGRAPH + {0xEE81, 0xFA1F}, //7215 #CJK COMPATIBILITY IDEOGRAPH + {0xEE82, 0x85B0}, //7216 #CJK UNIFIED IDEOGRAPH + {0xEE83, 0xFA20}, //7217 #CJK COMPATIBILITY IDEOGRAPH + {0xEE84, 0xFA21}, //7218 #CJK COMPATIBILITY IDEOGRAPH + {0xEE85, 0x8807}, //7219 #CJK UNIFIED IDEOGRAPH + {0xEE86, 0x88F5}, //7220 #CJK UNIFIED IDEOGRAPH + {0xEE87, 0x8A12}, //7221 #CJK UNIFIED IDEOGRAPH + {0xEE88, 0x8A37}, //7222 #CJK UNIFIED IDEOGRAPH + {0xEE89, 0x8A79}, //7223 #CJK UNIFIED IDEOGRAPH + {0xEE8A, 0x8AA7}, //7224 #CJK UNIFIED IDEOGRAPH + {0xEE8B, 0x8ABE}, //7225 #CJK UNIFIED IDEOGRAPH + {0xEE8C, 0x8ADF}, //7226 #CJK UNIFIED IDEOGRAPH + {0xEE8D, 0xFA22}, //7227 #CJK COMPATIBILITY IDEOGRAPH + {0xEE8E, 0x8AF6}, //7228 #CJK UNIFIED IDEOGRAPH + {0xEE8F, 0x8B53}, //7229 #CJK UNIFIED IDEOGRAPH + {0xEE90, 0x8B7F}, //7230 #CJK UNIFIED IDEOGRAPH + {0xEE91, 0x8CF0}, //7231 #CJK UNIFIED IDEOGRAPH + {0xEE92, 0x8CF4}, //7232 #CJK UNIFIED IDEOGRAPH + {0xEE93, 0x8D12}, //7233 #CJK UNIFIED IDEOGRAPH + {0xEE94, 0x8D76}, //7234 #CJK UNIFIED IDEOGRAPH + {0xEE95, 0xFA23}, //7235 #CJK COMPATIBILITY IDEOGRAPH + {0xEE96, 0x8ECF}, //7236 #CJK UNIFIED IDEOGRAPH + {0xEE97, 0xFA24}, //7237 #CJK COMPATIBILITY IDEOGRAPH + {0xEE98, 0xFA25}, //7238 #CJK COMPATIBILITY IDEOGRAPH + {0xEE99, 0x9067}, //7239 #CJK UNIFIED IDEOGRAPH + {0xEE9A, 0x90DE}, //7240 #CJK UNIFIED IDEOGRAPH + {0xEE9B, 0xFA26}, //7241 #CJK COMPATIBILITY IDEOGRAPH + {0xEE9C, 0x9115}, //7242 #CJK UNIFIED IDEOGRAPH + {0xEE9D, 0x9127}, //7243 #CJK UNIFIED IDEOGRAPH + {0xEE9E, 0x91DA}, //7244 #CJK UNIFIED IDEOGRAPH + {0xEE9F, 0x91D7}, //7245 #CJK UNIFIED IDEOGRAPH + {0xEEA0, 0x91DE}, //7246 #CJK UNIFIED IDEOGRAPH + {0xEEA1, 0x91ED}, //7247 #CJK UNIFIED IDEOGRAPH + {0xEEA2, 0x91EE}, //7248 #CJK UNIFIED IDEOGRAPH + {0xEEA3, 0x91E4}, //7249 #CJK UNIFIED IDEOGRAPH + {0xEEA4, 0x91E5}, //7250 #CJK UNIFIED IDEOGRAPH + {0xEEA5, 0x9206}, //7251 #CJK UNIFIED IDEOGRAPH + {0xEEA6, 0x9210}, //7252 #CJK UNIFIED IDEOGRAPH + {0xEEA7, 0x920A}, //7253 #CJK UNIFIED IDEOGRAPH + {0xEEA8, 0x923A}, //7254 #CJK UNIFIED IDEOGRAPH + {0xEEA9, 0x9240}, //7255 #CJK UNIFIED IDEOGRAPH + {0xEEAA, 0x923C}, //7256 #CJK UNIFIED IDEOGRAPH + {0xEEAB, 0x924E}, //7257 #CJK UNIFIED IDEOGRAPH + {0xEEAC, 0x9259}, //7258 #CJK UNIFIED IDEOGRAPH + {0xEEAD, 0x9251}, //7259 #CJK UNIFIED IDEOGRAPH + {0xEEAE, 0x9239}, //7260 #CJK UNIFIED IDEOGRAPH + {0xEEAF, 0x9267}, //7261 #CJK UNIFIED IDEOGRAPH + {0xEEB0, 0x92A7}, //7262 #CJK UNIFIED IDEOGRAPH + {0xEEB1, 0x9277}, //7263 #CJK UNIFIED IDEOGRAPH + {0xEEB2, 0x9278}, //7264 #CJK UNIFIED IDEOGRAPH + {0xEEB3, 0x92E7}, //7265 #CJK UNIFIED IDEOGRAPH + {0xEEB4, 0x92D7}, //7266 #CJK UNIFIED IDEOGRAPH + {0xEEB5, 0x92D9}, //7267 #CJK UNIFIED IDEOGRAPH + {0xEEB6, 0x92D0}, //7268 #CJK UNIFIED IDEOGRAPH + {0xEEB7, 0xFA27}, //7269 #CJK COMPATIBILITY IDEOGRAPH + {0xEEB8, 0x92D5}, //7270 #CJK UNIFIED IDEOGRAPH + {0xEEB9, 0x92E0}, //7271 #CJK UNIFIED IDEOGRAPH + {0xEEBA, 0x92D3}, //7272 #CJK UNIFIED IDEOGRAPH + {0xEEBB, 0x9325}, //7273 #CJK UNIFIED IDEOGRAPH + {0xEEBC, 0x9321}, //7274 #CJK UNIFIED IDEOGRAPH + {0xEEBD, 0x92FB}, //7275 #CJK UNIFIED IDEOGRAPH + {0xEEBE, 0xFA28}, //7276 #CJK COMPATIBILITY IDEOGRAPH + {0xEEBF, 0x931E}, //7277 #CJK UNIFIED IDEOGRAPH + {0xEEC0, 0x92FF}, //7278 #CJK UNIFIED IDEOGRAPH + {0xEEC1, 0x931D}, //7279 #CJK UNIFIED IDEOGRAPH + {0xEEC2, 0x9302}, //7280 #CJK UNIFIED IDEOGRAPH + {0xEEC3, 0x9370}, //7281 #CJK UNIFIED IDEOGRAPH + {0xEEC4, 0x9357}, //7282 #CJK UNIFIED IDEOGRAPH + {0xEEC5, 0x93A4}, //7283 #CJK UNIFIED IDEOGRAPH + {0xEEC6, 0x93C6}, //7284 #CJK UNIFIED IDEOGRAPH + {0xEEC7, 0x93DE}, //7285 #CJK UNIFIED IDEOGRAPH + {0xEEC8, 0x93F8}, //7286 #CJK UNIFIED IDEOGRAPH + {0xEEC9, 0x9431}, //7287 #CJK UNIFIED IDEOGRAPH + {0xEECA, 0x9445}, //7288 #CJK UNIFIED IDEOGRAPH + {0xEECB, 0x9448}, //7289 #CJK UNIFIED IDEOGRAPH + {0xEECC, 0x9592}, //7290 #CJK UNIFIED IDEOGRAPH + {0xEECD, 0xF9DC}, //7291 #CJK COMPATIBILITY IDEOGRAPH + {0xEECE, 0xFA29}, //7292 #CJK COMPATIBILITY IDEOGRAPH + {0xEECF, 0x969D}, //7293 #CJK UNIFIED IDEOGRAPH + {0xEED0, 0x96AF}, //7294 #CJK UNIFIED IDEOGRAPH + {0xEED1, 0x9733}, //7295 #CJK UNIFIED IDEOGRAPH + {0xEED2, 0x973B}, //7296 #CJK UNIFIED IDEOGRAPH + {0xEED3, 0x9743}, //7297 #CJK UNIFIED IDEOGRAPH + {0xEED4, 0x974D}, //7298 #CJK UNIFIED IDEOGRAPH + {0xEED5, 0x974F}, //7299 #CJK UNIFIED IDEOGRAPH + {0xEED6, 0x9751}, //7300 #CJK UNIFIED IDEOGRAPH + {0xEED7, 0x9755}, //7301 #CJK UNIFIED IDEOGRAPH + {0xEED8, 0x9857}, //7302 #CJK UNIFIED IDEOGRAPH + {0xEED9, 0x9865}, //7303 #CJK UNIFIED IDEOGRAPH + {0xEEDA, 0xFA2A}, //7304 #CJK COMPATIBILITY IDEOGRAPH + {0xEEDB, 0xFA2B}, //7305 #CJK COMPATIBILITY IDEOGRAPH + {0xEEDC, 0x9927}, //7306 #CJK UNIFIED IDEOGRAPH + {0xEEDD, 0xFA2C}, //7307 #CJK COMPATIBILITY IDEOGRAPH + {0xEEDE, 0x999E}, //7308 #CJK UNIFIED IDEOGRAPH + {0xEEDF, 0x9A4E}, //7309 #CJK UNIFIED IDEOGRAPH + {0xEEE0, 0x9AD9}, //7310 #CJK UNIFIED IDEOGRAPH + {0xEEE1, 0x9ADC}, //7311 #CJK UNIFIED IDEOGRAPH + {0xEEE2, 0x9B75}, //7312 #CJK UNIFIED IDEOGRAPH + {0xEEE3, 0x9B72}, //7313 #CJK UNIFIED IDEOGRAPH + {0xEEE4, 0x9B8F}, //7314 #CJK UNIFIED IDEOGRAPH + {0xEEE5, 0x9BB1}, //7315 #CJK UNIFIED IDEOGRAPH + {0xEEE6, 0x9BBB}, //7316 #CJK UNIFIED IDEOGRAPH + {0xEEE7, 0x9C00}, //7317 #CJK UNIFIED IDEOGRAPH + {0xEEE8, 0x9D70}, //7318 #CJK UNIFIED IDEOGRAPH + {0xEEE9, 0x9D6B}, //7319 #CJK UNIFIED IDEOGRAPH + {0xEEEA, 0xFA2D}, //7320 #CJK COMPATIBILITY IDEOGRAPH + {0xEEEB, 0x9E19}, //7321 #CJK UNIFIED IDEOGRAPH + {0xEEEC, 0x9ED1}, //7322 #CJK UNIFIED IDEOGRAPH + {0xEEEF, 0x2170}, //7323 #SMALL ROMAN NUMERAL ONE + {0xEEF0, 0x2171}, //7324 #SMALL ROMAN NUMERAL TWO + {0xEEF1, 0x2172}, //7325 #SMALL ROMAN NUMERAL THREE + {0xEEF2, 0x2173}, //7326 #SMALL ROMAN NUMERAL FOUR + {0xEEF3, 0x2174}, //7327 #SMALL ROMAN NUMERAL FIVE + {0xEEF4, 0x2175}, //7328 #SMALL ROMAN NUMERAL SIX + {0xEEF5, 0x2176}, //7329 #SMALL ROMAN NUMERAL SEVEN + {0xEEF6, 0x2177}, //7330 #SMALL ROMAN NUMERAL EIGHT + {0xEEF7, 0x2178}, //7331 #SMALL ROMAN NUMERAL NINE + {0xEEF8, 0x2179}, //7332 #SMALL ROMAN NUMERAL TEN + {0xEEF9, 0xFFE2}, //7333 #FULLWIDTH NOT SIGN + {0xEEFA, 0xFFE4}, //7334 #FULLWIDTH BROKEN BAR + {0xEEFB, 0xFF07}, //7335 #FULLWIDTH APOSTROPHE + {0xEEFC, 0xFF02}, //7336 #FULLWIDTH QUOTATION MARK + {0xFA40, 0x2170}, //7337 #SMALL ROMAN NUMERAL ONE + {0xFA41, 0x2171}, //7338 #SMALL ROMAN NUMERAL TWO + {0xFA42, 0x2172}, //7339 #SMALL ROMAN NUMERAL THREE + {0xFA43, 0x2173}, //7340 #SMALL ROMAN NUMERAL FOUR + {0xFA44, 0x2174}, //7341 #SMALL ROMAN NUMERAL FIVE + {0xFA45, 0x2175}, //7342 #SMALL ROMAN NUMERAL SIX + {0xFA46, 0x2176}, //7343 #SMALL ROMAN NUMERAL SEVEN + {0xFA47, 0x2177}, //7344 #SMALL ROMAN NUMERAL EIGHT + {0xFA48, 0x2178}, //7345 #SMALL ROMAN NUMERAL NINE + {0xFA49, 0x2179}, //7346 #SMALL ROMAN NUMERAL TEN + {0xFA4A, 0x2160}, //7347 #ROMAN NUMERAL ONE + {0xFA4B, 0x2161}, //7348 #ROMAN NUMERAL TWO + {0xFA4C, 0x2162}, //7349 #ROMAN NUMERAL THREE + {0xFA4D, 0x2163}, //7350 #ROMAN NUMERAL FOUR + {0xFA4E, 0x2164}, //7351 #ROMAN NUMERAL FIVE + {0xFA4F, 0x2165}, //7352 #ROMAN NUMERAL SIX + {0xFA50, 0x2166}, //7353 #ROMAN NUMERAL SEVEN + {0xFA51, 0x2167}, //7354 #ROMAN NUMERAL EIGHT + {0xFA52, 0x2168}, //7355 #ROMAN NUMERAL NINE + {0xFA53, 0x2169}, //7356 #ROMAN NUMERAL TEN + {0xFA54, 0xFFE2}, //7357 #FULLWIDTH NOT SIGN + {0xFA55, 0xFFE4}, //7358 #FULLWIDTH BROKEN BAR + {0xFA56, 0xFF07}, //7359 #FULLWIDTH APOSTROPHE + {0xFA57, 0xFF02}, //7360 #FULLWIDTH QUOTATION MARK + {0xFA58, 0x3231}, //7361 #PARENTHESIZED IDEOGRAPH STOCK + {0xFA59, 0x2116}, //7362 #NUMERO SIGN + {0xFA5A, 0x2121}, //7363 #TELEPHONE SIGN + {0xFA5B, 0x2235}, //7364 #BECAUSE + {0xFA5C, 0x7E8A}, //7365 #CJK UNIFIED IDEOGRAPH + {0xFA5D, 0x891C}, //7366 #CJK UNIFIED IDEOGRAPH + {0xFA5E, 0x9348}, //7367 #CJK UNIFIED IDEOGRAPH + {0xFA5F, 0x9288}, //7368 #CJK UNIFIED IDEOGRAPH + {0xFA60, 0x84DC}, //7369 #CJK UNIFIED IDEOGRAPH + {0xFA61, 0x4FC9}, //7370 #CJK UNIFIED IDEOGRAPH + {0xFA62, 0x70BB}, //7371 #CJK UNIFIED IDEOGRAPH + {0xFA63, 0x6631}, //7372 #CJK UNIFIED IDEOGRAPH + {0xFA64, 0x68C8}, //7373 #CJK UNIFIED IDEOGRAPH + {0xFA65, 0x92F9}, //7374 #CJK UNIFIED IDEOGRAPH + {0xFA66, 0x66FB}, //7375 #CJK UNIFIED IDEOGRAPH + {0xFA67, 0x5F45}, //7376 #CJK UNIFIED IDEOGRAPH + {0xFA68, 0x4E28}, //7377 #CJK UNIFIED IDEOGRAPH + {0xFA69, 0x4EE1}, //7378 #CJK UNIFIED IDEOGRAPH + {0xFA6A, 0x4EFC}, //7379 #CJK UNIFIED IDEOGRAPH + {0xFA6B, 0x4F00}, //7380 #CJK UNIFIED IDEOGRAPH + {0xFA6C, 0x4F03}, //7381 #CJK UNIFIED IDEOGRAPH + {0xFA6D, 0x4F39}, //7382 #CJK UNIFIED IDEOGRAPH + {0xFA6E, 0x4F56}, //7383 #CJK UNIFIED IDEOGRAPH + {0xFA6F, 0x4F92}, //7384 #CJK UNIFIED IDEOGRAPH + {0xFA70, 0x4F8A}, //7385 #CJK UNIFIED IDEOGRAPH + {0xFA71, 0x4F9A}, //7386 #CJK UNIFIED IDEOGRAPH + {0xFA72, 0x4F94}, //7387 #CJK UNIFIED IDEOGRAPH + {0xFA73, 0x4FCD}, //7388 #CJK UNIFIED IDEOGRAPH + {0xFA74, 0x5040}, //7389 #CJK UNIFIED IDEOGRAPH + {0xFA75, 0x5022}, //7390 #CJK UNIFIED IDEOGRAPH + {0xFA76, 0x4FFF}, //7391 #CJK UNIFIED IDEOGRAPH + {0xFA77, 0x501E}, //7392 #CJK UNIFIED IDEOGRAPH + {0xFA78, 0x5046}, //7393 #CJK UNIFIED IDEOGRAPH + {0xFA79, 0x5070}, //7394 #CJK UNIFIED IDEOGRAPH + {0xFA7A, 0x5042}, //7395 #CJK UNIFIED IDEOGRAPH + {0xFA7B, 0x5094}, //7396 #CJK UNIFIED IDEOGRAPH + {0xFA7C, 0x50F4}, //7397 #CJK UNIFIED IDEOGRAPH + {0xFA7D, 0x50D8}, //7398 #CJK UNIFIED IDEOGRAPH + {0xFA7E, 0x514A}, //7399 #CJK UNIFIED IDEOGRAPH + {0xFA80, 0x5164}, //7400 #CJK UNIFIED IDEOGRAPH + {0xFA81, 0x519D}, //7401 #CJK UNIFIED IDEOGRAPH + {0xFA82, 0x51BE}, //7402 #CJK UNIFIED IDEOGRAPH + {0xFA83, 0x51EC}, //7403 #CJK UNIFIED IDEOGRAPH + {0xFA84, 0x5215}, //7404 #CJK UNIFIED IDEOGRAPH + {0xFA85, 0x529C}, //7405 #CJK UNIFIED IDEOGRAPH + {0xFA86, 0x52A6}, //7406 #CJK UNIFIED IDEOGRAPH + {0xFA87, 0x52C0}, //7407 #CJK UNIFIED IDEOGRAPH + {0xFA88, 0x52DB}, //7408 #CJK UNIFIED IDEOGRAPH + {0xFA89, 0x5300}, //7409 #CJK UNIFIED IDEOGRAPH + {0xFA8A, 0x5307}, //7410 #CJK UNIFIED IDEOGRAPH + {0xFA8B, 0x5324}, //7411 #CJK UNIFIED IDEOGRAPH + {0xFA8C, 0x5372}, //7412 #CJK UNIFIED IDEOGRAPH + {0xFA8D, 0x5393}, //7413 #CJK UNIFIED IDEOGRAPH + {0xFA8E, 0x53B2}, //7414 #CJK UNIFIED IDEOGRAPH + {0xFA8F, 0x53DD}, //7415 #CJK UNIFIED IDEOGRAPH + {0xFA90, 0xFA0E}, //7416 #CJK COMPATIBILITY IDEOGRAPH + {0xFA91, 0x549C}, //7417 #CJK UNIFIED IDEOGRAPH + {0xFA92, 0x548A}, //7418 #CJK UNIFIED IDEOGRAPH + {0xFA93, 0x54A9}, //7419 #CJK UNIFIED IDEOGRAPH + {0xFA94, 0x54FF}, //7420 #CJK UNIFIED IDEOGRAPH + {0xFA95, 0x5586}, //7421 #CJK UNIFIED IDEOGRAPH + {0xFA96, 0x5759}, //7422 #CJK UNIFIED IDEOGRAPH + {0xFA97, 0x5765}, //7423 #CJK UNIFIED IDEOGRAPH + {0xFA98, 0x57AC}, //7424 #CJK UNIFIED IDEOGRAPH + {0xFA99, 0x57C8}, //7425 #CJK UNIFIED IDEOGRAPH + {0xFA9A, 0x57C7}, //7426 #CJK UNIFIED IDEOGRAPH + {0xFA9B, 0xFA0F}, //7427 #CJK COMPATIBILITY IDEOGRAPH + {0xFA9C, 0xFA10}, //7428 #CJK COMPATIBILITY IDEOGRAPH + {0xFA9D, 0x589E}, //7429 #CJK UNIFIED IDEOGRAPH + {0xFA9E, 0x58B2}, //7430 #CJK UNIFIED IDEOGRAPH + {0xFA9F, 0x590B}, //7431 #CJK UNIFIED IDEOGRAPH + {0xFAA0, 0x5953}, //7432 #CJK UNIFIED IDEOGRAPH + {0xFAA1, 0x595B}, //7433 #CJK UNIFIED IDEOGRAPH + {0xFAA2, 0x595D}, //7434 #CJK UNIFIED IDEOGRAPH + {0xFAA3, 0x5963}, //7435 #CJK UNIFIED IDEOGRAPH + {0xFAA4, 0x59A4}, //7436 #CJK UNIFIED IDEOGRAPH + {0xFAA5, 0x59BA}, //7437 #CJK UNIFIED IDEOGRAPH + {0xFAA6, 0x5B56}, //7438 #CJK UNIFIED IDEOGRAPH + {0xFAA7, 0x5BC0}, //7439 #CJK UNIFIED IDEOGRAPH + {0xFAA8, 0x752F}, //7440 #CJK UNIFIED IDEOGRAPH + {0xFAA9, 0x5BD8}, //7441 #CJK UNIFIED IDEOGRAPH + {0xFAAA, 0x5BEC}, //7442 #CJK UNIFIED IDEOGRAPH + {0xFAAB, 0x5C1E}, //7443 #CJK UNIFIED IDEOGRAPH + {0xFAAC, 0x5CA6}, //7444 #CJK UNIFIED IDEOGRAPH + {0xFAAD, 0x5CBA}, //7445 #CJK UNIFIED IDEOGRAPH + {0xFAAE, 0x5CF5}, //7446 #CJK UNIFIED IDEOGRAPH + {0xFAAF, 0x5D27}, //7447 #CJK UNIFIED IDEOGRAPH + {0xFAB0, 0x5D53}, //7448 #CJK UNIFIED IDEOGRAPH + {0xFAB1, 0xFA11}, //7449 #CJK COMPATIBILITY IDEOGRAPH + {0xFAB2, 0x5D42}, //7450 #CJK UNIFIED IDEOGRAPH + {0xFAB3, 0x5D6D}, //7451 #CJK UNIFIED IDEOGRAPH + {0xFAB4, 0x5DB8}, //7452 #CJK UNIFIED IDEOGRAPH + {0xFAB5, 0x5DB9}, //7453 #CJK UNIFIED IDEOGRAPH + {0xFAB6, 0x5DD0}, //7454 #CJK UNIFIED IDEOGRAPH + {0xFAB7, 0x5F21}, //7455 #CJK UNIFIED IDEOGRAPH + {0xFAB8, 0x5F34}, //7456 #CJK UNIFIED IDEOGRAPH + {0xFAB9, 0x5F67}, //7457 #CJK UNIFIED IDEOGRAPH + {0xFABA, 0x5FB7}, //7458 #CJK UNIFIED IDEOGRAPH + {0xFABB, 0x5FDE}, //7459 #CJK UNIFIED IDEOGRAPH + {0xFABC, 0x605D}, //7460 #CJK UNIFIED IDEOGRAPH + {0xFABD, 0x6085}, //7461 #CJK UNIFIED IDEOGRAPH + {0xFABE, 0x608A}, //7462 #CJK UNIFIED IDEOGRAPH + {0xFABF, 0x60DE}, //7463 #CJK UNIFIED IDEOGRAPH + {0xFAC0, 0x60D5}, //7464 #CJK UNIFIED IDEOGRAPH + {0xFAC1, 0x6120}, //7465 #CJK UNIFIED IDEOGRAPH + {0xFAC2, 0x60F2}, //7466 #CJK UNIFIED IDEOGRAPH + {0xFAC3, 0x6111}, //7467 #CJK UNIFIED IDEOGRAPH + {0xFAC4, 0x6137}, //7468 #CJK UNIFIED IDEOGRAPH + {0xFAC5, 0x6130}, //7469 #CJK UNIFIED IDEOGRAPH + {0xFAC6, 0x6198}, //7470 #CJK UNIFIED IDEOGRAPH + {0xFAC7, 0x6213}, //7471 #CJK UNIFIED IDEOGRAPH + {0xFAC8, 0x62A6}, //7472 #CJK UNIFIED IDEOGRAPH + {0xFAC9, 0x63F5}, //7473 #CJK UNIFIED IDEOGRAPH + {0xFACA, 0x6460}, //7474 #CJK UNIFIED IDEOGRAPH + {0xFACB, 0x649D}, //7475 #CJK UNIFIED IDEOGRAPH + {0xFACC, 0x64CE}, //7476 #CJK UNIFIED IDEOGRAPH + {0xFACD, 0x654E}, //7477 #CJK UNIFIED IDEOGRAPH + {0xFACE, 0x6600}, //7478 #CJK UNIFIED IDEOGRAPH + {0xFACF, 0x6615}, //7479 #CJK UNIFIED IDEOGRAPH + {0xFAD0, 0x663B}, //7480 #CJK UNIFIED IDEOGRAPH + {0xFAD1, 0x6609}, //7481 #CJK UNIFIED IDEOGRAPH + {0xFAD2, 0x662E}, //7482 #CJK UNIFIED IDEOGRAPH + {0xFAD3, 0x661E}, //7483 #CJK UNIFIED IDEOGRAPH + {0xFAD4, 0x6624}, //7484 #CJK UNIFIED IDEOGRAPH + {0xFAD5, 0x6665}, //7485 #CJK UNIFIED IDEOGRAPH + {0xFAD6, 0x6657}, //7486 #CJK UNIFIED IDEOGRAPH + {0xFAD7, 0x6659}, //7487 #CJK UNIFIED IDEOGRAPH + {0xFAD8, 0xFA12}, //7488 #CJK COMPATIBILITY IDEOGRAPH + {0xFAD9, 0x6673}, //7489 #CJK UNIFIED IDEOGRAPH + {0xFADA, 0x6699}, //7490 #CJK UNIFIED IDEOGRAPH + {0xFADB, 0x66A0}, //7491 #CJK UNIFIED IDEOGRAPH + {0xFADC, 0x66B2}, //7492 #CJK UNIFIED IDEOGRAPH + {0xFADD, 0x66BF}, //7493 #CJK UNIFIED IDEOGRAPH + {0xFADE, 0x66FA}, //7494 #CJK UNIFIED IDEOGRAPH + {0xFADF, 0x670E}, //7495 #CJK UNIFIED IDEOGRAPH + {0xFAE0, 0xF929}, //7496 #CJK COMPATIBILITY IDEOGRAPH + {0xFAE1, 0x6766}, //7497 #CJK UNIFIED IDEOGRAPH + {0xFAE2, 0x67BB}, //7498 #CJK UNIFIED IDEOGRAPH + {0xFAE3, 0x6852}, //7499 #CJK UNIFIED IDEOGRAPH + {0xFAE4, 0x67C0}, //7500 #CJK UNIFIED IDEOGRAPH + {0xFAE5, 0x6801}, //7501 #CJK UNIFIED IDEOGRAPH + {0xFAE6, 0x6844}, //7502 #CJK UNIFIED IDEOGRAPH + {0xFAE7, 0x68CF}, //7503 #CJK UNIFIED IDEOGRAPH + {0xFAE8, 0xFA13}, //7504 #CJK COMPATIBILITY IDEOGRAPH + {0xFAE9, 0x6968}, //7505 #CJK UNIFIED IDEOGRAPH + {0xFAEA, 0xFA14}, //7506 #CJK COMPATIBILITY IDEOGRAPH + {0xFAEB, 0x6998}, //7507 #CJK UNIFIED IDEOGRAPH + {0xFAEC, 0x69E2}, //7508 #CJK UNIFIED IDEOGRAPH + {0xFAED, 0x6A30}, //7509 #CJK UNIFIED IDEOGRAPH + {0xFAEE, 0x6A6B}, //7510 #CJK UNIFIED IDEOGRAPH + {0xFAEF, 0x6A46}, //7511 #CJK UNIFIED IDEOGRAPH + {0xFAF0, 0x6A73}, //7512 #CJK UNIFIED IDEOGRAPH + {0xFAF1, 0x6A7E}, //7513 #CJK UNIFIED IDEOGRAPH + {0xFAF2, 0x6AE2}, //7514 #CJK UNIFIED IDEOGRAPH + {0xFAF3, 0x6AE4}, //7515 #CJK UNIFIED IDEOGRAPH + {0xFAF4, 0x6BD6}, //7516 #CJK UNIFIED IDEOGRAPH + {0xFAF5, 0x6C3F}, //7517 #CJK UNIFIED IDEOGRAPH + {0xFAF6, 0x6C5C}, //7518 #CJK UNIFIED IDEOGRAPH + {0xFAF7, 0x6C86}, //7519 #CJK UNIFIED IDEOGRAPH + {0xFAF8, 0x6C6F}, //7520 #CJK UNIFIED IDEOGRAPH + {0xFAF9, 0x6CDA}, //7521 #CJK UNIFIED IDEOGRAPH + {0xFAFA, 0x6D04}, //7522 #CJK UNIFIED IDEOGRAPH + {0xFAFB, 0x6D87}, //7523 #CJK UNIFIED IDEOGRAPH + {0xFAFC, 0x6D6F}, //7524 #CJK UNIFIED IDEOGRAPH + {0xFB40, 0x6D96}, //7525 #CJK UNIFIED IDEOGRAPH + {0xFB41, 0x6DAC}, //7526 #CJK UNIFIED IDEOGRAPH + {0xFB42, 0x6DCF}, //7527 #CJK UNIFIED IDEOGRAPH + {0xFB43, 0x6DF8}, //7528 #CJK UNIFIED IDEOGRAPH + {0xFB44, 0x6DF2}, //7529 #CJK UNIFIED IDEOGRAPH + {0xFB45, 0x6DFC}, //7530 #CJK UNIFIED IDEOGRAPH + {0xFB46, 0x6E39}, //7531 #CJK UNIFIED IDEOGRAPH + {0xFB47, 0x6E5C}, //7532 #CJK UNIFIED IDEOGRAPH + {0xFB48, 0x6E27}, //7533 #CJK UNIFIED IDEOGRAPH + {0xFB49, 0x6E3C}, //7534 #CJK UNIFIED IDEOGRAPH + {0xFB4A, 0x6EBF}, //7535 #CJK UNIFIED IDEOGRAPH + {0xFB4B, 0x6F88}, //7536 #CJK UNIFIED IDEOGRAPH + {0xFB4C, 0x6FB5}, //7537 #CJK UNIFIED IDEOGRAPH + {0xFB4D, 0x6FF5}, //7538 #CJK UNIFIED IDEOGRAPH + {0xFB4E, 0x7005}, //7539 #CJK UNIFIED IDEOGRAPH + {0xFB4F, 0x7007}, //7540 #CJK UNIFIED IDEOGRAPH + {0xFB50, 0x7028}, //7541 #CJK UNIFIED IDEOGRAPH + {0xFB51, 0x7085}, //7542 #CJK UNIFIED IDEOGRAPH + {0xFB52, 0x70AB}, //7543 #CJK UNIFIED IDEOGRAPH + {0xFB53, 0x710F}, //7544 #CJK UNIFIED IDEOGRAPH + {0xFB54, 0x7104}, //7545 #CJK UNIFIED IDEOGRAPH + {0xFB55, 0x715C}, //7546 #CJK UNIFIED IDEOGRAPH + {0xFB56, 0x7146}, //7547 #CJK UNIFIED IDEOGRAPH + {0xFB57, 0x7147}, //7548 #CJK UNIFIED IDEOGRAPH + {0xFB58, 0xFA15}, //7549 #CJK COMPATIBILITY IDEOGRAPH + {0xFB59, 0x71C1}, //7550 #CJK UNIFIED IDEOGRAPH + {0xFB5A, 0x71FE}, //7551 #CJK UNIFIED IDEOGRAPH + {0xFB5B, 0x72B1}, //7552 #CJK UNIFIED IDEOGRAPH + {0xFB5C, 0x72BE}, //7553 #CJK UNIFIED IDEOGRAPH + {0xFB5D, 0x7324}, //7554 #CJK UNIFIED IDEOGRAPH + {0xFB5E, 0xFA16}, //7555 #CJK COMPATIBILITY IDEOGRAPH + {0xFB5F, 0x7377}, //7556 #CJK UNIFIED IDEOGRAPH + {0xFB60, 0x73BD}, //7557 #CJK UNIFIED IDEOGRAPH + {0xFB61, 0x73C9}, //7558 #CJK UNIFIED IDEOGRAPH + {0xFB62, 0x73D6}, //7559 #CJK UNIFIED IDEOGRAPH + {0xFB63, 0x73E3}, //7560 #CJK UNIFIED IDEOGRAPH + {0xFB64, 0x73D2}, //7561 #CJK UNIFIED IDEOGRAPH + {0xFB65, 0x7407}, //7562 #CJK UNIFIED IDEOGRAPH + {0xFB66, 0x73F5}, //7563 #CJK UNIFIED IDEOGRAPH + {0xFB67, 0x7426}, //7564 #CJK UNIFIED IDEOGRAPH + {0xFB68, 0x742A}, //7565 #CJK UNIFIED IDEOGRAPH + {0xFB69, 0x7429}, //7566 #CJK UNIFIED IDEOGRAPH + {0xFB6A, 0x742E}, //7567 #CJK UNIFIED IDEOGRAPH + {0xFB6B, 0x7462}, //7568 #CJK UNIFIED IDEOGRAPH + {0xFB6C, 0x7489}, //7569 #CJK UNIFIED IDEOGRAPH + {0xFB6D, 0x749F}, //7570 #CJK UNIFIED IDEOGRAPH + {0xFB6E, 0x7501}, //7571 #CJK UNIFIED IDEOGRAPH + {0xFB6F, 0x756F}, //7572 #CJK UNIFIED IDEOGRAPH + {0xFB70, 0x7682}, //7573 #CJK UNIFIED IDEOGRAPH + {0xFB71, 0x769C}, //7574 #CJK UNIFIED IDEOGRAPH + {0xFB72, 0x769E}, //7575 #CJK UNIFIED IDEOGRAPH + {0xFB73, 0x769B}, //7576 #CJK UNIFIED IDEOGRAPH + {0xFB74, 0x76A6}, //7577 #CJK UNIFIED IDEOGRAPH + {0xFB75, 0xFA17}, //7578 #CJK COMPATIBILITY IDEOGRAPH + {0xFB76, 0x7746}, //7579 #CJK UNIFIED IDEOGRAPH + {0xFB77, 0x52AF}, //7580 #CJK UNIFIED IDEOGRAPH + {0xFB78, 0x7821}, //7581 #CJK UNIFIED IDEOGRAPH + {0xFB79, 0x784E}, //7582 #CJK UNIFIED IDEOGRAPH + {0xFB7A, 0x7864}, //7583 #CJK UNIFIED IDEOGRAPH + {0xFB7B, 0x787A}, //7584 #CJK UNIFIED IDEOGRAPH + {0xFB7C, 0x7930}, //7585 #CJK UNIFIED IDEOGRAPH + {0xFB7D, 0xFA18}, //7586 #CJK COMPATIBILITY IDEOGRAPH + {0xFB7E, 0xFA19}, //7587 #CJK COMPATIBILITY IDEOGRAPH + {0xFB80, 0xFA1A}, //7588 #CJK COMPATIBILITY IDEOGRAPH + {0xFB81, 0x7994}, //7589 #CJK UNIFIED IDEOGRAPH + {0xFB82, 0xFA1B}, //7590 #CJK COMPATIBILITY IDEOGRAPH + {0xFB83, 0x799B}, //7591 #CJK UNIFIED IDEOGRAPH + {0xFB84, 0x7AD1}, //7592 #CJK UNIFIED IDEOGRAPH + {0xFB85, 0x7AE7}, //7593 #CJK UNIFIED IDEOGRAPH + {0xFB86, 0xFA1C}, //7594 #CJK COMPATIBILITY IDEOGRAPH + {0xFB87, 0x7AEB}, //7595 #CJK UNIFIED IDEOGRAPH + {0xFB88, 0x7B9E}, //7596 #CJK UNIFIED IDEOGRAPH + {0xFB89, 0xFA1D}, //7597 #CJK COMPATIBILITY IDEOGRAPH + {0xFB8A, 0x7D48}, //7598 #CJK UNIFIED IDEOGRAPH + {0xFB8B, 0x7D5C}, //7599 #CJK UNIFIED IDEOGRAPH + {0xFB8C, 0x7DB7}, //7600 #CJK UNIFIED IDEOGRAPH + {0xFB8D, 0x7DA0}, //7601 #CJK UNIFIED IDEOGRAPH + {0xFB8E, 0x7DD6}, //7602 #CJK UNIFIED IDEOGRAPH + {0xFB8F, 0x7E52}, //7603 #CJK UNIFIED IDEOGRAPH + {0xFB90, 0x7F47}, //7604 #CJK UNIFIED IDEOGRAPH + {0xFB91, 0x7FA1}, //7605 #CJK UNIFIED IDEOGRAPH + {0xFB92, 0xFA1E}, //7606 #CJK COMPATIBILITY IDEOGRAPH + {0xFB93, 0x8301}, //7607 #CJK UNIFIED IDEOGRAPH + {0xFB94, 0x8362}, //7608 #CJK UNIFIED IDEOGRAPH + {0xFB95, 0x837F}, //7609 #CJK UNIFIED IDEOGRAPH + {0xFB96, 0x83C7}, //7610 #CJK UNIFIED IDEOGRAPH + {0xFB97, 0x83F6}, //7611 #CJK UNIFIED IDEOGRAPH + {0xFB98, 0x8448}, //7612 #CJK UNIFIED IDEOGRAPH + {0xFB99, 0x84B4}, //7613 #CJK UNIFIED IDEOGRAPH + {0xFB9A, 0x8553}, //7614 #CJK UNIFIED IDEOGRAPH + {0xFB9B, 0x8559}, //7615 #CJK UNIFIED IDEOGRAPH + {0xFB9C, 0x856B}, //7616 #CJK UNIFIED IDEOGRAPH + {0xFB9D, 0xFA1F}, //7617 #CJK COMPATIBILITY IDEOGRAPH + {0xFB9E, 0x85B0}, //7618 #CJK UNIFIED IDEOGRAPH + {0xFB9F, 0xFA20}, //7619 #CJK COMPATIBILITY IDEOGRAPH + {0xFBA0, 0xFA21}, //7620 #CJK COMPATIBILITY IDEOGRAPH + {0xFBA1, 0x8807}, //7621 #CJK UNIFIED IDEOGRAPH + {0xFBA2, 0x88F5}, //7622 #CJK UNIFIED IDEOGRAPH + {0xFBA3, 0x8A12}, //7623 #CJK UNIFIED IDEOGRAPH + {0xFBA4, 0x8A37}, //7624 #CJK UNIFIED IDEOGRAPH + {0xFBA5, 0x8A79}, //7625 #CJK UNIFIED IDEOGRAPH + {0xFBA6, 0x8AA7}, //7626 #CJK UNIFIED IDEOGRAPH + {0xFBA7, 0x8ABE}, //7627 #CJK UNIFIED IDEOGRAPH + {0xFBA8, 0x8ADF}, //7628 #CJK UNIFIED IDEOGRAPH + {0xFBA9, 0xFA22}, //7629 #CJK COMPATIBILITY IDEOGRAPH + {0xFBAA, 0x8AF6}, //7630 #CJK UNIFIED IDEOGRAPH + {0xFBAB, 0x8B53}, //7631 #CJK UNIFIED IDEOGRAPH + {0xFBAC, 0x8B7F}, //7632 #CJK UNIFIED IDEOGRAPH + {0xFBAD, 0x8CF0}, //7633 #CJK UNIFIED IDEOGRAPH + {0xFBAE, 0x8CF4}, //7634 #CJK UNIFIED IDEOGRAPH + {0xFBAF, 0x8D12}, //7635 #CJK UNIFIED IDEOGRAPH + {0xFBB0, 0x8D76}, //7636 #CJK UNIFIED IDEOGRAPH + {0xFBB1, 0xFA23}, //7637 #CJK COMPATIBILITY IDEOGRAPH + {0xFBB2, 0x8ECF}, //7638 #CJK UNIFIED IDEOGRAPH + {0xFBB3, 0xFA24}, //7639 #CJK COMPATIBILITY IDEOGRAPH + {0xFBB4, 0xFA25}, //7640 #CJK COMPATIBILITY IDEOGRAPH + {0xFBB5, 0x9067}, //7641 #CJK UNIFIED IDEOGRAPH + {0xFBB6, 0x90DE}, //7642 #CJK UNIFIED IDEOGRAPH + {0xFBB7, 0xFA26}, //7643 #CJK COMPATIBILITY IDEOGRAPH + {0xFBB8, 0x9115}, //7644 #CJK UNIFIED IDEOGRAPH + {0xFBB9, 0x9127}, //7645 #CJK UNIFIED IDEOGRAPH + {0xFBBA, 0x91DA}, //7646 #CJK UNIFIED IDEOGRAPH + {0xFBBB, 0x91D7}, //7647 #CJK UNIFIED IDEOGRAPH + {0xFBBC, 0x91DE}, //7648 #CJK UNIFIED IDEOGRAPH + {0xFBBD, 0x91ED}, //7649 #CJK UNIFIED IDEOGRAPH + {0xFBBE, 0x91EE}, //7650 #CJK UNIFIED IDEOGRAPH + {0xFBBF, 0x91E4}, //7651 #CJK UNIFIED IDEOGRAPH + {0xFBC0, 0x91E5}, //7652 #CJK UNIFIED IDEOGRAPH + {0xFBC1, 0x9206}, //7653 #CJK UNIFIED IDEOGRAPH + {0xFBC2, 0x9210}, //7654 #CJK UNIFIED IDEOGRAPH + {0xFBC3, 0x920A}, //7655 #CJK UNIFIED IDEOGRAPH + {0xFBC4, 0x923A}, //7656 #CJK UNIFIED IDEOGRAPH + {0xFBC5, 0x9240}, //7657 #CJK UNIFIED IDEOGRAPH + {0xFBC6, 0x923C}, //7658 #CJK UNIFIED IDEOGRAPH + {0xFBC7, 0x924E}, //7659 #CJK UNIFIED IDEOGRAPH + {0xFBC8, 0x9259}, //7660 #CJK UNIFIED IDEOGRAPH + {0xFBC9, 0x9251}, //7661 #CJK UNIFIED IDEOGRAPH + {0xFBCA, 0x9239}, //7662 #CJK UNIFIED IDEOGRAPH + {0xFBCB, 0x9267}, //7663 #CJK UNIFIED IDEOGRAPH + {0xFBCC, 0x92A7}, //7664 #CJK UNIFIED IDEOGRAPH + {0xFBCD, 0x9277}, //7665 #CJK UNIFIED IDEOGRAPH + {0xFBCE, 0x9278}, //7666 #CJK UNIFIED IDEOGRAPH + {0xFBCF, 0x92E7}, //7667 #CJK UNIFIED IDEOGRAPH + {0xFBD0, 0x92D7}, //7668 #CJK UNIFIED IDEOGRAPH + {0xFBD1, 0x92D9}, //7669 #CJK UNIFIED IDEOGRAPH + {0xFBD2, 0x92D0}, //7670 #CJK UNIFIED IDEOGRAPH + {0xFBD3, 0xFA27}, //7671 #CJK COMPATIBILITY IDEOGRAPH + {0xFBD4, 0x92D5}, //7672 #CJK UNIFIED IDEOGRAPH + {0xFBD5, 0x92E0}, //7673 #CJK UNIFIED IDEOGRAPH + {0xFBD6, 0x92D3}, //7674 #CJK UNIFIED IDEOGRAPH + {0xFBD7, 0x9325}, //7675 #CJK UNIFIED IDEOGRAPH + {0xFBD8, 0x9321}, //7676 #CJK UNIFIED IDEOGRAPH + {0xFBD9, 0x92FB}, //7677 #CJK UNIFIED IDEOGRAPH + {0xFBDA, 0xFA28}, //7678 #CJK COMPATIBILITY IDEOGRAPH + {0xFBDB, 0x931E}, //7679 #CJK UNIFIED IDEOGRAPH + {0xFBDC, 0x92FF}, //7680 #CJK UNIFIED IDEOGRAPH + {0xFBDD, 0x931D}, //7681 #CJK UNIFIED IDEOGRAPH + {0xFBDE, 0x9302}, //7682 #CJK UNIFIED IDEOGRAPH + {0xFBDF, 0x9370}, //7683 #CJK UNIFIED IDEOGRAPH + {0xFBE0, 0x9357}, //7684 #CJK UNIFIED IDEOGRAPH + {0xFBE1, 0x93A4}, //7685 #CJK UNIFIED IDEOGRAPH + {0xFBE2, 0x93C6}, //7686 #CJK UNIFIED IDEOGRAPH + {0xFBE3, 0x93DE}, //7687 #CJK UNIFIED IDEOGRAPH + {0xFBE4, 0x93F8}, //7688 #CJK UNIFIED IDEOGRAPH + {0xFBE5, 0x9431}, //7689 #CJK UNIFIED IDEOGRAPH + {0xFBE6, 0x9445}, //7690 #CJK UNIFIED IDEOGRAPH + {0xFBE7, 0x9448}, //7691 #CJK UNIFIED IDEOGRAPH + {0xFBE8, 0x9592}, //7692 #CJK UNIFIED IDEOGRAPH + {0xFBE9, 0xF9DC}, //7693 #CJK COMPATIBILITY IDEOGRAPH + {0xFBEA, 0xFA29}, //7694 #CJK COMPATIBILITY IDEOGRAPH + {0xFBEB, 0x969D}, //7695 #CJK UNIFIED IDEOGRAPH + {0xFBEC, 0x96AF}, //7696 #CJK UNIFIED IDEOGRAPH + {0xFBED, 0x9733}, //7697 #CJK UNIFIED IDEOGRAPH + {0xFBEE, 0x973B}, //7698 #CJK UNIFIED IDEOGRAPH + {0xFBEF, 0x9743}, //7699 #CJK UNIFIED IDEOGRAPH + {0xFBF0, 0x974D}, //7700 #CJK UNIFIED IDEOGRAPH + {0xFBF1, 0x974F}, //7701 #CJK UNIFIED IDEOGRAPH + {0xFBF2, 0x9751}, //7702 #CJK UNIFIED IDEOGRAPH + {0xFBF3, 0x9755}, //7703 #CJK UNIFIED IDEOGRAPH + {0xFBF4, 0x9857}, //7704 #CJK UNIFIED IDEOGRAPH + {0xFBF5, 0x9865}, //7705 #CJK UNIFIED IDEOGRAPH + {0xFBF6, 0xFA2A}, //7706 #CJK COMPATIBILITY IDEOGRAPH + {0xFBF7, 0xFA2B}, //7707 #CJK COMPATIBILITY IDEOGRAPH + {0xFBF8, 0x9927}, //7708 #CJK UNIFIED IDEOGRAPH + {0xFBF9, 0xFA2C}, //7709 #CJK COMPATIBILITY IDEOGRAPH + {0xFBFA, 0x999E}, //7710 #CJK UNIFIED IDEOGRAPH + {0xFBFB, 0x9A4E}, //7711 #CJK UNIFIED IDEOGRAPH + {0xFBFC, 0x9AD9}, //7712 #CJK UNIFIED IDEOGRAPH + {0xFC40, 0x9ADC}, //7713 #CJK UNIFIED IDEOGRAPH + {0xFC41, 0x9B75}, //7714 #CJK UNIFIED IDEOGRAPH + {0xFC42, 0x9B72}, //7715 #CJK UNIFIED IDEOGRAPH + {0xFC43, 0x9B8F}, //7716 #CJK UNIFIED IDEOGRAPH + {0xFC44, 0x9BB1}, //7717 #CJK UNIFIED IDEOGRAPH + {0xFC45, 0x9BBB}, //7718 #CJK UNIFIED IDEOGRAPH + {0xFC46, 0x9C00}, //7719 #CJK UNIFIED IDEOGRAPH + {0xFC47, 0x9D70}, //7720 #CJK UNIFIED IDEOGRAPH + {0xFC48, 0x9D6B}, //7721 #CJK UNIFIED IDEOGRAPH + {0xFC49, 0xFA2D}, //7722 #CJK COMPATIBILITY IDEOGRAPH + {0xFC4A, 0x9E19}, //7723 #CJK UNIFIED IDEOGRAPH + {0xFC4B, 0x9ED1} //7724 #CJK UNIFIED IDEOGRAPH +}; +#endif // DRW_CPTABLE932_H diff --git a/extlib/libdxfrw/intern/drw_cptable936.h b/extlib/libdxfrw/intern/drw_cptable936.h new file mode 100644 index 0000000..9f5fb56 --- /dev/null +++ b/extlib/libdxfrw/intern/drw_cptable936.h @@ -0,0 +1,21943 @@ +#ifndef DRW_CPTABLE936_H +#define DRW_CPTABLE936_H + +//Chinese PRC GBK (XGB) + +//first entry in this tables are 0x80 +#define CPOFFSET936 0x80 +#define CPLENGTH936 21791 +#define NOTFOUND936 0x003F + +//Table 949 one byte +static const int DRW_Table936[] = { + 0x20AC //1 #EURO SIGN 0x80 +// 0xF8F5 //2 #EURO SIGN 0x80 +}; + +//Table 936 +static const int DRW_LeadTable936[] = { + 0, //1#DBCS LEAD BYTE 0x81 + 190, //2#DBCS LEAD BYTE 0x82 + 380, //3#DBCS LEAD BYTE 0x83 + 570, //4#DBCS LEAD BYTE 0x84 + 760, //5#DBCS LEAD BYTE 0x85 + 950, //6#DBCS LEAD BYTE 0x86 + 1140, //7#DBCS LEAD BYTE 0x87 + 1330, //8#DBCS LEAD BYTE 0x88 + 1520, //9#DBCS LEAD BYTE 0x89 + 1710, //10#DBCS LEAD BYTE 0x8A + 1900, //11#DBCS LEAD BYTE 0x8B + 2090, //12#DBCS LEAD BYTE 0x8C + 2280, //13#DBCS LEAD BYTE 0x8D + 2470, //14#DBCS LEAD BYTE 0x8E + 2660, //15#DBCS LEAD BYTE 0x8F + 2850, //16#DBCS LEAD BYTE 0x90 + 3040, //17#DBCS LEAD BYTE 0x91 + 3230, //18#DBCS LEAD BYTE 0x92 + 3420, //19#DBCS LEAD BYTE 0x93 + 3610, //20#DBCS LEAD BYTE 0x94 + 3800, //21#DBCS LEAD BYTE 0x95 + 3990, //22#DBCS LEAD BYTE 0x96 + 4180, //23#DBCS LEAD BYTE 0x97 + 4370, //24#DBCS LEAD BYTE 0x98 + 4560, //25#DBCS LEAD BYTE 0x99 + 4750, //26#DBCS LEAD BYTE 0x9A + 4940, //27#DBCS LEAD BYTE 0x9B + 5130, //28#DBCS LEAD BYTE 0x9C + 5320, //29#DBCS LEAD BYTE 0x9D + 5510, //30#DBCS LEAD BYTE 0x9E + 5700, //31#DBCS LEAD BYTE 0x9F + 5906, //32#DBCS LEAD BYTE 0xA0 + 6080, //33#DBCS LEAD BYTE 0xA1 + 6174, //34#DBCS LEAD BYTE 0xA2 + 6256, //35#DBCS LEAD BYTE 0xA3 + 6350, //36#DBCS LEAD BYTE 0xA4 + 6433, //37#DBCS LEAD BYTE 0xA5 + 6519, //38#DBCS LEAD BYTE 0xA6 + 6586, //39#DBCS LEAD BYTE 0xA7 + 6652, //40#DBCS LEAD BYTE 0xA8 + 6804, //41#DBCS LEAD BYTE 0xA9 + 6948, //42#DBCS LEAD BYTE 0xAA + 7044, //43#DBCS LEAD BYTE 0xAB + 7140, //44#DBCS LEAD BYTE 0xAC + 7236, //45#DBCS LEAD BYTE 0xAD + 7332, //46#DBCS LEAD BYTE 0xAE + 7428, //47#DBCS LEAD BYTE 0xAF + 7524, //48#DBCS LEAD BYTE 0xB0 + 7714, //49#DBCS LEAD BYTE 0xB1 + 7904, //50#DBCS LEAD BYTE 0xB2 + 8094, //51#DBCS LEAD BYTE 0xB3 + 8284, //52#DBCS LEAD BYTE 0xB4 + 8474, //53#DBCS LEAD BYTE 0xB5 + 8664, //54#DBCS LEAD BYTE 0xB6 + 8854, //55#DBCS LEAD BYTE 0xB7 + 9044, //56#DBCS LEAD BYTE 0xB8 + 9224, //57#DBCS LEAD BYTE 0xB9 + 9424, //58#DBCS LEAD BYTE 0xBA + 9614, //59#DBCS LEAD BYTE 0xBB + 9804, //60#DBCS LEAD BYTE 0xBC + 9994, //61#DBCS LEAD BYTE 0xBD + 10184, //62#DBCS LEAD BYTE 0xBE + 10374, //63#DBCS LEAD BYTE 0xBF + 10564, //64#DBCS LEAD BYTE 0xC0 + 10754, //65#DBCS LEAD BYTE 0xC1 + 10944, //66#DBCS LEAD BYTE 0xC2 + 11134, //67#DBCS LEAD BYTE 0xC3 + 11324, //68#DBCS LEAD BYTE 0xC4 + 11514, //69#DBCS LEAD BYTE 0xC5 + 11704, //70#DBCS LEAD BYTE 0xC6 + 11894, //71#DBCS LEAD BYTE 0xC7 + 12084, //72#DBCS LEAD BYTE 0xC8 + 12274, //73#DBCS LEAD BYTE 0xC9 + 12464, //74#DBCS LEAD BYTE 0xCA + 12654, //75#DBCS LEAD BYTE 0xCB + 12844, //76#DBCS LEAD BYTE 0xCC + 13034, //77#DBCS LEAD BYTE 0xCD + 13224, //78#DBCS LEAD BYTE 0xCE + 13414, //79#DBCS LEAD BYTE 0xCF + 13604, //80#DBCS LEAD BYTE 0xD0 + 13794, //81#DBCS LEAD BYTE 0xD1 + 13984, //82#DBCS LEAD BYTE 0xD2 + 14174, //83#DBCS LEAD BYTE 0xD3 + 14364, //84#DBCS LEAD BYTE 0xD4 + 14554, //85#DBCS LEAD BYTE 0xD5 + 14744, //86#DBCS LEAD BYTE 0xD6 + 14934, //87#DBCS LEAD BYTE 0xD7 + 15119, //88#DBCS LEAD BYTE 0xD8 + 15309, //89#DBCS LEAD BYTE 0xD9 + 15499, //90#DBCS LEAD BYTE 0xDA + 15689, //91#DBCS LEAD BYTE 0xDB + 15879, //92#DBCS LEAD BYTE 0xDC + 16069, //93#DBCS LEAD BYTE 0xDD + 16259, //94#DBCS LEAD BYTE 0xDE + 16449, //95#DBCS LEAD BYTE 0xDF + 16639, //96#DBCS LEAD BYTE 0xE0 + 16829, //97#DBCS LEAD BYTE 0xE1 + 17019, //98#DBCS LEAD BYTE 0xE2 + 17209, //99#DBCS LEAD BYTE 0xE3 + 17399, //100#DBCS LEAD BYTE 0xE4 + 17589, //101#DBCS LEAD BYTE 0xE5 + 17779, //102#DBCS LEAD BYTE 0xE6 + 17969, //103#DBCS LEAD BYTE 0xE7 + 18159, //104#DBCS LEAD BYTE 0xE8 + 18349, //105#DBCS LEAD BYTE 0xE9 + 18539, //106#DBCS LEAD BYTE 0xEA + 18729, //107#DBCS LEAD BYTE 0xEB + 18919, //108#DBCS LEAD BYTE 0xEC + 19109, //109#DBCS LEAD BYTE 0xED + 19299, //110#DBCS LEAD BYTE 0xEE + 19489, //111#DBCS LEAD BYTE 0xEF + 19679, //112#DBCS LEAD BYTE 0xF0 + 19869, //113#DBCS LEAD BYTE 0xF1 + 20059, //114#DBCS LEAD BYTE 0xF2 + 20249, //115#DBCS LEAD BYTE 0xF3 + 20439, //116#DBCS LEAD BYTE 0xF4 + 20659, //117#DBCS LEAD BYTE 0xF5 + 20819, //118#DBCS LEAD BYTE 0xF6 + 21009, //119#DBCS LEAD BYTE 0xF7 + 21199, //120#DBCS LEAD BYTE 0xF8 + 21295, //121#DBCS LEAD BYTE 0xF9 + 21391, //122#DBCS LEAD BYTE 0xFA + 21487, //123#DBCS LEAD BYTE 0xFB + 21583, //124#DBCS LEAD BYTE 0xFC + 21679, //125#DBCS LEAD BYTE 0xFD + 21775, //126#DBCS LEAD BYTE 0xFE + 21791, //127#UNDEFINED 0xFF, END OF TABLE +}; + +//Table 936 tail byte +static const int DRW_DoubleTable936[][2] = { + {0x8140, 0x4E02}, //1 #CJK UNIFIED IDEOGRAPH + {0x8141, 0x4E04}, //2 #CJK UNIFIED IDEOGRAPH + {0x8142, 0x4E05}, //3 #CJK UNIFIED IDEOGRAPH + {0x8143, 0x4E06}, //4 #CJK UNIFIED IDEOGRAPH + {0x8144, 0x4E0F}, //5 #CJK UNIFIED IDEOGRAPH + {0x8145, 0x4E12}, //6 #CJK UNIFIED IDEOGRAPH + {0x8146, 0x4E17}, //7 #CJK UNIFIED IDEOGRAPH + {0x8147, 0x4E1F}, //8 #CJK UNIFIED IDEOGRAPH + {0x8148, 0x4E20}, //9 #CJK UNIFIED IDEOGRAPH + {0x8149, 0x4E21}, //10 #CJK UNIFIED IDEOGRAPH + {0x814A, 0x4E23}, //11 #CJK UNIFIED IDEOGRAPH + {0x814B, 0x4E26}, //12 #CJK UNIFIED IDEOGRAPH + {0x814C, 0x4E29}, //13 #CJK UNIFIED IDEOGRAPH + {0x814D, 0x4E2E}, //14 #CJK UNIFIED IDEOGRAPH + {0x814E, 0x4E2F}, //15 #CJK UNIFIED IDEOGRAPH + {0x814F, 0x4E31}, //16 #CJK UNIFIED IDEOGRAPH + {0x8150, 0x4E33}, //17 #CJK UNIFIED IDEOGRAPH + {0x8151, 0x4E35}, //18 #CJK UNIFIED IDEOGRAPH + {0x8152, 0x4E37}, //19 #CJK UNIFIED IDEOGRAPH + {0x8153, 0x4E3C}, //20 #CJK UNIFIED IDEOGRAPH + {0x8154, 0x4E40}, //21 #CJK UNIFIED IDEOGRAPH + {0x8155, 0x4E41}, //22 #CJK UNIFIED IDEOGRAPH + {0x8156, 0x4E42}, //23 #CJK UNIFIED IDEOGRAPH + {0x8157, 0x4E44}, //24 #CJK UNIFIED IDEOGRAPH + {0x8158, 0x4E46}, //25 #CJK UNIFIED IDEOGRAPH + {0x8159, 0x4E4A}, //26 #CJK UNIFIED IDEOGRAPH + {0x815A, 0x4E51}, //27 #CJK UNIFIED IDEOGRAPH + {0x815B, 0x4E55}, //28 #CJK UNIFIED IDEOGRAPH + {0x815C, 0x4E57}, //29 #CJK UNIFIED IDEOGRAPH + {0x815D, 0x4E5A}, //30 #CJK UNIFIED IDEOGRAPH + {0x815E, 0x4E5B}, //31 #CJK UNIFIED IDEOGRAPH + {0x815F, 0x4E62}, //32 #CJK UNIFIED IDEOGRAPH + {0x8160, 0x4E63}, //33 #CJK UNIFIED IDEOGRAPH + {0x8161, 0x4E64}, //34 #CJK UNIFIED IDEOGRAPH + {0x8162, 0x4E65}, //35 #CJK UNIFIED IDEOGRAPH + {0x8163, 0x4E67}, //36 #CJK UNIFIED IDEOGRAPH + {0x8164, 0x4E68}, //37 #CJK UNIFIED IDEOGRAPH + {0x8165, 0x4E6A}, //38 #CJK UNIFIED IDEOGRAPH + {0x8166, 0x4E6B}, //39 #CJK UNIFIED IDEOGRAPH + {0x8167, 0x4E6C}, //40 #CJK UNIFIED IDEOGRAPH + {0x8168, 0x4E6D}, //41 #CJK UNIFIED IDEOGRAPH + {0x8169, 0x4E6E}, //42 #CJK UNIFIED IDEOGRAPH + {0x816A, 0x4E6F}, //43 #CJK UNIFIED IDEOGRAPH + {0x816B, 0x4E72}, //44 #CJK UNIFIED IDEOGRAPH + {0x816C, 0x4E74}, //45 #CJK UNIFIED IDEOGRAPH + {0x816D, 0x4E75}, //46 #CJK UNIFIED IDEOGRAPH + {0x816E, 0x4E76}, //47 #CJK UNIFIED IDEOGRAPH + {0x816F, 0x4E77}, //48 #CJK UNIFIED IDEOGRAPH + {0x8170, 0x4E78}, //49 #CJK UNIFIED IDEOGRAPH + {0x8171, 0x4E79}, //50 #CJK UNIFIED IDEOGRAPH + {0x8172, 0x4E7A}, //51 #CJK UNIFIED IDEOGRAPH + {0x8173, 0x4E7B}, //52 #CJK UNIFIED IDEOGRAPH + {0x8174, 0x4E7C}, //53 #CJK UNIFIED IDEOGRAPH + {0x8175, 0x4E7D}, //54 #CJK UNIFIED IDEOGRAPH + {0x8176, 0x4E7F}, //55 #CJK UNIFIED IDEOGRAPH + {0x8177, 0x4E80}, //56 #CJK UNIFIED IDEOGRAPH + {0x8178, 0x4E81}, //57 #CJK UNIFIED IDEOGRAPH + {0x8179, 0x4E82}, //58 #CJK UNIFIED IDEOGRAPH + {0x817A, 0x4E83}, //59 #CJK UNIFIED IDEOGRAPH + {0x817B, 0x4E84}, //60 #CJK UNIFIED IDEOGRAPH + {0x817C, 0x4E85}, //61 #CJK UNIFIED IDEOGRAPH + {0x817D, 0x4E87}, //62 #CJK UNIFIED IDEOGRAPH + {0x817E, 0x4E8A}, //63 #CJK UNIFIED IDEOGRAPH + {0x8180, 0x4E90}, //64 #CJK UNIFIED IDEOGRAPH + {0x8181, 0x4E96}, //65 #CJK UNIFIED IDEOGRAPH + {0x8182, 0x4E97}, //66 #CJK UNIFIED IDEOGRAPH + {0x8183, 0x4E99}, //67 #CJK UNIFIED IDEOGRAPH + {0x8184, 0x4E9C}, //68 #CJK UNIFIED IDEOGRAPH + {0x8185, 0x4E9D}, //69 #CJK UNIFIED IDEOGRAPH + {0x8186, 0x4E9E}, //70 #CJK UNIFIED IDEOGRAPH + {0x8187, 0x4EA3}, //71 #CJK UNIFIED IDEOGRAPH + {0x8188, 0x4EAA}, //72 #CJK UNIFIED IDEOGRAPH + {0x8189, 0x4EAF}, //73 #CJK UNIFIED IDEOGRAPH + {0x818A, 0x4EB0}, //74 #CJK UNIFIED IDEOGRAPH + {0x818B, 0x4EB1}, //75 #CJK UNIFIED IDEOGRAPH + {0x818C, 0x4EB4}, //76 #CJK UNIFIED IDEOGRAPH + {0x818D, 0x4EB6}, //77 #CJK UNIFIED IDEOGRAPH + {0x818E, 0x4EB7}, //78 #CJK UNIFIED IDEOGRAPH + {0x818F, 0x4EB8}, //79 #CJK UNIFIED IDEOGRAPH + {0x8190, 0x4EB9}, //80 #CJK UNIFIED IDEOGRAPH + {0x8191, 0x4EBC}, //81 #CJK UNIFIED IDEOGRAPH + {0x8192, 0x4EBD}, //82 #CJK UNIFIED IDEOGRAPH + {0x8193, 0x4EBE}, //83 #CJK UNIFIED IDEOGRAPH + {0x8194, 0x4EC8}, //84 #CJK UNIFIED IDEOGRAPH + {0x8195, 0x4ECC}, //85 #CJK UNIFIED IDEOGRAPH + {0x8196, 0x4ECF}, //86 #CJK UNIFIED IDEOGRAPH + {0x8197, 0x4ED0}, //87 #CJK UNIFIED IDEOGRAPH + {0x8198, 0x4ED2}, //88 #CJK UNIFIED IDEOGRAPH + {0x8199, 0x4EDA}, //89 #CJK UNIFIED IDEOGRAPH + {0x819A, 0x4EDB}, //90 #CJK UNIFIED IDEOGRAPH + {0x819B, 0x4EDC}, //91 #CJK UNIFIED IDEOGRAPH + {0x819C, 0x4EE0}, //92 #CJK UNIFIED IDEOGRAPH + {0x819D, 0x4EE2}, //93 #CJK UNIFIED IDEOGRAPH + {0x819E, 0x4EE6}, //94 #CJK UNIFIED IDEOGRAPH + {0x819F, 0x4EE7}, //95 #CJK UNIFIED IDEOGRAPH + {0x81A0, 0x4EE9}, //96 #CJK UNIFIED IDEOGRAPH + {0x81A1, 0x4EED}, //97 #CJK UNIFIED IDEOGRAPH + {0x81A2, 0x4EEE}, //98 #CJK UNIFIED IDEOGRAPH + {0x81A3, 0x4EEF}, //99 #CJK UNIFIED IDEOGRAPH + {0x81A4, 0x4EF1}, //100 #CJK UNIFIED IDEOGRAPH + {0x81A5, 0x4EF4}, //101 #CJK UNIFIED IDEOGRAPH + {0x81A6, 0x4EF8}, //102 #CJK UNIFIED IDEOGRAPH + {0x81A7, 0x4EF9}, //103 #CJK UNIFIED IDEOGRAPH + {0x81A8, 0x4EFA}, //104 #CJK UNIFIED IDEOGRAPH + {0x81A9, 0x4EFC}, //105 #CJK UNIFIED IDEOGRAPH + {0x81AA, 0x4EFE}, //106 #CJK UNIFIED IDEOGRAPH + {0x81AB, 0x4F00}, //107 #CJK UNIFIED IDEOGRAPH + {0x81AC, 0x4F02}, //108 #CJK UNIFIED IDEOGRAPH + {0x81AD, 0x4F03}, //109 #CJK UNIFIED IDEOGRAPH + {0x81AE, 0x4F04}, //110 #CJK UNIFIED IDEOGRAPH + {0x81AF, 0x4F05}, //111 #CJK UNIFIED IDEOGRAPH + {0x81B0, 0x4F06}, //112 #CJK UNIFIED IDEOGRAPH + {0x81B1, 0x4F07}, //113 #CJK UNIFIED IDEOGRAPH + {0x81B2, 0x4F08}, //114 #CJK UNIFIED IDEOGRAPH + {0x81B3, 0x4F0B}, //115 #CJK UNIFIED IDEOGRAPH + {0x81B4, 0x4F0C}, //116 #CJK UNIFIED IDEOGRAPH + {0x81B5, 0x4F12}, //117 #CJK UNIFIED IDEOGRAPH + {0x81B6, 0x4F13}, //118 #CJK UNIFIED IDEOGRAPH + {0x81B7, 0x4F14}, //119 #CJK UNIFIED IDEOGRAPH + {0x81B8, 0x4F15}, //120 #CJK UNIFIED IDEOGRAPH + {0x81B9, 0x4F16}, //121 #CJK UNIFIED IDEOGRAPH + {0x81BA, 0x4F1C}, //122 #CJK UNIFIED IDEOGRAPH + {0x81BB, 0x4F1D}, //123 #CJK UNIFIED IDEOGRAPH + {0x81BC, 0x4F21}, //124 #CJK UNIFIED IDEOGRAPH + {0x81BD, 0x4F23}, //125 #CJK UNIFIED IDEOGRAPH + {0x81BE, 0x4F28}, //126 #CJK UNIFIED IDEOGRAPH + {0x81BF, 0x4F29}, //127 #CJK UNIFIED IDEOGRAPH + {0x81C0, 0x4F2C}, //128 #CJK UNIFIED IDEOGRAPH + {0x81C1, 0x4F2D}, //129 #CJK UNIFIED IDEOGRAPH + {0x81C2, 0x4F2E}, //130 #CJK UNIFIED IDEOGRAPH + {0x81C3, 0x4F31}, //131 #CJK UNIFIED IDEOGRAPH + {0x81C4, 0x4F33}, //132 #CJK UNIFIED IDEOGRAPH + {0x81C5, 0x4F35}, //133 #CJK UNIFIED IDEOGRAPH + {0x81C6, 0x4F37}, //134 #CJK UNIFIED IDEOGRAPH + {0x81C7, 0x4F39}, //135 #CJK UNIFIED IDEOGRAPH + {0x81C8, 0x4F3B}, //136 #CJK UNIFIED IDEOGRAPH + {0x81C9, 0x4F3E}, //137 #CJK UNIFIED IDEOGRAPH + {0x81CA, 0x4F3F}, //138 #CJK UNIFIED IDEOGRAPH + {0x81CB, 0x4F40}, //139 #CJK UNIFIED IDEOGRAPH + {0x81CC, 0x4F41}, //140 #CJK UNIFIED IDEOGRAPH + {0x81CD, 0x4F42}, //141 #CJK UNIFIED IDEOGRAPH + {0x81CE, 0x4F44}, //142 #CJK UNIFIED IDEOGRAPH + {0x81CF, 0x4F45}, //143 #CJK UNIFIED IDEOGRAPH + {0x81D0, 0x4F47}, //144 #CJK UNIFIED IDEOGRAPH + {0x81D1, 0x4F48}, //145 #CJK UNIFIED IDEOGRAPH + {0x81D2, 0x4F49}, //146 #CJK UNIFIED IDEOGRAPH + {0x81D3, 0x4F4A}, //147 #CJK UNIFIED IDEOGRAPH + {0x81D4, 0x4F4B}, //148 #CJK UNIFIED IDEOGRAPH + {0x81D5, 0x4F4C}, //149 #CJK UNIFIED IDEOGRAPH + {0x81D6, 0x4F52}, //150 #CJK UNIFIED IDEOGRAPH + {0x81D7, 0x4F54}, //151 #CJK UNIFIED IDEOGRAPH + {0x81D8, 0x4F56}, //152 #CJK UNIFIED IDEOGRAPH + {0x81D9, 0x4F61}, //153 #CJK UNIFIED IDEOGRAPH + {0x81DA, 0x4F62}, //154 #CJK UNIFIED IDEOGRAPH + {0x81DB, 0x4F66}, //155 #CJK UNIFIED IDEOGRAPH + {0x81DC, 0x4F68}, //156 #CJK UNIFIED IDEOGRAPH + {0x81DD, 0x4F6A}, //157 #CJK UNIFIED IDEOGRAPH + {0x81DE, 0x4F6B}, //158 #CJK UNIFIED IDEOGRAPH + {0x81DF, 0x4F6D}, //159 #CJK UNIFIED IDEOGRAPH + {0x81E0, 0x4F6E}, //160 #CJK UNIFIED IDEOGRAPH + {0x81E1, 0x4F71}, //161 #CJK UNIFIED IDEOGRAPH + {0x81E2, 0x4F72}, //162 #CJK UNIFIED IDEOGRAPH + {0x81E3, 0x4F75}, //163 #CJK UNIFIED IDEOGRAPH + {0x81E4, 0x4F77}, //164 #CJK UNIFIED IDEOGRAPH + {0x81E5, 0x4F78}, //165 #CJK UNIFIED IDEOGRAPH + {0x81E6, 0x4F79}, //166 #CJK UNIFIED IDEOGRAPH + {0x81E7, 0x4F7A}, //167 #CJK UNIFIED IDEOGRAPH + {0x81E8, 0x4F7D}, //168 #CJK UNIFIED IDEOGRAPH + {0x81E9, 0x4F80}, //169 #CJK UNIFIED IDEOGRAPH + {0x81EA, 0x4F81}, //170 #CJK UNIFIED IDEOGRAPH + {0x81EB, 0x4F82}, //171 #CJK UNIFIED IDEOGRAPH + {0x81EC, 0x4F85}, //172 #CJK UNIFIED IDEOGRAPH + {0x81ED, 0x4F86}, //173 #CJK UNIFIED IDEOGRAPH + {0x81EE, 0x4F87}, //174 #CJK UNIFIED IDEOGRAPH + {0x81EF, 0x4F8A}, //175 #CJK UNIFIED IDEOGRAPH + {0x81F0, 0x4F8C}, //176 #CJK UNIFIED IDEOGRAPH + {0x81F1, 0x4F8E}, //177 #CJK UNIFIED IDEOGRAPH + {0x81F2, 0x4F90}, //178 #CJK UNIFIED IDEOGRAPH + {0x81F3, 0x4F92}, //179 #CJK UNIFIED IDEOGRAPH + {0x81F4, 0x4F93}, //180 #CJK UNIFIED IDEOGRAPH + {0x81F5, 0x4F95}, //181 #CJK UNIFIED IDEOGRAPH + {0x81F6, 0x4F96}, //182 #CJK UNIFIED IDEOGRAPH + {0x81F7, 0x4F98}, //183 #CJK UNIFIED IDEOGRAPH + {0x81F8, 0x4F99}, //184 #CJK UNIFIED IDEOGRAPH + {0x81F9, 0x4F9A}, //185 #CJK UNIFIED IDEOGRAPH + {0x81FA, 0x4F9C}, //186 #CJK UNIFIED IDEOGRAPH + {0x81FB, 0x4F9E}, //187 #CJK UNIFIED IDEOGRAPH + {0x81FC, 0x4F9F}, //188 #CJK UNIFIED IDEOGRAPH + {0x81FD, 0x4FA1}, //189 #CJK UNIFIED IDEOGRAPH + {0x81FE, 0x4FA2}, //190 #CJK UNIFIED IDEOGRAPH + {0x8240, 0x4FA4}, //191 #CJK UNIFIED IDEOGRAPH + {0x8241, 0x4FAB}, //192 #CJK UNIFIED IDEOGRAPH + {0x8242, 0x4FAD}, //193 #CJK UNIFIED IDEOGRAPH + {0x8243, 0x4FB0}, //194 #CJK UNIFIED IDEOGRAPH + {0x8244, 0x4FB1}, //195 #CJK UNIFIED IDEOGRAPH + {0x8245, 0x4FB2}, //196 #CJK UNIFIED IDEOGRAPH + {0x8246, 0x4FB3}, //197 #CJK UNIFIED IDEOGRAPH + {0x8247, 0x4FB4}, //198 #CJK UNIFIED IDEOGRAPH + {0x8248, 0x4FB6}, //199 #CJK UNIFIED IDEOGRAPH + {0x8249, 0x4FB7}, //200 #CJK UNIFIED IDEOGRAPH + {0x824A, 0x4FB8}, //201 #CJK UNIFIED IDEOGRAPH + {0x824B, 0x4FB9}, //202 #CJK UNIFIED IDEOGRAPH + {0x824C, 0x4FBA}, //203 #CJK UNIFIED IDEOGRAPH + {0x824D, 0x4FBB}, //204 #CJK UNIFIED IDEOGRAPH + {0x824E, 0x4FBC}, //205 #CJK UNIFIED IDEOGRAPH + {0x824F, 0x4FBD}, //206 #CJK UNIFIED IDEOGRAPH + {0x8250, 0x4FBE}, //207 #CJK UNIFIED IDEOGRAPH + {0x8251, 0x4FC0}, //208 #CJK UNIFIED IDEOGRAPH + {0x8252, 0x4FC1}, //209 #CJK UNIFIED IDEOGRAPH + {0x8253, 0x4FC2}, //210 #CJK UNIFIED IDEOGRAPH + {0x8254, 0x4FC6}, //211 #CJK UNIFIED IDEOGRAPH + {0x8255, 0x4FC7}, //212 #CJK UNIFIED IDEOGRAPH + {0x8256, 0x4FC8}, //213 #CJK UNIFIED IDEOGRAPH + {0x8257, 0x4FC9}, //214 #CJK UNIFIED IDEOGRAPH + {0x8258, 0x4FCB}, //215 #CJK UNIFIED IDEOGRAPH + {0x8259, 0x4FCC}, //216 #CJK UNIFIED IDEOGRAPH + {0x825A, 0x4FCD}, //217 #CJK UNIFIED IDEOGRAPH + {0x825B, 0x4FD2}, //218 #CJK UNIFIED IDEOGRAPH + {0x825C, 0x4FD3}, //219 #CJK UNIFIED IDEOGRAPH + {0x825D, 0x4FD4}, //220 #CJK UNIFIED IDEOGRAPH + {0x825E, 0x4FD5}, //221 #CJK UNIFIED IDEOGRAPH + {0x825F, 0x4FD6}, //222 #CJK UNIFIED IDEOGRAPH + {0x8260, 0x4FD9}, //223 #CJK UNIFIED IDEOGRAPH + {0x8261, 0x4FDB}, //224 #CJK UNIFIED IDEOGRAPH + {0x8262, 0x4FE0}, //225 #CJK UNIFIED IDEOGRAPH + {0x8263, 0x4FE2}, //226 #CJK UNIFIED IDEOGRAPH + {0x8264, 0x4FE4}, //227 #CJK UNIFIED IDEOGRAPH + {0x8265, 0x4FE5}, //228 #CJK UNIFIED IDEOGRAPH + {0x8266, 0x4FE7}, //229 #CJK UNIFIED IDEOGRAPH + {0x8267, 0x4FEB}, //230 #CJK UNIFIED IDEOGRAPH + {0x8268, 0x4FEC}, //231 #CJK UNIFIED IDEOGRAPH + {0x8269, 0x4FF0}, //232 #CJK UNIFIED IDEOGRAPH + {0x826A, 0x4FF2}, //233 #CJK UNIFIED IDEOGRAPH + {0x826B, 0x4FF4}, //234 #CJK UNIFIED IDEOGRAPH + {0x826C, 0x4FF5}, //235 #CJK UNIFIED IDEOGRAPH + {0x826D, 0x4FF6}, //236 #CJK UNIFIED IDEOGRAPH + {0x826E, 0x4FF7}, //237 #CJK UNIFIED IDEOGRAPH + {0x826F, 0x4FF9}, //238 #CJK UNIFIED IDEOGRAPH + {0x8270, 0x4FFB}, //239 #CJK UNIFIED IDEOGRAPH + {0x8271, 0x4FFC}, //240 #CJK UNIFIED IDEOGRAPH + {0x8272, 0x4FFD}, //241 #CJK UNIFIED IDEOGRAPH + {0x8273, 0x4FFF}, //242 #CJK UNIFIED IDEOGRAPH + {0x8274, 0x5000}, //243 #CJK UNIFIED IDEOGRAPH + {0x8275, 0x5001}, //244 #CJK UNIFIED IDEOGRAPH + {0x8276, 0x5002}, //245 #CJK UNIFIED IDEOGRAPH + {0x8277, 0x5003}, //246 #CJK UNIFIED IDEOGRAPH + {0x8278, 0x5004}, //247 #CJK UNIFIED IDEOGRAPH + {0x8279, 0x5005}, //248 #CJK UNIFIED IDEOGRAPH + {0x827A, 0x5006}, //249 #CJK UNIFIED IDEOGRAPH + {0x827B, 0x5007}, //250 #CJK UNIFIED IDEOGRAPH + {0x827C, 0x5008}, //251 #CJK UNIFIED IDEOGRAPH + {0x827D, 0x5009}, //252 #CJK UNIFIED IDEOGRAPH + {0x827E, 0x500A}, //253 #CJK UNIFIED IDEOGRAPH + {0x8280, 0x500B}, //254 #CJK UNIFIED IDEOGRAPH + {0x8281, 0x500E}, //255 #CJK UNIFIED IDEOGRAPH + {0x8282, 0x5010}, //256 #CJK UNIFIED IDEOGRAPH + {0x8283, 0x5011}, //257 #CJK UNIFIED IDEOGRAPH + {0x8284, 0x5013}, //258 #CJK UNIFIED IDEOGRAPH + {0x8285, 0x5015}, //259 #CJK UNIFIED IDEOGRAPH + {0x8286, 0x5016}, //260 #CJK UNIFIED IDEOGRAPH + {0x8287, 0x5017}, //261 #CJK UNIFIED IDEOGRAPH + {0x8288, 0x501B}, //262 #CJK UNIFIED IDEOGRAPH + {0x8289, 0x501D}, //263 #CJK UNIFIED IDEOGRAPH + {0x828A, 0x501E}, //264 #CJK UNIFIED IDEOGRAPH + {0x828B, 0x5020}, //265 #CJK UNIFIED IDEOGRAPH + {0x828C, 0x5022}, //266 #CJK UNIFIED IDEOGRAPH + {0x828D, 0x5023}, //267 #CJK UNIFIED IDEOGRAPH + {0x828E, 0x5024}, //268 #CJK UNIFIED IDEOGRAPH + {0x828F, 0x5027}, //269 #CJK UNIFIED IDEOGRAPH + {0x8290, 0x502B}, //270 #CJK UNIFIED IDEOGRAPH + {0x8291, 0x502F}, //271 #CJK UNIFIED IDEOGRAPH + {0x8292, 0x5030}, //272 #CJK UNIFIED IDEOGRAPH + {0x8293, 0x5031}, //273 #CJK UNIFIED IDEOGRAPH + {0x8294, 0x5032}, //274 #CJK UNIFIED IDEOGRAPH + {0x8295, 0x5033}, //275 #CJK UNIFIED IDEOGRAPH + {0x8296, 0x5034}, //276 #CJK UNIFIED IDEOGRAPH + {0x8297, 0x5035}, //277 #CJK UNIFIED IDEOGRAPH + {0x8298, 0x5036}, //278 #CJK UNIFIED IDEOGRAPH + {0x8299, 0x5037}, //279 #CJK UNIFIED IDEOGRAPH + {0x829A, 0x5038}, //280 #CJK UNIFIED IDEOGRAPH + {0x829B, 0x5039}, //281 #CJK UNIFIED IDEOGRAPH + {0x829C, 0x503B}, //282 #CJK UNIFIED IDEOGRAPH + {0x829D, 0x503D}, //283 #CJK UNIFIED IDEOGRAPH + {0x829E, 0x503F}, //284 #CJK UNIFIED IDEOGRAPH + {0x829F, 0x5040}, //285 #CJK UNIFIED IDEOGRAPH + {0x82A0, 0x5041}, //286 #CJK UNIFIED IDEOGRAPH + {0x82A1, 0x5042}, //287 #CJK UNIFIED IDEOGRAPH + {0x82A2, 0x5044}, //288 #CJK UNIFIED IDEOGRAPH + {0x82A3, 0x5045}, //289 #CJK UNIFIED IDEOGRAPH + {0x82A4, 0x5046}, //290 #CJK UNIFIED IDEOGRAPH + {0x82A5, 0x5049}, //291 #CJK UNIFIED IDEOGRAPH + {0x82A6, 0x504A}, //292 #CJK UNIFIED IDEOGRAPH + {0x82A7, 0x504B}, //293 #CJK UNIFIED IDEOGRAPH + {0x82A8, 0x504D}, //294 #CJK UNIFIED IDEOGRAPH + {0x82A9, 0x5050}, //295 #CJK UNIFIED IDEOGRAPH + {0x82AA, 0x5051}, //296 #CJK UNIFIED IDEOGRAPH + {0x82AB, 0x5052}, //297 #CJK UNIFIED IDEOGRAPH + {0x82AC, 0x5053}, //298 #CJK UNIFIED IDEOGRAPH + {0x82AD, 0x5054}, //299 #CJK UNIFIED IDEOGRAPH + {0x82AE, 0x5056}, //300 #CJK UNIFIED IDEOGRAPH + {0x82AF, 0x5057}, //301 #CJK UNIFIED IDEOGRAPH + {0x82B0, 0x5058}, //302 #CJK UNIFIED IDEOGRAPH + {0x82B1, 0x5059}, //303 #CJK UNIFIED IDEOGRAPH + {0x82B2, 0x505B}, //304 #CJK UNIFIED IDEOGRAPH + {0x82B3, 0x505D}, //305 #CJK UNIFIED IDEOGRAPH + {0x82B4, 0x505E}, //306 #CJK UNIFIED IDEOGRAPH + {0x82B5, 0x505F}, //307 #CJK UNIFIED IDEOGRAPH + {0x82B6, 0x5060}, //308 #CJK UNIFIED IDEOGRAPH + {0x82B7, 0x5061}, //309 #CJK UNIFIED IDEOGRAPH + {0x82B8, 0x5062}, //310 #CJK UNIFIED IDEOGRAPH + {0x82B9, 0x5063}, //311 #CJK UNIFIED IDEOGRAPH + {0x82BA, 0x5064}, //312 #CJK UNIFIED IDEOGRAPH + {0x82BB, 0x5066}, //313 #CJK UNIFIED IDEOGRAPH + {0x82BC, 0x5067}, //314 #CJK UNIFIED IDEOGRAPH + {0x82BD, 0x5068}, //315 #CJK UNIFIED IDEOGRAPH + {0x82BE, 0x5069}, //316 #CJK UNIFIED IDEOGRAPH + {0x82BF, 0x506A}, //317 #CJK UNIFIED IDEOGRAPH + {0x82C0, 0x506B}, //318 #CJK UNIFIED IDEOGRAPH + {0x82C1, 0x506D}, //319 #CJK UNIFIED IDEOGRAPH + {0x82C2, 0x506E}, //320 #CJK UNIFIED IDEOGRAPH + {0x82C3, 0x506F}, //321 #CJK UNIFIED IDEOGRAPH + {0x82C4, 0x5070}, //322 #CJK UNIFIED IDEOGRAPH + {0x82C5, 0x5071}, //323 #CJK UNIFIED IDEOGRAPH + {0x82C6, 0x5072}, //324 #CJK UNIFIED IDEOGRAPH + {0x82C7, 0x5073}, //325 #CJK UNIFIED IDEOGRAPH + {0x82C8, 0x5074}, //326 #CJK UNIFIED IDEOGRAPH + {0x82C9, 0x5075}, //327 #CJK UNIFIED IDEOGRAPH + {0x82CA, 0x5078}, //328 #CJK UNIFIED IDEOGRAPH + {0x82CB, 0x5079}, //329 #CJK UNIFIED IDEOGRAPH + {0x82CC, 0x507A}, //330 #CJK UNIFIED IDEOGRAPH + {0x82CD, 0x507C}, //331 #CJK UNIFIED IDEOGRAPH + {0x82CE, 0x507D}, //332 #CJK UNIFIED IDEOGRAPH + {0x82CF, 0x5081}, //333 #CJK UNIFIED IDEOGRAPH + {0x82D0, 0x5082}, //334 #CJK UNIFIED IDEOGRAPH + {0x82D1, 0x5083}, //335 #CJK UNIFIED IDEOGRAPH + {0x82D2, 0x5084}, //336 #CJK UNIFIED IDEOGRAPH + {0x82D3, 0x5086}, //337 #CJK UNIFIED IDEOGRAPH + {0x82D4, 0x5087}, //338 #CJK UNIFIED IDEOGRAPH + {0x82D5, 0x5089}, //339 #CJK UNIFIED IDEOGRAPH + {0x82D6, 0x508A}, //340 #CJK UNIFIED IDEOGRAPH + {0x82D7, 0x508B}, //341 #CJK UNIFIED IDEOGRAPH + {0x82D8, 0x508C}, //342 #CJK UNIFIED IDEOGRAPH + {0x82D9, 0x508E}, //343 #CJK UNIFIED IDEOGRAPH + {0x82DA, 0x508F}, //344 #CJK UNIFIED IDEOGRAPH + {0x82DB, 0x5090}, //345 #CJK UNIFIED IDEOGRAPH + {0x82DC, 0x5091}, //346 #CJK UNIFIED IDEOGRAPH + {0x82DD, 0x5092}, //347 #CJK UNIFIED IDEOGRAPH + {0x82DE, 0x5093}, //348 #CJK UNIFIED IDEOGRAPH + {0x82DF, 0x5094}, //349 #CJK UNIFIED IDEOGRAPH + {0x82E0, 0x5095}, //350 #CJK UNIFIED IDEOGRAPH + {0x82E1, 0x5096}, //351 #CJK UNIFIED IDEOGRAPH + {0x82E2, 0x5097}, //352 #CJK UNIFIED IDEOGRAPH + {0x82E3, 0x5098}, //353 #CJK UNIFIED IDEOGRAPH + {0x82E4, 0x5099}, //354 #CJK UNIFIED IDEOGRAPH + {0x82E5, 0x509A}, //355 #CJK UNIFIED IDEOGRAPH + {0x82E6, 0x509B}, //356 #CJK UNIFIED IDEOGRAPH + {0x82E7, 0x509C}, //357 #CJK UNIFIED IDEOGRAPH + {0x82E8, 0x509D}, //358 #CJK UNIFIED IDEOGRAPH + {0x82E9, 0x509E}, //359 #CJK UNIFIED IDEOGRAPH + {0x82EA, 0x509F}, //360 #CJK UNIFIED IDEOGRAPH + {0x82EB, 0x50A0}, //361 #CJK UNIFIED IDEOGRAPH + {0x82EC, 0x50A1}, //362 #CJK UNIFIED IDEOGRAPH + {0x82ED, 0x50A2}, //363 #CJK UNIFIED IDEOGRAPH + {0x82EE, 0x50A4}, //364 #CJK UNIFIED IDEOGRAPH + {0x82EF, 0x50A6}, //365 #CJK UNIFIED IDEOGRAPH + {0x82F0, 0x50AA}, //366 #CJK UNIFIED IDEOGRAPH + {0x82F1, 0x50AB}, //367 #CJK UNIFIED IDEOGRAPH + {0x82F2, 0x50AD}, //368 #CJK UNIFIED IDEOGRAPH + {0x82F3, 0x50AE}, //369 #CJK UNIFIED IDEOGRAPH + {0x82F4, 0x50AF}, //370 #CJK UNIFIED IDEOGRAPH + {0x82F5, 0x50B0}, //371 #CJK UNIFIED IDEOGRAPH + {0x82F6, 0x50B1}, //372 #CJK UNIFIED IDEOGRAPH + {0x82F7, 0x50B3}, //373 #CJK UNIFIED IDEOGRAPH + {0x82F8, 0x50B4}, //374 #CJK UNIFIED IDEOGRAPH + {0x82F9, 0x50B5}, //375 #CJK UNIFIED IDEOGRAPH + {0x82FA, 0x50B6}, //376 #CJK UNIFIED IDEOGRAPH + {0x82FB, 0x50B7}, //377 #CJK UNIFIED IDEOGRAPH + {0x82FC, 0x50B8}, //378 #CJK UNIFIED IDEOGRAPH + {0x82FD, 0x50B9}, //379 #CJK UNIFIED IDEOGRAPH + {0x82FE, 0x50BC}, //380 #CJK UNIFIED IDEOGRAPH + {0x8340, 0x50BD}, //381 #CJK UNIFIED IDEOGRAPH + {0x8341, 0x50BE}, //382 #CJK UNIFIED IDEOGRAPH + {0x8342, 0x50BF}, //383 #CJK UNIFIED IDEOGRAPH + {0x8343, 0x50C0}, //384 #CJK UNIFIED IDEOGRAPH + {0x8344, 0x50C1}, //385 #CJK UNIFIED IDEOGRAPH + {0x8345, 0x50C2}, //386 #CJK UNIFIED IDEOGRAPH + {0x8346, 0x50C3}, //387 #CJK UNIFIED IDEOGRAPH + {0x8347, 0x50C4}, //388 #CJK UNIFIED IDEOGRAPH + {0x8348, 0x50C5}, //389 #CJK UNIFIED IDEOGRAPH + {0x8349, 0x50C6}, //390 #CJK UNIFIED IDEOGRAPH + {0x834A, 0x50C7}, //391 #CJK UNIFIED IDEOGRAPH + {0x834B, 0x50C8}, //392 #CJK UNIFIED IDEOGRAPH + {0x834C, 0x50C9}, //393 #CJK UNIFIED IDEOGRAPH + {0x834D, 0x50CA}, //394 #CJK UNIFIED IDEOGRAPH + {0x834E, 0x50CB}, //395 #CJK UNIFIED IDEOGRAPH + {0x834F, 0x50CC}, //396 #CJK UNIFIED IDEOGRAPH + {0x8350, 0x50CD}, //397 #CJK UNIFIED IDEOGRAPH + {0x8351, 0x50CE}, //398 #CJK UNIFIED IDEOGRAPH + {0x8352, 0x50D0}, //399 #CJK UNIFIED IDEOGRAPH + {0x8353, 0x50D1}, //400 #CJK UNIFIED IDEOGRAPH + {0x8354, 0x50D2}, //401 #CJK UNIFIED IDEOGRAPH + {0x8355, 0x50D3}, //402 #CJK UNIFIED IDEOGRAPH + {0x8356, 0x50D4}, //403 #CJK UNIFIED IDEOGRAPH + {0x8357, 0x50D5}, //404 #CJK UNIFIED IDEOGRAPH + {0x8358, 0x50D7}, //405 #CJK UNIFIED IDEOGRAPH + {0x8359, 0x50D8}, //406 #CJK UNIFIED IDEOGRAPH + {0x835A, 0x50D9}, //407 #CJK UNIFIED IDEOGRAPH + {0x835B, 0x50DB}, //408 #CJK UNIFIED IDEOGRAPH + {0x835C, 0x50DC}, //409 #CJK UNIFIED IDEOGRAPH + {0x835D, 0x50DD}, //410 #CJK UNIFIED IDEOGRAPH + {0x835E, 0x50DE}, //411 #CJK UNIFIED IDEOGRAPH + {0x835F, 0x50DF}, //412 #CJK UNIFIED IDEOGRAPH + {0x8360, 0x50E0}, //413 #CJK UNIFIED IDEOGRAPH + {0x8361, 0x50E1}, //414 #CJK UNIFIED IDEOGRAPH + {0x8362, 0x50E2}, //415 #CJK UNIFIED IDEOGRAPH + {0x8363, 0x50E3}, //416 #CJK UNIFIED IDEOGRAPH + {0x8364, 0x50E4}, //417 #CJK UNIFIED IDEOGRAPH + {0x8365, 0x50E5}, //418 #CJK UNIFIED IDEOGRAPH + {0x8366, 0x50E8}, //419 #CJK UNIFIED IDEOGRAPH + {0x8367, 0x50E9}, //420 #CJK UNIFIED IDEOGRAPH + {0x8368, 0x50EA}, //421 #CJK UNIFIED IDEOGRAPH + {0x8369, 0x50EB}, //422 #CJK UNIFIED IDEOGRAPH + {0x836A, 0x50EF}, //423 #CJK UNIFIED IDEOGRAPH + {0x836B, 0x50F0}, //424 #CJK UNIFIED IDEOGRAPH + {0x836C, 0x50F1}, //425 #CJK UNIFIED IDEOGRAPH + {0x836D, 0x50F2}, //426 #CJK UNIFIED IDEOGRAPH + {0x836E, 0x50F4}, //427 #CJK UNIFIED IDEOGRAPH + {0x836F, 0x50F6}, //428 #CJK UNIFIED IDEOGRAPH + {0x8370, 0x50F7}, //429 #CJK UNIFIED IDEOGRAPH + {0x8371, 0x50F8}, //430 #CJK UNIFIED IDEOGRAPH + {0x8372, 0x50F9}, //431 #CJK UNIFIED IDEOGRAPH + {0x8373, 0x50FA}, //432 #CJK UNIFIED IDEOGRAPH + {0x8374, 0x50FC}, //433 #CJK UNIFIED IDEOGRAPH + {0x8375, 0x50FD}, //434 #CJK UNIFIED IDEOGRAPH + {0x8376, 0x50FE}, //435 #CJK UNIFIED IDEOGRAPH + {0x8377, 0x50FF}, //436 #CJK UNIFIED IDEOGRAPH + {0x8378, 0x5100}, //437 #CJK UNIFIED IDEOGRAPH + {0x8379, 0x5101}, //438 #CJK UNIFIED IDEOGRAPH + {0x837A, 0x5102}, //439 #CJK UNIFIED IDEOGRAPH + {0x837B, 0x5103}, //440 #CJK UNIFIED IDEOGRAPH + {0x837C, 0x5104}, //441 #CJK UNIFIED IDEOGRAPH + {0x837D, 0x5105}, //442 #CJK UNIFIED IDEOGRAPH + {0x837E, 0x5108}, //443 #CJK UNIFIED IDEOGRAPH + {0x8380, 0x5109}, //444 #CJK UNIFIED IDEOGRAPH + {0x8381, 0x510A}, //445 #CJK UNIFIED IDEOGRAPH + {0x8382, 0x510C}, //446 #CJK UNIFIED IDEOGRAPH + {0x8383, 0x510D}, //447 #CJK UNIFIED IDEOGRAPH + {0x8384, 0x510E}, //448 #CJK UNIFIED IDEOGRAPH + {0x8385, 0x510F}, //449 #CJK UNIFIED IDEOGRAPH + {0x8386, 0x5110}, //450 #CJK UNIFIED IDEOGRAPH + {0x8387, 0x5111}, //451 #CJK UNIFIED IDEOGRAPH + {0x8388, 0x5113}, //452 #CJK UNIFIED IDEOGRAPH + {0x8389, 0x5114}, //453 #CJK UNIFIED IDEOGRAPH + {0x838A, 0x5115}, //454 #CJK UNIFIED IDEOGRAPH + {0x838B, 0x5116}, //455 #CJK UNIFIED IDEOGRAPH + {0x838C, 0x5117}, //456 #CJK UNIFIED IDEOGRAPH + {0x838D, 0x5118}, //457 #CJK UNIFIED IDEOGRAPH + {0x838E, 0x5119}, //458 #CJK UNIFIED IDEOGRAPH + {0x838F, 0x511A}, //459 #CJK UNIFIED IDEOGRAPH + {0x8390, 0x511B}, //460 #CJK UNIFIED IDEOGRAPH + {0x8391, 0x511C}, //461 #CJK UNIFIED IDEOGRAPH + {0x8392, 0x511D}, //462 #CJK UNIFIED IDEOGRAPH + {0x8393, 0x511E}, //463 #CJK UNIFIED IDEOGRAPH + {0x8394, 0x511F}, //464 #CJK UNIFIED IDEOGRAPH + {0x8395, 0x5120}, //465 #CJK UNIFIED IDEOGRAPH + {0x8396, 0x5122}, //466 #CJK UNIFIED IDEOGRAPH + {0x8397, 0x5123}, //467 #CJK UNIFIED IDEOGRAPH + {0x8398, 0x5124}, //468 #CJK UNIFIED IDEOGRAPH + {0x8399, 0x5125}, //469 #CJK UNIFIED IDEOGRAPH + {0x839A, 0x5126}, //470 #CJK UNIFIED IDEOGRAPH + {0x839B, 0x5127}, //471 #CJK UNIFIED IDEOGRAPH + {0x839C, 0x5128}, //472 #CJK UNIFIED IDEOGRAPH + {0x839D, 0x5129}, //473 #CJK UNIFIED IDEOGRAPH + {0x839E, 0x512A}, //474 #CJK UNIFIED IDEOGRAPH + {0x839F, 0x512B}, //475 #CJK UNIFIED IDEOGRAPH + {0x83A0, 0x512C}, //476 #CJK UNIFIED IDEOGRAPH + {0x83A1, 0x512D}, //477 #CJK UNIFIED IDEOGRAPH + {0x83A2, 0x512E}, //478 #CJK UNIFIED IDEOGRAPH + {0x83A3, 0x512F}, //479 #CJK UNIFIED IDEOGRAPH + {0x83A4, 0x5130}, //480 #CJK UNIFIED IDEOGRAPH + {0x83A5, 0x5131}, //481 #CJK UNIFIED IDEOGRAPH + {0x83A6, 0x5132}, //482 #CJK UNIFIED IDEOGRAPH + {0x83A7, 0x5133}, //483 #CJK UNIFIED IDEOGRAPH + {0x83A8, 0x5134}, //484 #CJK UNIFIED IDEOGRAPH + {0x83A9, 0x5135}, //485 #CJK UNIFIED IDEOGRAPH + {0x83AA, 0x5136}, //486 #CJK UNIFIED IDEOGRAPH + {0x83AB, 0x5137}, //487 #CJK UNIFIED IDEOGRAPH + {0x83AC, 0x5138}, //488 #CJK UNIFIED IDEOGRAPH + {0x83AD, 0x5139}, //489 #CJK UNIFIED IDEOGRAPH + {0x83AE, 0x513A}, //490 #CJK UNIFIED IDEOGRAPH + {0x83AF, 0x513B}, //491 #CJK UNIFIED IDEOGRAPH + {0x83B0, 0x513C}, //492 #CJK UNIFIED IDEOGRAPH + {0x83B1, 0x513D}, //493 #CJK UNIFIED IDEOGRAPH + {0x83B2, 0x513E}, //494 #CJK UNIFIED IDEOGRAPH + {0x83B3, 0x5142}, //495 #CJK UNIFIED IDEOGRAPH + {0x83B4, 0x5147}, //496 #CJK UNIFIED IDEOGRAPH + {0x83B5, 0x514A}, //497 #CJK UNIFIED IDEOGRAPH + {0x83B6, 0x514C}, //498 #CJK UNIFIED IDEOGRAPH + {0x83B7, 0x514E}, //499 #CJK UNIFIED IDEOGRAPH + {0x83B8, 0x514F}, //500 #CJK UNIFIED IDEOGRAPH + {0x83B9, 0x5150}, //501 #CJK UNIFIED IDEOGRAPH + {0x83BA, 0x5152}, //502 #CJK UNIFIED IDEOGRAPH + {0x83BB, 0x5153}, //503 #CJK UNIFIED IDEOGRAPH + {0x83BC, 0x5157}, //504 #CJK UNIFIED IDEOGRAPH + {0x83BD, 0x5158}, //505 #CJK UNIFIED IDEOGRAPH + {0x83BE, 0x5159}, //506 #CJK UNIFIED IDEOGRAPH + {0x83BF, 0x515B}, //507 #CJK UNIFIED IDEOGRAPH + {0x83C0, 0x515D}, //508 #CJK UNIFIED IDEOGRAPH + {0x83C1, 0x515E}, //509 #CJK UNIFIED IDEOGRAPH + {0x83C2, 0x515F}, //510 #CJK UNIFIED IDEOGRAPH + {0x83C3, 0x5160}, //511 #CJK UNIFIED IDEOGRAPH + {0x83C4, 0x5161}, //512 #CJK UNIFIED IDEOGRAPH + {0x83C5, 0x5163}, //513 #CJK UNIFIED IDEOGRAPH + {0x83C6, 0x5164}, //514 #CJK UNIFIED IDEOGRAPH + {0x83C7, 0x5166}, //515 #CJK UNIFIED IDEOGRAPH + {0x83C8, 0x5167}, //516 #CJK UNIFIED IDEOGRAPH + {0x83C9, 0x5169}, //517 #CJK UNIFIED IDEOGRAPH + {0x83CA, 0x516A}, //518 #CJK UNIFIED IDEOGRAPH + {0x83CB, 0x516F}, //519 #CJK UNIFIED IDEOGRAPH + {0x83CC, 0x5172}, //520 #CJK UNIFIED IDEOGRAPH + {0x83CD, 0x517A}, //521 #CJK UNIFIED IDEOGRAPH + {0x83CE, 0x517E}, //522 #CJK UNIFIED IDEOGRAPH + {0x83CF, 0x517F}, //523 #CJK UNIFIED IDEOGRAPH + {0x83D0, 0x5183}, //524 #CJK UNIFIED IDEOGRAPH + {0x83D1, 0x5184}, //525 #CJK UNIFIED IDEOGRAPH + {0x83D2, 0x5186}, //526 #CJK UNIFIED IDEOGRAPH + {0x83D3, 0x5187}, //527 #CJK UNIFIED IDEOGRAPH + {0x83D4, 0x518A}, //528 #CJK UNIFIED IDEOGRAPH + {0x83D5, 0x518B}, //529 #CJK UNIFIED IDEOGRAPH + {0x83D6, 0x518E}, //530 #CJK UNIFIED IDEOGRAPH + {0x83D7, 0x518F}, //531 #CJK UNIFIED IDEOGRAPH + {0x83D8, 0x5190}, //532 #CJK UNIFIED IDEOGRAPH + {0x83D9, 0x5191}, //533 #CJK UNIFIED IDEOGRAPH + {0x83DA, 0x5193}, //534 #CJK UNIFIED IDEOGRAPH + {0x83DB, 0x5194}, //535 #CJK UNIFIED IDEOGRAPH + {0x83DC, 0x5198}, //536 #CJK UNIFIED IDEOGRAPH + {0x83DD, 0x519A}, //537 #CJK UNIFIED IDEOGRAPH + {0x83DE, 0x519D}, //538 #CJK UNIFIED IDEOGRAPH + {0x83DF, 0x519E}, //539 #CJK UNIFIED IDEOGRAPH + {0x83E0, 0x519F}, //540 #CJK UNIFIED IDEOGRAPH + {0x83E1, 0x51A1}, //541 #CJK UNIFIED IDEOGRAPH + {0x83E2, 0x51A3}, //542 #CJK UNIFIED IDEOGRAPH + {0x83E3, 0x51A6}, //543 #CJK UNIFIED IDEOGRAPH + {0x83E4, 0x51A7}, //544 #CJK UNIFIED IDEOGRAPH + {0x83E5, 0x51A8}, //545 #CJK UNIFIED IDEOGRAPH + {0x83E6, 0x51A9}, //546 #CJK UNIFIED IDEOGRAPH + {0x83E7, 0x51AA}, //547 #CJK UNIFIED IDEOGRAPH + {0x83E8, 0x51AD}, //548 #CJK UNIFIED IDEOGRAPH + {0x83E9, 0x51AE}, //549 #CJK UNIFIED IDEOGRAPH + {0x83EA, 0x51B4}, //550 #CJK UNIFIED IDEOGRAPH + {0x83EB, 0x51B8}, //551 #CJK UNIFIED IDEOGRAPH + {0x83EC, 0x51B9}, //552 #CJK UNIFIED IDEOGRAPH + {0x83ED, 0x51BA}, //553 #CJK UNIFIED IDEOGRAPH + {0x83EE, 0x51BE}, //554 #CJK UNIFIED IDEOGRAPH + {0x83EF, 0x51BF}, //555 #CJK UNIFIED IDEOGRAPH + {0x83F0, 0x51C1}, //556 #CJK UNIFIED IDEOGRAPH + {0x83F1, 0x51C2}, //557 #CJK UNIFIED IDEOGRAPH + {0x83F2, 0x51C3}, //558 #CJK UNIFIED IDEOGRAPH + {0x83F3, 0x51C5}, //559 #CJK UNIFIED IDEOGRAPH + {0x83F4, 0x51C8}, //560 #CJK UNIFIED IDEOGRAPH + {0x83F5, 0x51CA}, //561 #CJK UNIFIED IDEOGRAPH + {0x83F6, 0x51CD}, //562 #CJK UNIFIED IDEOGRAPH + {0x83F7, 0x51CE}, //563 #CJK UNIFIED IDEOGRAPH + {0x83F8, 0x51D0}, //564 #CJK UNIFIED IDEOGRAPH + {0x83F9, 0x51D2}, //565 #CJK UNIFIED IDEOGRAPH + {0x83FA, 0x51D3}, //566 #CJK UNIFIED IDEOGRAPH + {0x83FB, 0x51D4}, //567 #CJK UNIFIED IDEOGRAPH + {0x83FC, 0x51D5}, //568 #CJK UNIFIED IDEOGRAPH + {0x83FD, 0x51D6}, //569 #CJK UNIFIED IDEOGRAPH + {0x83FE, 0x51D7}, //570 #CJK UNIFIED IDEOGRAPH + {0x8440, 0x51D8}, //571 #CJK UNIFIED IDEOGRAPH + {0x8441, 0x51D9}, //572 #CJK UNIFIED IDEOGRAPH + {0x8442, 0x51DA}, //573 #CJK UNIFIED IDEOGRAPH + {0x8443, 0x51DC}, //574 #CJK UNIFIED IDEOGRAPH + {0x8444, 0x51DE}, //575 #CJK UNIFIED IDEOGRAPH + {0x8445, 0x51DF}, //576 #CJK UNIFIED IDEOGRAPH + {0x8446, 0x51E2}, //577 #CJK UNIFIED IDEOGRAPH + {0x8447, 0x51E3}, //578 #CJK UNIFIED IDEOGRAPH + {0x8448, 0x51E5}, //579 #CJK UNIFIED IDEOGRAPH + {0x8449, 0x51E6}, //580 #CJK UNIFIED IDEOGRAPH + {0x844A, 0x51E7}, //581 #CJK UNIFIED IDEOGRAPH + {0x844B, 0x51E8}, //582 #CJK UNIFIED IDEOGRAPH + {0x844C, 0x51E9}, //583 #CJK UNIFIED IDEOGRAPH + {0x844D, 0x51EA}, //584 #CJK UNIFIED IDEOGRAPH + {0x844E, 0x51EC}, //585 #CJK UNIFIED IDEOGRAPH + {0x844F, 0x51EE}, //586 #CJK UNIFIED IDEOGRAPH + {0x8450, 0x51F1}, //587 #CJK UNIFIED IDEOGRAPH + {0x8451, 0x51F2}, //588 #CJK UNIFIED IDEOGRAPH + {0x8452, 0x51F4}, //589 #CJK UNIFIED IDEOGRAPH + {0x8453, 0x51F7}, //590 #CJK UNIFIED IDEOGRAPH + {0x8454, 0x51FE}, //591 #CJK UNIFIED IDEOGRAPH + {0x8455, 0x5204}, //592 #CJK UNIFIED IDEOGRAPH + {0x8456, 0x5205}, //593 #CJK UNIFIED IDEOGRAPH + {0x8457, 0x5209}, //594 #CJK UNIFIED IDEOGRAPH + {0x8458, 0x520B}, //595 #CJK UNIFIED IDEOGRAPH + {0x8459, 0x520C}, //596 #CJK UNIFIED IDEOGRAPH + {0x845A, 0x520F}, //597 #CJK UNIFIED IDEOGRAPH + {0x845B, 0x5210}, //598 #CJK UNIFIED IDEOGRAPH + {0x845C, 0x5213}, //599 #CJK UNIFIED IDEOGRAPH + {0x845D, 0x5214}, //600 #CJK UNIFIED IDEOGRAPH + {0x845E, 0x5215}, //601 #CJK UNIFIED IDEOGRAPH + {0x845F, 0x521C}, //602 #CJK UNIFIED IDEOGRAPH + {0x8460, 0x521E}, //603 #CJK UNIFIED IDEOGRAPH + {0x8461, 0x521F}, //604 #CJK UNIFIED IDEOGRAPH + {0x8462, 0x5221}, //605 #CJK UNIFIED IDEOGRAPH + {0x8463, 0x5222}, //606 #CJK UNIFIED IDEOGRAPH + {0x8464, 0x5223}, //607 #CJK UNIFIED IDEOGRAPH + {0x8465, 0x5225}, //608 #CJK UNIFIED IDEOGRAPH + {0x8466, 0x5226}, //609 #CJK UNIFIED IDEOGRAPH + {0x8467, 0x5227}, //610 #CJK UNIFIED IDEOGRAPH + {0x8468, 0x522A}, //611 #CJK UNIFIED IDEOGRAPH + {0x8469, 0x522C}, //612 #CJK UNIFIED IDEOGRAPH + {0x846A, 0x522F}, //613 #CJK UNIFIED IDEOGRAPH + {0x846B, 0x5231}, //614 #CJK UNIFIED IDEOGRAPH + {0x846C, 0x5232}, //615 #CJK UNIFIED IDEOGRAPH + {0x846D, 0x5234}, //616 #CJK UNIFIED IDEOGRAPH + {0x846E, 0x5235}, //617 #CJK UNIFIED IDEOGRAPH + {0x846F, 0x523C}, //618 #CJK UNIFIED IDEOGRAPH + {0x8470, 0x523E}, //619 #CJK UNIFIED IDEOGRAPH + {0x8471, 0x5244}, //620 #CJK UNIFIED IDEOGRAPH + {0x8472, 0x5245}, //621 #CJK UNIFIED IDEOGRAPH + {0x8473, 0x5246}, //622 #CJK UNIFIED IDEOGRAPH + {0x8474, 0x5247}, //623 #CJK UNIFIED IDEOGRAPH + {0x8475, 0x5248}, //624 #CJK UNIFIED IDEOGRAPH + {0x8476, 0x5249}, //625 #CJK UNIFIED IDEOGRAPH + {0x8477, 0x524B}, //626 #CJK UNIFIED IDEOGRAPH + {0x8478, 0x524E}, //627 #CJK UNIFIED IDEOGRAPH + {0x8479, 0x524F}, //628 #CJK UNIFIED IDEOGRAPH + {0x847A, 0x5252}, //629 #CJK UNIFIED IDEOGRAPH + {0x847B, 0x5253}, //630 #CJK UNIFIED IDEOGRAPH + {0x847C, 0x5255}, //631 #CJK UNIFIED IDEOGRAPH + {0x847D, 0x5257}, //632 #CJK UNIFIED IDEOGRAPH + {0x847E, 0x5258}, //633 #CJK UNIFIED IDEOGRAPH + {0x8480, 0x5259}, //634 #CJK UNIFIED IDEOGRAPH + {0x8481, 0x525A}, //635 #CJK UNIFIED IDEOGRAPH + {0x8482, 0x525B}, //636 #CJK UNIFIED IDEOGRAPH + {0x8483, 0x525D}, //637 #CJK UNIFIED IDEOGRAPH + {0x8484, 0x525F}, //638 #CJK UNIFIED IDEOGRAPH + {0x8485, 0x5260}, //639 #CJK UNIFIED IDEOGRAPH + {0x8486, 0x5262}, //640 #CJK UNIFIED IDEOGRAPH + {0x8487, 0x5263}, //641 #CJK UNIFIED IDEOGRAPH + {0x8488, 0x5264}, //642 #CJK UNIFIED IDEOGRAPH + {0x8489, 0x5266}, //643 #CJK UNIFIED IDEOGRAPH + {0x848A, 0x5268}, //644 #CJK UNIFIED IDEOGRAPH + {0x848B, 0x526B}, //645 #CJK UNIFIED IDEOGRAPH + {0x848C, 0x526C}, //646 #CJK UNIFIED IDEOGRAPH + {0x848D, 0x526D}, //647 #CJK UNIFIED IDEOGRAPH + {0x848E, 0x526E}, //648 #CJK UNIFIED IDEOGRAPH + {0x848F, 0x5270}, //649 #CJK UNIFIED IDEOGRAPH + {0x8490, 0x5271}, //650 #CJK UNIFIED IDEOGRAPH + {0x8491, 0x5273}, //651 #CJK UNIFIED IDEOGRAPH + {0x8492, 0x5274}, //652 #CJK UNIFIED IDEOGRAPH + {0x8493, 0x5275}, //653 #CJK UNIFIED IDEOGRAPH + {0x8494, 0x5276}, //654 #CJK UNIFIED IDEOGRAPH + {0x8495, 0x5277}, //655 #CJK UNIFIED IDEOGRAPH + {0x8496, 0x5278}, //656 #CJK UNIFIED IDEOGRAPH + {0x8497, 0x5279}, //657 #CJK UNIFIED IDEOGRAPH + {0x8498, 0x527A}, //658 #CJK UNIFIED IDEOGRAPH + {0x8499, 0x527B}, //659 #CJK UNIFIED IDEOGRAPH + {0x849A, 0x527C}, //660 #CJK UNIFIED IDEOGRAPH + {0x849B, 0x527E}, //661 #CJK UNIFIED IDEOGRAPH + {0x849C, 0x5280}, //662 #CJK UNIFIED IDEOGRAPH + {0x849D, 0x5283}, //663 #CJK UNIFIED IDEOGRAPH + {0x849E, 0x5284}, //664 #CJK UNIFIED IDEOGRAPH + {0x849F, 0x5285}, //665 #CJK UNIFIED IDEOGRAPH + {0x84A0, 0x5286}, //666 #CJK UNIFIED IDEOGRAPH + {0x84A1, 0x5287}, //667 #CJK UNIFIED IDEOGRAPH + {0x84A2, 0x5289}, //668 #CJK UNIFIED IDEOGRAPH + {0x84A3, 0x528A}, //669 #CJK UNIFIED IDEOGRAPH + {0x84A4, 0x528B}, //670 #CJK UNIFIED IDEOGRAPH + {0x84A5, 0x528C}, //671 #CJK UNIFIED IDEOGRAPH + {0x84A6, 0x528D}, //672 #CJK UNIFIED IDEOGRAPH + {0x84A7, 0x528E}, //673 #CJK UNIFIED IDEOGRAPH + {0x84A8, 0x528F}, //674 #CJK UNIFIED IDEOGRAPH + {0x84A9, 0x5291}, //675 #CJK UNIFIED IDEOGRAPH + {0x84AA, 0x5292}, //676 #CJK UNIFIED IDEOGRAPH + {0x84AB, 0x5294}, //677 #CJK UNIFIED IDEOGRAPH + {0x84AC, 0x5295}, //678 #CJK UNIFIED IDEOGRAPH + {0x84AD, 0x5296}, //679 #CJK UNIFIED IDEOGRAPH + {0x84AE, 0x5297}, //680 #CJK UNIFIED IDEOGRAPH + {0x84AF, 0x5298}, //681 #CJK UNIFIED IDEOGRAPH + {0x84B0, 0x5299}, //682 #CJK UNIFIED IDEOGRAPH + {0x84B1, 0x529A}, //683 #CJK UNIFIED IDEOGRAPH + {0x84B2, 0x529C}, //684 #CJK UNIFIED IDEOGRAPH + {0x84B3, 0x52A4}, //685 #CJK UNIFIED IDEOGRAPH + {0x84B4, 0x52A5}, //686 #CJK UNIFIED IDEOGRAPH + {0x84B5, 0x52A6}, //687 #CJK UNIFIED IDEOGRAPH + {0x84B6, 0x52A7}, //688 #CJK UNIFIED IDEOGRAPH + {0x84B7, 0x52AE}, //689 #CJK UNIFIED IDEOGRAPH + {0x84B8, 0x52AF}, //690 #CJK UNIFIED IDEOGRAPH + {0x84B9, 0x52B0}, //691 #CJK UNIFIED IDEOGRAPH + {0x84BA, 0x52B4}, //692 #CJK UNIFIED IDEOGRAPH + {0x84BB, 0x52B5}, //693 #CJK UNIFIED IDEOGRAPH + {0x84BC, 0x52B6}, //694 #CJK UNIFIED IDEOGRAPH + {0x84BD, 0x52B7}, //695 #CJK UNIFIED IDEOGRAPH + {0x84BE, 0x52B8}, //696 #CJK UNIFIED IDEOGRAPH + {0x84BF, 0x52B9}, //697 #CJK UNIFIED IDEOGRAPH + {0x84C0, 0x52BA}, //698 #CJK UNIFIED IDEOGRAPH + {0x84C1, 0x52BB}, //699 #CJK UNIFIED IDEOGRAPH + {0x84C2, 0x52BC}, //700 #CJK UNIFIED IDEOGRAPH + {0x84C3, 0x52BD}, //701 #CJK UNIFIED IDEOGRAPH + {0x84C4, 0x52C0}, //702 #CJK UNIFIED IDEOGRAPH + {0x84C5, 0x52C1}, //703 #CJK UNIFIED IDEOGRAPH + {0x84C6, 0x52C2}, //704 #CJK UNIFIED IDEOGRAPH + {0x84C7, 0x52C4}, //705 #CJK UNIFIED IDEOGRAPH + {0x84C8, 0x52C5}, //706 #CJK UNIFIED IDEOGRAPH + {0x84C9, 0x52C6}, //707 #CJK UNIFIED IDEOGRAPH + {0x84CA, 0x52C8}, //708 #CJK UNIFIED IDEOGRAPH + {0x84CB, 0x52CA}, //709 #CJK UNIFIED IDEOGRAPH + {0x84CC, 0x52CC}, //710 #CJK UNIFIED IDEOGRAPH + {0x84CD, 0x52CD}, //711 #CJK UNIFIED IDEOGRAPH + {0x84CE, 0x52CE}, //712 #CJK UNIFIED IDEOGRAPH + {0x84CF, 0x52CF}, //713 #CJK UNIFIED IDEOGRAPH + {0x84D0, 0x52D1}, //714 #CJK UNIFIED IDEOGRAPH + {0x84D1, 0x52D3}, //715 #CJK UNIFIED IDEOGRAPH + {0x84D2, 0x52D4}, //716 #CJK UNIFIED IDEOGRAPH + {0x84D3, 0x52D5}, //717 #CJK UNIFIED IDEOGRAPH + {0x84D4, 0x52D7}, //718 #CJK UNIFIED IDEOGRAPH + {0x84D5, 0x52D9}, //719 #CJK UNIFIED IDEOGRAPH + {0x84D6, 0x52DA}, //720 #CJK UNIFIED IDEOGRAPH + {0x84D7, 0x52DB}, //721 #CJK UNIFIED IDEOGRAPH + {0x84D8, 0x52DC}, //722 #CJK UNIFIED IDEOGRAPH + {0x84D9, 0x52DD}, //723 #CJK UNIFIED IDEOGRAPH + {0x84DA, 0x52DE}, //724 #CJK UNIFIED IDEOGRAPH + {0x84DB, 0x52E0}, //725 #CJK UNIFIED IDEOGRAPH + {0x84DC, 0x52E1}, //726 #CJK UNIFIED IDEOGRAPH + {0x84DD, 0x52E2}, //727 #CJK UNIFIED IDEOGRAPH + {0x84DE, 0x52E3}, //728 #CJK UNIFIED IDEOGRAPH + {0x84DF, 0x52E5}, //729 #CJK UNIFIED IDEOGRAPH + {0x84E0, 0x52E6}, //730 #CJK UNIFIED IDEOGRAPH + {0x84E1, 0x52E7}, //731 #CJK UNIFIED IDEOGRAPH + {0x84E2, 0x52E8}, //732 #CJK UNIFIED IDEOGRAPH + {0x84E3, 0x52E9}, //733 #CJK UNIFIED IDEOGRAPH + {0x84E4, 0x52EA}, //734 #CJK UNIFIED IDEOGRAPH + {0x84E5, 0x52EB}, //735 #CJK UNIFIED IDEOGRAPH + {0x84E6, 0x52EC}, //736 #CJK UNIFIED IDEOGRAPH + {0x84E7, 0x52ED}, //737 #CJK UNIFIED IDEOGRAPH + {0x84E8, 0x52EE}, //738 #CJK UNIFIED IDEOGRAPH + {0x84E9, 0x52EF}, //739 #CJK UNIFIED IDEOGRAPH + {0x84EA, 0x52F1}, //740 #CJK UNIFIED IDEOGRAPH + {0x84EB, 0x52F2}, //741 #CJK UNIFIED IDEOGRAPH + {0x84EC, 0x52F3}, //742 #CJK UNIFIED IDEOGRAPH + {0x84ED, 0x52F4}, //743 #CJK UNIFIED IDEOGRAPH + {0x84EE, 0x52F5}, //744 #CJK UNIFIED IDEOGRAPH + {0x84EF, 0x52F6}, //745 #CJK UNIFIED IDEOGRAPH + {0x84F0, 0x52F7}, //746 #CJK UNIFIED IDEOGRAPH + {0x84F1, 0x52F8}, //747 #CJK UNIFIED IDEOGRAPH + {0x84F2, 0x52FB}, //748 #CJK UNIFIED IDEOGRAPH + {0x84F3, 0x52FC}, //749 #CJK UNIFIED IDEOGRAPH + {0x84F4, 0x52FD}, //750 #CJK UNIFIED IDEOGRAPH + {0x84F5, 0x5301}, //751 #CJK UNIFIED IDEOGRAPH + {0x84F6, 0x5302}, //752 #CJK UNIFIED IDEOGRAPH + {0x84F7, 0x5303}, //753 #CJK UNIFIED IDEOGRAPH + {0x84F8, 0x5304}, //754 #CJK UNIFIED IDEOGRAPH + {0x84F9, 0x5307}, //755 #CJK UNIFIED IDEOGRAPH + {0x84FA, 0x5309}, //756 #CJK UNIFIED IDEOGRAPH + {0x84FB, 0x530A}, //757 #CJK UNIFIED IDEOGRAPH + {0x84FC, 0x530B}, //758 #CJK UNIFIED IDEOGRAPH + {0x84FD, 0x530C}, //759 #CJK UNIFIED IDEOGRAPH + {0x84FE, 0x530E}, //760 #CJK UNIFIED IDEOGRAPH + {0x8540, 0x5311}, //761 #CJK UNIFIED IDEOGRAPH + {0x8541, 0x5312}, //762 #CJK UNIFIED IDEOGRAPH + {0x8542, 0x5313}, //763 #CJK UNIFIED IDEOGRAPH + {0x8543, 0x5314}, //764 #CJK UNIFIED IDEOGRAPH + {0x8544, 0x5318}, //765 #CJK UNIFIED IDEOGRAPH + {0x8545, 0x531B}, //766 #CJK UNIFIED IDEOGRAPH + {0x8546, 0x531C}, //767 #CJK UNIFIED IDEOGRAPH + {0x8547, 0x531E}, //768 #CJK UNIFIED IDEOGRAPH + {0x8548, 0x531F}, //769 #CJK UNIFIED IDEOGRAPH + {0x8549, 0x5322}, //770 #CJK UNIFIED IDEOGRAPH + {0x854A, 0x5324}, //771 #CJK UNIFIED IDEOGRAPH + {0x854B, 0x5325}, //772 #CJK UNIFIED IDEOGRAPH + {0x854C, 0x5327}, //773 #CJK UNIFIED IDEOGRAPH + {0x854D, 0x5328}, //774 #CJK UNIFIED IDEOGRAPH + {0x854E, 0x5329}, //775 #CJK UNIFIED IDEOGRAPH + {0x854F, 0x532B}, //776 #CJK UNIFIED IDEOGRAPH + {0x8550, 0x532C}, //777 #CJK UNIFIED IDEOGRAPH + {0x8551, 0x532D}, //778 #CJK UNIFIED IDEOGRAPH + {0x8552, 0x532F}, //779 #CJK UNIFIED IDEOGRAPH + {0x8553, 0x5330}, //780 #CJK UNIFIED IDEOGRAPH + {0x8554, 0x5331}, //781 #CJK UNIFIED IDEOGRAPH + {0x8555, 0x5332}, //782 #CJK UNIFIED IDEOGRAPH + {0x8556, 0x5333}, //783 #CJK UNIFIED IDEOGRAPH + {0x8557, 0x5334}, //784 #CJK UNIFIED IDEOGRAPH + {0x8558, 0x5335}, //785 #CJK UNIFIED IDEOGRAPH + {0x8559, 0x5336}, //786 #CJK UNIFIED IDEOGRAPH + {0x855A, 0x5337}, //787 #CJK UNIFIED IDEOGRAPH + {0x855B, 0x5338}, //788 #CJK UNIFIED IDEOGRAPH + {0x855C, 0x533C}, //789 #CJK UNIFIED IDEOGRAPH + {0x855D, 0x533D}, //790 #CJK UNIFIED IDEOGRAPH + {0x855E, 0x5340}, //791 #CJK UNIFIED IDEOGRAPH + {0x855F, 0x5342}, //792 #CJK UNIFIED IDEOGRAPH + {0x8560, 0x5344}, //793 #CJK UNIFIED IDEOGRAPH + {0x8561, 0x5346}, //794 #CJK UNIFIED IDEOGRAPH + {0x8562, 0x534B}, //795 #CJK UNIFIED IDEOGRAPH + {0x8563, 0x534C}, //796 #CJK UNIFIED IDEOGRAPH + {0x8564, 0x534D}, //797 #CJK UNIFIED IDEOGRAPH + {0x8565, 0x5350}, //798 #CJK UNIFIED IDEOGRAPH + {0x8566, 0x5354}, //799 #CJK UNIFIED IDEOGRAPH + {0x8567, 0x5358}, //800 #CJK UNIFIED IDEOGRAPH + {0x8568, 0x5359}, //801 #CJK UNIFIED IDEOGRAPH + {0x8569, 0x535B}, //802 #CJK UNIFIED IDEOGRAPH + {0x856A, 0x535D}, //803 #CJK UNIFIED IDEOGRAPH + {0x856B, 0x5365}, //804 #CJK UNIFIED IDEOGRAPH + {0x856C, 0x5368}, //805 #CJK UNIFIED IDEOGRAPH + {0x856D, 0x536A}, //806 #CJK UNIFIED IDEOGRAPH + {0x856E, 0x536C}, //807 #CJK UNIFIED IDEOGRAPH + {0x856F, 0x536D}, //808 #CJK UNIFIED IDEOGRAPH + {0x8570, 0x5372}, //809 #CJK UNIFIED IDEOGRAPH + {0x8571, 0x5376}, //810 #CJK UNIFIED IDEOGRAPH + {0x8572, 0x5379}, //811 #CJK UNIFIED IDEOGRAPH + {0x8573, 0x537B}, //812 #CJK UNIFIED IDEOGRAPH + {0x8574, 0x537C}, //813 #CJK UNIFIED IDEOGRAPH + {0x8575, 0x537D}, //814 #CJK UNIFIED IDEOGRAPH + {0x8576, 0x537E}, //815 #CJK UNIFIED IDEOGRAPH + {0x8577, 0x5380}, //816 #CJK UNIFIED IDEOGRAPH + {0x8578, 0x5381}, //817 #CJK UNIFIED IDEOGRAPH + {0x8579, 0x5383}, //818 #CJK UNIFIED IDEOGRAPH + {0x857A, 0x5387}, //819 #CJK UNIFIED IDEOGRAPH + {0x857B, 0x5388}, //820 #CJK UNIFIED IDEOGRAPH + {0x857C, 0x538A}, //821 #CJK UNIFIED IDEOGRAPH + {0x857D, 0x538E}, //822 #CJK UNIFIED IDEOGRAPH + {0x857E, 0x538F}, //823 #CJK UNIFIED IDEOGRAPH + {0x8580, 0x5390}, //824 #CJK UNIFIED IDEOGRAPH + {0x8581, 0x5391}, //825 #CJK UNIFIED IDEOGRAPH + {0x8582, 0x5392}, //826 #CJK UNIFIED IDEOGRAPH + {0x8583, 0x5393}, //827 #CJK UNIFIED IDEOGRAPH + {0x8584, 0x5394}, //828 #CJK UNIFIED IDEOGRAPH + {0x8585, 0x5396}, //829 #CJK UNIFIED IDEOGRAPH + {0x8586, 0x5397}, //830 #CJK UNIFIED IDEOGRAPH + {0x8587, 0x5399}, //831 #CJK UNIFIED IDEOGRAPH + {0x8588, 0x539B}, //832 #CJK UNIFIED IDEOGRAPH + {0x8589, 0x539C}, //833 #CJK UNIFIED IDEOGRAPH + {0x858A, 0x539E}, //834 #CJK UNIFIED IDEOGRAPH + {0x858B, 0x53A0}, //835 #CJK UNIFIED IDEOGRAPH + {0x858C, 0x53A1}, //836 #CJK UNIFIED IDEOGRAPH + {0x858D, 0x53A4}, //837 #CJK UNIFIED IDEOGRAPH + {0x858E, 0x53A7}, //838 #CJK UNIFIED IDEOGRAPH + {0x858F, 0x53AA}, //839 #CJK UNIFIED IDEOGRAPH + {0x8590, 0x53AB}, //840 #CJK UNIFIED IDEOGRAPH + {0x8591, 0x53AC}, //841 #CJK UNIFIED IDEOGRAPH + {0x8592, 0x53AD}, //842 #CJK UNIFIED IDEOGRAPH + {0x8593, 0x53AF}, //843 #CJK UNIFIED IDEOGRAPH + {0x8594, 0x53B0}, //844 #CJK UNIFIED IDEOGRAPH + {0x8595, 0x53B1}, //845 #CJK UNIFIED IDEOGRAPH + {0x8596, 0x53B2}, //846 #CJK UNIFIED IDEOGRAPH + {0x8597, 0x53B3}, //847 #CJK UNIFIED IDEOGRAPH + {0x8598, 0x53B4}, //848 #CJK UNIFIED IDEOGRAPH + {0x8599, 0x53B5}, //849 #CJK UNIFIED IDEOGRAPH + {0x859A, 0x53B7}, //850 #CJK UNIFIED IDEOGRAPH + {0x859B, 0x53B8}, //851 #CJK UNIFIED IDEOGRAPH + {0x859C, 0x53B9}, //852 #CJK UNIFIED IDEOGRAPH + {0x859D, 0x53BA}, //853 #CJK UNIFIED IDEOGRAPH + {0x859E, 0x53BC}, //854 #CJK UNIFIED IDEOGRAPH + {0x859F, 0x53BD}, //855 #CJK UNIFIED IDEOGRAPH + {0x85A0, 0x53BE}, //856 #CJK UNIFIED IDEOGRAPH + {0x85A1, 0x53C0}, //857 #CJK UNIFIED IDEOGRAPH + {0x85A2, 0x53C3}, //858 #CJK UNIFIED IDEOGRAPH + {0x85A3, 0x53C4}, //859 #CJK UNIFIED IDEOGRAPH + {0x85A4, 0x53C5}, //860 #CJK UNIFIED IDEOGRAPH + {0x85A5, 0x53C6}, //861 #CJK UNIFIED IDEOGRAPH + {0x85A6, 0x53C7}, //862 #CJK UNIFIED IDEOGRAPH + {0x85A7, 0x53CE}, //863 #CJK UNIFIED IDEOGRAPH + {0x85A8, 0x53CF}, //864 #CJK UNIFIED IDEOGRAPH + {0x85A9, 0x53D0}, //865 #CJK UNIFIED IDEOGRAPH + {0x85AA, 0x53D2}, //866 #CJK UNIFIED IDEOGRAPH + {0x85AB, 0x53D3}, //867 #CJK UNIFIED IDEOGRAPH + {0x85AC, 0x53D5}, //868 #CJK UNIFIED IDEOGRAPH + {0x85AD, 0x53DA}, //869 #CJK UNIFIED IDEOGRAPH + {0x85AE, 0x53DC}, //870 #CJK UNIFIED IDEOGRAPH + {0x85AF, 0x53DD}, //871 #CJK UNIFIED IDEOGRAPH + {0x85B0, 0x53DE}, //872 #CJK UNIFIED IDEOGRAPH + {0x85B1, 0x53E1}, //873 #CJK UNIFIED IDEOGRAPH + {0x85B2, 0x53E2}, //874 #CJK UNIFIED IDEOGRAPH + {0x85B3, 0x53E7}, //875 #CJK UNIFIED IDEOGRAPH + {0x85B4, 0x53F4}, //876 #CJK UNIFIED IDEOGRAPH + {0x85B5, 0x53FA}, //877 #CJK UNIFIED IDEOGRAPH + {0x85B6, 0x53FE}, //878 #CJK UNIFIED IDEOGRAPH + {0x85B7, 0x53FF}, //879 #CJK UNIFIED IDEOGRAPH + {0x85B8, 0x5400}, //880 #CJK UNIFIED IDEOGRAPH + {0x85B9, 0x5402}, //881 #CJK UNIFIED IDEOGRAPH + {0x85BA, 0x5405}, //882 #CJK UNIFIED IDEOGRAPH + {0x85BB, 0x5407}, //883 #CJK UNIFIED IDEOGRAPH + {0x85BC, 0x540B}, //884 #CJK UNIFIED IDEOGRAPH + {0x85BD, 0x5414}, //885 #CJK UNIFIED IDEOGRAPH + {0x85BE, 0x5418}, //886 #CJK UNIFIED IDEOGRAPH + {0x85BF, 0x5419}, //887 #CJK UNIFIED IDEOGRAPH + {0x85C0, 0x541A}, //888 #CJK UNIFIED IDEOGRAPH + {0x85C1, 0x541C}, //889 #CJK UNIFIED IDEOGRAPH + {0x85C2, 0x5422}, //890 #CJK UNIFIED IDEOGRAPH + {0x85C3, 0x5424}, //891 #CJK UNIFIED IDEOGRAPH + {0x85C4, 0x5425}, //892 #CJK UNIFIED IDEOGRAPH + {0x85C5, 0x542A}, //893 #CJK UNIFIED IDEOGRAPH + {0x85C6, 0x5430}, //894 #CJK UNIFIED IDEOGRAPH + {0x85C7, 0x5433}, //895 #CJK UNIFIED IDEOGRAPH + {0x85C8, 0x5436}, //896 #CJK UNIFIED IDEOGRAPH + {0x85C9, 0x5437}, //897 #CJK UNIFIED IDEOGRAPH + {0x85CA, 0x543A}, //898 #CJK UNIFIED IDEOGRAPH + {0x85CB, 0x543D}, //899 #CJK UNIFIED IDEOGRAPH + {0x85CC, 0x543F}, //900 #CJK UNIFIED IDEOGRAPH + {0x85CD, 0x5441}, //901 #CJK UNIFIED IDEOGRAPH + {0x85CE, 0x5442}, //902 #CJK UNIFIED IDEOGRAPH + {0x85CF, 0x5444}, //903 #CJK UNIFIED IDEOGRAPH + {0x85D0, 0x5445}, //904 #CJK UNIFIED IDEOGRAPH + {0x85D1, 0x5447}, //905 #CJK UNIFIED IDEOGRAPH + {0x85D2, 0x5449}, //906 #CJK UNIFIED IDEOGRAPH + {0x85D3, 0x544C}, //907 #CJK UNIFIED IDEOGRAPH + {0x85D4, 0x544D}, //908 #CJK UNIFIED IDEOGRAPH + {0x85D5, 0x544E}, //909 #CJK UNIFIED IDEOGRAPH + {0x85D6, 0x544F}, //910 #CJK UNIFIED IDEOGRAPH + {0x85D7, 0x5451}, //911 #CJK UNIFIED IDEOGRAPH + {0x85D8, 0x545A}, //912 #CJK UNIFIED IDEOGRAPH + {0x85D9, 0x545D}, //913 #CJK UNIFIED IDEOGRAPH + {0x85DA, 0x545E}, //914 #CJK UNIFIED IDEOGRAPH + {0x85DB, 0x545F}, //915 #CJK UNIFIED IDEOGRAPH + {0x85DC, 0x5460}, //916 #CJK UNIFIED IDEOGRAPH + {0x85DD, 0x5461}, //917 #CJK UNIFIED IDEOGRAPH + {0x85DE, 0x5463}, //918 #CJK UNIFIED IDEOGRAPH + {0x85DF, 0x5465}, //919 #CJK UNIFIED IDEOGRAPH + {0x85E0, 0x5467}, //920 #CJK UNIFIED IDEOGRAPH + {0x85E1, 0x5469}, //921 #CJK UNIFIED IDEOGRAPH + {0x85E2, 0x546A}, //922 #CJK UNIFIED IDEOGRAPH + {0x85E3, 0x546B}, //923 #CJK UNIFIED IDEOGRAPH + {0x85E4, 0x546C}, //924 #CJK UNIFIED IDEOGRAPH + {0x85E5, 0x546D}, //925 #CJK UNIFIED IDEOGRAPH + {0x85E6, 0x546E}, //926 #CJK UNIFIED IDEOGRAPH + {0x85E7, 0x546F}, //927 #CJK UNIFIED IDEOGRAPH + {0x85E8, 0x5470}, //928 #CJK UNIFIED IDEOGRAPH + {0x85E9, 0x5474}, //929 #CJK UNIFIED IDEOGRAPH + {0x85EA, 0x5479}, //930 #CJK UNIFIED IDEOGRAPH + {0x85EB, 0x547A}, //931 #CJK UNIFIED IDEOGRAPH + {0x85EC, 0x547E}, //932 #CJK UNIFIED IDEOGRAPH + {0x85ED, 0x547F}, //933 #CJK UNIFIED IDEOGRAPH + {0x85EE, 0x5481}, //934 #CJK UNIFIED IDEOGRAPH + {0x85EF, 0x5483}, //935 #CJK UNIFIED IDEOGRAPH + {0x85F0, 0x5485}, //936 #CJK UNIFIED IDEOGRAPH + {0x85F1, 0x5487}, //937 #CJK UNIFIED IDEOGRAPH + {0x85F2, 0x5488}, //938 #CJK UNIFIED IDEOGRAPH + {0x85F3, 0x5489}, //939 #CJK UNIFIED IDEOGRAPH + {0x85F4, 0x548A}, //940 #CJK UNIFIED IDEOGRAPH + {0x85F5, 0x548D}, //941 #CJK UNIFIED IDEOGRAPH + {0x85F6, 0x5491}, //942 #CJK UNIFIED IDEOGRAPH + {0x85F7, 0x5493}, //943 #CJK UNIFIED IDEOGRAPH + {0x85F8, 0x5497}, //944 #CJK UNIFIED IDEOGRAPH + {0x85F9, 0x5498}, //945 #CJK UNIFIED IDEOGRAPH + {0x85FA, 0x549C}, //946 #CJK UNIFIED IDEOGRAPH + {0x85FB, 0x549E}, //947 #CJK UNIFIED IDEOGRAPH + {0x85FC, 0x549F}, //948 #CJK UNIFIED IDEOGRAPH + {0x85FD, 0x54A0}, //949 #CJK UNIFIED IDEOGRAPH + {0x85FE, 0x54A1}, //950 #CJK UNIFIED IDEOGRAPH + {0x8640, 0x54A2}, //951 #CJK UNIFIED IDEOGRAPH + {0x8641, 0x54A5}, //952 #CJK UNIFIED IDEOGRAPH + {0x8642, 0x54AE}, //953 #CJK UNIFIED IDEOGRAPH + {0x8643, 0x54B0}, //954 #CJK UNIFIED IDEOGRAPH + {0x8644, 0x54B2}, //955 #CJK UNIFIED IDEOGRAPH + {0x8645, 0x54B5}, //956 #CJK UNIFIED IDEOGRAPH + {0x8646, 0x54B6}, //957 #CJK UNIFIED IDEOGRAPH + {0x8647, 0x54B7}, //958 #CJK UNIFIED IDEOGRAPH + {0x8648, 0x54B9}, //959 #CJK UNIFIED IDEOGRAPH + {0x8649, 0x54BA}, //960 #CJK UNIFIED IDEOGRAPH + {0x864A, 0x54BC}, //961 #CJK UNIFIED IDEOGRAPH + {0x864B, 0x54BE}, //962 #CJK UNIFIED IDEOGRAPH + {0x864C, 0x54C3}, //963 #CJK UNIFIED IDEOGRAPH + {0x864D, 0x54C5}, //964 #CJK UNIFIED IDEOGRAPH + {0x864E, 0x54CA}, //965 #CJK UNIFIED IDEOGRAPH + {0x864F, 0x54CB}, //966 #CJK UNIFIED IDEOGRAPH + {0x8650, 0x54D6}, //967 #CJK UNIFIED IDEOGRAPH + {0x8651, 0x54D8}, //968 #CJK UNIFIED IDEOGRAPH + {0x8652, 0x54DB}, //969 #CJK UNIFIED IDEOGRAPH + {0x8653, 0x54E0}, //970 #CJK UNIFIED IDEOGRAPH + {0x8654, 0x54E1}, //971 #CJK UNIFIED IDEOGRAPH + {0x8655, 0x54E2}, //972 #CJK UNIFIED IDEOGRAPH + {0x8656, 0x54E3}, //973 #CJK UNIFIED IDEOGRAPH + {0x8657, 0x54E4}, //974 #CJK UNIFIED IDEOGRAPH + {0x8658, 0x54EB}, //975 #CJK UNIFIED IDEOGRAPH + {0x8659, 0x54EC}, //976 #CJK UNIFIED IDEOGRAPH + {0x865A, 0x54EF}, //977 #CJK UNIFIED IDEOGRAPH + {0x865B, 0x54F0}, //978 #CJK UNIFIED IDEOGRAPH + {0x865C, 0x54F1}, //979 #CJK UNIFIED IDEOGRAPH + {0x865D, 0x54F4}, //980 #CJK UNIFIED IDEOGRAPH + {0x865E, 0x54F5}, //981 #CJK UNIFIED IDEOGRAPH + {0x865F, 0x54F6}, //982 #CJK UNIFIED IDEOGRAPH + {0x8660, 0x54F7}, //983 #CJK UNIFIED IDEOGRAPH + {0x8661, 0x54F8}, //984 #CJK UNIFIED IDEOGRAPH + {0x8662, 0x54F9}, //985 #CJK UNIFIED IDEOGRAPH + {0x8663, 0x54FB}, //986 #CJK UNIFIED IDEOGRAPH + {0x8664, 0x54FE}, //987 #CJK UNIFIED IDEOGRAPH + {0x8665, 0x5500}, //988 #CJK UNIFIED IDEOGRAPH + {0x8666, 0x5502}, //989 #CJK UNIFIED IDEOGRAPH + {0x8667, 0x5503}, //990 #CJK UNIFIED IDEOGRAPH + {0x8668, 0x5504}, //991 #CJK UNIFIED IDEOGRAPH + {0x8669, 0x5505}, //992 #CJK UNIFIED IDEOGRAPH + {0x866A, 0x5508}, //993 #CJK UNIFIED IDEOGRAPH + {0x866B, 0x550A}, //994 #CJK UNIFIED IDEOGRAPH + {0x866C, 0x550B}, //995 #CJK UNIFIED IDEOGRAPH + {0x866D, 0x550C}, //996 #CJK UNIFIED IDEOGRAPH + {0x866E, 0x550D}, //997 #CJK UNIFIED IDEOGRAPH + {0x866F, 0x550E}, //998 #CJK UNIFIED IDEOGRAPH + {0x8670, 0x5512}, //999 #CJK UNIFIED IDEOGRAPH + {0x8671, 0x5513}, //1000 #CJK UNIFIED IDEOGRAPH + {0x8672, 0x5515}, //1001 #CJK UNIFIED IDEOGRAPH + {0x8673, 0x5516}, //1002 #CJK UNIFIED IDEOGRAPH + {0x8674, 0x5517}, //1003 #CJK UNIFIED IDEOGRAPH + {0x8675, 0x5518}, //1004 #CJK UNIFIED IDEOGRAPH + {0x8676, 0x5519}, //1005 #CJK UNIFIED IDEOGRAPH + {0x8677, 0x551A}, //1006 #CJK UNIFIED IDEOGRAPH + {0x8678, 0x551C}, //1007 #CJK UNIFIED IDEOGRAPH + {0x8679, 0x551D}, //1008 #CJK UNIFIED IDEOGRAPH + {0x867A, 0x551E}, //1009 #CJK UNIFIED IDEOGRAPH + {0x867B, 0x551F}, //1010 #CJK UNIFIED IDEOGRAPH + {0x867C, 0x5521}, //1011 #CJK UNIFIED IDEOGRAPH + {0x867D, 0x5525}, //1012 #CJK UNIFIED IDEOGRAPH + {0x867E, 0x5526}, //1013 #CJK UNIFIED IDEOGRAPH + {0x8680, 0x5528}, //1014 #CJK UNIFIED IDEOGRAPH + {0x8681, 0x5529}, //1015 #CJK UNIFIED IDEOGRAPH + {0x8682, 0x552B}, //1016 #CJK UNIFIED IDEOGRAPH + {0x8683, 0x552D}, //1017 #CJK UNIFIED IDEOGRAPH + {0x8684, 0x5532}, //1018 #CJK UNIFIED IDEOGRAPH + {0x8685, 0x5534}, //1019 #CJK UNIFIED IDEOGRAPH + {0x8686, 0x5535}, //1020 #CJK UNIFIED IDEOGRAPH + {0x8687, 0x5536}, //1021 #CJK UNIFIED IDEOGRAPH + {0x8688, 0x5538}, //1022 #CJK UNIFIED IDEOGRAPH + {0x8689, 0x5539}, //1023 #CJK UNIFIED IDEOGRAPH + {0x868A, 0x553A}, //1024 #CJK UNIFIED IDEOGRAPH + {0x868B, 0x553B}, //1025 #CJK UNIFIED IDEOGRAPH + {0x868C, 0x553D}, //1026 #CJK UNIFIED IDEOGRAPH + {0x868D, 0x5540}, //1027 #CJK UNIFIED IDEOGRAPH + {0x868E, 0x5542}, //1028 #CJK UNIFIED IDEOGRAPH + {0x868F, 0x5545}, //1029 #CJK UNIFIED IDEOGRAPH + {0x8690, 0x5547}, //1030 #CJK UNIFIED IDEOGRAPH + {0x8691, 0x5548}, //1031 #CJK UNIFIED IDEOGRAPH + {0x8692, 0x554B}, //1032 #CJK UNIFIED IDEOGRAPH + {0x8693, 0x554C}, //1033 #CJK UNIFIED IDEOGRAPH + {0x8694, 0x554D}, //1034 #CJK UNIFIED IDEOGRAPH + {0x8695, 0x554E}, //1035 #CJK UNIFIED IDEOGRAPH + {0x8696, 0x554F}, //1036 #CJK UNIFIED IDEOGRAPH + {0x8697, 0x5551}, //1037 #CJK UNIFIED IDEOGRAPH + {0x8698, 0x5552}, //1038 #CJK UNIFIED IDEOGRAPH + {0x8699, 0x5553}, //1039 #CJK UNIFIED IDEOGRAPH + {0x869A, 0x5554}, //1040 #CJK UNIFIED IDEOGRAPH + {0x869B, 0x5557}, //1041 #CJK UNIFIED IDEOGRAPH + {0x869C, 0x5558}, //1042 #CJK UNIFIED IDEOGRAPH + {0x869D, 0x5559}, //1043 #CJK UNIFIED IDEOGRAPH + {0x869E, 0x555A}, //1044 #CJK UNIFIED IDEOGRAPH + {0x869F, 0x555B}, //1045 #CJK UNIFIED IDEOGRAPH + {0x86A0, 0x555D}, //1046 #CJK UNIFIED IDEOGRAPH + {0x86A1, 0x555E}, //1047 #CJK UNIFIED IDEOGRAPH + {0x86A2, 0x555F}, //1048 #CJK UNIFIED IDEOGRAPH + {0x86A3, 0x5560}, //1049 #CJK UNIFIED IDEOGRAPH + {0x86A4, 0x5562}, //1050 #CJK UNIFIED IDEOGRAPH + {0x86A5, 0x5563}, //1051 #CJK UNIFIED IDEOGRAPH + {0x86A6, 0x5568}, //1052 #CJK UNIFIED IDEOGRAPH + {0x86A7, 0x5569}, //1053 #CJK UNIFIED IDEOGRAPH + {0x86A8, 0x556B}, //1054 #CJK UNIFIED IDEOGRAPH + {0x86A9, 0x556F}, //1055 #CJK UNIFIED IDEOGRAPH + {0x86AA, 0x5570}, //1056 #CJK UNIFIED IDEOGRAPH + {0x86AB, 0x5571}, //1057 #CJK UNIFIED IDEOGRAPH + {0x86AC, 0x5572}, //1058 #CJK UNIFIED IDEOGRAPH + {0x86AD, 0x5573}, //1059 #CJK UNIFIED IDEOGRAPH + {0x86AE, 0x5574}, //1060 #CJK UNIFIED IDEOGRAPH + {0x86AF, 0x5579}, //1061 #CJK UNIFIED IDEOGRAPH + {0x86B0, 0x557A}, //1062 #CJK UNIFIED IDEOGRAPH + {0x86B1, 0x557D}, //1063 #CJK UNIFIED IDEOGRAPH + {0x86B2, 0x557F}, //1064 #CJK UNIFIED IDEOGRAPH + {0x86B3, 0x5585}, //1065 #CJK UNIFIED IDEOGRAPH + {0x86B4, 0x5586}, //1066 #CJK UNIFIED IDEOGRAPH + {0x86B5, 0x558C}, //1067 #CJK UNIFIED IDEOGRAPH + {0x86B6, 0x558D}, //1068 #CJK UNIFIED IDEOGRAPH + {0x86B7, 0x558E}, //1069 #CJK UNIFIED IDEOGRAPH + {0x86B8, 0x5590}, //1070 #CJK UNIFIED IDEOGRAPH + {0x86B9, 0x5592}, //1071 #CJK UNIFIED IDEOGRAPH + {0x86BA, 0x5593}, //1072 #CJK UNIFIED IDEOGRAPH + {0x86BB, 0x5595}, //1073 #CJK UNIFIED IDEOGRAPH + {0x86BC, 0x5596}, //1074 #CJK UNIFIED IDEOGRAPH + {0x86BD, 0x5597}, //1075 #CJK UNIFIED IDEOGRAPH + {0x86BE, 0x559A}, //1076 #CJK UNIFIED IDEOGRAPH + {0x86BF, 0x559B}, //1077 #CJK UNIFIED IDEOGRAPH + {0x86C0, 0x559E}, //1078 #CJK UNIFIED IDEOGRAPH + {0x86C1, 0x55A0}, //1079 #CJK UNIFIED IDEOGRAPH + {0x86C2, 0x55A1}, //1080 #CJK UNIFIED IDEOGRAPH + {0x86C3, 0x55A2}, //1081 #CJK UNIFIED IDEOGRAPH + {0x86C4, 0x55A3}, //1082 #CJK UNIFIED IDEOGRAPH + {0x86C5, 0x55A4}, //1083 #CJK UNIFIED IDEOGRAPH + {0x86C6, 0x55A5}, //1084 #CJK UNIFIED IDEOGRAPH + {0x86C7, 0x55A6}, //1085 #CJK UNIFIED IDEOGRAPH + {0x86C8, 0x55A8}, //1086 #CJK UNIFIED IDEOGRAPH + {0x86C9, 0x55A9}, //1087 #CJK UNIFIED IDEOGRAPH + {0x86CA, 0x55AA}, //1088 #CJK UNIFIED IDEOGRAPH + {0x86CB, 0x55AB}, //1089 #CJK UNIFIED IDEOGRAPH + {0x86CC, 0x55AC}, //1090 #CJK UNIFIED IDEOGRAPH + {0x86CD, 0x55AD}, //1091 #CJK UNIFIED IDEOGRAPH + {0x86CE, 0x55AE}, //1092 #CJK UNIFIED IDEOGRAPH + {0x86CF, 0x55AF}, //1093 #CJK UNIFIED IDEOGRAPH + {0x86D0, 0x55B0}, //1094 #CJK UNIFIED IDEOGRAPH + {0x86D1, 0x55B2}, //1095 #CJK UNIFIED IDEOGRAPH + {0x86D2, 0x55B4}, //1096 #CJK UNIFIED IDEOGRAPH + {0x86D3, 0x55B6}, //1097 #CJK UNIFIED IDEOGRAPH + {0x86D4, 0x55B8}, //1098 #CJK UNIFIED IDEOGRAPH + {0x86D5, 0x55BA}, //1099 #CJK UNIFIED IDEOGRAPH + {0x86D6, 0x55BC}, //1100 #CJK UNIFIED IDEOGRAPH + {0x86D7, 0x55BF}, //1101 #CJK UNIFIED IDEOGRAPH + {0x86D8, 0x55C0}, //1102 #CJK UNIFIED IDEOGRAPH + {0x86D9, 0x55C1}, //1103 #CJK UNIFIED IDEOGRAPH + {0x86DA, 0x55C2}, //1104 #CJK UNIFIED IDEOGRAPH + {0x86DB, 0x55C3}, //1105 #CJK UNIFIED IDEOGRAPH + {0x86DC, 0x55C6}, //1106 #CJK UNIFIED IDEOGRAPH + {0x86DD, 0x55C7}, //1107 #CJK UNIFIED IDEOGRAPH + {0x86DE, 0x55C8}, //1108 #CJK UNIFIED IDEOGRAPH + {0x86DF, 0x55CA}, //1109 #CJK UNIFIED IDEOGRAPH + {0x86E0, 0x55CB}, //1110 #CJK UNIFIED IDEOGRAPH + {0x86E1, 0x55CE}, //1111 #CJK UNIFIED IDEOGRAPH + {0x86E2, 0x55CF}, //1112 #CJK UNIFIED IDEOGRAPH + {0x86E3, 0x55D0}, //1113 #CJK UNIFIED IDEOGRAPH + {0x86E4, 0x55D5}, //1114 #CJK UNIFIED IDEOGRAPH + {0x86E5, 0x55D7}, //1115 #CJK UNIFIED IDEOGRAPH + {0x86E6, 0x55D8}, //1116 #CJK UNIFIED IDEOGRAPH + {0x86E7, 0x55D9}, //1117 #CJK UNIFIED IDEOGRAPH + {0x86E8, 0x55DA}, //1118 #CJK UNIFIED IDEOGRAPH + {0x86E9, 0x55DB}, //1119 #CJK UNIFIED IDEOGRAPH + {0x86EA, 0x55DE}, //1120 #CJK UNIFIED IDEOGRAPH + {0x86EB, 0x55E0}, //1121 #CJK UNIFIED IDEOGRAPH + {0x86EC, 0x55E2}, //1122 #CJK UNIFIED IDEOGRAPH + {0x86ED, 0x55E7}, //1123 #CJK UNIFIED IDEOGRAPH + {0x86EE, 0x55E9}, //1124 #CJK UNIFIED IDEOGRAPH + {0x86EF, 0x55ED}, //1125 #CJK UNIFIED IDEOGRAPH + {0x86F0, 0x55EE}, //1126 #CJK UNIFIED IDEOGRAPH + {0x86F1, 0x55F0}, //1127 #CJK UNIFIED IDEOGRAPH + {0x86F2, 0x55F1}, //1128 #CJK UNIFIED IDEOGRAPH + {0x86F3, 0x55F4}, //1129 #CJK UNIFIED IDEOGRAPH + {0x86F4, 0x55F6}, //1130 #CJK UNIFIED IDEOGRAPH + {0x86F5, 0x55F8}, //1131 #CJK UNIFIED IDEOGRAPH + {0x86F6, 0x55F9}, //1132 #CJK UNIFIED IDEOGRAPH + {0x86F7, 0x55FA}, //1133 #CJK UNIFIED IDEOGRAPH + {0x86F8, 0x55FB}, //1134 #CJK UNIFIED IDEOGRAPH + {0x86F9, 0x55FC}, //1135 #CJK UNIFIED IDEOGRAPH + {0x86FA, 0x55FF}, //1136 #CJK UNIFIED IDEOGRAPH + {0x86FB, 0x5602}, //1137 #CJK UNIFIED IDEOGRAPH + {0x86FC, 0x5603}, //1138 #CJK UNIFIED IDEOGRAPH + {0x86FD, 0x5604}, //1139 #CJK UNIFIED IDEOGRAPH + {0x86FE, 0x5605}, //1140 #CJK UNIFIED IDEOGRAPH + {0x8740, 0x5606}, //1141 #CJK UNIFIED IDEOGRAPH + {0x8741, 0x5607}, //1142 #CJK UNIFIED IDEOGRAPH + {0x8742, 0x560A}, //1143 #CJK UNIFIED IDEOGRAPH + {0x8743, 0x560B}, //1144 #CJK UNIFIED IDEOGRAPH + {0x8744, 0x560D}, //1145 #CJK UNIFIED IDEOGRAPH + {0x8745, 0x5610}, //1146 #CJK UNIFIED IDEOGRAPH + {0x8746, 0x5611}, //1147 #CJK UNIFIED IDEOGRAPH + {0x8747, 0x5612}, //1148 #CJK UNIFIED IDEOGRAPH + {0x8748, 0x5613}, //1149 #CJK UNIFIED IDEOGRAPH + {0x8749, 0x5614}, //1150 #CJK UNIFIED IDEOGRAPH + {0x874A, 0x5615}, //1151 #CJK UNIFIED IDEOGRAPH + {0x874B, 0x5616}, //1152 #CJK UNIFIED IDEOGRAPH + {0x874C, 0x5617}, //1153 #CJK UNIFIED IDEOGRAPH + {0x874D, 0x5619}, //1154 #CJK UNIFIED IDEOGRAPH + {0x874E, 0x561A}, //1155 #CJK UNIFIED IDEOGRAPH + {0x874F, 0x561C}, //1156 #CJK UNIFIED IDEOGRAPH + {0x8750, 0x561D}, //1157 #CJK UNIFIED IDEOGRAPH + {0x8751, 0x5620}, //1158 #CJK UNIFIED IDEOGRAPH + {0x8752, 0x5621}, //1159 #CJK UNIFIED IDEOGRAPH + {0x8753, 0x5622}, //1160 #CJK UNIFIED IDEOGRAPH + {0x8754, 0x5625}, //1161 #CJK UNIFIED IDEOGRAPH + {0x8755, 0x5626}, //1162 #CJK UNIFIED IDEOGRAPH + {0x8756, 0x5628}, //1163 #CJK UNIFIED IDEOGRAPH + {0x8757, 0x5629}, //1164 #CJK UNIFIED IDEOGRAPH + {0x8758, 0x562A}, //1165 #CJK UNIFIED IDEOGRAPH + {0x8759, 0x562B}, //1166 #CJK UNIFIED IDEOGRAPH + {0x875A, 0x562E}, //1167 #CJK UNIFIED IDEOGRAPH + {0x875B, 0x562F}, //1168 #CJK UNIFIED IDEOGRAPH + {0x875C, 0x5630}, //1169 #CJK UNIFIED IDEOGRAPH + {0x875D, 0x5633}, //1170 #CJK UNIFIED IDEOGRAPH + {0x875E, 0x5635}, //1171 #CJK UNIFIED IDEOGRAPH + {0x875F, 0x5637}, //1172 #CJK UNIFIED IDEOGRAPH + {0x8760, 0x5638}, //1173 #CJK UNIFIED IDEOGRAPH + {0x8761, 0x563A}, //1174 #CJK UNIFIED IDEOGRAPH + {0x8762, 0x563C}, //1175 #CJK UNIFIED IDEOGRAPH + {0x8763, 0x563D}, //1176 #CJK UNIFIED IDEOGRAPH + {0x8764, 0x563E}, //1177 #CJK UNIFIED IDEOGRAPH + {0x8765, 0x5640}, //1178 #CJK UNIFIED IDEOGRAPH + {0x8766, 0x5641}, //1179 #CJK UNIFIED IDEOGRAPH + {0x8767, 0x5642}, //1180 #CJK UNIFIED IDEOGRAPH + {0x8768, 0x5643}, //1181 #CJK UNIFIED IDEOGRAPH + {0x8769, 0x5644}, //1182 #CJK UNIFIED IDEOGRAPH + {0x876A, 0x5645}, //1183 #CJK UNIFIED IDEOGRAPH + {0x876B, 0x5646}, //1184 #CJK UNIFIED IDEOGRAPH + {0x876C, 0x5647}, //1185 #CJK UNIFIED IDEOGRAPH + {0x876D, 0x5648}, //1186 #CJK UNIFIED IDEOGRAPH + {0x876E, 0x5649}, //1187 #CJK UNIFIED IDEOGRAPH + {0x876F, 0x564A}, //1188 #CJK UNIFIED IDEOGRAPH + {0x8770, 0x564B}, //1189 #CJK UNIFIED IDEOGRAPH + {0x8771, 0x564F}, //1190 #CJK UNIFIED IDEOGRAPH + {0x8772, 0x5650}, //1191 #CJK UNIFIED IDEOGRAPH + {0x8773, 0x5651}, //1192 #CJK UNIFIED IDEOGRAPH + {0x8774, 0x5652}, //1193 #CJK UNIFIED IDEOGRAPH + {0x8775, 0x5653}, //1194 #CJK UNIFIED IDEOGRAPH + {0x8776, 0x5655}, //1195 #CJK UNIFIED IDEOGRAPH + {0x8777, 0x5656}, //1196 #CJK UNIFIED IDEOGRAPH + {0x8778, 0x565A}, //1197 #CJK UNIFIED IDEOGRAPH + {0x8779, 0x565B}, //1198 #CJK UNIFIED IDEOGRAPH + {0x877A, 0x565D}, //1199 #CJK UNIFIED IDEOGRAPH + {0x877B, 0x565E}, //1200 #CJK UNIFIED IDEOGRAPH + {0x877C, 0x565F}, //1201 #CJK UNIFIED IDEOGRAPH + {0x877D, 0x5660}, //1202 #CJK UNIFIED IDEOGRAPH + {0x877E, 0x5661}, //1203 #CJK UNIFIED IDEOGRAPH + {0x8780, 0x5663}, //1204 #CJK UNIFIED IDEOGRAPH + {0x8781, 0x5665}, //1205 #CJK UNIFIED IDEOGRAPH + {0x8782, 0x5666}, //1206 #CJK UNIFIED IDEOGRAPH + {0x8783, 0x5667}, //1207 #CJK UNIFIED IDEOGRAPH + {0x8784, 0x566D}, //1208 #CJK UNIFIED IDEOGRAPH + {0x8785, 0x566E}, //1209 #CJK UNIFIED IDEOGRAPH + {0x8786, 0x566F}, //1210 #CJK UNIFIED IDEOGRAPH + {0x8787, 0x5670}, //1211 #CJK UNIFIED IDEOGRAPH + {0x8788, 0x5672}, //1212 #CJK UNIFIED IDEOGRAPH + {0x8789, 0x5673}, //1213 #CJK UNIFIED IDEOGRAPH + {0x878A, 0x5674}, //1214 #CJK UNIFIED IDEOGRAPH + {0x878B, 0x5675}, //1215 #CJK UNIFIED IDEOGRAPH + {0x878C, 0x5677}, //1216 #CJK UNIFIED IDEOGRAPH + {0x878D, 0x5678}, //1217 #CJK UNIFIED IDEOGRAPH + {0x878E, 0x5679}, //1218 #CJK UNIFIED IDEOGRAPH + {0x878F, 0x567A}, //1219 #CJK UNIFIED IDEOGRAPH + {0x8790, 0x567D}, //1220 #CJK UNIFIED IDEOGRAPH + {0x8791, 0x567E}, //1221 #CJK UNIFIED IDEOGRAPH + {0x8792, 0x567F}, //1222 #CJK UNIFIED IDEOGRAPH + {0x8793, 0x5680}, //1223 #CJK UNIFIED IDEOGRAPH + {0x8794, 0x5681}, //1224 #CJK UNIFIED IDEOGRAPH + {0x8795, 0x5682}, //1225 #CJK UNIFIED IDEOGRAPH + {0x8796, 0x5683}, //1226 #CJK UNIFIED IDEOGRAPH + {0x8797, 0x5684}, //1227 #CJK UNIFIED IDEOGRAPH + {0x8798, 0x5687}, //1228 #CJK UNIFIED IDEOGRAPH + {0x8799, 0x5688}, //1229 #CJK UNIFIED IDEOGRAPH + {0x879A, 0x5689}, //1230 #CJK UNIFIED IDEOGRAPH + {0x879B, 0x568A}, //1231 #CJK UNIFIED IDEOGRAPH + {0x879C, 0x568B}, //1232 #CJK UNIFIED IDEOGRAPH + {0x879D, 0x568C}, //1233 #CJK UNIFIED IDEOGRAPH + {0x879E, 0x568D}, //1234 #CJK UNIFIED IDEOGRAPH + {0x879F, 0x5690}, //1235 #CJK UNIFIED IDEOGRAPH + {0x87A0, 0x5691}, //1236 #CJK UNIFIED IDEOGRAPH + {0x87A1, 0x5692}, //1237 #CJK UNIFIED IDEOGRAPH + {0x87A2, 0x5694}, //1238 #CJK UNIFIED IDEOGRAPH + {0x87A3, 0x5695}, //1239 #CJK UNIFIED IDEOGRAPH + {0x87A4, 0x5696}, //1240 #CJK UNIFIED IDEOGRAPH + {0x87A5, 0x5697}, //1241 #CJK UNIFIED IDEOGRAPH + {0x87A6, 0x5698}, //1242 #CJK UNIFIED IDEOGRAPH + {0x87A7, 0x5699}, //1243 #CJK UNIFIED IDEOGRAPH + {0x87A8, 0x569A}, //1244 #CJK UNIFIED IDEOGRAPH + {0x87A9, 0x569B}, //1245 #CJK UNIFIED IDEOGRAPH + {0x87AA, 0x569C}, //1246 #CJK UNIFIED IDEOGRAPH + {0x87AB, 0x569D}, //1247 #CJK UNIFIED IDEOGRAPH + {0x87AC, 0x569E}, //1248 #CJK UNIFIED IDEOGRAPH + {0x87AD, 0x569F}, //1249 #CJK UNIFIED IDEOGRAPH + {0x87AE, 0x56A0}, //1250 #CJK UNIFIED IDEOGRAPH + {0x87AF, 0x56A1}, //1251 #CJK UNIFIED IDEOGRAPH + {0x87B0, 0x56A2}, //1252 #CJK UNIFIED IDEOGRAPH + {0x87B1, 0x56A4}, //1253 #CJK UNIFIED IDEOGRAPH + {0x87B2, 0x56A5}, //1254 #CJK UNIFIED IDEOGRAPH + {0x87B3, 0x56A6}, //1255 #CJK UNIFIED IDEOGRAPH + {0x87B4, 0x56A7}, //1256 #CJK UNIFIED IDEOGRAPH + {0x87B5, 0x56A8}, //1257 #CJK UNIFIED IDEOGRAPH + {0x87B6, 0x56A9}, //1258 #CJK UNIFIED IDEOGRAPH + {0x87B7, 0x56AA}, //1259 #CJK UNIFIED IDEOGRAPH + {0x87B8, 0x56AB}, //1260 #CJK UNIFIED IDEOGRAPH + {0x87B9, 0x56AC}, //1261 #CJK UNIFIED IDEOGRAPH + {0x87BA, 0x56AD}, //1262 #CJK UNIFIED IDEOGRAPH + {0x87BB, 0x56AE}, //1263 #CJK UNIFIED IDEOGRAPH + {0x87BC, 0x56B0}, //1264 #CJK UNIFIED IDEOGRAPH + {0x87BD, 0x56B1}, //1265 #CJK UNIFIED IDEOGRAPH + {0x87BE, 0x56B2}, //1266 #CJK UNIFIED IDEOGRAPH + {0x87BF, 0x56B3}, //1267 #CJK UNIFIED IDEOGRAPH + {0x87C0, 0x56B4}, //1268 #CJK UNIFIED IDEOGRAPH + {0x87C1, 0x56B5}, //1269 #CJK UNIFIED IDEOGRAPH + {0x87C2, 0x56B6}, //1270 #CJK UNIFIED IDEOGRAPH + {0x87C3, 0x56B8}, //1271 #CJK UNIFIED IDEOGRAPH + {0x87C4, 0x56B9}, //1272 #CJK UNIFIED IDEOGRAPH + {0x87C5, 0x56BA}, //1273 #CJK UNIFIED IDEOGRAPH + {0x87C6, 0x56BB}, //1274 #CJK UNIFIED IDEOGRAPH + {0x87C7, 0x56BD}, //1275 #CJK UNIFIED IDEOGRAPH + {0x87C8, 0x56BE}, //1276 #CJK UNIFIED IDEOGRAPH + {0x87C9, 0x56BF}, //1277 #CJK UNIFIED IDEOGRAPH + {0x87CA, 0x56C0}, //1278 #CJK UNIFIED IDEOGRAPH + {0x87CB, 0x56C1}, //1279 #CJK UNIFIED IDEOGRAPH + {0x87CC, 0x56C2}, //1280 #CJK UNIFIED IDEOGRAPH + {0x87CD, 0x56C3}, //1281 #CJK UNIFIED IDEOGRAPH + {0x87CE, 0x56C4}, //1282 #CJK UNIFIED IDEOGRAPH + {0x87CF, 0x56C5}, //1283 #CJK UNIFIED IDEOGRAPH + {0x87D0, 0x56C6}, //1284 #CJK UNIFIED IDEOGRAPH + {0x87D1, 0x56C7}, //1285 #CJK UNIFIED IDEOGRAPH + {0x87D2, 0x56C8}, //1286 #CJK UNIFIED IDEOGRAPH + {0x87D3, 0x56C9}, //1287 #CJK UNIFIED IDEOGRAPH + {0x87D4, 0x56CB}, //1288 #CJK UNIFIED IDEOGRAPH + {0x87D5, 0x56CC}, //1289 #CJK UNIFIED IDEOGRAPH + {0x87D6, 0x56CD}, //1290 #CJK UNIFIED IDEOGRAPH + {0x87D7, 0x56CE}, //1291 #CJK UNIFIED IDEOGRAPH + {0x87D8, 0x56CF}, //1292 #CJK UNIFIED IDEOGRAPH + {0x87D9, 0x56D0}, //1293 #CJK UNIFIED IDEOGRAPH + {0x87DA, 0x56D1}, //1294 #CJK UNIFIED IDEOGRAPH + {0x87DB, 0x56D2}, //1295 #CJK UNIFIED IDEOGRAPH + {0x87DC, 0x56D3}, //1296 #CJK UNIFIED IDEOGRAPH + {0x87DD, 0x56D5}, //1297 #CJK UNIFIED IDEOGRAPH + {0x87DE, 0x56D6}, //1298 #CJK UNIFIED IDEOGRAPH + {0x87DF, 0x56D8}, //1299 #CJK UNIFIED IDEOGRAPH + {0x87E0, 0x56D9}, //1300 #CJK UNIFIED IDEOGRAPH + {0x87E1, 0x56DC}, //1301 #CJK UNIFIED IDEOGRAPH + {0x87E2, 0x56E3}, //1302 #CJK UNIFIED IDEOGRAPH + {0x87E3, 0x56E5}, //1303 #CJK UNIFIED IDEOGRAPH + {0x87E4, 0x56E6}, //1304 #CJK UNIFIED IDEOGRAPH + {0x87E5, 0x56E7}, //1305 #CJK UNIFIED IDEOGRAPH + {0x87E6, 0x56E8}, //1306 #CJK UNIFIED IDEOGRAPH + {0x87E7, 0x56E9}, //1307 #CJK UNIFIED IDEOGRAPH + {0x87E8, 0x56EA}, //1308 #CJK UNIFIED IDEOGRAPH + {0x87E9, 0x56EC}, //1309 #CJK UNIFIED IDEOGRAPH + {0x87EA, 0x56EE}, //1310 #CJK UNIFIED IDEOGRAPH + {0x87EB, 0x56EF}, //1311 #CJK UNIFIED IDEOGRAPH + {0x87EC, 0x56F2}, //1312 #CJK UNIFIED IDEOGRAPH + {0x87ED, 0x56F3}, //1313 #CJK UNIFIED IDEOGRAPH + {0x87EE, 0x56F6}, //1314 #CJK UNIFIED IDEOGRAPH + {0x87EF, 0x56F7}, //1315 #CJK UNIFIED IDEOGRAPH + {0x87F0, 0x56F8}, //1316 #CJK UNIFIED IDEOGRAPH + {0x87F1, 0x56FB}, //1317 #CJK UNIFIED IDEOGRAPH + {0x87F2, 0x56FC}, //1318 #CJK UNIFIED IDEOGRAPH + {0x87F3, 0x5700}, //1319 #CJK UNIFIED IDEOGRAPH + {0x87F4, 0x5701}, //1320 #CJK UNIFIED IDEOGRAPH + {0x87F5, 0x5702}, //1321 #CJK UNIFIED IDEOGRAPH + {0x87F6, 0x5705}, //1322 #CJK UNIFIED IDEOGRAPH + {0x87F7, 0x5707}, //1323 #CJK UNIFIED IDEOGRAPH + {0x87F8, 0x570B}, //1324 #CJK UNIFIED IDEOGRAPH + {0x87F9, 0x570C}, //1325 #CJK UNIFIED IDEOGRAPH + {0x87FA, 0x570D}, //1326 #CJK UNIFIED IDEOGRAPH + {0x87FB, 0x570E}, //1327 #CJK UNIFIED IDEOGRAPH + {0x87FC, 0x570F}, //1328 #CJK UNIFIED IDEOGRAPH + {0x87FD, 0x5710}, //1329 #CJK UNIFIED IDEOGRAPH + {0x87FE, 0x5711}, //1330 #CJK UNIFIED IDEOGRAPH + {0x8840, 0x5712}, //1331 #CJK UNIFIED IDEOGRAPH + {0x8841, 0x5713}, //1332 #CJK UNIFIED IDEOGRAPH + {0x8842, 0x5714}, //1333 #CJK UNIFIED IDEOGRAPH + {0x8843, 0x5715}, //1334 #CJK UNIFIED IDEOGRAPH + {0x8844, 0x5716}, //1335 #CJK UNIFIED IDEOGRAPH + {0x8845, 0x5717}, //1336 #CJK UNIFIED IDEOGRAPH + {0x8846, 0x5718}, //1337 #CJK UNIFIED IDEOGRAPH + {0x8847, 0x5719}, //1338 #CJK UNIFIED IDEOGRAPH + {0x8848, 0x571A}, //1339 #CJK UNIFIED IDEOGRAPH + {0x8849, 0x571B}, //1340 #CJK UNIFIED IDEOGRAPH + {0x884A, 0x571D}, //1341 #CJK UNIFIED IDEOGRAPH + {0x884B, 0x571E}, //1342 #CJK UNIFIED IDEOGRAPH + {0x884C, 0x5720}, //1343 #CJK UNIFIED IDEOGRAPH + {0x884D, 0x5721}, //1344 #CJK UNIFIED IDEOGRAPH + {0x884E, 0x5722}, //1345 #CJK UNIFIED IDEOGRAPH + {0x884F, 0x5724}, //1346 #CJK UNIFIED IDEOGRAPH + {0x8850, 0x5725}, //1347 #CJK UNIFIED IDEOGRAPH + {0x8851, 0x5726}, //1348 #CJK UNIFIED IDEOGRAPH + {0x8852, 0x5727}, //1349 #CJK UNIFIED IDEOGRAPH + {0x8853, 0x572B}, //1350 #CJK UNIFIED IDEOGRAPH + {0x8854, 0x5731}, //1351 #CJK UNIFIED IDEOGRAPH + {0x8855, 0x5732}, //1352 #CJK UNIFIED IDEOGRAPH + {0x8856, 0x5734}, //1353 #CJK UNIFIED IDEOGRAPH + {0x8857, 0x5735}, //1354 #CJK UNIFIED IDEOGRAPH + {0x8858, 0x5736}, //1355 #CJK UNIFIED IDEOGRAPH + {0x8859, 0x5737}, //1356 #CJK UNIFIED IDEOGRAPH + {0x885A, 0x5738}, //1357 #CJK UNIFIED IDEOGRAPH + {0x885B, 0x573C}, //1358 #CJK UNIFIED IDEOGRAPH + {0x885C, 0x573D}, //1359 #CJK UNIFIED IDEOGRAPH + {0x885D, 0x573F}, //1360 #CJK UNIFIED IDEOGRAPH + {0x885E, 0x5741}, //1361 #CJK UNIFIED IDEOGRAPH + {0x885F, 0x5743}, //1362 #CJK UNIFIED IDEOGRAPH + {0x8860, 0x5744}, //1363 #CJK UNIFIED IDEOGRAPH + {0x8861, 0x5745}, //1364 #CJK UNIFIED IDEOGRAPH + {0x8862, 0x5746}, //1365 #CJK UNIFIED IDEOGRAPH + {0x8863, 0x5748}, //1366 #CJK UNIFIED IDEOGRAPH + {0x8864, 0x5749}, //1367 #CJK UNIFIED IDEOGRAPH + {0x8865, 0x574B}, //1368 #CJK UNIFIED IDEOGRAPH + {0x8866, 0x5752}, //1369 #CJK UNIFIED IDEOGRAPH + {0x8867, 0x5753}, //1370 #CJK UNIFIED IDEOGRAPH + {0x8868, 0x5754}, //1371 #CJK UNIFIED IDEOGRAPH + {0x8869, 0x5755}, //1372 #CJK UNIFIED IDEOGRAPH + {0x886A, 0x5756}, //1373 #CJK UNIFIED IDEOGRAPH + {0x886B, 0x5758}, //1374 #CJK UNIFIED IDEOGRAPH + {0x886C, 0x5759}, //1375 #CJK UNIFIED IDEOGRAPH + {0x886D, 0x5762}, //1376 #CJK UNIFIED IDEOGRAPH + {0x886E, 0x5763}, //1377 #CJK UNIFIED IDEOGRAPH + {0x886F, 0x5765}, //1378 #CJK UNIFIED IDEOGRAPH + {0x8870, 0x5767}, //1379 #CJK UNIFIED IDEOGRAPH + {0x8871, 0x576C}, //1380 #CJK UNIFIED IDEOGRAPH + {0x8872, 0x576E}, //1381 #CJK UNIFIED IDEOGRAPH + {0x8873, 0x5770}, //1382 #CJK UNIFIED IDEOGRAPH + {0x8874, 0x5771}, //1383 #CJK UNIFIED IDEOGRAPH + {0x8875, 0x5772}, //1384 #CJK UNIFIED IDEOGRAPH + {0x8876, 0x5774}, //1385 #CJK UNIFIED IDEOGRAPH + {0x8877, 0x5775}, //1386 #CJK UNIFIED IDEOGRAPH + {0x8878, 0x5778}, //1387 #CJK UNIFIED IDEOGRAPH + {0x8879, 0x5779}, //1388 #CJK UNIFIED IDEOGRAPH + {0x887A, 0x577A}, //1389 #CJK UNIFIED IDEOGRAPH + {0x887B, 0x577D}, //1390 #CJK UNIFIED IDEOGRAPH + {0x887C, 0x577E}, //1391 #CJK UNIFIED IDEOGRAPH + {0x887D, 0x577F}, //1392 #CJK UNIFIED IDEOGRAPH + {0x887E, 0x5780}, //1393 #CJK UNIFIED IDEOGRAPH + {0x8880, 0x5781}, //1394 #CJK UNIFIED IDEOGRAPH + {0x8881, 0x5787}, //1395 #CJK UNIFIED IDEOGRAPH + {0x8882, 0x5788}, //1396 #CJK UNIFIED IDEOGRAPH + {0x8883, 0x5789}, //1397 #CJK UNIFIED IDEOGRAPH + {0x8884, 0x578A}, //1398 #CJK UNIFIED IDEOGRAPH + {0x8885, 0x578D}, //1399 #CJK UNIFIED IDEOGRAPH + {0x8886, 0x578E}, //1400 #CJK UNIFIED IDEOGRAPH + {0x8887, 0x578F}, //1401 #CJK UNIFIED IDEOGRAPH + {0x8888, 0x5790}, //1402 #CJK UNIFIED IDEOGRAPH + {0x8889, 0x5791}, //1403 #CJK UNIFIED IDEOGRAPH + {0x888A, 0x5794}, //1404 #CJK UNIFIED IDEOGRAPH + {0x888B, 0x5795}, //1405 #CJK UNIFIED IDEOGRAPH + {0x888C, 0x5796}, //1406 #CJK UNIFIED IDEOGRAPH + {0x888D, 0x5797}, //1407 #CJK UNIFIED IDEOGRAPH + {0x888E, 0x5798}, //1408 #CJK UNIFIED IDEOGRAPH + {0x888F, 0x5799}, //1409 #CJK UNIFIED IDEOGRAPH + {0x8890, 0x579A}, //1410 #CJK UNIFIED IDEOGRAPH + {0x8891, 0x579C}, //1411 #CJK UNIFIED IDEOGRAPH + {0x8892, 0x579D}, //1412 #CJK UNIFIED IDEOGRAPH + {0x8893, 0x579E}, //1413 #CJK UNIFIED IDEOGRAPH + {0x8894, 0x579F}, //1414 #CJK UNIFIED IDEOGRAPH + {0x8895, 0x57A5}, //1415 #CJK UNIFIED IDEOGRAPH + {0x8896, 0x57A8}, //1416 #CJK UNIFIED IDEOGRAPH + {0x8897, 0x57AA}, //1417 #CJK UNIFIED IDEOGRAPH + {0x8898, 0x57AC}, //1418 #CJK UNIFIED IDEOGRAPH + {0x8899, 0x57AF}, //1419 #CJK UNIFIED IDEOGRAPH + {0x889A, 0x57B0}, //1420 #CJK UNIFIED IDEOGRAPH + {0x889B, 0x57B1}, //1421 #CJK UNIFIED IDEOGRAPH + {0x889C, 0x57B3}, //1422 #CJK UNIFIED IDEOGRAPH + {0x889D, 0x57B5}, //1423 #CJK UNIFIED IDEOGRAPH + {0x889E, 0x57B6}, //1424 #CJK UNIFIED IDEOGRAPH + {0x889F, 0x57B7}, //1425 #CJK UNIFIED IDEOGRAPH + {0x88A0, 0x57B9}, //1426 #CJK UNIFIED IDEOGRAPH + {0x88A1, 0x57BA}, //1427 #CJK UNIFIED IDEOGRAPH + {0x88A2, 0x57BB}, //1428 #CJK UNIFIED IDEOGRAPH + {0x88A3, 0x57BC}, //1429 #CJK UNIFIED IDEOGRAPH + {0x88A4, 0x57BD}, //1430 #CJK UNIFIED IDEOGRAPH + {0x88A5, 0x57BE}, //1431 #CJK UNIFIED IDEOGRAPH + {0x88A6, 0x57BF}, //1432 #CJK UNIFIED IDEOGRAPH + {0x88A7, 0x57C0}, //1433 #CJK UNIFIED IDEOGRAPH + {0x88A8, 0x57C1}, //1434 #CJK UNIFIED IDEOGRAPH + {0x88A9, 0x57C4}, //1435 #CJK UNIFIED IDEOGRAPH + {0x88AA, 0x57C5}, //1436 #CJK UNIFIED IDEOGRAPH + {0x88AB, 0x57C6}, //1437 #CJK UNIFIED IDEOGRAPH + {0x88AC, 0x57C7}, //1438 #CJK UNIFIED IDEOGRAPH + {0x88AD, 0x57C8}, //1439 #CJK UNIFIED IDEOGRAPH + {0x88AE, 0x57C9}, //1440 #CJK UNIFIED IDEOGRAPH + {0x88AF, 0x57CA}, //1441 #CJK UNIFIED IDEOGRAPH + {0x88B0, 0x57CC}, //1442 #CJK UNIFIED IDEOGRAPH + {0x88B1, 0x57CD}, //1443 #CJK UNIFIED IDEOGRAPH + {0x88B2, 0x57D0}, //1444 #CJK UNIFIED IDEOGRAPH + {0x88B3, 0x57D1}, //1445 #CJK UNIFIED IDEOGRAPH + {0x88B4, 0x57D3}, //1446 #CJK UNIFIED IDEOGRAPH + {0x88B5, 0x57D6}, //1447 #CJK UNIFIED IDEOGRAPH + {0x88B6, 0x57D7}, //1448 #CJK UNIFIED IDEOGRAPH + {0x88B7, 0x57DB}, //1449 #CJK UNIFIED IDEOGRAPH + {0x88B8, 0x57DC}, //1450 #CJK UNIFIED IDEOGRAPH + {0x88B9, 0x57DE}, //1451 #CJK UNIFIED IDEOGRAPH + {0x88BA, 0x57E1}, //1452 #CJK UNIFIED IDEOGRAPH + {0x88BB, 0x57E2}, //1453 #CJK UNIFIED IDEOGRAPH + {0x88BC, 0x57E3}, //1454 #CJK UNIFIED IDEOGRAPH + {0x88BD, 0x57E5}, //1455 #CJK UNIFIED IDEOGRAPH + {0x88BE, 0x57E6}, //1456 #CJK UNIFIED IDEOGRAPH + {0x88BF, 0x57E7}, //1457 #CJK UNIFIED IDEOGRAPH + {0x88C0, 0x57E8}, //1458 #CJK UNIFIED IDEOGRAPH + {0x88C1, 0x57E9}, //1459 #CJK UNIFIED IDEOGRAPH + {0x88C2, 0x57EA}, //1460 #CJK UNIFIED IDEOGRAPH + {0x88C3, 0x57EB}, //1461 #CJK UNIFIED IDEOGRAPH + {0x88C4, 0x57EC}, //1462 #CJK UNIFIED IDEOGRAPH + {0x88C5, 0x57EE}, //1463 #CJK UNIFIED IDEOGRAPH + {0x88C6, 0x57F0}, //1464 #CJK UNIFIED IDEOGRAPH + {0x88C7, 0x57F1}, //1465 #CJK UNIFIED IDEOGRAPH + {0x88C8, 0x57F2}, //1466 #CJK UNIFIED IDEOGRAPH + {0x88C9, 0x57F3}, //1467 #CJK UNIFIED IDEOGRAPH + {0x88CA, 0x57F5}, //1468 #CJK UNIFIED IDEOGRAPH + {0x88CB, 0x57F6}, //1469 #CJK UNIFIED IDEOGRAPH + {0x88CC, 0x57F7}, //1470 #CJK UNIFIED IDEOGRAPH + {0x88CD, 0x57FB}, //1471 #CJK UNIFIED IDEOGRAPH + {0x88CE, 0x57FC}, //1472 #CJK UNIFIED IDEOGRAPH + {0x88CF, 0x57FE}, //1473 #CJK UNIFIED IDEOGRAPH + {0x88D0, 0x57FF}, //1474 #CJK UNIFIED IDEOGRAPH + {0x88D1, 0x5801}, //1475 #CJK UNIFIED IDEOGRAPH + {0x88D2, 0x5803}, //1476 #CJK UNIFIED IDEOGRAPH + {0x88D3, 0x5804}, //1477 #CJK UNIFIED IDEOGRAPH + {0x88D4, 0x5805}, //1478 #CJK UNIFIED IDEOGRAPH + {0x88D5, 0x5808}, //1479 #CJK UNIFIED IDEOGRAPH + {0x88D6, 0x5809}, //1480 #CJK UNIFIED IDEOGRAPH + {0x88D7, 0x580A}, //1481 #CJK UNIFIED IDEOGRAPH + {0x88D8, 0x580C}, //1482 #CJK UNIFIED IDEOGRAPH + {0x88D9, 0x580E}, //1483 #CJK UNIFIED IDEOGRAPH + {0x88DA, 0x580F}, //1484 #CJK UNIFIED IDEOGRAPH + {0x88DB, 0x5810}, //1485 #CJK UNIFIED IDEOGRAPH + {0x88DC, 0x5812}, //1486 #CJK UNIFIED IDEOGRAPH + {0x88DD, 0x5813}, //1487 #CJK UNIFIED IDEOGRAPH + {0x88DE, 0x5814}, //1488 #CJK UNIFIED IDEOGRAPH + {0x88DF, 0x5816}, //1489 #CJK UNIFIED IDEOGRAPH + {0x88E0, 0x5817}, //1490 #CJK UNIFIED IDEOGRAPH + {0x88E1, 0x5818}, //1491 #CJK UNIFIED IDEOGRAPH + {0x88E2, 0x581A}, //1492 #CJK UNIFIED IDEOGRAPH + {0x88E3, 0x581B}, //1493 #CJK UNIFIED IDEOGRAPH + {0x88E4, 0x581C}, //1494 #CJK UNIFIED IDEOGRAPH + {0x88E5, 0x581D}, //1495 #CJK UNIFIED IDEOGRAPH + {0x88E6, 0x581F}, //1496 #CJK UNIFIED IDEOGRAPH + {0x88E7, 0x5822}, //1497 #CJK UNIFIED IDEOGRAPH + {0x88E8, 0x5823}, //1498 #CJK UNIFIED IDEOGRAPH + {0x88E9, 0x5825}, //1499 #CJK UNIFIED IDEOGRAPH + {0x88EA, 0x5826}, //1500 #CJK UNIFIED IDEOGRAPH + {0x88EB, 0x5827}, //1501 #CJK UNIFIED IDEOGRAPH + {0x88EC, 0x5828}, //1502 #CJK UNIFIED IDEOGRAPH + {0x88ED, 0x5829}, //1503 #CJK UNIFIED IDEOGRAPH + {0x88EE, 0x582B}, //1504 #CJK UNIFIED IDEOGRAPH + {0x88EF, 0x582C}, //1505 #CJK UNIFIED IDEOGRAPH + {0x88F0, 0x582D}, //1506 #CJK UNIFIED IDEOGRAPH + {0x88F1, 0x582E}, //1507 #CJK UNIFIED IDEOGRAPH + {0x88F2, 0x582F}, //1508 #CJK UNIFIED IDEOGRAPH + {0x88F3, 0x5831}, //1509 #CJK UNIFIED IDEOGRAPH + {0x88F4, 0x5832}, //1510 #CJK UNIFIED IDEOGRAPH + {0x88F5, 0x5833}, //1511 #CJK UNIFIED IDEOGRAPH + {0x88F6, 0x5834}, //1512 #CJK UNIFIED IDEOGRAPH + {0x88F7, 0x5836}, //1513 #CJK UNIFIED IDEOGRAPH + {0x88F8, 0x5837}, //1514 #CJK UNIFIED IDEOGRAPH + {0x88F9, 0x5838}, //1515 #CJK UNIFIED IDEOGRAPH + {0x88FA, 0x5839}, //1516 #CJK UNIFIED IDEOGRAPH + {0x88FB, 0x583A}, //1517 #CJK UNIFIED IDEOGRAPH + {0x88FC, 0x583B}, //1518 #CJK UNIFIED IDEOGRAPH + {0x88FD, 0x583C}, //1519 #CJK UNIFIED IDEOGRAPH + {0x88FE, 0x583D}, //1520 #CJK UNIFIED IDEOGRAPH + {0x8940, 0x583E}, //1521 #CJK UNIFIED IDEOGRAPH + {0x8941, 0x583F}, //1522 #CJK UNIFIED IDEOGRAPH + {0x8942, 0x5840}, //1523 #CJK UNIFIED IDEOGRAPH + {0x8943, 0x5841}, //1524 #CJK UNIFIED IDEOGRAPH + {0x8944, 0x5842}, //1525 #CJK UNIFIED IDEOGRAPH + {0x8945, 0x5843}, //1526 #CJK UNIFIED IDEOGRAPH + {0x8946, 0x5845}, //1527 #CJK UNIFIED IDEOGRAPH + {0x8947, 0x5846}, //1528 #CJK UNIFIED IDEOGRAPH + {0x8948, 0x5847}, //1529 #CJK UNIFIED IDEOGRAPH + {0x8949, 0x5848}, //1530 #CJK UNIFIED IDEOGRAPH + {0x894A, 0x5849}, //1531 #CJK UNIFIED IDEOGRAPH + {0x894B, 0x584A}, //1532 #CJK UNIFIED IDEOGRAPH + {0x894C, 0x584B}, //1533 #CJK UNIFIED IDEOGRAPH + {0x894D, 0x584E}, //1534 #CJK UNIFIED IDEOGRAPH + {0x894E, 0x584F}, //1535 #CJK UNIFIED IDEOGRAPH + {0x894F, 0x5850}, //1536 #CJK UNIFIED IDEOGRAPH + {0x8950, 0x5852}, //1537 #CJK UNIFIED IDEOGRAPH + {0x8951, 0x5853}, //1538 #CJK UNIFIED IDEOGRAPH + {0x8952, 0x5855}, //1539 #CJK UNIFIED IDEOGRAPH + {0x8953, 0x5856}, //1540 #CJK UNIFIED IDEOGRAPH + {0x8954, 0x5857}, //1541 #CJK UNIFIED IDEOGRAPH + {0x8955, 0x5859}, //1542 #CJK UNIFIED IDEOGRAPH + {0x8956, 0x585A}, //1543 #CJK UNIFIED IDEOGRAPH + {0x8957, 0x585B}, //1544 #CJK UNIFIED IDEOGRAPH + {0x8958, 0x585C}, //1545 #CJK UNIFIED IDEOGRAPH + {0x8959, 0x585D}, //1546 #CJK UNIFIED IDEOGRAPH + {0x895A, 0x585F}, //1547 #CJK UNIFIED IDEOGRAPH + {0x895B, 0x5860}, //1548 #CJK UNIFIED IDEOGRAPH + {0x895C, 0x5861}, //1549 #CJK UNIFIED IDEOGRAPH + {0x895D, 0x5862}, //1550 #CJK UNIFIED IDEOGRAPH + {0x895E, 0x5863}, //1551 #CJK UNIFIED IDEOGRAPH + {0x895F, 0x5864}, //1552 #CJK UNIFIED IDEOGRAPH + {0x8960, 0x5866}, //1553 #CJK UNIFIED IDEOGRAPH + {0x8961, 0x5867}, //1554 #CJK UNIFIED IDEOGRAPH + {0x8962, 0x5868}, //1555 #CJK UNIFIED IDEOGRAPH + {0x8963, 0x5869}, //1556 #CJK UNIFIED IDEOGRAPH + {0x8964, 0x586A}, //1557 #CJK UNIFIED IDEOGRAPH + {0x8965, 0x586D}, //1558 #CJK UNIFIED IDEOGRAPH + {0x8966, 0x586E}, //1559 #CJK UNIFIED IDEOGRAPH + {0x8967, 0x586F}, //1560 #CJK UNIFIED IDEOGRAPH + {0x8968, 0x5870}, //1561 #CJK UNIFIED IDEOGRAPH + {0x8969, 0x5871}, //1562 #CJK UNIFIED IDEOGRAPH + {0x896A, 0x5872}, //1563 #CJK UNIFIED IDEOGRAPH + {0x896B, 0x5873}, //1564 #CJK UNIFIED IDEOGRAPH + {0x896C, 0x5874}, //1565 #CJK UNIFIED IDEOGRAPH + {0x896D, 0x5875}, //1566 #CJK UNIFIED IDEOGRAPH + {0x896E, 0x5876}, //1567 #CJK UNIFIED IDEOGRAPH + {0x896F, 0x5877}, //1568 #CJK UNIFIED IDEOGRAPH + {0x8970, 0x5878}, //1569 #CJK UNIFIED IDEOGRAPH + {0x8971, 0x5879}, //1570 #CJK UNIFIED IDEOGRAPH + {0x8972, 0x587A}, //1571 #CJK UNIFIED IDEOGRAPH + {0x8973, 0x587B}, //1572 #CJK UNIFIED IDEOGRAPH + {0x8974, 0x587C}, //1573 #CJK UNIFIED IDEOGRAPH + {0x8975, 0x587D}, //1574 #CJK UNIFIED IDEOGRAPH + {0x8976, 0x587F}, //1575 #CJK UNIFIED IDEOGRAPH + {0x8977, 0x5882}, //1576 #CJK UNIFIED IDEOGRAPH + {0x8978, 0x5884}, //1577 #CJK UNIFIED IDEOGRAPH + {0x8979, 0x5886}, //1578 #CJK UNIFIED IDEOGRAPH + {0x897A, 0x5887}, //1579 #CJK UNIFIED IDEOGRAPH + {0x897B, 0x5888}, //1580 #CJK UNIFIED IDEOGRAPH + {0x897C, 0x588A}, //1581 #CJK UNIFIED IDEOGRAPH + {0x897D, 0x588B}, //1582 #CJK UNIFIED IDEOGRAPH + {0x897E, 0x588C}, //1583 #CJK UNIFIED IDEOGRAPH + {0x8980, 0x588D}, //1584 #CJK UNIFIED IDEOGRAPH + {0x8981, 0x588E}, //1585 #CJK UNIFIED IDEOGRAPH + {0x8982, 0x588F}, //1586 #CJK UNIFIED IDEOGRAPH + {0x8983, 0x5890}, //1587 #CJK UNIFIED IDEOGRAPH + {0x8984, 0x5891}, //1588 #CJK UNIFIED IDEOGRAPH + {0x8985, 0x5894}, //1589 #CJK UNIFIED IDEOGRAPH + {0x8986, 0x5895}, //1590 #CJK UNIFIED IDEOGRAPH + {0x8987, 0x5896}, //1591 #CJK UNIFIED IDEOGRAPH + {0x8988, 0x5897}, //1592 #CJK UNIFIED IDEOGRAPH + {0x8989, 0x5898}, //1593 #CJK UNIFIED IDEOGRAPH + {0x898A, 0x589B}, //1594 #CJK UNIFIED IDEOGRAPH + {0x898B, 0x589C}, //1595 #CJK UNIFIED IDEOGRAPH + {0x898C, 0x589D}, //1596 #CJK UNIFIED IDEOGRAPH + {0x898D, 0x58A0}, //1597 #CJK UNIFIED IDEOGRAPH + {0x898E, 0x58A1}, //1598 #CJK UNIFIED IDEOGRAPH + {0x898F, 0x58A2}, //1599 #CJK UNIFIED IDEOGRAPH + {0x8990, 0x58A3}, //1600 #CJK UNIFIED IDEOGRAPH + {0x8991, 0x58A4}, //1601 #CJK UNIFIED IDEOGRAPH + {0x8992, 0x58A5}, //1602 #CJK UNIFIED IDEOGRAPH + {0x8993, 0x58A6}, //1603 #CJK UNIFIED IDEOGRAPH + {0x8994, 0x58A7}, //1604 #CJK UNIFIED IDEOGRAPH + {0x8995, 0x58AA}, //1605 #CJK UNIFIED IDEOGRAPH + {0x8996, 0x58AB}, //1606 #CJK UNIFIED IDEOGRAPH + {0x8997, 0x58AC}, //1607 #CJK UNIFIED IDEOGRAPH + {0x8998, 0x58AD}, //1608 #CJK UNIFIED IDEOGRAPH + {0x8999, 0x58AE}, //1609 #CJK UNIFIED IDEOGRAPH + {0x899A, 0x58AF}, //1610 #CJK UNIFIED IDEOGRAPH + {0x899B, 0x58B0}, //1611 #CJK UNIFIED IDEOGRAPH + {0x899C, 0x58B1}, //1612 #CJK UNIFIED IDEOGRAPH + {0x899D, 0x58B2}, //1613 #CJK UNIFIED IDEOGRAPH + {0x899E, 0x58B3}, //1614 #CJK UNIFIED IDEOGRAPH + {0x899F, 0x58B4}, //1615 #CJK UNIFIED IDEOGRAPH + {0x89A0, 0x58B5}, //1616 #CJK UNIFIED IDEOGRAPH + {0x89A1, 0x58B6}, //1617 #CJK UNIFIED IDEOGRAPH + {0x89A2, 0x58B7}, //1618 #CJK UNIFIED IDEOGRAPH + {0x89A3, 0x58B8}, //1619 #CJK UNIFIED IDEOGRAPH + {0x89A4, 0x58B9}, //1620 #CJK UNIFIED IDEOGRAPH + {0x89A5, 0x58BA}, //1621 #CJK UNIFIED IDEOGRAPH + {0x89A6, 0x58BB}, //1622 #CJK UNIFIED IDEOGRAPH + {0x89A7, 0x58BD}, //1623 #CJK UNIFIED IDEOGRAPH + {0x89A8, 0x58BE}, //1624 #CJK UNIFIED IDEOGRAPH + {0x89A9, 0x58BF}, //1625 #CJK UNIFIED IDEOGRAPH + {0x89AA, 0x58C0}, //1626 #CJK UNIFIED IDEOGRAPH + {0x89AB, 0x58C2}, //1627 #CJK UNIFIED IDEOGRAPH + {0x89AC, 0x58C3}, //1628 #CJK UNIFIED IDEOGRAPH + {0x89AD, 0x58C4}, //1629 #CJK UNIFIED IDEOGRAPH + {0x89AE, 0x58C6}, //1630 #CJK UNIFIED IDEOGRAPH + {0x89AF, 0x58C7}, //1631 #CJK UNIFIED IDEOGRAPH + {0x89B0, 0x58C8}, //1632 #CJK UNIFIED IDEOGRAPH + {0x89B1, 0x58C9}, //1633 #CJK UNIFIED IDEOGRAPH + {0x89B2, 0x58CA}, //1634 #CJK UNIFIED IDEOGRAPH + {0x89B3, 0x58CB}, //1635 #CJK UNIFIED IDEOGRAPH + {0x89B4, 0x58CC}, //1636 #CJK UNIFIED IDEOGRAPH + {0x89B5, 0x58CD}, //1637 #CJK UNIFIED IDEOGRAPH + {0x89B6, 0x58CE}, //1638 #CJK UNIFIED IDEOGRAPH + {0x89B7, 0x58CF}, //1639 #CJK UNIFIED IDEOGRAPH + {0x89B8, 0x58D0}, //1640 #CJK UNIFIED IDEOGRAPH + {0x89B9, 0x58D2}, //1641 #CJK UNIFIED IDEOGRAPH + {0x89BA, 0x58D3}, //1642 #CJK UNIFIED IDEOGRAPH + {0x89BB, 0x58D4}, //1643 #CJK UNIFIED IDEOGRAPH + {0x89BC, 0x58D6}, //1644 #CJK UNIFIED IDEOGRAPH + {0x89BD, 0x58D7}, //1645 #CJK UNIFIED IDEOGRAPH + {0x89BE, 0x58D8}, //1646 #CJK UNIFIED IDEOGRAPH + {0x89BF, 0x58D9}, //1647 #CJK UNIFIED IDEOGRAPH + {0x89C0, 0x58DA}, //1648 #CJK UNIFIED IDEOGRAPH + {0x89C1, 0x58DB}, //1649 #CJK UNIFIED IDEOGRAPH + {0x89C2, 0x58DC}, //1650 #CJK UNIFIED IDEOGRAPH + {0x89C3, 0x58DD}, //1651 #CJK UNIFIED IDEOGRAPH + {0x89C4, 0x58DE}, //1652 #CJK UNIFIED IDEOGRAPH + {0x89C5, 0x58DF}, //1653 #CJK UNIFIED IDEOGRAPH + {0x89C6, 0x58E0}, //1654 #CJK UNIFIED IDEOGRAPH + {0x89C7, 0x58E1}, //1655 #CJK UNIFIED IDEOGRAPH + {0x89C8, 0x58E2}, //1656 #CJK UNIFIED IDEOGRAPH + {0x89C9, 0x58E3}, //1657 #CJK UNIFIED IDEOGRAPH + {0x89CA, 0x58E5}, //1658 #CJK UNIFIED IDEOGRAPH + {0x89CB, 0x58E6}, //1659 #CJK UNIFIED IDEOGRAPH + {0x89CC, 0x58E7}, //1660 #CJK UNIFIED IDEOGRAPH + {0x89CD, 0x58E8}, //1661 #CJK UNIFIED IDEOGRAPH + {0x89CE, 0x58E9}, //1662 #CJK UNIFIED IDEOGRAPH + {0x89CF, 0x58EA}, //1663 #CJK UNIFIED IDEOGRAPH + {0x89D0, 0x58ED}, //1664 #CJK UNIFIED IDEOGRAPH + {0x89D1, 0x58EF}, //1665 #CJK UNIFIED IDEOGRAPH + {0x89D2, 0x58F1}, //1666 #CJK UNIFIED IDEOGRAPH + {0x89D3, 0x58F2}, //1667 #CJK UNIFIED IDEOGRAPH + {0x89D4, 0x58F4}, //1668 #CJK UNIFIED IDEOGRAPH + {0x89D5, 0x58F5}, //1669 #CJK UNIFIED IDEOGRAPH + {0x89D6, 0x58F7}, //1670 #CJK UNIFIED IDEOGRAPH + {0x89D7, 0x58F8}, //1671 #CJK UNIFIED IDEOGRAPH + {0x89D8, 0x58FA}, //1672 #CJK UNIFIED IDEOGRAPH + {0x89D9, 0x58FB}, //1673 #CJK UNIFIED IDEOGRAPH + {0x89DA, 0x58FC}, //1674 #CJK UNIFIED IDEOGRAPH + {0x89DB, 0x58FD}, //1675 #CJK UNIFIED IDEOGRAPH + {0x89DC, 0x58FE}, //1676 #CJK UNIFIED IDEOGRAPH + {0x89DD, 0x58FF}, //1677 #CJK UNIFIED IDEOGRAPH + {0x89DE, 0x5900}, //1678 #CJK UNIFIED IDEOGRAPH + {0x89DF, 0x5901}, //1679 #CJK UNIFIED IDEOGRAPH + {0x89E0, 0x5903}, //1680 #CJK UNIFIED IDEOGRAPH + {0x89E1, 0x5905}, //1681 #CJK UNIFIED IDEOGRAPH + {0x89E2, 0x5906}, //1682 #CJK UNIFIED IDEOGRAPH + {0x89E3, 0x5908}, //1683 #CJK UNIFIED IDEOGRAPH + {0x89E4, 0x5909}, //1684 #CJK UNIFIED IDEOGRAPH + {0x89E5, 0x590A}, //1685 #CJK UNIFIED IDEOGRAPH + {0x89E6, 0x590B}, //1686 #CJK UNIFIED IDEOGRAPH + {0x89E7, 0x590C}, //1687 #CJK UNIFIED IDEOGRAPH + {0x89E8, 0x590E}, //1688 #CJK UNIFIED IDEOGRAPH + {0x89E9, 0x5910}, //1689 #CJK UNIFIED IDEOGRAPH + {0x89EA, 0x5911}, //1690 #CJK UNIFIED IDEOGRAPH + {0x89EB, 0x5912}, //1691 #CJK UNIFIED IDEOGRAPH + {0x89EC, 0x5913}, //1692 #CJK UNIFIED IDEOGRAPH + {0x89ED, 0x5917}, //1693 #CJK UNIFIED IDEOGRAPH + {0x89EE, 0x5918}, //1694 #CJK UNIFIED IDEOGRAPH + {0x89EF, 0x591B}, //1695 #CJK UNIFIED IDEOGRAPH + {0x89F0, 0x591D}, //1696 #CJK UNIFIED IDEOGRAPH + {0x89F1, 0x591E}, //1697 #CJK UNIFIED IDEOGRAPH + {0x89F2, 0x5920}, //1698 #CJK UNIFIED IDEOGRAPH + {0x89F3, 0x5921}, //1699 #CJK UNIFIED IDEOGRAPH + {0x89F4, 0x5922}, //1700 #CJK UNIFIED IDEOGRAPH + {0x89F5, 0x5923}, //1701 #CJK UNIFIED IDEOGRAPH + {0x89F6, 0x5926}, //1702 #CJK UNIFIED IDEOGRAPH + {0x89F7, 0x5928}, //1703 #CJK UNIFIED IDEOGRAPH + {0x89F8, 0x592C}, //1704 #CJK UNIFIED IDEOGRAPH + {0x89F9, 0x5930}, //1705 #CJK UNIFIED IDEOGRAPH + {0x89FA, 0x5932}, //1706 #CJK UNIFIED IDEOGRAPH + {0x89FB, 0x5933}, //1707 #CJK UNIFIED IDEOGRAPH + {0x89FC, 0x5935}, //1708 #CJK UNIFIED IDEOGRAPH + {0x89FD, 0x5936}, //1709 #CJK UNIFIED IDEOGRAPH + {0x89FE, 0x593B}, //1710 #CJK UNIFIED IDEOGRAPH + {0x8A40, 0x593D}, //1711 #CJK UNIFIED IDEOGRAPH + {0x8A41, 0x593E}, //1712 #CJK UNIFIED IDEOGRAPH + {0x8A42, 0x593F}, //1713 #CJK UNIFIED IDEOGRAPH + {0x8A43, 0x5940}, //1714 #CJK UNIFIED IDEOGRAPH + {0x8A44, 0x5943}, //1715 #CJK UNIFIED IDEOGRAPH + {0x8A45, 0x5945}, //1716 #CJK UNIFIED IDEOGRAPH + {0x8A46, 0x5946}, //1717 #CJK UNIFIED IDEOGRAPH + {0x8A47, 0x594A}, //1718 #CJK UNIFIED IDEOGRAPH + {0x8A48, 0x594C}, //1719 #CJK UNIFIED IDEOGRAPH + {0x8A49, 0x594D}, //1720 #CJK UNIFIED IDEOGRAPH + {0x8A4A, 0x5950}, //1721 #CJK UNIFIED IDEOGRAPH + {0x8A4B, 0x5952}, //1722 #CJK UNIFIED IDEOGRAPH + {0x8A4C, 0x5953}, //1723 #CJK UNIFIED IDEOGRAPH + {0x8A4D, 0x5959}, //1724 #CJK UNIFIED IDEOGRAPH + {0x8A4E, 0x595B}, //1725 #CJK UNIFIED IDEOGRAPH + {0x8A4F, 0x595C}, //1726 #CJK UNIFIED IDEOGRAPH + {0x8A50, 0x595D}, //1727 #CJK UNIFIED IDEOGRAPH + {0x8A51, 0x595E}, //1728 #CJK UNIFIED IDEOGRAPH + {0x8A52, 0x595F}, //1729 #CJK UNIFIED IDEOGRAPH + {0x8A53, 0x5961}, //1730 #CJK UNIFIED IDEOGRAPH + {0x8A54, 0x5963}, //1731 #CJK UNIFIED IDEOGRAPH + {0x8A55, 0x5964}, //1732 #CJK UNIFIED IDEOGRAPH + {0x8A56, 0x5966}, //1733 #CJK UNIFIED IDEOGRAPH + {0x8A57, 0x5967}, //1734 #CJK UNIFIED IDEOGRAPH + {0x8A58, 0x5968}, //1735 #CJK UNIFIED IDEOGRAPH + {0x8A59, 0x5969}, //1736 #CJK UNIFIED IDEOGRAPH + {0x8A5A, 0x596A}, //1737 #CJK UNIFIED IDEOGRAPH + {0x8A5B, 0x596B}, //1738 #CJK UNIFIED IDEOGRAPH + {0x8A5C, 0x596C}, //1739 #CJK UNIFIED IDEOGRAPH + {0x8A5D, 0x596D}, //1740 #CJK UNIFIED IDEOGRAPH + {0x8A5E, 0x596E}, //1741 #CJK UNIFIED IDEOGRAPH + {0x8A5F, 0x596F}, //1742 #CJK UNIFIED IDEOGRAPH + {0x8A60, 0x5970}, //1743 #CJK UNIFIED IDEOGRAPH + {0x8A61, 0x5971}, //1744 #CJK UNIFIED IDEOGRAPH + {0x8A62, 0x5972}, //1745 #CJK UNIFIED IDEOGRAPH + {0x8A63, 0x5975}, //1746 #CJK UNIFIED IDEOGRAPH + {0x8A64, 0x5977}, //1747 #CJK UNIFIED IDEOGRAPH + {0x8A65, 0x597A}, //1748 #CJK UNIFIED IDEOGRAPH + {0x8A66, 0x597B}, //1749 #CJK UNIFIED IDEOGRAPH + {0x8A67, 0x597C}, //1750 #CJK UNIFIED IDEOGRAPH + {0x8A68, 0x597E}, //1751 #CJK UNIFIED IDEOGRAPH + {0x8A69, 0x597F}, //1752 #CJK UNIFIED IDEOGRAPH + {0x8A6A, 0x5980}, //1753 #CJK UNIFIED IDEOGRAPH + {0x8A6B, 0x5985}, //1754 #CJK UNIFIED IDEOGRAPH + {0x8A6C, 0x5989}, //1755 #CJK UNIFIED IDEOGRAPH + {0x8A6D, 0x598B}, //1756 #CJK UNIFIED IDEOGRAPH + {0x8A6E, 0x598C}, //1757 #CJK UNIFIED IDEOGRAPH + {0x8A6F, 0x598E}, //1758 #CJK UNIFIED IDEOGRAPH + {0x8A70, 0x598F}, //1759 #CJK UNIFIED IDEOGRAPH + {0x8A71, 0x5990}, //1760 #CJK UNIFIED IDEOGRAPH + {0x8A72, 0x5991}, //1761 #CJK UNIFIED IDEOGRAPH + {0x8A73, 0x5994}, //1762 #CJK UNIFIED IDEOGRAPH + {0x8A74, 0x5995}, //1763 #CJK UNIFIED IDEOGRAPH + {0x8A75, 0x5998}, //1764 #CJK UNIFIED IDEOGRAPH + {0x8A76, 0x599A}, //1765 #CJK UNIFIED IDEOGRAPH + {0x8A77, 0x599B}, //1766 #CJK UNIFIED IDEOGRAPH + {0x8A78, 0x599C}, //1767 #CJK UNIFIED IDEOGRAPH + {0x8A79, 0x599D}, //1768 #CJK UNIFIED IDEOGRAPH + {0x8A7A, 0x599F}, //1769 #CJK UNIFIED IDEOGRAPH + {0x8A7B, 0x59A0}, //1770 #CJK UNIFIED IDEOGRAPH + {0x8A7C, 0x59A1}, //1771 #CJK UNIFIED IDEOGRAPH + {0x8A7D, 0x59A2}, //1772 #CJK UNIFIED IDEOGRAPH + {0x8A7E, 0x59A6}, //1773 #CJK UNIFIED IDEOGRAPH + {0x8A80, 0x59A7}, //1774 #CJK UNIFIED IDEOGRAPH + {0x8A81, 0x59AC}, //1775 #CJK UNIFIED IDEOGRAPH + {0x8A82, 0x59AD}, //1776 #CJK UNIFIED IDEOGRAPH + {0x8A83, 0x59B0}, //1777 #CJK UNIFIED IDEOGRAPH + {0x8A84, 0x59B1}, //1778 #CJK UNIFIED IDEOGRAPH + {0x8A85, 0x59B3}, //1779 #CJK UNIFIED IDEOGRAPH + {0x8A86, 0x59B4}, //1780 #CJK UNIFIED IDEOGRAPH + {0x8A87, 0x59B5}, //1781 #CJK UNIFIED IDEOGRAPH + {0x8A88, 0x59B6}, //1782 #CJK UNIFIED IDEOGRAPH + {0x8A89, 0x59B7}, //1783 #CJK UNIFIED IDEOGRAPH + {0x8A8A, 0x59B8}, //1784 #CJK UNIFIED IDEOGRAPH + {0x8A8B, 0x59BA}, //1785 #CJK UNIFIED IDEOGRAPH + {0x8A8C, 0x59BC}, //1786 #CJK UNIFIED IDEOGRAPH + {0x8A8D, 0x59BD}, //1787 #CJK UNIFIED IDEOGRAPH + {0x8A8E, 0x59BF}, //1788 #CJK UNIFIED IDEOGRAPH + {0x8A8F, 0x59C0}, //1789 #CJK UNIFIED IDEOGRAPH + {0x8A90, 0x59C1}, //1790 #CJK UNIFIED IDEOGRAPH + {0x8A91, 0x59C2}, //1791 #CJK UNIFIED IDEOGRAPH + {0x8A92, 0x59C3}, //1792 #CJK UNIFIED IDEOGRAPH + {0x8A93, 0x59C4}, //1793 #CJK UNIFIED IDEOGRAPH + {0x8A94, 0x59C5}, //1794 #CJK UNIFIED IDEOGRAPH + {0x8A95, 0x59C7}, //1795 #CJK UNIFIED IDEOGRAPH + {0x8A96, 0x59C8}, //1796 #CJK UNIFIED IDEOGRAPH + {0x8A97, 0x59C9}, //1797 #CJK UNIFIED IDEOGRAPH + {0x8A98, 0x59CC}, //1798 #CJK UNIFIED IDEOGRAPH + {0x8A99, 0x59CD}, //1799 #CJK UNIFIED IDEOGRAPH + {0x8A9A, 0x59CE}, //1800 #CJK UNIFIED IDEOGRAPH + {0x8A9B, 0x59CF}, //1801 #CJK UNIFIED IDEOGRAPH + {0x8A9C, 0x59D5}, //1802 #CJK UNIFIED IDEOGRAPH + {0x8A9D, 0x59D6}, //1803 #CJK UNIFIED IDEOGRAPH + {0x8A9E, 0x59D9}, //1804 #CJK UNIFIED IDEOGRAPH + {0x8A9F, 0x59DB}, //1805 #CJK UNIFIED IDEOGRAPH + {0x8AA0, 0x59DE}, //1806 #CJK UNIFIED IDEOGRAPH + {0x8AA1, 0x59DF}, //1807 #CJK UNIFIED IDEOGRAPH + {0x8AA2, 0x59E0}, //1808 #CJK UNIFIED IDEOGRAPH + {0x8AA3, 0x59E1}, //1809 #CJK UNIFIED IDEOGRAPH + {0x8AA4, 0x59E2}, //1810 #CJK UNIFIED IDEOGRAPH + {0x8AA5, 0x59E4}, //1811 #CJK UNIFIED IDEOGRAPH + {0x8AA6, 0x59E6}, //1812 #CJK UNIFIED IDEOGRAPH + {0x8AA7, 0x59E7}, //1813 #CJK UNIFIED IDEOGRAPH + {0x8AA8, 0x59E9}, //1814 #CJK UNIFIED IDEOGRAPH + {0x8AA9, 0x59EA}, //1815 #CJK UNIFIED IDEOGRAPH + {0x8AAA, 0x59EB}, //1816 #CJK UNIFIED IDEOGRAPH + {0x8AAB, 0x59ED}, //1817 #CJK UNIFIED IDEOGRAPH + {0x8AAC, 0x59EE}, //1818 #CJK UNIFIED IDEOGRAPH + {0x8AAD, 0x59EF}, //1819 #CJK UNIFIED IDEOGRAPH + {0x8AAE, 0x59F0}, //1820 #CJK UNIFIED IDEOGRAPH + {0x8AAF, 0x59F1}, //1821 #CJK UNIFIED IDEOGRAPH + {0x8AB0, 0x59F2}, //1822 #CJK UNIFIED IDEOGRAPH + {0x8AB1, 0x59F3}, //1823 #CJK UNIFIED IDEOGRAPH + {0x8AB2, 0x59F4}, //1824 #CJK UNIFIED IDEOGRAPH + {0x8AB3, 0x59F5}, //1825 #CJK UNIFIED IDEOGRAPH + {0x8AB4, 0x59F6}, //1826 #CJK UNIFIED IDEOGRAPH + {0x8AB5, 0x59F7}, //1827 #CJK UNIFIED IDEOGRAPH + {0x8AB6, 0x59F8}, //1828 #CJK UNIFIED IDEOGRAPH + {0x8AB7, 0x59FA}, //1829 #CJK UNIFIED IDEOGRAPH + {0x8AB8, 0x59FC}, //1830 #CJK UNIFIED IDEOGRAPH + {0x8AB9, 0x59FD}, //1831 #CJK UNIFIED IDEOGRAPH + {0x8ABA, 0x59FE}, //1832 #CJK UNIFIED IDEOGRAPH + {0x8ABB, 0x5A00}, //1833 #CJK UNIFIED IDEOGRAPH + {0x8ABC, 0x5A02}, //1834 #CJK UNIFIED IDEOGRAPH + {0x8ABD, 0x5A0A}, //1835 #CJK UNIFIED IDEOGRAPH + {0x8ABE, 0x5A0B}, //1836 #CJK UNIFIED IDEOGRAPH + {0x8ABF, 0x5A0D}, //1837 #CJK UNIFIED IDEOGRAPH + {0x8AC0, 0x5A0E}, //1838 #CJK UNIFIED IDEOGRAPH + {0x8AC1, 0x5A0F}, //1839 #CJK UNIFIED IDEOGRAPH + {0x8AC2, 0x5A10}, //1840 #CJK UNIFIED IDEOGRAPH + {0x8AC3, 0x5A12}, //1841 #CJK UNIFIED IDEOGRAPH + {0x8AC4, 0x5A14}, //1842 #CJK UNIFIED IDEOGRAPH + {0x8AC5, 0x5A15}, //1843 #CJK UNIFIED IDEOGRAPH + {0x8AC6, 0x5A16}, //1844 #CJK UNIFIED IDEOGRAPH + {0x8AC7, 0x5A17}, //1845 #CJK UNIFIED IDEOGRAPH + {0x8AC8, 0x5A19}, //1846 #CJK UNIFIED IDEOGRAPH + {0x8AC9, 0x5A1A}, //1847 #CJK UNIFIED IDEOGRAPH + {0x8ACA, 0x5A1B}, //1848 #CJK UNIFIED IDEOGRAPH + {0x8ACB, 0x5A1D}, //1849 #CJK UNIFIED IDEOGRAPH + {0x8ACC, 0x5A1E}, //1850 #CJK UNIFIED IDEOGRAPH + {0x8ACD, 0x5A21}, //1851 #CJK UNIFIED IDEOGRAPH + {0x8ACE, 0x5A22}, //1852 #CJK UNIFIED IDEOGRAPH + {0x8ACF, 0x5A24}, //1853 #CJK UNIFIED IDEOGRAPH + {0x8AD0, 0x5A26}, //1854 #CJK UNIFIED IDEOGRAPH + {0x8AD1, 0x5A27}, //1855 #CJK UNIFIED IDEOGRAPH + {0x8AD2, 0x5A28}, //1856 #CJK UNIFIED IDEOGRAPH + {0x8AD3, 0x5A2A}, //1857 #CJK UNIFIED IDEOGRAPH + {0x8AD4, 0x5A2B}, //1858 #CJK UNIFIED IDEOGRAPH + {0x8AD5, 0x5A2C}, //1859 #CJK UNIFIED IDEOGRAPH + {0x8AD6, 0x5A2D}, //1860 #CJK UNIFIED IDEOGRAPH + {0x8AD7, 0x5A2E}, //1861 #CJK UNIFIED IDEOGRAPH + {0x8AD8, 0x5A2F}, //1862 #CJK UNIFIED IDEOGRAPH + {0x8AD9, 0x5A30}, //1863 #CJK UNIFIED IDEOGRAPH + {0x8ADA, 0x5A33}, //1864 #CJK UNIFIED IDEOGRAPH + {0x8ADB, 0x5A35}, //1865 #CJK UNIFIED IDEOGRAPH + {0x8ADC, 0x5A37}, //1866 #CJK UNIFIED IDEOGRAPH + {0x8ADD, 0x5A38}, //1867 #CJK UNIFIED IDEOGRAPH + {0x8ADE, 0x5A39}, //1868 #CJK UNIFIED IDEOGRAPH + {0x8ADF, 0x5A3A}, //1869 #CJK UNIFIED IDEOGRAPH + {0x8AE0, 0x5A3B}, //1870 #CJK UNIFIED IDEOGRAPH + {0x8AE1, 0x5A3D}, //1871 #CJK UNIFIED IDEOGRAPH + {0x8AE2, 0x5A3E}, //1872 #CJK UNIFIED IDEOGRAPH + {0x8AE3, 0x5A3F}, //1873 #CJK UNIFIED IDEOGRAPH + {0x8AE4, 0x5A41}, //1874 #CJK UNIFIED IDEOGRAPH + {0x8AE5, 0x5A42}, //1875 #CJK UNIFIED IDEOGRAPH + {0x8AE6, 0x5A43}, //1876 #CJK UNIFIED IDEOGRAPH + {0x8AE7, 0x5A44}, //1877 #CJK UNIFIED IDEOGRAPH + {0x8AE8, 0x5A45}, //1878 #CJK UNIFIED IDEOGRAPH + {0x8AE9, 0x5A47}, //1879 #CJK UNIFIED IDEOGRAPH + {0x8AEA, 0x5A48}, //1880 #CJK UNIFIED IDEOGRAPH + {0x8AEB, 0x5A4B}, //1881 #CJK UNIFIED IDEOGRAPH + {0x8AEC, 0x5A4C}, //1882 #CJK UNIFIED IDEOGRAPH + {0x8AED, 0x5A4D}, //1883 #CJK UNIFIED IDEOGRAPH + {0x8AEE, 0x5A4E}, //1884 #CJK UNIFIED IDEOGRAPH + {0x8AEF, 0x5A4F}, //1885 #CJK UNIFIED IDEOGRAPH + {0x8AF0, 0x5A50}, //1886 #CJK UNIFIED IDEOGRAPH + {0x8AF1, 0x5A51}, //1887 #CJK UNIFIED IDEOGRAPH + {0x8AF2, 0x5A52}, //1888 #CJK UNIFIED IDEOGRAPH + {0x8AF3, 0x5A53}, //1889 #CJK UNIFIED IDEOGRAPH + {0x8AF4, 0x5A54}, //1890 #CJK UNIFIED IDEOGRAPH + {0x8AF5, 0x5A56}, //1891 #CJK UNIFIED IDEOGRAPH + {0x8AF6, 0x5A57}, //1892 #CJK UNIFIED IDEOGRAPH + {0x8AF7, 0x5A58}, //1893 #CJK UNIFIED IDEOGRAPH + {0x8AF8, 0x5A59}, //1894 #CJK UNIFIED IDEOGRAPH + {0x8AF9, 0x5A5B}, //1895 #CJK UNIFIED IDEOGRAPH + {0x8AFA, 0x5A5C}, //1896 #CJK UNIFIED IDEOGRAPH + {0x8AFB, 0x5A5D}, //1897 #CJK UNIFIED IDEOGRAPH + {0x8AFC, 0x5A5E}, //1898 #CJK UNIFIED IDEOGRAPH + {0x8AFD, 0x5A5F}, //1899 #CJK UNIFIED IDEOGRAPH + {0x8AFE, 0x5A60}, //1900 #CJK UNIFIED IDEOGRAPH + {0x8B40, 0x5A61}, //1901 #CJK UNIFIED IDEOGRAPH + {0x8B41, 0x5A63}, //1902 #CJK UNIFIED IDEOGRAPH + {0x8B42, 0x5A64}, //1903 #CJK UNIFIED IDEOGRAPH + {0x8B43, 0x5A65}, //1904 #CJK UNIFIED IDEOGRAPH + {0x8B44, 0x5A66}, //1905 #CJK UNIFIED IDEOGRAPH + {0x8B45, 0x5A68}, //1906 #CJK UNIFIED IDEOGRAPH + {0x8B46, 0x5A69}, //1907 #CJK UNIFIED IDEOGRAPH + {0x8B47, 0x5A6B}, //1908 #CJK UNIFIED IDEOGRAPH + {0x8B48, 0x5A6C}, //1909 #CJK UNIFIED IDEOGRAPH + {0x8B49, 0x5A6D}, //1910 #CJK UNIFIED IDEOGRAPH + {0x8B4A, 0x5A6E}, //1911 #CJK UNIFIED IDEOGRAPH + {0x8B4B, 0x5A6F}, //1912 #CJK UNIFIED IDEOGRAPH + {0x8B4C, 0x5A70}, //1913 #CJK UNIFIED IDEOGRAPH + {0x8B4D, 0x5A71}, //1914 #CJK UNIFIED IDEOGRAPH + {0x8B4E, 0x5A72}, //1915 #CJK UNIFIED IDEOGRAPH + {0x8B4F, 0x5A73}, //1916 #CJK UNIFIED IDEOGRAPH + {0x8B50, 0x5A78}, //1917 #CJK UNIFIED IDEOGRAPH + {0x8B51, 0x5A79}, //1918 #CJK UNIFIED IDEOGRAPH + {0x8B52, 0x5A7B}, //1919 #CJK UNIFIED IDEOGRAPH + {0x8B53, 0x5A7C}, //1920 #CJK UNIFIED IDEOGRAPH + {0x8B54, 0x5A7D}, //1921 #CJK UNIFIED IDEOGRAPH + {0x8B55, 0x5A7E}, //1922 #CJK UNIFIED IDEOGRAPH + {0x8B56, 0x5A80}, //1923 #CJK UNIFIED IDEOGRAPH + {0x8B57, 0x5A81}, //1924 #CJK UNIFIED IDEOGRAPH + {0x8B58, 0x5A82}, //1925 #CJK UNIFIED IDEOGRAPH + {0x8B59, 0x5A83}, //1926 #CJK UNIFIED IDEOGRAPH + {0x8B5A, 0x5A84}, //1927 #CJK UNIFIED IDEOGRAPH + {0x8B5B, 0x5A85}, //1928 #CJK UNIFIED IDEOGRAPH + {0x8B5C, 0x5A86}, //1929 #CJK UNIFIED IDEOGRAPH + {0x8B5D, 0x5A87}, //1930 #CJK UNIFIED IDEOGRAPH + {0x8B5E, 0x5A88}, //1931 #CJK UNIFIED IDEOGRAPH + {0x8B5F, 0x5A89}, //1932 #CJK UNIFIED IDEOGRAPH + {0x8B60, 0x5A8A}, //1933 #CJK UNIFIED IDEOGRAPH + {0x8B61, 0x5A8B}, //1934 #CJK UNIFIED IDEOGRAPH + {0x8B62, 0x5A8C}, //1935 #CJK UNIFIED IDEOGRAPH + {0x8B63, 0x5A8D}, //1936 #CJK UNIFIED IDEOGRAPH + {0x8B64, 0x5A8E}, //1937 #CJK UNIFIED IDEOGRAPH + {0x8B65, 0x5A8F}, //1938 #CJK UNIFIED IDEOGRAPH + {0x8B66, 0x5A90}, //1939 #CJK UNIFIED IDEOGRAPH + {0x8B67, 0x5A91}, //1940 #CJK UNIFIED IDEOGRAPH + {0x8B68, 0x5A93}, //1941 #CJK UNIFIED IDEOGRAPH + {0x8B69, 0x5A94}, //1942 #CJK UNIFIED IDEOGRAPH + {0x8B6A, 0x5A95}, //1943 #CJK UNIFIED IDEOGRAPH + {0x8B6B, 0x5A96}, //1944 #CJK UNIFIED IDEOGRAPH + {0x8B6C, 0x5A97}, //1945 #CJK UNIFIED IDEOGRAPH + {0x8B6D, 0x5A98}, //1946 #CJK UNIFIED IDEOGRAPH + {0x8B6E, 0x5A99}, //1947 #CJK UNIFIED IDEOGRAPH + {0x8B6F, 0x5A9C}, //1948 #CJK UNIFIED IDEOGRAPH + {0x8B70, 0x5A9D}, //1949 #CJK UNIFIED IDEOGRAPH + {0x8B71, 0x5A9E}, //1950 #CJK UNIFIED IDEOGRAPH + {0x8B72, 0x5A9F}, //1951 #CJK UNIFIED IDEOGRAPH + {0x8B73, 0x5AA0}, //1952 #CJK UNIFIED IDEOGRAPH + {0x8B74, 0x5AA1}, //1953 #CJK UNIFIED IDEOGRAPH + {0x8B75, 0x5AA2}, //1954 #CJK UNIFIED IDEOGRAPH + {0x8B76, 0x5AA3}, //1955 #CJK UNIFIED IDEOGRAPH + {0x8B77, 0x5AA4}, //1956 #CJK UNIFIED IDEOGRAPH + {0x8B78, 0x5AA5}, //1957 #CJK UNIFIED IDEOGRAPH + {0x8B79, 0x5AA6}, //1958 #CJK UNIFIED IDEOGRAPH + {0x8B7A, 0x5AA7}, //1959 #CJK UNIFIED IDEOGRAPH + {0x8B7B, 0x5AA8}, //1960 #CJK UNIFIED IDEOGRAPH + {0x8B7C, 0x5AA9}, //1961 #CJK UNIFIED IDEOGRAPH + {0x8B7D, 0x5AAB}, //1962 #CJK UNIFIED IDEOGRAPH + {0x8B7E, 0x5AAC}, //1963 #CJK UNIFIED IDEOGRAPH + {0x8B80, 0x5AAD}, //1964 #CJK UNIFIED IDEOGRAPH + {0x8B81, 0x5AAE}, //1965 #CJK UNIFIED IDEOGRAPH + {0x8B82, 0x5AAF}, //1966 #CJK UNIFIED IDEOGRAPH + {0x8B83, 0x5AB0}, //1967 #CJK UNIFIED IDEOGRAPH + {0x8B84, 0x5AB1}, //1968 #CJK UNIFIED IDEOGRAPH + {0x8B85, 0x5AB4}, //1969 #CJK UNIFIED IDEOGRAPH + {0x8B86, 0x5AB6}, //1970 #CJK UNIFIED IDEOGRAPH + {0x8B87, 0x5AB7}, //1971 #CJK UNIFIED IDEOGRAPH + {0x8B88, 0x5AB9}, //1972 #CJK UNIFIED IDEOGRAPH + {0x8B89, 0x5ABA}, //1973 #CJK UNIFIED IDEOGRAPH + {0x8B8A, 0x5ABB}, //1974 #CJK UNIFIED IDEOGRAPH + {0x8B8B, 0x5ABC}, //1975 #CJK UNIFIED IDEOGRAPH + {0x8B8C, 0x5ABD}, //1976 #CJK UNIFIED IDEOGRAPH + {0x8B8D, 0x5ABF}, //1977 #CJK UNIFIED IDEOGRAPH + {0x8B8E, 0x5AC0}, //1978 #CJK UNIFIED IDEOGRAPH + {0x8B8F, 0x5AC3}, //1979 #CJK UNIFIED IDEOGRAPH + {0x8B90, 0x5AC4}, //1980 #CJK UNIFIED IDEOGRAPH + {0x8B91, 0x5AC5}, //1981 #CJK UNIFIED IDEOGRAPH + {0x8B92, 0x5AC6}, //1982 #CJK UNIFIED IDEOGRAPH + {0x8B93, 0x5AC7}, //1983 #CJK UNIFIED IDEOGRAPH + {0x8B94, 0x5AC8}, //1984 #CJK UNIFIED IDEOGRAPH + {0x8B95, 0x5ACA}, //1985 #CJK UNIFIED IDEOGRAPH + {0x8B96, 0x5ACB}, //1986 #CJK UNIFIED IDEOGRAPH + {0x8B97, 0x5ACD}, //1987 #CJK UNIFIED IDEOGRAPH + {0x8B98, 0x5ACE}, //1988 #CJK UNIFIED IDEOGRAPH + {0x8B99, 0x5ACF}, //1989 #CJK UNIFIED IDEOGRAPH + {0x8B9A, 0x5AD0}, //1990 #CJK UNIFIED IDEOGRAPH + {0x8B9B, 0x5AD1}, //1991 #CJK UNIFIED IDEOGRAPH + {0x8B9C, 0x5AD3}, //1992 #CJK UNIFIED IDEOGRAPH + {0x8B9D, 0x5AD5}, //1993 #CJK UNIFIED IDEOGRAPH + {0x8B9E, 0x5AD7}, //1994 #CJK UNIFIED IDEOGRAPH + {0x8B9F, 0x5AD9}, //1995 #CJK UNIFIED IDEOGRAPH + {0x8BA0, 0x5ADA}, //1996 #CJK UNIFIED IDEOGRAPH + {0x8BA1, 0x5ADB}, //1997 #CJK UNIFIED IDEOGRAPH + {0x8BA2, 0x5ADD}, //1998 #CJK UNIFIED IDEOGRAPH + {0x8BA3, 0x5ADE}, //1999 #CJK UNIFIED IDEOGRAPH + {0x8BA4, 0x5ADF}, //2000 #CJK UNIFIED IDEOGRAPH + {0x8BA5, 0x5AE2}, //2001 #CJK UNIFIED IDEOGRAPH + {0x8BA6, 0x5AE4}, //2002 #CJK UNIFIED IDEOGRAPH + {0x8BA7, 0x5AE5}, //2003 #CJK UNIFIED IDEOGRAPH + {0x8BA8, 0x5AE7}, //2004 #CJK UNIFIED IDEOGRAPH + {0x8BA9, 0x5AE8}, //2005 #CJK UNIFIED IDEOGRAPH + {0x8BAA, 0x5AEA}, //2006 #CJK UNIFIED IDEOGRAPH + {0x8BAB, 0x5AEC}, //2007 #CJK UNIFIED IDEOGRAPH + {0x8BAC, 0x5AED}, //2008 #CJK UNIFIED IDEOGRAPH + {0x8BAD, 0x5AEE}, //2009 #CJK UNIFIED IDEOGRAPH + {0x8BAE, 0x5AEF}, //2010 #CJK UNIFIED IDEOGRAPH + {0x8BAF, 0x5AF0}, //2011 #CJK UNIFIED IDEOGRAPH + {0x8BB0, 0x5AF2}, //2012 #CJK UNIFIED IDEOGRAPH + {0x8BB1, 0x5AF3}, //2013 #CJK UNIFIED IDEOGRAPH + {0x8BB2, 0x5AF4}, //2014 #CJK UNIFIED IDEOGRAPH + {0x8BB3, 0x5AF5}, //2015 #CJK UNIFIED IDEOGRAPH + {0x8BB4, 0x5AF6}, //2016 #CJK UNIFIED IDEOGRAPH + {0x8BB5, 0x5AF7}, //2017 #CJK UNIFIED IDEOGRAPH + {0x8BB6, 0x5AF8}, //2018 #CJK UNIFIED IDEOGRAPH + {0x8BB7, 0x5AF9}, //2019 #CJK UNIFIED IDEOGRAPH + {0x8BB8, 0x5AFA}, //2020 #CJK UNIFIED IDEOGRAPH + {0x8BB9, 0x5AFB}, //2021 #CJK UNIFIED IDEOGRAPH + {0x8BBA, 0x5AFC}, //2022 #CJK UNIFIED IDEOGRAPH + {0x8BBB, 0x5AFD}, //2023 #CJK UNIFIED IDEOGRAPH + {0x8BBC, 0x5AFE}, //2024 #CJK UNIFIED IDEOGRAPH + {0x8BBD, 0x5AFF}, //2025 #CJK UNIFIED IDEOGRAPH + {0x8BBE, 0x5B00}, //2026 #CJK UNIFIED IDEOGRAPH + {0x8BBF, 0x5B01}, //2027 #CJK UNIFIED IDEOGRAPH + {0x8BC0, 0x5B02}, //2028 #CJK UNIFIED IDEOGRAPH + {0x8BC1, 0x5B03}, //2029 #CJK UNIFIED IDEOGRAPH + {0x8BC2, 0x5B04}, //2030 #CJK UNIFIED IDEOGRAPH + {0x8BC3, 0x5B05}, //2031 #CJK UNIFIED IDEOGRAPH + {0x8BC4, 0x5B06}, //2032 #CJK UNIFIED IDEOGRAPH + {0x8BC5, 0x5B07}, //2033 #CJK UNIFIED IDEOGRAPH + {0x8BC6, 0x5B08}, //2034 #CJK UNIFIED IDEOGRAPH + {0x8BC7, 0x5B0A}, //2035 #CJK UNIFIED IDEOGRAPH + {0x8BC8, 0x5B0B}, //2036 #CJK UNIFIED IDEOGRAPH + {0x8BC9, 0x5B0C}, //2037 #CJK UNIFIED IDEOGRAPH + {0x8BCA, 0x5B0D}, //2038 #CJK UNIFIED IDEOGRAPH + {0x8BCB, 0x5B0E}, //2039 #CJK UNIFIED IDEOGRAPH + {0x8BCC, 0x5B0F}, //2040 #CJK UNIFIED IDEOGRAPH + {0x8BCD, 0x5B10}, //2041 #CJK UNIFIED IDEOGRAPH + {0x8BCE, 0x5B11}, //2042 #CJK UNIFIED IDEOGRAPH + {0x8BCF, 0x5B12}, //2043 #CJK UNIFIED IDEOGRAPH + {0x8BD0, 0x5B13}, //2044 #CJK UNIFIED IDEOGRAPH + {0x8BD1, 0x5B14}, //2045 #CJK UNIFIED IDEOGRAPH + {0x8BD2, 0x5B15}, //2046 #CJK UNIFIED IDEOGRAPH + {0x8BD3, 0x5B18}, //2047 #CJK UNIFIED IDEOGRAPH + {0x8BD4, 0x5B19}, //2048 #CJK UNIFIED IDEOGRAPH + {0x8BD5, 0x5B1A}, //2049 #CJK UNIFIED IDEOGRAPH + {0x8BD6, 0x5B1B}, //2050 #CJK UNIFIED IDEOGRAPH + {0x8BD7, 0x5B1C}, //2051 #CJK UNIFIED IDEOGRAPH + {0x8BD8, 0x5B1D}, //2052 #CJK UNIFIED IDEOGRAPH + {0x8BD9, 0x5B1E}, //2053 #CJK UNIFIED IDEOGRAPH + {0x8BDA, 0x5B1F}, //2054 #CJK UNIFIED IDEOGRAPH + {0x8BDB, 0x5B20}, //2055 #CJK UNIFIED IDEOGRAPH + {0x8BDC, 0x5B21}, //2056 #CJK UNIFIED IDEOGRAPH + {0x8BDD, 0x5B22}, //2057 #CJK UNIFIED IDEOGRAPH + {0x8BDE, 0x5B23}, //2058 #CJK UNIFIED IDEOGRAPH + {0x8BDF, 0x5B24}, //2059 #CJK UNIFIED IDEOGRAPH + {0x8BE0, 0x5B25}, //2060 #CJK UNIFIED IDEOGRAPH + {0x8BE1, 0x5B26}, //2061 #CJK UNIFIED IDEOGRAPH + {0x8BE2, 0x5B27}, //2062 #CJK UNIFIED IDEOGRAPH + {0x8BE3, 0x5B28}, //2063 #CJK UNIFIED IDEOGRAPH + {0x8BE4, 0x5B29}, //2064 #CJK UNIFIED IDEOGRAPH + {0x8BE5, 0x5B2A}, //2065 #CJK UNIFIED IDEOGRAPH + {0x8BE6, 0x5B2B}, //2066 #CJK UNIFIED IDEOGRAPH + {0x8BE7, 0x5B2C}, //2067 #CJK UNIFIED IDEOGRAPH + {0x8BE8, 0x5B2D}, //2068 #CJK UNIFIED IDEOGRAPH + {0x8BE9, 0x5B2E}, //2069 #CJK UNIFIED IDEOGRAPH + {0x8BEA, 0x5B2F}, //2070 #CJK UNIFIED IDEOGRAPH + {0x8BEB, 0x5B30}, //2071 #CJK UNIFIED IDEOGRAPH + {0x8BEC, 0x5B31}, //2072 #CJK UNIFIED IDEOGRAPH + {0x8BED, 0x5B33}, //2073 #CJK UNIFIED IDEOGRAPH + {0x8BEE, 0x5B35}, //2074 #CJK UNIFIED IDEOGRAPH + {0x8BEF, 0x5B36}, //2075 #CJK UNIFIED IDEOGRAPH + {0x8BF0, 0x5B38}, //2076 #CJK UNIFIED IDEOGRAPH + {0x8BF1, 0x5B39}, //2077 #CJK UNIFIED IDEOGRAPH + {0x8BF2, 0x5B3A}, //2078 #CJK UNIFIED IDEOGRAPH + {0x8BF3, 0x5B3B}, //2079 #CJK UNIFIED IDEOGRAPH + {0x8BF4, 0x5B3C}, //2080 #CJK UNIFIED IDEOGRAPH + {0x8BF5, 0x5B3D}, //2081 #CJK UNIFIED IDEOGRAPH + {0x8BF6, 0x5B3E}, //2082 #CJK UNIFIED IDEOGRAPH + {0x8BF7, 0x5B3F}, //2083 #CJK UNIFIED IDEOGRAPH + {0x8BF8, 0x5B41}, //2084 #CJK UNIFIED IDEOGRAPH + {0x8BF9, 0x5B42}, //2085 #CJK UNIFIED IDEOGRAPH + {0x8BFA, 0x5B43}, //2086 #CJK UNIFIED IDEOGRAPH + {0x8BFB, 0x5B44}, //2087 #CJK UNIFIED IDEOGRAPH + {0x8BFC, 0x5B45}, //2088 #CJK UNIFIED IDEOGRAPH + {0x8BFD, 0x5B46}, //2089 #CJK UNIFIED IDEOGRAPH + {0x8BFE, 0x5B47}, //2090 #CJK UNIFIED IDEOGRAPH + {0x8C40, 0x5B48}, //2091 #CJK UNIFIED IDEOGRAPH + {0x8C41, 0x5B49}, //2092 #CJK UNIFIED IDEOGRAPH + {0x8C42, 0x5B4A}, //2093 #CJK UNIFIED IDEOGRAPH + {0x8C43, 0x5B4B}, //2094 #CJK UNIFIED IDEOGRAPH + {0x8C44, 0x5B4C}, //2095 #CJK UNIFIED IDEOGRAPH + {0x8C45, 0x5B4D}, //2096 #CJK UNIFIED IDEOGRAPH + {0x8C46, 0x5B4E}, //2097 #CJK UNIFIED IDEOGRAPH + {0x8C47, 0x5B4F}, //2098 #CJK UNIFIED IDEOGRAPH + {0x8C48, 0x5B52}, //2099 #CJK UNIFIED IDEOGRAPH + {0x8C49, 0x5B56}, //2100 #CJK UNIFIED IDEOGRAPH + {0x8C4A, 0x5B5E}, //2101 #CJK UNIFIED IDEOGRAPH + {0x8C4B, 0x5B60}, //2102 #CJK UNIFIED IDEOGRAPH + {0x8C4C, 0x5B61}, //2103 #CJK UNIFIED IDEOGRAPH + {0x8C4D, 0x5B67}, //2104 #CJK UNIFIED IDEOGRAPH + {0x8C4E, 0x5B68}, //2105 #CJK UNIFIED IDEOGRAPH + {0x8C4F, 0x5B6B}, //2106 #CJK UNIFIED IDEOGRAPH + {0x8C50, 0x5B6D}, //2107 #CJK UNIFIED IDEOGRAPH + {0x8C51, 0x5B6E}, //2108 #CJK UNIFIED IDEOGRAPH + {0x8C52, 0x5B6F}, //2109 #CJK UNIFIED IDEOGRAPH + {0x8C53, 0x5B72}, //2110 #CJK UNIFIED IDEOGRAPH + {0x8C54, 0x5B74}, //2111 #CJK UNIFIED IDEOGRAPH + {0x8C55, 0x5B76}, //2112 #CJK UNIFIED IDEOGRAPH + {0x8C56, 0x5B77}, //2113 #CJK UNIFIED IDEOGRAPH + {0x8C57, 0x5B78}, //2114 #CJK UNIFIED IDEOGRAPH + {0x8C58, 0x5B79}, //2115 #CJK UNIFIED IDEOGRAPH + {0x8C59, 0x5B7B}, //2116 #CJK UNIFIED IDEOGRAPH + {0x8C5A, 0x5B7C}, //2117 #CJK UNIFIED IDEOGRAPH + {0x8C5B, 0x5B7E}, //2118 #CJK UNIFIED IDEOGRAPH + {0x8C5C, 0x5B7F}, //2119 #CJK UNIFIED IDEOGRAPH + {0x8C5D, 0x5B82}, //2120 #CJK UNIFIED IDEOGRAPH + {0x8C5E, 0x5B86}, //2121 #CJK UNIFIED IDEOGRAPH + {0x8C5F, 0x5B8A}, //2122 #CJK UNIFIED IDEOGRAPH + {0x8C60, 0x5B8D}, //2123 #CJK UNIFIED IDEOGRAPH + {0x8C61, 0x5B8E}, //2124 #CJK UNIFIED IDEOGRAPH + {0x8C62, 0x5B90}, //2125 #CJK UNIFIED IDEOGRAPH + {0x8C63, 0x5B91}, //2126 #CJK UNIFIED IDEOGRAPH + {0x8C64, 0x5B92}, //2127 #CJK UNIFIED IDEOGRAPH + {0x8C65, 0x5B94}, //2128 #CJK UNIFIED IDEOGRAPH + {0x8C66, 0x5B96}, //2129 #CJK UNIFIED IDEOGRAPH + {0x8C67, 0x5B9F}, //2130 #CJK UNIFIED IDEOGRAPH + {0x8C68, 0x5BA7}, //2131 #CJK UNIFIED IDEOGRAPH + {0x8C69, 0x5BA8}, //2132 #CJK UNIFIED IDEOGRAPH + {0x8C6A, 0x5BA9}, //2133 #CJK UNIFIED IDEOGRAPH + {0x8C6B, 0x5BAC}, //2134 #CJK UNIFIED IDEOGRAPH + {0x8C6C, 0x5BAD}, //2135 #CJK UNIFIED IDEOGRAPH + {0x8C6D, 0x5BAE}, //2136 #CJK UNIFIED IDEOGRAPH + {0x8C6E, 0x5BAF}, //2137 #CJK UNIFIED IDEOGRAPH + {0x8C6F, 0x5BB1}, //2138 #CJK UNIFIED IDEOGRAPH + {0x8C70, 0x5BB2}, //2139 #CJK UNIFIED IDEOGRAPH + {0x8C71, 0x5BB7}, //2140 #CJK UNIFIED IDEOGRAPH + {0x8C72, 0x5BBA}, //2141 #CJK UNIFIED IDEOGRAPH + {0x8C73, 0x5BBB}, //2142 #CJK UNIFIED IDEOGRAPH + {0x8C74, 0x5BBC}, //2143 #CJK UNIFIED IDEOGRAPH + {0x8C75, 0x5BC0}, //2144 #CJK UNIFIED IDEOGRAPH + {0x8C76, 0x5BC1}, //2145 #CJK UNIFIED IDEOGRAPH + {0x8C77, 0x5BC3}, //2146 #CJK UNIFIED IDEOGRAPH + {0x8C78, 0x5BC8}, //2147 #CJK UNIFIED IDEOGRAPH + {0x8C79, 0x5BC9}, //2148 #CJK UNIFIED IDEOGRAPH + {0x8C7A, 0x5BCA}, //2149 #CJK UNIFIED IDEOGRAPH + {0x8C7B, 0x5BCB}, //2150 #CJK UNIFIED IDEOGRAPH + {0x8C7C, 0x5BCD}, //2151 #CJK UNIFIED IDEOGRAPH + {0x8C7D, 0x5BCE}, //2152 #CJK UNIFIED IDEOGRAPH + {0x8C7E, 0x5BCF}, //2153 #CJK UNIFIED IDEOGRAPH + {0x8C80, 0x5BD1}, //2154 #CJK UNIFIED IDEOGRAPH + {0x8C81, 0x5BD4}, //2155 #CJK UNIFIED IDEOGRAPH + {0x8C82, 0x5BD5}, //2156 #CJK UNIFIED IDEOGRAPH + {0x8C83, 0x5BD6}, //2157 #CJK UNIFIED IDEOGRAPH + {0x8C84, 0x5BD7}, //2158 #CJK UNIFIED IDEOGRAPH + {0x8C85, 0x5BD8}, //2159 #CJK UNIFIED IDEOGRAPH + {0x8C86, 0x5BD9}, //2160 #CJK UNIFIED IDEOGRAPH + {0x8C87, 0x5BDA}, //2161 #CJK UNIFIED IDEOGRAPH + {0x8C88, 0x5BDB}, //2162 #CJK UNIFIED IDEOGRAPH + {0x8C89, 0x5BDC}, //2163 #CJK UNIFIED IDEOGRAPH + {0x8C8A, 0x5BE0}, //2164 #CJK UNIFIED IDEOGRAPH + {0x8C8B, 0x5BE2}, //2165 #CJK UNIFIED IDEOGRAPH + {0x8C8C, 0x5BE3}, //2166 #CJK UNIFIED IDEOGRAPH + {0x8C8D, 0x5BE6}, //2167 #CJK UNIFIED IDEOGRAPH + {0x8C8E, 0x5BE7}, //2168 #CJK UNIFIED IDEOGRAPH + {0x8C8F, 0x5BE9}, //2169 #CJK UNIFIED IDEOGRAPH + {0x8C90, 0x5BEA}, //2170 #CJK UNIFIED IDEOGRAPH + {0x8C91, 0x5BEB}, //2171 #CJK UNIFIED IDEOGRAPH + {0x8C92, 0x5BEC}, //2172 #CJK UNIFIED IDEOGRAPH + {0x8C93, 0x5BED}, //2173 #CJK UNIFIED IDEOGRAPH + {0x8C94, 0x5BEF}, //2174 #CJK UNIFIED IDEOGRAPH + {0x8C95, 0x5BF1}, //2175 #CJK UNIFIED IDEOGRAPH + {0x8C96, 0x5BF2}, //2176 #CJK UNIFIED IDEOGRAPH + {0x8C97, 0x5BF3}, //2177 #CJK UNIFIED IDEOGRAPH + {0x8C98, 0x5BF4}, //2178 #CJK UNIFIED IDEOGRAPH + {0x8C99, 0x5BF5}, //2179 #CJK UNIFIED IDEOGRAPH + {0x8C9A, 0x5BF6}, //2180 #CJK UNIFIED IDEOGRAPH + {0x8C9B, 0x5BF7}, //2181 #CJK UNIFIED IDEOGRAPH + {0x8C9C, 0x5BFD}, //2182 #CJK UNIFIED IDEOGRAPH + {0x8C9D, 0x5BFE}, //2183 #CJK UNIFIED IDEOGRAPH + {0x8C9E, 0x5C00}, //2184 #CJK UNIFIED IDEOGRAPH + {0x8C9F, 0x5C02}, //2185 #CJK UNIFIED IDEOGRAPH + {0x8CA0, 0x5C03}, //2186 #CJK UNIFIED IDEOGRAPH + {0x8CA1, 0x5C05}, //2187 #CJK UNIFIED IDEOGRAPH + {0x8CA2, 0x5C07}, //2188 #CJK UNIFIED IDEOGRAPH + {0x8CA3, 0x5C08}, //2189 #CJK UNIFIED IDEOGRAPH + {0x8CA4, 0x5C0B}, //2190 #CJK UNIFIED IDEOGRAPH + {0x8CA5, 0x5C0C}, //2191 #CJK UNIFIED IDEOGRAPH + {0x8CA6, 0x5C0D}, //2192 #CJK UNIFIED IDEOGRAPH + {0x8CA7, 0x5C0E}, //2193 #CJK UNIFIED IDEOGRAPH + {0x8CA8, 0x5C10}, //2194 #CJK UNIFIED IDEOGRAPH + {0x8CA9, 0x5C12}, //2195 #CJK UNIFIED IDEOGRAPH + {0x8CAA, 0x5C13}, //2196 #CJK UNIFIED IDEOGRAPH + {0x8CAB, 0x5C17}, //2197 #CJK UNIFIED IDEOGRAPH + {0x8CAC, 0x5C19}, //2198 #CJK UNIFIED IDEOGRAPH + {0x8CAD, 0x5C1B}, //2199 #CJK UNIFIED IDEOGRAPH + {0x8CAE, 0x5C1E}, //2200 #CJK UNIFIED IDEOGRAPH + {0x8CAF, 0x5C1F}, //2201 #CJK UNIFIED IDEOGRAPH + {0x8CB0, 0x5C20}, //2202 #CJK UNIFIED IDEOGRAPH + {0x8CB1, 0x5C21}, //2203 #CJK UNIFIED IDEOGRAPH + {0x8CB2, 0x5C23}, //2204 #CJK UNIFIED IDEOGRAPH + {0x8CB3, 0x5C26}, //2205 #CJK UNIFIED IDEOGRAPH + {0x8CB4, 0x5C28}, //2206 #CJK UNIFIED IDEOGRAPH + {0x8CB5, 0x5C29}, //2207 #CJK UNIFIED IDEOGRAPH + {0x8CB6, 0x5C2A}, //2208 #CJK UNIFIED IDEOGRAPH + {0x8CB7, 0x5C2B}, //2209 #CJK UNIFIED IDEOGRAPH + {0x8CB8, 0x5C2D}, //2210 #CJK UNIFIED IDEOGRAPH + {0x8CB9, 0x5C2E}, //2211 #CJK UNIFIED IDEOGRAPH + {0x8CBA, 0x5C2F}, //2212 #CJK UNIFIED IDEOGRAPH + {0x8CBB, 0x5C30}, //2213 #CJK UNIFIED IDEOGRAPH + {0x8CBC, 0x5C32}, //2214 #CJK UNIFIED IDEOGRAPH + {0x8CBD, 0x5C33}, //2215 #CJK UNIFIED IDEOGRAPH + {0x8CBE, 0x5C35}, //2216 #CJK UNIFIED IDEOGRAPH + {0x8CBF, 0x5C36}, //2217 #CJK UNIFIED IDEOGRAPH + {0x8CC0, 0x5C37}, //2218 #CJK UNIFIED IDEOGRAPH + {0x8CC1, 0x5C43}, //2219 #CJK UNIFIED IDEOGRAPH + {0x8CC2, 0x5C44}, //2220 #CJK UNIFIED IDEOGRAPH + {0x8CC3, 0x5C46}, //2221 #CJK UNIFIED IDEOGRAPH + {0x8CC4, 0x5C47}, //2222 #CJK UNIFIED IDEOGRAPH + {0x8CC5, 0x5C4C}, //2223 #CJK UNIFIED IDEOGRAPH + {0x8CC6, 0x5C4D}, //2224 #CJK UNIFIED IDEOGRAPH + {0x8CC7, 0x5C52}, //2225 #CJK UNIFIED IDEOGRAPH + {0x8CC8, 0x5C53}, //2226 #CJK UNIFIED IDEOGRAPH + {0x8CC9, 0x5C54}, //2227 #CJK UNIFIED IDEOGRAPH + {0x8CCA, 0x5C56}, //2228 #CJK UNIFIED IDEOGRAPH + {0x8CCB, 0x5C57}, //2229 #CJK UNIFIED IDEOGRAPH + {0x8CCC, 0x5C58}, //2230 #CJK UNIFIED IDEOGRAPH + {0x8CCD, 0x5C5A}, //2231 #CJK UNIFIED IDEOGRAPH + {0x8CCE, 0x5C5B}, //2232 #CJK UNIFIED IDEOGRAPH + {0x8CCF, 0x5C5C}, //2233 #CJK UNIFIED IDEOGRAPH + {0x8CD0, 0x5C5D}, //2234 #CJK UNIFIED IDEOGRAPH + {0x8CD1, 0x5C5F}, //2235 #CJK UNIFIED IDEOGRAPH + {0x8CD2, 0x5C62}, //2236 #CJK UNIFIED IDEOGRAPH + {0x8CD3, 0x5C64}, //2237 #CJK UNIFIED IDEOGRAPH + {0x8CD4, 0x5C67}, //2238 #CJK UNIFIED IDEOGRAPH + {0x8CD5, 0x5C68}, //2239 #CJK UNIFIED IDEOGRAPH + {0x8CD6, 0x5C69}, //2240 #CJK UNIFIED IDEOGRAPH + {0x8CD7, 0x5C6A}, //2241 #CJK UNIFIED IDEOGRAPH + {0x8CD8, 0x5C6B}, //2242 #CJK UNIFIED IDEOGRAPH + {0x8CD9, 0x5C6C}, //2243 #CJK UNIFIED IDEOGRAPH + {0x8CDA, 0x5C6D}, //2244 #CJK UNIFIED IDEOGRAPH + {0x8CDB, 0x5C70}, //2245 #CJK UNIFIED IDEOGRAPH + {0x8CDC, 0x5C72}, //2246 #CJK UNIFIED IDEOGRAPH + {0x8CDD, 0x5C73}, //2247 #CJK UNIFIED IDEOGRAPH + {0x8CDE, 0x5C74}, //2248 #CJK UNIFIED IDEOGRAPH + {0x8CDF, 0x5C75}, //2249 #CJK UNIFIED IDEOGRAPH + {0x8CE0, 0x5C76}, //2250 #CJK UNIFIED IDEOGRAPH + {0x8CE1, 0x5C77}, //2251 #CJK UNIFIED IDEOGRAPH + {0x8CE2, 0x5C78}, //2252 #CJK UNIFIED IDEOGRAPH + {0x8CE3, 0x5C7B}, //2253 #CJK UNIFIED IDEOGRAPH + {0x8CE4, 0x5C7C}, //2254 #CJK UNIFIED IDEOGRAPH + {0x8CE5, 0x5C7D}, //2255 #CJK UNIFIED IDEOGRAPH + {0x8CE6, 0x5C7E}, //2256 #CJK UNIFIED IDEOGRAPH + {0x8CE7, 0x5C80}, //2257 #CJK UNIFIED IDEOGRAPH + {0x8CE8, 0x5C83}, //2258 #CJK UNIFIED IDEOGRAPH + {0x8CE9, 0x5C84}, //2259 #CJK UNIFIED IDEOGRAPH + {0x8CEA, 0x5C85}, //2260 #CJK UNIFIED IDEOGRAPH + {0x8CEB, 0x5C86}, //2261 #CJK UNIFIED IDEOGRAPH + {0x8CEC, 0x5C87}, //2262 #CJK UNIFIED IDEOGRAPH + {0x8CED, 0x5C89}, //2263 #CJK UNIFIED IDEOGRAPH + {0x8CEE, 0x5C8A}, //2264 #CJK UNIFIED IDEOGRAPH + {0x8CEF, 0x5C8B}, //2265 #CJK UNIFIED IDEOGRAPH + {0x8CF0, 0x5C8E}, //2266 #CJK UNIFIED IDEOGRAPH + {0x8CF1, 0x5C8F}, //2267 #CJK UNIFIED IDEOGRAPH + {0x8CF2, 0x5C92}, //2268 #CJK UNIFIED IDEOGRAPH + {0x8CF3, 0x5C93}, //2269 #CJK UNIFIED IDEOGRAPH + {0x8CF4, 0x5C95}, //2270 #CJK UNIFIED IDEOGRAPH + {0x8CF5, 0x5C9D}, //2271 #CJK UNIFIED IDEOGRAPH + {0x8CF6, 0x5C9E}, //2272 #CJK UNIFIED IDEOGRAPH + {0x8CF7, 0x5C9F}, //2273 #CJK UNIFIED IDEOGRAPH + {0x8CF8, 0x5CA0}, //2274 #CJK UNIFIED IDEOGRAPH + {0x8CF9, 0x5CA1}, //2275 #CJK UNIFIED IDEOGRAPH + {0x8CFA, 0x5CA4}, //2276 #CJK UNIFIED IDEOGRAPH + {0x8CFB, 0x5CA5}, //2277 #CJK UNIFIED IDEOGRAPH + {0x8CFC, 0x5CA6}, //2278 #CJK UNIFIED IDEOGRAPH + {0x8CFD, 0x5CA7}, //2279 #CJK UNIFIED IDEOGRAPH + {0x8CFE, 0x5CA8}, //2280 #CJK UNIFIED IDEOGRAPH + {0x8D40, 0x5CAA}, //2281 #CJK UNIFIED IDEOGRAPH + {0x8D41, 0x5CAE}, //2282 #CJK UNIFIED IDEOGRAPH + {0x8D42, 0x5CAF}, //2283 #CJK UNIFIED IDEOGRAPH + {0x8D43, 0x5CB0}, //2284 #CJK UNIFIED IDEOGRAPH + {0x8D44, 0x5CB2}, //2285 #CJK UNIFIED IDEOGRAPH + {0x8D45, 0x5CB4}, //2286 #CJK UNIFIED IDEOGRAPH + {0x8D46, 0x5CB6}, //2287 #CJK UNIFIED IDEOGRAPH + {0x8D47, 0x5CB9}, //2288 #CJK UNIFIED IDEOGRAPH + {0x8D48, 0x5CBA}, //2289 #CJK UNIFIED IDEOGRAPH + {0x8D49, 0x5CBB}, //2290 #CJK UNIFIED IDEOGRAPH + {0x8D4A, 0x5CBC}, //2291 #CJK UNIFIED IDEOGRAPH + {0x8D4B, 0x5CBE}, //2292 #CJK UNIFIED IDEOGRAPH + {0x8D4C, 0x5CC0}, //2293 #CJK UNIFIED IDEOGRAPH + {0x8D4D, 0x5CC2}, //2294 #CJK UNIFIED IDEOGRAPH + {0x8D4E, 0x5CC3}, //2295 #CJK UNIFIED IDEOGRAPH + {0x8D4F, 0x5CC5}, //2296 #CJK UNIFIED IDEOGRAPH + {0x8D50, 0x5CC6}, //2297 #CJK UNIFIED IDEOGRAPH + {0x8D51, 0x5CC7}, //2298 #CJK UNIFIED IDEOGRAPH + {0x8D52, 0x5CC8}, //2299 #CJK UNIFIED IDEOGRAPH + {0x8D53, 0x5CC9}, //2300 #CJK UNIFIED IDEOGRAPH + {0x8D54, 0x5CCA}, //2301 #CJK UNIFIED IDEOGRAPH + {0x8D55, 0x5CCC}, //2302 #CJK UNIFIED IDEOGRAPH + {0x8D56, 0x5CCD}, //2303 #CJK UNIFIED IDEOGRAPH + {0x8D57, 0x5CCE}, //2304 #CJK UNIFIED IDEOGRAPH + {0x8D58, 0x5CCF}, //2305 #CJK UNIFIED IDEOGRAPH + {0x8D59, 0x5CD0}, //2306 #CJK UNIFIED IDEOGRAPH + {0x8D5A, 0x5CD1}, //2307 #CJK UNIFIED IDEOGRAPH + {0x8D5B, 0x5CD3}, //2308 #CJK UNIFIED IDEOGRAPH + {0x8D5C, 0x5CD4}, //2309 #CJK UNIFIED IDEOGRAPH + {0x8D5D, 0x5CD5}, //2310 #CJK UNIFIED IDEOGRAPH + {0x8D5E, 0x5CD6}, //2311 #CJK UNIFIED IDEOGRAPH + {0x8D5F, 0x5CD7}, //2312 #CJK UNIFIED IDEOGRAPH + {0x8D60, 0x5CD8}, //2313 #CJK UNIFIED IDEOGRAPH + {0x8D61, 0x5CDA}, //2314 #CJK UNIFIED IDEOGRAPH + {0x8D62, 0x5CDB}, //2315 #CJK UNIFIED IDEOGRAPH + {0x8D63, 0x5CDC}, //2316 #CJK UNIFIED IDEOGRAPH + {0x8D64, 0x5CDD}, //2317 #CJK UNIFIED IDEOGRAPH + {0x8D65, 0x5CDE}, //2318 #CJK UNIFIED IDEOGRAPH + {0x8D66, 0x5CDF}, //2319 #CJK UNIFIED IDEOGRAPH + {0x8D67, 0x5CE0}, //2320 #CJK UNIFIED IDEOGRAPH + {0x8D68, 0x5CE2}, //2321 #CJK UNIFIED IDEOGRAPH + {0x8D69, 0x5CE3}, //2322 #CJK UNIFIED IDEOGRAPH + {0x8D6A, 0x5CE7}, //2323 #CJK UNIFIED IDEOGRAPH + {0x8D6B, 0x5CE9}, //2324 #CJK UNIFIED IDEOGRAPH + {0x8D6C, 0x5CEB}, //2325 #CJK UNIFIED IDEOGRAPH + {0x8D6D, 0x5CEC}, //2326 #CJK UNIFIED IDEOGRAPH + {0x8D6E, 0x5CEE}, //2327 #CJK UNIFIED IDEOGRAPH + {0x8D6F, 0x5CEF}, //2328 #CJK UNIFIED IDEOGRAPH + {0x8D70, 0x5CF1}, //2329 #CJK UNIFIED IDEOGRAPH + {0x8D71, 0x5CF2}, //2330 #CJK UNIFIED IDEOGRAPH + {0x8D72, 0x5CF3}, //2331 #CJK UNIFIED IDEOGRAPH + {0x8D73, 0x5CF4}, //2332 #CJK UNIFIED IDEOGRAPH + {0x8D74, 0x5CF5}, //2333 #CJK UNIFIED IDEOGRAPH + {0x8D75, 0x5CF6}, //2334 #CJK UNIFIED IDEOGRAPH + {0x8D76, 0x5CF7}, //2335 #CJK UNIFIED IDEOGRAPH + {0x8D77, 0x5CF8}, //2336 #CJK UNIFIED IDEOGRAPH + {0x8D78, 0x5CF9}, //2337 #CJK UNIFIED IDEOGRAPH + {0x8D79, 0x5CFA}, //2338 #CJK UNIFIED IDEOGRAPH + {0x8D7A, 0x5CFC}, //2339 #CJK UNIFIED IDEOGRAPH + {0x8D7B, 0x5CFD}, //2340 #CJK UNIFIED IDEOGRAPH + {0x8D7C, 0x5CFE}, //2341 #CJK UNIFIED IDEOGRAPH + {0x8D7D, 0x5CFF}, //2342 #CJK UNIFIED IDEOGRAPH + {0x8D7E, 0x5D00}, //2343 #CJK UNIFIED IDEOGRAPH + {0x8D80, 0x5D01}, //2344 #CJK UNIFIED IDEOGRAPH + {0x8D81, 0x5D04}, //2345 #CJK UNIFIED IDEOGRAPH + {0x8D82, 0x5D05}, //2346 #CJK UNIFIED IDEOGRAPH + {0x8D83, 0x5D08}, //2347 #CJK UNIFIED IDEOGRAPH + {0x8D84, 0x5D09}, //2348 #CJK UNIFIED IDEOGRAPH + {0x8D85, 0x5D0A}, //2349 #CJK UNIFIED IDEOGRAPH + {0x8D86, 0x5D0B}, //2350 #CJK UNIFIED IDEOGRAPH + {0x8D87, 0x5D0C}, //2351 #CJK UNIFIED IDEOGRAPH + {0x8D88, 0x5D0D}, //2352 #CJK UNIFIED IDEOGRAPH + {0x8D89, 0x5D0F}, //2353 #CJK UNIFIED IDEOGRAPH + {0x8D8A, 0x5D10}, //2354 #CJK UNIFIED IDEOGRAPH + {0x8D8B, 0x5D11}, //2355 #CJK UNIFIED IDEOGRAPH + {0x8D8C, 0x5D12}, //2356 #CJK UNIFIED IDEOGRAPH + {0x8D8D, 0x5D13}, //2357 #CJK UNIFIED IDEOGRAPH + {0x8D8E, 0x5D15}, //2358 #CJK UNIFIED IDEOGRAPH + {0x8D8F, 0x5D17}, //2359 #CJK UNIFIED IDEOGRAPH + {0x8D90, 0x5D18}, //2360 #CJK UNIFIED IDEOGRAPH + {0x8D91, 0x5D19}, //2361 #CJK UNIFIED IDEOGRAPH + {0x8D92, 0x5D1A}, //2362 #CJK UNIFIED IDEOGRAPH + {0x8D93, 0x5D1C}, //2363 #CJK UNIFIED IDEOGRAPH + {0x8D94, 0x5D1D}, //2364 #CJK UNIFIED IDEOGRAPH + {0x8D95, 0x5D1F}, //2365 #CJK UNIFIED IDEOGRAPH + {0x8D96, 0x5D20}, //2366 #CJK UNIFIED IDEOGRAPH + {0x8D97, 0x5D21}, //2367 #CJK UNIFIED IDEOGRAPH + {0x8D98, 0x5D22}, //2368 #CJK UNIFIED IDEOGRAPH + {0x8D99, 0x5D23}, //2369 #CJK UNIFIED IDEOGRAPH + {0x8D9A, 0x5D25}, //2370 #CJK UNIFIED IDEOGRAPH + {0x8D9B, 0x5D28}, //2371 #CJK UNIFIED IDEOGRAPH + {0x8D9C, 0x5D2A}, //2372 #CJK UNIFIED IDEOGRAPH + {0x8D9D, 0x5D2B}, //2373 #CJK UNIFIED IDEOGRAPH + {0x8D9E, 0x5D2C}, //2374 #CJK UNIFIED IDEOGRAPH + {0x8D9F, 0x5D2F}, //2375 #CJK UNIFIED IDEOGRAPH + {0x8DA0, 0x5D30}, //2376 #CJK UNIFIED IDEOGRAPH + {0x8DA1, 0x5D31}, //2377 #CJK UNIFIED IDEOGRAPH + {0x8DA2, 0x5D32}, //2378 #CJK UNIFIED IDEOGRAPH + {0x8DA3, 0x5D33}, //2379 #CJK UNIFIED IDEOGRAPH + {0x8DA4, 0x5D35}, //2380 #CJK UNIFIED IDEOGRAPH + {0x8DA5, 0x5D36}, //2381 #CJK UNIFIED IDEOGRAPH + {0x8DA6, 0x5D37}, //2382 #CJK UNIFIED IDEOGRAPH + {0x8DA7, 0x5D38}, //2383 #CJK UNIFIED IDEOGRAPH + {0x8DA8, 0x5D39}, //2384 #CJK UNIFIED IDEOGRAPH + {0x8DA9, 0x5D3A}, //2385 #CJK UNIFIED IDEOGRAPH + {0x8DAA, 0x5D3B}, //2386 #CJK UNIFIED IDEOGRAPH + {0x8DAB, 0x5D3C}, //2387 #CJK UNIFIED IDEOGRAPH + {0x8DAC, 0x5D3F}, //2388 #CJK UNIFIED IDEOGRAPH + {0x8DAD, 0x5D40}, //2389 #CJK UNIFIED IDEOGRAPH + {0x8DAE, 0x5D41}, //2390 #CJK UNIFIED IDEOGRAPH + {0x8DAF, 0x5D42}, //2391 #CJK UNIFIED IDEOGRAPH + {0x8DB0, 0x5D43}, //2392 #CJK UNIFIED IDEOGRAPH + {0x8DB1, 0x5D44}, //2393 #CJK UNIFIED IDEOGRAPH + {0x8DB2, 0x5D45}, //2394 #CJK UNIFIED IDEOGRAPH + {0x8DB3, 0x5D46}, //2395 #CJK UNIFIED IDEOGRAPH + {0x8DB4, 0x5D48}, //2396 #CJK UNIFIED IDEOGRAPH + {0x8DB5, 0x5D49}, //2397 #CJK UNIFIED IDEOGRAPH + {0x8DB6, 0x5D4D}, //2398 #CJK UNIFIED IDEOGRAPH + {0x8DB7, 0x5D4E}, //2399 #CJK UNIFIED IDEOGRAPH + {0x8DB8, 0x5D4F}, //2400 #CJK UNIFIED IDEOGRAPH + {0x8DB9, 0x5D50}, //2401 #CJK UNIFIED IDEOGRAPH + {0x8DBA, 0x5D51}, //2402 #CJK UNIFIED IDEOGRAPH + {0x8DBB, 0x5D52}, //2403 #CJK UNIFIED IDEOGRAPH + {0x8DBC, 0x5D53}, //2404 #CJK UNIFIED IDEOGRAPH + {0x8DBD, 0x5D54}, //2405 #CJK UNIFIED IDEOGRAPH + {0x8DBE, 0x5D55}, //2406 #CJK UNIFIED IDEOGRAPH + {0x8DBF, 0x5D56}, //2407 #CJK UNIFIED IDEOGRAPH + {0x8DC0, 0x5D57}, //2408 #CJK UNIFIED IDEOGRAPH + {0x8DC1, 0x5D59}, //2409 #CJK UNIFIED IDEOGRAPH + {0x8DC2, 0x5D5A}, //2410 #CJK UNIFIED IDEOGRAPH + {0x8DC3, 0x5D5C}, //2411 #CJK UNIFIED IDEOGRAPH + {0x8DC4, 0x5D5E}, //2412 #CJK UNIFIED IDEOGRAPH + {0x8DC5, 0x5D5F}, //2413 #CJK UNIFIED IDEOGRAPH + {0x8DC6, 0x5D60}, //2414 #CJK UNIFIED IDEOGRAPH + {0x8DC7, 0x5D61}, //2415 #CJK UNIFIED IDEOGRAPH + {0x8DC8, 0x5D62}, //2416 #CJK UNIFIED IDEOGRAPH + {0x8DC9, 0x5D63}, //2417 #CJK UNIFIED IDEOGRAPH + {0x8DCA, 0x5D64}, //2418 #CJK UNIFIED IDEOGRAPH + {0x8DCB, 0x5D65}, //2419 #CJK UNIFIED IDEOGRAPH + {0x8DCC, 0x5D66}, //2420 #CJK UNIFIED IDEOGRAPH + {0x8DCD, 0x5D67}, //2421 #CJK UNIFIED IDEOGRAPH + {0x8DCE, 0x5D68}, //2422 #CJK UNIFIED IDEOGRAPH + {0x8DCF, 0x5D6A}, //2423 #CJK UNIFIED IDEOGRAPH + {0x8DD0, 0x5D6D}, //2424 #CJK UNIFIED IDEOGRAPH + {0x8DD1, 0x5D6E}, //2425 #CJK UNIFIED IDEOGRAPH + {0x8DD2, 0x5D70}, //2426 #CJK UNIFIED IDEOGRAPH + {0x8DD3, 0x5D71}, //2427 #CJK UNIFIED IDEOGRAPH + {0x8DD4, 0x5D72}, //2428 #CJK UNIFIED IDEOGRAPH + {0x8DD5, 0x5D73}, //2429 #CJK UNIFIED IDEOGRAPH + {0x8DD6, 0x5D75}, //2430 #CJK UNIFIED IDEOGRAPH + {0x8DD7, 0x5D76}, //2431 #CJK UNIFIED IDEOGRAPH + {0x8DD8, 0x5D77}, //2432 #CJK UNIFIED IDEOGRAPH + {0x8DD9, 0x5D78}, //2433 #CJK UNIFIED IDEOGRAPH + {0x8DDA, 0x5D79}, //2434 #CJK UNIFIED IDEOGRAPH + {0x8DDB, 0x5D7A}, //2435 #CJK UNIFIED IDEOGRAPH + {0x8DDC, 0x5D7B}, //2436 #CJK UNIFIED IDEOGRAPH + {0x8DDD, 0x5D7C}, //2437 #CJK UNIFIED IDEOGRAPH + {0x8DDE, 0x5D7D}, //2438 #CJK UNIFIED IDEOGRAPH + {0x8DDF, 0x5D7E}, //2439 #CJK UNIFIED IDEOGRAPH + {0x8DE0, 0x5D7F}, //2440 #CJK UNIFIED IDEOGRAPH + {0x8DE1, 0x5D80}, //2441 #CJK UNIFIED IDEOGRAPH + {0x8DE2, 0x5D81}, //2442 #CJK UNIFIED IDEOGRAPH + {0x8DE3, 0x5D83}, //2443 #CJK UNIFIED IDEOGRAPH + {0x8DE4, 0x5D84}, //2444 #CJK UNIFIED IDEOGRAPH + {0x8DE5, 0x5D85}, //2445 #CJK UNIFIED IDEOGRAPH + {0x8DE6, 0x5D86}, //2446 #CJK UNIFIED IDEOGRAPH + {0x8DE7, 0x5D87}, //2447 #CJK UNIFIED IDEOGRAPH + {0x8DE8, 0x5D88}, //2448 #CJK UNIFIED IDEOGRAPH + {0x8DE9, 0x5D89}, //2449 #CJK UNIFIED IDEOGRAPH + {0x8DEA, 0x5D8A}, //2450 #CJK UNIFIED IDEOGRAPH + {0x8DEB, 0x5D8B}, //2451 #CJK UNIFIED IDEOGRAPH + {0x8DEC, 0x5D8C}, //2452 #CJK UNIFIED IDEOGRAPH + {0x8DED, 0x5D8D}, //2453 #CJK UNIFIED IDEOGRAPH + {0x8DEE, 0x5D8E}, //2454 #CJK UNIFIED IDEOGRAPH + {0x8DEF, 0x5D8F}, //2455 #CJK UNIFIED IDEOGRAPH + {0x8DF0, 0x5D90}, //2456 #CJK UNIFIED IDEOGRAPH + {0x8DF1, 0x5D91}, //2457 #CJK UNIFIED IDEOGRAPH + {0x8DF2, 0x5D92}, //2458 #CJK UNIFIED IDEOGRAPH + {0x8DF3, 0x5D93}, //2459 #CJK UNIFIED IDEOGRAPH + {0x8DF4, 0x5D94}, //2460 #CJK UNIFIED IDEOGRAPH + {0x8DF5, 0x5D95}, //2461 #CJK UNIFIED IDEOGRAPH + {0x8DF6, 0x5D96}, //2462 #CJK UNIFIED IDEOGRAPH + {0x8DF7, 0x5D97}, //2463 #CJK UNIFIED IDEOGRAPH + {0x8DF8, 0x5D98}, //2464 #CJK UNIFIED IDEOGRAPH + {0x8DF9, 0x5D9A}, //2465 #CJK UNIFIED IDEOGRAPH + {0x8DFA, 0x5D9B}, //2466 #CJK UNIFIED IDEOGRAPH + {0x8DFB, 0x5D9C}, //2467 #CJK UNIFIED IDEOGRAPH + {0x8DFC, 0x5D9E}, //2468 #CJK UNIFIED IDEOGRAPH + {0x8DFD, 0x5D9F}, //2469 #CJK UNIFIED IDEOGRAPH + {0x8DFE, 0x5DA0}, //2470 #CJK UNIFIED IDEOGRAPH + {0x8E40, 0x5DA1}, //2471 #CJK UNIFIED IDEOGRAPH + {0x8E41, 0x5DA2}, //2472 #CJK UNIFIED IDEOGRAPH + {0x8E42, 0x5DA3}, //2473 #CJK UNIFIED IDEOGRAPH + {0x8E43, 0x5DA4}, //2474 #CJK UNIFIED IDEOGRAPH + {0x8E44, 0x5DA5}, //2475 #CJK UNIFIED IDEOGRAPH + {0x8E45, 0x5DA6}, //2476 #CJK UNIFIED IDEOGRAPH + {0x8E46, 0x5DA7}, //2477 #CJK UNIFIED IDEOGRAPH + {0x8E47, 0x5DA8}, //2478 #CJK UNIFIED IDEOGRAPH + {0x8E48, 0x5DA9}, //2479 #CJK UNIFIED IDEOGRAPH + {0x8E49, 0x5DAA}, //2480 #CJK UNIFIED IDEOGRAPH + {0x8E4A, 0x5DAB}, //2481 #CJK UNIFIED IDEOGRAPH + {0x8E4B, 0x5DAC}, //2482 #CJK UNIFIED IDEOGRAPH + {0x8E4C, 0x5DAD}, //2483 #CJK UNIFIED IDEOGRAPH + {0x8E4D, 0x5DAE}, //2484 #CJK UNIFIED IDEOGRAPH + {0x8E4E, 0x5DAF}, //2485 #CJK UNIFIED IDEOGRAPH + {0x8E4F, 0x5DB0}, //2486 #CJK UNIFIED IDEOGRAPH + {0x8E50, 0x5DB1}, //2487 #CJK UNIFIED IDEOGRAPH + {0x8E51, 0x5DB2}, //2488 #CJK UNIFIED IDEOGRAPH + {0x8E52, 0x5DB3}, //2489 #CJK UNIFIED IDEOGRAPH + {0x8E53, 0x5DB4}, //2490 #CJK UNIFIED IDEOGRAPH + {0x8E54, 0x5DB5}, //2491 #CJK UNIFIED IDEOGRAPH + {0x8E55, 0x5DB6}, //2492 #CJK UNIFIED IDEOGRAPH + {0x8E56, 0x5DB8}, //2493 #CJK UNIFIED IDEOGRAPH + {0x8E57, 0x5DB9}, //2494 #CJK UNIFIED IDEOGRAPH + {0x8E58, 0x5DBA}, //2495 #CJK UNIFIED IDEOGRAPH + {0x8E59, 0x5DBB}, //2496 #CJK UNIFIED IDEOGRAPH + {0x8E5A, 0x5DBC}, //2497 #CJK UNIFIED IDEOGRAPH + {0x8E5B, 0x5DBD}, //2498 #CJK UNIFIED IDEOGRAPH + {0x8E5C, 0x5DBE}, //2499 #CJK UNIFIED IDEOGRAPH + {0x8E5D, 0x5DBF}, //2500 #CJK UNIFIED IDEOGRAPH + {0x8E5E, 0x5DC0}, //2501 #CJK UNIFIED IDEOGRAPH + {0x8E5F, 0x5DC1}, //2502 #CJK UNIFIED IDEOGRAPH + {0x8E60, 0x5DC2}, //2503 #CJK UNIFIED IDEOGRAPH + {0x8E61, 0x5DC3}, //2504 #CJK UNIFIED IDEOGRAPH + {0x8E62, 0x5DC4}, //2505 #CJK UNIFIED IDEOGRAPH + {0x8E63, 0x5DC6}, //2506 #CJK UNIFIED IDEOGRAPH + {0x8E64, 0x5DC7}, //2507 #CJK UNIFIED IDEOGRAPH + {0x8E65, 0x5DC8}, //2508 #CJK UNIFIED IDEOGRAPH + {0x8E66, 0x5DC9}, //2509 #CJK UNIFIED IDEOGRAPH + {0x8E67, 0x5DCA}, //2510 #CJK UNIFIED IDEOGRAPH + {0x8E68, 0x5DCB}, //2511 #CJK UNIFIED IDEOGRAPH + {0x8E69, 0x5DCC}, //2512 #CJK UNIFIED IDEOGRAPH + {0x8E6A, 0x5DCE}, //2513 #CJK UNIFIED IDEOGRAPH + {0x8E6B, 0x5DCF}, //2514 #CJK UNIFIED IDEOGRAPH + {0x8E6C, 0x5DD0}, //2515 #CJK UNIFIED IDEOGRAPH + {0x8E6D, 0x5DD1}, //2516 #CJK UNIFIED IDEOGRAPH + {0x8E6E, 0x5DD2}, //2517 #CJK UNIFIED IDEOGRAPH + {0x8E6F, 0x5DD3}, //2518 #CJK UNIFIED IDEOGRAPH + {0x8E70, 0x5DD4}, //2519 #CJK UNIFIED IDEOGRAPH + {0x8E71, 0x5DD5}, //2520 #CJK UNIFIED IDEOGRAPH + {0x8E72, 0x5DD6}, //2521 #CJK UNIFIED IDEOGRAPH + {0x8E73, 0x5DD7}, //2522 #CJK UNIFIED IDEOGRAPH + {0x8E74, 0x5DD8}, //2523 #CJK UNIFIED IDEOGRAPH + {0x8E75, 0x5DD9}, //2524 #CJK UNIFIED IDEOGRAPH + {0x8E76, 0x5DDA}, //2525 #CJK UNIFIED IDEOGRAPH + {0x8E77, 0x5DDC}, //2526 #CJK UNIFIED IDEOGRAPH + {0x8E78, 0x5DDF}, //2527 #CJK UNIFIED IDEOGRAPH + {0x8E79, 0x5DE0}, //2528 #CJK UNIFIED IDEOGRAPH + {0x8E7A, 0x5DE3}, //2529 #CJK UNIFIED IDEOGRAPH + {0x8E7B, 0x5DE4}, //2530 #CJK UNIFIED IDEOGRAPH + {0x8E7C, 0x5DEA}, //2531 #CJK UNIFIED IDEOGRAPH + {0x8E7D, 0x5DEC}, //2532 #CJK UNIFIED IDEOGRAPH + {0x8E7E, 0x5DED}, //2533 #CJK UNIFIED IDEOGRAPH + {0x8E80, 0x5DF0}, //2534 #CJK UNIFIED IDEOGRAPH + {0x8E81, 0x5DF5}, //2535 #CJK UNIFIED IDEOGRAPH + {0x8E82, 0x5DF6}, //2536 #CJK UNIFIED IDEOGRAPH + {0x8E83, 0x5DF8}, //2537 #CJK UNIFIED IDEOGRAPH + {0x8E84, 0x5DF9}, //2538 #CJK UNIFIED IDEOGRAPH + {0x8E85, 0x5DFA}, //2539 #CJK UNIFIED IDEOGRAPH + {0x8E86, 0x5DFB}, //2540 #CJK UNIFIED IDEOGRAPH + {0x8E87, 0x5DFC}, //2541 #CJK UNIFIED IDEOGRAPH + {0x8E88, 0x5DFF}, //2542 #CJK UNIFIED IDEOGRAPH + {0x8E89, 0x5E00}, //2543 #CJK UNIFIED IDEOGRAPH + {0x8E8A, 0x5E04}, //2544 #CJK UNIFIED IDEOGRAPH + {0x8E8B, 0x5E07}, //2545 #CJK UNIFIED IDEOGRAPH + {0x8E8C, 0x5E09}, //2546 #CJK UNIFIED IDEOGRAPH + {0x8E8D, 0x5E0A}, //2547 #CJK UNIFIED IDEOGRAPH + {0x8E8E, 0x5E0B}, //2548 #CJK UNIFIED IDEOGRAPH + {0x8E8F, 0x5E0D}, //2549 #CJK UNIFIED IDEOGRAPH + {0x8E90, 0x5E0E}, //2550 #CJK UNIFIED IDEOGRAPH + {0x8E91, 0x5E12}, //2551 #CJK UNIFIED IDEOGRAPH + {0x8E92, 0x5E13}, //2552 #CJK UNIFIED IDEOGRAPH + {0x8E93, 0x5E17}, //2553 #CJK UNIFIED IDEOGRAPH + {0x8E94, 0x5E1E}, //2554 #CJK UNIFIED IDEOGRAPH + {0x8E95, 0x5E1F}, //2555 #CJK UNIFIED IDEOGRAPH + {0x8E96, 0x5E20}, //2556 #CJK UNIFIED IDEOGRAPH + {0x8E97, 0x5E21}, //2557 #CJK UNIFIED IDEOGRAPH + {0x8E98, 0x5E22}, //2558 #CJK UNIFIED IDEOGRAPH + {0x8E99, 0x5E23}, //2559 #CJK UNIFIED IDEOGRAPH + {0x8E9A, 0x5E24}, //2560 #CJK UNIFIED IDEOGRAPH + {0x8E9B, 0x5E25}, //2561 #CJK UNIFIED IDEOGRAPH + {0x8E9C, 0x5E28}, //2562 #CJK UNIFIED IDEOGRAPH + {0x8E9D, 0x5E29}, //2563 #CJK UNIFIED IDEOGRAPH + {0x8E9E, 0x5E2A}, //2564 #CJK UNIFIED IDEOGRAPH + {0x8E9F, 0x5E2B}, //2565 #CJK UNIFIED IDEOGRAPH + {0x8EA0, 0x5E2C}, //2566 #CJK UNIFIED IDEOGRAPH + {0x8EA1, 0x5E2F}, //2567 #CJK UNIFIED IDEOGRAPH + {0x8EA2, 0x5E30}, //2568 #CJK UNIFIED IDEOGRAPH + {0x8EA3, 0x5E32}, //2569 #CJK UNIFIED IDEOGRAPH + {0x8EA4, 0x5E33}, //2570 #CJK UNIFIED IDEOGRAPH + {0x8EA5, 0x5E34}, //2571 #CJK UNIFIED IDEOGRAPH + {0x8EA6, 0x5E35}, //2572 #CJK UNIFIED IDEOGRAPH + {0x8EA7, 0x5E36}, //2573 #CJK UNIFIED IDEOGRAPH + {0x8EA8, 0x5E39}, //2574 #CJK UNIFIED IDEOGRAPH + {0x8EA9, 0x5E3A}, //2575 #CJK UNIFIED IDEOGRAPH + {0x8EAA, 0x5E3E}, //2576 #CJK UNIFIED IDEOGRAPH + {0x8EAB, 0x5E3F}, //2577 #CJK UNIFIED IDEOGRAPH + {0x8EAC, 0x5E40}, //2578 #CJK UNIFIED IDEOGRAPH + {0x8EAD, 0x5E41}, //2579 #CJK UNIFIED IDEOGRAPH + {0x8EAE, 0x5E43}, //2580 #CJK UNIFIED IDEOGRAPH + {0x8EAF, 0x5E46}, //2581 #CJK UNIFIED IDEOGRAPH + {0x8EB0, 0x5E47}, //2582 #CJK UNIFIED IDEOGRAPH + {0x8EB1, 0x5E48}, //2583 #CJK UNIFIED IDEOGRAPH + {0x8EB2, 0x5E49}, //2584 #CJK UNIFIED IDEOGRAPH + {0x8EB3, 0x5E4A}, //2585 #CJK UNIFIED IDEOGRAPH + {0x8EB4, 0x5E4B}, //2586 #CJK UNIFIED IDEOGRAPH + {0x8EB5, 0x5E4D}, //2587 #CJK UNIFIED IDEOGRAPH + {0x8EB6, 0x5E4E}, //2588 #CJK UNIFIED IDEOGRAPH + {0x8EB7, 0x5E4F}, //2589 #CJK UNIFIED IDEOGRAPH + {0x8EB8, 0x5E50}, //2590 #CJK UNIFIED IDEOGRAPH + {0x8EB9, 0x5E51}, //2591 #CJK UNIFIED IDEOGRAPH + {0x8EBA, 0x5E52}, //2592 #CJK UNIFIED IDEOGRAPH + {0x8EBB, 0x5E53}, //2593 #CJK UNIFIED IDEOGRAPH + {0x8EBC, 0x5E56}, //2594 #CJK UNIFIED IDEOGRAPH + {0x8EBD, 0x5E57}, //2595 #CJK UNIFIED IDEOGRAPH + {0x8EBE, 0x5E58}, //2596 #CJK UNIFIED IDEOGRAPH + {0x8EBF, 0x5E59}, //2597 #CJK UNIFIED IDEOGRAPH + {0x8EC0, 0x5E5A}, //2598 #CJK UNIFIED IDEOGRAPH + {0x8EC1, 0x5E5C}, //2599 #CJK UNIFIED IDEOGRAPH + {0x8EC2, 0x5E5D}, //2600 #CJK UNIFIED IDEOGRAPH + {0x8EC3, 0x5E5F}, //2601 #CJK UNIFIED IDEOGRAPH + {0x8EC4, 0x5E60}, //2602 #CJK UNIFIED IDEOGRAPH + {0x8EC5, 0x5E63}, //2603 #CJK UNIFIED IDEOGRAPH + {0x8EC6, 0x5E64}, //2604 #CJK UNIFIED IDEOGRAPH + {0x8EC7, 0x5E65}, //2605 #CJK UNIFIED IDEOGRAPH + {0x8EC8, 0x5E66}, //2606 #CJK UNIFIED IDEOGRAPH + {0x8EC9, 0x5E67}, //2607 #CJK UNIFIED IDEOGRAPH + {0x8ECA, 0x5E68}, //2608 #CJK UNIFIED IDEOGRAPH + {0x8ECB, 0x5E69}, //2609 #CJK UNIFIED IDEOGRAPH + {0x8ECC, 0x5E6A}, //2610 #CJK UNIFIED IDEOGRAPH + {0x8ECD, 0x5E6B}, //2611 #CJK UNIFIED IDEOGRAPH + {0x8ECE, 0x5E6C}, //2612 #CJK UNIFIED IDEOGRAPH + {0x8ECF, 0x5E6D}, //2613 #CJK UNIFIED IDEOGRAPH + {0x8ED0, 0x5E6E}, //2614 #CJK UNIFIED IDEOGRAPH + {0x8ED1, 0x5E6F}, //2615 #CJK UNIFIED IDEOGRAPH + {0x8ED2, 0x5E70}, //2616 #CJK UNIFIED IDEOGRAPH + {0x8ED3, 0x5E71}, //2617 #CJK UNIFIED IDEOGRAPH + {0x8ED4, 0x5E75}, //2618 #CJK UNIFIED IDEOGRAPH + {0x8ED5, 0x5E77}, //2619 #CJK UNIFIED IDEOGRAPH + {0x8ED6, 0x5E79}, //2620 #CJK UNIFIED IDEOGRAPH + {0x8ED7, 0x5E7E}, //2621 #CJK UNIFIED IDEOGRAPH + {0x8ED8, 0x5E81}, //2622 #CJK UNIFIED IDEOGRAPH + {0x8ED9, 0x5E82}, //2623 #CJK UNIFIED IDEOGRAPH + {0x8EDA, 0x5E83}, //2624 #CJK UNIFIED IDEOGRAPH + {0x8EDB, 0x5E85}, //2625 #CJK UNIFIED IDEOGRAPH + {0x8EDC, 0x5E88}, //2626 #CJK UNIFIED IDEOGRAPH + {0x8EDD, 0x5E89}, //2627 #CJK UNIFIED IDEOGRAPH + {0x8EDE, 0x5E8C}, //2628 #CJK UNIFIED IDEOGRAPH + {0x8EDF, 0x5E8D}, //2629 #CJK UNIFIED IDEOGRAPH + {0x8EE0, 0x5E8E}, //2630 #CJK UNIFIED IDEOGRAPH + {0x8EE1, 0x5E92}, //2631 #CJK UNIFIED IDEOGRAPH + {0x8EE2, 0x5E98}, //2632 #CJK UNIFIED IDEOGRAPH + {0x8EE3, 0x5E9B}, //2633 #CJK UNIFIED IDEOGRAPH + {0x8EE4, 0x5E9D}, //2634 #CJK UNIFIED IDEOGRAPH + {0x8EE5, 0x5EA1}, //2635 #CJK UNIFIED IDEOGRAPH + {0x8EE6, 0x5EA2}, //2636 #CJK UNIFIED IDEOGRAPH + {0x8EE7, 0x5EA3}, //2637 #CJK UNIFIED IDEOGRAPH + {0x8EE8, 0x5EA4}, //2638 #CJK UNIFIED IDEOGRAPH + {0x8EE9, 0x5EA8}, //2639 #CJK UNIFIED IDEOGRAPH + {0x8EEA, 0x5EA9}, //2640 #CJK UNIFIED IDEOGRAPH + {0x8EEB, 0x5EAA}, //2641 #CJK UNIFIED IDEOGRAPH + {0x8EEC, 0x5EAB}, //2642 #CJK UNIFIED IDEOGRAPH + {0x8EED, 0x5EAC}, //2643 #CJK UNIFIED IDEOGRAPH + {0x8EEE, 0x5EAE}, //2644 #CJK UNIFIED IDEOGRAPH + {0x8EEF, 0x5EAF}, //2645 #CJK UNIFIED IDEOGRAPH + {0x8EF0, 0x5EB0}, //2646 #CJK UNIFIED IDEOGRAPH + {0x8EF1, 0x5EB1}, //2647 #CJK UNIFIED IDEOGRAPH + {0x8EF2, 0x5EB2}, //2648 #CJK UNIFIED IDEOGRAPH + {0x8EF3, 0x5EB4}, //2649 #CJK UNIFIED IDEOGRAPH + {0x8EF4, 0x5EBA}, //2650 #CJK UNIFIED IDEOGRAPH + {0x8EF5, 0x5EBB}, //2651 #CJK UNIFIED IDEOGRAPH + {0x8EF6, 0x5EBC}, //2652 #CJK UNIFIED IDEOGRAPH + {0x8EF7, 0x5EBD}, //2653 #CJK UNIFIED IDEOGRAPH + {0x8EF8, 0x5EBF}, //2654 #CJK UNIFIED IDEOGRAPH + {0x8EF9, 0x5EC0}, //2655 #CJK UNIFIED IDEOGRAPH + {0x8EFA, 0x5EC1}, //2656 #CJK UNIFIED IDEOGRAPH + {0x8EFB, 0x5EC2}, //2657 #CJK UNIFIED IDEOGRAPH + {0x8EFC, 0x5EC3}, //2658 #CJK UNIFIED IDEOGRAPH + {0x8EFD, 0x5EC4}, //2659 #CJK UNIFIED IDEOGRAPH + {0x8EFE, 0x5EC5}, //2660 #CJK UNIFIED IDEOGRAPH + {0x8F40, 0x5EC6}, //2661 #CJK UNIFIED IDEOGRAPH + {0x8F41, 0x5EC7}, //2662 #CJK UNIFIED IDEOGRAPH + {0x8F42, 0x5EC8}, //2663 #CJK UNIFIED IDEOGRAPH + {0x8F43, 0x5ECB}, //2664 #CJK UNIFIED IDEOGRAPH + {0x8F44, 0x5ECC}, //2665 #CJK UNIFIED IDEOGRAPH + {0x8F45, 0x5ECD}, //2666 #CJK UNIFIED IDEOGRAPH + {0x8F46, 0x5ECE}, //2667 #CJK UNIFIED IDEOGRAPH + {0x8F47, 0x5ECF}, //2668 #CJK UNIFIED IDEOGRAPH + {0x8F48, 0x5ED0}, //2669 #CJK UNIFIED IDEOGRAPH + {0x8F49, 0x5ED4}, //2670 #CJK UNIFIED IDEOGRAPH + {0x8F4A, 0x5ED5}, //2671 #CJK UNIFIED IDEOGRAPH + {0x8F4B, 0x5ED7}, //2672 #CJK UNIFIED IDEOGRAPH + {0x8F4C, 0x5ED8}, //2673 #CJK UNIFIED IDEOGRAPH + {0x8F4D, 0x5ED9}, //2674 #CJK UNIFIED IDEOGRAPH + {0x8F4E, 0x5EDA}, //2675 #CJK UNIFIED IDEOGRAPH + {0x8F4F, 0x5EDC}, //2676 #CJK UNIFIED IDEOGRAPH + {0x8F50, 0x5EDD}, //2677 #CJK UNIFIED IDEOGRAPH + {0x8F51, 0x5EDE}, //2678 #CJK UNIFIED IDEOGRAPH + {0x8F52, 0x5EDF}, //2679 #CJK UNIFIED IDEOGRAPH + {0x8F53, 0x5EE0}, //2680 #CJK UNIFIED IDEOGRAPH + {0x8F54, 0x5EE1}, //2681 #CJK UNIFIED IDEOGRAPH + {0x8F55, 0x5EE2}, //2682 #CJK UNIFIED IDEOGRAPH + {0x8F56, 0x5EE3}, //2683 #CJK UNIFIED IDEOGRAPH + {0x8F57, 0x5EE4}, //2684 #CJK UNIFIED IDEOGRAPH + {0x8F58, 0x5EE5}, //2685 #CJK UNIFIED IDEOGRAPH + {0x8F59, 0x5EE6}, //2686 #CJK UNIFIED IDEOGRAPH + {0x8F5A, 0x5EE7}, //2687 #CJK UNIFIED IDEOGRAPH + {0x8F5B, 0x5EE9}, //2688 #CJK UNIFIED IDEOGRAPH + {0x8F5C, 0x5EEB}, //2689 #CJK UNIFIED IDEOGRAPH + {0x8F5D, 0x5EEC}, //2690 #CJK UNIFIED IDEOGRAPH + {0x8F5E, 0x5EED}, //2691 #CJK UNIFIED IDEOGRAPH + {0x8F5F, 0x5EEE}, //2692 #CJK UNIFIED IDEOGRAPH + {0x8F60, 0x5EEF}, //2693 #CJK UNIFIED IDEOGRAPH + {0x8F61, 0x5EF0}, //2694 #CJK UNIFIED IDEOGRAPH + {0x8F62, 0x5EF1}, //2695 #CJK UNIFIED IDEOGRAPH + {0x8F63, 0x5EF2}, //2696 #CJK UNIFIED IDEOGRAPH + {0x8F64, 0x5EF3}, //2697 #CJK UNIFIED IDEOGRAPH + {0x8F65, 0x5EF5}, //2698 #CJK UNIFIED IDEOGRAPH + {0x8F66, 0x5EF8}, //2699 #CJK UNIFIED IDEOGRAPH + {0x8F67, 0x5EF9}, //2700 #CJK UNIFIED IDEOGRAPH + {0x8F68, 0x5EFB}, //2701 #CJK UNIFIED IDEOGRAPH + {0x8F69, 0x5EFC}, //2702 #CJK UNIFIED IDEOGRAPH + {0x8F6A, 0x5EFD}, //2703 #CJK UNIFIED IDEOGRAPH + {0x8F6B, 0x5F05}, //2704 #CJK UNIFIED IDEOGRAPH + {0x8F6C, 0x5F06}, //2705 #CJK UNIFIED IDEOGRAPH + {0x8F6D, 0x5F07}, //2706 #CJK UNIFIED IDEOGRAPH + {0x8F6E, 0x5F09}, //2707 #CJK UNIFIED IDEOGRAPH + {0x8F6F, 0x5F0C}, //2708 #CJK UNIFIED IDEOGRAPH + {0x8F70, 0x5F0D}, //2709 #CJK UNIFIED IDEOGRAPH + {0x8F71, 0x5F0E}, //2710 #CJK UNIFIED IDEOGRAPH + {0x8F72, 0x5F10}, //2711 #CJK UNIFIED IDEOGRAPH + {0x8F73, 0x5F12}, //2712 #CJK UNIFIED IDEOGRAPH + {0x8F74, 0x5F14}, //2713 #CJK UNIFIED IDEOGRAPH + {0x8F75, 0x5F16}, //2714 #CJK UNIFIED IDEOGRAPH + {0x8F76, 0x5F19}, //2715 #CJK UNIFIED IDEOGRAPH + {0x8F77, 0x5F1A}, //2716 #CJK UNIFIED IDEOGRAPH + {0x8F78, 0x5F1C}, //2717 #CJK UNIFIED IDEOGRAPH + {0x8F79, 0x5F1D}, //2718 #CJK UNIFIED IDEOGRAPH + {0x8F7A, 0x5F1E}, //2719 #CJK UNIFIED IDEOGRAPH + {0x8F7B, 0x5F21}, //2720 #CJK UNIFIED IDEOGRAPH + {0x8F7C, 0x5F22}, //2721 #CJK UNIFIED IDEOGRAPH + {0x8F7D, 0x5F23}, //2722 #CJK UNIFIED IDEOGRAPH + {0x8F7E, 0x5F24}, //2723 #CJK UNIFIED IDEOGRAPH + {0x8F80, 0x5F28}, //2724 #CJK UNIFIED IDEOGRAPH + {0x8F81, 0x5F2B}, //2725 #CJK UNIFIED IDEOGRAPH + {0x8F82, 0x5F2C}, //2726 #CJK UNIFIED IDEOGRAPH + {0x8F83, 0x5F2E}, //2727 #CJK UNIFIED IDEOGRAPH + {0x8F84, 0x5F30}, //2728 #CJK UNIFIED IDEOGRAPH + {0x8F85, 0x5F32}, //2729 #CJK UNIFIED IDEOGRAPH + {0x8F86, 0x5F33}, //2730 #CJK UNIFIED IDEOGRAPH + {0x8F87, 0x5F34}, //2731 #CJK UNIFIED IDEOGRAPH + {0x8F88, 0x5F35}, //2732 #CJK UNIFIED IDEOGRAPH + {0x8F89, 0x5F36}, //2733 #CJK UNIFIED IDEOGRAPH + {0x8F8A, 0x5F37}, //2734 #CJK UNIFIED IDEOGRAPH + {0x8F8B, 0x5F38}, //2735 #CJK UNIFIED IDEOGRAPH + {0x8F8C, 0x5F3B}, //2736 #CJK UNIFIED IDEOGRAPH + {0x8F8D, 0x5F3D}, //2737 #CJK UNIFIED IDEOGRAPH + {0x8F8E, 0x5F3E}, //2738 #CJK UNIFIED IDEOGRAPH + {0x8F8F, 0x5F3F}, //2739 #CJK UNIFIED IDEOGRAPH + {0x8F90, 0x5F41}, //2740 #CJK UNIFIED IDEOGRAPH + {0x8F91, 0x5F42}, //2741 #CJK UNIFIED IDEOGRAPH + {0x8F92, 0x5F43}, //2742 #CJK UNIFIED IDEOGRAPH + {0x8F93, 0x5F44}, //2743 #CJK UNIFIED IDEOGRAPH + {0x8F94, 0x5F45}, //2744 #CJK UNIFIED IDEOGRAPH + {0x8F95, 0x5F46}, //2745 #CJK UNIFIED IDEOGRAPH + {0x8F96, 0x5F47}, //2746 #CJK UNIFIED IDEOGRAPH + {0x8F97, 0x5F48}, //2747 #CJK UNIFIED IDEOGRAPH + {0x8F98, 0x5F49}, //2748 #CJK UNIFIED IDEOGRAPH + {0x8F99, 0x5F4A}, //2749 #CJK UNIFIED IDEOGRAPH + {0x8F9A, 0x5F4B}, //2750 #CJK UNIFIED IDEOGRAPH + {0x8F9B, 0x5F4C}, //2751 #CJK UNIFIED IDEOGRAPH + {0x8F9C, 0x5F4D}, //2752 #CJK UNIFIED IDEOGRAPH + {0x8F9D, 0x5F4E}, //2753 #CJK UNIFIED IDEOGRAPH + {0x8F9E, 0x5F4F}, //2754 #CJK UNIFIED IDEOGRAPH + {0x8F9F, 0x5F51}, //2755 #CJK UNIFIED IDEOGRAPH + {0x8FA0, 0x5F54}, //2756 #CJK UNIFIED IDEOGRAPH + {0x8FA1, 0x5F59}, //2757 #CJK UNIFIED IDEOGRAPH + {0x8FA2, 0x5F5A}, //2758 #CJK UNIFIED IDEOGRAPH + {0x8FA3, 0x5F5B}, //2759 #CJK UNIFIED IDEOGRAPH + {0x8FA4, 0x5F5C}, //2760 #CJK UNIFIED IDEOGRAPH + {0x8FA5, 0x5F5E}, //2761 #CJK UNIFIED IDEOGRAPH + {0x8FA6, 0x5F5F}, //2762 #CJK UNIFIED IDEOGRAPH + {0x8FA7, 0x5F60}, //2763 #CJK UNIFIED IDEOGRAPH + {0x8FA8, 0x5F63}, //2764 #CJK UNIFIED IDEOGRAPH + {0x8FA9, 0x5F65}, //2765 #CJK UNIFIED IDEOGRAPH + {0x8FAA, 0x5F67}, //2766 #CJK UNIFIED IDEOGRAPH + {0x8FAB, 0x5F68}, //2767 #CJK UNIFIED IDEOGRAPH + {0x8FAC, 0x5F6B}, //2768 #CJK UNIFIED IDEOGRAPH + {0x8FAD, 0x5F6E}, //2769 #CJK UNIFIED IDEOGRAPH + {0x8FAE, 0x5F6F}, //2770 #CJK UNIFIED IDEOGRAPH + {0x8FAF, 0x5F72}, //2771 #CJK UNIFIED IDEOGRAPH + {0x8FB0, 0x5F74}, //2772 #CJK UNIFIED IDEOGRAPH + {0x8FB1, 0x5F75}, //2773 #CJK UNIFIED IDEOGRAPH + {0x8FB2, 0x5F76}, //2774 #CJK UNIFIED IDEOGRAPH + {0x8FB3, 0x5F78}, //2775 #CJK UNIFIED IDEOGRAPH + {0x8FB4, 0x5F7A}, //2776 #CJK UNIFIED IDEOGRAPH + {0x8FB5, 0x5F7D}, //2777 #CJK UNIFIED IDEOGRAPH + {0x8FB6, 0x5F7E}, //2778 #CJK UNIFIED IDEOGRAPH + {0x8FB7, 0x5F7F}, //2779 #CJK UNIFIED IDEOGRAPH + {0x8FB8, 0x5F83}, //2780 #CJK UNIFIED IDEOGRAPH + {0x8FB9, 0x5F86}, //2781 #CJK UNIFIED IDEOGRAPH + {0x8FBA, 0x5F8D}, //2782 #CJK UNIFIED IDEOGRAPH + {0x8FBB, 0x5F8E}, //2783 #CJK UNIFIED IDEOGRAPH + {0x8FBC, 0x5F8F}, //2784 #CJK UNIFIED IDEOGRAPH + {0x8FBD, 0x5F91}, //2785 #CJK UNIFIED IDEOGRAPH + {0x8FBE, 0x5F93}, //2786 #CJK UNIFIED IDEOGRAPH + {0x8FBF, 0x5F94}, //2787 #CJK UNIFIED IDEOGRAPH + {0x8FC0, 0x5F96}, //2788 #CJK UNIFIED IDEOGRAPH + {0x8FC1, 0x5F9A}, //2789 #CJK UNIFIED IDEOGRAPH + {0x8FC2, 0x5F9B}, //2790 #CJK UNIFIED IDEOGRAPH + {0x8FC3, 0x5F9D}, //2791 #CJK UNIFIED IDEOGRAPH + {0x8FC4, 0x5F9E}, //2792 #CJK UNIFIED IDEOGRAPH + {0x8FC5, 0x5F9F}, //2793 #CJK UNIFIED IDEOGRAPH + {0x8FC6, 0x5FA0}, //2794 #CJK UNIFIED IDEOGRAPH + {0x8FC7, 0x5FA2}, //2795 #CJK UNIFIED IDEOGRAPH + {0x8FC8, 0x5FA3}, //2796 #CJK UNIFIED IDEOGRAPH + {0x8FC9, 0x5FA4}, //2797 #CJK UNIFIED IDEOGRAPH + {0x8FCA, 0x5FA5}, //2798 #CJK UNIFIED IDEOGRAPH + {0x8FCB, 0x5FA6}, //2799 #CJK UNIFIED IDEOGRAPH + {0x8FCC, 0x5FA7}, //2800 #CJK UNIFIED IDEOGRAPH + {0x8FCD, 0x5FA9}, //2801 #CJK UNIFIED IDEOGRAPH + {0x8FCE, 0x5FAB}, //2802 #CJK UNIFIED IDEOGRAPH + {0x8FCF, 0x5FAC}, //2803 #CJK UNIFIED IDEOGRAPH + {0x8FD0, 0x5FAF}, //2804 #CJK UNIFIED IDEOGRAPH + {0x8FD1, 0x5FB0}, //2805 #CJK UNIFIED IDEOGRAPH + {0x8FD2, 0x5FB1}, //2806 #CJK UNIFIED IDEOGRAPH + {0x8FD3, 0x5FB2}, //2807 #CJK UNIFIED IDEOGRAPH + {0x8FD4, 0x5FB3}, //2808 #CJK UNIFIED IDEOGRAPH + {0x8FD5, 0x5FB4}, //2809 #CJK UNIFIED IDEOGRAPH + {0x8FD6, 0x5FB6}, //2810 #CJK UNIFIED IDEOGRAPH + {0x8FD7, 0x5FB8}, //2811 #CJK UNIFIED IDEOGRAPH + {0x8FD8, 0x5FB9}, //2812 #CJK UNIFIED IDEOGRAPH + {0x8FD9, 0x5FBA}, //2813 #CJK UNIFIED IDEOGRAPH + {0x8FDA, 0x5FBB}, //2814 #CJK UNIFIED IDEOGRAPH + {0x8FDB, 0x5FBE}, //2815 #CJK UNIFIED IDEOGRAPH + {0x8FDC, 0x5FBF}, //2816 #CJK UNIFIED IDEOGRAPH + {0x8FDD, 0x5FC0}, //2817 #CJK UNIFIED IDEOGRAPH + {0x8FDE, 0x5FC1}, //2818 #CJK UNIFIED IDEOGRAPH + {0x8FDF, 0x5FC2}, //2819 #CJK UNIFIED IDEOGRAPH + {0x8FE0, 0x5FC7}, //2820 #CJK UNIFIED IDEOGRAPH + {0x8FE1, 0x5FC8}, //2821 #CJK UNIFIED IDEOGRAPH + {0x8FE2, 0x5FCA}, //2822 #CJK UNIFIED IDEOGRAPH + {0x8FE3, 0x5FCB}, //2823 #CJK UNIFIED IDEOGRAPH + {0x8FE4, 0x5FCE}, //2824 #CJK UNIFIED IDEOGRAPH + {0x8FE5, 0x5FD3}, //2825 #CJK UNIFIED IDEOGRAPH + {0x8FE6, 0x5FD4}, //2826 #CJK UNIFIED IDEOGRAPH + {0x8FE7, 0x5FD5}, //2827 #CJK UNIFIED IDEOGRAPH + {0x8FE8, 0x5FDA}, //2828 #CJK UNIFIED IDEOGRAPH + {0x8FE9, 0x5FDB}, //2829 #CJK UNIFIED IDEOGRAPH + {0x8FEA, 0x5FDC}, //2830 #CJK UNIFIED IDEOGRAPH + {0x8FEB, 0x5FDE}, //2831 #CJK UNIFIED IDEOGRAPH + {0x8FEC, 0x5FDF}, //2832 #CJK UNIFIED IDEOGRAPH + {0x8FED, 0x5FE2}, //2833 #CJK UNIFIED IDEOGRAPH + {0x8FEE, 0x5FE3}, //2834 #CJK UNIFIED IDEOGRAPH + {0x8FEF, 0x5FE5}, //2835 #CJK UNIFIED IDEOGRAPH + {0x8FF0, 0x5FE6}, //2836 #CJK UNIFIED IDEOGRAPH + {0x8FF1, 0x5FE8}, //2837 #CJK UNIFIED IDEOGRAPH + {0x8FF2, 0x5FE9}, //2838 #CJK UNIFIED IDEOGRAPH + {0x8FF3, 0x5FEC}, //2839 #CJK UNIFIED IDEOGRAPH + {0x8FF4, 0x5FEF}, //2840 #CJK UNIFIED IDEOGRAPH + {0x8FF5, 0x5FF0}, //2841 #CJK UNIFIED IDEOGRAPH + {0x8FF6, 0x5FF2}, //2842 #CJK UNIFIED IDEOGRAPH + {0x8FF7, 0x5FF3}, //2843 #CJK UNIFIED IDEOGRAPH + {0x8FF8, 0x5FF4}, //2844 #CJK UNIFIED IDEOGRAPH + {0x8FF9, 0x5FF6}, //2845 #CJK UNIFIED IDEOGRAPH + {0x8FFA, 0x5FF7}, //2846 #CJK UNIFIED IDEOGRAPH + {0x8FFB, 0x5FF9}, //2847 #CJK UNIFIED IDEOGRAPH + {0x8FFC, 0x5FFA}, //2848 #CJK UNIFIED IDEOGRAPH + {0x8FFD, 0x5FFC}, //2849 #CJK UNIFIED IDEOGRAPH + {0x8FFE, 0x6007}, //2850 #CJK UNIFIED IDEOGRAPH + {0x9040, 0x6008}, //2851 #CJK UNIFIED IDEOGRAPH + {0x9041, 0x6009}, //2852 #CJK UNIFIED IDEOGRAPH + {0x9042, 0x600B}, //2853 #CJK UNIFIED IDEOGRAPH + {0x9043, 0x600C}, //2854 #CJK UNIFIED IDEOGRAPH + {0x9044, 0x6010}, //2855 #CJK UNIFIED IDEOGRAPH + {0x9045, 0x6011}, //2856 #CJK UNIFIED IDEOGRAPH + {0x9046, 0x6013}, //2857 #CJK UNIFIED IDEOGRAPH + {0x9047, 0x6017}, //2858 #CJK UNIFIED IDEOGRAPH + {0x9048, 0x6018}, //2859 #CJK UNIFIED IDEOGRAPH + {0x9049, 0x601A}, //2860 #CJK UNIFIED IDEOGRAPH + {0x904A, 0x601E}, //2861 #CJK UNIFIED IDEOGRAPH + {0x904B, 0x601F}, //2862 #CJK UNIFIED IDEOGRAPH + {0x904C, 0x6022}, //2863 #CJK UNIFIED IDEOGRAPH + {0x904D, 0x6023}, //2864 #CJK UNIFIED IDEOGRAPH + {0x904E, 0x6024}, //2865 #CJK UNIFIED IDEOGRAPH + {0x904F, 0x602C}, //2866 #CJK UNIFIED IDEOGRAPH + {0x9050, 0x602D}, //2867 #CJK UNIFIED IDEOGRAPH + {0x9051, 0x602E}, //2868 #CJK UNIFIED IDEOGRAPH + {0x9052, 0x6030}, //2869 #CJK UNIFIED IDEOGRAPH + {0x9053, 0x6031}, //2870 #CJK UNIFIED IDEOGRAPH + {0x9054, 0x6032}, //2871 #CJK UNIFIED IDEOGRAPH + {0x9055, 0x6033}, //2872 #CJK UNIFIED IDEOGRAPH + {0x9056, 0x6034}, //2873 #CJK UNIFIED IDEOGRAPH + {0x9057, 0x6036}, //2874 #CJK UNIFIED IDEOGRAPH + {0x9058, 0x6037}, //2875 #CJK UNIFIED IDEOGRAPH + {0x9059, 0x6038}, //2876 #CJK UNIFIED IDEOGRAPH + {0x905A, 0x6039}, //2877 #CJK UNIFIED IDEOGRAPH + {0x905B, 0x603A}, //2878 #CJK UNIFIED IDEOGRAPH + {0x905C, 0x603D}, //2879 #CJK UNIFIED IDEOGRAPH + {0x905D, 0x603E}, //2880 #CJK UNIFIED IDEOGRAPH + {0x905E, 0x6040}, //2881 #CJK UNIFIED IDEOGRAPH + {0x905F, 0x6044}, //2882 #CJK UNIFIED IDEOGRAPH + {0x9060, 0x6045}, //2883 #CJK UNIFIED IDEOGRAPH + {0x9061, 0x6046}, //2884 #CJK UNIFIED IDEOGRAPH + {0x9062, 0x6047}, //2885 #CJK UNIFIED IDEOGRAPH + {0x9063, 0x6048}, //2886 #CJK UNIFIED IDEOGRAPH + {0x9064, 0x6049}, //2887 #CJK UNIFIED IDEOGRAPH + {0x9065, 0x604A}, //2888 #CJK UNIFIED IDEOGRAPH + {0x9066, 0x604C}, //2889 #CJK UNIFIED IDEOGRAPH + {0x9067, 0x604E}, //2890 #CJK UNIFIED IDEOGRAPH + {0x9068, 0x604F}, //2891 #CJK UNIFIED IDEOGRAPH + {0x9069, 0x6051}, //2892 #CJK UNIFIED IDEOGRAPH + {0x906A, 0x6053}, //2893 #CJK UNIFIED IDEOGRAPH + {0x906B, 0x6054}, //2894 #CJK UNIFIED IDEOGRAPH + {0x906C, 0x6056}, //2895 #CJK UNIFIED IDEOGRAPH + {0x906D, 0x6057}, //2896 #CJK UNIFIED IDEOGRAPH + {0x906E, 0x6058}, //2897 #CJK UNIFIED IDEOGRAPH + {0x906F, 0x605B}, //2898 #CJK UNIFIED IDEOGRAPH + {0x9070, 0x605C}, //2899 #CJK UNIFIED IDEOGRAPH + {0x9071, 0x605E}, //2900 #CJK UNIFIED IDEOGRAPH + {0x9072, 0x605F}, //2901 #CJK UNIFIED IDEOGRAPH + {0x9073, 0x6060}, //2902 #CJK UNIFIED IDEOGRAPH + {0x9074, 0x6061}, //2903 #CJK UNIFIED IDEOGRAPH + {0x9075, 0x6065}, //2904 #CJK UNIFIED IDEOGRAPH + {0x9076, 0x6066}, //2905 #CJK UNIFIED IDEOGRAPH + {0x9077, 0x606E}, //2906 #CJK UNIFIED IDEOGRAPH + {0x9078, 0x6071}, //2907 #CJK UNIFIED IDEOGRAPH + {0x9079, 0x6072}, //2908 #CJK UNIFIED IDEOGRAPH + {0x907A, 0x6074}, //2909 #CJK UNIFIED IDEOGRAPH + {0x907B, 0x6075}, //2910 #CJK UNIFIED IDEOGRAPH + {0x907C, 0x6077}, //2911 #CJK UNIFIED IDEOGRAPH + {0x907D, 0x607E}, //2912 #CJK UNIFIED IDEOGRAPH + {0x907E, 0x6080}, //2913 #CJK UNIFIED IDEOGRAPH + {0x9080, 0x6081}, //2914 #CJK UNIFIED IDEOGRAPH + {0x9081, 0x6082}, //2915 #CJK UNIFIED IDEOGRAPH + {0x9082, 0x6085}, //2916 #CJK UNIFIED IDEOGRAPH + {0x9083, 0x6086}, //2917 #CJK UNIFIED IDEOGRAPH + {0x9084, 0x6087}, //2918 #CJK UNIFIED IDEOGRAPH + {0x9085, 0x6088}, //2919 #CJK UNIFIED IDEOGRAPH + {0x9086, 0x608A}, //2920 #CJK UNIFIED IDEOGRAPH + {0x9087, 0x608B}, //2921 #CJK UNIFIED IDEOGRAPH + {0x9088, 0x608E}, //2922 #CJK UNIFIED IDEOGRAPH + {0x9089, 0x608F}, //2923 #CJK UNIFIED IDEOGRAPH + {0x908A, 0x6090}, //2924 #CJK UNIFIED IDEOGRAPH + {0x908B, 0x6091}, //2925 #CJK UNIFIED IDEOGRAPH + {0x908C, 0x6093}, //2926 #CJK UNIFIED IDEOGRAPH + {0x908D, 0x6095}, //2927 #CJK UNIFIED IDEOGRAPH + {0x908E, 0x6097}, //2928 #CJK UNIFIED IDEOGRAPH + {0x908F, 0x6098}, //2929 #CJK UNIFIED IDEOGRAPH + {0x9090, 0x6099}, //2930 #CJK UNIFIED IDEOGRAPH + {0x9091, 0x609C}, //2931 #CJK UNIFIED IDEOGRAPH + {0x9092, 0x609E}, //2932 #CJK UNIFIED IDEOGRAPH + {0x9093, 0x60A1}, //2933 #CJK UNIFIED IDEOGRAPH + {0x9094, 0x60A2}, //2934 #CJK UNIFIED IDEOGRAPH + {0x9095, 0x60A4}, //2935 #CJK UNIFIED IDEOGRAPH + {0x9096, 0x60A5}, //2936 #CJK UNIFIED IDEOGRAPH + {0x9097, 0x60A7}, //2937 #CJK UNIFIED IDEOGRAPH + {0x9098, 0x60A9}, //2938 #CJK UNIFIED IDEOGRAPH + {0x9099, 0x60AA}, //2939 #CJK UNIFIED IDEOGRAPH + {0x909A, 0x60AE}, //2940 #CJK UNIFIED IDEOGRAPH + {0x909B, 0x60B0}, //2941 #CJK UNIFIED IDEOGRAPH + {0x909C, 0x60B3}, //2942 #CJK UNIFIED IDEOGRAPH + {0x909D, 0x60B5}, //2943 #CJK UNIFIED IDEOGRAPH + {0x909E, 0x60B6}, //2944 #CJK UNIFIED IDEOGRAPH + {0x909F, 0x60B7}, //2945 #CJK UNIFIED IDEOGRAPH + {0x90A0, 0x60B9}, //2946 #CJK UNIFIED IDEOGRAPH + {0x90A1, 0x60BA}, //2947 #CJK UNIFIED IDEOGRAPH + {0x90A2, 0x60BD}, //2948 #CJK UNIFIED IDEOGRAPH + {0x90A3, 0x60BE}, //2949 #CJK UNIFIED IDEOGRAPH + {0x90A4, 0x60BF}, //2950 #CJK UNIFIED IDEOGRAPH + {0x90A5, 0x60C0}, //2951 #CJK UNIFIED IDEOGRAPH + {0x90A6, 0x60C1}, //2952 #CJK UNIFIED IDEOGRAPH + {0x90A7, 0x60C2}, //2953 #CJK UNIFIED IDEOGRAPH + {0x90A8, 0x60C3}, //2954 #CJK UNIFIED IDEOGRAPH + {0x90A9, 0x60C4}, //2955 #CJK UNIFIED IDEOGRAPH + {0x90AA, 0x60C7}, //2956 #CJK UNIFIED IDEOGRAPH + {0x90AB, 0x60C8}, //2957 #CJK UNIFIED IDEOGRAPH + {0x90AC, 0x60C9}, //2958 #CJK UNIFIED IDEOGRAPH + {0x90AD, 0x60CC}, //2959 #CJK UNIFIED IDEOGRAPH + {0x90AE, 0x60CD}, //2960 #CJK UNIFIED IDEOGRAPH + {0x90AF, 0x60CE}, //2961 #CJK UNIFIED IDEOGRAPH + {0x90B0, 0x60CF}, //2962 #CJK UNIFIED IDEOGRAPH + {0x90B1, 0x60D0}, //2963 #CJK UNIFIED IDEOGRAPH + {0x90B2, 0x60D2}, //2964 #CJK UNIFIED IDEOGRAPH + {0x90B3, 0x60D3}, //2965 #CJK UNIFIED IDEOGRAPH + {0x90B4, 0x60D4}, //2966 #CJK UNIFIED IDEOGRAPH + {0x90B5, 0x60D6}, //2967 #CJK UNIFIED IDEOGRAPH + {0x90B6, 0x60D7}, //2968 #CJK UNIFIED IDEOGRAPH + {0x90B7, 0x60D9}, //2969 #CJK UNIFIED IDEOGRAPH + {0x90B8, 0x60DB}, //2970 #CJK UNIFIED IDEOGRAPH + {0x90B9, 0x60DE}, //2971 #CJK UNIFIED IDEOGRAPH + {0x90BA, 0x60E1}, //2972 #CJK UNIFIED IDEOGRAPH + {0x90BB, 0x60E2}, //2973 #CJK UNIFIED IDEOGRAPH + {0x90BC, 0x60E3}, //2974 #CJK UNIFIED IDEOGRAPH + {0x90BD, 0x60E4}, //2975 #CJK UNIFIED IDEOGRAPH + {0x90BE, 0x60E5}, //2976 #CJK UNIFIED IDEOGRAPH + {0x90BF, 0x60EA}, //2977 #CJK UNIFIED IDEOGRAPH + {0x90C0, 0x60F1}, //2978 #CJK UNIFIED IDEOGRAPH + {0x90C1, 0x60F2}, //2979 #CJK UNIFIED IDEOGRAPH + {0x90C2, 0x60F5}, //2980 #CJK UNIFIED IDEOGRAPH + {0x90C3, 0x60F7}, //2981 #CJK UNIFIED IDEOGRAPH + {0x90C4, 0x60F8}, //2982 #CJK UNIFIED IDEOGRAPH + {0x90C5, 0x60FB}, //2983 #CJK UNIFIED IDEOGRAPH + {0x90C6, 0x60FC}, //2984 #CJK UNIFIED IDEOGRAPH + {0x90C7, 0x60FD}, //2985 #CJK UNIFIED IDEOGRAPH + {0x90C8, 0x60FE}, //2986 #CJK UNIFIED IDEOGRAPH + {0x90C9, 0x60FF}, //2987 #CJK UNIFIED IDEOGRAPH + {0x90CA, 0x6102}, //2988 #CJK UNIFIED IDEOGRAPH + {0x90CB, 0x6103}, //2989 #CJK UNIFIED IDEOGRAPH + {0x90CC, 0x6104}, //2990 #CJK UNIFIED IDEOGRAPH + {0x90CD, 0x6105}, //2991 #CJK UNIFIED IDEOGRAPH + {0x90CE, 0x6107}, //2992 #CJK UNIFIED IDEOGRAPH + {0x90CF, 0x610A}, //2993 #CJK UNIFIED IDEOGRAPH + {0x90D0, 0x610B}, //2994 #CJK UNIFIED IDEOGRAPH + {0x90D1, 0x610C}, //2995 #CJK UNIFIED IDEOGRAPH + {0x90D2, 0x6110}, //2996 #CJK UNIFIED IDEOGRAPH + {0x90D3, 0x6111}, //2997 #CJK UNIFIED IDEOGRAPH + {0x90D4, 0x6112}, //2998 #CJK UNIFIED IDEOGRAPH + {0x90D5, 0x6113}, //2999 #CJK UNIFIED IDEOGRAPH + {0x90D6, 0x6114}, //3000 #CJK UNIFIED IDEOGRAPH + {0x90D7, 0x6116}, //3001 #CJK UNIFIED IDEOGRAPH + {0x90D8, 0x6117}, //3002 #CJK UNIFIED IDEOGRAPH + {0x90D9, 0x6118}, //3003 #CJK UNIFIED IDEOGRAPH + {0x90DA, 0x6119}, //3004 #CJK UNIFIED IDEOGRAPH + {0x90DB, 0x611B}, //3005 #CJK UNIFIED IDEOGRAPH + {0x90DC, 0x611C}, //3006 #CJK UNIFIED IDEOGRAPH + {0x90DD, 0x611D}, //3007 #CJK UNIFIED IDEOGRAPH + {0x90DE, 0x611E}, //3008 #CJK UNIFIED IDEOGRAPH + {0x90DF, 0x6121}, //3009 #CJK UNIFIED IDEOGRAPH + {0x90E0, 0x6122}, //3010 #CJK UNIFIED IDEOGRAPH + {0x90E1, 0x6125}, //3011 #CJK UNIFIED IDEOGRAPH + {0x90E2, 0x6128}, //3012 #CJK UNIFIED IDEOGRAPH + {0x90E3, 0x6129}, //3013 #CJK UNIFIED IDEOGRAPH + {0x90E4, 0x612A}, //3014 #CJK UNIFIED IDEOGRAPH + {0x90E5, 0x612C}, //3015 #CJK UNIFIED IDEOGRAPH + {0x90E6, 0x612D}, //3016 #CJK UNIFIED IDEOGRAPH + {0x90E7, 0x612E}, //3017 #CJK UNIFIED IDEOGRAPH + {0x90E8, 0x612F}, //3018 #CJK UNIFIED IDEOGRAPH + {0x90E9, 0x6130}, //3019 #CJK UNIFIED IDEOGRAPH + {0x90EA, 0x6131}, //3020 #CJK UNIFIED IDEOGRAPH + {0x90EB, 0x6132}, //3021 #CJK UNIFIED IDEOGRAPH + {0x90EC, 0x6133}, //3022 #CJK UNIFIED IDEOGRAPH + {0x90ED, 0x6134}, //3023 #CJK UNIFIED IDEOGRAPH + {0x90EE, 0x6135}, //3024 #CJK UNIFIED IDEOGRAPH + {0x90EF, 0x6136}, //3025 #CJK UNIFIED IDEOGRAPH + {0x90F0, 0x6137}, //3026 #CJK UNIFIED IDEOGRAPH + {0x90F1, 0x6138}, //3027 #CJK UNIFIED IDEOGRAPH + {0x90F2, 0x6139}, //3028 #CJK UNIFIED IDEOGRAPH + {0x90F3, 0x613A}, //3029 #CJK UNIFIED IDEOGRAPH + {0x90F4, 0x613B}, //3030 #CJK UNIFIED IDEOGRAPH + {0x90F5, 0x613C}, //3031 #CJK UNIFIED IDEOGRAPH + {0x90F6, 0x613D}, //3032 #CJK UNIFIED IDEOGRAPH + {0x90F7, 0x613E}, //3033 #CJK UNIFIED IDEOGRAPH + {0x90F8, 0x6140}, //3034 #CJK UNIFIED IDEOGRAPH + {0x90F9, 0x6141}, //3035 #CJK UNIFIED IDEOGRAPH + {0x90FA, 0x6142}, //3036 #CJK UNIFIED IDEOGRAPH + {0x90FB, 0x6143}, //3037 #CJK UNIFIED IDEOGRAPH + {0x90FC, 0x6144}, //3038 #CJK UNIFIED IDEOGRAPH + {0x90FD, 0x6145}, //3039 #CJK UNIFIED IDEOGRAPH + {0x90FE, 0x6146}, //3040 #CJK UNIFIED IDEOGRAPH + {0x9140, 0x6147}, //3041 #CJK UNIFIED IDEOGRAPH + {0x9141, 0x6149}, //3042 #CJK UNIFIED IDEOGRAPH + {0x9142, 0x614B}, //3043 #CJK UNIFIED IDEOGRAPH + {0x9143, 0x614D}, //3044 #CJK UNIFIED IDEOGRAPH + {0x9144, 0x614F}, //3045 #CJK UNIFIED IDEOGRAPH + {0x9145, 0x6150}, //3046 #CJK UNIFIED IDEOGRAPH + {0x9146, 0x6152}, //3047 #CJK UNIFIED IDEOGRAPH + {0x9147, 0x6153}, //3048 #CJK UNIFIED IDEOGRAPH + {0x9148, 0x6154}, //3049 #CJK UNIFIED IDEOGRAPH + {0x9149, 0x6156}, //3050 #CJK UNIFIED IDEOGRAPH + {0x914A, 0x6157}, //3051 #CJK UNIFIED IDEOGRAPH + {0x914B, 0x6158}, //3052 #CJK UNIFIED IDEOGRAPH + {0x914C, 0x6159}, //3053 #CJK UNIFIED IDEOGRAPH + {0x914D, 0x615A}, //3054 #CJK UNIFIED IDEOGRAPH + {0x914E, 0x615B}, //3055 #CJK UNIFIED IDEOGRAPH + {0x914F, 0x615C}, //3056 #CJK UNIFIED IDEOGRAPH + {0x9150, 0x615E}, //3057 #CJK UNIFIED IDEOGRAPH + {0x9151, 0x615F}, //3058 #CJK UNIFIED IDEOGRAPH + {0x9152, 0x6160}, //3059 #CJK UNIFIED IDEOGRAPH + {0x9153, 0x6161}, //3060 #CJK UNIFIED IDEOGRAPH + {0x9154, 0x6163}, //3061 #CJK UNIFIED IDEOGRAPH + {0x9155, 0x6164}, //3062 #CJK UNIFIED IDEOGRAPH + {0x9156, 0x6165}, //3063 #CJK UNIFIED IDEOGRAPH + {0x9157, 0x6166}, //3064 #CJK UNIFIED IDEOGRAPH + {0x9158, 0x6169}, //3065 #CJK UNIFIED IDEOGRAPH + {0x9159, 0x616A}, //3066 #CJK UNIFIED IDEOGRAPH + {0x915A, 0x616B}, //3067 #CJK UNIFIED IDEOGRAPH + {0x915B, 0x616C}, //3068 #CJK UNIFIED IDEOGRAPH + {0x915C, 0x616D}, //3069 #CJK UNIFIED IDEOGRAPH + {0x915D, 0x616E}, //3070 #CJK UNIFIED IDEOGRAPH + {0x915E, 0x616F}, //3071 #CJK UNIFIED IDEOGRAPH + {0x915F, 0x6171}, //3072 #CJK UNIFIED IDEOGRAPH + {0x9160, 0x6172}, //3073 #CJK UNIFIED IDEOGRAPH + {0x9161, 0x6173}, //3074 #CJK UNIFIED IDEOGRAPH + {0x9162, 0x6174}, //3075 #CJK UNIFIED IDEOGRAPH + {0x9163, 0x6176}, //3076 #CJK UNIFIED IDEOGRAPH + {0x9164, 0x6178}, //3077 #CJK UNIFIED IDEOGRAPH + {0x9165, 0x6179}, //3078 #CJK UNIFIED IDEOGRAPH + {0x9166, 0x617A}, //3079 #CJK UNIFIED IDEOGRAPH + {0x9167, 0x617B}, //3080 #CJK UNIFIED IDEOGRAPH + {0x9168, 0x617C}, //3081 #CJK UNIFIED IDEOGRAPH + {0x9169, 0x617D}, //3082 #CJK UNIFIED IDEOGRAPH + {0x916A, 0x617E}, //3083 #CJK UNIFIED IDEOGRAPH + {0x916B, 0x617F}, //3084 #CJK UNIFIED IDEOGRAPH + {0x916C, 0x6180}, //3085 #CJK UNIFIED IDEOGRAPH + {0x916D, 0x6181}, //3086 #CJK UNIFIED IDEOGRAPH + {0x916E, 0x6182}, //3087 #CJK UNIFIED IDEOGRAPH + {0x916F, 0x6183}, //3088 #CJK UNIFIED IDEOGRAPH + {0x9170, 0x6184}, //3089 #CJK UNIFIED IDEOGRAPH + {0x9171, 0x6185}, //3090 #CJK UNIFIED IDEOGRAPH + {0x9172, 0x6186}, //3091 #CJK UNIFIED IDEOGRAPH + {0x9173, 0x6187}, //3092 #CJK UNIFIED IDEOGRAPH + {0x9174, 0x6188}, //3093 #CJK UNIFIED IDEOGRAPH + {0x9175, 0x6189}, //3094 #CJK UNIFIED IDEOGRAPH + {0x9176, 0x618A}, //3095 #CJK UNIFIED IDEOGRAPH + {0x9177, 0x618C}, //3096 #CJK UNIFIED IDEOGRAPH + {0x9178, 0x618D}, //3097 #CJK UNIFIED IDEOGRAPH + {0x9179, 0x618F}, //3098 #CJK UNIFIED IDEOGRAPH + {0x917A, 0x6190}, //3099 #CJK UNIFIED IDEOGRAPH + {0x917B, 0x6191}, //3100 #CJK UNIFIED IDEOGRAPH + {0x917C, 0x6192}, //3101 #CJK UNIFIED IDEOGRAPH + {0x917D, 0x6193}, //3102 #CJK UNIFIED IDEOGRAPH + {0x917E, 0x6195}, //3103 #CJK UNIFIED IDEOGRAPH + {0x9180, 0x6196}, //3104 #CJK UNIFIED IDEOGRAPH + {0x9181, 0x6197}, //3105 #CJK UNIFIED IDEOGRAPH + {0x9182, 0x6198}, //3106 #CJK UNIFIED IDEOGRAPH + {0x9183, 0x6199}, //3107 #CJK UNIFIED IDEOGRAPH + {0x9184, 0x619A}, //3108 #CJK UNIFIED IDEOGRAPH + {0x9185, 0x619B}, //3109 #CJK UNIFIED IDEOGRAPH + {0x9186, 0x619C}, //3110 #CJK UNIFIED IDEOGRAPH + {0x9187, 0x619E}, //3111 #CJK UNIFIED IDEOGRAPH + {0x9188, 0x619F}, //3112 #CJK UNIFIED IDEOGRAPH + {0x9189, 0x61A0}, //3113 #CJK UNIFIED IDEOGRAPH + {0x918A, 0x61A1}, //3114 #CJK UNIFIED IDEOGRAPH + {0x918B, 0x61A2}, //3115 #CJK UNIFIED IDEOGRAPH + {0x918C, 0x61A3}, //3116 #CJK UNIFIED IDEOGRAPH + {0x918D, 0x61A4}, //3117 #CJK UNIFIED IDEOGRAPH + {0x918E, 0x61A5}, //3118 #CJK UNIFIED IDEOGRAPH + {0x918F, 0x61A6}, //3119 #CJK UNIFIED IDEOGRAPH + {0x9190, 0x61AA}, //3120 #CJK UNIFIED IDEOGRAPH + {0x9191, 0x61AB}, //3121 #CJK UNIFIED IDEOGRAPH + {0x9192, 0x61AD}, //3122 #CJK UNIFIED IDEOGRAPH + {0x9193, 0x61AE}, //3123 #CJK UNIFIED IDEOGRAPH + {0x9194, 0x61AF}, //3124 #CJK UNIFIED IDEOGRAPH + {0x9195, 0x61B0}, //3125 #CJK UNIFIED IDEOGRAPH + {0x9196, 0x61B1}, //3126 #CJK UNIFIED IDEOGRAPH + {0x9197, 0x61B2}, //3127 #CJK UNIFIED IDEOGRAPH + {0x9198, 0x61B3}, //3128 #CJK UNIFIED IDEOGRAPH + {0x9199, 0x61B4}, //3129 #CJK UNIFIED IDEOGRAPH + {0x919A, 0x61B5}, //3130 #CJK UNIFIED IDEOGRAPH + {0x919B, 0x61B6}, //3131 #CJK UNIFIED IDEOGRAPH + {0x919C, 0x61B8}, //3132 #CJK UNIFIED IDEOGRAPH + {0x919D, 0x61B9}, //3133 #CJK UNIFIED IDEOGRAPH + {0x919E, 0x61BA}, //3134 #CJK UNIFIED IDEOGRAPH + {0x919F, 0x61BB}, //3135 #CJK UNIFIED IDEOGRAPH + {0x91A0, 0x61BC}, //3136 #CJK UNIFIED IDEOGRAPH + {0x91A1, 0x61BD}, //3137 #CJK UNIFIED IDEOGRAPH + {0x91A2, 0x61BF}, //3138 #CJK UNIFIED IDEOGRAPH + {0x91A3, 0x61C0}, //3139 #CJK UNIFIED IDEOGRAPH + {0x91A4, 0x61C1}, //3140 #CJK UNIFIED IDEOGRAPH + {0x91A5, 0x61C3}, //3141 #CJK UNIFIED IDEOGRAPH + {0x91A6, 0x61C4}, //3142 #CJK UNIFIED IDEOGRAPH + {0x91A7, 0x61C5}, //3143 #CJK UNIFIED IDEOGRAPH + {0x91A8, 0x61C6}, //3144 #CJK UNIFIED IDEOGRAPH + {0x91A9, 0x61C7}, //3145 #CJK UNIFIED IDEOGRAPH + {0x91AA, 0x61C9}, //3146 #CJK UNIFIED IDEOGRAPH + {0x91AB, 0x61CC}, //3147 #CJK UNIFIED IDEOGRAPH + {0x91AC, 0x61CD}, //3148 #CJK UNIFIED IDEOGRAPH + {0x91AD, 0x61CE}, //3149 #CJK UNIFIED IDEOGRAPH + {0x91AE, 0x61CF}, //3150 #CJK UNIFIED IDEOGRAPH + {0x91AF, 0x61D0}, //3151 #CJK UNIFIED IDEOGRAPH + {0x91B0, 0x61D3}, //3152 #CJK UNIFIED IDEOGRAPH + {0x91B1, 0x61D5}, //3153 #CJK UNIFIED IDEOGRAPH + {0x91B2, 0x61D6}, //3154 #CJK UNIFIED IDEOGRAPH + {0x91B3, 0x61D7}, //3155 #CJK UNIFIED IDEOGRAPH + {0x91B4, 0x61D8}, //3156 #CJK UNIFIED IDEOGRAPH + {0x91B5, 0x61D9}, //3157 #CJK UNIFIED IDEOGRAPH + {0x91B6, 0x61DA}, //3158 #CJK UNIFIED IDEOGRAPH + {0x91B7, 0x61DB}, //3159 #CJK UNIFIED IDEOGRAPH + {0x91B8, 0x61DC}, //3160 #CJK UNIFIED IDEOGRAPH + {0x91B9, 0x61DD}, //3161 #CJK UNIFIED IDEOGRAPH + {0x91BA, 0x61DE}, //3162 #CJK UNIFIED IDEOGRAPH + {0x91BB, 0x61DF}, //3163 #CJK UNIFIED IDEOGRAPH + {0x91BC, 0x61E0}, //3164 #CJK UNIFIED IDEOGRAPH + {0x91BD, 0x61E1}, //3165 #CJK UNIFIED IDEOGRAPH + {0x91BE, 0x61E2}, //3166 #CJK UNIFIED IDEOGRAPH + {0x91BF, 0x61E3}, //3167 #CJK UNIFIED IDEOGRAPH + {0x91C0, 0x61E4}, //3168 #CJK UNIFIED IDEOGRAPH + {0x91C1, 0x61E5}, //3169 #CJK UNIFIED IDEOGRAPH + {0x91C2, 0x61E7}, //3170 #CJK UNIFIED IDEOGRAPH + {0x91C3, 0x61E8}, //3171 #CJK UNIFIED IDEOGRAPH + {0x91C4, 0x61E9}, //3172 #CJK UNIFIED IDEOGRAPH + {0x91C5, 0x61EA}, //3173 #CJK UNIFIED IDEOGRAPH + {0x91C6, 0x61EB}, //3174 #CJK UNIFIED IDEOGRAPH + {0x91C7, 0x61EC}, //3175 #CJK UNIFIED IDEOGRAPH + {0x91C8, 0x61ED}, //3176 #CJK UNIFIED IDEOGRAPH + {0x91C9, 0x61EE}, //3177 #CJK UNIFIED IDEOGRAPH + {0x91CA, 0x61EF}, //3178 #CJK UNIFIED IDEOGRAPH + {0x91CB, 0x61F0}, //3179 #CJK UNIFIED IDEOGRAPH + {0x91CC, 0x61F1}, //3180 #CJK UNIFIED IDEOGRAPH + {0x91CD, 0x61F2}, //3181 #CJK UNIFIED IDEOGRAPH + {0x91CE, 0x61F3}, //3182 #CJK UNIFIED IDEOGRAPH + {0x91CF, 0x61F4}, //3183 #CJK UNIFIED IDEOGRAPH + {0x91D0, 0x61F6}, //3184 #CJK UNIFIED IDEOGRAPH + {0x91D1, 0x61F7}, //3185 #CJK UNIFIED IDEOGRAPH + {0x91D2, 0x61F8}, //3186 #CJK UNIFIED IDEOGRAPH + {0x91D3, 0x61F9}, //3187 #CJK UNIFIED IDEOGRAPH + {0x91D4, 0x61FA}, //3188 #CJK UNIFIED IDEOGRAPH + {0x91D5, 0x61FB}, //3189 #CJK UNIFIED IDEOGRAPH + {0x91D6, 0x61FC}, //3190 #CJK UNIFIED IDEOGRAPH + {0x91D7, 0x61FD}, //3191 #CJK UNIFIED IDEOGRAPH + {0x91D8, 0x61FE}, //3192 #CJK UNIFIED IDEOGRAPH + {0x91D9, 0x6200}, //3193 #CJK UNIFIED IDEOGRAPH + {0x91DA, 0x6201}, //3194 #CJK UNIFIED IDEOGRAPH + {0x91DB, 0x6202}, //3195 #CJK UNIFIED IDEOGRAPH + {0x91DC, 0x6203}, //3196 #CJK UNIFIED IDEOGRAPH + {0x91DD, 0x6204}, //3197 #CJK UNIFIED IDEOGRAPH + {0x91DE, 0x6205}, //3198 #CJK UNIFIED IDEOGRAPH + {0x91DF, 0x6207}, //3199 #CJK UNIFIED IDEOGRAPH + {0x91E0, 0x6209}, //3200 #CJK UNIFIED IDEOGRAPH + {0x91E1, 0x6213}, //3201 #CJK UNIFIED IDEOGRAPH + {0x91E2, 0x6214}, //3202 #CJK UNIFIED IDEOGRAPH + {0x91E3, 0x6219}, //3203 #CJK UNIFIED IDEOGRAPH + {0x91E4, 0x621C}, //3204 #CJK UNIFIED IDEOGRAPH + {0x91E5, 0x621D}, //3205 #CJK UNIFIED IDEOGRAPH + {0x91E6, 0x621E}, //3206 #CJK UNIFIED IDEOGRAPH + {0x91E7, 0x6220}, //3207 #CJK UNIFIED IDEOGRAPH + {0x91E8, 0x6223}, //3208 #CJK UNIFIED IDEOGRAPH + {0x91E9, 0x6226}, //3209 #CJK UNIFIED IDEOGRAPH + {0x91EA, 0x6227}, //3210 #CJK UNIFIED IDEOGRAPH + {0x91EB, 0x6228}, //3211 #CJK UNIFIED IDEOGRAPH + {0x91EC, 0x6229}, //3212 #CJK UNIFIED IDEOGRAPH + {0x91ED, 0x622B}, //3213 #CJK UNIFIED IDEOGRAPH + {0x91EE, 0x622D}, //3214 #CJK UNIFIED IDEOGRAPH + {0x91EF, 0x622F}, //3215 #CJK UNIFIED IDEOGRAPH + {0x91F0, 0x6230}, //3216 #CJK UNIFIED IDEOGRAPH + {0x91F1, 0x6231}, //3217 #CJK UNIFIED IDEOGRAPH + {0x91F2, 0x6232}, //3218 #CJK UNIFIED IDEOGRAPH + {0x91F3, 0x6235}, //3219 #CJK UNIFIED IDEOGRAPH + {0x91F4, 0x6236}, //3220 #CJK UNIFIED IDEOGRAPH + {0x91F5, 0x6238}, //3221 #CJK UNIFIED IDEOGRAPH + {0x91F6, 0x6239}, //3222 #CJK UNIFIED IDEOGRAPH + {0x91F7, 0x623A}, //3223 #CJK UNIFIED IDEOGRAPH + {0x91F8, 0x623B}, //3224 #CJK UNIFIED IDEOGRAPH + {0x91F9, 0x623C}, //3225 #CJK UNIFIED IDEOGRAPH + {0x91FA, 0x6242}, //3226 #CJK UNIFIED IDEOGRAPH + {0x91FB, 0x6244}, //3227 #CJK UNIFIED IDEOGRAPH + {0x91FC, 0x6245}, //3228 #CJK UNIFIED IDEOGRAPH + {0x91FD, 0x6246}, //3229 #CJK UNIFIED IDEOGRAPH + {0x91FE, 0x624A}, //3230 #CJK UNIFIED IDEOGRAPH + {0x9240, 0x624F}, //3231 #CJK UNIFIED IDEOGRAPH + {0x9241, 0x6250}, //3232 #CJK UNIFIED IDEOGRAPH + {0x9242, 0x6255}, //3233 #CJK UNIFIED IDEOGRAPH + {0x9243, 0x6256}, //3234 #CJK UNIFIED IDEOGRAPH + {0x9244, 0x6257}, //3235 #CJK UNIFIED IDEOGRAPH + {0x9245, 0x6259}, //3236 #CJK UNIFIED IDEOGRAPH + {0x9246, 0x625A}, //3237 #CJK UNIFIED IDEOGRAPH + {0x9247, 0x625C}, //3238 #CJK UNIFIED IDEOGRAPH + {0x9248, 0x625D}, //3239 #CJK UNIFIED IDEOGRAPH + {0x9249, 0x625E}, //3240 #CJK UNIFIED IDEOGRAPH + {0x924A, 0x625F}, //3241 #CJK UNIFIED IDEOGRAPH + {0x924B, 0x6260}, //3242 #CJK UNIFIED IDEOGRAPH + {0x924C, 0x6261}, //3243 #CJK UNIFIED IDEOGRAPH + {0x924D, 0x6262}, //3244 #CJK UNIFIED IDEOGRAPH + {0x924E, 0x6264}, //3245 #CJK UNIFIED IDEOGRAPH + {0x924F, 0x6265}, //3246 #CJK UNIFIED IDEOGRAPH + {0x9250, 0x6268}, //3247 #CJK UNIFIED IDEOGRAPH + {0x9251, 0x6271}, //3248 #CJK UNIFIED IDEOGRAPH + {0x9252, 0x6272}, //3249 #CJK UNIFIED IDEOGRAPH + {0x9253, 0x6274}, //3250 #CJK UNIFIED IDEOGRAPH + {0x9254, 0x6275}, //3251 #CJK UNIFIED IDEOGRAPH + {0x9255, 0x6277}, //3252 #CJK UNIFIED IDEOGRAPH + {0x9256, 0x6278}, //3253 #CJK UNIFIED IDEOGRAPH + {0x9257, 0x627A}, //3254 #CJK UNIFIED IDEOGRAPH + {0x9258, 0x627B}, //3255 #CJK UNIFIED IDEOGRAPH + {0x9259, 0x627D}, //3256 #CJK UNIFIED IDEOGRAPH + {0x925A, 0x6281}, //3257 #CJK UNIFIED IDEOGRAPH + {0x925B, 0x6282}, //3258 #CJK UNIFIED IDEOGRAPH + {0x925C, 0x6283}, //3259 #CJK UNIFIED IDEOGRAPH + {0x925D, 0x6285}, //3260 #CJK UNIFIED IDEOGRAPH + {0x925E, 0x6286}, //3261 #CJK UNIFIED IDEOGRAPH + {0x925F, 0x6287}, //3262 #CJK UNIFIED IDEOGRAPH + {0x9260, 0x6288}, //3263 #CJK UNIFIED IDEOGRAPH + {0x9261, 0x628B}, //3264 #CJK UNIFIED IDEOGRAPH + {0x9262, 0x628C}, //3265 #CJK UNIFIED IDEOGRAPH + {0x9263, 0x628D}, //3266 #CJK UNIFIED IDEOGRAPH + {0x9264, 0x628E}, //3267 #CJK UNIFIED IDEOGRAPH + {0x9265, 0x628F}, //3268 #CJK UNIFIED IDEOGRAPH + {0x9266, 0x6290}, //3269 #CJK UNIFIED IDEOGRAPH + {0x9267, 0x6294}, //3270 #CJK UNIFIED IDEOGRAPH + {0x9268, 0x6299}, //3271 #CJK UNIFIED IDEOGRAPH + {0x9269, 0x629C}, //3272 #CJK UNIFIED IDEOGRAPH + {0x926A, 0x629D}, //3273 #CJK UNIFIED IDEOGRAPH + {0x926B, 0x629E}, //3274 #CJK UNIFIED IDEOGRAPH + {0x926C, 0x62A3}, //3275 #CJK UNIFIED IDEOGRAPH + {0x926D, 0x62A6}, //3276 #CJK UNIFIED IDEOGRAPH + {0x926E, 0x62A7}, //3277 #CJK UNIFIED IDEOGRAPH + {0x926F, 0x62A9}, //3278 #CJK UNIFIED IDEOGRAPH + {0x9270, 0x62AA}, //3279 #CJK UNIFIED IDEOGRAPH + {0x9271, 0x62AD}, //3280 #CJK UNIFIED IDEOGRAPH + {0x9272, 0x62AE}, //3281 #CJK UNIFIED IDEOGRAPH + {0x9273, 0x62AF}, //3282 #CJK UNIFIED IDEOGRAPH + {0x9274, 0x62B0}, //3283 #CJK UNIFIED IDEOGRAPH + {0x9275, 0x62B2}, //3284 #CJK UNIFIED IDEOGRAPH + {0x9276, 0x62B3}, //3285 #CJK UNIFIED IDEOGRAPH + {0x9277, 0x62B4}, //3286 #CJK UNIFIED IDEOGRAPH + {0x9278, 0x62B6}, //3287 #CJK UNIFIED IDEOGRAPH + {0x9279, 0x62B7}, //3288 #CJK UNIFIED IDEOGRAPH + {0x927A, 0x62B8}, //3289 #CJK UNIFIED IDEOGRAPH + {0x927B, 0x62BA}, //3290 #CJK UNIFIED IDEOGRAPH + {0x927C, 0x62BE}, //3291 #CJK UNIFIED IDEOGRAPH + {0x927D, 0x62C0}, //3292 #CJK UNIFIED IDEOGRAPH + {0x927E, 0x62C1}, //3293 #CJK UNIFIED IDEOGRAPH + {0x9280, 0x62C3}, //3294 #CJK UNIFIED IDEOGRAPH + {0x9281, 0x62CB}, //3295 #CJK UNIFIED IDEOGRAPH + {0x9282, 0x62CF}, //3296 #CJK UNIFIED IDEOGRAPH + {0x9283, 0x62D1}, //3297 #CJK UNIFIED IDEOGRAPH + {0x9284, 0x62D5}, //3298 #CJK UNIFIED IDEOGRAPH + {0x9285, 0x62DD}, //3299 #CJK UNIFIED IDEOGRAPH + {0x9286, 0x62DE}, //3300 #CJK UNIFIED IDEOGRAPH + {0x9287, 0x62E0}, //3301 #CJK UNIFIED IDEOGRAPH + {0x9288, 0x62E1}, //3302 #CJK UNIFIED IDEOGRAPH + {0x9289, 0x62E4}, //3303 #CJK UNIFIED IDEOGRAPH + {0x928A, 0x62EA}, //3304 #CJK UNIFIED IDEOGRAPH + {0x928B, 0x62EB}, //3305 #CJK UNIFIED IDEOGRAPH + {0x928C, 0x62F0}, //3306 #CJK UNIFIED IDEOGRAPH + {0x928D, 0x62F2}, //3307 #CJK UNIFIED IDEOGRAPH + {0x928E, 0x62F5}, //3308 #CJK UNIFIED IDEOGRAPH + {0x928F, 0x62F8}, //3309 #CJK UNIFIED IDEOGRAPH + {0x9290, 0x62F9}, //3310 #CJK UNIFIED IDEOGRAPH + {0x9291, 0x62FA}, //3311 #CJK UNIFIED IDEOGRAPH + {0x9292, 0x62FB}, //3312 #CJK UNIFIED IDEOGRAPH + {0x9293, 0x6300}, //3313 #CJK UNIFIED IDEOGRAPH + {0x9294, 0x6303}, //3314 #CJK UNIFIED IDEOGRAPH + {0x9295, 0x6304}, //3315 #CJK UNIFIED IDEOGRAPH + {0x9296, 0x6305}, //3316 #CJK UNIFIED IDEOGRAPH + {0x9297, 0x6306}, //3317 #CJK UNIFIED IDEOGRAPH + {0x9298, 0x630A}, //3318 #CJK UNIFIED IDEOGRAPH + {0x9299, 0x630B}, //3319 #CJK UNIFIED IDEOGRAPH + {0x929A, 0x630C}, //3320 #CJK UNIFIED IDEOGRAPH + {0x929B, 0x630D}, //3321 #CJK UNIFIED IDEOGRAPH + {0x929C, 0x630F}, //3322 #CJK UNIFIED IDEOGRAPH + {0x929D, 0x6310}, //3323 #CJK UNIFIED IDEOGRAPH + {0x929E, 0x6312}, //3324 #CJK UNIFIED IDEOGRAPH + {0x929F, 0x6313}, //3325 #CJK UNIFIED IDEOGRAPH + {0x92A0, 0x6314}, //3326 #CJK UNIFIED IDEOGRAPH + {0x92A1, 0x6315}, //3327 #CJK UNIFIED IDEOGRAPH + {0x92A2, 0x6317}, //3328 #CJK UNIFIED IDEOGRAPH + {0x92A3, 0x6318}, //3329 #CJK UNIFIED IDEOGRAPH + {0x92A4, 0x6319}, //3330 #CJK UNIFIED IDEOGRAPH + {0x92A5, 0x631C}, //3331 #CJK UNIFIED IDEOGRAPH + {0x92A6, 0x6326}, //3332 #CJK UNIFIED IDEOGRAPH + {0x92A7, 0x6327}, //3333 #CJK UNIFIED IDEOGRAPH + {0x92A8, 0x6329}, //3334 #CJK UNIFIED IDEOGRAPH + {0x92A9, 0x632C}, //3335 #CJK UNIFIED IDEOGRAPH + {0x92AA, 0x632D}, //3336 #CJK UNIFIED IDEOGRAPH + {0x92AB, 0x632E}, //3337 #CJK UNIFIED IDEOGRAPH + {0x92AC, 0x6330}, //3338 #CJK UNIFIED IDEOGRAPH + {0x92AD, 0x6331}, //3339 #CJK UNIFIED IDEOGRAPH + {0x92AE, 0x6333}, //3340 #CJK UNIFIED IDEOGRAPH + {0x92AF, 0x6334}, //3341 #CJK UNIFIED IDEOGRAPH + {0x92B0, 0x6335}, //3342 #CJK UNIFIED IDEOGRAPH + {0x92B1, 0x6336}, //3343 #CJK UNIFIED IDEOGRAPH + {0x92B2, 0x6337}, //3344 #CJK UNIFIED IDEOGRAPH + {0x92B3, 0x6338}, //3345 #CJK UNIFIED IDEOGRAPH + {0x92B4, 0x633B}, //3346 #CJK UNIFIED IDEOGRAPH + {0x92B5, 0x633C}, //3347 #CJK UNIFIED IDEOGRAPH + {0x92B6, 0x633E}, //3348 #CJK UNIFIED IDEOGRAPH + {0x92B7, 0x633F}, //3349 #CJK UNIFIED IDEOGRAPH + {0x92B8, 0x6340}, //3350 #CJK UNIFIED IDEOGRAPH + {0x92B9, 0x6341}, //3351 #CJK UNIFIED IDEOGRAPH + {0x92BA, 0x6344}, //3352 #CJK UNIFIED IDEOGRAPH + {0x92BB, 0x6347}, //3353 #CJK UNIFIED IDEOGRAPH + {0x92BC, 0x6348}, //3354 #CJK UNIFIED IDEOGRAPH + {0x92BD, 0x634A}, //3355 #CJK UNIFIED IDEOGRAPH + {0x92BE, 0x6351}, //3356 #CJK UNIFIED IDEOGRAPH + {0x92BF, 0x6352}, //3357 #CJK UNIFIED IDEOGRAPH + {0x92C0, 0x6353}, //3358 #CJK UNIFIED IDEOGRAPH + {0x92C1, 0x6354}, //3359 #CJK UNIFIED IDEOGRAPH + {0x92C2, 0x6356}, //3360 #CJK UNIFIED IDEOGRAPH + {0x92C3, 0x6357}, //3361 #CJK UNIFIED IDEOGRAPH + {0x92C4, 0x6358}, //3362 #CJK UNIFIED IDEOGRAPH + {0x92C5, 0x6359}, //3363 #CJK UNIFIED IDEOGRAPH + {0x92C6, 0x635A}, //3364 #CJK UNIFIED IDEOGRAPH + {0x92C7, 0x635B}, //3365 #CJK UNIFIED IDEOGRAPH + {0x92C8, 0x635C}, //3366 #CJK UNIFIED IDEOGRAPH + {0x92C9, 0x635D}, //3367 #CJK UNIFIED IDEOGRAPH + {0x92CA, 0x6360}, //3368 #CJK UNIFIED IDEOGRAPH + {0x92CB, 0x6364}, //3369 #CJK UNIFIED IDEOGRAPH + {0x92CC, 0x6365}, //3370 #CJK UNIFIED IDEOGRAPH + {0x92CD, 0x6366}, //3371 #CJK UNIFIED IDEOGRAPH + {0x92CE, 0x6368}, //3372 #CJK UNIFIED IDEOGRAPH + {0x92CF, 0x636A}, //3373 #CJK UNIFIED IDEOGRAPH + {0x92D0, 0x636B}, //3374 #CJK UNIFIED IDEOGRAPH + {0x92D1, 0x636C}, //3375 #CJK UNIFIED IDEOGRAPH + {0x92D2, 0x636F}, //3376 #CJK UNIFIED IDEOGRAPH + {0x92D3, 0x6370}, //3377 #CJK UNIFIED IDEOGRAPH + {0x92D4, 0x6372}, //3378 #CJK UNIFIED IDEOGRAPH + {0x92D5, 0x6373}, //3379 #CJK UNIFIED IDEOGRAPH + {0x92D6, 0x6374}, //3380 #CJK UNIFIED IDEOGRAPH + {0x92D7, 0x6375}, //3381 #CJK UNIFIED IDEOGRAPH + {0x92D8, 0x6378}, //3382 #CJK UNIFIED IDEOGRAPH + {0x92D9, 0x6379}, //3383 #CJK UNIFIED IDEOGRAPH + {0x92DA, 0x637C}, //3384 #CJK UNIFIED IDEOGRAPH + {0x92DB, 0x637D}, //3385 #CJK UNIFIED IDEOGRAPH + {0x92DC, 0x637E}, //3386 #CJK UNIFIED IDEOGRAPH + {0x92DD, 0x637F}, //3387 #CJK UNIFIED IDEOGRAPH + {0x92DE, 0x6381}, //3388 #CJK UNIFIED IDEOGRAPH + {0x92DF, 0x6383}, //3389 #CJK UNIFIED IDEOGRAPH + {0x92E0, 0x6384}, //3390 #CJK UNIFIED IDEOGRAPH + {0x92E1, 0x6385}, //3391 #CJK UNIFIED IDEOGRAPH + {0x92E2, 0x6386}, //3392 #CJK UNIFIED IDEOGRAPH + {0x92E3, 0x638B}, //3393 #CJK UNIFIED IDEOGRAPH + {0x92E4, 0x638D}, //3394 #CJK UNIFIED IDEOGRAPH + {0x92E5, 0x6391}, //3395 #CJK UNIFIED IDEOGRAPH + {0x92E6, 0x6393}, //3396 #CJK UNIFIED IDEOGRAPH + {0x92E7, 0x6394}, //3397 #CJK UNIFIED IDEOGRAPH + {0x92E8, 0x6395}, //3398 #CJK UNIFIED IDEOGRAPH + {0x92E9, 0x6397}, //3399 #CJK UNIFIED IDEOGRAPH + {0x92EA, 0x6399}, //3400 #CJK UNIFIED IDEOGRAPH + {0x92EB, 0x639A}, //3401 #CJK UNIFIED IDEOGRAPH + {0x92EC, 0x639B}, //3402 #CJK UNIFIED IDEOGRAPH + {0x92ED, 0x639C}, //3403 #CJK UNIFIED IDEOGRAPH + {0x92EE, 0x639D}, //3404 #CJK UNIFIED IDEOGRAPH + {0x92EF, 0x639E}, //3405 #CJK UNIFIED IDEOGRAPH + {0x92F0, 0x639F}, //3406 #CJK UNIFIED IDEOGRAPH + {0x92F1, 0x63A1}, //3407 #CJK UNIFIED IDEOGRAPH + {0x92F2, 0x63A4}, //3408 #CJK UNIFIED IDEOGRAPH + {0x92F3, 0x63A6}, //3409 #CJK UNIFIED IDEOGRAPH + {0x92F4, 0x63AB}, //3410 #CJK UNIFIED IDEOGRAPH + {0x92F5, 0x63AF}, //3411 #CJK UNIFIED IDEOGRAPH + {0x92F6, 0x63B1}, //3412 #CJK UNIFIED IDEOGRAPH + {0x92F7, 0x63B2}, //3413 #CJK UNIFIED IDEOGRAPH + {0x92F8, 0x63B5}, //3414 #CJK UNIFIED IDEOGRAPH + {0x92F9, 0x63B6}, //3415 #CJK UNIFIED IDEOGRAPH + {0x92FA, 0x63B9}, //3416 #CJK UNIFIED IDEOGRAPH + {0x92FB, 0x63BB}, //3417 #CJK UNIFIED IDEOGRAPH + {0x92FC, 0x63BD}, //3418 #CJK UNIFIED IDEOGRAPH + {0x92FD, 0x63BF}, //3419 #CJK UNIFIED IDEOGRAPH + {0x92FE, 0x63C0}, //3420 #CJK UNIFIED IDEOGRAPH + {0x9340, 0x63C1}, //3421 #CJK UNIFIED IDEOGRAPH + {0x9341, 0x63C2}, //3422 #CJK UNIFIED IDEOGRAPH + {0x9342, 0x63C3}, //3423 #CJK UNIFIED IDEOGRAPH + {0x9343, 0x63C5}, //3424 #CJK UNIFIED IDEOGRAPH + {0x9344, 0x63C7}, //3425 #CJK UNIFIED IDEOGRAPH + {0x9345, 0x63C8}, //3426 #CJK UNIFIED IDEOGRAPH + {0x9346, 0x63CA}, //3427 #CJK UNIFIED IDEOGRAPH + {0x9347, 0x63CB}, //3428 #CJK UNIFIED IDEOGRAPH + {0x9348, 0x63CC}, //3429 #CJK UNIFIED IDEOGRAPH + {0x9349, 0x63D1}, //3430 #CJK UNIFIED IDEOGRAPH + {0x934A, 0x63D3}, //3431 #CJK UNIFIED IDEOGRAPH + {0x934B, 0x63D4}, //3432 #CJK UNIFIED IDEOGRAPH + {0x934C, 0x63D5}, //3433 #CJK UNIFIED IDEOGRAPH + {0x934D, 0x63D7}, //3434 #CJK UNIFIED IDEOGRAPH + {0x934E, 0x63D8}, //3435 #CJK UNIFIED IDEOGRAPH + {0x934F, 0x63D9}, //3436 #CJK UNIFIED IDEOGRAPH + {0x9350, 0x63DA}, //3437 #CJK UNIFIED IDEOGRAPH + {0x9351, 0x63DB}, //3438 #CJK UNIFIED IDEOGRAPH + {0x9352, 0x63DC}, //3439 #CJK UNIFIED IDEOGRAPH + {0x9353, 0x63DD}, //3440 #CJK UNIFIED IDEOGRAPH + {0x9354, 0x63DF}, //3441 #CJK UNIFIED IDEOGRAPH + {0x9355, 0x63E2}, //3442 #CJK UNIFIED IDEOGRAPH + {0x9356, 0x63E4}, //3443 #CJK UNIFIED IDEOGRAPH + {0x9357, 0x63E5}, //3444 #CJK UNIFIED IDEOGRAPH + {0x9358, 0x63E6}, //3445 #CJK UNIFIED IDEOGRAPH + {0x9359, 0x63E7}, //3446 #CJK UNIFIED IDEOGRAPH + {0x935A, 0x63E8}, //3447 #CJK UNIFIED IDEOGRAPH + {0x935B, 0x63EB}, //3448 #CJK UNIFIED IDEOGRAPH + {0x935C, 0x63EC}, //3449 #CJK UNIFIED IDEOGRAPH + {0x935D, 0x63EE}, //3450 #CJK UNIFIED IDEOGRAPH + {0x935E, 0x63EF}, //3451 #CJK UNIFIED IDEOGRAPH + {0x935F, 0x63F0}, //3452 #CJK UNIFIED IDEOGRAPH + {0x9360, 0x63F1}, //3453 #CJK UNIFIED IDEOGRAPH + {0x9361, 0x63F3}, //3454 #CJK UNIFIED IDEOGRAPH + {0x9362, 0x63F5}, //3455 #CJK UNIFIED IDEOGRAPH + {0x9363, 0x63F7}, //3456 #CJK UNIFIED IDEOGRAPH + {0x9364, 0x63F9}, //3457 #CJK UNIFIED IDEOGRAPH + {0x9365, 0x63FA}, //3458 #CJK UNIFIED IDEOGRAPH + {0x9366, 0x63FB}, //3459 #CJK UNIFIED IDEOGRAPH + {0x9367, 0x63FC}, //3460 #CJK UNIFIED IDEOGRAPH + {0x9368, 0x63FE}, //3461 #CJK UNIFIED IDEOGRAPH + {0x9369, 0x6403}, //3462 #CJK UNIFIED IDEOGRAPH + {0x936A, 0x6404}, //3463 #CJK UNIFIED IDEOGRAPH + {0x936B, 0x6406}, //3464 #CJK UNIFIED IDEOGRAPH + {0x936C, 0x6407}, //3465 #CJK UNIFIED IDEOGRAPH + {0x936D, 0x6408}, //3466 #CJK UNIFIED IDEOGRAPH + {0x936E, 0x6409}, //3467 #CJK UNIFIED IDEOGRAPH + {0x936F, 0x640A}, //3468 #CJK UNIFIED IDEOGRAPH + {0x9370, 0x640D}, //3469 #CJK UNIFIED IDEOGRAPH + {0x9371, 0x640E}, //3470 #CJK UNIFIED IDEOGRAPH + {0x9372, 0x6411}, //3471 #CJK UNIFIED IDEOGRAPH + {0x9373, 0x6412}, //3472 #CJK UNIFIED IDEOGRAPH + {0x9374, 0x6415}, //3473 #CJK UNIFIED IDEOGRAPH + {0x9375, 0x6416}, //3474 #CJK UNIFIED IDEOGRAPH + {0x9376, 0x6417}, //3475 #CJK UNIFIED IDEOGRAPH + {0x9377, 0x6418}, //3476 #CJK UNIFIED IDEOGRAPH + {0x9378, 0x6419}, //3477 #CJK UNIFIED IDEOGRAPH + {0x9379, 0x641A}, //3478 #CJK UNIFIED IDEOGRAPH + {0x937A, 0x641D}, //3479 #CJK UNIFIED IDEOGRAPH + {0x937B, 0x641F}, //3480 #CJK UNIFIED IDEOGRAPH + {0x937C, 0x6422}, //3481 #CJK UNIFIED IDEOGRAPH + {0x937D, 0x6423}, //3482 #CJK UNIFIED IDEOGRAPH + {0x937E, 0x6424}, //3483 #CJK UNIFIED IDEOGRAPH + {0x9380, 0x6425}, //3484 #CJK UNIFIED IDEOGRAPH + {0x9381, 0x6427}, //3485 #CJK UNIFIED IDEOGRAPH + {0x9382, 0x6428}, //3486 #CJK UNIFIED IDEOGRAPH + {0x9383, 0x6429}, //3487 #CJK UNIFIED IDEOGRAPH + {0x9384, 0x642B}, //3488 #CJK UNIFIED IDEOGRAPH + {0x9385, 0x642E}, //3489 #CJK UNIFIED IDEOGRAPH + {0x9386, 0x642F}, //3490 #CJK UNIFIED IDEOGRAPH + {0x9387, 0x6430}, //3491 #CJK UNIFIED IDEOGRAPH + {0x9388, 0x6431}, //3492 #CJK UNIFIED IDEOGRAPH + {0x9389, 0x6432}, //3493 #CJK UNIFIED IDEOGRAPH + {0x938A, 0x6433}, //3494 #CJK UNIFIED IDEOGRAPH + {0x938B, 0x6435}, //3495 #CJK UNIFIED IDEOGRAPH + {0x938C, 0x6436}, //3496 #CJK UNIFIED IDEOGRAPH + {0x938D, 0x6437}, //3497 #CJK UNIFIED IDEOGRAPH + {0x938E, 0x6438}, //3498 #CJK UNIFIED IDEOGRAPH + {0x938F, 0x6439}, //3499 #CJK UNIFIED IDEOGRAPH + {0x9390, 0x643B}, //3500 #CJK UNIFIED IDEOGRAPH + {0x9391, 0x643C}, //3501 #CJK UNIFIED IDEOGRAPH + {0x9392, 0x643E}, //3502 #CJK UNIFIED IDEOGRAPH + {0x9393, 0x6440}, //3503 #CJK UNIFIED IDEOGRAPH + {0x9394, 0x6442}, //3504 #CJK UNIFIED IDEOGRAPH + {0x9395, 0x6443}, //3505 #CJK UNIFIED IDEOGRAPH + {0x9396, 0x6449}, //3506 #CJK UNIFIED IDEOGRAPH + {0x9397, 0x644B}, //3507 #CJK UNIFIED IDEOGRAPH + {0x9398, 0x644C}, //3508 #CJK UNIFIED IDEOGRAPH + {0x9399, 0x644D}, //3509 #CJK UNIFIED IDEOGRAPH + {0x939A, 0x644E}, //3510 #CJK UNIFIED IDEOGRAPH + {0x939B, 0x644F}, //3511 #CJK UNIFIED IDEOGRAPH + {0x939C, 0x6450}, //3512 #CJK UNIFIED IDEOGRAPH + {0x939D, 0x6451}, //3513 #CJK UNIFIED IDEOGRAPH + {0x939E, 0x6453}, //3514 #CJK UNIFIED IDEOGRAPH + {0x939F, 0x6455}, //3515 #CJK UNIFIED IDEOGRAPH + {0x93A0, 0x6456}, //3516 #CJK UNIFIED IDEOGRAPH + {0x93A1, 0x6457}, //3517 #CJK UNIFIED IDEOGRAPH + {0x93A2, 0x6459}, //3518 #CJK UNIFIED IDEOGRAPH + {0x93A3, 0x645A}, //3519 #CJK UNIFIED IDEOGRAPH + {0x93A4, 0x645B}, //3520 #CJK UNIFIED IDEOGRAPH + {0x93A5, 0x645C}, //3521 #CJK UNIFIED IDEOGRAPH + {0x93A6, 0x645D}, //3522 #CJK UNIFIED IDEOGRAPH + {0x93A7, 0x645F}, //3523 #CJK UNIFIED IDEOGRAPH + {0x93A8, 0x6460}, //3524 #CJK UNIFIED IDEOGRAPH + {0x93A9, 0x6461}, //3525 #CJK UNIFIED IDEOGRAPH + {0x93AA, 0x6462}, //3526 #CJK UNIFIED IDEOGRAPH + {0x93AB, 0x6463}, //3527 #CJK UNIFIED IDEOGRAPH + {0x93AC, 0x6464}, //3528 #CJK UNIFIED IDEOGRAPH + {0x93AD, 0x6465}, //3529 #CJK UNIFIED IDEOGRAPH + {0x93AE, 0x6466}, //3530 #CJK UNIFIED IDEOGRAPH + {0x93AF, 0x6468}, //3531 #CJK UNIFIED IDEOGRAPH + {0x93B0, 0x646A}, //3532 #CJK UNIFIED IDEOGRAPH + {0x93B1, 0x646B}, //3533 #CJK UNIFIED IDEOGRAPH + {0x93B2, 0x646C}, //3534 #CJK UNIFIED IDEOGRAPH + {0x93B3, 0x646E}, //3535 #CJK UNIFIED IDEOGRAPH + {0x93B4, 0x646F}, //3536 #CJK UNIFIED IDEOGRAPH + {0x93B5, 0x6470}, //3537 #CJK UNIFIED IDEOGRAPH + {0x93B6, 0x6471}, //3538 #CJK UNIFIED IDEOGRAPH + {0x93B7, 0x6472}, //3539 #CJK UNIFIED IDEOGRAPH + {0x93B8, 0x6473}, //3540 #CJK UNIFIED IDEOGRAPH + {0x93B9, 0x6474}, //3541 #CJK UNIFIED IDEOGRAPH + {0x93BA, 0x6475}, //3542 #CJK UNIFIED IDEOGRAPH + {0x93BB, 0x6476}, //3543 #CJK UNIFIED IDEOGRAPH + {0x93BC, 0x6477}, //3544 #CJK UNIFIED IDEOGRAPH + {0x93BD, 0x647B}, //3545 #CJK UNIFIED IDEOGRAPH + {0x93BE, 0x647C}, //3546 #CJK UNIFIED IDEOGRAPH + {0x93BF, 0x647D}, //3547 #CJK UNIFIED IDEOGRAPH + {0x93C0, 0x647E}, //3548 #CJK UNIFIED IDEOGRAPH + {0x93C1, 0x647F}, //3549 #CJK UNIFIED IDEOGRAPH + {0x93C2, 0x6480}, //3550 #CJK UNIFIED IDEOGRAPH + {0x93C3, 0x6481}, //3551 #CJK UNIFIED IDEOGRAPH + {0x93C4, 0x6483}, //3552 #CJK UNIFIED IDEOGRAPH + {0x93C5, 0x6486}, //3553 #CJK UNIFIED IDEOGRAPH + {0x93C6, 0x6488}, //3554 #CJK UNIFIED IDEOGRAPH + {0x93C7, 0x6489}, //3555 #CJK UNIFIED IDEOGRAPH + {0x93C8, 0x648A}, //3556 #CJK UNIFIED IDEOGRAPH + {0x93C9, 0x648B}, //3557 #CJK UNIFIED IDEOGRAPH + {0x93CA, 0x648C}, //3558 #CJK UNIFIED IDEOGRAPH + {0x93CB, 0x648D}, //3559 #CJK UNIFIED IDEOGRAPH + {0x93CC, 0x648E}, //3560 #CJK UNIFIED IDEOGRAPH + {0x93CD, 0x648F}, //3561 #CJK UNIFIED IDEOGRAPH + {0x93CE, 0x6490}, //3562 #CJK UNIFIED IDEOGRAPH + {0x93CF, 0x6493}, //3563 #CJK UNIFIED IDEOGRAPH + {0x93D0, 0x6494}, //3564 #CJK UNIFIED IDEOGRAPH + {0x93D1, 0x6497}, //3565 #CJK UNIFIED IDEOGRAPH + {0x93D2, 0x6498}, //3566 #CJK UNIFIED IDEOGRAPH + {0x93D3, 0x649A}, //3567 #CJK UNIFIED IDEOGRAPH + {0x93D4, 0x649B}, //3568 #CJK UNIFIED IDEOGRAPH + {0x93D5, 0x649C}, //3569 #CJK UNIFIED IDEOGRAPH + {0x93D6, 0x649D}, //3570 #CJK UNIFIED IDEOGRAPH + {0x93D7, 0x649F}, //3571 #CJK UNIFIED IDEOGRAPH + {0x93D8, 0x64A0}, //3572 #CJK UNIFIED IDEOGRAPH + {0x93D9, 0x64A1}, //3573 #CJK UNIFIED IDEOGRAPH + {0x93DA, 0x64A2}, //3574 #CJK UNIFIED IDEOGRAPH + {0x93DB, 0x64A3}, //3575 #CJK UNIFIED IDEOGRAPH + {0x93DC, 0x64A5}, //3576 #CJK UNIFIED IDEOGRAPH + {0x93DD, 0x64A6}, //3577 #CJK UNIFIED IDEOGRAPH + {0x93DE, 0x64A7}, //3578 #CJK UNIFIED IDEOGRAPH + {0x93DF, 0x64A8}, //3579 #CJK UNIFIED IDEOGRAPH + {0x93E0, 0x64AA}, //3580 #CJK UNIFIED IDEOGRAPH + {0x93E1, 0x64AB}, //3581 #CJK UNIFIED IDEOGRAPH + {0x93E2, 0x64AF}, //3582 #CJK UNIFIED IDEOGRAPH + {0x93E3, 0x64B1}, //3583 #CJK UNIFIED IDEOGRAPH + {0x93E4, 0x64B2}, //3584 #CJK UNIFIED IDEOGRAPH + {0x93E5, 0x64B3}, //3585 #CJK UNIFIED IDEOGRAPH + {0x93E6, 0x64B4}, //3586 #CJK UNIFIED IDEOGRAPH + {0x93E7, 0x64B6}, //3587 #CJK UNIFIED IDEOGRAPH + {0x93E8, 0x64B9}, //3588 #CJK UNIFIED IDEOGRAPH + {0x93E9, 0x64BB}, //3589 #CJK UNIFIED IDEOGRAPH + {0x93EA, 0x64BD}, //3590 #CJK UNIFIED IDEOGRAPH + {0x93EB, 0x64BE}, //3591 #CJK UNIFIED IDEOGRAPH + {0x93EC, 0x64BF}, //3592 #CJK UNIFIED IDEOGRAPH + {0x93ED, 0x64C1}, //3593 #CJK UNIFIED IDEOGRAPH + {0x93EE, 0x64C3}, //3594 #CJK UNIFIED IDEOGRAPH + {0x93EF, 0x64C4}, //3595 #CJK UNIFIED IDEOGRAPH + {0x93F0, 0x64C6}, //3596 #CJK UNIFIED IDEOGRAPH + {0x93F1, 0x64C7}, //3597 #CJK UNIFIED IDEOGRAPH + {0x93F2, 0x64C8}, //3598 #CJK UNIFIED IDEOGRAPH + {0x93F3, 0x64C9}, //3599 #CJK UNIFIED IDEOGRAPH + {0x93F4, 0x64CA}, //3600 #CJK UNIFIED IDEOGRAPH + {0x93F5, 0x64CB}, //3601 #CJK UNIFIED IDEOGRAPH + {0x93F6, 0x64CC}, //3602 #CJK UNIFIED IDEOGRAPH + {0x93F7, 0x64CF}, //3603 #CJK UNIFIED IDEOGRAPH + {0x93F8, 0x64D1}, //3604 #CJK UNIFIED IDEOGRAPH + {0x93F9, 0x64D3}, //3605 #CJK UNIFIED IDEOGRAPH + {0x93FA, 0x64D4}, //3606 #CJK UNIFIED IDEOGRAPH + {0x93FB, 0x64D5}, //3607 #CJK UNIFIED IDEOGRAPH + {0x93FC, 0x64D6}, //3608 #CJK UNIFIED IDEOGRAPH + {0x93FD, 0x64D9}, //3609 #CJK UNIFIED IDEOGRAPH + {0x93FE, 0x64DA}, //3610 #CJK UNIFIED IDEOGRAPH + {0x9440, 0x64DB}, //3611 #CJK UNIFIED IDEOGRAPH + {0x9441, 0x64DC}, //3612 #CJK UNIFIED IDEOGRAPH + {0x9442, 0x64DD}, //3613 #CJK UNIFIED IDEOGRAPH + {0x9443, 0x64DF}, //3614 #CJK UNIFIED IDEOGRAPH + {0x9444, 0x64E0}, //3615 #CJK UNIFIED IDEOGRAPH + {0x9445, 0x64E1}, //3616 #CJK UNIFIED IDEOGRAPH + {0x9446, 0x64E3}, //3617 #CJK UNIFIED IDEOGRAPH + {0x9447, 0x64E5}, //3618 #CJK UNIFIED IDEOGRAPH + {0x9448, 0x64E7}, //3619 #CJK UNIFIED IDEOGRAPH + {0x9449, 0x64E8}, //3620 #CJK UNIFIED IDEOGRAPH + {0x944A, 0x64E9}, //3621 #CJK UNIFIED IDEOGRAPH + {0x944B, 0x64EA}, //3622 #CJK UNIFIED IDEOGRAPH + {0x944C, 0x64EB}, //3623 #CJK UNIFIED IDEOGRAPH + {0x944D, 0x64EC}, //3624 #CJK UNIFIED IDEOGRAPH + {0x944E, 0x64ED}, //3625 #CJK UNIFIED IDEOGRAPH + {0x944F, 0x64EE}, //3626 #CJK UNIFIED IDEOGRAPH + {0x9450, 0x64EF}, //3627 #CJK UNIFIED IDEOGRAPH + {0x9451, 0x64F0}, //3628 #CJK UNIFIED IDEOGRAPH + {0x9452, 0x64F1}, //3629 #CJK UNIFIED IDEOGRAPH + {0x9453, 0x64F2}, //3630 #CJK UNIFIED IDEOGRAPH + {0x9454, 0x64F3}, //3631 #CJK UNIFIED IDEOGRAPH + {0x9455, 0x64F4}, //3632 #CJK UNIFIED IDEOGRAPH + {0x9456, 0x64F5}, //3633 #CJK UNIFIED IDEOGRAPH + {0x9457, 0x64F6}, //3634 #CJK UNIFIED IDEOGRAPH + {0x9458, 0x64F7}, //3635 #CJK UNIFIED IDEOGRAPH + {0x9459, 0x64F8}, //3636 #CJK UNIFIED IDEOGRAPH + {0x945A, 0x64F9}, //3637 #CJK UNIFIED IDEOGRAPH + {0x945B, 0x64FA}, //3638 #CJK UNIFIED IDEOGRAPH + {0x945C, 0x64FB}, //3639 #CJK UNIFIED IDEOGRAPH + {0x945D, 0x64FC}, //3640 #CJK UNIFIED IDEOGRAPH + {0x945E, 0x64FD}, //3641 #CJK UNIFIED IDEOGRAPH + {0x945F, 0x64FE}, //3642 #CJK UNIFIED IDEOGRAPH + {0x9460, 0x64FF}, //3643 #CJK UNIFIED IDEOGRAPH + {0x9461, 0x6501}, //3644 #CJK UNIFIED IDEOGRAPH + {0x9462, 0x6502}, //3645 #CJK UNIFIED IDEOGRAPH + {0x9463, 0x6503}, //3646 #CJK UNIFIED IDEOGRAPH + {0x9464, 0x6504}, //3647 #CJK UNIFIED IDEOGRAPH + {0x9465, 0x6505}, //3648 #CJK UNIFIED IDEOGRAPH + {0x9466, 0x6506}, //3649 #CJK UNIFIED IDEOGRAPH + {0x9467, 0x6507}, //3650 #CJK UNIFIED IDEOGRAPH + {0x9468, 0x6508}, //3651 #CJK UNIFIED IDEOGRAPH + {0x9469, 0x650A}, //3652 #CJK UNIFIED IDEOGRAPH + {0x946A, 0x650B}, //3653 #CJK UNIFIED IDEOGRAPH + {0x946B, 0x650C}, //3654 #CJK UNIFIED IDEOGRAPH + {0x946C, 0x650D}, //3655 #CJK UNIFIED IDEOGRAPH + {0x946D, 0x650E}, //3656 #CJK UNIFIED IDEOGRAPH + {0x946E, 0x650F}, //3657 #CJK UNIFIED IDEOGRAPH + {0x946F, 0x6510}, //3658 #CJK UNIFIED IDEOGRAPH + {0x9470, 0x6511}, //3659 #CJK UNIFIED IDEOGRAPH + {0x9471, 0x6513}, //3660 #CJK UNIFIED IDEOGRAPH + {0x9472, 0x6514}, //3661 #CJK UNIFIED IDEOGRAPH + {0x9473, 0x6515}, //3662 #CJK UNIFIED IDEOGRAPH + {0x9474, 0x6516}, //3663 #CJK UNIFIED IDEOGRAPH + {0x9475, 0x6517}, //3664 #CJK UNIFIED IDEOGRAPH + {0x9476, 0x6519}, //3665 #CJK UNIFIED IDEOGRAPH + {0x9477, 0x651A}, //3666 #CJK UNIFIED IDEOGRAPH + {0x9478, 0x651B}, //3667 #CJK UNIFIED IDEOGRAPH + {0x9479, 0x651C}, //3668 #CJK UNIFIED IDEOGRAPH + {0x947A, 0x651D}, //3669 #CJK UNIFIED IDEOGRAPH + {0x947B, 0x651E}, //3670 #CJK UNIFIED IDEOGRAPH + {0x947C, 0x651F}, //3671 #CJK UNIFIED IDEOGRAPH + {0x947D, 0x6520}, //3672 #CJK UNIFIED IDEOGRAPH + {0x947E, 0x6521}, //3673 #CJK UNIFIED IDEOGRAPH + {0x9480, 0x6522}, //3674 #CJK UNIFIED IDEOGRAPH + {0x9481, 0x6523}, //3675 #CJK UNIFIED IDEOGRAPH + {0x9482, 0x6524}, //3676 #CJK UNIFIED IDEOGRAPH + {0x9483, 0x6526}, //3677 #CJK UNIFIED IDEOGRAPH + {0x9484, 0x6527}, //3678 #CJK UNIFIED IDEOGRAPH + {0x9485, 0x6528}, //3679 #CJK UNIFIED IDEOGRAPH + {0x9486, 0x6529}, //3680 #CJK UNIFIED IDEOGRAPH + {0x9487, 0x652A}, //3681 #CJK UNIFIED IDEOGRAPH + {0x9488, 0x652C}, //3682 #CJK UNIFIED IDEOGRAPH + {0x9489, 0x652D}, //3683 #CJK UNIFIED IDEOGRAPH + {0x948A, 0x6530}, //3684 #CJK UNIFIED IDEOGRAPH + {0x948B, 0x6531}, //3685 #CJK UNIFIED IDEOGRAPH + {0x948C, 0x6532}, //3686 #CJK UNIFIED IDEOGRAPH + {0x948D, 0x6533}, //3687 #CJK UNIFIED IDEOGRAPH + {0x948E, 0x6537}, //3688 #CJK UNIFIED IDEOGRAPH + {0x948F, 0x653A}, //3689 #CJK UNIFIED IDEOGRAPH + {0x9490, 0x653C}, //3690 #CJK UNIFIED IDEOGRAPH + {0x9491, 0x653D}, //3691 #CJK UNIFIED IDEOGRAPH + {0x9492, 0x6540}, //3692 #CJK UNIFIED IDEOGRAPH + {0x9493, 0x6541}, //3693 #CJK UNIFIED IDEOGRAPH + {0x9494, 0x6542}, //3694 #CJK UNIFIED IDEOGRAPH + {0x9495, 0x6543}, //3695 #CJK UNIFIED IDEOGRAPH + {0x9496, 0x6544}, //3696 #CJK UNIFIED IDEOGRAPH + {0x9497, 0x6546}, //3697 #CJK UNIFIED IDEOGRAPH + {0x9498, 0x6547}, //3698 #CJK UNIFIED IDEOGRAPH + {0x9499, 0x654A}, //3699 #CJK UNIFIED IDEOGRAPH + {0x949A, 0x654B}, //3700 #CJK UNIFIED IDEOGRAPH + {0x949B, 0x654D}, //3701 #CJK UNIFIED IDEOGRAPH + {0x949C, 0x654E}, //3702 #CJK UNIFIED IDEOGRAPH + {0x949D, 0x6550}, //3703 #CJK UNIFIED IDEOGRAPH + {0x949E, 0x6552}, //3704 #CJK UNIFIED IDEOGRAPH + {0x949F, 0x6553}, //3705 #CJK UNIFIED IDEOGRAPH + {0x94A0, 0x6554}, //3706 #CJK UNIFIED IDEOGRAPH + {0x94A1, 0x6557}, //3707 #CJK UNIFIED IDEOGRAPH + {0x94A2, 0x6558}, //3708 #CJK UNIFIED IDEOGRAPH + {0x94A3, 0x655A}, //3709 #CJK UNIFIED IDEOGRAPH + {0x94A4, 0x655C}, //3710 #CJK UNIFIED IDEOGRAPH + {0x94A5, 0x655F}, //3711 #CJK UNIFIED IDEOGRAPH + {0x94A6, 0x6560}, //3712 #CJK UNIFIED IDEOGRAPH + {0x94A7, 0x6561}, //3713 #CJK UNIFIED IDEOGRAPH + {0x94A8, 0x6564}, //3714 #CJK UNIFIED IDEOGRAPH + {0x94A9, 0x6565}, //3715 #CJK UNIFIED IDEOGRAPH + {0x94AA, 0x6567}, //3716 #CJK UNIFIED IDEOGRAPH + {0x94AB, 0x6568}, //3717 #CJK UNIFIED IDEOGRAPH + {0x94AC, 0x6569}, //3718 #CJK UNIFIED IDEOGRAPH + {0x94AD, 0x656A}, //3719 #CJK UNIFIED IDEOGRAPH + {0x94AE, 0x656D}, //3720 #CJK UNIFIED IDEOGRAPH + {0x94AF, 0x656E}, //3721 #CJK UNIFIED IDEOGRAPH + {0x94B0, 0x656F}, //3722 #CJK UNIFIED IDEOGRAPH + {0x94B1, 0x6571}, //3723 #CJK UNIFIED IDEOGRAPH + {0x94B2, 0x6573}, //3724 #CJK UNIFIED IDEOGRAPH + {0x94B3, 0x6575}, //3725 #CJK UNIFIED IDEOGRAPH + {0x94B4, 0x6576}, //3726 #CJK UNIFIED IDEOGRAPH + {0x94B5, 0x6578}, //3727 #CJK UNIFIED IDEOGRAPH + {0x94B6, 0x6579}, //3728 #CJK UNIFIED IDEOGRAPH + {0x94B7, 0x657A}, //3729 #CJK UNIFIED IDEOGRAPH + {0x94B8, 0x657B}, //3730 #CJK UNIFIED IDEOGRAPH + {0x94B9, 0x657C}, //3731 #CJK UNIFIED IDEOGRAPH + {0x94BA, 0x657D}, //3732 #CJK UNIFIED IDEOGRAPH + {0x94BB, 0x657E}, //3733 #CJK UNIFIED IDEOGRAPH + {0x94BC, 0x657F}, //3734 #CJK UNIFIED IDEOGRAPH + {0x94BD, 0x6580}, //3735 #CJK UNIFIED IDEOGRAPH + {0x94BE, 0x6581}, //3736 #CJK UNIFIED IDEOGRAPH + {0x94BF, 0x6582}, //3737 #CJK UNIFIED IDEOGRAPH + {0x94C0, 0x6583}, //3738 #CJK UNIFIED IDEOGRAPH + {0x94C1, 0x6584}, //3739 #CJK UNIFIED IDEOGRAPH + {0x94C2, 0x6585}, //3740 #CJK UNIFIED IDEOGRAPH + {0x94C3, 0x6586}, //3741 #CJK UNIFIED IDEOGRAPH + {0x94C4, 0x6588}, //3742 #CJK UNIFIED IDEOGRAPH + {0x94C5, 0x6589}, //3743 #CJK UNIFIED IDEOGRAPH + {0x94C6, 0x658A}, //3744 #CJK UNIFIED IDEOGRAPH + {0x94C7, 0x658D}, //3745 #CJK UNIFIED IDEOGRAPH + {0x94C8, 0x658E}, //3746 #CJK UNIFIED IDEOGRAPH + {0x94C9, 0x658F}, //3747 #CJK UNIFIED IDEOGRAPH + {0x94CA, 0x6592}, //3748 #CJK UNIFIED IDEOGRAPH + {0x94CB, 0x6594}, //3749 #CJK UNIFIED IDEOGRAPH + {0x94CC, 0x6595}, //3750 #CJK UNIFIED IDEOGRAPH + {0x94CD, 0x6596}, //3751 #CJK UNIFIED IDEOGRAPH + {0x94CE, 0x6598}, //3752 #CJK UNIFIED IDEOGRAPH + {0x94CF, 0x659A}, //3753 #CJK UNIFIED IDEOGRAPH + {0x94D0, 0x659D}, //3754 #CJK UNIFIED IDEOGRAPH + {0x94D1, 0x659E}, //3755 #CJK UNIFIED IDEOGRAPH + {0x94D2, 0x65A0}, //3756 #CJK UNIFIED IDEOGRAPH + {0x94D3, 0x65A2}, //3757 #CJK UNIFIED IDEOGRAPH + {0x94D4, 0x65A3}, //3758 #CJK UNIFIED IDEOGRAPH + {0x94D5, 0x65A6}, //3759 #CJK UNIFIED IDEOGRAPH + {0x94D6, 0x65A8}, //3760 #CJK UNIFIED IDEOGRAPH + {0x94D7, 0x65AA}, //3761 #CJK UNIFIED IDEOGRAPH + {0x94D8, 0x65AC}, //3762 #CJK UNIFIED IDEOGRAPH + {0x94D9, 0x65AE}, //3763 #CJK UNIFIED IDEOGRAPH + {0x94DA, 0x65B1}, //3764 #CJK UNIFIED IDEOGRAPH + {0x94DB, 0x65B2}, //3765 #CJK UNIFIED IDEOGRAPH + {0x94DC, 0x65B3}, //3766 #CJK UNIFIED IDEOGRAPH + {0x94DD, 0x65B4}, //3767 #CJK UNIFIED IDEOGRAPH + {0x94DE, 0x65B5}, //3768 #CJK UNIFIED IDEOGRAPH + {0x94DF, 0x65B6}, //3769 #CJK UNIFIED IDEOGRAPH + {0x94E0, 0x65B7}, //3770 #CJK UNIFIED IDEOGRAPH + {0x94E1, 0x65B8}, //3771 #CJK UNIFIED IDEOGRAPH + {0x94E2, 0x65BA}, //3772 #CJK UNIFIED IDEOGRAPH + {0x94E3, 0x65BB}, //3773 #CJK UNIFIED IDEOGRAPH + {0x94E4, 0x65BE}, //3774 #CJK UNIFIED IDEOGRAPH + {0x94E5, 0x65BF}, //3775 #CJK UNIFIED IDEOGRAPH + {0x94E6, 0x65C0}, //3776 #CJK UNIFIED IDEOGRAPH + {0x94E7, 0x65C2}, //3777 #CJK UNIFIED IDEOGRAPH + {0x94E8, 0x65C7}, //3778 #CJK UNIFIED IDEOGRAPH + {0x94E9, 0x65C8}, //3779 #CJK UNIFIED IDEOGRAPH + {0x94EA, 0x65C9}, //3780 #CJK UNIFIED IDEOGRAPH + {0x94EB, 0x65CA}, //3781 #CJK UNIFIED IDEOGRAPH + {0x94EC, 0x65CD}, //3782 #CJK UNIFIED IDEOGRAPH + {0x94ED, 0x65D0}, //3783 #CJK UNIFIED IDEOGRAPH + {0x94EE, 0x65D1}, //3784 #CJK UNIFIED IDEOGRAPH + {0x94EF, 0x65D3}, //3785 #CJK UNIFIED IDEOGRAPH + {0x94F0, 0x65D4}, //3786 #CJK UNIFIED IDEOGRAPH + {0x94F1, 0x65D5}, //3787 #CJK UNIFIED IDEOGRAPH + {0x94F2, 0x65D8}, //3788 #CJK UNIFIED IDEOGRAPH + {0x94F3, 0x65D9}, //3789 #CJK UNIFIED IDEOGRAPH + {0x94F4, 0x65DA}, //3790 #CJK UNIFIED IDEOGRAPH + {0x94F5, 0x65DB}, //3791 #CJK UNIFIED IDEOGRAPH + {0x94F6, 0x65DC}, //3792 #CJK UNIFIED IDEOGRAPH + {0x94F7, 0x65DD}, //3793 #CJK UNIFIED IDEOGRAPH + {0x94F8, 0x65DE}, //3794 #CJK UNIFIED IDEOGRAPH + {0x94F9, 0x65DF}, //3795 #CJK UNIFIED IDEOGRAPH + {0x94FA, 0x65E1}, //3796 #CJK UNIFIED IDEOGRAPH + {0x94FB, 0x65E3}, //3797 #CJK UNIFIED IDEOGRAPH + {0x94FC, 0x65E4}, //3798 #CJK UNIFIED IDEOGRAPH + {0x94FD, 0x65EA}, //3799 #CJK UNIFIED IDEOGRAPH + {0x94FE, 0x65EB}, //3800 #CJK UNIFIED IDEOGRAPH + {0x9540, 0x65F2}, //3801 #CJK UNIFIED IDEOGRAPH + {0x9541, 0x65F3}, //3802 #CJK UNIFIED IDEOGRAPH + {0x9542, 0x65F4}, //3803 #CJK UNIFIED IDEOGRAPH + {0x9543, 0x65F5}, //3804 #CJK UNIFIED IDEOGRAPH + {0x9544, 0x65F8}, //3805 #CJK UNIFIED IDEOGRAPH + {0x9545, 0x65F9}, //3806 #CJK UNIFIED IDEOGRAPH + {0x9546, 0x65FB}, //3807 #CJK UNIFIED IDEOGRAPH + {0x9547, 0x65FC}, //3808 #CJK UNIFIED IDEOGRAPH + {0x9548, 0x65FD}, //3809 #CJK UNIFIED IDEOGRAPH + {0x9549, 0x65FE}, //3810 #CJK UNIFIED IDEOGRAPH + {0x954A, 0x65FF}, //3811 #CJK UNIFIED IDEOGRAPH + {0x954B, 0x6601}, //3812 #CJK UNIFIED IDEOGRAPH + {0x954C, 0x6604}, //3813 #CJK UNIFIED IDEOGRAPH + {0x954D, 0x6605}, //3814 #CJK UNIFIED IDEOGRAPH + {0x954E, 0x6607}, //3815 #CJK UNIFIED IDEOGRAPH + {0x954F, 0x6608}, //3816 #CJK UNIFIED IDEOGRAPH + {0x9550, 0x6609}, //3817 #CJK UNIFIED IDEOGRAPH + {0x9551, 0x660B}, //3818 #CJK UNIFIED IDEOGRAPH + {0x9552, 0x660D}, //3819 #CJK UNIFIED IDEOGRAPH + {0x9553, 0x6610}, //3820 #CJK UNIFIED IDEOGRAPH + {0x9554, 0x6611}, //3821 #CJK UNIFIED IDEOGRAPH + {0x9555, 0x6612}, //3822 #CJK UNIFIED IDEOGRAPH + {0x9556, 0x6616}, //3823 #CJK UNIFIED IDEOGRAPH + {0x9557, 0x6617}, //3824 #CJK UNIFIED IDEOGRAPH + {0x9558, 0x6618}, //3825 #CJK UNIFIED IDEOGRAPH + {0x9559, 0x661A}, //3826 #CJK UNIFIED IDEOGRAPH + {0x955A, 0x661B}, //3827 #CJK UNIFIED IDEOGRAPH + {0x955B, 0x661C}, //3828 #CJK UNIFIED IDEOGRAPH + {0x955C, 0x661E}, //3829 #CJK UNIFIED IDEOGRAPH + {0x955D, 0x6621}, //3830 #CJK UNIFIED IDEOGRAPH + {0x955E, 0x6622}, //3831 #CJK UNIFIED IDEOGRAPH + {0x955F, 0x6623}, //3832 #CJK UNIFIED IDEOGRAPH + {0x9560, 0x6624}, //3833 #CJK UNIFIED IDEOGRAPH + {0x9561, 0x6626}, //3834 #CJK UNIFIED IDEOGRAPH + {0x9562, 0x6629}, //3835 #CJK UNIFIED IDEOGRAPH + {0x9563, 0x662A}, //3836 #CJK UNIFIED IDEOGRAPH + {0x9564, 0x662B}, //3837 #CJK UNIFIED IDEOGRAPH + {0x9565, 0x662C}, //3838 #CJK UNIFIED IDEOGRAPH + {0x9566, 0x662E}, //3839 #CJK UNIFIED IDEOGRAPH + {0x9567, 0x6630}, //3840 #CJK UNIFIED IDEOGRAPH + {0x9568, 0x6632}, //3841 #CJK UNIFIED IDEOGRAPH + {0x9569, 0x6633}, //3842 #CJK UNIFIED IDEOGRAPH + {0x956A, 0x6637}, //3843 #CJK UNIFIED IDEOGRAPH + {0x956B, 0x6638}, //3844 #CJK UNIFIED IDEOGRAPH + {0x956C, 0x6639}, //3845 #CJK UNIFIED IDEOGRAPH + {0x956D, 0x663A}, //3846 #CJK UNIFIED IDEOGRAPH + {0x956E, 0x663B}, //3847 #CJK UNIFIED IDEOGRAPH + {0x956F, 0x663D}, //3848 #CJK UNIFIED IDEOGRAPH + {0x9570, 0x663F}, //3849 #CJK UNIFIED IDEOGRAPH + {0x9571, 0x6640}, //3850 #CJK UNIFIED IDEOGRAPH + {0x9572, 0x6642}, //3851 #CJK UNIFIED IDEOGRAPH + {0x9573, 0x6644}, //3852 #CJK UNIFIED IDEOGRAPH + {0x9574, 0x6645}, //3853 #CJK UNIFIED IDEOGRAPH + {0x9575, 0x6646}, //3854 #CJK UNIFIED IDEOGRAPH + {0x9576, 0x6647}, //3855 #CJK UNIFIED IDEOGRAPH + {0x9577, 0x6648}, //3856 #CJK UNIFIED IDEOGRAPH + {0x9578, 0x6649}, //3857 #CJK UNIFIED IDEOGRAPH + {0x9579, 0x664A}, //3858 #CJK UNIFIED IDEOGRAPH + {0x957A, 0x664D}, //3859 #CJK UNIFIED IDEOGRAPH + {0x957B, 0x664E}, //3860 #CJK UNIFIED IDEOGRAPH + {0x957C, 0x6650}, //3861 #CJK UNIFIED IDEOGRAPH + {0x957D, 0x6651}, //3862 #CJK UNIFIED IDEOGRAPH + {0x957E, 0x6658}, //3863 #CJK UNIFIED IDEOGRAPH + {0x9580, 0x6659}, //3864 #CJK UNIFIED IDEOGRAPH + {0x9581, 0x665B}, //3865 #CJK UNIFIED IDEOGRAPH + {0x9582, 0x665C}, //3866 #CJK UNIFIED IDEOGRAPH + {0x9583, 0x665D}, //3867 #CJK UNIFIED IDEOGRAPH + {0x9584, 0x665E}, //3868 #CJK UNIFIED IDEOGRAPH + {0x9585, 0x6660}, //3869 #CJK UNIFIED IDEOGRAPH + {0x9586, 0x6662}, //3870 #CJK UNIFIED IDEOGRAPH + {0x9587, 0x6663}, //3871 #CJK UNIFIED IDEOGRAPH + {0x9588, 0x6665}, //3872 #CJK UNIFIED IDEOGRAPH + {0x9589, 0x6667}, //3873 #CJK UNIFIED IDEOGRAPH + {0x958A, 0x6669}, //3874 #CJK UNIFIED IDEOGRAPH + {0x958B, 0x666A}, //3875 #CJK UNIFIED IDEOGRAPH + {0x958C, 0x666B}, //3876 #CJK UNIFIED IDEOGRAPH + {0x958D, 0x666C}, //3877 #CJK UNIFIED IDEOGRAPH + {0x958E, 0x666D}, //3878 #CJK UNIFIED IDEOGRAPH + {0x958F, 0x6671}, //3879 #CJK UNIFIED IDEOGRAPH + {0x9590, 0x6672}, //3880 #CJK UNIFIED IDEOGRAPH + {0x9591, 0x6673}, //3881 #CJK UNIFIED IDEOGRAPH + {0x9592, 0x6675}, //3882 #CJK UNIFIED IDEOGRAPH + {0x9593, 0x6678}, //3883 #CJK UNIFIED IDEOGRAPH + {0x9594, 0x6679}, //3884 #CJK UNIFIED IDEOGRAPH + {0x9595, 0x667B}, //3885 #CJK UNIFIED IDEOGRAPH + {0x9596, 0x667C}, //3886 #CJK UNIFIED IDEOGRAPH + {0x9597, 0x667D}, //3887 #CJK UNIFIED IDEOGRAPH + {0x9598, 0x667F}, //3888 #CJK UNIFIED IDEOGRAPH + {0x9599, 0x6680}, //3889 #CJK UNIFIED IDEOGRAPH + {0x959A, 0x6681}, //3890 #CJK UNIFIED IDEOGRAPH + {0x959B, 0x6683}, //3891 #CJK UNIFIED IDEOGRAPH + {0x959C, 0x6685}, //3892 #CJK UNIFIED IDEOGRAPH + {0x959D, 0x6686}, //3893 #CJK UNIFIED IDEOGRAPH + {0x959E, 0x6688}, //3894 #CJK UNIFIED IDEOGRAPH + {0x959F, 0x6689}, //3895 #CJK UNIFIED IDEOGRAPH + {0x95A0, 0x668A}, //3896 #CJK UNIFIED IDEOGRAPH + {0x95A1, 0x668B}, //3897 #CJK UNIFIED IDEOGRAPH + {0x95A2, 0x668D}, //3898 #CJK UNIFIED IDEOGRAPH + {0x95A3, 0x668E}, //3899 #CJK UNIFIED IDEOGRAPH + {0x95A4, 0x668F}, //3900 #CJK UNIFIED IDEOGRAPH + {0x95A5, 0x6690}, //3901 #CJK UNIFIED IDEOGRAPH + {0x95A6, 0x6692}, //3902 #CJK UNIFIED IDEOGRAPH + {0x95A7, 0x6693}, //3903 #CJK UNIFIED IDEOGRAPH + {0x95A8, 0x6694}, //3904 #CJK UNIFIED IDEOGRAPH + {0x95A9, 0x6695}, //3905 #CJK UNIFIED IDEOGRAPH + {0x95AA, 0x6698}, //3906 #CJK UNIFIED IDEOGRAPH + {0x95AB, 0x6699}, //3907 #CJK UNIFIED IDEOGRAPH + {0x95AC, 0x669A}, //3908 #CJK UNIFIED IDEOGRAPH + {0x95AD, 0x669B}, //3909 #CJK UNIFIED IDEOGRAPH + {0x95AE, 0x669C}, //3910 #CJK UNIFIED IDEOGRAPH + {0x95AF, 0x669E}, //3911 #CJK UNIFIED IDEOGRAPH + {0x95B0, 0x669F}, //3912 #CJK UNIFIED IDEOGRAPH + {0x95B1, 0x66A0}, //3913 #CJK UNIFIED IDEOGRAPH + {0x95B2, 0x66A1}, //3914 #CJK UNIFIED IDEOGRAPH + {0x95B3, 0x66A2}, //3915 #CJK UNIFIED IDEOGRAPH + {0x95B4, 0x66A3}, //3916 #CJK UNIFIED IDEOGRAPH + {0x95B5, 0x66A4}, //3917 #CJK UNIFIED IDEOGRAPH + {0x95B6, 0x66A5}, //3918 #CJK UNIFIED IDEOGRAPH + {0x95B7, 0x66A6}, //3919 #CJK UNIFIED IDEOGRAPH + {0x95B8, 0x66A9}, //3920 #CJK UNIFIED IDEOGRAPH + {0x95B9, 0x66AA}, //3921 #CJK UNIFIED IDEOGRAPH + {0x95BA, 0x66AB}, //3922 #CJK UNIFIED IDEOGRAPH + {0x95BB, 0x66AC}, //3923 #CJK UNIFIED IDEOGRAPH + {0x95BC, 0x66AD}, //3924 #CJK UNIFIED IDEOGRAPH + {0x95BD, 0x66AF}, //3925 #CJK UNIFIED IDEOGRAPH + {0x95BE, 0x66B0}, //3926 #CJK UNIFIED IDEOGRAPH + {0x95BF, 0x66B1}, //3927 #CJK UNIFIED IDEOGRAPH + {0x95C0, 0x66B2}, //3928 #CJK UNIFIED IDEOGRAPH + {0x95C1, 0x66B3}, //3929 #CJK UNIFIED IDEOGRAPH + {0x95C2, 0x66B5}, //3930 #CJK UNIFIED IDEOGRAPH + {0x95C3, 0x66B6}, //3931 #CJK UNIFIED IDEOGRAPH + {0x95C4, 0x66B7}, //3932 #CJK UNIFIED IDEOGRAPH + {0x95C5, 0x66B8}, //3933 #CJK UNIFIED IDEOGRAPH + {0x95C6, 0x66BA}, //3934 #CJK UNIFIED IDEOGRAPH + {0x95C7, 0x66BB}, //3935 #CJK UNIFIED IDEOGRAPH + {0x95C8, 0x66BC}, //3936 #CJK UNIFIED IDEOGRAPH + {0x95C9, 0x66BD}, //3937 #CJK UNIFIED IDEOGRAPH + {0x95CA, 0x66BF}, //3938 #CJK UNIFIED IDEOGRAPH + {0x95CB, 0x66C0}, //3939 #CJK UNIFIED IDEOGRAPH + {0x95CC, 0x66C1}, //3940 #CJK UNIFIED IDEOGRAPH + {0x95CD, 0x66C2}, //3941 #CJK UNIFIED IDEOGRAPH + {0x95CE, 0x66C3}, //3942 #CJK UNIFIED IDEOGRAPH + {0x95CF, 0x66C4}, //3943 #CJK UNIFIED IDEOGRAPH + {0x95D0, 0x66C5}, //3944 #CJK UNIFIED IDEOGRAPH + {0x95D1, 0x66C6}, //3945 #CJK UNIFIED IDEOGRAPH + {0x95D2, 0x66C7}, //3946 #CJK UNIFIED IDEOGRAPH + {0x95D3, 0x66C8}, //3947 #CJK UNIFIED IDEOGRAPH + {0x95D4, 0x66C9}, //3948 #CJK UNIFIED IDEOGRAPH + {0x95D5, 0x66CA}, //3949 #CJK UNIFIED IDEOGRAPH + {0x95D6, 0x66CB}, //3950 #CJK UNIFIED IDEOGRAPH + {0x95D7, 0x66CC}, //3951 #CJK UNIFIED IDEOGRAPH + {0x95D8, 0x66CD}, //3952 #CJK UNIFIED IDEOGRAPH + {0x95D9, 0x66CE}, //3953 #CJK UNIFIED IDEOGRAPH + {0x95DA, 0x66CF}, //3954 #CJK UNIFIED IDEOGRAPH + {0x95DB, 0x66D0}, //3955 #CJK UNIFIED IDEOGRAPH + {0x95DC, 0x66D1}, //3956 #CJK UNIFIED IDEOGRAPH + {0x95DD, 0x66D2}, //3957 #CJK UNIFIED IDEOGRAPH + {0x95DE, 0x66D3}, //3958 #CJK UNIFIED IDEOGRAPH + {0x95DF, 0x66D4}, //3959 #CJK UNIFIED IDEOGRAPH + {0x95E0, 0x66D5}, //3960 #CJK UNIFIED IDEOGRAPH + {0x95E1, 0x66D6}, //3961 #CJK UNIFIED IDEOGRAPH + {0x95E2, 0x66D7}, //3962 #CJK UNIFIED IDEOGRAPH + {0x95E3, 0x66D8}, //3963 #CJK UNIFIED IDEOGRAPH + {0x95E4, 0x66DA}, //3964 #CJK UNIFIED IDEOGRAPH + {0x95E5, 0x66DE}, //3965 #CJK UNIFIED IDEOGRAPH + {0x95E6, 0x66DF}, //3966 #CJK UNIFIED IDEOGRAPH + {0x95E7, 0x66E0}, //3967 #CJK UNIFIED IDEOGRAPH + {0x95E8, 0x66E1}, //3968 #CJK UNIFIED IDEOGRAPH + {0x95E9, 0x66E2}, //3969 #CJK UNIFIED IDEOGRAPH + {0x95EA, 0x66E3}, //3970 #CJK UNIFIED IDEOGRAPH + {0x95EB, 0x66E4}, //3971 #CJK UNIFIED IDEOGRAPH + {0x95EC, 0x66E5}, //3972 #CJK UNIFIED IDEOGRAPH + {0x95ED, 0x66E7}, //3973 #CJK UNIFIED IDEOGRAPH + {0x95EE, 0x66E8}, //3974 #CJK UNIFIED IDEOGRAPH + {0x95EF, 0x66EA}, //3975 #CJK UNIFIED IDEOGRAPH + {0x95F0, 0x66EB}, //3976 #CJK UNIFIED IDEOGRAPH + {0x95F1, 0x66EC}, //3977 #CJK UNIFIED IDEOGRAPH + {0x95F2, 0x66ED}, //3978 #CJK UNIFIED IDEOGRAPH + {0x95F3, 0x66EE}, //3979 #CJK UNIFIED IDEOGRAPH + {0x95F4, 0x66EF}, //3980 #CJK UNIFIED IDEOGRAPH + {0x95F5, 0x66F1}, //3981 #CJK UNIFIED IDEOGRAPH + {0x95F6, 0x66F5}, //3982 #CJK UNIFIED IDEOGRAPH + {0x95F7, 0x66F6}, //3983 #CJK UNIFIED IDEOGRAPH + {0x95F8, 0x66F8}, //3984 #CJK UNIFIED IDEOGRAPH + {0x95F9, 0x66FA}, //3985 #CJK UNIFIED IDEOGRAPH + {0x95FA, 0x66FB}, //3986 #CJK UNIFIED IDEOGRAPH + {0x95FB, 0x66FD}, //3987 #CJK UNIFIED IDEOGRAPH + {0x95FC, 0x6701}, //3988 #CJK UNIFIED IDEOGRAPH + {0x95FD, 0x6702}, //3989 #CJK UNIFIED IDEOGRAPH + {0x95FE, 0x6703}, //3990 #CJK UNIFIED IDEOGRAPH + {0x9640, 0x6704}, //3991 #CJK UNIFIED IDEOGRAPH + {0x9641, 0x6705}, //3992 #CJK UNIFIED IDEOGRAPH + {0x9642, 0x6706}, //3993 #CJK UNIFIED IDEOGRAPH + {0x9643, 0x6707}, //3994 #CJK UNIFIED IDEOGRAPH + {0x9644, 0x670C}, //3995 #CJK UNIFIED IDEOGRAPH + {0x9645, 0x670E}, //3996 #CJK UNIFIED IDEOGRAPH + {0x9646, 0x670F}, //3997 #CJK UNIFIED IDEOGRAPH + {0x9647, 0x6711}, //3998 #CJK UNIFIED IDEOGRAPH + {0x9648, 0x6712}, //3999 #CJK UNIFIED IDEOGRAPH + {0x9649, 0x6713}, //4000 #CJK UNIFIED IDEOGRAPH + {0x964A, 0x6716}, //4001 #CJK UNIFIED IDEOGRAPH + {0x964B, 0x6718}, //4002 #CJK UNIFIED IDEOGRAPH + {0x964C, 0x6719}, //4003 #CJK UNIFIED IDEOGRAPH + {0x964D, 0x671A}, //4004 #CJK UNIFIED IDEOGRAPH + {0x964E, 0x671C}, //4005 #CJK UNIFIED IDEOGRAPH + {0x964F, 0x671E}, //4006 #CJK UNIFIED IDEOGRAPH + {0x9650, 0x6720}, //4007 #CJK UNIFIED IDEOGRAPH + {0x9651, 0x6721}, //4008 #CJK UNIFIED IDEOGRAPH + {0x9652, 0x6722}, //4009 #CJK UNIFIED IDEOGRAPH + {0x9653, 0x6723}, //4010 #CJK UNIFIED IDEOGRAPH + {0x9654, 0x6724}, //4011 #CJK UNIFIED IDEOGRAPH + {0x9655, 0x6725}, //4012 #CJK UNIFIED IDEOGRAPH + {0x9656, 0x6727}, //4013 #CJK UNIFIED IDEOGRAPH + {0x9657, 0x6729}, //4014 #CJK UNIFIED IDEOGRAPH + {0x9658, 0x672E}, //4015 #CJK UNIFIED IDEOGRAPH + {0x9659, 0x6730}, //4016 #CJK UNIFIED IDEOGRAPH + {0x965A, 0x6732}, //4017 #CJK UNIFIED IDEOGRAPH + {0x965B, 0x6733}, //4018 #CJK UNIFIED IDEOGRAPH + {0x965C, 0x6736}, //4019 #CJK UNIFIED IDEOGRAPH + {0x965D, 0x6737}, //4020 #CJK UNIFIED IDEOGRAPH + {0x965E, 0x6738}, //4021 #CJK UNIFIED IDEOGRAPH + {0x965F, 0x6739}, //4022 #CJK UNIFIED IDEOGRAPH + {0x9660, 0x673B}, //4023 #CJK UNIFIED IDEOGRAPH + {0x9661, 0x673C}, //4024 #CJK UNIFIED IDEOGRAPH + {0x9662, 0x673E}, //4025 #CJK UNIFIED IDEOGRAPH + {0x9663, 0x673F}, //4026 #CJK UNIFIED IDEOGRAPH + {0x9664, 0x6741}, //4027 #CJK UNIFIED IDEOGRAPH + {0x9665, 0x6744}, //4028 #CJK UNIFIED IDEOGRAPH + {0x9666, 0x6745}, //4029 #CJK UNIFIED IDEOGRAPH + {0x9667, 0x6747}, //4030 #CJK UNIFIED IDEOGRAPH + {0x9668, 0x674A}, //4031 #CJK UNIFIED IDEOGRAPH + {0x9669, 0x674B}, //4032 #CJK UNIFIED IDEOGRAPH + {0x966A, 0x674D}, //4033 #CJK UNIFIED IDEOGRAPH + {0x966B, 0x6752}, //4034 #CJK UNIFIED IDEOGRAPH + {0x966C, 0x6754}, //4035 #CJK UNIFIED IDEOGRAPH + {0x966D, 0x6755}, //4036 #CJK UNIFIED IDEOGRAPH + {0x966E, 0x6757}, //4037 #CJK UNIFIED IDEOGRAPH + {0x966F, 0x6758}, //4038 #CJK UNIFIED IDEOGRAPH + {0x9670, 0x6759}, //4039 #CJK UNIFIED IDEOGRAPH + {0x9671, 0x675A}, //4040 #CJK UNIFIED IDEOGRAPH + {0x9672, 0x675B}, //4041 #CJK UNIFIED IDEOGRAPH + {0x9673, 0x675D}, //4042 #CJK UNIFIED IDEOGRAPH + {0x9674, 0x6762}, //4043 #CJK UNIFIED IDEOGRAPH + {0x9675, 0x6763}, //4044 #CJK UNIFIED IDEOGRAPH + {0x9676, 0x6764}, //4045 #CJK UNIFIED IDEOGRAPH + {0x9677, 0x6766}, //4046 #CJK UNIFIED IDEOGRAPH + {0x9678, 0x6767}, //4047 #CJK UNIFIED IDEOGRAPH + {0x9679, 0x676B}, //4048 #CJK UNIFIED IDEOGRAPH + {0x967A, 0x676C}, //4049 #CJK UNIFIED IDEOGRAPH + {0x967B, 0x676E}, //4050 #CJK UNIFIED IDEOGRAPH + {0x967C, 0x6771}, //4051 #CJK UNIFIED IDEOGRAPH + {0x967D, 0x6774}, //4052 #CJK UNIFIED IDEOGRAPH + {0x967E, 0x6776}, //4053 #CJK UNIFIED IDEOGRAPH + {0x9680, 0x6778}, //4054 #CJK UNIFIED IDEOGRAPH + {0x9681, 0x6779}, //4055 #CJK UNIFIED IDEOGRAPH + {0x9682, 0x677A}, //4056 #CJK UNIFIED IDEOGRAPH + {0x9683, 0x677B}, //4057 #CJK UNIFIED IDEOGRAPH + {0x9684, 0x677D}, //4058 #CJK UNIFIED IDEOGRAPH + {0x9685, 0x6780}, //4059 #CJK UNIFIED IDEOGRAPH + {0x9686, 0x6782}, //4060 #CJK UNIFIED IDEOGRAPH + {0x9687, 0x6783}, //4061 #CJK UNIFIED IDEOGRAPH + {0x9688, 0x6785}, //4062 #CJK UNIFIED IDEOGRAPH + {0x9689, 0x6786}, //4063 #CJK UNIFIED IDEOGRAPH + {0x968A, 0x6788}, //4064 #CJK UNIFIED IDEOGRAPH + {0x968B, 0x678A}, //4065 #CJK UNIFIED IDEOGRAPH + {0x968C, 0x678C}, //4066 #CJK UNIFIED IDEOGRAPH + {0x968D, 0x678D}, //4067 #CJK UNIFIED IDEOGRAPH + {0x968E, 0x678E}, //4068 #CJK UNIFIED IDEOGRAPH + {0x968F, 0x678F}, //4069 #CJK UNIFIED IDEOGRAPH + {0x9690, 0x6791}, //4070 #CJK UNIFIED IDEOGRAPH + {0x9691, 0x6792}, //4071 #CJK UNIFIED IDEOGRAPH + {0x9692, 0x6793}, //4072 #CJK UNIFIED IDEOGRAPH + {0x9693, 0x6794}, //4073 #CJK UNIFIED IDEOGRAPH + {0x9694, 0x6796}, //4074 #CJK UNIFIED IDEOGRAPH + {0x9695, 0x6799}, //4075 #CJK UNIFIED IDEOGRAPH + {0x9696, 0x679B}, //4076 #CJK UNIFIED IDEOGRAPH + {0x9697, 0x679F}, //4077 #CJK UNIFIED IDEOGRAPH + {0x9698, 0x67A0}, //4078 #CJK UNIFIED IDEOGRAPH + {0x9699, 0x67A1}, //4079 #CJK UNIFIED IDEOGRAPH + {0x969A, 0x67A4}, //4080 #CJK UNIFIED IDEOGRAPH + {0x969B, 0x67A6}, //4081 #CJK UNIFIED IDEOGRAPH + {0x969C, 0x67A9}, //4082 #CJK UNIFIED IDEOGRAPH + {0x969D, 0x67AC}, //4083 #CJK UNIFIED IDEOGRAPH + {0x969E, 0x67AE}, //4084 #CJK UNIFIED IDEOGRAPH + {0x969F, 0x67B1}, //4085 #CJK UNIFIED IDEOGRAPH + {0x96A0, 0x67B2}, //4086 #CJK UNIFIED IDEOGRAPH + {0x96A1, 0x67B4}, //4087 #CJK UNIFIED IDEOGRAPH + {0x96A2, 0x67B9}, //4088 #CJK UNIFIED IDEOGRAPH + {0x96A3, 0x67BA}, //4089 #CJK UNIFIED IDEOGRAPH + {0x96A4, 0x67BB}, //4090 #CJK UNIFIED IDEOGRAPH + {0x96A5, 0x67BC}, //4091 #CJK UNIFIED IDEOGRAPH + {0x96A6, 0x67BD}, //4092 #CJK UNIFIED IDEOGRAPH + {0x96A7, 0x67BE}, //4093 #CJK UNIFIED IDEOGRAPH + {0x96A8, 0x67BF}, //4094 #CJK UNIFIED IDEOGRAPH + {0x96A9, 0x67C0}, //4095 #CJK UNIFIED IDEOGRAPH + {0x96AA, 0x67C2}, //4096 #CJK UNIFIED IDEOGRAPH + {0x96AB, 0x67C5}, //4097 #CJK UNIFIED IDEOGRAPH + {0x96AC, 0x67C6}, //4098 #CJK UNIFIED IDEOGRAPH + {0x96AD, 0x67C7}, //4099 #CJK UNIFIED IDEOGRAPH + {0x96AE, 0x67C8}, //4100 #CJK UNIFIED IDEOGRAPH + {0x96AF, 0x67C9}, //4101 #CJK UNIFIED IDEOGRAPH + {0x96B0, 0x67CA}, //4102 #CJK UNIFIED IDEOGRAPH + {0x96B1, 0x67CB}, //4103 #CJK UNIFIED IDEOGRAPH + {0x96B2, 0x67CC}, //4104 #CJK UNIFIED IDEOGRAPH + {0x96B3, 0x67CD}, //4105 #CJK UNIFIED IDEOGRAPH + {0x96B4, 0x67CE}, //4106 #CJK UNIFIED IDEOGRAPH + {0x96B5, 0x67D5}, //4107 #CJK UNIFIED IDEOGRAPH + {0x96B6, 0x67D6}, //4108 #CJK UNIFIED IDEOGRAPH + {0x96B7, 0x67D7}, //4109 #CJK UNIFIED IDEOGRAPH + {0x96B8, 0x67DB}, //4110 #CJK UNIFIED IDEOGRAPH + {0x96B9, 0x67DF}, //4111 #CJK UNIFIED IDEOGRAPH + {0x96BA, 0x67E1}, //4112 #CJK UNIFIED IDEOGRAPH + {0x96BB, 0x67E3}, //4113 #CJK UNIFIED IDEOGRAPH + {0x96BC, 0x67E4}, //4114 #CJK UNIFIED IDEOGRAPH + {0x96BD, 0x67E6}, //4115 #CJK UNIFIED IDEOGRAPH + {0x96BE, 0x67E7}, //4116 #CJK UNIFIED IDEOGRAPH + {0x96BF, 0x67E8}, //4117 #CJK UNIFIED IDEOGRAPH + {0x96C0, 0x67EA}, //4118 #CJK UNIFIED IDEOGRAPH + {0x96C1, 0x67EB}, //4119 #CJK UNIFIED IDEOGRAPH + {0x96C2, 0x67ED}, //4120 #CJK UNIFIED IDEOGRAPH + {0x96C3, 0x67EE}, //4121 #CJK UNIFIED IDEOGRAPH + {0x96C4, 0x67F2}, //4122 #CJK UNIFIED IDEOGRAPH + {0x96C5, 0x67F5}, //4123 #CJK UNIFIED IDEOGRAPH + {0x96C6, 0x67F6}, //4124 #CJK UNIFIED IDEOGRAPH + {0x96C7, 0x67F7}, //4125 #CJK UNIFIED IDEOGRAPH + {0x96C8, 0x67F8}, //4126 #CJK UNIFIED IDEOGRAPH + {0x96C9, 0x67F9}, //4127 #CJK UNIFIED IDEOGRAPH + {0x96CA, 0x67FA}, //4128 #CJK UNIFIED IDEOGRAPH + {0x96CB, 0x67FB}, //4129 #CJK UNIFIED IDEOGRAPH + {0x96CC, 0x67FC}, //4130 #CJK UNIFIED IDEOGRAPH + {0x96CD, 0x67FE}, //4131 #CJK UNIFIED IDEOGRAPH + {0x96CE, 0x6801}, //4132 #CJK UNIFIED IDEOGRAPH + {0x96CF, 0x6802}, //4133 #CJK UNIFIED IDEOGRAPH + {0x96D0, 0x6803}, //4134 #CJK UNIFIED IDEOGRAPH + {0x96D1, 0x6804}, //4135 #CJK UNIFIED IDEOGRAPH + {0x96D2, 0x6806}, //4136 #CJK UNIFIED IDEOGRAPH + {0x96D3, 0x680D}, //4137 #CJK UNIFIED IDEOGRAPH + {0x96D4, 0x6810}, //4138 #CJK UNIFIED IDEOGRAPH + {0x96D5, 0x6812}, //4139 #CJK UNIFIED IDEOGRAPH + {0x96D6, 0x6814}, //4140 #CJK UNIFIED IDEOGRAPH + {0x96D7, 0x6815}, //4141 #CJK UNIFIED IDEOGRAPH + {0x96D8, 0x6818}, //4142 #CJK UNIFIED IDEOGRAPH + {0x96D9, 0x6819}, //4143 #CJK UNIFIED IDEOGRAPH + {0x96DA, 0x681A}, //4144 #CJK UNIFIED IDEOGRAPH + {0x96DB, 0x681B}, //4145 #CJK UNIFIED IDEOGRAPH + {0x96DC, 0x681C}, //4146 #CJK UNIFIED IDEOGRAPH + {0x96DD, 0x681E}, //4147 #CJK UNIFIED IDEOGRAPH + {0x96DE, 0x681F}, //4148 #CJK UNIFIED IDEOGRAPH + {0x96DF, 0x6820}, //4149 #CJK UNIFIED IDEOGRAPH + {0x96E0, 0x6822}, //4150 #CJK UNIFIED IDEOGRAPH + {0x96E1, 0x6823}, //4151 #CJK UNIFIED IDEOGRAPH + {0x96E2, 0x6824}, //4152 #CJK UNIFIED IDEOGRAPH + {0x96E3, 0x6825}, //4153 #CJK UNIFIED IDEOGRAPH + {0x96E4, 0x6826}, //4154 #CJK UNIFIED IDEOGRAPH + {0x96E5, 0x6827}, //4155 #CJK UNIFIED IDEOGRAPH + {0x96E6, 0x6828}, //4156 #CJK UNIFIED IDEOGRAPH + {0x96E7, 0x682B}, //4157 #CJK UNIFIED IDEOGRAPH + {0x96E8, 0x682C}, //4158 #CJK UNIFIED IDEOGRAPH + {0x96E9, 0x682D}, //4159 #CJK UNIFIED IDEOGRAPH + {0x96EA, 0x682E}, //4160 #CJK UNIFIED IDEOGRAPH + {0x96EB, 0x682F}, //4161 #CJK UNIFIED IDEOGRAPH + {0x96EC, 0x6830}, //4162 #CJK UNIFIED IDEOGRAPH + {0x96ED, 0x6831}, //4163 #CJK UNIFIED IDEOGRAPH + {0x96EE, 0x6834}, //4164 #CJK UNIFIED IDEOGRAPH + {0x96EF, 0x6835}, //4165 #CJK UNIFIED IDEOGRAPH + {0x96F0, 0x6836}, //4166 #CJK UNIFIED IDEOGRAPH + {0x96F1, 0x683A}, //4167 #CJK UNIFIED IDEOGRAPH + {0x96F2, 0x683B}, //4168 #CJK UNIFIED IDEOGRAPH + {0x96F3, 0x683F}, //4169 #CJK UNIFIED IDEOGRAPH + {0x96F4, 0x6847}, //4170 #CJK UNIFIED IDEOGRAPH + {0x96F5, 0x684B}, //4171 #CJK UNIFIED IDEOGRAPH + {0x96F6, 0x684D}, //4172 #CJK UNIFIED IDEOGRAPH + {0x96F7, 0x684F}, //4173 #CJK UNIFIED IDEOGRAPH + {0x96F8, 0x6852}, //4174 #CJK UNIFIED IDEOGRAPH + {0x96F9, 0x6856}, //4175 #CJK UNIFIED IDEOGRAPH + {0x96FA, 0x6857}, //4176 #CJK UNIFIED IDEOGRAPH + {0x96FB, 0x6858}, //4177 #CJK UNIFIED IDEOGRAPH + {0x96FC, 0x6859}, //4178 #CJK UNIFIED IDEOGRAPH + {0x96FD, 0x685A}, //4179 #CJK UNIFIED IDEOGRAPH + {0x96FE, 0x685B}, //4180 #CJK UNIFIED IDEOGRAPH + {0x9740, 0x685C}, //4181 #CJK UNIFIED IDEOGRAPH + {0x9741, 0x685D}, //4182 #CJK UNIFIED IDEOGRAPH + {0x9742, 0x685E}, //4183 #CJK UNIFIED IDEOGRAPH + {0x9743, 0x685F}, //4184 #CJK UNIFIED IDEOGRAPH + {0x9744, 0x686A}, //4185 #CJK UNIFIED IDEOGRAPH + {0x9745, 0x686C}, //4186 #CJK UNIFIED IDEOGRAPH + {0x9746, 0x686D}, //4187 #CJK UNIFIED IDEOGRAPH + {0x9747, 0x686E}, //4188 #CJK UNIFIED IDEOGRAPH + {0x9748, 0x686F}, //4189 #CJK UNIFIED IDEOGRAPH + {0x9749, 0x6870}, //4190 #CJK UNIFIED IDEOGRAPH + {0x974A, 0x6871}, //4191 #CJK UNIFIED IDEOGRAPH + {0x974B, 0x6872}, //4192 #CJK UNIFIED IDEOGRAPH + {0x974C, 0x6873}, //4193 #CJK UNIFIED IDEOGRAPH + {0x974D, 0x6875}, //4194 #CJK UNIFIED IDEOGRAPH + {0x974E, 0x6878}, //4195 #CJK UNIFIED IDEOGRAPH + {0x974F, 0x6879}, //4196 #CJK UNIFIED IDEOGRAPH + {0x9750, 0x687A}, //4197 #CJK UNIFIED IDEOGRAPH + {0x9751, 0x687B}, //4198 #CJK UNIFIED IDEOGRAPH + {0x9752, 0x687C}, //4199 #CJK UNIFIED IDEOGRAPH + {0x9753, 0x687D}, //4200 #CJK UNIFIED IDEOGRAPH + {0x9754, 0x687E}, //4201 #CJK UNIFIED IDEOGRAPH + {0x9755, 0x687F}, //4202 #CJK UNIFIED IDEOGRAPH + {0x9756, 0x6880}, //4203 #CJK UNIFIED IDEOGRAPH + {0x9757, 0x6882}, //4204 #CJK UNIFIED IDEOGRAPH + {0x9758, 0x6884}, //4205 #CJK UNIFIED IDEOGRAPH + {0x9759, 0x6887}, //4206 #CJK UNIFIED IDEOGRAPH + {0x975A, 0x6888}, //4207 #CJK UNIFIED IDEOGRAPH + {0x975B, 0x6889}, //4208 #CJK UNIFIED IDEOGRAPH + {0x975C, 0x688A}, //4209 #CJK UNIFIED IDEOGRAPH + {0x975D, 0x688B}, //4210 #CJK UNIFIED IDEOGRAPH + {0x975E, 0x688C}, //4211 #CJK UNIFIED IDEOGRAPH + {0x975F, 0x688D}, //4212 #CJK UNIFIED IDEOGRAPH + {0x9760, 0x688E}, //4213 #CJK UNIFIED IDEOGRAPH + {0x9761, 0x6890}, //4214 #CJK UNIFIED IDEOGRAPH + {0x9762, 0x6891}, //4215 #CJK UNIFIED IDEOGRAPH + {0x9763, 0x6892}, //4216 #CJK UNIFIED IDEOGRAPH + {0x9764, 0x6894}, //4217 #CJK UNIFIED IDEOGRAPH + {0x9765, 0x6895}, //4218 #CJK UNIFIED IDEOGRAPH + {0x9766, 0x6896}, //4219 #CJK UNIFIED IDEOGRAPH + {0x9767, 0x6898}, //4220 #CJK UNIFIED IDEOGRAPH + {0x9768, 0x6899}, //4221 #CJK UNIFIED IDEOGRAPH + {0x9769, 0x689A}, //4222 #CJK UNIFIED IDEOGRAPH + {0x976A, 0x689B}, //4223 #CJK UNIFIED IDEOGRAPH + {0x976B, 0x689C}, //4224 #CJK UNIFIED IDEOGRAPH + {0x976C, 0x689D}, //4225 #CJK UNIFIED IDEOGRAPH + {0x976D, 0x689E}, //4226 #CJK UNIFIED IDEOGRAPH + {0x976E, 0x689F}, //4227 #CJK UNIFIED IDEOGRAPH + {0x976F, 0x68A0}, //4228 #CJK UNIFIED IDEOGRAPH + {0x9770, 0x68A1}, //4229 #CJK UNIFIED IDEOGRAPH + {0x9771, 0x68A3}, //4230 #CJK UNIFIED IDEOGRAPH + {0x9772, 0x68A4}, //4231 #CJK UNIFIED IDEOGRAPH + {0x9773, 0x68A5}, //4232 #CJK UNIFIED IDEOGRAPH + {0x9774, 0x68A9}, //4233 #CJK UNIFIED IDEOGRAPH + {0x9775, 0x68AA}, //4234 #CJK UNIFIED IDEOGRAPH + {0x9776, 0x68AB}, //4235 #CJK UNIFIED IDEOGRAPH + {0x9777, 0x68AC}, //4236 #CJK UNIFIED IDEOGRAPH + {0x9778, 0x68AE}, //4237 #CJK UNIFIED IDEOGRAPH + {0x9779, 0x68B1}, //4238 #CJK UNIFIED IDEOGRAPH + {0x977A, 0x68B2}, //4239 #CJK UNIFIED IDEOGRAPH + {0x977B, 0x68B4}, //4240 #CJK UNIFIED IDEOGRAPH + {0x977C, 0x68B6}, //4241 #CJK UNIFIED IDEOGRAPH + {0x977D, 0x68B7}, //4242 #CJK UNIFIED IDEOGRAPH + {0x977E, 0x68B8}, //4243 #CJK UNIFIED IDEOGRAPH + {0x9780, 0x68B9}, //4244 #CJK UNIFIED IDEOGRAPH + {0x9781, 0x68BA}, //4245 #CJK UNIFIED IDEOGRAPH + {0x9782, 0x68BB}, //4246 #CJK UNIFIED IDEOGRAPH + {0x9783, 0x68BC}, //4247 #CJK UNIFIED IDEOGRAPH + {0x9784, 0x68BD}, //4248 #CJK UNIFIED IDEOGRAPH + {0x9785, 0x68BE}, //4249 #CJK UNIFIED IDEOGRAPH + {0x9786, 0x68BF}, //4250 #CJK UNIFIED IDEOGRAPH + {0x9787, 0x68C1}, //4251 #CJK UNIFIED IDEOGRAPH + {0x9788, 0x68C3}, //4252 #CJK UNIFIED IDEOGRAPH + {0x9789, 0x68C4}, //4253 #CJK UNIFIED IDEOGRAPH + {0x978A, 0x68C5}, //4254 #CJK UNIFIED IDEOGRAPH + {0x978B, 0x68C6}, //4255 #CJK UNIFIED IDEOGRAPH + {0x978C, 0x68C7}, //4256 #CJK UNIFIED IDEOGRAPH + {0x978D, 0x68C8}, //4257 #CJK UNIFIED IDEOGRAPH + {0x978E, 0x68CA}, //4258 #CJK UNIFIED IDEOGRAPH + {0x978F, 0x68CC}, //4259 #CJK UNIFIED IDEOGRAPH + {0x9790, 0x68CE}, //4260 #CJK UNIFIED IDEOGRAPH + {0x9791, 0x68CF}, //4261 #CJK UNIFIED IDEOGRAPH + {0x9792, 0x68D0}, //4262 #CJK UNIFIED IDEOGRAPH + {0x9793, 0x68D1}, //4263 #CJK UNIFIED IDEOGRAPH + {0x9794, 0x68D3}, //4264 #CJK UNIFIED IDEOGRAPH + {0x9795, 0x68D4}, //4265 #CJK UNIFIED IDEOGRAPH + {0x9796, 0x68D6}, //4266 #CJK UNIFIED IDEOGRAPH + {0x9797, 0x68D7}, //4267 #CJK UNIFIED IDEOGRAPH + {0x9798, 0x68D9}, //4268 #CJK UNIFIED IDEOGRAPH + {0x9799, 0x68DB}, //4269 #CJK UNIFIED IDEOGRAPH + {0x979A, 0x68DC}, //4270 #CJK UNIFIED IDEOGRAPH + {0x979B, 0x68DD}, //4271 #CJK UNIFIED IDEOGRAPH + {0x979C, 0x68DE}, //4272 #CJK UNIFIED IDEOGRAPH + {0x979D, 0x68DF}, //4273 #CJK UNIFIED IDEOGRAPH + {0x979E, 0x68E1}, //4274 #CJK UNIFIED IDEOGRAPH + {0x979F, 0x68E2}, //4275 #CJK UNIFIED IDEOGRAPH + {0x97A0, 0x68E4}, //4276 #CJK UNIFIED IDEOGRAPH + {0x97A1, 0x68E5}, //4277 #CJK UNIFIED IDEOGRAPH + {0x97A2, 0x68E6}, //4278 #CJK UNIFIED IDEOGRAPH + {0x97A3, 0x68E7}, //4279 #CJK UNIFIED IDEOGRAPH + {0x97A4, 0x68E8}, //4280 #CJK UNIFIED IDEOGRAPH + {0x97A5, 0x68E9}, //4281 #CJK UNIFIED IDEOGRAPH + {0x97A6, 0x68EA}, //4282 #CJK UNIFIED IDEOGRAPH + {0x97A7, 0x68EB}, //4283 #CJK UNIFIED IDEOGRAPH + {0x97A8, 0x68EC}, //4284 #CJK UNIFIED IDEOGRAPH + {0x97A9, 0x68ED}, //4285 #CJK UNIFIED IDEOGRAPH + {0x97AA, 0x68EF}, //4286 #CJK UNIFIED IDEOGRAPH + {0x97AB, 0x68F2}, //4287 #CJK UNIFIED IDEOGRAPH + {0x97AC, 0x68F3}, //4288 #CJK UNIFIED IDEOGRAPH + {0x97AD, 0x68F4}, //4289 #CJK UNIFIED IDEOGRAPH + {0x97AE, 0x68F6}, //4290 #CJK UNIFIED IDEOGRAPH + {0x97AF, 0x68F7}, //4291 #CJK UNIFIED IDEOGRAPH + {0x97B0, 0x68F8}, //4292 #CJK UNIFIED IDEOGRAPH + {0x97B1, 0x68FB}, //4293 #CJK UNIFIED IDEOGRAPH + {0x97B2, 0x68FD}, //4294 #CJK UNIFIED IDEOGRAPH + {0x97B3, 0x68FE}, //4295 #CJK UNIFIED IDEOGRAPH + {0x97B4, 0x68FF}, //4296 #CJK UNIFIED IDEOGRAPH + {0x97B5, 0x6900}, //4297 #CJK UNIFIED IDEOGRAPH + {0x97B6, 0x6902}, //4298 #CJK UNIFIED IDEOGRAPH + {0x97B7, 0x6903}, //4299 #CJK UNIFIED IDEOGRAPH + {0x97B8, 0x6904}, //4300 #CJK UNIFIED IDEOGRAPH + {0x97B9, 0x6906}, //4301 #CJK UNIFIED IDEOGRAPH + {0x97BA, 0x6907}, //4302 #CJK UNIFIED IDEOGRAPH + {0x97BB, 0x6908}, //4303 #CJK UNIFIED IDEOGRAPH + {0x97BC, 0x6909}, //4304 #CJK UNIFIED IDEOGRAPH + {0x97BD, 0x690A}, //4305 #CJK UNIFIED IDEOGRAPH + {0x97BE, 0x690C}, //4306 #CJK UNIFIED IDEOGRAPH + {0x97BF, 0x690F}, //4307 #CJK UNIFIED IDEOGRAPH + {0x97C0, 0x6911}, //4308 #CJK UNIFIED IDEOGRAPH + {0x97C1, 0x6913}, //4309 #CJK UNIFIED IDEOGRAPH + {0x97C2, 0x6914}, //4310 #CJK UNIFIED IDEOGRAPH + {0x97C3, 0x6915}, //4311 #CJK UNIFIED IDEOGRAPH + {0x97C4, 0x6916}, //4312 #CJK UNIFIED IDEOGRAPH + {0x97C5, 0x6917}, //4313 #CJK UNIFIED IDEOGRAPH + {0x97C6, 0x6918}, //4314 #CJK UNIFIED IDEOGRAPH + {0x97C7, 0x6919}, //4315 #CJK UNIFIED IDEOGRAPH + {0x97C8, 0x691A}, //4316 #CJK UNIFIED IDEOGRAPH + {0x97C9, 0x691B}, //4317 #CJK UNIFIED IDEOGRAPH + {0x97CA, 0x691C}, //4318 #CJK UNIFIED IDEOGRAPH + {0x97CB, 0x691D}, //4319 #CJK UNIFIED IDEOGRAPH + {0x97CC, 0x691E}, //4320 #CJK UNIFIED IDEOGRAPH + {0x97CD, 0x6921}, //4321 #CJK UNIFIED IDEOGRAPH + {0x97CE, 0x6922}, //4322 #CJK UNIFIED IDEOGRAPH + {0x97CF, 0x6923}, //4323 #CJK UNIFIED IDEOGRAPH + {0x97D0, 0x6925}, //4324 #CJK UNIFIED IDEOGRAPH + {0x97D1, 0x6926}, //4325 #CJK UNIFIED IDEOGRAPH + {0x97D2, 0x6927}, //4326 #CJK UNIFIED IDEOGRAPH + {0x97D3, 0x6928}, //4327 #CJK UNIFIED IDEOGRAPH + {0x97D4, 0x6929}, //4328 #CJK UNIFIED IDEOGRAPH + {0x97D5, 0x692A}, //4329 #CJK UNIFIED IDEOGRAPH + {0x97D6, 0x692B}, //4330 #CJK UNIFIED IDEOGRAPH + {0x97D7, 0x692C}, //4331 #CJK UNIFIED IDEOGRAPH + {0x97D8, 0x692E}, //4332 #CJK UNIFIED IDEOGRAPH + {0x97D9, 0x692F}, //4333 #CJK UNIFIED IDEOGRAPH + {0x97DA, 0x6931}, //4334 #CJK UNIFIED IDEOGRAPH + {0x97DB, 0x6932}, //4335 #CJK UNIFIED IDEOGRAPH + {0x97DC, 0x6933}, //4336 #CJK UNIFIED IDEOGRAPH + {0x97DD, 0x6935}, //4337 #CJK UNIFIED IDEOGRAPH + {0x97DE, 0x6936}, //4338 #CJK UNIFIED IDEOGRAPH + {0x97DF, 0x6937}, //4339 #CJK UNIFIED IDEOGRAPH + {0x97E0, 0x6938}, //4340 #CJK UNIFIED IDEOGRAPH + {0x97E1, 0x693A}, //4341 #CJK UNIFIED IDEOGRAPH + {0x97E2, 0x693B}, //4342 #CJK UNIFIED IDEOGRAPH + {0x97E3, 0x693C}, //4343 #CJK UNIFIED IDEOGRAPH + {0x97E4, 0x693E}, //4344 #CJK UNIFIED IDEOGRAPH + {0x97E5, 0x6940}, //4345 #CJK UNIFIED IDEOGRAPH + {0x97E6, 0x6941}, //4346 #CJK UNIFIED IDEOGRAPH + {0x97E7, 0x6943}, //4347 #CJK UNIFIED IDEOGRAPH + {0x97E8, 0x6944}, //4348 #CJK UNIFIED IDEOGRAPH + {0x97E9, 0x6945}, //4349 #CJK UNIFIED IDEOGRAPH + {0x97EA, 0x6946}, //4350 #CJK UNIFIED IDEOGRAPH + {0x97EB, 0x6947}, //4351 #CJK UNIFIED IDEOGRAPH + {0x97EC, 0x6948}, //4352 #CJK UNIFIED IDEOGRAPH + {0x97ED, 0x6949}, //4353 #CJK UNIFIED IDEOGRAPH + {0x97EE, 0x694A}, //4354 #CJK UNIFIED IDEOGRAPH + {0x97EF, 0x694B}, //4355 #CJK UNIFIED IDEOGRAPH + {0x97F0, 0x694C}, //4356 #CJK UNIFIED IDEOGRAPH + {0x97F1, 0x694D}, //4357 #CJK UNIFIED IDEOGRAPH + {0x97F2, 0x694E}, //4358 #CJK UNIFIED IDEOGRAPH + {0x97F3, 0x694F}, //4359 #CJK UNIFIED IDEOGRAPH + {0x97F4, 0x6950}, //4360 #CJK UNIFIED IDEOGRAPH + {0x97F5, 0x6951}, //4361 #CJK UNIFIED IDEOGRAPH + {0x97F6, 0x6952}, //4362 #CJK UNIFIED IDEOGRAPH + {0x97F7, 0x6953}, //4363 #CJK UNIFIED IDEOGRAPH + {0x97F8, 0x6955}, //4364 #CJK UNIFIED IDEOGRAPH + {0x97F9, 0x6956}, //4365 #CJK UNIFIED IDEOGRAPH + {0x97FA, 0x6958}, //4366 #CJK UNIFIED IDEOGRAPH + {0x97FB, 0x6959}, //4367 #CJK UNIFIED IDEOGRAPH + {0x97FC, 0x695B}, //4368 #CJK UNIFIED IDEOGRAPH + {0x97FD, 0x695C}, //4369 #CJK UNIFIED IDEOGRAPH + {0x97FE, 0x695F}, //4370 #CJK UNIFIED IDEOGRAPH + {0x9840, 0x6961}, //4371 #CJK UNIFIED IDEOGRAPH + {0x9841, 0x6962}, //4372 #CJK UNIFIED IDEOGRAPH + {0x9842, 0x6964}, //4373 #CJK UNIFIED IDEOGRAPH + {0x9843, 0x6965}, //4374 #CJK UNIFIED IDEOGRAPH + {0x9844, 0x6967}, //4375 #CJK UNIFIED IDEOGRAPH + {0x9845, 0x6968}, //4376 #CJK UNIFIED IDEOGRAPH + {0x9846, 0x6969}, //4377 #CJK UNIFIED IDEOGRAPH + {0x9847, 0x696A}, //4378 #CJK UNIFIED IDEOGRAPH + {0x9848, 0x696C}, //4379 #CJK UNIFIED IDEOGRAPH + {0x9849, 0x696D}, //4380 #CJK UNIFIED IDEOGRAPH + {0x984A, 0x696F}, //4381 #CJK UNIFIED IDEOGRAPH + {0x984B, 0x6970}, //4382 #CJK UNIFIED IDEOGRAPH + {0x984C, 0x6972}, //4383 #CJK UNIFIED IDEOGRAPH + {0x984D, 0x6973}, //4384 #CJK UNIFIED IDEOGRAPH + {0x984E, 0x6974}, //4385 #CJK UNIFIED IDEOGRAPH + {0x984F, 0x6975}, //4386 #CJK UNIFIED IDEOGRAPH + {0x9850, 0x6976}, //4387 #CJK UNIFIED IDEOGRAPH + {0x9851, 0x697A}, //4388 #CJK UNIFIED IDEOGRAPH + {0x9852, 0x697B}, //4389 #CJK UNIFIED IDEOGRAPH + {0x9853, 0x697D}, //4390 #CJK UNIFIED IDEOGRAPH + {0x9854, 0x697E}, //4391 #CJK UNIFIED IDEOGRAPH + {0x9855, 0x697F}, //4392 #CJK UNIFIED IDEOGRAPH + {0x9856, 0x6981}, //4393 #CJK UNIFIED IDEOGRAPH + {0x9857, 0x6983}, //4394 #CJK UNIFIED IDEOGRAPH + {0x9858, 0x6985}, //4395 #CJK UNIFIED IDEOGRAPH + {0x9859, 0x698A}, //4396 #CJK UNIFIED IDEOGRAPH + {0x985A, 0x698B}, //4397 #CJK UNIFIED IDEOGRAPH + {0x985B, 0x698C}, //4398 #CJK UNIFIED IDEOGRAPH + {0x985C, 0x698E}, //4399 #CJK UNIFIED IDEOGRAPH + {0x985D, 0x698F}, //4400 #CJK UNIFIED IDEOGRAPH + {0x985E, 0x6990}, //4401 #CJK UNIFIED IDEOGRAPH + {0x985F, 0x6991}, //4402 #CJK UNIFIED IDEOGRAPH + {0x9860, 0x6992}, //4403 #CJK UNIFIED IDEOGRAPH + {0x9861, 0x6993}, //4404 #CJK UNIFIED IDEOGRAPH + {0x9862, 0x6996}, //4405 #CJK UNIFIED IDEOGRAPH + {0x9863, 0x6997}, //4406 #CJK UNIFIED IDEOGRAPH + {0x9864, 0x6999}, //4407 #CJK UNIFIED IDEOGRAPH + {0x9865, 0x699A}, //4408 #CJK UNIFIED IDEOGRAPH + {0x9866, 0x699D}, //4409 #CJK UNIFIED IDEOGRAPH + {0x9867, 0x699E}, //4410 #CJK UNIFIED IDEOGRAPH + {0x9868, 0x699F}, //4411 #CJK UNIFIED IDEOGRAPH + {0x9869, 0x69A0}, //4412 #CJK UNIFIED IDEOGRAPH + {0x986A, 0x69A1}, //4413 #CJK UNIFIED IDEOGRAPH + {0x986B, 0x69A2}, //4414 #CJK UNIFIED IDEOGRAPH + {0x986C, 0x69A3}, //4415 #CJK UNIFIED IDEOGRAPH + {0x986D, 0x69A4}, //4416 #CJK UNIFIED IDEOGRAPH + {0x986E, 0x69A5}, //4417 #CJK UNIFIED IDEOGRAPH + {0x986F, 0x69A6}, //4418 #CJK UNIFIED IDEOGRAPH + {0x9870, 0x69A9}, //4419 #CJK UNIFIED IDEOGRAPH + {0x9871, 0x69AA}, //4420 #CJK UNIFIED IDEOGRAPH + {0x9872, 0x69AC}, //4421 #CJK UNIFIED IDEOGRAPH + {0x9873, 0x69AE}, //4422 #CJK UNIFIED IDEOGRAPH + {0x9874, 0x69AF}, //4423 #CJK UNIFIED IDEOGRAPH + {0x9875, 0x69B0}, //4424 #CJK UNIFIED IDEOGRAPH + {0x9876, 0x69B2}, //4425 #CJK UNIFIED IDEOGRAPH + {0x9877, 0x69B3}, //4426 #CJK UNIFIED IDEOGRAPH + {0x9878, 0x69B5}, //4427 #CJK UNIFIED IDEOGRAPH + {0x9879, 0x69B6}, //4428 #CJK UNIFIED IDEOGRAPH + {0x987A, 0x69B8}, //4429 #CJK UNIFIED IDEOGRAPH + {0x987B, 0x69B9}, //4430 #CJK UNIFIED IDEOGRAPH + {0x987C, 0x69BA}, //4431 #CJK UNIFIED IDEOGRAPH + {0x987D, 0x69BC}, //4432 #CJK UNIFIED IDEOGRAPH + {0x987E, 0x69BD}, //4433 #CJK UNIFIED IDEOGRAPH + {0x9880, 0x69BE}, //4434 #CJK UNIFIED IDEOGRAPH + {0x9881, 0x69BF}, //4435 #CJK UNIFIED IDEOGRAPH + {0x9882, 0x69C0}, //4436 #CJK UNIFIED IDEOGRAPH + {0x9883, 0x69C2}, //4437 #CJK UNIFIED IDEOGRAPH + {0x9884, 0x69C3}, //4438 #CJK UNIFIED IDEOGRAPH + {0x9885, 0x69C4}, //4439 #CJK UNIFIED IDEOGRAPH + {0x9886, 0x69C5}, //4440 #CJK UNIFIED IDEOGRAPH + {0x9887, 0x69C6}, //4441 #CJK UNIFIED IDEOGRAPH + {0x9888, 0x69C7}, //4442 #CJK UNIFIED IDEOGRAPH + {0x9889, 0x69C8}, //4443 #CJK UNIFIED IDEOGRAPH + {0x988A, 0x69C9}, //4444 #CJK UNIFIED IDEOGRAPH + {0x988B, 0x69CB}, //4445 #CJK UNIFIED IDEOGRAPH + {0x988C, 0x69CD}, //4446 #CJK UNIFIED IDEOGRAPH + {0x988D, 0x69CF}, //4447 #CJK UNIFIED IDEOGRAPH + {0x988E, 0x69D1}, //4448 #CJK UNIFIED IDEOGRAPH + {0x988F, 0x69D2}, //4449 #CJK UNIFIED IDEOGRAPH + {0x9890, 0x69D3}, //4450 #CJK UNIFIED IDEOGRAPH + {0x9891, 0x69D5}, //4451 #CJK UNIFIED IDEOGRAPH + {0x9892, 0x69D6}, //4452 #CJK UNIFIED IDEOGRAPH + {0x9893, 0x69D7}, //4453 #CJK UNIFIED IDEOGRAPH + {0x9894, 0x69D8}, //4454 #CJK UNIFIED IDEOGRAPH + {0x9895, 0x69D9}, //4455 #CJK UNIFIED IDEOGRAPH + {0x9896, 0x69DA}, //4456 #CJK UNIFIED IDEOGRAPH + {0x9897, 0x69DC}, //4457 #CJK UNIFIED IDEOGRAPH + {0x9898, 0x69DD}, //4458 #CJK UNIFIED IDEOGRAPH + {0x9899, 0x69DE}, //4459 #CJK UNIFIED IDEOGRAPH + {0x989A, 0x69E1}, //4460 #CJK UNIFIED IDEOGRAPH + {0x989B, 0x69E2}, //4461 #CJK UNIFIED IDEOGRAPH + {0x989C, 0x69E3}, //4462 #CJK UNIFIED IDEOGRAPH + {0x989D, 0x69E4}, //4463 #CJK UNIFIED IDEOGRAPH + {0x989E, 0x69E5}, //4464 #CJK UNIFIED IDEOGRAPH + {0x989F, 0x69E6}, //4465 #CJK UNIFIED IDEOGRAPH + {0x98A0, 0x69E7}, //4466 #CJK UNIFIED IDEOGRAPH + {0x98A1, 0x69E8}, //4467 #CJK UNIFIED IDEOGRAPH + {0x98A2, 0x69E9}, //4468 #CJK UNIFIED IDEOGRAPH + {0x98A3, 0x69EA}, //4469 #CJK UNIFIED IDEOGRAPH + {0x98A4, 0x69EB}, //4470 #CJK UNIFIED IDEOGRAPH + {0x98A5, 0x69EC}, //4471 #CJK UNIFIED IDEOGRAPH + {0x98A6, 0x69EE}, //4472 #CJK UNIFIED IDEOGRAPH + {0x98A7, 0x69EF}, //4473 #CJK UNIFIED IDEOGRAPH + {0x98A8, 0x69F0}, //4474 #CJK UNIFIED IDEOGRAPH + {0x98A9, 0x69F1}, //4475 #CJK UNIFIED IDEOGRAPH + {0x98AA, 0x69F3}, //4476 #CJK UNIFIED IDEOGRAPH + {0x98AB, 0x69F4}, //4477 #CJK UNIFIED IDEOGRAPH + {0x98AC, 0x69F5}, //4478 #CJK UNIFIED IDEOGRAPH + {0x98AD, 0x69F6}, //4479 #CJK UNIFIED IDEOGRAPH + {0x98AE, 0x69F7}, //4480 #CJK UNIFIED IDEOGRAPH + {0x98AF, 0x69F8}, //4481 #CJK UNIFIED IDEOGRAPH + {0x98B0, 0x69F9}, //4482 #CJK UNIFIED IDEOGRAPH + {0x98B1, 0x69FA}, //4483 #CJK UNIFIED IDEOGRAPH + {0x98B2, 0x69FB}, //4484 #CJK UNIFIED IDEOGRAPH + {0x98B3, 0x69FC}, //4485 #CJK UNIFIED IDEOGRAPH + {0x98B4, 0x69FE}, //4486 #CJK UNIFIED IDEOGRAPH + {0x98B5, 0x6A00}, //4487 #CJK UNIFIED IDEOGRAPH + {0x98B6, 0x6A01}, //4488 #CJK UNIFIED IDEOGRAPH + {0x98B7, 0x6A02}, //4489 #CJK UNIFIED IDEOGRAPH + {0x98B8, 0x6A03}, //4490 #CJK UNIFIED IDEOGRAPH + {0x98B9, 0x6A04}, //4491 #CJK UNIFIED IDEOGRAPH + {0x98BA, 0x6A05}, //4492 #CJK UNIFIED IDEOGRAPH + {0x98BB, 0x6A06}, //4493 #CJK UNIFIED IDEOGRAPH + {0x98BC, 0x6A07}, //4494 #CJK UNIFIED IDEOGRAPH + {0x98BD, 0x6A08}, //4495 #CJK UNIFIED IDEOGRAPH + {0x98BE, 0x6A09}, //4496 #CJK UNIFIED IDEOGRAPH + {0x98BF, 0x6A0B}, //4497 #CJK UNIFIED IDEOGRAPH + {0x98C0, 0x6A0C}, //4498 #CJK UNIFIED IDEOGRAPH + {0x98C1, 0x6A0D}, //4499 #CJK UNIFIED IDEOGRAPH + {0x98C2, 0x6A0E}, //4500 #CJK UNIFIED IDEOGRAPH + {0x98C3, 0x6A0F}, //4501 #CJK UNIFIED IDEOGRAPH + {0x98C4, 0x6A10}, //4502 #CJK UNIFIED IDEOGRAPH + {0x98C5, 0x6A11}, //4503 #CJK UNIFIED IDEOGRAPH + {0x98C6, 0x6A12}, //4504 #CJK UNIFIED IDEOGRAPH + {0x98C7, 0x6A13}, //4505 #CJK UNIFIED IDEOGRAPH + {0x98C8, 0x6A14}, //4506 #CJK UNIFIED IDEOGRAPH + {0x98C9, 0x6A15}, //4507 #CJK UNIFIED IDEOGRAPH + {0x98CA, 0x6A16}, //4508 #CJK UNIFIED IDEOGRAPH + {0x98CB, 0x6A19}, //4509 #CJK UNIFIED IDEOGRAPH + {0x98CC, 0x6A1A}, //4510 #CJK UNIFIED IDEOGRAPH + {0x98CD, 0x6A1B}, //4511 #CJK UNIFIED IDEOGRAPH + {0x98CE, 0x6A1C}, //4512 #CJK UNIFIED IDEOGRAPH + {0x98CF, 0x6A1D}, //4513 #CJK UNIFIED IDEOGRAPH + {0x98D0, 0x6A1E}, //4514 #CJK UNIFIED IDEOGRAPH + {0x98D1, 0x6A20}, //4515 #CJK UNIFIED IDEOGRAPH + {0x98D2, 0x6A22}, //4516 #CJK UNIFIED IDEOGRAPH + {0x98D3, 0x6A23}, //4517 #CJK UNIFIED IDEOGRAPH + {0x98D4, 0x6A24}, //4518 #CJK UNIFIED IDEOGRAPH + {0x98D5, 0x6A25}, //4519 #CJK UNIFIED IDEOGRAPH + {0x98D6, 0x6A26}, //4520 #CJK UNIFIED IDEOGRAPH + {0x98D7, 0x6A27}, //4521 #CJK UNIFIED IDEOGRAPH + {0x98D8, 0x6A29}, //4522 #CJK UNIFIED IDEOGRAPH + {0x98D9, 0x6A2B}, //4523 #CJK UNIFIED IDEOGRAPH + {0x98DA, 0x6A2C}, //4524 #CJK UNIFIED IDEOGRAPH + {0x98DB, 0x6A2D}, //4525 #CJK UNIFIED IDEOGRAPH + {0x98DC, 0x6A2E}, //4526 #CJK UNIFIED IDEOGRAPH + {0x98DD, 0x6A30}, //4527 #CJK UNIFIED IDEOGRAPH + {0x98DE, 0x6A32}, //4528 #CJK UNIFIED IDEOGRAPH + {0x98DF, 0x6A33}, //4529 #CJK UNIFIED IDEOGRAPH + {0x98E0, 0x6A34}, //4530 #CJK UNIFIED IDEOGRAPH + {0x98E1, 0x6A36}, //4531 #CJK UNIFIED IDEOGRAPH + {0x98E2, 0x6A37}, //4532 #CJK UNIFIED IDEOGRAPH + {0x98E3, 0x6A38}, //4533 #CJK UNIFIED IDEOGRAPH + {0x98E4, 0x6A39}, //4534 #CJK UNIFIED IDEOGRAPH + {0x98E5, 0x6A3A}, //4535 #CJK UNIFIED IDEOGRAPH + {0x98E6, 0x6A3B}, //4536 #CJK UNIFIED IDEOGRAPH + {0x98E7, 0x6A3C}, //4537 #CJK UNIFIED IDEOGRAPH + {0x98E8, 0x6A3F}, //4538 #CJK UNIFIED IDEOGRAPH + {0x98E9, 0x6A40}, //4539 #CJK UNIFIED IDEOGRAPH + {0x98EA, 0x6A41}, //4540 #CJK UNIFIED IDEOGRAPH + {0x98EB, 0x6A42}, //4541 #CJK UNIFIED IDEOGRAPH + {0x98EC, 0x6A43}, //4542 #CJK UNIFIED IDEOGRAPH + {0x98ED, 0x6A45}, //4543 #CJK UNIFIED IDEOGRAPH + {0x98EE, 0x6A46}, //4544 #CJK UNIFIED IDEOGRAPH + {0x98EF, 0x6A48}, //4545 #CJK UNIFIED IDEOGRAPH + {0x98F0, 0x6A49}, //4546 #CJK UNIFIED IDEOGRAPH + {0x98F1, 0x6A4A}, //4547 #CJK UNIFIED IDEOGRAPH + {0x98F2, 0x6A4B}, //4548 #CJK UNIFIED IDEOGRAPH + {0x98F3, 0x6A4C}, //4549 #CJK UNIFIED IDEOGRAPH + {0x98F4, 0x6A4D}, //4550 #CJK UNIFIED IDEOGRAPH + {0x98F5, 0x6A4E}, //4551 #CJK UNIFIED IDEOGRAPH + {0x98F6, 0x6A4F}, //4552 #CJK UNIFIED IDEOGRAPH + {0x98F7, 0x6A51}, //4553 #CJK UNIFIED IDEOGRAPH + {0x98F8, 0x6A52}, //4554 #CJK UNIFIED IDEOGRAPH + {0x98F9, 0x6A53}, //4555 #CJK UNIFIED IDEOGRAPH + {0x98FA, 0x6A54}, //4556 #CJK UNIFIED IDEOGRAPH + {0x98FB, 0x6A55}, //4557 #CJK UNIFIED IDEOGRAPH + {0x98FC, 0x6A56}, //4558 #CJK UNIFIED IDEOGRAPH + {0x98FD, 0x6A57}, //4559 #CJK UNIFIED IDEOGRAPH + {0x98FE, 0x6A5A}, //4560 #CJK UNIFIED IDEOGRAPH + {0x9940, 0x6A5C}, //4561 #CJK UNIFIED IDEOGRAPH + {0x9941, 0x6A5D}, //4562 #CJK UNIFIED IDEOGRAPH + {0x9942, 0x6A5E}, //4563 #CJK UNIFIED IDEOGRAPH + {0x9943, 0x6A5F}, //4564 #CJK UNIFIED IDEOGRAPH + {0x9944, 0x6A60}, //4565 #CJK UNIFIED IDEOGRAPH + {0x9945, 0x6A62}, //4566 #CJK UNIFIED IDEOGRAPH + {0x9946, 0x6A63}, //4567 #CJK UNIFIED IDEOGRAPH + {0x9947, 0x6A64}, //4568 #CJK UNIFIED IDEOGRAPH + {0x9948, 0x6A66}, //4569 #CJK UNIFIED IDEOGRAPH + {0x9949, 0x6A67}, //4570 #CJK UNIFIED IDEOGRAPH + {0x994A, 0x6A68}, //4571 #CJK UNIFIED IDEOGRAPH + {0x994B, 0x6A69}, //4572 #CJK UNIFIED IDEOGRAPH + {0x994C, 0x6A6A}, //4573 #CJK UNIFIED IDEOGRAPH + {0x994D, 0x6A6B}, //4574 #CJK UNIFIED IDEOGRAPH + {0x994E, 0x6A6C}, //4575 #CJK UNIFIED IDEOGRAPH + {0x994F, 0x6A6D}, //4576 #CJK UNIFIED IDEOGRAPH + {0x9950, 0x6A6E}, //4577 #CJK UNIFIED IDEOGRAPH + {0x9951, 0x6A6F}, //4578 #CJK UNIFIED IDEOGRAPH + {0x9952, 0x6A70}, //4579 #CJK UNIFIED IDEOGRAPH + {0x9953, 0x6A72}, //4580 #CJK UNIFIED IDEOGRAPH + {0x9954, 0x6A73}, //4581 #CJK UNIFIED IDEOGRAPH + {0x9955, 0x6A74}, //4582 #CJK UNIFIED IDEOGRAPH + {0x9956, 0x6A75}, //4583 #CJK UNIFIED IDEOGRAPH + {0x9957, 0x6A76}, //4584 #CJK UNIFIED IDEOGRAPH + {0x9958, 0x6A77}, //4585 #CJK UNIFIED IDEOGRAPH + {0x9959, 0x6A78}, //4586 #CJK UNIFIED IDEOGRAPH + {0x995A, 0x6A7A}, //4587 #CJK UNIFIED IDEOGRAPH + {0x995B, 0x6A7B}, //4588 #CJK UNIFIED IDEOGRAPH + {0x995C, 0x6A7D}, //4589 #CJK UNIFIED IDEOGRAPH + {0x995D, 0x6A7E}, //4590 #CJK UNIFIED IDEOGRAPH + {0x995E, 0x6A7F}, //4591 #CJK UNIFIED IDEOGRAPH + {0x995F, 0x6A81}, //4592 #CJK UNIFIED IDEOGRAPH + {0x9960, 0x6A82}, //4593 #CJK UNIFIED IDEOGRAPH + {0x9961, 0x6A83}, //4594 #CJK UNIFIED IDEOGRAPH + {0x9962, 0x6A85}, //4595 #CJK UNIFIED IDEOGRAPH + {0x9963, 0x6A86}, //4596 #CJK UNIFIED IDEOGRAPH + {0x9964, 0x6A87}, //4597 #CJK UNIFIED IDEOGRAPH + {0x9965, 0x6A88}, //4598 #CJK UNIFIED IDEOGRAPH + {0x9966, 0x6A89}, //4599 #CJK UNIFIED IDEOGRAPH + {0x9967, 0x6A8A}, //4600 #CJK UNIFIED IDEOGRAPH + {0x9968, 0x6A8B}, //4601 #CJK UNIFIED IDEOGRAPH + {0x9969, 0x6A8C}, //4602 #CJK UNIFIED IDEOGRAPH + {0x996A, 0x6A8D}, //4603 #CJK UNIFIED IDEOGRAPH + {0x996B, 0x6A8F}, //4604 #CJK UNIFIED IDEOGRAPH + {0x996C, 0x6A92}, //4605 #CJK UNIFIED IDEOGRAPH + {0x996D, 0x6A93}, //4606 #CJK UNIFIED IDEOGRAPH + {0x996E, 0x6A94}, //4607 #CJK UNIFIED IDEOGRAPH + {0x996F, 0x6A95}, //4608 #CJK UNIFIED IDEOGRAPH + {0x9970, 0x6A96}, //4609 #CJK UNIFIED IDEOGRAPH + {0x9971, 0x6A98}, //4610 #CJK UNIFIED IDEOGRAPH + {0x9972, 0x6A99}, //4611 #CJK UNIFIED IDEOGRAPH + {0x9973, 0x6A9A}, //4612 #CJK UNIFIED IDEOGRAPH + {0x9974, 0x6A9B}, //4613 #CJK UNIFIED IDEOGRAPH + {0x9975, 0x6A9C}, //4614 #CJK UNIFIED IDEOGRAPH + {0x9976, 0x6A9D}, //4615 #CJK UNIFIED IDEOGRAPH + {0x9977, 0x6A9E}, //4616 #CJK UNIFIED IDEOGRAPH + {0x9978, 0x6A9F}, //4617 #CJK UNIFIED IDEOGRAPH + {0x9979, 0x6AA1}, //4618 #CJK UNIFIED IDEOGRAPH + {0x997A, 0x6AA2}, //4619 #CJK UNIFIED IDEOGRAPH + {0x997B, 0x6AA3}, //4620 #CJK UNIFIED IDEOGRAPH + {0x997C, 0x6AA4}, //4621 #CJK UNIFIED IDEOGRAPH + {0x997D, 0x6AA5}, //4622 #CJK UNIFIED IDEOGRAPH + {0x997E, 0x6AA6}, //4623 #CJK UNIFIED IDEOGRAPH + {0x9980, 0x6AA7}, //4624 #CJK UNIFIED IDEOGRAPH + {0x9981, 0x6AA8}, //4625 #CJK UNIFIED IDEOGRAPH + {0x9982, 0x6AAA}, //4626 #CJK UNIFIED IDEOGRAPH + {0x9983, 0x6AAD}, //4627 #CJK UNIFIED IDEOGRAPH + {0x9984, 0x6AAE}, //4628 #CJK UNIFIED IDEOGRAPH + {0x9985, 0x6AAF}, //4629 #CJK UNIFIED IDEOGRAPH + {0x9986, 0x6AB0}, //4630 #CJK UNIFIED IDEOGRAPH + {0x9987, 0x6AB1}, //4631 #CJK UNIFIED IDEOGRAPH + {0x9988, 0x6AB2}, //4632 #CJK UNIFIED IDEOGRAPH + {0x9989, 0x6AB3}, //4633 #CJK UNIFIED IDEOGRAPH + {0x998A, 0x6AB4}, //4634 #CJK UNIFIED IDEOGRAPH + {0x998B, 0x6AB5}, //4635 #CJK UNIFIED IDEOGRAPH + {0x998C, 0x6AB6}, //4636 #CJK UNIFIED IDEOGRAPH + {0x998D, 0x6AB7}, //4637 #CJK UNIFIED IDEOGRAPH + {0x998E, 0x6AB8}, //4638 #CJK UNIFIED IDEOGRAPH + {0x998F, 0x6AB9}, //4639 #CJK UNIFIED IDEOGRAPH + {0x9990, 0x6ABA}, //4640 #CJK UNIFIED IDEOGRAPH + {0x9991, 0x6ABB}, //4641 #CJK UNIFIED IDEOGRAPH + {0x9992, 0x6ABC}, //4642 #CJK UNIFIED IDEOGRAPH + {0x9993, 0x6ABD}, //4643 #CJK UNIFIED IDEOGRAPH + {0x9994, 0x6ABE}, //4644 #CJK UNIFIED IDEOGRAPH + {0x9995, 0x6ABF}, //4645 #CJK UNIFIED IDEOGRAPH + {0x9996, 0x6AC0}, //4646 #CJK UNIFIED IDEOGRAPH + {0x9997, 0x6AC1}, //4647 #CJK UNIFIED IDEOGRAPH + {0x9998, 0x6AC2}, //4648 #CJK UNIFIED IDEOGRAPH + {0x9999, 0x6AC3}, //4649 #CJK UNIFIED IDEOGRAPH + {0x999A, 0x6AC4}, //4650 #CJK UNIFIED IDEOGRAPH + {0x999B, 0x6AC5}, //4651 #CJK UNIFIED IDEOGRAPH + {0x999C, 0x6AC6}, //4652 #CJK UNIFIED IDEOGRAPH + {0x999D, 0x6AC7}, //4653 #CJK UNIFIED IDEOGRAPH + {0x999E, 0x6AC8}, //4654 #CJK UNIFIED IDEOGRAPH + {0x999F, 0x6AC9}, //4655 #CJK UNIFIED IDEOGRAPH + {0x99A0, 0x6ACA}, //4656 #CJK UNIFIED IDEOGRAPH + {0x99A1, 0x6ACB}, //4657 #CJK UNIFIED IDEOGRAPH + {0x99A2, 0x6ACC}, //4658 #CJK UNIFIED IDEOGRAPH + {0x99A3, 0x6ACD}, //4659 #CJK UNIFIED IDEOGRAPH + {0x99A4, 0x6ACE}, //4660 #CJK UNIFIED IDEOGRAPH + {0x99A5, 0x6ACF}, //4661 #CJK UNIFIED IDEOGRAPH + {0x99A6, 0x6AD0}, //4662 #CJK UNIFIED IDEOGRAPH + {0x99A7, 0x6AD1}, //4663 #CJK UNIFIED IDEOGRAPH + {0x99A8, 0x6AD2}, //4664 #CJK UNIFIED IDEOGRAPH + {0x99A9, 0x6AD3}, //4665 #CJK UNIFIED IDEOGRAPH + {0x99AA, 0x6AD4}, //4666 #CJK UNIFIED IDEOGRAPH + {0x99AB, 0x6AD5}, //4667 #CJK UNIFIED IDEOGRAPH + {0x99AC, 0x6AD6}, //4668 #CJK UNIFIED IDEOGRAPH + {0x99AD, 0x6AD7}, //4669 #CJK UNIFIED IDEOGRAPH + {0x99AE, 0x6AD8}, //4670 #CJK UNIFIED IDEOGRAPH + {0x99AF, 0x6AD9}, //4671 #CJK UNIFIED IDEOGRAPH + {0x99B0, 0x6ADA}, //4672 #CJK UNIFIED IDEOGRAPH + {0x99B1, 0x6ADB}, //4673 #CJK UNIFIED IDEOGRAPH + {0x99B2, 0x6ADC}, //4674 #CJK UNIFIED IDEOGRAPH + {0x99B3, 0x6ADD}, //4675 #CJK UNIFIED IDEOGRAPH + {0x99B4, 0x6ADE}, //4676 #CJK UNIFIED IDEOGRAPH + {0x99B5, 0x6ADF}, //4677 #CJK UNIFIED IDEOGRAPH + {0x99B6, 0x6AE0}, //4678 #CJK UNIFIED IDEOGRAPH + {0x99B7, 0x6AE1}, //4679 #CJK UNIFIED IDEOGRAPH + {0x99B8, 0x6AE2}, //4680 #CJK UNIFIED IDEOGRAPH + {0x99B9, 0x6AE3}, //4681 #CJK UNIFIED IDEOGRAPH + {0x99BA, 0x6AE4}, //4682 #CJK UNIFIED IDEOGRAPH + {0x99BB, 0x6AE5}, //4683 #CJK UNIFIED IDEOGRAPH + {0x99BC, 0x6AE6}, //4684 #CJK UNIFIED IDEOGRAPH + {0x99BD, 0x6AE7}, //4685 #CJK UNIFIED IDEOGRAPH + {0x99BE, 0x6AE8}, //4686 #CJK UNIFIED IDEOGRAPH + {0x99BF, 0x6AE9}, //4687 #CJK UNIFIED IDEOGRAPH + {0x99C0, 0x6AEA}, //4688 #CJK UNIFIED IDEOGRAPH + {0x99C1, 0x6AEB}, //4689 #CJK UNIFIED IDEOGRAPH + {0x99C2, 0x6AEC}, //4690 #CJK UNIFIED IDEOGRAPH + {0x99C3, 0x6AED}, //4691 #CJK UNIFIED IDEOGRAPH + {0x99C4, 0x6AEE}, //4692 #CJK UNIFIED IDEOGRAPH + {0x99C5, 0x6AEF}, //4693 #CJK UNIFIED IDEOGRAPH + {0x99C6, 0x6AF0}, //4694 #CJK UNIFIED IDEOGRAPH + {0x99C7, 0x6AF1}, //4695 #CJK UNIFIED IDEOGRAPH + {0x99C8, 0x6AF2}, //4696 #CJK UNIFIED IDEOGRAPH + {0x99C9, 0x6AF3}, //4697 #CJK UNIFIED IDEOGRAPH + {0x99CA, 0x6AF4}, //4698 #CJK UNIFIED IDEOGRAPH + {0x99CB, 0x6AF5}, //4699 #CJK UNIFIED IDEOGRAPH + {0x99CC, 0x6AF6}, //4700 #CJK UNIFIED IDEOGRAPH + {0x99CD, 0x6AF7}, //4701 #CJK UNIFIED IDEOGRAPH + {0x99CE, 0x6AF8}, //4702 #CJK UNIFIED IDEOGRAPH + {0x99CF, 0x6AF9}, //4703 #CJK UNIFIED IDEOGRAPH + {0x99D0, 0x6AFA}, //4704 #CJK UNIFIED IDEOGRAPH + {0x99D1, 0x6AFB}, //4705 #CJK UNIFIED IDEOGRAPH + {0x99D2, 0x6AFC}, //4706 #CJK UNIFIED IDEOGRAPH + {0x99D3, 0x6AFD}, //4707 #CJK UNIFIED IDEOGRAPH + {0x99D4, 0x6AFE}, //4708 #CJK UNIFIED IDEOGRAPH + {0x99D5, 0x6AFF}, //4709 #CJK UNIFIED IDEOGRAPH + {0x99D6, 0x6B00}, //4710 #CJK UNIFIED IDEOGRAPH + {0x99D7, 0x6B01}, //4711 #CJK UNIFIED IDEOGRAPH + {0x99D8, 0x6B02}, //4712 #CJK UNIFIED IDEOGRAPH + {0x99D9, 0x6B03}, //4713 #CJK UNIFIED IDEOGRAPH + {0x99DA, 0x6B04}, //4714 #CJK UNIFIED IDEOGRAPH + {0x99DB, 0x6B05}, //4715 #CJK UNIFIED IDEOGRAPH + {0x99DC, 0x6B06}, //4716 #CJK UNIFIED IDEOGRAPH + {0x99DD, 0x6B07}, //4717 #CJK UNIFIED IDEOGRAPH + {0x99DE, 0x6B08}, //4718 #CJK UNIFIED IDEOGRAPH + {0x99DF, 0x6B09}, //4719 #CJK UNIFIED IDEOGRAPH + {0x99E0, 0x6B0A}, //4720 #CJK UNIFIED IDEOGRAPH + {0x99E1, 0x6B0B}, //4721 #CJK UNIFIED IDEOGRAPH + {0x99E2, 0x6B0C}, //4722 #CJK UNIFIED IDEOGRAPH + {0x99E3, 0x6B0D}, //4723 #CJK UNIFIED IDEOGRAPH + {0x99E4, 0x6B0E}, //4724 #CJK UNIFIED IDEOGRAPH + {0x99E5, 0x6B0F}, //4725 #CJK UNIFIED IDEOGRAPH + {0x99E6, 0x6B10}, //4726 #CJK UNIFIED IDEOGRAPH + {0x99E7, 0x6B11}, //4727 #CJK UNIFIED IDEOGRAPH + {0x99E8, 0x6B12}, //4728 #CJK UNIFIED IDEOGRAPH + {0x99E9, 0x6B13}, //4729 #CJK UNIFIED IDEOGRAPH + {0x99EA, 0x6B14}, //4730 #CJK UNIFIED IDEOGRAPH + {0x99EB, 0x6B15}, //4731 #CJK UNIFIED IDEOGRAPH + {0x99EC, 0x6B16}, //4732 #CJK UNIFIED IDEOGRAPH + {0x99ED, 0x6B17}, //4733 #CJK UNIFIED IDEOGRAPH + {0x99EE, 0x6B18}, //4734 #CJK UNIFIED IDEOGRAPH + {0x99EF, 0x6B19}, //4735 #CJK UNIFIED IDEOGRAPH + {0x99F0, 0x6B1A}, //4736 #CJK UNIFIED IDEOGRAPH + {0x99F1, 0x6B1B}, //4737 #CJK UNIFIED IDEOGRAPH + {0x99F2, 0x6B1C}, //4738 #CJK UNIFIED IDEOGRAPH + {0x99F3, 0x6B1D}, //4739 #CJK UNIFIED IDEOGRAPH + {0x99F4, 0x6B1E}, //4740 #CJK UNIFIED IDEOGRAPH + {0x99F5, 0x6B1F}, //4741 #CJK UNIFIED IDEOGRAPH + {0x99F6, 0x6B25}, //4742 #CJK UNIFIED IDEOGRAPH + {0x99F7, 0x6B26}, //4743 #CJK UNIFIED IDEOGRAPH + {0x99F8, 0x6B28}, //4744 #CJK UNIFIED IDEOGRAPH + {0x99F9, 0x6B29}, //4745 #CJK UNIFIED IDEOGRAPH + {0x99FA, 0x6B2A}, //4746 #CJK UNIFIED IDEOGRAPH + {0x99FB, 0x6B2B}, //4747 #CJK UNIFIED IDEOGRAPH + {0x99FC, 0x6B2C}, //4748 #CJK UNIFIED IDEOGRAPH + {0x99FD, 0x6B2D}, //4749 #CJK UNIFIED IDEOGRAPH + {0x99FE, 0x6B2E}, //4750 #CJK UNIFIED IDEOGRAPH + {0x9A40, 0x6B2F}, //4751 #CJK UNIFIED IDEOGRAPH + {0x9A41, 0x6B30}, //4752 #CJK UNIFIED IDEOGRAPH + {0x9A42, 0x6B31}, //4753 #CJK UNIFIED IDEOGRAPH + {0x9A43, 0x6B33}, //4754 #CJK UNIFIED IDEOGRAPH + {0x9A44, 0x6B34}, //4755 #CJK UNIFIED IDEOGRAPH + {0x9A45, 0x6B35}, //4756 #CJK UNIFIED IDEOGRAPH + {0x9A46, 0x6B36}, //4757 #CJK UNIFIED IDEOGRAPH + {0x9A47, 0x6B38}, //4758 #CJK UNIFIED IDEOGRAPH + {0x9A48, 0x6B3B}, //4759 #CJK UNIFIED IDEOGRAPH + {0x9A49, 0x6B3C}, //4760 #CJK UNIFIED IDEOGRAPH + {0x9A4A, 0x6B3D}, //4761 #CJK UNIFIED IDEOGRAPH + {0x9A4B, 0x6B3F}, //4762 #CJK UNIFIED IDEOGRAPH + {0x9A4C, 0x6B40}, //4763 #CJK UNIFIED IDEOGRAPH + {0x9A4D, 0x6B41}, //4764 #CJK UNIFIED IDEOGRAPH + {0x9A4E, 0x6B42}, //4765 #CJK UNIFIED IDEOGRAPH + {0x9A4F, 0x6B44}, //4766 #CJK UNIFIED IDEOGRAPH + {0x9A50, 0x6B45}, //4767 #CJK UNIFIED IDEOGRAPH + {0x9A51, 0x6B48}, //4768 #CJK UNIFIED IDEOGRAPH + {0x9A52, 0x6B4A}, //4769 #CJK UNIFIED IDEOGRAPH + {0x9A53, 0x6B4B}, //4770 #CJK UNIFIED IDEOGRAPH + {0x9A54, 0x6B4D}, //4771 #CJK UNIFIED IDEOGRAPH + {0x9A55, 0x6B4E}, //4772 #CJK UNIFIED IDEOGRAPH + {0x9A56, 0x6B4F}, //4773 #CJK UNIFIED IDEOGRAPH + {0x9A57, 0x6B50}, //4774 #CJK UNIFIED IDEOGRAPH + {0x9A58, 0x6B51}, //4775 #CJK UNIFIED IDEOGRAPH + {0x9A59, 0x6B52}, //4776 #CJK UNIFIED IDEOGRAPH + {0x9A5A, 0x6B53}, //4777 #CJK UNIFIED IDEOGRAPH + {0x9A5B, 0x6B54}, //4778 #CJK UNIFIED IDEOGRAPH + {0x9A5C, 0x6B55}, //4779 #CJK UNIFIED IDEOGRAPH + {0x9A5D, 0x6B56}, //4780 #CJK UNIFIED IDEOGRAPH + {0x9A5E, 0x6B57}, //4781 #CJK UNIFIED IDEOGRAPH + {0x9A5F, 0x6B58}, //4782 #CJK UNIFIED IDEOGRAPH + {0x9A60, 0x6B5A}, //4783 #CJK UNIFIED IDEOGRAPH + {0x9A61, 0x6B5B}, //4784 #CJK UNIFIED IDEOGRAPH + {0x9A62, 0x6B5C}, //4785 #CJK UNIFIED IDEOGRAPH + {0x9A63, 0x6B5D}, //4786 #CJK UNIFIED IDEOGRAPH + {0x9A64, 0x6B5E}, //4787 #CJK UNIFIED IDEOGRAPH + {0x9A65, 0x6B5F}, //4788 #CJK UNIFIED IDEOGRAPH + {0x9A66, 0x6B60}, //4789 #CJK UNIFIED IDEOGRAPH + {0x9A67, 0x6B61}, //4790 #CJK UNIFIED IDEOGRAPH + {0x9A68, 0x6B68}, //4791 #CJK UNIFIED IDEOGRAPH + {0x9A69, 0x6B69}, //4792 #CJK UNIFIED IDEOGRAPH + {0x9A6A, 0x6B6B}, //4793 #CJK UNIFIED IDEOGRAPH + {0x9A6B, 0x6B6C}, //4794 #CJK UNIFIED IDEOGRAPH + {0x9A6C, 0x6B6D}, //4795 #CJK UNIFIED IDEOGRAPH + {0x9A6D, 0x6B6E}, //4796 #CJK UNIFIED IDEOGRAPH + {0x9A6E, 0x6B6F}, //4797 #CJK UNIFIED IDEOGRAPH + {0x9A6F, 0x6B70}, //4798 #CJK UNIFIED IDEOGRAPH + {0x9A70, 0x6B71}, //4799 #CJK UNIFIED IDEOGRAPH + {0x9A71, 0x6B72}, //4800 #CJK UNIFIED IDEOGRAPH + {0x9A72, 0x6B73}, //4801 #CJK UNIFIED IDEOGRAPH + {0x9A73, 0x6B74}, //4802 #CJK UNIFIED IDEOGRAPH + {0x9A74, 0x6B75}, //4803 #CJK UNIFIED IDEOGRAPH + {0x9A75, 0x6B76}, //4804 #CJK UNIFIED IDEOGRAPH + {0x9A76, 0x6B77}, //4805 #CJK UNIFIED IDEOGRAPH + {0x9A77, 0x6B78}, //4806 #CJK UNIFIED IDEOGRAPH + {0x9A78, 0x6B7A}, //4807 #CJK UNIFIED IDEOGRAPH + {0x9A79, 0x6B7D}, //4808 #CJK UNIFIED IDEOGRAPH + {0x9A7A, 0x6B7E}, //4809 #CJK UNIFIED IDEOGRAPH + {0x9A7B, 0x6B7F}, //4810 #CJK UNIFIED IDEOGRAPH + {0x9A7C, 0x6B80}, //4811 #CJK UNIFIED IDEOGRAPH + {0x9A7D, 0x6B85}, //4812 #CJK UNIFIED IDEOGRAPH + {0x9A7E, 0x6B88}, //4813 #CJK UNIFIED IDEOGRAPH + {0x9A80, 0x6B8C}, //4814 #CJK UNIFIED IDEOGRAPH + {0x9A81, 0x6B8E}, //4815 #CJK UNIFIED IDEOGRAPH + {0x9A82, 0x6B8F}, //4816 #CJK UNIFIED IDEOGRAPH + {0x9A83, 0x6B90}, //4817 #CJK UNIFIED IDEOGRAPH + {0x9A84, 0x6B91}, //4818 #CJK UNIFIED IDEOGRAPH + {0x9A85, 0x6B94}, //4819 #CJK UNIFIED IDEOGRAPH + {0x9A86, 0x6B95}, //4820 #CJK UNIFIED IDEOGRAPH + {0x9A87, 0x6B97}, //4821 #CJK UNIFIED IDEOGRAPH + {0x9A88, 0x6B98}, //4822 #CJK UNIFIED IDEOGRAPH + {0x9A89, 0x6B99}, //4823 #CJK UNIFIED IDEOGRAPH + {0x9A8A, 0x6B9C}, //4824 #CJK UNIFIED IDEOGRAPH + {0x9A8B, 0x6B9D}, //4825 #CJK UNIFIED IDEOGRAPH + {0x9A8C, 0x6B9E}, //4826 #CJK UNIFIED IDEOGRAPH + {0x9A8D, 0x6B9F}, //4827 #CJK UNIFIED IDEOGRAPH + {0x9A8E, 0x6BA0}, //4828 #CJK UNIFIED IDEOGRAPH + {0x9A8F, 0x6BA2}, //4829 #CJK UNIFIED IDEOGRAPH + {0x9A90, 0x6BA3}, //4830 #CJK UNIFIED IDEOGRAPH + {0x9A91, 0x6BA4}, //4831 #CJK UNIFIED IDEOGRAPH + {0x9A92, 0x6BA5}, //4832 #CJK UNIFIED IDEOGRAPH + {0x9A93, 0x6BA6}, //4833 #CJK UNIFIED IDEOGRAPH + {0x9A94, 0x6BA7}, //4834 #CJK UNIFIED IDEOGRAPH + {0x9A95, 0x6BA8}, //4835 #CJK UNIFIED IDEOGRAPH + {0x9A96, 0x6BA9}, //4836 #CJK UNIFIED IDEOGRAPH + {0x9A97, 0x6BAB}, //4837 #CJK UNIFIED IDEOGRAPH + {0x9A98, 0x6BAC}, //4838 #CJK UNIFIED IDEOGRAPH + {0x9A99, 0x6BAD}, //4839 #CJK UNIFIED IDEOGRAPH + {0x9A9A, 0x6BAE}, //4840 #CJK UNIFIED IDEOGRAPH + {0x9A9B, 0x6BAF}, //4841 #CJK UNIFIED IDEOGRAPH + {0x9A9C, 0x6BB0}, //4842 #CJK UNIFIED IDEOGRAPH + {0x9A9D, 0x6BB1}, //4843 #CJK UNIFIED IDEOGRAPH + {0x9A9E, 0x6BB2}, //4844 #CJK UNIFIED IDEOGRAPH + {0x9A9F, 0x6BB6}, //4845 #CJK UNIFIED IDEOGRAPH + {0x9AA0, 0x6BB8}, //4846 #CJK UNIFIED IDEOGRAPH + {0x9AA1, 0x6BB9}, //4847 #CJK UNIFIED IDEOGRAPH + {0x9AA2, 0x6BBA}, //4848 #CJK UNIFIED IDEOGRAPH + {0x9AA3, 0x6BBB}, //4849 #CJK UNIFIED IDEOGRAPH + {0x9AA4, 0x6BBC}, //4850 #CJK UNIFIED IDEOGRAPH + {0x9AA5, 0x6BBD}, //4851 #CJK UNIFIED IDEOGRAPH + {0x9AA6, 0x6BBE}, //4852 #CJK UNIFIED IDEOGRAPH + {0x9AA7, 0x6BC0}, //4853 #CJK UNIFIED IDEOGRAPH + {0x9AA8, 0x6BC3}, //4854 #CJK UNIFIED IDEOGRAPH + {0x9AA9, 0x6BC4}, //4855 #CJK UNIFIED IDEOGRAPH + {0x9AAA, 0x6BC6}, //4856 #CJK UNIFIED IDEOGRAPH + {0x9AAB, 0x6BC7}, //4857 #CJK UNIFIED IDEOGRAPH + {0x9AAC, 0x6BC8}, //4858 #CJK UNIFIED IDEOGRAPH + {0x9AAD, 0x6BC9}, //4859 #CJK UNIFIED IDEOGRAPH + {0x9AAE, 0x6BCA}, //4860 #CJK UNIFIED IDEOGRAPH + {0x9AAF, 0x6BCC}, //4861 #CJK UNIFIED IDEOGRAPH + {0x9AB0, 0x6BCE}, //4862 #CJK UNIFIED IDEOGRAPH + {0x9AB1, 0x6BD0}, //4863 #CJK UNIFIED IDEOGRAPH + {0x9AB2, 0x6BD1}, //4864 #CJK UNIFIED IDEOGRAPH + {0x9AB3, 0x6BD8}, //4865 #CJK UNIFIED IDEOGRAPH + {0x9AB4, 0x6BDA}, //4866 #CJK UNIFIED IDEOGRAPH + {0x9AB5, 0x6BDC}, //4867 #CJK UNIFIED IDEOGRAPH + {0x9AB6, 0x6BDD}, //4868 #CJK UNIFIED IDEOGRAPH + {0x9AB7, 0x6BDE}, //4869 #CJK UNIFIED IDEOGRAPH + {0x9AB8, 0x6BDF}, //4870 #CJK UNIFIED IDEOGRAPH + {0x9AB9, 0x6BE0}, //4871 #CJK UNIFIED IDEOGRAPH + {0x9ABA, 0x6BE2}, //4872 #CJK UNIFIED IDEOGRAPH + {0x9ABB, 0x6BE3}, //4873 #CJK UNIFIED IDEOGRAPH + {0x9ABC, 0x6BE4}, //4874 #CJK UNIFIED IDEOGRAPH + {0x9ABD, 0x6BE5}, //4875 #CJK UNIFIED IDEOGRAPH + {0x9ABE, 0x6BE6}, //4876 #CJK UNIFIED IDEOGRAPH + {0x9ABF, 0x6BE7}, //4877 #CJK UNIFIED IDEOGRAPH + {0x9AC0, 0x6BE8}, //4878 #CJK UNIFIED IDEOGRAPH + {0x9AC1, 0x6BE9}, //4879 #CJK UNIFIED IDEOGRAPH + {0x9AC2, 0x6BEC}, //4880 #CJK UNIFIED IDEOGRAPH + {0x9AC3, 0x6BED}, //4881 #CJK UNIFIED IDEOGRAPH + {0x9AC4, 0x6BEE}, //4882 #CJK UNIFIED IDEOGRAPH + {0x9AC5, 0x6BF0}, //4883 #CJK UNIFIED IDEOGRAPH + {0x9AC6, 0x6BF1}, //4884 #CJK UNIFIED IDEOGRAPH + {0x9AC7, 0x6BF2}, //4885 #CJK UNIFIED IDEOGRAPH + {0x9AC8, 0x6BF4}, //4886 #CJK UNIFIED IDEOGRAPH + {0x9AC9, 0x6BF6}, //4887 #CJK UNIFIED IDEOGRAPH + {0x9ACA, 0x6BF7}, //4888 #CJK UNIFIED IDEOGRAPH + {0x9ACB, 0x6BF8}, //4889 #CJK UNIFIED IDEOGRAPH + {0x9ACC, 0x6BFA}, //4890 #CJK UNIFIED IDEOGRAPH + {0x9ACD, 0x6BFB}, //4891 #CJK UNIFIED IDEOGRAPH + {0x9ACE, 0x6BFC}, //4892 #CJK UNIFIED IDEOGRAPH + {0x9ACF, 0x6BFE}, //4893 #CJK UNIFIED IDEOGRAPH + {0x9AD0, 0x6BFF}, //4894 #CJK UNIFIED IDEOGRAPH + {0x9AD1, 0x6C00}, //4895 #CJK UNIFIED IDEOGRAPH + {0x9AD2, 0x6C01}, //4896 #CJK UNIFIED IDEOGRAPH + {0x9AD3, 0x6C02}, //4897 #CJK UNIFIED IDEOGRAPH + {0x9AD4, 0x6C03}, //4898 #CJK UNIFIED IDEOGRAPH + {0x9AD5, 0x6C04}, //4899 #CJK UNIFIED IDEOGRAPH + {0x9AD6, 0x6C08}, //4900 #CJK UNIFIED IDEOGRAPH + {0x9AD7, 0x6C09}, //4901 #CJK UNIFIED IDEOGRAPH + {0x9AD8, 0x6C0A}, //4902 #CJK UNIFIED IDEOGRAPH + {0x9AD9, 0x6C0B}, //4903 #CJK UNIFIED IDEOGRAPH + {0x9ADA, 0x6C0C}, //4904 #CJK UNIFIED IDEOGRAPH + {0x9ADB, 0x6C0E}, //4905 #CJK UNIFIED IDEOGRAPH + {0x9ADC, 0x6C12}, //4906 #CJK UNIFIED IDEOGRAPH + {0x9ADD, 0x6C17}, //4907 #CJK UNIFIED IDEOGRAPH + {0x9ADE, 0x6C1C}, //4908 #CJK UNIFIED IDEOGRAPH + {0x9ADF, 0x6C1D}, //4909 #CJK UNIFIED IDEOGRAPH + {0x9AE0, 0x6C1E}, //4910 #CJK UNIFIED IDEOGRAPH + {0x9AE1, 0x6C20}, //4911 #CJK UNIFIED IDEOGRAPH + {0x9AE2, 0x6C23}, //4912 #CJK UNIFIED IDEOGRAPH + {0x9AE3, 0x6C25}, //4913 #CJK UNIFIED IDEOGRAPH + {0x9AE4, 0x6C2B}, //4914 #CJK UNIFIED IDEOGRAPH + {0x9AE5, 0x6C2C}, //4915 #CJK UNIFIED IDEOGRAPH + {0x9AE6, 0x6C2D}, //4916 #CJK UNIFIED IDEOGRAPH + {0x9AE7, 0x6C31}, //4917 #CJK UNIFIED IDEOGRAPH + {0x9AE8, 0x6C33}, //4918 #CJK UNIFIED IDEOGRAPH + {0x9AE9, 0x6C36}, //4919 #CJK UNIFIED IDEOGRAPH + {0x9AEA, 0x6C37}, //4920 #CJK UNIFIED IDEOGRAPH + {0x9AEB, 0x6C39}, //4921 #CJK UNIFIED IDEOGRAPH + {0x9AEC, 0x6C3A}, //4922 #CJK UNIFIED IDEOGRAPH + {0x9AED, 0x6C3B}, //4923 #CJK UNIFIED IDEOGRAPH + {0x9AEE, 0x6C3C}, //4924 #CJK UNIFIED IDEOGRAPH + {0x9AEF, 0x6C3E}, //4925 #CJK UNIFIED IDEOGRAPH + {0x9AF0, 0x6C3F}, //4926 #CJK UNIFIED IDEOGRAPH + {0x9AF1, 0x6C43}, //4927 #CJK UNIFIED IDEOGRAPH + {0x9AF2, 0x6C44}, //4928 #CJK UNIFIED IDEOGRAPH + {0x9AF3, 0x6C45}, //4929 #CJK UNIFIED IDEOGRAPH + {0x9AF4, 0x6C48}, //4930 #CJK UNIFIED IDEOGRAPH + {0x9AF5, 0x6C4B}, //4931 #CJK UNIFIED IDEOGRAPH + {0x9AF6, 0x6C4C}, //4932 #CJK UNIFIED IDEOGRAPH + {0x9AF7, 0x6C4D}, //4933 #CJK UNIFIED IDEOGRAPH + {0x9AF8, 0x6C4E}, //4934 #CJK UNIFIED IDEOGRAPH + {0x9AF9, 0x6C4F}, //4935 #CJK UNIFIED IDEOGRAPH + {0x9AFA, 0x6C51}, //4936 #CJK UNIFIED IDEOGRAPH + {0x9AFB, 0x6C52}, //4937 #CJK UNIFIED IDEOGRAPH + {0x9AFC, 0x6C53}, //4938 #CJK UNIFIED IDEOGRAPH + {0x9AFD, 0x6C56}, //4939 #CJK UNIFIED IDEOGRAPH + {0x9AFE, 0x6C58}, //4940 #CJK UNIFIED IDEOGRAPH + {0x9B40, 0x6C59}, //4941 #CJK UNIFIED IDEOGRAPH + {0x9B41, 0x6C5A}, //4942 #CJK UNIFIED IDEOGRAPH + {0x9B42, 0x6C62}, //4943 #CJK UNIFIED IDEOGRAPH + {0x9B43, 0x6C63}, //4944 #CJK UNIFIED IDEOGRAPH + {0x9B44, 0x6C65}, //4945 #CJK UNIFIED IDEOGRAPH + {0x9B45, 0x6C66}, //4946 #CJK UNIFIED IDEOGRAPH + {0x9B46, 0x6C67}, //4947 #CJK UNIFIED IDEOGRAPH + {0x9B47, 0x6C6B}, //4948 #CJK UNIFIED IDEOGRAPH + {0x9B48, 0x6C6C}, //4949 #CJK UNIFIED IDEOGRAPH + {0x9B49, 0x6C6D}, //4950 #CJK UNIFIED IDEOGRAPH + {0x9B4A, 0x6C6E}, //4951 #CJK UNIFIED IDEOGRAPH + {0x9B4B, 0x6C6F}, //4952 #CJK UNIFIED IDEOGRAPH + {0x9B4C, 0x6C71}, //4953 #CJK UNIFIED IDEOGRAPH + {0x9B4D, 0x6C73}, //4954 #CJK UNIFIED IDEOGRAPH + {0x9B4E, 0x6C75}, //4955 #CJK UNIFIED IDEOGRAPH + {0x9B4F, 0x6C77}, //4956 #CJK UNIFIED IDEOGRAPH + {0x9B50, 0x6C78}, //4957 #CJK UNIFIED IDEOGRAPH + {0x9B51, 0x6C7A}, //4958 #CJK UNIFIED IDEOGRAPH + {0x9B52, 0x6C7B}, //4959 #CJK UNIFIED IDEOGRAPH + {0x9B53, 0x6C7C}, //4960 #CJK UNIFIED IDEOGRAPH + {0x9B54, 0x6C7F}, //4961 #CJK UNIFIED IDEOGRAPH + {0x9B55, 0x6C80}, //4962 #CJK UNIFIED IDEOGRAPH + {0x9B56, 0x6C84}, //4963 #CJK UNIFIED IDEOGRAPH + {0x9B57, 0x6C87}, //4964 #CJK UNIFIED IDEOGRAPH + {0x9B58, 0x6C8A}, //4965 #CJK UNIFIED IDEOGRAPH + {0x9B59, 0x6C8B}, //4966 #CJK UNIFIED IDEOGRAPH + {0x9B5A, 0x6C8D}, //4967 #CJK UNIFIED IDEOGRAPH + {0x9B5B, 0x6C8E}, //4968 #CJK UNIFIED IDEOGRAPH + {0x9B5C, 0x6C91}, //4969 #CJK UNIFIED IDEOGRAPH + {0x9B5D, 0x6C92}, //4970 #CJK UNIFIED IDEOGRAPH + {0x9B5E, 0x6C95}, //4971 #CJK UNIFIED IDEOGRAPH + {0x9B5F, 0x6C96}, //4972 #CJK UNIFIED IDEOGRAPH + {0x9B60, 0x6C97}, //4973 #CJK UNIFIED IDEOGRAPH + {0x9B61, 0x6C98}, //4974 #CJK UNIFIED IDEOGRAPH + {0x9B62, 0x6C9A}, //4975 #CJK UNIFIED IDEOGRAPH + {0x9B63, 0x6C9C}, //4976 #CJK UNIFIED IDEOGRAPH + {0x9B64, 0x6C9D}, //4977 #CJK UNIFIED IDEOGRAPH + {0x9B65, 0x6C9E}, //4978 #CJK UNIFIED IDEOGRAPH + {0x9B66, 0x6CA0}, //4979 #CJK UNIFIED IDEOGRAPH + {0x9B67, 0x6CA2}, //4980 #CJK UNIFIED IDEOGRAPH + {0x9B68, 0x6CA8}, //4981 #CJK UNIFIED IDEOGRAPH + {0x9B69, 0x6CAC}, //4982 #CJK UNIFIED IDEOGRAPH + {0x9B6A, 0x6CAF}, //4983 #CJK UNIFIED IDEOGRAPH + {0x9B6B, 0x6CB0}, //4984 #CJK UNIFIED IDEOGRAPH + {0x9B6C, 0x6CB4}, //4985 #CJK UNIFIED IDEOGRAPH + {0x9B6D, 0x6CB5}, //4986 #CJK UNIFIED IDEOGRAPH + {0x9B6E, 0x6CB6}, //4987 #CJK UNIFIED IDEOGRAPH + {0x9B6F, 0x6CB7}, //4988 #CJK UNIFIED IDEOGRAPH + {0x9B70, 0x6CBA}, //4989 #CJK UNIFIED IDEOGRAPH + {0x9B71, 0x6CC0}, //4990 #CJK UNIFIED IDEOGRAPH + {0x9B72, 0x6CC1}, //4991 #CJK UNIFIED IDEOGRAPH + {0x9B73, 0x6CC2}, //4992 #CJK UNIFIED IDEOGRAPH + {0x9B74, 0x6CC3}, //4993 #CJK UNIFIED IDEOGRAPH + {0x9B75, 0x6CC6}, //4994 #CJK UNIFIED IDEOGRAPH + {0x9B76, 0x6CC7}, //4995 #CJK UNIFIED IDEOGRAPH + {0x9B77, 0x6CC8}, //4996 #CJK UNIFIED IDEOGRAPH + {0x9B78, 0x6CCB}, //4997 #CJK UNIFIED IDEOGRAPH + {0x9B79, 0x6CCD}, //4998 #CJK UNIFIED IDEOGRAPH + {0x9B7A, 0x6CCE}, //4999 #CJK UNIFIED IDEOGRAPH + {0x9B7B, 0x6CCF}, //5000 #CJK UNIFIED IDEOGRAPH + {0x9B7C, 0x6CD1}, //5001 #CJK UNIFIED IDEOGRAPH + {0x9B7D, 0x6CD2}, //5002 #CJK UNIFIED IDEOGRAPH + {0x9B7E, 0x6CD8}, //5003 #CJK UNIFIED IDEOGRAPH + {0x9B80, 0x6CD9}, //5004 #CJK UNIFIED IDEOGRAPH + {0x9B81, 0x6CDA}, //5005 #CJK UNIFIED IDEOGRAPH + {0x9B82, 0x6CDC}, //5006 #CJK UNIFIED IDEOGRAPH + {0x9B83, 0x6CDD}, //5007 #CJK UNIFIED IDEOGRAPH + {0x9B84, 0x6CDF}, //5008 #CJK UNIFIED IDEOGRAPH + {0x9B85, 0x6CE4}, //5009 #CJK UNIFIED IDEOGRAPH + {0x9B86, 0x6CE6}, //5010 #CJK UNIFIED IDEOGRAPH + {0x9B87, 0x6CE7}, //5011 #CJK UNIFIED IDEOGRAPH + {0x9B88, 0x6CE9}, //5012 #CJK UNIFIED IDEOGRAPH + {0x9B89, 0x6CEC}, //5013 #CJK UNIFIED IDEOGRAPH + {0x9B8A, 0x6CED}, //5014 #CJK UNIFIED IDEOGRAPH + {0x9B8B, 0x6CF2}, //5015 #CJK UNIFIED IDEOGRAPH + {0x9B8C, 0x6CF4}, //5016 #CJK UNIFIED IDEOGRAPH + {0x9B8D, 0x6CF9}, //5017 #CJK UNIFIED IDEOGRAPH + {0x9B8E, 0x6CFF}, //5018 #CJK UNIFIED IDEOGRAPH + {0x9B8F, 0x6D00}, //5019 #CJK UNIFIED IDEOGRAPH + {0x9B90, 0x6D02}, //5020 #CJK UNIFIED IDEOGRAPH + {0x9B91, 0x6D03}, //5021 #CJK UNIFIED IDEOGRAPH + {0x9B92, 0x6D05}, //5022 #CJK UNIFIED IDEOGRAPH + {0x9B93, 0x6D06}, //5023 #CJK UNIFIED IDEOGRAPH + {0x9B94, 0x6D08}, //5024 #CJK UNIFIED IDEOGRAPH + {0x9B95, 0x6D09}, //5025 #CJK UNIFIED IDEOGRAPH + {0x9B96, 0x6D0A}, //5026 #CJK UNIFIED IDEOGRAPH + {0x9B97, 0x6D0D}, //5027 #CJK UNIFIED IDEOGRAPH + {0x9B98, 0x6D0F}, //5028 #CJK UNIFIED IDEOGRAPH + {0x9B99, 0x6D10}, //5029 #CJK UNIFIED IDEOGRAPH + {0x9B9A, 0x6D11}, //5030 #CJK UNIFIED IDEOGRAPH + {0x9B9B, 0x6D13}, //5031 #CJK UNIFIED IDEOGRAPH + {0x9B9C, 0x6D14}, //5032 #CJK UNIFIED IDEOGRAPH + {0x9B9D, 0x6D15}, //5033 #CJK UNIFIED IDEOGRAPH + {0x9B9E, 0x6D16}, //5034 #CJK UNIFIED IDEOGRAPH + {0x9B9F, 0x6D18}, //5035 #CJK UNIFIED IDEOGRAPH + {0x9BA0, 0x6D1C}, //5036 #CJK UNIFIED IDEOGRAPH + {0x9BA1, 0x6D1D}, //5037 #CJK UNIFIED IDEOGRAPH + {0x9BA2, 0x6D1F}, //5038 #CJK UNIFIED IDEOGRAPH + {0x9BA3, 0x6D20}, //5039 #CJK UNIFIED IDEOGRAPH + {0x9BA4, 0x6D21}, //5040 #CJK UNIFIED IDEOGRAPH + {0x9BA5, 0x6D22}, //5041 #CJK UNIFIED IDEOGRAPH + {0x9BA6, 0x6D23}, //5042 #CJK UNIFIED IDEOGRAPH + {0x9BA7, 0x6D24}, //5043 #CJK UNIFIED IDEOGRAPH + {0x9BA8, 0x6D26}, //5044 #CJK UNIFIED IDEOGRAPH + {0x9BA9, 0x6D28}, //5045 #CJK UNIFIED IDEOGRAPH + {0x9BAA, 0x6D29}, //5046 #CJK UNIFIED IDEOGRAPH + {0x9BAB, 0x6D2C}, //5047 #CJK UNIFIED IDEOGRAPH + {0x9BAC, 0x6D2D}, //5048 #CJK UNIFIED IDEOGRAPH + {0x9BAD, 0x6D2F}, //5049 #CJK UNIFIED IDEOGRAPH + {0x9BAE, 0x6D30}, //5050 #CJK UNIFIED IDEOGRAPH + {0x9BAF, 0x6D34}, //5051 #CJK UNIFIED IDEOGRAPH + {0x9BB0, 0x6D36}, //5052 #CJK UNIFIED IDEOGRAPH + {0x9BB1, 0x6D37}, //5053 #CJK UNIFIED IDEOGRAPH + {0x9BB2, 0x6D38}, //5054 #CJK UNIFIED IDEOGRAPH + {0x9BB3, 0x6D3A}, //5055 #CJK UNIFIED IDEOGRAPH + {0x9BB4, 0x6D3F}, //5056 #CJK UNIFIED IDEOGRAPH + {0x9BB5, 0x6D40}, //5057 #CJK UNIFIED IDEOGRAPH + {0x9BB6, 0x6D42}, //5058 #CJK UNIFIED IDEOGRAPH + {0x9BB7, 0x6D44}, //5059 #CJK UNIFIED IDEOGRAPH + {0x9BB8, 0x6D49}, //5060 #CJK UNIFIED IDEOGRAPH + {0x9BB9, 0x6D4C}, //5061 #CJK UNIFIED IDEOGRAPH + {0x9BBA, 0x6D50}, //5062 #CJK UNIFIED IDEOGRAPH + {0x9BBB, 0x6D55}, //5063 #CJK UNIFIED IDEOGRAPH + {0x9BBC, 0x6D56}, //5064 #CJK UNIFIED IDEOGRAPH + {0x9BBD, 0x6D57}, //5065 #CJK UNIFIED IDEOGRAPH + {0x9BBE, 0x6D58}, //5066 #CJK UNIFIED IDEOGRAPH + {0x9BBF, 0x6D5B}, //5067 #CJK UNIFIED IDEOGRAPH + {0x9BC0, 0x6D5D}, //5068 #CJK UNIFIED IDEOGRAPH + {0x9BC1, 0x6D5F}, //5069 #CJK UNIFIED IDEOGRAPH + {0x9BC2, 0x6D61}, //5070 #CJK UNIFIED IDEOGRAPH + {0x9BC3, 0x6D62}, //5071 #CJK UNIFIED IDEOGRAPH + {0x9BC4, 0x6D64}, //5072 #CJK UNIFIED IDEOGRAPH + {0x9BC5, 0x6D65}, //5073 #CJK UNIFIED IDEOGRAPH + {0x9BC6, 0x6D67}, //5074 #CJK UNIFIED IDEOGRAPH + {0x9BC7, 0x6D68}, //5075 #CJK UNIFIED IDEOGRAPH + {0x9BC8, 0x6D6B}, //5076 #CJK UNIFIED IDEOGRAPH + {0x9BC9, 0x6D6C}, //5077 #CJK UNIFIED IDEOGRAPH + {0x9BCA, 0x6D6D}, //5078 #CJK UNIFIED IDEOGRAPH + {0x9BCB, 0x6D70}, //5079 #CJK UNIFIED IDEOGRAPH + {0x9BCC, 0x6D71}, //5080 #CJK UNIFIED IDEOGRAPH + {0x9BCD, 0x6D72}, //5081 #CJK UNIFIED IDEOGRAPH + {0x9BCE, 0x6D73}, //5082 #CJK UNIFIED IDEOGRAPH + {0x9BCF, 0x6D75}, //5083 #CJK UNIFIED IDEOGRAPH + {0x9BD0, 0x6D76}, //5084 #CJK UNIFIED IDEOGRAPH + {0x9BD1, 0x6D79}, //5085 #CJK UNIFIED IDEOGRAPH + {0x9BD2, 0x6D7A}, //5086 #CJK UNIFIED IDEOGRAPH + {0x9BD3, 0x6D7B}, //5087 #CJK UNIFIED IDEOGRAPH + {0x9BD4, 0x6D7D}, //5088 #CJK UNIFIED IDEOGRAPH + {0x9BD5, 0x6D7E}, //5089 #CJK UNIFIED IDEOGRAPH + {0x9BD6, 0x6D7F}, //5090 #CJK UNIFIED IDEOGRAPH + {0x9BD7, 0x6D80}, //5091 #CJK UNIFIED IDEOGRAPH + {0x9BD8, 0x6D81}, //5092 #CJK UNIFIED IDEOGRAPH + {0x9BD9, 0x6D83}, //5093 #CJK UNIFIED IDEOGRAPH + {0x9BDA, 0x6D84}, //5094 #CJK UNIFIED IDEOGRAPH + {0x9BDB, 0x6D86}, //5095 #CJK UNIFIED IDEOGRAPH + {0x9BDC, 0x6D87}, //5096 #CJK UNIFIED IDEOGRAPH + {0x9BDD, 0x6D8A}, //5097 #CJK UNIFIED IDEOGRAPH + {0x9BDE, 0x6D8B}, //5098 #CJK UNIFIED IDEOGRAPH + {0x9BDF, 0x6D8D}, //5099 #CJK UNIFIED IDEOGRAPH + {0x9BE0, 0x6D8F}, //5100 #CJK UNIFIED IDEOGRAPH + {0x9BE1, 0x6D90}, //5101 #CJK UNIFIED IDEOGRAPH + {0x9BE2, 0x6D92}, //5102 #CJK UNIFIED IDEOGRAPH + {0x9BE3, 0x6D96}, //5103 #CJK UNIFIED IDEOGRAPH + {0x9BE4, 0x6D97}, //5104 #CJK UNIFIED IDEOGRAPH + {0x9BE5, 0x6D98}, //5105 #CJK UNIFIED IDEOGRAPH + {0x9BE6, 0x6D99}, //5106 #CJK UNIFIED IDEOGRAPH + {0x9BE7, 0x6D9A}, //5107 #CJK UNIFIED IDEOGRAPH + {0x9BE8, 0x6D9C}, //5108 #CJK UNIFIED IDEOGRAPH + {0x9BE9, 0x6DA2}, //5109 #CJK UNIFIED IDEOGRAPH + {0x9BEA, 0x6DA5}, //5110 #CJK UNIFIED IDEOGRAPH + {0x9BEB, 0x6DAC}, //5111 #CJK UNIFIED IDEOGRAPH + {0x9BEC, 0x6DAD}, //5112 #CJK UNIFIED IDEOGRAPH + {0x9BED, 0x6DB0}, //5113 #CJK UNIFIED IDEOGRAPH + {0x9BEE, 0x6DB1}, //5114 #CJK UNIFIED IDEOGRAPH + {0x9BEF, 0x6DB3}, //5115 #CJK UNIFIED IDEOGRAPH + {0x9BF0, 0x6DB4}, //5116 #CJK UNIFIED IDEOGRAPH + {0x9BF1, 0x6DB6}, //5117 #CJK UNIFIED IDEOGRAPH + {0x9BF2, 0x6DB7}, //5118 #CJK UNIFIED IDEOGRAPH + {0x9BF3, 0x6DB9}, //5119 #CJK UNIFIED IDEOGRAPH + {0x9BF4, 0x6DBA}, //5120 #CJK UNIFIED IDEOGRAPH + {0x9BF5, 0x6DBB}, //5121 #CJK UNIFIED IDEOGRAPH + {0x9BF6, 0x6DBC}, //5122 #CJK UNIFIED IDEOGRAPH + {0x9BF7, 0x6DBD}, //5123 #CJK UNIFIED IDEOGRAPH + {0x9BF8, 0x6DBE}, //5124 #CJK UNIFIED IDEOGRAPH + {0x9BF9, 0x6DC1}, //5125 #CJK UNIFIED IDEOGRAPH + {0x9BFA, 0x6DC2}, //5126 #CJK UNIFIED IDEOGRAPH + {0x9BFB, 0x6DC3}, //5127 #CJK UNIFIED IDEOGRAPH + {0x9BFC, 0x6DC8}, //5128 #CJK UNIFIED IDEOGRAPH + {0x9BFD, 0x6DC9}, //5129 #CJK UNIFIED IDEOGRAPH + {0x9BFE, 0x6DCA}, //5130 #CJK UNIFIED IDEOGRAPH + {0x9C40, 0x6DCD}, //5131 #CJK UNIFIED IDEOGRAPH + {0x9C41, 0x6DCE}, //5132 #CJK UNIFIED IDEOGRAPH + {0x9C42, 0x6DCF}, //5133 #CJK UNIFIED IDEOGRAPH + {0x9C43, 0x6DD0}, //5134 #CJK UNIFIED IDEOGRAPH + {0x9C44, 0x6DD2}, //5135 #CJK UNIFIED IDEOGRAPH + {0x9C45, 0x6DD3}, //5136 #CJK UNIFIED IDEOGRAPH + {0x9C46, 0x6DD4}, //5137 #CJK UNIFIED IDEOGRAPH + {0x9C47, 0x6DD5}, //5138 #CJK UNIFIED IDEOGRAPH + {0x9C48, 0x6DD7}, //5139 #CJK UNIFIED IDEOGRAPH + {0x9C49, 0x6DDA}, //5140 #CJK UNIFIED IDEOGRAPH + {0x9C4A, 0x6DDB}, //5141 #CJK UNIFIED IDEOGRAPH + {0x9C4B, 0x6DDC}, //5142 #CJK UNIFIED IDEOGRAPH + {0x9C4C, 0x6DDF}, //5143 #CJK UNIFIED IDEOGRAPH + {0x9C4D, 0x6DE2}, //5144 #CJK UNIFIED IDEOGRAPH + {0x9C4E, 0x6DE3}, //5145 #CJK UNIFIED IDEOGRAPH + {0x9C4F, 0x6DE5}, //5146 #CJK UNIFIED IDEOGRAPH + {0x9C50, 0x6DE7}, //5147 #CJK UNIFIED IDEOGRAPH + {0x9C51, 0x6DE8}, //5148 #CJK UNIFIED IDEOGRAPH + {0x9C52, 0x6DE9}, //5149 #CJK UNIFIED IDEOGRAPH + {0x9C53, 0x6DEA}, //5150 #CJK UNIFIED IDEOGRAPH + {0x9C54, 0x6DED}, //5151 #CJK UNIFIED IDEOGRAPH + {0x9C55, 0x6DEF}, //5152 #CJK UNIFIED IDEOGRAPH + {0x9C56, 0x6DF0}, //5153 #CJK UNIFIED IDEOGRAPH + {0x9C57, 0x6DF2}, //5154 #CJK UNIFIED IDEOGRAPH + {0x9C58, 0x6DF4}, //5155 #CJK UNIFIED IDEOGRAPH + {0x9C59, 0x6DF5}, //5156 #CJK UNIFIED IDEOGRAPH + {0x9C5A, 0x6DF6}, //5157 #CJK UNIFIED IDEOGRAPH + {0x9C5B, 0x6DF8}, //5158 #CJK UNIFIED IDEOGRAPH + {0x9C5C, 0x6DFA}, //5159 #CJK UNIFIED IDEOGRAPH + {0x9C5D, 0x6DFD}, //5160 #CJK UNIFIED IDEOGRAPH + {0x9C5E, 0x6DFE}, //5161 #CJK UNIFIED IDEOGRAPH + {0x9C5F, 0x6DFF}, //5162 #CJK UNIFIED IDEOGRAPH + {0x9C60, 0x6E00}, //5163 #CJK UNIFIED IDEOGRAPH + {0x9C61, 0x6E01}, //5164 #CJK UNIFIED IDEOGRAPH + {0x9C62, 0x6E02}, //5165 #CJK UNIFIED IDEOGRAPH + {0x9C63, 0x6E03}, //5166 #CJK UNIFIED IDEOGRAPH + {0x9C64, 0x6E04}, //5167 #CJK UNIFIED IDEOGRAPH + {0x9C65, 0x6E06}, //5168 #CJK UNIFIED IDEOGRAPH + {0x9C66, 0x6E07}, //5169 #CJK UNIFIED IDEOGRAPH + {0x9C67, 0x6E08}, //5170 #CJK UNIFIED IDEOGRAPH + {0x9C68, 0x6E09}, //5171 #CJK UNIFIED IDEOGRAPH + {0x9C69, 0x6E0B}, //5172 #CJK UNIFIED IDEOGRAPH + {0x9C6A, 0x6E0F}, //5173 #CJK UNIFIED IDEOGRAPH + {0x9C6B, 0x6E12}, //5174 #CJK UNIFIED IDEOGRAPH + {0x9C6C, 0x6E13}, //5175 #CJK UNIFIED IDEOGRAPH + {0x9C6D, 0x6E15}, //5176 #CJK UNIFIED IDEOGRAPH + {0x9C6E, 0x6E18}, //5177 #CJK UNIFIED IDEOGRAPH + {0x9C6F, 0x6E19}, //5178 #CJK UNIFIED IDEOGRAPH + {0x9C70, 0x6E1B}, //5179 #CJK UNIFIED IDEOGRAPH + {0x9C71, 0x6E1C}, //5180 #CJK UNIFIED IDEOGRAPH + {0x9C72, 0x6E1E}, //5181 #CJK UNIFIED IDEOGRAPH + {0x9C73, 0x6E1F}, //5182 #CJK UNIFIED IDEOGRAPH + {0x9C74, 0x6E22}, //5183 #CJK UNIFIED IDEOGRAPH + {0x9C75, 0x6E26}, //5184 #CJK UNIFIED IDEOGRAPH + {0x9C76, 0x6E27}, //5185 #CJK UNIFIED IDEOGRAPH + {0x9C77, 0x6E28}, //5186 #CJK UNIFIED IDEOGRAPH + {0x9C78, 0x6E2A}, //5187 #CJK UNIFIED IDEOGRAPH + {0x9C79, 0x6E2C}, //5188 #CJK UNIFIED IDEOGRAPH + {0x9C7A, 0x6E2E}, //5189 #CJK UNIFIED IDEOGRAPH + {0x9C7B, 0x6E30}, //5190 #CJK UNIFIED IDEOGRAPH + {0x9C7C, 0x6E31}, //5191 #CJK UNIFIED IDEOGRAPH + {0x9C7D, 0x6E33}, //5192 #CJK UNIFIED IDEOGRAPH + {0x9C7E, 0x6E35}, //5193 #CJK UNIFIED IDEOGRAPH + {0x9C80, 0x6E36}, //5194 #CJK UNIFIED IDEOGRAPH + {0x9C81, 0x6E37}, //5195 #CJK UNIFIED IDEOGRAPH + {0x9C82, 0x6E39}, //5196 #CJK UNIFIED IDEOGRAPH + {0x9C83, 0x6E3B}, //5197 #CJK UNIFIED IDEOGRAPH + {0x9C84, 0x6E3C}, //5198 #CJK UNIFIED IDEOGRAPH + {0x9C85, 0x6E3D}, //5199 #CJK UNIFIED IDEOGRAPH + {0x9C86, 0x6E3E}, //5200 #CJK UNIFIED IDEOGRAPH + {0x9C87, 0x6E3F}, //5201 #CJK UNIFIED IDEOGRAPH + {0x9C88, 0x6E40}, //5202 #CJK UNIFIED IDEOGRAPH + {0x9C89, 0x6E41}, //5203 #CJK UNIFIED IDEOGRAPH + {0x9C8A, 0x6E42}, //5204 #CJK UNIFIED IDEOGRAPH + {0x9C8B, 0x6E45}, //5205 #CJK UNIFIED IDEOGRAPH + {0x9C8C, 0x6E46}, //5206 #CJK UNIFIED IDEOGRAPH + {0x9C8D, 0x6E47}, //5207 #CJK UNIFIED IDEOGRAPH + {0x9C8E, 0x6E48}, //5208 #CJK UNIFIED IDEOGRAPH + {0x9C8F, 0x6E49}, //5209 #CJK UNIFIED IDEOGRAPH + {0x9C90, 0x6E4A}, //5210 #CJK UNIFIED IDEOGRAPH + {0x9C91, 0x6E4B}, //5211 #CJK UNIFIED IDEOGRAPH + {0x9C92, 0x6E4C}, //5212 #CJK UNIFIED IDEOGRAPH + {0x9C93, 0x6E4F}, //5213 #CJK UNIFIED IDEOGRAPH + {0x9C94, 0x6E50}, //5214 #CJK UNIFIED IDEOGRAPH + {0x9C95, 0x6E51}, //5215 #CJK UNIFIED IDEOGRAPH + {0x9C96, 0x6E52}, //5216 #CJK UNIFIED IDEOGRAPH + {0x9C97, 0x6E55}, //5217 #CJK UNIFIED IDEOGRAPH + {0x9C98, 0x6E57}, //5218 #CJK UNIFIED IDEOGRAPH + {0x9C99, 0x6E59}, //5219 #CJK UNIFIED IDEOGRAPH + {0x9C9A, 0x6E5A}, //5220 #CJK UNIFIED IDEOGRAPH + {0x9C9B, 0x6E5C}, //5221 #CJK UNIFIED IDEOGRAPH + {0x9C9C, 0x6E5D}, //5222 #CJK UNIFIED IDEOGRAPH + {0x9C9D, 0x6E5E}, //5223 #CJK UNIFIED IDEOGRAPH + {0x9C9E, 0x6E60}, //5224 #CJK UNIFIED IDEOGRAPH + {0x9C9F, 0x6E61}, //5225 #CJK UNIFIED IDEOGRAPH + {0x9CA0, 0x6E62}, //5226 #CJK UNIFIED IDEOGRAPH + {0x9CA1, 0x6E63}, //5227 #CJK UNIFIED IDEOGRAPH + {0x9CA2, 0x6E64}, //5228 #CJK UNIFIED IDEOGRAPH + {0x9CA3, 0x6E65}, //5229 #CJK UNIFIED IDEOGRAPH + {0x9CA4, 0x6E66}, //5230 #CJK UNIFIED IDEOGRAPH + {0x9CA5, 0x6E67}, //5231 #CJK UNIFIED IDEOGRAPH + {0x9CA6, 0x6E68}, //5232 #CJK UNIFIED IDEOGRAPH + {0x9CA7, 0x6E69}, //5233 #CJK UNIFIED IDEOGRAPH + {0x9CA8, 0x6E6A}, //5234 #CJK UNIFIED IDEOGRAPH + {0x9CA9, 0x6E6C}, //5235 #CJK UNIFIED IDEOGRAPH + {0x9CAA, 0x6E6D}, //5236 #CJK UNIFIED IDEOGRAPH + {0x9CAB, 0x6E6F}, //5237 #CJK UNIFIED IDEOGRAPH + {0x9CAC, 0x6E70}, //5238 #CJK UNIFIED IDEOGRAPH + {0x9CAD, 0x6E71}, //5239 #CJK UNIFIED IDEOGRAPH + {0x9CAE, 0x6E72}, //5240 #CJK UNIFIED IDEOGRAPH + {0x9CAF, 0x6E73}, //5241 #CJK UNIFIED IDEOGRAPH + {0x9CB0, 0x6E74}, //5242 #CJK UNIFIED IDEOGRAPH + {0x9CB1, 0x6E75}, //5243 #CJK UNIFIED IDEOGRAPH + {0x9CB2, 0x6E76}, //5244 #CJK UNIFIED IDEOGRAPH + {0x9CB3, 0x6E77}, //5245 #CJK UNIFIED IDEOGRAPH + {0x9CB4, 0x6E78}, //5246 #CJK UNIFIED IDEOGRAPH + {0x9CB5, 0x6E79}, //5247 #CJK UNIFIED IDEOGRAPH + {0x9CB6, 0x6E7A}, //5248 #CJK UNIFIED IDEOGRAPH + {0x9CB7, 0x6E7B}, //5249 #CJK UNIFIED IDEOGRAPH + {0x9CB8, 0x6E7C}, //5250 #CJK UNIFIED IDEOGRAPH + {0x9CB9, 0x6E7D}, //5251 #CJK UNIFIED IDEOGRAPH + {0x9CBA, 0x6E80}, //5252 #CJK UNIFIED IDEOGRAPH + {0x9CBB, 0x6E81}, //5253 #CJK UNIFIED IDEOGRAPH + {0x9CBC, 0x6E82}, //5254 #CJK UNIFIED IDEOGRAPH + {0x9CBD, 0x6E84}, //5255 #CJK UNIFIED IDEOGRAPH + {0x9CBE, 0x6E87}, //5256 #CJK UNIFIED IDEOGRAPH + {0x9CBF, 0x6E88}, //5257 #CJK UNIFIED IDEOGRAPH + {0x9CC0, 0x6E8A}, //5258 #CJK UNIFIED IDEOGRAPH + {0x9CC1, 0x6E8B}, //5259 #CJK UNIFIED IDEOGRAPH + {0x9CC2, 0x6E8C}, //5260 #CJK UNIFIED IDEOGRAPH + {0x9CC3, 0x6E8D}, //5261 #CJK UNIFIED IDEOGRAPH + {0x9CC4, 0x6E8E}, //5262 #CJK UNIFIED IDEOGRAPH + {0x9CC5, 0x6E91}, //5263 #CJK UNIFIED IDEOGRAPH + {0x9CC6, 0x6E92}, //5264 #CJK UNIFIED IDEOGRAPH + {0x9CC7, 0x6E93}, //5265 #CJK UNIFIED IDEOGRAPH + {0x9CC8, 0x6E94}, //5266 #CJK UNIFIED IDEOGRAPH + {0x9CC9, 0x6E95}, //5267 #CJK UNIFIED IDEOGRAPH + {0x9CCA, 0x6E96}, //5268 #CJK UNIFIED IDEOGRAPH + {0x9CCB, 0x6E97}, //5269 #CJK UNIFIED IDEOGRAPH + {0x9CCC, 0x6E99}, //5270 #CJK UNIFIED IDEOGRAPH + {0x9CCD, 0x6E9A}, //5271 #CJK UNIFIED IDEOGRAPH + {0x9CCE, 0x6E9B}, //5272 #CJK UNIFIED IDEOGRAPH + {0x9CCF, 0x6E9D}, //5273 #CJK UNIFIED IDEOGRAPH + {0x9CD0, 0x6E9E}, //5274 #CJK UNIFIED IDEOGRAPH + {0x9CD1, 0x6EA0}, //5275 #CJK UNIFIED IDEOGRAPH + {0x9CD2, 0x6EA1}, //5276 #CJK UNIFIED IDEOGRAPH + {0x9CD3, 0x6EA3}, //5277 #CJK UNIFIED IDEOGRAPH + {0x9CD4, 0x6EA4}, //5278 #CJK UNIFIED IDEOGRAPH + {0x9CD5, 0x6EA6}, //5279 #CJK UNIFIED IDEOGRAPH + {0x9CD6, 0x6EA8}, //5280 #CJK UNIFIED IDEOGRAPH + {0x9CD7, 0x6EA9}, //5281 #CJK UNIFIED IDEOGRAPH + {0x9CD8, 0x6EAB}, //5282 #CJK UNIFIED IDEOGRAPH + {0x9CD9, 0x6EAC}, //5283 #CJK UNIFIED IDEOGRAPH + {0x9CDA, 0x6EAD}, //5284 #CJK UNIFIED IDEOGRAPH + {0x9CDB, 0x6EAE}, //5285 #CJK UNIFIED IDEOGRAPH + {0x9CDC, 0x6EB0}, //5286 #CJK UNIFIED IDEOGRAPH + {0x9CDD, 0x6EB3}, //5287 #CJK UNIFIED IDEOGRAPH + {0x9CDE, 0x6EB5}, //5288 #CJK UNIFIED IDEOGRAPH + {0x9CDF, 0x6EB8}, //5289 #CJK UNIFIED IDEOGRAPH + {0x9CE0, 0x6EB9}, //5290 #CJK UNIFIED IDEOGRAPH + {0x9CE1, 0x6EBC}, //5291 #CJK UNIFIED IDEOGRAPH + {0x9CE2, 0x6EBE}, //5292 #CJK UNIFIED IDEOGRAPH + {0x9CE3, 0x6EBF}, //5293 #CJK UNIFIED IDEOGRAPH + {0x9CE4, 0x6EC0}, //5294 #CJK UNIFIED IDEOGRAPH + {0x9CE5, 0x6EC3}, //5295 #CJK UNIFIED IDEOGRAPH + {0x9CE6, 0x6EC4}, //5296 #CJK UNIFIED IDEOGRAPH + {0x9CE7, 0x6EC5}, //5297 #CJK UNIFIED IDEOGRAPH + {0x9CE8, 0x6EC6}, //5298 #CJK UNIFIED IDEOGRAPH + {0x9CE9, 0x6EC8}, //5299 #CJK UNIFIED IDEOGRAPH + {0x9CEA, 0x6EC9}, //5300 #CJK UNIFIED IDEOGRAPH + {0x9CEB, 0x6ECA}, //5301 #CJK UNIFIED IDEOGRAPH + {0x9CEC, 0x6ECC}, //5302 #CJK UNIFIED IDEOGRAPH + {0x9CED, 0x6ECD}, //5303 #CJK UNIFIED IDEOGRAPH + {0x9CEE, 0x6ECE}, //5304 #CJK UNIFIED IDEOGRAPH + {0x9CEF, 0x6ED0}, //5305 #CJK UNIFIED IDEOGRAPH + {0x9CF0, 0x6ED2}, //5306 #CJK UNIFIED IDEOGRAPH + {0x9CF1, 0x6ED6}, //5307 #CJK UNIFIED IDEOGRAPH + {0x9CF2, 0x6ED8}, //5308 #CJK UNIFIED IDEOGRAPH + {0x9CF3, 0x6ED9}, //5309 #CJK UNIFIED IDEOGRAPH + {0x9CF4, 0x6EDB}, //5310 #CJK UNIFIED IDEOGRAPH + {0x9CF5, 0x6EDC}, //5311 #CJK UNIFIED IDEOGRAPH + {0x9CF6, 0x6EDD}, //5312 #CJK UNIFIED IDEOGRAPH + {0x9CF7, 0x6EE3}, //5313 #CJK UNIFIED IDEOGRAPH + {0x9CF8, 0x6EE7}, //5314 #CJK UNIFIED IDEOGRAPH + {0x9CF9, 0x6EEA}, //5315 #CJK UNIFIED IDEOGRAPH + {0x9CFA, 0x6EEB}, //5316 #CJK UNIFIED IDEOGRAPH + {0x9CFB, 0x6EEC}, //5317 #CJK UNIFIED IDEOGRAPH + {0x9CFC, 0x6EED}, //5318 #CJK UNIFIED IDEOGRAPH + {0x9CFD, 0x6EEE}, //5319 #CJK UNIFIED IDEOGRAPH + {0x9CFE, 0x6EEF}, //5320 #CJK UNIFIED IDEOGRAPH + {0x9D40, 0x6EF0}, //5321 #CJK UNIFIED IDEOGRAPH + {0x9D41, 0x6EF1}, //5322 #CJK UNIFIED IDEOGRAPH + {0x9D42, 0x6EF2}, //5323 #CJK UNIFIED IDEOGRAPH + {0x9D43, 0x6EF3}, //5324 #CJK UNIFIED IDEOGRAPH + {0x9D44, 0x6EF5}, //5325 #CJK UNIFIED IDEOGRAPH + {0x9D45, 0x6EF6}, //5326 #CJK UNIFIED IDEOGRAPH + {0x9D46, 0x6EF7}, //5327 #CJK UNIFIED IDEOGRAPH + {0x9D47, 0x6EF8}, //5328 #CJK UNIFIED IDEOGRAPH + {0x9D48, 0x6EFA}, //5329 #CJK UNIFIED IDEOGRAPH + {0x9D49, 0x6EFB}, //5330 #CJK UNIFIED IDEOGRAPH + {0x9D4A, 0x6EFC}, //5331 #CJK UNIFIED IDEOGRAPH + {0x9D4B, 0x6EFD}, //5332 #CJK UNIFIED IDEOGRAPH + {0x9D4C, 0x6EFE}, //5333 #CJK UNIFIED IDEOGRAPH + {0x9D4D, 0x6EFF}, //5334 #CJK UNIFIED IDEOGRAPH + {0x9D4E, 0x6F00}, //5335 #CJK UNIFIED IDEOGRAPH + {0x9D4F, 0x6F01}, //5336 #CJK UNIFIED IDEOGRAPH + {0x9D50, 0x6F03}, //5337 #CJK UNIFIED IDEOGRAPH + {0x9D51, 0x6F04}, //5338 #CJK UNIFIED IDEOGRAPH + {0x9D52, 0x6F05}, //5339 #CJK UNIFIED IDEOGRAPH + {0x9D53, 0x6F07}, //5340 #CJK UNIFIED IDEOGRAPH + {0x9D54, 0x6F08}, //5341 #CJK UNIFIED IDEOGRAPH + {0x9D55, 0x6F0A}, //5342 #CJK UNIFIED IDEOGRAPH + {0x9D56, 0x6F0B}, //5343 #CJK UNIFIED IDEOGRAPH + {0x9D57, 0x6F0C}, //5344 #CJK UNIFIED IDEOGRAPH + {0x9D58, 0x6F0D}, //5345 #CJK UNIFIED IDEOGRAPH + {0x9D59, 0x6F0E}, //5346 #CJK UNIFIED IDEOGRAPH + {0x9D5A, 0x6F10}, //5347 #CJK UNIFIED IDEOGRAPH + {0x9D5B, 0x6F11}, //5348 #CJK UNIFIED IDEOGRAPH + {0x9D5C, 0x6F12}, //5349 #CJK UNIFIED IDEOGRAPH + {0x9D5D, 0x6F16}, //5350 #CJK UNIFIED IDEOGRAPH + {0x9D5E, 0x6F17}, //5351 #CJK UNIFIED IDEOGRAPH + {0x9D5F, 0x6F18}, //5352 #CJK UNIFIED IDEOGRAPH + {0x9D60, 0x6F19}, //5353 #CJK UNIFIED IDEOGRAPH + {0x9D61, 0x6F1A}, //5354 #CJK UNIFIED IDEOGRAPH + {0x9D62, 0x6F1B}, //5355 #CJK UNIFIED IDEOGRAPH + {0x9D63, 0x6F1C}, //5356 #CJK UNIFIED IDEOGRAPH + {0x9D64, 0x6F1D}, //5357 #CJK UNIFIED IDEOGRAPH + {0x9D65, 0x6F1E}, //5358 #CJK UNIFIED IDEOGRAPH + {0x9D66, 0x6F1F}, //5359 #CJK UNIFIED IDEOGRAPH + {0x9D67, 0x6F21}, //5360 #CJK UNIFIED IDEOGRAPH + {0x9D68, 0x6F22}, //5361 #CJK UNIFIED IDEOGRAPH + {0x9D69, 0x6F23}, //5362 #CJK UNIFIED IDEOGRAPH + {0x9D6A, 0x6F25}, //5363 #CJK UNIFIED IDEOGRAPH + {0x9D6B, 0x6F26}, //5364 #CJK UNIFIED IDEOGRAPH + {0x9D6C, 0x6F27}, //5365 #CJK UNIFIED IDEOGRAPH + {0x9D6D, 0x6F28}, //5366 #CJK UNIFIED IDEOGRAPH + {0x9D6E, 0x6F2C}, //5367 #CJK UNIFIED IDEOGRAPH + {0x9D6F, 0x6F2E}, //5368 #CJK UNIFIED IDEOGRAPH + {0x9D70, 0x6F30}, //5369 #CJK UNIFIED IDEOGRAPH + {0x9D71, 0x6F32}, //5370 #CJK UNIFIED IDEOGRAPH + {0x9D72, 0x6F34}, //5371 #CJK UNIFIED IDEOGRAPH + {0x9D73, 0x6F35}, //5372 #CJK UNIFIED IDEOGRAPH + {0x9D74, 0x6F37}, //5373 #CJK UNIFIED IDEOGRAPH + {0x9D75, 0x6F38}, //5374 #CJK UNIFIED IDEOGRAPH + {0x9D76, 0x6F39}, //5375 #CJK UNIFIED IDEOGRAPH + {0x9D77, 0x6F3A}, //5376 #CJK UNIFIED IDEOGRAPH + {0x9D78, 0x6F3B}, //5377 #CJK UNIFIED IDEOGRAPH + {0x9D79, 0x6F3C}, //5378 #CJK UNIFIED IDEOGRAPH + {0x9D7A, 0x6F3D}, //5379 #CJK UNIFIED IDEOGRAPH + {0x9D7B, 0x6F3F}, //5380 #CJK UNIFIED IDEOGRAPH + {0x9D7C, 0x6F40}, //5381 #CJK UNIFIED IDEOGRAPH + {0x9D7D, 0x6F41}, //5382 #CJK UNIFIED IDEOGRAPH + {0x9D7E, 0x6F42}, //5383 #CJK UNIFIED IDEOGRAPH + {0x9D80, 0x6F43}, //5384 #CJK UNIFIED IDEOGRAPH + {0x9D81, 0x6F44}, //5385 #CJK UNIFIED IDEOGRAPH + {0x9D82, 0x6F45}, //5386 #CJK UNIFIED IDEOGRAPH + {0x9D83, 0x6F48}, //5387 #CJK UNIFIED IDEOGRAPH + {0x9D84, 0x6F49}, //5388 #CJK UNIFIED IDEOGRAPH + {0x9D85, 0x6F4A}, //5389 #CJK UNIFIED IDEOGRAPH + {0x9D86, 0x6F4C}, //5390 #CJK UNIFIED IDEOGRAPH + {0x9D87, 0x6F4E}, //5391 #CJK UNIFIED IDEOGRAPH + {0x9D88, 0x6F4F}, //5392 #CJK UNIFIED IDEOGRAPH + {0x9D89, 0x6F50}, //5393 #CJK UNIFIED IDEOGRAPH + {0x9D8A, 0x6F51}, //5394 #CJK UNIFIED IDEOGRAPH + {0x9D8B, 0x6F52}, //5395 #CJK UNIFIED IDEOGRAPH + {0x9D8C, 0x6F53}, //5396 #CJK UNIFIED IDEOGRAPH + {0x9D8D, 0x6F54}, //5397 #CJK UNIFIED IDEOGRAPH + {0x9D8E, 0x6F55}, //5398 #CJK UNIFIED IDEOGRAPH + {0x9D8F, 0x6F56}, //5399 #CJK UNIFIED IDEOGRAPH + {0x9D90, 0x6F57}, //5400 #CJK UNIFIED IDEOGRAPH + {0x9D91, 0x6F59}, //5401 #CJK UNIFIED IDEOGRAPH + {0x9D92, 0x6F5A}, //5402 #CJK UNIFIED IDEOGRAPH + {0x9D93, 0x6F5B}, //5403 #CJK UNIFIED IDEOGRAPH + {0x9D94, 0x6F5D}, //5404 #CJK UNIFIED IDEOGRAPH + {0x9D95, 0x6F5F}, //5405 #CJK UNIFIED IDEOGRAPH + {0x9D96, 0x6F60}, //5406 #CJK UNIFIED IDEOGRAPH + {0x9D97, 0x6F61}, //5407 #CJK UNIFIED IDEOGRAPH + {0x9D98, 0x6F63}, //5408 #CJK UNIFIED IDEOGRAPH + {0x9D99, 0x6F64}, //5409 #CJK UNIFIED IDEOGRAPH + {0x9D9A, 0x6F65}, //5410 #CJK UNIFIED IDEOGRAPH + {0x9D9B, 0x6F67}, //5411 #CJK UNIFIED IDEOGRAPH + {0x9D9C, 0x6F68}, //5412 #CJK UNIFIED IDEOGRAPH + {0x9D9D, 0x6F69}, //5413 #CJK UNIFIED IDEOGRAPH + {0x9D9E, 0x6F6A}, //5414 #CJK UNIFIED IDEOGRAPH + {0x9D9F, 0x6F6B}, //5415 #CJK UNIFIED IDEOGRAPH + {0x9DA0, 0x6F6C}, //5416 #CJK UNIFIED IDEOGRAPH + {0x9DA1, 0x6F6F}, //5417 #CJK UNIFIED IDEOGRAPH + {0x9DA2, 0x6F70}, //5418 #CJK UNIFIED IDEOGRAPH + {0x9DA3, 0x6F71}, //5419 #CJK UNIFIED IDEOGRAPH + {0x9DA4, 0x6F73}, //5420 #CJK UNIFIED IDEOGRAPH + {0x9DA5, 0x6F75}, //5421 #CJK UNIFIED IDEOGRAPH + {0x9DA6, 0x6F76}, //5422 #CJK UNIFIED IDEOGRAPH + {0x9DA7, 0x6F77}, //5423 #CJK UNIFIED IDEOGRAPH + {0x9DA8, 0x6F79}, //5424 #CJK UNIFIED IDEOGRAPH + {0x9DA9, 0x6F7B}, //5425 #CJK UNIFIED IDEOGRAPH + {0x9DAA, 0x6F7D}, //5426 #CJK UNIFIED IDEOGRAPH + {0x9DAB, 0x6F7E}, //5427 #CJK UNIFIED IDEOGRAPH + {0x9DAC, 0x6F7F}, //5428 #CJK UNIFIED IDEOGRAPH + {0x9DAD, 0x6F80}, //5429 #CJK UNIFIED IDEOGRAPH + {0x9DAE, 0x6F81}, //5430 #CJK UNIFIED IDEOGRAPH + {0x9DAF, 0x6F82}, //5431 #CJK UNIFIED IDEOGRAPH + {0x9DB0, 0x6F83}, //5432 #CJK UNIFIED IDEOGRAPH + {0x9DB1, 0x6F85}, //5433 #CJK UNIFIED IDEOGRAPH + {0x9DB2, 0x6F86}, //5434 #CJK UNIFIED IDEOGRAPH + {0x9DB3, 0x6F87}, //5435 #CJK UNIFIED IDEOGRAPH + {0x9DB4, 0x6F8A}, //5436 #CJK UNIFIED IDEOGRAPH + {0x9DB5, 0x6F8B}, //5437 #CJK UNIFIED IDEOGRAPH + {0x9DB6, 0x6F8F}, //5438 #CJK UNIFIED IDEOGRAPH + {0x9DB7, 0x6F90}, //5439 #CJK UNIFIED IDEOGRAPH + {0x9DB8, 0x6F91}, //5440 #CJK UNIFIED IDEOGRAPH + {0x9DB9, 0x6F92}, //5441 #CJK UNIFIED IDEOGRAPH + {0x9DBA, 0x6F93}, //5442 #CJK UNIFIED IDEOGRAPH + {0x9DBB, 0x6F94}, //5443 #CJK UNIFIED IDEOGRAPH + {0x9DBC, 0x6F95}, //5444 #CJK UNIFIED IDEOGRAPH + {0x9DBD, 0x6F96}, //5445 #CJK UNIFIED IDEOGRAPH + {0x9DBE, 0x6F97}, //5446 #CJK UNIFIED IDEOGRAPH + {0x9DBF, 0x6F98}, //5447 #CJK UNIFIED IDEOGRAPH + {0x9DC0, 0x6F99}, //5448 #CJK UNIFIED IDEOGRAPH + {0x9DC1, 0x6F9A}, //5449 #CJK UNIFIED IDEOGRAPH + {0x9DC2, 0x6F9B}, //5450 #CJK UNIFIED IDEOGRAPH + {0x9DC3, 0x6F9D}, //5451 #CJK UNIFIED IDEOGRAPH + {0x9DC4, 0x6F9E}, //5452 #CJK UNIFIED IDEOGRAPH + {0x9DC5, 0x6F9F}, //5453 #CJK UNIFIED IDEOGRAPH + {0x9DC6, 0x6FA0}, //5454 #CJK UNIFIED IDEOGRAPH + {0x9DC7, 0x6FA2}, //5455 #CJK UNIFIED IDEOGRAPH + {0x9DC8, 0x6FA3}, //5456 #CJK UNIFIED IDEOGRAPH + {0x9DC9, 0x6FA4}, //5457 #CJK UNIFIED IDEOGRAPH + {0x9DCA, 0x6FA5}, //5458 #CJK UNIFIED IDEOGRAPH + {0x9DCB, 0x6FA6}, //5459 #CJK UNIFIED IDEOGRAPH + {0x9DCC, 0x6FA8}, //5460 #CJK UNIFIED IDEOGRAPH + {0x9DCD, 0x6FA9}, //5461 #CJK UNIFIED IDEOGRAPH + {0x9DCE, 0x6FAA}, //5462 #CJK UNIFIED IDEOGRAPH + {0x9DCF, 0x6FAB}, //5463 #CJK UNIFIED IDEOGRAPH + {0x9DD0, 0x6FAC}, //5464 #CJK UNIFIED IDEOGRAPH + {0x9DD1, 0x6FAD}, //5465 #CJK UNIFIED IDEOGRAPH + {0x9DD2, 0x6FAE}, //5466 #CJK UNIFIED IDEOGRAPH + {0x9DD3, 0x6FAF}, //5467 #CJK UNIFIED IDEOGRAPH + {0x9DD4, 0x6FB0}, //5468 #CJK UNIFIED IDEOGRAPH + {0x9DD5, 0x6FB1}, //5469 #CJK UNIFIED IDEOGRAPH + {0x9DD6, 0x6FB2}, //5470 #CJK UNIFIED IDEOGRAPH + {0x9DD7, 0x6FB4}, //5471 #CJK UNIFIED IDEOGRAPH + {0x9DD8, 0x6FB5}, //5472 #CJK UNIFIED IDEOGRAPH + {0x9DD9, 0x6FB7}, //5473 #CJK UNIFIED IDEOGRAPH + {0x9DDA, 0x6FB8}, //5474 #CJK UNIFIED IDEOGRAPH + {0x9DDB, 0x6FBA}, //5475 #CJK UNIFIED IDEOGRAPH + {0x9DDC, 0x6FBB}, //5476 #CJK UNIFIED IDEOGRAPH + {0x9DDD, 0x6FBC}, //5477 #CJK UNIFIED IDEOGRAPH + {0x9DDE, 0x6FBD}, //5478 #CJK UNIFIED IDEOGRAPH + {0x9DDF, 0x6FBE}, //5479 #CJK UNIFIED IDEOGRAPH + {0x9DE0, 0x6FBF}, //5480 #CJK UNIFIED IDEOGRAPH + {0x9DE1, 0x6FC1}, //5481 #CJK UNIFIED IDEOGRAPH + {0x9DE2, 0x6FC3}, //5482 #CJK UNIFIED IDEOGRAPH + {0x9DE3, 0x6FC4}, //5483 #CJK UNIFIED IDEOGRAPH + {0x9DE4, 0x6FC5}, //5484 #CJK UNIFIED IDEOGRAPH + {0x9DE5, 0x6FC6}, //5485 #CJK UNIFIED IDEOGRAPH + {0x9DE6, 0x6FC7}, //5486 #CJK UNIFIED IDEOGRAPH + {0x9DE7, 0x6FC8}, //5487 #CJK UNIFIED IDEOGRAPH + {0x9DE8, 0x6FCA}, //5488 #CJK UNIFIED IDEOGRAPH + {0x9DE9, 0x6FCB}, //5489 #CJK UNIFIED IDEOGRAPH + {0x9DEA, 0x6FCC}, //5490 #CJK UNIFIED IDEOGRAPH + {0x9DEB, 0x6FCD}, //5491 #CJK UNIFIED IDEOGRAPH + {0x9DEC, 0x6FCE}, //5492 #CJK UNIFIED IDEOGRAPH + {0x9DED, 0x6FCF}, //5493 #CJK UNIFIED IDEOGRAPH + {0x9DEE, 0x6FD0}, //5494 #CJK UNIFIED IDEOGRAPH + {0x9DEF, 0x6FD3}, //5495 #CJK UNIFIED IDEOGRAPH + {0x9DF0, 0x6FD4}, //5496 #CJK UNIFIED IDEOGRAPH + {0x9DF1, 0x6FD5}, //5497 #CJK UNIFIED IDEOGRAPH + {0x9DF2, 0x6FD6}, //5498 #CJK UNIFIED IDEOGRAPH + {0x9DF3, 0x6FD7}, //5499 #CJK UNIFIED IDEOGRAPH + {0x9DF4, 0x6FD8}, //5500 #CJK UNIFIED IDEOGRAPH + {0x9DF5, 0x6FD9}, //5501 #CJK UNIFIED IDEOGRAPH + {0x9DF6, 0x6FDA}, //5502 #CJK UNIFIED IDEOGRAPH + {0x9DF7, 0x6FDB}, //5503 #CJK UNIFIED IDEOGRAPH + {0x9DF8, 0x6FDC}, //5504 #CJK UNIFIED IDEOGRAPH + {0x9DF9, 0x6FDD}, //5505 #CJK UNIFIED IDEOGRAPH + {0x9DFA, 0x6FDF}, //5506 #CJK UNIFIED IDEOGRAPH + {0x9DFB, 0x6FE2}, //5507 #CJK UNIFIED IDEOGRAPH + {0x9DFC, 0x6FE3}, //5508 #CJK UNIFIED IDEOGRAPH + {0x9DFD, 0x6FE4}, //5509 #CJK UNIFIED IDEOGRAPH + {0x9DFE, 0x6FE5}, //5510 #CJK UNIFIED IDEOGRAPH + {0x9E40, 0x6FE6}, //5511 #CJK UNIFIED IDEOGRAPH + {0x9E41, 0x6FE7}, //5512 #CJK UNIFIED IDEOGRAPH + {0x9E42, 0x6FE8}, //5513 #CJK UNIFIED IDEOGRAPH + {0x9E43, 0x6FE9}, //5514 #CJK UNIFIED IDEOGRAPH + {0x9E44, 0x6FEA}, //5515 #CJK UNIFIED IDEOGRAPH + {0x9E45, 0x6FEB}, //5516 #CJK UNIFIED IDEOGRAPH + {0x9E46, 0x6FEC}, //5517 #CJK UNIFIED IDEOGRAPH + {0x9E47, 0x6FED}, //5518 #CJK UNIFIED IDEOGRAPH + {0x9E48, 0x6FF0}, //5519 #CJK UNIFIED IDEOGRAPH + {0x9E49, 0x6FF1}, //5520 #CJK UNIFIED IDEOGRAPH + {0x9E4A, 0x6FF2}, //5521 #CJK UNIFIED IDEOGRAPH + {0x9E4B, 0x6FF3}, //5522 #CJK UNIFIED IDEOGRAPH + {0x9E4C, 0x6FF4}, //5523 #CJK UNIFIED IDEOGRAPH + {0x9E4D, 0x6FF5}, //5524 #CJK UNIFIED IDEOGRAPH + {0x9E4E, 0x6FF6}, //5525 #CJK UNIFIED IDEOGRAPH + {0x9E4F, 0x6FF7}, //5526 #CJK UNIFIED IDEOGRAPH + {0x9E50, 0x6FF8}, //5527 #CJK UNIFIED IDEOGRAPH + {0x9E51, 0x6FF9}, //5528 #CJK UNIFIED IDEOGRAPH + {0x9E52, 0x6FFA}, //5529 #CJK UNIFIED IDEOGRAPH + {0x9E53, 0x6FFB}, //5530 #CJK UNIFIED IDEOGRAPH + {0x9E54, 0x6FFC}, //5531 #CJK UNIFIED IDEOGRAPH + {0x9E55, 0x6FFD}, //5532 #CJK UNIFIED IDEOGRAPH + {0x9E56, 0x6FFE}, //5533 #CJK UNIFIED IDEOGRAPH + {0x9E57, 0x6FFF}, //5534 #CJK UNIFIED IDEOGRAPH + {0x9E58, 0x7000}, //5535 #CJK UNIFIED IDEOGRAPH + {0x9E59, 0x7001}, //5536 #CJK UNIFIED IDEOGRAPH + {0x9E5A, 0x7002}, //5537 #CJK UNIFIED IDEOGRAPH + {0x9E5B, 0x7003}, //5538 #CJK UNIFIED IDEOGRAPH + {0x9E5C, 0x7004}, //5539 #CJK UNIFIED IDEOGRAPH + {0x9E5D, 0x7005}, //5540 #CJK UNIFIED IDEOGRAPH + {0x9E5E, 0x7006}, //5541 #CJK UNIFIED IDEOGRAPH + {0x9E5F, 0x7007}, //5542 #CJK UNIFIED IDEOGRAPH + {0x9E60, 0x7008}, //5543 #CJK UNIFIED IDEOGRAPH + {0x9E61, 0x7009}, //5544 #CJK UNIFIED IDEOGRAPH + {0x9E62, 0x700A}, //5545 #CJK UNIFIED IDEOGRAPH + {0x9E63, 0x700B}, //5546 #CJK UNIFIED IDEOGRAPH + {0x9E64, 0x700C}, //5547 #CJK UNIFIED IDEOGRAPH + {0x9E65, 0x700D}, //5548 #CJK UNIFIED IDEOGRAPH + {0x9E66, 0x700E}, //5549 #CJK UNIFIED IDEOGRAPH + {0x9E67, 0x700F}, //5550 #CJK UNIFIED IDEOGRAPH + {0x9E68, 0x7010}, //5551 #CJK UNIFIED IDEOGRAPH + {0x9E69, 0x7012}, //5552 #CJK UNIFIED IDEOGRAPH + {0x9E6A, 0x7013}, //5553 #CJK UNIFIED IDEOGRAPH + {0x9E6B, 0x7014}, //5554 #CJK UNIFIED IDEOGRAPH + {0x9E6C, 0x7015}, //5555 #CJK UNIFIED IDEOGRAPH + {0x9E6D, 0x7016}, //5556 #CJK UNIFIED IDEOGRAPH + {0x9E6E, 0x7017}, //5557 #CJK UNIFIED IDEOGRAPH + {0x9E6F, 0x7018}, //5558 #CJK UNIFIED IDEOGRAPH + {0x9E70, 0x7019}, //5559 #CJK UNIFIED IDEOGRAPH + {0x9E71, 0x701C}, //5560 #CJK UNIFIED IDEOGRAPH + {0x9E72, 0x701D}, //5561 #CJK UNIFIED IDEOGRAPH + {0x9E73, 0x701E}, //5562 #CJK UNIFIED IDEOGRAPH + {0x9E74, 0x701F}, //5563 #CJK UNIFIED IDEOGRAPH + {0x9E75, 0x7020}, //5564 #CJK UNIFIED IDEOGRAPH + {0x9E76, 0x7021}, //5565 #CJK UNIFIED IDEOGRAPH + {0x9E77, 0x7022}, //5566 #CJK UNIFIED IDEOGRAPH + {0x9E78, 0x7024}, //5567 #CJK UNIFIED IDEOGRAPH + {0x9E79, 0x7025}, //5568 #CJK UNIFIED IDEOGRAPH + {0x9E7A, 0x7026}, //5569 #CJK UNIFIED IDEOGRAPH + {0x9E7B, 0x7027}, //5570 #CJK UNIFIED IDEOGRAPH + {0x9E7C, 0x7028}, //5571 #CJK UNIFIED IDEOGRAPH + {0x9E7D, 0x7029}, //5572 #CJK UNIFIED IDEOGRAPH + {0x9E7E, 0x702A}, //5573 #CJK UNIFIED IDEOGRAPH + {0x9E80, 0x702B}, //5574 #CJK UNIFIED IDEOGRAPH + {0x9E81, 0x702C}, //5575 #CJK UNIFIED IDEOGRAPH + {0x9E82, 0x702D}, //5576 #CJK UNIFIED IDEOGRAPH + {0x9E83, 0x702E}, //5577 #CJK UNIFIED IDEOGRAPH + {0x9E84, 0x702F}, //5578 #CJK UNIFIED IDEOGRAPH + {0x9E85, 0x7030}, //5579 #CJK UNIFIED IDEOGRAPH + {0x9E86, 0x7031}, //5580 #CJK UNIFIED IDEOGRAPH + {0x9E87, 0x7032}, //5581 #CJK UNIFIED IDEOGRAPH + {0x9E88, 0x7033}, //5582 #CJK UNIFIED IDEOGRAPH + {0x9E89, 0x7034}, //5583 #CJK UNIFIED IDEOGRAPH + {0x9E8A, 0x7036}, //5584 #CJK UNIFIED IDEOGRAPH + {0x9E8B, 0x7037}, //5585 #CJK UNIFIED IDEOGRAPH + {0x9E8C, 0x7038}, //5586 #CJK UNIFIED IDEOGRAPH + {0x9E8D, 0x703A}, //5587 #CJK UNIFIED IDEOGRAPH + {0x9E8E, 0x703B}, //5588 #CJK UNIFIED IDEOGRAPH + {0x9E8F, 0x703C}, //5589 #CJK UNIFIED IDEOGRAPH + {0x9E90, 0x703D}, //5590 #CJK UNIFIED IDEOGRAPH + {0x9E91, 0x703E}, //5591 #CJK UNIFIED IDEOGRAPH + {0x9E92, 0x703F}, //5592 #CJK UNIFIED IDEOGRAPH + {0x9E93, 0x7040}, //5593 #CJK UNIFIED IDEOGRAPH + {0x9E94, 0x7041}, //5594 #CJK UNIFIED IDEOGRAPH + {0x9E95, 0x7042}, //5595 #CJK UNIFIED IDEOGRAPH + {0x9E96, 0x7043}, //5596 #CJK UNIFIED IDEOGRAPH + {0x9E97, 0x7044}, //5597 #CJK UNIFIED IDEOGRAPH + {0x9E98, 0x7045}, //5598 #CJK UNIFIED IDEOGRAPH + {0x9E99, 0x7046}, //5599 #CJK UNIFIED IDEOGRAPH + {0x9E9A, 0x7047}, //5600 #CJK UNIFIED IDEOGRAPH + {0x9E9B, 0x7048}, //5601 #CJK UNIFIED IDEOGRAPH + {0x9E9C, 0x7049}, //5602 #CJK UNIFIED IDEOGRAPH + {0x9E9D, 0x704A}, //5603 #CJK UNIFIED IDEOGRAPH + {0x9E9E, 0x704B}, //5604 #CJK UNIFIED IDEOGRAPH + {0x9E9F, 0x704D}, //5605 #CJK UNIFIED IDEOGRAPH + {0x9EA0, 0x704E}, //5606 #CJK UNIFIED IDEOGRAPH + {0x9EA1, 0x7050}, //5607 #CJK UNIFIED IDEOGRAPH + {0x9EA2, 0x7051}, //5608 #CJK UNIFIED IDEOGRAPH + {0x9EA3, 0x7052}, //5609 #CJK UNIFIED IDEOGRAPH + {0x9EA4, 0x7053}, //5610 #CJK UNIFIED IDEOGRAPH + {0x9EA5, 0x7054}, //5611 #CJK UNIFIED IDEOGRAPH + {0x9EA6, 0x7055}, //5612 #CJK UNIFIED IDEOGRAPH + {0x9EA7, 0x7056}, //5613 #CJK UNIFIED IDEOGRAPH + {0x9EA8, 0x7057}, //5614 #CJK UNIFIED IDEOGRAPH + {0x9EA9, 0x7058}, //5615 #CJK UNIFIED IDEOGRAPH + {0x9EAA, 0x7059}, //5616 #CJK UNIFIED IDEOGRAPH + {0x9EAB, 0x705A}, //5617 #CJK UNIFIED IDEOGRAPH + {0x9EAC, 0x705B}, //5618 #CJK UNIFIED IDEOGRAPH + {0x9EAD, 0x705C}, //5619 #CJK UNIFIED IDEOGRAPH + {0x9EAE, 0x705D}, //5620 #CJK UNIFIED IDEOGRAPH + {0x9EAF, 0x705F}, //5621 #CJK UNIFIED IDEOGRAPH + {0x9EB0, 0x7060}, //5622 #CJK UNIFIED IDEOGRAPH + {0x9EB1, 0x7061}, //5623 #CJK UNIFIED IDEOGRAPH + {0x9EB2, 0x7062}, //5624 #CJK UNIFIED IDEOGRAPH + {0x9EB3, 0x7063}, //5625 #CJK UNIFIED IDEOGRAPH + {0x9EB4, 0x7064}, //5626 #CJK UNIFIED IDEOGRAPH + {0x9EB5, 0x7065}, //5627 #CJK UNIFIED IDEOGRAPH + {0x9EB6, 0x7066}, //5628 #CJK UNIFIED IDEOGRAPH + {0x9EB7, 0x7067}, //5629 #CJK UNIFIED IDEOGRAPH + {0x9EB8, 0x7068}, //5630 #CJK UNIFIED IDEOGRAPH + {0x9EB9, 0x7069}, //5631 #CJK UNIFIED IDEOGRAPH + {0x9EBA, 0x706A}, //5632 #CJK UNIFIED IDEOGRAPH + {0x9EBB, 0x706E}, //5633 #CJK UNIFIED IDEOGRAPH + {0x9EBC, 0x7071}, //5634 #CJK UNIFIED IDEOGRAPH + {0x9EBD, 0x7072}, //5635 #CJK UNIFIED IDEOGRAPH + {0x9EBE, 0x7073}, //5636 #CJK UNIFIED IDEOGRAPH + {0x9EBF, 0x7074}, //5637 #CJK UNIFIED IDEOGRAPH + {0x9EC0, 0x7077}, //5638 #CJK UNIFIED IDEOGRAPH + {0x9EC1, 0x7079}, //5639 #CJK UNIFIED IDEOGRAPH + {0x9EC2, 0x707A}, //5640 #CJK UNIFIED IDEOGRAPH + {0x9EC3, 0x707B}, //5641 #CJK UNIFIED IDEOGRAPH + {0x9EC4, 0x707D}, //5642 #CJK UNIFIED IDEOGRAPH + {0x9EC5, 0x7081}, //5643 #CJK UNIFIED IDEOGRAPH + {0x9EC6, 0x7082}, //5644 #CJK UNIFIED IDEOGRAPH + {0x9EC7, 0x7083}, //5645 #CJK UNIFIED IDEOGRAPH + {0x9EC8, 0x7084}, //5646 #CJK UNIFIED IDEOGRAPH + {0x9EC9, 0x7086}, //5647 #CJK UNIFIED IDEOGRAPH + {0x9ECA, 0x7087}, //5648 #CJK UNIFIED IDEOGRAPH + {0x9ECB, 0x7088}, //5649 #CJK UNIFIED IDEOGRAPH + {0x9ECC, 0x708B}, //5650 #CJK UNIFIED IDEOGRAPH + {0x9ECD, 0x708C}, //5651 #CJK UNIFIED IDEOGRAPH + {0x9ECE, 0x708D}, //5652 #CJK UNIFIED IDEOGRAPH + {0x9ECF, 0x708F}, //5653 #CJK UNIFIED IDEOGRAPH + {0x9ED0, 0x7090}, //5654 #CJK UNIFIED IDEOGRAPH + {0x9ED1, 0x7091}, //5655 #CJK UNIFIED IDEOGRAPH + {0x9ED2, 0x7093}, //5656 #CJK UNIFIED IDEOGRAPH + {0x9ED3, 0x7097}, //5657 #CJK UNIFIED IDEOGRAPH + {0x9ED4, 0x7098}, //5658 #CJK UNIFIED IDEOGRAPH + {0x9ED5, 0x709A}, //5659 #CJK UNIFIED IDEOGRAPH + {0x9ED6, 0x709B}, //5660 #CJK UNIFIED IDEOGRAPH + {0x9ED7, 0x709E}, //5661 #CJK UNIFIED IDEOGRAPH + {0x9ED8, 0x709F}, //5662 #CJK UNIFIED IDEOGRAPH + {0x9ED9, 0x70A0}, //5663 #CJK UNIFIED IDEOGRAPH + {0x9EDA, 0x70A1}, //5664 #CJK UNIFIED IDEOGRAPH + {0x9EDB, 0x70A2}, //5665 #CJK UNIFIED IDEOGRAPH + {0x9EDC, 0x70A3}, //5666 #CJK UNIFIED IDEOGRAPH + {0x9EDD, 0x70A4}, //5667 #CJK UNIFIED IDEOGRAPH + {0x9EDE, 0x70A5}, //5668 #CJK UNIFIED IDEOGRAPH + {0x9EDF, 0x70A6}, //5669 #CJK UNIFIED IDEOGRAPH + {0x9EE0, 0x70A7}, //5670 #CJK UNIFIED IDEOGRAPH + {0x9EE1, 0x70A8}, //5671 #CJK UNIFIED IDEOGRAPH + {0x9EE2, 0x70A9}, //5672 #CJK UNIFIED IDEOGRAPH + {0x9EE3, 0x70AA}, //5673 #CJK UNIFIED IDEOGRAPH + {0x9EE4, 0x70B0}, //5674 #CJK UNIFIED IDEOGRAPH + {0x9EE5, 0x70B2}, //5675 #CJK UNIFIED IDEOGRAPH + {0x9EE6, 0x70B4}, //5676 #CJK UNIFIED IDEOGRAPH + {0x9EE7, 0x70B5}, //5677 #CJK UNIFIED IDEOGRAPH + {0x9EE8, 0x70B6}, //5678 #CJK UNIFIED IDEOGRAPH + {0x9EE9, 0x70BA}, //5679 #CJK UNIFIED IDEOGRAPH + {0x9EEA, 0x70BE}, //5680 #CJK UNIFIED IDEOGRAPH + {0x9EEB, 0x70BF}, //5681 #CJK UNIFIED IDEOGRAPH + {0x9EEC, 0x70C4}, //5682 #CJK UNIFIED IDEOGRAPH + {0x9EED, 0x70C5}, //5683 #CJK UNIFIED IDEOGRAPH + {0x9EEE, 0x70C6}, //5684 #CJK UNIFIED IDEOGRAPH + {0x9EEF, 0x70C7}, //5685 #CJK UNIFIED IDEOGRAPH + {0x9EF0, 0x70C9}, //5686 #CJK UNIFIED IDEOGRAPH + {0x9EF1, 0x70CB}, //5687 #CJK UNIFIED IDEOGRAPH + {0x9EF2, 0x70CC}, //5688 #CJK UNIFIED IDEOGRAPH + {0x9EF3, 0x70CD}, //5689 #CJK UNIFIED IDEOGRAPH + {0x9EF4, 0x70CE}, //5690 #CJK UNIFIED IDEOGRAPH + {0x9EF5, 0x70CF}, //5691 #CJK UNIFIED IDEOGRAPH + {0x9EF6, 0x70D0}, //5692 #CJK UNIFIED IDEOGRAPH + {0x9EF7, 0x70D1}, //5693 #CJK UNIFIED IDEOGRAPH + {0x9EF8, 0x70D2}, //5694 #CJK UNIFIED IDEOGRAPH + {0x9EF9, 0x70D3}, //5695 #CJK UNIFIED IDEOGRAPH + {0x9EFA, 0x70D4}, //5696 #CJK UNIFIED IDEOGRAPH + {0x9EFB, 0x70D5}, //5697 #CJK UNIFIED IDEOGRAPH + {0x9EFC, 0x70D6}, //5698 #CJK UNIFIED IDEOGRAPH + {0x9EFD, 0x70D7}, //5699 #CJK UNIFIED IDEOGRAPH + {0x9EFE, 0x70DA}, //5700 #CJK UNIFIED IDEOGRAPH + {0x9F40, 0x70DC}, //5701 #CJK UNIFIED IDEOGRAPH + {0x9F41, 0x70DD}, //5702 #CJK UNIFIED IDEOGRAPH + {0x9F42, 0x70DE}, //5703 #CJK UNIFIED IDEOGRAPH + {0x9F43, 0x70E0}, //5704 #CJK UNIFIED IDEOGRAPH + {0x9F44, 0x70E1}, //5705 #CJK UNIFIED IDEOGRAPH + {0x9F45, 0x70E2}, //5706 #CJK UNIFIED IDEOGRAPH + {0x9F46, 0x70E3}, //5707 #CJK UNIFIED IDEOGRAPH + {0x9F47, 0x70E5}, //5708 #CJK UNIFIED IDEOGRAPH + {0x9F48, 0x70EA}, //5709 #CJK UNIFIED IDEOGRAPH + {0x9F49, 0x70EE}, //5710 #CJK UNIFIED IDEOGRAPH + {0x9F4A, 0x70F0}, //5711 #CJK UNIFIED IDEOGRAPH + {0x9F4B, 0x70F1}, //5712 #CJK UNIFIED IDEOGRAPH + {0x9F4C, 0x70F2}, //5713 #CJK UNIFIED IDEOGRAPH + {0x9F4D, 0x70F3}, //5714 #CJK UNIFIED IDEOGRAPH + {0x9F4E, 0x70F4}, //5715 #CJK UNIFIED IDEOGRAPH + {0x9F4F, 0x70F5}, //5716 #CJK UNIFIED IDEOGRAPH + {0x9F50, 0x70F6}, //5717 #CJK UNIFIED IDEOGRAPH + {0x9F51, 0x70F8}, //5718 #CJK UNIFIED IDEOGRAPH + {0x9F52, 0x70FA}, //5719 #CJK UNIFIED IDEOGRAPH + {0x9F53, 0x70FB}, //5720 #CJK UNIFIED IDEOGRAPH + {0x9F54, 0x70FC}, //5721 #CJK UNIFIED IDEOGRAPH + {0x9F55, 0x70FE}, //5722 #CJK UNIFIED IDEOGRAPH + {0x9F56, 0x70FF}, //5723 #CJK UNIFIED IDEOGRAPH + {0x9F57, 0x7100}, //5724 #CJK UNIFIED IDEOGRAPH + {0x9F58, 0x7101}, //5725 #CJK UNIFIED IDEOGRAPH + {0x9F59, 0x7102}, //5726 #CJK UNIFIED IDEOGRAPH + {0x9F5A, 0x7103}, //5727 #CJK UNIFIED IDEOGRAPH + {0x9F5B, 0x7104}, //5728 #CJK UNIFIED IDEOGRAPH + {0x9F5C, 0x7105}, //5729 #CJK UNIFIED IDEOGRAPH + {0x9F5D, 0x7106}, //5730 #CJK UNIFIED IDEOGRAPH + {0x9F5E, 0x7107}, //5731 #CJK UNIFIED IDEOGRAPH + {0x9F5F, 0x7108}, //5732 #CJK UNIFIED IDEOGRAPH + {0x9F60, 0x710B}, //5733 #CJK UNIFIED IDEOGRAPH + {0x9F61, 0x710C}, //5734 #CJK UNIFIED IDEOGRAPH + {0x9F62, 0x710D}, //5735 #CJK UNIFIED IDEOGRAPH + {0x9F63, 0x710E}, //5736 #CJK UNIFIED IDEOGRAPH + {0x9F64, 0x710F}, //5737 #CJK UNIFIED IDEOGRAPH + {0x9F65, 0x7111}, //5738 #CJK UNIFIED IDEOGRAPH + {0x9F66, 0x7112}, //5739 #CJK UNIFIED IDEOGRAPH + {0x9F67, 0x7114}, //5740 #CJK UNIFIED IDEOGRAPH + {0x9F68, 0x7117}, //5741 #CJK UNIFIED IDEOGRAPH + {0x9F69, 0x711B}, //5742 #CJK UNIFIED IDEOGRAPH + {0x9F6A, 0x711C}, //5743 #CJK UNIFIED IDEOGRAPH + {0x9F6B, 0x711D}, //5744 #CJK UNIFIED IDEOGRAPH + {0x9F6C, 0x711E}, //5745 #CJK UNIFIED IDEOGRAPH + {0x9F6D, 0x711F}, //5746 #CJK UNIFIED IDEOGRAPH + {0x9F6E, 0x7120}, //5747 #CJK UNIFIED IDEOGRAPH + {0x9F6F, 0x7121}, //5748 #CJK UNIFIED IDEOGRAPH + {0x9F70, 0x7122}, //5749 #CJK UNIFIED IDEOGRAPH + {0x9F71, 0x7123}, //5750 #CJK UNIFIED IDEOGRAPH + {0x9F72, 0x7124}, //5751 #CJK UNIFIED IDEOGRAPH + {0x9F73, 0x7125}, //5752 #CJK UNIFIED IDEOGRAPH + {0x9F74, 0x7127}, //5753 #CJK UNIFIED IDEOGRAPH + {0x9F75, 0x7128}, //5754 #CJK UNIFIED IDEOGRAPH + {0x9F76, 0x7129}, //5755 #CJK UNIFIED IDEOGRAPH + {0x9F77, 0x712A}, //5756 #CJK UNIFIED IDEOGRAPH + {0x9F78, 0x712B}, //5757 #CJK UNIFIED IDEOGRAPH + {0x9F79, 0x712C}, //5758 #CJK UNIFIED IDEOGRAPH + {0x9F7A, 0x712D}, //5759 #CJK UNIFIED IDEOGRAPH + {0x9F7B, 0x712E}, //5760 #CJK UNIFIED IDEOGRAPH + {0x9F7C, 0x7132}, //5761 #CJK UNIFIED IDEOGRAPH + {0x9F7D, 0x7133}, //5762 #CJK UNIFIED IDEOGRAPH + {0x9F7E, 0x7134}, //5763 #CJK UNIFIED IDEOGRAPH + {0x9F80, 0x7135}, //5764 #CJK UNIFIED IDEOGRAPH + {0x9F81, 0x7137}, //5765 #CJK UNIFIED IDEOGRAPH + {0x9F82, 0x7138}, //5766 #CJK UNIFIED IDEOGRAPH + {0x9F83, 0x7139}, //5767 #CJK UNIFIED IDEOGRAPH + {0x9F84, 0x713A}, //5768 #CJK UNIFIED IDEOGRAPH + {0x9F85, 0x713B}, //5769 #CJK UNIFIED IDEOGRAPH + {0x9F86, 0x713C}, //5770 #CJK UNIFIED IDEOGRAPH + {0x9F87, 0x713D}, //5771 #CJK UNIFIED IDEOGRAPH + {0x9F88, 0x713E}, //5772 #CJK UNIFIED IDEOGRAPH + {0x9F89, 0x713F}, //5773 #CJK UNIFIED IDEOGRAPH + {0x9F8A, 0x7140}, //5774 #CJK UNIFIED IDEOGRAPH + {0x9F8B, 0x7141}, //5775 #CJK UNIFIED IDEOGRAPH + {0x9F8C, 0x7142}, //5776 #CJK UNIFIED IDEOGRAPH + {0x9F8D, 0x7143}, //5777 #CJK UNIFIED IDEOGRAPH + {0x9F8E, 0x7144}, //5778 #CJK UNIFIED IDEOGRAPH + {0x9F8F, 0x7146}, //5779 #CJK UNIFIED IDEOGRAPH + {0x9F90, 0x7147}, //5780 #CJK UNIFIED IDEOGRAPH + {0x9F91, 0x7148}, //5781 #CJK UNIFIED IDEOGRAPH + {0x9F92, 0x7149}, //5782 #CJK UNIFIED IDEOGRAPH + {0x9F93, 0x714B}, //5783 #CJK UNIFIED IDEOGRAPH + {0x9F94, 0x714D}, //5784 #CJK UNIFIED IDEOGRAPH + {0x9F95, 0x714F}, //5785 #CJK UNIFIED IDEOGRAPH + {0x9F96, 0x7150}, //5786 #CJK UNIFIED IDEOGRAPH + {0x9F97, 0x7151}, //5787 #CJK UNIFIED IDEOGRAPH + {0x9F98, 0x7152}, //5788 #CJK UNIFIED IDEOGRAPH + {0x9F99, 0x7153}, //5789 #CJK UNIFIED IDEOGRAPH + {0x9F9A, 0x7154}, //5790 #CJK UNIFIED IDEOGRAPH + {0x9F9B, 0x7155}, //5791 #CJK UNIFIED IDEOGRAPH + {0x9F9C, 0x7156}, //5792 #CJK UNIFIED IDEOGRAPH + {0x9F9D, 0x7157}, //5793 #CJK UNIFIED IDEOGRAPH + {0x9F9E, 0x7158}, //5794 #CJK UNIFIED IDEOGRAPH + {0x9F9F, 0x7159}, //5795 #CJK UNIFIED IDEOGRAPH + {0x9FA0, 0x715A}, //5796 #CJK UNIFIED IDEOGRAPH + {0x9FA1, 0x715B}, //5797 #CJK UNIFIED IDEOGRAPH + {0x9FA2, 0x715D}, //5798 #CJK UNIFIED IDEOGRAPH + {0x9FA3, 0x715F}, //5799 #CJK UNIFIED IDEOGRAPH + {0x9FA4, 0x7160}, //5800 #CJK UNIFIED IDEOGRAPH + {0x9FA5, 0x7161}, //5801 #CJK UNIFIED IDEOGRAPH + {0x9FA6, 0x7162}, //5802 #CJK UNIFIED IDEOGRAPH + {0x9FA7, 0x7163}, //5803 #CJK UNIFIED IDEOGRAPH + {0x9FA8, 0x7165}, //5804 #CJK UNIFIED IDEOGRAPH + {0x9FA9, 0x7169}, //5805 #CJK UNIFIED IDEOGRAPH + {0x9FAA, 0x716A}, //5806 #CJK UNIFIED IDEOGRAPH + {0x9FAB, 0x716B}, //5807 #CJK UNIFIED IDEOGRAPH + {0x9FAC, 0x716C}, //5808 #CJK UNIFIED IDEOGRAPH + {0x9FAD, 0x716D}, //5809 #CJK UNIFIED IDEOGRAPH + {0x9FAE, 0x716F}, //5810 #CJK UNIFIED IDEOGRAPH + {0x9FAF, 0x7170}, //5811 #CJK UNIFIED IDEOGRAPH + {0x9FB0, 0x7171}, //5812 #CJK UNIFIED IDEOGRAPH + {0x9FB1, 0x7174}, //5813 #CJK UNIFIED IDEOGRAPH + {0x9FB2, 0x7175}, //5814 #CJK UNIFIED IDEOGRAPH + {0x9FB3, 0x7176}, //5815 #CJK UNIFIED IDEOGRAPH + {0x9FB4, 0x7177}, //5816 #CJK UNIFIED IDEOGRAPH + {0x9FB5, 0x7179}, //5817 #CJK UNIFIED IDEOGRAPH + {0x9FB6, 0x717B}, //5818 #CJK UNIFIED IDEOGRAPH + {0x9FB7, 0x717C}, //5819 #CJK UNIFIED IDEOGRAPH + {0x9FB8, 0x717E}, //5820 #CJK UNIFIED IDEOGRAPH + {0x9FB9, 0x717F}, //5821 #CJK UNIFIED IDEOGRAPH + {0x9FBA, 0x7180}, //5822 #CJK UNIFIED IDEOGRAPH + {0x9FBB, 0x7181}, //5823 #CJK UNIFIED IDEOGRAPH + {0x9FBC, 0x7182}, //5824 #CJK UNIFIED IDEOGRAPH + {0x9FBD, 0x7183}, //5825 #CJK UNIFIED IDEOGRAPH + {0x9FBE, 0x7185}, //5826 #CJK UNIFIED IDEOGRAPH + {0x9FBF, 0x7186}, //5827 #CJK UNIFIED IDEOGRAPH + {0x9FC0, 0x7187}, //5828 #CJK UNIFIED IDEOGRAPH + {0x9FC1, 0x7188}, //5829 #CJK UNIFIED IDEOGRAPH + {0x9FC2, 0x7189}, //5830 #CJK UNIFIED IDEOGRAPH + {0x9FC3, 0x718B}, //5831 #CJK UNIFIED IDEOGRAPH + {0x9FC4, 0x718C}, //5832 #CJK UNIFIED IDEOGRAPH + {0x9FC5, 0x718D}, //5833 #CJK UNIFIED IDEOGRAPH + {0x9FC6, 0x718E}, //5834 #CJK UNIFIED IDEOGRAPH + {0x9FC7, 0x7190}, //5835 #CJK UNIFIED IDEOGRAPH + {0x9FC8, 0x7191}, //5836 #CJK UNIFIED IDEOGRAPH + {0x9FC9, 0x7192}, //5837 #CJK UNIFIED IDEOGRAPH + {0x9FCA, 0x7193}, //5838 #CJK UNIFIED IDEOGRAPH + {0x9FCB, 0x7195}, //5839 #CJK UNIFIED IDEOGRAPH + {0x9FCC, 0x7196}, //5840 #CJK UNIFIED IDEOGRAPH + {0x9FCD, 0x7197}, //5841 #CJK UNIFIED IDEOGRAPH + {0x9FCE, 0x719A}, //5842 #CJK UNIFIED IDEOGRAPH + {0x9FCF, 0x719B}, //5843 #CJK UNIFIED IDEOGRAPH + {0x9FD0, 0x719C}, //5844 #CJK UNIFIED IDEOGRAPH + {0x9FD1, 0x719D}, //5845 #CJK UNIFIED IDEOGRAPH + {0x9FD2, 0x719E}, //5846 #CJK UNIFIED IDEOGRAPH + {0x9FD3, 0x71A1}, //5847 #CJK UNIFIED IDEOGRAPH + {0x9FD4, 0x71A2}, //5848 #CJK UNIFIED IDEOGRAPH + {0x9FD5, 0x71A3}, //5849 #CJK UNIFIED IDEOGRAPH + {0x9FD6, 0x71A4}, //5850 #CJK UNIFIED IDEOGRAPH + {0x9FD7, 0x71A5}, //5851 #CJK UNIFIED IDEOGRAPH + {0x9FD8, 0x71A6}, //5852 #CJK UNIFIED IDEOGRAPH + {0x9FD9, 0x71A7}, //5853 #CJK UNIFIED IDEOGRAPH + {0x9FDA, 0x71A9}, //5854 #CJK UNIFIED IDEOGRAPH + {0x9FDB, 0x71AA}, //5855 #CJK UNIFIED IDEOGRAPH + {0x9FDC, 0x71AB}, //5856 #CJK UNIFIED IDEOGRAPH + {0x9FDD, 0x71AD}, //5857 #CJK UNIFIED IDEOGRAPH + {0x9FDE, 0x71AE}, //5858 #CJK UNIFIED IDEOGRAPH + {0x9FDF, 0x71AF}, //5859 #CJK UNIFIED IDEOGRAPH + {0x9FE0, 0x71B0}, //5860 #CJK UNIFIED IDEOGRAPH + {0x9FE1, 0x71B1}, //5861 #CJK UNIFIED IDEOGRAPH + {0x9FE2, 0x71B2}, //5862 #CJK UNIFIED IDEOGRAPH + {0x9FE3, 0x71B4}, //5863 #CJK UNIFIED IDEOGRAPH + {0x9FE4, 0x71B6}, //5864 #CJK UNIFIED IDEOGRAPH + {0x9FE5, 0x71B7}, //5865 #CJK UNIFIED IDEOGRAPH + {0x9FE6, 0x71B8}, //5866 #CJK UNIFIED IDEOGRAPH + {0x9FE7, 0x71BA}, //5867 #CJK UNIFIED IDEOGRAPH + {0x9FE8, 0x71BB}, //5868 #CJK UNIFIED IDEOGRAPH + {0x9FE9, 0x71BC}, //5869 #CJK UNIFIED IDEOGRAPH + {0x9FEA, 0x71BD}, //5870 #CJK UNIFIED IDEOGRAPH + {0x9FEB, 0x71BE}, //5871 #CJK UNIFIED IDEOGRAPH + {0x9FEC, 0x71BF}, //5872 #CJK UNIFIED IDEOGRAPH + {0x9FED, 0x71C0}, //5873 #CJK UNIFIED IDEOGRAPH + {0x9FEE, 0x71C1}, //5874 #CJK UNIFIED IDEOGRAPH + {0x9FEF, 0x71C2}, //5875 #CJK UNIFIED IDEOGRAPH + {0x9FF0, 0x71C4}, //5876 #CJK UNIFIED IDEOGRAPH + {0x9FF1, 0x71C5}, //5877 #CJK UNIFIED IDEOGRAPH + {0x9FF2, 0x71C6}, //5878 #CJK UNIFIED IDEOGRAPH + {0x9FF3, 0x71C7}, //5879 #CJK UNIFIED IDEOGRAPH + {0x9FF4, 0x71C8}, //5880 #CJK UNIFIED IDEOGRAPH + {0x9FF5, 0x71C9}, //5881 #CJK UNIFIED IDEOGRAPH + {0x9FF6, 0x71CA}, //5882 #CJK UNIFIED IDEOGRAPH + {0x9FF7, 0x71CB}, //5883 #CJK UNIFIED IDEOGRAPH + {0x9FF8, 0x71CC}, //5884 #CJK UNIFIED IDEOGRAPH + {0x9FF9, 0x71CD}, //5885 #CJK UNIFIED IDEOGRAPH + {0x9FFA, 0x71CF}, //5886 #CJK UNIFIED IDEOGRAPH + {0x9FFB, 0x71D0}, //5887 #CJK UNIFIED IDEOGRAPH + {0x9FFC, 0x71D1}, //5888 #CJK UNIFIED IDEOGRAPH + {0x9FFD, 0x71D2}, //5889 #CJK UNIFIED IDEOGRAPH + {0x9FFE, 0x71D3}, //5890 #CJK UNIFIED IDEOGRAPH + {0xA040, 0x71D6}, //5891 #CJK UNIFIED IDEOGRAPH + {0xA041, 0x71D7}, //5892 #CJK UNIFIED IDEOGRAPH + {0xA042, 0x71D8}, //5893 #CJK UNIFIED IDEOGRAPH + {0xA043, 0x71D9}, //5894 #CJK UNIFIED IDEOGRAPH + {0xA044, 0x71DA}, //5895 #CJK UNIFIED IDEOGRAPH + {0xA045, 0x71DB}, //5896 #CJK UNIFIED IDEOGRAPH + {0xA046, 0x71DC}, //5897 #CJK UNIFIED IDEOGRAPH + {0xA047, 0x71DD}, //5898 #CJK UNIFIED IDEOGRAPH + {0xA048, 0x71DE}, //5899 #CJK UNIFIED IDEOGRAPH + {0xA049, 0x71DF}, //5900 #CJK UNIFIED IDEOGRAPH + {0xA04A, 0x71E1}, //5901 #CJK UNIFIED IDEOGRAPH + {0xA04B, 0x71E2}, //5902 #CJK UNIFIED IDEOGRAPH + {0xA04C, 0x71E3}, //5903 #CJK UNIFIED IDEOGRAPH + {0xA04D, 0x71E4}, //5904 #CJK UNIFIED IDEOGRAPH + {0xA04E, 0x71E6}, //5905 #CJK UNIFIED IDEOGRAPH + {0xA04F, 0x71E8}, //5906 #CJK UNIFIED IDEOGRAPH + {0xA050, 0x71E9}, //5907 #CJK UNIFIED IDEOGRAPH + {0xA051, 0x71EA}, //5908 #CJK UNIFIED IDEOGRAPH + {0xA052, 0x71EB}, //5909 #CJK UNIFIED IDEOGRAPH + {0xA053, 0x71EC}, //5910 #CJK UNIFIED IDEOGRAPH + {0xA054, 0x71ED}, //5911 #CJK UNIFIED IDEOGRAPH + {0xA055, 0x71EF}, //5912 #CJK UNIFIED IDEOGRAPH + {0xA056, 0x71F0}, //5913 #CJK UNIFIED IDEOGRAPH + {0xA057, 0x71F1}, //5914 #CJK UNIFIED IDEOGRAPH + {0xA058, 0x71F2}, //5915 #CJK UNIFIED IDEOGRAPH + {0xA059, 0x71F3}, //5916 #CJK UNIFIED IDEOGRAPH + {0xA05A, 0x71F4}, //5917 #CJK UNIFIED IDEOGRAPH + {0xA05B, 0x71F5}, //5918 #CJK UNIFIED IDEOGRAPH + {0xA05C, 0x71F6}, //5919 #CJK UNIFIED IDEOGRAPH + {0xA05D, 0x71F7}, //5920 #CJK UNIFIED IDEOGRAPH + {0xA05E, 0x71F8}, //5921 #CJK UNIFIED IDEOGRAPH + {0xA05F, 0x71FA}, //5922 #CJK UNIFIED IDEOGRAPH + {0xA060, 0x71FB}, //5923 #CJK UNIFIED IDEOGRAPH + {0xA061, 0x71FC}, //5924 #CJK UNIFIED IDEOGRAPH + {0xA062, 0x71FD}, //5925 #CJK UNIFIED IDEOGRAPH + {0xA063, 0x71FE}, //5926 #CJK UNIFIED IDEOGRAPH + {0xA064, 0x71FF}, //5927 #CJK UNIFIED IDEOGRAPH + {0xA065, 0x7200}, //5928 #CJK UNIFIED IDEOGRAPH + {0xA066, 0x7201}, //5929 #CJK UNIFIED IDEOGRAPH + {0xA067, 0x7202}, //5930 #CJK UNIFIED IDEOGRAPH + {0xA068, 0x7203}, //5931 #CJK UNIFIED IDEOGRAPH + {0xA069, 0x7204}, //5932 #CJK UNIFIED IDEOGRAPH + {0xA06A, 0x7205}, //5933 #CJK UNIFIED IDEOGRAPH + {0xA06B, 0x7207}, //5934 #CJK UNIFIED IDEOGRAPH + {0xA06C, 0x7208}, //5935 #CJK UNIFIED IDEOGRAPH + {0xA06D, 0x7209}, //5936 #CJK UNIFIED IDEOGRAPH + {0xA06E, 0x720A}, //5937 #CJK UNIFIED IDEOGRAPH + {0xA06F, 0x720B}, //5938 #CJK UNIFIED IDEOGRAPH + {0xA070, 0x720C}, //5939 #CJK UNIFIED IDEOGRAPH + {0xA071, 0x720D}, //5940 #CJK UNIFIED IDEOGRAPH + {0xA072, 0x720E}, //5941 #CJK UNIFIED IDEOGRAPH + {0xA073, 0x720F}, //5942 #CJK UNIFIED IDEOGRAPH + {0xA074, 0x7210}, //5943 #CJK UNIFIED IDEOGRAPH + {0xA075, 0x7211}, //5944 #CJK UNIFIED IDEOGRAPH + {0xA076, 0x7212}, //5945 #CJK UNIFIED IDEOGRAPH + {0xA077, 0x7213}, //5946 #CJK UNIFIED IDEOGRAPH + {0xA078, 0x7214}, //5947 #CJK UNIFIED IDEOGRAPH + {0xA079, 0x7215}, //5948 #CJK UNIFIED IDEOGRAPH + {0xA07A, 0x7216}, //5949 #CJK UNIFIED IDEOGRAPH + {0xA07B, 0x7217}, //5950 #CJK UNIFIED IDEOGRAPH + {0xA07C, 0x7218}, //5951 #CJK UNIFIED IDEOGRAPH + {0xA07D, 0x7219}, //5952 #CJK UNIFIED IDEOGRAPH + {0xA07E, 0x721A}, //5953 #CJK UNIFIED IDEOGRAPH + {0xA080, 0x721B}, //5954 #CJK UNIFIED IDEOGRAPH + {0xA081, 0x721C}, //5955 #CJK UNIFIED IDEOGRAPH + {0xA082, 0x721E}, //5956 #CJK UNIFIED IDEOGRAPH + {0xA083, 0x721F}, //5957 #CJK UNIFIED IDEOGRAPH + {0xA084, 0x7220}, //5958 #CJK UNIFIED IDEOGRAPH + {0xA085, 0x7221}, //5959 #CJK UNIFIED IDEOGRAPH + {0xA086, 0x7222}, //5960 #CJK UNIFIED IDEOGRAPH + {0xA087, 0x7223}, //5961 #CJK UNIFIED IDEOGRAPH + {0xA088, 0x7224}, //5962 #CJK UNIFIED IDEOGRAPH + {0xA089, 0x7225}, //5963 #CJK UNIFIED IDEOGRAPH + {0xA08A, 0x7226}, //5964 #CJK UNIFIED IDEOGRAPH + {0xA08B, 0x7227}, //5965 #CJK UNIFIED IDEOGRAPH + {0xA08C, 0x7229}, //5966 #CJK UNIFIED IDEOGRAPH + {0xA08D, 0x722B}, //5967 #CJK UNIFIED IDEOGRAPH + {0xA08E, 0x722D}, //5968 #CJK UNIFIED IDEOGRAPH + {0xA08F, 0x722E}, //5969 #CJK UNIFIED IDEOGRAPH + {0xA090, 0x722F}, //5970 #CJK UNIFIED IDEOGRAPH + {0xA091, 0x7232}, //5971 #CJK UNIFIED IDEOGRAPH + {0xA092, 0x7233}, //5972 #CJK UNIFIED IDEOGRAPH + {0xA093, 0x7234}, //5973 #CJK UNIFIED IDEOGRAPH + {0xA094, 0x723A}, //5974 #CJK UNIFIED IDEOGRAPH + {0xA095, 0x723C}, //5975 #CJK UNIFIED IDEOGRAPH + {0xA096, 0x723E}, //5976 #CJK UNIFIED IDEOGRAPH + {0xA097, 0x7240}, //5977 #CJK UNIFIED IDEOGRAPH + {0xA098, 0x7241}, //5978 #CJK UNIFIED IDEOGRAPH + {0xA099, 0x7242}, //5979 #CJK UNIFIED IDEOGRAPH + {0xA09A, 0x7243}, //5980 #CJK UNIFIED IDEOGRAPH + {0xA09B, 0x7244}, //5981 #CJK UNIFIED IDEOGRAPH + {0xA09C, 0x7245}, //5982 #CJK UNIFIED IDEOGRAPH + {0xA09D, 0x7246}, //5983 #CJK UNIFIED IDEOGRAPH + {0xA09E, 0x7249}, //5984 #CJK UNIFIED IDEOGRAPH + {0xA09F, 0x724A}, //5985 #CJK UNIFIED IDEOGRAPH + {0xA0A0, 0x724B}, //5986 #CJK UNIFIED IDEOGRAPH + {0xA0A1, 0x724E}, //5987 #CJK UNIFIED IDEOGRAPH + {0xA0A2, 0x724F}, //5988 #CJK UNIFIED IDEOGRAPH + {0xA0A3, 0x7250}, //5989 #CJK UNIFIED IDEOGRAPH + {0xA0A4, 0x7251}, //5990 #CJK UNIFIED IDEOGRAPH + {0xA0A5, 0x7253}, //5991 #CJK UNIFIED IDEOGRAPH + {0xA0A6, 0x7254}, //5992 #CJK UNIFIED IDEOGRAPH + {0xA0A7, 0x7255}, //5993 #CJK UNIFIED IDEOGRAPH + {0xA0A8, 0x7257}, //5994 #CJK UNIFIED IDEOGRAPH + {0xA0A9, 0x7258}, //5995 #CJK UNIFIED IDEOGRAPH + {0xA0AA, 0x725A}, //5996 #CJK UNIFIED IDEOGRAPH + {0xA0AB, 0x725C}, //5997 #CJK UNIFIED IDEOGRAPH + {0xA0AC, 0x725E}, //5998 #CJK UNIFIED IDEOGRAPH + {0xA0AD, 0x7260}, //5999 #CJK UNIFIED IDEOGRAPH + {0xA0AE, 0x7263}, //6000 #CJK UNIFIED IDEOGRAPH + {0xA0AF, 0x7264}, //6001 #CJK UNIFIED IDEOGRAPH + {0xA0B0, 0x7265}, //6002 #CJK UNIFIED IDEOGRAPH + {0xA0B1, 0x7268}, //6003 #CJK UNIFIED IDEOGRAPH + {0xA0B2, 0x726A}, //6004 #CJK UNIFIED IDEOGRAPH + {0xA0B3, 0x726B}, //6005 #CJK UNIFIED IDEOGRAPH + {0xA0B4, 0x726C}, //6006 #CJK UNIFIED IDEOGRAPH + {0xA0B5, 0x726D}, //6007 #CJK UNIFIED IDEOGRAPH + {0xA0B6, 0x7270}, //6008 #CJK UNIFIED IDEOGRAPH + {0xA0B7, 0x7271}, //6009 #CJK UNIFIED IDEOGRAPH + {0xA0B8, 0x7273}, //6010 #CJK UNIFIED IDEOGRAPH + {0xA0B9, 0x7274}, //6011 #CJK UNIFIED IDEOGRAPH + {0xA0BA, 0x7276}, //6012 #CJK UNIFIED IDEOGRAPH + {0xA0BB, 0x7277}, //6013 #CJK UNIFIED IDEOGRAPH + {0xA0BC, 0x7278}, //6014 #CJK UNIFIED IDEOGRAPH + {0xA0BD, 0x727B}, //6015 #CJK UNIFIED IDEOGRAPH + {0xA0BE, 0x727C}, //6016 #CJK UNIFIED IDEOGRAPH + {0xA0BF, 0x727D}, //6017 #CJK UNIFIED IDEOGRAPH + {0xA0C0, 0x7282}, //6018 #CJK UNIFIED IDEOGRAPH + {0xA0C1, 0x7283}, //6019 #CJK UNIFIED IDEOGRAPH + {0xA0C2, 0x7285}, //6020 #CJK UNIFIED IDEOGRAPH + {0xA0C3, 0x7286}, //6021 #CJK UNIFIED IDEOGRAPH + {0xA0C4, 0x7287}, //6022 #CJK UNIFIED IDEOGRAPH + {0xA0C5, 0x7288}, //6023 #CJK UNIFIED IDEOGRAPH + {0xA0C6, 0x7289}, //6024 #CJK UNIFIED IDEOGRAPH + {0xA0C7, 0x728C}, //6025 #CJK UNIFIED IDEOGRAPH + {0xA0C8, 0x728E}, //6026 #CJK UNIFIED IDEOGRAPH + {0xA0C9, 0x7290}, //6027 #CJK UNIFIED IDEOGRAPH + {0xA0CA, 0x7291}, //6028 #CJK UNIFIED IDEOGRAPH + {0xA0CB, 0x7293}, //6029 #CJK UNIFIED IDEOGRAPH + {0xA0CC, 0x7294}, //6030 #CJK UNIFIED IDEOGRAPH + {0xA0CD, 0x7295}, //6031 #CJK UNIFIED IDEOGRAPH + {0xA0CE, 0x7296}, //6032 #CJK UNIFIED IDEOGRAPH + {0xA0CF, 0x7297}, //6033 #CJK UNIFIED IDEOGRAPH + {0xA0D0, 0x7298}, //6034 #CJK UNIFIED IDEOGRAPH + {0xA0D1, 0x7299}, //6035 #CJK UNIFIED IDEOGRAPH + {0xA0D2, 0x729A}, //6036 #CJK UNIFIED IDEOGRAPH + {0xA0D3, 0x729B}, //6037 #CJK UNIFIED IDEOGRAPH + {0xA0D4, 0x729C}, //6038 #CJK UNIFIED IDEOGRAPH + {0xA0D5, 0x729D}, //6039 #CJK UNIFIED IDEOGRAPH + {0xA0D6, 0x729E}, //6040 #CJK UNIFIED IDEOGRAPH + {0xA0D7, 0x72A0}, //6041 #CJK UNIFIED IDEOGRAPH + {0xA0D8, 0x72A1}, //6042 #CJK UNIFIED IDEOGRAPH + {0xA0D9, 0x72A2}, //6043 #CJK UNIFIED IDEOGRAPH + {0xA0DA, 0x72A3}, //6044 #CJK UNIFIED IDEOGRAPH + {0xA0DB, 0x72A4}, //6045 #CJK UNIFIED IDEOGRAPH + {0xA0DC, 0x72A5}, //6046 #CJK UNIFIED IDEOGRAPH + {0xA0DD, 0x72A6}, //6047 #CJK UNIFIED IDEOGRAPH + {0xA0DE, 0x72A7}, //6048 #CJK UNIFIED IDEOGRAPH + {0xA0DF, 0x72A8}, //6049 #CJK UNIFIED IDEOGRAPH + {0xA0E0, 0x72A9}, //6050 #CJK UNIFIED IDEOGRAPH + {0xA0E1, 0x72AA}, //6051 #CJK UNIFIED IDEOGRAPH + {0xA0E2, 0x72AB}, //6052 #CJK UNIFIED IDEOGRAPH + {0xA0E3, 0x72AE}, //6053 #CJK UNIFIED IDEOGRAPH + {0xA0E4, 0x72B1}, //6054 #CJK UNIFIED IDEOGRAPH + {0xA0E5, 0x72B2}, //6055 #CJK UNIFIED IDEOGRAPH + {0xA0E6, 0x72B3}, //6056 #CJK UNIFIED IDEOGRAPH + {0xA0E7, 0x72B5}, //6057 #CJK UNIFIED IDEOGRAPH + {0xA0E8, 0x72BA}, //6058 #CJK UNIFIED IDEOGRAPH + {0xA0E9, 0x72BB}, //6059 #CJK UNIFIED IDEOGRAPH + {0xA0EA, 0x72BC}, //6060 #CJK UNIFIED IDEOGRAPH + {0xA0EB, 0x72BD}, //6061 #CJK UNIFIED IDEOGRAPH + {0xA0EC, 0x72BE}, //6062 #CJK UNIFIED IDEOGRAPH + {0xA0ED, 0x72BF}, //6063 #CJK UNIFIED IDEOGRAPH + {0xA0EE, 0x72C0}, //6064 #CJK UNIFIED IDEOGRAPH + {0xA0EF, 0x72C5}, //6065 #CJK UNIFIED IDEOGRAPH + {0xA0F0, 0x72C6}, //6066 #CJK UNIFIED IDEOGRAPH + {0xA0F1, 0x72C7}, //6067 #CJK UNIFIED IDEOGRAPH + {0xA0F2, 0x72C9}, //6068 #CJK UNIFIED IDEOGRAPH + {0xA0F3, 0x72CA}, //6069 #CJK UNIFIED IDEOGRAPH + {0xA0F4, 0x72CB}, //6070 #CJK UNIFIED IDEOGRAPH + {0xA0F5, 0x72CC}, //6071 #CJK UNIFIED IDEOGRAPH + {0xA0F6, 0x72CF}, //6072 #CJK UNIFIED IDEOGRAPH + {0xA0F7, 0x72D1}, //6073 #CJK UNIFIED IDEOGRAPH + {0xA0F8, 0x72D3}, //6074 #CJK UNIFIED IDEOGRAPH + {0xA0F9, 0x72D4}, //6075 #CJK UNIFIED IDEOGRAPH + {0xA0FA, 0x72D5}, //6076 #CJK UNIFIED IDEOGRAPH + {0xA0FB, 0x72D6}, //6077 #CJK UNIFIED IDEOGRAPH + {0xA0FC, 0x72D8}, //6078 #CJK UNIFIED IDEOGRAPH + {0xA0FD, 0x72DA}, //6079 #CJK UNIFIED IDEOGRAPH + {0xA0FE, 0x72DB}, //6080 #CJK UNIFIED IDEOGRAPH + {0xA1A1, 0x3000}, //6081 #IDEOGRAPHIC SPACE + {0xA1A2, 0x3001}, //6082 #IDEOGRAPHIC COMMA + {0xA1A3, 0x3002}, //6083 #IDEOGRAPHIC FULL STOP + {0xA1A4, 0x00B7}, //6084 #MIDDLE DOT + {0xA1A5, 0x02C9}, //6085 #MODIFIER LETTER MACRON + {0xA1A6, 0x02C7}, //6086 #CARON + {0xA1A7, 0x00A8}, //6087 #DIAERESIS + {0xA1A8, 0x3003}, //6088 #DITTO MARK + {0xA1A9, 0x3005}, //6089 #IDEOGRAPHIC ITERATION MARK + {0xA1AA, 0x2014}, //6090 #EM DASH + {0xA1AB, 0xFF5E}, //6091 #FULLWIDTH TILDE + {0xA1AC, 0x2016}, //6092 #DOUBLE VERTICAL LINE + {0xA1AD, 0x2026}, //6093 #HORIZONTAL ELLIPSIS + {0xA1AE, 0x2018}, //6094 #LEFT SINGLE QUOTATION MARK + {0xA1AF, 0x2019}, //6095 #RIGHT SINGLE QUOTATION MARK + {0xA1B0, 0x201C}, //6096 #LEFT DOUBLE QUOTATION MARK + {0xA1B1, 0x201D}, //6097 #RIGHT DOUBLE QUOTATION MARK + {0xA1B2, 0x3014}, //6098 #LEFT TORTOISE SHELL BRACKET + {0xA1B3, 0x3015}, //6099 #RIGHT TORTOISE SHELL BRACKET + {0xA1B4, 0x3008}, //6100 #LEFT ANGLE BRACKET + {0xA1B5, 0x3009}, //6101 #RIGHT ANGLE BRACKET + {0xA1B6, 0x300A}, //6102 #LEFT DOUBLE ANGLE BRACKET + {0xA1B7, 0x300B}, //6103 #RIGHT DOUBLE ANGLE BRACKET + {0xA1B8, 0x300C}, //6104 #LEFT CORNER BRACKET + {0xA1B9, 0x300D}, //6105 #RIGHT CORNER BRACKET + {0xA1BA, 0x300E}, //6106 #LEFT WHITE CORNER BRACKET + {0xA1BB, 0x300F}, //6107 #RIGHT WHITE CORNER BRACKET + {0xA1BC, 0x3016}, //6108 #LEFT WHITE LENTICULAR BRACKET + {0xA1BD, 0x3017}, //6109 #RIGHT WHITE LENTICULAR BRACKET + {0xA1BE, 0x3010}, //6110 #LEFT BLACK LENTICULAR BRACKET + {0xA1BF, 0x3011}, //6111 #RIGHT BLACK LENTICULAR BRACKET + {0xA1C0, 0x00B1}, //6112 #PLUS-MINUS SIGN + {0xA1C1, 0x00D7}, //6113 #MULTIPLICATION SIGN + {0xA1C2, 0x00F7}, //6114 #DIVISION SIGN + {0xA1C3, 0x2236}, //6115 #RATIO + {0xA1C4, 0x2227}, //6116 #LOGICAL AND + {0xA1C5, 0x2228}, //6117 #LOGICAL OR + {0xA1C6, 0x2211}, //6118 #N-ARY SUMMATION + {0xA1C7, 0x220F}, //6119 #N-ARY PRODUCT + {0xA1C8, 0x222A}, //6120 #UNION + {0xA1C9, 0x2229}, //6121 #INTERSECTION + {0xA1CA, 0x2208}, //6122 #ELEMENT OF + {0xA1CB, 0x2237}, //6123 #PROPORTION + {0xA1CC, 0x221A}, //6124 #SQUARE ROOT + {0xA1CD, 0x22A5}, //6125 #UP TACK + {0xA1CE, 0x2225}, //6126 #PARALLEL TO + {0xA1CF, 0x2220}, //6127 #ANGLE + {0xA1D0, 0x2312}, //6128 #ARC + {0xA1D1, 0x2299}, //6129 #CIRCLED DOT OPERATOR + {0xA1D2, 0x222B}, //6130 #INTEGRAL + {0xA1D3, 0x222E}, //6131 #CONTOUR INTEGRAL + {0xA1D4, 0x2261}, //6132 #IDENTICAL TO + {0xA1D5, 0x224C}, //6133 #ALL EQUAL TO + {0xA1D6, 0x2248}, //6134 #ALMOST EQUAL TO + {0xA1D7, 0x223D}, //6135 #REVERSED TILDE + {0xA1D8, 0x221D}, //6136 #PROPORTIONAL TO + {0xA1D9, 0x2260}, //6137 #NOT EQUAL TO + {0xA1DA, 0x226E}, //6138 #NOT LESS-THAN + {0xA1DB, 0x226F}, //6139 #NOT GREATER-THAN + {0xA1DC, 0x2264}, //6140 #LESS-THAN OR EQUAL TO + {0xA1DD, 0x2265}, //6141 #GREATER-THAN OR EQUAL TO + {0xA1DE, 0x221E}, //6142 #INFINITY + {0xA1DF, 0x2235}, //6143 #BECAUSE + {0xA1E0, 0x2234}, //6144 #THEREFORE + {0xA1E1, 0x2642}, //6145 #MALE SIGN + {0xA1E2, 0x2640}, //6146 #FEMALE SIGN + {0xA1E3, 0x00B0}, //6147 #DEGREE SIGN + {0xA1E4, 0x2032}, //6148 #PRIME + {0xA1E5, 0x2033}, //6149 #DOUBLE PRIME + {0xA1E6, 0x2103}, //6150 #DEGREE CELSIUS + {0xA1E7, 0xFF04}, //6151 #FULLWIDTH DOLLAR SIGN + {0xA1E8, 0x00A4}, //6152 #CURRENCY SIGN + {0xA1E9, 0xFFE0}, //6153 #FULLWIDTH CENT SIGN + {0xA1EA, 0xFFE1}, //6154 #FULLWIDTH POUND SIGN + {0xA1EB, 0x2030}, //6155 #PER MILLE SIGN + {0xA1EC, 0x00A7}, //6156 #SECTION SIGN + {0xA1ED, 0x2116}, //6157 #NUMERO SIGN + {0xA1EE, 0x2606}, //6158 #WHITE STAR + {0xA1EF, 0x2605}, //6159 #BLACK STAR + {0xA1F0, 0x25CB}, //6160 #WHITE CIRCLE + {0xA1F1, 0x25CF}, //6161 #BLACK CIRCLE + {0xA1F2, 0x25CE}, //6162 #BULLSEYE + {0xA1F3, 0x25C7}, //6163 #WHITE DIAMOND + {0xA1F4, 0x25C6}, //6164 #BLACK DIAMOND + {0xA1F5, 0x25A1}, //6165 #WHITE SQUARE + {0xA1F6, 0x25A0}, //6166 #BLACK SQUARE + {0xA1F7, 0x25B3}, //6167 #WHITE UP-POINTING TRIANGLE + {0xA1F8, 0x25B2}, //6168 #BLACK UP-POINTING TRIANGLE + {0xA1F9, 0x203B}, //6169 #REFERENCE MARK + {0xA1FA, 0x2192}, //6170 #RIGHTWARDS ARROW + {0xA1FB, 0x2190}, //6171 #LEFTWARDS ARROW + {0xA1FC, 0x2191}, //6172 #UPWARDS ARROW + {0xA1FD, 0x2193}, //6173 #DOWNWARDS ARROW + {0xA1FE, 0x3013}, //6174 #GETA MARK + {0xA2A1, 0x2170}, //6175 #SMALL ROMAN NUMERAL ONE + {0xA2A2, 0x2171}, //6176 #SMALL ROMAN NUMERAL TWO + {0xA2A3, 0x2172}, //6177 #SMALL ROMAN NUMERAL THREE + {0xA2A4, 0x2173}, //6178 #SMALL ROMAN NUMERAL FOUR + {0xA2A5, 0x2174}, //6179 #SMALL ROMAN NUMERAL FIVE + {0xA2A6, 0x2175}, //6180 #SMALL ROMAN NUMERAL SIX + {0xA2A7, 0x2176}, //6181 #SMALL ROMAN NUMERAL SEVEN + {0xA2A8, 0x2177}, //6182 #SMALL ROMAN NUMERAL EIGHT + {0xA2A9, 0x2178}, //6183 #SMALL ROMAN NUMERAL NINE + {0xA2AA, 0x2179}, //6184 #SMALL ROMAN NUMERAL TEN + {0xA2B1, 0x2488}, //6185 #DIGIT ONE FULL STOP + {0xA2B2, 0x2489}, //6186 #DIGIT TWO FULL STOP + {0xA2B3, 0x248A}, //6187 #DIGIT THREE FULL STOP + {0xA2B4, 0x248B}, //6188 #DIGIT FOUR FULL STOP + {0xA2B5, 0x248C}, //6189 #DIGIT FIVE FULL STOP + {0xA2B6, 0x248D}, //6190 #DIGIT SIX FULL STOP + {0xA2B7, 0x248E}, //6191 #DIGIT SEVEN FULL STOP + {0xA2B8, 0x248F}, //6192 #DIGIT EIGHT FULL STOP + {0xA2B9, 0x2490}, //6193 #DIGIT NINE FULL STOP + {0xA2BA, 0x2491}, //6194 #NUMBER TEN FULL STOP + {0xA2BB, 0x2492}, //6195 #NUMBER ELEVEN FULL STOP + {0xA2BC, 0x2493}, //6196 #NUMBER TWELVE FULL STOP + {0xA2BD, 0x2494}, //6197 #NUMBER THIRTEEN FULL STOP + {0xA2BE, 0x2495}, //6198 #NUMBER FOURTEEN FULL STOP + {0xA2BF, 0x2496}, //6199 #NUMBER FIFTEEN FULL STOP + {0xA2C0, 0x2497}, //6200 #NUMBER SIXTEEN FULL STOP + {0xA2C1, 0x2498}, //6201 #NUMBER SEVENTEEN FULL STOP + {0xA2C2, 0x2499}, //6202 #NUMBER EIGHTEEN FULL STOP + {0xA2C3, 0x249A}, //6203 #NUMBER NINETEEN FULL STOP + {0xA2C4, 0x249B}, //6204 #NUMBER TWENTY FULL STOP + {0xA2C5, 0x2474}, //6205 #PARENTHESIZED DIGIT ONE + {0xA2C6, 0x2475}, //6206 #PARENTHESIZED DIGIT TWO + {0xA2C7, 0x2476}, //6207 #PARENTHESIZED DIGIT THREE + {0xA2C8, 0x2477}, //6208 #PARENTHESIZED DIGIT FOUR + {0xA2C9, 0x2478}, //6209 #PARENTHESIZED DIGIT FIVE + {0xA2CA, 0x2479}, //6210 #PARENTHESIZED DIGIT SIX + {0xA2CB, 0x247A}, //6211 #PARENTHESIZED DIGIT SEVEN + {0xA2CC, 0x247B}, //6212 #PARENTHESIZED DIGIT EIGHT + {0xA2CD, 0x247C}, //6213 #PARENTHESIZED DIGIT NINE + {0xA2CE, 0x247D}, //6214 #PARENTHESIZED NUMBER TEN + {0xA2CF, 0x247E}, //6215 #PARENTHESIZED NUMBER ELEVEN + {0xA2D0, 0x247F}, //6216 #PARENTHESIZED NUMBER TWELVE + {0xA2D1, 0x2480}, //6217 #PARENTHESIZED NUMBER THIRTEEN + {0xA2D2, 0x2481}, //6218 #PARENTHESIZED NUMBER FOURTEEN + {0xA2D3, 0x2482}, //6219 #PARENTHESIZED NUMBER FIFTEEN + {0xA2D4, 0x2483}, //6220 #PARENTHESIZED NUMBER SIXTEEN + {0xA2D5, 0x2484}, //6221 #PARENTHESIZED NUMBER SEVENTEEN + {0xA2D6, 0x2485}, //6222 #PARENTHESIZED NUMBER EIGHTEEN + {0xA2D7, 0x2486}, //6223 #PARENTHESIZED NUMBER NINETEEN + {0xA2D8, 0x2487}, //6224 #PARENTHESIZED NUMBER TWENTY + {0xA2D9, 0x2460}, //6225 #CIRCLED DIGIT ONE + {0xA2DA, 0x2461}, //6226 #CIRCLED DIGIT TWO + {0xA2DB, 0x2462}, //6227 #CIRCLED DIGIT THREE + {0xA2DC, 0x2463}, //6228 #CIRCLED DIGIT FOUR + {0xA2DD, 0x2464}, //6229 #CIRCLED DIGIT FIVE + {0xA2DE, 0x2465}, //6230 #CIRCLED DIGIT SIX + {0xA2DF, 0x2466}, //6231 #CIRCLED DIGIT SEVEN + {0xA2E0, 0x2467}, //6232 #CIRCLED DIGIT EIGHT + {0xA2E1, 0x2468}, //6233 #CIRCLED DIGIT NINE + {0xA2E2, 0x2469}, //6234 #CIRCLED NUMBER TEN + {0xA2E5, 0x3220}, //6235 #PARENTHESIZED IDEOGRAPH ONE + {0xA2E6, 0x3221}, //6236 #PARENTHESIZED IDEOGRAPH TWO + {0xA2E7, 0x3222}, //6237 #PARENTHESIZED IDEOGRAPH THREE + {0xA2E8, 0x3223}, //6238 #PARENTHESIZED IDEOGRAPH FOUR + {0xA2E9, 0x3224}, //6239 #PARENTHESIZED IDEOGRAPH FIVE + {0xA2EA, 0x3225}, //6240 #PARENTHESIZED IDEOGRAPH SIX + {0xA2EB, 0x3226}, //6241 #PARENTHESIZED IDEOGRAPH SEVEN + {0xA2EC, 0x3227}, //6242 #PARENTHESIZED IDEOGRAPH EIGHT + {0xA2ED, 0x3228}, //6243 #PARENTHESIZED IDEOGRAPH NINE + {0xA2EE, 0x3229}, //6244 #PARENTHESIZED IDEOGRAPH TEN + {0xA2F1, 0x2160}, //6245 #ROMAN NUMERAL ONE + {0xA2F2, 0x2161}, //6246 #ROMAN NUMERAL TWO + {0xA2F3, 0x2162}, //6247 #ROMAN NUMERAL THREE + {0xA2F4, 0x2163}, //6248 #ROMAN NUMERAL FOUR + {0xA2F5, 0x2164}, //6249 #ROMAN NUMERAL FIVE + {0xA2F6, 0x2165}, //6250 #ROMAN NUMERAL SIX + {0xA2F7, 0x2166}, //6251 #ROMAN NUMERAL SEVEN + {0xA2F8, 0x2167}, //6252 #ROMAN NUMERAL EIGHT + {0xA2F9, 0x2168}, //6253 #ROMAN NUMERAL NINE + {0xA2FA, 0x2169}, //6254 #ROMAN NUMERAL TEN + {0xA2FB, 0x216A}, //6255 #ROMAN NUMERAL ELEVEN + {0xA2FC, 0x216B}, //6256 #ROMAN NUMERAL TWELVE + {0xA3A1, 0xFF01}, //6257 #FULLWIDTH EXCLAMATION MARK + {0xA3A2, 0xFF02}, //6258 #FULLWIDTH QUOTATION MARK + {0xA3A3, 0xFF03}, //6259 #FULLWIDTH NUMBER SIGN + {0xA3A4, 0xFFE5}, //6260 #FULLWIDTH YEN SIGN + {0xA3A5, 0xFF05}, //6261 #FULLWIDTH PERCENT SIGN + {0xA3A6, 0xFF06}, //6262 #FULLWIDTH AMPERSAND + {0xA3A7, 0xFF07}, //6263 #FULLWIDTH APOSTROPHE + {0xA3A8, 0xFF08}, //6264 #FULLWIDTH LEFT PARENTHESIS + {0xA3A9, 0xFF09}, //6265 #FULLWIDTH RIGHT PARENTHESIS + {0xA3AA, 0xFF0A}, //6266 #FULLWIDTH ASTERISK + {0xA3AB, 0xFF0B}, //6267 #FULLWIDTH PLUS SIGN + {0xA3AC, 0xFF0C}, //6268 #FULLWIDTH COMMA + {0xA3AD, 0xFF0D}, //6269 #FULLWIDTH HYPHEN-MINUS + {0xA3AE, 0xFF0E}, //6270 #FULLWIDTH FULL STOP + {0xA3AF, 0xFF0F}, //6271 #FULLWIDTH SOLIDUS + {0xA3B0, 0xFF10}, //6272 #FULLWIDTH DIGIT ZERO + {0xA3B1, 0xFF11}, //6273 #FULLWIDTH DIGIT ONE + {0xA3B2, 0xFF12}, //6274 #FULLWIDTH DIGIT TWO + {0xA3B3, 0xFF13}, //6275 #FULLWIDTH DIGIT THREE + {0xA3B4, 0xFF14}, //6276 #FULLWIDTH DIGIT FOUR + {0xA3B5, 0xFF15}, //6277 #FULLWIDTH DIGIT FIVE + {0xA3B6, 0xFF16}, //6278 #FULLWIDTH DIGIT SIX + {0xA3B7, 0xFF17}, //6279 #FULLWIDTH DIGIT SEVEN + {0xA3B8, 0xFF18}, //6280 #FULLWIDTH DIGIT EIGHT + {0xA3B9, 0xFF19}, //6281 #FULLWIDTH DIGIT NINE + {0xA3BA, 0xFF1A}, //6282 #FULLWIDTH COLON + {0xA3BB, 0xFF1B}, //6283 #FULLWIDTH SEMICOLON + {0xA3BC, 0xFF1C}, //6284 #FULLWIDTH LESS-THAN SIGN + {0xA3BD, 0xFF1D}, //6285 #FULLWIDTH EQUALS SIGN + {0xA3BE, 0xFF1E}, //6286 #FULLWIDTH GREATER-THAN SIGN + {0xA3BF, 0xFF1F}, //6287 #FULLWIDTH QUESTION MARK + {0xA3C0, 0xFF20}, //6288 #FULLWIDTH COMMERCIAL AT + {0xA3C1, 0xFF21}, //6289 #FULLWIDTH LATIN CAPITAL LETTER A + {0xA3C2, 0xFF22}, //6290 #FULLWIDTH LATIN CAPITAL LETTER B + {0xA3C3, 0xFF23}, //6291 #FULLWIDTH LATIN CAPITAL LETTER C + {0xA3C4, 0xFF24}, //6292 #FULLWIDTH LATIN CAPITAL LETTER D + {0xA3C5, 0xFF25}, //6293 #FULLWIDTH LATIN CAPITAL LETTER E + {0xA3C6, 0xFF26}, //6294 #FULLWIDTH LATIN CAPITAL LETTER F + {0xA3C7, 0xFF27}, //6295 #FULLWIDTH LATIN CAPITAL LETTER G + {0xA3C8, 0xFF28}, //6296 #FULLWIDTH LATIN CAPITAL LETTER H + {0xA3C9, 0xFF29}, //6297 #FULLWIDTH LATIN CAPITAL LETTER I + {0xA3CA, 0xFF2A}, //6298 #FULLWIDTH LATIN CAPITAL LETTER J + {0xA3CB, 0xFF2B}, //6299 #FULLWIDTH LATIN CAPITAL LETTER K + {0xA3CC, 0xFF2C}, //6300 #FULLWIDTH LATIN CAPITAL LETTER L + {0xA3CD, 0xFF2D}, //6301 #FULLWIDTH LATIN CAPITAL LETTER M + {0xA3CE, 0xFF2E}, //6302 #FULLWIDTH LATIN CAPITAL LETTER N + {0xA3CF, 0xFF2F}, //6303 #FULLWIDTH LATIN CAPITAL LETTER O + {0xA3D0, 0xFF30}, //6304 #FULLWIDTH LATIN CAPITAL LETTER P + {0xA3D1, 0xFF31}, //6305 #FULLWIDTH LATIN CAPITAL LETTER Q + {0xA3D2, 0xFF32}, //6306 #FULLWIDTH LATIN CAPITAL LETTER R + {0xA3D3, 0xFF33}, //6307 #FULLWIDTH LATIN CAPITAL LETTER S + {0xA3D4, 0xFF34}, //6308 #FULLWIDTH LATIN CAPITAL LETTER T + {0xA3D5, 0xFF35}, //6309 #FULLWIDTH LATIN CAPITAL LETTER U + {0xA3D6, 0xFF36}, //6310 #FULLWIDTH LATIN CAPITAL LETTER V + {0xA3D7, 0xFF37}, //6311 #FULLWIDTH LATIN CAPITAL LETTER W + {0xA3D8, 0xFF38}, //6312 #FULLWIDTH LATIN CAPITAL LETTER X + {0xA3D9, 0xFF39}, //6313 #FULLWIDTH LATIN CAPITAL LETTER Y + {0xA3DA, 0xFF3A}, //6314 #FULLWIDTH LATIN CAPITAL LETTER Z + {0xA3DB, 0xFF3B}, //6315 #FULLWIDTH LEFT SQUARE BRACKET + {0xA3DC, 0xFF3C}, //6316 #FULLWIDTH REVERSE SOLIDUS + {0xA3DD, 0xFF3D}, //6317 #FULLWIDTH RIGHT SQUARE BRACKET + {0xA3DE, 0xFF3E}, //6318 #FULLWIDTH CIRCUMFLEX ACCENT + {0xA3DF, 0xFF3F}, //6319 #FULLWIDTH LOW LINE + {0xA3E0, 0xFF40}, //6320 #FULLWIDTH GRAVE ACCENT + {0xA3E1, 0xFF41}, //6321 #FULLWIDTH LATIN SMALL LETTER A + {0xA3E2, 0xFF42}, //6322 #FULLWIDTH LATIN SMALL LETTER B + {0xA3E3, 0xFF43}, //6323 #FULLWIDTH LATIN SMALL LETTER C + {0xA3E4, 0xFF44}, //6324 #FULLWIDTH LATIN SMALL LETTER D + {0xA3E5, 0xFF45}, //6325 #FULLWIDTH LATIN SMALL LETTER E + {0xA3E6, 0xFF46}, //6326 #FULLWIDTH LATIN SMALL LETTER F + {0xA3E7, 0xFF47}, //6327 #FULLWIDTH LATIN SMALL LETTER G + {0xA3E8, 0xFF48}, //6328 #FULLWIDTH LATIN SMALL LETTER H + {0xA3E9, 0xFF49}, //6329 #FULLWIDTH LATIN SMALL LETTER I + {0xA3EA, 0xFF4A}, //6330 #FULLWIDTH LATIN SMALL LETTER J + {0xA3EB, 0xFF4B}, //6331 #FULLWIDTH LATIN SMALL LETTER K + {0xA3EC, 0xFF4C}, //6332 #FULLWIDTH LATIN SMALL LETTER L + {0xA3ED, 0xFF4D}, //6333 #FULLWIDTH LATIN SMALL LETTER M + {0xA3EE, 0xFF4E}, //6334 #FULLWIDTH LATIN SMALL LETTER N + {0xA3EF, 0xFF4F}, //6335 #FULLWIDTH LATIN SMALL LETTER O + {0xA3F0, 0xFF50}, //6336 #FULLWIDTH LATIN SMALL LETTER P + {0xA3F1, 0xFF51}, //6337 #FULLWIDTH LATIN SMALL LETTER Q + {0xA3F2, 0xFF52}, //6338 #FULLWIDTH LATIN SMALL LETTER R + {0xA3F3, 0xFF53}, //6339 #FULLWIDTH LATIN SMALL LETTER S + {0xA3F4, 0xFF54}, //6340 #FULLWIDTH LATIN SMALL LETTER T + {0xA3F5, 0xFF55}, //6341 #FULLWIDTH LATIN SMALL LETTER U + {0xA3F6, 0xFF56}, //6342 #FULLWIDTH LATIN SMALL LETTER V + {0xA3F7, 0xFF57}, //6343 #FULLWIDTH LATIN SMALL LETTER W + {0xA3F8, 0xFF58}, //6344 #FULLWIDTH LATIN SMALL LETTER X + {0xA3F9, 0xFF59}, //6345 #FULLWIDTH LATIN SMALL LETTER Y + {0xA3FA, 0xFF5A}, //6346 #FULLWIDTH LATIN SMALL LETTER Z + {0xA3FB, 0xFF5B}, //6347 #FULLWIDTH LEFT CURLY BRACKET + {0xA3FC, 0xFF5C}, //6348 #FULLWIDTH VERTICAL LINE + {0xA3FD, 0xFF5D}, //6349 #FULLWIDTH RIGHT CURLY BRACKET + {0xA3FE, 0xFFE3}, //6350 #FULLWIDTH MACRON + {0xA4A1, 0x3041}, //6351 #HIRAGANA LETTER SMALL A + {0xA4A2, 0x3042}, //6352 #HIRAGANA LETTER A + {0xA4A3, 0x3043}, //6353 #HIRAGANA LETTER SMALL I + {0xA4A4, 0x3044}, //6354 #HIRAGANA LETTER I + {0xA4A5, 0x3045}, //6355 #HIRAGANA LETTER SMALL U + {0xA4A6, 0x3046}, //6356 #HIRAGANA LETTER U + {0xA4A7, 0x3047}, //6357 #HIRAGANA LETTER SMALL E + {0xA4A8, 0x3048}, //6358 #HIRAGANA LETTER E + {0xA4A9, 0x3049}, //6359 #HIRAGANA LETTER SMALL O + {0xA4AA, 0x304A}, //6360 #HIRAGANA LETTER O + {0xA4AB, 0x304B}, //6361 #HIRAGANA LETTER KA + {0xA4AC, 0x304C}, //6362 #HIRAGANA LETTER GA + {0xA4AD, 0x304D}, //6363 #HIRAGANA LETTER KI + {0xA4AE, 0x304E}, //6364 #HIRAGANA LETTER GI + {0xA4AF, 0x304F}, //6365 #HIRAGANA LETTER KU + {0xA4B0, 0x3050}, //6366 #HIRAGANA LETTER GU + {0xA4B1, 0x3051}, //6367 #HIRAGANA LETTER KE + {0xA4B2, 0x3052}, //6368 #HIRAGANA LETTER GE + {0xA4B3, 0x3053}, //6369 #HIRAGANA LETTER KO + {0xA4B4, 0x3054}, //6370 #HIRAGANA LETTER GO + {0xA4B5, 0x3055}, //6371 #HIRAGANA LETTER SA + {0xA4B6, 0x3056}, //6372 #HIRAGANA LETTER ZA + {0xA4B7, 0x3057}, //6373 #HIRAGANA LETTER SI + {0xA4B8, 0x3058}, //6374 #HIRAGANA LETTER ZI + {0xA4B9, 0x3059}, //6375 #HIRAGANA LETTER SU + {0xA4BA, 0x305A}, //6376 #HIRAGANA LETTER ZU + {0xA4BB, 0x305B}, //6377 #HIRAGANA LETTER SE + {0xA4BC, 0x305C}, //6378 #HIRAGANA LETTER ZE + {0xA4BD, 0x305D}, //6379 #HIRAGANA LETTER SO + {0xA4BE, 0x305E}, //6380 #HIRAGANA LETTER ZO + {0xA4BF, 0x305F}, //6381 #HIRAGANA LETTER TA + {0xA4C0, 0x3060}, //6382 #HIRAGANA LETTER DA + {0xA4C1, 0x3061}, //6383 #HIRAGANA LETTER TI + {0xA4C2, 0x3062}, //6384 #HIRAGANA LETTER DI + {0xA4C3, 0x3063}, //6385 #HIRAGANA LETTER SMALL TU + {0xA4C4, 0x3064}, //6386 #HIRAGANA LETTER TU + {0xA4C5, 0x3065}, //6387 #HIRAGANA LETTER DU + {0xA4C6, 0x3066}, //6388 #HIRAGANA LETTER TE + {0xA4C7, 0x3067}, //6389 #HIRAGANA LETTER DE + {0xA4C8, 0x3068}, //6390 #HIRAGANA LETTER TO + {0xA4C9, 0x3069}, //6391 #HIRAGANA LETTER DO + {0xA4CA, 0x306A}, //6392 #HIRAGANA LETTER NA + {0xA4CB, 0x306B}, //6393 #HIRAGANA LETTER NI + {0xA4CC, 0x306C}, //6394 #HIRAGANA LETTER NU + {0xA4CD, 0x306D}, //6395 #HIRAGANA LETTER NE + {0xA4CE, 0x306E}, //6396 #HIRAGANA LETTER NO + {0xA4CF, 0x306F}, //6397 #HIRAGANA LETTER HA + {0xA4D0, 0x3070}, //6398 #HIRAGANA LETTER BA + {0xA4D1, 0x3071}, //6399 #HIRAGANA LETTER PA + {0xA4D2, 0x3072}, //6400 #HIRAGANA LETTER HI + {0xA4D3, 0x3073}, //6401 #HIRAGANA LETTER BI + {0xA4D4, 0x3074}, //6402 #HIRAGANA LETTER PI + {0xA4D5, 0x3075}, //6403 #HIRAGANA LETTER HU + {0xA4D6, 0x3076}, //6404 #HIRAGANA LETTER BU + {0xA4D7, 0x3077}, //6405 #HIRAGANA LETTER PU + {0xA4D8, 0x3078}, //6406 #HIRAGANA LETTER HE + {0xA4D9, 0x3079}, //6407 #HIRAGANA LETTER BE + {0xA4DA, 0x307A}, //6408 #HIRAGANA LETTER PE + {0xA4DB, 0x307B}, //6409 #HIRAGANA LETTER HO + {0xA4DC, 0x307C}, //6410 #HIRAGANA LETTER BO + {0xA4DD, 0x307D}, //6411 #HIRAGANA LETTER PO + {0xA4DE, 0x307E}, //6412 #HIRAGANA LETTER MA + {0xA4DF, 0x307F}, //6413 #HIRAGANA LETTER MI + {0xA4E0, 0x3080}, //6414 #HIRAGANA LETTER MU + {0xA4E1, 0x3081}, //6415 #HIRAGANA LETTER ME + {0xA4E2, 0x3082}, //6416 #HIRAGANA LETTER MO + {0xA4E3, 0x3083}, //6417 #HIRAGANA LETTER SMALL YA + {0xA4E4, 0x3084}, //6418 #HIRAGANA LETTER YA + {0xA4E5, 0x3085}, //6419 #HIRAGANA LETTER SMALL YU + {0xA4E6, 0x3086}, //6420 #HIRAGANA LETTER YU + {0xA4E7, 0x3087}, //6421 #HIRAGANA LETTER SMALL YO + {0xA4E8, 0x3088}, //6422 #HIRAGANA LETTER YO + {0xA4E9, 0x3089}, //6423 #HIRAGANA LETTER RA + {0xA4EA, 0x308A}, //6424 #HIRAGANA LETTER RI + {0xA4EB, 0x308B}, //6425 #HIRAGANA LETTER RU + {0xA4EC, 0x308C}, //6426 #HIRAGANA LETTER RE + {0xA4ED, 0x308D}, //6427 #HIRAGANA LETTER RO + {0xA4EE, 0x308E}, //6428 #HIRAGANA LETTER SMALL WA + {0xA4EF, 0x308F}, //6429 #HIRAGANA LETTER WA + {0xA4F0, 0x3090}, //6430 #HIRAGANA LETTER WI + {0xA4F1, 0x3091}, //6431 #HIRAGANA LETTER WE + {0xA4F2, 0x3092}, //6432 #HIRAGANA LETTER WO + {0xA4F3, 0x3093}, //6433 #HIRAGANA LETTER N + {0xA5A1, 0x30A1}, //6434 #KATAKANA LETTER SMALL A + {0xA5A2, 0x30A2}, //6435 #KATAKANA LETTER A + {0xA5A3, 0x30A3}, //6436 #KATAKANA LETTER SMALL I + {0xA5A4, 0x30A4}, //6437 #KATAKANA LETTER I + {0xA5A5, 0x30A5}, //6438 #KATAKANA LETTER SMALL U + {0xA5A6, 0x30A6}, //6439 #KATAKANA LETTER U + {0xA5A7, 0x30A7}, //6440 #KATAKANA LETTER SMALL E + {0xA5A8, 0x30A8}, //6441 #KATAKANA LETTER E + {0xA5A9, 0x30A9}, //6442 #KATAKANA LETTER SMALL O + {0xA5AA, 0x30AA}, //6443 #KATAKANA LETTER O + {0xA5AB, 0x30AB}, //6444 #KATAKANA LETTER KA + {0xA5AC, 0x30AC}, //6445 #KATAKANA LETTER GA + {0xA5AD, 0x30AD}, //6446 #KATAKANA LETTER KI + {0xA5AE, 0x30AE}, //6447 #KATAKANA LETTER GI + {0xA5AF, 0x30AF}, //6448 #KATAKANA LETTER KU + {0xA5B0, 0x30B0}, //6449 #KATAKANA LETTER GU + {0xA5B1, 0x30B1}, //6450 #KATAKANA LETTER KE + {0xA5B2, 0x30B2}, //6451 #KATAKANA LETTER GE + {0xA5B3, 0x30B3}, //6452 #KATAKANA LETTER KO + {0xA5B4, 0x30B4}, //6453 #KATAKANA LETTER GO + {0xA5B5, 0x30B5}, //6454 #KATAKANA LETTER SA + {0xA5B6, 0x30B6}, //6455 #KATAKANA LETTER ZA + {0xA5B7, 0x30B7}, //6456 #KATAKANA LETTER SI + {0xA5B8, 0x30B8}, //6457 #KATAKANA LETTER ZI + {0xA5B9, 0x30B9}, //6458 #KATAKANA LETTER SU + {0xA5BA, 0x30BA}, //6459 #KATAKANA LETTER ZU + {0xA5BB, 0x30BB}, //6460 #KATAKANA LETTER SE + {0xA5BC, 0x30BC}, //6461 #KATAKANA LETTER ZE + {0xA5BD, 0x30BD}, //6462 #KATAKANA LETTER SO + {0xA5BE, 0x30BE}, //6463 #KATAKANA LETTER ZO + {0xA5BF, 0x30BF}, //6464 #KATAKANA LETTER TA + {0xA5C0, 0x30C0}, //6465 #KATAKANA LETTER DA + {0xA5C1, 0x30C1}, //6466 #KATAKANA LETTER TI + {0xA5C2, 0x30C2}, //6467 #KATAKANA LETTER DI + {0xA5C3, 0x30C3}, //6468 #KATAKANA LETTER SMALL TU + {0xA5C4, 0x30C4}, //6469 #KATAKANA LETTER TU + {0xA5C5, 0x30C5}, //6470 #KATAKANA LETTER DU + {0xA5C6, 0x30C6}, //6471 #KATAKANA LETTER TE + {0xA5C7, 0x30C7}, //6472 #KATAKANA LETTER DE + {0xA5C8, 0x30C8}, //6473 #KATAKANA LETTER TO + {0xA5C9, 0x30C9}, //6474 #KATAKANA LETTER DO + {0xA5CA, 0x30CA}, //6475 #KATAKANA LETTER NA + {0xA5CB, 0x30CB}, //6476 #KATAKANA LETTER NI + {0xA5CC, 0x30CC}, //6477 #KATAKANA LETTER NU + {0xA5CD, 0x30CD}, //6478 #KATAKANA LETTER NE + {0xA5CE, 0x30CE}, //6479 #KATAKANA LETTER NO + {0xA5CF, 0x30CF}, //6480 #KATAKANA LETTER HA + {0xA5D0, 0x30D0}, //6481 #KATAKANA LETTER BA + {0xA5D1, 0x30D1}, //6482 #KATAKANA LETTER PA + {0xA5D2, 0x30D2}, //6483 #KATAKANA LETTER HI + {0xA5D3, 0x30D3}, //6484 #KATAKANA LETTER BI + {0xA5D4, 0x30D4}, //6485 #KATAKANA LETTER PI + {0xA5D5, 0x30D5}, //6486 #KATAKANA LETTER HU + {0xA5D6, 0x30D6}, //6487 #KATAKANA LETTER BU + {0xA5D7, 0x30D7}, //6488 #KATAKANA LETTER PU + {0xA5D8, 0x30D8}, //6489 #KATAKANA LETTER HE + {0xA5D9, 0x30D9}, //6490 #KATAKANA LETTER BE + {0xA5DA, 0x30DA}, //6491 #KATAKANA LETTER PE + {0xA5DB, 0x30DB}, //6492 #KATAKANA LETTER HO + {0xA5DC, 0x30DC}, //6493 #KATAKANA LETTER BO + {0xA5DD, 0x30DD}, //6494 #KATAKANA LETTER PO + {0xA5DE, 0x30DE}, //6495 #KATAKANA LETTER MA + {0xA5DF, 0x30DF}, //6496 #KATAKANA LETTER MI + {0xA5E0, 0x30E0}, //6497 #KATAKANA LETTER MU + {0xA5E1, 0x30E1}, //6498 #KATAKANA LETTER ME + {0xA5E2, 0x30E2}, //6499 #KATAKANA LETTER MO + {0xA5E3, 0x30E3}, //6500 #KATAKANA LETTER SMALL YA + {0xA5E4, 0x30E4}, //6501 #KATAKANA LETTER YA + {0xA5E5, 0x30E5}, //6502 #KATAKANA LETTER SMALL YU + {0xA5E6, 0x30E6}, //6503 #KATAKANA LETTER YU + {0xA5E7, 0x30E7}, //6504 #KATAKANA LETTER SMALL YO + {0xA5E8, 0x30E8}, //6505 #KATAKANA LETTER YO + {0xA5E9, 0x30E9}, //6506 #KATAKANA LETTER RA + {0xA5EA, 0x30EA}, //6507 #KATAKANA LETTER RI + {0xA5EB, 0x30EB}, //6508 #KATAKANA LETTER RU + {0xA5EC, 0x30EC}, //6509 #KATAKANA LETTER RE + {0xA5ED, 0x30ED}, //6510 #KATAKANA LETTER RO + {0xA5EE, 0x30EE}, //6511 #KATAKANA LETTER SMALL WA + {0xA5EF, 0x30EF}, //6512 #KATAKANA LETTER WA + {0xA5F0, 0x30F0}, //6513 #KATAKANA LETTER WI + {0xA5F1, 0x30F1}, //6514 #KATAKANA LETTER WE + {0xA5F2, 0x30F2}, //6515 #KATAKANA LETTER WO + {0xA5F3, 0x30F3}, //6516 #KATAKANA LETTER N + {0xA5F4, 0x30F4}, //6517 #KATAKANA LETTER VU + {0xA5F5, 0x30F5}, //6518 #KATAKANA LETTER SMALL KA + {0xA5F6, 0x30F6}, //6519 #KATAKANA LETTER SMALL KE + {0xA6A1, 0x0391}, //6520 #GREEK CAPITAL LETTER ALPHA + {0xA6A2, 0x0392}, //6521 #GREEK CAPITAL LETTER BETA + {0xA6A3, 0x0393}, //6522 #GREEK CAPITAL LETTER GAMMA + {0xA6A4, 0x0394}, //6523 #GREEK CAPITAL LETTER DELTA + {0xA6A5, 0x0395}, //6524 #GREEK CAPITAL LETTER EPSILON + {0xA6A6, 0x0396}, //6525 #GREEK CAPITAL LETTER ZETA + {0xA6A7, 0x0397}, //6526 #GREEK CAPITAL LETTER ETA + {0xA6A8, 0x0398}, //6527 #GREEK CAPITAL LETTER THETA + {0xA6A9, 0x0399}, //6528 #GREEK CAPITAL LETTER IOTA + {0xA6AA, 0x039A}, //6529 #GREEK CAPITAL LETTER KAPPA + {0xA6AB, 0x039B}, //6530 #GREEK CAPITAL LETTER LAMDA + {0xA6AC, 0x039C}, //6531 #GREEK CAPITAL LETTER MU + {0xA6AD, 0x039D}, //6532 #GREEK CAPITAL LETTER NU + {0xA6AE, 0x039E}, //6533 #GREEK CAPITAL LETTER XI + {0xA6AF, 0x039F}, //6534 #GREEK CAPITAL LETTER OMICRON + {0xA6B0, 0x03A0}, //6535 #GREEK CAPITAL LETTER PI + {0xA6B1, 0x03A1}, //6536 #GREEK CAPITAL LETTER RHO + {0xA6B2, 0x03A3}, //6537 #GREEK CAPITAL LETTER SIGMA + {0xA6B3, 0x03A4}, //6538 #GREEK CAPITAL LETTER TAU + {0xA6B4, 0x03A5}, //6539 #GREEK CAPITAL LETTER UPSILON + {0xA6B5, 0x03A6}, //6540 #GREEK CAPITAL LETTER PHI + {0xA6B6, 0x03A7}, //6541 #GREEK CAPITAL LETTER CHI + {0xA6B7, 0x03A8}, //6542 #GREEK CAPITAL LETTER PSI + {0xA6B8, 0x03A9}, //6543 #GREEK CAPITAL LETTER OMEGA + {0xA6C1, 0x03B1}, //6544 #GREEK SMALL LETTER ALPHA + {0xA6C2, 0x03B2}, //6545 #GREEK SMALL LETTER BETA + {0xA6C3, 0x03B3}, //6546 #GREEK SMALL LETTER GAMMA + {0xA6C4, 0x03B4}, //6547 #GREEK SMALL LETTER DELTA + {0xA6C5, 0x03B5}, //6548 #GREEK SMALL LETTER EPSILON + {0xA6C6, 0x03B6}, //6549 #GREEK SMALL LETTER ZETA + {0xA6C7, 0x03B7}, //6550 #GREEK SMALL LETTER ETA + {0xA6C8, 0x03B8}, //6551 #GREEK SMALL LETTER THETA + {0xA6C9, 0x03B9}, //6552 #GREEK SMALL LETTER IOTA + {0xA6CA, 0x03BA}, //6553 #GREEK SMALL LETTER KAPPA + {0xA6CB, 0x03BB}, //6554 #GREEK SMALL LETTER LAMDA + {0xA6CC, 0x03BC}, //6555 #GREEK SMALL LETTER MU + {0xA6CD, 0x03BD}, //6556 #GREEK SMALL LETTER NU + {0xA6CE, 0x03BE}, //6557 #GREEK SMALL LETTER XI + {0xA6CF, 0x03BF}, //6558 #GREEK SMALL LETTER OMICRON + {0xA6D0, 0x03C0}, //6559 #GREEK SMALL LETTER PI + {0xA6D1, 0x03C1}, //6560 #GREEK SMALL LETTER RHO + {0xA6D2, 0x03C3}, //6561 #GREEK SMALL LETTER SIGMA + {0xA6D3, 0x03C4}, //6562 #GREEK SMALL LETTER TAU + {0xA6D4, 0x03C5}, //6563 #GREEK SMALL LETTER UPSILON + {0xA6D5, 0x03C6}, //6564 #GREEK SMALL LETTER PHI + {0xA6D6, 0x03C7}, //6565 #GREEK SMALL LETTER CHI + {0xA6D7, 0x03C8}, //6566 #GREEK SMALL LETTER PSI + {0xA6D8, 0x03C9}, //6567 #GREEK SMALL LETTER OMEGA + {0xA6E0, 0xFE35}, //6568 #PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS + {0xA6E1, 0xFE36}, //6569 #PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS + {0xA6E2, 0xFE39}, //6570 #PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET + {0xA6E3, 0xFE3A}, //6571 #PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET + {0xA6E4, 0xFE3F}, //6572 #PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET + {0xA6E5, 0xFE40}, //6573 #PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET + {0xA6E6, 0xFE3D}, //6574 #PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET + {0xA6E7, 0xFE3E}, //6575 #PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET + {0xA6E8, 0xFE41}, //6576 #PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET + {0xA6E9, 0xFE42}, //6577 #PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET + {0xA6EA, 0xFE43}, //6578 #PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET + {0xA6EB, 0xFE44}, //6579 #PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET + {0xA6EE, 0xFE3B}, //6580 #PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET + {0xA6EF, 0xFE3C}, //6581 #PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET + {0xA6F0, 0xFE37}, //6582 #PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET + {0xA6F1, 0xFE38}, //6583 #PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET + {0xA6F2, 0xFE31}, //6584 #PRESENTATION FORM FOR VERTICAL EM DASH + {0xA6F4, 0xFE33}, //6585 #PRESENTATION FORM FOR VERTICAL LOW LINE + {0xA6F5, 0xFE34}, //6586 #PRESENTATION FORM FOR VERTICAL WAVY LOW LINE + {0xA7A1, 0x0410}, //6587 #CYRILLIC CAPITAL LETTER A + {0xA7A2, 0x0411}, //6588 #CYRILLIC CAPITAL LETTER BE + {0xA7A3, 0x0412}, //6589 #CYRILLIC CAPITAL LETTER VE + {0xA7A4, 0x0413}, //6590 #CYRILLIC CAPITAL LETTER GHE + {0xA7A5, 0x0414}, //6591 #CYRILLIC CAPITAL LETTER DE + {0xA7A6, 0x0415}, //6592 #CYRILLIC CAPITAL LETTER IE + {0xA7A7, 0x0401}, //6593 #CYRILLIC CAPITAL LETTER IO + {0xA7A8, 0x0416}, //6594 #CYRILLIC CAPITAL LETTER ZHE + {0xA7A9, 0x0417}, //6595 #CYRILLIC CAPITAL LETTER ZE + {0xA7AA, 0x0418}, //6596 #CYRILLIC CAPITAL LETTER I + {0xA7AB, 0x0419}, //6597 #CYRILLIC CAPITAL LETTER SHORT I + {0xA7AC, 0x041A}, //6598 #CYRILLIC CAPITAL LETTER KA + {0xA7AD, 0x041B}, //6599 #CYRILLIC CAPITAL LETTER EL + {0xA7AE, 0x041C}, //6600 #CYRILLIC CAPITAL LETTER EM + {0xA7AF, 0x041D}, //6601 #CYRILLIC CAPITAL LETTER EN + {0xA7B0, 0x041E}, //6602 #CYRILLIC CAPITAL LETTER O + {0xA7B1, 0x041F}, //6603 #CYRILLIC CAPITAL LETTER PE + {0xA7B2, 0x0420}, //6604 #CYRILLIC CAPITAL LETTER ER + {0xA7B3, 0x0421}, //6605 #CYRILLIC CAPITAL LETTER ES + {0xA7B4, 0x0422}, //6606 #CYRILLIC CAPITAL LETTER TE + {0xA7B5, 0x0423}, //6607 #CYRILLIC CAPITAL LETTER U + {0xA7B6, 0x0424}, //6608 #CYRILLIC CAPITAL LETTER EF + {0xA7B7, 0x0425}, //6609 #CYRILLIC CAPITAL LETTER HA + {0xA7B8, 0x0426}, //6610 #CYRILLIC CAPITAL LETTER TSE + {0xA7B9, 0x0427}, //6611 #CYRILLIC CAPITAL LETTER CHE + {0xA7BA, 0x0428}, //6612 #CYRILLIC CAPITAL LETTER SHA + {0xA7BB, 0x0429}, //6613 #CYRILLIC CAPITAL LETTER SHCHA + {0xA7BC, 0x042A}, //6614 #CYRILLIC CAPITAL LETTER HARD SIGN + {0xA7BD, 0x042B}, //6615 #CYRILLIC CAPITAL LETTER YERU + {0xA7BE, 0x042C}, //6616 #CYRILLIC CAPITAL LETTER SOFT SIGN + {0xA7BF, 0x042D}, //6617 #CYRILLIC CAPITAL LETTER E + {0xA7C0, 0x042E}, //6618 #CYRILLIC CAPITAL LETTER YU + {0xA7C1, 0x042F}, //6619 #CYRILLIC CAPITAL LETTER YA + {0xA7D1, 0x0430}, //6620 #CYRILLIC SMALL LETTER A + {0xA7D2, 0x0431}, //6621 #CYRILLIC SMALL LETTER BE + {0xA7D3, 0x0432}, //6622 #CYRILLIC SMALL LETTER VE + {0xA7D4, 0x0433}, //6623 #CYRILLIC SMALL LETTER GHE + {0xA7D5, 0x0434}, //6624 #CYRILLIC SMALL LETTER DE + {0xA7D6, 0x0435}, //6625 #CYRILLIC SMALL LETTER IE + {0xA7D7, 0x0451}, //6626 #CYRILLIC SMALL LETTER IO + {0xA7D8, 0x0436}, //6627 #CYRILLIC SMALL LETTER ZHE + {0xA7D9, 0x0437}, //6628 #CYRILLIC SMALL LETTER ZE + {0xA7DA, 0x0438}, //6629 #CYRILLIC SMALL LETTER I + {0xA7DB, 0x0439}, //6630 #CYRILLIC SMALL LETTER SHORT I + {0xA7DC, 0x043A}, //6631 #CYRILLIC SMALL LETTER KA + {0xA7DD, 0x043B}, //6632 #CYRILLIC SMALL LETTER EL + {0xA7DE, 0x043C}, //6633 #CYRILLIC SMALL LETTER EM + {0xA7DF, 0x043D}, //6634 #CYRILLIC SMALL LETTER EN + {0xA7E0, 0x043E}, //6635 #CYRILLIC SMALL LETTER O + {0xA7E1, 0x043F}, //6636 #CYRILLIC SMALL LETTER PE + {0xA7E2, 0x0440}, //6637 #CYRILLIC SMALL LETTER ER + {0xA7E3, 0x0441}, //6638 #CYRILLIC SMALL LETTER ES + {0xA7E4, 0x0442}, //6639 #CYRILLIC SMALL LETTER TE + {0xA7E5, 0x0443}, //6640 #CYRILLIC SMALL LETTER U + {0xA7E6, 0x0444}, //6641 #CYRILLIC SMALL LETTER EF + {0xA7E7, 0x0445}, //6642 #CYRILLIC SMALL LETTER HA + {0xA7E8, 0x0446}, //6643 #CYRILLIC SMALL LETTER TSE + {0xA7E9, 0x0447}, //6644 #CYRILLIC SMALL LETTER CHE + {0xA7EA, 0x0448}, //6645 #CYRILLIC SMALL LETTER SHA + {0xA7EB, 0x0449}, //6646 #CYRILLIC SMALL LETTER SHCHA + {0xA7EC, 0x044A}, //6647 #CYRILLIC SMALL LETTER HARD SIGN + {0xA7ED, 0x044B}, //6648 #CYRILLIC SMALL LETTER YERU + {0xA7EE, 0x044C}, //6649 #CYRILLIC SMALL LETTER SOFT SIGN + {0xA7EF, 0x044D}, //6650 #CYRILLIC SMALL LETTER E + {0xA7F0, 0x044E}, //6651 #CYRILLIC SMALL LETTER YU + {0xA7F1, 0x044F}, //6652 #CYRILLIC SMALL LETTER YA + {0xA840, 0x02CA}, //6653 #MODIFIER LETTER ACUTE ACCENT + {0xA841, 0x02CB}, //6654 #MODIFIER LETTER GRAVE ACCENT + {0xA842, 0x02D9}, //6655 #DOT ABOVE + {0xA843, 0x2013}, //6656 #EN DASH + {0xA844, 0x2015}, //6657 #HORIZONTAL BAR + {0xA845, 0x2025}, //6658 #TWO DOT LEADER + {0xA846, 0x2035}, //6659 #REVERSED PRIME + {0xA847, 0x2105}, //6660 #CARE OF + {0xA848, 0x2109}, //6661 #DEGREE FAHRENHEIT + {0xA849, 0x2196}, //6662 #NORTH WEST ARROW + {0xA84A, 0x2197}, //6663 #NORTH EAST ARROW + {0xA84B, 0x2198}, //6664 #SOUTH EAST ARROW + {0xA84C, 0x2199}, //6665 #SOUTH WEST ARROW + {0xA84D, 0x2215}, //6666 #DIVISION SLASH + {0xA84E, 0x221F}, //6667 #RIGHT ANGLE + {0xA84F, 0x2223}, //6668 #DIVIDES + {0xA850, 0x2252}, //6669 #APPROXIMATELY EQUAL TO OR THE IMAGE OF + {0xA851, 0x2266}, //6670 #LESS-THAN OVER EQUAL TO + {0xA852, 0x2267}, //6671 #GREATER-THAN OVER EQUAL TO + {0xA853, 0x22BF}, //6672 #RIGHT TRIANGLE + {0xA854, 0x2550}, //6673 #BOX DRAWINGS DOUBLE HORIZONTAL + {0xA855, 0x2551}, //6674 #BOX DRAWINGS DOUBLE VERTICAL + {0xA856, 0x2552}, //6675 #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + {0xA857, 0x2553}, //6676 #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + {0xA858, 0x2554}, //6677 #BOX DRAWINGS DOUBLE DOWN AND RIGHT + {0xA859, 0x2555}, //6678 #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + {0xA85A, 0x2556}, //6679 #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + {0xA85B, 0x2557}, //6680 #BOX DRAWINGS DOUBLE DOWN AND LEFT + {0xA85C, 0x2558}, //6681 #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + {0xA85D, 0x2559}, //6682 #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + {0xA85E, 0x255A}, //6683 #BOX DRAWINGS DOUBLE UP AND RIGHT + {0xA85F, 0x255B}, //6684 #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + {0xA860, 0x255C}, //6685 #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + {0xA861, 0x255D}, //6686 #BOX DRAWINGS DOUBLE UP AND LEFT + {0xA862, 0x255E}, //6687 #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + {0xA863, 0x255F}, //6688 #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + {0xA864, 0x2560}, //6689 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + {0xA865, 0x2561}, //6690 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + {0xA866, 0x2562}, //6691 #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + {0xA867, 0x2563}, //6692 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT + {0xA868, 0x2564}, //6693 #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + {0xA869, 0x2565}, //6694 #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + {0xA86A, 0x2566}, //6695 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + {0xA86B, 0x2567}, //6696 #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + {0xA86C, 0x2568}, //6697 #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + {0xA86D, 0x2569}, //6698 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL + {0xA86E, 0x256A}, //6699 #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + {0xA86F, 0x256B}, //6700 #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + {0xA870, 0x256C}, //6701 #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + {0xA871, 0x256D}, //6702 #BOX DRAWINGS LIGHT ARC DOWN AND RIGHT + {0xA872, 0x256E}, //6703 #BOX DRAWINGS LIGHT ARC DOWN AND LEFT + {0xA873, 0x256F}, //6704 #BOX DRAWINGS LIGHT ARC UP AND LEFT + {0xA874, 0x2570}, //6705 #BOX DRAWINGS LIGHT ARC UP AND RIGHT + {0xA875, 0x2571}, //6706 #BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT + {0xA876, 0x2572}, //6707 #BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT + {0xA877, 0x2573}, //6708 #BOX DRAWINGS LIGHT DIAGONAL CROSS + {0xA878, 0x2581}, //6709 #LOWER ONE EIGHTH BLOCK + {0xA879, 0x2582}, //6710 #LOWER ONE QUARTER BLOCK + {0xA87A, 0x2583}, //6711 #LOWER THREE EIGHTHS BLOCK + {0xA87B, 0x2584}, //6712 #LOWER HALF BLOCK + {0xA87C, 0x2585}, //6713 #LOWER FIVE EIGHTHS BLOCK + {0xA87D, 0x2586}, //6714 #LOWER THREE QUARTERS BLOCK + {0xA87E, 0x2587}, //6715 #LOWER SEVEN EIGHTHS BLOCK + {0xA880, 0x2588}, //6716 #FULL BLOCK + {0xA881, 0x2589}, //6717 #LEFT SEVEN EIGHTHS BLOCK + {0xA882, 0x258A}, //6718 #LEFT THREE QUARTERS BLOCK + {0xA883, 0x258B}, //6719 #LEFT FIVE EIGHTHS BLOCK + {0xA884, 0x258C}, //6720 #LEFT HALF BLOCK + {0xA885, 0x258D}, //6721 #LEFT THREE EIGHTHS BLOCK + {0xA886, 0x258E}, //6722 #LEFT ONE QUARTER BLOCK + {0xA887, 0x258F}, //6723 #LEFT ONE EIGHTH BLOCK + {0xA888, 0x2593}, //6724 #DARK SHADE + {0xA889, 0x2594}, //6725 #UPPER ONE EIGHTH BLOCK + {0xA88A, 0x2595}, //6726 #RIGHT ONE EIGHTH BLOCK + {0xA88B, 0x25BC}, //6727 #BLACK DOWN-POINTING TRIANGLE + {0xA88C, 0x25BD}, //6728 #WHITE DOWN-POINTING TRIANGLE + {0xA88D, 0x25E2}, //6729 #BLACK LOWER RIGHT TRIANGLE + {0xA88E, 0x25E3}, //6730 #BLACK LOWER LEFT TRIANGLE + {0xA88F, 0x25E4}, //6731 #BLACK UPPER LEFT TRIANGLE + {0xA890, 0x25E5}, //6732 #BLACK UPPER RIGHT TRIANGLE + {0xA891, 0x2609}, //6733 #SUN + {0xA892, 0x2295}, //6734 #CIRCLED PLUS + {0xA893, 0x3012}, //6735 #POSTAL MARK + {0xA894, 0x301D}, //6736 #REVERSED DOUBLE PRIME QUOTATION MARK + {0xA895, 0x301E}, //6737 #DOUBLE PRIME QUOTATION MARK + {0xA8A1, 0x0101}, //6738 #LATIN SMALL LETTER A WITH MACRON + {0xA8A2, 0x00E1}, //6739 #LATIN SMALL LETTER A WITH ACUTE + {0xA8A3, 0x01CE}, //6740 #LATIN SMALL LETTER A WITH CARON + {0xA8A4, 0x00E0}, //6741 #LATIN SMALL LETTER A WITH GRAVE + {0xA8A5, 0x0113}, //6742 #LATIN SMALL LETTER E WITH MACRON + {0xA8A6, 0x00E9}, //6743 #LATIN SMALL LETTER E WITH ACUTE + {0xA8A7, 0x011B}, //6744 #LATIN SMALL LETTER E WITH CARON + {0xA8A8, 0x00E8}, //6745 #LATIN SMALL LETTER E WITH GRAVE + {0xA8A9, 0x012B}, //6746 #LATIN SMALL LETTER I WITH MACRON + {0xA8AA, 0x00ED}, //6747 #LATIN SMALL LETTER I WITH ACUTE + {0xA8AB, 0x01D0}, //6748 #LATIN SMALL LETTER I WITH CARON + {0xA8AC, 0x00EC}, //6749 #LATIN SMALL LETTER I WITH GRAVE + {0xA8AD, 0x014D}, //6750 #LATIN SMALL LETTER O WITH MACRON + {0xA8AE, 0x00F3}, //6751 #LATIN SMALL LETTER O WITH ACUTE + {0xA8AF, 0x01D2}, //6752 #LATIN SMALL LETTER O WITH CARON + {0xA8B0, 0x00F2}, //6753 #LATIN SMALL LETTER O WITH GRAVE + {0xA8B1, 0x016B}, //6754 #LATIN SMALL LETTER U WITH MACRON + {0xA8B2, 0x00FA}, //6755 #LATIN SMALL LETTER U WITH ACUTE + {0xA8B3, 0x01D4}, //6756 #LATIN SMALL LETTER U WITH CARON + {0xA8B4, 0x00F9}, //6757 #LATIN SMALL LETTER U WITH GRAVE + {0xA8B5, 0x01D6}, //6758 #LATIN SMALL LETTER U WITH DIAERESIS AND MACRON + {0xA8B6, 0x01D8}, //6759 #LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE + {0xA8B7, 0x01DA}, //6760 #LATIN SMALL LETTER U WITH DIAERESIS AND CARON + {0xA8B8, 0x01DC}, //6761 #LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE + {0xA8B9, 0x00FC}, //6762 #LATIN SMALL LETTER U WITH DIAERESIS + {0xA8BA, 0x00EA}, //6763 #LATIN SMALL LETTER E WITH CIRCUMFLEX + {0xA8BB, 0x0251}, //6764 #LATIN SMALL LETTER ALPHA + {0xA8BD, 0x0144}, //6765 #LATIN SMALL LETTER N WITH ACUTE + {0xA8BE, 0x0148}, //6766 #LATIN SMALL LETTER N WITH CARON + {0xA8C0, 0x0261}, //6767 #LATIN SMALL LETTER SCRIPT G + {0xA8C5, 0x3105}, //6768 #BOPOMOFO LETTER B + {0xA8C6, 0x3106}, //6769 #BOPOMOFO LETTER P + {0xA8C7, 0x3107}, //6770 #BOPOMOFO LETTER M + {0xA8C8, 0x3108}, //6771 #BOPOMOFO LETTER F + {0xA8C9, 0x3109}, //6772 #BOPOMOFO LETTER D + {0xA8CA, 0x310A}, //6773 #BOPOMOFO LETTER T + {0xA8CB, 0x310B}, //6774 #BOPOMOFO LETTER N + {0xA8CC, 0x310C}, //6775 #BOPOMOFO LETTER L + {0xA8CD, 0x310D}, //6776 #BOPOMOFO LETTER G + {0xA8CE, 0x310E}, //6777 #BOPOMOFO LETTER K + {0xA8CF, 0x310F}, //6778 #BOPOMOFO LETTER H + {0xA8D0, 0x3110}, //6779 #BOPOMOFO LETTER J + {0xA8D1, 0x3111}, //6780 #BOPOMOFO LETTER Q + {0xA8D2, 0x3112}, //6781 #BOPOMOFO LETTER X + {0xA8D3, 0x3113}, //6782 #BOPOMOFO LETTER ZH + {0xA8D4, 0x3114}, //6783 #BOPOMOFO LETTER CH + {0xA8D5, 0x3115}, //6784 #BOPOMOFO LETTER SH + {0xA8D6, 0x3116}, //6785 #BOPOMOFO LETTER R + {0xA8D7, 0x3117}, //6786 #BOPOMOFO LETTER Z + {0xA8D8, 0x3118}, //6787 #BOPOMOFO LETTER C + {0xA8D9, 0x3119}, //6788 #BOPOMOFO LETTER S + {0xA8DA, 0x311A}, //6789 #BOPOMOFO LETTER A + {0xA8DB, 0x311B}, //6790 #BOPOMOFO LETTER O + {0xA8DC, 0x311C}, //6791 #BOPOMOFO LETTER E + {0xA8DD, 0x311D}, //6792 #BOPOMOFO LETTER EH + {0xA8DE, 0x311E}, //6793 #BOPOMOFO LETTER AI + {0xA8DF, 0x311F}, //6794 #BOPOMOFO LETTER EI + {0xA8E0, 0x3120}, //6795 #BOPOMOFO LETTER AU + {0xA8E1, 0x3121}, //6796 #BOPOMOFO LETTER OU + {0xA8E2, 0x3122}, //6797 #BOPOMOFO LETTER AN + {0xA8E3, 0x3123}, //6798 #BOPOMOFO LETTER EN + {0xA8E4, 0x3124}, //6799 #BOPOMOFO LETTER ANG + {0xA8E5, 0x3125}, //6800 #BOPOMOFO LETTER ENG + {0xA8E6, 0x3126}, //6801 #BOPOMOFO LETTER ER + {0xA8E7, 0x3127}, //6802 #BOPOMOFO LETTER I + {0xA8E8, 0x3128}, //6803 #BOPOMOFO LETTER U + {0xA8E9, 0x3129}, //6804 #BOPOMOFO LETTER IU + {0xA940, 0x3021}, //6805 #HANGZHOU NUMERAL ONE + {0xA941, 0x3022}, //6806 #HANGZHOU NUMERAL TWO + {0xA942, 0x3023}, //6807 #HANGZHOU NUMERAL THREE + {0xA943, 0x3024}, //6808 #HANGZHOU NUMERAL FOUR + {0xA944, 0x3025}, //6809 #HANGZHOU NUMERAL FIVE + {0xA945, 0x3026}, //6810 #HANGZHOU NUMERAL SIX + {0xA946, 0x3027}, //6811 #HANGZHOU NUMERAL SEVEN + {0xA947, 0x3028}, //6812 #HANGZHOU NUMERAL EIGHT + {0xA948, 0x3029}, //6813 #HANGZHOU NUMERAL NINE + {0xA949, 0x32A3}, //6814 #CIRCLED IDEOGRAPH CORRECT + {0xA94A, 0x338E}, //6815 #SQUARE MG + {0xA94B, 0x338F}, //6816 #SQUARE KG + {0xA94C, 0x339C}, //6817 #SQUARE MM + {0xA94D, 0x339D}, //6818 #SQUARE CM + {0xA94E, 0x339E}, //6819 #SQUARE KM + {0xA94F, 0x33A1}, //6820 #SQUARE M SQUARED + {0xA950, 0x33C4}, //6821 #SQUARE CC + {0xA951, 0x33CE}, //6822 #SQUARE KM CAPITAL + {0xA952, 0x33D1}, //6823 #SQUARE LN + {0xA953, 0x33D2}, //6824 #SQUARE LOG + {0xA954, 0x33D5}, //6825 #SQUARE MIL + {0xA955, 0xFE30}, //6826 #PRESENTATION FORM FOR VERTICAL TWO DOT LEADER + {0xA956, 0xFFE2}, //6827 #FULLWIDTH NOT SIGN + {0xA957, 0xFFE4}, //6828 #FULLWIDTH BROKEN BAR + {0xA959, 0x2121}, //6829 #TELEPHONE SIGN + {0xA95A, 0x3231}, //6830 #PARENTHESIZED IDEOGRAPH STOCK + {0xA95C, 0x2010}, //6831 #HYPHEN + {0xA960, 0x30FC}, //6832 #KATAKANA-HIRAGANA PROLONGED SOUND MARK + {0xA961, 0x309B}, //6833 #KATAKANA-HIRAGANA VOICED SOUND MARK + {0xA962, 0x309C}, //6834 #KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + {0xA963, 0x30FD}, //6835 #KATAKANA ITERATION MARK + {0xA964, 0x30FE}, //6836 #KATAKANA VOICED ITERATION MARK + {0xA965, 0x3006}, //6837 #IDEOGRAPHIC CLOSING MARK + {0xA966, 0x309D}, //6838 #HIRAGANA ITERATION MARK + {0xA967, 0x309E}, //6839 #HIRAGANA VOICED ITERATION MARK + {0xA968, 0xFE49}, //6840 #DASHED OVERLINE + {0xA969, 0xFE4A}, //6841 #CENTRELINE OVERLINE + {0xA96A, 0xFE4B}, //6842 #WAVY OVERLINE + {0xA96B, 0xFE4C}, //6843 #DOUBLE WAVY OVERLINE + {0xA96C, 0xFE4D}, //6844 #DASHED LOW LINE + {0xA96D, 0xFE4E}, //6845 #CENTRELINE LOW LINE + {0xA96E, 0xFE4F}, //6846 #WAVY LOW LINE + {0xA96F, 0xFE50}, //6847 #SMALL COMMA + {0xA970, 0xFE51}, //6848 #SMALL IDEOGRAPHIC COMMA + {0xA971, 0xFE52}, //6849 #SMALL FULL STOP + {0xA972, 0xFE54}, //6850 #SMALL SEMICOLON + {0xA973, 0xFE55}, //6851 #SMALL COLON + {0xA974, 0xFE56}, //6852 #SMALL QUESTION MARK + {0xA975, 0xFE57}, //6853 #SMALL EXCLAMATION MARK + {0xA976, 0xFE59}, //6854 #SMALL LEFT PARENTHESIS + {0xA977, 0xFE5A}, //6855 #SMALL RIGHT PARENTHESIS + {0xA978, 0xFE5B}, //6856 #SMALL LEFT CURLY BRACKET + {0xA979, 0xFE5C}, //6857 #SMALL RIGHT CURLY BRACKET + {0xA97A, 0xFE5D}, //6858 #SMALL LEFT TORTOISE SHELL BRACKET + {0xA97B, 0xFE5E}, //6859 #SMALL RIGHT TORTOISE SHELL BRACKET + {0xA97C, 0xFE5F}, //6860 #SMALL NUMBER SIGN + {0xA97D, 0xFE60}, //6861 #SMALL AMPERSAND + {0xA97E, 0xFE61}, //6862 #SMALL ASTERISK + {0xA980, 0xFE62}, //6863 #SMALL PLUS SIGN + {0xA981, 0xFE63}, //6864 #SMALL HYPHEN-MINUS + {0xA982, 0xFE64}, //6865 #SMALL LESS-THAN SIGN + {0xA983, 0xFE65}, //6866 #SMALL GREATER-THAN SIGN + {0xA984, 0xFE66}, //6867 #SMALL EQUALS SIGN + {0xA985, 0xFE68}, //6868 #SMALL REVERSE SOLIDUS + {0xA986, 0xFE69}, //6869 #SMALL DOLLAR SIGN + {0xA987, 0xFE6A}, //6870 #SMALL PERCENT SIGN + {0xA988, 0xFE6B}, //6871 #SMALL COMMERCIAL AT + {0xA996, 0x3007}, //6872 #IDEOGRAPHIC NUMBER ZERO + {0xA9A4, 0x2500}, //6873 #BOX DRAWINGS LIGHT HORIZONTAL + {0xA9A5, 0x2501}, //6874 #BOX DRAWINGS HEAVY HORIZONTAL + {0xA9A6, 0x2502}, //6875 #BOX DRAWINGS LIGHT VERTICAL + {0xA9A7, 0x2503}, //6876 #BOX DRAWINGS HEAVY VERTICAL + {0xA9A8, 0x2504}, //6877 #BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL + {0xA9A9, 0x2505}, //6878 #BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL + {0xA9AA, 0x2506}, //6879 #BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL + {0xA9AB, 0x2507}, //6880 #BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL + {0xA9AC, 0x2508}, //6881 #BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL + {0xA9AD, 0x2509}, //6882 #BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL + {0xA9AE, 0x250A}, //6883 #BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL + {0xA9AF, 0x250B}, //6884 #BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL + {0xA9B0, 0x250C}, //6885 #BOX DRAWINGS LIGHT DOWN AND RIGHT + {0xA9B1, 0x250D}, //6886 #BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY + {0xA9B2, 0x250E}, //6887 #BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT + {0xA9B3, 0x250F}, //6888 #BOX DRAWINGS HEAVY DOWN AND RIGHT + {0xA9B4, 0x2510}, //6889 #BOX DRAWINGS LIGHT DOWN AND LEFT + {0xA9B5, 0x2511}, //6890 #BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY + {0xA9B6, 0x2512}, //6891 #BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT + {0xA9B7, 0x2513}, //6892 #BOX DRAWINGS HEAVY DOWN AND LEFT + {0xA9B8, 0x2514}, //6893 #BOX DRAWINGS LIGHT UP AND RIGHT + {0xA9B9, 0x2515}, //6894 #BOX DRAWINGS UP LIGHT AND RIGHT HEAVY + {0xA9BA, 0x2516}, //6895 #BOX DRAWINGS UP HEAVY AND RIGHT LIGHT + {0xA9BB, 0x2517}, //6896 #BOX DRAWINGS HEAVY UP AND RIGHT + {0xA9BC, 0x2518}, //6897 #BOX DRAWINGS LIGHT UP AND LEFT + {0xA9BD, 0x2519}, //6898 #BOX DRAWINGS UP LIGHT AND LEFT HEAVY + {0xA9BE, 0x251A}, //6899 #BOX DRAWINGS UP HEAVY AND LEFT LIGHT + {0xA9BF, 0x251B}, //6900 #BOX DRAWINGS HEAVY UP AND LEFT + {0xA9C0, 0x251C}, //6901 #BOX DRAWINGS LIGHT VERTICAL AND RIGHT + {0xA9C1, 0x251D}, //6902 #BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY + {0xA9C2, 0x251E}, //6903 #BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT + {0xA9C3, 0x251F}, //6904 #BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT + {0xA9C4, 0x2520}, //6905 #BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT + {0xA9C5, 0x2521}, //6906 #BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY + {0xA9C6, 0x2522}, //6907 #BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY + {0xA9C7, 0x2523}, //6908 #BOX DRAWINGS HEAVY VERTICAL AND RIGHT + {0xA9C8, 0x2524}, //6909 #BOX DRAWINGS LIGHT VERTICAL AND LEFT + {0xA9C9, 0x2525}, //6910 #BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY + {0xA9CA, 0x2526}, //6911 #BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT + {0xA9CB, 0x2527}, //6912 #BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT + {0xA9CC, 0x2528}, //6913 #BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT + {0xA9CD, 0x2529}, //6914 #BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY + {0xA9CE, 0x252A}, //6915 #BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY + {0xA9CF, 0x252B}, //6916 #BOX DRAWINGS HEAVY VERTICAL AND LEFT + {0xA9D0, 0x252C}, //6917 #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + {0xA9D1, 0x252D}, //6918 #BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT + {0xA9D2, 0x252E}, //6919 #BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT + {0xA9D3, 0x252F}, //6920 #BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY + {0xA9D4, 0x2530}, //6921 #BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT + {0xA9D5, 0x2531}, //6922 #BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY + {0xA9D6, 0x2532}, //6923 #BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY + {0xA9D7, 0x2533}, //6924 #BOX DRAWINGS HEAVY DOWN AND HORIZONTAL + {0xA9D8, 0x2534}, //6925 #BOX DRAWINGS LIGHT UP AND HORIZONTAL + {0xA9D9, 0x2535}, //6926 #BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT + {0xA9DA, 0x2536}, //6927 #BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT + {0xA9DB, 0x2537}, //6928 #BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY + {0xA9DC, 0x2538}, //6929 #BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT + {0xA9DD, 0x2539}, //6930 #BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY + {0xA9DE, 0x253A}, //6931 #BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY + {0xA9DF, 0x253B}, //6932 #BOX DRAWINGS HEAVY UP AND HORIZONTAL + {0xA9E0, 0x253C}, //6933 #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + {0xA9E1, 0x253D}, //6934 #BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT + {0xA9E2, 0x253E}, //6935 #BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT + {0xA9E3, 0x253F}, //6936 #BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY + {0xA9E4, 0x2540}, //6937 #BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT + {0xA9E5, 0x2541}, //6938 #BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT + {0xA9E6, 0x2542}, //6939 #BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT + {0xA9E7, 0x2543}, //6940 #BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT + {0xA9E8, 0x2544}, //6941 #BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT + {0xA9E9, 0x2545}, //6942 #BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT + {0xA9EA, 0x2546}, //6943 #BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT + {0xA9EB, 0x2547}, //6944 #BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY + {0xA9EC, 0x2548}, //6945 #BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY + {0xA9ED, 0x2549}, //6946 #BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY + {0xA9EE, 0x254A}, //6947 #BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY + {0xA9EF, 0x254B}, //6948 #BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL + {0xAA40, 0x72DC}, //6949 #CJK UNIFIED IDEOGRAPH + {0xAA41, 0x72DD}, //6950 #CJK UNIFIED IDEOGRAPH + {0xAA42, 0x72DF}, //6951 #CJK UNIFIED IDEOGRAPH + {0xAA43, 0x72E2}, //6952 #CJK UNIFIED IDEOGRAPH + {0xAA44, 0x72E3}, //6953 #CJK UNIFIED IDEOGRAPH + {0xAA45, 0x72E4}, //6954 #CJK UNIFIED IDEOGRAPH + {0xAA46, 0x72E5}, //6955 #CJK UNIFIED IDEOGRAPH + {0xAA47, 0x72E6}, //6956 #CJK UNIFIED IDEOGRAPH + {0xAA48, 0x72E7}, //6957 #CJK UNIFIED IDEOGRAPH + {0xAA49, 0x72EA}, //6958 #CJK UNIFIED IDEOGRAPH + {0xAA4A, 0x72EB}, //6959 #CJK UNIFIED IDEOGRAPH + {0xAA4B, 0x72F5}, //6960 #CJK UNIFIED IDEOGRAPH + {0xAA4C, 0x72F6}, //6961 #CJK UNIFIED IDEOGRAPH + {0xAA4D, 0x72F9}, //6962 #CJK UNIFIED IDEOGRAPH + {0xAA4E, 0x72FD}, //6963 #CJK UNIFIED IDEOGRAPH + {0xAA4F, 0x72FE}, //6964 #CJK UNIFIED IDEOGRAPH + {0xAA50, 0x72FF}, //6965 #CJK UNIFIED IDEOGRAPH + {0xAA51, 0x7300}, //6966 #CJK UNIFIED IDEOGRAPH + {0xAA52, 0x7302}, //6967 #CJK UNIFIED IDEOGRAPH + {0xAA53, 0x7304}, //6968 #CJK UNIFIED IDEOGRAPH + {0xAA54, 0x7305}, //6969 #CJK UNIFIED IDEOGRAPH + {0xAA55, 0x7306}, //6970 #CJK UNIFIED IDEOGRAPH + {0xAA56, 0x7307}, //6971 #CJK UNIFIED IDEOGRAPH + {0xAA57, 0x7308}, //6972 #CJK UNIFIED IDEOGRAPH + {0xAA58, 0x7309}, //6973 #CJK UNIFIED IDEOGRAPH + {0xAA59, 0x730B}, //6974 #CJK UNIFIED IDEOGRAPH + {0xAA5A, 0x730C}, //6975 #CJK UNIFIED IDEOGRAPH + {0xAA5B, 0x730D}, //6976 #CJK UNIFIED IDEOGRAPH + {0xAA5C, 0x730F}, //6977 #CJK UNIFIED IDEOGRAPH + {0xAA5D, 0x7310}, //6978 #CJK UNIFIED IDEOGRAPH + {0xAA5E, 0x7311}, //6979 #CJK UNIFIED IDEOGRAPH + {0xAA5F, 0x7312}, //6980 #CJK UNIFIED IDEOGRAPH + {0xAA60, 0x7314}, //6981 #CJK UNIFIED IDEOGRAPH + {0xAA61, 0x7318}, //6982 #CJK UNIFIED IDEOGRAPH + {0xAA62, 0x7319}, //6983 #CJK UNIFIED IDEOGRAPH + {0xAA63, 0x731A}, //6984 #CJK UNIFIED IDEOGRAPH + {0xAA64, 0x731F}, //6985 #CJK UNIFIED IDEOGRAPH + {0xAA65, 0x7320}, //6986 #CJK UNIFIED IDEOGRAPH + {0xAA66, 0x7323}, //6987 #CJK UNIFIED IDEOGRAPH + {0xAA67, 0x7324}, //6988 #CJK UNIFIED IDEOGRAPH + {0xAA68, 0x7326}, //6989 #CJK UNIFIED IDEOGRAPH + {0xAA69, 0x7327}, //6990 #CJK UNIFIED IDEOGRAPH + {0xAA6A, 0x7328}, //6991 #CJK UNIFIED IDEOGRAPH + {0xAA6B, 0x732D}, //6992 #CJK UNIFIED IDEOGRAPH + {0xAA6C, 0x732F}, //6993 #CJK UNIFIED IDEOGRAPH + {0xAA6D, 0x7330}, //6994 #CJK UNIFIED IDEOGRAPH + {0xAA6E, 0x7332}, //6995 #CJK UNIFIED IDEOGRAPH + {0xAA6F, 0x7333}, //6996 #CJK UNIFIED IDEOGRAPH + {0xAA70, 0x7335}, //6997 #CJK UNIFIED IDEOGRAPH + {0xAA71, 0x7336}, //6998 #CJK UNIFIED IDEOGRAPH + {0xAA72, 0x733A}, //6999 #CJK UNIFIED IDEOGRAPH + {0xAA73, 0x733B}, //7000 #CJK UNIFIED IDEOGRAPH + {0xAA74, 0x733C}, //7001 #CJK UNIFIED IDEOGRAPH + {0xAA75, 0x733D}, //7002 #CJK UNIFIED IDEOGRAPH + {0xAA76, 0x7340}, //7003 #CJK UNIFIED IDEOGRAPH + {0xAA77, 0x7341}, //7004 #CJK UNIFIED IDEOGRAPH + {0xAA78, 0x7342}, //7005 #CJK UNIFIED IDEOGRAPH + {0xAA79, 0x7343}, //7006 #CJK UNIFIED IDEOGRAPH + {0xAA7A, 0x7344}, //7007 #CJK UNIFIED IDEOGRAPH + {0xAA7B, 0x7345}, //7008 #CJK UNIFIED IDEOGRAPH + {0xAA7C, 0x7346}, //7009 #CJK UNIFIED IDEOGRAPH + {0xAA7D, 0x7347}, //7010 #CJK UNIFIED IDEOGRAPH + {0xAA7E, 0x7348}, //7011 #CJK UNIFIED IDEOGRAPH + {0xAA80, 0x7349}, //7012 #CJK UNIFIED IDEOGRAPH + {0xAA81, 0x734A}, //7013 #CJK UNIFIED IDEOGRAPH + {0xAA82, 0x734B}, //7014 #CJK UNIFIED IDEOGRAPH + {0xAA83, 0x734C}, //7015 #CJK UNIFIED IDEOGRAPH + {0xAA84, 0x734E}, //7016 #CJK UNIFIED IDEOGRAPH + {0xAA85, 0x734F}, //7017 #CJK UNIFIED IDEOGRAPH + {0xAA86, 0x7351}, //7018 #CJK UNIFIED IDEOGRAPH + {0xAA87, 0x7353}, //7019 #CJK UNIFIED IDEOGRAPH + {0xAA88, 0x7354}, //7020 #CJK UNIFIED IDEOGRAPH + {0xAA89, 0x7355}, //7021 #CJK UNIFIED IDEOGRAPH + {0xAA8A, 0x7356}, //7022 #CJK UNIFIED IDEOGRAPH + {0xAA8B, 0x7358}, //7023 #CJK UNIFIED IDEOGRAPH + {0xAA8C, 0x7359}, //7024 #CJK UNIFIED IDEOGRAPH + {0xAA8D, 0x735A}, //7025 #CJK UNIFIED IDEOGRAPH + {0xAA8E, 0x735B}, //7026 #CJK UNIFIED IDEOGRAPH + {0xAA8F, 0x735C}, //7027 #CJK UNIFIED IDEOGRAPH + {0xAA90, 0x735D}, //7028 #CJK UNIFIED IDEOGRAPH + {0xAA91, 0x735E}, //7029 #CJK UNIFIED IDEOGRAPH + {0xAA92, 0x735F}, //7030 #CJK UNIFIED IDEOGRAPH + {0xAA93, 0x7361}, //7031 #CJK UNIFIED IDEOGRAPH + {0xAA94, 0x7362}, //7032 #CJK UNIFIED IDEOGRAPH + {0xAA95, 0x7363}, //7033 #CJK UNIFIED IDEOGRAPH + {0xAA96, 0x7364}, //7034 #CJK UNIFIED IDEOGRAPH + {0xAA97, 0x7365}, //7035 #CJK UNIFIED IDEOGRAPH + {0xAA98, 0x7366}, //7036 #CJK UNIFIED IDEOGRAPH + {0xAA99, 0x7367}, //7037 #CJK UNIFIED IDEOGRAPH + {0xAA9A, 0x7368}, //7038 #CJK UNIFIED IDEOGRAPH + {0xAA9B, 0x7369}, //7039 #CJK UNIFIED IDEOGRAPH + {0xAA9C, 0x736A}, //7040 #CJK UNIFIED IDEOGRAPH + {0xAA9D, 0x736B}, //7041 #CJK UNIFIED IDEOGRAPH + {0xAA9E, 0x736E}, //7042 #CJK UNIFIED IDEOGRAPH + {0xAA9F, 0x7370}, //7043 #CJK UNIFIED IDEOGRAPH + {0xAAA0, 0x7371}, //7044 #CJK UNIFIED IDEOGRAPH + {0xAB40, 0x7372}, //7045 #CJK UNIFIED IDEOGRAPH + {0xAB41, 0x7373}, //7046 #CJK UNIFIED IDEOGRAPH + {0xAB42, 0x7374}, //7047 #CJK UNIFIED IDEOGRAPH + {0xAB43, 0x7375}, //7048 #CJK UNIFIED IDEOGRAPH + {0xAB44, 0x7376}, //7049 #CJK UNIFIED IDEOGRAPH + {0xAB45, 0x7377}, //7050 #CJK UNIFIED IDEOGRAPH + {0xAB46, 0x7378}, //7051 #CJK UNIFIED IDEOGRAPH + {0xAB47, 0x7379}, //7052 #CJK UNIFIED IDEOGRAPH + {0xAB48, 0x737A}, //7053 #CJK UNIFIED IDEOGRAPH + {0xAB49, 0x737B}, //7054 #CJK UNIFIED IDEOGRAPH + {0xAB4A, 0x737C}, //7055 #CJK UNIFIED IDEOGRAPH + {0xAB4B, 0x737D}, //7056 #CJK UNIFIED IDEOGRAPH + {0xAB4C, 0x737F}, //7057 #CJK UNIFIED IDEOGRAPH + {0xAB4D, 0x7380}, //7058 #CJK UNIFIED IDEOGRAPH + {0xAB4E, 0x7381}, //7059 #CJK UNIFIED IDEOGRAPH + {0xAB4F, 0x7382}, //7060 #CJK UNIFIED IDEOGRAPH + {0xAB50, 0x7383}, //7061 #CJK UNIFIED IDEOGRAPH + {0xAB51, 0x7385}, //7062 #CJK UNIFIED IDEOGRAPH + {0xAB52, 0x7386}, //7063 #CJK UNIFIED IDEOGRAPH + {0xAB53, 0x7388}, //7064 #CJK UNIFIED IDEOGRAPH + {0xAB54, 0x738A}, //7065 #CJK UNIFIED IDEOGRAPH + {0xAB55, 0x738C}, //7066 #CJK UNIFIED IDEOGRAPH + {0xAB56, 0x738D}, //7067 #CJK UNIFIED IDEOGRAPH + {0xAB57, 0x738F}, //7068 #CJK UNIFIED IDEOGRAPH + {0xAB58, 0x7390}, //7069 #CJK UNIFIED IDEOGRAPH + {0xAB59, 0x7392}, //7070 #CJK UNIFIED IDEOGRAPH + {0xAB5A, 0x7393}, //7071 #CJK UNIFIED IDEOGRAPH + {0xAB5B, 0x7394}, //7072 #CJK UNIFIED IDEOGRAPH + {0xAB5C, 0x7395}, //7073 #CJK UNIFIED IDEOGRAPH + {0xAB5D, 0x7397}, //7074 #CJK UNIFIED IDEOGRAPH + {0xAB5E, 0x7398}, //7075 #CJK UNIFIED IDEOGRAPH + {0xAB5F, 0x7399}, //7076 #CJK UNIFIED IDEOGRAPH + {0xAB60, 0x739A}, //7077 #CJK UNIFIED IDEOGRAPH + {0xAB61, 0x739C}, //7078 #CJK UNIFIED IDEOGRAPH + {0xAB62, 0x739D}, //7079 #CJK UNIFIED IDEOGRAPH + {0xAB63, 0x739E}, //7080 #CJK UNIFIED IDEOGRAPH + {0xAB64, 0x73A0}, //7081 #CJK UNIFIED IDEOGRAPH + {0xAB65, 0x73A1}, //7082 #CJK UNIFIED IDEOGRAPH + {0xAB66, 0x73A3}, //7083 #CJK UNIFIED IDEOGRAPH + {0xAB67, 0x73A4}, //7084 #CJK UNIFIED IDEOGRAPH + {0xAB68, 0x73A5}, //7085 #CJK UNIFIED IDEOGRAPH + {0xAB69, 0x73A6}, //7086 #CJK UNIFIED IDEOGRAPH + {0xAB6A, 0x73A7}, //7087 #CJK UNIFIED IDEOGRAPH + {0xAB6B, 0x73A8}, //7088 #CJK UNIFIED IDEOGRAPH + {0xAB6C, 0x73AA}, //7089 #CJK UNIFIED IDEOGRAPH + {0xAB6D, 0x73AC}, //7090 #CJK UNIFIED IDEOGRAPH + {0xAB6E, 0x73AD}, //7091 #CJK UNIFIED IDEOGRAPH + {0xAB6F, 0x73B1}, //7092 #CJK UNIFIED IDEOGRAPH + {0xAB70, 0x73B4}, //7093 #CJK UNIFIED IDEOGRAPH + {0xAB71, 0x73B5}, //7094 #CJK UNIFIED IDEOGRAPH + {0xAB72, 0x73B6}, //7095 #CJK UNIFIED IDEOGRAPH + {0xAB73, 0x73B8}, //7096 #CJK UNIFIED IDEOGRAPH + {0xAB74, 0x73B9}, //7097 #CJK UNIFIED IDEOGRAPH + {0xAB75, 0x73BC}, //7098 #CJK UNIFIED IDEOGRAPH + {0xAB76, 0x73BD}, //7099 #CJK UNIFIED IDEOGRAPH + {0xAB77, 0x73BE}, //7100 #CJK UNIFIED IDEOGRAPH + {0xAB78, 0x73BF}, //7101 #CJK UNIFIED IDEOGRAPH + {0xAB79, 0x73C1}, //7102 #CJK UNIFIED IDEOGRAPH + {0xAB7A, 0x73C3}, //7103 #CJK UNIFIED IDEOGRAPH + {0xAB7B, 0x73C4}, //7104 #CJK UNIFIED IDEOGRAPH + {0xAB7C, 0x73C5}, //7105 #CJK UNIFIED IDEOGRAPH + {0xAB7D, 0x73C6}, //7106 #CJK UNIFIED IDEOGRAPH + {0xAB7E, 0x73C7}, //7107 #CJK UNIFIED IDEOGRAPH + {0xAB80, 0x73CB}, //7108 #CJK UNIFIED IDEOGRAPH + {0xAB81, 0x73CC}, //7109 #CJK UNIFIED IDEOGRAPH + {0xAB82, 0x73CE}, //7110 #CJK UNIFIED IDEOGRAPH + {0xAB83, 0x73D2}, //7111 #CJK UNIFIED IDEOGRAPH + {0xAB84, 0x73D3}, //7112 #CJK UNIFIED IDEOGRAPH + {0xAB85, 0x73D4}, //7113 #CJK UNIFIED IDEOGRAPH + {0xAB86, 0x73D5}, //7114 #CJK UNIFIED IDEOGRAPH + {0xAB87, 0x73D6}, //7115 #CJK UNIFIED IDEOGRAPH + {0xAB88, 0x73D7}, //7116 #CJK UNIFIED IDEOGRAPH + {0xAB89, 0x73D8}, //7117 #CJK UNIFIED IDEOGRAPH + {0xAB8A, 0x73DA}, //7118 #CJK UNIFIED IDEOGRAPH + {0xAB8B, 0x73DB}, //7119 #CJK UNIFIED IDEOGRAPH + {0xAB8C, 0x73DC}, //7120 #CJK UNIFIED IDEOGRAPH + {0xAB8D, 0x73DD}, //7121 #CJK UNIFIED IDEOGRAPH + {0xAB8E, 0x73DF}, //7122 #CJK UNIFIED IDEOGRAPH + {0xAB8F, 0x73E1}, //7123 #CJK UNIFIED IDEOGRAPH + {0xAB90, 0x73E2}, //7124 #CJK UNIFIED IDEOGRAPH + {0xAB91, 0x73E3}, //7125 #CJK UNIFIED IDEOGRAPH + {0xAB92, 0x73E4}, //7126 #CJK UNIFIED IDEOGRAPH + {0xAB93, 0x73E6}, //7127 #CJK UNIFIED IDEOGRAPH + {0xAB94, 0x73E8}, //7128 #CJK UNIFIED IDEOGRAPH + {0xAB95, 0x73EA}, //7129 #CJK UNIFIED IDEOGRAPH + {0xAB96, 0x73EB}, //7130 #CJK UNIFIED IDEOGRAPH + {0xAB97, 0x73EC}, //7131 #CJK UNIFIED IDEOGRAPH + {0xAB98, 0x73EE}, //7132 #CJK UNIFIED IDEOGRAPH + {0xAB99, 0x73EF}, //7133 #CJK UNIFIED IDEOGRAPH + {0xAB9A, 0x73F0}, //7134 #CJK UNIFIED IDEOGRAPH + {0xAB9B, 0x73F1}, //7135 #CJK UNIFIED IDEOGRAPH + {0xAB9C, 0x73F3}, //7136 #CJK UNIFIED IDEOGRAPH + {0xAB9D, 0x73F4}, //7137 #CJK UNIFIED IDEOGRAPH + {0xAB9E, 0x73F5}, //7138 #CJK UNIFIED IDEOGRAPH + {0xAB9F, 0x73F6}, //7139 #CJK UNIFIED IDEOGRAPH + {0xABA0, 0x73F7}, //7140 #CJK UNIFIED IDEOGRAPH + {0xAC40, 0x73F8}, //7141 #CJK UNIFIED IDEOGRAPH + {0xAC41, 0x73F9}, //7142 #CJK UNIFIED IDEOGRAPH + {0xAC42, 0x73FA}, //7143 #CJK UNIFIED IDEOGRAPH + {0xAC43, 0x73FB}, //7144 #CJK UNIFIED IDEOGRAPH + {0xAC44, 0x73FC}, //7145 #CJK UNIFIED IDEOGRAPH + {0xAC45, 0x73FD}, //7146 #CJK UNIFIED IDEOGRAPH + {0xAC46, 0x73FE}, //7147 #CJK UNIFIED IDEOGRAPH + {0xAC47, 0x73FF}, //7148 #CJK UNIFIED IDEOGRAPH + {0xAC48, 0x7400}, //7149 #CJK UNIFIED IDEOGRAPH + {0xAC49, 0x7401}, //7150 #CJK UNIFIED IDEOGRAPH + {0xAC4A, 0x7402}, //7151 #CJK UNIFIED IDEOGRAPH + {0xAC4B, 0x7404}, //7152 #CJK UNIFIED IDEOGRAPH + {0xAC4C, 0x7407}, //7153 #CJK UNIFIED IDEOGRAPH + {0xAC4D, 0x7408}, //7154 #CJK UNIFIED IDEOGRAPH + {0xAC4E, 0x740B}, //7155 #CJK UNIFIED IDEOGRAPH + {0xAC4F, 0x740C}, //7156 #CJK UNIFIED IDEOGRAPH + {0xAC50, 0x740D}, //7157 #CJK UNIFIED IDEOGRAPH + {0xAC51, 0x740E}, //7158 #CJK UNIFIED IDEOGRAPH + {0xAC52, 0x7411}, //7159 #CJK UNIFIED IDEOGRAPH + {0xAC53, 0x7412}, //7160 #CJK UNIFIED IDEOGRAPH + {0xAC54, 0x7413}, //7161 #CJK UNIFIED IDEOGRAPH + {0xAC55, 0x7414}, //7162 #CJK UNIFIED IDEOGRAPH + {0xAC56, 0x7415}, //7163 #CJK UNIFIED IDEOGRAPH + {0xAC57, 0x7416}, //7164 #CJK UNIFIED IDEOGRAPH + {0xAC58, 0x7417}, //7165 #CJK UNIFIED IDEOGRAPH + {0xAC59, 0x7418}, //7166 #CJK UNIFIED IDEOGRAPH + {0xAC5A, 0x7419}, //7167 #CJK UNIFIED IDEOGRAPH + {0xAC5B, 0x741C}, //7168 #CJK UNIFIED IDEOGRAPH + {0xAC5C, 0x741D}, //7169 #CJK UNIFIED IDEOGRAPH + {0xAC5D, 0x741E}, //7170 #CJK UNIFIED IDEOGRAPH + {0xAC5E, 0x741F}, //7171 #CJK UNIFIED IDEOGRAPH + {0xAC5F, 0x7420}, //7172 #CJK UNIFIED IDEOGRAPH + {0xAC60, 0x7421}, //7173 #CJK UNIFIED IDEOGRAPH + {0xAC61, 0x7423}, //7174 #CJK UNIFIED IDEOGRAPH + {0xAC62, 0x7424}, //7175 #CJK UNIFIED IDEOGRAPH + {0xAC63, 0x7427}, //7176 #CJK UNIFIED IDEOGRAPH + {0xAC64, 0x7429}, //7177 #CJK UNIFIED IDEOGRAPH + {0xAC65, 0x742B}, //7178 #CJK UNIFIED IDEOGRAPH + {0xAC66, 0x742D}, //7179 #CJK UNIFIED IDEOGRAPH + {0xAC67, 0x742F}, //7180 #CJK UNIFIED IDEOGRAPH + {0xAC68, 0x7431}, //7181 #CJK UNIFIED IDEOGRAPH + {0xAC69, 0x7432}, //7182 #CJK UNIFIED IDEOGRAPH + {0xAC6A, 0x7437}, //7183 #CJK UNIFIED IDEOGRAPH + {0xAC6B, 0x7438}, //7184 #CJK UNIFIED IDEOGRAPH + {0xAC6C, 0x7439}, //7185 #CJK UNIFIED IDEOGRAPH + {0xAC6D, 0x743A}, //7186 #CJK UNIFIED IDEOGRAPH + {0xAC6E, 0x743B}, //7187 #CJK UNIFIED IDEOGRAPH + {0xAC6F, 0x743D}, //7188 #CJK UNIFIED IDEOGRAPH + {0xAC70, 0x743E}, //7189 #CJK UNIFIED IDEOGRAPH + {0xAC71, 0x743F}, //7190 #CJK UNIFIED IDEOGRAPH + {0xAC72, 0x7440}, //7191 #CJK UNIFIED IDEOGRAPH + {0xAC73, 0x7442}, //7192 #CJK UNIFIED IDEOGRAPH + {0xAC74, 0x7443}, //7193 #CJK UNIFIED IDEOGRAPH + {0xAC75, 0x7444}, //7194 #CJK UNIFIED IDEOGRAPH + {0xAC76, 0x7445}, //7195 #CJK UNIFIED IDEOGRAPH + {0xAC77, 0x7446}, //7196 #CJK UNIFIED IDEOGRAPH + {0xAC78, 0x7447}, //7197 #CJK UNIFIED IDEOGRAPH + {0xAC79, 0x7448}, //7198 #CJK UNIFIED IDEOGRAPH + {0xAC7A, 0x7449}, //7199 #CJK UNIFIED IDEOGRAPH + {0xAC7B, 0x744A}, //7200 #CJK UNIFIED IDEOGRAPH + {0xAC7C, 0x744B}, //7201 #CJK UNIFIED IDEOGRAPH + {0xAC7D, 0x744C}, //7202 #CJK UNIFIED IDEOGRAPH + {0xAC7E, 0x744D}, //7203 #CJK UNIFIED IDEOGRAPH + {0xAC80, 0x744E}, //7204 #CJK UNIFIED IDEOGRAPH + {0xAC81, 0x744F}, //7205 #CJK UNIFIED IDEOGRAPH + {0xAC82, 0x7450}, //7206 #CJK UNIFIED IDEOGRAPH + {0xAC83, 0x7451}, //7207 #CJK UNIFIED IDEOGRAPH + {0xAC84, 0x7452}, //7208 #CJK UNIFIED IDEOGRAPH + {0xAC85, 0x7453}, //7209 #CJK UNIFIED IDEOGRAPH + {0xAC86, 0x7454}, //7210 #CJK UNIFIED IDEOGRAPH + {0xAC87, 0x7456}, //7211 #CJK UNIFIED IDEOGRAPH + {0xAC88, 0x7458}, //7212 #CJK UNIFIED IDEOGRAPH + {0xAC89, 0x745D}, //7213 #CJK UNIFIED IDEOGRAPH + {0xAC8A, 0x7460}, //7214 #CJK UNIFIED IDEOGRAPH + {0xAC8B, 0x7461}, //7215 #CJK UNIFIED IDEOGRAPH + {0xAC8C, 0x7462}, //7216 #CJK UNIFIED IDEOGRAPH + {0xAC8D, 0x7463}, //7217 #CJK UNIFIED IDEOGRAPH + {0xAC8E, 0x7464}, //7218 #CJK UNIFIED IDEOGRAPH + {0xAC8F, 0x7465}, //7219 #CJK UNIFIED IDEOGRAPH + {0xAC90, 0x7466}, //7220 #CJK UNIFIED IDEOGRAPH + {0xAC91, 0x7467}, //7221 #CJK UNIFIED IDEOGRAPH + {0xAC92, 0x7468}, //7222 #CJK UNIFIED IDEOGRAPH + {0xAC93, 0x7469}, //7223 #CJK UNIFIED IDEOGRAPH + {0xAC94, 0x746A}, //7224 #CJK UNIFIED IDEOGRAPH + {0xAC95, 0x746B}, //7225 #CJK UNIFIED IDEOGRAPH + {0xAC96, 0x746C}, //7226 #CJK UNIFIED IDEOGRAPH + {0xAC97, 0x746E}, //7227 #CJK UNIFIED IDEOGRAPH + {0xAC98, 0x746F}, //7228 #CJK UNIFIED IDEOGRAPH + {0xAC99, 0x7471}, //7229 #CJK UNIFIED IDEOGRAPH + {0xAC9A, 0x7472}, //7230 #CJK UNIFIED IDEOGRAPH + {0xAC9B, 0x7473}, //7231 #CJK UNIFIED IDEOGRAPH + {0xAC9C, 0x7474}, //7232 #CJK UNIFIED IDEOGRAPH + {0xAC9D, 0x7475}, //7233 #CJK UNIFIED IDEOGRAPH + {0xAC9E, 0x7478}, //7234 #CJK UNIFIED IDEOGRAPH + {0xAC9F, 0x7479}, //7235 #CJK UNIFIED IDEOGRAPH + {0xACA0, 0x747A}, //7236 #CJK UNIFIED IDEOGRAPH + {0xAD40, 0x747B}, //7237 #CJK UNIFIED IDEOGRAPH + {0xAD41, 0x747C}, //7238 #CJK UNIFIED IDEOGRAPH + {0xAD42, 0x747D}, //7239 #CJK UNIFIED IDEOGRAPH + {0xAD43, 0x747F}, //7240 #CJK UNIFIED IDEOGRAPH + {0xAD44, 0x7482}, //7241 #CJK UNIFIED IDEOGRAPH + {0xAD45, 0x7484}, //7242 #CJK UNIFIED IDEOGRAPH + {0xAD46, 0x7485}, //7243 #CJK UNIFIED IDEOGRAPH + {0xAD47, 0x7486}, //7244 #CJK UNIFIED IDEOGRAPH + {0xAD48, 0x7488}, //7245 #CJK UNIFIED IDEOGRAPH + {0xAD49, 0x7489}, //7246 #CJK UNIFIED IDEOGRAPH + {0xAD4A, 0x748A}, //7247 #CJK UNIFIED IDEOGRAPH + {0xAD4B, 0x748C}, //7248 #CJK UNIFIED IDEOGRAPH + {0xAD4C, 0x748D}, //7249 #CJK UNIFIED IDEOGRAPH + {0xAD4D, 0x748F}, //7250 #CJK UNIFIED IDEOGRAPH + {0xAD4E, 0x7491}, //7251 #CJK UNIFIED IDEOGRAPH + {0xAD4F, 0x7492}, //7252 #CJK UNIFIED IDEOGRAPH + {0xAD50, 0x7493}, //7253 #CJK UNIFIED IDEOGRAPH + {0xAD51, 0x7494}, //7254 #CJK UNIFIED IDEOGRAPH + {0xAD52, 0x7495}, //7255 #CJK UNIFIED IDEOGRAPH + {0xAD53, 0x7496}, //7256 #CJK UNIFIED IDEOGRAPH + {0xAD54, 0x7497}, //7257 #CJK UNIFIED IDEOGRAPH + {0xAD55, 0x7498}, //7258 #CJK UNIFIED IDEOGRAPH + {0xAD56, 0x7499}, //7259 #CJK UNIFIED IDEOGRAPH + {0xAD57, 0x749A}, //7260 #CJK UNIFIED IDEOGRAPH + {0xAD58, 0x749B}, //7261 #CJK UNIFIED IDEOGRAPH + {0xAD59, 0x749D}, //7262 #CJK UNIFIED IDEOGRAPH + {0xAD5A, 0x749F}, //7263 #CJK UNIFIED IDEOGRAPH + {0xAD5B, 0x74A0}, //7264 #CJK UNIFIED IDEOGRAPH + {0xAD5C, 0x74A1}, //7265 #CJK UNIFIED IDEOGRAPH + {0xAD5D, 0x74A2}, //7266 #CJK UNIFIED IDEOGRAPH + {0xAD5E, 0x74A3}, //7267 #CJK UNIFIED IDEOGRAPH + {0xAD5F, 0x74A4}, //7268 #CJK UNIFIED IDEOGRAPH + {0xAD60, 0x74A5}, //7269 #CJK UNIFIED IDEOGRAPH + {0xAD61, 0x74A6}, //7270 #CJK UNIFIED IDEOGRAPH + {0xAD62, 0x74AA}, //7271 #CJK UNIFIED IDEOGRAPH + {0xAD63, 0x74AB}, //7272 #CJK UNIFIED IDEOGRAPH + {0xAD64, 0x74AC}, //7273 #CJK UNIFIED IDEOGRAPH + {0xAD65, 0x74AD}, //7274 #CJK UNIFIED IDEOGRAPH + {0xAD66, 0x74AE}, //7275 #CJK UNIFIED IDEOGRAPH + {0xAD67, 0x74AF}, //7276 #CJK UNIFIED IDEOGRAPH + {0xAD68, 0x74B0}, //7277 #CJK UNIFIED IDEOGRAPH + {0xAD69, 0x74B1}, //7278 #CJK UNIFIED IDEOGRAPH + {0xAD6A, 0x74B2}, //7279 #CJK UNIFIED IDEOGRAPH + {0xAD6B, 0x74B3}, //7280 #CJK UNIFIED IDEOGRAPH + {0xAD6C, 0x74B4}, //7281 #CJK UNIFIED IDEOGRAPH + {0xAD6D, 0x74B5}, //7282 #CJK UNIFIED IDEOGRAPH + {0xAD6E, 0x74B6}, //7283 #CJK UNIFIED IDEOGRAPH + {0xAD6F, 0x74B7}, //7284 #CJK UNIFIED IDEOGRAPH + {0xAD70, 0x74B8}, //7285 #CJK UNIFIED IDEOGRAPH + {0xAD71, 0x74B9}, //7286 #CJK UNIFIED IDEOGRAPH + {0xAD72, 0x74BB}, //7287 #CJK UNIFIED IDEOGRAPH + {0xAD73, 0x74BC}, //7288 #CJK UNIFIED IDEOGRAPH + {0xAD74, 0x74BD}, //7289 #CJK UNIFIED IDEOGRAPH + {0xAD75, 0x74BE}, //7290 #CJK UNIFIED IDEOGRAPH + {0xAD76, 0x74BF}, //7291 #CJK UNIFIED IDEOGRAPH + {0xAD77, 0x74C0}, //7292 #CJK UNIFIED IDEOGRAPH + {0xAD78, 0x74C1}, //7293 #CJK UNIFIED IDEOGRAPH + {0xAD79, 0x74C2}, //7294 #CJK UNIFIED IDEOGRAPH + {0xAD7A, 0x74C3}, //7295 #CJK UNIFIED IDEOGRAPH + {0xAD7B, 0x74C4}, //7296 #CJK UNIFIED IDEOGRAPH + {0xAD7C, 0x74C5}, //7297 #CJK UNIFIED IDEOGRAPH + {0xAD7D, 0x74C6}, //7298 #CJK UNIFIED IDEOGRAPH + {0xAD7E, 0x74C7}, //7299 #CJK UNIFIED IDEOGRAPH + {0xAD80, 0x74C8}, //7300 #CJK UNIFIED IDEOGRAPH + {0xAD81, 0x74C9}, //7301 #CJK UNIFIED IDEOGRAPH + {0xAD82, 0x74CA}, //7302 #CJK UNIFIED IDEOGRAPH + {0xAD83, 0x74CB}, //7303 #CJK UNIFIED IDEOGRAPH + {0xAD84, 0x74CC}, //7304 #CJK UNIFIED IDEOGRAPH + {0xAD85, 0x74CD}, //7305 #CJK UNIFIED IDEOGRAPH + {0xAD86, 0x74CE}, //7306 #CJK UNIFIED IDEOGRAPH + {0xAD87, 0x74CF}, //7307 #CJK UNIFIED IDEOGRAPH + {0xAD88, 0x74D0}, //7308 #CJK UNIFIED IDEOGRAPH + {0xAD89, 0x74D1}, //7309 #CJK UNIFIED IDEOGRAPH + {0xAD8A, 0x74D3}, //7310 #CJK UNIFIED IDEOGRAPH + {0xAD8B, 0x74D4}, //7311 #CJK UNIFIED IDEOGRAPH + {0xAD8C, 0x74D5}, //7312 #CJK UNIFIED IDEOGRAPH + {0xAD8D, 0x74D6}, //7313 #CJK UNIFIED IDEOGRAPH + {0xAD8E, 0x74D7}, //7314 #CJK UNIFIED IDEOGRAPH + {0xAD8F, 0x74D8}, //7315 #CJK UNIFIED IDEOGRAPH + {0xAD90, 0x74D9}, //7316 #CJK UNIFIED IDEOGRAPH + {0xAD91, 0x74DA}, //7317 #CJK UNIFIED IDEOGRAPH + {0xAD92, 0x74DB}, //7318 #CJK UNIFIED IDEOGRAPH + {0xAD93, 0x74DD}, //7319 #CJK UNIFIED IDEOGRAPH + {0xAD94, 0x74DF}, //7320 #CJK UNIFIED IDEOGRAPH + {0xAD95, 0x74E1}, //7321 #CJK UNIFIED IDEOGRAPH + {0xAD96, 0x74E5}, //7322 #CJK UNIFIED IDEOGRAPH + {0xAD97, 0x74E7}, //7323 #CJK UNIFIED IDEOGRAPH + {0xAD98, 0x74E8}, //7324 #CJK UNIFIED IDEOGRAPH + {0xAD99, 0x74E9}, //7325 #CJK UNIFIED IDEOGRAPH + {0xAD9A, 0x74EA}, //7326 #CJK UNIFIED IDEOGRAPH + {0xAD9B, 0x74EB}, //7327 #CJK UNIFIED IDEOGRAPH + {0xAD9C, 0x74EC}, //7328 #CJK UNIFIED IDEOGRAPH + {0xAD9D, 0x74ED}, //7329 #CJK UNIFIED IDEOGRAPH + {0xAD9E, 0x74F0}, //7330 #CJK UNIFIED IDEOGRAPH + {0xAD9F, 0x74F1}, //7331 #CJK UNIFIED IDEOGRAPH + {0xADA0, 0x74F2}, //7332 #CJK UNIFIED IDEOGRAPH + {0xAE40, 0x74F3}, //7333 #CJK UNIFIED IDEOGRAPH + {0xAE41, 0x74F5}, //7334 #CJK UNIFIED IDEOGRAPH + {0xAE42, 0x74F8}, //7335 #CJK UNIFIED IDEOGRAPH + {0xAE43, 0x74F9}, //7336 #CJK UNIFIED IDEOGRAPH + {0xAE44, 0x74FA}, //7337 #CJK UNIFIED IDEOGRAPH + {0xAE45, 0x74FB}, //7338 #CJK UNIFIED IDEOGRAPH + {0xAE46, 0x74FC}, //7339 #CJK UNIFIED IDEOGRAPH + {0xAE47, 0x74FD}, //7340 #CJK UNIFIED IDEOGRAPH + {0xAE48, 0x74FE}, //7341 #CJK UNIFIED IDEOGRAPH + {0xAE49, 0x7500}, //7342 #CJK UNIFIED IDEOGRAPH + {0xAE4A, 0x7501}, //7343 #CJK UNIFIED IDEOGRAPH + {0xAE4B, 0x7502}, //7344 #CJK UNIFIED IDEOGRAPH + {0xAE4C, 0x7503}, //7345 #CJK UNIFIED IDEOGRAPH + {0xAE4D, 0x7505}, //7346 #CJK UNIFIED IDEOGRAPH + {0xAE4E, 0x7506}, //7347 #CJK UNIFIED IDEOGRAPH + {0xAE4F, 0x7507}, //7348 #CJK UNIFIED IDEOGRAPH + {0xAE50, 0x7508}, //7349 #CJK UNIFIED IDEOGRAPH + {0xAE51, 0x7509}, //7350 #CJK UNIFIED IDEOGRAPH + {0xAE52, 0x750A}, //7351 #CJK UNIFIED IDEOGRAPH + {0xAE53, 0x750B}, //7352 #CJK UNIFIED IDEOGRAPH + {0xAE54, 0x750C}, //7353 #CJK UNIFIED IDEOGRAPH + {0xAE55, 0x750E}, //7354 #CJK UNIFIED IDEOGRAPH + {0xAE56, 0x7510}, //7355 #CJK UNIFIED IDEOGRAPH + {0xAE57, 0x7512}, //7356 #CJK UNIFIED IDEOGRAPH + {0xAE58, 0x7514}, //7357 #CJK UNIFIED IDEOGRAPH + {0xAE59, 0x7515}, //7358 #CJK UNIFIED IDEOGRAPH + {0xAE5A, 0x7516}, //7359 #CJK UNIFIED IDEOGRAPH + {0xAE5B, 0x7517}, //7360 #CJK UNIFIED IDEOGRAPH + {0xAE5C, 0x751B}, //7361 #CJK UNIFIED IDEOGRAPH + {0xAE5D, 0x751D}, //7362 #CJK UNIFIED IDEOGRAPH + {0xAE5E, 0x751E}, //7363 #CJK UNIFIED IDEOGRAPH + {0xAE5F, 0x7520}, //7364 #CJK UNIFIED IDEOGRAPH + {0xAE60, 0x7521}, //7365 #CJK UNIFIED IDEOGRAPH + {0xAE61, 0x7522}, //7366 #CJK UNIFIED IDEOGRAPH + {0xAE62, 0x7523}, //7367 #CJK UNIFIED IDEOGRAPH + {0xAE63, 0x7524}, //7368 #CJK UNIFIED IDEOGRAPH + {0xAE64, 0x7526}, //7369 #CJK UNIFIED IDEOGRAPH + {0xAE65, 0x7527}, //7370 #CJK UNIFIED IDEOGRAPH + {0xAE66, 0x752A}, //7371 #CJK UNIFIED IDEOGRAPH + {0xAE67, 0x752E}, //7372 #CJK UNIFIED IDEOGRAPH + {0xAE68, 0x7534}, //7373 #CJK UNIFIED IDEOGRAPH + {0xAE69, 0x7536}, //7374 #CJK UNIFIED IDEOGRAPH + {0xAE6A, 0x7539}, //7375 #CJK UNIFIED IDEOGRAPH + {0xAE6B, 0x753C}, //7376 #CJK UNIFIED IDEOGRAPH + {0xAE6C, 0x753D}, //7377 #CJK UNIFIED IDEOGRAPH + {0xAE6D, 0x753F}, //7378 #CJK UNIFIED IDEOGRAPH + {0xAE6E, 0x7541}, //7379 #CJK UNIFIED IDEOGRAPH + {0xAE6F, 0x7542}, //7380 #CJK UNIFIED IDEOGRAPH + {0xAE70, 0x7543}, //7381 #CJK UNIFIED IDEOGRAPH + {0xAE71, 0x7544}, //7382 #CJK UNIFIED IDEOGRAPH + {0xAE72, 0x7546}, //7383 #CJK UNIFIED IDEOGRAPH + {0xAE73, 0x7547}, //7384 #CJK UNIFIED IDEOGRAPH + {0xAE74, 0x7549}, //7385 #CJK UNIFIED IDEOGRAPH + {0xAE75, 0x754A}, //7386 #CJK UNIFIED IDEOGRAPH + {0xAE76, 0x754D}, //7387 #CJK UNIFIED IDEOGRAPH + {0xAE77, 0x7550}, //7388 #CJK UNIFIED IDEOGRAPH + {0xAE78, 0x7551}, //7389 #CJK UNIFIED IDEOGRAPH + {0xAE79, 0x7552}, //7390 #CJK UNIFIED IDEOGRAPH + {0xAE7A, 0x7553}, //7391 #CJK UNIFIED IDEOGRAPH + {0xAE7B, 0x7555}, //7392 #CJK UNIFIED IDEOGRAPH + {0xAE7C, 0x7556}, //7393 #CJK UNIFIED IDEOGRAPH + {0xAE7D, 0x7557}, //7394 #CJK UNIFIED IDEOGRAPH + {0xAE7E, 0x7558}, //7395 #CJK UNIFIED IDEOGRAPH + {0xAE80, 0x755D}, //7396 #CJK UNIFIED IDEOGRAPH + {0xAE81, 0x755E}, //7397 #CJK UNIFIED IDEOGRAPH + {0xAE82, 0x755F}, //7398 #CJK UNIFIED IDEOGRAPH + {0xAE83, 0x7560}, //7399 #CJK UNIFIED IDEOGRAPH + {0xAE84, 0x7561}, //7400 #CJK UNIFIED IDEOGRAPH + {0xAE85, 0x7562}, //7401 #CJK UNIFIED IDEOGRAPH + {0xAE86, 0x7563}, //7402 #CJK UNIFIED IDEOGRAPH + {0xAE87, 0x7564}, //7403 #CJK UNIFIED IDEOGRAPH + {0xAE88, 0x7567}, //7404 #CJK UNIFIED IDEOGRAPH + {0xAE89, 0x7568}, //7405 #CJK UNIFIED IDEOGRAPH + {0xAE8A, 0x7569}, //7406 #CJK UNIFIED IDEOGRAPH + {0xAE8B, 0x756B}, //7407 #CJK UNIFIED IDEOGRAPH + {0xAE8C, 0x756C}, //7408 #CJK UNIFIED IDEOGRAPH + {0xAE8D, 0x756D}, //7409 #CJK UNIFIED IDEOGRAPH + {0xAE8E, 0x756E}, //7410 #CJK UNIFIED IDEOGRAPH + {0xAE8F, 0x756F}, //7411 #CJK UNIFIED IDEOGRAPH + {0xAE90, 0x7570}, //7412 #CJK UNIFIED IDEOGRAPH + {0xAE91, 0x7571}, //7413 #CJK UNIFIED IDEOGRAPH + {0xAE92, 0x7573}, //7414 #CJK UNIFIED IDEOGRAPH + {0xAE93, 0x7575}, //7415 #CJK UNIFIED IDEOGRAPH + {0xAE94, 0x7576}, //7416 #CJK UNIFIED IDEOGRAPH + {0xAE95, 0x7577}, //7417 #CJK UNIFIED IDEOGRAPH + {0xAE96, 0x757A}, //7418 #CJK UNIFIED IDEOGRAPH + {0xAE97, 0x757B}, //7419 #CJK UNIFIED IDEOGRAPH + {0xAE98, 0x757C}, //7420 #CJK UNIFIED IDEOGRAPH + {0xAE99, 0x757D}, //7421 #CJK UNIFIED IDEOGRAPH + {0xAE9A, 0x757E}, //7422 #CJK UNIFIED IDEOGRAPH + {0xAE9B, 0x7580}, //7423 #CJK UNIFIED IDEOGRAPH + {0xAE9C, 0x7581}, //7424 #CJK UNIFIED IDEOGRAPH + {0xAE9D, 0x7582}, //7425 #CJK UNIFIED IDEOGRAPH + {0xAE9E, 0x7584}, //7426 #CJK UNIFIED IDEOGRAPH + {0xAE9F, 0x7585}, //7427 #CJK UNIFIED IDEOGRAPH + {0xAEA0, 0x7587}, //7428 #CJK UNIFIED IDEOGRAPH + {0xAF40, 0x7588}, //7429 #CJK UNIFIED IDEOGRAPH + {0xAF41, 0x7589}, //7430 #CJK UNIFIED IDEOGRAPH + {0xAF42, 0x758A}, //7431 #CJK UNIFIED IDEOGRAPH + {0xAF43, 0x758C}, //7432 #CJK UNIFIED IDEOGRAPH + {0xAF44, 0x758D}, //7433 #CJK UNIFIED IDEOGRAPH + {0xAF45, 0x758E}, //7434 #CJK UNIFIED IDEOGRAPH + {0xAF46, 0x7590}, //7435 #CJK UNIFIED IDEOGRAPH + {0xAF47, 0x7593}, //7436 #CJK UNIFIED IDEOGRAPH + {0xAF48, 0x7595}, //7437 #CJK UNIFIED IDEOGRAPH + {0xAF49, 0x7598}, //7438 #CJK UNIFIED IDEOGRAPH + {0xAF4A, 0x759B}, //7439 #CJK UNIFIED IDEOGRAPH + {0xAF4B, 0x759C}, //7440 #CJK UNIFIED IDEOGRAPH + {0xAF4C, 0x759E}, //7441 #CJK UNIFIED IDEOGRAPH + {0xAF4D, 0x75A2}, //7442 #CJK UNIFIED IDEOGRAPH + {0xAF4E, 0x75A6}, //7443 #CJK UNIFIED IDEOGRAPH + {0xAF4F, 0x75A7}, //7444 #CJK UNIFIED IDEOGRAPH + {0xAF50, 0x75A8}, //7445 #CJK UNIFIED IDEOGRAPH + {0xAF51, 0x75A9}, //7446 #CJK UNIFIED IDEOGRAPH + {0xAF52, 0x75AA}, //7447 #CJK UNIFIED IDEOGRAPH + {0xAF53, 0x75AD}, //7448 #CJK UNIFIED IDEOGRAPH + {0xAF54, 0x75B6}, //7449 #CJK UNIFIED IDEOGRAPH + {0xAF55, 0x75B7}, //7450 #CJK UNIFIED IDEOGRAPH + {0xAF56, 0x75BA}, //7451 #CJK UNIFIED IDEOGRAPH + {0xAF57, 0x75BB}, //7452 #CJK UNIFIED IDEOGRAPH + {0xAF58, 0x75BF}, //7453 #CJK UNIFIED IDEOGRAPH + {0xAF59, 0x75C0}, //7454 #CJK UNIFIED IDEOGRAPH + {0xAF5A, 0x75C1}, //7455 #CJK UNIFIED IDEOGRAPH + {0xAF5B, 0x75C6}, //7456 #CJK UNIFIED IDEOGRAPH + {0xAF5C, 0x75CB}, //7457 #CJK UNIFIED IDEOGRAPH + {0xAF5D, 0x75CC}, //7458 #CJK UNIFIED IDEOGRAPH + {0xAF5E, 0x75CE}, //7459 #CJK UNIFIED IDEOGRAPH + {0xAF5F, 0x75CF}, //7460 #CJK UNIFIED IDEOGRAPH + {0xAF60, 0x75D0}, //7461 #CJK UNIFIED IDEOGRAPH + {0xAF61, 0x75D1}, //7462 #CJK UNIFIED IDEOGRAPH + {0xAF62, 0x75D3}, //7463 #CJK UNIFIED IDEOGRAPH + {0xAF63, 0x75D7}, //7464 #CJK UNIFIED IDEOGRAPH + {0xAF64, 0x75D9}, //7465 #CJK UNIFIED IDEOGRAPH + {0xAF65, 0x75DA}, //7466 #CJK UNIFIED IDEOGRAPH + {0xAF66, 0x75DC}, //7467 #CJK UNIFIED IDEOGRAPH + {0xAF67, 0x75DD}, //7468 #CJK UNIFIED IDEOGRAPH + {0xAF68, 0x75DF}, //7469 #CJK UNIFIED IDEOGRAPH + {0xAF69, 0x75E0}, //7470 #CJK UNIFIED IDEOGRAPH + {0xAF6A, 0x75E1}, //7471 #CJK UNIFIED IDEOGRAPH + {0xAF6B, 0x75E5}, //7472 #CJK UNIFIED IDEOGRAPH + {0xAF6C, 0x75E9}, //7473 #CJK UNIFIED IDEOGRAPH + {0xAF6D, 0x75EC}, //7474 #CJK UNIFIED IDEOGRAPH + {0xAF6E, 0x75ED}, //7475 #CJK UNIFIED IDEOGRAPH + {0xAF6F, 0x75EE}, //7476 #CJK UNIFIED IDEOGRAPH + {0xAF70, 0x75EF}, //7477 #CJK UNIFIED IDEOGRAPH + {0xAF71, 0x75F2}, //7478 #CJK UNIFIED IDEOGRAPH + {0xAF72, 0x75F3}, //7479 #CJK UNIFIED IDEOGRAPH + {0xAF73, 0x75F5}, //7480 #CJK UNIFIED IDEOGRAPH + {0xAF74, 0x75F6}, //7481 #CJK UNIFIED IDEOGRAPH + {0xAF75, 0x75F7}, //7482 #CJK UNIFIED IDEOGRAPH + {0xAF76, 0x75F8}, //7483 #CJK UNIFIED IDEOGRAPH + {0xAF77, 0x75FA}, //7484 #CJK UNIFIED IDEOGRAPH + {0xAF78, 0x75FB}, //7485 #CJK UNIFIED IDEOGRAPH + {0xAF79, 0x75FD}, //7486 #CJK UNIFIED IDEOGRAPH + {0xAF7A, 0x75FE}, //7487 #CJK UNIFIED IDEOGRAPH + {0xAF7B, 0x7602}, //7488 #CJK UNIFIED IDEOGRAPH + {0xAF7C, 0x7604}, //7489 #CJK UNIFIED IDEOGRAPH + {0xAF7D, 0x7606}, //7490 #CJK UNIFIED IDEOGRAPH + {0xAF7E, 0x7607}, //7491 #CJK UNIFIED IDEOGRAPH + {0xAF80, 0x7608}, //7492 #CJK UNIFIED IDEOGRAPH + {0xAF81, 0x7609}, //7493 #CJK UNIFIED IDEOGRAPH + {0xAF82, 0x760B}, //7494 #CJK UNIFIED IDEOGRAPH + {0xAF83, 0x760D}, //7495 #CJK UNIFIED IDEOGRAPH + {0xAF84, 0x760E}, //7496 #CJK UNIFIED IDEOGRAPH + {0xAF85, 0x760F}, //7497 #CJK UNIFIED IDEOGRAPH + {0xAF86, 0x7611}, //7498 #CJK UNIFIED IDEOGRAPH + {0xAF87, 0x7612}, //7499 #CJK UNIFIED IDEOGRAPH + {0xAF88, 0x7613}, //7500 #CJK UNIFIED IDEOGRAPH + {0xAF89, 0x7614}, //7501 #CJK UNIFIED IDEOGRAPH + {0xAF8A, 0x7616}, //7502 #CJK UNIFIED IDEOGRAPH + {0xAF8B, 0x761A}, //7503 #CJK UNIFIED IDEOGRAPH + {0xAF8C, 0x761C}, //7504 #CJK UNIFIED IDEOGRAPH + {0xAF8D, 0x761D}, //7505 #CJK UNIFIED IDEOGRAPH + {0xAF8E, 0x761E}, //7506 #CJK UNIFIED IDEOGRAPH + {0xAF8F, 0x7621}, //7507 #CJK UNIFIED IDEOGRAPH + {0xAF90, 0x7623}, //7508 #CJK UNIFIED IDEOGRAPH + {0xAF91, 0x7627}, //7509 #CJK UNIFIED IDEOGRAPH + {0xAF92, 0x7628}, //7510 #CJK UNIFIED IDEOGRAPH + {0xAF93, 0x762C}, //7511 #CJK UNIFIED IDEOGRAPH + {0xAF94, 0x762E}, //7512 #CJK UNIFIED IDEOGRAPH + {0xAF95, 0x762F}, //7513 #CJK UNIFIED IDEOGRAPH + {0xAF96, 0x7631}, //7514 #CJK UNIFIED IDEOGRAPH + {0xAF97, 0x7632}, //7515 #CJK UNIFIED IDEOGRAPH + {0xAF98, 0x7636}, //7516 #CJK UNIFIED IDEOGRAPH + {0xAF99, 0x7637}, //7517 #CJK UNIFIED IDEOGRAPH + {0xAF9A, 0x7639}, //7518 #CJK UNIFIED IDEOGRAPH + {0xAF9B, 0x763A}, //7519 #CJK UNIFIED IDEOGRAPH + {0xAF9C, 0x763B}, //7520 #CJK UNIFIED IDEOGRAPH + {0xAF9D, 0x763D}, //7521 #CJK UNIFIED IDEOGRAPH + {0xAF9E, 0x7641}, //7522 #CJK UNIFIED IDEOGRAPH + {0xAF9F, 0x7642}, //7523 #CJK UNIFIED IDEOGRAPH + {0xAFA0, 0x7644}, //7524 #CJK UNIFIED IDEOGRAPH + {0xB040, 0x7645}, //7525 #CJK UNIFIED IDEOGRAPH + {0xB041, 0x7646}, //7526 #CJK UNIFIED IDEOGRAPH + {0xB042, 0x7647}, //7527 #CJK UNIFIED IDEOGRAPH + {0xB043, 0x7648}, //7528 #CJK UNIFIED IDEOGRAPH + {0xB044, 0x7649}, //7529 #CJK UNIFIED IDEOGRAPH + {0xB045, 0x764A}, //7530 #CJK UNIFIED IDEOGRAPH + {0xB046, 0x764B}, //7531 #CJK UNIFIED IDEOGRAPH + {0xB047, 0x764E}, //7532 #CJK UNIFIED IDEOGRAPH + {0xB048, 0x764F}, //7533 #CJK UNIFIED IDEOGRAPH + {0xB049, 0x7650}, //7534 #CJK UNIFIED IDEOGRAPH + {0xB04A, 0x7651}, //7535 #CJK UNIFIED IDEOGRAPH + {0xB04B, 0x7652}, //7536 #CJK UNIFIED IDEOGRAPH + {0xB04C, 0x7653}, //7537 #CJK UNIFIED IDEOGRAPH + {0xB04D, 0x7655}, //7538 #CJK UNIFIED IDEOGRAPH + {0xB04E, 0x7657}, //7539 #CJK UNIFIED IDEOGRAPH + {0xB04F, 0x7658}, //7540 #CJK UNIFIED IDEOGRAPH + {0xB050, 0x7659}, //7541 #CJK UNIFIED IDEOGRAPH + {0xB051, 0x765A}, //7542 #CJK UNIFIED IDEOGRAPH + {0xB052, 0x765B}, //7543 #CJK UNIFIED IDEOGRAPH + {0xB053, 0x765D}, //7544 #CJK UNIFIED IDEOGRAPH + {0xB054, 0x765F}, //7545 #CJK UNIFIED IDEOGRAPH + {0xB055, 0x7660}, //7546 #CJK UNIFIED IDEOGRAPH + {0xB056, 0x7661}, //7547 #CJK UNIFIED IDEOGRAPH + {0xB057, 0x7662}, //7548 #CJK UNIFIED IDEOGRAPH + {0xB058, 0x7664}, //7549 #CJK UNIFIED IDEOGRAPH + {0xB059, 0x7665}, //7550 #CJK UNIFIED IDEOGRAPH + {0xB05A, 0x7666}, //7551 #CJK UNIFIED IDEOGRAPH + {0xB05B, 0x7667}, //7552 #CJK UNIFIED IDEOGRAPH + {0xB05C, 0x7668}, //7553 #CJK UNIFIED IDEOGRAPH + {0xB05D, 0x7669}, //7554 #CJK UNIFIED IDEOGRAPH + {0xB05E, 0x766A}, //7555 #CJK UNIFIED IDEOGRAPH + {0xB05F, 0x766C}, //7556 #CJK UNIFIED IDEOGRAPH + {0xB060, 0x766D}, //7557 #CJK UNIFIED IDEOGRAPH + {0xB061, 0x766E}, //7558 #CJK UNIFIED IDEOGRAPH + {0xB062, 0x7670}, //7559 #CJK UNIFIED IDEOGRAPH + {0xB063, 0x7671}, //7560 #CJK UNIFIED IDEOGRAPH + {0xB064, 0x7672}, //7561 #CJK UNIFIED IDEOGRAPH + {0xB065, 0x7673}, //7562 #CJK UNIFIED IDEOGRAPH + {0xB066, 0x7674}, //7563 #CJK UNIFIED IDEOGRAPH + {0xB067, 0x7675}, //7564 #CJK UNIFIED IDEOGRAPH + {0xB068, 0x7676}, //7565 #CJK UNIFIED IDEOGRAPH + {0xB069, 0x7677}, //7566 #CJK UNIFIED IDEOGRAPH + {0xB06A, 0x7679}, //7567 #CJK UNIFIED IDEOGRAPH + {0xB06B, 0x767A}, //7568 #CJK UNIFIED IDEOGRAPH + {0xB06C, 0x767C}, //7569 #CJK UNIFIED IDEOGRAPH + {0xB06D, 0x767F}, //7570 #CJK UNIFIED IDEOGRAPH + {0xB06E, 0x7680}, //7571 #CJK UNIFIED IDEOGRAPH + {0xB06F, 0x7681}, //7572 #CJK UNIFIED IDEOGRAPH + {0xB070, 0x7683}, //7573 #CJK UNIFIED IDEOGRAPH + {0xB071, 0x7685}, //7574 #CJK UNIFIED IDEOGRAPH + {0xB072, 0x7689}, //7575 #CJK UNIFIED IDEOGRAPH + {0xB073, 0x768A}, //7576 #CJK UNIFIED IDEOGRAPH + {0xB074, 0x768C}, //7577 #CJK UNIFIED IDEOGRAPH + {0xB075, 0x768D}, //7578 #CJK UNIFIED IDEOGRAPH + {0xB076, 0x768F}, //7579 #CJK UNIFIED IDEOGRAPH + {0xB077, 0x7690}, //7580 #CJK UNIFIED IDEOGRAPH + {0xB078, 0x7692}, //7581 #CJK UNIFIED IDEOGRAPH + {0xB079, 0x7694}, //7582 #CJK UNIFIED IDEOGRAPH + {0xB07A, 0x7695}, //7583 #CJK UNIFIED IDEOGRAPH + {0xB07B, 0x7697}, //7584 #CJK UNIFIED IDEOGRAPH + {0xB07C, 0x7698}, //7585 #CJK UNIFIED IDEOGRAPH + {0xB07D, 0x769A}, //7586 #CJK UNIFIED IDEOGRAPH + {0xB07E, 0x769B}, //7587 #CJK UNIFIED IDEOGRAPH + {0xB080, 0x769C}, //7588 #CJK UNIFIED IDEOGRAPH + {0xB081, 0x769D}, //7589 #CJK UNIFIED IDEOGRAPH + {0xB082, 0x769E}, //7590 #CJK UNIFIED IDEOGRAPH + {0xB083, 0x769F}, //7591 #CJK UNIFIED IDEOGRAPH + {0xB084, 0x76A0}, //7592 #CJK UNIFIED IDEOGRAPH + {0xB085, 0x76A1}, //7593 #CJK UNIFIED IDEOGRAPH + {0xB086, 0x76A2}, //7594 #CJK UNIFIED IDEOGRAPH + {0xB087, 0x76A3}, //7595 #CJK UNIFIED IDEOGRAPH + {0xB088, 0x76A5}, //7596 #CJK UNIFIED IDEOGRAPH + {0xB089, 0x76A6}, //7597 #CJK UNIFIED IDEOGRAPH + {0xB08A, 0x76A7}, //7598 #CJK UNIFIED IDEOGRAPH + {0xB08B, 0x76A8}, //7599 #CJK UNIFIED IDEOGRAPH + {0xB08C, 0x76A9}, //7600 #CJK UNIFIED IDEOGRAPH + {0xB08D, 0x76AA}, //7601 #CJK UNIFIED IDEOGRAPH + {0xB08E, 0x76AB}, //7602 #CJK UNIFIED IDEOGRAPH + {0xB08F, 0x76AC}, //7603 #CJK UNIFIED IDEOGRAPH + {0xB090, 0x76AD}, //7604 #CJK UNIFIED IDEOGRAPH + {0xB091, 0x76AF}, //7605 #CJK UNIFIED IDEOGRAPH + {0xB092, 0x76B0}, //7606 #CJK UNIFIED IDEOGRAPH + {0xB093, 0x76B3}, //7607 #CJK UNIFIED IDEOGRAPH + {0xB094, 0x76B5}, //7608 #CJK UNIFIED IDEOGRAPH + {0xB095, 0x76B6}, //7609 #CJK UNIFIED IDEOGRAPH + {0xB096, 0x76B7}, //7610 #CJK UNIFIED IDEOGRAPH + {0xB097, 0x76B8}, //7611 #CJK UNIFIED IDEOGRAPH + {0xB098, 0x76B9}, //7612 #CJK UNIFIED IDEOGRAPH + {0xB099, 0x76BA}, //7613 #CJK UNIFIED IDEOGRAPH + {0xB09A, 0x76BB}, //7614 #CJK UNIFIED IDEOGRAPH + {0xB09B, 0x76BC}, //7615 #CJK UNIFIED IDEOGRAPH + {0xB09C, 0x76BD}, //7616 #CJK UNIFIED IDEOGRAPH + {0xB09D, 0x76BE}, //7617 #CJK UNIFIED IDEOGRAPH + {0xB09E, 0x76C0}, //7618 #CJK UNIFIED IDEOGRAPH + {0xB09F, 0x76C1}, //7619 #CJK UNIFIED IDEOGRAPH + {0xB0A0, 0x76C3}, //7620 #CJK UNIFIED IDEOGRAPH + {0xB0A1, 0x554A}, //7621 #CJK UNIFIED IDEOGRAPH + {0xB0A2, 0x963F}, //7622 #CJK UNIFIED IDEOGRAPH + {0xB0A3, 0x57C3}, //7623 #CJK UNIFIED IDEOGRAPH + {0xB0A4, 0x6328}, //7624 #CJK UNIFIED IDEOGRAPH + {0xB0A5, 0x54CE}, //7625 #CJK UNIFIED IDEOGRAPH + {0xB0A6, 0x5509}, //7626 #CJK UNIFIED IDEOGRAPH + {0xB0A7, 0x54C0}, //7627 #CJK UNIFIED IDEOGRAPH + {0xB0A8, 0x7691}, //7628 #CJK UNIFIED IDEOGRAPH + {0xB0A9, 0x764C}, //7629 #CJK UNIFIED IDEOGRAPH + {0xB0AA, 0x853C}, //7630 #CJK UNIFIED IDEOGRAPH + {0xB0AB, 0x77EE}, //7631 #CJK UNIFIED IDEOGRAPH + {0xB0AC, 0x827E}, //7632 #CJK UNIFIED IDEOGRAPH + {0xB0AD, 0x788D}, //7633 #CJK UNIFIED IDEOGRAPH + {0xB0AE, 0x7231}, //7634 #CJK UNIFIED IDEOGRAPH + {0xB0AF, 0x9698}, //7635 #CJK UNIFIED IDEOGRAPH + {0xB0B0, 0x978D}, //7636 #CJK UNIFIED IDEOGRAPH + {0xB0B1, 0x6C28}, //7637 #CJK UNIFIED IDEOGRAPH + {0xB0B2, 0x5B89}, //7638 #CJK UNIFIED IDEOGRAPH + {0xB0B3, 0x4FFA}, //7639 #CJK UNIFIED IDEOGRAPH + {0xB0B4, 0x6309}, //7640 #CJK UNIFIED IDEOGRAPH + {0xB0B5, 0x6697}, //7641 #CJK UNIFIED IDEOGRAPH + {0xB0B6, 0x5CB8}, //7642 #CJK UNIFIED IDEOGRAPH + {0xB0B7, 0x80FA}, //7643 #CJK UNIFIED IDEOGRAPH + {0xB0B8, 0x6848}, //7644 #CJK UNIFIED IDEOGRAPH + {0xB0B9, 0x80AE}, //7645 #CJK UNIFIED IDEOGRAPH + {0xB0BA, 0x6602}, //7646 #CJK UNIFIED IDEOGRAPH + {0xB0BB, 0x76CE}, //7647 #CJK UNIFIED IDEOGRAPH + {0xB0BC, 0x51F9}, //7648 #CJK UNIFIED IDEOGRAPH + {0xB0BD, 0x6556}, //7649 #CJK UNIFIED IDEOGRAPH + {0xB0BE, 0x71AC}, //7650 #CJK UNIFIED IDEOGRAPH + {0xB0BF, 0x7FF1}, //7651 #CJK UNIFIED IDEOGRAPH + {0xB0C0, 0x8884}, //7652 #CJK UNIFIED IDEOGRAPH + {0xB0C1, 0x50B2}, //7653 #CJK UNIFIED IDEOGRAPH + {0xB0C2, 0x5965}, //7654 #CJK UNIFIED IDEOGRAPH + {0xB0C3, 0x61CA}, //7655 #CJK UNIFIED IDEOGRAPH + {0xB0C4, 0x6FB3}, //7656 #CJK UNIFIED IDEOGRAPH + {0xB0C5, 0x82AD}, //7657 #CJK UNIFIED IDEOGRAPH + {0xB0C6, 0x634C}, //7658 #CJK UNIFIED IDEOGRAPH + {0xB0C7, 0x6252}, //7659 #CJK UNIFIED IDEOGRAPH + {0xB0C8, 0x53ED}, //7660 #CJK UNIFIED IDEOGRAPH + {0xB0C9, 0x5427}, //7661 #CJK UNIFIED IDEOGRAPH + {0xB0CA, 0x7B06}, //7662 #CJK UNIFIED IDEOGRAPH + {0xB0CB, 0x516B}, //7663 #CJK UNIFIED IDEOGRAPH + {0xB0CC, 0x75A4}, //7664 #CJK UNIFIED IDEOGRAPH + {0xB0CD, 0x5DF4}, //7665 #CJK UNIFIED IDEOGRAPH + {0xB0CE, 0x62D4}, //7666 #CJK UNIFIED IDEOGRAPH + {0xB0CF, 0x8DCB}, //7667 #CJK UNIFIED IDEOGRAPH + {0xB0D0, 0x9776}, //7668 #CJK UNIFIED IDEOGRAPH + {0xB0D1, 0x628A}, //7669 #CJK UNIFIED IDEOGRAPH + {0xB0D2, 0x8019}, //7670 #CJK UNIFIED IDEOGRAPH + {0xB0D3, 0x575D}, //7671 #CJK UNIFIED IDEOGRAPH + {0xB0D4, 0x9738}, //7672 #CJK UNIFIED IDEOGRAPH + {0xB0D5, 0x7F62}, //7673 #CJK UNIFIED IDEOGRAPH + {0xB0D6, 0x7238}, //7674 #CJK UNIFIED IDEOGRAPH + {0xB0D7, 0x767D}, //7675 #CJK UNIFIED IDEOGRAPH + {0xB0D8, 0x67CF}, //7676 #CJK UNIFIED IDEOGRAPH + {0xB0D9, 0x767E}, //7677 #CJK UNIFIED IDEOGRAPH + {0xB0DA, 0x6446}, //7678 #CJK UNIFIED IDEOGRAPH + {0xB0DB, 0x4F70}, //7679 #CJK UNIFIED IDEOGRAPH + {0xB0DC, 0x8D25}, //7680 #CJK UNIFIED IDEOGRAPH + {0xB0DD, 0x62DC}, //7681 #CJK UNIFIED IDEOGRAPH + {0xB0DE, 0x7A17}, //7682 #CJK UNIFIED IDEOGRAPH + {0xB0DF, 0x6591}, //7683 #CJK UNIFIED IDEOGRAPH + {0xB0E0, 0x73ED}, //7684 #CJK UNIFIED IDEOGRAPH + {0xB0E1, 0x642C}, //7685 #CJK UNIFIED IDEOGRAPH + {0xB0E2, 0x6273}, //7686 #CJK UNIFIED IDEOGRAPH + {0xB0E3, 0x822C}, //7687 #CJK UNIFIED IDEOGRAPH + {0xB0E4, 0x9881}, //7688 #CJK UNIFIED IDEOGRAPH + {0xB0E5, 0x677F}, //7689 #CJK UNIFIED IDEOGRAPH + {0xB0E6, 0x7248}, //7690 #CJK UNIFIED IDEOGRAPH + {0xB0E7, 0x626E}, //7691 #CJK UNIFIED IDEOGRAPH + {0xB0E8, 0x62CC}, //7692 #CJK UNIFIED IDEOGRAPH + {0xB0E9, 0x4F34}, //7693 #CJK UNIFIED IDEOGRAPH + {0xB0EA, 0x74E3}, //7694 #CJK UNIFIED IDEOGRAPH + {0xB0EB, 0x534A}, //7695 #CJK UNIFIED IDEOGRAPH + {0xB0EC, 0x529E}, //7696 #CJK UNIFIED IDEOGRAPH + {0xB0ED, 0x7ECA}, //7697 #CJK UNIFIED IDEOGRAPH + {0xB0EE, 0x90A6}, //7698 #CJK UNIFIED IDEOGRAPH + {0xB0EF, 0x5E2E}, //7699 #CJK UNIFIED IDEOGRAPH + {0xB0F0, 0x6886}, //7700 #CJK UNIFIED IDEOGRAPH + {0xB0F1, 0x699C}, //7701 #CJK UNIFIED IDEOGRAPH + {0xB0F2, 0x8180}, //7702 #CJK UNIFIED IDEOGRAPH + {0xB0F3, 0x7ED1}, //7703 #CJK UNIFIED IDEOGRAPH + {0xB0F4, 0x68D2}, //7704 #CJK UNIFIED IDEOGRAPH + {0xB0F5, 0x78C5}, //7705 #CJK UNIFIED IDEOGRAPH + {0xB0F6, 0x868C}, //7706 #CJK UNIFIED IDEOGRAPH + {0xB0F7, 0x9551}, //7707 #CJK UNIFIED IDEOGRAPH + {0xB0F8, 0x508D}, //7708 #CJK UNIFIED IDEOGRAPH + {0xB0F9, 0x8C24}, //7709 #CJK UNIFIED IDEOGRAPH + {0xB0FA, 0x82DE}, //7710 #CJK UNIFIED IDEOGRAPH + {0xB0FB, 0x80DE}, //7711 #CJK UNIFIED IDEOGRAPH + {0xB0FC, 0x5305}, //7712 #CJK UNIFIED IDEOGRAPH + {0xB0FD, 0x8912}, //7713 #CJK UNIFIED IDEOGRAPH + {0xB0FE, 0x5265}, //7714 #CJK UNIFIED IDEOGRAPH + {0xB140, 0x76C4}, //7715 #CJK UNIFIED IDEOGRAPH + {0xB141, 0x76C7}, //7716 #CJK UNIFIED IDEOGRAPH + {0xB142, 0x76C9}, //7717 #CJK UNIFIED IDEOGRAPH + {0xB143, 0x76CB}, //7718 #CJK UNIFIED IDEOGRAPH + {0xB144, 0x76CC}, //7719 #CJK UNIFIED IDEOGRAPH + {0xB145, 0x76D3}, //7720 #CJK UNIFIED IDEOGRAPH + {0xB146, 0x76D5}, //7721 #CJK UNIFIED IDEOGRAPH + {0xB147, 0x76D9}, //7722 #CJK UNIFIED IDEOGRAPH + {0xB148, 0x76DA}, //7723 #CJK UNIFIED IDEOGRAPH + {0xB149, 0x76DC}, //7724 #CJK UNIFIED IDEOGRAPH + {0xB14A, 0x76DD}, //7725 #CJK UNIFIED IDEOGRAPH + {0xB14B, 0x76DE}, //7726 #CJK UNIFIED IDEOGRAPH + {0xB14C, 0x76E0}, //7727 #CJK UNIFIED IDEOGRAPH + {0xB14D, 0x76E1}, //7728 #CJK UNIFIED IDEOGRAPH + {0xB14E, 0x76E2}, //7729 #CJK UNIFIED IDEOGRAPH + {0xB14F, 0x76E3}, //7730 #CJK UNIFIED IDEOGRAPH + {0xB150, 0x76E4}, //7731 #CJK UNIFIED IDEOGRAPH + {0xB151, 0x76E6}, //7732 #CJK UNIFIED IDEOGRAPH + {0xB152, 0x76E7}, //7733 #CJK UNIFIED IDEOGRAPH + {0xB153, 0x76E8}, //7734 #CJK UNIFIED IDEOGRAPH + {0xB154, 0x76E9}, //7735 #CJK UNIFIED IDEOGRAPH + {0xB155, 0x76EA}, //7736 #CJK UNIFIED IDEOGRAPH + {0xB156, 0x76EB}, //7737 #CJK UNIFIED IDEOGRAPH + {0xB157, 0x76EC}, //7738 #CJK UNIFIED IDEOGRAPH + {0xB158, 0x76ED}, //7739 #CJK UNIFIED IDEOGRAPH + {0xB159, 0x76F0}, //7740 #CJK UNIFIED IDEOGRAPH + {0xB15A, 0x76F3}, //7741 #CJK UNIFIED IDEOGRAPH + {0xB15B, 0x76F5}, //7742 #CJK UNIFIED IDEOGRAPH + {0xB15C, 0x76F6}, //7743 #CJK UNIFIED IDEOGRAPH + {0xB15D, 0x76F7}, //7744 #CJK UNIFIED IDEOGRAPH + {0xB15E, 0x76FA}, //7745 #CJK UNIFIED IDEOGRAPH + {0xB15F, 0x76FB}, //7746 #CJK UNIFIED IDEOGRAPH + {0xB160, 0x76FD}, //7747 #CJK UNIFIED IDEOGRAPH + {0xB161, 0x76FF}, //7748 #CJK UNIFIED IDEOGRAPH + {0xB162, 0x7700}, //7749 #CJK UNIFIED IDEOGRAPH + {0xB163, 0x7702}, //7750 #CJK UNIFIED IDEOGRAPH + {0xB164, 0x7703}, //7751 #CJK UNIFIED IDEOGRAPH + {0xB165, 0x7705}, //7752 #CJK UNIFIED IDEOGRAPH + {0xB166, 0x7706}, //7753 #CJK UNIFIED IDEOGRAPH + {0xB167, 0x770A}, //7754 #CJK UNIFIED IDEOGRAPH + {0xB168, 0x770C}, //7755 #CJK UNIFIED IDEOGRAPH + {0xB169, 0x770E}, //7756 #CJK UNIFIED IDEOGRAPH + {0xB16A, 0x770F}, //7757 #CJK UNIFIED IDEOGRAPH + {0xB16B, 0x7710}, //7758 #CJK UNIFIED IDEOGRAPH + {0xB16C, 0x7711}, //7759 #CJK UNIFIED IDEOGRAPH + {0xB16D, 0x7712}, //7760 #CJK UNIFIED IDEOGRAPH + {0xB16E, 0x7713}, //7761 #CJK UNIFIED IDEOGRAPH + {0xB16F, 0x7714}, //7762 #CJK UNIFIED IDEOGRAPH + {0xB170, 0x7715}, //7763 #CJK UNIFIED IDEOGRAPH + {0xB171, 0x7716}, //7764 #CJK UNIFIED IDEOGRAPH + {0xB172, 0x7717}, //7765 #CJK UNIFIED IDEOGRAPH + {0xB173, 0x7718}, //7766 #CJK UNIFIED IDEOGRAPH + {0xB174, 0x771B}, //7767 #CJK UNIFIED IDEOGRAPH + {0xB175, 0x771C}, //7768 #CJK UNIFIED IDEOGRAPH + {0xB176, 0x771D}, //7769 #CJK UNIFIED IDEOGRAPH + {0xB177, 0x771E}, //7770 #CJK UNIFIED IDEOGRAPH + {0xB178, 0x7721}, //7771 #CJK UNIFIED IDEOGRAPH + {0xB179, 0x7723}, //7772 #CJK UNIFIED IDEOGRAPH + {0xB17A, 0x7724}, //7773 #CJK UNIFIED IDEOGRAPH + {0xB17B, 0x7725}, //7774 #CJK UNIFIED IDEOGRAPH + {0xB17C, 0x7727}, //7775 #CJK UNIFIED IDEOGRAPH + {0xB17D, 0x772A}, //7776 #CJK UNIFIED IDEOGRAPH + {0xB17E, 0x772B}, //7777 #CJK UNIFIED IDEOGRAPH + {0xB180, 0x772C}, //7778 #CJK UNIFIED IDEOGRAPH + {0xB181, 0x772E}, //7779 #CJK UNIFIED IDEOGRAPH + {0xB182, 0x7730}, //7780 #CJK UNIFIED IDEOGRAPH + {0xB183, 0x7731}, //7781 #CJK UNIFIED IDEOGRAPH + {0xB184, 0x7732}, //7782 #CJK UNIFIED IDEOGRAPH + {0xB185, 0x7733}, //7783 #CJK UNIFIED IDEOGRAPH + {0xB186, 0x7734}, //7784 #CJK UNIFIED IDEOGRAPH + {0xB187, 0x7739}, //7785 #CJK UNIFIED IDEOGRAPH + {0xB188, 0x773B}, //7786 #CJK UNIFIED IDEOGRAPH + {0xB189, 0x773D}, //7787 #CJK UNIFIED IDEOGRAPH + {0xB18A, 0x773E}, //7788 #CJK UNIFIED IDEOGRAPH + {0xB18B, 0x773F}, //7789 #CJK UNIFIED IDEOGRAPH + {0xB18C, 0x7742}, //7790 #CJK UNIFIED IDEOGRAPH + {0xB18D, 0x7744}, //7791 #CJK UNIFIED IDEOGRAPH + {0xB18E, 0x7745}, //7792 #CJK UNIFIED IDEOGRAPH + {0xB18F, 0x7746}, //7793 #CJK UNIFIED IDEOGRAPH + {0xB190, 0x7748}, //7794 #CJK UNIFIED IDEOGRAPH + {0xB191, 0x7749}, //7795 #CJK UNIFIED IDEOGRAPH + {0xB192, 0x774A}, //7796 #CJK UNIFIED IDEOGRAPH + {0xB193, 0x774B}, //7797 #CJK UNIFIED IDEOGRAPH + {0xB194, 0x774C}, //7798 #CJK UNIFIED IDEOGRAPH + {0xB195, 0x774D}, //7799 #CJK UNIFIED IDEOGRAPH + {0xB196, 0x774E}, //7800 #CJK UNIFIED IDEOGRAPH + {0xB197, 0x774F}, //7801 #CJK UNIFIED IDEOGRAPH + {0xB198, 0x7752}, //7802 #CJK UNIFIED IDEOGRAPH + {0xB199, 0x7753}, //7803 #CJK UNIFIED IDEOGRAPH + {0xB19A, 0x7754}, //7804 #CJK UNIFIED IDEOGRAPH + {0xB19B, 0x7755}, //7805 #CJK UNIFIED IDEOGRAPH + {0xB19C, 0x7756}, //7806 #CJK UNIFIED IDEOGRAPH + {0xB19D, 0x7757}, //7807 #CJK UNIFIED IDEOGRAPH + {0xB19E, 0x7758}, //7808 #CJK UNIFIED IDEOGRAPH + {0xB19F, 0x7759}, //7809 #CJK UNIFIED IDEOGRAPH + {0xB1A0, 0x775C}, //7810 #CJK UNIFIED IDEOGRAPH + {0xB1A1, 0x8584}, //7811 #CJK UNIFIED IDEOGRAPH + {0xB1A2, 0x96F9}, //7812 #CJK UNIFIED IDEOGRAPH + {0xB1A3, 0x4FDD}, //7813 #CJK UNIFIED IDEOGRAPH + {0xB1A4, 0x5821}, //7814 #CJK UNIFIED IDEOGRAPH + {0xB1A5, 0x9971}, //7815 #CJK UNIFIED IDEOGRAPH + {0xB1A6, 0x5B9D}, //7816 #CJK UNIFIED IDEOGRAPH + {0xB1A7, 0x62B1}, //7817 #CJK UNIFIED IDEOGRAPH + {0xB1A8, 0x62A5}, //7818 #CJK UNIFIED IDEOGRAPH + {0xB1A9, 0x66B4}, //7819 #CJK UNIFIED IDEOGRAPH + {0xB1AA, 0x8C79}, //7820 #CJK UNIFIED IDEOGRAPH + {0xB1AB, 0x9C8D}, //7821 #CJK UNIFIED IDEOGRAPH + {0xB1AC, 0x7206}, //7822 #CJK UNIFIED IDEOGRAPH + {0xB1AD, 0x676F}, //7823 #CJK UNIFIED IDEOGRAPH + {0xB1AE, 0x7891}, //7824 #CJK UNIFIED IDEOGRAPH + {0xB1AF, 0x60B2}, //7825 #CJK UNIFIED IDEOGRAPH + {0xB1B0, 0x5351}, //7826 #CJK UNIFIED IDEOGRAPH + {0xB1B1, 0x5317}, //7827 #CJK UNIFIED IDEOGRAPH + {0xB1B2, 0x8F88}, //7828 #CJK UNIFIED IDEOGRAPH + {0xB1B3, 0x80CC}, //7829 #CJK UNIFIED IDEOGRAPH + {0xB1B4, 0x8D1D}, //7830 #CJK UNIFIED IDEOGRAPH + {0xB1B5, 0x94A1}, //7831 #CJK UNIFIED IDEOGRAPH + {0xB1B6, 0x500D}, //7832 #CJK UNIFIED IDEOGRAPH + {0xB1B7, 0x72C8}, //7833 #CJK UNIFIED IDEOGRAPH + {0xB1B8, 0x5907}, //7834 #CJK UNIFIED IDEOGRAPH + {0xB1B9, 0x60EB}, //7835 #CJK UNIFIED IDEOGRAPH + {0xB1BA, 0x7119}, //7836 #CJK UNIFIED IDEOGRAPH + {0xB1BB, 0x88AB}, //7837 #CJK UNIFIED IDEOGRAPH + {0xB1BC, 0x5954}, //7838 #CJK UNIFIED IDEOGRAPH + {0xB1BD, 0x82EF}, //7839 #CJK UNIFIED IDEOGRAPH + {0xB1BE, 0x672C}, //7840 #CJK UNIFIED IDEOGRAPH + {0xB1BF, 0x7B28}, //7841 #CJK UNIFIED IDEOGRAPH + {0xB1C0, 0x5D29}, //7842 #CJK UNIFIED IDEOGRAPH + {0xB1C1, 0x7EF7}, //7843 #CJK UNIFIED IDEOGRAPH + {0xB1C2, 0x752D}, //7844 #CJK UNIFIED IDEOGRAPH + {0xB1C3, 0x6CF5}, //7845 #CJK UNIFIED IDEOGRAPH + {0xB1C4, 0x8E66}, //7846 #CJK UNIFIED IDEOGRAPH + {0xB1C5, 0x8FF8}, //7847 #CJK UNIFIED IDEOGRAPH + {0xB1C6, 0x903C}, //7848 #CJK UNIFIED IDEOGRAPH + {0xB1C7, 0x9F3B}, //7849 #CJK UNIFIED IDEOGRAPH + {0xB1C8, 0x6BD4}, //7850 #CJK UNIFIED IDEOGRAPH + {0xB1C9, 0x9119}, //7851 #CJK UNIFIED IDEOGRAPH + {0xB1CA, 0x7B14}, //7852 #CJK UNIFIED IDEOGRAPH + {0xB1CB, 0x5F7C}, //7853 #CJK UNIFIED IDEOGRAPH + {0xB1CC, 0x78A7}, //7854 #CJK UNIFIED IDEOGRAPH + {0xB1CD, 0x84D6}, //7855 #CJK UNIFIED IDEOGRAPH + {0xB1CE, 0x853D}, //7856 #CJK UNIFIED IDEOGRAPH + {0xB1CF, 0x6BD5}, //7857 #CJK UNIFIED IDEOGRAPH + {0xB1D0, 0x6BD9}, //7858 #CJK UNIFIED IDEOGRAPH + {0xB1D1, 0x6BD6}, //7859 #CJK UNIFIED IDEOGRAPH + {0xB1D2, 0x5E01}, //7860 #CJK UNIFIED IDEOGRAPH + {0xB1D3, 0x5E87}, //7861 #CJK UNIFIED IDEOGRAPH + {0xB1D4, 0x75F9}, //7862 #CJK UNIFIED IDEOGRAPH + {0xB1D5, 0x95ED}, //7863 #CJK UNIFIED IDEOGRAPH + {0xB1D6, 0x655D}, //7864 #CJK UNIFIED IDEOGRAPH + {0xB1D7, 0x5F0A}, //7865 #CJK UNIFIED IDEOGRAPH + {0xB1D8, 0x5FC5}, //7866 #CJK UNIFIED IDEOGRAPH + {0xB1D9, 0x8F9F}, //7867 #CJK UNIFIED IDEOGRAPH + {0xB1DA, 0x58C1}, //7868 #CJK UNIFIED IDEOGRAPH + {0xB1DB, 0x81C2}, //7869 #CJK UNIFIED IDEOGRAPH + {0xB1DC, 0x907F}, //7870 #CJK UNIFIED IDEOGRAPH + {0xB1DD, 0x965B}, //7871 #CJK UNIFIED IDEOGRAPH + {0xB1DE, 0x97AD}, //7872 #CJK UNIFIED IDEOGRAPH + {0xB1DF, 0x8FB9}, //7873 #CJK UNIFIED IDEOGRAPH + {0xB1E0, 0x7F16}, //7874 #CJK UNIFIED IDEOGRAPH + {0xB1E1, 0x8D2C}, //7875 #CJK UNIFIED IDEOGRAPH + {0xB1E2, 0x6241}, //7876 #CJK UNIFIED IDEOGRAPH + {0xB1E3, 0x4FBF}, //7877 #CJK UNIFIED IDEOGRAPH + {0xB1E4, 0x53D8}, //7878 #CJK UNIFIED IDEOGRAPH + {0xB1E5, 0x535E}, //7879 #CJK UNIFIED IDEOGRAPH + {0xB1E6, 0x8FA8}, //7880 #CJK UNIFIED IDEOGRAPH + {0xB1E7, 0x8FA9}, //7881 #CJK UNIFIED IDEOGRAPH + {0xB1E8, 0x8FAB}, //7882 #CJK UNIFIED IDEOGRAPH + {0xB1E9, 0x904D}, //7883 #CJK UNIFIED IDEOGRAPH + {0xB1EA, 0x6807}, //7884 #CJK UNIFIED IDEOGRAPH + {0xB1EB, 0x5F6A}, //7885 #CJK UNIFIED IDEOGRAPH + {0xB1EC, 0x8198}, //7886 #CJK UNIFIED IDEOGRAPH + {0xB1ED, 0x8868}, //7887 #CJK UNIFIED IDEOGRAPH + {0xB1EE, 0x9CD6}, //7888 #CJK UNIFIED IDEOGRAPH + {0xB1EF, 0x618B}, //7889 #CJK UNIFIED IDEOGRAPH + {0xB1F0, 0x522B}, //7890 #CJK UNIFIED IDEOGRAPH + {0xB1F1, 0x762A}, //7891 #CJK UNIFIED IDEOGRAPH + {0xB1F2, 0x5F6C}, //7892 #CJK UNIFIED IDEOGRAPH + {0xB1F3, 0x658C}, //7893 #CJK UNIFIED IDEOGRAPH + {0xB1F4, 0x6FD2}, //7894 #CJK UNIFIED IDEOGRAPH + {0xB1F5, 0x6EE8}, //7895 #CJK UNIFIED IDEOGRAPH + {0xB1F6, 0x5BBE}, //7896 #CJK UNIFIED IDEOGRAPH + {0xB1F7, 0x6448}, //7897 #CJK UNIFIED IDEOGRAPH + {0xB1F8, 0x5175}, //7898 #CJK UNIFIED IDEOGRAPH + {0xB1F9, 0x51B0}, //7899 #CJK UNIFIED IDEOGRAPH + {0xB1FA, 0x67C4}, //7900 #CJK UNIFIED IDEOGRAPH + {0xB1FB, 0x4E19}, //7901 #CJK UNIFIED IDEOGRAPH + {0xB1FC, 0x79C9}, //7902 #CJK UNIFIED IDEOGRAPH + {0xB1FD, 0x997C}, //7903 #CJK UNIFIED IDEOGRAPH + {0xB1FE, 0x70B3}, //7904 #CJK UNIFIED IDEOGRAPH + {0xB240, 0x775D}, //7905 #CJK UNIFIED IDEOGRAPH + {0xB241, 0x775E}, //7906 #CJK UNIFIED IDEOGRAPH + {0xB242, 0x775F}, //7907 #CJK UNIFIED IDEOGRAPH + {0xB243, 0x7760}, //7908 #CJK UNIFIED IDEOGRAPH + {0xB244, 0x7764}, //7909 #CJK UNIFIED IDEOGRAPH + {0xB245, 0x7767}, //7910 #CJK UNIFIED IDEOGRAPH + {0xB246, 0x7769}, //7911 #CJK UNIFIED IDEOGRAPH + {0xB247, 0x776A}, //7912 #CJK UNIFIED IDEOGRAPH + {0xB248, 0x776D}, //7913 #CJK UNIFIED IDEOGRAPH + {0xB249, 0x776E}, //7914 #CJK UNIFIED IDEOGRAPH + {0xB24A, 0x776F}, //7915 #CJK UNIFIED IDEOGRAPH + {0xB24B, 0x7770}, //7916 #CJK UNIFIED IDEOGRAPH + {0xB24C, 0x7771}, //7917 #CJK UNIFIED IDEOGRAPH + {0xB24D, 0x7772}, //7918 #CJK UNIFIED IDEOGRAPH + {0xB24E, 0x7773}, //7919 #CJK UNIFIED IDEOGRAPH + {0xB24F, 0x7774}, //7920 #CJK UNIFIED IDEOGRAPH + {0xB250, 0x7775}, //7921 #CJK UNIFIED IDEOGRAPH + {0xB251, 0x7776}, //7922 #CJK UNIFIED IDEOGRAPH + {0xB252, 0x7777}, //7923 #CJK UNIFIED IDEOGRAPH + {0xB253, 0x7778}, //7924 #CJK UNIFIED IDEOGRAPH + {0xB254, 0x777A}, //7925 #CJK UNIFIED IDEOGRAPH + {0xB255, 0x777B}, //7926 #CJK UNIFIED IDEOGRAPH + {0xB256, 0x777C}, //7927 #CJK UNIFIED IDEOGRAPH + {0xB257, 0x7781}, //7928 #CJK UNIFIED IDEOGRAPH + {0xB258, 0x7782}, //7929 #CJK UNIFIED IDEOGRAPH + {0xB259, 0x7783}, //7930 #CJK UNIFIED IDEOGRAPH + {0xB25A, 0x7786}, //7931 #CJK UNIFIED IDEOGRAPH + {0xB25B, 0x7787}, //7932 #CJK UNIFIED IDEOGRAPH + {0xB25C, 0x7788}, //7933 #CJK UNIFIED IDEOGRAPH + {0xB25D, 0x7789}, //7934 #CJK UNIFIED IDEOGRAPH + {0xB25E, 0x778A}, //7935 #CJK UNIFIED IDEOGRAPH + {0xB25F, 0x778B}, //7936 #CJK UNIFIED IDEOGRAPH + {0xB260, 0x778F}, //7937 #CJK UNIFIED IDEOGRAPH + {0xB261, 0x7790}, //7938 #CJK UNIFIED IDEOGRAPH + {0xB262, 0x7793}, //7939 #CJK UNIFIED IDEOGRAPH + {0xB263, 0x7794}, //7940 #CJK UNIFIED IDEOGRAPH + {0xB264, 0x7795}, //7941 #CJK UNIFIED IDEOGRAPH + {0xB265, 0x7796}, //7942 #CJK UNIFIED IDEOGRAPH + {0xB266, 0x7797}, //7943 #CJK UNIFIED IDEOGRAPH + {0xB267, 0x7798}, //7944 #CJK UNIFIED IDEOGRAPH + {0xB268, 0x7799}, //7945 #CJK UNIFIED IDEOGRAPH + {0xB269, 0x779A}, //7946 #CJK UNIFIED IDEOGRAPH + {0xB26A, 0x779B}, //7947 #CJK UNIFIED IDEOGRAPH + {0xB26B, 0x779C}, //7948 #CJK UNIFIED IDEOGRAPH + {0xB26C, 0x779D}, //7949 #CJK UNIFIED IDEOGRAPH + {0xB26D, 0x779E}, //7950 #CJK UNIFIED IDEOGRAPH + {0xB26E, 0x77A1}, //7951 #CJK UNIFIED IDEOGRAPH + {0xB26F, 0x77A3}, //7952 #CJK UNIFIED IDEOGRAPH + {0xB270, 0x77A4}, //7953 #CJK UNIFIED IDEOGRAPH + {0xB271, 0x77A6}, //7954 #CJK UNIFIED IDEOGRAPH + {0xB272, 0x77A8}, //7955 #CJK UNIFIED IDEOGRAPH + {0xB273, 0x77AB}, //7956 #CJK UNIFIED IDEOGRAPH + {0xB274, 0x77AD}, //7957 #CJK UNIFIED IDEOGRAPH + {0xB275, 0x77AE}, //7958 #CJK UNIFIED IDEOGRAPH + {0xB276, 0x77AF}, //7959 #CJK UNIFIED IDEOGRAPH + {0xB277, 0x77B1}, //7960 #CJK UNIFIED IDEOGRAPH + {0xB278, 0x77B2}, //7961 #CJK UNIFIED IDEOGRAPH + {0xB279, 0x77B4}, //7962 #CJK UNIFIED IDEOGRAPH + {0xB27A, 0x77B6}, //7963 #CJK UNIFIED IDEOGRAPH + {0xB27B, 0x77B7}, //7964 #CJK UNIFIED IDEOGRAPH + {0xB27C, 0x77B8}, //7965 #CJK UNIFIED IDEOGRAPH + {0xB27D, 0x77B9}, //7966 #CJK UNIFIED IDEOGRAPH + {0xB27E, 0x77BA}, //7967 #CJK UNIFIED IDEOGRAPH + {0xB280, 0x77BC}, //7968 #CJK UNIFIED IDEOGRAPH + {0xB281, 0x77BE}, //7969 #CJK UNIFIED IDEOGRAPH + {0xB282, 0x77C0}, //7970 #CJK UNIFIED IDEOGRAPH + {0xB283, 0x77C1}, //7971 #CJK UNIFIED IDEOGRAPH + {0xB284, 0x77C2}, //7972 #CJK UNIFIED IDEOGRAPH + {0xB285, 0x77C3}, //7973 #CJK UNIFIED IDEOGRAPH + {0xB286, 0x77C4}, //7974 #CJK UNIFIED IDEOGRAPH + {0xB287, 0x77C5}, //7975 #CJK UNIFIED IDEOGRAPH + {0xB288, 0x77C6}, //7976 #CJK UNIFIED IDEOGRAPH + {0xB289, 0x77C7}, //7977 #CJK UNIFIED IDEOGRAPH + {0xB28A, 0x77C8}, //7978 #CJK UNIFIED IDEOGRAPH + {0xB28B, 0x77C9}, //7979 #CJK UNIFIED IDEOGRAPH + {0xB28C, 0x77CA}, //7980 #CJK UNIFIED IDEOGRAPH + {0xB28D, 0x77CB}, //7981 #CJK UNIFIED IDEOGRAPH + {0xB28E, 0x77CC}, //7982 #CJK UNIFIED IDEOGRAPH + {0xB28F, 0x77CE}, //7983 #CJK UNIFIED IDEOGRAPH + {0xB290, 0x77CF}, //7984 #CJK UNIFIED IDEOGRAPH + {0xB291, 0x77D0}, //7985 #CJK UNIFIED IDEOGRAPH + {0xB292, 0x77D1}, //7986 #CJK UNIFIED IDEOGRAPH + {0xB293, 0x77D2}, //7987 #CJK UNIFIED IDEOGRAPH + {0xB294, 0x77D3}, //7988 #CJK UNIFIED IDEOGRAPH + {0xB295, 0x77D4}, //7989 #CJK UNIFIED IDEOGRAPH + {0xB296, 0x77D5}, //7990 #CJK UNIFIED IDEOGRAPH + {0xB297, 0x77D6}, //7991 #CJK UNIFIED IDEOGRAPH + {0xB298, 0x77D8}, //7992 #CJK UNIFIED IDEOGRAPH + {0xB299, 0x77D9}, //7993 #CJK UNIFIED IDEOGRAPH + {0xB29A, 0x77DA}, //7994 #CJK UNIFIED IDEOGRAPH + {0xB29B, 0x77DD}, //7995 #CJK UNIFIED IDEOGRAPH + {0xB29C, 0x77DE}, //7996 #CJK UNIFIED IDEOGRAPH + {0xB29D, 0x77DF}, //7997 #CJK UNIFIED IDEOGRAPH + {0xB29E, 0x77E0}, //7998 #CJK UNIFIED IDEOGRAPH + {0xB29F, 0x77E1}, //7999 #CJK UNIFIED IDEOGRAPH + {0xB2A0, 0x77E4}, //8000 #CJK UNIFIED IDEOGRAPH + {0xB2A1, 0x75C5}, //8001 #CJK UNIFIED IDEOGRAPH + {0xB2A2, 0x5E76}, //8002 #CJK UNIFIED IDEOGRAPH + {0xB2A3, 0x73BB}, //8003 #CJK UNIFIED IDEOGRAPH + {0xB2A4, 0x83E0}, //8004 #CJK UNIFIED IDEOGRAPH + {0xB2A5, 0x64AD}, //8005 #CJK UNIFIED IDEOGRAPH + {0xB2A6, 0x62E8}, //8006 #CJK UNIFIED IDEOGRAPH + {0xB2A7, 0x94B5}, //8007 #CJK UNIFIED IDEOGRAPH + {0xB2A8, 0x6CE2}, //8008 #CJK UNIFIED IDEOGRAPH + {0xB2A9, 0x535A}, //8009 #CJK UNIFIED IDEOGRAPH + {0xB2AA, 0x52C3}, //8010 #CJK UNIFIED IDEOGRAPH + {0xB2AB, 0x640F}, //8011 #CJK UNIFIED IDEOGRAPH + {0xB2AC, 0x94C2}, //8012 #CJK UNIFIED IDEOGRAPH + {0xB2AD, 0x7B94}, //8013 #CJK UNIFIED IDEOGRAPH + {0xB2AE, 0x4F2F}, //8014 #CJK UNIFIED IDEOGRAPH + {0xB2AF, 0x5E1B}, //8015 #CJK UNIFIED IDEOGRAPH + {0xB2B0, 0x8236}, //8016 #CJK UNIFIED IDEOGRAPH + {0xB2B1, 0x8116}, //8017 #CJK UNIFIED IDEOGRAPH + {0xB2B2, 0x818A}, //8018 #CJK UNIFIED IDEOGRAPH + {0xB2B3, 0x6E24}, //8019 #CJK UNIFIED IDEOGRAPH + {0xB2B4, 0x6CCA}, //8020 #CJK UNIFIED IDEOGRAPH + {0xB2B5, 0x9A73}, //8021 #CJK UNIFIED IDEOGRAPH + {0xB2B6, 0x6355}, //8022 #CJK UNIFIED IDEOGRAPH + {0xB2B7, 0x535C}, //8023 #CJK UNIFIED IDEOGRAPH + {0xB2B8, 0x54FA}, //8024 #CJK UNIFIED IDEOGRAPH + {0xB2B9, 0x8865}, //8025 #CJK UNIFIED IDEOGRAPH + {0xB2BA, 0x57E0}, //8026 #CJK UNIFIED IDEOGRAPH + {0xB2BB, 0x4E0D}, //8027 #CJK UNIFIED IDEOGRAPH + {0xB2BC, 0x5E03}, //8028 #CJK UNIFIED IDEOGRAPH + {0xB2BD, 0x6B65}, //8029 #CJK UNIFIED IDEOGRAPH + {0xB2BE, 0x7C3F}, //8030 #CJK UNIFIED IDEOGRAPH + {0xB2BF, 0x90E8}, //8031 #CJK UNIFIED IDEOGRAPH + {0xB2C0, 0x6016}, //8032 #CJK UNIFIED IDEOGRAPH + {0xB2C1, 0x64E6}, //8033 #CJK UNIFIED IDEOGRAPH + {0xB2C2, 0x731C}, //8034 #CJK UNIFIED IDEOGRAPH + {0xB2C3, 0x88C1}, //8035 #CJK UNIFIED IDEOGRAPH + {0xB2C4, 0x6750}, //8036 #CJK UNIFIED IDEOGRAPH + {0xB2C5, 0x624D}, //8037 #CJK UNIFIED IDEOGRAPH + {0xB2C6, 0x8D22}, //8038 #CJK UNIFIED IDEOGRAPH + {0xB2C7, 0x776C}, //8039 #CJK UNIFIED IDEOGRAPH + {0xB2C8, 0x8E29}, //8040 #CJK UNIFIED IDEOGRAPH + {0xB2C9, 0x91C7}, //8041 #CJK UNIFIED IDEOGRAPH + {0xB2CA, 0x5F69}, //8042 #CJK UNIFIED IDEOGRAPH + {0xB2CB, 0x83DC}, //8043 #CJK UNIFIED IDEOGRAPH + {0xB2CC, 0x8521}, //8044 #CJK UNIFIED IDEOGRAPH + {0xB2CD, 0x9910}, //8045 #CJK UNIFIED IDEOGRAPH + {0xB2CE, 0x53C2}, //8046 #CJK UNIFIED IDEOGRAPH + {0xB2CF, 0x8695}, //8047 #CJK UNIFIED IDEOGRAPH + {0xB2D0, 0x6B8B}, //8048 #CJK UNIFIED IDEOGRAPH + {0xB2D1, 0x60ED}, //8049 #CJK UNIFIED IDEOGRAPH + {0xB2D2, 0x60E8}, //8050 #CJK UNIFIED IDEOGRAPH + {0xB2D3, 0x707F}, //8051 #CJK UNIFIED IDEOGRAPH + {0xB2D4, 0x82CD}, //8052 #CJK UNIFIED IDEOGRAPH + {0xB2D5, 0x8231}, //8053 #CJK UNIFIED IDEOGRAPH + {0xB2D6, 0x4ED3}, //8054 #CJK UNIFIED IDEOGRAPH + {0xB2D7, 0x6CA7}, //8055 #CJK UNIFIED IDEOGRAPH + {0xB2D8, 0x85CF}, //8056 #CJK UNIFIED IDEOGRAPH + {0xB2D9, 0x64CD}, //8057 #CJK UNIFIED IDEOGRAPH + {0xB2DA, 0x7CD9}, //8058 #CJK UNIFIED IDEOGRAPH + {0xB2DB, 0x69FD}, //8059 #CJK UNIFIED IDEOGRAPH + {0xB2DC, 0x66F9}, //8060 #CJK UNIFIED IDEOGRAPH + {0xB2DD, 0x8349}, //8061 #CJK UNIFIED IDEOGRAPH + {0xB2DE, 0x5395}, //8062 #CJK UNIFIED IDEOGRAPH + {0xB2DF, 0x7B56}, //8063 #CJK UNIFIED IDEOGRAPH + {0xB2E0, 0x4FA7}, //8064 #CJK UNIFIED IDEOGRAPH + {0xB2E1, 0x518C}, //8065 #CJK UNIFIED IDEOGRAPH + {0xB2E2, 0x6D4B}, //8066 #CJK UNIFIED IDEOGRAPH + {0xB2E3, 0x5C42}, //8067 #CJK UNIFIED IDEOGRAPH + {0xB2E4, 0x8E6D}, //8068 #CJK UNIFIED IDEOGRAPH + {0xB2E5, 0x63D2}, //8069 #CJK UNIFIED IDEOGRAPH + {0xB2E6, 0x53C9}, //8070 #CJK UNIFIED IDEOGRAPH + {0xB2E7, 0x832C}, //8071 #CJK UNIFIED IDEOGRAPH + {0xB2E8, 0x8336}, //8072 #CJK UNIFIED IDEOGRAPH + {0xB2E9, 0x67E5}, //8073 #CJK UNIFIED IDEOGRAPH + {0xB2EA, 0x78B4}, //8074 #CJK UNIFIED IDEOGRAPH + {0xB2EB, 0x643D}, //8075 #CJK UNIFIED IDEOGRAPH + {0xB2EC, 0x5BDF}, //8076 #CJK UNIFIED IDEOGRAPH + {0xB2ED, 0x5C94}, //8077 #CJK UNIFIED IDEOGRAPH + {0xB2EE, 0x5DEE}, //8078 #CJK UNIFIED IDEOGRAPH + {0xB2EF, 0x8BE7}, //8079 #CJK UNIFIED IDEOGRAPH + {0xB2F0, 0x62C6}, //8080 #CJK UNIFIED IDEOGRAPH + {0xB2F1, 0x67F4}, //8081 #CJK UNIFIED IDEOGRAPH + {0xB2F2, 0x8C7A}, //8082 #CJK UNIFIED IDEOGRAPH + {0xB2F3, 0x6400}, //8083 #CJK UNIFIED IDEOGRAPH + {0xB2F4, 0x63BA}, //8084 #CJK UNIFIED IDEOGRAPH + {0xB2F5, 0x8749}, //8085 #CJK UNIFIED IDEOGRAPH + {0xB2F6, 0x998B}, //8086 #CJK UNIFIED IDEOGRAPH + {0xB2F7, 0x8C17}, //8087 #CJK UNIFIED IDEOGRAPH + {0xB2F8, 0x7F20}, //8088 #CJK UNIFIED IDEOGRAPH + {0xB2F9, 0x94F2}, //8089 #CJK UNIFIED IDEOGRAPH + {0xB2FA, 0x4EA7}, //8090 #CJK UNIFIED IDEOGRAPH + {0xB2FB, 0x9610}, //8091 #CJK UNIFIED IDEOGRAPH + {0xB2FC, 0x98A4}, //8092 #CJK UNIFIED IDEOGRAPH + {0xB2FD, 0x660C}, //8093 #CJK UNIFIED IDEOGRAPH + {0xB2FE, 0x7316}, //8094 #CJK UNIFIED IDEOGRAPH + {0xB340, 0x77E6}, //8095 #CJK UNIFIED IDEOGRAPH + {0xB341, 0x77E8}, //8096 #CJK UNIFIED IDEOGRAPH + {0xB342, 0x77EA}, //8097 #CJK UNIFIED IDEOGRAPH + {0xB343, 0x77EF}, //8098 #CJK UNIFIED IDEOGRAPH + {0xB344, 0x77F0}, //8099 #CJK UNIFIED IDEOGRAPH + {0xB345, 0x77F1}, //8100 #CJK UNIFIED IDEOGRAPH + {0xB346, 0x77F2}, //8101 #CJK UNIFIED IDEOGRAPH + {0xB347, 0x77F4}, //8102 #CJK UNIFIED IDEOGRAPH + {0xB348, 0x77F5}, //8103 #CJK UNIFIED IDEOGRAPH + {0xB349, 0x77F7}, //8104 #CJK UNIFIED IDEOGRAPH + {0xB34A, 0x77F9}, //8105 #CJK UNIFIED IDEOGRAPH + {0xB34B, 0x77FA}, //8106 #CJK UNIFIED IDEOGRAPH + {0xB34C, 0x77FB}, //8107 #CJK UNIFIED IDEOGRAPH + {0xB34D, 0x77FC}, //8108 #CJK UNIFIED IDEOGRAPH + {0xB34E, 0x7803}, //8109 #CJK UNIFIED IDEOGRAPH + {0xB34F, 0x7804}, //8110 #CJK UNIFIED IDEOGRAPH + {0xB350, 0x7805}, //8111 #CJK UNIFIED IDEOGRAPH + {0xB351, 0x7806}, //8112 #CJK UNIFIED IDEOGRAPH + {0xB352, 0x7807}, //8113 #CJK UNIFIED IDEOGRAPH + {0xB353, 0x7808}, //8114 #CJK UNIFIED IDEOGRAPH + {0xB354, 0x780A}, //8115 #CJK UNIFIED IDEOGRAPH + {0xB355, 0x780B}, //8116 #CJK UNIFIED IDEOGRAPH + {0xB356, 0x780E}, //8117 #CJK UNIFIED IDEOGRAPH + {0xB357, 0x780F}, //8118 #CJK UNIFIED IDEOGRAPH + {0xB358, 0x7810}, //8119 #CJK UNIFIED IDEOGRAPH + {0xB359, 0x7813}, //8120 #CJK UNIFIED IDEOGRAPH + {0xB35A, 0x7815}, //8121 #CJK UNIFIED IDEOGRAPH + {0xB35B, 0x7819}, //8122 #CJK UNIFIED IDEOGRAPH + {0xB35C, 0x781B}, //8123 #CJK UNIFIED IDEOGRAPH + {0xB35D, 0x781E}, //8124 #CJK UNIFIED IDEOGRAPH + {0xB35E, 0x7820}, //8125 #CJK UNIFIED IDEOGRAPH + {0xB35F, 0x7821}, //8126 #CJK UNIFIED IDEOGRAPH + {0xB360, 0x7822}, //8127 #CJK UNIFIED IDEOGRAPH + {0xB361, 0x7824}, //8128 #CJK UNIFIED IDEOGRAPH + {0xB362, 0x7828}, //8129 #CJK UNIFIED IDEOGRAPH + {0xB363, 0x782A}, //8130 #CJK UNIFIED IDEOGRAPH + {0xB364, 0x782B}, //8131 #CJK UNIFIED IDEOGRAPH + {0xB365, 0x782E}, //8132 #CJK UNIFIED IDEOGRAPH + {0xB366, 0x782F}, //8133 #CJK UNIFIED IDEOGRAPH + {0xB367, 0x7831}, //8134 #CJK UNIFIED IDEOGRAPH + {0xB368, 0x7832}, //8135 #CJK UNIFIED IDEOGRAPH + {0xB369, 0x7833}, //8136 #CJK UNIFIED IDEOGRAPH + {0xB36A, 0x7835}, //8137 #CJK UNIFIED IDEOGRAPH + {0xB36B, 0x7836}, //8138 #CJK UNIFIED IDEOGRAPH + {0xB36C, 0x783D}, //8139 #CJK UNIFIED IDEOGRAPH + {0xB36D, 0x783F}, //8140 #CJK UNIFIED IDEOGRAPH + {0xB36E, 0x7841}, //8141 #CJK UNIFIED IDEOGRAPH + {0xB36F, 0x7842}, //8142 #CJK UNIFIED IDEOGRAPH + {0xB370, 0x7843}, //8143 #CJK UNIFIED IDEOGRAPH + {0xB371, 0x7844}, //8144 #CJK UNIFIED IDEOGRAPH + {0xB372, 0x7846}, //8145 #CJK UNIFIED IDEOGRAPH + {0xB373, 0x7848}, //8146 #CJK UNIFIED IDEOGRAPH + {0xB374, 0x7849}, //8147 #CJK UNIFIED IDEOGRAPH + {0xB375, 0x784A}, //8148 #CJK UNIFIED IDEOGRAPH + {0xB376, 0x784B}, //8149 #CJK UNIFIED IDEOGRAPH + {0xB377, 0x784D}, //8150 #CJK UNIFIED IDEOGRAPH + {0xB378, 0x784F}, //8151 #CJK UNIFIED IDEOGRAPH + {0xB379, 0x7851}, //8152 #CJK UNIFIED IDEOGRAPH + {0xB37A, 0x7853}, //8153 #CJK UNIFIED IDEOGRAPH + {0xB37B, 0x7854}, //8154 #CJK UNIFIED IDEOGRAPH + {0xB37C, 0x7858}, //8155 #CJK UNIFIED IDEOGRAPH + {0xB37D, 0x7859}, //8156 #CJK UNIFIED IDEOGRAPH + {0xB37E, 0x785A}, //8157 #CJK UNIFIED IDEOGRAPH + {0xB380, 0x785B}, //8158 #CJK UNIFIED IDEOGRAPH + {0xB381, 0x785C}, //8159 #CJK UNIFIED IDEOGRAPH + {0xB382, 0x785E}, //8160 #CJK UNIFIED IDEOGRAPH + {0xB383, 0x785F}, //8161 #CJK UNIFIED IDEOGRAPH + {0xB384, 0x7860}, //8162 #CJK UNIFIED IDEOGRAPH + {0xB385, 0x7861}, //8163 #CJK UNIFIED IDEOGRAPH + {0xB386, 0x7862}, //8164 #CJK UNIFIED IDEOGRAPH + {0xB387, 0x7863}, //8165 #CJK UNIFIED IDEOGRAPH + {0xB388, 0x7864}, //8166 #CJK UNIFIED IDEOGRAPH + {0xB389, 0x7865}, //8167 #CJK UNIFIED IDEOGRAPH + {0xB38A, 0x7866}, //8168 #CJK UNIFIED IDEOGRAPH + {0xB38B, 0x7867}, //8169 #CJK UNIFIED IDEOGRAPH + {0xB38C, 0x7868}, //8170 #CJK UNIFIED IDEOGRAPH + {0xB38D, 0x7869}, //8171 #CJK UNIFIED IDEOGRAPH + {0xB38E, 0x786F}, //8172 #CJK UNIFIED IDEOGRAPH + {0xB38F, 0x7870}, //8173 #CJK UNIFIED IDEOGRAPH + {0xB390, 0x7871}, //8174 #CJK UNIFIED IDEOGRAPH + {0xB391, 0x7872}, //8175 #CJK UNIFIED IDEOGRAPH + {0xB392, 0x7873}, //8176 #CJK UNIFIED IDEOGRAPH + {0xB393, 0x7874}, //8177 #CJK UNIFIED IDEOGRAPH + {0xB394, 0x7875}, //8178 #CJK UNIFIED IDEOGRAPH + {0xB395, 0x7876}, //8179 #CJK UNIFIED IDEOGRAPH + {0xB396, 0x7878}, //8180 #CJK UNIFIED IDEOGRAPH + {0xB397, 0x7879}, //8181 #CJK UNIFIED IDEOGRAPH + {0xB398, 0x787A}, //8182 #CJK UNIFIED IDEOGRAPH + {0xB399, 0x787B}, //8183 #CJK UNIFIED IDEOGRAPH + {0xB39A, 0x787D}, //8184 #CJK UNIFIED IDEOGRAPH + {0xB39B, 0x787E}, //8185 #CJK UNIFIED IDEOGRAPH + {0xB39C, 0x787F}, //8186 #CJK UNIFIED IDEOGRAPH + {0xB39D, 0x7880}, //8187 #CJK UNIFIED IDEOGRAPH + {0xB39E, 0x7881}, //8188 #CJK UNIFIED IDEOGRAPH + {0xB39F, 0x7882}, //8189 #CJK UNIFIED IDEOGRAPH + {0xB3A0, 0x7883}, //8190 #CJK UNIFIED IDEOGRAPH + {0xB3A1, 0x573A}, //8191 #CJK UNIFIED IDEOGRAPH + {0xB3A2, 0x5C1D}, //8192 #CJK UNIFIED IDEOGRAPH + {0xB3A3, 0x5E38}, //8193 #CJK UNIFIED IDEOGRAPH + {0xB3A4, 0x957F}, //8194 #CJK UNIFIED IDEOGRAPH + {0xB3A5, 0x507F}, //8195 #CJK UNIFIED IDEOGRAPH + {0xB3A6, 0x80A0}, //8196 #CJK UNIFIED IDEOGRAPH + {0xB3A7, 0x5382}, //8197 #CJK UNIFIED IDEOGRAPH + {0xB3A8, 0x655E}, //8198 #CJK UNIFIED IDEOGRAPH + {0xB3A9, 0x7545}, //8199 #CJK UNIFIED IDEOGRAPH + {0xB3AA, 0x5531}, //8200 #CJK UNIFIED IDEOGRAPH + {0xB3AB, 0x5021}, //8201 #CJK UNIFIED IDEOGRAPH + {0xB3AC, 0x8D85}, //8202 #CJK UNIFIED IDEOGRAPH + {0xB3AD, 0x6284}, //8203 #CJK UNIFIED IDEOGRAPH + {0xB3AE, 0x949E}, //8204 #CJK UNIFIED IDEOGRAPH + {0xB3AF, 0x671D}, //8205 #CJK UNIFIED IDEOGRAPH + {0xB3B0, 0x5632}, //8206 #CJK UNIFIED IDEOGRAPH + {0xB3B1, 0x6F6E}, //8207 #CJK UNIFIED IDEOGRAPH + {0xB3B2, 0x5DE2}, //8208 #CJK UNIFIED IDEOGRAPH + {0xB3B3, 0x5435}, //8209 #CJK UNIFIED IDEOGRAPH + {0xB3B4, 0x7092}, //8210 #CJK UNIFIED IDEOGRAPH + {0xB3B5, 0x8F66}, //8211 #CJK UNIFIED IDEOGRAPH + {0xB3B6, 0x626F}, //8212 #CJK UNIFIED IDEOGRAPH + {0xB3B7, 0x64A4}, //8213 #CJK UNIFIED IDEOGRAPH + {0xB3B8, 0x63A3}, //8214 #CJK UNIFIED IDEOGRAPH + {0xB3B9, 0x5F7B}, //8215 #CJK UNIFIED IDEOGRAPH + {0xB3BA, 0x6F88}, //8216 #CJK UNIFIED IDEOGRAPH + {0xB3BB, 0x90F4}, //8217 #CJK UNIFIED IDEOGRAPH + {0xB3BC, 0x81E3}, //8218 #CJK UNIFIED IDEOGRAPH + {0xB3BD, 0x8FB0}, //8219 #CJK UNIFIED IDEOGRAPH + {0xB3BE, 0x5C18}, //8220 #CJK UNIFIED IDEOGRAPH + {0xB3BF, 0x6668}, //8221 #CJK UNIFIED IDEOGRAPH + {0xB3C0, 0x5FF1}, //8222 #CJK UNIFIED IDEOGRAPH + {0xB3C1, 0x6C89}, //8223 #CJK UNIFIED IDEOGRAPH + {0xB3C2, 0x9648}, //8224 #CJK UNIFIED IDEOGRAPH + {0xB3C3, 0x8D81}, //8225 #CJK UNIFIED IDEOGRAPH + {0xB3C4, 0x886C}, //8226 #CJK UNIFIED IDEOGRAPH + {0xB3C5, 0x6491}, //8227 #CJK UNIFIED IDEOGRAPH + {0xB3C6, 0x79F0}, //8228 #CJK UNIFIED IDEOGRAPH + {0xB3C7, 0x57CE}, //8229 #CJK UNIFIED IDEOGRAPH + {0xB3C8, 0x6A59}, //8230 #CJK UNIFIED IDEOGRAPH + {0xB3C9, 0x6210}, //8231 #CJK UNIFIED IDEOGRAPH + {0xB3CA, 0x5448}, //8232 #CJK UNIFIED IDEOGRAPH + {0xB3CB, 0x4E58}, //8233 #CJK UNIFIED IDEOGRAPH + {0xB3CC, 0x7A0B}, //8234 #CJK UNIFIED IDEOGRAPH + {0xB3CD, 0x60E9}, //8235 #CJK UNIFIED IDEOGRAPH + {0xB3CE, 0x6F84}, //8236 #CJK UNIFIED IDEOGRAPH + {0xB3CF, 0x8BDA}, //8237 #CJK UNIFIED IDEOGRAPH + {0xB3D0, 0x627F}, //8238 #CJK UNIFIED IDEOGRAPH + {0xB3D1, 0x901E}, //8239 #CJK UNIFIED IDEOGRAPH + {0xB3D2, 0x9A8B}, //8240 #CJK UNIFIED IDEOGRAPH + {0xB3D3, 0x79E4}, //8241 #CJK UNIFIED IDEOGRAPH + {0xB3D4, 0x5403}, //8242 #CJK UNIFIED IDEOGRAPH + {0xB3D5, 0x75F4}, //8243 #CJK UNIFIED IDEOGRAPH + {0xB3D6, 0x6301}, //8244 #CJK UNIFIED IDEOGRAPH + {0xB3D7, 0x5319}, //8245 #CJK UNIFIED IDEOGRAPH + {0xB3D8, 0x6C60}, //8246 #CJK UNIFIED IDEOGRAPH + {0xB3D9, 0x8FDF}, //8247 #CJK UNIFIED IDEOGRAPH + {0xB3DA, 0x5F1B}, //8248 #CJK UNIFIED IDEOGRAPH + {0xB3DB, 0x9A70}, //8249 #CJK UNIFIED IDEOGRAPH + {0xB3DC, 0x803B}, //8250 #CJK UNIFIED IDEOGRAPH + {0xB3DD, 0x9F7F}, //8251 #CJK UNIFIED IDEOGRAPH + {0xB3DE, 0x4F88}, //8252 #CJK UNIFIED IDEOGRAPH + {0xB3DF, 0x5C3A}, //8253 #CJK UNIFIED IDEOGRAPH + {0xB3E0, 0x8D64}, //8254 #CJK UNIFIED IDEOGRAPH + {0xB3E1, 0x7FC5}, //8255 #CJK UNIFIED IDEOGRAPH + {0xB3E2, 0x65A5}, //8256 #CJK UNIFIED IDEOGRAPH + {0xB3E3, 0x70BD}, //8257 #CJK UNIFIED IDEOGRAPH + {0xB3E4, 0x5145}, //8258 #CJK UNIFIED IDEOGRAPH + {0xB3E5, 0x51B2}, //8259 #CJK UNIFIED IDEOGRAPH + {0xB3E6, 0x866B}, //8260 #CJK UNIFIED IDEOGRAPH + {0xB3E7, 0x5D07}, //8261 #CJK UNIFIED IDEOGRAPH + {0xB3E8, 0x5BA0}, //8262 #CJK UNIFIED IDEOGRAPH + {0xB3E9, 0x62BD}, //8263 #CJK UNIFIED IDEOGRAPH + {0xB3EA, 0x916C}, //8264 #CJK UNIFIED IDEOGRAPH + {0xB3EB, 0x7574}, //8265 #CJK UNIFIED IDEOGRAPH + {0xB3EC, 0x8E0C}, //8266 #CJK UNIFIED IDEOGRAPH + {0xB3ED, 0x7A20}, //8267 #CJK UNIFIED IDEOGRAPH + {0xB3EE, 0x6101}, //8268 #CJK UNIFIED IDEOGRAPH + {0xB3EF, 0x7B79}, //8269 #CJK UNIFIED IDEOGRAPH + {0xB3F0, 0x4EC7}, //8270 #CJK UNIFIED IDEOGRAPH + {0xB3F1, 0x7EF8}, //8271 #CJK UNIFIED IDEOGRAPH + {0xB3F2, 0x7785}, //8272 #CJK UNIFIED IDEOGRAPH + {0xB3F3, 0x4E11}, //8273 #CJK UNIFIED IDEOGRAPH + {0xB3F4, 0x81ED}, //8274 #CJK UNIFIED IDEOGRAPH + {0xB3F5, 0x521D}, //8275 #CJK UNIFIED IDEOGRAPH + {0xB3F6, 0x51FA}, //8276 #CJK UNIFIED IDEOGRAPH + {0xB3F7, 0x6A71}, //8277 #CJK UNIFIED IDEOGRAPH + {0xB3F8, 0x53A8}, //8278 #CJK UNIFIED IDEOGRAPH + {0xB3F9, 0x8E87}, //8279 #CJK UNIFIED IDEOGRAPH + {0xB3FA, 0x9504}, //8280 #CJK UNIFIED IDEOGRAPH + {0xB3FB, 0x96CF}, //8281 #CJK UNIFIED IDEOGRAPH + {0xB3FC, 0x6EC1}, //8282 #CJK UNIFIED IDEOGRAPH + {0xB3FD, 0x9664}, //8283 #CJK UNIFIED IDEOGRAPH + {0xB3FE, 0x695A}, //8284 #CJK UNIFIED IDEOGRAPH + {0xB440, 0x7884}, //8285 #CJK UNIFIED IDEOGRAPH + {0xB441, 0x7885}, //8286 #CJK UNIFIED IDEOGRAPH + {0xB442, 0x7886}, //8287 #CJK UNIFIED IDEOGRAPH + {0xB443, 0x7888}, //8288 #CJK UNIFIED IDEOGRAPH + {0xB444, 0x788A}, //8289 #CJK UNIFIED IDEOGRAPH + {0xB445, 0x788B}, //8290 #CJK UNIFIED IDEOGRAPH + {0xB446, 0x788F}, //8291 #CJK UNIFIED IDEOGRAPH + {0xB447, 0x7890}, //8292 #CJK UNIFIED IDEOGRAPH + {0xB448, 0x7892}, //8293 #CJK UNIFIED IDEOGRAPH + {0xB449, 0x7894}, //8294 #CJK UNIFIED IDEOGRAPH + {0xB44A, 0x7895}, //8295 #CJK UNIFIED IDEOGRAPH + {0xB44B, 0x7896}, //8296 #CJK UNIFIED IDEOGRAPH + {0xB44C, 0x7899}, //8297 #CJK UNIFIED IDEOGRAPH + {0xB44D, 0x789D}, //8298 #CJK UNIFIED IDEOGRAPH + {0xB44E, 0x789E}, //8299 #CJK UNIFIED IDEOGRAPH + {0xB44F, 0x78A0}, //8300 #CJK UNIFIED IDEOGRAPH + {0xB450, 0x78A2}, //8301 #CJK UNIFIED IDEOGRAPH + {0xB451, 0x78A4}, //8302 #CJK UNIFIED IDEOGRAPH + {0xB452, 0x78A6}, //8303 #CJK UNIFIED IDEOGRAPH + {0xB453, 0x78A8}, //8304 #CJK UNIFIED IDEOGRAPH + {0xB454, 0x78A9}, //8305 #CJK UNIFIED IDEOGRAPH + {0xB455, 0x78AA}, //8306 #CJK UNIFIED IDEOGRAPH + {0xB456, 0x78AB}, //8307 #CJK UNIFIED IDEOGRAPH + {0xB457, 0x78AC}, //8308 #CJK UNIFIED IDEOGRAPH + {0xB458, 0x78AD}, //8309 #CJK UNIFIED IDEOGRAPH + {0xB459, 0x78AE}, //8310 #CJK UNIFIED IDEOGRAPH + {0xB45A, 0x78AF}, //8311 #CJK UNIFIED IDEOGRAPH + {0xB45B, 0x78B5}, //8312 #CJK UNIFIED IDEOGRAPH + {0xB45C, 0x78B6}, //8313 #CJK UNIFIED IDEOGRAPH + {0xB45D, 0x78B7}, //8314 #CJK UNIFIED IDEOGRAPH + {0xB45E, 0x78B8}, //8315 #CJK UNIFIED IDEOGRAPH + {0xB45F, 0x78BA}, //8316 #CJK UNIFIED IDEOGRAPH + {0xB460, 0x78BB}, //8317 #CJK UNIFIED IDEOGRAPH + {0xB461, 0x78BC}, //8318 #CJK UNIFIED IDEOGRAPH + {0xB462, 0x78BD}, //8319 #CJK UNIFIED IDEOGRAPH + {0xB463, 0x78BF}, //8320 #CJK UNIFIED IDEOGRAPH + {0xB464, 0x78C0}, //8321 #CJK UNIFIED IDEOGRAPH + {0xB465, 0x78C2}, //8322 #CJK UNIFIED IDEOGRAPH + {0xB466, 0x78C3}, //8323 #CJK UNIFIED IDEOGRAPH + {0xB467, 0x78C4}, //8324 #CJK UNIFIED IDEOGRAPH + {0xB468, 0x78C6}, //8325 #CJK UNIFIED IDEOGRAPH + {0xB469, 0x78C7}, //8326 #CJK UNIFIED IDEOGRAPH + {0xB46A, 0x78C8}, //8327 #CJK UNIFIED IDEOGRAPH + {0xB46B, 0x78CC}, //8328 #CJK UNIFIED IDEOGRAPH + {0xB46C, 0x78CD}, //8329 #CJK UNIFIED IDEOGRAPH + {0xB46D, 0x78CE}, //8330 #CJK UNIFIED IDEOGRAPH + {0xB46E, 0x78CF}, //8331 #CJK UNIFIED IDEOGRAPH + {0xB46F, 0x78D1}, //8332 #CJK UNIFIED IDEOGRAPH + {0xB470, 0x78D2}, //8333 #CJK UNIFIED IDEOGRAPH + {0xB471, 0x78D3}, //8334 #CJK UNIFIED IDEOGRAPH + {0xB472, 0x78D6}, //8335 #CJK UNIFIED IDEOGRAPH + {0xB473, 0x78D7}, //8336 #CJK UNIFIED IDEOGRAPH + {0xB474, 0x78D8}, //8337 #CJK UNIFIED IDEOGRAPH + {0xB475, 0x78DA}, //8338 #CJK UNIFIED IDEOGRAPH + {0xB476, 0x78DB}, //8339 #CJK UNIFIED IDEOGRAPH + {0xB477, 0x78DC}, //8340 #CJK UNIFIED IDEOGRAPH + {0xB478, 0x78DD}, //8341 #CJK UNIFIED IDEOGRAPH + {0xB479, 0x78DE}, //8342 #CJK UNIFIED IDEOGRAPH + {0xB47A, 0x78DF}, //8343 #CJK UNIFIED IDEOGRAPH + {0xB47B, 0x78E0}, //8344 #CJK UNIFIED IDEOGRAPH + {0xB47C, 0x78E1}, //8345 #CJK UNIFIED IDEOGRAPH + {0xB47D, 0x78E2}, //8346 #CJK UNIFIED IDEOGRAPH + {0xB47E, 0x78E3}, //8347 #CJK UNIFIED IDEOGRAPH + {0xB480, 0x78E4}, //8348 #CJK UNIFIED IDEOGRAPH + {0xB481, 0x78E5}, //8349 #CJK UNIFIED IDEOGRAPH + {0xB482, 0x78E6}, //8350 #CJK UNIFIED IDEOGRAPH + {0xB483, 0x78E7}, //8351 #CJK UNIFIED IDEOGRAPH + {0xB484, 0x78E9}, //8352 #CJK UNIFIED IDEOGRAPH + {0xB485, 0x78EA}, //8353 #CJK UNIFIED IDEOGRAPH + {0xB486, 0x78EB}, //8354 #CJK UNIFIED IDEOGRAPH + {0xB487, 0x78ED}, //8355 #CJK UNIFIED IDEOGRAPH + {0xB488, 0x78EE}, //8356 #CJK UNIFIED IDEOGRAPH + {0xB489, 0x78EF}, //8357 #CJK UNIFIED IDEOGRAPH + {0xB48A, 0x78F0}, //8358 #CJK UNIFIED IDEOGRAPH + {0xB48B, 0x78F1}, //8359 #CJK UNIFIED IDEOGRAPH + {0xB48C, 0x78F3}, //8360 #CJK UNIFIED IDEOGRAPH + {0xB48D, 0x78F5}, //8361 #CJK UNIFIED IDEOGRAPH + {0xB48E, 0x78F6}, //8362 #CJK UNIFIED IDEOGRAPH + {0xB48F, 0x78F8}, //8363 #CJK UNIFIED IDEOGRAPH + {0xB490, 0x78F9}, //8364 #CJK UNIFIED IDEOGRAPH + {0xB491, 0x78FB}, //8365 #CJK UNIFIED IDEOGRAPH + {0xB492, 0x78FC}, //8366 #CJK UNIFIED IDEOGRAPH + {0xB493, 0x78FD}, //8367 #CJK UNIFIED IDEOGRAPH + {0xB494, 0x78FE}, //8368 #CJK UNIFIED IDEOGRAPH + {0xB495, 0x78FF}, //8369 #CJK UNIFIED IDEOGRAPH + {0xB496, 0x7900}, //8370 #CJK UNIFIED IDEOGRAPH + {0xB497, 0x7902}, //8371 #CJK UNIFIED IDEOGRAPH + {0xB498, 0x7903}, //8372 #CJK UNIFIED IDEOGRAPH + {0xB499, 0x7904}, //8373 #CJK UNIFIED IDEOGRAPH + {0xB49A, 0x7906}, //8374 #CJK UNIFIED IDEOGRAPH + {0xB49B, 0x7907}, //8375 #CJK UNIFIED IDEOGRAPH + {0xB49C, 0x7908}, //8376 #CJK UNIFIED IDEOGRAPH + {0xB49D, 0x7909}, //8377 #CJK UNIFIED IDEOGRAPH + {0xB49E, 0x790A}, //8378 #CJK UNIFIED IDEOGRAPH + {0xB49F, 0x790B}, //8379 #CJK UNIFIED IDEOGRAPH + {0xB4A0, 0x790C}, //8380 #CJK UNIFIED IDEOGRAPH + {0xB4A1, 0x7840}, //8381 #CJK UNIFIED IDEOGRAPH + {0xB4A2, 0x50A8}, //8382 #CJK UNIFIED IDEOGRAPH + {0xB4A3, 0x77D7}, //8383 #CJK UNIFIED IDEOGRAPH + {0xB4A4, 0x6410}, //8384 #CJK UNIFIED IDEOGRAPH + {0xB4A5, 0x89E6}, //8385 #CJK UNIFIED IDEOGRAPH + {0xB4A6, 0x5904}, //8386 #CJK UNIFIED IDEOGRAPH + {0xB4A7, 0x63E3}, //8387 #CJK UNIFIED IDEOGRAPH + {0xB4A8, 0x5DDD}, //8388 #CJK UNIFIED IDEOGRAPH + {0xB4A9, 0x7A7F}, //8389 #CJK UNIFIED IDEOGRAPH + {0xB4AA, 0x693D}, //8390 #CJK UNIFIED IDEOGRAPH + {0xB4AB, 0x4F20}, //8391 #CJK UNIFIED IDEOGRAPH + {0xB4AC, 0x8239}, //8392 #CJK UNIFIED IDEOGRAPH + {0xB4AD, 0x5598}, //8393 #CJK UNIFIED IDEOGRAPH + {0xB4AE, 0x4E32}, //8394 #CJK UNIFIED IDEOGRAPH + {0xB4AF, 0x75AE}, //8395 #CJK UNIFIED IDEOGRAPH + {0xB4B0, 0x7A97}, //8396 #CJK UNIFIED IDEOGRAPH + {0xB4B1, 0x5E62}, //8397 #CJK UNIFIED IDEOGRAPH + {0xB4B2, 0x5E8A}, //8398 #CJK UNIFIED IDEOGRAPH + {0xB4B3, 0x95EF}, //8399 #CJK UNIFIED IDEOGRAPH + {0xB4B4, 0x521B}, //8400 #CJK UNIFIED IDEOGRAPH + {0xB4B5, 0x5439}, //8401 #CJK UNIFIED IDEOGRAPH + {0xB4B6, 0x708A}, //8402 #CJK UNIFIED IDEOGRAPH + {0xB4B7, 0x6376}, //8403 #CJK UNIFIED IDEOGRAPH + {0xB4B8, 0x9524}, //8404 #CJK UNIFIED IDEOGRAPH + {0xB4B9, 0x5782}, //8405 #CJK UNIFIED IDEOGRAPH + {0xB4BA, 0x6625}, //8406 #CJK UNIFIED IDEOGRAPH + {0xB4BB, 0x693F}, //8407 #CJK UNIFIED IDEOGRAPH + {0xB4BC, 0x9187}, //8408 #CJK UNIFIED IDEOGRAPH + {0xB4BD, 0x5507}, //8409 #CJK UNIFIED IDEOGRAPH + {0xB4BE, 0x6DF3}, //8410 #CJK UNIFIED IDEOGRAPH + {0xB4BF, 0x7EAF}, //8411 #CJK UNIFIED IDEOGRAPH + {0xB4C0, 0x8822}, //8412 #CJK UNIFIED IDEOGRAPH + {0xB4C1, 0x6233}, //8413 #CJK UNIFIED IDEOGRAPH + {0xB4C2, 0x7EF0}, //8414 #CJK UNIFIED IDEOGRAPH + {0xB4C3, 0x75B5}, //8415 #CJK UNIFIED IDEOGRAPH + {0xB4C4, 0x8328}, //8416 #CJK UNIFIED IDEOGRAPH + {0xB4C5, 0x78C1}, //8417 #CJK UNIFIED IDEOGRAPH + {0xB4C6, 0x96CC}, //8418 #CJK UNIFIED IDEOGRAPH + {0xB4C7, 0x8F9E}, //8419 #CJK UNIFIED IDEOGRAPH + {0xB4C8, 0x6148}, //8420 #CJK UNIFIED IDEOGRAPH + {0xB4C9, 0x74F7}, //8421 #CJK UNIFIED IDEOGRAPH + {0xB4CA, 0x8BCD}, //8422 #CJK UNIFIED IDEOGRAPH + {0xB4CB, 0x6B64}, //8423 #CJK UNIFIED IDEOGRAPH + {0xB4CC, 0x523A}, //8424 #CJK UNIFIED IDEOGRAPH + {0xB4CD, 0x8D50}, //8425 #CJK UNIFIED IDEOGRAPH + {0xB4CE, 0x6B21}, //8426 #CJK UNIFIED IDEOGRAPH + {0xB4CF, 0x806A}, //8427 #CJK UNIFIED IDEOGRAPH + {0xB4D0, 0x8471}, //8428 #CJK UNIFIED IDEOGRAPH + {0xB4D1, 0x56F1}, //8429 #CJK UNIFIED IDEOGRAPH + {0xB4D2, 0x5306}, //8430 #CJK UNIFIED IDEOGRAPH + {0xB4D3, 0x4ECE}, //8431 #CJK UNIFIED IDEOGRAPH + {0xB4D4, 0x4E1B}, //8432 #CJK UNIFIED IDEOGRAPH + {0xB4D5, 0x51D1}, //8433 #CJK UNIFIED IDEOGRAPH + {0xB4D6, 0x7C97}, //8434 #CJK UNIFIED IDEOGRAPH + {0xB4D7, 0x918B}, //8435 #CJK UNIFIED IDEOGRAPH + {0xB4D8, 0x7C07}, //8436 #CJK UNIFIED IDEOGRAPH + {0xB4D9, 0x4FC3}, //8437 #CJK UNIFIED IDEOGRAPH + {0xB4DA, 0x8E7F}, //8438 #CJK UNIFIED IDEOGRAPH + {0xB4DB, 0x7BE1}, //8439 #CJK UNIFIED IDEOGRAPH + {0xB4DC, 0x7A9C}, //8440 #CJK UNIFIED IDEOGRAPH + {0xB4DD, 0x6467}, //8441 #CJK UNIFIED IDEOGRAPH + {0xB4DE, 0x5D14}, //8442 #CJK UNIFIED IDEOGRAPH + {0xB4DF, 0x50AC}, //8443 #CJK UNIFIED IDEOGRAPH + {0xB4E0, 0x8106}, //8444 #CJK UNIFIED IDEOGRAPH + {0xB4E1, 0x7601}, //8445 #CJK UNIFIED IDEOGRAPH + {0xB4E2, 0x7CB9}, //8446 #CJK UNIFIED IDEOGRAPH + {0xB4E3, 0x6DEC}, //8447 #CJK UNIFIED IDEOGRAPH + {0xB4E4, 0x7FE0}, //8448 #CJK UNIFIED IDEOGRAPH + {0xB4E5, 0x6751}, //8449 #CJK UNIFIED IDEOGRAPH + {0xB4E6, 0x5B58}, //8450 #CJK UNIFIED IDEOGRAPH + {0xB4E7, 0x5BF8}, //8451 #CJK UNIFIED IDEOGRAPH + {0xB4E8, 0x78CB}, //8452 #CJK UNIFIED IDEOGRAPH + {0xB4E9, 0x64AE}, //8453 #CJK UNIFIED IDEOGRAPH + {0xB4EA, 0x6413}, //8454 #CJK UNIFIED IDEOGRAPH + {0xB4EB, 0x63AA}, //8455 #CJK UNIFIED IDEOGRAPH + {0xB4EC, 0x632B}, //8456 #CJK UNIFIED IDEOGRAPH + {0xB4ED, 0x9519}, //8457 #CJK UNIFIED IDEOGRAPH + {0xB4EE, 0x642D}, //8458 #CJK UNIFIED IDEOGRAPH + {0xB4EF, 0x8FBE}, //8459 #CJK UNIFIED IDEOGRAPH + {0xB4F0, 0x7B54}, //8460 #CJK UNIFIED IDEOGRAPH + {0xB4F1, 0x7629}, //8461 #CJK UNIFIED IDEOGRAPH + {0xB4F2, 0x6253}, //8462 #CJK UNIFIED IDEOGRAPH + {0xB4F3, 0x5927}, //8463 #CJK UNIFIED IDEOGRAPH + {0xB4F4, 0x5446}, //8464 #CJK UNIFIED IDEOGRAPH + {0xB4F5, 0x6B79}, //8465 #CJK UNIFIED IDEOGRAPH + {0xB4F6, 0x50A3}, //8466 #CJK UNIFIED IDEOGRAPH + {0xB4F7, 0x6234}, //8467 #CJK UNIFIED IDEOGRAPH + {0xB4F8, 0x5E26}, //8468 #CJK UNIFIED IDEOGRAPH + {0xB4F9, 0x6B86}, //8469 #CJK UNIFIED IDEOGRAPH + {0xB4FA, 0x4EE3}, //8470 #CJK UNIFIED IDEOGRAPH + {0xB4FB, 0x8D37}, //8471 #CJK UNIFIED IDEOGRAPH + {0xB4FC, 0x888B}, //8472 #CJK UNIFIED IDEOGRAPH + {0xB4FD, 0x5F85}, //8473 #CJK UNIFIED IDEOGRAPH + {0xB4FE, 0x902E}, //8474 #CJK UNIFIED IDEOGRAPH + {0xB540, 0x790D}, //8475 #CJK UNIFIED IDEOGRAPH + {0xB541, 0x790E}, //8476 #CJK UNIFIED IDEOGRAPH + {0xB542, 0x790F}, //8477 #CJK UNIFIED IDEOGRAPH + {0xB543, 0x7910}, //8478 #CJK UNIFIED IDEOGRAPH + {0xB544, 0x7911}, //8479 #CJK UNIFIED IDEOGRAPH + {0xB545, 0x7912}, //8480 #CJK UNIFIED IDEOGRAPH + {0xB546, 0x7914}, //8481 #CJK UNIFIED IDEOGRAPH + {0xB547, 0x7915}, //8482 #CJK UNIFIED IDEOGRAPH + {0xB548, 0x7916}, //8483 #CJK UNIFIED IDEOGRAPH + {0xB549, 0x7917}, //8484 #CJK UNIFIED IDEOGRAPH + {0xB54A, 0x7918}, //8485 #CJK UNIFIED IDEOGRAPH + {0xB54B, 0x7919}, //8486 #CJK UNIFIED IDEOGRAPH + {0xB54C, 0x791A}, //8487 #CJK UNIFIED IDEOGRAPH + {0xB54D, 0x791B}, //8488 #CJK UNIFIED IDEOGRAPH + {0xB54E, 0x791C}, //8489 #CJK UNIFIED IDEOGRAPH + {0xB54F, 0x791D}, //8490 #CJK UNIFIED IDEOGRAPH + {0xB550, 0x791F}, //8491 #CJK UNIFIED IDEOGRAPH + {0xB551, 0x7920}, //8492 #CJK UNIFIED IDEOGRAPH + {0xB552, 0x7921}, //8493 #CJK UNIFIED IDEOGRAPH + {0xB553, 0x7922}, //8494 #CJK UNIFIED IDEOGRAPH + {0xB554, 0x7923}, //8495 #CJK UNIFIED IDEOGRAPH + {0xB555, 0x7925}, //8496 #CJK UNIFIED IDEOGRAPH + {0xB556, 0x7926}, //8497 #CJK UNIFIED IDEOGRAPH + {0xB557, 0x7927}, //8498 #CJK UNIFIED IDEOGRAPH + {0xB558, 0x7928}, //8499 #CJK UNIFIED IDEOGRAPH + {0xB559, 0x7929}, //8500 #CJK UNIFIED IDEOGRAPH + {0xB55A, 0x792A}, //8501 #CJK UNIFIED IDEOGRAPH + {0xB55B, 0x792B}, //8502 #CJK UNIFIED IDEOGRAPH + {0xB55C, 0x792C}, //8503 #CJK UNIFIED IDEOGRAPH + {0xB55D, 0x792D}, //8504 #CJK UNIFIED IDEOGRAPH + {0xB55E, 0x792E}, //8505 #CJK UNIFIED IDEOGRAPH + {0xB55F, 0x792F}, //8506 #CJK UNIFIED IDEOGRAPH + {0xB560, 0x7930}, //8507 #CJK UNIFIED IDEOGRAPH + {0xB561, 0x7931}, //8508 #CJK UNIFIED IDEOGRAPH + {0xB562, 0x7932}, //8509 #CJK UNIFIED IDEOGRAPH + {0xB563, 0x7933}, //8510 #CJK UNIFIED IDEOGRAPH + {0xB564, 0x7935}, //8511 #CJK UNIFIED IDEOGRAPH + {0xB565, 0x7936}, //8512 #CJK UNIFIED IDEOGRAPH + {0xB566, 0x7937}, //8513 #CJK UNIFIED IDEOGRAPH + {0xB567, 0x7938}, //8514 #CJK UNIFIED IDEOGRAPH + {0xB568, 0x7939}, //8515 #CJK UNIFIED IDEOGRAPH + {0xB569, 0x793D}, //8516 #CJK UNIFIED IDEOGRAPH + {0xB56A, 0x793F}, //8517 #CJK UNIFIED IDEOGRAPH + {0xB56B, 0x7942}, //8518 #CJK UNIFIED IDEOGRAPH + {0xB56C, 0x7943}, //8519 #CJK UNIFIED IDEOGRAPH + {0xB56D, 0x7944}, //8520 #CJK UNIFIED IDEOGRAPH + {0xB56E, 0x7945}, //8521 #CJK UNIFIED IDEOGRAPH + {0xB56F, 0x7947}, //8522 #CJK UNIFIED IDEOGRAPH + {0xB570, 0x794A}, //8523 #CJK UNIFIED IDEOGRAPH + {0xB571, 0x794B}, //8524 #CJK UNIFIED IDEOGRAPH + {0xB572, 0x794C}, //8525 #CJK UNIFIED IDEOGRAPH + {0xB573, 0x794D}, //8526 #CJK UNIFIED IDEOGRAPH + {0xB574, 0x794E}, //8527 #CJK UNIFIED IDEOGRAPH + {0xB575, 0x794F}, //8528 #CJK UNIFIED IDEOGRAPH + {0xB576, 0x7950}, //8529 #CJK UNIFIED IDEOGRAPH + {0xB577, 0x7951}, //8530 #CJK UNIFIED IDEOGRAPH + {0xB578, 0x7952}, //8531 #CJK UNIFIED IDEOGRAPH + {0xB579, 0x7954}, //8532 #CJK UNIFIED IDEOGRAPH + {0xB57A, 0x7955}, //8533 #CJK UNIFIED IDEOGRAPH + {0xB57B, 0x7958}, //8534 #CJK UNIFIED IDEOGRAPH + {0xB57C, 0x7959}, //8535 #CJK UNIFIED IDEOGRAPH + {0xB57D, 0x7961}, //8536 #CJK UNIFIED IDEOGRAPH + {0xB57E, 0x7963}, //8537 #CJK UNIFIED IDEOGRAPH + {0xB580, 0x7964}, //8538 #CJK UNIFIED IDEOGRAPH + {0xB581, 0x7966}, //8539 #CJK UNIFIED IDEOGRAPH + {0xB582, 0x7969}, //8540 #CJK UNIFIED IDEOGRAPH + {0xB583, 0x796A}, //8541 #CJK UNIFIED IDEOGRAPH + {0xB584, 0x796B}, //8542 #CJK UNIFIED IDEOGRAPH + {0xB585, 0x796C}, //8543 #CJK UNIFIED IDEOGRAPH + {0xB586, 0x796E}, //8544 #CJK UNIFIED IDEOGRAPH + {0xB587, 0x7970}, //8545 #CJK UNIFIED IDEOGRAPH + {0xB588, 0x7971}, //8546 #CJK UNIFIED IDEOGRAPH + {0xB589, 0x7972}, //8547 #CJK UNIFIED IDEOGRAPH + {0xB58A, 0x7973}, //8548 #CJK UNIFIED IDEOGRAPH + {0xB58B, 0x7974}, //8549 #CJK UNIFIED IDEOGRAPH + {0xB58C, 0x7975}, //8550 #CJK UNIFIED IDEOGRAPH + {0xB58D, 0x7976}, //8551 #CJK UNIFIED IDEOGRAPH + {0xB58E, 0x7979}, //8552 #CJK UNIFIED IDEOGRAPH + {0xB58F, 0x797B}, //8553 #CJK UNIFIED IDEOGRAPH + {0xB590, 0x797C}, //8554 #CJK UNIFIED IDEOGRAPH + {0xB591, 0x797D}, //8555 #CJK UNIFIED IDEOGRAPH + {0xB592, 0x797E}, //8556 #CJK UNIFIED IDEOGRAPH + {0xB593, 0x797F}, //8557 #CJK UNIFIED IDEOGRAPH + {0xB594, 0x7982}, //8558 #CJK UNIFIED IDEOGRAPH + {0xB595, 0x7983}, //8559 #CJK UNIFIED IDEOGRAPH + {0xB596, 0x7986}, //8560 #CJK UNIFIED IDEOGRAPH + {0xB597, 0x7987}, //8561 #CJK UNIFIED IDEOGRAPH + {0xB598, 0x7988}, //8562 #CJK UNIFIED IDEOGRAPH + {0xB599, 0x7989}, //8563 #CJK UNIFIED IDEOGRAPH + {0xB59A, 0x798B}, //8564 #CJK UNIFIED IDEOGRAPH + {0xB59B, 0x798C}, //8565 #CJK UNIFIED IDEOGRAPH + {0xB59C, 0x798D}, //8566 #CJK UNIFIED IDEOGRAPH + {0xB59D, 0x798E}, //8567 #CJK UNIFIED IDEOGRAPH + {0xB59E, 0x7990}, //8568 #CJK UNIFIED IDEOGRAPH + {0xB59F, 0x7991}, //8569 #CJK UNIFIED IDEOGRAPH + {0xB5A0, 0x7992}, //8570 #CJK UNIFIED IDEOGRAPH + {0xB5A1, 0x6020}, //8571 #CJK UNIFIED IDEOGRAPH + {0xB5A2, 0x803D}, //8572 #CJK UNIFIED IDEOGRAPH + {0xB5A3, 0x62C5}, //8573 #CJK UNIFIED IDEOGRAPH + {0xB5A4, 0x4E39}, //8574 #CJK UNIFIED IDEOGRAPH + {0xB5A5, 0x5355}, //8575 #CJK UNIFIED IDEOGRAPH + {0xB5A6, 0x90F8}, //8576 #CJK UNIFIED IDEOGRAPH + {0xB5A7, 0x63B8}, //8577 #CJK UNIFIED IDEOGRAPH + {0xB5A8, 0x80C6}, //8578 #CJK UNIFIED IDEOGRAPH + {0xB5A9, 0x65E6}, //8579 #CJK UNIFIED IDEOGRAPH + {0xB5AA, 0x6C2E}, //8580 #CJK UNIFIED IDEOGRAPH + {0xB5AB, 0x4F46}, //8581 #CJK UNIFIED IDEOGRAPH + {0xB5AC, 0x60EE}, //8582 #CJK UNIFIED IDEOGRAPH + {0xB5AD, 0x6DE1}, //8583 #CJK UNIFIED IDEOGRAPH + {0xB5AE, 0x8BDE}, //8584 #CJK UNIFIED IDEOGRAPH + {0xB5AF, 0x5F39}, //8585 #CJK UNIFIED IDEOGRAPH + {0xB5B0, 0x86CB}, //8586 #CJK UNIFIED IDEOGRAPH + {0xB5B1, 0x5F53}, //8587 #CJK UNIFIED IDEOGRAPH + {0xB5B2, 0x6321}, //8588 #CJK UNIFIED IDEOGRAPH + {0xB5B3, 0x515A}, //8589 #CJK UNIFIED IDEOGRAPH + {0xB5B4, 0x8361}, //8590 #CJK UNIFIED IDEOGRAPH + {0xB5B5, 0x6863}, //8591 #CJK UNIFIED IDEOGRAPH + {0xB5B6, 0x5200}, //8592 #CJK UNIFIED IDEOGRAPH + {0xB5B7, 0x6363}, //8593 #CJK UNIFIED IDEOGRAPH + {0xB5B8, 0x8E48}, //8594 #CJK UNIFIED IDEOGRAPH + {0xB5B9, 0x5012}, //8595 #CJK UNIFIED IDEOGRAPH + {0xB5BA, 0x5C9B}, //8596 #CJK UNIFIED IDEOGRAPH + {0xB5BB, 0x7977}, //8597 #CJK UNIFIED IDEOGRAPH + {0xB5BC, 0x5BFC}, //8598 #CJK UNIFIED IDEOGRAPH + {0xB5BD, 0x5230}, //8599 #CJK UNIFIED IDEOGRAPH + {0xB5BE, 0x7A3B}, //8600 #CJK UNIFIED IDEOGRAPH + {0xB5BF, 0x60BC}, //8601 #CJK UNIFIED IDEOGRAPH + {0xB5C0, 0x9053}, //8602 #CJK UNIFIED IDEOGRAPH + {0xB5C1, 0x76D7}, //8603 #CJK UNIFIED IDEOGRAPH + {0xB5C2, 0x5FB7}, //8604 #CJK UNIFIED IDEOGRAPH + {0xB5C3, 0x5F97}, //8605 #CJK UNIFIED IDEOGRAPH + {0xB5C4, 0x7684}, //8606 #CJK UNIFIED IDEOGRAPH + {0xB5C5, 0x8E6C}, //8607 #CJK UNIFIED IDEOGRAPH + {0xB5C6, 0x706F}, //8608 #CJK UNIFIED IDEOGRAPH + {0xB5C7, 0x767B}, //8609 #CJK UNIFIED IDEOGRAPH + {0xB5C8, 0x7B49}, //8610 #CJK UNIFIED IDEOGRAPH + {0xB5C9, 0x77AA}, //8611 #CJK UNIFIED IDEOGRAPH + {0xB5CA, 0x51F3}, //8612 #CJK UNIFIED IDEOGRAPH + {0xB5CB, 0x9093}, //8613 #CJK UNIFIED IDEOGRAPH + {0xB5CC, 0x5824}, //8614 #CJK UNIFIED IDEOGRAPH + {0xB5CD, 0x4F4E}, //8615 #CJK UNIFIED IDEOGRAPH + {0xB5CE, 0x6EF4}, //8616 #CJK UNIFIED IDEOGRAPH + {0xB5CF, 0x8FEA}, //8617 #CJK UNIFIED IDEOGRAPH + {0xB5D0, 0x654C}, //8618 #CJK UNIFIED IDEOGRAPH + {0xB5D1, 0x7B1B}, //8619 #CJK UNIFIED IDEOGRAPH + {0xB5D2, 0x72C4}, //8620 #CJK UNIFIED IDEOGRAPH + {0xB5D3, 0x6DA4}, //8621 #CJK UNIFIED IDEOGRAPH + {0xB5D4, 0x7FDF}, //8622 #CJK UNIFIED IDEOGRAPH + {0xB5D5, 0x5AE1}, //8623 #CJK UNIFIED IDEOGRAPH + {0xB5D6, 0x62B5}, //8624 #CJK UNIFIED IDEOGRAPH + {0xB5D7, 0x5E95}, //8625 #CJK UNIFIED IDEOGRAPH + {0xB5D8, 0x5730}, //8626 #CJK UNIFIED IDEOGRAPH + {0xB5D9, 0x8482}, //8627 #CJK UNIFIED IDEOGRAPH + {0xB5DA, 0x7B2C}, //8628 #CJK UNIFIED IDEOGRAPH + {0xB5DB, 0x5E1D}, //8629 #CJK UNIFIED IDEOGRAPH + {0xB5DC, 0x5F1F}, //8630 #CJK UNIFIED IDEOGRAPH + {0xB5DD, 0x9012}, //8631 #CJK UNIFIED IDEOGRAPH + {0xB5DE, 0x7F14}, //8632 #CJK UNIFIED IDEOGRAPH + {0xB5DF, 0x98A0}, //8633 #CJK UNIFIED IDEOGRAPH + {0xB5E0, 0x6382}, //8634 #CJK UNIFIED IDEOGRAPH + {0xB5E1, 0x6EC7}, //8635 #CJK UNIFIED IDEOGRAPH + {0xB5E2, 0x7898}, //8636 #CJK UNIFIED IDEOGRAPH + {0xB5E3, 0x70B9}, //8637 #CJK UNIFIED IDEOGRAPH + {0xB5E4, 0x5178}, //8638 #CJK UNIFIED IDEOGRAPH + {0xB5E5, 0x975B}, //8639 #CJK UNIFIED IDEOGRAPH + {0xB5E6, 0x57AB}, //8640 #CJK UNIFIED IDEOGRAPH + {0xB5E7, 0x7535}, //8641 #CJK UNIFIED IDEOGRAPH + {0xB5E8, 0x4F43}, //8642 #CJK UNIFIED IDEOGRAPH + {0xB5E9, 0x7538}, //8643 #CJK UNIFIED IDEOGRAPH + {0xB5EA, 0x5E97}, //8644 #CJK UNIFIED IDEOGRAPH + {0xB5EB, 0x60E6}, //8645 #CJK UNIFIED IDEOGRAPH + {0xB5EC, 0x5960}, //8646 #CJK UNIFIED IDEOGRAPH + {0xB5ED, 0x6DC0}, //8647 #CJK UNIFIED IDEOGRAPH + {0xB5EE, 0x6BBF}, //8648 #CJK UNIFIED IDEOGRAPH + {0xB5EF, 0x7889}, //8649 #CJK UNIFIED IDEOGRAPH + {0xB5F0, 0x53FC}, //8650 #CJK UNIFIED IDEOGRAPH + {0xB5F1, 0x96D5}, //8651 #CJK UNIFIED IDEOGRAPH + {0xB5F2, 0x51CB}, //8652 #CJK UNIFIED IDEOGRAPH + {0xB5F3, 0x5201}, //8653 #CJK UNIFIED IDEOGRAPH + {0xB5F4, 0x6389}, //8654 #CJK UNIFIED IDEOGRAPH + {0xB5F5, 0x540A}, //8655 #CJK UNIFIED IDEOGRAPH + {0xB5F6, 0x9493}, //8656 #CJK UNIFIED IDEOGRAPH + {0xB5F7, 0x8C03}, //8657 #CJK UNIFIED IDEOGRAPH + {0xB5F8, 0x8DCC}, //8658 #CJK UNIFIED IDEOGRAPH + {0xB5F9, 0x7239}, //8659 #CJK UNIFIED IDEOGRAPH + {0xB5FA, 0x789F}, //8660 #CJK UNIFIED IDEOGRAPH + {0xB5FB, 0x8776}, //8661 #CJK UNIFIED IDEOGRAPH + {0xB5FC, 0x8FED}, //8662 #CJK UNIFIED IDEOGRAPH + {0xB5FD, 0x8C0D}, //8663 #CJK UNIFIED IDEOGRAPH + {0xB5FE, 0x53E0}, //8664 #CJK UNIFIED IDEOGRAPH + {0xB640, 0x7993}, //8665 #CJK UNIFIED IDEOGRAPH + {0xB641, 0x7994}, //8666 #CJK UNIFIED IDEOGRAPH + {0xB642, 0x7995}, //8667 #CJK UNIFIED IDEOGRAPH + {0xB643, 0x7996}, //8668 #CJK UNIFIED IDEOGRAPH + {0xB644, 0x7997}, //8669 #CJK UNIFIED IDEOGRAPH + {0xB645, 0x7998}, //8670 #CJK UNIFIED IDEOGRAPH + {0xB646, 0x7999}, //8671 #CJK UNIFIED IDEOGRAPH + {0xB647, 0x799B}, //8672 #CJK UNIFIED IDEOGRAPH + {0xB648, 0x799C}, //8673 #CJK UNIFIED IDEOGRAPH + {0xB649, 0x799D}, //8674 #CJK UNIFIED IDEOGRAPH + {0xB64A, 0x799E}, //8675 #CJK UNIFIED IDEOGRAPH + {0xB64B, 0x799F}, //8676 #CJK UNIFIED IDEOGRAPH + {0xB64C, 0x79A0}, //8677 #CJK UNIFIED IDEOGRAPH + {0xB64D, 0x79A1}, //8678 #CJK UNIFIED IDEOGRAPH + {0xB64E, 0x79A2}, //8679 #CJK UNIFIED IDEOGRAPH + {0xB64F, 0x79A3}, //8680 #CJK UNIFIED IDEOGRAPH + {0xB650, 0x79A4}, //8681 #CJK UNIFIED IDEOGRAPH + {0xB651, 0x79A5}, //8682 #CJK UNIFIED IDEOGRAPH + {0xB652, 0x79A6}, //8683 #CJK UNIFIED IDEOGRAPH + {0xB653, 0x79A8}, //8684 #CJK UNIFIED IDEOGRAPH + {0xB654, 0x79A9}, //8685 #CJK UNIFIED IDEOGRAPH + {0xB655, 0x79AA}, //8686 #CJK UNIFIED IDEOGRAPH + {0xB656, 0x79AB}, //8687 #CJK UNIFIED IDEOGRAPH + {0xB657, 0x79AC}, //8688 #CJK UNIFIED IDEOGRAPH + {0xB658, 0x79AD}, //8689 #CJK UNIFIED IDEOGRAPH + {0xB659, 0x79AE}, //8690 #CJK UNIFIED IDEOGRAPH + {0xB65A, 0x79AF}, //8691 #CJK UNIFIED IDEOGRAPH + {0xB65B, 0x79B0}, //8692 #CJK UNIFIED IDEOGRAPH + {0xB65C, 0x79B1}, //8693 #CJK UNIFIED IDEOGRAPH + {0xB65D, 0x79B2}, //8694 #CJK UNIFIED IDEOGRAPH + {0xB65E, 0x79B4}, //8695 #CJK UNIFIED IDEOGRAPH + {0xB65F, 0x79B5}, //8696 #CJK UNIFIED IDEOGRAPH + {0xB660, 0x79B6}, //8697 #CJK UNIFIED IDEOGRAPH + {0xB661, 0x79B7}, //8698 #CJK UNIFIED IDEOGRAPH + {0xB662, 0x79B8}, //8699 #CJK UNIFIED IDEOGRAPH + {0xB663, 0x79BC}, //8700 #CJK UNIFIED IDEOGRAPH + {0xB664, 0x79BF}, //8701 #CJK UNIFIED IDEOGRAPH + {0xB665, 0x79C2}, //8702 #CJK UNIFIED IDEOGRAPH + {0xB666, 0x79C4}, //8703 #CJK UNIFIED IDEOGRAPH + {0xB667, 0x79C5}, //8704 #CJK UNIFIED IDEOGRAPH + {0xB668, 0x79C7}, //8705 #CJK UNIFIED IDEOGRAPH + {0xB669, 0x79C8}, //8706 #CJK UNIFIED IDEOGRAPH + {0xB66A, 0x79CA}, //8707 #CJK UNIFIED IDEOGRAPH + {0xB66B, 0x79CC}, //8708 #CJK UNIFIED IDEOGRAPH + {0xB66C, 0x79CE}, //8709 #CJK UNIFIED IDEOGRAPH + {0xB66D, 0x79CF}, //8710 #CJK UNIFIED IDEOGRAPH + {0xB66E, 0x79D0}, //8711 #CJK UNIFIED IDEOGRAPH + {0xB66F, 0x79D3}, //8712 #CJK UNIFIED IDEOGRAPH + {0xB670, 0x79D4}, //8713 #CJK UNIFIED IDEOGRAPH + {0xB671, 0x79D6}, //8714 #CJK UNIFIED IDEOGRAPH + {0xB672, 0x79D7}, //8715 #CJK UNIFIED IDEOGRAPH + {0xB673, 0x79D9}, //8716 #CJK UNIFIED IDEOGRAPH + {0xB674, 0x79DA}, //8717 #CJK UNIFIED IDEOGRAPH + {0xB675, 0x79DB}, //8718 #CJK UNIFIED IDEOGRAPH + {0xB676, 0x79DC}, //8719 #CJK UNIFIED IDEOGRAPH + {0xB677, 0x79DD}, //8720 #CJK UNIFIED IDEOGRAPH + {0xB678, 0x79DE}, //8721 #CJK UNIFIED IDEOGRAPH + {0xB679, 0x79E0}, //8722 #CJK UNIFIED IDEOGRAPH + {0xB67A, 0x79E1}, //8723 #CJK UNIFIED IDEOGRAPH + {0xB67B, 0x79E2}, //8724 #CJK UNIFIED IDEOGRAPH + {0xB67C, 0x79E5}, //8725 #CJK UNIFIED IDEOGRAPH + {0xB67D, 0x79E8}, //8726 #CJK UNIFIED IDEOGRAPH + {0xB67E, 0x79EA}, //8727 #CJK UNIFIED IDEOGRAPH + {0xB680, 0x79EC}, //8728 #CJK UNIFIED IDEOGRAPH + {0xB681, 0x79EE}, //8729 #CJK UNIFIED IDEOGRAPH + {0xB682, 0x79F1}, //8730 #CJK UNIFIED IDEOGRAPH + {0xB683, 0x79F2}, //8731 #CJK UNIFIED IDEOGRAPH + {0xB684, 0x79F3}, //8732 #CJK UNIFIED IDEOGRAPH + {0xB685, 0x79F4}, //8733 #CJK UNIFIED IDEOGRAPH + {0xB686, 0x79F5}, //8734 #CJK UNIFIED IDEOGRAPH + {0xB687, 0x79F6}, //8735 #CJK UNIFIED IDEOGRAPH + {0xB688, 0x79F7}, //8736 #CJK UNIFIED IDEOGRAPH + {0xB689, 0x79F9}, //8737 #CJK UNIFIED IDEOGRAPH + {0xB68A, 0x79FA}, //8738 #CJK UNIFIED IDEOGRAPH + {0xB68B, 0x79FC}, //8739 #CJK UNIFIED IDEOGRAPH + {0xB68C, 0x79FE}, //8740 #CJK UNIFIED IDEOGRAPH + {0xB68D, 0x79FF}, //8741 #CJK UNIFIED IDEOGRAPH + {0xB68E, 0x7A01}, //8742 #CJK UNIFIED IDEOGRAPH + {0xB68F, 0x7A04}, //8743 #CJK UNIFIED IDEOGRAPH + {0xB690, 0x7A05}, //8744 #CJK UNIFIED IDEOGRAPH + {0xB691, 0x7A07}, //8745 #CJK UNIFIED IDEOGRAPH + {0xB692, 0x7A08}, //8746 #CJK UNIFIED IDEOGRAPH + {0xB693, 0x7A09}, //8747 #CJK UNIFIED IDEOGRAPH + {0xB694, 0x7A0A}, //8748 #CJK UNIFIED IDEOGRAPH + {0xB695, 0x7A0C}, //8749 #CJK UNIFIED IDEOGRAPH + {0xB696, 0x7A0F}, //8750 #CJK UNIFIED IDEOGRAPH + {0xB697, 0x7A10}, //8751 #CJK UNIFIED IDEOGRAPH + {0xB698, 0x7A11}, //8752 #CJK UNIFIED IDEOGRAPH + {0xB699, 0x7A12}, //8753 #CJK UNIFIED IDEOGRAPH + {0xB69A, 0x7A13}, //8754 #CJK UNIFIED IDEOGRAPH + {0xB69B, 0x7A15}, //8755 #CJK UNIFIED IDEOGRAPH + {0xB69C, 0x7A16}, //8756 #CJK UNIFIED IDEOGRAPH + {0xB69D, 0x7A18}, //8757 #CJK UNIFIED IDEOGRAPH + {0xB69E, 0x7A19}, //8758 #CJK UNIFIED IDEOGRAPH + {0xB69F, 0x7A1B}, //8759 #CJK UNIFIED IDEOGRAPH + {0xB6A0, 0x7A1C}, //8760 #CJK UNIFIED IDEOGRAPH + {0xB6A1, 0x4E01}, //8761 #CJK UNIFIED IDEOGRAPH + {0xB6A2, 0x76EF}, //8762 #CJK UNIFIED IDEOGRAPH + {0xB6A3, 0x53EE}, //8763 #CJK UNIFIED IDEOGRAPH + {0xB6A4, 0x9489}, //8764 #CJK UNIFIED IDEOGRAPH + {0xB6A5, 0x9876}, //8765 #CJK UNIFIED IDEOGRAPH + {0xB6A6, 0x9F0E}, //8766 #CJK UNIFIED IDEOGRAPH + {0xB6A7, 0x952D}, //8767 #CJK UNIFIED IDEOGRAPH + {0xB6A8, 0x5B9A}, //8768 #CJK UNIFIED IDEOGRAPH + {0xB6A9, 0x8BA2}, //8769 #CJK UNIFIED IDEOGRAPH + {0xB6AA, 0x4E22}, //8770 #CJK UNIFIED IDEOGRAPH + {0xB6AB, 0x4E1C}, //8771 #CJK UNIFIED IDEOGRAPH + {0xB6AC, 0x51AC}, //8772 #CJK UNIFIED IDEOGRAPH + {0xB6AD, 0x8463}, //8773 #CJK UNIFIED IDEOGRAPH + {0xB6AE, 0x61C2}, //8774 #CJK UNIFIED IDEOGRAPH + {0xB6AF, 0x52A8}, //8775 #CJK UNIFIED IDEOGRAPH + {0xB6B0, 0x680B}, //8776 #CJK UNIFIED IDEOGRAPH + {0xB6B1, 0x4F97}, //8777 #CJK UNIFIED IDEOGRAPH + {0xB6B2, 0x606B}, //8778 #CJK UNIFIED IDEOGRAPH + {0xB6B3, 0x51BB}, //8779 #CJK UNIFIED IDEOGRAPH + {0xB6B4, 0x6D1E}, //8780 #CJK UNIFIED IDEOGRAPH + {0xB6B5, 0x515C}, //8781 #CJK UNIFIED IDEOGRAPH + {0xB6B6, 0x6296}, //8782 #CJK UNIFIED IDEOGRAPH + {0xB6B7, 0x6597}, //8783 #CJK UNIFIED IDEOGRAPH + {0xB6B8, 0x9661}, //8784 #CJK UNIFIED IDEOGRAPH + {0xB6B9, 0x8C46}, //8785 #CJK UNIFIED IDEOGRAPH + {0xB6BA, 0x9017}, //8786 #CJK UNIFIED IDEOGRAPH + {0xB6BB, 0x75D8}, //8787 #CJK UNIFIED IDEOGRAPH + {0xB6BC, 0x90FD}, //8788 #CJK UNIFIED IDEOGRAPH + {0xB6BD, 0x7763}, //8789 #CJK UNIFIED IDEOGRAPH + {0xB6BE, 0x6BD2}, //8790 #CJK UNIFIED IDEOGRAPH + {0xB6BF, 0x728A}, //8791 #CJK UNIFIED IDEOGRAPH + {0xB6C0, 0x72EC}, //8792 #CJK UNIFIED IDEOGRAPH + {0xB6C1, 0x8BFB}, //8793 #CJK UNIFIED IDEOGRAPH + {0xB6C2, 0x5835}, //8794 #CJK UNIFIED IDEOGRAPH + {0xB6C3, 0x7779}, //8795 #CJK UNIFIED IDEOGRAPH + {0xB6C4, 0x8D4C}, //8796 #CJK UNIFIED IDEOGRAPH + {0xB6C5, 0x675C}, //8797 #CJK UNIFIED IDEOGRAPH + {0xB6C6, 0x9540}, //8798 #CJK UNIFIED IDEOGRAPH + {0xB6C7, 0x809A}, //8799 #CJK UNIFIED IDEOGRAPH + {0xB6C8, 0x5EA6}, //8800 #CJK UNIFIED IDEOGRAPH + {0xB6C9, 0x6E21}, //8801 #CJK UNIFIED IDEOGRAPH + {0xB6CA, 0x5992}, //8802 #CJK UNIFIED IDEOGRAPH + {0xB6CB, 0x7AEF}, //8803 #CJK UNIFIED IDEOGRAPH + {0xB6CC, 0x77ED}, //8804 #CJK UNIFIED IDEOGRAPH + {0xB6CD, 0x953B}, //8805 #CJK UNIFIED IDEOGRAPH + {0xB6CE, 0x6BB5}, //8806 #CJK UNIFIED IDEOGRAPH + {0xB6CF, 0x65AD}, //8807 #CJK UNIFIED IDEOGRAPH + {0xB6D0, 0x7F0E}, //8808 #CJK UNIFIED IDEOGRAPH + {0xB6D1, 0x5806}, //8809 #CJK UNIFIED IDEOGRAPH + {0xB6D2, 0x5151}, //8810 #CJK UNIFIED IDEOGRAPH + {0xB6D3, 0x961F}, //8811 #CJK UNIFIED IDEOGRAPH + {0xB6D4, 0x5BF9}, //8812 #CJK UNIFIED IDEOGRAPH + {0xB6D5, 0x58A9}, //8813 #CJK UNIFIED IDEOGRAPH + {0xB6D6, 0x5428}, //8814 #CJK UNIFIED IDEOGRAPH + {0xB6D7, 0x8E72}, //8815 #CJK UNIFIED IDEOGRAPH + {0xB6D8, 0x6566}, //8816 #CJK UNIFIED IDEOGRAPH + {0xB6D9, 0x987F}, //8817 #CJK UNIFIED IDEOGRAPH + {0xB6DA, 0x56E4}, //8818 #CJK UNIFIED IDEOGRAPH + {0xB6DB, 0x949D}, //8819 #CJK UNIFIED IDEOGRAPH + {0xB6DC, 0x76FE}, //8820 #CJK UNIFIED IDEOGRAPH + {0xB6DD, 0x9041}, //8821 #CJK UNIFIED IDEOGRAPH + {0xB6DE, 0x6387}, //8822 #CJK UNIFIED IDEOGRAPH + {0xB6DF, 0x54C6}, //8823 #CJK UNIFIED IDEOGRAPH + {0xB6E0, 0x591A}, //8824 #CJK UNIFIED IDEOGRAPH + {0xB6E1, 0x593A}, //8825 #CJK UNIFIED IDEOGRAPH + {0xB6E2, 0x579B}, //8826 #CJK UNIFIED IDEOGRAPH + {0xB6E3, 0x8EB2}, //8827 #CJK UNIFIED IDEOGRAPH + {0xB6E4, 0x6735}, //8828 #CJK UNIFIED IDEOGRAPH + {0xB6E5, 0x8DFA}, //8829 #CJK UNIFIED IDEOGRAPH + {0xB6E6, 0x8235}, //8830 #CJK UNIFIED IDEOGRAPH + {0xB6E7, 0x5241}, //8831 #CJK UNIFIED IDEOGRAPH + {0xB6E8, 0x60F0}, //8832 #CJK UNIFIED IDEOGRAPH + {0xB6E9, 0x5815}, //8833 #CJK UNIFIED IDEOGRAPH + {0xB6EA, 0x86FE}, //8834 #CJK UNIFIED IDEOGRAPH + {0xB6EB, 0x5CE8}, //8835 #CJK UNIFIED IDEOGRAPH + {0xB6EC, 0x9E45}, //8836 #CJK UNIFIED IDEOGRAPH + {0xB6ED, 0x4FC4}, //8837 #CJK UNIFIED IDEOGRAPH + {0xB6EE, 0x989D}, //8838 #CJK UNIFIED IDEOGRAPH + {0xB6EF, 0x8BB9}, //8839 #CJK UNIFIED IDEOGRAPH + {0xB6F0, 0x5A25}, //8840 #CJK UNIFIED IDEOGRAPH + {0xB6F1, 0x6076}, //8841 #CJK UNIFIED IDEOGRAPH + {0xB6F2, 0x5384}, //8842 #CJK UNIFIED IDEOGRAPH + {0xB6F3, 0x627C}, //8843 #CJK UNIFIED IDEOGRAPH + {0xB6F4, 0x904F}, //8844 #CJK UNIFIED IDEOGRAPH + {0xB6F5, 0x9102}, //8845 #CJK UNIFIED IDEOGRAPH + {0xB6F6, 0x997F}, //8846 #CJK UNIFIED IDEOGRAPH + {0xB6F7, 0x6069}, //8847 #CJK UNIFIED IDEOGRAPH + {0xB6F8, 0x800C}, //8848 #CJK UNIFIED IDEOGRAPH + {0xB6F9, 0x513F}, //8849 #CJK UNIFIED IDEOGRAPH + {0xB6FA, 0x8033}, //8850 #CJK UNIFIED IDEOGRAPH + {0xB6FB, 0x5C14}, //8851 #CJK UNIFIED IDEOGRAPH + {0xB6FC, 0x9975}, //8852 #CJK UNIFIED IDEOGRAPH + {0xB6FD, 0x6D31}, //8853 #CJK UNIFIED IDEOGRAPH + {0xB6FE, 0x4E8C}, //8854 #CJK UNIFIED IDEOGRAPH + {0xB740, 0x7A1D}, //8855 #CJK UNIFIED IDEOGRAPH + {0xB741, 0x7A1F}, //8856 #CJK UNIFIED IDEOGRAPH + {0xB742, 0x7A21}, //8857 #CJK UNIFIED IDEOGRAPH + {0xB743, 0x7A22}, //8858 #CJK UNIFIED IDEOGRAPH + {0xB744, 0x7A24}, //8859 #CJK UNIFIED IDEOGRAPH + {0xB745, 0x7A25}, //8860 #CJK UNIFIED IDEOGRAPH + {0xB746, 0x7A26}, //8861 #CJK UNIFIED IDEOGRAPH + {0xB747, 0x7A27}, //8862 #CJK UNIFIED IDEOGRAPH + {0xB748, 0x7A28}, //8863 #CJK UNIFIED IDEOGRAPH + {0xB749, 0x7A29}, //8864 #CJK UNIFIED IDEOGRAPH + {0xB74A, 0x7A2A}, //8865 #CJK UNIFIED IDEOGRAPH + {0xB74B, 0x7A2B}, //8866 #CJK UNIFIED IDEOGRAPH + {0xB74C, 0x7A2C}, //8867 #CJK UNIFIED IDEOGRAPH + {0xB74D, 0x7A2D}, //8868 #CJK UNIFIED IDEOGRAPH + {0xB74E, 0x7A2E}, //8869 #CJK UNIFIED IDEOGRAPH + {0xB74F, 0x7A2F}, //8870 #CJK UNIFIED IDEOGRAPH + {0xB750, 0x7A30}, //8871 #CJK UNIFIED IDEOGRAPH + {0xB751, 0x7A31}, //8872 #CJK UNIFIED IDEOGRAPH + {0xB752, 0x7A32}, //8873 #CJK UNIFIED IDEOGRAPH + {0xB753, 0x7A34}, //8874 #CJK UNIFIED IDEOGRAPH + {0xB754, 0x7A35}, //8875 #CJK UNIFIED IDEOGRAPH + {0xB755, 0x7A36}, //8876 #CJK UNIFIED IDEOGRAPH + {0xB756, 0x7A38}, //8877 #CJK UNIFIED IDEOGRAPH + {0xB757, 0x7A3A}, //8878 #CJK UNIFIED IDEOGRAPH + {0xB758, 0x7A3E}, //8879 #CJK UNIFIED IDEOGRAPH + {0xB759, 0x7A40}, //8880 #CJK UNIFIED IDEOGRAPH + {0xB75A, 0x7A41}, //8881 #CJK UNIFIED IDEOGRAPH + {0xB75B, 0x7A42}, //8882 #CJK UNIFIED IDEOGRAPH + {0xB75C, 0x7A43}, //8883 #CJK UNIFIED IDEOGRAPH + {0xB75D, 0x7A44}, //8884 #CJK UNIFIED IDEOGRAPH + {0xB75E, 0x7A45}, //8885 #CJK UNIFIED IDEOGRAPH + {0xB75F, 0x7A47}, //8886 #CJK UNIFIED IDEOGRAPH + {0xB760, 0x7A48}, //8887 #CJK UNIFIED IDEOGRAPH + {0xB761, 0x7A49}, //8888 #CJK UNIFIED IDEOGRAPH + {0xB762, 0x7A4A}, //8889 #CJK UNIFIED IDEOGRAPH + {0xB763, 0x7A4B}, //8890 #CJK UNIFIED IDEOGRAPH + {0xB764, 0x7A4C}, //8891 #CJK UNIFIED IDEOGRAPH + {0xB765, 0x7A4D}, //8892 #CJK UNIFIED IDEOGRAPH + {0xB766, 0x7A4E}, //8893 #CJK UNIFIED IDEOGRAPH + {0xB767, 0x7A4F}, //8894 #CJK UNIFIED IDEOGRAPH + {0xB768, 0x7A50}, //8895 #CJK UNIFIED IDEOGRAPH + {0xB769, 0x7A52}, //8896 #CJK UNIFIED IDEOGRAPH + {0xB76A, 0x7A53}, //8897 #CJK UNIFIED IDEOGRAPH + {0xB76B, 0x7A54}, //8898 #CJK UNIFIED IDEOGRAPH + {0xB76C, 0x7A55}, //8899 #CJK UNIFIED IDEOGRAPH + {0xB76D, 0x7A56}, //8900 #CJK UNIFIED IDEOGRAPH + {0xB76E, 0x7A58}, //8901 #CJK UNIFIED IDEOGRAPH + {0xB76F, 0x7A59}, //8902 #CJK UNIFIED IDEOGRAPH + {0xB770, 0x7A5A}, //8903 #CJK UNIFIED IDEOGRAPH + {0xB771, 0x7A5B}, //8904 #CJK UNIFIED IDEOGRAPH + {0xB772, 0x7A5C}, //8905 #CJK UNIFIED IDEOGRAPH + {0xB773, 0x7A5D}, //8906 #CJK UNIFIED IDEOGRAPH + {0xB774, 0x7A5E}, //8907 #CJK UNIFIED IDEOGRAPH + {0xB775, 0x7A5F}, //8908 #CJK UNIFIED IDEOGRAPH + {0xB776, 0x7A60}, //8909 #CJK UNIFIED IDEOGRAPH + {0xB777, 0x7A61}, //8910 #CJK UNIFIED IDEOGRAPH + {0xB778, 0x7A62}, //8911 #CJK UNIFIED IDEOGRAPH + {0xB779, 0x7A63}, //8912 #CJK UNIFIED IDEOGRAPH + {0xB77A, 0x7A64}, //8913 #CJK UNIFIED IDEOGRAPH + {0xB77B, 0x7A65}, //8914 #CJK UNIFIED IDEOGRAPH + {0xB77C, 0x7A66}, //8915 #CJK UNIFIED IDEOGRAPH + {0xB77D, 0x7A67}, //8916 #CJK UNIFIED IDEOGRAPH + {0xB77E, 0x7A68}, //8917 #CJK UNIFIED IDEOGRAPH + {0xB780, 0x7A69}, //8918 #CJK UNIFIED IDEOGRAPH + {0xB781, 0x7A6A}, //8919 #CJK UNIFIED IDEOGRAPH + {0xB782, 0x7A6B}, //8920 #CJK UNIFIED IDEOGRAPH + {0xB783, 0x7A6C}, //8921 #CJK UNIFIED IDEOGRAPH + {0xB784, 0x7A6D}, //8922 #CJK UNIFIED IDEOGRAPH + {0xB785, 0x7A6E}, //8923 #CJK UNIFIED IDEOGRAPH + {0xB786, 0x7A6F}, //8924 #CJK UNIFIED IDEOGRAPH + {0xB787, 0x7A71}, //8925 #CJK UNIFIED IDEOGRAPH + {0xB788, 0x7A72}, //8926 #CJK UNIFIED IDEOGRAPH + {0xB789, 0x7A73}, //8927 #CJK UNIFIED IDEOGRAPH + {0xB78A, 0x7A75}, //8928 #CJK UNIFIED IDEOGRAPH + {0xB78B, 0x7A7B}, //8929 #CJK UNIFIED IDEOGRAPH + {0xB78C, 0x7A7C}, //8930 #CJK UNIFIED IDEOGRAPH + {0xB78D, 0x7A7D}, //8931 #CJK UNIFIED IDEOGRAPH + {0xB78E, 0x7A7E}, //8932 #CJK UNIFIED IDEOGRAPH + {0xB78F, 0x7A82}, //8933 #CJK UNIFIED IDEOGRAPH + {0xB790, 0x7A85}, //8934 #CJK UNIFIED IDEOGRAPH + {0xB791, 0x7A87}, //8935 #CJK UNIFIED IDEOGRAPH + {0xB792, 0x7A89}, //8936 #CJK UNIFIED IDEOGRAPH + {0xB793, 0x7A8A}, //8937 #CJK UNIFIED IDEOGRAPH + {0xB794, 0x7A8B}, //8938 #CJK UNIFIED IDEOGRAPH + {0xB795, 0x7A8C}, //8939 #CJK UNIFIED IDEOGRAPH + {0xB796, 0x7A8E}, //8940 #CJK UNIFIED IDEOGRAPH + {0xB797, 0x7A8F}, //8941 #CJK UNIFIED IDEOGRAPH + {0xB798, 0x7A90}, //8942 #CJK UNIFIED IDEOGRAPH + {0xB799, 0x7A93}, //8943 #CJK UNIFIED IDEOGRAPH + {0xB79A, 0x7A94}, //8944 #CJK UNIFIED IDEOGRAPH + {0xB79B, 0x7A99}, //8945 #CJK UNIFIED IDEOGRAPH + {0xB79C, 0x7A9A}, //8946 #CJK UNIFIED IDEOGRAPH + {0xB79D, 0x7A9B}, //8947 #CJK UNIFIED IDEOGRAPH + {0xB79E, 0x7A9E}, //8948 #CJK UNIFIED IDEOGRAPH + {0xB79F, 0x7AA1}, //8949 #CJK UNIFIED IDEOGRAPH + {0xB7A0, 0x7AA2}, //8950 #CJK UNIFIED IDEOGRAPH + {0xB7A1, 0x8D30}, //8951 #CJK UNIFIED IDEOGRAPH + {0xB7A2, 0x53D1}, //8952 #CJK UNIFIED IDEOGRAPH + {0xB7A3, 0x7F5A}, //8953 #CJK UNIFIED IDEOGRAPH + {0xB7A4, 0x7B4F}, //8954 #CJK UNIFIED IDEOGRAPH + {0xB7A5, 0x4F10}, //8955 #CJK UNIFIED IDEOGRAPH + {0xB7A6, 0x4E4F}, //8956 #CJK UNIFIED IDEOGRAPH + {0xB7A7, 0x9600}, //8957 #CJK UNIFIED IDEOGRAPH + {0xB7A8, 0x6CD5}, //8958 #CJK UNIFIED IDEOGRAPH + {0xB7A9, 0x73D0}, //8959 #CJK UNIFIED IDEOGRAPH + {0xB7AA, 0x85E9}, //8960 #CJK UNIFIED IDEOGRAPH + {0xB7AB, 0x5E06}, //8961 #CJK UNIFIED IDEOGRAPH + {0xB7AC, 0x756A}, //8962 #CJK UNIFIED IDEOGRAPH + {0xB7AD, 0x7FFB}, //8963 #CJK UNIFIED IDEOGRAPH + {0xB7AE, 0x6A0A}, //8964 #CJK UNIFIED IDEOGRAPH + {0xB7AF, 0x77FE}, //8965 #CJK UNIFIED IDEOGRAPH + {0xB7B0, 0x9492}, //8966 #CJK UNIFIED IDEOGRAPH + {0xB7B1, 0x7E41}, //8967 #CJK UNIFIED IDEOGRAPH + {0xB7B2, 0x51E1}, //8968 #CJK UNIFIED IDEOGRAPH + {0xB7B3, 0x70E6}, //8969 #CJK UNIFIED IDEOGRAPH + {0xB7B4, 0x53CD}, //8970 #CJK UNIFIED IDEOGRAPH + {0xB7B5, 0x8FD4}, //8971 #CJK UNIFIED IDEOGRAPH + {0xB7B6, 0x8303}, //8972 #CJK UNIFIED IDEOGRAPH + {0xB7B7, 0x8D29}, //8973 #CJK UNIFIED IDEOGRAPH + {0xB7B8, 0x72AF}, //8974 #CJK UNIFIED IDEOGRAPH + {0xB7B9, 0x996D}, //8975 #CJK UNIFIED IDEOGRAPH + {0xB7BA, 0x6CDB}, //8976 #CJK UNIFIED IDEOGRAPH + {0xB7BB, 0x574A}, //8977 #CJK UNIFIED IDEOGRAPH + {0xB7BC, 0x82B3}, //8978 #CJK UNIFIED IDEOGRAPH + {0xB7BD, 0x65B9}, //8979 #CJK UNIFIED IDEOGRAPH + {0xB7BE, 0x80AA}, //8980 #CJK UNIFIED IDEOGRAPH + {0xB7BF, 0x623F}, //8981 #CJK UNIFIED IDEOGRAPH + {0xB7C0, 0x9632}, //8982 #CJK UNIFIED IDEOGRAPH + {0xB7C1, 0x59A8}, //8983 #CJK UNIFIED IDEOGRAPH + {0xB7C2, 0x4EFF}, //8984 #CJK UNIFIED IDEOGRAPH + {0xB7C3, 0x8BBF}, //8985 #CJK UNIFIED IDEOGRAPH + {0xB7C4, 0x7EBA}, //8986 #CJK UNIFIED IDEOGRAPH + {0xB7C5, 0x653E}, //8987 #CJK UNIFIED IDEOGRAPH + {0xB7C6, 0x83F2}, //8988 #CJK UNIFIED IDEOGRAPH + {0xB7C7, 0x975E}, //8989 #CJK UNIFIED IDEOGRAPH + {0xB7C8, 0x5561}, //8990 #CJK UNIFIED IDEOGRAPH + {0xB7C9, 0x98DE}, //8991 #CJK UNIFIED IDEOGRAPH + {0xB7CA, 0x80A5}, //8992 #CJK UNIFIED IDEOGRAPH + {0xB7CB, 0x532A}, //8993 #CJK UNIFIED IDEOGRAPH + {0xB7CC, 0x8BFD}, //8994 #CJK UNIFIED IDEOGRAPH + {0xB7CD, 0x5420}, //8995 #CJK UNIFIED IDEOGRAPH + {0xB7CE, 0x80BA}, //8996 #CJK UNIFIED IDEOGRAPH + {0xB7CF, 0x5E9F}, //8997 #CJK UNIFIED IDEOGRAPH + {0xB7D0, 0x6CB8}, //8998 #CJK UNIFIED IDEOGRAPH + {0xB7D1, 0x8D39}, //8999 #CJK UNIFIED IDEOGRAPH + {0xB7D2, 0x82AC}, //9000 #CJK UNIFIED IDEOGRAPH + {0xB7D3, 0x915A}, //9001 #CJK UNIFIED IDEOGRAPH + {0xB7D4, 0x5429}, //9002 #CJK UNIFIED IDEOGRAPH + {0xB7D5, 0x6C1B}, //9003 #CJK UNIFIED IDEOGRAPH + {0xB7D6, 0x5206}, //9004 #CJK UNIFIED IDEOGRAPH + {0xB7D7, 0x7EB7}, //9005 #CJK UNIFIED IDEOGRAPH + {0xB7D8, 0x575F}, //9006 #CJK UNIFIED IDEOGRAPH + {0xB7D9, 0x711A}, //9007 #CJK UNIFIED IDEOGRAPH + {0xB7DA, 0x6C7E}, //9008 #CJK UNIFIED IDEOGRAPH + {0xB7DB, 0x7C89}, //9009 #CJK UNIFIED IDEOGRAPH + {0xB7DC, 0x594B}, //9010 #CJK UNIFIED IDEOGRAPH + {0xB7DD, 0x4EFD}, //9011 #CJK UNIFIED IDEOGRAPH + {0xB7DE, 0x5FFF}, //9012 #CJK UNIFIED IDEOGRAPH + {0xB7DF, 0x6124}, //9013 #CJK UNIFIED IDEOGRAPH + {0xB7E0, 0x7CAA}, //9014 #CJK UNIFIED IDEOGRAPH + {0xB7E1, 0x4E30}, //9015 #CJK UNIFIED IDEOGRAPH + {0xB7E2, 0x5C01}, //9016 #CJK UNIFIED IDEOGRAPH + {0xB7E3, 0x67AB}, //9017 #CJK UNIFIED IDEOGRAPH + {0xB7E4, 0x8702}, //9018 #CJK UNIFIED IDEOGRAPH + {0xB7E5, 0x5CF0}, //9019 #CJK UNIFIED IDEOGRAPH + {0xB7E6, 0x950B}, //9020 #CJK UNIFIED IDEOGRAPH + {0xB7E7, 0x98CE}, //9021 #CJK UNIFIED IDEOGRAPH + {0xB7E8, 0x75AF}, //9022 #CJK UNIFIED IDEOGRAPH + {0xB7E9, 0x70FD}, //9023 #CJK UNIFIED IDEOGRAPH + {0xB7EA, 0x9022}, //9024 #CJK UNIFIED IDEOGRAPH + {0xB7EB, 0x51AF}, //9025 #CJK UNIFIED IDEOGRAPH + {0xB7EC, 0x7F1D}, //9026 #CJK UNIFIED IDEOGRAPH + {0xB7ED, 0x8BBD}, //9027 #CJK UNIFIED IDEOGRAPH + {0xB7EE, 0x5949}, //9028 #CJK UNIFIED IDEOGRAPH + {0xB7EF, 0x51E4}, //9029 #CJK UNIFIED IDEOGRAPH + {0xB7F0, 0x4F5B}, //9030 #CJK UNIFIED IDEOGRAPH + {0xB7F1, 0x5426}, //9031 #CJK UNIFIED IDEOGRAPH + {0xB7F2, 0x592B}, //9032 #CJK UNIFIED IDEOGRAPH + {0xB7F3, 0x6577}, //9033 #CJK UNIFIED IDEOGRAPH + {0xB7F4, 0x80A4}, //9034 #CJK UNIFIED IDEOGRAPH + {0xB7F5, 0x5B75}, //9035 #CJK UNIFIED IDEOGRAPH + {0xB7F6, 0x6276}, //9036 #CJK UNIFIED IDEOGRAPH + {0xB7F7, 0x62C2}, //9037 #CJK UNIFIED IDEOGRAPH + {0xB7F8, 0x8F90}, //9038 #CJK UNIFIED IDEOGRAPH + {0xB7F9, 0x5E45}, //9039 #CJK UNIFIED IDEOGRAPH + {0xB7FA, 0x6C1F}, //9040 #CJK UNIFIED IDEOGRAPH + {0xB7FB, 0x7B26}, //9041 #CJK UNIFIED IDEOGRAPH + {0xB7FC, 0x4F0F}, //9042 #CJK UNIFIED IDEOGRAPH + {0xB7FD, 0x4FD8}, //9043 #CJK UNIFIED IDEOGRAPH + {0xB7FE, 0x670D}, //9044 #CJK UNIFIED IDEOGRAPH + {0xB840, 0x7AA3}, //9045 #CJK UNIFIED IDEOGRAPH + {0xB841, 0x7AA4}, //9046 #CJK UNIFIED IDEOGRAPH + {0xB842, 0x7AA7}, //9047 #CJK UNIFIED IDEOGRAPH + {0xB843, 0x7AA9}, //9048 #CJK UNIFIED IDEOGRAPH + {0xB844, 0x7AAA}, //9049 #CJK UNIFIED IDEOGRAPH + {0xB845, 0x7AAB}, //9050 #CJK UNIFIED IDEOGRAPH + {0xB846, 0x7AAE}, //9051 #CJK UNIFIED IDEOGRAPH + {0xB847, 0x7AAF}, //9052 #CJK UNIFIED IDEOGRAPH + {0xB848, 0x7AB0}, //9053 #CJK UNIFIED IDEOGRAPH + {0xB849, 0x7AB1}, //9054 #CJK UNIFIED IDEOGRAPH + {0xB84A, 0x7AB2}, //9055 #CJK UNIFIED IDEOGRAPH + {0xB84B, 0x7AB4}, //9056 #CJK UNIFIED IDEOGRAPH + {0xB84C, 0x7AB5}, //9057 #CJK UNIFIED IDEOGRAPH + {0xB84D, 0x7AB6}, //9058 #CJK UNIFIED IDEOGRAPH + {0xB84E, 0x7AB7}, //9059 #CJK UNIFIED IDEOGRAPH + {0xB84F, 0x7AB8}, //9060 #CJK UNIFIED IDEOGRAPH + {0xB850, 0x7AB9}, //9061 #CJK UNIFIED IDEOGRAPH + {0xB851, 0x7ABA}, //9062 #CJK UNIFIED IDEOGRAPH + {0xB852, 0x7ABB}, //9063 #CJK UNIFIED IDEOGRAPH + {0xB853, 0x7ABC}, //9064 #CJK UNIFIED IDEOGRAPH + {0xB854, 0x7ABD}, //9065 #CJK UNIFIED IDEOGRAPH + {0xB855, 0x7ABE}, //9066 #CJK UNIFIED IDEOGRAPH + {0xB856, 0x7AC0}, //9067 #CJK UNIFIED IDEOGRAPH + {0xB857, 0x7AC1}, //9068 #CJK UNIFIED IDEOGRAPH + {0xB858, 0x7AC2}, //9069 #CJK UNIFIED IDEOGRAPH + {0xB859, 0x7AC3}, //9070 #CJK UNIFIED IDEOGRAPH + {0xB85A, 0x7AC4}, //9071 #CJK UNIFIED IDEOGRAPH + {0xB85B, 0x7AC5}, //9072 #CJK UNIFIED IDEOGRAPH + {0xB85C, 0x7AC6}, //9073 #CJK UNIFIED IDEOGRAPH + {0xB85D, 0x7AC7}, //9074 #CJK UNIFIED IDEOGRAPH + {0xB85E, 0x7AC8}, //9075 #CJK UNIFIED IDEOGRAPH + {0xB85F, 0x7AC9}, //9076 #CJK UNIFIED IDEOGRAPH + {0xB860, 0x7ACA}, //9077 #CJK UNIFIED IDEOGRAPH + {0xB861, 0x7ACC}, //9078 #CJK UNIFIED IDEOGRAPH + {0xB862, 0x7ACD}, //9079 #CJK UNIFIED IDEOGRAPH + {0xB863, 0x7ACE}, //9080 #CJK UNIFIED IDEOGRAPH + {0xB864, 0x7ACF}, //9081 #CJK UNIFIED IDEOGRAPH + {0xB865, 0x7AD0}, //9082 #CJK UNIFIED IDEOGRAPH + {0xB866, 0x7AD1}, //9083 #CJK UNIFIED IDEOGRAPH + {0xB867, 0x7AD2}, //9084 #CJK UNIFIED IDEOGRAPH + {0xB868, 0x7AD3}, //9085 #CJK UNIFIED IDEOGRAPH + {0xB869, 0x7AD4}, //9086 #CJK UNIFIED IDEOGRAPH + {0xB86A, 0x7AD5}, //9087 #CJK UNIFIED IDEOGRAPH + {0xB86B, 0x7AD7}, //9088 #CJK UNIFIED IDEOGRAPH + {0xB86C, 0x7AD8}, //9089 #CJK UNIFIED IDEOGRAPH + {0xB86D, 0x7ADA}, //9090 #CJK UNIFIED IDEOGRAPH + {0xB86E, 0x7ADB}, //9091 #CJK UNIFIED IDEOGRAPH + {0xB86F, 0x7ADC}, //9092 #CJK UNIFIED IDEOGRAPH + {0xB870, 0x7ADD}, //9093 #CJK UNIFIED IDEOGRAPH + {0xB871, 0x7AE1}, //9094 #CJK UNIFIED IDEOGRAPH + {0xB872, 0x7AE2}, //9095 #CJK UNIFIED IDEOGRAPH + {0xB873, 0x7AE4}, //9096 #CJK UNIFIED IDEOGRAPH + {0xB874, 0x7AE7}, //9097 #CJK UNIFIED IDEOGRAPH + {0xB875, 0x7AE8}, //9098 #CJK UNIFIED IDEOGRAPH + {0xB876, 0x7AE9}, //9099 #CJK UNIFIED IDEOGRAPH + {0xB877, 0x7AEA}, //9100 #CJK UNIFIED IDEOGRAPH + {0xB878, 0x7AEB}, //9101 #CJK UNIFIED IDEOGRAPH + {0xB879, 0x7AEC}, //9102 #CJK UNIFIED IDEOGRAPH + {0xB87A, 0x7AEE}, //9103 #CJK UNIFIED IDEOGRAPH + {0xB87B, 0x7AF0}, //9104 #CJK UNIFIED IDEOGRAPH + {0xB87C, 0x7AF1}, //9105 #CJK UNIFIED IDEOGRAPH + {0xB87D, 0x7AF2}, //9106 #CJK UNIFIED IDEOGRAPH + {0xB87E, 0x7AF3}, //9107 #CJK UNIFIED IDEOGRAPH + {0xB880, 0x7AF4}, //9108 #CJK UNIFIED IDEOGRAPH + {0xB881, 0x7AF5}, //9109 #CJK UNIFIED IDEOGRAPH + {0xB882, 0x7AF6}, //9110 #CJK UNIFIED IDEOGRAPH + {0xB883, 0x7AF7}, //9111 #CJK UNIFIED IDEOGRAPH + {0xB884, 0x7AF8}, //9112 #CJK UNIFIED IDEOGRAPH + {0xB885, 0x7AFB}, //9113 #CJK UNIFIED IDEOGRAPH + {0xB886, 0x7AFC}, //9114 #CJK UNIFIED IDEOGRAPH + {0xB887, 0x7AFE}, //9115 #CJK UNIFIED IDEOGRAPH + {0xB888, 0x7B00}, //9116 #CJK UNIFIED IDEOGRAPH + {0xB889, 0x7B01}, //9117 #CJK UNIFIED IDEOGRAPH + {0xB88A, 0x7B02}, //9118 #CJK UNIFIED IDEOGRAPH + {0xB88B, 0x7B05}, //9119 #CJK UNIFIED IDEOGRAPH + {0xB88C, 0x7B07}, //9120 #CJK UNIFIED IDEOGRAPH + {0xB88D, 0x7B09}, //9121 #CJK UNIFIED IDEOGRAPH + {0xB88E, 0x7B0C}, //9122 #CJK UNIFIED IDEOGRAPH + {0xB88F, 0x7B0D}, //9123 #CJK UNIFIED IDEOGRAPH + {0xB890, 0x7B0E}, //9124 #CJK UNIFIED IDEOGRAPH + {0xB891, 0x7B10}, //9125 #CJK UNIFIED IDEOGRAPH + {0xB892, 0x7B12}, //9126 #CJK UNIFIED IDEOGRAPH + {0xB893, 0x7B13}, //9127 #CJK UNIFIED IDEOGRAPH + {0xB894, 0x7B16}, //9128 #CJK UNIFIED IDEOGRAPH + {0xB895, 0x7B17}, //9129 #CJK UNIFIED IDEOGRAPH + {0xB896, 0x7B18}, //9130 #CJK UNIFIED IDEOGRAPH + {0xB897, 0x7B1A}, //9131 #CJK UNIFIED IDEOGRAPH + {0xB898, 0x7B1C}, //9132 #CJK UNIFIED IDEOGRAPH + {0xB899, 0x7B1D}, //9133 #CJK UNIFIED IDEOGRAPH + {0xB89A, 0x7B1F}, //9134 #CJK UNIFIED IDEOGRAPH + {0xB89B, 0x7B21}, //9135 #CJK UNIFIED IDEOGRAPH + {0xB89C, 0x7B22}, //9136 #CJK UNIFIED IDEOGRAPH + {0xB89D, 0x7B23}, //9137 #CJK UNIFIED IDEOGRAPH + {0xB89E, 0x7B27}, //9138 #CJK UNIFIED IDEOGRAPH + {0xB89F, 0x7B29}, //9139 #CJK UNIFIED IDEOGRAPH + {0xB8A0, 0x7B2D}, //9140 #CJK UNIFIED IDEOGRAPH + {0xB8A1, 0x6D6E}, //9141 #CJK UNIFIED IDEOGRAPH + {0xB8A2, 0x6DAA}, //9142 #CJK UNIFIED IDEOGRAPH + {0xB8A3, 0x798F}, //9143 #CJK UNIFIED IDEOGRAPH + {0xB8A4, 0x88B1}, //9144 #CJK UNIFIED IDEOGRAPH + {0xB8A5, 0x5F17}, //9145 #CJK UNIFIED IDEOGRAPH + {0xB8A6, 0x752B}, //9146 #CJK UNIFIED IDEOGRAPH + {0xB8A7, 0x629A}, //9147 #CJK UNIFIED IDEOGRAPH + {0xB8A8, 0x8F85}, //9148 #CJK UNIFIED IDEOGRAPH + {0xB8A9, 0x4FEF}, //9149 #CJK UNIFIED IDEOGRAPH + {0xB8AA, 0x91DC}, //9150 #CJK UNIFIED IDEOGRAPH + {0xB8AB, 0x65A7}, //9151 #CJK UNIFIED IDEOGRAPH + {0xB8AC, 0x812F}, //9152 #CJK UNIFIED IDEOGRAPH + {0xB8AD, 0x8151}, //9153 #CJK UNIFIED IDEOGRAPH + {0xB8AE, 0x5E9C}, //9154 #CJK UNIFIED IDEOGRAPH + {0xB8AF, 0x8150}, //9155 #CJK UNIFIED IDEOGRAPH + {0xB8B0, 0x8D74}, //9156 #CJK UNIFIED IDEOGRAPH + {0xB8B1, 0x526F}, //9157 #CJK UNIFIED IDEOGRAPH + {0xB8B2, 0x8986}, //9158 #CJK UNIFIED IDEOGRAPH + {0xB8B3, 0x8D4B}, //9159 #CJK UNIFIED IDEOGRAPH + {0xB8B4, 0x590D}, //9160 #CJK UNIFIED IDEOGRAPH + {0xB8B5, 0x5085}, //9161 #CJK UNIFIED IDEOGRAPH + {0xB8B6, 0x4ED8}, //9162 #CJK UNIFIED IDEOGRAPH + {0xB8B7, 0x961C}, //9163 #CJK UNIFIED IDEOGRAPH + {0xB8B8, 0x7236}, //9164 #CJK UNIFIED IDEOGRAPH + {0xB8B9, 0x8179}, //9165 #CJK UNIFIED IDEOGRAPH + {0xB8BA, 0x8D1F}, //9166 #CJK UNIFIED IDEOGRAPH + {0xB8BB, 0x5BCC}, //9167 #CJK UNIFIED IDEOGRAPH + {0xB8BC, 0x8BA3}, //9168 #CJK UNIFIED IDEOGRAPH + {0xB8BD, 0x9644}, //9169 #CJK UNIFIED IDEOGRAPH + {0xB8BE, 0x5987}, //9170 #CJK UNIFIED IDEOGRAPH + {0xB8BF, 0x7F1A}, //9171 #CJK UNIFIED IDEOGRAPH + {0xB8C0, 0x5490}, //9172 #CJK UNIFIED IDEOGRAPH + {0xB8C1, 0x5676}, //9173 #CJK UNIFIED IDEOGRAPH + {0xB8C2, 0x560E}, //9174 #CJK UNIFIED IDEOGRAPH + {0xB8C3, 0x8BE5}, //9175 #CJK UNIFIED IDEOGRAPH + {0xB8C4, 0x6539}, //9176 #CJK UNIFIED IDEOGRAPH + {0xB8C5, 0x6982}, //9177 #CJK UNIFIED IDEOGRAPH + {0xB8C6, 0x9499}, //9178 #CJK UNIFIED IDEOGRAPH + {0xB8C7, 0x76D6}, //9179 #CJK UNIFIED IDEOGRAPH + {0xB8C8, 0x6E89}, //9180 #CJK UNIFIED IDEOGRAPH + {0xB8C9, 0x5E72}, //9181 #CJK UNIFIED IDEOGRAPH + {0xB8CA, 0x7518}, //9182 #CJK UNIFIED IDEOGRAPH + {0xB8CB, 0x6746}, //9183 #CJK UNIFIED IDEOGRAPH + {0xB8CC, 0x67D1}, //9184 #CJK UNIFIED IDEOGRAPH + {0xB8CD, 0x7AFF}, //9185 #CJK UNIFIED IDEOGRAPH + {0xB8CE, 0x809D}, //9186 #CJK UNIFIED IDEOGRAPH + {0xB8CF, 0x8D76}, //9187 #CJK UNIFIED IDEOGRAPH + {0xB8D0, 0x611F}, //9188 #CJK UNIFIED IDEOGRAPH + {0xB8D1, 0x79C6}, //9189 #CJK UNIFIED IDEOGRAPH + {0xB8D2, 0x6562}, //9190 #CJK UNIFIED IDEOGRAPH + {0xB8D3, 0x8D63}, //9191 #CJK UNIFIED IDEOGRAPH + {0xB8D4, 0x5188}, //9192 #CJK UNIFIED IDEOGRAPH + {0xB8D5, 0x521A}, //9193 #CJK UNIFIED IDEOGRAPH + {0xB8D6, 0x94A2}, //9194 #CJK UNIFIED IDEOGRAPH + {0xB8D7, 0x7F38}, //9195 #CJK UNIFIED IDEOGRAPH + {0xB8D8, 0x809B}, //9196 #CJK UNIFIED IDEOGRAPH + {0xB8D9, 0x7EB2}, //9197 #CJK UNIFIED IDEOGRAPH + {0xB8DA, 0x5C97}, //9198 #CJK UNIFIED IDEOGRAPH + {0xB8DB, 0x6E2F}, //9199 #CJK UNIFIED IDEOGRAPH + {0xB8DC, 0x6760}, //9200 #CJK UNIFIED IDEOGRAPH + {0xB8DD, 0x7BD9}, //9201 #CJK UNIFIED IDEOGRAPH + {0xB8DE, 0x768B}, //9202 #CJK UNIFIED IDEOGRAPH + {0xB8DF, 0x9AD8}, //9203 #CJK UNIFIED IDEOGRAPH + {0xB8E0, 0x818F}, //9204 #CJK UNIFIED IDEOGRAPH + {0xB8E1, 0x7F94}, //9205 #CJK UNIFIED IDEOGRAPH + {0xB8E2, 0x7CD5}, //9206 #CJK UNIFIED IDEOGRAPH + {0xB8E3, 0x641E}, //9207 #CJK UNIFIED IDEOGRAPH + {0xB8E4, 0x9550}, //9208 #CJK UNIFIED IDEOGRAPH + {0xB8E5, 0x7A3F}, //9209 #CJK UNIFIED IDEOGRAPH + {0xB8E6, 0x544A}, //9210 #CJK UNIFIED IDEOGRAPH + {0xB8E7, 0x54E5}, //9211 #CJK UNIFIED IDEOGRAPH + {0xB8E8, 0x6B4C}, //9212 #CJK UNIFIED IDEOGRAPH + {0xB8E9, 0x6401}, //9213 #CJK UNIFIED IDEOGRAPH + {0xB8EA, 0x6208}, //9214 #CJK UNIFIED IDEOGRAPH + {0xB8EB, 0x9E3D}, //9215 #CJK UNIFIED IDEOGRAPH + {0xB8EC, 0x80F3}, //9216 #CJK UNIFIED IDEOGRAPH + {0xB8ED, 0x7599}, //9217 #CJK UNIFIED IDEOGRAPH + {0xB8EE, 0x5272}, //9218 #CJK UNIFIED IDEOGRAPH + {0xB8EF, 0x9769}, //9219 #CJK UNIFIED IDEOGRAPH + {0xB8F0, 0x845B}, //9220 #CJK UNIFIED IDEOGRAPH + {0xB8F1, 0x683C}, //9221 #CJK UNIFIED IDEOGRAPH + {0xB8F2, 0x86E4}, //9222 #CJK UNIFIED IDEOGRAPH + {0xB8F3, 0x9601}, //9223 #CJK UNIFIED IDEOGRAPH + {0xB8F4, 0x9694}, //9224 #CJK UNIFIED IDEOGRAPH + {0xB8F5, 0x94EC}, //9225 #CJK UNIFIED IDEOGRAPH + {0xB8F6, 0x4E2A}, //9226 #CJK UNIFIED IDEOGRAPH + {0xB8F7, 0x5404}, //9227 #CJK UNIFIED IDEOGRAPH + {0xB8F8, 0x7ED9}, //9228 #CJK UNIFIED IDEOGRAPH + {0xB8F9, 0x6839}, //9229 #CJK UNIFIED IDEOGRAPH + {0xB8FA, 0x8DDF}, //9230 #CJK UNIFIED IDEOGRAPH + {0xB8FB, 0x8015}, //9231 #CJK UNIFIED IDEOGRAPH + {0xB8FC, 0x66F4}, //9232 #CJK UNIFIED IDEOGRAPH + {0xB8FD, 0x5E9A}, //9233 #CJK UNIFIED IDEOGRAPH + {0xB8FE, 0x7FB9}, //9234 #CJK UNIFIED IDEOGRAPH + {0xB940, 0x7B2F}, //9235 #CJK UNIFIED IDEOGRAPH + {0xB941, 0x7B30}, //9236 #CJK UNIFIED IDEOGRAPH + {0xB942, 0x7B32}, //9237 #CJK UNIFIED IDEOGRAPH + {0xB943, 0x7B34}, //9238 #CJK UNIFIED IDEOGRAPH + {0xB944, 0x7B35}, //9239 #CJK UNIFIED IDEOGRAPH + {0xB945, 0x7B36}, //9240 #CJK UNIFIED IDEOGRAPH + {0xB946, 0x7B37}, //9241 #CJK UNIFIED IDEOGRAPH + {0xB947, 0x7B39}, //9242 #CJK UNIFIED IDEOGRAPH + {0xB948, 0x7B3B}, //9243 #CJK UNIFIED IDEOGRAPH + {0xB949, 0x7B3D}, //9244 #CJK UNIFIED IDEOGRAPH + {0xB94A, 0x7B3F}, //9245 #CJK UNIFIED IDEOGRAPH + {0xB94B, 0x7B40}, //9246 #CJK UNIFIED IDEOGRAPH + {0xB94C, 0x7B41}, //9247 #CJK UNIFIED IDEOGRAPH + {0xB94D, 0x7B42}, //9248 #CJK UNIFIED IDEOGRAPH + {0xB94E, 0x7B43}, //9249 #CJK UNIFIED IDEOGRAPH + {0xB94F, 0x7B44}, //9250 #CJK UNIFIED IDEOGRAPH + {0xB950, 0x7B46}, //9251 #CJK UNIFIED IDEOGRAPH + {0xB951, 0x7B48}, //9252 #CJK UNIFIED IDEOGRAPH + {0xB952, 0x7B4A}, //9253 #CJK UNIFIED IDEOGRAPH + {0xB953, 0x7B4D}, //9254 #CJK UNIFIED IDEOGRAPH + {0xB954, 0x7B4E}, //9255 #CJK UNIFIED IDEOGRAPH + {0xB955, 0x7B53}, //9256 #CJK UNIFIED IDEOGRAPH + {0xB956, 0x7B55}, //9257 #CJK UNIFIED IDEOGRAPH + {0xB957, 0x7B57}, //9258 #CJK UNIFIED IDEOGRAPH + {0xB958, 0x7B59}, //9259 #CJK UNIFIED IDEOGRAPH + {0xB959, 0x7B5C}, //9260 #CJK UNIFIED IDEOGRAPH + {0xB95A, 0x7B5E}, //9261 #CJK UNIFIED IDEOGRAPH + {0xB95B, 0x7B5F}, //9262 #CJK UNIFIED IDEOGRAPH + {0xB95C, 0x7B61}, //9263 #CJK UNIFIED IDEOGRAPH + {0xB95D, 0x7B63}, //9264 #CJK UNIFIED IDEOGRAPH + {0xB95E, 0x7B64}, //9265 #CJK UNIFIED IDEOGRAPH + {0xB95F, 0x7B65}, //9266 #CJK UNIFIED IDEOGRAPH + {0xB960, 0x7B66}, //9267 #CJK UNIFIED IDEOGRAPH + {0xB961, 0x7B67}, //9268 #CJK UNIFIED IDEOGRAPH + {0xB962, 0x7B68}, //9269 #CJK UNIFIED IDEOGRAPH + {0xB963, 0x7B69}, //9270 #CJK UNIFIED IDEOGRAPH + {0xB964, 0x7B6A}, //9271 #CJK UNIFIED IDEOGRAPH + {0xB965, 0x7B6B}, //9272 #CJK UNIFIED IDEOGRAPH + {0xB966, 0x7B6C}, //9273 #CJK UNIFIED IDEOGRAPH + {0xB967, 0x7B6D}, //9274 #CJK UNIFIED IDEOGRAPH + {0xB968, 0x7B6F}, //9275 #CJK UNIFIED IDEOGRAPH + {0xB969, 0x7B70}, //9276 #CJK UNIFIED IDEOGRAPH + {0xB96A, 0x7B73}, //9277 #CJK UNIFIED IDEOGRAPH + {0xB96B, 0x7B74}, //9278 #CJK UNIFIED IDEOGRAPH + {0xB96C, 0x7B76}, //9279 #CJK UNIFIED IDEOGRAPH + {0xB96D, 0x7B78}, //9280 #CJK UNIFIED IDEOGRAPH + {0xB96E, 0x7B7A}, //9281 #CJK UNIFIED IDEOGRAPH + {0xB96F, 0x7B7C}, //9282 #CJK UNIFIED IDEOGRAPH + {0xB970, 0x7B7D}, //9283 #CJK UNIFIED IDEOGRAPH + {0xB971, 0x7B7F}, //9284 #CJK UNIFIED IDEOGRAPH + {0xB972, 0x7B81}, //9285 #CJK UNIFIED IDEOGRAPH + {0xB973, 0x7B82}, //9286 #CJK UNIFIED IDEOGRAPH + {0xB974, 0x7B83}, //9287 #CJK UNIFIED IDEOGRAPH + {0xB975, 0x7B84}, //9288 #CJK UNIFIED IDEOGRAPH + {0xB976, 0x7B86}, //9289 #CJK UNIFIED IDEOGRAPH + {0xB977, 0x7B87}, //9290 #CJK UNIFIED IDEOGRAPH + {0xB978, 0x7B88}, //9291 #CJK UNIFIED IDEOGRAPH + {0xB979, 0x7B89}, //9292 #CJK UNIFIED IDEOGRAPH + {0xB97A, 0x7B8A}, //9293 #CJK UNIFIED IDEOGRAPH + {0xB97B, 0x7B8B}, //9294 #CJK UNIFIED IDEOGRAPH + {0xB97C, 0x7B8C}, //9295 #CJK UNIFIED IDEOGRAPH + {0xB97D, 0x7B8E}, //9296 #CJK UNIFIED IDEOGRAPH + {0xB97E, 0x7B8F}, //9297 #CJK UNIFIED IDEOGRAPH + {0xB980, 0x7B91}, //9298 #CJK UNIFIED IDEOGRAPH + {0xB981, 0x7B92}, //9299 #CJK UNIFIED IDEOGRAPH + {0xB982, 0x7B93}, //9300 #CJK UNIFIED IDEOGRAPH + {0xB983, 0x7B96}, //9301 #CJK UNIFIED IDEOGRAPH + {0xB984, 0x7B98}, //9302 #CJK UNIFIED IDEOGRAPH + {0xB985, 0x7B99}, //9303 #CJK UNIFIED IDEOGRAPH + {0xB986, 0x7B9A}, //9304 #CJK UNIFIED IDEOGRAPH + {0xB987, 0x7B9B}, //9305 #CJK UNIFIED IDEOGRAPH + {0xB988, 0x7B9E}, //9306 #CJK UNIFIED IDEOGRAPH + {0xB989, 0x7B9F}, //9307 #CJK UNIFIED IDEOGRAPH + {0xB98A, 0x7BA0}, //9308 #CJK UNIFIED IDEOGRAPH + {0xB98B, 0x7BA3}, //9309 #CJK UNIFIED IDEOGRAPH + {0xB98C, 0x7BA4}, //9310 #CJK UNIFIED IDEOGRAPH + {0xB98D, 0x7BA5}, //9311 #CJK UNIFIED IDEOGRAPH + {0xB98E, 0x7BAE}, //9312 #CJK UNIFIED IDEOGRAPH + {0xB98F, 0x7BAF}, //9313 #CJK UNIFIED IDEOGRAPH + {0xB990, 0x7BB0}, //9314 #CJK UNIFIED IDEOGRAPH + {0xB991, 0x7BB2}, //9315 #CJK UNIFIED IDEOGRAPH + {0xB992, 0x7BB3}, //9316 #CJK UNIFIED IDEOGRAPH + {0xB993, 0x7BB5}, //9317 #CJK UNIFIED IDEOGRAPH + {0xB994, 0x7BB6}, //9318 #CJK UNIFIED IDEOGRAPH + {0xB995, 0x7BB7}, //9319 #CJK UNIFIED IDEOGRAPH + {0xB996, 0x7BB9}, //9320 #CJK UNIFIED IDEOGRAPH + {0xB997, 0x7BBA}, //9321 #CJK UNIFIED IDEOGRAPH + {0xB998, 0x7BBB}, //9322 #CJK UNIFIED IDEOGRAPH + {0xB999, 0x7BBC}, //9323 #CJK UNIFIED IDEOGRAPH + {0xB99A, 0x7BBD}, //9324 #CJK UNIFIED IDEOGRAPH + {0xB99B, 0x7BBE}, //9325 #CJK UNIFIED IDEOGRAPH + {0xB99C, 0x7BBF}, //9326 #CJK UNIFIED IDEOGRAPH + {0xB99D, 0x7BC0}, //9327 #CJK UNIFIED IDEOGRAPH + {0xB99E, 0x7BC2}, //9328 #CJK UNIFIED IDEOGRAPH + {0xB99F, 0x7BC3}, //9329 #CJK UNIFIED IDEOGRAPH + {0xB9A0, 0x7BC4}, //9330 #CJK UNIFIED IDEOGRAPH + {0xB9A1, 0x57C2}, //9331 #CJK UNIFIED IDEOGRAPH + {0xB9A2, 0x803F}, //9332 #CJK UNIFIED IDEOGRAPH + {0xB9A3, 0x6897}, //9333 #CJK UNIFIED IDEOGRAPH + {0xB9A4, 0x5DE5}, //9334 #CJK UNIFIED IDEOGRAPH + {0xB9A5, 0x653B}, //9335 #CJK UNIFIED IDEOGRAPH + {0xB9A6, 0x529F}, //9336 #CJK UNIFIED IDEOGRAPH + {0xB9A7, 0x606D}, //9337 #CJK UNIFIED IDEOGRAPH + {0xB9A8, 0x9F9A}, //9338 #CJK UNIFIED IDEOGRAPH + {0xB9A9, 0x4F9B}, //9339 #CJK UNIFIED IDEOGRAPH + {0xB9AA, 0x8EAC}, //9340 #CJK UNIFIED IDEOGRAPH + {0xB9AB, 0x516C}, //9341 #CJK UNIFIED IDEOGRAPH + {0xB9AC, 0x5BAB}, //9342 #CJK UNIFIED IDEOGRAPH + {0xB9AD, 0x5F13}, //9343 #CJK UNIFIED IDEOGRAPH + {0xB9AE, 0x5DE9}, //9344 #CJK UNIFIED IDEOGRAPH + {0xB9AF, 0x6C5E}, //9345 #CJK UNIFIED IDEOGRAPH + {0xB9B0, 0x62F1}, //9346 #CJK UNIFIED IDEOGRAPH + {0xB9B1, 0x8D21}, //9347 #CJK UNIFIED IDEOGRAPH + {0xB9B2, 0x5171}, //9348 #CJK UNIFIED IDEOGRAPH + {0xB9B3, 0x94A9}, //9349 #CJK UNIFIED IDEOGRAPH + {0xB9B4, 0x52FE}, //9350 #CJK UNIFIED IDEOGRAPH + {0xB9B5, 0x6C9F}, //9351 #CJK UNIFIED IDEOGRAPH + {0xB9B6, 0x82DF}, //9352 #CJK UNIFIED IDEOGRAPH + {0xB9B7, 0x72D7}, //9353 #CJK UNIFIED IDEOGRAPH + {0xB9B8, 0x57A2}, //9354 #CJK UNIFIED IDEOGRAPH + {0xB9B9, 0x6784}, //9355 #CJK UNIFIED IDEOGRAPH + {0xB9BA, 0x8D2D}, //9356 #CJK UNIFIED IDEOGRAPH + {0xB9BB, 0x591F}, //9357 #CJK UNIFIED IDEOGRAPH + {0xB9BC, 0x8F9C}, //9358 #CJK UNIFIED IDEOGRAPH + {0xB9BD, 0x83C7}, //9359 #CJK UNIFIED IDEOGRAPH + {0xB9BE, 0x5495}, //9360 #CJK UNIFIED IDEOGRAPH + {0xB9BF, 0x7B8D}, //9361 #CJK UNIFIED IDEOGRAPH + {0xB9C0, 0x4F30}, //9362 #CJK UNIFIED IDEOGRAPH + {0xB9C1, 0x6CBD}, //9363 #CJK UNIFIED IDEOGRAPH + {0xB9C2, 0x5B64}, //9364 #CJK UNIFIED IDEOGRAPH + {0xB9C3, 0x59D1}, //9365 #CJK UNIFIED IDEOGRAPH + {0xB9C4, 0x9F13}, //9366 #CJK UNIFIED IDEOGRAPH + {0xB9C5, 0x53E4}, //9367 #CJK UNIFIED IDEOGRAPH + {0xB9C6, 0x86CA}, //9368 #CJK UNIFIED IDEOGRAPH + {0xB9C7, 0x9AA8}, //9369 #CJK UNIFIED IDEOGRAPH + {0xB9C8, 0x8C37}, //9370 #CJK UNIFIED IDEOGRAPH + {0xB9C9, 0x80A1}, //9371 #CJK UNIFIED IDEOGRAPH + {0xB9CA, 0x6545}, //9372 #CJK UNIFIED IDEOGRAPH + {0xB9CB, 0x987E}, //9373 #CJK UNIFIED IDEOGRAPH + {0xB9CC, 0x56FA}, //9374 #CJK UNIFIED IDEOGRAPH + {0xB9CD, 0x96C7}, //9375 #CJK UNIFIED IDEOGRAPH + {0xB9CE, 0x522E}, //9376 #CJK UNIFIED IDEOGRAPH + {0xB9CF, 0x74DC}, //9377 #CJK UNIFIED IDEOGRAPH + {0xB9D0, 0x5250}, //9378 #CJK UNIFIED IDEOGRAPH + {0xB9D1, 0x5BE1}, //9379 #CJK UNIFIED IDEOGRAPH + {0xB9D2, 0x6302}, //9380 #CJK UNIFIED IDEOGRAPH + {0xB9D3, 0x8902}, //9381 #CJK UNIFIED IDEOGRAPH + {0xB9D4, 0x4E56}, //9382 #CJK UNIFIED IDEOGRAPH + {0xB9D5, 0x62D0}, //9383 #CJK UNIFIED IDEOGRAPH + {0xB9D6, 0x602A}, //9384 #CJK UNIFIED IDEOGRAPH + {0xB9D7, 0x68FA}, //9385 #CJK UNIFIED IDEOGRAPH + {0xB9D8, 0x5173}, //9386 #CJK UNIFIED IDEOGRAPH + {0xB9D9, 0x5B98}, //9387 #CJK UNIFIED IDEOGRAPH + {0xB9DA, 0x51A0}, //9388 #CJK UNIFIED IDEOGRAPH + {0xB9DB, 0x89C2}, //9389 #CJK UNIFIED IDEOGRAPH + {0xB9DC, 0x7BA1}, //9390 #CJK UNIFIED IDEOGRAPH + {0xB9DD, 0x9986}, //9391 #CJK UNIFIED IDEOGRAPH + {0xB9DE, 0x7F50}, //9392 #CJK UNIFIED IDEOGRAPH + {0xB9DF, 0x60EF}, //9393 #CJK UNIFIED IDEOGRAPH + {0xB9E0, 0x704C}, //9394 #CJK UNIFIED IDEOGRAPH + {0xB9E1, 0x8D2F}, //9395 #CJK UNIFIED IDEOGRAPH + {0xB9E2, 0x5149}, //9396 #CJK UNIFIED IDEOGRAPH + {0xB9E3, 0x5E7F}, //9397 #CJK UNIFIED IDEOGRAPH + {0xB9E4, 0x901B}, //9398 #CJK UNIFIED IDEOGRAPH + {0xB9E5, 0x7470}, //9399 #CJK UNIFIED IDEOGRAPH + {0xB9E6, 0x89C4}, //9400 #CJK UNIFIED IDEOGRAPH + {0xB9E7, 0x572D}, //9401 #CJK UNIFIED IDEOGRAPH + {0xB9E8, 0x7845}, //9402 #CJK UNIFIED IDEOGRAPH + {0xB9E9, 0x5F52}, //9403 #CJK UNIFIED IDEOGRAPH + {0xB9EA, 0x9F9F}, //9404 #CJK UNIFIED IDEOGRAPH + {0xB9EB, 0x95FA}, //9405 #CJK UNIFIED IDEOGRAPH + {0xB9EC, 0x8F68}, //9406 #CJK UNIFIED IDEOGRAPH + {0xB9ED, 0x9B3C}, //9407 #CJK UNIFIED IDEOGRAPH + {0xB9EE, 0x8BE1}, //9408 #CJK UNIFIED IDEOGRAPH + {0xB9EF, 0x7678}, //9409 #CJK UNIFIED IDEOGRAPH + {0xB9F0, 0x6842}, //9410 #CJK UNIFIED IDEOGRAPH + {0xB9F1, 0x67DC}, //9411 #CJK UNIFIED IDEOGRAPH + {0xB9F2, 0x8DEA}, //9412 #CJK UNIFIED IDEOGRAPH + {0xB9F3, 0x8D35}, //9413 #CJK UNIFIED IDEOGRAPH + {0xB9F4, 0x523D}, //9414 #CJK UNIFIED IDEOGRAPH + {0xB9F5, 0x8F8A}, //9415 #CJK UNIFIED IDEOGRAPH + {0xB9F6, 0x6EDA}, //9416 #CJK UNIFIED IDEOGRAPH + {0xB9F7, 0x68CD}, //9417 #CJK UNIFIED IDEOGRAPH + {0xB9F8, 0x9505}, //9418 #CJK UNIFIED IDEOGRAPH + {0xB9F9, 0x90ED}, //9419 #CJK UNIFIED IDEOGRAPH + {0xB9FA, 0x56FD}, //9420 #CJK UNIFIED IDEOGRAPH + {0xB9FB, 0x679C}, //9421 #CJK UNIFIED IDEOGRAPH + {0xB9FC, 0x88F9}, //9422 #CJK UNIFIED IDEOGRAPH + {0xB9FD, 0x8FC7}, //9423 #CJK UNIFIED IDEOGRAPH + {0xB9FE, 0x54C8}, //9424 #CJK UNIFIED IDEOGRAPH + {0xBA40, 0x7BC5}, //9425 #CJK UNIFIED IDEOGRAPH + {0xBA41, 0x7BC8}, //9426 #CJK UNIFIED IDEOGRAPH + {0xBA42, 0x7BC9}, //9427 #CJK UNIFIED IDEOGRAPH + {0xBA43, 0x7BCA}, //9428 #CJK UNIFIED IDEOGRAPH + {0xBA44, 0x7BCB}, //9429 #CJK UNIFIED IDEOGRAPH + {0xBA45, 0x7BCD}, //9430 #CJK UNIFIED IDEOGRAPH + {0xBA46, 0x7BCE}, //9431 #CJK UNIFIED IDEOGRAPH + {0xBA47, 0x7BCF}, //9432 #CJK UNIFIED IDEOGRAPH + {0xBA48, 0x7BD0}, //9433 #CJK UNIFIED IDEOGRAPH + {0xBA49, 0x7BD2}, //9434 #CJK UNIFIED IDEOGRAPH + {0xBA4A, 0x7BD4}, //9435 #CJK UNIFIED IDEOGRAPH + {0xBA4B, 0x7BD5}, //9436 #CJK UNIFIED IDEOGRAPH + {0xBA4C, 0x7BD6}, //9437 #CJK UNIFIED IDEOGRAPH + {0xBA4D, 0x7BD7}, //9438 #CJK UNIFIED IDEOGRAPH + {0xBA4E, 0x7BD8}, //9439 #CJK UNIFIED IDEOGRAPH + {0xBA4F, 0x7BDB}, //9440 #CJK UNIFIED IDEOGRAPH + {0xBA50, 0x7BDC}, //9441 #CJK UNIFIED IDEOGRAPH + {0xBA51, 0x7BDE}, //9442 #CJK UNIFIED IDEOGRAPH + {0xBA52, 0x7BDF}, //9443 #CJK UNIFIED IDEOGRAPH + {0xBA53, 0x7BE0}, //9444 #CJK UNIFIED IDEOGRAPH + {0xBA54, 0x7BE2}, //9445 #CJK UNIFIED IDEOGRAPH + {0xBA55, 0x7BE3}, //9446 #CJK UNIFIED IDEOGRAPH + {0xBA56, 0x7BE4}, //9447 #CJK UNIFIED IDEOGRAPH + {0xBA57, 0x7BE7}, //9448 #CJK UNIFIED IDEOGRAPH + {0xBA58, 0x7BE8}, //9449 #CJK UNIFIED IDEOGRAPH + {0xBA59, 0x7BE9}, //9450 #CJK UNIFIED IDEOGRAPH + {0xBA5A, 0x7BEB}, //9451 #CJK UNIFIED IDEOGRAPH + {0xBA5B, 0x7BEC}, //9452 #CJK UNIFIED IDEOGRAPH + {0xBA5C, 0x7BED}, //9453 #CJK UNIFIED IDEOGRAPH + {0xBA5D, 0x7BEF}, //9454 #CJK UNIFIED IDEOGRAPH + {0xBA5E, 0x7BF0}, //9455 #CJK UNIFIED IDEOGRAPH + {0xBA5F, 0x7BF2}, //9456 #CJK UNIFIED IDEOGRAPH + {0xBA60, 0x7BF3}, //9457 #CJK UNIFIED IDEOGRAPH + {0xBA61, 0x7BF4}, //9458 #CJK UNIFIED IDEOGRAPH + {0xBA62, 0x7BF5}, //9459 #CJK UNIFIED IDEOGRAPH + {0xBA63, 0x7BF6}, //9460 #CJK UNIFIED IDEOGRAPH + {0xBA64, 0x7BF8}, //9461 #CJK UNIFIED IDEOGRAPH + {0xBA65, 0x7BF9}, //9462 #CJK UNIFIED IDEOGRAPH + {0xBA66, 0x7BFA}, //9463 #CJK UNIFIED IDEOGRAPH + {0xBA67, 0x7BFB}, //9464 #CJK UNIFIED IDEOGRAPH + {0xBA68, 0x7BFD}, //9465 #CJK UNIFIED IDEOGRAPH + {0xBA69, 0x7BFF}, //9466 #CJK UNIFIED IDEOGRAPH + {0xBA6A, 0x7C00}, //9467 #CJK UNIFIED IDEOGRAPH + {0xBA6B, 0x7C01}, //9468 #CJK UNIFIED IDEOGRAPH + {0xBA6C, 0x7C02}, //9469 #CJK UNIFIED IDEOGRAPH + {0xBA6D, 0x7C03}, //9470 #CJK UNIFIED IDEOGRAPH + {0xBA6E, 0x7C04}, //9471 #CJK UNIFIED IDEOGRAPH + {0xBA6F, 0x7C05}, //9472 #CJK UNIFIED IDEOGRAPH + {0xBA70, 0x7C06}, //9473 #CJK UNIFIED IDEOGRAPH + {0xBA71, 0x7C08}, //9474 #CJK UNIFIED IDEOGRAPH + {0xBA72, 0x7C09}, //9475 #CJK UNIFIED IDEOGRAPH + {0xBA73, 0x7C0A}, //9476 #CJK UNIFIED IDEOGRAPH + {0xBA74, 0x7C0D}, //9477 #CJK UNIFIED IDEOGRAPH + {0xBA75, 0x7C0E}, //9478 #CJK UNIFIED IDEOGRAPH + {0xBA76, 0x7C10}, //9479 #CJK UNIFIED IDEOGRAPH + {0xBA77, 0x7C11}, //9480 #CJK UNIFIED IDEOGRAPH + {0xBA78, 0x7C12}, //9481 #CJK UNIFIED IDEOGRAPH + {0xBA79, 0x7C13}, //9482 #CJK UNIFIED IDEOGRAPH + {0xBA7A, 0x7C14}, //9483 #CJK UNIFIED IDEOGRAPH + {0xBA7B, 0x7C15}, //9484 #CJK UNIFIED IDEOGRAPH + {0xBA7C, 0x7C17}, //9485 #CJK UNIFIED IDEOGRAPH + {0xBA7D, 0x7C18}, //9486 #CJK UNIFIED IDEOGRAPH + {0xBA7E, 0x7C19}, //9487 #CJK UNIFIED IDEOGRAPH + {0xBA80, 0x7C1A}, //9488 #CJK UNIFIED IDEOGRAPH + {0xBA81, 0x7C1B}, //9489 #CJK UNIFIED IDEOGRAPH + {0xBA82, 0x7C1C}, //9490 #CJK UNIFIED IDEOGRAPH + {0xBA83, 0x7C1D}, //9491 #CJK UNIFIED IDEOGRAPH + {0xBA84, 0x7C1E}, //9492 #CJK UNIFIED IDEOGRAPH + {0xBA85, 0x7C20}, //9493 #CJK UNIFIED IDEOGRAPH + {0xBA86, 0x7C21}, //9494 #CJK UNIFIED IDEOGRAPH + {0xBA87, 0x7C22}, //9495 #CJK UNIFIED IDEOGRAPH + {0xBA88, 0x7C23}, //9496 #CJK UNIFIED IDEOGRAPH + {0xBA89, 0x7C24}, //9497 #CJK UNIFIED IDEOGRAPH + {0xBA8A, 0x7C25}, //9498 #CJK UNIFIED IDEOGRAPH + {0xBA8B, 0x7C28}, //9499 #CJK UNIFIED IDEOGRAPH + {0xBA8C, 0x7C29}, //9500 #CJK UNIFIED IDEOGRAPH + {0xBA8D, 0x7C2B}, //9501 #CJK UNIFIED IDEOGRAPH + {0xBA8E, 0x7C2C}, //9502 #CJK UNIFIED IDEOGRAPH + {0xBA8F, 0x7C2D}, //9503 #CJK UNIFIED IDEOGRAPH + {0xBA90, 0x7C2E}, //9504 #CJK UNIFIED IDEOGRAPH + {0xBA91, 0x7C2F}, //9505 #CJK UNIFIED IDEOGRAPH + {0xBA92, 0x7C30}, //9506 #CJK UNIFIED IDEOGRAPH + {0xBA93, 0x7C31}, //9507 #CJK UNIFIED IDEOGRAPH + {0xBA94, 0x7C32}, //9508 #CJK UNIFIED IDEOGRAPH + {0xBA95, 0x7C33}, //9509 #CJK UNIFIED IDEOGRAPH + {0xBA96, 0x7C34}, //9510 #CJK UNIFIED IDEOGRAPH + {0xBA97, 0x7C35}, //9511 #CJK UNIFIED IDEOGRAPH + {0xBA98, 0x7C36}, //9512 #CJK UNIFIED IDEOGRAPH + {0xBA99, 0x7C37}, //9513 #CJK UNIFIED IDEOGRAPH + {0xBA9A, 0x7C39}, //9514 #CJK UNIFIED IDEOGRAPH + {0xBA9B, 0x7C3A}, //9515 #CJK UNIFIED IDEOGRAPH + {0xBA9C, 0x7C3B}, //9516 #CJK UNIFIED IDEOGRAPH + {0xBA9D, 0x7C3C}, //9517 #CJK UNIFIED IDEOGRAPH + {0xBA9E, 0x7C3D}, //9518 #CJK UNIFIED IDEOGRAPH + {0xBA9F, 0x7C3E}, //9519 #CJK UNIFIED IDEOGRAPH + {0xBAA0, 0x7C42}, //9520 #CJK UNIFIED IDEOGRAPH + {0xBAA1, 0x9AB8}, //9521 #CJK UNIFIED IDEOGRAPH + {0xBAA2, 0x5B69}, //9522 #CJK UNIFIED IDEOGRAPH + {0xBAA3, 0x6D77}, //9523 #CJK UNIFIED IDEOGRAPH + {0xBAA4, 0x6C26}, //9524 #CJK UNIFIED IDEOGRAPH + {0xBAA5, 0x4EA5}, //9525 #CJK UNIFIED IDEOGRAPH + {0xBAA6, 0x5BB3}, //9526 #CJK UNIFIED IDEOGRAPH + {0xBAA7, 0x9A87}, //9527 #CJK UNIFIED IDEOGRAPH + {0xBAA8, 0x9163}, //9528 #CJK UNIFIED IDEOGRAPH + {0xBAA9, 0x61A8}, //9529 #CJK UNIFIED IDEOGRAPH + {0xBAAA, 0x90AF}, //9530 #CJK UNIFIED IDEOGRAPH + {0xBAAB, 0x97E9}, //9531 #CJK UNIFIED IDEOGRAPH + {0xBAAC, 0x542B}, //9532 #CJK UNIFIED IDEOGRAPH + {0xBAAD, 0x6DB5}, //9533 #CJK UNIFIED IDEOGRAPH + {0xBAAE, 0x5BD2}, //9534 #CJK UNIFIED IDEOGRAPH + {0xBAAF, 0x51FD}, //9535 #CJK UNIFIED IDEOGRAPH + {0xBAB0, 0x558A}, //9536 #CJK UNIFIED IDEOGRAPH + {0xBAB1, 0x7F55}, //9537 #CJK UNIFIED IDEOGRAPH + {0xBAB2, 0x7FF0}, //9538 #CJK UNIFIED IDEOGRAPH + {0xBAB3, 0x64BC}, //9539 #CJK UNIFIED IDEOGRAPH + {0xBAB4, 0x634D}, //9540 #CJK UNIFIED IDEOGRAPH + {0xBAB5, 0x65F1}, //9541 #CJK UNIFIED IDEOGRAPH + {0xBAB6, 0x61BE}, //9542 #CJK UNIFIED IDEOGRAPH + {0xBAB7, 0x608D}, //9543 #CJK UNIFIED IDEOGRAPH + {0xBAB8, 0x710A}, //9544 #CJK UNIFIED IDEOGRAPH + {0xBAB9, 0x6C57}, //9545 #CJK UNIFIED IDEOGRAPH + {0xBABA, 0x6C49}, //9546 #CJK UNIFIED IDEOGRAPH + {0xBABB, 0x592F}, //9547 #CJK UNIFIED IDEOGRAPH + {0xBABC, 0x676D}, //9548 #CJK UNIFIED IDEOGRAPH + {0xBABD, 0x822A}, //9549 #CJK UNIFIED IDEOGRAPH + {0xBABE, 0x58D5}, //9550 #CJK UNIFIED IDEOGRAPH + {0xBABF, 0x568E}, //9551 #CJK UNIFIED IDEOGRAPH + {0xBAC0, 0x8C6A}, //9552 #CJK UNIFIED IDEOGRAPH + {0xBAC1, 0x6BEB}, //9553 #CJK UNIFIED IDEOGRAPH + {0xBAC2, 0x90DD}, //9554 #CJK UNIFIED IDEOGRAPH + {0xBAC3, 0x597D}, //9555 #CJK UNIFIED IDEOGRAPH + {0xBAC4, 0x8017}, //9556 #CJK UNIFIED IDEOGRAPH + {0xBAC5, 0x53F7}, //9557 #CJK UNIFIED IDEOGRAPH + {0xBAC6, 0x6D69}, //9558 #CJK UNIFIED IDEOGRAPH + {0xBAC7, 0x5475}, //9559 #CJK UNIFIED IDEOGRAPH + {0xBAC8, 0x559D}, //9560 #CJK UNIFIED IDEOGRAPH + {0xBAC9, 0x8377}, //9561 #CJK UNIFIED IDEOGRAPH + {0xBACA, 0x83CF}, //9562 #CJK UNIFIED IDEOGRAPH + {0xBACB, 0x6838}, //9563 #CJK UNIFIED IDEOGRAPH + {0xBACC, 0x79BE}, //9564 #CJK UNIFIED IDEOGRAPH + {0xBACD, 0x548C}, //9565 #CJK UNIFIED IDEOGRAPH + {0xBACE, 0x4F55}, //9566 #CJK UNIFIED IDEOGRAPH + {0xBACF, 0x5408}, //9567 #CJK UNIFIED IDEOGRAPH + {0xBAD0, 0x76D2}, //9568 #CJK UNIFIED IDEOGRAPH + {0xBAD1, 0x8C89}, //9569 #CJK UNIFIED IDEOGRAPH + {0xBAD2, 0x9602}, //9570 #CJK UNIFIED IDEOGRAPH + {0xBAD3, 0x6CB3}, //9571 #CJK UNIFIED IDEOGRAPH + {0xBAD4, 0x6DB8}, //9572 #CJK UNIFIED IDEOGRAPH + {0xBAD5, 0x8D6B}, //9573 #CJK UNIFIED IDEOGRAPH + {0xBAD6, 0x8910}, //9574 #CJK UNIFIED IDEOGRAPH + {0xBAD7, 0x9E64}, //9575 #CJK UNIFIED IDEOGRAPH + {0xBAD8, 0x8D3A}, //9576 #CJK UNIFIED IDEOGRAPH + {0xBAD9, 0x563F}, //9577 #CJK UNIFIED IDEOGRAPH + {0xBADA, 0x9ED1}, //9578 #CJK UNIFIED IDEOGRAPH + {0xBADB, 0x75D5}, //9579 #CJK UNIFIED IDEOGRAPH + {0xBADC, 0x5F88}, //9580 #CJK UNIFIED IDEOGRAPH + {0xBADD, 0x72E0}, //9581 #CJK UNIFIED IDEOGRAPH + {0xBADE, 0x6068}, //9582 #CJK UNIFIED IDEOGRAPH + {0xBADF, 0x54FC}, //9583 #CJK UNIFIED IDEOGRAPH + {0xBAE0, 0x4EA8}, //9584 #CJK UNIFIED IDEOGRAPH + {0xBAE1, 0x6A2A}, //9585 #CJK UNIFIED IDEOGRAPH + {0xBAE2, 0x8861}, //9586 #CJK UNIFIED IDEOGRAPH + {0xBAE3, 0x6052}, //9587 #CJK UNIFIED IDEOGRAPH + {0xBAE4, 0x8F70}, //9588 #CJK UNIFIED IDEOGRAPH + {0xBAE5, 0x54C4}, //9589 #CJK UNIFIED IDEOGRAPH + {0xBAE6, 0x70D8}, //9590 #CJK UNIFIED IDEOGRAPH + {0xBAE7, 0x8679}, //9591 #CJK UNIFIED IDEOGRAPH + {0xBAE8, 0x9E3F}, //9592 #CJK UNIFIED IDEOGRAPH + {0xBAE9, 0x6D2A}, //9593 #CJK UNIFIED IDEOGRAPH + {0xBAEA, 0x5B8F}, //9594 #CJK UNIFIED IDEOGRAPH + {0xBAEB, 0x5F18}, //9595 #CJK UNIFIED IDEOGRAPH + {0xBAEC, 0x7EA2}, //9596 #CJK UNIFIED IDEOGRAPH + {0xBAED, 0x5589}, //9597 #CJK UNIFIED IDEOGRAPH + {0xBAEE, 0x4FAF}, //9598 #CJK UNIFIED IDEOGRAPH + {0xBAEF, 0x7334}, //9599 #CJK UNIFIED IDEOGRAPH + {0xBAF0, 0x543C}, //9600 #CJK UNIFIED IDEOGRAPH + {0xBAF1, 0x539A}, //9601 #CJK UNIFIED IDEOGRAPH + {0xBAF2, 0x5019}, //9602 #CJK UNIFIED IDEOGRAPH + {0xBAF3, 0x540E}, //9603 #CJK UNIFIED IDEOGRAPH + {0xBAF4, 0x547C}, //9604 #CJK UNIFIED IDEOGRAPH + {0xBAF5, 0x4E4E}, //9605 #CJK UNIFIED IDEOGRAPH + {0xBAF6, 0x5FFD}, //9606 #CJK UNIFIED IDEOGRAPH + {0xBAF7, 0x745A}, //9607 #CJK UNIFIED IDEOGRAPH + {0xBAF8, 0x58F6}, //9608 #CJK UNIFIED IDEOGRAPH + {0xBAF9, 0x846B}, //9609 #CJK UNIFIED IDEOGRAPH + {0xBAFA, 0x80E1}, //9610 #CJK UNIFIED IDEOGRAPH + {0xBAFB, 0x8774}, //9611 #CJK UNIFIED IDEOGRAPH + {0xBAFC, 0x72D0}, //9612 #CJK UNIFIED IDEOGRAPH + {0xBAFD, 0x7CCA}, //9613 #CJK UNIFIED IDEOGRAPH + {0xBAFE, 0x6E56}, //9614 #CJK UNIFIED IDEOGRAPH + {0xBB40, 0x7C43}, //9615 #CJK UNIFIED IDEOGRAPH + {0xBB41, 0x7C44}, //9616 #CJK UNIFIED IDEOGRAPH + {0xBB42, 0x7C45}, //9617 #CJK UNIFIED IDEOGRAPH + {0xBB43, 0x7C46}, //9618 #CJK UNIFIED IDEOGRAPH + {0xBB44, 0x7C47}, //9619 #CJK UNIFIED IDEOGRAPH + {0xBB45, 0x7C48}, //9620 #CJK UNIFIED IDEOGRAPH + {0xBB46, 0x7C49}, //9621 #CJK UNIFIED IDEOGRAPH + {0xBB47, 0x7C4A}, //9622 #CJK UNIFIED IDEOGRAPH + {0xBB48, 0x7C4B}, //9623 #CJK UNIFIED IDEOGRAPH + {0xBB49, 0x7C4C}, //9624 #CJK UNIFIED IDEOGRAPH + {0xBB4A, 0x7C4E}, //9625 #CJK UNIFIED IDEOGRAPH + {0xBB4B, 0x7C4F}, //9626 #CJK UNIFIED IDEOGRAPH + {0xBB4C, 0x7C50}, //9627 #CJK UNIFIED IDEOGRAPH + {0xBB4D, 0x7C51}, //9628 #CJK UNIFIED IDEOGRAPH + {0xBB4E, 0x7C52}, //9629 #CJK UNIFIED IDEOGRAPH + {0xBB4F, 0x7C53}, //9630 #CJK UNIFIED IDEOGRAPH + {0xBB50, 0x7C54}, //9631 #CJK UNIFIED IDEOGRAPH + {0xBB51, 0x7C55}, //9632 #CJK UNIFIED IDEOGRAPH + {0xBB52, 0x7C56}, //9633 #CJK UNIFIED IDEOGRAPH + {0xBB53, 0x7C57}, //9634 #CJK UNIFIED IDEOGRAPH + {0xBB54, 0x7C58}, //9635 #CJK UNIFIED IDEOGRAPH + {0xBB55, 0x7C59}, //9636 #CJK UNIFIED IDEOGRAPH + {0xBB56, 0x7C5A}, //9637 #CJK UNIFIED IDEOGRAPH + {0xBB57, 0x7C5B}, //9638 #CJK UNIFIED IDEOGRAPH + {0xBB58, 0x7C5C}, //9639 #CJK UNIFIED IDEOGRAPH + {0xBB59, 0x7C5D}, //9640 #CJK UNIFIED IDEOGRAPH + {0xBB5A, 0x7C5E}, //9641 #CJK UNIFIED IDEOGRAPH + {0xBB5B, 0x7C5F}, //9642 #CJK UNIFIED IDEOGRAPH + {0xBB5C, 0x7C60}, //9643 #CJK UNIFIED IDEOGRAPH + {0xBB5D, 0x7C61}, //9644 #CJK UNIFIED IDEOGRAPH + {0xBB5E, 0x7C62}, //9645 #CJK UNIFIED IDEOGRAPH + {0xBB5F, 0x7C63}, //9646 #CJK UNIFIED IDEOGRAPH + {0xBB60, 0x7C64}, //9647 #CJK UNIFIED IDEOGRAPH + {0xBB61, 0x7C65}, //9648 #CJK UNIFIED IDEOGRAPH + {0xBB62, 0x7C66}, //9649 #CJK UNIFIED IDEOGRAPH + {0xBB63, 0x7C67}, //9650 #CJK UNIFIED IDEOGRAPH + {0xBB64, 0x7C68}, //9651 #CJK UNIFIED IDEOGRAPH + {0xBB65, 0x7C69}, //9652 #CJK UNIFIED IDEOGRAPH + {0xBB66, 0x7C6A}, //9653 #CJK UNIFIED IDEOGRAPH + {0xBB67, 0x7C6B}, //9654 #CJK UNIFIED IDEOGRAPH + {0xBB68, 0x7C6C}, //9655 #CJK UNIFIED IDEOGRAPH + {0xBB69, 0x7C6D}, //9656 #CJK UNIFIED IDEOGRAPH + {0xBB6A, 0x7C6E}, //9657 #CJK UNIFIED IDEOGRAPH + {0xBB6B, 0x7C6F}, //9658 #CJK UNIFIED IDEOGRAPH + {0xBB6C, 0x7C70}, //9659 #CJK UNIFIED IDEOGRAPH + {0xBB6D, 0x7C71}, //9660 #CJK UNIFIED IDEOGRAPH + {0xBB6E, 0x7C72}, //9661 #CJK UNIFIED IDEOGRAPH + {0xBB6F, 0x7C75}, //9662 #CJK UNIFIED IDEOGRAPH + {0xBB70, 0x7C76}, //9663 #CJK UNIFIED IDEOGRAPH + {0xBB71, 0x7C77}, //9664 #CJK UNIFIED IDEOGRAPH + {0xBB72, 0x7C78}, //9665 #CJK UNIFIED IDEOGRAPH + {0xBB73, 0x7C79}, //9666 #CJK UNIFIED IDEOGRAPH + {0xBB74, 0x7C7A}, //9667 #CJK UNIFIED IDEOGRAPH + {0xBB75, 0x7C7E}, //9668 #CJK UNIFIED IDEOGRAPH + {0xBB76, 0x7C7F}, //9669 #CJK UNIFIED IDEOGRAPH + {0xBB77, 0x7C80}, //9670 #CJK UNIFIED IDEOGRAPH + {0xBB78, 0x7C81}, //9671 #CJK UNIFIED IDEOGRAPH + {0xBB79, 0x7C82}, //9672 #CJK UNIFIED IDEOGRAPH + {0xBB7A, 0x7C83}, //9673 #CJK UNIFIED IDEOGRAPH + {0xBB7B, 0x7C84}, //9674 #CJK UNIFIED IDEOGRAPH + {0xBB7C, 0x7C85}, //9675 #CJK UNIFIED IDEOGRAPH + {0xBB7D, 0x7C86}, //9676 #CJK UNIFIED IDEOGRAPH + {0xBB7E, 0x7C87}, //9677 #CJK UNIFIED IDEOGRAPH + {0xBB80, 0x7C88}, //9678 #CJK UNIFIED IDEOGRAPH + {0xBB81, 0x7C8A}, //9679 #CJK UNIFIED IDEOGRAPH + {0xBB82, 0x7C8B}, //9680 #CJK UNIFIED IDEOGRAPH + {0xBB83, 0x7C8C}, //9681 #CJK UNIFIED IDEOGRAPH + {0xBB84, 0x7C8D}, //9682 #CJK UNIFIED IDEOGRAPH + {0xBB85, 0x7C8E}, //9683 #CJK UNIFIED IDEOGRAPH + {0xBB86, 0x7C8F}, //9684 #CJK UNIFIED IDEOGRAPH + {0xBB87, 0x7C90}, //9685 #CJK UNIFIED IDEOGRAPH + {0xBB88, 0x7C93}, //9686 #CJK UNIFIED IDEOGRAPH + {0xBB89, 0x7C94}, //9687 #CJK UNIFIED IDEOGRAPH + {0xBB8A, 0x7C96}, //9688 #CJK UNIFIED IDEOGRAPH + {0xBB8B, 0x7C99}, //9689 #CJK UNIFIED IDEOGRAPH + {0xBB8C, 0x7C9A}, //9690 #CJK UNIFIED IDEOGRAPH + {0xBB8D, 0x7C9B}, //9691 #CJK UNIFIED IDEOGRAPH + {0xBB8E, 0x7CA0}, //9692 #CJK UNIFIED IDEOGRAPH + {0xBB8F, 0x7CA1}, //9693 #CJK UNIFIED IDEOGRAPH + {0xBB90, 0x7CA3}, //9694 #CJK UNIFIED IDEOGRAPH + {0xBB91, 0x7CA6}, //9695 #CJK UNIFIED IDEOGRAPH + {0xBB92, 0x7CA7}, //9696 #CJK UNIFIED IDEOGRAPH + {0xBB93, 0x7CA8}, //9697 #CJK UNIFIED IDEOGRAPH + {0xBB94, 0x7CA9}, //9698 #CJK UNIFIED IDEOGRAPH + {0xBB95, 0x7CAB}, //9699 #CJK UNIFIED IDEOGRAPH + {0xBB96, 0x7CAC}, //9700 #CJK UNIFIED IDEOGRAPH + {0xBB97, 0x7CAD}, //9701 #CJK UNIFIED IDEOGRAPH + {0xBB98, 0x7CAF}, //9702 #CJK UNIFIED IDEOGRAPH + {0xBB99, 0x7CB0}, //9703 #CJK UNIFIED IDEOGRAPH + {0xBB9A, 0x7CB4}, //9704 #CJK UNIFIED IDEOGRAPH + {0xBB9B, 0x7CB5}, //9705 #CJK UNIFIED IDEOGRAPH + {0xBB9C, 0x7CB6}, //9706 #CJK UNIFIED IDEOGRAPH + {0xBB9D, 0x7CB7}, //9707 #CJK UNIFIED IDEOGRAPH + {0xBB9E, 0x7CB8}, //9708 #CJK UNIFIED IDEOGRAPH + {0xBB9F, 0x7CBA}, //9709 #CJK UNIFIED IDEOGRAPH + {0xBBA0, 0x7CBB}, //9710 #CJK UNIFIED IDEOGRAPH + {0xBBA1, 0x5F27}, //9711 #CJK UNIFIED IDEOGRAPH + {0xBBA2, 0x864E}, //9712 #CJK UNIFIED IDEOGRAPH + {0xBBA3, 0x552C}, //9713 #CJK UNIFIED IDEOGRAPH + {0xBBA4, 0x62A4}, //9714 #CJK UNIFIED IDEOGRAPH + {0xBBA5, 0x4E92}, //9715 #CJK UNIFIED IDEOGRAPH + {0xBBA6, 0x6CAA}, //9716 #CJK UNIFIED IDEOGRAPH + {0xBBA7, 0x6237}, //9717 #CJK UNIFIED IDEOGRAPH + {0xBBA8, 0x82B1}, //9718 #CJK UNIFIED IDEOGRAPH + {0xBBA9, 0x54D7}, //9719 #CJK UNIFIED IDEOGRAPH + {0xBBAA, 0x534E}, //9720 #CJK UNIFIED IDEOGRAPH + {0xBBAB, 0x733E}, //9721 #CJK UNIFIED IDEOGRAPH + {0xBBAC, 0x6ED1}, //9722 #CJK UNIFIED IDEOGRAPH + {0xBBAD, 0x753B}, //9723 #CJK UNIFIED IDEOGRAPH + {0xBBAE, 0x5212}, //9724 #CJK UNIFIED IDEOGRAPH + {0xBBAF, 0x5316}, //9725 #CJK UNIFIED IDEOGRAPH + {0xBBB0, 0x8BDD}, //9726 #CJK UNIFIED IDEOGRAPH + {0xBBB1, 0x69D0}, //9727 #CJK UNIFIED IDEOGRAPH + {0xBBB2, 0x5F8A}, //9728 #CJK UNIFIED IDEOGRAPH + {0xBBB3, 0x6000}, //9729 #CJK UNIFIED IDEOGRAPH + {0xBBB4, 0x6DEE}, //9730 #CJK UNIFIED IDEOGRAPH + {0xBBB5, 0x574F}, //9731 #CJK UNIFIED IDEOGRAPH + {0xBBB6, 0x6B22}, //9732 #CJK UNIFIED IDEOGRAPH + {0xBBB7, 0x73AF}, //9733 #CJK UNIFIED IDEOGRAPH + {0xBBB8, 0x6853}, //9734 #CJK UNIFIED IDEOGRAPH + {0xBBB9, 0x8FD8}, //9735 #CJK UNIFIED IDEOGRAPH + {0xBBBA, 0x7F13}, //9736 #CJK UNIFIED IDEOGRAPH + {0xBBBB, 0x6362}, //9737 #CJK UNIFIED IDEOGRAPH + {0xBBBC, 0x60A3}, //9738 #CJK UNIFIED IDEOGRAPH + {0xBBBD, 0x5524}, //9739 #CJK UNIFIED IDEOGRAPH + {0xBBBE, 0x75EA}, //9740 #CJK UNIFIED IDEOGRAPH + {0xBBBF, 0x8C62}, //9741 #CJK UNIFIED IDEOGRAPH + {0xBBC0, 0x7115}, //9742 #CJK UNIFIED IDEOGRAPH + {0xBBC1, 0x6DA3}, //9743 #CJK UNIFIED IDEOGRAPH + {0xBBC2, 0x5BA6}, //9744 #CJK UNIFIED IDEOGRAPH + {0xBBC3, 0x5E7B}, //9745 #CJK UNIFIED IDEOGRAPH + {0xBBC4, 0x8352}, //9746 #CJK UNIFIED IDEOGRAPH + {0xBBC5, 0x614C}, //9747 #CJK UNIFIED IDEOGRAPH + {0xBBC6, 0x9EC4}, //9748 #CJK UNIFIED IDEOGRAPH + {0xBBC7, 0x78FA}, //9749 #CJK UNIFIED IDEOGRAPH + {0xBBC8, 0x8757}, //9750 #CJK UNIFIED IDEOGRAPH + {0xBBC9, 0x7C27}, //9751 #CJK UNIFIED IDEOGRAPH + {0xBBCA, 0x7687}, //9752 #CJK UNIFIED IDEOGRAPH + {0xBBCB, 0x51F0}, //9753 #CJK UNIFIED IDEOGRAPH + {0xBBCC, 0x60F6}, //9754 #CJK UNIFIED IDEOGRAPH + {0xBBCD, 0x714C}, //9755 #CJK UNIFIED IDEOGRAPH + {0xBBCE, 0x6643}, //9756 #CJK UNIFIED IDEOGRAPH + {0xBBCF, 0x5E4C}, //9757 #CJK UNIFIED IDEOGRAPH + {0xBBD0, 0x604D}, //9758 #CJK UNIFIED IDEOGRAPH + {0xBBD1, 0x8C0E}, //9759 #CJK UNIFIED IDEOGRAPH + {0xBBD2, 0x7070}, //9760 #CJK UNIFIED IDEOGRAPH + {0xBBD3, 0x6325}, //9761 #CJK UNIFIED IDEOGRAPH + {0xBBD4, 0x8F89}, //9762 #CJK UNIFIED IDEOGRAPH + {0xBBD5, 0x5FBD}, //9763 #CJK UNIFIED IDEOGRAPH + {0xBBD6, 0x6062}, //9764 #CJK UNIFIED IDEOGRAPH + {0xBBD7, 0x86D4}, //9765 #CJK UNIFIED IDEOGRAPH + {0xBBD8, 0x56DE}, //9766 #CJK UNIFIED IDEOGRAPH + {0xBBD9, 0x6BC1}, //9767 #CJK UNIFIED IDEOGRAPH + {0xBBDA, 0x6094}, //9768 #CJK UNIFIED IDEOGRAPH + {0xBBDB, 0x6167}, //9769 #CJK UNIFIED IDEOGRAPH + {0xBBDC, 0x5349}, //9770 #CJK UNIFIED IDEOGRAPH + {0xBBDD, 0x60E0}, //9771 #CJK UNIFIED IDEOGRAPH + {0xBBDE, 0x6666}, //9772 #CJK UNIFIED IDEOGRAPH + {0xBBDF, 0x8D3F}, //9773 #CJK UNIFIED IDEOGRAPH + {0xBBE0, 0x79FD}, //9774 #CJK UNIFIED IDEOGRAPH + {0xBBE1, 0x4F1A}, //9775 #CJK UNIFIED IDEOGRAPH + {0xBBE2, 0x70E9}, //9776 #CJK UNIFIED IDEOGRAPH + {0xBBE3, 0x6C47}, //9777 #CJK UNIFIED IDEOGRAPH + {0xBBE4, 0x8BB3}, //9778 #CJK UNIFIED IDEOGRAPH + {0xBBE5, 0x8BF2}, //9779 #CJK UNIFIED IDEOGRAPH + {0xBBE6, 0x7ED8}, //9780 #CJK UNIFIED IDEOGRAPH + {0xBBE7, 0x8364}, //9781 #CJK UNIFIED IDEOGRAPH + {0xBBE8, 0x660F}, //9782 #CJK UNIFIED IDEOGRAPH + {0xBBE9, 0x5A5A}, //9783 #CJK UNIFIED IDEOGRAPH + {0xBBEA, 0x9B42}, //9784 #CJK UNIFIED IDEOGRAPH + {0xBBEB, 0x6D51}, //9785 #CJK UNIFIED IDEOGRAPH + {0xBBEC, 0x6DF7}, //9786 #CJK UNIFIED IDEOGRAPH + {0xBBED, 0x8C41}, //9787 #CJK UNIFIED IDEOGRAPH + {0xBBEE, 0x6D3B}, //9788 #CJK UNIFIED IDEOGRAPH + {0xBBEF, 0x4F19}, //9789 #CJK UNIFIED IDEOGRAPH + {0xBBF0, 0x706B}, //9790 #CJK UNIFIED IDEOGRAPH + {0xBBF1, 0x83B7}, //9791 #CJK UNIFIED IDEOGRAPH + {0xBBF2, 0x6216}, //9792 #CJK UNIFIED IDEOGRAPH + {0xBBF3, 0x60D1}, //9793 #CJK UNIFIED IDEOGRAPH + {0xBBF4, 0x970D}, //9794 #CJK UNIFIED IDEOGRAPH + {0xBBF5, 0x8D27}, //9795 #CJK UNIFIED IDEOGRAPH + {0xBBF6, 0x7978}, //9796 #CJK UNIFIED IDEOGRAPH + {0xBBF7, 0x51FB}, //9797 #CJK UNIFIED IDEOGRAPH + {0xBBF8, 0x573E}, //9798 #CJK UNIFIED IDEOGRAPH + {0xBBF9, 0x57FA}, //9799 #CJK UNIFIED IDEOGRAPH + {0xBBFA, 0x673A}, //9800 #CJK UNIFIED IDEOGRAPH + {0xBBFB, 0x7578}, //9801 #CJK UNIFIED IDEOGRAPH + {0xBBFC, 0x7A3D}, //9802 #CJK UNIFIED IDEOGRAPH + {0xBBFD, 0x79EF}, //9803 #CJK UNIFIED IDEOGRAPH + {0xBBFE, 0x7B95}, //9804 #CJK UNIFIED IDEOGRAPH + {0xBC40, 0x7CBF}, //9805 #CJK UNIFIED IDEOGRAPH + {0xBC41, 0x7CC0}, //9806 #CJK UNIFIED IDEOGRAPH + {0xBC42, 0x7CC2}, //9807 #CJK UNIFIED IDEOGRAPH + {0xBC43, 0x7CC3}, //9808 #CJK UNIFIED IDEOGRAPH + {0xBC44, 0x7CC4}, //9809 #CJK UNIFIED IDEOGRAPH + {0xBC45, 0x7CC6}, //9810 #CJK UNIFIED IDEOGRAPH + {0xBC46, 0x7CC9}, //9811 #CJK UNIFIED IDEOGRAPH + {0xBC47, 0x7CCB}, //9812 #CJK UNIFIED IDEOGRAPH + {0xBC48, 0x7CCE}, //9813 #CJK UNIFIED IDEOGRAPH + {0xBC49, 0x7CCF}, //9814 #CJK UNIFIED IDEOGRAPH + {0xBC4A, 0x7CD0}, //9815 #CJK UNIFIED IDEOGRAPH + {0xBC4B, 0x7CD1}, //9816 #CJK UNIFIED IDEOGRAPH + {0xBC4C, 0x7CD2}, //9817 #CJK UNIFIED IDEOGRAPH + {0xBC4D, 0x7CD3}, //9818 #CJK UNIFIED IDEOGRAPH + {0xBC4E, 0x7CD4}, //9819 #CJK UNIFIED IDEOGRAPH + {0xBC4F, 0x7CD8}, //9820 #CJK UNIFIED IDEOGRAPH + {0xBC50, 0x7CDA}, //9821 #CJK UNIFIED IDEOGRAPH + {0xBC51, 0x7CDB}, //9822 #CJK UNIFIED IDEOGRAPH + {0xBC52, 0x7CDD}, //9823 #CJK UNIFIED IDEOGRAPH + {0xBC53, 0x7CDE}, //9824 #CJK UNIFIED IDEOGRAPH + {0xBC54, 0x7CE1}, //9825 #CJK UNIFIED IDEOGRAPH + {0xBC55, 0x7CE2}, //9826 #CJK UNIFIED IDEOGRAPH + {0xBC56, 0x7CE3}, //9827 #CJK UNIFIED IDEOGRAPH + {0xBC57, 0x7CE4}, //9828 #CJK UNIFIED IDEOGRAPH + {0xBC58, 0x7CE5}, //9829 #CJK UNIFIED IDEOGRAPH + {0xBC59, 0x7CE6}, //9830 #CJK UNIFIED IDEOGRAPH + {0xBC5A, 0x7CE7}, //9831 #CJK UNIFIED IDEOGRAPH + {0xBC5B, 0x7CE9}, //9832 #CJK UNIFIED IDEOGRAPH + {0xBC5C, 0x7CEA}, //9833 #CJK UNIFIED IDEOGRAPH + {0xBC5D, 0x7CEB}, //9834 #CJK UNIFIED IDEOGRAPH + {0xBC5E, 0x7CEC}, //9835 #CJK UNIFIED IDEOGRAPH + {0xBC5F, 0x7CED}, //9836 #CJK UNIFIED IDEOGRAPH + {0xBC60, 0x7CEE}, //9837 #CJK UNIFIED IDEOGRAPH + {0xBC61, 0x7CF0}, //9838 #CJK UNIFIED IDEOGRAPH + {0xBC62, 0x7CF1}, //9839 #CJK UNIFIED IDEOGRAPH + {0xBC63, 0x7CF2}, //9840 #CJK UNIFIED IDEOGRAPH + {0xBC64, 0x7CF3}, //9841 #CJK UNIFIED IDEOGRAPH + {0xBC65, 0x7CF4}, //9842 #CJK UNIFIED IDEOGRAPH + {0xBC66, 0x7CF5}, //9843 #CJK UNIFIED IDEOGRAPH + {0xBC67, 0x7CF6}, //9844 #CJK UNIFIED IDEOGRAPH + {0xBC68, 0x7CF7}, //9845 #CJK UNIFIED IDEOGRAPH + {0xBC69, 0x7CF9}, //9846 #CJK UNIFIED IDEOGRAPH + {0xBC6A, 0x7CFA}, //9847 #CJK UNIFIED IDEOGRAPH + {0xBC6B, 0x7CFC}, //9848 #CJK UNIFIED IDEOGRAPH + {0xBC6C, 0x7CFD}, //9849 #CJK UNIFIED IDEOGRAPH + {0xBC6D, 0x7CFE}, //9850 #CJK UNIFIED IDEOGRAPH + {0xBC6E, 0x7CFF}, //9851 #CJK UNIFIED IDEOGRAPH + {0xBC6F, 0x7D00}, //9852 #CJK UNIFIED IDEOGRAPH + {0xBC70, 0x7D01}, //9853 #CJK UNIFIED IDEOGRAPH + {0xBC71, 0x7D02}, //9854 #CJK UNIFIED IDEOGRAPH + {0xBC72, 0x7D03}, //9855 #CJK UNIFIED IDEOGRAPH + {0xBC73, 0x7D04}, //9856 #CJK UNIFIED IDEOGRAPH + {0xBC74, 0x7D05}, //9857 #CJK UNIFIED IDEOGRAPH + {0xBC75, 0x7D06}, //9858 #CJK UNIFIED IDEOGRAPH + {0xBC76, 0x7D07}, //9859 #CJK UNIFIED IDEOGRAPH + {0xBC77, 0x7D08}, //9860 #CJK UNIFIED IDEOGRAPH + {0xBC78, 0x7D09}, //9861 #CJK UNIFIED IDEOGRAPH + {0xBC79, 0x7D0B}, //9862 #CJK UNIFIED IDEOGRAPH + {0xBC7A, 0x7D0C}, //9863 #CJK UNIFIED IDEOGRAPH + {0xBC7B, 0x7D0D}, //9864 #CJK UNIFIED IDEOGRAPH + {0xBC7C, 0x7D0E}, //9865 #CJK UNIFIED IDEOGRAPH + {0xBC7D, 0x7D0F}, //9866 #CJK UNIFIED IDEOGRAPH + {0xBC7E, 0x7D10}, //9867 #CJK UNIFIED IDEOGRAPH + {0xBC80, 0x7D11}, //9868 #CJK UNIFIED IDEOGRAPH + {0xBC81, 0x7D12}, //9869 #CJK UNIFIED IDEOGRAPH + {0xBC82, 0x7D13}, //9870 #CJK UNIFIED IDEOGRAPH + {0xBC83, 0x7D14}, //9871 #CJK UNIFIED IDEOGRAPH + {0xBC84, 0x7D15}, //9872 #CJK UNIFIED IDEOGRAPH + {0xBC85, 0x7D16}, //9873 #CJK UNIFIED IDEOGRAPH + {0xBC86, 0x7D17}, //9874 #CJK UNIFIED IDEOGRAPH + {0xBC87, 0x7D18}, //9875 #CJK UNIFIED IDEOGRAPH + {0xBC88, 0x7D19}, //9876 #CJK UNIFIED IDEOGRAPH + {0xBC89, 0x7D1A}, //9877 #CJK UNIFIED IDEOGRAPH + {0xBC8A, 0x7D1B}, //9878 #CJK UNIFIED IDEOGRAPH + {0xBC8B, 0x7D1C}, //9879 #CJK UNIFIED IDEOGRAPH + {0xBC8C, 0x7D1D}, //9880 #CJK UNIFIED IDEOGRAPH + {0xBC8D, 0x7D1E}, //9881 #CJK UNIFIED IDEOGRAPH + {0xBC8E, 0x7D1F}, //9882 #CJK UNIFIED IDEOGRAPH + {0xBC8F, 0x7D21}, //9883 #CJK UNIFIED IDEOGRAPH + {0xBC90, 0x7D23}, //9884 #CJK UNIFIED IDEOGRAPH + {0xBC91, 0x7D24}, //9885 #CJK UNIFIED IDEOGRAPH + {0xBC92, 0x7D25}, //9886 #CJK UNIFIED IDEOGRAPH + {0xBC93, 0x7D26}, //9887 #CJK UNIFIED IDEOGRAPH + {0xBC94, 0x7D28}, //9888 #CJK UNIFIED IDEOGRAPH + {0xBC95, 0x7D29}, //9889 #CJK UNIFIED IDEOGRAPH + {0xBC96, 0x7D2A}, //9890 #CJK UNIFIED IDEOGRAPH + {0xBC97, 0x7D2C}, //9891 #CJK UNIFIED IDEOGRAPH + {0xBC98, 0x7D2D}, //9892 #CJK UNIFIED IDEOGRAPH + {0xBC99, 0x7D2E}, //9893 #CJK UNIFIED IDEOGRAPH + {0xBC9A, 0x7D30}, //9894 #CJK UNIFIED IDEOGRAPH + {0xBC9B, 0x7D31}, //9895 #CJK UNIFIED IDEOGRAPH + {0xBC9C, 0x7D32}, //9896 #CJK UNIFIED IDEOGRAPH + {0xBC9D, 0x7D33}, //9897 #CJK UNIFIED IDEOGRAPH + {0xBC9E, 0x7D34}, //9898 #CJK UNIFIED IDEOGRAPH + {0xBC9F, 0x7D35}, //9899 #CJK UNIFIED IDEOGRAPH + {0xBCA0, 0x7D36}, //9900 #CJK UNIFIED IDEOGRAPH + {0xBCA1, 0x808C}, //9901 #CJK UNIFIED IDEOGRAPH + {0xBCA2, 0x9965}, //9902 #CJK UNIFIED IDEOGRAPH + {0xBCA3, 0x8FF9}, //9903 #CJK UNIFIED IDEOGRAPH + {0xBCA4, 0x6FC0}, //9904 #CJK UNIFIED IDEOGRAPH + {0xBCA5, 0x8BA5}, //9905 #CJK UNIFIED IDEOGRAPH + {0xBCA6, 0x9E21}, //9906 #CJK UNIFIED IDEOGRAPH + {0xBCA7, 0x59EC}, //9907 #CJK UNIFIED IDEOGRAPH + {0xBCA8, 0x7EE9}, //9908 #CJK UNIFIED IDEOGRAPH + {0xBCA9, 0x7F09}, //9909 #CJK UNIFIED IDEOGRAPH + {0xBCAA, 0x5409}, //9910 #CJK UNIFIED IDEOGRAPH + {0xBCAB, 0x6781}, //9911 #CJK UNIFIED IDEOGRAPH + {0xBCAC, 0x68D8}, //9912 #CJK UNIFIED IDEOGRAPH + {0xBCAD, 0x8F91}, //9913 #CJK UNIFIED IDEOGRAPH + {0xBCAE, 0x7C4D}, //9914 #CJK UNIFIED IDEOGRAPH + {0xBCAF, 0x96C6}, //9915 #CJK UNIFIED IDEOGRAPH + {0xBCB0, 0x53CA}, //9916 #CJK UNIFIED IDEOGRAPH + {0xBCB1, 0x6025}, //9917 #CJK UNIFIED IDEOGRAPH + {0xBCB2, 0x75BE}, //9918 #CJK UNIFIED IDEOGRAPH + {0xBCB3, 0x6C72}, //9919 #CJK UNIFIED IDEOGRAPH + {0xBCB4, 0x5373}, //9920 #CJK UNIFIED IDEOGRAPH + {0xBCB5, 0x5AC9}, //9921 #CJK UNIFIED IDEOGRAPH + {0xBCB6, 0x7EA7}, //9922 #CJK UNIFIED IDEOGRAPH + {0xBCB7, 0x6324}, //9923 #CJK UNIFIED IDEOGRAPH + {0xBCB8, 0x51E0}, //9924 #CJK UNIFIED IDEOGRAPH + {0xBCB9, 0x810A}, //9925 #CJK UNIFIED IDEOGRAPH + {0xBCBA, 0x5DF1}, //9926 #CJK UNIFIED IDEOGRAPH + {0xBCBB, 0x84DF}, //9927 #CJK UNIFIED IDEOGRAPH + {0xBCBC, 0x6280}, //9928 #CJK UNIFIED IDEOGRAPH + {0xBCBD, 0x5180}, //9929 #CJK UNIFIED IDEOGRAPH + {0xBCBE, 0x5B63}, //9930 #CJK UNIFIED IDEOGRAPH + {0xBCBF, 0x4F0E}, //9931 #CJK UNIFIED IDEOGRAPH + {0xBCC0, 0x796D}, //9932 #CJK UNIFIED IDEOGRAPH + {0xBCC1, 0x5242}, //9933 #CJK UNIFIED IDEOGRAPH + {0xBCC2, 0x60B8}, //9934 #CJK UNIFIED IDEOGRAPH + {0xBCC3, 0x6D4E}, //9935 #CJK UNIFIED IDEOGRAPH + {0xBCC4, 0x5BC4}, //9936 #CJK UNIFIED IDEOGRAPH + {0xBCC5, 0x5BC2}, //9937 #CJK UNIFIED IDEOGRAPH + {0xBCC6, 0x8BA1}, //9938 #CJK UNIFIED IDEOGRAPH + {0xBCC7, 0x8BB0}, //9939 #CJK UNIFIED IDEOGRAPH + {0xBCC8, 0x65E2}, //9940 #CJK UNIFIED IDEOGRAPH + {0xBCC9, 0x5FCC}, //9941 #CJK UNIFIED IDEOGRAPH + {0xBCCA, 0x9645}, //9942 #CJK UNIFIED IDEOGRAPH + {0xBCCB, 0x5993}, //9943 #CJK UNIFIED IDEOGRAPH + {0xBCCC, 0x7EE7}, //9944 #CJK UNIFIED IDEOGRAPH + {0xBCCD, 0x7EAA}, //9945 #CJK UNIFIED IDEOGRAPH + {0xBCCE, 0x5609}, //9946 #CJK UNIFIED IDEOGRAPH + {0xBCCF, 0x67B7}, //9947 #CJK UNIFIED IDEOGRAPH + {0xBCD0, 0x5939}, //9948 #CJK UNIFIED IDEOGRAPH + {0xBCD1, 0x4F73}, //9949 #CJK UNIFIED IDEOGRAPH + {0xBCD2, 0x5BB6}, //9950 #CJK UNIFIED IDEOGRAPH + {0xBCD3, 0x52A0}, //9951 #CJK UNIFIED IDEOGRAPH + {0xBCD4, 0x835A}, //9952 #CJK UNIFIED IDEOGRAPH + {0xBCD5, 0x988A}, //9953 #CJK UNIFIED IDEOGRAPH + {0xBCD6, 0x8D3E}, //9954 #CJK UNIFIED IDEOGRAPH + {0xBCD7, 0x7532}, //9955 #CJK UNIFIED IDEOGRAPH + {0xBCD8, 0x94BE}, //9956 #CJK UNIFIED IDEOGRAPH + {0xBCD9, 0x5047}, //9957 #CJK UNIFIED IDEOGRAPH + {0xBCDA, 0x7A3C}, //9958 #CJK UNIFIED IDEOGRAPH + {0xBCDB, 0x4EF7}, //9959 #CJK UNIFIED IDEOGRAPH + {0xBCDC, 0x67B6}, //9960 #CJK UNIFIED IDEOGRAPH + {0xBCDD, 0x9A7E}, //9961 #CJK UNIFIED IDEOGRAPH + {0xBCDE, 0x5AC1}, //9962 #CJK UNIFIED IDEOGRAPH + {0xBCDF, 0x6B7C}, //9963 #CJK UNIFIED IDEOGRAPH + {0xBCE0, 0x76D1}, //9964 #CJK UNIFIED IDEOGRAPH + {0xBCE1, 0x575A}, //9965 #CJK UNIFIED IDEOGRAPH + {0xBCE2, 0x5C16}, //9966 #CJK UNIFIED IDEOGRAPH + {0xBCE3, 0x7B3A}, //9967 #CJK UNIFIED IDEOGRAPH + {0xBCE4, 0x95F4}, //9968 #CJK UNIFIED IDEOGRAPH + {0xBCE5, 0x714E}, //9969 #CJK UNIFIED IDEOGRAPH + {0xBCE6, 0x517C}, //9970 #CJK UNIFIED IDEOGRAPH + {0xBCE7, 0x80A9}, //9971 #CJK UNIFIED IDEOGRAPH + {0xBCE8, 0x8270}, //9972 #CJK UNIFIED IDEOGRAPH + {0xBCE9, 0x5978}, //9973 #CJK UNIFIED IDEOGRAPH + {0xBCEA, 0x7F04}, //9974 #CJK UNIFIED IDEOGRAPH + {0xBCEB, 0x8327}, //9975 #CJK UNIFIED IDEOGRAPH + {0xBCEC, 0x68C0}, //9976 #CJK UNIFIED IDEOGRAPH + {0xBCED, 0x67EC}, //9977 #CJK UNIFIED IDEOGRAPH + {0xBCEE, 0x78B1}, //9978 #CJK UNIFIED IDEOGRAPH + {0xBCEF, 0x7877}, //9979 #CJK UNIFIED IDEOGRAPH + {0xBCF0, 0x62E3}, //9980 #CJK UNIFIED IDEOGRAPH + {0xBCF1, 0x6361}, //9981 #CJK UNIFIED IDEOGRAPH + {0xBCF2, 0x7B80}, //9982 #CJK UNIFIED IDEOGRAPH + {0xBCF3, 0x4FED}, //9983 #CJK UNIFIED IDEOGRAPH + {0xBCF4, 0x526A}, //9984 #CJK UNIFIED IDEOGRAPH + {0xBCF5, 0x51CF}, //9985 #CJK UNIFIED IDEOGRAPH + {0xBCF6, 0x8350}, //9986 #CJK UNIFIED IDEOGRAPH + {0xBCF7, 0x69DB}, //9987 #CJK UNIFIED IDEOGRAPH + {0xBCF8, 0x9274}, //9988 #CJK UNIFIED IDEOGRAPH + {0xBCF9, 0x8DF5}, //9989 #CJK UNIFIED IDEOGRAPH + {0xBCFA, 0x8D31}, //9990 #CJK UNIFIED IDEOGRAPH + {0xBCFB, 0x89C1}, //9991 #CJK UNIFIED IDEOGRAPH + {0xBCFC, 0x952E}, //9992 #CJK UNIFIED IDEOGRAPH + {0xBCFD, 0x7BAD}, //9993 #CJK UNIFIED IDEOGRAPH + {0xBCFE, 0x4EF6}, //9994 #CJK UNIFIED IDEOGRAPH + {0xBD40, 0x7D37}, //9995 #CJK UNIFIED IDEOGRAPH + {0xBD41, 0x7D38}, //9996 #CJK UNIFIED IDEOGRAPH + {0xBD42, 0x7D39}, //9997 #CJK UNIFIED IDEOGRAPH + {0xBD43, 0x7D3A}, //9998 #CJK UNIFIED IDEOGRAPH + {0xBD44, 0x7D3B}, //9999 #CJK UNIFIED IDEOGRAPH + {0xBD45, 0x7D3C}, //10000 #CJK UNIFIED IDEOGRAPH + {0xBD46, 0x7D3D}, //10001 #CJK UNIFIED IDEOGRAPH + {0xBD47, 0x7D3E}, //10002 #CJK UNIFIED IDEOGRAPH + {0xBD48, 0x7D3F}, //10003 #CJK UNIFIED IDEOGRAPH + {0xBD49, 0x7D40}, //10004 #CJK UNIFIED IDEOGRAPH + {0xBD4A, 0x7D41}, //10005 #CJK UNIFIED IDEOGRAPH + {0xBD4B, 0x7D42}, //10006 #CJK UNIFIED IDEOGRAPH + {0xBD4C, 0x7D43}, //10007 #CJK UNIFIED IDEOGRAPH + {0xBD4D, 0x7D44}, //10008 #CJK UNIFIED IDEOGRAPH + {0xBD4E, 0x7D45}, //10009 #CJK UNIFIED IDEOGRAPH + {0xBD4F, 0x7D46}, //10010 #CJK UNIFIED IDEOGRAPH + {0xBD50, 0x7D47}, //10011 #CJK UNIFIED IDEOGRAPH + {0xBD51, 0x7D48}, //10012 #CJK UNIFIED IDEOGRAPH + {0xBD52, 0x7D49}, //10013 #CJK UNIFIED IDEOGRAPH + {0xBD53, 0x7D4A}, //10014 #CJK UNIFIED IDEOGRAPH + {0xBD54, 0x7D4B}, //10015 #CJK UNIFIED IDEOGRAPH + {0xBD55, 0x7D4C}, //10016 #CJK UNIFIED IDEOGRAPH + {0xBD56, 0x7D4D}, //10017 #CJK UNIFIED IDEOGRAPH + {0xBD57, 0x7D4E}, //10018 #CJK UNIFIED IDEOGRAPH + {0xBD58, 0x7D4F}, //10019 #CJK UNIFIED IDEOGRAPH + {0xBD59, 0x7D50}, //10020 #CJK UNIFIED IDEOGRAPH + {0xBD5A, 0x7D51}, //10021 #CJK UNIFIED IDEOGRAPH + {0xBD5B, 0x7D52}, //10022 #CJK UNIFIED IDEOGRAPH + {0xBD5C, 0x7D53}, //10023 #CJK UNIFIED IDEOGRAPH + {0xBD5D, 0x7D54}, //10024 #CJK UNIFIED IDEOGRAPH + {0xBD5E, 0x7D55}, //10025 #CJK UNIFIED IDEOGRAPH + {0xBD5F, 0x7D56}, //10026 #CJK UNIFIED IDEOGRAPH + {0xBD60, 0x7D57}, //10027 #CJK UNIFIED IDEOGRAPH + {0xBD61, 0x7D58}, //10028 #CJK UNIFIED IDEOGRAPH + {0xBD62, 0x7D59}, //10029 #CJK UNIFIED IDEOGRAPH + {0xBD63, 0x7D5A}, //10030 #CJK UNIFIED IDEOGRAPH + {0xBD64, 0x7D5B}, //10031 #CJK UNIFIED IDEOGRAPH + {0xBD65, 0x7D5C}, //10032 #CJK UNIFIED IDEOGRAPH + {0xBD66, 0x7D5D}, //10033 #CJK UNIFIED IDEOGRAPH + {0xBD67, 0x7D5E}, //10034 #CJK UNIFIED IDEOGRAPH + {0xBD68, 0x7D5F}, //10035 #CJK UNIFIED IDEOGRAPH + {0xBD69, 0x7D60}, //10036 #CJK UNIFIED IDEOGRAPH + {0xBD6A, 0x7D61}, //10037 #CJK UNIFIED IDEOGRAPH + {0xBD6B, 0x7D62}, //10038 #CJK UNIFIED IDEOGRAPH + {0xBD6C, 0x7D63}, //10039 #CJK UNIFIED IDEOGRAPH + {0xBD6D, 0x7D64}, //10040 #CJK UNIFIED IDEOGRAPH + {0xBD6E, 0x7D65}, //10041 #CJK UNIFIED IDEOGRAPH + {0xBD6F, 0x7D66}, //10042 #CJK UNIFIED IDEOGRAPH + {0xBD70, 0x7D67}, //10043 #CJK UNIFIED IDEOGRAPH + {0xBD71, 0x7D68}, //10044 #CJK UNIFIED IDEOGRAPH + {0xBD72, 0x7D69}, //10045 #CJK UNIFIED IDEOGRAPH + {0xBD73, 0x7D6A}, //10046 #CJK UNIFIED IDEOGRAPH + {0xBD74, 0x7D6B}, //10047 #CJK UNIFIED IDEOGRAPH + {0xBD75, 0x7D6C}, //10048 #CJK UNIFIED IDEOGRAPH + {0xBD76, 0x7D6D}, //10049 #CJK UNIFIED IDEOGRAPH + {0xBD77, 0x7D6F}, //10050 #CJK UNIFIED IDEOGRAPH + {0xBD78, 0x7D70}, //10051 #CJK UNIFIED IDEOGRAPH + {0xBD79, 0x7D71}, //10052 #CJK UNIFIED IDEOGRAPH + {0xBD7A, 0x7D72}, //10053 #CJK UNIFIED IDEOGRAPH + {0xBD7B, 0x7D73}, //10054 #CJK UNIFIED IDEOGRAPH + {0xBD7C, 0x7D74}, //10055 #CJK UNIFIED IDEOGRAPH + {0xBD7D, 0x7D75}, //10056 #CJK UNIFIED IDEOGRAPH + {0xBD7E, 0x7D76}, //10057 #CJK UNIFIED IDEOGRAPH + {0xBD80, 0x7D78}, //10058 #CJK UNIFIED IDEOGRAPH + {0xBD81, 0x7D79}, //10059 #CJK UNIFIED IDEOGRAPH + {0xBD82, 0x7D7A}, //10060 #CJK UNIFIED IDEOGRAPH + {0xBD83, 0x7D7B}, //10061 #CJK UNIFIED IDEOGRAPH + {0xBD84, 0x7D7C}, //10062 #CJK UNIFIED IDEOGRAPH + {0xBD85, 0x7D7D}, //10063 #CJK UNIFIED IDEOGRAPH + {0xBD86, 0x7D7E}, //10064 #CJK UNIFIED IDEOGRAPH + {0xBD87, 0x7D7F}, //10065 #CJK UNIFIED IDEOGRAPH + {0xBD88, 0x7D80}, //10066 #CJK UNIFIED IDEOGRAPH + {0xBD89, 0x7D81}, //10067 #CJK UNIFIED IDEOGRAPH + {0xBD8A, 0x7D82}, //10068 #CJK UNIFIED IDEOGRAPH + {0xBD8B, 0x7D83}, //10069 #CJK UNIFIED IDEOGRAPH + {0xBD8C, 0x7D84}, //10070 #CJK UNIFIED IDEOGRAPH + {0xBD8D, 0x7D85}, //10071 #CJK UNIFIED IDEOGRAPH + {0xBD8E, 0x7D86}, //10072 #CJK UNIFIED IDEOGRAPH + {0xBD8F, 0x7D87}, //10073 #CJK UNIFIED IDEOGRAPH + {0xBD90, 0x7D88}, //10074 #CJK UNIFIED IDEOGRAPH + {0xBD91, 0x7D89}, //10075 #CJK UNIFIED IDEOGRAPH + {0xBD92, 0x7D8A}, //10076 #CJK UNIFIED IDEOGRAPH + {0xBD93, 0x7D8B}, //10077 #CJK UNIFIED IDEOGRAPH + {0xBD94, 0x7D8C}, //10078 #CJK UNIFIED IDEOGRAPH + {0xBD95, 0x7D8D}, //10079 #CJK UNIFIED IDEOGRAPH + {0xBD96, 0x7D8E}, //10080 #CJK UNIFIED IDEOGRAPH + {0xBD97, 0x7D8F}, //10081 #CJK UNIFIED IDEOGRAPH + {0xBD98, 0x7D90}, //10082 #CJK UNIFIED IDEOGRAPH + {0xBD99, 0x7D91}, //10083 #CJK UNIFIED IDEOGRAPH + {0xBD9A, 0x7D92}, //10084 #CJK UNIFIED IDEOGRAPH + {0xBD9B, 0x7D93}, //10085 #CJK UNIFIED IDEOGRAPH + {0xBD9C, 0x7D94}, //10086 #CJK UNIFIED IDEOGRAPH + {0xBD9D, 0x7D95}, //10087 #CJK UNIFIED IDEOGRAPH + {0xBD9E, 0x7D96}, //10088 #CJK UNIFIED IDEOGRAPH + {0xBD9F, 0x7D97}, //10089 #CJK UNIFIED IDEOGRAPH + {0xBDA0, 0x7D98}, //10090 #CJK UNIFIED IDEOGRAPH + {0xBDA1, 0x5065}, //10091 #CJK UNIFIED IDEOGRAPH + {0xBDA2, 0x8230}, //10092 #CJK UNIFIED IDEOGRAPH + {0xBDA3, 0x5251}, //10093 #CJK UNIFIED IDEOGRAPH + {0xBDA4, 0x996F}, //10094 #CJK UNIFIED IDEOGRAPH + {0xBDA5, 0x6E10}, //10095 #CJK UNIFIED IDEOGRAPH + {0xBDA6, 0x6E85}, //10096 #CJK UNIFIED IDEOGRAPH + {0xBDA7, 0x6DA7}, //10097 #CJK UNIFIED IDEOGRAPH + {0xBDA8, 0x5EFA}, //10098 #CJK UNIFIED IDEOGRAPH + {0xBDA9, 0x50F5}, //10099 #CJK UNIFIED IDEOGRAPH + {0xBDAA, 0x59DC}, //10100 #CJK UNIFIED IDEOGRAPH + {0xBDAB, 0x5C06}, //10101 #CJK UNIFIED IDEOGRAPH + {0xBDAC, 0x6D46}, //10102 #CJK UNIFIED IDEOGRAPH + {0xBDAD, 0x6C5F}, //10103 #CJK UNIFIED IDEOGRAPH + {0xBDAE, 0x7586}, //10104 #CJK UNIFIED IDEOGRAPH + {0xBDAF, 0x848B}, //10105 #CJK UNIFIED IDEOGRAPH + {0xBDB0, 0x6868}, //10106 #CJK UNIFIED IDEOGRAPH + {0xBDB1, 0x5956}, //10107 #CJK UNIFIED IDEOGRAPH + {0xBDB2, 0x8BB2}, //10108 #CJK UNIFIED IDEOGRAPH + {0xBDB3, 0x5320}, //10109 #CJK UNIFIED IDEOGRAPH + {0xBDB4, 0x9171}, //10110 #CJK UNIFIED IDEOGRAPH + {0xBDB5, 0x964D}, //10111 #CJK UNIFIED IDEOGRAPH + {0xBDB6, 0x8549}, //10112 #CJK UNIFIED IDEOGRAPH + {0xBDB7, 0x6912}, //10113 #CJK UNIFIED IDEOGRAPH + {0xBDB8, 0x7901}, //10114 #CJK UNIFIED IDEOGRAPH + {0xBDB9, 0x7126}, //10115 #CJK UNIFIED IDEOGRAPH + {0xBDBA, 0x80F6}, //10116 #CJK UNIFIED IDEOGRAPH + {0xBDBB, 0x4EA4}, //10117 #CJK UNIFIED IDEOGRAPH + {0xBDBC, 0x90CA}, //10118 #CJK UNIFIED IDEOGRAPH + {0xBDBD, 0x6D47}, //10119 #CJK UNIFIED IDEOGRAPH + {0xBDBE, 0x9A84}, //10120 #CJK UNIFIED IDEOGRAPH + {0xBDBF, 0x5A07}, //10121 #CJK UNIFIED IDEOGRAPH + {0xBDC0, 0x56BC}, //10122 #CJK UNIFIED IDEOGRAPH + {0xBDC1, 0x6405}, //10123 #CJK UNIFIED IDEOGRAPH + {0xBDC2, 0x94F0}, //10124 #CJK UNIFIED IDEOGRAPH + {0xBDC3, 0x77EB}, //10125 #CJK UNIFIED IDEOGRAPH + {0xBDC4, 0x4FA5}, //10126 #CJK UNIFIED IDEOGRAPH + {0xBDC5, 0x811A}, //10127 #CJK UNIFIED IDEOGRAPH + {0xBDC6, 0x72E1}, //10128 #CJK UNIFIED IDEOGRAPH + {0xBDC7, 0x89D2}, //10129 #CJK UNIFIED IDEOGRAPH + {0xBDC8, 0x997A}, //10130 #CJK UNIFIED IDEOGRAPH + {0xBDC9, 0x7F34}, //10131 #CJK UNIFIED IDEOGRAPH + {0xBDCA, 0x7EDE}, //10132 #CJK UNIFIED IDEOGRAPH + {0xBDCB, 0x527F}, //10133 #CJK UNIFIED IDEOGRAPH + {0xBDCC, 0x6559}, //10134 #CJK UNIFIED IDEOGRAPH + {0xBDCD, 0x9175}, //10135 #CJK UNIFIED IDEOGRAPH + {0xBDCE, 0x8F7F}, //10136 #CJK UNIFIED IDEOGRAPH + {0xBDCF, 0x8F83}, //10137 #CJK UNIFIED IDEOGRAPH + {0xBDD0, 0x53EB}, //10138 #CJK UNIFIED IDEOGRAPH + {0xBDD1, 0x7A96}, //10139 #CJK UNIFIED IDEOGRAPH + {0xBDD2, 0x63ED}, //10140 #CJK UNIFIED IDEOGRAPH + {0xBDD3, 0x63A5}, //10141 #CJK UNIFIED IDEOGRAPH + {0xBDD4, 0x7686}, //10142 #CJK UNIFIED IDEOGRAPH + {0xBDD5, 0x79F8}, //10143 #CJK UNIFIED IDEOGRAPH + {0xBDD6, 0x8857}, //10144 #CJK UNIFIED IDEOGRAPH + {0xBDD7, 0x9636}, //10145 #CJK UNIFIED IDEOGRAPH + {0xBDD8, 0x622A}, //10146 #CJK UNIFIED IDEOGRAPH + {0xBDD9, 0x52AB}, //10147 #CJK UNIFIED IDEOGRAPH + {0xBDDA, 0x8282}, //10148 #CJK UNIFIED IDEOGRAPH + {0xBDDB, 0x6854}, //10149 #CJK UNIFIED IDEOGRAPH + {0xBDDC, 0x6770}, //10150 #CJK UNIFIED IDEOGRAPH + {0xBDDD, 0x6377}, //10151 #CJK UNIFIED IDEOGRAPH + {0xBDDE, 0x776B}, //10152 #CJK UNIFIED IDEOGRAPH + {0xBDDF, 0x7AED}, //10153 #CJK UNIFIED IDEOGRAPH + {0xBDE0, 0x6D01}, //10154 #CJK UNIFIED IDEOGRAPH + {0xBDE1, 0x7ED3}, //10155 #CJK UNIFIED IDEOGRAPH + {0xBDE2, 0x89E3}, //10156 #CJK UNIFIED IDEOGRAPH + {0xBDE3, 0x59D0}, //10157 #CJK UNIFIED IDEOGRAPH + {0xBDE4, 0x6212}, //10158 #CJK UNIFIED IDEOGRAPH + {0xBDE5, 0x85C9}, //10159 #CJK UNIFIED IDEOGRAPH + {0xBDE6, 0x82A5}, //10160 #CJK UNIFIED IDEOGRAPH + {0xBDE7, 0x754C}, //10161 #CJK UNIFIED IDEOGRAPH + {0xBDE8, 0x501F}, //10162 #CJK UNIFIED IDEOGRAPH + {0xBDE9, 0x4ECB}, //10163 #CJK UNIFIED IDEOGRAPH + {0xBDEA, 0x75A5}, //10164 #CJK UNIFIED IDEOGRAPH + {0xBDEB, 0x8BEB}, //10165 #CJK UNIFIED IDEOGRAPH + {0xBDEC, 0x5C4A}, //10166 #CJK UNIFIED IDEOGRAPH + {0xBDED, 0x5DFE}, //10167 #CJK UNIFIED IDEOGRAPH + {0xBDEE, 0x7B4B}, //10168 #CJK UNIFIED IDEOGRAPH + {0xBDEF, 0x65A4}, //10169 #CJK UNIFIED IDEOGRAPH + {0xBDF0, 0x91D1}, //10170 #CJK UNIFIED IDEOGRAPH + {0xBDF1, 0x4ECA}, //10171 #CJK UNIFIED IDEOGRAPH + {0xBDF2, 0x6D25}, //10172 #CJK UNIFIED IDEOGRAPH + {0xBDF3, 0x895F}, //10173 #CJK UNIFIED IDEOGRAPH + {0xBDF4, 0x7D27}, //10174 #CJK UNIFIED IDEOGRAPH + {0xBDF5, 0x9526}, //10175 #CJK UNIFIED IDEOGRAPH + {0xBDF6, 0x4EC5}, //10176 #CJK UNIFIED IDEOGRAPH + {0xBDF7, 0x8C28}, //10177 #CJK UNIFIED IDEOGRAPH + {0xBDF8, 0x8FDB}, //10178 #CJK UNIFIED IDEOGRAPH + {0xBDF9, 0x9773}, //10179 #CJK UNIFIED IDEOGRAPH + {0xBDFA, 0x664B}, //10180 #CJK UNIFIED IDEOGRAPH + {0xBDFB, 0x7981}, //10181 #CJK UNIFIED IDEOGRAPH + {0xBDFC, 0x8FD1}, //10182 #CJK UNIFIED IDEOGRAPH + {0xBDFD, 0x70EC}, //10183 #CJK UNIFIED IDEOGRAPH + {0xBDFE, 0x6D78}, //10184 #CJK UNIFIED IDEOGRAPH + {0xBE40, 0x7D99}, //10185 #CJK UNIFIED IDEOGRAPH + {0xBE41, 0x7D9A}, //10186 #CJK UNIFIED IDEOGRAPH + {0xBE42, 0x7D9B}, //10187 #CJK UNIFIED IDEOGRAPH + {0xBE43, 0x7D9C}, //10188 #CJK UNIFIED IDEOGRAPH + {0xBE44, 0x7D9D}, //10189 #CJK UNIFIED IDEOGRAPH + {0xBE45, 0x7D9E}, //10190 #CJK UNIFIED IDEOGRAPH + {0xBE46, 0x7D9F}, //10191 #CJK UNIFIED IDEOGRAPH + {0xBE47, 0x7DA0}, //10192 #CJK UNIFIED IDEOGRAPH + {0xBE48, 0x7DA1}, //10193 #CJK UNIFIED IDEOGRAPH + {0xBE49, 0x7DA2}, //10194 #CJK UNIFIED IDEOGRAPH + {0xBE4A, 0x7DA3}, //10195 #CJK UNIFIED IDEOGRAPH + {0xBE4B, 0x7DA4}, //10196 #CJK UNIFIED IDEOGRAPH + {0xBE4C, 0x7DA5}, //10197 #CJK UNIFIED IDEOGRAPH + {0xBE4D, 0x7DA7}, //10198 #CJK UNIFIED IDEOGRAPH + {0xBE4E, 0x7DA8}, //10199 #CJK UNIFIED IDEOGRAPH + {0xBE4F, 0x7DA9}, //10200 #CJK UNIFIED IDEOGRAPH + {0xBE50, 0x7DAA}, //10201 #CJK UNIFIED IDEOGRAPH + {0xBE51, 0x7DAB}, //10202 #CJK UNIFIED IDEOGRAPH + {0xBE52, 0x7DAC}, //10203 #CJK UNIFIED IDEOGRAPH + {0xBE53, 0x7DAD}, //10204 #CJK UNIFIED IDEOGRAPH + {0xBE54, 0x7DAF}, //10205 #CJK UNIFIED IDEOGRAPH + {0xBE55, 0x7DB0}, //10206 #CJK UNIFIED IDEOGRAPH + {0xBE56, 0x7DB1}, //10207 #CJK UNIFIED IDEOGRAPH + {0xBE57, 0x7DB2}, //10208 #CJK UNIFIED IDEOGRAPH + {0xBE58, 0x7DB3}, //10209 #CJK UNIFIED IDEOGRAPH + {0xBE59, 0x7DB4}, //10210 #CJK UNIFIED IDEOGRAPH + {0xBE5A, 0x7DB5}, //10211 #CJK UNIFIED IDEOGRAPH + {0xBE5B, 0x7DB6}, //10212 #CJK UNIFIED IDEOGRAPH + {0xBE5C, 0x7DB7}, //10213 #CJK UNIFIED IDEOGRAPH + {0xBE5D, 0x7DB8}, //10214 #CJK UNIFIED IDEOGRAPH + {0xBE5E, 0x7DB9}, //10215 #CJK UNIFIED IDEOGRAPH + {0xBE5F, 0x7DBA}, //10216 #CJK UNIFIED IDEOGRAPH + {0xBE60, 0x7DBB}, //10217 #CJK UNIFIED IDEOGRAPH + {0xBE61, 0x7DBC}, //10218 #CJK UNIFIED IDEOGRAPH + {0xBE62, 0x7DBD}, //10219 #CJK UNIFIED IDEOGRAPH + {0xBE63, 0x7DBE}, //10220 #CJK UNIFIED IDEOGRAPH + {0xBE64, 0x7DBF}, //10221 #CJK UNIFIED IDEOGRAPH + {0xBE65, 0x7DC0}, //10222 #CJK UNIFIED IDEOGRAPH + {0xBE66, 0x7DC1}, //10223 #CJK UNIFIED IDEOGRAPH + {0xBE67, 0x7DC2}, //10224 #CJK UNIFIED IDEOGRAPH + {0xBE68, 0x7DC3}, //10225 #CJK UNIFIED IDEOGRAPH + {0xBE69, 0x7DC4}, //10226 #CJK UNIFIED IDEOGRAPH + {0xBE6A, 0x7DC5}, //10227 #CJK UNIFIED IDEOGRAPH + {0xBE6B, 0x7DC6}, //10228 #CJK UNIFIED IDEOGRAPH + {0xBE6C, 0x7DC7}, //10229 #CJK UNIFIED IDEOGRAPH + {0xBE6D, 0x7DC8}, //10230 #CJK UNIFIED IDEOGRAPH + {0xBE6E, 0x7DC9}, //10231 #CJK UNIFIED IDEOGRAPH + {0xBE6F, 0x7DCA}, //10232 #CJK UNIFIED IDEOGRAPH + {0xBE70, 0x7DCB}, //10233 #CJK UNIFIED IDEOGRAPH + {0xBE71, 0x7DCC}, //10234 #CJK UNIFIED IDEOGRAPH + {0xBE72, 0x7DCD}, //10235 #CJK UNIFIED IDEOGRAPH + {0xBE73, 0x7DCE}, //10236 #CJK UNIFIED IDEOGRAPH + {0xBE74, 0x7DCF}, //10237 #CJK UNIFIED IDEOGRAPH + {0xBE75, 0x7DD0}, //10238 #CJK UNIFIED IDEOGRAPH + {0xBE76, 0x7DD1}, //10239 #CJK UNIFIED IDEOGRAPH + {0xBE77, 0x7DD2}, //10240 #CJK UNIFIED IDEOGRAPH + {0xBE78, 0x7DD3}, //10241 #CJK UNIFIED IDEOGRAPH + {0xBE79, 0x7DD4}, //10242 #CJK UNIFIED IDEOGRAPH + {0xBE7A, 0x7DD5}, //10243 #CJK UNIFIED IDEOGRAPH + {0xBE7B, 0x7DD6}, //10244 #CJK UNIFIED IDEOGRAPH + {0xBE7C, 0x7DD7}, //10245 #CJK UNIFIED IDEOGRAPH + {0xBE7D, 0x7DD8}, //10246 #CJK UNIFIED IDEOGRAPH + {0xBE7E, 0x7DD9}, //10247 #CJK UNIFIED IDEOGRAPH + {0xBE80, 0x7DDA}, //10248 #CJK UNIFIED IDEOGRAPH + {0xBE81, 0x7DDB}, //10249 #CJK UNIFIED IDEOGRAPH + {0xBE82, 0x7DDC}, //10250 #CJK UNIFIED IDEOGRAPH + {0xBE83, 0x7DDD}, //10251 #CJK UNIFIED IDEOGRAPH + {0xBE84, 0x7DDE}, //10252 #CJK UNIFIED IDEOGRAPH + {0xBE85, 0x7DDF}, //10253 #CJK UNIFIED IDEOGRAPH + {0xBE86, 0x7DE0}, //10254 #CJK UNIFIED IDEOGRAPH + {0xBE87, 0x7DE1}, //10255 #CJK UNIFIED IDEOGRAPH + {0xBE88, 0x7DE2}, //10256 #CJK UNIFIED IDEOGRAPH + {0xBE89, 0x7DE3}, //10257 #CJK UNIFIED IDEOGRAPH + {0xBE8A, 0x7DE4}, //10258 #CJK UNIFIED IDEOGRAPH + {0xBE8B, 0x7DE5}, //10259 #CJK UNIFIED IDEOGRAPH + {0xBE8C, 0x7DE6}, //10260 #CJK UNIFIED IDEOGRAPH + {0xBE8D, 0x7DE7}, //10261 #CJK UNIFIED IDEOGRAPH + {0xBE8E, 0x7DE8}, //10262 #CJK UNIFIED IDEOGRAPH + {0xBE8F, 0x7DE9}, //10263 #CJK UNIFIED IDEOGRAPH + {0xBE90, 0x7DEA}, //10264 #CJK UNIFIED IDEOGRAPH + {0xBE91, 0x7DEB}, //10265 #CJK UNIFIED IDEOGRAPH + {0xBE92, 0x7DEC}, //10266 #CJK UNIFIED IDEOGRAPH + {0xBE93, 0x7DED}, //10267 #CJK UNIFIED IDEOGRAPH + {0xBE94, 0x7DEE}, //10268 #CJK UNIFIED IDEOGRAPH + {0xBE95, 0x7DEF}, //10269 #CJK UNIFIED IDEOGRAPH + {0xBE96, 0x7DF0}, //10270 #CJK UNIFIED IDEOGRAPH + {0xBE97, 0x7DF1}, //10271 #CJK UNIFIED IDEOGRAPH + {0xBE98, 0x7DF2}, //10272 #CJK UNIFIED IDEOGRAPH + {0xBE99, 0x7DF3}, //10273 #CJK UNIFIED IDEOGRAPH + {0xBE9A, 0x7DF4}, //10274 #CJK UNIFIED IDEOGRAPH + {0xBE9B, 0x7DF5}, //10275 #CJK UNIFIED IDEOGRAPH + {0xBE9C, 0x7DF6}, //10276 #CJK UNIFIED IDEOGRAPH + {0xBE9D, 0x7DF7}, //10277 #CJK UNIFIED IDEOGRAPH + {0xBE9E, 0x7DF8}, //10278 #CJK UNIFIED IDEOGRAPH + {0xBE9F, 0x7DF9}, //10279 #CJK UNIFIED IDEOGRAPH + {0xBEA0, 0x7DFA}, //10280 #CJK UNIFIED IDEOGRAPH + {0xBEA1, 0x5C3D}, //10281 #CJK UNIFIED IDEOGRAPH + {0xBEA2, 0x52B2}, //10282 #CJK UNIFIED IDEOGRAPH + {0xBEA3, 0x8346}, //10283 #CJK UNIFIED IDEOGRAPH + {0xBEA4, 0x5162}, //10284 #CJK UNIFIED IDEOGRAPH + {0xBEA5, 0x830E}, //10285 #CJK UNIFIED IDEOGRAPH + {0xBEA6, 0x775B}, //10286 #CJK UNIFIED IDEOGRAPH + {0xBEA7, 0x6676}, //10287 #CJK UNIFIED IDEOGRAPH + {0xBEA8, 0x9CB8}, //10288 #CJK UNIFIED IDEOGRAPH + {0xBEA9, 0x4EAC}, //10289 #CJK UNIFIED IDEOGRAPH + {0xBEAA, 0x60CA}, //10290 #CJK UNIFIED IDEOGRAPH + {0xBEAB, 0x7CBE}, //10291 #CJK UNIFIED IDEOGRAPH + {0xBEAC, 0x7CB3}, //10292 #CJK UNIFIED IDEOGRAPH + {0xBEAD, 0x7ECF}, //10293 #CJK UNIFIED IDEOGRAPH + {0xBEAE, 0x4E95}, //10294 #CJK UNIFIED IDEOGRAPH + {0xBEAF, 0x8B66}, //10295 #CJK UNIFIED IDEOGRAPH + {0xBEB0, 0x666F}, //10296 #CJK UNIFIED IDEOGRAPH + {0xBEB1, 0x9888}, //10297 #CJK UNIFIED IDEOGRAPH + {0xBEB2, 0x9759}, //10298 #CJK UNIFIED IDEOGRAPH + {0xBEB3, 0x5883}, //10299 #CJK UNIFIED IDEOGRAPH + {0xBEB4, 0x656C}, //10300 #CJK UNIFIED IDEOGRAPH + {0xBEB5, 0x955C}, //10301 #CJK UNIFIED IDEOGRAPH + {0xBEB6, 0x5F84}, //10302 #CJK UNIFIED IDEOGRAPH + {0xBEB7, 0x75C9}, //10303 #CJK UNIFIED IDEOGRAPH + {0xBEB8, 0x9756}, //10304 #CJK UNIFIED IDEOGRAPH + {0xBEB9, 0x7ADF}, //10305 #CJK UNIFIED IDEOGRAPH + {0xBEBA, 0x7ADE}, //10306 #CJK UNIFIED IDEOGRAPH + {0xBEBB, 0x51C0}, //10307 #CJK UNIFIED IDEOGRAPH + {0xBEBC, 0x70AF}, //10308 #CJK UNIFIED IDEOGRAPH + {0xBEBD, 0x7A98}, //10309 #CJK UNIFIED IDEOGRAPH + {0xBEBE, 0x63EA}, //10310 #CJK UNIFIED IDEOGRAPH + {0xBEBF, 0x7A76}, //10311 #CJK UNIFIED IDEOGRAPH + {0xBEC0, 0x7EA0}, //10312 #CJK UNIFIED IDEOGRAPH + {0xBEC1, 0x7396}, //10313 #CJK UNIFIED IDEOGRAPH + {0xBEC2, 0x97ED}, //10314 #CJK UNIFIED IDEOGRAPH + {0xBEC3, 0x4E45}, //10315 #CJK UNIFIED IDEOGRAPH + {0xBEC4, 0x7078}, //10316 #CJK UNIFIED IDEOGRAPH + {0xBEC5, 0x4E5D}, //10317 #CJK UNIFIED IDEOGRAPH + {0xBEC6, 0x9152}, //10318 #CJK UNIFIED IDEOGRAPH + {0xBEC7, 0x53A9}, //10319 #CJK UNIFIED IDEOGRAPH + {0xBEC8, 0x6551}, //10320 #CJK UNIFIED IDEOGRAPH + {0xBEC9, 0x65E7}, //10321 #CJK UNIFIED IDEOGRAPH + {0xBECA, 0x81FC}, //10322 #CJK UNIFIED IDEOGRAPH + {0xBECB, 0x8205}, //10323 #CJK UNIFIED IDEOGRAPH + {0xBECC, 0x548E}, //10324 #CJK UNIFIED IDEOGRAPH + {0xBECD, 0x5C31}, //10325 #CJK UNIFIED IDEOGRAPH + {0xBECE, 0x759A}, //10326 #CJK UNIFIED IDEOGRAPH + {0xBECF, 0x97A0}, //10327 #CJK UNIFIED IDEOGRAPH + {0xBED0, 0x62D8}, //10328 #CJK UNIFIED IDEOGRAPH + {0xBED1, 0x72D9}, //10329 #CJK UNIFIED IDEOGRAPH + {0xBED2, 0x75BD}, //10330 #CJK UNIFIED IDEOGRAPH + {0xBED3, 0x5C45}, //10331 #CJK UNIFIED IDEOGRAPH + {0xBED4, 0x9A79}, //10332 #CJK UNIFIED IDEOGRAPH + {0xBED5, 0x83CA}, //10333 #CJK UNIFIED IDEOGRAPH + {0xBED6, 0x5C40}, //10334 #CJK UNIFIED IDEOGRAPH + {0xBED7, 0x5480}, //10335 #CJK UNIFIED IDEOGRAPH + {0xBED8, 0x77E9}, //10336 #CJK UNIFIED IDEOGRAPH + {0xBED9, 0x4E3E}, //10337 #CJK UNIFIED IDEOGRAPH + {0xBEDA, 0x6CAE}, //10338 #CJK UNIFIED IDEOGRAPH + {0xBEDB, 0x805A}, //10339 #CJK UNIFIED IDEOGRAPH + {0xBEDC, 0x62D2}, //10340 #CJK UNIFIED IDEOGRAPH + {0xBEDD, 0x636E}, //10341 #CJK UNIFIED IDEOGRAPH + {0xBEDE, 0x5DE8}, //10342 #CJK UNIFIED IDEOGRAPH + {0xBEDF, 0x5177}, //10343 #CJK UNIFIED IDEOGRAPH + {0xBEE0, 0x8DDD}, //10344 #CJK UNIFIED IDEOGRAPH + {0xBEE1, 0x8E1E}, //10345 #CJK UNIFIED IDEOGRAPH + {0xBEE2, 0x952F}, //10346 #CJK UNIFIED IDEOGRAPH + {0xBEE3, 0x4FF1}, //10347 #CJK UNIFIED IDEOGRAPH + {0xBEE4, 0x53E5}, //10348 #CJK UNIFIED IDEOGRAPH + {0xBEE5, 0x60E7}, //10349 #CJK UNIFIED IDEOGRAPH + {0xBEE6, 0x70AC}, //10350 #CJK UNIFIED IDEOGRAPH + {0xBEE7, 0x5267}, //10351 #CJK UNIFIED IDEOGRAPH + {0xBEE8, 0x6350}, //10352 #CJK UNIFIED IDEOGRAPH + {0xBEE9, 0x9E43}, //10353 #CJK UNIFIED IDEOGRAPH + {0xBEEA, 0x5A1F}, //10354 #CJK UNIFIED IDEOGRAPH + {0xBEEB, 0x5026}, //10355 #CJK UNIFIED IDEOGRAPH + {0xBEEC, 0x7737}, //10356 #CJK UNIFIED IDEOGRAPH + {0xBEED, 0x5377}, //10357 #CJK UNIFIED IDEOGRAPH + {0xBEEE, 0x7EE2}, //10358 #CJK UNIFIED IDEOGRAPH + {0xBEEF, 0x6485}, //10359 #CJK UNIFIED IDEOGRAPH + {0xBEF0, 0x652B}, //10360 #CJK UNIFIED IDEOGRAPH + {0xBEF1, 0x6289}, //10361 #CJK UNIFIED IDEOGRAPH + {0xBEF2, 0x6398}, //10362 #CJK UNIFIED IDEOGRAPH + {0xBEF3, 0x5014}, //10363 #CJK UNIFIED IDEOGRAPH + {0xBEF4, 0x7235}, //10364 #CJK UNIFIED IDEOGRAPH + {0xBEF5, 0x89C9}, //10365 #CJK UNIFIED IDEOGRAPH + {0xBEF6, 0x51B3}, //10366 #CJK UNIFIED IDEOGRAPH + {0xBEF7, 0x8BC0}, //10367 #CJK UNIFIED IDEOGRAPH + {0xBEF8, 0x7EDD}, //10368 #CJK UNIFIED IDEOGRAPH + {0xBEF9, 0x5747}, //10369 #CJK UNIFIED IDEOGRAPH + {0xBEFA, 0x83CC}, //10370 #CJK UNIFIED IDEOGRAPH + {0xBEFB, 0x94A7}, //10371 #CJK UNIFIED IDEOGRAPH + {0xBEFC, 0x519B}, //10372 #CJK UNIFIED IDEOGRAPH + {0xBEFD, 0x541B}, //10373 #CJK UNIFIED IDEOGRAPH + {0xBEFE, 0x5CFB}, //10374 #CJK UNIFIED IDEOGRAPH + {0xBF40, 0x7DFB}, //10375 #CJK UNIFIED IDEOGRAPH + {0xBF41, 0x7DFC}, //10376 #CJK UNIFIED IDEOGRAPH + {0xBF42, 0x7DFD}, //10377 #CJK UNIFIED IDEOGRAPH + {0xBF43, 0x7DFE}, //10378 #CJK UNIFIED IDEOGRAPH + {0xBF44, 0x7DFF}, //10379 #CJK UNIFIED IDEOGRAPH + {0xBF45, 0x7E00}, //10380 #CJK UNIFIED IDEOGRAPH + {0xBF46, 0x7E01}, //10381 #CJK UNIFIED IDEOGRAPH + {0xBF47, 0x7E02}, //10382 #CJK UNIFIED IDEOGRAPH + {0xBF48, 0x7E03}, //10383 #CJK UNIFIED IDEOGRAPH + {0xBF49, 0x7E04}, //10384 #CJK UNIFIED IDEOGRAPH + {0xBF4A, 0x7E05}, //10385 #CJK UNIFIED IDEOGRAPH + {0xBF4B, 0x7E06}, //10386 #CJK UNIFIED IDEOGRAPH + {0xBF4C, 0x7E07}, //10387 #CJK UNIFIED IDEOGRAPH + {0xBF4D, 0x7E08}, //10388 #CJK UNIFIED IDEOGRAPH + {0xBF4E, 0x7E09}, //10389 #CJK UNIFIED IDEOGRAPH + {0xBF4F, 0x7E0A}, //10390 #CJK UNIFIED IDEOGRAPH + {0xBF50, 0x7E0B}, //10391 #CJK UNIFIED IDEOGRAPH + {0xBF51, 0x7E0C}, //10392 #CJK UNIFIED IDEOGRAPH + {0xBF52, 0x7E0D}, //10393 #CJK UNIFIED IDEOGRAPH + {0xBF53, 0x7E0E}, //10394 #CJK UNIFIED IDEOGRAPH + {0xBF54, 0x7E0F}, //10395 #CJK UNIFIED IDEOGRAPH + {0xBF55, 0x7E10}, //10396 #CJK UNIFIED IDEOGRAPH + {0xBF56, 0x7E11}, //10397 #CJK UNIFIED IDEOGRAPH + {0xBF57, 0x7E12}, //10398 #CJK UNIFIED IDEOGRAPH + {0xBF58, 0x7E13}, //10399 #CJK UNIFIED IDEOGRAPH + {0xBF59, 0x7E14}, //10400 #CJK UNIFIED IDEOGRAPH + {0xBF5A, 0x7E15}, //10401 #CJK UNIFIED IDEOGRAPH + {0xBF5B, 0x7E16}, //10402 #CJK UNIFIED IDEOGRAPH + {0xBF5C, 0x7E17}, //10403 #CJK UNIFIED IDEOGRAPH + {0xBF5D, 0x7E18}, //10404 #CJK UNIFIED IDEOGRAPH + {0xBF5E, 0x7E19}, //10405 #CJK UNIFIED IDEOGRAPH + {0xBF5F, 0x7E1A}, //10406 #CJK UNIFIED IDEOGRAPH + {0xBF60, 0x7E1B}, //10407 #CJK UNIFIED IDEOGRAPH + {0xBF61, 0x7E1C}, //10408 #CJK UNIFIED IDEOGRAPH + {0xBF62, 0x7E1D}, //10409 #CJK UNIFIED IDEOGRAPH + {0xBF63, 0x7E1E}, //10410 #CJK UNIFIED IDEOGRAPH + {0xBF64, 0x7E1F}, //10411 #CJK UNIFIED IDEOGRAPH + {0xBF65, 0x7E20}, //10412 #CJK UNIFIED IDEOGRAPH + {0xBF66, 0x7E21}, //10413 #CJK UNIFIED IDEOGRAPH + {0xBF67, 0x7E22}, //10414 #CJK UNIFIED IDEOGRAPH + {0xBF68, 0x7E23}, //10415 #CJK UNIFIED IDEOGRAPH + {0xBF69, 0x7E24}, //10416 #CJK UNIFIED IDEOGRAPH + {0xBF6A, 0x7E25}, //10417 #CJK UNIFIED IDEOGRAPH + {0xBF6B, 0x7E26}, //10418 #CJK UNIFIED IDEOGRAPH + {0xBF6C, 0x7E27}, //10419 #CJK UNIFIED IDEOGRAPH + {0xBF6D, 0x7E28}, //10420 #CJK UNIFIED IDEOGRAPH + {0xBF6E, 0x7E29}, //10421 #CJK UNIFIED IDEOGRAPH + {0xBF6F, 0x7E2A}, //10422 #CJK UNIFIED IDEOGRAPH + {0xBF70, 0x7E2B}, //10423 #CJK UNIFIED IDEOGRAPH + {0xBF71, 0x7E2C}, //10424 #CJK UNIFIED IDEOGRAPH + {0xBF72, 0x7E2D}, //10425 #CJK UNIFIED IDEOGRAPH + {0xBF73, 0x7E2E}, //10426 #CJK UNIFIED IDEOGRAPH + {0xBF74, 0x7E2F}, //10427 #CJK UNIFIED IDEOGRAPH + {0xBF75, 0x7E30}, //10428 #CJK UNIFIED IDEOGRAPH + {0xBF76, 0x7E31}, //10429 #CJK UNIFIED IDEOGRAPH + {0xBF77, 0x7E32}, //10430 #CJK UNIFIED IDEOGRAPH + {0xBF78, 0x7E33}, //10431 #CJK UNIFIED IDEOGRAPH + {0xBF79, 0x7E34}, //10432 #CJK UNIFIED IDEOGRAPH + {0xBF7A, 0x7E35}, //10433 #CJK UNIFIED IDEOGRAPH + {0xBF7B, 0x7E36}, //10434 #CJK UNIFIED IDEOGRAPH + {0xBF7C, 0x7E37}, //10435 #CJK UNIFIED IDEOGRAPH + {0xBF7D, 0x7E38}, //10436 #CJK UNIFIED IDEOGRAPH + {0xBF7E, 0x7E39}, //10437 #CJK UNIFIED IDEOGRAPH + {0xBF80, 0x7E3A}, //10438 #CJK UNIFIED IDEOGRAPH + {0xBF81, 0x7E3C}, //10439 #CJK UNIFIED IDEOGRAPH + {0xBF82, 0x7E3D}, //10440 #CJK UNIFIED IDEOGRAPH + {0xBF83, 0x7E3E}, //10441 #CJK UNIFIED IDEOGRAPH + {0xBF84, 0x7E3F}, //10442 #CJK UNIFIED IDEOGRAPH + {0xBF85, 0x7E40}, //10443 #CJK UNIFIED IDEOGRAPH + {0xBF86, 0x7E42}, //10444 #CJK UNIFIED IDEOGRAPH + {0xBF87, 0x7E43}, //10445 #CJK UNIFIED IDEOGRAPH + {0xBF88, 0x7E44}, //10446 #CJK UNIFIED IDEOGRAPH + {0xBF89, 0x7E45}, //10447 #CJK UNIFIED IDEOGRAPH + {0xBF8A, 0x7E46}, //10448 #CJK UNIFIED IDEOGRAPH + {0xBF8B, 0x7E48}, //10449 #CJK UNIFIED IDEOGRAPH + {0xBF8C, 0x7E49}, //10450 #CJK UNIFIED IDEOGRAPH + {0xBF8D, 0x7E4A}, //10451 #CJK UNIFIED IDEOGRAPH + {0xBF8E, 0x7E4B}, //10452 #CJK UNIFIED IDEOGRAPH + {0xBF8F, 0x7E4C}, //10453 #CJK UNIFIED IDEOGRAPH + {0xBF90, 0x7E4D}, //10454 #CJK UNIFIED IDEOGRAPH + {0xBF91, 0x7E4E}, //10455 #CJK UNIFIED IDEOGRAPH + {0xBF92, 0x7E4F}, //10456 #CJK UNIFIED IDEOGRAPH + {0xBF93, 0x7E50}, //10457 #CJK UNIFIED IDEOGRAPH + {0xBF94, 0x7E51}, //10458 #CJK UNIFIED IDEOGRAPH + {0xBF95, 0x7E52}, //10459 #CJK UNIFIED IDEOGRAPH + {0xBF96, 0x7E53}, //10460 #CJK UNIFIED IDEOGRAPH + {0xBF97, 0x7E54}, //10461 #CJK UNIFIED IDEOGRAPH + {0xBF98, 0x7E55}, //10462 #CJK UNIFIED IDEOGRAPH + {0xBF99, 0x7E56}, //10463 #CJK UNIFIED IDEOGRAPH + {0xBF9A, 0x7E57}, //10464 #CJK UNIFIED IDEOGRAPH + {0xBF9B, 0x7E58}, //10465 #CJK UNIFIED IDEOGRAPH + {0xBF9C, 0x7E59}, //10466 #CJK UNIFIED IDEOGRAPH + {0xBF9D, 0x7E5A}, //10467 #CJK UNIFIED IDEOGRAPH + {0xBF9E, 0x7E5B}, //10468 #CJK UNIFIED IDEOGRAPH + {0xBF9F, 0x7E5C}, //10469 #CJK UNIFIED IDEOGRAPH + {0xBFA0, 0x7E5D}, //10470 #CJK UNIFIED IDEOGRAPH + {0xBFA1, 0x4FCA}, //10471 #CJK UNIFIED IDEOGRAPH + {0xBFA2, 0x7AE3}, //10472 #CJK UNIFIED IDEOGRAPH + {0xBFA3, 0x6D5A}, //10473 #CJK UNIFIED IDEOGRAPH + {0xBFA4, 0x90E1}, //10474 #CJK UNIFIED IDEOGRAPH + {0xBFA5, 0x9A8F}, //10475 #CJK UNIFIED IDEOGRAPH + {0xBFA6, 0x5580}, //10476 #CJK UNIFIED IDEOGRAPH + {0xBFA7, 0x5496}, //10477 #CJK UNIFIED IDEOGRAPH + {0xBFA8, 0x5361}, //10478 #CJK UNIFIED IDEOGRAPH + {0xBFA9, 0x54AF}, //10479 #CJK UNIFIED IDEOGRAPH + {0xBFAA, 0x5F00}, //10480 #CJK UNIFIED IDEOGRAPH + {0xBFAB, 0x63E9}, //10481 #CJK UNIFIED IDEOGRAPH + {0xBFAC, 0x6977}, //10482 #CJK UNIFIED IDEOGRAPH + {0xBFAD, 0x51EF}, //10483 #CJK UNIFIED IDEOGRAPH + {0xBFAE, 0x6168}, //10484 #CJK UNIFIED IDEOGRAPH + {0xBFAF, 0x520A}, //10485 #CJK UNIFIED IDEOGRAPH + {0xBFB0, 0x582A}, //10486 #CJK UNIFIED IDEOGRAPH + {0xBFB1, 0x52D8}, //10487 #CJK UNIFIED IDEOGRAPH + {0xBFB2, 0x574E}, //10488 #CJK UNIFIED IDEOGRAPH + {0xBFB3, 0x780D}, //10489 #CJK UNIFIED IDEOGRAPH + {0xBFB4, 0x770B}, //10490 #CJK UNIFIED IDEOGRAPH + {0xBFB5, 0x5EB7}, //10491 #CJK UNIFIED IDEOGRAPH + {0xBFB6, 0x6177}, //10492 #CJK UNIFIED IDEOGRAPH + {0xBFB7, 0x7CE0}, //10493 #CJK UNIFIED IDEOGRAPH + {0xBFB8, 0x625B}, //10494 #CJK UNIFIED IDEOGRAPH + {0xBFB9, 0x6297}, //10495 #CJK UNIFIED IDEOGRAPH + {0xBFBA, 0x4EA2}, //10496 #CJK UNIFIED IDEOGRAPH + {0xBFBB, 0x7095}, //10497 #CJK UNIFIED IDEOGRAPH + {0xBFBC, 0x8003}, //10498 #CJK UNIFIED IDEOGRAPH + {0xBFBD, 0x62F7}, //10499 #CJK UNIFIED IDEOGRAPH + {0xBFBE, 0x70E4}, //10500 #CJK UNIFIED IDEOGRAPH + {0xBFBF, 0x9760}, //10501 #CJK UNIFIED IDEOGRAPH + {0xBFC0, 0x5777}, //10502 #CJK UNIFIED IDEOGRAPH + {0xBFC1, 0x82DB}, //10503 #CJK UNIFIED IDEOGRAPH + {0xBFC2, 0x67EF}, //10504 #CJK UNIFIED IDEOGRAPH + {0xBFC3, 0x68F5}, //10505 #CJK UNIFIED IDEOGRAPH + {0xBFC4, 0x78D5}, //10506 #CJK UNIFIED IDEOGRAPH + {0xBFC5, 0x9897}, //10507 #CJK UNIFIED IDEOGRAPH + {0xBFC6, 0x79D1}, //10508 #CJK UNIFIED IDEOGRAPH + {0xBFC7, 0x58F3}, //10509 #CJK UNIFIED IDEOGRAPH + {0xBFC8, 0x54B3}, //10510 #CJK UNIFIED IDEOGRAPH + {0xBFC9, 0x53EF}, //10511 #CJK UNIFIED IDEOGRAPH + {0xBFCA, 0x6E34}, //10512 #CJK UNIFIED IDEOGRAPH + {0xBFCB, 0x514B}, //10513 #CJK UNIFIED IDEOGRAPH + {0xBFCC, 0x523B}, //10514 #CJK UNIFIED IDEOGRAPH + {0xBFCD, 0x5BA2}, //10515 #CJK UNIFIED IDEOGRAPH + {0xBFCE, 0x8BFE}, //10516 #CJK UNIFIED IDEOGRAPH + {0xBFCF, 0x80AF}, //10517 #CJK UNIFIED IDEOGRAPH + {0xBFD0, 0x5543}, //10518 #CJK UNIFIED IDEOGRAPH + {0xBFD1, 0x57A6}, //10519 #CJK UNIFIED IDEOGRAPH + {0xBFD2, 0x6073}, //10520 #CJK UNIFIED IDEOGRAPH + {0xBFD3, 0x5751}, //10521 #CJK UNIFIED IDEOGRAPH + {0xBFD4, 0x542D}, //10522 #CJK UNIFIED IDEOGRAPH + {0xBFD5, 0x7A7A}, //10523 #CJK UNIFIED IDEOGRAPH + {0xBFD6, 0x6050}, //10524 #CJK UNIFIED IDEOGRAPH + {0xBFD7, 0x5B54}, //10525 #CJK UNIFIED IDEOGRAPH + {0xBFD8, 0x63A7}, //10526 #CJK UNIFIED IDEOGRAPH + {0xBFD9, 0x62A0}, //10527 #CJK UNIFIED IDEOGRAPH + {0xBFDA, 0x53E3}, //10528 #CJK UNIFIED IDEOGRAPH + {0xBFDB, 0x6263}, //10529 #CJK UNIFIED IDEOGRAPH + {0xBFDC, 0x5BC7}, //10530 #CJK UNIFIED IDEOGRAPH + {0xBFDD, 0x67AF}, //10531 #CJK UNIFIED IDEOGRAPH + {0xBFDE, 0x54ED}, //10532 #CJK UNIFIED IDEOGRAPH + {0xBFDF, 0x7A9F}, //10533 #CJK UNIFIED IDEOGRAPH + {0xBFE0, 0x82E6}, //10534 #CJK UNIFIED IDEOGRAPH + {0xBFE1, 0x9177}, //10535 #CJK UNIFIED IDEOGRAPH + {0xBFE2, 0x5E93}, //10536 #CJK UNIFIED IDEOGRAPH + {0xBFE3, 0x88E4}, //10537 #CJK UNIFIED IDEOGRAPH + {0xBFE4, 0x5938}, //10538 #CJK UNIFIED IDEOGRAPH + {0xBFE5, 0x57AE}, //10539 #CJK UNIFIED IDEOGRAPH + {0xBFE6, 0x630E}, //10540 #CJK UNIFIED IDEOGRAPH + {0xBFE7, 0x8DE8}, //10541 #CJK UNIFIED IDEOGRAPH + {0xBFE8, 0x80EF}, //10542 #CJK UNIFIED IDEOGRAPH + {0xBFE9, 0x5757}, //10543 #CJK UNIFIED IDEOGRAPH + {0xBFEA, 0x7B77}, //10544 #CJK UNIFIED IDEOGRAPH + {0xBFEB, 0x4FA9}, //10545 #CJK UNIFIED IDEOGRAPH + {0xBFEC, 0x5FEB}, //10546 #CJK UNIFIED IDEOGRAPH + {0xBFED, 0x5BBD}, //10547 #CJK UNIFIED IDEOGRAPH + {0xBFEE, 0x6B3E}, //10548 #CJK UNIFIED IDEOGRAPH + {0xBFEF, 0x5321}, //10549 #CJK UNIFIED IDEOGRAPH + {0xBFF0, 0x7B50}, //10550 #CJK UNIFIED IDEOGRAPH + {0xBFF1, 0x72C2}, //10551 #CJK UNIFIED IDEOGRAPH + {0xBFF2, 0x6846}, //10552 #CJK UNIFIED IDEOGRAPH + {0xBFF3, 0x77FF}, //10553 #CJK UNIFIED IDEOGRAPH + {0xBFF4, 0x7736}, //10554 #CJK UNIFIED IDEOGRAPH + {0xBFF5, 0x65F7}, //10555 #CJK UNIFIED IDEOGRAPH + {0xBFF6, 0x51B5}, //10556 #CJK UNIFIED IDEOGRAPH + {0xBFF7, 0x4E8F}, //10557 #CJK UNIFIED IDEOGRAPH + {0xBFF8, 0x76D4}, //10558 #CJK UNIFIED IDEOGRAPH + {0xBFF9, 0x5CBF}, //10559 #CJK UNIFIED IDEOGRAPH + {0xBFFA, 0x7AA5}, //10560 #CJK UNIFIED IDEOGRAPH + {0xBFFB, 0x8475}, //10561 #CJK UNIFIED IDEOGRAPH + {0xBFFC, 0x594E}, //10562 #CJK UNIFIED IDEOGRAPH + {0xBFFD, 0x9B41}, //10563 #CJK UNIFIED IDEOGRAPH + {0xBFFE, 0x5080}, //10564 #CJK UNIFIED IDEOGRAPH + {0xC040, 0x7E5E}, //10565 #CJK UNIFIED IDEOGRAPH + {0xC041, 0x7E5F}, //10566 #CJK UNIFIED IDEOGRAPH + {0xC042, 0x7E60}, //10567 #CJK UNIFIED IDEOGRAPH + {0xC043, 0x7E61}, //10568 #CJK UNIFIED IDEOGRAPH + {0xC044, 0x7E62}, //10569 #CJK UNIFIED IDEOGRAPH + {0xC045, 0x7E63}, //10570 #CJK UNIFIED IDEOGRAPH + {0xC046, 0x7E64}, //10571 #CJK UNIFIED IDEOGRAPH + {0xC047, 0x7E65}, //10572 #CJK UNIFIED IDEOGRAPH + {0xC048, 0x7E66}, //10573 #CJK UNIFIED IDEOGRAPH + {0xC049, 0x7E67}, //10574 #CJK UNIFIED IDEOGRAPH + {0xC04A, 0x7E68}, //10575 #CJK UNIFIED IDEOGRAPH + {0xC04B, 0x7E69}, //10576 #CJK UNIFIED IDEOGRAPH + {0xC04C, 0x7E6A}, //10577 #CJK UNIFIED IDEOGRAPH + {0xC04D, 0x7E6B}, //10578 #CJK UNIFIED IDEOGRAPH + {0xC04E, 0x7E6C}, //10579 #CJK UNIFIED IDEOGRAPH + {0xC04F, 0x7E6D}, //10580 #CJK UNIFIED IDEOGRAPH + {0xC050, 0x7E6E}, //10581 #CJK UNIFIED IDEOGRAPH + {0xC051, 0x7E6F}, //10582 #CJK UNIFIED IDEOGRAPH + {0xC052, 0x7E70}, //10583 #CJK UNIFIED IDEOGRAPH + {0xC053, 0x7E71}, //10584 #CJK UNIFIED IDEOGRAPH + {0xC054, 0x7E72}, //10585 #CJK UNIFIED IDEOGRAPH + {0xC055, 0x7E73}, //10586 #CJK UNIFIED IDEOGRAPH + {0xC056, 0x7E74}, //10587 #CJK UNIFIED IDEOGRAPH + {0xC057, 0x7E75}, //10588 #CJK UNIFIED IDEOGRAPH + {0xC058, 0x7E76}, //10589 #CJK UNIFIED IDEOGRAPH + {0xC059, 0x7E77}, //10590 #CJK UNIFIED IDEOGRAPH + {0xC05A, 0x7E78}, //10591 #CJK UNIFIED IDEOGRAPH + {0xC05B, 0x7E79}, //10592 #CJK UNIFIED IDEOGRAPH + {0xC05C, 0x7E7A}, //10593 #CJK UNIFIED IDEOGRAPH + {0xC05D, 0x7E7B}, //10594 #CJK UNIFIED IDEOGRAPH + {0xC05E, 0x7E7C}, //10595 #CJK UNIFIED IDEOGRAPH + {0xC05F, 0x7E7D}, //10596 #CJK UNIFIED IDEOGRAPH + {0xC060, 0x7E7E}, //10597 #CJK UNIFIED IDEOGRAPH + {0xC061, 0x7E7F}, //10598 #CJK UNIFIED IDEOGRAPH + {0xC062, 0x7E80}, //10599 #CJK UNIFIED IDEOGRAPH + {0xC063, 0x7E81}, //10600 #CJK UNIFIED IDEOGRAPH + {0xC064, 0x7E83}, //10601 #CJK UNIFIED IDEOGRAPH + {0xC065, 0x7E84}, //10602 #CJK UNIFIED IDEOGRAPH + {0xC066, 0x7E85}, //10603 #CJK UNIFIED IDEOGRAPH + {0xC067, 0x7E86}, //10604 #CJK UNIFIED IDEOGRAPH + {0xC068, 0x7E87}, //10605 #CJK UNIFIED IDEOGRAPH + {0xC069, 0x7E88}, //10606 #CJK UNIFIED IDEOGRAPH + {0xC06A, 0x7E89}, //10607 #CJK UNIFIED IDEOGRAPH + {0xC06B, 0x7E8A}, //10608 #CJK UNIFIED IDEOGRAPH + {0xC06C, 0x7E8B}, //10609 #CJK UNIFIED IDEOGRAPH + {0xC06D, 0x7E8C}, //10610 #CJK UNIFIED IDEOGRAPH + {0xC06E, 0x7E8D}, //10611 #CJK UNIFIED IDEOGRAPH + {0xC06F, 0x7E8E}, //10612 #CJK UNIFIED IDEOGRAPH + {0xC070, 0x7E8F}, //10613 #CJK UNIFIED IDEOGRAPH + {0xC071, 0x7E90}, //10614 #CJK UNIFIED IDEOGRAPH + {0xC072, 0x7E91}, //10615 #CJK UNIFIED IDEOGRAPH + {0xC073, 0x7E92}, //10616 #CJK UNIFIED IDEOGRAPH + {0xC074, 0x7E93}, //10617 #CJK UNIFIED IDEOGRAPH + {0xC075, 0x7E94}, //10618 #CJK UNIFIED IDEOGRAPH + {0xC076, 0x7E95}, //10619 #CJK UNIFIED IDEOGRAPH + {0xC077, 0x7E96}, //10620 #CJK UNIFIED IDEOGRAPH + {0xC078, 0x7E97}, //10621 #CJK UNIFIED IDEOGRAPH + {0xC079, 0x7E98}, //10622 #CJK UNIFIED IDEOGRAPH + {0xC07A, 0x7E99}, //10623 #CJK UNIFIED IDEOGRAPH + {0xC07B, 0x7E9A}, //10624 #CJK UNIFIED IDEOGRAPH + {0xC07C, 0x7E9C}, //10625 #CJK UNIFIED IDEOGRAPH + {0xC07D, 0x7E9D}, //10626 #CJK UNIFIED IDEOGRAPH + {0xC07E, 0x7E9E}, //10627 #CJK UNIFIED IDEOGRAPH + {0xC080, 0x7EAE}, //10628 #CJK UNIFIED IDEOGRAPH + {0xC081, 0x7EB4}, //10629 #CJK UNIFIED IDEOGRAPH + {0xC082, 0x7EBB}, //10630 #CJK UNIFIED IDEOGRAPH + {0xC083, 0x7EBC}, //10631 #CJK UNIFIED IDEOGRAPH + {0xC084, 0x7ED6}, //10632 #CJK UNIFIED IDEOGRAPH + {0xC085, 0x7EE4}, //10633 #CJK UNIFIED IDEOGRAPH + {0xC086, 0x7EEC}, //10634 #CJK UNIFIED IDEOGRAPH + {0xC087, 0x7EF9}, //10635 #CJK UNIFIED IDEOGRAPH + {0xC088, 0x7F0A}, //10636 #CJK UNIFIED IDEOGRAPH + {0xC089, 0x7F10}, //10637 #CJK UNIFIED IDEOGRAPH + {0xC08A, 0x7F1E}, //10638 #CJK UNIFIED IDEOGRAPH + {0xC08B, 0x7F37}, //10639 #CJK UNIFIED IDEOGRAPH + {0xC08C, 0x7F39}, //10640 #CJK UNIFIED IDEOGRAPH + {0xC08D, 0x7F3B}, //10641 #CJK UNIFIED IDEOGRAPH + {0xC08E, 0x7F3C}, //10642 #CJK UNIFIED IDEOGRAPH + {0xC08F, 0x7F3D}, //10643 #CJK UNIFIED IDEOGRAPH + {0xC090, 0x7F3E}, //10644 #CJK UNIFIED IDEOGRAPH + {0xC091, 0x7F3F}, //10645 #CJK UNIFIED IDEOGRAPH + {0xC092, 0x7F40}, //10646 #CJK UNIFIED IDEOGRAPH + {0xC093, 0x7F41}, //10647 #CJK UNIFIED IDEOGRAPH + {0xC094, 0x7F43}, //10648 #CJK UNIFIED IDEOGRAPH + {0xC095, 0x7F46}, //10649 #CJK UNIFIED IDEOGRAPH + {0xC096, 0x7F47}, //10650 #CJK UNIFIED IDEOGRAPH + {0xC097, 0x7F48}, //10651 #CJK UNIFIED IDEOGRAPH + {0xC098, 0x7F49}, //10652 #CJK UNIFIED IDEOGRAPH + {0xC099, 0x7F4A}, //10653 #CJK UNIFIED IDEOGRAPH + {0xC09A, 0x7F4B}, //10654 #CJK UNIFIED IDEOGRAPH + {0xC09B, 0x7F4C}, //10655 #CJK UNIFIED IDEOGRAPH + {0xC09C, 0x7F4D}, //10656 #CJK UNIFIED IDEOGRAPH + {0xC09D, 0x7F4E}, //10657 #CJK UNIFIED IDEOGRAPH + {0xC09E, 0x7F4F}, //10658 #CJK UNIFIED IDEOGRAPH + {0xC09F, 0x7F52}, //10659 #CJK UNIFIED IDEOGRAPH + {0xC0A0, 0x7F53}, //10660 #CJK UNIFIED IDEOGRAPH + {0xC0A1, 0x9988}, //10661 #CJK UNIFIED IDEOGRAPH + {0xC0A2, 0x6127}, //10662 #CJK UNIFIED IDEOGRAPH + {0xC0A3, 0x6E83}, //10663 #CJK UNIFIED IDEOGRAPH + {0xC0A4, 0x5764}, //10664 #CJK UNIFIED IDEOGRAPH + {0xC0A5, 0x6606}, //10665 #CJK UNIFIED IDEOGRAPH + {0xC0A6, 0x6346}, //10666 #CJK UNIFIED IDEOGRAPH + {0xC0A7, 0x56F0}, //10667 #CJK UNIFIED IDEOGRAPH + {0xC0A8, 0x62EC}, //10668 #CJK UNIFIED IDEOGRAPH + {0xC0A9, 0x6269}, //10669 #CJK UNIFIED IDEOGRAPH + {0xC0AA, 0x5ED3}, //10670 #CJK UNIFIED IDEOGRAPH + {0xC0AB, 0x9614}, //10671 #CJK UNIFIED IDEOGRAPH + {0xC0AC, 0x5783}, //10672 #CJK UNIFIED IDEOGRAPH + {0xC0AD, 0x62C9}, //10673 #CJK UNIFIED IDEOGRAPH + {0xC0AE, 0x5587}, //10674 #CJK UNIFIED IDEOGRAPH + {0xC0AF, 0x8721}, //10675 #CJK UNIFIED IDEOGRAPH + {0xC0B0, 0x814A}, //10676 #CJK UNIFIED IDEOGRAPH + {0xC0B1, 0x8FA3}, //10677 #CJK UNIFIED IDEOGRAPH + {0xC0B2, 0x5566}, //10678 #CJK UNIFIED IDEOGRAPH + {0xC0B3, 0x83B1}, //10679 #CJK UNIFIED IDEOGRAPH + {0xC0B4, 0x6765}, //10680 #CJK UNIFIED IDEOGRAPH + {0xC0B5, 0x8D56}, //10681 #CJK UNIFIED IDEOGRAPH + {0xC0B6, 0x84DD}, //10682 #CJK UNIFIED IDEOGRAPH + {0xC0B7, 0x5A6A}, //10683 #CJK UNIFIED IDEOGRAPH + {0xC0B8, 0x680F}, //10684 #CJK UNIFIED IDEOGRAPH + {0xC0B9, 0x62E6}, //10685 #CJK UNIFIED IDEOGRAPH + {0xC0BA, 0x7BEE}, //10686 #CJK UNIFIED IDEOGRAPH + {0xC0BB, 0x9611}, //10687 #CJK UNIFIED IDEOGRAPH + {0xC0BC, 0x5170}, //10688 #CJK UNIFIED IDEOGRAPH + {0xC0BD, 0x6F9C}, //10689 #CJK UNIFIED IDEOGRAPH + {0xC0BE, 0x8C30}, //10690 #CJK UNIFIED IDEOGRAPH + {0xC0BF, 0x63FD}, //10691 #CJK UNIFIED IDEOGRAPH + {0xC0C0, 0x89C8}, //10692 #CJK UNIFIED IDEOGRAPH + {0xC0C1, 0x61D2}, //10693 #CJK UNIFIED IDEOGRAPH + {0xC0C2, 0x7F06}, //10694 #CJK UNIFIED IDEOGRAPH + {0xC0C3, 0x70C2}, //10695 #CJK UNIFIED IDEOGRAPH + {0xC0C4, 0x6EE5}, //10696 #CJK UNIFIED IDEOGRAPH + {0xC0C5, 0x7405}, //10697 #CJK UNIFIED IDEOGRAPH + {0xC0C6, 0x6994}, //10698 #CJK UNIFIED IDEOGRAPH + {0xC0C7, 0x72FC}, //10699 #CJK UNIFIED IDEOGRAPH + {0xC0C8, 0x5ECA}, //10700 #CJK UNIFIED IDEOGRAPH + {0xC0C9, 0x90CE}, //10701 #CJK UNIFIED IDEOGRAPH + {0xC0CA, 0x6717}, //10702 #CJK UNIFIED IDEOGRAPH + {0xC0CB, 0x6D6A}, //10703 #CJK UNIFIED IDEOGRAPH + {0xC0CC, 0x635E}, //10704 #CJK UNIFIED IDEOGRAPH + {0xC0CD, 0x52B3}, //10705 #CJK UNIFIED IDEOGRAPH + {0xC0CE, 0x7262}, //10706 #CJK UNIFIED IDEOGRAPH + {0xC0CF, 0x8001}, //10707 #CJK UNIFIED IDEOGRAPH + {0xC0D0, 0x4F6C}, //10708 #CJK UNIFIED IDEOGRAPH + {0xC0D1, 0x59E5}, //10709 #CJK UNIFIED IDEOGRAPH + {0xC0D2, 0x916A}, //10710 #CJK UNIFIED IDEOGRAPH + {0xC0D3, 0x70D9}, //10711 #CJK UNIFIED IDEOGRAPH + {0xC0D4, 0x6D9D}, //10712 #CJK UNIFIED IDEOGRAPH + {0xC0D5, 0x52D2}, //10713 #CJK UNIFIED IDEOGRAPH + {0xC0D6, 0x4E50}, //10714 #CJK UNIFIED IDEOGRAPH + {0xC0D7, 0x96F7}, //10715 #CJK UNIFIED IDEOGRAPH + {0xC0D8, 0x956D}, //10716 #CJK UNIFIED IDEOGRAPH + {0xC0D9, 0x857E}, //10717 #CJK UNIFIED IDEOGRAPH + {0xC0DA, 0x78CA}, //10718 #CJK UNIFIED IDEOGRAPH + {0xC0DB, 0x7D2F}, //10719 #CJK UNIFIED IDEOGRAPH + {0xC0DC, 0x5121}, //10720 #CJK UNIFIED IDEOGRAPH + {0xC0DD, 0x5792}, //10721 #CJK UNIFIED IDEOGRAPH + {0xC0DE, 0x64C2}, //10722 #CJK UNIFIED IDEOGRAPH + {0xC0DF, 0x808B}, //10723 #CJK UNIFIED IDEOGRAPH + {0xC0E0, 0x7C7B}, //10724 #CJK UNIFIED IDEOGRAPH + {0xC0E1, 0x6CEA}, //10725 #CJK UNIFIED IDEOGRAPH + {0xC0E2, 0x68F1}, //10726 #CJK UNIFIED IDEOGRAPH + {0xC0E3, 0x695E}, //10727 #CJK UNIFIED IDEOGRAPH + {0xC0E4, 0x51B7}, //10728 #CJK UNIFIED IDEOGRAPH + {0xC0E5, 0x5398}, //10729 #CJK UNIFIED IDEOGRAPH + {0xC0E6, 0x68A8}, //10730 #CJK UNIFIED IDEOGRAPH + {0xC0E7, 0x7281}, //10731 #CJK UNIFIED IDEOGRAPH + {0xC0E8, 0x9ECE}, //10732 #CJK UNIFIED IDEOGRAPH + {0xC0E9, 0x7BF1}, //10733 #CJK UNIFIED IDEOGRAPH + {0xC0EA, 0x72F8}, //10734 #CJK UNIFIED IDEOGRAPH + {0xC0EB, 0x79BB}, //10735 #CJK UNIFIED IDEOGRAPH + {0xC0EC, 0x6F13}, //10736 #CJK UNIFIED IDEOGRAPH + {0xC0ED, 0x7406}, //10737 #CJK UNIFIED IDEOGRAPH + {0xC0EE, 0x674E}, //10738 #CJK UNIFIED IDEOGRAPH + {0xC0EF, 0x91CC}, //10739 #CJK UNIFIED IDEOGRAPH + {0xC0F0, 0x9CA4}, //10740 #CJK UNIFIED IDEOGRAPH + {0xC0F1, 0x793C}, //10741 #CJK UNIFIED IDEOGRAPH + {0xC0F2, 0x8389}, //10742 #CJK UNIFIED IDEOGRAPH + {0xC0F3, 0x8354}, //10743 #CJK UNIFIED IDEOGRAPH + {0xC0F4, 0x540F}, //10744 #CJK UNIFIED IDEOGRAPH + {0xC0F5, 0x6817}, //10745 #CJK UNIFIED IDEOGRAPH + {0xC0F6, 0x4E3D}, //10746 #CJK UNIFIED IDEOGRAPH + {0xC0F7, 0x5389}, //10747 #CJK UNIFIED IDEOGRAPH + {0xC0F8, 0x52B1}, //10748 #CJK UNIFIED IDEOGRAPH + {0xC0F9, 0x783E}, //10749 #CJK UNIFIED IDEOGRAPH + {0xC0FA, 0x5386}, //10750 #CJK UNIFIED IDEOGRAPH + {0xC0FB, 0x5229}, //10751 #CJK UNIFIED IDEOGRAPH + {0xC0FC, 0x5088}, //10752 #CJK UNIFIED IDEOGRAPH + {0xC0FD, 0x4F8B}, //10753 #CJK UNIFIED IDEOGRAPH + {0xC0FE, 0x4FD0}, //10754 #CJK UNIFIED IDEOGRAPH + {0xC140, 0x7F56}, //10755 #CJK UNIFIED IDEOGRAPH + {0xC141, 0x7F59}, //10756 #CJK UNIFIED IDEOGRAPH + {0xC142, 0x7F5B}, //10757 #CJK UNIFIED IDEOGRAPH + {0xC143, 0x7F5C}, //10758 #CJK UNIFIED IDEOGRAPH + {0xC144, 0x7F5D}, //10759 #CJK UNIFIED IDEOGRAPH + {0xC145, 0x7F5E}, //10760 #CJK UNIFIED IDEOGRAPH + {0xC146, 0x7F60}, //10761 #CJK UNIFIED IDEOGRAPH + {0xC147, 0x7F63}, //10762 #CJK UNIFIED IDEOGRAPH + {0xC148, 0x7F64}, //10763 #CJK UNIFIED IDEOGRAPH + {0xC149, 0x7F65}, //10764 #CJK UNIFIED IDEOGRAPH + {0xC14A, 0x7F66}, //10765 #CJK UNIFIED IDEOGRAPH + {0xC14B, 0x7F67}, //10766 #CJK UNIFIED IDEOGRAPH + {0xC14C, 0x7F6B}, //10767 #CJK UNIFIED IDEOGRAPH + {0xC14D, 0x7F6C}, //10768 #CJK UNIFIED IDEOGRAPH + {0xC14E, 0x7F6D}, //10769 #CJK UNIFIED IDEOGRAPH + {0xC14F, 0x7F6F}, //10770 #CJK UNIFIED IDEOGRAPH + {0xC150, 0x7F70}, //10771 #CJK UNIFIED IDEOGRAPH + {0xC151, 0x7F73}, //10772 #CJK UNIFIED IDEOGRAPH + {0xC152, 0x7F75}, //10773 #CJK UNIFIED IDEOGRAPH + {0xC153, 0x7F76}, //10774 #CJK UNIFIED IDEOGRAPH + {0xC154, 0x7F77}, //10775 #CJK UNIFIED IDEOGRAPH + {0xC155, 0x7F78}, //10776 #CJK UNIFIED IDEOGRAPH + {0xC156, 0x7F7A}, //10777 #CJK UNIFIED IDEOGRAPH + {0xC157, 0x7F7B}, //10778 #CJK UNIFIED IDEOGRAPH + {0xC158, 0x7F7C}, //10779 #CJK UNIFIED IDEOGRAPH + {0xC159, 0x7F7D}, //10780 #CJK UNIFIED IDEOGRAPH + {0xC15A, 0x7F7F}, //10781 #CJK UNIFIED IDEOGRAPH + {0xC15B, 0x7F80}, //10782 #CJK UNIFIED IDEOGRAPH + {0xC15C, 0x7F82}, //10783 #CJK UNIFIED IDEOGRAPH + {0xC15D, 0x7F83}, //10784 #CJK UNIFIED IDEOGRAPH + {0xC15E, 0x7F84}, //10785 #CJK UNIFIED IDEOGRAPH + {0xC15F, 0x7F85}, //10786 #CJK UNIFIED IDEOGRAPH + {0xC160, 0x7F86}, //10787 #CJK UNIFIED IDEOGRAPH + {0xC161, 0x7F87}, //10788 #CJK UNIFIED IDEOGRAPH + {0xC162, 0x7F88}, //10789 #CJK UNIFIED IDEOGRAPH + {0xC163, 0x7F89}, //10790 #CJK UNIFIED IDEOGRAPH + {0xC164, 0x7F8B}, //10791 #CJK UNIFIED IDEOGRAPH + {0xC165, 0x7F8D}, //10792 #CJK UNIFIED IDEOGRAPH + {0xC166, 0x7F8F}, //10793 #CJK UNIFIED IDEOGRAPH + {0xC167, 0x7F90}, //10794 #CJK UNIFIED IDEOGRAPH + {0xC168, 0x7F91}, //10795 #CJK UNIFIED IDEOGRAPH + {0xC169, 0x7F92}, //10796 #CJK UNIFIED IDEOGRAPH + {0xC16A, 0x7F93}, //10797 #CJK UNIFIED IDEOGRAPH + {0xC16B, 0x7F95}, //10798 #CJK UNIFIED IDEOGRAPH + {0xC16C, 0x7F96}, //10799 #CJK UNIFIED IDEOGRAPH + {0xC16D, 0x7F97}, //10800 #CJK UNIFIED IDEOGRAPH + {0xC16E, 0x7F98}, //10801 #CJK UNIFIED IDEOGRAPH + {0xC16F, 0x7F99}, //10802 #CJK UNIFIED IDEOGRAPH + {0xC170, 0x7F9B}, //10803 #CJK UNIFIED IDEOGRAPH + {0xC171, 0x7F9C}, //10804 #CJK UNIFIED IDEOGRAPH + {0xC172, 0x7FA0}, //10805 #CJK UNIFIED IDEOGRAPH + {0xC173, 0x7FA2}, //10806 #CJK UNIFIED IDEOGRAPH + {0xC174, 0x7FA3}, //10807 #CJK UNIFIED IDEOGRAPH + {0xC175, 0x7FA5}, //10808 #CJK UNIFIED IDEOGRAPH + {0xC176, 0x7FA6}, //10809 #CJK UNIFIED IDEOGRAPH + {0xC177, 0x7FA8}, //10810 #CJK UNIFIED IDEOGRAPH + {0xC178, 0x7FA9}, //10811 #CJK UNIFIED IDEOGRAPH + {0xC179, 0x7FAA}, //10812 #CJK UNIFIED IDEOGRAPH + {0xC17A, 0x7FAB}, //10813 #CJK UNIFIED IDEOGRAPH + {0xC17B, 0x7FAC}, //10814 #CJK UNIFIED IDEOGRAPH + {0xC17C, 0x7FAD}, //10815 #CJK UNIFIED IDEOGRAPH + {0xC17D, 0x7FAE}, //10816 #CJK UNIFIED IDEOGRAPH + {0xC17E, 0x7FB1}, //10817 #CJK UNIFIED IDEOGRAPH + {0xC180, 0x7FB3}, //10818 #CJK UNIFIED IDEOGRAPH + {0xC181, 0x7FB4}, //10819 #CJK UNIFIED IDEOGRAPH + {0xC182, 0x7FB5}, //10820 #CJK UNIFIED IDEOGRAPH + {0xC183, 0x7FB6}, //10821 #CJK UNIFIED IDEOGRAPH + {0xC184, 0x7FB7}, //10822 #CJK UNIFIED IDEOGRAPH + {0xC185, 0x7FBA}, //10823 #CJK UNIFIED IDEOGRAPH + {0xC186, 0x7FBB}, //10824 #CJK UNIFIED IDEOGRAPH + {0xC187, 0x7FBE}, //10825 #CJK UNIFIED IDEOGRAPH + {0xC188, 0x7FC0}, //10826 #CJK UNIFIED IDEOGRAPH + {0xC189, 0x7FC2}, //10827 #CJK UNIFIED IDEOGRAPH + {0xC18A, 0x7FC3}, //10828 #CJK UNIFIED IDEOGRAPH + {0xC18B, 0x7FC4}, //10829 #CJK UNIFIED IDEOGRAPH + {0xC18C, 0x7FC6}, //10830 #CJK UNIFIED IDEOGRAPH + {0xC18D, 0x7FC7}, //10831 #CJK UNIFIED IDEOGRAPH + {0xC18E, 0x7FC8}, //10832 #CJK UNIFIED IDEOGRAPH + {0xC18F, 0x7FC9}, //10833 #CJK UNIFIED IDEOGRAPH + {0xC190, 0x7FCB}, //10834 #CJK UNIFIED IDEOGRAPH + {0xC191, 0x7FCD}, //10835 #CJK UNIFIED IDEOGRAPH + {0xC192, 0x7FCF}, //10836 #CJK UNIFIED IDEOGRAPH + {0xC193, 0x7FD0}, //10837 #CJK UNIFIED IDEOGRAPH + {0xC194, 0x7FD1}, //10838 #CJK UNIFIED IDEOGRAPH + {0xC195, 0x7FD2}, //10839 #CJK UNIFIED IDEOGRAPH + {0xC196, 0x7FD3}, //10840 #CJK UNIFIED IDEOGRAPH + {0xC197, 0x7FD6}, //10841 #CJK UNIFIED IDEOGRAPH + {0xC198, 0x7FD7}, //10842 #CJK UNIFIED IDEOGRAPH + {0xC199, 0x7FD9}, //10843 #CJK UNIFIED IDEOGRAPH + {0xC19A, 0x7FDA}, //10844 #CJK UNIFIED IDEOGRAPH + {0xC19B, 0x7FDB}, //10845 #CJK UNIFIED IDEOGRAPH + {0xC19C, 0x7FDC}, //10846 #CJK UNIFIED IDEOGRAPH + {0xC19D, 0x7FDD}, //10847 #CJK UNIFIED IDEOGRAPH + {0xC19E, 0x7FDE}, //10848 #CJK UNIFIED IDEOGRAPH + {0xC19F, 0x7FE2}, //10849 #CJK UNIFIED IDEOGRAPH + {0xC1A0, 0x7FE3}, //10850 #CJK UNIFIED IDEOGRAPH + {0xC1A1, 0x75E2}, //10851 #CJK UNIFIED IDEOGRAPH + {0xC1A2, 0x7ACB}, //10852 #CJK UNIFIED IDEOGRAPH + {0xC1A3, 0x7C92}, //10853 #CJK UNIFIED IDEOGRAPH + {0xC1A4, 0x6CA5}, //10854 #CJK UNIFIED IDEOGRAPH + {0xC1A5, 0x96B6}, //10855 #CJK UNIFIED IDEOGRAPH + {0xC1A6, 0x529B}, //10856 #CJK UNIFIED IDEOGRAPH + {0xC1A7, 0x7483}, //10857 #CJK UNIFIED IDEOGRAPH + {0xC1A8, 0x54E9}, //10858 #CJK UNIFIED IDEOGRAPH + {0xC1A9, 0x4FE9}, //10859 #CJK UNIFIED IDEOGRAPH + {0xC1AA, 0x8054}, //10860 #CJK UNIFIED IDEOGRAPH + {0xC1AB, 0x83B2}, //10861 #CJK UNIFIED IDEOGRAPH + {0xC1AC, 0x8FDE}, //10862 #CJK UNIFIED IDEOGRAPH + {0xC1AD, 0x9570}, //10863 #CJK UNIFIED IDEOGRAPH + {0xC1AE, 0x5EC9}, //10864 #CJK UNIFIED IDEOGRAPH + {0xC1AF, 0x601C}, //10865 #CJK UNIFIED IDEOGRAPH + {0xC1B0, 0x6D9F}, //10866 #CJK UNIFIED IDEOGRAPH + {0xC1B1, 0x5E18}, //10867 #CJK UNIFIED IDEOGRAPH + {0xC1B2, 0x655B}, //10868 #CJK UNIFIED IDEOGRAPH + {0xC1B3, 0x8138}, //10869 #CJK UNIFIED IDEOGRAPH + {0xC1B4, 0x94FE}, //10870 #CJK UNIFIED IDEOGRAPH + {0xC1B5, 0x604B}, //10871 #CJK UNIFIED IDEOGRAPH + {0xC1B6, 0x70BC}, //10872 #CJK UNIFIED IDEOGRAPH + {0xC1B7, 0x7EC3}, //10873 #CJK UNIFIED IDEOGRAPH + {0xC1B8, 0x7CAE}, //10874 #CJK UNIFIED IDEOGRAPH + {0xC1B9, 0x51C9}, //10875 #CJK UNIFIED IDEOGRAPH + {0xC1BA, 0x6881}, //10876 #CJK UNIFIED IDEOGRAPH + {0xC1BB, 0x7CB1}, //10877 #CJK UNIFIED IDEOGRAPH + {0xC1BC, 0x826F}, //10878 #CJK UNIFIED IDEOGRAPH + {0xC1BD, 0x4E24}, //10879 #CJK UNIFIED IDEOGRAPH + {0xC1BE, 0x8F86}, //10880 #CJK UNIFIED IDEOGRAPH + {0xC1BF, 0x91CF}, //10881 #CJK UNIFIED IDEOGRAPH + {0xC1C0, 0x667E}, //10882 #CJK UNIFIED IDEOGRAPH + {0xC1C1, 0x4EAE}, //10883 #CJK UNIFIED IDEOGRAPH + {0xC1C2, 0x8C05}, //10884 #CJK UNIFIED IDEOGRAPH + {0xC1C3, 0x64A9}, //10885 #CJK UNIFIED IDEOGRAPH + {0xC1C4, 0x804A}, //10886 #CJK UNIFIED IDEOGRAPH + {0xC1C5, 0x50DA}, //10887 #CJK UNIFIED IDEOGRAPH + {0xC1C6, 0x7597}, //10888 #CJK UNIFIED IDEOGRAPH + {0xC1C7, 0x71CE}, //10889 #CJK UNIFIED IDEOGRAPH + {0xC1C8, 0x5BE5}, //10890 #CJK UNIFIED IDEOGRAPH + {0xC1C9, 0x8FBD}, //10891 #CJK UNIFIED IDEOGRAPH + {0xC1CA, 0x6F66}, //10892 #CJK UNIFIED IDEOGRAPH + {0xC1CB, 0x4E86}, //10893 #CJK UNIFIED IDEOGRAPH + {0xC1CC, 0x6482}, //10894 #CJK UNIFIED IDEOGRAPH + {0xC1CD, 0x9563}, //10895 #CJK UNIFIED IDEOGRAPH + {0xC1CE, 0x5ED6}, //10896 #CJK UNIFIED IDEOGRAPH + {0xC1CF, 0x6599}, //10897 #CJK UNIFIED IDEOGRAPH + {0xC1D0, 0x5217}, //10898 #CJK UNIFIED IDEOGRAPH + {0xC1D1, 0x88C2}, //10899 #CJK UNIFIED IDEOGRAPH + {0xC1D2, 0x70C8}, //10900 #CJK UNIFIED IDEOGRAPH + {0xC1D3, 0x52A3}, //10901 #CJK UNIFIED IDEOGRAPH + {0xC1D4, 0x730E}, //10902 #CJK UNIFIED IDEOGRAPH + {0xC1D5, 0x7433}, //10903 #CJK UNIFIED IDEOGRAPH + {0xC1D6, 0x6797}, //10904 #CJK UNIFIED IDEOGRAPH + {0xC1D7, 0x78F7}, //10905 #CJK UNIFIED IDEOGRAPH + {0xC1D8, 0x9716}, //10906 #CJK UNIFIED IDEOGRAPH + {0xC1D9, 0x4E34}, //10907 #CJK UNIFIED IDEOGRAPH + {0xC1DA, 0x90BB}, //10908 #CJK UNIFIED IDEOGRAPH + {0xC1DB, 0x9CDE}, //10909 #CJK UNIFIED IDEOGRAPH + {0xC1DC, 0x6DCB}, //10910 #CJK UNIFIED IDEOGRAPH + {0xC1DD, 0x51DB}, //10911 #CJK UNIFIED IDEOGRAPH + {0xC1DE, 0x8D41}, //10912 #CJK UNIFIED IDEOGRAPH + {0xC1DF, 0x541D}, //10913 #CJK UNIFIED IDEOGRAPH + {0xC1E0, 0x62CE}, //10914 #CJK UNIFIED IDEOGRAPH + {0xC1E1, 0x73B2}, //10915 #CJK UNIFIED IDEOGRAPH + {0xC1E2, 0x83F1}, //10916 #CJK UNIFIED IDEOGRAPH + {0xC1E3, 0x96F6}, //10917 #CJK UNIFIED IDEOGRAPH + {0xC1E4, 0x9F84}, //10918 #CJK UNIFIED IDEOGRAPH + {0xC1E5, 0x94C3}, //10919 #CJK UNIFIED IDEOGRAPH + {0xC1E6, 0x4F36}, //10920 #CJK UNIFIED IDEOGRAPH + {0xC1E7, 0x7F9A}, //10921 #CJK UNIFIED IDEOGRAPH + {0xC1E8, 0x51CC}, //10922 #CJK UNIFIED IDEOGRAPH + {0xC1E9, 0x7075}, //10923 #CJK UNIFIED IDEOGRAPH + {0xC1EA, 0x9675}, //10924 #CJK UNIFIED IDEOGRAPH + {0xC1EB, 0x5CAD}, //10925 #CJK UNIFIED IDEOGRAPH + {0xC1EC, 0x9886}, //10926 #CJK UNIFIED IDEOGRAPH + {0xC1ED, 0x53E6}, //10927 #CJK UNIFIED IDEOGRAPH + {0xC1EE, 0x4EE4}, //10928 #CJK UNIFIED IDEOGRAPH + {0xC1EF, 0x6E9C}, //10929 #CJK UNIFIED IDEOGRAPH + {0xC1F0, 0x7409}, //10930 #CJK UNIFIED IDEOGRAPH + {0xC1F1, 0x69B4}, //10931 #CJK UNIFIED IDEOGRAPH + {0xC1F2, 0x786B}, //10932 #CJK UNIFIED IDEOGRAPH + {0xC1F3, 0x998F}, //10933 #CJK UNIFIED IDEOGRAPH + {0xC1F4, 0x7559}, //10934 #CJK UNIFIED IDEOGRAPH + {0xC1F5, 0x5218}, //10935 #CJK UNIFIED IDEOGRAPH + {0xC1F6, 0x7624}, //10936 #CJK UNIFIED IDEOGRAPH + {0xC1F7, 0x6D41}, //10937 #CJK UNIFIED IDEOGRAPH + {0xC1F8, 0x67F3}, //10938 #CJK UNIFIED IDEOGRAPH + {0xC1F9, 0x516D}, //10939 #CJK UNIFIED IDEOGRAPH + {0xC1FA, 0x9F99}, //10940 #CJK UNIFIED IDEOGRAPH + {0xC1FB, 0x804B}, //10941 #CJK UNIFIED IDEOGRAPH + {0xC1FC, 0x5499}, //10942 #CJK UNIFIED IDEOGRAPH + {0xC1FD, 0x7B3C}, //10943 #CJK UNIFIED IDEOGRAPH + {0xC1FE, 0x7ABF}, //10944 #CJK UNIFIED IDEOGRAPH + {0xC240, 0x7FE4}, //10945 #CJK UNIFIED IDEOGRAPH + {0xC241, 0x7FE7}, //10946 #CJK UNIFIED IDEOGRAPH + {0xC242, 0x7FE8}, //10947 #CJK UNIFIED IDEOGRAPH + {0xC243, 0x7FEA}, //10948 #CJK UNIFIED IDEOGRAPH + {0xC244, 0x7FEB}, //10949 #CJK UNIFIED IDEOGRAPH + {0xC245, 0x7FEC}, //10950 #CJK UNIFIED IDEOGRAPH + {0xC246, 0x7FED}, //10951 #CJK UNIFIED IDEOGRAPH + {0xC247, 0x7FEF}, //10952 #CJK UNIFIED IDEOGRAPH + {0xC248, 0x7FF2}, //10953 #CJK UNIFIED IDEOGRAPH + {0xC249, 0x7FF4}, //10954 #CJK UNIFIED IDEOGRAPH + {0xC24A, 0x7FF5}, //10955 #CJK UNIFIED IDEOGRAPH + {0xC24B, 0x7FF6}, //10956 #CJK UNIFIED IDEOGRAPH + {0xC24C, 0x7FF7}, //10957 #CJK UNIFIED IDEOGRAPH + {0xC24D, 0x7FF8}, //10958 #CJK UNIFIED IDEOGRAPH + {0xC24E, 0x7FF9}, //10959 #CJK UNIFIED IDEOGRAPH + {0xC24F, 0x7FFA}, //10960 #CJK UNIFIED IDEOGRAPH + {0xC250, 0x7FFD}, //10961 #CJK UNIFIED IDEOGRAPH + {0xC251, 0x7FFE}, //10962 #CJK UNIFIED IDEOGRAPH + {0xC252, 0x7FFF}, //10963 #CJK UNIFIED IDEOGRAPH + {0xC253, 0x8002}, //10964 #CJK UNIFIED IDEOGRAPH + {0xC254, 0x8007}, //10965 #CJK UNIFIED IDEOGRAPH + {0xC255, 0x8008}, //10966 #CJK UNIFIED IDEOGRAPH + {0xC256, 0x8009}, //10967 #CJK UNIFIED IDEOGRAPH + {0xC257, 0x800A}, //10968 #CJK UNIFIED IDEOGRAPH + {0xC258, 0x800E}, //10969 #CJK UNIFIED IDEOGRAPH + {0xC259, 0x800F}, //10970 #CJK UNIFIED IDEOGRAPH + {0xC25A, 0x8011}, //10971 #CJK UNIFIED IDEOGRAPH + {0xC25B, 0x8013}, //10972 #CJK UNIFIED IDEOGRAPH + {0xC25C, 0x801A}, //10973 #CJK UNIFIED IDEOGRAPH + {0xC25D, 0x801B}, //10974 #CJK UNIFIED IDEOGRAPH + {0xC25E, 0x801D}, //10975 #CJK UNIFIED IDEOGRAPH + {0xC25F, 0x801E}, //10976 #CJK UNIFIED IDEOGRAPH + {0xC260, 0x801F}, //10977 #CJK UNIFIED IDEOGRAPH + {0xC261, 0x8021}, //10978 #CJK UNIFIED IDEOGRAPH + {0xC262, 0x8023}, //10979 #CJK UNIFIED IDEOGRAPH + {0xC263, 0x8024}, //10980 #CJK UNIFIED IDEOGRAPH + {0xC264, 0x802B}, //10981 #CJK UNIFIED IDEOGRAPH + {0xC265, 0x802C}, //10982 #CJK UNIFIED IDEOGRAPH + {0xC266, 0x802D}, //10983 #CJK UNIFIED IDEOGRAPH + {0xC267, 0x802E}, //10984 #CJK UNIFIED IDEOGRAPH + {0xC268, 0x802F}, //10985 #CJK UNIFIED IDEOGRAPH + {0xC269, 0x8030}, //10986 #CJK UNIFIED IDEOGRAPH + {0xC26A, 0x8032}, //10987 #CJK UNIFIED IDEOGRAPH + {0xC26B, 0x8034}, //10988 #CJK UNIFIED IDEOGRAPH + {0xC26C, 0x8039}, //10989 #CJK UNIFIED IDEOGRAPH + {0xC26D, 0x803A}, //10990 #CJK UNIFIED IDEOGRAPH + {0xC26E, 0x803C}, //10991 #CJK UNIFIED IDEOGRAPH + {0xC26F, 0x803E}, //10992 #CJK UNIFIED IDEOGRAPH + {0xC270, 0x8040}, //10993 #CJK UNIFIED IDEOGRAPH + {0xC271, 0x8041}, //10994 #CJK UNIFIED IDEOGRAPH + {0xC272, 0x8044}, //10995 #CJK UNIFIED IDEOGRAPH + {0xC273, 0x8045}, //10996 #CJK UNIFIED IDEOGRAPH + {0xC274, 0x8047}, //10997 #CJK UNIFIED IDEOGRAPH + {0xC275, 0x8048}, //10998 #CJK UNIFIED IDEOGRAPH + {0xC276, 0x8049}, //10999 #CJK UNIFIED IDEOGRAPH + {0xC277, 0x804E}, //11000 #CJK UNIFIED IDEOGRAPH + {0xC278, 0x804F}, //11001 #CJK UNIFIED IDEOGRAPH + {0xC279, 0x8050}, //11002 #CJK UNIFIED IDEOGRAPH + {0xC27A, 0x8051}, //11003 #CJK UNIFIED IDEOGRAPH + {0xC27B, 0x8053}, //11004 #CJK UNIFIED IDEOGRAPH + {0xC27C, 0x8055}, //11005 #CJK UNIFIED IDEOGRAPH + {0xC27D, 0x8056}, //11006 #CJK UNIFIED IDEOGRAPH + {0xC27E, 0x8057}, //11007 #CJK UNIFIED IDEOGRAPH + {0xC280, 0x8059}, //11008 #CJK UNIFIED IDEOGRAPH + {0xC281, 0x805B}, //11009 #CJK UNIFIED IDEOGRAPH + {0xC282, 0x805C}, //11010 #CJK UNIFIED IDEOGRAPH + {0xC283, 0x805D}, //11011 #CJK UNIFIED IDEOGRAPH + {0xC284, 0x805E}, //11012 #CJK UNIFIED IDEOGRAPH + {0xC285, 0x805F}, //11013 #CJK UNIFIED IDEOGRAPH + {0xC286, 0x8060}, //11014 #CJK UNIFIED IDEOGRAPH + {0xC287, 0x8061}, //11015 #CJK UNIFIED IDEOGRAPH + {0xC288, 0x8062}, //11016 #CJK UNIFIED IDEOGRAPH + {0xC289, 0x8063}, //11017 #CJK UNIFIED IDEOGRAPH + {0xC28A, 0x8064}, //11018 #CJK UNIFIED IDEOGRAPH + {0xC28B, 0x8065}, //11019 #CJK UNIFIED IDEOGRAPH + {0xC28C, 0x8066}, //11020 #CJK UNIFIED IDEOGRAPH + {0xC28D, 0x8067}, //11021 #CJK UNIFIED IDEOGRAPH + {0xC28E, 0x8068}, //11022 #CJK UNIFIED IDEOGRAPH + {0xC28F, 0x806B}, //11023 #CJK UNIFIED IDEOGRAPH + {0xC290, 0x806C}, //11024 #CJK UNIFIED IDEOGRAPH + {0xC291, 0x806D}, //11025 #CJK UNIFIED IDEOGRAPH + {0xC292, 0x806E}, //11026 #CJK UNIFIED IDEOGRAPH + {0xC293, 0x806F}, //11027 #CJK UNIFIED IDEOGRAPH + {0xC294, 0x8070}, //11028 #CJK UNIFIED IDEOGRAPH + {0xC295, 0x8072}, //11029 #CJK UNIFIED IDEOGRAPH + {0xC296, 0x8073}, //11030 #CJK UNIFIED IDEOGRAPH + {0xC297, 0x8074}, //11031 #CJK UNIFIED IDEOGRAPH + {0xC298, 0x8075}, //11032 #CJK UNIFIED IDEOGRAPH + {0xC299, 0x8076}, //11033 #CJK UNIFIED IDEOGRAPH + {0xC29A, 0x8077}, //11034 #CJK UNIFIED IDEOGRAPH + {0xC29B, 0x8078}, //11035 #CJK UNIFIED IDEOGRAPH + {0xC29C, 0x8079}, //11036 #CJK UNIFIED IDEOGRAPH + {0xC29D, 0x807A}, //11037 #CJK UNIFIED IDEOGRAPH + {0xC29E, 0x807B}, //11038 #CJK UNIFIED IDEOGRAPH + {0xC29F, 0x807C}, //11039 #CJK UNIFIED IDEOGRAPH + {0xC2A0, 0x807D}, //11040 #CJK UNIFIED IDEOGRAPH + {0xC2A1, 0x9686}, //11041 #CJK UNIFIED IDEOGRAPH + {0xC2A2, 0x5784}, //11042 #CJK UNIFIED IDEOGRAPH + {0xC2A3, 0x62E2}, //11043 #CJK UNIFIED IDEOGRAPH + {0xC2A4, 0x9647}, //11044 #CJK UNIFIED IDEOGRAPH + {0xC2A5, 0x697C}, //11045 #CJK UNIFIED IDEOGRAPH + {0xC2A6, 0x5A04}, //11046 #CJK UNIFIED IDEOGRAPH + {0xC2A7, 0x6402}, //11047 #CJK UNIFIED IDEOGRAPH + {0xC2A8, 0x7BD3}, //11048 #CJK UNIFIED IDEOGRAPH + {0xC2A9, 0x6F0F}, //11049 #CJK UNIFIED IDEOGRAPH + {0xC2AA, 0x964B}, //11050 #CJK UNIFIED IDEOGRAPH + {0xC2AB, 0x82A6}, //11051 #CJK UNIFIED IDEOGRAPH + {0xC2AC, 0x5362}, //11052 #CJK UNIFIED IDEOGRAPH + {0xC2AD, 0x9885}, //11053 #CJK UNIFIED IDEOGRAPH + {0xC2AE, 0x5E90}, //11054 #CJK UNIFIED IDEOGRAPH + {0xC2AF, 0x7089}, //11055 #CJK UNIFIED IDEOGRAPH + {0xC2B0, 0x63B3}, //11056 #CJK UNIFIED IDEOGRAPH + {0xC2B1, 0x5364}, //11057 #CJK UNIFIED IDEOGRAPH + {0xC2B2, 0x864F}, //11058 #CJK UNIFIED IDEOGRAPH + {0xC2B3, 0x9C81}, //11059 #CJK UNIFIED IDEOGRAPH + {0xC2B4, 0x9E93}, //11060 #CJK UNIFIED IDEOGRAPH + {0xC2B5, 0x788C}, //11061 #CJK UNIFIED IDEOGRAPH + {0xC2B6, 0x9732}, //11062 #CJK UNIFIED IDEOGRAPH + {0xC2B7, 0x8DEF}, //11063 #CJK UNIFIED IDEOGRAPH + {0xC2B8, 0x8D42}, //11064 #CJK UNIFIED IDEOGRAPH + {0xC2B9, 0x9E7F}, //11065 #CJK UNIFIED IDEOGRAPH + {0xC2BA, 0x6F5E}, //11066 #CJK UNIFIED IDEOGRAPH + {0xC2BB, 0x7984}, //11067 #CJK UNIFIED IDEOGRAPH + {0xC2BC, 0x5F55}, //11068 #CJK UNIFIED IDEOGRAPH + {0xC2BD, 0x9646}, //11069 #CJK UNIFIED IDEOGRAPH + {0xC2BE, 0x622E}, //11070 #CJK UNIFIED IDEOGRAPH + {0xC2BF, 0x9A74}, //11071 #CJK UNIFIED IDEOGRAPH + {0xC2C0, 0x5415}, //11072 #CJK UNIFIED IDEOGRAPH + {0xC2C1, 0x94DD}, //11073 #CJK UNIFIED IDEOGRAPH + {0xC2C2, 0x4FA3}, //11074 #CJK UNIFIED IDEOGRAPH + {0xC2C3, 0x65C5}, //11075 #CJK UNIFIED IDEOGRAPH + {0xC2C4, 0x5C65}, //11076 #CJK UNIFIED IDEOGRAPH + {0xC2C5, 0x5C61}, //11077 #CJK UNIFIED IDEOGRAPH + {0xC2C6, 0x7F15}, //11078 #CJK UNIFIED IDEOGRAPH + {0xC2C7, 0x8651}, //11079 #CJK UNIFIED IDEOGRAPH + {0xC2C8, 0x6C2F}, //11080 #CJK UNIFIED IDEOGRAPH + {0xC2C9, 0x5F8B}, //11081 #CJK UNIFIED IDEOGRAPH + {0xC2CA, 0x7387}, //11082 #CJK UNIFIED IDEOGRAPH + {0xC2CB, 0x6EE4}, //11083 #CJK UNIFIED IDEOGRAPH + {0xC2CC, 0x7EFF}, //11084 #CJK UNIFIED IDEOGRAPH + {0xC2CD, 0x5CE6}, //11085 #CJK UNIFIED IDEOGRAPH + {0xC2CE, 0x631B}, //11086 #CJK UNIFIED IDEOGRAPH + {0xC2CF, 0x5B6A}, //11087 #CJK UNIFIED IDEOGRAPH + {0xC2D0, 0x6EE6}, //11088 #CJK UNIFIED IDEOGRAPH + {0xC2D1, 0x5375}, //11089 #CJK UNIFIED IDEOGRAPH + {0xC2D2, 0x4E71}, //11090 #CJK UNIFIED IDEOGRAPH + {0xC2D3, 0x63A0}, //11091 #CJK UNIFIED IDEOGRAPH + {0xC2D4, 0x7565}, //11092 #CJK UNIFIED IDEOGRAPH + {0xC2D5, 0x62A1}, //11093 #CJK UNIFIED IDEOGRAPH + {0xC2D6, 0x8F6E}, //11094 #CJK UNIFIED IDEOGRAPH + {0xC2D7, 0x4F26}, //11095 #CJK UNIFIED IDEOGRAPH + {0xC2D8, 0x4ED1}, //11096 #CJK UNIFIED IDEOGRAPH + {0xC2D9, 0x6CA6}, //11097 #CJK UNIFIED IDEOGRAPH + {0xC2DA, 0x7EB6}, //11098 #CJK UNIFIED IDEOGRAPH + {0xC2DB, 0x8BBA}, //11099 #CJK UNIFIED IDEOGRAPH + {0xC2DC, 0x841D}, //11100 #CJK UNIFIED IDEOGRAPH + {0xC2DD, 0x87BA}, //11101 #CJK UNIFIED IDEOGRAPH + {0xC2DE, 0x7F57}, //11102 #CJK UNIFIED IDEOGRAPH + {0xC2DF, 0x903B}, //11103 #CJK UNIFIED IDEOGRAPH + {0xC2E0, 0x9523}, //11104 #CJK UNIFIED IDEOGRAPH + {0xC2E1, 0x7BA9}, //11105 #CJK UNIFIED IDEOGRAPH + {0xC2E2, 0x9AA1}, //11106 #CJK UNIFIED IDEOGRAPH + {0xC2E3, 0x88F8}, //11107 #CJK UNIFIED IDEOGRAPH + {0xC2E4, 0x843D}, //11108 #CJK UNIFIED IDEOGRAPH + {0xC2E5, 0x6D1B}, //11109 #CJK UNIFIED IDEOGRAPH + {0xC2E6, 0x9A86}, //11110 #CJK UNIFIED IDEOGRAPH + {0xC2E7, 0x7EDC}, //11111 #CJK UNIFIED IDEOGRAPH + {0xC2E8, 0x5988}, //11112 #CJK UNIFIED IDEOGRAPH + {0xC2E9, 0x9EBB}, //11113 #CJK UNIFIED IDEOGRAPH + {0xC2EA, 0x739B}, //11114 #CJK UNIFIED IDEOGRAPH + {0xC2EB, 0x7801}, //11115 #CJK UNIFIED IDEOGRAPH + {0xC2EC, 0x8682}, //11116 #CJK UNIFIED IDEOGRAPH + {0xC2ED, 0x9A6C}, //11117 #CJK UNIFIED IDEOGRAPH + {0xC2EE, 0x9A82}, //11118 #CJK UNIFIED IDEOGRAPH + {0xC2EF, 0x561B}, //11119 #CJK UNIFIED IDEOGRAPH + {0xC2F0, 0x5417}, //11120 #CJK UNIFIED IDEOGRAPH + {0xC2F1, 0x57CB}, //11121 #CJK UNIFIED IDEOGRAPH + {0xC2F2, 0x4E70}, //11122 #CJK UNIFIED IDEOGRAPH + {0xC2F3, 0x9EA6}, //11123 #CJK UNIFIED IDEOGRAPH + {0xC2F4, 0x5356}, //11124 #CJK UNIFIED IDEOGRAPH + {0xC2F5, 0x8FC8}, //11125 #CJK UNIFIED IDEOGRAPH + {0xC2F6, 0x8109}, //11126 #CJK UNIFIED IDEOGRAPH + {0xC2F7, 0x7792}, //11127 #CJK UNIFIED IDEOGRAPH + {0xC2F8, 0x9992}, //11128 #CJK UNIFIED IDEOGRAPH + {0xC2F9, 0x86EE}, //11129 #CJK UNIFIED IDEOGRAPH + {0xC2FA, 0x6EE1}, //11130 #CJK UNIFIED IDEOGRAPH + {0xC2FB, 0x8513}, //11131 #CJK UNIFIED IDEOGRAPH + {0xC2FC, 0x66FC}, //11132 #CJK UNIFIED IDEOGRAPH + {0xC2FD, 0x6162}, //11133 #CJK UNIFIED IDEOGRAPH + {0xC2FE, 0x6F2B}, //11134 #CJK UNIFIED IDEOGRAPH + {0xC340, 0x807E}, //11135 #CJK UNIFIED IDEOGRAPH + {0xC341, 0x8081}, //11136 #CJK UNIFIED IDEOGRAPH + {0xC342, 0x8082}, //11137 #CJK UNIFIED IDEOGRAPH + {0xC343, 0x8085}, //11138 #CJK UNIFIED IDEOGRAPH + {0xC344, 0x8088}, //11139 #CJK UNIFIED IDEOGRAPH + {0xC345, 0x808A}, //11140 #CJK UNIFIED IDEOGRAPH + {0xC346, 0x808D}, //11141 #CJK UNIFIED IDEOGRAPH + {0xC347, 0x808E}, //11142 #CJK UNIFIED IDEOGRAPH + {0xC348, 0x808F}, //11143 #CJK UNIFIED IDEOGRAPH + {0xC349, 0x8090}, //11144 #CJK UNIFIED IDEOGRAPH + {0xC34A, 0x8091}, //11145 #CJK UNIFIED IDEOGRAPH + {0xC34B, 0x8092}, //11146 #CJK UNIFIED IDEOGRAPH + {0xC34C, 0x8094}, //11147 #CJK UNIFIED IDEOGRAPH + {0xC34D, 0x8095}, //11148 #CJK UNIFIED IDEOGRAPH + {0xC34E, 0x8097}, //11149 #CJK UNIFIED IDEOGRAPH + {0xC34F, 0x8099}, //11150 #CJK UNIFIED IDEOGRAPH + {0xC350, 0x809E}, //11151 #CJK UNIFIED IDEOGRAPH + {0xC351, 0x80A3}, //11152 #CJK UNIFIED IDEOGRAPH + {0xC352, 0x80A6}, //11153 #CJK UNIFIED IDEOGRAPH + {0xC353, 0x80A7}, //11154 #CJK UNIFIED IDEOGRAPH + {0xC354, 0x80A8}, //11155 #CJK UNIFIED IDEOGRAPH + {0xC355, 0x80AC}, //11156 #CJK UNIFIED IDEOGRAPH + {0xC356, 0x80B0}, //11157 #CJK UNIFIED IDEOGRAPH + {0xC357, 0x80B3}, //11158 #CJK UNIFIED IDEOGRAPH + {0xC358, 0x80B5}, //11159 #CJK UNIFIED IDEOGRAPH + {0xC359, 0x80B6}, //11160 #CJK UNIFIED IDEOGRAPH + {0xC35A, 0x80B8}, //11161 #CJK UNIFIED IDEOGRAPH + {0xC35B, 0x80B9}, //11162 #CJK UNIFIED IDEOGRAPH + {0xC35C, 0x80BB}, //11163 #CJK UNIFIED IDEOGRAPH + {0xC35D, 0x80C5}, //11164 #CJK UNIFIED IDEOGRAPH + {0xC35E, 0x80C7}, //11165 #CJK UNIFIED IDEOGRAPH + {0xC35F, 0x80C8}, //11166 #CJK UNIFIED IDEOGRAPH + {0xC360, 0x80C9}, //11167 #CJK UNIFIED IDEOGRAPH + {0xC361, 0x80CA}, //11168 #CJK UNIFIED IDEOGRAPH + {0xC362, 0x80CB}, //11169 #CJK UNIFIED IDEOGRAPH + {0xC363, 0x80CF}, //11170 #CJK UNIFIED IDEOGRAPH + {0xC364, 0x80D0}, //11171 #CJK UNIFIED IDEOGRAPH + {0xC365, 0x80D1}, //11172 #CJK UNIFIED IDEOGRAPH + {0xC366, 0x80D2}, //11173 #CJK UNIFIED IDEOGRAPH + {0xC367, 0x80D3}, //11174 #CJK UNIFIED IDEOGRAPH + {0xC368, 0x80D4}, //11175 #CJK UNIFIED IDEOGRAPH + {0xC369, 0x80D5}, //11176 #CJK UNIFIED IDEOGRAPH + {0xC36A, 0x80D8}, //11177 #CJK UNIFIED IDEOGRAPH + {0xC36B, 0x80DF}, //11178 #CJK UNIFIED IDEOGRAPH + {0xC36C, 0x80E0}, //11179 #CJK UNIFIED IDEOGRAPH + {0xC36D, 0x80E2}, //11180 #CJK UNIFIED IDEOGRAPH + {0xC36E, 0x80E3}, //11181 #CJK UNIFIED IDEOGRAPH + {0xC36F, 0x80E6}, //11182 #CJK UNIFIED IDEOGRAPH + {0xC370, 0x80EE}, //11183 #CJK UNIFIED IDEOGRAPH + {0xC371, 0x80F5}, //11184 #CJK UNIFIED IDEOGRAPH + {0xC372, 0x80F7}, //11185 #CJK UNIFIED IDEOGRAPH + {0xC373, 0x80F9}, //11186 #CJK UNIFIED IDEOGRAPH + {0xC374, 0x80FB}, //11187 #CJK UNIFIED IDEOGRAPH + {0xC375, 0x80FE}, //11188 #CJK UNIFIED IDEOGRAPH + {0xC376, 0x80FF}, //11189 #CJK UNIFIED IDEOGRAPH + {0xC377, 0x8100}, //11190 #CJK UNIFIED IDEOGRAPH + {0xC378, 0x8101}, //11191 #CJK UNIFIED IDEOGRAPH + {0xC379, 0x8103}, //11192 #CJK UNIFIED IDEOGRAPH + {0xC37A, 0x8104}, //11193 #CJK UNIFIED IDEOGRAPH + {0xC37B, 0x8105}, //11194 #CJK UNIFIED IDEOGRAPH + {0xC37C, 0x8107}, //11195 #CJK UNIFIED IDEOGRAPH + {0xC37D, 0x8108}, //11196 #CJK UNIFIED IDEOGRAPH + {0xC37E, 0x810B}, //11197 #CJK UNIFIED IDEOGRAPH + {0xC380, 0x810C}, //11198 #CJK UNIFIED IDEOGRAPH + {0xC381, 0x8115}, //11199 #CJK UNIFIED IDEOGRAPH + {0xC382, 0x8117}, //11200 #CJK UNIFIED IDEOGRAPH + {0xC383, 0x8119}, //11201 #CJK UNIFIED IDEOGRAPH + {0xC384, 0x811B}, //11202 #CJK UNIFIED IDEOGRAPH + {0xC385, 0x811C}, //11203 #CJK UNIFIED IDEOGRAPH + {0xC386, 0x811D}, //11204 #CJK UNIFIED IDEOGRAPH + {0xC387, 0x811F}, //11205 #CJK UNIFIED IDEOGRAPH + {0xC388, 0x8120}, //11206 #CJK UNIFIED IDEOGRAPH + {0xC389, 0x8121}, //11207 #CJK UNIFIED IDEOGRAPH + {0xC38A, 0x8122}, //11208 #CJK UNIFIED IDEOGRAPH + {0xC38B, 0x8123}, //11209 #CJK UNIFIED IDEOGRAPH + {0xC38C, 0x8124}, //11210 #CJK UNIFIED IDEOGRAPH + {0xC38D, 0x8125}, //11211 #CJK UNIFIED IDEOGRAPH + {0xC38E, 0x8126}, //11212 #CJK UNIFIED IDEOGRAPH + {0xC38F, 0x8127}, //11213 #CJK UNIFIED IDEOGRAPH + {0xC390, 0x8128}, //11214 #CJK UNIFIED IDEOGRAPH + {0xC391, 0x8129}, //11215 #CJK UNIFIED IDEOGRAPH + {0xC392, 0x812A}, //11216 #CJK UNIFIED IDEOGRAPH + {0xC393, 0x812B}, //11217 #CJK UNIFIED IDEOGRAPH + {0xC394, 0x812D}, //11218 #CJK UNIFIED IDEOGRAPH + {0xC395, 0x812E}, //11219 #CJK UNIFIED IDEOGRAPH + {0xC396, 0x8130}, //11220 #CJK UNIFIED IDEOGRAPH + {0xC397, 0x8133}, //11221 #CJK UNIFIED IDEOGRAPH + {0xC398, 0x8134}, //11222 #CJK UNIFIED IDEOGRAPH + {0xC399, 0x8135}, //11223 #CJK UNIFIED IDEOGRAPH + {0xC39A, 0x8137}, //11224 #CJK UNIFIED IDEOGRAPH + {0xC39B, 0x8139}, //11225 #CJK UNIFIED IDEOGRAPH + {0xC39C, 0x813A}, //11226 #CJK UNIFIED IDEOGRAPH + {0xC39D, 0x813B}, //11227 #CJK UNIFIED IDEOGRAPH + {0xC39E, 0x813C}, //11228 #CJK UNIFIED IDEOGRAPH + {0xC39F, 0x813D}, //11229 #CJK UNIFIED IDEOGRAPH + {0xC3A0, 0x813F}, //11230 #CJK UNIFIED IDEOGRAPH + {0xC3A1, 0x8C29}, //11231 #CJK UNIFIED IDEOGRAPH + {0xC3A2, 0x8292}, //11232 #CJK UNIFIED IDEOGRAPH + {0xC3A3, 0x832B}, //11233 #CJK UNIFIED IDEOGRAPH + {0xC3A4, 0x76F2}, //11234 #CJK UNIFIED IDEOGRAPH + {0xC3A5, 0x6C13}, //11235 #CJK UNIFIED IDEOGRAPH + {0xC3A6, 0x5FD9}, //11236 #CJK UNIFIED IDEOGRAPH + {0xC3A7, 0x83BD}, //11237 #CJK UNIFIED IDEOGRAPH + {0xC3A8, 0x732B}, //11238 #CJK UNIFIED IDEOGRAPH + {0xC3A9, 0x8305}, //11239 #CJK UNIFIED IDEOGRAPH + {0xC3AA, 0x951A}, //11240 #CJK UNIFIED IDEOGRAPH + {0xC3AB, 0x6BDB}, //11241 #CJK UNIFIED IDEOGRAPH + {0xC3AC, 0x77DB}, //11242 #CJK UNIFIED IDEOGRAPH + {0xC3AD, 0x94C6}, //11243 #CJK UNIFIED IDEOGRAPH + {0xC3AE, 0x536F}, //11244 #CJK UNIFIED IDEOGRAPH + {0xC3AF, 0x8302}, //11245 #CJK UNIFIED IDEOGRAPH + {0xC3B0, 0x5192}, //11246 #CJK UNIFIED IDEOGRAPH + {0xC3B1, 0x5E3D}, //11247 #CJK UNIFIED IDEOGRAPH + {0xC3B2, 0x8C8C}, //11248 #CJK UNIFIED IDEOGRAPH + {0xC3B3, 0x8D38}, //11249 #CJK UNIFIED IDEOGRAPH + {0xC3B4, 0x4E48}, //11250 #CJK UNIFIED IDEOGRAPH + {0xC3B5, 0x73AB}, //11251 #CJK UNIFIED IDEOGRAPH + {0xC3B6, 0x679A}, //11252 #CJK UNIFIED IDEOGRAPH + {0xC3B7, 0x6885}, //11253 #CJK UNIFIED IDEOGRAPH + {0xC3B8, 0x9176}, //11254 #CJK UNIFIED IDEOGRAPH + {0xC3B9, 0x9709}, //11255 #CJK UNIFIED IDEOGRAPH + {0xC3BA, 0x7164}, //11256 #CJK UNIFIED IDEOGRAPH + {0xC3BB, 0x6CA1}, //11257 #CJK UNIFIED IDEOGRAPH + {0xC3BC, 0x7709}, //11258 #CJK UNIFIED IDEOGRAPH + {0xC3BD, 0x5A92}, //11259 #CJK UNIFIED IDEOGRAPH + {0xC3BE, 0x9541}, //11260 #CJK UNIFIED IDEOGRAPH + {0xC3BF, 0x6BCF}, //11261 #CJK UNIFIED IDEOGRAPH + {0xC3C0, 0x7F8E}, //11262 #CJK UNIFIED IDEOGRAPH + {0xC3C1, 0x6627}, //11263 #CJK UNIFIED IDEOGRAPH + {0xC3C2, 0x5BD0}, //11264 #CJK UNIFIED IDEOGRAPH + {0xC3C3, 0x59B9}, //11265 #CJK UNIFIED IDEOGRAPH + {0xC3C4, 0x5A9A}, //11266 #CJK UNIFIED IDEOGRAPH + {0xC3C5, 0x95E8}, //11267 #CJK UNIFIED IDEOGRAPH + {0xC3C6, 0x95F7}, //11268 #CJK UNIFIED IDEOGRAPH + {0xC3C7, 0x4EEC}, //11269 #CJK UNIFIED IDEOGRAPH + {0xC3C8, 0x840C}, //11270 #CJK UNIFIED IDEOGRAPH + {0xC3C9, 0x8499}, //11271 #CJK UNIFIED IDEOGRAPH + {0xC3CA, 0x6AAC}, //11272 #CJK UNIFIED IDEOGRAPH + {0xC3CB, 0x76DF}, //11273 #CJK UNIFIED IDEOGRAPH + {0xC3CC, 0x9530}, //11274 #CJK UNIFIED IDEOGRAPH + {0xC3CD, 0x731B}, //11275 #CJK UNIFIED IDEOGRAPH + {0xC3CE, 0x68A6}, //11276 #CJK UNIFIED IDEOGRAPH + {0xC3CF, 0x5B5F}, //11277 #CJK UNIFIED IDEOGRAPH + {0xC3D0, 0x772F}, //11278 #CJK UNIFIED IDEOGRAPH + {0xC3D1, 0x919A}, //11279 #CJK UNIFIED IDEOGRAPH + {0xC3D2, 0x9761}, //11280 #CJK UNIFIED IDEOGRAPH + {0xC3D3, 0x7CDC}, //11281 #CJK UNIFIED IDEOGRAPH + {0xC3D4, 0x8FF7}, //11282 #CJK UNIFIED IDEOGRAPH + {0xC3D5, 0x8C1C}, //11283 #CJK UNIFIED IDEOGRAPH + {0xC3D6, 0x5F25}, //11284 #CJK UNIFIED IDEOGRAPH + {0xC3D7, 0x7C73}, //11285 #CJK UNIFIED IDEOGRAPH + {0xC3D8, 0x79D8}, //11286 #CJK UNIFIED IDEOGRAPH + {0xC3D9, 0x89C5}, //11287 #CJK UNIFIED IDEOGRAPH + {0xC3DA, 0x6CCC}, //11288 #CJK UNIFIED IDEOGRAPH + {0xC3DB, 0x871C}, //11289 #CJK UNIFIED IDEOGRAPH + {0xC3DC, 0x5BC6}, //11290 #CJK UNIFIED IDEOGRAPH + {0xC3DD, 0x5E42}, //11291 #CJK UNIFIED IDEOGRAPH + {0xC3DE, 0x68C9}, //11292 #CJK UNIFIED IDEOGRAPH + {0xC3DF, 0x7720}, //11293 #CJK UNIFIED IDEOGRAPH + {0xC3E0, 0x7EF5}, //11294 #CJK UNIFIED IDEOGRAPH + {0xC3E1, 0x5195}, //11295 #CJK UNIFIED IDEOGRAPH + {0xC3E2, 0x514D}, //11296 #CJK UNIFIED IDEOGRAPH + {0xC3E3, 0x52C9}, //11297 #CJK UNIFIED IDEOGRAPH + {0xC3E4, 0x5A29}, //11298 #CJK UNIFIED IDEOGRAPH + {0xC3E5, 0x7F05}, //11299 #CJK UNIFIED IDEOGRAPH + {0xC3E6, 0x9762}, //11300 #CJK UNIFIED IDEOGRAPH + {0xC3E7, 0x82D7}, //11301 #CJK UNIFIED IDEOGRAPH + {0xC3E8, 0x63CF}, //11302 #CJK UNIFIED IDEOGRAPH + {0xC3E9, 0x7784}, //11303 #CJK UNIFIED IDEOGRAPH + {0xC3EA, 0x85D0}, //11304 #CJK UNIFIED IDEOGRAPH + {0xC3EB, 0x79D2}, //11305 #CJK UNIFIED IDEOGRAPH + {0xC3EC, 0x6E3A}, //11306 #CJK UNIFIED IDEOGRAPH + {0xC3ED, 0x5E99}, //11307 #CJK UNIFIED IDEOGRAPH + {0xC3EE, 0x5999}, //11308 #CJK UNIFIED IDEOGRAPH + {0xC3EF, 0x8511}, //11309 #CJK UNIFIED IDEOGRAPH + {0xC3F0, 0x706D}, //11310 #CJK UNIFIED IDEOGRAPH + {0xC3F1, 0x6C11}, //11311 #CJK UNIFIED IDEOGRAPH + {0xC3F2, 0x62BF}, //11312 #CJK UNIFIED IDEOGRAPH + {0xC3F3, 0x76BF}, //11313 #CJK UNIFIED IDEOGRAPH + {0xC3F4, 0x654F}, //11314 #CJK UNIFIED IDEOGRAPH + {0xC3F5, 0x60AF}, //11315 #CJK UNIFIED IDEOGRAPH + {0xC3F6, 0x95FD}, //11316 #CJK UNIFIED IDEOGRAPH + {0xC3F7, 0x660E}, //11317 #CJK UNIFIED IDEOGRAPH + {0xC3F8, 0x879F}, //11318 #CJK UNIFIED IDEOGRAPH + {0xC3F9, 0x9E23}, //11319 #CJK UNIFIED IDEOGRAPH + {0xC3FA, 0x94ED}, //11320 #CJK UNIFIED IDEOGRAPH + {0xC3FB, 0x540D}, //11321 #CJK UNIFIED IDEOGRAPH + {0xC3FC, 0x547D}, //11322 #CJK UNIFIED IDEOGRAPH + {0xC3FD, 0x8C2C}, //11323 #CJK UNIFIED IDEOGRAPH + {0xC3FE, 0x6478}, //11324 #CJK UNIFIED IDEOGRAPH + {0xC440, 0x8140}, //11325 #CJK UNIFIED IDEOGRAPH + {0xC441, 0x8141}, //11326 #CJK UNIFIED IDEOGRAPH + {0xC442, 0x8142}, //11327 #CJK UNIFIED IDEOGRAPH + {0xC443, 0x8143}, //11328 #CJK UNIFIED IDEOGRAPH + {0xC444, 0x8144}, //11329 #CJK UNIFIED IDEOGRAPH + {0xC445, 0x8145}, //11330 #CJK UNIFIED IDEOGRAPH + {0xC446, 0x8147}, //11331 #CJK UNIFIED IDEOGRAPH + {0xC447, 0x8149}, //11332 #CJK UNIFIED IDEOGRAPH + {0xC448, 0x814D}, //11333 #CJK UNIFIED IDEOGRAPH + {0xC449, 0x814E}, //11334 #CJK UNIFIED IDEOGRAPH + {0xC44A, 0x814F}, //11335 #CJK UNIFIED IDEOGRAPH + {0xC44B, 0x8152}, //11336 #CJK UNIFIED IDEOGRAPH + {0xC44C, 0x8156}, //11337 #CJK UNIFIED IDEOGRAPH + {0xC44D, 0x8157}, //11338 #CJK UNIFIED IDEOGRAPH + {0xC44E, 0x8158}, //11339 #CJK UNIFIED IDEOGRAPH + {0xC44F, 0x815B}, //11340 #CJK UNIFIED IDEOGRAPH + {0xC450, 0x815C}, //11341 #CJK UNIFIED IDEOGRAPH + {0xC451, 0x815D}, //11342 #CJK UNIFIED IDEOGRAPH + {0xC452, 0x815E}, //11343 #CJK UNIFIED IDEOGRAPH + {0xC453, 0x815F}, //11344 #CJK UNIFIED IDEOGRAPH + {0xC454, 0x8161}, //11345 #CJK UNIFIED IDEOGRAPH + {0xC455, 0x8162}, //11346 #CJK UNIFIED IDEOGRAPH + {0xC456, 0x8163}, //11347 #CJK UNIFIED IDEOGRAPH + {0xC457, 0x8164}, //11348 #CJK UNIFIED IDEOGRAPH + {0xC458, 0x8166}, //11349 #CJK UNIFIED IDEOGRAPH + {0xC459, 0x8168}, //11350 #CJK UNIFIED IDEOGRAPH + {0xC45A, 0x816A}, //11351 #CJK UNIFIED IDEOGRAPH + {0xC45B, 0x816B}, //11352 #CJK UNIFIED IDEOGRAPH + {0xC45C, 0x816C}, //11353 #CJK UNIFIED IDEOGRAPH + {0xC45D, 0x816F}, //11354 #CJK UNIFIED IDEOGRAPH + {0xC45E, 0x8172}, //11355 #CJK UNIFIED IDEOGRAPH + {0xC45F, 0x8173}, //11356 #CJK UNIFIED IDEOGRAPH + {0xC460, 0x8175}, //11357 #CJK UNIFIED IDEOGRAPH + {0xC461, 0x8176}, //11358 #CJK UNIFIED IDEOGRAPH + {0xC462, 0x8177}, //11359 #CJK UNIFIED IDEOGRAPH + {0xC463, 0x8178}, //11360 #CJK UNIFIED IDEOGRAPH + {0xC464, 0x8181}, //11361 #CJK UNIFIED IDEOGRAPH + {0xC465, 0x8183}, //11362 #CJK UNIFIED IDEOGRAPH + {0xC466, 0x8184}, //11363 #CJK UNIFIED IDEOGRAPH + {0xC467, 0x8185}, //11364 #CJK UNIFIED IDEOGRAPH + {0xC468, 0x8186}, //11365 #CJK UNIFIED IDEOGRAPH + {0xC469, 0x8187}, //11366 #CJK UNIFIED IDEOGRAPH + {0xC46A, 0x8189}, //11367 #CJK UNIFIED IDEOGRAPH + {0xC46B, 0x818B}, //11368 #CJK UNIFIED IDEOGRAPH + {0xC46C, 0x818C}, //11369 #CJK UNIFIED IDEOGRAPH + {0xC46D, 0x818D}, //11370 #CJK UNIFIED IDEOGRAPH + {0xC46E, 0x818E}, //11371 #CJK UNIFIED IDEOGRAPH + {0xC46F, 0x8190}, //11372 #CJK UNIFIED IDEOGRAPH + {0xC470, 0x8192}, //11373 #CJK UNIFIED IDEOGRAPH + {0xC471, 0x8193}, //11374 #CJK UNIFIED IDEOGRAPH + {0xC472, 0x8194}, //11375 #CJK UNIFIED IDEOGRAPH + {0xC473, 0x8195}, //11376 #CJK UNIFIED IDEOGRAPH + {0xC474, 0x8196}, //11377 #CJK UNIFIED IDEOGRAPH + {0xC475, 0x8197}, //11378 #CJK UNIFIED IDEOGRAPH + {0xC476, 0x8199}, //11379 #CJK UNIFIED IDEOGRAPH + {0xC477, 0x819A}, //11380 #CJK UNIFIED IDEOGRAPH + {0xC478, 0x819E}, //11381 #CJK UNIFIED IDEOGRAPH + {0xC479, 0x819F}, //11382 #CJK UNIFIED IDEOGRAPH + {0xC47A, 0x81A0}, //11383 #CJK UNIFIED IDEOGRAPH + {0xC47B, 0x81A1}, //11384 #CJK UNIFIED IDEOGRAPH + {0xC47C, 0x81A2}, //11385 #CJK UNIFIED IDEOGRAPH + {0xC47D, 0x81A4}, //11386 #CJK UNIFIED IDEOGRAPH + {0xC47E, 0x81A5}, //11387 #CJK UNIFIED IDEOGRAPH + {0xC480, 0x81A7}, //11388 #CJK UNIFIED IDEOGRAPH + {0xC481, 0x81A9}, //11389 #CJK UNIFIED IDEOGRAPH + {0xC482, 0x81AB}, //11390 #CJK UNIFIED IDEOGRAPH + {0xC483, 0x81AC}, //11391 #CJK UNIFIED IDEOGRAPH + {0xC484, 0x81AD}, //11392 #CJK UNIFIED IDEOGRAPH + {0xC485, 0x81AE}, //11393 #CJK UNIFIED IDEOGRAPH + {0xC486, 0x81AF}, //11394 #CJK UNIFIED IDEOGRAPH + {0xC487, 0x81B0}, //11395 #CJK UNIFIED IDEOGRAPH + {0xC488, 0x81B1}, //11396 #CJK UNIFIED IDEOGRAPH + {0xC489, 0x81B2}, //11397 #CJK UNIFIED IDEOGRAPH + {0xC48A, 0x81B4}, //11398 #CJK UNIFIED IDEOGRAPH + {0xC48B, 0x81B5}, //11399 #CJK UNIFIED IDEOGRAPH + {0xC48C, 0x81B6}, //11400 #CJK UNIFIED IDEOGRAPH + {0xC48D, 0x81B7}, //11401 #CJK UNIFIED IDEOGRAPH + {0xC48E, 0x81B8}, //11402 #CJK UNIFIED IDEOGRAPH + {0xC48F, 0x81B9}, //11403 #CJK UNIFIED IDEOGRAPH + {0xC490, 0x81BC}, //11404 #CJK UNIFIED IDEOGRAPH + {0xC491, 0x81BD}, //11405 #CJK UNIFIED IDEOGRAPH + {0xC492, 0x81BE}, //11406 #CJK UNIFIED IDEOGRAPH + {0xC493, 0x81BF}, //11407 #CJK UNIFIED IDEOGRAPH + {0xC494, 0x81C4}, //11408 #CJK UNIFIED IDEOGRAPH + {0xC495, 0x81C5}, //11409 #CJK UNIFIED IDEOGRAPH + {0xC496, 0x81C7}, //11410 #CJK UNIFIED IDEOGRAPH + {0xC497, 0x81C8}, //11411 #CJK UNIFIED IDEOGRAPH + {0xC498, 0x81C9}, //11412 #CJK UNIFIED IDEOGRAPH + {0xC499, 0x81CB}, //11413 #CJK UNIFIED IDEOGRAPH + {0xC49A, 0x81CD}, //11414 #CJK UNIFIED IDEOGRAPH + {0xC49B, 0x81CE}, //11415 #CJK UNIFIED IDEOGRAPH + {0xC49C, 0x81CF}, //11416 #CJK UNIFIED IDEOGRAPH + {0xC49D, 0x81D0}, //11417 #CJK UNIFIED IDEOGRAPH + {0xC49E, 0x81D1}, //11418 #CJK UNIFIED IDEOGRAPH + {0xC49F, 0x81D2}, //11419 #CJK UNIFIED IDEOGRAPH + {0xC4A0, 0x81D3}, //11420 #CJK UNIFIED IDEOGRAPH + {0xC4A1, 0x6479}, //11421 #CJK UNIFIED IDEOGRAPH + {0xC4A2, 0x8611}, //11422 #CJK UNIFIED IDEOGRAPH + {0xC4A3, 0x6A21}, //11423 #CJK UNIFIED IDEOGRAPH + {0xC4A4, 0x819C}, //11424 #CJK UNIFIED IDEOGRAPH + {0xC4A5, 0x78E8}, //11425 #CJK UNIFIED IDEOGRAPH + {0xC4A6, 0x6469}, //11426 #CJK UNIFIED IDEOGRAPH + {0xC4A7, 0x9B54}, //11427 #CJK UNIFIED IDEOGRAPH + {0xC4A8, 0x62B9}, //11428 #CJK UNIFIED IDEOGRAPH + {0xC4A9, 0x672B}, //11429 #CJK UNIFIED IDEOGRAPH + {0xC4AA, 0x83AB}, //11430 #CJK UNIFIED IDEOGRAPH + {0xC4AB, 0x58A8}, //11431 #CJK UNIFIED IDEOGRAPH + {0xC4AC, 0x9ED8}, //11432 #CJK UNIFIED IDEOGRAPH + {0xC4AD, 0x6CAB}, //11433 #CJK UNIFIED IDEOGRAPH + {0xC4AE, 0x6F20}, //11434 #CJK UNIFIED IDEOGRAPH + {0xC4AF, 0x5BDE}, //11435 #CJK UNIFIED IDEOGRAPH + {0xC4B0, 0x964C}, //11436 #CJK UNIFIED IDEOGRAPH + {0xC4B1, 0x8C0B}, //11437 #CJK UNIFIED IDEOGRAPH + {0xC4B2, 0x725F}, //11438 #CJK UNIFIED IDEOGRAPH + {0xC4B3, 0x67D0}, //11439 #CJK UNIFIED IDEOGRAPH + {0xC4B4, 0x62C7}, //11440 #CJK UNIFIED IDEOGRAPH + {0xC4B5, 0x7261}, //11441 #CJK UNIFIED IDEOGRAPH + {0xC4B6, 0x4EA9}, //11442 #CJK UNIFIED IDEOGRAPH + {0xC4B7, 0x59C6}, //11443 #CJK UNIFIED IDEOGRAPH + {0xC4B8, 0x6BCD}, //11444 #CJK UNIFIED IDEOGRAPH + {0xC4B9, 0x5893}, //11445 #CJK UNIFIED IDEOGRAPH + {0xC4BA, 0x66AE}, //11446 #CJK UNIFIED IDEOGRAPH + {0xC4BB, 0x5E55}, //11447 #CJK UNIFIED IDEOGRAPH + {0xC4BC, 0x52DF}, //11448 #CJK UNIFIED IDEOGRAPH + {0xC4BD, 0x6155}, //11449 #CJK UNIFIED IDEOGRAPH + {0xC4BE, 0x6728}, //11450 #CJK UNIFIED IDEOGRAPH + {0xC4BF, 0x76EE}, //11451 #CJK UNIFIED IDEOGRAPH + {0xC4C0, 0x7766}, //11452 #CJK UNIFIED IDEOGRAPH + {0xC4C1, 0x7267}, //11453 #CJK UNIFIED IDEOGRAPH + {0xC4C2, 0x7A46}, //11454 #CJK UNIFIED IDEOGRAPH + {0xC4C3, 0x62FF}, //11455 #CJK UNIFIED IDEOGRAPH + {0xC4C4, 0x54EA}, //11456 #CJK UNIFIED IDEOGRAPH + {0xC4C5, 0x5450}, //11457 #CJK UNIFIED IDEOGRAPH + {0xC4C6, 0x94A0}, //11458 #CJK UNIFIED IDEOGRAPH + {0xC4C7, 0x90A3}, //11459 #CJK UNIFIED IDEOGRAPH + {0xC4C8, 0x5A1C}, //11460 #CJK UNIFIED IDEOGRAPH + {0xC4C9, 0x7EB3}, //11461 #CJK UNIFIED IDEOGRAPH + {0xC4CA, 0x6C16}, //11462 #CJK UNIFIED IDEOGRAPH + {0xC4CB, 0x4E43}, //11463 #CJK UNIFIED IDEOGRAPH + {0xC4CC, 0x5976}, //11464 #CJK UNIFIED IDEOGRAPH + {0xC4CD, 0x8010}, //11465 #CJK UNIFIED IDEOGRAPH + {0xC4CE, 0x5948}, //11466 #CJK UNIFIED IDEOGRAPH + {0xC4CF, 0x5357}, //11467 #CJK UNIFIED IDEOGRAPH + {0xC4D0, 0x7537}, //11468 #CJK UNIFIED IDEOGRAPH + {0xC4D1, 0x96BE}, //11469 #CJK UNIFIED IDEOGRAPH + {0xC4D2, 0x56CA}, //11470 #CJK UNIFIED IDEOGRAPH + {0xC4D3, 0x6320}, //11471 #CJK UNIFIED IDEOGRAPH + {0xC4D4, 0x8111}, //11472 #CJK UNIFIED IDEOGRAPH + {0xC4D5, 0x607C}, //11473 #CJK UNIFIED IDEOGRAPH + {0xC4D6, 0x95F9}, //11474 #CJK UNIFIED IDEOGRAPH + {0xC4D7, 0x6DD6}, //11475 #CJK UNIFIED IDEOGRAPH + {0xC4D8, 0x5462}, //11476 #CJK UNIFIED IDEOGRAPH + {0xC4D9, 0x9981}, //11477 #CJK UNIFIED IDEOGRAPH + {0xC4DA, 0x5185}, //11478 #CJK UNIFIED IDEOGRAPH + {0xC4DB, 0x5AE9}, //11479 #CJK UNIFIED IDEOGRAPH + {0xC4DC, 0x80FD}, //11480 #CJK UNIFIED IDEOGRAPH + {0xC4DD, 0x59AE}, //11481 #CJK UNIFIED IDEOGRAPH + {0xC4DE, 0x9713}, //11482 #CJK UNIFIED IDEOGRAPH + {0xC4DF, 0x502A}, //11483 #CJK UNIFIED IDEOGRAPH + {0xC4E0, 0x6CE5}, //11484 #CJK UNIFIED IDEOGRAPH + {0xC4E1, 0x5C3C}, //11485 #CJK UNIFIED IDEOGRAPH + {0xC4E2, 0x62DF}, //11486 #CJK UNIFIED IDEOGRAPH + {0xC4E3, 0x4F60}, //11487 #CJK UNIFIED IDEOGRAPH + {0xC4E4, 0x533F}, //11488 #CJK UNIFIED IDEOGRAPH + {0xC4E5, 0x817B}, //11489 #CJK UNIFIED IDEOGRAPH + {0xC4E6, 0x9006}, //11490 #CJK UNIFIED IDEOGRAPH + {0xC4E7, 0x6EBA}, //11491 #CJK UNIFIED IDEOGRAPH + {0xC4E8, 0x852B}, //11492 #CJK UNIFIED IDEOGRAPH + {0xC4E9, 0x62C8}, //11493 #CJK UNIFIED IDEOGRAPH + {0xC4EA, 0x5E74}, //11494 #CJK UNIFIED IDEOGRAPH + {0xC4EB, 0x78BE}, //11495 #CJK UNIFIED IDEOGRAPH + {0xC4EC, 0x64B5}, //11496 #CJK UNIFIED IDEOGRAPH + {0xC4ED, 0x637B}, //11497 #CJK UNIFIED IDEOGRAPH + {0xC4EE, 0x5FF5}, //11498 #CJK UNIFIED IDEOGRAPH + {0xC4EF, 0x5A18}, //11499 #CJK UNIFIED IDEOGRAPH + {0xC4F0, 0x917F}, //11500 #CJK UNIFIED IDEOGRAPH + {0xC4F1, 0x9E1F}, //11501 #CJK UNIFIED IDEOGRAPH + {0xC4F2, 0x5C3F}, //11502 #CJK UNIFIED IDEOGRAPH + {0xC4F3, 0x634F}, //11503 #CJK UNIFIED IDEOGRAPH + {0xC4F4, 0x8042}, //11504 #CJK UNIFIED IDEOGRAPH + {0xC4F5, 0x5B7D}, //11505 #CJK UNIFIED IDEOGRAPH + {0xC4F6, 0x556E}, //11506 #CJK UNIFIED IDEOGRAPH + {0xC4F7, 0x954A}, //11507 #CJK UNIFIED IDEOGRAPH + {0xC4F8, 0x954D}, //11508 #CJK UNIFIED IDEOGRAPH + {0xC4F9, 0x6D85}, //11509 #CJK UNIFIED IDEOGRAPH + {0xC4FA, 0x60A8}, //11510 #CJK UNIFIED IDEOGRAPH + {0xC4FB, 0x67E0}, //11511 #CJK UNIFIED IDEOGRAPH + {0xC4FC, 0x72DE}, //11512 #CJK UNIFIED IDEOGRAPH + {0xC4FD, 0x51DD}, //11513 #CJK UNIFIED IDEOGRAPH + {0xC4FE, 0x5B81}, //11514 #CJK UNIFIED IDEOGRAPH + {0xC540, 0x81D4}, //11515 #CJK UNIFIED IDEOGRAPH + {0xC541, 0x81D5}, //11516 #CJK UNIFIED IDEOGRAPH + {0xC542, 0x81D6}, //11517 #CJK UNIFIED IDEOGRAPH + {0xC543, 0x81D7}, //11518 #CJK UNIFIED IDEOGRAPH + {0xC544, 0x81D8}, //11519 #CJK UNIFIED IDEOGRAPH + {0xC545, 0x81D9}, //11520 #CJK UNIFIED IDEOGRAPH + {0xC546, 0x81DA}, //11521 #CJK UNIFIED IDEOGRAPH + {0xC547, 0x81DB}, //11522 #CJK UNIFIED IDEOGRAPH + {0xC548, 0x81DC}, //11523 #CJK UNIFIED IDEOGRAPH + {0xC549, 0x81DD}, //11524 #CJK UNIFIED IDEOGRAPH + {0xC54A, 0x81DE}, //11525 #CJK UNIFIED IDEOGRAPH + {0xC54B, 0x81DF}, //11526 #CJK UNIFIED IDEOGRAPH + {0xC54C, 0x81E0}, //11527 #CJK UNIFIED IDEOGRAPH + {0xC54D, 0x81E1}, //11528 #CJK UNIFIED IDEOGRAPH + {0xC54E, 0x81E2}, //11529 #CJK UNIFIED IDEOGRAPH + {0xC54F, 0x81E4}, //11530 #CJK UNIFIED IDEOGRAPH + {0xC550, 0x81E5}, //11531 #CJK UNIFIED IDEOGRAPH + {0xC551, 0x81E6}, //11532 #CJK UNIFIED IDEOGRAPH + {0xC552, 0x81E8}, //11533 #CJK UNIFIED IDEOGRAPH + {0xC553, 0x81E9}, //11534 #CJK UNIFIED IDEOGRAPH + {0xC554, 0x81EB}, //11535 #CJK UNIFIED IDEOGRAPH + {0xC555, 0x81EE}, //11536 #CJK UNIFIED IDEOGRAPH + {0xC556, 0x81EF}, //11537 #CJK UNIFIED IDEOGRAPH + {0xC557, 0x81F0}, //11538 #CJK UNIFIED IDEOGRAPH + {0xC558, 0x81F1}, //11539 #CJK UNIFIED IDEOGRAPH + {0xC559, 0x81F2}, //11540 #CJK UNIFIED IDEOGRAPH + {0xC55A, 0x81F5}, //11541 #CJK UNIFIED IDEOGRAPH + {0xC55B, 0x81F6}, //11542 #CJK UNIFIED IDEOGRAPH + {0xC55C, 0x81F7}, //11543 #CJK UNIFIED IDEOGRAPH + {0xC55D, 0x81F8}, //11544 #CJK UNIFIED IDEOGRAPH + {0xC55E, 0x81F9}, //11545 #CJK UNIFIED IDEOGRAPH + {0xC55F, 0x81FA}, //11546 #CJK UNIFIED IDEOGRAPH + {0xC560, 0x81FD}, //11547 #CJK UNIFIED IDEOGRAPH + {0xC561, 0x81FF}, //11548 #CJK UNIFIED IDEOGRAPH + {0xC562, 0x8203}, //11549 #CJK UNIFIED IDEOGRAPH + {0xC563, 0x8207}, //11550 #CJK UNIFIED IDEOGRAPH + {0xC564, 0x8208}, //11551 #CJK UNIFIED IDEOGRAPH + {0xC565, 0x8209}, //11552 #CJK UNIFIED IDEOGRAPH + {0xC566, 0x820A}, //11553 #CJK UNIFIED IDEOGRAPH + {0xC567, 0x820B}, //11554 #CJK UNIFIED IDEOGRAPH + {0xC568, 0x820E}, //11555 #CJK UNIFIED IDEOGRAPH + {0xC569, 0x820F}, //11556 #CJK UNIFIED IDEOGRAPH + {0xC56A, 0x8211}, //11557 #CJK UNIFIED IDEOGRAPH + {0xC56B, 0x8213}, //11558 #CJK UNIFIED IDEOGRAPH + {0xC56C, 0x8215}, //11559 #CJK UNIFIED IDEOGRAPH + {0xC56D, 0x8216}, //11560 #CJK UNIFIED IDEOGRAPH + {0xC56E, 0x8217}, //11561 #CJK UNIFIED IDEOGRAPH + {0xC56F, 0x8218}, //11562 #CJK UNIFIED IDEOGRAPH + {0xC570, 0x8219}, //11563 #CJK UNIFIED IDEOGRAPH + {0xC571, 0x821A}, //11564 #CJK UNIFIED IDEOGRAPH + {0xC572, 0x821D}, //11565 #CJK UNIFIED IDEOGRAPH + {0xC573, 0x8220}, //11566 #CJK UNIFIED IDEOGRAPH + {0xC574, 0x8224}, //11567 #CJK UNIFIED IDEOGRAPH + {0xC575, 0x8225}, //11568 #CJK UNIFIED IDEOGRAPH + {0xC576, 0x8226}, //11569 #CJK UNIFIED IDEOGRAPH + {0xC577, 0x8227}, //11570 #CJK UNIFIED IDEOGRAPH + {0xC578, 0x8229}, //11571 #CJK UNIFIED IDEOGRAPH + {0xC579, 0x822E}, //11572 #CJK UNIFIED IDEOGRAPH + {0xC57A, 0x8232}, //11573 #CJK UNIFIED IDEOGRAPH + {0xC57B, 0x823A}, //11574 #CJK UNIFIED IDEOGRAPH + {0xC57C, 0x823C}, //11575 #CJK UNIFIED IDEOGRAPH + {0xC57D, 0x823D}, //11576 #CJK UNIFIED IDEOGRAPH + {0xC57E, 0x823F}, //11577 #CJK UNIFIED IDEOGRAPH + {0xC580, 0x8240}, //11578 #CJK UNIFIED IDEOGRAPH + {0xC581, 0x8241}, //11579 #CJK UNIFIED IDEOGRAPH + {0xC582, 0x8242}, //11580 #CJK UNIFIED IDEOGRAPH + {0xC583, 0x8243}, //11581 #CJK UNIFIED IDEOGRAPH + {0xC584, 0x8245}, //11582 #CJK UNIFIED IDEOGRAPH + {0xC585, 0x8246}, //11583 #CJK UNIFIED IDEOGRAPH + {0xC586, 0x8248}, //11584 #CJK UNIFIED IDEOGRAPH + {0xC587, 0x824A}, //11585 #CJK UNIFIED IDEOGRAPH + {0xC588, 0x824C}, //11586 #CJK UNIFIED IDEOGRAPH + {0xC589, 0x824D}, //11587 #CJK UNIFIED IDEOGRAPH + {0xC58A, 0x824E}, //11588 #CJK UNIFIED IDEOGRAPH + {0xC58B, 0x8250}, //11589 #CJK UNIFIED IDEOGRAPH + {0xC58C, 0x8251}, //11590 #CJK UNIFIED IDEOGRAPH + {0xC58D, 0x8252}, //11591 #CJK UNIFIED IDEOGRAPH + {0xC58E, 0x8253}, //11592 #CJK UNIFIED IDEOGRAPH + {0xC58F, 0x8254}, //11593 #CJK UNIFIED IDEOGRAPH + {0xC590, 0x8255}, //11594 #CJK UNIFIED IDEOGRAPH + {0xC591, 0x8256}, //11595 #CJK UNIFIED IDEOGRAPH + {0xC592, 0x8257}, //11596 #CJK UNIFIED IDEOGRAPH + {0xC593, 0x8259}, //11597 #CJK UNIFIED IDEOGRAPH + {0xC594, 0x825B}, //11598 #CJK UNIFIED IDEOGRAPH + {0xC595, 0x825C}, //11599 #CJK UNIFIED IDEOGRAPH + {0xC596, 0x825D}, //11600 #CJK UNIFIED IDEOGRAPH + {0xC597, 0x825E}, //11601 #CJK UNIFIED IDEOGRAPH + {0xC598, 0x8260}, //11602 #CJK UNIFIED IDEOGRAPH + {0xC599, 0x8261}, //11603 #CJK UNIFIED IDEOGRAPH + {0xC59A, 0x8262}, //11604 #CJK UNIFIED IDEOGRAPH + {0xC59B, 0x8263}, //11605 #CJK UNIFIED IDEOGRAPH + {0xC59C, 0x8264}, //11606 #CJK UNIFIED IDEOGRAPH + {0xC59D, 0x8265}, //11607 #CJK UNIFIED IDEOGRAPH + {0xC59E, 0x8266}, //11608 #CJK UNIFIED IDEOGRAPH + {0xC59F, 0x8267}, //11609 #CJK UNIFIED IDEOGRAPH + {0xC5A0, 0x8269}, //11610 #CJK UNIFIED IDEOGRAPH + {0xC5A1, 0x62E7}, //11611 #CJK UNIFIED IDEOGRAPH + {0xC5A2, 0x6CDE}, //11612 #CJK UNIFIED IDEOGRAPH + {0xC5A3, 0x725B}, //11613 #CJK UNIFIED IDEOGRAPH + {0xC5A4, 0x626D}, //11614 #CJK UNIFIED IDEOGRAPH + {0xC5A5, 0x94AE}, //11615 #CJK UNIFIED IDEOGRAPH + {0xC5A6, 0x7EBD}, //11616 #CJK UNIFIED IDEOGRAPH + {0xC5A7, 0x8113}, //11617 #CJK UNIFIED IDEOGRAPH + {0xC5A8, 0x6D53}, //11618 #CJK UNIFIED IDEOGRAPH + {0xC5A9, 0x519C}, //11619 #CJK UNIFIED IDEOGRAPH + {0xC5AA, 0x5F04}, //11620 #CJK UNIFIED IDEOGRAPH + {0xC5AB, 0x5974}, //11621 #CJK UNIFIED IDEOGRAPH + {0xC5AC, 0x52AA}, //11622 #CJK UNIFIED IDEOGRAPH + {0xC5AD, 0x6012}, //11623 #CJK UNIFIED IDEOGRAPH + {0xC5AE, 0x5973}, //11624 #CJK UNIFIED IDEOGRAPH + {0xC5AF, 0x6696}, //11625 #CJK UNIFIED IDEOGRAPH + {0xC5B0, 0x8650}, //11626 #CJK UNIFIED IDEOGRAPH + {0xC5B1, 0x759F}, //11627 #CJK UNIFIED IDEOGRAPH + {0xC5B2, 0x632A}, //11628 #CJK UNIFIED IDEOGRAPH + {0xC5B3, 0x61E6}, //11629 #CJK UNIFIED IDEOGRAPH + {0xC5B4, 0x7CEF}, //11630 #CJK UNIFIED IDEOGRAPH + {0xC5B5, 0x8BFA}, //11631 #CJK UNIFIED IDEOGRAPH + {0xC5B6, 0x54E6}, //11632 #CJK UNIFIED IDEOGRAPH + {0xC5B7, 0x6B27}, //11633 #CJK UNIFIED IDEOGRAPH + {0xC5B8, 0x9E25}, //11634 #CJK UNIFIED IDEOGRAPH + {0xC5B9, 0x6BB4}, //11635 #CJK UNIFIED IDEOGRAPH + {0xC5BA, 0x85D5}, //11636 #CJK UNIFIED IDEOGRAPH + {0xC5BB, 0x5455}, //11637 #CJK UNIFIED IDEOGRAPH + {0xC5BC, 0x5076}, //11638 #CJK UNIFIED IDEOGRAPH + {0xC5BD, 0x6CA4}, //11639 #CJK UNIFIED IDEOGRAPH + {0xC5BE, 0x556A}, //11640 #CJK UNIFIED IDEOGRAPH + {0xC5BF, 0x8DB4}, //11641 #CJK UNIFIED IDEOGRAPH + {0xC5C0, 0x722C}, //11642 #CJK UNIFIED IDEOGRAPH + {0xC5C1, 0x5E15}, //11643 #CJK UNIFIED IDEOGRAPH + {0xC5C2, 0x6015}, //11644 #CJK UNIFIED IDEOGRAPH + {0xC5C3, 0x7436}, //11645 #CJK UNIFIED IDEOGRAPH + {0xC5C4, 0x62CD}, //11646 #CJK UNIFIED IDEOGRAPH + {0xC5C5, 0x6392}, //11647 #CJK UNIFIED IDEOGRAPH + {0xC5C6, 0x724C}, //11648 #CJK UNIFIED IDEOGRAPH + {0xC5C7, 0x5F98}, //11649 #CJK UNIFIED IDEOGRAPH + {0xC5C8, 0x6E43}, //11650 #CJK UNIFIED IDEOGRAPH + {0xC5C9, 0x6D3E}, //11651 #CJK UNIFIED IDEOGRAPH + {0xC5CA, 0x6500}, //11652 #CJK UNIFIED IDEOGRAPH + {0xC5CB, 0x6F58}, //11653 #CJK UNIFIED IDEOGRAPH + {0xC5CC, 0x76D8}, //11654 #CJK UNIFIED IDEOGRAPH + {0xC5CD, 0x78D0}, //11655 #CJK UNIFIED IDEOGRAPH + {0xC5CE, 0x76FC}, //11656 #CJK UNIFIED IDEOGRAPH + {0xC5CF, 0x7554}, //11657 #CJK UNIFIED IDEOGRAPH + {0xC5D0, 0x5224}, //11658 #CJK UNIFIED IDEOGRAPH + {0xC5D1, 0x53DB}, //11659 #CJK UNIFIED IDEOGRAPH + {0xC5D2, 0x4E53}, //11660 #CJK UNIFIED IDEOGRAPH + {0xC5D3, 0x5E9E}, //11661 #CJK UNIFIED IDEOGRAPH + {0xC5D4, 0x65C1}, //11662 #CJK UNIFIED IDEOGRAPH + {0xC5D5, 0x802A}, //11663 #CJK UNIFIED IDEOGRAPH + {0xC5D6, 0x80D6}, //11664 #CJK UNIFIED IDEOGRAPH + {0xC5D7, 0x629B}, //11665 #CJK UNIFIED IDEOGRAPH + {0xC5D8, 0x5486}, //11666 #CJK UNIFIED IDEOGRAPH + {0xC5D9, 0x5228}, //11667 #CJK UNIFIED IDEOGRAPH + {0xC5DA, 0x70AE}, //11668 #CJK UNIFIED IDEOGRAPH + {0xC5DB, 0x888D}, //11669 #CJK UNIFIED IDEOGRAPH + {0xC5DC, 0x8DD1}, //11670 #CJK UNIFIED IDEOGRAPH + {0xC5DD, 0x6CE1}, //11671 #CJK UNIFIED IDEOGRAPH + {0xC5DE, 0x5478}, //11672 #CJK UNIFIED IDEOGRAPH + {0xC5DF, 0x80DA}, //11673 #CJK UNIFIED IDEOGRAPH + {0xC5E0, 0x57F9}, //11674 #CJK UNIFIED IDEOGRAPH + {0xC5E1, 0x88F4}, //11675 #CJK UNIFIED IDEOGRAPH + {0xC5E2, 0x8D54}, //11676 #CJK UNIFIED IDEOGRAPH + {0xC5E3, 0x966A}, //11677 #CJK UNIFIED IDEOGRAPH + {0xC5E4, 0x914D}, //11678 #CJK UNIFIED IDEOGRAPH + {0xC5E5, 0x4F69}, //11679 #CJK UNIFIED IDEOGRAPH + {0xC5E6, 0x6C9B}, //11680 #CJK UNIFIED IDEOGRAPH + {0xC5E7, 0x55B7}, //11681 #CJK UNIFIED IDEOGRAPH + {0xC5E8, 0x76C6}, //11682 #CJK UNIFIED IDEOGRAPH + {0xC5E9, 0x7830}, //11683 #CJK UNIFIED IDEOGRAPH + {0xC5EA, 0x62A8}, //11684 #CJK UNIFIED IDEOGRAPH + {0xC5EB, 0x70F9}, //11685 #CJK UNIFIED IDEOGRAPH + {0xC5EC, 0x6F8E}, //11686 #CJK UNIFIED IDEOGRAPH + {0xC5ED, 0x5F6D}, //11687 #CJK UNIFIED IDEOGRAPH + {0xC5EE, 0x84EC}, //11688 #CJK UNIFIED IDEOGRAPH + {0xC5EF, 0x68DA}, //11689 #CJK UNIFIED IDEOGRAPH + {0xC5F0, 0x787C}, //11690 #CJK UNIFIED IDEOGRAPH + {0xC5F1, 0x7BF7}, //11691 #CJK UNIFIED IDEOGRAPH + {0xC5F2, 0x81A8}, //11692 #CJK UNIFIED IDEOGRAPH + {0xC5F3, 0x670B}, //11693 #CJK UNIFIED IDEOGRAPH + {0xC5F4, 0x9E4F}, //11694 #CJK UNIFIED IDEOGRAPH + {0xC5F5, 0x6367}, //11695 #CJK UNIFIED IDEOGRAPH + {0xC5F6, 0x78B0}, //11696 #CJK UNIFIED IDEOGRAPH + {0xC5F7, 0x576F}, //11697 #CJK UNIFIED IDEOGRAPH + {0xC5F8, 0x7812}, //11698 #CJK UNIFIED IDEOGRAPH + {0xC5F9, 0x9739}, //11699 #CJK UNIFIED IDEOGRAPH + {0xC5FA, 0x6279}, //11700 #CJK UNIFIED IDEOGRAPH + {0xC5FB, 0x62AB}, //11701 #CJK UNIFIED IDEOGRAPH + {0xC5FC, 0x5288}, //11702 #CJK UNIFIED IDEOGRAPH + {0xC5FD, 0x7435}, //11703 #CJK UNIFIED IDEOGRAPH + {0xC5FE, 0x6BD7}, //11704 #CJK UNIFIED IDEOGRAPH + {0xC640, 0x826A}, //11705 #CJK UNIFIED IDEOGRAPH + {0xC641, 0x826B}, //11706 #CJK UNIFIED IDEOGRAPH + {0xC642, 0x826C}, //11707 #CJK UNIFIED IDEOGRAPH + {0xC643, 0x826D}, //11708 #CJK UNIFIED IDEOGRAPH + {0xC644, 0x8271}, //11709 #CJK UNIFIED IDEOGRAPH + {0xC645, 0x8275}, //11710 #CJK UNIFIED IDEOGRAPH + {0xC646, 0x8276}, //11711 #CJK UNIFIED IDEOGRAPH + {0xC647, 0x8277}, //11712 #CJK UNIFIED IDEOGRAPH + {0xC648, 0x8278}, //11713 #CJK UNIFIED IDEOGRAPH + {0xC649, 0x827B}, //11714 #CJK UNIFIED IDEOGRAPH + {0xC64A, 0x827C}, //11715 #CJK UNIFIED IDEOGRAPH + {0xC64B, 0x8280}, //11716 #CJK UNIFIED IDEOGRAPH + {0xC64C, 0x8281}, //11717 #CJK UNIFIED IDEOGRAPH + {0xC64D, 0x8283}, //11718 #CJK UNIFIED IDEOGRAPH + {0xC64E, 0x8285}, //11719 #CJK UNIFIED IDEOGRAPH + {0xC64F, 0x8286}, //11720 #CJK UNIFIED IDEOGRAPH + {0xC650, 0x8287}, //11721 #CJK UNIFIED IDEOGRAPH + {0xC651, 0x8289}, //11722 #CJK UNIFIED IDEOGRAPH + {0xC652, 0x828C}, //11723 #CJK UNIFIED IDEOGRAPH + {0xC653, 0x8290}, //11724 #CJK UNIFIED IDEOGRAPH + {0xC654, 0x8293}, //11725 #CJK UNIFIED IDEOGRAPH + {0xC655, 0x8294}, //11726 #CJK UNIFIED IDEOGRAPH + {0xC656, 0x8295}, //11727 #CJK UNIFIED IDEOGRAPH + {0xC657, 0x8296}, //11728 #CJK UNIFIED IDEOGRAPH + {0xC658, 0x829A}, //11729 #CJK UNIFIED IDEOGRAPH + {0xC659, 0x829B}, //11730 #CJK UNIFIED IDEOGRAPH + {0xC65A, 0x829E}, //11731 #CJK UNIFIED IDEOGRAPH + {0xC65B, 0x82A0}, //11732 #CJK UNIFIED IDEOGRAPH + {0xC65C, 0x82A2}, //11733 #CJK UNIFIED IDEOGRAPH + {0xC65D, 0x82A3}, //11734 #CJK UNIFIED IDEOGRAPH + {0xC65E, 0x82A7}, //11735 #CJK UNIFIED IDEOGRAPH + {0xC65F, 0x82B2}, //11736 #CJK UNIFIED IDEOGRAPH + {0xC660, 0x82B5}, //11737 #CJK UNIFIED IDEOGRAPH + {0xC661, 0x82B6}, //11738 #CJK UNIFIED IDEOGRAPH + {0xC662, 0x82BA}, //11739 #CJK UNIFIED IDEOGRAPH + {0xC663, 0x82BB}, //11740 #CJK UNIFIED IDEOGRAPH + {0xC664, 0x82BC}, //11741 #CJK UNIFIED IDEOGRAPH + {0xC665, 0x82BF}, //11742 #CJK UNIFIED IDEOGRAPH + {0xC666, 0x82C0}, //11743 #CJK UNIFIED IDEOGRAPH + {0xC667, 0x82C2}, //11744 #CJK UNIFIED IDEOGRAPH + {0xC668, 0x82C3}, //11745 #CJK UNIFIED IDEOGRAPH + {0xC669, 0x82C5}, //11746 #CJK UNIFIED IDEOGRAPH + {0xC66A, 0x82C6}, //11747 #CJK UNIFIED IDEOGRAPH + {0xC66B, 0x82C9}, //11748 #CJK UNIFIED IDEOGRAPH + {0xC66C, 0x82D0}, //11749 #CJK UNIFIED IDEOGRAPH + {0xC66D, 0x82D6}, //11750 #CJK UNIFIED IDEOGRAPH + {0xC66E, 0x82D9}, //11751 #CJK UNIFIED IDEOGRAPH + {0xC66F, 0x82DA}, //11752 #CJK UNIFIED IDEOGRAPH + {0xC670, 0x82DD}, //11753 #CJK UNIFIED IDEOGRAPH + {0xC671, 0x82E2}, //11754 #CJK UNIFIED IDEOGRAPH + {0xC672, 0x82E7}, //11755 #CJK UNIFIED IDEOGRAPH + {0xC673, 0x82E8}, //11756 #CJK UNIFIED IDEOGRAPH + {0xC674, 0x82E9}, //11757 #CJK UNIFIED IDEOGRAPH + {0xC675, 0x82EA}, //11758 #CJK UNIFIED IDEOGRAPH + {0xC676, 0x82EC}, //11759 #CJK UNIFIED IDEOGRAPH + {0xC677, 0x82ED}, //11760 #CJK UNIFIED IDEOGRAPH + {0xC678, 0x82EE}, //11761 #CJK UNIFIED IDEOGRAPH + {0xC679, 0x82F0}, //11762 #CJK UNIFIED IDEOGRAPH + {0xC67A, 0x82F2}, //11763 #CJK UNIFIED IDEOGRAPH + {0xC67B, 0x82F3}, //11764 #CJK UNIFIED IDEOGRAPH + {0xC67C, 0x82F5}, //11765 #CJK UNIFIED IDEOGRAPH + {0xC67D, 0x82F6}, //11766 #CJK UNIFIED IDEOGRAPH + {0xC67E, 0x82F8}, //11767 #CJK UNIFIED IDEOGRAPH + {0xC680, 0x82FA}, //11768 #CJK UNIFIED IDEOGRAPH + {0xC681, 0x82FC}, //11769 #CJK UNIFIED IDEOGRAPH + {0xC682, 0x82FD}, //11770 #CJK UNIFIED IDEOGRAPH + {0xC683, 0x82FE}, //11771 #CJK UNIFIED IDEOGRAPH + {0xC684, 0x82FF}, //11772 #CJK UNIFIED IDEOGRAPH + {0xC685, 0x8300}, //11773 #CJK UNIFIED IDEOGRAPH + {0xC686, 0x830A}, //11774 #CJK UNIFIED IDEOGRAPH + {0xC687, 0x830B}, //11775 #CJK UNIFIED IDEOGRAPH + {0xC688, 0x830D}, //11776 #CJK UNIFIED IDEOGRAPH + {0xC689, 0x8310}, //11777 #CJK UNIFIED IDEOGRAPH + {0xC68A, 0x8312}, //11778 #CJK UNIFIED IDEOGRAPH + {0xC68B, 0x8313}, //11779 #CJK UNIFIED IDEOGRAPH + {0xC68C, 0x8316}, //11780 #CJK UNIFIED IDEOGRAPH + {0xC68D, 0x8318}, //11781 #CJK UNIFIED IDEOGRAPH + {0xC68E, 0x8319}, //11782 #CJK UNIFIED IDEOGRAPH + {0xC68F, 0x831D}, //11783 #CJK UNIFIED IDEOGRAPH + {0xC690, 0x831E}, //11784 #CJK UNIFIED IDEOGRAPH + {0xC691, 0x831F}, //11785 #CJK UNIFIED IDEOGRAPH + {0xC692, 0x8320}, //11786 #CJK UNIFIED IDEOGRAPH + {0xC693, 0x8321}, //11787 #CJK UNIFIED IDEOGRAPH + {0xC694, 0x8322}, //11788 #CJK UNIFIED IDEOGRAPH + {0xC695, 0x8323}, //11789 #CJK UNIFIED IDEOGRAPH + {0xC696, 0x8324}, //11790 #CJK UNIFIED IDEOGRAPH + {0xC697, 0x8325}, //11791 #CJK UNIFIED IDEOGRAPH + {0xC698, 0x8326}, //11792 #CJK UNIFIED IDEOGRAPH + {0xC699, 0x8329}, //11793 #CJK UNIFIED IDEOGRAPH + {0xC69A, 0x832A}, //11794 #CJK UNIFIED IDEOGRAPH + {0xC69B, 0x832E}, //11795 #CJK UNIFIED IDEOGRAPH + {0xC69C, 0x8330}, //11796 #CJK UNIFIED IDEOGRAPH + {0xC69D, 0x8332}, //11797 #CJK UNIFIED IDEOGRAPH + {0xC69E, 0x8337}, //11798 #CJK UNIFIED IDEOGRAPH + {0xC69F, 0x833B}, //11799 #CJK UNIFIED IDEOGRAPH + {0xC6A0, 0x833D}, //11800 #CJK UNIFIED IDEOGRAPH + {0xC6A1, 0x5564}, //11801 #CJK UNIFIED IDEOGRAPH + {0xC6A2, 0x813E}, //11802 #CJK UNIFIED IDEOGRAPH + {0xC6A3, 0x75B2}, //11803 #CJK UNIFIED IDEOGRAPH + {0xC6A4, 0x76AE}, //11804 #CJK UNIFIED IDEOGRAPH + {0xC6A5, 0x5339}, //11805 #CJK UNIFIED IDEOGRAPH + {0xC6A6, 0x75DE}, //11806 #CJK UNIFIED IDEOGRAPH + {0xC6A7, 0x50FB}, //11807 #CJK UNIFIED IDEOGRAPH + {0xC6A8, 0x5C41}, //11808 #CJK UNIFIED IDEOGRAPH + {0xC6A9, 0x8B6C}, //11809 #CJK UNIFIED IDEOGRAPH + {0xC6AA, 0x7BC7}, //11810 #CJK UNIFIED IDEOGRAPH + {0xC6AB, 0x504F}, //11811 #CJK UNIFIED IDEOGRAPH + {0xC6AC, 0x7247}, //11812 #CJK UNIFIED IDEOGRAPH + {0xC6AD, 0x9A97}, //11813 #CJK UNIFIED IDEOGRAPH + {0xC6AE, 0x98D8}, //11814 #CJK UNIFIED IDEOGRAPH + {0xC6AF, 0x6F02}, //11815 #CJK UNIFIED IDEOGRAPH + {0xC6B0, 0x74E2}, //11816 #CJK UNIFIED IDEOGRAPH + {0xC6B1, 0x7968}, //11817 #CJK UNIFIED IDEOGRAPH + {0xC6B2, 0x6487}, //11818 #CJK UNIFIED IDEOGRAPH + {0xC6B3, 0x77A5}, //11819 #CJK UNIFIED IDEOGRAPH + {0xC6B4, 0x62FC}, //11820 #CJK UNIFIED IDEOGRAPH + {0xC6B5, 0x9891}, //11821 #CJK UNIFIED IDEOGRAPH + {0xC6B6, 0x8D2B}, //11822 #CJK UNIFIED IDEOGRAPH + {0xC6B7, 0x54C1}, //11823 #CJK UNIFIED IDEOGRAPH + {0xC6B8, 0x8058}, //11824 #CJK UNIFIED IDEOGRAPH + {0xC6B9, 0x4E52}, //11825 #CJK UNIFIED IDEOGRAPH + {0xC6BA, 0x576A}, //11826 #CJK UNIFIED IDEOGRAPH + {0xC6BB, 0x82F9}, //11827 #CJK UNIFIED IDEOGRAPH + {0xC6BC, 0x840D}, //11828 #CJK UNIFIED IDEOGRAPH + {0xC6BD, 0x5E73}, //11829 #CJK UNIFIED IDEOGRAPH + {0xC6BE, 0x51ED}, //11830 #CJK UNIFIED IDEOGRAPH + {0xC6BF, 0x74F6}, //11831 #CJK UNIFIED IDEOGRAPH + {0xC6C0, 0x8BC4}, //11832 #CJK UNIFIED IDEOGRAPH + {0xC6C1, 0x5C4F}, //11833 #CJK UNIFIED IDEOGRAPH + {0xC6C2, 0x5761}, //11834 #CJK UNIFIED IDEOGRAPH + {0xC6C3, 0x6CFC}, //11835 #CJK UNIFIED IDEOGRAPH + {0xC6C4, 0x9887}, //11836 #CJK UNIFIED IDEOGRAPH + {0xC6C5, 0x5A46}, //11837 #CJK UNIFIED IDEOGRAPH + {0xC6C6, 0x7834}, //11838 #CJK UNIFIED IDEOGRAPH + {0xC6C7, 0x9B44}, //11839 #CJK UNIFIED IDEOGRAPH + {0xC6C8, 0x8FEB}, //11840 #CJK UNIFIED IDEOGRAPH + {0xC6C9, 0x7C95}, //11841 #CJK UNIFIED IDEOGRAPH + {0xC6CA, 0x5256}, //11842 #CJK UNIFIED IDEOGRAPH + {0xC6CB, 0x6251}, //11843 #CJK UNIFIED IDEOGRAPH + {0xC6CC, 0x94FA}, //11844 #CJK UNIFIED IDEOGRAPH + {0xC6CD, 0x4EC6}, //11845 #CJK UNIFIED IDEOGRAPH + {0xC6CE, 0x8386}, //11846 #CJK UNIFIED IDEOGRAPH + {0xC6CF, 0x8461}, //11847 #CJK UNIFIED IDEOGRAPH + {0xC6D0, 0x83E9}, //11848 #CJK UNIFIED IDEOGRAPH + {0xC6D1, 0x84B2}, //11849 #CJK UNIFIED IDEOGRAPH + {0xC6D2, 0x57D4}, //11850 #CJK UNIFIED IDEOGRAPH + {0xC6D3, 0x6734}, //11851 #CJK UNIFIED IDEOGRAPH + {0xC6D4, 0x5703}, //11852 #CJK UNIFIED IDEOGRAPH + {0xC6D5, 0x666E}, //11853 #CJK UNIFIED IDEOGRAPH + {0xC6D6, 0x6D66}, //11854 #CJK UNIFIED IDEOGRAPH + {0xC6D7, 0x8C31}, //11855 #CJK UNIFIED IDEOGRAPH + {0xC6D8, 0x66DD}, //11856 #CJK UNIFIED IDEOGRAPH + {0xC6D9, 0x7011}, //11857 #CJK UNIFIED IDEOGRAPH + {0xC6DA, 0x671F}, //11858 #CJK UNIFIED IDEOGRAPH + {0xC6DB, 0x6B3A}, //11859 #CJK UNIFIED IDEOGRAPH + {0xC6DC, 0x6816}, //11860 #CJK UNIFIED IDEOGRAPH + {0xC6DD, 0x621A}, //11861 #CJK UNIFIED IDEOGRAPH + {0xC6DE, 0x59BB}, //11862 #CJK UNIFIED IDEOGRAPH + {0xC6DF, 0x4E03}, //11863 #CJK UNIFIED IDEOGRAPH + {0xC6E0, 0x51C4}, //11864 #CJK UNIFIED IDEOGRAPH + {0xC6E1, 0x6F06}, //11865 #CJK UNIFIED IDEOGRAPH + {0xC6E2, 0x67D2}, //11866 #CJK UNIFIED IDEOGRAPH + {0xC6E3, 0x6C8F}, //11867 #CJK UNIFIED IDEOGRAPH + {0xC6E4, 0x5176}, //11868 #CJK UNIFIED IDEOGRAPH + {0xC6E5, 0x68CB}, //11869 #CJK UNIFIED IDEOGRAPH + {0xC6E6, 0x5947}, //11870 #CJK UNIFIED IDEOGRAPH + {0xC6E7, 0x6B67}, //11871 #CJK UNIFIED IDEOGRAPH + {0xC6E8, 0x7566}, //11872 #CJK UNIFIED IDEOGRAPH + {0xC6E9, 0x5D0E}, //11873 #CJK UNIFIED IDEOGRAPH + {0xC6EA, 0x8110}, //11874 #CJK UNIFIED IDEOGRAPH + {0xC6EB, 0x9F50}, //11875 #CJK UNIFIED IDEOGRAPH + {0xC6EC, 0x65D7}, //11876 #CJK UNIFIED IDEOGRAPH + {0xC6ED, 0x7948}, //11877 #CJK UNIFIED IDEOGRAPH + {0xC6EE, 0x7941}, //11878 #CJK UNIFIED IDEOGRAPH + {0xC6EF, 0x9A91}, //11879 #CJK UNIFIED IDEOGRAPH + {0xC6F0, 0x8D77}, //11880 #CJK UNIFIED IDEOGRAPH + {0xC6F1, 0x5C82}, //11881 #CJK UNIFIED IDEOGRAPH + {0xC6F2, 0x4E5E}, //11882 #CJK UNIFIED IDEOGRAPH + {0xC6F3, 0x4F01}, //11883 #CJK UNIFIED IDEOGRAPH + {0xC6F4, 0x542F}, //11884 #CJK UNIFIED IDEOGRAPH + {0xC6F5, 0x5951}, //11885 #CJK UNIFIED IDEOGRAPH + {0xC6F6, 0x780C}, //11886 #CJK UNIFIED IDEOGRAPH + {0xC6F7, 0x5668}, //11887 #CJK UNIFIED IDEOGRAPH + {0xC6F8, 0x6C14}, //11888 #CJK UNIFIED IDEOGRAPH + {0xC6F9, 0x8FC4}, //11889 #CJK UNIFIED IDEOGRAPH + {0xC6FA, 0x5F03}, //11890 #CJK UNIFIED IDEOGRAPH + {0xC6FB, 0x6C7D}, //11891 #CJK UNIFIED IDEOGRAPH + {0xC6FC, 0x6CE3}, //11892 #CJK UNIFIED IDEOGRAPH + {0xC6FD, 0x8BAB}, //11893 #CJK UNIFIED IDEOGRAPH + {0xC6FE, 0x6390}, //11894 #CJK UNIFIED IDEOGRAPH + {0xC740, 0x833E}, //11895 #CJK UNIFIED IDEOGRAPH + {0xC741, 0x833F}, //11896 #CJK UNIFIED IDEOGRAPH + {0xC742, 0x8341}, //11897 #CJK UNIFIED IDEOGRAPH + {0xC743, 0x8342}, //11898 #CJK UNIFIED IDEOGRAPH + {0xC744, 0x8344}, //11899 #CJK UNIFIED IDEOGRAPH + {0xC745, 0x8345}, //11900 #CJK UNIFIED IDEOGRAPH + {0xC746, 0x8348}, //11901 #CJK UNIFIED IDEOGRAPH + {0xC747, 0x834A}, //11902 #CJK UNIFIED IDEOGRAPH + {0xC748, 0x834B}, //11903 #CJK UNIFIED IDEOGRAPH + {0xC749, 0x834C}, //11904 #CJK UNIFIED IDEOGRAPH + {0xC74A, 0x834D}, //11905 #CJK UNIFIED IDEOGRAPH + {0xC74B, 0x834E}, //11906 #CJK UNIFIED IDEOGRAPH + {0xC74C, 0x8353}, //11907 #CJK UNIFIED IDEOGRAPH + {0xC74D, 0x8355}, //11908 #CJK UNIFIED IDEOGRAPH + {0xC74E, 0x8356}, //11909 #CJK UNIFIED IDEOGRAPH + {0xC74F, 0x8357}, //11910 #CJK UNIFIED IDEOGRAPH + {0xC750, 0x8358}, //11911 #CJK UNIFIED IDEOGRAPH + {0xC751, 0x8359}, //11912 #CJK UNIFIED IDEOGRAPH + {0xC752, 0x835D}, //11913 #CJK UNIFIED IDEOGRAPH + {0xC753, 0x8362}, //11914 #CJK UNIFIED IDEOGRAPH + {0xC754, 0x8370}, //11915 #CJK UNIFIED IDEOGRAPH + {0xC755, 0x8371}, //11916 #CJK UNIFIED IDEOGRAPH + {0xC756, 0x8372}, //11917 #CJK UNIFIED IDEOGRAPH + {0xC757, 0x8373}, //11918 #CJK UNIFIED IDEOGRAPH + {0xC758, 0x8374}, //11919 #CJK UNIFIED IDEOGRAPH + {0xC759, 0x8375}, //11920 #CJK UNIFIED IDEOGRAPH + {0xC75A, 0x8376}, //11921 #CJK UNIFIED IDEOGRAPH + {0xC75B, 0x8379}, //11922 #CJK UNIFIED IDEOGRAPH + {0xC75C, 0x837A}, //11923 #CJK UNIFIED IDEOGRAPH + {0xC75D, 0x837E}, //11924 #CJK UNIFIED IDEOGRAPH + {0xC75E, 0x837F}, //11925 #CJK UNIFIED IDEOGRAPH + {0xC75F, 0x8380}, //11926 #CJK UNIFIED IDEOGRAPH + {0xC760, 0x8381}, //11927 #CJK UNIFIED IDEOGRAPH + {0xC761, 0x8382}, //11928 #CJK UNIFIED IDEOGRAPH + {0xC762, 0x8383}, //11929 #CJK UNIFIED IDEOGRAPH + {0xC763, 0x8384}, //11930 #CJK UNIFIED IDEOGRAPH + {0xC764, 0x8387}, //11931 #CJK UNIFIED IDEOGRAPH + {0xC765, 0x8388}, //11932 #CJK UNIFIED IDEOGRAPH + {0xC766, 0x838A}, //11933 #CJK UNIFIED IDEOGRAPH + {0xC767, 0x838B}, //11934 #CJK UNIFIED IDEOGRAPH + {0xC768, 0x838C}, //11935 #CJK UNIFIED IDEOGRAPH + {0xC769, 0x838D}, //11936 #CJK UNIFIED IDEOGRAPH + {0xC76A, 0x838F}, //11937 #CJK UNIFIED IDEOGRAPH + {0xC76B, 0x8390}, //11938 #CJK UNIFIED IDEOGRAPH + {0xC76C, 0x8391}, //11939 #CJK UNIFIED IDEOGRAPH + {0xC76D, 0x8394}, //11940 #CJK UNIFIED IDEOGRAPH + {0xC76E, 0x8395}, //11941 #CJK UNIFIED IDEOGRAPH + {0xC76F, 0x8396}, //11942 #CJK UNIFIED IDEOGRAPH + {0xC770, 0x8397}, //11943 #CJK UNIFIED IDEOGRAPH + {0xC771, 0x8399}, //11944 #CJK UNIFIED IDEOGRAPH + {0xC772, 0x839A}, //11945 #CJK UNIFIED IDEOGRAPH + {0xC773, 0x839D}, //11946 #CJK UNIFIED IDEOGRAPH + {0xC774, 0x839F}, //11947 #CJK UNIFIED IDEOGRAPH + {0xC775, 0x83A1}, //11948 #CJK UNIFIED IDEOGRAPH + {0xC776, 0x83A2}, //11949 #CJK UNIFIED IDEOGRAPH + {0xC777, 0x83A3}, //11950 #CJK UNIFIED IDEOGRAPH + {0xC778, 0x83A4}, //11951 #CJK UNIFIED IDEOGRAPH + {0xC779, 0x83A5}, //11952 #CJK UNIFIED IDEOGRAPH + {0xC77A, 0x83A6}, //11953 #CJK UNIFIED IDEOGRAPH + {0xC77B, 0x83A7}, //11954 #CJK UNIFIED IDEOGRAPH + {0xC77C, 0x83AC}, //11955 #CJK UNIFIED IDEOGRAPH + {0xC77D, 0x83AD}, //11956 #CJK UNIFIED IDEOGRAPH + {0xC77E, 0x83AE}, //11957 #CJK UNIFIED IDEOGRAPH + {0xC780, 0x83AF}, //11958 #CJK UNIFIED IDEOGRAPH + {0xC781, 0x83B5}, //11959 #CJK UNIFIED IDEOGRAPH + {0xC782, 0x83BB}, //11960 #CJK UNIFIED IDEOGRAPH + {0xC783, 0x83BE}, //11961 #CJK UNIFIED IDEOGRAPH + {0xC784, 0x83BF}, //11962 #CJK UNIFIED IDEOGRAPH + {0xC785, 0x83C2}, //11963 #CJK UNIFIED IDEOGRAPH + {0xC786, 0x83C3}, //11964 #CJK UNIFIED IDEOGRAPH + {0xC787, 0x83C4}, //11965 #CJK UNIFIED IDEOGRAPH + {0xC788, 0x83C6}, //11966 #CJK UNIFIED IDEOGRAPH + {0xC789, 0x83C8}, //11967 #CJK UNIFIED IDEOGRAPH + {0xC78A, 0x83C9}, //11968 #CJK UNIFIED IDEOGRAPH + {0xC78B, 0x83CB}, //11969 #CJK UNIFIED IDEOGRAPH + {0xC78C, 0x83CD}, //11970 #CJK UNIFIED IDEOGRAPH + {0xC78D, 0x83CE}, //11971 #CJK UNIFIED IDEOGRAPH + {0xC78E, 0x83D0}, //11972 #CJK UNIFIED IDEOGRAPH + {0xC78F, 0x83D1}, //11973 #CJK UNIFIED IDEOGRAPH + {0xC790, 0x83D2}, //11974 #CJK UNIFIED IDEOGRAPH + {0xC791, 0x83D3}, //11975 #CJK UNIFIED IDEOGRAPH + {0xC792, 0x83D5}, //11976 #CJK UNIFIED IDEOGRAPH + {0xC793, 0x83D7}, //11977 #CJK UNIFIED IDEOGRAPH + {0xC794, 0x83D9}, //11978 #CJK UNIFIED IDEOGRAPH + {0xC795, 0x83DA}, //11979 #CJK UNIFIED IDEOGRAPH + {0xC796, 0x83DB}, //11980 #CJK UNIFIED IDEOGRAPH + {0xC797, 0x83DE}, //11981 #CJK UNIFIED IDEOGRAPH + {0xC798, 0x83E2}, //11982 #CJK UNIFIED IDEOGRAPH + {0xC799, 0x83E3}, //11983 #CJK UNIFIED IDEOGRAPH + {0xC79A, 0x83E4}, //11984 #CJK UNIFIED IDEOGRAPH + {0xC79B, 0x83E6}, //11985 #CJK UNIFIED IDEOGRAPH + {0xC79C, 0x83E7}, //11986 #CJK UNIFIED IDEOGRAPH + {0xC79D, 0x83E8}, //11987 #CJK UNIFIED IDEOGRAPH + {0xC79E, 0x83EB}, //11988 #CJK UNIFIED IDEOGRAPH + {0xC79F, 0x83EC}, //11989 #CJK UNIFIED IDEOGRAPH + {0xC7A0, 0x83ED}, //11990 #CJK UNIFIED IDEOGRAPH + {0xC7A1, 0x6070}, //11991 #CJK UNIFIED IDEOGRAPH + {0xC7A2, 0x6D3D}, //11992 #CJK UNIFIED IDEOGRAPH + {0xC7A3, 0x7275}, //11993 #CJK UNIFIED IDEOGRAPH + {0xC7A4, 0x6266}, //11994 #CJK UNIFIED IDEOGRAPH + {0xC7A5, 0x948E}, //11995 #CJK UNIFIED IDEOGRAPH + {0xC7A6, 0x94C5}, //11996 #CJK UNIFIED IDEOGRAPH + {0xC7A7, 0x5343}, //11997 #CJK UNIFIED IDEOGRAPH + {0xC7A8, 0x8FC1}, //11998 #CJK UNIFIED IDEOGRAPH + {0xC7A9, 0x7B7E}, //11999 #CJK UNIFIED IDEOGRAPH + {0xC7AA, 0x4EDF}, //12000 #CJK UNIFIED IDEOGRAPH + {0xC7AB, 0x8C26}, //12001 #CJK UNIFIED IDEOGRAPH + {0xC7AC, 0x4E7E}, //12002 #CJK UNIFIED IDEOGRAPH + {0xC7AD, 0x9ED4}, //12003 #CJK UNIFIED IDEOGRAPH + {0xC7AE, 0x94B1}, //12004 #CJK UNIFIED IDEOGRAPH + {0xC7AF, 0x94B3}, //12005 #CJK UNIFIED IDEOGRAPH + {0xC7B0, 0x524D}, //12006 #CJK UNIFIED IDEOGRAPH + {0xC7B1, 0x6F5C}, //12007 #CJK UNIFIED IDEOGRAPH + {0xC7B2, 0x9063}, //12008 #CJK UNIFIED IDEOGRAPH + {0xC7B3, 0x6D45}, //12009 #CJK UNIFIED IDEOGRAPH + {0xC7B4, 0x8C34}, //12010 #CJK UNIFIED IDEOGRAPH + {0xC7B5, 0x5811}, //12011 #CJK UNIFIED IDEOGRAPH + {0xC7B6, 0x5D4C}, //12012 #CJK UNIFIED IDEOGRAPH + {0xC7B7, 0x6B20}, //12013 #CJK UNIFIED IDEOGRAPH + {0xC7B8, 0x6B49}, //12014 #CJK UNIFIED IDEOGRAPH + {0xC7B9, 0x67AA}, //12015 #CJK UNIFIED IDEOGRAPH + {0xC7BA, 0x545B}, //12016 #CJK UNIFIED IDEOGRAPH + {0xC7BB, 0x8154}, //12017 #CJK UNIFIED IDEOGRAPH + {0xC7BC, 0x7F8C}, //12018 #CJK UNIFIED IDEOGRAPH + {0xC7BD, 0x5899}, //12019 #CJK UNIFIED IDEOGRAPH + {0xC7BE, 0x8537}, //12020 #CJK UNIFIED IDEOGRAPH + {0xC7BF, 0x5F3A}, //12021 #CJK UNIFIED IDEOGRAPH + {0xC7C0, 0x62A2}, //12022 #CJK UNIFIED IDEOGRAPH + {0xC7C1, 0x6A47}, //12023 #CJK UNIFIED IDEOGRAPH + {0xC7C2, 0x9539}, //12024 #CJK UNIFIED IDEOGRAPH + {0xC7C3, 0x6572}, //12025 #CJK UNIFIED IDEOGRAPH + {0xC7C4, 0x6084}, //12026 #CJK UNIFIED IDEOGRAPH + {0xC7C5, 0x6865}, //12027 #CJK UNIFIED IDEOGRAPH + {0xC7C6, 0x77A7}, //12028 #CJK UNIFIED IDEOGRAPH + {0xC7C7, 0x4E54}, //12029 #CJK UNIFIED IDEOGRAPH + {0xC7C8, 0x4FA8}, //12030 #CJK UNIFIED IDEOGRAPH + {0xC7C9, 0x5DE7}, //12031 #CJK UNIFIED IDEOGRAPH + {0xC7CA, 0x9798}, //12032 #CJK UNIFIED IDEOGRAPH + {0xC7CB, 0x64AC}, //12033 #CJK UNIFIED IDEOGRAPH + {0xC7CC, 0x7FD8}, //12034 #CJK UNIFIED IDEOGRAPH + {0xC7CD, 0x5CED}, //12035 #CJK UNIFIED IDEOGRAPH + {0xC7CE, 0x4FCF}, //12036 #CJK UNIFIED IDEOGRAPH + {0xC7CF, 0x7A8D}, //12037 #CJK UNIFIED IDEOGRAPH + {0xC7D0, 0x5207}, //12038 #CJK UNIFIED IDEOGRAPH + {0xC7D1, 0x8304}, //12039 #CJK UNIFIED IDEOGRAPH + {0xC7D2, 0x4E14}, //12040 #CJK UNIFIED IDEOGRAPH + {0xC7D3, 0x602F}, //12041 #CJK UNIFIED IDEOGRAPH + {0xC7D4, 0x7A83}, //12042 #CJK UNIFIED IDEOGRAPH + {0xC7D5, 0x94A6}, //12043 #CJK UNIFIED IDEOGRAPH + {0xC7D6, 0x4FB5}, //12044 #CJK UNIFIED IDEOGRAPH + {0xC7D7, 0x4EB2}, //12045 #CJK UNIFIED IDEOGRAPH + {0xC7D8, 0x79E6}, //12046 #CJK UNIFIED IDEOGRAPH + {0xC7D9, 0x7434}, //12047 #CJK UNIFIED IDEOGRAPH + {0xC7DA, 0x52E4}, //12048 #CJK UNIFIED IDEOGRAPH + {0xC7DB, 0x82B9}, //12049 #CJK UNIFIED IDEOGRAPH + {0xC7DC, 0x64D2}, //12050 #CJK UNIFIED IDEOGRAPH + {0xC7DD, 0x79BD}, //12051 #CJK UNIFIED IDEOGRAPH + {0xC7DE, 0x5BDD}, //12052 #CJK UNIFIED IDEOGRAPH + {0xC7DF, 0x6C81}, //12053 #CJK UNIFIED IDEOGRAPH + {0xC7E0, 0x9752}, //12054 #CJK UNIFIED IDEOGRAPH + {0xC7E1, 0x8F7B}, //12055 #CJK UNIFIED IDEOGRAPH + {0xC7E2, 0x6C22}, //12056 #CJK UNIFIED IDEOGRAPH + {0xC7E3, 0x503E}, //12057 #CJK UNIFIED IDEOGRAPH + {0xC7E4, 0x537F}, //12058 #CJK UNIFIED IDEOGRAPH + {0xC7E5, 0x6E05}, //12059 #CJK UNIFIED IDEOGRAPH + {0xC7E6, 0x64CE}, //12060 #CJK UNIFIED IDEOGRAPH + {0xC7E7, 0x6674}, //12061 #CJK UNIFIED IDEOGRAPH + {0xC7E8, 0x6C30}, //12062 #CJK UNIFIED IDEOGRAPH + {0xC7E9, 0x60C5}, //12063 #CJK UNIFIED IDEOGRAPH + {0xC7EA, 0x9877}, //12064 #CJK UNIFIED IDEOGRAPH + {0xC7EB, 0x8BF7}, //12065 #CJK UNIFIED IDEOGRAPH + {0xC7EC, 0x5E86}, //12066 #CJK UNIFIED IDEOGRAPH + {0xC7ED, 0x743C}, //12067 #CJK UNIFIED IDEOGRAPH + {0xC7EE, 0x7A77}, //12068 #CJK UNIFIED IDEOGRAPH + {0xC7EF, 0x79CB}, //12069 #CJK UNIFIED IDEOGRAPH + {0xC7F0, 0x4E18}, //12070 #CJK UNIFIED IDEOGRAPH + {0xC7F1, 0x90B1}, //12071 #CJK UNIFIED IDEOGRAPH + {0xC7F2, 0x7403}, //12072 #CJK UNIFIED IDEOGRAPH + {0xC7F3, 0x6C42}, //12073 #CJK UNIFIED IDEOGRAPH + {0xC7F4, 0x56DA}, //12074 #CJK UNIFIED IDEOGRAPH + {0xC7F5, 0x914B}, //12075 #CJK UNIFIED IDEOGRAPH + {0xC7F6, 0x6CC5}, //12076 #CJK UNIFIED IDEOGRAPH + {0xC7F7, 0x8D8B}, //12077 #CJK UNIFIED IDEOGRAPH + {0xC7F8, 0x533A}, //12078 #CJK UNIFIED IDEOGRAPH + {0xC7F9, 0x86C6}, //12079 #CJK UNIFIED IDEOGRAPH + {0xC7FA, 0x66F2}, //12080 #CJK UNIFIED IDEOGRAPH + {0xC7FB, 0x8EAF}, //12081 #CJK UNIFIED IDEOGRAPH + {0xC7FC, 0x5C48}, //12082 #CJK UNIFIED IDEOGRAPH + {0xC7FD, 0x9A71}, //12083 #CJK UNIFIED IDEOGRAPH + {0xC7FE, 0x6E20}, //12084 #CJK UNIFIED IDEOGRAPH + {0xC840, 0x83EE}, //12085 #CJK UNIFIED IDEOGRAPH + {0xC841, 0x83EF}, //12086 #CJK UNIFIED IDEOGRAPH + {0xC842, 0x83F3}, //12087 #CJK UNIFIED IDEOGRAPH + {0xC843, 0x83F4}, //12088 #CJK UNIFIED IDEOGRAPH + {0xC844, 0x83F5}, //12089 #CJK UNIFIED IDEOGRAPH + {0xC845, 0x83F6}, //12090 #CJK UNIFIED IDEOGRAPH + {0xC846, 0x83F7}, //12091 #CJK UNIFIED IDEOGRAPH + {0xC847, 0x83FA}, //12092 #CJK UNIFIED IDEOGRAPH + {0xC848, 0x83FB}, //12093 #CJK UNIFIED IDEOGRAPH + {0xC849, 0x83FC}, //12094 #CJK UNIFIED IDEOGRAPH + {0xC84A, 0x83FE}, //12095 #CJK UNIFIED IDEOGRAPH + {0xC84B, 0x83FF}, //12096 #CJK UNIFIED IDEOGRAPH + {0xC84C, 0x8400}, //12097 #CJK UNIFIED IDEOGRAPH + {0xC84D, 0x8402}, //12098 #CJK UNIFIED IDEOGRAPH + {0xC84E, 0x8405}, //12099 #CJK UNIFIED IDEOGRAPH + {0xC84F, 0x8407}, //12100 #CJK UNIFIED IDEOGRAPH + {0xC850, 0x8408}, //12101 #CJK UNIFIED IDEOGRAPH + {0xC851, 0x8409}, //12102 #CJK UNIFIED IDEOGRAPH + {0xC852, 0x840A}, //12103 #CJK UNIFIED IDEOGRAPH + {0xC853, 0x8410}, //12104 #CJK UNIFIED IDEOGRAPH + {0xC854, 0x8412}, //12105 #CJK UNIFIED IDEOGRAPH + {0xC855, 0x8413}, //12106 #CJK UNIFIED IDEOGRAPH + {0xC856, 0x8414}, //12107 #CJK UNIFIED IDEOGRAPH + {0xC857, 0x8415}, //12108 #CJK UNIFIED IDEOGRAPH + {0xC858, 0x8416}, //12109 #CJK UNIFIED IDEOGRAPH + {0xC859, 0x8417}, //12110 #CJK UNIFIED IDEOGRAPH + {0xC85A, 0x8419}, //12111 #CJK UNIFIED IDEOGRAPH + {0xC85B, 0x841A}, //12112 #CJK UNIFIED IDEOGRAPH + {0xC85C, 0x841B}, //12113 #CJK UNIFIED IDEOGRAPH + {0xC85D, 0x841E}, //12114 #CJK UNIFIED IDEOGRAPH + {0xC85E, 0x841F}, //12115 #CJK UNIFIED IDEOGRAPH + {0xC85F, 0x8420}, //12116 #CJK UNIFIED IDEOGRAPH + {0xC860, 0x8421}, //12117 #CJK UNIFIED IDEOGRAPH + {0xC861, 0x8422}, //12118 #CJK UNIFIED IDEOGRAPH + {0xC862, 0x8423}, //12119 #CJK UNIFIED IDEOGRAPH + {0xC863, 0x8429}, //12120 #CJK UNIFIED IDEOGRAPH + {0xC864, 0x842A}, //12121 #CJK UNIFIED IDEOGRAPH + {0xC865, 0x842B}, //12122 #CJK UNIFIED IDEOGRAPH + {0xC866, 0x842C}, //12123 #CJK UNIFIED IDEOGRAPH + {0xC867, 0x842D}, //12124 #CJK UNIFIED IDEOGRAPH + {0xC868, 0x842E}, //12125 #CJK UNIFIED IDEOGRAPH + {0xC869, 0x842F}, //12126 #CJK UNIFIED IDEOGRAPH + {0xC86A, 0x8430}, //12127 #CJK UNIFIED IDEOGRAPH + {0xC86B, 0x8432}, //12128 #CJK UNIFIED IDEOGRAPH + {0xC86C, 0x8433}, //12129 #CJK UNIFIED IDEOGRAPH + {0xC86D, 0x8434}, //12130 #CJK UNIFIED IDEOGRAPH + {0xC86E, 0x8435}, //12131 #CJK UNIFIED IDEOGRAPH + {0xC86F, 0x8436}, //12132 #CJK UNIFIED IDEOGRAPH + {0xC870, 0x8437}, //12133 #CJK UNIFIED IDEOGRAPH + {0xC871, 0x8439}, //12134 #CJK UNIFIED IDEOGRAPH + {0xC872, 0x843A}, //12135 #CJK UNIFIED IDEOGRAPH + {0xC873, 0x843B}, //12136 #CJK UNIFIED IDEOGRAPH + {0xC874, 0x843E}, //12137 #CJK UNIFIED IDEOGRAPH + {0xC875, 0x843F}, //12138 #CJK UNIFIED IDEOGRAPH + {0xC876, 0x8440}, //12139 #CJK UNIFIED IDEOGRAPH + {0xC877, 0x8441}, //12140 #CJK UNIFIED IDEOGRAPH + {0xC878, 0x8442}, //12141 #CJK UNIFIED IDEOGRAPH + {0xC879, 0x8443}, //12142 #CJK UNIFIED IDEOGRAPH + {0xC87A, 0x8444}, //12143 #CJK UNIFIED IDEOGRAPH + {0xC87B, 0x8445}, //12144 #CJK UNIFIED IDEOGRAPH + {0xC87C, 0x8447}, //12145 #CJK UNIFIED IDEOGRAPH + {0xC87D, 0x8448}, //12146 #CJK UNIFIED IDEOGRAPH + {0xC87E, 0x8449}, //12147 #CJK UNIFIED IDEOGRAPH + {0xC880, 0x844A}, //12148 #CJK UNIFIED IDEOGRAPH + {0xC881, 0x844B}, //12149 #CJK UNIFIED IDEOGRAPH + {0xC882, 0x844C}, //12150 #CJK UNIFIED IDEOGRAPH + {0xC883, 0x844D}, //12151 #CJK UNIFIED IDEOGRAPH + {0xC884, 0x844E}, //12152 #CJK UNIFIED IDEOGRAPH + {0xC885, 0x844F}, //12153 #CJK UNIFIED IDEOGRAPH + {0xC886, 0x8450}, //12154 #CJK UNIFIED IDEOGRAPH + {0xC887, 0x8452}, //12155 #CJK UNIFIED IDEOGRAPH + {0xC888, 0x8453}, //12156 #CJK UNIFIED IDEOGRAPH + {0xC889, 0x8454}, //12157 #CJK UNIFIED IDEOGRAPH + {0xC88A, 0x8455}, //12158 #CJK UNIFIED IDEOGRAPH + {0xC88B, 0x8456}, //12159 #CJK UNIFIED IDEOGRAPH + {0xC88C, 0x8458}, //12160 #CJK UNIFIED IDEOGRAPH + {0xC88D, 0x845D}, //12161 #CJK UNIFIED IDEOGRAPH + {0xC88E, 0x845E}, //12162 #CJK UNIFIED IDEOGRAPH + {0xC88F, 0x845F}, //12163 #CJK UNIFIED IDEOGRAPH + {0xC890, 0x8460}, //12164 #CJK UNIFIED IDEOGRAPH + {0xC891, 0x8462}, //12165 #CJK UNIFIED IDEOGRAPH + {0xC892, 0x8464}, //12166 #CJK UNIFIED IDEOGRAPH + {0xC893, 0x8465}, //12167 #CJK UNIFIED IDEOGRAPH + {0xC894, 0x8466}, //12168 #CJK UNIFIED IDEOGRAPH + {0xC895, 0x8467}, //12169 #CJK UNIFIED IDEOGRAPH + {0xC896, 0x8468}, //12170 #CJK UNIFIED IDEOGRAPH + {0xC897, 0x846A}, //12171 #CJK UNIFIED IDEOGRAPH + {0xC898, 0x846E}, //12172 #CJK UNIFIED IDEOGRAPH + {0xC899, 0x846F}, //12173 #CJK UNIFIED IDEOGRAPH + {0xC89A, 0x8470}, //12174 #CJK UNIFIED IDEOGRAPH + {0xC89B, 0x8472}, //12175 #CJK UNIFIED IDEOGRAPH + {0xC89C, 0x8474}, //12176 #CJK UNIFIED IDEOGRAPH + {0xC89D, 0x8477}, //12177 #CJK UNIFIED IDEOGRAPH + {0xC89E, 0x8479}, //12178 #CJK UNIFIED IDEOGRAPH + {0xC89F, 0x847B}, //12179 #CJK UNIFIED IDEOGRAPH + {0xC8A0, 0x847C}, //12180 #CJK UNIFIED IDEOGRAPH + {0xC8A1, 0x53D6}, //12181 #CJK UNIFIED IDEOGRAPH + {0xC8A2, 0x5A36}, //12182 #CJK UNIFIED IDEOGRAPH + {0xC8A3, 0x9F8B}, //12183 #CJK UNIFIED IDEOGRAPH + {0xC8A4, 0x8DA3}, //12184 #CJK UNIFIED IDEOGRAPH + {0xC8A5, 0x53BB}, //12185 #CJK UNIFIED IDEOGRAPH + {0xC8A6, 0x5708}, //12186 #CJK UNIFIED IDEOGRAPH + {0xC8A7, 0x98A7}, //12187 #CJK UNIFIED IDEOGRAPH + {0xC8A8, 0x6743}, //12188 #CJK UNIFIED IDEOGRAPH + {0xC8A9, 0x919B}, //12189 #CJK UNIFIED IDEOGRAPH + {0xC8AA, 0x6CC9}, //12190 #CJK UNIFIED IDEOGRAPH + {0xC8AB, 0x5168}, //12191 #CJK UNIFIED IDEOGRAPH + {0xC8AC, 0x75CA}, //12192 #CJK UNIFIED IDEOGRAPH + {0xC8AD, 0x62F3}, //12193 #CJK UNIFIED IDEOGRAPH + {0xC8AE, 0x72AC}, //12194 #CJK UNIFIED IDEOGRAPH + {0xC8AF, 0x5238}, //12195 #CJK UNIFIED IDEOGRAPH + {0xC8B0, 0x529D}, //12196 #CJK UNIFIED IDEOGRAPH + {0xC8B1, 0x7F3A}, //12197 #CJK UNIFIED IDEOGRAPH + {0xC8B2, 0x7094}, //12198 #CJK UNIFIED IDEOGRAPH + {0xC8B3, 0x7638}, //12199 #CJK UNIFIED IDEOGRAPH + {0xC8B4, 0x5374}, //12200 #CJK UNIFIED IDEOGRAPH + {0xC8B5, 0x9E4A}, //12201 #CJK UNIFIED IDEOGRAPH + {0xC8B6, 0x69B7}, //12202 #CJK UNIFIED IDEOGRAPH + {0xC8B7, 0x786E}, //12203 #CJK UNIFIED IDEOGRAPH + {0xC8B8, 0x96C0}, //12204 #CJK UNIFIED IDEOGRAPH + {0xC8B9, 0x88D9}, //12205 #CJK UNIFIED IDEOGRAPH + {0xC8BA, 0x7FA4}, //12206 #CJK UNIFIED IDEOGRAPH + {0xC8BB, 0x7136}, //12207 #CJK UNIFIED IDEOGRAPH + {0xC8BC, 0x71C3}, //12208 #CJK UNIFIED IDEOGRAPH + {0xC8BD, 0x5189}, //12209 #CJK UNIFIED IDEOGRAPH + {0xC8BE, 0x67D3}, //12210 #CJK UNIFIED IDEOGRAPH + {0xC8BF, 0x74E4}, //12211 #CJK UNIFIED IDEOGRAPH + {0xC8C0, 0x58E4}, //12212 #CJK UNIFIED IDEOGRAPH + {0xC8C1, 0x6518}, //12213 #CJK UNIFIED IDEOGRAPH + {0xC8C2, 0x56B7}, //12214 #CJK UNIFIED IDEOGRAPH + {0xC8C3, 0x8BA9}, //12215 #CJK UNIFIED IDEOGRAPH + {0xC8C4, 0x9976}, //12216 #CJK UNIFIED IDEOGRAPH + {0xC8C5, 0x6270}, //12217 #CJK UNIFIED IDEOGRAPH + {0xC8C6, 0x7ED5}, //12218 #CJK UNIFIED IDEOGRAPH + {0xC8C7, 0x60F9}, //12219 #CJK UNIFIED IDEOGRAPH + {0xC8C8, 0x70ED}, //12220 #CJK UNIFIED IDEOGRAPH + {0xC8C9, 0x58EC}, //12221 #CJK UNIFIED IDEOGRAPH + {0xC8CA, 0x4EC1}, //12222 #CJK UNIFIED IDEOGRAPH + {0xC8CB, 0x4EBA}, //12223 #CJK UNIFIED IDEOGRAPH + {0xC8CC, 0x5FCD}, //12224 #CJK UNIFIED IDEOGRAPH + {0xC8CD, 0x97E7}, //12225 #CJK UNIFIED IDEOGRAPH + {0xC8CE, 0x4EFB}, //12226 #CJK UNIFIED IDEOGRAPH + {0xC8CF, 0x8BA4}, //12227 #CJK UNIFIED IDEOGRAPH + {0xC8D0, 0x5203}, //12228 #CJK UNIFIED IDEOGRAPH + {0xC8D1, 0x598A}, //12229 #CJK UNIFIED IDEOGRAPH + {0xC8D2, 0x7EAB}, //12230 #CJK UNIFIED IDEOGRAPH + {0xC8D3, 0x6254}, //12231 #CJK UNIFIED IDEOGRAPH + {0xC8D4, 0x4ECD}, //12232 #CJK UNIFIED IDEOGRAPH + {0xC8D5, 0x65E5}, //12233 #CJK UNIFIED IDEOGRAPH + {0xC8D6, 0x620E}, //12234 #CJK UNIFIED IDEOGRAPH + {0xC8D7, 0x8338}, //12235 #CJK UNIFIED IDEOGRAPH + {0xC8D8, 0x84C9}, //12236 #CJK UNIFIED IDEOGRAPH + {0xC8D9, 0x8363}, //12237 #CJK UNIFIED IDEOGRAPH + {0xC8DA, 0x878D}, //12238 #CJK UNIFIED IDEOGRAPH + {0xC8DB, 0x7194}, //12239 #CJK UNIFIED IDEOGRAPH + {0xC8DC, 0x6EB6}, //12240 #CJK UNIFIED IDEOGRAPH + {0xC8DD, 0x5BB9}, //12241 #CJK UNIFIED IDEOGRAPH + {0xC8DE, 0x7ED2}, //12242 #CJK UNIFIED IDEOGRAPH + {0xC8DF, 0x5197}, //12243 #CJK UNIFIED IDEOGRAPH + {0xC8E0, 0x63C9}, //12244 #CJK UNIFIED IDEOGRAPH + {0xC8E1, 0x67D4}, //12245 #CJK UNIFIED IDEOGRAPH + {0xC8E2, 0x8089}, //12246 #CJK UNIFIED IDEOGRAPH + {0xC8E3, 0x8339}, //12247 #CJK UNIFIED IDEOGRAPH + {0xC8E4, 0x8815}, //12248 #CJK UNIFIED IDEOGRAPH + {0xC8E5, 0x5112}, //12249 #CJK UNIFIED IDEOGRAPH + {0xC8E6, 0x5B7A}, //12250 #CJK UNIFIED IDEOGRAPH + {0xC8E7, 0x5982}, //12251 #CJK UNIFIED IDEOGRAPH + {0xC8E8, 0x8FB1}, //12252 #CJK UNIFIED IDEOGRAPH + {0xC8E9, 0x4E73}, //12253 #CJK UNIFIED IDEOGRAPH + {0xC8EA, 0x6C5D}, //12254 #CJK UNIFIED IDEOGRAPH + {0xC8EB, 0x5165}, //12255 #CJK UNIFIED IDEOGRAPH + {0xC8EC, 0x8925}, //12256 #CJK UNIFIED IDEOGRAPH + {0xC8ED, 0x8F6F}, //12257 #CJK UNIFIED IDEOGRAPH + {0xC8EE, 0x962E}, //12258 #CJK UNIFIED IDEOGRAPH + {0xC8EF, 0x854A}, //12259 #CJK UNIFIED IDEOGRAPH + {0xC8F0, 0x745E}, //12260 #CJK UNIFIED IDEOGRAPH + {0xC8F1, 0x9510}, //12261 #CJK UNIFIED IDEOGRAPH + {0xC8F2, 0x95F0}, //12262 #CJK UNIFIED IDEOGRAPH + {0xC8F3, 0x6DA6}, //12263 #CJK UNIFIED IDEOGRAPH + {0xC8F4, 0x82E5}, //12264 #CJK UNIFIED IDEOGRAPH + {0xC8F5, 0x5F31}, //12265 #CJK UNIFIED IDEOGRAPH + {0xC8F6, 0x6492}, //12266 #CJK UNIFIED IDEOGRAPH + {0xC8F7, 0x6D12}, //12267 #CJK UNIFIED IDEOGRAPH + {0xC8F8, 0x8428}, //12268 #CJK UNIFIED IDEOGRAPH + {0xC8F9, 0x816E}, //12269 #CJK UNIFIED IDEOGRAPH + {0xC8FA, 0x9CC3}, //12270 #CJK UNIFIED IDEOGRAPH + {0xC8FB, 0x585E}, //12271 #CJK UNIFIED IDEOGRAPH + {0xC8FC, 0x8D5B}, //12272 #CJK UNIFIED IDEOGRAPH + {0xC8FD, 0x4E09}, //12273 #CJK UNIFIED IDEOGRAPH + {0xC8FE, 0x53C1}, //12274 #CJK UNIFIED IDEOGRAPH + {0xC940, 0x847D}, //12275 #CJK UNIFIED IDEOGRAPH + {0xC941, 0x847E}, //12276 #CJK UNIFIED IDEOGRAPH + {0xC942, 0x847F}, //12277 #CJK UNIFIED IDEOGRAPH + {0xC943, 0x8480}, //12278 #CJK UNIFIED IDEOGRAPH + {0xC944, 0x8481}, //12279 #CJK UNIFIED IDEOGRAPH + {0xC945, 0x8483}, //12280 #CJK UNIFIED IDEOGRAPH + {0xC946, 0x8484}, //12281 #CJK UNIFIED IDEOGRAPH + {0xC947, 0x8485}, //12282 #CJK UNIFIED IDEOGRAPH + {0xC948, 0x8486}, //12283 #CJK UNIFIED IDEOGRAPH + {0xC949, 0x848A}, //12284 #CJK UNIFIED IDEOGRAPH + {0xC94A, 0x848D}, //12285 #CJK UNIFIED IDEOGRAPH + {0xC94B, 0x848F}, //12286 #CJK UNIFIED IDEOGRAPH + {0xC94C, 0x8490}, //12287 #CJK UNIFIED IDEOGRAPH + {0xC94D, 0x8491}, //12288 #CJK UNIFIED IDEOGRAPH + {0xC94E, 0x8492}, //12289 #CJK UNIFIED IDEOGRAPH + {0xC94F, 0x8493}, //12290 #CJK UNIFIED IDEOGRAPH + {0xC950, 0x8494}, //12291 #CJK UNIFIED IDEOGRAPH + {0xC951, 0x8495}, //12292 #CJK UNIFIED IDEOGRAPH + {0xC952, 0x8496}, //12293 #CJK UNIFIED IDEOGRAPH + {0xC953, 0x8498}, //12294 #CJK UNIFIED IDEOGRAPH + {0xC954, 0x849A}, //12295 #CJK UNIFIED IDEOGRAPH + {0xC955, 0x849B}, //12296 #CJK UNIFIED IDEOGRAPH + {0xC956, 0x849D}, //12297 #CJK UNIFIED IDEOGRAPH + {0xC957, 0x849E}, //12298 #CJK UNIFIED IDEOGRAPH + {0xC958, 0x849F}, //12299 #CJK UNIFIED IDEOGRAPH + {0xC959, 0x84A0}, //12300 #CJK UNIFIED IDEOGRAPH + {0xC95A, 0x84A2}, //12301 #CJK UNIFIED IDEOGRAPH + {0xC95B, 0x84A3}, //12302 #CJK UNIFIED IDEOGRAPH + {0xC95C, 0x84A4}, //12303 #CJK UNIFIED IDEOGRAPH + {0xC95D, 0x84A5}, //12304 #CJK UNIFIED IDEOGRAPH + {0xC95E, 0x84A6}, //12305 #CJK UNIFIED IDEOGRAPH + {0xC95F, 0x84A7}, //12306 #CJK UNIFIED IDEOGRAPH + {0xC960, 0x84A8}, //12307 #CJK UNIFIED IDEOGRAPH + {0xC961, 0x84A9}, //12308 #CJK UNIFIED IDEOGRAPH + {0xC962, 0x84AA}, //12309 #CJK UNIFIED IDEOGRAPH + {0xC963, 0x84AB}, //12310 #CJK UNIFIED IDEOGRAPH + {0xC964, 0x84AC}, //12311 #CJK UNIFIED IDEOGRAPH + {0xC965, 0x84AD}, //12312 #CJK UNIFIED IDEOGRAPH + {0xC966, 0x84AE}, //12313 #CJK UNIFIED IDEOGRAPH + {0xC967, 0x84B0}, //12314 #CJK UNIFIED IDEOGRAPH + {0xC968, 0x84B1}, //12315 #CJK UNIFIED IDEOGRAPH + {0xC969, 0x84B3}, //12316 #CJK UNIFIED IDEOGRAPH + {0xC96A, 0x84B5}, //12317 #CJK UNIFIED IDEOGRAPH + {0xC96B, 0x84B6}, //12318 #CJK UNIFIED IDEOGRAPH + {0xC96C, 0x84B7}, //12319 #CJK UNIFIED IDEOGRAPH + {0xC96D, 0x84BB}, //12320 #CJK UNIFIED IDEOGRAPH + {0xC96E, 0x84BC}, //12321 #CJK UNIFIED IDEOGRAPH + {0xC96F, 0x84BE}, //12322 #CJK UNIFIED IDEOGRAPH + {0xC970, 0x84C0}, //12323 #CJK UNIFIED IDEOGRAPH + {0xC971, 0x84C2}, //12324 #CJK UNIFIED IDEOGRAPH + {0xC972, 0x84C3}, //12325 #CJK UNIFIED IDEOGRAPH + {0xC973, 0x84C5}, //12326 #CJK UNIFIED IDEOGRAPH + {0xC974, 0x84C6}, //12327 #CJK UNIFIED IDEOGRAPH + {0xC975, 0x84C7}, //12328 #CJK UNIFIED IDEOGRAPH + {0xC976, 0x84C8}, //12329 #CJK UNIFIED IDEOGRAPH + {0xC977, 0x84CB}, //12330 #CJK UNIFIED IDEOGRAPH + {0xC978, 0x84CC}, //12331 #CJK UNIFIED IDEOGRAPH + {0xC979, 0x84CE}, //12332 #CJK UNIFIED IDEOGRAPH + {0xC97A, 0x84CF}, //12333 #CJK UNIFIED IDEOGRAPH + {0xC97B, 0x84D2}, //12334 #CJK UNIFIED IDEOGRAPH + {0xC97C, 0x84D4}, //12335 #CJK UNIFIED IDEOGRAPH + {0xC97D, 0x84D5}, //12336 #CJK UNIFIED IDEOGRAPH + {0xC97E, 0x84D7}, //12337 #CJK UNIFIED IDEOGRAPH + {0xC980, 0x84D8}, //12338 #CJK UNIFIED IDEOGRAPH + {0xC981, 0x84D9}, //12339 #CJK UNIFIED IDEOGRAPH + {0xC982, 0x84DA}, //12340 #CJK UNIFIED IDEOGRAPH + {0xC983, 0x84DB}, //12341 #CJK UNIFIED IDEOGRAPH + {0xC984, 0x84DC}, //12342 #CJK UNIFIED IDEOGRAPH + {0xC985, 0x84DE}, //12343 #CJK UNIFIED IDEOGRAPH + {0xC986, 0x84E1}, //12344 #CJK UNIFIED IDEOGRAPH + {0xC987, 0x84E2}, //12345 #CJK UNIFIED IDEOGRAPH + {0xC988, 0x84E4}, //12346 #CJK UNIFIED IDEOGRAPH + {0xC989, 0x84E7}, //12347 #CJK UNIFIED IDEOGRAPH + {0xC98A, 0x84E8}, //12348 #CJK UNIFIED IDEOGRAPH + {0xC98B, 0x84E9}, //12349 #CJK UNIFIED IDEOGRAPH + {0xC98C, 0x84EA}, //12350 #CJK UNIFIED IDEOGRAPH + {0xC98D, 0x84EB}, //12351 #CJK UNIFIED IDEOGRAPH + {0xC98E, 0x84ED}, //12352 #CJK UNIFIED IDEOGRAPH + {0xC98F, 0x84EE}, //12353 #CJK UNIFIED IDEOGRAPH + {0xC990, 0x84EF}, //12354 #CJK UNIFIED IDEOGRAPH + {0xC991, 0x84F1}, //12355 #CJK UNIFIED IDEOGRAPH + {0xC992, 0x84F2}, //12356 #CJK UNIFIED IDEOGRAPH + {0xC993, 0x84F3}, //12357 #CJK UNIFIED IDEOGRAPH + {0xC994, 0x84F4}, //12358 #CJK UNIFIED IDEOGRAPH + {0xC995, 0x84F5}, //12359 #CJK UNIFIED IDEOGRAPH + {0xC996, 0x84F6}, //12360 #CJK UNIFIED IDEOGRAPH + {0xC997, 0x84F7}, //12361 #CJK UNIFIED IDEOGRAPH + {0xC998, 0x84F8}, //12362 #CJK UNIFIED IDEOGRAPH + {0xC999, 0x84F9}, //12363 #CJK UNIFIED IDEOGRAPH + {0xC99A, 0x84FA}, //12364 #CJK UNIFIED IDEOGRAPH + {0xC99B, 0x84FB}, //12365 #CJK UNIFIED IDEOGRAPH + {0xC99C, 0x84FD}, //12366 #CJK UNIFIED IDEOGRAPH + {0xC99D, 0x84FE}, //12367 #CJK UNIFIED IDEOGRAPH + {0xC99E, 0x8500}, //12368 #CJK UNIFIED IDEOGRAPH + {0xC99F, 0x8501}, //12369 #CJK UNIFIED IDEOGRAPH + {0xC9A0, 0x8502}, //12370 #CJK UNIFIED IDEOGRAPH + {0xC9A1, 0x4F1E}, //12371 #CJK UNIFIED IDEOGRAPH + {0xC9A2, 0x6563}, //12372 #CJK UNIFIED IDEOGRAPH + {0xC9A3, 0x6851}, //12373 #CJK UNIFIED IDEOGRAPH + {0xC9A4, 0x55D3}, //12374 #CJK UNIFIED IDEOGRAPH + {0xC9A5, 0x4E27}, //12375 #CJK UNIFIED IDEOGRAPH + {0xC9A6, 0x6414}, //12376 #CJK UNIFIED IDEOGRAPH + {0xC9A7, 0x9A9A}, //12377 #CJK UNIFIED IDEOGRAPH + {0xC9A8, 0x626B}, //12378 #CJK UNIFIED IDEOGRAPH + {0xC9A9, 0x5AC2}, //12379 #CJK UNIFIED IDEOGRAPH + {0xC9AA, 0x745F}, //12380 #CJK UNIFIED IDEOGRAPH + {0xC9AB, 0x8272}, //12381 #CJK UNIFIED IDEOGRAPH + {0xC9AC, 0x6DA9}, //12382 #CJK UNIFIED IDEOGRAPH + {0xC9AD, 0x68EE}, //12383 #CJK UNIFIED IDEOGRAPH + {0xC9AE, 0x50E7}, //12384 #CJK UNIFIED IDEOGRAPH + {0xC9AF, 0x838E}, //12385 #CJK UNIFIED IDEOGRAPH + {0xC9B0, 0x7802}, //12386 #CJK UNIFIED IDEOGRAPH + {0xC9B1, 0x6740}, //12387 #CJK UNIFIED IDEOGRAPH + {0xC9B2, 0x5239}, //12388 #CJK UNIFIED IDEOGRAPH + {0xC9B3, 0x6C99}, //12389 #CJK UNIFIED IDEOGRAPH + {0xC9B4, 0x7EB1}, //12390 #CJK UNIFIED IDEOGRAPH + {0xC9B5, 0x50BB}, //12391 #CJK UNIFIED IDEOGRAPH + {0xC9B6, 0x5565}, //12392 #CJK UNIFIED IDEOGRAPH + {0xC9B7, 0x715E}, //12393 #CJK UNIFIED IDEOGRAPH + {0xC9B8, 0x7B5B}, //12394 #CJK UNIFIED IDEOGRAPH + {0xC9B9, 0x6652}, //12395 #CJK UNIFIED IDEOGRAPH + {0xC9BA, 0x73CA}, //12396 #CJK UNIFIED IDEOGRAPH + {0xC9BB, 0x82EB}, //12397 #CJK UNIFIED IDEOGRAPH + {0xC9BC, 0x6749}, //12398 #CJK UNIFIED IDEOGRAPH + {0xC9BD, 0x5C71}, //12399 #CJK UNIFIED IDEOGRAPH + {0xC9BE, 0x5220}, //12400 #CJK UNIFIED IDEOGRAPH + {0xC9BF, 0x717D}, //12401 #CJK UNIFIED IDEOGRAPH + {0xC9C0, 0x886B}, //12402 #CJK UNIFIED IDEOGRAPH + {0xC9C1, 0x95EA}, //12403 #CJK UNIFIED IDEOGRAPH + {0xC9C2, 0x9655}, //12404 #CJK UNIFIED IDEOGRAPH + {0xC9C3, 0x64C5}, //12405 #CJK UNIFIED IDEOGRAPH + {0xC9C4, 0x8D61}, //12406 #CJK UNIFIED IDEOGRAPH + {0xC9C5, 0x81B3}, //12407 #CJK UNIFIED IDEOGRAPH + {0xC9C6, 0x5584}, //12408 #CJK UNIFIED IDEOGRAPH + {0xC9C7, 0x6C55}, //12409 #CJK UNIFIED IDEOGRAPH + {0xC9C8, 0x6247}, //12410 #CJK UNIFIED IDEOGRAPH + {0xC9C9, 0x7F2E}, //12411 #CJK UNIFIED IDEOGRAPH + {0xC9CA, 0x5892}, //12412 #CJK UNIFIED IDEOGRAPH + {0xC9CB, 0x4F24}, //12413 #CJK UNIFIED IDEOGRAPH + {0xC9CC, 0x5546}, //12414 #CJK UNIFIED IDEOGRAPH + {0xC9CD, 0x8D4F}, //12415 #CJK UNIFIED IDEOGRAPH + {0xC9CE, 0x664C}, //12416 #CJK UNIFIED IDEOGRAPH + {0xC9CF, 0x4E0A}, //12417 #CJK UNIFIED IDEOGRAPH + {0xC9D0, 0x5C1A}, //12418 #CJK UNIFIED IDEOGRAPH + {0xC9D1, 0x88F3}, //12419 #CJK UNIFIED IDEOGRAPH + {0xC9D2, 0x68A2}, //12420 #CJK UNIFIED IDEOGRAPH + {0xC9D3, 0x634E}, //12421 #CJK UNIFIED IDEOGRAPH + {0xC9D4, 0x7A0D}, //12422 #CJK UNIFIED IDEOGRAPH + {0xC9D5, 0x70E7}, //12423 #CJK UNIFIED IDEOGRAPH + {0xC9D6, 0x828D}, //12424 #CJK UNIFIED IDEOGRAPH + {0xC9D7, 0x52FA}, //12425 #CJK UNIFIED IDEOGRAPH + {0xC9D8, 0x97F6}, //12426 #CJK UNIFIED IDEOGRAPH + {0xC9D9, 0x5C11}, //12427 #CJK UNIFIED IDEOGRAPH + {0xC9DA, 0x54E8}, //12428 #CJK UNIFIED IDEOGRAPH + {0xC9DB, 0x90B5}, //12429 #CJK UNIFIED IDEOGRAPH + {0xC9DC, 0x7ECD}, //12430 #CJK UNIFIED IDEOGRAPH + {0xC9DD, 0x5962}, //12431 #CJK UNIFIED IDEOGRAPH + {0xC9DE, 0x8D4A}, //12432 #CJK UNIFIED IDEOGRAPH + {0xC9DF, 0x86C7}, //12433 #CJK UNIFIED IDEOGRAPH + {0xC9E0, 0x820C}, //12434 #CJK UNIFIED IDEOGRAPH + {0xC9E1, 0x820D}, //12435 #CJK UNIFIED IDEOGRAPH + {0xC9E2, 0x8D66}, //12436 #CJK UNIFIED IDEOGRAPH + {0xC9E3, 0x6444}, //12437 #CJK UNIFIED IDEOGRAPH + {0xC9E4, 0x5C04}, //12438 #CJK UNIFIED IDEOGRAPH + {0xC9E5, 0x6151}, //12439 #CJK UNIFIED IDEOGRAPH + {0xC9E6, 0x6D89}, //12440 #CJK UNIFIED IDEOGRAPH + {0xC9E7, 0x793E}, //12441 #CJK UNIFIED IDEOGRAPH + {0xC9E8, 0x8BBE}, //12442 #CJK UNIFIED IDEOGRAPH + {0xC9E9, 0x7837}, //12443 #CJK UNIFIED IDEOGRAPH + {0xC9EA, 0x7533}, //12444 #CJK UNIFIED IDEOGRAPH + {0xC9EB, 0x547B}, //12445 #CJK UNIFIED IDEOGRAPH + {0xC9EC, 0x4F38}, //12446 #CJK UNIFIED IDEOGRAPH + {0xC9ED, 0x8EAB}, //12447 #CJK UNIFIED IDEOGRAPH + {0xC9EE, 0x6DF1}, //12448 #CJK UNIFIED IDEOGRAPH + {0xC9EF, 0x5A20}, //12449 #CJK UNIFIED IDEOGRAPH + {0xC9F0, 0x7EC5}, //12450 #CJK UNIFIED IDEOGRAPH + {0xC9F1, 0x795E}, //12451 #CJK UNIFIED IDEOGRAPH + {0xC9F2, 0x6C88}, //12452 #CJK UNIFIED IDEOGRAPH + {0xC9F3, 0x5BA1}, //12453 #CJK UNIFIED IDEOGRAPH + {0xC9F4, 0x5A76}, //12454 #CJK UNIFIED IDEOGRAPH + {0xC9F5, 0x751A}, //12455 #CJK UNIFIED IDEOGRAPH + {0xC9F6, 0x80BE}, //12456 #CJK UNIFIED IDEOGRAPH + {0xC9F7, 0x614E}, //12457 #CJK UNIFIED IDEOGRAPH + {0xC9F8, 0x6E17}, //12458 #CJK UNIFIED IDEOGRAPH + {0xC9F9, 0x58F0}, //12459 #CJK UNIFIED IDEOGRAPH + {0xC9FA, 0x751F}, //12460 #CJK UNIFIED IDEOGRAPH + {0xC9FB, 0x7525}, //12461 #CJK UNIFIED IDEOGRAPH + {0xC9FC, 0x7272}, //12462 #CJK UNIFIED IDEOGRAPH + {0xC9FD, 0x5347}, //12463 #CJK UNIFIED IDEOGRAPH + {0xC9FE, 0x7EF3}, //12464 #CJK UNIFIED IDEOGRAPH + {0xCA40, 0x8503}, //12465 #CJK UNIFIED IDEOGRAPH + {0xCA41, 0x8504}, //12466 #CJK UNIFIED IDEOGRAPH + {0xCA42, 0x8505}, //12467 #CJK UNIFIED IDEOGRAPH + {0xCA43, 0x8506}, //12468 #CJK UNIFIED IDEOGRAPH + {0xCA44, 0x8507}, //12469 #CJK UNIFIED IDEOGRAPH + {0xCA45, 0x8508}, //12470 #CJK UNIFIED IDEOGRAPH + {0xCA46, 0x8509}, //12471 #CJK UNIFIED IDEOGRAPH + {0xCA47, 0x850A}, //12472 #CJK UNIFIED IDEOGRAPH + {0xCA48, 0x850B}, //12473 #CJK UNIFIED IDEOGRAPH + {0xCA49, 0x850D}, //12474 #CJK UNIFIED IDEOGRAPH + {0xCA4A, 0x850E}, //12475 #CJK UNIFIED IDEOGRAPH + {0xCA4B, 0x850F}, //12476 #CJK UNIFIED IDEOGRAPH + {0xCA4C, 0x8510}, //12477 #CJK UNIFIED IDEOGRAPH + {0xCA4D, 0x8512}, //12478 #CJK UNIFIED IDEOGRAPH + {0xCA4E, 0x8514}, //12479 #CJK UNIFIED IDEOGRAPH + {0xCA4F, 0x8515}, //12480 #CJK UNIFIED IDEOGRAPH + {0xCA50, 0x8516}, //12481 #CJK UNIFIED IDEOGRAPH + {0xCA51, 0x8518}, //12482 #CJK UNIFIED IDEOGRAPH + {0xCA52, 0x8519}, //12483 #CJK UNIFIED IDEOGRAPH + {0xCA53, 0x851B}, //12484 #CJK UNIFIED IDEOGRAPH + {0xCA54, 0x851C}, //12485 #CJK UNIFIED IDEOGRAPH + {0xCA55, 0x851D}, //12486 #CJK UNIFIED IDEOGRAPH + {0xCA56, 0x851E}, //12487 #CJK UNIFIED IDEOGRAPH + {0xCA57, 0x8520}, //12488 #CJK UNIFIED IDEOGRAPH + {0xCA58, 0x8522}, //12489 #CJK UNIFIED IDEOGRAPH + {0xCA59, 0x8523}, //12490 #CJK UNIFIED IDEOGRAPH + {0xCA5A, 0x8524}, //12491 #CJK UNIFIED IDEOGRAPH + {0xCA5B, 0x8525}, //12492 #CJK UNIFIED IDEOGRAPH + {0xCA5C, 0x8526}, //12493 #CJK UNIFIED IDEOGRAPH + {0xCA5D, 0x8527}, //12494 #CJK UNIFIED IDEOGRAPH + {0xCA5E, 0x8528}, //12495 #CJK UNIFIED IDEOGRAPH + {0xCA5F, 0x8529}, //12496 #CJK UNIFIED IDEOGRAPH + {0xCA60, 0x852A}, //12497 #CJK UNIFIED IDEOGRAPH + {0xCA61, 0x852D}, //12498 #CJK UNIFIED IDEOGRAPH + {0xCA62, 0x852E}, //12499 #CJK UNIFIED IDEOGRAPH + {0xCA63, 0x852F}, //12500 #CJK UNIFIED IDEOGRAPH + {0xCA64, 0x8530}, //12501 #CJK UNIFIED IDEOGRAPH + {0xCA65, 0x8531}, //12502 #CJK UNIFIED IDEOGRAPH + {0xCA66, 0x8532}, //12503 #CJK UNIFIED IDEOGRAPH + {0xCA67, 0x8533}, //12504 #CJK UNIFIED IDEOGRAPH + {0xCA68, 0x8534}, //12505 #CJK UNIFIED IDEOGRAPH + {0xCA69, 0x8535}, //12506 #CJK UNIFIED IDEOGRAPH + {0xCA6A, 0x8536}, //12507 #CJK UNIFIED IDEOGRAPH + {0xCA6B, 0x853E}, //12508 #CJK UNIFIED IDEOGRAPH + {0xCA6C, 0x853F}, //12509 #CJK UNIFIED IDEOGRAPH + {0xCA6D, 0x8540}, //12510 #CJK UNIFIED IDEOGRAPH + {0xCA6E, 0x8541}, //12511 #CJK UNIFIED IDEOGRAPH + {0xCA6F, 0x8542}, //12512 #CJK UNIFIED IDEOGRAPH + {0xCA70, 0x8544}, //12513 #CJK UNIFIED IDEOGRAPH + {0xCA71, 0x8545}, //12514 #CJK UNIFIED IDEOGRAPH + {0xCA72, 0x8546}, //12515 #CJK UNIFIED IDEOGRAPH + {0xCA73, 0x8547}, //12516 #CJK UNIFIED IDEOGRAPH + {0xCA74, 0x854B}, //12517 #CJK UNIFIED IDEOGRAPH + {0xCA75, 0x854C}, //12518 #CJK UNIFIED IDEOGRAPH + {0xCA76, 0x854D}, //12519 #CJK UNIFIED IDEOGRAPH + {0xCA77, 0x854E}, //12520 #CJK UNIFIED IDEOGRAPH + {0xCA78, 0x854F}, //12521 #CJK UNIFIED IDEOGRAPH + {0xCA79, 0x8550}, //12522 #CJK UNIFIED IDEOGRAPH + {0xCA7A, 0x8551}, //12523 #CJK UNIFIED IDEOGRAPH + {0xCA7B, 0x8552}, //12524 #CJK UNIFIED IDEOGRAPH + {0xCA7C, 0x8553}, //12525 #CJK UNIFIED IDEOGRAPH + {0xCA7D, 0x8554}, //12526 #CJK UNIFIED IDEOGRAPH + {0xCA7E, 0x8555}, //12527 #CJK UNIFIED IDEOGRAPH + {0xCA80, 0x8557}, //12528 #CJK UNIFIED IDEOGRAPH + {0xCA81, 0x8558}, //12529 #CJK UNIFIED IDEOGRAPH + {0xCA82, 0x855A}, //12530 #CJK UNIFIED IDEOGRAPH + {0xCA83, 0x855B}, //12531 #CJK UNIFIED IDEOGRAPH + {0xCA84, 0x855C}, //12532 #CJK UNIFIED IDEOGRAPH + {0xCA85, 0x855D}, //12533 #CJK UNIFIED IDEOGRAPH + {0xCA86, 0x855F}, //12534 #CJK UNIFIED IDEOGRAPH + {0xCA87, 0x8560}, //12535 #CJK UNIFIED IDEOGRAPH + {0xCA88, 0x8561}, //12536 #CJK UNIFIED IDEOGRAPH + {0xCA89, 0x8562}, //12537 #CJK UNIFIED IDEOGRAPH + {0xCA8A, 0x8563}, //12538 #CJK UNIFIED IDEOGRAPH + {0xCA8B, 0x8565}, //12539 #CJK UNIFIED IDEOGRAPH + {0xCA8C, 0x8566}, //12540 #CJK UNIFIED IDEOGRAPH + {0xCA8D, 0x8567}, //12541 #CJK UNIFIED IDEOGRAPH + {0xCA8E, 0x8569}, //12542 #CJK UNIFIED IDEOGRAPH + {0xCA8F, 0x856A}, //12543 #CJK UNIFIED IDEOGRAPH + {0xCA90, 0x856B}, //12544 #CJK UNIFIED IDEOGRAPH + {0xCA91, 0x856C}, //12545 #CJK UNIFIED IDEOGRAPH + {0xCA92, 0x856D}, //12546 #CJK UNIFIED IDEOGRAPH + {0xCA93, 0x856E}, //12547 #CJK UNIFIED IDEOGRAPH + {0xCA94, 0x856F}, //12548 #CJK UNIFIED IDEOGRAPH + {0xCA95, 0x8570}, //12549 #CJK UNIFIED IDEOGRAPH + {0xCA96, 0x8571}, //12550 #CJK UNIFIED IDEOGRAPH + {0xCA97, 0x8573}, //12551 #CJK UNIFIED IDEOGRAPH + {0xCA98, 0x8575}, //12552 #CJK UNIFIED IDEOGRAPH + {0xCA99, 0x8576}, //12553 #CJK UNIFIED IDEOGRAPH + {0xCA9A, 0x8577}, //12554 #CJK UNIFIED IDEOGRAPH + {0xCA9B, 0x8578}, //12555 #CJK UNIFIED IDEOGRAPH + {0xCA9C, 0x857C}, //12556 #CJK UNIFIED IDEOGRAPH + {0xCA9D, 0x857D}, //12557 #CJK UNIFIED IDEOGRAPH + {0xCA9E, 0x857F}, //12558 #CJK UNIFIED IDEOGRAPH + {0xCA9F, 0x8580}, //12559 #CJK UNIFIED IDEOGRAPH + {0xCAA0, 0x8581}, //12560 #CJK UNIFIED IDEOGRAPH + {0xCAA1, 0x7701}, //12561 #CJK UNIFIED IDEOGRAPH + {0xCAA2, 0x76DB}, //12562 #CJK UNIFIED IDEOGRAPH + {0xCAA3, 0x5269}, //12563 #CJK UNIFIED IDEOGRAPH + {0xCAA4, 0x80DC}, //12564 #CJK UNIFIED IDEOGRAPH + {0xCAA5, 0x5723}, //12565 #CJK UNIFIED IDEOGRAPH + {0xCAA6, 0x5E08}, //12566 #CJK UNIFIED IDEOGRAPH + {0xCAA7, 0x5931}, //12567 #CJK UNIFIED IDEOGRAPH + {0xCAA8, 0x72EE}, //12568 #CJK UNIFIED IDEOGRAPH + {0xCAA9, 0x65BD}, //12569 #CJK UNIFIED IDEOGRAPH + {0xCAAA, 0x6E7F}, //12570 #CJK UNIFIED IDEOGRAPH + {0xCAAB, 0x8BD7}, //12571 #CJK UNIFIED IDEOGRAPH + {0xCAAC, 0x5C38}, //12572 #CJK UNIFIED IDEOGRAPH + {0xCAAD, 0x8671}, //12573 #CJK UNIFIED IDEOGRAPH + {0xCAAE, 0x5341}, //12574 #CJK UNIFIED IDEOGRAPH + {0xCAAF, 0x77F3}, //12575 #CJK UNIFIED IDEOGRAPH + {0xCAB0, 0x62FE}, //12576 #CJK UNIFIED IDEOGRAPH + {0xCAB1, 0x65F6}, //12577 #CJK UNIFIED IDEOGRAPH + {0xCAB2, 0x4EC0}, //12578 #CJK UNIFIED IDEOGRAPH + {0xCAB3, 0x98DF}, //12579 #CJK UNIFIED IDEOGRAPH + {0xCAB4, 0x8680}, //12580 #CJK UNIFIED IDEOGRAPH + {0xCAB5, 0x5B9E}, //12581 #CJK UNIFIED IDEOGRAPH + {0xCAB6, 0x8BC6}, //12582 #CJK UNIFIED IDEOGRAPH + {0xCAB7, 0x53F2}, //12583 #CJK UNIFIED IDEOGRAPH + {0xCAB8, 0x77E2}, //12584 #CJK UNIFIED IDEOGRAPH + {0xCAB9, 0x4F7F}, //12585 #CJK UNIFIED IDEOGRAPH + {0xCABA, 0x5C4E}, //12586 #CJK UNIFIED IDEOGRAPH + {0xCABB, 0x9A76}, //12587 #CJK UNIFIED IDEOGRAPH + {0xCABC, 0x59CB}, //12588 #CJK UNIFIED IDEOGRAPH + {0xCABD, 0x5F0F}, //12589 #CJK UNIFIED IDEOGRAPH + {0xCABE, 0x793A}, //12590 #CJK UNIFIED IDEOGRAPH + {0xCABF, 0x58EB}, //12591 #CJK UNIFIED IDEOGRAPH + {0xCAC0, 0x4E16}, //12592 #CJK UNIFIED IDEOGRAPH + {0xCAC1, 0x67FF}, //12593 #CJK UNIFIED IDEOGRAPH + {0xCAC2, 0x4E8B}, //12594 #CJK UNIFIED IDEOGRAPH + {0xCAC3, 0x62ED}, //12595 #CJK UNIFIED IDEOGRAPH + {0xCAC4, 0x8A93}, //12596 #CJK UNIFIED IDEOGRAPH + {0xCAC5, 0x901D}, //12597 #CJK UNIFIED IDEOGRAPH + {0xCAC6, 0x52BF}, //12598 #CJK UNIFIED IDEOGRAPH + {0xCAC7, 0x662F}, //12599 #CJK UNIFIED IDEOGRAPH + {0xCAC8, 0x55DC}, //12600 #CJK UNIFIED IDEOGRAPH + {0xCAC9, 0x566C}, //12601 #CJK UNIFIED IDEOGRAPH + {0xCACA, 0x9002}, //12602 #CJK UNIFIED IDEOGRAPH + {0xCACB, 0x4ED5}, //12603 #CJK UNIFIED IDEOGRAPH + {0xCACC, 0x4F8D}, //12604 #CJK UNIFIED IDEOGRAPH + {0xCACD, 0x91CA}, //12605 #CJK UNIFIED IDEOGRAPH + {0xCACE, 0x9970}, //12606 #CJK UNIFIED IDEOGRAPH + {0xCACF, 0x6C0F}, //12607 #CJK UNIFIED IDEOGRAPH + {0xCAD0, 0x5E02}, //12608 #CJK UNIFIED IDEOGRAPH + {0xCAD1, 0x6043}, //12609 #CJK UNIFIED IDEOGRAPH + {0xCAD2, 0x5BA4}, //12610 #CJK UNIFIED IDEOGRAPH + {0xCAD3, 0x89C6}, //12611 #CJK UNIFIED IDEOGRAPH + {0xCAD4, 0x8BD5}, //12612 #CJK UNIFIED IDEOGRAPH + {0xCAD5, 0x6536}, //12613 #CJK UNIFIED IDEOGRAPH + {0xCAD6, 0x624B}, //12614 #CJK UNIFIED IDEOGRAPH + {0xCAD7, 0x9996}, //12615 #CJK UNIFIED IDEOGRAPH + {0xCAD8, 0x5B88}, //12616 #CJK UNIFIED IDEOGRAPH + {0xCAD9, 0x5BFF}, //12617 #CJK UNIFIED IDEOGRAPH + {0xCADA, 0x6388}, //12618 #CJK UNIFIED IDEOGRAPH + {0xCADB, 0x552E}, //12619 #CJK UNIFIED IDEOGRAPH + {0xCADC, 0x53D7}, //12620 #CJK UNIFIED IDEOGRAPH + {0xCADD, 0x7626}, //12621 #CJK UNIFIED IDEOGRAPH + {0xCADE, 0x517D}, //12622 #CJK UNIFIED IDEOGRAPH + {0xCADF, 0x852C}, //12623 #CJK UNIFIED IDEOGRAPH + {0xCAE0, 0x67A2}, //12624 #CJK UNIFIED IDEOGRAPH + {0xCAE1, 0x68B3}, //12625 #CJK UNIFIED IDEOGRAPH + {0xCAE2, 0x6B8A}, //12626 #CJK UNIFIED IDEOGRAPH + {0xCAE3, 0x6292}, //12627 #CJK UNIFIED IDEOGRAPH + {0xCAE4, 0x8F93}, //12628 #CJK UNIFIED IDEOGRAPH + {0xCAE5, 0x53D4}, //12629 #CJK UNIFIED IDEOGRAPH + {0xCAE6, 0x8212}, //12630 #CJK UNIFIED IDEOGRAPH + {0xCAE7, 0x6DD1}, //12631 #CJK UNIFIED IDEOGRAPH + {0xCAE8, 0x758F}, //12632 #CJK UNIFIED IDEOGRAPH + {0xCAE9, 0x4E66}, //12633 #CJK UNIFIED IDEOGRAPH + {0xCAEA, 0x8D4E}, //12634 #CJK UNIFIED IDEOGRAPH + {0xCAEB, 0x5B70}, //12635 #CJK UNIFIED IDEOGRAPH + {0xCAEC, 0x719F}, //12636 #CJK UNIFIED IDEOGRAPH + {0xCAED, 0x85AF}, //12637 #CJK UNIFIED IDEOGRAPH + {0xCAEE, 0x6691}, //12638 #CJK UNIFIED IDEOGRAPH + {0xCAEF, 0x66D9}, //12639 #CJK UNIFIED IDEOGRAPH + {0xCAF0, 0x7F72}, //12640 #CJK UNIFIED IDEOGRAPH + {0xCAF1, 0x8700}, //12641 #CJK UNIFIED IDEOGRAPH + {0xCAF2, 0x9ECD}, //12642 #CJK UNIFIED IDEOGRAPH + {0xCAF3, 0x9F20}, //12643 #CJK UNIFIED IDEOGRAPH + {0xCAF4, 0x5C5E}, //12644 #CJK UNIFIED IDEOGRAPH + {0xCAF5, 0x672F}, //12645 #CJK UNIFIED IDEOGRAPH + {0xCAF6, 0x8FF0}, //12646 #CJK UNIFIED IDEOGRAPH + {0xCAF7, 0x6811}, //12647 #CJK UNIFIED IDEOGRAPH + {0xCAF8, 0x675F}, //12648 #CJK UNIFIED IDEOGRAPH + {0xCAF9, 0x620D}, //12649 #CJK UNIFIED IDEOGRAPH + {0xCAFA, 0x7AD6}, //12650 #CJK UNIFIED IDEOGRAPH + {0xCAFB, 0x5885}, //12651 #CJK UNIFIED IDEOGRAPH + {0xCAFC, 0x5EB6}, //12652 #CJK UNIFIED IDEOGRAPH + {0xCAFD, 0x6570}, //12653 #CJK UNIFIED IDEOGRAPH + {0xCAFE, 0x6F31}, //12654 #CJK UNIFIED IDEOGRAPH + {0xCB40, 0x8582}, //12655 #CJK UNIFIED IDEOGRAPH + {0xCB41, 0x8583}, //12656 #CJK UNIFIED IDEOGRAPH + {0xCB42, 0x8586}, //12657 #CJK UNIFIED IDEOGRAPH + {0xCB43, 0x8588}, //12658 #CJK UNIFIED IDEOGRAPH + {0xCB44, 0x8589}, //12659 #CJK UNIFIED IDEOGRAPH + {0xCB45, 0x858A}, //12660 #CJK UNIFIED IDEOGRAPH + {0xCB46, 0x858B}, //12661 #CJK UNIFIED IDEOGRAPH + {0xCB47, 0x858C}, //12662 #CJK UNIFIED IDEOGRAPH + {0xCB48, 0x858D}, //12663 #CJK UNIFIED IDEOGRAPH + {0xCB49, 0x858E}, //12664 #CJK UNIFIED IDEOGRAPH + {0xCB4A, 0x8590}, //12665 #CJK UNIFIED IDEOGRAPH + {0xCB4B, 0x8591}, //12666 #CJK UNIFIED IDEOGRAPH + {0xCB4C, 0x8592}, //12667 #CJK UNIFIED IDEOGRAPH + {0xCB4D, 0x8593}, //12668 #CJK UNIFIED IDEOGRAPH + {0xCB4E, 0x8594}, //12669 #CJK UNIFIED IDEOGRAPH + {0xCB4F, 0x8595}, //12670 #CJK UNIFIED IDEOGRAPH + {0xCB50, 0x8596}, //12671 #CJK UNIFIED IDEOGRAPH + {0xCB51, 0x8597}, //12672 #CJK UNIFIED IDEOGRAPH + {0xCB52, 0x8598}, //12673 #CJK UNIFIED IDEOGRAPH + {0xCB53, 0x8599}, //12674 #CJK UNIFIED IDEOGRAPH + {0xCB54, 0x859A}, //12675 #CJK UNIFIED IDEOGRAPH + {0xCB55, 0x859D}, //12676 #CJK UNIFIED IDEOGRAPH + {0xCB56, 0x859E}, //12677 #CJK UNIFIED IDEOGRAPH + {0xCB57, 0x859F}, //12678 #CJK UNIFIED IDEOGRAPH + {0xCB58, 0x85A0}, //12679 #CJK UNIFIED IDEOGRAPH + {0xCB59, 0x85A1}, //12680 #CJK UNIFIED IDEOGRAPH + {0xCB5A, 0x85A2}, //12681 #CJK UNIFIED IDEOGRAPH + {0xCB5B, 0x85A3}, //12682 #CJK UNIFIED IDEOGRAPH + {0xCB5C, 0x85A5}, //12683 #CJK UNIFIED IDEOGRAPH + {0xCB5D, 0x85A6}, //12684 #CJK UNIFIED IDEOGRAPH + {0xCB5E, 0x85A7}, //12685 #CJK UNIFIED IDEOGRAPH + {0xCB5F, 0x85A9}, //12686 #CJK UNIFIED IDEOGRAPH + {0xCB60, 0x85AB}, //12687 #CJK UNIFIED IDEOGRAPH + {0xCB61, 0x85AC}, //12688 #CJK UNIFIED IDEOGRAPH + {0xCB62, 0x85AD}, //12689 #CJK UNIFIED IDEOGRAPH + {0xCB63, 0x85B1}, //12690 #CJK UNIFIED IDEOGRAPH + {0xCB64, 0x85B2}, //12691 #CJK UNIFIED IDEOGRAPH + {0xCB65, 0x85B3}, //12692 #CJK UNIFIED IDEOGRAPH + {0xCB66, 0x85B4}, //12693 #CJK UNIFIED IDEOGRAPH + {0xCB67, 0x85B5}, //12694 #CJK UNIFIED IDEOGRAPH + {0xCB68, 0x85B6}, //12695 #CJK UNIFIED IDEOGRAPH + {0xCB69, 0x85B8}, //12696 #CJK UNIFIED IDEOGRAPH + {0xCB6A, 0x85BA}, //12697 #CJK UNIFIED IDEOGRAPH + {0xCB6B, 0x85BB}, //12698 #CJK UNIFIED IDEOGRAPH + {0xCB6C, 0x85BC}, //12699 #CJK UNIFIED IDEOGRAPH + {0xCB6D, 0x85BD}, //12700 #CJK UNIFIED IDEOGRAPH + {0xCB6E, 0x85BE}, //12701 #CJK UNIFIED IDEOGRAPH + {0xCB6F, 0x85BF}, //12702 #CJK UNIFIED IDEOGRAPH + {0xCB70, 0x85C0}, //12703 #CJK UNIFIED IDEOGRAPH + {0xCB71, 0x85C2}, //12704 #CJK UNIFIED IDEOGRAPH + {0xCB72, 0x85C3}, //12705 #CJK UNIFIED IDEOGRAPH + {0xCB73, 0x85C4}, //12706 #CJK UNIFIED IDEOGRAPH + {0xCB74, 0x85C5}, //12707 #CJK UNIFIED IDEOGRAPH + {0xCB75, 0x85C6}, //12708 #CJK UNIFIED IDEOGRAPH + {0xCB76, 0x85C7}, //12709 #CJK UNIFIED IDEOGRAPH + {0xCB77, 0x85C8}, //12710 #CJK UNIFIED IDEOGRAPH + {0xCB78, 0x85CA}, //12711 #CJK UNIFIED IDEOGRAPH + {0xCB79, 0x85CB}, //12712 #CJK UNIFIED IDEOGRAPH + {0xCB7A, 0x85CC}, //12713 #CJK UNIFIED IDEOGRAPH + {0xCB7B, 0x85CD}, //12714 #CJK UNIFIED IDEOGRAPH + {0xCB7C, 0x85CE}, //12715 #CJK UNIFIED IDEOGRAPH + {0xCB7D, 0x85D1}, //12716 #CJK UNIFIED IDEOGRAPH + {0xCB7E, 0x85D2}, //12717 #CJK UNIFIED IDEOGRAPH + {0xCB80, 0x85D4}, //12718 #CJK UNIFIED IDEOGRAPH + {0xCB81, 0x85D6}, //12719 #CJK UNIFIED IDEOGRAPH + {0xCB82, 0x85D7}, //12720 #CJK UNIFIED IDEOGRAPH + {0xCB83, 0x85D8}, //12721 #CJK UNIFIED IDEOGRAPH + {0xCB84, 0x85D9}, //12722 #CJK UNIFIED IDEOGRAPH + {0xCB85, 0x85DA}, //12723 #CJK UNIFIED IDEOGRAPH + {0xCB86, 0x85DB}, //12724 #CJK UNIFIED IDEOGRAPH + {0xCB87, 0x85DD}, //12725 #CJK UNIFIED IDEOGRAPH + {0xCB88, 0x85DE}, //12726 #CJK UNIFIED IDEOGRAPH + {0xCB89, 0x85DF}, //12727 #CJK UNIFIED IDEOGRAPH + {0xCB8A, 0x85E0}, //12728 #CJK UNIFIED IDEOGRAPH + {0xCB8B, 0x85E1}, //12729 #CJK UNIFIED IDEOGRAPH + {0xCB8C, 0x85E2}, //12730 #CJK UNIFIED IDEOGRAPH + {0xCB8D, 0x85E3}, //12731 #CJK UNIFIED IDEOGRAPH + {0xCB8E, 0x85E5}, //12732 #CJK UNIFIED IDEOGRAPH + {0xCB8F, 0x85E6}, //12733 #CJK UNIFIED IDEOGRAPH + {0xCB90, 0x85E7}, //12734 #CJK UNIFIED IDEOGRAPH + {0xCB91, 0x85E8}, //12735 #CJK UNIFIED IDEOGRAPH + {0xCB92, 0x85EA}, //12736 #CJK UNIFIED IDEOGRAPH + {0xCB93, 0x85EB}, //12737 #CJK UNIFIED IDEOGRAPH + {0xCB94, 0x85EC}, //12738 #CJK UNIFIED IDEOGRAPH + {0xCB95, 0x85ED}, //12739 #CJK UNIFIED IDEOGRAPH + {0xCB96, 0x85EE}, //12740 #CJK UNIFIED IDEOGRAPH + {0xCB97, 0x85EF}, //12741 #CJK UNIFIED IDEOGRAPH + {0xCB98, 0x85F0}, //12742 #CJK UNIFIED IDEOGRAPH + {0xCB99, 0x85F1}, //12743 #CJK UNIFIED IDEOGRAPH + {0xCB9A, 0x85F2}, //12744 #CJK UNIFIED IDEOGRAPH + {0xCB9B, 0x85F3}, //12745 #CJK UNIFIED IDEOGRAPH + {0xCB9C, 0x85F4}, //12746 #CJK UNIFIED IDEOGRAPH + {0xCB9D, 0x85F5}, //12747 #CJK UNIFIED IDEOGRAPH + {0xCB9E, 0x85F6}, //12748 #CJK UNIFIED IDEOGRAPH + {0xCB9F, 0x85F7}, //12749 #CJK UNIFIED IDEOGRAPH + {0xCBA0, 0x85F8}, //12750 #CJK UNIFIED IDEOGRAPH + {0xCBA1, 0x6055}, //12751 #CJK UNIFIED IDEOGRAPH + {0xCBA2, 0x5237}, //12752 #CJK UNIFIED IDEOGRAPH + {0xCBA3, 0x800D}, //12753 #CJK UNIFIED IDEOGRAPH + {0xCBA4, 0x6454}, //12754 #CJK UNIFIED IDEOGRAPH + {0xCBA5, 0x8870}, //12755 #CJK UNIFIED IDEOGRAPH + {0xCBA6, 0x7529}, //12756 #CJK UNIFIED IDEOGRAPH + {0xCBA7, 0x5E05}, //12757 #CJK UNIFIED IDEOGRAPH + {0xCBA8, 0x6813}, //12758 #CJK UNIFIED IDEOGRAPH + {0xCBA9, 0x62F4}, //12759 #CJK UNIFIED IDEOGRAPH + {0xCBAA, 0x971C}, //12760 #CJK UNIFIED IDEOGRAPH + {0xCBAB, 0x53CC}, //12761 #CJK UNIFIED IDEOGRAPH + {0xCBAC, 0x723D}, //12762 #CJK UNIFIED IDEOGRAPH + {0xCBAD, 0x8C01}, //12763 #CJK UNIFIED IDEOGRAPH + {0xCBAE, 0x6C34}, //12764 #CJK UNIFIED IDEOGRAPH + {0xCBAF, 0x7761}, //12765 #CJK UNIFIED IDEOGRAPH + {0xCBB0, 0x7A0E}, //12766 #CJK UNIFIED IDEOGRAPH + {0xCBB1, 0x542E}, //12767 #CJK UNIFIED IDEOGRAPH + {0xCBB2, 0x77AC}, //12768 #CJK UNIFIED IDEOGRAPH + {0xCBB3, 0x987A}, //12769 #CJK UNIFIED IDEOGRAPH + {0xCBB4, 0x821C}, //12770 #CJK UNIFIED IDEOGRAPH + {0xCBB5, 0x8BF4}, //12771 #CJK UNIFIED IDEOGRAPH + {0xCBB6, 0x7855}, //12772 #CJK UNIFIED IDEOGRAPH + {0xCBB7, 0x6714}, //12773 #CJK UNIFIED IDEOGRAPH + {0xCBB8, 0x70C1}, //12774 #CJK UNIFIED IDEOGRAPH + {0xCBB9, 0x65AF}, //12775 #CJK UNIFIED IDEOGRAPH + {0xCBBA, 0x6495}, //12776 #CJK UNIFIED IDEOGRAPH + {0xCBBB, 0x5636}, //12777 #CJK UNIFIED IDEOGRAPH + {0xCBBC, 0x601D}, //12778 #CJK UNIFIED IDEOGRAPH + {0xCBBD, 0x79C1}, //12779 #CJK UNIFIED IDEOGRAPH + {0xCBBE, 0x53F8}, //12780 #CJK UNIFIED IDEOGRAPH + {0xCBBF, 0x4E1D}, //12781 #CJK UNIFIED IDEOGRAPH + {0xCBC0, 0x6B7B}, //12782 #CJK UNIFIED IDEOGRAPH + {0xCBC1, 0x8086}, //12783 #CJK UNIFIED IDEOGRAPH + {0xCBC2, 0x5BFA}, //12784 #CJK UNIFIED IDEOGRAPH + {0xCBC3, 0x55E3}, //12785 #CJK UNIFIED IDEOGRAPH + {0xCBC4, 0x56DB}, //12786 #CJK UNIFIED IDEOGRAPH + {0xCBC5, 0x4F3A}, //12787 #CJK UNIFIED IDEOGRAPH + {0xCBC6, 0x4F3C}, //12788 #CJK UNIFIED IDEOGRAPH + {0xCBC7, 0x9972}, //12789 #CJK UNIFIED IDEOGRAPH + {0xCBC8, 0x5DF3}, //12790 #CJK UNIFIED IDEOGRAPH + {0xCBC9, 0x677E}, //12791 #CJK UNIFIED IDEOGRAPH + {0xCBCA, 0x8038}, //12792 #CJK UNIFIED IDEOGRAPH + {0xCBCB, 0x6002}, //12793 #CJK UNIFIED IDEOGRAPH + {0xCBCC, 0x9882}, //12794 #CJK UNIFIED IDEOGRAPH + {0xCBCD, 0x9001}, //12795 #CJK UNIFIED IDEOGRAPH + {0xCBCE, 0x5B8B}, //12796 #CJK UNIFIED IDEOGRAPH + {0xCBCF, 0x8BBC}, //12797 #CJK UNIFIED IDEOGRAPH + {0xCBD0, 0x8BF5}, //12798 #CJK UNIFIED IDEOGRAPH + {0xCBD1, 0x641C}, //12799 #CJK UNIFIED IDEOGRAPH + {0xCBD2, 0x8258}, //12800 #CJK UNIFIED IDEOGRAPH + {0xCBD3, 0x64DE}, //12801 #CJK UNIFIED IDEOGRAPH + {0xCBD4, 0x55FD}, //12802 #CJK UNIFIED IDEOGRAPH + {0xCBD5, 0x82CF}, //12803 #CJK UNIFIED IDEOGRAPH + {0xCBD6, 0x9165}, //12804 #CJK UNIFIED IDEOGRAPH + {0xCBD7, 0x4FD7}, //12805 #CJK UNIFIED IDEOGRAPH + {0xCBD8, 0x7D20}, //12806 #CJK UNIFIED IDEOGRAPH + {0xCBD9, 0x901F}, //12807 #CJK UNIFIED IDEOGRAPH + {0xCBDA, 0x7C9F}, //12808 #CJK UNIFIED IDEOGRAPH + {0xCBDB, 0x50F3}, //12809 #CJK UNIFIED IDEOGRAPH + {0xCBDC, 0x5851}, //12810 #CJK UNIFIED IDEOGRAPH + {0xCBDD, 0x6EAF}, //12811 #CJK UNIFIED IDEOGRAPH + {0xCBDE, 0x5BBF}, //12812 #CJK UNIFIED IDEOGRAPH + {0xCBDF, 0x8BC9}, //12813 #CJK UNIFIED IDEOGRAPH + {0xCBE0, 0x8083}, //12814 #CJK UNIFIED IDEOGRAPH + {0xCBE1, 0x9178}, //12815 #CJK UNIFIED IDEOGRAPH + {0xCBE2, 0x849C}, //12816 #CJK UNIFIED IDEOGRAPH + {0xCBE3, 0x7B97}, //12817 #CJK UNIFIED IDEOGRAPH + {0xCBE4, 0x867D}, //12818 #CJK UNIFIED IDEOGRAPH + {0xCBE5, 0x968B}, //12819 #CJK UNIFIED IDEOGRAPH + {0xCBE6, 0x968F}, //12820 #CJK UNIFIED IDEOGRAPH + {0xCBE7, 0x7EE5}, //12821 #CJK UNIFIED IDEOGRAPH + {0xCBE8, 0x9AD3}, //12822 #CJK UNIFIED IDEOGRAPH + {0xCBE9, 0x788E}, //12823 #CJK UNIFIED IDEOGRAPH + {0xCBEA, 0x5C81}, //12824 #CJK UNIFIED IDEOGRAPH + {0xCBEB, 0x7A57}, //12825 #CJK UNIFIED IDEOGRAPH + {0xCBEC, 0x9042}, //12826 #CJK UNIFIED IDEOGRAPH + {0xCBED, 0x96A7}, //12827 #CJK UNIFIED IDEOGRAPH + {0xCBEE, 0x795F}, //12828 #CJK UNIFIED IDEOGRAPH + {0xCBEF, 0x5B59}, //12829 #CJK UNIFIED IDEOGRAPH + {0xCBF0, 0x635F}, //12830 #CJK UNIFIED IDEOGRAPH + {0xCBF1, 0x7B0B}, //12831 #CJK UNIFIED IDEOGRAPH + {0xCBF2, 0x84D1}, //12832 #CJK UNIFIED IDEOGRAPH + {0xCBF3, 0x68AD}, //12833 #CJK UNIFIED IDEOGRAPH + {0xCBF4, 0x5506}, //12834 #CJK UNIFIED IDEOGRAPH + {0xCBF5, 0x7F29}, //12835 #CJK UNIFIED IDEOGRAPH + {0xCBF6, 0x7410}, //12836 #CJK UNIFIED IDEOGRAPH + {0xCBF7, 0x7D22}, //12837 #CJK UNIFIED IDEOGRAPH + {0xCBF8, 0x9501}, //12838 #CJK UNIFIED IDEOGRAPH + {0xCBF9, 0x6240}, //12839 #CJK UNIFIED IDEOGRAPH + {0xCBFA, 0x584C}, //12840 #CJK UNIFIED IDEOGRAPH + {0xCBFB, 0x4ED6}, //12841 #CJK UNIFIED IDEOGRAPH + {0xCBFC, 0x5B83}, //12842 #CJK UNIFIED IDEOGRAPH + {0xCBFD, 0x5979}, //12843 #CJK UNIFIED IDEOGRAPH + {0xCBFE, 0x5854}, //12844 #CJK UNIFIED IDEOGRAPH + {0xCC40, 0x85F9}, //12845 #CJK UNIFIED IDEOGRAPH + {0xCC41, 0x85FA}, //12846 #CJK UNIFIED IDEOGRAPH + {0xCC42, 0x85FC}, //12847 #CJK UNIFIED IDEOGRAPH + {0xCC43, 0x85FD}, //12848 #CJK UNIFIED IDEOGRAPH + {0xCC44, 0x85FE}, //12849 #CJK UNIFIED IDEOGRAPH + {0xCC45, 0x8600}, //12850 #CJK UNIFIED IDEOGRAPH + {0xCC46, 0x8601}, //12851 #CJK UNIFIED IDEOGRAPH + {0xCC47, 0x8602}, //12852 #CJK UNIFIED IDEOGRAPH + {0xCC48, 0x8603}, //12853 #CJK UNIFIED IDEOGRAPH + {0xCC49, 0x8604}, //12854 #CJK UNIFIED IDEOGRAPH + {0xCC4A, 0x8606}, //12855 #CJK UNIFIED IDEOGRAPH + {0xCC4B, 0x8607}, //12856 #CJK UNIFIED IDEOGRAPH + {0xCC4C, 0x8608}, //12857 #CJK UNIFIED IDEOGRAPH + {0xCC4D, 0x8609}, //12858 #CJK UNIFIED IDEOGRAPH + {0xCC4E, 0x860A}, //12859 #CJK UNIFIED IDEOGRAPH + {0xCC4F, 0x860B}, //12860 #CJK UNIFIED IDEOGRAPH + {0xCC50, 0x860C}, //12861 #CJK UNIFIED IDEOGRAPH + {0xCC51, 0x860D}, //12862 #CJK UNIFIED IDEOGRAPH + {0xCC52, 0x860E}, //12863 #CJK UNIFIED IDEOGRAPH + {0xCC53, 0x860F}, //12864 #CJK UNIFIED IDEOGRAPH + {0xCC54, 0x8610}, //12865 #CJK UNIFIED IDEOGRAPH + {0xCC55, 0x8612}, //12866 #CJK UNIFIED IDEOGRAPH + {0xCC56, 0x8613}, //12867 #CJK UNIFIED IDEOGRAPH + {0xCC57, 0x8614}, //12868 #CJK UNIFIED IDEOGRAPH + {0xCC58, 0x8615}, //12869 #CJK UNIFIED IDEOGRAPH + {0xCC59, 0x8617}, //12870 #CJK UNIFIED IDEOGRAPH + {0xCC5A, 0x8618}, //12871 #CJK UNIFIED IDEOGRAPH + {0xCC5B, 0x8619}, //12872 #CJK UNIFIED IDEOGRAPH + {0xCC5C, 0x861A}, //12873 #CJK UNIFIED IDEOGRAPH + {0xCC5D, 0x861B}, //12874 #CJK UNIFIED IDEOGRAPH + {0xCC5E, 0x861C}, //12875 #CJK UNIFIED IDEOGRAPH + {0xCC5F, 0x861D}, //12876 #CJK UNIFIED IDEOGRAPH + {0xCC60, 0x861E}, //12877 #CJK UNIFIED IDEOGRAPH + {0xCC61, 0x861F}, //12878 #CJK UNIFIED IDEOGRAPH + {0xCC62, 0x8620}, //12879 #CJK UNIFIED IDEOGRAPH + {0xCC63, 0x8621}, //12880 #CJK UNIFIED IDEOGRAPH + {0xCC64, 0x8622}, //12881 #CJK UNIFIED IDEOGRAPH + {0xCC65, 0x8623}, //12882 #CJK UNIFIED IDEOGRAPH + {0xCC66, 0x8624}, //12883 #CJK UNIFIED IDEOGRAPH + {0xCC67, 0x8625}, //12884 #CJK UNIFIED IDEOGRAPH + {0xCC68, 0x8626}, //12885 #CJK UNIFIED IDEOGRAPH + {0xCC69, 0x8628}, //12886 #CJK UNIFIED IDEOGRAPH + {0xCC6A, 0x862A}, //12887 #CJK UNIFIED IDEOGRAPH + {0xCC6B, 0x862B}, //12888 #CJK UNIFIED IDEOGRAPH + {0xCC6C, 0x862C}, //12889 #CJK UNIFIED IDEOGRAPH + {0xCC6D, 0x862D}, //12890 #CJK UNIFIED IDEOGRAPH + {0xCC6E, 0x862E}, //12891 #CJK UNIFIED IDEOGRAPH + {0xCC6F, 0x862F}, //12892 #CJK UNIFIED IDEOGRAPH + {0xCC70, 0x8630}, //12893 #CJK UNIFIED IDEOGRAPH + {0xCC71, 0x8631}, //12894 #CJK UNIFIED IDEOGRAPH + {0xCC72, 0x8632}, //12895 #CJK UNIFIED IDEOGRAPH + {0xCC73, 0x8633}, //12896 #CJK UNIFIED IDEOGRAPH + {0xCC74, 0x8634}, //12897 #CJK UNIFIED IDEOGRAPH + {0xCC75, 0x8635}, //12898 #CJK UNIFIED IDEOGRAPH + {0xCC76, 0x8636}, //12899 #CJK UNIFIED IDEOGRAPH + {0xCC77, 0x8637}, //12900 #CJK UNIFIED IDEOGRAPH + {0xCC78, 0x8639}, //12901 #CJK UNIFIED IDEOGRAPH + {0xCC79, 0x863A}, //12902 #CJK UNIFIED IDEOGRAPH + {0xCC7A, 0x863B}, //12903 #CJK UNIFIED IDEOGRAPH + {0xCC7B, 0x863D}, //12904 #CJK UNIFIED IDEOGRAPH + {0xCC7C, 0x863E}, //12905 #CJK UNIFIED IDEOGRAPH + {0xCC7D, 0x863F}, //12906 #CJK UNIFIED IDEOGRAPH + {0xCC7E, 0x8640}, //12907 #CJK UNIFIED IDEOGRAPH + {0xCC80, 0x8641}, //12908 #CJK UNIFIED IDEOGRAPH + {0xCC81, 0x8642}, //12909 #CJK UNIFIED IDEOGRAPH + {0xCC82, 0x8643}, //12910 #CJK UNIFIED IDEOGRAPH + {0xCC83, 0x8644}, //12911 #CJK UNIFIED IDEOGRAPH + {0xCC84, 0x8645}, //12912 #CJK UNIFIED IDEOGRAPH + {0xCC85, 0x8646}, //12913 #CJK UNIFIED IDEOGRAPH + {0xCC86, 0x8647}, //12914 #CJK UNIFIED IDEOGRAPH + {0xCC87, 0x8648}, //12915 #CJK UNIFIED IDEOGRAPH + {0xCC88, 0x8649}, //12916 #CJK UNIFIED IDEOGRAPH + {0xCC89, 0x864A}, //12917 #CJK UNIFIED IDEOGRAPH + {0xCC8A, 0x864B}, //12918 #CJK UNIFIED IDEOGRAPH + {0xCC8B, 0x864C}, //12919 #CJK UNIFIED IDEOGRAPH + {0xCC8C, 0x8652}, //12920 #CJK UNIFIED IDEOGRAPH + {0xCC8D, 0x8653}, //12921 #CJK UNIFIED IDEOGRAPH + {0xCC8E, 0x8655}, //12922 #CJK UNIFIED IDEOGRAPH + {0xCC8F, 0x8656}, //12923 #CJK UNIFIED IDEOGRAPH + {0xCC90, 0x8657}, //12924 #CJK UNIFIED IDEOGRAPH + {0xCC91, 0x8658}, //12925 #CJK UNIFIED IDEOGRAPH + {0xCC92, 0x8659}, //12926 #CJK UNIFIED IDEOGRAPH + {0xCC93, 0x865B}, //12927 #CJK UNIFIED IDEOGRAPH + {0xCC94, 0x865C}, //12928 #CJK UNIFIED IDEOGRAPH + {0xCC95, 0x865D}, //12929 #CJK UNIFIED IDEOGRAPH + {0xCC96, 0x865F}, //12930 #CJK UNIFIED IDEOGRAPH + {0xCC97, 0x8660}, //12931 #CJK UNIFIED IDEOGRAPH + {0xCC98, 0x8661}, //12932 #CJK UNIFIED IDEOGRAPH + {0xCC99, 0x8663}, //12933 #CJK UNIFIED IDEOGRAPH + {0xCC9A, 0x8664}, //12934 #CJK UNIFIED IDEOGRAPH + {0xCC9B, 0x8665}, //12935 #CJK UNIFIED IDEOGRAPH + {0xCC9C, 0x8666}, //12936 #CJK UNIFIED IDEOGRAPH + {0xCC9D, 0x8667}, //12937 #CJK UNIFIED IDEOGRAPH + {0xCC9E, 0x8668}, //12938 #CJK UNIFIED IDEOGRAPH + {0xCC9F, 0x8669}, //12939 #CJK UNIFIED IDEOGRAPH + {0xCCA0, 0x866A}, //12940 #CJK UNIFIED IDEOGRAPH + {0xCCA1, 0x736D}, //12941 #CJK UNIFIED IDEOGRAPH + {0xCCA2, 0x631E}, //12942 #CJK UNIFIED IDEOGRAPH + {0xCCA3, 0x8E4B}, //12943 #CJK UNIFIED IDEOGRAPH + {0xCCA4, 0x8E0F}, //12944 #CJK UNIFIED IDEOGRAPH + {0xCCA5, 0x80CE}, //12945 #CJK UNIFIED IDEOGRAPH + {0xCCA6, 0x82D4}, //12946 #CJK UNIFIED IDEOGRAPH + {0xCCA7, 0x62AC}, //12947 #CJK UNIFIED IDEOGRAPH + {0xCCA8, 0x53F0}, //12948 #CJK UNIFIED IDEOGRAPH + {0xCCA9, 0x6CF0}, //12949 #CJK UNIFIED IDEOGRAPH + {0xCCAA, 0x915E}, //12950 #CJK UNIFIED IDEOGRAPH + {0xCCAB, 0x592A}, //12951 #CJK UNIFIED IDEOGRAPH + {0xCCAC, 0x6001}, //12952 #CJK UNIFIED IDEOGRAPH + {0xCCAD, 0x6C70}, //12953 #CJK UNIFIED IDEOGRAPH + {0xCCAE, 0x574D}, //12954 #CJK UNIFIED IDEOGRAPH + {0xCCAF, 0x644A}, //12955 #CJK UNIFIED IDEOGRAPH + {0xCCB0, 0x8D2A}, //12956 #CJK UNIFIED IDEOGRAPH + {0xCCB1, 0x762B}, //12957 #CJK UNIFIED IDEOGRAPH + {0xCCB2, 0x6EE9}, //12958 #CJK UNIFIED IDEOGRAPH + {0xCCB3, 0x575B}, //12959 #CJK UNIFIED IDEOGRAPH + {0xCCB4, 0x6A80}, //12960 #CJK UNIFIED IDEOGRAPH + {0xCCB5, 0x75F0}, //12961 #CJK UNIFIED IDEOGRAPH + {0xCCB6, 0x6F6D}, //12962 #CJK UNIFIED IDEOGRAPH + {0xCCB7, 0x8C2D}, //12963 #CJK UNIFIED IDEOGRAPH + {0xCCB8, 0x8C08}, //12964 #CJK UNIFIED IDEOGRAPH + {0xCCB9, 0x5766}, //12965 #CJK UNIFIED IDEOGRAPH + {0xCCBA, 0x6BEF}, //12966 #CJK UNIFIED IDEOGRAPH + {0xCCBB, 0x8892}, //12967 #CJK UNIFIED IDEOGRAPH + {0xCCBC, 0x78B3}, //12968 #CJK UNIFIED IDEOGRAPH + {0xCCBD, 0x63A2}, //12969 #CJK UNIFIED IDEOGRAPH + {0xCCBE, 0x53F9}, //12970 #CJK UNIFIED IDEOGRAPH + {0xCCBF, 0x70AD}, //12971 #CJK UNIFIED IDEOGRAPH + {0xCCC0, 0x6C64}, //12972 #CJK UNIFIED IDEOGRAPH + {0xCCC1, 0x5858}, //12973 #CJK UNIFIED IDEOGRAPH + {0xCCC2, 0x642A}, //12974 #CJK UNIFIED IDEOGRAPH + {0xCCC3, 0x5802}, //12975 #CJK UNIFIED IDEOGRAPH + {0xCCC4, 0x68E0}, //12976 #CJK UNIFIED IDEOGRAPH + {0xCCC5, 0x819B}, //12977 #CJK UNIFIED IDEOGRAPH + {0xCCC6, 0x5510}, //12978 #CJK UNIFIED IDEOGRAPH + {0xCCC7, 0x7CD6}, //12979 #CJK UNIFIED IDEOGRAPH + {0xCCC8, 0x5018}, //12980 #CJK UNIFIED IDEOGRAPH + {0xCCC9, 0x8EBA}, //12981 #CJK UNIFIED IDEOGRAPH + {0xCCCA, 0x6DCC}, //12982 #CJK UNIFIED IDEOGRAPH + {0xCCCB, 0x8D9F}, //12983 #CJK UNIFIED IDEOGRAPH + {0xCCCC, 0x70EB}, //12984 #CJK UNIFIED IDEOGRAPH + {0xCCCD, 0x638F}, //12985 #CJK UNIFIED IDEOGRAPH + {0xCCCE, 0x6D9B}, //12986 #CJK UNIFIED IDEOGRAPH + {0xCCCF, 0x6ED4}, //12987 #CJK UNIFIED IDEOGRAPH + {0xCCD0, 0x7EE6}, //12988 #CJK UNIFIED IDEOGRAPH + {0xCCD1, 0x8404}, //12989 #CJK UNIFIED IDEOGRAPH + {0xCCD2, 0x6843}, //12990 #CJK UNIFIED IDEOGRAPH + {0xCCD3, 0x9003}, //12991 #CJK UNIFIED IDEOGRAPH + {0xCCD4, 0x6DD8}, //12992 #CJK UNIFIED IDEOGRAPH + {0xCCD5, 0x9676}, //12993 #CJK UNIFIED IDEOGRAPH + {0xCCD6, 0x8BA8}, //12994 #CJK UNIFIED IDEOGRAPH + {0xCCD7, 0x5957}, //12995 #CJK UNIFIED IDEOGRAPH + {0xCCD8, 0x7279}, //12996 #CJK UNIFIED IDEOGRAPH + {0xCCD9, 0x85E4}, //12997 #CJK UNIFIED IDEOGRAPH + {0xCCDA, 0x817E}, //12998 #CJK UNIFIED IDEOGRAPH + {0xCCDB, 0x75BC}, //12999 #CJK UNIFIED IDEOGRAPH + {0xCCDC, 0x8A8A}, //13000 #CJK UNIFIED IDEOGRAPH + {0xCCDD, 0x68AF}, //13001 #CJK UNIFIED IDEOGRAPH + {0xCCDE, 0x5254}, //13002 #CJK UNIFIED IDEOGRAPH + {0xCCDF, 0x8E22}, //13003 #CJK UNIFIED IDEOGRAPH + {0xCCE0, 0x9511}, //13004 #CJK UNIFIED IDEOGRAPH + {0xCCE1, 0x63D0}, //13005 #CJK UNIFIED IDEOGRAPH + {0xCCE2, 0x9898}, //13006 #CJK UNIFIED IDEOGRAPH + {0xCCE3, 0x8E44}, //13007 #CJK UNIFIED IDEOGRAPH + {0xCCE4, 0x557C}, //13008 #CJK UNIFIED IDEOGRAPH + {0xCCE5, 0x4F53}, //13009 #CJK UNIFIED IDEOGRAPH + {0xCCE6, 0x66FF}, //13010 #CJK UNIFIED IDEOGRAPH + {0xCCE7, 0x568F}, //13011 #CJK UNIFIED IDEOGRAPH + {0xCCE8, 0x60D5}, //13012 #CJK UNIFIED IDEOGRAPH + {0xCCE9, 0x6D95}, //13013 #CJK UNIFIED IDEOGRAPH + {0xCCEA, 0x5243}, //13014 #CJK UNIFIED IDEOGRAPH + {0xCCEB, 0x5C49}, //13015 #CJK UNIFIED IDEOGRAPH + {0xCCEC, 0x5929}, //13016 #CJK UNIFIED IDEOGRAPH + {0xCCED, 0x6DFB}, //13017 #CJK UNIFIED IDEOGRAPH + {0xCCEE, 0x586B}, //13018 #CJK UNIFIED IDEOGRAPH + {0xCCEF, 0x7530}, //13019 #CJK UNIFIED IDEOGRAPH + {0xCCF0, 0x751C}, //13020 #CJK UNIFIED IDEOGRAPH + {0xCCF1, 0x606C}, //13021 #CJK UNIFIED IDEOGRAPH + {0xCCF2, 0x8214}, //13022 #CJK UNIFIED IDEOGRAPH + {0xCCF3, 0x8146}, //13023 #CJK UNIFIED IDEOGRAPH + {0xCCF4, 0x6311}, //13024 #CJK UNIFIED IDEOGRAPH + {0xCCF5, 0x6761}, //13025 #CJK UNIFIED IDEOGRAPH + {0xCCF6, 0x8FE2}, //13026 #CJK UNIFIED IDEOGRAPH + {0xCCF7, 0x773A}, //13027 #CJK UNIFIED IDEOGRAPH + {0xCCF8, 0x8DF3}, //13028 #CJK UNIFIED IDEOGRAPH + {0xCCF9, 0x8D34}, //13029 #CJK UNIFIED IDEOGRAPH + {0xCCFA, 0x94C1}, //13030 #CJK UNIFIED IDEOGRAPH + {0xCCFB, 0x5E16}, //13031 #CJK UNIFIED IDEOGRAPH + {0xCCFC, 0x5385}, //13032 #CJK UNIFIED IDEOGRAPH + {0xCCFD, 0x542C}, //13033 #CJK UNIFIED IDEOGRAPH + {0xCCFE, 0x70C3}, //13034 #CJK UNIFIED IDEOGRAPH + {0xCD40, 0x866D}, //13035 #CJK UNIFIED IDEOGRAPH + {0xCD41, 0x866F}, //13036 #CJK UNIFIED IDEOGRAPH + {0xCD42, 0x8670}, //13037 #CJK UNIFIED IDEOGRAPH + {0xCD43, 0x8672}, //13038 #CJK UNIFIED IDEOGRAPH + {0xCD44, 0x8673}, //13039 #CJK UNIFIED IDEOGRAPH + {0xCD45, 0x8674}, //13040 #CJK UNIFIED IDEOGRAPH + {0xCD46, 0x8675}, //13041 #CJK UNIFIED IDEOGRAPH + {0xCD47, 0x8676}, //13042 #CJK UNIFIED IDEOGRAPH + {0xCD48, 0x8677}, //13043 #CJK UNIFIED IDEOGRAPH + {0xCD49, 0x8678}, //13044 #CJK UNIFIED IDEOGRAPH + {0xCD4A, 0x8683}, //13045 #CJK UNIFIED IDEOGRAPH + {0xCD4B, 0x8684}, //13046 #CJK UNIFIED IDEOGRAPH + {0xCD4C, 0x8685}, //13047 #CJK UNIFIED IDEOGRAPH + {0xCD4D, 0x8686}, //13048 #CJK UNIFIED IDEOGRAPH + {0xCD4E, 0x8687}, //13049 #CJK UNIFIED IDEOGRAPH + {0xCD4F, 0x8688}, //13050 #CJK UNIFIED IDEOGRAPH + {0xCD50, 0x8689}, //13051 #CJK UNIFIED IDEOGRAPH + {0xCD51, 0x868E}, //13052 #CJK UNIFIED IDEOGRAPH + {0xCD52, 0x868F}, //13053 #CJK UNIFIED IDEOGRAPH + {0xCD53, 0x8690}, //13054 #CJK UNIFIED IDEOGRAPH + {0xCD54, 0x8691}, //13055 #CJK UNIFIED IDEOGRAPH + {0xCD55, 0x8692}, //13056 #CJK UNIFIED IDEOGRAPH + {0xCD56, 0x8694}, //13057 #CJK UNIFIED IDEOGRAPH + {0xCD57, 0x8696}, //13058 #CJK UNIFIED IDEOGRAPH + {0xCD58, 0x8697}, //13059 #CJK UNIFIED IDEOGRAPH + {0xCD59, 0x8698}, //13060 #CJK UNIFIED IDEOGRAPH + {0xCD5A, 0x8699}, //13061 #CJK UNIFIED IDEOGRAPH + {0xCD5B, 0x869A}, //13062 #CJK UNIFIED IDEOGRAPH + {0xCD5C, 0x869B}, //13063 #CJK UNIFIED IDEOGRAPH + {0xCD5D, 0x869E}, //13064 #CJK UNIFIED IDEOGRAPH + {0xCD5E, 0x869F}, //13065 #CJK UNIFIED IDEOGRAPH + {0xCD5F, 0x86A0}, //13066 #CJK UNIFIED IDEOGRAPH + {0xCD60, 0x86A1}, //13067 #CJK UNIFIED IDEOGRAPH + {0xCD61, 0x86A2}, //13068 #CJK UNIFIED IDEOGRAPH + {0xCD62, 0x86A5}, //13069 #CJK UNIFIED IDEOGRAPH + {0xCD63, 0x86A6}, //13070 #CJK UNIFIED IDEOGRAPH + {0xCD64, 0x86AB}, //13071 #CJK UNIFIED IDEOGRAPH + {0xCD65, 0x86AD}, //13072 #CJK UNIFIED IDEOGRAPH + {0xCD66, 0x86AE}, //13073 #CJK UNIFIED IDEOGRAPH + {0xCD67, 0x86B2}, //13074 #CJK UNIFIED IDEOGRAPH + {0xCD68, 0x86B3}, //13075 #CJK UNIFIED IDEOGRAPH + {0xCD69, 0x86B7}, //13076 #CJK UNIFIED IDEOGRAPH + {0xCD6A, 0x86B8}, //13077 #CJK UNIFIED IDEOGRAPH + {0xCD6B, 0x86B9}, //13078 #CJK UNIFIED IDEOGRAPH + {0xCD6C, 0x86BB}, //13079 #CJK UNIFIED IDEOGRAPH + {0xCD6D, 0x86BC}, //13080 #CJK UNIFIED IDEOGRAPH + {0xCD6E, 0x86BD}, //13081 #CJK UNIFIED IDEOGRAPH + {0xCD6F, 0x86BE}, //13082 #CJK UNIFIED IDEOGRAPH + {0xCD70, 0x86BF}, //13083 #CJK UNIFIED IDEOGRAPH + {0xCD71, 0x86C1}, //13084 #CJK UNIFIED IDEOGRAPH + {0xCD72, 0x86C2}, //13085 #CJK UNIFIED IDEOGRAPH + {0xCD73, 0x86C3}, //13086 #CJK UNIFIED IDEOGRAPH + {0xCD74, 0x86C5}, //13087 #CJK UNIFIED IDEOGRAPH + {0xCD75, 0x86C8}, //13088 #CJK UNIFIED IDEOGRAPH + {0xCD76, 0x86CC}, //13089 #CJK UNIFIED IDEOGRAPH + {0xCD77, 0x86CD}, //13090 #CJK UNIFIED IDEOGRAPH + {0xCD78, 0x86D2}, //13091 #CJK UNIFIED IDEOGRAPH + {0xCD79, 0x86D3}, //13092 #CJK UNIFIED IDEOGRAPH + {0xCD7A, 0x86D5}, //13093 #CJK UNIFIED IDEOGRAPH + {0xCD7B, 0x86D6}, //13094 #CJK UNIFIED IDEOGRAPH + {0xCD7C, 0x86D7}, //13095 #CJK UNIFIED IDEOGRAPH + {0xCD7D, 0x86DA}, //13096 #CJK UNIFIED IDEOGRAPH + {0xCD7E, 0x86DC}, //13097 #CJK UNIFIED IDEOGRAPH + {0xCD80, 0x86DD}, //13098 #CJK UNIFIED IDEOGRAPH + {0xCD81, 0x86E0}, //13099 #CJK UNIFIED IDEOGRAPH + {0xCD82, 0x86E1}, //13100 #CJK UNIFIED IDEOGRAPH + {0xCD83, 0x86E2}, //13101 #CJK UNIFIED IDEOGRAPH + {0xCD84, 0x86E3}, //13102 #CJK UNIFIED IDEOGRAPH + {0xCD85, 0x86E5}, //13103 #CJK UNIFIED IDEOGRAPH + {0xCD86, 0x86E6}, //13104 #CJK UNIFIED IDEOGRAPH + {0xCD87, 0x86E7}, //13105 #CJK UNIFIED IDEOGRAPH + {0xCD88, 0x86E8}, //13106 #CJK UNIFIED IDEOGRAPH + {0xCD89, 0x86EA}, //13107 #CJK UNIFIED IDEOGRAPH + {0xCD8A, 0x86EB}, //13108 #CJK UNIFIED IDEOGRAPH + {0xCD8B, 0x86EC}, //13109 #CJK UNIFIED IDEOGRAPH + {0xCD8C, 0x86EF}, //13110 #CJK UNIFIED IDEOGRAPH + {0xCD8D, 0x86F5}, //13111 #CJK UNIFIED IDEOGRAPH + {0xCD8E, 0x86F6}, //13112 #CJK UNIFIED IDEOGRAPH + {0xCD8F, 0x86F7}, //13113 #CJK UNIFIED IDEOGRAPH + {0xCD90, 0x86FA}, //13114 #CJK UNIFIED IDEOGRAPH + {0xCD91, 0x86FB}, //13115 #CJK UNIFIED IDEOGRAPH + {0xCD92, 0x86FC}, //13116 #CJK UNIFIED IDEOGRAPH + {0xCD93, 0x86FD}, //13117 #CJK UNIFIED IDEOGRAPH + {0xCD94, 0x86FF}, //13118 #CJK UNIFIED IDEOGRAPH + {0xCD95, 0x8701}, //13119 #CJK UNIFIED IDEOGRAPH + {0xCD96, 0x8704}, //13120 #CJK UNIFIED IDEOGRAPH + {0xCD97, 0x8705}, //13121 #CJK UNIFIED IDEOGRAPH + {0xCD98, 0x8706}, //13122 #CJK UNIFIED IDEOGRAPH + {0xCD99, 0x870B}, //13123 #CJK UNIFIED IDEOGRAPH + {0xCD9A, 0x870C}, //13124 #CJK UNIFIED IDEOGRAPH + {0xCD9B, 0x870E}, //13125 #CJK UNIFIED IDEOGRAPH + {0xCD9C, 0x870F}, //13126 #CJK UNIFIED IDEOGRAPH + {0xCD9D, 0x8710}, //13127 #CJK UNIFIED IDEOGRAPH + {0xCD9E, 0x8711}, //13128 #CJK UNIFIED IDEOGRAPH + {0xCD9F, 0x8714}, //13129 #CJK UNIFIED IDEOGRAPH + {0xCDA0, 0x8716}, //13130 #CJK UNIFIED IDEOGRAPH + {0xCDA1, 0x6C40}, //13131 #CJK UNIFIED IDEOGRAPH + {0xCDA2, 0x5EF7}, //13132 #CJK UNIFIED IDEOGRAPH + {0xCDA3, 0x505C}, //13133 #CJK UNIFIED IDEOGRAPH + {0xCDA4, 0x4EAD}, //13134 #CJK UNIFIED IDEOGRAPH + {0xCDA5, 0x5EAD}, //13135 #CJK UNIFIED IDEOGRAPH + {0xCDA6, 0x633A}, //13136 #CJK UNIFIED IDEOGRAPH + {0xCDA7, 0x8247}, //13137 #CJK UNIFIED IDEOGRAPH + {0xCDA8, 0x901A}, //13138 #CJK UNIFIED IDEOGRAPH + {0xCDA9, 0x6850}, //13139 #CJK UNIFIED IDEOGRAPH + {0xCDAA, 0x916E}, //13140 #CJK UNIFIED IDEOGRAPH + {0xCDAB, 0x77B3}, //13141 #CJK UNIFIED IDEOGRAPH + {0xCDAC, 0x540C}, //13142 #CJK UNIFIED IDEOGRAPH + {0xCDAD, 0x94DC}, //13143 #CJK UNIFIED IDEOGRAPH + {0xCDAE, 0x5F64}, //13144 #CJK UNIFIED IDEOGRAPH + {0xCDAF, 0x7AE5}, //13145 #CJK UNIFIED IDEOGRAPH + {0xCDB0, 0x6876}, //13146 #CJK UNIFIED IDEOGRAPH + {0xCDB1, 0x6345}, //13147 #CJK UNIFIED IDEOGRAPH + {0xCDB2, 0x7B52}, //13148 #CJK UNIFIED IDEOGRAPH + {0xCDB3, 0x7EDF}, //13149 #CJK UNIFIED IDEOGRAPH + {0xCDB4, 0x75DB}, //13150 #CJK UNIFIED IDEOGRAPH + {0xCDB5, 0x5077}, //13151 #CJK UNIFIED IDEOGRAPH + {0xCDB6, 0x6295}, //13152 #CJK UNIFIED IDEOGRAPH + {0xCDB7, 0x5934}, //13153 #CJK UNIFIED IDEOGRAPH + {0xCDB8, 0x900F}, //13154 #CJK UNIFIED IDEOGRAPH + {0xCDB9, 0x51F8}, //13155 #CJK UNIFIED IDEOGRAPH + {0xCDBA, 0x79C3}, //13156 #CJK UNIFIED IDEOGRAPH + {0xCDBB, 0x7A81}, //13157 #CJK UNIFIED IDEOGRAPH + {0xCDBC, 0x56FE}, //13158 #CJK UNIFIED IDEOGRAPH + {0xCDBD, 0x5F92}, //13159 #CJK UNIFIED IDEOGRAPH + {0xCDBE, 0x9014}, //13160 #CJK UNIFIED IDEOGRAPH + {0xCDBF, 0x6D82}, //13161 #CJK UNIFIED IDEOGRAPH + {0xCDC0, 0x5C60}, //13162 #CJK UNIFIED IDEOGRAPH + {0xCDC1, 0x571F}, //13163 #CJK UNIFIED IDEOGRAPH + {0xCDC2, 0x5410}, //13164 #CJK UNIFIED IDEOGRAPH + {0xCDC3, 0x5154}, //13165 #CJK UNIFIED IDEOGRAPH + {0xCDC4, 0x6E4D}, //13166 #CJK UNIFIED IDEOGRAPH + {0xCDC5, 0x56E2}, //13167 #CJK UNIFIED IDEOGRAPH + {0xCDC6, 0x63A8}, //13168 #CJK UNIFIED IDEOGRAPH + {0xCDC7, 0x9893}, //13169 #CJK UNIFIED IDEOGRAPH + {0xCDC8, 0x817F}, //13170 #CJK UNIFIED IDEOGRAPH + {0xCDC9, 0x8715}, //13171 #CJK UNIFIED IDEOGRAPH + {0xCDCA, 0x892A}, //13172 #CJK UNIFIED IDEOGRAPH + {0xCDCB, 0x9000}, //13173 #CJK UNIFIED IDEOGRAPH + {0xCDCC, 0x541E}, //13174 #CJK UNIFIED IDEOGRAPH + {0xCDCD, 0x5C6F}, //13175 #CJK UNIFIED IDEOGRAPH + {0xCDCE, 0x81C0}, //13176 #CJK UNIFIED IDEOGRAPH + {0xCDCF, 0x62D6}, //13177 #CJK UNIFIED IDEOGRAPH + {0xCDD0, 0x6258}, //13178 #CJK UNIFIED IDEOGRAPH + {0xCDD1, 0x8131}, //13179 #CJK UNIFIED IDEOGRAPH + {0xCDD2, 0x9E35}, //13180 #CJK UNIFIED IDEOGRAPH + {0xCDD3, 0x9640}, //13181 #CJK UNIFIED IDEOGRAPH + {0xCDD4, 0x9A6E}, //13182 #CJK UNIFIED IDEOGRAPH + {0xCDD5, 0x9A7C}, //13183 #CJK UNIFIED IDEOGRAPH + {0xCDD6, 0x692D}, //13184 #CJK UNIFIED IDEOGRAPH + {0xCDD7, 0x59A5}, //13185 #CJK UNIFIED IDEOGRAPH + {0xCDD8, 0x62D3}, //13186 #CJK UNIFIED IDEOGRAPH + {0xCDD9, 0x553E}, //13187 #CJK UNIFIED IDEOGRAPH + {0xCDDA, 0x6316}, //13188 #CJK UNIFIED IDEOGRAPH + {0xCDDB, 0x54C7}, //13189 #CJK UNIFIED IDEOGRAPH + {0xCDDC, 0x86D9}, //13190 #CJK UNIFIED IDEOGRAPH + {0xCDDD, 0x6D3C}, //13191 #CJK UNIFIED IDEOGRAPH + {0xCDDE, 0x5A03}, //13192 #CJK UNIFIED IDEOGRAPH + {0xCDDF, 0x74E6}, //13193 #CJK UNIFIED IDEOGRAPH + {0xCDE0, 0x889C}, //13194 #CJK UNIFIED IDEOGRAPH + {0xCDE1, 0x6B6A}, //13195 #CJK UNIFIED IDEOGRAPH + {0xCDE2, 0x5916}, //13196 #CJK UNIFIED IDEOGRAPH + {0xCDE3, 0x8C4C}, //13197 #CJK UNIFIED IDEOGRAPH + {0xCDE4, 0x5F2F}, //13198 #CJK UNIFIED IDEOGRAPH + {0xCDE5, 0x6E7E}, //13199 #CJK UNIFIED IDEOGRAPH + {0xCDE6, 0x73A9}, //13200 #CJK UNIFIED IDEOGRAPH + {0xCDE7, 0x987D}, //13201 #CJK UNIFIED IDEOGRAPH + {0xCDE8, 0x4E38}, //13202 #CJK UNIFIED IDEOGRAPH + {0xCDE9, 0x70F7}, //13203 #CJK UNIFIED IDEOGRAPH + {0xCDEA, 0x5B8C}, //13204 #CJK UNIFIED IDEOGRAPH + {0xCDEB, 0x7897}, //13205 #CJK UNIFIED IDEOGRAPH + {0xCDEC, 0x633D}, //13206 #CJK UNIFIED IDEOGRAPH + {0xCDED, 0x665A}, //13207 #CJK UNIFIED IDEOGRAPH + {0xCDEE, 0x7696}, //13208 #CJK UNIFIED IDEOGRAPH + {0xCDEF, 0x60CB}, //13209 #CJK UNIFIED IDEOGRAPH + {0xCDF0, 0x5B9B}, //13210 #CJK UNIFIED IDEOGRAPH + {0xCDF1, 0x5A49}, //13211 #CJK UNIFIED IDEOGRAPH + {0xCDF2, 0x4E07}, //13212 #CJK UNIFIED IDEOGRAPH + {0xCDF3, 0x8155}, //13213 #CJK UNIFIED IDEOGRAPH + {0xCDF4, 0x6C6A}, //13214 #CJK UNIFIED IDEOGRAPH + {0xCDF5, 0x738B}, //13215 #CJK UNIFIED IDEOGRAPH + {0xCDF6, 0x4EA1}, //13216 #CJK UNIFIED IDEOGRAPH + {0xCDF7, 0x6789}, //13217 #CJK UNIFIED IDEOGRAPH + {0xCDF8, 0x7F51}, //13218 #CJK UNIFIED IDEOGRAPH + {0xCDF9, 0x5F80}, //13219 #CJK UNIFIED IDEOGRAPH + {0xCDFA, 0x65FA}, //13220 #CJK UNIFIED IDEOGRAPH + {0xCDFB, 0x671B}, //13221 #CJK UNIFIED IDEOGRAPH + {0xCDFC, 0x5FD8}, //13222 #CJK UNIFIED IDEOGRAPH + {0xCDFD, 0x5984}, //13223 #CJK UNIFIED IDEOGRAPH + {0xCDFE, 0x5A01}, //13224 #CJK UNIFIED IDEOGRAPH + {0xCE40, 0x8719}, //13225 #CJK UNIFIED IDEOGRAPH + {0xCE41, 0x871B}, //13226 #CJK UNIFIED IDEOGRAPH + {0xCE42, 0x871D}, //13227 #CJK UNIFIED IDEOGRAPH + {0xCE43, 0x871F}, //13228 #CJK UNIFIED IDEOGRAPH + {0xCE44, 0x8720}, //13229 #CJK UNIFIED IDEOGRAPH + {0xCE45, 0x8724}, //13230 #CJK UNIFIED IDEOGRAPH + {0xCE46, 0x8726}, //13231 #CJK UNIFIED IDEOGRAPH + {0xCE47, 0x8727}, //13232 #CJK UNIFIED IDEOGRAPH + {0xCE48, 0x8728}, //13233 #CJK UNIFIED IDEOGRAPH + {0xCE49, 0x872A}, //13234 #CJK UNIFIED IDEOGRAPH + {0xCE4A, 0x872B}, //13235 #CJK UNIFIED IDEOGRAPH + {0xCE4B, 0x872C}, //13236 #CJK UNIFIED IDEOGRAPH + {0xCE4C, 0x872D}, //13237 #CJK UNIFIED IDEOGRAPH + {0xCE4D, 0x872F}, //13238 #CJK UNIFIED IDEOGRAPH + {0xCE4E, 0x8730}, //13239 #CJK UNIFIED IDEOGRAPH + {0xCE4F, 0x8732}, //13240 #CJK UNIFIED IDEOGRAPH + {0xCE50, 0x8733}, //13241 #CJK UNIFIED IDEOGRAPH + {0xCE51, 0x8735}, //13242 #CJK UNIFIED IDEOGRAPH + {0xCE52, 0x8736}, //13243 #CJK UNIFIED IDEOGRAPH + {0xCE53, 0x8738}, //13244 #CJK UNIFIED IDEOGRAPH + {0xCE54, 0x8739}, //13245 #CJK UNIFIED IDEOGRAPH + {0xCE55, 0x873A}, //13246 #CJK UNIFIED IDEOGRAPH + {0xCE56, 0x873C}, //13247 #CJK UNIFIED IDEOGRAPH + {0xCE57, 0x873D}, //13248 #CJK UNIFIED IDEOGRAPH + {0xCE58, 0x8740}, //13249 #CJK UNIFIED IDEOGRAPH + {0xCE59, 0x8741}, //13250 #CJK UNIFIED IDEOGRAPH + {0xCE5A, 0x8742}, //13251 #CJK UNIFIED IDEOGRAPH + {0xCE5B, 0x8743}, //13252 #CJK UNIFIED IDEOGRAPH + {0xCE5C, 0x8744}, //13253 #CJK UNIFIED IDEOGRAPH + {0xCE5D, 0x8745}, //13254 #CJK UNIFIED IDEOGRAPH + {0xCE5E, 0x8746}, //13255 #CJK UNIFIED IDEOGRAPH + {0xCE5F, 0x874A}, //13256 #CJK UNIFIED IDEOGRAPH + {0xCE60, 0x874B}, //13257 #CJK UNIFIED IDEOGRAPH + {0xCE61, 0x874D}, //13258 #CJK UNIFIED IDEOGRAPH + {0xCE62, 0x874F}, //13259 #CJK UNIFIED IDEOGRAPH + {0xCE63, 0x8750}, //13260 #CJK UNIFIED IDEOGRAPH + {0xCE64, 0x8751}, //13261 #CJK UNIFIED IDEOGRAPH + {0xCE65, 0x8752}, //13262 #CJK UNIFIED IDEOGRAPH + {0xCE66, 0x8754}, //13263 #CJK UNIFIED IDEOGRAPH + {0xCE67, 0x8755}, //13264 #CJK UNIFIED IDEOGRAPH + {0xCE68, 0x8756}, //13265 #CJK UNIFIED IDEOGRAPH + {0xCE69, 0x8758}, //13266 #CJK UNIFIED IDEOGRAPH + {0xCE6A, 0x875A}, //13267 #CJK UNIFIED IDEOGRAPH + {0xCE6B, 0x875B}, //13268 #CJK UNIFIED IDEOGRAPH + {0xCE6C, 0x875C}, //13269 #CJK UNIFIED IDEOGRAPH + {0xCE6D, 0x875D}, //13270 #CJK UNIFIED IDEOGRAPH + {0xCE6E, 0x875E}, //13271 #CJK UNIFIED IDEOGRAPH + {0xCE6F, 0x875F}, //13272 #CJK UNIFIED IDEOGRAPH + {0xCE70, 0x8761}, //13273 #CJK UNIFIED IDEOGRAPH + {0xCE71, 0x8762}, //13274 #CJK UNIFIED IDEOGRAPH + {0xCE72, 0x8766}, //13275 #CJK UNIFIED IDEOGRAPH + {0xCE73, 0x8767}, //13276 #CJK UNIFIED IDEOGRAPH + {0xCE74, 0x8768}, //13277 #CJK UNIFIED IDEOGRAPH + {0xCE75, 0x8769}, //13278 #CJK UNIFIED IDEOGRAPH + {0xCE76, 0x876A}, //13279 #CJK UNIFIED IDEOGRAPH + {0xCE77, 0x876B}, //13280 #CJK UNIFIED IDEOGRAPH + {0xCE78, 0x876C}, //13281 #CJK UNIFIED IDEOGRAPH + {0xCE79, 0x876D}, //13282 #CJK UNIFIED IDEOGRAPH + {0xCE7A, 0x876F}, //13283 #CJK UNIFIED IDEOGRAPH + {0xCE7B, 0x8771}, //13284 #CJK UNIFIED IDEOGRAPH + {0xCE7C, 0x8772}, //13285 #CJK UNIFIED IDEOGRAPH + {0xCE7D, 0x8773}, //13286 #CJK UNIFIED IDEOGRAPH + {0xCE7E, 0x8775}, //13287 #CJK UNIFIED IDEOGRAPH + {0xCE80, 0x8777}, //13288 #CJK UNIFIED IDEOGRAPH + {0xCE81, 0x8778}, //13289 #CJK UNIFIED IDEOGRAPH + {0xCE82, 0x8779}, //13290 #CJK UNIFIED IDEOGRAPH + {0xCE83, 0x877A}, //13291 #CJK UNIFIED IDEOGRAPH + {0xCE84, 0x877F}, //13292 #CJK UNIFIED IDEOGRAPH + {0xCE85, 0x8780}, //13293 #CJK UNIFIED IDEOGRAPH + {0xCE86, 0x8781}, //13294 #CJK UNIFIED IDEOGRAPH + {0xCE87, 0x8784}, //13295 #CJK UNIFIED IDEOGRAPH + {0xCE88, 0x8786}, //13296 #CJK UNIFIED IDEOGRAPH + {0xCE89, 0x8787}, //13297 #CJK UNIFIED IDEOGRAPH + {0xCE8A, 0x8789}, //13298 #CJK UNIFIED IDEOGRAPH + {0xCE8B, 0x878A}, //13299 #CJK UNIFIED IDEOGRAPH + {0xCE8C, 0x878C}, //13300 #CJK UNIFIED IDEOGRAPH + {0xCE8D, 0x878E}, //13301 #CJK UNIFIED IDEOGRAPH + {0xCE8E, 0x878F}, //13302 #CJK UNIFIED IDEOGRAPH + {0xCE8F, 0x8790}, //13303 #CJK UNIFIED IDEOGRAPH + {0xCE90, 0x8791}, //13304 #CJK UNIFIED IDEOGRAPH + {0xCE91, 0x8792}, //13305 #CJK UNIFIED IDEOGRAPH + {0xCE92, 0x8794}, //13306 #CJK UNIFIED IDEOGRAPH + {0xCE93, 0x8795}, //13307 #CJK UNIFIED IDEOGRAPH + {0xCE94, 0x8796}, //13308 #CJK UNIFIED IDEOGRAPH + {0xCE95, 0x8798}, //13309 #CJK UNIFIED IDEOGRAPH + {0xCE96, 0x8799}, //13310 #CJK UNIFIED IDEOGRAPH + {0xCE97, 0x879A}, //13311 #CJK UNIFIED IDEOGRAPH + {0xCE98, 0x879B}, //13312 #CJK UNIFIED IDEOGRAPH + {0xCE99, 0x879C}, //13313 #CJK UNIFIED IDEOGRAPH + {0xCE9A, 0x879D}, //13314 #CJK UNIFIED IDEOGRAPH + {0xCE9B, 0x879E}, //13315 #CJK UNIFIED IDEOGRAPH + {0xCE9C, 0x87A0}, //13316 #CJK UNIFIED IDEOGRAPH + {0xCE9D, 0x87A1}, //13317 #CJK UNIFIED IDEOGRAPH + {0xCE9E, 0x87A2}, //13318 #CJK UNIFIED IDEOGRAPH + {0xCE9F, 0x87A3}, //13319 #CJK UNIFIED IDEOGRAPH + {0xCEA0, 0x87A4}, //13320 #CJK UNIFIED IDEOGRAPH + {0xCEA1, 0x5DCD}, //13321 #CJK UNIFIED IDEOGRAPH + {0xCEA2, 0x5FAE}, //13322 #CJK UNIFIED IDEOGRAPH + {0xCEA3, 0x5371}, //13323 #CJK UNIFIED IDEOGRAPH + {0xCEA4, 0x97E6}, //13324 #CJK UNIFIED IDEOGRAPH + {0xCEA5, 0x8FDD}, //13325 #CJK UNIFIED IDEOGRAPH + {0xCEA6, 0x6845}, //13326 #CJK UNIFIED IDEOGRAPH + {0xCEA7, 0x56F4}, //13327 #CJK UNIFIED IDEOGRAPH + {0xCEA8, 0x552F}, //13328 #CJK UNIFIED IDEOGRAPH + {0xCEA9, 0x60DF}, //13329 #CJK UNIFIED IDEOGRAPH + {0xCEAA, 0x4E3A}, //13330 #CJK UNIFIED IDEOGRAPH + {0xCEAB, 0x6F4D}, //13331 #CJK UNIFIED IDEOGRAPH + {0xCEAC, 0x7EF4}, //13332 #CJK UNIFIED IDEOGRAPH + {0xCEAD, 0x82C7}, //13333 #CJK UNIFIED IDEOGRAPH + {0xCEAE, 0x840E}, //13334 #CJK UNIFIED IDEOGRAPH + {0xCEAF, 0x59D4}, //13335 #CJK UNIFIED IDEOGRAPH + {0xCEB0, 0x4F1F}, //13336 #CJK UNIFIED IDEOGRAPH + {0xCEB1, 0x4F2A}, //13337 #CJK UNIFIED IDEOGRAPH + {0xCEB2, 0x5C3E}, //13338 #CJK UNIFIED IDEOGRAPH + {0xCEB3, 0x7EAC}, //13339 #CJK UNIFIED IDEOGRAPH + {0xCEB4, 0x672A}, //13340 #CJK UNIFIED IDEOGRAPH + {0xCEB5, 0x851A}, //13341 #CJK UNIFIED IDEOGRAPH + {0xCEB6, 0x5473}, //13342 #CJK UNIFIED IDEOGRAPH + {0xCEB7, 0x754F}, //13343 #CJK UNIFIED IDEOGRAPH + {0xCEB8, 0x80C3}, //13344 #CJK UNIFIED IDEOGRAPH + {0xCEB9, 0x5582}, //13345 #CJK UNIFIED IDEOGRAPH + {0xCEBA, 0x9B4F}, //13346 #CJK UNIFIED IDEOGRAPH + {0xCEBB, 0x4F4D}, //13347 #CJK UNIFIED IDEOGRAPH + {0xCEBC, 0x6E2D}, //13348 #CJK UNIFIED IDEOGRAPH + {0xCEBD, 0x8C13}, //13349 #CJK UNIFIED IDEOGRAPH + {0xCEBE, 0x5C09}, //13350 #CJK UNIFIED IDEOGRAPH + {0xCEBF, 0x6170}, //13351 #CJK UNIFIED IDEOGRAPH + {0xCEC0, 0x536B}, //13352 #CJK UNIFIED IDEOGRAPH + {0xCEC1, 0x761F}, //13353 #CJK UNIFIED IDEOGRAPH + {0xCEC2, 0x6E29}, //13354 #CJK UNIFIED IDEOGRAPH + {0xCEC3, 0x868A}, //13355 #CJK UNIFIED IDEOGRAPH + {0xCEC4, 0x6587}, //13356 #CJK UNIFIED IDEOGRAPH + {0xCEC5, 0x95FB}, //13357 #CJK UNIFIED IDEOGRAPH + {0xCEC6, 0x7EB9}, //13358 #CJK UNIFIED IDEOGRAPH + {0xCEC7, 0x543B}, //13359 #CJK UNIFIED IDEOGRAPH + {0xCEC8, 0x7A33}, //13360 #CJK UNIFIED IDEOGRAPH + {0xCEC9, 0x7D0A}, //13361 #CJK UNIFIED IDEOGRAPH + {0xCECA, 0x95EE}, //13362 #CJK UNIFIED IDEOGRAPH + {0xCECB, 0x55E1}, //13363 #CJK UNIFIED IDEOGRAPH + {0xCECC, 0x7FC1}, //13364 #CJK UNIFIED IDEOGRAPH + {0xCECD, 0x74EE}, //13365 #CJK UNIFIED IDEOGRAPH + {0xCECE, 0x631D}, //13366 #CJK UNIFIED IDEOGRAPH + {0xCECF, 0x8717}, //13367 #CJK UNIFIED IDEOGRAPH + {0xCED0, 0x6DA1}, //13368 #CJK UNIFIED IDEOGRAPH + {0xCED1, 0x7A9D}, //13369 #CJK UNIFIED IDEOGRAPH + {0xCED2, 0x6211}, //13370 #CJK UNIFIED IDEOGRAPH + {0xCED3, 0x65A1}, //13371 #CJK UNIFIED IDEOGRAPH + {0xCED4, 0x5367}, //13372 #CJK UNIFIED IDEOGRAPH + {0xCED5, 0x63E1}, //13373 #CJK UNIFIED IDEOGRAPH + {0xCED6, 0x6C83}, //13374 #CJK UNIFIED IDEOGRAPH + {0xCED7, 0x5DEB}, //13375 #CJK UNIFIED IDEOGRAPH + {0xCED8, 0x545C}, //13376 #CJK UNIFIED IDEOGRAPH + {0xCED9, 0x94A8}, //13377 #CJK UNIFIED IDEOGRAPH + {0xCEDA, 0x4E4C}, //13378 #CJK UNIFIED IDEOGRAPH + {0xCEDB, 0x6C61}, //13379 #CJK UNIFIED IDEOGRAPH + {0xCEDC, 0x8BEC}, //13380 #CJK UNIFIED IDEOGRAPH + {0xCEDD, 0x5C4B}, //13381 #CJK UNIFIED IDEOGRAPH + {0xCEDE, 0x65E0}, //13382 #CJK UNIFIED IDEOGRAPH + {0xCEDF, 0x829C}, //13383 #CJK UNIFIED IDEOGRAPH + {0xCEE0, 0x68A7}, //13384 #CJK UNIFIED IDEOGRAPH + {0xCEE1, 0x543E}, //13385 #CJK UNIFIED IDEOGRAPH + {0xCEE2, 0x5434}, //13386 #CJK UNIFIED IDEOGRAPH + {0xCEE3, 0x6BCB}, //13387 #CJK UNIFIED IDEOGRAPH + {0xCEE4, 0x6B66}, //13388 #CJK UNIFIED IDEOGRAPH + {0xCEE5, 0x4E94}, //13389 #CJK UNIFIED IDEOGRAPH + {0xCEE6, 0x6342}, //13390 #CJK UNIFIED IDEOGRAPH + {0xCEE7, 0x5348}, //13391 #CJK UNIFIED IDEOGRAPH + {0xCEE8, 0x821E}, //13392 #CJK UNIFIED IDEOGRAPH + {0xCEE9, 0x4F0D}, //13393 #CJK UNIFIED IDEOGRAPH + {0xCEEA, 0x4FAE}, //13394 #CJK UNIFIED IDEOGRAPH + {0xCEEB, 0x575E}, //13395 #CJK UNIFIED IDEOGRAPH + {0xCEEC, 0x620A}, //13396 #CJK UNIFIED IDEOGRAPH + {0xCEED, 0x96FE}, //13397 #CJK UNIFIED IDEOGRAPH + {0xCEEE, 0x6664}, //13398 #CJK UNIFIED IDEOGRAPH + {0xCEEF, 0x7269}, //13399 #CJK UNIFIED IDEOGRAPH + {0xCEF0, 0x52FF}, //13400 #CJK UNIFIED IDEOGRAPH + {0xCEF1, 0x52A1}, //13401 #CJK UNIFIED IDEOGRAPH + {0xCEF2, 0x609F}, //13402 #CJK UNIFIED IDEOGRAPH + {0xCEF3, 0x8BEF}, //13403 #CJK UNIFIED IDEOGRAPH + {0xCEF4, 0x6614}, //13404 #CJK UNIFIED IDEOGRAPH + {0xCEF5, 0x7199}, //13405 #CJK UNIFIED IDEOGRAPH + {0xCEF6, 0x6790}, //13406 #CJK UNIFIED IDEOGRAPH + {0xCEF7, 0x897F}, //13407 #CJK UNIFIED IDEOGRAPH + {0xCEF8, 0x7852}, //13408 #CJK UNIFIED IDEOGRAPH + {0xCEF9, 0x77FD}, //13409 #CJK UNIFIED IDEOGRAPH + {0xCEFA, 0x6670}, //13410 #CJK UNIFIED IDEOGRAPH + {0xCEFB, 0x563B}, //13411 #CJK UNIFIED IDEOGRAPH + {0xCEFC, 0x5438}, //13412 #CJK UNIFIED IDEOGRAPH + {0xCEFD, 0x9521}, //13413 #CJK UNIFIED IDEOGRAPH + {0xCEFE, 0x727A}, //13414 #CJK UNIFIED IDEOGRAPH + {0xCF40, 0x87A5}, //13415 #CJK UNIFIED IDEOGRAPH + {0xCF41, 0x87A6}, //13416 #CJK UNIFIED IDEOGRAPH + {0xCF42, 0x87A7}, //13417 #CJK UNIFIED IDEOGRAPH + {0xCF43, 0x87A9}, //13418 #CJK UNIFIED IDEOGRAPH + {0xCF44, 0x87AA}, //13419 #CJK UNIFIED IDEOGRAPH + {0xCF45, 0x87AE}, //13420 #CJK UNIFIED IDEOGRAPH + {0xCF46, 0x87B0}, //13421 #CJK UNIFIED IDEOGRAPH + {0xCF47, 0x87B1}, //13422 #CJK UNIFIED IDEOGRAPH + {0xCF48, 0x87B2}, //13423 #CJK UNIFIED IDEOGRAPH + {0xCF49, 0x87B4}, //13424 #CJK UNIFIED IDEOGRAPH + {0xCF4A, 0x87B6}, //13425 #CJK UNIFIED IDEOGRAPH + {0xCF4B, 0x87B7}, //13426 #CJK UNIFIED IDEOGRAPH + {0xCF4C, 0x87B8}, //13427 #CJK UNIFIED IDEOGRAPH + {0xCF4D, 0x87B9}, //13428 #CJK UNIFIED IDEOGRAPH + {0xCF4E, 0x87BB}, //13429 #CJK UNIFIED IDEOGRAPH + {0xCF4F, 0x87BC}, //13430 #CJK UNIFIED IDEOGRAPH + {0xCF50, 0x87BE}, //13431 #CJK UNIFIED IDEOGRAPH + {0xCF51, 0x87BF}, //13432 #CJK UNIFIED IDEOGRAPH + {0xCF52, 0x87C1}, //13433 #CJK UNIFIED IDEOGRAPH + {0xCF53, 0x87C2}, //13434 #CJK UNIFIED IDEOGRAPH + {0xCF54, 0x87C3}, //13435 #CJK UNIFIED IDEOGRAPH + {0xCF55, 0x87C4}, //13436 #CJK UNIFIED IDEOGRAPH + {0xCF56, 0x87C5}, //13437 #CJK UNIFIED IDEOGRAPH + {0xCF57, 0x87C7}, //13438 #CJK UNIFIED IDEOGRAPH + {0xCF58, 0x87C8}, //13439 #CJK UNIFIED IDEOGRAPH + {0xCF59, 0x87C9}, //13440 #CJK UNIFIED IDEOGRAPH + {0xCF5A, 0x87CC}, //13441 #CJK UNIFIED IDEOGRAPH + {0xCF5B, 0x87CD}, //13442 #CJK UNIFIED IDEOGRAPH + {0xCF5C, 0x87CE}, //13443 #CJK UNIFIED IDEOGRAPH + {0xCF5D, 0x87CF}, //13444 #CJK UNIFIED IDEOGRAPH + {0xCF5E, 0x87D0}, //13445 #CJK UNIFIED IDEOGRAPH + {0xCF5F, 0x87D4}, //13446 #CJK UNIFIED IDEOGRAPH + {0xCF60, 0x87D5}, //13447 #CJK UNIFIED IDEOGRAPH + {0xCF61, 0x87D6}, //13448 #CJK UNIFIED IDEOGRAPH + {0xCF62, 0x87D7}, //13449 #CJK UNIFIED IDEOGRAPH + {0xCF63, 0x87D8}, //13450 #CJK UNIFIED IDEOGRAPH + {0xCF64, 0x87D9}, //13451 #CJK UNIFIED IDEOGRAPH + {0xCF65, 0x87DA}, //13452 #CJK UNIFIED IDEOGRAPH + {0xCF66, 0x87DC}, //13453 #CJK UNIFIED IDEOGRAPH + {0xCF67, 0x87DD}, //13454 #CJK UNIFIED IDEOGRAPH + {0xCF68, 0x87DE}, //13455 #CJK UNIFIED IDEOGRAPH + {0xCF69, 0x87DF}, //13456 #CJK UNIFIED IDEOGRAPH + {0xCF6A, 0x87E1}, //13457 #CJK UNIFIED IDEOGRAPH + {0xCF6B, 0x87E2}, //13458 #CJK UNIFIED IDEOGRAPH + {0xCF6C, 0x87E3}, //13459 #CJK UNIFIED IDEOGRAPH + {0xCF6D, 0x87E4}, //13460 #CJK UNIFIED IDEOGRAPH + {0xCF6E, 0x87E6}, //13461 #CJK UNIFIED IDEOGRAPH + {0xCF6F, 0x87E7}, //13462 #CJK UNIFIED IDEOGRAPH + {0xCF70, 0x87E8}, //13463 #CJK UNIFIED IDEOGRAPH + {0xCF71, 0x87E9}, //13464 #CJK UNIFIED IDEOGRAPH + {0xCF72, 0x87EB}, //13465 #CJK UNIFIED IDEOGRAPH + {0xCF73, 0x87EC}, //13466 #CJK UNIFIED IDEOGRAPH + {0xCF74, 0x87ED}, //13467 #CJK UNIFIED IDEOGRAPH + {0xCF75, 0x87EF}, //13468 #CJK UNIFIED IDEOGRAPH + {0xCF76, 0x87F0}, //13469 #CJK UNIFIED IDEOGRAPH + {0xCF77, 0x87F1}, //13470 #CJK UNIFIED IDEOGRAPH + {0xCF78, 0x87F2}, //13471 #CJK UNIFIED IDEOGRAPH + {0xCF79, 0x87F3}, //13472 #CJK UNIFIED IDEOGRAPH + {0xCF7A, 0x87F4}, //13473 #CJK UNIFIED IDEOGRAPH + {0xCF7B, 0x87F5}, //13474 #CJK UNIFIED IDEOGRAPH + {0xCF7C, 0x87F6}, //13475 #CJK UNIFIED IDEOGRAPH + {0xCF7D, 0x87F7}, //13476 #CJK UNIFIED IDEOGRAPH + {0xCF7E, 0x87F8}, //13477 #CJK UNIFIED IDEOGRAPH + {0xCF80, 0x87FA}, //13478 #CJK UNIFIED IDEOGRAPH + {0xCF81, 0x87FB}, //13479 #CJK UNIFIED IDEOGRAPH + {0xCF82, 0x87FC}, //13480 #CJK UNIFIED IDEOGRAPH + {0xCF83, 0x87FD}, //13481 #CJK UNIFIED IDEOGRAPH + {0xCF84, 0x87FF}, //13482 #CJK UNIFIED IDEOGRAPH + {0xCF85, 0x8800}, //13483 #CJK UNIFIED IDEOGRAPH + {0xCF86, 0x8801}, //13484 #CJK UNIFIED IDEOGRAPH + {0xCF87, 0x8802}, //13485 #CJK UNIFIED IDEOGRAPH + {0xCF88, 0x8804}, //13486 #CJK UNIFIED IDEOGRAPH + {0xCF89, 0x8805}, //13487 #CJK UNIFIED IDEOGRAPH + {0xCF8A, 0x8806}, //13488 #CJK UNIFIED IDEOGRAPH + {0xCF8B, 0x8807}, //13489 #CJK UNIFIED IDEOGRAPH + {0xCF8C, 0x8808}, //13490 #CJK UNIFIED IDEOGRAPH + {0xCF8D, 0x8809}, //13491 #CJK UNIFIED IDEOGRAPH + {0xCF8E, 0x880B}, //13492 #CJK UNIFIED IDEOGRAPH + {0xCF8F, 0x880C}, //13493 #CJK UNIFIED IDEOGRAPH + {0xCF90, 0x880D}, //13494 #CJK UNIFIED IDEOGRAPH + {0xCF91, 0x880E}, //13495 #CJK UNIFIED IDEOGRAPH + {0xCF92, 0x880F}, //13496 #CJK UNIFIED IDEOGRAPH + {0xCF93, 0x8810}, //13497 #CJK UNIFIED IDEOGRAPH + {0xCF94, 0x8811}, //13498 #CJK UNIFIED IDEOGRAPH + {0xCF95, 0x8812}, //13499 #CJK UNIFIED IDEOGRAPH + {0xCF96, 0x8814}, //13500 #CJK UNIFIED IDEOGRAPH + {0xCF97, 0x8817}, //13501 #CJK UNIFIED IDEOGRAPH + {0xCF98, 0x8818}, //13502 #CJK UNIFIED IDEOGRAPH + {0xCF99, 0x8819}, //13503 #CJK UNIFIED IDEOGRAPH + {0xCF9A, 0x881A}, //13504 #CJK UNIFIED IDEOGRAPH + {0xCF9B, 0x881C}, //13505 #CJK UNIFIED IDEOGRAPH + {0xCF9C, 0x881D}, //13506 #CJK UNIFIED IDEOGRAPH + {0xCF9D, 0x881E}, //13507 #CJK UNIFIED IDEOGRAPH + {0xCF9E, 0x881F}, //13508 #CJK UNIFIED IDEOGRAPH + {0xCF9F, 0x8820}, //13509 #CJK UNIFIED IDEOGRAPH + {0xCFA0, 0x8823}, //13510 #CJK UNIFIED IDEOGRAPH + {0xCFA1, 0x7A00}, //13511 #CJK UNIFIED IDEOGRAPH + {0xCFA2, 0x606F}, //13512 #CJK UNIFIED IDEOGRAPH + {0xCFA3, 0x5E0C}, //13513 #CJK UNIFIED IDEOGRAPH + {0xCFA4, 0x6089}, //13514 #CJK UNIFIED IDEOGRAPH + {0xCFA5, 0x819D}, //13515 #CJK UNIFIED IDEOGRAPH + {0xCFA6, 0x5915}, //13516 #CJK UNIFIED IDEOGRAPH + {0xCFA7, 0x60DC}, //13517 #CJK UNIFIED IDEOGRAPH + {0xCFA8, 0x7184}, //13518 #CJK UNIFIED IDEOGRAPH + {0xCFA9, 0x70EF}, //13519 #CJK UNIFIED IDEOGRAPH + {0xCFAA, 0x6EAA}, //13520 #CJK UNIFIED IDEOGRAPH + {0xCFAB, 0x6C50}, //13521 #CJK UNIFIED IDEOGRAPH + {0xCFAC, 0x7280}, //13522 #CJK UNIFIED IDEOGRAPH + {0xCFAD, 0x6A84}, //13523 #CJK UNIFIED IDEOGRAPH + {0xCFAE, 0x88AD}, //13524 #CJK UNIFIED IDEOGRAPH + {0xCFAF, 0x5E2D}, //13525 #CJK UNIFIED IDEOGRAPH + {0xCFB0, 0x4E60}, //13526 #CJK UNIFIED IDEOGRAPH + {0xCFB1, 0x5AB3}, //13527 #CJK UNIFIED IDEOGRAPH + {0xCFB2, 0x559C}, //13528 #CJK UNIFIED IDEOGRAPH + {0xCFB3, 0x94E3}, //13529 #CJK UNIFIED IDEOGRAPH + {0xCFB4, 0x6D17}, //13530 #CJK UNIFIED IDEOGRAPH + {0xCFB5, 0x7CFB}, //13531 #CJK UNIFIED IDEOGRAPH + {0xCFB6, 0x9699}, //13532 #CJK UNIFIED IDEOGRAPH + {0xCFB7, 0x620F}, //13533 #CJK UNIFIED IDEOGRAPH + {0xCFB8, 0x7EC6}, //13534 #CJK UNIFIED IDEOGRAPH + {0xCFB9, 0x778E}, //13535 #CJK UNIFIED IDEOGRAPH + {0xCFBA, 0x867E}, //13536 #CJK UNIFIED IDEOGRAPH + {0xCFBB, 0x5323}, //13537 #CJK UNIFIED IDEOGRAPH + {0xCFBC, 0x971E}, //13538 #CJK UNIFIED IDEOGRAPH + {0xCFBD, 0x8F96}, //13539 #CJK UNIFIED IDEOGRAPH + {0xCFBE, 0x6687}, //13540 #CJK UNIFIED IDEOGRAPH + {0xCFBF, 0x5CE1}, //13541 #CJK UNIFIED IDEOGRAPH + {0xCFC0, 0x4FA0}, //13542 #CJK UNIFIED IDEOGRAPH + {0xCFC1, 0x72ED}, //13543 #CJK UNIFIED IDEOGRAPH + {0xCFC2, 0x4E0B}, //13544 #CJK UNIFIED IDEOGRAPH + {0xCFC3, 0x53A6}, //13545 #CJK UNIFIED IDEOGRAPH + {0xCFC4, 0x590F}, //13546 #CJK UNIFIED IDEOGRAPH + {0xCFC5, 0x5413}, //13547 #CJK UNIFIED IDEOGRAPH + {0xCFC6, 0x6380}, //13548 #CJK UNIFIED IDEOGRAPH + {0xCFC7, 0x9528}, //13549 #CJK UNIFIED IDEOGRAPH + {0xCFC8, 0x5148}, //13550 #CJK UNIFIED IDEOGRAPH + {0xCFC9, 0x4ED9}, //13551 #CJK UNIFIED IDEOGRAPH + {0xCFCA, 0x9C9C}, //13552 #CJK UNIFIED IDEOGRAPH + {0xCFCB, 0x7EA4}, //13553 #CJK UNIFIED IDEOGRAPH + {0xCFCC, 0x54B8}, //13554 #CJK UNIFIED IDEOGRAPH + {0xCFCD, 0x8D24}, //13555 #CJK UNIFIED IDEOGRAPH + {0xCFCE, 0x8854}, //13556 #CJK UNIFIED IDEOGRAPH + {0xCFCF, 0x8237}, //13557 #CJK UNIFIED IDEOGRAPH + {0xCFD0, 0x95F2}, //13558 #CJK UNIFIED IDEOGRAPH + {0xCFD1, 0x6D8E}, //13559 #CJK UNIFIED IDEOGRAPH + {0xCFD2, 0x5F26}, //13560 #CJK UNIFIED IDEOGRAPH + {0xCFD3, 0x5ACC}, //13561 #CJK UNIFIED IDEOGRAPH + {0xCFD4, 0x663E}, //13562 #CJK UNIFIED IDEOGRAPH + {0xCFD5, 0x9669}, //13563 #CJK UNIFIED IDEOGRAPH + {0xCFD6, 0x73B0}, //13564 #CJK UNIFIED IDEOGRAPH + {0xCFD7, 0x732E}, //13565 #CJK UNIFIED IDEOGRAPH + {0xCFD8, 0x53BF}, //13566 #CJK UNIFIED IDEOGRAPH + {0xCFD9, 0x817A}, //13567 #CJK UNIFIED IDEOGRAPH + {0xCFDA, 0x9985}, //13568 #CJK UNIFIED IDEOGRAPH + {0xCFDB, 0x7FA1}, //13569 #CJK UNIFIED IDEOGRAPH + {0xCFDC, 0x5BAA}, //13570 #CJK UNIFIED IDEOGRAPH + {0xCFDD, 0x9677}, //13571 #CJK UNIFIED IDEOGRAPH + {0xCFDE, 0x9650}, //13572 #CJK UNIFIED IDEOGRAPH + {0xCFDF, 0x7EBF}, //13573 #CJK UNIFIED IDEOGRAPH + {0xCFE0, 0x76F8}, //13574 #CJK UNIFIED IDEOGRAPH + {0xCFE1, 0x53A2}, //13575 #CJK UNIFIED IDEOGRAPH + {0xCFE2, 0x9576}, //13576 #CJK UNIFIED IDEOGRAPH + {0xCFE3, 0x9999}, //13577 #CJK UNIFIED IDEOGRAPH + {0xCFE4, 0x7BB1}, //13578 #CJK UNIFIED IDEOGRAPH + {0xCFE5, 0x8944}, //13579 #CJK UNIFIED IDEOGRAPH + {0xCFE6, 0x6E58}, //13580 #CJK UNIFIED IDEOGRAPH + {0xCFE7, 0x4E61}, //13581 #CJK UNIFIED IDEOGRAPH + {0xCFE8, 0x7FD4}, //13582 #CJK UNIFIED IDEOGRAPH + {0xCFE9, 0x7965}, //13583 #CJK UNIFIED IDEOGRAPH + {0xCFEA, 0x8BE6}, //13584 #CJK UNIFIED IDEOGRAPH + {0xCFEB, 0x60F3}, //13585 #CJK UNIFIED IDEOGRAPH + {0xCFEC, 0x54CD}, //13586 #CJK UNIFIED IDEOGRAPH + {0xCFED, 0x4EAB}, //13587 #CJK UNIFIED IDEOGRAPH + {0xCFEE, 0x9879}, //13588 #CJK UNIFIED IDEOGRAPH + {0xCFEF, 0x5DF7}, //13589 #CJK UNIFIED IDEOGRAPH + {0xCFF0, 0x6A61}, //13590 #CJK UNIFIED IDEOGRAPH + {0xCFF1, 0x50CF}, //13591 #CJK UNIFIED IDEOGRAPH + {0xCFF2, 0x5411}, //13592 #CJK UNIFIED IDEOGRAPH + {0xCFF3, 0x8C61}, //13593 #CJK UNIFIED IDEOGRAPH + {0xCFF4, 0x8427}, //13594 #CJK UNIFIED IDEOGRAPH + {0xCFF5, 0x785D}, //13595 #CJK UNIFIED IDEOGRAPH + {0xCFF6, 0x9704}, //13596 #CJK UNIFIED IDEOGRAPH + {0xCFF7, 0x524A}, //13597 #CJK UNIFIED IDEOGRAPH + {0xCFF8, 0x54EE}, //13598 #CJK UNIFIED IDEOGRAPH + {0xCFF9, 0x56A3}, //13599 #CJK UNIFIED IDEOGRAPH + {0xCFFA, 0x9500}, //13600 #CJK UNIFIED IDEOGRAPH + {0xCFFB, 0x6D88}, //13601 #CJK UNIFIED IDEOGRAPH + {0xCFFC, 0x5BB5}, //13602 #CJK UNIFIED IDEOGRAPH + {0xCFFD, 0x6DC6}, //13603 #CJK UNIFIED IDEOGRAPH + {0xCFFE, 0x6653}, //13604 #CJK UNIFIED IDEOGRAPH + {0xD040, 0x8824}, //13605 #CJK UNIFIED IDEOGRAPH + {0xD041, 0x8825}, //13606 #CJK UNIFIED IDEOGRAPH + {0xD042, 0x8826}, //13607 #CJK UNIFIED IDEOGRAPH + {0xD043, 0x8827}, //13608 #CJK UNIFIED IDEOGRAPH + {0xD044, 0x8828}, //13609 #CJK UNIFIED IDEOGRAPH + {0xD045, 0x8829}, //13610 #CJK UNIFIED IDEOGRAPH + {0xD046, 0x882A}, //13611 #CJK UNIFIED IDEOGRAPH + {0xD047, 0x882B}, //13612 #CJK UNIFIED IDEOGRAPH + {0xD048, 0x882C}, //13613 #CJK UNIFIED IDEOGRAPH + {0xD049, 0x882D}, //13614 #CJK UNIFIED IDEOGRAPH + {0xD04A, 0x882E}, //13615 #CJK UNIFIED IDEOGRAPH + {0xD04B, 0x882F}, //13616 #CJK UNIFIED IDEOGRAPH + {0xD04C, 0x8830}, //13617 #CJK UNIFIED IDEOGRAPH + {0xD04D, 0x8831}, //13618 #CJK UNIFIED IDEOGRAPH + {0xD04E, 0x8833}, //13619 #CJK UNIFIED IDEOGRAPH + {0xD04F, 0x8834}, //13620 #CJK UNIFIED IDEOGRAPH + {0xD050, 0x8835}, //13621 #CJK UNIFIED IDEOGRAPH + {0xD051, 0x8836}, //13622 #CJK UNIFIED IDEOGRAPH + {0xD052, 0x8837}, //13623 #CJK UNIFIED IDEOGRAPH + {0xD053, 0x8838}, //13624 #CJK UNIFIED IDEOGRAPH + {0xD054, 0x883A}, //13625 #CJK UNIFIED IDEOGRAPH + {0xD055, 0x883B}, //13626 #CJK UNIFIED IDEOGRAPH + {0xD056, 0x883D}, //13627 #CJK UNIFIED IDEOGRAPH + {0xD057, 0x883E}, //13628 #CJK UNIFIED IDEOGRAPH + {0xD058, 0x883F}, //13629 #CJK UNIFIED IDEOGRAPH + {0xD059, 0x8841}, //13630 #CJK UNIFIED IDEOGRAPH + {0xD05A, 0x8842}, //13631 #CJK UNIFIED IDEOGRAPH + {0xD05B, 0x8843}, //13632 #CJK UNIFIED IDEOGRAPH + {0xD05C, 0x8846}, //13633 #CJK UNIFIED IDEOGRAPH + {0xD05D, 0x8847}, //13634 #CJK UNIFIED IDEOGRAPH + {0xD05E, 0x8848}, //13635 #CJK UNIFIED IDEOGRAPH + {0xD05F, 0x8849}, //13636 #CJK UNIFIED IDEOGRAPH + {0xD060, 0x884A}, //13637 #CJK UNIFIED IDEOGRAPH + {0xD061, 0x884B}, //13638 #CJK UNIFIED IDEOGRAPH + {0xD062, 0x884E}, //13639 #CJK UNIFIED IDEOGRAPH + {0xD063, 0x884F}, //13640 #CJK UNIFIED IDEOGRAPH + {0xD064, 0x8850}, //13641 #CJK UNIFIED IDEOGRAPH + {0xD065, 0x8851}, //13642 #CJK UNIFIED IDEOGRAPH + {0xD066, 0x8852}, //13643 #CJK UNIFIED IDEOGRAPH + {0xD067, 0x8853}, //13644 #CJK UNIFIED IDEOGRAPH + {0xD068, 0x8855}, //13645 #CJK UNIFIED IDEOGRAPH + {0xD069, 0x8856}, //13646 #CJK UNIFIED IDEOGRAPH + {0xD06A, 0x8858}, //13647 #CJK UNIFIED IDEOGRAPH + {0xD06B, 0x885A}, //13648 #CJK UNIFIED IDEOGRAPH + {0xD06C, 0x885B}, //13649 #CJK UNIFIED IDEOGRAPH + {0xD06D, 0x885C}, //13650 #CJK UNIFIED IDEOGRAPH + {0xD06E, 0x885D}, //13651 #CJK UNIFIED IDEOGRAPH + {0xD06F, 0x885E}, //13652 #CJK UNIFIED IDEOGRAPH + {0xD070, 0x885F}, //13653 #CJK UNIFIED IDEOGRAPH + {0xD071, 0x8860}, //13654 #CJK UNIFIED IDEOGRAPH + {0xD072, 0x8866}, //13655 #CJK UNIFIED IDEOGRAPH + {0xD073, 0x8867}, //13656 #CJK UNIFIED IDEOGRAPH + {0xD074, 0x886A}, //13657 #CJK UNIFIED IDEOGRAPH + {0xD075, 0x886D}, //13658 #CJK UNIFIED IDEOGRAPH + {0xD076, 0x886F}, //13659 #CJK UNIFIED IDEOGRAPH + {0xD077, 0x8871}, //13660 #CJK UNIFIED IDEOGRAPH + {0xD078, 0x8873}, //13661 #CJK UNIFIED IDEOGRAPH + {0xD079, 0x8874}, //13662 #CJK UNIFIED IDEOGRAPH + {0xD07A, 0x8875}, //13663 #CJK UNIFIED IDEOGRAPH + {0xD07B, 0x8876}, //13664 #CJK UNIFIED IDEOGRAPH + {0xD07C, 0x8878}, //13665 #CJK UNIFIED IDEOGRAPH + {0xD07D, 0x8879}, //13666 #CJK UNIFIED IDEOGRAPH + {0xD07E, 0x887A}, //13667 #CJK UNIFIED IDEOGRAPH + {0xD080, 0x887B}, //13668 #CJK UNIFIED IDEOGRAPH + {0xD081, 0x887C}, //13669 #CJK UNIFIED IDEOGRAPH + {0xD082, 0x8880}, //13670 #CJK UNIFIED IDEOGRAPH + {0xD083, 0x8883}, //13671 #CJK UNIFIED IDEOGRAPH + {0xD084, 0x8886}, //13672 #CJK UNIFIED IDEOGRAPH + {0xD085, 0x8887}, //13673 #CJK UNIFIED IDEOGRAPH + {0xD086, 0x8889}, //13674 #CJK UNIFIED IDEOGRAPH + {0xD087, 0x888A}, //13675 #CJK UNIFIED IDEOGRAPH + {0xD088, 0x888C}, //13676 #CJK UNIFIED IDEOGRAPH + {0xD089, 0x888E}, //13677 #CJK UNIFIED IDEOGRAPH + {0xD08A, 0x888F}, //13678 #CJK UNIFIED IDEOGRAPH + {0xD08B, 0x8890}, //13679 #CJK UNIFIED IDEOGRAPH + {0xD08C, 0x8891}, //13680 #CJK UNIFIED IDEOGRAPH + {0xD08D, 0x8893}, //13681 #CJK UNIFIED IDEOGRAPH + {0xD08E, 0x8894}, //13682 #CJK UNIFIED IDEOGRAPH + {0xD08F, 0x8895}, //13683 #CJK UNIFIED IDEOGRAPH + {0xD090, 0x8897}, //13684 #CJK UNIFIED IDEOGRAPH + {0xD091, 0x8898}, //13685 #CJK UNIFIED IDEOGRAPH + {0xD092, 0x8899}, //13686 #CJK UNIFIED IDEOGRAPH + {0xD093, 0x889A}, //13687 #CJK UNIFIED IDEOGRAPH + {0xD094, 0x889B}, //13688 #CJK UNIFIED IDEOGRAPH + {0xD095, 0x889D}, //13689 #CJK UNIFIED IDEOGRAPH + {0xD096, 0x889E}, //13690 #CJK UNIFIED IDEOGRAPH + {0xD097, 0x889F}, //13691 #CJK UNIFIED IDEOGRAPH + {0xD098, 0x88A0}, //13692 #CJK UNIFIED IDEOGRAPH + {0xD099, 0x88A1}, //13693 #CJK UNIFIED IDEOGRAPH + {0xD09A, 0x88A3}, //13694 #CJK UNIFIED IDEOGRAPH + {0xD09B, 0x88A5}, //13695 #CJK UNIFIED IDEOGRAPH + {0xD09C, 0x88A6}, //13696 #CJK UNIFIED IDEOGRAPH + {0xD09D, 0x88A7}, //13697 #CJK UNIFIED IDEOGRAPH + {0xD09E, 0x88A8}, //13698 #CJK UNIFIED IDEOGRAPH + {0xD09F, 0x88A9}, //13699 #CJK UNIFIED IDEOGRAPH + {0xD0A0, 0x88AA}, //13700 #CJK UNIFIED IDEOGRAPH + {0xD0A1, 0x5C0F}, //13701 #CJK UNIFIED IDEOGRAPH + {0xD0A2, 0x5B5D}, //13702 #CJK UNIFIED IDEOGRAPH + {0xD0A3, 0x6821}, //13703 #CJK UNIFIED IDEOGRAPH + {0xD0A4, 0x8096}, //13704 #CJK UNIFIED IDEOGRAPH + {0xD0A5, 0x5578}, //13705 #CJK UNIFIED IDEOGRAPH + {0xD0A6, 0x7B11}, //13706 #CJK UNIFIED IDEOGRAPH + {0xD0A7, 0x6548}, //13707 #CJK UNIFIED IDEOGRAPH + {0xD0A8, 0x6954}, //13708 #CJK UNIFIED IDEOGRAPH + {0xD0A9, 0x4E9B}, //13709 #CJK UNIFIED IDEOGRAPH + {0xD0AA, 0x6B47}, //13710 #CJK UNIFIED IDEOGRAPH + {0xD0AB, 0x874E}, //13711 #CJK UNIFIED IDEOGRAPH + {0xD0AC, 0x978B}, //13712 #CJK UNIFIED IDEOGRAPH + {0xD0AD, 0x534F}, //13713 #CJK UNIFIED IDEOGRAPH + {0xD0AE, 0x631F}, //13714 #CJK UNIFIED IDEOGRAPH + {0xD0AF, 0x643A}, //13715 #CJK UNIFIED IDEOGRAPH + {0xD0B0, 0x90AA}, //13716 #CJK UNIFIED IDEOGRAPH + {0xD0B1, 0x659C}, //13717 #CJK UNIFIED IDEOGRAPH + {0xD0B2, 0x80C1}, //13718 #CJK UNIFIED IDEOGRAPH + {0xD0B3, 0x8C10}, //13719 #CJK UNIFIED IDEOGRAPH + {0xD0B4, 0x5199}, //13720 #CJK UNIFIED IDEOGRAPH + {0xD0B5, 0x68B0}, //13721 #CJK UNIFIED IDEOGRAPH + {0xD0B6, 0x5378}, //13722 #CJK UNIFIED IDEOGRAPH + {0xD0B7, 0x87F9}, //13723 #CJK UNIFIED IDEOGRAPH + {0xD0B8, 0x61C8}, //13724 #CJK UNIFIED IDEOGRAPH + {0xD0B9, 0x6CC4}, //13725 #CJK UNIFIED IDEOGRAPH + {0xD0BA, 0x6CFB}, //13726 #CJK UNIFIED IDEOGRAPH + {0xD0BB, 0x8C22}, //13727 #CJK UNIFIED IDEOGRAPH + {0xD0BC, 0x5C51}, //13728 #CJK UNIFIED IDEOGRAPH + {0xD0BD, 0x85AA}, //13729 #CJK UNIFIED IDEOGRAPH + {0xD0BE, 0x82AF}, //13730 #CJK UNIFIED IDEOGRAPH + {0xD0BF, 0x950C}, //13731 #CJK UNIFIED IDEOGRAPH + {0xD0C0, 0x6B23}, //13732 #CJK UNIFIED IDEOGRAPH + {0xD0C1, 0x8F9B}, //13733 #CJK UNIFIED IDEOGRAPH + {0xD0C2, 0x65B0}, //13734 #CJK UNIFIED IDEOGRAPH + {0xD0C3, 0x5FFB}, //13735 #CJK UNIFIED IDEOGRAPH + {0xD0C4, 0x5FC3}, //13736 #CJK UNIFIED IDEOGRAPH + {0xD0C5, 0x4FE1}, //13737 #CJK UNIFIED IDEOGRAPH + {0xD0C6, 0x8845}, //13738 #CJK UNIFIED IDEOGRAPH + {0xD0C7, 0x661F}, //13739 #CJK UNIFIED IDEOGRAPH + {0xD0C8, 0x8165}, //13740 #CJK UNIFIED IDEOGRAPH + {0xD0C9, 0x7329}, //13741 #CJK UNIFIED IDEOGRAPH + {0xD0CA, 0x60FA}, //13742 #CJK UNIFIED IDEOGRAPH + {0xD0CB, 0x5174}, //13743 #CJK UNIFIED IDEOGRAPH + {0xD0CC, 0x5211}, //13744 #CJK UNIFIED IDEOGRAPH + {0xD0CD, 0x578B}, //13745 #CJK UNIFIED IDEOGRAPH + {0xD0CE, 0x5F62}, //13746 #CJK UNIFIED IDEOGRAPH + {0xD0CF, 0x90A2}, //13747 #CJK UNIFIED IDEOGRAPH + {0xD0D0, 0x884C}, //13748 #CJK UNIFIED IDEOGRAPH + {0xD0D1, 0x9192}, //13749 #CJK UNIFIED IDEOGRAPH + {0xD0D2, 0x5E78}, //13750 #CJK UNIFIED IDEOGRAPH + {0xD0D3, 0x674F}, //13751 #CJK UNIFIED IDEOGRAPH + {0xD0D4, 0x6027}, //13752 #CJK UNIFIED IDEOGRAPH + {0xD0D5, 0x59D3}, //13753 #CJK UNIFIED IDEOGRAPH + {0xD0D6, 0x5144}, //13754 #CJK UNIFIED IDEOGRAPH + {0xD0D7, 0x51F6}, //13755 #CJK UNIFIED IDEOGRAPH + {0xD0D8, 0x80F8}, //13756 #CJK UNIFIED IDEOGRAPH + {0xD0D9, 0x5308}, //13757 #CJK UNIFIED IDEOGRAPH + {0xD0DA, 0x6C79}, //13758 #CJK UNIFIED IDEOGRAPH + {0xD0DB, 0x96C4}, //13759 #CJK UNIFIED IDEOGRAPH + {0xD0DC, 0x718A}, //13760 #CJK UNIFIED IDEOGRAPH + {0xD0DD, 0x4F11}, //13761 #CJK UNIFIED IDEOGRAPH + {0xD0DE, 0x4FEE}, //13762 #CJK UNIFIED IDEOGRAPH + {0xD0DF, 0x7F9E}, //13763 #CJK UNIFIED IDEOGRAPH + {0xD0E0, 0x673D}, //13764 #CJK UNIFIED IDEOGRAPH + {0xD0E1, 0x55C5}, //13765 #CJK UNIFIED IDEOGRAPH + {0xD0E2, 0x9508}, //13766 #CJK UNIFIED IDEOGRAPH + {0xD0E3, 0x79C0}, //13767 #CJK UNIFIED IDEOGRAPH + {0xD0E4, 0x8896}, //13768 #CJK UNIFIED IDEOGRAPH + {0xD0E5, 0x7EE3}, //13769 #CJK UNIFIED IDEOGRAPH + {0xD0E6, 0x589F}, //13770 #CJK UNIFIED IDEOGRAPH + {0xD0E7, 0x620C}, //13771 #CJK UNIFIED IDEOGRAPH + {0xD0E8, 0x9700}, //13772 #CJK UNIFIED IDEOGRAPH + {0xD0E9, 0x865A}, //13773 #CJK UNIFIED IDEOGRAPH + {0xD0EA, 0x5618}, //13774 #CJK UNIFIED IDEOGRAPH + {0xD0EB, 0x987B}, //13775 #CJK UNIFIED IDEOGRAPH + {0xD0EC, 0x5F90}, //13776 #CJK UNIFIED IDEOGRAPH + {0xD0ED, 0x8BB8}, //13777 #CJK UNIFIED IDEOGRAPH + {0xD0EE, 0x84C4}, //13778 #CJK UNIFIED IDEOGRAPH + {0xD0EF, 0x9157}, //13779 #CJK UNIFIED IDEOGRAPH + {0xD0F0, 0x53D9}, //13780 #CJK UNIFIED IDEOGRAPH + {0xD0F1, 0x65ED}, //13781 #CJK UNIFIED IDEOGRAPH + {0xD0F2, 0x5E8F}, //13782 #CJK UNIFIED IDEOGRAPH + {0xD0F3, 0x755C}, //13783 #CJK UNIFIED IDEOGRAPH + {0xD0F4, 0x6064}, //13784 #CJK UNIFIED IDEOGRAPH + {0xD0F5, 0x7D6E}, //13785 #CJK UNIFIED IDEOGRAPH + {0xD0F6, 0x5A7F}, //13786 #CJK UNIFIED IDEOGRAPH + {0xD0F7, 0x7EEA}, //13787 #CJK UNIFIED IDEOGRAPH + {0xD0F8, 0x7EED}, //13788 #CJK UNIFIED IDEOGRAPH + {0xD0F9, 0x8F69}, //13789 #CJK UNIFIED IDEOGRAPH + {0xD0FA, 0x55A7}, //13790 #CJK UNIFIED IDEOGRAPH + {0xD0FB, 0x5BA3}, //13791 #CJK UNIFIED IDEOGRAPH + {0xD0FC, 0x60AC}, //13792 #CJK UNIFIED IDEOGRAPH + {0xD0FD, 0x65CB}, //13793 #CJK UNIFIED IDEOGRAPH + {0xD0FE, 0x7384}, //13794 #CJK UNIFIED IDEOGRAPH + {0xD140, 0x88AC}, //13795 #CJK UNIFIED IDEOGRAPH + {0xD141, 0x88AE}, //13796 #CJK UNIFIED IDEOGRAPH + {0xD142, 0x88AF}, //13797 #CJK UNIFIED IDEOGRAPH + {0xD143, 0x88B0}, //13798 #CJK UNIFIED IDEOGRAPH + {0xD144, 0x88B2}, //13799 #CJK UNIFIED IDEOGRAPH + {0xD145, 0x88B3}, //13800 #CJK UNIFIED IDEOGRAPH + {0xD146, 0x88B4}, //13801 #CJK UNIFIED IDEOGRAPH + {0xD147, 0x88B5}, //13802 #CJK UNIFIED IDEOGRAPH + {0xD148, 0x88B6}, //13803 #CJK UNIFIED IDEOGRAPH + {0xD149, 0x88B8}, //13804 #CJK UNIFIED IDEOGRAPH + {0xD14A, 0x88B9}, //13805 #CJK UNIFIED IDEOGRAPH + {0xD14B, 0x88BA}, //13806 #CJK UNIFIED IDEOGRAPH + {0xD14C, 0x88BB}, //13807 #CJK UNIFIED IDEOGRAPH + {0xD14D, 0x88BD}, //13808 #CJK UNIFIED IDEOGRAPH + {0xD14E, 0x88BE}, //13809 #CJK UNIFIED IDEOGRAPH + {0xD14F, 0x88BF}, //13810 #CJK UNIFIED IDEOGRAPH + {0xD150, 0x88C0}, //13811 #CJK UNIFIED IDEOGRAPH + {0xD151, 0x88C3}, //13812 #CJK UNIFIED IDEOGRAPH + {0xD152, 0x88C4}, //13813 #CJK UNIFIED IDEOGRAPH + {0xD153, 0x88C7}, //13814 #CJK UNIFIED IDEOGRAPH + {0xD154, 0x88C8}, //13815 #CJK UNIFIED IDEOGRAPH + {0xD155, 0x88CA}, //13816 #CJK UNIFIED IDEOGRAPH + {0xD156, 0x88CB}, //13817 #CJK UNIFIED IDEOGRAPH + {0xD157, 0x88CC}, //13818 #CJK UNIFIED IDEOGRAPH + {0xD158, 0x88CD}, //13819 #CJK UNIFIED IDEOGRAPH + {0xD159, 0x88CF}, //13820 #CJK UNIFIED IDEOGRAPH + {0xD15A, 0x88D0}, //13821 #CJK UNIFIED IDEOGRAPH + {0xD15B, 0x88D1}, //13822 #CJK UNIFIED IDEOGRAPH + {0xD15C, 0x88D3}, //13823 #CJK UNIFIED IDEOGRAPH + {0xD15D, 0x88D6}, //13824 #CJK UNIFIED IDEOGRAPH + {0xD15E, 0x88D7}, //13825 #CJK UNIFIED IDEOGRAPH + {0xD15F, 0x88DA}, //13826 #CJK UNIFIED IDEOGRAPH + {0xD160, 0x88DB}, //13827 #CJK UNIFIED IDEOGRAPH + {0xD161, 0x88DC}, //13828 #CJK UNIFIED IDEOGRAPH + {0xD162, 0x88DD}, //13829 #CJK UNIFIED IDEOGRAPH + {0xD163, 0x88DE}, //13830 #CJK UNIFIED IDEOGRAPH + {0xD164, 0x88E0}, //13831 #CJK UNIFIED IDEOGRAPH + {0xD165, 0x88E1}, //13832 #CJK UNIFIED IDEOGRAPH + {0xD166, 0x88E6}, //13833 #CJK UNIFIED IDEOGRAPH + {0xD167, 0x88E7}, //13834 #CJK UNIFIED IDEOGRAPH + {0xD168, 0x88E9}, //13835 #CJK UNIFIED IDEOGRAPH + {0xD169, 0x88EA}, //13836 #CJK UNIFIED IDEOGRAPH + {0xD16A, 0x88EB}, //13837 #CJK UNIFIED IDEOGRAPH + {0xD16B, 0x88EC}, //13838 #CJK UNIFIED IDEOGRAPH + {0xD16C, 0x88ED}, //13839 #CJK UNIFIED IDEOGRAPH + {0xD16D, 0x88EE}, //13840 #CJK UNIFIED IDEOGRAPH + {0xD16E, 0x88EF}, //13841 #CJK UNIFIED IDEOGRAPH + {0xD16F, 0x88F2}, //13842 #CJK UNIFIED IDEOGRAPH + {0xD170, 0x88F5}, //13843 #CJK UNIFIED IDEOGRAPH + {0xD171, 0x88F6}, //13844 #CJK UNIFIED IDEOGRAPH + {0xD172, 0x88F7}, //13845 #CJK UNIFIED IDEOGRAPH + {0xD173, 0x88FA}, //13846 #CJK UNIFIED IDEOGRAPH + {0xD174, 0x88FB}, //13847 #CJK UNIFIED IDEOGRAPH + {0xD175, 0x88FD}, //13848 #CJK UNIFIED IDEOGRAPH + {0xD176, 0x88FF}, //13849 #CJK UNIFIED IDEOGRAPH + {0xD177, 0x8900}, //13850 #CJK UNIFIED IDEOGRAPH + {0xD178, 0x8901}, //13851 #CJK UNIFIED IDEOGRAPH + {0xD179, 0x8903}, //13852 #CJK UNIFIED IDEOGRAPH + {0xD17A, 0x8904}, //13853 #CJK UNIFIED IDEOGRAPH + {0xD17B, 0x8905}, //13854 #CJK UNIFIED IDEOGRAPH + {0xD17C, 0x8906}, //13855 #CJK UNIFIED IDEOGRAPH + {0xD17D, 0x8907}, //13856 #CJK UNIFIED IDEOGRAPH + {0xD17E, 0x8908}, //13857 #CJK UNIFIED IDEOGRAPH + {0xD180, 0x8909}, //13858 #CJK UNIFIED IDEOGRAPH + {0xD181, 0x890B}, //13859 #CJK UNIFIED IDEOGRAPH + {0xD182, 0x890C}, //13860 #CJK UNIFIED IDEOGRAPH + {0xD183, 0x890D}, //13861 #CJK UNIFIED IDEOGRAPH + {0xD184, 0x890E}, //13862 #CJK UNIFIED IDEOGRAPH + {0xD185, 0x890F}, //13863 #CJK UNIFIED IDEOGRAPH + {0xD186, 0x8911}, //13864 #CJK UNIFIED IDEOGRAPH + {0xD187, 0x8914}, //13865 #CJK UNIFIED IDEOGRAPH + {0xD188, 0x8915}, //13866 #CJK UNIFIED IDEOGRAPH + {0xD189, 0x8916}, //13867 #CJK UNIFIED IDEOGRAPH + {0xD18A, 0x8917}, //13868 #CJK UNIFIED IDEOGRAPH + {0xD18B, 0x8918}, //13869 #CJK UNIFIED IDEOGRAPH + {0xD18C, 0x891C}, //13870 #CJK UNIFIED IDEOGRAPH + {0xD18D, 0x891D}, //13871 #CJK UNIFIED IDEOGRAPH + {0xD18E, 0x891E}, //13872 #CJK UNIFIED IDEOGRAPH + {0xD18F, 0x891F}, //13873 #CJK UNIFIED IDEOGRAPH + {0xD190, 0x8920}, //13874 #CJK UNIFIED IDEOGRAPH + {0xD191, 0x8922}, //13875 #CJK UNIFIED IDEOGRAPH + {0xD192, 0x8923}, //13876 #CJK UNIFIED IDEOGRAPH + {0xD193, 0x8924}, //13877 #CJK UNIFIED IDEOGRAPH + {0xD194, 0x8926}, //13878 #CJK UNIFIED IDEOGRAPH + {0xD195, 0x8927}, //13879 #CJK UNIFIED IDEOGRAPH + {0xD196, 0x8928}, //13880 #CJK UNIFIED IDEOGRAPH + {0xD197, 0x8929}, //13881 #CJK UNIFIED IDEOGRAPH + {0xD198, 0x892C}, //13882 #CJK UNIFIED IDEOGRAPH + {0xD199, 0x892D}, //13883 #CJK UNIFIED IDEOGRAPH + {0xD19A, 0x892E}, //13884 #CJK UNIFIED IDEOGRAPH + {0xD19B, 0x892F}, //13885 #CJK UNIFIED IDEOGRAPH + {0xD19C, 0x8931}, //13886 #CJK UNIFIED IDEOGRAPH + {0xD19D, 0x8932}, //13887 #CJK UNIFIED IDEOGRAPH + {0xD19E, 0x8933}, //13888 #CJK UNIFIED IDEOGRAPH + {0xD19F, 0x8935}, //13889 #CJK UNIFIED IDEOGRAPH + {0xD1A0, 0x8937}, //13890 #CJK UNIFIED IDEOGRAPH + {0xD1A1, 0x9009}, //13891 #CJK UNIFIED IDEOGRAPH + {0xD1A2, 0x7663}, //13892 #CJK UNIFIED IDEOGRAPH + {0xD1A3, 0x7729}, //13893 #CJK UNIFIED IDEOGRAPH + {0xD1A4, 0x7EDA}, //13894 #CJK UNIFIED IDEOGRAPH + {0xD1A5, 0x9774}, //13895 #CJK UNIFIED IDEOGRAPH + {0xD1A6, 0x859B}, //13896 #CJK UNIFIED IDEOGRAPH + {0xD1A7, 0x5B66}, //13897 #CJK UNIFIED IDEOGRAPH + {0xD1A8, 0x7A74}, //13898 #CJK UNIFIED IDEOGRAPH + {0xD1A9, 0x96EA}, //13899 #CJK UNIFIED IDEOGRAPH + {0xD1AA, 0x8840}, //13900 #CJK UNIFIED IDEOGRAPH + {0xD1AB, 0x52CB}, //13901 #CJK UNIFIED IDEOGRAPH + {0xD1AC, 0x718F}, //13902 #CJK UNIFIED IDEOGRAPH + {0xD1AD, 0x5FAA}, //13903 #CJK UNIFIED IDEOGRAPH + {0xD1AE, 0x65EC}, //13904 #CJK UNIFIED IDEOGRAPH + {0xD1AF, 0x8BE2}, //13905 #CJK UNIFIED IDEOGRAPH + {0xD1B0, 0x5BFB}, //13906 #CJK UNIFIED IDEOGRAPH + {0xD1B1, 0x9A6F}, //13907 #CJK UNIFIED IDEOGRAPH + {0xD1B2, 0x5DE1}, //13908 #CJK UNIFIED IDEOGRAPH + {0xD1B3, 0x6B89}, //13909 #CJK UNIFIED IDEOGRAPH + {0xD1B4, 0x6C5B}, //13910 #CJK UNIFIED IDEOGRAPH + {0xD1B5, 0x8BAD}, //13911 #CJK UNIFIED IDEOGRAPH + {0xD1B6, 0x8BAF}, //13912 #CJK UNIFIED IDEOGRAPH + {0xD1B7, 0x900A}, //13913 #CJK UNIFIED IDEOGRAPH + {0xD1B8, 0x8FC5}, //13914 #CJK UNIFIED IDEOGRAPH + {0xD1B9, 0x538B}, //13915 #CJK UNIFIED IDEOGRAPH + {0xD1BA, 0x62BC}, //13916 #CJK UNIFIED IDEOGRAPH + {0xD1BB, 0x9E26}, //13917 #CJK UNIFIED IDEOGRAPH + {0xD1BC, 0x9E2D}, //13918 #CJK UNIFIED IDEOGRAPH + {0xD1BD, 0x5440}, //13919 #CJK UNIFIED IDEOGRAPH + {0xD1BE, 0x4E2B}, //13920 #CJK UNIFIED IDEOGRAPH + {0xD1BF, 0x82BD}, //13921 #CJK UNIFIED IDEOGRAPH + {0xD1C0, 0x7259}, //13922 #CJK UNIFIED IDEOGRAPH + {0xD1C1, 0x869C}, //13923 #CJK UNIFIED IDEOGRAPH + {0xD1C2, 0x5D16}, //13924 #CJK UNIFIED IDEOGRAPH + {0xD1C3, 0x8859}, //13925 #CJK UNIFIED IDEOGRAPH + {0xD1C4, 0x6DAF}, //13926 #CJK UNIFIED IDEOGRAPH + {0xD1C5, 0x96C5}, //13927 #CJK UNIFIED IDEOGRAPH + {0xD1C6, 0x54D1}, //13928 #CJK UNIFIED IDEOGRAPH + {0xD1C7, 0x4E9A}, //13929 #CJK UNIFIED IDEOGRAPH + {0xD1C8, 0x8BB6}, //13930 #CJK UNIFIED IDEOGRAPH + {0xD1C9, 0x7109}, //13931 #CJK UNIFIED IDEOGRAPH + {0xD1CA, 0x54BD}, //13932 #CJK UNIFIED IDEOGRAPH + {0xD1CB, 0x9609}, //13933 #CJK UNIFIED IDEOGRAPH + {0xD1CC, 0x70DF}, //13934 #CJK UNIFIED IDEOGRAPH + {0xD1CD, 0x6DF9}, //13935 #CJK UNIFIED IDEOGRAPH + {0xD1CE, 0x76D0}, //13936 #CJK UNIFIED IDEOGRAPH + {0xD1CF, 0x4E25}, //13937 #CJK UNIFIED IDEOGRAPH + {0xD1D0, 0x7814}, //13938 #CJK UNIFIED IDEOGRAPH + {0xD1D1, 0x8712}, //13939 #CJK UNIFIED IDEOGRAPH + {0xD1D2, 0x5CA9}, //13940 #CJK UNIFIED IDEOGRAPH + {0xD1D3, 0x5EF6}, //13941 #CJK UNIFIED IDEOGRAPH + {0xD1D4, 0x8A00}, //13942 #CJK UNIFIED IDEOGRAPH + {0xD1D5, 0x989C}, //13943 #CJK UNIFIED IDEOGRAPH + {0xD1D6, 0x960E}, //13944 #CJK UNIFIED IDEOGRAPH + {0xD1D7, 0x708E}, //13945 #CJK UNIFIED IDEOGRAPH + {0xD1D8, 0x6CBF}, //13946 #CJK UNIFIED IDEOGRAPH + {0xD1D9, 0x5944}, //13947 #CJK UNIFIED IDEOGRAPH + {0xD1DA, 0x63A9}, //13948 #CJK UNIFIED IDEOGRAPH + {0xD1DB, 0x773C}, //13949 #CJK UNIFIED IDEOGRAPH + {0xD1DC, 0x884D}, //13950 #CJK UNIFIED IDEOGRAPH + {0xD1DD, 0x6F14}, //13951 #CJK UNIFIED IDEOGRAPH + {0xD1DE, 0x8273}, //13952 #CJK UNIFIED IDEOGRAPH + {0xD1DF, 0x5830}, //13953 #CJK UNIFIED IDEOGRAPH + {0xD1E0, 0x71D5}, //13954 #CJK UNIFIED IDEOGRAPH + {0xD1E1, 0x538C}, //13955 #CJK UNIFIED IDEOGRAPH + {0xD1E2, 0x781A}, //13956 #CJK UNIFIED IDEOGRAPH + {0xD1E3, 0x96C1}, //13957 #CJK UNIFIED IDEOGRAPH + {0xD1E4, 0x5501}, //13958 #CJK UNIFIED IDEOGRAPH + {0xD1E5, 0x5F66}, //13959 #CJK UNIFIED IDEOGRAPH + {0xD1E6, 0x7130}, //13960 #CJK UNIFIED IDEOGRAPH + {0xD1E7, 0x5BB4}, //13961 #CJK UNIFIED IDEOGRAPH + {0xD1E8, 0x8C1A}, //13962 #CJK UNIFIED IDEOGRAPH + {0xD1E9, 0x9A8C}, //13963 #CJK UNIFIED IDEOGRAPH + {0xD1EA, 0x6B83}, //13964 #CJK UNIFIED IDEOGRAPH + {0xD1EB, 0x592E}, //13965 #CJK UNIFIED IDEOGRAPH + {0xD1EC, 0x9E2F}, //13966 #CJK UNIFIED IDEOGRAPH + {0xD1ED, 0x79E7}, //13967 #CJK UNIFIED IDEOGRAPH + {0xD1EE, 0x6768}, //13968 #CJK UNIFIED IDEOGRAPH + {0xD1EF, 0x626C}, //13969 #CJK UNIFIED IDEOGRAPH + {0xD1F0, 0x4F6F}, //13970 #CJK UNIFIED IDEOGRAPH + {0xD1F1, 0x75A1}, //13971 #CJK UNIFIED IDEOGRAPH + {0xD1F2, 0x7F8A}, //13972 #CJK UNIFIED IDEOGRAPH + {0xD1F3, 0x6D0B}, //13973 #CJK UNIFIED IDEOGRAPH + {0xD1F4, 0x9633}, //13974 #CJK UNIFIED IDEOGRAPH + {0xD1F5, 0x6C27}, //13975 #CJK UNIFIED IDEOGRAPH + {0xD1F6, 0x4EF0}, //13976 #CJK UNIFIED IDEOGRAPH + {0xD1F7, 0x75D2}, //13977 #CJK UNIFIED IDEOGRAPH + {0xD1F8, 0x517B}, //13978 #CJK UNIFIED IDEOGRAPH + {0xD1F9, 0x6837}, //13979 #CJK UNIFIED IDEOGRAPH + {0xD1FA, 0x6F3E}, //13980 #CJK UNIFIED IDEOGRAPH + {0xD1FB, 0x9080}, //13981 #CJK UNIFIED IDEOGRAPH + {0xD1FC, 0x8170}, //13982 #CJK UNIFIED IDEOGRAPH + {0xD1FD, 0x5996}, //13983 #CJK UNIFIED IDEOGRAPH + {0xD1FE, 0x7476}, //13984 #CJK UNIFIED IDEOGRAPH + {0xD240, 0x8938}, //13985 #CJK UNIFIED IDEOGRAPH + {0xD241, 0x8939}, //13986 #CJK UNIFIED IDEOGRAPH + {0xD242, 0x893A}, //13987 #CJK UNIFIED IDEOGRAPH + {0xD243, 0x893B}, //13988 #CJK UNIFIED IDEOGRAPH + {0xD244, 0x893C}, //13989 #CJK UNIFIED IDEOGRAPH + {0xD245, 0x893D}, //13990 #CJK UNIFIED IDEOGRAPH + {0xD246, 0x893E}, //13991 #CJK UNIFIED IDEOGRAPH + {0xD247, 0x893F}, //13992 #CJK UNIFIED IDEOGRAPH + {0xD248, 0x8940}, //13993 #CJK UNIFIED IDEOGRAPH + {0xD249, 0x8942}, //13994 #CJK UNIFIED IDEOGRAPH + {0xD24A, 0x8943}, //13995 #CJK UNIFIED IDEOGRAPH + {0xD24B, 0x8945}, //13996 #CJK UNIFIED IDEOGRAPH + {0xD24C, 0x8946}, //13997 #CJK UNIFIED IDEOGRAPH + {0xD24D, 0x8947}, //13998 #CJK UNIFIED IDEOGRAPH + {0xD24E, 0x8948}, //13999 #CJK UNIFIED IDEOGRAPH + {0xD24F, 0x8949}, //14000 #CJK UNIFIED IDEOGRAPH + {0xD250, 0x894A}, //14001 #CJK UNIFIED IDEOGRAPH + {0xD251, 0x894B}, //14002 #CJK UNIFIED IDEOGRAPH + {0xD252, 0x894C}, //14003 #CJK UNIFIED IDEOGRAPH + {0xD253, 0x894D}, //14004 #CJK UNIFIED IDEOGRAPH + {0xD254, 0x894E}, //14005 #CJK UNIFIED IDEOGRAPH + {0xD255, 0x894F}, //14006 #CJK UNIFIED IDEOGRAPH + {0xD256, 0x8950}, //14007 #CJK UNIFIED IDEOGRAPH + {0xD257, 0x8951}, //14008 #CJK UNIFIED IDEOGRAPH + {0xD258, 0x8952}, //14009 #CJK UNIFIED IDEOGRAPH + {0xD259, 0x8953}, //14010 #CJK UNIFIED IDEOGRAPH + {0xD25A, 0x8954}, //14011 #CJK UNIFIED IDEOGRAPH + {0xD25B, 0x8955}, //14012 #CJK UNIFIED IDEOGRAPH + {0xD25C, 0x8956}, //14013 #CJK UNIFIED IDEOGRAPH + {0xD25D, 0x8957}, //14014 #CJK UNIFIED IDEOGRAPH + {0xD25E, 0x8958}, //14015 #CJK UNIFIED IDEOGRAPH + {0xD25F, 0x8959}, //14016 #CJK UNIFIED IDEOGRAPH + {0xD260, 0x895A}, //14017 #CJK UNIFIED IDEOGRAPH + {0xD261, 0x895B}, //14018 #CJK UNIFIED IDEOGRAPH + {0xD262, 0x895C}, //14019 #CJK UNIFIED IDEOGRAPH + {0xD263, 0x895D}, //14020 #CJK UNIFIED IDEOGRAPH + {0xD264, 0x8960}, //14021 #CJK UNIFIED IDEOGRAPH + {0xD265, 0x8961}, //14022 #CJK UNIFIED IDEOGRAPH + {0xD266, 0x8962}, //14023 #CJK UNIFIED IDEOGRAPH + {0xD267, 0x8963}, //14024 #CJK UNIFIED IDEOGRAPH + {0xD268, 0x8964}, //14025 #CJK UNIFIED IDEOGRAPH + {0xD269, 0x8965}, //14026 #CJK UNIFIED IDEOGRAPH + {0xD26A, 0x8967}, //14027 #CJK UNIFIED IDEOGRAPH + {0xD26B, 0x8968}, //14028 #CJK UNIFIED IDEOGRAPH + {0xD26C, 0x8969}, //14029 #CJK UNIFIED IDEOGRAPH + {0xD26D, 0x896A}, //14030 #CJK UNIFIED IDEOGRAPH + {0xD26E, 0x896B}, //14031 #CJK UNIFIED IDEOGRAPH + {0xD26F, 0x896C}, //14032 #CJK UNIFIED IDEOGRAPH + {0xD270, 0x896D}, //14033 #CJK UNIFIED IDEOGRAPH + {0xD271, 0x896E}, //14034 #CJK UNIFIED IDEOGRAPH + {0xD272, 0x896F}, //14035 #CJK UNIFIED IDEOGRAPH + {0xD273, 0x8970}, //14036 #CJK UNIFIED IDEOGRAPH + {0xD274, 0x8971}, //14037 #CJK UNIFIED IDEOGRAPH + {0xD275, 0x8972}, //14038 #CJK UNIFIED IDEOGRAPH + {0xD276, 0x8973}, //14039 #CJK UNIFIED IDEOGRAPH + {0xD277, 0x8974}, //14040 #CJK UNIFIED IDEOGRAPH + {0xD278, 0x8975}, //14041 #CJK UNIFIED IDEOGRAPH + {0xD279, 0x8976}, //14042 #CJK UNIFIED IDEOGRAPH + {0xD27A, 0x8977}, //14043 #CJK UNIFIED IDEOGRAPH + {0xD27B, 0x8978}, //14044 #CJK UNIFIED IDEOGRAPH + {0xD27C, 0x8979}, //14045 #CJK UNIFIED IDEOGRAPH + {0xD27D, 0x897A}, //14046 #CJK UNIFIED IDEOGRAPH + {0xD27E, 0x897C}, //14047 #CJK UNIFIED IDEOGRAPH + {0xD280, 0x897D}, //14048 #CJK UNIFIED IDEOGRAPH + {0xD281, 0x897E}, //14049 #CJK UNIFIED IDEOGRAPH + {0xD282, 0x8980}, //14050 #CJK UNIFIED IDEOGRAPH + {0xD283, 0x8982}, //14051 #CJK UNIFIED IDEOGRAPH + {0xD284, 0x8984}, //14052 #CJK UNIFIED IDEOGRAPH + {0xD285, 0x8985}, //14053 #CJK UNIFIED IDEOGRAPH + {0xD286, 0x8987}, //14054 #CJK UNIFIED IDEOGRAPH + {0xD287, 0x8988}, //14055 #CJK UNIFIED IDEOGRAPH + {0xD288, 0x8989}, //14056 #CJK UNIFIED IDEOGRAPH + {0xD289, 0x898A}, //14057 #CJK UNIFIED IDEOGRAPH + {0xD28A, 0x898B}, //14058 #CJK UNIFIED IDEOGRAPH + {0xD28B, 0x898C}, //14059 #CJK UNIFIED IDEOGRAPH + {0xD28C, 0x898D}, //14060 #CJK UNIFIED IDEOGRAPH + {0xD28D, 0x898E}, //14061 #CJK UNIFIED IDEOGRAPH + {0xD28E, 0x898F}, //14062 #CJK UNIFIED IDEOGRAPH + {0xD28F, 0x8990}, //14063 #CJK UNIFIED IDEOGRAPH + {0xD290, 0x8991}, //14064 #CJK UNIFIED IDEOGRAPH + {0xD291, 0x8992}, //14065 #CJK UNIFIED IDEOGRAPH + {0xD292, 0x8993}, //14066 #CJK UNIFIED IDEOGRAPH + {0xD293, 0x8994}, //14067 #CJK UNIFIED IDEOGRAPH + {0xD294, 0x8995}, //14068 #CJK UNIFIED IDEOGRAPH + {0xD295, 0x8996}, //14069 #CJK UNIFIED IDEOGRAPH + {0xD296, 0x8997}, //14070 #CJK UNIFIED IDEOGRAPH + {0xD297, 0x8998}, //14071 #CJK UNIFIED IDEOGRAPH + {0xD298, 0x8999}, //14072 #CJK UNIFIED IDEOGRAPH + {0xD299, 0x899A}, //14073 #CJK UNIFIED IDEOGRAPH + {0xD29A, 0x899B}, //14074 #CJK UNIFIED IDEOGRAPH + {0xD29B, 0x899C}, //14075 #CJK UNIFIED IDEOGRAPH + {0xD29C, 0x899D}, //14076 #CJK UNIFIED IDEOGRAPH + {0xD29D, 0x899E}, //14077 #CJK UNIFIED IDEOGRAPH + {0xD29E, 0x899F}, //14078 #CJK UNIFIED IDEOGRAPH + {0xD29F, 0x89A0}, //14079 #CJK UNIFIED IDEOGRAPH + {0xD2A0, 0x89A1}, //14080 #CJK UNIFIED IDEOGRAPH + {0xD2A1, 0x6447}, //14081 #CJK UNIFIED IDEOGRAPH + {0xD2A2, 0x5C27}, //14082 #CJK UNIFIED IDEOGRAPH + {0xD2A3, 0x9065}, //14083 #CJK UNIFIED IDEOGRAPH + {0xD2A4, 0x7A91}, //14084 #CJK UNIFIED IDEOGRAPH + {0xD2A5, 0x8C23}, //14085 #CJK UNIFIED IDEOGRAPH + {0xD2A6, 0x59DA}, //14086 #CJK UNIFIED IDEOGRAPH + {0xD2A7, 0x54AC}, //14087 #CJK UNIFIED IDEOGRAPH + {0xD2A8, 0x8200}, //14088 #CJK UNIFIED IDEOGRAPH + {0xD2A9, 0x836F}, //14089 #CJK UNIFIED IDEOGRAPH + {0xD2AA, 0x8981}, //14090 #CJK UNIFIED IDEOGRAPH + {0xD2AB, 0x8000}, //14091 #CJK UNIFIED IDEOGRAPH + {0xD2AC, 0x6930}, //14092 #CJK UNIFIED IDEOGRAPH + {0xD2AD, 0x564E}, //14093 #CJK UNIFIED IDEOGRAPH + {0xD2AE, 0x8036}, //14094 #CJK UNIFIED IDEOGRAPH + {0xD2AF, 0x7237}, //14095 #CJK UNIFIED IDEOGRAPH + {0xD2B0, 0x91CE}, //14096 #CJK UNIFIED IDEOGRAPH + {0xD2B1, 0x51B6}, //14097 #CJK UNIFIED IDEOGRAPH + {0xD2B2, 0x4E5F}, //14098 #CJK UNIFIED IDEOGRAPH + {0xD2B3, 0x9875}, //14099 #CJK UNIFIED IDEOGRAPH + {0xD2B4, 0x6396}, //14100 #CJK UNIFIED IDEOGRAPH + {0xD2B5, 0x4E1A}, //14101 #CJK UNIFIED IDEOGRAPH + {0xD2B6, 0x53F6}, //14102 #CJK UNIFIED IDEOGRAPH + {0xD2B7, 0x66F3}, //14103 #CJK UNIFIED IDEOGRAPH + {0xD2B8, 0x814B}, //14104 #CJK UNIFIED IDEOGRAPH + {0xD2B9, 0x591C}, //14105 #CJK UNIFIED IDEOGRAPH + {0xD2BA, 0x6DB2}, //14106 #CJK UNIFIED IDEOGRAPH + {0xD2BB, 0x4E00}, //14107 #CJK UNIFIED IDEOGRAPH + {0xD2BC, 0x58F9}, //14108 #CJK UNIFIED IDEOGRAPH + {0xD2BD, 0x533B}, //14109 #CJK UNIFIED IDEOGRAPH + {0xD2BE, 0x63D6}, //14110 #CJK UNIFIED IDEOGRAPH + {0xD2BF, 0x94F1}, //14111 #CJK UNIFIED IDEOGRAPH + {0xD2C0, 0x4F9D}, //14112 #CJK UNIFIED IDEOGRAPH + {0xD2C1, 0x4F0A}, //14113 #CJK UNIFIED IDEOGRAPH + {0xD2C2, 0x8863}, //14114 #CJK UNIFIED IDEOGRAPH + {0xD2C3, 0x9890}, //14115 #CJK UNIFIED IDEOGRAPH + {0xD2C4, 0x5937}, //14116 #CJK UNIFIED IDEOGRAPH + {0xD2C5, 0x9057}, //14117 #CJK UNIFIED IDEOGRAPH + {0xD2C6, 0x79FB}, //14118 #CJK UNIFIED IDEOGRAPH + {0xD2C7, 0x4EEA}, //14119 #CJK UNIFIED IDEOGRAPH + {0xD2C8, 0x80F0}, //14120 #CJK UNIFIED IDEOGRAPH + {0xD2C9, 0x7591}, //14121 #CJK UNIFIED IDEOGRAPH + {0xD2CA, 0x6C82}, //14122 #CJK UNIFIED IDEOGRAPH + {0xD2CB, 0x5B9C}, //14123 #CJK UNIFIED IDEOGRAPH + {0xD2CC, 0x59E8}, //14124 #CJK UNIFIED IDEOGRAPH + {0xD2CD, 0x5F5D}, //14125 #CJK UNIFIED IDEOGRAPH + {0xD2CE, 0x6905}, //14126 #CJK UNIFIED IDEOGRAPH + {0xD2CF, 0x8681}, //14127 #CJK UNIFIED IDEOGRAPH + {0xD2D0, 0x501A}, //14128 #CJK UNIFIED IDEOGRAPH + {0xD2D1, 0x5DF2}, //14129 #CJK UNIFIED IDEOGRAPH + {0xD2D2, 0x4E59}, //14130 #CJK UNIFIED IDEOGRAPH + {0xD2D3, 0x77E3}, //14131 #CJK UNIFIED IDEOGRAPH + {0xD2D4, 0x4EE5}, //14132 #CJK UNIFIED IDEOGRAPH + {0xD2D5, 0x827A}, //14133 #CJK UNIFIED IDEOGRAPH + {0xD2D6, 0x6291}, //14134 #CJK UNIFIED IDEOGRAPH + {0xD2D7, 0x6613}, //14135 #CJK UNIFIED IDEOGRAPH + {0xD2D8, 0x9091}, //14136 #CJK UNIFIED IDEOGRAPH + {0xD2D9, 0x5C79}, //14137 #CJK UNIFIED IDEOGRAPH + {0xD2DA, 0x4EBF}, //14138 #CJK UNIFIED IDEOGRAPH + {0xD2DB, 0x5F79}, //14139 #CJK UNIFIED IDEOGRAPH + {0xD2DC, 0x81C6}, //14140 #CJK UNIFIED IDEOGRAPH + {0xD2DD, 0x9038}, //14141 #CJK UNIFIED IDEOGRAPH + {0xD2DE, 0x8084}, //14142 #CJK UNIFIED IDEOGRAPH + {0xD2DF, 0x75AB}, //14143 #CJK UNIFIED IDEOGRAPH + {0xD2E0, 0x4EA6}, //14144 #CJK UNIFIED IDEOGRAPH + {0xD2E1, 0x88D4}, //14145 #CJK UNIFIED IDEOGRAPH + {0xD2E2, 0x610F}, //14146 #CJK UNIFIED IDEOGRAPH + {0xD2E3, 0x6BC5}, //14147 #CJK UNIFIED IDEOGRAPH + {0xD2E4, 0x5FC6}, //14148 #CJK UNIFIED IDEOGRAPH + {0xD2E5, 0x4E49}, //14149 #CJK UNIFIED IDEOGRAPH + {0xD2E6, 0x76CA}, //14150 #CJK UNIFIED IDEOGRAPH + {0xD2E7, 0x6EA2}, //14151 #CJK UNIFIED IDEOGRAPH + {0xD2E8, 0x8BE3}, //14152 #CJK UNIFIED IDEOGRAPH + {0xD2E9, 0x8BAE}, //14153 #CJK UNIFIED IDEOGRAPH + {0xD2EA, 0x8C0A}, //14154 #CJK UNIFIED IDEOGRAPH + {0xD2EB, 0x8BD1}, //14155 #CJK UNIFIED IDEOGRAPH + {0xD2EC, 0x5F02}, //14156 #CJK UNIFIED IDEOGRAPH + {0xD2ED, 0x7FFC}, //14157 #CJK UNIFIED IDEOGRAPH + {0xD2EE, 0x7FCC}, //14158 #CJK UNIFIED IDEOGRAPH + {0xD2EF, 0x7ECE}, //14159 #CJK UNIFIED IDEOGRAPH + {0xD2F0, 0x8335}, //14160 #CJK UNIFIED IDEOGRAPH + {0xD2F1, 0x836B}, //14161 #CJK UNIFIED IDEOGRAPH + {0xD2F2, 0x56E0}, //14162 #CJK UNIFIED IDEOGRAPH + {0xD2F3, 0x6BB7}, //14163 #CJK UNIFIED IDEOGRAPH + {0xD2F4, 0x97F3}, //14164 #CJK UNIFIED IDEOGRAPH + {0xD2F5, 0x9634}, //14165 #CJK UNIFIED IDEOGRAPH + {0xD2F6, 0x59FB}, //14166 #CJK UNIFIED IDEOGRAPH + {0xD2F7, 0x541F}, //14167 #CJK UNIFIED IDEOGRAPH + {0xD2F8, 0x94F6}, //14168 #CJK UNIFIED IDEOGRAPH + {0xD2F9, 0x6DEB}, //14169 #CJK UNIFIED IDEOGRAPH + {0xD2FA, 0x5BC5}, //14170 #CJK UNIFIED IDEOGRAPH + {0xD2FB, 0x996E}, //14171 #CJK UNIFIED IDEOGRAPH + {0xD2FC, 0x5C39}, //14172 #CJK UNIFIED IDEOGRAPH + {0xD2FD, 0x5F15}, //14173 #CJK UNIFIED IDEOGRAPH + {0xD2FE, 0x9690}, //14174 #CJK UNIFIED IDEOGRAPH + {0xD340, 0x89A2}, //14175 #CJK UNIFIED IDEOGRAPH + {0xD341, 0x89A3}, //14176 #CJK UNIFIED IDEOGRAPH + {0xD342, 0x89A4}, //14177 #CJK UNIFIED IDEOGRAPH + {0xD343, 0x89A5}, //14178 #CJK UNIFIED IDEOGRAPH + {0xD344, 0x89A6}, //14179 #CJK UNIFIED IDEOGRAPH + {0xD345, 0x89A7}, //14180 #CJK UNIFIED IDEOGRAPH + {0xD346, 0x89A8}, //14181 #CJK UNIFIED IDEOGRAPH + {0xD347, 0x89A9}, //14182 #CJK UNIFIED IDEOGRAPH + {0xD348, 0x89AA}, //14183 #CJK UNIFIED IDEOGRAPH + {0xD349, 0x89AB}, //14184 #CJK UNIFIED IDEOGRAPH + {0xD34A, 0x89AC}, //14185 #CJK UNIFIED IDEOGRAPH + {0xD34B, 0x89AD}, //14186 #CJK UNIFIED IDEOGRAPH + {0xD34C, 0x89AE}, //14187 #CJK UNIFIED IDEOGRAPH + {0xD34D, 0x89AF}, //14188 #CJK UNIFIED IDEOGRAPH + {0xD34E, 0x89B0}, //14189 #CJK UNIFIED IDEOGRAPH + {0xD34F, 0x89B1}, //14190 #CJK UNIFIED IDEOGRAPH + {0xD350, 0x89B2}, //14191 #CJK UNIFIED IDEOGRAPH + {0xD351, 0x89B3}, //14192 #CJK UNIFIED IDEOGRAPH + {0xD352, 0x89B4}, //14193 #CJK UNIFIED IDEOGRAPH + {0xD353, 0x89B5}, //14194 #CJK UNIFIED IDEOGRAPH + {0xD354, 0x89B6}, //14195 #CJK UNIFIED IDEOGRAPH + {0xD355, 0x89B7}, //14196 #CJK UNIFIED IDEOGRAPH + {0xD356, 0x89B8}, //14197 #CJK UNIFIED IDEOGRAPH + {0xD357, 0x89B9}, //14198 #CJK UNIFIED IDEOGRAPH + {0xD358, 0x89BA}, //14199 #CJK UNIFIED IDEOGRAPH + {0xD359, 0x89BB}, //14200 #CJK UNIFIED IDEOGRAPH + {0xD35A, 0x89BC}, //14201 #CJK UNIFIED IDEOGRAPH + {0xD35B, 0x89BD}, //14202 #CJK UNIFIED IDEOGRAPH + {0xD35C, 0x89BE}, //14203 #CJK UNIFIED IDEOGRAPH + {0xD35D, 0x89BF}, //14204 #CJK UNIFIED IDEOGRAPH + {0xD35E, 0x89C0}, //14205 #CJK UNIFIED IDEOGRAPH + {0xD35F, 0x89C3}, //14206 #CJK UNIFIED IDEOGRAPH + {0xD360, 0x89CD}, //14207 #CJK UNIFIED IDEOGRAPH + {0xD361, 0x89D3}, //14208 #CJK UNIFIED IDEOGRAPH + {0xD362, 0x89D4}, //14209 #CJK UNIFIED IDEOGRAPH + {0xD363, 0x89D5}, //14210 #CJK UNIFIED IDEOGRAPH + {0xD364, 0x89D7}, //14211 #CJK UNIFIED IDEOGRAPH + {0xD365, 0x89D8}, //14212 #CJK UNIFIED IDEOGRAPH + {0xD366, 0x89D9}, //14213 #CJK UNIFIED IDEOGRAPH + {0xD367, 0x89DB}, //14214 #CJK UNIFIED IDEOGRAPH + {0xD368, 0x89DD}, //14215 #CJK UNIFIED IDEOGRAPH + {0xD369, 0x89DF}, //14216 #CJK UNIFIED IDEOGRAPH + {0xD36A, 0x89E0}, //14217 #CJK UNIFIED IDEOGRAPH + {0xD36B, 0x89E1}, //14218 #CJK UNIFIED IDEOGRAPH + {0xD36C, 0x89E2}, //14219 #CJK UNIFIED IDEOGRAPH + {0xD36D, 0x89E4}, //14220 #CJK UNIFIED IDEOGRAPH + {0xD36E, 0x89E7}, //14221 #CJK UNIFIED IDEOGRAPH + {0xD36F, 0x89E8}, //14222 #CJK UNIFIED IDEOGRAPH + {0xD370, 0x89E9}, //14223 #CJK UNIFIED IDEOGRAPH + {0xD371, 0x89EA}, //14224 #CJK UNIFIED IDEOGRAPH + {0xD372, 0x89EC}, //14225 #CJK UNIFIED IDEOGRAPH + {0xD373, 0x89ED}, //14226 #CJK UNIFIED IDEOGRAPH + {0xD374, 0x89EE}, //14227 #CJK UNIFIED IDEOGRAPH + {0xD375, 0x89F0}, //14228 #CJK UNIFIED IDEOGRAPH + {0xD376, 0x89F1}, //14229 #CJK UNIFIED IDEOGRAPH + {0xD377, 0x89F2}, //14230 #CJK UNIFIED IDEOGRAPH + {0xD378, 0x89F4}, //14231 #CJK UNIFIED IDEOGRAPH + {0xD379, 0x89F5}, //14232 #CJK UNIFIED IDEOGRAPH + {0xD37A, 0x89F6}, //14233 #CJK UNIFIED IDEOGRAPH + {0xD37B, 0x89F7}, //14234 #CJK UNIFIED IDEOGRAPH + {0xD37C, 0x89F8}, //14235 #CJK UNIFIED IDEOGRAPH + {0xD37D, 0x89F9}, //14236 #CJK UNIFIED IDEOGRAPH + {0xD37E, 0x89FA}, //14237 #CJK UNIFIED IDEOGRAPH + {0xD380, 0x89FB}, //14238 #CJK UNIFIED IDEOGRAPH + {0xD381, 0x89FC}, //14239 #CJK UNIFIED IDEOGRAPH + {0xD382, 0x89FD}, //14240 #CJK UNIFIED IDEOGRAPH + {0xD383, 0x89FE}, //14241 #CJK UNIFIED IDEOGRAPH + {0xD384, 0x89FF}, //14242 #CJK UNIFIED IDEOGRAPH + {0xD385, 0x8A01}, //14243 #CJK UNIFIED IDEOGRAPH + {0xD386, 0x8A02}, //14244 #CJK UNIFIED IDEOGRAPH + {0xD387, 0x8A03}, //14245 #CJK UNIFIED IDEOGRAPH + {0xD388, 0x8A04}, //14246 #CJK UNIFIED IDEOGRAPH + {0xD389, 0x8A05}, //14247 #CJK UNIFIED IDEOGRAPH + {0xD38A, 0x8A06}, //14248 #CJK UNIFIED IDEOGRAPH + {0xD38B, 0x8A08}, //14249 #CJK UNIFIED IDEOGRAPH + {0xD38C, 0x8A09}, //14250 #CJK UNIFIED IDEOGRAPH + {0xD38D, 0x8A0A}, //14251 #CJK UNIFIED IDEOGRAPH + {0xD38E, 0x8A0B}, //14252 #CJK UNIFIED IDEOGRAPH + {0xD38F, 0x8A0C}, //14253 #CJK UNIFIED IDEOGRAPH + {0xD390, 0x8A0D}, //14254 #CJK UNIFIED IDEOGRAPH + {0xD391, 0x8A0E}, //14255 #CJK UNIFIED IDEOGRAPH + {0xD392, 0x8A0F}, //14256 #CJK UNIFIED IDEOGRAPH + {0xD393, 0x8A10}, //14257 #CJK UNIFIED IDEOGRAPH + {0xD394, 0x8A11}, //14258 #CJK UNIFIED IDEOGRAPH + {0xD395, 0x8A12}, //14259 #CJK UNIFIED IDEOGRAPH + {0xD396, 0x8A13}, //14260 #CJK UNIFIED IDEOGRAPH + {0xD397, 0x8A14}, //14261 #CJK UNIFIED IDEOGRAPH + {0xD398, 0x8A15}, //14262 #CJK UNIFIED IDEOGRAPH + {0xD399, 0x8A16}, //14263 #CJK UNIFIED IDEOGRAPH + {0xD39A, 0x8A17}, //14264 #CJK UNIFIED IDEOGRAPH + {0xD39B, 0x8A18}, //14265 #CJK UNIFIED IDEOGRAPH + {0xD39C, 0x8A19}, //14266 #CJK UNIFIED IDEOGRAPH + {0xD39D, 0x8A1A}, //14267 #CJK UNIFIED IDEOGRAPH + {0xD39E, 0x8A1B}, //14268 #CJK UNIFIED IDEOGRAPH + {0xD39F, 0x8A1C}, //14269 #CJK UNIFIED IDEOGRAPH + {0xD3A0, 0x8A1D}, //14270 #CJK UNIFIED IDEOGRAPH + {0xD3A1, 0x5370}, //14271 #CJK UNIFIED IDEOGRAPH + {0xD3A2, 0x82F1}, //14272 #CJK UNIFIED IDEOGRAPH + {0xD3A3, 0x6A31}, //14273 #CJK UNIFIED IDEOGRAPH + {0xD3A4, 0x5A74}, //14274 #CJK UNIFIED IDEOGRAPH + {0xD3A5, 0x9E70}, //14275 #CJK UNIFIED IDEOGRAPH + {0xD3A6, 0x5E94}, //14276 #CJK UNIFIED IDEOGRAPH + {0xD3A7, 0x7F28}, //14277 #CJK UNIFIED IDEOGRAPH + {0xD3A8, 0x83B9}, //14278 #CJK UNIFIED IDEOGRAPH + {0xD3A9, 0x8424}, //14279 #CJK UNIFIED IDEOGRAPH + {0xD3AA, 0x8425}, //14280 #CJK UNIFIED IDEOGRAPH + {0xD3AB, 0x8367}, //14281 #CJK UNIFIED IDEOGRAPH + {0xD3AC, 0x8747}, //14282 #CJK UNIFIED IDEOGRAPH + {0xD3AD, 0x8FCE}, //14283 #CJK UNIFIED IDEOGRAPH + {0xD3AE, 0x8D62}, //14284 #CJK UNIFIED IDEOGRAPH + {0xD3AF, 0x76C8}, //14285 #CJK UNIFIED IDEOGRAPH + {0xD3B0, 0x5F71}, //14286 #CJK UNIFIED IDEOGRAPH + {0xD3B1, 0x9896}, //14287 #CJK UNIFIED IDEOGRAPH + {0xD3B2, 0x786C}, //14288 #CJK UNIFIED IDEOGRAPH + {0xD3B3, 0x6620}, //14289 #CJK UNIFIED IDEOGRAPH + {0xD3B4, 0x54DF}, //14290 #CJK UNIFIED IDEOGRAPH + {0xD3B5, 0x62E5}, //14291 #CJK UNIFIED IDEOGRAPH + {0xD3B6, 0x4F63}, //14292 #CJK UNIFIED IDEOGRAPH + {0xD3B7, 0x81C3}, //14293 #CJK UNIFIED IDEOGRAPH + {0xD3B8, 0x75C8}, //14294 #CJK UNIFIED IDEOGRAPH + {0xD3B9, 0x5EB8}, //14295 #CJK UNIFIED IDEOGRAPH + {0xD3BA, 0x96CD}, //14296 #CJK UNIFIED IDEOGRAPH + {0xD3BB, 0x8E0A}, //14297 #CJK UNIFIED IDEOGRAPH + {0xD3BC, 0x86F9}, //14298 #CJK UNIFIED IDEOGRAPH + {0xD3BD, 0x548F}, //14299 #CJK UNIFIED IDEOGRAPH + {0xD3BE, 0x6CF3}, //14300 #CJK UNIFIED IDEOGRAPH + {0xD3BF, 0x6D8C}, //14301 #CJK UNIFIED IDEOGRAPH + {0xD3C0, 0x6C38}, //14302 #CJK UNIFIED IDEOGRAPH + {0xD3C1, 0x607F}, //14303 #CJK UNIFIED IDEOGRAPH + {0xD3C2, 0x52C7}, //14304 #CJK UNIFIED IDEOGRAPH + {0xD3C3, 0x7528}, //14305 #CJK UNIFIED IDEOGRAPH + {0xD3C4, 0x5E7D}, //14306 #CJK UNIFIED IDEOGRAPH + {0xD3C5, 0x4F18}, //14307 #CJK UNIFIED IDEOGRAPH + {0xD3C6, 0x60A0}, //14308 #CJK UNIFIED IDEOGRAPH + {0xD3C7, 0x5FE7}, //14309 #CJK UNIFIED IDEOGRAPH + {0xD3C8, 0x5C24}, //14310 #CJK UNIFIED IDEOGRAPH + {0xD3C9, 0x7531}, //14311 #CJK UNIFIED IDEOGRAPH + {0xD3CA, 0x90AE}, //14312 #CJK UNIFIED IDEOGRAPH + {0xD3CB, 0x94C0}, //14313 #CJK UNIFIED IDEOGRAPH + {0xD3CC, 0x72B9}, //14314 #CJK UNIFIED IDEOGRAPH + {0xD3CD, 0x6CB9}, //14315 #CJK UNIFIED IDEOGRAPH + {0xD3CE, 0x6E38}, //14316 #CJK UNIFIED IDEOGRAPH + {0xD3CF, 0x9149}, //14317 #CJK UNIFIED IDEOGRAPH + {0xD3D0, 0x6709}, //14318 #CJK UNIFIED IDEOGRAPH + {0xD3D1, 0x53CB}, //14319 #CJK UNIFIED IDEOGRAPH + {0xD3D2, 0x53F3}, //14320 #CJK UNIFIED IDEOGRAPH + {0xD3D3, 0x4F51}, //14321 #CJK UNIFIED IDEOGRAPH + {0xD3D4, 0x91C9}, //14322 #CJK UNIFIED IDEOGRAPH + {0xD3D5, 0x8BF1}, //14323 #CJK UNIFIED IDEOGRAPH + {0xD3D6, 0x53C8}, //14324 #CJK UNIFIED IDEOGRAPH + {0xD3D7, 0x5E7C}, //14325 #CJK UNIFIED IDEOGRAPH + {0xD3D8, 0x8FC2}, //14326 #CJK UNIFIED IDEOGRAPH + {0xD3D9, 0x6DE4}, //14327 #CJK UNIFIED IDEOGRAPH + {0xD3DA, 0x4E8E}, //14328 #CJK UNIFIED IDEOGRAPH + {0xD3DB, 0x76C2}, //14329 #CJK UNIFIED IDEOGRAPH + {0xD3DC, 0x6986}, //14330 #CJK UNIFIED IDEOGRAPH + {0xD3DD, 0x865E}, //14331 #CJK UNIFIED IDEOGRAPH + {0xD3DE, 0x611A}, //14332 #CJK UNIFIED IDEOGRAPH + {0xD3DF, 0x8206}, //14333 #CJK UNIFIED IDEOGRAPH + {0xD3E0, 0x4F59}, //14334 #CJK UNIFIED IDEOGRAPH + {0xD3E1, 0x4FDE}, //14335 #CJK UNIFIED IDEOGRAPH + {0xD3E2, 0x903E}, //14336 #CJK UNIFIED IDEOGRAPH + {0xD3E3, 0x9C7C}, //14337 #CJK UNIFIED IDEOGRAPH + {0xD3E4, 0x6109}, //14338 #CJK UNIFIED IDEOGRAPH + {0xD3E5, 0x6E1D}, //14339 #CJK UNIFIED IDEOGRAPH + {0xD3E6, 0x6E14}, //14340 #CJK UNIFIED IDEOGRAPH + {0xD3E7, 0x9685}, //14341 #CJK UNIFIED IDEOGRAPH + {0xD3E8, 0x4E88}, //14342 #CJK UNIFIED IDEOGRAPH + {0xD3E9, 0x5A31}, //14343 #CJK UNIFIED IDEOGRAPH + {0xD3EA, 0x96E8}, //14344 #CJK UNIFIED IDEOGRAPH + {0xD3EB, 0x4E0E}, //14345 #CJK UNIFIED IDEOGRAPH + {0xD3EC, 0x5C7F}, //14346 #CJK UNIFIED IDEOGRAPH + {0xD3ED, 0x79B9}, //14347 #CJK UNIFIED IDEOGRAPH + {0xD3EE, 0x5B87}, //14348 #CJK UNIFIED IDEOGRAPH + {0xD3EF, 0x8BED}, //14349 #CJK UNIFIED IDEOGRAPH + {0xD3F0, 0x7FBD}, //14350 #CJK UNIFIED IDEOGRAPH + {0xD3F1, 0x7389}, //14351 #CJK UNIFIED IDEOGRAPH + {0xD3F2, 0x57DF}, //14352 #CJK UNIFIED IDEOGRAPH + {0xD3F3, 0x828B}, //14353 #CJK UNIFIED IDEOGRAPH + {0xD3F4, 0x90C1}, //14354 #CJK UNIFIED IDEOGRAPH + {0xD3F5, 0x5401}, //14355 #CJK UNIFIED IDEOGRAPH + {0xD3F6, 0x9047}, //14356 #CJK UNIFIED IDEOGRAPH + {0xD3F7, 0x55BB}, //14357 #CJK UNIFIED IDEOGRAPH + {0xD3F8, 0x5CEA}, //14358 #CJK UNIFIED IDEOGRAPH + {0xD3F9, 0x5FA1}, //14359 #CJK UNIFIED IDEOGRAPH + {0xD3FA, 0x6108}, //14360 #CJK UNIFIED IDEOGRAPH + {0xD3FB, 0x6B32}, //14361 #CJK UNIFIED IDEOGRAPH + {0xD3FC, 0x72F1}, //14362 #CJK UNIFIED IDEOGRAPH + {0xD3FD, 0x80B2}, //14363 #CJK UNIFIED IDEOGRAPH + {0xD3FE, 0x8A89}, //14364 #CJK UNIFIED IDEOGRAPH + {0xD440, 0x8A1E}, //14365 #CJK UNIFIED IDEOGRAPH + {0xD441, 0x8A1F}, //14366 #CJK UNIFIED IDEOGRAPH + {0xD442, 0x8A20}, //14367 #CJK UNIFIED IDEOGRAPH + {0xD443, 0x8A21}, //14368 #CJK UNIFIED IDEOGRAPH + {0xD444, 0x8A22}, //14369 #CJK UNIFIED IDEOGRAPH + {0xD445, 0x8A23}, //14370 #CJK UNIFIED IDEOGRAPH + {0xD446, 0x8A24}, //14371 #CJK UNIFIED IDEOGRAPH + {0xD447, 0x8A25}, //14372 #CJK UNIFIED IDEOGRAPH + {0xD448, 0x8A26}, //14373 #CJK UNIFIED IDEOGRAPH + {0xD449, 0x8A27}, //14374 #CJK UNIFIED IDEOGRAPH + {0xD44A, 0x8A28}, //14375 #CJK UNIFIED IDEOGRAPH + {0xD44B, 0x8A29}, //14376 #CJK UNIFIED IDEOGRAPH + {0xD44C, 0x8A2A}, //14377 #CJK UNIFIED IDEOGRAPH + {0xD44D, 0x8A2B}, //14378 #CJK UNIFIED IDEOGRAPH + {0xD44E, 0x8A2C}, //14379 #CJK UNIFIED IDEOGRAPH + {0xD44F, 0x8A2D}, //14380 #CJK UNIFIED IDEOGRAPH + {0xD450, 0x8A2E}, //14381 #CJK UNIFIED IDEOGRAPH + {0xD451, 0x8A2F}, //14382 #CJK UNIFIED IDEOGRAPH + {0xD452, 0x8A30}, //14383 #CJK UNIFIED IDEOGRAPH + {0xD453, 0x8A31}, //14384 #CJK UNIFIED IDEOGRAPH + {0xD454, 0x8A32}, //14385 #CJK UNIFIED IDEOGRAPH + {0xD455, 0x8A33}, //14386 #CJK UNIFIED IDEOGRAPH + {0xD456, 0x8A34}, //14387 #CJK UNIFIED IDEOGRAPH + {0xD457, 0x8A35}, //14388 #CJK UNIFIED IDEOGRAPH + {0xD458, 0x8A36}, //14389 #CJK UNIFIED IDEOGRAPH + {0xD459, 0x8A37}, //14390 #CJK UNIFIED IDEOGRAPH + {0xD45A, 0x8A38}, //14391 #CJK UNIFIED IDEOGRAPH + {0xD45B, 0x8A39}, //14392 #CJK UNIFIED IDEOGRAPH + {0xD45C, 0x8A3A}, //14393 #CJK UNIFIED IDEOGRAPH + {0xD45D, 0x8A3B}, //14394 #CJK UNIFIED IDEOGRAPH + {0xD45E, 0x8A3C}, //14395 #CJK UNIFIED IDEOGRAPH + {0xD45F, 0x8A3D}, //14396 #CJK UNIFIED IDEOGRAPH + {0xD460, 0x8A3F}, //14397 #CJK UNIFIED IDEOGRAPH + {0xD461, 0x8A40}, //14398 #CJK UNIFIED IDEOGRAPH + {0xD462, 0x8A41}, //14399 #CJK UNIFIED IDEOGRAPH + {0xD463, 0x8A42}, //14400 #CJK UNIFIED IDEOGRAPH + {0xD464, 0x8A43}, //14401 #CJK UNIFIED IDEOGRAPH + {0xD465, 0x8A44}, //14402 #CJK UNIFIED IDEOGRAPH + {0xD466, 0x8A45}, //14403 #CJK UNIFIED IDEOGRAPH + {0xD467, 0x8A46}, //14404 #CJK UNIFIED IDEOGRAPH + {0xD468, 0x8A47}, //14405 #CJK UNIFIED IDEOGRAPH + {0xD469, 0x8A49}, //14406 #CJK UNIFIED IDEOGRAPH + {0xD46A, 0x8A4A}, //14407 #CJK UNIFIED IDEOGRAPH + {0xD46B, 0x8A4B}, //14408 #CJK UNIFIED IDEOGRAPH + {0xD46C, 0x8A4C}, //14409 #CJK UNIFIED IDEOGRAPH + {0xD46D, 0x8A4D}, //14410 #CJK UNIFIED IDEOGRAPH + {0xD46E, 0x8A4E}, //14411 #CJK UNIFIED IDEOGRAPH + {0xD46F, 0x8A4F}, //14412 #CJK UNIFIED IDEOGRAPH + {0xD470, 0x8A50}, //14413 #CJK UNIFIED IDEOGRAPH + {0xD471, 0x8A51}, //14414 #CJK UNIFIED IDEOGRAPH + {0xD472, 0x8A52}, //14415 #CJK UNIFIED IDEOGRAPH + {0xD473, 0x8A53}, //14416 #CJK UNIFIED IDEOGRAPH + {0xD474, 0x8A54}, //14417 #CJK UNIFIED IDEOGRAPH + {0xD475, 0x8A55}, //14418 #CJK UNIFIED IDEOGRAPH + {0xD476, 0x8A56}, //14419 #CJK UNIFIED IDEOGRAPH + {0xD477, 0x8A57}, //14420 #CJK UNIFIED IDEOGRAPH + {0xD478, 0x8A58}, //14421 #CJK UNIFIED IDEOGRAPH + {0xD479, 0x8A59}, //14422 #CJK UNIFIED IDEOGRAPH + {0xD47A, 0x8A5A}, //14423 #CJK UNIFIED IDEOGRAPH + {0xD47B, 0x8A5B}, //14424 #CJK UNIFIED IDEOGRAPH + {0xD47C, 0x8A5C}, //14425 #CJK UNIFIED IDEOGRAPH + {0xD47D, 0x8A5D}, //14426 #CJK UNIFIED IDEOGRAPH + {0xD47E, 0x8A5E}, //14427 #CJK UNIFIED IDEOGRAPH + {0xD480, 0x8A5F}, //14428 #CJK UNIFIED IDEOGRAPH + {0xD481, 0x8A60}, //14429 #CJK UNIFIED IDEOGRAPH + {0xD482, 0x8A61}, //14430 #CJK UNIFIED IDEOGRAPH + {0xD483, 0x8A62}, //14431 #CJK UNIFIED IDEOGRAPH + {0xD484, 0x8A63}, //14432 #CJK UNIFIED IDEOGRAPH + {0xD485, 0x8A64}, //14433 #CJK UNIFIED IDEOGRAPH + {0xD486, 0x8A65}, //14434 #CJK UNIFIED IDEOGRAPH + {0xD487, 0x8A66}, //14435 #CJK UNIFIED IDEOGRAPH + {0xD488, 0x8A67}, //14436 #CJK UNIFIED IDEOGRAPH + {0xD489, 0x8A68}, //14437 #CJK UNIFIED IDEOGRAPH + {0xD48A, 0x8A69}, //14438 #CJK UNIFIED IDEOGRAPH + {0xD48B, 0x8A6A}, //14439 #CJK UNIFIED IDEOGRAPH + {0xD48C, 0x8A6B}, //14440 #CJK UNIFIED IDEOGRAPH + {0xD48D, 0x8A6C}, //14441 #CJK UNIFIED IDEOGRAPH + {0xD48E, 0x8A6D}, //14442 #CJK UNIFIED IDEOGRAPH + {0xD48F, 0x8A6E}, //14443 #CJK UNIFIED IDEOGRAPH + {0xD490, 0x8A6F}, //14444 #CJK UNIFIED IDEOGRAPH + {0xD491, 0x8A70}, //14445 #CJK UNIFIED IDEOGRAPH + {0xD492, 0x8A71}, //14446 #CJK UNIFIED IDEOGRAPH + {0xD493, 0x8A72}, //14447 #CJK UNIFIED IDEOGRAPH + {0xD494, 0x8A73}, //14448 #CJK UNIFIED IDEOGRAPH + {0xD495, 0x8A74}, //14449 #CJK UNIFIED IDEOGRAPH + {0xD496, 0x8A75}, //14450 #CJK UNIFIED IDEOGRAPH + {0xD497, 0x8A76}, //14451 #CJK UNIFIED IDEOGRAPH + {0xD498, 0x8A77}, //14452 #CJK UNIFIED IDEOGRAPH + {0xD499, 0x8A78}, //14453 #CJK UNIFIED IDEOGRAPH + {0xD49A, 0x8A7A}, //14454 #CJK UNIFIED IDEOGRAPH + {0xD49B, 0x8A7B}, //14455 #CJK UNIFIED IDEOGRAPH + {0xD49C, 0x8A7C}, //14456 #CJK UNIFIED IDEOGRAPH + {0xD49D, 0x8A7D}, //14457 #CJK UNIFIED IDEOGRAPH + {0xD49E, 0x8A7E}, //14458 #CJK UNIFIED IDEOGRAPH + {0xD49F, 0x8A7F}, //14459 #CJK UNIFIED IDEOGRAPH + {0xD4A0, 0x8A80}, //14460 #CJK UNIFIED IDEOGRAPH + {0xD4A1, 0x6D74}, //14461 #CJK UNIFIED IDEOGRAPH + {0xD4A2, 0x5BD3}, //14462 #CJK UNIFIED IDEOGRAPH + {0xD4A3, 0x88D5}, //14463 #CJK UNIFIED IDEOGRAPH + {0xD4A4, 0x9884}, //14464 #CJK UNIFIED IDEOGRAPH + {0xD4A5, 0x8C6B}, //14465 #CJK UNIFIED IDEOGRAPH + {0xD4A6, 0x9A6D}, //14466 #CJK UNIFIED IDEOGRAPH + {0xD4A7, 0x9E33}, //14467 #CJK UNIFIED IDEOGRAPH + {0xD4A8, 0x6E0A}, //14468 #CJK UNIFIED IDEOGRAPH + {0xD4A9, 0x51A4}, //14469 #CJK UNIFIED IDEOGRAPH + {0xD4AA, 0x5143}, //14470 #CJK UNIFIED IDEOGRAPH + {0xD4AB, 0x57A3}, //14471 #CJK UNIFIED IDEOGRAPH + {0xD4AC, 0x8881}, //14472 #CJK UNIFIED IDEOGRAPH + {0xD4AD, 0x539F}, //14473 #CJK UNIFIED IDEOGRAPH + {0xD4AE, 0x63F4}, //14474 #CJK UNIFIED IDEOGRAPH + {0xD4AF, 0x8F95}, //14475 #CJK UNIFIED IDEOGRAPH + {0xD4B0, 0x56ED}, //14476 #CJK UNIFIED IDEOGRAPH + {0xD4B1, 0x5458}, //14477 #CJK UNIFIED IDEOGRAPH + {0xD4B2, 0x5706}, //14478 #CJK UNIFIED IDEOGRAPH + {0xD4B3, 0x733F}, //14479 #CJK UNIFIED IDEOGRAPH + {0xD4B4, 0x6E90}, //14480 #CJK UNIFIED IDEOGRAPH + {0xD4B5, 0x7F18}, //14481 #CJK UNIFIED IDEOGRAPH + {0xD4B6, 0x8FDC}, //14482 #CJK UNIFIED IDEOGRAPH + {0xD4B7, 0x82D1}, //14483 #CJK UNIFIED IDEOGRAPH + {0xD4B8, 0x613F}, //14484 #CJK UNIFIED IDEOGRAPH + {0xD4B9, 0x6028}, //14485 #CJK UNIFIED IDEOGRAPH + {0xD4BA, 0x9662}, //14486 #CJK UNIFIED IDEOGRAPH + {0xD4BB, 0x66F0}, //14487 #CJK UNIFIED IDEOGRAPH + {0xD4BC, 0x7EA6}, //14488 #CJK UNIFIED IDEOGRAPH + {0xD4BD, 0x8D8A}, //14489 #CJK UNIFIED IDEOGRAPH + {0xD4BE, 0x8DC3}, //14490 #CJK UNIFIED IDEOGRAPH + {0xD4BF, 0x94A5}, //14491 #CJK UNIFIED IDEOGRAPH + {0xD4C0, 0x5CB3}, //14492 #CJK UNIFIED IDEOGRAPH + {0xD4C1, 0x7CA4}, //14493 #CJK UNIFIED IDEOGRAPH + {0xD4C2, 0x6708}, //14494 #CJK UNIFIED IDEOGRAPH + {0xD4C3, 0x60A6}, //14495 #CJK UNIFIED IDEOGRAPH + {0xD4C4, 0x9605}, //14496 #CJK UNIFIED IDEOGRAPH + {0xD4C5, 0x8018}, //14497 #CJK UNIFIED IDEOGRAPH + {0xD4C6, 0x4E91}, //14498 #CJK UNIFIED IDEOGRAPH + {0xD4C7, 0x90E7}, //14499 #CJK UNIFIED IDEOGRAPH + {0xD4C8, 0x5300}, //14500 #CJK UNIFIED IDEOGRAPH + {0xD4C9, 0x9668}, //14501 #CJK UNIFIED IDEOGRAPH + {0xD4CA, 0x5141}, //14502 #CJK UNIFIED IDEOGRAPH + {0xD4CB, 0x8FD0}, //14503 #CJK UNIFIED IDEOGRAPH + {0xD4CC, 0x8574}, //14504 #CJK UNIFIED IDEOGRAPH + {0xD4CD, 0x915D}, //14505 #CJK UNIFIED IDEOGRAPH + {0xD4CE, 0x6655}, //14506 #CJK UNIFIED IDEOGRAPH + {0xD4CF, 0x97F5}, //14507 #CJK UNIFIED IDEOGRAPH + {0xD4D0, 0x5B55}, //14508 #CJK UNIFIED IDEOGRAPH + {0xD4D1, 0x531D}, //14509 #CJK UNIFIED IDEOGRAPH + {0xD4D2, 0x7838}, //14510 #CJK UNIFIED IDEOGRAPH + {0xD4D3, 0x6742}, //14511 #CJK UNIFIED IDEOGRAPH + {0xD4D4, 0x683D}, //14512 #CJK UNIFIED IDEOGRAPH + {0xD4D5, 0x54C9}, //14513 #CJK UNIFIED IDEOGRAPH + {0xD4D6, 0x707E}, //14514 #CJK UNIFIED IDEOGRAPH + {0xD4D7, 0x5BB0}, //14515 #CJK UNIFIED IDEOGRAPH + {0xD4D8, 0x8F7D}, //14516 #CJK UNIFIED IDEOGRAPH + {0xD4D9, 0x518D}, //14517 #CJK UNIFIED IDEOGRAPH + {0xD4DA, 0x5728}, //14518 #CJK UNIFIED IDEOGRAPH + {0xD4DB, 0x54B1}, //14519 #CJK UNIFIED IDEOGRAPH + {0xD4DC, 0x6512}, //14520 #CJK UNIFIED IDEOGRAPH + {0xD4DD, 0x6682}, //14521 #CJK UNIFIED IDEOGRAPH + {0xD4DE, 0x8D5E}, //14522 #CJK UNIFIED IDEOGRAPH + {0xD4DF, 0x8D43}, //14523 #CJK UNIFIED IDEOGRAPH + {0xD4E0, 0x810F}, //14524 #CJK UNIFIED IDEOGRAPH + {0xD4E1, 0x846C}, //14525 #CJK UNIFIED IDEOGRAPH + {0xD4E2, 0x906D}, //14526 #CJK UNIFIED IDEOGRAPH + {0xD4E3, 0x7CDF}, //14527 #CJK UNIFIED IDEOGRAPH + {0xD4E4, 0x51FF}, //14528 #CJK UNIFIED IDEOGRAPH + {0xD4E5, 0x85FB}, //14529 #CJK UNIFIED IDEOGRAPH + {0xD4E6, 0x67A3}, //14530 #CJK UNIFIED IDEOGRAPH + {0xD4E7, 0x65E9}, //14531 #CJK UNIFIED IDEOGRAPH + {0xD4E8, 0x6FA1}, //14532 #CJK UNIFIED IDEOGRAPH + {0xD4E9, 0x86A4}, //14533 #CJK UNIFIED IDEOGRAPH + {0xD4EA, 0x8E81}, //14534 #CJK UNIFIED IDEOGRAPH + {0xD4EB, 0x566A}, //14535 #CJK UNIFIED IDEOGRAPH + {0xD4EC, 0x9020}, //14536 #CJK UNIFIED IDEOGRAPH + {0xD4ED, 0x7682}, //14537 #CJK UNIFIED IDEOGRAPH + {0xD4EE, 0x7076}, //14538 #CJK UNIFIED IDEOGRAPH + {0xD4EF, 0x71E5}, //14539 #CJK UNIFIED IDEOGRAPH + {0xD4F0, 0x8D23}, //14540 #CJK UNIFIED IDEOGRAPH + {0xD4F1, 0x62E9}, //14541 #CJK UNIFIED IDEOGRAPH + {0xD4F2, 0x5219}, //14542 #CJK UNIFIED IDEOGRAPH + {0xD4F3, 0x6CFD}, //14543 #CJK UNIFIED IDEOGRAPH + {0xD4F4, 0x8D3C}, //14544 #CJK UNIFIED IDEOGRAPH + {0xD4F5, 0x600E}, //14545 #CJK UNIFIED IDEOGRAPH + {0xD4F6, 0x589E}, //14546 #CJK UNIFIED IDEOGRAPH + {0xD4F7, 0x618E}, //14547 #CJK UNIFIED IDEOGRAPH + {0xD4F8, 0x66FE}, //14548 #CJK UNIFIED IDEOGRAPH + {0xD4F9, 0x8D60}, //14549 #CJK UNIFIED IDEOGRAPH + {0xD4FA, 0x624E}, //14550 #CJK UNIFIED IDEOGRAPH + {0xD4FB, 0x55B3}, //14551 #CJK UNIFIED IDEOGRAPH + {0xD4FC, 0x6E23}, //14552 #CJK UNIFIED IDEOGRAPH + {0xD4FD, 0x672D}, //14553 #CJK UNIFIED IDEOGRAPH + {0xD4FE, 0x8F67}, //14554 #CJK UNIFIED IDEOGRAPH + {0xD540, 0x8A81}, //14555 #CJK UNIFIED IDEOGRAPH + {0xD541, 0x8A82}, //14556 #CJK UNIFIED IDEOGRAPH + {0xD542, 0x8A83}, //14557 #CJK UNIFIED IDEOGRAPH + {0xD543, 0x8A84}, //14558 #CJK UNIFIED IDEOGRAPH + {0xD544, 0x8A85}, //14559 #CJK UNIFIED IDEOGRAPH + {0xD545, 0x8A86}, //14560 #CJK UNIFIED IDEOGRAPH + {0xD546, 0x8A87}, //14561 #CJK UNIFIED IDEOGRAPH + {0xD547, 0x8A88}, //14562 #CJK UNIFIED IDEOGRAPH + {0xD548, 0x8A8B}, //14563 #CJK UNIFIED IDEOGRAPH + {0xD549, 0x8A8C}, //14564 #CJK UNIFIED IDEOGRAPH + {0xD54A, 0x8A8D}, //14565 #CJK UNIFIED IDEOGRAPH + {0xD54B, 0x8A8E}, //14566 #CJK UNIFIED IDEOGRAPH + {0xD54C, 0x8A8F}, //14567 #CJK UNIFIED IDEOGRAPH + {0xD54D, 0x8A90}, //14568 #CJK UNIFIED IDEOGRAPH + {0xD54E, 0x8A91}, //14569 #CJK UNIFIED IDEOGRAPH + {0xD54F, 0x8A92}, //14570 #CJK UNIFIED IDEOGRAPH + {0xD550, 0x8A94}, //14571 #CJK UNIFIED IDEOGRAPH + {0xD551, 0x8A95}, //14572 #CJK UNIFIED IDEOGRAPH + {0xD552, 0x8A96}, //14573 #CJK UNIFIED IDEOGRAPH + {0xD553, 0x8A97}, //14574 #CJK UNIFIED IDEOGRAPH + {0xD554, 0x8A98}, //14575 #CJK UNIFIED IDEOGRAPH + {0xD555, 0x8A99}, //14576 #CJK UNIFIED IDEOGRAPH + {0xD556, 0x8A9A}, //14577 #CJK UNIFIED IDEOGRAPH + {0xD557, 0x8A9B}, //14578 #CJK UNIFIED IDEOGRAPH + {0xD558, 0x8A9C}, //14579 #CJK UNIFIED IDEOGRAPH + {0xD559, 0x8A9D}, //14580 #CJK UNIFIED IDEOGRAPH + {0xD55A, 0x8A9E}, //14581 #CJK UNIFIED IDEOGRAPH + {0xD55B, 0x8A9F}, //14582 #CJK UNIFIED IDEOGRAPH + {0xD55C, 0x8AA0}, //14583 #CJK UNIFIED IDEOGRAPH + {0xD55D, 0x8AA1}, //14584 #CJK UNIFIED IDEOGRAPH + {0xD55E, 0x8AA2}, //14585 #CJK UNIFIED IDEOGRAPH + {0xD55F, 0x8AA3}, //14586 #CJK UNIFIED IDEOGRAPH + {0xD560, 0x8AA4}, //14587 #CJK UNIFIED IDEOGRAPH + {0xD561, 0x8AA5}, //14588 #CJK UNIFIED IDEOGRAPH + {0xD562, 0x8AA6}, //14589 #CJK UNIFIED IDEOGRAPH + {0xD563, 0x8AA7}, //14590 #CJK UNIFIED IDEOGRAPH + {0xD564, 0x8AA8}, //14591 #CJK UNIFIED IDEOGRAPH + {0xD565, 0x8AA9}, //14592 #CJK UNIFIED IDEOGRAPH + {0xD566, 0x8AAA}, //14593 #CJK UNIFIED IDEOGRAPH + {0xD567, 0x8AAB}, //14594 #CJK UNIFIED IDEOGRAPH + {0xD568, 0x8AAC}, //14595 #CJK UNIFIED IDEOGRAPH + {0xD569, 0x8AAD}, //14596 #CJK UNIFIED IDEOGRAPH + {0xD56A, 0x8AAE}, //14597 #CJK UNIFIED IDEOGRAPH + {0xD56B, 0x8AAF}, //14598 #CJK UNIFIED IDEOGRAPH + {0xD56C, 0x8AB0}, //14599 #CJK UNIFIED IDEOGRAPH + {0xD56D, 0x8AB1}, //14600 #CJK UNIFIED IDEOGRAPH + {0xD56E, 0x8AB2}, //14601 #CJK UNIFIED IDEOGRAPH + {0xD56F, 0x8AB3}, //14602 #CJK UNIFIED IDEOGRAPH + {0xD570, 0x8AB4}, //14603 #CJK UNIFIED IDEOGRAPH + {0xD571, 0x8AB5}, //14604 #CJK UNIFIED IDEOGRAPH + {0xD572, 0x8AB6}, //14605 #CJK UNIFIED IDEOGRAPH + {0xD573, 0x8AB7}, //14606 #CJK UNIFIED IDEOGRAPH + {0xD574, 0x8AB8}, //14607 #CJK UNIFIED IDEOGRAPH + {0xD575, 0x8AB9}, //14608 #CJK UNIFIED IDEOGRAPH + {0xD576, 0x8ABA}, //14609 #CJK UNIFIED IDEOGRAPH + {0xD577, 0x8ABB}, //14610 #CJK UNIFIED IDEOGRAPH + {0xD578, 0x8ABC}, //14611 #CJK UNIFIED IDEOGRAPH + {0xD579, 0x8ABD}, //14612 #CJK UNIFIED IDEOGRAPH + {0xD57A, 0x8ABE}, //14613 #CJK UNIFIED IDEOGRAPH + {0xD57B, 0x8ABF}, //14614 #CJK UNIFIED IDEOGRAPH + {0xD57C, 0x8AC0}, //14615 #CJK UNIFIED IDEOGRAPH + {0xD57D, 0x8AC1}, //14616 #CJK UNIFIED IDEOGRAPH + {0xD57E, 0x8AC2}, //14617 #CJK UNIFIED IDEOGRAPH + {0xD580, 0x8AC3}, //14618 #CJK UNIFIED IDEOGRAPH + {0xD581, 0x8AC4}, //14619 #CJK UNIFIED IDEOGRAPH + {0xD582, 0x8AC5}, //14620 #CJK UNIFIED IDEOGRAPH + {0xD583, 0x8AC6}, //14621 #CJK UNIFIED IDEOGRAPH + {0xD584, 0x8AC7}, //14622 #CJK UNIFIED IDEOGRAPH + {0xD585, 0x8AC8}, //14623 #CJK UNIFIED IDEOGRAPH + {0xD586, 0x8AC9}, //14624 #CJK UNIFIED IDEOGRAPH + {0xD587, 0x8ACA}, //14625 #CJK UNIFIED IDEOGRAPH + {0xD588, 0x8ACB}, //14626 #CJK UNIFIED IDEOGRAPH + {0xD589, 0x8ACC}, //14627 #CJK UNIFIED IDEOGRAPH + {0xD58A, 0x8ACD}, //14628 #CJK UNIFIED IDEOGRAPH + {0xD58B, 0x8ACE}, //14629 #CJK UNIFIED IDEOGRAPH + {0xD58C, 0x8ACF}, //14630 #CJK UNIFIED IDEOGRAPH + {0xD58D, 0x8AD0}, //14631 #CJK UNIFIED IDEOGRAPH + {0xD58E, 0x8AD1}, //14632 #CJK UNIFIED IDEOGRAPH + {0xD58F, 0x8AD2}, //14633 #CJK UNIFIED IDEOGRAPH + {0xD590, 0x8AD3}, //14634 #CJK UNIFIED IDEOGRAPH + {0xD591, 0x8AD4}, //14635 #CJK UNIFIED IDEOGRAPH + {0xD592, 0x8AD5}, //14636 #CJK UNIFIED IDEOGRAPH + {0xD593, 0x8AD6}, //14637 #CJK UNIFIED IDEOGRAPH + {0xD594, 0x8AD7}, //14638 #CJK UNIFIED IDEOGRAPH + {0xD595, 0x8AD8}, //14639 #CJK UNIFIED IDEOGRAPH + {0xD596, 0x8AD9}, //14640 #CJK UNIFIED IDEOGRAPH + {0xD597, 0x8ADA}, //14641 #CJK UNIFIED IDEOGRAPH + {0xD598, 0x8ADB}, //14642 #CJK UNIFIED IDEOGRAPH + {0xD599, 0x8ADC}, //14643 #CJK UNIFIED IDEOGRAPH + {0xD59A, 0x8ADD}, //14644 #CJK UNIFIED IDEOGRAPH + {0xD59B, 0x8ADE}, //14645 #CJK UNIFIED IDEOGRAPH + {0xD59C, 0x8ADF}, //14646 #CJK UNIFIED IDEOGRAPH + {0xD59D, 0x8AE0}, //14647 #CJK UNIFIED IDEOGRAPH + {0xD59E, 0x8AE1}, //14648 #CJK UNIFIED IDEOGRAPH + {0xD59F, 0x8AE2}, //14649 #CJK UNIFIED IDEOGRAPH + {0xD5A0, 0x8AE3}, //14650 #CJK UNIFIED IDEOGRAPH + {0xD5A1, 0x94E1}, //14651 #CJK UNIFIED IDEOGRAPH + {0xD5A2, 0x95F8}, //14652 #CJK UNIFIED IDEOGRAPH + {0xD5A3, 0x7728}, //14653 #CJK UNIFIED IDEOGRAPH + {0xD5A4, 0x6805}, //14654 #CJK UNIFIED IDEOGRAPH + {0xD5A5, 0x69A8}, //14655 #CJK UNIFIED IDEOGRAPH + {0xD5A6, 0x548B}, //14656 #CJK UNIFIED IDEOGRAPH + {0xD5A7, 0x4E4D}, //14657 #CJK UNIFIED IDEOGRAPH + {0xD5A8, 0x70B8}, //14658 #CJK UNIFIED IDEOGRAPH + {0xD5A9, 0x8BC8}, //14659 #CJK UNIFIED IDEOGRAPH + {0xD5AA, 0x6458}, //14660 #CJK UNIFIED IDEOGRAPH + {0xD5AB, 0x658B}, //14661 #CJK UNIFIED IDEOGRAPH + {0xD5AC, 0x5B85}, //14662 #CJK UNIFIED IDEOGRAPH + {0xD5AD, 0x7A84}, //14663 #CJK UNIFIED IDEOGRAPH + {0xD5AE, 0x503A}, //14664 #CJK UNIFIED IDEOGRAPH + {0xD5AF, 0x5BE8}, //14665 #CJK UNIFIED IDEOGRAPH + {0xD5B0, 0x77BB}, //14666 #CJK UNIFIED IDEOGRAPH + {0xD5B1, 0x6BE1}, //14667 #CJK UNIFIED IDEOGRAPH + {0xD5B2, 0x8A79}, //14668 #CJK UNIFIED IDEOGRAPH + {0xD5B3, 0x7C98}, //14669 #CJK UNIFIED IDEOGRAPH + {0xD5B4, 0x6CBE}, //14670 #CJK UNIFIED IDEOGRAPH + {0xD5B5, 0x76CF}, //14671 #CJK UNIFIED IDEOGRAPH + {0xD5B6, 0x65A9}, //14672 #CJK UNIFIED IDEOGRAPH + {0xD5B7, 0x8F97}, //14673 #CJK UNIFIED IDEOGRAPH + {0xD5B8, 0x5D2D}, //14674 #CJK UNIFIED IDEOGRAPH + {0xD5B9, 0x5C55}, //14675 #CJK UNIFIED IDEOGRAPH + {0xD5BA, 0x8638}, //14676 #CJK UNIFIED IDEOGRAPH + {0xD5BB, 0x6808}, //14677 #CJK UNIFIED IDEOGRAPH + {0xD5BC, 0x5360}, //14678 #CJK UNIFIED IDEOGRAPH + {0xD5BD, 0x6218}, //14679 #CJK UNIFIED IDEOGRAPH + {0xD5BE, 0x7AD9}, //14680 #CJK UNIFIED IDEOGRAPH + {0xD5BF, 0x6E5B}, //14681 #CJK UNIFIED IDEOGRAPH + {0xD5C0, 0x7EFD}, //14682 #CJK UNIFIED IDEOGRAPH + {0xD5C1, 0x6A1F}, //14683 #CJK UNIFIED IDEOGRAPH + {0xD5C2, 0x7AE0}, //14684 #CJK UNIFIED IDEOGRAPH + {0xD5C3, 0x5F70}, //14685 #CJK UNIFIED IDEOGRAPH + {0xD5C4, 0x6F33}, //14686 #CJK UNIFIED IDEOGRAPH + {0xD5C5, 0x5F20}, //14687 #CJK UNIFIED IDEOGRAPH + {0xD5C6, 0x638C}, //14688 #CJK UNIFIED IDEOGRAPH + {0xD5C7, 0x6DA8}, //14689 #CJK UNIFIED IDEOGRAPH + {0xD5C8, 0x6756}, //14690 #CJK UNIFIED IDEOGRAPH + {0xD5C9, 0x4E08}, //14691 #CJK UNIFIED IDEOGRAPH + {0xD5CA, 0x5E10}, //14692 #CJK UNIFIED IDEOGRAPH + {0xD5CB, 0x8D26}, //14693 #CJK UNIFIED IDEOGRAPH + {0xD5CC, 0x4ED7}, //14694 #CJK UNIFIED IDEOGRAPH + {0xD5CD, 0x80C0}, //14695 #CJK UNIFIED IDEOGRAPH + {0xD5CE, 0x7634}, //14696 #CJK UNIFIED IDEOGRAPH + {0xD5CF, 0x969C}, //14697 #CJK UNIFIED IDEOGRAPH + {0xD5D0, 0x62DB}, //14698 #CJK UNIFIED IDEOGRAPH + {0xD5D1, 0x662D}, //14699 #CJK UNIFIED IDEOGRAPH + {0xD5D2, 0x627E}, //14700 #CJK UNIFIED IDEOGRAPH + {0xD5D3, 0x6CBC}, //14701 #CJK UNIFIED IDEOGRAPH + {0xD5D4, 0x8D75}, //14702 #CJK UNIFIED IDEOGRAPH + {0xD5D5, 0x7167}, //14703 #CJK UNIFIED IDEOGRAPH + {0xD5D6, 0x7F69}, //14704 #CJK UNIFIED IDEOGRAPH + {0xD5D7, 0x5146}, //14705 #CJK UNIFIED IDEOGRAPH + {0xD5D8, 0x8087}, //14706 #CJK UNIFIED IDEOGRAPH + {0xD5D9, 0x53EC}, //14707 #CJK UNIFIED IDEOGRAPH + {0xD5DA, 0x906E}, //14708 #CJK UNIFIED IDEOGRAPH + {0xD5DB, 0x6298}, //14709 #CJK UNIFIED IDEOGRAPH + {0xD5DC, 0x54F2}, //14710 #CJK UNIFIED IDEOGRAPH + {0xD5DD, 0x86F0}, //14711 #CJK UNIFIED IDEOGRAPH + {0xD5DE, 0x8F99}, //14712 #CJK UNIFIED IDEOGRAPH + {0xD5DF, 0x8005}, //14713 #CJK UNIFIED IDEOGRAPH + {0xD5E0, 0x9517}, //14714 #CJK UNIFIED IDEOGRAPH + {0xD5E1, 0x8517}, //14715 #CJK UNIFIED IDEOGRAPH + {0xD5E2, 0x8FD9}, //14716 #CJK UNIFIED IDEOGRAPH + {0xD5E3, 0x6D59}, //14717 #CJK UNIFIED IDEOGRAPH + {0xD5E4, 0x73CD}, //14718 #CJK UNIFIED IDEOGRAPH + {0xD5E5, 0x659F}, //14719 #CJK UNIFIED IDEOGRAPH + {0xD5E6, 0x771F}, //14720 #CJK UNIFIED IDEOGRAPH + {0xD5E7, 0x7504}, //14721 #CJK UNIFIED IDEOGRAPH + {0xD5E8, 0x7827}, //14722 #CJK UNIFIED IDEOGRAPH + {0xD5E9, 0x81FB}, //14723 #CJK UNIFIED IDEOGRAPH + {0xD5EA, 0x8D1E}, //14724 #CJK UNIFIED IDEOGRAPH + {0xD5EB, 0x9488}, //14725 #CJK UNIFIED IDEOGRAPH + {0xD5EC, 0x4FA6}, //14726 #CJK UNIFIED IDEOGRAPH + {0xD5ED, 0x6795}, //14727 #CJK UNIFIED IDEOGRAPH + {0xD5EE, 0x75B9}, //14728 #CJK UNIFIED IDEOGRAPH + {0xD5EF, 0x8BCA}, //14729 #CJK UNIFIED IDEOGRAPH + {0xD5F0, 0x9707}, //14730 #CJK UNIFIED IDEOGRAPH + {0xD5F1, 0x632F}, //14731 #CJK UNIFIED IDEOGRAPH + {0xD5F2, 0x9547}, //14732 #CJK UNIFIED IDEOGRAPH + {0xD5F3, 0x9635}, //14733 #CJK UNIFIED IDEOGRAPH + {0xD5F4, 0x84B8}, //14734 #CJK UNIFIED IDEOGRAPH + {0xD5F5, 0x6323}, //14735 #CJK UNIFIED IDEOGRAPH + {0xD5F6, 0x7741}, //14736 #CJK UNIFIED IDEOGRAPH + {0xD5F7, 0x5F81}, //14737 #CJK UNIFIED IDEOGRAPH + {0xD5F8, 0x72F0}, //14738 #CJK UNIFIED IDEOGRAPH + {0xD5F9, 0x4E89}, //14739 #CJK UNIFIED IDEOGRAPH + {0xD5FA, 0x6014}, //14740 #CJK UNIFIED IDEOGRAPH + {0xD5FB, 0x6574}, //14741 #CJK UNIFIED IDEOGRAPH + {0xD5FC, 0x62EF}, //14742 #CJK UNIFIED IDEOGRAPH + {0xD5FD, 0x6B63}, //14743 #CJK UNIFIED IDEOGRAPH + {0xD5FE, 0x653F}, //14744 #CJK UNIFIED IDEOGRAPH + {0xD640, 0x8AE4}, //14745 #CJK UNIFIED IDEOGRAPH + {0xD641, 0x8AE5}, //14746 #CJK UNIFIED IDEOGRAPH + {0xD642, 0x8AE6}, //14747 #CJK UNIFIED IDEOGRAPH + {0xD643, 0x8AE7}, //14748 #CJK UNIFIED IDEOGRAPH + {0xD644, 0x8AE8}, //14749 #CJK UNIFIED IDEOGRAPH + {0xD645, 0x8AE9}, //14750 #CJK UNIFIED IDEOGRAPH + {0xD646, 0x8AEA}, //14751 #CJK UNIFIED IDEOGRAPH + {0xD647, 0x8AEB}, //14752 #CJK UNIFIED IDEOGRAPH + {0xD648, 0x8AEC}, //14753 #CJK UNIFIED IDEOGRAPH + {0xD649, 0x8AED}, //14754 #CJK UNIFIED IDEOGRAPH + {0xD64A, 0x8AEE}, //14755 #CJK UNIFIED IDEOGRAPH + {0xD64B, 0x8AEF}, //14756 #CJK UNIFIED IDEOGRAPH + {0xD64C, 0x8AF0}, //14757 #CJK UNIFIED IDEOGRAPH + {0xD64D, 0x8AF1}, //14758 #CJK UNIFIED IDEOGRAPH + {0xD64E, 0x8AF2}, //14759 #CJK UNIFIED IDEOGRAPH + {0xD64F, 0x8AF3}, //14760 #CJK UNIFIED IDEOGRAPH + {0xD650, 0x8AF4}, //14761 #CJK UNIFIED IDEOGRAPH + {0xD651, 0x8AF5}, //14762 #CJK UNIFIED IDEOGRAPH + {0xD652, 0x8AF6}, //14763 #CJK UNIFIED IDEOGRAPH + {0xD653, 0x8AF7}, //14764 #CJK UNIFIED IDEOGRAPH + {0xD654, 0x8AF8}, //14765 #CJK UNIFIED IDEOGRAPH + {0xD655, 0x8AF9}, //14766 #CJK UNIFIED IDEOGRAPH + {0xD656, 0x8AFA}, //14767 #CJK UNIFIED IDEOGRAPH + {0xD657, 0x8AFB}, //14768 #CJK UNIFIED IDEOGRAPH + {0xD658, 0x8AFC}, //14769 #CJK UNIFIED IDEOGRAPH + {0xD659, 0x8AFD}, //14770 #CJK UNIFIED IDEOGRAPH + {0xD65A, 0x8AFE}, //14771 #CJK UNIFIED IDEOGRAPH + {0xD65B, 0x8AFF}, //14772 #CJK UNIFIED IDEOGRAPH + {0xD65C, 0x8B00}, //14773 #CJK UNIFIED IDEOGRAPH + {0xD65D, 0x8B01}, //14774 #CJK UNIFIED IDEOGRAPH + {0xD65E, 0x8B02}, //14775 #CJK UNIFIED IDEOGRAPH + {0xD65F, 0x8B03}, //14776 #CJK UNIFIED IDEOGRAPH + {0xD660, 0x8B04}, //14777 #CJK UNIFIED IDEOGRAPH + {0xD661, 0x8B05}, //14778 #CJK UNIFIED IDEOGRAPH + {0xD662, 0x8B06}, //14779 #CJK UNIFIED IDEOGRAPH + {0xD663, 0x8B08}, //14780 #CJK UNIFIED IDEOGRAPH + {0xD664, 0x8B09}, //14781 #CJK UNIFIED IDEOGRAPH + {0xD665, 0x8B0A}, //14782 #CJK UNIFIED IDEOGRAPH + {0xD666, 0x8B0B}, //14783 #CJK UNIFIED IDEOGRAPH + {0xD667, 0x8B0C}, //14784 #CJK UNIFIED IDEOGRAPH + {0xD668, 0x8B0D}, //14785 #CJK UNIFIED IDEOGRAPH + {0xD669, 0x8B0E}, //14786 #CJK UNIFIED IDEOGRAPH + {0xD66A, 0x8B0F}, //14787 #CJK UNIFIED IDEOGRAPH + {0xD66B, 0x8B10}, //14788 #CJK UNIFIED IDEOGRAPH + {0xD66C, 0x8B11}, //14789 #CJK UNIFIED IDEOGRAPH + {0xD66D, 0x8B12}, //14790 #CJK UNIFIED IDEOGRAPH + {0xD66E, 0x8B13}, //14791 #CJK UNIFIED IDEOGRAPH + {0xD66F, 0x8B14}, //14792 #CJK UNIFIED IDEOGRAPH + {0xD670, 0x8B15}, //14793 #CJK UNIFIED IDEOGRAPH + {0xD671, 0x8B16}, //14794 #CJK UNIFIED IDEOGRAPH + {0xD672, 0x8B17}, //14795 #CJK UNIFIED IDEOGRAPH + {0xD673, 0x8B18}, //14796 #CJK UNIFIED IDEOGRAPH + {0xD674, 0x8B19}, //14797 #CJK UNIFIED IDEOGRAPH + {0xD675, 0x8B1A}, //14798 #CJK UNIFIED IDEOGRAPH + {0xD676, 0x8B1B}, //14799 #CJK UNIFIED IDEOGRAPH + {0xD677, 0x8B1C}, //14800 #CJK UNIFIED IDEOGRAPH + {0xD678, 0x8B1D}, //14801 #CJK UNIFIED IDEOGRAPH + {0xD679, 0x8B1E}, //14802 #CJK UNIFIED IDEOGRAPH + {0xD67A, 0x8B1F}, //14803 #CJK UNIFIED IDEOGRAPH + {0xD67B, 0x8B20}, //14804 #CJK UNIFIED IDEOGRAPH + {0xD67C, 0x8B21}, //14805 #CJK UNIFIED IDEOGRAPH + {0xD67D, 0x8B22}, //14806 #CJK UNIFIED IDEOGRAPH + {0xD67E, 0x8B23}, //14807 #CJK UNIFIED IDEOGRAPH + {0xD680, 0x8B24}, //14808 #CJK UNIFIED IDEOGRAPH + {0xD681, 0x8B25}, //14809 #CJK UNIFIED IDEOGRAPH + {0xD682, 0x8B27}, //14810 #CJK UNIFIED IDEOGRAPH + {0xD683, 0x8B28}, //14811 #CJK UNIFIED IDEOGRAPH + {0xD684, 0x8B29}, //14812 #CJK UNIFIED IDEOGRAPH + {0xD685, 0x8B2A}, //14813 #CJK UNIFIED IDEOGRAPH + {0xD686, 0x8B2B}, //14814 #CJK UNIFIED IDEOGRAPH + {0xD687, 0x8B2C}, //14815 #CJK UNIFIED IDEOGRAPH + {0xD688, 0x8B2D}, //14816 #CJK UNIFIED IDEOGRAPH + {0xD689, 0x8B2E}, //14817 #CJK UNIFIED IDEOGRAPH + {0xD68A, 0x8B2F}, //14818 #CJK UNIFIED IDEOGRAPH + {0xD68B, 0x8B30}, //14819 #CJK UNIFIED IDEOGRAPH + {0xD68C, 0x8B31}, //14820 #CJK UNIFIED IDEOGRAPH + {0xD68D, 0x8B32}, //14821 #CJK UNIFIED IDEOGRAPH + {0xD68E, 0x8B33}, //14822 #CJK UNIFIED IDEOGRAPH + {0xD68F, 0x8B34}, //14823 #CJK UNIFIED IDEOGRAPH + {0xD690, 0x8B35}, //14824 #CJK UNIFIED IDEOGRAPH + {0xD691, 0x8B36}, //14825 #CJK UNIFIED IDEOGRAPH + {0xD692, 0x8B37}, //14826 #CJK UNIFIED IDEOGRAPH + {0xD693, 0x8B38}, //14827 #CJK UNIFIED IDEOGRAPH + {0xD694, 0x8B39}, //14828 #CJK UNIFIED IDEOGRAPH + {0xD695, 0x8B3A}, //14829 #CJK UNIFIED IDEOGRAPH + {0xD696, 0x8B3B}, //14830 #CJK UNIFIED IDEOGRAPH + {0xD697, 0x8B3C}, //14831 #CJK UNIFIED IDEOGRAPH + {0xD698, 0x8B3D}, //14832 #CJK UNIFIED IDEOGRAPH + {0xD699, 0x8B3E}, //14833 #CJK UNIFIED IDEOGRAPH + {0xD69A, 0x8B3F}, //14834 #CJK UNIFIED IDEOGRAPH + {0xD69B, 0x8B40}, //14835 #CJK UNIFIED IDEOGRAPH + {0xD69C, 0x8B41}, //14836 #CJK UNIFIED IDEOGRAPH + {0xD69D, 0x8B42}, //14837 #CJK UNIFIED IDEOGRAPH + {0xD69E, 0x8B43}, //14838 #CJK UNIFIED IDEOGRAPH + {0xD69F, 0x8B44}, //14839 #CJK UNIFIED IDEOGRAPH + {0xD6A0, 0x8B45}, //14840 #CJK UNIFIED IDEOGRAPH + {0xD6A1, 0x5E27}, //14841 #CJK UNIFIED IDEOGRAPH + {0xD6A2, 0x75C7}, //14842 #CJK UNIFIED IDEOGRAPH + {0xD6A3, 0x90D1}, //14843 #CJK UNIFIED IDEOGRAPH + {0xD6A4, 0x8BC1}, //14844 #CJK UNIFIED IDEOGRAPH + {0xD6A5, 0x829D}, //14845 #CJK UNIFIED IDEOGRAPH + {0xD6A6, 0x679D}, //14846 #CJK UNIFIED IDEOGRAPH + {0xD6A7, 0x652F}, //14847 #CJK UNIFIED IDEOGRAPH + {0xD6A8, 0x5431}, //14848 #CJK UNIFIED IDEOGRAPH + {0xD6A9, 0x8718}, //14849 #CJK UNIFIED IDEOGRAPH + {0xD6AA, 0x77E5}, //14850 #CJK UNIFIED IDEOGRAPH + {0xD6AB, 0x80A2}, //14851 #CJK UNIFIED IDEOGRAPH + {0xD6AC, 0x8102}, //14852 #CJK UNIFIED IDEOGRAPH + {0xD6AD, 0x6C41}, //14853 #CJK UNIFIED IDEOGRAPH + {0xD6AE, 0x4E4B}, //14854 #CJK UNIFIED IDEOGRAPH + {0xD6AF, 0x7EC7}, //14855 #CJK UNIFIED IDEOGRAPH + {0xD6B0, 0x804C}, //14856 #CJK UNIFIED IDEOGRAPH + {0xD6B1, 0x76F4}, //14857 #CJK UNIFIED IDEOGRAPH + {0xD6B2, 0x690D}, //14858 #CJK UNIFIED IDEOGRAPH + {0xD6B3, 0x6B96}, //14859 #CJK UNIFIED IDEOGRAPH + {0xD6B4, 0x6267}, //14860 #CJK UNIFIED IDEOGRAPH + {0xD6B5, 0x503C}, //14861 #CJK UNIFIED IDEOGRAPH + {0xD6B6, 0x4F84}, //14862 #CJK UNIFIED IDEOGRAPH + {0xD6B7, 0x5740}, //14863 #CJK UNIFIED IDEOGRAPH + {0xD6B8, 0x6307}, //14864 #CJK UNIFIED IDEOGRAPH + {0xD6B9, 0x6B62}, //14865 #CJK UNIFIED IDEOGRAPH + {0xD6BA, 0x8DBE}, //14866 #CJK UNIFIED IDEOGRAPH + {0xD6BB, 0x53EA}, //14867 #CJK UNIFIED IDEOGRAPH + {0xD6BC, 0x65E8}, //14868 #CJK UNIFIED IDEOGRAPH + {0xD6BD, 0x7EB8}, //14869 #CJK UNIFIED IDEOGRAPH + {0xD6BE, 0x5FD7}, //14870 #CJK UNIFIED IDEOGRAPH + {0xD6BF, 0x631A}, //14871 #CJK UNIFIED IDEOGRAPH + {0xD6C0, 0x63B7}, //14872 #CJK UNIFIED IDEOGRAPH + {0xD6C1, 0x81F3}, //14873 #CJK UNIFIED IDEOGRAPH + {0xD6C2, 0x81F4}, //14874 #CJK UNIFIED IDEOGRAPH + {0xD6C3, 0x7F6E}, //14875 #CJK UNIFIED IDEOGRAPH + {0xD6C4, 0x5E1C}, //14876 #CJK UNIFIED IDEOGRAPH + {0xD6C5, 0x5CD9}, //14877 #CJK UNIFIED IDEOGRAPH + {0xD6C6, 0x5236}, //14878 #CJK UNIFIED IDEOGRAPH + {0xD6C7, 0x667A}, //14879 #CJK UNIFIED IDEOGRAPH + {0xD6C8, 0x79E9}, //14880 #CJK UNIFIED IDEOGRAPH + {0xD6C9, 0x7A1A}, //14881 #CJK UNIFIED IDEOGRAPH + {0xD6CA, 0x8D28}, //14882 #CJK UNIFIED IDEOGRAPH + {0xD6CB, 0x7099}, //14883 #CJK UNIFIED IDEOGRAPH + {0xD6CC, 0x75D4}, //14884 #CJK UNIFIED IDEOGRAPH + {0xD6CD, 0x6EDE}, //14885 #CJK UNIFIED IDEOGRAPH + {0xD6CE, 0x6CBB}, //14886 #CJK UNIFIED IDEOGRAPH + {0xD6CF, 0x7A92}, //14887 #CJK UNIFIED IDEOGRAPH + {0xD6D0, 0x4E2D}, //14888 #CJK UNIFIED IDEOGRAPH + {0xD6D1, 0x76C5}, //14889 #CJK UNIFIED IDEOGRAPH + {0xD6D2, 0x5FE0}, //14890 #CJK UNIFIED IDEOGRAPH + {0xD6D3, 0x949F}, //14891 #CJK UNIFIED IDEOGRAPH + {0xD6D4, 0x8877}, //14892 #CJK UNIFIED IDEOGRAPH + {0xD6D5, 0x7EC8}, //14893 #CJK UNIFIED IDEOGRAPH + {0xD6D6, 0x79CD}, //14894 #CJK UNIFIED IDEOGRAPH + {0xD6D7, 0x80BF}, //14895 #CJK UNIFIED IDEOGRAPH + {0xD6D8, 0x91CD}, //14896 #CJK UNIFIED IDEOGRAPH + {0xD6D9, 0x4EF2}, //14897 #CJK UNIFIED IDEOGRAPH + {0xD6DA, 0x4F17}, //14898 #CJK UNIFIED IDEOGRAPH + {0xD6DB, 0x821F}, //14899 #CJK UNIFIED IDEOGRAPH + {0xD6DC, 0x5468}, //14900 #CJK UNIFIED IDEOGRAPH + {0xD6DD, 0x5DDE}, //14901 #CJK UNIFIED IDEOGRAPH + {0xD6DE, 0x6D32}, //14902 #CJK UNIFIED IDEOGRAPH + {0xD6DF, 0x8BCC}, //14903 #CJK UNIFIED IDEOGRAPH + {0xD6E0, 0x7CA5}, //14904 #CJK UNIFIED IDEOGRAPH + {0xD6E1, 0x8F74}, //14905 #CJK UNIFIED IDEOGRAPH + {0xD6E2, 0x8098}, //14906 #CJK UNIFIED IDEOGRAPH + {0xD6E3, 0x5E1A}, //14907 #CJK UNIFIED IDEOGRAPH + {0xD6E4, 0x5492}, //14908 #CJK UNIFIED IDEOGRAPH + {0xD6E5, 0x76B1}, //14909 #CJK UNIFIED IDEOGRAPH + {0xD6E6, 0x5B99}, //14910 #CJK UNIFIED IDEOGRAPH + {0xD6E7, 0x663C}, //14911 #CJK UNIFIED IDEOGRAPH + {0xD6E8, 0x9AA4}, //14912 #CJK UNIFIED IDEOGRAPH + {0xD6E9, 0x73E0}, //14913 #CJK UNIFIED IDEOGRAPH + {0xD6EA, 0x682A}, //14914 #CJK UNIFIED IDEOGRAPH + {0xD6EB, 0x86DB}, //14915 #CJK UNIFIED IDEOGRAPH + {0xD6EC, 0x6731}, //14916 #CJK UNIFIED IDEOGRAPH + {0xD6ED, 0x732A}, //14917 #CJK UNIFIED IDEOGRAPH + {0xD6EE, 0x8BF8}, //14918 #CJK UNIFIED IDEOGRAPH + {0xD6EF, 0x8BDB}, //14919 #CJK UNIFIED IDEOGRAPH + {0xD6F0, 0x9010}, //14920 #CJK UNIFIED IDEOGRAPH + {0xD6F1, 0x7AF9}, //14921 #CJK UNIFIED IDEOGRAPH + {0xD6F2, 0x70DB}, //14922 #CJK UNIFIED IDEOGRAPH + {0xD6F3, 0x716E}, //14923 #CJK UNIFIED IDEOGRAPH + {0xD6F4, 0x62C4}, //14924 #CJK UNIFIED IDEOGRAPH + {0xD6F5, 0x77A9}, //14925 #CJK UNIFIED IDEOGRAPH + {0xD6F6, 0x5631}, //14926 #CJK UNIFIED IDEOGRAPH + {0xD6F7, 0x4E3B}, //14927 #CJK UNIFIED IDEOGRAPH + {0xD6F8, 0x8457}, //14928 #CJK UNIFIED IDEOGRAPH + {0xD6F9, 0x67F1}, //14929 #CJK UNIFIED IDEOGRAPH + {0xD6FA, 0x52A9}, //14930 #CJK UNIFIED IDEOGRAPH + {0xD6FB, 0x86C0}, //14931 #CJK UNIFIED IDEOGRAPH + {0xD6FC, 0x8D2E}, //14932 #CJK UNIFIED IDEOGRAPH + {0xD6FD, 0x94F8}, //14933 #CJK UNIFIED IDEOGRAPH + {0xD6FE, 0x7B51}, //14934 #CJK UNIFIED IDEOGRAPH + {0xD740, 0x8B46}, //14935 #CJK UNIFIED IDEOGRAPH + {0xD741, 0x8B47}, //14936 #CJK UNIFIED IDEOGRAPH + {0xD742, 0x8B48}, //14937 #CJK UNIFIED IDEOGRAPH + {0xD743, 0x8B49}, //14938 #CJK UNIFIED IDEOGRAPH + {0xD744, 0x8B4A}, //14939 #CJK UNIFIED IDEOGRAPH + {0xD745, 0x8B4B}, //14940 #CJK UNIFIED IDEOGRAPH + {0xD746, 0x8B4C}, //14941 #CJK UNIFIED IDEOGRAPH + {0xD747, 0x8B4D}, //14942 #CJK UNIFIED IDEOGRAPH + {0xD748, 0x8B4E}, //14943 #CJK UNIFIED IDEOGRAPH + {0xD749, 0x8B4F}, //14944 #CJK UNIFIED IDEOGRAPH + {0xD74A, 0x8B50}, //14945 #CJK UNIFIED IDEOGRAPH + {0xD74B, 0x8B51}, //14946 #CJK UNIFIED IDEOGRAPH + {0xD74C, 0x8B52}, //14947 #CJK UNIFIED IDEOGRAPH + {0xD74D, 0x8B53}, //14948 #CJK UNIFIED IDEOGRAPH + {0xD74E, 0x8B54}, //14949 #CJK UNIFIED IDEOGRAPH + {0xD74F, 0x8B55}, //14950 #CJK UNIFIED IDEOGRAPH + {0xD750, 0x8B56}, //14951 #CJK UNIFIED IDEOGRAPH + {0xD751, 0x8B57}, //14952 #CJK UNIFIED IDEOGRAPH + {0xD752, 0x8B58}, //14953 #CJK UNIFIED IDEOGRAPH + {0xD753, 0x8B59}, //14954 #CJK UNIFIED IDEOGRAPH + {0xD754, 0x8B5A}, //14955 #CJK UNIFIED IDEOGRAPH + {0xD755, 0x8B5B}, //14956 #CJK UNIFIED IDEOGRAPH + {0xD756, 0x8B5C}, //14957 #CJK UNIFIED IDEOGRAPH + {0xD757, 0x8B5D}, //14958 #CJK UNIFIED IDEOGRAPH + {0xD758, 0x8B5E}, //14959 #CJK UNIFIED IDEOGRAPH + {0xD759, 0x8B5F}, //14960 #CJK UNIFIED IDEOGRAPH + {0xD75A, 0x8B60}, //14961 #CJK UNIFIED IDEOGRAPH + {0xD75B, 0x8B61}, //14962 #CJK UNIFIED IDEOGRAPH + {0xD75C, 0x8B62}, //14963 #CJK UNIFIED IDEOGRAPH + {0xD75D, 0x8B63}, //14964 #CJK UNIFIED IDEOGRAPH + {0xD75E, 0x8B64}, //14965 #CJK UNIFIED IDEOGRAPH + {0xD75F, 0x8B65}, //14966 #CJK UNIFIED IDEOGRAPH + {0xD760, 0x8B67}, //14967 #CJK UNIFIED IDEOGRAPH + {0xD761, 0x8B68}, //14968 #CJK UNIFIED IDEOGRAPH + {0xD762, 0x8B69}, //14969 #CJK UNIFIED IDEOGRAPH + {0xD763, 0x8B6A}, //14970 #CJK UNIFIED IDEOGRAPH + {0xD764, 0x8B6B}, //14971 #CJK UNIFIED IDEOGRAPH + {0xD765, 0x8B6D}, //14972 #CJK UNIFIED IDEOGRAPH + {0xD766, 0x8B6E}, //14973 #CJK UNIFIED IDEOGRAPH + {0xD767, 0x8B6F}, //14974 #CJK UNIFIED IDEOGRAPH + {0xD768, 0x8B70}, //14975 #CJK UNIFIED IDEOGRAPH + {0xD769, 0x8B71}, //14976 #CJK UNIFIED IDEOGRAPH + {0xD76A, 0x8B72}, //14977 #CJK UNIFIED IDEOGRAPH + {0xD76B, 0x8B73}, //14978 #CJK UNIFIED IDEOGRAPH + {0xD76C, 0x8B74}, //14979 #CJK UNIFIED IDEOGRAPH + {0xD76D, 0x8B75}, //14980 #CJK UNIFIED IDEOGRAPH + {0xD76E, 0x8B76}, //14981 #CJK UNIFIED IDEOGRAPH + {0xD76F, 0x8B77}, //14982 #CJK UNIFIED IDEOGRAPH + {0xD770, 0x8B78}, //14983 #CJK UNIFIED IDEOGRAPH + {0xD771, 0x8B79}, //14984 #CJK UNIFIED IDEOGRAPH + {0xD772, 0x8B7A}, //14985 #CJK UNIFIED IDEOGRAPH + {0xD773, 0x8B7B}, //14986 #CJK UNIFIED IDEOGRAPH + {0xD774, 0x8B7C}, //14987 #CJK UNIFIED IDEOGRAPH + {0xD775, 0x8B7D}, //14988 #CJK UNIFIED IDEOGRAPH + {0xD776, 0x8B7E}, //14989 #CJK UNIFIED IDEOGRAPH + {0xD777, 0x8B7F}, //14990 #CJK UNIFIED IDEOGRAPH + {0xD778, 0x8B80}, //14991 #CJK UNIFIED IDEOGRAPH + {0xD779, 0x8B81}, //14992 #CJK UNIFIED IDEOGRAPH + {0xD77A, 0x8B82}, //14993 #CJK UNIFIED IDEOGRAPH + {0xD77B, 0x8B83}, //14994 #CJK UNIFIED IDEOGRAPH + {0xD77C, 0x8B84}, //14995 #CJK UNIFIED IDEOGRAPH + {0xD77D, 0x8B85}, //14996 #CJK UNIFIED IDEOGRAPH + {0xD77E, 0x8B86}, //14997 #CJK UNIFIED IDEOGRAPH + {0xD780, 0x8B87}, //14998 #CJK UNIFIED IDEOGRAPH + {0xD781, 0x8B88}, //14999 #CJK UNIFIED IDEOGRAPH + {0xD782, 0x8B89}, //15000 #CJK UNIFIED IDEOGRAPH + {0xD783, 0x8B8A}, //15001 #CJK UNIFIED IDEOGRAPH + {0xD784, 0x8B8B}, //15002 #CJK UNIFIED IDEOGRAPH + {0xD785, 0x8B8C}, //15003 #CJK UNIFIED IDEOGRAPH + {0xD786, 0x8B8D}, //15004 #CJK UNIFIED IDEOGRAPH + {0xD787, 0x8B8E}, //15005 #CJK UNIFIED IDEOGRAPH + {0xD788, 0x8B8F}, //15006 #CJK UNIFIED IDEOGRAPH + {0xD789, 0x8B90}, //15007 #CJK UNIFIED IDEOGRAPH + {0xD78A, 0x8B91}, //15008 #CJK UNIFIED IDEOGRAPH + {0xD78B, 0x8B92}, //15009 #CJK UNIFIED IDEOGRAPH + {0xD78C, 0x8B93}, //15010 #CJK UNIFIED IDEOGRAPH + {0xD78D, 0x8B94}, //15011 #CJK UNIFIED IDEOGRAPH + {0xD78E, 0x8B95}, //15012 #CJK UNIFIED IDEOGRAPH + {0xD78F, 0x8B96}, //15013 #CJK UNIFIED IDEOGRAPH + {0xD790, 0x8B97}, //15014 #CJK UNIFIED IDEOGRAPH + {0xD791, 0x8B98}, //15015 #CJK UNIFIED IDEOGRAPH + {0xD792, 0x8B99}, //15016 #CJK UNIFIED IDEOGRAPH + {0xD793, 0x8B9A}, //15017 #CJK UNIFIED IDEOGRAPH + {0xD794, 0x8B9B}, //15018 #CJK UNIFIED IDEOGRAPH + {0xD795, 0x8B9C}, //15019 #CJK UNIFIED IDEOGRAPH + {0xD796, 0x8B9D}, //15020 #CJK UNIFIED IDEOGRAPH + {0xD797, 0x8B9E}, //15021 #CJK UNIFIED IDEOGRAPH + {0xD798, 0x8B9F}, //15022 #CJK UNIFIED IDEOGRAPH + {0xD799, 0x8BAC}, //15023 #CJK UNIFIED IDEOGRAPH + {0xD79A, 0x8BB1}, //15024 #CJK UNIFIED IDEOGRAPH + {0xD79B, 0x8BBB}, //15025 #CJK UNIFIED IDEOGRAPH + {0xD79C, 0x8BC7}, //15026 #CJK UNIFIED IDEOGRAPH + {0xD79D, 0x8BD0}, //15027 #CJK UNIFIED IDEOGRAPH + {0xD79E, 0x8BEA}, //15028 #CJK UNIFIED IDEOGRAPH + {0xD79F, 0x8C09}, //15029 #CJK UNIFIED IDEOGRAPH + {0xD7A0, 0x8C1E}, //15030 #CJK UNIFIED IDEOGRAPH + {0xD7A1, 0x4F4F}, //15031 #CJK UNIFIED IDEOGRAPH + {0xD7A2, 0x6CE8}, //15032 #CJK UNIFIED IDEOGRAPH + {0xD7A3, 0x795D}, //15033 #CJK UNIFIED IDEOGRAPH + {0xD7A4, 0x9A7B}, //15034 #CJK UNIFIED IDEOGRAPH + {0xD7A5, 0x6293}, //15035 #CJK UNIFIED IDEOGRAPH + {0xD7A6, 0x722A}, //15036 #CJK UNIFIED IDEOGRAPH + {0xD7A7, 0x62FD}, //15037 #CJK UNIFIED IDEOGRAPH + {0xD7A8, 0x4E13}, //15038 #CJK UNIFIED IDEOGRAPH + {0xD7A9, 0x7816}, //15039 #CJK UNIFIED IDEOGRAPH + {0xD7AA, 0x8F6C}, //15040 #CJK UNIFIED IDEOGRAPH + {0xD7AB, 0x64B0}, //15041 #CJK UNIFIED IDEOGRAPH + {0xD7AC, 0x8D5A}, //15042 #CJK UNIFIED IDEOGRAPH + {0xD7AD, 0x7BC6}, //15043 #CJK UNIFIED IDEOGRAPH + {0xD7AE, 0x6869}, //15044 #CJK UNIFIED IDEOGRAPH + {0xD7AF, 0x5E84}, //15045 #CJK UNIFIED IDEOGRAPH + {0xD7B0, 0x88C5}, //15046 #CJK UNIFIED IDEOGRAPH + {0xD7B1, 0x5986}, //15047 #CJK UNIFIED IDEOGRAPH + {0xD7B2, 0x649E}, //15048 #CJK UNIFIED IDEOGRAPH + {0xD7B3, 0x58EE}, //15049 #CJK UNIFIED IDEOGRAPH + {0xD7B4, 0x72B6}, //15050 #CJK UNIFIED IDEOGRAPH + {0xD7B5, 0x690E}, //15051 #CJK UNIFIED IDEOGRAPH + {0xD7B6, 0x9525}, //15052 #CJK UNIFIED IDEOGRAPH + {0xD7B7, 0x8FFD}, //15053 #CJK UNIFIED IDEOGRAPH + {0xD7B8, 0x8D58}, //15054 #CJK UNIFIED IDEOGRAPH + {0xD7B9, 0x5760}, //15055 #CJK UNIFIED IDEOGRAPH + {0xD7BA, 0x7F00}, //15056 #CJK UNIFIED IDEOGRAPH + {0xD7BB, 0x8C06}, //15057 #CJK UNIFIED IDEOGRAPH + {0xD7BC, 0x51C6}, //15058 #CJK UNIFIED IDEOGRAPH + {0xD7BD, 0x6349}, //15059 #CJK UNIFIED IDEOGRAPH + {0xD7BE, 0x62D9}, //15060 #CJK UNIFIED IDEOGRAPH + {0xD7BF, 0x5353}, //15061 #CJK UNIFIED IDEOGRAPH + {0xD7C0, 0x684C}, //15062 #CJK UNIFIED IDEOGRAPH + {0xD7C1, 0x7422}, //15063 #CJK UNIFIED IDEOGRAPH + {0xD7C2, 0x8301}, //15064 #CJK UNIFIED IDEOGRAPH + {0xD7C3, 0x914C}, //15065 #CJK UNIFIED IDEOGRAPH + {0xD7C4, 0x5544}, //15066 #CJK UNIFIED IDEOGRAPH + {0xD7C5, 0x7740}, //15067 #CJK UNIFIED IDEOGRAPH + {0xD7C6, 0x707C}, //15068 #CJK UNIFIED IDEOGRAPH + {0xD7C7, 0x6D4A}, //15069 #CJK UNIFIED IDEOGRAPH + {0xD7C8, 0x5179}, //15070 #CJK UNIFIED IDEOGRAPH + {0xD7C9, 0x54A8}, //15071 #CJK UNIFIED IDEOGRAPH + {0xD7CA, 0x8D44}, //15072 #CJK UNIFIED IDEOGRAPH + {0xD7CB, 0x59FF}, //15073 #CJK UNIFIED IDEOGRAPH + {0xD7CC, 0x6ECB}, //15074 #CJK UNIFIED IDEOGRAPH + {0xD7CD, 0x6DC4}, //15075 #CJK UNIFIED IDEOGRAPH + {0xD7CE, 0x5B5C}, //15076 #CJK UNIFIED IDEOGRAPH + {0xD7CF, 0x7D2B}, //15077 #CJK UNIFIED IDEOGRAPH + {0xD7D0, 0x4ED4}, //15078 #CJK UNIFIED IDEOGRAPH + {0xD7D1, 0x7C7D}, //15079 #CJK UNIFIED IDEOGRAPH + {0xD7D2, 0x6ED3}, //15080 #CJK UNIFIED IDEOGRAPH + {0xD7D3, 0x5B50}, //15081 #CJK UNIFIED IDEOGRAPH + {0xD7D4, 0x81EA}, //15082 #CJK UNIFIED IDEOGRAPH + {0xD7D5, 0x6E0D}, //15083 #CJK UNIFIED IDEOGRAPH + {0xD7D6, 0x5B57}, //15084 #CJK UNIFIED IDEOGRAPH + {0xD7D7, 0x9B03}, //15085 #CJK UNIFIED IDEOGRAPH + {0xD7D8, 0x68D5}, //15086 #CJK UNIFIED IDEOGRAPH + {0xD7D9, 0x8E2A}, //15087 #CJK UNIFIED IDEOGRAPH + {0xD7DA, 0x5B97}, //15088 #CJK UNIFIED IDEOGRAPH + {0xD7DB, 0x7EFC}, //15089 #CJK UNIFIED IDEOGRAPH + {0xD7DC, 0x603B}, //15090 #CJK UNIFIED IDEOGRAPH + {0xD7DD, 0x7EB5}, //15091 #CJK UNIFIED IDEOGRAPH + {0xD7DE, 0x90B9}, //15092 #CJK UNIFIED IDEOGRAPH + {0xD7DF, 0x8D70}, //15093 #CJK UNIFIED IDEOGRAPH + {0xD7E0, 0x594F}, //15094 #CJK UNIFIED IDEOGRAPH + {0xD7E1, 0x63CD}, //15095 #CJK UNIFIED IDEOGRAPH + {0xD7E2, 0x79DF}, //15096 #CJK UNIFIED IDEOGRAPH + {0xD7E3, 0x8DB3}, //15097 #CJK UNIFIED IDEOGRAPH + {0xD7E4, 0x5352}, //15098 #CJK UNIFIED IDEOGRAPH + {0xD7E5, 0x65CF}, //15099 #CJK UNIFIED IDEOGRAPH + {0xD7E6, 0x7956}, //15100 #CJK UNIFIED IDEOGRAPH + {0xD7E7, 0x8BC5}, //15101 #CJK UNIFIED IDEOGRAPH + {0xD7E8, 0x963B}, //15102 #CJK UNIFIED IDEOGRAPH + {0xD7E9, 0x7EC4}, //15103 #CJK UNIFIED IDEOGRAPH + {0xD7EA, 0x94BB}, //15104 #CJK UNIFIED IDEOGRAPH + {0xD7EB, 0x7E82}, //15105 #CJK UNIFIED IDEOGRAPH + {0xD7EC, 0x5634}, //15106 #CJK UNIFIED IDEOGRAPH + {0xD7ED, 0x9189}, //15107 #CJK UNIFIED IDEOGRAPH + {0xD7EE, 0x6700}, //15108 #CJK UNIFIED IDEOGRAPH + {0xD7EF, 0x7F6A}, //15109 #CJK UNIFIED IDEOGRAPH + {0xD7F0, 0x5C0A}, //15110 #CJK UNIFIED IDEOGRAPH + {0xD7F1, 0x9075}, //15111 #CJK UNIFIED IDEOGRAPH + {0xD7F2, 0x6628}, //15112 #CJK UNIFIED IDEOGRAPH + {0xD7F3, 0x5DE6}, //15113 #CJK UNIFIED IDEOGRAPH + {0xD7F4, 0x4F50}, //15114 #CJK UNIFIED IDEOGRAPH + {0xD7F5, 0x67DE}, //15115 #CJK UNIFIED IDEOGRAPH + {0xD7F6, 0x505A}, //15116 #CJK UNIFIED IDEOGRAPH + {0xD7F7, 0x4F5C}, //15117 #CJK UNIFIED IDEOGRAPH + {0xD7F8, 0x5750}, //15118 #CJK UNIFIED IDEOGRAPH + {0xD7F9, 0x5EA7}, //15119 #CJK UNIFIED IDEOGRAPH + {0xD840, 0x8C38}, //15120 #CJK UNIFIED IDEOGRAPH + {0xD841, 0x8C39}, //15121 #CJK UNIFIED IDEOGRAPH + {0xD842, 0x8C3A}, //15122 #CJK UNIFIED IDEOGRAPH + {0xD843, 0x8C3B}, //15123 #CJK UNIFIED IDEOGRAPH + {0xD844, 0x8C3C}, //15124 #CJK UNIFIED IDEOGRAPH + {0xD845, 0x8C3D}, //15125 #CJK UNIFIED IDEOGRAPH + {0xD846, 0x8C3E}, //15126 #CJK UNIFIED IDEOGRAPH + {0xD847, 0x8C3F}, //15127 #CJK UNIFIED IDEOGRAPH + {0xD848, 0x8C40}, //15128 #CJK UNIFIED IDEOGRAPH + {0xD849, 0x8C42}, //15129 #CJK UNIFIED IDEOGRAPH + {0xD84A, 0x8C43}, //15130 #CJK UNIFIED IDEOGRAPH + {0xD84B, 0x8C44}, //15131 #CJK UNIFIED IDEOGRAPH + {0xD84C, 0x8C45}, //15132 #CJK UNIFIED IDEOGRAPH + {0xD84D, 0x8C48}, //15133 #CJK UNIFIED IDEOGRAPH + {0xD84E, 0x8C4A}, //15134 #CJK UNIFIED IDEOGRAPH + {0xD84F, 0x8C4B}, //15135 #CJK UNIFIED IDEOGRAPH + {0xD850, 0x8C4D}, //15136 #CJK UNIFIED IDEOGRAPH + {0xD851, 0x8C4E}, //15137 #CJK UNIFIED IDEOGRAPH + {0xD852, 0x8C4F}, //15138 #CJK UNIFIED IDEOGRAPH + {0xD853, 0x8C50}, //15139 #CJK UNIFIED IDEOGRAPH + {0xD854, 0x8C51}, //15140 #CJK UNIFIED IDEOGRAPH + {0xD855, 0x8C52}, //15141 #CJK UNIFIED IDEOGRAPH + {0xD856, 0x8C53}, //15142 #CJK UNIFIED IDEOGRAPH + {0xD857, 0x8C54}, //15143 #CJK UNIFIED IDEOGRAPH + {0xD858, 0x8C56}, //15144 #CJK UNIFIED IDEOGRAPH + {0xD859, 0x8C57}, //15145 #CJK UNIFIED IDEOGRAPH + {0xD85A, 0x8C58}, //15146 #CJK UNIFIED IDEOGRAPH + {0xD85B, 0x8C59}, //15147 #CJK UNIFIED IDEOGRAPH + {0xD85C, 0x8C5B}, //15148 #CJK UNIFIED IDEOGRAPH + {0xD85D, 0x8C5C}, //15149 #CJK UNIFIED IDEOGRAPH + {0xD85E, 0x8C5D}, //15150 #CJK UNIFIED IDEOGRAPH + {0xD85F, 0x8C5E}, //15151 #CJK UNIFIED IDEOGRAPH + {0xD860, 0x8C5F}, //15152 #CJK UNIFIED IDEOGRAPH + {0xD861, 0x8C60}, //15153 #CJK UNIFIED IDEOGRAPH + {0xD862, 0x8C63}, //15154 #CJK UNIFIED IDEOGRAPH + {0xD863, 0x8C64}, //15155 #CJK UNIFIED IDEOGRAPH + {0xD864, 0x8C65}, //15156 #CJK UNIFIED IDEOGRAPH + {0xD865, 0x8C66}, //15157 #CJK UNIFIED IDEOGRAPH + {0xD866, 0x8C67}, //15158 #CJK UNIFIED IDEOGRAPH + {0xD867, 0x8C68}, //15159 #CJK UNIFIED IDEOGRAPH + {0xD868, 0x8C69}, //15160 #CJK UNIFIED IDEOGRAPH + {0xD869, 0x8C6C}, //15161 #CJK UNIFIED IDEOGRAPH + {0xD86A, 0x8C6D}, //15162 #CJK UNIFIED IDEOGRAPH + {0xD86B, 0x8C6E}, //15163 #CJK UNIFIED IDEOGRAPH + {0xD86C, 0x8C6F}, //15164 #CJK UNIFIED IDEOGRAPH + {0xD86D, 0x8C70}, //15165 #CJK UNIFIED IDEOGRAPH + {0xD86E, 0x8C71}, //15166 #CJK UNIFIED IDEOGRAPH + {0xD86F, 0x8C72}, //15167 #CJK UNIFIED IDEOGRAPH + {0xD870, 0x8C74}, //15168 #CJK UNIFIED IDEOGRAPH + {0xD871, 0x8C75}, //15169 #CJK UNIFIED IDEOGRAPH + {0xD872, 0x8C76}, //15170 #CJK UNIFIED IDEOGRAPH + {0xD873, 0x8C77}, //15171 #CJK UNIFIED IDEOGRAPH + {0xD874, 0x8C7B}, //15172 #CJK UNIFIED IDEOGRAPH + {0xD875, 0x8C7C}, //15173 #CJK UNIFIED IDEOGRAPH + {0xD876, 0x8C7D}, //15174 #CJK UNIFIED IDEOGRAPH + {0xD877, 0x8C7E}, //15175 #CJK UNIFIED IDEOGRAPH + {0xD878, 0x8C7F}, //15176 #CJK UNIFIED IDEOGRAPH + {0xD879, 0x8C80}, //15177 #CJK UNIFIED IDEOGRAPH + {0xD87A, 0x8C81}, //15178 #CJK UNIFIED IDEOGRAPH + {0xD87B, 0x8C83}, //15179 #CJK UNIFIED IDEOGRAPH + {0xD87C, 0x8C84}, //15180 #CJK UNIFIED IDEOGRAPH + {0xD87D, 0x8C86}, //15181 #CJK UNIFIED IDEOGRAPH + {0xD87E, 0x8C87}, //15182 #CJK UNIFIED IDEOGRAPH + {0xD880, 0x8C88}, //15183 #CJK UNIFIED IDEOGRAPH + {0xD881, 0x8C8B}, //15184 #CJK UNIFIED IDEOGRAPH + {0xD882, 0x8C8D}, //15185 #CJK UNIFIED IDEOGRAPH + {0xD883, 0x8C8E}, //15186 #CJK UNIFIED IDEOGRAPH + {0xD884, 0x8C8F}, //15187 #CJK UNIFIED IDEOGRAPH + {0xD885, 0x8C90}, //15188 #CJK UNIFIED IDEOGRAPH + {0xD886, 0x8C91}, //15189 #CJK UNIFIED IDEOGRAPH + {0xD887, 0x8C92}, //15190 #CJK UNIFIED IDEOGRAPH + {0xD888, 0x8C93}, //15191 #CJK UNIFIED IDEOGRAPH + {0xD889, 0x8C95}, //15192 #CJK UNIFIED IDEOGRAPH + {0xD88A, 0x8C96}, //15193 #CJK UNIFIED IDEOGRAPH + {0xD88B, 0x8C97}, //15194 #CJK UNIFIED IDEOGRAPH + {0xD88C, 0x8C99}, //15195 #CJK UNIFIED IDEOGRAPH + {0xD88D, 0x8C9A}, //15196 #CJK UNIFIED IDEOGRAPH + {0xD88E, 0x8C9B}, //15197 #CJK UNIFIED IDEOGRAPH + {0xD88F, 0x8C9C}, //15198 #CJK UNIFIED IDEOGRAPH + {0xD890, 0x8C9D}, //15199 #CJK UNIFIED IDEOGRAPH + {0xD891, 0x8C9E}, //15200 #CJK UNIFIED IDEOGRAPH + {0xD892, 0x8C9F}, //15201 #CJK UNIFIED IDEOGRAPH + {0xD893, 0x8CA0}, //15202 #CJK UNIFIED IDEOGRAPH + {0xD894, 0x8CA1}, //15203 #CJK UNIFIED IDEOGRAPH + {0xD895, 0x8CA2}, //15204 #CJK UNIFIED IDEOGRAPH + {0xD896, 0x8CA3}, //15205 #CJK UNIFIED IDEOGRAPH + {0xD897, 0x8CA4}, //15206 #CJK UNIFIED IDEOGRAPH + {0xD898, 0x8CA5}, //15207 #CJK UNIFIED IDEOGRAPH + {0xD899, 0x8CA6}, //15208 #CJK UNIFIED IDEOGRAPH + {0xD89A, 0x8CA7}, //15209 #CJK UNIFIED IDEOGRAPH + {0xD89B, 0x8CA8}, //15210 #CJK UNIFIED IDEOGRAPH + {0xD89C, 0x8CA9}, //15211 #CJK UNIFIED IDEOGRAPH + {0xD89D, 0x8CAA}, //15212 #CJK UNIFIED IDEOGRAPH + {0xD89E, 0x8CAB}, //15213 #CJK UNIFIED IDEOGRAPH + {0xD89F, 0x8CAC}, //15214 #CJK UNIFIED IDEOGRAPH + {0xD8A0, 0x8CAD}, //15215 #CJK UNIFIED IDEOGRAPH + {0xD8A1, 0x4E8D}, //15216 #CJK UNIFIED IDEOGRAPH + {0xD8A2, 0x4E0C}, //15217 #CJK UNIFIED IDEOGRAPH + {0xD8A3, 0x5140}, //15218 #CJK UNIFIED IDEOGRAPH + {0xD8A4, 0x4E10}, //15219 #CJK UNIFIED IDEOGRAPH + {0xD8A5, 0x5EFF}, //15220 #CJK UNIFIED IDEOGRAPH + {0xD8A6, 0x5345}, //15221 #CJK UNIFIED IDEOGRAPH + {0xD8A7, 0x4E15}, //15222 #CJK UNIFIED IDEOGRAPH + {0xD8A8, 0x4E98}, //15223 #CJK UNIFIED IDEOGRAPH + {0xD8A9, 0x4E1E}, //15224 #CJK UNIFIED IDEOGRAPH + {0xD8AA, 0x9B32}, //15225 #CJK UNIFIED IDEOGRAPH + {0xD8AB, 0x5B6C}, //15226 #CJK UNIFIED IDEOGRAPH + {0xD8AC, 0x5669}, //15227 #CJK UNIFIED IDEOGRAPH + {0xD8AD, 0x4E28}, //15228 #CJK UNIFIED IDEOGRAPH + {0xD8AE, 0x79BA}, //15229 #CJK UNIFIED IDEOGRAPH + {0xD8AF, 0x4E3F}, //15230 #CJK UNIFIED IDEOGRAPH + {0xD8B0, 0x5315}, //15231 #CJK UNIFIED IDEOGRAPH + {0xD8B1, 0x4E47}, //15232 #CJK UNIFIED IDEOGRAPH + {0xD8B2, 0x592D}, //15233 #CJK UNIFIED IDEOGRAPH + {0xD8B3, 0x723B}, //15234 #CJK UNIFIED IDEOGRAPH + {0xD8B4, 0x536E}, //15235 #CJK UNIFIED IDEOGRAPH + {0xD8B5, 0x6C10}, //15236 #CJK UNIFIED IDEOGRAPH + {0xD8B6, 0x56DF}, //15237 #CJK UNIFIED IDEOGRAPH + {0xD8B7, 0x80E4}, //15238 #CJK UNIFIED IDEOGRAPH + {0xD8B8, 0x9997}, //15239 #CJK UNIFIED IDEOGRAPH + {0xD8B9, 0x6BD3}, //15240 #CJK UNIFIED IDEOGRAPH + {0xD8BA, 0x777E}, //15241 #CJK UNIFIED IDEOGRAPH + {0xD8BB, 0x9F17}, //15242 #CJK UNIFIED IDEOGRAPH + {0xD8BC, 0x4E36}, //15243 #CJK UNIFIED IDEOGRAPH + {0xD8BD, 0x4E9F}, //15244 #CJK UNIFIED IDEOGRAPH + {0xD8BE, 0x9F10}, //15245 #CJK UNIFIED IDEOGRAPH + {0xD8BF, 0x4E5C}, //15246 #CJK UNIFIED IDEOGRAPH + {0xD8C0, 0x4E69}, //15247 #CJK UNIFIED IDEOGRAPH + {0xD8C1, 0x4E93}, //15248 #CJK UNIFIED IDEOGRAPH + {0xD8C2, 0x8288}, //15249 #CJK UNIFIED IDEOGRAPH + {0xD8C3, 0x5B5B}, //15250 #CJK UNIFIED IDEOGRAPH + {0xD8C4, 0x556C}, //15251 #CJK UNIFIED IDEOGRAPH + {0xD8C5, 0x560F}, //15252 #CJK UNIFIED IDEOGRAPH + {0xD8C6, 0x4EC4}, //15253 #CJK UNIFIED IDEOGRAPH + {0xD8C7, 0x538D}, //15254 #CJK UNIFIED IDEOGRAPH + {0xD8C8, 0x539D}, //15255 #CJK UNIFIED IDEOGRAPH + {0xD8C9, 0x53A3}, //15256 #CJK UNIFIED IDEOGRAPH + {0xD8CA, 0x53A5}, //15257 #CJK UNIFIED IDEOGRAPH + {0xD8CB, 0x53AE}, //15258 #CJK UNIFIED IDEOGRAPH + {0xD8CC, 0x9765}, //15259 #CJK UNIFIED IDEOGRAPH + {0xD8CD, 0x8D5D}, //15260 #CJK UNIFIED IDEOGRAPH + {0xD8CE, 0x531A}, //15261 #CJK UNIFIED IDEOGRAPH + {0xD8CF, 0x53F5}, //15262 #CJK UNIFIED IDEOGRAPH + {0xD8D0, 0x5326}, //15263 #CJK UNIFIED IDEOGRAPH + {0xD8D1, 0x532E}, //15264 #CJK UNIFIED IDEOGRAPH + {0xD8D2, 0x533E}, //15265 #CJK UNIFIED IDEOGRAPH + {0xD8D3, 0x8D5C}, //15266 #CJK UNIFIED IDEOGRAPH + {0xD8D4, 0x5366}, //15267 #CJK UNIFIED IDEOGRAPH + {0xD8D5, 0x5363}, //15268 #CJK UNIFIED IDEOGRAPH + {0xD8D6, 0x5202}, //15269 #CJK UNIFIED IDEOGRAPH + {0xD8D7, 0x5208}, //15270 #CJK UNIFIED IDEOGRAPH + {0xD8D8, 0x520E}, //15271 #CJK UNIFIED IDEOGRAPH + {0xD8D9, 0x522D}, //15272 #CJK UNIFIED IDEOGRAPH + {0xD8DA, 0x5233}, //15273 #CJK UNIFIED IDEOGRAPH + {0xD8DB, 0x523F}, //15274 #CJK UNIFIED IDEOGRAPH + {0xD8DC, 0x5240}, //15275 #CJK UNIFIED IDEOGRAPH + {0xD8DD, 0x524C}, //15276 #CJK UNIFIED IDEOGRAPH + {0xD8DE, 0x525E}, //15277 #CJK UNIFIED IDEOGRAPH + {0xD8DF, 0x5261}, //15278 #CJK UNIFIED IDEOGRAPH + {0xD8E0, 0x525C}, //15279 #CJK UNIFIED IDEOGRAPH + {0xD8E1, 0x84AF}, //15280 #CJK UNIFIED IDEOGRAPH + {0xD8E2, 0x527D}, //15281 #CJK UNIFIED IDEOGRAPH + {0xD8E3, 0x5282}, //15282 #CJK UNIFIED IDEOGRAPH + {0xD8E4, 0x5281}, //15283 #CJK UNIFIED IDEOGRAPH + {0xD8E5, 0x5290}, //15284 #CJK UNIFIED IDEOGRAPH + {0xD8E6, 0x5293}, //15285 #CJK UNIFIED IDEOGRAPH + {0xD8E7, 0x5182}, //15286 #CJK UNIFIED IDEOGRAPH + {0xD8E8, 0x7F54}, //15287 #CJK UNIFIED IDEOGRAPH + {0xD8E9, 0x4EBB}, //15288 #CJK UNIFIED IDEOGRAPH + {0xD8EA, 0x4EC3}, //15289 #CJK UNIFIED IDEOGRAPH + {0xD8EB, 0x4EC9}, //15290 #CJK UNIFIED IDEOGRAPH + {0xD8EC, 0x4EC2}, //15291 #CJK UNIFIED IDEOGRAPH + {0xD8ED, 0x4EE8}, //15292 #CJK UNIFIED IDEOGRAPH + {0xD8EE, 0x4EE1}, //15293 #CJK UNIFIED IDEOGRAPH + {0xD8EF, 0x4EEB}, //15294 #CJK UNIFIED IDEOGRAPH + {0xD8F0, 0x4EDE}, //15295 #CJK UNIFIED IDEOGRAPH + {0xD8F1, 0x4F1B}, //15296 #CJK UNIFIED IDEOGRAPH + {0xD8F2, 0x4EF3}, //15297 #CJK UNIFIED IDEOGRAPH + {0xD8F3, 0x4F22}, //15298 #CJK UNIFIED IDEOGRAPH + {0xD8F4, 0x4F64}, //15299 #CJK UNIFIED IDEOGRAPH + {0xD8F5, 0x4EF5}, //15300 #CJK UNIFIED IDEOGRAPH + {0xD8F6, 0x4F25}, //15301 #CJK UNIFIED IDEOGRAPH + {0xD8F7, 0x4F27}, //15302 #CJK UNIFIED IDEOGRAPH + {0xD8F8, 0x4F09}, //15303 #CJK UNIFIED IDEOGRAPH + {0xD8F9, 0x4F2B}, //15304 #CJK UNIFIED IDEOGRAPH + {0xD8FA, 0x4F5E}, //15305 #CJK UNIFIED IDEOGRAPH + {0xD8FB, 0x4F67}, //15306 #CJK UNIFIED IDEOGRAPH + {0xD8FC, 0x6538}, //15307 #CJK UNIFIED IDEOGRAPH + {0xD8FD, 0x4F5A}, //15308 #CJK UNIFIED IDEOGRAPH + {0xD8FE, 0x4F5D}, //15309 #CJK UNIFIED IDEOGRAPH + {0xD940, 0x8CAE}, //15310 #CJK UNIFIED IDEOGRAPH + {0xD941, 0x8CAF}, //15311 #CJK UNIFIED IDEOGRAPH + {0xD942, 0x8CB0}, //15312 #CJK UNIFIED IDEOGRAPH + {0xD943, 0x8CB1}, //15313 #CJK UNIFIED IDEOGRAPH + {0xD944, 0x8CB2}, //15314 #CJK UNIFIED IDEOGRAPH + {0xD945, 0x8CB3}, //15315 #CJK UNIFIED IDEOGRAPH + {0xD946, 0x8CB4}, //15316 #CJK UNIFIED IDEOGRAPH + {0xD947, 0x8CB5}, //15317 #CJK UNIFIED IDEOGRAPH + {0xD948, 0x8CB6}, //15318 #CJK UNIFIED IDEOGRAPH + {0xD949, 0x8CB7}, //15319 #CJK UNIFIED IDEOGRAPH + {0xD94A, 0x8CB8}, //15320 #CJK UNIFIED IDEOGRAPH + {0xD94B, 0x8CB9}, //15321 #CJK UNIFIED IDEOGRAPH + {0xD94C, 0x8CBA}, //15322 #CJK UNIFIED IDEOGRAPH + {0xD94D, 0x8CBB}, //15323 #CJK UNIFIED IDEOGRAPH + {0xD94E, 0x8CBC}, //15324 #CJK UNIFIED IDEOGRAPH + {0xD94F, 0x8CBD}, //15325 #CJK UNIFIED IDEOGRAPH + {0xD950, 0x8CBE}, //15326 #CJK UNIFIED IDEOGRAPH + {0xD951, 0x8CBF}, //15327 #CJK UNIFIED IDEOGRAPH + {0xD952, 0x8CC0}, //15328 #CJK UNIFIED IDEOGRAPH + {0xD953, 0x8CC1}, //15329 #CJK UNIFIED IDEOGRAPH + {0xD954, 0x8CC2}, //15330 #CJK UNIFIED IDEOGRAPH + {0xD955, 0x8CC3}, //15331 #CJK UNIFIED IDEOGRAPH + {0xD956, 0x8CC4}, //15332 #CJK UNIFIED IDEOGRAPH + {0xD957, 0x8CC5}, //15333 #CJK UNIFIED IDEOGRAPH + {0xD958, 0x8CC6}, //15334 #CJK UNIFIED IDEOGRAPH + {0xD959, 0x8CC7}, //15335 #CJK UNIFIED IDEOGRAPH + {0xD95A, 0x8CC8}, //15336 #CJK UNIFIED IDEOGRAPH + {0xD95B, 0x8CC9}, //15337 #CJK UNIFIED IDEOGRAPH + {0xD95C, 0x8CCA}, //15338 #CJK UNIFIED IDEOGRAPH + {0xD95D, 0x8CCB}, //15339 #CJK UNIFIED IDEOGRAPH + {0xD95E, 0x8CCC}, //15340 #CJK UNIFIED IDEOGRAPH + {0xD95F, 0x8CCD}, //15341 #CJK UNIFIED IDEOGRAPH + {0xD960, 0x8CCE}, //15342 #CJK UNIFIED IDEOGRAPH + {0xD961, 0x8CCF}, //15343 #CJK UNIFIED IDEOGRAPH + {0xD962, 0x8CD0}, //15344 #CJK UNIFIED IDEOGRAPH + {0xD963, 0x8CD1}, //15345 #CJK UNIFIED IDEOGRAPH + {0xD964, 0x8CD2}, //15346 #CJK UNIFIED IDEOGRAPH + {0xD965, 0x8CD3}, //15347 #CJK UNIFIED IDEOGRAPH + {0xD966, 0x8CD4}, //15348 #CJK UNIFIED IDEOGRAPH + {0xD967, 0x8CD5}, //15349 #CJK UNIFIED IDEOGRAPH + {0xD968, 0x8CD6}, //15350 #CJK UNIFIED IDEOGRAPH + {0xD969, 0x8CD7}, //15351 #CJK UNIFIED IDEOGRAPH + {0xD96A, 0x8CD8}, //15352 #CJK UNIFIED IDEOGRAPH + {0xD96B, 0x8CD9}, //15353 #CJK UNIFIED IDEOGRAPH + {0xD96C, 0x8CDA}, //15354 #CJK UNIFIED IDEOGRAPH + {0xD96D, 0x8CDB}, //15355 #CJK UNIFIED IDEOGRAPH + {0xD96E, 0x8CDC}, //15356 #CJK UNIFIED IDEOGRAPH + {0xD96F, 0x8CDD}, //15357 #CJK UNIFIED IDEOGRAPH + {0xD970, 0x8CDE}, //15358 #CJK UNIFIED IDEOGRAPH + {0xD971, 0x8CDF}, //15359 #CJK UNIFIED IDEOGRAPH + {0xD972, 0x8CE0}, //15360 #CJK UNIFIED IDEOGRAPH + {0xD973, 0x8CE1}, //15361 #CJK UNIFIED IDEOGRAPH + {0xD974, 0x8CE2}, //15362 #CJK UNIFIED IDEOGRAPH + {0xD975, 0x8CE3}, //15363 #CJK UNIFIED IDEOGRAPH + {0xD976, 0x8CE4}, //15364 #CJK UNIFIED IDEOGRAPH + {0xD977, 0x8CE5}, //15365 #CJK UNIFIED IDEOGRAPH + {0xD978, 0x8CE6}, //15366 #CJK UNIFIED IDEOGRAPH + {0xD979, 0x8CE7}, //15367 #CJK UNIFIED IDEOGRAPH + {0xD97A, 0x8CE8}, //15368 #CJK UNIFIED IDEOGRAPH + {0xD97B, 0x8CE9}, //15369 #CJK UNIFIED IDEOGRAPH + {0xD97C, 0x8CEA}, //15370 #CJK UNIFIED IDEOGRAPH + {0xD97D, 0x8CEB}, //15371 #CJK UNIFIED IDEOGRAPH + {0xD97E, 0x8CEC}, //15372 #CJK UNIFIED IDEOGRAPH + {0xD980, 0x8CED}, //15373 #CJK UNIFIED IDEOGRAPH + {0xD981, 0x8CEE}, //15374 #CJK UNIFIED IDEOGRAPH + {0xD982, 0x8CEF}, //15375 #CJK UNIFIED IDEOGRAPH + {0xD983, 0x8CF0}, //15376 #CJK UNIFIED IDEOGRAPH + {0xD984, 0x8CF1}, //15377 #CJK UNIFIED IDEOGRAPH + {0xD985, 0x8CF2}, //15378 #CJK UNIFIED IDEOGRAPH + {0xD986, 0x8CF3}, //15379 #CJK UNIFIED IDEOGRAPH + {0xD987, 0x8CF4}, //15380 #CJK UNIFIED IDEOGRAPH + {0xD988, 0x8CF5}, //15381 #CJK UNIFIED IDEOGRAPH + {0xD989, 0x8CF6}, //15382 #CJK UNIFIED IDEOGRAPH + {0xD98A, 0x8CF7}, //15383 #CJK UNIFIED IDEOGRAPH + {0xD98B, 0x8CF8}, //15384 #CJK UNIFIED IDEOGRAPH + {0xD98C, 0x8CF9}, //15385 #CJK UNIFIED IDEOGRAPH + {0xD98D, 0x8CFA}, //15386 #CJK UNIFIED IDEOGRAPH + {0xD98E, 0x8CFB}, //15387 #CJK UNIFIED IDEOGRAPH + {0xD98F, 0x8CFC}, //15388 #CJK UNIFIED IDEOGRAPH + {0xD990, 0x8CFD}, //15389 #CJK UNIFIED IDEOGRAPH + {0xD991, 0x8CFE}, //15390 #CJK UNIFIED IDEOGRAPH + {0xD992, 0x8CFF}, //15391 #CJK UNIFIED IDEOGRAPH + {0xD993, 0x8D00}, //15392 #CJK UNIFIED IDEOGRAPH + {0xD994, 0x8D01}, //15393 #CJK UNIFIED IDEOGRAPH + {0xD995, 0x8D02}, //15394 #CJK UNIFIED IDEOGRAPH + {0xD996, 0x8D03}, //15395 #CJK UNIFIED IDEOGRAPH + {0xD997, 0x8D04}, //15396 #CJK UNIFIED IDEOGRAPH + {0xD998, 0x8D05}, //15397 #CJK UNIFIED IDEOGRAPH + {0xD999, 0x8D06}, //15398 #CJK UNIFIED IDEOGRAPH + {0xD99A, 0x8D07}, //15399 #CJK UNIFIED IDEOGRAPH + {0xD99B, 0x8D08}, //15400 #CJK UNIFIED IDEOGRAPH + {0xD99C, 0x8D09}, //15401 #CJK UNIFIED IDEOGRAPH + {0xD99D, 0x8D0A}, //15402 #CJK UNIFIED IDEOGRAPH + {0xD99E, 0x8D0B}, //15403 #CJK UNIFIED IDEOGRAPH + {0xD99F, 0x8D0C}, //15404 #CJK UNIFIED IDEOGRAPH + {0xD9A0, 0x8D0D}, //15405 #CJK UNIFIED IDEOGRAPH + {0xD9A1, 0x4F5F}, //15406 #CJK UNIFIED IDEOGRAPH + {0xD9A2, 0x4F57}, //15407 #CJK UNIFIED IDEOGRAPH + {0xD9A3, 0x4F32}, //15408 #CJK UNIFIED IDEOGRAPH + {0xD9A4, 0x4F3D}, //15409 #CJK UNIFIED IDEOGRAPH + {0xD9A5, 0x4F76}, //15410 #CJK UNIFIED IDEOGRAPH + {0xD9A6, 0x4F74}, //15411 #CJK UNIFIED IDEOGRAPH + {0xD9A7, 0x4F91}, //15412 #CJK UNIFIED IDEOGRAPH + {0xD9A8, 0x4F89}, //15413 #CJK UNIFIED IDEOGRAPH + {0xD9A9, 0x4F83}, //15414 #CJK UNIFIED IDEOGRAPH + {0xD9AA, 0x4F8F}, //15415 #CJK UNIFIED IDEOGRAPH + {0xD9AB, 0x4F7E}, //15416 #CJK UNIFIED IDEOGRAPH + {0xD9AC, 0x4F7B}, //15417 #CJK UNIFIED IDEOGRAPH + {0xD9AD, 0x4FAA}, //15418 #CJK UNIFIED IDEOGRAPH + {0xD9AE, 0x4F7C}, //15419 #CJK UNIFIED IDEOGRAPH + {0xD9AF, 0x4FAC}, //15420 #CJK UNIFIED IDEOGRAPH + {0xD9B0, 0x4F94}, //15421 #CJK UNIFIED IDEOGRAPH + {0xD9B1, 0x4FE6}, //15422 #CJK UNIFIED IDEOGRAPH + {0xD9B2, 0x4FE8}, //15423 #CJK UNIFIED IDEOGRAPH + {0xD9B3, 0x4FEA}, //15424 #CJK UNIFIED IDEOGRAPH + {0xD9B4, 0x4FC5}, //15425 #CJK UNIFIED IDEOGRAPH + {0xD9B5, 0x4FDA}, //15426 #CJK UNIFIED IDEOGRAPH + {0xD9B6, 0x4FE3}, //15427 #CJK UNIFIED IDEOGRAPH + {0xD9B7, 0x4FDC}, //15428 #CJK UNIFIED IDEOGRAPH + {0xD9B8, 0x4FD1}, //15429 #CJK UNIFIED IDEOGRAPH + {0xD9B9, 0x4FDF}, //15430 #CJK UNIFIED IDEOGRAPH + {0xD9BA, 0x4FF8}, //15431 #CJK UNIFIED IDEOGRAPH + {0xD9BB, 0x5029}, //15432 #CJK UNIFIED IDEOGRAPH + {0xD9BC, 0x504C}, //15433 #CJK UNIFIED IDEOGRAPH + {0xD9BD, 0x4FF3}, //15434 #CJK UNIFIED IDEOGRAPH + {0xD9BE, 0x502C}, //15435 #CJK UNIFIED IDEOGRAPH + {0xD9BF, 0x500F}, //15436 #CJK UNIFIED IDEOGRAPH + {0xD9C0, 0x502E}, //15437 #CJK UNIFIED IDEOGRAPH + {0xD9C1, 0x502D}, //15438 #CJK UNIFIED IDEOGRAPH + {0xD9C2, 0x4FFE}, //15439 #CJK UNIFIED IDEOGRAPH + {0xD9C3, 0x501C}, //15440 #CJK UNIFIED IDEOGRAPH + {0xD9C4, 0x500C}, //15441 #CJK UNIFIED IDEOGRAPH + {0xD9C5, 0x5025}, //15442 #CJK UNIFIED IDEOGRAPH + {0xD9C6, 0x5028}, //15443 #CJK UNIFIED IDEOGRAPH + {0xD9C7, 0x507E}, //15444 #CJK UNIFIED IDEOGRAPH + {0xD9C8, 0x5043}, //15445 #CJK UNIFIED IDEOGRAPH + {0xD9C9, 0x5055}, //15446 #CJK UNIFIED IDEOGRAPH + {0xD9CA, 0x5048}, //15447 #CJK UNIFIED IDEOGRAPH + {0xD9CB, 0x504E}, //15448 #CJK UNIFIED IDEOGRAPH + {0xD9CC, 0x506C}, //15449 #CJK UNIFIED IDEOGRAPH + {0xD9CD, 0x507B}, //15450 #CJK UNIFIED IDEOGRAPH + {0xD9CE, 0x50A5}, //15451 #CJK UNIFIED IDEOGRAPH + {0xD9CF, 0x50A7}, //15452 #CJK UNIFIED IDEOGRAPH + {0xD9D0, 0x50A9}, //15453 #CJK UNIFIED IDEOGRAPH + {0xD9D1, 0x50BA}, //15454 #CJK UNIFIED IDEOGRAPH + {0xD9D2, 0x50D6}, //15455 #CJK UNIFIED IDEOGRAPH + {0xD9D3, 0x5106}, //15456 #CJK UNIFIED IDEOGRAPH + {0xD9D4, 0x50ED}, //15457 #CJK UNIFIED IDEOGRAPH + {0xD9D5, 0x50EC}, //15458 #CJK UNIFIED IDEOGRAPH + {0xD9D6, 0x50E6}, //15459 #CJK UNIFIED IDEOGRAPH + {0xD9D7, 0x50EE}, //15460 #CJK UNIFIED IDEOGRAPH + {0xD9D8, 0x5107}, //15461 #CJK UNIFIED IDEOGRAPH + {0xD9D9, 0x510B}, //15462 #CJK UNIFIED IDEOGRAPH + {0xD9DA, 0x4EDD}, //15463 #CJK UNIFIED IDEOGRAPH + {0xD9DB, 0x6C3D}, //15464 #CJK UNIFIED IDEOGRAPH + {0xD9DC, 0x4F58}, //15465 #CJK UNIFIED IDEOGRAPH + {0xD9DD, 0x4F65}, //15466 #CJK UNIFIED IDEOGRAPH + {0xD9DE, 0x4FCE}, //15467 #CJK UNIFIED IDEOGRAPH + {0xD9DF, 0x9FA0}, //15468 #CJK UNIFIED IDEOGRAPH + {0xD9E0, 0x6C46}, //15469 #CJK UNIFIED IDEOGRAPH + {0xD9E1, 0x7C74}, //15470 #CJK UNIFIED IDEOGRAPH + {0xD9E2, 0x516E}, //15471 #CJK UNIFIED IDEOGRAPH + {0xD9E3, 0x5DFD}, //15472 #CJK UNIFIED IDEOGRAPH + {0xD9E4, 0x9EC9}, //15473 #CJK UNIFIED IDEOGRAPH + {0xD9E5, 0x9998}, //15474 #CJK UNIFIED IDEOGRAPH + {0xD9E6, 0x5181}, //15475 #CJK UNIFIED IDEOGRAPH + {0xD9E7, 0x5914}, //15476 #CJK UNIFIED IDEOGRAPH + {0xD9E8, 0x52F9}, //15477 #CJK UNIFIED IDEOGRAPH + {0xD9E9, 0x530D}, //15478 #CJK UNIFIED IDEOGRAPH + {0xD9EA, 0x8A07}, //15479 #CJK UNIFIED IDEOGRAPH + {0xD9EB, 0x5310}, //15480 #CJK UNIFIED IDEOGRAPH + {0xD9EC, 0x51EB}, //15481 #CJK UNIFIED IDEOGRAPH + {0xD9ED, 0x5919}, //15482 #CJK UNIFIED IDEOGRAPH + {0xD9EE, 0x5155}, //15483 #CJK UNIFIED IDEOGRAPH + {0xD9EF, 0x4EA0}, //15484 #CJK UNIFIED IDEOGRAPH + {0xD9F0, 0x5156}, //15485 #CJK UNIFIED IDEOGRAPH + {0xD9F1, 0x4EB3}, //15486 #CJK UNIFIED IDEOGRAPH + {0xD9F2, 0x886E}, //15487 #CJK UNIFIED IDEOGRAPH + {0xD9F3, 0x88A4}, //15488 #CJK UNIFIED IDEOGRAPH + {0xD9F4, 0x4EB5}, //15489 #CJK UNIFIED IDEOGRAPH + {0xD9F5, 0x8114}, //15490 #CJK UNIFIED IDEOGRAPH + {0xD9F6, 0x88D2}, //15491 #CJK UNIFIED IDEOGRAPH + {0xD9F7, 0x7980}, //15492 #CJK UNIFIED IDEOGRAPH + {0xD9F8, 0x5B34}, //15493 #CJK UNIFIED IDEOGRAPH + {0xD9F9, 0x8803}, //15494 #CJK UNIFIED IDEOGRAPH + {0xD9FA, 0x7FB8}, //15495 #CJK UNIFIED IDEOGRAPH + {0xD9FB, 0x51AB}, //15496 #CJK UNIFIED IDEOGRAPH + {0xD9FC, 0x51B1}, //15497 #CJK UNIFIED IDEOGRAPH + {0xD9FD, 0x51BD}, //15498 #CJK UNIFIED IDEOGRAPH + {0xD9FE, 0x51BC}, //15499 #CJK UNIFIED IDEOGRAPH + {0xDA40, 0x8D0E}, //15500 #CJK UNIFIED IDEOGRAPH + {0xDA41, 0x8D0F}, //15501 #CJK UNIFIED IDEOGRAPH + {0xDA42, 0x8D10}, //15502 #CJK UNIFIED IDEOGRAPH + {0xDA43, 0x8D11}, //15503 #CJK UNIFIED IDEOGRAPH + {0xDA44, 0x8D12}, //15504 #CJK UNIFIED IDEOGRAPH + {0xDA45, 0x8D13}, //15505 #CJK UNIFIED IDEOGRAPH + {0xDA46, 0x8D14}, //15506 #CJK UNIFIED IDEOGRAPH + {0xDA47, 0x8D15}, //15507 #CJK UNIFIED IDEOGRAPH + {0xDA48, 0x8D16}, //15508 #CJK UNIFIED IDEOGRAPH + {0xDA49, 0x8D17}, //15509 #CJK UNIFIED IDEOGRAPH + {0xDA4A, 0x8D18}, //15510 #CJK UNIFIED IDEOGRAPH + {0xDA4B, 0x8D19}, //15511 #CJK UNIFIED IDEOGRAPH + {0xDA4C, 0x8D1A}, //15512 #CJK UNIFIED IDEOGRAPH + {0xDA4D, 0x8D1B}, //15513 #CJK UNIFIED IDEOGRAPH + {0xDA4E, 0x8D1C}, //15514 #CJK UNIFIED IDEOGRAPH + {0xDA4F, 0x8D20}, //15515 #CJK UNIFIED IDEOGRAPH + {0xDA50, 0x8D51}, //15516 #CJK UNIFIED IDEOGRAPH + {0xDA51, 0x8D52}, //15517 #CJK UNIFIED IDEOGRAPH + {0xDA52, 0x8D57}, //15518 #CJK UNIFIED IDEOGRAPH + {0xDA53, 0x8D5F}, //15519 #CJK UNIFIED IDEOGRAPH + {0xDA54, 0x8D65}, //15520 #CJK UNIFIED IDEOGRAPH + {0xDA55, 0x8D68}, //15521 #CJK UNIFIED IDEOGRAPH + {0xDA56, 0x8D69}, //15522 #CJK UNIFIED IDEOGRAPH + {0xDA57, 0x8D6A}, //15523 #CJK UNIFIED IDEOGRAPH + {0xDA58, 0x8D6C}, //15524 #CJK UNIFIED IDEOGRAPH + {0xDA59, 0x8D6E}, //15525 #CJK UNIFIED IDEOGRAPH + {0xDA5A, 0x8D6F}, //15526 #CJK UNIFIED IDEOGRAPH + {0xDA5B, 0x8D71}, //15527 #CJK UNIFIED IDEOGRAPH + {0xDA5C, 0x8D72}, //15528 #CJK UNIFIED IDEOGRAPH + {0xDA5D, 0x8D78}, //15529 #CJK UNIFIED IDEOGRAPH + {0xDA5E, 0x8D79}, //15530 #CJK UNIFIED IDEOGRAPH + {0xDA5F, 0x8D7A}, //15531 #CJK UNIFIED IDEOGRAPH + {0xDA60, 0x8D7B}, //15532 #CJK UNIFIED IDEOGRAPH + {0xDA61, 0x8D7C}, //15533 #CJK UNIFIED IDEOGRAPH + {0xDA62, 0x8D7D}, //15534 #CJK UNIFIED IDEOGRAPH + {0xDA63, 0x8D7E}, //15535 #CJK UNIFIED IDEOGRAPH + {0xDA64, 0x8D7F}, //15536 #CJK UNIFIED IDEOGRAPH + {0xDA65, 0x8D80}, //15537 #CJK UNIFIED IDEOGRAPH + {0xDA66, 0x8D82}, //15538 #CJK UNIFIED IDEOGRAPH + {0xDA67, 0x8D83}, //15539 #CJK UNIFIED IDEOGRAPH + {0xDA68, 0x8D86}, //15540 #CJK UNIFIED IDEOGRAPH + {0xDA69, 0x8D87}, //15541 #CJK UNIFIED IDEOGRAPH + {0xDA6A, 0x8D88}, //15542 #CJK UNIFIED IDEOGRAPH + {0xDA6B, 0x8D89}, //15543 #CJK UNIFIED IDEOGRAPH + {0xDA6C, 0x8D8C}, //15544 #CJK UNIFIED IDEOGRAPH + {0xDA6D, 0x8D8D}, //15545 #CJK UNIFIED IDEOGRAPH + {0xDA6E, 0x8D8E}, //15546 #CJK UNIFIED IDEOGRAPH + {0xDA6F, 0x8D8F}, //15547 #CJK UNIFIED IDEOGRAPH + {0xDA70, 0x8D90}, //15548 #CJK UNIFIED IDEOGRAPH + {0xDA71, 0x8D92}, //15549 #CJK UNIFIED IDEOGRAPH + {0xDA72, 0x8D93}, //15550 #CJK UNIFIED IDEOGRAPH + {0xDA73, 0x8D95}, //15551 #CJK UNIFIED IDEOGRAPH + {0xDA74, 0x8D96}, //15552 #CJK UNIFIED IDEOGRAPH + {0xDA75, 0x8D97}, //15553 #CJK UNIFIED IDEOGRAPH + {0xDA76, 0x8D98}, //15554 #CJK UNIFIED IDEOGRAPH + {0xDA77, 0x8D99}, //15555 #CJK UNIFIED IDEOGRAPH + {0xDA78, 0x8D9A}, //15556 #CJK UNIFIED IDEOGRAPH + {0xDA79, 0x8D9B}, //15557 #CJK UNIFIED IDEOGRAPH + {0xDA7A, 0x8D9C}, //15558 #CJK UNIFIED IDEOGRAPH + {0xDA7B, 0x8D9D}, //15559 #CJK UNIFIED IDEOGRAPH + {0xDA7C, 0x8D9E}, //15560 #CJK UNIFIED IDEOGRAPH + {0xDA7D, 0x8DA0}, //15561 #CJK UNIFIED IDEOGRAPH + {0xDA7E, 0x8DA1}, //15562 #CJK UNIFIED IDEOGRAPH + {0xDA80, 0x8DA2}, //15563 #CJK UNIFIED IDEOGRAPH + {0xDA81, 0x8DA4}, //15564 #CJK UNIFIED IDEOGRAPH + {0xDA82, 0x8DA5}, //15565 #CJK UNIFIED IDEOGRAPH + {0xDA83, 0x8DA6}, //15566 #CJK UNIFIED IDEOGRAPH + {0xDA84, 0x8DA7}, //15567 #CJK UNIFIED IDEOGRAPH + {0xDA85, 0x8DA8}, //15568 #CJK UNIFIED IDEOGRAPH + {0xDA86, 0x8DA9}, //15569 #CJK UNIFIED IDEOGRAPH + {0xDA87, 0x8DAA}, //15570 #CJK UNIFIED IDEOGRAPH + {0xDA88, 0x8DAB}, //15571 #CJK UNIFIED IDEOGRAPH + {0xDA89, 0x8DAC}, //15572 #CJK UNIFIED IDEOGRAPH + {0xDA8A, 0x8DAD}, //15573 #CJK UNIFIED IDEOGRAPH + {0xDA8B, 0x8DAE}, //15574 #CJK UNIFIED IDEOGRAPH + {0xDA8C, 0x8DAF}, //15575 #CJK UNIFIED IDEOGRAPH + {0xDA8D, 0x8DB0}, //15576 #CJK UNIFIED IDEOGRAPH + {0xDA8E, 0x8DB2}, //15577 #CJK UNIFIED IDEOGRAPH + {0xDA8F, 0x8DB6}, //15578 #CJK UNIFIED IDEOGRAPH + {0xDA90, 0x8DB7}, //15579 #CJK UNIFIED IDEOGRAPH + {0xDA91, 0x8DB9}, //15580 #CJK UNIFIED IDEOGRAPH + {0xDA92, 0x8DBB}, //15581 #CJK UNIFIED IDEOGRAPH + {0xDA93, 0x8DBD}, //15582 #CJK UNIFIED IDEOGRAPH + {0xDA94, 0x8DC0}, //15583 #CJK UNIFIED IDEOGRAPH + {0xDA95, 0x8DC1}, //15584 #CJK UNIFIED IDEOGRAPH + {0xDA96, 0x8DC2}, //15585 #CJK UNIFIED IDEOGRAPH + {0xDA97, 0x8DC5}, //15586 #CJK UNIFIED IDEOGRAPH + {0xDA98, 0x8DC7}, //15587 #CJK UNIFIED IDEOGRAPH + {0xDA99, 0x8DC8}, //15588 #CJK UNIFIED IDEOGRAPH + {0xDA9A, 0x8DC9}, //15589 #CJK UNIFIED IDEOGRAPH + {0xDA9B, 0x8DCA}, //15590 #CJK UNIFIED IDEOGRAPH + {0xDA9C, 0x8DCD}, //15591 #CJK UNIFIED IDEOGRAPH + {0xDA9D, 0x8DD0}, //15592 #CJK UNIFIED IDEOGRAPH + {0xDA9E, 0x8DD2}, //15593 #CJK UNIFIED IDEOGRAPH + {0xDA9F, 0x8DD3}, //15594 #CJK UNIFIED IDEOGRAPH + {0xDAA0, 0x8DD4}, //15595 #CJK UNIFIED IDEOGRAPH + {0xDAA1, 0x51C7}, //15596 #CJK UNIFIED IDEOGRAPH + {0xDAA2, 0x5196}, //15597 #CJK UNIFIED IDEOGRAPH + {0xDAA3, 0x51A2}, //15598 #CJK UNIFIED IDEOGRAPH + {0xDAA4, 0x51A5}, //15599 #CJK UNIFIED IDEOGRAPH + {0xDAA5, 0x8BA0}, //15600 #CJK UNIFIED IDEOGRAPH + {0xDAA6, 0x8BA6}, //15601 #CJK UNIFIED IDEOGRAPH + {0xDAA7, 0x8BA7}, //15602 #CJK UNIFIED IDEOGRAPH + {0xDAA8, 0x8BAA}, //15603 #CJK UNIFIED IDEOGRAPH + {0xDAA9, 0x8BB4}, //15604 #CJK UNIFIED IDEOGRAPH + {0xDAAA, 0x8BB5}, //15605 #CJK UNIFIED IDEOGRAPH + {0xDAAB, 0x8BB7}, //15606 #CJK UNIFIED IDEOGRAPH + {0xDAAC, 0x8BC2}, //15607 #CJK UNIFIED IDEOGRAPH + {0xDAAD, 0x8BC3}, //15608 #CJK UNIFIED IDEOGRAPH + {0xDAAE, 0x8BCB}, //15609 #CJK UNIFIED IDEOGRAPH + {0xDAAF, 0x8BCF}, //15610 #CJK UNIFIED IDEOGRAPH + {0xDAB0, 0x8BCE}, //15611 #CJK UNIFIED IDEOGRAPH + {0xDAB1, 0x8BD2}, //15612 #CJK UNIFIED IDEOGRAPH + {0xDAB2, 0x8BD3}, //15613 #CJK UNIFIED IDEOGRAPH + {0xDAB3, 0x8BD4}, //15614 #CJK UNIFIED IDEOGRAPH + {0xDAB4, 0x8BD6}, //15615 #CJK UNIFIED IDEOGRAPH + {0xDAB5, 0x8BD8}, //15616 #CJK UNIFIED IDEOGRAPH + {0xDAB6, 0x8BD9}, //15617 #CJK UNIFIED IDEOGRAPH + {0xDAB7, 0x8BDC}, //15618 #CJK UNIFIED IDEOGRAPH + {0xDAB8, 0x8BDF}, //15619 #CJK UNIFIED IDEOGRAPH + {0xDAB9, 0x8BE0}, //15620 #CJK UNIFIED IDEOGRAPH + {0xDABA, 0x8BE4}, //15621 #CJK UNIFIED IDEOGRAPH + {0xDABB, 0x8BE8}, //15622 #CJK UNIFIED IDEOGRAPH + {0xDABC, 0x8BE9}, //15623 #CJK UNIFIED IDEOGRAPH + {0xDABD, 0x8BEE}, //15624 #CJK UNIFIED IDEOGRAPH + {0xDABE, 0x8BF0}, //15625 #CJK UNIFIED IDEOGRAPH + {0xDABF, 0x8BF3}, //15626 #CJK UNIFIED IDEOGRAPH + {0xDAC0, 0x8BF6}, //15627 #CJK UNIFIED IDEOGRAPH + {0xDAC1, 0x8BF9}, //15628 #CJK UNIFIED IDEOGRAPH + {0xDAC2, 0x8BFC}, //15629 #CJK UNIFIED IDEOGRAPH + {0xDAC3, 0x8BFF}, //15630 #CJK UNIFIED IDEOGRAPH + {0xDAC4, 0x8C00}, //15631 #CJK UNIFIED IDEOGRAPH + {0xDAC5, 0x8C02}, //15632 #CJK UNIFIED IDEOGRAPH + {0xDAC6, 0x8C04}, //15633 #CJK UNIFIED IDEOGRAPH + {0xDAC7, 0x8C07}, //15634 #CJK UNIFIED IDEOGRAPH + {0xDAC8, 0x8C0C}, //15635 #CJK UNIFIED IDEOGRAPH + {0xDAC9, 0x8C0F}, //15636 #CJK UNIFIED IDEOGRAPH + {0xDACA, 0x8C11}, //15637 #CJK UNIFIED IDEOGRAPH + {0xDACB, 0x8C12}, //15638 #CJK UNIFIED IDEOGRAPH + {0xDACC, 0x8C14}, //15639 #CJK UNIFIED IDEOGRAPH + {0xDACD, 0x8C15}, //15640 #CJK UNIFIED IDEOGRAPH + {0xDACE, 0x8C16}, //15641 #CJK UNIFIED IDEOGRAPH + {0xDACF, 0x8C19}, //15642 #CJK UNIFIED IDEOGRAPH + {0xDAD0, 0x8C1B}, //15643 #CJK UNIFIED IDEOGRAPH + {0xDAD1, 0x8C18}, //15644 #CJK UNIFIED IDEOGRAPH + {0xDAD2, 0x8C1D}, //15645 #CJK UNIFIED IDEOGRAPH + {0xDAD3, 0x8C1F}, //15646 #CJK UNIFIED IDEOGRAPH + {0xDAD4, 0x8C20}, //15647 #CJK UNIFIED IDEOGRAPH + {0xDAD5, 0x8C21}, //15648 #CJK UNIFIED IDEOGRAPH + {0xDAD6, 0x8C25}, //15649 #CJK UNIFIED IDEOGRAPH + {0xDAD7, 0x8C27}, //15650 #CJK UNIFIED IDEOGRAPH + {0xDAD8, 0x8C2A}, //15651 #CJK UNIFIED IDEOGRAPH + {0xDAD9, 0x8C2B}, //15652 #CJK UNIFIED IDEOGRAPH + {0xDADA, 0x8C2E}, //15653 #CJK UNIFIED IDEOGRAPH + {0xDADB, 0x8C2F}, //15654 #CJK UNIFIED IDEOGRAPH + {0xDADC, 0x8C32}, //15655 #CJK UNIFIED IDEOGRAPH + {0xDADD, 0x8C33}, //15656 #CJK UNIFIED IDEOGRAPH + {0xDADE, 0x8C35}, //15657 #CJK UNIFIED IDEOGRAPH + {0xDADF, 0x8C36}, //15658 #CJK UNIFIED IDEOGRAPH + {0xDAE0, 0x5369}, //15659 #CJK UNIFIED IDEOGRAPH + {0xDAE1, 0x537A}, //15660 #CJK UNIFIED IDEOGRAPH + {0xDAE2, 0x961D}, //15661 #CJK UNIFIED IDEOGRAPH + {0xDAE3, 0x9622}, //15662 #CJK UNIFIED IDEOGRAPH + {0xDAE4, 0x9621}, //15663 #CJK UNIFIED IDEOGRAPH + {0xDAE5, 0x9631}, //15664 #CJK UNIFIED IDEOGRAPH + {0xDAE6, 0x962A}, //15665 #CJK UNIFIED IDEOGRAPH + {0xDAE7, 0x963D}, //15666 #CJK UNIFIED IDEOGRAPH + {0xDAE8, 0x963C}, //15667 #CJK UNIFIED IDEOGRAPH + {0xDAE9, 0x9642}, //15668 #CJK UNIFIED IDEOGRAPH + {0xDAEA, 0x9649}, //15669 #CJK UNIFIED IDEOGRAPH + {0xDAEB, 0x9654}, //15670 #CJK UNIFIED IDEOGRAPH + {0xDAEC, 0x965F}, //15671 #CJK UNIFIED IDEOGRAPH + {0xDAED, 0x9667}, //15672 #CJK UNIFIED IDEOGRAPH + {0xDAEE, 0x966C}, //15673 #CJK UNIFIED IDEOGRAPH + {0xDAEF, 0x9672}, //15674 #CJK UNIFIED IDEOGRAPH + {0xDAF0, 0x9674}, //15675 #CJK UNIFIED IDEOGRAPH + {0xDAF1, 0x9688}, //15676 #CJK UNIFIED IDEOGRAPH + {0xDAF2, 0x968D}, //15677 #CJK UNIFIED IDEOGRAPH + {0xDAF3, 0x9697}, //15678 #CJK UNIFIED IDEOGRAPH + {0xDAF4, 0x96B0}, //15679 #CJK UNIFIED IDEOGRAPH + {0xDAF5, 0x9097}, //15680 #CJK UNIFIED IDEOGRAPH + {0xDAF6, 0x909B}, //15681 #CJK UNIFIED IDEOGRAPH + {0xDAF7, 0x909D}, //15682 #CJK UNIFIED IDEOGRAPH + {0xDAF8, 0x9099}, //15683 #CJK UNIFIED IDEOGRAPH + {0xDAF9, 0x90AC}, //15684 #CJK UNIFIED IDEOGRAPH + {0xDAFA, 0x90A1}, //15685 #CJK UNIFIED IDEOGRAPH + {0xDAFB, 0x90B4}, //15686 #CJK UNIFIED IDEOGRAPH + {0xDAFC, 0x90B3}, //15687 #CJK UNIFIED IDEOGRAPH + {0xDAFD, 0x90B6}, //15688 #CJK UNIFIED IDEOGRAPH + {0xDAFE, 0x90BA}, //15689 #CJK UNIFIED IDEOGRAPH + {0xDB40, 0x8DD5}, //15690 #CJK UNIFIED IDEOGRAPH + {0xDB41, 0x8DD8}, //15691 #CJK UNIFIED IDEOGRAPH + {0xDB42, 0x8DD9}, //15692 #CJK UNIFIED IDEOGRAPH + {0xDB43, 0x8DDC}, //15693 #CJK UNIFIED IDEOGRAPH + {0xDB44, 0x8DE0}, //15694 #CJK UNIFIED IDEOGRAPH + {0xDB45, 0x8DE1}, //15695 #CJK UNIFIED IDEOGRAPH + {0xDB46, 0x8DE2}, //15696 #CJK UNIFIED IDEOGRAPH + {0xDB47, 0x8DE5}, //15697 #CJK UNIFIED IDEOGRAPH + {0xDB48, 0x8DE6}, //15698 #CJK UNIFIED IDEOGRAPH + {0xDB49, 0x8DE7}, //15699 #CJK UNIFIED IDEOGRAPH + {0xDB4A, 0x8DE9}, //15700 #CJK UNIFIED IDEOGRAPH + {0xDB4B, 0x8DED}, //15701 #CJK UNIFIED IDEOGRAPH + {0xDB4C, 0x8DEE}, //15702 #CJK UNIFIED IDEOGRAPH + {0xDB4D, 0x8DF0}, //15703 #CJK UNIFIED IDEOGRAPH + {0xDB4E, 0x8DF1}, //15704 #CJK UNIFIED IDEOGRAPH + {0xDB4F, 0x8DF2}, //15705 #CJK UNIFIED IDEOGRAPH + {0xDB50, 0x8DF4}, //15706 #CJK UNIFIED IDEOGRAPH + {0xDB51, 0x8DF6}, //15707 #CJK UNIFIED IDEOGRAPH + {0xDB52, 0x8DFC}, //15708 #CJK UNIFIED IDEOGRAPH + {0xDB53, 0x8DFE}, //15709 #CJK UNIFIED IDEOGRAPH + {0xDB54, 0x8DFF}, //15710 #CJK UNIFIED IDEOGRAPH + {0xDB55, 0x8E00}, //15711 #CJK UNIFIED IDEOGRAPH + {0xDB56, 0x8E01}, //15712 #CJK UNIFIED IDEOGRAPH + {0xDB57, 0x8E02}, //15713 #CJK UNIFIED IDEOGRAPH + {0xDB58, 0x8E03}, //15714 #CJK UNIFIED IDEOGRAPH + {0xDB59, 0x8E04}, //15715 #CJK UNIFIED IDEOGRAPH + {0xDB5A, 0x8E06}, //15716 #CJK UNIFIED IDEOGRAPH + {0xDB5B, 0x8E07}, //15717 #CJK UNIFIED IDEOGRAPH + {0xDB5C, 0x8E08}, //15718 #CJK UNIFIED IDEOGRAPH + {0xDB5D, 0x8E0B}, //15719 #CJK UNIFIED IDEOGRAPH + {0xDB5E, 0x8E0D}, //15720 #CJK UNIFIED IDEOGRAPH + {0xDB5F, 0x8E0E}, //15721 #CJK UNIFIED IDEOGRAPH + {0xDB60, 0x8E10}, //15722 #CJK UNIFIED IDEOGRAPH + {0xDB61, 0x8E11}, //15723 #CJK UNIFIED IDEOGRAPH + {0xDB62, 0x8E12}, //15724 #CJK UNIFIED IDEOGRAPH + {0xDB63, 0x8E13}, //15725 #CJK UNIFIED IDEOGRAPH + {0xDB64, 0x8E15}, //15726 #CJK UNIFIED IDEOGRAPH + {0xDB65, 0x8E16}, //15727 #CJK UNIFIED IDEOGRAPH + {0xDB66, 0x8E17}, //15728 #CJK UNIFIED IDEOGRAPH + {0xDB67, 0x8E18}, //15729 #CJK UNIFIED IDEOGRAPH + {0xDB68, 0x8E19}, //15730 #CJK UNIFIED IDEOGRAPH + {0xDB69, 0x8E1A}, //15731 #CJK UNIFIED IDEOGRAPH + {0xDB6A, 0x8E1B}, //15732 #CJK UNIFIED IDEOGRAPH + {0xDB6B, 0x8E1C}, //15733 #CJK UNIFIED IDEOGRAPH + {0xDB6C, 0x8E20}, //15734 #CJK UNIFIED IDEOGRAPH + {0xDB6D, 0x8E21}, //15735 #CJK UNIFIED IDEOGRAPH + {0xDB6E, 0x8E24}, //15736 #CJK UNIFIED IDEOGRAPH + {0xDB6F, 0x8E25}, //15737 #CJK UNIFIED IDEOGRAPH + {0xDB70, 0x8E26}, //15738 #CJK UNIFIED IDEOGRAPH + {0xDB71, 0x8E27}, //15739 #CJK UNIFIED IDEOGRAPH + {0xDB72, 0x8E28}, //15740 #CJK UNIFIED IDEOGRAPH + {0xDB73, 0x8E2B}, //15741 #CJK UNIFIED IDEOGRAPH + {0xDB74, 0x8E2D}, //15742 #CJK UNIFIED IDEOGRAPH + {0xDB75, 0x8E30}, //15743 #CJK UNIFIED IDEOGRAPH + {0xDB76, 0x8E32}, //15744 #CJK UNIFIED IDEOGRAPH + {0xDB77, 0x8E33}, //15745 #CJK UNIFIED IDEOGRAPH + {0xDB78, 0x8E34}, //15746 #CJK UNIFIED IDEOGRAPH + {0xDB79, 0x8E36}, //15747 #CJK UNIFIED IDEOGRAPH + {0xDB7A, 0x8E37}, //15748 #CJK UNIFIED IDEOGRAPH + {0xDB7B, 0x8E38}, //15749 #CJK UNIFIED IDEOGRAPH + {0xDB7C, 0x8E3B}, //15750 #CJK UNIFIED IDEOGRAPH + {0xDB7D, 0x8E3C}, //15751 #CJK UNIFIED IDEOGRAPH + {0xDB7E, 0x8E3E}, //15752 #CJK UNIFIED IDEOGRAPH + {0xDB80, 0x8E3F}, //15753 #CJK UNIFIED IDEOGRAPH + {0xDB81, 0x8E43}, //15754 #CJK UNIFIED IDEOGRAPH + {0xDB82, 0x8E45}, //15755 #CJK UNIFIED IDEOGRAPH + {0xDB83, 0x8E46}, //15756 #CJK UNIFIED IDEOGRAPH + {0xDB84, 0x8E4C}, //15757 #CJK UNIFIED IDEOGRAPH + {0xDB85, 0x8E4D}, //15758 #CJK UNIFIED IDEOGRAPH + {0xDB86, 0x8E4E}, //15759 #CJK UNIFIED IDEOGRAPH + {0xDB87, 0x8E4F}, //15760 #CJK UNIFIED IDEOGRAPH + {0xDB88, 0x8E50}, //15761 #CJK UNIFIED IDEOGRAPH + {0xDB89, 0x8E53}, //15762 #CJK UNIFIED IDEOGRAPH + {0xDB8A, 0x8E54}, //15763 #CJK UNIFIED IDEOGRAPH + {0xDB8B, 0x8E55}, //15764 #CJK UNIFIED IDEOGRAPH + {0xDB8C, 0x8E56}, //15765 #CJK UNIFIED IDEOGRAPH + {0xDB8D, 0x8E57}, //15766 #CJK UNIFIED IDEOGRAPH + {0xDB8E, 0x8E58}, //15767 #CJK UNIFIED IDEOGRAPH + {0xDB8F, 0x8E5A}, //15768 #CJK UNIFIED IDEOGRAPH + {0xDB90, 0x8E5B}, //15769 #CJK UNIFIED IDEOGRAPH + {0xDB91, 0x8E5C}, //15770 #CJK UNIFIED IDEOGRAPH + {0xDB92, 0x8E5D}, //15771 #CJK UNIFIED IDEOGRAPH + {0xDB93, 0x8E5E}, //15772 #CJK UNIFIED IDEOGRAPH + {0xDB94, 0x8E5F}, //15773 #CJK UNIFIED IDEOGRAPH + {0xDB95, 0x8E60}, //15774 #CJK UNIFIED IDEOGRAPH + {0xDB96, 0x8E61}, //15775 #CJK UNIFIED IDEOGRAPH + {0xDB97, 0x8E62}, //15776 #CJK UNIFIED IDEOGRAPH + {0xDB98, 0x8E63}, //15777 #CJK UNIFIED IDEOGRAPH + {0xDB99, 0x8E64}, //15778 #CJK UNIFIED IDEOGRAPH + {0xDB9A, 0x8E65}, //15779 #CJK UNIFIED IDEOGRAPH + {0xDB9B, 0x8E67}, //15780 #CJK UNIFIED IDEOGRAPH + {0xDB9C, 0x8E68}, //15781 #CJK UNIFIED IDEOGRAPH + {0xDB9D, 0x8E6A}, //15782 #CJK UNIFIED IDEOGRAPH + {0xDB9E, 0x8E6B}, //15783 #CJK UNIFIED IDEOGRAPH + {0xDB9F, 0x8E6E}, //15784 #CJK UNIFIED IDEOGRAPH + {0xDBA0, 0x8E71}, //15785 #CJK UNIFIED IDEOGRAPH + {0xDBA1, 0x90B8}, //15786 #CJK UNIFIED IDEOGRAPH + {0xDBA2, 0x90B0}, //15787 #CJK UNIFIED IDEOGRAPH + {0xDBA3, 0x90CF}, //15788 #CJK UNIFIED IDEOGRAPH + {0xDBA4, 0x90C5}, //15789 #CJK UNIFIED IDEOGRAPH + {0xDBA5, 0x90BE}, //15790 #CJK UNIFIED IDEOGRAPH + {0xDBA6, 0x90D0}, //15791 #CJK UNIFIED IDEOGRAPH + {0xDBA7, 0x90C4}, //15792 #CJK UNIFIED IDEOGRAPH + {0xDBA8, 0x90C7}, //15793 #CJK UNIFIED IDEOGRAPH + {0xDBA9, 0x90D3}, //15794 #CJK UNIFIED IDEOGRAPH + {0xDBAA, 0x90E6}, //15795 #CJK UNIFIED IDEOGRAPH + {0xDBAB, 0x90E2}, //15796 #CJK UNIFIED IDEOGRAPH + {0xDBAC, 0x90DC}, //15797 #CJK UNIFIED IDEOGRAPH + {0xDBAD, 0x90D7}, //15798 #CJK UNIFIED IDEOGRAPH + {0xDBAE, 0x90DB}, //15799 #CJK UNIFIED IDEOGRAPH + {0xDBAF, 0x90EB}, //15800 #CJK UNIFIED IDEOGRAPH + {0xDBB0, 0x90EF}, //15801 #CJK UNIFIED IDEOGRAPH + {0xDBB1, 0x90FE}, //15802 #CJK UNIFIED IDEOGRAPH + {0xDBB2, 0x9104}, //15803 #CJK UNIFIED IDEOGRAPH + {0xDBB3, 0x9122}, //15804 #CJK UNIFIED IDEOGRAPH + {0xDBB4, 0x911E}, //15805 #CJK UNIFIED IDEOGRAPH + {0xDBB5, 0x9123}, //15806 #CJK UNIFIED IDEOGRAPH + {0xDBB6, 0x9131}, //15807 #CJK UNIFIED IDEOGRAPH + {0xDBB7, 0x912F}, //15808 #CJK UNIFIED IDEOGRAPH + {0xDBB8, 0x9139}, //15809 #CJK UNIFIED IDEOGRAPH + {0xDBB9, 0x9143}, //15810 #CJK UNIFIED IDEOGRAPH + {0xDBBA, 0x9146}, //15811 #CJK UNIFIED IDEOGRAPH + {0xDBBB, 0x520D}, //15812 #CJK UNIFIED IDEOGRAPH + {0xDBBC, 0x5942}, //15813 #CJK UNIFIED IDEOGRAPH + {0xDBBD, 0x52A2}, //15814 #CJK UNIFIED IDEOGRAPH + {0xDBBE, 0x52AC}, //15815 #CJK UNIFIED IDEOGRAPH + {0xDBBF, 0x52AD}, //15816 #CJK UNIFIED IDEOGRAPH + {0xDBC0, 0x52BE}, //15817 #CJK UNIFIED IDEOGRAPH + {0xDBC1, 0x54FF}, //15818 #CJK UNIFIED IDEOGRAPH + {0xDBC2, 0x52D0}, //15819 #CJK UNIFIED IDEOGRAPH + {0xDBC3, 0x52D6}, //15820 #CJK UNIFIED IDEOGRAPH + {0xDBC4, 0x52F0}, //15821 #CJK UNIFIED IDEOGRAPH + {0xDBC5, 0x53DF}, //15822 #CJK UNIFIED IDEOGRAPH + {0xDBC6, 0x71EE}, //15823 #CJK UNIFIED IDEOGRAPH + {0xDBC7, 0x77CD}, //15824 #CJK UNIFIED IDEOGRAPH + {0xDBC8, 0x5EF4}, //15825 #CJK UNIFIED IDEOGRAPH + {0xDBC9, 0x51F5}, //15826 #CJK UNIFIED IDEOGRAPH + {0xDBCA, 0x51FC}, //15827 #CJK UNIFIED IDEOGRAPH + {0xDBCB, 0x9B2F}, //15828 #CJK UNIFIED IDEOGRAPH + {0xDBCC, 0x53B6}, //15829 #CJK UNIFIED IDEOGRAPH + {0xDBCD, 0x5F01}, //15830 #CJK UNIFIED IDEOGRAPH + {0xDBCE, 0x755A}, //15831 #CJK UNIFIED IDEOGRAPH + {0xDBCF, 0x5DEF}, //15832 #CJK UNIFIED IDEOGRAPH + {0xDBD0, 0x574C}, //15833 #CJK UNIFIED IDEOGRAPH + {0xDBD1, 0x57A9}, //15834 #CJK UNIFIED IDEOGRAPH + {0xDBD2, 0x57A1}, //15835 #CJK UNIFIED IDEOGRAPH + {0xDBD3, 0x587E}, //15836 #CJK UNIFIED IDEOGRAPH + {0xDBD4, 0x58BC}, //15837 #CJK UNIFIED IDEOGRAPH + {0xDBD5, 0x58C5}, //15838 #CJK UNIFIED IDEOGRAPH + {0xDBD6, 0x58D1}, //15839 #CJK UNIFIED IDEOGRAPH + {0xDBD7, 0x5729}, //15840 #CJK UNIFIED IDEOGRAPH + {0xDBD8, 0x572C}, //15841 #CJK UNIFIED IDEOGRAPH + {0xDBD9, 0x572A}, //15842 #CJK UNIFIED IDEOGRAPH + {0xDBDA, 0x5733}, //15843 #CJK UNIFIED IDEOGRAPH + {0xDBDB, 0x5739}, //15844 #CJK UNIFIED IDEOGRAPH + {0xDBDC, 0x572E}, //15845 #CJK UNIFIED IDEOGRAPH + {0xDBDD, 0x572F}, //15846 #CJK UNIFIED IDEOGRAPH + {0xDBDE, 0x575C}, //15847 #CJK UNIFIED IDEOGRAPH + {0xDBDF, 0x573B}, //15848 #CJK UNIFIED IDEOGRAPH + {0xDBE0, 0x5742}, //15849 #CJK UNIFIED IDEOGRAPH + {0xDBE1, 0x5769}, //15850 #CJK UNIFIED IDEOGRAPH + {0xDBE2, 0x5785}, //15851 #CJK UNIFIED IDEOGRAPH + {0xDBE3, 0x576B}, //15852 #CJK UNIFIED IDEOGRAPH + {0xDBE4, 0x5786}, //15853 #CJK UNIFIED IDEOGRAPH + {0xDBE5, 0x577C}, //15854 #CJK UNIFIED IDEOGRAPH + {0xDBE6, 0x577B}, //15855 #CJK UNIFIED IDEOGRAPH + {0xDBE7, 0x5768}, //15856 #CJK UNIFIED IDEOGRAPH + {0xDBE8, 0x576D}, //15857 #CJK UNIFIED IDEOGRAPH + {0xDBE9, 0x5776}, //15858 #CJK UNIFIED IDEOGRAPH + {0xDBEA, 0x5773}, //15859 #CJK UNIFIED IDEOGRAPH + {0xDBEB, 0x57AD}, //15860 #CJK UNIFIED IDEOGRAPH + {0xDBEC, 0x57A4}, //15861 #CJK UNIFIED IDEOGRAPH + {0xDBED, 0x578C}, //15862 #CJK UNIFIED IDEOGRAPH + {0xDBEE, 0x57B2}, //15863 #CJK UNIFIED IDEOGRAPH + {0xDBEF, 0x57CF}, //15864 #CJK UNIFIED IDEOGRAPH + {0xDBF0, 0x57A7}, //15865 #CJK UNIFIED IDEOGRAPH + {0xDBF1, 0x57B4}, //15866 #CJK UNIFIED IDEOGRAPH + {0xDBF2, 0x5793}, //15867 #CJK UNIFIED IDEOGRAPH + {0xDBF3, 0x57A0}, //15868 #CJK UNIFIED IDEOGRAPH + {0xDBF4, 0x57D5}, //15869 #CJK UNIFIED IDEOGRAPH + {0xDBF5, 0x57D8}, //15870 #CJK UNIFIED IDEOGRAPH + {0xDBF6, 0x57DA}, //15871 #CJK UNIFIED IDEOGRAPH + {0xDBF7, 0x57D9}, //15872 #CJK UNIFIED IDEOGRAPH + {0xDBF8, 0x57D2}, //15873 #CJK UNIFIED IDEOGRAPH + {0xDBF9, 0x57B8}, //15874 #CJK UNIFIED IDEOGRAPH + {0xDBFA, 0x57F4}, //15875 #CJK UNIFIED IDEOGRAPH + {0xDBFB, 0x57EF}, //15876 #CJK UNIFIED IDEOGRAPH + {0xDBFC, 0x57F8}, //15877 #CJK UNIFIED IDEOGRAPH + {0xDBFD, 0x57E4}, //15878 #CJK UNIFIED IDEOGRAPH + {0xDBFE, 0x57DD}, //15879 #CJK UNIFIED IDEOGRAPH + {0xDC40, 0x8E73}, //15880 #CJK UNIFIED IDEOGRAPH + {0xDC41, 0x8E75}, //15881 #CJK UNIFIED IDEOGRAPH + {0xDC42, 0x8E77}, //15882 #CJK UNIFIED IDEOGRAPH + {0xDC43, 0x8E78}, //15883 #CJK UNIFIED IDEOGRAPH + {0xDC44, 0x8E79}, //15884 #CJK UNIFIED IDEOGRAPH + {0xDC45, 0x8E7A}, //15885 #CJK UNIFIED IDEOGRAPH + {0xDC46, 0x8E7B}, //15886 #CJK UNIFIED IDEOGRAPH + {0xDC47, 0x8E7D}, //15887 #CJK UNIFIED IDEOGRAPH + {0xDC48, 0x8E7E}, //15888 #CJK UNIFIED IDEOGRAPH + {0xDC49, 0x8E80}, //15889 #CJK UNIFIED IDEOGRAPH + {0xDC4A, 0x8E82}, //15890 #CJK UNIFIED IDEOGRAPH + {0xDC4B, 0x8E83}, //15891 #CJK UNIFIED IDEOGRAPH + {0xDC4C, 0x8E84}, //15892 #CJK UNIFIED IDEOGRAPH + {0xDC4D, 0x8E86}, //15893 #CJK UNIFIED IDEOGRAPH + {0xDC4E, 0x8E88}, //15894 #CJK UNIFIED IDEOGRAPH + {0xDC4F, 0x8E89}, //15895 #CJK UNIFIED IDEOGRAPH + {0xDC50, 0x8E8A}, //15896 #CJK UNIFIED IDEOGRAPH + {0xDC51, 0x8E8B}, //15897 #CJK UNIFIED IDEOGRAPH + {0xDC52, 0x8E8C}, //15898 #CJK UNIFIED IDEOGRAPH + {0xDC53, 0x8E8D}, //15899 #CJK UNIFIED IDEOGRAPH + {0xDC54, 0x8E8E}, //15900 #CJK UNIFIED IDEOGRAPH + {0xDC55, 0x8E91}, //15901 #CJK UNIFIED IDEOGRAPH + {0xDC56, 0x8E92}, //15902 #CJK UNIFIED IDEOGRAPH + {0xDC57, 0x8E93}, //15903 #CJK UNIFIED IDEOGRAPH + {0xDC58, 0x8E95}, //15904 #CJK UNIFIED IDEOGRAPH + {0xDC59, 0x8E96}, //15905 #CJK UNIFIED IDEOGRAPH + {0xDC5A, 0x8E97}, //15906 #CJK UNIFIED IDEOGRAPH + {0xDC5B, 0x8E98}, //15907 #CJK UNIFIED IDEOGRAPH + {0xDC5C, 0x8E99}, //15908 #CJK UNIFIED IDEOGRAPH + {0xDC5D, 0x8E9A}, //15909 #CJK UNIFIED IDEOGRAPH + {0xDC5E, 0x8E9B}, //15910 #CJK UNIFIED IDEOGRAPH + {0xDC5F, 0x8E9D}, //15911 #CJK UNIFIED IDEOGRAPH + {0xDC60, 0x8E9F}, //15912 #CJK UNIFIED IDEOGRAPH + {0xDC61, 0x8EA0}, //15913 #CJK UNIFIED IDEOGRAPH + {0xDC62, 0x8EA1}, //15914 #CJK UNIFIED IDEOGRAPH + {0xDC63, 0x8EA2}, //15915 #CJK UNIFIED IDEOGRAPH + {0xDC64, 0x8EA3}, //15916 #CJK UNIFIED IDEOGRAPH + {0xDC65, 0x8EA4}, //15917 #CJK UNIFIED IDEOGRAPH + {0xDC66, 0x8EA5}, //15918 #CJK UNIFIED IDEOGRAPH + {0xDC67, 0x8EA6}, //15919 #CJK UNIFIED IDEOGRAPH + {0xDC68, 0x8EA7}, //15920 #CJK UNIFIED IDEOGRAPH + {0xDC69, 0x8EA8}, //15921 #CJK UNIFIED IDEOGRAPH + {0xDC6A, 0x8EA9}, //15922 #CJK UNIFIED IDEOGRAPH + {0xDC6B, 0x8EAA}, //15923 #CJK UNIFIED IDEOGRAPH + {0xDC6C, 0x8EAD}, //15924 #CJK UNIFIED IDEOGRAPH + {0xDC6D, 0x8EAE}, //15925 #CJK UNIFIED IDEOGRAPH + {0xDC6E, 0x8EB0}, //15926 #CJK UNIFIED IDEOGRAPH + {0xDC6F, 0x8EB1}, //15927 #CJK UNIFIED IDEOGRAPH + {0xDC70, 0x8EB3}, //15928 #CJK UNIFIED IDEOGRAPH + {0xDC71, 0x8EB4}, //15929 #CJK UNIFIED IDEOGRAPH + {0xDC72, 0x8EB5}, //15930 #CJK UNIFIED IDEOGRAPH + {0xDC73, 0x8EB6}, //15931 #CJK UNIFIED IDEOGRAPH + {0xDC74, 0x8EB7}, //15932 #CJK UNIFIED IDEOGRAPH + {0xDC75, 0x8EB8}, //15933 #CJK UNIFIED IDEOGRAPH + {0xDC76, 0x8EB9}, //15934 #CJK UNIFIED IDEOGRAPH + {0xDC77, 0x8EBB}, //15935 #CJK UNIFIED IDEOGRAPH + {0xDC78, 0x8EBC}, //15936 #CJK UNIFIED IDEOGRAPH + {0xDC79, 0x8EBD}, //15937 #CJK UNIFIED IDEOGRAPH + {0xDC7A, 0x8EBE}, //15938 #CJK UNIFIED IDEOGRAPH + {0xDC7B, 0x8EBF}, //15939 #CJK UNIFIED IDEOGRAPH + {0xDC7C, 0x8EC0}, //15940 #CJK UNIFIED IDEOGRAPH + {0xDC7D, 0x8EC1}, //15941 #CJK UNIFIED IDEOGRAPH + {0xDC7E, 0x8EC2}, //15942 #CJK UNIFIED IDEOGRAPH + {0xDC80, 0x8EC3}, //15943 #CJK UNIFIED IDEOGRAPH + {0xDC81, 0x8EC4}, //15944 #CJK UNIFIED IDEOGRAPH + {0xDC82, 0x8EC5}, //15945 #CJK UNIFIED IDEOGRAPH + {0xDC83, 0x8EC6}, //15946 #CJK UNIFIED IDEOGRAPH + {0xDC84, 0x8EC7}, //15947 #CJK UNIFIED IDEOGRAPH + {0xDC85, 0x8EC8}, //15948 #CJK UNIFIED IDEOGRAPH + {0xDC86, 0x8EC9}, //15949 #CJK UNIFIED IDEOGRAPH + {0xDC87, 0x8ECA}, //15950 #CJK UNIFIED IDEOGRAPH + {0xDC88, 0x8ECB}, //15951 #CJK UNIFIED IDEOGRAPH + {0xDC89, 0x8ECC}, //15952 #CJK UNIFIED IDEOGRAPH + {0xDC8A, 0x8ECD}, //15953 #CJK UNIFIED IDEOGRAPH + {0xDC8B, 0x8ECF}, //15954 #CJK UNIFIED IDEOGRAPH + {0xDC8C, 0x8ED0}, //15955 #CJK UNIFIED IDEOGRAPH + {0xDC8D, 0x8ED1}, //15956 #CJK UNIFIED IDEOGRAPH + {0xDC8E, 0x8ED2}, //15957 #CJK UNIFIED IDEOGRAPH + {0xDC8F, 0x8ED3}, //15958 #CJK UNIFIED IDEOGRAPH + {0xDC90, 0x8ED4}, //15959 #CJK UNIFIED IDEOGRAPH + {0xDC91, 0x8ED5}, //15960 #CJK UNIFIED IDEOGRAPH + {0xDC92, 0x8ED6}, //15961 #CJK UNIFIED IDEOGRAPH + {0xDC93, 0x8ED7}, //15962 #CJK UNIFIED IDEOGRAPH + {0xDC94, 0x8ED8}, //15963 #CJK UNIFIED IDEOGRAPH + {0xDC95, 0x8ED9}, //15964 #CJK UNIFIED IDEOGRAPH + {0xDC96, 0x8EDA}, //15965 #CJK UNIFIED IDEOGRAPH + {0xDC97, 0x8EDB}, //15966 #CJK UNIFIED IDEOGRAPH + {0xDC98, 0x8EDC}, //15967 #CJK UNIFIED IDEOGRAPH + {0xDC99, 0x8EDD}, //15968 #CJK UNIFIED IDEOGRAPH + {0xDC9A, 0x8EDE}, //15969 #CJK UNIFIED IDEOGRAPH + {0xDC9B, 0x8EDF}, //15970 #CJK UNIFIED IDEOGRAPH + {0xDC9C, 0x8EE0}, //15971 #CJK UNIFIED IDEOGRAPH + {0xDC9D, 0x8EE1}, //15972 #CJK UNIFIED IDEOGRAPH + {0xDC9E, 0x8EE2}, //15973 #CJK UNIFIED IDEOGRAPH + {0xDC9F, 0x8EE3}, //15974 #CJK UNIFIED IDEOGRAPH + {0xDCA0, 0x8EE4}, //15975 #CJK UNIFIED IDEOGRAPH + {0xDCA1, 0x580B}, //15976 #CJK UNIFIED IDEOGRAPH + {0xDCA2, 0x580D}, //15977 #CJK UNIFIED IDEOGRAPH + {0xDCA3, 0x57FD}, //15978 #CJK UNIFIED IDEOGRAPH + {0xDCA4, 0x57ED}, //15979 #CJK UNIFIED IDEOGRAPH + {0xDCA5, 0x5800}, //15980 #CJK UNIFIED IDEOGRAPH + {0xDCA6, 0x581E}, //15981 #CJK UNIFIED IDEOGRAPH + {0xDCA7, 0x5819}, //15982 #CJK UNIFIED IDEOGRAPH + {0xDCA8, 0x5844}, //15983 #CJK UNIFIED IDEOGRAPH + {0xDCA9, 0x5820}, //15984 #CJK UNIFIED IDEOGRAPH + {0xDCAA, 0x5865}, //15985 #CJK UNIFIED IDEOGRAPH + {0xDCAB, 0x586C}, //15986 #CJK UNIFIED IDEOGRAPH + {0xDCAC, 0x5881}, //15987 #CJK UNIFIED IDEOGRAPH + {0xDCAD, 0x5889}, //15988 #CJK UNIFIED IDEOGRAPH + {0xDCAE, 0x589A}, //15989 #CJK UNIFIED IDEOGRAPH + {0xDCAF, 0x5880}, //15990 #CJK UNIFIED IDEOGRAPH + {0xDCB0, 0x99A8}, //15991 #CJK UNIFIED IDEOGRAPH + {0xDCB1, 0x9F19}, //15992 #CJK UNIFIED IDEOGRAPH + {0xDCB2, 0x61FF}, //15993 #CJK UNIFIED IDEOGRAPH + {0xDCB3, 0x8279}, //15994 #CJK UNIFIED IDEOGRAPH + {0xDCB4, 0x827D}, //15995 #CJK UNIFIED IDEOGRAPH + {0xDCB5, 0x827F}, //15996 #CJK UNIFIED IDEOGRAPH + {0xDCB6, 0x828F}, //15997 #CJK UNIFIED IDEOGRAPH + {0xDCB7, 0x828A}, //15998 #CJK UNIFIED IDEOGRAPH + {0xDCB8, 0x82A8}, //15999 #CJK UNIFIED IDEOGRAPH + {0xDCB9, 0x8284}, //16000 #CJK UNIFIED IDEOGRAPH + {0xDCBA, 0x828E}, //16001 #CJK UNIFIED IDEOGRAPH + {0xDCBB, 0x8291}, //16002 #CJK UNIFIED IDEOGRAPH + {0xDCBC, 0x8297}, //16003 #CJK UNIFIED IDEOGRAPH + {0xDCBD, 0x8299}, //16004 #CJK UNIFIED IDEOGRAPH + {0xDCBE, 0x82AB}, //16005 #CJK UNIFIED IDEOGRAPH + {0xDCBF, 0x82B8}, //16006 #CJK UNIFIED IDEOGRAPH + {0xDCC0, 0x82BE}, //16007 #CJK UNIFIED IDEOGRAPH + {0xDCC1, 0x82B0}, //16008 #CJK UNIFIED IDEOGRAPH + {0xDCC2, 0x82C8}, //16009 #CJK UNIFIED IDEOGRAPH + {0xDCC3, 0x82CA}, //16010 #CJK UNIFIED IDEOGRAPH + {0xDCC4, 0x82E3}, //16011 #CJK UNIFIED IDEOGRAPH + {0xDCC5, 0x8298}, //16012 #CJK UNIFIED IDEOGRAPH + {0xDCC6, 0x82B7}, //16013 #CJK UNIFIED IDEOGRAPH + {0xDCC7, 0x82AE}, //16014 #CJK UNIFIED IDEOGRAPH + {0xDCC8, 0x82CB}, //16015 #CJK UNIFIED IDEOGRAPH + {0xDCC9, 0x82CC}, //16016 #CJK UNIFIED IDEOGRAPH + {0xDCCA, 0x82C1}, //16017 #CJK UNIFIED IDEOGRAPH + {0xDCCB, 0x82A9}, //16018 #CJK UNIFIED IDEOGRAPH + {0xDCCC, 0x82B4}, //16019 #CJK UNIFIED IDEOGRAPH + {0xDCCD, 0x82A1}, //16020 #CJK UNIFIED IDEOGRAPH + {0xDCCE, 0x82AA}, //16021 #CJK UNIFIED IDEOGRAPH + {0xDCCF, 0x829F}, //16022 #CJK UNIFIED IDEOGRAPH + {0xDCD0, 0x82C4}, //16023 #CJK UNIFIED IDEOGRAPH + {0xDCD1, 0x82CE}, //16024 #CJK UNIFIED IDEOGRAPH + {0xDCD2, 0x82A4}, //16025 #CJK UNIFIED IDEOGRAPH + {0xDCD3, 0x82E1}, //16026 #CJK UNIFIED IDEOGRAPH + {0xDCD4, 0x8309}, //16027 #CJK UNIFIED IDEOGRAPH + {0xDCD5, 0x82F7}, //16028 #CJK UNIFIED IDEOGRAPH + {0xDCD6, 0x82E4}, //16029 #CJK UNIFIED IDEOGRAPH + {0xDCD7, 0x830F}, //16030 #CJK UNIFIED IDEOGRAPH + {0xDCD8, 0x8307}, //16031 #CJK UNIFIED IDEOGRAPH + {0xDCD9, 0x82DC}, //16032 #CJK UNIFIED IDEOGRAPH + {0xDCDA, 0x82F4}, //16033 #CJK UNIFIED IDEOGRAPH + {0xDCDB, 0x82D2}, //16034 #CJK UNIFIED IDEOGRAPH + {0xDCDC, 0x82D8}, //16035 #CJK UNIFIED IDEOGRAPH + {0xDCDD, 0x830C}, //16036 #CJK UNIFIED IDEOGRAPH + {0xDCDE, 0x82FB}, //16037 #CJK UNIFIED IDEOGRAPH + {0xDCDF, 0x82D3}, //16038 #CJK UNIFIED IDEOGRAPH + {0xDCE0, 0x8311}, //16039 #CJK UNIFIED IDEOGRAPH + {0xDCE1, 0x831A}, //16040 #CJK UNIFIED IDEOGRAPH + {0xDCE2, 0x8306}, //16041 #CJK UNIFIED IDEOGRAPH + {0xDCE3, 0x8314}, //16042 #CJK UNIFIED IDEOGRAPH + {0xDCE4, 0x8315}, //16043 #CJK UNIFIED IDEOGRAPH + {0xDCE5, 0x82E0}, //16044 #CJK UNIFIED IDEOGRAPH + {0xDCE6, 0x82D5}, //16045 #CJK UNIFIED IDEOGRAPH + {0xDCE7, 0x831C}, //16046 #CJK UNIFIED IDEOGRAPH + {0xDCE8, 0x8351}, //16047 #CJK UNIFIED IDEOGRAPH + {0xDCE9, 0x835B}, //16048 #CJK UNIFIED IDEOGRAPH + {0xDCEA, 0x835C}, //16049 #CJK UNIFIED IDEOGRAPH + {0xDCEB, 0x8308}, //16050 #CJK UNIFIED IDEOGRAPH + {0xDCEC, 0x8392}, //16051 #CJK UNIFIED IDEOGRAPH + {0xDCED, 0x833C}, //16052 #CJK UNIFIED IDEOGRAPH + {0xDCEE, 0x8334}, //16053 #CJK UNIFIED IDEOGRAPH + {0xDCEF, 0x8331}, //16054 #CJK UNIFIED IDEOGRAPH + {0xDCF0, 0x839B}, //16055 #CJK UNIFIED IDEOGRAPH + {0xDCF1, 0x835E}, //16056 #CJK UNIFIED IDEOGRAPH + {0xDCF2, 0x832F}, //16057 #CJK UNIFIED IDEOGRAPH + {0xDCF3, 0x834F}, //16058 #CJK UNIFIED IDEOGRAPH + {0xDCF4, 0x8347}, //16059 #CJK UNIFIED IDEOGRAPH + {0xDCF5, 0x8343}, //16060 #CJK UNIFIED IDEOGRAPH + {0xDCF6, 0x835F}, //16061 #CJK UNIFIED IDEOGRAPH + {0xDCF7, 0x8340}, //16062 #CJK UNIFIED IDEOGRAPH + {0xDCF8, 0x8317}, //16063 #CJK UNIFIED IDEOGRAPH + {0xDCF9, 0x8360}, //16064 #CJK UNIFIED IDEOGRAPH + {0xDCFA, 0x832D}, //16065 #CJK UNIFIED IDEOGRAPH + {0xDCFB, 0x833A}, //16066 #CJK UNIFIED IDEOGRAPH + {0xDCFC, 0x8333}, //16067 #CJK UNIFIED IDEOGRAPH + {0xDCFD, 0x8366}, //16068 #CJK UNIFIED IDEOGRAPH + {0xDCFE, 0x8365}, //16069 #CJK UNIFIED IDEOGRAPH + {0xDD40, 0x8EE5}, //16070 #CJK UNIFIED IDEOGRAPH + {0xDD41, 0x8EE6}, //16071 #CJK UNIFIED IDEOGRAPH + {0xDD42, 0x8EE7}, //16072 #CJK UNIFIED IDEOGRAPH + {0xDD43, 0x8EE8}, //16073 #CJK UNIFIED IDEOGRAPH + {0xDD44, 0x8EE9}, //16074 #CJK UNIFIED IDEOGRAPH + {0xDD45, 0x8EEA}, //16075 #CJK UNIFIED IDEOGRAPH + {0xDD46, 0x8EEB}, //16076 #CJK UNIFIED IDEOGRAPH + {0xDD47, 0x8EEC}, //16077 #CJK UNIFIED IDEOGRAPH + {0xDD48, 0x8EED}, //16078 #CJK UNIFIED IDEOGRAPH + {0xDD49, 0x8EEE}, //16079 #CJK UNIFIED IDEOGRAPH + {0xDD4A, 0x8EEF}, //16080 #CJK UNIFIED IDEOGRAPH + {0xDD4B, 0x8EF0}, //16081 #CJK UNIFIED IDEOGRAPH + {0xDD4C, 0x8EF1}, //16082 #CJK UNIFIED IDEOGRAPH + {0xDD4D, 0x8EF2}, //16083 #CJK UNIFIED IDEOGRAPH + {0xDD4E, 0x8EF3}, //16084 #CJK UNIFIED IDEOGRAPH + {0xDD4F, 0x8EF4}, //16085 #CJK UNIFIED IDEOGRAPH + {0xDD50, 0x8EF5}, //16086 #CJK UNIFIED IDEOGRAPH + {0xDD51, 0x8EF6}, //16087 #CJK UNIFIED IDEOGRAPH + {0xDD52, 0x8EF7}, //16088 #CJK UNIFIED IDEOGRAPH + {0xDD53, 0x8EF8}, //16089 #CJK UNIFIED IDEOGRAPH + {0xDD54, 0x8EF9}, //16090 #CJK UNIFIED IDEOGRAPH + {0xDD55, 0x8EFA}, //16091 #CJK UNIFIED IDEOGRAPH + {0xDD56, 0x8EFB}, //16092 #CJK UNIFIED IDEOGRAPH + {0xDD57, 0x8EFC}, //16093 #CJK UNIFIED IDEOGRAPH + {0xDD58, 0x8EFD}, //16094 #CJK UNIFIED IDEOGRAPH + {0xDD59, 0x8EFE}, //16095 #CJK UNIFIED IDEOGRAPH + {0xDD5A, 0x8EFF}, //16096 #CJK UNIFIED IDEOGRAPH + {0xDD5B, 0x8F00}, //16097 #CJK UNIFIED IDEOGRAPH + {0xDD5C, 0x8F01}, //16098 #CJK UNIFIED IDEOGRAPH + {0xDD5D, 0x8F02}, //16099 #CJK UNIFIED IDEOGRAPH + {0xDD5E, 0x8F03}, //16100 #CJK UNIFIED IDEOGRAPH + {0xDD5F, 0x8F04}, //16101 #CJK UNIFIED IDEOGRAPH + {0xDD60, 0x8F05}, //16102 #CJK UNIFIED IDEOGRAPH + {0xDD61, 0x8F06}, //16103 #CJK UNIFIED IDEOGRAPH + {0xDD62, 0x8F07}, //16104 #CJK UNIFIED IDEOGRAPH + {0xDD63, 0x8F08}, //16105 #CJK UNIFIED IDEOGRAPH + {0xDD64, 0x8F09}, //16106 #CJK UNIFIED IDEOGRAPH + {0xDD65, 0x8F0A}, //16107 #CJK UNIFIED IDEOGRAPH + {0xDD66, 0x8F0B}, //16108 #CJK UNIFIED IDEOGRAPH + {0xDD67, 0x8F0C}, //16109 #CJK UNIFIED IDEOGRAPH + {0xDD68, 0x8F0D}, //16110 #CJK UNIFIED IDEOGRAPH + {0xDD69, 0x8F0E}, //16111 #CJK UNIFIED IDEOGRAPH + {0xDD6A, 0x8F0F}, //16112 #CJK UNIFIED IDEOGRAPH + {0xDD6B, 0x8F10}, //16113 #CJK UNIFIED IDEOGRAPH + {0xDD6C, 0x8F11}, //16114 #CJK UNIFIED IDEOGRAPH + {0xDD6D, 0x8F12}, //16115 #CJK UNIFIED IDEOGRAPH + {0xDD6E, 0x8F13}, //16116 #CJK UNIFIED IDEOGRAPH + {0xDD6F, 0x8F14}, //16117 #CJK UNIFIED IDEOGRAPH + {0xDD70, 0x8F15}, //16118 #CJK UNIFIED IDEOGRAPH + {0xDD71, 0x8F16}, //16119 #CJK UNIFIED IDEOGRAPH + {0xDD72, 0x8F17}, //16120 #CJK UNIFIED IDEOGRAPH + {0xDD73, 0x8F18}, //16121 #CJK UNIFIED IDEOGRAPH + {0xDD74, 0x8F19}, //16122 #CJK UNIFIED IDEOGRAPH + {0xDD75, 0x8F1A}, //16123 #CJK UNIFIED IDEOGRAPH + {0xDD76, 0x8F1B}, //16124 #CJK UNIFIED IDEOGRAPH + {0xDD77, 0x8F1C}, //16125 #CJK UNIFIED IDEOGRAPH + {0xDD78, 0x8F1D}, //16126 #CJK UNIFIED IDEOGRAPH + {0xDD79, 0x8F1E}, //16127 #CJK UNIFIED IDEOGRAPH + {0xDD7A, 0x8F1F}, //16128 #CJK UNIFIED IDEOGRAPH + {0xDD7B, 0x8F20}, //16129 #CJK UNIFIED IDEOGRAPH + {0xDD7C, 0x8F21}, //16130 #CJK UNIFIED IDEOGRAPH + {0xDD7D, 0x8F22}, //16131 #CJK UNIFIED IDEOGRAPH + {0xDD7E, 0x8F23}, //16132 #CJK UNIFIED IDEOGRAPH + {0xDD80, 0x8F24}, //16133 #CJK UNIFIED IDEOGRAPH + {0xDD81, 0x8F25}, //16134 #CJK UNIFIED IDEOGRAPH + {0xDD82, 0x8F26}, //16135 #CJK UNIFIED IDEOGRAPH + {0xDD83, 0x8F27}, //16136 #CJK UNIFIED IDEOGRAPH + {0xDD84, 0x8F28}, //16137 #CJK UNIFIED IDEOGRAPH + {0xDD85, 0x8F29}, //16138 #CJK UNIFIED IDEOGRAPH + {0xDD86, 0x8F2A}, //16139 #CJK UNIFIED IDEOGRAPH + {0xDD87, 0x8F2B}, //16140 #CJK UNIFIED IDEOGRAPH + {0xDD88, 0x8F2C}, //16141 #CJK UNIFIED IDEOGRAPH + {0xDD89, 0x8F2D}, //16142 #CJK UNIFIED IDEOGRAPH + {0xDD8A, 0x8F2E}, //16143 #CJK UNIFIED IDEOGRAPH + {0xDD8B, 0x8F2F}, //16144 #CJK UNIFIED IDEOGRAPH + {0xDD8C, 0x8F30}, //16145 #CJK UNIFIED IDEOGRAPH + {0xDD8D, 0x8F31}, //16146 #CJK UNIFIED IDEOGRAPH + {0xDD8E, 0x8F32}, //16147 #CJK UNIFIED IDEOGRAPH + {0xDD8F, 0x8F33}, //16148 #CJK UNIFIED IDEOGRAPH + {0xDD90, 0x8F34}, //16149 #CJK UNIFIED IDEOGRAPH + {0xDD91, 0x8F35}, //16150 #CJK UNIFIED IDEOGRAPH + {0xDD92, 0x8F36}, //16151 #CJK UNIFIED IDEOGRAPH + {0xDD93, 0x8F37}, //16152 #CJK UNIFIED IDEOGRAPH + {0xDD94, 0x8F38}, //16153 #CJK UNIFIED IDEOGRAPH + {0xDD95, 0x8F39}, //16154 #CJK UNIFIED IDEOGRAPH + {0xDD96, 0x8F3A}, //16155 #CJK UNIFIED IDEOGRAPH + {0xDD97, 0x8F3B}, //16156 #CJK UNIFIED IDEOGRAPH + {0xDD98, 0x8F3C}, //16157 #CJK UNIFIED IDEOGRAPH + {0xDD99, 0x8F3D}, //16158 #CJK UNIFIED IDEOGRAPH + {0xDD9A, 0x8F3E}, //16159 #CJK UNIFIED IDEOGRAPH + {0xDD9B, 0x8F3F}, //16160 #CJK UNIFIED IDEOGRAPH + {0xDD9C, 0x8F40}, //16161 #CJK UNIFIED IDEOGRAPH + {0xDD9D, 0x8F41}, //16162 #CJK UNIFIED IDEOGRAPH + {0xDD9E, 0x8F42}, //16163 #CJK UNIFIED IDEOGRAPH + {0xDD9F, 0x8F43}, //16164 #CJK UNIFIED IDEOGRAPH + {0xDDA0, 0x8F44}, //16165 #CJK UNIFIED IDEOGRAPH + {0xDDA1, 0x8368}, //16166 #CJK UNIFIED IDEOGRAPH + {0xDDA2, 0x831B}, //16167 #CJK UNIFIED IDEOGRAPH + {0xDDA3, 0x8369}, //16168 #CJK UNIFIED IDEOGRAPH + {0xDDA4, 0x836C}, //16169 #CJK UNIFIED IDEOGRAPH + {0xDDA5, 0x836A}, //16170 #CJK UNIFIED IDEOGRAPH + {0xDDA6, 0x836D}, //16171 #CJK UNIFIED IDEOGRAPH + {0xDDA7, 0x836E}, //16172 #CJK UNIFIED IDEOGRAPH + {0xDDA8, 0x83B0}, //16173 #CJK UNIFIED IDEOGRAPH + {0xDDA9, 0x8378}, //16174 #CJK UNIFIED IDEOGRAPH + {0xDDAA, 0x83B3}, //16175 #CJK UNIFIED IDEOGRAPH + {0xDDAB, 0x83B4}, //16176 #CJK UNIFIED IDEOGRAPH + {0xDDAC, 0x83A0}, //16177 #CJK UNIFIED IDEOGRAPH + {0xDDAD, 0x83AA}, //16178 #CJK UNIFIED IDEOGRAPH + {0xDDAE, 0x8393}, //16179 #CJK UNIFIED IDEOGRAPH + {0xDDAF, 0x839C}, //16180 #CJK UNIFIED IDEOGRAPH + {0xDDB0, 0x8385}, //16181 #CJK UNIFIED IDEOGRAPH + {0xDDB1, 0x837C}, //16182 #CJK UNIFIED IDEOGRAPH + {0xDDB2, 0x83B6}, //16183 #CJK UNIFIED IDEOGRAPH + {0xDDB3, 0x83A9}, //16184 #CJK UNIFIED IDEOGRAPH + {0xDDB4, 0x837D}, //16185 #CJK UNIFIED IDEOGRAPH + {0xDDB5, 0x83B8}, //16186 #CJK UNIFIED IDEOGRAPH + {0xDDB6, 0x837B}, //16187 #CJK UNIFIED IDEOGRAPH + {0xDDB7, 0x8398}, //16188 #CJK UNIFIED IDEOGRAPH + {0xDDB8, 0x839E}, //16189 #CJK UNIFIED IDEOGRAPH + {0xDDB9, 0x83A8}, //16190 #CJK UNIFIED IDEOGRAPH + {0xDDBA, 0x83BA}, //16191 #CJK UNIFIED IDEOGRAPH + {0xDDBB, 0x83BC}, //16192 #CJK UNIFIED IDEOGRAPH + {0xDDBC, 0x83C1}, //16193 #CJK UNIFIED IDEOGRAPH + {0xDDBD, 0x8401}, //16194 #CJK UNIFIED IDEOGRAPH + {0xDDBE, 0x83E5}, //16195 #CJK UNIFIED IDEOGRAPH + {0xDDBF, 0x83D8}, //16196 #CJK UNIFIED IDEOGRAPH + {0xDDC0, 0x5807}, //16197 #CJK UNIFIED IDEOGRAPH + {0xDDC1, 0x8418}, //16198 #CJK UNIFIED IDEOGRAPH + {0xDDC2, 0x840B}, //16199 #CJK UNIFIED IDEOGRAPH + {0xDDC3, 0x83DD}, //16200 #CJK UNIFIED IDEOGRAPH + {0xDDC4, 0x83FD}, //16201 #CJK UNIFIED IDEOGRAPH + {0xDDC5, 0x83D6}, //16202 #CJK UNIFIED IDEOGRAPH + {0xDDC6, 0x841C}, //16203 #CJK UNIFIED IDEOGRAPH + {0xDDC7, 0x8438}, //16204 #CJK UNIFIED IDEOGRAPH + {0xDDC8, 0x8411}, //16205 #CJK UNIFIED IDEOGRAPH + {0xDDC9, 0x8406}, //16206 #CJK UNIFIED IDEOGRAPH + {0xDDCA, 0x83D4}, //16207 #CJK UNIFIED IDEOGRAPH + {0xDDCB, 0x83DF}, //16208 #CJK UNIFIED IDEOGRAPH + {0xDDCC, 0x840F}, //16209 #CJK UNIFIED IDEOGRAPH + {0xDDCD, 0x8403}, //16210 #CJK UNIFIED IDEOGRAPH + {0xDDCE, 0x83F8}, //16211 #CJK UNIFIED IDEOGRAPH + {0xDDCF, 0x83F9}, //16212 #CJK UNIFIED IDEOGRAPH + {0xDDD0, 0x83EA}, //16213 #CJK UNIFIED IDEOGRAPH + {0xDDD1, 0x83C5}, //16214 #CJK UNIFIED IDEOGRAPH + {0xDDD2, 0x83C0}, //16215 #CJK UNIFIED IDEOGRAPH + {0xDDD3, 0x8426}, //16216 #CJK UNIFIED IDEOGRAPH + {0xDDD4, 0x83F0}, //16217 #CJK UNIFIED IDEOGRAPH + {0xDDD5, 0x83E1}, //16218 #CJK UNIFIED IDEOGRAPH + {0xDDD6, 0x845C}, //16219 #CJK UNIFIED IDEOGRAPH + {0xDDD7, 0x8451}, //16220 #CJK UNIFIED IDEOGRAPH + {0xDDD8, 0x845A}, //16221 #CJK UNIFIED IDEOGRAPH + {0xDDD9, 0x8459}, //16222 #CJK UNIFIED IDEOGRAPH + {0xDDDA, 0x8473}, //16223 #CJK UNIFIED IDEOGRAPH + {0xDDDB, 0x8487}, //16224 #CJK UNIFIED IDEOGRAPH + {0xDDDC, 0x8488}, //16225 #CJK UNIFIED IDEOGRAPH + {0xDDDD, 0x847A}, //16226 #CJK UNIFIED IDEOGRAPH + {0xDDDE, 0x8489}, //16227 #CJK UNIFIED IDEOGRAPH + {0xDDDF, 0x8478}, //16228 #CJK UNIFIED IDEOGRAPH + {0xDDE0, 0x843C}, //16229 #CJK UNIFIED IDEOGRAPH + {0xDDE1, 0x8446}, //16230 #CJK UNIFIED IDEOGRAPH + {0xDDE2, 0x8469}, //16231 #CJK UNIFIED IDEOGRAPH + {0xDDE3, 0x8476}, //16232 #CJK UNIFIED IDEOGRAPH + {0xDDE4, 0x848C}, //16233 #CJK UNIFIED IDEOGRAPH + {0xDDE5, 0x848E}, //16234 #CJK UNIFIED IDEOGRAPH + {0xDDE6, 0x8431}, //16235 #CJK UNIFIED IDEOGRAPH + {0xDDE7, 0x846D}, //16236 #CJK UNIFIED IDEOGRAPH + {0xDDE8, 0x84C1}, //16237 #CJK UNIFIED IDEOGRAPH + {0xDDE9, 0x84CD}, //16238 #CJK UNIFIED IDEOGRAPH + {0xDDEA, 0x84D0}, //16239 #CJK UNIFIED IDEOGRAPH + {0xDDEB, 0x84E6}, //16240 #CJK UNIFIED IDEOGRAPH + {0xDDEC, 0x84BD}, //16241 #CJK UNIFIED IDEOGRAPH + {0xDDED, 0x84D3}, //16242 #CJK UNIFIED IDEOGRAPH + {0xDDEE, 0x84CA}, //16243 #CJK UNIFIED IDEOGRAPH + {0xDDEF, 0x84BF}, //16244 #CJK UNIFIED IDEOGRAPH + {0xDDF0, 0x84BA}, //16245 #CJK UNIFIED IDEOGRAPH + {0xDDF1, 0x84E0}, //16246 #CJK UNIFIED IDEOGRAPH + {0xDDF2, 0x84A1}, //16247 #CJK UNIFIED IDEOGRAPH + {0xDDF3, 0x84B9}, //16248 #CJK UNIFIED IDEOGRAPH + {0xDDF4, 0x84B4}, //16249 #CJK UNIFIED IDEOGRAPH + {0xDDF5, 0x8497}, //16250 #CJK UNIFIED IDEOGRAPH + {0xDDF6, 0x84E5}, //16251 #CJK UNIFIED IDEOGRAPH + {0xDDF7, 0x84E3}, //16252 #CJK UNIFIED IDEOGRAPH + {0xDDF8, 0x850C}, //16253 #CJK UNIFIED IDEOGRAPH + {0xDDF9, 0x750D}, //16254 #CJK UNIFIED IDEOGRAPH + {0xDDFA, 0x8538}, //16255 #CJK UNIFIED IDEOGRAPH + {0xDDFB, 0x84F0}, //16256 #CJK UNIFIED IDEOGRAPH + {0xDDFC, 0x8539}, //16257 #CJK UNIFIED IDEOGRAPH + {0xDDFD, 0x851F}, //16258 #CJK UNIFIED IDEOGRAPH + {0xDDFE, 0x853A}, //16259 #CJK UNIFIED IDEOGRAPH + {0xDE40, 0x8F45}, //16260 #CJK UNIFIED IDEOGRAPH + {0xDE41, 0x8F46}, //16261 #CJK UNIFIED IDEOGRAPH + {0xDE42, 0x8F47}, //16262 #CJK UNIFIED IDEOGRAPH + {0xDE43, 0x8F48}, //16263 #CJK UNIFIED IDEOGRAPH + {0xDE44, 0x8F49}, //16264 #CJK UNIFIED IDEOGRAPH + {0xDE45, 0x8F4A}, //16265 #CJK UNIFIED IDEOGRAPH + {0xDE46, 0x8F4B}, //16266 #CJK UNIFIED IDEOGRAPH + {0xDE47, 0x8F4C}, //16267 #CJK UNIFIED IDEOGRAPH + {0xDE48, 0x8F4D}, //16268 #CJK UNIFIED IDEOGRAPH + {0xDE49, 0x8F4E}, //16269 #CJK UNIFIED IDEOGRAPH + {0xDE4A, 0x8F4F}, //16270 #CJK UNIFIED IDEOGRAPH + {0xDE4B, 0x8F50}, //16271 #CJK UNIFIED IDEOGRAPH + {0xDE4C, 0x8F51}, //16272 #CJK UNIFIED IDEOGRAPH + {0xDE4D, 0x8F52}, //16273 #CJK UNIFIED IDEOGRAPH + {0xDE4E, 0x8F53}, //16274 #CJK UNIFIED IDEOGRAPH + {0xDE4F, 0x8F54}, //16275 #CJK UNIFIED IDEOGRAPH + {0xDE50, 0x8F55}, //16276 #CJK UNIFIED IDEOGRAPH + {0xDE51, 0x8F56}, //16277 #CJK UNIFIED IDEOGRAPH + {0xDE52, 0x8F57}, //16278 #CJK UNIFIED IDEOGRAPH + {0xDE53, 0x8F58}, //16279 #CJK UNIFIED IDEOGRAPH + {0xDE54, 0x8F59}, //16280 #CJK UNIFIED IDEOGRAPH + {0xDE55, 0x8F5A}, //16281 #CJK UNIFIED IDEOGRAPH + {0xDE56, 0x8F5B}, //16282 #CJK UNIFIED IDEOGRAPH + {0xDE57, 0x8F5C}, //16283 #CJK UNIFIED IDEOGRAPH + {0xDE58, 0x8F5D}, //16284 #CJK UNIFIED IDEOGRAPH + {0xDE59, 0x8F5E}, //16285 #CJK UNIFIED IDEOGRAPH + {0xDE5A, 0x8F5F}, //16286 #CJK UNIFIED IDEOGRAPH + {0xDE5B, 0x8F60}, //16287 #CJK UNIFIED IDEOGRAPH + {0xDE5C, 0x8F61}, //16288 #CJK UNIFIED IDEOGRAPH + {0xDE5D, 0x8F62}, //16289 #CJK UNIFIED IDEOGRAPH + {0xDE5E, 0x8F63}, //16290 #CJK UNIFIED IDEOGRAPH + {0xDE5F, 0x8F64}, //16291 #CJK UNIFIED IDEOGRAPH + {0xDE60, 0x8F65}, //16292 #CJK UNIFIED IDEOGRAPH + {0xDE61, 0x8F6A}, //16293 #CJK UNIFIED IDEOGRAPH + {0xDE62, 0x8F80}, //16294 #CJK UNIFIED IDEOGRAPH + {0xDE63, 0x8F8C}, //16295 #CJK UNIFIED IDEOGRAPH + {0xDE64, 0x8F92}, //16296 #CJK UNIFIED IDEOGRAPH + {0xDE65, 0x8F9D}, //16297 #CJK UNIFIED IDEOGRAPH + {0xDE66, 0x8FA0}, //16298 #CJK UNIFIED IDEOGRAPH + {0xDE67, 0x8FA1}, //16299 #CJK UNIFIED IDEOGRAPH + {0xDE68, 0x8FA2}, //16300 #CJK UNIFIED IDEOGRAPH + {0xDE69, 0x8FA4}, //16301 #CJK UNIFIED IDEOGRAPH + {0xDE6A, 0x8FA5}, //16302 #CJK UNIFIED IDEOGRAPH + {0xDE6B, 0x8FA6}, //16303 #CJK UNIFIED IDEOGRAPH + {0xDE6C, 0x8FA7}, //16304 #CJK UNIFIED IDEOGRAPH + {0xDE6D, 0x8FAA}, //16305 #CJK UNIFIED IDEOGRAPH + {0xDE6E, 0x8FAC}, //16306 #CJK UNIFIED IDEOGRAPH + {0xDE6F, 0x8FAD}, //16307 #CJK UNIFIED IDEOGRAPH + {0xDE70, 0x8FAE}, //16308 #CJK UNIFIED IDEOGRAPH + {0xDE71, 0x8FAF}, //16309 #CJK UNIFIED IDEOGRAPH + {0xDE72, 0x8FB2}, //16310 #CJK UNIFIED IDEOGRAPH + {0xDE73, 0x8FB3}, //16311 #CJK UNIFIED IDEOGRAPH + {0xDE74, 0x8FB4}, //16312 #CJK UNIFIED IDEOGRAPH + {0xDE75, 0x8FB5}, //16313 #CJK UNIFIED IDEOGRAPH + {0xDE76, 0x8FB7}, //16314 #CJK UNIFIED IDEOGRAPH + {0xDE77, 0x8FB8}, //16315 #CJK UNIFIED IDEOGRAPH + {0xDE78, 0x8FBA}, //16316 #CJK UNIFIED IDEOGRAPH + {0xDE79, 0x8FBB}, //16317 #CJK UNIFIED IDEOGRAPH + {0xDE7A, 0x8FBC}, //16318 #CJK UNIFIED IDEOGRAPH + {0xDE7B, 0x8FBF}, //16319 #CJK UNIFIED IDEOGRAPH + {0xDE7C, 0x8FC0}, //16320 #CJK UNIFIED IDEOGRAPH + {0xDE7D, 0x8FC3}, //16321 #CJK UNIFIED IDEOGRAPH + {0xDE7E, 0x8FC6}, //16322 #CJK UNIFIED IDEOGRAPH + {0xDE80, 0x8FC9}, //16323 #CJK UNIFIED IDEOGRAPH + {0xDE81, 0x8FCA}, //16324 #CJK UNIFIED IDEOGRAPH + {0xDE82, 0x8FCB}, //16325 #CJK UNIFIED IDEOGRAPH + {0xDE83, 0x8FCC}, //16326 #CJK UNIFIED IDEOGRAPH + {0xDE84, 0x8FCD}, //16327 #CJK UNIFIED IDEOGRAPH + {0xDE85, 0x8FCF}, //16328 #CJK UNIFIED IDEOGRAPH + {0xDE86, 0x8FD2}, //16329 #CJK UNIFIED IDEOGRAPH + {0xDE87, 0x8FD6}, //16330 #CJK UNIFIED IDEOGRAPH + {0xDE88, 0x8FD7}, //16331 #CJK UNIFIED IDEOGRAPH + {0xDE89, 0x8FDA}, //16332 #CJK UNIFIED IDEOGRAPH + {0xDE8A, 0x8FE0}, //16333 #CJK UNIFIED IDEOGRAPH + {0xDE8B, 0x8FE1}, //16334 #CJK UNIFIED IDEOGRAPH + {0xDE8C, 0x8FE3}, //16335 #CJK UNIFIED IDEOGRAPH + {0xDE8D, 0x8FE7}, //16336 #CJK UNIFIED IDEOGRAPH + {0xDE8E, 0x8FEC}, //16337 #CJK UNIFIED IDEOGRAPH + {0xDE8F, 0x8FEF}, //16338 #CJK UNIFIED IDEOGRAPH + {0xDE90, 0x8FF1}, //16339 #CJK UNIFIED IDEOGRAPH + {0xDE91, 0x8FF2}, //16340 #CJK UNIFIED IDEOGRAPH + {0xDE92, 0x8FF4}, //16341 #CJK UNIFIED IDEOGRAPH + {0xDE93, 0x8FF5}, //16342 #CJK UNIFIED IDEOGRAPH + {0xDE94, 0x8FF6}, //16343 #CJK UNIFIED IDEOGRAPH + {0xDE95, 0x8FFA}, //16344 #CJK UNIFIED IDEOGRAPH + {0xDE96, 0x8FFB}, //16345 #CJK UNIFIED IDEOGRAPH + {0xDE97, 0x8FFC}, //16346 #CJK UNIFIED IDEOGRAPH + {0xDE98, 0x8FFE}, //16347 #CJK UNIFIED IDEOGRAPH + {0xDE99, 0x8FFF}, //16348 #CJK UNIFIED IDEOGRAPH + {0xDE9A, 0x9007}, //16349 #CJK UNIFIED IDEOGRAPH + {0xDE9B, 0x9008}, //16350 #CJK UNIFIED IDEOGRAPH + {0xDE9C, 0x900C}, //16351 #CJK UNIFIED IDEOGRAPH + {0xDE9D, 0x900E}, //16352 #CJK UNIFIED IDEOGRAPH + {0xDE9E, 0x9013}, //16353 #CJK UNIFIED IDEOGRAPH + {0xDE9F, 0x9015}, //16354 #CJK UNIFIED IDEOGRAPH + {0xDEA0, 0x9018}, //16355 #CJK UNIFIED IDEOGRAPH + {0xDEA1, 0x8556}, //16356 #CJK UNIFIED IDEOGRAPH + {0xDEA2, 0x853B}, //16357 #CJK UNIFIED IDEOGRAPH + {0xDEA3, 0x84FF}, //16358 #CJK UNIFIED IDEOGRAPH + {0xDEA4, 0x84FC}, //16359 #CJK UNIFIED IDEOGRAPH + {0xDEA5, 0x8559}, //16360 #CJK UNIFIED IDEOGRAPH + {0xDEA6, 0x8548}, //16361 #CJK UNIFIED IDEOGRAPH + {0xDEA7, 0x8568}, //16362 #CJK UNIFIED IDEOGRAPH + {0xDEA8, 0x8564}, //16363 #CJK UNIFIED IDEOGRAPH + {0xDEA9, 0x855E}, //16364 #CJK UNIFIED IDEOGRAPH + {0xDEAA, 0x857A}, //16365 #CJK UNIFIED IDEOGRAPH + {0xDEAB, 0x77A2}, //16366 #CJK UNIFIED IDEOGRAPH + {0xDEAC, 0x8543}, //16367 #CJK UNIFIED IDEOGRAPH + {0xDEAD, 0x8572}, //16368 #CJK UNIFIED IDEOGRAPH + {0xDEAE, 0x857B}, //16369 #CJK UNIFIED IDEOGRAPH + {0xDEAF, 0x85A4}, //16370 #CJK UNIFIED IDEOGRAPH + {0xDEB0, 0x85A8}, //16371 #CJK UNIFIED IDEOGRAPH + {0xDEB1, 0x8587}, //16372 #CJK UNIFIED IDEOGRAPH + {0xDEB2, 0x858F}, //16373 #CJK UNIFIED IDEOGRAPH + {0xDEB3, 0x8579}, //16374 #CJK UNIFIED IDEOGRAPH + {0xDEB4, 0x85AE}, //16375 #CJK UNIFIED IDEOGRAPH + {0xDEB5, 0x859C}, //16376 #CJK UNIFIED IDEOGRAPH + {0xDEB6, 0x8585}, //16377 #CJK UNIFIED IDEOGRAPH + {0xDEB7, 0x85B9}, //16378 #CJK UNIFIED IDEOGRAPH + {0xDEB8, 0x85B7}, //16379 #CJK UNIFIED IDEOGRAPH + {0xDEB9, 0x85B0}, //16380 #CJK UNIFIED IDEOGRAPH + {0xDEBA, 0x85D3}, //16381 #CJK UNIFIED IDEOGRAPH + {0xDEBB, 0x85C1}, //16382 #CJK UNIFIED IDEOGRAPH + {0xDEBC, 0x85DC}, //16383 #CJK UNIFIED IDEOGRAPH + {0xDEBD, 0x85FF}, //16384 #CJK UNIFIED IDEOGRAPH + {0xDEBE, 0x8627}, //16385 #CJK UNIFIED IDEOGRAPH + {0xDEBF, 0x8605}, //16386 #CJK UNIFIED IDEOGRAPH + {0xDEC0, 0x8629}, //16387 #CJK UNIFIED IDEOGRAPH + {0xDEC1, 0x8616}, //16388 #CJK UNIFIED IDEOGRAPH + {0xDEC2, 0x863C}, //16389 #CJK UNIFIED IDEOGRAPH + {0xDEC3, 0x5EFE}, //16390 #CJK UNIFIED IDEOGRAPH + {0xDEC4, 0x5F08}, //16391 #CJK UNIFIED IDEOGRAPH + {0xDEC5, 0x593C}, //16392 #CJK UNIFIED IDEOGRAPH + {0xDEC6, 0x5941}, //16393 #CJK UNIFIED IDEOGRAPH + {0xDEC7, 0x8037}, //16394 #CJK UNIFIED IDEOGRAPH + {0xDEC8, 0x5955}, //16395 #CJK UNIFIED IDEOGRAPH + {0xDEC9, 0x595A}, //16396 #CJK UNIFIED IDEOGRAPH + {0xDECA, 0x5958}, //16397 #CJK UNIFIED IDEOGRAPH + {0xDECB, 0x530F}, //16398 #CJK UNIFIED IDEOGRAPH + {0xDECC, 0x5C22}, //16399 #CJK UNIFIED IDEOGRAPH + {0xDECD, 0x5C25}, //16400 #CJK UNIFIED IDEOGRAPH + {0xDECE, 0x5C2C}, //16401 #CJK UNIFIED IDEOGRAPH + {0xDECF, 0x5C34}, //16402 #CJK UNIFIED IDEOGRAPH + {0xDED0, 0x624C}, //16403 #CJK UNIFIED IDEOGRAPH + {0xDED1, 0x626A}, //16404 #CJK UNIFIED IDEOGRAPH + {0xDED2, 0x629F}, //16405 #CJK UNIFIED IDEOGRAPH + {0xDED3, 0x62BB}, //16406 #CJK UNIFIED IDEOGRAPH + {0xDED4, 0x62CA}, //16407 #CJK UNIFIED IDEOGRAPH + {0xDED5, 0x62DA}, //16408 #CJK UNIFIED IDEOGRAPH + {0xDED6, 0x62D7}, //16409 #CJK UNIFIED IDEOGRAPH + {0xDED7, 0x62EE}, //16410 #CJK UNIFIED IDEOGRAPH + {0xDED8, 0x6322}, //16411 #CJK UNIFIED IDEOGRAPH + {0xDED9, 0x62F6}, //16412 #CJK UNIFIED IDEOGRAPH + {0xDEDA, 0x6339}, //16413 #CJK UNIFIED IDEOGRAPH + {0xDEDB, 0x634B}, //16414 #CJK UNIFIED IDEOGRAPH + {0xDEDC, 0x6343}, //16415 #CJK UNIFIED IDEOGRAPH + {0xDEDD, 0x63AD}, //16416 #CJK UNIFIED IDEOGRAPH + {0xDEDE, 0x63F6}, //16417 #CJK UNIFIED IDEOGRAPH + {0xDEDF, 0x6371}, //16418 #CJK UNIFIED IDEOGRAPH + {0xDEE0, 0x637A}, //16419 #CJK UNIFIED IDEOGRAPH + {0xDEE1, 0x638E}, //16420 #CJK UNIFIED IDEOGRAPH + {0xDEE2, 0x63B4}, //16421 #CJK UNIFIED IDEOGRAPH + {0xDEE3, 0x636D}, //16422 #CJK UNIFIED IDEOGRAPH + {0xDEE4, 0x63AC}, //16423 #CJK UNIFIED IDEOGRAPH + {0xDEE5, 0x638A}, //16424 #CJK UNIFIED IDEOGRAPH + {0xDEE6, 0x6369}, //16425 #CJK UNIFIED IDEOGRAPH + {0xDEE7, 0x63AE}, //16426 #CJK UNIFIED IDEOGRAPH + {0xDEE8, 0x63BC}, //16427 #CJK UNIFIED IDEOGRAPH + {0xDEE9, 0x63F2}, //16428 #CJK UNIFIED IDEOGRAPH + {0xDEEA, 0x63F8}, //16429 #CJK UNIFIED IDEOGRAPH + {0xDEEB, 0x63E0}, //16430 #CJK UNIFIED IDEOGRAPH + {0xDEEC, 0x63FF}, //16431 #CJK UNIFIED IDEOGRAPH + {0xDEED, 0x63C4}, //16432 #CJK UNIFIED IDEOGRAPH + {0xDEEE, 0x63DE}, //16433 #CJK UNIFIED IDEOGRAPH + {0xDEEF, 0x63CE}, //16434 #CJK UNIFIED IDEOGRAPH + {0xDEF0, 0x6452}, //16435 #CJK UNIFIED IDEOGRAPH + {0xDEF1, 0x63C6}, //16436 #CJK UNIFIED IDEOGRAPH + {0xDEF2, 0x63BE}, //16437 #CJK UNIFIED IDEOGRAPH + {0xDEF3, 0x6445}, //16438 #CJK UNIFIED IDEOGRAPH + {0xDEF4, 0x6441}, //16439 #CJK UNIFIED IDEOGRAPH + {0xDEF5, 0x640B}, //16440 #CJK UNIFIED IDEOGRAPH + {0xDEF6, 0x641B}, //16441 #CJK UNIFIED IDEOGRAPH + {0xDEF7, 0x6420}, //16442 #CJK UNIFIED IDEOGRAPH + {0xDEF8, 0x640C}, //16443 #CJK UNIFIED IDEOGRAPH + {0xDEF9, 0x6426}, //16444 #CJK UNIFIED IDEOGRAPH + {0xDEFA, 0x6421}, //16445 #CJK UNIFIED IDEOGRAPH + {0xDEFB, 0x645E}, //16446 #CJK UNIFIED IDEOGRAPH + {0xDEFC, 0x6484}, //16447 #CJK UNIFIED IDEOGRAPH + {0xDEFD, 0x646D}, //16448 #CJK UNIFIED IDEOGRAPH + {0xDEFE, 0x6496}, //16449 #CJK UNIFIED IDEOGRAPH + {0xDF40, 0x9019}, //16450 #CJK UNIFIED IDEOGRAPH + {0xDF41, 0x901C}, //16451 #CJK UNIFIED IDEOGRAPH + {0xDF42, 0x9023}, //16452 #CJK UNIFIED IDEOGRAPH + {0xDF43, 0x9024}, //16453 #CJK UNIFIED IDEOGRAPH + {0xDF44, 0x9025}, //16454 #CJK UNIFIED IDEOGRAPH + {0xDF45, 0x9027}, //16455 #CJK UNIFIED IDEOGRAPH + {0xDF46, 0x9028}, //16456 #CJK UNIFIED IDEOGRAPH + {0xDF47, 0x9029}, //16457 #CJK UNIFIED IDEOGRAPH + {0xDF48, 0x902A}, //16458 #CJK UNIFIED IDEOGRAPH + {0xDF49, 0x902B}, //16459 #CJK UNIFIED IDEOGRAPH + {0xDF4A, 0x902C}, //16460 #CJK UNIFIED IDEOGRAPH + {0xDF4B, 0x9030}, //16461 #CJK UNIFIED IDEOGRAPH + {0xDF4C, 0x9031}, //16462 #CJK UNIFIED IDEOGRAPH + {0xDF4D, 0x9032}, //16463 #CJK UNIFIED IDEOGRAPH + {0xDF4E, 0x9033}, //16464 #CJK UNIFIED IDEOGRAPH + {0xDF4F, 0x9034}, //16465 #CJK UNIFIED IDEOGRAPH + {0xDF50, 0x9037}, //16466 #CJK UNIFIED IDEOGRAPH + {0xDF51, 0x9039}, //16467 #CJK UNIFIED IDEOGRAPH + {0xDF52, 0x903A}, //16468 #CJK UNIFIED IDEOGRAPH + {0xDF53, 0x903D}, //16469 #CJK UNIFIED IDEOGRAPH + {0xDF54, 0x903F}, //16470 #CJK UNIFIED IDEOGRAPH + {0xDF55, 0x9040}, //16471 #CJK UNIFIED IDEOGRAPH + {0xDF56, 0x9043}, //16472 #CJK UNIFIED IDEOGRAPH + {0xDF57, 0x9045}, //16473 #CJK UNIFIED IDEOGRAPH + {0xDF58, 0x9046}, //16474 #CJK UNIFIED IDEOGRAPH + {0xDF59, 0x9048}, //16475 #CJK UNIFIED IDEOGRAPH + {0xDF5A, 0x9049}, //16476 #CJK UNIFIED IDEOGRAPH + {0xDF5B, 0x904A}, //16477 #CJK UNIFIED IDEOGRAPH + {0xDF5C, 0x904B}, //16478 #CJK UNIFIED IDEOGRAPH + {0xDF5D, 0x904C}, //16479 #CJK UNIFIED IDEOGRAPH + {0xDF5E, 0x904E}, //16480 #CJK UNIFIED IDEOGRAPH + {0xDF5F, 0x9054}, //16481 #CJK UNIFIED IDEOGRAPH + {0xDF60, 0x9055}, //16482 #CJK UNIFIED IDEOGRAPH + {0xDF61, 0x9056}, //16483 #CJK UNIFIED IDEOGRAPH + {0xDF62, 0x9059}, //16484 #CJK UNIFIED IDEOGRAPH + {0xDF63, 0x905A}, //16485 #CJK UNIFIED IDEOGRAPH + {0xDF64, 0x905C}, //16486 #CJK UNIFIED IDEOGRAPH + {0xDF65, 0x905D}, //16487 #CJK UNIFIED IDEOGRAPH + {0xDF66, 0x905E}, //16488 #CJK UNIFIED IDEOGRAPH + {0xDF67, 0x905F}, //16489 #CJK UNIFIED IDEOGRAPH + {0xDF68, 0x9060}, //16490 #CJK UNIFIED IDEOGRAPH + {0xDF69, 0x9061}, //16491 #CJK UNIFIED IDEOGRAPH + {0xDF6A, 0x9064}, //16492 #CJK UNIFIED IDEOGRAPH + {0xDF6B, 0x9066}, //16493 #CJK UNIFIED IDEOGRAPH + {0xDF6C, 0x9067}, //16494 #CJK UNIFIED IDEOGRAPH + {0xDF6D, 0x9069}, //16495 #CJK UNIFIED IDEOGRAPH + {0xDF6E, 0x906A}, //16496 #CJK UNIFIED IDEOGRAPH + {0xDF6F, 0x906B}, //16497 #CJK UNIFIED IDEOGRAPH + {0xDF70, 0x906C}, //16498 #CJK UNIFIED IDEOGRAPH + {0xDF71, 0x906F}, //16499 #CJK UNIFIED IDEOGRAPH + {0xDF72, 0x9070}, //16500 #CJK UNIFIED IDEOGRAPH + {0xDF73, 0x9071}, //16501 #CJK UNIFIED IDEOGRAPH + {0xDF74, 0x9072}, //16502 #CJK UNIFIED IDEOGRAPH + {0xDF75, 0x9073}, //16503 #CJK UNIFIED IDEOGRAPH + {0xDF76, 0x9076}, //16504 #CJK UNIFIED IDEOGRAPH + {0xDF77, 0x9077}, //16505 #CJK UNIFIED IDEOGRAPH + {0xDF78, 0x9078}, //16506 #CJK UNIFIED IDEOGRAPH + {0xDF79, 0x9079}, //16507 #CJK UNIFIED IDEOGRAPH + {0xDF7A, 0x907A}, //16508 #CJK UNIFIED IDEOGRAPH + {0xDF7B, 0x907B}, //16509 #CJK UNIFIED IDEOGRAPH + {0xDF7C, 0x907C}, //16510 #CJK UNIFIED IDEOGRAPH + {0xDF7D, 0x907E}, //16511 #CJK UNIFIED IDEOGRAPH + {0xDF7E, 0x9081}, //16512 #CJK UNIFIED IDEOGRAPH + {0xDF80, 0x9084}, //16513 #CJK UNIFIED IDEOGRAPH + {0xDF81, 0x9085}, //16514 #CJK UNIFIED IDEOGRAPH + {0xDF82, 0x9086}, //16515 #CJK UNIFIED IDEOGRAPH + {0xDF83, 0x9087}, //16516 #CJK UNIFIED IDEOGRAPH + {0xDF84, 0x9089}, //16517 #CJK UNIFIED IDEOGRAPH + {0xDF85, 0x908A}, //16518 #CJK UNIFIED IDEOGRAPH + {0xDF86, 0x908C}, //16519 #CJK UNIFIED IDEOGRAPH + {0xDF87, 0x908D}, //16520 #CJK UNIFIED IDEOGRAPH + {0xDF88, 0x908E}, //16521 #CJK UNIFIED IDEOGRAPH + {0xDF89, 0x908F}, //16522 #CJK UNIFIED IDEOGRAPH + {0xDF8A, 0x9090}, //16523 #CJK UNIFIED IDEOGRAPH + {0xDF8B, 0x9092}, //16524 #CJK UNIFIED IDEOGRAPH + {0xDF8C, 0x9094}, //16525 #CJK UNIFIED IDEOGRAPH + {0xDF8D, 0x9096}, //16526 #CJK UNIFIED IDEOGRAPH + {0xDF8E, 0x9098}, //16527 #CJK UNIFIED IDEOGRAPH + {0xDF8F, 0x909A}, //16528 #CJK UNIFIED IDEOGRAPH + {0xDF90, 0x909C}, //16529 #CJK UNIFIED IDEOGRAPH + {0xDF91, 0x909E}, //16530 #CJK UNIFIED IDEOGRAPH + {0xDF92, 0x909F}, //16531 #CJK UNIFIED IDEOGRAPH + {0xDF93, 0x90A0}, //16532 #CJK UNIFIED IDEOGRAPH + {0xDF94, 0x90A4}, //16533 #CJK UNIFIED IDEOGRAPH + {0xDF95, 0x90A5}, //16534 #CJK UNIFIED IDEOGRAPH + {0xDF96, 0x90A7}, //16535 #CJK UNIFIED IDEOGRAPH + {0xDF97, 0x90A8}, //16536 #CJK UNIFIED IDEOGRAPH + {0xDF98, 0x90A9}, //16537 #CJK UNIFIED IDEOGRAPH + {0xDF99, 0x90AB}, //16538 #CJK UNIFIED IDEOGRAPH + {0xDF9A, 0x90AD}, //16539 #CJK UNIFIED IDEOGRAPH + {0xDF9B, 0x90B2}, //16540 #CJK UNIFIED IDEOGRAPH + {0xDF9C, 0x90B7}, //16541 #CJK UNIFIED IDEOGRAPH + {0xDF9D, 0x90BC}, //16542 #CJK UNIFIED IDEOGRAPH + {0xDF9E, 0x90BD}, //16543 #CJK UNIFIED IDEOGRAPH + {0xDF9F, 0x90BF}, //16544 #CJK UNIFIED IDEOGRAPH + {0xDFA0, 0x90C0}, //16545 #CJK UNIFIED IDEOGRAPH + {0xDFA1, 0x647A}, //16546 #CJK UNIFIED IDEOGRAPH + {0xDFA2, 0x64B7}, //16547 #CJK UNIFIED IDEOGRAPH + {0xDFA3, 0x64B8}, //16548 #CJK UNIFIED IDEOGRAPH + {0xDFA4, 0x6499}, //16549 #CJK UNIFIED IDEOGRAPH + {0xDFA5, 0x64BA}, //16550 #CJK UNIFIED IDEOGRAPH + {0xDFA6, 0x64C0}, //16551 #CJK UNIFIED IDEOGRAPH + {0xDFA7, 0x64D0}, //16552 #CJK UNIFIED IDEOGRAPH + {0xDFA8, 0x64D7}, //16553 #CJK UNIFIED IDEOGRAPH + {0xDFA9, 0x64E4}, //16554 #CJK UNIFIED IDEOGRAPH + {0xDFAA, 0x64E2}, //16555 #CJK UNIFIED IDEOGRAPH + {0xDFAB, 0x6509}, //16556 #CJK UNIFIED IDEOGRAPH + {0xDFAC, 0x6525}, //16557 #CJK UNIFIED IDEOGRAPH + {0xDFAD, 0x652E}, //16558 #CJK UNIFIED IDEOGRAPH + {0xDFAE, 0x5F0B}, //16559 #CJK UNIFIED IDEOGRAPH + {0xDFAF, 0x5FD2}, //16560 #CJK UNIFIED IDEOGRAPH + {0xDFB0, 0x7519}, //16561 #CJK UNIFIED IDEOGRAPH + {0xDFB1, 0x5F11}, //16562 #CJK UNIFIED IDEOGRAPH + {0xDFB2, 0x535F}, //16563 #CJK UNIFIED IDEOGRAPH + {0xDFB3, 0x53F1}, //16564 #CJK UNIFIED IDEOGRAPH + {0xDFB4, 0x53FD}, //16565 #CJK UNIFIED IDEOGRAPH + {0xDFB5, 0x53E9}, //16566 #CJK UNIFIED IDEOGRAPH + {0xDFB6, 0x53E8}, //16567 #CJK UNIFIED IDEOGRAPH + {0xDFB7, 0x53FB}, //16568 #CJK UNIFIED IDEOGRAPH + {0xDFB8, 0x5412}, //16569 #CJK UNIFIED IDEOGRAPH + {0xDFB9, 0x5416}, //16570 #CJK UNIFIED IDEOGRAPH + {0xDFBA, 0x5406}, //16571 #CJK UNIFIED IDEOGRAPH + {0xDFBB, 0x544B}, //16572 #CJK UNIFIED IDEOGRAPH + {0xDFBC, 0x5452}, //16573 #CJK UNIFIED IDEOGRAPH + {0xDFBD, 0x5453}, //16574 #CJK UNIFIED IDEOGRAPH + {0xDFBE, 0x5454}, //16575 #CJK UNIFIED IDEOGRAPH + {0xDFBF, 0x5456}, //16576 #CJK UNIFIED IDEOGRAPH + {0xDFC0, 0x5443}, //16577 #CJK UNIFIED IDEOGRAPH + {0xDFC1, 0x5421}, //16578 #CJK UNIFIED IDEOGRAPH + {0xDFC2, 0x5457}, //16579 #CJK UNIFIED IDEOGRAPH + {0xDFC3, 0x5459}, //16580 #CJK UNIFIED IDEOGRAPH + {0xDFC4, 0x5423}, //16581 #CJK UNIFIED IDEOGRAPH + {0xDFC5, 0x5432}, //16582 #CJK UNIFIED IDEOGRAPH + {0xDFC6, 0x5482}, //16583 #CJK UNIFIED IDEOGRAPH + {0xDFC7, 0x5494}, //16584 #CJK UNIFIED IDEOGRAPH + {0xDFC8, 0x5477}, //16585 #CJK UNIFIED IDEOGRAPH + {0xDFC9, 0x5471}, //16586 #CJK UNIFIED IDEOGRAPH + {0xDFCA, 0x5464}, //16587 #CJK UNIFIED IDEOGRAPH + {0xDFCB, 0x549A}, //16588 #CJK UNIFIED IDEOGRAPH + {0xDFCC, 0x549B}, //16589 #CJK UNIFIED IDEOGRAPH + {0xDFCD, 0x5484}, //16590 #CJK UNIFIED IDEOGRAPH + {0xDFCE, 0x5476}, //16591 #CJK UNIFIED IDEOGRAPH + {0xDFCF, 0x5466}, //16592 #CJK UNIFIED IDEOGRAPH + {0xDFD0, 0x549D}, //16593 #CJK UNIFIED IDEOGRAPH + {0xDFD1, 0x54D0}, //16594 #CJK UNIFIED IDEOGRAPH + {0xDFD2, 0x54AD}, //16595 #CJK UNIFIED IDEOGRAPH + {0xDFD3, 0x54C2}, //16596 #CJK UNIFIED IDEOGRAPH + {0xDFD4, 0x54B4}, //16597 #CJK UNIFIED IDEOGRAPH + {0xDFD5, 0x54D2}, //16598 #CJK UNIFIED IDEOGRAPH + {0xDFD6, 0x54A7}, //16599 #CJK UNIFIED IDEOGRAPH + {0xDFD7, 0x54A6}, //16600 #CJK UNIFIED IDEOGRAPH + {0xDFD8, 0x54D3}, //16601 #CJK UNIFIED IDEOGRAPH + {0xDFD9, 0x54D4}, //16602 #CJK UNIFIED IDEOGRAPH + {0xDFDA, 0x5472}, //16603 #CJK UNIFIED IDEOGRAPH + {0xDFDB, 0x54A3}, //16604 #CJK UNIFIED IDEOGRAPH + {0xDFDC, 0x54D5}, //16605 #CJK UNIFIED IDEOGRAPH + {0xDFDD, 0x54BB}, //16606 #CJK UNIFIED IDEOGRAPH + {0xDFDE, 0x54BF}, //16607 #CJK UNIFIED IDEOGRAPH + {0xDFDF, 0x54CC}, //16608 #CJK UNIFIED IDEOGRAPH + {0xDFE0, 0x54D9}, //16609 #CJK UNIFIED IDEOGRAPH + {0xDFE1, 0x54DA}, //16610 #CJK UNIFIED IDEOGRAPH + {0xDFE2, 0x54DC}, //16611 #CJK UNIFIED IDEOGRAPH + {0xDFE3, 0x54A9}, //16612 #CJK UNIFIED IDEOGRAPH + {0xDFE4, 0x54AA}, //16613 #CJK UNIFIED IDEOGRAPH + {0xDFE5, 0x54A4}, //16614 #CJK UNIFIED IDEOGRAPH + {0xDFE6, 0x54DD}, //16615 #CJK UNIFIED IDEOGRAPH + {0xDFE7, 0x54CF}, //16616 #CJK UNIFIED IDEOGRAPH + {0xDFE8, 0x54DE}, //16617 #CJK UNIFIED IDEOGRAPH + {0xDFE9, 0x551B}, //16618 #CJK UNIFIED IDEOGRAPH + {0xDFEA, 0x54E7}, //16619 #CJK UNIFIED IDEOGRAPH + {0xDFEB, 0x5520}, //16620 #CJK UNIFIED IDEOGRAPH + {0xDFEC, 0x54FD}, //16621 #CJK UNIFIED IDEOGRAPH + {0xDFED, 0x5514}, //16622 #CJK UNIFIED IDEOGRAPH + {0xDFEE, 0x54F3}, //16623 #CJK UNIFIED IDEOGRAPH + {0xDFEF, 0x5522}, //16624 #CJK UNIFIED IDEOGRAPH + {0xDFF0, 0x5523}, //16625 #CJK UNIFIED IDEOGRAPH + {0xDFF1, 0x550F}, //16626 #CJK UNIFIED IDEOGRAPH + {0xDFF2, 0x5511}, //16627 #CJK UNIFIED IDEOGRAPH + {0xDFF3, 0x5527}, //16628 #CJK UNIFIED IDEOGRAPH + {0xDFF4, 0x552A}, //16629 #CJK UNIFIED IDEOGRAPH + {0xDFF5, 0x5567}, //16630 #CJK UNIFIED IDEOGRAPH + {0xDFF6, 0x558F}, //16631 #CJK UNIFIED IDEOGRAPH + {0xDFF7, 0x55B5}, //16632 #CJK UNIFIED IDEOGRAPH + {0xDFF8, 0x5549}, //16633 #CJK UNIFIED IDEOGRAPH + {0xDFF9, 0x556D}, //16634 #CJK UNIFIED IDEOGRAPH + {0xDFFA, 0x5541}, //16635 #CJK UNIFIED IDEOGRAPH + {0xDFFB, 0x5555}, //16636 #CJK UNIFIED IDEOGRAPH + {0xDFFC, 0x553F}, //16637 #CJK UNIFIED IDEOGRAPH + {0xDFFD, 0x5550}, //16638 #CJK UNIFIED IDEOGRAPH + {0xDFFE, 0x553C}, //16639 #CJK UNIFIED IDEOGRAPH + {0xE040, 0x90C2}, //16640 #CJK UNIFIED IDEOGRAPH + {0xE041, 0x90C3}, //16641 #CJK UNIFIED IDEOGRAPH + {0xE042, 0x90C6}, //16642 #CJK UNIFIED IDEOGRAPH + {0xE043, 0x90C8}, //16643 #CJK UNIFIED IDEOGRAPH + {0xE044, 0x90C9}, //16644 #CJK UNIFIED IDEOGRAPH + {0xE045, 0x90CB}, //16645 #CJK UNIFIED IDEOGRAPH + {0xE046, 0x90CC}, //16646 #CJK UNIFIED IDEOGRAPH + {0xE047, 0x90CD}, //16647 #CJK UNIFIED IDEOGRAPH + {0xE048, 0x90D2}, //16648 #CJK UNIFIED IDEOGRAPH + {0xE049, 0x90D4}, //16649 #CJK UNIFIED IDEOGRAPH + {0xE04A, 0x90D5}, //16650 #CJK UNIFIED IDEOGRAPH + {0xE04B, 0x90D6}, //16651 #CJK UNIFIED IDEOGRAPH + {0xE04C, 0x90D8}, //16652 #CJK UNIFIED IDEOGRAPH + {0xE04D, 0x90D9}, //16653 #CJK UNIFIED IDEOGRAPH + {0xE04E, 0x90DA}, //16654 #CJK UNIFIED IDEOGRAPH + {0xE04F, 0x90DE}, //16655 #CJK UNIFIED IDEOGRAPH + {0xE050, 0x90DF}, //16656 #CJK UNIFIED IDEOGRAPH + {0xE051, 0x90E0}, //16657 #CJK UNIFIED IDEOGRAPH + {0xE052, 0x90E3}, //16658 #CJK UNIFIED IDEOGRAPH + {0xE053, 0x90E4}, //16659 #CJK UNIFIED IDEOGRAPH + {0xE054, 0x90E5}, //16660 #CJK UNIFIED IDEOGRAPH + {0xE055, 0x90E9}, //16661 #CJK UNIFIED IDEOGRAPH + {0xE056, 0x90EA}, //16662 #CJK UNIFIED IDEOGRAPH + {0xE057, 0x90EC}, //16663 #CJK UNIFIED IDEOGRAPH + {0xE058, 0x90EE}, //16664 #CJK UNIFIED IDEOGRAPH + {0xE059, 0x90F0}, //16665 #CJK UNIFIED IDEOGRAPH + {0xE05A, 0x90F1}, //16666 #CJK UNIFIED IDEOGRAPH + {0xE05B, 0x90F2}, //16667 #CJK UNIFIED IDEOGRAPH + {0xE05C, 0x90F3}, //16668 #CJK UNIFIED IDEOGRAPH + {0xE05D, 0x90F5}, //16669 #CJK UNIFIED IDEOGRAPH + {0xE05E, 0x90F6}, //16670 #CJK UNIFIED IDEOGRAPH + {0xE05F, 0x90F7}, //16671 #CJK UNIFIED IDEOGRAPH + {0xE060, 0x90F9}, //16672 #CJK UNIFIED IDEOGRAPH + {0xE061, 0x90FA}, //16673 #CJK UNIFIED IDEOGRAPH + {0xE062, 0x90FB}, //16674 #CJK UNIFIED IDEOGRAPH + {0xE063, 0x90FC}, //16675 #CJK UNIFIED IDEOGRAPH + {0xE064, 0x90FF}, //16676 #CJK UNIFIED IDEOGRAPH + {0xE065, 0x9100}, //16677 #CJK UNIFIED IDEOGRAPH + {0xE066, 0x9101}, //16678 #CJK UNIFIED IDEOGRAPH + {0xE067, 0x9103}, //16679 #CJK UNIFIED IDEOGRAPH + {0xE068, 0x9105}, //16680 #CJK UNIFIED IDEOGRAPH + {0xE069, 0x9106}, //16681 #CJK UNIFIED IDEOGRAPH + {0xE06A, 0x9107}, //16682 #CJK UNIFIED IDEOGRAPH + {0xE06B, 0x9108}, //16683 #CJK UNIFIED IDEOGRAPH + {0xE06C, 0x9109}, //16684 #CJK UNIFIED IDEOGRAPH + {0xE06D, 0x910A}, //16685 #CJK UNIFIED IDEOGRAPH + {0xE06E, 0x910B}, //16686 #CJK UNIFIED IDEOGRAPH + {0xE06F, 0x910C}, //16687 #CJK UNIFIED IDEOGRAPH + {0xE070, 0x910D}, //16688 #CJK UNIFIED IDEOGRAPH + {0xE071, 0x910E}, //16689 #CJK UNIFIED IDEOGRAPH + {0xE072, 0x910F}, //16690 #CJK UNIFIED IDEOGRAPH + {0xE073, 0x9110}, //16691 #CJK UNIFIED IDEOGRAPH + {0xE074, 0x9111}, //16692 #CJK UNIFIED IDEOGRAPH + {0xE075, 0x9112}, //16693 #CJK UNIFIED IDEOGRAPH + {0xE076, 0x9113}, //16694 #CJK UNIFIED IDEOGRAPH + {0xE077, 0x9114}, //16695 #CJK UNIFIED IDEOGRAPH + {0xE078, 0x9115}, //16696 #CJK UNIFIED IDEOGRAPH + {0xE079, 0x9116}, //16697 #CJK UNIFIED IDEOGRAPH + {0xE07A, 0x9117}, //16698 #CJK UNIFIED IDEOGRAPH + {0xE07B, 0x9118}, //16699 #CJK UNIFIED IDEOGRAPH + {0xE07C, 0x911A}, //16700 #CJK UNIFIED IDEOGRAPH + {0xE07D, 0x911B}, //16701 #CJK UNIFIED IDEOGRAPH + {0xE07E, 0x911C}, //16702 #CJK UNIFIED IDEOGRAPH + {0xE080, 0x911D}, //16703 #CJK UNIFIED IDEOGRAPH + {0xE081, 0x911F}, //16704 #CJK UNIFIED IDEOGRAPH + {0xE082, 0x9120}, //16705 #CJK UNIFIED IDEOGRAPH + {0xE083, 0x9121}, //16706 #CJK UNIFIED IDEOGRAPH + {0xE084, 0x9124}, //16707 #CJK UNIFIED IDEOGRAPH + {0xE085, 0x9125}, //16708 #CJK UNIFIED IDEOGRAPH + {0xE086, 0x9126}, //16709 #CJK UNIFIED IDEOGRAPH + {0xE087, 0x9127}, //16710 #CJK UNIFIED IDEOGRAPH + {0xE088, 0x9128}, //16711 #CJK UNIFIED IDEOGRAPH + {0xE089, 0x9129}, //16712 #CJK UNIFIED IDEOGRAPH + {0xE08A, 0x912A}, //16713 #CJK UNIFIED IDEOGRAPH + {0xE08B, 0x912B}, //16714 #CJK UNIFIED IDEOGRAPH + {0xE08C, 0x912C}, //16715 #CJK UNIFIED IDEOGRAPH + {0xE08D, 0x912D}, //16716 #CJK UNIFIED IDEOGRAPH + {0xE08E, 0x912E}, //16717 #CJK UNIFIED IDEOGRAPH + {0xE08F, 0x9130}, //16718 #CJK UNIFIED IDEOGRAPH + {0xE090, 0x9132}, //16719 #CJK UNIFIED IDEOGRAPH + {0xE091, 0x9133}, //16720 #CJK UNIFIED IDEOGRAPH + {0xE092, 0x9134}, //16721 #CJK UNIFIED IDEOGRAPH + {0xE093, 0x9135}, //16722 #CJK UNIFIED IDEOGRAPH + {0xE094, 0x9136}, //16723 #CJK UNIFIED IDEOGRAPH + {0xE095, 0x9137}, //16724 #CJK UNIFIED IDEOGRAPH + {0xE096, 0x9138}, //16725 #CJK UNIFIED IDEOGRAPH + {0xE097, 0x913A}, //16726 #CJK UNIFIED IDEOGRAPH + {0xE098, 0x913B}, //16727 #CJK UNIFIED IDEOGRAPH + {0xE099, 0x913C}, //16728 #CJK UNIFIED IDEOGRAPH + {0xE09A, 0x913D}, //16729 #CJK UNIFIED IDEOGRAPH + {0xE09B, 0x913E}, //16730 #CJK UNIFIED IDEOGRAPH + {0xE09C, 0x913F}, //16731 #CJK UNIFIED IDEOGRAPH + {0xE09D, 0x9140}, //16732 #CJK UNIFIED IDEOGRAPH + {0xE09E, 0x9141}, //16733 #CJK UNIFIED IDEOGRAPH + {0xE09F, 0x9142}, //16734 #CJK UNIFIED IDEOGRAPH + {0xE0A0, 0x9144}, //16735 #CJK UNIFIED IDEOGRAPH + {0xE0A1, 0x5537}, //16736 #CJK UNIFIED IDEOGRAPH + {0xE0A2, 0x5556}, //16737 #CJK UNIFIED IDEOGRAPH + {0xE0A3, 0x5575}, //16738 #CJK UNIFIED IDEOGRAPH + {0xE0A4, 0x5576}, //16739 #CJK UNIFIED IDEOGRAPH + {0xE0A5, 0x5577}, //16740 #CJK UNIFIED IDEOGRAPH + {0xE0A6, 0x5533}, //16741 #CJK UNIFIED IDEOGRAPH + {0xE0A7, 0x5530}, //16742 #CJK UNIFIED IDEOGRAPH + {0xE0A8, 0x555C}, //16743 #CJK UNIFIED IDEOGRAPH + {0xE0A9, 0x558B}, //16744 #CJK UNIFIED IDEOGRAPH + {0xE0AA, 0x55D2}, //16745 #CJK UNIFIED IDEOGRAPH + {0xE0AB, 0x5583}, //16746 #CJK UNIFIED IDEOGRAPH + {0xE0AC, 0x55B1}, //16747 #CJK UNIFIED IDEOGRAPH + {0xE0AD, 0x55B9}, //16748 #CJK UNIFIED IDEOGRAPH + {0xE0AE, 0x5588}, //16749 #CJK UNIFIED IDEOGRAPH + {0xE0AF, 0x5581}, //16750 #CJK UNIFIED IDEOGRAPH + {0xE0B0, 0x559F}, //16751 #CJK UNIFIED IDEOGRAPH + {0xE0B1, 0x557E}, //16752 #CJK UNIFIED IDEOGRAPH + {0xE0B2, 0x55D6}, //16753 #CJK UNIFIED IDEOGRAPH + {0xE0B3, 0x5591}, //16754 #CJK UNIFIED IDEOGRAPH + {0xE0B4, 0x557B}, //16755 #CJK UNIFIED IDEOGRAPH + {0xE0B5, 0x55DF}, //16756 #CJK UNIFIED IDEOGRAPH + {0xE0B6, 0x55BD}, //16757 #CJK UNIFIED IDEOGRAPH + {0xE0B7, 0x55BE}, //16758 #CJK UNIFIED IDEOGRAPH + {0xE0B8, 0x5594}, //16759 #CJK UNIFIED IDEOGRAPH + {0xE0B9, 0x5599}, //16760 #CJK UNIFIED IDEOGRAPH + {0xE0BA, 0x55EA}, //16761 #CJK UNIFIED IDEOGRAPH + {0xE0BB, 0x55F7}, //16762 #CJK UNIFIED IDEOGRAPH + {0xE0BC, 0x55C9}, //16763 #CJK UNIFIED IDEOGRAPH + {0xE0BD, 0x561F}, //16764 #CJK UNIFIED IDEOGRAPH + {0xE0BE, 0x55D1}, //16765 #CJK UNIFIED IDEOGRAPH + {0xE0BF, 0x55EB}, //16766 #CJK UNIFIED IDEOGRAPH + {0xE0C0, 0x55EC}, //16767 #CJK UNIFIED IDEOGRAPH + {0xE0C1, 0x55D4}, //16768 #CJK UNIFIED IDEOGRAPH + {0xE0C2, 0x55E6}, //16769 #CJK UNIFIED IDEOGRAPH + {0xE0C3, 0x55DD}, //16770 #CJK UNIFIED IDEOGRAPH + {0xE0C4, 0x55C4}, //16771 #CJK UNIFIED IDEOGRAPH + {0xE0C5, 0x55EF}, //16772 #CJK UNIFIED IDEOGRAPH + {0xE0C6, 0x55E5}, //16773 #CJK UNIFIED IDEOGRAPH + {0xE0C7, 0x55F2}, //16774 #CJK UNIFIED IDEOGRAPH + {0xE0C8, 0x55F3}, //16775 #CJK UNIFIED IDEOGRAPH + {0xE0C9, 0x55CC}, //16776 #CJK UNIFIED IDEOGRAPH + {0xE0CA, 0x55CD}, //16777 #CJK UNIFIED IDEOGRAPH + {0xE0CB, 0x55E8}, //16778 #CJK UNIFIED IDEOGRAPH + {0xE0CC, 0x55F5}, //16779 #CJK UNIFIED IDEOGRAPH + {0xE0CD, 0x55E4}, //16780 #CJK UNIFIED IDEOGRAPH + {0xE0CE, 0x8F94}, //16781 #CJK UNIFIED IDEOGRAPH + {0xE0CF, 0x561E}, //16782 #CJK UNIFIED IDEOGRAPH + {0xE0D0, 0x5608}, //16783 #CJK UNIFIED IDEOGRAPH + {0xE0D1, 0x560C}, //16784 #CJK UNIFIED IDEOGRAPH + {0xE0D2, 0x5601}, //16785 #CJK UNIFIED IDEOGRAPH + {0xE0D3, 0x5624}, //16786 #CJK UNIFIED IDEOGRAPH + {0xE0D4, 0x5623}, //16787 #CJK UNIFIED IDEOGRAPH + {0xE0D5, 0x55FE}, //16788 #CJK UNIFIED IDEOGRAPH + {0xE0D6, 0x5600}, //16789 #CJK UNIFIED IDEOGRAPH + {0xE0D7, 0x5627}, //16790 #CJK UNIFIED IDEOGRAPH + {0xE0D8, 0x562D}, //16791 #CJK UNIFIED IDEOGRAPH + {0xE0D9, 0x5658}, //16792 #CJK UNIFIED IDEOGRAPH + {0xE0DA, 0x5639}, //16793 #CJK UNIFIED IDEOGRAPH + {0xE0DB, 0x5657}, //16794 #CJK UNIFIED IDEOGRAPH + {0xE0DC, 0x562C}, //16795 #CJK UNIFIED IDEOGRAPH + {0xE0DD, 0x564D}, //16796 #CJK UNIFIED IDEOGRAPH + {0xE0DE, 0x5662}, //16797 #CJK UNIFIED IDEOGRAPH + {0xE0DF, 0x5659}, //16798 #CJK UNIFIED IDEOGRAPH + {0xE0E0, 0x565C}, //16799 #CJK UNIFIED IDEOGRAPH + {0xE0E1, 0x564C}, //16800 #CJK UNIFIED IDEOGRAPH + {0xE0E2, 0x5654}, //16801 #CJK UNIFIED IDEOGRAPH + {0xE0E3, 0x5686}, //16802 #CJK UNIFIED IDEOGRAPH + {0xE0E4, 0x5664}, //16803 #CJK UNIFIED IDEOGRAPH + {0xE0E5, 0x5671}, //16804 #CJK UNIFIED IDEOGRAPH + {0xE0E6, 0x566B}, //16805 #CJK UNIFIED IDEOGRAPH + {0xE0E7, 0x567B}, //16806 #CJK UNIFIED IDEOGRAPH + {0xE0E8, 0x567C}, //16807 #CJK UNIFIED IDEOGRAPH + {0xE0E9, 0x5685}, //16808 #CJK UNIFIED IDEOGRAPH + {0xE0EA, 0x5693}, //16809 #CJK UNIFIED IDEOGRAPH + {0xE0EB, 0x56AF}, //16810 #CJK UNIFIED IDEOGRAPH + {0xE0EC, 0x56D4}, //16811 #CJK UNIFIED IDEOGRAPH + {0xE0ED, 0x56D7}, //16812 #CJK UNIFIED IDEOGRAPH + {0xE0EE, 0x56DD}, //16813 #CJK UNIFIED IDEOGRAPH + {0xE0EF, 0x56E1}, //16814 #CJK UNIFIED IDEOGRAPH + {0xE0F0, 0x56F5}, //16815 #CJK UNIFIED IDEOGRAPH + {0xE0F1, 0x56EB}, //16816 #CJK UNIFIED IDEOGRAPH + {0xE0F2, 0x56F9}, //16817 #CJK UNIFIED IDEOGRAPH + {0xE0F3, 0x56FF}, //16818 #CJK UNIFIED IDEOGRAPH + {0xE0F4, 0x5704}, //16819 #CJK UNIFIED IDEOGRAPH + {0xE0F5, 0x570A}, //16820 #CJK UNIFIED IDEOGRAPH + {0xE0F6, 0x5709}, //16821 #CJK UNIFIED IDEOGRAPH + {0xE0F7, 0x571C}, //16822 #CJK UNIFIED IDEOGRAPH + {0xE0F8, 0x5E0F}, //16823 #CJK UNIFIED IDEOGRAPH + {0xE0F9, 0x5E19}, //16824 #CJK UNIFIED IDEOGRAPH + {0xE0FA, 0x5E14}, //16825 #CJK UNIFIED IDEOGRAPH + {0xE0FB, 0x5E11}, //16826 #CJK UNIFIED IDEOGRAPH + {0xE0FC, 0x5E31}, //16827 #CJK UNIFIED IDEOGRAPH + {0xE0FD, 0x5E3B}, //16828 #CJK UNIFIED IDEOGRAPH + {0xE0FE, 0x5E3C}, //16829 #CJK UNIFIED IDEOGRAPH + {0xE140, 0x9145}, //16830 #CJK UNIFIED IDEOGRAPH + {0xE141, 0x9147}, //16831 #CJK UNIFIED IDEOGRAPH + {0xE142, 0x9148}, //16832 #CJK UNIFIED IDEOGRAPH + {0xE143, 0x9151}, //16833 #CJK UNIFIED IDEOGRAPH + {0xE144, 0x9153}, //16834 #CJK UNIFIED IDEOGRAPH + {0xE145, 0x9154}, //16835 #CJK UNIFIED IDEOGRAPH + {0xE146, 0x9155}, //16836 #CJK UNIFIED IDEOGRAPH + {0xE147, 0x9156}, //16837 #CJK UNIFIED IDEOGRAPH + {0xE148, 0x9158}, //16838 #CJK UNIFIED IDEOGRAPH + {0xE149, 0x9159}, //16839 #CJK UNIFIED IDEOGRAPH + {0xE14A, 0x915B}, //16840 #CJK UNIFIED IDEOGRAPH + {0xE14B, 0x915C}, //16841 #CJK UNIFIED IDEOGRAPH + {0xE14C, 0x915F}, //16842 #CJK UNIFIED IDEOGRAPH + {0xE14D, 0x9160}, //16843 #CJK UNIFIED IDEOGRAPH + {0xE14E, 0x9166}, //16844 #CJK UNIFIED IDEOGRAPH + {0xE14F, 0x9167}, //16845 #CJK UNIFIED IDEOGRAPH + {0xE150, 0x9168}, //16846 #CJK UNIFIED IDEOGRAPH + {0xE151, 0x916B}, //16847 #CJK UNIFIED IDEOGRAPH + {0xE152, 0x916D}, //16848 #CJK UNIFIED IDEOGRAPH + {0xE153, 0x9173}, //16849 #CJK UNIFIED IDEOGRAPH + {0xE154, 0x917A}, //16850 #CJK UNIFIED IDEOGRAPH + {0xE155, 0x917B}, //16851 #CJK UNIFIED IDEOGRAPH + {0xE156, 0x917C}, //16852 #CJK UNIFIED IDEOGRAPH + {0xE157, 0x9180}, //16853 #CJK UNIFIED IDEOGRAPH + {0xE158, 0x9181}, //16854 #CJK UNIFIED IDEOGRAPH + {0xE159, 0x9182}, //16855 #CJK UNIFIED IDEOGRAPH + {0xE15A, 0x9183}, //16856 #CJK UNIFIED IDEOGRAPH + {0xE15B, 0x9184}, //16857 #CJK UNIFIED IDEOGRAPH + {0xE15C, 0x9186}, //16858 #CJK UNIFIED IDEOGRAPH + {0xE15D, 0x9188}, //16859 #CJK UNIFIED IDEOGRAPH + {0xE15E, 0x918A}, //16860 #CJK UNIFIED IDEOGRAPH + {0xE15F, 0x918E}, //16861 #CJK UNIFIED IDEOGRAPH + {0xE160, 0x918F}, //16862 #CJK UNIFIED IDEOGRAPH + {0xE161, 0x9193}, //16863 #CJK UNIFIED IDEOGRAPH + {0xE162, 0x9194}, //16864 #CJK UNIFIED IDEOGRAPH + {0xE163, 0x9195}, //16865 #CJK UNIFIED IDEOGRAPH + {0xE164, 0x9196}, //16866 #CJK UNIFIED IDEOGRAPH + {0xE165, 0x9197}, //16867 #CJK UNIFIED IDEOGRAPH + {0xE166, 0x9198}, //16868 #CJK UNIFIED IDEOGRAPH + {0xE167, 0x9199}, //16869 #CJK UNIFIED IDEOGRAPH + {0xE168, 0x919C}, //16870 #CJK UNIFIED IDEOGRAPH + {0xE169, 0x919D}, //16871 #CJK UNIFIED IDEOGRAPH + {0xE16A, 0x919E}, //16872 #CJK UNIFIED IDEOGRAPH + {0xE16B, 0x919F}, //16873 #CJK UNIFIED IDEOGRAPH + {0xE16C, 0x91A0}, //16874 #CJK UNIFIED IDEOGRAPH + {0xE16D, 0x91A1}, //16875 #CJK UNIFIED IDEOGRAPH + {0xE16E, 0x91A4}, //16876 #CJK UNIFIED IDEOGRAPH + {0xE16F, 0x91A5}, //16877 #CJK UNIFIED IDEOGRAPH + {0xE170, 0x91A6}, //16878 #CJK UNIFIED IDEOGRAPH + {0xE171, 0x91A7}, //16879 #CJK UNIFIED IDEOGRAPH + {0xE172, 0x91A8}, //16880 #CJK UNIFIED IDEOGRAPH + {0xE173, 0x91A9}, //16881 #CJK UNIFIED IDEOGRAPH + {0xE174, 0x91AB}, //16882 #CJK UNIFIED IDEOGRAPH + {0xE175, 0x91AC}, //16883 #CJK UNIFIED IDEOGRAPH + {0xE176, 0x91B0}, //16884 #CJK UNIFIED IDEOGRAPH + {0xE177, 0x91B1}, //16885 #CJK UNIFIED IDEOGRAPH + {0xE178, 0x91B2}, //16886 #CJK UNIFIED IDEOGRAPH + {0xE179, 0x91B3}, //16887 #CJK UNIFIED IDEOGRAPH + {0xE17A, 0x91B6}, //16888 #CJK UNIFIED IDEOGRAPH + {0xE17B, 0x91B7}, //16889 #CJK UNIFIED IDEOGRAPH + {0xE17C, 0x91B8}, //16890 #CJK UNIFIED IDEOGRAPH + {0xE17D, 0x91B9}, //16891 #CJK UNIFIED IDEOGRAPH + {0xE17E, 0x91BB}, //16892 #CJK UNIFIED IDEOGRAPH + {0xE180, 0x91BC}, //16893 #CJK UNIFIED IDEOGRAPH + {0xE181, 0x91BD}, //16894 #CJK UNIFIED IDEOGRAPH + {0xE182, 0x91BE}, //16895 #CJK UNIFIED IDEOGRAPH + {0xE183, 0x91BF}, //16896 #CJK UNIFIED IDEOGRAPH + {0xE184, 0x91C0}, //16897 #CJK UNIFIED IDEOGRAPH + {0xE185, 0x91C1}, //16898 #CJK UNIFIED IDEOGRAPH + {0xE186, 0x91C2}, //16899 #CJK UNIFIED IDEOGRAPH + {0xE187, 0x91C3}, //16900 #CJK UNIFIED IDEOGRAPH + {0xE188, 0x91C4}, //16901 #CJK UNIFIED IDEOGRAPH + {0xE189, 0x91C5}, //16902 #CJK UNIFIED IDEOGRAPH + {0xE18A, 0x91C6}, //16903 #CJK UNIFIED IDEOGRAPH + {0xE18B, 0x91C8}, //16904 #CJK UNIFIED IDEOGRAPH + {0xE18C, 0x91CB}, //16905 #CJK UNIFIED IDEOGRAPH + {0xE18D, 0x91D0}, //16906 #CJK UNIFIED IDEOGRAPH + {0xE18E, 0x91D2}, //16907 #CJK UNIFIED IDEOGRAPH + {0xE18F, 0x91D3}, //16908 #CJK UNIFIED IDEOGRAPH + {0xE190, 0x91D4}, //16909 #CJK UNIFIED IDEOGRAPH + {0xE191, 0x91D5}, //16910 #CJK UNIFIED IDEOGRAPH + {0xE192, 0x91D6}, //16911 #CJK UNIFIED IDEOGRAPH + {0xE193, 0x91D7}, //16912 #CJK UNIFIED IDEOGRAPH + {0xE194, 0x91D8}, //16913 #CJK UNIFIED IDEOGRAPH + {0xE195, 0x91D9}, //16914 #CJK UNIFIED IDEOGRAPH + {0xE196, 0x91DA}, //16915 #CJK UNIFIED IDEOGRAPH + {0xE197, 0x91DB}, //16916 #CJK UNIFIED IDEOGRAPH + {0xE198, 0x91DD}, //16917 #CJK UNIFIED IDEOGRAPH + {0xE199, 0x91DE}, //16918 #CJK UNIFIED IDEOGRAPH + {0xE19A, 0x91DF}, //16919 #CJK UNIFIED IDEOGRAPH + {0xE19B, 0x91E0}, //16920 #CJK UNIFIED IDEOGRAPH + {0xE19C, 0x91E1}, //16921 #CJK UNIFIED IDEOGRAPH + {0xE19D, 0x91E2}, //16922 #CJK UNIFIED IDEOGRAPH + {0xE19E, 0x91E3}, //16923 #CJK UNIFIED IDEOGRAPH + {0xE19F, 0x91E4}, //16924 #CJK UNIFIED IDEOGRAPH + {0xE1A0, 0x91E5}, //16925 #CJK UNIFIED IDEOGRAPH + {0xE1A1, 0x5E37}, //16926 #CJK UNIFIED IDEOGRAPH + {0xE1A2, 0x5E44}, //16927 #CJK UNIFIED IDEOGRAPH + {0xE1A3, 0x5E54}, //16928 #CJK UNIFIED IDEOGRAPH + {0xE1A4, 0x5E5B}, //16929 #CJK UNIFIED IDEOGRAPH + {0xE1A5, 0x5E5E}, //16930 #CJK UNIFIED IDEOGRAPH + {0xE1A6, 0x5E61}, //16931 #CJK UNIFIED IDEOGRAPH + {0xE1A7, 0x5C8C}, //16932 #CJK UNIFIED IDEOGRAPH + {0xE1A8, 0x5C7A}, //16933 #CJK UNIFIED IDEOGRAPH + {0xE1A9, 0x5C8D}, //16934 #CJK UNIFIED IDEOGRAPH + {0xE1AA, 0x5C90}, //16935 #CJK UNIFIED IDEOGRAPH + {0xE1AB, 0x5C96}, //16936 #CJK UNIFIED IDEOGRAPH + {0xE1AC, 0x5C88}, //16937 #CJK UNIFIED IDEOGRAPH + {0xE1AD, 0x5C98}, //16938 #CJK UNIFIED IDEOGRAPH + {0xE1AE, 0x5C99}, //16939 #CJK UNIFIED IDEOGRAPH + {0xE1AF, 0x5C91}, //16940 #CJK UNIFIED IDEOGRAPH + {0xE1B0, 0x5C9A}, //16941 #CJK UNIFIED IDEOGRAPH + {0xE1B1, 0x5C9C}, //16942 #CJK UNIFIED IDEOGRAPH + {0xE1B2, 0x5CB5}, //16943 #CJK UNIFIED IDEOGRAPH + {0xE1B3, 0x5CA2}, //16944 #CJK UNIFIED IDEOGRAPH + {0xE1B4, 0x5CBD}, //16945 #CJK UNIFIED IDEOGRAPH + {0xE1B5, 0x5CAC}, //16946 #CJK UNIFIED IDEOGRAPH + {0xE1B6, 0x5CAB}, //16947 #CJK UNIFIED IDEOGRAPH + {0xE1B7, 0x5CB1}, //16948 #CJK UNIFIED IDEOGRAPH + {0xE1B8, 0x5CA3}, //16949 #CJK UNIFIED IDEOGRAPH + {0xE1B9, 0x5CC1}, //16950 #CJK UNIFIED IDEOGRAPH + {0xE1BA, 0x5CB7}, //16951 #CJK UNIFIED IDEOGRAPH + {0xE1BB, 0x5CC4}, //16952 #CJK UNIFIED IDEOGRAPH + {0xE1BC, 0x5CD2}, //16953 #CJK UNIFIED IDEOGRAPH + {0xE1BD, 0x5CE4}, //16954 #CJK UNIFIED IDEOGRAPH + {0xE1BE, 0x5CCB}, //16955 #CJK UNIFIED IDEOGRAPH + {0xE1BF, 0x5CE5}, //16956 #CJK UNIFIED IDEOGRAPH + {0xE1C0, 0x5D02}, //16957 #CJK UNIFIED IDEOGRAPH + {0xE1C1, 0x5D03}, //16958 #CJK UNIFIED IDEOGRAPH + {0xE1C2, 0x5D27}, //16959 #CJK UNIFIED IDEOGRAPH + {0xE1C3, 0x5D26}, //16960 #CJK UNIFIED IDEOGRAPH + {0xE1C4, 0x5D2E}, //16961 #CJK UNIFIED IDEOGRAPH + {0xE1C5, 0x5D24}, //16962 #CJK UNIFIED IDEOGRAPH + {0xE1C6, 0x5D1E}, //16963 #CJK UNIFIED IDEOGRAPH + {0xE1C7, 0x5D06}, //16964 #CJK UNIFIED IDEOGRAPH + {0xE1C8, 0x5D1B}, //16965 #CJK UNIFIED IDEOGRAPH + {0xE1C9, 0x5D58}, //16966 #CJK UNIFIED IDEOGRAPH + {0xE1CA, 0x5D3E}, //16967 #CJK UNIFIED IDEOGRAPH + {0xE1CB, 0x5D34}, //16968 #CJK UNIFIED IDEOGRAPH + {0xE1CC, 0x5D3D}, //16969 #CJK UNIFIED IDEOGRAPH + {0xE1CD, 0x5D6C}, //16970 #CJK UNIFIED IDEOGRAPH + {0xE1CE, 0x5D5B}, //16971 #CJK UNIFIED IDEOGRAPH + {0xE1CF, 0x5D6F}, //16972 #CJK UNIFIED IDEOGRAPH + {0xE1D0, 0x5D5D}, //16973 #CJK UNIFIED IDEOGRAPH + {0xE1D1, 0x5D6B}, //16974 #CJK UNIFIED IDEOGRAPH + {0xE1D2, 0x5D4B}, //16975 #CJK UNIFIED IDEOGRAPH + {0xE1D3, 0x5D4A}, //16976 #CJK UNIFIED IDEOGRAPH + {0xE1D4, 0x5D69}, //16977 #CJK UNIFIED IDEOGRAPH + {0xE1D5, 0x5D74}, //16978 #CJK UNIFIED IDEOGRAPH + {0xE1D6, 0x5D82}, //16979 #CJK UNIFIED IDEOGRAPH + {0xE1D7, 0x5D99}, //16980 #CJK UNIFIED IDEOGRAPH + {0xE1D8, 0x5D9D}, //16981 #CJK UNIFIED IDEOGRAPH + {0xE1D9, 0x8C73}, //16982 #CJK UNIFIED IDEOGRAPH + {0xE1DA, 0x5DB7}, //16983 #CJK UNIFIED IDEOGRAPH + {0xE1DB, 0x5DC5}, //16984 #CJK UNIFIED IDEOGRAPH + {0xE1DC, 0x5F73}, //16985 #CJK UNIFIED IDEOGRAPH + {0xE1DD, 0x5F77}, //16986 #CJK UNIFIED IDEOGRAPH + {0xE1DE, 0x5F82}, //16987 #CJK UNIFIED IDEOGRAPH + {0xE1DF, 0x5F87}, //16988 #CJK UNIFIED IDEOGRAPH + {0xE1E0, 0x5F89}, //16989 #CJK UNIFIED IDEOGRAPH + {0xE1E1, 0x5F8C}, //16990 #CJK UNIFIED IDEOGRAPH + {0xE1E2, 0x5F95}, //16991 #CJK UNIFIED IDEOGRAPH + {0xE1E3, 0x5F99}, //16992 #CJK UNIFIED IDEOGRAPH + {0xE1E4, 0x5F9C}, //16993 #CJK UNIFIED IDEOGRAPH + {0xE1E5, 0x5FA8}, //16994 #CJK UNIFIED IDEOGRAPH + {0xE1E6, 0x5FAD}, //16995 #CJK UNIFIED IDEOGRAPH + {0xE1E7, 0x5FB5}, //16996 #CJK UNIFIED IDEOGRAPH + {0xE1E8, 0x5FBC}, //16997 #CJK UNIFIED IDEOGRAPH + {0xE1E9, 0x8862}, //16998 #CJK UNIFIED IDEOGRAPH + {0xE1EA, 0x5F61}, //16999 #CJK UNIFIED IDEOGRAPH + {0xE1EB, 0x72AD}, //17000 #CJK UNIFIED IDEOGRAPH + {0xE1EC, 0x72B0}, //17001 #CJK UNIFIED IDEOGRAPH + {0xE1ED, 0x72B4}, //17002 #CJK UNIFIED IDEOGRAPH + {0xE1EE, 0x72B7}, //17003 #CJK UNIFIED IDEOGRAPH + {0xE1EF, 0x72B8}, //17004 #CJK UNIFIED IDEOGRAPH + {0xE1F0, 0x72C3}, //17005 #CJK UNIFIED IDEOGRAPH + {0xE1F1, 0x72C1}, //17006 #CJK UNIFIED IDEOGRAPH + {0xE1F2, 0x72CE}, //17007 #CJK UNIFIED IDEOGRAPH + {0xE1F3, 0x72CD}, //17008 #CJK UNIFIED IDEOGRAPH + {0xE1F4, 0x72D2}, //17009 #CJK UNIFIED IDEOGRAPH + {0xE1F5, 0x72E8}, //17010 #CJK UNIFIED IDEOGRAPH + {0xE1F6, 0x72EF}, //17011 #CJK UNIFIED IDEOGRAPH + {0xE1F7, 0x72E9}, //17012 #CJK UNIFIED IDEOGRAPH + {0xE1F8, 0x72F2}, //17013 #CJK UNIFIED IDEOGRAPH + {0xE1F9, 0x72F4}, //17014 #CJK UNIFIED IDEOGRAPH + {0xE1FA, 0x72F7}, //17015 #CJK UNIFIED IDEOGRAPH + {0xE1FB, 0x7301}, //17016 #CJK UNIFIED IDEOGRAPH + {0xE1FC, 0x72F3}, //17017 #CJK UNIFIED IDEOGRAPH + {0xE1FD, 0x7303}, //17018 #CJK UNIFIED IDEOGRAPH + {0xE1FE, 0x72FA}, //17019 #CJK UNIFIED IDEOGRAPH + {0xE240, 0x91E6}, //17020 #CJK UNIFIED IDEOGRAPH + {0xE241, 0x91E7}, //17021 #CJK UNIFIED IDEOGRAPH + {0xE242, 0x91E8}, //17022 #CJK UNIFIED IDEOGRAPH + {0xE243, 0x91E9}, //17023 #CJK UNIFIED IDEOGRAPH + {0xE244, 0x91EA}, //17024 #CJK UNIFIED IDEOGRAPH + {0xE245, 0x91EB}, //17025 #CJK UNIFIED IDEOGRAPH + {0xE246, 0x91EC}, //17026 #CJK UNIFIED IDEOGRAPH + {0xE247, 0x91ED}, //17027 #CJK UNIFIED IDEOGRAPH + {0xE248, 0x91EE}, //17028 #CJK UNIFIED IDEOGRAPH + {0xE249, 0x91EF}, //17029 #CJK UNIFIED IDEOGRAPH + {0xE24A, 0x91F0}, //17030 #CJK UNIFIED IDEOGRAPH + {0xE24B, 0x91F1}, //17031 #CJK UNIFIED IDEOGRAPH + {0xE24C, 0x91F2}, //17032 #CJK UNIFIED IDEOGRAPH + {0xE24D, 0x91F3}, //17033 #CJK UNIFIED IDEOGRAPH + {0xE24E, 0x91F4}, //17034 #CJK UNIFIED IDEOGRAPH + {0xE24F, 0x91F5}, //17035 #CJK UNIFIED IDEOGRAPH + {0xE250, 0x91F6}, //17036 #CJK UNIFIED IDEOGRAPH + {0xE251, 0x91F7}, //17037 #CJK UNIFIED IDEOGRAPH + {0xE252, 0x91F8}, //17038 #CJK UNIFIED IDEOGRAPH + {0xE253, 0x91F9}, //17039 #CJK UNIFIED IDEOGRAPH + {0xE254, 0x91FA}, //17040 #CJK UNIFIED IDEOGRAPH + {0xE255, 0x91FB}, //17041 #CJK UNIFIED IDEOGRAPH + {0xE256, 0x91FC}, //17042 #CJK UNIFIED IDEOGRAPH + {0xE257, 0x91FD}, //17043 #CJK UNIFIED IDEOGRAPH + {0xE258, 0x91FE}, //17044 #CJK UNIFIED IDEOGRAPH + {0xE259, 0x91FF}, //17045 #CJK UNIFIED IDEOGRAPH + {0xE25A, 0x9200}, //17046 #CJK UNIFIED IDEOGRAPH + {0xE25B, 0x9201}, //17047 #CJK UNIFIED IDEOGRAPH + {0xE25C, 0x9202}, //17048 #CJK UNIFIED IDEOGRAPH + {0xE25D, 0x9203}, //17049 #CJK UNIFIED IDEOGRAPH + {0xE25E, 0x9204}, //17050 #CJK UNIFIED IDEOGRAPH + {0xE25F, 0x9205}, //17051 #CJK UNIFIED IDEOGRAPH + {0xE260, 0x9206}, //17052 #CJK UNIFIED IDEOGRAPH + {0xE261, 0x9207}, //17053 #CJK UNIFIED IDEOGRAPH + {0xE262, 0x9208}, //17054 #CJK UNIFIED IDEOGRAPH + {0xE263, 0x9209}, //17055 #CJK UNIFIED IDEOGRAPH + {0xE264, 0x920A}, //17056 #CJK UNIFIED IDEOGRAPH + {0xE265, 0x920B}, //17057 #CJK UNIFIED IDEOGRAPH + {0xE266, 0x920C}, //17058 #CJK UNIFIED IDEOGRAPH + {0xE267, 0x920D}, //17059 #CJK UNIFIED IDEOGRAPH + {0xE268, 0x920E}, //17060 #CJK UNIFIED IDEOGRAPH + {0xE269, 0x920F}, //17061 #CJK UNIFIED IDEOGRAPH + {0xE26A, 0x9210}, //17062 #CJK UNIFIED IDEOGRAPH + {0xE26B, 0x9211}, //17063 #CJK UNIFIED IDEOGRAPH + {0xE26C, 0x9212}, //17064 #CJK UNIFIED IDEOGRAPH + {0xE26D, 0x9213}, //17065 #CJK UNIFIED IDEOGRAPH + {0xE26E, 0x9214}, //17066 #CJK UNIFIED IDEOGRAPH + {0xE26F, 0x9215}, //17067 #CJK UNIFIED IDEOGRAPH + {0xE270, 0x9216}, //17068 #CJK UNIFIED IDEOGRAPH + {0xE271, 0x9217}, //17069 #CJK UNIFIED IDEOGRAPH + {0xE272, 0x9218}, //17070 #CJK UNIFIED IDEOGRAPH + {0xE273, 0x9219}, //17071 #CJK UNIFIED IDEOGRAPH + {0xE274, 0x921A}, //17072 #CJK UNIFIED IDEOGRAPH + {0xE275, 0x921B}, //17073 #CJK UNIFIED IDEOGRAPH + {0xE276, 0x921C}, //17074 #CJK UNIFIED IDEOGRAPH + {0xE277, 0x921D}, //17075 #CJK UNIFIED IDEOGRAPH + {0xE278, 0x921E}, //17076 #CJK UNIFIED IDEOGRAPH + {0xE279, 0x921F}, //17077 #CJK UNIFIED IDEOGRAPH + {0xE27A, 0x9220}, //17078 #CJK UNIFIED IDEOGRAPH + {0xE27B, 0x9221}, //17079 #CJK UNIFIED IDEOGRAPH + {0xE27C, 0x9222}, //17080 #CJK UNIFIED IDEOGRAPH + {0xE27D, 0x9223}, //17081 #CJK UNIFIED IDEOGRAPH + {0xE27E, 0x9224}, //17082 #CJK UNIFIED IDEOGRAPH + {0xE280, 0x9225}, //17083 #CJK UNIFIED IDEOGRAPH + {0xE281, 0x9226}, //17084 #CJK UNIFIED IDEOGRAPH + {0xE282, 0x9227}, //17085 #CJK UNIFIED IDEOGRAPH + {0xE283, 0x9228}, //17086 #CJK UNIFIED IDEOGRAPH + {0xE284, 0x9229}, //17087 #CJK UNIFIED IDEOGRAPH + {0xE285, 0x922A}, //17088 #CJK UNIFIED IDEOGRAPH + {0xE286, 0x922B}, //17089 #CJK UNIFIED IDEOGRAPH + {0xE287, 0x922C}, //17090 #CJK UNIFIED IDEOGRAPH + {0xE288, 0x922D}, //17091 #CJK UNIFIED IDEOGRAPH + {0xE289, 0x922E}, //17092 #CJK UNIFIED IDEOGRAPH + {0xE28A, 0x922F}, //17093 #CJK UNIFIED IDEOGRAPH + {0xE28B, 0x9230}, //17094 #CJK UNIFIED IDEOGRAPH + {0xE28C, 0x9231}, //17095 #CJK UNIFIED IDEOGRAPH + {0xE28D, 0x9232}, //17096 #CJK UNIFIED IDEOGRAPH + {0xE28E, 0x9233}, //17097 #CJK UNIFIED IDEOGRAPH + {0xE28F, 0x9234}, //17098 #CJK UNIFIED IDEOGRAPH + {0xE290, 0x9235}, //17099 #CJK UNIFIED IDEOGRAPH + {0xE291, 0x9236}, //17100 #CJK UNIFIED IDEOGRAPH + {0xE292, 0x9237}, //17101 #CJK UNIFIED IDEOGRAPH + {0xE293, 0x9238}, //17102 #CJK UNIFIED IDEOGRAPH + {0xE294, 0x9239}, //17103 #CJK UNIFIED IDEOGRAPH + {0xE295, 0x923A}, //17104 #CJK UNIFIED IDEOGRAPH + {0xE296, 0x923B}, //17105 #CJK UNIFIED IDEOGRAPH + {0xE297, 0x923C}, //17106 #CJK UNIFIED IDEOGRAPH + {0xE298, 0x923D}, //17107 #CJK UNIFIED IDEOGRAPH + {0xE299, 0x923E}, //17108 #CJK UNIFIED IDEOGRAPH + {0xE29A, 0x923F}, //17109 #CJK UNIFIED IDEOGRAPH + {0xE29B, 0x9240}, //17110 #CJK UNIFIED IDEOGRAPH + {0xE29C, 0x9241}, //17111 #CJK UNIFIED IDEOGRAPH + {0xE29D, 0x9242}, //17112 #CJK UNIFIED IDEOGRAPH + {0xE29E, 0x9243}, //17113 #CJK UNIFIED IDEOGRAPH + {0xE29F, 0x9244}, //17114 #CJK UNIFIED IDEOGRAPH + {0xE2A0, 0x9245}, //17115 #CJK UNIFIED IDEOGRAPH + {0xE2A1, 0x72FB}, //17116 #CJK UNIFIED IDEOGRAPH + {0xE2A2, 0x7317}, //17117 #CJK UNIFIED IDEOGRAPH + {0xE2A3, 0x7313}, //17118 #CJK UNIFIED IDEOGRAPH + {0xE2A4, 0x7321}, //17119 #CJK UNIFIED IDEOGRAPH + {0xE2A5, 0x730A}, //17120 #CJK UNIFIED IDEOGRAPH + {0xE2A6, 0x731E}, //17121 #CJK UNIFIED IDEOGRAPH + {0xE2A7, 0x731D}, //17122 #CJK UNIFIED IDEOGRAPH + {0xE2A8, 0x7315}, //17123 #CJK UNIFIED IDEOGRAPH + {0xE2A9, 0x7322}, //17124 #CJK UNIFIED IDEOGRAPH + {0xE2AA, 0x7339}, //17125 #CJK UNIFIED IDEOGRAPH + {0xE2AB, 0x7325}, //17126 #CJK UNIFIED IDEOGRAPH + {0xE2AC, 0x732C}, //17127 #CJK UNIFIED IDEOGRAPH + {0xE2AD, 0x7338}, //17128 #CJK UNIFIED IDEOGRAPH + {0xE2AE, 0x7331}, //17129 #CJK UNIFIED IDEOGRAPH + {0xE2AF, 0x7350}, //17130 #CJK UNIFIED IDEOGRAPH + {0xE2B0, 0x734D}, //17131 #CJK UNIFIED IDEOGRAPH + {0xE2B1, 0x7357}, //17132 #CJK UNIFIED IDEOGRAPH + {0xE2B2, 0x7360}, //17133 #CJK UNIFIED IDEOGRAPH + {0xE2B3, 0x736C}, //17134 #CJK UNIFIED IDEOGRAPH + {0xE2B4, 0x736F}, //17135 #CJK UNIFIED IDEOGRAPH + {0xE2B5, 0x737E}, //17136 #CJK UNIFIED IDEOGRAPH + {0xE2B6, 0x821B}, //17137 #CJK UNIFIED IDEOGRAPH + {0xE2B7, 0x5925}, //17138 #CJK UNIFIED IDEOGRAPH + {0xE2B8, 0x98E7}, //17139 #CJK UNIFIED IDEOGRAPH + {0xE2B9, 0x5924}, //17140 #CJK UNIFIED IDEOGRAPH + {0xE2BA, 0x5902}, //17141 #CJK UNIFIED IDEOGRAPH + {0xE2BB, 0x9963}, //17142 #CJK UNIFIED IDEOGRAPH + {0xE2BC, 0x9967}, //17143 #CJK UNIFIED IDEOGRAPH + {0xE2BD, 0x9968}, //17144 #CJK UNIFIED IDEOGRAPH + {0xE2BE, 0x9969}, //17145 #CJK UNIFIED IDEOGRAPH + {0xE2BF, 0x996A}, //17146 #CJK UNIFIED IDEOGRAPH + {0xE2C0, 0x996B}, //17147 #CJK UNIFIED IDEOGRAPH + {0xE2C1, 0x996C}, //17148 #CJK UNIFIED IDEOGRAPH + {0xE2C2, 0x9974}, //17149 #CJK UNIFIED IDEOGRAPH + {0xE2C3, 0x9977}, //17150 #CJK UNIFIED IDEOGRAPH + {0xE2C4, 0x997D}, //17151 #CJK UNIFIED IDEOGRAPH + {0xE2C5, 0x9980}, //17152 #CJK UNIFIED IDEOGRAPH + {0xE2C6, 0x9984}, //17153 #CJK UNIFIED IDEOGRAPH + {0xE2C7, 0x9987}, //17154 #CJK UNIFIED IDEOGRAPH + {0xE2C8, 0x998A}, //17155 #CJK UNIFIED IDEOGRAPH + {0xE2C9, 0x998D}, //17156 #CJK UNIFIED IDEOGRAPH + {0xE2CA, 0x9990}, //17157 #CJK UNIFIED IDEOGRAPH + {0xE2CB, 0x9991}, //17158 #CJK UNIFIED IDEOGRAPH + {0xE2CC, 0x9993}, //17159 #CJK UNIFIED IDEOGRAPH + {0xE2CD, 0x9994}, //17160 #CJK UNIFIED IDEOGRAPH + {0xE2CE, 0x9995}, //17161 #CJK UNIFIED IDEOGRAPH + {0xE2CF, 0x5E80}, //17162 #CJK UNIFIED IDEOGRAPH + {0xE2D0, 0x5E91}, //17163 #CJK UNIFIED IDEOGRAPH + {0xE2D1, 0x5E8B}, //17164 #CJK UNIFIED IDEOGRAPH + {0xE2D2, 0x5E96}, //17165 #CJK UNIFIED IDEOGRAPH + {0xE2D3, 0x5EA5}, //17166 #CJK UNIFIED IDEOGRAPH + {0xE2D4, 0x5EA0}, //17167 #CJK UNIFIED IDEOGRAPH + {0xE2D5, 0x5EB9}, //17168 #CJK UNIFIED IDEOGRAPH + {0xE2D6, 0x5EB5}, //17169 #CJK UNIFIED IDEOGRAPH + {0xE2D7, 0x5EBE}, //17170 #CJK UNIFIED IDEOGRAPH + {0xE2D8, 0x5EB3}, //17171 #CJK UNIFIED IDEOGRAPH + {0xE2D9, 0x8D53}, //17172 #CJK UNIFIED IDEOGRAPH + {0xE2DA, 0x5ED2}, //17173 #CJK UNIFIED IDEOGRAPH + {0xE2DB, 0x5ED1}, //17174 #CJK UNIFIED IDEOGRAPH + {0xE2DC, 0x5EDB}, //17175 #CJK UNIFIED IDEOGRAPH + {0xE2DD, 0x5EE8}, //17176 #CJK UNIFIED IDEOGRAPH + {0xE2DE, 0x5EEA}, //17177 #CJK UNIFIED IDEOGRAPH + {0xE2DF, 0x81BA}, //17178 #CJK UNIFIED IDEOGRAPH + {0xE2E0, 0x5FC4}, //17179 #CJK UNIFIED IDEOGRAPH + {0xE2E1, 0x5FC9}, //17180 #CJK UNIFIED IDEOGRAPH + {0xE2E2, 0x5FD6}, //17181 #CJK UNIFIED IDEOGRAPH + {0xE2E3, 0x5FCF}, //17182 #CJK UNIFIED IDEOGRAPH + {0xE2E4, 0x6003}, //17183 #CJK UNIFIED IDEOGRAPH + {0xE2E5, 0x5FEE}, //17184 #CJK UNIFIED IDEOGRAPH + {0xE2E6, 0x6004}, //17185 #CJK UNIFIED IDEOGRAPH + {0xE2E7, 0x5FE1}, //17186 #CJK UNIFIED IDEOGRAPH + {0xE2E8, 0x5FE4}, //17187 #CJK UNIFIED IDEOGRAPH + {0xE2E9, 0x5FFE}, //17188 #CJK UNIFIED IDEOGRAPH + {0xE2EA, 0x6005}, //17189 #CJK UNIFIED IDEOGRAPH + {0xE2EB, 0x6006}, //17190 #CJK UNIFIED IDEOGRAPH + {0xE2EC, 0x5FEA}, //17191 #CJK UNIFIED IDEOGRAPH + {0xE2ED, 0x5FED}, //17192 #CJK UNIFIED IDEOGRAPH + {0xE2EE, 0x5FF8}, //17193 #CJK UNIFIED IDEOGRAPH + {0xE2EF, 0x6019}, //17194 #CJK UNIFIED IDEOGRAPH + {0xE2F0, 0x6035}, //17195 #CJK UNIFIED IDEOGRAPH + {0xE2F1, 0x6026}, //17196 #CJK UNIFIED IDEOGRAPH + {0xE2F2, 0x601B}, //17197 #CJK UNIFIED IDEOGRAPH + {0xE2F3, 0x600F}, //17198 #CJK UNIFIED IDEOGRAPH + {0xE2F4, 0x600D}, //17199 #CJK UNIFIED IDEOGRAPH + {0xE2F5, 0x6029}, //17200 #CJK UNIFIED IDEOGRAPH + {0xE2F6, 0x602B}, //17201 #CJK UNIFIED IDEOGRAPH + {0xE2F7, 0x600A}, //17202 #CJK UNIFIED IDEOGRAPH + {0xE2F8, 0x603F}, //17203 #CJK UNIFIED IDEOGRAPH + {0xE2F9, 0x6021}, //17204 #CJK UNIFIED IDEOGRAPH + {0xE2FA, 0x6078}, //17205 #CJK UNIFIED IDEOGRAPH + {0xE2FB, 0x6079}, //17206 #CJK UNIFIED IDEOGRAPH + {0xE2FC, 0x607B}, //17207 #CJK UNIFIED IDEOGRAPH + {0xE2FD, 0x607A}, //17208 #CJK UNIFIED IDEOGRAPH + {0xE2FE, 0x6042}, //17209 #CJK UNIFIED IDEOGRAPH + {0xE340, 0x9246}, //17210 #CJK UNIFIED IDEOGRAPH + {0xE341, 0x9247}, //17211 #CJK UNIFIED IDEOGRAPH + {0xE342, 0x9248}, //17212 #CJK UNIFIED IDEOGRAPH + {0xE343, 0x9249}, //17213 #CJK UNIFIED IDEOGRAPH + {0xE344, 0x924A}, //17214 #CJK UNIFIED IDEOGRAPH + {0xE345, 0x924B}, //17215 #CJK UNIFIED IDEOGRAPH + {0xE346, 0x924C}, //17216 #CJK UNIFIED IDEOGRAPH + {0xE347, 0x924D}, //17217 #CJK UNIFIED IDEOGRAPH + {0xE348, 0x924E}, //17218 #CJK UNIFIED IDEOGRAPH + {0xE349, 0x924F}, //17219 #CJK UNIFIED IDEOGRAPH + {0xE34A, 0x9250}, //17220 #CJK UNIFIED IDEOGRAPH + {0xE34B, 0x9251}, //17221 #CJK UNIFIED IDEOGRAPH + {0xE34C, 0x9252}, //17222 #CJK UNIFIED IDEOGRAPH + {0xE34D, 0x9253}, //17223 #CJK UNIFIED IDEOGRAPH + {0xE34E, 0x9254}, //17224 #CJK UNIFIED IDEOGRAPH + {0xE34F, 0x9255}, //17225 #CJK UNIFIED IDEOGRAPH + {0xE350, 0x9256}, //17226 #CJK UNIFIED IDEOGRAPH + {0xE351, 0x9257}, //17227 #CJK UNIFIED IDEOGRAPH + {0xE352, 0x9258}, //17228 #CJK UNIFIED IDEOGRAPH + {0xE353, 0x9259}, //17229 #CJK UNIFIED IDEOGRAPH + {0xE354, 0x925A}, //17230 #CJK UNIFIED IDEOGRAPH + {0xE355, 0x925B}, //17231 #CJK UNIFIED IDEOGRAPH + {0xE356, 0x925C}, //17232 #CJK UNIFIED IDEOGRAPH + {0xE357, 0x925D}, //17233 #CJK UNIFIED IDEOGRAPH + {0xE358, 0x925E}, //17234 #CJK UNIFIED IDEOGRAPH + {0xE359, 0x925F}, //17235 #CJK UNIFIED IDEOGRAPH + {0xE35A, 0x9260}, //17236 #CJK UNIFIED IDEOGRAPH + {0xE35B, 0x9261}, //17237 #CJK UNIFIED IDEOGRAPH + {0xE35C, 0x9262}, //17238 #CJK UNIFIED IDEOGRAPH + {0xE35D, 0x9263}, //17239 #CJK UNIFIED IDEOGRAPH + {0xE35E, 0x9264}, //17240 #CJK UNIFIED IDEOGRAPH + {0xE35F, 0x9265}, //17241 #CJK UNIFIED IDEOGRAPH + {0xE360, 0x9266}, //17242 #CJK UNIFIED IDEOGRAPH + {0xE361, 0x9267}, //17243 #CJK UNIFIED IDEOGRAPH + {0xE362, 0x9268}, //17244 #CJK UNIFIED IDEOGRAPH + {0xE363, 0x9269}, //17245 #CJK UNIFIED IDEOGRAPH + {0xE364, 0x926A}, //17246 #CJK UNIFIED IDEOGRAPH + {0xE365, 0x926B}, //17247 #CJK UNIFIED IDEOGRAPH + {0xE366, 0x926C}, //17248 #CJK UNIFIED IDEOGRAPH + {0xE367, 0x926D}, //17249 #CJK UNIFIED IDEOGRAPH + {0xE368, 0x926E}, //17250 #CJK UNIFIED IDEOGRAPH + {0xE369, 0x926F}, //17251 #CJK UNIFIED IDEOGRAPH + {0xE36A, 0x9270}, //17252 #CJK UNIFIED IDEOGRAPH + {0xE36B, 0x9271}, //17253 #CJK UNIFIED IDEOGRAPH + {0xE36C, 0x9272}, //17254 #CJK UNIFIED IDEOGRAPH + {0xE36D, 0x9273}, //17255 #CJK UNIFIED IDEOGRAPH + {0xE36E, 0x9275}, //17256 #CJK UNIFIED IDEOGRAPH + {0xE36F, 0x9276}, //17257 #CJK UNIFIED IDEOGRAPH + {0xE370, 0x9277}, //17258 #CJK UNIFIED IDEOGRAPH + {0xE371, 0x9278}, //17259 #CJK UNIFIED IDEOGRAPH + {0xE372, 0x9279}, //17260 #CJK UNIFIED IDEOGRAPH + {0xE373, 0x927A}, //17261 #CJK UNIFIED IDEOGRAPH + {0xE374, 0x927B}, //17262 #CJK UNIFIED IDEOGRAPH + {0xE375, 0x927C}, //17263 #CJK UNIFIED IDEOGRAPH + {0xE376, 0x927D}, //17264 #CJK UNIFIED IDEOGRAPH + {0xE377, 0x927E}, //17265 #CJK UNIFIED IDEOGRAPH + {0xE378, 0x927F}, //17266 #CJK UNIFIED IDEOGRAPH + {0xE379, 0x9280}, //17267 #CJK UNIFIED IDEOGRAPH + {0xE37A, 0x9281}, //17268 #CJK UNIFIED IDEOGRAPH + {0xE37B, 0x9282}, //17269 #CJK UNIFIED IDEOGRAPH + {0xE37C, 0x9283}, //17270 #CJK UNIFIED IDEOGRAPH + {0xE37D, 0x9284}, //17271 #CJK UNIFIED IDEOGRAPH + {0xE37E, 0x9285}, //17272 #CJK UNIFIED IDEOGRAPH + {0xE380, 0x9286}, //17273 #CJK UNIFIED IDEOGRAPH + {0xE381, 0x9287}, //17274 #CJK UNIFIED IDEOGRAPH + {0xE382, 0x9288}, //17275 #CJK UNIFIED IDEOGRAPH + {0xE383, 0x9289}, //17276 #CJK UNIFIED IDEOGRAPH + {0xE384, 0x928A}, //17277 #CJK UNIFIED IDEOGRAPH + {0xE385, 0x928B}, //17278 #CJK UNIFIED IDEOGRAPH + {0xE386, 0x928C}, //17279 #CJK UNIFIED IDEOGRAPH + {0xE387, 0x928D}, //17280 #CJK UNIFIED IDEOGRAPH + {0xE388, 0x928F}, //17281 #CJK UNIFIED IDEOGRAPH + {0xE389, 0x9290}, //17282 #CJK UNIFIED IDEOGRAPH + {0xE38A, 0x9291}, //17283 #CJK UNIFIED IDEOGRAPH + {0xE38B, 0x9292}, //17284 #CJK UNIFIED IDEOGRAPH + {0xE38C, 0x9293}, //17285 #CJK UNIFIED IDEOGRAPH + {0xE38D, 0x9294}, //17286 #CJK UNIFIED IDEOGRAPH + {0xE38E, 0x9295}, //17287 #CJK UNIFIED IDEOGRAPH + {0xE38F, 0x9296}, //17288 #CJK UNIFIED IDEOGRAPH + {0xE390, 0x9297}, //17289 #CJK UNIFIED IDEOGRAPH + {0xE391, 0x9298}, //17290 #CJK UNIFIED IDEOGRAPH + {0xE392, 0x9299}, //17291 #CJK UNIFIED IDEOGRAPH + {0xE393, 0x929A}, //17292 #CJK UNIFIED IDEOGRAPH + {0xE394, 0x929B}, //17293 #CJK UNIFIED IDEOGRAPH + {0xE395, 0x929C}, //17294 #CJK UNIFIED IDEOGRAPH + {0xE396, 0x929D}, //17295 #CJK UNIFIED IDEOGRAPH + {0xE397, 0x929E}, //17296 #CJK UNIFIED IDEOGRAPH + {0xE398, 0x929F}, //17297 #CJK UNIFIED IDEOGRAPH + {0xE399, 0x92A0}, //17298 #CJK UNIFIED IDEOGRAPH + {0xE39A, 0x92A1}, //17299 #CJK UNIFIED IDEOGRAPH + {0xE39B, 0x92A2}, //17300 #CJK UNIFIED IDEOGRAPH + {0xE39C, 0x92A3}, //17301 #CJK UNIFIED IDEOGRAPH + {0xE39D, 0x92A4}, //17302 #CJK UNIFIED IDEOGRAPH + {0xE39E, 0x92A5}, //17303 #CJK UNIFIED IDEOGRAPH + {0xE39F, 0x92A6}, //17304 #CJK UNIFIED IDEOGRAPH + {0xE3A0, 0x92A7}, //17305 #CJK UNIFIED IDEOGRAPH + {0xE3A1, 0x606A}, //17306 #CJK UNIFIED IDEOGRAPH + {0xE3A2, 0x607D}, //17307 #CJK UNIFIED IDEOGRAPH + {0xE3A3, 0x6096}, //17308 #CJK UNIFIED IDEOGRAPH + {0xE3A4, 0x609A}, //17309 #CJK UNIFIED IDEOGRAPH + {0xE3A5, 0x60AD}, //17310 #CJK UNIFIED IDEOGRAPH + {0xE3A6, 0x609D}, //17311 #CJK UNIFIED IDEOGRAPH + {0xE3A7, 0x6083}, //17312 #CJK UNIFIED IDEOGRAPH + {0xE3A8, 0x6092}, //17313 #CJK UNIFIED IDEOGRAPH + {0xE3A9, 0x608C}, //17314 #CJK UNIFIED IDEOGRAPH + {0xE3AA, 0x609B}, //17315 #CJK UNIFIED IDEOGRAPH + {0xE3AB, 0x60EC}, //17316 #CJK UNIFIED IDEOGRAPH + {0xE3AC, 0x60BB}, //17317 #CJK UNIFIED IDEOGRAPH + {0xE3AD, 0x60B1}, //17318 #CJK UNIFIED IDEOGRAPH + {0xE3AE, 0x60DD}, //17319 #CJK UNIFIED IDEOGRAPH + {0xE3AF, 0x60D8}, //17320 #CJK UNIFIED IDEOGRAPH + {0xE3B0, 0x60C6}, //17321 #CJK UNIFIED IDEOGRAPH + {0xE3B1, 0x60DA}, //17322 #CJK UNIFIED IDEOGRAPH + {0xE3B2, 0x60B4}, //17323 #CJK UNIFIED IDEOGRAPH + {0xE3B3, 0x6120}, //17324 #CJK UNIFIED IDEOGRAPH + {0xE3B4, 0x6126}, //17325 #CJK UNIFIED IDEOGRAPH + {0xE3B5, 0x6115}, //17326 #CJK UNIFIED IDEOGRAPH + {0xE3B6, 0x6123}, //17327 #CJK UNIFIED IDEOGRAPH + {0xE3B7, 0x60F4}, //17328 #CJK UNIFIED IDEOGRAPH + {0xE3B8, 0x6100}, //17329 #CJK UNIFIED IDEOGRAPH + {0xE3B9, 0x610E}, //17330 #CJK UNIFIED IDEOGRAPH + {0xE3BA, 0x612B}, //17331 #CJK UNIFIED IDEOGRAPH + {0xE3BB, 0x614A}, //17332 #CJK UNIFIED IDEOGRAPH + {0xE3BC, 0x6175}, //17333 #CJK UNIFIED IDEOGRAPH + {0xE3BD, 0x61AC}, //17334 #CJK UNIFIED IDEOGRAPH + {0xE3BE, 0x6194}, //17335 #CJK UNIFIED IDEOGRAPH + {0xE3BF, 0x61A7}, //17336 #CJK UNIFIED IDEOGRAPH + {0xE3C0, 0x61B7}, //17337 #CJK UNIFIED IDEOGRAPH + {0xE3C1, 0x61D4}, //17338 #CJK UNIFIED IDEOGRAPH + {0xE3C2, 0x61F5}, //17339 #CJK UNIFIED IDEOGRAPH + {0xE3C3, 0x5FDD}, //17340 #CJK UNIFIED IDEOGRAPH + {0xE3C4, 0x96B3}, //17341 #CJK UNIFIED IDEOGRAPH + {0xE3C5, 0x95E9}, //17342 #CJK UNIFIED IDEOGRAPH + {0xE3C6, 0x95EB}, //17343 #CJK UNIFIED IDEOGRAPH + {0xE3C7, 0x95F1}, //17344 #CJK UNIFIED IDEOGRAPH + {0xE3C8, 0x95F3}, //17345 #CJK UNIFIED IDEOGRAPH + {0xE3C9, 0x95F5}, //17346 #CJK UNIFIED IDEOGRAPH + {0xE3CA, 0x95F6}, //17347 #CJK UNIFIED IDEOGRAPH + {0xE3CB, 0x95FC}, //17348 #CJK UNIFIED IDEOGRAPH + {0xE3CC, 0x95FE}, //17349 #CJK UNIFIED IDEOGRAPH + {0xE3CD, 0x9603}, //17350 #CJK UNIFIED IDEOGRAPH + {0xE3CE, 0x9604}, //17351 #CJK UNIFIED IDEOGRAPH + {0xE3CF, 0x9606}, //17352 #CJK UNIFIED IDEOGRAPH + {0xE3D0, 0x9608}, //17353 #CJK UNIFIED IDEOGRAPH + {0xE3D1, 0x960A}, //17354 #CJK UNIFIED IDEOGRAPH + {0xE3D2, 0x960B}, //17355 #CJK UNIFIED IDEOGRAPH + {0xE3D3, 0x960C}, //17356 #CJK UNIFIED IDEOGRAPH + {0xE3D4, 0x960D}, //17357 #CJK UNIFIED IDEOGRAPH + {0xE3D5, 0x960F}, //17358 #CJK UNIFIED IDEOGRAPH + {0xE3D6, 0x9612}, //17359 #CJK UNIFIED IDEOGRAPH + {0xE3D7, 0x9615}, //17360 #CJK UNIFIED IDEOGRAPH + {0xE3D8, 0x9616}, //17361 #CJK UNIFIED IDEOGRAPH + {0xE3D9, 0x9617}, //17362 #CJK UNIFIED IDEOGRAPH + {0xE3DA, 0x9619}, //17363 #CJK UNIFIED IDEOGRAPH + {0xE3DB, 0x961A}, //17364 #CJK UNIFIED IDEOGRAPH + {0xE3DC, 0x4E2C}, //17365 #CJK UNIFIED IDEOGRAPH + {0xE3DD, 0x723F}, //17366 #CJK UNIFIED IDEOGRAPH + {0xE3DE, 0x6215}, //17367 #CJK UNIFIED IDEOGRAPH + {0xE3DF, 0x6C35}, //17368 #CJK UNIFIED IDEOGRAPH + {0xE3E0, 0x6C54}, //17369 #CJK UNIFIED IDEOGRAPH + {0xE3E1, 0x6C5C}, //17370 #CJK UNIFIED IDEOGRAPH + {0xE3E2, 0x6C4A}, //17371 #CJK UNIFIED IDEOGRAPH + {0xE3E3, 0x6CA3}, //17372 #CJK UNIFIED IDEOGRAPH + {0xE3E4, 0x6C85}, //17373 #CJK UNIFIED IDEOGRAPH + {0xE3E5, 0x6C90}, //17374 #CJK UNIFIED IDEOGRAPH + {0xE3E6, 0x6C94}, //17375 #CJK UNIFIED IDEOGRAPH + {0xE3E7, 0x6C8C}, //17376 #CJK UNIFIED IDEOGRAPH + {0xE3E8, 0x6C68}, //17377 #CJK UNIFIED IDEOGRAPH + {0xE3E9, 0x6C69}, //17378 #CJK UNIFIED IDEOGRAPH + {0xE3EA, 0x6C74}, //17379 #CJK UNIFIED IDEOGRAPH + {0xE3EB, 0x6C76}, //17380 #CJK UNIFIED IDEOGRAPH + {0xE3EC, 0x6C86}, //17381 #CJK UNIFIED IDEOGRAPH + {0xE3ED, 0x6CA9}, //17382 #CJK UNIFIED IDEOGRAPH + {0xE3EE, 0x6CD0}, //17383 #CJK UNIFIED IDEOGRAPH + {0xE3EF, 0x6CD4}, //17384 #CJK UNIFIED IDEOGRAPH + {0xE3F0, 0x6CAD}, //17385 #CJK UNIFIED IDEOGRAPH + {0xE3F1, 0x6CF7}, //17386 #CJK UNIFIED IDEOGRAPH + {0xE3F2, 0x6CF8}, //17387 #CJK UNIFIED IDEOGRAPH + {0xE3F3, 0x6CF1}, //17388 #CJK UNIFIED IDEOGRAPH + {0xE3F4, 0x6CD7}, //17389 #CJK UNIFIED IDEOGRAPH + {0xE3F5, 0x6CB2}, //17390 #CJK UNIFIED IDEOGRAPH + {0xE3F6, 0x6CE0}, //17391 #CJK UNIFIED IDEOGRAPH + {0xE3F7, 0x6CD6}, //17392 #CJK UNIFIED IDEOGRAPH + {0xE3F8, 0x6CFA}, //17393 #CJK UNIFIED IDEOGRAPH + {0xE3F9, 0x6CEB}, //17394 #CJK UNIFIED IDEOGRAPH + {0xE3FA, 0x6CEE}, //17395 #CJK UNIFIED IDEOGRAPH + {0xE3FB, 0x6CB1}, //17396 #CJK UNIFIED IDEOGRAPH + {0xE3FC, 0x6CD3}, //17397 #CJK UNIFIED IDEOGRAPH + {0xE3FD, 0x6CEF}, //17398 #CJK UNIFIED IDEOGRAPH + {0xE3FE, 0x6CFE}, //17399 #CJK UNIFIED IDEOGRAPH + {0xE440, 0x92A8}, //17400 #CJK UNIFIED IDEOGRAPH + {0xE441, 0x92A9}, //17401 #CJK UNIFIED IDEOGRAPH + {0xE442, 0x92AA}, //17402 #CJK UNIFIED IDEOGRAPH + {0xE443, 0x92AB}, //17403 #CJK UNIFIED IDEOGRAPH + {0xE444, 0x92AC}, //17404 #CJK UNIFIED IDEOGRAPH + {0xE445, 0x92AD}, //17405 #CJK UNIFIED IDEOGRAPH + {0xE446, 0x92AF}, //17406 #CJK UNIFIED IDEOGRAPH + {0xE447, 0x92B0}, //17407 #CJK UNIFIED IDEOGRAPH + {0xE448, 0x92B1}, //17408 #CJK UNIFIED IDEOGRAPH + {0xE449, 0x92B2}, //17409 #CJK UNIFIED IDEOGRAPH + {0xE44A, 0x92B3}, //17410 #CJK UNIFIED IDEOGRAPH + {0xE44B, 0x92B4}, //17411 #CJK UNIFIED IDEOGRAPH + {0xE44C, 0x92B5}, //17412 #CJK UNIFIED IDEOGRAPH + {0xE44D, 0x92B6}, //17413 #CJK UNIFIED IDEOGRAPH + {0xE44E, 0x92B7}, //17414 #CJK UNIFIED IDEOGRAPH + {0xE44F, 0x92B8}, //17415 #CJK UNIFIED IDEOGRAPH + {0xE450, 0x92B9}, //17416 #CJK UNIFIED IDEOGRAPH + {0xE451, 0x92BA}, //17417 #CJK UNIFIED IDEOGRAPH + {0xE452, 0x92BB}, //17418 #CJK UNIFIED IDEOGRAPH + {0xE453, 0x92BC}, //17419 #CJK UNIFIED IDEOGRAPH + {0xE454, 0x92BD}, //17420 #CJK UNIFIED IDEOGRAPH + {0xE455, 0x92BE}, //17421 #CJK UNIFIED IDEOGRAPH + {0xE456, 0x92BF}, //17422 #CJK UNIFIED IDEOGRAPH + {0xE457, 0x92C0}, //17423 #CJK UNIFIED IDEOGRAPH + {0xE458, 0x92C1}, //17424 #CJK UNIFIED IDEOGRAPH + {0xE459, 0x92C2}, //17425 #CJK UNIFIED IDEOGRAPH + {0xE45A, 0x92C3}, //17426 #CJK UNIFIED IDEOGRAPH + {0xE45B, 0x92C4}, //17427 #CJK UNIFIED IDEOGRAPH + {0xE45C, 0x92C5}, //17428 #CJK UNIFIED IDEOGRAPH + {0xE45D, 0x92C6}, //17429 #CJK UNIFIED IDEOGRAPH + {0xE45E, 0x92C7}, //17430 #CJK UNIFIED IDEOGRAPH + {0xE45F, 0x92C9}, //17431 #CJK UNIFIED IDEOGRAPH + {0xE460, 0x92CA}, //17432 #CJK UNIFIED IDEOGRAPH + {0xE461, 0x92CB}, //17433 #CJK UNIFIED IDEOGRAPH + {0xE462, 0x92CC}, //17434 #CJK UNIFIED IDEOGRAPH + {0xE463, 0x92CD}, //17435 #CJK UNIFIED IDEOGRAPH + {0xE464, 0x92CE}, //17436 #CJK UNIFIED IDEOGRAPH + {0xE465, 0x92CF}, //17437 #CJK UNIFIED IDEOGRAPH + {0xE466, 0x92D0}, //17438 #CJK UNIFIED IDEOGRAPH + {0xE467, 0x92D1}, //17439 #CJK UNIFIED IDEOGRAPH + {0xE468, 0x92D2}, //17440 #CJK UNIFIED IDEOGRAPH + {0xE469, 0x92D3}, //17441 #CJK UNIFIED IDEOGRAPH + {0xE46A, 0x92D4}, //17442 #CJK UNIFIED IDEOGRAPH + {0xE46B, 0x92D5}, //17443 #CJK UNIFIED IDEOGRAPH + {0xE46C, 0x92D6}, //17444 #CJK UNIFIED IDEOGRAPH + {0xE46D, 0x92D7}, //17445 #CJK UNIFIED IDEOGRAPH + {0xE46E, 0x92D8}, //17446 #CJK UNIFIED IDEOGRAPH + {0xE46F, 0x92D9}, //17447 #CJK UNIFIED IDEOGRAPH + {0xE470, 0x92DA}, //17448 #CJK UNIFIED IDEOGRAPH + {0xE471, 0x92DB}, //17449 #CJK UNIFIED IDEOGRAPH + {0xE472, 0x92DC}, //17450 #CJK UNIFIED IDEOGRAPH + {0xE473, 0x92DD}, //17451 #CJK UNIFIED IDEOGRAPH + {0xE474, 0x92DE}, //17452 #CJK UNIFIED IDEOGRAPH + {0xE475, 0x92DF}, //17453 #CJK UNIFIED IDEOGRAPH + {0xE476, 0x92E0}, //17454 #CJK UNIFIED IDEOGRAPH + {0xE477, 0x92E1}, //17455 #CJK UNIFIED IDEOGRAPH + {0xE478, 0x92E2}, //17456 #CJK UNIFIED IDEOGRAPH + {0xE479, 0x92E3}, //17457 #CJK UNIFIED IDEOGRAPH + {0xE47A, 0x92E4}, //17458 #CJK UNIFIED IDEOGRAPH + {0xE47B, 0x92E5}, //17459 #CJK UNIFIED IDEOGRAPH + {0xE47C, 0x92E6}, //17460 #CJK UNIFIED IDEOGRAPH + {0xE47D, 0x92E7}, //17461 #CJK UNIFIED IDEOGRAPH + {0xE47E, 0x92E8}, //17462 #CJK UNIFIED IDEOGRAPH + {0xE480, 0x92E9}, //17463 #CJK UNIFIED IDEOGRAPH + {0xE481, 0x92EA}, //17464 #CJK UNIFIED IDEOGRAPH + {0xE482, 0x92EB}, //17465 #CJK UNIFIED IDEOGRAPH + {0xE483, 0x92EC}, //17466 #CJK UNIFIED IDEOGRAPH + {0xE484, 0x92ED}, //17467 #CJK UNIFIED IDEOGRAPH + {0xE485, 0x92EE}, //17468 #CJK UNIFIED IDEOGRAPH + {0xE486, 0x92EF}, //17469 #CJK UNIFIED IDEOGRAPH + {0xE487, 0x92F0}, //17470 #CJK UNIFIED IDEOGRAPH + {0xE488, 0x92F1}, //17471 #CJK UNIFIED IDEOGRAPH + {0xE489, 0x92F2}, //17472 #CJK UNIFIED IDEOGRAPH + {0xE48A, 0x92F3}, //17473 #CJK UNIFIED IDEOGRAPH + {0xE48B, 0x92F4}, //17474 #CJK UNIFIED IDEOGRAPH + {0xE48C, 0x92F5}, //17475 #CJK UNIFIED IDEOGRAPH + {0xE48D, 0x92F6}, //17476 #CJK UNIFIED IDEOGRAPH + {0xE48E, 0x92F7}, //17477 #CJK UNIFIED IDEOGRAPH + {0xE48F, 0x92F8}, //17478 #CJK UNIFIED IDEOGRAPH + {0xE490, 0x92F9}, //17479 #CJK UNIFIED IDEOGRAPH + {0xE491, 0x92FA}, //17480 #CJK UNIFIED IDEOGRAPH + {0xE492, 0x92FB}, //17481 #CJK UNIFIED IDEOGRAPH + {0xE493, 0x92FC}, //17482 #CJK UNIFIED IDEOGRAPH + {0xE494, 0x92FD}, //17483 #CJK UNIFIED IDEOGRAPH + {0xE495, 0x92FE}, //17484 #CJK UNIFIED IDEOGRAPH + {0xE496, 0x92FF}, //17485 #CJK UNIFIED IDEOGRAPH + {0xE497, 0x9300}, //17486 #CJK UNIFIED IDEOGRAPH + {0xE498, 0x9301}, //17487 #CJK UNIFIED IDEOGRAPH + {0xE499, 0x9302}, //17488 #CJK UNIFIED IDEOGRAPH + {0xE49A, 0x9303}, //17489 #CJK UNIFIED IDEOGRAPH + {0xE49B, 0x9304}, //17490 #CJK UNIFIED IDEOGRAPH + {0xE49C, 0x9305}, //17491 #CJK UNIFIED IDEOGRAPH + {0xE49D, 0x9306}, //17492 #CJK UNIFIED IDEOGRAPH + {0xE49E, 0x9307}, //17493 #CJK UNIFIED IDEOGRAPH + {0xE49F, 0x9308}, //17494 #CJK UNIFIED IDEOGRAPH + {0xE4A0, 0x9309}, //17495 #CJK UNIFIED IDEOGRAPH + {0xE4A1, 0x6D39}, //17496 #CJK UNIFIED IDEOGRAPH + {0xE4A2, 0x6D27}, //17497 #CJK UNIFIED IDEOGRAPH + {0xE4A3, 0x6D0C}, //17498 #CJK UNIFIED IDEOGRAPH + {0xE4A4, 0x6D43}, //17499 #CJK UNIFIED IDEOGRAPH + {0xE4A5, 0x6D48}, //17500 #CJK UNIFIED IDEOGRAPH + {0xE4A6, 0x6D07}, //17501 #CJK UNIFIED IDEOGRAPH + {0xE4A7, 0x6D04}, //17502 #CJK UNIFIED IDEOGRAPH + {0xE4A8, 0x6D19}, //17503 #CJK UNIFIED IDEOGRAPH + {0xE4A9, 0x6D0E}, //17504 #CJK UNIFIED IDEOGRAPH + {0xE4AA, 0x6D2B}, //17505 #CJK UNIFIED IDEOGRAPH + {0xE4AB, 0x6D4D}, //17506 #CJK UNIFIED IDEOGRAPH + {0xE4AC, 0x6D2E}, //17507 #CJK UNIFIED IDEOGRAPH + {0xE4AD, 0x6D35}, //17508 #CJK UNIFIED IDEOGRAPH + {0xE4AE, 0x6D1A}, //17509 #CJK UNIFIED IDEOGRAPH + {0xE4AF, 0x6D4F}, //17510 #CJK UNIFIED IDEOGRAPH + {0xE4B0, 0x6D52}, //17511 #CJK UNIFIED IDEOGRAPH + {0xE4B1, 0x6D54}, //17512 #CJK UNIFIED IDEOGRAPH + {0xE4B2, 0x6D33}, //17513 #CJK UNIFIED IDEOGRAPH + {0xE4B3, 0x6D91}, //17514 #CJK UNIFIED IDEOGRAPH + {0xE4B4, 0x6D6F}, //17515 #CJK UNIFIED IDEOGRAPH + {0xE4B5, 0x6D9E}, //17516 #CJK UNIFIED IDEOGRAPH + {0xE4B6, 0x6DA0}, //17517 #CJK UNIFIED IDEOGRAPH + {0xE4B7, 0x6D5E}, //17518 #CJK UNIFIED IDEOGRAPH + {0xE4B8, 0x6D93}, //17519 #CJK UNIFIED IDEOGRAPH + {0xE4B9, 0x6D94}, //17520 #CJK UNIFIED IDEOGRAPH + {0xE4BA, 0x6D5C}, //17521 #CJK UNIFIED IDEOGRAPH + {0xE4BB, 0x6D60}, //17522 #CJK UNIFIED IDEOGRAPH + {0xE4BC, 0x6D7C}, //17523 #CJK UNIFIED IDEOGRAPH + {0xE4BD, 0x6D63}, //17524 #CJK UNIFIED IDEOGRAPH + {0xE4BE, 0x6E1A}, //17525 #CJK UNIFIED IDEOGRAPH + {0xE4BF, 0x6DC7}, //17526 #CJK UNIFIED IDEOGRAPH + {0xE4C0, 0x6DC5}, //17527 #CJK UNIFIED IDEOGRAPH + {0xE4C1, 0x6DDE}, //17528 #CJK UNIFIED IDEOGRAPH + {0xE4C2, 0x6E0E}, //17529 #CJK UNIFIED IDEOGRAPH + {0xE4C3, 0x6DBF}, //17530 #CJK UNIFIED IDEOGRAPH + {0xE4C4, 0x6DE0}, //17531 #CJK UNIFIED IDEOGRAPH + {0xE4C5, 0x6E11}, //17532 #CJK UNIFIED IDEOGRAPH + {0xE4C6, 0x6DE6}, //17533 #CJK UNIFIED IDEOGRAPH + {0xE4C7, 0x6DDD}, //17534 #CJK UNIFIED IDEOGRAPH + {0xE4C8, 0x6DD9}, //17535 #CJK UNIFIED IDEOGRAPH + {0xE4C9, 0x6E16}, //17536 #CJK UNIFIED IDEOGRAPH + {0xE4CA, 0x6DAB}, //17537 #CJK UNIFIED IDEOGRAPH + {0xE4CB, 0x6E0C}, //17538 #CJK UNIFIED IDEOGRAPH + {0xE4CC, 0x6DAE}, //17539 #CJK UNIFIED IDEOGRAPH + {0xE4CD, 0x6E2B}, //17540 #CJK UNIFIED IDEOGRAPH + {0xE4CE, 0x6E6E}, //17541 #CJK UNIFIED IDEOGRAPH + {0xE4CF, 0x6E4E}, //17542 #CJK UNIFIED IDEOGRAPH + {0xE4D0, 0x6E6B}, //17543 #CJK UNIFIED IDEOGRAPH + {0xE4D1, 0x6EB2}, //17544 #CJK UNIFIED IDEOGRAPH + {0xE4D2, 0x6E5F}, //17545 #CJK UNIFIED IDEOGRAPH + {0xE4D3, 0x6E86}, //17546 #CJK UNIFIED IDEOGRAPH + {0xE4D4, 0x6E53}, //17547 #CJK UNIFIED IDEOGRAPH + {0xE4D5, 0x6E54}, //17548 #CJK UNIFIED IDEOGRAPH + {0xE4D6, 0x6E32}, //17549 #CJK UNIFIED IDEOGRAPH + {0xE4D7, 0x6E25}, //17550 #CJK UNIFIED IDEOGRAPH + {0xE4D8, 0x6E44}, //17551 #CJK UNIFIED IDEOGRAPH + {0xE4D9, 0x6EDF}, //17552 #CJK UNIFIED IDEOGRAPH + {0xE4DA, 0x6EB1}, //17553 #CJK UNIFIED IDEOGRAPH + {0xE4DB, 0x6E98}, //17554 #CJK UNIFIED IDEOGRAPH + {0xE4DC, 0x6EE0}, //17555 #CJK UNIFIED IDEOGRAPH + {0xE4DD, 0x6F2D}, //17556 #CJK UNIFIED IDEOGRAPH + {0xE4DE, 0x6EE2}, //17557 #CJK UNIFIED IDEOGRAPH + {0xE4DF, 0x6EA5}, //17558 #CJK UNIFIED IDEOGRAPH + {0xE4E0, 0x6EA7}, //17559 #CJK UNIFIED IDEOGRAPH + {0xE4E1, 0x6EBD}, //17560 #CJK UNIFIED IDEOGRAPH + {0xE4E2, 0x6EBB}, //17561 #CJK UNIFIED IDEOGRAPH + {0xE4E3, 0x6EB7}, //17562 #CJK UNIFIED IDEOGRAPH + {0xE4E4, 0x6ED7}, //17563 #CJK UNIFIED IDEOGRAPH + {0xE4E5, 0x6EB4}, //17564 #CJK UNIFIED IDEOGRAPH + {0xE4E6, 0x6ECF}, //17565 #CJK UNIFIED IDEOGRAPH + {0xE4E7, 0x6E8F}, //17566 #CJK UNIFIED IDEOGRAPH + {0xE4E8, 0x6EC2}, //17567 #CJK UNIFIED IDEOGRAPH + {0xE4E9, 0x6E9F}, //17568 #CJK UNIFIED IDEOGRAPH + {0xE4EA, 0x6F62}, //17569 #CJK UNIFIED IDEOGRAPH + {0xE4EB, 0x6F46}, //17570 #CJK UNIFIED IDEOGRAPH + {0xE4EC, 0x6F47}, //17571 #CJK UNIFIED IDEOGRAPH + {0xE4ED, 0x6F24}, //17572 #CJK UNIFIED IDEOGRAPH + {0xE4EE, 0x6F15}, //17573 #CJK UNIFIED IDEOGRAPH + {0xE4EF, 0x6EF9}, //17574 #CJK UNIFIED IDEOGRAPH + {0xE4F0, 0x6F2F}, //17575 #CJK UNIFIED IDEOGRAPH + {0xE4F1, 0x6F36}, //17576 #CJK UNIFIED IDEOGRAPH + {0xE4F2, 0x6F4B}, //17577 #CJK UNIFIED IDEOGRAPH + {0xE4F3, 0x6F74}, //17578 #CJK UNIFIED IDEOGRAPH + {0xE4F4, 0x6F2A}, //17579 #CJK UNIFIED IDEOGRAPH + {0xE4F5, 0x6F09}, //17580 #CJK UNIFIED IDEOGRAPH + {0xE4F6, 0x6F29}, //17581 #CJK UNIFIED IDEOGRAPH + {0xE4F7, 0x6F89}, //17582 #CJK UNIFIED IDEOGRAPH + {0xE4F8, 0x6F8D}, //17583 #CJK UNIFIED IDEOGRAPH + {0xE4F9, 0x6F8C}, //17584 #CJK UNIFIED IDEOGRAPH + {0xE4FA, 0x6F78}, //17585 #CJK UNIFIED IDEOGRAPH + {0xE4FB, 0x6F72}, //17586 #CJK UNIFIED IDEOGRAPH + {0xE4FC, 0x6F7C}, //17587 #CJK UNIFIED IDEOGRAPH + {0xE4FD, 0x6F7A}, //17588 #CJK UNIFIED IDEOGRAPH + {0xE4FE, 0x6FD1}, //17589 #CJK UNIFIED IDEOGRAPH + {0xE540, 0x930A}, //17590 #CJK UNIFIED IDEOGRAPH + {0xE541, 0x930B}, //17591 #CJK UNIFIED IDEOGRAPH + {0xE542, 0x930C}, //17592 #CJK UNIFIED IDEOGRAPH + {0xE543, 0x930D}, //17593 #CJK UNIFIED IDEOGRAPH + {0xE544, 0x930E}, //17594 #CJK UNIFIED IDEOGRAPH + {0xE545, 0x930F}, //17595 #CJK UNIFIED IDEOGRAPH + {0xE546, 0x9310}, //17596 #CJK UNIFIED IDEOGRAPH + {0xE547, 0x9311}, //17597 #CJK UNIFIED IDEOGRAPH + {0xE548, 0x9312}, //17598 #CJK UNIFIED IDEOGRAPH + {0xE549, 0x9313}, //17599 #CJK UNIFIED IDEOGRAPH + {0xE54A, 0x9314}, //17600 #CJK UNIFIED IDEOGRAPH + {0xE54B, 0x9315}, //17601 #CJK UNIFIED IDEOGRAPH + {0xE54C, 0x9316}, //17602 #CJK UNIFIED IDEOGRAPH + {0xE54D, 0x9317}, //17603 #CJK UNIFIED IDEOGRAPH + {0xE54E, 0x9318}, //17604 #CJK UNIFIED IDEOGRAPH + {0xE54F, 0x9319}, //17605 #CJK UNIFIED IDEOGRAPH + {0xE550, 0x931A}, //17606 #CJK UNIFIED IDEOGRAPH + {0xE551, 0x931B}, //17607 #CJK UNIFIED IDEOGRAPH + {0xE552, 0x931C}, //17608 #CJK UNIFIED IDEOGRAPH + {0xE553, 0x931D}, //17609 #CJK UNIFIED IDEOGRAPH + {0xE554, 0x931E}, //17610 #CJK UNIFIED IDEOGRAPH + {0xE555, 0x931F}, //17611 #CJK UNIFIED IDEOGRAPH + {0xE556, 0x9320}, //17612 #CJK UNIFIED IDEOGRAPH + {0xE557, 0x9321}, //17613 #CJK UNIFIED IDEOGRAPH + {0xE558, 0x9322}, //17614 #CJK UNIFIED IDEOGRAPH + {0xE559, 0x9323}, //17615 #CJK UNIFIED IDEOGRAPH + {0xE55A, 0x9324}, //17616 #CJK UNIFIED IDEOGRAPH + {0xE55B, 0x9325}, //17617 #CJK UNIFIED IDEOGRAPH + {0xE55C, 0x9326}, //17618 #CJK UNIFIED IDEOGRAPH + {0xE55D, 0x9327}, //17619 #CJK UNIFIED IDEOGRAPH + {0xE55E, 0x9328}, //17620 #CJK UNIFIED IDEOGRAPH + {0xE55F, 0x9329}, //17621 #CJK UNIFIED IDEOGRAPH + {0xE560, 0x932A}, //17622 #CJK UNIFIED IDEOGRAPH + {0xE561, 0x932B}, //17623 #CJK UNIFIED IDEOGRAPH + {0xE562, 0x932C}, //17624 #CJK UNIFIED IDEOGRAPH + {0xE563, 0x932D}, //17625 #CJK UNIFIED IDEOGRAPH + {0xE564, 0x932E}, //17626 #CJK UNIFIED IDEOGRAPH + {0xE565, 0x932F}, //17627 #CJK UNIFIED IDEOGRAPH + {0xE566, 0x9330}, //17628 #CJK UNIFIED IDEOGRAPH + {0xE567, 0x9331}, //17629 #CJK UNIFIED IDEOGRAPH + {0xE568, 0x9332}, //17630 #CJK UNIFIED IDEOGRAPH + {0xE569, 0x9333}, //17631 #CJK UNIFIED IDEOGRAPH + {0xE56A, 0x9334}, //17632 #CJK UNIFIED IDEOGRAPH + {0xE56B, 0x9335}, //17633 #CJK UNIFIED IDEOGRAPH + {0xE56C, 0x9336}, //17634 #CJK UNIFIED IDEOGRAPH + {0xE56D, 0x9337}, //17635 #CJK UNIFIED IDEOGRAPH + {0xE56E, 0x9338}, //17636 #CJK UNIFIED IDEOGRAPH + {0xE56F, 0x9339}, //17637 #CJK UNIFIED IDEOGRAPH + {0xE570, 0x933A}, //17638 #CJK UNIFIED IDEOGRAPH + {0xE571, 0x933B}, //17639 #CJK UNIFIED IDEOGRAPH + {0xE572, 0x933C}, //17640 #CJK UNIFIED IDEOGRAPH + {0xE573, 0x933D}, //17641 #CJK UNIFIED IDEOGRAPH + {0xE574, 0x933F}, //17642 #CJK UNIFIED IDEOGRAPH + {0xE575, 0x9340}, //17643 #CJK UNIFIED IDEOGRAPH + {0xE576, 0x9341}, //17644 #CJK UNIFIED IDEOGRAPH + {0xE577, 0x9342}, //17645 #CJK UNIFIED IDEOGRAPH + {0xE578, 0x9343}, //17646 #CJK UNIFIED IDEOGRAPH + {0xE579, 0x9344}, //17647 #CJK UNIFIED IDEOGRAPH + {0xE57A, 0x9345}, //17648 #CJK UNIFIED IDEOGRAPH + {0xE57B, 0x9346}, //17649 #CJK UNIFIED IDEOGRAPH + {0xE57C, 0x9347}, //17650 #CJK UNIFIED IDEOGRAPH + {0xE57D, 0x9348}, //17651 #CJK UNIFIED IDEOGRAPH + {0xE57E, 0x9349}, //17652 #CJK UNIFIED IDEOGRAPH + {0xE580, 0x934A}, //17653 #CJK UNIFIED IDEOGRAPH + {0xE581, 0x934B}, //17654 #CJK UNIFIED IDEOGRAPH + {0xE582, 0x934C}, //17655 #CJK UNIFIED IDEOGRAPH + {0xE583, 0x934D}, //17656 #CJK UNIFIED IDEOGRAPH + {0xE584, 0x934E}, //17657 #CJK UNIFIED IDEOGRAPH + {0xE585, 0x934F}, //17658 #CJK UNIFIED IDEOGRAPH + {0xE586, 0x9350}, //17659 #CJK UNIFIED IDEOGRAPH + {0xE587, 0x9351}, //17660 #CJK UNIFIED IDEOGRAPH + {0xE588, 0x9352}, //17661 #CJK UNIFIED IDEOGRAPH + {0xE589, 0x9353}, //17662 #CJK UNIFIED IDEOGRAPH + {0xE58A, 0x9354}, //17663 #CJK UNIFIED IDEOGRAPH + {0xE58B, 0x9355}, //17664 #CJK UNIFIED IDEOGRAPH + {0xE58C, 0x9356}, //17665 #CJK UNIFIED IDEOGRAPH + {0xE58D, 0x9357}, //17666 #CJK UNIFIED IDEOGRAPH + {0xE58E, 0x9358}, //17667 #CJK UNIFIED IDEOGRAPH + {0xE58F, 0x9359}, //17668 #CJK UNIFIED IDEOGRAPH + {0xE590, 0x935A}, //17669 #CJK UNIFIED IDEOGRAPH + {0xE591, 0x935B}, //17670 #CJK UNIFIED IDEOGRAPH + {0xE592, 0x935C}, //17671 #CJK UNIFIED IDEOGRAPH + {0xE593, 0x935D}, //17672 #CJK UNIFIED IDEOGRAPH + {0xE594, 0x935E}, //17673 #CJK UNIFIED IDEOGRAPH + {0xE595, 0x935F}, //17674 #CJK UNIFIED IDEOGRAPH + {0xE596, 0x9360}, //17675 #CJK UNIFIED IDEOGRAPH + {0xE597, 0x9361}, //17676 #CJK UNIFIED IDEOGRAPH + {0xE598, 0x9362}, //17677 #CJK UNIFIED IDEOGRAPH + {0xE599, 0x9363}, //17678 #CJK UNIFIED IDEOGRAPH + {0xE59A, 0x9364}, //17679 #CJK UNIFIED IDEOGRAPH + {0xE59B, 0x9365}, //17680 #CJK UNIFIED IDEOGRAPH + {0xE59C, 0x9366}, //17681 #CJK UNIFIED IDEOGRAPH + {0xE59D, 0x9367}, //17682 #CJK UNIFIED IDEOGRAPH + {0xE59E, 0x9368}, //17683 #CJK UNIFIED IDEOGRAPH + {0xE59F, 0x9369}, //17684 #CJK UNIFIED IDEOGRAPH + {0xE5A0, 0x936B}, //17685 #CJK UNIFIED IDEOGRAPH + {0xE5A1, 0x6FC9}, //17686 #CJK UNIFIED IDEOGRAPH + {0xE5A2, 0x6FA7}, //17687 #CJK UNIFIED IDEOGRAPH + {0xE5A3, 0x6FB9}, //17688 #CJK UNIFIED IDEOGRAPH + {0xE5A4, 0x6FB6}, //17689 #CJK UNIFIED IDEOGRAPH + {0xE5A5, 0x6FC2}, //17690 #CJK UNIFIED IDEOGRAPH + {0xE5A6, 0x6FE1}, //17691 #CJK UNIFIED IDEOGRAPH + {0xE5A7, 0x6FEE}, //17692 #CJK UNIFIED IDEOGRAPH + {0xE5A8, 0x6FDE}, //17693 #CJK UNIFIED IDEOGRAPH + {0xE5A9, 0x6FE0}, //17694 #CJK UNIFIED IDEOGRAPH + {0xE5AA, 0x6FEF}, //17695 #CJK UNIFIED IDEOGRAPH + {0xE5AB, 0x701A}, //17696 #CJK UNIFIED IDEOGRAPH + {0xE5AC, 0x7023}, //17697 #CJK UNIFIED IDEOGRAPH + {0xE5AD, 0x701B}, //17698 #CJK UNIFIED IDEOGRAPH + {0xE5AE, 0x7039}, //17699 #CJK UNIFIED IDEOGRAPH + {0xE5AF, 0x7035}, //17700 #CJK UNIFIED IDEOGRAPH + {0xE5B0, 0x704F}, //17701 #CJK UNIFIED IDEOGRAPH + {0xE5B1, 0x705E}, //17702 #CJK UNIFIED IDEOGRAPH + {0xE5B2, 0x5B80}, //17703 #CJK UNIFIED IDEOGRAPH + {0xE5B3, 0x5B84}, //17704 #CJK UNIFIED IDEOGRAPH + {0xE5B4, 0x5B95}, //17705 #CJK UNIFIED IDEOGRAPH + {0xE5B5, 0x5B93}, //17706 #CJK UNIFIED IDEOGRAPH + {0xE5B6, 0x5BA5}, //17707 #CJK UNIFIED IDEOGRAPH + {0xE5B7, 0x5BB8}, //17708 #CJK UNIFIED IDEOGRAPH + {0xE5B8, 0x752F}, //17709 #CJK UNIFIED IDEOGRAPH + {0xE5B9, 0x9A9E}, //17710 #CJK UNIFIED IDEOGRAPH + {0xE5BA, 0x6434}, //17711 #CJK UNIFIED IDEOGRAPH + {0xE5BB, 0x5BE4}, //17712 #CJK UNIFIED IDEOGRAPH + {0xE5BC, 0x5BEE}, //17713 #CJK UNIFIED IDEOGRAPH + {0xE5BD, 0x8930}, //17714 #CJK UNIFIED IDEOGRAPH + {0xE5BE, 0x5BF0}, //17715 #CJK UNIFIED IDEOGRAPH + {0xE5BF, 0x8E47}, //17716 #CJK UNIFIED IDEOGRAPH + {0xE5C0, 0x8B07}, //17717 #CJK UNIFIED IDEOGRAPH + {0xE5C1, 0x8FB6}, //17718 #CJK UNIFIED IDEOGRAPH + {0xE5C2, 0x8FD3}, //17719 #CJK UNIFIED IDEOGRAPH + {0xE5C3, 0x8FD5}, //17720 #CJK UNIFIED IDEOGRAPH + {0xE5C4, 0x8FE5}, //17721 #CJK UNIFIED IDEOGRAPH + {0xE5C5, 0x8FEE}, //17722 #CJK UNIFIED IDEOGRAPH + {0xE5C6, 0x8FE4}, //17723 #CJK UNIFIED IDEOGRAPH + {0xE5C7, 0x8FE9}, //17724 #CJK UNIFIED IDEOGRAPH + {0xE5C8, 0x8FE6}, //17725 #CJK UNIFIED IDEOGRAPH + {0xE5C9, 0x8FF3}, //17726 #CJK UNIFIED IDEOGRAPH + {0xE5CA, 0x8FE8}, //17727 #CJK UNIFIED IDEOGRAPH + {0xE5CB, 0x9005}, //17728 #CJK UNIFIED IDEOGRAPH + {0xE5CC, 0x9004}, //17729 #CJK UNIFIED IDEOGRAPH + {0xE5CD, 0x900B}, //17730 #CJK UNIFIED IDEOGRAPH + {0xE5CE, 0x9026}, //17731 #CJK UNIFIED IDEOGRAPH + {0xE5CF, 0x9011}, //17732 #CJK UNIFIED IDEOGRAPH + {0xE5D0, 0x900D}, //17733 #CJK UNIFIED IDEOGRAPH + {0xE5D1, 0x9016}, //17734 #CJK UNIFIED IDEOGRAPH + {0xE5D2, 0x9021}, //17735 #CJK UNIFIED IDEOGRAPH + {0xE5D3, 0x9035}, //17736 #CJK UNIFIED IDEOGRAPH + {0xE5D4, 0x9036}, //17737 #CJK UNIFIED IDEOGRAPH + {0xE5D5, 0x902D}, //17738 #CJK UNIFIED IDEOGRAPH + {0xE5D6, 0x902F}, //17739 #CJK UNIFIED IDEOGRAPH + {0xE5D7, 0x9044}, //17740 #CJK UNIFIED IDEOGRAPH + {0xE5D8, 0x9051}, //17741 #CJK UNIFIED IDEOGRAPH + {0xE5D9, 0x9052}, //17742 #CJK UNIFIED IDEOGRAPH + {0xE5DA, 0x9050}, //17743 #CJK UNIFIED IDEOGRAPH + {0xE5DB, 0x9068}, //17744 #CJK UNIFIED IDEOGRAPH + {0xE5DC, 0x9058}, //17745 #CJK UNIFIED IDEOGRAPH + {0xE5DD, 0x9062}, //17746 #CJK UNIFIED IDEOGRAPH + {0xE5DE, 0x905B}, //17747 #CJK UNIFIED IDEOGRAPH + {0xE5DF, 0x66B9}, //17748 #CJK UNIFIED IDEOGRAPH + {0xE5E0, 0x9074}, //17749 #CJK UNIFIED IDEOGRAPH + {0xE5E1, 0x907D}, //17750 #CJK UNIFIED IDEOGRAPH + {0xE5E2, 0x9082}, //17751 #CJK UNIFIED IDEOGRAPH + {0xE5E3, 0x9088}, //17752 #CJK UNIFIED IDEOGRAPH + {0xE5E4, 0x9083}, //17753 #CJK UNIFIED IDEOGRAPH + {0xE5E5, 0x908B}, //17754 #CJK UNIFIED IDEOGRAPH + {0xE5E6, 0x5F50}, //17755 #CJK UNIFIED IDEOGRAPH + {0xE5E7, 0x5F57}, //17756 #CJK UNIFIED IDEOGRAPH + {0xE5E8, 0x5F56}, //17757 #CJK UNIFIED IDEOGRAPH + {0xE5E9, 0x5F58}, //17758 #CJK UNIFIED IDEOGRAPH + {0xE5EA, 0x5C3B}, //17759 #CJK UNIFIED IDEOGRAPH + {0xE5EB, 0x54AB}, //17760 #CJK UNIFIED IDEOGRAPH + {0xE5EC, 0x5C50}, //17761 #CJK UNIFIED IDEOGRAPH + {0xE5ED, 0x5C59}, //17762 #CJK UNIFIED IDEOGRAPH + {0xE5EE, 0x5B71}, //17763 #CJK UNIFIED IDEOGRAPH + {0xE5EF, 0x5C63}, //17764 #CJK UNIFIED IDEOGRAPH + {0xE5F0, 0x5C66}, //17765 #CJK UNIFIED IDEOGRAPH + {0xE5F1, 0x7FBC}, //17766 #CJK UNIFIED IDEOGRAPH + {0xE5F2, 0x5F2A}, //17767 #CJK UNIFIED IDEOGRAPH + {0xE5F3, 0x5F29}, //17768 #CJK UNIFIED IDEOGRAPH + {0xE5F4, 0x5F2D}, //17769 #CJK UNIFIED IDEOGRAPH + {0xE5F5, 0x8274}, //17770 #CJK UNIFIED IDEOGRAPH + {0xE5F6, 0x5F3C}, //17771 #CJK UNIFIED IDEOGRAPH + {0xE5F7, 0x9B3B}, //17772 #CJK UNIFIED IDEOGRAPH + {0xE5F8, 0x5C6E}, //17773 #CJK UNIFIED IDEOGRAPH + {0xE5F9, 0x5981}, //17774 #CJK UNIFIED IDEOGRAPH + {0xE5FA, 0x5983}, //17775 #CJK UNIFIED IDEOGRAPH + {0xE5FB, 0x598D}, //17776 #CJK UNIFIED IDEOGRAPH + {0xE5FC, 0x59A9}, //17777 #CJK UNIFIED IDEOGRAPH + {0xE5FD, 0x59AA}, //17778 #CJK UNIFIED IDEOGRAPH + {0xE5FE, 0x59A3}, //17779 #CJK UNIFIED IDEOGRAPH + {0xE640, 0x936C}, //17780 #CJK UNIFIED IDEOGRAPH + {0xE641, 0x936D}, //17781 #CJK UNIFIED IDEOGRAPH + {0xE642, 0x936E}, //17782 #CJK UNIFIED IDEOGRAPH + {0xE643, 0x936F}, //17783 #CJK UNIFIED IDEOGRAPH + {0xE644, 0x9370}, //17784 #CJK UNIFIED IDEOGRAPH + {0xE645, 0x9371}, //17785 #CJK UNIFIED IDEOGRAPH + {0xE646, 0x9372}, //17786 #CJK UNIFIED IDEOGRAPH + {0xE647, 0x9373}, //17787 #CJK UNIFIED IDEOGRAPH + {0xE648, 0x9374}, //17788 #CJK UNIFIED IDEOGRAPH + {0xE649, 0x9375}, //17789 #CJK UNIFIED IDEOGRAPH + {0xE64A, 0x9376}, //17790 #CJK UNIFIED IDEOGRAPH + {0xE64B, 0x9377}, //17791 #CJK UNIFIED IDEOGRAPH + {0xE64C, 0x9378}, //17792 #CJK UNIFIED IDEOGRAPH + {0xE64D, 0x9379}, //17793 #CJK UNIFIED IDEOGRAPH + {0xE64E, 0x937A}, //17794 #CJK UNIFIED IDEOGRAPH + {0xE64F, 0x937B}, //17795 #CJK UNIFIED IDEOGRAPH + {0xE650, 0x937C}, //17796 #CJK UNIFIED IDEOGRAPH + {0xE651, 0x937D}, //17797 #CJK UNIFIED IDEOGRAPH + {0xE652, 0x937E}, //17798 #CJK UNIFIED IDEOGRAPH + {0xE653, 0x937F}, //17799 #CJK UNIFIED IDEOGRAPH + {0xE654, 0x9380}, //17800 #CJK UNIFIED IDEOGRAPH + {0xE655, 0x9381}, //17801 #CJK UNIFIED IDEOGRAPH + {0xE656, 0x9382}, //17802 #CJK UNIFIED IDEOGRAPH + {0xE657, 0x9383}, //17803 #CJK UNIFIED IDEOGRAPH + {0xE658, 0x9384}, //17804 #CJK UNIFIED IDEOGRAPH + {0xE659, 0x9385}, //17805 #CJK UNIFIED IDEOGRAPH + {0xE65A, 0x9386}, //17806 #CJK UNIFIED IDEOGRAPH + {0xE65B, 0x9387}, //17807 #CJK UNIFIED IDEOGRAPH + {0xE65C, 0x9388}, //17808 #CJK UNIFIED IDEOGRAPH + {0xE65D, 0x9389}, //17809 #CJK UNIFIED IDEOGRAPH + {0xE65E, 0x938A}, //17810 #CJK UNIFIED IDEOGRAPH + {0xE65F, 0x938B}, //17811 #CJK UNIFIED IDEOGRAPH + {0xE660, 0x938C}, //17812 #CJK UNIFIED IDEOGRAPH + {0xE661, 0x938D}, //17813 #CJK UNIFIED IDEOGRAPH + {0xE662, 0x938E}, //17814 #CJK UNIFIED IDEOGRAPH + {0xE663, 0x9390}, //17815 #CJK UNIFIED IDEOGRAPH + {0xE664, 0x9391}, //17816 #CJK UNIFIED IDEOGRAPH + {0xE665, 0x9392}, //17817 #CJK UNIFIED IDEOGRAPH + {0xE666, 0x9393}, //17818 #CJK UNIFIED IDEOGRAPH + {0xE667, 0x9394}, //17819 #CJK UNIFIED IDEOGRAPH + {0xE668, 0x9395}, //17820 #CJK UNIFIED IDEOGRAPH + {0xE669, 0x9396}, //17821 #CJK UNIFIED IDEOGRAPH + {0xE66A, 0x9397}, //17822 #CJK UNIFIED IDEOGRAPH + {0xE66B, 0x9398}, //17823 #CJK UNIFIED IDEOGRAPH + {0xE66C, 0x9399}, //17824 #CJK UNIFIED IDEOGRAPH + {0xE66D, 0x939A}, //17825 #CJK UNIFIED IDEOGRAPH + {0xE66E, 0x939B}, //17826 #CJK UNIFIED IDEOGRAPH + {0xE66F, 0x939C}, //17827 #CJK UNIFIED IDEOGRAPH + {0xE670, 0x939D}, //17828 #CJK UNIFIED IDEOGRAPH + {0xE671, 0x939E}, //17829 #CJK UNIFIED IDEOGRAPH + {0xE672, 0x939F}, //17830 #CJK UNIFIED IDEOGRAPH + {0xE673, 0x93A0}, //17831 #CJK UNIFIED IDEOGRAPH + {0xE674, 0x93A1}, //17832 #CJK UNIFIED IDEOGRAPH + {0xE675, 0x93A2}, //17833 #CJK UNIFIED IDEOGRAPH + {0xE676, 0x93A3}, //17834 #CJK UNIFIED IDEOGRAPH + {0xE677, 0x93A4}, //17835 #CJK UNIFIED IDEOGRAPH + {0xE678, 0x93A5}, //17836 #CJK UNIFIED IDEOGRAPH + {0xE679, 0x93A6}, //17837 #CJK UNIFIED IDEOGRAPH + {0xE67A, 0x93A7}, //17838 #CJK UNIFIED IDEOGRAPH + {0xE67B, 0x93A8}, //17839 #CJK UNIFIED IDEOGRAPH + {0xE67C, 0x93A9}, //17840 #CJK UNIFIED IDEOGRAPH + {0xE67D, 0x93AA}, //17841 #CJK UNIFIED IDEOGRAPH + {0xE67E, 0x93AB}, //17842 #CJK UNIFIED IDEOGRAPH + {0xE680, 0x93AC}, //17843 #CJK UNIFIED IDEOGRAPH + {0xE681, 0x93AD}, //17844 #CJK UNIFIED IDEOGRAPH + {0xE682, 0x93AE}, //17845 #CJK UNIFIED IDEOGRAPH + {0xE683, 0x93AF}, //17846 #CJK UNIFIED IDEOGRAPH + {0xE684, 0x93B0}, //17847 #CJK UNIFIED IDEOGRAPH + {0xE685, 0x93B1}, //17848 #CJK UNIFIED IDEOGRAPH + {0xE686, 0x93B2}, //17849 #CJK UNIFIED IDEOGRAPH + {0xE687, 0x93B3}, //17850 #CJK UNIFIED IDEOGRAPH + {0xE688, 0x93B4}, //17851 #CJK UNIFIED IDEOGRAPH + {0xE689, 0x93B5}, //17852 #CJK UNIFIED IDEOGRAPH + {0xE68A, 0x93B6}, //17853 #CJK UNIFIED IDEOGRAPH + {0xE68B, 0x93B7}, //17854 #CJK UNIFIED IDEOGRAPH + {0xE68C, 0x93B8}, //17855 #CJK UNIFIED IDEOGRAPH + {0xE68D, 0x93B9}, //17856 #CJK UNIFIED IDEOGRAPH + {0xE68E, 0x93BA}, //17857 #CJK UNIFIED IDEOGRAPH + {0xE68F, 0x93BB}, //17858 #CJK UNIFIED IDEOGRAPH + {0xE690, 0x93BC}, //17859 #CJK UNIFIED IDEOGRAPH + {0xE691, 0x93BD}, //17860 #CJK UNIFIED IDEOGRAPH + {0xE692, 0x93BE}, //17861 #CJK UNIFIED IDEOGRAPH + {0xE693, 0x93BF}, //17862 #CJK UNIFIED IDEOGRAPH + {0xE694, 0x93C0}, //17863 #CJK UNIFIED IDEOGRAPH + {0xE695, 0x93C1}, //17864 #CJK UNIFIED IDEOGRAPH + {0xE696, 0x93C2}, //17865 #CJK UNIFIED IDEOGRAPH + {0xE697, 0x93C3}, //17866 #CJK UNIFIED IDEOGRAPH + {0xE698, 0x93C4}, //17867 #CJK UNIFIED IDEOGRAPH + {0xE699, 0x93C5}, //17868 #CJK UNIFIED IDEOGRAPH + {0xE69A, 0x93C6}, //17869 #CJK UNIFIED IDEOGRAPH + {0xE69B, 0x93C7}, //17870 #CJK UNIFIED IDEOGRAPH + {0xE69C, 0x93C8}, //17871 #CJK UNIFIED IDEOGRAPH + {0xE69D, 0x93C9}, //17872 #CJK UNIFIED IDEOGRAPH + {0xE69E, 0x93CB}, //17873 #CJK UNIFIED IDEOGRAPH + {0xE69F, 0x93CC}, //17874 #CJK UNIFIED IDEOGRAPH + {0xE6A0, 0x93CD}, //17875 #CJK UNIFIED IDEOGRAPH + {0xE6A1, 0x5997}, //17876 #CJK UNIFIED IDEOGRAPH + {0xE6A2, 0x59CA}, //17877 #CJK UNIFIED IDEOGRAPH + {0xE6A3, 0x59AB}, //17878 #CJK UNIFIED IDEOGRAPH + {0xE6A4, 0x599E}, //17879 #CJK UNIFIED IDEOGRAPH + {0xE6A5, 0x59A4}, //17880 #CJK UNIFIED IDEOGRAPH + {0xE6A6, 0x59D2}, //17881 #CJK UNIFIED IDEOGRAPH + {0xE6A7, 0x59B2}, //17882 #CJK UNIFIED IDEOGRAPH + {0xE6A8, 0x59AF}, //17883 #CJK UNIFIED IDEOGRAPH + {0xE6A9, 0x59D7}, //17884 #CJK UNIFIED IDEOGRAPH + {0xE6AA, 0x59BE}, //17885 #CJK UNIFIED IDEOGRAPH + {0xE6AB, 0x5A05}, //17886 #CJK UNIFIED IDEOGRAPH + {0xE6AC, 0x5A06}, //17887 #CJK UNIFIED IDEOGRAPH + {0xE6AD, 0x59DD}, //17888 #CJK UNIFIED IDEOGRAPH + {0xE6AE, 0x5A08}, //17889 #CJK UNIFIED IDEOGRAPH + {0xE6AF, 0x59E3}, //17890 #CJK UNIFIED IDEOGRAPH + {0xE6B0, 0x59D8}, //17891 #CJK UNIFIED IDEOGRAPH + {0xE6B1, 0x59F9}, //17892 #CJK UNIFIED IDEOGRAPH + {0xE6B2, 0x5A0C}, //17893 #CJK UNIFIED IDEOGRAPH + {0xE6B3, 0x5A09}, //17894 #CJK UNIFIED IDEOGRAPH + {0xE6B4, 0x5A32}, //17895 #CJK UNIFIED IDEOGRAPH + {0xE6B5, 0x5A34}, //17896 #CJK UNIFIED IDEOGRAPH + {0xE6B6, 0x5A11}, //17897 #CJK UNIFIED IDEOGRAPH + {0xE6B7, 0x5A23}, //17898 #CJK UNIFIED IDEOGRAPH + {0xE6B8, 0x5A13}, //17899 #CJK UNIFIED IDEOGRAPH + {0xE6B9, 0x5A40}, //17900 #CJK UNIFIED IDEOGRAPH + {0xE6BA, 0x5A67}, //17901 #CJK UNIFIED IDEOGRAPH + {0xE6BB, 0x5A4A}, //17902 #CJK UNIFIED IDEOGRAPH + {0xE6BC, 0x5A55}, //17903 #CJK UNIFIED IDEOGRAPH + {0xE6BD, 0x5A3C}, //17904 #CJK UNIFIED IDEOGRAPH + {0xE6BE, 0x5A62}, //17905 #CJK UNIFIED IDEOGRAPH + {0xE6BF, 0x5A75}, //17906 #CJK UNIFIED IDEOGRAPH + {0xE6C0, 0x80EC}, //17907 #CJK UNIFIED IDEOGRAPH + {0xE6C1, 0x5AAA}, //17908 #CJK UNIFIED IDEOGRAPH + {0xE6C2, 0x5A9B}, //17909 #CJK UNIFIED IDEOGRAPH + {0xE6C3, 0x5A77}, //17910 #CJK UNIFIED IDEOGRAPH + {0xE6C4, 0x5A7A}, //17911 #CJK UNIFIED IDEOGRAPH + {0xE6C5, 0x5ABE}, //17912 #CJK UNIFIED IDEOGRAPH + {0xE6C6, 0x5AEB}, //17913 #CJK UNIFIED IDEOGRAPH + {0xE6C7, 0x5AB2}, //17914 #CJK UNIFIED IDEOGRAPH + {0xE6C8, 0x5AD2}, //17915 #CJK UNIFIED IDEOGRAPH + {0xE6C9, 0x5AD4}, //17916 #CJK UNIFIED IDEOGRAPH + {0xE6CA, 0x5AB8}, //17917 #CJK UNIFIED IDEOGRAPH + {0xE6CB, 0x5AE0}, //17918 #CJK UNIFIED IDEOGRAPH + {0xE6CC, 0x5AE3}, //17919 #CJK UNIFIED IDEOGRAPH + {0xE6CD, 0x5AF1}, //17920 #CJK UNIFIED IDEOGRAPH + {0xE6CE, 0x5AD6}, //17921 #CJK UNIFIED IDEOGRAPH + {0xE6CF, 0x5AE6}, //17922 #CJK UNIFIED IDEOGRAPH + {0xE6D0, 0x5AD8}, //17923 #CJK UNIFIED IDEOGRAPH + {0xE6D1, 0x5ADC}, //17924 #CJK UNIFIED IDEOGRAPH + {0xE6D2, 0x5B09}, //17925 #CJK UNIFIED IDEOGRAPH + {0xE6D3, 0x5B17}, //17926 #CJK UNIFIED IDEOGRAPH + {0xE6D4, 0x5B16}, //17927 #CJK UNIFIED IDEOGRAPH + {0xE6D5, 0x5B32}, //17928 #CJK UNIFIED IDEOGRAPH + {0xE6D6, 0x5B37}, //17929 #CJK UNIFIED IDEOGRAPH + {0xE6D7, 0x5B40}, //17930 #CJK UNIFIED IDEOGRAPH + {0xE6D8, 0x5C15}, //17931 #CJK UNIFIED IDEOGRAPH + {0xE6D9, 0x5C1C}, //17932 #CJK UNIFIED IDEOGRAPH + {0xE6DA, 0x5B5A}, //17933 #CJK UNIFIED IDEOGRAPH + {0xE6DB, 0x5B65}, //17934 #CJK UNIFIED IDEOGRAPH + {0xE6DC, 0x5B73}, //17935 #CJK UNIFIED IDEOGRAPH + {0xE6DD, 0x5B51}, //17936 #CJK UNIFIED IDEOGRAPH + {0xE6DE, 0x5B53}, //17937 #CJK UNIFIED IDEOGRAPH + {0xE6DF, 0x5B62}, //17938 #CJK UNIFIED IDEOGRAPH + {0xE6E0, 0x9A75}, //17939 #CJK UNIFIED IDEOGRAPH + {0xE6E1, 0x9A77}, //17940 #CJK UNIFIED IDEOGRAPH + {0xE6E2, 0x9A78}, //17941 #CJK UNIFIED IDEOGRAPH + {0xE6E3, 0x9A7A}, //17942 #CJK UNIFIED IDEOGRAPH + {0xE6E4, 0x9A7F}, //17943 #CJK UNIFIED IDEOGRAPH + {0xE6E5, 0x9A7D}, //17944 #CJK UNIFIED IDEOGRAPH + {0xE6E6, 0x9A80}, //17945 #CJK UNIFIED IDEOGRAPH + {0xE6E7, 0x9A81}, //17946 #CJK UNIFIED IDEOGRAPH + {0xE6E8, 0x9A85}, //17947 #CJK UNIFIED IDEOGRAPH + {0xE6E9, 0x9A88}, //17948 #CJK UNIFIED IDEOGRAPH + {0xE6EA, 0x9A8A}, //17949 #CJK UNIFIED IDEOGRAPH + {0xE6EB, 0x9A90}, //17950 #CJK UNIFIED IDEOGRAPH + {0xE6EC, 0x9A92}, //17951 #CJK UNIFIED IDEOGRAPH + {0xE6ED, 0x9A93}, //17952 #CJK UNIFIED IDEOGRAPH + {0xE6EE, 0x9A96}, //17953 #CJK UNIFIED IDEOGRAPH + {0xE6EF, 0x9A98}, //17954 #CJK UNIFIED IDEOGRAPH + {0xE6F0, 0x9A9B}, //17955 #CJK UNIFIED IDEOGRAPH + {0xE6F1, 0x9A9C}, //17956 #CJK UNIFIED IDEOGRAPH + {0xE6F2, 0x9A9D}, //17957 #CJK UNIFIED IDEOGRAPH + {0xE6F3, 0x9A9F}, //17958 #CJK UNIFIED IDEOGRAPH + {0xE6F4, 0x9AA0}, //17959 #CJK UNIFIED IDEOGRAPH + {0xE6F5, 0x9AA2}, //17960 #CJK UNIFIED IDEOGRAPH + {0xE6F6, 0x9AA3}, //17961 #CJK UNIFIED IDEOGRAPH + {0xE6F7, 0x9AA5}, //17962 #CJK UNIFIED IDEOGRAPH + {0xE6F8, 0x9AA7}, //17963 #CJK UNIFIED IDEOGRAPH + {0xE6F9, 0x7E9F}, //17964 #CJK UNIFIED IDEOGRAPH + {0xE6FA, 0x7EA1}, //17965 #CJK UNIFIED IDEOGRAPH + {0xE6FB, 0x7EA3}, //17966 #CJK UNIFIED IDEOGRAPH + {0xE6FC, 0x7EA5}, //17967 #CJK UNIFIED IDEOGRAPH + {0xE6FD, 0x7EA8}, //17968 #CJK UNIFIED IDEOGRAPH + {0xE6FE, 0x7EA9}, //17969 #CJK UNIFIED IDEOGRAPH + {0xE740, 0x93CE}, //17970 #CJK UNIFIED IDEOGRAPH + {0xE741, 0x93CF}, //17971 #CJK UNIFIED IDEOGRAPH + {0xE742, 0x93D0}, //17972 #CJK UNIFIED IDEOGRAPH + {0xE743, 0x93D1}, //17973 #CJK UNIFIED IDEOGRAPH + {0xE744, 0x93D2}, //17974 #CJK UNIFIED IDEOGRAPH + {0xE745, 0x93D3}, //17975 #CJK UNIFIED IDEOGRAPH + {0xE746, 0x93D4}, //17976 #CJK UNIFIED IDEOGRAPH + {0xE747, 0x93D5}, //17977 #CJK UNIFIED IDEOGRAPH + {0xE748, 0x93D7}, //17978 #CJK UNIFIED IDEOGRAPH + {0xE749, 0x93D8}, //17979 #CJK UNIFIED IDEOGRAPH + {0xE74A, 0x93D9}, //17980 #CJK UNIFIED IDEOGRAPH + {0xE74B, 0x93DA}, //17981 #CJK UNIFIED IDEOGRAPH + {0xE74C, 0x93DB}, //17982 #CJK UNIFIED IDEOGRAPH + {0xE74D, 0x93DC}, //17983 #CJK UNIFIED IDEOGRAPH + {0xE74E, 0x93DD}, //17984 #CJK UNIFIED IDEOGRAPH + {0xE74F, 0x93DE}, //17985 #CJK UNIFIED IDEOGRAPH + {0xE750, 0x93DF}, //17986 #CJK UNIFIED IDEOGRAPH + {0xE751, 0x93E0}, //17987 #CJK UNIFIED IDEOGRAPH + {0xE752, 0x93E1}, //17988 #CJK UNIFIED IDEOGRAPH + {0xE753, 0x93E2}, //17989 #CJK UNIFIED IDEOGRAPH + {0xE754, 0x93E3}, //17990 #CJK UNIFIED IDEOGRAPH + {0xE755, 0x93E4}, //17991 #CJK UNIFIED IDEOGRAPH + {0xE756, 0x93E5}, //17992 #CJK UNIFIED IDEOGRAPH + {0xE757, 0x93E6}, //17993 #CJK UNIFIED IDEOGRAPH + {0xE758, 0x93E7}, //17994 #CJK UNIFIED IDEOGRAPH + {0xE759, 0x93E8}, //17995 #CJK UNIFIED IDEOGRAPH + {0xE75A, 0x93E9}, //17996 #CJK UNIFIED IDEOGRAPH + {0xE75B, 0x93EA}, //17997 #CJK UNIFIED IDEOGRAPH + {0xE75C, 0x93EB}, //17998 #CJK UNIFIED IDEOGRAPH + {0xE75D, 0x93EC}, //17999 #CJK UNIFIED IDEOGRAPH + {0xE75E, 0x93ED}, //18000 #CJK UNIFIED IDEOGRAPH + {0xE75F, 0x93EE}, //18001 #CJK UNIFIED IDEOGRAPH + {0xE760, 0x93EF}, //18002 #CJK UNIFIED IDEOGRAPH + {0xE761, 0x93F0}, //18003 #CJK UNIFIED IDEOGRAPH + {0xE762, 0x93F1}, //18004 #CJK UNIFIED IDEOGRAPH + {0xE763, 0x93F2}, //18005 #CJK UNIFIED IDEOGRAPH + {0xE764, 0x93F3}, //18006 #CJK UNIFIED IDEOGRAPH + {0xE765, 0x93F4}, //18007 #CJK UNIFIED IDEOGRAPH + {0xE766, 0x93F5}, //18008 #CJK UNIFIED IDEOGRAPH + {0xE767, 0x93F6}, //18009 #CJK UNIFIED IDEOGRAPH + {0xE768, 0x93F7}, //18010 #CJK UNIFIED IDEOGRAPH + {0xE769, 0x93F8}, //18011 #CJK UNIFIED IDEOGRAPH + {0xE76A, 0x93F9}, //18012 #CJK UNIFIED IDEOGRAPH + {0xE76B, 0x93FA}, //18013 #CJK UNIFIED IDEOGRAPH + {0xE76C, 0x93FB}, //18014 #CJK UNIFIED IDEOGRAPH + {0xE76D, 0x93FC}, //18015 #CJK UNIFIED IDEOGRAPH + {0xE76E, 0x93FD}, //18016 #CJK UNIFIED IDEOGRAPH + {0xE76F, 0x93FE}, //18017 #CJK UNIFIED IDEOGRAPH + {0xE770, 0x93FF}, //18018 #CJK UNIFIED IDEOGRAPH + {0xE771, 0x9400}, //18019 #CJK UNIFIED IDEOGRAPH + {0xE772, 0x9401}, //18020 #CJK UNIFIED IDEOGRAPH + {0xE773, 0x9402}, //18021 #CJK UNIFIED IDEOGRAPH + {0xE774, 0x9403}, //18022 #CJK UNIFIED IDEOGRAPH + {0xE775, 0x9404}, //18023 #CJK UNIFIED IDEOGRAPH + {0xE776, 0x9405}, //18024 #CJK UNIFIED IDEOGRAPH + {0xE777, 0x9406}, //18025 #CJK UNIFIED IDEOGRAPH + {0xE778, 0x9407}, //18026 #CJK UNIFIED IDEOGRAPH + {0xE779, 0x9408}, //18027 #CJK UNIFIED IDEOGRAPH + {0xE77A, 0x9409}, //18028 #CJK UNIFIED IDEOGRAPH + {0xE77B, 0x940A}, //18029 #CJK UNIFIED IDEOGRAPH + {0xE77C, 0x940B}, //18030 #CJK UNIFIED IDEOGRAPH + {0xE77D, 0x940C}, //18031 #CJK UNIFIED IDEOGRAPH + {0xE77E, 0x940D}, //18032 #CJK UNIFIED IDEOGRAPH + {0xE780, 0x940E}, //18033 #CJK UNIFIED IDEOGRAPH + {0xE781, 0x940F}, //18034 #CJK UNIFIED IDEOGRAPH + {0xE782, 0x9410}, //18035 #CJK UNIFIED IDEOGRAPH + {0xE783, 0x9411}, //18036 #CJK UNIFIED IDEOGRAPH + {0xE784, 0x9412}, //18037 #CJK UNIFIED IDEOGRAPH + {0xE785, 0x9413}, //18038 #CJK UNIFIED IDEOGRAPH + {0xE786, 0x9414}, //18039 #CJK UNIFIED IDEOGRAPH + {0xE787, 0x9415}, //18040 #CJK UNIFIED IDEOGRAPH + {0xE788, 0x9416}, //18041 #CJK UNIFIED IDEOGRAPH + {0xE789, 0x9417}, //18042 #CJK UNIFIED IDEOGRAPH + {0xE78A, 0x9418}, //18043 #CJK UNIFIED IDEOGRAPH + {0xE78B, 0x9419}, //18044 #CJK UNIFIED IDEOGRAPH + {0xE78C, 0x941A}, //18045 #CJK UNIFIED IDEOGRAPH + {0xE78D, 0x941B}, //18046 #CJK UNIFIED IDEOGRAPH + {0xE78E, 0x941C}, //18047 #CJK UNIFIED IDEOGRAPH + {0xE78F, 0x941D}, //18048 #CJK UNIFIED IDEOGRAPH + {0xE790, 0x941E}, //18049 #CJK UNIFIED IDEOGRAPH + {0xE791, 0x941F}, //18050 #CJK UNIFIED IDEOGRAPH + {0xE792, 0x9420}, //18051 #CJK UNIFIED IDEOGRAPH + {0xE793, 0x9421}, //18052 #CJK UNIFIED IDEOGRAPH + {0xE794, 0x9422}, //18053 #CJK UNIFIED IDEOGRAPH + {0xE795, 0x9423}, //18054 #CJK UNIFIED IDEOGRAPH + {0xE796, 0x9424}, //18055 #CJK UNIFIED IDEOGRAPH + {0xE797, 0x9425}, //18056 #CJK UNIFIED IDEOGRAPH + {0xE798, 0x9426}, //18057 #CJK UNIFIED IDEOGRAPH + {0xE799, 0x9427}, //18058 #CJK UNIFIED IDEOGRAPH + {0xE79A, 0x9428}, //18059 #CJK UNIFIED IDEOGRAPH + {0xE79B, 0x9429}, //18060 #CJK UNIFIED IDEOGRAPH + {0xE79C, 0x942A}, //18061 #CJK UNIFIED IDEOGRAPH + {0xE79D, 0x942B}, //18062 #CJK UNIFIED IDEOGRAPH + {0xE79E, 0x942C}, //18063 #CJK UNIFIED IDEOGRAPH + {0xE79F, 0x942D}, //18064 #CJK UNIFIED IDEOGRAPH + {0xE7A0, 0x942E}, //18065 #CJK UNIFIED IDEOGRAPH + {0xE7A1, 0x7EAD}, //18066 #CJK UNIFIED IDEOGRAPH + {0xE7A2, 0x7EB0}, //18067 #CJK UNIFIED IDEOGRAPH + {0xE7A3, 0x7EBE}, //18068 #CJK UNIFIED IDEOGRAPH + {0xE7A4, 0x7EC0}, //18069 #CJK UNIFIED IDEOGRAPH + {0xE7A5, 0x7EC1}, //18070 #CJK UNIFIED IDEOGRAPH + {0xE7A6, 0x7EC2}, //18071 #CJK UNIFIED IDEOGRAPH + {0xE7A7, 0x7EC9}, //18072 #CJK UNIFIED IDEOGRAPH + {0xE7A8, 0x7ECB}, //18073 #CJK UNIFIED IDEOGRAPH + {0xE7A9, 0x7ECC}, //18074 #CJK UNIFIED IDEOGRAPH + {0xE7AA, 0x7ED0}, //18075 #CJK UNIFIED IDEOGRAPH + {0xE7AB, 0x7ED4}, //18076 #CJK UNIFIED IDEOGRAPH + {0xE7AC, 0x7ED7}, //18077 #CJK UNIFIED IDEOGRAPH + {0xE7AD, 0x7EDB}, //18078 #CJK UNIFIED IDEOGRAPH + {0xE7AE, 0x7EE0}, //18079 #CJK UNIFIED IDEOGRAPH + {0xE7AF, 0x7EE1}, //18080 #CJK UNIFIED IDEOGRAPH + {0xE7B0, 0x7EE8}, //18081 #CJK UNIFIED IDEOGRAPH + {0xE7B1, 0x7EEB}, //18082 #CJK UNIFIED IDEOGRAPH + {0xE7B2, 0x7EEE}, //18083 #CJK UNIFIED IDEOGRAPH + {0xE7B3, 0x7EEF}, //18084 #CJK UNIFIED IDEOGRAPH + {0xE7B4, 0x7EF1}, //18085 #CJK UNIFIED IDEOGRAPH + {0xE7B5, 0x7EF2}, //18086 #CJK UNIFIED IDEOGRAPH + {0xE7B6, 0x7F0D}, //18087 #CJK UNIFIED IDEOGRAPH + {0xE7B7, 0x7EF6}, //18088 #CJK UNIFIED IDEOGRAPH + {0xE7B8, 0x7EFA}, //18089 #CJK UNIFIED IDEOGRAPH + {0xE7B9, 0x7EFB}, //18090 #CJK UNIFIED IDEOGRAPH + {0xE7BA, 0x7EFE}, //18091 #CJK UNIFIED IDEOGRAPH + {0xE7BB, 0x7F01}, //18092 #CJK UNIFIED IDEOGRAPH + {0xE7BC, 0x7F02}, //18093 #CJK UNIFIED IDEOGRAPH + {0xE7BD, 0x7F03}, //18094 #CJK UNIFIED IDEOGRAPH + {0xE7BE, 0x7F07}, //18095 #CJK UNIFIED IDEOGRAPH + {0xE7BF, 0x7F08}, //18096 #CJK UNIFIED IDEOGRAPH + {0xE7C0, 0x7F0B}, //18097 #CJK UNIFIED IDEOGRAPH + {0xE7C1, 0x7F0C}, //18098 #CJK UNIFIED IDEOGRAPH + {0xE7C2, 0x7F0F}, //18099 #CJK UNIFIED IDEOGRAPH + {0xE7C3, 0x7F11}, //18100 #CJK UNIFIED IDEOGRAPH + {0xE7C4, 0x7F12}, //18101 #CJK UNIFIED IDEOGRAPH + {0xE7C5, 0x7F17}, //18102 #CJK UNIFIED IDEOGRAPH + {0xE7C6, 0x7F19}, //18103 #CJK UNIFIED IDEOGRAPH + {0xE7C7, 0x7F1C}, //18104 #CJK UNIFIED IDEOGRAPH + {0xE7C8, 0x7F1B}, //18105 #CJK UNIFIED IDEOGRAPH + {0xE7C9, 0x7F1F}, //18106 #CJK UNIFIED IDEOGRAPH + {0xE7CA, 0x7F21}, //18107 #CJK UNIFIED IDEOGRAPH + {0xE7CB, 0x7F22}, //18108 #CJK UNIFIED IDEOGRAPH + {0xE7CC, 0x7F23}, //18109 #CJK UNIFIED IDEOGRAPH + {0xE7CD, 0x7F24}, //18110 #CJK UNIFIED IDEOGRAPH + {0xE7CE, 0x7F25}, //18111 #CJK UNIFIED IDEOGRAPH + {0xE7CF, 0x7F26}, //18112 #CJK UNIFIED IDEOGRAPH + {0xE7D0, 0x7F27}, //18113 #CJK UNIFIED IDEOGRAPH + {0xE7D1, 0x7F2A}, //18114 #CJK UNIFIED IDEOGRAPH + {0xE7D2, 0x7F2B}, //18115 #CJK UNIFIED IDEOGRAPH + {0xE7D3, 0x7F2C}, //18116 #CJK UNIFIED IDEOGRAPH + {0xE7D4, 0x7F2D}, //18117 #CJK UNIFIED IDEOGRAPH + {0xE7D5, 0x7F2F}, //18118 #CJK UNIFIED IDEOGRAPH + {0xE7D6, 0x7F30}, //18119 #CJK UNIFIED IDEOGRAPH + {0xE7D7, 0x7F31}, //18120 #CJK UNIFIED IDEOGRAPH + {0xE7D8, 0x7F32}, //18121 #CJK UNIFIED IDEOGRAPH + {0xE7D9, 0x7F33}, //18122 #CJK UNIFIED IDEOGRAPH + {0xE7DA, 0x7F35}, //18123 #CJK UNIFIED IDEOGRAPH + {0xE7DB, 0x5E7A}, //18124 #CJK UNIFIED IDEOGRAPH + {0xE7DC, 0x757F}, //18125 #CJK UNIFIED IDEOGRAPH + {0xE7DD, 0x5DDB}, //18126 #CJK UNIFIED IDEOGRAPH + {0xE7DE, 0x753E}, //18127 #CJK UNIFIED IDEOGRAPH + {0xE7DF, 0x9095}, //18128 #CJK UNIFIED IDEOGRAPH + {0xE7E0, 0x738E}, //18129 #CJK UNIFIED IDEOGRAPH + {0xE7E1, 0x7391}, //18130 #CJK UNIFIED IDEOGRAPH + {0xE7E2, 0x73AE}, //18131 #CJK UNIFIED IDEOGRAPH + {0xE7E3, 0x73A2}, //18132 #CJK UNIFIED IDEOGRAPH + {0xE7E4, 0x739F}, //18133 #CJK UNIFIED IDEOGRAPH + {0xE7E5, 0x73CF}, //18134 #CJK UNIFIED IDEOGRAPH + {0xE7E6, 0x73C2}, //18135 #CJK UNIFIED IDEOGRAPH + {0xE7E7, 0x73D1}, //18136 #CJK UNIFIED IDEOGRAPH + {0xE7E8, 0x73B7}, //18137 #CJK UNIFIED IDEOGRAPH + {0xE7E9, 0x73B3}, //18138 #CJK UNIFIED IDEOGRAPH + {0xE7EA, 0x73C0}, //18139 #CJK UNIFIED IDEOGRAPH + {0xE7EB, 0x73C9}, //18140 #CJK UNIFIED IDEOGRAPH + {0xE7EC, 0x73C8}, //18141 #CJK UNIFIED IDEOGRAPH + {0xE7ED, 0x73E5}, //18142 #CJK UNIFIED IDEOGRAPH + {0xE7EE, 0x73D9}, //18143 #CJK UNIFIED IDEOGRAPH + {0xE7EF, 0x987C}, //18144 #CJK UNIFIED IDEOGRAPH + {0xE7F0, 0x740A}, //18145 #CJK UNIFIED IDEOGRAPH + {0xE7F1, 0x73E9}, //18146 #CJK UNIFIED IDEOGRAPH + {0xE7F2, 0x73E7}, //18147 #CJK UNIFIED IDEOGRAPH + {0xE7F3, 0x73DE}, //18148 #CJK UNIFIED IDEOGRAPH + {0xE7F4, 0x73BA}, //18149 #CJK UNIFIED IDEOGRAPH + {0xE7F5, 0x73F2}, //18150 #CJK UNIFIED IDEOGRAPH + {0xE7F6, 0x740F}, //18151 #CJK UNIFIED IDEOGRAPH + {0xE7F7, 0x742A}, //18152 #CJK UNIFIED IDEOGRAPH + {0xE7F8, 0x745B}, //18153 #CJK UNIFIED IDEOGRAPH + {0xE7F9, 0x7426}, //18154 #CJK UNIFIED IDEOGRAPH + {0xE7FA, 0x7425}, //18155 #CJK UNIFIED IDEOGRAPH + {0xE7FB, 0x7428}, //18156 #CJK UNIFIED IDEOGRAPH + {0xE7FC, 0x7430}, //18157 #CJK UNIFIED IDEOGRAPH + {0xE7FD, 0x742E}, //18158 #CJK UNIFIED IDEOGRAPH + {0xE7FE, 0x742C}, //18159 #CJK UNIFIED IDEOGRAPH + {0xE840, 0x942F}, //18160 #CJK UNIFIED IDEOGRAPH + {0xE841, 0x9430}, //18161 #CJK UNIFIED IDEOGRAPH + {0xE842, 0x9431}, //18162 #CJK UNIFIED IDEOGRAPH + {0xE843, 0x9432}, //18163 #CJK UNIFIED IDEOGRAPH + {0xE844, 0x9433}, //18164 #CJK UNIFIED IDEOGRAPH + {0xE845, 0x9434}, //18165 #CJK UNIFIED IDEOGRAPH + {0xE846, 0x9435}, //18166 #CJK UNIFIED IDEOGRAPH + {0xE847, 0x9436}, //18167 #CJK UNIFIED IDEOGRAPH + {0xE848, 0x9437}, //18168 #CJK UNIFIED IDEOGRAPH + {0xE849, 0x9438}, //18169 #CJK UNIFIED IDEOGRAPH + {0xE84A, 0x9439}, //18170 #CJK UNIFIED IDEOGRAPH + {0xE84B, 0x943A}, //18171 #CJK UNIFIED IDEOGRAPH + {0xE84C, 0x943B}, //18172 #CJK UNIFIED IDEOGRAPH + {0xE84D, 0x943C}, //18173 #CJK UNIFIED IDEOGRAPH + {0xE84E, 0x943D}, //18174 #CJK UNIFIED IDEOGRAPH + {0xE84F, 0x943F}, //18175 #CJK UNIFIED IDEOGRAPH + {0xE850, 0x9440}, //18176 #CJK UNIFIED IDEOGRAPH + {0xE851, 0x9441}, //18177 #CJK UNIFIED IDEOGRAPH + {0xE852, 0x9442}, //18178 #CJK UNIFIED IDEOGRAPH + {0xE853, 0x9443}, //18179 #CJK UNIFIED IDEOGRAPH + {0xE854, 0x9444}, //18180 #CJK UNIFIED IDEOGRAPH + {0xE855, 0x9445}, //18181 #CJK UNIFIED IDEOGRAPH + {0xE856, 0x9446}, //18182 #CJK UNIFIED IDEOGRAPH + {0xE857, 0x9447}, //18183 #CJK UNIFIED IDEOGRAPH + {0xE858, 0x9448}, //18184 #CJK UNIFIED IDEOGRAPH + {0xE859, 0x9449}, //18185 #CJK UNIFIED IDEOGRAPH + {0xE85A, 0x944A}, //18186 #CJK UNIFIED IDEOGRAPH + {0xE85B, 0x944B}, //18187 #CJK UNIFIED IDEOGRAPH + {0xE85C, 0x944C}, //18188 #CJK UNIFIED IDEOGRAPH + {0xE85D, 0x944D}, //18189 #CJK UNIFIED IDEOGRAPH + {0xE85E, 0x944E}, //18190 #CJK UNIFIED IDEOGRAPH + {0xE85F, 0x944F}, //18191 #CJK UNIFIED IDEOGRAPH + {0xE860, 0x9450}, //18192 #CJK UNIFIED IDEOGRAPH + {0xE861, 0x9451}, //18193 #CJK UNIFIED IDEOGRAPH + {0xE862, 0x9452}, //18194 #CJK UNIFIED IDEOGRAPH + {0xE863, 0x9453}, //18195 #CJK UNIFIED IDEOGRAPH + {0xE864, 0x9454}, //18196 #CJK UNIFIED IDEOGRAPH + {0xE865, 0x9455}, //18197 #CJK UNIFIED IDEOGRAPH + {0xE866, 0x9456}, //18198 #CJK UNIFIED IDEOGRAPH + {0xE867, 0x9457}, //18199 #CJK UNIFIED IDEOGRAPH + {0xE868, 0x9458}, //18200 #CJK UNIFIED IDEOGRAPH + {0xE869, 0x9459}, //18201 #CJK UNIFIED IDEOGRAPH + {0xE86A, 0x945A}, //18202 #CJK UNIFIED IDEOGRAPH + {0xE86B, 0x945B}, //18203 #CJK UNIFIED IDEOGRAPH + {0xE86C, 0x945C}, //18204 #CJK UNIFIED IDEOGRAPH + {0xE86D, 0x945D}, //18205 #CJK UNIFIED IDEOGRAPH + {0xE86E, 0x945E}, //18206 #CJK UNIFIED IDEOGRAPH + {0xE86F, 0x945F}, //18207 #CJK UNIFIED IDEOGRAPH + {0xE870, 0x9460}, //18208 #CJK UNIFIED IDEOGRAPH + {0xE871, 0x9461}, //18209 #CJK UNIFIED IDEOGRAPH + {0xE872, 0x9462}, //18210 #CJK UNIFIED IDEOGRAPH + {0xE873, 0x9463}, //18211 #CJK UNIFIED IDEOGRAPH + {0xE874, 0x9464}, //18212 #CJK UNIFIED IDEOGRAPH + {0xE875, 0x9465}, //18213 #CJK UNIFIED IDEOGRAPH + {0xE876, 0x9466}, //18214 #CJK UNIFIED IDEOGRAPH + {0xE877, 0x9467}, //18215 #CJK UNIFIED IDEOGRAPH + {0xE878, 0x9468}, //18216 #CJK UNIFIED IDEOGRAPH + {0xE879, 0x9469}, //18217 #CJK UNIFIED IDEOGRAPH + {0xE87A, 0x946A}, //18218 #CJK UNIFIED IDEOGRAPH + {0xE87B, 0x946C}, //18219 #CJK UNIFIED IDEOGRAPH + {0xE87C, 0x946D}, //18220 #CJK UNIFIED IDEOGRAPH + {0xE87D, 0x946E}, //18221 #CJK UNIFIED IDEOGRAPH + {0xE87E, 0x946F}, //18222 #CJK UNIFIED IDEOGRAPH + {0xE880, 0x9470}, //18223 #CJK UNIFIED IDEOGRAPH + {0xE881, 0x9471}, //18224 #CJK UNIFIED IDEOGRAPH + {0xE882, 0x9472}, //18225 #CJK UNIFIED IDEOGRAPH + {0xE883, 0x9473}, //18226 #CJK UNIFIED IDEOGRAPH + {0xE884, 0x9474}, //18227 #CJK UNIFIED IDEOGRAPH + {0xE885, 0x9475}, //18228 #CJK UNIFIED IDEOGRAPH + {0xE886, 0x9476}, //18229 #CJK UNIFIED IDEOGRAPH + {0xE887, 0x9477}, //18230 #CJK UNIFIED IDEOGRAPH + {0xE888, 0x9478}, //18231 #CJK UNIFIED IDEOGRAPH + {0xE889, 0x9479}, //18232 #CJK UNIFIED IDEOGRAPH + {0xE88A, 0x947A}, //18233 #CJK UNIFIED IDEOGRAPH + {0xE88B, 0x947B}, //18234 #CJK UNIFIED IDEOGRAPH + {0xE88C, 0x947C}, //18235 #CJK UNIFIED IDEOGRAPH + {0xE88D, 0x947D}, //18236 #CJK UNIFIED IDEOGRAPH + {0xE88E, 0x947E}, //18237 #CJK UNIFIED IDEOGRAPH + {0xE88F, 0x947F}, //18238 #CJK UNIFIED IDEOGRAPH + {0xE890, 0x9480}, //18239 #CJK UNIFIED IDEOGRAPH + {0xE891, 0x9481}, //18240 #CJK UNIFIED IDEOGRAPH + {0xE892, 0x9482}, //18241 #CJK UNIFIED IDEOGRAPH + {0xE893, 0x9483}, //18242 #CJK UNIFIED IDEOGRAPH + {0xE894, 0x9484}, //18243 #CJK UNIFIED IDEOGRAPH + {0xE895, 0x9491}, //18244 #CJK UNIFIED IDEOGRAPH + {0xE896, 0x9496}, //18245 #CJK UNIFIED IDEOGRAPH + {0xE897, 0x9498}, //18246 #CJK UNIFIED IDEOGRAPH + {0xE898, 0x94C7}, //18247 #CJK UNIFIED IDEOGRAPH + {0xE899, 0x94CF}, //18248 #CJK UNIFIED IDEOGRAPH + {0xE89A, 0x94D3}, //18249 #CJK UNIFIED IDEOGRAPH + {0xE89B, 0x94D4}, //18250 #CJK UNIFIED IDEOGRAPH + {0xE89C, 0x94DA}, //18251 #CJK UNIFIED IDEOGRAPH + {0xE89D, 0x94E6}, //18252 #CJK UNIFIED IDEOGRAPH + {0xE89E, 0x94FB}, //18253 #CJK UNIFIED IDEOGRAPH + {0xE89F, 0x951C}, //18254 #CJK UNIFIED IDEOGRAPH + {0xE8A0, 0x9520}, //18255 #CJK UNIFIED IDEOGRAPH + {0xE8A1, 0x741B}, //18256 #CJK UNIFIED IDEOGRAPH + {0xE8A2, 0x741A}, //18257 #CJK UNIFIED IDEOGRAPH + {0xE8A3, 0x7441}, //18258 #CJK UNIFIED IDEOGRAPH + {0xE8A4, 0x745C}, //18259 #CJK UNIFIED IDEOGRAPH + {0xE8A5, 0x7457}, //18260 #CJK UNIFIED IDEOGRAPH + {0xE8A6, 0x7455}, //18261 #CJK UNIFIED IDEOGRAPH + {0xE8A7, 0x7459}, //18262 #CJK UNIFIED IDEOGRAPH + {0xE8A8, 0x7477}, //18263 #CJK UNIFIED IDEOGRAPH + {0xE8A9, 0x746D}, //18264 #CJK UNIFIED IDEOGRAPH + {0xE8AA, 0x747E}, //18265 #CJK UNIFIED IDEOGRAPH + {0xE8AB, 0x749C}, //18266 #CJK UNIFIED IDEOGRAPH + {0xE8AC, 0x748E}, //18267 #CJK UNIFIED IDEOGRAPH + {0xE8AD, 0x7480}, //18268 #CJK UNIFIED IDEOGRAPH + {0xE8AE, 0x7481}, //18269 #CJK UNIFIED IDEOGRAPH + {0xE8AF, 0x7487}, //18270 #CJK UNIFIED IDEOGRAPH + {0xE8B0, 0x748B}, //18271 #CJK UNIFIED IDEOGRAPH + {0xE8B1, 0x749E}, //18272 #CJK UNIFIED IDEOGRAPH + {0xE8B2, 0x74A8}, //18273 #CJK UNIFIED IDEOGRAPH + {0xE8B3, 0x74A9}, //18274 #CJK UNIFIED IDEOGRAPH + {0xE8B4, 0x7490}, //18275 #CJK UNIFIED IDEOGRAPH + {0xE8B5, 0x74A7}, //18276 #CJK UNIFIED IDEOGRAPH + {0xE8B6, 0x74D2}, //18277 #CJK UNIFIED IDEOGRAPH + {0xE8B7, 0x74BA}, //18278 #CJK UNIFIED IDEOGRAPH + {0xE8B8, 0x97EA}, //18279 #CJK UNIFIED IDEOGRAPH + {0xE8B9, 0x97EB}, //18280 #CJK UNIFIED IDEOGRAPH + {0xE8BA, 0x97EC}, //18281 #CJK UNIFIED IDEOGRAPH + {0xE8BB, 0x674C}, //18282 #CJK UNIFIED IDEOGRAPH + {0xE8BC, 0x6753}, //18283 #CJK UNIFIED IDEOGRAPH + {0xE8BD, 0x675E}, //18284 #CJK UNIFIED IDEOGRAPH + {0xE8BE, 0x6748}, //18285 #CJK UNIFIED IDEOGRAPH + {0xE8BF, 0x6769}, //18286 #CJK UNIFIED IDEOGRAPH + {0xE8C0, 0x67A5}, //18287 #CJK UNIFIED IDEOGRAPH + {0xE8C1, 0x6787}, //18288 #CJK UNIFIED IDEOGRAPH + {0xE8C2, 0x676A}, //18289 #CJK UNIFIED IDEOGRAPH + {0xE8C3, 0x6773}, //18290 #CJK UNIFIED IDEOGRAPH + {0xE8C4, 0x6798}, //18291 #CJK UNIFIED IDEOGRAPH + {0xE8C5, 0x67A7}, //18292 #CJK UNIFIED IDEOGRAPH + {0xE8C6, 0x6775}, //18293 #CJK UNIFIED IDEOGRAPH + {0xE8C7, 0x67A8}, //18294 #CJK UNIFIED IDEOGRAPH + {0xE8C8, 0x679E}, //18295 #CJK UNIFIED IDEOGRAPH + {0xE8C9, 0x67AD}, //18296 #CJK UNIFIED IDEOGRAPH + {0xE8CA, 0x678B}, //18297 #CJK UNIFIED IDEOGRAPH + {0xE8CB, 0x6777}, //18298 #CJK UNIFIED IDEOGRAPH + {0xE8CC, 0x677C}, //18299 #CJK UNIFIED IDEOGRAPH + {0xE8CD, 0x67F0}, //18300 #CJK UNIFIED IDEOGRAPH + {0xE8CE, 0x6809}, //18301 #CJK UNIFIED IDEOGRAPH + {0xE8CF, 0x67D8}, //18302 #CJK UNIFIED IDEOGRAPH + {0xE8D0, 0x680A}, //18303 #CJK UNIFIED IDEOGRAPH + {0xE8D1, 0x67E9}, //18304 #CJK UNIFIED IDEOGRAPH + {0xE8D2, 0x67B0}, //18305 #CJK UNIFIED IDEOGRAPH + {0xE8D3, 0x680C}, //18306 #CJK UNIFIED IDEOGRAPH + {0xE8D4, 0x67D9}, //18307 #CJK UNIFIED IDEOGRAPH + {0xE8D5, 0x67B5}, //18308 #CJK UNIFIED IDEOGRAPH + {0xE8D6, 0x67DA}, //18309 #CJK UNIFIED IDEOGRAPH + {0xE8D7, 0x67B3}, //18310 #CJK UNIFIED IDEOGRAPH + {0xE8D8, 0x67DD}, //18311 #CJK UNIFIED IDEOGRAPH + {0xE8D9, 0x6800}, //18312 #CJK UNIFIED IDEOGRAPH + {0xE8DA, 0x67C3}, //18313 #CJK UNIFIED IDEOGRAPH + {0xE8DB, 0x67B8}, //18314 #CJK UNIFIED IDEOGRAPH + {0xE8DC, 0x67E2}, //18315 #CJK UNIFIED IDEOGRAPH + {0xE8DD, 0x680E}, //18316 #CJK UNIFIED IDEOGRAPH + {0xE8DE, 0x67C1}, //18317 #CJK UNIFIED IDEOGRAPH + {0xE8DF, 0x67FD}, //18318 #CJK UNIFIED IDEOGRAPH + {0xE8E0, 0x6832}, //18319 #CJK UNIFIED IDEOGRAPH + {0xE8E1, 0x6833}, //18320 #CJK UNIFIED IDEOGRAPH + {0xE8E2, 0x6860}, //18321 #CJK UNIFIED IDEOGRAPH + {0xE8E3, 0x6861}, //18322 #CJK UNIFIED IDEOGRAPH + {0xE8E4, 0x684E}, //18323 #CJK UNIFIED IDEOGRAPH + {0xE8E5, 0x6862}, //18324 #CJK UNIFIED IDEOGRAPH + {0xE8E6, 0x6844}, //18325 #CJK UNIFIED IDEOGRAPH + {0xE8E7, 0x6864}, //18326 #CJK UNIFIED IDEOGRAPH + {0xE8E8, 0x6883}, //18327 #CJK UNIFIED IDEOGRAPH + {0xE8E9, 0x681D}, //18328 #CJK UNIFIED IDEOGRAPH + {0xE8EA, 0x6855}, //18329 #CJK UNIFIED IDEOGRAPH + {0xE8EB, 0x6866}, //18330 #CJK UNIFIED IDEOGRAPH + {0xE8EC, 0x6841}, //18331 #CJK UNIFIED IDEOGRAPH + {0xE8ED, 0x6867}, //18332 #CJK UNIFIED IDEOGRAPH + {0xE8EE, 0x6840}, //18333 #CJK UNIFIED IDEOGRAPH + {0xE8EF, 0x683E}, //18334 #CJK UNIFIED IDEOGRAPH + {0xE8F0, 0x684A}, //18335 #CJK UNIFIED IDEOGRAPH + {0xE8F1, 0x6849}, //18336 #CJK UNIFIED IDEOGRAPH + {0xE8F2, 0x6829}, //18337 #CJK UNIFIED IDEOGRAPH + {0xE8F3, 0x68B5}, //18338 #CJK UNIFIED IDEOGRAPH + {0xE8F4, 0x688F}, //18339 #CJK UNIFIED IDEOGRAPH + {0xE8F5, 0x6874}, //18340 #CJK UNIFIED IDEOGRAPH + {0xE8F6, 0x6877}, //18341 #CJK UNIFIED IDEOGRAPH + {0xE8F7, 0x6893}, //18342 #CJK UNIFIED IDEOGRAPH + {0xE8F8, 0x686B}, //18343 #CJK UNIFIED IDEOGRAPH + {0xE8F9, 0x68C2}, //18344 #CJK UNIFIED IDEOGRAPH + {0xE8FA, 0x696E}, //18345 #CJK UNIFIED IDEOGRAPH + {0xE8FB, 0x68FC}, //18346 #CJK UNIFIED IDEOGRAPH + {0xE8FC, 0x691F}, //18347 #CJK UNIFIED IDEOGRAPH + {0xE8FD, 0x6920}, //18348 #CJK UNIFIED IDEOGRAPH + {0xE8FE, 0x68F9}, //18349 #CJK UNIFIED IDEOGRAPH + {0xE940, 0x9527}, //18350 #CJK UNIFIED IDEOGRAPH + {0xE941, 0x9533}, //18351 #CJK UNIFIED IDEOGRAPH + {0xE942, 0x953D}, //18352 #CJK UNIFIED IDEOGRAPH + {0xE943, 0x9543}, //18353 #CJK UNIFIED IDEOGRAPH + {0xE944, 0x9548}, //18354 #CJK UNIFIED IDEOGRAPH + {0xE945, 0x954B}, //18355 #CJK UNIFIED IDEOGRAPH + {0xE946, 0x9555}, //18356 #CJK UNIFIED IDEOGRAPH + {0xE947, 0x955A}, //18357 #CJK UNIFIED IDEOGRAPH + {0xE948, 0x9560}, //18358 #CJK UNIFIED IDEOGRAPH + {0xE949, 0x956E}, //18359 #CJK UNIFIED IDEOGRAPH + {0xE94A, 0x9574}, //18360 #CJK UNIFIED IDEOGRAPH + {0xE94B, 0x9575}, //18361 #CJK UNIFIED IDEOGRAPH + {0xE94C, 0x9577}, //18362 #CJK UNIFIED IDEOGRAPH + {0xE94D, 0x9578}, //18363 #CJK UNIFIED IDEOGRAPH + {0xE94E, 0x9579}, //18364 #CJK UNIFIED IDEOGRAPH + {0xE94F, 0x957A}, //18365 #CJK UNIFIED IDEOGRAPH + {0xE950, 0x957B}, //18366 #CJK UNIFIED IDEOGRAPH + {0xE951, 0x957C}, //18367 #CJK UNIFIED IDEOGRAPH + {0xE952, 0x957D}, //18368 #CJK UNIFIED IDEOGRAPH + {0xE953, 0x957E}, //18369 #CJK UNIFIED IDEOGRAPH + {0xE954, 0x9580}, //18370 #CJK UNIFIED IDEOGRAPH + {0xE955, 0x9581}, //18371 #CJK UNIFIED IDEOGRAPH + {0xE956, 0x9582}, //18372 #CJK UNIFIED IDEOGRAPH + {0xE957, 0x9583}, //18373 #CJK UNIFIED IDEOGRAPH + {0xE958, 0x9584}, //18374 #CJK UNIFIED IDEOGRAPH + {0xE959, 0x9585}, //18375 #CJK UNIFIED IDEOGRAPH + {0xE95A, 0x9586}, //18376 #CJK UNIFIED IDEOGRAPH + {0xE95B, 0x9587}, //18377 #CJK UNIFIED IDEOGRAPH + {0xE95C, 0x9588}, //18378 #CJK UNIFIED IDEOGRAPH + {0xE95D, 0x9589}, //18379 #CJK UNIFIED IDEOGRAPH + {0xE95E, 0x958A}, //18380 #CJK UNIFIED IDEOGRAPH + {0xE95F, 0x958B}, //18381 #CJK UNIFIED IDEOGRAPH + {0xE960, 0x958C}, //18382 #CJK UNIFIED IDEOGRAPH + {0xE961, 0x958D}, //18383 #CJK UNIFIED IDEOGRAPH + {0xE962, 0x958E}, //18384 #CJK UNIFIED IDEOGRAPH + {0xE963, 0x958F}, //18385 #CJK UNIFIED IDEOGRAPH + {0xE964, 0x9590}, //18386 #CJK UNIFIED IDEOGRAPH + {0xE965, 0x9591}, //18387 #CJK UNIFIED IDEOGRAPH + {0xE966, 0x9592}, //18388 #CJK UNIFIED IDEOGRAPH + {0xE967, 0x9593}, //18389 #CJK UNIFIED IDEOGRAPH + {0xE968, 0x9594}, //18390 #CJK UNIFIED IDEOGRAPH + {0xE969, 0x9595}, //18391 #CJK UNIFIED IDEOGRAPH + {0xE96A, 0x9596}, //18392 #CJK UNIFIED IDEOGRAPH + {0xE96B, 0x9597}, //18393 #CJK UNIFIED IDEOGRAPH + {0xE96C, 0x9598}, //18394 #CJK UNIFIED IDEOGRAPH + {0xE96D, 0x9599}, //18395 #CJK UNIFIED IDEOGRAPH + {0xE96E, 0x959A}, //18396 #CJK UNIFIED IDEOGRAPH + {0xE96F, 0x959B}, //18397 #CJK UNIFIED IDEOGRAPH + {0xE970, 0x959C}, //18398 #CJK UNIFIED IDEOGRAPH + {0xE971, 0x959D}, //18399 #CJK UNIFIED IDEOGRAPH + {0xE972, 0x959E}, //18400 #CJK UNIFIED IDEOGRAPH + {0xE973, 0x959F}, //18401 #CJK UNIFIED IDEOGRAPH + {0xE974, 0x95A0}, //18402 #CJK UNIFIED IDEOGRAPH + {0xE975, 0x95A1}, //18403 #CJK UNIFIED IDEOGRAPH + {0xE976, 0x95A2}, //18404 #CJK UNIFIED IDEOGRAPH + {0xE977, 0x95A3}, //18405 #CJK UNIFIED IDEOGRAPH + {0xE978, 0x95A4}, //18406 #CJK UNIFIED IDEOGRAPH + {0xE979, 0x95A5}, //18407 #CJK UNIFIED IDEOGRAPH + {0xE97A, 0x95A6}, //18408 #CJK UNIFIED IDEOGRAPH + {0xE97B, 0x95A7}, //18409 #CJK UNIFIED IDEOGRAPH + {0xE97C, 0x95A8}, //18410 #CJK UNIFIED IDEOGRAPH + {0xE97D, 0x95A9}, //18411 #CJK UNIFIED IDEOGRAPH + {0xE97E, 0x95AA}, //18412 #CJK UNIFIED IDEOGRAPH + {0xE980, 0x95AB}, //18413 #CJK UNIFIED IDEOGRAPH + {0xE981, 0x95AC}, //18414 #CJK UNIFIED IDEOGRAPH + {0xE982, 0x95AD}, //18415 #CJK UNIFIED IDEOGRAPH + {0xE983, 0x95AE}, //18416 #CJK UNIFIED IDEOGRAPH + {0xE984, 0x95AF}, //18417 #CJK UNIFIED IDEOGRAPH + {0xE985, 0x95B0}, //18418 #CJK UNIFIED IDEOGRAPH + {0xE986, 0x95B1}, //18419 #CJK UNIFIED IDEOGRAPH + {0xE987, 0x95B2}, //18420 #CJK UNIFIED IDEOGRAPH + {0xE988, 0x95B3}, //18421 #CJK UNIFIED IDEOGRAPH + {0xE989, 0x95B4}, //18422 #CJK UNIFIED IDEOGRAPH + {0xE98A, 0x95B5}, //18423 #CJK UNIFIED IDEOGRAPH + {0xE98B, 0x95B6}, //18424 #CJK UNIFIED IDEOGRAPH + {0xE98C, 0x95B7}, //18425 #CJK UNIFIED IDEOGRAPH + {0xE98D, 0x95B8}, //18426 #CJK UNIFIED IDEOGRAPH + {0xE98E, 0x95B9}, //18427 #CJK UNIFIED IDEOGRAPH + {0xE98F, 0x95BA}, //18428 #CJK UNIFIED IDEOGRAPH + {0xE990, 0x95BB}, //18429 #CJK UNIFIED IDEOGRAPH + {0xE991, 0x95BC}, //18430 #CJK UNIFIED IDEOGRAPH + {0xE992, 0x95BD}, //18431 #CJK UNIFIED IDEOGRAPH + {0xE993, 0x95BE}, //18432 #CJK UNIFIED IDEOGRAPH + {0xE994, 0x95BF}, //18433 #CJK UNIFIED IDEOGRAPH + {0xE995, 0x95C0}, //18434 #CJK UNIFIED IDEOGRAPH + {0xE996, 0x95C1}, //18435 #CJK UNIFIED IDEOGRAPH + {0xE997, 0x95C2}, //18436 #CJK UNIFIED IDEOGRAPH + {0xE998, 0x95C3}, //18437 #CJK UNIFIED IDEOGRAPH + {0xE999, 0x95C4}, //18438 #CJK UNIFIED IDEOGRAPH + {0xE99A, 0x95C5}, //18439 #CJK UNIFIED IDEOGRAPH + {0xE99B, 0x95C6}, //18440 #CJK UNIFIED IDEOGRAPH + {0xE99C, 0x95C7}, //18441 #CJK UNIFIED IDEOGRAPH + {0xE99D, 0x95C8}, //18442 #CJK UNIFIED IDEOGRAPH + {0xE99E, 0x95C9}, //18443 #CJK UNIFIED IDEOGRAPH + {0xE99F, 0x95CA}, //18444 #CJK UNIFIED IDEOGRAPH + {0xE9A0, 0x95CB}, //18445 #CJK UNIFIED IDEOGRAPH + {0xE9A1, 0x6924}, //18446 #CJK UNIFIED IDEOGRAPH + {0xE9A2, 0x68F0}, //18447 #CJK UNIFIED IDEOGRAPH + {0xE9A3, 0x690B}, //18448 #CJK UNIFIED IDEOGRAPH + {0xE9A4, 0x6901}, //18449 #CJK UNIFIED IDEOGRAPH + {0xE9A5, 0x6957}, //18450 #CJK UNIFIED IDEOGRAPH + {0xE9A6, 0x68E3}, //18451 #CJK UNIFIED IDEOGRAPH + {0xE9A7, 0x6910}, //18452 #CJK UNIFIED IDEOGRAPH + {0xE9A8, 0x6971}, //18453 #CJK UNIFIED IDEOGRAPH + {0xE9A9, 0x6939}, //18454 #CJK UNIFIED IDEOGRAPH + {0xE9AA, 0x6960}, //18455 #CJK UNIFIED IDEOGRAPH + {0xE9AB, 0x6942}, //18456 #CJK UNIFIED IDEOGRAPH + {0xE9AC, 0x695D}, //18457 #CJK UNIFIED IDEOGRAPH + {0xE9AD, 0x6984}, //18458 #CJK UNIFIED IDEOGRAPH + {0xE9AE, 0x696B}, //18459 #CJK UNIFIED IDEOGRAPH + {0xE9AF, 0x6980}, //18460 #CJK UNIFIED IDEOGRAPH + {0xE9B0, 0x6998}, //18461 #CJK UNIFIED IDEOGRAPH + {0xE9B1, 0x6978}, //18462 #CJK UNIFIED IDEOGRAPH + {0xE9B2, 0x6934}, //18463 #CJK UNIFIED IDEOGRAPH + {0xE9B3, 0x69CC}, //18464 #CJK UNIFIED IDEOGRAPH + {0xE9B4, 0x6987}, //18465 #CJK UNIFIED IDEOGRAPH + {0xE9B5, 0x6988}, //18466 #CJK UNIFIED IDEOGRAPH + {0xE9B6, 0x69CE}, //18467 #CJK UNIFIED IDEOGRAPH + {0xE9B7, 0x6989}, //18468 #CJK UNIFIED IDEOGRAPH + {0xE9B8, 0x6966}, //18469 #CJK UNIFIED IDEOGRAPH + {0xE9B9, 0x6963}, //18470 #CJK UNIFIED IDEOGRAPH + {0xE9BA, 0x6979}, //18471 #CJK UNIFIED IDEOGRAPH + {0xE9BB, 0x699B}, //18472 #CJK UNIFIED IDEOGRAPH + {0xE9BC, 0x69A7}, //18473 #CJK UNIFIED IDEOGRAPH + {0xE9BD, 0x69BB}, //18474 #CJK UNIFIED IDEOGRAPH + {0xE9BE, 0x69AB}, //18475 #CJK UNIFIED IDEOGRAPH + {0xE9BF, 0x69AD}, //18476 #CJK UNIFIED IDEOGRAPH + {0xE9C0, 0x69D4}, //18477 #CJK UNIFIED IDEOGRAPH + {0xE9C1, 0x69B1}, //18478 #CJK UNIFIED IDEOGRAPH + {0xE9C2, 0x69C1}, //18479 #CJK UNIFIED IDEOGRAPH + {0xE9C3, 0x69CA}, //18480 #CJK UNIFIED IDEOGRAPH + {0xE9C4, 0x69DF}, //18481 #CJK UNIFIED IDEOGRAPH + {0xE9C5, 0x6995}, //18482 #CJK UNIFIED IDEOGRAPH + {0xE9C6, 0x69E0}, //18483 #CJK UNIFIED IDEOGRAPH + {0xE9C7, 0x698D}, //18484 #CJK UNIFIED IDEOGRAPH + {0xE9C8, 0x69FF}, //18485 #CJK UNIFIED IDEOGRAPH + {0xE9C9, 0x6A2F}, //18486 #CJK UNIFIED IDEOGRAPH + {0xE9CA, 0x69ED}, //18487 #CJK UNIFIED IDEOGRAPH + {0xE9CB, 0x6A17}, //18488 #CJK UNIFIED IDEOGRAPH + {0xE9CC, 0x6A18}, //18489 #CJK UNIFIED IDEOGRAPH + {0xE9CD, 0x6A65}, //18490 #CJK UNIFIED IDEOGRAPH + {0xE9CE, 0x69F2}, //18491 #CJK UNIFIED IDEOGRAPH + {0xE9CF, 0x6A44}, //18492 #CJK UNIFIED IDEOGRAPH + {0xE9D0, 0x6A3E}, //18493 #CJK UNIFIED IDEOGRAPH + {0xE9D1, 0x6AA0}, //18494 #CJK UNIFIED IDEOGRAPH + {0xE9D2, 0x6A50}, //18495 #CJK UNIFIED IDEOGRAPH + {0xE9D3, 0x6A5B}, //18496 #CJK UNIFIED IDEOGRAPH + {0xE9D4, 0x6A35}, //18497 #CJK UNIFIED IDEOGRAPH + {0xE9D5, 0x6A8E}, //18498 #CJK UNIFIED IDEOGRAPH + {0xE9D6, 0x6A79}, //18499 #CJK UNIFIED IDEOGRAPH + {0xE9D7, 0x6A3D}, //18500 #CJK UNIFIED IDEOGRAPH + {0xE9D8, 0x6A28}, //18501 #CJK UNIFIED IDEOGRAPH + {0xE9D9, 0x6A58}, //18502 #CJK UNIFIED IDEOGRAPH + {0xE9DA, 0x6A7C}, //18503 #CJK UNIFIED IDEOGRAPH + {0xE9DB, 0x6A91}, //18504 #CJK UNIFIED IDEOGRAPH + {0xE9DC, 0x6A90}, //18505 #CJK UNIFIED IDEOGRAPH + {0xE9DD, 0x6AA9}, //18506 #CJK UNIFIED IDEOGRAPH + {0xE9DE, 0x6A97}, //18507 #CJK UNIFIED IDEOGRAPH + {0xE9DF, 0x6AAB}, //18508 #CJK UNIFIED IDEOGRAPH + {0xE9E0, 0x7337}, //18509 #CJK UNIFIED IDEOGRAPH + {0xE9E1, 0x7352}, //18510 #CJK UNIFIED IDEOGRAPH + {0xE9E2, 0x6B81}, //18511 #CJK UNIFIED IDEOGRAPH + {0xE9E3, 0x6B82}, //18512 #CJK UNIFIED IDEOGRAPH + {0xE9E4, 0x6B87}, //18513 #CJK UNIFIED IDEOGRAPH + {0xE9E5, 0x6B84}, //18514 #CJK UNIFIED IDEOGRAPH + {0xE9E6, 0x6B92}, //18515 #CJK UNIFIED IDEOGRAPH + {0xE9E7, 0x6B93}, //18516 #CJK UNIFIED IDEOGRAPH + {0xE9E8, 0x6B8D}, //18517 #CJK UNIFIED IDEOGRAPH + {0xE9E9, 0x6B9A}, //18518 #CJK UNIFIED IDEOGRAPH + {0xE9EA, 0x6B9B}, //18519 #CJK UNIFIED IDEOGRAPH + {0xE9EB, 0x6BA1}, //18520 #CJK UNIFIED IDEOGRAPH + {0xE9EC, 0x6BAA}, //18521 #CJK UNIFIED IDEOGRAPH + {0xE9ED, 0x8F6B}, //18522 #CJK UNIFIED IDEOGRAPH + {0xE9EE, 0x8F6D}, //18523 #CJK UNIFIED IDEOGRAPH + {0xE9EF, 0x8F71}, //18524 #CJK UNIFIED IDEOGRAPH + {0xE9F0, 0x8F72}, //18525 #CJK UNIFIED IDEOGRAPH + {0xE9F1, 0x8F73}, //18526 #CJK UNIFIED IDEOGRAPH + {0xE9F2, 0x8F75}, //18527 #CJK UNIFIED IDEOGRAPH + {0xE9F3, 0x8F76}, //18528 #CJK UNIFIED IDEOGRAPH + {0xE9F4, 0x8F78}, //18529 #CJK UNIFIED IDEOGRAPH + {0xE9F5, 0x8F77}, //18530 #CJK UNIFIED IDEOGRAPH + {0xE9F6, 0x8F79}, //18531 #CJK UNIFIED IDEOGRAPH + {0xE9F7, 0x8F7A}, //18532 #CJK UNIFIED IDEOGRAPH + {0xE9F8, 0x8F7C}, //18533 #CJK UNIFIED IDEOGRAPH + {0xE9F9, 0x8F7E}, //18534 #CJK UNIFIED IDEOGRAPH + {0xE9FA, 0x8F81}, //18535 #CJK UNIFIED IDEOGRAPH + {0xE9FB, 0x8F82}, //18536 #CJK UNIFIED IDEOGRAPH + {0xE9FC, 0x8F84}, //18537 #CJK UNIFIED IDEOGRAPH + {0xE9FD, 0x8F87}, //18538 #CJK UNIFIED IDEOGRAPH + {0xE9FE, 0x8F8B}, //18539 #CJK UNIFIED IDEOGRAPH + {0xEA40, 0x95CC}, //18540 #CJK UNIFIED IDEOGRAPH + {0xEA41, 0x95CD}, //18541 #CJK UNIFIED IDEOGRAPH + {0xEA42, 0x95CE}, //18542 #CJK UNIFIED IDEOGRAPH + {0xEA43, 0x95CF}, //18543 #CJK UNIFIED IDEOGRAPH + {0xEA44, 0x95D0}, //18544 #CJK UNIFIED IDEOGRAPH + {0xEA45, 0x95D1}, //18545 #CJK UNIFIED IDEOGRAPH + {0xEA46, 0x95D2}, //18546 #CJK UNIFIED IDEOGRAPH + {0xEA47, 0x95D3}, //18547 #CJK UNIFIED IDEOGRAPH + {0xEA48, 0x95D4}, //18548 #CJK UNIFIED IDEOGRAPH + {0xEA49, 0x95D5}, //18549 #CJK UNIFIED IDEOGRAPH + {0xEA4A, 0x95D6}, //18550 #CJK UNIFIED IDEOGRAPH + {0xEA4B, 0x95D7}, //18551 #CJK UNIFIED IDEOGRAPH + {0xEA4C, 0x95D8}, //18552 #CJK UNIFIED IDEOGRAPH + {0xEA4D, 0x95D9}, //18553 #CJK UNIFIED IDEOGRAPH + {0xEA4E, 0x95DA}, //18554 #CJK UNIFIED IDEOGRAPH + {0xEA4F, 0x95DB}, //18555 #CJK UNIFIED IDEOGRAPH + {0xEA50, 0x95DC}, //18556 #CJK UNIFIED IDEOGRAPH + {0xEA51, 0x95DD}, //18557 #CJK UNIFIED IDEOGRAPH + {0xEA52, 0x95DE}, //18558 #CJK UNIFIED IDEOGRAPH + {0xEA53, 0x95DF}, //18559 #CJK UNIFIED IDEOGRAPH + {0xEA54, 0x95E0}, //18560 #CJK UNIFIED IDEOGRAPH + {0xEA55, 0x95E1}, //18561 #CJK UNIFIED IDEOGRAPH + {0xEA56, 0x95E2}, //18562 #CJK UNIFIED IDEOGRAPH + {0xEA57, 0x95E3}, //18563 #CJK UNIFIED IDEOGRAPH + {0xEA58, 0x95E4}, //18564 #CJK UNIFIED IDEOGRAPH + {0xEA59, 0x95E5}, //18565 #CJK UNIFIED IDEOGRAPH + {0xEA5A, 0x95E6}, //18566 #CJK UNIFIED IDEOGRAPH + {0xEA5B, 0x95E7}, //18567 #CJK UNIFIED IDEOGRAPH + {0xEA5C, 0x95EC}, //18568 #CJK UNIFIED IDEOGRAPH + {0xEA5D, 0x95FF}, //18569 #CJK UNIFIED IDEOGRAPH + {0xEA5E, 0x9607}, //18570 #CJK UNIFIED IDEOGRAPH + {0xEA5F, 0x9613}, //18571 #CJK UNIFIED IDEOGRAPH + {0xEA60, 0x9618}, //18572 #CJK UNIFIED IDEOGRAPH + {0xEA61, 0x961B}, //18573 #CJK UNIFIED IDEOGRAPH + {0xEA62, 0x961E}, //18574 #CJK UNIFIED IDEOGRAPH + {0xEA63, 0x9620}, //18575 #CJK UNIFIED IDEOGRAPH + {0xEA64, 0x9623}, //18576 #CJK UNIFIED IDEOGRAPH + {0xEA65, 0x9624}, //18577 #CJK UNIFIED IDEOGRAPH + {0xEA66, 0x9625}, //18578 #CJK UNIFIED IDEOGRAPH + {0xEA67, 0x9626}, //18579 #CJK UNIFIED IDEOGRAPH + {0xEA68, 0x9627}, //18580 #CJK UNIFIED IDEOGRAPH + {0xEA69, 0x9628}, //18581 #CJK UNIFIED IDEOGRAPH + {0xEA6A, 0x9629}, //18582 #CJK UNIFIED IDEOGRAPH + {0xEA6B, 0x962B}, //18583 #CJK UNIFIED IDEOGRAPH + {0xEA6C, 0x962C}, //18584 #CJK UNIFIED IDEOGRAPH + {0xEA6D, 0x962D}, //18585 #CJK UNIFIED IDEOGRAPH + {0xEA6E, 0x962F}, //18586 #CJK UNIFIED IDEOGRAPH + {0xEA6F, 0x9630}, //18587 #CJK UNIFIED IDEOGRAPH + {0xEA70, 0x9637}, //18588 #CJK UNIFIED IDEOGRAPH + {0xEA71, 0x9638}, //18589 #CJK UNIFIED IDEOGRAPH + {0xEA72, 0x9639}, //18590 #CJK UNIFIED IDEOGRAPH + {0xEA73, 0x963A}, //18591 #CJK UNIFIED IDEOGRAPH + {0xEA74, 0x963E}, //18592 #CJK UNIFIED IDEOGRAPH + {0xEA75, 0x9641}, //18593 #CJK UNIFIED IDEOGRAPH + {0xEA76, 0x9643}, //18594 #CJK UNIFIED IDEOGRAPH + {0xEA77, 0x964A}, //18595 #CJK UNIFIED IDEOGRAPH + {0xEA78, 0x964E}, //18596 #CJK UNIFIED IDEOGRAPH + {0xEA79, 0x964F}, //18597 #CJK UNIFIED IDEOGRAPH + {0xEA7A, 0x9651}, //18598 #CJK UNIFIED IDEOGRAPH + {0xEA7B, 0x9652}, //18599 #CJK UNIFIED IDEOGRAPH + {0xEA7C, 0x9653}, //18600 #CJK UNIFIED IDEOGRAPH + {0xEA7D, 0x9656}, //18601 #CJK UNIFIED IDEOGRAPH + {0xEA7E, 0x9657}, //18602 #CJK UNIFIED IDEOGRAPH + {0xEA80, 0x9658}, //18603 #CJK UNIFIED IDEOGRAPH + {0xEA81, 0x9659}, //18604 #CJK UNIFIED IDEOGRAPH + {0xEA82, 0x965A}, //18605 #CJK UNIFIED IDEOGRAPH + {0xEA83, 0x965C}, //18606 #CJK UNIFIED IDEOGRAPH + {0xEA84, 0x965D}, //18607 #CJK UNIFIED IDEOGRAPH + {0xEA85, 0x965E}, //18608 #CJK UNIFIED IDEOGRAPH + {0xEA86, 0x9660}, //18609 #CJK UNIFIED IDEOGRAPH + {0xEA87, 0x9663}, //18610 #CJK UNIFIED IDEOGRAPH + {0xEA88, 0x9665}, //18611 #CJK UNIFIED IDEOGRAPH + {0xEA89, 0x9666}, //18612 #CJK UNIFIED IDEOGRAPH + {0xEA8A, 0x966B}, //18613 #CJK UNIFIED IDEOGRAPH + {0xEA8B, 0x966D}, //18614 #CJK UNIFIED IDEOGRAPH + {0xEA8C, 0x966E}, //18615 #CJK UNIFIED IDEOGRAPH + {0xEA8D, 0x966F}, //18616 #CJK UNIFIED IDEOGRAPH + {0xEA8E, 0x9670}, //18617 #CJK UNIFIED IDEOGRAPH + {0xEA8F, 0x9671}, //18618 #CJK UNIFIED IDEOGRAPH + {0xEA90, 0x9673}, //18619 #CJK UNIFIED IDEOGRAPH + {0xEA91, 0x9678}, //18620 #CJK UNIFIED IDEOGRAPH + {0xEA92, 0x9679}, //18621 #CJK UNIFIED IDEOGRAPH + {0xEA93, 0x967A}, //18622 #CJK UNIFIED IDEOGRAPH + {0xEA94, 0x967B}, //18623 #CJK UNIFIED IDEOGRAPH + {0xEA95, 0x967C}, //18624 #CJK UNIFIED IDEOGRAPH + {0xEA96, 0x967D}, //18625 #CJK UNIFIED IDEOGRAPH + {0xEA97, 0x967E}, //18626 #CJK UNIFIED IDEOGRAPH + {0xEA98, 0x967F}, //18627 #CJK UNIFIED IDEOGRAPH + {0xEA99, 0x9680}, //18628 #CJK UNIFIED IDEOGRAPH + {0xEA9A, 0x9681}, //18629 #CJK UNIFIED IDEOGRAPH + {0xEA9B, 0x9682}, //18630 #CJK UNIFIED IDEOGRAPH + {0xEA9C, 0x9683}, //18631 #CJK UNIFIED IDEOGRAPH + {0xEA9D, 0x9684}, //18632 #CJK UNIFIED IDEOGRAPH + {0xEA9E, 0x9687}, //18633 #CJK UNIFIED IDEOGRAPH + {0xEA9F, 0x9689}, //18634 #CJK UNIFIED IDEOGRAPH + {0xEAA0, 0x968A}, //18635 #CJK UNIFIED IDEOGRAPH + {0xEAA1, 0x8F8D}, //18636 #CJK UNIFIED IDEOGRAPH + {0xEAA2, 0x8F8E}, //18637 #CJK UNIFIED IDEOGRAPH + {0xEAA3, 0x8F8F}, //18638 #CJK UNIFIED IDEOGRAPH + {0xEAA4, 0x8F98}, //18639 #CJK UNIFIED IDEOGRAPH + {0xEAA5, 0x8F9A}, //18640 #CJK UNIFIED IDEOGRAPH + {0xEAA6, 0x8ECE}, //18641 #CJK UNIFIED IDEOGRAPH + {0xEAA7, 0x620B}, //18642 #CJK UNIFIED IDEOGRAPH + {0xEAA8, 0x6217}, //18643 #CJK UNIFIED IDEOGRAPH + {0xEAA9, 0x621B}, //18644 #CJK UNIFIED IDEOGRAPH + {0xEAAA, 0x621F}, //18645 #CJK UNIFIED IDEOGRAPH + {0xEAAB, 0x6222}, //18646 #CJK UNIFIED IDEOGRAPH + {0xEAAC, 0x6221}, //18647 #CJK UNIFIED IDEOGRAPH + {0xEAAD, 0x6225}, //18648 #CJK UNIFIED IDEOGRAPH + {0xEAAE, 0x6224}, //18649 #CJK UNIFIED IDEOGRAPH + {0xEAAF, 0x622C}, //18650 #CJK UNIFIED IDEOGRAPH + {0xEAB0, 0x81E7}, //18651 #CJK UNIFIED IDEOGRAPH + {0xEAB1, 0x74EF}, //18652 #CJK UNIFIED IDEOGRAPH + {0xEAB2, 0x74F4}, //18653 #CJK UNIFIED IDEOGRAPH + {0xEAB3, 0x74FF}, //18654 #CJK UNIFIED IDEOGRAPH + {0xEAB4, 0x750F}, //18655 #CJK UNIFIED IDEOGRAPH + {0xEAB5, 0x7511}, //18656 #CJK UNIFIED IDEOGRAPH + {0xEAB6, 0x7513}, //18657 #CJK UNIFIED IDEOGRAPH + {0xEAB7, 0x6534}, //18658 #CJK UNIFIED IDEOGRAPH + {0xEAB8, 0x65EE}, //18659 #CJK UNIFIED IDEOGRAPH + {0xEAB9, 0x65EF}, //18660 #CJK UNIFIED IDEOGRAPH + {0xEABA, 0x65F0}, //18661 #CJK UNIFIED IDEOGRAPH + {0xEABB, 0x660A}, //18662 #CJK UNIFIED IDEOGRAPH + {0xEABC, 0x6619}, //18663 #CJK UNIFIED IDEOGRAPH + {0xEABD, 0x6772}, //18664 #CJK UNIFIED IDEOGRAPH + {0xEABE, 0x6603}, //18665 #CJK UNIFIED IDEOGRAPH + {0xEABF, 0x6615}, //18666 #CJK UNIFIED IDEOGRAPH + {0xEAC0, 0x6600}, //18667 #CJK UNIFIED IDEOGRAPH + {0xEAC1, 0x7085}, //18668 #CJK UNIFIED IDEOGRAPH + {0xEAC2, 0x66F7}, //18669 #CJK UNIFIED IDEOGRAPH + {0xEAC3, 0x661D}, //18670 #CJK UNIFIED IDEOGRAPH + {0xEAC4, 0x6634}, //18671 #CJK UNIFIED IDEOGRAPH + {0xEAC5, 0x6631}, //18672 #CJK UNIFIED IDEOGRAPH + {0xEAC6, 0x6636}, //18673 #CJK UNIFIED IDEOGRAPH + {0xEAC7, 0x6635}, //18674 #CJK UNIFIED IDEOGRAPH + {0xEAC8, 0x8006}, //18675 #CJK UNIFIED IDEOGRAPH + {0xEAC9, 0x665F}, //18676 #CJK UNIFIED IDEOGRAPH + {0xEACA, 0x6654}, //18677 #CJK UNIFIED IDEOGRAPH + {0xEACB, 0x6641}, //18678 #CJK UNIFIED IDEOGRAPH + {0xEACC, 0x664F}, //18679 #CJK UNIFIED IDEOGRAPH + {0xEACD, 0x6656}, //18680 #CJK UNIFIED IDEOGRAPH + {0xEACE, 0x6661}, //18681 #CJK UNIFIED IDEOGRAPH + {0xEACF, 0x6657}, //18682 #CJK UNIFIED IDEOGRAPH + {0xEAD0, 0x6677}, //18683 #CJK UNIFIED IDEOGRAPH + {0xEAD1, 0x6684}, //18684 #CJK UNIFIED IDEOGRAPH + {0xEAD2, 0x668C}, //18685 #CJK UNIFIED IDEOGRAPH + {0xEAD3, 0x66A7}, //18686 #CJK UNIFIED IDEOGRAPH + {0xEAD4, 0x669D}, //18687 #CJK UNIFIED IDEOGRAPH + {0xEAD5, 0x66BE}, //18688 #CJK UNIFIED IDEOGRAPH + {0xEAD6, 0x66DB}, //18689 #CJK UNIFIED IDEOGRAPH + {0xEAD7, 0x66DC}, //18690 #CJK UNIFIED IDEOGRAPH + {0xEAD8, 0x66E6}, //18691 #CJK UNIFIED IDEOGRAPH + {0xEAD9, 0x66E9}, //18692 #CJK UNIFIED IDEOGRAPH + {0xEADA, 0x8D32}, //18693 #CJK UNIFIED IDEOGRAPH + {0xEADB, 0x8D33}, //18694 #CJK UNIFIED IDEOGRAPH + {0xEADC, 0x8D36}, //18695 #CJK UNIFIED IDEOGRAPH + {0xEADD, 0x8D3B}, //18696 #CJK UNIFIED IDEOGRAPH + {0xEADE, 0x8D3D}, //18697 #CJK UNIFIED IDEOGRAPH + {0xEADF, 0x8D40}, //18698 #CJK UNIFIED IDEOGRAPH + {0xEAE0, 0x8D45}, //18699 #CJK UNIFIED IDEOGRAPH + {0xEAE1, 0x8D46}, //18700 #CJK UNIFIED IDEOGRAPH + {0xEAE2, 0x8D48}, //18701 #CJK UNIFIED IDEOGRAPH + {0xEAE3, 0x8D49}, //18702 #CJK UNIFIED IDEOGRAPH + {0xEAE4, 0x8D47}, //18703 #CJK UNIFIED IDEOGRAPH + {0xEAE5, 0x8D4D}, //18704 #CJK UNIFIED IDEOGRAPH + {0xEAE6, 0x8D55}, //18705 #CJK UNIFIED IDEOGRAPH + {0xEAE7, 0x8D59}, //18706 #CJK UNIFIED IDEOGRAPH + {0xEAE8, 0x89C7}, //18707 #CJK UNIFIED IDEOGRAPH + {0xEAE9, 0x89CA}, //18708 #CJK UNIFIED IDEOGRAPH + {0xEAEA, 0x89CB}, //18709 #CJK UNIFIED IDEOGRAPH + {0xEAEB, 0x89CC}, //18710 #CJK UNIFIED IDEOGRAPH + {0xEAEC, 0x89CE}, //18711 #CJK UNIFIED IDEOGRAPH + {0xEAED, 0x89CF}, //18712 #CJK UNIFIED IDEOGRAPH + {0xEAEE, 0x89D0}, //18713 #CJK UNIFIED IDEOGRAPH + {0xEAEF, 0x89D1}, //18714 #CJK UNIFIED IDEOGRAPH + {0xEAF0, 0x726E}, //18715 #CJK UNIFIED IDEOGRAPH + {0xEAF1, 0x729F}, //18716 #CJK UNIFIED IDEOGRAPH + {0xEAF2, 0x725D}, //18717 #CJK UNIFIED IDEOGRAPH + {0xEAF3, 0x7266}, //18718 #CJK UNIFIED IDEOGRAPH + {0xEAF4, 0x726F}, //18719 #CJK UNIFIED IDEOGRAPH + {0xEAF5, 0x727E}, //18720 #CJK UNIFIED IDEOGRAPH + {0xEAF6, 0x727F}, //18721 #CJK UNIFIED IDEOGRAPH + {0xEAF7, 0x7284}, //18722 #CJK UNIFIED IDEOGRAPH + {0xEAF8, 0x728B}, //18723 #CJK UNIFIED IDEOGRAPH + {0xEAF9, 0x728D}, //18724 #CJK UNIFIED IDEOGRAPH + {0xEAFA, 0x728F}, //18725 #CJK UNIFIED IDEOGRAPH + {0xEAFB, 0x7292}, //18726 #CJK UNIFIED IDEOGRAPH + {0xEAFC, 0x6308}, //18727 #CJK UNIFIED IDEOGRAPH + {0xEAFD, 0x6332}, //18728 #CJK UNIFIED IDEOGRAPH + {0xEAFE, 0x63B0}, //18729 #CJK UNIFIED IDEOGRAPH + {0xEB40, 0x968C}, //18730 #CJK UNIFIED IDEOGRAPH + {0xEB41, 0x968E}, //18731 #CJK UNIFIED IDEOGRAPH + {0xEB42, 0x9691}, //18732 #CJK UNIFIED IDEOGRAPH + {0xEB43, 0x9692}, //18733 #CJK UNIFIED IDEOGRAPH + {0xEB44, 0x9693}, //18734 #CJK UNIFIED IDEOGRAPH + {0xEB45, 0x9695}, //18735 #CJK UNIFIED IDEOGRAPH + {0xEB46, 0x9696}, //18736 #CJK UNIFIED IDEOGRAPH + {0xEB47, 0x969A}, //18737 #CJK UNIFIED IDEOGRAPH + {0xEB48, 0x969B}, //18738 #CJK UNIFIED IDEOGRAPH + {0xEB49, 0x969D}, //18739 #CJK UNIFIED IDEOGRAPH + {0xEB4A, 0x969E}, //18740 #CJK UNIFIED IDEOGRAPH + {0xEB4B, 0x969F}, //18741 #CJK UNIFIED IDEOGRAPH + {0xEB4C, 0x96A0}, //18742 #CJK UNIFIED IDEOGRAPH + {0xEB4D, 0x96A1}, //18743 #CJK UNIFIED IDEOGRAPH + {0xEB4E, 0x96A2}, //18744 #CJK UNIFIED IDEOGRAPH + {0xEB4F, 0x96A3}, //18745 #CJK UNIFIED IDEOGRAPH + {0xEB50, 0x96A4}, //18746 #CJK UNIFIED IDEOGRAPH + {0xEB51, 0x96A5}, //18747 #CJK UNIFIED IDEOGRAPH + {0xEB52, 0x96A6}, //18748 #CJK UNIFIED IDEOGRAPH + {0xEB53, 0x96A8}, //18749 #CJK UNIFIED IDEOGRAPH + {0xEB54, 0x96A9}, //18750 #CJK UNIFIED IDEOGRAPH + {0xEB55, 0x96AA}, //18751 #CJK UNIFIED IDEOGRAPH + {0xEB56, 0x96AB}, //18752 #CJK UNIFIED IDEOGRAPH + {0xEB57, 0x96AC}, //18753 #CJK UNIFIED IDEOGRAPH + {0xEB58, 0x96AD}, //18754 #CJK UNIFIED IDEOGRAPH + {0xEB59, 0x96AE}, //18755 #CJK UNIFIED IDEOGRAPH + {0xEB5A, 0x96AF}, //18756 #CJK UNIFIED IDEOGRAPH + {0xEB5B, 0x96B1}, //18757 #CJK UNIFIED IDEOGRAPH + {0xEB5C, 0x96B2}, //18758 #CJK UNIFIED IDEOGRAPH + {0xEB5D, 0x96B4}, //18759 #CJK UNIFIED IDEOGRAPH + {0xEB5E, 0x96B5}, //18760 #CJK UNIFIED IDEOGRAPH + {0xEB5F, 0x96B7}, //18761 #CJK UNIFIED IDEOGRAPH + {0xEB60, 0x96B8}, //18762 #CJK UNIFIED IDEOGRAPH + {0xEB61, 0x96BA}, //18763 #CJK UNIFIED IDEOGRAPH + {0xEB62, 0x96BB}, //18764 #CJK UNIFIED IDEOGRAPH + {0xEB63, 0x96BF}, //18765 #CJK UNIFIED IDEOGRAPH + {0xEB64, 0x96C2}, //18766 #CJK UNIFIED IDEOGRAPH + {0xEB65, 0x96C3}, //18767 #CJK UNIFIED IDEOGRAPH + {0xEB66, 0x96C8}, //18768 #CJK UNIFIED IDEOGRAPH + {0xEB67, 0x96CA}, //18769 #CJK UNIFIED IDEOGRAPH + {0xEB68, 0x96CB}, //18770 #CJK UNIFIED IDEOGRAPH + {0xEB69, 0x96D0}, //18771 #CJK UNIFIED IDEOGRAPH + {0xEB6A, 0x96D1}, //18772 #CJK UNIFIED IDEOGRAPH + {0xEB6B, 0x96D3}, //18773 #CJK UNIFIED IDEOGRAPH + {0xEB6C, 0x96D4}, //18774 #CJK UNIFIED IDEOGRAPH + {0xEB6D, 0x96D6}, //18775 #CJK UNIFIED IDEOGRAPH + {0xEB6E, 0x96D7}, //18776 #CJK UNIFIED IDEOGRAPH + {0xEB6F, 0x96D8}, //18777 #CJK UNIFIED IDEOGRAPH + {0xEB70, 0x96D9}, //18778 #CJK UNIFIED IDEOGRAPH + {0xEB71, 0x96DA}, //18779 #CJK UNIFIED IDEOGRAPH + {0xEB72, 0x96DB}, //18780 #CJK UNIFIED IDEOGRAPH + {0xEB73, 0x96DC}, //18781 #CJK UNIFIED IDEOGRAPH + {0xEB74, 0x96DD}, //18782 #CJK UNIFIED IDEOGRAPH + {0xEB75, 0x96DE}, //18783 #CJK UNIFIED IDEOGRAPH + {0xEB76, 0x96DF}, //18784 #CJK UNIFIED IDEOGRAPH + {0xEB77, 0x96E1}, //18785 #CJK UNIFIED IDEOGRAPH + {0xEB78, 0x96E2}, //18786 #CJK UNIFIED IDEOGRAPH + {0xEB79, 0x96E3}, //18787 #CJK UNIFIED IDEOGRAPH + {0xEB7A, 0x96E4}, //18788 #CJK UNIFIED IDEOGRAPH + {0xEB7B, 0x96E5}, //18789 #CJK UNIFIED IDEOGRAPH + {0xEB7C, 0x96E6}, //18790 #CJK UNIFIED IDEOGRAPH + {0xEB7D, 0x96E7}, //18791 #CJK UNIFIED IDEOGRAPH + {0xEB7E, 0x96EB}, //18792 #CJK UNIFIED IDEOGRAPH + {0xEB80, 0x96EC}, //18793 #CJK UNIFIED IDEOGRAPH + {0xEB81, 0x96ED}, //18794 #CJK UNIFIED IDEOGRAPH + {0xEB82, 0x96EE}, //18795 #CJK UNIFIED IDEOGRAPH + {0xEB83, 0x96F0}, //18796 #CJK UNIFIED IDEOGRAPH + {0xEB84, 0x96F1}, //18797 #CJK UNIFIED IDEOGRAPH + {0xEB85, 0x96F2}, //18798 #CJK UNIFIED IDEOGRAPH + {0xEB86, 0x96F4}, //18799 #CJK UNIFIED IDEOGRAPH + {0xEB87, 0x96F5}, //18800 #CJK UNIFIED IDEOGRAPH + {0xEB88, 0x96F8}, //18801 #CJK UNIFIED IDEOGRAPH + {0xEB89, 0x96FA}, //18802 #CJK UNIFIED IDEOGRAPH + {0xEB8A, 0x96FB}, //18803 #CJK UNIFIED IDEOGRAPH + {0xEB8B, 0x96FC}, //18804 #CJK UNIFIED IDEOGRAPH + {0xEB8C, 0x96FD}, //18805 #CJK UNIFIED IDEOGRAPH + {0xEB8D, 0x96FF}, //18806 #CJK UNIFIED IDEOGRAPH + {0xEB8E, 0x9702}, //18807 #CJK UNIFIED IDEOGRAPH + {0xEB8F, 0x9703}, //18808 #CJK UNIFIED IDEOGRAPH + {0xEB90, 0x9705}, //18809 #CJK UNIFIED IDEOGRAPH + {0xEB91, 0x970A}, //18810 #CJK UNIFIED IDEOGRAPH + {0xEB92, 0x970B}, //18811 #CJK UNIFIED IDEOGRAPH + {0xEB93, 0x970C}, //18812 #CJK UNIFIED IDEOGRAPH + {0xEB94, 0x9710}, //18813 #CJK UNIFIED IDEOGRAPH + {0xEB95, 0x9711}, //18814 #CJK UNIFIED IDEOGRAPH + {0xEB96, 0x9712}, //18815 #CJK UNIFIED IDEOGRAPH + {0xEB97, 0x9714}, //18816 #CJK UNIFIED IDEOGRAPH + {0xEB98, 0x9715}, //18817 #CJK UNIFIED IDEOGRAPH + {0xEB99, 0x9717}, //18818 #CJK UNIFIED IDEOGRAPH + {0xEB9A, 0x9718}, //18819 #CJK UNIFIED IDEOGRAPH + {0xEB9B, 0x9719}, //18820 #CJK UNIFIED IDEOGRAPH + {0xEB9C, 0x971A}, //18821 #CJK UNIFIED IDEOGRAPH + {0xEB9D, 0x971B}, //18822 #CJK UNIFIED IDEOGRAPH + {0xEB9E, 0x971D}, //18823 #CJK UNIFIED IDEOGRAPH + {0xEB9F, 0x971F}, //18824 #CJK UNIFIED IDEOGRAPH + {0xEBA0, 0x9720}, //18825 #CJK UNIFIED IDEOGRAPH + {0xEBA1, 0x643F}, //18826 #CJK UNIFIED IDEOGRAPH + {0xEBA2, 0x64D8}, //18827 #CJK UNIFIED IDEOGRAPH + {0xEBA3, 0x8004}, //18828 #CJK UNIFIED IDEOGRAPH + {0xEBA4, 0x6BEA}, //18829 #CJK UNIFIED IDEOGRAPH + {0xEBA5, 0x6BF3}, //18830 #CJK UNIFIED IDEOGRAPH + {0xEBA6, 0x6BFD}, //18831 #CJK UNIFIED IDEOGRAPH + {0xEBA7, 0x6BF5}, //18832 #CJK UNIFIED IDEOGRAPH + {0xEBA8, 0x6BF9}, //18833 #CJK UNIFIED IDEOGRAPH + {0xEBA9, 0x6C05}, //18834 #CJK UNIFIED IDEOGRAPH + {0xEBAA, 0x6C07}, //18835 #CJK UNIFIED IDEOGRAPH + {0xEBAB, 0x6C06}, //18836 #CJK UNIFIED IDEOGRAPH + {0xEBAC, 0x6C0D}, //18837 #CJK UNIFIED IDEOGRAPH + {0xEBAD, 0x6C15}, //18838 #CJK UNIFIED IDEOGRAPH + {0xEBAE, 0x6C18}, //18839 #CJK UNIFIED IDEOGRAPH + {0xEBAF, 0x6C19}, //18840 #CJK UNIFIED IDEOGRAPH + {0xEBB0, 0x6C1A}, //18841 #CJK UNIFIED IDEOGRAPH + {0xEBB1, 0x6C21}, //18842 #CJK UNIFIED IDEOGRAPH + {0xEBB2, 0x6C29}, //18843 #CJK UNIFIED IDEOGRAPH + {0xEBB3, 0x6C24}, //18844 #CJK UNIFIED IDEOGRAPH + {0xEBB4, 0x6C2A}, //18845 #CJK UNIFIED IDEOGRAPH + {0xEBB5, 0x6C32}, //18846 #CJK UNIFIED IDEOGRAPH + {0xEBB6, 0x6535}, //18847 #CJK UNIFIED IDEOGRAPH + {0xEBB7, 0x6555}, //18848 #CJK UNIFIED IDEOGRAPH + {0xEBB8, 0x656B}, //18849 #CJK UNIFIED IDEOGRAPH + {0xEBB9, 0x724D}, //18850 #CJK UNIFIED IDEOGRAPH + {0xEBBA, 0x7252}, //18851 #CJK UNIFIED IDEOGRAPH + {0xEBBB, 0x7256}, //18852 #CJK UNIFIED IDEOGRAPH + {0xEBBC, 0x7230}, //18853 #CJK UNIFIED IDEOGRAPH + {0xEBBD, 0x8662}, //18854 #CJK UNIFIED IDEOGRAPH + {0xEBBE, 0x5216}, //18855 #CJK UNIFIED IDEOGRAPH + {0xEBBF, 0x809F}, //18856 #CJK UNIFIED IDEOGRAPH + {0xEBC0, 0x809C}, //18857 #CJK UNIFIED IDEOGRAPH + {0xEBC1, 0x8093}, //18858 #CJK UNIFIED IDEOGRAPH + {0xEBC2, 0x80BC}, //18859 #CJK UNIFIED IDEOGRAPH + {0xEBC3, 0x670A}, //18860 #CJK UNIFIED IDEOGRAPH + {0xEBC4, 0x80BD}, //18861 #CJK UNIFIED IDEOGRAPH + {0xEBC5, 0x80B1}, //18862 #CJK UNIFIED IDEOGRAPH + {0xEBC6, 0x80AB}, //18863 #CJK UNIFIED IDEOGRAPH + {0xEBC7, 0x80AD}, //18864 #CJK UNIFIED IDEOGRAPH + {0xEBC8, 0x80B4}, //18865 #CJK UNIFIED IDEOGRAPH + {0xEBC9, 0x80B7}, //18866 #CJK UNIFIED IDEOGRAPH + {0xEBCA, 0x80E7}, //18867 #CJK UNIFIED IDEOGRAPH + {0xEBCB, 0x80E8}, //18868 #CJK UNIFIED IDEOGRAPH + {0xEBCC, 0x80E9}, //18869 #CJK UNIFIED IDEOGRAPH + {0xEBCD, 0x80EA}, //18870 #CJK UNIFIED IDEOGRAPH + {0xEBCE, 0x80DB}, //18871 #CJK UNIFIED IDEOGRAPH + {0xEBCF, 0x80C2}, //18872 #CJK UNIFIED IDEOGRAPH + {0xEBD0, 0x80C4}, //18873 #CJK UNIFIED IDEOGRAPH + {0xEBD1, 0x80D9}, //18874 #CJK UNIFIED IDEOGRAPH + {0xEBD2, 0x80CD}, //18875 #CJK UNIFIED IDEOGRAPH + {0xEBD3, 0x80D7}, //18876 #CJK UNIFIED IDEOGRAPH + {0xEBD4, 0x6710}, //18877 #CJK UNIFIED IDEOGRAPH + {0xEBD5, 0x80DD}, //18878 #CJK UNIFIED IDEOGRAPH + {0xEBD6, 0x80EB}, //18879 #CJK UNIFIED IDEOGRAPH + {0xEBD7, 0x80F1}, //18880 #CJK UNIFIED IDEOGRAPH + {0xEBD8, 0x80F4}, //18881 #CJK UNIFIED IDEOGRAPH + {0xEBD9, 0x80ED}, //18882 #CJK UNIFIED IDEOGRAPH + {0xEBDA, 0x810D}, //18883 #CJK UNIFIED IDEOGRAPH + {0xEBDB, 0x810E}, //18884 #CJK UNIFIED IDEOGRAPH + {0xEBDC, 0x80F2}, //18885 #CJK UNIFIED IDEOGRAPH + {0xEBDD, 0x80FC}, //18886 #CJK UNIFIED IDEOGRAPH + {0xEBDE, 0x6715}, //18887 #CJK UNIFIED IDEOGRAPH + {0xEBDF, 0x8112}, //18888 #CJK UNIFIED IDEOGRAPH + {0xEBE0, 0x8C5A}, //18889 #CJK UNIFIED IDEOGRAPH + {0xEBE1, 0x8136}, //18890 #CJK UNIFIED IDEOGRAPH + {0xEBE2, 0x811E}, //18891 #CJK UNIFIED IDEOGRAPH + {0xEBE3, 0x812C}, //18892 #CJK UNIFIED IDEOGRAPH + {0xEBE4, 0x8118}, //18893 #CJK UNIFIED IDEOGRAPH + {0xEBE5, 0x8132}, //18894 #CJK UNIFIED IDEOGRAPH + {0xEBE6, 0x8148}, //18895 #CJK UNIFIED IDEOGRAPH + {0xEBE7, 0x814C}, //18896 #CJK UNIFIED IDEOGRAPH + {0xEBE8, 0x8153}, //18897 #CJK UNIFIED IDEOGRAPH + {0xEBE9, 0x8174}, //18898 #CJK UNIFIED IDEOGRAPH + {0xEBEA, 0x8159}, //18899 #CJK UNIFIED IDEOGRAPH + {0xEBEB, 0x815A}, //18900 #CJK UNIFIED IDEOGRAPH + {0xEBEC, 0x8171}, //18901 #CJK UNIFIED IDEOGRAPH + {0xEBED, 0x8160}, //18902 #CJK UNIFIED IDEOGRAPH + {0xEBEE, 0x8169}, //18903 #CJK UNIFIED IDEOGRAPH + {0xEBEF, 0x817C}, //18904 #CJK UNIFIED IDEOGRAPH + {0xEBF0, 0x817D}, //18905 #CJK UNIFIED IDEOGRAPH + {0xEBF1, 0x816D}, //18906 #CJK UNIFIED IDEOGRAPH + {0xEBF2, 0x8167}, //18907 #CJK UNIFIED IDEOGRAPH + {0xEBF3, 0x584D}, //18908 #CJK UNIFIED IDEOGRAPH + {0xEBF4, 0x5AB5}, //18909 #CJK UNIFIED IDEOGRAPH + {0xEBF5, 0x8188}, //18910 #CJK UNIFIED IDEOGRAPH + {0xEBF6, 0x8182}, //18911 #CJK UNIFIED IDEOGRAPH + {0xEBF7, 0x8191}, //18912 #CJK UNIFIED IDEOGRAPH + {0xEBF8, 0x6ED5}, //18913 #CJK UNIFIED IDEOGRAPH + {0xEBF9, 0x81A3}, //18914 #CJK UNIFIED IDEOGRAPH + {0xEBFA, 0x81AA}, //18915 #CJK UNIFIED IDEOGRAPH + {0xEBFB, 0x81CC}, //18916 #CJK UNIFIED IDEOGRAPH + {0xEBFC, 0x6726}, //18917 #CJK UNIFIED IDEOGRAPH + {0xEBFD, 0x81CA}, //18918 #CJK UNIFIED IDEOGRAPH + {0xEBFE, 0x81BB}, //18919 #CJK UNIFIED IDEOGRAPH + {0xEC40, 0x9721}, //18920 #CJK UNIFIED IDEOGRAPH + {0xEC41, 0x9722}, //18921 #CJK UNIFIED IDEOGRAPH + {0xEC42, 0x9723}, //18922 #CJK UNIFIED IDEOGRAPH + {0xEC43, 0x9724}, //18923 #CJK UNIFIED IDEOGRAPH + {0xEC44, 0x9725}, //18924 #CJK UNIFIED IDEOGRAPH + {0xEC45, 0x9726}, //18925 #CJK UNIFIED IDEOGRAPH + {0xEC46, 0x9727}, //18926 #CJK UNIFIED IDEOGRAPH + {0xEC47, 0x9728}, //18927 #CJK UNIFIED IDEOGRAPH + {0xEC48, 0x9729}, //18928 #CJK UNIFIED IDEOGRAPH + {0xEC49, 0x972B}, //18929 #CJK UNIFIED IDEOGRAPH + {0xEC4A, 0x972C}, //18930 #CJK UNIFIED IDEOGRAPH + {0xEC4B, 0x972E}, //18931 #CJK UNIFIED IDEOGRAPH + {0xEC4C, 0x972F}, //18932 #CJK UNIFIED IDEOGRAPH + {0xEC4D, 0x9731}, //18933 #CJK UNIFIED IDEOGRAPH + {0xEC4E, 0x9733}, //18934 #CJK UNIFIED IDEOGRAPH + {0xEC4F, 0x9734}, //18935 #CJK UNIFIED IDEOGRAPH + {0xEC50, 0x9735}, //18936 #CJK UNIFIED IDEOGRAPH + {0xEC51, 0x9736}, //18937 #CJK UNIFIED IDEOGRAPH + {0xEC52, 0x9737}, //18938 #CJK UNIFIED IDEOGRAPH + {0xEC53, 0x973A}, //18939 #CJK UNIFIED IDEOGRAPH + {0xEC54, 0x973B}, //18940 #CJK UNIFIED IDEOGRAPH + {0xEC55, 0x973C}, //18941 #CJK UNIFIED IDEOGRAPH + {0xEC56, 0x973D}, //18942 #CJK UNIFIED IDEOGRAPH + {0xEC57, 0x973F}, //18943 #CJK UNIFIED IDEOGRAPH + {0xEC58, 0x9740}, //18944 #CJK UNIFIED IDEOGRAPH + {0xEC59, 0x9741}, //18945 #CJK UNIFIED IDEOGRAPH + {0xEC5A, 0x9742}, //18946 #CJK UNIFIED IDEOGRAPH + {0xEC5B, 0x9743}, //18947 #CJK UNIFIED IDEOGRAPH + {0xEC5C, 0x9744}, //18948 #CJK UNIFIED IDEOGRAPH + {0xEC5D, 0x9745}, //18949 #CJK UNIFIED IDEOGRAPH + {0xEC5E, 0x9746}, //18950 #CJK UNIFIED IDEOGRAPH + {0xEC5F, 0x9747}, //18951 #CJK UNIFIED IDEOGRAPH + {0xEC60, 0x9748}, //18952 #CJK UNIFIED IDEOGRAPH + {0xEC61, 0x9749}, //18953 #CJK UNIFIED IDEOGRAPH + {0xEC62, 0x974A}, //18954 #CJK UNIFIED IDEOGRAPH + {0xEC63, 0x974B}, //18955 #CJK UNIFIED IDEOGRAPH + {0xEC64, 0x974C}, //18956 #CJK UNIFIED IDEOGRAPH + {0xEC65, 0x974D}, //18957 #CJK UNIFIED IDEOGRAPH + {0xEC66, 0x974E}, //18958 #CJK UNIFIED IDEOGRAPH + {0xEC67, 0x974F}, //18959 #CJK UNIFIED IDEOGRAPH + {0xEC68, 0x9750}, //18960 #CJK UNIFIED IDEOGRAPH + {0xEC69, 0x9751}, //18961 #CJK UNIFIED IDEOGRAPH + {0xEC6A, 0x9754}, //18962 #CJK UNIFIED IDEOGRAPH + {0xEC6B, 0x9755}, //18963 #CJK UNIFIED IDEOGRAPH + {0xEC6C, 0x9757}, //18964 #CJK UNIFIED IDEOGRAPH + {0xEC6D, 0x9758}, //18965 #CJK UNIFIED IDEOGRAPH + {0xEC6E, 0x975A}, //18966 #CJK UNIFIED IDEOGRAPH + {0xEC6F, 0x975C}, //18967 #CJK UNIFIED IDEOGRAPH + {0xEC70, 0x975D}, //18968 #CJK UNIFIED IDEOGRAPH + {0xEC71, 0x975F}, //18969 #CJK UNIFIED IDEOGRAPH + {0xEC72, 0x9763}, //18970 #CJK UNIFIED IDEOGRAPH + {0xEC73, 0x9764}, //18971 #CJK UNIFIED IDEOGRAPH + {0xEC74, 0x9766}, //18972 #CJK UNIFIED IDEOGRAPH + {0xEC75, 0x9767}, //18973 #CJK UNIFIED IDEOGRAPH + {0xEC76, 0x9768}, //18974 #CJK UNIFIED IDEOGRAPH + {0xEC77, 0x976A}, //18975 #CJK UNIFIED IDEOGRAPH + {0xEC78, 0x976B}, //18976 #CJK UNIFIED IDEOGRAPH + {0xEC79, 0x976C}, //18977 #CJK UNIFIED IDEOGRAPH + {0xEC7A, 0x976D}, //18978 #CJK UNIFIED IDEOGRAPH + {0xEC7B, 0x976E}, //18979 #CJK UNIFIED IDEOGRAPH + {0xEC7C, 0x976F}, //18980 #CJK UNIFIED IDEOGRAPH + {0xEC7D, 0x9770}, //18981 #CJK UNIFIED IDEOGRAPH + {0xEC7E, 0x9771}, //18982 #CJK UNIFIED IDEOGRAPH + {0xEC80, 0x9772}, //18983 #CJK UNIFIED IDEOGRAPH + {0xEC81, 0x9775}, //18984 #CJK UNIFIED IDEOGRAPH + {0xEC82, 0x9777}, //18985 #CJK UNIFIED IDEOGRAPH + {0xEC83, 0x9778}, //18986 #CJK UNIFIED IDEOGRAPH + {0xEC84, 0x9779}, //18987 #CJK UNIFIED IDEOGRAPH + {0xEC85, 0x977A}, //18988 #CJK UNIFIED IDEOGRAPH + {0xEC86, 0x977B}, //18989 #CJK UNIFIED IDEOGRAPH + {0xEC87, 0x977D}, //18990 #CJK UNIFIED IDEOGRAPH + {0xEC88, 0x977E}, //18991 #CJK UNIFIED IDEOGRAPH + {0xEC89, 0x977F}, //18992 #CJK UNIFIED IDEOGRAPH + {0xEC8A, 0x9780}, //18993 #CJK UNIFIED IDEOGRAPH + {0xEC8B, 0x9781}, //18994 #CJK UNIFIED IDEOGRAPH + {0xEC8C, 0x9782}, //18995 #CJK UNIFIED IDEOGRAPH + {0xEC8D, 0x9783}, //18996 #CJK UNIFIED IDEOGRAPH + {0xEC8E, 0x9784}, //18997 #CJK UNIFIED IDEOGRAPH + {0xEC8F, 0x9786}, //18998 #CJK UNIFIED IDEOGRAPH + {0xEC90, 0x9787}, //18999 #CJK UNIFIED IDEOGRAPH + {0xEC91, 0x9788}, //19000 #CJK UNIFIED IDEOGRAPH + {0xEC92, 0x9789}, //19001 #CJK UNIFIED IDEOGRAPH + {0xEC93, 0x978A}, //19002 #CJK UNIFIED IDEOGRAPH + {0xEC94, 0x978C}, //19003 #CJK UNIFIED IDEOGRAPH + {0xEC95, 0x978E}, //19004 #CJK UNIFIED IDEOGRAPH + {0xEC96, 0x978F}, //19005 #CJK UNIFIED IDEOGRAPH + {0xEC97, 0x9790}, //19006 #CJK UNIFIED IDEOGRAPH + {0xEC98, 0x9793}, //19007 #CJK UNIFIED IDEOGRAPH + {0xEC99, 0x9795}, //19008 #CJK UNIFIED IDEOGRAPH + {0xEC9A, 0x9796}, //19009 #CJK UNIFIED IDEOGRAPH + {0xEC9B, 0x9797}, //19010 #CJK UNIFIED IDEOGRAPH + {0xEC9C, 0x9799}, //19011 #CJK UNIFIED IDEOGRAPH + {0xEC9D, 0x979A}, //19012 #CJK UNIFIED IDEOGRAPH + {0xEC9E, 0x979B}, //19013 #CJK UNIFIED IDEOGRAPH + {0xEC9F, 0x979C}, //19014 #CJK UNIFIED IDEOGRAPH + {0xECA0, 0x979D}, //19015 #CJK UNIFIED IDEOGRAPH + {0xECA1, 0x81C1}, //19016 #CJK UNIFIED IDEOGRAPH + {0xECA2, 0x81A6}, //19017 #CJK UNIFIED IDEOGRAPH + {0xECA3, 0x6B24}, //19018 #CJK UNIFIED IDEOGRAPH + {0xECA4, 0x6B37}, //19019 #CJK UNIFIED IDEOGRAPH + {0xECA5, 0x6B39}, //19020 #CJK UNIFIED IDEOGRAPH + {0xECA6, 0x6B43}, //19021 #CJK UNIFIED IDEOGRAPH + {0xECA7, 0x6B46}, //19022 #CJK UNIFIED IDEOGRAPH + {0xECA8, 0x6B59}, //19023 #CJK UNIFIED IDEOGRAPH + {0xECA9, 0x98D1}, //19024 #CJK UNIFIED IDEOGRAPH + {0xECAA, 0x98D2}, //19025 #CJK UNIFIED IDEOGRAPH + {0xECAB, 0x98D3}, //19026 #CJK UNIFIED IDEOGRAPH + {0xECAC, 0x98D5}, //19027 #CJK UNIFIED IDEOGRAPH + {0xECAD, 0x98D9}, //19028 #CJK UNIFIED IDEOGRAPH + {0xECAE, 0x98DA}, //19029 #CJK UNIFIED IDEOGRAPH + {0xECAF, 0x6BB3}, //19030 #CJK UNIFIED IDEOGRAPH + {0xECB0, 0x5F40}, //19031 #CJK UNIFIED IDEOGRAPH + {0xECB1, 0x6BC2}, //19032 #CJK UNIFIED IDEOGRAPH + {0xECB2, 0x89F3}, //19033 #CJK UNIFIED IDEOGRAPH + {0xECB3, 0x6590}, //19034 #CJK UNIFIED IDEOGRAPH + {0xECB4, 0x9F51}, //19035 #CJK UNIFIED IDEOGRAPH + {0xECB5, 0x6593}, //19036 #CJK UNIFIED IDEOGRAPH + {0xECB6, 0x65BC}, //19037 #CJK UNIFIED IDEOGRAPH + {0xECB7, 0x65C6}, //19038 #CJK UNIFIED IDEOGRAPH + {0xECB8, 0x65C4}, //19039 #CJK UNIFIED IDEOGRAPH + {0xECB9, 0x65C3}, //19040 #CJK UNIFIED IDEOGRAPH + {0xECBA, 0x65CC}, //19041 #CJK UNIFIED IDEOGRAPH + {0xECBB, 0x65CE}, //19042 #CJK UNIFIED IDEOGRAPH + {0xECBC, 0x65D2}, //19043 #CJK UNIFIED IDEOGRAPH + {0xECBD, 0x65D6}, //19044 #CJK UNIFIED IDEOGRAPH + {0xECBE, 0x7080}, //19045 #CJK UNIFIED IDEOGRAPH + {0xECBF, 0x709C}, //19046 #CJK UNIFIED IDEOGRAPH + {0xECC0, 0x7096}, //19047 #CJK UNIFIED IDEOGRAPH + {0xECC1, 0x709D}, //19048 #CJK UNIFIED IDEOGRAPH + {0xECC2, 0x70BB}, //19049 #CJK UNIFIED IDEOGRAPH + {0xECC3, 0x70C0}, //19050 #CJK UNIFIED IDEOGRAPH + {0xECC4, 0x70B7}, //19051 #CJK UNIFIED IDEOGRAPH + {0xECC5, 0x70AB}, //19052 #CJK UNIFIED IDEOGRAPH + {0xECC6, 0x70B1}, //19053 #CJK UNIFIED IDEOGRAPH + {0xECC7, 0x70E8}, //19054 #CJK UNIFIED IDEOGRAPH + {0xECC8, 0x70CA}, //19055 #CJK UNIFIED IDEOGRAPH + {0xECC9, 0x7110}, //19056 #CJK UNIFIED IDEOGRAPH + {0xECCA, 0x7113}, //19057 #CJK UNIFIED IDEOGRAPH + {0xECCB, 0x7116}, //19058 #CJK UNIFIED IDEOGRAPH + {0xECCC, 0x712F}, //19059 #CJK UNIFIED IDEOGRAPH + {0xECCD, 0x7131}, //19060 #CJK UNIFIED IDEOGRAPH + {0xECCE, 0x7173}, //19061 #CJK UNIFIED IDEOGRAPH + {0xECCF, 0x715C}, //19062 #CJK UNIFIED IDEOGRAPH + {0xECD0, 0x7168}, //19063 #CJK UNIFIED IDEOGRAPH + {0xECD1, 0x7145}, //19064 #CJK UNIFIED IDEOGRAPH + {0xECD2, 0x7172}, //19065 #CJK UNIFIED IDEOGRAPH + {0xECD3, 0x714A}, //19066 #CJK UNIFIED IDEOGRAPH + {0xECD4, 0x7178}, //19067 #CJK UNIFIED IDEOGRAPH + {0xECD5, 0x717A}, //19068 #CJK UNIFIED IDEOGRAPH + {0xECD6, 0x7198}, //19069 #CJK UNIFIED IDEOGRAPH + {0xECD7, 0x71B3}, //19070 #CJK UNIFIED IDEOGRAPH + {0xECD8, 0x71B5}, //19071 #CJK UNIFIED IDEOGRAPH + {0xECD9, 0x71A8}, //19072 #CJK UNIFIED IDEOGRAPH + {0xECDA, 0x71A0}, //19073 #CJK UNIFIED IDEOGRAPH + {0xECDB, 0x71E0}, //19074 #CJK UNIFIED IDEOGRAPH + {0xECDC, 0x71D4}, //19075 #CJK UNIFIED IDEOGRAPH + {0xECDD, 0x71E7}, //19076 #CJK UNIFIED IDEOGRAPH + {0xECDE, 0x71F9}, //19077 #CJK UNIFIED IDEOGRAPH + {0xECDF, 0x721D}, //19078 #CJK UNIFIED IDEOGRAPH + {0xECE0, 0x7228}, //19079 #CJK UNIFIED IDEOGRAPH + {0xECE1, 0x706C}, //19080 #CJK UNIFIED IDEOGRAPH + {0xECE2, 0x7118}, //19081 #CJK UNIFIED IDEOGRAPH + {0xECE3, 0x7166}, //19082 #CJK UNIFIED IDEOGRAPH + {0xECE4, 0x71B9}, //19083 #CJK UNIFIED IDEOGRAPH + {0xECE5, 0x623E}, //19084 #CJK UNIFIED IDEOGRAPH + {0xECE6, 0x623D}, //19085 #CJK UNIFIED IDEOGRAPH + {0xECE7, 0x6243}, //19086 #CJK UNIFIED IDEOGRAPH + {0xECE8, 0x6248}, //19087 #CJK UNIFIED IDEOGRAPH + {0xECE9, 0x6249}, //19088 #CJK UNIFIED IDEOGRAPH + {0xECEA, 0x793B}, //19089 #CJK UNIFIED IDEOGRAPH + {0xECEB, 0x7940}, //19090 #CJK UNIFIED IDEOGRAPH + {0xECEC, 0x7946}, //19091 #CJK UNIFIED IDEOGRAPH + {0xECED, 0x7949}, //19092 #CJK UNIFIED IDEOGRAPH + {0xECEE, 0x795B}, //19093 #CJK UNIFIED IDEOGRAPH + {0xECEF, 0x795C}, //19094 #CJK UNIFIED IDEOGRAPH + {0xECF0, 0x7953}, //19095 #CJK UNIFIED IDEOGRAPH + {0xECF1, 0x795A}, //19096 #CJK UNIFIED IDEOGRAPH + {0xECF2, 0x7962}, //19097 #CJK UNIFIED IDEOGRAPH + {0xECF3, 0x7957}, //19098 #CJK UNIFIED IDEOGRAPH + {0xECF4, 0x7960}, //19099 #CJK UNIFIED IDEOGRAPH + {0xECF5, 0x796F}, //19100 #CJK UNIFIED IDEOGRAPH + {0xECF6, 0x7967}, //19101 #CJK UNIFIED IDEOGRAPH + {0xECF7, 0x797A}, //19102 #CJK UNIFIED IDEOGRAPH + {0xECF8, 0x7985}, //19103 #CJK UNIFIED IDEOGRAPH + {0xECF9, 0x798A}, //19104 #CJK UNIFIED IDEOGRAPH + {0xECFA, 0x799A}, //19105 #CJK UNIFIED IDEOGRAPH + {0xECFB, 0x79A7}, //19106 #CJK UNIFIED IDEOGRAPH + {0xECFC, 0x79B3}, //19107 #CJK UNIFIED IDEOGRAPH + {0xECFD, 0x5FD1}, //19108 #CJK UNIFIED IDEOGRAPH + {0xECFE, 0x5FD0}, //19109 #CJK UNIFIED IDEOGRAPH + {0xED40, 0x979E}, //19110 #CJK UNIFIED IDEOGRAPH + {0xED41, 0x979F}, //19111 #CJK UNIFIED IDEOGRAPH + {0xED42, 0x97A1}, //19112 #CJK UNIFIED IDEOGRAPH + {0xED43, 0x97A2}, //19113 #CJK UNIFIED IDEOGRAPH + {0xED44, 0x97A4}, //19114 #CJK UNIFIED IDEOGRAPH + {0xED45, 0x97A5}, //19115 #CJK UNIFIED IDEOGRAPH + {0xED46, 0x97A6}, //19116 #CJK UNIFIED IDEOGRAPH + {0xED47, 0x97A7}, //19117 #CJK UNIFIED IDEOGRAPH + {0xED48, 0x97A8}, //19118 #CJK UNIFIED IDEOGRAPH + {0xED49, 0x97A9}, //19119 #CJK UNIFIED IDEOGRAPH + {0xED4A, 0x97AA}, //19120 #CJK UNIFIED IDEOGRAPH + {0xED4B, 0x97AC}, //19121 #CJK UNIFIED IDEOGRAPH + {0xED4C, 0x97AE}, //19122 #CJK UNIFIED IDEOGRAPH + {0xED4D, 0x97B0}, //19123 #CJK UNIFIED IDEOGRAPH + {0xED4E, 0x97B1}, //19124 #CJK UNIFIED IDEOGRAPH + {0xED4F, 0x97B3}, //19125 #CJK UNIFIED IDEOGRAPH + {0xED50, 0x97B5}, //19126 #CJK UNIFIED IDEOGRAPH + {0xED51, 0x97B6}, //19127 #CJK UNIFIED IDEOGRAPH + {0xED52, 0x97B7}, //19128 #CJK UNIFIED IDEOGRAPH + {0xED53, 0x97B8}, //19129 #CJK UNIFIED IDEOGRAPH + {0xED54, 0x97B9}, //19130 #CJK UNIFIED IDEOGRAPH + {0xED55, 0x97BA}, //19131 #CJK UNIFIED IDEOGRAPH + {0xED56, 0x97BB}, //19132 #CJK UNIFIED IDEOGRAPH + {0xED57, 0x97BC}, //19133 #CJK UNIFIED IDEOGRAPH + {0xED58, 0x97BD}, //19134 #CJK UNIFIED IDEOGRAPH + {0xED59, 0x97BE}, //19135 #CJK UNIFIED IDEOGRAPH + {0xED5A, 0x97BF}, //19136 #CJK UNIFIED IDEOGRAPH + {0xED5B, 0x97C0}, //19137 #CJK UNIFIED IDEOGRAPH + {0xED5C, 0x97C1}, //19138 #CJK UNIFIED IDEOGRAPH + {0xED5D, 0x97C2}, //19139 #CJK UNIFIED IDEOGRAPH + {0xED5E, 0x97C3}, //19140 #CJK UNIFIED IDEOGRAPH + {0xED5F, 0x97C4}, //19141 #CJK UNIFIED IDEOGRAPH + {0xED60, 0x97C5}, //19142 #CJK UNIFIED IDEOGRAPH + {0xED61, 0x97C6}, //19143 #CJK UNIFIED IDEOGRAPH + {0xED62, 0x97C7}, //19144 #CJK UNIFIED IDEOGRAPH + {0xED63, 0x97C8}, //19145 #CJK UNIFIED IDEOGRAPH + {0xED64, 0x97C9}, //19146 #CJK UNIFIED IDEOGRAPH + {0xED65, 0x97CA}, //19147 #CJK UNIFIED IDEOGRAPH + {0xED66, 0x97CB}, //19148 #CJK UNIFIED IDEOGRAPH + {0xED67, 0x97CC}, //19149 #CJK UNIFIED IDEOGRAPH + {0xED68, 0x97CD}, //19150 #CJK UNIFIED IDEOGRAPH + {0xED69, 0x97CE}, //19151 #CJK UNIFIED IDEOGRAPH + {0xED6A, 0x97CF}, //19152 #CJK UNIFIED IDEOGRAPH + {0xED6B, 0x97D0}, //19153 #CJK UNIFIED IDEOGRAPH + {0xED6C, 0x97D1}, //19154 #CJK UNIFIED IDEOGRAPH + {0xED6D, 0x97D2}, //19155 #CJK UNIFIED IDEOGRAPH + {0xED6E, 0x97D3}, //19156 #CJK UNIFIED IDEOGRAPH + {0xED6F, 0x97D4}, //19157 #CJK UNIFIED IDEOGRAPH + {0xED70, 0x97D5}, //19158 #CJK UNIFIED IDEOGRAPH + {0xED71, 0x97D6}, //19159 #CJK UNIFIED IDEOGRAPH + {0xED72, 0x97D7}, //19160 #CJK UNIFIED IDEOGRAPH + {0xED73, 0x97D8}, //19161 #CJK UNIFIED IDEOGRAPH + {0xED74, 0x97D9}, //19162 #CJK UNIFIED IDEOGRAPH + {0xED75, 0x97DA}, //19163 #CJK UNIFIED IDEOGRAPH + {0xED76, 0x97DB}, //19164 #CJK UNIFIED IDEOGRAPH + {0xED77, 0x97DC}, //19165 #CJK UNIFIED IDEOGRAPH + {0xED78, 0x97DD}, //19166 #CJK UNIFIED IDEOGRAPH + {0xED79, 0x97DE}, //19167 #CJK UNIFIED IDEOGRAPH + {0xED7A, 0x97DF}, //19168 #CJK UNIFIED IDEOGRAPH + {0xED7B, 0x97E0}, //19169 #CJK UNIFIED IDEOGRAPH + {0xED7C, 0x97E1}, //19170 #CJK UNIFIED IDEOGRAPH + {0xED7D, 0x97E2}, //19171 #CJK UNIFIED IDEOGRAPH + {0xED7E, 0x97E3}, //19172 #CJK UNIFIED IDEOGRAPH + {0xED80, 0x97E4}, //19173 #CJK UNIFIED IDEOGRAPH + {0xED81, 0x97E5}, //19174 #CJK UNIFIED IDEOGRAPH + {0xED82, 0x97E8}, //19175 #CJK UNIFIED IDEOGRAPH + {0xED83, 0x97EE}, //19176 #CJK UNIFIED IDEOGRAPH + {0xED84, 0x97EF}, //19177 #CJK UNIFIED IDEOGRAPH + {0xED85, 0x97F0}, //19178 #CJK UNIFIED IDEOGRAPH + {0xED86, 0x97F1}, //19179 #CJK UNIFIED IDEOGRAPH + {0xED87, 0x97F2}, //19180 #CJK UNIFIED IDEOGRAPH + {0xED88, 0x97F4}, //19181 #CJK UNIFIED IDEOGRAPH + {0xED89, 0x97F7}, //19182 #CJK UNIFIED IDEOGRAPH + {0xED8A, 0x97F8}, //19183 #CJK UNIFIED IDEOGRAPH + {0xED8B, 0x97F9}, //19184 #CJK UNIFIED IDEOGRAPH + {0xED8C, 0x97FA}, //19185 #CJK UNIFIED IDEOGRAPH + {0xED8D, 0x97FB}, //19186 #CJK UNIFIED IDEOGRAPH + {0xED8E, 0x97FC}, //19187 #CJK UNIFIED IDEOGRAPH + {0xED8F, 0x97FD}, //19188 #CJK UNIFIED IDEOGRAPH + {0xED90, 0x97FE}, //19189 #CJK UNIFIED IDEOGRAPH + {0xED91, 0x97FF}, //19190 #CJK UNIFIED IDEOGRAPH + {0xED92, 0x9800}, //19191 #CJK UNIFIED IDEOGRAPH + {0xED93, 0x9801}, //19192 #CJK UNIFIED IDEOGRAPH + {0xED94, 0x9802}, //19193 #CJK UNIFIED IDEOGRAPH + {0xED95, 0x9803}, //19194 #CJK UNIFIED IDEOGRAPH + {0xED96, 0x9804}, //19195 #CJK UNIFIED IDEOGRAPH + {0xED97, 0x9805}, //19196 #CJK UNIFIED IDEOGRAPH + {0xED98, 0x9806}, //19197 #CJK UNIFIED IDEOGRAPH + {0xED99, 0x9807}, //19198 #CJK UNIFIED IDEOGRAPH + {0xED9A, 0x9808}, //19199 #CJK UNIFIED IDEOGRAPH + {0xED9B, 0x9809}, //19200 #CJK UNIFIED IDEOGRAPH + {0xED9C, 0x980A}, //19201 #CJK UNIFIED IDEOGRAPH + {0xED9D, 0x980B}, //19202 #CJK UNIFIED IDEOGRAPH + {0xED9E, 0x980C}, //19203 #CJK UNIFIED IDEOGRAPH + {0xED9F, 0x980D}, //19204 #CJK UNIFIED IDEOGRAPH + {0xEDA0, 0x980E}, //19205 #CJK UNIFIED IDEOGRAPH + {0xEDA1, 0x603C}, //19206 #CJK UNIFIED IDEOGRAPH + {0xEDA2, 0x605D}, //19207 #CJK UNIFIED IDEOGRAPH + {0xEDA3, 0x605A}, //19208 #CJK UNIFIED IDEOGRAPH + {0xEDA4, 0x6067}, //19209 #CJK UNIFIED IDEOGRAPH + {0xEDA5, 0x6041}, //19210 #CJK UNIFIED IDEOGRAPH + {0xEDA6, 0x6059}, //19211 #CJK UNIFIED IDEOGRAPH + {0xEDA7, 0x6063}, //19212 #CJK UNIFIED IDEOGRAPH + {0xEDA8, 0x60AB}, //19213 #CJK UNIFIED IDEOGRAPH + {0xEDA9, 0x6106}, //19214 #CJK UNIFIED IDEOGRAPH + {0xEDAA, 0x610D}, //19215 #CJK UNIFIED IDEOGRAPH + {0xEDAB, 0x615D}, //19216 #CJK UNIFIED IDEOGRAPH + {0xEDAC, 0x61A9}, //19217 #CJK UNIFIED IDEOGRAPH + {0xEDAD, 0x619D}, //19218 #CJK UNIFIED IDEOGRAPH + {0xEDAE, 0x61CB}, //19219 #CJK UNIFIED IDEOGRAPH + {0xEDAF, 0x61D1}, //19220 #CJK UNIFIED IDEOGRAPH + {0xEDB0, 0x6206}, //19221 #CJK UNIFIED IDEOGRAPH + {0xEDB1, 0x8080}, //19222 #CJK UNIFIED IDEOGRAPH + {0xEDB2, 0x807F}, //19223 #CJK UNIFIED IDEOGRAPH + {0xEDB3, 0x6C93}, //19224 #CJK UNIFIED IDEOGRAPH + {0xEDB4, 0x6CF6}, //19225 #CJK UNIFIED IDEOGRAPH + {0xEDB5, 0x6DFC}, //19226 #CJK UNIFIED IDEOGRAPH + {0xEDB6, 0x77F6}, //19227 #CJK UNIFIED IDEOGRAPH + {0xEDB7, 0x77F8}, //19228 #CJK UNIFIED IDEOGRAPH + {0xEDB8, 0x7800}, //19229 #CJK UNIFIED IDEOGRAPH + {0xEDB9, 0x7809}, //19230 #CJK UNIFIED IDEOGRAPH + {0xEDBA, 0x7817}, //19231 #CJK UNIFIED IDEOGRAPH + {0xEDBB, 0x7818}, //19232 #CJK UNIFIED IDEOGRAPH + {0xEDBC, 0x7811}, //19233 #CJK UNIFIED IDEOGRAPH + {0xEDBD, 0x65AB}, //19234 #CJK UNIFIED IDEOGRAPH + {0xEDBE, 0x782D}, //19235 #CJK UNIFIED IDEOGRAPH + {0xEDBF, 0x781C}, //19236 #CJK UNIFIED IDEOGRAPH + {0xEDC0, 0x781D}, //19237 #CJK UNIFIED IDEOGRAPH + {0xEDC1, 0x7839}, //19238 #CJK UNIFIED IDEOGRAPH + {0xEDC2, 0x783A}, //19239 #CJK UNIFIED IDEOGRAPH + {0xEDC3, 0x783B}, //19240 #CJK UNIFIED IDEOGRAPH + {0xEDC4, 0x781F}, //19241 #CJK UNIFIED IDEOGRAPH + {0xEDC5, 0x783C}, //19242 #CJK UNIFIED IDEOGRAPH + {0xEDC6, 0x7825}, //19243 #CJK UNIFIED IDEOGRAPH + {0xEDC7, 0x782C}, //19244 #CJK UNIFIED IDEOGRAPH + {0xEDC8, 0x7823}, //19245 #CJK UNIFIED IDEOGRAPH + {0xEDC9, 0x7829}, //19246 #CJK UNIFIED IDEOGRAPH + {0xEDCA, 0x784E}, //19247 #CJK UNIFIED IDEOGRAPH + {0xEDCB, 0x786D}, //19248 #CJK UNIFIED IDEOGRAPH + {0xEDCC, 0x7856}, //19249 #CJK UNIFIED IDEOGRAPH + {0xEDCD, 0x7857}, //19250 #CJK UNIFIED IDEOGRAPH + {0xEDCE, 0x7826}, //19251 #CJK UNIFIED IDEOGRAPH + {0xEDCF, 0x7850}, //19252 #CJK UNIFIED IDEOGRAPH + {0xEDD0, 0x7847}, //19253 #CJK UNIFIED IDEOGRAPH + {0xEDD1, 0x784C}, //19254 #CJK UNIFIED IDEOGRAPH + {0xEDD2, 0x786A}, //19255 #CJK UNIFIED IDEOGRAPH + {0xEDD3, 0x789B}, //19256 #CJK UNIFIED IDEOGRAPH + {0xEDD4, 0x7893}, //19257 #CJK UNIFIED IDEOGRAPH + {0xEDD5, 0x789A}, //19258 #CJK UNIFIED IDEOGRAPH + {0xEDD6, 0x7887}, //19259 #CJK UNIFIED IDEOGRAPH + {0xEDD7, 0x789C}, //19260 #CJK UNIFIED IDEOGRAPH + {0xEDD8, 0x78A1}, //19261 #CJK UNIFIED IDEOGRAPH + {0xEDD9, 0x78A3}, //19262 #CJK UNIFIED IDEOGRAPH + {0xEDDA, 0x78B2}, //19263 #CJK UNIFIED IDEOGRAPH + {0xEDDB, 0x78B9}, //19264 #CJK UNIFIED IDEOGRAPH + {0xEDDC, 0x78A5}, //19265 #CJK UNIFIED IDEOGRAPH + {0xEDDD, 0x78D4}, //19266 #CJK UNIFIED IDEOGRAPH + {0xEDDE, 0x78D9}, //19267 #CJK UNIFIED IDEOGRAPH + {0xEDDF, 0x78C9}, //19268 #CJK UNIFIED IDEOGRAPH + {0xEDE0, 0x78EC}, //19269 #CJK UNIFIED IDEOGRAPH + {0xEDE1, 0x78F2}, //19270 #CJK UNIFIED IDEOGRAPH + {0xEDE2, 0x7905}, //19271 #CJK UNIFIED IDEOGRAPH + {0xEDE3, 0x78F4}, //19272 #CJK UNIFIED IDEOGRAPH + {0xEDE4, 0x7913}, //19273 #CJK UNIFIED IDEOGRAPH + {0xEDE5, 0x7924}, //19274 #CJK UNIFIED IDEOGRAPH + {0xEDE6, 0x791E}, //19275 #CJK UNIFIED IDEOGRAPH + {0xEDE7, 0x7934}, //19276 #CJK UNIFIED IDEOGRAPH + {0xEDE8, 0x9F9B}, //19277 #CJK UNIFIED IDEOGRAPH + {0xEDE9, 0x9EF9}, //19278 #CJK UNIFIED IDEOGRAPH + {0xEDEA, 0x9EFB}, //19279 #CJK UNIFIED IDEOGRAPH + {0xEDEB, 0x9EFC}, //19280 #CJK UNIFIED IDEOGRAPH + {0xEDEC, 0x76F1}, //19281 #CJK UNIFIED IDEOGRAPH + {0xEDED, 0x7704}, //19282 #CJK UNIFIED IDEOGRAPH + {0xEDEE, 0x770D}, //19283 #CJK UNIFIED IDEOGRAPH + {0xEDEF, 0x76F9}, //19284 #CJK UNIFIED IDEOGRAPH + {0xEDF0, 0x7707}, //19285 #CJK UNIFIED IDEOGRAPH + {0xEDF1, 0x7708}, //19286 #CJK UNIFIED IDEOGRAPH + {0xEDF2, 0x771A}, //19287 #CJK UNIFIED IDEOGRAPH + {0xEDF3, 0x7722}, //19288 #CJK UNIFIED IDEOGRAPH + {0xEDF4, 0x7719}, //19289 #CJK UNIFIED IDEOGRAPH + {0xEDF5, 0x772D}, //19290 #CJK UNIFIED IDEOGRAPH + {0xEDF6, 0x7726}, //19291 #CJK UNIFIED IDEOGRAPH + {0xEDF7, 0x7735}, //19292 #CJK UNIFIED IDEOGRAPH + {0xEDF8, 0x7738}, //19293 #CJK UNIFIED IDEOGRAPH + {0xEDF9, 0x7750}, //19294 #CJK UNIFIED IDEOGRAPH + {0xEDFA, 0x7751}, //19295 #CJK UNIFIED IDEOGRAPH + {0xEDFB, 0x7747}, //19296 #CJK UNIFIED IDEOGRAPH + {0xEDFC, 0x7743}, //19297 #CJK UNIFIED IDEOGRAPH + {0xEDFD, 0x775A}, //19298 #CJK UNIFIED IDEOGRAPH + {0xEDFE, 0x7768}, //19299 #CJK UNIFIED IDEOGRAPH + {0xEE40, 0x980F}, //19300 #CJK UNIFIED IDEOGRAPH + {0xEE41, 0x9810}, //19301 #CJK UNIFIED IDEOGRAPH + {0xEE42, 0x9811}, //19302 #CJK UNIFIED IDEOGRAPH + {0xEE43, 0x9812}, //19303 #CJK UNIFIED IDEOGRAPH + {0xEE44, 0x9813}, //19304 #CJK UNIFIED IDEOGRAPH + {0xEE45, 0x9814}, //19305 #CJK UNIFIED IDEOGRAPH + {0xEE46, 0x9815}, //19306 #CJK UNIFIED IDEOGRAPH + {0xEE47, 0x9816}, //19307 #CJK UNIFIED IDEOGRAPH + {0xEE48, 0x9817}, //19308 #CJK UNIFIED IDEOGRAPH + {0xEE49, 0x9818}, //19309 #CJK UNIFIED IDEOGRAPH + {0xEE4A, 0x9819}, //19310 #CJK UNIFIED IDEOGRAPH + {0xEE4B, 0x981A}, //19311 #CJK UNIFIED IDEOGRAPH + {0xEE4C, 0x981B}, //19312 #CJK UNIFIED IDEOGRAPH + {0xEE4D, 0x981C}, //19313 #CJK UNIFIED IDEOGRAPH + {0xEE4E, 0x981D}, //19314 #CJK UNIFIED IDEOGRAPH + {0xEE4F, 0x981E}, //19315 #CJK UNIFIED IDEOGRAPH + {0xEE50, 0x981F}, //19316 #CJK UNIFIED IDEOGRAPH + {0xEE51, 0x9820}, //19317 #CJK UNIFIED IDEOGRAPH + {0xEE52, 0x9821}, //19318 #CJK UNIFIED IDEOGRAPH + {0xEE53, 0x9822}, //19319 #CJK UNIFIED IDEOGRAPH + {0xEE54, 0x9823}, //19320 #CJK UNIFIED IDEOGRAPH + {0xEE55, 0x9824}, //19321 #CJK UNIFIED IDEOGRAPH + {0xEE56, 0x9825}, //19322 #CJK UNIFIED IDEOGRAPH + {0xEE57, 0x9826}, //19323 #CJK UNIFIED IDEOGRAPH + {0xEE58, 0x9827}, //19324 #CJK UNIFIED IDEOGRAPH + {0xEE59, 0x9828}, //19325 #CJK UNIFIED IDEOGRAPH + {0xEE5A, 0x9829}, //19326 #CJK UNIFIED IDEOGRAPH + {0xEE5B, 0x982A}, //19327 #CJK UNIFIED IDEOGRAPH + {0xEE5C, 0x982B}, //19328 #CJK UNIFIED IDEOGRAPH + {0xEE5D, 0x982C}, //19329 #CJK UNIFIED IDEOGRAPH + {0xEE5E, 0x982D}, //19330 #CJK UNIFIED IDEOGRAPH + {0xEE5F, 0x982E}, //19331 #CJK UNIFIED IDEOGRAPH + {0xEE60, 0x982F}, //19332 #CJK UNIFIED IDEOGRAPH + {0xEE61, 0x9830}, //19333 #CJK UNIFIED IDEOGRAPH + {0xEE62, 0x9831}, //19334 #CJK UNIFIED IDEOGRAPH + {0xEE63, 0x9832}, //19335 #CJK UNIFIED IDEOGRAPH + {0xEE64, 0x9833}, //19336 #CJK UNIFIED IDEOGRAPH + {0xEE65, 0x9834}, //19337 #CJK UNIFIED IDEOGRAPH + {0xEE66, 0x9835}, //19338 #CJK UNIFIED IDEOGRAPH + {0xEE67, 0x9836}, //19339 #CJK UNIFIED IDEOGRAPH + {0xEE68, 0x9837}, //19340 #CJK UNIFIED IDEOGRAPH + {0xEE69, 0x9838}, //19341 #CJK UNIFIED IDEOGRAPH + {0xEE6A, 0x9839}, //19342 #CJK UNIFIED IDEOGRAPH + {0xEE6B, 0x983A}, //19343 #CJK UNIFIED IDEOGRAPH + {0xEE6C, 0x983B}, //19344 #CJK UNIFIED IDEOGRAPH + {0xEE6D, 0x983C}, //19345 #CJK UNIFIED IDEOGRAPH + {0xEE6E, 0x983D}, //19346 #CJK UNIFIED IDEOGRAPH + {0xEE6F, 0x983E}, //19347 #CJK UNIFIED IDEOGRAPH + {0xEE70, 0x983F}, //19348 #CJK UNIFIED IDEOGRAPH + {0xEE71, 0x9840}, //19349 #CJK UNIFIED IDEOGRAPH + {0xEE72, 0x9841}, //19350 #CJK UNIFIED IDEOGRAPH + {0xEE73, 0x9842}, //19351 #CJK UNIFIED IDEOGRAPH + {0xEE74, 0x9843}, //19352 #CJK UNIFIED IDEOGRAPH + {0xEE75, 0x9844}, //19353 #CJK UNIFIED IDEOGRAPH + {0xEE76, 0x9845}, //19354 #CJK UNIFIED IDEOGRAPH + {0xEE77, 0x9846}, //19355 #CJK UNIFIED IDEOGRAPH + {0xEE78, 0x9847}, //19356 #CJK UNIFIED IDEOGRAPH + {0xEE79, 0x9848}, //19357 #CJK UNIFIED IDEOGRAPH + {0xEE7A, 0x9849}, //19358 #CJK UNIFIED IDEOGRAPH + {0xEE7B, 0x984A}, //19359 #CJK UNIFIED IDEOGRAPH + {0xEE7C, 0x984B}, //19360 #CJK UNIFIED IDEOGRAPH + {0xEE7D, 0x984C}, //19361 #CJK UNIFIED IDEOGRAPH + {0xEE7E, 0x984D}, //19362 #CJK UNIFIED IDEOGRAPH + {0xEE80, 0x984E}, //19363 #CJK UNIFIED IDEOGRAPH + {0xEE81, 0x984F}, //19364 #CJK UNIFIED IDEOGRAPH + {0xEE82, 0x9850}, //19365 #CJK UNIFIED IDEOGRAPH + {0xEE83, 0x9851}, //19366 #CJK UNIFIED IDEOGRAPH + {0xEE84, 0x9852}, //19367 #CJK UNIFIED IDEOGRAPH + {0xEE85, 0x9853}, //19368 #CJK UNIFIED IDEOGRAPH + {0xEE86, 0x9854}, //19369 #CJK UNIFIED IDEOGRAPH + {0xEE87, 0x9855}, //19370 #CJK UNIFIED IDEOGRAPH + {0xEE88, 0x9856}, //19371 #CJK UNIFIED IDEOGRAPH + {0xEE89, 0x9857}, //19372 #CJK UNIFIED IDEOGRAPH + {0xEE8A, 0x9858}, //19373 #CJK UNIFIED IDEOGRAPH + {0xEE8B, 0x9859}, //19374 #CJK UNIFIED IDEOGRAPH + {0xEE8C, 0x985A}, //19375 #CJK UNIFIED IDEOGRAPH + {0xEE8D, 0x985B}, //19376 #CJK UNIFIED IDEOGRAPH + {0xEE8E, 0x985C}, //19377 #CJK UNIFIED IDEOGRAPH + {0xEE8F, 0x985D}, //19378 #CJK UNIFIED IDEOGRAPH + {0xEE90, 0x985E}, //19379 #CJK UNIFIED IDEOGRAPH + {0xEE91, 0x985F}, //19380 #CJK UNIFIED IDEOGRAPH + {0xEE92, 0x9860}, //19381 #CJK UNIFIED IDEOGRAPH + {0xEE93, 0x9861}, //19382 #CJK UNIFIED IDEOGRAPH + {0xEE94, 0x9862}, //19383 #CJK UNIFIED IDEOGRAPH + {0xEE95, 0x9863}, //19384 #CJK UNIFIED IDEOGRAPH + {0xEE96, 0x9864}, //19385 #CJK UNIFIED IDEOGRAPH + {0xEE97, 0x9865}, //19386 #CJK UNIFIED IDEOGRAPH + {0xEE98, 0x9866}, //19387 #CJK UNIFIED IDEOGRAPH + {0xEE99, 0x9867}, //19388 #CJK UNIFIED IDEOGRAPH + {0xEE9A, 0x9868}, //19389 #CJK UNIFIED IDEOGRAPH + {0xEE9B, 0x9869}, //19390 #CJK UNIFIED IDEOGRAPH + {0xEE9C, 0x986A}, //19391 #CJK UNIFIED IDEOGRAPH + {0xEE9D, 0x986B}, //19392 #CJK UNIFIED IDEOGRAPH + {0xEE9E, 0x986C}, //19393 #CJK UNIFIED IDEOGRAPH + {0xEE9F, 0x986D}, //19394 #CJK UNIFIED IDEOGRAPH + {0xEEA0, 0x986E}, //19395 #CJK UNIFIED IDEOGRAPH + {0xEEA1, 0x7762}, //19396 #CJK UNIFIED IDEOGRAPH + {0xEEA2, 0x7765}, //19397 #CJK UNIFIED IDEOGRAPH + {0xEEA3, 0x777F}, //19398 #CJK UNIFIED IDEOGRAPH + {0xEEA4, 0x778D}, //19399 #CJK UNIFIED IDEOGRAPH + {0xEEA5, 0x777D}, //19400 #CJK UNIFIED IDEOGRAPH + {0xEEA6, 0x7780}, //19401 #CJK UNIFIED IDEOGRAPH + {0xEEA7, 0x778C}, //19402 #CJK UNIFIED IDEOGRAPH + {0xEEA8, 0x7791}, //19403 #CJK UNIFIED IDEOGRAPH + {0xEEA9, 0x779F}, //19404 #CJK UNIFIED IDEOGRAPH + {0xEEAA, 0x77A0}, //19405 #CJK UNIFIED IDEOGRAPH + {0xEEAB, 0x77B0}, //19406 #CJK UNIFIED IDEOGRAPH + {0xEEAC, 0x77B5}, //19407 #CJK UNIFIED IDEOGRAPH + {0xEEAD, 0x77BD}, //19408 #CJK UNIFIED IDEOGRAPH + {0xEEAE, 0x753A}, //19409 #CJK UNIFIED IDEOGRAPH + {0xEEAF, 0x7540}, //19410 #CJK UNIFIED IDEOGRAPH + {0xEEB0, 0x754E}, //19411 #CJK UNIFIED IDEOGRAPH + {0xEEB1, 0x754B}, //19412 #CJK UNIFIED IDEOGRAPH + {0xEEB2, 0x7548}, //19413 #CJK UNIFIED IDEOGRAPH + {0xEEB3, 0x755B}, //19414 #CJK UNIFIED IDEOGRAPH + {0xEEB4, 0x7572}, //19415 #CJK UNIFIED IDEOGRAPH + {0xEEB5, 0x7579}, //19416 #CJK UNIFIED IDEOGRAPH + {0xEEB6, 0x7583}, //19417 #CJK UNIFIED IDEOGRAPH + {0xEEB7, 0x7F58}, //19418 #CJK UNIFIED IDEOGRAPH + {0xEEB8, 0x7F61}, //19419 #CJK UNIFIED IDEOGRAPH + {0xEEB9, 0x7F5F}, //19420 #CJK UNIFIED IDEOGRAPH + {0xEEBA, 0x8A48}, //19421 #CJK UNIFIED IDEOGRAPH + {0xEEBB, 0x7F68}, //19422 #CJK UNIFIED IDEOGRAPH + {0xEEBC, 0x7F74}, //19423 #CJK UNIFIED IDEOGRAPH + {0xEEBD, 0x7F71}, //19424 #CJK UNIFIED IDEOGRAPH + {0xEEBE, 0x7F79}, //19425 #CJK UNIFIED IDEOGRAPH + {0xEEBF, 0x7F81}, //19426 #CJK UNIFIED IDEOGRAPH + {0xEEC0, 0x7F7E}, //19427 #CJK UNIFIED IDEOGRAPH + {0xEEC1, 0x76CD}, //19428 #CJK UNIFIED IDEOGRAPH + {0xEEC2, 0x76E5}, //19429 #CJK UNIFIED IDEOGRAPH + {0xEEC3, 0x8832}, //19430 #CJK UNIFIED IDEOGRAPH + {0xEEC4, 0x9485}, //19431 #CJK UNIFIED IDEOGRAPH + {0xEEC5, 0x9486}, //19432 #CJK UNIFIED IDEOGRAPH + {0xEEC6, 0x9487}, //19433 #CJK UNIFIED IDEOGRAPH + {0xEEC7, 0x948B}, //19434 #CJK UNIFIED IDEOGRAPH + {0xEEC8, 0x948A}, //19435 #CJK UNIFIED IDEOGRAPH + {0xEEC9, 0x948C}, //19436 #CJK UNIFIED IDEOGRAPH + {0xEECA, 0x948D}, //19437 #CJK UNIFIED IDEOGRAPH + {0xEECB, 0x948F}, //19438 #CJK UNIFIED IDEOGRAPH + {0xEECC, 0x9490}, //19439 #CJK UNIFIED IDEOGRAPH + {0xEECD, 0x9494}, //19440 #CJK UNIFIED IDEOGRAPH + {0xEECE, 0x9497}, //19441 #CJK UNIFIED IDEOGRAPH + {0xEECF, 0x9495}, //19442 #CJK UNIFIED IDEOGRAPH + {0xEED0, 0x949A}, //19443 #CJK UNIFIED IDEOGRAPH + {0xEED1, 0x949B}, //19444 #CJK UNIFIED IDEOGRAPH + {0xEED2, 0x949C}, //19445 #CJK UNIFIED IDEOGRAPH + {0xEED3, 0x94A3}, //19446 #CJK UNIFIED IDEOGRAPH + {0xEED4, 0x94A4}, //19447 #CJK UNIFIED IDEOGRAPH + {0xEED5, 0x94AB}, //19448 #CJK UNIFIED IDEOGRAPH + {0xEED6, 0x94AA}, //19449 #CJK UNIFIED IDEOGRAPH + {0xEED7, 0x94AD}, //19450 #CJK UNIFIED IDEOGRAPH + {0xEED8, 0x94AC}, //19451 #CJK UNIFIED IDEOGRAPH + {0xEED9, 0x94AF}, //19452 #CJK UNIFIED IDEOGRAPH + {0xEEDA, 0x94B0}, //19453 #CJK UNIFIED IDEOGRAPH + {0xEEDB, 0x94B2}, //19454 #CJK UNIFIED IDEOGRAPH + {0xEEDC, 0x94B4}, //19455 #CJK UNIFIED IDEOGRAPH + {0xEEDD, 0x94B6}, //19456 #CJK UNIFIED IDEOGRAPH + {0xEEDE, 0x94B7}, //19457 #CJK UNIFIED IDEOGRAPH + {0xEEDF, 0x94B8}, //19458 #CJK UNIFIED IDEOGRAPH + {0xEEE0, 0x94B9}, //19459 #CJK UNIFIED IDEOGRAPH + {0xEEE1, 0x94BA}, //19460 #CJK UNIFIED IDEOGRAPH + {0xEEE2, 0x94BC}, //19461 #CJK UNIFIED IDEOGRAPH + {0xEEE3, 0x94BD}, //19462 #CJK UNIFIED IDEOGRAPH + {0xEEE4, 0x94BF}, //19463 #CJK UNIFIED IDEOGRAPH + {0xEEE5, 0x94C4}, //19464 #CJK UNIFIED IDEOGRAPH + {0xEEE6, 0x94C8}, //19465 #CJK UNIFIED IDEOGRAPH + {0xEEE7, 0x94C9}, //19466 #CJK UNIFIED IDEOGRAPH + {0xEEE8, 0x94CA}, //19467 #CJK UNIFIED IDEOGRAPH + {0xEEE9, 0x94CB}, //19468 #CJK UNIFIED IDEOGRAPH + {0xEEEA, 0x94CC}, //19469 #CJK UNIFIED IDEOGRAPH + {0xEEEB, 0x94CD}, //19470 #CJK UNIFIED IDEOGRAPH + {0xEEEC, 0x94CE}, //19471 #CJK UNIFIED IDEOGRAPH + {0xEEED, 0x94D0}, //19472 #CJK UNIFIED IDEOGRAPH + {0xEEEE, 0x94D1}, //19473 #CJK UNIFIED IDEOGRAPH + {0xEEEF, 0x94D2}, //19474 #CJK UNIFIED IDEOGRAPH + {0xEEF0, 0x94D5}, //19475 #CJK UNIFIED IDEOGRAPH + {0xEEF1, 0x94D6}, //19476 #CJK UNIFIED IDEOGRAPH + {0xEEF2, 0x94D7}, //19477 #CJK UNIFIED IDEOGRAPH + {0xEEF3, 0x94D9}, //19478 #CJK UNIFIED IDEOGRAPH + {0xEEF4, 0x94D8}, //19479 #CJK UNIFIED IDEOGRAPH + {0xEEF5, 0x94DB}, //19480 #CJK UNIFIED IDEOGRAPH + {0xEEF6, 0x94DE}, //19481 #CJK UNIFIED IDEOGRAPH + {0xEEF7, 0x94DF}, //19482 #CJK UNIFIED IDEOGRAPH + {0xEEF8, 0x94E0}, //19483 #CJK UNIFIED IDEOGRAPH + {0xEEF9, 0x94E2}, //19484 #CJK UNIFIED IDEOGRAPH + {0xEEFA, 0x94E4}, //19485 #CJK UNIFIED IDEOGRAPH + {0xEEFB, 0x94E5}, //19486 #CJK UNIFIED IDEOGRAPH + {0xEEFC, 0x94E7}, //19487 #CJK UNIFIED IDEOGRAPH + {0xEEFD, 0x94E8}, //19488 #CJK UNIFIED IDEOGRAPH + {0xEEFE, 0x94EA}, //19489 #CJK UNIFIED IDEOGRAPH + {0xEF40, 0x986F}, //19490 #CJK UNIFIED IDEOGRAPH + {0xEF41, 0x9870}, //19491 #CJK UNIFIED IDEOGRAPH + {0xEF42, 0x9871}, //19492 #CJK UNIFIED IDEOGRAPH + {0xEF43, 0x9872}, //19493 #CJK UNIFIED IDEOGRAPH + {0xEF44, 0x9873}, //19494 #CJK UNIFIED IDEOGRAPH + {0xEF45, 0x9874}, //19495 #CJK UNIFIED IDEOGRAPH + {0xEF46, 0x988B}, //19496 #CJK UNIFIED IDEOGRAPH + {0xEF47, 0x988E}, //19497 #CJK UNIFIED IDEOGRAPH + {0xEF48, 0x9892}, //19498 #CJK UNIFIED IDEOGRAPH + {0xEF49, 0x9895}, //19499 #CJK UNIFIED IDEOGRAPH + {0xEF4A, 0x9899}, //19500 #CJK UNIFIED IDEOGRAPH + {0xEF4B, 0x98A3}, //19501 #CJK UNIFIED IDEOGRAPH + {0xEF4C, 0x98A8}, //19502 #CJK UNIFIED IDEOGRAPH + {0xEF4D, 0x98A9}, //19503 #CJK UNIFIED IDEOGRAPH + {0xEF4E, 0x98AA}, //19504 #CJK UNIFIED IDEOGRAPH + {0xEF4F, 0x98AB}, //19505 #CJK UNIFIED IDEOGRAPH + {0xEF50, 0x98AC}, //19506 #CJK UNIFIED IDEOGRAPH + {0xEF51, 0x98AD}, //19507 #CJK UNIFIED IDEOGRAPH + {0xEF52, 0x98AE}, //19508 #CJK UNIFIED IDEOGRAPH + {0xEF53, 0x98AF}, //19509 #CJK UNIFIED IDEOGRAPH + {0xEF54, 0x98B0}, //19510 #CJK UNIFIED IDEOGRAPH + {0xEF55, 0x98B1}, //19511 #CJK UNIFIED IDEOGRAPH + {0xEF56, 0x98B2}, //19512 #CJK UNIFIED IDEOGRAPH + {0xEF57, 0x98B3}, //19513 #CJK UNIFIED IDEOGRAPH + {0xEF58, 0x98B4}, //19514 #CJK UNIFIED IDEOGRAPH + {0xEF59, 0x98B5}, //19515 #CJK UNIFIED IDEOGRAPH + {0xEF5A, 0x98B6}, //19516 #CJK UNIFIED IDEOGRAPH + {0xEF5B, 0x98B7}, //19517 #CJK UNIFIED IDEOGRAPH + {0xEF5C, 0x98B8}, //19518 #CJK UNIFIED IDEOGRAPH + {0xEF5D, 0x98B9}, //19519 #CJK UNIFIED IDEOGRAPH + {0xEF5E, 0x98BA}, //19520 #CJK UNIFIED IDEOGRAPH + {0xEF5F, 0x98BB}, //19521 #CJK UNIFIED IDEOGRAPH + {0xEF60, 0x98BC}, //19522 #CJK UNIFIED IDEOGRAPH + {0xEF61, 0x98BD}, //19523 #CJK UNIFIED IDEOGRAPH + {0xEF62, 0x98BE}, //19524 #CJK UNIFIED IDEOGRAPH + {0xEF63, 0x98BF}, //19525 #CJK UNIFIED IDEOGRAPH + {0xEF64, 0x98C0}, //19526 #CJK UNIFIED IDEOGRAPH + {0xEF65, 0x98C1}, //19527 #CJK UNIFIED IDEOGRAPH + {0xEF66, 0x98C2}, //19528 #CJK UNIFIED IDEOGRAPH + {0xEF67, 0x98C3}, //19529 #CJK UNIFIED IDEOGRAPH + {0xEF68, 0x98C4}, //19530 #CJK UNIFIED IDEOGRAPH + {0xEF69, 0x98C5}, //19531 #CJK UNIFIED IDEOGRAPH + {0xEF6A, 0x98C6}, //19532 #CJK UNIFIED IDEOGRAPH + {0xEF6B, 0x98C7}, //19533 #CJK UNIFIED IDEOGRAPH + {0xEF6C, 0x98C8}, //19534 #CJK UNIFIED IDEOGRAPH + {0xEF6D, 0x98C9}, //19535 #CJK UNIFIED IDEOGRAPH + {0xEF6E, 0x98CA}, //19536 #CJK UNIFIED IDEOGRAPH + {0xEF6F, 0x98CB}, //19537 #CJK UNIFIED IDEOGRAPH + {0xEF70, 0x98CC}, //19538 #CJK UNIFIED IDEOGRAPH + {0xEF71, 0x98CD}, //19539 #CJK UNIFIED IDEOGRAPH + {0xEF72, 0x98CF}, //19540 #CJK UNIFIED IDEOGRAPH + {0xEF73, 0x98D0}, //19541 #CJK UNIFIED IDEOGRAPH + {0xEF74, 0x98D4}, //19542 #CJK UNIFIED IDEOGRAPH + {0xEF75, 0x98D6}, //19543 #CJK UNIFIED IDEOGRAPH + {0xEF76, 0x98D7}, //19544 #CJK UNIFIED IDEOGRAPH + {0xEF77, 0x98DB}, //19545 #CJK UNIFIED IDEOGRAPH + {0xEF78, 0x98DC}, //19546 #CJK UNIFIED IDEOGRAPH + {0xEF79, 0x98DD}, //19547 #CJK UNIFIED IDEOGRAPH + {0xEF7A, 0x98E0}, //19548 #CJK UNIFIED IDEOGRAPH + {0xEF7B, 0x98E1}, //19549 #CJK UNIFIED IDEOGRAPH + {0xEF7C, 0x98E2}, //19550 #CJK UNIFIED IDEOGRAPH + {0xEF7D, 0x98E3}, //19551 #CJK UNIFIED IDEOGRAPH + {0xEF7E, 0x98E4}, //19552 #CJK UNIFIED IDEOGRAPH + {0xEF80, 0x98E5}, //19553 #CJK UNIFIED IDEOGRAPH + {0xEF81, 0x98E6}, //19554 #CJK UNIFIED IDEOGRAPH + {0xEF82, 0x98E9}, //19555 #CJK UNIFIED IDEOGRAPH + {0xEF83, 0x98EA}, //19556 #CJK UNIFIED IDEOGRAPH + {0xEF84, 0x98EB}, //19557 #CJK UNIFIED IDEOGRAPH + {0xEF85, 0x98EC}, //19558 #CJK UNIFIED IDEOGRAPH + {0xEF86, 0x98ED}, //19559 #CJK UNIFIED IDEOGRAPH + {0xEF87, 0x98EE}, //19560 #CJK UNIFIED IDEOGRAPH + {0xEF88, 0x98EF}, //19561 #CJK UNIFIED IDEOGRAPH + {0xEF89, 0x98F0}, //19562 #CJK UNIFIED IDEOGRAPH + {0xEF8A, 0x98F1}, //19563 #CJK UNIFIED IDEOGRAPH + {0xEF8B, 0x98F2}, //19564 #CJK UNIFIED IDEOGRAPH + {0xEF8C, 0x98F3}, //19565 #CJK UNIFIED IDEOGRAPH + {0xEF8D, 0x98F4}, //19566 #CJK UNIFIED IDEOGRAPH + {0xEF8E, 0x98F5}, //19567 #CJK UNIFIED IDEOGRAPH + {0xEF8F, 0x98F6}, //19568 #CJK UNIFIED IDEOGRAPH + {0xEF90, 0x98F7}, //19569 #CJK UNIFIED IDEOGRAPH + {0xEF91, 0x98F8}, //19570 #CJK UNIFIED IDEOGRAPH + {0xEF92, 0x98F9}, //19571 #CJK UNIFIED IDEOGRAPH + {0xEF93, 0x98FA}, //19572 #CJK UNIFIED IDEOGRAPH + {0xEF94, 0x98FB}, //19573 #CJK UNIFIED IDEOGRAPH + {0xEF95, 0x98FC}, //19574 #CJK UNIFIED IDEOGRAPH + {0xEF96, 0x98FD}, //19575 #CJK UNIFIED IDEOGRAPH + {0xEF97, 0x98FE}, //19576 #CJK UNIFIED IDEOGRAPH + {0xEF98, 0x98FF}, //19577 #CJK UNIFIED IDEOGRAPH + {0xEF99, 0x9900}, //19578 #CJK UNIFIED IDEOGRAPH + {0xEF9A, 0x9901}, //19579 #CJK UNIFIED IDEOGRAPH + {0xEF9B, 0x9902}, //19580 #CJK UNIFIED IDEOGRAPH + {0xEF9C, 0x9903}, //19581 #CJK UNIFIED IDEOGRAPH + {0xEF9D, 0x9904}, //19582 #CJK UNIFIED IDEOGRAPH + {0xEF9E, 0x9905}, //19583 #CJK UNIFIED IDEOGRAPH + {0xEF9F, 0x9906}, //19584 #CJK UNIFIED IDEOGRAPH + {0xEFA0, 0x9907}, //19585 #CJK UNIFIED IDEOGRAPH + {0xEFA1, 0x94E9}, //19586 #CJK UNIFIED IDEOGRAPH + {0xEFA2, 0x94EB}, //19587 #CJK UNIFIED IDEOGRAPH + {0xEFA3, 0x94EE}, //19588 #CJK UNIFIED IDEOGRAPH + {0xEFA4, 0x94EF}, //19589 #CJK UNIFIED IDEOGRAPH + {0xEFA5, 0x94F3}, //19590 #CJK UNIFIED IDEOGRAPH + {0xEFA6, 0x94F4}, //19591 #CJK UNIFIED IDEOGRAPH + {0xEFA7, 0x94F5}, //19592 #CJK UNIFIED IDEOGRAPH + {0xEFA8, 0x94F7}, //19593 #CJK UNIFIED IDEOGRAPH + {0xEFA9, 0x94F9}, //19594 #CJK UNIFIED IDEOGRAPH + {0xEFAA, 0x94FC}, //19595 #CJK UNIFIED IDEOGRAPH + {0xEFAB, 0x94FD}, //19596 #CJK UNIFIED IDEOGRAPH + {0xEFAC, 0x94FF}, //19597 #CJK UNIFIED IDEOGRAPH + {0xEFAD, 0x9503}, //19598 #CJK UNIFIED IDEOGRAPH + {0xEFAE, 0x9502}, //19599 #CJK UNIFIED IDEOGRAPH + {0xEFAF, 0x9506}, //19600 #CJK UNIFIED IDEOGRAPH + {0xEFB0, 0x9507}, //19601 #CJK UNIFIED IDEOGRAPH + {0xEFB1, 0x9509}, //19602 #CJK UNIFIED IDEOGRAPH + {0xEFB2, 0x950A}, //19603 #CJK UNIFIED IDEOGRAPH + {0xEFB3, 0x950D}, //19604 #CJK UNIFIED IDEOGRAPH + {0xEFB4, 0x950E}, //19605 #CJK UNIFIED IDEOGRAPH + {0xEFB5, 0x950F}, //19606 #CJK UNIFIED IDEOGRAPH + {0xEFB6, 0x9512}, //19607 #CJK UNIFIED IDEOGRAPH + {0xEFB7, 0x9513}, //19608 #CJK UNIFIED IDEOGRAPH + {0xEFB8, 0x9514}, //19609 #CJK UNIFIED IDEOGRAPH + {0xEFB9, 0x9515}, //19610 #CJK UNIFIED IDEOGRAPH + {0xEFBA, 0x9516}, //19611 #CJK UNIFIED IDEOGRAPH + {0xEFBB, 0x9518}, //19612 #CJK UNIFIED IDEOGRAPH + {0xEFBC, 0x951B}, //19613 #CJK UNIFIED IDEOGRAPH + {0xEFBD, 0x951D}, //19614 #CJK UNIFIED IDEOGRAPH + {0xEFBE, 0x951E}, //19615 #CJK UNIFIED IDEOGRAPH + {0xEFBF, 0x951F}, //19616 #CJK UNIFIED IDEOGRAPH + {0xEFC0, 0x9522}, //19617 #CJK UNIFIED IDEOGRAPH + {0xEFC1, 0x952A}, //19618 #CJK UNIFIED IDEOGRAPH + {0xEFC2, 0x952B}, //19619 #CJK UNIFIED IDEOGRAPH + {0xEFC3, 0x9529}, //19620 #CJK UNIFIED IDEOGRAPH + {0xEFC4, 0x952C}, //19621 #CJK UNIFIED IDEOGRAPH + {0xEFC5, 0x9531}, //19622 #CJK UNIFIED IDEOGRAPH + {0xEFC6, 0x9532}, //19623 #CJK UNIFIED IDEOGRAPH + {0xEFC7, 0x9534}, //19624 #CJK UNIFIED IDEOGRAPH + {0xEFC8, 0x9536}, //19625 #CJK UNIFIED IDEOGRAPH + {0xEFC9, 0x9537}, //19626 #CJK UNIFIED IDEOGRAPH + {0xEFCA, 0x9538}, //19627 #CJK UNIFIED IDEOGRAPH + {0xEFCB, 0x953C}, //19628 #CJK UNIFIED IDEOGRAPH + {0xEFCC, 0x953E}, //19629 #CJK UNIFIED IDEOGRAPH + {0xEFCD, 0x953F}, //19630 #CJK UNIFIED IDEOGRAPH + {0xEFCE, 0x9542}, //19631 #CJK UNIFIED IDEOGRAPH + {0xEFCF, 0x9535}, //19632 #CJK UNIFIED IDEOGRAPH + {0xEFD0, 0x9544}, //19633 #CJK UNIFIED IDEOGRAPH + {0xEFD1, 0x9545}, //19634 #CJK UNIFIED IDEOGRAPH + {0xEFD2, 0x9546}, //19635 #CJK UNIFIED IDEOGRAPH + {0xEFD3, 0x9549}, //19636 #CJK UNIFIED IDEOGRAPH + {0xEFD4, 0x954C}, //19637 #CJK UNIFIED IDEOGRAPH + {0xEFD5, 0x954E}, //19638 #CJK UNIFIED IDEOGRAPH + {0xEFD6, 0x954F}, //19639 #CJK UNIFIED IDEOGRAPH + {0xEFD7, 0x9552}, //19640 #CJK UNIFIED IDEOGRAPH + {0xEFD8, 0x9553}, //19641 #CJK UNIFIED IDEOGRAPH + {0xEFD9, 0x9554}, //19642 #CJK UNIFIED IDEOGRAPH + {0xEFDA, 0x9556}, //19643 #CJK UNIFIED IDEOGRAPH + {0xEFDB, 0x9557}, //19644 #CJK UNIFIED IDEOGRAPH + {0xEFDC, 0x9558}, //19645 #CJK UNIFIED IDEOGRAPH + {0xEFDD, 0x9559}, //19646 #CJK UNIFIED IDEOGRAPH + {0xEFDE, 0x955B}, //19647 #CJK UNIFIED IDEOGRAPH + {0xEFDF, 0x955E}, //19648 #CJK UNIFIED IDEOGRAPH + {0xEFE0, 0x955F}, //19649 #CJK UNIFIED IDEOGRAPH + {0xEFE1, 0x955D}, //19650 #CJK UNIFIED IDEOGRAPH + {0xEFE2, 0x9561}, //19651 #CJK UNIFIED IDEOGRAPH + {0xEFE3, 0x9562}, //19652 #CJK UNIFIED IDEOGRAPH + {0xEFE4, 0x9564}, //19653 #CJK UNIFIED IDEOGRAPH + {0xEFE5, 0x9565}, //19654 #CJK UNIFIED IDEOGRAPH + {0xEFE6, 0x9566}, //19655 #CJK UNIFIED IDEOGRAPH + {0xEFE7, 0x9567}, //19656 #CJK UNIFIED IDEOGRAPH + {0xEFE8, 0x9568}, //19657 #CJK UNIFIED IDEOGRAPH + {0xEFE9, 0x9569}, //19658 #CJK UNIFIED IDEOGRAPH + {0xEFEA, 0x956A}, //19659 #CJK UNIFIED IDEOGRAPH + {0xEFEB, 0x956B}, //19660 #CJK UNIFIED IDEOGRAPH + {0xEFEC, 0x956C}, //19661 #CJK UNIFIED IDEOGRAPH + {0xEFED, 0x956F}, //19662 #CJK UNIFIED IDEOGRAPH + {0xEFEE, 0x9571}, //19663 #CJK UNIFIED IDEOGRAPH + {0xEFEF, 0x9572}, //19664 #CJK UNIFIED IDEOGRAPH + {0xEFF0, 0x9573}, //19665 #CJK UNIFIED IDEOGRAPH + {0xEFF1, 0x953A}, //19666 #CJK UNIFIED IDEOGRAPH + {0xEFF2, 0x77E7}, //19667 #CJK UNIFIED IDEOGRAPH + {0xEFF3, 0x77EC}, //19668 #CJK UNIFIED IDEOGRAPH + {0xEFF4, 0x96C9}, //19669 #CJK UNIFIED IDEOGRAPH + {0xEFF5, 0x79D5}, //19670 #CJK UNIFIED IDEOGRAPH + {0xEFF6, 0x79ED}, //19671 #CJK UNIFIED IDEOGRAPH + {0xEFF7, 0x79E3}, //19672 #CJK UNIFIED IDEOGRAPH + {0xEFF8, 0x79EB}, //19673 #CJK UNIFIED IDEOGRAPH + {0xEFF9, 0x7A06}, //19674 #CJK UNIFIED IDEOGRAPH + {0xEFFA, 0x5D47}, //19675 #CJK UNIFIED IDEOGRAPH + {0xEFFB, 0x7A03}, //19676 #CJK UNIFIED IDEOGRAPH + {0xEFFC, 0x7A02}, //19677 #CJK UNIFIED IDEOGRAPH + {0xEFFD, 0x7A1E}, //19678 #CJK UNIFIED IDEOGRAPH + {0xEFFE, 0x7A14}, //19679 #CJK UNIFIED IDEOGRAPH + {0xF040, 0x9908}, //19680 #CJK UNIFIED IDEOGRAPH + {0xF041, 0x9909}, //19681 #CJK UNIFIED IDEOGRAPH + {0xF042, 0x990A}, //19682 #CJK UNIFIED IDEOGRAPH + {0xF043, 0x990B}, //19683 #CJK UNIFIED IDEOGRAPH + {0xF044, 0x990C}, //19684 #CJK UNIFIED IDEOGRAPH + {0xF045, 0x990E}, //19685 #CJK UNIFIED IDEOGRAPH + {0xF046, 0x990F}, //19686 #CJK UNIFIED IDEOGRAPH + {0xF047, 0x9911}, //19687 #CJK UNIFIED IDEOGRAPH + {0xF048, 0x9912}, //19688 #CJK UNIFIED IDEOGRAPH + {0xF049, 0x9913}, //19689 #CJK UNIFIED IDEOGRAPH + {0xF04A, 0x9914}, //19690 #CJK UNIFIED IDEOGRAPH + {0xF04B, 0x9915}, //19691 #CJK UNIFIED IDEOGRAPH + {0xF04C, 0x9916}, //19692 #CJK UNIFIED IDEOGRAPH + {0xF04D, 0x9917}, //19693 #CJK UNIFIED IDEOGRAPH + {0xF04E, 0x9918}, //19694 #CJK UNIFIED IDEOGRAPH + {0xF04F, 0x9919}, //19695 #CJK UNIFIED IDEOGRAPH + {0xF050, 0x991A}, //19696 #CJK UNIFIED IDEOGRAPH + {0xF051, 0x991B}, //19697 #CJK UNIFIED IDEOGRAPH + {0xF052, 0x991C}, //19698 #CJK UNIFIED IDEOGRAPH + {0xF053, 0x991D}, //19699 #CJK UNIFIED IDEOGRAPH + {0xF054, 0x991E}, //19700 #CJK UNIFIED IDEOGRAPH + {0xF055, 0x991F}, //19701 #CJK UNIFIED IDEOGRAPH + {0xF056, 0x9920}, //19702 #CJK UNIFIED IDEOGRAPH + {0xF057, 0x9921}, //19703 #CJK UNIFIED IDEOGRAPH + {0xF058, 0x9922}, //19704 #CJK UNIFIED IDEOGRAPH + {0xF059, 0x9923}, //19705 #CJK UNIFIED IDEOGRAPH + {0xF05A, 0x9924}, //19706 #CJK UNIFIED IDEOGRAPH + {0xF05B, 0x9925}, //19707 #CJK UNIFIED IDEOGRAPH + {0xF05C, 0x9926}, //19708 #CJK UNIFIED IDEOGRAPH + {0xF05D, 0x9927}, //19709 #CJK UNIFIED IDEOGRAPH + {0xF05E, 0x9928}, //19710 #CJK UNIFIED IDEOGRAPH + {0xF05F, 0x9929}, //19711 #CJK UNIFIED IDEOGRAPH + {0xF060, 0x992A}, //19712 #CJK UNIFIED IDEOGRAPH + {0xF061, 0x992B}, //19713 #CJK UNIFIED IDEOGRAPH + {0xF062, 0x992C}, //19714 #CJK UNIFIED IDEOGRAPH + {0xF063, 0x992D}, //19715 #CJK UNIFIED IDEOGRAPH + {0xF064, 0x992F}, //19716 #CJK UNIFIED IDEOGRAPH + {0xF065, 0x9930}, //19717 #CJK UNIFIED IDEOGRAPH + {0xF066, 0x9931}, //19718 #CJK UNIFIED IDEOGRAPH + {0xF067, 0x9932}, //19719 #CJK UNIFIED IDEOGRAPH + {0xF068, 0x9933}, //19720 #CJK UNIFIED IDEOGRAPH + {0xF069, 0x9934}, //19721 #CJK UNIFIED IDEOGRAPH + {0xF06A, 0x9935}, //19722 #CJK UNIFIED IDEOGRAPH + {0xF06B, 0x9936}, //19723 #CJK UNIFIED IDEOGRAPH + {0xF06C, 0x9937}, //19724 #CJK UNIFIED IDEOGRAPH + {0xF06D, 0x9938}, //19725 #CJK UNIFIED IDEOGRAPH + {0xF06E, 0x9939}, //19726 #CJK UNIFIED IDEOGRAPH + {0xF06F, 0x993A}, //19727 #CJK UNIFIED IDEOGRAPH + {0xF070, 0x993B}, //19728 #CJK UNIFIED IDEOGRAPH + {0xF071, 0x993C}, //19729 #CJK UNIFIED IDEOGRAPH + {0xF072, 0x993D}, //19730 #CJK UNIFIED IDEOGRAPH + {0xF073, 0x993E}, //19731 #CJK UNIFIED IDEOGRAPH + {0xF074, 0x993F}, //19732 #CJK UNIFIED IDEOGRAPH + {0xF075, 0x9940}, //19733 #CJK UNIFIED IDEOGRAPH + {0xF076, 0x9941}, //19734 #CJK UNIFIED IDEOGRAPH + {0xF077, 0x9942}, //19735 #CJK UNIFIED IDEOGRAPH + {0xF078, 0x9943}, //19736 #CJK UNIFIED IDEOGRAPH + {0xF079, 0x9944}, //19737 #CJK UNIFIED IDEOGRAPH + {0xF07A, 0x9945}, //19738 #CJK UNIFIED IDEOGRAPH + {0xF07B, 0x9946}, //19739 #CJK UNIFIED IDEOGRAPH + {0xF07C, 0x9947}, //19740 #CJK UNIFIED IDEOGRAPH + {0xF07D, 0x9948}, //19741 #CJK UNIFIED IDEOGRAPH + {0xF07E, 0x9949}, //19742 #CJK UNIFIED IDEOGRAPH + {0xF080, 0x994A}, //19743 #CJK UNIFIED IDEOGRAPH + {0xF081, 0x994B}, //19744 #CJK UNIFIED IDEOGRAPH + {0xF082, 0x994C}, //19745 #CJK UNIFIED IDEOGRAPH + {0xF083, 0x994D}, //19746 #CJK UNIFIED IDEOGRAPH + {0xF084, 0x994E}, //19747 #CJK UNIFIED IDEOGRAPH + {0xF085, 0x994F}, //19748 #CJK UNIFIED IDEOGRAPH + {0xF086, 0x9950}, //19749 #CJK UNIFIED IDEOGRAPH + {0xF087, 0x9951}, //19750 #CJK UNIFIED IDEOGRAPH + {0xF088, 0x9952}, //19751 #CJK UNIFIED IDEOGRAPH + {0xF089, 0x9953}, //19752 #CJK UNIFIED IDEOGRAPH + {0xF08A, 0x9956}, //19753 #CJK UNIFIED IDEOGRAPH + {0xF08B, 0x9957}, //19754 #CJK UNIFIED IDEOGRAPH + {0xF08C, 0x9958}, //19755 #CJK UNIFIED IDEOGRAPH + {0xF08D, 0x9959}, //19756 #CJK UNIFIED IDEOGRAPH + {0xF08E, 0x995A}, //19757 #CJK UNIFIED IDEOGRAPH + {0xF08F, 0x995B}, //19758 #CJK UNIFIED IDEOGRAPH + {0xF090, 0x995C}, //19759 #CJK UNIFIED IDEOGRAPH + {0xF091, 0x995D}, //19760 #CJK UNIFIED IDEOGRAPH + {0xF092, 0x995E}, //19761 #CJK UNIFIED IDEOGRAPH + {0xF093, 0x995F}, //19762 #CJK UNIFIED IDEOGRAPH + {0xF094, 0x9960}, //19763 #CJK UNIFIED IDEOGRAPH + {0xF095, 0x9961}, //19764 #CJK UNIFIED IDEOGRAPH + {0xF096, 0x9962}, //19765 #CJK UNIFIED IDEOGRAPH + {0xF097, 0x9964}, //19766 #CJK UNIFIED IDEOGRAPH + {0xF098, 0x9966}, //19767 #CJK UNIFIED IDEOGRAPH + {0xF099, 0x9973}, //19768 #CJK UNIFIED IDEOGRAPH + {0xF09A, 0x9978}, //19769 #CJK UNIFIED IDEOGRAPH + {0xF09B, 0x9979}, //19770 #CJK UNIFIED IDEOGRAPH + {0xF09C, 0x997B}, //19771 #CJK UNIFIED IDEOGRAPH + {0xF09D, 0x997E}, //19772 #CJK UNIFIED IDEOGRAPH + {0xF09E, 0x9982}, //19773 #CJK UNIFIED IDEOGRAPH + {0xF09F, 0x9983}, //19774 #CJK UNIFIED IDEOGRAPH + {0xF0A0, 0x9989}, //19775 #CJK UNIFIED IDEOGRAPH + {0xF0A1, 0x7A39}, //19776 #CJK UNIFIED IDEOGRAPH + {0xF0A2, 0x7A37}, //19777 #CJK UNIFIED IDEOGRAPH + {0xF0A3, 0x7A51}, //19778 #CJK UNIFIED IDEOGRAPH + {0xF0A4, 0x9ECF}, //19779 #CJK UNIFIED IDEOGRAPH + {0xF0A5, 0x99A5}, //19780 #CJK UNIFIED IDEOGRAPH + {0xF0A6, 0x7A70}, //19781 #CJK UNIFIED IDEOGRAPH + {0xF0A7, 0x7688}, //19782 #CJK UNIFIED IDEOGRAPH + {0xF0A8, 0x768E}, //19783 #CJK UNIFIED IDEOGRAPH + {0xF0A9, 0x7693}, //19784 #CJK UNIFIED IDEOGRAPH + {0xF0AA, 0x7699}, //19785 #CJK UNIFIED IDEOGRAPH + {0xF0AB, 0x76A4}, //19786 #CJK UNIFIED IDEOGRAPH + {0xF0AC, 0x74DE}, //19787 #CJK UNIFIED IDEOGRAPH + {0xF0AD, 0x74E0}, //19788 #CJK UNIFIED IDEOGRAPH + {0xF0AE, 0x752C}, //19789 #CJK UNIFIED IDEOGRAPH + {0xF0AF, 0x9E20}, //19790 #CJK UNIFIED IDEOGRAPH + {0xF0B0, 0x9E22}, //19791 #CJK UNIFIED IDEOGRAPH + {0xF0B1, 0x9E28}, //19792 #CJK UNIFIED IDEOGRAPH + {0xF0B2, 0x9E29}, //19793 #CJK UNIFIED IDEOGRAPH + {0xF0B3, 0x9E2A}, //19794 #CJK UNIFIED IDEOGRAPH + {0xF0B4, 0x9E2B}, //19795 #CJK UNIFIED IDEOGRAPH + {0xF0B5, 0x9E2C}, //19796 #CJK UNIFIED IDEOGRAPH + {0xF0B6, 0x9E32}, //19797 #CJK UNIFIED IDEOGRAPH + {0xF0B7, 0x9E31}, //19798 #CJK UNIFIED IDEOGRAPH + {0xF0B8, 0x9E36}, //19799 #CJK UNIFIED IDEOGRAPH + {0xF0B9, 0x9E38}, //19800 #CJK UNIFIED IDEOGRAPH + {0xF0BA, 0x9E37}, //19801 #CJK UNIFIED IDEOGRAPH + {0xF0BB, 0x9E39}, //19802 #CJK UNIFIED IDEOGRAPH + {0xF0BC, 0x9E3A}, //19803 #CJK UNIFIED IDEOGRAPH + {0xF0BD, 0x9E3E}, //19804 #CJK UNIFIED IDEOGRAPH + {0xF0BE, 0x9E41}, //19805 #CJK UNIFIED IDEOGRAPH + {0xF0BF, 0x9E42}, //19806 #CJK UNIFIED IDEOGRAPH + {0xF0C0, 0x9E44}, //19807 #CJK UNIFIED IDEOGRAPH + {0xF0C1, 0x9E46}, //19808 #CJK UNIFIED IDEOGRAPH + {0xF0C2, 0x9E47}, //19809 #CJK UNIFIED IDEOGRAPH + {0xF0C3, 0x9E48}, //19810 #CJK UNIFIED IDEOGRAPH + {0xF0C4, 0x9E49}, //19811 #CJK UNIFIED IDEOGRAPH + {0xF0C5, 0x9E4B}, //19812 #CJK UNIFIED IDEOGRAPH + {0xF0C6, 0x9E4C}, //19813 #CJK UNIFIED IDEOGRAPH + {0xF0C7, 0x9E4E}, //19814 #CJK UNIFIED IDEOGRAPH + {0xF0C8, 0x9E51}, //19815 #CJK UNIFIED IDEOGRAPH + {0xF0C9, 0x9E55}, //19816 #CJK UNIFIED IDEOGRAPH + {0xF0CA, 0x9E57}, //19817 #CJK UNIFIED IDEOGRAPH + {0xF0CB, 0x9E5A}, //19818 #CJK UNIFIED IDEOGRAPH + {0xF0CC, 0x9E5B}, //19819 #CJK UNIFIED IDEOGRAPH + {0xF0CD, 0x9E5C}, //19820 #CJK UNIFIED IDEOGRAPH + {0xF0CE, 0x9E5E}, //19821 #CJK UNIFIED IDEOGRAPH + {0xF0CF, 0x9E63}, //19822 #CJK UNIFIED IDEOGRAPH + {0xF0D0, 0x9E66}, //19823 #CJK UNIFIED IDEOGRAPH + {0xF0D1, 0x9E67}, //19824 #CJK UNIFIED IDEOGRAPH + {0xF0D2, 0x9E68}, //19825 #CJK UNIFIED IDEOGRAPH + {0xF0D3, 0x9E69}, //19826 #CJK UNIFIED IDEOGRAPH + {0xF0D4, 0x9E6A}, //19827 #CJK UNIFIED IDEOGRAPH + {0xF0D5, 0x9E6B}, //19828 #CJK UNIFIED IDEOGRAPH + {0xF0D6, 0x9E6C}, //19829 #CJK UNIFIED IDEOGRAPH + {0xF0D7, 0x9E71}, //19830 #CJK UNIFIED IDEOGRAPH + {0xF0D8, 0x9E6D}, //19831 #CJK UNIFIED IDEOGRAPH + {0xF0D9, 0x9E73}, //19832 #CJK UNIFIED IDEOGRAPH + {0xF0DA, 0x7592}, //19833 #CJK UNIFIED IDEOGRAPH + {0xF0DB, 0x7594}, //19834 #CJK UNIFIED IDEOGRAPH + {0xF0DC, 0x7596}, //19835 #CJK UNIFIED IDEOGRAPH + {0xF0DD, 0x75A0}, //19836 #CJK UNIFIED IDEOGRAPH + {0xF0DE, 0x759D}, //19837 #CJK UNIFIED IDEOGRAPH + {0xF0DF, 0x75AC}, //19838 #CJK UNIFIED IDEOGRAPH + {0xF0E0, 0x75A3}, //19839 #CJK UNIFIED IDEOGRAPH + {0xF0E1, 0x75B3}, //19840 #CJK UNIFIED IDEOGRAPH + {0xF0E2, 0x75B4}, //19841 #CJK UNIFIED IDEOGRAPH + {0xF0E3, 0x75B8}, //19842 #CJK UNIFIED IDEOGRAPH + {0xF0E4, 0x75C4}, //19843 #CJK UNIFIED IDEOGRAPH + {0xF0E5, 0x75B1}, //19844 #CJK UNIFIED IDEOGRAPH + {0xF0E6, 0x75B0}, //19845 #CJK UNIFIED IDEOGRAPH + {0xF0E7, 0x75C3}, //19846 #CJK UNIFIED IDEOGRAPH + {0xF0E8, 0x75C2}, //19847 #CJK UNIFIED IDEOGRAPH + {0xF0E9, 0x75D6}, //19848 #CJK UNIFIED IDEOGRAPH + {0xF0EA, 0x75CD}, //19849 #CJK UNIFIED IDEOGRAPH + {0xF0EB, 0x75E3}, //19850 #CJK UNIFIED IDEOGRAPH + {0xF0EC, 0x75E8}, //19851 #CJK UNIFIED IDEOGRAPH + {0xF0ED, 0x75E6}, //19852 #CJK UNIFIED IDEOGRAPH + {0xF0EE, 0x75E4}, //19853 #CJK UNIFIED IDEOGRAPH + {0xF0EF, 0x75EB}, //19854 #CJK UNIFIED IDEOGRAPH + {0xF0F0, 0x75E7}, //19855 #CJK UNIFIED IDEOGRAPH + {0xF0F1, 0x7603}, //19856 #CJK UNIFIED IDEOGRAPH + {0xF0F2, 0x75F1}, //19857 #CJK UNIFIED IDEOGRAPH + {0xF0F3, 0x75FC}, //19858 #CJK UNIFIED IDEOGRAPH + {0xF0F4, 0x75FF}, //19859 #CJK UNIFIED IDEOGRAPH + {0xF0F5, 0x7610}, //19860 #CJK UNIFIED IDEOGRAPH + {0xF0F6, 0x7600}, //19861 #CJK UNIFIED IDEOGRAPH + {0xF0F7, 0x7605}, //19862 #CJK UNIFIED IDEOGRAPH + {0xF0F8, 0x760C}, //19863 #CJK UNIFIED IDEOGRAPH + {0xF0F9, 0x7617}, //19864 #CJK UNIFIED IDEOGRAPH + {0xF0FA, 0x760A}, //19865 #CJK UNIFIED IDEOGRAPH + {0xF0FB, 0x7625}, //19866 #CJK UNIFIED IDEOGRAPH + {0xF0FC, 0x7618}, //19867 #CJK UNIFIED IDEOGRAPH + {0xF0FD, 0x7615}, //19868 #CJK UNIFIED IDEOGRAPH + {0xF0FE, 0x7619}, //19869 #CJK UNIFIED IDEOGRAPH + {0xF140, 0x998C}, //19870 #CJK UNIFIED IDEOGRAPH + {0xF141, 0x998E}, //19871 #CJK UNIFIED IDEOGRAPH + {0xF142, 0x999A}, //19872 #CJK UNIFIED IDEOGRAPH + {0xF143, 0x999B}, //19873 #CJK UNIFIED IDEOGRAPH + {0xF144, 0x999C}, //19874 #CJK UNIFIED IDEOGRAPH + {0xF145, 0x999D}, //19875 #CJK UNIFIED IDEOGRAPH + {0xF146, 0x999E}, //19876 #CJK UNIFIED IDEOGRAPH + {0xF147, 0x999F}, //19877 #CJK UNIFIED IDEOGRAPH + {0xF148, 0x99A0}, //19878 #CJK UNIFIED IDEOGRAPH + {0xF149, 0x99A1}, //19879 #CJK UNIFIED IDEOGRAPH + {0xF14A, 0x99A2}, //19880 #CJK UNIFIED IDEOGRAPH + {0xF14B, 0x99A3}, //19881 #CJK UNIFIED IDEOGRAPH + {0xF14C, 0x99A4}, //19882 #CJK UNIFIED IDEOGRAPH + {0xF14D, 0x99A6}, //19883 #CJK UNIFIED IDEOGRAPH + {0xF14E, 0x99A7}, //19884 #CJK UNIFIED IDEOGRAPH + {0xF14F, 0x99A9}, //19885 #CJK UNIFIED IDEOGRAPH + {0xF150, 0x99AA}, //19886 #CJK UNIFIED IDEOGRAPH + {0xF151, 0x99AB}, //19887 #CJK UNIFIED IDEOGRAPH + {0xF152, 0x99AC}, //19888 #CJK UNIFIED IDEOGRAPH + {0xF153, 0x99AD}, //19889 #CJK UNIFIED IDEOGRAPH + {0xF154, 0x99AE}, //19890 #CJK UNIFIED IDEOGRAPH + {0xF155, 0x99AF}, //19891 #CJK UNIFIED IDEOGRAPH + {0xF156, 0x99B0}, //19892 #CJK UNIFIED IDEOGRAPH + {0xF157, 0x99B1}, //19893 #CJK UNIFIED IDEOGRAPH + {0xF158, 0x99B2}, //19894 #CJK UNIFIED IDEOGRAPH + {0xF159, 0x99B3}, //19895 #CJK UNIFIED IDEOGRAPH + {0xF15A, 0x99B4}, //19896 #CJK UNIFIED IDEOGRAPH + {0xF15B, 0x99B5}, //19897 #CJK UNIFIED IDEOGRAPH + {0xF15C, 0x99B6}, //19898 #CJK UNIFIED IDEOGRAPH + {0xF15D, 0x99B7}, //19899 #CJK UNIFIED IDEOGRAPH + {0xF15E, 0x99B8}, //19900 #CJK UNIFIED IDEOGRAPH + {0xF15F, 0x99B9}, //19901 #CJK UNIFIED IDEOGRAPH + {0xF160, 0x99BA}, //19902 #CJK UNIFIED IDEOGRAPH + {0xF161, 0x99BB}, //19903 #CJK UNIFIED IDEOGRAPH + {0xF162, 0x99BC}, //19904 #CJK UNIFIED IDEOGRAPH + {0xF163, 0x99BD}, //19905 #CJK UNIFIED IDEOGRAPH + {0xF164, 0x99BE}, //19906 #CJK UNIFIED IDEOGRAPH + {0xF165, 0x99BF}, //19907 #CJK UNIFIED IDEOGRAPH + {0xF166, 0x99C0}, //19908 #CJK UNIFIED IDEOGRAPH + {0xF167, 0x99C1}, //19909 #CJK UNIFIED IDEOGRAPH + {0xF168, 0x99C2}, //19910 #CJK UNIFIED IDEOGRAPH + {0xF169, 0x99C3}, //19911 #CJK UNIFIED IDEOGRAPH + {0xF16A, 0x99C4}, //19912 #CJK UNIFIED IDEOGRAPH + {0xF16B, 0x99C5}, //19913 #CJK UNIFIED IDEOGRAPH + {0xF16C, 0x99C6}, //19914 #CJK UNIFIED IDEOGRAPH + {0xF16D, 0x99C7}, //19915 #CJK UNIFIED IDEOGRAPH + {0xF16E, 0x99C8}, //19916 #CJK UNIFIED IDEOGRAPH + {0xF16F, 0x99C9}, //19917 #CJK UNIFIED IDEOGRAPH + {0xF170, 0x99CA}, //19918 #CJK UNIFIED IDEOGRAPH + {0xF171, 0x99CB}, //19919 #CJK UNIFIED IDEOGRAPH + {0xF172, 0x99CC}, //19920 #CJK UNIFIED IDEOGRAPH + {0xF173, 0x99CD}, //19921 #CJK UNIFIED IDEOGRAPH + {0xF174, 0x99CE}, //19922 #CJK UNIFIED IDEOGRAPH + {0xF175, 0x99CF}, //19923 #CJK UNIFIED IDEOGRAPH + {0xF176, 0x99D0}, //19924 #CJK UNIFIED IDEOGRAPH + {0xF177, 0x99D1}, //19925 #CJK UNIFIED IDEOGRAPH + {0xF178, 0x99D2}, //19926 #CJK UNIFIED IDEOGRAPH + {0xF179, 0x99D3}, //19927 #CJK UNIFIED IDEOGRAPH + {0xF17A, 0x99D4}, //19928 #CJK UNIFIED IDEOGRAPH + {0xF17B, 0x99D5}, //19929 #CJK UNIFIED IDEOGRAPH + {0xF17C, 0x99D6}, //19930 #CJK UNIFIED IDEOGRAPH + {0xF17D, 0x99D7}, //19931 #CJK UNIFIED IDEOGRAPH + {0xF17E, 0x99D8}, //19932 #CJK UNIFIED IDEOGRAPH + {0xF180, 0x99D9}, //19933 #CJK UNIFIED IDEOGRAPH + {0xF181, 0x99DA}, //19934 #CJK UNIFIED IDEOGRAPH + {0xF182, 0x99DB}, //19935 #CJK UNIFIED IDEOGRAPH + {0xF183, 0x99DC}, //19936 #CJK UNIFIED IDEOGRAPH + {0xF184, 0x99DD}, //19937 #CJK UNIFIED IDEOGRAPH + {0xF185, 0x99DE}, //19938 #CJK UNIFIED IDEOGRAPH + {0xF186, 0x99DF}, //19939 #CJK UNIFIED IDEOGRAPH + {0xF187, 0x99E0}, //19940 #CJK UNIFIED IDEOGRAPH + {0xF188, 0x99E1}, //19941 #CJK UNIFIED IDEOGRAPH + {0xF189, 0x99E2}, //19942 #CJK UNIFIED IDEOGRAPH + {0xF18A, 0x99E3}, //19943 #CJK UNIFIED IDEOGRAPH + {0xF18B, 0x99E4}, //19944 #CJK UNIFIED IDEOGRAPH + {0xF18C, 0x99E5}, //19945 #CJK UNIFIED IDEOGRAPH + {0xF18D, 0x99E6}, //19946 #CJK UNIFIED IDEOGRAPH + {0xF18E, 0x99E7}, //19947 #CJK UNIFIED IDEOGRAPH + {0xF18F, 0x99E8}, //19948 #CJK UNIFIED IDEOGRAPH + {0xF190, 0x99E9}, //19949 #CJK UNIFIED IDEOGRAPH + {0xF191, 0x99EA}, //19950 #CJK UNIFIED IDEOGRAPH + {0xF192, 0x99EB}, //19951 #CJK UNIFIED IDEOGRAPH + {0xF193, 0x99EC}, //19952 #CJK UNIFIED IDEOGRAPH + {0xF194, 0x99ED}, //19953 #CJK UNIFIED IDEOGRAPH + {0xF195, 0x99EE}, //19954 #CJK UNIFIED IDEOGRAPH + {0xF196, 0x99EF}, //19955 #CJK UNIFIED IDEOGRAPH + {0xF197, 0x99F0}, //19956 #CJK UNIFIED IDEOGRAPH + {0xF198, 0x99F1}, //19957 #CJK UNIFIED IDEOGRAPH + {0xF199, 0x99F2}, //19958 #CJK UNIFIED IDEOGRAPH + {0xF19A, 0x99F3}, //19959 #CJK UNIFIED IDEOGRAPH + {0xF19B, 0x99F4}, //19960 #CJK UNIFIED IDEOGRAPH + {0xF19C, 0x99F5}, //19961 #CJK UNIFIED IDEOGRAPH + {0xF19D, 0x99F6}, //19962 #CJK UNIFIED IDEOGRAPH + {0xF19E, 0x99F7}, //19963 #CJK UNIFIED IDEOGRAPH + {0xF19F, 0x99F8}, //19964 #CJK UNIFIED IDEOGRAPH + {0xF1A0, 0x99F9}, //19965 #CJK UNIFIED IDEOGRAPH + {0xF1A1, 0x761B}, //19966 #CJK UNIFIED IDEOGRAPH + {0xF1A2, 0x763C}, //19967 #CJK UNIFIED IDEOGRAPH + {0xF1A3, 0x7622}, //19968 #CJK UNIFIED IDEOGRAPH + {0xF1A4, 0x7620}, //19969 #CJK UNIFIED IDEOGRAPH + {0xF1A5, 0x7640}, //19970 #CJK UNIFIED IDEOGRAPH + {0xF1A6, 0x762D}, //19971 #CJK UNIFIED IDEOGRAPH + {0xF1A7, 0x7630}, //19972 #CJK UNIFIED IDEOGRAPH + {0xF1A8, 0x763F}, //19973 #CJK UNIFIED IDEOGRAPH + {0xF1A9, 0x7635}, //19974 #CJK UNIFIED IDEOGRAPH + {0xF1AA, 0x7643}, //19975 #CJK UNIFIED IDEOGRAPH + {0xF1AB, 0x763E}, //19976 #CJK UNIFIED IDEOGRAPH + {0xF1AC, 0x7633}, //19977 #CJK UNIFIED IDEOGRAPH + {0xF1AD, 0x764D}, //19978 #CJK UNIFIED IDEOGRAPH + {0xF1AE, 0x765E}, //19979 #CJK UNIFIED IDEOGRAPH + {0xF1AF, 0x7654}, //19980 #CJK UNIFIED IDEOGRAPH + {0xF1B0, 0x765C}, //19981 #CJK UNIFIED IDEOGRAPH + {0xF1B1, 0x7656}, //19982 #CJK UNIFIED IDEOGRAPH + {0xF1B2, 0x766B}, //19983 #CJK UNIFIED IDEOGRAPH + {0xF1B3, 0x766F}, //19984 #CJK UNIFIED IDEOGRAPH + {0xF1B4, 0x7FCA}, //19985 #CJK UNIFIED IDEOGRAPH + {0xF1B5, 0x7AE6}, //19986 #CJK UNIFIED IDEOGRAPH + {0xF1B6, 0x7A78}, //19987 #CJK UNIFIED IDEOGRAPH + {0xF1B7, 0x7A79}, //19988 #CJK UNIFIED IDEOGRAPH + {0xF1B8, 0x7A80}, //19989 #CJK UNIFIED IDEOGRAPH + {0xF1B9, 0x7A86}, //19990 #CJK UNIFIED IDEOGRAPH + {0xF1BA, 0x7A88}, //19991 #CJK UNIFIED IDEOGRAPH + {0xF1BB, 0x7A95}, //19992 #CJK UNIFIED IDEOGRAPH + {0xF1BC, 0x7AA6}, //19993 #CJK UNIFIED IDEOGRAPH + {0xF1BD, 0x7AA0}, //19994 #CJK UNIFIED IDEOGRAPH + {0xF1BE, 0x7AAC}, //19995 #CJK UNIFIED IDEOGRAPH + {0xF1BF, 0x7AA8}, //19996 #CJK UNIFIED IDEOGRAPH + {0xF1C0, 0x7AAD}, //19997 #CJK UNIFIED IDEOGRAPH + {0xF1C1, 0x7AB3}, //19998 #CJK UNIFIED IDEOGRAPH + {0xF1C2, 0x8864}, //19999 #CJK UNIFIED IDEOGRAPH + {0xF1C3, 0x8869}, //20000 #CJK UNIFIED IDEOGRAPH + {0xF1C4, 0x8872}, //20001 #CJK UNIFIED IDEOGRAPH + {0xF1C5, 0x887D}, //20002 #CJK UNIFIED IDEOGRAPH + {0xF1C6, 0x887F}, //20003 #CJK UNIFIED IDEOGRAPH + {0xF1C7, 0x8882}, //20004 #CJK UNIFIED IDEOGRAPH + {0xF1C8, 0x88A2}, //20005 #CJK UNIFIED IDEOGRAPH + {0xF1C9, 0x88C6}, //20006 #CJK UNIFIED IDEOGRAPH + {0xF1CA, 0x88B7}, //20007 #CJK UNIFIED IDEOGRAPH + {0xF1CB, 0x88BC}, //20008 #CJK UNIFIED IDEOGRAPH + {0xF1CC, 0x88C9}, //20009 #CJK UNIFIED IDEOGRAPH + {0xF1CD, 0x88E2}, //20010 #CJK UNIFIED IDEOGRAPH + {0xF1CE, 0x88CE}, //20011 #CJK UNIFIED IDEOGRAPH + {0xF1CF, 0x88E3}, //20012 #CJK UNIFIED IDEOGRAPH + {0xF1D0, 0x88E5}, //20013 #CJK UNIFIED IDEOGRAPH + {0xF1D1, 0x88F1}, //20014 #CJK UNIFIED IDEOGRAPH + {0xF1D2, 0x891A}, //20015 #CJK UNIFIED IDEOGRAPH + {0xF1D3, 0x88FC}, //20016 #CJK UNIFIED IDEOGRAPH + {0xF1D4, 0x88E8}, //20017 #CJK UNIFIED IDEOGRAPH + {0xF1D5, 0x88FE}, //20018 #CJK UNIFIED IDEOGRAPH + {0xF1D6, 0x88F0}, //20019 #CJK UNIFIED IDEOGRAPH + {0xF1D7, 0x8921}, //20020 #CJK UNIFIED IDEOGRAPH + {0xF1D8, 0x8919}, //20021 #CJK UNIFIED IDEOGRAPH + {0xF1D9, 0x8913}, //20022 #CJK UNIFIED IDEOGRAPH + {0xF1DA, 0x891B}, //20023 #CJK UNIFIED IDEOGRAPH + {0xF1DB, 0x890A}, //20024 #CJK UNIFIED IDEOGRAPH + {0xF1DC, 0x8934}, //20025 #CJK UNIFIED IDEOGRAPH + {0xF1DD, 0x892B}, //20026 #CJK UNIFIED IDEOGRAPH + {0xF1DE, 0x8936}, //20027 #CJK UNIFIED IDEOGRAPH + {0xF1DF, 0x8941}, //20028 #CJK UNIFIED IDEOGRAPH + {0xF1E0, 0x8966}, //20029 #CJK UNIFIED IDEOGRAPH + {0xF1E1, 0x897B}, //20030 #CJK UNIFIED IDEOGRAPH + {0xF1E2, 0x758B}, //20031 #CJK UNIFIED IDEOGRAPH + {0xF1E3, 0x80E5}, //20032 #CJK UNIFIED IDEOGRAPH + {0xF1E4, 0x76B2}, //20033 #CJK UNIFIED IDEOGRAPH + {0xF1E5, 0x76B4}, //20034 #CJK UNIFIED IDEOGRAPH + {0xF1E6, 0x77DC}, //20035 #CJK UNIFIED IDEOGRAPH + {0xF1E7, 0x8012}, //20036 #CJK UNIFIED IDEOGRAPH + {0xF1E8, 0x8014}, //20037 #CJK UNIFIED IDEOGRAPH + {0xF1E9, 0x8016}, //20038 #CJK UNIFIED IDEOGRAPH + {0xF1EA, 0x801C}, //20039 #CJK UNIFIED IDEOGRAPH + {0xF1EB, 0x8020}, //20040 #CJK UNIFIED IDEOGRAPH + {0xF1EC, 0x8022}, //20041 #CJK UNIFIED IDEOGRAPH + {0xF1ED, 0x8025}, //20042 #CJK UNIFIED IDEOGRAPH + {0xF1EE, 0x8026}, //20043 #CJK UNIFIED IDEOGRAPH + {0xF1EF, 0x8027}, //20044 #CJK UNIFIED IDEOGRAPH + {0xF1F0, 0x8029}, //20045 #CJK UNIFIED IDEOGRAPH + {0xF1F1, 0x8028}, //20046 #CJK UNIFIED IDEOGRAPH + {0xF1F2, 0x8031}, //20047 #CJK UNIFIED IDEOGRAPH + {0xF1F3, 0x800B}, //20048 #CJK UNIFIED IDEOGRAPH + {0xF1F4, 0x8035}, //20049 #CJK UNIFIED IDEOGRAPH + {0xF1F5, 0x8043}, //20050 #CJK UNIFIED IDEOGRAPH + {0xF1F6, 0x8046}, //20051 #CJK UNIFIED IDEOGRAPH + {0xF1F7, 0x804D}, //20052 #CJK UNIFIED IDEOGRAPH + {0xF1F8, 0x8052}, //20053 #CJK UNIFIED IDEOGRAPH + {0xF1F9, 0x8069}, //20054 #CJK UNIFIED IDEOGRAPH + {0xF1FA, 0x8071}, //20055 #CJK UNIFIED IDEOGRAPH + {0xF1FB, 0x8983}, //20056 #CJK UNIFIED IDEOGRAPH + {0xF1FC, 0x9878}, //20057 #CJK UNIFIED IDEOGRAPH + {0xF1FD, 0x9880}, //20058 #CJK UNIFIED IDEOGRAPH + {0xF1FE, 0x9883}, //20059 #CJK UNIFIED IDEOGRAPH + {0xF240, 0x99FA}, //20060 #CJK UNIFIED IDEOGRAPH + {0xF241, 0x99FB}, //20061 #CJK UNIFIED IDEOGRAPH + {0xF242, 0x99FC}, //20062 #CJK UNIFIED IDEOGRAPH + {0xF243, 0x99FD}, //20063 #CJK UNIFIED IDEOGRAPH + {0xF244, 0x99FE}, //20064 #CJK UNIFIED IDEOGRAPH + {0xF245, 0x99FF}, //20065 #CJK UNIFIED IDEOGRAPH + {0xF246, 0x9A00}, //20066 #CJK UNIFIED IDEOGRAPH + {0xF247, 0x9A01}, //20067 #CJK UNIFIED IDEOGRAPH + {0xF248, 0x9A02}, //20068 #CJK UNIFIED IDEOGRAPH + {0xF249, 0x9A03}, //20069 #CJK UNIFIED IDEOGRAPH + {0xF24A, 0x9A04}, //20070 #CJK UNIFIED IDEOGRAPH + {0xF24B, 0x9A05}, //20071 #CJK UNIFIED IDEOGRAPH + {0xF24C, 0x9A06}, //20072 #CJK UNIFIED IDEOGRAPH + {0xF24D, 0x9A07}, //20073 #CJK UNIFIED IDEOGRAPH + {0xF24E, 0x9A08}, //20074 #CJK UNIFIED IDEOGRAPH + {0xF24F, 0x9A09}, //20075 #CJK UNIFIED IDEOGRAPH + {0xF250, 0x9A0A}, //20076 #CJK UNIFIED IDEOGRAPH + {0xF251, 0x9A0B}, //20077 #CJK UNIFIED IDEOGRAPH + {0xF252, 0x9A0C}, //20078 #CJK UNIFIED IDEOGRAPH + {0xF253, 0x9A0D}, //20079 #CJK UNIFIED IDEOGRAPH + {0xF254, 0x9A0E}, //20080 #CJK UNIFIED IDEOGRAPH + {0xF255, 0x9A0F}, //20081 #CJK UNIFIED IDEOGRAPH + {0xF256, 0x9A10}, //20082 #CJK UNIFIED IDEOGRAPH + {0xF257, 0x9A11}, //20083 #CJK UNIFIED IDEOGRAPH + {0xF258, 0x9A12}, //20084 #CJK UNIFIED IDEOGRAPH + {0xF259, 0x9A13}, //20085 #CJK UNIFIED IDEOGRAPH + {0xF25A, 0x9A14}, //20086 #CJK UNIFIED IDEOGRAPH + {0xF25B, 0x9A15}, //20087 #CJK UNIFIED IDEOGRAPH + {0xF25C, 0x9A16}, //20088 #CJK UNIFIED IDEOGRAPH + {0xF25D, 0x9A17}, //20089 #CJK UNIFIED IDEOGRAPH + {0xF25E, 0x9A18}, //20090 #CJK UNIFIED IDEOGRAPH + {0xF25F, 0x9A19}, //20091 #CJK UNIFIED IDEOGRAPH + {0xF260, 0x9A1A}, //20092 #CJK UNIFIED IDEOGRAPH + {0xF261, 0x9A1B}, //20093 #CJK UNIFIED IDEOGRAPH + {0xF262, 0x9A1C}, //20094 #CJK UNIFIED IDEOGRAPH + {0xF263, 0x9A1D}, //20095 #CJK UNIFIED IDEOGRAPH + {0xF264, 0x9A1E}, //20096 #CJK UNIFIED IDEOGRAPH + {0xF265, 0x9A1F}, //20097 #CJK UNIFIED IDEOGRAPH + {0xF266, 0x9A20}, //20098 #CJK UNIFIED IDEOGRAPH + {0xF267, 0x9A21}, //20099 #CJK UNIFIED IDEOGRAPH + {0xF268, 0x9A22}, //20100 #CJK UNIFIED IDEOGRAPH + {0xF269, 0x9A23}, //20101 #CJK UNIFIED IDEOGRAPH + {0xF26A, 0x9A24}, //20102 #CJK UNIFIED IDEOGRAPH + {0xF26B, 0x9A25}, //20103 #CJK UNIFIED IDEOGRAPH + {0xF26C, 0x9A26}, //20104 #CJK UNIFIED IDEOGRAPH + {0xF26D, 0x9A27}, //20105 #CJK UNIFIED IDEOGRAPH + {0xF26E, 0x9A28}, //20106 #CJK UNIFIED IDEOGRAPH + {0xF26F, 0x9A29}, //20107 #CJK UNIFIED IDEOGRAPH + {0xF270, 0x9A2A}, //20108 #CJK UNIFIED IDEOGRAPH + {0xF271, 0x9A2B}, //20109 #CJK UNIFIED IDEOGRAPH + {0xF272, 0x9A2C}, //20110 #CJK UNIFIED IDEOGRAPH + {0xF273, 0x9A2D}, //20111 #CJK UNIFIED IDEOGRAPH + {0xF274, 0x9A2E}, //20112 #CJK UNIFIED IDEOGRAPH + {0xF275, 0x9A2F}, //20113 #CJK UNIFIED IDEOGRAPH + {0xF276, 0x9A30}, //20114 #CJK UNIFIED IDEOGRAPH + {0xF277, 0x9A31}, //20115 #CJK UNIFIED IDEOGRAPH + {0xF278, 0x9A32}, //20116 #CJK UNIFIED IDEOGRAPH + {0xF279, 0x9A33}, //20117 #CJK UNIFIED IDEOGRAPH + {0xF27A, 0x9A34}, //20118 #CJK UNIFIED IDEOGRAPH + {0xF27B, 0x9A35}, //20119 #CJK UNIFIED IDEOGRAPH + {0xF27C, 0x9A36}, //20120 #CJK UNIFIED IDEOGRAPH + {0xF27D, 0x9A37}, //20121 #CJK UNIFIED IDEOGRAPH + {0xF27E, 0x9A38}, //20122 #CJK UNIFIED IDEOGRAPH + {0xF280, 0x9A39}, //20123 #CJK UNIFIED IDEOGRAPH + {0xF281, 0x9A3A}, //20124 #CJK UNIFIED IDEOGRAPH + {0xF282, 0x9A3B}, //20125 #CJK UNIFIED IDEOGRAPH + {0xF283, 0x9A3C}, //20126 #CJK UNIFIED IDEOGRAPH + {0xF284, 0x9A3D}, //20127 #CJK UNIFIED IDEOGRAPH + {0xF285, 0x9A3E}, //20128 #CJK UNIFIED IDEOGRAPH + {0xF286, 0x9A3F}, //20129 #CJK UNIFIED IDEOGRAPH + {0xF287, 0x9A40}, //20130 #CJK UNIFIED IDEOGRAPH + {0xF288, 0x9A41}, //20131 #CJK UNIFIED IDEOGRAPH + {0xF289, 0x9A42}, //20132 #CJK UNIFIED IDEOGRAPH + {0xF28A, 0x9A43}, //20133 #CJK UNIFIED IDEOGRAPH + {0xF28B, 0x9A44}, //20134 #CJK UNIFIED IDEOGRAPH + {0xF28C, 0x9A45}, //20135 #CJK UNIFIED IDEOGRAPH + {0xF28D, 0x9A46}, //20136 #CJK UNIFIED IDEOGRAPH + {0xF28E, 0x9A47}, //20137 #CJK UNIFIED IDEOGRAPH + {0xF28F, 0x9A48}, //20138 #CJK UNIFIED IDEOGRAPH + {0xF290, 0x9A49}, //20139 #CJK UNIFIED IDEOGRAPH + {0xF291, 0x9A4A}, //20140 #CJK UNIFIED IDEOGRAPH + {0xF292, 0x9A4B}, //20141 #CJK UNIFIED IDEOGRAPH + {0xF293, 0x9A4C}, //20142 #CJK UNIFIED IDEOGRAPH + {0xF294, 0x9A4D}, //20143 #CJK UNIFIED IDEOGRAPH + {0xF295, 0x9A4E}, //20144 #CJK UNIFIED IDEOGRAPH + {0xF296, 0x9A4F}, //20145 #CJK UNIFIED IDEOGRAPH + {0xF297, 0x9A50}, //20146 #CJK UNIFIED IDEOGRAPH + {0xF298, 0x9A51}, //20147 #CJK UNIFIED IDEOGRAPH + {0xF299, 0x9A52}, //20148 #CJK UNIFIED IDEOGRAPH + {0xF29A, 0x9A53}, //20149 #CJK UNIFIED IDEOGRAPH + {0xF29B, 0x9A54}, //20150 #CJK UNIFIED IDEOGRAPH + {0xF29C, 0x9A55}, //20151 #CJK UNIFIED IDEOGRAPH + {0xF29D, 0x9A56}, //20152 #CJK UNIFIED IDEOGRAPH + {0xF29E, 0x9A57}, //20153 #CJK UNIFIED IDEOGRAPH + {0xF29F, 0x9A58}, //20154 #CJK UNIFIED IDEOGRAPH + {0xF2A0, 0x9A59}, //20155 #CJK UNIFIED IDEOGRAPH + {0xF2A1, 0x9889}, //20156 #CJK UNIFIED IDEOGRAPH + {0xF2A2, 0x988C}, //20157 #CJK UNIFIED IDEOGRAPH + {0xF2A3, 0x988D}, //20158 #CJK UNIFIED IDEOGRAPH + {0xF2A4, 0x988F}, //20159 #CJK UNIFIED IDEOGRAPH + {0xF2A5, 0x9894}, //20160 #CJK UNIFIED IDEOGRAPH + {0xF2A6, 0x989A}, //20161 #CJK UNIFIED IDEOGRAPH + {0xF2A7, 0x989B}, //20162 #CJK UNIFIED IDEOGRAPH + {0xF2A8, 0x989E}, //20163 #CJK UNIFIED IDEOGRAPH + {0xF2A9, 0x989F}, //20164 #CJK UNIFIED IDEOGRAPH + {0xF2AA, 0x98A1}, //20165 #CJK UNIFIED IDEOGRAPH + {0xF2AB, 0x98A2}, //20166 #CJK UNIFIED IDEOGRAPH + {0xF2AC, 0x98A5}, //20167 #CJK UNIFIED IDEOGRAPH + {0xF2AD, 0x98A6}, //20168 #CJK UNIFIED IDEOGRAPH + {0xF2AE, 0x864D}, //20169 #CJK UNIFIED IDEOGRAPH + {0xF2AF, 0x8654}, //20170 #CJK UNIFIED IDEOGRAPH + {0xF2B0, 0x866C}, //20171 #CJK UNIFIED IDEOGRAPH + {0xF2B1, 0x866E}, //20172 #CJK UNIFIED IDEOGRAPH + {0xF2B2, 0x867F}, //20173 #CJK UNIFIED IDEOGRAPH + {0xF2B3, 0x867A}, //20174 #CJK UNIFIED IDEOGRAPH + {0xF2B4, 0x867C}, //20175 #CJK UNIFIED IDEOGRAPH + {0xF2B5, 0x867B}, //20176 #CJK UNIFIED IDEOGRAPH + {0xF2B6, 0x86A8}, //20177 #CJK UNIFIED IDEOGRAPH + {0xF2B7, 0x868D}, //20178 #CJK UNIFIED IDEOGRAPH + {0xF2B8, 0x868B}, //20179 #CJK UNIFIED IDEOGRAPH + {0xF2B9, 0x86AC}, //20180 #CJK UNIFIED IDEOGRAPH + {0xF2BA, 0x869D}, //20181 #CJK UNIFIED IDEOGRAPH + {0xF2BB, 0x86A7}, //20182 #CJK UNIFIED IDEOGRAPH + {0xF2BC, 0x86A3}, //20183 #CJK UNIFIED IDEOGRAPH + {0xF2BD, 0x86AA}, //20184 #CJK UNIFIED IDEOGRAPH + {0xF2BE, 0x8693}, //20185 #CJK UNIFIED IDEOGRAPH + {0xF2BF, 0x86A9}, //20186 #CJK UNIFIED IDEOGRAPH + {0xF2C0, 0x86B6}, //20187 #CJK UNIFIED IDEOGRAPH + {0xF2C1, 0x86C4}, //20188 #CJK UNIFIED IDEOGRAPH + {0xF2C2, 0x86B5}, //20189 #CJK UNIFIED IDEOGRAPH + {0xF2C3, 0x86CE}, //20190 #CJK UNIFIED IDEOGRAPH + {0xF2C4, 0x86B0}, //20191 #CJK UNIFIED IDEOGRAPH + {0xF2C5, 0x86BA}, //20192 #CJK UNIFIED IDEOGRAPH + {0xF2C6, 0x86B1}, //20193 #CJK UNIFIED IDEOGRAPH + {0xF2C7, 0x86AF}, //20194 #CJK UNIFIED IDEOGRAPH + {0xF2C8, 0x86C9}, //20195 #CJK UNIFIED IDEOGRAPH + {0xF2C9, 0x86CF}, //20196 #CJK UNIFIED IDEOGRAPH + {0xF2CA, 0x86B4}, //20197 #CJK UNIFIED IDEOGRAPH + {0xF2CB, 0x86E9}, //20198 #CJK UNIFIED IDEOGRAPH + {0xF2CC, 0x86F1}, //20199 #CJK UNIFIED IDEOGRAPH + {0xF2CD, 0x86F2}, //20200 #CJK UNIFIED IDEOGRAPH + {0xF2CE, 0x86ED}, //20201 #CJK UNIFIED IDEOGRAPH + {0xF2CF, 0x86F3}, //20202 #CJK UNIFIED IDEOGRAPH + {0xF2D0, 0x86D0}, //20203 #CJK UNIFIED IDEOGRAPH + {0xF2D1, 0x8713}, //20204 #CJK UNIFIED IDEOGRAPH + {0xF2D2, 0x86DE}, //20205 #CJK UNIFIED IDEOGRAPH + {0xF2D3, 0x86F4}, //20206 #CJK UNIFIED IDEOGRAPH + {0xF2D4, 0x86DF}, //20207 #CJK UNIFIED IDEOGRAPH + {0xF2D5, 0x86D8}, //20208 #CJK UNIFIED IDEOGRAPH + {0xF2D6, 0x86D1}, //20209 #CJK UNIFIED IDEOGRAPH + {0xF2D7, 0x8703}, //20210 #CJK UNIFIED IDEOGRAPH + {0xF2D8, 0x8707}, //20211 #CJK UNIFIED IDEOGRAPH + {0xF2D9, 0x86F8}, //20212 #CJK UNIFIED IDEOGRAPH + {0xF2DA, 0x8708}, //20213 #CJK UNIFIED IDEOGRAPH + {0xF2DB, 0x870A}, //20214 #CJK UNIFIED IDEOGRAPH + {0xF2DC, 0x870D}, //20215 #CJK UNIFIED IDEOGRAPH + {0xF2DD, 0x8709}, //20216 #CJK UNIFIED IDEOGRAPH + {0xF2DE, 0x8723}, //20217 #CJK UNIFIED IDEOGRAPH + {0xF2DF, 0x873B}, //20218 #CJK UNIFIED IDEOGRAPH + {0xF2E0, 0x871E}, //20219 #CJK UNIFIED IDEOGRAPH + {0xF2E1, 0x8725}, //20220 #CJK UNIFIED IDEOGRAPH + {0xF2E2, 0x872E}, //20221 #CJK UNIFIED IDEOGRAPH + {0xF2E3, 0x871A}, //20222 #CJK UNIFIED IDEOGRAPH + {0xF2E4, 0x873E}, //20223 #CJK UNIFIED IDEOGRAPH + {0xF2E5, 0x8748}, //20224 #CJK UNIFIED IDEOGRAPH + {0xF2E6, 0x8734}, //20225 #CJK UNIFIED IDEOGRAPH + {0xF2E7, 0x8731}, //20226 #CJK UNIFIED IDEOGRAPH + {0xF2E8, 0x8729}, //20227 #CJK UNIFIED IDEOGRAPH + {0xF2E9, 0x8737}, //20228 #CJK UNIFIED IDEOGRAPH + {0xF2EA, 0x873F}, //20229 #CJK UNIFIED IDEOGRAPH + {0xF2EB, 0x8782}, //20230 #CJK UNIFIED IDEOGRAPH + {0xF2EC, 0x8722}, //20231 #CJK UNIFIED IDEOGRAPH + {0xF2ED, 0x877D}, //20232 #CJK UNIFIED IDEOGRAPH + {0xF2EE, 0x877E}, //20233 #CJK UNIFIED IDEOGRAPH + {0xF2EF, 0x877B}, //20234 #CJK UNIFIED IDEOGRAPH + {0xF2F0, 0x8760}, //20235 #CJK UNIFIED IDEOGRAPH + {0xF2F1, 0x8770}, //20236 #CJK UNIFIED IDEOGRAPH + {0xF2F2, 0x874C}, //20237 #CJK UNIFIED IDEOGRAPH + {0xF2F3, 0x876E}, //20238 #CJK UNIFIED IDEOGRAPH + {0xF2F4, 0x878B}, //20239 #CJK UNIFIED IDEOGRAPH + {0xF2F5, 0x8753}, //20240 #CJK UNIFIED IDEOGRAPH + {0xF2F6, 0x8763}, //20241 #CJK UNIFIED IDEOGRAPH + {0xF2F7, 0x877C}, //20242 #CJK UNIFIED IDEOGRAPH + {0xF2F8, 0x8764}, //20243 #CJK UNIFIED IDEOGRAPH + {0xF2F9, 0x8759}, //20244 #CJK UNIFIED IDEOGRAPH + {0xF2FA, 0x8765}, //20245 #CJK UNIFIED IDEOGRAPH + {0xF2FB, 0x8793}, //20246 #CJK UNIFIED IDEOGRAPH + {0xF2FC, 0x87AF}, //20247 #CJK UNIFIED IDEOGRAPH + {0xF2FD, 0x87A8}, //20248 #CJK UNIFIED IDEOGRAPH + {0xF2FE, 0x87D2}, //20249 #CJK UNIFIED IDEOGRAPH + {0xF340, 0x9A5A}, //20250 #CJK UNIFIED IDEOGRAPH + {0xF341, 0x9A5B}, //20251 #CJK UNIFIED IDEOGRAPH + {0xF342, 0x9A5C}, //20252 #CJK UNIFIED IDEOGRAPH + {0xF343, 0x9A5D}, //20253 #CJK UNIFIED IDEOGRAPH + {0xF344, 0x9A5E}, //20254 #CJK UNIFIED IDEOGRAPH + {0xF345, 0x9A5F}, //20255 #CJK UNIFIED IDEOGRAPH + {0xF346, 0x9A60}, //20256 #CJK UNIFIED IDEOGRAPH + {0xF347, 0x9A61}, //20257 #CJK UNIFIED IDEOGRAPH + {0xF348, 0x9A62}, //20258 #CJK UNIFIED IDEOGRAPH + {0xF349, 0x9A63}, //20259 #CJK UNIFIED IDEOGRAPH + {0xF34A, 0x9A64}, //20260 #CJK UNIFIED IDEOGRAPH + {0xF34B, 0x9A65}, //20261 #CJK UNIFIED IDEOGRAPH + {0xF34C, 0x9A66}, //20262 #CJK UNIFIED IDEOGRAPH + {0xF34D, 0x9A67}, //20263 #CJK UNIFIED IDEOGRAPH + {0xF34E, 0x9A68}, //20264 #CJK UNIFIED IDEOGRAPH + {0xF34F, 0x9A69}, //20265 #CJK UNIFIED IDEOGRAPH + {0xF350, 0x9A6A}, //20266 #CJK UNIFIED IDEOGRAPH + {0xF351, 0x9A6B}, //20267 #CJK UNIFIED IDEOGRAPH + {0xF352, 0x9A72}, //20268 #CJK UNIFIED IDEOGRAPH + {0xF353, 0x9A83}, //20269 #CJK UNIFIED IDEOGRAPH + {0xF354, 0x9A89}, //20270 #CJK UNIFIED IDEOGRAPH + {0xF355, 0x9A8D}, //20271 #CJK UNIFIED IDEOGRAPH + {0xF356, 0x9A8E}, //20272 #CJK UNIFIED IDEOGRAPH + {0xF357, 0x9A94}, //20273 #CJK UNIFIED IDEOGRAPH + {0xF358, 0x9A95}, //20274 #CJK UNIFIED IDEOGRAPH + {0xF359, 0x9A99}, //20275 #CJK UNIFIED IDEOGRAPH + {0xF35A, 0x9AA6}, //20276 #CJK UNIFIED IDEOGRAPH + {0xF35B, 0x9AA9}, //20277 #CJK UNIFIED IDEOGRAPH + {0xF35C, 0x9AAA}, //20278 #CJK UNIFIED IDEOGRAPH + {0xF35D, 0x9AAB}, //20279 #CJK UNIFIED IDEOGRAPH + {0xF35E, 0x9AAC}, //20280 #CJK UNIFIED IDEOGRAPH + {0xF35F, 0x9AAD}, //20281 #CJK UNIFIED IDEOGRAPH + {0xF360, 0x9AAE}, //20282 #CJK UNIFIED IDEOGRAPH + {0xF361, 0x9AAF}, //20283 #CJK UNIFIED IDEOGRAPH + {0xF362, 0x9AB2}, //20284 #CJK UNIFIED IDEOGRAPH + {0xF363, 0x9AB3}, //20285 #CJK UNIFIED IDEOGRAPH + {0xF364, 0x9AB4}, //20286 #CJK UNIFIED IDEOGRAPH + {0xF365, 0x9AB5}, //20287 #CJK UNIFIED IDEOGRAPH + {0xF366, 0x9AB9}, //20288 #CJK UNIFIED IDEOGRAPH + {0xF367, 0x9ABB}, //20289 #CJK UNIFIED IDEOGRAPH + {0xF368, 0x9ABD}, //20290 #CJK UNIFIED IDEOGRAPH + {0xF369, 0x9ABE}, //20291 #CJK UNIFIED IDEOGRAPH + {0xF36A, 0x9ABF}, //20292 #CJK UNIFIED IDEOGRAPH + {0xF36B, 0x9AC3}, //20293 #CJK UNIFIED IDEOGRAPH + {0xF36C, 0x9AC4}, //20294 #CJK UNIFIED IDEOGRAPH + {0xF36D, 0x9AC6}, //20295 #CJK UNIFIED IDEOGRAPH + {0xF36E, 0x9AC7}, //20296 #CJK UNIFIED IDEOGRAPH + {0xF36F, 0x9AC8}, //20297 #CJK UNIFIED IDEOGRAPH + {0xF370, 0x9AC9}, //20298 #CJK UNIFIED IDEOGRAPH + {0xF371, 0x9ACA}, //20299 #CJK UNIFIED IDEOGRAPH + {0xF372, 0x9ACD}, //20300 #CJK UNIFIED IDEOGRAPH + {0xF373, 0x9ACE}, //20301 #CJK UNIFIED IDEOGRAPH + {0xF374, 0x9ACF}, //20302 #CJK UNIFIED IDEOGRAPH + {0xF375, 0x9AD0}, //20303 #CJK UNIFIED IDEOGRAPH + {0xF376, 0x9AD2}, //20304 #CJK UNIFIED IDEOGRAPH + {0xF377, 0x9AD4}, //20305 #CJK UNIFIED IDEOGRAPH + {0xF378, 0x9AD5}, //20306 #CJK UNIFIED IDEOGRAPH + {0xF379, 0x9AD6}, //20307 #CJK UNIFIED IDEOGRAPH + {0xF37A, 0x9AD7}, //20308 #CJK UNIFIED IDEOGRAPH + {0xF37B, 0x9AD9}, //20309 #CJK UNIFIED IDEOGRAPH + {0xF37C, 0x9ADA}, //20310 #CJK UNIFIED IDEOGRAPH + {0xF37D, 0x9ADB}, //20311 #CJK UNIFIED IDEOGRAPH + {0xF37E, 0x9ADC}, //20312 #CJK UNIFIED IDEOGRAPH + {0xF380, 0x9ADD}, //20313 #CJK UNIFIED IDEOGRAPH + {0xF381, 0x9ADE}, //20314 #CJK UNIFIED IDEOGRAPH + {0xF382, 0x9AE0}, //20315 #CJK UNIFIED IDEOGRAPH + {0xF383, 0x9AE2}, //20316 #CJK UNIFIED IDEOGRAPH + {0xF384, 0x9AE3}, //20317 #CJK UNIFIED IDEOGRAPH + {0xF385, 0x9AE4}, //20318 #CJK UNIFIED IDEOGRAPH + {0xF386, 0x9AE5}, //20319 #CJK UNIFIED IDEOGRAPH + {0xF387, 0x9AE7}, //20320 #CJK UNIFIED IDEOGRAPH + {0xF388, 0x9AE8}, //20321 #CJK UNIFIED IDEOGRAPH + {0xF389, 0x9AE9}, //20322 #CJK UNIFIED IDEOGRAPH + {0xF38A, 0x9AEA}, //20323 #CJK UNIFIED IDEOGRAPH + {0xF38B, 0x9AEC}, //20324 #CJK UNIFIED IDEOGRAPH + {0xF38C, 0x9AEE}, //20325 #CJK UNIFIED IDEOGRAPH + {0xF38D, 0x9AF0}, //20326 #CJK UNIFIED IDEOGRAPH + {0xF38E, 0x9AF1}, //20327 #CJK UNIFIED IDEOGRAPH + {0xF38F, 0x9AF2}, //20328 #CJK UNIFIED IDEOGRAPH + {0xF390, 0x9AF3}, //20329 #CJK UNIFIED IDEOGRAPH + {0xF391, 0x9AF4}, //20330 #CJK UNIFIED IDEOGRAPH + {0xF392, 0x9AF5}, //20331 #CJK UNIFIED IDEOGRAPH + {0xF393, 0x9AF6}, //20332 #CJK UNIFIED IDEOGRAPH + {0xF394, 0x9AF7}, //20333 #CJK UNIFIED IDEOGRAPH + {0xF395, 0x9AF8}, //20334 #CJK UNIFIED IDEOGRAPH + {0xF396, 0x9AFA}, //20335 #CJK UNIFIED IDEOGRAPH + {0xF397, 0x9AFC}, //20336 #CJK UNIFIED IDEOGRAPH + {0xF398, 0x9AFD}, //20337 #CJK UNIFIED IDEOGRAPH + {0xF399, 0x9AFE}, //20338 #CJK UNIFIED IDEOGRAPH + {0xF39A, 0x9AFF}, //20339 #CJK UNIFIED IDEOGRAPH + {0xF39B, 0x9B00}, //20340 #CJK UNIFIED IDEOGRAPH + {0xF39C, 0x9B01}, //20341 #CJK UNIFIED IDEOGRAPH + {0xF39D, 0x9B02}, //20342 #CJK UNIFIED IDEOGRAPH + {0xF39E, 0x9B04}, //20343 #CJK UNIFIED IDEOGRAPH + {0xF39F, 0x9B05}, //20344 #CJK UNIFIED IDEOGRAPH + {0xF3A0, 0x9B06}, //20345 #CJK UNIFIED IDEOGRAPH + {0xF3A1, 0x87C6}, //20346 #CJK UNIFIED IDEOGRAPH + {0xF3A2, 0x8788}, //20347 #CJK UNIFIED IDEOGRAPH + {0xF3A3, 0x8785}, //20348 #CJK UNIFIED IDEOGRAPH + {0xF3A4, 0x87AD}, //20349 #CJK UNIFIED IDEOGRAPH + {0xF3A5, 0x8797}, //20350 #CJK UNIFIED IDEOGRAPH + {0xF3A6, 0x8783}, //20351 #CJK UNIFIED IDEOGRAPH + {0xF3A7, 0x87AB}, //20352 #CJK UNIFIED IDEOGRAPH + {0xF3A8, 0x87E5}, //20353 #CJK UNIFIED IDEOGRAPH + {0xF3A9, 0x87AC}, //20354 #CJK UNIFIED IDEOGRAPH + {0xF3AA, 0x87B5}, //20355 #CJK UNIFIED IDEOGRAPH + {0xF3AB, 0x87B3}, //20356 #CJK UNIFIED IDEOGRAPH + {0xF3AC, 0x87CB}, //20357 #CJK UNIFIED IDEOGRAPH + {0xF3AD, 0x87D3}, //20358 #CJK UNIFIED IDEOGRAPH + {0xF3AE, 0x87BD}, //20359 #CJK UNIFIED IDEOGRAPH + {0xF3AF, 0x87D1}, //20360 #CJK UNIFIED IDEOGRAPH + {0xF3B0, 0x87C0}, //20361 #CJK UNIFIED IDEOGRAPH + {0xF3B1, 0x87CA}, //20362 #CJK UNIFIED IDEOGRAPH + {0xF3B2, 0x87DB}, //20363 #CJK UNIFIED IDEOGRAPH + {0xF3B3, 0x87EA}, //20364 #CJK UNIFIED IDEOGRAPH + {0xF3B4, 0x87E0}, //20365 #CJK UNIFIED IDEOGRAPH + {0xF3B5, 0x87EE}, //20366 #CJK UNIFIED IDEOGRAPH + {0xF3B6, 0x8816}, //20367 #CJK UNIFIED IDEOGRAPH + {0xF3B7, 0x8813}, //20368 #CJK UNIFIED IDEOGRAPH + {0xF3B8, 0x87FE}, //20369 #CJK UNIFIED IDEOGRAPH + {0xF3B9, 0x880A}, //20370 #CJK UNIFIED IDEOGRAPH + {0xF3BA, 0x881B}, //20371 #CJK UNIFIED IDEOGRAPH + {0xF3BB, 0x8821}, //20372 #CJK UNIFIED IDEOGRAPH + {0xF3BC, 0x8839}, //20373 #CJK UNIFIED IDEOGRAPH + {0xF3BD, 0x883C}, //20374 #CJK UNIFIED IDEOGRAPH + {0xF3BE, 0x7F36}, //20375 #CJK UNIFIED IDEOGRAPH + {0xF3BF, 0x7F42}, //20376 #CJK UNIFIED IDEOGRAPH + {0xF3C0, 0x7F44}, //20377 #CJK UNIFIED IDEOGRAPH + {0xF3C1, 0x7F45}, //20378 #CJK UNIFIED IDEOGRAPH + {0xF3C2, 0x8210}, //20379 #CJK UNIFIED IDEOGRAPH + {0xF3C3, 0x7AFA}, //20380 #CJK UNIFIED IDEOGRAPH + {0xF3C4, 0x7AFD}, //20381 #CJK UNIFIED IDEOGRAPH + {0xF3C5, 0x7B08}, //20382 #CJK UNIFIED IDEOGRAPH + {0xF3C6, 0x7B03}, //20383 #CJK UNIFIED IDEOGRAPH + {0xF3C7, 0x7B04}, //20384 #CJK UNIFIED IDEOGRAPH + {0xF3C8, 0x7B15}, //20385 #CJK UNIFIED IDEOGRAPH + {0xF3C9, 0x7B0A}, //20386 #CJK UNIFIED IDEOGRAPH + {0xF3CA, 0x7B2B}, //20387 #CJK UNIFIED IDEOGRAPH + {0xF3CB, 0x7B0F}, //20388 #CJK UNIFIED IDEOGRAPH + {0xF3CC, 0x7B47}, //20389 #CJK UNIFIED IDEOGRAPH + {0xF3CD, 0x7B38}, //20390 #CJK UNIFIED IDEOGRAPH + {0xF3CE, 0x7B2A}, //20391 #CJK UNIFIED IDEOGRAPH + {0xF3CF, 0x7B19}, //20392 #CJK UNIFIED IDEOGRAPH + {0xF3D0, 0x7B2E}, //20393 #CJK UNIFIED IDEOGRAPH + {0xF3D1, 0x7B31}, //20394 #CJK UNIFIED IDEOGRAPH + {0xF3D2, 0x7B20}, //20395 #CJK UNIFIED IDEOGRAPH + {0xF3D3, 0x7B25}, //20396 #CJK UNIFIED IDEOGRAPH + {0xF3D4, 0x7B24}, //20397 #CJK UNIFIED IDEOGRAPH + {0xF3D5, 0x7B33}, //20398 #CJK UNIFIED IDEOGRAPH + {0xF3D6, 0x7B3E}, //20399 #CJK UNIFIED IDEOGRAPH + {0xF3D7, 0x7B1E}, //20400 #CJK UNIFIED IDEOGRAPH + {0xF3D8, 0x7B58}, //20401 #CJK UNIFIED IDEOGRAPH + {0xF3D9, 0x7B5A}, //20402 #CJK UNIFIED IDEOGRAPH + {0xF3DA, 0x7B45}, //20403 #CJK UNIFIED IDEOGRAPH + {0xF3DB, 0x7B75}, //20404 #CJK UNIFIED IDEOGRAPH + {0xF3DC, 0x7B4C}, //20405 #CJK UNIFIED IDEOGRAPH + {0xF3DD, 0x7B5D}, //20406 #CJK UNIFIED IDEOGRAPH + {0xF3DE, 0x7B60}, //20407 #CJK UNIFIED IDEOGRAPH + {0xF3DF, 0x7B6E}, //20408 #CJK UNIFIED IDEOGRAPH + {0xF3E0, 0x7B7B}, //20409 #CJK UNIFIED IDEOGRAPH + {0xF3E1, 0x7B62}, //20410 #CJK UNIFIED IDEOGRAPH + {0xF3E2, 0x7B72}, //20411 #CJK UNIFIED IDEOGRAPH + {0xF3E3, 0x7B71}, //20412 #CJK UNIFIED IDEOGRAPH + {0xF3E4, 0x7B90}, //20413 #CJK UNIFIED IDEOGRAPH + {0xF3E5, 0x7BA6}, //20414 #CJK UNIFIED IDEOGRAPH + {0xF3E6, 0x7BA7}, //20415 #CJK UNIFIED IDEOGRAPH + {0xF3E7, 0x7BB8}, //20416 #CJK UNIFIED IDEOGRAPH + {0xF3E8, 0x7BAC}, //20417 #CJK UNIFIED IDEOGRAPH + {0xF3E9, 0x7B9D}, //20418 #CJK UNIFIED IDEOGRAPH + {0xF3EA, 0x7BA8}, //20419 #CJK UNIFIED IDEOGRAPH + {0xF3EB, 0x7B85}, //20420 #CJK UNIFIED IDEOGRAPH + {0xF3EC, 0x7BAA}, //20421 #CJK UNIFIED IDEOGRAPH + {0xF3ED, 0x7B9C}, //20422 #CJK UNIFIED IDEOGRAPH + {0xF3EE, 0x7BA2}, //20423 #CJK UNIFIED IDEOGRAPH + {0xF3EF, 0x7BAB}, //20424 #CJK UNIFIED IDEOGRAPH + {0xF3F0, 0x7BB4}, //20425 #CJK UNIFIED IDEOGRAPH + {0xF3F1, 0x7BD1}, //20426 #CJK UNIFIED IDEOGRAPH + {0xF3F2, 0x7BC1}, //20427 #CJK UNIFIED IDEOGRAPH + {0xF3F3, 0x7BCC}, //20428 #CJK UNIFIED IDEOGRAPH + {0xF3F4, 0x7BDD}, //20429 #CJK UNIFIED IDEOGRAPH + {0xF3F5, 0x7BDA}, //20430 #CJK UNIFIED IDEOGRAPH + {0xF3F6, 0x7BE5}, //20431 #CJK UNIFIED IDEOGRAPH + {0xF3F7, 0x7BE6}, //20432 #CJK UNIFIED IDEOGRAPH + {0xF3F8, 0x7BEA}, //20433 #CJK UNIFIED IDEOGRAPH + {0xF3F9, 0x7C0C}, //20434 #CJK UNIFIED IDEOGRAPH + {0xF3FA, 0x7BFE}, //20435 #CJK UNIFIED IDEOGRAPH + {0xF3FB, 0x7BFC}, //20436 #CJK UNIFIED IDEOGRAPH + {0xF3FC, 0x7C0F}, //20437 #CJK UNIFIED IDEOGRAPH + {0xF3FD, 0x7C16}, //20438 #CJK UNIFIED IDEOGRAPH + {0xF3FE, 0x7C0B}, //20439 #CJK UNIFIED IDEOGRAPH + {0xF440, 0x9B07}, //20440 #CJK UNIFIED IDEOGRAPH + {0xF441, 0x9B09}, //20441 #CJK UNIFIED IDEOGRAPH + {0xF442, 0x9B0A}, //20442 #CJK UNIFIED IDEOGRAPH + {0xF443, 0x9B0B}, //20443 #CJK UNIFIED IDEOGRAPH + {0xF444, 0x9B0C}, //20444 #CJK UNIFIED IDEOGRAPH + {0xF445, 0x9B0D}, //20445 #CJK UNIFIED IDEOGRAPH + {0xF446, 0x9B0E}, //20446 #CJK UNIFIED IDEOGRAPH + {0xF447, 0x9B10}, //20447 #CJK UNIFIED IDEOGRAPH + {0xF448, 0x9B11}, //20448 #CJK UNIFIED IDEOGRAPH + {0xF449, 0x9B12}, //20449 #CJK UNIFIED IDEOGRAPH + {0xF44A, 0x9B14}, //20450 #CJK UNIFIED IDEOGRAPH + {0xF44B, 0x9B15}, //20451 #CJK UNIFIED IDEOGRAPH + {0xF44C, 0x9B16}, //20452 #CJK UNIFIED IDEOGRAPH + {0xF44D, 0x9B17}, //20453 #CJK UNIFIED IDEOGRAPH + {0xF44E, 0x9B18}, //20454 #CJK UNIFIED IDEOGRAPH + {0xF44F, 0x9B19}, //20455 #CJK UNIFIED IDEOGRAPH + {0xF450, 0x9B1A}, //20456 #CJK UNIFIED IDEOGRAPH + {0xF451, 0x9B1B}, //20457 #CJK UNIFIED IDEOGRAPH + {0xF452, 0x9B1C}, //20458 #CJK UNIFIED IDEOGRAPH + {0xF453, 0x9B1D}, //20459 #CJK UNIFIED IDEOGRAPH + {0xF454, 0x9B1E}, //20460 #CJK UNIFIED IDEOGRAPH + {0xF455, 0x9B20}, //20461 #CJK UNIFIED IDEOGRAPH + {0xF456, 0x9B21}, //20462 #CJK UNIFIED IDEOGRAPH + {0xF457, 0x9B22}, //20463 #CJK UNIFIED IDEOGRAPH + {0xF458, 0x9B24}, //20464 #CJK UNIFIED IDEOGRAPH + {0xF459, 0x9B25}, //20465 #CJK UNIFIED IDEOGRAPH + {0xF45A, 0x9B26}, //20466 #CJK UNIFIED IDEOGRAPH + {0xF45B, 0x9B27}, //20467 #CJK UNIFIED IDEOGRAPH + {0xF45C, 0x9B28}, //20468 #CJK UNIFIED IDEOGRAPH + {0xF45D, 0x9B29}, //20469 #CJK UNIFIED IDEOGRAPH + {0xF45E, 0x9B2A}, //20470 #CJK UNIFIED IDEOGRAPH + {0xF45F, 0x9B2B}, //20471 #CJK UNIFIED IDEOGRAPH + {0xF460, 0x9B2C}, //20472 #CJK UNIFIED IDEOGRAPH + {0xF461, 0x9B2D}, //20473 #CJK UNIFIED IDEOGRAPH + {0xF462, 0x9B2E}, //20474 #CJK UNIFIED IDEOGRAPH + {0xF463, 0x9B30}, //20475 #CJK UNIFIED IDEOGRAPH + {0xF464, 0x9B31}, //20476 #CJK UNIFIED IDEOGRAPH + {0xF465, 0x9B33}, //20477 #CJK UNIFIED IDEOGRAPH + {0xF466, 0x9B34}, //20478 #CJK UNIFIED IDEOGRAPH + {0xF467, 0x9B35}, //20479 #CJK UNIFIED IDEOGRAPH + {0xF468, 0x9B36}, //20480 #CJK UNIFIED IDEOGRAPH + {0xF469, 0x9B37}, //20481 #CJK UNIFIED IDEOGRAPH + {0xF46A, 0x9B38}, //20482 #CJK UNIFIED IDEOGRAPH + {0xF46B, 0x9B39}, //20483 #CJK UNIFIED IDEOGRAPH + {0xF46C, 0x9B3A}, //20484 #CJK UNIFIED IDEOGRAPH + {0xF46D, 0x9B3D}, //20485 #CJK UNIFIED IDEOGRAPH + {0xF46E, 0x9B3E}, //20486 #CJK UNIFIED IDEOGRAPH + {0xF46F, 0x9B3F}, //20487 #CJK UNIFIED IDEOGRAPH + {0xF470, 0x9B40}, //20488 #CJK UNIFIED IDEOGRAPH + {0xF471, 0x9B46}, //20489 #CJK UNIFIED IDEOGRAPH + {0xF472, 0x9B4A}, //20490 #CJK UNIFIED IDEOGRAPH + {0xF473, 0x9B4B}, //20491 #CJK UNIFIED IDEOGRAPH + {0xF474, 0x9B4C}, //20492 #CJK UNIFIED IDEOGRAPH + {0xF475, 0x9B4E}, //20493 #CJK UNIFIED IDEOGRAPH + {0xF476, 0x9B50}, //20494 #CJK UNIFIED IDEOGRAPH + {0xF477, 0x9B52}, //20495 #CJK UNIFIED IDEOGRAPH + {0xF478, 0x9B53}, //20496 #CJK UNIFIED IDEOGRAPH + {0xF479, 0x9B55}, //20497 #CJK UNIFIED IDEOGRAPH + {0xF47A, 0x9B56}, //20498 #CJK UNIFIED IDEOGRAPH + {0xF47B, 0x9B57}, //20499 #CJK UNIFIED IDEOGRAPH + {0xF47C, 0x9B58}, //20500 #CJK UNIFIED IDEOGRAPH + {0xF47D, 0x9B59}, //20501 #CJK UNIFIED IDEOGRAPH + {0xF47E, 0x9B5A}, //20502 #CJK UNIFIED IDEOGRAPH + {0xF480, 0x9B5B}, //20503 #CJK UNIFIED IDEOGRAPH + {0xF481, 0x9B5C}, //20504 #CJK UNIFIED IDEOGRAPH + {0xF482, 0x9B5D}, //20505 #CJK UNIFIED IDEOGRAPH + {0xF483, 0x9B5E}, //20506 #CJK UNIFIED IDEOGRAPH + {0xF484, 0x9B5F}, //20507 #CJK UNIFIED IDEOGRAPH + {0xF485, 0x9B60}, //20508 #CJK UNIFIED IDEOGRAPH + {0xF486, 0x9B61}, //20509 #CJK UNIFIED IDEOGRAPH + {0xF487, 0x9B62}, //20510 #CJK UNIFIED IDEOGRAPH + {0xF488, 0x9B63}, //20511 #CJK UNIFIED IDEOGRAPH + {0xF489, 0x9B64}, //20512 #CJK UNIFIED IDEOGRAPH + {0xF48A, 0x9B65}, //20513 #CJK UNIFIED IDEOGRAPH + {0xF48B, 0x9B66}, //20514 #CJK UNIFIED IDEOGRAPH + {0xF48C, 0x9B67}, //20515 #CJK UNIFIED IDEOGRAPH + {0xF48D, 0x9B68}, //20516 #CJK UNIFIED IDEOGRAPH + {0xF48E, 0x9B69}, //20517 #CJK UNIFIED IDEOGRAPH + {0xF48F, 0x9B6A}, //20518 #CJK UNIFIED IDEOGRAPH + {0xF490, 0x9B6B}, //20519 #CJK UNIFIED IDEOGRAPH + {0xF491, 0x9B6C}, //20520 #CJK UNIFIED IDEOGRAPH + {0xF492, 0x9B6D}, //20521 #CJK UNIFIED IDEOGRAPH + {0xF493, 0x9B6E}, //20522 #CJK UNIFIED IDEOGRAPH + {0xF494, 0x9B6F}, //20523 #CJK UNIFIED IDEOGRAPH + {0xF495, 0x9B70}, //20524 #CJK UNIFIED IDEOGRAPH + {0xF496, 0x9B71}, //20525 #CJK UNIFIED IDEOGRAPH + {0xF497, 0x9B72}, //20526 #CJK UNIFIED IDEOGRAPH + {0xF498, 0x9B73}, //20527 #CJK UNIFIED IDEOGRAPH + {0xF499, 0x9B74}, //20528 #CJK UNIFIED IDEOGRAPH + {0xF49A, 0x9B75}, //20529 #CJK UNIFIED IDEOGRAPH + {0xF49B, 0x9B76}, //20530 #CJK UNIFIED IDEOGRAPH + {0xF49C, 0x9B77}, //20531 #CJK UNIFIED IDEOGRAPH + {0xF49D, 0x9B78}, //20532 #CJK UNIFIED IDEOGRAPH + {0xF49E, 0x9B79}, //20533 #CJK UNIFIED IDEOGRAPH + {0xF49F, 0x9B7A}, //20534 #CJK UNIFIED IDEOGRAPH + {0xF4A0, 0x9B7B}, //20535 #CJK UNIFIED IDEOGRAPH + {0xF4A1, 0x7C1F}, //20536 #CJK UNIFIED IDEOGRAPH + {0xF4A2, 0x7C2A}, //20537 #CJK UNIFIED IDEOGRAPH + {0xF4A3, 0x7C26}, //20538 #CJK UNIFIED IDEOGRAPH + {0xF4A4, 0x7C38}, //20539 #CJK UNIFIED IDEOGRAPH + {0xF4A5, 0x7C41}, //20540 #CJK UNIFIED IDEOGRAPH + {0xF4A6, 0x7C40}, //20541 #CJK UNIFIED IDEOGRAPH + {0xF4A7, 0x81FE}, //20542 #CJK UNIFIED IDEOGRAPH + {0xF4A8, 0x8201}, //20543 #CJK UNIFIED IDEOGRAPH + {0xF4A9, 0x8202}, //20544 #CJK UNIFIED IDEOGRAPH + {0xF4AA, 0x8204}, //20545 #CJK UNIFIED IDEOGRAPH + {0xF4AB, 0x81EC}, //20546 #CJK UNIFIED IDEOGRAPH + {0xF4AC, 0x8844}, //20547 #CJK UNIFIED IDEOGRAPH + {0xF4AD, 0x8221}, //20548 #CJK UNIFIED IDEOGRAPH + {0xF4AE, 0x8222}, //20549 #CJK UNIFIED IDEOGRAPH + {0xF4AF, 0x8223}, //20550 #CJK UNIFIED IDEOGRAPH + {0xF4B0, 0x822D}, //20551 #CJK UNIFIED IDEOGRAPH + {0xF4B1, 0x822F}, //20552 #CJK UNIFIED IDEOGRAPH + {0xF4B2, 0x8228}, //20553 #CJK UNIFIED IDEOGRAPH + {0xF4B3, 0x822B}, //20554 #CJK UNIFIED IDEOGRAPH + {0xF4B4, 0x8238}, //20555 #CJK UNIFIED IDEOGRAPH + {0xF4B5, 0x823B}, //20556 #CJK UNIFIED IDEOGRAPH + {0xF4B6, 0x8233}, //20557 #CJK UNIFIED IDEOGRAPH + {0xF4B7, 0x8234}, //20558 #CJK UNIFIED IDEOGRAPH + {0xF4B8, 0x823E}, //20559 #CJK UNIFIED IDEOGRAPH + {0xF4B9, 0x8244}, //20560 #CJK UNIFIED IDEOGRAPH + {0xF4BA, 0x8249}, //20561 #CJK UNIFIED IDEOGRAPH + {0xF4BB, 0x824B}, //20562 #CJK UNIFIED IDEOGRAPH + {0xF4BC, 0x824F}, //20563 #CJK UNIFIED IDEOGRAPH + {0xF4BD, 0x825A}, //20564 #CJK UNIFIED IDEOGRAPH + {0xF4BE, 0x825F}, //20565 #CJK UNIFIED IDEOGRAPH + {0xF4BF, 0x8268}, //20566 #CJK UNIFIED IDEOGRAPH + {0xF4C0, 0x887E}, //20567 #CJK UNIFIED IDEOGRAPH + {0xF4C1, 0x8885}, //20568 #CJK UNIFIED IDEOGRAPH + {0xF4C2, 0x8888}, //20569 #CJK UNIFIED IDEOGRAPH + {0xF4C3, 0x88D8}, //20570 #CJK UNIFIED IDEOGRAPH + {0xF4C4, 0x88DF}, //20571 #CJK UNIFIED IDEOGRAPH + {0xF4C5, 0x895E}, //20572 #CJK UNIFIED IDEOGRAPH + {0xF4C6, 0x7F9D}, //20573 #CJK UNIFIED IDEOGRAPH + {0xF4C7, 0x7F9F}, //20574 #CJK UNIFIED IDEOGRAPH + {0xF4C8, 0x7FA7}, //20575 #CJK UNIFIED IDEOGRAPH + {0xF4C9, 0x7FAF}, //20576 #CJK UNIFIED IDEOGRAPH + {0xF4CA, 0x7FB0}, //20577 #CJK UNIFIED IDEOGRAPH + {0xF4CB, 0x7FB2}, //20578 #CJK UNIFIED IDEOGRAPH + {0xF4CC, 0x7C7C}, //20579 #CJK UNIFIED IDEOGRAPH + {0xF4CD, 0x6549}, //20580 #CJK UNIFIED IDEOGRAPH + {0xF4CE, 0x7C91}, //20581 #CJK UNIFIED IDEOGRAPH + {0xF4CF, 0x7C9D}, //20582 #CJK UNIFIED IDEOGRAPH + {0xF4D0, 0x7C9C}, //20583 #CJK UNIFIED IDEOGRAPH + {0xF4D1, 0x7C9E}, //20584 #CJK UNIFIED IDEOGRAPH + {0xF4D2, 0x7CA2}, //20585 #CJK UNIFIED IDEOGRAPH + {0xF4D3, 0x7CB2}, //20586 #CJK UNIFIED IDEOGRAPH + {0xF4D4, 0x7CBC}, //20587 #CJK UNIFIED IDEOGRAPH + {0xF4D5, 0x7CBD}, //20588 #CJK UNIFIED IDEOGRAPH + {0xF4D6, 0x7CC1}, //20589 #CJK UNIFIED IDEOGRAPH + {0xF4D7, 0x7CC7}, //20590 #CJK UNIFIED IDEOGRAPH + {0xF4D8, 0x7CCC}, //20591 #CJK UNIFIED IDEOGRAPH + {0xF4D9, 0x7CCD}, //20592 #CJK UNIFIED IDEOGRAPH + {0xF4DA, 0x7CC8}, //20593 #CJK UNIFIED IDEOGRAPH + {0xF4DB, 0x7CC5}, //20594 #CJK UNIFIED IDEOGRAPH + {0xF4DC, 0x7CD7}, //20595 #CJK UNIFIED IDEOGRAPH + {0xF4DD, 0x7CE8}, //20596 #CJK UNIFIED IDEOGRAPH + {0xF4DE, 0x826E}, //20597 #CJK UNIFIED IDEOGRAPH + {0xF4DF, 0x66A8}, //20598 #CJK UNIFIED IDEOGRAPH + {0xF4E0, 0x7FBF}, //20599 #CJK UNIFIED IDEOGRAPH + {0xF4E1, 0x7FCE}, //20600 #CJK UNIFIED IDEOGRAPH + {0xF4E2, 0x7FD5}, //20601 #CJK UNIFIED IDEOGRAPH + {0xF4E3, 0x7FE5}, //20602 #CJK UNIFIED IDEOGRAPH + {0xF4E4, 0x7FE1}, //20603 #CJK UNIFIED IDEOGRAPH + {0xF4E5, 0x7FE6}, //20604 #CJK UNIFIED IDEOGRAPH + {0xF4E6, 0x7FE9}, //20605 #CJK UNIFIED IDEOGRAPH + {0xF4E7, 0x7FEE}, //20606 #CJK UNIFIED IDEOGRAPH + {0xF4E8, 0x7FF3}, //20607 #CJK UNIFIED IDEOGRAPH + {0xF4E9, 0x7CF8}, //20608 #CJK UNIFIED IDEOGRAPH + {0xF4EA, 0x7D77}, //20609 #CJK UNIFIED IDEOGRAPH + {0xF4EB, 0x7DA6}, //20610 #CJK UNIFIED IDEOGRAPH + {0xF4EC, 0x7DAE}, //20611 #CJK UNIFIED IDEOGRAPH + {0xF4ED, 0x7E47}, //20612 #CJK UNIFIED IDEOGRAPH + {0xF4EE, 0x7E9B}, //20613 #CJK UNIFIED IDEOGRAPH + {0xF4EF, 0x9EB8}, //20614 #CJK UNIFIED IDEOGRAPH + {0xF4F0, 0x9EB4}, //20615 #CJK UNIFIED IDEOGRAPH + {0xF4F1, 0x8D73}, //20616 #CJK UNIFIED IDEOGRAPH + {0xF4F2, 0x8D84}, //20617 #CJK UNIFIED IDEOGRAPH + {0xF4F3, 0x8D94}, //20618 #CJK UNIFIED IDEOGRAPH + {0xF4F4, 0x8D91}, //20619 #CJK UNIFIED IDEOGRAPH + {0xF4F5, 0x8DB1}, //20620 #CJK UNIFIED IDEOGRAPH + {0xF4F6, 0x8D67}, //20621 #CJK UNIFIED IDEOGRAPH + {0xF4F7, 0x8D6D}, //20622 #CJK UNIFIED IDEOGRAPH + {0xF4F8, 0x8C47}, //20623 #CJK UNIFIED IDEOGRAPH + {0xF4F9, 0x8C49}, //20624 #CJK UNIFIED IDEOGRAPH + {0xF4FA, 0x914A}, //20625 #CJK UNIFIED IDEOGRAPH + {0xF4FB, 0x9150}, //20626 #CJK UNIFIED IDEOGRAPH + {0xF4FC, 0x914E}, //20627 #CJK UNIFIED IDEOGRAPH + {0xF4FD, 0x914F}, //20628 #CJK UNIFIED IDEOGRAPH + {0xF4FE, 0x9164}, //20629 #CJK UNIFIED IDEOGRAPH + {0xF540, 0x9B7C}, //20630 #CJK UNIFIED IDEOGRAPH + {0xF541, 0x9B7D}, //20631 #CJK UNIFIED IDEOGRAPH + {0xF542, 0x9B7E}, //20632 #CJK UNIFIED IDEOGRAPH + {0xF543, 0x9B7F}, //20633 #CJK UNIFIED IDEOGRAPH + {0xF544, 0x9B80}, //20634 #CJK UNIFIED IDEOGRAPH + {0xF545, 0x9B81}, //20635 #CJK UNIFIED IDEOGRAPH + {0xF546, 0x9B82}, //20636 #CJK UNIFIED IDEOGRAPH + {0xF547, 0x9B83}, //20637 #CJK UNIFIED IDEOGRAPH + {0xF548, 0x9B84}, //20638 #CJK UNIFIED IDEOGRAPH + {0xF549, 0x9B85}, //20639 #CJK UNIFIED IDEOGRAPH + {0xF54A, 0x9B86}, //20640 #CJK UNIFIED IDEOGRAPH + {0xF54B, 0x9B87}, //20641 #CJK UNIFIED IDEOGRAPH + {0xF54C, 0x9B88}, //20642 #CJK UNIFIED IDEOGRAPH + {0xF54D, 0x9B89}, //20643 #CJK UNIFIED IDEOGRAPH + {0xF54E, 0x9B8A}, //20644 #CJK UNIFIED IDEOGRAPH + {0xF54F, 0x9B8B}, //20645 #CJK UNIFIED IDEOGRAPH + {0xF550, 0x9B8C}, //20646 #CJK UNIFIED IDEOGRAPH + {0xF551, 0x9B8D}, //20647 #CJK UNIFIED IDEOGRAPH + {0xF552, 0x9B8E}, //20648 #CJK UNIFIED IDEOGRAPH + {0xF553, 0x9B8F}, //20649 #CJK UNIFIED IDEOGRAPH + {0xF554, 0x9B90}, //20650 #CJK UNIFIED IDEOGRAPH + {0xF555, 0x9B91}, //20651 #CJK UNIFIED IDEOGRAPH + {0xF556, 0x9B92}, //20652 #CJK UNIFIED IDEOGRAPH + {0xF557, 0x9B93}, //20653 #CJK UNIFIED IDEOGRAPH + {0xF558, 0x9B94}, //20654 #CJK UNIFIED IDEOGRAPH + {0xF559, 0x9B95}, //20655 #CJK UNIFIED IDEOGRAPH + {0xF55A, 0x9B96}, //20656 #CJK UNIFIED IDEOGRAPH + {0xF55B, 0x9B97}, //20657 #CJK UNIFIED IDEOGRAPH + {0xF55C, 0x9B98}, //20658 #CJK UNIFIED IDEOGRAPH + {0xF55D, 0x9B99}, //20659 #CJK UNIFIED IDEOGRAPH + {0xF55E, 0x9B9A}, //20660 #CJK UNIFIED IDEOGRAPH + {0xF55F, 0x9B9B}, //20661 #CJK UNIFIED IDEOGRAPH + {0xF560, 0x9B9C}, //20662 #CJK UNIFIED IDEOGRAPH + {0xF561, 0x9B9D}, //20663 #CJK UNIFIED IDEOGRAPH + {0xF562, 0x9B9E}, //20664 #CJK UNIFIED IDEOGRAPH + {0xF563, 0x9B9F}, //20665 #CJK UNIFIED IDEOGRAPH + {0xF564, 0x9BA0}, //20666 #CJK UNIFIED IDEOGRAPH + {0xF565, 0x9BA1}, //20667 #CJK UNIFIED IDEOGRAPH + {0xF566, 0x9BA2}, //20668 #CJK UNIFIED IDEOGRAPH + {0xF567, 0x9BA3}, //20669 #CJK UNIFIED IDEOGRAPH + {0xF568, 0x9BA4}, //20670 #CJK UNIFIED IDEOGRAPH + {0xF569, 0x9BA5}, //20671 #CJK UNIFIED IDEOGRAPH + {0xF56A, 0x9BA6}, //20672 #CJK UNIFIED IDEOGRAPH + {0xF56B, 0x9BA7}, //20673 #CJK UNIFIED IDEOGRAPH + {0xF56C, 0x9BA8}, //20674 #CJK UNIFIED IDEOGRAPH + {0xF56D, 0x9BA9}, //20675 #CJK UNIFIED IDEOGRAPH + {0xF56E, 0x9BAA}, //20676 #CJK UNIFIED IDEOGRAPH + {0xF56F, 0x9BAB}, //20677 #CJK UNIFIED IDEOGRAPH + {0xF570, 0x9BAC}, //20678 #CJK UNIFIED IDEOGRAPH + {0xF571, 0x9BAD}, //20679 #CJK UNIFIED IDEOGRAPH + {0xF572, 0x9BAE}, //20680 #CJK UNIFIED IDEOGRAPH + {0xF573, 0x9BAF}, //20681 #CJK UNIFIED IDEOGRAPH + {0xF574, 0x9BB0}, //20682 #CJK UNIFIED IDEOGRAPH + {0xF575, 0x9BB1}, //20683 #CJK UNIFIED IDEOGRAPH + {0xF576, 0x9BB2}, //20684 #CJK UNIFIED IDEOGRAPH + {0xF577, 0x9BB3}, //20685 #CJK UNIFIED IDEOGRAPH + {0xF578, 0x9BB4}, //20686 #CJK UNIFIED IDEOGRAPH + {0xF579, 0x9BB5}, //20687 #CJK UNIFIED IDEOGRAPH + {0xF57A, 0x9BB6}, //20688 #CJK UNIFIED IDEOGRAPH + {0xF57B, 0x9BB7}, //20689 #CJK UNIFIED IDEOGRAPH + {0xF57C, 0x9BB8}, //20690 #CJK UNIFIED IDEOGRAPH + {0xF57D, 0x9BB9}, //20691 #CJK UNIFIED IDEOGRAPH + {0xF57E, 0x9BBA}, //20692 #CJK UNIFIED IDEOGRAPH + {0xF580, 0x9BBB}, //20693 #CJK UNIFIED IDEOGRAPH + {0xF581, 0x9BBC}, //20694 #CJK UNIFIED IDEOGRAPH + {0xF582, 0x9BBD}, //20695 #CJK UNIFIED IDEOGRAPH + {0xF583, 0x9BBE}, //20696 #CJK UNIFIED IDEOGRAPH + {0xF584, 0x9BBF}, //20697 #CJK UNIFIED IDEOGRAPH + {0xF585, 0x9BC0}, //20698 #CJK UNIFIED IDEOGRAPH + {0xF586, 0x9BC1}, //20699 #CJK UNIFIED IDEOGRAPH + {0xF587, 0x9BC2}, //20700 #CJK UNIFIED IDEOGRAPH + {0xF588, 0x9BC3}, //20701 #CJK UNIFIED IDEOGRAPH + {0xF589, 0x9BC4}, //20702 #CJK UNIFIED IDEOGRAPH + {0xF58A, 0x9BC5}, //20703 #CJK UNIFIED IDEOGRAPH + {0xF58B, 0x9BC6}, //20704 #CJK UNIFIED IDEOGRAPH + {0xF58C, 0x9BC7}, //20705 #CJK UNIFIED IDEOGRAPH + {0xF58D, 0x9BC8}, //20706 #CJK UNIFIED IDEOGRAPH + {0xF58E, 0x9BC9}, //20707 #CJK UNIFIED IDEOGRAPH + {0xF58F, 0x9BCA}, //20708 #CJK UNIFIED IDEOGRAPH + {0xF590, 0x9BCB}, //20709 #CJK UNIFIED IDEOGRAPH + {0xF591, 0x9BCC}, //20710 #CJK UNIFIED IDEOGRAPH + {0xF592, 0x9BCD}, //20711 #CJK UNIFIED IDEOGRAPH + {0xF593, 0x9BCE}, //20712 #CJK UNIFIED IDEOGRAPH + {0xF594, 0x9BCF}, //20713 #CJK UNIFIED IDEOGRAPH + {0xF595, 0x9BD0}, //20714 #CJK UNIFIED IDEOGRAPH + {0xF596, 0x9BD1}, //20715 #CJK UNIFIED IDEOGRAPH + {0xF597, 0x9BD2}, //20716 #CJK UNIFIED IDEOGRAPH + {0xF598, 0x9BD3}, //20717 #CJK UNIFIED IDEOGRAPH + {0xF599, 0x9BD4}, //20718 #CJK UNIFIED IDEOGRAPH + {0xF59A, 0x9BD5}, //20719 #CJK UNIFIED IDEOGRAPH + {0xF59B, 0x9BD6}, //20720 #CJK UNIFIED IDEOGRAPH + {0xF59C, 0x9BD7}, //20721 #CJK UNIFIED IDEOGRAPH + {0xF59D, 0x9BD8}, //20722 #CJK UNIFIED IDEOGRAPH + {0xF59E, 0x9BD9}, //20723 #CJK UNIFIED IDEOGRAPH + {0xF59F, 0x9BDA}, //20724 #CJK UNIFIED IDEOGRAPH + {0xF5A0, 0x9BDB}, //20725 #CJK UNIFIED IDEOGRAPH + {0xF5A1, 0x9162}, //20726 #CJK UNIFIED IDEOGRAPH + {0xF5A2, 0x9161}, //20727 #CJK UNIFIED IDEOGRAPH + {0xF5A3, 0x9170}, //20728 #CJK UNIFIED IDEOGRAPH + {0xF5A4, 0x9169}, //20729 #CJK UNIFIED IDEOGRAPH + {0xF5A5, 0x916F}, //20730 #CJK UNIFIED IDEOGRAPH + {0xF5A6, 0x917D}, //20731 #CJK UNIFIED IDEOGRAPH + {0xF5A7, 0x917E}, //20732 #CJK UNIFIED IDEOGRAPH + {0xF5A8, 0x9172}, //20733 #CJK UNIFIED IDEOGRAPH + {0xF5A9, 0x9174}, //20734 #CJK UNIFIED IDEOGRAPH + {0xF5AA, 0x9179}, //20735 #CJK UNIFIED IDEOGRAPH + {0xF5AB, 0x918C}, //20736 #CJK UNIFIED IDEOGRAPH + {0xF5AC, 0x9185}, //20737 #CJK UNIFIED IDEOGRAPH + {0xF5AD, 0x9190}, //20738 #CJK UNIFIED IDEOGRAPH + {0xF5AE, 0x918D}, //20739 #CJK UNIFIED IDEOGRAPH + {0xF5AF, 0x9191}, //20740 #CJK UNIFIED IDEOGRAPH + {0xF5B0, 0x91A2}, //20741 #CJK UNIFIED IDEOGRAPH + {0xF5B1, 0x91A3}, //20742 #CJK UNIFIED IDEOGRAPH + {0xF5B2, 0x91AA}, //20743 #CJK UNIFIED IDEOGRAPH + {0xF5B3, 0x91AD}, //20744 #CJK UNIFIED IDEOGRAPH + {0xF5B4, 0x91AE}, //20745 #CJK UNIFIED IDEOGRAPH + {0xF5B5, 0x91AF}, //20746 #CJK UNIFIED IDEOGRAPH + {0xF5B6, 0x91B5}, //20747 #CJK UNIFIED IDEOGRAPH + {0xF5B7, 0x91B4}, //20748 #CJK UNIFIED IDEOGRAPH + {0xF5B8, 0x91BA}, //20749 #CJK UNIFIED IDEOGRAPH + {0xF5B9, 0x8C55}, //20750 #CJK UNIFIED IDEOGRAPH + {0xF5BA, 0x9E7E}, //20751 #CJK UNIFIED IDEOGRAPH + {0xF5BB, 0x8DB8}, //20752 #CJK UNIFIED IDEOGRAPH + {0xF5BC, 0x8DEB}, //20753 #CJK UNIFIED IDEOGRAPH + {0xF5BD, 0x8E05}, //20754 #CJK UNIFIED IDEOGRAPH + {0xF5BE, 0x8E59}, //20755 #CJK UNIFIED IDEOGRAPH + {0xF5BF, 0x8E69}, //20756 #CJK UNIFIED IDEOGRAPH + {0xF5C0, 0x8DB5}, //20757 #CJK UNIFIED IDEOGRAPH + {0xF5C1, 0x8DBF}, //20758 #CJK UNIFIED IDEOGRAPH + {0xF5C2, 0x8DBC}, //20759 #CJK UNIFIED IDEOGRAPH + {0xF5C3, 0x8DBA}, //20760 #CJK UNIFIED IDEOGRAPH + {0xF5C4, 0x8DC4}, //20761 #CJK UNIFIED IDEOGRAPH + {0xF5C5, 0x8DD6}, //20762 #CJK UNIFIED IDEOGRAPH + {0xF5C6, 0x8DD7}, //20763 #CJK UNIFIED IDEOGRAPH + {0xF5C7, 0x8DDA}, //20764 #CJK UNIFIED IDEOGRAPH + {0xF5C8, 0x8DDE}, //20765 #CJK UNIFIED IDEOGRAPH + {0xF5C9, 0x8DCE}, //20766 #CJK UNIFIED IDEOGRAPH + {0xF5CA, 0x8DCF}, //20767 #CJK UNIFIED IDEOGRAPH + {0xF5CB, 0x8DDB}, //20768 #CJK UNIFIED IDEOGRAPH + {0xF5CC, 0x8DC6}, //20769 #CJK UNIFIED IDEOGRAPH + {0xF5CD, 0x8DEC}, //20770 #CJK UNIFIED IDEOGRAPH + {0xF5CE, 0x8DF7}, //20771 #CJK UNIFIED IDEOGRAPH + {0xF5CF, 0x8DF8}, //20772 #CJK UNIFIED IDEOGRAPH + {0xF5D0, 0x8DE3}, //20773 #CJK UNIFIED IDEOGRAPH + {0xF5D1, 0x8DF9}, //20774 #CJK UNIFIED IDEOGRAPH + {0xF5D2, 0x8DFB}, //20775 #CJK UNIFIED IDEOGRAPH + {0xF5D3, 0x8DE4}, //20776 #CJK UNIFIED IDEOGRAPH + {0xF5D4, 0x8E09}, //20777 #CJK UNIFIED IDEOGRAPH + {0xF5D5, 0x8DFD}, //20778 #CJK UNIFIED IDEOGRAPH + {0xF5D6, 0x8E14}, //20779 #CJK UNIFIED IDEOGRAPH + {0xF5D7, 0x8E1D}, //20780 #CJK UNIFIED IDEOGRAPH + {0xF5D8, 0x8E1F}, //20781 #CJK UNIFIED IDEOGRAPH + {0xF5D9, 0x8E2C}, //20782 #CJK UNIFIED IDEOGRAPH + {0xF5DA, 0x8E2E}, //20783 #CJK UNIFIED IDEOGRAPH + {0xF5DB, 0x8E23}, //20784 #CJK UNIFIED IDEOGRAPH + {0xF5DC, 0x8E2F}, //20785 #CJK UNIFIED IDEOGRAPH + {0xF5DD, 0x8E3A}, //20786 #CJK UNIFIED IDEOGRAPH + {0xF5DE, 0x8E40}, //20787 #CJK UNIFIED IDEOGRAPH + {0xF5DF, 0x8E39}, //20788 #CJK UNIFIED IDEOGRAPH + {0xF5E0, 0x8E35}, //20789 #CJK UNIFIED IDEOGRAPH + {0xF5E1, 0x8E3D}, //20790 #CJK UNIFIED IDEOGRAPH + {0xF5E2, 0x8E31}, //20791 #CJK UNIFIED IDEOGRAPH + {0xF5E3, 0x8E49}, //20792 #CJK UNIFIED IDEOGRAPH + {0xF5E4, 0x8E41}, //20793 #CJK UNIFIED IDEOGRAPH + {0xF5E5, 0x8E42}, //20794 #CJK UNIFIED IDEOGRAPH + {0xF5E6, 0x8E51}, //20795 #CJK UNIFIED IDEOGRAPH + {0xF5E7, 0x8E52}, //20796 #CJK UNIFIED IDEOGRAPH + {0xF5E8, 0x8E4A}, //20797 #CJK UNIFIED IDEOGRAPH + {0xF5E9, 0x8E70}, //20798 #CJK UNIFIED IDEOGRAPH + {0xF5EA, 0x8E76}, //20799 #CJK UNIFIED IDEOGRAPH + {0xF5EB, 0x8E7C}, //20800 #CJK UNIFIED IDEOGRAPH + {0xF5EC, 0x8E6F}, //20801 #CJK UNIFIED IDEOGRAPH + {0xF5ED, 0x8E74}, //20802 #CJK UNIFIED IDEOGRAPH + {0xF5EE, 0x8E85}, //20803 #CJK UNIFIED IDEOGRAPH + {0xF5EF, 0x8E8F}, //20804 #CJK UNIFIED IDEOGRAPH + {0xF5F0, 0x8E94}, //20805 #CJK UNIFIED IDEOGRAPH + {0xF5F1, 0x8E90}, //20806 #CJK UNIFIED IDEOGRAPH + {0xF5F2, 0x8E9C}, //20807 #CJK UNIFIED IDEOGRAPH + {0xF5F3, 0x8E9E}, //20808 #CJK UNIFIED IDEOGRAPH + {0xF5F4, 0x8C78}, //20809 #CJK UNIFIED IDEOGRAPH + {0xF5F5, 0x8C82}, //20810 #CJK UNIFIED IDEOGRAPH + {0xF5F6, 0x8C8A}, //20811 #CJK UNIFIED IDEOGRAPH + {0xF5F7, 0x8C85}, //20812 #CJK UNIFIED IDEOGRAPH + {0xF5F8, 0x8C98}, //20813 #CJK UNIFIED IDEOGRAPH + {0xF5F9, 0x8C94}, //20814 #CJK UNIFIED IDEOGRAPH + {0xF5FA, 0x659B}, //20815 #CJK UNIFIED IDEOGRAPH + {0xF5FB, 0x89D6}, //20816 #CJK UNIFIED IDEOGRAPH + {0xF5FC, 0x89DE}, //20817 #CJK UNIFIED IDEOGRAPH + {0xF5FD, 0x89DA}, //20818 #CJK UNIFIED IDEOGRAPH + {0xF5FE, 0x89DC}, //20819 #CJK UNIFIED IDEOGRAPH + {0xF640, 0x9BDC}, //20820 #CJK UNIFIED IDEOGRAPH + {0xF641, 0x9BDD}, //20821 #CJK UNIFIED IDEOGRAPH + {0xF642, 0x9BDE}, //20822 #CJK UNIFIED IDEOGRAPH + {0xF643, 0x9BDF}, //20823 #CJK UNIFIED IDEOGRAPH + {0xF644, 0x9BE0}, //20824 #CJK UNIFIED IDEOGRAPH + {0xF645, 0x9BE1}, //20825 #CJK UNIFIED IDEOGRAPH + {0xF646, 0x9BE2}, //20826 #CJK UNIFIED IDEOGRAPH + {0xF647, 0x9BE3}, //20827 #CJK UNIFIED IDEOGRAPH + {0xF648, 0x9BE4}, //20828 #CJK UNIFIED IDEOGRAPH + {0xF649, 0x9BE5}, //20829 #CJK UNIFIED IDEOGRAPH + {0xF64A, 0x9BE6}, //20830 #CJK UNIFIED IDEOGRAPH + {0xF64B, 0x9BE7}, //20831 #CJK UNIFIED IDEOGRAPH + {0xF64C, 0x9BE8}, //20832 #CJK UNIFIED IDEOGRAPH + {0xF64D, 0x9BE9}, //20833 #CJK UNIFIED IDEOGRAPH + {0xF64E, 0x9BEA}, //20834 #CJK UNIFIED IDEOGRAPH + {0xF64F, 0x9BEB}, //20835 #CJK UNIFIED IDEOGRAPH + {0xF650, 0x9BEC}, //20836 #CJK UNIFIED IDEOGRAPH + {0xF651, 0x9BED}, //20837 #CJK UNIFIED IDEOGRAPH + {0xF652, 0x9BEE}, //20838 #CJK UNIFIED IDEOGRAPH + {0xF653, 0x9BEF}, //20839 #CJK UNIFIED IDEOGRAPH + {0xF654, 0x9BF0}, //20840 #CJK UNIFIED IDEOGRAPH + {0xF655, 0x9BF1}, //20841 #CJK UNIFIED IDEOGRAPH + {0xF656, 0x9BF2}, //20842 #CJK UNIFIED IDEOGRAPH + {0xF657, 0x9BF3}, //20843 #CJK UNIFIED IDEOGRAPH + {0xF658, 0x9BF4}, //20844 #CJK UNIFIED IDEOGRAPH + {0xF659, 0x9BF5}, //20845 #CJK UNIFIED IDEOGRAPH + {0xF65A, 0x9BF6}, //20846 #CJK UNIFIED IDEOGRAPH + {0xF65B, 0x9BF7}, //20847 #CJK UNIFIED IDEOGRAPH + {0xF65C, 0x9BF8}, //20848 #CJK UNIFIED IDEOGRAPH + {0xF65D, 0x9BF9}, //20849 #CJK UNIFIED IDEOGRAPH + {0xF65E, 0x9BFA}, //20850 #CJK UNIFIED IDEOGRAPH + {0xF65F, 0x9BFB}, //20851 #CJK UNIFIED IDEOGRAPH + {0xF660, 0x9BFC}, //20852 #CJK UNIFIED IDEOGRAPH + {0xF661, 0x9BFD}, //20853 #CJK UNIFIED IDEOGRAPH + {0xF662, 0x9BFE}, //20854 #CJK UNIFIED IDEOGRAPH + {0xF663, 0x9BFF}, //20855 #CJK UNIFIED IDEOGRAPH + {0xF664, 0x9C00}, //20856 #CJK UNIFIED IDEOGRAPH + {0xF665, 0x9C01}, //20857 #CJK UNIFIED IDEOGRAPH + {0xF666, 0x9C02}, //20858 #CJK UNIFIED IDEOGRAPH + {0xF667, 0x9C03}, //20859 #CJK UNIFIED IDEOGRAPH + {0xF668, 0x9C04}, //20860 #CJK UNIFIED IDEOGRAPH + {0xF669, 0x9C05}, //20861 #CJK UNIFIED IDEOGRAPH + {0xF66A, 0x9C06}, //20862 #CJK UNIFIED IDEOGRAPH + {0xF66B, 0x9C07}, //20863 #CJK UNIFIED IDEOGRAPH + {0xF66C, 0x9C08}, //20864 #CJK UNIFIED IDEOGRAPH + {0xF66D, 0x9C09}, //20865 #CJK UNIFIED IDEOGRAPH + {0xF66E, 0x9C0A}, //20866 #CJK UNIFIED IDEOGRAPH + {0xF66F, 0x9C0B}, //20867 #CJK UNIFIED IDEOGRAPH + {0xF670, 0x9C0C}, //20868 #CJK UNIFIED IDEOGRAPH + {0xF671, 0x9C0D}, //20869 #CJK UNIFIED IDEOGRAPH + {0xF672, 0x9C0E}, //20870 #CJK UNIFIED IDEOGRAPH + {0xF673, 0x9C0F}, //20871 #CJK UNIFIED IDEOGRAPH + {0xF674, 0x9C10}, //20872 #CJK UNIFIED IDEOGRAPH + {0xF675, 0x9C11}, //20873 #CJK UNIFIED IDEOGRAPH + {0xF676, 0x9C12}, //20874 #CJK UNIFIED IDEOGRAPH + {0xF677, 0x9C13}, //20875 #CJK UNIFIED IDEOGRAPH + {0xF678, 0x9C14}, //20876 #CJK UNIFIED IDEOGRAPH + {0xF679, 0x9C15}, //20877 #CJK UNIFIED IDEOGRAPH + {0xF67A, 0x9C16}, //20878 #CJK UNIFIED IDEOGRAPH + {0xF67B, 0x9C17}, //20879 #CJK UNIFIED IDEOGRAPH + {0xF67C, 0x9C18}, //20880 #CJK UNIFIED IDEOGRAPH + {0xF67D, 0x9C19}, //20881 #CJK UNIFIED IDEOGRAPH + {0xF67E, 0x9C1A}, //20882 #CJK UNIFIED IDEOGRAPH + {0xF680, 0x9C1B}, //20883 #CJK UNIFIED IDEOGRAPH + {0xF681, 0x9C1C}, //20884 #CJK UNIFIED IDEOGRAPH + {0xF682, 0x9C1D}, //20885 #CJK UNIFIED IDEOGRAPH + {0xF683, 0x9C1E}, //20886 #CJK UNIFIED IDEOGRAPH + {0xF684, 0x9C1F}, //20887 #CJK UNIFIED IDEOGRAPH + {0xF685, 0x9C20}, //20888 #CJK UNIFIED IDEOGRAPH + {0xF686, 0x9C21}, //20889 #CJK UNIFIED IDEOGRAPH + {0xF687, 0x9C22}, //20890 #CJK UNIFIED IDEOGRAPH + {0xF688, 0x9C23}, //20891 #CJK UNIFIED IDEOGRAPH + {0xF689, 0x9C24}, //20892 #CJK UNIFIED IDEOGRAPH + {0xF68A, 0x9C25}, //20893 #CJK UNIFIED IDEOGRAPH + {0xF68B, 0x9C26}, //20894 #CJK UNIFIED IDEOGRAPH + {0xF68C, 0x9C27}, //20895 #CJK UNIFIED IDEOGRAPH + {0xF68D, 0x9C28}, //20896 #CJK UNIFIED IDEOGRAPH + {0xF68E, 0x9C29}, //20897 #CJK UNIFIED IDEOGRAPH + {0xF68F, 0x9C2A}, //20898 #CJK UNIFIED IDEOGRAPH + {0xF690, 0x9C2B}, //20899 #CJK UNIFIED IDEOGRAPH + {0xF691, 0x9C2C}, //20900 #CJK UNIFIED IDEOGRAPH + {0xF692, 0x9C2D}, //20901 #CJK UNIFIED IDEOGRAPH + {0xF693, 0x9C2E}, //20902 #CJK UNIFIED IDEOGRAPH + {0xF694, 0x9C2F}, //20903 #CJK UNIFIED IDEOGRAPH + {0xF695, 0x9C30}, //20904 #CJK UNIFIED IDEOGRAPH + {0xF696, 0x9C31}, //20905 #CJK UNIFIED IDEOGRAPH + {0xF697, 0x9C32}, //20906 #CJK UNIFIED IDEOGRAPH + {0xF698, 0x9C33}, //20907 #CJK UNIFIED IDEOGRAPH + {0xF699, 0x9C34}, //20908 #CJK UNIFIED IDEOGRAPH + {0xF69A, 0x9C35}, //20909 #CJK UNIFIED IDEOGRAPH + {0xF69B, 0x9C36}, //20910 #CJK UNIFIED IDEOGRAPH + {0xF69C, 0x9C37}, //20911 #CJK UNIFIED IDEOGRAPH + {0xF69D, 0x9C38}, //20912 #CJK UNIFIED IDEOGRAPH + {0xF69E, 0x9C39}, //20913 #CJK UNIFIED IDEOGRAPH + {0xF69F, 0x9C3A}, //20914 #CJK UNIFIED IDEOGRAPH + {0xF6A0, 0x9C3B}, //20915 #CJK UNIFIED IDEOGRAPH + {0xF6A1, 0x89E5}, //20916 #CJK UNIFIED IDEOGRAPH + {0xF6A2, 0x89EB}, //20917 #CJK UNIFIED IDEOGRAPH + {0xF6A3, 0x89EF}, //20918 #CJK UNIFIED IDEOGRAPH + {0xF6A4, 0x8A3E}, //20919 #CJK UNIFIED IDEOGRAPH + {0xF6A5, 0x8B26}, //20920 #CJK UNIFIED IDEOGRAPH + {0xF6A6, 0x9753}, //20921 #CJK UNIFIED IDEOGRAPH + {0xF6A7, 0x96E9}, //20922 #CJK UNIFIED IDEOGRAPH + {0xF6A8, 0x96F3}, //20923 #CJK UNIFIED IDEOGRAPH + {0xF6A9, 0x96EF}, //20924 #CJK UNIFIED IDEOGRAPH + {0xF6AA, 0x9706}, //20925 #CJK UNIFIED IDEOGRAPH + {0xF6AB, 0x9701}, //20926 #CJK UNIFIED IDEOGRAPH + {0xF6AC, 0x9708}, //20927 #CJK UNIFIED IDEOGRAPH + {0xF6AD, 0x970F}, //20928 #CJK UNIFIED IDEOGRAPH + {0xF6AE, 0x970E}, //20929 #CJK UNIFIED IDEOGRAPH + {0xF6AF, 0x972A}, //20930 #CJK UNIFIED IDEOGRAPH + {0xF6B0, 0x972D}, //20931 #CJK UNIFIED IDEOGRAPH + {0xF6B1, 0x9730}, //20932 #CJK UNIFIED IDEOGRAPH + {0xF6B2, 0x973E}, //20933 #CJK UNIFIED IDEOGRAPH + {0xF6B3, 0x9F80}, //20934 #CJK UNIFIED IDEOGRAPH + {0xF6B4, 0x9F83}, //20935 #CJK UNIFIED IDEOGRAPH + {0xF6B5, 0x9F85}, //20936 #CJK UNIFIED IDEOGRAPH + {0xF6B6, 0x9F86}, //20937 #CJK UNIFIED IDEOGRAPH + {0xF6B7, 0x9F87}, //20938 #CJK UNIFIED IDEOGRAPH + {0xF6B8, 0x9F88}, //20939 #CJK UNIFIED IDEOGRAPH + {0xF6B9, 0x9F89}, //20940 #CJK UNIFIED IDEOGRAPH + {0xF6BA, 0x9F8A}, //20941 #CJK UNIFIED IDEOGRAPH + {0xF6BB, 0x9F8C}, //20942 #CJK UNIFIED IDEOGRAPH + {0xF6BC, 0x9EFE}, //20943 #CJK UNIFIED IDEOGRAPH + {0xF6BD, 0x9F0B}, //20944 #CJK UNIFIED IDEOGRAPH + {0xF6BE, 0x9F0D}, //20945 #CJK UNIFIED IDEOGRAPH + {0xF6BF, 0x96B9}, //20946 #CJK UNIFIED IDEOGRAPH + {0xF6C0, 0x96BC}, //20947 #CJK UNIFIED IDEOGRAPH + {0xF6C1, 0x96BD}, //20948 #CJK UNIFIED IDEOGRAPH + {0xF6C2, 0x96CE}, //20949 #CJK UNIFIED IDEOGRAPH + {0xF6C3, 0x96D2}, //20950 #CJK UNIFIED IDEOGRAPH + {0xF6C4, 0x77BF}, //20951 #CJK UNIFIED IDEOGRAPH + {0xF6C5, 0x96E0}, //20952 #CJK UNIFIED IDEOGRAPH + {0xF6C6, 0x928E}, //20953 #CJK UNIFIED IDEOGRAPH + {0xF6C7, 0x92AE}, //20954 #CJK UNIFIED IDEOGRAPH + {0xF6C8, 0x92C8}, //20955 #CJK UNIFIED IDEOGRAPH + {0xF6C9, 0x933E}, //20956 #CJK UNIFIED IDEOGRAPH + {0xF6CA, 0x936A}, //20957 #CJK UNIFIED IDEOGRAPH + {0xF6CB, 0x93CA}, //20958 #CJK UNIFIED IDEOGRAPH + {0xF6CC, 0x938F}, //20959 #CJK UNIFIED IDEOGRAPH + {0xF6CD, 0x943E}, //20960 #CJK UNIFIED IDEOGRAPH + {0xF6CE, 0x946B}, //20961 #CJK UNIFIED IDEOGRAPH + {0xF6CF, 0x9C7F}, //20962 #CJK UNIFIED IDEOGRAPH + {0xF6D0, 0x9C82}, //20963 #CJK UNIFIED IDEOGRAPH + {0xF6D1, 0x9C85}, //20964 #CJK UNIFIED IDEOGRAPH + {0xF6D2, 0x9C86}, //20965 #CJK UNIFIED IDEOGRAPH + {0xF6D3, 0x9C87}, //20966 #CJK UNIFIED IDEOGRAPH + {0xF6D4, 0x9C88}, //20967 #CJK UNIFIED IDEOGRAPH + {0xF6D5, 0x7A23}, //20968 #CJK UNIFIED IDEOGRAPH + {0xF6D6, 0x9C8B}, //20969 #CJK UNIFIED IDEOGRAPH + {0xF6D7, 0x9C8E}, //20970 #CJK UNIFIED IDEOGRAPH + {0xF6D8, 0x9C90}, //20971 #CJK UNIFIED IDEOGRAPH + {0xF6D9, 0x9C91}, //20972 #CJK UNIFIED IDEOGRAPH + {0xF6DA, 0x9C92}, //20973 #CJK UNIFIED IDEOGRAPH + {0xF6DB, 0x9C94}, //20974 #CJK UNIFIED IDEOGRAPH + {0xF6DC, 0x9C95}, //20975 #CJK UNIFIED IDEOGRAPH + {0xF6DD, 0x9C9A}, //20976 #CJK UNIFIED IDEOGRAPH + {0xF6DE, 0x9C9B}, //20977 #CJK UNIFIED IDEOGRAPH + {0xF6DF, 0x9C9E}, //20978 #CJK UNIFIED IDEOGRAPH + {0xF6E0, 0x9C9F}, //20979 #CJK UNIFIED IDEOGRAPH + {0xF6E1, 0x9CA0}, //20980 #CJK UNIFIED IDEOGRAPH + {0xF6E2, 0x9CA1}, //20981 #CJK UNIFIED IDEOGRAPH + {0xF6E3, 0x9CA2}, //20982 #CJK UNIFIED IDEOGRAPH + {0xF6E4, 0x9CA3}, //20983 #CJK UNIFIED IDEOGRAPH + {0xF6E5, 0x9CA5}, //20984 #CJK UNIFIED IDEOGRAPH + {0xF6E6, 0x9CA6}, //20985 #CJK UNIFIED IDEOGRAPH + {0xF6E7, 0x9CA7}, //20986 #CJK UNIFIED IDEOGRAPH + {0xF6E8, 0x9CA8}, //20987 #CJK UNIFIED IDEOGRAPH + {0xF6E9, 0x9CA9}, //20988 #CJK UNIFIED IDEOGRAPH + {0xF6EA, 0x9CAB}, //20989 #CJK UNIFIED IDEOGRAPH + {0xF6EB, 0x9CAD}, //20990 #CJK UNIFIED IDEOGRAPH + {0xF6EC, 0x9CAE}, //20991 #CJK UNIFIED IDEOGRAPH + {0xF6ED, 0x9CB0}, //20992 #CJK UNIFIED IDEOGRAPH + {0xF6EE, 0x9CB1}, //20993 #CJK UNIFIED IDEOGRAPH + {0xF6EF, 0x9CB2}, //20994 #CJK UNIFIED IDEOGRAPH + {0xF6F0, 0x9CB3}, //20995 #CJK UNIFIED IDEOGRAPH + {0xF6F1, 0x9CB4}, //20996 #CJK UNIFIED IDEOGRAPH + {0xF6F2, 0x9CB5}, //20997 #CJK UNIFIED IDEOGRAPH + {0xF6F3, 0x9CB6}, //20998 #CJK UNIFIED IDEOGRAPH + {0xF6F4, 0x9CB7}, //20999 #CJK UNIFIED IDEOGRAPH + {0xF6F5, 0x9CBA}, //21000 #CJK UNIFIED IDEOGRAPH + {0xF6F6, 0x9CBB}, //21001 #CJK UNIFIED IDEOGRAPH + {0xF6F7, 0x9CBC}, //21002 #CJK UNIFIED IDEOGRAPH + {0xF6F8, 0x9CBD}, //21003 #CJK UNIFIED IDEOGRAPH + {0xF6F9, 0x9CC4}, //21004 #CJK UNIFIED IDEOGRAPH + {0xF6FA, 0x9CC5}, //21005 #CJK UNIFIED IDEOGRAPH + {0xF6FB, 0x9CC6}, //21006 #CJK UNIFIED IDEOGRAPH + {0xF6FC, 0x9CC7}, //21007 #CJK UNIFIED IDEOGRAPH + {0xF6FD, 0x9CCA}, //21008 #CJK UNIFIED IDEOGRAPH + {0xF6FE, 0x9CCB}, //21009 #CJK UNIFIED IDEOGRAPH + {0xF740, 0x9C3C}, //21010 #CJK UNIFIED IDEOGRAPH + {0xF741, 0x9C3D}, //21011 #CJK UNIFIED IDEOGRAPH + {0xF742, 0x9C3E}, //21012 #CJK UNIFIED IDEOGRAPH + {0xF743, 0x9C3F}, //21013 #CJK UNIFIED IDEOGRAPH + {0xF744, 0x9C40}, //21014 #CJK UNIFIED IDEOGRAPH + {0xF745, 0x9C41}, //21015 #CJK UNIFIED IDEOGRAPH + {0xF746, 0x9C42}, //21016 #CJK UNIFIED IDEOGRAPH + {0xF747, 0x9C43}, //21017 #CJK UNIFIED IDEOGRAPH + {0xF748, 0x9C44}, //21018 #CJK UNIFIED IDEOGRAPH + {0xF749, 0x9C45}, //21019 #CJK UNIFIED IDEOGRAPH + {0xF74A, 0x9C46}, //21020 #CJK UNIFIED IDEOGRAPH + {0xF74B, 0x9C47}, //21021 #CJK UNIFIED IDEOGRAPH + {0xF74C, 0x9C48}, //21022 #CJK UNIFIED IDEOGRAPH + {0xF74D, 0x9C49}, //21023 #CJK UNIFIED IDEOGRAPH + {0xF74E, 0x9C4A}, //21024 #CJK UNIFIED IDEOGRAPH + {0xF74F, 0x9C4B}, //21025 #CJK UNIFIED IDEOGRAPH + {0xF750, 0x9C4C}, //21026 #CJK UNIFIED IDEOGRAPH + {0xF751, 0x9C4D}, //21027 #CJK UNIFIED IDEOGRAPH + {0xF752, 0x9C4E}, //21028 #CJK UNIFIED IDEOGRAPH + {0xF753, 0x9C4F}, //21029 #CJK UNIFIED IDEOGRAPH + {0xF754, 0x9C50}, //21030 #CJK UNIFIED IDEOGRAPH + {0xF755, 0x9C51}, //21031 #CJK UNIFIED IDEOGRAPH + {0xF756, 0x9C52}, //21032 #CJK UNIFIED IDEOGRAPH + {0xF757, 0x9C53}, //21033 #CJK UNIFIED IDEOGRAPH + {0xF758, 0x9C54}, //21034 #CJK UNIFIED IDEOGRAPH + {0xF759, 0x9C55}, //21035 #CJK UNIFIED IDEOGRAPH + {0xF75A, 0x9C56}, //21036 #CJK UNIFIED IDEOGRAPH + {0xF75B, 0x9C57}, //21037 #CJK UNIFIED IDEOGRAPH + {0xF75C, 0x9C58}, //21038 #CJK UNIFIED IDEOGRAPH + {0xF75D, 0x9C59}, //21039 #CJK UNIFIED IDEOGRAPH + {0xF75E, 0x9C5A}, //21040 #CJK UNIFIED IDEOGRAPH + {0xF75F, 0x9C5B}, //21041 #CJK UNIFIED IDEOGRAPH + {0xF760, 0x9C5C}, //21042 #CJK UNIFIED IDEOGRAPH + {0xF761, 0x9C5D}, //21043 #CJK UNIFIED IDEOGRAPH + {0xF762, 0x9C5E}, //21044 #CJK UNIFIED IDEOGRAPH + {0xF763, 0x9C5F}, //21045 #CJK UNIFIED IDEOGRAPH + {0xF764, 0x9C60}, //21046 #CJK UNIFIED IDEOGRAPH + {0xF765, 0x9C61}, //21047 #CJK UNIFIED IDEOGRAPH + {0xF766, 0x9C62}, //21048 #CJK UNIFIED IDEOGRAPH + {0xF767, 0x9C63}, //21049 #CJK UNIFIED IDEOGRAPH + {0xF768, 0x9C64}, //21050 #CJK UNIFIED IDEOGRAPH + {0xF769, 0x9C65}, //21051 #CJK UNIFIED IDEOGRAPH + {0xF76A, 0x9C66}, //21052 #CJK UNIFIED IDEOGRAPH + {0xF76B, 0x9C67}, //21053 #CJK UNIFIED IDEOGRAPH + {0xF76C, 0x9C68}, //21054 #CJK UNIFIED IDEOGRAPH + {0xF76D, 0x9C69}, //21055 #CJK UNIFIED IDEOGRAPH + {0xF76E, 0x9C6A}, //21056 #CJK UNIFIED IDEOGRAPH + {0xF76F, 0x9C6B}, //21057 #CJK UNIFIED IDEOGRAPH + {0xF770, 0x9C6C}, //21058 #CJK UNIFIED IDEOGRAPH + {0xF771, 0x9C6D}, //21059 #CJK UNIFIED IDEOGRAPH + {0xF772, 0x9C6E}, //21060 #CJK UNIFIED IDEOGRAPH + {0xF773, 0x9C6F}, //21061 #CJK UNIFIED IDEOGRAPH + {0xF774, 0x9C70}, //21062 #CJK UNIFIED IDEOGRAPH + {0xF775, 0x9C71}, //21063 #CJK UNIFIED IDEOGRAPH + {0xF776, 0x9C72}, //21064 #CJK UNIFIED IDEOGRAPH + {0xF777, 0x9C73}, //21065 #CJK UNIFIED IDEOGRAPH + {0xF778, 0x9C74}, //21066 #CJK UNIFIED IDEOGRAPH + {0xF779, 0x9C75}, //21067 #CJK UNIFIED IDEOGRAPH + {0xF77A, 0x9C76}, //21068 #CJK UNIFIED IDEOGRAPH + {0xF77B, 0x9C77}, //21069 #CJK UNIFIED IDEOGRAPH + {0xF77C, 0x9C78}, //21070 #CJK UNIFIED IDEOGRAPH + {0xF77D, 0x9C79}, //21071 #CJK UNIFIED IDEOGRAPH + {0xF77E, 0x9C7A}, //21072 #CJK UNIFIED IDEOGRAPH + {0xF780, 0x9C7B}, //21073 #CJK UNIFIED IDEOGRAPH + {0xF781, 0x9C7D}, //21074 #CJK UNIFIED IDEOGRAPH + {0xF782, 0x9C7E}, //21075 #CJK UNIFIED IDEOGRAPH + {0xF783, 0x9C80}, //21076 #CJK UNIFIED IDEOGRAPH + {0xF784, 0x9C83}, //21077 #CJK UNIFIED IDEOGRAPH + {0xF785, 0x9C84}, //21078 #CJK UNIFIED IDEOGRAPH + {0xF786, 0x9C89}, //21079 #CJK UNIFIED IDEOGRAPH + {0xF787, 0x9C8A}, //21080 #CJK UNIFIED IDEOGRAPH + {0xF788, 0x9C8C}, //21081 #CJK UNIFIED IDEOGRAPH + {0xF789, 0x9C8F}, //21082 #CJK UNIFIED IDEOGRAPH + {0xF78A, 0x9C93}, //21083 #CJK UNIFIED IDEOGRAPH + {0xF78B, 0x9C96}, //21084 #CJK UNIFIED IDEOGRAPH + {0xF78C, 0x9C97}, //21085 #CJK UNIFIED IDEOGRAPH + {0xF78D, 0x9C98}, //21086 #CJK UNIFIED IDEOGRAPH + {0xF78E, 0x9C99}, //21087 #CJK UNIFIED IDEOGRAPH + {0xF78F, 0x9C9D}, //21088 #CJK UNIFIED IDEOGRAPH + {0xF790, 0x9CAA}, //21089 #CJK UNIFIED IDEOGRAPH + {0xF791, 0x9CAC}, //21090 #CJK UNIFIED IDEOGRAPH + {0xF792, 0x9CAF}, //21091 #CJK UNIFIED IDEOGRAPH + {0xF793, 0x9CB9}, //21092 #CJK UNIFIED IDEOGRAPH + {0xF794, 0x9CBE}, //21093 #CJK UNIFIED IDEOGRAPH + {0xF795, 0x9CBF}, //21094 #CJK UNIFIED IDEOGRAPH + {0xF796, 0x9CC0}, //21095 #CJK UNIFIED IDEOGRAPH + {0xF797, 0x9CC1}, //21096 #CJK UNIFIED IDEOGRAPH + {0xF798, 0x9CC2}, //21097 #CJK UNIFIED IDEOGRAPH + {0xF799, 0x9CC8}, //21098 #CJK UNIFIED IDEOGRAPH + {0xF79A, 0x9CC9}, //21099 #CJK UNIFIED IDEOGRAPH + {0xF79B, 0x9CD1}, //21100 #CJK UNIFIED IDEOGRAPH + {0xF79C, 0x9CD2}, //21101 #CJK UNIFIED IDEOGRAPH + {0xF79D, 0x9CDA}, //21102 #CJK UNIFIED IDEOGRAPH + {0xF79E, 0x9CDB}, //21103 #CJK UNIFIED IDEOGRAPH + {0xF79F, 0x9CE0}, //21104 #CJK UNIFIED IDEOGRAPH + {0xF7A0, 0x9CE1}, //21105 #CJK UNIFIED IDEOGRAPH + {0xF7A1, 0x9CCC}, //21106 #CJK UNIFIED IDEOGRAPH + {0xF7A2, 0x9CCD}, //21107 #CJK UNIFIED IDEOGRAPH + {0xF7A3, 0x9CCE}, //21108 #CJK UNIFIED IDEOGRAPH + {0xF7A4, 0x9CCF}, //21109 #CJK UNIFIED IDEOGRAPH + {0xF7A5, 0x9CD0}, //21110 #CJK UNIFIED IDEOGRAPH + {0xF7A6, 0x9CD3}, //21111 #CJK UNIFIED IDEOGRAPH + {0xF7A7, 0x9CD4}, //21112 #CJK UNIFIED IDEOGRAPH + {0xF7A8, 0x9CD5}, //21113 #CJK UNIFIED IDEOGRAPH + {0xF7A9, 0x9CD7}, //21114 #CJK UNIFIED IDEOGRAPH + {0xF7AA, 0x9CD8}, //21115 #CJK UNIFIED IDEOGRAPH + {0xF7AB, 0x9CD9}, //21116 #CJK UNIFIED IDEOGRAPH + {0xF7AC, 0x9CDC}, //21117 #CJK UNIFIED IDEOGRAPH + {0xF7AD, 0x9CDD}, //21118 #CJK UNIFIED IDEOGRAPH + {0xF7AE, 0x9CDF}, //21119 #CJK UNIFIED IDEOGRAPH + {0xF7AF, 0x9CE2}, //21120 #CJK UNIFIED IDEOGRAPH + {0xF7B0, 0x977C}, //21121 #CJK UNIFIED IDEOGRAPH + {0xF7B1, 0x9785}, //21122 #CJK UNIFIED IDEOGRAPH + {0xF7B2, 0x9791}, //21123 #CJK UNIFIED IDEOGRAPH + {0xF7B3, 0x9792}, //21124 #CJK UNIFIED IDEOGRAPH + {0xF7B4, 0x9794}, //21125 #CJK UNIFIED IDEOGRAPH + {0xF7B5, 0x97AF}, //21126 #CJK UNIFIED IDEOGRAPH + {0xF7B6, 0x97AB}, //21127 #CJK UNIFIED IDEOGRAPH + {0xF7B7, 0x97A3}, //21128 #CJK UNIFIED IDEOGRAPH + {0xF7B8, 0x97B2}, //21129 #CJK UNIFIED IDEOGRAPH + {0xF7B9, 0x97B4}, //21130 #CJK UNIFIED IDEOGRAPH + {0xF7BA, 0x9AB1}, //21131 #CJK UNIFIED IDEOGRAPH + {0xF7BB, 0x9AB0}, //21132 #CJK UNIFIED IDEOGRAPH + {0xF7BC, 0x9AB7}, //21133 #CJK UNIFIED IDEOGRAPH + {0xF7BD, 0x9E58}, //21134 #CJK UNIFIED IDEOGRAPH + {0xF7BE, 0x9AB6}, //21135 #CJK UNIFIED IDEOGRAPH + {0xF7BF, 0x9ABA}, //21136 #CJK UNIFIED IDEOGRAPH + {0xF7C0, 0x9ABC}, //21137 #CJK UNIFIED IDEOGRAPH + {0xF7C1, 0x9AC1}, //21138 #CJK UNIFIED IDEOGRAPH + {0xF7C2, 0x9AC0}, //21139 #CJK UNIFIED IDEOGRAPH + {0xF7C3, 0x9AC5}, //21140 #CJK UNIFIED IDEOGRAPH + {0xF7C4, 0x9AC2}, //21141 #CJK UNIFIED IDEOGRAPH + {0xF7C5, 0x9ACB}, //21142 #CJK UNIFIED IDEOGRAPH + {0xF7C6, 0x9ACC}, //21143 #CJK UNIFIED IDEOGRAPH + {0xF7C7, 0x9AD1}, //21144 #CJK UNIFIED IDEOGRAPH + {0xF7C8, 0x9B45}, //21145 #CJK UNIFIED IDEOGRAPH + {0xF7C9, 0x9B43}, //21146 #CJK UNIFIED IDEOGRAPH + {0xF7CA, 0x9B47}, //21147 #CJK UNIFIED IDEOGRAPH + {0xF7CB, 0x9B49}, //21148 #CJK UNIFIED IDEOGRAPH + {0xF7CC, 0x9B48}, //21149 #CJK UNIFIED IDEOGRAPH + {0xF7CD, 0x9B4D}, //21150 #CJK UNIFIED IDEOGRAPH + {0xF7CE, 0x9B51}, //21151 #CJK UNIFIED IDEOGRAPH + {0xF7CF, 0x98E8}, //21152 #CJK UNIFIED IDEOGRAPH + {0xF7D0, 0x990D}, //21153 #CJK UNIFIED IDEOGRAPH + {0xF7D1, 0x992E}, //21154 #CJK UNIFIED IDEOGRAPH + {0xF7D2, 0x9955}, //21155 #CJK UNIFIED IDEOGRAPH + {0xF7D3, 0x9954}, //21156 #CJK UNIFIED IDEOGRAPH + {0xF7D4, 0x9ADF}, //21157 #CJK UNIFIED IDEOGRAPH + {0xF7D5, 0x9AE1}, //21158 #CJK UNIFIED IDEOGRAPH + {0xF7D6, 0x9AE6}, //21159 #CJK UNIFIED IDEOGRAPH + {0xF7D7, 0x9AEF}, //21160 #CJK UNIFIED IDEOGRAPH + {0xF7D8, 0x9AEB}, //21161 #CJK UNIFIED IDEOGRAPH + {0xF7D9, 0x9AFB}, //21162 #CJK UNIFIED IDEOGRAPH + {0xF7DA, 0x9AED}, //21163 #CJK UNIFIED IDEOGRAPH + {0xF7DB, 0x9AF9}, //21164 #CJK UNIFIED IDEOGRAPH + {0xF7DC, 0x9B08}, //21165 #CJK UNIFIED IDEOGRAPH + {0xF7DD, 0x9B0F}, //21166 #CJK UNIFIED IDEOGRAPH + {0xF7DE, 0x9B13}, //21167 #CJK UNIFIED IDEOGRAPH + {0xF7DF, 0x9B1F}, //21168 #CJK UNIFIED IDEOGRAPH + {0xF7E0, 0x9B23}, //21169 #CJK UNIFIED IDEOGRAPH + {0xF7E1, 0x9EBD}, //21170 #CJK UNIFIED IDEOGRAPH + {0xF7E2, 0x9EBE}, //21171 #CJK UNIFIED IDEOGRAPH + {0xF7E3, 0x7E3B}, //21172 #CJK UNIFIED IDEOGRAPH + {0xF7E4, 0x9E82}, //21173 #CJK UNIFIED IDEOGRAPH + {0xF7E5, 0x9E87}, //21174 #CJK UNIFIED IDEOGRAPH + {0xF7E6, 0x9E88}, //21175 #CJK UNIFIED IDEOGRAPH + {0xF7E7, 0x9E8B}, //21176 #CJK UNIFIED IDEOGRAPH + {0xF7E8, 0x9E92}, //21177 #CJK UNIFIED IDEOGRAPH + {0xF7E9, 0x93D6}, //21178 #CJK UNIFIED IDEOGRAPH + {0xF7EA, 0x9E9D}, //21179 #CJK UNIFIED IDEOGRAPH + {0xF7EB, 0x9E9F}, //21180 #CJK UNIFIED IDEOGRAPH + {0xF7EC, 0x9EDB}, //21181 #CJK UNIFIED IDEOGRAPH + {0xF7ED, 0x9EDC}, //21182 #CJK UNIFIED IDEOGRAPH + {0xF7EE, 0x9EDD}, //21183 #CJK UNIFIED IDEOGRAPH + {0xF7EF, 0x9EE0}, //21184 #CJK UNIFIED IDEOGRAPH + {0xF7F0, 0x9EDF}, //21185 #CJK UNIFIED IDEOGRAPH + {0xF7F1, 0x9EE2}, //21186 #CJK UNIFIED IDEOGRAPH + {0xF7F2, 0x9EE9}, //21187 #CJK UNIFIED IDEOGRAPH + {0xF7F3, 0x9EE7}, //21188 #CJK UNIFIED IDEOGRAPH + {0xF7F4, 0x9EE5}, //21189 #CJK UNIFIED IDEOGRAPH + {0xF7F5, 0x9EEA}, //21190 #CJK UNIFIED IDEOGRAPH + {0xF7F6, 0x9EEF}, //21191 #CJK UNIFIED IDEOGRAPH + {0xF7F7, 0x9F22}, //21192 #CJK UNIFIED IDEOGRAPH + {0xF7F8, 0x9F2C}, //21193 #CJK UNIFIED IDEOGRAPH + {0xF7F9, 0x9F2F}, //21194 #CJK UNIFIED IDEOGRAPH + {0xF7FA, 0x9F39}, //21195 #CJK UNIFIED IDEOGRAPH + {0xF7FB, 0x9F37}, //21196 #CJK UNIFIED IDEOGRAPH + {0xF7FC, 0x9F3D}, //21197 #CJK UNIFIED IDEOGRAPH + {0xF7FD, 0x9F3E}, //21198 #CJK UNIFIED IDEOGRAPH + {0xF7FE, 0x9F44}, //21199 #CJK UNIFIED IDEOGRAPH + {0xF840, 0x9CE3}, //21200 #CJK UNIFIED IDEOGRAPH + {0xF841, 0x9CE4}, //21201 #CJK UNIFIED IDEOGRAPH + {0xF842, 0x9CE5}, //21202 #CJK UNIFIED IDEOGRAPH + {0xF843, 0x9CE6}, //21203 #CJK UNIFIED IDEOGRAPH + {0xF844, 0x9CE7}, //21204 #CJK UNIFIED IDEOGRAPH + {0xF845, 0x9CE8}, //21205 #CJK UNIFIED IDEOGRAPH + {0xF846, 0x9CE9}, //21206 #CJK UNIFIED IDEOGRAPH + {0xF847, 0x9CEA}, //21207 #CJK UNIFIED IDEOGRAPH + {0xF848, 0x9CEB}, //21208 #CJK UNIFIED IDEOGRAPH + {0xF849, 0x9CEC}, //21209 #CJK UNIFIED IDEOGRAPH + {0xF84A, 0x9CED}, //21210 #CJK UNIFIED IDEOGRAPH + {0xF84B, 0x9CEE}, //21211 #CJK UNIFIED IDEOGRAPH + {0xF84C, 0x9CEF}, //21212 #CJK UNIFIED IDEOGRAPH + {0xF84D, 0x9CF0}, //21213 #CJK UNIFIED IDEOGRAPH + {0xF84E, 0x9CF1}, //21214 #CJK UNIFIED IDEOGRAPH + {0xF84F, 0x9CF2}, //21215 #CJK UNIFIED IDEOGRAPH + {0xF850, 0x9CF3}, //21216 #CJK UNIFIED IDEOGRAPH + {0xF851, 0x9CF4}, //21217 #CJK UNIFIED IDEOGRAPH + {0xF852, 0x9CF5}, //21218 #CJK UNIFIED IDEOGRAPH + {0xF853, 0x9CF6}, //21219 #CJK UNIFIED IDEOGRAPH + {0xF854, 0x9CF7}, //21220 #CJK UNIFIED IDEOGRAPH + {0xF855, 0x9CF8}, //21221 #CJK UNIFIED IDEOGRAPH + {0xF856, 0x9CF9}, //21222 #CJK UNIFIED IDEOGRAPH + {0xF857, 0x9CFA}, //21223 #CJK UNIFIED IDEOGRAPH + {0xF858, 0x9CFB}, //21224 #CJK UNIFIED IDEOGRAPH + {0xF859, 0x9CFC}, //21225 #CJK UNIFIED IDEOGRAPH + {0xF85A, 0x9CFD}, //21226 #CJK UNIFIED IDEOGRAPH + {0xF85B, 0x9CFE}, //21227 #CJK UNIFIED IDEOGRAPH + {0xF85C, 0x9CFF}, //21228 #CJK UNIFIED IDEOGRAPH + {0xF85D, 0x9D00}, //21229 #CJK UNIFIED IDEOGRAPH + {0xF85E, 0x9D01}, //21230 #CJK UNIFIED IDEOGRAPH + {0xF85F, 0x9D02}, //21231 #CJK UNIFIED IDEOGRAPH + {0xF860, 0x9D03}, //21232 #CJK UNIFIED IDEOGRAPH + {0xF861, 0x9D04}, //21233 #CJK UNIFIED IDEOGRAPH + {0xF862, 0x9D05}, //21234 #CJK UNIFIED IDEOGRAPH + {0xF863, 0x9D06}, //21235 #CJK UNIFIED IDEOGRAPH + {0xF864, 0x9D07}, //21236 #CJK UNIFIED IDEOGRAPH + {0xF865, 0x9D08}, //21237 #CJK UNIFIED IDEOGRAPH + {0xF866, 0x9D09}, //21238 #CJK UNIFIED IDEOGRAPH + {0xF867, 0x9D0A}, //21239 #CJK UNIFIED IDEOGRAPH + {0xF868, 0x9D0B}, //21240 #CJK UNIFIED IDEOGRAPH + {0xF869, 0x9D0C}, //21241 #CJK UNIFIED IDEOGRAPH + {0xF86A, 0x9D0D}, //21242 #CJK UNIFIED IDEOGRAPH + {0xF86B, 0x9D0E}, //21243 #CJK UNIFIED IDEOGRAPH + {0xF86C, 0x9D0F}, //21244 #CJK UNIFIED IDEOGRAPH + {0xF86D, 0x9D10}, //21245 #CJK UNIFIED IDEOGRAPH + {0xF86E, 0x9D11}, //21246 #CJK UNIFIED IDEOGRAPH + {0xF86F, 0x9D12}, //21247 #CJK UNIFIED IDEOGRAPH + {0xF870, 0x9D13}, //21248 #CJK UNIFIED IDEOGRAPH + {0xF871, 0x9D14}, //21249 #CJK UNIFIED IDEOGRAPH + {0xF872, 0x9D15}, //21250 #CJK UNIFIED IDEOGRAPH + {0xF873, 0x9D16}, //21251 #CJK UNIFIED IDEOGRAPH + {0xF874, 0x9D17}, //21252 #CJK UNIFIED IDEOGRAPH + {0xF875, 0x9D18}, //21253 #CJK UNIFIED IDEOGRAPH + {0xF876, 0x9D19}, //21254 #CJK UNIFIED IDEOGRAPH + {0xF877, 0x9D1A}, //21255 #CJK UNIFIED IDEOGRAPH + {0xF878, 0x9D1B}, //21256 #CJK UNIFIED IDEOGRAPH + {0xF879, 0x9D1C}, //21257 #CJK UNIFIED IDEOGRAPH + {0xF87A, 0x9D1D}, //21258 #CJK UNIFIED IDEOGRAPH + {0xF87B, 0x9D1E}, //21259 #CJK UNIFIED IDEOGRAPH + {0xF87C, 0x9D1F}, //21260 #CJK UNIFIED IDEOGRAPH + {0xF87D, 0x9D20}, //21261 #CJK UNIFIED IDEOGRAPH + {0xF87E, 0x9D21}, //21262 #CJK UNIFIED IDEOGRAPH + {0xF880, 0x9D22}, //21263 #CJK UNIFIED IDEOGRAPH + {0xF881, 0x9D23}, //21264 #CJK UNIFIED IDEOGRAPH + {0xF882, 0x9D24}, //21265 #CJK UNIFIED IDEOGRAPH + {0xF883, 0x9D25}, //21266 #CJK UNIFIED IDEOGRAPH + {0xF884, 0x9D26}, //21267 #CJK UNIFIED IDEOGRAPH + {0xF885, 0x9D27}, //21268 #CJK UNIFIED IDEOGRAPH + {0xF886, 0x9D28}, //21269 #CJK UNIFIED IDEOGRAPH + {0xF887, 0x9D29}, //21270 #CJK UNIFIED IDEOGRAPH + {0xF888, 0x9D2A}, //21271 #CJK UNIFIED IDEOGRAPH + {0xF889, 0x9D2B}, //21272 #CJK UNIFIED IDEOGRAPH + {0xF88A, 0x9D2C}, //21273 #CJK UNIFIED IDEOGRAPH + {0xF88B, 0x9D2D}, //21274 #CJK UNIFIED IDEOGRAPH + {0xF88C, 0x9D2E}, //21275 #CJK UNIFIED IDEOGRAPH + {0xF88D, 0x9D2F}, //21276 #CJK UNIFIED IDEOGRAPH + {0xF88E, 0x9D30}, //21277 #CJK UNIFIED IDEOGRAPH + {0xF88F, 0x9D31}, //21278 #CJK UNIFIED IDEOGRAPH + {0xF890, 0x9D32}, //21279 #CJK UNIFIED IDEOGRAPH + {0xF891, 0x9D33}, //21280 #CJK UNIFIED IDEOGRAPH + {0xF892, 0x9D34}, //21281 #CJK UNIFIED IDEOGRAPH + {0xF893, 0x9D35}, //21282 #CJK UNIFIED IDEOGRAPH + {0xF894, 0x9D36}, //21283 #CJK UNIFIED IDEOGRAPH + {0xF895, 0x9D37}, //21284 #CJK UNIFIED IDEOGRAPH + {0xF896, 0x9D38}, //21285 #CJK UNIFIED IDEOGRAPH + {0xF897, 0x9D39}, //21286 #CJK UNIFIED IDEOGRAPH + {0xF898, 0x9D3A}, //21287 #CJK UNIFIED IDEOGRAPH + {0xF899, 0x9D3B}, //21288 #CJK UNIFIED IDEOGRAPH + {0xF89A, 0x9D3C}, //21289 #CJK UNIFIED IDEOGRAPH + {0xF89B, 0x9D3D}, //21290 #CJK UNIFIED IDEOGRAPH + {0xF89C, 0x9D3E}, //21291 #CJK UNIFIED IDEOGRAPH + {0xF89D, 0x9D3F}, //21292 #CJK UNIFIED IDEOGRAPH + {0xF89E, 0x9D40}, //21293 #CJK UNIFIED IDEOGRAPH + {0xF89F, 0x9D41}, //21294 #CJK UNIFIED IDEOGRAPH + {0xF8A0, 0x9D42}, //21295 #CJK UNIFIED IDEOGRAPH + {0xF940, 0x9D43}, //21296 #CJK UNIFIED IDEOGRAPH + {0xF941, 0x9D44}, //21297 #CJK UNIFIED IDEOGRAPH + {0xF942, 0x9D45}, //21298 #CJK UNIFIED IDEOGRAPH + {0xF943, 0x9D46}, //21299 #CJK UNIFIED IDEOGRAPH + {0xF944, 0x9D47}, //21300 #CJK UNIFIED IDEOGRAPH + {0xF945, 0x9D48}, //21301 #CJK UNIFIED IDEOGRAPH + {0xF946, 0x9D49}, //21302 #CJK UNIFIED IDEOGRAPH + {0xF947, 0x9D4A}, //21303 #CJK UNIFIED IDEOGRAPH + {0xF948, 0x9D4B}, //21304 #CJK UNIFIED IDEOGRAPH + {0xF949, 0x9D4C}, //21305 #CJK UNIFIED IDEOGRAPH + {0xF94A, 0x9D4D}, //21306 #CJK UNIFIED IDEOGRAPH + {0xF94B, 0x9D4E}, //21307 #CJK UNIFIED IDEOGRAPH + {0xF94C, 0x9D4F}, //21308 #CJK UNIFIED IDEOGRAPH + {0xF94D, 0x9D50}, //21309 #CJK UNIFIED IDEOGRAPH + {0xF94E, 0x9D51}, //21310 #CJK UNIFIED IDEOGRAPH + {0xF94F, 0x9D52}, //21311 #CJK UNIFIED IDEOGRAPH + {0xF950, 0x9D53}, //21312 #CJK UNIFIED IDEOGRAPH + {0xF951, 0x9D54}, //21313 #CJK UNIFIED IDEOGRAPH + {0xF952, 0x9D55}, //21314 #CJK UNIFIED IDEOGRAPH + {0xF953, 0x9D56}, //21315 #CJK UNIFIED IDEOGRAPH + {0xF954, 0x9D57}, //21316 #CJK UNIFIED IDEOGRAPH + {0xF955, 0x9D58}, //21317 #CJK UNIFIED IDEOGRAPH + {0xF956, 0x9D59}, //21318 #CJK UNIFIED IDEOGRAPH + {0xF957, 0x9D5A}, //21319 #CJK UNIFIED IDEOGRAPH + {0xF958, 0x9D5B}, //21320 #CJK UNIFIED IDEOGRAPH + {0xF959, 0x9D5C}, //21321 #CJK UNIFIED IDEOGRAPH + {0xF95A, 0x9D5D}, //21322 #CJK UNIFIED IDEOGRAPH + {0xF95B, 0x9D5E}, //21323 #CJK UNIFIED IDEOGRAPH + {0xF95C, 0x9D5F}, //21324 #CJK UNIFIED IDEOGRAPH + {0xF95D, 0x9D60}, //21325 #CJK UNIFIED IDEOGRAPH + {0xF95E, 0x9D61}, //21326 #CJK UNIFIED IDEOGRAPH + {0xF95F, 0x9D62}, //21327 #CJK UNIFIED IDEOGRAPH + {0xF960, 0x9D63}, //21328 #CJK UNIFIED IDEOGRAPH + {0xF961, 0x9D64}, //21329 #CJK UNIFIED IDEOGRAPH + {0xF962, 0x9D65}, //21330 #CJK UNIFIED IDEOGRAPH + {0xF963, 0x9D66}, //21331 #CJK UNIFIED IDEOGRAPH + {0xF964, 0x9D67}, //21332 #CJK UNIFIED IDEOGRAPH + {0xF965, 0x9D68}, //21333 #CJK UNIFIED IDEOGRAPH + {0xF966, 0x9D69}, //21334 #CJK UNIFIED IDEOGRAPH + {0xF967, 0x9D6A}, //21335 #CJK UNIFIED IDEOGRAPH + {0xF968, 0x9D6B}, //21336 #CJK UNIFIED IDEOGRAPH + {0xF969, 0x9D6C}, //21337 #CJK UNIFIED IDEOGRAPH + {0xF96A, 0x9D6D}, //21338 #CJK UNIFIED IDEOGRAPH + {0xF96B, 0x9D6E}, //21339 #CJK UNIFIED IDEOGRAPH + {0xF96C, 0x9D6F}, //21340 #CJK UNIFIED IDEOGRAPH + {0xF96D, 0x9D70}, //21341 #CJK UNIFIED IDEOGRAPH + {0xF96E, 0x9D71}, //21342 #CJK UNIFIED IDEOGRAPH + {0xF96F, 0x9D72}, //21343 #CJK UNIFIED IDEOGRAPH + {0xF970, 0x9D73}, //21344 #CJK UNIFIED IDEOGRAPH + {0xF971, 0x9D74}, //21345 #CJK UNIFIED IDEOGRAPH + {0xF972, 0x9D75}, //21346 #CJK UNIFIED IDEOGRAPH + {0xF973, 0x9D76}, //21347 #CJK UNIFIED IDEOGRAPH + {0xF974, 0x9D77}, //21348 #CJK UNIFIED IDEOGRAPH + {0xF975, 0x9D78}, //21349 #CJK UNIFIED IDEOGRAPH + {0xF976, 0x9D79}, //21350 #CJK UNIFIED IDEOGRAPH + {0xF977, 0x9D7A}, //21351 #CJK UNIFIED IDEOGRAPH + {0xF978, 0x9D7B}, //21352 #CJK UNIFIED IDEOGRAPH + {0xF979, 0x9D7C}, //21353 #CJK UNIFIED IDEOGRAPH + {0xF97A, 0x9D7D}, //21354 #CJK UNIFIED IDEOGRAPH + {0xF97B, 0x9D7E}, //21355 #CJK UNIFIED IDEOGRAPH + {0xF97C, 0x9D7F}, //21356 #CJK UNIFIED IDEOGRAPH + {0xF97D, 0x9D80}, //21357 #CJK UNIFIED IDEOGRAPH + {0xF97E, 0x9D81}, //21358 #CJK UNIFIED IDEOGRAPH + {0xF980, 0x9D82}, //21359 #CJK UNIFIED IDEOGRAPH + {0xF981, 0x9D83}, //21360 #CJK UNIFIED IDEOGRAPH + {0xF982, 0x9D84}, //21361 #CJK UNIFIED IDEOGRAPH + {0xF983, 0x9D85}, //21362 #CJK UNIFIED IDEOGRAPH + {0xF984, 0x9D86}, //21363 #CJK UNIFIED IDEOGRAPH + {0xF985, 0x9D87}, //21364 #CJK UNIFIED IDEOGRAPH + {0xF986, 0x9D88}, //21365 #CJK UNIFIED IDEOGRAPH + {0xF987, 0x9D89}, //21366 #CJK UNIFIED IDEOGRAPH + {0xF988, 0x9D8A}, //21367 #CJK UNIFIED IDEOGRAPH + {0xF989, 0x9D8B}, //21368 #CJK UNIFIED IDEOGRAPH + {0xF98A, 0x9D8C}, //21369 #CJK UNIFIED IDEOGRAPH + {0xF98B, 0x9D8D}, //21370 #CJK UNIFIED IDEOGRAPH + {0xF98C, 0x9D8E}, //21371 #CJK UNIFIED IDEOGRAPH + {0xF98D, 0x9D8F}, //21372 #CJK UNIFIED IDEOGRAPH + {0xF98E, 0x9D90}, //21373 #CJK UNIFIED IDEOGRAPH + {0xF98F, 0x9D91}, //21374 #CJK UNIFIED IDEOGRAPH + {0xF990, 0x9D92}, //21375 #CJK UNIFIED IDEOGRAPH + {0xF991, 0x9D93}, //21376 #CJK UNIFIED IDEOGRAPH + {0xF992, 0x9D94}, //21377 #CJK UNIFIED IDEOGRAPH + {0xF993, 0x9D95}, //21378 #CJK UNIFIED IDEOGRAPH + {0xF994, 0x9D96}, //21379 #CJK UNIFIED IDEOGRAPH + {0xF995, 0x9D97}, //21380 #CJK UNIFIED IDEOGRAPH + {0xF996, 0x9D98}, //21381 #CJK UNIFIED IDEOGRAPH + {0xF997, 0x9D99}, //21382 #CJK UNIFIED IDEOGRAPH + {0xF998, 0x9D9A}, //21383 #CJK UNIFIED IDEOGRAPH + {0xF999, 0x9D9B}, //21384 #CJK UNIFIED IDEOGRAPH + {0xF99A, 0x9D9C}, //21385 #CJK UNIFIED IDEOGRAPH + {0xF99B, 0x9D9D}, //21386 #CJK UNIFIED IDEOGRAPH + {0xF99C, 0x9D9E}, //21387 #CJK UNIFIED IDEOGRAPH + {0xF99D, 0x9D9F}, //21388 #CJK UNIFIED IDEOGRAPH + {0xF99E, 0x9DA0}, //21389 #CJK UNIFIED IDEOGRAPH + {0xF99F, 0x9DA1}, //21390 #CJK UNIFIED IDEOGRAPH + {0xF9A0, 0x9DA2}, //21391 #CJK UNIFIED IDEOGRAPH + {0xFA40, 0x9DA3}, //21392 #CJK UNIFIED IDEOGRAPH + {0xFA41, 0x9DA4}, //21393 #CJK UNIFIED IDEOGRAPH + {0xFA42, 0x9DA5}, //21394 #CJK UNIFIED IDEOGRAPH + {0xFA43, 0x9DA6}, //21395 #CJK UNIFIED IDEOGRAPH + {0xFA44, 0x9DA7}, //21396 #CJK UNIFIED IDEOGRAPH + {0xFA45, 0x9DA8}, //21397 #CJK UNIFIED IDEOGRAPH + {0xFA46, 0x9DA9}, //21398 #CJK UNIFIED IDEOGRAPH + {0xFA47, 0x9DAA}, //21399 #CJK UNIFIED IDEOGRAPH + {0xFA48, 0x9DAB}, //21400 #CJK UNIFIED IDEOGRAPH + {0xFA49, 0x9DAC}, //21401 #CJK UNIFIED IDEOGRAPH + {0xFA4A, 0x9DAD}, //21402 #CJK UNIFIED IDEOGRAPH + {0xFA4B, 0x9DAE}, //21403 #CJK UNIFIED IDEOGRAPH + {0xFA4C, 0x9DAF}, //21404 #CJK UNIFIED IDEOGRAPH + {0xFA4D, 0x9DB0}, //21405 #CJK UNIFIED IDEOGRAPH + {0xFA4E, 0x9DB1}, //21406 #CJK UNIFIED IDEOGRAPH + {0xFA4F, 0x9DB2}, //21407 #CJK UNIFIED IDEOGRAPH + {0xFA50, 0x9DB3}, //21408 #CJK UNIFIED IDEOGRAPH + {0xFA51, 0x9DB4}, //21409 #CJK UNIFIED IDEOGRAPH + {0xFA52, 0x9DB5}, //21410 #CJK UNIFIED IDEOGRAPH + {0xFA53, 0x9DB6}, //21411 #CJK UNIFIED IDEOGRAPH + {0xFA54, 0x9DB7}, //21412 #CJK UNIFIED IDEOGRAPH + {0xFA55, 0x9DB8}, //21413 #CJK UNIFIED IDEOGRAPH + {0xFA56, 0x9DB9}, //21414 #CJK UNIFIED IDEOGRAPH + {0xFA57, 0x9DBA}, //21415 #CJK UNIFIED IDEOGRAPH + {0xFA58, 0x9DBB}, //21416 #CJK UNIFIED IDEOGRAPH + {0xFA59, 0x9DBC}, //21417 #CJK UNIFIED IDEOGRAPH + {0xFA5A, 0x9DBD}, //21418 #CJK UNIFIED IDEOGRAPH + {0xFA5B, 0x9DBE}, //21419 #CJK UNIFIED IDEOGRAPH + {0xFA5C, 0x9DBF}, //21420 #CJK UNIFIED IDEOGRAPH + {0xFA5D, 0x9DC0}, //21421 #CJK UNIFIED IDEOGRAPH + {0xFA5E, 0x9DC1}, //21422 #CJK UNIFIED IDEOGRAPH + {0xFA5F, 0x9DC2}, //21423 #CJK UNIFIED IDEOGRAPH + {0xFA60, 0x9DC3}, //21424 #CJK UNIFIED IDEOGRAPH + {0xFA61, 0x9DC4}, //21425 #CJK UNIFIED IDEOGRAPH + {0xFA62, 0x9DC5}, //21426 #CJK UNIFIED IDEOGRAPH + {0xFA63, 0x9DC6}, //21427 #CJK UNIFIED IDEOGRAPH + {0xFA64, 0x9DC7}, //21428 #CJK UNIFIED IDEOGRAPH + {0xFA65, 0x9DC8}, //21429 #CJK UNIFIED IDEOGRAPH + {0xFA66, 0x9DC9}, //21430 #CJK UNIFIED IDEOGRAPH + {0xFA67, 0x9DCA}, //21431 #CJK UNIFIED IDEOGRAPH + {0xFA68, 0x9DCB}, //21432 #CJK UNIFIED IDEOGRAPH + {0xFA69, 0x9DCC}, //21433 #CJK UNIFIED IDEOGRAPH + {0xFA6A, 0x9DCD}, //21434 #CJK UNIFIED IDEOGRAPH + {0xFA6B, 0x9DCE}, //21435 #CJK UNIFIED IDEOGRAPH + {0xFA6C, 0x9DCF}, //21436 #CJK UNIFIED IDEOGRAPH + {0xFA6D, 0x9DD0}, //21437 #CJK UNIFIED IDEOGRAPH + {0xFA6E, 0x9DD1}, //21438 #CJK UNIFIED IDEOGRAPH + {0xFA6F, 0x9DD2}, //21439 #CJK UNIFIED IDEOGRAPH + {0xFA70, 0x9DD3}, //21440 #CJK UNIFIED IDEOGRAPH + {0xFA71, 0x9DD4}, //21441 #CJK UNIFIED IDEOGRAPH + {0xFA72, 0x9DD5}, //21442 #CJK UNIFIED IDEOGRAPH + {0xFA73, 0x9DD6}, //21443 #CJK UNIFIED IDEOGRAPH + {0xFA74, 0x9DD7}, //21444 #CJK UNIFIED IDEOGRAPH + {0xFA75, 0x9DD8}, //21445 #CJK UNIFIED IDEOGRAPH + {0xFA76, 0x9DD9}, //21446 #CJK UNIFIED IDEOGRAPH + {0xFA77, 0x9DDA}, //21447 #CJK UNIFIED IDEOGRAPH + {0xFA78, 0x9DDB}, //21448 #CJK UNIFIED IDEOGRAPH + {0xFA79, 0x9DDC}, //21449 #CJK UNIFIED IDEOGRAPH + {0xFA7A, 0x9DDD}, //21450 #CJK UNIFIED IDEOGRAPH + {0xFA7B, 0x9DDE}, //21451 #CJK UNIFIED IDEOGRAPH + {0xFA7C, 0x9DDF}, //21452 #CJK UNIFIED IDEOGRAPH + {0xFA7D, 0x9DE0}, //21453 #CJK UNIFIED IDEOGRAPH + {0xFA7E, 0x9DE1}, //21454 #CJK UNIFIED IDEOGRAPH + {0xFA80, 0x9DE2}, //21455 #CJK UNIFIED IDEOGRAPH + {0xFA81, 0x9DE3}, //21456 #CJK UNIFIED IDEOGRAPH + {0xFA82, 0x9DE4}, //21457 #CJK UNIFIED IDEOGRAPH + {0xFA83, 0x9DE5}, //21458 #CJK UNIFIED IDEOGRAPH + {0xFA84, 0x9DE6}, //21459 #CJK UNIFIED IDEOGRAPH + {0xFA85, 0x9DE7}, //21460 #CJK UNIFIED IDEOGRAPH + {0xFA86, 0x9DE8}, //21461 #CJK UNIFIED IDEOGRAPH + {0xFA87, 0x9DE9}, //21462 #CJK UNIFIED IDEOGRAPH + {0xFA88, 0x9DEA}, //21463 #CJK UNIFIED IDEOGRAPH + {0xFA89, 0x9DEB}, //21464 #CJK UNIFIED IDEOGRAPH + {0xFA8A, 0x9DEC}, //21465 #CJK UNIFIED IDEOGRAPH + {0xFA8B, 0x9DED}, //21466 #CJK UNIFIED IDEOGRAPH + {0xFA8C, 0x9DEE}, //21467 #CJK UNIFIED IDEOGRAPH + {0xFA8D, 0x9DEF}, //21468 #CJK UNIFIED IDEOGRAPH + {0xFA8E, 0x9DF0}, //21469 #CJK UNIFIED IDEOGRAPH + {0xFA8F, 0x9DF1}, //21470 #CJK UNIFIED IDEOGRAPH + {0xFA90, 0x9DF2}, //21471 #CJK UNIFIED IDEOGRAPH + {0xFA91, 0x9DF3}, //21472 #CJK UNIFIED IDEOGRAPH + {0xFA92, 0x9DF4}, //21473 #CJK UNIFIED IDEOGRAPH + {0xFA93, 0x9DF5}, //21474 #CJK UNIFIED IDEOGRAPH + {0xFA94, 0x9DF6}, //21475 #CJK UNIFIED IDEOGRAPH + {0xFA95, 0x9DF7}, //21476 #CJK UNIFIED IDEOGRAPH + {0xFA96, 0x9DF8}, //21477 #CJK UNIFIED IDEOGRAPH + {0xFA97, 0x9DF9}, //21478 #CJK UNIFIED IDEOGRAPH + {0xFA98, 0x9DFA}, //21479 #CJK UNIFIED IDEOGRAPH + {0xFA99, 0x9DFB}, //21480 #CJK UNIFIED IDEOGRAPH + {0xFA9A, 0x9DFC}, //21481 #CJK UNIFIED IDEOGRAPH + {0xFA9B, 0x9DFD}, //21482 #CJK UNIFIED IDEOGRAPH + {0xFA9C, 0x9DFE}, //21483 #CJK UNIFIED IDEOGRAPH + {0xFA9D, 0x9DFF}, //21484 #CJK UNIFIED IDEOGRAPH + {0xFA9E, 0x9E00}, //21485 #CJK UNIFIED IDEOGRAPH + {0xFA9F, 0x9E01}, //21486 #CJK UNIFIED IDEOGRAPH + {0xFAA0, 0x9E02}, //21487 #CJK UNIFIED IDEOGRAPH + {0xFB40, 0x9E03}, //21488 #CJK UNIFIED IDEOGRAPH + {0xFB41, 0x9E04}, //21489 #CJK UNIFIED IDEOGRAPH + {0xFB42, 0x9E05}, //21490 #CJK UNIFIED IDEOGRAPH + {0xFB43, 0x9E06}, //21491 #CJK UNIFIED IDEOGRAPH + {0xFB44, 0x9E07}, //21492 #CJK UNIFIED IDEOGRAPH + {0xFB45, 0x9E08}, //21493 #CJK UNIFIED IDEOGRAPH + {0xFB46, 0x9E09}, //21494 #CJK UNIFIED IDEOGRAPH + {0xFB47, 0x9E0A}, //21495 #CJK UNIFIED IDEOGRAPH + {0xFB48, 0x9E0B}, //21496 #CJK UNIFIED IDEOGRAPH + {0xFB49, 0x9E0C}, //21497 #CJK UNIFIED IDEOGRAPH + {0xFB4A, 0x9E0D}, //21498 #CJK UNIFIED IDEOGRAPH + {0xFB4B, 0x9E0E}, //21499 #CJK UNIFIED IDEOGRAPH + {0xFB4C, 0x9E0F}, //21500 #CJK UNIFIED IDEOGRAPH + {0xFB4D, 0x9E10}, //21501 #CJK UNIFIED IDEOGRAPH + {0xFB4E, 0x9E11}, //21502 #CJK UNIFIED IDEOGRAPH + {0xFB4F, 0x9E12}, //21503 #CJK UNIFIED IDEOGRAPH + {0xFB50, 0x9E13}, //21504 #CJK UNIFIED IDEOGRAPH + {0xFB51, 0x9E14}, //21505 #CJK UNIFIED IDEOGRAPH + {0xFB52, 0x9E15}, //21506 #CJK UNIFIED IDEOGRAPH + {0xFB53, 0x9E16}, //21507 #CJK UNIFIED IDEOGRAPH + {0xFB54, 0x9E17}, //21508 #CJK UNIFIED IDEOGRAPH + {0xFB55, 0x9E18}, //21509 #CJK UNIFIED IDEOGRAPH + {0xFB56, 0x9E19}, //21510 #CJK UNIFIED IDEOGRAPH + {0xFB57, 0x9E1A}, //21511 #CJK UNIFIED IDEOGRAPH + {0xFB58, 0x9E1B}, //21512 #CJK UNIFIED IDEOGRAPH + {0xFB59, 0x9E1C}, //21513 #CJK UNIFIED IDEOGRAPH + {0xFB5A, 0x9E1D}, //21514 #CJK UNIFIED IDEOGRAPH + {0xFB5B, 0x9E1E}, //21515 #CJK UNIFIED IDEOGRAPH + {0xFB5C, 0x9E24}, //21516 #CJK UNIFIED IDEOGRAPH + {0xFB5D, 0x9E27}, //21517 #CJK UNIFIED IDEOGRAPH + {0xFB5E, 0x9E2E}, //21518 #CJK UNIFIED IDEOGRAPH + {0xFB5F, 0x9E30}, //21519 #CJK UNIFIED IDEOGRAPH + {0xFB60, 0x9E34}, //21520 #CJK UNIFIED IDEOGRAPH + {0xFB61, 0x9E3B}, //21521 #CJK UNIFIED IDEOGRAPH + {0xFB62, 0x9E3C}, //21522 #CJK UNIFIED IDEOGRAPH + {0xFB63, 0x9E40}, //21523 #CJK UNIFIED IDEOGRAPH + {0xFB64, 0x9E4D}, //21524 #CJK UNIFIED IDEOGRAPH + {0xFB65, 0x9E50}, //21525 #CJK UNIFIED IDEOGRAPH + {0xFB66, 0x9E52}, //21526 #CJK UNIFIED IDEOGRAPH + {0xFB67, 0x9E53}, //21527 #CJK UNIFIED IDEOGRAPH + {0xFB68, 0x9E54}, //21528 #CJK UNIFIED IDEOGRAPH + {0xFB69, 0x9E56}, //21529 #CJK UNIFIED IDEOGRAPH + {0xFB6A, 0x9E59}, //21530 #CJK UNIFIED IDEOGRAPH + {0xFB6B, 0x9E5D}, //21531 #CJK UNIFIED IDEOGRAPH + {0xFB6C, 0x9E5F}, //21532 #CJK UNIFIED IDEOGRAPH + {0xFB6D, 0x9E60}, //21533 #CJK UNIFIED IDEOGRAPH + {0xFB6E, 0x9E61}, //21534 #CJK UNIFIED IDEOGRAPH + {0xFB6F, 0x9E62}, //21535 #CJK UNIFIED IDEOGRAPH + {0xFB70, 0x9E65}, //21536 #CJK UNIFIED IDEOGRAPH + {0xFB71, 0x9E6E}, //21537 #CJK UNIFIED IDEOGRAPH + {0xFB72, 0x9E6F}, //21538 #CJK UNIFIED IDEOGRAPH + {0xFB73, 0x9E72}, //21539 #CJK UNIFIED IDEOGRAPH + {0xFB74, 0x9E74}, //21540 #CJK UNIFIED IDEOGRAPH + {0xFB75, 0x9E75}, //21541 #CJK UNIFIED IDEOGRAPH + {0xFB76, 0x9E76}, //21542 #CJK UNIFIED IDEOGRAPH + {0xFB77, 0x9E77}, //21543 #CJK UNIFIED IDEOGRAPH + {0xFB78, 0x9E78}, //21544 #CJK UNIFIED IDEOGRAPH + {0xFB79, 0x9E79}, //21545 #CJK UNIFIED IDEOGRAPH + {0xFB7A, 0x9E7A}, //21546 #CJK UNIFIED IDEOGRAPH + {0xFB7B, 0x9E7B}, //21547 #CJK UNIFIED IDEOGRAPH + {0xFB7C, 0x9E7C}, //21548 #CJK UNIFIED IDEOGRAPH + {0xFB7D, 0x9E7D}, //21549 #CJK UNIFIED IDEOGRAPH + {0xFB7E, 0x9E80}, //21550 #CJK UNIFIED IDEOGRAPH + {0xFB80, 0x9E81}, //21551 #CJK UNIFIED IDEOGRAPH + {0xFB81, 0x9E83}, //21552 #CJK UNIFIED IDEOGRAPH + {0xFB82, 0x9E84}, //21553 #CJK UNIFIED IDEOGRAPH + {0xFB83, 0x9E85}, //21554 #CJK UNIFIED IDEOGRAPH + {0xFB84, 0x9E86}, //21555 #CJK UNIFIED IDEOGRAPH + {0xFB85, 0x9E89}, //21556 #CJK UNIFIED IDEOGRAPH + {0xFB86, 0x9E8A}, //21557 #CJK UNIFIED IDEOGRAPH + {0xFB87, 0x9E8C}, //21558 #CJK UNIFIED IDEOGRAPH + {0xFB88, 0x9E8D}, //21559 #CJK UNIFIED IDEOGRAPH + {0xFB89, 0x9E8E}, //21560 #CJK UNIFIED IDEOGRAPH + {0xFB8A, 0x9E8F}, //21561 #CJK UNIFIED IDEOGRAPH + {0xFB8B, 0x9E90}, //21562 #CJK UNIFIED IDEOGRAPH + {0xFB8C, 0x9E91}, //21563 #CJK UNIFIED IDEOGRAPH + {0xFB8D, 0x9E94}, //21564 #CJK UNIFIED IDEOGRAPH + {0xFB8E, 0x9E95}, //21565 #CJK UNIFIED IDEOGRAPH + {0xFB8F, 0x9E96}, //21566 #CJK UNIFIED IDEOGRAPH + {0xFB90, 0x9E97}, //21567 #CJK UNIFIED IDEOGRAPH + {0xFB91, 0x9E98}, //21568 #CJK UNIFIED IDEOGRAPH + {0xFB92, 0x9E99}, //21569 #CJK UNIFIED IDEOGRAPH + {0xFB93, 0x9E9A}, //21570 #CJK UNIFIED IDEOGRAPH + {0xFB94, 0x9E9B}, //21571 #CJK UNIFIED IDEOGRAPH + {0xFB95, 0x9E9C}, //21572 #CJK UNIFIED IDEOGRAPH + {0xFB96, 0x9E9E}, //21573 #CJK UNIFIED IDEOGRAPH + {0xFB97, 0x9EA0}, //21574 #CJK UNIFIED IDEOGRAPH + {0xFB98, 0x9EA1}, //21575 #CJK UNIFIED IDEOGRAPH + {0xFB99, 0x9EA2}, //21576 #CJK UNIFIED IDEOGRAPH + {0xFB9A, 0x9EA3}, //21577 #CJK UNIFIED IDEOGRAPH + {0xFB9B, 0x9EA4}, //21578 #CJK UNIFIED IDEOGRAPH + {0xFB9C, 0x9EA5}, //21579 #CJK UNIFIED IDEOGRAPH + {0xFB9D, 0x9EA7}, //21580 #CJK UNIFIED IDEOGRAPH + {0xFB9E, 0x9EA8}, //21581 #CJK UNIFIED IDEOGRAPH + {0xFB9F, 0x9EA9}, //21582 #CJK UNIFIED IDEOGRAPH + {0xFBA0, 0x9EAA}, //21583 #CJK UNIFIED IDEOGRAPH + {0xFC40, 0x9EAB}, //21584 #CJK UNIFIED IDEOGRAPH + {0xFC41, 0x9EAC}, //21585 #CJK UNIFIED IDEOGRAPH + {0xFC42, 0x9EAD}, //21586 #CJK UNIFIED IDEOGRAPH + {0xFC43, 0x9EAE}, //21587 #CJK UNIFIED IDEOGRAPH + {0xFC44, 0x9EAF}, //21588 #CJK UNIFIED IDEOGRAPH + {0xFC45, 0x9EB0}, //21589 #CJK UNIFIED IDEOGRAPH + {0xFC46, 0x9EB1}, //21590 #CJK UNIFIED IDEOGRAPH + {0xFC47, 0x9EB2}, //21591 #CJK UNIFIED IDEOGRAPH + {0xFC48, 0x9EB3}, //21592 #CJK UNIFIED IDEOGRAPH + {0xFC49, 0x9EB5}, //21593 #CJK UNIFIED IDEOGRAPH + {0xFC4A, 0x9EB6}, //21594 #CJK UNIFIED IDEOGRAPH + {0xFC4B, 0x9EB7}, //21595 #CJK UNIFIED IDEOGRAPH + {0xFC4C, 0x9EB9}, //21596 #CJK UNIFIED IDEOGRAPH + {0xFC4D, 0x9EBA}, //21597 #CJK UNIFIED IDEOGRAPH + {0xFC4E, 0x9EBC}, //21598 #CJK UNIFIED IDEOGRAPH + {0xFC4F, 0x9EBF}, //21599 #CJK UNIFIED IDEOGRAPH + {0xFC50, 0x9EC0}, //21600 #CJK UNIFIED IDEOGRAPH + {0xFC51, 0x9EC1}, //21601 #CJK UNIFIED IDEOGRAPH + {0xFC52, 0x9EC2}, //21602 #CJK UNIFIED IDEOGRAPH + {0xFC53, 0x9EC3}, //21603 #CJK UNIFIED IDEOGRAPH + {0xFC54, 0x9EC5}, //21604 #CJK UNIFIED IDEOGRAPH + {0xFC55, 0x9EC6}, //21605 #CJK UNIFIED IDEOGRAPH + {0xFC56, 0x9EC7}, //21606 #CJK UNIFIED IDEOGRAPH + {0xFC57, 0x9EC8}, //21607 #CJK UNIFIED IDEOGRAPH + {0xFC58, 0x9ECA}, //21608 #CJK UNIFIED IDEOGRAPH + {0xFC59, 0x9ECB}, //21609 #CJK UNIFIED IDEOGRAPH + {0xFC5A, 0x9ECC}, //21610 #CJK UNIFIED IDEOGRAPH + {0xFC5B, 0x9ED0}, //21611 #CJK UNIFIED IDEOGRAPH + {0xFC5C, 0x9ED2}, //21612 #CJK UNIFIED IDEOGRAPH + {0xFC5D, 0x9ED3}, //21613 #CJK UNIFIED IDEOGRAPH + {0xFC5E, 0x9ED5}, //21614 #CJK UNIFIED IDEOGRAPH + {0xFC5F, 0x9ED6}, //21615 #CJK UNIFIED IDEOGRAPH + {0xFC60, 0x9ED7}, //21616 #CJK UNIFIED IDEOGRAPH + {0xFC61, 0x9ED9}, //21617 #CJK UNIFIED IDEOGRAPH + {0xFC62, 0x9EDA}, //21618 #CJK UNIFIED IDEOGRAPH + {0xFC63, 0x9EDE}, //21619 #CJK UNIFIED IDEOGRAPH + {0xFC64, 0x9EE1}, //21620 #CJK UNIFIED IDEOGRAPH + {0xFC65, 0x9EE3}, //21621 #CJK UNIFIED IDEOGRAPH + {0xFC66, 0x9EE4}, //21622 #CJK UNIFIED IDEOGRAPH + {0xFC67, 0x9EE6}, //21623 #CJK UNIFIED IDEOGRAPH + {0xFC68, 0x9EE8}, //21624 #CJK UNIFIED IDEOGRAPH + {0xFC69, 0x9EEB}, //21625 #CJK UNIFIED IDEOGRAPH + {0xFC6A, 0x9EEC}, //21626 #CJK UNIFIED IDEOGRAPH + {0xFC6B, 0x9EED}, //21627 #CJK UNIFIED IDEOGRAPH + {0xFC6C, 0x9EEE}, //21628 #CJK UNIFIED IDEOGRAPH + {0xFC6D, 0x9EF0}, //21629 #CJK UNIFIED IDEOGRAPH + {0xFC6E, 0x9EF1}, //21630 #CJK UNIFIED IDEOGRAPH + {0xFC6F, 0x9EF2}, //21631 #CJK UNIFIED IDEOGRAPH + {0xFC70, 0x9EF3}, //21632 #CJK UNIFIED IDEOGRAPH + {0xFC71, 0x9EF4}, //21633 #CJK UNIFIED IDEOGRAPH + {0xFC72, 0x9EF5}, //21634 #CJK UNIFIED IDEOGRAPH + {0xFC73, 0x9EF6}, //21635 #CJK UNIFIED IDEOGRAPH + {0xFC74, 0x9EF7}, //21636 #CJK UNIFIED IDEOGRAPH + {0xFC75, 0x9EF8}, //21637 #CJK UNIFIED IDEOGRAPH + {0xFC76, 0x9EFA}, //21638 #CJK UNIFIED IDEOGRAPH + {0xFC77, 0x9EFD}, //21639 #CJK UNIFIED IDEOGRAPH + {0xFC78, 0x9EFF}, //21640 #CJK UNIFIED IDEOGRAPH + {0xFC79, 0x9F00}, //21641 #CJK UNIFIED IDEOGRAPH + {0xFC7A, 0x9F01}, //21642 #CJK UNIFIED IDEOGRAPH + {0xFC7B, 0x9F02}, //21643 #CJK UNIFIED IDEOGRAPH + {0xFC7C, 0x9F03}, //21644 #CJK UNIFIED IDEOGRAPH + {0xFC7D, 0x9F04}, //21645 #CJK UNIFIED IDEOGRAPH + {0xFC7E, 0x9F05}, //21646 #CJK UNIFIED IDEOGRAPH + {0xFC80, 0x9F06}, //21647 #CJK UNIFIED IDEOGRAPH + {0xFC81, 0x9F07}, //21648 #CJK UNIFIED IDEOGRAPH + {0xFC82, 0x9F08}, //21649 #CJK UNIFIED IDEOGRAPH + {0xFC83, 0x9F09}, //21650 #CJK UNIFIED IDEOGRAPH + {0xFC84, 0x9F0A}, //21651 #CJK UNIFIED IDEOGRAPH + {0xFC85, 0x9F0C}, //21652 #CJK UNIFIED IDEOGRAPH + {0xFC86, 0x9F0F}, //21653 #CJK UNIFIED IDEOGRAPH + {0xFC87, 0x9F11}, //21654 #CJK UNIFIED IDEOGRAPH + {0xFC88, 0x9F12}, //21655 #CJK UNIFIED IDEOGRAPH + {0xFC89, 0x9F14}, //21656 #CJK UNIFIED IDEOGRAPH + {0xFC8A, 0x9F15}, //21657 #CJK UNIFIED IDEOGRAPH + {0xFC8B, 0x9F16}, //21658 #CJK UNIFIED IDEOGRAPH + {0xFC8C, 0x9F18}, //21659 #CJK UNIFIED IDEOGRAPH + {0xFC8D, 0x9F1A}, //21660 #CJK UNIFIED IDEOGRAPH + {0xFC8E, 0x9F1B}, //21661 #CJK UNIFIED IDEOGRAPH + {0xFC8F, 0x9F1C}, //21662 #CJK UNIFIED IDEOGRAPH + {0xFC90, 0x9F1D}, //21663 #CJK UNIFIED IDEOGRAPH + {0xFC91, 0x9F1E}, //21664 #CJK UNIFIED IDEOGRAPH + {0xFC92, 0x9F1F}, //21665 #CJK UNIFIED IDEOGRAPH + {0xFC93, 0x9F21}, //21666 #CJK UNIFIED IDEOGRAPH + {0xFC94, 0x9F23}, //21667 #CJK UNIFIED IDEOGRAPH + {0xFC95, 0x9F24}, //21668 #CJK UNIFIED IDEOGRAPH + {0xFC96, 0x9F25}, //21669 #CJK UNIFIED IDEOGRAPH + {0xFC97, 0x9F26}, //21670 #CJK UNIFIED IDEOGRAPH + {0xFC98, 0x9F27}, //21671 #CJK UNIFIED IDEOGRAPH + {0xFC99, 0x9F28}, //21672 #CJK UNIFIED IDEOGRAPH + {0xFC9A, 0x9F29}, //21673 #CJK UNIFIED IDEOGRAPH + {0xFC9B, 0x9F2A}, //21674 #CJK UNIFIED IDEOGRAPH + {0xFC9C, 0x9F2B}, //21675 #CJK UNIFIED IDEOGRAPH + {0xFC9D, 0x9F2D}, //21676 #CJK UNIFIED IDEOGRAPH + {0xFC9E, 0x9F2E}, //21677 #CJK UNIFIED IDEOGRAPH + {0xFC9F, 0x9F30}, //21678 #CJK UNIFIED IDEOGRAPH + {0xFCA0, 0x9F31}, //21679 #CJK UNIFIED IDEOGRAPH + {0xFD40, 0x9F32}, //21680 #CJK UNIFIED IDEOGRAPH + {0xFD41, 0x9F33}, //21681 #CJK UNIFIED IDEOGRAPH + {0xFD42, 0x9F34}, //21682 #CJK UNIFIED IDEOGRAPH + {0xFD43, 0x9F35}, //21683 #CJK UNIFIED IDEOGRAPH + {0xFD44, 0x9F36}, //21684 #CJK UNIFIED IDEOGRAPH + {0xFD45, 0x9F38}, //21685 #CJK UNIFIED IDEOGRAPH + {0xFD46, 0x9F3A}, //21686 #CJK UNIFIED IDEOGRAPH + {0xFD47, 0x9F3C}, //21687 #CJK UNIFIED IDEOGRAPH + {0xFD48, 0x9F3F}, //21688 #CJK UNIFIED IDEOGRAPH + {0xFD49, 0x9F40}, //21689 #CJK UNIFIED IDEOGRAPH + {0xFD4A, 0x9F41}, //21690 #CJK UNIFIED IDEOGRAPH + {0xFD4B, 0x9F42}, //21691 #CJK UNIFIED IDEOGRAPH + {0xFD4C, 0x9F43}, //21692 #CJK UNIFIED IDEOGRAPH + {0xFD4D, 0x9F45}, //21693 #CJK UNIFIED IDEOGRAPH + {0xFD4E, 0x9F46}, //21694 #CJK UNIFIED IDEOGRAPH + {0xFD4F, 0x9F47}, //21695 #CJK UNIFIED IDEOGRAPH + {0xFD50, 0x9F48}, //21696 #CJK UNIFIED IDEOGRAPH + {0xFD51, 0x9F49}, //21697 #CJK UNIFIED IDEOGRAPH + {0xFD52, 0x9F4A}, //21698 #CJK UNIFIED IDEOGRAPH + {0xFD53, 0x9F4B}, //21699 #CJK UNIFIED IDEOGRAPH + {0xFD54, 0x9F4C}, //21700 #CJK UNIFIED IDEOGRAPH + {0xFD55, 0x9F4D}, //21701 #CJK UNIFIED IDEOGRAPH + {0xFD56, 0x9F4E}, //21702 #CJK UNIFIED IDEOGRAPH + {0xFD57, 0x9F4F}, //21703 #CJK UNIFIED IDEOGRAPH + {0xFD58, 0x9F52}, //21704 #CJK UNIFIED IDEOGRAPH + {0xFD59, 0x9F53}, //21705 #CJK UNIFIED IDEOGRAPH + {0xFD5A, 0x9F54}, //21706 #CJK UNIFIED IDEOGRAPH + {0xFD5B, 0x9F55}, //21707 #CJK UNIFIED IDEOGRAPH + {0xFD5C, 0x9F56}, //21708 #CJK UNIFIED IDEOGRAPH + {0xFD5D, 0x9F57}, //21709 #CJK UNIFIED IDEOGRAPH + {0xFD5E, 0x9F58}, //21710 #CJK UNIFIED IDEOGRAPH + {0xFD5F, 0x9F59}, //21711 #CJK UNIFIED IDEOGRAPH + {0xFD60, 0x9F5A}, //21712 #CJK UNIFIED IDEOGRAPH + {0xFD61, 0x9F5B}, //21713 #CJK UNIFIED IDEOGRAPH + {0xFD62, 0x9F5C}, //21714 #CJK UNIFIED IDEOGRAPH + {0xFD63, 0x9F5D}, //21715 #CJK UNIFIED IDEOGRAPH + {0xFD64, 0x9F5E}, //21716 #CJK UNIFIED IDEOGRAPH + {0xFD65, 0x9F5F}, //21717 #CJK UNIFIED IDEOGRAPH + {0xFD66, 0x9F60}, //21718 #CJK UNIFIED IDEOGRAPH + {0xFD67, 0x9F61}, //21719 #CJK UNIFIED IDEOGRAPH + {0xFD68, 0x9F62}, //21720 #CJK UNIFIED IDEOGRAPH + {0xFD69, 0x9F63}, //21721 #CJK UNIFIED IDEOGRAPH + {0xFD6A, 0x9F64}, //21722 #CJK UNIFIED IDEOGRAPH + {0xFD6B, 0x9F65}, //21723 #CJK UNIFIED IDEOGRAPH + {0xFD6C, 0x9F66}, //21724 #CJK UNIFIED IDEOGRAPH + {0xFD6D, 0x9F67}, //21725 #CJK UNIFIED IDEOGRAPH + {0xFD6E, 0x9F68}, //21726 #CJK UNIFIED IDEOGRAPH + {0xFD6F, 0x9F69}, //21727 #CJK UNIFIED IDEOGRAPH + {0xFD70, 0x9F6A}, //21728 #CJK UNIFIED IDEOGRAPH + {0xFD71, 0x9F6B}, //21729 #CJK UNIFIED IDEOGRAPH + {0xFD72, 0x9F6C}, //21730 #CJK UNIFIED IDEOGRAPH + {0xFD73, 0x9F6D}, //21731 #CJK UNIFIED IDEOGRAPH + {0xFD74, 0x9F6E}, //21732 #CJK UNIFIED IDEOGRAPH + {0xFD75, 0x9F6F}, //21733 #CJK UNIFIED IDEOGRAPH + {0xFD76, 0x9F70}, //21734 #CJK UNIFIED IDEOGRAPH + {0xFD77, 0x9F71}, //21735 #CJK UNIFIED IDEOGRAPH + {0xFD78, 0x9F72}, //21736 #CJK UNIFIED IDEOGRAPH + {0xFD79, 0x9F73}, //21737 #CJK UNIFIED IDEOGRAPH + {0xFD7A, 0x9F74}, //21738 #CJK UNIFIED IDEOGRAPH + {0xFD7B, 0x9F75}, //21739 #CJK UNIFIED IDEOGRAPH + {0xFD7C, 0x9F76}, //21740 #CJK UNIFIED IDEOGRAPH + {0xFD7D, 0x9F77}, //21741 #CJK UNIFIED IDEOGRAPH + {0xFD7E, 0x9F78}, //21742 #CJK UNIFIED IDEOGRAPH + {0xFD80, 0x9F79}, //21743 #CJK UNIFIED IDEOGRAPH + {0xFD81, 0x9F7A}, //21744 #CJK UNIFIED IDEOGRAPH + {0xFD82, 0x9F7B}, //21745 #CJK UNIFIED IDEOGRAPH + {0xFD83, 0x9F7C}, //21746 #CJK UNIFIED IDEOGRAPH + {0xFD84, 0x9F7D}, //21747 #CJK UNIFIED IDEOGRAPH + {0xFD85, 0x9F7E}, //21748 #CJK UNIFIED IDEOGRAPH + {0xFD86, 0x9F81}, //21749 #CJK UNIFIED IDEOGRAPH + {0xFD87, 0x9F82}, //21750 #CJK UNIFIED IDEOGRAPH + {0xFD88, 0x9F8D}, //21751 #CJK UNIFIED IDEOGRAPH + {0xFD89, 0x9F8E}, //21752 #CJK UNIFIED IDEOGRAPH + {0xFD8A, 0x9F8F}, //21753 #CJK UNIFIED IDEOGRAPH + {0xFD8B, 0x9F90}, //21754 #CJK UNIFIED IDEOGRAPH + {0xFD8C, 0x9F91}, //21755 #CJK UNIFIED IDEOGRAPH + {0xFD8D, 0x9F92}, //21756 #CJK UNIFIED IDEOGRAPH + {0xFD8E, 0x9F93}, //21757 #CJK UNIFIED IDEOGRAPH + {0xFD8F, 0x9F94}, //21758 #CJK UNIFIED IDEOGRAPH + {0xFD90, 0x9F95}, //21759 #CJK UNIFIED IDEOGRAPH + {0xFD91, 0x9F96}, //21760 #CJK UNIFIED IDEOGRAPH + {0xFD92, 0x9F97}, //21761 #CJK UNIFIED IDEOGRAPH + {0xFD93, 0x9F98}, //21762 #CJK UNIFIED IDEOGRAPH + {0xFD94, 0x9F9C}, //21763 #CJK UNIFIED IDEOGRAPH + {0xFD95, 0x9F9D}, //21764 #CJK UNIFIED IDEOGRAPH + {0xFD96, 0x9F9E}, //21765 #CJK UNIFIED IDEOGRAPH + {0xFD97, 0x9FA1}, //21766 #CJK UNIFIED IDEOGRAPH + {0xFD98, 0x9FA2}, //21767 #CJK UNIFIED IDEOGRAPH + {0xFD99, 0x9FA3}, //21768 #CJK UNIFIED IDEOGRAPH + {0xFD9A, 0x9FA4}, //21769 #CJK UNIFIED IDEOGRAPH + {0xFD9B, 0x9FA5}, //21770 #CJK UNIFIED IDEOGRAPH + {0xFD9C, 0xF92C}, //21771 #CJK COMPATIBILITY IDEOGRAPH + {0xFD9D, 0xF979}, //21772 #CJK COMPATIBILITY IDEOGRAPH + {0xFD9E, 0xF995}, //21773 #CJK COMPATIBILITY IDEOGRAPH + {0xFD9F, 0xF9E7}, //21774 #CJK COMPATIBILITY IDEOGRAPH + {0xFDA0, 0xF9F1}, //21775 #CJK COMPATIBILITY IDEOGRAPH + {0xFE40, 0xFA0C}, //21776 #CJK COMPATIBILITY IDEOGRAPH + {0xFE41, 0xFA0D}, //21777 #CJK COMPATIBILITY IDEOGRAPH + {0xFE42, 0xFA0E}, //21778 #CJK COMPATIBILITY IDEOGRAPH + {0xFE43, 0xFA0F}, //21779 #CJK COMPATIBILITY IDEOGRAPH + {0xFE44, 0xFA11}, //21780 #CJK COMPATIBILITY IDEOGRAPH + {0xFE45, 0xFA13}, //21781 #CJK COMPATIBILITY IDEOGRAPH + {0xFE46, 0xFA14}, //21782 #CJK COMPATIBILITY IDEOGRAPH + {0xFE47, 0xFA18}, //21783 #CJK COMPATIBILITY IDEOGRAPH + {0xFE48, 0xFA1F}, //21784 #CJK COMPATIBILITY IDEOGRAPH + {0xFE49, 0xFA20}, //21785 #CJK COMPATIBILITY IDEOGRAPH + {0xFE4A, 0xFA21}, //21786 #CJK COMPATIBILITY IDEOGRAPH + {0xFE4B, 0xFA23}, //21787 #CJK COMPATIBILITY IDEOGRAPH + {0xFE4C, 0xFA24}, //21788 #CJK COMPATIBILITY IDEOGRAPH + {0xFE4D, 0xFA27}, //21789 #CJK COMPATIBILITY IDEOGRAPH + {0xFE4E, 0xFA28}, //21790 #CJK COMPATIBILITY IDEOGRAPH + {0xFE4F, 0xFA29} //21791 #CJK COMPATIBILITY IDEOGRAPH +}; + +#endif // DRW_CPTABLE936_H diff --git a/extlib/libdxfrw/intern/drw_cptable949.h b/extlib/libdxfrw/intern/drw_cptable949.h new file mode 100644 index 0000000..5364bea --- /dev/null +++ b/extlib/libdxfrw/intern/drw_cptable949.h @@ -0,0 +1,17199 @@ +#ifndef DRW_CPTABLE949_H +#define DRW_CPTABLE949_H + +//Korean Extended Wansung + +//first entry in this table are 0x80 +#define CPOFFSET949 0x80 +#define CPLENGTH949 17048 +#define NOTFOUND949 0x003F + +//Table 949 one byte +static const int DRW_Table949[1] = { +}; + +//Table 949 lead byte +//pairs of start/end in DRW_DoubleTable949 +static const int DRW_LeadTable949[] = { + 0, //1#DBCS LEAD BYTE 0x81 + 178, //2#DBCS LEAD BYTE 0x82 + 356, //3#DBCS LEAD BYTE 0x83 + 564, //4#DBCS LEAD BYTE 0x84 + 712, //5#DBCS LEAD BYTE 0x85 + 890, //6#DBCS LEAD BYTE 0x86 + 1068, //7#DBCS LEAD BYTE 0x87 + 1246, //8#DBCS LEAD BYTE 0x88 + 1424, //9#DBCS LEAD BYTE 0x89 + 1602, //10#DBCS LEAD BYTE 0x8A + 1780, //11#DBCS LEAD BYTE 0x8B + 1958, //12#DBCS LEAD BYTE 0x8C + 2136, //13#DBCS LEAD BYTE 0x8D + 2314, //14#DBCS LEAD BYTE 0x8E + 2492, //15#DBCS LEAD BYTE 0x8F + 2670, //16#DBCS LEAD BYTE 0x90 + 2848, //17#DBCS LEAD BYTE 0x91 + 3026, //18#DBCS LEAD BYTE 0x92 + 3204, //19#DBCS LEAD BYTE 0x93 + 3382, //20#DBCS LEAD BYTE 0x94 + 3560, //21#DBCS LEAD BYTE 0x95 + 3738, //22#DBCS LEAD BYTE 0x96 + 3916, //23#DBCS LEAD BYTE 0x97 + 4094, //24#DBCS LEAD BYTE 0x98 + 4272, //25#DBCS LEAD BYTE 0x99 + 4450, //26#DBCS LEAD BYTE 0x9A + 4628, //27#DBCS LEAD BYTE 0x9B + 4806, //28#DBCS LEAD BYTE 0x9C + 4984, //29#DBCS LEAD BYTE 0x9D + 5162, //30#DBCS LEAD BYTE 0x9E + 5340, //31#DBCS LEAD BYTE 0x9F + 5518, //32#DBCS LEAD BYTE 0xA0 + 5696, //33#DBCS LEAD BYTE 0xA1 + 5874, //34#DBCS LEAD BYTE 0xA2 + 6029, //35#DBCS LEAD BYTE 0xA3 + 6207, //36#DBCS LEAD BYTE 0xA4 + 6385, //37#DBCS LEAD BYTE 0xA5 + 6537, //38#DBCS LEAD BYTE 0xA6 + 6689, //39#DBCS LEAD BYTE 0xA7 + 6852, //40#DBCS LEAD BYTE 0xA8 + 7027, //41#DBCS LEAD BYTE 0xA9 + 7205, //42#DBCS LEAD BYTE 0xAA + 7372, //43#DBCS LEAD BYTE 0xAB + 7542, //44#DBCS LEAD BYTE 0xAC + 7692, //45#DBCS LEAD BYTE 0xAD + 7776, //46#DBCS LEAD BYTE 0xAE + 7860, //47#DBCS LEAD BYTE 0xAF + 7944, //48#DBCS LEAD BYTE 0xB0 + 8122, //49#DBCS LEAD BYTE 0xB1 + 8300, //50#DBCS LEAD BYTE 0xB2 + 8478, //51#DBCS LEAD BYTE 0xB3 + 8656, //52#DBCS LEAD BYTE 0xB4 + 8834, //53#DBCS LEAD BYTE 0xB5 + 9012, //54#DBCS LEAD BYTE 0xB6 + 9190, //55#DBCS LEAD BYTE 0xB7 + 9368, //56#DBCS LEAD BYTE 0xB8 + 9546, //57#DBCS LEAD BYTE 0xB9 + 9724, //58#DBCS LEAD BYTE 0xBA + 9902, //59#DBCS LEAD BYTE 0xBB + 10080, //60#DBCS LEAD BYTE 0xBC + 10258, //61#DBCS LEAD BYTE 0xBD + 10436, //62#DBCS LEAD BYTE 0xBE + 10614, //63#DBCS LEAD BYTE 0xBF + 10792, //64#DBCS LEAD BYTE 0xC0 + 10970, //65#DBCS LEAD BYTE 0xC1 + 11148, //66#DBCS LEAD BYTE 0xC2 + 11326, //67#DBCS LEAD BYTE 0xC3 + 11504, //68#DBCS LEAD BYTE 0xC4 + 11682, //69#DBCS LEAD BYTE 0xC5 + 11860, //70#DBCS LEAD BYTE 0xC6 + 11972, //71#DBCS LEAD BYTE 0xC7 + 12066, //72#DBCS LEAD BYTE 0xC8 + 12160, //73#DBCS LEAD BYTE 0xC9, empty + 12160, //74#DBCS LEAD BYTE 0xCA + 12254, //75#DBCS LEAD BYTE 0xCB + 12348, //76#DBCS LEAD BYTE 0xCC + 12442, //77#DBCS LEAD BYTE 0xCD + 12536, //78#DBCS LEAD BYTE 0xCE + 12630, //79#DBCS LEAD BYTE 0xCF + 12724, //80#DBCS LEAD BYTE 0xD0 + 12818, //81#DBCS LEAD BYTE 0xD1 + 12912, //82#DBCS LEAD BYTE 0xD2 + 13006, //83#DBCS LEAD BYTE 0xD3 + 13100, //84#DBCS LEAD BYTE 0xD4 + 13194, //85#DBCS LEAD BYTE 0xD5 + 13288, //86#DBCS LEAD BYTE 0xD6 + 13382, //87#DBCS LEAD BYTE 0xD7 + 13476, //88#DBCS LEAD BYTE 0xD8 + 13570, //89#DBCS LEAD BYTE 0xD9 + 13664, //90#DBCS LEAD BYTE 0xDA + 13758, //91#DBCS LEAD BYTE 0xDB + 13852, //92#DBCS LEAD BYTE 0xDC + 13946, //93#DBCS LEAD BYTE 0xDD + 14040, //94#DBCS LEAD BYTE 0xDE + 14134, //95#DBCS LEAD BYTE 0xDF + 14228, //96#DBCS LEAD BYTE 0xE0 + 14322, //97#DBCS LEAD BYTE 0xE1 + 14416, //98#DBCS LEAD BYTE 0xE2 + 14510, //99#DBCS LEAD BYTE 0xE3 + 14604, //100#DBCS LEAD BYTE 0xE4 + 14698, //101#DBCS LEAD BYTE 0xE5 + 14792, //102#DBCS LEAD BYTE 0xE6 + 14886, //103#DBCS LEAD BYTE 0xE7 + 14980, //104#DBCS LEAD BYTE 0xE8 + 15074, //105#DBCS LEAD BYTE 0xE9 + 15168, //106#DBCS LEAD BYTE 0xEA + 15262, //107#DBCS LEAD BYTE 0xEB + 15356, //108#DBCS LEAD BYTE 0xEC + 15450, //109#DBCS LEAD BYTE 0xED + 15544, //110#DBCS LEAD BYTE 0xEE + 15638, //111#DBCS LEAD BYTE 0xEF + 15732, //112#DBCS LEAD BYTE 0xF0 + 15826, //113#DBCS LEAD BYTE 0xF1 + 15920, //114#DBCS LEAD BYTE 0xF2 + 16014, //115#DBCS LEAD BYTE 0xF3 + 16108, //116#DBCS LEAD BYTE 0xF4 + 16202, //117#DBCS LEAD BYTE 0xF5 + 16296, //118#DBCS LEAD BYTE 0xF6 + 16390, //119#DBCS LEAD BYTE 0xF7 + 16484, //120#DBCS LEAD BYTE 0xF8 + 16578, //121#DBCS LEAD BYTE 0xF9 + 16672, //122#DBCS LEAD BYTE 0xFA + 16766, //123#DBCS LEAD BYTE 0xFB + 16860, //124#DBCS LEAD BYTE 0xFC + 16954, //125#DBCS LEAD BYTE 0xFD + 17047, //126#DBCS LEAD BYTE 0xFE, empty + 17047, //127#UNDEFINED 0xFF, END OF TABLE +}; + +//Table 949 tail byte +static const int DRW_DoubleTable949[][2] = { + {0x8141, 0xAC02}, //1 #HANGUL SYLLABLE KIYEOK A SSANGKIYEOK + {0x8142, 0xAC03}, //2 #HANGUL SYLLABLE KIYEOK A KIYEOKSIOS + {0x8143, 0xAC05}, //3 #HANGUL SYLLABLE KIYEOK A NIEUNCIEUC + {0x8144, 0xAC06}, //4 #HANGUL SYLLABLE KIYEOK A NIEUNHIEUH + {0x8145, 0xAC0B}, //5 #HANGUL SYLLABLE KIYEOK A RIEULPIEUP + {0x8146, 0xAC0C}, //6 #HANGUL SYLLABLE KIYEOK A RIEULSIOS + {0x8147, 0xAC0D}, //7 #HANGUL SYLLABLE KIYEOK A RIEULTHIEUTH + {0x8148, 0xAC0E}, //8 #HANGUL SYLLABLE KIYEOK A RIEULPHIEUPH + {0x8149, 0xAC0F}, //9 #HANGUL SYLLABLE KIYEOK A RIEULHIEUH + {0x814A, 0xAC18}, //10 #HANGUL SYLLABLE KIYEOK A KHIEUKH + {0x814B, 0xAC1E}, //11 #HANGUL SYLLABLE KIYEOK AE SSANGKIYEOK + {0x814C, 0xAC1F}, //12 #HANGUL SYLLABLE KIYEOK AE KIYEOKSIOS + {0x814D, 0xAC21}, //13 #HANGUL SYLLABLE KIYEOK AE NIEUNCIEUC + {0x814E, 0xAC22}, //14 #HANGUL SYLLABLE KIYEOK AE NIEUNHIEUH + {0x814F, 0xAC23}, //15 #HANGUL SYLLABLE KIYEOK AE TIKEUT + {0x8150, 0xAC25}, //16 #HANGUL SYLLABLE KIYEOK AE RIEULKIYEOK + {0x8151, 0xAC26}, //17 #HANGUL SYLLABLE KIYEOK AE RIEULMIEUM + {0x8152, 0xAC27}, //18 #HANGUL SYLLABLE KIYEOK AE RIEULPIEUP + {0x8153, 0xAC28}, //19 #HANGUL SYLLABLE KIYEOK AE RIEULSIOS + {0x8154, 0xAC29}, //20 #HANGUL SYLLABLE KIYEOK AE RIEULTHIEUTH + {0x8155, 0xAC2A}, //21 #HANGUL SYLLABLE KIYEOK AE RIEULPHIEUPH + {0x8156, 0xAC2B}, //22 #HANGUL SYLLABLE KIYEOK AE RIEULHIEUH + {0x8157, 0xAC2E}, //23 #HANGUL SYLLABLE KIYEOK AE PIEUPSIOS + {0x8158, 0xAC32}, //24 #HANGUL SYLLABLE KIYEOK AE CIEUC + {0x8159, 0xAC33}, //25 #HANGUL SYLLABLE KIYEOK AE CHIEUCH + {0x815A, 0xAC34}, //26 #HANGUL SYLLABLE KIYEOK AE KHIEUKH + {0x8161, 0xAC35}, //27 #HANGUL SYLLABLE KIYEOK AE THIEUTH + {0x8162, 0xAC36}, //28 #HANGUL SYLLABLE KIYEOK AE PHIEUPH + {0x8163, 0xAC37}, //29 #HANGUL SYLLABLE KIYEOK AE HIEUH + {0x8164, 0xAC3A}, //30 #HANGUL SYLLABLE KIYEOK YA SSANGKIYEOK + {0x8165, 0xAC3B}, //31 #HANGUL SYLLABLE KIYEOK YA KIYEOKSIOS + {0x8166, 0xAC3D}, //32 #HANGUL SYLLABLE KIYEOK YA NIEUNCIEUC + {0x8167, 0xAC3E}, //33 #HANGUL SYLLABLE KIYEOK YA NIEUNHIEUH + {0x8168, 0xAC3F}, //34 #HANGUL SYLLABLE KIYEOK YA TIKEUT + {0x8169, 0xAC41}, //35 #HANGUL SYLLABLE KIYEOK YA RIEULKIYEOK + {0x816A, 0xAC42}, //36 #HANGUL SYLLABLE KIYEOK YA RIEULMIEUM + {0x816B, 0xAC43}, //37 #HANGUL SYLLABLE KIYEOK YA RIEULPIEUP + {0x816C, 0xAC44}, //38 #HANGUL SYLLABLE KIYEOK YA RIEULSIOS + {0x816D, 0xAC45}, //39 #HANGUL SYLLABLE KIYEOK YA RIEULTHIEUTH + {0x816E, 0xAC46}, //40 #HANGUL SYLLABLE KIYEOK YA RIEULPHIEUPH + {0x816F, 0xAC47}, //41 #HANGUL SYLLABLE KIYEOK YA RIEULHIEUH + {0x8170, 0xAC48}, //42 #HANGUL SYLLABLE KIYEOK YA MIEUM + {0x8171, 0xAC49}, //43 #HANGUL SYLLABLE KIYEOK YA PIEUP + {0x8172, 0xAC4A}, //44 #HANGUL SYLLABLE KIYEOK YA PIEUPSIOS + {0x8173, 0xAC4C}, //45 #HANGUL SYLLABLE KIYEOK YA SSANGSIOS + {0x8174, 0xAC4E}, //46 #HANGUL SYLLABLE KIYEOK YA CIEUC + {0x8175, 0xAC4F}, //47 #HANGUL SYLLABLE KIYEOK YA CHIEUCH + {0x8176, 0xAC50}, //48 #HANGUL SYLLABLE KIYEOK YA KHIEUKH + {0x8177, 0xAC51}, //49 #HANGUL SYLLABLE KIYEOK YA THIEUTH + {0x8178, 0xAC52}, //50 #HANGUL SYLLABLE KIYEOK YA PHIEUPH + {0x8179, 0xAC53}, //51 #HANGUL SYLLABLE KIYEOK YA HIEUH + {0x817A, 0xAC55}, //52 #HANGUL SYLLABLE KIYEOK YAE KIYEOK + {0x8181, 0xAC56}, //53 #HANGUL SYLLABLE KIYEOK YAE SSANGKIYEOK + {0x8182, 0xAC57}, //54 #HANGUL SYLLABLE KIYEOK YAE KIYEOKSIOS + {0x8183, 0xAC59}, //55 #HANGUL SYLLABLE KIYEOK YAE NIEUNCIEUC + {0x8184, 0xAC5A}, //56 #HANGUL SYLLABLE KIYEOK YAE NIEUNHIEUH + {0x8185, 0xAC5B}, //57 #HANGUL SYLLABLE KIYEOK YAE TIKEUT + {0x8186, 0xAC5D}, //58 #HANGUL SYLLABLE KIYEOK YAE RIEULKIYEOK + {0x8187, 0xAC5E}, //59 #HANGUL SYLLABLE KIYEOK YAE RIEULMIEUM + {0x8188, 0xAC5F}, //60 #HANGUL SYLLABLE KIYEOK YAE RIEULPIEUP + {0x8189, 0xAC60}, //61 #HANGUL SYLLABLE KIYEOK YAE RIEULSIOS + {0x818A, 0xAC61}, //62 #HANGUL SYLLABLE KIYEOK YAE RIEULTHIEUTH + {0x818B, 0xAC62}, //63 #HANGUL SYLLABLE KIYEOK YAE RIEULPHIEUPH + {0x818C, 0xAC63}, //64 #HANGUL SYLLABLE KIYEOK YAE RIEULHIEUH + {0x818D, 0xAC64}, //65 #HANGUL SYLLABLE KIYEOK YAE MIEUM + {0x818E, 0xAC65}, //66 #HANGUL SYLLABLE KIYEOK YAE PIEUP + {0x818F, 0xAC66}, //67 #HANGUL SYLLABLE KIYEOK YAE PIEUPSIOS + {0x8190, 0xAC67}, //68 #HANGUL SYLLABLE KIYEOK YAE SIOS + {0x8191, 0xAC68}, //69 #HANGUL SYLLABLE KIYEOK YAE SSANGSIOS + {0x8192, 0xAC69}, //70 #HANGUL SYLLABLE KIYEOK YAE IEUNG + {0x8193, 0xAC6A}, //71 #HANGUL SYLLABLE KIYEOK YAE CIEUC + {0x8194, 0xAC6B}, //72 #HANGUL SYLLABLE KIYEOK YAE CHIEUCH + {0x8195, 0xAC6C}, //73 #HANGUL SYLLABLE KIYEOK YAE KHIEUKH + {0x8196, 0xAC6D}, //74 #HANGUL SYLLABLE KIYEOK YAE THIEUTH + {0x8197, 0xAC6E}, //75 #HANGUL SYLLABLE KIYEOK YAE PHIEUPH + {0x8198, 0xAC6F}, //76 #HANGUL SYLLABLE KIYEOK YAE HIEUH + {0x8199, 0xAC72}, //77 #HANGUL SYLLABLE KIYEOK EO SSANGKIYEOK + {0x819A, 0xAC73}, //78 #HANGUL SYLLABLE KIYEOK EO KIYEOKSIOS + {0x819B, 0xAC75}, //79 #HANGUL SYLLABLE KIYEOK EO NIEUNCIEUC + {0x819C, 0xAC76}, //80 #HANGUL SYLLABLE KIYEOK EO NIEUNHIEUH + {0x819D, 0xAC79}, //81 #HANGUL SYLLABLE KIYEOK EO RIEULKIYEOK + {0x819E, 0xAC7B}, //82 #HANGUL SYLLABLE KIYEOK EO RIEULPIEUP + {0x819F, 0xAC7C}, //83 #HANGUL SYLLABLE KIYEOK EO RIEULSIOS + {0x81A0, 0xAC7D}, //84 #HANGUL SYLLABLE KIYEOK EO RIEULTHIEUTH + {0x81A1, 0xAC7E}, //85 #HANGUL SYLLABLE KIYEOK EO RIEULPHIEUPH + {0x81A2, 0xAC7F}, //86 #HANGUL SYLLABLE KIYEOK EO RIEULHIEUH + {0x81A3, 0xAC82}, //87 #HANGUL SYLLABLE KIYEOK EO PIEUPSIOS + {0x81A4, 0xAC87}, //88 #HANGUL SYLLABLE KIYEOK EO CHIEUCH + {0x81A5, 0xAC88}, //89 #HANGUL SYLLABLE KIYEOK EO KHIEUKH + {0x81A6, 0xAC8D}, //90 #HANGUL SYLLABLE KIYEOK E KIYEOK + {0x81A7, 0xAC8E}, //91 #HANGUL SYLLABLE KIYEOK E SSANGKIYEOK + {0x81A8, 0xAC8F}, //92 #HANGUL SYLLABLE KIYEOK E KIYEOKSIOS + {0x81A9, 0xAC91}, //93 #HANGUL SYLLABLE KIYEOK E NIEUNCIEUC + {0x81AA, 0xAC92}, //94 #HANGUL SYLLABLE KIYEOK E NIEUNHIEUH + {0x81AB, 0xAC93}, //95 #HANGUL SYLLABLE KIYEOK E TIKEUT + {0x81AC, 0xAC95}, //96 #HANGUL SYLLABLE KIYEOK E RIEULKIYEOK + {0x81AD, 0xAC96}, //97 #HANGUL SYLLABLE KIYEOK E RIEULMIEUM + {0x81AE, 0xAC97}, //98 #HANGUL SYLLABLE KIYEOK E RIEULPIEUP + {0x81AF, 0xAC98}, //99 #HANGUL SYLLABLE KIYEOK E RIEULSIOS + {0x81B0, 0xAC99}, //100 #HANGUL SYLLABLE KIYEOK E RIEULTHIEUTH + {0x81B1, 0xAC9A}, //101 #HANGUL SYLLABLE KIYEOK E RIEULPHIEUPH + {0x81B2, 0xAC9B}, //102 #HANGUL SYLLABLE KIYEOK E RIEULHIEUH + {0x81B3, 0xAC9E}, //103 #HANGUL SYLLABLE KIYEOK E PIEUPSIOS + {0x81B4, 0xACA2}, //104 #HANGUL SYLLABLE KIYEOK E CIEUC + {0x81B5, 0xACA3}, //105 #HANGUL SYLLABLE KIYEOK E CHIEUCH + {0x81B6, 0xACA4}, //106 #HANGUL SYLLABLE KIYEOK E KHIEUKH + {0x81B7, 0xACA5}, //107 #HANGUL SYLLABLE KIYEOK E THIEUTH + {0x81B8, 0xACA6}, //108 #HANGUL SYLLABLE KIYEOK E PHIEUPH + {0x81B9, 0xACA7}, //109 #HANGUL SYLLABLE KIYEOK E HIEUH + {0x81BA, 0xACAB}, //110 #HANGUL SYLLABLE KIYEOK YEO KIYEOKSIOS + {0x81BB, 0xACAD}, //111 #HANGUL SYLLABLE KIYEOK YEO NIEUNCIEUC + {0x81BC, 0xACAE}, //112 #HANGUL SYLLABLE KIYEOK YEO NIEUNHIEUH + {0x81BD, 0xACB1}, //113 #HANGUL SYLLABLE KIYEOK YEO RIEULKIYEOK + {0x81BE, 0xACB2}, //114 #HANGUL SYLLABLE KIYEOK YEO RIEULMIEUM + {0x81BF, 0xACB3}, //115 #HANGUL SYLLABLE KIYEOK YEO RIEULPIEUP + {0x81C0, 0xACB4}, //116 #HANGUL SYLLABLE KIYEOK YEO RIEULSIOS + {0x81C1, 0xACB5}, //117 #HANGUL SYLLABLE KIYEOK YEO RIEULTHIEUTH + {0x81C2, 0xACB6}, //118 #HANGUL SYLLABLE KIYEOK YEO RIEULPHIEUPH + {0x81C3, 0xACB7}, //119 #HANGUL SYLLABLE KIYEOK YEO RIEULHIEUH + {0x81C4, 0xACBA}, //120 #HANGUL SYLLABLE KIYEOK YEO PIEUPSIOS + {0x81C5, 0xACBE}, //121 #HANGUL SYLLABLE KIYEOK YEO CIEUC + {0x81C6, 0xACBF}, //122 #HANGUL SYLLABLE KIYEOK YEO CHIEUCH + {0x81C7, 0xACC0}, //123 #HANGUL SYLLABLE KIYEOK YEO KHIEUKH + {0x81C8, 0xACC2}, //124 #HANGUL SYLLABLE KIYEOK YEO PHIEUPH + {0x81C9, 0xACC3}, //125 #HANGUL SYLLABLE KIYEOK YEO HIEUH + {0x81CA, 0xACC5}, //126 #HANGUL SYLLABLE KIYEOK YE KIYEOK + {0x81CB, 0xACC6}, //127 #HANGUL SYLLABLE KIYEOK YE SSANGKIYEOK + {0x81CC, 0xACC7}, //128 #HANGUL SYLLABLE KIYEOK YE KIYEOKSIOS + {0x81CD, 0xACC9}, //129 #HANGUL SYLLABLE KIYEOK YE NIEUNCIEUC + {0x81CE, 0xACCA}, //130 #HANGUL SYLLABLE KIYEOK YE NIEUNHIEUH + {0x81CF, 0xACCB}, //131 #HANGUL SYLLABLE KIYEOK YE TIKEUT + {0x81D0, 0xACCD}, //132 #HANGUL SYLLABLE KIYEOK YE RIEULKIYEOK + {0x81D1, 0xACCE}, //133 #HANGUL SYLLABLE KIYEOK YE RIEULMIEUM + {0x81D2, 0xACCF}, //134 #HANGUL SYLLABLE KIYEOK YE RIEULPIEUP + {0x81D3, 0xACD0}, //135 #HANGUL SYLLABLE KIYEOK YE RIEULSIOS + {0x81D4, 0xACD1}, //136 #HANGUL SYLLABLE KIYEOK YE RIEULTHIEUTH + {0x81D5, 0xACD2}, //137 #HANGUL SYLLABLE KIYEOK YE RIEULPHIEUPH + {0x81D6, 0xACD3}, //138 #HANGUL SYLLABLE KIYEOK YE RIEULHIEUH + {0x81D7, 0xACD4}, //139 #HANGUL SYLLABLE KIYEOK YE MIEUM + {0x81D8, 0xACD6}, //140 #HANGUL SYLLABLE KIYEOK YE PIEUPSIOS + {0x81D9, 0xACD8}, //141 #HANGUL SYLLABLE KIYEOK YE SSANGSIOS + {0x81DA, 0xACD9}, //142 #HANGUL SYLLABLE KIYEOK YE IEUNG + {0x81DB, 0xACDA}, //143 #HANGUL SYLLABLE KIYEOK YE CIEUC + {0x81DC, 0xACDB}, //144 #HANGUL SYLLABLE KIYEOK YE CHIEUCH + {0x81DD, 0xACDC}, //145 #HANGUL SYLLABLE KIYEOK YE KHIEUKH + {0x81DE, 0xACDD}, //146 #HANGUL SYLLABLE KIYEOK YE THIEUTH + {0x81DF, 0xACDE}, //147 #HANGUL SYLLABLE KIYEOK YE PHIEUPH + {0x81E0, 0xACDF}, //148 #HANGUL SYLLABLE KIYEOK YE HIEUH + {0x81E1, 0xACE2}, //149 #HANGUL SYLLABLE KIYEOK O SSANGKIYEOK + {0x81E2, 0xACE3}, //150 #HANGUL SYLLABLE KIYEOK O KIYEOKSIOS + {0x81E3, 0xACE5}, //151 #HANGUL SYLLABLE KIYEOK O NIEUNCIEUC + {0x81E4, 0xACE6}, //152 #HANGUL SYLLABLE KIYEOK O NIEUNHIEUH + {0x81E5, 0xACE9}, //153 #HANGUL SYLLABLE KIYEOK O RIEULKIYEOK + {0x81E6, 0xACEB}, //154 #HANGUL SYLLABLE KIYEOK O RIEULPIEUP + {0x81E7, 0xACED}, //155 #HANGUL SYLLABLE KIYEOK O RIEULTHIEUTH + {0x81E8, 0xACEE}, //156 #HANGUL SYLLABLE KIYEOK O RIEULPHIEUPH + {0x81E9, 0xACF2}, //157 #HANGUL SYLLABLE KIYEOK O PIEUPSIOS + {0x81EA, 0xACF4}, //158 #HANGUL SYLLABLE KIYEOK O SSANGSIOS + {0x81EB, 0xACF7}, //159 #HANGUL SYLLABLE KIYEOK O CHIEUCH + {0x81EC, 0xACF8}, //160 #HANGUL SYLLABLE KIYEOK O KHIEUKH + {0x81ED, 0xACF9}, //161 #HANGUL SYLLABLE KIYEOK O THIEUTH + {0x81EE, 0xACFA}, //162 #HANGUL SYLLABLE KIYEOK O PHIEUPH + {0x81EF, 0xACFB}, //163 #HANGUL SYLLABLE KIYEOK O HIEUH + {0x81F0, 0xACFE}, //164 #HANGUL SYLLABLE KIYEOK WA SSANGKIYEOK + {0x81F1, 0xACFF}, //165 #HANGUL SYLLABLE KIYEOK WA KIYEOKSIOS + {0x81F2, 0xAD01}, //166 #HANGUL SYLLABLE KIYEOK WA NIEUNCIEUC + {0x81F3, 0xAD02}, //167 #HANGUL SYLLABLE KIYEOK WA NIEUNHIEUH + {0x81F4, 0xAD03}, //168 #HANGUL SYLLABLE KIYEOK WA TIKEUT + {0x81F5, 0xAD05}, //169 #HANGUL SYLLABLE KIYEOK WA RIEULKIYEOK + {0x81F6, 0xAD07}, //170 #HANGUL SYLLABLE KIYEOK WA RIEULPIEUP + {0x81F7, 0xAD08}, //171 #HANGUL SYLLABLE KIYEOK WA RIEULSIOS + {0x81F8, 0xAD09}, //172 #HANGUL SYLLABLE KIYEOK WA RIEULTHIEUTH + {0x81F9, 0xAD0A}, //173 #HANGUL SYLLABLE KIYEOK WA RIEULPHIEUPH + {0x81FA, 0xAD0B}, //174 #HANGUL SYLLABLE KIYEOK WA RIEULHIEUH + {0x81FB, 0xAD0E}, //175 #HANGUL SYLLABLE KIYEOK WA PIEUPSIOS + {0x81FC, 0xAD10}, //176 #HANGUL SYLLABLE KIYEOK WA SSANGSIOS + {0x81FD, 0xAD12}, //177 #HANGUL SYLLABLE KIYEOK WA CIEUC + {0x81FE, 0xAD13}, //178 #HANGUL SYLLABLE KIYEOK WA CHIEUCH + {0x8241, 0xAD14}, //179 #HANGUL SYLLABLE KIYEOK WA KHIEUKH + {0x8242, 0xAD15}, //180 #HANGUL SYLLABLE KIYEOK WA THIEUTH + {0x8243, 0xAD16}, //181 #HANGUL SYLLABLE KIYEOK WA PHIEUPH + {0x8244, 0xAD17}, //182 #HANGUL SYLLABLE KIYEOK WA HIEUH + {0x8245, 0xAD19}, //183 #HANGUL SYLLABLE KIYEOK WAE KIYEOK + {0x8246, 0xAD1A}, //184 #HANGUL SYLLABLE KIYEOK WAE SSANGKIYEOK + {0x8247, 0xAD1B}, //185 #HANGUL SYLLABLE KIYEOK WAE KIYEOKSIOS + {0x8248, 0xAD1D}, //186 #HANGUL SYLLABLE KIYEOK WAE NIEUNCIEUC + {0x8249, 0xAD1E}, //187 #HANGUL SYLLABLE KIYEOK WAE NIEUNHIEUH + {0x824A, 0xAD1F}, //188 #HANGUL SYLLABLE KIYEOK WAE TIKEUT + {0x824B, 0xAD21}, //189 #HANGUL SYLLABLE KIYEOK WAE RIEULKIYEOK + {0x824C, 0xAD22}, //190 #HANGUL SYLLABLE KIYEOK WAE RIEULMIEUM + {0x824D, 0xAD23}, //191 #HANGUL SYLLABLE KIYEOK WAE RIEULPIEUP + {0x824E, 0xAD24}, //192 #HANGUL SYLLABLE KIYEOK WAE RIEULSIOS + {0x824F, 0xAD25}, //193 #HANGUL SYLLABLE KIYEOK WAE RIEULTHIEUTH + {0x8250, 0xAD26}, //194 #HANGUL SYLLABLE KIYEOK WAE RIEULPHIEUPH + {0x8251, 0xAD27}, //195 #HANGUL SYLLABLE KIYEOK WAE RIEULHIEUH + {0x8252, 0xAD28}, //196 #HANGUL SYLLABLE KIYEOK WAE MIEUM + {0x8253, 0xAD2A}, //197 #HANGUL SYLLABLE KIYEOK WAE PIEUPSIOS + {0x8254, 0xAD2B}, //198 #HANGUL SYLLABLE KIYEOK WAE SIOS + {0x8255, 0xAD2E}, //199 #HANGUL SYLLABLE KIYEOK WAE CIEUC + {0x8256, 0xAD2F}, //200 #HANGUL SYLLABLE KIYEOK WAE CHIEUCH + {0x8257, 0xAD30}, //201 #HANGUL SYLLABLE KIYEOK WAE KHIEUKH + {0x8258, 0xAD31}, //202 #HANGUL SYLLABLE KIYEOK WAE THIEUTH + {0x8259, 0xAD32}, //203 #HANGUL SYLLABLE KIYEOK WAE PHIEUPH + {0x825A, 0xAD33}, //204 #HANGUL SYLLABLE KIYEOK WAE HIEUH + {0x8261, 0xAD36}, //205 #HANGUL SYLLABLE KIYEOK OE SSANGKIYEOK + {0x8262, 0xAD37}, //206 #HANGUL SYLLABLE KIYEOK OE KIYEOKSIOS + {0x8263, 0xAD39}, //207 #HANGUL SYLLABLE KIYEOK OE NIEUNCIEUC + {0x8264, 0xAD3A}, //208 #HANGUL SYLLABLE KIYEOK OE NIEUNHIEUH + {0x8265, 0xAD3B}, //209 #HANGUL SYLLABLE KIYEOK OE TIKEUT + {0x8266, 0xAD3D}, //210 #HANGUL SYLLABLE KIYEOK OE RIEULKIYEOK + {0x8267, 0xAD3E}, //211 #HANGUL SYLLABLE KIYEOK OE RIEULMIEUM + {0x8268, 0xAD3F}, //212 #HANGUL SYLLABLE KIYEOK OE RIEULPIEUP + {0x8269, 0xAD40}, //213 #HANGUL SYLLABLE KIYEOK OE RIEULSIOS + {0x826A, 0xAD41}, //214 #HANGUL SYLLABLE KIYEOK OE RIEULTHIEUTH + {0x826B, 0xAD42}, //215 #HANGUL SYLLABLE KIYEOK OE RIEULPHIEUPH + {0x826C, 0xAD43}, //216 #HANGUL SYLLABLE KIYEOK OE RIEULHIEUH + {0x826D, 0xAD46}, //217 #HANGUL SYLLABLE KIYEOK OE PIEUPSIOS + {0x826E, 0xAD48}, //218 #HANGUL SYLLABLE KIYEOK OE SSANGSIOS + {0x826F, 0xAD4A}, //219 #HANGUL SYLLABLE KIYEOK OE CIEUC + {0x8270, 0xAD4B}, //220 #HANGUL SYLLABLE KIYEOK OE CHIEUCH + {0x8271, 0xAD4C}, //221 #HANGUL SYLLABLE KIYEOK OE KHIEUKH + {0x8272, 0xAD4D}, //222 #HANGUL SYLLABLE KIYEOK OE THIEUTH + {0x8273, 0xAD4E}, //223 #HANGUL SYLLABLE KIYEOK OE PHIEUPH + {0x8274, 0xAD4F}, //224 #HANGUL SYLLABLE KIYEOK OE HIEUH + {0x8275, 0xAD51}, //225 #HANGUL SYLLABLE KIYEOK YO KIYEOK + {0x8276, 0xAD52}, //226 #HANGUL SYLLABLE KIYEOK YO SSANGKIYEOK + {0x8277, 0xAD53}, //227 #HANGUL SYLLABLE KIYEOK YO KIYEOKSIOS + {0x8278, 0xAD55}, //228 #HANGUL SYLLABLE KIYEOK YO NIEUNCIEUC + {0x8279, 0xAD56}, //229 #HANGUL SYLLABLE KIYEOK YO NIEUNHIEUH + {0x827A, 0xAD57}, //230 #HANGUL SYLLABLE KIYEOK YO TIKEUT + {0x8281, 0xAD59}, //231 #HANGUL SYLLABLE KIYEOK YO RIEULKIYEOK + {0x8282, 0xAD5A}, //232 #HANGUL SYLLABLE KIYEOK YO RIEULMIEUM + {0x8283, 0xAD5B}, //233 #HANGUL SYLLABLE KIYEOK YO RIEULPIEUP + {0x8284, 0xAD5C}, //234 #HANGUL SYLLABLE KIYEOK YO RIEULSIOS + {0x8285, 0xAD5D}, //235 #HANGUL SYLLABLE KIYEOK YO RIEULTHIEUTH + {0x8286, 0xAD5E}, //236 #HANGUL SYLLABLE KIYEOK YO RIEULPHIEUPH + {0x8287, 0xAD5F}, //237 #HANGUL SYLLABLE KIYEOK YO RIEULHIEUH + {0x8288, 0xAD60}, //238 #HANGUL SYLLABLE KIYEOK YO MIEUM + {0x8289, 0xAD62}, //239 #HANGUL SYLLABLE KIYEOK YO PIEUPSIOS + {0x828A, 0xAD64}, //240 #HANGUL SYLLABLE KIYEOK YO SSANGSIOS + {0x828B, 0xAD65}, //241 #HANGUL SYLLABLE KIYEOK YO IEUNG + {0x828C, 0xAD66}, //242 #HANGUL SYLLABLE KIYEOK YO CIEUC + {0x828D, 0xAD67}, //243 #HANGUL SYLLABLE KIYEOK YO CHIEUCH + {0x828E, 0xAD68}, //244 #HANGUL SYLLABLE KIYEOK YO KHIEUKH + {0x828F, 0xAD69}, //245 #HANGUL SYLLABLE KIYEOK YO THIEUTH + {0x8290, 0xAD6A}, //246 #HANGUL SYLLABLE KIYEOK YO PHIEUPH + {0x8291, 0xAD6B}, //247 #HANGUL SYLLABLE KIYEOK YO HIEUH + {0x8292, 0xAD6E}, //248 #HANGUL SYLLABLE KIYEOK U SSANGKIYEOK + {0x8293, 0xAD6F}, //249 #HANGUL SYLLABLE KIYEOK U KIYEOKSIOS + {0x8294, 0xAD71}, //250 #HANGUL SYLLABLE KIYEOK U NIEUNCIEUC + {0x8295, 0xAD72}, //251 #HANGUL SYLLABLE KIYEOK U NIEUNHIEUH + {0x8296, 0xAD77}, //252 #HANGUL SYLLABLE KIYEOK U RIEULPIEUP + {0x8297, 0xAD78}, //253 #HANGUL SYLLABLE KIYEOK U RIEULSIOS + {0x8298, 0xAD79}, //254 #HANGUL SYLLABLE KIYEOK U RIEULTHIEUTH + {0x8299, 0xAD7A}, //255 #HANGUL SYLLABLE KIYEOK U RIEULPHIEUPH + {0x829A, 0xAD7E}, //256 #HANGUL SYLLABLE KIYEOK U PIEUPSIOS + {0x829B, 0xAD80}, //257 #HANGUL SYLLABLE KIYEOK U SSANGSIOS + {0x829C, 0xAD83}, //258 #HANGUL SYLLABLE KIYEOK U CHIEUCH + {0x829D, 0xAD84}, //259 #HANGUL SYLLABLE KIYEOK U KHIEUKH + {0x829E, 0xAD85}, //260 #HANGUL SYLLABLE KIYEOK U THIEUTH + {0x829F, 0xAD86}, //261 #HANGUL SYLLABLE KIYEOK U PHIEUPH + {0x82A0, 0xAD87}, //262 #HANGUL SYLLABLE KIYEOK U HIEUH + {0x82A1, 0xAD8A}, //263 #HANGUL SYLLABLE KIYEOK WEO SSANGKIYEOK + {0x82A2, 0xAD8B}, //264 #HANGUL SYLLABLE KIYEOK WEO KIYEOKSIOS + {0x82A3, 0xAD8D}, //265 #HANGUL SYLLABLE KIYEOK WEO NIEUNCIEUC + {0x82A4, 0xAD8E}, //266 #HANGUL SYLLABLE KIYEOK WEO NIEUNHIEUH + {0x82A5, 0xAD8F}, //267 #HANGUL SYLLABLE KIYEOK WEO TIKEUT + {0x82A6, 0xAD91}, //268 #HANGUL SYLLABLE KIYEOK WEO RIEULKIYEOK + {0x82A7, 0xAD92}, //269 #HANGUL SYLLABLE KIYEOK WEO RIEULMIEUM + {0x82A8, 0xAD93}, //270 #HANGUL SYLLABLE KIYEOK WEO RIEULPIEUP + {0x82A9, 0xAD94}, //271 #HANGUL SYLLABLE KIYEOK WEO RIEULSIOS + {0x82AA, 0xAD95}, //272 #HANGUL SYLLABLE KIYEOK WEO RIEULTHIEUTH + {0x82AB, 0xAD96}, //273 #HANGUL SYLLABLE KIYEOK WEO RIEULPHIEUPH + {0x82AC, 0xAD97}, //274 #HANGUL SYLLABLE KIYEOK WEO RIEULHIEUH + {0x82AD, 0xAD98}, //275 #HANGUL SYLLABLE KIYEOK WEO MIEUM + {0x82AE, 0xAD99}, //276 #HANGUL SYLLABLE KIYEOK WEO PIEUP + {0x82AF, 0xAD9A}, //277 #HANGUL SYLLABLE KIYEOK WEO PIEUPSIOS + {0x82B0, 0xAD9B}, //278 #HANGUL SYLLABLE KIYEOK WEO SIOS + {0x82B1, 0xAD9E}, //279 #HANGUL SYLLABLE KIYEOK WEO CIEUC + {0x82B2, 0xAD9F}, //280 #HANGUL SYLLABLE KIYEOK WEO CHIEUCH + {0x82B3, 0xADA0}, //281 #HANGUL SYLLABLE KIYEOK WEO KHIEUKH + {0x82B4, 0xADA1}, //282 #HANGUL SYLLABLE KIYEOK WEO THIEUTH + {0x82B5, 0xADA2}, //283 #HANGUL SYLLABLE KIYEOK WEO PHIEUPH + {0x82B6, 0xADA3}, //284 #HANGUL SYLLABLE KIYEOK WEO HIEUH + {0x82B7, 0xADA5}, //285 #HANGUL SYLLABLE KIYEOK WE KIYEOK + {0x82B8, 0xADA6}, //286 #HANGUL SYLLABLE KIYEOK WE SSANGKIYEOK + {0x82B9, 0xADA7}, //287 #HANGUL SYLLABLE KIYEOK WE KIYEOKSIOS + {0x82BA, 0xADA8}, //288 #HANGUL SYLLABLE KIYEOK WE NIEUN + {0x82BB, 0xADA9}, //289 #HANGUL SYLLABLE KIYEOK WE NIEUNCIEUC + {0x82BC, 0xADAA}, //290 #HANGUL SYLLABLE KIYEOK WE NIEUNHIEUH + {0x82BD, 0xADAB}, //291 #HANGUL SYLLABLE KIYEOK WE TIKEUT + {0x82BE, 0xADAC}, //292 #HANGUL SYLLABLE KIYEOK WE RIEUL + {0x82BF, 0xADAD}, //293 #HANGUL SYLLABLE KIYEOK WE RIEULKIYEOK + {0x82C0, 0xADAE}, //294 #HANGUL SYLLABLE KIYEOK WE RIEULMIEUM + {0x82C1, 0xADAF}, //295 #HANGUL SYLLABLE KIYEOK WE RIEULPIEUP + {0x82C2, 0xADB0}, //296 #HANGUL SYLLABLE KIYEOK WE RIEULSIOS + {0x82C3, 0xADB1}, //297 #HANGUL SYLLABLE KIYEOK WE RIEULTHIEUTH + {0x82C4, 0xADB2}, //298 #HANGUL SYLLABLE KIYEOK WE RIEULPHIEUPH + {0x82C5, 0xADB3}, //299 #HANGUL SYLLABLE KIYEOK WE RIEULHIEUH + {0x82C6, 0xADB4}, //300 #HANGUL SYLLABLE KIYEOK WE MIEUM + {0x82C7, 0xADB5}, //301 #HANGUL SYLLABLE KIYEOK WE PIEUP + {0x82C8, 0xADB6}, //302 #HANGUL SYLLABLE KIYEOK WE PIEUPSIOS + {0x82C9, 0xADB8}, //303 #HANGUL SYLLABLE KIYEOK WE SSANGSIOS + {0x82CA, 0xADB9}, //304 #HANGUL SYLLABLE KIYEOK WE IEUNG + {0x82CB, 0xADBA}, //305 #HANGUL SYLLABLE KIYEOK WE CIEUC + {0x82CC, 0xADBB}, //306 #HANGUL SYLLABLE KIYEOK WE CHIEUCH + {0x82CD, 0xADBC}, //307 #HANGUL SYLLABLE KIYEOK WE KHIEUKH + {0x82CE, 0xADBD}, //308 #HANGUL SYLLABLE KIYEOK WE THIEUTH + {0x82CF, 0xADBE}, //309 #HANGUL SYLLABLE KIYEOK WE PHIEUPH + {0x82D0, 0xADBF}, //310 #HANGUL SYLLABLE KIYEOK WE HIEUH + {0x82D1, 0xADC2}, //311 #HANGUL SYLLABLE KIYEOK WI SSANGKIYEOK + {0x82D2, 0xADC3}, //312 #HANGUL SYLLABLE KIYEOK WI KIYEOKSIOS + {0x82D3, 0xADC5}, //313 #HANGUL SYLLABLE KIYEOK WI NIEUNCIEUC + {0x82D4, 0xADC6}, //314 #HANGUL SYLLABLE KIYEOK WI NIEUNHIEUH + {0x82D5, 0xADC7}, //315 #HANGUL SYLLABLE KIYEOK WI TIKEUT + {0x82D6, 0xADC9}, //316 #HANGUL SYLLABLE KIYEOK WI RIEULKIYEOK + {0x82D7, 0xADCA}, //317 #HANGUL SYLLABLE KIYEOK WI RIEULMIEUM + {0x82D8, 0xADCB}, //318 #HANGUL SYLLABLE KIYEOK WI RIEULPIEUP + {0x82D9, 0xADCC}, //319 #HANGUL SYLLABLE KIYEOK WI RIEULSIOS + {0x82DA, 0xADCD}, //320 #HANGUL SYLLABLE KIYEOK WI RIEULTHIEUTH + {0x82DB, 0xADCE}, //321 #HANGUL SYLLABLE KIYEOK WI RIEULPHIEUPH + {0x82DC, 0xADCF}, //322 #HANGUL SYLLABLE KIYEOK WI RIEULHIEUH + {0x82DD, 0xADD2}, //323 #HANGUL SYLLABLE KIYEOK WI PIEUPSIOS + {0x82DE, 0xADD4}, //324 #HANGUL SYLLABLE KIYEOK WI SSANGSIOS + {0x82DF, 0xADD5}, //325 #HANGUL SYLLABLE KIYEOK WI IEUNG + {0x82E0, 0xADD6}, //326 #HANGUL SYLLABLE KIYEOK WI CIEUC + {0x82E1, 0xADD7}, //327 #HANGUL SYLLABLE KIYEOK WI CHIEUCH + {0x82E2, 0xADD8}, //328 #HANGUL SYLLABLE KIYEOK WI KHIEUKH + {0x82E3, 0xADD9}, //329 #HANGUL SYLLABLE KIYEOK WI THIEUTH + {0x82E4, 0xADDA}, //330 #HANGUL SYLLABLE KIYEOK WI PHIEUPH + {0x82E5, 0xADDB}, //331 #HANGUL SYLLABLE KIYEOK WI HIEUH + {0x82E6, 0xADDD}, //332 #HANGUL SYLLABLE KIYEOK YU KIYEOK + {0x82E7, 0xADDE}, //333 #HANGUL SYLLABLE KIYEOK YU SSANGKIYEOK + {0x82E8, 0xADDF}, //334 #HANGUL SYLLABLE KIYEOK YU KIYEOKSIOS + {0x82E9, 0xADE1}, //335 #HANGUL SYLLABLE KIYEOK YU NIEUNCIEUC + {0x82EA, 0xADE2}, //336 #HANGUL SYLLABLE KIYEOK YU NIEUNHIEUH + {0x82EB, 0xADE3}, //337 #HANGUL SYLLABLE KIYEOK YU TIKEUT + {0x82EC, 0xADE5}, //338 #HANGUL SYLLABLE KIYEOK YU RIEULKIYEOK + {0x82ED, 0xADE6}, //339 #HANGUL SYLLABLE KIYEOK YU RIEULMIEUM + {0x82EE, 0xADE7}, //340 #HANGUL SYLLABLE KIYEOK YU RIEULPIEUP + {0x82EF, 0xADE8}, //341 #HANGUL SYLLABLE KIYEOK YU RIEULSIOS + {0x82F0, 0xADE9}, //342 #HANGUL SYLLABLE KIYEOK YU RIEULTHIEUTH + {0x82F1, 0xADEA}, //343 #HANGUL SYLLABLE KIYEOK YU RIEULPHIEUPH + {0x82F2, 0xADEB}, //344 #HANGUL SYLLABLE KIYEOK YU RIEULHIEUH + {0x82F3, 0xADEC}, //345 #HANGUL SYLLABLE KIYEOK YU MIEUM + {0x82F4, 0xADED}, //346 #HANGUL SYLLABLE KIYEOK YU PIEUP + {0x82F5, 0xADEE}, //347 #HANGUL SYLLABLE KIYEOK YU PIEUPSIOS + {0x82F6, 0xADEF}, //348 #HANGUL SYLLABLE KIYEOK YU SIOS + {0x82F7, 0xADF0}, //349 #HANGUL SYLLABLE KIYEOK YU SSANGSIOS + {0x82F8, 0xADF1}, //350 #HANGUL SYLLABLE KIYEOK YU IEUNG + {0x82F9, 0xADF2}, //351 #HANGUL SYLLABLE KIYEOK YU CIEUC + {0x82FA, 0xADF3}, //352 #HANGUL SYLLABLE KIYEOK YU CHIEUCH + {0x82FB, 0xADF4}, //353 #HANGUL SYLLABLE KIYEOK YU KHIEUKH + {0x82FC, 0xADF5}, //354 #HANGUL SYLLABLE KIYEOK YU THIEUTH + {0x82FD, 0xADF6}, //355 #HANGUL SYLLABLE KIYEOK YU PHIEUPH + {0x82FE, 0xADF7}, //356 #HANGUL SYLLABLE KIYEOK YU HIEUH + {0x8341, 0xADFA}, //357 #HANGUL SYLLABLE KIYEOK EU SSANGKIYEOK + {0x8342, 0xADFB}, //358 #HANGUL SYLLABLE KIYEOK EU KIYEOKSIOS + {0x8343, 0xADFD}, //359 #HANGUL SYLLABLE KIYEOK EU NIEUNCIEUC + {0x8344, 0xADFE}, //360 #HANGUL SYLLABLE KIYEOK EU NIEUNHIEUH + {0x8345, 0xAE02}, //361 #HANGUL SYLLABLE KIYEOK EU RIEULMIEUM + {0x8346, 0xAE03}, //362 #HANGUL SYLLABLE KIYEOK EU RIEULPIEUP + {0x8347, 0xAE04}, //363 #HANGUL SYLLABLE KIYEOK EU RIEULSIOS + {0x8348, 0xAE05}, //364 #HANGUL SYLLABLE KIYEOK EU RIEULTHIEUTH + {0x8349, 0xAE06}, //365 #HANGUL SYLLABLE KIYEOK EU RIEULPHIEUPH + {0x834A, 0xAE07}, //366 #HANGUL SYLLABLE KIYEOK EU RIEULHIEUH + {0x834B, 0xAE0A}, //367 #HANGUL SYLLABLE KIYEOK EU PIEUPSIOS + {0x834C, 0xAE0C}, //368 #HANGUL SYLLABLE KIYEOK EU SSANGSIOS + {0x834D, 0xAE0E}, //369 #HANGUL SYLLABLE KIYEOK EU CIEUC + {0x834E, 0xAE0F}, //370 #HANGUL SYLLABLE KIYEOK EU CHIEUCH + {0x834F, 0xAE10}, //371 #HANGUL SYLLABLE KIYEOK EU KHIEUKH + {0x8350, 0xAE11}, //372 #HANGUL SYLLABLE KIYEOK EU THIEUTH + {0x8351, 0xAE12}, //373 #HANGUL SYLLABLE KIYEOK EU PHIEUPH + {0x8352, 0xAE13}, //374 #HANGUL SYLLABLE KIYEOK EU HIEUH + {0x8353, 0xAE15}, //375 #HANGUL SYLLABLE KIYEOK YI KIYEOK + {0x8354, 0xAE16}, //376 #HANGUL SYLLABLE KIYEOK YI SSANGKIYEOK + {0x8355, 0xAE17}, //377 #HANGUL SYLLABLE KIYEOK YI KIYEOKSIOS + {0x8356, 0xAE18}, //378 #HANGUL SYLLABLE KIYEOK YI NIEUN + {0x8357, 0xAE19}, //379 #HANGUL SYLLABLE KIYEOK YI NIEUNCIEUC + {0x8358, 0xAE1A}, //380 #HANGUL SYLLABLE KIYEOK YI NIEUNHIEUH + {0x8359, 0xAE1B}, //381 #HANGUL SYLLABLE KIYEOK YI TIKEUT + {0x835A, 0xAE1C}, //382 #HANGUL SYLLABLE KIYEOK YI RIEUL + {0x8361, 0xAE1D}, //383 #HANGUL SYLLABLE KIYEOK YI RIEULKIYEOK + {0x8362, 0xAE1E}, //384 #HANGUL SYLLABLE KIYEOK YI RIEULMIEUM + {0x8363, 0xAE1F}, //385 #HANGUL SYLLABLE KIYEOK YI RIEULPIEUP + {0x8364, 0xAE20}, //386 #HANGUL SYLLABLE KIYEOK YI RIEULSIOS + {0x8365, 0xAE21}, //387 #HANGUL SYLLABLE KIYEOK YI RIEULTHIEUTH + {0x8366, 0xAE22}, //388 #HANGUL SYLLABLE KIYEOK YI RIEULPHIEUPH + {0x8367, 0xAE23}, //389 #HANGUL SYLLABLE KIYEOK YI RIEULHIEUH + {0x8368, 0xAE24}, //390 #HANGUL SYLLABLE KIYEOK YI MIEUM + {0x8369, 0xAE25}, //391 #HANGUL SYLLABLE KIYEOK YI PIEUP + {0x836A, 0xAE26}, //392 #HANGUL SYLLABLE KIYEOK YI PIEUPSIOS + {0x836B, 0xAE27}, //393 #HANGUL SYLLABLE KIYEOK YI SIOS + {0x836C, 0xAE28}, //394 #HANGUL SYLLABLE KIYEOK YI SSANGSIOS + {0x836D, 0xAE29}, //395 #HANGUL SYLLABLE KIYEOK YI IEUNG + {0x836E, 0xAE2A}, //396 #HANGUL SYLLABLE KIYEOK YI CIEUC + {0x836F, 0xAE2B}, //397 #HANGUL SYLLABLE KIYEOK YI CHIEUCH + {0x8370, 0xAE2C}, //398 #HANGUL SYLLABLE KIYEOK YI KHIEUKH + {0x8371, 0xAE2D}, //399 #HANGUL SYLLABLE KIYEOK YI THIEUTH + {0x8372, 0xAE2E}, //400 #HANGUL SYLLABLE KIYEOK YI PHIEUPH + {0x8373, 0xAE2F}, //401 #HANGUL SYLLABLE KIYEOK YI HIEUH + {0x8374, 0xAE32}, //402 #HANGUL SYLLABLE KIYEOK I SSANGKIYEOK + {0x8375, 0xAE33}, //403 #HANGUL SYLLABLE KIYEOK I KIYEOKSIOS + {0x8376, 0xAE35}, //404 #HANGUL SYLLABLE KIYEOK I NIEUNCIEUC + {0x8377, 0xAE36}, //405 #HANGUL SYLLABLE KIYEOK I NIEUNHIEUH + {0x8378, 0xAE39}, //406 #HANGUL SYLLABLE KIYEOK I RIEULKIYEOK + {0x8379, 0xAE3B}, //407 #HANGUL SYLLABLE KIYEOK I RIEULPIEUP + {0x837A, 0xAE3C}, //408 #HANGUL SYLLABLE KIYEOK I RIEULSIOS + {0x8381, 0xAE3D}, //409 #HANGUL SYLLABLE KIYEOK I RIEULTHIEUTH + {0x8382, 0xAE3E}, //410 #HANGUL SYLLABLE KIYEOK I RIEULPHIEUPH + {0x8383, 0xAE3F}, //411 #HANGUL SYLLABLE KIYEOK I RIEULHIEUH + {0x8384, 0xAE42}, //412 #HANGUL SYLLABLE KIYEOK I PIEUPSIOS + {0x8385, 0xAE44}, //413 #HANGUL SYLLABLE KIYEOK I SSANGSIOS + {0x8386, 0xAE47}, //414 #HANGUL SYLLABLE KIYEOK I CHIEUCH + {0x8387, 0xAE48}, //415 #HANGUL SYLLABLE KIYEOK I KHIEUKH + {0x8388, 0xAE49}, //416 #HANGUL SYLLABLE KIYEOK I THIEUTH + {0x8389, 0xAE4B}, //417 #HANGUL SYLLABLE KIYEOK I HIEUH + {0x838A, 0xAE4F}, //418 #HANGUL SYLLABLE SSANGKIYEOK A KIYEOKSIOS + {0x838B, 0xAE51}, //419 #HANGUL SYLLABLE SSANGKIYEOK A NIEUNCIEUC + {0x838C, 0xAE52}, //420 #HANGUL SYLLABLE SSANGKIYEOK A NIEUNHIEUH + {0x838D, 0xAE53}, //421 #HANGUL SYLLABLE SSANGKIYEOK A TIKEUT + {0x838E, 0xAE55}, //422 #HANGUL SYLLABLE SSANGKIYEOK A RIEULKIYEOK + {0x838F, 0xAE57}, //423 #HANGUL SYLLABLE SSANGKIYEOK A RIEULPIEUP + {0x8390, 0xAE58}, //424 #HANGUL SYLLABLE SSANGKIYEOK A RIEULSIOS + {0x8391, 0xAE59}, //425 #HANGUL SYLLABLE SSANGKIYEOK A RIEULTHIEUTH + {0x8392, 0xAE5A}, //426 #HANGUL SYLLABLE SSANGKIYEOK A RIEULPHIEUPH + {0x8393, 0xAE5B}, //427 #HANGUL SYLLABLE SSANGKIYEOK A RIEULHIEUH + {0x8394, 0xAE5E}, //428 #HANGUL SYLLABLE SSANGKIYEOK A PIEUPSIOS + {0x8395, 0xAE62}, //429 #HANGUL SYLLABLE SSANGKIYEOK A CIEUC + {0x8396, 0xAE63}, //430 #HANGUL SYLLABLE SSANGKIYEOK A CHIEUCH + {0x8397, 0xAE64}, //431 #HANGUL SYLLABLE SSANGKIYEOK A KHIEUKH + {0x8398, 0xAE66}, //432 #HANGUL SYLLABLE SSANGKIYEOK A PHIEUPH + {0x8399, 0xAE67}, //433 #HANGUL SYLLABLE SSANGKIYEOK A HIEUH + {0x839A, 0xAE6A}, //434 #HANGUL SYLLABLE SSANGKIYEOK AE SSANGKIYEOK + {0x839B, 0xAE6B}, //435 #HANGUL SYLLABLE SSANGKIYEOK AE KIYEOKSIOS + {0x839C, 0xAE6D}, //436 #HANGUL SYLLABLE SSANGKIYEOK AE NIEUNCIEUC + {0x839D, 0xAE6E}, //437 #HANGUL SYLLABLE SSANGKIYEOK AE NIEUNHIEUH + {0x839E, 0xAE6F}, //438 #HANGUL SYLLABLE SSANGKIYEOK AE TIKEUT + {0x839F, 0xAE71}, //439 #HANGUL SYLLABLE SSANGKIYEOK AE RIEULKIYEOK + {0x83A0, 0xAE72}, //440 #HANGUL SYLLABLE SSANGKIYEOK AE RIEULMIEUM + {0x83A1, 0xAE73}, //441 #HANGUL SYLLABLE SSANGKIYEOK AE RIEULPIEUP + {0x83A2, 0xAE74}, //442 #HANGUL SYLLABLE SSANGKIYEOK AE RIEULSIOS + {0x83A3, 0xAE75}, //443 #HANGUL SYLLABLE SSANGKIYEOK AE RIEULTHIEUTH + {0x83A4, 0xAE76}, //444 #HANGUL SYLLABLE SSANGKIYEOK AE RIEULPHIEUPH + {0x83A5, 0xAE77}, //445 #HANGUL SYLLABLE SSANGKIYEOK AE RIEULHIEUH + {0x83A6, 0xAE7A}, //446 #HANGUL SYLLABLE SSANGKIYEOK AE PIEUPSIOS + {0x83A7, 0xAE7E}, //447 #HANGUL SYLLABLE SSANGKIYEOK AE CIEUC + {0x83A8, 0xAE7F}, //448 #HANGUL SYLLABLE SSANGKIYEOK AE CHIEUCH + {0x83A9, 0xAE80}, //449 #HANGUL SYLLABLE SSANGKIYEOK AE KHIEUKH + {0x83AA, 0xAE81}, //450 #HANGUL SYLLABLE SSANGKIYEOK AE THIEUTH + {0x83AB, 0xAE82}, //451 #HANGUL SYLLABLE SSANGKIYEOK AE PHIEUPH + {0x83AC, 0xAE83}, //452 #HANGUL SYLLABLE SSANGKIYEOK AE HIEUH + {0x83AD, 0xAE86}, //453 #HANGUL SYLLABLE SSANGKIYEOK YA SSANGKIYEOK + {0x83AE, 0xAE87}, //454 #HANGUL SYLLABLE SSANGKIYEOK YA KIYEOKSIOS + {0x83AF, 0xAE88}, //455 #HANGUL SYLLABLE SSANGKIYEOK YA NIEUN + {0x83B0, 0xAE89}, //456 #HANGUL SYLLABLE SSANGKIYEOK YA NIEUNCIEUC + {0x83B1, 0xAE8A}, //457 #HANGUL SYLLABLE SSANGKIYEOK YA NIEUNHIEUH + {0x83B2, 0xAE8B}, //458 #HANGUL SYLLABLE SSANGKIYEOK YA TIKEUT + {0x83B3, 0xAE8D}, //459 #HANGUL SYLLABLE SSANGKIYEOK YA RIEULKIYEOK + {0x83B4, 0xAE8E}, //460 #HANGUL SYLLABLE SSANGKIYEOK YA RIEULMIEUM + {0x83B5, 0xAE8F}, //461 #HANGUL SYLLABLE SSANGKIYEOK YA RIEULPIEUP + {0x83B6, 0xAE90}, //462 #HANGUL SYLLABLE SSANGKIYEOK YA RIEULSIOS + {0x83B7, 0xAE91}, //463 #HANGUL SYLLABLE SSANGKIYEOK YA RIEULTHIEUTH + {0x83B8, 0xAE92}, //464 #HANGUL SYLLABLE SSANGKIYEOK YA RIEULPHIEUPH + {0x83B9, 0xAE93}, //465 #HANGUL SYLLABLE SSANGKIYEOK YA RIEULHIEUH + {0x83BA, 0xAE94}, //466 #HANGUL SYLLABLE SSANGKIYEOK YA MIEUM + {0x83BB, 0xAE95}, //467 #HANGUL SYLLABLE SSANGKIYEOK YA PIEUP + {0x83BC, 0xAE96}, //468 #HANGUL SYLLABLE SSANGKIYEOK YA PIEUPSIOS + {0x83BD, 0xAE97}, //469 #HANGUL SYLLABLE SSANGKIYEOK YA SIOS + {0x83BE, 0xAE98}, //470 #HANGUL SYLLABLE SSANGKIYEOK YA SSANGSIOS + {0x83BF, 0xAE99}, //471 #HANGUL SYLLABLE SSANGKIYEOK YA IEUNG + {0x83C0, 0xAE9A}, //472 #HANGUL SYLLABLE SSANGKIYEOK YA CIEUC + {0x83C1, 0xAE9B}, //473 #HANGUL SYLLABLE SSANGKIYEOK YA CHIEUCH + {0x83C2, 0xAE9C}, //474 #HANGUL SYLLABLE SSANGKIYEOK YA KHIEUKH + {0x83C3, 0xAE9D}, //475 #HANGUL SYLLABLE SSANGKIYEOK YA THIEUTH + {0x83C4, 0xAE9E}, //476 #HANGUL SYLLABLE SSANGKIYEOK YA PHIEUPH + {0x83C5, 0xAE9F}, //477 #HANGUL SYLLABLE SSANGKIYEOK YA HIEUH + {0x83C6, 0xAEA0}, //478 #HANGUL SYLLABLE SSANGKIYEOK YAE + {0x83C7, 0xAEA1}, //479 #HANGUL SYLLABLE SSANGKIYEOK YAE KIYEOK + {0x83C8, 0xAEA2}, //480 #HANGUL SYLLABLE SSANGKIYEOK YAE SSANGKIYEOK + {0x83C9, 0xAEA3}, //481 #HANGUL SYLLABLE SSANGKIYEOK YAE KIYEOKSIOS + {0x83CA, 0xAEA4}, //482 #HANGUL SYLLABLE SSANGKIYEOK YAE NIEUN + {0x83CB, 0xAEA5}, //483 #HANGUL SYLLABLE SSANGKIYEOK YAE NIEUNCIEUC + {0x83CC, 0xAEA6}, //484 #HANGUL SYLLABLE SSANGKIYEOK YAE NIEUNHIEUH + {0x83CD, 0xAEA7}, //485 #HANGUL SYLLABLE SSANGKIYEOK YAE TIKEUT + {0x83CE, 0xAEA8}, //486 #HANGUL SYLLABLE SSANGKIYEOK YAE RIEUL + {0x83CF, 0xAEA9}, //487 #HANGUL SYLLABLE SSANGKIYEOK YAE RIEULKIYEOK + {0x83D0, 0xAEAA}, //488 #HANGUL SYLLABLE SSANGKIYEOK YAE RIEULMIEUM + {0x83D1, 0xAEAB}, //489 #HANGUL SYLLABLE SSANGKIYEOK YAE RIEULPIEUP + {0x83D2, 0xAEAC}, //490 #HANGUL SYLLABLE SSANGKIYEOK YAE RIEULSIOS + {0x83D3, 0xAEAD}, //491 #HANGUL SYLLABLE SSANGKIYEOK YAE RIEULTHIEUTH + {0x83D4, 0xAEAE}, //492 #HANGUL SYLLABLE SSANGKIYEOK YAE RIEULPHIEUPH + {0x83D5, 0xAEAF}, //493 #HANGUL SYLLABLE SSANGKIYEOK YAE RIEULHIEUH + {0x83D6, 0xAEB0}, //494 #HANGUL SYLLABLE SSANGKIYEOK YAE MIEUM + {0x83D7, 0xAEB1}, //495 #HANGUL SYLLABLE SSANGKIYEOK YAE PIEUP + {0x83D8, 0xAEB2}, //496 #HANGUL SYLLABLE SSANGKIYEOK YAE PIEUPSIOS + {0x83D9, 0xAEB3}, //497 #HANGUL SYLLABLE SSANGKIYEOK YAE SIOS + {0x83DA, 0xAEB4}, //498 #HANGUL SYLLABLE SSANGKIYEOK YAE SSANGSIOS + {0x83DB, 0xAEB5}, //499 #HANGUL SYLLABLE SSANGKIYEOK YAE IEUNG + {0x83DC, 0xAEB6}, //500 #HANGUL SYLLABLE SSANGKIYEOK YAE CIEUC + {0x83DD, 0xAEB7}, //501 #HANGUL SYLLABLE SSANGKIYEOK YAE CHIEUCH + {0x83DE, 0xAEB8}, //502 #HANGUL SYLLABLE SSANGKIYEOK YAE KHIEUKH + {0x83DF, 0xAEB9}, //503 #HANGUL SYLLABLE SSANGKIYEOK YAE THIEUTH + {0x83E0, 0xAEBA}, //504 #HANGUL SYLLABLE SSANGKIYEOK YAE PHIEUPH + {0x83E1, 0xAEBB}, //505 #HANGUL SYLLABLE SSANGKIYEOK YAE HIEUH + {0x83E2, 0xAEBF}, //506 #HANGUL SYLLABLE SSANGKIYEOK EO KIYEOKSIOS + {0x83E3, 0xAEC1}, //507 #HANGUL SYLLABLE SSANGKIYEOK EO NIEUNCIEUC + {0x83E4, 0xAEC2}, //508 #HANGUL SYLLABLE SSANGKIYEOK EO NIEUNHIEUH + {0x83E5, 0xAEC3}, //509 #HANGUL SYLLABLE SSANGKIYEOK EO TIKEUT + {0x83E6, 0xAEC5}, //510 #HANGUL SYLLABLE SSANGKIYEOK EO RIEULKIYEOK + {0x83E7, 0xAEC6}, //511 #HANGUL SYLLABLE SSANGKIYEOK EO RIEULMIEUM + {0x83E8, 0xAEC7}, //512 #HANGUL SYLLABLE SSANGKIYEOK EO RIEULPIEUP + {0x83E9, 0xAEC8}, //513 #HANGUL SYLLABLE SSANGKIYEOK EO RIEULSIOS + {0x83EA, 0xAEC9}, //514 #HANGUL SYLLABLE SSANGKIYEOK EO RIEULTHIEUTH + {0x83EB, 0xAECA}, //515 #HANGUL SYLLABLE SSANGKIYEOK EO RIEULPHIEUPH + {0x83EC, 0xAECB}, //516 #HANGUL SYLLABLE SSANGKIYEOK EO RIEULHIEUH + {0x83ED, 0xAECE}, //517 #HANGUL SYLLABLE SSANGKIYEOK EO PIEUPSIOS + {0x83EE, 0xAED2}, //518 #HANGUL SYLLABLE SSANGKIYEOK EO CIEUC + {0x83EF, 0xAED3}, //519 #HANGUL SYLLABLE SSANGKIYEOK EO CHIEUCH + {0x83F0, 0xAED4}, //520 #HANGUL SYLLABLE SSANGKIYEOK EO KHIEUKH + {0x83F1, 0xAED5}, //521 #HANGUL SYLLABLE SSANGKIYEOK EO THIEUTH + {0x83F2, 0xAED6}, //522 #HANGUL SYLLABLE SSANGKIYEOK EO PHIEUPH + {0x83F3, 0xAED7}, //523 #HANGUL SYLLABLE SSANGKIYEOK EO HIEUH + {0x83F4, 0xAEDA}, //524 #HANGUL SYLLABLE SSANGKIYEOK E SSANGKIYEOK + {0x83F5, 0xAEDB}, //525 #HANGUL SYLLABLE SSANGKIYEOK E KIYEOKSIOS + {0x83F6, 0xAEDD}, //526 #HANGUL SYLLABLE SSANGKIYEOK E NIEUNCIEUC + {0x83F7, 0xAEDE}, //527 #HANGUL SYLLABLE SSANGKIYEOK E NIEUNHIEUH + {0x83F8, 0xAEDF}, //528 #HANGUL SYLLABLE SSANGKIYEOK E TIKEUT + {0x83F9, 0xAEE0}, //529 #HANGUL SYLLABLE SSANGKIYEOK E RIEUL + {0x83FA, 0xAEE1}, //530 #HANGUL SYLLABLE SSANGKIYEOK E RIEULKIYEOK + {0x83FB, 0xAEE2}, //531 #HANGUL SYLLABLE SSANGKIYEOK E RIEULMIEUM + {0x83FC, 0xAEE3}, //532 #HANGUL SYLLABLE SSANGKIYEOK E RIEULPIEUP + {0x83FD, 0xAEE4}, //533 #HANGUL SYLLABLE SSANGKIYEOK E RIEULSIOS + {0x83FE, 0xAEE5}, //534 #HANGUL SYLLABLE SSANGKIYEOK E RIEULTHIEUTH + {0x8441, 0xAEE6}, //535 #HANGUL SYLLABLE SSANGKIYEOK E RIEULPHIEUPH + {0x8442, 0xAEE7}, //536 #HANGUL SYLLABLE SSANGKIYEOK E RIEULHIEUH + {0x8443, 0xAEE9}, //537 #HANGUL SYLLABLE SSANGKIYEOK E PIEUP + {0x8444, 0xAEEA}, //538 #HANGUL SYLLABLE SSANGKIYEOK E PIEUPSIOS + {0x8445, 0xAEEC}, //539 #HANGUL SYLLABLE SSANGKIYEOK E SSANGSIOS + {0x8446, 0xAEEE}, //540 #HANGUL SYLLABLE SSANGKIYEOK E CIEUC + {0x8447, 0xAEEF}, //541 #HANGUL SYLLABLE SSANGKIYEOK E CHIEUCH + {0x8448, 0xAEF0}, //542 #HANGUL SYLLABLE SSANGKIYEOK E KHIEUKH + {0x8449, 0xAEF1}, //543 #HANGUL SYLLABLE SSANGKIYEOK E THIEUTH + {0x844A, 0xAEF2}, //544 #HANGUL SYLLABLE SSANGKIYEOK E PHIEUPH + {0x844B, 0xAEF3}, //545 #HANGUL SYLLABLE SSANGKIYEOK E HIEUH + {0x844C, 0xAEF5}, //546 #HANGUL SYLLABLE SSANGKIYEOK YEO KIYEOK + {0x844D, 0xAEF6}, //547 #HANGUL SYLLABLE SSANGKIYEOK YEO SSANGKIYEOK + {0x844E, 0xAEF7}, //548 #HANGUL SYLLABLE SSANGKIYEOK YEO KIYEOKSIOS + {0x844F, 0xAEF9}, //549 #HANGUL SYLLABLE SSANGKIYEOK YEO NIEUNCIEUC + {0x8450, 0xAEFA}, //550 #HANGUL SYLLABLE SSANGKIYEOK YEO NIEUNHIEUH + {0x8451, 0xAEFB}, //551 #HANGUL SYLLABLE SSANGKIYEOK YEO TIKEUT + {0x8452, 0xAEFD}, //552 #HANGUL SYLLABLE SSANGKIYEOK YEO RIEULKIYEOK + {0x8453, 0xAEFE}, //553 #HANGUL SYLLABLE SSANGKIYEOK YEO RIEULMIEUM + {0x8454, 0xAEFF}, //554 #HANGUL SYLLABLE SSANGKIYEOK YEO RIEULPIEUP + {0x8455, 0xAF00}, //555 #HANGUL SYLLABLE SSANGKIYEOK YEO RIEULSIOS + {0x8456, 0xAF01}, //556 #HANGUL SYLLABLE SSANGKIYEOK YEO RIEULTHIEUTH + {0x8457, 0xAF02}, //557 #HANGUL SYLLABLE SSANGKIYEOK YEO RIEULPHIEUPH + {0x8458, 0xAF03}, //558 #HANGUL SYLLABLE SSANGKIYEOK YEO RIEULHIEUH + {0x8459, 0xAF04}, //559 #HANGUL SYLLABLE SSANGKIYEOK YEO MIEUM + {0x845A, 0xAF05}, //560 #HANGUL SYLLABLE SSANGKIYEOK YEO PIEUP + {0x8461, 0xAF06}, //561 #HANGUL SYLLABLE SSANGKIYEOK YEO PIEUPSIOS + {0x8462, 0xAF09}, //562 #HANGUL SYLLABLE SSANGKIYEOK YEO IEUNG + {0x8463, 0xAF0A}, //563 #HANGUL SYLLABLE SSANGKIYEOK YEO CIEUC + {0x8464, 0xAF0B}, //564 #HANGUL SYLLABLE SSANGKIYEOK YEO CHIEUCH + {0x8465, 0xAF0C}, //565 #HANGUL SYLLABLE SSANGKIYEOK YEO KHIEUKH + {0x8466, 0xAF0E}, //566 #HANGUL SYLLABLE SSANGKIYEOK YEO PHIEUPH + {0x8467, 0xAF0F}, //567 #HANGUL SYLLABLE SSANGKIYEOK YEO HIEUH + {0x8468, 0xAF11}, //568 #HANGUL SYLLABLE SSANGKIYEOK YE KIYEOK + {0x8469, 0xAF12}, //569 #HANGUL SYLLABLE SSANGKIYEOK YE SSANGKIYEOK + {0x846A, 0xAF13}, //570 #HANGUL SYLLABLE SSANGKIYEOK YE KIYEOKSIOS + {0x846B, 0xAF14}, //571 #HANGUL SYLLABLE SSANGKIYEOK YE NIEUN + {0x846C, 0xAF15}, //572 #HANGUL SYLLABLE SSANGKIYEOK YE NIEUNCIEUC + {0x846D, 0xAF16}, //573 #HANGUL SYLLABLE SSANGKIYEOK YE NIEUNHIEUH + {0x846E, 0xAF17}, //574 #HANGUL SYLLABLE SSANGKIYEOK YE TIKEUT + {0x846F, 0xAF18}, //575 #HANGUL SYLLABLE SSANGKIYEOK YE RIEUL + {0x8470, 0xAF19}, //576 #HANGUL SYLLABLE SSANGKIYEOK YE RIEULKIYEOK + {0x8471, 0xAF1A}, //577 #HANGUL SYLLABLE SSANGKIYEOK YE RIEULMIEUM + {0x8472, 0xAF1B}, //578 #HANGUL SYLLABLE SSANGKIYEOK YE RIEULPIEUP + {0x8473, 0xAF1C}, //579 #HANGUL SYLLABLE SSANGKIYEOK YE RIEULSIOS + {0x8474, 0xAF1D}, //580 #HANGUL SYLLABLE SSANGKIYEOK YE RIEULTHIEUTH + {0x8475, 0xAF1E}, //581 #HANGUL SYLLABLE SSANGKIYEOK YE RIEULPHIEUPH + {0x8476, 0xAF1F}, //582 #HANGUL SYLLABLE SSANGKIYEOK YE RIEULHIEUH + {0x8477, 0xAF20}, //583 #HANGUL SYLLABLE SSANGKIYEOK YE MIEUM + {0x8478, 0xAF21}, //584 #HANGUL SYLLABLE SSANGKIYEOK YE PIEUP + {0x8479, 0xAF22}, //585 #HANGUL SYLLABLE SSANGKIYEOK YE PIEUPSIOS + {0x847A, 0xAF23}, //586 #HANGUL SYLLABLE SSANGKIYEOK YE SIOS + {0x8481, 0xAF24}, //587 #HANGUL SYLLABLE SSANGKIYEOK YE SSANGSIOS + {0x8482, 0xAF25}, //588 #HANGUL SYLLABLE SSANGKIYEOK YE IEUNG + {0x8483, 0xAF26}, //589 #HANGUL SYLLABLE SSANGKIYEOK YE CIEUC + {0x8484, 0xAF27}, //590 #HANGUL SYLLABLE SSANGKIYEOK YE CHIEUCH + {0x8485, 0xAF28}, //591 #HANGUL SYLLABLE SSANGKIYEOK YE KHIEUKH + {0x8486, 0xAF29}, //592 #HANGUL SYLLABLE SSANGKIYEOK YE THIEUTH + {0x8487, 0xAF2A}, //593 #HANGUL SYLLABLE SSANGKIYEOK YE PHIEUPH + {0x8488, 0xAF2B}, //594 #HANGUL SYLLABLE SSANGKIYEOK YE HIEUH + {0x8489, 0xAF2E}, //595 #HANGUL SYLLABLE SSANGKIYEOK O SSANGKIYEOK + {0x848A, 0xAF2F}, //596 #HANGUL SYLLABLE SSANGKIYEOK O KIYEOKSIOS + {0x848B, 0xAF31}, //597 #HANGUL SYLLABLE SSANGKIYEOK O NIEUNCIEUC + {0x848C, 0xAF33}, //598 #HANGUL SYLLABLE SSANGKIYEOK O TIKEUT + {0x848D, 0xAF35}, //599 #HANGUL SYLLABLE SSANGKIYEOK O RIEULKIYEOK + {0x848E, 0xAF36}, //600 #HANGUL SYLLABLE SSANGKIYEOK O RIEULMIEUM + {0x848F, 0xAF37}, //601 #HANGUL SYLLABLE SSANGKIYEOK O RIEULPIEUP + {0x8490, 0xAF38}, //602 #HANGUL SYLLABLE SSANGKIYEOK O RIEULSIOS + {0x8491, 0xAF39}, //603 #HANGUL SYLLABLE SSANGKIYEOK O RIEULTHIEUTH + {0x8492, 0xAF3A}, //604 #HANGUL SYLLABLE SSANGKIYEOK O RIEULPHIEUPH + {0x8493, 0xAF3B}, //605 #HANGUL SYLLABLE SSANGKIYEOK O RIEULHIEUH + {0x8494, 0xAF3E}, //606 #HANGUL SYLLABLE SSANGKIYEOK O PIEUPSIOS + {0x8495, 0xAF40}, //607 #HANGUL SYLLABLE SSANGKIYEOK O SSANGSIOS + {0x8496, 0xAF44}, //608 #HANGUL SYLLABLE SSANGKIYEOK O KHIEUKH + {0x8497, 0xAF45}, //609 #HANGUL SYLLABLE SSANGKIYEOK O THIEUTH + {0x8498, 0xAF46}, //610 #HANGUL SYLLABLE SSANGKIYEOK O PHIEUPH + {0x8499, 0xAF47}, //611 #HANGUL SYLLABLE SSANGKIYEOK O HIEUH + {0x849A, 0xAF4A}, //612 #HANGUL SYLLABLE SSANGKIYEOK WA SSANGKIYEOK + {0x849B, 0xAF4B}, //613 #HANGUL SYLLABLE SSANGKIYEOK WA KIYEOKSIOS + {0x849C, 0xAF4C}, //614 #HANGUL SYLLABLE SSANGKIYEOK WA NIEUN + {0x849D, 0xAF4D}, //615 #HANGUL SYLLABLE SSANGKIYEOK WA NIEUNCIEUC + {0x849E, 0xAF4E}, //616 #HANGUL SYLLABLE SSANGKIYEOK WA NIEUNHIEUH + {0x849F, 0xAF4F}, //617 #HANGUL SYLLABLE SSANGKIYEOK WA TIKEUT + {0x84A0, 0xAF51}, //618 #HANGUL SYLLABLE SSANGKIYEOK WA RIEULKIYEOK + {0x84A1, 0xAF52}, //619 #HANGUL SYLLABLE SSANGKIYEOK WA RIEULMIEUM + {0x84A2, 0xAF53}, //620 #HANGUL SYLLABLE SSANGKIYEOK WA RIEULPIEUP + {0x84A3, 0xAF54}, //621 #HANGUL SYLLABLE SSANGKIYEOK WA RIEULSIOS + {0x84A4, 0xAF55}, //622 #HANGUL SYLLABLE SSANGKIYEOK WA RIEULTHIEUTH + {0x84A5, 0xAF56}, //623 #HANGUL SYLLABLE SSANGKIYEOK WA RIEULPHIEUPH + {0x84A6, 0xAF57}, //624 #HANGUL SYLLABLE SSANGKIYEOK WA RIEULHIEUH + {0x84A7, 0xAF58}, //625 #HANGUL SYLLABLE SSANGKIYEOK WA MIEUM + {0x84A8, 0xAF59}, //626 #HANGUL SYLLABLE SSANGKIYEOK WA PIEUP + {0x84A9, 0xAF5A}, //627 #HANGUL SYLLABLE SSANGKIYEOK WA PIEUPSIOS + {0x84AA, 0xAF5B}, //628 #HANGUL SYLLABLE SSANGKIYEOK WA SIOS + {0x84AB, 0xAF5E}, //629 #HANGUL SYLLABLE SSANGKIYEOK WA CIEUC + {0x84AC, 0xAF5F}, //630 #HANGUL SYLLABLE SSANGKIYEOK WA CHIEUCH + {0x84AD, 0xAF60}, //631 #HANGUL SYLLABLE SSANGKIYEOK WA KHIEUKH + {0x84AE, 0xAF61}, //632 #HANGUL SYLLABLE SSANGKIYEOK WA THIEUTH + {0x84AF, 0xAF62}, //633 #HANGUL SYLLABLE SSANGKIYEOK WA PHIEUPH + {0x84B0, 0xAF63}, //634 #HANGUL SYLLABLE SSANGKIYEOK WA HIEUH + {0x84B1, 0xAF66}, //635 #HANGUL SYLLABLE SSANGKIYEOK WAE SSANGKIYEOK + {0x84B2, 0xAF67}, //636 #HANGUL SYLLABLE SSANGKIYEOK WAE KIYEOKSIOS + {0x84B3, 0xAF68}, //637 #HANGUL SYLLABLE SSANGKIYEOK WAE NIEUN + {0x84B4, 0xAF69}, //638 #HANGUL SYLLABLE SSANGKIYEOK WAE NIEUNCIEUC + {0x84B5, 0xAF6A}, //639 #HANGUL SYLLABLE SSANGKIYEOK WAE NIEUNHIEUH + {0x84B6, 0xAF6B}, //640 #HANGUL SYLLABLE SSANGKIYEOK WAE TIKEUT + {0x84B7, 0xAF6C}, //641 #HANGUL SYLLABLE SSANGKIYEOK WAE RIEUL + {0x84B8, 0xAF6D}, //642 #HANGUL SYLLABLE SSANGKIYEOK WAE RIEULKIYEOK + {0x84B9, 0xAF6E}, //643 #HANGUL SYLLABLE SSANGKIYEOK WAE RIEULMIEUM + {0x84BA, 0xAF6F}, //644 #HANGUL SYLLABLE SSANGKIYEOK WAE RIEULPIEUP + {0x84BB, 0xAF70}, //645 #HANGUL SYLLABLE SSANGKIYEOK WAE RIEULSIOS + {0x84BC, 0xAF71}, //646 #HANGUL SYLLABLE SSANGKIYEOK WAE RIEULTHIEUTH + {0x84BD, 0xAF72}, //647 #HANGUL SYLLABLE SSANGKIYEOK WAE RIEULPHIEUPH + {0x84BE, 0xAF73}, //648 #HANGUL SYLLABLE SSANGKIYEOK WAE RIEULHIEUH + {0x84BF, 0xAF74}, //649 #HANGUL SYLLABLE SSANGKIYEOK WAE MIEUM + {0x84C0, 0xAF75}, //650 #HANGUL SYLLABLE SSANGKIYEOK WAE PIEUP + {0x84C1, 0xAF76}, //651 #HANGUL SYLLABLE SSANGKIYEOK WAE PIEUPSIOS + {0x84C2, 0xAF77}, //652 #HANGUL SYLLABLE SSANGKIYEOK WAE SIOS + {0x84C3, 0xAF78}, //653 #HANGUL SYLLABLE SSANGKIYEOK WAE SSANGSIOS + {0x84C4, 0xAF7A}, //654 #HANGUL SYLLABLE SSANGKIYEOK WAE CIEUC + {0x84C5, 0xAF7B}, //655 #HANGUL SYLLABLE SSANGKIYEOK WAE CHIEUCH + {0x84C6, 0xAF7C}, //656 #HANGUL SYLLABLE SSANGKIYEOK WAE KHIEUKH + {0x84C7, 0xAF7D}, //657 #HANGUL SYLLABLE SSANGKIYEOK WAE THIEUTH + {0x84C8, 0xAF7E}, //658 #HANGUL SYLLABLE SSANGKIYEOK WAE PHIEUPH + {0x84C9, 0xAF7F}, //659 #HANGUL SYLLABLE SSANGKIYEOK WAE HIEUH + {0x84CA, 0xAF81}, //660 #HANGUL SYLLABLE SSANGKIYEOK OE KIYEOK + {0x84CB, 0xAF82}, //661 #HANGUL SYLLABLE SSANGKIYEOK OE SSANGKIYEOK + {0x84CC, 0xAF83}, //662 #HANGUL SYLLABLE SSANGKIYEOK OE KIYEOKSIOS + {0x84CD, 0xAF85}, //663 #HANGUL SYLLABLE SSANGKIYEOK OE NIEUNCIEUC + {0x84CE, 0xAF86}, //664 #HANGUL SYLLABLE SSANGKIYEOK OE NIEUNHIEUH + {0x84CF, 0xAF87}, //665 #HANGUL SYLLABLE SSANGKIYEOK OE TIKEUT + {0x84D0, 0xAF89}, //666 #HANGUL SYLLABLE SSANGKIYEOK OE RIEULKIYEOK + {0x84D1, 0xAF8A}, //667 #HANGUL SYLLABLE SSANGKIYEOK OE RIEULMIEUM + {0x84D2, 0xAF8B}, //668 #HANGUL SYLLABLE SSANGKIYEOK OE RIEULPIEUP + {0x84D3, 0xAF8C}, //669 #HANGUL SYLLABLE SSANGKIYEOK OE RIEULSIOS + {0x84D4, 0xAF8D}, //670 #HANGUL SYLLABLE SSANGKIYEOK OE RIEULTHIEUTH + {0x84D5, 0xAF8E}, //671 #HANGUL SYLLABLE SSANGKIYEOK OE RIEULPHIEUPH + {0x84D6, 0xAF8F}, //672 #HANGUL SYLLABLE SSANGKIYEOK OE RIEULHIEUH + {0x84D7, 0xAF92}, //673 #HANGUL SYLLABLE SSANGKIYEOK OE PIEUPSIOS + {0x84D8, 0xAF93}, //674 #HANGUL SYLLABLE SSANGKIYEOK OE SIOS + {0x84D9, 0xAF94}, //675 #HANGUL SYLLABLE SSANGKIYEOK OE SSANGSIOS + {0x84DA, 0xAF96}, //676 #HANGUL SYLLABLE SSANGKIYEOK OE CIEUC + {0x84DB, 0xAF97}, //677 #HANGUL SYLLABLE SSANGKIYEOK OE CHIEUCH + {0x84DC, 0xAF98}, //678 #HANGUL SYLLABLE SSANGKIYEOK OE KHIEUKH + {0x84DD, 0xAF99}, //679 #HANGUL SYLLABLE SSANGKIYEOK OE THIEUTH + {0x84DE, 0xAF9A}, //680 #HANGUL SYLLABLE SSANGKIYEOK OE PHIEUPH + {0x84DF, 0xAF9B}, //681 #HANGUL SYLLABLE SSANGKIYEOK OE HIEUH + {0x84E0, 0xAF9D}, //682 #HANGUL SYLLABLE SSANGKIYEOK YO KIYEOK + {0x84E1, 0xAF9E}, //683 #HANGUL SYLLABLE SSANGKIYEOK YO SSANGKIYEOK + {0x84E2, 0xAF9F}, //684 #HANGUL SYLLABLE SSANGKIYEOK YO KIYEOKSIOS + {0x84E3, 0xAFA0}, //685 #HANGUL SYLLABLE SSANGKIYEOK YO NIEUN + {0x84E4, 0xAFA1}, //686 #HANGUL SYLLABLE SSANGKIYEOK YO NIEUNCIEUC + {0x84E5, 0xAFA2}, //687 #HANGUL SYLLABLE SSANGKIYEOK YO NIEUNHIEUH + {0x84E6, 0xAFA3}, //688 #HANGUL SYLLABLE SSANGKIYEOK YO TIKEUT + {0x84E7, 0xAFA4}, //689 #HANGUL SYLLABLE SSANGKIYEOK YO RIEUL + {0x84E8, 0xAFA5}, //690 #HANGUL SYLLABLE SSANGKIYEOK YO RIEULKIYEOK + {0x84E9, 0xAFA6}, //691 #HANGUL SYLLABLE SSANGKIYEOK YO RIEULMIEUM + {0x84EA, 0xAFA7}, //692 #HANGUL SYLLABLE SSANGKIYEOK YO RIEULPIEUP + {0x84EB, 0xAFA8}, //693 #HANGUL SYLLABLE SSANGKIYEOK YO RIEULSIOS + {0x84EC, 0xAFA9}, //694 #HANGUL SYLLABLE SSANGKIYEOK YO RIEULTHIEUTH + {0x84ED, 0xAFAA}, //695 #HANGUL SYLLABLE SSANGKIYEOK YO RIEULPHIEUPH + {0x84EE, 0xAFAB}, //696 #HANGUL SYLLABLE SSANGKIYEOK YO RIEULHIEUH + {0x84EF, 0xAFAC}, //697 #HANGUL SYLLABLE SSANGKIYEOK YO MIEUM + {0x84F0, 0xAFAD}, //698 #HANGUL SYLLABLE SSANGKIYEOK YO PIEUP + {0x84F1, 0xAFAE}, //699 #HANGUL SYLLABLE SSANGKIYEOK YO PIEUPSIOS + {0x84F2, 0xAFAF}, //700 #HANGUL SYLLABLE SSANGKIYEOK YO SIOS + {0x84F3, 0xAFB0}, //701 #HANGUL SYLLABLE SSANGKIYEOK YO SSANGSIOS + {0x84F4, 0xAFB1}, //702 #HANGUL SYLLABLE SSANGKIYEOK YO IEUNG + {0x84F5, 0xAFB2}, //703 #HANGUL SYLLABLE SSANGKIYEOK YO CIEUC + {0x84F6, 0xAFB3}, //704 #HANGUL SYLLABLE SSANGKIYEOK YO CHIEUCH + {0x84F7, 0xAFB4}, //705 #HANGUL SYLLABLE SSANGKIYEOK YO KHIEUKH + {0x84F8, 0xAFB5}, //706 #HANGUL SYLLABLE SSANGKIYEOK YO THIEUTH + {0x84F9, 0xAFB6}, //707 #HANGUL SYLLABLE SSANGKIYEOK YO PHIEUPH + {0x84FA, 0xAFB7}, //708 #HANGUL SYLLABLE SSANGKIYEOK YO HIEUH + {0x84FB, 0xAFBA}, //709 #HANGUL SYLLABLE SSANGKIYEOK U SSANGKIYEOK + {0x84FC, 0xAFBB}, //710 #HANGUL SYLLABLE SSANGKIYEOK U KIYEOKSIOS + {0x84FD, 0xAFBD}, //711 #HANGUL SYLLABLE SSANGKIYEOK U NIEUNCIEUC + {0x84FE, 0xAFBE}, //712 #HANGUL SYLLABLE SSANGKIYEOK U NIEUNHIEUH + {0x8541, 0xAFBF}, //713 #HANGUL SYLLABLE SSANGKIYEOK U TIKEUT + {0x8542, 0xAFC1}, //714 #HANGUL SYLLABLE SSANGKIYEOK U RIEULKIYEOK + {0x8543, 0xAFC2}, //715 #HANGUL SYLLABLE SSANGKIYEOK U RIEULMIEUM + {0x8544, 0xAFC3}, //716 #HANGUL SYLLABLE SSANGKIYEOK U RIEULPIEUP + {0x8545, 0xAFC4}, //717 #HANGUL SYLLABLE SSANGKIYEOK U RIEULSIOS + {0x8546, 0xAFC5}, //718 #HANGUL SYLLABLE SSANGKIYEOK U RIEULTHIEUTH + {0x8547, 0xAFC6}, //719 #HANGUL SYLLABLE SSANGKIYEOK U RIEULPHIEUPH + {0x8548, 0xAFCA}, //720 #HANGUL SYLLABLE SSANGKIYEOK U PIEUPSIOS + {0x8549, 0xAFCC}, //721 #HANGUL SYLLABLE SSANGKIYEOK U SSANGSIOS + {0x854A, 0xAFCF}, //722 #HANGUL SYLLABLE SSANGKIYEOK U CHIEUCH + {0x854B, 0xAFD0}, //723 #HANGUL SYLLABLE SSANGKIYEOK U KHIEUKH + {0x854C, 0xAFD1}, //724 #HANGUL SYLLABLE SSANGKIYEOK U THIEUTH + {0x854D, 0xAFD2}, //725 #HANGUL SYLLABLE SSANGKIYEOK U PHIEUPH + {0x854E, 0xAFD3}, //726 #HANGUL SYLLABLE SSANGKIYEOK U HIEUH + {0x854F, 0xAFD5}, //727 #HANGUL SYLLABLE SSANGKIYEOK WEO KIYEOK + {0x8550, 0xAFD6}, //728 #HANGUL SYLLABLE SSANGKIYEOK WEO SSANGKIYEOK + {0x8551, 0xAFD7}, //729 #HANGUL SYLLABLE SSANGKIYEOK WEO KIYEOKSIOS + {0x8552, 0xAFD8}, //730 #HANGUL SYLLABLE SSANGKIYEOK WEO NIEUN + {0x8553, 0xAFD9}, //731 #HANGUL SYLLABLE SSANGKIYEOK WEO NIEUNCIEUC + {0x8554, 0xAFDA}, //732 #HANGUL SYLLABLE SSANGKIYEOK WEO NIEUNHIEUH + {0x8555, 0xAFDB}, //733 #HANGUL SYLLABLE SSANGKIYEOK WEO TIKEUT + {0x8556, 0xAFDD}, //734 #HANGUL SYLLABLE SSANGKIYEOK WEO RIEULKIYEOK + {0x8557, 0xAFDE}, //735 #HANGUL SYLLABLE SSANGKIYEOK WEO RIEULMIEUM + {0x8558, 0xAFDF}, //736 #HANGUL SYLLABLE SSANGKIYEOK WEO RIEULPIEUP + {0x8559, 0xAFE0}, //737 #HANGUL SYLLABLE SSANGKIYEOK WEO RIEULSIOS + {0x855A, 0xAFE1}, //738 #HANGUL SYLLABLE SSANGKIYEOK WEO RIEULTHIEUTH + {0x8561, 0xAFE2}, //739 #HANGUL SYLLABLE SSANGKIYEOK WEO RIEULPHIEUPH + {0x8562, 0xAFE3}, //740 #HANGUL SYLLABLE SSANGKIYEOK WEO RIEULHIEUH + {0x8563, 0xAFE4}, //741 #HANGUL SYLLABLE SSANGKIYEOK WEO MIEUM + {0x8564, 0xAFE5}, //742 #HANGUL SYLLABLE SSANGKIYEOK WEO PIEUP + {0x8565, 0xAFE6}, //743 #HANGUL SYLLABLE SSANGKIYEOK WEO PIEUPSIOS + {0x8566, 0xAFE7}, //744 #HANGUL SYLLABLE SSANGKIYEOK WEO SIOS + {0x8567, 0xAFEA}, //745 #HANGUL SYLLABLE SSANGKIYEOK WEO CIEUC + {0x8568, 0xAFEB}, //746 #HANGUL SYLLABLE SSANGKIYEOK WEO CHIEUCH + {0x8569, 0xAFEC}, //747 #HANGUL SYLLABLE SSANGKIYEOK WEO KHIEUKH + {0x856A, 0xAFED}, //748 #HANGUL SYLLABLE SSANGKIYEOK WEO THIEUTH + {0x856B, 0xAFEE}, //749 #HANGUL SYLLABLE SSANGKIYEOK WEO PHIEUPH + {0x856C, 0xAFEF}, //750 #HANGUL SYLLABLE SSANGKIYEOK WEO HIEUH + {0x856D, 0xAFF2}, //751 #HANGUL SYLLABLE SSANGKIYEOK WE SSANGKIYEOK + {0x856E, 0xAFF3}, //752 #HANGUL SYLLABLE SSANGKIYEOK WE KIYEOKSIOS + {0x856F, 0xAFF5}, //753 #HANGUL SYLLABLE SSANGKIYEOK WE NIEUNCIEUC + {0x8570, 0xAFF6}, //754 #HANGUL SYLLABLE SSANGKIYEOK WE NIEUNHIEUH + {0x8571, 0xAFF7}, //755 #HANGUL SYLLABLE SSANGKIYEOK WE TIKEUT + {0x8572, 0xAFF9}, //756 #HANGUL SYLLABLE SSANGKIYEOK WE RIEULKIYEOK + {0x8573, 0xAFFA}, //757 #HANGUL SYLLABLE SSANGKIYEOK WE RIEULMIEUM + {0x8574, 0xAFFB}, //758 #HANGUL SYLLABLE SSANGKIYEOK WE RIEULPIEUP + {0x8575, 0xAFFC}, //759 #HANGUL SYLLABLE SSANGKIYEOK WE RIEULSIOS + {0x8576, 0xAFFD}, //760 #HANGUL SYLLABLE SSANGKIYEOK WE RIEULTHIEUTH + {0x8577, 0xAFFE}, //761 #HANGUL SYLLABLE SSANGKIYEOK WE RIEULPHIEUPH + {0x8578, 0xAFFF}, //762 #HANGUL SYLLABLE SSANGKIYEOK WE RIEULHIEUH + {0x8579, 0xB002}, //763 #HANGUL SYLLABLE SSANGKIYEOK WE PIEUPSIOS + {0x857A, 0xB003}, //764 #HANGUL SYLLABLE SSANGKIYEOK WE SIOS + {0x8581, 0xB005}, //765 #HANGUL SYLLABLE SSANGKIYEOK WE IEUNG + {0x8582, 0xB006}, //766 #HANGUL SYLLABLE SSANGKIYEOK WE CIEUC + {0x8583, 0xB007}, //767 #HANGUL SYLLABLE SSANGKIYEOK WE CHIEUCH + {0x8584, 0xB008}, //768 #HANGUL SYLLABLE SSANGKIYEOK WE KHIEUKH + {0x8585, 0xB009}, //769 #HANGUL SYLLABLE SSANGKIYEOK WE THIEUTH + {0x8586, 0xB00A}, //770 #HANGUL SYLLABLE SSANGKIYEOK WE PHIEUPH + {0x8587, 0xB00B}, //771 #HANGUL SYLLABLE SSANGKIYEOK WE HIEUH + {0x8588, 0xB00D}, //772 #HANGUL SYLLABLE SSANGKIYEOK WI KIYEOK + {0x8589, 0xB00E}, //773 #HANGUL SYLLABLE SSANGKIYEOK WI SSANGKIYEOK + {0x858A, 0xB00F}, //774 #HANGUL SYLLABLE SSANGKIYEOK WI KIYEOKSIOS + {0x858B, 0xB011}, //775 #HANGUL SYLLABLE SSANGKIYEOK WI NIEUNCIEUC + {0x858C, 0xB012}, //776 #HANGUL SYLLABLE SSANGKIYEOK WI NIEUNHIEUH + {0x858D, 0xB013}, //777 #HANGUL SYLLABLE SSANGKIYEOK WI TIKEUT + {0x858E, 0xB015}, //778 #HANGUL SYLLABLE SSANGKIYEOK WI RIEULKIYEOK + {0x858F, 0xB016}, //779 #HANGUL SYLLABLE SSANGKIYEOK WI RIEULMIEUM + {0x8590, 0xB017}, //780 #HANGUL SYLLABLE SSANGKIYEOK WI RIEULPIEUP + {0x8591, 0xB018}, //781 #HANGUL SYLLABLE SSANGKIYEOK WI RIEULSIOS + {0x8592, 0xB019}, //782 #HANGUL SYLLABLE SSANGKIYEOK WI RIEULTHIEUTH + {0x8593, 0xB01A}, //783 #HANGUL SYLLABLE SSANGKIYEOK WI RIEULPHIEUPH + {0x8594, 0xB01B}, //784 #HANGUL SYLLABLE SSANGKIYEOK WI RIEULHIEUH + {0x8595, 0xB01E}, //785 #HANGUL SYLLABLE SSANGKIYEOK WI PIEUPSIOS + {0x8596, 0xB01F}, //786 #HANGUL SYLLABLE SSANGKIYEOK WI SIOS + {0x8597, 0xB020}, //787 #HANGUL SYLLABLE SSANGKIYEOK WI SSANGSIOS + {0x8598, 0xB021}, //788 #HANGUL SYLLABLE SSANGKIYEOK WI IEUNG + {0x8599, 0xB022}, //789 #HANGUL SYLLABLE SSANGKIYEOK WI CIEUC + {0x859A, 0xB023}, //790 #HANGUL SYLLABLE SSANGKIYEOK WI CHIEUCH + {0x859B, 0xB024}, //791 #HANGUL SYLLABLE SSANGKIYEOK WI KHIEUKH + {0x859C, 0xB025}, //792 #HANGUL SYLLABLE SSANGKIYEOK WI THIEUTH + {0x859D, 0xB026}, //793 #HANGUL SYLLABLE SSANGKIYEOK WI PHIEUPH + {0x859E, 0xB027}, //794 #HANGUL SYLLABLE SSANGKIYEOK WI HIEUH + {0x859F, 0xB029}, //795 #HANGUL SYLLABLE SSANGKIYEOK YU KIYEOK + {0x85A0, 0xB02A}, //796 #HANGUL SYLLABLE SSANGKIYEOK YU SSANGKIYEOK + {0x85A1, 0xB02B}, //797 #HANGUL SYLLABLE SSANGKIYEOK YU KIYEOKSIOS + {0x85A2, 0xB02C}, //798 #HANGUL SYLLABLE SSANGKIYEOK YU NIEUN + {0x85A3, 0xB02D}, //799 #HANGUL SYLLABLE SSANGKIYEOK YU NIEUNCIEUC + {0x85A4, 0xB02E}, //800 #HANGUL SYLLABLE SSANGKIYEOK YU NIEUNHIEUH + {0x85A5, 0xB02F}, //801 #HANGUL SYLLABLE SSANGKIYEOK YU TIKEUT + {0x85A6, 0xB030}, //802 #HANGUL SYLLABLE SSANGKIYEOK YU RIEUL + {0x85A7, 0xB031}, //803 #HANGUL SYLLABLE SSANGKIYEOK YU RIEULKIYEOK + {0x85A8, 0xB032}, //804 #HANGUL SYLLABLE SSANGKIYEOK YU RIEULMIEUM + {0x85A9, 0xB033}, //805 #HANGUL SYLLABLE SSANGKIYEOK YU RIEULPIEUP + {0x85AA, 0xB034}, //806 #HANGUL SYLLABLE SSANGKIYEOK YU RIEULSIOS + {0x85AB, 0xB035}, //807 #HANGUL SYLLABLE SSANGKIYEOK YU RIEULTHIEUTH + {0x85AC, 0xB036}, //808 #HANGUL SYLLABLE SSANGKIYEOK YU RIEULPHIEUPH + {0x85AD, 0xB037}, //809 #HANGUL SYLLABLE SSANGKIYEOK YU RIEULHIEUH + {0x85AE, 0xB038}, //810 #HANGUL SYLLABLE SSANGKIYEOK YU MIEUM + {0x85AF, 0xB039}, //811 #HANGUL SYLLABLE SSANGKIYEOK YU PIEUP + {0x85B0, 0xB03A}, //812 #HANGUL SYLLABLE SSANGKIYEOK YU PIEUPSIOS + {0x85B1, 0xB03B}, //813 #HANGUL SYLLABLE SSANGKIYEOK YU SIOS + {0x85B2, 0xB03C}, //814 #HANGUL SYLLABLE SSANGKIYEOK YU SSANGSIOS + {0x85B3, 0xB03D}, //815 #HANGUL SYLLABLE SSANGKIYEOK YU IEUNG + {0x85B4, 0xB03E}, //816 #HANGUL SYLLABLE SSANGKIYEOK YU CIEUC + {0x85B5, 0xB03F}, //817 #HANGUL SYLLABLE SSANGKIYEOK YU CHIEUCH + {0x85B6, 0xB040}, //818 #HANGUL SYLLABLE SSANGKIYEOK YU KHIEUKH + {0x85B7, 0xB041}, //819 #HANGUL SYLLABLE SSANGKIYEOK YU THIEUTH + {0x85B8, 0xB042}, //820 #HANGUL SYLLABLE SSANGKIYEOK YU PHIEUPH + {0x85B9, 0xB043}, //821 #HANGUL SYLLABLE SSANGKIYEOK YU HIEUH + {0x85BA, 0xB046}, //822 #HANGUL SYLLABLE SSANGKIYEOK EU SSANGKIYEOK + {0x85BB, 0xB047}, //823 #HANGUL SYLLABLE SSANGKIYEOK EU KIYEOKSIOS + {0x85BC, 0xB049}, //824 #HANGUL SYLLABLE SSANGKIYEOK EU NIEUNCIEUC + {0x85BD, 0xB04B}, //825 #HANGUL SYLLABLE SSANGKIYEOK EU TIKEUT + {0x85BE, 0xB04D}, //826 #HANGUL SYLLABLE SSANGKIYEOK EU RIEULKIYEOK + {0x85BF, 0xB04F}, //827 #HANGUL SYLLABLE SSANGKIYEOK EU RIEULPIEUP + {0x85C0, 0xB050}, //828 #HANGUL SYLLABLE SSANGKIYEOK EU RIEULSIOS + {0x85C1, 0xB051}, //829 #HANGUL SYLLABLE SSANGKIYEOK EU RIEULTHIEUTH + {0x85C2, 0xB052}, //830 #HANGUL SYLLABLE SSANGKIYEOK EU RIEULPHIEUPH + {0x85C3, 0xB056}, //831 #HANGUL SYLLABLE SSANGKIYEOK EU PIEUPSIOS + {0x85C4, 0xB058}, //832 #HANGUL SYLLABLE SSANGKIYEOK EU SSANGSIOS + {0x85C5, 0xB05A}, //833 #HANGUL SYLLABLE SSANGKIYEOK EU CIEUC + {0x85C6, 0xB05B}, //834 #HANGUL SYLLABLE SSANGKIYEOK EU CHIEUCH + {0x85C7, 0xB05C}, //835 #HANGUL SYLLABLE SSANGKIYEOK EU KHIEUKH + {0x85C8, 0xB05E}, //836 #HANGUL SYLLABLE SSANGKIYEOK EU PHIEUPH + {0x85C9, 0xB05F}, //837 #HANGUL SYLLABLE SSANGKIYEOK EU HIEUH + {0x85CA, 0xB060}, //838 #HANGUL SYLLABLE SSANGKIYEOK YI + {0x85CB, 0xB061}, //839 #HANGUL SYLLABLE SSANGKIYEOK YI KIYEOK + {0x85CC, 0xB062}, //840 #HANGUL SYLLABLE SSANGKIYEOK YI SSANGKIYEOK + {0x85CD, 0xB063}, //841 #HANGUL SYLLABLE SSANGKIYEOK YI KIYEOKSIOS + {0x85CE, 0xB064}, //842 #HANGUL SYLLABLE SSANGKIYEOK YI NIEUN + {0x85CF, 0xB065}, //843 #HANGUL SYLLABLE SSANGKIYEOK YI NIEUNCIEUC + {0x85D0, 0xB066}, //844 #HANGUL SYLLABLE SSANGKIYEOK YI NIEUNHIEUH + {0x85D1, 0xB067}, //845 #HANGUL SYLLABLE SSANGKIYEOK YI TIKEUT + {0x85D2, 0xB068}, //846 #HANGUL SYLLABLE SSANGKIYEOK YI RIEUL + {0x85D3, 0xB069}, //847 #HANGUL SYLLABLE SSANGKIYEOK YI RIEULKIYEOK + {0x85D4, 0xB06A}, //848 #HANGUL SYLLABLE SSANGKIYEOK YI RIEULMIEUM + {0x85D5, 0xB06B}, //849 #HANGUL SYLLABLE SSANGKIYEOK YI RIEULPIEUP + {0x85D6, 0xB06C}, //850 #HANGUL SYLLABLE SSANGKIYEOK YI RIEULSIOS + {0x85D7, 0xB06D}, //851 #HANGUL SYLLABLE SSANGKIYEOK YI RIEULTHIEUTH + {0x85D8, 0xB06E}, //852 #HANGUL SYLLABLE SSANGKIYEOK YI RIEULPHIEUPH + {0x85D9, 0xB06F}, //853 #HANGUL SYLLABLE SSANGKIYEOK YI RIEULHIEUH + {0x85DA, 0xB070}, //854 #HANGUL SYLLABLE SSANGKIYEOK YI MIEUM + {0x85DB, 0xB071}, //855 #HANGUL SYLLABLE SSANGKIYEOK YI PIEUP + {0x85DC, 0xB072}, //856 #HANGUL SYLLABLE SSANGKIYEOK YI PIEUPSIOS + {0x85DD, 0xB073}, //857 #HANGUL SYLLABLE SSANGKIYEOK YI SIOS + {0x85DE, 0xB074}, //858 #HANGUL SYLLABLE SSANGKIYEOK YI SSANGSIOS + {0x85DF, 0xB075}, //859 #HANGUL SYLLABLE SSANGKIYEOK YI IEUNG + {0x85E0, 0xB076}, //860 #HANGUL SYLLABLE SSANGKIYEOK YI CIEUC + {0x85E1, 0xB077}, //861 #HANGUL SYLLABLE SSANGKIYEOK YI CHIEUCH + {0x85E2, 0xB078}, //862 #HANGUL SYLLABLE SSANGKIYEOK YI KHIEUKH + {0x85E3, 0xB079}, //863 #HANGUL SYLLABLE SSANGKIYEOK YI THIEUTH + {0x85E4, 0xB07A}, //864 #HANGUL SYLLABLE SSANGKIYEOK YI PHIEUPH + {0x85E5, 0xB07B}, //865 #HANGUL SYLLABLE SSANGKIYEOK YI HIEUH + {0x85E6, 0xB07E}, //866 #HANGUL SYLLABLE SSANGKIYEOK I SSANGKIYEOK + {0x85E7, 0xB07F}, //867 #HANGUL SYLLABLE SSANGKIYEOK I KIYEOKSIOS + {0x85E8, 0xB081}, //868 #HANGUL SYLLABLE SSANGKIYEOK I NIEUNCIEUC + {0x85E9, 0xB082}, //869 #HANGUL SYLLABLE SSANGKIYEOK I NIEUNHIEUH + {0x85EA, 0xB083}, //870 #HANGUL SYLLABLE SSANGKIYEOK I TIKEUT + {0x85EB, 0xB085}, //871 #HANGUL SYLLABLE SSANGKIYEOK I RIEULKIYEOK + {0x85EC, 0xB086}, //872 #HANGUL SYLLABLE SSANGKIYEOK I RIEULMIEUM + {0x85ED, 0xB087}, //873 #HANGUL SYLLABLE SSANGKIYEOK I RIEULPIEUP + {0x85EE, 0xB088}, //874 #HANGUL SYLLABLE SSANGKIYEOK I RIEULSIOS + {0x85EF, 0xB089}, //875 #HANGUL SYLLABLE SSANGKIYEOK I RIEULTHIEUTH + {0x85F0, 0xB08A}, //876 #HANGUL SYLLABLE SSANGKIYEOK I RIEULPHIEUPH + {0x85F1, 0xB08B}, //877 #HANGUL SYLLABLE SSANGKIYEOK I RIEULHIEUH + {0x85F2, 0xB08E}, //878 #HANGUL SYLLABLE SSANGKIYEOK I PIEUPSIOS + {0x85F3, 0xB090}, //879 #HANGUL SYLLABLE SSANGKIYEOK I SSANGSIOS + {0x85F4, 0xB092}, //880 #HANGUL SYLLABLE SSANGKIYEOK I CIEUC + {0x85F5, 0xB093}, //881 #HANGUL SYLLABLE SSANGKIYEOK I CHIEUCH + {0x85F6, 0xB094}, //882 #HANGUL SYLLABLE SSANGKIYEOK I KHIEUKH + {0x85F7, 0xB095}, //883 #HANGUL SYLLABLE SSANGKIYEOK I THIEUTH + {0x85F8, 0xB096}, //884 #HANGUL SYLLABLE SSANGKIYEOK I PHIEUPH + {0x85F9, 0xB097}, //885 #HANGUL SYLLABLE SSANGKIYEOK I HIEUH + {0x85FA, 0xB09B}, //886 #HANGUL SYLLABLE NIEUN A KIYEOKSIOS + {0x85FB, 0xB09D}, //887 #HANGUL SYLLABLE NIEUN A NIEUNCIEUC + {0x85FC, 0xB09E}, //888 #HANGUL SYLLABLE NIEUN A NIEUNHIEUH + {0x85FD, 0xB0A3}, //889 #HANGUL SYLLABLE NIEUN A RIEULPIEUP + {0x85FE, 0xB0A4}, //890 #HANGUL SYLLABLE NIEUN A RIEULSIOS + {0x8641, 0xB0A5}, //891 #HANGUL SYLLABLE NIEUN A RIEULTHIEUTH + {0x8642, 0xB0A6}, //892 #HANGUL SYLLABLE NIEUN A RIEULPHIEUPH + {0x8643, 0xB0A7}, //893 #HANGUL SYLLABLE NIEUN A RIEULHIEUH + {0x8644, 0xB0AA}, //894 #HANGUL SYLLABLE NIEUN A PIEUPSIOS + {0x8645, 0xB0B0}, //895 #HANGUL SYLLABLE NIEUN A KHIEUKH + {0x8646, 0xB0B2}, //896 #HANGUL SYLLABLE NIEUN A PHIEUPH + {0x8647, 0xB0B6}, //897 #HANGUL SYLLABLE NIEUN AE SSANGKIYEOK + {0x8648, 0xB0B7}, //898 #HANGUL SYLLABLE NIEUN AE KIYEOKSIOS + {0x8649, 0xB0B9}, //899 #HANGUL SYLLABLE NIEUN AE NIEUNCIEUC + {0x864A, 0xB0BA}, //900 #HANGUL SYLLABLE NIEUN AE NIEUNHIEUH + {0x864B, 0xB0BB}, //901 #HANGUL SYLLABLE NIEUN AE TIKEUT + {0x864C, 0xB0BD}, //902 #HANGUL SYLLABLE NIEUN AE RIEULKIYEOK + {0x864D, 0xB0BE}, //903 #HANGUL SYLLABLE NIEUN AE RIEULMIEUM + {0x864E, 0xB0BF}, //904 #HANGUL SYLLABLE NIEUN AE RIEULPIEUP + {0x864F, 0xB0C0}, //905 #HANGUL SYLLABLE NIEUN AE RIEULSIOS + {0x8650, 0xB0C1}, //906 #HANGUL SYLLABLE NIEUN AE RIEULTHIEUTH + {0x8651, 0xB0C2}, //907 #HANGUL SYLLABLE NIEUN AE RIEULPHIEUPH + {0x8652, 0xB0C3}, //908 #HANGUL SYLLABLE NIEUN AE RIEULHIEUH + {0x8653, 0xB0C6}, //909 #HANGUL SYLLABLE NIEUN AE PIEUPSIOS + {0x8654, 0xB0CA}, //910 #HANGUL SYLLABLE NIEUN AE CIEUC + {0x8655, 0xB0CB}, //911 #HANGUL SYLLABLE NIEUN AE CHIEUCH + {0x8656, 0xB0CC}, //912 #HANGUL SYLLABLE NIEUN AE KHIEUKH + {0x8657, 0xB0CD}, //913 #HANGUL SYLLABLE NIEUN AE THIEUTH + {0x8658, 0xB0CE}, //914 #HANGUL SYLLABLE NIEUN AE PHIEUPH + {0x8659, 0xB0CF}, //915 #HANGUL SYLLABLE NIEUN AE HIEUH + {0x865A, 0xB0D2}, //916 #HANGUL SYLLABLE NIEUN YA SSANGKIYEOK + {0x8661, 0xB0D3}, //917 #HANGUL SYLLABLE NIEUN YA KIYEOKSIOS + {0x8662, 0xB0D5}, //918 #HANGUL SYLLABLE NIEUN YA NIEUNCIEUC + {0x8663, 0xB0D6}, //919 #HANGUL SYLLABLE NIEUN YA NIEUNHIEUH + {0x8664, 0xB0D7}, //920 #HANGUL SYLLABLE NIEUN YA TIKEUT + {0x8665, 0xB0D9}, //921 #HANGUL SYLLABLE NIEUN YA RIEULKIYEOK + {0x8666, 0xB0DA}, //922 #HANGUL SYLLABLE NIEUN YA RIEULMIEUM + {0x8667, 0xB0DB}, //923 #HANGUL SYLLABLE NIEUN YA RIEULPIEUP + {0x8668, 0xB0DC}, //924 #HANGUL SYLLABLE NIEUN YA RIEULSIOS + {0x8669, 0xB0DD}, //925 #HANGUL SYLLABLE NIEUN YA RIEULTHIEUTH + {0x866A, 0xB0DE}, //926 #HANGUL SYLLABLE NIEUN YA RIEULPHIEUPH + {0x866B, 0xB0DF}, //927 #HANGUL SYLLABLE NIEUN YA RIEULHIEUH + {0x866C, 0xB0E1}, //928 #HANGUL SYLLABLE NIEUN YA PIEUP + {0x866D, 0xB0E2}, //929 #HANGUL SYLLABLE NIEUN YA PIEUPSIOS + {0x866E, 0xB0E3}, //930 #HANGUL SYLLABLE NIEUN YA SIOS + {0x866F, 0xB0E4}, //931 #HANGUL SYLLABLE NIEUN YA SSANGSIOS + {0x8670, 0xB0E6}, //932 #HANGUL SYLLABLE NIEUN YA CIEUC + {0x8671, 0xB0E7}, //933 #HANGUL SYLLABLE NIEUN YA CHIEUCH + {0x8672, 0xB0E8}, //934 #HANGUL SYLLABLE NIEUN YA KHIEUKH + {0x8673, 0xB0E9}, //935 #HANGUL SYLLABLE NIEUN YA THIEUTH + {0x8674, 0xB0EA}, //936 #HANGUL SYLLABLE NIEUN YA PHIEUPH + {0x8675, 0xB0EB}, //937 #HANGUL SYLLABLE NIEUN YA HIEUH + {0x8676, 0xB0EC}, //938 #HANGUL SYLLABLE NIEUN YAE + {0x8677, 0xB0ED}, //939 #HANGUL SYLLABLE NIEUN YAE KIYEOK + {0x8678, 0xB0EE}, //940 #HANGUL SYLLABLE NIEUN YAE SSANGKIYEOK + {0x8679, 0xB0EF}, //941 #HANGUL SYLLABLE NIEUN YAE KIYEOKSIOS + {0x867A, 0xB0F0}, //942 #HANGUL SYLLABLE NIEUN YAE NIEUN + {0x8681, 0xB0F1}, //943 #HANGUL SYLLABLE NIEUN YAE NIEUNCIEUC + {0x8682, 0xB0F2}, //944 #HANGUL SYLLABLE NIEUN YAE NIEUNHIEUH + {0x8683, 0xB0F3}, //945 #HANGUL SYLLABLE NIEUN YAE TIKEUT + {0x8684, 0xB0F4}, //946 #HANGUL SYLLABLE NIEUN YAE RIEUL + {0x8685, 0xB0F5}, //947 #HANGUL SYLLABLE NIEUN YAE RIEULKIYEOK + {0x8686, 0xB0F6}, //948 #HANGUL SYLLABLE NIEUN YAE RIEULMIEUM + {0x8687, 0xB0F7}, //949 #HANGUL SYLLABLE NIEUN YAE RIEULPIEUP + {0x8688, 0xB0F8}, //950 #HANGUL SYLLABLE NIEUN YAE RIEULSIOS + {0x8689, 0xB0F9}, //951 #HANGUL SYLLABLE NIEUN YAE RIEULTHIEUTH + {0x868A, 0xB0FA}, //952 #HANGUL SYLLABLE NIEUN YAE RIEULPHIEUPH + {0x868B, 0xB0FB}, //953 #HANGUL SYLLABLE NIEUN YAE RIEULHIEUH + {0x868C, 0xB0FC}, //954 #HANGUL SYLLABLE NIEUN YAE MIEUM + {0x868D, 0xB0FD}, //955 #HANGUL SYLLABLE NIEUN YAE PIEUP + {0x868E, 0xB0FE}, //956 #HANGUL SYLLABLE NIEUN YAE PIEUPSIOS + {0x868F, 0xB0FF}, //957 #HANGUL SYLLABLE NIEUN YAE SIOS + {0x8690, 0xB100}, //958 #HANGUL SYLLABLE NIEUN YAE SSANGSIOS + {0x8691, 0xB101}, //959 #HANGUL SYLLABLE NIEUN YAE IEUNG + {0x8692, 0xB102}, //960 #HANGUL SYLLABLE NIEUN YAE CIEUC + {0x8693, 0xB103}, //961 #HANGUL SYLLABLE NIEUN YAE CHIEUCH + {0x8694, 0xB104}, //962 #HANGUL SYLLABLE NIEUN YAE KHIEUKH + {0x8695, 0xB105}, //963 #HANGUL SYLLABLE NIEUN YAE THIEUTH + {0x8696, 0xB106}, //964 #HANGUL SYLLABLE NIEUN YAE PHIEUPH + {0x8697, 0xB107}, //965 #HANGUL SYLLABLE NIEUN YAE HIEUH + {0x8698, 0xB10A}, //966 #HANGUL SYLLABLE NIEUN EO SSANGKIYEOK + {0x8699, 0xB10D}, //967 #HANGUL SYLLABLE NIEUN EO NIEUNCIEUC + {0x869A, 0xB10E}, //968 #HANGUL SYLLABLE NIEUN EO NIEUNHIEUH + {0x869B, 0xB10F}, //969 #HANGUL SYLLABLE NIEUN EO TIKEUT + {0x869C, 0xB111}, //970 #HANGUL SYLLABLE NIEUN EO RIEULKIYEOK + {0x869D, 0xB114}, //971 #HANGUL SYLLABLE NIEUN EO RIEULSIOS + {0x869E, 0xB115}, //972 #HANGUL SYLLABLE NIEUN EO RIEULTHIEUTH + {0x869F, 0xB116}, //973 #HANGUL SYLLABLE NIEUN EO RIEULPHIEUPH + {0x86A0, 0xB117}, //974 #HANGUL SYLLABLE NIEUN EO RIEULHIEUH + {0x86A1, 0xB11A}, //975 #HANGUL SYLLABLE NIEUN EO PIEUPSIOS + {0x86A2, 0xB11E}, //976 #HANGUL SYLLABLE NIEUN EO CIEUC + {0x86A3, 0xB11F}, //977 #HANGUL SYLLABLE NIEUN EO CHIEUCH + {0x86A4, 0xB120}, //978 #HANGUL SYLLABLE NIEUN EO KHIEUKH + {0x86A5, 0xB121}, //979 #HANGUL SYLLABLE NIEUN EO THIEUTH + {0x86A6, 0xB122}, //980 #HANGUL SYLLABLE NIEUN EO PHIEUPH + {0x86A7, 0xB126}, //981 #HANGUL SYLLABLE NIEUN E SSANGKIYEOK + {0x86A8, 0xB127}, //982 #HANGUL SYLLABLE NIEUN E KIYEOKSIOS + {0x86A9, 0xB129}, //983 #HANGUL SYLLABLE NIEUN E NIEUNCIEUC + {0x86AA, 0xB12A}, //984 #HANGUL SYLLABLE NIEUN E NIEUNHIEUH + {0x86AB, 0xB12B}, //985 #HANGUL SYLLABLE NIEUN E TIKEUT + {0x86AC, 0xB12D}, //986 #HANGUL SYLLABLE NIEUN E RIEULKIYEOK + {0x86AD, 0xB12E}, //987 #HANGUL SYLLABLE NIEUN E RIEULMIEUM + {0x86AE, 0xB12F}, //988 #HANGUL SYLLABLE NIEUN E RIEULPIEUP + {0x86AF, 0xB130}, //989 #HANGUL SYLLABLE NIEUN E RIEULSIOS + {0x86B0, 0xB131}, //990 #HANGUL SYLLABLE NIEUN E RIEULTHIEUTH + {0x86B1, 0xB132}, //991 #HANGUL SYLLABLE NIEUN E RIEULPHIEUPH + {0x86B2, 0xB133}, //992 #HANGUL SYLLABLE NIEUN E RIEULHIEUH + {0x86B3, 0xB136}, //993 #HANGUL SYLLABLE NIEUN E PIEUPSIOS + {0x86B4, 0xB13A}, //994 #HANGUL SYLLABLE NIEUN E CIEUC + {0x86B5, 0xB13B}, //995 #HANGUL SYLLABLE NIEUN E CHIEUCH + {0x86B6, 0xB13C}, //996 #HANGUL SYLLABLE NIEUN E KHIEUKH + {0x86B7, 0xB13D}, //997 #HANGUL SYLLABLE NIEUN E THIEUTH + {0x86B8, 0xB13E}, //998 #HANGUL SYLLABLE NIEUN E PHIEUPH + {0x86B9, 0xB13F}, //999 #HANGUL SYLLABLE NIEUN E HIEUH + {0x86BA, 0xB142}, //1000 #HANGUL SYLLABLE NIEUN YEO SSANGKIYEOK + {0x86BB, 0xB143}, //1001 #HANGUL SYLLABLE NIEUN YEO KIYEOKSIOS + {0x86BC, 0xB145}, //1002 #HANGUL SYLLABLE NIEUN YEO NIEUNCIEUC + {0x86BD, 0xB146}, //1003 #HANGUL SYLLABLE NIEUN YEO NIEUNHIEUH + {0x86BE, 0xB147}, //1004 #HANGUL SYLLABLE NIEUN YEO TIKEUT + {0x86BF, 0xB149}, //1005 #HANGUL SYLLABLE NIEUN YEO RIEULKIYEOK + {0x86C0, 0xB14A}, //1006 #HANGUL SYLLABLE NIEUN YEO RIEULMIEUM + {0x86C1, 0xB14B}, //1007 #HANGUL SYLLABLE NIEUN YEO RIEULPIEUP + {0x86C2, 0xB14C}, //1008 #HANGUL SYLLABLE NIEUN YEO RIEULSIOS + {0x86C3, 0xB14D}, //1009 #HANGUL SYLLABLE NIEUN YEO RIEULTHIEUTH + {0x86C4, 0xB14E}, //1010 #HANGUL SYLLABLE NIEUN YEO RIEULPHIEUPH + {0x86C5, 0xB14F}, //1011 #HANGUL SYLLABLE NIEUN YEO RIEULHIEUH + {0x86C6, 0xB152}, //1012 #HANGUL SYLLABLE NIEUN YEO PIEUPSIOS + {0x86C7, 0xB153}, //1013 #HANGUL SYLLABLE NIEUN YEO SIOS + {0x86C8, 0xB156}, //1014 #HANGUL SYLLABLE NIEUN YEO CIEUC + {0x86C9, 0xB157}, //1015 #HANGUL SYLLABLE NIEUN YEO CHIEUCH + {0x86CA, 0xB159}, //1016 #HANGUL SYLLABLE NIEUN YEO THIEUTH + {0x86CB, 0xB15A}, //1017 #HANGUL SYLLABLE NIEUN YEO PHIEUPH + {0x86CC, 0xB15B}, //1018 #HANGUL SYLLABLE NIEUN YEO HIEUH + {0x86CD, 0xB15D}, //1019 #HANGUL SYLLABLE NIEUN YE KIYEOK + {0x86CE, 0xB15E}, //1020 #HANGUL SYLLABLE NIEUN YE SSANGKIYEOK + {0x86CF, 0xB15F}, //1021 #HANGUL SYLLABLE NIEUN YE KIYEOKSIOS + {0x86D0, 0xB161}, //1022 #HANGUL SYLLABLE NIEUN YE NIEUNCIEUC + {0x86D1, 0xB162}, //1023 #HANGUL SYLLABLE NIEUN YE NIEUNHIEUH + {0x86D2, 0xB163}, //1024 #HANGUL SYLLABLE NIEUN YE TIKEUT + {0x86D3, 0xB164}, //1025 #HANGUL SYLLABLE NIEUN YE RIEUL + {0x86D4, 0xB165}, //1026 #HANGUL SYLLABLE NIEUN YE RIEULKIYEOK + {0x86D5, 0xB166}, //1027 #HANGUL SYLLABLE NIEUN YE RIEULMIEUM + {0x86D6, 0xB167}, //1028 #HANGUL SYLLABLE NIEUN YE RIEULPIEUP + {0x86D7, 0xB168}, //1029 #HANGUL SYLLABLE NIEUN YE RIEULSIOS + {0x86D8, 0xB169}, //1030 #HANGUL SYLLABLE NIEUN YE RIEULTHIEUTH + {0x86D9, 0xB16A}, //1031 #HANGUL SYLLABLE NIEUN YE RIEULPHIEUPH + {0x86DA, 0xB16B}, //1032 #HANGUL SYLLABLE NIEUN YE RIEULHIEUH + {0x86DB, 0xB16C}, //1033 #HANGUL SYLLABLE NIEUN YE MIEUM + {0x86DC, 0xB16D}, //1034 #HANGUL SYLLABLE NIEUN YE PIEUP + {0x86DD, 0xB16E}, //1035 #HANGUL SYLLABLE NIEUN YE PIEUPSIOS + {0x86DE, 0xB16F}, //1036 #HANGUL SYLLABLE NIEUN YE SIOS + {0x86DF, 0xB170}, //1037 #HANGUL SYLLABLE NIEUN YE SSANGSIOS + {0x86E0, 0xB171}, //1038 #HANGUL SYLLABLE NIEUN YE IEUNG + {0x86E1, 0xB172}, //1039 #HANGUL SYLLABLE NIEUN YE CIEUC + {0x86E2, 0xB173}, //1040 #HANGUL SYLLABLE NIEUN YE CHIEUCH + {0x86E3, 0xB174}, //1041 #HANGUL SYLLABLE NIEUN YE KHIEUKH + {0x86E4, 0xB175}, //1042 #HANGUL SYLLABLE NIEUN YE THIEUTH + {0x86E5, 0xB176}, //1043 #HANGUL SYLLABLE NIEUN YE PHIEUPH + {0x86E6, 0xB177}, //1044 #HANGUL SYLLABLE NIEUN YE HIEUH + {0x86E7, 0xB17A}, //1045 #HANGUL SYLLABLE NIEUN O SSANGKIYEOK + {0x86E8, 0xB17B}, //1046 #HANGUL SYLLABLE NIEUN O KIYEOKSIOS + {0x86E9, 0xB17D}, //1047 #HANGUL SYLLABLE NIEUN O NIEUNCIEUC + {0x86EA, 0xB17E}, //1048 #HANGUL SYLLABLE NIEUN O NIEUNHIEUH + {0x86EB, 0xB17F}, //1049 #HANGUL SYLLABLE NIEUN O TIKEUT + {0x86EC, 0xB181}, //1050 #HANGUL SYLLABLE NIEUN O RIEULKIYEOK + {0x86ED, 0xB183}, //1051 #HANGUL SYLLABLE NIEUN O RIEULPIEUP + {0x86EE, 0xB184}, //1052 #HANGUL SYLLABLE NIEUN O RIEULSIOS + {0x86EF, 0xB185}, //1053 #HANGUL SYLLABLE NIEUN O RIEULTHIEUTH + {0x86F0, 0xB186}, //1054 #HANGUL SYLLABLE NIEUN O RIEULPHIEUPH + {0x86F1, 0xB187}, //1055 #HANGUL SYLLABLE NIEUN O RIEULHIEUH + {0x86F2, 0xB18A}, //1056 #HANGUL SYLLABLE NIEUN O PIEUPSIOS + {0x86F3, 0xB18C}, //1057 #HANGUL SYLLABLE NIEUN O SSANGSIOS + {0x86F4, 0xB18E}, //1058 #HANGUL SYLLABLE NIEUN O CIEUC + {0x86F5, 0xB18F}, //1059 #HANGUL SYLLABLE NIEUN O CHIEUCH + {0x86F6, 0xB190}, //1060 #HANGUL SYLLABLE NIEUN O KHIEUKH + {0x86F7, 0xB191}, //1061 #HANGUL SYLLABLE NIEUN O THIEUTH + {0x86F8, 0xB195}, //1062 #HANGUL SYLLABLE NIEUN WA KIYEOK + {0x86F9, 0xB196}, //1063 #HANGUL SYLLABLE NIEUN WA SSANGKIYEOK + {0x86FA, 0xB197}, //1064 #HANGUL SYLLABLE NIEUN WA KIYEOKSIOS + {0x86FB, 0xB199}, //1065 #HANGUL SYLLABLE NIEUN WA NIEUNCIEUC + {0x86FC, 0xB19A}, //1066 #HANGUL SYLLABLE NIEUN WA NIEUNHIEUH + {0x86FD, 0xB19B}, //1067 #HANGUL SYLLABLE NIEUN WA TIKEUT + {0x86FE, 0xB19D}, //1068 #HANGUL SYLLABLE NIEUN WA RIEULKIYEOK + {0x8741, 0xB19E}, //1069 #HANGUL SYLLABLE NIEUN WA RIEULMIEUM + {0x8742, 0xB19F}, //1070 #HANGUL SYLLABLE NIEUN WA RIEULPIEUP + {0x8743, 0xB1A0}, //1071 #HANGUL SYLLABLE NIEUN WA RIEULSIOS + {0x8744, 0xB1A1}, //1072 #HANGUL SYLLABLE NIEUN WA RIEULTHIEUTH + {0x8745, 0xB1A2}, //1073 #HANGUL SYLLABLE NIEUN WA RIEULPHIEUPH + {0x8746, 0xB1A3}, //1074 #HANGUL SYLLABLE NIEUN WA RIEULHIEUH + {0x8747, 0xB1A4}, //1075 #HANGUL SYLLABLE NIEUN WA MIEUM + {0x8748, 0xB1A5}, //1076 #HANGUL SYLLABLE NIEUN WA PIEUP + {0x8749, 0xB1A6}, //1077 #HANGUL SYLLABLE NIEUN WA PIEUPSIOS + {0x874A, 0xB1A7}, //1078 #HANGUL SYLLABLE NIEUN WA SIOS + {0x874B, 0xB1A9}, //1079 #HANGUL SYLLABLE NIEUN WA IEUNG + {0x874C, 0xB1AA}, //1080 #HANGUL SYLLABLE NIEUN WA CIEUC + {0x874D, 0xB1AB}, //1081 #HANGUL SYLLABLE NIEUN WA CHIEUCH + {0x874E, 0xB1AC}, //1082 #HANGUL SYLLABLE NIEUN WA KHIEUKH + {0x874F, 0xB1AD}, //1083 #HANGUL SYLLABLE NIEUN WA THIEUTH + {0x8750, 0xB1AE}, //1084 #HANGUL SYLLABLE NIEUN WA PHIEUPH + {0x8751, 0xB1AF}, //1085 #HANGUL SYLLABLE NIEUN WA HIEUH + {0x8752, 0xB1B0}, //1086 #HANGUL SYLLABLE NIEUN WAE + {0x8753, 0xB1B1}, //1087 #HANGUL SYLLABLE NIEUN WAE KIYEOK + {0x8754, 0xB1B2}, //1088 #HANGUL SYLLABLE NIEUN WAE SSANGKIYEOK + {0x8755, 0xB1B3}, //1089 #HANGUL SYLLABLE NIEUN WAE KIYEOKSIOS + {0x8756, 0xB1B4}, //1090 #HANGUL SYLLABLE NIEUN WAE NIEUN + {0x8757, 0xB1B5}, //1091 #HANGUL SYLLABLE NIEUN WAE NIEUNCIEUC + {0x8758, 0xB1B6}, //1092 #HANGUL SYLLABLE NIEUN WAE NIEUNHIEUH + {0x8759, 0xB1B7}, //1093 #HANGUL SYLLABLE NIEUN WAE TIKEUT + {0x875A, 0xB1B8}, //1094 #HANGUL SYLLABLE NIEUN WAE RIEUL + {0x8761, 0xB1B9}, //1095 #HANGUL SYLLABLE NIEUN WAE RIEULKIYEOK + {0x8762, 0xB1BA}, //1096 #HANGUL SYLLABLE NIEUN WAE RIEULMIEUM + {0x8763, 0xB1BB}, //1097 #HANGUL SYLLABLE NIEUN WAE RIEULPIEUP + {0x8764, 0xB1BC}, //1098 #HANGUL SYLLABLE NIEUN WAE RIEULSIOS + {0x8765, 0xB1BD}, //1099 #HANGUL SYLLABLE NIEUN WAE RIEULTHIEUTH + {0x8766, 0xB1BE}, //1100 #HANGUL SYLLABLE NIEUN WAE RIEULPHIEUPH + {0x8767, 0xB1BF}, //1101 #HANGUL SYLLABLE NIEUN WAE RIEULHIEUH + {0x8768, 0xB1C0}, //1102 #HANGUL SYLLABLE NIEUN WAE MIEUM + {0x8769, 0xB1C1}, //1103 #HANGUL SYLLABLE NIEUN WAE PIEUP + {0x876A, 0xB1C2}, //1104 #HANGUL SYLLABLE NIEUN WAE PIEUPSIOS + {0x876B, 0xB1C3}, //1105 #HANGUL SYLLABLE NIEUN WAE SIOS + {0x876C, 0xB1C4}, //1106 #HANGUL SYLLABLE NIEUN WAE SSANGSIOS + {0x876D, 0xB1C5}, //1107 #HANGUL SYLLABLE NIEUN WAE IEUNG + {0x876E, 0xB1C6}, //1108 #HANGUL SYLLABLE NIEUN WAE CIEUC + {0x876F, 0xB1C7}, //1109 #HANGUL SYLLABLE NIEUN WAE CHIEUCH + {0x8770, 0xB1C8}, //1110 #HANGUL SYLLABLE NIEUN WAE KHIEUKH + {0x8771, 0xB1C9}, //1111 #HANGUL SYLLABLE NIEUN WAE THIEUTH + {0x8772, 0xB1CA}, //1112 #HANGUL SYLLABLE NIEUN WAE PHIEUPH + {0x8773, 0xB1CB}, //1113 #HANGUL SYLLABLE NIEUN WAE HIEUH + {0x8774, 0xB1CD}, //1114 #HANGUL SYLLABLE NIEUN OE KIYEOK + {0x8775, 0xB1CE}, //1115 #HANGUL SYLLABLE NIEUN OE SSANGKIYEOK + {0x8776, 0xB1CF}, //1116 #HANGUL SYLLABLE NIEUN OE KIYEOKSIOS + {0x8777, 0xB1D1}, //1117 #HANGUL SYLLABLE NIEUN OE NIEUNCIEUC + {0x8778, 0xB1D2}, //1118 #HANGUL SYLLABLE NIEUN OE NIEUNHIEUH + {0x8779, 0xB1D3}, //1119 #HANGUL SYLLABLE NIEUN OE TIKEUT + {0x877A, 0xB1D5}, //1120 #HANGUL SYLLABLE NIEUN OE RIEULKIYEOK + {0x8781, 0xB1D6}, //1121 #HANGUL SYLLABLE NIEUN OE RIEULMIEUM + {0x8782, 0xB1D7}, //1122 #HANGUL SYLLABLE NIEUN OE RIEULPIEUP + {0x8783, 0xB1D8}, //1123 #HANGUL SYLLABLE NIEUN OE RIEULSIOS + {0x8784, 0xB1D9}, //1124 #HANGUL SYLLABLE NIEUN OE RIEULTHIEUTH + {0x8785, 0xB1DA}, //1125 #HANGUL SYLLABLE NIEUN OE RIEULPHIEUPH + {0x8786, 0xB1DB}, //1126 #HANGUL SYLLABLE NIEUN OE RIEULHIEUH + {0x8787, 0xB1DE}, //1127 #HANGUL SYLLABLE NIEUN OE PIEUPSIOS + {0x8788, 0xB1E0}, //1128 #HANGUL SYLLABLE NIEUN OE SSANGSIOS + {0x8789, 0xB1E1}, //1129 #HANGUL SYLLABLE NIEUN OE IEUNG + {0x878A, 0xB1E2}, //1130 #HANGUL SYLLABLE NIEUN OE CIEUC + {0x878B, 0xB1E3}, //1131 #HANGUL SYLLABLE NIEUN OE CHIEUCH + {0x878C, 0xB1E4}, //1132 #HANGUL SYLLABLE NIEUN OE KHIEUKH + {0x878D, 0xB1E5}, //1133 #HANGUL SYLLABLE NIEUN OE THIEUTH + {0x878E, 0xB1E6}, //1134 #HANGUL SYLLABLE NIEUN OE PHIEUPH + {0x878F, 0xB1E7}, //1135 #HANGUL SYLLABLE NIEUN OE HIEUH + {0x8790, 0xB1EA}, //1136 #HANGUL SYLLABLE NIEUN YO SSANGKIYEOK + {0x8791, 0xB1EB}, //1137 #HANGUL SYLLABLE NIEUN YO KIYEOKSIOS + {0x8792, 0xB1ED}, //1138 #HANGUL SYLLABLE NIEUN YO NIEUNCIEUC + {0x8793, 0xB1EE}, //1139 #HANGUL SYLLABLE NIEUN YO NIEUNHIEUH + {0x8794, 0xB1EF}, //1140 #HANGUL SYLLABLE NIEUN YO TIKEUT + {0x8795, 0xB1F1}, //1141 #HANGUL SYLLABLE NIEUN YO RIEULKIYEOK + {0x8796, 0xB1F2}, //1142 #HANGUL SYLLABLE NIEUN YO RIEULMIEUM + {0x8797, 0xB1F3}, //1143 #HANGUL SYLLABLE NIEUN YO RIEULPIEUP + {0x8798, 0xB1F4}, //1144 #HANGUL SYLLABLE NIEUN YO RIEULSIOS + {0x8799, 0xB1F5}, //1145 #HANGUL SYLLABLE NIEUN YO RIEULTHIEUTH + {0x879A, 0xB1F6}, //1146 #HANGUL SYLLABLE NIEUN YO RIEULPHIEUPH + {0x879B, 0xB1F7}, //1147 #HANGUL SYLLABLE NIEUN YO RIEULHIEUH + {0x879C, 0xB1F8}, //1148 #HANGUL SYLLABLE NIEUN YO MIEUM + {0x879D, 0xB1FA}, //1149 #HANGUL SYLLABLE NIEUN YO PIEUPSIOS + {0x879E, 0xB1FC}, //1150 #HANGUL SYLLABLE NIEUN YO SSANGSIOS + {0x879F, 0xB1FE}, //1151 #HANGUL SYLLABLE NIEUN YO CIEUC + {0x87A0, 0xB1FF}, //1152 #HANGUL SYLLABLE NIEUN YO CHIEUCH + {0x87A1, 0xB200}, //1153 #HANGUL SYLLABLE NIEUN YO KHIEUKH + {0x87A2, 0xB201}, //1154 #HANGUL SYLLABLE NIEUN YO THIEUTH + {0x87A3, 0xB202}, //1155 #HANGUL SYLLABLE NIEUN YO PHIEUPH + {0x87A4, 0xB203}, //1156 #HANGUL SYLLABLE NIEUN YO HIEUH + {0x87A5, 0xB206}, //1157 #HANGUL SYLLABLE NIEUN U SSANGKIYEOK + {0x87A6, 0xB207}, //1158 #HANGUL SYLLABLE NIEUN U KIYEOKSIOS + {0x87A7, 0xB209}, //1159 #HANGUL SYLLABLE NIEUN U NIEUNCIEUC + {0x87A8, 0xB20A}, //1160 #HANGUL SYLLABLE NIEUN U NIEUNHIEUH + {0x87A9, 0xB20D}, //1161 #HANGUL SYLLABLE NIEUN U RIEULKIYEOK + {0x87AA, 0xB20E}, //1162 #HANGUL SYLLABLE NIEUN U RIEULMIEUM + {0x87AB, 0xB20F}, //1163 #HANGUL SYLLABLE NIEUN U RIEULPIEUP + {0x87AC, 0xB210}, //1164 #HANGUL SYLLABLE NIEUN U RIEULSIOS + {0x87AD, 0xB211}, //1165 #HANGUL SYLLABLE NIEUN U RIEULTHIEUTH + {0x87AE, 0xB212}, //1166 #HANGUL SYLLABLE NIEUN U RIEULPHIEUPH + {0x87AF, 0xB213}, //1167 #HANGUL SYLLABLE NIEUN U RIEULHIEUH + {0x87B0, 0xB216}, //1168 #HANGUL SYLLABLE NIEUN U PIEUPSIOS + {0x87B1, 0xB218}, //1169 #HANGUL SYLLABLE NIEUN U SSANGSIOS + {0x87B2, 0xB21A}, //1170 #HANGUL SYLLABLE NIEUN U CIEUC + {0x87B3, 0xB21B}, //1171 #HANGUL SYLLABLE NIEUN U CHIEUCH + {0x87B4, 0xB21C}, //1172 #HANGUL SYLLABLE NIEUN U KHIEUKH + {0x87B5, 0xB21D}, //1173 #HANGUL SYLLABLE NIEUN U THIEUTH + {0x87B6, 0xB21E}, //1174 #HANGUL SYLLABLE NIEUN U PHIEUPH + {0x87B7, 0xB21F}, //1175 #HANGUL SYLLABLE NIEUN U HIEUH + {0x87B8, 0xB221}, //1176 #HANGUL SYLLABLE NIEUN WEO KIYEOK + {0x87B9, 0xB222}, //1177 #HANGUL SYLLABLE NIEUN WEO SSANGKIYEOK + {0x87BA, 0xB223}, //1178 #HANGUL SYLLABLE NIEUN WEO KIYEOKSIOS + {0x87BB, 0xB224}, //1179 #HANGUL SYLLABLE NIEUN WEO NIEUN + {0x87BC, 0xB225}, //1180 #HANGUL SYLLABLE NIEUN WEO NIEUNCIEUC + {0x87BD, 0xB226}, //1181 #HANGUL SYLLABLE NIEUN WEO NIEUNHIEUH + {0x87BE, 0xB227}, //1182 #HANGUL SYLLABLE NIEUN WEO TIKEUT + {0x87BF, 0xB228}, //1183 #HANGUL SYLLABLE NIEUN WEO RIEUL + {0x87C0, 0xB229}, //1184 #HANGUL SYLLABLE NIEUN WEO RIEULKIYEOK + {0x87C1, 0xB22A}, //1185 #HANGUL SYLLABLE NIEUN WEO RIEULMIEUM + {0x87C2, 0xB22B}, //1186 #HANGUL SYLLABLE NIEUN WEO RIEULPIEUP + {0x87C3, 0xB22C}, //1187 #HANGUL SYLLABLE NIEUN WEO RIEULSIOS + {0x87C4, 0xB22D}, //1188 #HANGUL SYLLABLE NIEUN WEO RIEULTHIEUTH + {0x87C5, 0xB22E}, //1189 #HANGUL SYLLABLE NIEUN WEO RIEULPHIEUPH + {0x87C6, 0xB22F}, //1190 #HANGUL SYLLABLE NIEUN WEO RIEULHIEUH + {0x87C7, 0xB230}, //1191 #HANGUL SYLLABLE NIEUN WEO MIEUM + {0x87C8, 0xB231}, //1192 #HANGUL SYLLABLE NIEUN WEO PIEUP + {0x87C9, 0xB232}, //1193 #HANGUL SYLLABLE NIEUN WEO PIEUPSIOS + {0x87CA, 0xB233}, //1194 #HANGUL SYLLABLE NIEUN WEO SIOS + {0x87CB, 0xB235}, //1195 #HANGUL SYLLABLE NIEUN WEO IEUNG + {0x87CC, 0xB236}, //1196 #HANGUL SYLLABLE NIEUN WEO CIEUC + {0x87CD, 0xB237}, //1197 #HANGUL SYLLABLE NIEUN WEO CHIEUCH + {0x87CE, 0xB238}, //1198 #HANGUL SYLLABLE NIEUN WEO KHIEUKH + {0x87CF, 0xB239}, //1199 #HANGUL SYLLABLE NIEUN WEO THIEUTH + {0x87D0, 0xB23A}, //1200 #HANGUL SYLLABLE NIEUN WEO PHIEUPH + {0x87D1, 0xB23B}, //1201 #HANGUL SYLLABLE NIEUN WEO HIEUH + {0x87D2, 0xB23D}, //1202 #HANGUL SYLLABLE NIEUN WE KIYEOK + {0x87D3, 0xB23E}, //1203 #HANGUL SYLLABLE NIEUN WE SSANGKIYEOK + {0x87D4, 0xB23F}, //1204 #HANGUL SYLLABLE NIEUN WE KIYEOKSIOS + {0x87D5, 0xB240}, //1205 #HANGUL SYLLABLE NIEUN WE NIEUN + {0x87D6, 0xB241}, //1206 #HANGUL SYLLABLE NIEUN WE NIEUNCIEUC + {0x87D7, 0xB242}, //1207 #HANGUL SYLLABLE NIEUN WE NIEUNHIEUH + {0x87D8, 0xB243}, //1208 #HANGUL SYLLABLE NIEUN WE TIKEUT + {0x87D9, 0xB244}, //1209 #HANGUL SYLLABLE NIEUN WE RIEUL + {0x87DA, 0xB245}, //1210 #HANGUL SYLLABLE NIEUN WE RIEULKIYEOK + {0x87DB, 0xB246}, //1211 #HANGUL SYLLABLE NIEUN WE RIEULMIEUM + {0x87DC, 0xB247}, //1212 #HANGUL SYLLABLE NIEUN WE RIEULPIEUP + {0x87DD, 0xB248}, //1213 #HANGUL SYLLABLE NIEUN WE RIEULSIOS + {0x87DE, 0xB249}, //1214 #HANGUL SYLLABLE NIEUN WE RIEULTHIEUTH + {0x87DF, 0xB24A}, //1215 #HANGUL SYLLABLE NIEUN WE RIEULPHIEUPH + {0x87E0, 0xB24B}, //1216 #HANGUL SYLLABLE NIEUN WE RIEULHIEUH + {0x87E1, 0xB24C}, //1217 #HANGUL SYLLABLE NIEUN WE MIEUM + {0x87E2, 0xB24D}, //1218 #HANGUL SYLLABLE NIEUN WE PIEUP + {0x87E3, 0xB24E}, //1219 #HANGUL SYLLABLE NIEUN WE PIEUPSIOS + {0x87E4, 0xB24F}, //1220 #HANGUL SYLLABLE NIEUN WE SIOS + {0x87E5, 0xB250}, //1221 #HANGUL SYLLABLE NIEUN WE SSANGSIOS + {0x87E6, 0xB251}, //1222 #HANGUL SYLLABLE NIEUN WE IEUNG + {0x87E7, 0xB252}, //1223 #HANGUL SYLLABLE NIEUN WE CIEUC + {0x87E8, 0xB253}, //1224 #HANGUL SYLLABLE NIEUN WE CHIEUCH + {0x87E9, 0xB254}, //1225 #HANGUL SYLLABLE NIEUN WE KHIEUKH + {0x87EA, 0xB255}, //1226 #HANGUL SYLLABLE NIEUN WE THIEUTH + {0x87EB, 0xB256}, //1227 #HANGUL SYLLABLE NIEUN WE PHIEUPH + {0x87EC, 0xB257}, //1228 #HANGUL SYLLABLE NIEUN WE HIEUH + {0x87ED, 0xB259}, //1229 #HANGUL SYLLABLE NIEUN WI KIYEOK + {0x87EE, 0xB25A}, //1230 #HANGUL SYLLABLE NIEUN WI SSANGKIYEOK + {0x87EF, 0xB25B}, //1231 #HANGUL SYLLABLE NIEUN WI KIYEOKSIOS + {0x87F0, 0xB25D}, //1232 #HANGUL SYLLABLE NIEUN WI NIEUNCIEUC + {0x87F1, 0xB25E}, //1233 #HANGUL SYLLABLE NIEUN WI NIEUNHIEUH + {0x87F2, 0xB25F}, //1234 #HANGUL SYLLABLE NIEUN WI TIKEUT + {0x87F3, 0xB261}, //1235 #HANGUL SYLLABLE NIEUN WI RIEULKIYEOK + {0x87F4, 0xB262}, //1236 #HANGUL SYLLABLE NIEUN WI RIEULMIEUM + {0x87F5, 0xB263}, //1237 #HANGUL SYLLABLE NIEUN WI RIEULPIEUP + {0x87F6, 0xB264}, //1238 #HANGUL SYLLABLE NIEUN WI RIEULSIOS + {0x87F7, 0xB265}, //1239 #HANGUL SYLLABLE NIEUN WI RIEULTHIEUTH + {0x87F8, 0xB266}, //1240 #HANGUL SYLLABLE NIEUN WI RIEULPHIEUPH + {0x87F9, 0xB267}, //1241 #HANGUL SYLLABLE NIEUN WI RIEULHIEUH + {0x87FA, 0xB26A}, //1242 #HANGUL SYLLABLE NIEUN WI PIEUPSIOS + {0x87FB, 0xB26B}, //1243 #HANGUL SYLLABLE NIEUN WI SIOS + {0x87FC, 0xB26C}, //1244 #HANGUL SYLLABLE NIEUN WI SSANGSIOS + {0x87FD, 0xB26D}, //1245 #HANGUL SYLLABLE NIEUN WI IEUNG + {0x87FE, 0xB26E}, //1246 #HANGUL SYLLABLE NIEUN WI CIEUC + {0x8841, 0xB26F}, //1247 #HANGUL SYLLABLE NIEUN WI CHIEUCH + {0x8842, 0xB270}, //1248 #HANGUL SYLLABLE NIEUN WI KHIEUKH + {0x8843, 0xB271}, //1249 #HANGUL SYLLABLE NIEUN WI THIEUTH + {0x8844, 0xB272}, //1250 #HANGUL SYLLABLE NIEUN WI PHIEUPH + {0x8845, 0xB273}, //1251 #HANGUL SYLLABLE NIEUN WI HIEUH + {0x8846, 0xB276}, //1252 #HANGUL SYLLABLE NIEUN YU SSANGKIYEOK + {0x8847, 0xB277}, //1253 #HANGUL SYLLABLE NIEUN YU KIYEOKSIOS + {0x8848, 0xB278}, //1254 #HANGUL SYLLABLE NIEUN YU NIEUN + {0x8849, 0xB279}, //1255 #HANGUL SYLLABLE NIEUN YU NIEUNCIEUC + {0x884A, 0xB27A}, //1256 #HANGUL SYLLABLE NIEUN YU NIEUNHIEUH + {0x884B, 0xB27B}, //1257 #HANGUL SYLLABLE NIEUN YU TIKEUT + {0x884C, 0xB27D}, //1258 #HANGUL SYLLABLE NIEUN YU RIEULKIYEOK + {0x884D, 0xB27E}, //1259 #HANGUL SYLLABLE NIEUN YU RIEULMIEUM + {0x884E, 0xB27F}, //1260 #HANGUL SYLLABLE NIEUN YU RIEULPIEUP + {0x884F, 0xB280}, //1261 #HANGUL SYLLABLE NIEUN YU RIEULSIOS + {0x8850, 0xB281}, //1262 #HANGUL SYLLABLE NIEUN YU RIEULTHIEUTH + {0x8851, 0xB282}, //1263 #HANGUL SYLLABLE NIEUN YU RIEULPHIEUPH + {0x8852, 0xB283}, //1264 #HANGUL SYLLABLE NIEUN YU RIEULHIEUH + {0x8853, 0xB286}, //1265 #HANGUL SYLLABLE NIEUN YU PIEUPSIOS + {0x8854, 0xB287}, //1266 #HANGUL SYLLABLE NIEUN YU SIOS + {0x8855, 0xB288}, //1267 #HANGUL SYLLABLE NIEUN YU SSANGSIOS + {0x8856, 0xB28A}, //1268 #HANGUL SYLLABLE NIEUN YU CIEUC + {0x8857, 0xB28B}, //1269 #HANGUL SYLLABLE NIEUN YU CHIEUCH + {0x8858, 0xB28C}, //1270 #HANGUL SYLLABLE NIEUN YU KHIEUKH + {0x8859, 0xB28D}, //1271 #HANGUL SYLLABLE NIEUN YU THIEUTH + {0x885A, 0xB28E}, //1272 #HANGUL SYLLABLE NIEUN YU PHIEUPH + {0x8861, 0xB28F}, //1273 #HANGUL SYLLABLE NIEUN YU HIEUH + {0x8862, 0xB292}, //1274 #HANGUL SYLLABLE NIEUN EU SSANGKIYEOK + {0x8863, 0xB293}, //1275 #HANGUL SYLLABLE NIEUN EU KIYEOKSIOS + {0x8864, 0xB295}, //1276 #HANGUL SYLLABLE NIEUN EU NIEUNCIEUC + {0x8865, 0xB296}, //1277 #HANGUL SYLLABLE NIEUN EU NIEUNHIEUH + {0x8866, 0xB297}, //1278 #HANGUL SYLLABLE NIEUN EU TIKEUT + {0x8867, 0xB29B}, //1279 #HANGUL SYLLABLE NIEUN EU RIEULPIEUP + {0x8868, 0xB29C}, //1280 #HANGUL SYLLABLE NIEUN EU RIEULSIOS + {0x8869, 0xB29D}, //1281 #HANGUL SYLLABLE NIEUN EU RIEULTHIEUTH + {0x886A, 0xB29E}, //1282 #HANGUL SYLLABLE NIEUN EU RIEULPHIEUPH + {0x886B, 0xB29F}, //1283 #HANGUL SYLLABLE NIEUN EU RIEULHIEUH + {0x886C, 0xB2A2}, //1284 #HANGUL SYLLABLE NIEUN EU PIEUPSIOS + {0x886D, 0xB2A4}, //1285 #HANGUL SYLLABLE NIEUN EU SSANGSIOS + {0x886E, 0xB2A7}, //1286 #HANGUL SYLLABLE NIEUN EU CHIEUCH + {0x886F, 0xB2A8}, //1287 #HANGUL SYLLABLE NIEUN EU KHIEUKH + {0x8870, 0xB2A9}, //1288 #HANGUL SYLLABLE NIEUN EU THIEUTH + {0x8871, 0xB2AB}, //1289 #HANGUL SYLLABLE NIEUN EU HIEUH + {0x8872, 0xB2AD}, //1290 #HANGUL SYLLABLE NIEUN YI KIYEOK + {0x8873, 0xB2AE}, //1291 #HANGUL SYLLABLE NIEUN YI SSANGKIYEOK + {0x8874, 0xB2AF}, //1292 #HANGUL SYLLABLE NIEUN YI KIYEOKSIOS + {0x8875, 0xB2B1}, //1293 #HANGUL SYLLABLE NIEUN YI NIEUNCIEUC + {0x8876, 0xB2B2}, //1294 #HANGUL SYLLABLE NIEUN YI NIEUNHIEUH + {0x8877, 0xB2B3}, //1295 #HANGUL SYLLABLE NIEUN YI TIKEUT + {0x8878, 0xB2B5}, //1296 #HANGUL SYLLABLE NIEUN YI RIEULKIYEOK + {0x8879, 0xB2B6}, //1297 #HANGUL SYLLABLE NIEUN YI RIEULMIEUM + {0x887A, 0xB2B7}, //1298 #HANGUL SYLLABLE NIEUN YI RIEULPIEUP + {0x8881, 0xB2B8}, //1299 #HANGUL SYLLABLE NIEUN YI RIEULSIOS + {0x8882, 0xB2B9}, //1300 #HANGUL SYLLABLE NIEUN YI RIEULTHIEUTH + {0x8883, 0xB2BA}, //1301 #HANGUL SYLLABLE NIEUN YI RIEULPHIEUPH + {0x8884, 0xB2BB}, //1302 #HANGUL SYLLABLE NIEUN YI RIEULHIEUH + {0x8885, 0xB2BC}, //1303 #HANGUL SYLLABLE NIEUN YI MIEUM + {0x8886, 0xB2BD}, //1304 #HANGUL SYLLABLE NIEUN YI PIEUP + {0x8887, 0xB2BE}, //1305 #HANGUL SYLLABLE NIEUN YI PIEUPSIOS + {0x8888, 0xB2BF}, //1306 #HANGUL SYLLABLE NIEUN YI SIOS + {0x8889, 0xB2C0}, //1307 #HANGUL SYLLABLE NIEUN YI SSANGSIOS + {0x888A, 0xB2C1}, //1308 #HANGUL SYLLABLE NIEUN YI IEUNG + {0x888B, 0xB2C2}, //1309 #HANGUL SYLLABLE NIEUN YI CIEUC + {0x888C, 0xB2C3}, //1310 #HANGUL SYLLABLE NIEUN YI CHIEUCH + {0x888D, 0xB2C4}, //1311 #HANGUL SYLLABLE NIEUN YI KHIEUKH + {0x888E, 0xB2C5}, //1312 #HANGUL SYLLABLE NIEUN YI THIEUTH + {0x888F, 0xB2C6}, //1313 #HANGUL SYLLABLE NIEUN YI PHIEUPH + {0x8890, 0xB2C7}, //1314 #HANGUL SYLLABLE NIEUN YI HIEUH + {0x8891, 0xB2CA}, //1315 #HANGUL SYLLABLE NIEUN I SSANGKIYEOK + {0x8892, 0xB2CB}, //1316 #HANGUL SYLLABLE NIEUN I KIYEOKSIOS + {0x8893, 0xB2CD}, //1317 #HANGUL SYLLABLE NIEUN I NIEUNCIEUC + {0x8894, 0xB2CE}, //1318 #HANGUL SYLLABLE NIEUN I NIEUNHIEUH + {0x8895, 0xB2CF}, //1319 #HANGUL SYLLABLE NIEUN I TIKEUT + {0x8896, 0xB2D1}, //1320 #HANGUL SYLLABLE NIEUN I RIEULKIYEOK + {0x8897, 0xB2D3}, //1321 #HANGUL SYLLABLE NIEUN I RIEULPIEUP + {0x8898, 0xB2D4}, //1322 #HANGUL SYLLABLE NIEUN I RIEULSIOS + {0x8899, 0xB2D5}, //1323 #HANGUL SYLLABLE NIEUN I RIEULTHIEUTH + {0x889A, 0xB2D6}, //1324 #HANGUL SYLLABLE NIEUN I RIEULPHIEUPH + {0x889B, 0xB2D7}, //1325 #HANGUL SYLLABLE NIEUN I RIEULHIEUH + {0x889C, 0xB2DA}, //1326 #HANGUL SYLLABLE NIEUN I PIEUPSIOS + {0x889D, 0xB2DC}, //1327 #HANGUL SYLLABLE NIEUN I SSANGSIOS + {0x889E, 0xB2DE}, //1328 #HANGUL SYLLABLE NIEUN I CIEUC + {0x889F, 0xB2DF}, //1329 #HANGUL SYLLABLE NIEUN I CHIEUCH + {0x88A0, 0xB2E0}, //1330 #HANGUL SYLLABLE NIEUN I KHIEUKH + {0x88A1, 0xB2E1}, //1331 #HANGUL SYLLABLE NIEUN I THIEUTH + {0x88A2, 0xB2E3}, //1332 #HANGUL SYLLABLE NIEUN I HIEUH + {0x88A3, 0xB2E7}, //1333 #HANGUL SYLLABLE TIKEUT A KIYEOKSIOS + {0x88A4, 0xB2E9}, //1334 #HANGUL SYLLABLE TIKEUT A NIEUNCIEUC + {0x88A5, 0xB2EA}, //1335 #HANGUL SYLLABLE TIKEUT A NIEUNHIEUH + {0x88A6, 0xB2F0}, //1336 #HANGUL SYLLABLE TIKEUT A RIEULSIOS + {0x88A7, 0xB2F1}, //1337 #HANGUL SYLLABLE TIKEUT A RIEULTHIEUTH + {0x88A8, 0xB2F2}, //1338 #HANGUL SYLLABLE TIKEUT A RIEULPHIEUPH + {0x88A9, 0xB2F6}, //1339 #HANGUL SYLLABLE TIKEUT A PIEUPSIOS + {0x88AA, 0xB2FC}, //1340 #HANGUL SYLLABLE TIKEUT A KHIEUKH + {0x88AB, 0xB2FD}, //1341 #HANGUL SYLLABLE TIKEUT A THIEUTH + {0x88AC, 0xB2FE}, //1342 #HANGUL SYLLABLE TIKEUT A PHIEUPH + {0x88AD, 0xB302}, //1343 #HANGUL SYLLABLE TIKEUT AE SSANGKIYEOK + {0x88AE, 0xB303}, //1344 #HANGUL SYLLABLE TIKEUT AE KIYEOKSIOS + {0x88AF, 0xB305}, //1345 #HANGUL SYLLABLE TIKEUT AE NIEUNCIEUC + {0x88B0, 0xB306}, //1346 #HANGUL SYLLABLE TIKEUT AE NIEUNHIEUH + {0x88B1, 0xB307}, //1347 #HANGUL SYLLABLE TIKEUT AE TIKEUT + {0x88B2, 0xB309}, //1348 #HANGUL SYLLABLE TIKEUT AE RIEULKIYEOK + {0x88B3, 0xB30A}, //1349 #HANGUL SYLLABLE TIKEUT AE RIEULMIEUM + {0x88B4, 0xB30B}, //1350 #HANGUL SYLLABLE TIKEUT AE RIEULPIEUP + {0x88B5, 0xB30C}, //1351 #HANGUL SYLLABLE TIKEUT AE RIEULSIOS + {0x88B6, 0xB30D}, //1352 #HANGUL SYLLABLE TIKEUT AE RIEULTHIEUTH + {0x88B7, 0xB30E}, //1353 #HANGUL SYLLABLE TIKEUT AE RIEULPHIEUPH + {0x88B8, 0xB30F}, //1354 #HANGUL SYLLABLE TIKEUT AE RIEULHIEUH + {0x88B9, 0xB312}, //1355 #HANGUL SYLLABLE TIKEUT AE PIEUPSIOS + {0x88BA, 0xB316}, //1356 #HANGUL SYLLABLE TIKEUT AE CIEUC + {0x88BB, 0xB317}, //1357 #HANGUL SYLLABLE TIKEUT AE CHIEUCH + {0x88BC, 0xB318}, //1358 #HANGUL SYLLABLE TIKEUT AE KHIEUKH + {0x88BD, 0xB319}, //1359 #HANGUL SYLLABLE TIKEUT AE THIEUTH + {0x88BE, 0xB31A}, //1360 #HANGUL SYLLABLE TIKEUT AE PHIEUPH + {0x88BF, 0xB31B}, //1361 #HANGUL SYLLABLE TIKEUT AE HIEUH + {0x88C0, 0xB31D}, //1362 #HANGUL SYLLABLE TIKEUT YA KIYEOK + {0x88C1, 0xB31E}, //1363 #HANGUL SYLLABLE TIKEUT YA SSANGKIYEOK + {0x88C2, 0xB31F}, //1364 #HANGUL SYLLABLE TIKEUT YA KIYEOKSIOS + {0x88C3, 0xB320}, //1365 #HANGUL SYLLABLE TIKEUT YA NIEUN + {0x88C4, 0xB321}, //1366 #HANGUL SYLLABLE TIKEUT YA NIEUNCIEUC + {0x88C5, 0xB322}, //1367 #HANGUL SYLLABLE TIKEUT YA NIEUNHIEUH + {0x88C6, 0xB323}, //1368 #HANGUL SYLLABLE TIKEUT YA TIKEUT + {0x88C7, 0xB324}, //1369 #HANGUL SYLLABLE TIKEUT YA RIEUL + {0x88C8, 0xB325}, //1370 #HANGUL SYLLABLE TIKEUT YA RIEULKIYEOK + {0x88C9, 0xB326}, //1371 #HANGUL SYLLABLE TIKEUT YA RIEULMIEUM + {0x88CA, 0xB327}, //1372 #HANGUL SYLLABLE TIKEUT YA RIEULPIEUP + {0x88CB, 0xB328}, //1373 #HANGUL SYLLABLE TIKEUT YA RIEULSIOS + {0x88CC, 0xB329}, //1374 #HANGUL SYLLABLE TIKEUT YA RIEULTHIEUTH + {0x88CD, 0xB32A}, //1375 #HANGUL SYLLABLE TIKEUT YA RIEULPHIEUPH + {0x88CE, 0xB32B}, //1376 #HANGUL SYLLABLE TIKEUT YA RIEULHIEUH + {0x88CF, 0xB32C}, //1377 #HANGUL SYLLABLE TIKEUT YA MIEUM + {0x88D0, 0xB32D}, //1378 #HANGUL SYLLABLE TIKEUT YA PIEUP + {0x88D1, 0xB32E}, //1379 #HANGUL SYLLABLE TIKEUT YA PIEUPSIOS + {0x88D2, 0xB32F}, //1380 #HANGUL SYLLABLE TIKEUT YA SIOS + {0x88D3, 0xB330}, //1381 #HANGUL SYLLABLE TIKEUT YA SSANGSIOS + {0x88D4, 0xB331}, //1382 #HANGUL SYLLABLE TIKEUT YA IEUNG + {0x88D5, 0xB332}, //1383 #HANGUL SYLLABLE TIKEUT YA CIEUC + {0x88D6, 0xB333}, //1384 #HANGUL SYLLABLE TIKEUT YA CHIEUCH + {0x88D7, 0xB334}, //1385 #HANGUL SYLLABLE TIKEUT YA KHIEUKH + {0x88D8, 0xB335}, //1386 #HANGUL SYLLABLE TIKEUT YA THIEUTH + {0x88D9, 0xB336}, //1387 #HANGUL SYLLABLE TIKEUT YA PHIEUPH + {0x88DA, 0xB337}, //1388 #HANGUL SYLLABLE TIKEUT YA HIEUH + {0x88DB, 0xB338}, //1389 #HANGUL SYLLABLE TIKEUT YAE + {0x88DC, 0xB339}, //1390 #HANGUL SYLLABLE TIKEUT YAE KIYEOK + {0x88DD, 0xB33A}, //1391 #HANGUL SYLLABLE TIKEUT YAE SSANGKIYEOK + {0x88DE, 0xB33B}, //1392 #HANGUL SYLLABLE TIKEUT YAE KIYEOKSIOS + {0x88DF, 0xB33C}, //1393 #HANGUL SYLLABLE TIKEUT YAE NIEUN + {0x88E0, 0xB33D}, //1394 #HANGUL SYLLABLE TIKEUT YAE NIEUNCIEUC + {0x88E1, 0xB33E}, //1395 #HANGUL SYLLABLE TIKEUT YAE NIEUNHIEUH + {0x88E2, 0xB33F}, //1396 #HANGUL SYLLABLE TIKEUT YAE TIKEUT + {0x88E3, 0xB340}, //1397 #HANGUL SYLLABLE TIKEUT YAE RIEUL + {0x88E4, 0xB341}, //1398 #HANGUL SYLLABLE TIKEUT YAE RIEULKIYEOK + {0x88E5, 0xB342}, //1399 #HANGUL SYLLABLE TIKEUT YAE RIEULMIEUM + {0x88E6, 0xB343}, //1400 #HANGUL SYLLABLE TIKEUT YAE RIEULPIEUP + {0x88E7, 0xB344}, //1401 #HANGUL SYLLABLE TIKEUT YAE RIEULSIOS + {0x88E8, 0xB345}, //1402 #HANGUL SYLLABLE TIKEUT YAE RIEULTHIEUTH + {0x88E9, 0xB346}, //1403 #HANGUL SYLLABLE TIKEUT YAE RIEULPHIEUPH + {0x88EA, 0xB347}, //1404 #HANGUL SYLLABLE TIKEUT YAE RIEULHIEUH + {0x88EB, 0xB348}, //1405 #HANGUL SYLLABLE TIKEUT YAE MIEUM + {0x88EC, 0xB349}, //1406 #HANGUL SYLLABLE TIKEUT YAE PIEUP + {0x88ED, 0xB34A}, //1407 #HANGUL SYLLABLE TIKEUT YAE PIEUPSIOS + {0x88EE, 0xB34B}, //1408 #HANGUL SYLLABLE TIKEUT YAE SIOS + {0x88EF, 0xB34C}, //1409 #HANGUL SYLLABLE TIKEUT YAE SSANGSIOS + {0x88F0, 0xB34D}, //1410 #HANGUL SYLLABLE TIKEUT YAE IEUNG + {0x88F1, 0xB34E}, //1411 #HANGUL SYLLABLE TIKEUT YAE CIEUC + {0x88F2, 0xB34F}, //1412 #HANGUL SYLLABLE TIKEUT YAE CHIEUCH + {0x88F3, 0xB350}, //1413 #HANGUL SYLLABLE TIKEUT YAE KHIEUKH + {0x88F4, 0xB351}, //1414 #HANGUL SYLLABLE TIKEUT YAE THIEUTH + {0x88F5, 0xB352}, //1415 #HANGUL SYLLABLE TIKEUT YAE PHIEUPH + {0x88F6, 0xB353}, //1416 #HANGUL SYLLABLE TIKEUT YAE HIEUH + {0x88F7, 0xB357}, //1417 #HANGUL SYLLABLE TIKEUT EO KIYEOKSIOS + {0x88F8, 0xB359}, //1418 #HANGUL SYLLABLE TIKEUT EO NIEUNCIEUC + {0x88F9, 0xB35A}, //1419 #HANGUL SYLLABLE TIKEUT EO NIEUNHIEUH + {0x88FA, 0xB35D}, //1420 #HANGUL SYLLABLE TIKEUT EO RIEULKIYEOK + {0x88FB, 0xB360}, //1421 #HANGUL SYLLABLE TIKEUT EO RIEULSIOS + {0x88FC, 0xB361}, //1422 #HANGUL SYLLABLE TIKEUT EO RIEULTHIEUTH + {0x88FD, 0xB362}, //1423 #HANGUL SYLLABLE TIKEUT EO RIEULPHIEUPH + {0x88FE, 0xB363}, //1424 #HANGUL SYLLABLE TIKEUT EO RIEULHIEUH + {0x8941, 0xB366}, //1425 #HANGUL SYLLABLE TIKEUT EO PIEUPSIOS + {0x8942, 0xB368}, //1426 #HANGUL SYLLABLE TIKEUT EO SSANGSIOS + {0x8943, 0xB36A}, //1427 #HANGUL SYLLABLE TIKEUT EO CIEUC + {0x8944, 0xB36C}, //1428 #HANGUL SYLLABLE TIKEUT EO KHIEUKH + {0x8945, 0xB36D}, //1429 #HANGUL SYLLABLE TIKEUT EO THIEUTH + {0x8946, 0xB36F}, //1430 #HANGUL SYLLABLE TIKEUT EO HIEUH + {0x8947, 0xB372}, //1431 #HANGUL SYLLABLE TIKEUT E SSANGKIYEOK + {0x8948, 0xB373}, //1432 #HANGUL SYLLABLE TIKEUT E KIYEOKSIOS + {0x8949, 0xB375}, //1433 #HANGUL SYLLABLE TIKEUT E NIEUNCIEUC + {0x894A, 0xB376}, //1434 #HANGUL SYLLABLE TIKEUT E NIEUNHIEUH + {0x894B, 0xB377}, //1435 #HANGUL SYLLABLE TIKEUT E TIKEUT + {0x894C, 0xB379}, //1436 #HANGUL SYLLABLE TIKEUT E RIEULKIYEOK + {0x894D, 0xB37A}, //1437 #HANGUL SYLLABLE TIKEUT E RIEULMIEUM + {0x894E, 0xB37B}, //1438 #HANGUL SYLLABLE TIKEUT E RIEULPIEUP + {0x894F, 0xB37C}, //1439 #HANGUL SYLLABLE TIKEUT E RIEULSIOS + {0x8950, 0xB37D}, //1440 #HANGUL SYLLABLE TIKEUT E RIEULTHIEUTH + {0x8951, 0xB37E}, //1441 #HANGUL SYLLABLE TIKEUT E RIEULPHIEUPH + {0x8952, 0xB37F}, //1442 #HANGUL SYLLABLE TIKEUT E RIEULHIEUH + {0x8953, 0xB382}, //1443 #HANGUL SYLLABLE TIKEUT E PIEUPSIOS + {0x8954, 0xB386}, //1444 #HANGUL SYLLABLE TIKEUT E CIEUC + {0x8955, 0xB387}, //1445 #HANGUL SYLLABLE TIKEUT E CHIEUCH + {0x8956, 0xB388}, //1446 #HANGUL SYLLABLE TIKEUT E KHIEUKH + {0x8957, 0xB389}, //1447 #HANGUL SYLLABLE TIKEUT E THIEUTH + {0x8958, 0xB38A}, //1448 #HANGUL SYLLABLE TIKEUT E PHIEUPH + {0x8959, 0xB38B}, //1449 #HANGUL SYLLABLE TIKEUT E HIEUH + {0x895A, 0xB38D}, //1450 #HANGUL SYLLABLE TIKEUT YEO KIYEOK + {0x8961, 0xB38E}, //1451 #HANGUL SYLLABLE TIKEUT YEO SSANGKIYEOK + {0x8962, 0xB38F}, //1452 #HANGUL SYLLABLE TIKEUT YEO KIYEOKSIOS + {0x8963, 0xB391}, //1453 #HANGUL SYLLABLE TIKEUT YEO NIEUNCIEUC + {0x8964, 0xB392}, //1454 #HANGUL SYLLABLE TIKEUT YEO NIEUNHIEUH + {0x8965, 0xB393}, //1455 #HANGUL SYLLABLE TIKEUT YEO TIKEUT + {0x8966, 0xB395}, //1456 #HANGUL SYLLABLE TIKEUT YEO RIEULKIYEOK + {0x8967, 0xB396}, //1457 #HANGUL SYLLABLE TIKEUT YEO RIEULMIEUM + {0x8968, 0xB397}, //1458 #HANGUL SYLLABLE TIKEUT YEO RIEULPIEUP + {0x8969, 0xB398}, //1459 #HANGUL SYLLABLE TIKEUT YEO RIEULSIOS + {0x896A, 0xB399}, //1460 #HANGUL SYLLABLE TIKEUT YEO RIEULTHIEUTH + {0x896B, 0xB39A}, //1461 #HANGUL SYLLABLE TIKEUT YEO RIEULPHIEUPH + {0x896C, 0xB39B}, //1462 #HANGUL SYLLABLE TIKEUT YEO RIEULHIEUH + {0x896D, 0xB39C}, //1463 #HANGUL SYLLABLE TIKEUT YEO MIEUM + {0x896E, 0xB39D}, //1464 #HANGUL SYLLABLE TIKEUT YEO PIEUP + {0x896F, 0xB39E}, //1465 #HANGUL SYLLABLE TIKEUT YEO PIEUPSIOS + {0x8970, 0xB39F}, //1466 #HANGUL SYLLABLE TIKEUT YEO SIOS + {0x8971, 0xB3A2}, //1467 #HANGUL SYLLABLE TIKEUT YEO CIEUC + {0x8972, 0xB3A3}, //1468 #HANGUL SYLLABLE TIKEUT YEO CHIEUCH + {0x8973, 0xB3A4}, //1469 #HANGUL SYLLABLE TIKEUT YEO KHIEUKH + {0x8974, 0xB3A5}, //1470 #HANGUL SYLLABLE TIKEUT YEO THIEUTH + {0x8975, 0xB3A6}, //1471 #HANGUL SYLLABLE TIKEUT YEO PHIEUPH + {0x8976, 0xB3A7}, //1472 #HANGUL SYLLABLE TIKEUT YEO HIEUH + {0x8977, 0xB3A9}, //1473 #HANGUL SYLLABLE TIKEUT YE KIYEOK + {0x8978, 0xB3AA}, //1474 #HANGUL SYLLABLE TIKEUT YE SSANGKIYEOK + {0x8979, 0xB3AB}, //1475 #HANGUL SYLLABLE TIKEUT YE KIYEOKSIOS + {0x897A, 0xB3AD}, //1476 #HANGUL SYLLABLE TIKEUT YE NIEUNCIEUC + {0x8981, 0xB3AE}, //1477 #HANGUL SYLLABLE TIKEUT YE NIEUNHIEUH + {0x8982, 0xB3AF}, //1478 #HANGUL SYLLABLE TIKEUT YE TIKEUT + {0x8983, 0xB3B0}, //1479 #HANGUL SYLLABLE TIKEUT YE RIEUL + {0x8984, 0xB3B1}, //1480 #HANGUL SYLLABLE TIKEUT YE RIEULKIYEOK + {0x8985, 0xB3B2}, //1481 #HANGUL SYLLABLE TIKEUT YE RIEULMIEUM + {0x8986, 0xB3B3}, //1482 #HANGUL SYLLABLE TIKEUT YE RIEULPIEUP + {0x8987, 0xB3B4}, //1483 #HANGUL SYLLABLE TIKEUT YE RIEULSIOS + {0x8988, 0xB3B5}, //1484 #HANGUL SYLLABLE TIKEUT YE RIEULTHIEUTH + {0x8989, 0xB3B6}, //1485 #HANGUL SYLLABLE TIKEUT YE RIEULPHIEUPH + {0x898A, 0xB3B7}, //1486 #HANGUL SYLLABLE TIKEUT YE RIEULHIEUH + {0x898B, 0xB3B8}, //1487 #HANGUL SYLLABLE TIKEUT YE MIEUM + {0x898C, 0xB3B9}, //1488 #HANGUL SYLLABLE TIKEUT YE PIEUP + {0x898D, 0xB3BA}, //1489 #HANGUL SYLLABLE TIKEUT YE PIEUPSIOS + {0x898E, 0xB3BB}, //1490 #HANGUL SYLLABLE TIKEUT YE SIOS + {0x898F, 0xB3BC}, //1491 #HANGUL SYLLABLE TIKEUT YE SSANGSIOS + {0x8990, 0xB3BD}, //1492 #HANGUL SYLLABLE TIKEUT YE IEUNG + {0x8991, 0xB3BE}, //1493 #HANGUL SYLLABLE TIKEUT YE CIEUC + {0x8992, 0xB3BF}, //1494 #HANGUL SYLLABLE TIKEUT YE CHIEUCH + {0x8993, 0xB3C0}, //1495 #HANGUL SYLLABLE TIKEUT YE KHIEUKH + {0x8994, 0xB3C1}, //1496 #HANGUL SYLLABLE TIKEUT YE THIEUTH + {0x8995, 0xB3C2}, //1497 #HANGUL SYLLABLE TIKEUT YE PHIEUPH + {0x8996, 0xB3C3}, //1498 #HANGUL SYLLABLE TIKEUT YE HIEUH + {0x8997, 0xB3C6}, //1499 #HANGUL SYLLABLE TIKEUT O SSANGKIYEOK + {0x8998, 0xB3C7}, //1500 #HANGUL SYLLABLE TIKEUT O KIYEOKSIOS + {0x8999, 0xB3C9}, //1501 #HANGUL SYLLABLE TIKEUT O NIEUNCIEUC + {0x899A, 0xB3CA}, //1502 #HANGUL SYLLABLE TIKEUT O NIEUNHIEUH + {0x899B, 0xB3CD}, //1503 #HANGUL SYLLABLE TIKEUT O RIEULKIYEOK + {0x899C, 0xB3CF}, //1504 #HANGUL SYLLABLE TIKEUT O RIEULPIEUP + {0x899D, 0xB3D1}, //1505 #HANGUL SYLLABLE TIKEUT O RIEULTHIEUTH + {0x899E, 0xB3D2}, //1506 #HANGUL SYLLABLE TIKEUT O RIEULPHIEUPH + {0x899F, 0xB3D3}, //1507 #HANGUL SYLLABLE TIKEUT O RIEULHIEUH + {0x89A0, 0xB3D6}, //1508 #HANGUL SYLLABLE TIKEUT O PIEUPSIOS + {0x89A1, 0xB3D8}, //1509 #HANGUL SYLLABLE TIKEUT O SSANGSIOS + {0x89A2, 0xB3DA}, //1510 #HANGUL SYLLABLE TIKEUT O CIEUC + {0x89A3, 0xB3DC}, //1511 #HANGUL SYLLABLE TIKEUT O KHIEUKH + {0x89A4, 0xB3DE}, //1512 #HANGUL SYLLABLE TIKEUT O PHIEUPH + {0x89A5, 0xB3DF}, //1513 #HANGUL SYLLABLE TIKEUT O HIEUH + {0x89A6, 0xB3E1}, //1514 #HANGUL SYLLABLE TIKEUT WA KIYEOK + {0x89A7, 0xB3E2}, //1515 #HANGUL SYLLABLE TIKEUT WA SSANGKIYEOK + {0x89A8, 0xB3E3}, //1516 #HANGUL SYLLABLE TIKEUT WA KIYEOKSIOS + {0x89A9, 0xB3E5}, //1517 #HANGUL SYLLABLE TIKEUT WA NIEUNCIEUC + {0x89AA, 0xB3E6}, //1518 #HANGUL SYLLABLE TIKEUT WA NIEUNHIEUH + {0x89AB, 0xB3E7}, //1519 #HANGUL SYLLABLE TIKEUT WA TIKEUT + {0x89AC, 0xB3E9}, //1520 #HANGUL SYLLABLE TIKEUT WA RIEULKIYEOK + {0x89AD, 0xB3EA}, //1521 #HANGUL SYLLABLE TIKEUT WA RIEULMIEUM + {0x89AE, 0xB3EB}, //1522 #HANGUL SYLLABLE TIKEUT WA RIEULPIEUP + {0x89AF, 0xB3EC}, //1523 #HANGUL SYLLABLE TIKEUT WA RIEULSIOS + {0x89B0, 0xB3ED}, //1524 #HANGUL SYLLABLE TIKEUT WA RIEULTHIEUTH + {0x89B1, 0xB3EE}, //1525 #HANGUL SYLLABLE TIKEUT WA RIEULPHIEUPH + {0x89B2, 0xB3EF}, //1526 #HANGUL SYLLABLE TIKEUT WA RIEULHIEUH + {0x89B3, 0xB3F0}, //1527 #HANGUL SYLLABLE TIKEUT WA MIEUM + {0x89B4, 0xB3F1}, //1528 #HANGUL SYLLABLE TIKEUT WA PIEUP + {0x89B5, 0xB3F2}, //1529 #HANGUL SYLLABLE TIKEUT WA PIEUPSIOS + {0x89B6, 0xB3F3}, //1530 #HANGUL SYLLABLE TIKEUT WA SIOS + {0x89B7, 0xB3F4}, //1531 #HANGUL SYLLABLE TIKEUT WA SSANGSIOS + {0x89B8, 0xB3F5}, //1532 #HANGUL SYLLABLE TIKEUT WA IEUNG + {0x89B9, 0xB3F6}, //1533 #HANGUL SYLLABLE TIKEUT WA CIEUC + {0x89BA, 0xB3F7}, //1534 #HANGUL SYLLABLE TIKEUT WA CHIEUCH + {0x89BB, 0xB3F8}, //1535 #HANGUL SYLLABLE TIKEUT WA KHIEUKH + {0x89BC, 0xB3F9}, //1536 #HANGUL SYLLABLE TIKEUT WA THIEUTH + {0x89BD, 0xB3FA}, //1537 #HANGUL SYLLABLE TIKEUT WA PHIEUPH + {0x89BE, 0xB3FB}, //1538 #HANGUL SYLLABLE TIKEUT WA HIEUH + {0x89BF, 0xB3FD}, //1539 #HANGUL SYLLABLE TIKEUT WAE KIYEOK + {0x89C0, 0xB3FE}, //1540 #HANGUL SYLLABLE TIKEUT WAE SSANGKIYEOK + {0x89C1, 0xB3FF}, //1541 #HANGUL SYLLABLE TIKEUT WAE KIYEOKSIOS + {0x89C2, 0xB400}, //1542 #HANGUL SYLLABLE TIKEUT WAE NIEUN + {0x89C3, 0xB401}, //1543 #HANGUL SYLLABLE TIKEUT WAE NIEUNCIEUC + {0x89C4, 0xB402}, //1544 #HANGUL SYLLABLE TIKEUT WAE NIEUNHIEUH + {0x89C5, 0xB403}, //1545 #HANGUL SYLLABLE TIKEUT WAE TIKEUT + {0x89C6, 0xB404}, //1546 #HANGUL SYLLABLE TIKEUT WAE RIEUL + {0x89C7, 0xB405}, //1547 #HANGUL SYLLABLE TIKEUT WAE RIEULKIYEOK + {0x89C8, 0xB406}, //1548 #HANGUL SYLLABLE TIKEUT WAE RIEULMIEUM + {0x89C9, 0xB407}, //1549 #HANGUL SYLLABLE TIKEUT WAE RIEULPIEUP + {0x89CA, 0xB408}, //1550 #HANGUL SYLLABLE TIKEUT WAE RIEULSIOS + {0x89CB, 0xB409}, //1551 #HANGUL SYLLABLE TIKEUT WAE RIEULTHIEUTH + {0x89CC, 0xB40A}, //1552 #HANGUL SYLLABLE TIKEUT WAE RIEULPHIEUPH + {0x89CD, 0xB40B}, //1553 #HANGUL SYLLABLE TIKEUT WAE RIEULHIEUH + {0x89CE, 0xB40C}, //1554 #HANGUL SYLLABLE TIKEUT WAE MIEUM + {0x89CF, 0xB40D}, //1555 #HANGUL SYLLABLE TIKEUT WAE PIEUP + {0x89D0, 0xB40E}, //1556 #HANGUL SYLLABLE TIKEUT WAE PIEUPSIOS + {0x89D1, 0xB40F}, //1557 #HANGUL SYLLABLE TIKEUT WAE SIOS + {0x89D2, 0xB411}, //1558 #HANGUL SYLLABLE TIKEUT WAE IEUNG + {0x89D3, 0xB412}, //1559 #HANGUL SYLLABLE TIKEUT WAE CIEUC + {0x89D4, 0xB413}, //1560 #HANGUL SYLLABLE TIKEUT WAE CHIEUCH + {0x89D5, 0xB414}, //1561 #HANGUL SYLLABLE TIKEUT WAE KHIEUKH + {0x89D6, 0xB415}, //1562 #HANGUL SYLLABLE TIKEUT WAE THIEUTH + {0x89D7, 0xB416}, //1563 #HANGUL SYLLABLE TIKEUT WAE PHIEUPH + {0x89D8, 0xB417}, //1564 #HANGUL SYLLABLE TIKEUT WAE HIEUH + {0x89D9, 0xB419}, //1565 #HANGUL SYLLABLE TIKEUT OE KIYEOK + {0x89DA, 0xB41A}, //1566 #HANGUL SYLLABLE TIKEUT OE SSANGKIYEOK + {0x89DB, 0xB41B}, //1567 #HANGUL SYLLABLE TIKEUT OE KIYEOKSIOS + {0x89DC, 0xB41D}, //1568 #HANGUL SYLLABLE TIKEUT OE NIEUNCIEUC + {0x89DD, 0xB41E}, //1569 #HANGUL SYLLABLE TIKEUT OE NIEUNHIEUH + {0x89DE, 0xB41F}, //1570 #HANGUL SYLLABLE TIKEUT OE TIKEUT + {0x89DF, 0xB421}, //1571 #HANGUL SYLLABLE TIKEUT OE RIEULKIYEOK + {0x89E0, 0xB422}, //1572 #HANGUL SYLLABLE TIKEUT OE RIEULMIEUM + {0x89E1, 0xB423}, //1573 #HANGUL SYLLABLE TIKEUT OE RIEULPIEUP + {0x89E2, 0xB424}, //1574 #HANGUL SYLLABLE TIKEUT OE RIEULSIOS + {0x89E3, 0xB425}, //1575 #HANGUL SYLLABLE TIKEUT OE RIEULTHIEUTH + {0x89E4, 0xB426}, //1576 #HANGUL SYLLABLE TIKEUT OE RIEULPHIEUPH + {0x89E5, 0xB427}, //1577 #HANGUL SYLLABLE TIKEUT OE RIEULHIEUH + {0x89E6, 0xB42A}, //1578 #HANGUL SYLLABLE TIKEUT OE PIEUPSIOS + {0x89E7, 0xB42C}, //1579 #HANGUL SYLLABLE TIKEUT OE SSANGSIOS + {0x89E8, 0xB42D}, //1580 #HANGUL SYLLABLE TIKEUT OE IEUNG + {0x89E9, 0xB42E}, //1581 #HANGUL SYLLABLE TIKEUT OE CIEUC + {0x89EA, 0xB42F}, //1582 #HANGUL SYLLABLE TIKEUT OE CHIEUCH + {0x89EB, 0xB430}, //1583 #HANGUL SYLLABLE TIKEUT OE KHIEUKH + {0x89EC, 0xB431}, //1584 #HANGUL SYLLABLE TIKEUT OE THIEUTH + {0x89ED, 0xB432}, //1585 #HANGUL SYLLABLE TIKEUT OE PHIEUPH + {0x89EE, 0xB433}, //1586 #HANGUL SYLLABLE TIKEUT OE HIEUH + {0x89EF, 0xB435}, //1587 #HANGUL SYLLABLE TIKEUT YO KIYEOK + {0x89F0, 0xB436}, //1588 #HANGUL SYLLABLE TIKEUT YO SSANGKIYEOK + {0x89F1, 0xB437}, //1589 #HANGUL SYLLABLE TIKEUT YO KIYEOKSIOS + {0x89F2, 0xB438}, //1590 #HANGUL SYLLABLE TIKEUT YO NIEUN + {0x89F3, 0xB439}, //1591 #HANGUL SYLLABLE TIKEUT YO NIEUNCIEUC + {0x89F4, 0xB43A}, //1592 #HANGUL SYLLABLE TIKEUT YO NIEUNHIEUH + {0x89F5, 0xB43B}, //1593 #HANGUL SYLLABLE TIKEUT YO TIKEUT + {0x89F6, 0xB43C}, //1594 #HANGUL SYLLABLE TIKEUT YO RIEUL + {0x89F7, 0xB43D}, //1595 #HANGUL SYLLABLE TIKEUT YO RIEULKIYEOK + {0x89F8, 0xB43E}, //1596 #HANGUL SYLLABLE TIKEUT YO RIEULMIEUM + {0x89F9, 0xB43F}, //1597 #HANGUL SYLLABLE TIKEUT YO RIEULPIEUP + {0x89FA, 0xB440}, //1598 #HANGUL SYLLABLE TIKEUT YO RIEULSIOS + {0x89FB, 0xB441}, //1599 #HANGUL SYLLABLE TIKEUT YO RIEULTHIEUTH + {0x89FC, 0xB442}, //1600 #HANGUL SYLLABLE TIKEUT YO RIEULPHIEUPH + {0x89FD, 0xB443}, //1601 #HANGUL SYLLABLE TIKEUT YO RIEULHIEUH + {0x89FE, 0xB444}, //1602 #HANGUL SYLLABLE TIKEUT YO MIEUM + {0x8A41, 0xB445}, //1603 #HANGUL SYLLABLE TIKEUT YO PIEUP + {0x8A42, 0xB446}, //1604 #HANGUL SYLLABLE TIKEUT YO PIEUPSIOS + {0x8A43, 0xB447}, //1605 #HANGUL SYLLABLE TIKEUT YO SIOS + {0x8A44, 0xB448}, //1606 #HANGUL SYLLABLE TIKEUT YO SSANGSIOS + {0x8A45, 0xB449}, //1607 #HANGUL SYLLABLE TIKEUT YO IEUNG + {0x8A46, 0xB44A}, //1608 #HANGUL SYLLABLE TIKEUT YO CIEUC + {0x8A47, 0xB44B}, //1609 #HANGUL SYLLABLE TIKEUT YO CHIEUCH + {0x8A48, 0xB44C}, //1610 #HANGUL SYLLABLE TIKEUT YO KHIEUKH + {0x8A49, 0xB44D}, //1611 #HANGUL SYLLABLE TIKEUT YO THIEUTH + {0x8A4A, 0xB44E}, //1612 #HANGUL SYLLABLE TIKEUT YO PHIEUPH + {0x8A4B, 0xB44F}, //1613 #HANGUL SYLLABLE TIKEUT YO HIEUH + {0x8A4C, 0xB452}, //1614 #HANGUL SYLLABLE TIKEUT U SSANGKIYEOK + {0x8A4D, 0xB453}, //1615 #HANGUL SYLLABLE TIKEUT U KIYEOKSIOS + {0x8A4E, 0xB455}, //1616 #HANGUL SYLLABLE TIKEUT U NIEUNCIEUC + {0x8A4F, 0xB456}, //1617 #HANGUL SYLLABLE TIKEUT U NIEUNHIEUH + {0x8A50, 0xB457}, //1618 #HANGUL SYLLABLE TIKEUT U TIKEUT + {0x8A51, 0xB459}, //1619 #HANGUL SYLLABLE TIKEUT U RIEULKIYEOK + {0x8A52, 0xB45A}, //1620 #HANGUL SYLLABLE TIKEUT U RIEULMIEUM + {0x8A53, 0xB45B}, //1621 #HANGUL SYLLABLE TIKEUT U RIEULPIEUP + {0x8A54, 0xB45C}, //1622 #HANGUL SYLLABLE TIKEUT U RIEULSIOS + {0x8A55, 0xB45D}, //1623 #HANGUL SYLLABLE TIKEUT U RIEULTHIEUTH + {0x8A56, 0xB45E}, //1624 #HANGUL SYLLABLE TIKEUT U RIEULPHIEUPH + {0x8A57, 0xB45F}, //1625 #HANGUL SYLLABLE TIKEUT U RIEULHIEUH + {0x8A58, 0xB462}, //1626 #HANGUL SYLLABLE TIKEUT U PIEUPSIOS + {0x8A59, 0xB464}, //1627 #HANGUL SYLLABLE TIKEUT U SSANGSIOS + {0x8A5A, 0xB466}, //1628 #HANGUL SYLLABLE TIKEUT U CIEUC + {0x8A61, 0xB467}, //1629 #HANGUL SYLLABLE TIKEUT U CHIEUCH + {0x8A62, 0xB468}, //1630 #HANGUL SYLLABLE TIKEUT U KHIEUKH + {0x8A63, 0xB469}, //1631 #HANGUL SYLLABLE TIKEUT U THIEUTH + {0x8A64, 0xB46A}, //1632 #HANGUL SYLLABLE TIKEUT U PHIEUPH + {0x8A65, 0xB46B}, //1633 #HANGUL SYLLABLE TIKEUT U HIEUH + {0x8A66, 0xB46D}, //1634 #HANGUL SYLLABLE TIKEUT WEO KIYEOK + {0x8A67, 0xB46E}, //1635 #HANGUL SYLLABLE TIKEUT WEO SSANGKIYEOK + {0x8A68, 0xB46F}, //1636 #HANGUL SYLLABLE TIKEUT WEO KIYEOKSIOS + {0x8A69, 0xB470}, //1637 #HANGUL SYLLABLE TIKEUT WEO NIEUN + {0x8A6A, 0xB471}, //1638 #HANGUL SYLLABLE TIKEUT WEO NIEUNCIEUC + {0x8A6B, 0xB472}, //1639 #HANGUL SYLLABLE TIKEUT WEO NIEUNHIEUH + {0x8A6C, 0xB473}, //1640 #HANGUL SYLLABLE TIKEUT WEO TIKEUT + {0x8A6D, 0xB474}, //1641 #HANGUL SYLLABLE TIKEUT WEO RIEUL + {0x8A6E, 0xB475}, //1642 #HANGUL SYLLABLE TIKEUT WEO RIEULKIYEOK + {0x8A6F, 0xB476}, //1643 #HANGUL SYLLABLE TIKEUT WEO RIEULMIEUM + {0x8A70, 0xB477}, //1644 #HANGUL SYLLABLE TIKEUT WEO RIEULPIEUP + {0x8A71, 0xB478}, //1645 #HANGUL SYLLABLE TIKEUT WEO RIEULSIOS + {0x8A72, 0xB479}, //1646 #HANGUL SYLLABLE TIKEUT WEO RIEULTHIEUTH + {0x8A73, 0xB47A}, //1647 #HANGUL SYLLABLE TIKEUT WEO RIEULPHIEUPH + {0x8A74, 0xB47B}, //1648 #HANGUL SYLLABLE TIKEUT WEO RIEULHIEUH + {0x8A75, 0xB47C}, //1649 #HANGUL SYLLABLE TIKEUT WEO MIEUM + {0x8A76, 0xB47D}, //1650 #HANGUL SYLLABLE TIKEUT WEO PIEUP + {0x8A77, 0xB47E}, //1651 #HANGUL SYLLABLE TIKEUT WEO PIEUPSIOS + {0x8A78, 0xB47F}, //1652 #HANGUL SYLLABLE TIKEUT WEO SIOS + {0x8A79, 0xB481}, //1653 #HANGUL SYLLABLE TIKEUT WEO IEUNG + {0x8A7A, 0xB482}, //1654 #HANGUL SYLLABLE TIKEUT WEO CIEUC + {0x8A81, 0xB483}, //1655 #HANGUL SYLLABLE TIKEUT WEO CHIEUCH + {0x8A82, 0xB484}, //1656 #HANGUL SYLLABLE TIKEUT WEO KHIEUKH + {0x8A83, 0xB485}, //1657 #HANGUL SYLLABLE TIKEUT WEO THIEUTH + {0x8A84, 0xB486}, //1658 #HANGUL SYLLABLE TIKEUT WEO PHIEUPH + {0x8A85, 0xB487}, //1659 #HANGUL SYLLABLE TIKEUT WEO HIEUH + {0x8A86, 0xB489}, //1660 #HANGUL SYLLABLE TIKEUT WE KIYEOK + {0x8A87, 0xB48A}, //1661 #HANGUL SYLLABLE TIKEUT WE SSANGKIYEOK + {0x8A88, 0xB48B}, //1662 #HANGUL SYLLABLE TIKEUT WE KIYEOKSIOS + {0x8A89, 0xB48C}, //1663 #HANGUL SYLLABLE TIKEUT WE NIEUN + {0x8A8A, 0xB48D}, //1664 #HANGUL SYLLABLE TIKEUT WE NIEUNCIEUC + {0x8A8B, 0xB48E}, //1665 #HANGUL SYLLABLE TIKEUT WE NIEUNHIEUH + {0x8A8C, 0xB48F}, //1666 #HANGUL SYLLABLE TIKEUT WE TIKEUT + {0x8A8D, 0xB490}, //1667 #HANGUL SYLLABLE TIKEUT WE RIEUL + {0x8A8E, 0xB491}, //1668 #HANGUL SYLLABLE TIKEUT WE RIEULKIYEOK + {0x8A8F, 0xB492}, //1669 #HANGUL SYLLABLE TIKEUT WE RIEULMIEUM + {0x8A90, 0xB493}, //1670 #HANGUL SYLLABLE TIKEUT WE RIEULPIEUP + {0x8A91, 0xB494}, //1671 #HANGUL SYLLABLE TIKEUT WE RIEULSIOS + {0x8A92, 0xB495}, //1672 #HANGUL SYLLABLE TIKEUT WE RIEULTHIEUTH + {0x8A93, 0xB496}, //1673 #HANGUL SYLLABLE TIKEUT WE RIEULPHIEUPH + {0x8A94, 0xB497}, //1674 #HANGUL SYLLABLE TIKEUT WE RIEULHIEUH + {0x8A95, 0xB498}, //1675 #HANGUL SYLLABLE TIKEUT WE MIEUM + {0x8A96, 0xB499}, //1676 #HANGUL SYLLABLE TIKEUT WE PIEUP + {0x8A97, 0xB49A}, //1677 #HANGUL SYLLABLE TIKEUT WE PIEUPSIOS + {0x8A98, 0xB49B}, //1678 #HANGUL SYLLABLE TIKEUT WE SIOS + {0x8A99, 0xB49C}, //1679 #HANGUL SYLLABLE TIKEUT WE SSANGSIOS + {0x8A9A, 0xB49E}, //1680 #HANGUL SYLLABLE TIKEUT WE CIEUC + {0x8A9B, 0xB49F}, //1681 #HANGUL SYLLABLE TIKEUT WE CHIEUCH + {0x8A9C, 0xB4A0}, //1682 #HANGUL SYLLABLE TIKEUT WE KHIEUKH + {0x8A9D, 0xB4A1}, //1683 #HANGUL SYLLABLE TIKEUT WE THIEUTH + {0x8A9E, 0xB4A2}, //1684 #HANGUL SYLLABLE TIKEUT WE PHIEUPH + {0x8A9F, 0xB4A3}, //1685 #HANGUL SYLLABLE TIKEUT WE HIEUH + {0x8AA0, 0xB4A5}, //1686 #HANGUL SYLLABLE TIKEUT WI KIYEOK + {0x8AA1, 0xB4A6}, //1687 #HANGUL SYLLABLE TIKEUT WI SSANGKIYEOK + {0x8AA2, 0xB4A7}, //1688 #HANGUL SYLLABLE TIKEUT WI KIYEOKSIOS + {0x8AA3, 0xB4A9}, //1689 #HANGUL SYLLABLE TIKEUT WI NIEUNCIEUC + {0x8AA4, 0xB4AA}, //1690 #HANGUL SYLLABLE TIKEUT WI NIEUNHIEUH + {0x8AA5, 0xB4AB}, //1691 #HANGUL SYLLABLE TIKEUT WI TIKEUT + {0x8AA6, 0xB4AD}, //1692 #HANGUL SYLLABLE TIKEUT WI RIEULKIYEOK + {0x8AA7, 0xB4AE}, //1693 #HANGUL SYLLABLE TIKEUT WI RIEULMIEUM + {0x8AA8, 0xB4AF}, //1694 #HANGUL SYLLABLE TIKEUT WI RIEULPIEUP + {0x8AA9, 0xB4B0}, //1695 #HANGUL SYLLABLE TIKEUT WI RIEULSIOS + {0x8AAA, 0xB4B1}, //1696 #HANGUL SYLLABLE TIKEUT WI RIEULTHIEUTH + {0x8AAB, 0xB4B2}, //1697 #HANGUL SYLLABLE TIKEUT WI RIEULPHIEUPH + {0x8AAC, 0xB4B3}, //1698 #HANGUL SYLLABLE TIKEUT WI RIEULHIEUH + {0x8AAD, 0xB4B4}, //1699 #HANGUL SYLLABLE TIKEUT WI MIEUM + {0x8AAE, 0xB4B6}, //1700 #HANGUL SYLLABLE TIKEUT WI PIEUPSIOS + {0x8AAF, 0xB4B8}, //1701 #HANGUL SYLLABLE TIKEUT WI SSANGSIOS + {0x8AB0, 0xB4BA}, //1702 #HANGUL SYLLABLE TIKEUT WI CIEUC + {0x8AB1, 0xB4BB}, //1703 #HANGUL SYLLABLE TIKEUT WI CHIEUCH + {0x8AB2, 0xB4BC}, //1704 #HANGUL SYLLABLE TIKEUT WI KHIEUKH + {0x8AB3, 0xB4BD}, //1705 #HANGUL SYLLABLE TIKEUT WI THIEUTH + {0x8AB4, 0xB4BE}, //1706 #HANGUL SYLLABLE TIKEUT WI PHIEUPH + {0x8AB5, 0xB4BF}, //1707 #HANGUL SYLLABLE TIKEUT WI HIEUH + {0x8AB6, 0xB4C1}, //1708 #HANGUL SYLLABLE TIKEUT YU KIYEOK + {0x8AB7, 0xB4C2}, //1709 #HANGUL SYLLABLE TIKEUT YU SSANGKIYEOK + {0x8AB8, 0xB4C3}, //1710 #HANGUL SYLLABLE TIKEUT YU KIYEOKSIOS + {0x8AB9, 0xB4C5}, //1711 #HANGUL SYLLABLE TIKEUT YU NIEUNCIEUC + {0x8ABA, 0xB4C6}, //1712 #HANGUL SYLLABLE TIKEUT YU NIEUNHIEUH + {0x8ABB, 0xB4C7}, //1713 #HANGUL SYLLABLE TIKEUT YU TIKEUT + {0x8ABC, 0xB4C9}, //1714 #HANGUL SYLLABLE TIKEUT YU RIEULKIYEOK + {0x8ABD, 0xB4CA}, //1715 #HANGUL SYLLABLE TIKEUT YU RIEULMIEUM + {0x8ABE, 0xB4CB}, //1716 #HANGUL SYLLABLE TIKEUT YU RIEULPIEUP + {0x8ABF, 0xB4CC}, //1717 #HANGUL SYLLABLE TIKEUT YU RIEULSIOS + {0x8AC0, 0xB4CD}, //1718 #HANGUL SYLLABLE TIKEUT YU RIEULTHIEUTH + {0x8AC1, 0xB4CE}, //1719 #HANGUL SYLLABLE TIKEUT YU RIEULPHIEUPH + {0x8AC2, 0xB4CF}, //1720 #HANGUL SYLLABLE TIKEUT YU RIEULHIEUH + {0x8AC3, 0xB4D1}, //1721 #HANGUL SYLLABLE TIKEUT YU PIEUP + {0x8AC4, 0xB4D2}, //1722 #HANGUL SYLLABLE TIKEUT YU PIEUPSIOS + {0x8AC5, 0xB4D3}, //1723 #HANGUL SYLLABLE TIKEUT YU SIOS + {0x8AC6, 0xB4D4}, //1724 #HANGUL SYLLABLE TIKEUT YU SSANGSIOS + {0x8AC7, 0xB4D6}, //1725 #HANGUL SYLLABLE TIKEUT YU CIEUC + {0x8AC8, 0xB4D7}, //1726 #HANGUL SYLLABLE TIKEUT YU CHIEUCH + {0x8AC9, 0xB4D8}, //1727 #HANGUL SYLLABLE TIKEUT YU KHIEUKH + {0x8ACA, 0xB4D9}, //1728 #HANGUL SYLLABLE TIKEUT YU THIEUTH + {0x8ACB, 0xB4DA}, //1729 #HANGUL SYLLABLE TIKEUT YU PHIEUPH + {0x8ACC, 0xB4DB}, //1730 #HANGUL SYLLABLE TIKEUT YU HIEUH + {0x8ACD, 0xB4DE}, //1731 #HANGUL SYLLABLE TIKEUT EU SSANGKIYEOK + {0x8ACE, 0xB4DF}, //1732 #HANGUL SYLLABLE TIKEUT EU KIYEOKSIOS + {0x8ACF, 0xB4E1}, //1733 #HANGUL SYLLABLE TIKEUT EU NIEUNCIEUC + {0x8AD0, 0xB4E2}, //1734 #HANGUL SYLLABLE TIKEUT EU NIEUNHIEUH + {0x8AD1, 0xB4E5}, //1735 #HANGUL SYLLABLE TIKEUT EU RIEULKIYEOK + {0x8AD2, 0xB4E7}, //1736 #HANGUL SYLLABLE TIKEUT EU RIEULPIEUP + {0x8AD3, 0xB4E8}, //1737 #HANGUL SYLLABLE TIKEUT EU RIEULSIOS + {0x8AD4, 0xB4E9}, //1738 #HANGUL SYLLABLE TIKEUT EU RIEULTHIEUTH + {0x8AD5, 0xB4EA}, //1739 #HANGUL SYLLABLE TIKEUT EU RIEULPHIEUPH + {0x8AD6, 0xB4EB}, //1740 #HANGUL SYLLABLE TIKEUT EU RIEULHIEUH + {0x8AD7, 0xB4EE}, //1741 #HANGUL SYLLABLE TIKEUT EU PIEUPSIOS + {0x8AD8, 0xB4F0}, //1742 #HANGUL SYLLABLE TIKEUT EU SSANGSIOS + {0x8AD9, 0xB4F2}, //1743 #HANGUL SYLLABLE TIKEUT EU CIEUC + {0x8ADA, 0xB4F3}, //1744 #HANGUL SYLLABLE TIKEUT EU CHIEUCH + {0x8ADB, 0xB4F4}, //1745 #HANGUL SYLLABLE TIKEUT EU KHIEUKH + {0x8ADC, 0xB4F5}, //1746 #HANGUL SYLLABLE TIKEUT EU THIEUTH + {0x8ADD, 0xB4F6}, //1747 #HANGUL SYLLABLE TIKEUT EU PHIEUPH + {0x8ADE, 0xB4F7}, //1748 #HANGUL SYLLABLE TIKEUT EU HIEUH + {0x8ADF, 0xB4F9}, //1749 #HANGUL SYLLABLE TIKEUT YI KIYEOK + {0x8AE0, 0xB4FA}, //1750 #HANGUL SYLLABLE TIKEUT YI SSANGKIYEOK + {0x8AE1, 0xB4FB}, //1751 #HANGUL SYLLABLE TIKEUT YI KIYEOKSIOS + {0x8AE2, 0xB4FC}, //1752 #HANGUL SYLLABLE TIKEUT YI NIEUN + {0x8AE3, 0xB4FD}, //1753 #HANGUL SYLLABLE TIKEUT YI NIEUNCIEUC + {0x8AE4, 0xB4FE}, //1754 #HANGUL SYLLABLE TIKEUT YI NIEUNHIEUH + {0x8AE5, 0xB4FF}, //1755 #HANGUL SYLLABLE TIKEUT YI TIKEUT + {0x8AE6, 0xB500}, //1756 #HANGUL SYLLABLE TIKEUT YI RIEUL + {0x8AE7, 0xB501}, //1757 #HANGUL SYLLABLE TIKEUT YI RIEULKIYEOK + {0x8AE8, 0xB502}, //1758 #HANGUL SYLLABLE TIKEUT YI RIEULMIEUM + {0x8AE9, 0xB503}, //1759 #HANGUL SYLLABLE TIKEUT YI RIEULPIEUP + {0x8AEA, 0xB504}, //1760 #HANGUL SYLLABLE TIKEUT YI RIEULSIOS + {0x8AEB, 0xB505}, //1761 #HANGUL SYLLABLE TIKEUT YI RIEULTHIEUTH + {0x8AEC, 0xB506}, //1762 #HANGUL SYLLABLE TIKEUT YI RIEULPHIEUPH + {0x8AED, 0xB507}, //1763 #HANGUL SYLLABLE TIKEUT YI RIEULHIEUH + {0x8AEE, 0xB508}, //1764 #HANGUL SYLLABLE TIKEUT YI MIEUM + {0x8AEF, 0xB509}, //1765 #HANGUL SYLLABLE TIKEUT YI PIEUP + {0x8AF0, 0xB50A}, //1766 #HANGUL SYLLABLE TIKEUT YI PIEUPSIOS + {0x8AF1, 0xB50B}, //1767 #HANGUL SYLLABLE TIKEUT YI SIOS + {0x8AF2, 0xB50C}, //1768 #HANGUL SYLLABLE TIKEUT YI SSANGSIOS + {0x8AF3, 0xB50D}, //1769 #HANGUL SYLLABLE TIKEUT YI IEUNG + {0x8AF4, 0xB50E}, //1770 #HANGUL SYLLABLE TIKEUT YI CIEUC + {0x8AF5, 0xB50F}, //1771 #HANGUL SYLLABLE TIKEUT YI CHIEUCH + {0x8AF6, 0xB510}, //1772 #HANGUL SYLLABLE TIKEUT YI KHIEUKH + {0x8AF7, 0xB511}, //1773 #HANGUL SYLLABLE TIKEUT YI THIEUTH + {0x8AF8, 0xB512}, //1774 #HANGUL SYLLABLE TIKEUT YI PHIEUPH + {0x8AF9, 0xB513}, //1775 #HANGUL SYLLABLE TIKEUT YI HIEUH + {0x8AFA, 0xB516}, //1776 #HANGUL SYLLABLE TIKEUT I SSANGKIYEOK + {0x8AFB, 0xB517}, //1777 #HANGUL SYLLABLE TIKEUT I KIYEOKSIOS + {0x8AFC, 0xB519}, //1778 #HANGUL SYLLABLE TIKEUT I NIEUNCIEUC + {0x8AFD, 0xB51A}, //1779 #HANGUL SYLLABLE TIKEUT I NIEUNHIEUH + {0x8AFE, 0xB51D}, //1780 #HANGUL SYLLABLE TIKEUT I RIEULKIYEOK + {0x8B41, 0xB51E}, //1781 #HANGUL SYLLABLE TIKEUT I RIEULMIEUM + {0x8B42, 0xB51F}, //1782 #HANGUL SYLLABLE TIKEUT I RIEULPIEUP + {0x8B43, 0xB520}, //1783 #HANGUL SYLLABLE TIKEUT I RIEULSIOS + {0x8B44, 0xB521}, //1784 #HANGUL SYLLABLE TIKEUT I RIEULTHIEUTH + {0x8B45, 0xB522}, //1785 #HANGUL SYLLABLE TIKEUT I RIEULPHIEUPH + {0x8B46, 0xB523}, //1786 #HANGUL SYLLABLE TIKEUT I RIEULHIEUH + {0x8B47, 0xB526}, //1787 #HANGUL SYLLABLE TIKEUT I PIEUPSIOS + {0x8B48, 0xB52B}, //1788 #HANGUL SYLLABLE TIKEUT I CHIEUCH + {0x8B49, 0xB52C}, //1789 #HANGUL SYLLABLE TIKEUT I KHIEUKH + {0x8B4A, 0xB52D}, //1790 #HANGUL SYLLABLE TIKEUT I THIEUTH + {0x8B4B, 0xB52E}, //1791 #HANGUL SYLLABLE TIKEUT I PHIEUPH + {0x8B4C, 0xB52F}, //1792 #HANGUL SYLLABLE TIKEUT I HIEUH + {0x8B4D, 0xB532}, //1793 #HANGUL SYLLABLE SSANGTIKEUT A SSANGKIYEOK + {0x8B4E, 0xB533}, //1794 #HANGUL SYLLABLE SSANGTIKEUT A KIYEOKSIOS + {0x8B4F, 0xB535}, //1795 #HANGUL SYLLABLE SSANGTIKEUT A NIEUNCIEUC + {0x8B50, 0xB536}, //1796 #HANGUL SYLLABLE SSANGTIKEUT A NIEUNHIEUH + {0x8B51, 0xB537}, //1797 #HANGUL SYLLABLE SSANGTIKEUT A TIKEUT + {0x8B52, 0xB539}, //1798 #HANGUL SYLLABLE SSANGTIKEUT A RIEULKIYEOK + {0x8B53, 0xB53A}, //1799 #HANGUL SYLLABLE SSANGTIKEUT A RIEULMIEUM + {0x8B54, 0xB53B}, //1800 #HANGUL SYLLABLE SSANGTIKEUT A RIEULPIEUP + {0x8B55, 0xB53C}, //1801 #HANGUL SYLLABLE SSANGTIKEUT A RIEULSIOS + {0x8B56, 0xB53D}, //1802 #HANGUL SYLLABLE SSANGTIKEUT A RIEULTHIEUTH + {0x8B57, 0xB53E}, //1803 #HANGUL SYLLABLE SSANGTIKEUT A RIEULPHIEUPH + {0x8B58, 0xB53F}, //1804 #HANGUL SYLLABLE SSANGTIKEUT A RIEULHIEUH + {0x8B59, 0xB542}, //1805 #HANGUL SYLLABLE SSANGTIKEUT A PIEUPSIOS + {0x8B5A, 0xB546}, //1806 #HANGUL SYLLABLE SSANGTIKEUT A CIEUC + {0x8B61, 0xB547}, //1807 #HANGUL SYLLABLE SSANGTIKEUT A CHIEUCH + {0x8B62, 0xB548}, //1808 #HANGUL SYLLABLE SSANGTIKEUT A KHIEUKH + {0x8B63, 0xB549}, //1809 #HANGUL SYLLABLE SSANGTIKEUT A THIEUTH + {0x8B64, 0xB54A}, //1810 #HANGUL SYLLABLE SSANGTIKEUT A PHIEUPH + {0x8B65, 0xB54E}, //1811 #HANGUL SYLLABLE SSANGTIKEUT AE SSANGKIYEOK + {0x8B66, 0xB54F}, //1812 #HANGUL SYLLABLE SSANGTIKEUT AE KIYEOKSIOS + {0x8B67, 0xB551}, //1813 #HANGUL SYLLABLE SSANGTIKEUT AE NIEUNCIEUC + {0x8B68, 0xB552}, //1814 #HANGUL SYLLABLE SSANGTIKEUT AE NIEUNHIEUH + {0x8B69, 0xB553}, //1815 #HANGUL SYLLABLE SSANGTIKEUT AE TIKEUT + {0x8B6A, 0xB555}, //1816 #HANGUL SYLLABLE SSANGTIKEUT AE RIEULKIYEOK + {0x8B6B, 0xB556}, //1817 #HANGUL SYLLABLE SSANGTIKEUT AE RIEULMIEUM + {0x8B6C, 0xB557}, //1818 #HANGUL SYLLABLE SSANGTIKEUT AE RIEULPIEUP + {0x8B6D, 0xB558}, //1819 #HANGUL SYLLABLE SSANGTIKEUT AE RIEULSIOS + {0x8B6E, 0xB559}, //1820 #HANGUL SYLLABLE SSANGTIKEUT AE RIEULTHIEUTH + {0x8B6F, 0xB55A}, //1821 #HANGUL SYLLABLE SSANGTIKEUT AE RIEULPHIEUPH + {0x8B70, 0xB55B}, //1822 #HANGUL SYLLABLE SSANGTIKEUT AE RIEULHIEUH + {0x8B71, 0xB55E}, //1823 #HANGUL SYLLABLE SSANGTIKEUT AE PIEUPSIOS + {0x8B72, 0xB562}, //1824 #HANGUL SYLLABLE SSANGTIKEUT AE CIEUC + {0x8B73, 0xB563}, //1825 #HANGUL SYLLABLE SSANGTIKEUT AE CHIEUCH + {0x8B74, 0xB564}, //1826 #HANGUL SYLLABLE SSANGTIKEUT AE KHIEUKH + {0x8B75, 0xB565}, //1827 #HANGUL SYLLABLE SSANGTIKEUT AE THIEUTH + {0x8B76, 0xB566}, //1828 #HANGUL SYLLABLE SSANGTIKEUT AE PHIEUPH + {0x8B77, 0xB567}, //1829 #HANGUL SYLLABLE SSANGTIKEUT AE HIEUH + {0x8B78, 0xB568}, //1830 #HANGUL SYLLABLE SSANGTIKEUT YA + {0x8B79, 0xB569}, //1831 #HANGUL SYLLABLE SSANGTIKEUT YA KIYEOK + {0x8B7A, 0xB56A}, //1832 #HANGUL SYLLABLE SSANGTIKEUT YA SSANGKIYEOK + {0x8B81, 0xB56B}, //1833 #HANGUL SYLLABLE SSANGTIKEUT YA KIYEOKSIOS + {0x8B82, 0xB56C}, //1834 #HANGUL SYLLABLE SSANGTIKEUT YA NIEUN + {0x8B83, 0xB56D}, //1835 #HANGUL SYLLABLE SSANGTIKEUT YA NIEUNCIEUC + {0x8B84, 0xB56E}, //1836 #HANGUL SYLLABLE SSANGTIKEUT YA NIEUNHIEUH + {0x8B85, 0xB56F}, //1837 #HANGUL SYLLABLE SSANGTIKEUT YA TIKEUT + {0x8B86, 0xB570}, //1838 #HANGUL SYLLABLE SSANGTIKEUT YA RIEUL + {0x8B87, 0xB571}, //1839 #HANGUL SYLLABLE SSANGTIKEUT YA RIEULKIYEOK + {0x8B88, 0xB572}, //1840 #HANGUL SYLLABLE SSANGTIKEUT YA RIEULMIEUM + {0x8B89, 0xB573}, //1841 #HANGUL SYLLABLE SSANGTIKEUT YA RIEULPIEUP + {0x8B8A, 0xB574}, //1842 #HANGUL SYLLABLE SSANGTIKEUT YA RIEULSIOS + {0x8B8B, 0xB575}, //1843 #HANGUL SYLLABLE SSANGTIKEUT YA RIEULTHIEUTH + {0x8B8C, 0xB576}, //1844 #HANGUL SYLLABLE SSANGTIKEUT YA RIEULPHIEUPH + {0x8B8D, 0xB577}, //1845 #HANGUL SYLLABLE SSANGTIKEUT YA RIEULHIEUH + {0x8B8E, 0xB578}, //1846 #HANGUL SYLLABLE SSANGTIKEUT YA MIEUM + {0x8B8F, 0xB579}, //1847 #HANGUL SYLLABLE SSANGTIKEUT YA PIEUP + {0x8B90, 0xB57A}, //1848 #HANGUL SYLLABLE SSANGTIKEUT YA PIEUPSIOS + {0x8B91, 0xB57B}, //1849 #HANGUL SYLLABLE SSANGTIKEUT YA SIOS + {0x8B92, 0xB57C}, //1850 #HANGUL SYLLABLE SSANGTIKEUT YA SSANGSIOS + {0x8B93, 0xB57D}, //1851 #HANGUL SYLLABLE SSANGTIKEUT YA IEUNG + {0x8B94, 0xB57E}, //1852 #HANGUL SYLLABLE SSANGTIKEUT YA CIEUC + {0x8B95, 0xB57F}, //1853 #HANGUL SYLLABLE SSANGTIKEUT YA CHIEUCH + {0x8B96, 0xB580}, //1854 #HANGUL SYLLABLE SSANGTIKEUT YA KHIEUKH + {0x8B97, 0xB581}, //1855 #HANGUL SYLLABLE SSANGTIKEUT YA THIEUTH + {0x8B98, 0xB582}, //1856 #HANGUL SYLLABLE SSANGTIKEUT YA PHIEUPH + {0x8B99, 0xB583}, //1857 #HANGUL SYLLABLE SSANGTIKEUT YA HIEUH + {0x8B9A, 0xB584}, //1858 #HANGUL SYLLABLE SSANGTIKEUT YAE + {0x8B9B, 0xB585}, //1859 #HANGUL SYLLABLE SSANGTIKEUT YAE KIYEOK + {0x8B9C, 0xB586}, //1860 #HANGUL SYLLABLE SSANGTIKEUT YAE SSANGKIYEOK + {0x8B9D, 0xB587}, //1861 #HANGUL SYLLABLE SSANGTIKEUT YAE KIYEOKSIOS + {0x8B9E, 0xB588}, //1862 #HANGUL SYLLABLE SSANGTIKEUT YAE NIEUN + {0x8B9F, 0xB589}, //1863 #HANGUL SYLLABLE SSANGTIKEUT YAE NIEUNCIEUC + {0x8BA0, 0xB58A}, //1864 #HANGUL SYLLABLE SSANGTIKEUT YAE NIEUNHIEUH + {0x8BA1, 0xB58B}, //1865 #HANGUL SYLLABLE SSANGTIKEUT YAE TIKEUT + {0x8BA2, 0xB58C}, //1866 #HANGUL SYLLABLE SSANGTIKEUT YAE RIEUL + {0x8BA3, 0xB58D}, //1867 #HANGUL SYLLABLE SSANGTIKEUT YAE RIEULKIYEOK + {0x8BA4, 0xB58E}, //1868 #HANGUL SYLLABLE SSANGTIKEUT YAE RIEULMIEUM + {0x8BA5, 0xB58F}, //1869 #HANGUL SYLLABLE SSANGTIKEUT YAE RIEULPIEUP + {0x8BA6, 0xB590}, //1870 #HANGUL SYLLABLE SSANGTIKEUT YAE RIEULSIOS + {0x8BA7, 0xB591}, //1871 #HANGUL SYLLABLE SSANGTIKEUT YAE RIEULTHIEUTH + {0x8BA8, 0xB592}, //1872 #HANGUL SYLLABLE SSANGTIKEUT YAE RIEULPHIEUPH + {0x8BA9, 0xB593}, //1873 #HANGUL SYLLABLE SSANGTIKEUT YAE RIEULHIEUH + {0x8BAA, 0xB594}, //1874 #HANGUL SYLLABLE SSANGTIKEUT YAE MIEUM + {0x8BAB, 0xB595}, //1875 #HANGUL SYLLABLE SSANGTIKEUT YAE PIEUP + {0x8BAC, 0xB596}, //1876 #HANGUL SYLLABLE SSANGTIKEUT YAE PIEUPSIOS + {0x8BAD, 0xB597}, //1877 #HANGUL SYLLABLE SSANGTIKEUT YAE SIOS + {0x8BAE, 0xB598}, //1878 #HANGUL SYLLABLE SSANGTIKEUT YAE SSANGSIOS + {0x8BAF, 0xB599}, //1879 #HANGUL SYLLABLE SSANGTIKEUT YAE IEUNG + {0x8BB0, 0xB59A}, //1880 #HANGUL SYLLABLE SSANGTIKEUT YAE CIEUC + {0x8BB1, 0xB59B}, //1881 #HANGUL SYLLABLE SSANGTIKEUT YAE CHIEUCH + {0x8BB2, 0xB59C}, //1882 #HANGUL SYLLABLE SSANGTIKEUT YAE KHIEUKH + {0x8BB3, 0xB59D}, //1883 #HANGUL SYLLABLE SSANGTIKEUT YAE THIEUTH + {0x8BB4, 0xB59E}, //1884 #HANGUL SYLLABLE SSANGTIKEUT YAE PHIEUPH + {0x8BB5, 0xB59F}, //1885 #HANGUL SYLLABLE SSANGTIKEUT YAE HIEUH + {0x8BB6, 0xB5A2}, //1886 #HANGUL SYLLABLE SSANGTIKEUT EO SSANGKIYEOK + {0x8BB7, 0xB5A3}, //1887 #HANGUL SYLLABLE SSANGTIKEUT EO KIYEOKSIOS + {0x8BB8, 0xB5A5}, //1888 #HANGUL SYLLABLE SSANGTIKEUT EO NIEUNCIEUC + {0x8BB9, 0xB5A6}, //1889 #HANGUL SYLLABLE SSANGTIKEUT EO NIEUNHIEUH + {0x8BBA, 0xB5A7}, //1890 #HANGUL SYLLABLE SSANGTIKEUT EO TIKEUT + {0x8BBB, 0xB5A9}, //1891 #HANGUL SYLLABLE SSANGTIKEUT EO RIEULKIYEOK + {0x8BBC, 0xB5AC}, //1892 #HANGUL SYLLABLE SSANGTIKEUT EO RIEULSIOS + {0x8BBD, 0xB5AD}, //1893 #HANGUL SYLLABLE SSANGTIKEUT EO RIEULTHIEUTH + {0x8BBE, 0xB5AE}, //1894 #HANGUL SYLLABLE SSANGTIKEUT EO RIEULPHIEUPH + {0x8BBF, 0xB5AF}, //1895 #HANGUL SYLLABLE SSANGTIKEUT EO RIEULHIEUH + {0x8BC0, 0xB5B2}, //1896 #HANGUL SYLLABLE SSANGTIKEUT EO PIEUPSIOS + {0x8BC1, 0xB5B6}, //1897 #HANGUL SYLLABLE SSANGTIKEUT EO CIEUC + {0x8BC2, 0xB5B7}, //1898 #HANGUL SYLLABLE SSANGTIKEUT EO CHIEUCH + {0x8BC3, 0xB5B8}, //1899 #HANGUL SYLLABLE SSANGTIKEUT EO KHIEUKH + {0x8BC4, 0xB5B9}, //1900 #HANGUL SYLLABLE SSANGTIKEUT EO THIEUTH + {0x8BC5, 0xB5BA}, //1901 #HANGUL SYLLABLE SSANGTIKEUT EO PHIEUPH + {0x8BC6, 0xB5BE}, //1902 #HANGUL SYLLABLE SSANGTIKEUT E SSANGKIYEOK + {0x8BC7, 0xB5BF}, //1903 #HANGUL SYLLABLE SSANGTIKEUT E KIYEOKSIOS + {0x8BC8, 0xB5C1}, //1904 #HANGUL SYLLABLE SSANGTIKEUT E NIEUNCIEUC + {0x8BC9, 0xB5C2}, //1905 #HANGUL SYLLABLE SSANGTIKEUT E NIEUNHIEUH + {0x8BCA, 0xB5C3}, //1906 #HANGUL SYLLABLE SSANGTIKEUT E TIKEUT + {0x8BCB, 0xB5C5}, //1907 #HANGUL SYLLABLE SSANGTIKEUT E RIEULKIYEOK + {0x8BCC, 0xB5C6}, //1908 #HANGUL SYLLABLE SSANGTIKEUT E RIEULMIEUM + {0x8BCD, 0xB5C7}, //1909 #HANGUL SYLLABLE SSANGTIKEUT E RIEULPIEUP + {0x8BCE, 0xB5C8}, //1910 #HANGUL SYLLABLE SSANGTIKEUT E RIEULSIOS + {0x8BCF, 0xB5C9}, //1911 #HANGUL SYLLABLE SSANGTIKEUT E RIEULTHIEUTH + {0x8BD0, 0xB5CA}, //1912 #HANGUL SYLLABLE SSANGTIKEUT E RIEULPHIEUPH + {0x8BD1, 0xB5CB}, //1913 #HANGUL SYLLABLE SSANGTIKEUT E RIEULHIEUH + {0x8BD2, 0xB5CE}, //1914 #HANGUL SYLLABLE SSANGTIKEUT E PIEUPSIOS + {0x8BD3, 0xB5D2}, //1915 #HANGUL SYLLABLE SSANGTIKEUT E CIEUC + {0x8BD4, 0xB5D3}, //1916 #HANGUL SYLLABLE SSANGTIKEUT E CHIEUCH + {0x8BD5, 0xB5D4}, //1917 #HANGUL SYLLABLE SSANGTIKEUT E KHIEUKH + {0x8BD6, 0xB5D5}, //1918 #HANGUL SYLLABLE SSANGTIKEUT E THIEUTH + {0x8BD7, 0xB5D6}, //1919 #HANGUL SYLLABLE SSANGTIKEUT E PHIEUPH + {0x8BD8, 0xB5D7}, //1920 #HANGUL SYLLABLE SSANGTIKEUT E HIEUH + {0x8BD9, 0xB5D9}, //1921 #HANGUL SYLLABLE SSANGTIKEUT YEO KIYEOK + {0x8BDA, 0xB5DA}, //1922 #HANGUL SYLLABLE SSANGTIKEUT YEO SSANGKIYEOK + {0x8BDB, 0xB5DB}, //1923 #HANGUL SYLLABLE SSANGTIKEUT YEO KIYEOKSIOS + {0x8BDC, 0xB5DC}, //1924 #HANGUL SYLLABLE SSANGTIKEUT YEO NIEUN + {0x8BDD, 0xB5DD}, //1925 #HANGUL SYLLABLE SSANGTIKEUT YEO NIEUNCIEUC + {0x8BDE, 0xB5DE}, //1926 #HANGUL SYLLABLE SSANGTIKEUT YEO NIEUNHIEUH + {0x8BDF, 0xB5DF}, //1927 #HANGUL SYLLABLE SSANGTIKEUT YEO TIKEUT + {0x8BE0, 0xB5E0}, //1928 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEUL + {0x8BE1, 0xB5E1}, //1929 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEULKIYEOK + {0x8BE2, 0xB5E2}, //1930 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEULMIEUM + {0x8BE3, 0xB5E3}, //1931 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEULPIEUP + {0x8BE4, 0xB5E4}, //1932 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEULSIOS + {0x8BE5, 0xB5E5}, //1933 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEULTHIEUTH + {0x8BE6, 0xB5E6}, //1934 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEULPHIEUPH + {0x8BE7, 0xB5E7}, //1935 #HANGUL SYLLABLE SSANGTIKEUT YEO RIEULHIEUH + {0x8BE8, 0xB5E8}, //1936 #HANGUL SYLLABLE SSANGTIKEUT YEO MIEUM + {0x8BE9, 0xB5E9}, //1937 #HANGUL SYLLABLE SSANGTIKEUT YEO PIEUP + {0x8BEA, 0xB5EA}, //1938 #HANGUL SYLLABLE SSANGTIKEUT YEO PIEUPSIOS + {0x8BEB, 0xB5EB}, //1939 #HANGUL SYLLABLE SSANGTIKEUT YEO SIOS + {0x8BEC, 0xB5ED}, //1940 #HANGUL SYLLABLE SSANGTIKEUT YEO IEUNG + {0x8BED, 0xB5EE}, //1941 #HANGUL SYLLABLE SSANGTIKEUT YEO CIEUC + {0x8BEE, 0xB5EF}, //1942 #HANGUL SYLLABLE SSANGTIKEUT YEO CHIEUCH + {0x8BEF, 0xB5F0}, //1943 #HANGUL SYLLABLE SSANGTIKEUT YEO KHIEUKH + {0x8BF0, 0xB5F1}, //1944 #HANGUL SYLLABLE SSANGTIKEUT YEO THIEUTH + {0x8BF1, 0xB5F2}, //1945 #HANGUL SYLLABLE SSANGTIKEUT YEO PHIEUPH + {0x8BF2, 0xB5F3}, //1946 #HANGUL SYLLABLE SSANGTIKEUT YEO HIEUH + {0x8BF3, 0xB5F4}, //1947 #HANGUL SYLLABLE SSANGTIKEUT YE + {0x8BF4, 0xB5F5}, //1948 #HANGUL SYLLABLE SSANGTIKEUT YE KIYEOK + {0x8BF5, 0xB5F6}, //1949 #HANGUL SYLLABLE SSANGTIKEUT YE SSANGKIYEOK + {0x8BF6, 0xB5F7}, //1950 #HANGUL SYLLABLE SSANGTIKEUT YE KIYEOKSIOS + {0x8BF7, 0xB5F8}, //1951 #HANGUL SYLLABLE SSANGTIKEUT YE NIEUN + {0x8BF8, 0xB5F9}, //1952 #HANGUL SYLLABLE SSANGTIKEUT YE NIEUNCIEUC + {0x8BF9, 0xB5FA}, //1953 #HANGUL SYLLABLE SSANGTIKEUT YE NIEUNHIEUH + {0x8BFA, 0xB5FB}, //1954 #HANGUL SYLLABLE SSANGTIKEUT YE TIKEUT + {0x8BFB, 0xB5FC}, //1955 #HANGUL SYLLABLE SSANGTIKEUT YE RIEUL + {0x8BFC, 0xB5FD}, //1956 #HANGUL SYLLABLE SSANGTIKEUT YE RIEULKIYEOK + {0x8BFD, 0xB5FE}, //1957 #HANGUL SYLLABLE SSANGTIKEUT YE RIEULMIEUM + {0x8BFE, 0xB5FF}, //1958 #HANGUL SYLLABLE SSANGTIKEUT YE RIEULPIEUP + {0x8C41, 0xB600}, //1959 #HANGUL SYLLABLE SSANGTIKEUT YE RIEULSIOS + {0x8C42, 0xB601}, //1960 #HANGUL SYLLABLE SSANGTIKEUT YE RIEULTHIEUTH + {0x8C43, 0xB602}, //1961 #HANGUL SYLLABLE SSANGTIKEUT YE RIEULPHIEUPH + {0x8C44, 0xB603}, //1962 #HANGUL SYLLABLE SSANGTIKEUT YE RIEULHIEUH + {0x8C45, 0xB604}, //1963 #HANGUL SYLLABLE SSANGTIKEUT YE MIEUM + {0x8C46, 0xB605}, //1964 #HANGUL SYLLABLE SSANGTIKEUT YE PIEUP + {0x8C47, 0xB606}, //1965 #HANGUL SYLLABLE SSANGTIKEUT YE PIEUPSIOS + {0x8C48, 0xB607}, //1966 #HANGUL SYLLABLE SSANGTIKEUT YE SIOS + {0x8C49, 0xB608}, //1967 #HANGUL SYLLABLE SSANGTIKEUT YE SSANGSIOS + {0x8C4A, 0xB609}, //1968 #HANGUL SYLLABLE SSANGTIKEUT YE IEUNG + {0x8C4B, 0xB60A}, //1969 #HANGUL SYLLABLE SSANGTIKEUT YE CIEUC + {0x8C4C, 0xB60B}, //1970 #HANGUL SYLLABLE SSANGTIKEUT YE CHIEUCH + {0x8C4D, 0xB60C}, //1971 #HANGUL SYLLABLE SSANGTIKEUT YE KHIEUKH + {0x8C4E, 0xB60D}, //1972 #HANGUL SYLLABLE SSANGTIKEUT YE THIEUTH + {0x8C4F, 0xB60E}, //1973 #HANGUL SYLLABLE SSANGTIKEUT YE PHIEUPH + {0x8C50, 0xB60F}, //1974 #HANGUL SYLLABLE SSANGTIKEUT YE HIEUH + {0x8C51, 0xB612}, //1975 #HANGUL SYLLABLE SSANGTIKEUT O SSANGKIYEOK + {0x8C52, 0xB613}, //1976 #HANGUL SYLLABLE SSANGTIKEUT O KIYEOKSIOS + {0x8C53, 0xB615}, //1977 #HANGUL SYLLABLE SSANGTIKEUT O NIEUNCIEUC + {0x8C54, 0xB616}, //1978 #HANGUL SYLLABLE SSANGTIKEUT O NIEUNHIEUH + {0x8C55, 0xB617}, //1979 #HANGUL SYLLABLE SSANGTIKEUT O TIKEUT + {0x8C56, 0xB619}, //1980 #HANGUL SYLLABLE SSANGTIKEUT O RIEULKIYEOK + {0x8C57, 0xB61A}, //1981 #HANGUL SYLLABLE SSANGTIKEUT O RIEULMIEUM + {0x8C58, 0xB61B}, //1982 #HANGUL SYLLABLE SSANGTIKEUT O RIEULPIEUP + {0x8C59, 0xB61C}, //1983 #HANGUL SYLLABLE SSANGTIKEUT O RIEULSIOS + {0x8C5A, 0xB61D}, //1984 #HANGUL SYLLABLE SSANGTIKEUT O RIEULTHIEUTH + {0x8C61, 0xB61E}, //1985 #HANGUL SYLLABLE SSANGTIKEUT O RIEULPHIEUPH + {0x8C62, 0xB61F}, //1986 #HANGUL SYLLABLE SSANGTIKEUT O RIEULHIEUH + {0x8C63, 0xB620}, //1987 #HANGUL SYLLABLE SSANGTIKEUT O MIEUM + {0x8C64, 0xB621}, //1988 #HANGUL SYLLABLE SSANGTIKEUT O PIEUP + {0x8C65, 0xB622}, //1989 #HANGUL SYLLABLE SSANGTIKEUT O PIEUPSIOS + {0x8C66, 0xB623}, //1990 #HANGUL SYLLABLE SSANGTIKEUT O SIOS + {0x8C67, 0xB624}, //1991 #HANGUL SYLLABLE SSANGTIKEUT O SSANGSIOS + {0x8C68, 0xB626}, //1992 #HANGUL SYLLABLE SSANGTIKEUT O CIEUC + {0x8C69, 0xB627}, //1993 #HANGUL SYLLABLE SSANGTIKEUT O CHIEUCH + {0x8C6A, 0xB628}, //1994 #HANGUL SYLLABLE SSANGTIKEUT O KHIEUKH + {0x8C6B, 0xB629}, //1995 #HANGUL SYLLABLE SSANGTIKEUT O THIEUTH + {0x8C6C, 0xB62A}, //1996 #HANGUL SYLLABLE SSANGTIKEUT O PHIEUPH + {0x8C6D, 0xB62B}, //1997 #HANGUL SYLLABLE SSANGTIKEUT O HIEUH + {0x8C6E, 0xB62D}, //1998 #HANGUL SYLLABLE SSANGTIKEUT WA KIYEOK + {0x8C6F, 0xB62E}, //1999 #HANGUL SYLLABLE SSANGTIKEUT WA SSANGKIYEOK + {0x8C70, 0xB62F}, //2000 #HANGUL SYLLABLE SSANGTIKEUT WA KIYEOKSIOS + {0x8C71, 0xB630}, //2001 #HANGUL SYLLABLE SSANGTIKEUT WA NIEUN + {0x8C72, 0xB631}, //2002 #HANGUL SYLLABLE SSANGTIKEUT WA NIEUNCIEUC + {0x8C73, 0xB632}, //2003 #HANGUL SYLLABLE SSANGTIKEUT WA NIEUNHIEUH + {0x8C74, 0xB633}, //2004 #HANGUL SYLLABLE SSANGTIKEUT WA TIKEUT + {0x8C75, 0xB635}, //2005 #HANGUL SYLLABLE SSANGTIKEUT WA RIEULKIYEOK + {0x8C76, 0xB636}, //2006 #HANGUL SYLLABLE SSANGTIKEUT WA RIEULMIEUM + {0x8C77, 0xB637}, //2007 #HANGUL SYLLABLE SSANGTIKEUT WA RIEULPIEUP + {0x8C78, 0xB638}, //2008 #HANGUL SYLLABLE SSANGTIKEUT WA RIEULSIOS + {0x8C79, 0xB639}, //2009 #HANGUL SYLLABLE SSANGTIKEUT WA RIEULTHIEUTH + {0x8C7A, 0xB63A}, //2010 #HANGUL SYLLABLE SSANGTIKEUT WA RIEULPHIEUPH + {0x8C81, 0xB63B}, //2011 #HANGUL SYLLABLE SSANGTIKEUT WA RIEULHIEUH + {0x8C82, 0xB63C}, //2012 #HANGUL SYLLABLE SSANGTIKEUT WA MIEUM + {0x8C83, 0xB63D}, //2013 #HANGUL SYLLABLE SSANGTIKEUT WA PIEUP + {0x8C84, 0xB63E}, //2014 #HANGUL SYLLABLE SSANGTIKEUT WA PIEUPSIOS + {0x8C85, 0xB63F}, //2015 #HANGUL SYLLABLE SSANGTIKEUT WA SIOS + {0x8C86, 0xB640}, //2016 #HANGUL SYLLABLE SSANGTIKEUT WA SSANGSIOS + {0x8C87, 0xB641}, //2017 #HANGUL SYLLABLE SSANGTIKEUT WA IEUNG + {0x8C88, 0xB642}, //2018 #HANGUL SYLLABLE SSANGTIKEUT WA CIEUC + {0x8C89, 0xB643}, //2019 #HANGUL SYLLABLE SSANGTIKEUT WA CHIEUCH + {0x8C8A, 0xB644}, //2020 #HANGUL SYLLABLE SSANGTIKEUT WA KHIEUKH + {0x8C8B, 0xB645}, //2021 #HANGUL SYLLABLE SSANGTIKEUT WA THIEUTH + {0x8C8C, 0xB646}, //2022 #HANGUL SYLLABLE SSANGTIKEUT WA PHIEUPH + {0x8C8D, 0xB647}, //2023 #HANGUL SYLLABLE SSANGTIKEUT WA HIEUH + {0x8C8E, 0xB649}, //2024 #HANGUL SYLLABLE SSANGTIKEUT WAE KIYEOK + {0x8C8F, 0xB64A}, //2025 #HANGUL SYLLABLE SSANGTIKEUT WAE SSANGKIYEOK + {0x8C90, 0xB64B}, //2026 #HANGUL SYLLABLE SSANGTIKEUT WAE KIYEOKSIOS + {0x8C91, 0xB64C}, //2027 #HANGUL SYLLABLE SSANGTIKEUT WAE NIEUN + {0x8C92, 0xB64D}, //2028 #HANGUL SYLLABLE SSANGTIKEUT WAE NIEUNCIEUC + {0x8C93, 0xB64E}, //2029 #HANGUL SYLLABLE SSANGTIKEUT WAE NIEUNHIEUH + {0x8C94, 0xB64F}, //2030 #HANGUL SYLLABLE SSANGTIKEUT WAE TIKEUT + {0x8C95, 0xB650}, //2031 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEUL + {0x8C96, 0xB651}, //2032 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEULKIYEOK + {0x8C97, 0xB652}, //2033 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEULMIEUM + {0x8C98, 0xB653}, //2034 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEULPIEUP + {0x8C99, 0xB654}, //2035 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEULSIOS + {0x8C9A, 0xB655}, //2036 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEULTHIEUTH + {0x8C9B, 0xB656}, //2037 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEULPHIEUPH + {0x8C9C, 0xB657}, //2038 #HANGUL SYLLABLE SSANGTIKEUT WAE RIEULHIEUH + {0x8C9D, 0xB658}, //2039 #HANGUL SYLLABLE SSANGTIKEUT WAE MIEUM + {0x8C9E, 0xB659}, //2040 #HANGUL SYLLABLE SSANGTIKEUT WAE PIEUP + {0x8C9F, 0xB65A}, //2041 #HANGUL SYLLABLE SSANGTIKEUT WAE PIEUPSIOS + {0x8CA0, 0xB65B}, //2042 #HANGUL SYLLABLE SSANGTIKEUT WAE SIOS + {0x8CA1, 0xB65C}, //2043 #HANGUL SYLLABLE SSANGTIKEUT WAE SSANGSIOS + {0x8CA2, 0xB65D}, //2044 #HANGUL SYLLABLE SSANGTIKEUT WAE IEUNG + {0x8CA3, 0xB65E}, //2045 #HANGUL SYLLABLE SSANGTIKEUT WAE CIEUC + {0x8CA4, 0xB65F}, //2046 #HANGUL SYLLABLE SSANGTIKEUT WAE CHIEUCH + {0x8CA5, 0xB660}, //2047 #HANGUL SYLLABLE SSANGTIKEUT WAE KHIEUKH + {0x8CA6, 0xB661}, //2048 #HANGUL SYLLABLE SSANGTIKEUT WAE THIEUTH + {0x8CA7, 0xB662}, //2049 #HANGUL SYLLABLE SSANGTIKEUT WAE PHIEUPH + {0x8CA8, 0xB663}, //2050 #HANGUL SYLLABLE SSANGTIKEUT WAE HIEUH + {0x8CA9, 0xB665}, //2051 #HANGUL SYLLABLE SSANGTIKEUT OE KIYEOK + {0x8CAA, 0xB666}, //2052 #HANGUL SYLLABLE SSANGTIKEUT OE SSANGKIYEOK + {0x8CAB, 0xB667}, //2053 #HANGUL SYLLABLE SSANGTIKEUT OE KIYEOKSIOS + {0x8CAC, 0xB669}, //2054 #HANGUL SYLLABLE SSANGTIKEUT OE NIEUNCIEUC + {0x8CAD, 0xB66A}, //2055 #HANGUL SYLLABLE SSANGTIKEUT OE NIEUNHIEUH + {0x8CAE, 0xB66B}, //2056 #HANGUL SYLLABLE SSANGTIKEUT OE TIKEUT + {0x8CAF, 0xB66C}, //2057 #HANGUL SYLLABLE SSANGTIKEUT OE RIEUL + {0x8CB0, 0xB66D}, //2058 #HANGUL SYLLABLE SSANGTIKEUT OE RIEULKIYEOK + {0x8CB1, 0xB66E}, //2059 #HANGUL SYLLABLE SSANGTIKEUT OE RIEULMIEUM + {0x8CB2, 0xB66F}, //2060 #HANGUL SYLLABLE SSANGTIKEUT OE RIEULPIEUP + {0x8CB3, 0xB670}, //2061 #HANGUL SYLLABLE SSANGTIKEUT OE RIEULSIOS + {0x8CB4, 0xB671}, //2062 #HANGUL SYLLABLE SSANGTIKEUT OE RIEULTHIEUTH + {0x8CB5, 0xB672}, //2063 #HANGUL SYLLABLE SSANGTIKEUT OE RIEULPHIEUPH + {0x8CB6, 0xB673}, //2064 #HANGUL SYLLABLE SSANGTIKEUT OE RIEULHIEUH + {0x8CB7, 0xB674}, //2065 #HANGUL SYLLABLE SSANGTIKEUT OE MIEUM + {0x8CB8, 0xB675}, //2066 #HANGUL SYLLABLE SSANGTIKEUT OE PIEUP + {0x8CB9, 0xB676}, //2067 #HANGUL SYLLABLE SSANGTIKEUT OE PIEUPSIOS + {0x8CBA, 0xB677}, //2068 #HANGUL SYLLABLE SSANGTIKEUT OE SIOS + {0x8CBB, 0xB678}, //2069 #HANGUL SYLLABLE SSANGTIKEUT OE SSANGSIOS + {0x8CBC, 0xB679}, //2070 #HANGUL SYLLABLE SSANGTIKEUT OE IEUNG + {0x8CBD, 0xB67A}, //2071 #HANGUL SYLLABLE SSANGTIKEUT OE CIEUC + {0x8CBE, 0xB67B}, //2072 #HANGUL SYLLABLE SSANGTIKEUT OE CHIEUCH + {0x8CBF, 0xB67C}, //2073 #HANGUL SYLLABLE SSANGTIKEUT OE KHIEUKH + {0x8CC0, 0xB67D}, //2074 #HANGUL SYLLABLE SSANGTIKEUT OE THIEUTH + {0x8CC1, 0xB67E}, //2075 #HANGUL SYLLABLE SSANGTIKEUT OE PHIEUPH + {0x8CC2, 0xB67F}, //2076 #HANGUL SYLLABLE SSANGTIKEUT OE HIEUH + {0x8CC3, 0xB680}, //2077 #HANGUL SYLLABLE SSANGTIKEUT YO + {0x8CC4, 0xB681}, //2078 #HANGUL SYLLABLE SSANGTIKEUT YO KIYEOK + {0x8CC5, 0xB682}, //2079 #HANGUL SYLLABLE SSANGTIKEUT YO SSANGKIYEOK + {0x8CC6, 0xB683}, //2080 #HANGUL SYLLABLE SSANGTIKEUT YO KIYEOKSIOS + {0x8CC7, 0xB684}, //2081 #HANGUL SYLLABLE SSANGTIKEUT YO NIEUN + {0x8CC8, 0xB685}, //2082 #HANGUL SYLLABLE SSANGTIKEUT YO NIEUNCIEUC + {0x8CC9, 0xB686}, //2083 #HANGUL SYLLABLE SSANGTIKEUT YO NIEUNHIEUH + {0x8CCA, 0xB687}, //2084 #HANGUL SYLLABLE SSANGTIKEUT YO TIKEUT + {0x8CCB, 0xB688}, //2085 #HANGUL SYLLABLE SSANGTIKEUT YO RIEUL + {0x8CCC, 0xB689}, //2086 #HANGUL SYLLABLE SSANGTIKEUT YO RIEULKIYEOK + {0x8CCD, 0xB68A}, //2087 #HANGUL SYLLABLE SSANGTIKEUT YO RIEULMIEUM + {0x8CCE, 0xB68B}, //2088 #HANGUL SYLLABLE SSANGTIKEUT YO RIEULPIEUP + {0x8CCF, 0xB68C}, //2089 #HANGUL SYLLABLE SSANGTIKEUT YO RIEULSIOS + {0x8CD0, 0xB68D}, //2090 #HANGUL SYLLABLE SSANGTIKEUT YO RIEULTHIEUTH + {0x8CD1, 0xB68E}, //2091 #HANGUL SYLLABLE SSANGTIKEUT YO RIEULPHIEUPH + {0x8CD2, 0xB68F}, //2092 #HANGUL SYLLABLE SSANGTIKEUT YO RIEULHIEUH + {0x8CD3, 0xB690}, //2093 #HANGUL SYLLABLE SSANGTIKEUT YO MIEUM + {0x8CD4, 0xB691}, //2094 #HANGUL SYLLABLE SSANGTIKEUT YO PIEUP + {0x8CD5, 0xB692}, //2095 #HANGUL SYLLABLE SSANGTIKEUT YO PIEUPSIOS + {0x8CD6, 0xB693}, //2096 #HANGUL SYLLABLE SSANGTIKEUT YO SIOS + {0x8CD7, 0xB694}, //2097 #HANGUL SYLLABLE SSANGTIKEUT YO SSANGSIOS + {0x8CD8, 0xB695}, //2098 #HANGUL SYLLABLE SSANGTIKEUT YO IEUNG + {0x8CD9, 0xB696}, //2099 #HANGUL SYLLABLE SSANGTIKEUT YO CIEUC + {0x8CDA, 0xB697}, //2100 #HANGUL SYLLABLE SSANGTIKEUT YO CHIEUCH + {0x8CDB, 0xB698}, //2101 #HANGUL SYLLABLE SSANGTIKEUT YO KHIEUKH + {0x8CDC, 0xB699}, //2102 #HANGUL SYLLABLE SSANGTIKEUT YO THIEUTH + {0x8CDD, 0xB69A}, //2103 #HANGUL SYLLABLE SSANGTIKEUT YO PHIEUPH + {0x8CDE, 0xB69B}, //2104 #HANGUL SYLLABLE SSANGTIKEUT YO HIEUH + {0x8CDF, 0xB69E}, //2105 #HANGUL SYLLABLE SSANGTIKEUT U SSANGKIYEOK + {0x8CE0, 0xB69F}, //2106 #HANGUL SYLLABLE SSANGTIKEUT U KIYEOKSIOS + {0x8CE1, 0xB6A1}, //2107 #HANGUL SYLLABLE SSANGTIKEUT U NIEUNCIEUC + {0x8CE2, 0xB6A2}, //2108 #HANGUL SYLLABLE SSANGTIKEUT U NIEUNHIEUH + {0x8CE3, 0xB6A3}, //2109 #HANGUL SYLLABLE SSANGTIKEUT U TIKEUT + {0x8CE4, 0xB6A5}, //2110 #HANGUL SYLLABLE SSANGTIKEUT U RIEULKIYEOK + {0x8CE5, 0xB6A6}, //2111 #HANGUL SYLLABLE SSANGTIKEUT U RIEULMIEUM + {0x8CE6, 0xB6A7}, //2112 #HANGUL SYLLABLE SSANGTIKEUT U RIEULPIEUP + {0x8CE7, 0xB6A8}, //2113 #HANGUL SYLLABLE SSANGTIKEUT U RIEULSIOS + {0x8CE8, 0xB6A9}, //2114 #HANGUL SYLLABLE SSANGTIKEUT U RIEULTHIEUTH + {0x8CE9, 0xB6AA}, //2115 #HANGUL SYLLABLE SSANGTIKEUT U RIEULPHIEUPH + {0x8CEA, 0xB6AD}, //2116 #HANGUL SYLLABLE SSANGTIKEUT U PIEUP + {0x8CEB, 0xB6AE}, //2117 #HANGUL SYLLABLE SSANGTIKEUT U PIEUPSIOS + {0x8CEC, 0xB6AF}, //2118 #HANGUL SYLLABLE SSANGTIKEUT U SIOS + {0x8CED, 0xB6B0}, //2119 #HANGUL SYLLABLE SSANGTIKEUT U SSANGSIOS + {0x8CEE, 0xB6B2}, //2120 #HANGUL SYLLABLE SSANGTIKEUT U CIEUC + {0x8CEF, 0xB6B3}, //2121 #HANGUL SYLLABLE SSANGTIKEUT U CHIEUCH + {0x8CF0, 0xB6B4}, //2122 #HANGUL SYLLABLE SSANGTIKEUT U KHIEUKH + {0x8CF1, 0xB6B5}, //2123 #HANGUL SYLLABLE SSANGTIKEUT U THIEUTH + {0x8CF2, 0xB6B6}, //2124 #HANGUL SYLLABLE SSANGTIKEUT U PHIEUPH + {0x8CF3, 0xB6B7}, //2125 #HANGUL SYLLABLE SSANGTIKEUT U HIEUH + {0x8CF4, 0xB6B8}, //2126 #HANGUL SYLLABLE SSANGTIKEUT WEO + {0x8CF5, 0xB6B9}, //2127 #HANGUL SYLLABLE SSANGTIKEUT WEO KIYEOK + {0x8CF6, 0xB6BA}, //2128 #HANGUL SYLLABLE SSANGTIKEUT WEO SSANGKIYEOK + {0x8CF7, 0xB6BB}, //2129 #HANGUL SYLLABLE SSANGTIKEUT WEO KIYEOKSIOS + {0x8CF8, 0xB6BC}, //2130 #HANGUL SYLLABLE SSANGTIKEUT WEO NIEUN + {0x8CF9, 0xB6BD}, //2131 #HANGUL SYLLABLE SSANGTIKEUT WEO NIEUNCIEUC + {0x8CFA, 0xB6BE}, //2132 #HANGUL SYLLABLE SSANGTIKEUT WEO NIEUNHIEUH + {0x8CFB, 0xB6BF}, //2133 #HANGUL SYLLABLE SSANGTIKEUT WEO TIKEUT + {0x8CFC, 0xB6C0}, //2134 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEUL + {0x8CFD, 0xB6C1}, //2135 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEULKIYEOK + {0x8CFE, 0xB6C2}, //2136 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEULMIEUM + {0x8D41, 0xB6C3}, //2137 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEULPIEUP + {0x8D42, 0xB6C4}, //2138 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEULSIOS + {0x8D43, 0xB6C5}, //2139 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEULTHIEUTH + {0x8D44, 0xB6C6}, //2140 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEULPHIEUPH + {0x8D45, 0xB6C7}, //2141 #HANGUL SYLLABLE SSANGTIKEUT WEO RIEULHIEUH + {0x8D46, 0xB6C8}, //2142 #HANGUL SYLLABLE SSANGTIKEUT WEO MIEUM + {0x8D47, 0xB6C9}, //2143 #HANGUL SYLLABLE SSANGTIKEUT WEO PIEUP + {0x8D48, 0xB6CA}, //2144 #HANGUL SYLLABLE SSANGTIKEUT WEO PIEUPSIOS + {0x8D49, 0xB6CB}, //2145 #HANGUL SYLLABLE SSANGTIKEUT WEO SIOS + {0x8D4A, 0xB6CC}, //2146 #HANGUL SYLLABLE SSANGTIKEUT WEO SSANGSIOS + {0x8D4B, 0xB6CD}, //2147 #HANGUL SYLLABLE SSANGTIKEUT WEO IEUNG + {0x8D4C, 0xB6CE}, //2148 #HANGUL SYLLABLE SSANGTIKEUT WEO CIEUC + {0x8D4D, 0xB6CF}, //2149 #HANGUL SYLLABLE SSANGTIKEUT WEO CHIEUCH + {0x8D4E, 0xB6D0}, //2150 #HANGUL SYLLABLE SSANGTIKEUT WEO KHIEUKH + {0x8D4F, 0xB6D1}, //2151 #HANGUL SYLLABLE SSANGTIKEUT WEO THIEUTH + {0x8D50, 0xB6D2}, //2152 #HANGUL SYLLABLE SSANGTIKEUT WEO PHIEUPH + {0x8D51, 0xB6D3}, //2153 #HANGUL SYLLABLE SSANGTIKEUT WEO HIEUH + {0x8D52, 0xB6D5}, //2154 #HANGUL SYLLABLE SSANGTIKEUT WE KIYEOK + {0x8D53, 0xB6D6}, //2155 #HANGUL SYLLABLE SSANGTIKEUT WE SSANGKIYEOK + {0x8D54, 0xB6D7}, //2156 #HANGUL SYLLABLE SSANGTIKEUT WE KIYEOKSIOS + {0x8D55, 0xB6D8}, //2157 #HANGUL SYLLABLE SSANGTIKEUT WE NIEUN + {0x8D56, 0xB6D9}, //2158 #HANGUL SYLLABLE SSANGTIKEUT WE NIEUNCIEUC + {0x8D57, 0xB6DA}, //2159 #HANGUL SYLLABLE SSANGTIKEUT WE NIEUNHIEUH + {0x8D58, 0xB6DB}, //2160 #HANGUL SYLLABLE SSANGTIKEUT WE TIKEUT + {0x8D59, 0xB6DC}, //2161 #HANGUL SYLLABLE SSANGTIKEUT WE RIEUL + {0x8D5A, 0xB6DD}, //2162 #HANGUL SYLLABLE SSANGTIKEUT WE RIEULKIYEOK + {0x8D61, 0xB6DE}, //2163 #HANGUL SYLLABLE SSANGTIKEUT WE RIEULMIEUM + {0x8D62, 0xB6DF}, //2164 #HANGUL SYLLABLE SSANGTIKEUT WE RIEULPIEUP + {0x8D63, 0xB6E0}, //2165 #HANGUL SYLLABLE SSANGTIKEUT WE RIEULSIOS + {0x8D64, 0xB6E1}, //2166 #HANGUL SYLLABLE SSANGTIKEUT WE RIEULTHIEUTH + {0x8D65, 0xB6E2}, //2167 #HANGUL SYLLABLE SSANGTIKEUT WE RIEULPHIEUPH + {0x8D66, 0xB6E3}, //2168 #HANGUL SYLLABLE SSANGTIKEUT WE RIEULHIEUH + {0x8D67, 0xB6E4}, //2169 #HANGUL SYLLABLE SSANGTIKEUT WE MIEUM + {0x8D68, 0xB6E5}, //2170 #HANGUL SYLLABLE SSANGTIKEUT WE PIEUP + {0x8D69, 0xB6E6}, //2171 #HANGUL SYLLABLE SSANGTIKEUT WE PIEUPSIOS + {0x8D6A, 0xB6E7}, //2172 #HANGUL SYLLABLE SSANGTIKEUT WE SIOS + {0x8D6B, 0xB6E8}, //2173 #HANGUL SYLLABLE SSANGTIKEUT WE SSANGSIOS + {0x8D6C, 0xB6E9}, //2174 #HANGUL SYLLABLE SSANGTIKEUT WE IEUNG + {0x8D6D, 0xB6EA}, //2175 #HANGUL SYLLABLE SSANGTIKEUT WE CIEUC + {0x8D6E, 0xB6EB}, //2176 #HANGUL SYLLABLE SSANGTIKEUT WE CHIEUCH + {0x8D6F, 0xB6EC}, //2177 #HANGUL SYLLABLE SSANGTIKEUT WE KHIEUKH + {0x8D70, 0xB6ED}, //2178 #HANGUL SYLLABLE SSANGTIKEUT WE THIEUTH + {0x8D71, 0xB6EE}, //2179 #HANGUL SYLLABLE SSANGTIKEUT WE PHIEUPH + {0x8D72, 0xB6EF}, //2180 #HANGUL SYLLABLE SSANGTIKEUT WE HIEUH + {0x8D73, 0xB6F1}, //2181 #HANGUL SYLLABLE SSANGTIKEUT WI KIYEOK + {0x8D74, 0xB6F2}, //2182 #HANGUL SYLLABLE SSANGTIKEUT WI SSANGKIYEOK + {0x8D75, 0xB6F3}, //2183 #HANGUL SYLLABLE SSANGTIKEUT WI KIYEOKSIOS + {0x8D76, 0xB6F5}, //2184 #HANGUL SYLLABLE SSANGTIKEUT WI NIEUNCIEUC + {0x8D77, 0xB6F6}, //2185 #HANGUL SYLLABLE SSANGTIKEUT WI NIEUNHIEUH + {0x8D78, 0xB6F7}, //2186 #HANGUL SYLLABLE SSANGTIKEUT WI TIKEUT + {0x8D79, 0xB6F9}, //2187 #HANGUL SYLLABLE SSANGTIKEUT WI RIEULKIYEOK + {0x8D7A, 0xB6FA}, //2188 #HANGUL SYLLABLE SSANGTIKEUT WI RIEULMIEUM + {0x8D81, 0xB6FB}, //2189 #HANGUL SYLLABLE SSANGTIKEUT WI RIEULPIEUP + {0x8D82, 0xB6FC}, //2190 #HANGUL SYLLABLE SSANGTIKEUT WI RIEULSIOS + {0x8D83, 0xB6FD}, //2191 #HANGUL SYLLABLE SSANGTIKEUT WI RIEULTHIEUTH + {0x8D84, 0xB6FE}, //2192 #HANGUL SYLLABLE SSANGTIKEUT WI RIEULPHIEUPH + {0x8D85, 0xB6FF}, //2193 #HANGUL SYLLABLE SSANGTIKEUT WI RIEULHIEUH + {0x8D86, 0xB702}, //2194 #HANGUL SYLLABLE SSANGTIKEUT WI PIEUPSIOS + {0x8D87, 0xB703}, //2195 #HANGUL SYLLABLE SSANGTIKEUT WI SIOS + {0x8D88, 0xB704}, //2196 #HANGUL SYLLABLE SSANGTIKEUT WI SSANGSIOS + {0x8D89, 0xB706}, //2197 #HANGUL SYLLABLE SSANGTIKEUT WI CIEUC + {0x8D8A, 0xB707}, //2198 #HANGUL SYLLABLE SSANGTIKEUT WI CHIEUCH + {0x8D8B, 0xB708}, //2199 #HANGUL SYLLABLE SSANGTIKEUT WI KHIEUKH + {0x8D8C, 0xB709}, //2200 #HANGUL SYLLABLE SSANGTIKEUT WI THIEUTH + {0x8D8D, 0xB70A}, //2201 #HANGUL SYLLABLE SSANGTIKEUT WI PHIEUPH + {0x8D8E, 0xB70B}, //2202 #HANGUL SYLLABLE SSANGTIKEUT WI HIEUH + {0x8D8F, 0xB70C}, //2203 #HANGUL SYLLABLE SSANGTIKEUT YU + {0x8D90, 0xB70D}, //2204 #HANGUL SYLLABLE SSANGTIKEUT YU KIYEOK + {0x8D91, 0xB70E}, //2205 #HANGUL SYLLABLE SSANGTIKEUT YU SSANGKIYEOK + {0x8D92, 0xB70F}, //2206 #HANGUL SYLLABLE SSANGTIKEUT YU KIYEOKSIOS + {0x8D93, 0xB710}, //2207 #HANGUL SYLLABLE SSANGTIKEUT YU NIEUN + {0x8D94, 0xB711}, //2208 #HANGUL SYLLABLE SSANGTIKEUT YU NIEUNCIEUC + {0x8D95, 0xB712}, //2209 #HANGUL SYLLABLE SSANGTIKEUT YU NIEUNHIEUH + {0x8D96, 0xB713}, //2210 #HANGUL SYLLABLE SSANGTIKEUT YU TIKEUT + {0x8D97, 0xB714}, //2211 #HANGUL SYLLABLE SSANGTIKEUT YU RIEUL + {0x8D98, 0xB715}, //2212 #HANGUL SYLLABLE SSANGTIKEUT YU RIEULKIYEOK + {0x8D99, 0xB716}, //2213 #HANGUL SYLLABLE SSANGTIKEUT YU RIEULMIEUM + {0x8D9A, 0xB717}, //2214 #HANGUL SYLLABLE SSANGTIKEUT YU RIEULPIEUP + {0x8D9B, 0xB718}, //2215 #HANGUL SYLLABLE SSANGTIKEUT YU RIEULSIOS + {0x8D9C, 0xB719}, //2216 #HANGUL SYLLABLE SSANGTIKEUT YU RIEULTHIEUTH + {0x8D9D, 0xB71A}, //2217 #HANGUL SYLLABLE SSANGTIKEUT YU RIEULPHIEUPH + {0x8D9E, 0xB71B}, //2218 #HANGUL SYLLABLE SSANGTIKEUT YU RIEULHIEUH + {0x8D9F, 0xB71C}, //2219 #HANGUL SYLLABLE SSANGTIKEUT YU MIEUM + {0x8DA0, 0xB71D}, //2220 #HANGUL SYLLABLE SSANGTIKEUT YU PIEUP + {0x8DA1, 0xB71E}, //2221 #HANGUL SYLLABLE SSANGTIKEUT YU PIEUPSIOS + {0x8DA2, 0xB71F}, //2222 #HANGUL SYLLABLE SSANGTIKEUT YU SIOS + {0x8DA3, 0xB720}, //2223 #HANGUL SYLLABLE SSANGTIKEUT YU SSANGSIOS + {0x8DA4, 0xB721}, //2224 #HANGUL SYLLABLE SSANGTIKEUT YU IEUNG + {0x8DA5, 0xB722}, //2225 #HANGUL SYLLABLE SSANGTIKEUT YU CIEUC + {0x8DA6, 0xB723}, //2226 #HANGUL SYLLABLE SSANGTIKEUT YU CHIEUCH + {0x8DA7, 0xB724}, //2227 #HANGUL SYLLABLE SSANGTIKEUT YU KHIEUKH + {0x8DA8, 0xB725}, //2228 #HANGUL SYLLABLE SSANGTIKEUT YU THIEUTH + {0x8DA9, 0xB726}, //2229 #HANGUL SYLLABLE SSANGTIKEUT YU PHIEUPH + {0x8DAA, 0xB727}, //2230 #HANGUL SYLLABLE SSANGTIKEUT YU HIEUH + {0x8DAB, 0xB72A}, //2231 #HANGUL SYLLABLE SSANGTIKEUT EU SSANGKIYEOK + {0x8DAC, 0xB72B}, //2232 #HANGUL SYLLABLE SSANGTIKEUT EU KIYEOKSIOS + {0x8DAD, 0xB72D}, //2233 #HANGUL SYLLABLE SSANGTIKEUT EU NIEUNCIEUC + {0x8DAE, 0xB72E}, //2234 #HANGUL SYLLABLE SSANGTIKEUT EU NIEUNHIEUH + {0x8DAF, 0xB731}, //2235 #HANGUL SYLLABLE SSANGTIKEUT EU RIEULKIYEOK + {0x8DB0, 0xB732}, //2236 #HANGUL SYLLABLE SSANGTIKEUT EU RIEULMIEUM + {0x8DB1, 0xB733}, //2237 #HANGUL SYLLABLE SSANGTIKEUT EU RIEULPIEUP + {0x8DB2, 0xB734}, //2238 #HANGUL SYLLABLE SSANGTIKEUT EU RIEULSIOS + {0x8DB3, 0xB735}, //2239 #HANGUL SYLLABLE SSANGTIKEUT EU RIEULTHIEUTH + {0x8DB4, 0xB736}, //2240 #HANGUL SYLLABLE SSANGTIKEUT EU RIEULPHIEUPH + {0x8DB5, 0xB737}, //2241 #HANGUL SYLLABLE SSANGTIKEUT EU RIEULHIEUH + {0x8DB6, 0xB73A}, //2242 #HANGUL SYLLABLE SSANGTIKEUT EU PIEUPSIOS + {0x8DB7, 0xB73C}, //2243 #HANGUL SYLLABLE SSANGTIKEUT EU SSANGSIOS + {0x8DB8, 0xB73D}, //2244 #HANGUL SYLLABLE SSANGTIKEUT EU IEUNG + {0x8DB9, 0xB73E}, //2245 #HANGUL SYLLABLE SSANGTIKEUT EU CIEUC + {0x8DBA, 0xB73F}, //2246 #HANGUL SYLLABLE SSANGTIKEUT EU CHIEUCH + {0x8DBB, 0xB740}, //2247 #HANGUL SYLLABLE SSANGTIKEUT EU KHIEUKH + {0x8DBC, 0xB741}, //2248 #HANGUL SYLLABLE SSANGTIKEUT EU THIEUTH + {0x8DBD, 0xB742}, //2249 #HANGUL SYLLABLE SSANGTIKEUT EU PHIEUPH + {0x8DBE, 0xB743}, //2250 #HANGUL SYLLABLE SSANGTIKEUT EU HIEUH + {0x8DBF, 0xB745}, //2251 #HANGUL SYLLABLE SSANGTIKEUT YI KIYEOK + {0x8DC0, 0xB746}, //2252 #HANGUL SYLLABLE SSANGTIKEUT YI SSANGKIYEOK + {0x8DC1, 0xB747}, //2253 #HANGUL SYLLABLE SSANGTIKEUT YI KIYEOKSIOS + {0x8DC2, 0xB749}, //2254 #HANGUL SYLLABLE SSANGTIKEUT YI NIEUNCIEUC + {0x8DC3, 0xB74A}, //2255 #HANGUL SYLLABLE SSANGTIKEUT YI NIEUNHIEUH + {0x8DC4, 0xB74B}, //2256 #HANGUL SYLLABLE SSANGTIKEUT YI TIKEUT + {0x8DC5, 0xB74D}, //2257 #HANGUL SYLLABLE SSANGTIKEUT YI RIEULKIYEOK + {0x8DC6, 0xB74E}, //2258 #HANGUL SYLLABLE SSANGTIKEUT YI RIEULMIEUM + {0x8DC7, 0xB74F}, //2259 #HANGUL SYLLABLE SSANGTIKEUT YI RIEULPIEUP + {0x8DC8, 0xB750}, //2260 #HANGUL SYLLABLE SSANGTIKEUT YI RIEULSIOS + {0x8DC9, 0xB751}, //2261 #HANGUL SYLLABLE SSANGTIKEUT YI RIEULTHIEUTH + {0x8DCA, 0xB752}, //2262 #HANGUL SYLLABLE SSANGTIKEUT YI RIEULPHIEUPH + {0x8DCB, 0xB753}, //2263 #HANGUL SYLLABLE SSANGTIKEUT YI RIEULHIEUH + {0x8DCC, 0xB756}, //2264 #HANGUL SYLLABLE SSANGTIKEUT YI PIEUPSIOS + {0x8DCD, 0xB757}, //2265 #HANGUL SYLLABLE SSANGTIKEUT YI SIOS + {0x8DCE, 0xB758}, //2266 #HANGUL SYLLABLE SSANGTIKEUT YI SSANGSIOS + {0x8DCF, 0xB759}, //2267 #HANGUL SYLLABLE SSANGTIKEUT YI IEUNG + {0x8DD0, 0xB75A}, //2268 #HANGUL SYLLABLE SSANGTIKEUT YI CIEUC + {0x8DD1, 0xB75B}, //2269 #HANGUL SYLLABLE SSANGTIKEUT YI CHIEUCH + {0x8DD2, 0xB75C}, //2270 #HANGUL SYLLABLE SSANGTIKEUT YI KHIEUKH + {0x8DD3, 0xB75D}, //2271 #HANGUL SYLLABLE SSANGTIKEUT YI THIEUTH + {0x8DD4, 0xB75E}, //2272 #HANGUL SYLLABLE SSANGTIKEUT YI PHIEUPH + {0x8DD5, 0xB75F}, //2273 #HANGUL SYLLABLE SSANGTIKEUT YI HIEUH + {0x8DD6, 0xB761}, //2274 #HANGUL SYLLABLE SSANGTIKEUT I KIYEOK + {0x8DD7, 0xB762}, //2275 #HANGUL SYLLABLE SSANGTIKEUT I SSANGKIYEOK + {0x8DD8, 0xB763}, //2276 #HANGUL SYLLABLE SSANGTIKEUT I KIYEOKSIOS + {0x8DD9, 0xB765}, //2277 #HANGUL SYLLABLE SSANGTIKEUT I NIEUNCIEUC + {0x8DDA, 0xB766}, //2278 #HANGUL SYLLABLE SSANGTIKEUT I NIEUNHIEUH + {0x8DDB, 0xB767}, //2279 #HANGUL SYLLABLE SSANGTIKEUT I TIKEUT + {0x8DDC, 0xB769}, //2280 #HANGUL SYLLABLE SSANGTIKEUT I RIEULKIYEOK + {0x8DDD, 0xB76A}, //2281 #HANGUL SYLLABLE SSANGTIKEUT I RIEULMIEUM + {0x8DDE, 0xB76B}, //2282 #HANGUL SYLLABLE SSANGTIKEUT I RIEULPIEUP + {0x8DDF, 0xB76C}, //2283 #HANGUL SYLLABLE SSANGTIKEUT I RIEULSIOS + {0x8DE0, 0xB76D}, //2284 #HANGUL SYLLABLE SSANGTIKEUT I RIEULTHIEUTH + {0x8DE1, 0xB76E}, //2285 #HANGUL SYLLABLE SSANGTIKEUT I RIEULPHIEUPH + {0x8DE2, 0xB76F}, //2286 #HANGUL SYLLABLE SSANGTIKEUT I RIEULHIEUH + {0x8DE3, 0xB772}, //2287 #HANGUL SYLLABLE SSANGTIKEUT I PIEUPSIOS + {0x8DE4, 0xB774}, //2288 #HANGUL SYLLABLE SSANGTIKEUT I SSANGSIOS + {0x8DE5, 0xB776}, //2289 #HANGUL SYLLABLE SSANGTIKEUT I CIEUC + {0x8DE6, 0xB777}, //2290 #HANGUL SYLLABLE SSANGTIKEUT I CHIEUCH + {0x8DE7, 0xB778}, //2291 #HANGUL SYLLABLE SSANGTIKEUT I KHIEUKH + {0x8DE8, 0xB779}, //2292 #HANGUL SYLLABLE SSANGTIKEUT I THIEUTH + {0x8DE9, 0xB77A}, //2293 #HANGUL SYLLABLE SSANGTIKEUT I PHIEUPH + {0x8DEA, 0xB77B}, //2294 #HANGUL SYLLABLE SSANGTIKEUT I HIEUH + {0x8DEB, 0xB77E}, //2295 #HANGUL SYLLABLE RIEUL A SSANGKIYEOK + {0x8DEC, 0xB77F}, //2296 #HANGUL SYLLABLE RIEUL A KIYEOKSIOS + {0x8DED, 0xB781}, //2297 #HANGUL SYLLABLE RIEUL A NIEUNCIEUC + {0x8DEE, 0xB782}, //2298 #HANGUL SYLLABLE RIEUL A NIEUNHIEUH + {0x8DEF, 0xB783}, //2299 #HANGUL SYLLABLE RIEUL A TIKEUT + {0x8DF0, 0xB785}, //2300 #HANGUL SYLLABLE RIEUL A RIEULKIYEOK + {0x8DF1, 0xB786}, //2301 #HANGUL SYLLABLE RIEUL A RIEULMIEUM + {0x8DF2, 0xB787}, //2302 #HANGUL SYLLABLE RIEUL A RIEULPIEUP + {0x8DF3, 0xB788}, //2303 #HANGUL SYLLABLE RIEUL A RIEULSIOS + {0x8DF4, 0xB789}, //2304 #HANGUL SYLLABLE RIEUL A RIEULTHIEUTH + {0x8DF5, 0xB78A}, //2305 #HANGUL SYLLABLE RIEUL A RIEULPHIEUPH + {0x8DF6, 0xB78B}, //2306 #HANGUL SYLLABLE RIEUL A RIEULHIEUH + {0x8DF7, 0xB78E}, //2307 #HANGUL SYLLABLE RIEUL A PIEUPSIOS + {0x8DF8, 0xB793}, //2308 #HANGUL SYLLABLE RIEUL A CHIEUCH + {0x8DF9, 0xB794}, //2309 #HANGUL SYLLABLE RIEUL A KHIEUKH + {0x8DFA, 0xB795}, //2310 #HANGUL SYLLABLE RIEUL A THIEUTH + {0x8DFB, 0xB79A}, //2311 #HANGUL SYLLABLE RIEUL AE SSANGKIYEOK + {0x8DFC, 0xB79B}, //2312 #HANGUL SYLLABLE RIEUL AE KIYEOKSIOS + {0x8DFD, 0xB79D}, //2313 #HANGUL SYLLABLE RIEUL AE NIEUNCIEUC + {0x8DFE, 0xB79E}, //2314 #HANGUL SYLLABLE RIEUL AE NIEUNHIEUH + {0x8E41, 0xB79F}, //2315 #HANGUL SYLLABLE RIEUL AE TIKEUT + {0x8E42, 0xB7A1}, //2316 #HANGUL SYLLABLE RIEUL AE RIEULKIYEOK + {0x8E43, 0xB7A2}, //2317 #HANGUL SYLLABLE RIEUL AE RIEULMIEUM + {0x8E44, 0xB7A3}, //2318 #HANGUL SYLLABLE RIEUL AE RIEULPIEUP + {0x8E45, 0xB7A4}, //2319 #HANGUL SYLLABLE RIEUL AE RIEULSIOS + {0x8E46, 0xB7A5}, //2320 #HANGUL SYLLABLE RIEUL AE RIEULTHIEUTH + {0x8E47, 0xB7A6}, //2321 #HANGUL SYLLABLE RIEUL AE RIEULPHIEUPH + {0x8E48, 0xB7A7}, //2322 #HANGUL SYLLABLE RIEUL AE RIEULHIEUH + {0x8E49, 0xB7AA}, //2323 #HANGUL SYLLABLE RIEUL AE PIEUPSIOS + {0x8E4A, 0xB7AE}, //2324 #HANGUL SYLLABLE RIEUL AE CIEUC + {0x8E4B, 0xB7AF}, //2325 #HANGUL SYLLABLE RIEUL AE CHIEUCH + {0x8E4C, 0xB7B0}, //2326 #HANGUL SYLLABLE RIEUL AE KHIEUKH + {0x8E4D, 0xB7B1}, //2327 #HANGUL SYLLABLE RIEUL AE THIEUTH + {0x8E4E, 0xB7B2}, //2328 #HANGUL SYLLABLE RIEUL AE PHIEUPH + {0x8E4F, 0xB7B3}, //2329 #HANGUL SYLLABLE RIEUL AE HIEUH + {0x8E50, 0xB7B6}, //2330 #HANGUL SYLLABLE RIEUL YA SSANGKIYEOK + {0x8E51, 0xB7B7}, //2331 #HANGUL SYLLABLE RIEUL YA KIYEOKSIOS + {0x8E52, 0xB7B9}, //2332 #HANGUL SYLLABLE RIEUL YA NIEUNCIEUC + {0x8E53, 0xB7BA}, //2333 #HANGUL SYLLABLE RIEUL YA NIEUNHIEUH + {0x8E54, 0xB7BB}, //2334 #HANGUL SYLLABLE RIEUL YA TIKEUT + {0x8E55, 0xB7BC}, //2335 #HANGUL SYLLABLE RIEUL YA RIEUL + {0x8E56, 0xB7BD}, //2336 #HANGUL SYLLABLE RIEUL YA RIEULKIYEOK + {0x8E57, 0xB7BE}, //2337 #HANGUL SYLLABLE RIEUL YA RIEULMIEUM + {0x8E58, 0xB7BF}, //2338 #HANGUL SYLLABLE RIEUL YA RIEULPIEUP + {0x8E59, 0xB7C0}, //2339 #HANGUL SYLLABLE RIEUL YA RIEULSIOS + {0x8E5A, 0xB7C1}, //2340 #HANGUL SYLLABLE RIEUL YA RIEULTHIEUTH + {0x8E61, 0xB7C2}, //2341 #HANGUL SYLLABLE RIEUL YA RIEULPHIEUPH + {0x8E62, 0xB7C3}, //2342 #HANGUL SYLLABLE RIEUL YA RIEULHIEUH + {0x8E63, 0xB7C4}, //2343 #HANGUL SYLLABLE RIEUL YA MIEUM + {0x8E64, 0xB7C5}, //2344 #HANGUL SYLLABLE RIEUL YA PIEUP + {0x8E65, 0xB7C6}, //2345 #HANGUL SYLLABLE RIEUL YA PIEUPSIOS + {0x8E66, 0xB7C8}, //2346 #HANGUL SYLLABLE RIEUL YA SSANGSIOS + {0x8E67, 0xB7CA}, //2347 #HANGUL SYLLABLE RIEUL YA CIEUC + {0x8E68, 0xB7CB}, //2348 #HANGUL SYLLABLE RIEUL YA CHIEUCH + {0x8E69, 0xB7CC}, //2349 #HANGUL SYLLABLE RIEUL YA KHIEUKH + {0x8E6A, 0xB7CD}, //2350 #HANGUL SYLLABLE RIEUL YA THIEUTH + {0x8E6B, 0xB7CE}, //2351 #HANGUL SYLLABLE RIEUL YA PHIEUPH + {0x8E6C, 0xB7CF}, //2352 #HANGUL SYLLABLE RIEUL YA HIEUH + {0x8E6D, 0xB7D0}, //2353 #HANGUL SYLLABLE RIEUL YAE + {0x8E6E, 0xB7D1}, //2354 #HANGUL SYLLABLE RIEUL YAE KIYEOK + {0x8E6F, 0xB7D2}, //2355 #HANGUL SYLLABLE RIEUL YAE SSANGKIYEOK + {0x8E70, 0xB7D3}, //2356 #HANGUL SYLLABLE RIEUL YAE KIYEOKSIOS + {0x8E71, 0xB7D4}, //2357 #HANGUL SYLLABLE RIEUL YAE NIEUN + {0x8E72, 0xB7D5}, //2358 #HANGUL SYLLABLE RIEUL YAE NIEUNCIEUC + {0x8E73, 0xB7D6}, //2359 #HANGUL SYLLABLE RIEUL YAE NIEUNHIEUH + {0x8E74, 0xB7D7}, //2360 #HANGUL SYLLABLE RIEUL YAE TIKEUT + {0x8E75, 0xB7D8}, //2361 #HANGUL SYLLABLE RIEUL YAE RIEUL + {0x8E76, 0xB7D9}, //2362 #HANGUL SYLLABLE RIEUL YAE RIEULKIYEOK + {0x8E77, 0xB7DA}, //2363 #HANGUL SYLLABLE RIEUL YAE RIEULMIEUM + {0x8E78, 0xB7DB}, //2364 #HANGUL SYLLABLE RIEUL YAE RIEULPIEUP + {0x8E79, 0xB7DC}, //2365 #HANGUL SYLLABLE RIEUL YAE RIEULSIOS + {0x8E7A, 0xB7DD}, //2366 #HANGUL SYLLABLE RIEUL YAE RIEULTHIEUTH + {0x8E81, 0xB7DE}, //2367 #HANGUL SYLLABLE RIEUL YAE RIEULPHIEUPH + {0x8E82, 0xB7DF}, //2368 #HANGUL SYLLABLE RIEUL YAE RIEULHIEUH + {0x8E83, 0xB7E0}, //2369 #HANGUL SYLLABLE RIEUL YAE MIEUM + {0x8E84, 0xB7E1}, //2370 #HANGUL SYLLABLE RIEUL YAE PIEUP + {0x8E85, 0xB7E2}, //2371 #HANGUL SYLLABLE RIEUL YAE PIEUPSIOS + {0x8E86, 0xB7E3}, //2372 #HANGUL SYLLABLE RIEUL YAE SIOS + {0x8E87, 0xB7E4}, //2373 #HANGUL SYLLABLE RIEUL YAE SSANGSIOS + {0x8E88, 0xB7E5}, //2374 #HANGUL SYLLABLE RIEUL YAE IEUNG + {0x8E89, 0xB7E6}, //2375 #HANGUL SYLLABLE RIEUL YAE CIEUC + {0x8E8A, 0xB7E7}, //2376 #HANGUL SYLLABLE RIEUL YAE CHIEUCH + {0x8E8B, 0xB7E8}, //2377 #HANGUL SYLLABLE RIEUL YAE KHIEUKH + {0x8E8C, 0xB7E9}, //2378 #HANGUL SYLLABLE RIEUL YAE THIEUTH + {0x8E8D, 0xB7EA}, //2379 #HANGUL SYLLABLE RIEUL YAE PHIEUPH + {0x8E8E, 0xB7EB}, //2380 #HANGUL SYLLABLE RIEUL YAE HIEUH + {0x8E8F, 0xB7EE}, //2381 #HANGUL SYLLABLE RIEUL EO SSANGKIYEOK + {0x8E90, 0xB7EF}, //2382 #HANGUL SYLLABLE RIEUL EO KIYEOKSIOS + {0x8E91, 0xB7F1}, //2383 #HANGUL SYLLABLE RIEUL EO NIEUNCIEUC + {0x8E92, 0xB7F2}, //2384 #HANGUL SYLLABLE RIEUL EO NIEUNHIEUH + {0x8E93, 0xB7F3}, //2385 #HANGUL SYLLABLE RIEUL EO TIKEUT + {0x8E94, 0xB7F5}, //2386 #HANGUL SYLLABLE RIEUL EO RIEULKIYEOK + {0x8E95, 0xB7F6}, //2387 #HANGUL SYLLABLE RIEUL EO RIEULMIEUM + {0x8E96, 0xB7F7}, //2388 #HANGUL SYLLABLE RIEUL EO RIEULPIEUP + {0x8E97, 0xB7F8}, //2389 #HANGUL SYLLABLE RIEUL EO RIEULSIOS + {0x8E98, 0xB7F9}, //2390 #HANGUL SYLLABLE RIEUL EO RIEULTHIEUTH + {0x8E99, 0xB7FA}, //2391 #HANGUL SYLLABLE RIEUL EO RIEULPHIEUPH + {0x8E9A, 0xB7FB}, //2392 #HANGUL SYLLABLE RIEUL EO RIEULHIEUH + {0x8E9B, 0xB7FE}, //2393 #HANGUL SYLLABLE RIEUL EO PIEUPSIOS + {0x8E9C, 0xB802}, //2394 #HANGUL SYLLABLE RIEUL EO CIEUC + {0x8E9D, 0xB803}, //2395 #HANGUL SYLLABLE RIEUL EO CHIEUCH + {0x8E9E, 0xB804}, //2396 #HANGUL SYLLABLE RIEUL EO KHIEUKH + {0x8E9F, 0xB805}, //2397 #HANGUL SYLLABLE RIEUL EO THIEUTH + {0x8EA0, 0xB806}, //2398 #HANGUL SYLLABLE RIEUL EO PHIEUPH + {0x8EA1, 0xB80A}, //2399 #HANGUL SYLLABLE RIEUL E SSANGKIYEOK + {0x8EA2, 0xB80B}, //2400 #HANGUL SYLLABLE RIEUL E KIYEOKSIOS + {0x8EA3, 0xB80D}, //2401 #HANGUL SYLLABLE RIEUL E NIEUNCIEUC + {0x8EA4, 0xB80E}, //2402 #HANGUL SYLLABLE RIEUL E NIEUNHIEUH + {0x8EA5, 0xB80F}, //2403 #HANGUL SYLLABLE RIEUL E TIKEUT + {0x8EA6, 0xB811}, //2404 #HANGUL SYLLABLE RIEUL E RIEULKIYEOK + {0x8EA7, 0xB812}, //2405 #HANGUL SYLLABLE RIEUL E RIEULMIEUM + {0x8EA8, 0xB813}, //2406 #HANGUL SYLLABLE RIEUL E RIEULPIEUP + {0x8EA9, 0xB814}, //2407 #HANGUL SYLLABLE RIEUL E RIEULSIOS + {0x8EAA, 0xB815}, //2408 #HANGUL SYLLABLE RIEUL E RIEULTHIEUTH + {0x8EAB, 0xB816}, //2409 #HANGUL SYLLABLE RIEUL E RIEULPHIEUPH + {0x8EAC, 0xB817}, //2410 #HANGUL SYLLABLE RIEUL E RIEULHIEUH + {0x8EAD, 0xB81A}, //2411 #HANGUL SYLLABLE RIEUL E PIEUPSIOS + {0x8EAE, 0xB81C}, //2412 #HANGUL SYLLABLE RIEUL E SSANGSIOS + {0x8EAF, 0xB81E}, //2413 #HANGUL SYLLABLE RIEUL E CIEUC + {0x8EB0, 0xB81F}, //2414 #HANGUL SYLLABLE RIEUL E CHIEUCH + {0x8EB1, 0xB820}, //2415 #HANGUL SYLLABLE RIEUL E KHIEUKH + {0x8EB2, 0xB821}, //2416 #HANGUL SYLLABLE RIEUL E THIEUTH + {0x8EB3, 0xB822}, //2417 #HANGUL SYLLABLE RIEUL E PHIEUPH + {0x8EB4, 0xB823}, //2418 #HANGUL SYLLABLE RIEUL E HIEUH + {0x8EB5, 0xB826}, //2419 #HANGUL SYLLABLE RIEUL YEO SSANGKIYEOK + {0x8EB6, 0xB827}, //2420 #HANGUL SYLLABLE RIEUL YEO KIYEOKSIOS + {0x8EB7, 0xB829}, //2421 #HANGUL SYLLABLE RIEUL YEO NIEUNCIEUC + {0x8EB8, 0xB82A}, //2422 #HANGUL SYLLABLE RIEUL YEO NIEUNHIEUH + {0x8EB9, 0xB82B}, //2423 #HANGUL SYLLABLE RIEUL YEO TIKEUT + {0x8EBA, 0xB82D}, //2424 #HANGUL SYLLABLE RIEUL YEO RIEULKIYEOK + {0x8EBB, 0xB82E}, //2425 #HANGUL SYLLABLE RIEUL YEO RIEULMIEUM + {0x8EBC, 0xB82F}, //2426 #HANGUL SYLLABLE RIEUL YEO RIEULPIEUP + {0x8EBD, 0xB830}, //2427 #HANGUL SYLLABLE RIEUL YEO RIEULSIOS + {0x8EBE, 0xB831}, //2428 #HANGUL SYLLABLE RIEUL YEO RIEULTHIEUTH + {0x8EBF, 0xB832}, //2429 #HANGUL SYLLABLE RIEUL YEO RIEULPHIEUPH + {0x8EC0, 0xB833}, //2430 #HANGUL SYLLABLE RIEUL YEO RIEULHIEUH + {0x8EC1, 0xB836}, //2431 #HANGUL SYLLABLE RIEUL YEO PIEUPSIOS + {0x8EC2, 0xB83A}, //2432 #HANGUL SYLLABLE RIEUL YEO CIEUC + {0x8EC3, 0xB83B}, //2433 #HANGUL SYLLABLE RIEUL YEO CHIEUCH + {0x8EC4, 0xB83C}, //2434 #HANGUL SYLLABLE RIEUL YEO KHIEUKH + {0x8EC5, 0xB83D}, //2435 #HANGUL SYLLABLE RIEUL YEO THIEUTH + {0x8EC6, 0xB83E}, //2436 #HANGUL SYLLABLE RIEUL YEO PHIEUPH + {0x8EC7, 0xB83F}, //2437 #HANGUL SYLLABLE RIEUL YEO HIEUH + {0x8EC8, 0xB841}, //2438 #HANGUL SYLLABLE RIEUL YE KIYEOK + {0x8EC9, 0xB842}, //2439 #HANGUL SYLLABLE RIEUL YE SSANGKIYEOK + {0x8ECA, 0xB843}, //2440 #HANGUL SYLLABLE RIEUL YE KIYEOKSIOS + {0x8ECB, 0xB845}, //2441 #HANGUL SYLLABLE RIEUL YE NIEUNCIEUC + {0x8ECC, 0xB846}, //2442 #HANGUL SYLLABLE RIEUL YE NIEUNHIEUH + {0x8ECD, 0xB847}, //2443 #HANGUL SYLLABLE RIEUL YE TIKEUT + {0x8ECE, 0xB848}, //2444 #HANGUL SYLLABLE RIEUL YE RIEUL + {0x8ECF, 0xB849}, //2445 #HANGUL SYLLABLE RIEUL YE RIEULKIYEOK + {0x8ED0, 0xB84A}, //2446 #HANGUL SYLLABLE RIEUL YE RIEULMIEUM + {0x8ED1, 0xB84B}, //2447 #HANGUL SYLLABLE RIEUL YE RIEULPIEUP + {0x8ED2, 0xB84C}, //2448 #HANGUL SYLLABLE RIEUL YE RIEULSIOS + {0x8ED3, 0xB84D}, //2449 #HANGUL SYLLABLE RIEUL YE RIEULTHIEUTH + {0x8ED4, 0xB84E}, //2450 #HANGUL SYLLABLE RIEUL YE RIEULPHIEUPH + {0x8ED5, 0xB84F}, //2451 #HANGUL SYLLABLE RIEUL YE RIEULHIEUH + {0x8ED6, 0xB850}, //2452 #HANGUL SYLLABLE RIEUL YE MIEUM + {0x8ED7, 0xB852}, //2453 #HANGUL SYLLABLE RIEUL YE PIEUPSIOS + {0x8ED8, 0xB854}, //2454 #HANGUL SYLLABLE RIEUL YE SSANGSIOS + {0x8ED9, 0xB855}, //2455 #HANGUL SYLLABLE RIEUL YE IEUNG + {0x8EDA, 0xB856}, //2456 #HANGUL SYLLABLE RIEUL YE CIEUC + {0x8EDB, 0xB857}, //2457 #HANGUL SYLLABLE RIEUL YE CHIEUCH + {0x8EDC, 0xB858}, //2458 #HANGUL SYLLABLE RIEUL YE KHIEUKH + {0x8EDD, 0xB859}, //2459 #HANGUL SYLLABLE RIEUL YE THIEUTH + {0x8EDE, 0xB85A}, //2460 #HANGUL SYLLABLE RIEUL YE PHIEUPH + {0x8EDF, 0xB85B}, //2461 #HANGUL SYLLABLE RIEUL YE HIEUH + {0x8EE0, 0xB85E}, //2462 #HANGUL SYLLABLE RIEUL O SSANGKIYEOK + {0x8EE1, 0xB85F}, //2463 #HANGUL SYLLABLE RIEUL O KIYEOKSIOS + {0x8EE2, 0xB861}, //2464 #HANGUL SYLLABLE RIEUL O NIEUNCIEUC + {0x8EE3, 0xB862}, //2465 #HANGUL SYLLABLE RIEUL O NIEUNHIEUH + {0x8EE4, 0xB863}, //2466 #HANGUL SYLLABLE RIEUL O TIKEUT + {0x8EE5, 0xB865}, //2467 #HANGUL SYLLABLE RIEUL O RIEULKIYEOK + {0x8EE6, 0xB866}, //2468 #HANGUL SYLLABLE RIEUL O RIEULMIEUM + {0x8EE7, 0xB867}, //2469 #HANGUL SYLLABLE RIEUL O RIEULPIEUP + {0x8EE8, 0xB868}, //2470 #HANGUL SYLLABLE RIEUL O RIEULSIOS + {0x8EE9, 0xB869}, //2471 #HANGUL SYLLABLE RIEUL O RIEULTHIEUTH + {0x8EEA, 0xB86A}, //2472 #HANGUL SYLLABLE RIEUL O RIEULPHIEUPH + {0x8EEB, 0xB86B}, //2473 #HANGUL SYLLABLE RIEUL O RIEULHIEUH + {0x8EEC, 0xB86E}, //2474 #HANGUL SYLLABLE RIEUL O PIEUPSIOS + {0x8EED, 0xB870}, //2475 #HANGUL SYLLABLE RIEUL O SSANGSIOS + {0x8EEE, 0xB872}, //2476 #HANGUL SYLLABLE RIEUL O CIEUC + {0x8EEF, 0xB873}, //2477 #HANGUL SYLLABLE RIEUL O CHIEUCH + {0x8EF0, 0xB874}, //2478 #HANGUL SYLLABLE RIEUL O KHIEUKH + {0x8EF1, 0xB875}, //2479 #HANGUL SYLLABLE RIEUL O THIEUTH + {0x8EF2, 0xB876}, //2480 #HANGUL SYLLABLE RIEUL O PHIEUPH + {0x8EF3, 0xB877}, //2481 #HANGUL SYLLABLE RIEUL O HIEUH + {0x8EF4, 0xB879}, //2482 #HANGUL SYLLABLE RIEUL WA KIYEOK + {0x8EF5, 0xB87A}, //2483 #HANGUL SYLLABLE RIEUL WA SSANGKIYEOK + {0x8EF6, 0xB87B}, //2484 #HANGUL SYLLABLE RIEUL WA KIYEOKSIOS + {0x8EF7, 0xB87D}, //2485 #HANGUL SYLLABLE RIEUL WA NIEUNCIEUC + {0x8EF8, 0xB87E}, //2486 #HANGUL SYLLABLE RIEUL WA NIEUNHIEUH + {0x8EF9, 0xB87F}, //2487 #HANGUL SYLLABLE RIEUL WA TIKEUT + {0x8EFA, 0xB880}, //2488 #HANGUL SYLLABLE RIEUL WA RIEUL + {0x8EFB, 0xB881}, //2489 #HANGUL SYLLABLE RIEUL WA RIEULKIYEOK + {0x8EFC, 0xB882}, //2490 #HANGUL SYLLABLE RIEUL WA RIEULMIEUM + {0x8EFD, 0xB883}, //2491 #HANGUL SYLLABLE RIEUL WA RIEULPIEUP + {0x8EFE, 0xB884}, //2492 #HANGUL SYLLABLE RIEUL WA RIEULSIOS + {0x8F41, 0xB885}, //2493 #HANGUL SYLLABLE RIEUL WA RIEULTHIEUTH + {0x8F42, 0xB886}, //2494 #HANGUL SYLLABLE RIEUL WA RIEULPHIEUPH + {0x8F43, 0xB887}, //2495 #HANGUL SYLLABLE RIEUL WA RIEULHIEUH + {0x8F44, 0xB888}, //2496 #HANGUL SYLLABLE RIEUL WA MIEUM + {0x8F45, 0xB889}, //2497 #HANGUL SYLLABLE RIEUL WA PIEUP + {0x8F46, 0xB88A}, //2498 #HANGUL SYLLABLE RIEUL WA PIEUPSIOS + {0x8F47, 0xB88B}, //2499 #HANGUL SYLLABLE RIEUL WA SIOS + {0x8F48, 0xB88C}, //2500 #HANGUL SYLLABLE RIEUL WA SSANGSIOS + {0x8F49, 0xB88E}, //2501 #HANGUL SYLLABLE RIEUL WA CIEUC + {0x8F4A, 0xB88F}, //2502 #HANGUL SYLLABLE RIEUL WA CHIEUCH + {0x8F4B, 0xB890}, //2503 #HANGUL SYLLABLE RIEUL WA KHIEUKH + {0x8F4C, 0xB891}, //2504 #HANGUL SYLLABLE RIEUL WA THIEUTH + {0x8F4D, 0xB892}, //2505 #HANGUL SYLLABLE RIEUL WA PHIEUPH + {0x8F4E, 0xB893}, //2506 #HANGUL SYLLABLE RIEUL WA HIEUH + {0x8F4F, 0xB894}, //2507 #HANGUL SYLLABLE RIEUL WAE + {0x8F50, 0xB895}, //2508 #HANGUL SYLLABLE RIEUL WAE KIYEOK + {0x8F51, 0xB896}, //2509 #HANGUL SYLLABLE RIEUL WAE SSANGKIYEOK + {0x8F52, 0xB897}, //2510 #HANGUL SYLLABLE RIEUL WAE KIYEOKSIOS + {0x8F53, 0xB898}, //2511 #HANGUL SYLLABLE RIEUL WAE NIEUN + {0x8F54, 0xB899}, //2512 #HANGUL SYLLABLE RIEUL WAE NIEUNCIEUC + {0x8F55, 0xB89A}, //2513 #HANGUL SYLLABLE RIEUL WAE NIEUNHIEUH + {0x8F56, 0xB89B}, //2514 #HANGUL SYLLABLE RIEUL WAE TIKEUT + {0x8F57, 0xB89C}, //2515 #HANGUL SYLLABLE RIEUL WAE RIEUL + {0x8F58, 0xB89D}, //2516 #HANGUL SYLLABLE RIEUL WAE RIEULKIYEOK + {0x8F59, 0xB89E}, //2517 #HANGUL SYLLABLE RIEUL WAE RIEULMIEUM + {0x8F5A, 0xB89F}, //2518 #HANGUL SYLLABLE RIEUL WAE RIEULPIEUP + {0x8F61, 0xB8A0}, //2519 #HANGUL SYLLABLE RIEUL WAE RIEULSIOS + {0x8F62, 0xB8A1}, //2520 #HANGUL SYLLABLE RIEUL WAE RIEULTHIEUTH + {0x8F63, 0xB8A2}, //2521 #HANGUL SYLLABLE RIEUL WAE RIEULPHIEUPH + {0x8F64, 0xB8A3}, //2522 #HANGUL SYLLABLE RIEUL WAE RIEULHIEUH + {0x8F65, 0xB8A4}, //2523 #HANGUL SYLLABLE RIEUL WAE MIEUM + {0x8F66, 0xB8A5}, //2524 #HANGUL SYLLABLE RIEUL WAE PIEUP + {0x8F67, 0xB8A6}, //2525 #HANGUL SYLLABLE RIEUL WAE PIEUPSIOS + {0x8F68, 0xB8A7}, //2526 #HANGUL SYLLABLE RIEUL WAE SIOS + {0x8F69, 0xB8A9}, //2527 #HANGUL SYLLABLE RIEUL WAE IEUNG + {0x8F6A, 0xB8AA}, //2528 #HANGUL SYLLABLE RIEUL WAE CIEUC + {0x8F6B, 0xB8AB}, //2529 #HANGUL SYLLABLE RIEUL WAE CHIEUCH + {0x8F6C, 0xB8AC}, //2530 #HANGUL SYLLABLE RIEUL WAE KHIEUKH + {0x8F6D, 0xB8AD}, //2531 #HANGUL SYLLABLE RIEUL WAE THIEUTH + {0x8F6E, 0xB8AE}, //2532 #HANGUL SYLLABLE RIEUL WAE PHIEUPH + {0x8F6F, 0xB8AF}, //2533 #HANGUL SYLLABLE RIEUL WAE HIEUH + {0x8F70, 0xB8B1}, //2534 #HANGUL SYLLABLE RIEUL OE KIYEOK + {0x8F71, 0xB8B2}, //2535 #HANGUL SYLLABLE RIEUL OE SSANGKIYEOK + {0x8F72, 0xB8B3}, //2536 #HANGUL SYLLABLE RIEUL OE KIYEOKSIOS + {0x8F73, 0xB8B5}, //2537 #HANGUL SYLLABLE RIEUL OE NIEUNCIEUC + {0x8F74, 0xB8B6}, //2538 #HANGUL SYLLABLE RIEUL OE NIEUNHIEUH + {0x8F75, 0xB8B7}, //2539 #HANGUL SYLLABLE RIEUL OE TIKEUT + {0x8F76, 0xB8B9}, //2540 #HANGUL SYLLABLE RIEUL OE RIEULKIYEOK + {0x8F77, 0xB8BA}, //2541 #HANGUL SYLLABLE RIEUL OE RIEULMIEUM + {0x8F78, 0xB8BB}, //2542 #HANGUL SYLLABLE RIEUL OE RIEULPIEUP + {0x8F79, 0xB8BC}, //2543 #HANGUL SYLLABLE RIEUL OE RIEULSIOS + {0x8F7A, 0xB8BD}, //2544 #HANGUL SYLLABLE RIEUL OE RIEULTHIEUTH + {0x8F81, 0xB8BE}, //2545 #HANGUL SYLLABLE RIEUL OE RIEULPHIEUPH + {0x8F82, 0xB8BF}, //2546 #HANGUL SYLLABLE RIEUL OE RIEULHIEUH + {0x8F83, 0xB8C2}, //2547 #HANGUL SYLLABLE RIEUL OE PIEUPSIOS + {0x8F84, 0xB8C4}, //2548 #HANGUL SYLLABLE RIEUL OE SSANGSIOS + {0x8F85, 0xB8C6}, //2549 #HANGUL SYLLABLE RIEUL OE CIEUC + {0x8F86, 0xB8C7}, //2550 #HANGUL SYLLABLE RIEUL OE CHIEUCH + {0x8F87, 0xB8C8}, //2551 #HANGUL SYLLABLE RIEUL OE KHIEUKH + {0x8F88, 0xB8C9}, //2552 #HANGUL SYLLABLE RIEUL OE THIEUTH + {0x8F89, 0xB8CA}, //2553 #HANGUL SYLLABLE RIEUL OE PHIEUPH + {0x8F8A, 0xB8CB}, //2554 #HANGUL SYLLABLE RIEUL OE HIEUH + {0x8F8B, 0xB8CD}, //2555 #HANGUL SYLLABLE RIEUL YO KIYEOK + {0x8F8C, 0xB8CE}, //2556 #HANGUL SYLLABLE RIEUL YO SSANGKIYEOK + {0x8F8D, 0xB8CF}, //2557 #HANGUL SYLLABLE RIEUL YO KIYEOKSIOS + {0x8F8E, 0xB8D1}, //2558 #HANGUL SYLLABLE RIEUL YO NIEUNCIEUC + {0x8F8F, 0xB8D2}, //2559 #HANGUL SYLLABLE RIEUL YO NIEUNHIEUH + {0x8F90, 0xB8D3}, //2560 #HANGUL SYLLABLE RIEUL YO TIKEUT + {0x8F91, 0xB8D5}, //2561 #HANGUL SYLLABLE RIEUL YO RIEULKIYEOK + {0x8F92, 0xB8D6}, //2562 #HANGUL SYLLABLE RIEUL YO RIEULMIEUM + {0x8F93, 0xB8D7}, //2563 #HANGUL SYLLABLE RIEUL YO RIEULPIEUP + {0x8F94, 0xB8D8}, //2564 #HANGUL SYLLABLE RIEUL YO RIEULSIOS + {0x8F95, 0xB8D9}, //2565 #HANGUL SYLLABLE RIEUL YO RIEULTHIEUTH + {0x8F96, 0xB8DA}, //2566 #HANGUL SYLLABLE RIEUL YO RIEULPHIEUPH + {0x8F97, 0xB8DB}, //2567 #HANGUL SYLLABLE RIEUL YO RIEULHIEUH + {0x8F98, 0xB8DC}, //2568 #HANGUL SYLLABLE RIEUL YO MIEUM + {0x8F99, 0xB8DE}, //2569 #HANGUL SYLLABLE RIEUL YO PIEUPSIOS + {0x8F9A, 0xB8E0}, //2570 #HANGUL SYLLABLE RIEUL YO SSANGSIOS + {0x8F9B, 0xB8E2}, //2571 #HANGUL SYLLABLE RIEUL YO CIEUC + {0x8F9C, 0xB8E3}, //2572 #HANGUL SYLLABLE RIEUL YO CHIEUCH + {0x8F9D, 0xB8E4}, //2573 #HANGUL SYLLABLE RIEUL YO KHIEUKH + {0x8F9E, 0xB8E5}, //2574 #HANGUL SYLLABLE RIEUL YO THIEUTH + {0x8F9F, 0xB8E6}, //2575 #HANGUL SYLLABLE RIEUL YO PHIEUPH + {0x8FA0, 0xB8E7}, //2576 #HANGUL SYLLABLE RIEUL YO HIEUH + {0x8FA1, 0xB8EA}, //2577 #HANGUL SYLLABLE RIEUL U SSANGKIYEOK + {0x8FA2, 0xB8EB}, //2578 #HANGUL SYLLABLE RIEUL U KIYEOKSIOS + {0x8FA3, 0xB8ED}, //2579 #HANGUL SYLLABLE RIEUL U NIEUNCIEUC + {0x8FA4, 0xB8EE}, //2580 #HANGUL SYLLABLE RIEUL U NIEUNHIEUH + {0x8FA5, 0xB8EF}, //2581 #HANGUL SYLLABLE RIEUL U TIKEUT + {0x8FA6, 0xB8F1}, //2582 #HANGUL SYLLABLE RIEUL U RIEULKIYEOK + {0x8FA7, 0xB8F2}, //2583 #HANGUL SYLLABLE RIEUL U RIEULMIEUM + {0x8FA8, 0xB8F3}, //2584 #HANGUL SYLLABLE RIEUL U RIEULPIEUP + {0x8FA9, 0xB8F4}, //2585 #HANGUL SYLLABLE RIEUL U RIEULSIOS + {0x8FAA, 0xB8F5}, //2586 #HANGUL SYLLABLE RIEUL U RIEULTHIEUTH + {0x8FAB, 0xB8F6}, //2587 #HANGUL SYLLABLE RIEUL U RIEULPHIEUPH + {0x8FAC, 0xB8F7}, //2588 #HANGUL SYLLABLE RIEUL U RIEULHIEUH + {0x8FAD, 0xB8FA}, //2589 #HANGUL SYLLABLE RIEUL U PIEUPSIOS + {0x8FAE, 0xB8FC}, //2590 #HANGUL SYLLABLE RIEUL U SSANGSIOS + {0x8FAF, 0xB8FE}, //2591 #HANGUL SYLLABLE RIEUL U CIEUC + {0x8FB0, 0xB8FF}, //2592 #HANGUL SYLLABLE RIEUL U CHIEUCH + {0x8FB1, 0xB900}, //2593 #HANGUL SYLLABLE RIEUL U KHIEUKH + {0x8FB2, 0xB901}, //2594 #HANGUL SYLLABLE RIEUL U THIEUTH + {0x8FB3, 0xB902}, //2595 #HANGUL SYLLABLE RIEUL U PHIEUPH + {0x8FB4, 0xB903}, //2596 #HANGUL SYLLABLE RIEUL U HIEUH + {0x8FB5, 0xB905}, //2597 #HANGUL SYLLABLE RIEUL WEO KIYEOK + {0x8FB6, 0xB906}, //2598 #HANGUL SYLLABLE RIEUL WEO SSANGKIYEOK + {0x8FB7, 0xB907}, //2599 #HANGUL SYLLABLE RIEUL WEO KIYEOKSIOS + {0x8FB8, 0xB908}, //2600 #HANGUL SYLLABLE RIEUL WEO NIEUN + {0x8FB9, 0xB909}, //2601 #HANGUL SYLLABLE RIEUL WEO NIEUNCIEUC + {0x8FBA, 0xB90A}, //2602 #HANGUL SYLLABLE RIEUL WEO NIEUNHIEUH + {0x8FBB, 0xB90B}, //2603 #HANGUL SYLLABLE RIEUL WEO TIKEUT + {0x8FBC, 0xB90C}, //2604 #HANGUL SYLLABLE RIEUL WEO RIEUL + {0x8FBD, 0xB90D}, //2605 #HANGUL SYLLABLE RIEUL WEO RIEULKIYEOK + {0x8FBE, 0xB90E}, //2606 #HANGUL SYLLABLE RIEUL WEO RIEULMIEUM + {0x8FBF, 0xB90F}, //2607 #HANGUL SYLLABLE RIEUL WEO RIEULPIEUP + {0x8FC0, 0xB910}, //2608 #HANGUL SYLLABLE RIEUL WEO RIEULSIOS + {0x8FC1, 0xB911}, //2609 #HANGUL SYLLABLE RIEUL WEO RIEULTHIEUTH + {0x8FC2, 0xB912}, //2610 #HANGUL SYLLABLE RIEUL WEO RIEULPHIEUPH + {0x8FC3, 0xB913}, //2611 #HANGUL SYLLABLE RIEUL WEO RIEULHIEUH + {0x8FC4, 0xB914}, //2612 #HANGUL SYLLABLE RIEUL WEO MIEUM + {0x8FC5, 0xB915}, //2613 #HANGUL SYLLABLE RIEUL WEO PIEUP + {0x8FC6, 0xB916}, //2614 #HANGUL SYLLABLE RIEUL WEO PIEUPSIOS + {0x8FC7, 0xB917}, //2615 #HANGUL SYLLABLE RIEUL WEO SIOS + {0x8FC8, 0xB919}, //2616 #HANGUL SYLLABLE RIEUL WEO IEUNG + {0x8FC9, 0xB91A}, //2617 #HANGUL SYLLABLE RIEUL WEO CIEUC + {0x8FCA, 0xB91B}, //2618 #HANGUL SYLLABLE RIEUL WEO CHIEUCH + {0x8FCB, 0xB91C}, //2619 #HANGUL SYLLABLE RIEUL WEO KHIEUKH + {0x8FCC, 0xB91D}, //2620 #HANGUL SYLLABLE RIEUL WEO THIEUTH + {0x8FCD, 0xB91E}, //2621 #HANGUL SYLLABLE RIEUL WEO PHIEUPH + {0x8FCE, 0xB91F}, //2622 #HANGUL SYLLABLE RIEUL WEO HIEUH + {0x8FCF, 0xB921}, //2623 #HANGUL SYLLABLE RIEUL WE KIYEOK + {0x8FD0, 0xB922}, //2624 #HANGUL SYLLABLE RIEUL WE SSANGKIYEOK + {0x8FD1, 0xB923}, //2625 #HANGUL SYLLABLE RIEUL WE KIYEOKSIOS + {0x8FD2, 0xB924}, //2626 #HANGUL SYLLABLE RIEUL WE NIEUN + {0x8FD3, 0xB925}, //2627 #HANGUL SYLLABLE RIEUL WE NIEUNCIEUC + {0x8FD4, 0xB926}, //2628 #HANGUL SYLLABLE RIEUL WE NIEUNHIEUH + {0x8FD5, 0xB927}, //2629 #HANGUL SYLLABLE RIEUL WE TIKEUT + {0x8FD6, 0xB928}, //2630 #HANGUL SYLLABLE RIEUL WE RIEUL + {0x8FD7, 0xB929}, //2631 #HANGUL SYLLABLE RIEUL WE RIEULKIYEOK + {0x8FD8, 0xB92A}, //2632 #HANGUL SYLLABLE RIEUL WE RIEULMIEUM + {0x8FD9, 0xB92B}, //2633 #HANGUL SYLLABLE RIEUL WE RIEULPIEUP + {0x8FDA, 0xB92C}, //2634 #HANGUL SYLLABLE RIEUL WE RIEULSIOS + {0x8FDB, 0xB92D}, //2635 #HANGUL SYLLABLE RIEUL WE RIEULTHIEUTH + {0x8FDC, 0xB92E}, //2636 #HANGUL SYLLABLE RIEUL WE RIEULPHIEUPH + {0x8FDD, 0xB92F}, //2637 #HANGUL SYLLABLE RIEUL WE RIEULHIEUH + {0x8FDE, 0xB930}, //2638 #HANGUL SYLLABLE RIEUL WE MIEUM + {0x8FDF, 0xB931}, //2639 #HANGUL SYLLABLE RIEUL WE PIEUP + {0x8FE0, 0xB932}, //2640 #HANGUL SYLLABLE RIEUL WE PIEUPSIOS + {0x8FE1, 0xB933}, //2641 #HANGUL SYLLABLE RIEUL WE SIOS + {0x8FE2, 0xB934}, //2642 #HANGUL SYLLABLE RIEUL WE SSANGSIOS + {0x8FE3, 0xB935}, //2643 #HANGUL SYLLABLE RIEUL WE IEUNG + {0x8FE4, 0xB936}, //2644 #HANGUL SYLLABLE RIEUL WE CIEUC + {0x8FE5, 0xB937}, //2645 #HANGUL SYLLABLE RIEUL WE CHIEUCH + {0x8FE6, 0xB938}, //2646 #HANGUL SYLLABLE RIEUL WE KHIEUKH + {0x8FE7, 0xB939}, //2647 #HANGUL SYLLABLE RIEUL WE THIEUTH + {0x8FE8, 0xB93A}, //2648 #HANGUL SYLLABLE RIEUL WE PHIEUPH + {0x8FE9, 0xB93B}, //2649 #HANGUL SYLLABLE RIEUL WE HIEUH + {0x8FEA, 0xB93E}, //2650 #HANGUL SYLLABLE RIEUL WI SSANGKIYEOK + {0x8FEB, 0xB93F}, //2651 #HANGUL SYLLABLE RIEUL WI KIYEOKSIOS + {0x8FEC, 0xB941}, //2652 #HANGUL SYLLABLE RIEUL WI NIEUNCIEUC + {0x8FED, 0xB942}, //2653 #HANGUL SYLLABLE RIEUL WI NIEUNHIEUH + {0x8FEE, 0xB943}, //2654 #HANGUL SYLLABLE RIEUL WI TIKEUT + {0x8FEF, 0xB945}, //2655 #HANGUL SYLLABLE RIEUL WI RIEULKIYEOK + {0x8FF0, 0xB946}, //2656 #HANGUL SYLLABLE RIEUL WI RIEULMIEUM + {0x8FF1, 0xB947}, //2657 #HANGUL SYLLABLE RIEUL WI RIEULPIEUP + {0x8FF2, 0xB948}, //2658 #HANGUL SYLLABLE RIEUL WI RIEULSIOS + {0x8FF3, 0xB949}, //2659 #HANGUL SYLLABLE RIEUL WI RIEULTHIEUTH + {0x8FF4, 0xB94A}, //2660 #HANGUL SYLLABLE RIEUL WI RIEULPHIEUPH + {0x8FF5, 0xB94B}, //2661 #HANGUL SYLLABLE RIEUL WI RIEULHIEUH + {0x8FF6, 0xB94D}, //2662 #HANGUL SYLLABLE RIEUL WI PIEUP + {0x8FF7, 0xB94E}, //2663 #HANGUL SYLLABLE RIEUL WI PIEUPSIOS + {0x8FF8, 0xB950}, //2664 #HANGUL SYLLABLE RIEUL WI SSANGSIOS + {0x8FF9, 0xB952}, //2665 #HANGUL SYLLABLE RIEUL WI CIEUC + {0x8FFA, 0xB953}, //2666 #HANGUL SYLLABLE RIEUL WI CHIEUCH + {0x8FFB, 0xB954}, //2667 #HANGUL SYLLABLE RIEUL WI KHIEUKH + {0x8FFC, 0xB955}, //2668 #HANGUL SYLLABLE RIEUL WI THIEUTH + {0x8FFD, 0xB956}, //2669 #HANGUL SYLLABLE RIEUL WI PHIEUPH + {0x8FFE, 0xB957}, //2670 #HANGUL SYLLABLE RIEUL WI HIEUH + {0x9041, 0xB95A}, //2671 #HANGUL SYLLABLE RIEUL YU SSANGKIYEOK + {0x9042, 0xB95B}, //2672 #HANGUL SYLLABLE RIEUL YU KIYEOKSIOS + {0x9043, 0xB95D}, //2673 #HANGUL SYLLABLE RIEUL YU NIEUNCIEUC + {0x9044, 0xB95E}, //2674 #HANGUL SYLLABLE RIEUL YU NIEUNHIEUH + {0x9045, 0xB95F}, //2675 #HANGUL SYLLABLE RIEUL YU TIKEUT + {0x9046, 0xB961}, //2676 #HANGUL SYLLABLE RIEUL YU RIEULKIYEOK + {0x9047, 0xB962}, //2677 #HANGUL SYLLABLE RIEUL YU RIEULMIEUM + {0x9048, 0xB963}, //2678 #HANGUL SYLLABLE RIEUL YU RIEULPIEUP + {0x9049, 0xB964}, //2679 #HANGUL SYLLABLE RIEUL YU RIEULSIOS + {0x904A, 0xB965}, //2680 #HANGUL SYLLABLE RIEUL YU RIEULTHIEUTH + {0x904B, 0xB966}, //2681 #HANGUL SYLLABLE RIEUL YU RIEULPHIEUPH + {0x904C, 0xB967}, //2682 #HANGUL SYLLABLE RIEUL YU RIEULHIEUH + {0x904D, 0xB96A}, //2683 #HANGUL SYLLABLE RIEUL YU PIEUPSIOS + {0x904E, 0xB96C}, //2684 #HANGUL SYLLABLE RIEUL YU SSANGSIOS + {0x904F, 0xB96E}, //2685 #HANGUL SYLLABLE RIEUL YU CIEUC + {0x9050, 0xB96F}, //2686 #HANGUL SYLLABLE RIEUL YU CHIEUCH + {0x9051, 0xB970}, //2687 #HANGUL SYLLABLE RIEUL YU KHIEUKH + {0x9052, 0xB971}, //2688 #HANGUL SYLLABLE RIEUL YU THIEUTH + {0x9053, 0xB972}, //2689 #HANGUL SYLLABLE RIEUL YU PHIEUPH + {0x9054, 0xB973}, //2690 #HANGUL SYLLABLE RIEUL YU HIEUH + {0x9055, 0xB976}, //2691 #HANGUL SYLLABLE RIEUL EU SSANGKIYEOK + {0x9056, 0xB977}, //2692 #HANGUL SYLLABLE RIEUL EU KIYEOKSIOS + {0x9057, 0xB979}, //2693 #HANGUL SYLLABLE RIEUL EU NIEUNCIEUC + {0x9058, 0xB97A}, //2694 #HANGUL SYLLABLE RIEUL EU NIEUNHIEUH + {0x9059, 0xB97B}, //2695 #HANGUL SYLLABLE RIEUL EU TIKEUT + {0x905A, 0xB97D}, //2696 #HANGUL SYLLABLE RIEUL EU RIEULKIYEOK + {0x9061, 0xB97E}, //2697 #HANGUL SYLLABLE RIEUL EU RIEULMIEUM + {0x9062, 0xB97F}, //2698 #HANGUL SYLLABLE RIEUL EU RIEULPIEUP + {0x9063, 0xB980}, //2699 #HANGUL SYLLABLE RIEUL EU RIEULSIOS + {0x9064, 0xB981}, //2700 #HANGUL SYLLABLE RIEUL EU RIEULTHIEUTH + {0x9065, 0xB982}, //2701 #HANGUL SYLLABLE RIEUL EU RIEULPHIEUPH + {0x9066, 0xB983}, //2702 #HANGUL SYLLABLE RIEUL EU RIEULHIEUH + {0x9067, 0xB986}, //2703 #HANGUL SYLLABLE RIEUL EU PIEUPSIOS + {0x9068, 0xB988}, //2704 #HANGUL SYLLABLE RIEUL EU SSANGSIOS + {0x9069, 0xB98B}, //2705 #HANGUL SYLLABLE RIEUL EU CHIEUCH + {0x906A, 0xB98C}, //2706 #HANGUL SYLLABLE RIEUL EU KHIEUKH + {0x906B, 0xB98F}, //2707 #HANGUL SYLLABLE RIEUL EU HIEUH + {0x906C, 0xB990}, //2708 #HANGUL SYLLABLE RIEUL YI + {0x906D, 0xB991}, //2709 #HANGUL SYLLABLE RIEUL YI KIYEOK + {0x906E, 0xB992}, //2710 #HANGUL SYLLABLE RIEUL YI SSANGKIYEOK + {0x906F, 0xB993}, //2711 #HANGUL SYLLABLE RIEUL YI KIYEOKSIOS + {0x9070, 0xB994}, //2712 #HANGUL SYLLABLE RIEUL YI NIEUN + {0x9071, 0xB995}, //2713 #HANGUL SYLLABLE RIEUL YI NIEUNCIEUC + {0x9072, 0xB996}, //2714 #HANGUL SYLLABLE RIEUL YI NIEUNHIEUH + {0x9073, 0xB997}, //2715 #HANGUL SYLLABLE RIEUL YI TIKEUT + {0x9074, 0xB998}, //2716 #HANGUL SYLLABLE RIEUL YI RIEUL + {0x9075, 0xB999}, //2717 #HANGUL SYLLABLE RIEUL YI RIEULKIYEOK + {0x9076, 0xB99A}, //2718 #HANGUL SYLLABLE RIEUL YI RIEULMIEUM + {0x9077, 0xB99B}, //2719 #HANGUL SYLLABLE RIEUL YI RIEULPIEUP + {0x9078, 0xB99C}, //2720 #HANGUL SYLLABLE RIEUL YI RIEULSIOS + {0x9079, 0xB99D}, //2721 #HANGUL SYLLABLE RIEUL YI RIEULTHIEUTH + {0x907A, 0xB99E}, //2722 #HANGUL SYLLABLE RIEUL YI RIEULPHIEUPH + {0x9081, 0xB99F}, //2723 #HANGUL SYLLABLE RIEUL YI RIEULHIEUH + {0x9082, 0xB9A0}, //2724 #HANGUL SYLLABLE RIEUL YI MIEUM + {0x9083, 0xB9A1}, //2725 #HANGUL SYLLABLE RIEUL YI PIEUP + {0x9084, 0xB9A2}, //2726 #HANGUL SYLLABLE RIEUL YI PIEUPSIOS + {0x9085, 0xB9A3}, //2727 #HANGUL SYLLABLE RIEUL YI SIOS + {0x9086, 0xB9A4}, //2728 #HANGUL SYLLABLE RIEUL YI SSANGSIOS + {0x9087, 0xB9A5}, //2729 #HANGUL SYLLABLE RIEUL YI IEUNG + {0x9088, 0xB9A6}, //2730 #HANGUL SYLLABLE RIEUL YI CIEUC + {0x9089, 0xB9A7}, //2731 #HANGUL SYLLABLE RIEUL YI CHIEUCH + {0x908A, 0xB9A8}, //2732 #HANGUL SYLLABLE RIEUL YI KHIEUKH + {0x908B, 0xB9A9}, //2733 #HANGUL SYLLABLE RIEUL YI THIEUTH + {0x908C, 0xB9AA}, //2734 #HANGUL SYLLABLE RIEUL YI PHIEUPH + {0x908D, 0xB9AB}, //2735 #HANGUL SYLLABLE RIEUL YI HIEUH + {0x908E, 0xB9AE}, //2736 #HANGUL SYLLABLE RIEUL I SSANGKIYEOK + {0x908F, 0xB9AF}, //2737 #HANGUL SYLLABLE RIEUL I KIYEOKSIOS + {0x9090, 0xB9B1}, //2738 #HANGUL SYLLABLE RIEUL I NIEUNCIEUC + {0x9091, 0xB9B2}, //2739 #HANGUL SYLLABLE RIEUL I NIEUNHIEUH + {0x9092, 0xB9B3}, //2740 #HANGUL SYLLABLE RIEUL I TIKEUT + {0x9093, 0xB9B5}, //2741 #HANGUL SYLLABLE RIEUL I RIEULKIYEOK + {0x9094, 0xB9B6}, //2742 #HANGUL SYLLABLE RIEUL I RIEULMIEUM + {0x9095, 0xB9B7}, //2743 #HANGUL SYLLABLE RIEUL I RIEULPIEUP + {0x9096, 0xB9B8}, //2744 #HANGUL SYLLABLE RIEUL I RIEULSIOS + {0x9097, 0xB9B9}, //2745 #HANGUL SYLLABLE RIEUL I RIEULTHIEUTH + {0x9098, 0xB9BA}, //2746 #HANGUL SYLLABLE RIEUL I RIEULPHIEUPH + {0x9099, 0xB9BB}, //2747 #HANGUL SYLLABLE RIEUL I RIEULHIEUH + {0x909A, 0xB9BE}, //2748 #HANGUL SYLLABLE RIEUL I PIEUPSIOS + {0x909B, 0xB9C0}, //2749 #HANGUL SYLLABLE RIEUL I SSANGSIOS + {0x909C, 0xB9C2}, //2750 #HANGUL SYLLABLE RIEUL I CIEUC + {0x909D, 0xB9C3}, //2751 #HANGUL SYLLABLE RIEUL I CHIEUCH + {0x909E, 0xB9C4}, //2752 #HANGUL SYLLABLE RIEUL I KHIEUKH + {0x909F, 0xB9C5}, //2753 #HANGUL SYLLABLE RIEUL I THIEUTH + {0x90A0, 0xB9C6}, //2754 #HANGUL SYLLABLE RIEUL I PHIEUPH + {0x90A1, 0xB9C7}, //2755 #HANGUL SYLLABLE RIEUL I HIEUH + {0x90A2, 0xB9CA}, //2756 #HANGUL SYLLABLE MIEUM A SSANGKIYEOK + {0x90A3, 0xB9CB}, //2757 #HANGUL SYLLABLE MIEUM A KIYEOKSIOS + {0x90A4, 0xB9CD}, //2758 #HANGUL SYLLABLE MIEUM A NIEUNCIEUC + {0x90A5, 0xB9D3}, //2759 #HANGUL SYLLABLE MIEUM A RIEULPIEUP + {0x90A6, 0xB9D4}, //2760 #HANGUL SYLLABLE MIEUM A RIEULSIOS + {0x90A7, 0xB9D5}, //2761 #HANGUL SYLLABLE MIEUM A RIEULTHIEUTH + {0x90A8, 0xB9D6}, //2762 #HANGUL SYLLABLE MIEUM A RIEULPHIEUPH + {0x90A9, 0xB9D7}, //2763 #HANGUL SYLLABLE MIEUM A RIEULHIEUH + {0x90AA, 0xB9DA}, //2764 #HANGUL SYLLABLE MIEUM A PIEUPSIOS + {0x90AB, 0xB9DC}, //2765 #HANGUL SYLLABLE MIEUM A SSANGSIOS + {0x90AC, 0xB9DF}, //2766 #HANGUL SYLLABLE MIEUM A CHIEUCH + {0x90AD, 0xB9E0}, //2767 #HANGUL SYLLABLE MIEUM A KHIEUKH + {0x90AE, 0xB9E2}, //2768 #HANGUL SYLLABLE MIEUM A PHIEUPH + {0x90AF, 0xB9E6}, //2769 #HANGUL SYLLABLE MIEUM AE SSANGKIYEOK + {0x90B0, 0xB9E7}, //2770 #HANGUL SYLLABLE MIEUM AE KIYEOKSIOS + {0x90B1, 0xB9E9}, //2771 #HANGUL SYLLABLE MIEUM AE NIEUNCIEUC + {0x90B2, 0xB9EA}, //2772 #HANGUL SYLLABLE MIEUM AE NIEUNHIEUH + {0x90B3, 0xB9EB}, //2773 #HANGUL SYLLABLE MIEUM AE TIKEUT + {0x90B4, 0xB9ED}, //2774 #HANGUL SYLLABLE MIEUM AE RIEULKIYEOK + {0x90B5, 0xB9EE}, //2775 #HANGUL SYLLABLE MIEUM AE RIEULMIEUM + {0x90B6, 0xB9EF}, //2776 #HANGUL SYLLABLE MIEUM AE RIEULPIEUP + {0x90B7, 0xB9F0}, //2777 #HANGUL SYLLABLE MIEUM AE RIEULSIOS + {0x90B8, 0xB9F1}, //2778 #HANGUL SYLLABLE MIEUM AE RIEULTHIEUTH + {0x90B9, 0xB9F2}, //2779 #HANGUL SYLLABLE MIEUM AE RIEULPHIEUPH + {0x90BA, 0xB9F3}, //2780 #HANGUL SYLLABLE MIEUM AE RIEULHIEUH + {0x90BB, 0xB9F6}, //2781 #HANGUL SYLLABLE MIEUM AE PIEUPSIOS + {0x90BC, 0xB9FB}, //2782 #HANGUL SYLLABLE MIEUM AE CHIEUCH + {0x90BD, 0xB9FC}, //2783 #HANGUL SYLLABLE MIEUM AE KHIEUKH + {0x90BE, 0xB9FD}, //2784 #HANGUL SYLLABLE MIEUM AE THIEUTH + {0x90BF, 0xB9FE}, //2785 #HANGUL SYLLABLE MIEUM AE PHIEUPH + {0x90C0, 0xB9FF}, //2786 #HANGUL SYLLABLE MIEUM AE HIEUH + {0x90C1, 0xBA02}, //2787 #HANGUL SYLLABLE MIEUM YA SSANGKIYEOK + {0x90C2, 0xBA03}, //2788 #HANGUL SYLLABLE MIEUM YA KIYEOKSIOS + {0x90C3, 0xBA04}, //2789 #HANGUL SYLLABLE MIEUM YA NIEUN + {0x90C4, 0xBA05}, //2790 #HANGUL SYLLABLE MIEUM YA NIEUNCIEUC + {0x90C5, 0xBA06}, //2791 #HANGUL SYLLABLE MIEUM YA NIEUNHIEUH + {0x90C6, 0xBA07}, //2792 #HANGUL SYLLABLE MIEUM YA TIKEUT + {0x90C7, 0xBA09}, //2793 #HANGUL SYLLABLE MIEUM YA RIEULKIYEOK + {0x90C8, 0xBA0A}, //2794 #HANGUL SYLLABLE MIEUM YA RIEULMIEUM + {0x90C9, 0xBA0B}, //2795 #HANGUL SYLLABLE MIEUM YA RIEULPIEUP + {0x90CA, 0xBA0C}, //2796 #HANGUL SYLLABLE MIEUM YA RIEULSIOS + {0x90CB, 0xBA0D}, //2797 #HANGUL SYLLABLE MIEUM YA RIEULTHIEUTH + {0x90CC, 0xBA0E}, //2798 #HANGUL SYLLABLE MIEUM YA RIEULPHIEUPH + {0x90CD, 0xBA0F}, //2799 #HANGUL SYLLABLE MIEUM YA RIEULHIEUH + {0x90CE, 0xBA10}, //2800 #HANGUL SYLLABLE MIEUM YA MIEUM + {0x90CF, 0xBA11}, //2801 #HANGUL SYLLABLE MIEUM YA PIEUP + {0x90D0, 0xBA12}, //2802 #HANGUL SYLLABLE MIEUM YA PIEUPSIOS + {0x90D1, 0xBA13}, //2803 #HANGUL SYLLABLE MIEUM YA SIOS + {0x90D2, 0xBA14}, //2804 #HANGUL SYLLABLE MIEUM YA SSANGSIOS + {0x90D3, 0xBA16}, //2805 #HANGUL SYLLABLE MIEUM YA CIEUC + {0x90D4, 0xBA17}, //2806 #HANGUL SYLLABLE MIEUM YA CHIEUCH + {0x90D5, 0xBA18}, //2807 #HANGUL SYLLABLE MIEUM YA KHIEUKH + {0x90D6, 0xBA19}, //2808 #HANGUL SYLLABLE MIEUM YA THIEUTH + {0x90D7, 0xBA1A}, //2809 #HANGUL SYLLABLE MIEUM YA PHIEUPH + {0x90D8, 0xBA1B}, //2810 #HANGUL SYLLABLE MIEUM YA HIEUH + {0x90D9, 0xBA1C}, //2811 #HANGUL SYLLABLE MIEUM YAE + {0x90DA, 0xBA1D}, //2812 #HANGUL SYLLABLE MIEUM YAE KIYEOK + {0x90DB, 0xBA1E}, //2813 #HANGUL SYLLABLE MIEUM YAE SSANGKIYEOK + {0x90DC, 0xBA1F}, //2814 #HANGUL SYLLABLE MIEUM YAE KIYEOKSIOS + {0x90DD, 0xBA20}, //2815 #HANGUL SYLLABLE MIEUM YAE NIEUN + {0x90DE, 0xBA21}, //2816 #HANGUL SYLLABLE MIEUM YAE NIEUNCIEUC + {0x90DF, 0xBA22}, //2817 #HANGUL SYLLABLE MIEUM YAE NIEUNHIEUH + {0x90E0, 0xBA23}, //2818 #HANGUL SYLLABLE MIEUM YAE TIKEUT + {0x90E1, 0xBA24}, //2819 #HANGUL SYLLABLE MIEUM YAE RIEUL + {0x90E2, 0xBA25}, //2820 #HANGUL SYLLABLE MIEUM YAE RIEULKIYEOK + {0x90E3, 0xBA26}, //2821 #HANGUL SYLLABLE MIEUM YAE RIEULMIEUM + {0x90E4, 0xBA27}, //2822 #HANGUL SYLLABLE MIEUM YAE RIEULPIEUP + {0x90E5, 0xBA28}, //2823 #HANGUL SYLLABLE MIEUM YAE RIEULSIOS + {0x90E6, 0xBA29}, //2824 #HANGUL SYLLABLE MIEUM YAE RIEULTHIEUTH + {0x90E7, 0xBA2A}, //2825 #HANGUL SYLLABLE MIEUM YAE RIEULPHIEUPH + {0x90E8, 0xBA2B}, //2826 #HANGUL SYLLABLE MIEUM YAE RIEULHIEUH + {0x90E9, 0xBA2C}, //2827 #HANGUL SYLLABLE MIEUM YAE MIEUM + {0x90EA, 0xBA2D}, //2828 #HANGUL SYLLABLE MIEUM YAE PIEUP + {0x90EB, 0xBA2E}, //2829 #HANGUL SYLLABLE MIEUM YAE PIEUPSIOS + {0x90EC, 0xBA2F}, //2830 #HANGUL SYLLABLE MIEUM YAE SIOS + {0x90ED, 0xBA30}, //2831 #HANGUL SYLLABLE MIEUM YAE SSANGSIOS + {0x90EE, 0xBA31}, //2832 #HANGUL SYLLABLE MIEUM YAE IEUNG + {0x90EF, 0xBA32}, //2833 #HANGUL SYLLABLE MIEUM YAE CIEUC + {0x90F0, 0xBA33}, //2834 #HANGUL SYLLABLE MIEUM YAE CHIEUCH + {0x90F1, 0xBA34}, //2835 #HANGUL SYLLABLE MIEUM YAE KHIEUKH + {0x90F2, 0xBA35}, //2836 #HANGUL SYLLABLE MIEUM YAE THIEUTH + {0x90F3, 0xBA36}, //2837 #HANGUL SYLLABLE MIEUM YAE PHIEUPH + {0x90F4, 0xBA37}, //2838 #HANGUL SYLLABLE MIEUM YAE HIEUH + {0x90F5, 0xBA3A}, //2839 #HANGUL SYLLABLE MIEUM EO SSANGKIYEOK + {0x90F6, 0xBA3B}, //2840 #HANGUL SYLLABLE MIEUM EO KIYEOKSIOS + {0x90F7, 0xBA3D}, //2841 #HANGUL SYLLABLE MIEUM EO NIEUNCIEUC + {0x90F8, 0xBA3E}, //2842 #HANGUL SYLLABLE MIEUM EO NIEUNHIEUH + {0x90F9, 0xBA3F}, //2843 #HANGUL SYLLABLE MIEUM EO TIKEUT + {0x90FA, 0xBA41}, //2844 #HANGUL SYLLABLE MIEUM EO RIEULKIYEOK + {0x90FB, 0xBA43}, //2845 #HANGUL SYLLABLE MIEUM EO RIEULPIEUP + {0x90FC, 0xBA44}, //2846 #HANGUL SYLLABLE MIEUM EO RIEULSIOS + {0x90FD, 0xBA45}, //2847 #HANGUL SYLLABLE MIEUM EO RIEULTHIEUTH + {0x90FE, 0xBA46}, //2848 #HANGUL SYLLABLE MIEUM EO RIEULPHIEUPH + {0x9141, 0xBA47}, //2849 #HANGUL SYLLABLE MIEUM EO RIEULHIEUH + {0x9142, 0xBA4A}, //2850 #HANGUL SYLLABLE MIEUM EO PIEUPSIOS + {0x9143, 0xBA4C}, //2851 #HANGUL SYLLABLE MIEUM EO SSANGSIOS + {0x9144, 0xBA4F}, //2852 #HANGUL SYLLABLE MIEUM EO CHIEUCH + {0x9145, 0xBA50}, //2853 #HANGUL SYLLABLE MIEUM EO KHIEUKH + {0x9146, 0xBA51}, //2854 #HANGUL SYLLABLE MIEUM EO THIEUTH + {0x9147, 0xBA52}, //2855 #HANGUL SYLLABLE MIEUM EO PHIEUPH + {0x9148, 0xBA56}, //2856 #HANGUL SYLLABLE MIEUM E SSANGKIYEOK + {0x9149, 0xBA57}, //2857 #HANGUL SYLLABLE MIEUM E KIYEOKSIOS + {0x914A, 0xBA59}, //2858 #HANGUL SYLLABLE MIEUM E NIEUNCIEUC + {0x914B, 0xBA5A}, //2859 #HANGUL SYLLABLE MIEUM E NIEUNHIEUH + {0x914C, 0xBA5B}, //2860 #HANGUL SYLLABLE MIEUM E TIKEUT + {0x914D, 0xBA5D}, //2861 #HANGUL SYLLABLE MIEUM E RIEULKIYEOK + {0x914E, 0xBA5E}, //2862 #HANGUL SYLLABLE MIEUM E RIEULMIEUM + {0x914F, 0xBA5F}, //2863 #HANGUL SYLLABLE MIEUM E RIEULPIEUP + {0x9150, 0xBA60}, //2864 #HANGUL SYLLABLE MIEUM E RIEULSIOS + {0x9151, 0xBA61}, //2865 #HANGUL SYLLABLE MIEUM E RIEULTHIEUTH + {0x9152, 0xBA62}, //2866 #HANGUL SYLLABLE MIEUM E RIEULPHIEUPH + {0x9153, 0xBA63}, //2867 #HANGUL SYLLABLE MIEUM E RIEULHIEUH + {0x9154, 0xBA66}, //2868 #HANGUL SYLLABLE MIEUM E PIEUPSIOS + {0x9155, 0xBA6A}, //2869 #HANGUL SYLLABLE MIEUM E CIEUC + {0x9156, 0xBA6B}, //2870 #HANGUL SYLLABLE MIEUM E CHIEUCH + {0x9157, 0xBA6C}, //2871 #HANGUL SYLLABLE MIEUM E KHIEUKH + {0x9158, 0xBA6D}, //2872 #HANGUL SYLLABLE MIEUM E THIEUTH + {0x9159, 0xBA6E}, //2873 #HANGUL SYLLABLE MIEUM E PHIEUPH + {0x915A, 0xBA6F}, //2874 #HANGUL SYLLABLE MIEUM E HIEUH + {0x9161, 0xBA72}, //2875 #HANGUL SYLLABLE MIEUM YEO SSANGKIYEOK + {0x9162, 0xBA73}, //2876 #HANGUL SYLLABLE MIEUM YEO KIYEOKSIOS + {0x9163, 0xBA75}, //2877 #HANGUL SYLLABLE MIEUM YEO NIEUNCIEUC + {0x9164, 0xBA76}, //2878 #HANGUL SYLLABLE MIEUM YEO NIEUNHIEUH + {0x9165, 0xBA77}, //2879 #HANGUL SYLLABLE MIEUM YEO TIKEUT + {0x9166, 0xBA79}, //2880 #HANGUL SYLLABLE MIEUM YEO RIEULKIYEOK + {0x9167, 0xBA7A}, //2881 #HANGUL SYLLABLE MIEUM YEO RIEULMIEUM + {0x9168, 0xBA7B}, //2882 #HANGUL SYLLABLE MIEUM YEO RIEULPIEUP + {0x9169, 0xBA7C}, //2883 #HANGUL SYLLABLE MIEUM YEO RIEULSIOS + {0x916A, 0xBA7D}, //2884 #HANGUL SYLLABLE MIEUM YEO RIEULTHIEUTH + {0x916B, 0xBA7E}, //2885 #HANGUL SYLLABLE MIEUM YEO RIEULPHIEUPH + {0x916C, 0xBA7F}, //2886 #HANGUL SYLLABLE MIEUM YEO RIEULHIEUH + {0x916D, 0xBA80}, //2887 #HANGUL SYLLABLE MIEUM YEO MIEUM + {0x916E, 0xBA81}, //2888 #HANGUL SYLLABLE MIEUM YEO PIEUP + {0x916F, 0xBA82}, //2889 #HANGUL SYLLABLE MIEUM YEO PIEUPSIOS + {0x9170, 0xBA86}, //2890 #HANGUL SYLLABLE MIEUM YEO CIEUC + {0x9171, 0xBA88}, //2891 #HANGUL SYLLABLE MIEUM YEO KHIEUKH + {0x9172, 0xBA89}, //2892 #HANGUL SYLLABLE MIEUM YEO THIEUTH + {0x9173, 0xBA8A}, //2893 #HANGUL SYLLABLE MIEUM YEO PHIEUPH + {0x9174, 0xBA8B}, //2894 #HANGUL SYLLABLE MIEUM YEO HIEUH + {0x9175, 0xBA8D}, //2895 #HANGUL SYLLABLE MIEUM YE KIYEOK + {0x9176, 0xBA8E}, //2896 #HANGUL SYLLABLE MIEUM YE SSANGKIYEOK + {0x9177, 0xBA8F}, //2897 #HANGUL SYLLABLE MIEUM YE KIYEOKSIOS + {0x9178, 0xBA90}, //2898 #HANGUL SYLLABLE MIEUM YE NIEUN + {0x9179, 0xBA91}, //2899 #HANGUL SYLLABLE MIEUM YE NIEUNCIEUC + {0x917A, 0xBA92}, //2900 #HANGUL SYLLABLE MIEUM YE NIEUNHIEUH + {0x9181, 0xBA93}, //2901 #HANGUL SYLLABLE MIEUM YE TIKEUT + {0x9182, 0xBA94}, //2902 #HANGUL SYLLABLE MIEUM YE RIEUL + {0x9183, 0xBA95}, //2903 #HANGUL SYLLABLE MIEUM YE RIEULKIYEOK + {0x9184, 0xBA96}, //2904 #HANGUL SYLLABLE MIEUM YE RIEULMIEUM + {0x9185, 0xBA97}, //2905 #HANGUL SYLLABLE MIEUM YE RIEULPIEUP + {0x9186, 0xBA98}, //2906 #HANGUL SYLLABLE MIEUM YE RIEULSIOS + {0x9187, 0xBA99}, //2907 #HANGUL SYLLABLE MIEUM YE RIEULTHIEUTH + {0x9188, 0xBA9A}, //2908 #HANGUL SYLLABLE MIEUM YE RIEULPHIEUPH + {0x9189, 0xBA9B}, //2909 #HANGUL SYLLABLE MIEUM YE RIEULHIEUH + {0x918A, 0xBA9C}, //2910 #HANGUL SYLLABLE MIEUM YE MIEUM + {0x918B, 0xBA9D}, //2911 #HANGUL SYLLABLE MIEUM YE PIEUP + {0x918C, 0xBA9E}, //2912 #HANGUL SYLLABLE MIEUM YE PIEUPSIOS + {0x918D, 0xBA9F}, //2913 #HANGUL SYLLABLE MIEUM YE SIOS + {0x918E, 0xBAA0}, //2914 #HANGUL SYLLABLE MIEUM YE SSANGSIOS + {0x918F, 0xBAA1}, //2915 #HANGUL SYLLABLE MIEUM YE IEUNG + {0x9190, 0xBAA2}, //2916 #HANGUL SYLLABLE MIEUM YE CIEUC + {0x9191, 0xBAA3}, //2917 #HANGUL SYLLABLE MIEUM YE CHIEUCH + {0x9192, 0xBAA4}, //2918 #HANGUL SYLLABLE MIEUM YE KHIEUKH + {0x9193, 0xBAA5}, //2919 #HANGUL SYLLABLE MIEUM YE THIEUTH + {0x9194, 0xBAA6}, //2920 #HANGUL SYLLABLE MIEUM YE PHIEUPH + {0x9195, 0xBAA7}, //2921 #HANGUL SYLLABLE MIEUM YE HIEUH + {0x9196, 0xBAAA}, //2922 #HANGUL SYLLABLE MIEUM O SSANGKIYEOK + {0x9197, 0xBAAD}, //2923 #HANGUL SYLLABLE MIEUM O NIEUNCIEUC + {0x9198, 0xBAAE}, //2924 #HANGUL SYLLABLE MIEUM O NIEUNHIEUH + {0x9199, 0xBAAF}, //2925 #HANGUL SYLLABLE MIEUM O TIKEUT + {0x919A, 0xBAB1}, //2926 #HANGUL SYLLABLE MIEUM O RIEULKIYEOK + {0x919B, 0xBAB3}, //2927 #HANGUL SYLLABLE MIEUM O RIEULPIEUP + {0x919C, 0xBAB4}, //2928 #HANGUL SYLLABLE MIEUM O RIEULSIOS + {0x919D, 0xBAB5}, //2929 #HANGUL SYLLABLE MIEUM O RIEULTHIEUTH + {0x919E, 0xBAB6}, //2930 #HANGUL SYLLABLE MIEUM O RIEULPHIEUPH + {0x919F, 0xBAB7}, //2931 #HANGUL SYLLABLE MIEUM O RIEULHIEUH + {0x91A0, 0xBABA}, //2932 #HANGUL SYLLABLE MIEUM O PIEUPSIOS + {0x91A1, 0xBABC}, //2933 #HANGUL SYLLABLE MIEUM O SSANGSIOS + {0x91A2, 0xBABE}, //2934 #HANGUL SYLLABLE MIEUM O CIEUC + {0x91A3, 0xBABF}, //2935 #HANGUL SYLLABLE MIEUM O CHIEUCH + {0x91A4, 0xBAC0}, //2936 #HANGUL SYLLABLE MIEUM O KHIEUKH + {0x91A5, 0xBAC1}, //2937 #HANGUL SYLLABLE MIEUM O THIEUTH + {0x91A6, 0xBAC2}, //2938 #HANGUL SYLLABLE MIEUM O PHIEUPH + {0x91A7, 0xBAC3}, //2939 #HANGUL SYLLABLE MIEUM O HIEUH + {0x91A8, 0xBAC5}, //2940 #HANGUL SYLLABLE MIEUM WA KIYEOK + {0x91A9, 0xBAC6}, //2941 #HANGUL SYLLABLE MIEUM WA SSANGKIYEOK + {0x91AA, 0xBAC7}, //2942 #HANGUL SYLLABLE MIEUM WA KIYEOKSIOS + {0x91AB, 0xBAC9}, //2943 #HANGUL SYLLABLE MIEUM WA NIEUNCIEUC + {0x91AC, 0xBACA}, //2944 #HANGUL SYLLABLE MIEUM WA NIEUNHIEUH + {0x91AD, 0xBACB}, //2945 #HANGUL SYLLABLE MIEUM WA TIKEUT + {0x91AE, 0xBACC}, //2946 #HANGUL SYLLABLE MIEUM WA RIEUL + {0x91AF, 0xBACD}, //2947 #HANGUL SYLLABLE MIEUM WA RIEULKIYEOK + {0x91B0, 0xBACE}, //2948 #HANGUL SYLLABLE MIEUM WA RIEULMIEUM + {0x91B1, 0xBACF}, //2949 #HANGUL SYLLABLE MIEUM WA RIEULPIEUP + {0x91B2, 0xBAD0}, //2950 #HANGUL SYLLABLE MIEUM WA RIEULSIOS + {0x91B3, 0xBAD1}, //2951 #HANGUL SYLLABLE MIEUM WA RIEULTHIEUTH + {0x91B4, 0xBAD2}, //2952 #HANGUL SYLLABLE MIEUM WA RIEULPHIEUPH + {0x91B5, 0xBAD3}, //2953 #HANGUL SYLLABLE MIEUM WA RIEULHIEUH + {0x91B6, 0xBAD4}, //2954 #HANGUL SYLLABLE MIEUM WA MIEUM + {0x91B7, 0xBAD5}, //2955 #HANGUL SYLLABLE MIEUM WA PIEUP + {0x91B8, 0xBAD6}, //2956 #HANGUL SYLLABLE MIEUM WA PIEUPSIOS + {0x91B9, 0xBAD7}, //2957 #HANGUL SYLLABLE MIEUM WA SIOS + {0x91BA, 0xBADA}, //2958 #HANGUL SYLLABLE MIEUM WA CIEUC + {0x91BB, 0xBADB}, //2959 #HANGUL SYLLABLE MIEUM WA CHIEUCH + {0x91BC, 0xBADC}, //2960 #HANGUL SYLLABLE MIEUM WA KHIEUKH + {0x91BD, 0xBADD}, //2961 #HANGUL SYLLABLE MIEUM WA THIEUTH + {0x91BE, 0xBADE}, //2962 #HANGUL SYLLABLE MIEUM WA PHIEUPH + {0x91BF, 0xBADF}, //2963 #HANGUL SYLLABLE MIEUM WA HIEUH + {0x91C0, 0xBAE0}, //2964 #HANGUL SYLLABLE MIEUM WAE + {0x91C1, 0xBAE1}, //2965 #HANGUL SYLLABLE MIEUM WAE KIYEOK + {0x91C2, 0xBAE2}, //2966 #HANGUL SYLLABLE MIEUM WAE SSANGKIYEOK + {0x91C3, 0xBAE3}, //2967 #HANGUL SYLLABLE MIEUM WAE KIYEOKSIOS + {0x91C4, 0xBAE4}, //2968 #HANGUL SYLLABLE MIEUM WAE NIEUN + {0x91C5, 0xBAE5}, //2969 #HANGUL SYLLABLE MIEUM WAE NIEUNCIEUC + {0x91C6, 0xBAE6}, //2970 #HANGUL SYLLABLE MIEUM WAE NIEUNHIEUH + {0x91C7, 0xBAE7}, //2971 #HANGUL SYLLABLE MIEUM WAE TIKEUT + {0x91C8, 0xBAE8}, //2972 #HANGUL SYLLABLE MIEUM WAE RIEUL + {0x91C9, 0xBAE9}, //2973 #HANGUL SYLLABLE MIEUM WAE RIEULKIYEOK + {0x91CA, 0xBAEA}, //2974 #HANGUL SYLLABLE MIEUM WAE RIEULMIEUM + {0x91CB, 0xBAEB}, //2975 #HANGUL SYLLABLE MIEUM WAE RIEULPIEUP + {0x91CC, 0xBAEC}, //2976 #HANGUL SYLLABLE MIEUM WAE RIEULSIOS + {0x91CD, 0xBAED}, //2977 #HANGUL SYLLABLE MIEUM WAE RIEULTHIEUTH + {0x91CE, 0xBAEE}, //2978 #HANGUL SYLLABLE MIEUM WAE RIEULPHIEUPH + {0x91CF, 0xBAEF}, //2979 #HANGUL SYLLABLE MIEUM WAE RIEULHIEUH + {0x91D0, 0xBAF0}, //2980 #HANGUL SYLLABLE MIEUM WAE MIEUM + {0x91D1, 0xBAF1}, //2981 #HANGUL SYLLABLE MIEUM WAE PIEUP + {0x91D2, 0xBAF2}, //2982 #HANGUL SYLLABLE MIEUM WAE PIEUPSIOS + {0x91D3, 0xBAF3}, //2983 #HANGUL SYLLABLE MIEUM WAE SIOS + {0x91D4, 0xBAF4}, //2984 #HANGUL SYLLABLE MIEUM WAE SSANGSIOS + {0x91D5, 0xBAF5}, //2985 #HANGUL SYLLABLE MIEUM WAE IEUNG + {0x91D6, 0xBAF6}, //2986 #HANGUL SYLLABLE MIEUM WAE CIEUC + {0x91D7, 0xBAF7}, //2987 #HANGUL SYLLABLE MIEUM WAE CHIEUCH + {0x91D8, 0xBAF8}, //2988 #HANGUL SYLLABLE MIEUM WAE KHIEUKH + {0x91D9, 0xBAF9}, //2989 #HANGUL SYLLABLE MIEUM WAE THIEUTH + {0x91DA, 0xBAFA}, //2990 #HANGUL SYLLABLE MIEUM WAE PHIEUPH + {0x91DB, 0xBAFB}, //2991 #HANGUL SYLLABLE MIEUM WAE HIEUH + {0x91DC, 0xBAFD}, //2992 #HANGUL SYLLABLE MIEUM OE KIYEOK + {0x91DD, 0xBAFE}, //2993 #HANGUL SYLLABLE MIEUM OE SSANGKIYEOK + {0x91DE, 0xBAFF}, //2994 #HANGUL SYLLABLE MIEUM OE KIYEOKSIOS + {0x91DF, 0xBB01}, //2995 #HANGUL SYLLABLE MIEUM OE NIEUNCIEUC + {0x91E0, 0xBB02}, //2996 #HANGUL SYLLABLE MIEUM OE NIEUNHIEUH + {0x91E1, 0xBB03}, //2997 #HANGUL SYLLABLE MIEUM OE TIKEUT + {0x91E2, 0xBB05}, //2998 #HANGUL SYLLABLE MIEUM OE RIEULKIYEOK + {0x91E3, 0xBB06}, //2999 #HANGUL SYLLABLE MIEUM OE RIEULMIEUM + {0x91E4, 0xBB07}, //3000 #HANGUL SYLLABLE MIEUM OE RIEULPIEUP + {0x91E5, 0xBB08}, //3001 #HANGUL SYLLABLE MIEUM OE RIEULSIOS + {0x91E6, 0xBB09}, //3002 #HANGUL SYLLABLE MIEUM OE RIEULTHIEUTH + {0x91E7, 0xBB0A}, //3003 #HANGUL SYLLABLE MIEUM OE RIEULPHIEUPH + {0x91E8, 0xBB0B}, //3004 #HANGUL SYLLABLE MIEUM OE RIEULHIEUH + {0x91E9, 0xBB0C}, //3005 #HANGUL SYLLABLE MIEUM OE MIEUM + {0x91EA, 0xBB0E}, //3006 #HANGUL SYLLABLE MIEUM OE PIEUPSIOS + {0x91EB, 0xBB10}, //3007 #HANGUL SYLLABLE MIEUM OE SSANGSIOS + {0x91EC, 0xBB12}, //3008 #HANGUL SYLLABLE MIEUM OE CIEUC + {0x91ED, 0xBB13}, //3009 #HANGUL SYLLABLE MIEUM OE CHIEUCH + {0x91EE, 0xBB14}, //3010 #HANGUL SYLLABLE MIEUM OE KHIEUKH + {0x91EF, 0xBB15}, //3011 #HANGUL SYLLABLE MIEUM OE THIEUTH + {0x91F0, 0xBB16}, //3012 #HANGUL SYLLABLE MIEUM OE PHIEUPH + {0x91F1, 0xBB17}, //3013 #HANGUL SYLLABLE MIEUM OE HIEUH + {0x91F2, 0xBB19}, //3014 #HANGUL SYLLABLE MIEUM YO KIYEOK + {0x91F3, 0xBB1A}, //3015 #HANGUL SYLLABLE MIEUM YO SSANGKIYEOK + {0x91F4, 0xBB1B}, //3016 #HANGUL SYLLABLE MIEUM YO KIYEOKSIOS + {0x91F5, 0xBB1D}, //3017 #HANGUL SYLLABLE MIEUM YO NIEUNCIEUC + {0x91F6, 0xBB1E}, //3018 #HANGUL SYLLABLE MIEUM YO NIEUNHIEUH + {0x91F7, 0xBB1F}, //3019 #HANGUL SYLLABLE MIEUM YO TIKEUT + {0x91F8, 0xBB21}, //3020 #HANGUL SYLLABLE MIEUM YO RIEULKIYEOK + {0x91F9, 0xBB22}, //3021 #HANGUL SYLLABLE MIEUM YO RIEULMIEUM + {0x91FA, 0xBB23}, //3022 #HANGUL SYLLABLE MIEUM YO RIEULPIEUP + {0x91FB, 0xBB24}, //3023 #HANGUL SYLLABLE MIEUM YO RIEULSIOS + {0x91FC, 0xBB25}, //3024 #HANGUL SYLLABLE MIEUM YO RIEULTHIEUTH + {0x91FD, 0xBB26}, //3025 #HANGUL SYLLABLE MIEUM YO RIEULPHIEUPH + {0x91FE, 0xBB27}, //3026 #HANGUL SYLLABLE MIEUM YO RIEULHIEUH + {0x9241, 0xBB28}, //3027 #HANGUL SYLLABLE MIEUM YO MIEUM + {0x9242, 0xBB2A}, //3028 #HANGUL SYLLABLE MIEUM YO PIEUPSIOS + {0x9243, 0xBB2C}, //3029 #HANGUL SYLLABLE MIEUM YO SSANGSIOS + {0x9244, 0xBB2D}, //3030 #HANGUL SYLLABLE MIEUM YO IEUNG + {0x9245, 0xBB2E}, //3031 #HANGUL SYLLABLE MIEUM YO CIEUC + {0x9246, 0xBB2F}, //3032 #HANGUL SYLLABLE MIEUM YO CHIEUCH + {0x9247, 0xBB30}, //3033 #HANGUL SYLLABLE MIEUM YO KHIEUKH + {0x9248, 0xBB31}, //3034 #HANGUL SYLLABLE MIEUM YO THIEUTH + {0x9249, 0xBB32}, //3035 #HANGUL SYLLABLE MIEUM YO PHIEUPH + {0x924A, 0xBB33}, //3036 #HANGUL SYLLABLE MIEUM YO HIEUH + {0x924B, 0xBB37}, //3037 #HANGUL SYLLABLE MIEUM U KIYEOKSIOS + {0x924C, 0xBB39}, //3038 #HANGUL SYLLABLE MIEUM U NIEUNCIEUC + {0x924D, 0xBB3A}, //3039 #HANGUL SYLLABLE MIEUM U NIEUNHIEUH + {0x924E, 0xBB3F}, //3040 #HANGUL SYLLABLE MIEUM U RIEULPIEUP + {0x924F, 0xBB40}, //3041 #HANGUL SYLLABLE MIEUM U RIEULSIOS + {0x9250, 0xBB41}, //3042 #HANGUL SYLLABLE MIEUM U RIEULTHIEUTH + {0x9251, 0xBB42}, //3043 #HANGUL SYLLABLE MIEUM U RIEULPHIEUPH + {0x9252, 0xBB43}, //3044 #HANGUL SYLLABLE MIEUM U RIEULHIEUH + {0x9253, 0xBB46}, //3045 #HANGUL SYLLABLE MIEUM U PIEUPSIOS + {0x9254, 0xBB48}, //3046 #HANGUL SYLLABLE MIEUM U SSANGSIOS + {0x9255, 0xBB4A}, //3047 #HANGUL SYLLABLE MIEUM U CIEUC + {0x9256, 0xBB4B}, //3048 #HANGUL SYLLABLE MIEUM U CHIEUCH + {0x9257, 0xBB4C}, //3049 #HANGUL SYLLABLE MIEUM U KHIEUKH + {0x9258, 0xBB4E}, //3050 #HANGUL SYLLABLE MIEUM U PHIEUPH + {0x9259, 0xBB51}, //3051 #HANGUL SYLLABLE MIEUM WEO KIYEOK + {0x925A, 0xBB52}, //3052 #HANGUL SYLLABLE MIEUM WEO SSANGKIYEOK + {0x9261, 0xBB53}, //3053 #HANGUL SYLLABLE MIEUM WEO KIYEOKSIOS + {0x9262, 0xBB55}, //3054 #HANGUL SYLLABLE MIEUM WEO NIEUNCIEUC + {0x9263, 0xBB56}, //3055 #HANGUL SYLLABLE MIEUM WEO NIEUNHIEUH + {0x9264, 0xBB57}, //3056 #HANGUL SYLLABLE MIEUM WEO TIKEUT + {0x9265, 0xBB59}, //3057 #HANGUL SYLLABLE MIEUM WEO RIEULKIYEOK + {0x9266, 0xBB5A}, //3058 #HANGUL SYLLABLE MIEUM WEO RIEULMIEUM + {0x9267, 0xBB5B}, //3059 #HANGUL SYLLABLE MIEUM WEO RIEULPIEUP + {0x9268, 0xBB5C}, //3060 #HANGUL SYLLABLE MIEUM WEO RIEULSIOS + {0x9269, 0xBB5D}, //3061 #HANGUL SYLLABLE MIEUM WEO RIEULTHIEUTH + {0x926A, 0xBB5E}, //3062 #HANGUL SYLLABLE MIEUM WEO RIEULPHIEUPH + {0x926B, 0xBB5F}, //3063 #HANGUL SYLLABLE MIEUM WEO RIEULHIEUH + {0x926C, 0xBB60}, //3064 #HANGUL SYLLABLE MIEUM WEO MIEUM + {0x926D, 0xBB62}, //3065 #HANGUL SYLLABLE MIEUM WEO PIEUPSIOS + {0x926E, 0xBB64}, //3066 #HANGUL SYLLABLE MIEUM WEO SSANGSIOS + {0x926F, 0xBB65}, //3067 #HANGUL SYLLABLE MIEUM WEO IEUNG + {0x9270, 0xBB66}, //3068 #HANGUL SYLLABLE MIEUM WEO CIEUC + {0x9271, 0xBB67}, //3069 #HANGUL SYLLABLE MIEUM WEO CHIEUCH + {0x9272, 0xBB68}, //3070 #HANGUL SYLLABLE MIEUM WEO KHIEUKH + {0x9273, 0xBB69}, //3071 #HANGUL SYLLABLE MIEUM WEO THIEUTH + {0x9274, 0xBB6A}, //3072 #HANGUL SYLLABLE MIEUM WEO PHIEUPH + {0x9275, 0xBB6B}, //3073 #HANGUL SYLLABLE MIEUM WEO HIEUH + {0x9276, 0xBB6D}, //3074 #HANGUL SYLLABLE MIEUM WE KIYEOK + {0x9277, 0xBB6E}, //3075 #HANGUL SYLLABLE MIEUM WE SSANGKIYEOK + {0x9278, 0xBB6F}, //3076 #HANGUL SYLLABLE MIEUM WE KIYEOKSIOS + {0x9279, 0xBB70}, //3077 #HANGUL SYLLABLE MIEUM WE NIEUN + {0x927A, 0xBB71}, //3078 #HANGUL SYLLABLE MIEUM WE NIEUNCIEUC + {0x9281, 0xBB72}, //3079 #HANGUL SYLLABLE MIEUM WE NIEUNHIEUH + {0x9282, 0xBB73}, //3080 #HANGUL SYLLABLE MIEUM WE TIKEUT + {0x9283, 0xBB74}, //3081 #HANGUL SYLLABLE MIEUM WE RIEUL + {0x9284, 0xBB75}, //3082 #HANGUL SYLLABLE MIEUM WE RIEULKIYEOK + {0x9285, 0xBB76}, //3083 #HANGUL SYLLABLE MIEUM WE RIEULMIEUM + {0x9286, 0xBB77}, //3084 #HANGUL SYLLABLE MIEUM WE RIEULPIEUP + {0x9287, 0xBB78}, //3085 #HANGUL SYLLABLE MIEUM WE RIEULSIOS + {0x9288, 0xBB79}, //3086 #HANGUL SYLLABLE MIEUM WE RIEULTHIEUTH + {0x9289, 0xBB7A}, //3087 #HANGUL SYLLABLE MIEUM WE RIEULPHIEUPH + {0x928A, 0xBB7B}, //3088 #HANGUL SYLLABLE MIEUM WE RIEULHIEUH + {0x928B, 0xBB7C}, //3089 #HANGUL SYLLABLE MIEUM WE MIEUM + {0x928C, 0xBB7D}, //3090 #HANGUL SYLLABLE MIEUM WE PIEUP + {0x928D, 0xBB7E}, //3091 #HANGUL SYLLABLE MIEUM WE PIEUPSIOS + {0x928E, 0xBB7F}, //3092 #HANGUL SYLLABLE MIEUM WE SIOS + {0x928F, 0xBB80}, //3093 #HANGUL SYLLABLE MIEUM WE SSANGSIOS + {0x9290, 0xBB81}, //3094 #HANGUL SYLLABLE MIEUM WE IEUNG + {0x9291, 0xBB82}, //3095 #HANGUL SYLLABLE MIEUM WE CIEUC + {0x9292, 0xBB83}, //3096 #HANGUL SYLLABLE MIEUM WE CHIEUCH + {0x9293, 0xBB84}, //3097 #HANGUL SYLLABLE MIEUM WE KHIEUKH + {0x9294, 0xBB85}, //3098 #HANGUL SYLLABLE MIEUM WE THIEUTH + {0x9295, 0xBB86}, //3099 #HANGUL SYLLABLE MIEUM WE PHIEUPH + {0x9296, 0xBB87}, //3100 #HANGUL SYLLABLE MIEUM WE HIEUH + {0x9297, 0xBB89}, //3101 #HANGUL SYLLABLE MIEUM WI KIYEOK + {0x9298, 0xBB8A}, //3102 #HANGUL SYLLABLE MIEUM WI SSANGKIYEOK + {0x9299, 0xBB8B}, //3103 #HANGUL SYLLABLE MIEUM WI KIYEOKSIOS + {0x929A, 0xBB8D}, //3104 #HANGUL SYLLABLE MIEUM WI NIEUNCIEUC + {0x929B, 0xBB8E}, //3105 #HANGUL SYLLABLE MIEUM WI NIEUNHIEUH + {0x929C, 0xBB8F}, //3106 #HANGUL SYLLABLE MIEUM WI TIKEUT + {0x929D, 0xBB91}, //3107 #HANGUL SYLLABLE MIEUM WI RIEULKIYEOK + {0x929E, 0xBB92}, //3108 #HANGUL SYLLABLE MIEUM WI RIEULMIEUM + {0x929F, 0xBB93}, //3109 #HANGUL SYLLABLE MIEUM WI RIEULPIEUP + {0x92A0, 0xBB94}, //3110 #HANGUL SYLLABLE MIEUM WI RIEULSIOS + {0x92A1, 0xBB95}, //3111 #HANGUL SYLLABLE MIEUM WI RIEULTHIEUTH + {0x92A2, 0xBB96}, //3112 #HANGUL SYLLABLE MIEUM WI RIEULPHIEUPH + {0x92A3, 0xBB97}, //3113 #HANGUL SYLLABLE MIEUM WI RIEULHIEUH + {0x92A4, 0xBB98}, //3114 #HANGUL SYLLABLE MIEUM WI MIEUM + {0x92A5, 0xBB99}, //3115 #HANGUL SYLLABLE MIEUM WI PIEUP + {0x92A6, 0xBB9A}, //3116 #HANGUL SYLLABLE MIEUM WI PIEUPSIOS + {0x92A7, 0xBB9B}, //3117 #HANGUL SYLLABLE MIEUM WI SIOS + {0x92A8, 0xBB9C}, //3118 #HANGUL SYLLABLE MIEUM WI SSANGSIOS + {0x92A9, 0xBB9D}, //3119 #HANGUL SYLLABLE MIEUM WI IEUNG + {0x92AA, 0xBB9E}, //3120 #HANGUL SYLLABLE MIEUM WI CIEUC + {0x92AB, 0xBB9F}, //3121 #HANGUL SYLLABLE MIEUM WI CHIEUCH + {0x92AC, 0xBBA0}, //3122 #HANGUL SYLLABLE MIEUM WI KHIEUKH + {0x92AD, 0xBBA1}, //3123 #HANGUL SYLLABLE MIEUM WI THIEUTH + {0x92AE, 0xBBA2}, //3124 #HANGUL SYLLABLE MIEUM WI PHIEUPH + {0x92AF, 0xBBA3}, //3125 #HANGUL SYLLABLE MIEUM WI HIEUH + {0x92B0, 0xBBA5}, //3126 #HANGUL SYLLABLE MIEUM YU KIYEOK + {0x92B1, 0xBBA6}, //3127 #HANGUL SYLLABLE MIEUM YU SSANGKIYEOK + {0x92B2, 0xBBA7}, //3128 #HANGUL SYLLABLE MIEUM YU KIYEOKSIOS + {0x92B3, 0xBBA9}, //3129 #HANGUL SYLLABLE MIEUM YU NIEUNCIEUC + {0x92B4, 0xBBAA}, //3130 #HANGUL SYLLABLE MIEUM YU NIEUNHIEUH + {0x92B5, 0xBBAB}, //3131 #HANGUL SYLLABLE MIEUM YU TIKEUT + {0x92B6, 0xBBAD}, //3132 #HANGUL SYLLABLE MIEUM YU RIEULKIYEOK + {0x92B7, 0xBBAE}, //3133 #HANGUL SYLLABLE MIEUM YU RIEULMIEUM + {0x92B8, 0xBBAF}, //3134 #HANGUL SYLLABLE MIEUM YU RIEULPIEUP + {0x92B9, 0xBBB0}, //3135 #HANGUL SYLLABLE MIEUM YU RIEULSIOS + {0x92BA, 0xBBB1}, //3136 #HANGUL SYLLABLE MIEUM YU RIEULTHIEUTH + {0x92BB, 0xBBB2}, //3137 #HANGUL SYLLABLE MIEUM YU RIEULPHIEUPH + {0x92BC, 0xBBB3}, //3138 #HANGUL SYLLABLE MIEUM YU RIEULHIEUH + {0x92BD, 0xBBB5}, //3139 #HANGUL SYLLABLE MIEUM YU PIEUP + {0x92BE, 0xBBB6}, //3140 #HANGUL SYLLABLE MIEUM YU PIEUPSIOS + {0x92BF, 0xBBB8}, //3141 #HANGUL SYLLABLE MIEUM YU SSANGSIOS + {0x92C0, 0xBBB9}, //3142 #HANGUL SYLLABLE MIEUM YU IEUNG + {0x92C1, 0xBBBA}, //3143 #HANGUL SYLLABLE MIEUM YU CIEUC + {0x92C2, 0xBBBB}, //3144 #HANGUL SYLLABLE MIEUM YU CHIEUCH + {0x92C3, 0xBBBC}, //3145 #HANGUL SYLLABLE MIEUM YU KHIEUKH + {0x92C4, 0xBBBD}, //3146 #HANGUL SYLLABLE MIEUM YU THIEUTH + {0x92C5, 0xBBBE}, //3147 #HANGUL SYLLABLE MIEUM YU PHIEUPH + {0x92C6, 0xBBBF}, //3148 #HANGUL SYLLABLE MIEUM YU HIEUH + {0x92C7, 0xBBC1}, //3149 #HANGUL SYLLABLE MIEUM EU KIYEOK + {0x92C8, 0xBBC2}, //3150 #HANGUL SYLLABLE MIEUM EU SSANGKIYEOK + {0x92C9, 0xBBC3}, //3151 #HANGUL SYLLABLE MIEUM EU KIYEOKSIOS + {0x92CA, 0xBBC5}, //3152 #HANGUL SYLLABLE MIEUM EU NIEUNCIEUC + {0x92CB, 0xBBC6}, //3153 #HANGUL SYLLABLE MIEUM EU NIEUNHIEUH + {0x92CC, 0xBBC7}, //3154 #HANGUL SYLLABLE MIEUM EU TIKEUT + {0x92CD, 0xBBC9}, //3155 #HANGUL SYLLABLE MIEUM EU RIEULKIYEOK + {0x92CE, 0xBBCA}, //3156 #HANGUL SYLLABLE MIEUM EU RIEULMIEUM + {0x92CF, 0xBBCB}, //3157 #HANGUL SYLLABLE MIEUM EU RIEULPIEUP + {0x92D0, 0xBBCC}, //3158 #HANGUL SYLLABLE MIEUM EU RIEULSIOS + {0x92D1, 0xBBCD}, //3159 #HANGUL SYLLABLE MIEUM EU RIEULTHIEUTH + {0x92D2, 0xBBCE}, //3160 #HANGUL SYLLABLE MIEUM EU RIEULPHIEUPH + {0x92D3, 0xBBCF}, //3161 #HANGUL SYLLABLE MIEUM EU RIEULHIEUH + {0x92D4, 0xBBD1}, //3162 #HANGUL SYLLABLE MIEUM EU PIEUP + {0x92D5, 0xBBD2}, //3163 #HANGUL SYLLABLE MIEUM EU PIEUPSIOS + {0x92D6, 0xBBD4}, //3164 #HANGUL SYLLABLE MIEUM EU SSANGSIOS + {0x92D7, 0xBBD5}, //3165 #HANGUL SYLLABLE MIEUM EU IEUNG + {0x92D8, 0xBBD6}, //3166 #HANGUL SYLLABLE MIEUM EU CIEUC + {0x92D9, 0xBBD7}, //3167 #HANGUL SYLLABLE MIEUM EU CHIEUCH + {0x92DA, 0xBBD8}, //3168 #HANGUL SYLLABLE MIEUM EU KHIEUKH + {0x92DB, 0xBBD9}, //3169 #HANGUL SYLLABLE MIEUM EU THIEUTH + {0x92DC, 0xBBDA}, //3170 #HANGUL SYLLABLE MIEUM EU PHIEUPH + {0x92DD, 0xBBDB}, //3171 #HANGUL SYLLABLE MIEUM EU HIEUH + {0x92DE, 0xBBDC}, //3172 #HANGUL SYLLABLE MIEUM YI + {0x92DF, 0xBBDD}, //3173 #HANGUL SYLLABLE MIEUM YI KIYEOK + {0x92E0, 0xBBDE}, //3174 #HANGUL SYLLABLE MIEUM YI SSANGKIYEOK + {0x92E1, 0xBBDF}, //3175 #HANGUL SYLLABLE MIEUM YI KIYEOKSIOS + {0x92E2, 0xBBE0}, //3176 #HANGUL SYLLABLE MIEUM YI NIEUN + {0x92E3, 0xBBE1}, //3177 #HANGUL SYLLABLE MIEUM YI NIEUNCIEUC + {0x92E4, 0xBBE2}, //3178 #HANGUL SYLLABLE MIEUM YI NIEUNHIEUH + {0x92E5, 0xBBE3}, //3179 #HANGUL SYLLABLE MIEUM YI TIKEUT + {0x92E6, 0xBBE4}, //3180 #HANGUL SYLLABLE MIEUM YI RIEUL + {0x92E7, 0xBBE5}, //3181 #HANGUL SYLLABLE MIEUM YI RIEULKIYEOK + {0x92E8, 0xBBE6}, //3182 #HANGUL SYLLABLE MIEUM YI RIEULMIEUM + {0x92E9, 0xBBE7}, //3183 #HANGUL SYLLABLE MIEUM YI RIEULPIEUP + {0x92EA, 0xBBE8}, //3184 #HANGUL SYLLABLE MIEUM YI RIEULSIOS + {0x92EB, 0xBBE9}, //3185 #HANGUL SYLLABLE MIEUM YI RIEULTHIEUTH + {0x92EC, 0xBBEA}, //3186 #HANGUL SYLLABLE MIEUM YI RIEULPHIEUPH + {0x92ED, 0xBBEB}, //3187 #HANGUL SYLLABLE MIEUM YI RIEULHIEUH + {0x92EE, 0xBBEC}, //3188 #HANGUL SYLLABLE MIEUM YI MIEUM + {0x92EF, 0xBBED}, //3189 #HANGUL SYLLABLE MIEUM YI PIEUP + {0x92F0, 0xBBEE}, //3190 #HANGUL SYLLABLE MIEUM YI PIEUPSIOS + {0x92F1, 0xBBEF}, //3191 #HANGUL SYLLABLE MIEUM YI SIOS + {0x92F2, 0xBBF0}, //3192 #HANGUL SYLLABLE MIEUM YI SSANGSIOS + {0x92F3, 0xBBF1}, //3193 #HANGUL SYLLABLE MIEUM YI IEUNG + {0x92F4, 0xBBF2}, //3194 #HANGUL SYLLABLE MIEUM YI CIEUC + {0x92F5, 0xBBF3}, //3195 #HANGUL SYLLABLE MIEUM YI CHIEUCH + {0x92F6, 0xBBF4}, //3196 #HANGUL SYLLABLE MIEUM YI KHIEUKH + {0x92F7, 0xBBF5}, //3197 #HANGUL SYLLABLE MIEUM YI THIEUTH + {0x92F8, 0xBBF6}, //3198 #HANGUL SYLLABLE MIEUM YI PHIEUPH + {0x92F9, 0xBBF7}, //3199 #HANGUL SYLLABLE MIEUM YI HIEUH + {0x92FA, 0xBBFA}, //3200 #HANGUL SYLLABLE MIEUM I SSANGKIYEOK + {0x92FB, 0xBBFB}, //3201 #HANGUL SYLLABLE MIEUM I KIYEOKSIOS + {0x92FC, 0xBBFD}, //3202 #HANGUL SYLLABLE MIEUM I NIEUNCIEUC + {0x92FD, 0xBBFE}, //3203 #HANGUL SYLLABLE MIEUM I NIEUNHIEUH + {0x92FE, 0xBC01}, //3204 #HANGUL SYLLABLE MIEUM I RIEULKIYEOK + {0x9341, 0xBC03}, //3205 #HANGUL SYLLABLE MIEUM I RIEULPIEUP + {0x9342, 0xBC04}, //3206 #HANGUL SYLLABLE MIEUM I RIEULSIOS + {0x9343, 0xBC05}, //3207 #HANGUL SYLLABLE MIEUM I RIEULTHIEUTH + {0x9344, 0xBC06}, //3208 #HANGUL SYLLABLE MIEUM I RIEULPHIEUPH + {0x9345, 0xBC07}, //3209 #HANGUL SYLLABLE MIEUM I RIEULHIEUH + {0x9346, 0xBC0A}, //3210 #HANGUL SYLLABLE MIEUM I PIEUPSIOS + {0x9347, 0xBC0E}, //3211 #HANGUL SYLLABLE MIEUM I CIEUC + {0x9348, 0xBC10}, //3212 #HANGUL SYLLABLE MIEUM I KHIEUKH + {0x9349, 0xBC12}, //3213 #HANGUL SYLLABLE MIEUM I PHIEUPH + {0x934A, 0xBC13}, //3214 #HANGUL SYLLABLE MIEUM I HIEUH + {0x934B, 0xBC19}, //3215 #HANGUL SYLLABLE PIEUP A NIEUNCIEUC + {0x934C, 0xBC1A}, //3216 #HANGUL SYLLABLE PIEUP A NIEUNHIEUH + {0x934D, 0xBC20}, //3217 #HANGUL SYLLABLE PIEUP A RIEULSIOS + {0x934E, 0xBC21}, //3218 #HANGUL SYLLABLE PIEUP A RIEULTHIEUTH + {0x934F, 0xBC22}, //3219 #HANGUL SYLLABLE PIEUP A RIEULPHIEUPH + {0x9350, 0xBC23}, //3220 #HANGUL SYLLABLE PIEUP A RIEULHIEUH + {0x9351, 0xBC26}, //3221 #HANGUL SYLLABLE PIEUP A PIEUPSIOS + {0x9352, 0xBC28}, //3222 #HANGUL SYLLABLE PIEUP A SSANGSIOS + {0x9353, 0xBC2A}, //3223 #HANGUL SYLLABLE PIEUP A CIEUC + {0x9354, 0xBC2B}, //3224 #HANGUL SYLLABLE PIEUP A CHIEUCH + {0x9355, 0xBC2C}, //3225 #HANGUL SYLLABLE PIEUP A KHIEUKH + {0x9356, 0xBC2E}, //3226 #HANGUL SYLLABLE PIEUP A PHIEUPH + {0x9357, 0xBC2F}, //3227 #HANGUL SYLLABLE PIEUP A HIEUH + {0x9358, 0xBC32}, //3228 #HANGUL SYLLABLE PIEUP AE SSANGKIYEOK + {0x9359, 0xBC33}, //3229 #HANGUL SYLLABLE PIEUP AE KIYEOKSIOS + {0x935A, 0xBC35}, //3230 #HANGUL SYLLABLE PIEUP AE NIEUNCIEUC + {0x9361, 0xBC36}, //3231 #HANGUL SYLLABLE PIEUP AE NIEUNHIEUH + {0x9362, 0xBC37}, //3232 #HANGUL SYLLABLE PIEUP AE TIKEUT + {0x9363, 0xBC39}, //3233 #HANGUL SYLLABLE PIEUP AE RIEULKIYEOK + {0x9364, 0xBC3A}, //3234 #HANGUL SYLLABLE PIEUP AE RIEULMIEUM + {0x9365, 0xBC3B}, //3235 #HANGUL SYLLABLE PIEUP AE RIEULPIEUP + {0x9366, 0xBC3C}, //3236 #HANGUL SYLLABLE PIEUP AE RIEULSIOS + {0x9367, 0xBC3D}, //3237 #HANGUL SYLLABLE PIEUP AE RIEULTHIEUTH + {0x9368, 0xBC3E}, //3238 #HANGUL SYLLABLE PIEUP AE RIEULPHIEUPH + {0x9369, 0xBC3F}, //3239 #HANGUL SYLLABLE PIEUP AE RIEULHIEUH + {0x936A, 0xBC42}, //3240 #HANGUL SYLLABLE PIEUP AE PIEUPSIOS + {0x936B, 0xBC46}, //3241 #HANGUL SYLLABLE PIEUP AE CIEUC + {0x936C, 0xBC47}, //3242 #HANGUL SYLLABLE PIEUP AE CHIEUCH + {0x936D, 0xBC48}, //3243 #HANGUL SYLLABLE PIEUP AE KHIEUKH + {0x936E, 0xBC4A}, //3244 #HANGUL SYLLABLE PIEUP AE PHIEUPH + {0x936F, 0xBC4B}, //3245 #HANGUL SYLLABLE PIEUP AE HIEUH + {0x9370, 0xBC4E}, //3246 #HANGUL SYLLABLE PIEUP YA SSANGKIYEOK + {0x9371, 0xBC4F}, //3247 #HANGUL SYLLABLE PIEUP YA KIYEOKSIOS + {0x9372, 0xBC51}, //3248 #HANGUL SYLLABLE PIEUP YA NIEUNCIEUC + {0x9373, 0xBC52}, //3249 #HANGUL SYLLABLE PIEUP YA NIEUNHIEUH + {0x9374, 0xBC53}, //3250 #HANGUL SYLLABLE PIEUP YA TIKEUT + {0x9375, 0xBC54}, //3251 #HANGUL SYLLABLE PIEUP YA RIEUL + {0x9376, 0xBC55}, //3252 #HANGUL SYLLABLE PIEUP YA RIEULKIYEOK + {0x9377, 0xBC56}, //3253 #HANGUL SYLLABLE PIEUP YA RIEULMIEUM + {0x9378, 0xBC57}, //3254 #HANGUL SYLLABLE PIEUP YA RIEULPIEUP + {0x9379, 0xBC58}, //3255 #HANGUL SYLLABLE PIEUP YA RIEULSIOS + {0x937A, 0xBC59}, //3256 #HANGUL SYLLABLE PIEUP YA RIEULTHIEUTH + {0x9381, 0xBC5A}, //3257 #HANGUL SYLLABLE PIEUP YA RIEULPHIEUPH + {0x9382, 0xBC5B}, //3258 #HANGUL SYLLABLE PIEUP YA RIEULHIEUH + {0x9383, 0xBC5C}, //3259 #HANGUL SYLLABLE PIEUP YA MIEUM + {0x9384, 0xBC5E}, //3260 #HANGUL SYLLABLE PIEUP YA PIEUPSIOS + {0x9385, 0xBC5F}, //3261 #HANGUL SYLLABLE PIEUP YA SIOS + {0x9386, 0xBC60}, //3262 #HANGUL SYLLABLE PIEUP YA SSANGSIOS + {0x9387, 0xBC61}, //3263 #HANGUL SYLLABLE PIEUP YA IEUNG + {0x9388, 0xBC62}, //3264 #HANGUL SYLLABLE PIEUP YA CIEUC + {0x9389, 0xBC63}, //3265 #HANGUL SYLLABLE PIEUP YA CHIEUCH + {0x938A, 0xBC64}, //3266 #HANGUL SYLLABLE PIEUP YA KHIEUKH + {0x938B, 0xBC65}, //3267 #HANGUL SYLLABLE PIEUP YA THIEUTH + {0x938C, 0xBC66}, //3268 #HANGUL SYLLABLE PIEUP YA PHIEUPH + {0x938D, 0xBC67}, //3269 #HANGUL SYLLABLE PIEUP YA HIEUH + {0x938E, 0xBC68}, //3270 #HANGUL SYLLABLE PIEUP YAE + {0x938F, 0xBC69}, //3271 #HANGUL SYLLABLE PIEUP YAE KIYEOK + {0x9390, 0xBC6A}, //3272 #HANGUL SYLLABLE PIEUP YAE SSANGKIYEOK + {0x9391, 0xBC6B}, //3273 #HANGUL SYLLABLE PIEUP YAE KIYEOKSIOS + {0x9392, 0xBC6C}, //3274 #HANGUL SYLLABLE PIEUP YAE NIEUN + {0x9393, 0xBC6D}, //3275 #HANGUL SYLLABLE PIEUP YAE NIEUNCIEUC + {0x9394, 0xBC6E}, //3276 #HANGUL SYLLABLE PIEUP YAE NIEUNHIEUH + {0x9395, 0xBC6F}, //3277 #HANGUL SYLLABLE PIEUP YAE TIKEUT + {0x9396, 0xBC70}, //3278 #HANGUL SYLLABLE PIEUP YAE RIEUL + {0x9397, 0xBC71}, //3279 #HANGUL SYLLABLE PIEUP YAE RIEULKIYEOK + {0x9398, 0xBC72}, //3280 #HANGUL SYLLABLE PIEUP YAE RIEULMIEUM + {0x9399, 0xBC73}, //3281 #HANGUL SYLLABLE PIEUP YAE RIEULPIEUP + {0x939A, 0xBC74}, //3282 #HANGUL SYLLABLE PIEUP YAE RIEULSIOS + {0x939B, 0xBC75}, //3283 #HANGUL SYLLABLE PIEUP YAE RIEULTHIEUTH + {0x939C, 0xBC76}, //3284 #HANGUL SYLLABLE PIEUP YAE RIEULPHIEUPH + {0x939D, 0xBC77}, //3285 #HANGUL SYLLABLE PIEUP YAE RIEULHIEUH + {0x939E, 0xBC78}, //3286 #HANGUL SYLLABLE PIEUP YAE MIEUM + {0x939F, 0xBC79}, //3287 #HANGUL SYLLABLE PIEUP YAE PIEUP + {0x93A0, 0xBC7A}, //3288 #HANGUL SYLLABLE PIEUP YAE PIEUPSIOS + {0x93A1, 0xBC7B}, //3289 #HANGUL SYLLABLE PIEUP YAE SIOS + {0x93A2, 0xBC7C}, //3290 #HANGUL SYLLABLE PIEUP YAE SSANGSIOS + {0x93A3, 0xBC7D}, //3291 #HANGUL SYLLABLE PIEUP YAE IEUNG + {0x93A4, 0xBC7E}, //3292 #HANGUL SYLLABLE PIEUP YAE CIEUC + {0x93A5, 0xBC7F}, //3293 #HANGUL SYLLABLE PIEUP YAE CHIEUCH + {0x93A6, 0xBC80}, //3294 #HANGUL SYLLABLE PIEUP YAE KHIEUKH + {0x93A7, 0xBC81}, //3295 #HANGUL SYLLABLE PIEUP YAE THIEUTH + {0x93A8, 0xBC82}, //3296 #HANGUL SYLLABLE PIEUP YAE PHIEUPH + {0x93A9, 0xBC83}, //3297 #HANGUL SYLLABLE PIEUP YAE HIEUH + {0x93AA, 0xBC86}, //3298 #HANGUL SYLLABLE PIEUP EO SSANGKIYEOK + {0x93AB, 0xBC87}, //3299 #HANGUL SYLLABLE PIEUP EO KIYEOKSIOS + {0x93AC, 0xBC89}, //3300 #HANGUL SYLLABLE PIEUP EO NIEUNCIEUC + {0x93AD, 0xBC8A}, //3301 #HANGUL SYLLABLE PIEUP EO NIEUNHIEUH + {0x93AE, 0xBC8D}, //3302 #HANGUL SYLLABLE PIEUP EO RIEULKIYEOK + {0x93AF, 0xBC8F}, //3303 #HANGUL SYLLABLE PIEUP EO RIEULPIEUP + {0x93B0, 0xBC90}, //3304 #HANGUL SYLLABLE PIEUP EO RIEULSIOS + {0x93B1, 0xBC91}, //3305 #HANGUL SYLLABLE PIEUP EO RIEULTHIEUTH + {0x93B2, 0xBC92}, //3306 #HANGUL SYLLABLE PIEUP EO RIEULPHIEUPH + {0x93B3, 0xBC93}, //3307 #HANGUL SYLLABLE PIEUP EO RIEULHIEUH + {0x93B4, 0xBC96}, //3308 #HANGUL SYLLABLE PIEUP EO PIEUPSIOS + {0x93B5, 0xBC98}, //3309 #HANGUL SYLLABLE PIEUP EO SSANGSIOS + {0x93B6, 0xBC9B}, //3310 #HANGUL SYLLABLE PIEUP EO CHIEUCH + {0x93B7, 0xBC9C}, //3311 #HANGUL SYLLABLE PIEUP EO KHIEUKH + {0x93B8, 0xBC9D}, //3312 #HANGUL SYLLABLE PIEUP EO THIEUTH + {0x93B9, 0xBC9E}, //3313 #HANGUL SYLLABLE PIEUP EO PHIEUPH + {0x93BA, 0xBC9F}, //3314 #HANGUL SYLLABLE PIEUP EO HIEUH + {0x93BB, 0xBCA2}, //3315 #HANGUL SYLLABLE PIEUP E SSANGKIYEOK + {0x93BC, 0xBCA3}, //3316 #HANGUL SYLLABLE PIEUP E KIYEOKSIOS + {0x93BD, 0xBCA5}, //3317 #HANGUL SYLLABLE PIEUP E NIEUNCIEUC + {0x93BE, 0xBCA6}, //3318 #HANGUL SYLLABLE PIEUP E NIEUNHIEUH + {0x93BF, 0xBCA9}, //3319 #HANGUL SYLLABLE PIEUP E RIEULKIYEOK + {0x93C0, 0xBCAA}, //3320 #HANGUL SYLLABLE PIEUP E RIEULMIEUM + {0x93C1, 0xBCAB}, //3321 #HANGUL SYLLABLE PIEUP E RIEULPIEUP + {0x93C2, 0xBCAC}, //3322 #HANGUL SYLLABLE PIEUP E RIEULSIOS + {0x93C3, 0xBCAD}, //3323 #HANGUL SYLLABLE PIEUP E RIEULTHIEUTH + {0x93C4, 0xBCAE}, //3324 #HANGUL SYLLABLE PIEUP E RIEULPHIEUPH + {0x93C5, 0xBCAF}, //3325 #HANGUL SYLLABLE PIEUP E RIEULHIEUH + {0x93C6, 0xBCB2}, //3326 #HANGUL SYLLABLE PIEUP E PIEUPSIOS + {0x93C7, 0xBCB6}, //3327 #HANGUL SYLLABLE PIEUP E CIEUC + {0x93C8, 0xBCB7}, //3328 #HANGUL SYLLABLE PIEUP E CHIEUCH + {0x93C9, 0xBCB8}, //3329 #HANGUL SYLLABLE PIEUP E KHIEUKH + {0x93CA, 0xBCB9}, //3330 #HANGUL SYLLABLE PIEUP E THIEUTH + {0x93CB, 0xBCBA}, //3331 #HANGUL SYLLABLE PIEUP E PHIEUPH + {0x93CC, 0xBCBB}, //3332 #HANGUL SYLLABLE PIEUP E HIEUH + {0x93CD, 0xBCBE}, //3333 #HANGUL SYLLABLE PIEUP YEO SSANGKIYEOK + {0x93CE, 0xBCBF}, //3334 #HANGUL SYLLABLE PIEUP YEO KIYEOKSIOS + {0x93CF, 0xBCC1}, //3335 #HANGUL SYLLABLE PIEUP YEO NIEUNCIEUC + {0x93D0, 0xBCC2}, //3336 #HANGUL SYLLABLE PIEUP YEO NIEUNHIEUH + {0x93D1, 0xBCC3}, //3337 #HANGUL SYLLABLE PIEUP YEO TIKEUT + {0x93D2, 0xBCC5}, //3338 #HANGUL SYLLABLE PIEUP YEO RIEULKIYEOK + {0x93D3, 0xBCC6}, //3339 #HANGUL SYLLABLE PIEUP YEO RIEULMIEUM + {0x93D4, 0xBCC7}, //3340 #HANGUL SYLLABLE PIEUP YEO RIEULPIEUP + {0x93D5, 0xBCC8}, //3341 #HANGUL SYLLABLE PIEUP YEO RIEULSIOS + {0x93D6, 0xBCC9}, //3342 #HANGUL SYLLABLE PIEUP YEO RIEULTHIEUTH + {0x93D7, 0xBCCA}, //3343 #HANGUL SYLLABLE PIEUP YEO RIEULPHIEUPH + {0x93D8, 0xBCCB}, //3344 #HANGUL SYLLABLE PIEUP YEO RIEULHIEUH + {0x93D9, 0xBCCC}, //3345 #HANGUL SYLLABLE PIEUP YEO MIEUM + {0x93DA, 0xBCCE}, //3346 #HANGUL SYLLABLE PIEUP YEO PIEUPSIOS + {0x93DB, 0xBCD2}, //3347 #HANGUL SYLLABLE PIEUP YEO CIEUC + {0x93DC, 0xBCD3}, //3348 #HANGUL SYLLABLE PIEUP YEO CHIEUCH + {0x93DD, 0xBCD4}, //3349 #HANGUL SYLLABLE PIEUP YEO KHIEUKH + {0x93DE, 0xBCD6}, //3350 #HANGUL SYLLABLE PIEUP YEO PHIEUPH + {0x93DF, 0xBCD7}, //3351 #HANGUL SYLLABLE PIEUP YEO HIEUH + {0x93E0, 0xBCD9}, //3352 #HANGUL SYLLABLE PIEUP YE KIYEOK + {0x93E1, 0xBCDA}, //3353 #HANGUL SYLLABLE PIEUP YE SSANGKIYEOK + {0x93E2, 0xBCDB}, //3354 #HANGUL SYLLABLE PIEUP YE KIYEOKSIOS + {0x93E3, 0xBCDD}, //3355 #HANGUL SYLLABLE PIEUP YE NIEUNCIEUC + {0x93E4, 0xBCDE}, //3356 #HANGUL SYLLABLE PIEUP YE NIEUNHIEUH + {0x93E5, 0xBCDF}, //3357 #HANGUL SYLLABLE PIEUP YE TIKEUT + {0x93E6, 0xBCE0}, //3358 #HANGUL SYLLABLE PIEUP YE RIEUL + {0x93E7, 0xBCE1}, //3359 #HANGUL SYLLABLE PIEUP YE RIEULKIYEOK + {0x93E8, 0xBCE2}, //3360 #HANGUL SYLLABLE PIEUP YE RIEULMIEUM + {0x93E9, 0xBCE3}, //3361 #HANGUL SYLLABLE PIEUP YE RIEULPIEUP + {0x93EA, 0xBCE4}, //3362 #HANGUL SYLLABLE PIEUP YE RIEULSIOS + {0x93EB, 0xBCE5}, //3363 #HANGUL SYLLABLE PIEUP YE RIEULTHIEUTH + {0x93EC, 0xBCE6}, //3364 #HANGUL SYLLABLE PIEUP YE RIEULPHIEUPH + {0x93ED, 0xBCE7}, //3365 #HANGUL SYLLABLE PIEUP YE RIEULHIEUH + {0x93EE, 0xBCE8}, //3366 #HANGUL SYLLABLE PIEUP YE MIEUM + {0x93EF, 0xBCE9}, //3367 #HANGUL SYLLABLE PIEUP YE PIEUP + {0x93F0, 0xBCEA}, //3368 #HANGUL SYLLABLE PIEUP YE PIEUPSIOS + {0x93F1, 0xBCEB}, //3369 #HANGUL SYLLABLE PIEUP YE SIOS + {0x93F2, 0xBCEC}, //3370 #HANGUL SYLLABLE PIEUP YE SSANGSIOS + {0x93F3, 0xBCED}, //3371 #HANGUL SYLLABLE PIEUP YE IEUNG + {0x93F4, 0xBCEE}, //3372 #HANGUL SYLLABLE PIEUP YE CIEUC + {0x93F5, 0xBCEF}, //3373 #HANGUL SYLLABLE PIEUP YE CHIEUCH + {0x93F6, 0xBCF0}, //3374 #HANGUL SYLLABLE PIEUP YE KHIEUKH + {0x93F7, 0xBCF1}, //3375 #HANGUL SYLLABLE PIEUP YE THIEUTH + {0x93F8, 0xBCF2}, //3376 #HANGUL SYLLABLE PIEUP YE PHIEUPH + {0x93F9, 0xBCF3}, //3377 #HANGUL SYLLABLE PIEUP YE HIEUH + {0x93FA, 0xBCF7}, //3378 #HANGUL SYLLABLE PIEUP O KIYEOKSIOS + {0x93FB, 0xBCF9}, //3379 #HANGUL SYLLABLE PIEUP O NIEUNCIEUC + {0x93FC, 0xBCFA}, //3380 #HANGUL SYLLABLE PIEUP O NIEUNHIEUH + {0x93FD, 0xBCFB}, //3381 #HANGUL SYLLABLE PIEUP O TIKEUT + {0x93FE, 0xBCFD}, //3382 #HANGUL SYLLABLE PIEUP O RIEULKIYEOK + {0x9441, 0xBCFE}, //3383 #HANGUL SYLLABLE PIEUP O RIEULMIEUM + {0x9442, 0xBCFF}, //3384 #HANGUL SYLLABLE PIEUP O RIEULPIEUP + {0x9443, 0xBD00}, //3385 #HANGUL SYLLABLE PIEUP O RIEULSIOS + {0x9444, 0xBD01}, //3386 #HANGUL SYLLABLE PIEUP O RIEULTHIEUTH + {0x9445, 0xBD02}, //3387 #HANGUL SYLLABLE PIEUP O RIEULPHIEUPH + {0x9446, 0xBD03}, //3388 #HANGUL SYLLABLE PIEUP O RIEULHIEUH + {0x9447, 0xBD06}, //3389 #HANGUL SYLLABLE PIEUP O PIEUPSIOS + {0x9448, 0xBD08}, //3390 #HANGUL SYLLABLE PIEUP O SSANGSIOS + {0x9449, 0xBD0A}, //3391 #HANGUL SYLLABLE PIEUP O CIEUC + {0x944A, 0xBD0B}, //3392 #HANGUL SYLLABLE PIEUP O CHIEUCH + {0x944B, 0xBD0C}, //3393 #HANGUL SYLLABLE PIEUP O KHIEUKH + {0x944C, 0xBD0D}, //3394 #HANGUL SYLLABLE PIEUP O THIEUTH + {0x944D, 0xBD0E}, //3395 #HANGUL SYLLABLE PIEUP O PHIEUPH + {0x944E, 0xBD0F}, //3396 #HANGUL SYLLABLE PIEUP O HIEUH + {0x944F, 0xBD11}, //3397 #HANGUL SYLLABLE PIEUP WA KIYEOK + {0x9450, 0xBD12}, //3398 #HANGUL SYLLABLE PIEUP WA SSANGKIYEOK + {0x9451, 0xBD13}, //3399 #HANGUL SYLLABLE PIEUP WA KIYEOKSIOS + {0x9452, 0xBD15}, //3400 #HANGUL SYLLABLE PIEUP WA NIEUNCIEUC + {0x9453, 0xBD16}, //3401 #HANGUL SYLLABLE PIEUP WA NIEUNHIEUH + {0x9454, 0xBD17}, //3402 #HANGUL SYLLABLE PIEUP WA TIKEUT + {0x9455, 0xBD18}, //3403 #HANGUL SYLLABLE PIEUP WA RIEUL + {0x9456, 0xBD19}, //3404 #HANGUL SYLLABLE PIEUP WA RIEULKIYEOK + {0x9457, 0xBD1A}, //3405 #HANGUL SYLLABLE PIEUP WA RIEULMIEUM + {0x9458, 0xBD1B}, //3406 #HANGUL SYLLABLE PIEUP WA RIEULPIEUP + {0x9459, 0xBD1C}, //3407 #HANGUL SYLLABLE PIEUP WA RIEULSIOS + {0x945A, 0xBD1D}, //3408 #HANGUL SYLLABLE PIEUP WA RIEULTHIEUTH + {0x9461, 0xBD1E}, //3409 #HANGUL SYLLABLE PIEUP WA RIEULPHIEUPH + {0x9462, 0xBD1F}, //3410 #HANGUL SYLLABLE PIEUP WA RIEULHIEUH + {0x9463, 0xBD20}, //3411 #HANGUL SYLLABLE PIEUP WA MIEUM + {0x9464, 0xBD21}, //3412 #HANGUL SYLLABLE PIEUP WA PIEUP + {0x9465, 0xBD22}, //3413 #HANGUL SYLLABLE PIEUP WA PIEUPSIOS + {0x9466, 0xBD23}, //3414 #HANGUL SYLLABLE PIEUP WA SIOS + {0x9467, 0xBD25}, //3415 #HANGUL SYLLABLE PIEUP WA IEUNG + {0x9468, 0xBD26}, //3416 #HANGUL SYLLABLE PIEUP WA CIEUC + {0x9469, 0xBD27}, //3417 #HANGUL SYLLABLE PIEUP WA CHIEUCH + {0x946A, 0xBD28}, //3418 #HANGUL SYLLABLE PIEUP WA KHIEUKH + {0x946B, 0xBD29}, //3419 #HANGUL SYLLABLE PIEUP WA THIEUTH + {0x946C, 0xBD2A}, //3420 #HANGUL SYLLABLE PIEUP WA PHIEUPH + {0x946D, 0xBD2B}, //3421 #HANGUL SYLLABLE PIEUP WA HIEUH + {0x946E, 0xBD2D}, //3422 #HANGUL SYLLABLE PIEUP WAE KIYEOK + {0x946F, 0xBD2E}, //3423 #HANGUL SYLLABLE PIEUP WAE SSANGKIYEOK + {0x9470, 0xBD2F}, //3424 #HANGUL SYLLABLE PIEUP WAE KIYEOKSIOS + {0x9471, 0xBD30}, //3425 #HANGUL SYLLABLE PIEUP WAE NIEUN + {0x9472, 0xBD31}, //3426 #HANGUL SYLLABLE PIEUP WAE NIEUNCIEUC + {0x9473, 0xBD32}, //3427 #HANGUL SYLLABLE PIEUP WAE NIEUNHIEUH + {0x9474, 0xBD33}, //3428 #HANGUL SYLLABLE PIEUP WAE TIKEUT + {0x9475, 0xBD34}, //3429 #HANGUL SYLLABLE PIEUP WAE RIEUL + {0x9476, 0xBD35}, //3430 #HANGUL SYLLABLE PIEUP WAE RIEULKIYEOK + {0x9477, 0xBD36}, //3431 #HANGUL SYLLABLE PIEUP WAE RIEULMIEUM + {0x9478, 0xBD37}, //3432 #HANGUL SYLLABLE PIEUP WAE RIEULPIEUP + {0x9479, 0xBD38}, //3433 #HANGUL SYLLABLE PIEUP WAE RIEULSIOS + {0x947A, 0xBD39}, //3434 #HANGUL SYLLABLE PIEUP WAE RIEULTHIEUTH + {0x9481, 0xBD3A}, //3435 #HANGUL SYLLABLE PIEUP WAE RIEULPHIEUPH + {0x9482, 0xBD3B}, //3436 #HANGUL SYLLABLE PIEUP WAE RIEULHIEUH + {0x9483, 0xBD3C}, //3437 #HANGUL SYLLABLE PIEUP WAE MIEUM + {0x9484, 0xBD3D}, //3438 #HANGUL SYLLABLE PIEUP WAE PIEUP + {0x9485, 0xBD3E}, //3439 #HANGUL SYLLABLE PIEUP WAE PIEUPSIOS + {0x9486, 0xBD3F}, //3440 #HANGUL SYLLABLE PIEUP WAE SIOS + {0x9487, 0xBD41}, //3441 #HANGUL SYLLABLE PIEUP WAE IEUNG + {0x9488, 0xBD42}, //3442 #HANGUL SYLLABLE PIEUP WAE CIEUC + {0x9489, 0xBD43}, //3443 #HANGUL SYLLABLE PIEUP WAE CHIEUCH + {0x948A, 0xBD44}, //3444 #HANGUL SYLLABLE PIEUP WAE KHIEUKH + {0x948B, 0xBD45}, //3445 #HANGUL SYLLABLE PIEUP WAE THIEUTH + {0x948C, 0xBD46}, //3446 #HANGUL SYLLABLE PIEUP WAE PHIEUPH + {0x948D, 0xBD47}, //3447 #HANGUL SYLLABLE PIEUP WAE HIEUH + {0x948E, 0xBD4A}, //3448 #HANGUL SYLLABLE PIEUP OE SSANGKIYEOK + {0x948F, 0xBD4B}, //3449 #HANGUL SYLLABLE PIEUP OE KIYEOKSIOS + {0x9490, 0xBD4D}, //3450 #HANGUL SYLLABLE PIEUP OE NIEUNCIEUC + {0x9491, 0xBD4E}, //3451 #HANGUL SYLLABLE PIEUP OE NIEUNHIEUH + {0x9492, 0xBD4F}, //3452 #HANGUL SYLLABLE PIEUP OE TIKEUT + {0x9493, 0xBD51}, //3453 #HANGUL SYLLABLE PIEUP OE RIEULKIYEOK + {0x9494, 0xBD52}, //3454 #HANGUL SYLLABLE PIEUP OE RIEULMIEUM + {0x9495, 0xBD53}, //3455 #HANGUL SYLLABLE PIEUP OE RIEULPIEUP + {0x9496, 0xBD54}, //3456 #HANGUL SYLLABLE PIEUP OE RIEULSIOS + {0x9497, 0xBD55}, //3457 #HANGUL SYLLABLE PIEUP OE RIEULTHIEUTH + {0x9498, 0xBD56}, //3458 #HANGUL SYLLABLE PIEUP OE RIEULPHIEUPH + {0x9499, 0xBD57}, //3459 #HANGUL SYLLABLE PIEUP OE RIEULHIEUH + {0x949A, 0xBD5A}, //3460 #HANGUL SYLLABLE PIEUP OE PIEUPSIOS + {0x949B, 0xBD5B}, //3461 #HANGUL SYLLABLE PIEUP OE SIOS + {0x949C, 0xBD5C}, //3462 #HANGUL SYLLABLE PIEUP OE SSANGSIOS + {0x949D, 0xBD5D}, //3463 #HANGUL SYLLABLE PIEUP OE IEUNG + {0x949E, 0xBD5E}, //3464 #HANGUL SYLLABLE PIEUP OE CIEUC + {0x949F, 0xBD5F}, //3465 #HANGUL SYLLABLE PIEUP OE CHIEUCH + {0x94A0, 0xBD60}, //3466 #HANGUL SYLLABLE PIEUP OE KHIEUKH + {0x94A1, 0xBD61}, //3467 #HANGUL SYLLABLE PIEUP OE THIEUTH + {0x94A2, 0xBD62}, //3468 #HANGUL SYLLABLE PIEUP OE PHIEUPH + {0x94A3, 0xBD63}, //3469 #HANGUL SYLLABLE PIEUP OE HIEUH + {0x94A4, 0xBD65}, //3470 #HANGUL SYLLABLE PIEUP YO KIYEOK + {0x94A5, 0xBD66}, //3471 #HANGUL SYLLABLE PIEUP YO SSANGKIYEOK + {0x94A6, 0xBD67}, //3472 #HANGUL SYLLABLE PIEUP YO KIYEOKSIOS + {0x94A7, 0xBD69}, //3473 #HANGUL SYLLABLE PIEUP YO NIEUNCIEUC + {0x94A8, 0xBD6A}, //3474 #HANGUL SYLLABLE PIEUP YO NIEUNHIEUH + {0x94A9, 0xBD6B}, //3475 #HANGUL SYLLABLE PIEUP YO TIKEUT + {0x94AA, 0xBD6C}, //3476 #HANGUL SYLLABLE PIEUP YO RIEUL + {0x94AB, 0xBD6D}, //3477 #HANGUL SYLLABLE PIEUP YO RIEULKIYEOK + {0x94AC, 0xBD6E}, //3478 #HANGUL SYLLABLE PIEUP YO RIEULMIEUM + {0x94AD, 0xBD6F}, //3479 #HANGUL SYLLABLE PIEUP YO RIEULPIEUP + {0x94AE, 0xBD70}, //3480 #HANGUL SYLLABLE PIEUP YO RIEULSIOS + {0x94AF, 0xBD71}, //3481 #HANGUL SYLLABLE PIEUP YO RIEULTHIEUTH + {0x94B0, 0xBD72}, //3482 #HANGUL SYLLABLE PIEUP YO RIEULPHIEUPH + {0x94B1, 0xBD73}, //3483 #HANGUL SYLLABLE PIEUP YO RIEULHIEUH + {0x94B2, 0xBD74}, //3484 #HANGUL SYLLABLE PIEUP YO MIEUM + {0x94B3, 0xBD75}, //3485 #HANGUL SYLLABLE PIEUP YO PIEUP + {0x94B4, 0xBD76}, //3486 #HANGUL SYLLABLE PIEUP YO PIEUPSIOS + {0x94B5, 0xBD77}, //3487 #HANGUL SYLLABLE PIEUP YO SIOS + {0x94B6, 0xBD78}, //3488 #HANGUL SYLLABLE PIEUP YO SSANGSIOS + {0x94B7, 0xBD79}, //3489 #HANGUL SYLLABLE PIEUP YO IEUNG + {0x94B8, 0xBD7A}, //3490 #HANGUL SYLLABLE PIEUP YO CIEUC + {0x94B9, 0xBD7B}, //3491 #HANGUL SYLLABLE PIEUP YO CHIEUCH + {0x94BA, 0xBD7C}, //3492 #HANGUL SYLLABLE PIEUP YO KHIEUKH + {0x94BB, 0xBD7D}, //3493 #HANGUL SYLLABLE PIEUP YO THIEUTH + {0x94BC, 0xBD7E}, //3494 #HANGUL SYLLABLE PIEUP YO PHIEUPH + {0x94BD, 0xBD7F}, //3495 #HANGUL SYLLABLE PIEUP YO HIEUH + {0x94BE, 0xBD82}, //3496 #HANGUL SYLLABLE PIEUP U SSANGKIYEOK + {0x94BF, 0xBD83}, //3497 #HANGUL SYLLABLE PIEUP U KIYEOKSIOS + {0x94C0, 0xBD85}, //3498 #HANGUL SYLLABLE PIEUP U NIEUNCIEUC + {0x94C1, 0xBD86}, //3499 #HANGUL SYLLABLE PIEUP U NIEUNHIEUH + {0x94C2, 0xBD8B}, //3500 #HANGUL SYLLABLE PIEUP U RIEULPIEUP + {0x94C3, 0xBD8C}, //3501 #HANGUL SYLLABLE PIEUP U RIEULSIOS + {0x94C4, 0xBD8D}, //3502 #HANGUL SYLLABLE PIEUP U RIEULTHIEUTH + {0x94C5, 0xBD8E}, //3503 #HANGUL SYLLABLE PIEUP U RIEULPHIEUPH + {0x94C6, 0xBD8F}, //3504 #HANGUL SYLLABLE PIEUP U RIEULHIEUH + {0x94C7, 0xBD92}, //3505 #HANGUL SYLLABLE PIEUP U PIEUPSIOS + {0x94C8, 0xBD94}, //3506 #HANGUL SYLLABLE PIEUP U SSANGSIOS + {0x94C9, 0xBD96}, //3507 #HANGUL SYLLABLE PIEUP U CIEUC + {0x94CA, 0xBD97}, //3508 #HANGUL SYLLABLE PIEUP U CHIEUCH + {0x94CB, 0xBD98}, //3509 #HANGUL SYLLABLE PIEUP U KHIEUKH + {0x94CC, 0xBD9B}, //3510 #HANGUL SYLLABLE PIEUP U HIEUH + {0x94CD, 0xBD9D}, //3511 #HANGUL SYLLABLE PIEUP WEO KIYEOK + {0x94CE, 0xBD9E}, //3512 #HANGUL SYLLABLE PIEUP WEO SSANGKIYEOK + {0x94CF, 0xBD9F}, //3513 #HANGUL SYLLABLE PIEUP WEO KIYEOKSIOS + {0x94D0, 0xBDA0}, //3514 #HANGUL SYLLABLE PIEUP WEO NIEUN + {0x94D1, 0xBDA1}, //3515 #HANGUL SYLLABLE PIEUP WEO NIEUNCIEUC + {0x94D2, 0xBDA2}, //3516 #HANGUL SYLLABLE PIEUP WEO NIEUNHIEUH + {0x94D3, 0xBDA3}, //3517 #HANGUL SYLLABLE PIEUP WEO TIKEUT + {0x94D4, 0xBDA5}, //3518 #HANGUL SYLLABLE PIEUP WEO RIEULKIYEOK + {0x94D5, 0xBDA6}, //3519 #HANGUL SYLLABLE PIEUP WEO RIEULMIEUM + {0x94D6, 0xBDA7}, //3520 #HANGUL SYLLABLE PIEUP WEO RIEULPIEUP + {0x94D7, 0xBDA8}, //3521 #HANGUL SYLLABLE PIEUP WEO RIEULSIOS + {0x94D8, 0xBDA9}, //3522 #HANGUL SYLLABLE PIEUP WEO RIEULTHIEUTH + {0x94D9, 0xBDAA}, //3523 #HANGUL SYLLABLE PIEUP WEO RIEULPHIEUPH + {0x94DA, 0xBDAB}, //3524 #HANGUL SYLLABLE PIEUP WEO RIEULHIEUH + {0x94DB, 0xBDAC}, //3525 #HANGUL SYLLABLE PIEUP WEO MIEUM + {0x94DC, 0xBDAD}, //3526 #HANGUL SYLLABLE PIEUP WEO PIEUP + {0x94DD, 0xBDAE}, //3527 #HANGUL SYLLABLE PIEUP WEO PIEUPSIOS + {0x94DE, 0xBDAF}, //3528 #HANGUL SYLLABLE PIEUP WEO SIOS + {0x94DF, 0xBDB1}, //3529 #HANGUL SYLLABLE PIEUP WEO IEUNG + {0x94E0, 0xBDB2}, //3530 #HANGUL SYLLABLE PIEUP WEO CIEUC + {0x94E1, 0xBDB3}, //3531 #HANGUL SYLLABLE PIEUP WEO CHIEUCH + {0x94E2, 0xBDB4}, //3532 #HANGUL SYLLABLE PIEUP WEO KHIEUKH + {0x94E3, 0xBDB5}, //3533 #HANGUL SYLLABLE PIEUP WEO THIEUTH + {0x94E4, 0xBDB6}, //3534 #HANGUL SYLLABLE PIEUP WEO PHIEUPH + {0x94E5, 0xBDB7}, //3535 #HANGUL SYLLABLE PIEUP WEO HIEUH + {0x94E6, 0xBDB9}, //3536 #HANGUL SYLLABLE PIEUP WE KIYEOK + {0x94E7, 0xBDBA}, //3537 #HANGUL SYLLABLE PIEUP WE SSANGKIYEOK + {0x94E8, 0xBDBB}, //3538 #HANGUL SYLLABLE PIEUP WE KIYEOKSIOS + {0x94E9, 0xBDBC}, //3539 #HANGUL SYLLABLE PIEUP WE NIEUN + {0x94EA, 0xBDBD}, //3540 #HANGUL SYLLABLE PIEUP WE NIEUNCIEUC + {0x94EB, 0xBDBE}, //3541 #HANGUL SYLLABLE PIEUP WE NIEUNHIEUH + {0x94EC, 0xBDBF}, //3542 #HANGUL SYLLABLE PIEUP WE TIKEUT + {0x94ED, 0xBDC0}, //3543 #HANGUL SYLLABLE PIEUP WE RIEUL + {0x94EE, 0xBDC1}, //3544 #HANGUL SYLLABLE PIEUP WE RIEULKIYEOK + {0x94EF, 0xBDC2}, //3545 #HANGUL SYLLABLE PIEUP WE RIEULMIEUM + {0x94F0, 0xBDC3}, //3546 #HANGUL SYLLABLE PIEUP WE RIEULPIEUP + {0x94F1, 0xBDC4}, //3547 #HANGUL SYLLABLE PIEUP WE RIEULSIOS + {0x94F2, 0xBDC5}, //3548 #HANGUL SYLLABLE PIEUP WE RIEULTHIEUTH + {0x94F3, 0xBDC6}, //3549 #HANGUL SYLLABLE PIEUP WE RIEULPHIEUPH + {0x94F4, 0xBDC7}, //3550 #HANGUL SYLLABLE PIEUP WE RIEULHIEUH + {0x94F5, 0xBDC8}, //3551 #HANGUL SYLLABLE PIEUP WE MIEUM + {0x94F6, 0xBDC9}, //3552 #HANGUL SYLLABLE PIEUP WE PIEUP + {0x94F7, 0xBDCA}, //3553 #HANGUL SYLLABLE PIEUP WE PIEUPSIOS + {0x94F8, 0xBDCB}, //3554 #HANGUL SYLLABLE PIEUP WE SIOS + {0x94F9, 0xBDCC}, //3555 #HANGUL SYLLABLE PIEUP WE SSANGSIOS + {0x94FA, 0xBDCD}, //3556 #HANGUL SYLLABLE PIEUP WE IEUNG + {0x94FB, 0xBDCE}, //3557 #HANGUL SYLLABLE PIEUP WE CIEUC + {0x94FC, 0xBDCF}, //3558 #HANGUL SYLLABLE PIEUP WE CHIEUCH + {0x94FD, 0xBDD0}, //3559 #HANGUL SYLLABLE PIEUP WE KHIEUKH + {0x94FE, 0xBDD1}, //3560 #HANGUL SYLLABLE PIEUP WE THIEUTH + {0x9541, 0xBDD2}, //3561 #HANGUL SYLLABLE PIEUP WE PHIEUPH + {0x9542, 0xBDD3}, //3562 #HANGUL SYLLABLE PIEUP WE HIEUH + {0x9543, 0xBDD6}, //3563 #HANGUL SYLLABLE PIEUP WI SSANGKIYEOK + {0x9544, 0xBDD7}, //3564 #HANGUL SYLLABLE PIEUP WI KIYEOKSIOS + {0x9545, 0xBDD9}, //3565 #HANGUL SYLLABLE PIEUP WI NIEUNCIEUC + {0x9546, 0xBDDA}, //3566 #HANGUL SYLLABLE PIEUP WI NIEUNHIEUH + {0x9547, 0xBDDB}, //3567 #HANGUL SYLLABLE PIEUP WI TIKEUT + {0x9548, 0xBDDD}, //3568 #HANGUL SYLLABLE PIEUP WI RIEULKIYEOK + {0x9549, 0xBDDE}, //3569 #HANGUL SYLLABLE PIEUP WI RIEULMIEUM + {0x954A, 0xBDDF}, //3570 #HANGUL SYLLABLE PIEUP WI RIEULPIEUP + {0x954B, 0xBDE0}, //3571 #HANGUL SYLLABLE PIEUP WI RIEULSIOS + {0x954C, 0xBDE1}, //3572 #HANGUL SYLLABLE PIEUP WI RIEULTHIEUTH + {0x954D, 0xBDE2}, //3573 #HANGUL SYLLABLE PIEUP WI RIEULPHIEUPH + {0x954E, 0xBDE3}, //3574 #HANGUL SYLLABLE PIEUP WI RIEULHIEUH + {0x954F, 0xBDE4}, //3575 #HANGUL SYLLABLE PIEUP WI MIEUM + {0x9550, 0xBDE5}, //3576 #HANGUL SYLLABLE PIEUP WI PIEUP + {0x9551, 0xBDE6}, //3577 #HANGUL SYLLABLE PIEUP WI PIEUPSIOS + {0x9552, 0xBDE7}, //3578 #HANGUL SYLLABLE PIEUP WI SIOS + {0x9553, 0xBDE8}, //3579 #HANGUL SYLLABLE PIEUP WI SSANGSIOS + {0x9554, 0xBDEA}, //3580 #HANGUL SYLLABLE PIEUP WI CIEUC + {0x9555, 0xBDEB}, //3581 #HANGUL SYLLABLE PIEUP WI CHIEUCH + {0x9556, 0xBDEC}, //3582 #HANGUL SYLLABLE PIEUP WI KHIEUKH + {0x9557, 0xBDED}, //3583 #HANGUL SYLLABLE PIEUP WI THIEUTH + {0x9558, 0xBDEE}, //3584 #HANGUL SYLLABLE PIEUP WI PHIEUPH + {0x9559, 0xBDEF}, //3585 #HANGUL SYLLABLE PIEUP WI HIEUH + {0x955A, 0xBDF1}, //3586 #HANGUL SYLLABLE PIEUP YU KIYEOK + {0x9561, 0xBDF2}, //3587 #HANGUL SYLLABLE PIEUP YU SSANGKIYEOK + {0x9562, 0xBDF3}, //3588 #HANGUL SYLLABLE PIEUP YU KIYEOKSIOS + {0x9563, 0xBDF5}, //3589 #HANGUL SYLLABLE PIEUP YU NIEUNCIEUC + {0x9564, 0xBDF6}, //3590 #HANGUL SYLLABLE PIEUP YU NIEUNHIEUH + {0x9565, 0xBDF7}, //3591 #HANGUL SYLLABLE PIEUP YU TIKEUT + {0x9566, 0xBDF9}, //3592 #HANGUL SYLLABLE PIEUP YU RIEULKIYEOK + {0x9567, 0xBDFA}, //3593 #HANGUL SYLLABLE PIEUP YU RIEULMIEUM + {0x9568, 0xBDFB}, //3594 #HANGUL SYLLABLE PIEUP YU RIEULPIEUP + {0x9569, 0xBDFC}, //3595 #HANGUL SYLLABLE PIEUP YU RIEULSIOS + {0x956A, 0xBDFD}, //3596 #HANGUL SYLLABLE PIEUP YU RIEULTHIEUTH + {0x956B, 0xBDFE}, //3597 #HANGUL SYLLABLE PIEUP YU RIEULPHIEUPH + {0x956C, 0xBDFF}, //3598 #HANGUL SYLLABLE PIEUP YU RIEULHIEUH + {0x956D, 0xBE01}, //3599 #HANGUL SYLLABLE PIEUP YU PIEUP + {0x956E, 0xBE02}, //3600 #HANGUL SYLLABLE PIEUP YU PIEUPSIOS + {0x956F, 0xBE04}, //3601 #HANGUL SYLLABLE PIEUP YU SSANGSIOS + {0x9570, 0xBE06}, //3602 #HANGUL SYLLABLE PIEUP YU CIEUC + {0x9571, 0xBE07}, //3603 #HANGUL SYLLABLE PIEUP YU CHIEUCH + {0x9572, 0xBE08}, //3604 #HANGUL SYLLABLE PIEUP YU KHIEUKH + {0x9573, 0xBE09}, //3605 #HANGUL SYLLABLE PIEUP YU THIEUTH + {0x9574, 0xBE0A}, //3606 #HANGUL SYLLABLE PIEUP YU PHIEUPH + {0x9575, 0xBE0B}, //3607 #HANGUL SYLLABLE PIEUP YU HIEUH + {0x9576, 0xBE0E}, //3608 #HANGUL SYLLABLE PIEUP EU SSANGKIYEOK + {0x9577, 0xBE0F}, //3609 #HANGUL SYLLABLE PIEUP EU KIYEOKSIOS + {0x9578, 0xBE11}, //3610 #HANGUL SYLLABLE PIEUP EU NIEUNCIEUC + {0x9579, 0xBE12}, //3611 #HANGUL SYLLABLE PIEUP EU NIEUNHIEUH + {0x957A, 0xBE13}, //3612 #HANGUL SYLLABLE PIEUP EU TIKEUT + {0x9581, 0xBE15}, //3613 #HANGUL SYLLABLE PIEUP EU RIEULKIYEOK + {0x9582, 0xBE16}, //3614 #HANGUL SYLLABLE PIEUP EU RIEULMIEUM + {0x9583, 0xBE17}, //3615 #HANGUL SYLLABLE PIEUP EU RIEULPIEUP + {0x9584, 0xBE18}, //3616 #HANGUL SYLLABLE PIEUP EU RIEULSIOS + {0x9585, 0xBE19}, //3617 #HANGUL SYLLABLE PIEUP EU RIEULTHIEUTH + {0x9586, 0xBE1A}, //3618 #HANGUL SYLLABLE PIEUP EU RIEULPHIEUPH + {0x9587, 0xBE1B}, //3619 #HANGUL SYLLABLE PIEUP EU RIEULHIEUH + {0x9588, 0xBE1E}, //3620 #HANGUL SYLLABLE PIEUP EU PIEUPSIOS + {0x9589, 0xBE20}, //3621 #HANGUL SYLLABLE PIEUP EU SSANGSIOS + {0x958A, 0xBE21}, //3622 #HANGUL SYLLABLE PIEUP EU IEUNG + {0x958B, 0xBE22}, //3623 #HANGUL SYLLABLE PIEUP EU CIEUC + {0x958C, 0xBE23}, //3624 #HANGUL SYLLABLE PIEUP EU CHIEUCH + {0x958D, 0xBE24}, //3625 #HANGUL SYLLABLE PIEUP EU KHIEUKH + {0x958E, 0xBE25}, //3626 #HANGUL SYLLABLE PIEUP EU THIEUTH + {0x958F, 0xBE26}, //3627 #HANGUL SYLLABLE PIEUP EU PHIEUPH + {0x9590, 0xBE27}, //3628 #HANGUL SYLLABLE PIEUP EU HIEUH + {0x9591, 0xBE28}, //3629 #HANGUL SYLLABLE PIEUP YI + {0x9592, 0xBE29}, //3630 #HANGUL SYLLABLE PIEUP YI KIYEOK + {0x9593, 0xBE2A}, //3631 #HANGUL SYLLABLE PIEUP YI SSANGKIYEOK + {0x9594, 0xBE2B}, //3632 #HANGUL SYLLABLE PIEUP YI KIYEOKSIOS + {0x9595, 0xBE2C}, //3633 #HANGUL SYLLABLE PIEUP YI NIEUN + {0x9596, 0xBE2D}, //3634 #HANGUL SYLLABLE PIEUP YI NIEUNCIEUC + {0x9597, 0xBE2E}, //3635 #HANGUL SYLLABLE PIEUP YI NIEUNHIEUH + {0x9598, 0xBE2F}, //3636 #HANGUL SYLLABLE PIEUP YI TIKEUT + {0x9599, 0xBE30}, //3637 #HANGUL SYLLABLE PIEUP YI RIEUL + {0x959A, 0xBE31}, //3638 #HANGUL SYLLABLE PIEUP YI RIEULKIYEOK + {0x959B, 0xBE32}, //3639 #HANGUL SYLLABLE PIEUP YI RIEULMIEUM + {0x959C, 0xBE33}, //3640 #HANGUL SYLLABLE PIEUP YI RIEULPIEUP + {0x959D, 0xBE34}, //3641 #HANGUL SYLLABLE PIEUP YI RIEULSIOS + {0x959E, 0xBE35}, //3642 #HANGUL SYLLABLE PIEUP YI RIEULTHIEUTH + {0x959F, 0xBE36}, //3643 #HANGUL SYLLABLE PIEUP YI RIEULPHIEUPH + {0x95A0, 0xBE37}, //3644 #HANGUL SYLLABLE PIEUP YI RIEULHIEUH + {0x95A1, 0xBE38}, //3645 #HANGUL SYLLABLE PIEUP YI MIEUM + {0x95A2, 0xBE39}, //3646 #HANGUL SYLLABLE PIEUP YI PIEUP + {0x95A3, 0xBE3A}, //3647 #HANGUL SYLLABLE PIEUP YI PIEUPSIOS + {0x95A4, 0xBE3B}, //3648 #HANGUL SYLLABLE PIEUP YI SIOS + {0x95A5, 0xBE3C}, //3649 #HANGUL SYLLABLE PIEUP YI SSANGSIOS + {0x95A6, 0xBE3D}, //3650 #HANGUL SYLLABLE PIEUP YI IEUNG + {0x95A7, 0xBE3E}, //3651 #HANGUL SYLLABLE PIEUP YI CIEUC + {0x95A8, 0xBE3F}, //3652 #HANGUL SYLLABLE PIEUP YI CHIEUCH + {0x95A9, 0xBE40}, //3653 #HANGUL SYLLABLE PIEUP YI KHIEUKH + {0x95AA, 0xBE41}, //3654 #HANGUL SYLLABLE PIEUP YI THIEUTH + {0x95AB, 0xBE42}, //3655 #HANGUL SYLLABLE PIEUP YI PHIEUPH + {0x95AC, 0xBE43}, //3656 #HANGUL SYLLABLE PIEUP YI HIEUH + {0x95AD, 0xBE46}, //3657 #HANGUL SYLLABLE PIEUP I SSANGKIYEOK + {0x95AE, 0xBE47}, //3658 #HANGUL SYLLABLE PIEUP I KIYEOKSIOS + {0x95AF, 0xBE49}, //3659 #HANGUL SYLLABLE PIEUP I NIEUNCIEUC + {0x95B0, 0xBE4A}, //3660 #HANGUL SYLLABLE PIEUP I NIEUNHIEUH + {0x95B1, 0xBE4B}, //3661 #HANGUL SYLLABLE PIEUP I TIKEUT + {0x95B2, 0xBE4D}, //3662 #HANGUL SYLLABLE PIEUP I RIEULKIYEOK + {0x95B3, 0xBE4F}, //3663 #HANGUL SYLLABLE PIEUP I RIEULPIEUP + {0x95B4, 0xBE50}, //3664 #HANGUL SYLLABLE PIEUP I RIEULSIOS + {0x95B5, 0xBE51}, //3665 #HANGUL SYLLABLE PIEUP I RIEULTHIEUTH + {0x95B6, 0xBE52}, //3666 #HANGUL SYLLABLE PIEUP I RIEULPHIEUPH + {0x95B7, 0xBE53}, //3667 #HANGUL SYLLABLE PIEUP I RIEULHIEUH + {0x95B8, 0xBE56}, //3668 #HANGUL SYLLABLE PIEUP I PIEUPSIOS + {0x95B9, 0xBE58}, //3669 #HANGUL SYLLABLE PIEUP I SSANGSIOS + {0x95BA, 0xBE5C}, //3670 #HANGUL SYLLABLE PIEUP I KHIEUKH + {0x95BB, 0xBE5D}, //3671 #HANGUL SYLLABLE PIEUP I THIEUTH + {0x95BC, 0xBE5E}, //3672 #HANGUL SYLLABLE PIEUP I PHIEUPH + {0x95BD, 0xBE5F}, //3673 #HANGUL SYLLABLE PIEUP I HIEUH + {0x95BE, 0xBE62}, //3674 #HANGUL SYLLABLE SSANGPIEUP A SSANGKIYEOK + {0x95BF, 0xBE63}, //3675 #HANGUL SYLLABLE SSANGPIEUP A KIYEOKSIOS + {0x95C0, 0xBE65}, //3676 #HANGUL SYLLABLE SSANGPIEUP A NIEUNCIEUC + {0x95C1, 0xBE66}, //3677 #HANGUL SYLLABLE SSANGPIEUP A NIEUNHIEUH + {0x95C2, 0xBE67}, //3678 #HANGUL SYLLABLE SSANGPIEUP A TIKEUT + {0x95C3, 0xBE69}, //3679 #HANGUL SYLLABLE SSANGPIEUP A RIEULKIYEOK + {0x95C4, 0xBE6B}, //3680 #HANGUL SYLLABLE SSANGPIEUP A RIEULPIEUP + {0x95C5, 0xBE6C}, //3681 #HANGUL SYLLABLE SSANGPIEUP A RIEULSIOS + {0x95C6, 0xBE6D}, //3682 #HANGUL SYLLABLE SSANGPIEUP A RIEULTHIEUTH + {0x95C7, 0xBE6E}, //3683 #HANGUL SYLLABLE SSANGPIEUP A RIEULPHIEUPH + {0x95C8, 0xBE6F}, //3684 #HANGUL SYLLABLE SSANGPIEUP A RIEULHIEUH + {0x95C9, 0xBE72}, //3685 #HANGUL SYLLABLE SSANGPIEUP A PIEUPSIOS + {0x95CA, 0xBE76}, //3686 #HANGUL SYLLABLE SSANGPIEUP A CIEUC + {0x95CB, 0xBE77}, //3687 #HANGUL SYLLABLE SSANGPIEUP A CHIEUCH + {0x95CC, 0xBE78}, //3688 #HANGUL SYLLABLE SSANGPIEUP A KHIEUKH + {0x95CD, 0xBE79}, //3689 #HANGUL SYLLABLE SSANGPIEUP A THIEUTH + {0x95CE, 0xBE7A}, //3690 #HANGUL SYLLABLE SSANGPIEUP A PHIEUPH + {0x95CF, 0xBE7E}, //3691 #HANGUL SYLLABLE SSANGPIEUP AE SSANGKIYEOK + {0x95D0, 0xBE7F}, //3692 #HANGUL SYLLABLE SSANGPIEUP AE KIYEOKSIOS + {0x95D1, 0xBE81}, //3693 #HANGUL SYLLABLE SSANGPIEUP AE NIEUNCIEUC + {0x95D2, 0xBE82}, //3694 #HANGUL SYLLABLE SSANGPIEUP AE NIEUNHIEUH + {0x95D3, 0xBE83}, //3695 #HANGUL SYLLABLE SSANGPIEUP AE TIKEUT + {0x95D4, 0xBE85}, //3696 #HANGUL SYLLABLE SSANGPIEUP AE RIEULKIYEOK + {0x95D5, 0xBE86}, //3697 #HANGUL SYLLABLE SSANGPIEUP AE RIEULMIEUM + {0x95D6, 0xBE87}, //3698 #HANGUL SYLLABLE SSANGPIEUP AE RIEULPIEUP + {0x95D7, 0xBE88}, //3699 #HANGUL SYLLABLE SSANGPIEUP AE RIEULSIOS + {0x95D8, 0xBE89}, //3700 #HANGUL SYLLABLE SSANGPIEUP AE RIEULTHIEUTH + {0x95D9, 0xBE8A}, //3701 #HANGUL SYLLABLE SSANGPIEUP AE RIEULPHIEUPH + {0x95DA, 0xBE8B}, //3702 #HANGUL SYLLABLE SSANGPIEUP AE RIEULHIEUH + {0x95DB, 0xBE8E}, //3703 #HANGUL SYLLABLE SSANGPIEUP AE PIEUPSIOS + {0x95DC, 0xBE92}, //3704 #HANGUL SYLLABLE SSANGPIEUP AE CIEUC + {0x95DD, 0xBE93}, //3705 #HANGUL SYLLABLE SSANGPIEUP AE CHIEUCH + {0x95DE, 0xBE94}, //3706 #HANGUL SYLLABLE SSANGPIEUP AE KHIEUKH + {0x95DF, 0xBE95}, //3707 #HANGUL SYLLABLE SSANGPIEUP AE THIEUTH + {0x95E0, 0xBE96}, //3708 #HANGUL SYLLABLE SSANGPIEUP AE PHIEUPH + {0x95E1, 0xBE97}, //3709 #HANGUL SYLLABLE SSANGPIEUP AE HIEUH + {0x95E2, 0xBE9A}, //3710 #HANGUL SYLLABLE SSANGPIEUP YA SSANGKIYEOK + {0x95E3, 0xBE9B}, //3711 #HANGUL SYLLABLE SSANGPIEUP YA KIYEOKSIOS + {0x95E4, 0xBE9C}, //3712 #HANGUL SYLLABLE SSANGPIEUP YA NIEUN + {0x95E5, 0xBE9D}, //3713 #HANGUL SYLLABLE SSANGPIEUP YA NIEUNCIEUC + {0x95E6, 0xBE9E}, //3714 #HANGUL SYLLABLE SSANGPIEUP YA NIEUNHIEUH + {0x95E7, 0xBE9F}, //3715 #HANGUL SYLLABLE SSANGPIEUP YA TIKEUT + {0x95E8, 0xBEA0}, //3716 #HANGUL SYLLABLE SSANGPIEUP YA RIEUL + {0x95E9, 0xBEA1}, //3717 #HANGUL SYLLABLE SSANGPIEUP YA RIEULKIYEOK + {0x95EA, 0xBEA2}, //3718 #HANGUL SYLLABLE SSANGPIEUP YA RIEULMIEUM + {0x95EB, 0xBEA3}, //3719 #HANGUL SYLLABLE SSANGPIEUP YA RIEULPIEUP + {0x95EC, 0xBEA4}, //3720 #HANGUL SYLLABLE SSANGPIEUP YA RIEULSIOS + {0x95ED, 0xBEA5}, //3721 #HANGUL SYLLABLE SSANGPIEUP YA RIEULTHIEUTH + {0x95EE, 0xBEA6}, //3722 #HANGUL SYLLABLE SSANGPIEUP YA RIEULPHIEUPH + {0x95EF, 0xBEA7}, //3723 #HANGUL SYLLABLE SSANGPIEUP YA RIEULHIEUH + {0x95F0, 0xBEA9}, //3724 #HANGUL SYLLABLE SSANGPIEUP YA PIEUP + {0x95F1, 0xBEAA}, //3725 #HANGUL SYLLABLE SSANGPIEUP YA PIEUPSIOS + {0x95F2, 0xBEAB}, //3726 #HANGUL SYLLABLE SSANGPIEUP YA SIOS + {0x95F3, 0xBEAC}, //3727 #HANGUL SYLLABLE SSANGPIEUP YA SSANGSIOS + {0x95F4, 0xBEAD}, //3728 #HANGUL SYLLABLE SSANGPIEUP YA IEUNG + {0x95F5, 0xBEAE}, //3729 #HANGUL SYLLABLE SSANGPIEUP YA CIEUC + {0x95F6, 0xBEAF}, //3730 #HANGUL SYLLABLE SSANGPIEUP YA CHIEUCH + {0x95F7, 0xBEB0}, //3731 #HANGUL SYLLABLE SSANGPIEUP YA KHIEUKH + {0x95F8, 0xBEB1}, //3732 #HANGUL SYLLABLE SSANGPIEUP YA THIEUTH + {0x95F9, 0xBEB2}, //3733 #HANGUL SYLLABLE SSANGPIEUP YA PHIEUPH + {0x95FA, 0xBEB3}, //3734 #HANGUL SYLLABLE SSANGPIEUP YA HIEUH + {0x95FB, 0xBEB4}, //3735 #HANGUL SYLLABLE SSANGPIEUP YAE + {0x95FC, 0xBEB5}, //3736 #HANGUL SYLLABLE SSANGPIEUP YAE KIYEOK + {0x95FD, 0xBEB6}, //3737 #HANGUL SYLLABLE SSANGPIEUP YAE SSANGKIYEOK + {0x95FE, 0xBEB7}, //3738 #HANGUL SYLLABLE SSANGPIEUP YAE KIYEOKSIOS + {0x9641, 0xBEB8}, //3739 #HANGUL SYLLABLE SSANGPIEUP YAE NIEUN + {0x9642, 0xBEB9}, //3740 #HANGUL SYLLABLE SSANGPIEUP YAE NIEUNCIEUC + {0x9643, 0xBEBA}, //3741 #HANGUL SYLLABLE SSANGPIEUP YAE NIEUNHIEUH + {0x9644, 0xBEBB}, //3742 #HANGUL SYLLABLE SSANGPIEUP YAE TIKEUT + {0x9645, 0xBEBC}, //3743 #HANGUL SYLLABLE SSANGPIEUP YAE RIEUL + {0x9646, 0xBEBD}, //3744 #HANGUL SYLLABLE SSANGPIEUP YAE RIEULKIYEOK + {0x9647, 0xBEBE}, //3745 #HANGUL SYLLABLE SSANGPIEUP YAE RIEULMIEUM + {0x9648, 0xBEBF}, //3746 #HANGUL SYLLABLE SSANGPIEUP YAE RIEULPIEUP + {0x9649, 0xBEC0}, //3747 #HANGUL SYLLABLE SSANGPIEUP YAE RIEULSIOS + {0x964A, 0xBEC1}, //3748 #HANGUL SYLLABLE SSANGPIEUP YAE RIEULTHIEUTH + {0x964B, 0xBEC2}, //3749 #HANGUL SYLLABLE SSANGPIEUP YAE RIEULPHIEUPH + {0x964C, 0xBEC3}, //3750 #HANGUL SYLLABLE SSANGPIEUP YAE RIEULHIEUH + {0x964D, 0xBEC4}, //3751 #HANGUL SYLLABLE SSANGPIEUP YAE MIEUM + {0x964E, 0xBEC5}, //3752 #HANGUL SYLLABLE SSANGPIEUP YAE PIEUP + {0x964F, 0xBEC6}, //3753 #HANGUL SYLLABLE SSANGPIEUP YAE PIEUPSIOS + {0x9650, 0xBEC7}, //3754 #HANGUL SYLLABLE SSANGPIEUP YAE SIOS + {0x9651, 0xBEC8}, //3755 #HANGUL SYLLABLE SSANGPIEUP YAE SSANGSIOS + {0x9652, 0xBEC9}, //3756 #HANGUL SYLLABLE SSANGPIEUP YAE IEUNG + {0x9653, 0xBECA}, //3757 #HANGUL SYLLABLE SSANGPIEUP YAE CIEUC + {0x9654, 0xBECB}, //3758 #HANGUL SYLLABLE SSANGPIEUP YAE CHIEUCH + {0x9655, 0xBECC}, //3759 #HANGUL SYLLABLE SSANGPIEUP YAE KHIEUKH + {0x9656, 0xBECD}, //3760 #HANGUL SYLLABLE SSANGPIEUP YAE THIEUTH + {0x9657, 0xBECE}, //3761 #HANGUL SYLLABLE SSANGPIEUP YAE PHIEUPH + {0x9658, 0xBECF}, //3762 #HANGUL SYLLABLE SSANGPIEUP YAE HIEUH + {0x9659, 0xBED2}, //3763 #HANGUL SYLLABLE SSANGPIEUP EO SSANGKIYEOK + {0x965A, 0xBED3}, //3764 #HANGUL SYLLABLE SSANGPIEUP EO KIYEOKSIOS + {0x9661, 0xBED5}, //3765 #HANGUL SYLLABLE SSANGPIEUP EO NIEUNCIEUC + {0x9662, 0xBED6}, //3766 #HANGUL SYLLABLE SSANGPIEUP EO NIEUNHIEUH + {0x9663, 0xBED9}, //3767 #HANGUL SYLLABLE SSANGPIEUP EO RIEULKIYEOK + {0x9664, 0xBEDA}, //3768 #HANGUL SYLLABLE SSANGPIEUP EO RIEULMIEUM + {0x9665, 0xBEDB}, //3769 #HANGUL SYLLABLE SSANGPIEUP EO RIEULPIEUP + {0x9666, 0xBEDC}, //3770 #HANGUL SYLLABLE SSANGPIEUP EO RIEULSIOS + {0x9667, 0xBEDD}, //3771 #HANGUL SYLLABLE SSANGPIEUP EO RIEULTHIEUTH + {0x9668, 0xBEDE}, //3772 #HANGUL SYLLABLE SSANGPIEUP EO RIEULPHIEUPH + {0x9669, 0xBEDF}, //3773 #HANGUL SYLLABLE SSANGPIEUP EO RIEULHIEUH + {0x966A, 0xBEE1}, //3774 #HANGUL SYLLABLE SSANGPIEUP EO PIEUP + {0x966B, 0xBEE2}, //3775 #HANGUL SYLLABLE SSANGPIEUP EO PIEUPSIOS + {0x966C, 0xBEE6}, //3776 #HANGUL SYLLABLE SSANGPIEUP EO CIEUC + {0x966D, 0xBEE7}, //3777 #HANGUL SYLLABLE SSANGPIEUP EO CHIEUCH + {0x966E, 0xBEE8}, //3778 #HANGUL SYLLABLE SSANGPIEUP EO KHIEUKH + {0x966F, 0xBEE9}, //3779 #HANGUL SYLLABLE SSANGPIEUP EO THIEUTH + {0x9670, 0xBEEA}, //3780 #HANGUL SYLLABLE SSANGPIEUP EO PHIEUPH + {0x9671, 0xBEEB}, //3781 #HANGUL SYLLABLE SSANGPIEUP EO HIEUH + {0x9672, 0xBEED}, //3782 #HANGUL SYLLABLE SSANGPIEUP E KIYEOK + {0x9673, 0xBEEE}, //3783 #HANGUL SYLLABLE SSANGPIEUP E SSANGKIYEOK + {0x9674, 0xBEEF}, //3784 #HANGUL SYLLABLE SSANGPIEUP E KIYEOKSIOS + {0x9675, 0xBEF0}, //3785 #HANGUL SYLLABLE SSANGPIEUP E NIEUN + {0x9676, 0xBEF1}, //3786 #HANGUL SYLLABLE SSANGPIEUP E NIEUNCIEUC + {0x9677, 0xBEF2}, //3787 #HANGUL SYLLABLE SSANGPIEUP E NIEUNHIEUH + {0x9678, 0xBEF3}, //3788 #HANGUL SYLLABLE SSANGPIEUP E TIKEUT + {0x9679, 0xBEF4}, //3789 #HANGUL SYLLABLE SSANGPIEUP E RIEUL + {0x967A, 0xBEF5}, //3790 #HANGUL SYLLABLE SSANGPIEUP E RIEULKIYEOK + {0x9681, 0xBEF6}, //3791 #HANGUL SYLLABLE SSANGPIEUP E RIEULMIEUM + {0x9682, 0xBEF7}, //3792 #HANGUL SYLLABLE SSANGPIEUP E RIEULPIEUP + {0x9683, 0xBEF8}, //3793 #HANGUL SYLLABLE SSANGPIEUP E RIEULSIOS + {0x9684, 0xBEF9}, //3794 #HANGUL SYLLABLE SSANGPIEUP E RIEULTHIEUTH + {0x9685, 0xBEFA}, //3795 #HANGUL SYLLABLE SSANGPIEUP E RIEULPHIEUPH + {0x9686, 0xBEFB}, //3796 #HANGUL SYLLABLE SSANGPIEUP E RIEULHIEUH + {0x9687, 0xBEFC}, //3797 #HANGUL SYLLABLE SSANGPIEUP E MIEUM + {0x9688, 0xBEFD}, //3798 #HANGUL SYLLABLE SSANGPIEUP E PIEUP + {0x9689, 0xBEFE}, //3799 #HANGUL SYLLABLE SSANGPIEUP E PIEUPSIOS + {0x968A, 0xBEFF}, //3800 #HANGUL SYLLABLE SSANGPIEUP E SIOS + {0x968B, 0xBF00}, //3801 #HANGUL SYLLABLE SSANGPIEUP E SSANGSIOS + {0x968C, 0xBF02}, //3802 #HANGUL SYLLABLE SSANGPIEUP E CIEUC + {0x968D, 0xBF03}, //3803 #HANGUL SYLLABLE SSANGPIEUP E CHIEUCH + {0x968E, 0xBF04}, //3804 #HANGUL SYLLABLE SSANGPIEUP E KHIEUKH + {0x968F, 0xBF05}, //3805 #HANGUL SYLLABLE SSANGPIEUP E THIEUTH + {0x9690, 0xBF06}, //3806 #HANGUL SYLLABLE SSANGPIEUP E PHIEUPH + {0x9691, 0xBF07}, //3807 #HANGUL SYLLABLE SSANGPIEUP E HIEUH + {0x9692, 0xBF0A}, //3808 #HANGUL SYLLABLE SSANGPIEUP YEO SSANGKIYEOK + {0x9693, 0xBF0B}, //3809 #HANGUL SYLLABLE SSANGPIEUP YEO KIYEOKSIOS + {0x9694, 0xBF0C}, //3810 #HANGUL SYLLABLE SSANGPIEUP YEO NIEUN + {0x9695, 0xBF0D}, //3811 #HANGUL SYLLABLE SSANGPIEUP YEO NIEUNCIEUC + {0x9696, 0xBF0E}, //3812 #HANGUL SYLLABLE SSANGPIEUP YEO NIEUNHIEUH + {0x9697, 0xBF0F}, //3813 #HANGUL SYLLABLE SSANGPIEUP YEO TIKEUT + {0x9698, 0xBF10}, //3814 #HANGUL SYLLABLE SSANGPIEUP YEO RIEUL + {0x9699, 0xBF11}, //3815 #HANGUL SYLLABLE SSANGPIEUP YEO RIEULKIYEOK + {0x969A, 0xBF12}, //3816 #HANGUL SYLLABLE SSANGPIEUP YEO RIEULMIEUM + {0x969B, 0xBF13}, //3817 #HANGUL SYLLABLE SSANGPIEUP YEO RIEULPIEUP + {0x969C, 0xBF14}, //3818 #HANGUL SYLLABLE SSANGPIEUP YEO RIEULSIOS + {0x969D, 0xBF15}, //3819 #HANGUL SYLLABLE SSANGPIEUP YEO RIEULTHIEUTH + {0x969E, 0xBF16}, //3820 #HANGUL SYLLABLE SSANGPIEUP YEO RIEULPHIEUPH + {0x969F, 0xBF17}, //3821 #HANGUL SYLLABLE SSANGPIEUP YEO RIEULHIEUH + {0x96A0, 0xBF1A}, //3822 #HANGUL SYLLABLE SSANGPIEUP YEO PIEUPSIOS + {0x96A1, 0xBF1E}, //3823 #HANGUL SYLLABLE SSANGPIEUP YEO CIEUC + {0x96A2, 0xBF1F}, //3824 #HANGUL SYLLABLE SSANGPIEUP YEO CHIEUCH + {0x96A3, 0xBF20}, //3825 #HANGUL SYLLABLE SSANGPIEUP YEO KHIEUKH + {0x96A4, 0xBF21}, //3826 #HANGUL SYLLABLE SSANGPIEUP YEO THIEUTH + {0x96A5, 0xBF22}, //3827 #HANGUL SYLLABLE SSANGPIEUP YEO PHIEUPH + {0x96A6, 0xBF23}, //3828 #HANGUL SYLLABLE SSANGPIEUP YEO HIEUH + {0x96A7, 0xBF24}, //3829 #HANGUL SYLLABLE SSANGPIEUP YE + {0x96A8, 0xBF25}, //3830 #HANGUL SYLLABLE SSANGPIEUP YE KIYEOK + {0x96A9, 0xBF26}, //3831 #HANGUL SYLLABLE SSANGPIEUP YE SSANGKIYEOK + {0x96AA, 0xBF27}, //3832 #HANGUL SYLLABLE SSANGPIEUP YE KIYEOKSIOS + {0x96AB, 0xBF28}, //3833 #HANGUL SYLLABLE SSANGPIEUP YE NIEUN + {0x96AC, 0xBF29}, //3834 #HANGUL SYLLABLE SSANGPIEUP YE NIEUNCIEUC + {0x96AD, 0xBF2A}, //3835 #HANGUL SYLLABLE SSANGPIEUP YE NIEUNHIEUH + {0x96AE, 0xBF2B}, //3836 #HANGUL SYLLABLE SSANGPIEUP YE TIKEUT + {0x96AF, 0xBF2C}, //3837 #HANGUL SYLLABLE SSANGPIEUP YE RIEUL + {0x96B0, 0xBF2D}, //3838 #HANGUL SYLLABLE SSANGPIEUP YE RIEULKIYEOK + {0x96B1, 0xBF2E}, //3839 #HANGUL SYLLABLE SSANGPIEUP YE RIEULMIEUM + {0x96B2, 0xBF2F}, //3840 #HANGUL SYLLABLE SSANGPIEUP YE RIEULPIEUP + {0x96B3, 0xBF30}, //3841 #HANGUL SYLLABLE SSANGPIEUP YE RIEULSIOS + {0x96B4, 0xBF31}, //3842 #HANGUL SYLLABLE SSANGPIEUP YE RIEULTHIEUTH + {0x96B5, 0xBF32}, //3843 #HANGUL SYLLABLE SSANGPIEUP YE RIEULPHIEUPH + {0x96B6, 0xBF33}, //3844 #HANGUL SYLLABLE SSANGPIEUP YE RIEULHIEUH + {0x96B7, 0xBF34}, //3845 #HANGUL SYLLABLE SSANGPIEUP YE MIEUM + {0x96B8, 0xBF35}, //3846 #HANGUL SYLLABLE SSANGPIEUP YE PIEUP + {0x96B9, 0xBF36}, //3847 #HANGUL SYLLABLE SSANGPIEUP YE PIEUPSIOS + {0x96BA, 0xBF37}, //3848 #HANGUL SYLLABLE SSANGPIEUP YE SIOS + {0x96BB, 0xBF38}, //3849 #HANGUL SYLLABLE SSANGPIEUP YE SSANGSIOS + {0x96BC, 0xBF39}, //3850 #HANGUL SYLLABLE SSANGPIEUP YE IEUNG + {0x96BD, 0xBF3A}, //3851 #HANGUL SYLLABLE SSANGPIEUP YE CIEUC + {0x96BE, 0xBF3B}, //3852 #HANGUL SYLLABLE SSANGPIEUP YE CHIEUCH + {0x96BF, 0xBF3C}, //3853 #HANGUL SYLLABLE SSANGPIEUP YE KHIEUKH + {0x96C0, 0xBF3D}, //3854 #HANGUL SYLLABLE SSANGPIEUP YE THIEUTH + {0x96C1, 0xBF3E}, //3855 #HANGUL SYLLABLE SSANGPIEUP YE PHIEUPH + {0x96C2, 0xBF3F}, //3856 #HANGUL SYLLABLE SSANGPIEUP YE HIEUH + {0x96C3, 0xBF42}, //3857 #HANGUL SYLLABLE SSANGPIEUP O SSANGKIYEOK + {0x96C4, 0xBF43}, //3858 #HANGUL SYLLABLE SSANGPIEUP O KIYEOKSIOS + {0x96C5, 0xBF45}, //3859 #HANGUL SYLLABLE SSANGPIEUP O NIEUNCIEUC + {0x96C6, 0xBF46}, //3860 #HANGUL SYLLABLE SSANGPIEUP O NIEUNHIEUH + {0x96C7, 0xBF47}, //3861 #HANGUL SYLLABLE SSANGPIEUP O TIKEUT + {0x96C8, 0xBF49}, //3862 #HANGUL SYLLABLE SSANGPIEUP O RIEULKIYEOK + {0x96C9, 0xBF4A}, //3863 #HANGUL SYLLABLE SSANGPIEUP O RIEULMIEUM + {0x96CA, 0xBF4B}, //3864 #HANGUL SYLLABLE SSANGPIEUP O RIEULPIEUP + {0x96CB, 0xBF4C}, //3865 #HANGUL SYLLABLE SSANGPIEUP O RIEULSIOS + {0x96CC, 0xBF4D}, //3866 #HANGUL SYLLABLE SSANGPIEUP O RIEULTHIEUTH + {0x96CD, 0xBF4E}, //3867 #HANGUL SYLLABLE SSANGPIEUP O RIEULPHIEUPH + {0x96CE, 0xBF4F}, //3868 #HANGUL SYLLABLE SSANGPIEUP O RIEULHIEUH + {0x96CF, 0xBF52}, //3869 #HANGUL SYLLABLE SSANGPIEUP O PIEUPSIOS + {0x96D0, 0xBF53}, //3870 #HANGUL SYLLABLE SSANGPIEUP O SIOS + {0x96D1, 0xBF54}, //3871 #HANGUL SYLLABLE SSANGPIEUP O SSANGSIOS + {0x96D2, 0xBF56}, //3872 #HANGUL SYLLABLE SSANGPIEUP O CIEUC + {0x96D3, 0xBF57}, //3873 #HANGUL SYLLABLE SSANGPIEUP O CHIEUCH + {0x96D4, 0xBF58}, //3874 #HANGUL SYLLABLE SSANGPIEUP O KHIEUKH + {0x96D5, 0xBF59}, //3875 #HANGUL SYLLABLE SSANGPIEUP O THIEUTH + {0x96D6, 0xBF5A}, //3876 #HANGUL SYLLABLE SSANGPIEUP O PHIEUPH + {0x96D7, 0xBF5B}, //3877 #HANGUL SYLLABLE SSANGPIEUP O HIEUH + {0x96D8, 0xBF5C}, //3878 #HANGUL SYLLABLE SSANGPIEUP WA + {0x96D9, 0xBF5D}, //3879 #HANGUL SYLLABLE SSANGPIEUP WA KIYEOK + {0x96DA, 0xBF5E}, //3880 #HANGUL SYLLABLE SSANGPIEUP WA SSANGKIYEOK + {0x96DB, 0xBF5F}, //3881 #HANGUL SYLLABLE SSANGPIEUP WA KIYEOKSIOS + {0x96DC, 0xBF60}, //3882 #HANGUL SYLLABLE SSANGPIEUP WA NIEUN + {0x96DD, 0xBF61}, //3883 #HANGUL SYLLABLE SSANGPIEUP WA NIEUNCIEUC + {0x96DE, 0xBF62}, //3884 #HANGUL SYLLABLE SSANGPIEUP WA NIEUNHIEUH + {0x96DF, 0xBF63}, //3885 #HANGUL SYLLABLE SSANGPIEUP WA TIKEUT + {0x96E0, 0xBF64}, //3886 #HANGUL SYLLABLE SSANGPIEUP WA RIEUL + {0x96E1, 0xBF65}, //3887 #HANGUL SYLLABLE SSANGPIEUP WA RIEULKIYEOK + {0x96E2, 0xBF66}, //3888 #HANGUL SYLLABLE SSANGPIEUP WA RIEULMIEUM + {0x96E3, 0xBF67}, //3889 #HANGUL SYLLABLE SSANGPIEUP WA RIEULPIEUP + {0x96E4, 0xBF68}, //3890 #HANGUL SYLLABLE SSANGPIEUP WA RIEULSIOS + {0x96E5, 0xBF69}, //3891 #HANGUL SYLLABLE SSANGPIEUP WA RIEULTHIEUTH + {0x96E6, 0xBF6A}, //3892 #HANGUL SYLLABLE SSANGPIEUP WA RIEULPHIEUPH + {0x96E7, 0xBF6B}, //3893 #HANGUL SYLLABLE SSANGPIEUP WA RIEULHIEUH + {0x96E8, 0xBF6C}, //3894 #HANGUL SYLLABLE SSANGPIEUP WA MIEUM + {0x96E9, 0xBF6D}, //3895 #HANGUL SYLLABLE SSANGPIEUP WA PIEUP + {0x96EA, 0xBF6E}, //3896 #HANGUL SYLLABLE SSANGPIEUP WA PIEUPSIOS + {0x96EB, 0xBF6F}, //3897 #HANGUL SYLLABLE SSANGPIEUP WA SIOS + {0x96EC, 0xBF70}, //3898 #HANGUL SYLLABLE SSANGPIEUP WA SSANGSIOS + {0x96ED, 0xBF71}, //3899 #HANGUL SYLLABLE SSANGPIEUP WA IEUNG + {0x96EE, 0xBF72}, //3900 #HANGUL SYLLABLE SSANGPIEUP WA CIEUC + {0x96EF, 0xBF73}, //3901 #HANGUL SYLLABLE SSANGPIEUP WA CHIEUCH + {0x96F0, 0xBF74}, //3902 #HANGUL SYLLABLE SSANGPIEUP WA KHIEUKH + {0x96F1, 0xBF75}, //3903 #HANGUL SYLLABLE SSANGPIEUP WA THIEUTH + {0x96F2, 0xBF76}, //3904 #HANGUL SYLLABLE SSANGPIEUP WA PHIEUPH + {0x96F3, 0xBF77}, //3905 #HANGUL SYLLABLE SSANGPIEUP WA HIEUH + {0x96F4, 0xBF78}, //3906 #HANGUL SYLLABLE SSANGPIEUP WAE + {0x96F5, 0xBF79}, //3907 #HANGUL SYLLABLE SSANGPIEUP WAE KIYEOK + {0x96F6, 0xBF7A}, //3908 #HANGUL SYLLABLE SSANGPIEUP WAE SSANGKIYEOK + {0x96F7, 0xBF7B}, //3909 #HANGUL SYLLABLE SSANGPIEUP WAE KIYEOKSIOS + {0x96F8, 0xBF7C}, //3910 #HANGUL SYLLABLE SSANGPIEUP WAE NIEUN + {0x96F9, 0xBF7D}, //3911 #HANGUL SYLLABLE SSANGPIEUP WAE NIEUNCIEUC + {0x96FA, 0xBF7E}, //3912 #HANGUL SYLLABLE SSANGPIEUP WAE NIEUNHIEUH + {0x96FB, 0xBF7F}, //3913 #HANGUL SYLLABLE SSANGPIEUP WAE TIKEUT + {0x96FC, 0xBF80}, //3914 #HANGUL SYLLABLE SSANGPIEUP WAE RIEUL + {0x96FD, 0xBF81}, //3915 #HANGUL SYLLABLE SSANGPIEUP WAE RIEULKIYEOK + {0x96FE, 0xBF82}, //3916 #HANGUL SYLLABLE SSANGPIEUP WAE RIEULMIEUM + {0x9741, 0xBF83}, //3917 #HANGUL SYLLABLE SSANGPIEUP WAE RIEULPIEUP + {0x9742, 0xBF84}, //3918 #HANGUL SYLLABLE SSANGPIEUP WAE RIEULSIOS + {0x9743, 0xBF85}, //3919 #HANGUL SYLLABLE SSANGPIEUP WAE RIEULTHIEUTH + {0x9744, 0xBF86}, //3920 #HANGUL SYLLABLE SSANGPIEUP WAE RIEULPHIEUPH + {0x9745, 0xBF87}, //3921 #HANGUL SYLLABLE SSANGPIEUP WAE RIEULHIEUH + {0x9746, 0xBF88}, //3922 #HANGUL SYLLABLE SSANGPIEUP WAE MIEUM + {0x9747, 0xBF89}, //3923 #HANGUL SYLLABLE SSANGPIEUP WAE PIEUP + {0x9748, 0xBF8A}, //3924 #HANGUL SYLLABLE SSANGPIEUP WAE PIEUPSIOS + {0x9749, 0xBF8B}, //3925 #HANGUL SYLLABLE SSANGPIEUP WAE SIOS + {0x974A, 0xBF8C}, //3926 #HANGUL SYLLABLE SSANGPIEUP WAE SSANGSIOS + {0x974B, 0xBF8D}, //3927 #HANGUL SYLLABLE SSANGPIEUP WAE IEUNG + {0x974C, 0xBF8E}, //3928 #HANGUL SYLLABLE SSANGPIEUP WAE CIEUC + {0x974D, 0xBF8F}, //3929 #HANGUL SYLLABLE SSANGPIEUP WAE CHIEUCH + {0x974E, 0xBF90}, //3930 #HANGUL SYLLABLE SSANGPIEUP WAE KHIEUKH + {0x974F, 0xBF91}, //3931 #HANGUL SYLLABLE SSANGPIEUP WAE THIEUTH + {0x9750, 0xBF92}, //3932 #HANGUL SYLLABLE SSANGPIEUP WAE PHIEUPH + {0x9751, 0xBF93}, //3933 #HANGUL SYLLABLE SSANGPIEUP WAE HIEUH + {0x9752, 0xBF95}, //3934 #HANGUL SYLLABLE SSANGPIEUP OE KIYEOK + {0x9753, 0xBF96}, //3935 #HANGUL SYLLABLE SSANGPIEUP OE SSANGKIYEOK + {0x9754, 0xBF97}, //3936 #HANGUL SYLLABLE SSANGPIEUP OE KIYEOKSIOS + {0x9755, 0xBF98}, //3937 #HANGUL SYLLABLE SSANGPIEUP OE NIEUN + {0x9756, 0xBF99}, //3938 #HANGUL SYLLABLE SSANGPIEUP OE NIEUNCIEUC + {0x9757, 0xBF9A}, //3939 #HANGUL SYLLABLE SSANGPIEUP OE NIEUNHIEUH + {0x9758, 0xBF9B}, //3940 #HANGUL SYLLABLE SSANGPIEUP OE TIKEUT + {0x9759, 0xBF9C}, //3941 #HANGUL SYLLABLE SSANGPIEUP OE RIEUL + {0x975A, 0xBF9D}, //3942 #HANGUL SYLLABLE SSANGPIEUP OE RIEULKIYEOK + {0x9761, 0xBF9E}, //3943 #HANGUL SYLLABLE SSANGPIEUP OE RIEULMIEUM + {0x9762, 0xBF9F}, //3944 #HANGUL SYLLABLE SSANGPIEUP OE RIEULPIEUP + {0x9763, 0xBFA0}, //3945 #HANGUL SYLLABLE SSANGPIEUP OE RIEULSIOS + {0x9764, 0xBFA1}, //3946 #HANGUL SYLLABLE SSANGPIEUP OE RIEULTHIEUTH + {0x9765, 0xBFA2}, //3947 #HANGUL SYLLABLE SSANGPIEUP OE RIEULPHIEUPH + {0x9766, 0xBFA3}, //3948 #HANGUL SYLLABLE SSANGPIEUP OE RIEULHIEUH + {0x9767, 0xBFA4}, //3949 #HANGUL SYLLABLE SSANGPIEUP OE MIEUM + {0x9768, 0xBFA5}, //3950 #HANGUL SYLLABLE SSANGPIEUP OE PIEUP + {0x9769, 0xBFA6}, //3951 #HANGUL SYLLABLE SSANGPIEUP OE PIEUPSIOS + {0x976A, 0xBFA7}, //3952 #HANGUL SYLLABLE SSANGPIEUP OE SIOS + {0x976B, 0xBFA8}, //3953 #HANGUL SYLLABLE SSANGPIEUP OE SSANGSIOS + {0x976C, 0xBFA9}, //3954 #HANGUL SYLLABLE SSANGPIEUP OE IEUNG + {0x976D, 0xBFAA}, //3955 #HANGUL SYLLABLE SSANGPIEUP OE CIEUC + {0x976E, 0xBFAB}, //3956 #HANGUL SYLLABLE SSANGPIEUP OE CHIEUCH + {0x976F, 0xBFAC}, //3957 #HANGUL SYLLABLE SSANGPIEUP OE KHIEUKH + {0x9770, 0xBFAD}, //3958 #HANGUL SYLLABLE SSANGPIEUP OE THIEUTH + {0x9771, 0xBFAE}, //3959 #HANGUL SYLLABLE SSANGPIEUP OE PHIEUPH + {0x9772, 0xBFAF}, //3960 #HANGUL SYLLABLE SSANGPIEUP OE HIEUH + {0x9773, 0xBFB1}, //3961 #HANGUL SYLLABLE SSANGPIEUP YO KIYEOK + {0x9774, 0xBFB2}, //3962 #HANGUL SYLLABLE SSANGPIEUP YO SSANGKIYEOK + {0x9775, 0xBFB3}, //3963 #HANGUL SYLLABLE SSANGPIEUP YO KIYEOKSIOS + {0x9776, 0xBFB4}, //3964 #HANGUL SYLLABLE SSANGPIEUP YO NIEUN + {0x9777, 0xBFB5}, //3965 #HANGUL SYLLABLE SSANGPIEUP YO NIEUNCIEUC + {0x9778, 0xBFB6}, //3966 #HANGUL SYLLABLE SSANGPIEUP YO NIEUNHIEUH + {0x9779, 0xBFB7}, //3967 #HANGUL SYLLABLE SSANGPIEUP YO TIKEUT + {0x977A, 0xBFB8}, //3968 #HANGUL SYLLABLE SSANGPIEUP YO RIEUL + {0x9781, 0xBFB9}, //3969 #HANGUL SYLLABLE SSANGPIEUP YO RIEULKIYEOK + {0x9782, 0xBFBA}, //3970 #HANGUL SYLLABLE SSANGPIEUP YO RIEULMIEUM + {0x9783, 0xBFBB}, //3971 #HANGUL SYLLABLE SSANGPIEUP YO RIEULPIEUP + {0x9784, 0xBFBC}, //3972 #HANGUL SYLLABLE SSANGPIEUP YO RIEULSIOS + {0x9785, 0xBFBD}, //3973 #HANGUL SYLLABLE SSANGPIEUP YO RIEULTHIEUTH + {0x9786, 0xBFBE}, //3974 #HANGUL SYLLABLE SSANGPIEUP YO RIEULPHIEUPH + {0x9787, 0xBFBF}, //3975 #HANGUL SYLLABLE SSANGPIEUP YO RIEULHIEUH + {0x9788, 0xBFC0}, //3976 #HANGUL SYLLABLE SSANGPIEUP YO MIEUM + {0x9789, 0xBFC1}, //3977 #HANGUL SYLLABLE SSANGPIEUP YO PIEUP + {0x978A, 0xBFC2}, //3978 #HANGUL SYLLABLE SSANGPIEUP YO PIEUPSIOS + {0x978B, 0xBFC3}, //3979 #HANGUL SYLLABLE SSANGPIEUP YO SIOS + {0x978C, 0xBFC4}, //3980 #HANGUL SYLLABLE SSANGPIEUP YO SSANGSIOS + {0x978D, 0xBFC6}, //3981 #HANGUL SYLLABLE SSANGPIEUP YO CIEUC + {0x978E, 0xBFC7}, //3982 #HANGUL SYLLABLE SSANGPIEUP YO CHIEUCH + {0x978F, 0xBFC8}, //3983 #HANGUL SYLLABLE SSANGPIEUP YO KHIEUKH + {0x9790, 0xBFC9}, //3984 #HANGUL SYLLABLE SSANGPIEUP YO THIEUTH + {0x9791, 0xBFCA}, //3985 #HANGUL SYLLABLE SSANGPIEUP YO PHIEUPH + {0x9792, 0xBFCB}, //3986 #HANGUL SYLLABLE SSANGPIEUP YO HIEUH + {0x9793, 0xBFCE}, //3987 #HANGUL SYLLABLE SSANGPIEUP U SSANGKIYEOK + {0x9794, 0xBFCF}, //3988 #HANGUL SYLLABLE SSANGPIEUP U KIYEOKSIOS + {0x9795, 0xBFD1}, //3989 #HANGUL SYLLABLE SSANGPIEUP U NIEUNCIEUC + {0x9796, 0xBFD2}, //3990 #HANGUL SYLLABLE SSANGPIEUP U NIEUNHIEUH + {0x9797, 0xBFD3}, //3991 #HANGUL SYLLABLE SSANGPIEUP U TIKEUT + {0x9798, 0xBFD5}, //3992 #HANGUL SYLLABLE SSANGPIEUP U RIEULKIYEOK + {0x9799, 0xBFD6}, //3993 #HANGUL SYLLABLE SSANGPIEUP U RIEULMIEUM + {0x979A, 0xBFD7}, //3994 #HANGUL SYLLABLE SSANGPIEUP U RIEULPIEUP + {0x979B, 0xBFD8}, //3995 #HANGUL SYLLABLE SSANGPIEUP U RIEULSIOS + {0x979C, 0xBFD9}, //3996 #HANGUL SYLLABLE SSANGPIEUP U RIEULTHIEUTH + {0x979D, 0xBFDA}, //3997 #HANGUL SYLLABLE SSANGPIEUP U RIEULPHIEUPH + {0x979E, 0xBFDB}, //3998 #HANGUL SYLLABLE SSANGPIEUP U RIEULHIEUH + {0x979F, 0xBFDD}, //3999 #HANGUL SYLLABLE SSANGPIEUP U PIEUP + {0x97A0, 0xBFDE}, //4000 #HANGUL SYLLABLE SSANGPIEUP U PIEUPSIOS + {0x97A1, 0xBFE0}, //4001 #HANGUL SYLLABLE SSANGPIEUP U SSANGSIOS + {0x97A2, 0xBFE2}, //4002 #HANGUL SYLLABLE SSANGPIEUP U CIEUC + {0x97A3, 0xBFE3}, //4003 #HANGUL SYLLABLE SSANGPIEUP U CHIEUCH + {0x97A4, 0xBFE4}, //4004 #HANGUL SYLLABLE SSANGPIEUP U KHIEUKH + {0x97A5, 0xBFE5}, //4005 #HANGUL SYLLABLE SSANGPIEUP U THIEUTH + {0x97A6, 0xBFE6}, //4006 #HANGUL SYLLABLE SSANGPIEUP U PHIEUPH + {0x97A7, 0xBFE7}, //4007 #HANGUL SYLLABLE SSANGPIEUP U HIEUH + {0x97A8, 0xBFE8}, //4008 #HANGUL SYLLABLE SSANGPIEUP WEO + {0x97A9, 0xBFE9}, //4009 #HANGUL SYLLABLE SSANGPIEUP WEO KIYEOK + {0x97AA, 0xBFEA}, //4010 #HANGUL SYLLABLE SSANGPIEUP WEO SSANGKIYEOK + {0x97AB, 0xBFEB}, //4011 #HANGUL SYLLABLE SSANGPIEUP WEO KIYEOKSIOS + {0x97AC, 0xBFEC}, //4012 #HANGUL SYLLABLE SSANGPIEUP WEO NIEUN + {0x97AD, 0xBFED}, //4013 #HANGUL SYLLABLE SSANGPIEUP WEO NIEUNCIEUC + {0x97AE, 0xBFEE}, //4014 #HANGUL SYLLABLE SSANGPIEUP WEO NIEUNHIEUH + {0x97AF, 0xBFEF}, //4015 #HANGUL SYLLABLE SSANGPIEUP WEO TIKEUT + {0x97B0, 0xBFF0}, //4016 #HANGUL SYLLABLE SSANGPIEUP WEO RIEUL + {0x97B1, 0xBFF1}, //4017 #HANGUL SYLLABLE SSANGPIEUP WEO RIEULKIYEOK + {0x97B2, 0xBFF2}, //4018 #HANGUL SYLLABLE SSANGPIEUP WEO RIEULMIEUM + {0x97B3, 0xBFF3}, //4019 #HANGUL SYLLABLE SSANGPIEUP WEO RIEULPIEUP + {0x97B4, 0xBFF4}, //4020 #HANGUL SYLLABLE SSANGPIEUP WEO RIEULSIOS + {0x97B5, 0xBFF5}, //4021 #HANGUL SYLLABLE SSANGPIEUP WEO RIEULTHIEUTH + {0x97B6, 0xBFF6}, //4022 #HANGUL SYLLABLE SSANGPIEUP WEO RIEULPHIEUPH + {0x97B7, 0xBFF7}, //4023 #HANGUL SYLLABLE SSANGPIEUP WEO RIEULHIEUH + {0x97B8, 0xBFF8}, //4024 #HANGUL SYLLABLE SSANGPIEUP WEO MIEUM + {0x97B9, 0xBFF9}, //4025 #HANGUL SYLLABLE SSANGPIEUP WEO PIEUP + {0x97BA, 0xBFFA}, //4026 #HANGUL SYLLABLE SSANGPIEUP WEO PIEUPSIOS + {0x97BB, 0xBFFB}, //4027 #HANGUL SYLLABLE SSANGPIEUP WEO SIOS + {0x97BC, 0xBFFC}, //4028 #HANGUL SYLLABLE SSANGPIEUP WEO SSANGSIOS + {0x97BD, 0xBFFD}, //4029 #HANGUL SYLLABLE SSANGPIEUP WEO IEUNG + {0x97BE, 0xBFFE}, //4030 #HANGUL SYLLABLE SSANGPIEUP WEO CIEUC + {0x97BF, 0xBFFF}, //4031 #HANGUL SYLLABLE SSANGPIEUP WEO CHIEUCH + {0x97C0, 0xC000}, //4032 #HANGUL SYLLABLE SSANGPIEUP WEO KHIEUKH + {0x97C1, 0xC001}, //4033 #HANGUL SYLLABLE SSANGPIEUP WEO THIEUTH + {0x97C2, 0xC002}, //4034 #HANGUL SYLLABLE SSANGPIEUP WEO PHIEUPH + {0x97C3, 0xC003}, //4035 #HANGUL SYLLABLE SSANGPIEUP WEO HIEUH + {0x97C4, 0xC004}, //4036 #HANGUL SYLLABLE SSANGPIEUP WE + {0x97C5, 0xC005}, //4037 #HANGUL SYLLABLE SSANGPIEUP WE KIYEOK + {0x97C6, 0xC006}, //4038 #HANGUL SYLLABLE SSANGPIEUP WE SSANGKIYEOK + {0x97C7, 0xC007}, //4039 #HANGUL SYLLABLE SSANGPIEUP WE KIYEOKSIOS + {0x97C8, 0xC008}, //4040 #HANGUL SYLLABLE SSANGPIEUP WE NIEUN + {0x97C9, 0xC009}, //4041 #HANGUL SYLLABLE SSANGPIEUP WE NIEUNCIEUC + {0x97CA, 0xC00A}, //4042 #HANGUL SYLLABLE SSANGPIEUP WE NIEUNHIEUH + {0x97CB, 0xC00B}, //4043 #HANGUL SYLLABLE SSANGPIEUP WE TIKEUT + {0x97CC, 0xC00C}, //4044 #HANGUL SYLLABLE SSANGPIEUP WE RIEUL + {0x97CD, 0xC00D}, //4045 #HANGUL SYLLABLE SSANGPIEUP WE RIEULKIYEOK + {0x97CE, 0xC00E}, //4046 #HANGUL SYLLABLE SSANGPIEUP WE RIEULMIEUM + {0x97CF, 0xC00F}, //4047 #HANGUL SYLLABLE SSANGPIEUP WE RIEULPIEUP + {0x97D0, 0xC010}, //4048 #HANGUL SYLLABLE SSANGPIEUP WE RIEULSIOS + {0x97D1, 0xC011}, //4049 #HANGUL SYLLABLE SSANGPIEUP WE RIEULTHIEUTH + {0x97D2, 0xC012}, //4050 #HANGUL SYLLABLE SSANGPIEUP WE RIEULPHIEUPH + {0x97D3, 0xC013}, //4051 #HANGUL SYLLABLE SSANGPIEUP WE RIEULHIEUH + {0x97D4, 0xC014}, //4052 #HANGUL SYLLABLE SSANGPIEUP WE MIEUM + {0x97D5, 0xC015}, //4053 #HANGUL SYLLABLE SSANGPIEUP WE PIEUP + {0x97D6, 0xC016}, //4054 #HANGUL SYLLABLE SSANGPIEUP WE PIEUPSIOS + {0x97D7, 0xC017}, //4055 #HANGUL SYLLABLE SSANGPIEUP WE SIOS + {0x97D8, 0xC018}, //4056 #HANGUL SYLLABLE SSANGPIEUP WE SSANGSIOS + {0x97D9, 0xC019}, //4057 #HANGUL SYLLABLE SSANGPIEUP WE IEUNG + {0x97DA, 0xC01A}, //4058 #HANGUL SYLLABLE SSANGPIEUP WE CIEUC + {0x97DB, 0xC01B}, //4059 #HANGUL SYLLABLE SSANGPIEUP WE CHIEUCH + {0x97DC, 0xC01C}, //4060 #HANGUL SYLLABLE SSANGPIEUP WE KHIEUKH + {0x97DD, 0xC01D}, //4061 #HANGUL SYLLABLE SSANGPIEUP WE THIEUTH + {0x97DE, 0xC01E}, //4062 #HANGUL SYLLABLE SSANGPIEUP WE PHIEUPH + {0x97DF, 0xC01F}, //4063 #HANGUL SYLLABLE SSANGPIEUP WE HIEUH + {0x97E0, 0xC020}, //4064 #HANGUL SYLLABLE SSANGPIEUP WI + {0x97E1, 0xC021}, //4065 #HANGUL SYLLABLE SSANGPIEUP WI KIYEOK + {0x97E2, 0xC022}, //4066 #HANGUL SYLLABLE SSANGPIEUP WI SSANGKIYEOK + {0x97E3, 0xC023}, //4067 #HANGUL SYLLABLE SSANGPIEUP WI KIYEOKSIOS + {0x97E4, 0xC024}, //4068 #HANGUL SYLLABLE SSANGPIEUP WI NIEUN + {0x97E5, 0xC025}, //4069 #HANGUL SYLLABLE SSANGPIEUP WI NIEUNCIEUC + {0x97E6, 0xC026}, //4070 #HANGUL SYLLABLE SSANGPIEUP WI NIEUNHIEUH + {0x97E7, 0xC027}, //4071 #HANGUL SYLLABLE SSANGPIEUP WI TIKEUT + {0x97E8, 0xC028}, //4072 #HANGUL SYLLABLE SSANGPIEUP WI RIEUL + {0x97E9, 0xC029}, //4073 #HANGUL SYLLABLE SSANGPIEUP WI RIEULKIYEOK + {0x97EA, 0xC02A}, //4074 #HANGUL SYLLABLE SSANGPIEUP WI RIEULMIEUM + {0x97EB, 0xC02B}, //4075 #HANGUL SYLLABLE SSANGPIEUP WI RIEULPIEUP + {0x97EC, 0xC02C}, //4076 #HANGUL SYLLABLE SSANGPIEUP WI RIEULSIOS + {0x97ED, 0xC02D}, //4077 #HANGUL SYLLABLE SSANGPIEUP WI RIEULTHIEUTH + {0x97EE, 0xC02E}, //4078 #HANGUL SYLLABLE SSANGPIEUP WI RIEULPHIEUPH + {0x97EF, 0xC02F}, //4079 #HANGUL SYLLABLE SSANGPIEUP WI RIEULHIEUH + {0x97F0, 0xC030}, //4080 #HANGUL SYLLABLE SSANGPIEUP WI MIEUM + {0x97F1, 0xC031}, //4081 #HANGUL SYLLABLE SSANGPIEUP WI PIEUP + {0x97F2, 0xC032}, //4082 #HANGUL SYLLABLE SSANGPIEUP WI PIEUPSIOS + {0x97F3, 0xC033}, //4083 #HANGUL SYLLABLE SSANGPIEUP WI SIOS + {0x97F4, 0xC034}, //4084 #HANGUL SYLLABLE SSANGPIEUP WI SSANGSIOS + {0x97F5, 0xC035}, //4085 #HANGUL SYLLABLE SSANGPIEUP WI IEUNG + {0x97F6, 0xC036}, //4086 #HANGUL SYLLABLE SSANGPIEUP WI CIEUC + {0x97F7, 0xC037}, //4087 #HANGUL SYLLABLE SSANGPIEUP WI CHIEUCH + {0x97F8, 0xC038}, //4088 #HANGUL SYLLABLE SSANGPIEUP WI KHIEUKH + {0x97F9, 0xC039}, //4089 #HANGUL SYLLABLE SSANGPIEUP WI THIEUTH + {0x97FA, 0xC03A}, //4090 #HANGUL SYLLABLE SSANGPIEUP WI PHIEUPH + {0x97FB, 0xC03B}, //4091 #HANGUL SYLLABLE SSANGPIEUP WI HIEUH + {0x97FC, 0xC03D}, //4092 #HANGUL SYLLABLE SSANGPIEUP YU KIYEOK + {0x97FD, 0xC03E}, //4093 #HANGUL SYLLABLE SSANGPIEUP YU SSANGKIYEOK + {0x97FE, 0xC03F}, //4094 #HANGUL SYLLABLE SSANGPIEUP YU KIYEOKSIOS + {0x9841, 0xC040}, //4095 #HANGUL SYLLABLE SSANGPIEUP YU NIEUN + {0x9842, 0xC041}, //4096 #HANGUL SYLLABLE SSANGPIEUP YU NIEUNCIEUC + {0x9843, 0xC042}, //4097 #HANGUL SYLLABLE SSANGPIEUP YU NIEUNHIEUH + {0x9844, 0xC043}, //4098 #HANGUL SYLLABLE SSANGPIEUP YU TIKEUT + {0x9845, 0xC044}, //4099 #HANGUL SYLLABLE SSANGPIEUP YU RIEUL + {0x9846, 0xC045}, //4100 #HANGUL SYLLABLE SSANGPIEUP YU RIEULKIYEOK + {0x9847, 0xC046}, //4101 #HANGUL SYLLABLE SSANGPIEUP YU RIEULMIEUM + {0x9848, 0xC047}, //4102 #HANGUL SYLLABLE SSANGPIEUP YU RIEULPIEUP + {0x9849, 0xC048}, //4103 #HANGUL SYLLABLE SSANGPIEUP YU RIEULSIOS + {0x984A, 0xC049}, //4104 #HANGUL SYLLABLE SSANGPIEUP YU RIEULTHIEUTH + {0x984B, 0xC04A}, //4105 #HANGUL SYLLABLE SSANGPIEUP YU RIEULPHIEUPH + {0x984C, 0xC04B}, //4106 #HANGUL SYLLABLE SSANGPIEUP YU RIEULHIEUH + {0x984D, 0xC04C}, //4107 #HANGUL SYLLABLE SSANGPIEUP YU MIEUM + {0x984E, 0xC04D}, //4108 #HANGUL SYLLABLE SSANGPIEUP YU PIEUP + {0x984F, 0xC04E}, //4109 #HANGUL SYLLABLE SSANGPIEUP YU PIEUPSIOS + {0x9850, 0xC04F}, //4110 #HANGUL SYLLABLE SSANGPIEUP YU SIOS + {0x9851, 0xC050}, //4111 #HANGUL SYLLABLE SSANGPIEUP YU SSANGSIOS + {0x9852, 0xC052}, //4112 #HANGUL SYLLABLE SSANGPIEUP YU CIEUC + {0x9853, 0xC053}, //4113 #HANGUL SYLLABLE SSANGPIEUP YU CHIEUCH + {0x9854, 0xC054}, //4114 #HANGUL SYLLABLE SSANGPIEUP YU KHIEUKH + {0x9855, 0xC055}, //4115 #HANGUL SYLLABLE SSANGPIEUP YU THIEUTH + {0x9856, 0xC056}, //4116 #HANGUL SYLLABLE SSANGPIEUP YU PHIEUPH + {0x9857, 0xC057}, //4117 #HANGUL SYLLABLE SSANGPIEUP YU HIEUH + {0x9858, 0xC059}, //4118 #HANGUL SYLLABLE SSANGPIEUP EU KIYEOK + {0x9859, 0xC05A}, //4119 #HANGUL SYLLABLE SSANGPIEUP EU SSANGKIYEOK + {0x985A, 0xC05B}, //4120 #HANGUL SYLLABLE SSANGPIEUP EU KIYEOKSIOS + {0x9861, 0xC05D}, //4121 #HANGUL SYLLABLE SSANGPIEUP EU NIEUNCIEUC + {0x9862, 0xC05E}, //4122 #HANGUL SYLLABLE SSANGPIEUP EU NIEUNHIEUH + {0x9863, 0xC05F}, //4123 #HANGUL SYLLABLE SSANGPIEUP EU TIKEUT + {0x9864, 0xC061}, //4124 #HANGUL SYLLABLE SSANGPIEUP EU RIEULKIYEOK + {0x9865, 0xC062}, //4125 #HANGUL SYLLABLE SSANGPIEUP EU RIEULMIEUM + {0x9866, 0xC063}, //4126 #HANGUL SYLLABLE SSANGPIEUP EU RIEULPIEUP + {0x9867, 0xC064}, //4127 #HANGUL SYLLABLE SSANGPIEUP EU RIEULSIOS + {0x9868, 0xC065}, //4128 #HANGUL SYLLABLE SSANGPIEUP EU RIEULTHIEUTH + {0x9869, 0xC066}, //4129 #HANGUL SYLLABLE SSANGPIEUP EU RIEULPHIEUPH + {0x986A, 0xC067}, //4130 #HANGUL SYLLABLE SSANGPIEUP EU RIEULHIEUH + {0x986B, 0xC06A}, //4131 #HANGUL SYLLABLE SSANGPIEUP EU PIEUPSIOS + {0x986C, 0xC06B}, //4132 #HANGUL SYLLABLE SSANGPIEUP EU SIOS + {0x986D, 0xC06C}, //4133 #HANGUL SYLLABLE SSANGPIEUP EU SSANGSIOS + {0x986E, 0xC06D}, //4134 #HANGUL SYLLABLE SSANGPIEUP EU IEUNG + {0x986F, 0xC06E}, //4135 #HANGUL SYLLABLE SSANGPIEUP EU CIEUC + {0x9870, 0xC06F}, //4136 #HANGUL SYLLABLE SSANGPIEUP EU CHIEUCH + {0x9871, 0xC070}, //4137 #HANGUL SYLLABLE SSANGPIEUP EU KHIEUKH + {0x9872, 0xC071}, //4138 #HANGUL SYLLABLE SSANGPIEUP EU THIEUTH + {0x9873, 0xC072}, //4139 #HANGUL SYLLABLE SSANGPIEUP EU PHIEUPH + {0x9874, 0xC073}, //4140 #HANGUL SYLLABLE SSANGPIEUP EU HIEUH + {0x9875, 0xC074}, //4141 #HANGUL SYLLABLE SSANGPIEUP YI + {0x9876, 0xC075}, //4142 #HANGUL SYLLABLE SSANGPIEUP YI KIYEOK + {0x9877, 0xC076}, //4143 #HANGUL SYLLABLE SSANGPIEUP YI SSANGKIYEOK + {0x9878, 0xC077}, //4144 #HANGUL SYLLABLE SSANGPIEUP YI KIYEOKSIOS + {0x9879, 0xC078}, //4145 #HANGUL SYLLABLE SSANGPIEUP YI NIEUN + {0x987A, 0xC079}, //4146 #HANGUL SYLLABLE SSANGPIEUP YI NIEUNCIEUC + {0x9881, 0xC07A}, //4147 #HANGUL SYLLABLE SSANGPIEUP YI NIEUNHIEUH + {0x9882, 0xC07B}, //4148 #HANGUL SYLLABLE SSANGPIEUP YI TIKEUT + {0x9883, 0xC07C}, //4149 #HANGUL SYLLABLE SSANGPIEUP YI RIEUL + {0x9884, 0xC07D}, //4150 #HANGUL SYLLABLE SSANGPIEUP YI RIEULKIYEOK + {0x9885, 0xC07E}, //4151 #HANGUL SYLLABLE SSANGPIEUP YI RIEULMIEUM + {0x9886, 0xC07F}, //4152 #HANGUL SYLLABLE SSANGPIEUP YI RIEULPIEUP + {0x9887, 0xC080}, //4153 #HANGUL SYLLABLE SSANGPIEUP YI RIEULSIOS + {0x9888, 0xC081}, //4154 #HANGUL SYLLABLE SSANGPIEUP YI RIEULTHIEUTH + {0x9889, 0xC082}, //4155 #HANGUL SYLLABLE SSANGPIEUP YI RIEULPHIEUPH + {0x988A, 0xC083}, //4156 #HANGUL SYLLABLE SSANGPIEUP YI RIEULHIEUH + {0x988B, 0xC084}, //4157 #HANGUL SYLLABLE SSANGPIEUP YI MIEUM + {0x988C, 0xC085}, //4158 #HANGUL SYLLABLE SSANGPIEUP YI PIEUP + {0x988D, 0xC086}, //4159 #HANGUL SYLLABLE SSANGPIEUP YI PIEUPSIOS + {0x988E, 0xC087}, //4160 #HANGUL SYLLABLE SSANGPIEUP YI SIOS + {0x988F, 0xC088}, //4161 #HANGUL SYLLABLE SSANGPIEUP YI SSANGSIOS + {0x9890, 0xC089}, //4162 #HANGUL SYLLABLE SSANGPIEUP YI IEUNG + {0x9891, 0xC08A}, //4163 #HANGUL SYLLABLE SSANGPIEUP YI CIEUC + {0x9892, 0xC08B}, //4164 #HANGUL SYLLABLE SSANGPIEUP YI CHIEUCH + {0x9893, 0xC08C}, //4165 #HANGUL SYLLABLE SSANGPIEUP YI KHIEUKH + {0x9894, 0xC08D}, //4166 #HANGUL SYLLABLE SSANGPIEUP YI THIEUTH + {0x9895, 0xC08E}, //4167 #HANGUL SYLLABLE SSANGPIEUP YI PHIEUPH + {0x9896, 0xC08F}, //4168 #HANGUL SYLLABLE SSANGPIEUP YI HIEUH + {0x9897, 0xC092}, //4169 #HANGUL SYLLABLE SSANGPIEUP I SSANGKIYEOK + {0x9898, 0xC093}, //4170 #HANGUL SYLLABLE SSANGPIEUP I KIYEOKSIOS + {0x9899, 0xC095}, //4171 #HANGUL SYLLABLE SSANGPIEUP I NIEUNCIEUC + {0x989A, 0xC096}, //4172 #HANGUL SYLLABLE SSANGPIEUP I NIEUNHIEUH + {0x989B, 0xC097}, //4173 #HANGUL SYLLABLE SSANGPIEUP I TIKEUT + {0x989C, 0xC099}, //4174 #HANGUL SYLLABLE SSANGPIEUP I RIEULKIYEOK + {0x989D, 0xC09A}, //4175 #HANGUL SYLLABLE SSANGPIEUP I RIEULMIEUM + {0x989E, 0xC09B}, //4176 #HANGUL SYLLABLE SSANGPIEUP I RIEULPIEUP + {0x989F, 0xC09C}, //4177 #HANGUL SYLLABLE SSANGPIEUP I RIEULSIOS + {0x98A0, 0xC09D}, //4178 #HANGUL SYLLABLE SSANGPIEUP I RIEULTHIEUTH + {0x98A1, 0xC09E}, //4179 #HANGUL SYLLABLE SSANGPIEUP I RIEULPHIEUPH + {0x98A2, 0xC09F}, //4180 #HANGUL SYLLABLE SSANGPIEUP I RIEULHIEUH + {0x98A3, 0xC0A2}, //4181 #HANGUL SYLLABLE SSANGPIEUP I PIEUPSIOS + {0x98A4, 0xC0A4}, //4182 #HANGUL SYLLABLE SSANGPIEUP I SSANGSIOS + {0x98A5, 0xC0A6}, //4183 #HANGUL SYLLABLE SSANGPIEUP I CIEUC + {0x98A6, 0xC0A7}, //4184 #HANGUL SYLLABLE SSANGPIEUP I CHIEUCH + {0x98A7, 0xC0A8}, //4185 #HANGUL SYLLABLE SSANGPIEUP I KHIEUKH + {0x98A8, 0xC0A9}, //4186 #HANGUL SYLLABLE SSANGPIEUP I THIEUTH + {0x98A9, 0xC0AA}, //4187 #HANGUL SYLLABLE SSANGPIEUP I PHIEUPH + {0x98AA, 0xC0AB}, //4188 #HANGUL SYLLABLE SSANGPIEUP I HIEUH + {0x98AB, 0xC0AE}, //4189 #HANGUL SYLLABLE SIOS A SSANGKIYEOK + {0x98AC, 0xC0B1}, //4190 #HANGUL SYLLABLE SIOS A NIEUNCIEUC + {0x98AD, 0xC0B2}, //4191 #HANGUL SYLLABLE SIOS A NIEUNHIEUH + {0x98AE, 0xC0B7}, //4192 #HANGUL SYLLABLE SIOS A RIEULPIEUP + {0x98AF, 0xC0B8}, //4193 #HANGUL SYLLABLE SIOS A RIEULSIOS + {0x98B0, 0xC0B9}, //4194 #HANGUL SYLLABLE SIOS A RIEULTHIEUTH + {0x98B1, 0xC0BA}, //4195 #HANGUL SYLLABLE SIOS A RIEULPHIEUPH + {0x98B2, 0xC0BB}, //4196 #HANGUL SYLLABLE SIOS A RIEULHIEUH + {0x98B3, 0xC0BE}, //4197 #HANGUL SYLLABLE SIOS A PIEUPSIOS + {0x98B4, 0xC0C2}, //4198 #HANGUL SYLLABLE SIOS A CIEUC + {0x98B5, 0xC0C3}, //4199 #HANGUL SYLLABLE SIOS A CHIEUCH + {0x98B6, 0xC0C4}, //4200 #HANGUL SYLLABLE SIOS A KHIEUKH + {0x98B7, 0xC0C6}, //4201 #HANGUL SYLLABLE SIOS A PHIEUPH + {0x98B8, 0xC0C7}, //4202 #HANGUL SYLLABLE SIOS A HIEUH + {0x98B9, 0xC0CA}, //4203 #HANGUL SYLLABLE SIOS AE SSANGKIYEOK + {0x98BA, 0xC0CB}, //4204 #HANGUL SYLLABLE SIOS AE KIYEOKSIOS + {0x98BB, 0xC0CD}, //4205 #HANGUL SYLLABLE SIOS AE NIEUNCIEUC + {0x98BC, 0xC0CE}, //4206 #HANGUL SYLLABLE SIOS AE NIEUNHIEUH + {0x98BD, 0xC0CF}, //4207 #HANGUL SYLLABLE SIOS AE TIKEUT + {0x98BE, 0xC0D1}, //4208 #HANGUL SYLLABLE SIOS AE RIEULKIYEOK + {0x98BF, 0xC0D2}, //4209 #HANGUL SYLLABLE SIOS AE RIEULMIEUM + {0x98C0, 0xC0D3}, //4210 #HANGUL SYLLABLE SIOS AE RIEULPIEUP + {0x98C1, 0xC0D4}, //4211 #HANGUL SYLLABLE SIOS AE RIEULSIOS + {0x98C2, 0xC0D5}, //4212 #HANGUL SYLLABLE SIOS AE RIEULTHIEUTH + {0x98C3, 0xC0D6}, //4213 #HANGUL SYLLABLE SIOS AE RIEULPHIEUPH + {0x98C4, 0xC0D7}, //4214 #HANGUL SYLLABLE SIOS AE RIEULHIEUH + {0x98C5, 0xC0DA}, //4215 #HANGUL SYLLABLE SIOS AE PIEUPSIOS + {0x98C6, 0xC0DE}, //4216 #HANGUL SYLLABLE SIOS AE CIEUC + {0x98C7, 0xC0DF}, //4217 #HANGUL SYLLABLE SIOS AE CHIEUCH + {0x98C8, 0xC0E0}, //4218 #HANGUL SYLLABLE SIOS AE KHIEUKH + {0x98C9, 0xC0E1}, //4219 #HANGUL SYLLABLE SIOS AE THIEUTH + {0x98CA, 0xC0E2}, //4220 #HANGUL SYLLABLE SIOS AE PHIEUPH + {0x98CB, 0xC0E3}, //4221 #HANGUL SYLLABLE SIOS AE HIEUH + {0x98CC, 0xC0E6}, //4222 #HANGUL SYLLABLE SIOS YA SSANGKIYEOK + {0x98CD, 0xC0E7}, //4223 #HANGUL SYLLABLE SIOS YA KIYEOKSIOS + {0x98CE, 0xC0E9}, //4224 #HANGUL SYLLABLE SIOS YA NIEUNCIEUC + {0x98CF, 0xC0EA}, //4225 #HANGUL SYLLABLE SIOS YA NIEUNHIEUH + {0x98D0, 0xC0EB}, //4226 #HANGUL SYLLABLE SIOS YA TIKEUT + {0x98D1, 0xC0ED}, //4227 #HANGUL SYLLABLE SIOS YA RIEULKIYEOK + {0x98D2, 0xC0EE}, //4228 #HANGUL SYLLABLE SIOS YA RIEULMIEUM + {0x98D3, 0xC0EF}, //4229 #HANGUL SYLLABLE SIOS YA RIEULPIEUP + {0x98D4, 0xC0F0}, //4230 #HANGUL SYLLABLE SIOS YA RIEULSIOS + {0x98D5, 0xC0F1}, //4231 #HANGUL SYLLABLE SIOS YA RIEULTHIEUTH + {0x98D6, 0xC0F2}, //4232 #HANGUL SYLLABLE SIOS YA RIEULPHIEUPH + {0x98D7, 0xC0F3}, //4233 #HANGUL SYLLABLE SIOS YA RIEULHIEUH + {0x98D8, 0xC0F6}, //4234 #HANGUL SYLLABLE SIOS YA PIEUPSIOS + {0x98D9, 0xC0F8}, //4235 #HANGUL SYLLABLE SIOS YA SSANGSIOS + {0x98DA, 0xC0FA}, //4236 #HANGUL SYLLABLE SIOS YA CIEUC + {0x98DB, 0xC0FB}, //4237 #HANGUL SYLLABLE SIOS YA CHIEUCH + {0x98DC, 0xC0FC}, //4238 #HANGUL SYLLABLE SIOS YA KHIEUKH + {0x98DD, 0xC0FD}, //4239 #HANGUL SYLLABLE SIOS YA THIEUTH + {0x98DE, 0xC0FE}, //4240 #HANGUL SYLLABLE SIOS YA PHIEUPH + {0x98DF, 0xC0FF}, //4241 #HANGUL SYLLABLE SIOS YA HIEUH + {0x98E0, 0xC101}, //4242 #HANGUL SYLLABLE SIOS YAE KIYEOK + {0x98E1, 0xC102}, //4243 #HANGUL SYLLABLE SIOS YAE SSANGKIYEOK + {0x98E2, 0xC103}, //4244 #HANGUL SYLLABLE SIOS YAE KIYEOKSIOS + {0x98E3, 0xC105}, //4245 #HANGUL SYLLABLE SIOS YAE NIEUNCIEUC + {0x98E4, 0xC106}, //4246 #HANGUL SYLLABLE SIOS YAE NIEUNHIEUH + {0x98E5, 0xC107}, //4247 #HANGUL SYLLABLE SIOS YAE TIKEUT + {0x98E6, 0xC109}, //4248 #HANGUL SYLLABLE SIOS YAE RIEULKIYEOK + {0x98E7, 0xC10A}, //4249 #HANGUL SYLLABLE SIOS YAE RIEULMIEUM + {0x98E8, 0xC10B}, //4250 #HANGUL SYLLABLE SIOS YAE RIEULPIEUP + {0x98E9, 0xC10C}, //4251 #HANGUL SYLLABLE SIOS YAE RIEULSIOS + {0x98EA, 0xC10D}, //4252 #HANGUL SYLLABLE SIOS YAE RIEULTHIEUTH + {0x98EB, 0xC10E}, //4253 #HANGUL SYLLABLE SIOS YAE RIEULPHIEUPH + {0x98EC, 0xC10F}, //4254 #HANGUL SYLLABLE SIOS YAE RIEULHIEUH + {0x98ED, 0xC111}, //4255 #HANGUL SYLLABLE SIOS YAE PIEUP + {0x98EE, 0xC112}, //4256 #HANGUL SYLLABLE SIOS YAE PIEUPSIOS + {0x98EF, 0xC113}, //4257 #HANGUL SYLLABLE SIOS YAE SIOS + {0x98F0, 0xC114}, //4258 #HANGUL SYLLABLE SIOS YAE SSANGSIOS + {0x98F1, 0xC116}, //4259 #HANGUL SYLLABLE SIOS YAE CIEUC + {0x98F2, 0xC117}, //4260 #HANGUL SYLLABLE SIOS YAE CHIEUCH + {0x98F3, 0xC118}, //4261 #HANGUL SYLLABLE SIOS YAE KHIEUKH + {0x98F4, 0xC119}, //4262 #HANGUL SYLLABLE SIOS YAE THIEUTH + {0x98F5, 0xC11A}, //4263 #HANGUL SYLLABLE SIOS YAE PHIEUPH + {0x98F6, 0xC11B}, //4264 #HANGUL SYLLABLE SIOS YAE HIEUH + {0x98F7, 0xC121}, //4265 #HANGUL SYLLABLE SIOS EO NIEUNCIEUC + {0x98F8, 0xC122}, //4266 #HANGUL SYLLABLE SIOS EO NIEUNHIEUH + {0x98F9, 0xC125}, //4267 #HANGUL SYLLABLE SIOS EO RIEULKIYEOK + {0x98FA, 0xC128}, //4268 #HANGUL SYLLABLE SIOS EO RIEULSIOS + {0x98FB, 0xC129}, //4269 #HANGUL SYLLABLE SIOS EO RIEULTHIEUTH + {0x98FC, 0xC12A}, //4270 #HANGUL SYLLABLE SIOS EO RIEULPHIEUPH + {0x98FD, 0xC12B}, //4271 #HANGUL SYLLABLE SIOS EO RIEULHIEUH + {0x98FE, 0xC12E}, //4272 #HANGUL SYLLABLE SIOS EO PIEUPSIOS + {0x9941, 0xC132}, //4273 #HANGUL SYLLABLE SIOS EO CIEUC + {0x9942, 0xC133}, //4274 #HANGUL SYLLABLE SIOS EO CHIEUCH + {0x9943, 0xC134}, //4275 #HANGUL SYLLABLE SIOS EO KHIEUKH + {0x9944, 0xC135}, //4276 #HANGUL SYLLABLE SIOS EO THIEUTH + {0x9945, 0xC137}, //4277 #HANGUL SYLLABLE SIOS EO HIEUH + {0x9946, 0xC13A}, //4278 #HANGUL SYLLABLE SIOS E SSANGKIYEOK + {0x9947, 0xC13B}, //4279 #HANGUL SYLLABLE SIOS E KIYEOKSIOS + {0x9948, 0xC13D}, //4280 #HANGUL SYLLABLE SIOS E NIEUNCIEUC + {0x9949, 0xC13E}, //4281 #HANGUL SYLLABLE SIOS E NIEUNHIEUH + {0x994A, 0xC13F}, //4282 #HANGUL SYLLABLE SIOS E TIKEUT + {0x994B, 0xC141}, //4283 #HANGUL SYLLABLE SIOS E RIEULKIYEOK + {0x994C, 0xC142}, //4284 #HANGUL SYLLABLE SIOS E RIEULMIEUM + {0x994D, 0xC143}, //4285 #HANGUL SYLLABLE SIOS E RIEULPIEUP + {0x994E, 0xC144}, //4286 #HANGUL SYLLABLE SIOS E RIEULSIOS + {0x994F, 0xC145}, //4287 #HANGUL SYLLABLE SIOS E RIEULTHIEUTH + {0x9950, 0xC146}, //4288 #HANGUL SYLLABLE SIOS E RIEULPHIEUPH + {0x9951, 0xC147}, //4289 #HANGUL SYLLABLE SIOS E RIEULHIEUH + {0x9952, 0xC14A}, //4290 #HANGUL SYLLABLE SIOS E PIEUPSIOS + {0x9953, 0xC14E}, //4291 #HANGUL SYLLABLE SIOS E CIEUC + {0x9954, 0xC14F}, //4292 #HANGUL SYLLABLE SIOS E CHIEUCH + {0x9955, 0xC150}, //4293 #HANGUL SYLLABLE SIOS E KHIEUKH + {0x9956, 0xC151}, //4294 #HANGUL SYLLABLE SIOS E THIEUTH + {0x9957, 0xC152}, //4295 #HANGUL SYLLABLE SIOS E PHIEUPH + {0x9958, 0xC153}, //4296 #HANGUL SYLLABLE SIOS E HIEUH + {0x9959, 0xC156}, //4297 #HANGUL SYLLABLE SIOS YEO SSANGKIYEOK + {0x995A, 0xC157}, //4298 #HANGUL SYLLABLE SIOS YEO KIYEOKSIOS + {0x9961, 0xC159}, //4299 #HANGUL SYLLABLE SIOS YEO NIEUNCIEUC + {0x9962, 0xC15A}, //4300 #HANGUL SYLLABLE SIOS YEO NIEUNHIEUH + {0x9963, 0xC15B}, //4301 #HANGUL SYLLABLE SIOS YEO TIKEUT + {0x9964, 0xC15D}, //4302 #HANGUL SYLLABLE SIOS YEO RIEULKIYEOK + {0x9965, 0xC15E}, //4303 #HANGUL SYLLABLE SIOS YEO RIEULMIEUM + {0x9966, 0xC15F}, //4304 #HANGUL SYLLABLE SIOS YEO RIEULPIEUP + {0x9967, 0xC160}, //4305 #HANGUL SYLLABLE SIOS YEO RIEULSIOS + {0x9968, 0xC161}, //4306 #HANGUL SYLLABLE SIOS YEO RIEULTHIEUTH + {0x9969, 0xC162}, //4307 #HANGUL SYLLABLE SIOS YEO RIEULPHIEUPH + {0x996A, 0xC163}, //4308 #HANGUL SYLLABLE SIOS YEO RIEULHIEUH + {0x996B, 0xC166}, //4309 #HANGUL SYLLABLE SIOS YEO PIEUPSIOS + {0x996C, 0xC16A}, //4310 #HANGUL SYLLABLE SIOS YEO CIEUC + {0x996D, 0xC16B}, //4311 #HANGUL SYLLABLE SIOS YEO CHIEUCH + {0x996E, 0xC16C}, //4312 #HANGUL SYLLABLE SIOS YEO KHIEUKH + {0x996F, 0xC16D}, //4313 #HANGUL SYLLABLE SIOS YEO THIEUTH + {0x9970, 0xC16E}, //4314 #HANGUL SYLLABLE SIOS YEO PHIEUPH + {0x9971, 0xC16F}, //4315 #HANGUL SYLLABLE SIOS YEO HIEUH + {0x9972, 0xC171}, //4316 #HANGUL SYLLABLE SIOS YE KIYEOK + {0x9973, 0xC172}, //4317 #HANGUL SYLLABLE SIOS YE SSANGKIYEOK + {0x9974, 0xC173}, //4318 #HANGUL SYLLABLE SIOS YE KIYEOKSIOS + {0x9975, 0xC175}, //4319 #HANGUL SYLLABLE SIOS YE NIEUNCIEUC + {0x9976, 0xC176}, //4320 #HANGUL SYLLABLE SIOS YE NIEUNHIEUH + {0x9977, 0xC177}, //4321 #HANGUL SYLLABLE SIOS YE TIKEUT + {0x9978, 0xC179}, //4322 #HANGUL SYLLABLE SIOS YE RIEULKIYEOK + {0x9979, 0xC17A}, //4323 #HANGUL SYLLABLE SIOS YE RIEULMIEUM + {0x997A, 0xC17B}, //4324 #HANGUL SYLLABLE SIOS YE RIEULPIEUP + {0x9981, 0xC17C}, //4325 #HANGUL SYLLABLE SIOS YE RIEULSIOS + {0x9982, 0xC17D}, //4326 #HANGUL SYLLABLE SIOS YE RIEULTHIEUTH + {0x9983, 0xC17E}, //4327 #HANGUL SYLLABLE SIOS YE RIEULPHIEUPH + {0x9984, 0xC17F}, //4328 #HANGUL SYLLABLE SIOS YE RIEULHIEUH + {0x9985, 0xC180}, //4329 #HANGUL SYLLABLE SIOS YE MIEUM + {0x9986, 0xC181}, //4330 #HANGUL SYLLABLE SIOS YE PIEUP + {0x9987, 0xC182}, //4331 #HANGUL SYLLABLE SIOS YE PIEUPSIOS + {0x9988, 0xC183}, //4332 #HANGUL SYLLABLE SIOS YE SIOS + {0x9989, 0xC184}, //4333 #HANGUL SYLLABLE SIOS YE SSANGSIOS + {0x998A, 0xC186}, //4334 #HANGUL SYLLABLE SIOS YE CIEUC + {0x998B, 0xC187}, //4335 #HANGUL SYLLABLE SIOS YE CHIEUCH + {0x998C, 0xC188}, //4336 #HANGUL SYLLABLE SIOS YE KHIEUKH + {0x998D, 0xC189}, //4337 #HANGUL SYLLABLE SIOS YE THIEUTH + {0x998E, 0xC18A}, //4338 #HANGUL SYLLABLE SIOS YE PHIEUPH + {0x998F, 0xC18B}, //4339 #HANGUL SYLLABLE SIOS YE HIEUH + {0x9990, 0xC18F}, //4340 #HANGUL SYLLABLE SIOS O KIYEOKSIOS + {0x9991, 0xC191}, //4341 #HANGUL SYLLABLE SIOS O NIEUNCIEUC + {0x9992, 0xC192}, //4342 #HANGUL SYLLABLE SIOS O NIEUNHIEUH + {0x9993, 0xC193}, //4343 #HANGUL SYLLABLE SIOS O TIKEUT + {0x9994, 0xC195}, //4344 #HANGUL SYLLABLE SIOS O RIEULKIYEOK + {0x9995, 0xC197}, //4345 #HANGUL SYLLABLE SIOS O RIEULPIEUP + {0x9996, 0xC198}, //4346 #HANGUL SYLLABLE SIOS O RIEULSIOS + {0x9997, 0xC199}, //4347 #HANGUL SYLLABLE SIOS O RIEULTHIEUTH + {0x9998, 0xC19A}, //4348 #HANGUL SYLLABLE SIOS O RIEULPHIEUPH + {0x9999, 0xC19B}, //4349 #HANGUL SYLLABLE SIOS O RIEULHIEUH + {0x999A, 0xC19E}, //4350 #HANGUL SYLLABLE SIOS O PIEUPSIOS + {0x999B, 0xC1A0}, //4351 #HANGUL SYLLABLE SIOS O SSANGSIOS + {0x999C, 0xC1A2}, //4352 #HANGUL SYLLABLE SIOS O CIEUC + {0x999D, 0xC1A3}, //4353 #HANGUL SYLLABLE SIOS O CHIEUCH + {0x999E, 0xC1A4}, //4354 #HANGUL SYLLABLE SIOS O KHIEUKH + {0x999F, 0xC1A6}, //4355 #HANGUL SYLLABLE SIOS O PHIEUPH + {0x99A0, 0xC1A7}, //4356 #HANGUL SYLLABLE SIOS O HIEUH + {0x99A1, 0xC1AA}, //4357 #HANGUL SYLLABLE SIOS WA SSANGKIYEOK + {0x99A2, 0xC1AB}, //4358 #HANGUL SYLLABLE SIOS WA KIYEOKSIOS + {0x99A3, 0xC1AD}, //4359 #HANGUL SYLLABLE SIOS WA NIEUNCIEUC + {0x99A4, 0xC1AE}, //4360 #HANGUL SYLLABLE SIOS WA NIEUNHIEUH + {0x99A5, 0xC1AF}, //4361 #HANGUL SYLLABLE SIOS WA TIKEUT + {0x99A6, 0xC1B1}, //4362 #HANGUL SYLLABLE SIOS WA RIEULKIYEOK + {0x99A7, 0xC1B2}, //4363 #HANGUL SYLLABLE SIOS WA RIEULMIEUM + {0x99A8, 0xC1B3}, //4364 #HANGUL SYLLABLE SIOS WA RIEULPIEUP + {0x99A9, 0xC1B4}, //4365 #HANGUL SYLLABLE SIOS WA RIEULSIOS + {0x99AA, 0xC1B5}, //4366 #HANGUL SYLLABLE SIOS WA RIEULTHIEUTH + {0x99AB, 0xC1B6}, //4367 #HANGUL SYLLABLE SIOS WA RIEULPHIEUPH + {0x99AC, 0xC1B7}, //4368 #HANGUL SYLLABLE SIOS WA RIEULHIEUH + {0x99AD, 0xC1B8}, //4369 #HANGUL SYLLABLE SIOS WA MIEUM + {0x99AE, 0xC1B9}, //4370 #HANGUL SYLLABLE SIOS WA PIEUP + {0x99AF, 0xC1BA}, //4371 #HANGUL SYLLABLE SIOS WA PIEUPSIOS + {0x99B0, 0xC1BB}, //4372 #HANGUL SYLLABLE SIOS WA SIOS + {0x99B1, 0xC1BC}, //4373 #HANGUL SYLLABLE SIOS WA SSANGSIOS + {0x99B2, 0xC1BE}, //4374 #HANGUL SYLLABLE SIOS WA CIEUC + {0x99B3, 0xC1BF}, //4375 #HANGUL SYLLABLE SIOS WA CHIEUCH + {0x99B4, 0xC1C0}, //4376 #HANGUL SYLLABLE SIOS WA KHIEUKH + {0x99B5, 0xC1C1}, //4377 #HANGUL SYLLABLE SIOS WA THIEUTH + {0x99B6, 0xC1C2}, //4378 #HANGUL SYLLABLE SIOS WA PHIEUPH + {0x99B7, 0xC1C3}, //4379 #HANGUL SYLLABLE SIOS WA HIEUH + {0x99B8, 0xC1C5}, //4380 #HANGUL SYLLABLE SIOS WAE KIYEOK + {0x99B9, 0xC1C6}, //4381 #HANGUL SYLLABLE SIOS WAE SSANGKIYEOK + {0x99BA, 0xC1C7}, //4382 #HANGUL SYLLABLE SIOS WAE KIYEOKSIOS + {0x99BB, 0xC1C9}, //4383 #HANGUL SYLLABLE SIOS WAE NIEUNCIEUC + {0x99BC, 0xC1CA}, //4384 #HANGUL SYLLABLE SIOS WAE NIEUNHIEUH + {0x99BD, 0xC1CB}, //4385 #HANGUL SYLLABLE SIOS WAE TIKEUT + {0x99BE, 0xC1CD}, //4386 #HANGUL SYLLABLE SIOS WAE RIEULKIYEOK + {0x99BF, 0xC1CE}, //4387 #HANGUL SYLLABLE SIOS WAE RIEULMIEUM + {0x99C0, 0xC1CF}, //4388 #HANGUL SYLLABLE SIOS WAE RIEULPIEUP + {0x99C1, 0xC1D0}, //4389 #HANGUL SYLLABLE SIOS WAE RIEULSIOS + {0x99C2, 0xC1D1}, //4390 #HANGUL SYLLABLE SIOS WAE RIEULTHIEUTH + {0x99C3, 0xC1D2}, //4391 #HANGUL SYLLABLE SIOS WAE RIEULPHIEUPH + {0x99C4, 0xC1D3}, //4392 #HANGUL SYLLABLE SIOS WAE RIEULHIEUH + {0x99C5, 0xC1D5}, //4393 #HANGUL SYLLABLE SIOS WAE PIEUP + {0x99C6, 0xC1D6}, //4394 #HANGUL SYLLABLE SIOS WAE PIEUPSIOS + {0x99C7, 0xC1D9}, //4395 #HANGUL SYLLABLE SIOS WAE IEUNG + {0x99C8, 0xC1DA}, //4396 #HANGUL SYLLABLE SIOS WAE CIEUC + {0x99C9, 0xC1DB}, //4397 #HANGUL SYLLABLE SIOS WAE CHIEUCH + {0x99CA, 0xC1DC}, //4398 #HANGUL SYLLABLE SIOS WAE KHIEUKH + {0x99CB, 0xC1DD}, //4399 #HANGUL SYLLABLE SIOS WAE THIEUTH + {0x99CC, 0xC1DE}, //4400 #HANGUL SYLLABLE SIOS WAE PHIEUPH + {0x99CD, 0xC1DF}, //4401 #HANGUL SYLLABLE SIOS WAE HIEUH + {0x99CE, 0xC1E1}, //4402 #HANGUL SYLLABLE SIOS OE KIYEOK + {0x99CF, 0xC1E2}, //4403 #HANGUL SYLLABLE SIOS OE SSANGKIYEOK + {0x99D0, 0xC1E3}, //4404 #HANGUL SYLLABLE SIOS OE KIYEOKSIOS + {0x99D1, 0xC1E5}, //4405 #HANGUL SYLLABLE SIOS OE NIEUNCIEUC + {0x99D2, 0xC1E6}, //4406 #HANGUL SYLLABLE SIOS OE NIEUNHIEUH + {0x99D3, 0xC1E7}, //4407 #HANGUL SYLLABLE SIOS OE TIKEUT + {0x99D4, 0xC1E9}, //4408 #HANGUL SYLLABLE SIOS OE RIEULKIYEOK + {0x99D5, 0xC1EA}, //4409 #HANGUL SYLLABLE SIOS OE RIEULMIEUM + {0x99D6, 0xC1EB}, //4410 #HANGUL SYLLABLE SIOS OE RIEULPIEUP + {0x99D7, 0xC1EC}, //4411 #HANGUL SYLLABLE SIOS OE RIEULSIOS + {0x99D8, 0xC1ED}, //4412 #HANGUL SYLLABLE SIOS OE RIEULTHIEUTH + {0x99D9, 0xC1EE}, //4413 #HANGUL SYLLABLE SIOS OE RIEULPHIEUPH + {0x99DA, 0xC1EF}, //4414 #HANGUL SYLLABLE SIOS OE RIEULHIEUH + {0x99DB, 0xC1F2}, //4415 #HANGUL SYLLABLE SIOS OE PIEUPSIOS + {0x99DC, 0xC1F4}, //4416 #HANGUL SYLLABLE SIOS OE SSANGSIOS + {0x99DD, 0xC1F5}, //4417 #HANGUL SYLLABLE SIOS OE IEUNG + {0x99DE, 0xC1F6}, //4418 #HANGUL SYLLABLE SIOS OE CIEUC + {0x99DF, 0xC1F7}, //4419 #HANGUL SYLLABLE SIOS OE CHIEUCH + {0x99E0, 0xC1F8}, //4420 #HANGUL SYLLABLE SIOS OE KHIEUKH + {0x99E1, 0xC1F9}, //4421 #HANGUL SYLLABLE SIOS OE THIEUTH + {0x99E2, 0xC1FA}, //4422 #HANGUL SYLLABLE SIOS OE PHIEUPH + {0x99E3, 0xC1FB}, //4423 #HANGUL SYLLABLE SIOS OE HIEUH + {0x99E4, 0xC1FE}, //4424 #HANGUL SYLLABLE SIOS YO SSANGKIYEOK + {0x99E5, 0xC1FF}, //4425 #HANGUL SYLLABLE SIOS YO KIYEOKSIOS + {0x99E6, 0xC201}, //4426 #HANGUL SYLLABLE SIOS YO NIEUNCIEUC + {0x99E7, 0xC202}, //4427 #HANGUL SYLLABLE SIOS YO NIEUNHIEUH + {0x99E8, 0xC203}, //4428 #HANGUL SYLLABLE SIOS YO TIKEUT + {0x99E9, 0xC205}, //4429 #HANGUL SYLLABLE SIOS YO RIEULKIYEOK + {0x99EA, 0xC206}, //4430 #HANGUL SYLLABLE SIOS YO RIEULMIEUM + {0x99EB, 0xC207}, //4431 #HANGUL SYLLABLE SIOS YO RIEULPIEUP + {0x99EC, 0xC208}, //4432 #HANGUL SYLLABLE SIOS YO RIEULSIOS + {0x99ED, 0xC209}, //4433 #HANGUL SYLLABLE SIOS YO RIEULTHIEUTH + {0x99EE, 0xC20A}, //4434 #HANGUL SYLLABLE SIOS YO RIEULPHIEUPH + {0x99EF, 0xC20B}, //4435 #HANGUL SYLLABLE SIOS YO RIEULHIEUH + {0x99F0, 0xC20E}, //4436 #HANGUL SYLLABLE SIOS YO PIEUPSIOS + {0x99F1, 0xC210}, //4437 #HANGUL SYLLABLE SIOS YO SSANGSIOS + {0x99F2, 0xC212}, //4438 #HANGUL SYLLABLE SIOS YO CIEUC + {0x99F3, 0xC213}, //4439 #HANGUL SYLLABLE SIOS YO CHIEUCH + {0x99F4, 0xC214}, //4440 #HANGUL SYLLABLE SIOS YO KHIEUKH + {0x99F5, 0xC215}, //4441 #HANGUL SYLLABLE SIOS YO THIEUTH + {0x99F6, 0xC216}, //4442 #HANGUL SYLLABLE SIOS YO PHIEUPH + {0x99F7, 0xC217}, //4443 #HANGUL SYLLABLE SIOS YO HIEUH + {0x99F8, 0xC21A}, //4444 #HANGUL SYLLABLE SIOS U SSANGKIYEOK + {0x99F9, 0xC21B}, //4445 #HANGUL SYLLABLE SIOS U KIYEOKSIOS + {0x99FA, 0xC21D}, //4446 #HANGUL SYLLABLE SIOS U NIEUNCIEUC + {0x99FB, 0xC21E}, //4447 #HANGUL SYLLABLE SIOS U NIEUNHIEUH + {0x99FC, 0xC221}, //4448 #HANGUL SYLLABLE SIOS U RIEULKIYEOK + {0x99FD, 0xC222}, //4449 #HANGUL SYLLABLE SIOS U RIEULMIEUM + {0x99FE, 0xC223}, //4450 #HANGUL SYLLABLE SIOS U RIEULPIEUP + {0x9A41, 0xC224}, //4451 #HANGUL SYLLABLE SIOS U RIEULSIOS + {0x9A42, 0xC225}, //4452 #HANGUL SYLLABLE SIOS U RIEULTHIEUTH + {0x9A43, 0xC226}, //4453 #HANGUL SYLLABLE SIOS U RIEULPHIEUPH + {0x9A44, 0xC227}, //4454 #HANGUL SYLLABLE SIOS U RIEULHIEUH + {0x9A45, 0xC22A}, //4455 #HANGUL SYLLABLE SIOS U PIEUPSIOS + {0x9A46, 0xC22C}, //4456 #HANGUL SYLLABLE SIOS U SSANGSIOS + {0x9A47, 0xC22E}, //4457 #HANGUL SYLLABLE SIOS U CIEUC + {0x9A48, 0xC230}, //4458 #HANGUL SYLLABLE SIOS U KHIEUKH + {0x9A49, 0xC233}, //4459 #HANGUL SYLLABLE SIOS U HIEUH + {0x9A4A, 0xC235}, //4460 #HANGUL SYLLABLE SIOS WEO KIYEOK + {0x9A4B, 0xC236}, //4461 #HANGUL SYLLABLE SIOS WEO SSANGKIYEOK + {0x9A4C, 0xC237}, //4462 #HANGUL SYLLABLE SIOS WEO KIYEOKSIOS + {0x9A4D, 0xC238}, //4463 #HANGUL SYLLABLE SIOS WEO NIEUN + {0x9A4E, 0xC239}, //4464 #HANGUL SYLLABLE SIOS WEO NIEUNCIEUC + {0x9A4F, 0xC23A}, //4465 #HANGUL SYLLABLE SIOS WEO NIEUNHIEUH + {0x9A50, 0xC23B}, //4466 #HANGUL SYLLABLE SIOS WEO TIKEUT + {0x9A51, 0xC23C}, //4467 #HANGUL SYLLABLE SIOS WEO RIEUL + {0x9A52, 0xC23D}, //4468 #HANGUL SYLLABLE SIOS WEO RIEULKIYEOK + {0x9A53, 0xC23E}, //4469 #HANGUL SYLLABLE SIOS WEO RIEULMIEUM + {0x9A54, 0xC23F}, //4470 #HANGUL SYLLABLE SIOS WEO RIEULPIEUP + {0x9A55, 0xC240}, //4471 #HANGUL SYLLABLE SIOS WEO RIEULSIOS + {0x9A56, 0xC241}, //4472 #HANGUL SYLLABLE SIOS WEO RIEULTHIEUTH + {0x9A57, 0xC242}, //4473 #HANGUL SYLLABLE SIOS WEO RIEULPHIEUPH + {0x9A58, 0xC243}, //4474 #HANGUL SYLLABLE SIOS WEO RIEULHIEUH + {0x9A59, 0xC244}, //4475 #HANGUL SYLLABLE SIOS WEO MIEUM + {0x9A5A, 0xC245}, //4476 #HANGUL SYLLABLE SIOS WEO PIEUP + {0x9A61, 0xC246}, //4477 #HANGUL SYLLABLE SIOS WEO PIEUPSIOS + {0x9A62, 0xC247}, //4478 #HANGUL SYLLABLE SIOS WEO SIOS + {0x9A63, 0xC249}, //4479 #HANGUL SYLLABLE SIOS WEO IEUNG + {0x9A64, 0xC24A}, //4480 #HANGUL SYLLABLE SIOS WEO CIEUC + {0x9A65, 0xC24B}, //4481 #HANGUL SYLLABLE SIOS WEO CHIEUCH + {0x9A66, 0xC24C}, //4482 #HANGUL SYLLABLE SIOS WEO KHIEUKH + {0x9A67, 0xC24D}, //4483 #HANGUL SYLLABLE SIOS WEO THIEUTH + {0x9A68, 0xC24E}, //4484 #HANGUL SYLLABLE SIOS WEO PHIEUPH + {0x9A69, 0xC24F}, //4485 #HANGUL SYLLABLE SIOS WEO HIEUH + {0x9A6A, 0xC252}, //4486 #HANGUL SYLLABLE SIOS WE SSANGKIYEOK + {0x9A6B, 0xC253}, //4487 #HANGUL SYLLABLE SIOS WE KIYEOKSIOS + {0x9A6C, 0xC255}, //4488 #HANGUL SYLLABLE SIOS WE NIEUNCIEUC + {0x9A6D, 0xC256}, //4489 #HANGUL SYLLABLE SIOS WE NIEUNHIEUH + {0x9A6E, 0xC257}, //4490 #HANGUL SYLLABLE SIOS WE TIKEUT + {0x9A6F, 0xC259}, //4491 #HANGUL SYLLABLE SIOS WE RIEULKIYEOK + {0x9A70, 0xC25A}, //4492 #HANGUL SYLLABLE SIOS WE RIEULMIEUM + {0x9A71, 0xC25B}, //4493 #HANGUL SYLLABLE SIOS WE RIEULPIEUP + {0x9A72, 0xC25C}, //4494 #HANGUL SYLLABLE SIOS WE RIEULSIOS + {0x9A73, 0xC25D}, //4495 #HANGUL SYLLABLE SIOS WE RIEULTHIEUTH + {0x9A74, 0xC25E}, //4496 #HANGUL SYLLABLE SIOS WE RIEULPHIEUPH + {0x9A75, 0xC25F}, //4497 #HANGUL SYLLABLE SIOS WE RIEULHIEUH + {0x9A76, 0xC261}, //4498 #HANGUL SYLLABLE SIOS WE PIEUP + {0x9A77, 0xC262}, //4499 #HANGUL SYLLABLE SIOS WE PIEUPSIOS + {0x9A78, 0xC263}, //4500 #HANGUL SYLLABLE SIOS WE SIOS + {0x9A79, 0xC264}, //4501 #HANGUL SYLLABLE SIOS WE SSANGSIOS + {0x9A7A, 0xC266}, //4502 #HANGUL SYLLABLE SIOS WE CIEUC + {0x9A81, 0xC267}, //4503 #HANGUL SYLLABLE SIOS WE CHIEUCH + {0x9A82, 0xC268}, //4504 #HANGUL SYLLABLE SIOS WE KHIEUKH + {0x9A83, 0xC269}, //4505 #HANGUL SYLLABLE SIOS WE THIEUTH + {0x9A84, 0xC26A}, //4506 #HANGUL SYLLABLE SIOS WE PHIEUPH + {0x9A85, 0xC26B}, //4507 #HANGUL SYLLABLE SIOS WE HIEUH + {0x9A86, 0xC26E}, //4508 #HANGUL SYLLABLE SIOS WI SSANGKIYEOK + {0x9A87, 0xC26F}, //4509 #HANGUL SYLLABLE SIOS WI KIYEOKSIOS + {0x9A88, 0xC271}, //4510 #HANGUL SYLLABLE SIOS WI NIEUNCIEUC + {0x9A89, 0xC272}, //4511 #HANGUL SYLLABLE SIOS WI NIEUNHIEUH + {0x9A8A, 0xC273}, //4512 #HANGUL SYLLABLE SIOS WI TIKEUT + {0x9A8B, 0xC275}, //4513 #HANGUL SYLLABLE SIOS WI RIEULKIYEOK + {0x9A8C, 0xC276}, //4514 #HANGUL SYLLABLE SIOS WI RIEULMIEUM + {0x9A8D, 0xC277}, //4515 #HANGUL SYLLABLE SIOS WI RIEULPIEUP + {0x9A8E, 0xC278}, //4516 #HANGUL SYLLABLE SIOS WI RIEULSIOS + {0x9A8F, 0xC279}, //4517 #HANGUL SYLLABLE SIOS WI RIEULTHIEUTH + {0x9A90, 0xC27A}, //4518 #HANGUL SYLLABLE SIOS WI RIEULPHIEUPH + {0x9A91, 0xC27B}, //4519 #HANGUL SYLLABLE SIOS WI RIEULHIEUH + {0x9A92, 0xC27E}, //4520 #HANGUL SYLLABLE SIOS WI PIEUPSIOS + {0x9A93, 0xC280}, //4521 #HANGUL SYLLABLE SIOS WI SSANGSIOS + {0x9A94, 0xC282}, //4522 #HANGUL SYLLABLE SIOS WI CIEUC + {0x9A95, 0xC283}, //4523 #HANGUL SYLLABLE SIOS WI CHIEUCH + {0x9A96, 0xC284}, //4524 #HANGUL SYLLABLE SIOS WI KHIEUKH + {0x9A97, 0xC285}, //4525 #HANGUL SYLLABLE SIOS WI THIEUTH + {0x9A98, 0xC286}, //4526 #HANGUL SYLLABLE SIOS WI PHIEUPH + {0x9A99, 0xC287}, //4527 #HANGUL SYLLABLE SIOS WI HIEUH + {0x9A9A, 0xC28A}, //4528 #HANGUL SYLLABLE SIOS YU SSANGKIYEOK + {0x9A9B, 0xC28B}, //4529 #HANGUL SYLLABLE SIOS YU KIYEOKSIOS + {0x9A9C, 0xC28C}, //4530 #HANGUL SYLLABLE SIOS YU NIEUN + {0x9A9D, 0xC28D}, //4531 #HANGUL SYLLABLE SIOS YU NIEUNCIEUC + {0x9A9E, 0xC28E}, //4532 #HANGUL SYLLABLE SIOS YU NIEUNHIEUH + {0x9A9F, 0xC28F}, //4533 #HANGUL SYLLABLE SIOS YU TIKEUT + {0x9AA0, 0xC291}, //4534 #HANGUL SYLLABLE SIOS YU RIEULKIYEOK + {0x9AA1, 0xC292}, //4535 #HANGUL SYLLABLE SIOS YU RIEULMIEUM + {0x9AA2, 0xC293}, //4536 #HANGUL SYLLABLE SIOS YU RIEULPIEUP + {0x9AA3, 0xC294}, //4537 #HANGUL SYLLABLE SIOS YU RIEULSIOS + {0x9AA4, 0xC295}, //4538 #HANGUL SYLLABLE SIOS YU RIEULTHIEUTH + {0x9AA5, 0xC296}, //4539 #HANGUL SYLLABLE SIOS YU RIEULPHIEUPH + {0x9AA6, 0xC297}, //4540 #HANGUL SYLLABLE SIOS YU RIEULHIEUH + {0x9AA7, 0xC299}, //4541 #HANGUL SYLLABLE SIOS YU PIEUP + {0x9AA8, 0xC29A}, //4542 #HANGUL SYLLABLE SIOS YU PIEUPSIOS + {0x9AA9, 0xC29C}, //4543 #HANGUL SYLLABLE SIOS YU SSANGSIOS + {0x9AAA, 0xC29E}, //4544 #HANGUL SYLLABLE SIOS YU CIEUC + {0x9AAB, 0xC29F}, //4545 #HANGUL SYLLABLE SIOS YU CHIEUCH + {0x9AAC, 0xC2A0}, //4546 #HANGUL SYLLABLE SIOS YU KHIEUKH + {0x9AAD, 0xC2A1}, //4547 #HANGUL SYLLABLE SIOS YU THIEUTH + {0x9AAE, 0xC2A2}, //4548 #HANGUL SYLLABLE SIOS YU PHIEUPH + {0x9AAF, 0xC2A3}, //4549 #HANGUL SYLLABLE SIOS YU HIEUH + {0x9AB0, 0xC2A6}, //4550 #HANGUL SYLLABLE SIOS EU SSANGKIYEOK + {0x9AB1, 0xC2A7}, //4551 #HANGUL SYLLABLE SIOS EU KIYEOKSIOS + {0x9AB2, 0xC2A9}, //4552 #HANGUL SYLLABLE SIOS EU NIEUNCIEUC + {0x9AB3, 0xC2AA}, //4553 #HANGUL SYLLABLE SIOS EU NIEUNHIEUH + {0x9AB4, 0xC2AB}, //4554 #HANGUL SYLLABLE SIOS EU TIKEUT + {0x9AB5, 0xC2AE}, //4555 #HANGUL SYLLABLE SIOS EU RIEULMIEUM + {0x9AB6, 0xC2AF}, //4556 #HANGUL SYLLABLE SIOS EU RIEULPIEUP + {0x9AB7, 0xC2B0}, //4557 #HANGUL SYLLABLE SIOS EU RIEULSIOS + {0x9AB8, 0xC2B1}, //4558 #HANGUL SYLLABLE SIOS EU RIEULTHIEUTH + {0x9AB9, 0xC2B2}, //4559 #HANGUL SYLLABLE SIOS EU RIEULPHIEUPH + {0x9ABA, 0xC2B3}, //4560 #HANGUL SYLLABLE SIOS EU RIEULHIEUH + {0x9ABB, 0xC2B6}, //4561 #HANGUL SYLLABLE SIOS EU PIEUPSIOS + {0x9ABC, 0xC2B8}, //4562 #HANGUL SYLLABLE SIOS EU SSANGSIOS + {0x9ABD, 0xC2BA}, //4563 #HANGUL SYLLABLE SIOS EU CIEUC + {0x9ABE, 0xC2BB}, //4564 #HANGUL SYLLABLE SIOS EU CHIEUCH + {0x9ABF, 0xC2BC}, //4565 #HANGUL SYLLABLE SIOS EU KHIEUKH + {0x9AC0, 0xC2BD}, //4566 #HANGUL SYLLABLE SIOS EU THIEUTH + {0x9AC1, 0xC2BE}, //4567 #HANGUL SYLLABLE SIOS EU PHIEUPH + {0x9AC2, 0xC2BF}, //4568 #HANGUL SYLLABLE SIOS EU HIEUH + {0x9AC3, 0xC2C0}, //4569 #HANGUL SYLLABLE SIOS YI + {0x9AC4, 0xC2C1}, //4570 #HANGUL SYLLABLE SIOS YI KIYEOK + {0x9AC5, 0xC2C2}, //4571 #HANGUL SYLLABLE SIOS YI SSANGKIYEOK + {0x9AC6, 0xC2C3}, //4572 #HANGUL SYLLABLE SIOS YI KIYEOKSIOS + {0x9AC7, 0xC2C4}, //4573 #HANGUL SYLLABLE SIOS YI NIEUN + {0x9AC8, 0xC2C5}, //4574 #HANGUL SYLLABLE SIOS YI NIEUNCIEUC + {0x9AC9, 0xC2C6}, //4575 #HANGUL SYLLABLE SIOS YI NIEUNHIEUH + {0x9ACA, 0xC2C7}, //4576 #HANGUL SYLLABLE SIOS YI TIKEUT + {0x9ACB, 0xC2C8}, //4577 #HANGUL SYLLABLE SIOS YI RIEUL + {0x9ACC, 0xC2C9}, //4578 #HANGUL SYLLABLE SIOS YI RIEULKIYEOK + {0x9ACD, 0xC2CA}, //4579 #HANGUL SYLLABLE SIOS YI RIEULMIEUM + {0x9ACE, 0xC2CB}, //4580 #HANGUL SYLLABLE SIOS YI RIEULPIEUP + {0x9ACF, 0xC2CC}, //4581 #HANGUL SYLLABLE SIOS YI RIEULSIOS + {0x9AD0, 0xC2CD}, //4582 #HANGUL SYLLABLE SIOS YI RIEULTHIEUTH + {0x9AD1, 0xC2CE}, //4583 #HANGUL SYLLABLE SIOS YI RIEULPHIEUPH + {0x9AD2, 0xC2CF}, //4584 #HANGUL SYLLABLE SIOS YI RIEULHIEUH + {0x9AD3, 0xC2D0}, //4585 #HANGUL SYLLABLE SIOS YI MIEUM + {0x9AD4, 0xC2D1}, //4586 #HANGUL SYLLABLE SIOS YI PIEUP + {0x9AD5, 0xC2D2}, //4587 #HANGUL SYLLABLE SIOS YI PIEUPSIOS + {0x9AD6, 0xC2D3}, //4588 #HANGUL SYLLABLE SIOS YI SIOS + {0x9AD7, 0xC2D4}, //4589 #HANGUL SYLLABLE SIOS YI SSANGSIOS + {0x9AD8, 0xC2D5}, //4590 #HANGUL SYLLABLE SIOS YI IEUNG + {0x9AD9, 0xC2D6}, //4591 #HANGUL SYLLABLE SIOS YI CIEUC + {0x9ADA, 0xC2D7}, //4592 #HANGUL SYLLABLE SIOS YI CHIEUCH + {0x9ADB, 0xC2D8}, //4593 #HANGUL SYLLABLE SIOS YI KHIEUKH + {0x9ADC, 0xC2D9}, //4594 #HANGUL SYLLABLE SIOS YI THIEUTH + {0x9ADD, 0xC2DA}, //4595 #HANGUL SYLLABLE SIOS YI PHIEUPH + {0x9ADE, 0xC2DB}, //4596 #HANGUL SYLLABLE SIOS YI HIEUH + {0x9ADF, 0xC2DE}, //4597 #HANGUL SYLLABLE SIOS I SSANGKIYEOK + {0x9AE0, 0xC2DF}, //4598 #HANGUL SYLLABLE SIOS I KIYEOKSIOS + {0x9AE1, 0xC2E1}, //4599 #HANGUL SYLLABLE SIOS I NIEUNCIEUC + {0x9AE2, 0xC2E2}, //4600 #HANGUL SYLLABLE SIOS I NIEUNHIEUH + {0x9AE3, 0xC2E5}, //4601 #HANGUL SYLLABLE SIOS I RIEULKIYEOK + {0x9AE4, 0xC2E6}, //4602 #HANGUL SYLLABLE SIOS I RIEULMIEUM + {0x9AE5, 0xC2E7}, //4603 #HANGUL SYLLABLE SIOS I RIEULPIEUP + {0x9AE6, 0xC2E8}, //4604 #HANGUL SYLLABLE SIOS I RIEULSIOS + {0x9AE7, 0xC2E9}, //4605 #HANGUL SYLLABLE SIOS I RIEULTHIEUTH + {0x9AE8, 0xC2EA}, //4606 #HANGUL SYLLABLE SIOS I RIEULPHIEUPH + {0x9AE9, 0xC2EE}, //4607 #HANGUL SYLLABLE SIOS I PIEUPSIOS + {0x9AEA, 0xC2F0}, //4608 #HANGUL SYLLABLE SIOS I SSANGSIOS + {0x9AEB, 0xC2F2}, //4609 #HANGUL SYLLABLE SIOS I CIEUC + {0x9AEC, 0xC2F3}, //4610 #HANGUL SYLLABLE SIOS I CHIEUCH + {0x9AED, 0xC2F4}, //4611 #HANGUL SYLLABLE SIOS I KHIEUKH + {0x9AEE, 0xC2F5}, //4612 #HANGUL SYLLABLE SIOS I THIEUTH + {0x9AEF, 0xC2F7}, //4613 #HANGUL SYLLABLE SIOS I HIEUH + {0x9AF0, 0xC2FA}, //4614 #HANGUL SYLLABLE SSANGSIOS A SSANGKIYEOK + {0x9AF1, 0xC2FD}, //4615 #HANGUL SYLLABLE SSANGSIOS A NIEUNCIEUC + {0x9AF2, 0xC2FE}, //4616 #HANGUL SYLLABLE SSANGSIOS A NIEUNHIEUH + {0x9AF3, 0xC2FF}, //4617 #HANGUL SYLLABLE SSANGSIOS A TIKEUT + {0x9AF4, 0xC301}, //4618 #HANGUL SYLLABLE SSANGSIOS A RIEULKIYEOK + {0x9AF5, 0xC302}, //4619 #HANGUL SYLLABLE SSANGSIOS A RIEULMIEUM + {0x9AF6, 0xC303}, //4620 #HANGUL SYLLABLE SSANGSIOS A RIEULPIEUP + {0x9AF7, 0xC304}, //4621 #HANGUL SYLLABLE SSANGSIOS A RIEULSIOS + {0x9AF8, 0xC305}, //4622 #HANGUL SYLLABLE SSANGSIOS A RIEULTHIEUTH + {0x9AF9, 0xC306}, //4623 #HANGUL SYLLABLE SSANGSIOS A RIEULPHIEUPH + {0x9AFA, 0xC307}, //4624 #HANGUL SYLLABLE SSANGSIOS A RIEULHIEUH + {0x9AFB, 0xC30A}, //4625 #HANGUL SYLLABLE SSANGSIOS A PIEUPSIOS + {0x9AFC, 0xC30B}, //4626 #HANGUL SYLLABLE SSANGSIOS A SIOS + {0x9AFD, 0xC30E}, //4627 #HANGUL SYLLABLE SSANGSIOS A CIEUC + {0x9AFE, 0xC30F}, //4628 #HANGUL SYLLABLE SSANGSIOS A CHIEUCH + {0x9B41, 0xC310}, //4629 #HANGUL SYLLABLE SSANGSIOS A KHIEUKH + {0x9B42, 0xC311}, //4630 #HANGUL SYLLABLE SSANGSIOS A THIEUTH + {0x9B43, 0xC312}, //4631 #HANGUL SYLLABLE SSANGSIOS A PHIEUPH + {0x9B44, 0xC316}, //4632 #HANGUL SYLLABLE SSANGSIOS AE SSANGKIYEOK + {0x9B45, 0xC317}, //4633 #HANGUL SYLLABLE SSANGSIOS AE KIYEOKSIOS + {0x9B46, 0xC319}, //4634 #HANGUL SYLLABLE SSANGSIOS AE NIEUNCIEUC + {0x9B47, 0xC31A}, //4635 #HANGUL SYLLABLE SSANGSIOS AE NIEUNHIEUH + {0x9B48, 0xC31B}, //4636 #HANGUL SYLLABLE SSANGSIOS AE TIKEUT + {0x9B49, 0xC31D}, //4637 #HANGUL SYLLABLE SSANGSIOS AE RIEULKIYEOK + {0x9B4A, 0xC31E}, //4638 #HANGUL SYLLABLE SSANGSIOS AE RIEULMIEUM + {0x9B4B, 0xC31F}, //4639 #HANGUL SYLLABLE SSANGSIOS AE RIEULPIEUP + {0x9B4C, 0xC320}, //4640 #HANGUL SYLLABLE SSANGSIOS AE RIEULSIOS + {0x9B4D, 0xC321}, //4641 #HANGUL SYLLABLE SSANGSIOS AE RIEULTHIEUTH + {0x9B4E, 0xC322}, //4642 #HANGUL SYLLABLE SSANGSIOS AE RIEULPHIEUPH + {0x9B4F, 0xC323}, //4643 #HANGUL SYLLABLE SSANGSIOS AE RIEULHIEUH + {0x9B50, 0xC326}, //4644 #HANGUL SYLLABLE SSANGSIOS AE PIEUPSIOS + {0x9B51, 0xC327}, //4645 #HANGUL SYLLABLE SSANGSIOS AE SIOS + {0x9B52, 0xC32A}, //4646 #HANGUL SYLLABLE SSANGSIOS AE CIEUC + {0x9B53, 0xC32B}, //4647 #HANGUL SYLLABLE SSANGSIOS AE CHIEUCH + {0x9B54, 0xC32C}, //4648 #HANGUL SYLLABLE SSANGSIOS AE KHIEUKH + {0x9B55, 0xC32D}, //4649 #HANGUL SYLLABLE SSANGSIOS AE THIEUTH + {0x9B56, 0xC32E}, //4650 #HANGUL SYLLABLE SSANGSIOS AE PHIEUPH + {0x9B57, 0xC32F}, //4651 #HANGUL SYLLABLE SSANGSIOS AE HIEUH + {0x9B58, 0xC330}, //4652 #HANGUL SYLLABLE SSANGSIOS YA + {0x9B59, 0xC331}, //4653 #HANGUL SYLLABLE SSANGSIOS YA KIYEOK + {0x9B5A, 0xC332}, //4654 #HANGUL SYLLABLE SSANGSIOS YA SSANGKIYEOK + {0x9B61, 0xC333}, //4655 #HANGUL SYLLABLE SSANGSIOS YA KIYEOKSIOS + {0x9B62, 0xC334}, //4656 #HANGUL SYLLABLE SSANGSIOS YA NIEUN + {0x9B63, 0xC335}, //4657 #HANGUL SYLLABLE SSANGSIOS YA NIEUNCIEUC + {0x9B64, 0xC336}, //4658 #HANGUL SYLLABLE SSANGSIOS YA NIEUNHIEUH + {0x9B65, 0xC337}, //4659 #HANGUL SYLLABLE SSANGSIOS YA TIKEUT + {0x9B66, 0xC338}, //4660 #HANGUL SYLLABLE SSANGSIOS YA RIEUL + {0x9B67, 0xC339}, //4661 #HANGUL SYLLABLE SSANGSIOS YA RIEULKIYEOK + {0x9B68, 0xC33A}, //4662 #HANGUL SYLLABLE SSANGSIOS YA RIEULMIEUM + {0x9B69, 0xC33B}, //4663 #HANGUL SYLLABLE SSANGSIOS YA RIEULPIEUP + {0x9B6A, 0xC33C}, //4664 #HANGUL SYLLABLE SSANGSIOS YA RIEULSIOS + {0x9B6B, 0xC33D}, //4665 #HANGUL SYLLABLE SSANGSIOS YA RIEULTHIEUTH + {0x9B6C, 0xC33E}, //4666 #HANGUL SYLLABLE SSANGSIOS YA RIEULPHIEUPH + {0x9B6D, 0xC33F}, //4667 #HANGUL SYLLABLE SSANGSIOS YA RIEULHIEUH + {0x9B6E, 0xC340}, //4668 #HANGUL SYLLABLE SSANGSIOS YA MIEUM + {0x9B6F, 0xC341}, //4669 #HANGUL SYLLABLE SSANGSIOS YA PIEUP + {0x9B70, 0xC342}, //4670 #HANGUL SYLLABLE SSANGSIOS YA PIEUPSIOS + {0x9B71, 0xC343}, //4671 #HANGUL SYLLABLE SSANGSIOS YA SIOS + {0x9B72, 0xC344}, //4672 #HANGUL SYLLABLE SSANGSIOS YA SSANGSIOS + {0x9B73, 0xC346}, //4673 #HANGUL SYLLABLE SSANGSIOS YA CIEUC + {0x9B74, 0xC347}, //4674 #HANGUL SYLLABLE SSANGSIOS YA CHIEUCH + {0x9B75, 0xC348}, //4675 #HANGUL SYLLABLE SSANGSIOS YA KHIEUKH + {0x9B76, 0xC349}, //4676 #HANGUL SYLLABLE SSANGSIOS YA THIEUTH + {0x9B77, 0xC34A}, //4677 #HANGUL SYLLABLE SSANGSIOS YA PHIEUPH + {0x9B78, 0xC34B}, //4678 #HANGUL SYLLABLE SSANGSIOS YA HIEUH + {0x9B79, 0xC34C}, //4679 #HANGUL SYLLABLE SSANGSIOS YAE + {0x9B7A, 0xC34D}, //4680 #HANGUL SYLLABLE SSANGSIOS YAE KIYEOK + {0x9B81, 0xC34E}, //4681 #HANGUL SYLLABLE SSANGSIOS YAE SSANGKIYEOK + {0x9B82, 0xC34F}, //4682 #HANGUL SYLLABLE SSANGSIOS YAE KIYEOKSIOS + {0x9B83, 0xC350}, //4683 #HANGUL SYLLABLE SSANGSIOS YAE NIEUN + {0x9B84, 0xC351}, //4684 #HANGUL SYLLABLE SSANGSIOS YAE NIEUNCIEUC + {0x9B85, 0xC352}, //4685 #HANGUL SYLLABLE SSANGSIOS YAE NIEUNHIEUH + {0x9B86, 0xC353}, //4686 #HANGUL SYLLABLE SSANGSIOS YAE TIKEUT + {0x9B87, 0xC354}, //4687 #HANGUL SYLLABLE SSANGSIOS YAE RIEUL + {0x9B88, 0xC355}, //4688 #HANGUL SYLLABLE SSANGSIOS YAE RIEULKIYEOK + {0x9B89, 0xC356}, //4689 #HANGUL SYLLABLE SSANGSIOS YAE RIEULMIEUM + {0x9B8A, 0xC357}, //4690 #HANGUL SYLLABLE SSANGSIOS YAE RIEULPIEUP + {0x9B8B, 0xC358}, //4691 #HANGUL SYLLABLE SSANGSIOS YAE RIEULSIOS + {0x9B8C, 0xC359}, //4692 #HANGUL SYLLABLE SSANGSIOS YAE RIEULTHIEUTH + {0x9B8D, 0xC35A}, //4693 #HANGUL SYLLABLE SSANGSIOS YAE RIEULPHIEUPH + {0x9B8E, 0xC35B}, //4694 #HANGUL SYLLABLE SSANGSIOS YAE RIEULHIEUH + {0x9B8F, 0xC35C}, //4695 #HANGUL SYLLABLE SSANGSIOS YAE MIEUM + {0x9B90, 0xC35D}, //4696 #HANGUL SYLLABLE SSANGSIOS YAE PIEUP + {0x9B91, 0xC35E}, //4697 #HANGUL SYLLABLE SSANGSIOS YAE PIEUPSIOS + {0x9B92, 0xC35F}, //4698 #HANGUL SYLLABLE SSANGSIOS YAE SIOS + {0x9B93, 0xC360}, //4699 #HANGUL SYLLABLE SSANGSIOS YAE SSANGSIOS + {0x9B94, 0xC361}, //4700 #HANGUL SYLLABLE SSANGSIOS YAE IEUNG + {0x9B95, 0xC362}, //4701 #HANGUL SYLLABLE SSANGSIOS YAE CIEUC + {0x9B96, 0xC363}, //4702 #HANGUL SYLLABLE SSANGSIOS YAE CHIEUCH + {0x9B97, 0xC364}, //4703 #HANGUL SYLLABLE SSANGSIOS YAE KHIEUKH + {0x9B98, 0xC365}, //4704 #HANGUL SYLLABLE SSANGSIOS YAE THIEUTH + {0x9B99, 0xC366}, //4705 #HANGUL SYLLABLE SSANGSIOS YAE PHIEUPH + {0x9B9A, 0xC367}, //4706 #HANGUL SYLLABLE SSANGSIOS YAE HIEUH + {0x9B9B, 0xC36A}, //4707 #HANGUL SYLLABLE SSANGSIOS EO SSANGKIYEOK + {0x9B9C, 0xC36B}, //4708 #HANGUL SYLLABLE SSANGSIOS EO KIYEOKSIOS + {0x9B9D, 0xC36D}, //4709 #HANGUL SYLLABLE SSANGSIOS EO NIEUNCIEUC + {0x9B9E, 0xC36E}, //4710 #HANGUL SYLLABLE SSANGSIOS EO NIEUNHIEUH + {0x9B9F, 0xC36F}, //4711 #HANGUL SYLLABLE SSANGSIOS EO TIKEUT + {0x9BA0, 0xC371}, //4712 #HANGUL SYLLABLE SSANGSIOS EO RIEULKIYEOK + {0x9BA1, 0xC373}, //4713 #HANGUL SYLLABLE SSANGSIOS EO RIEULPIEUP + {0x9BA2, 0xC374}, //4714 #HANGUL SYLLABLE SSANGSIOS EO RIEULSIOS + {0x9BA3, 0xC375}, //4715 #HANGUL SYLLABLE SSANGSIOS EO RIEULTHIEUTH + {0x9BA4, 0xC376}, //4716 #HANGUL SYLLABLE SSANGSIOS EO RIEULPHIEUPH + {0x9BA5, 0xC377}, //4717 #HANGUL SYLLABLE SSANGSIOS EO RIEULHIEUH + {0x9BA6, 0xC37A}, //4718 #HANGUL SYLLABLE SSANGSIOS EO PIEUPSIOS + {0x9BA7, 0xC37B}, //4719 #HANGUL SYLLABLE SSANGSIOS EO SIOS + {0x9BA8, 0xC37E}, //4720 #HANGUL SYLLABLE SSANGSIOS EO CIEUC + {0x9BA9, 0xC37F}, //4721 #HANGUL SYLLABLE SSANGSIOS EO CHIEUCH + {0x9BAA, 0xC380}, //4722 #HANGUL SYLLABLE SSANGSIOS EO KHIEUKH + {0x9BAB, 0xC381}, //4723 #HANGUL SYLLABLE SSANGSIOS EO THIEUTH + {0x9BAC, 0xC382}, //4724 #HANGUL SYLLABLE SSANGSIOS EO PHIEUPH + {0x9BAD, 0xC383}, //4725 #HANGUL SYLLABLE SSANGSIOS EO HIEUH + {0x9BAE, 0xC385}, //4726 #HANGUL SYLLABLE SSANGSIOS E KIYEOK + {0x9BAF, 0xC386}, //4727 #HANGUL SYLLABLE SSANGSIOS E SSANGKIYEOK + {0x9BB0, 0xC387}, //4728 #HANGUL SYLLABLE SSANGSIOS E KIYEOKSIOS + {0x9BB1, 0xC389}, //4729 #HANGUL SYLLABLE SSANGSIOS E NIEUNCIEUC + {0x9BB2, 0xC38A}, //4730 #HANGUL SYLLABLE SSANGSIOS E NIEUNHIEUH + {0x9BB3, 0xC38B}, //4731 #HANGUL SYLLABLE SSANGSIOS E TIKEUT + {0x9BB4, 0xC38D}, //4732 #HANGUL SYLLABLE SSANGSIOS E RIEULKIYEOK + {0x9BB5, 0xC38E}, //4733 #HANGUL SYLLABLE SSANGSIOS E RIEULMIEUM + {0x9BB6, 0xC38F}, //4734 #HANGUL SYLLABLE SSANGSIOS E RIEULPIEUP + {0x9BB7, 0xC390}, //4735 #HANGUL SYLLABLE SSANGSIOS E RIEULSIOS + {0x9BB8, 0xC391}, //4736 #HANGUL SYLLABLE SSANGSIOS E RIEULTHIEUTH + {0x9BB9, 0xC392}, //4737 #HANGUL SYLLABLE SSANGSIOS E RIEULPHIEUPH + {0x9BBA, 0xC393}, //4738 #HANGUL SYLLABLE SSANGSIOS E RIEULHIEUH + {0x9BBB, 0xC394}, //4739 #HANGUL SYLLABLE SSANGSIOS E MIEUM + {0x9BBC, 0xC395}, //4740 #HANGUL SYLLABLE SSANGSIOS E PIEUP + {0x9BBD, 0xC396}, //4741 #HANGUL SYLLABLE SSANGSIOS E PIEUPSIOS + {0x9BBE, 0xC397}, //4742 #HANGUL SYLLABLE SSANGSIOS E SIOS + {0x9BBF, 0xC398}, //4743 #HANGUL SYLLABLE SSANGSIOS E SSANGSIOS + {0x9BC0, 0xC399}, //4744 #HANGUL SYLLABLE SSANGSIOS E IEUNG + {0x9BC1, 0xC39A}, //4745 #HANGUL SYLLABLE SSANGSIOS E CIEUC + {0x9BC2, 0xC39B}, //4746 #HANGUL SYLLABLE SSANGSIOS E CHIEUCH + {0x9BC3, 0xC39C}, //4747 #HANGUL SYLLABLE SSANGSIOS E KHIEUKH + {0x9BC4, 0xC39D}, //4748 #HANGUL SYLLABLE SSANGSIOS E THIEUTH + {0x9BC5, 0xC39E}, //4749 #HANGUL SYLLABLE SSANGSIOS E PHIEUPH + {0x9BC6, 0xC39F}, //4750 #HANGUL SYLLABLE SSANGSIOS E HIEUH + {0x9BC7, 0xC3A0}, //4751 #HANGUL SYLLABLE SSANGSIOS YEO + {0x9BC8, 0xC3A1}, //4752 #HANGUL SYLLABLE SSANGSIOS YEO KIYEOK + {0x9BC9, 0xC3A2}, //4753 #HANGUL SYLLABLE SSANGSIOS YEO SSANGKIYEOK + {0x9BCA, 0xC3A3}, //4754 #HANGUL SYLLABLE SSANGSIOS YEO KIYEOKSIOS + {0x9BCB, 0xC3A4}, //4755 #HANGUL SYLLABLE SSANGSIOS YEO NIEUN + {0x9BCC, 0xC3A5}, //4756 #HANGUL SYLLABLE SSANGSIOS YEO NIEUNCIEUC + {0x9BCD, 0xC3A6}, //4757 #HANGUL SYLLABLE SSANGSIOS YEO NIEUNHIEUH + {0x9BCE, 0xC3A7}, //4758 #HANGUL SYLLABLE SSANGSIOS YEO TIKEUT + {0x9BCF, 0xC3A8}, //4759 #HANGUL SYLLABLE SSANGSIOS YEO RIEUL + {0x9BD0, 0xC3A9}, //4760 #HANGUL SYLLABLE SSANGSIOS YEO RIEULKIYEOK + {0x9BD1, 0xC3AA}, //4761 #HANGUL SYLLABLE SSANGSIOS YEO RIEULMIEUM + {0x9BD2, 0xC3AB}, //4762 #HANGUL SYLLABLE SSANGSIOS YEO RIEULPIEUP + {0x9BD3, 0xC3AC}, //4763 #HANGUL SYLLABLE SSANGSIOS YEO RIEULSIOS + {0x9BD4, 0xC3AD}, //4764 #HANGUL SYLLABLE SSANGSIOS YEO RIEULTHIEUTH + {0x9BD5, 0xC3AE}, //4765 #HANGUL SYLLABLE SSANGSIOS YEO RIEULPHIEUPH + {0x9BD6, 0xC3AF}, //4766 #HANGUL SYLLABLE SSANGSIOS YEO RIEULHIEUH + {0x9BD7, 0xC3B0}, //4767 #HANGUL SYLLABLE SSANGSIOS YEO MIEUM + {0x9BD8, 0xC3B1}, //4768 #HANGUL SYLLABLE SSANGSIOS YEO PIEUP + {0x9BD9, 0xC3B2}, //4769 #HANGUL SYLLABLE SSANGSIOS YEO PIEUPSIOS + {0x9BDA, 0xC3B3}, //4770 #HANGUL SYLLABLE SSANGSIOS YEO SIOS + {0x9BDB, 0xC3B4}, //4771 #HANGUL SYLLABLE SSANGSIOS YEO SSANGSIOS + {0x9BDC, 0xC3B5}, //4772 #HANGUL SYLLABLE SSANGSIOS YEO IEUNG + {0x9BDD, 0xC3B6}, //4773 #HANGUL SYLLABLE SSANGSIOS YEO CIEUC + {0x9BDE, 0xC3B7}, //4774 #HANGUL SYLLABLE SSANGSIOS YEO CHIEUCH + {0x9BDF, 0xC3B8}, //4775 #HANGUL SYLLABLE SSANGSIOS YEO KHIEUKH + {0x9BE0, 0xC3B9}, //4776 #HANGUL SYLLABLE SSANGSIOS YEO THIEUTH + {0x9BE1, 0xC3BA}, //4777 #HANGUL SYLLABLE SSANGSIOS YEO PHIEUPH + {0x9BE2, 0xC3BB}, //4778 #HANGUL SYLLABLE SSANGSIOS YEO HIEUH + {0x9BE3, 0xC3BC}, //4779 #HANGUL SYLLABLE SSANGSIOS YE + {0x9BE4, 0xC3BD}, //4780 #HANGUL SYLLABLE SSANGSIOS YE KIYEOK + {0x9BE5, 0xC3BE}, //4781 #HANGUL SYLLABLE SSANGSIOS YE SSANGKIYEOK + {0x9BE6, 0xC3BF}, //4782 #HANGUL SYLLABLE SSANGSIOS YE KIYEOKSIOS + {0x9BE7, 0xC3C1}, //4783 #HANGUL SYLLABLE SSANGSIOS YE NIEUNCIEUC + {0x9BE8, 0xC3C2}, //4784 #HANGUL SYLLABLE SSANGSIOS YE NIEUNHIEUH + {0x9BE9, 0xC3C3}, //4785 #HANGUL SYLLABLE SSANGSIOS YE TIKEUT + {0x9BEA, 0xC3C4}, //4786 #HANGUL SYLLABLE SSANGSIOS YE RIEUL + {0x9BEB, 0xC3C5}, //4787 #HANGUL SYLLABLE SSANGSIOS YE RIEULKIYEOK + {0x9BEC, 0xC3C6}, //4788 #HANGUL SYLLABLE SSANGSIOS YE RIEULMIEUM + {0x9BED, 0xC3C7}, //4789 #HANGUL SYLLABLE SSANGSIOS YE RIEULPIEUP + {0x9BEE, 0xC3C8}, //4790 #HANGUL SYLLABLE SSANGSIOS YE RIEULSIOS + {0x9BEF, 0xC3C9}, //4791 #HANGUL SYLLABLE SSANGSIOS YE RIEULTHIEUTH + {0x9BF0, 0xC3CA}, //4792 #HANGUL SYLLABLE SSANGSIOS YE RIEULPHIEUPH + {0x9BF1, 0xC3CB}, //4793 #HANGUL SYLLABLE SSANGSIOS YE RIEULHIEUH + {0x9BF2, 0xC3CC}, //4794 #HANGUL SYLLABLE SSANGSIOS YE MIEUM + {0x9BF3, 0xC3CD}, //4795 #HANGUL SYLLABLE SSANGSIOS YE PIEUP + {0x9BF4, 0xC3CE}, //4796 #HANGUL SYLLABLE SSANGSIOS YE PIEUPSIOS + {0x9BF5, 0xC3CF}, //4797 #HANGUL SYLLABLE SSANGSIOS YE SIOS + {0x9BF6, 0xC3D0}, //4798 #HANGUL SYLLABLE SSANGSIOS YE SSANGSIOS + {0x9BF7, 0xC3D1}, //4799 #HANGUL SYLLABLE SSANGSIOS YE IEUNG + {0x9BF8, 0xC3D2}, //4800 #HANGUL SYLLABLE SSANGSIOS YE CIEUC + {0x9BF9, 0xC3D3}, //4801 #HANGUL SYLLABLE SSANGSIOS YE CHIEUCH + {0x9BFA, 0xC3D4}, //4802 #HANGUL SYLLABLE SSANGSIOS YE KHIEUKH + {0x9BFB, 0xC3D5}, //4803 #HANGUL SYLLABLE SSANGSIOS YE THIEUTH + {0x9BFC, 0xC3D6}, //4804 #HANGUL SYLLABLE SSANGSIOS YE PHIEUPH + {0x9BFD, 0xC3D7}, //4805 #HANGUL SYLLABLE SSANGSIOS YE HIEUH + {0x9BFE, 0xC3DA}, //4806 #HANGUL SYLLABLE SSANGSIOS O SSANGKIYEOK + {0x9C41, 0xC3DB}, //4807 #HANGUL SYLLABLE SSANGSIOS O KIYEOKSIOS + {0x9C42, 0xC3DD}, //4808 #HANGUL SYLLABLE SSANGSIOS O NIEUNCIEUC + {0x9C43, 0xC3DE}, //4809 #HANGUL SYLLABLE SSANGSIOS O NIEUNHIEUH + {0x9C44, 0xC3E1}, //4810 #HANGUL SYLLABLE SSANGSIOS O RIEULKIYEOK + {0x9C45, 0xC3E3}, //4811 #HANGUL SYLLABLE SSANGSIOS O RIEULPIEUP + {0x9C46, 0xC3E4}, //4812 #HANGUL SYLLABLE SSANGSIOS O RIEULSIOS + {0x9C47, 0xC3E5}, //4813 #HANGUL SYLLABLE SSANGSIOS O RIEULTHIEUTH + {0x9C48, 0xC3E6}, //4814 #HANGUL SYLLABLE SSANGSIOS O RIEULPHIEUPH + {0x9C49, 0xC3E7}, //4815 #HANGUL SYLLABLE SSANGSIOS O RIEULHIEUH + {0x9C4A, 0xC3EA}, //4816 #HANGUL SYLLABLE SSANGSIOS O PIEUPSIOS + {0x9C4B, 0xC3EB}, //4817 #HANGUL SYLLABLE SSANGSIOS O SIOS + {0x9C4C, 0xC3EC}, //4818 #HANGUL SYLLABLE SSANGSIOS O SSANGSIOS + {0x9C4D, 0xC3EE}, //4819 #HANGUL SYLLABLE SSANGSIOS O CIEUC + {0x9C4E, 0xC3EF}, //4820 #HANGUL SYLLABLE SSANGSIOS O CHIEUCH + {0x9C4F, 0xC3F0}, //4821 #HANGUL SYLLABLE SSANGSIOS O KHIEUKH + {0x9C50, 0xC3F1}, //4822 #HANGUL SYLLABLE SSANGSIOS O THIEUTH + {0x9C51, 0xC3F2}, //4823 #HANGUL SYLLABLE SSANGSIOS O PHIEUPH + {0x9C52, 0xC3F3}, //4824 #HANGUL SYLLABLE SSANGSIOS O HIEUH + {0x9C53, 0xC3F6}, //4825 #HANGUL SYLLABLE SSANGSIOS WA SSANGKIYEOK + {0x9C54, 0xC3F7}, //4826 #HANGUL SYLLABLE SSANGSIOS WA KIYEOKSIOS + {0x9C55, 0xC3F9}, //4827 #HANGUL SYLLABLE SSANGSIOS WA NIEUNCIEUC + {0x9C56, 0xC3FA}, //4828 #HANGUL SYLLABLE SSANGSIOS WA NIEUNHIEUH + {0x9C57, 0xC3FB}, //4829 #HANGUL SYLLABLE SSANGSIOS WA TIKEUT + {0x9C58, 0xC3FC}, //4830 #HANGUL SYLLABLE SSANGSIOS WA RIEUL + {0x9C59, 0xC3FD}, //4831 #HANGUL SYLLABLE SSANGSIOS WA RIEULKIYEOK + {0x9C5A, 0xC3FE}, //4832 #HANGUL SYLLABLE SSANGSIOS WA RIEULMIEUM + {0x9C61, 0xC3FF}, //4833 #HANGUL SYLLABLE SSANGSIOS WA RIEULPIEUP + {0x9C62, 0xC400}, //4834 #HANGUL SYLLABLE SSANGSIOS WA RIEULSIOS + {0x9C63, 0xC401}, //4835 #HANGUL SYLLABLE SSANGSIOS WA RIEULTHIEUTH + {0x9C64, 0xC402}, //4836 #HANGUL SYLLABLE SSANGSIOS WA RIEULPHIEUPH + {0x9C65, 0xC403}, //4837 #HANGUL SYLLABLE SSANGSIOS WA RIEULHIEUH + {0x9C66, 0xC404}, //4838 #HANGUL SYLLABLE SSANGSIOS WA MIEUM + {0x9C67, 0xC405}, //4839 #HANGUL SYLLABLE SSANGSIOS WA PIEUP + {0x9C68, 0xC406}, //4840 #HANGUL SYLLABLE SSANGSIOS WA PIEUPSIOS + {0x9C69, 0xC407}, //4841 #HANGUL SYLLABLE SSANGSIOS WA SIOS + {0x9C6A, 0xC409}, //4842 #HANGUL SYLLABLE SSANGSIOS WA IEUNG + {0x9C6B, 0xC40A}, //4843 #HANGUL SYLLABLE SSANGSIOS WA CIEUC + {0x9C6C, 0xC40B}, //4844 #HANGUL SYLLABLE SSANGSIOS WA CHIEUCH + {0x9C6D, 0xC40C}, //4845 #HANGUL SYLLABLE SSANGSIOS WA KHIEUKH + {0x9C6E, 0xC40D}, //4846 #HANGUL SYLLABLE SSANGSIOS WA THIEUTH + {0x9C6F, 0xC40E}, //4847 #HANGUL SYLLABLE SSANGSIOS WA PHIEUPH + {0x9C70, 0xC40F}, //4848 #HANGUL SYLLABLE SSANGSIOS WA HIEUH + {0x9C71, 0xC411}, //4849 #HANGUL SYLLABLE SSANGSIOS WAE KIYEOK + {0x9C72, 0xC412}, //4850 #HANGUL SYLLABLE SSANGSIOS WAE SSANGKIYEOK + {0x9C73, 0xC413}, //4851 #HANGUL SYLLABLE SSANGSIOS WAE KIYEOKSIOS + {0x9C74, 0xC414}, //4852 #HANGUL SYLLABLE SSANGSIOS WAE NIEUN + {0x9C75, 0xC415}, //4853 #HANGUL SYLLABLE SSANGSIOS WAE NIEUNCIEUC + {0x9C76, 0xC416}, //4854 #HANGUL SYLLABLE SSANGSIOS WAE NIEUNHIEUH + {0x9C77, 0xC417}, //4855 #HANGUL SYLLABLE SSANGSIOS WAE TIKEUT + {0x9C78, 0xC418}, //4856 #HANGUL SYLLABLE SSANGSIOS WAE RIEUL + {0x9C79, 0xC419}, //4857 #HANGUL SYLLABLE SSANGSIOS WAE RIEULKIYEOK + {0x9C7A, 0xC41A}, //4858 #HANGUL SYLLABLE SSANGSIOS WAE RIEULMIEUM + {0x9C81, 0xC41B}, //4859 #HANGUL SYLLABLE SSANGSIOS WAE RIEULPIEUP + {0x9C82, 0xC41C}, //4860 #HANGUL SYLLABLE SSANGSIOS WAE RIEULSIOS + {0x9C83, 0xC41D}, //4861 #HANGUL SYLLABLE SSANGSIOS WAE RIEULTHIEUTH + {0x9C84, 0xC41E}, //4862 #HANGUL SYLLABLE SSANGSIOS WAE RIEULPHIEUPH + {0x9C85, 0xC41F}, //4863 #HANGUL SYLLABLE SSANGSIOS WAE RIEULHIEUH + {0x9C86, 0xC420}, //4864 #HANGUL SYLLABLE SSANGSIOS WAE MIEUM + {0x9C87, 0xC421}, //4865 #HANGUL SYLLABLE SSANGSIOS WAE PIEUP + {0x9C88, 0xC422}, //4866 #HANGUL SYLLABLE SSANGSIOS WAE PIEUPSIOS + {0x9C89, 0xC423}, //4867 #HANGUL SYLLABLE SSANGSIOS WAE SIOS + {0x9C8A, 0xC425}, //4868 #HANGUL SYLLABLE SSANGSIOS WAE IEUNG + {0x9C8B, 0xC426}, //4869 #HANGUL SYLLABLE SSANGSIOS WAE CIEUC + {0x9C8C, 0xC427}, //4870 #HANGUL SYLLABLE SSANGSIOS WAE CHIEUCH + {0x9C8D, 0xC428}, //4871 #HANGUL SYLLABLE SSANGSIOS WAE KHIEUKH + {0x9C8E, 0xC429}, //4872 #HANGUL SYLLABLE SSANGSIOS WAE THIEUTH + {0x9C8F, 0xC42A}, //4873 #HANGUL SYLLABLE SSANGSIOS WAE PHIEUPH + {0x9C90, 0xC42B}, //4874 #HANGUL SYLLABLE SSANGSIOS WAE HIEUH + {0x9C91, 0xC42D}, //4875 #HANGUL SYLLABLE SSANGSIOS OE KIYEOK + {0x9C92, 0xC42E}, //4876 #HANGUL SYLLABLE SSANGSIOS OE SSANGKIYEOK + {0x9C93, 0xC42F}, //4877 #HANGUL SYLLABLE SSANGSIOS OE KIYEOKSIOS + {0x9C94, 0xC431}, //4878 #HANGUL SYLLABLE SSANGSIOS OE NIEUNCIEUC + {0x9C95, 0xC432}, //4879 #HANGUL SYLLABLE SSANGSIOS OE NIEUNHIEUH + {0x9C96, 0xC433}, //4880 #HANGUL SYLLABLE SSANGSIOS OE TIKEUT + {0x9C97, 0xC435}, //4881 #HANGUL SYLLABLE SSANGSIOS OE RIEULKIYEOK + {0x9C98, 0xC436}, //4882 #HANGUL SYLLABLE SSANGSIOS OE RIEULMIEUM + {0x9C99, 0xC437}, //4883 #HANGUL SYLLABLE SSANGSIOS OE RIEULPIEUP + {0x9C9A, 0xC438}, //4884 #HANGUL SYLLABLE SSANGSIOS OE RIEULSIOS + {0x9C9B, 0xC439}, //4885 #HANGUL SYLLABLE SSANGSIOS OE RIEULTHIEUTH + {0x9C9C, 0xC43A}, //4886 #HANGUL SYLLABLE SSANGSIOS OE RIEULPHIEUPH + {0x9C9D, 0xC43B}, //4887 #HANGUL SYLLABLE SSANGSIOS OE RIEULHIEUH + {0x9C9E, 0xC43E}, //4888 #HANGUL SYLLABLE SSANGSIOS OE PIEUPSIOS + {0x9C9F, 0xC43F}, //4889 #HANGUL SYLLABLE SSANGSIOS OE SIOS + {0x9CA0, 0xC440}, //4890 #HANGUL SYLLABLE SSANGSIOS OE SSANGSIOS + {0x9CA1, 0xC441}, //4891 #HANGUL SYLLABLE SSANGSIOS OE IEUNG + {0x9CA2, 0xC442}, //4892 #HANGUL SYLLABLE SSANGSIOS OE CIEUC + {0x9CA3, 0xC443}, //4893 #HANGUL SYLLABLE SSANGSIOS OE CHIEUCH + {0x9CA4, 0xC444}, //4894 #HANGUL SYLLABLE SSANGSIOS OE KHIEUKH + {0x9CA5, 0xC445}, //4895 #HANGUL SYLLABLE SSANGSIOS OE THIEUTH + {0x9CA6, 0xC446}, //4896 #HANGUL SYLLABLE SSANGSIOS OE PHIEUPH + {0x9CA7, 0xC447}, //4897 #HANGUL SYLLABLE SSANGSIOS OE HIEUH + {0x9CA8, 0xC449}, //4898 #HANGUL SYLLABLE SSANGSIOS YO KIYEOK + {0x9CA9, 0xC44A}, //4899 #HANGUL SYLLABLE SSANGSIOS YO SSANGKIYEOK + {0x9CAA, 0xC44B}, //4900 #HANGUL SYLLABLE SSANGSIOS YO KIYEOKSIOS + {0x9CAB, 0xC44C}, //4901 #HANGUL SYLLABLE SSANGSIOS YO NIEUN + {0x9CAC, 0xC44D}, //4902 #HANGUL SYLLABLE SSANGSIOS YO NIEUNCIEUC + {0x9CAD, 0xC44E}, //4903 #HANGUL SYLLABLE SSANGSIOS YO NIEUNHIEUH + {0x9CAE, 0xC44F}, //4904 #HANGUL SYLLABLE SSANGSIOS YO TIKEUT + {0x9CAF, 0xC450}, //4905 #HANGUL SYLLABLE SSANGSIOS YO RIEUL + {0x9CB0, 0xC451}, //4906 #HANGUL SYLLABLE SSANGSIOS YO RIEULKIYEOK + {0x9CB1, 0xC452}, //4907 #HANGUL SYLLABLE SSANGSIOS YO RIEULMIEUM + {0x9CB2, 0xC453}, //4908 #HANGUL SYLLABLE SSANGSIOS YO RIEULPIEUP + {0x9CB3, 0xC454}, //4909 #HANGUL SYLLABLE SSANGSIOS YO RIEULSIOS + {0x9CB4, 0xC455}, //4910 #HANGUL SYLLABLE SSANGSIOS YO RIEULTHIEUTH + {0x9CB5, 0xC456}, //4911 #HANGUL SYLLABLE SSANGSIOS YO RIEULPHIEUPH + {0x9CB6, 0xC457}, //4912 #HANGUL SYLLABLE SSANGSIOS YO RIEULHIEUH + {0x9CB7, 0xC458}, //4913 #HANGUL SYLLABLE SSANGSIOS YO MIEUM + {0x9CB8, 0xC459}, //4914 #HANGUL SYLLABLE SSANGSIOS YO PIEUP + {0x9CB9, 0xC45A}, //4915 #HANGUL SYLLABLE SSANGSIOS YO PIEUPSIOS + {0x9CBA, 0xC45B}, //4916 #HANGUL SYLLABLE SSANGSIOS YO SIOS + {0x9CBB, 0xC45C}, //4917 #HANGUL SYLLABLE SSANGSIOS YO SSANGSIOS + {0x9CBC, 0xC45D}, //4918 #HANGUL SYLLABLE SSANGSIOS YO IEUNG + {0x9CBD, 0xC45E}, //4919 #HANGUL SYLLABLE SSANGSIOS YO CIEUC + {0x9CBE, 0xC45F}, //4920 #HANGUL SYLLABLE SSANGSIOS YO CHIEUCH + {0x9CBF, 0xC460}, //4921 #HANGUL SYLLABLE SSANGSIOS YO KHIEUKH + {0x9CC0, 0xC461}, //4922 #HANGUL SYLLABLE SSANGSIOS YO THIEUTH + {0x9CC1, 0xC462}, //4923 #HANGUL SYLLABLE SSANGSIOS YO PHIEUPH + {0x9CC2, 0xC463}, //4924 #HANGUL SYLLABLE SSANGSIOS YO HIEUH + {0x9CC3, 0xC466}, //4925 #HANGUL SYLLABLE SSANGSIOS U SSANGKIYEOK + {0x9CC4, 0xC467}, //4926 #HANGUL SYLLABLE SSANGSIOS U KIYEOKSIOS + {0x9CC5, 0xC469}, //4927 #HANGUL SYLLABLE SSANGSIOS U NIEUNCIEUC + {0x9CC6, 0xC46A}, //4928 #HANGUL SYLLABLE SSANGSIOS U NIEUNHIEUH + {0x9CC7, 0xC46B}, //4929 #HANGUL SYLLABLE SSANGSIOS U TIKEUT + {0x9CC8, 0xC46D}, //4930 #HANGUL SYLLABLE SSANGSIOS U RIEULKIYEOK + {0x9CC9, 0xC46E}, //4931 #HANGUL SYLLABLE SSANGSIOS U RIEULMIEUM + {0x9CCA, 0xC46F}, //4932 #HANGUL SYLLABLE SSANGSIOS U RIEULPIEUP + {0x9CCB, 0xC470}, //4933 #HANGUL SYLLABLE SSANGSIOS U RIEULSIOS + {0x9CCC, 0xC471}, //4934 #HANGUL SYLLABLE SSANGSIOS U RIEULTHIEUTH + {0x9CCD, 0xC472}, //4935 #HANGUL SYLLABLE SSANGSIOS U RIEULPHIEUPH + {0x9CCE, 0xC473}, //4936 #HANGUL SYLLABLE SSANGSIOS U RIEULHIEUH + {0x9CCF, 0xC476}, //4937 #HANGUL SYLLABLE SSANGSIOS U PIEUPSIOS + {0x9CD0, 0xC477}, //4938 #HANGUL SYLLABLE SSANGSIOS U SIOS + {0x9CD1, 0xC478}, //4939 #HANGUL SYLLABLE SSANGSIOS U SSANGSIOS + {0x9CD2, 0xC47A}, //4940 #HANGUL SYLLABLE SSANGSIOS U CIEUC + {0x9CD3, 0xC47B}, //4941 #HANGUL SYLLABLE SSANGSIOS U CHIEUCH + {0x9CD4, 0xC47C}, //4942 #HANGUL SYLLABLE SSANGSIOS U KHIEUKH + {0x9CD5, 0xC47D}, //4943 #HANGUL SYLLABLE SSANGSIOS U THIEUTH + {0x9CD6, 0xC47E}, //4944 #HANGUL SYLLABLE SSANGSIOS U PHIEUPH + {0x9CD7, 0xC47F}, //4945 #HANGUL SYLLABLE SSANGSIOS U HIEUH + {0x9CD8, 0xC481}, //4946 #HANGUL SYLLABLE SSANGSIOS WEO KIYEOK + {0x9CD9, 0xC482}, //4947 #HANGUL SYLLABLE SSANGSIOS WEO SSANGKIYEOK + {0x9CDA, 0xC483}, //4948 #HANGUL SYLLABLE SSANGSIOS WEO KIYEOKSIOS + {0x9CDB, 0xC484}, //4949 #HANGUL SYLLABLE SSANGSIOS WEO NIEUN + {0x9CDC, 0xC485}, //4950 #HANGUL SYLLABLE SSANGSIOS WEO NIEUNCIEUC + {0x9CDD, 0xC486}, //4951 #HANGUL SYLLABLE SSANGSIOS WEO NIEUNHIEUH + {0x9CDE, 0xC487}, //4952 #HANGUL SYLLABLE SSANGSIOS WEO TIKEUT + {0x9CDF, 0xC488}, //4953 #HANGUL SYLLABLE SSANGSIOS WEO RIEUL + {0x9CE0, 0xC489}, //4954 #HANGUL SYLLABLE SSANGSIOS WEO RIEULKIYEOK + {0x9CE1, 0xC48A}, //4955 #HANGUL SYLLABLE SSANGSIOS WEO RIEULMIEUM + {0x9CE2, 0xC48B}, //4956 #HANGUL SYLLABLE SSANGSIOS WEO RIEULPIEUP + {0x9CE3, 0xC48C}, //4957 #HANGUL SYLLABLE SSANGSIOS WEO RIEULSIOS + {0x9CE4, 0xC48D}, //4958 #HANGUL SYLLABLE SSANGSIOS WEO RIEULTHIEUTH + {0x9CE5, 0xC48E}, //4959 #HANGUL SYLLABLE SSANGSIOS WEO RIEULPHIEUPH + {0x9CE6, 0xC48F}, //4960 #HANGUL SYLLABLE SSANGSIOS WEO RIEULHIEUH + {0x9CE7, 0xC490}, //4961 #HANGUL SYLLABLE SSANGSIOS WEO MIEUM + {0x9CE8, 0xC491}, //4962 #HANGUL SYLLABLE SSANGSIOS WEO PIEUP + {0x9CE9, 0xC492}, //4963 #HANGUL SYLLABLE SSANGSIOS WEO PIEUPSIOS + {0x9CEA, 0xC493}, //4964 #HANGUL SYLLABLE SSANGSIOS WEO SIOS + {0x9CEB, 0xC495}, //4965 #HANGUL SYLLABLE SSANGSIOS WEO IEUNG + {0x9CEC, 0xC496}, //4966 #HANGUL SYLLABLE SSANGSIOS WEO CIEUC + {0x9CED, 0xC497}, //4967 #HANGUL SYLLABLE SSANGSIOS WEO CHIEUCH + {0x9CEE, 0xC498}, //4968 #HANGUL SYLLABLE SSANGSIOS WEO KHIEUKH + {0x9CEF, 0xC499}, //4969 #HANGUL SYLLABLE SSANGSIOS WEO THIEUTH + {0x9CF0, 0xC49A}, //4970 #HANGUL SYLLABLE SSANGSIOS WEO PHIEUPH + {0x9CF1, 0xC49B}, //4971 #HANGUL SYLLABLE SSANGSIOS WEO HIEUH + {0x9CF2, 0xC49D}, //4972 #HANGUL SYLLABLE SSANGSIOS WE KIYEOK + {0x9CF3, 0xC49E}, //4973 #HANGUL SYLLABLE SSANGSIOS WE SSANGKIYEOK + {0x9CF4, 0xC49F}, //4974 #HANGUL SYLLABLE SSANGSIOS WE KIYEOKSIOS + {0x9CF5, 0xC4A0}, //4975 #HANGUL SYLLABLE SSANGSIOS WE NIEUN + {0x9CF6, 0xC4A1}, //4976 #HANGUL SYLLABLE SSANGSIOS WE NIEUNCIEUC + {0x9CF7, 0xC4A2}, //4977 #HANGUL SYLLABLE SSANGSIOS WE NIEUNHIEUH + {0x9CF8, 0xC4A3}, //4978 #HANGUL SYLLABLE SSANGSIOS WE TIKEUT + {0x9CF9, 0xC4A4}, //4979 #HANGUL SYLLABLE SSANGSIOS WE RIEUL + {0x9CFA, 0xC4A5}, //4980 #HANGUL SYLLABLE SSANGSIOS WE RIEULKIYEOK + {0x9CFB, 0xC4A6}, //4981 #HANGUL SYLLABLE SSANGSIOS WE RIEULMIEUM + {0x9CFC, 0xC4A7}, //4982 #HANGUL SYLLABLE SSANGSIOS WE RIEULPIEUP + {0x9CFD, 0xC4A8}, //4983 #HANGUL SYLLABLE SSANGSIOS WE RIEULSIOS + {0x9CFE, 0xC4A9}, //4984 #HANGUL SYLLABLE SSANGSIOS WE RIEULTHIEUTH + {0x9D41, 0xC4AA}, //4985 #HANGUL SYLLABLE SSANGSIOS WE RIEULPHIEUPH + {0x9D42, 0xC4AB}, //4986 #HANGUL SYLLABLE SSANGSIOS WE RIEULHIEUH + {0x9D43, 0xC4AC}, //4987 #HANGUL SYLLABLE SSANGSIOS WE MIEUM + {0x9D44, 0xC4AD}, //4988 #HANGUL SYLLABLE SSANGSIOS WE PIEUP + {0x9D45, 0xC4AE}, //4989 #HANGUL SYLLABLE SSANGSIOS WE PIEUPSIOS + {0x9D46, 0xC4AF}, //4990 #HANGUL SYLLABLE SSANGSIOS WE SIOS + {0x9D47, 0xC4B0}, //4991 #HANGUL SYLLABLE SSANGSIOS WE SSANGSIOS + {0x9D48, 0xC4B1}, //4992 #HANGUL SYLLABLE SSANGSIOS WE IEUNG + {0x9D49, 0xC4B2}, //4993 #HANGUL SYLLABLE SSANGSIOS WE CIEUC + {0x9D4A, 0xC4B3}, //4994 #HANGUL SYLLABLE SSANGSIOS WE CHIEUCH + {0x9D4B, 0xC4B4}, //4995 #HANGUL SYLLABLE SSANGSIOS WE KHIEUKH + {0x9D4C, 0xC4B5}, //4996 #HANGUL SYLLABLE SSANGSIOS WE THIEUTH + {0x9D4D, 0xC4B6}, //4997 #HANGUL SYLLABLE SSANGSIOS WE PHIEUPH + {0x9D4E, 0xC4B7}, //4998 #HANGUL SYLLABLE SSANGSIOS WE HIEUH + {0x9D4F, 0xC4B9}, //4999 #HANGUL SYLLABLE SSANGSIOS WI KIYEOK + {0x9D50, 0xC4BA}, //5000 #HANGUL SYLLABLE SSANGSIOS WI SSANGKIYEOK + {0x9D51, 0xC4BB}, //5001 #HANGUL SYLLABLE SSANGSIOS WI KIYEOKSIOS + {0x9D52, 0xC4BD}, //5002 #HANGUL SYLLABLE SSANGSIOS WI NIEUNCIEUC + {0x9D53, 0xC4BE}, //5003 #HANGUL SYLLABLE SSANGSIOS WI NIEUNHIEUH + {0x9D54, 0xC4BF}, //5004 #HANGUL SYLLABLE SSANGSIOS WI TIKEUT + {0x9D55, 0xC4C0}, //5005 #HANGUL SYLLABLE SSANGSIOS WI RIEUL + {0x9D56, 0xC4C1}, //5006 #HANGUL SYLLABLE SSANGSIOS WI RIEULKIYEOK + {0x9D57, 0xC4C2}, //5007 #HANGUL SYLLABLE SSANGSIOS WI RIEULMIEUM + {0x9D58, 0xC4C3}, //5008 #HANGUL SYLLABLE SSANGSIOS WI RIEULPIEUP + {0x9D59, 0xC4C4}, //5009 #HANGUL SYLLABLE SSANGSIOS WI RIEULSIOS + {0x9D5A, 0xC4C5}, //5010 #HANGUL SYLLABLE SSANGSIOS WI RIEULTHIEUTH + {0x9D61, 0xC4C6}, //5011 #HANGUL SYLLABLE SSANGSIOS WI RIEULPHIEUPH + {0x9D62, 0xC4C7}, //5012 #HANGUL SYLLABLE SSANGSIOS WI RIEULHIEUH + {0x9D63, 0xC4C8}, //5013 #HANGUL SYLLABLE SSANGSIOS WI MIEUM + {0x9D64, 0xC4C9}, //5014 #HANGUL SYLLABLE SSANGSIOS WI PIEUP + {0x9D65, 0xC4CA}, //5015 #HANGUL SYLLABLE SSANGSIOS WI PIEUPSIOS + {0x9D66, 0xC4CB}, //5016 #HANGUL SYLLABLE SSANGSIOS WI SIOS + {0x9D67, 0xC4CC}, //5017 #HANGUL SYLLABLE SSANGSIOS WI SSANGSIOS + {0x9D68, 0xC4CD}, //5018 #HANGUL SYLLABLE SSANGSIOS WI IEUNG + {0x9D69, 0xC4CE}, //5019 #HANGUL SYLLABLE SSANGSIOS WI CIEUC + {0x9D6A, 0xC4CF}, //5020 #HANGUL SYLLABLE SSANGSIOS WI CHIEUCH + {0x9D6B, 0xC4D0}, //5021 #HANGUL SYLLABLE SSANGSIOS WI KHIEUKH + {0x9D6C, 0xC4D1}, //5022 #HANGUL SYLLABLE SSANGSIOS WI THIEUTH + {0x9D6D, 0xC4D2}, //5023 #HANGUL SYLLABLE SSANGSIOS WI PHIEUPH + {0x9D6E, 0xC4D3}, //5024 #HANGUL SYLLABLE SSANGSIOS WI HIEUH + {0x9D6F, 0xC4D4}, //5025 #HANGUL SYLLABLE SSANGSIOS YU + {0x9D70, 0xC4D5}, //5026 #HANGUL SYLLABLE SSANGSIOS YU KIYEOK + {0x9D71, 0xC4D6}, //5027 #HANGUL SYLLABLE SSANGSIOS YU SSANGKIYEOK + {0x9D72, 0xC4D7}, //5028 #HANGUL SYLLABLE SSANGSIOS YU KIYEOKSIOS + {0x9D73, 0xC4D8}, //5029 #HANGUL SYLLABLE SSANGSIOS YU NIEUN + {0x9D74, 0xC4D9}, //5030 #HANGUL SYLLABLE SSANGSIOS YU NIEUNCIEUC + {0x9D75, 0xC4DA}, //5031 #HANGUL SYLLABLE SSANGSIOS YU NIEUNHIEUH + {0x9D76, 0xC4DB}, //5032 #HANGUL SYLLABLE SSANGSIOS YU TIKEUT + {0x9D77, 0xC4DC}, //5033 #HANGUL SYLLABLE SSANGSIOS YU RIEUL + {0x9D78, 0xC4DD}, //5034 #HANGUL SYLLABLE SSANGSIOS YU RIEULKIYEOK + {0x9D79, 0xC4DE}, //5035 #HANGUL SYLLABLE SSANGSIOS YU RIEULMIEUM + {0x9D7A, 0xC4DF}, //5036 #HANGUL SYLLABLE SSANGSIOS YU RIEULPIEUP + {0x9D81, 0xC4E0}, //5037 #HANGUL SYLLABLE SSANGSIOS YU RIEULSIOS + {0x9D82, 0xC4E1}, //5038 #HANGUL SYLLABLE SSANGSIOS YU RIEULTHIEUTH + {0x9D83, 0xC4E2}, //5039 #HANGUL SYLLABLE SSANGSIOS YU RIEULPHIEUPH + {0x9D84, 0xC4E3}, //5040 #HANGUL SYLLABLE SSANGSIOS YU RIEULHIEUH + {0x9D85, 0xC4E4}, //5041 #HANGUL SYLLABLE SSANGSIOS YU MIEUM + {0x9D86, 0xC4E5}, //5042 #HANGUL SYLLABLE SSANGSIOS YU PIEUP + {0x9D87, 0xC4E6}, //5043 #HANGUL SYLLABLE SSANGSIOS YU PIEUPSIOS + {0x9D88, 0xC4E7}, //5044 #HANGUL SYLLABLE SSANGSIOS YU SIOS + {0x9D89, 0xC4E8}, //5045 #HANGUL SYLLABLE SSANGSIOS YU SSANGSIOS + {0x9D8A, 0xC4EA}, //5046 #HANGUL SYLLABLE SSANGSIOS YU CIEUC + {0x9D8B, 0xC4EB}, //5047 #HANGUL SYLLABLE SSANGSIOS YU CHIEUCH + {0x9D8C, 0xC4EC}, //5048 #HANGUL SYLLABLE SSANGSIOS YU KHIEUKH + {0x9D8D, 0xC4ED}, //5049 #HANGUL SYLLABLE SSANGSIOS YU THIEUTH + {0x9D8E, 0xC4EE}, //5050 #HANGUL SYLLABLE SSANGSIOS YU PHIEUPH + {0x9D8F, 0xC4EF}, //5051 #HANGUL SYLLABLE SSANGSIOS YU HIEUH + {0x9D90, 0xC4F2}, //5052 #HANGUL SYLLABLE SSANGSIOS EU SSANGKIYEOK + {0x9D91, 0xC4F3}, //5053 #HANGUL SYLLABLE SSANGSIOS EU KIYEOKSIOS + {0x9D92, 0xC4F5}, //5054 #HANGUL SYLLABLE SSANGSIOS EU NIEUNCIEUC + {0x9D93, 0xC4F6}, //5055 #HANGUL SYLLABLE SSANGSIOS EU NIEUNHIEUH + {0x9D94, 0xC4F7}, //5056 #HANGUL SYLLABLE SSANGSIOS EU TIKEUT + {0x9D95, 0xC4F9}, //5057 #HANGUL SYLLABLE SSANGSIOS EU RIEULKIYEOK + {0x9D96, 0xC4FB}, //5058 #HANGUL SYLLABLE SSANGSIOS EU RIEULPIEUP + {0x9D97, 0xC4FC}, //5059 #HANGUL SYLLABLE SSANGSIOS EU RIEULSIOS + {0x9D98, 0xC4FD}, //5060 #HANGUL SYLLABLE SSANGSIOS EU RIEULTHIEUTH + {0x9D99, 0xC4FE}, //5061 #HANGUL SYLLABLE SSANGSIOS EU RIEULPHIEUPH + {0x9D9A, 0xC502}, //5062 #HANGUL SYLLABLE SSANGSIOS EU PIEUPSIOS + {0x9D9B, 0xC503}, //5063 #HANGUL SYLLABLE SSANGSIOS EU SIOS + {0x9D9C, 0xC504}, //5064 #HANGUL SYLLABLE SSANGSIOS EU SSANGSIOS + {0x9D9D, 0xC505}, //5065 #HANGUL SYLLABLE SSANGSIOS EU IEUNG + {0x9D9E, 0xC506}, //5066 #HANGUL SYLLABLE SSANGSIOS EU CIEUC + {0x9D9F, 0xC507}, //5067 #HANGUL SYLLABLE SSANGSIOS EU CHIEUCH + {0x9DA0, 0xC508}, //5068 #HANGUL SYLLABLE SSANGSIOS EU KHIEUKH + {0x9DA1, 0xC509}, //5069 #HANGUL SYLLABLE SSANGSIOS EU THIEUTH + {0x9DA2, 0xC50A}, //5070 #HANGUL SYLLABLE SSANGSIOS EU PHIEUPH + {0x9DA3, 0xC50B}, //5071 #HANGUL SYLLABLE SSANGSIOS EU HIEUH + {0x9DA4, 0xC50D}, //5072 #HANGUL SYLLABLE SSANGSIOS YI KIYEOK + {0x9DA5, 0xC50E}, //5073 #HANGUL SYLLABLE SSANGSIOS YI SSANGKIYEOK + {0x9DA6, 0xC50F}, //5074 #HANGUL SYLLABLE SSANGSIOS YI KIYEOKSIOS + {0x9DA7, 0xC511}, //5075 #HANGUL SYLLABLE SSANGSIOS YI NIEUNCIEUC + {0x9DA8, 0xC512}, //5076 #HANGUL SYLLABLE SSANGSIOS YI NIEUNHIEUH + {0x9DA9, 0xC513}, //5077 #HANGUL SYLLABLE SSANGSIOS YI TIKEUT + {0x9DAA, 0xC515}, //5078 #HANGUL SYLLABLE SSANGSIOS YI RIEULKIYEOK + {0x9DAB, 0xC516}, //5079 #HANGUL SYLLABLE SSANGSIOS YI RIEULMIEUM + {0x9DAC, 0xC517}, //5080 #HANGUL SYLLABLE SSANGSIOS YI RIEULPIEUP + {0x9DAD, 0xC518}, //5081 #HANGUL SYLLABLE SSANGSIOS YI RIEULSIOS + {0x9DAE, 0xC519}, //5082 #HANGUL SYLLABLE SSANGSIOS YI RIEULTHIEUTH + {0x9DAF, 0xC51A}, //5083 #HANGUL SYLLABLE SSANGSIOS YI RIEULPHIEUPH + {0x9DB0, 0xC51B}, //5084 #HANGUL SYLLABLE SSANGSIOS YI RIEULHIEUH + {0x9DB1, 0xC51D}, //5085 #HANGUL SYLLABLE SSANGSIOS YI PIEUP + {0x9DB2, 0xC51E}, //5086 #HANGUL SYLLABLE SSANGSIOS YI PIEUPSIOS + {0x9DB3, 0xC51F}, //5087 #HANGUL SYLLABLE SSANGSIOS YI SIOS + {0x9DB4, 0xC520}, //5088 #HANGUL SYLLABLE SSANGSIOS YI SSANGSIOS + {0x9DB5, 0xC521}, //5089 #HANGUL SYLLABLE SSANGSIOS YI IEUNG + {0x9DB6, 0xC522}, //5090 #HANGUL SYLLABLE SSANGSIOS YI CIEUC + {0x9DB7, 0xC523}, //5091 #HANGUL SYLLABLE SSANGSIOS YI CHIEUCH + {0x9DB8, 0xC524}, //5092 #HANGUL SYLLABLE SSANGSIOS YI KHIEUKH + {0x9DB9, 0xC525}, //5093 #HANGUL SYLLABLE SSANGSIOS YI THIEUTH + {0x9DBA, 0xC526}, //5094 #HANGUL SYLLABLE SSANGSIOS YI PHIEUPH + {0x9DBB, 0xC527}, //5095 #HANGUL SYLLABLE SSANGSIOS YI HIEUH + {0x9DBC, 0xC52A}, //5096 #HANGUL SYLLABLE SSANGSIOS I SSANGKIYEOK + {0x9DBD, 0xC52B}, //5097 #HANGUL SYLLABLE SSANGSIOS I KIYEOKSIOS + {0x9DBE, 0xC52D}, //5098 #HANGUL SYLLABLE SSANGSIOS I NIEUNCIEUC + {0x9DBF, 0xC52E}, //5099 #HANGUL SYLLABLE SSANGSIOS I NIEUNHIEUH + {0x9DC0, 0xC52F}, //5100 #HANGUL SYLLABLE SSANGSIOS I TIKEUT + {0x9DC1, 0xC531}, //5101 #HANGUL SYLLABLE SSANGSIOS I RIEULKIYEOK + {0x9DC2, 0xC532}, //5102 #HANGUL SYLLABLE SSANGSIOS I RIEULMIEUM + {0x9DC3, 0xC533}, //5103 #HANGUL SYLLABLE SSANGSIOS I RIEULPIEUP + {0x9DC4, 0xC534}, //5104 #HANGUL SYLLABLE SSANGSIOS I RIEULSIOS + {0x9DC5, 0xC535}, //5105 #HANGUL SYLLABLE SSANGSIOS I RIEULTHIEUTH + {0x9DC6, 0xC536}, //5106 #HANGUL SYLLABLE SSANGSIOS I RIEULPHIEUPH + {0x9DC7, 0xC537}, //5107 #HANGUL SYLLABLE SSANGSIOS I RIEULHIEUH + {0x9DC8, 0xC53A}, //5108 #HANGUL SYLLABLE SSANGSIOS I PIEUPSIOS + {0x9DC9, 0xC53C}, //5109 #HANGUL SYLLABLE SSANGSIOS I SSANGSIOS + {0x9DCA, 0xC53E}, //5110 #HANGUL SYLLABLE SSANGSIOS I CIEUC + {0x9DCB, 0xC53F}, //5111 #HANGUL SYLLABLE SSANGSIOS I CHIEUCH + {0x9DCC, 0xC540}, //5112 #HANGUL SYLLABLE SSANGSIOS I KHIEUKH + {0x9DCD, 0xC541}, //5113 #HANGUL SYLLABLE SSANGSIOS I THIEUTH + {0x9DCE, 0xC542}, //5114 #HANGUL SYLLABLE SSANGSIOS I PHIEUPH + {0x9DCF, 0xC543}, //5115 #HANGUL SYLLABLE SSANGSIOS I HIEUH + {0x9DD0, 0xC546}, //5116 #HANGUL SYLLABLE IEUNG A SSANGKIYEOK + {0x9DD1, 0xC547}, //5117 #HANGUL SYLLABLE IEUNG A KIYEOKSIOS + {0x9DD2, 0xC54B}, //5118 #HANGUL SYLLABLE IEUNG A TIKEUT + {0x9DD3, 0xC54F}, //5119 #HANGUL SYLLABLE IEUNG A RIEULPIEUP + {0x9DD4, 0xC550}, //5120 #HANGUL SYLLABLE IEUNG A RIEULSIOS + {0x9DD5, 0xC551}, //5121 #HANGUL SYLLABLE IEUNG A RIEULTHIEUTH + {0x9DD6, 0xC552}, //5122 #HANGUL SYLLABLE IEUNG A RIEULPHIEUPH + {0x9DD7, 0xC556}, //5123 #HANGUL SYLLABLE IEUNG A PIEUPSIOS + {0x9DD8, 0xC55A}, //5124 #HANGUL SYLLABLE IEUNG A CIEUC + {0x9DD9, 0xC55B}, //5125 #HANGUL SYLLABLE IEUNG A CHIEUCH + {0x9DDA, 0xC55C}, //5126 #HANGUL SYLLABLE IEUNG A KHIEUKH + {0x9DDB, 0xC55F}, //5127 #HANGUL SYLLABLE IEUNG A HIEUH + {0x9DDC, 0xC562}, //5128 #HANGUL SYLLABLE IEUNG AE SSANGKIYEOK + {0x9DDD, 0xC563}, //5129 #HANGUL SYLLABLE IEUNG AE KIYEOKSIOS + {0x9DDE, 0xC565}, //5130 #HANGUL SYLLABLE IEUNG AE NIEUNCIEUC + {0x9DDF, 0xC566}, //5131 #HANGUL SYLLABLE IEUNG AE NIEUNHIEUH + {0x9DE0, 0xC567}, //5132 #HANGUL SYLLABLE IEUNG AE TIKEUT + {0x9DE1, 0xC569}, //5133 #HANGUL SYLLABLE IEUNG AE RIEULKIYEOK + {0x9DE2, 0xC56A}, //5134 #HANGUL SYLLABLE IEUNG AE RIEULMIEUM + {0x9DE3, 0xC56B}, //5135 #HANGUL SYLLABLE IEUNG AE RIEULPIEUP + {0x9DE4, 0xC56C}, //5136 #HANGUL SYLLABLE IEUNG AE RIEULSIOS + {0x9DE5, 0xC56D}, //5137 #HANGUL SYLLABLE IEUNG AE RIEULTHIEUTH + {0x9DE6, 0xC56E}, //5138 #HANGUL SYLLABLE IEUNG AE RIEULPHIEUPH + {0x9DE7, 0xC56F}, //5139 #HANGUL SYLLABLE IEUNG AE RIEULHIEUH + {0x9DE8, 0xC572}, //5140 #HANGUL SYLLABLE IEUNG AE PIEUPSIOS + {0x9DE9, 0xC576}, //5141 #HANGUL SYLLABLE IEUNG AE CIEUC + {0x9DEA, 0xC577}, //5142 #HANGUL SYLLABLE IEUNG AE CHIEUCH + {0x9DEB, 0xC578}, //5143 #HANGUL SYLLABLE IEUNG AE KHIEUKH + {0x9DEC, 0xC579}, //5144 #HANGUL SYLLABLE IEUNG AE THIEUTH + {0x9DED, 0xC57A}, //5145 #HANGUL SYLLABLE IEUNG AE PHIEUPH + {0x9DEE, 0xC57B}, //5146 #HANGUL SYLLABLE IEUNG AE HIEUH + {0x9DEF, 0xC57E}, //5147 #HANGUL SYLLABLE IEUNG YA SSANGKIYEOK + {0x9DF0, 0xC57F}, //5148 #HANGUL SYLLABLE IEUNG YA KIYEOKSIOS + {0x9DF1, 0xC581}, //5149 #HANGUL SYLLABLE IEUNG YA NIEUNCIEUC + {0x9DF2, 0xC582}, //5150 #HANGUL SYLLABLE IEUNG YA NIEUNHIEUH + {0x9DF3, 0xC583}, //5151 #HANGUL SYLLABLE IEUNG YA TIKEUT + {0x9DF4, 0xC585}, //5152 #HANGUL SYLLABLE IEUNG YA RIEULKIYEOK + {0x9DF5, 0xC586}, //5153 #HANGUL SYLLABLE IEUNG YA RIEULMIEUM + {0x9DF6, 0xC588}, //5154 #HANGUL SYLLABLE IEUNG YA RIEULSIOS + {0x9DF7, 0xC589}, //5155 #HANGUL SYLLABLE IEUNG YA RIEULTHIEUTH + {0x9DF8, 0xC58A}, //5156 #HANGUL SYLLABLE IEUNG YA RIEULPHIEUPH + {0x9DF9, 0xC58B}, //5157 #HANGUL SYLLABLE IEUNG YA RIEULHIEUH + {0x9DFA, 0xC58E}, //5158 #HANGUL SYLLABLE IEUNG YA PIEUPSIOS + {0x9DFB, 0xC590}, //5159 #HANGUL SYLLABLE IEUNG YA SSANGSIOS + {0x9DFC, 0xC592}, //5160 #HANGUL SYLLABLE IEUNG YA CIEUC + {0x9DFD, 0xC593}, //5161 #HANGUL SYLLABLE IEUNG YA CHIEUCH + {0x9DFE, 0xC594}, //5162 #HANGUL SYLLABLE IEUNG YA KHIEUKH + {0x9E41, 0xC596}, //5163 #HANGUL SYLLABLE IEUNG YA PHIEUPH + {0x9E42, 0xC599}, //5164 #HANGUL SYLLABLE IEUNG YAE KIYEOK + {0x9E43, 0xC59A}, //5165 #HANGUL SYLLABLE IEUNG YAE SSANGKIYEOK + {0x9E44, 0xC59B}, //5166 #HANGUL SYLLABLE IEUNG YAE KIYEOKSIOS + {0x9E45, 0xC59D}, //5167 #HANGUL SYLLABLE IEUNG YAE NIEUNCIEUC + {0x9E46, 0xC59E}, //5168 #HANGUL SYLLABLE IEUNG YAE NIEUNHIEUH + {0x9E47, 0xC59F}, //5169 #HANGUL SYLLABLE IEUNG YAE TIKEUT + {0x9E48, 0xC5A1}, //5170 #HANGUL SYLLABLE IEUNG YAE RIEULKIYEOK + {0x9E49, 0xC5A2}, //5171 #HANGUL SYLLABLE IEUNG YAE RIEULMIEUM + {0x9E4A, 0xC5A3}, //5172 #HANGUL SYLLABLE IEUNG YAE RIEULPIEUP + {0x9E4B, 0xC5A4}, //5173 #HANGUL SYLLABLE IEUNG YAE RIEULSIOS + {0x9E4C, 0xC5A5}, //5174 #HANGUL SYLLABLE IEUNG YAE RIEULTHIEUTH + {0x9E4D, 0xC5A6}, //5175 #HANGUL SYLLABLE IEUNG YAE RIEULPHIEUPH + {0x9E4E, 0xC5A7}, //5176 #HANGUL SYLLABLE IEUNG YAE RIEULHIEUH + {0x9E4F, 0xC5A8}, //5177 #HANGUL SYLLABLE IEUNG YAE MIEUM + {0x9E50, 0xC5AA}, //5178 #HANGUL SYLLABLE IEUNG YAE PIEUPSIOS + {0x9E51, 0xC5AB}, //5179 #HANGUL SYLLABLE IEUNG YAE SIOS + {0x9E52, 0xC5AC}, //5180 #HANGUL SYLLABLE IEUNG YAE SSANGSIOS + {0x9E53, 0xC5AD}, //5181 #HANGUL SYLLABLE IEUNG YAE IEUNG + {0x9E54, 0xC5AE}, //5182 #HANGUL SYLLABLE IEUNG YAE CIEUC + {0x9E55, 0xC5AF}, //5183 #HANGUL SYLLABLE IEUNG YAE CHIEUCH + {0x9E56, 0xC5B0}, //5184 #HANGUL SYLLABLE IEUNG YAE KHIEUKH + {0x9E57, 0xC5B1}, //5185 #HANGUL SYLLABLE IEUNG YAE THIEUTH + {0x9E58, 0xC5B2}, //5186 #HANGUL SYLLABLE IEUNG YAE PHIEUPH + {0x9E59, 0xC5B3}, //5187 #HANGUL SYLLABLE IEUNG YAE HIEUH + {0x9E5A, 0xC5B6}, //5188 #HANGUL SYLLABLE IEUNG EO SSANGKIYEOK + {0x9E61, 0xC5B7}, //5189 #HANGUL SYLLABLE IEUNG EO KIYEOKSIOS + {0x9E62, 0xC5BA}, //5190 #HANGUL SYLLABLE IEUNG EO NIEUNHIEUH + {0x9E63, 0xC5BF}, //5191 #HANGUL SYLLABLE IEUNG EO RIEULPIEUP + {0x9E64, 0xC5C0}, //5192 #HANGUL SYLLABLE IEUNG EO RIEULSIOS + {0x9E65, 0xC5C1}, //5193 #HANGUL SYLLABLE IEUNG EO RIEULTHIEUTH + {0x9E66, 0xC5C2}, //5194 #HANGUL SYLLABLE IEUNG EO RIEULPHIEUPH + {0x9E67, 0xC5C3}, //5195 #HANGUL SYLLABLE IEUNG EO RIEULHIEUH + {0x9E68, 0xC5CB}, //5196 #HANGUL SYLLABLE IEUNG EO CHIEUCH + {0x9E69, 0xC5CD}, //5197 #HANGUL SYLLABLE IEUNG EO THIEUTH + {0x9E6A, 0xC5CF}, //5198 #HANGUL SYLLABLE IEUNG EO HIEUH + {0x9E6B, 0xC5D2}, //5199 #HANGUL SYLLABLE IEUNG E SSANGKIYEOK + {0x9E6C, 0xC5D3}, //5200 #HANGUL SYLLABLE IEUNG E KIYEOKSIOS + {0x9E6D, 0xC5D5}, //5201 #HANGUL SYLLABLE IEUNG E NIEUNCIEUC + {0x9E6E, 0xC5D6}, //5202 #HANGUL SYLLABLE IEUNG E NIEUNHIEUH + {0x9E6F, 0xC5D7}, //5203 #HANGUL SYLLABLE IEUNG E TIKEUT + {0x9E70, 0xC5D9}, //5204 #HANGUL SYLLABLE IEUNG E RIEULKIYEOK + {0x9E71, 0xC5DA}, //5205 #HANGUL SYLLABLE IEUNG E RIEULMIEUM + {0x9E72, 0xC5DB}, //5206 #HANGUL SYLLABLE IEUNG E RIEULPIEUP + {0x9E73, 0xC5DC}, //5207 #HANGUL SYLLABLE IEUNG E RIEULSIOS + {0x9E74, 0xC5DD}, //5208 #HANGUL SYLLABLE IEUNG E RIEULTHIEUTH + {0x9E75, 0xC5DE}, //5209 #HANGUL SYLLABLE IEUNG E RIEULPHIEUPH + {0x9E76, 0xC5DF}, //5210 #HANGUL SYLLABLE IEUNG E RIEULHIEUH + {0x9E77, 0xC5E2}, //5211 #HANGUL SYLLABLE IEUNG E PIEUPSIOS + {0x9E78, 0xC5E4}, //5212 #HANGUL SYLLABLE IEUNG E SSANGSIOS + {0x9E79, 0xC5E6}, //5213 #HANGUL SYLLABLE IEUNG E CIEUC + {0x9E7A, 0xC5E7}, //5214 #HANGUL SYLLABLE IEUNG E CHIEUCH + {0x9E81, 0xC5E8}, //5215 #HANGUL SYLLABLE IEUNG E KHIEUKH + {0x9E82, 0xC5E9}, //5216 #HANGUL SYLLABLE IEUNG E THIEUTH + {0x9E83, 0xC5EA}, //5217 #HANGUL SYLLABLE IEUNG E PHIEUPH + {0x9E84, 0xC5EB}, //5218 #HANGUL SYLLABLE IEUNG E HIEUH + {0x9E85, 0xC5EF}, //5219 #HANGUL SYLLABLE IEUNG YEO KIYEOKSIOS + {0x9E86, 0xC5F1}, //5220 #HANGUL SYLLABLE IEUNG YEO NIEUNCIEUC + {0x9E87, 0xC5F2}, //5221 #HANGUL SYLLABLE IEUNG YEO NIEUNHIEUH + {0x9E88, 0xC5F3}, //5222 #HANGUL SYLLABLE IEUNG YEO TIKEUT + {0x9E89, 0xC5F5}, //5223 #HANGUL SYLLABLE IEUNG YEO RIEULKIYEOK + {0x9E8A, 0xC5F8}, //5224 #HANGUL SYLLABLE IEUNG YEO RIEULSIOS + {0x9E8B, 0xC5F9}, //5225 #HANGUL SYLLABLE IEUNG YEO RIEULTHIEUTH + {0x9E8C, 0xC5FA}, //5226 #HANGUL SYLLABLE IEUNG YEO RIEULPHIEUPH + {0x9E8D, 0xC5FB}, //5227 #HANGUL SYLLABLE IEUNG YEO RIEULHIEUH + {0x9E8E, 0xC602}, //5228 #HANGUL SYLLABLE IEUNG YEO CIEUC + {0x9E8F, 0xC603}, //5229 #HANGUL SYLLABLE IEUNG YEO CHIEUCH + {0x9E90, 0xC604}, //5230 #HANGUL SYLLABLE IEUNG YEO KHIEUKH + {0x9E91, 0xC609}, //5231 #HANGUL SYLLABLE IEUNG YE KIYEOK + {0x9E92, 0xC60A}, //5232 #HANGUL SYLLABLE IEUNG YE SSANGKIYEOK + {0x9E93, 0xC60B}, //5233 #HANGUL SYLLABLE IEUNG YE KIYEOKSIOS + {0x9E94, 0xC60D}, //5234 #HANGUL SYLLABLE IEUNG YE NIEUNCIEUC + {0x9E95, 0xC60E}, //5235 #HANGUL SYLLABLE IEUNG YE NIEUNHIEUH + {0x9E96, 0xC60F}, //5236 #HANGUL SYLLABLE IEUNG YE TIKEUT + {0x9E97, 0xC611}, //5237 #HANGUL SYLLABLE IEUNG YE RIEULKIYEOK + {0x9E98, 0xC612}, //5238 #HANGUL SYLLABLE IEUNG YE RIEULMIEUM + {0x9E99, 0xC613}, //5239 #HANGUL SYLLABLE IEUNG YE RIEULPIEUP + {0x9E9A, 0xC614}, //5240 #HANGUL SYLLABLE IEUNG YE RIEULSIOS + {0x9E9B, 0xC615}, //5241 #HANGUL SYLLABLE IEUNG YE RIEULTHIEUTH + {0x9E9C, 0xC616}, //5242 #HANGUL SYLLABLE IEUNG YE RIEULPHIEUPH + {0x9E9D, 0xC617}, //5243 #HANGUL SYLLABLE IEUNG YE RIEULHIEUH + {0x9E9E, 0xC61A}, //5244 #HANGUL SYLLABLE IEUNG YE PIEUPSIOS + {0x9E9F, 0xC61D}, //5245 #HANGUL SYLLABLE IEUNG YE IEUNG + {0x9EA0, 0xC61E}, //5246 #HANGUL SYLLABLE IEUNG YE CIEUC + {0x9EA1, 0xC61F}, //5247 #HANGUL SYLLABLE IEUNG YE CHIEUCH + {0x9EA2, 0xC620}, //5248 #HANGUL SYLLABLE IEUNG YE KHIEUKH + {0x9EA3, 0xC621}, //5249 #HANGUL SYLLABLE IEUNG YE THIEUTH + {0x9EA4, 0xC622}, //5250 #HANGUL SYLLABLE IEUNG YE PHIEUPH + {0x9EA5, 0xC623}, //5251 #HANGUL SYLLABLE IEUNG YE HIEUH + {0x9EA6, 0xC626}, //5252 #HANGUL SYLLABLE IEUNG O SSANGKIYEOK + {0x9EA7, 0xC627}, //5253 #HANGUL SYLLABLE IEUNG O KIYEOKSIOS + {0x9EA8, 0xC629}, //5254 #HANGUL SYLLABLE IEUNG O NIEUNCIEUC + {0x9EA9, 0xC62A}, //5255 #HANGUL SYLLABLE IEUNG O NIEUNHIEUH + {0x9EAA, 0xC62B}, //5256 #HANGUL SYLLABLE IEUNG O TIKEUT + {0x9EAB, 0xC62F}, //5257 #HANGUL SYLLABLE IEUNG O RIEULPIEUP + {0x9EAC, 0xC631}, //5258 #HANGUL SYLLABLE IEUNG O RIEULTHIEUTH + {0x9EAD, 0xC632}, //5259 #HANGUL SYLLABLE IEUNG O RIEULPHIEUPH + {0x9EAE, 0xC636}, //5260 #HANGUL SYLLABLE IEUNG O PIEUPSIOS + {0x9EAF, 0xC638}, //5261 #HANGUL SYLLABLE IEUNG O SSANGSIOS + {0x9EB0, 0xC63A}, //5262 #HANGUL SYLLABLE IEUNG O CIEUC + {0x9EB1, 0xC63C}, //5263 #HANGUL SYLLABLE IEUNG O KHIEUKH + {0x9EB2, 0xC63D}, //5264 #HANGUL SYLLABLE IEUNG O THIEUTH + {0x9EB3, 0xC63E}, //5265 #HANGUL SYLLABLE IEUNG O PHIEUPH + {0x9EB4, 0xC63F}, //5266 #HANGUL SYLLABLE IEUNG O HIEUH + {0x9EB5, 0xC642}, //5267 #HANGUL SYLLABLE IEUNG WA SSANGKIYEOK + {0x9EB6, 0xC643}, //5268 #HANGUL SYLLABLE IEUNG WA KIYEOKSIOS + {0x9EB7, 0xC645}, //5269 #HANGUL SYLLABLE IEUNG WA NIEUNCIEUC + {0x9EB8, 0xC646}, //5270 #HANGUL SYLLABLE IEUNG WA NIEUNHIEUH + {0x9EB9, 0xC647}, //5271 #HANGUL SYLLABLE IEUNG WA TIKEUT + {0x9EBA, 0xC649}, //5272 #HANGUL SYLLABLE IEUNG WA RIEULKIYEOK + {0x9EBB, 0xC64A}, //5273 #HANGUL SYLLABLE IEUNG WA RIEULMIEUM + {0x9EBC, 0xC64B}, //5274 #HANGUL SYLLABLE IEUNG WA RIEULPIEUP + {0x9EBD, 0xC64C}, //5275 #HANGUL SYLLABLE IEUNG WA RIEULSIOS + {0x9EBE, 0xC64D}, //5276 #HANGUL SYLLABLE IEUNG WA RIEULTHIEUTH + {0x9EBF, 0xC64E}, //5277 #HANGUL SYLLABLE IEUNG WA RIEULPHIEUPH + {0x9EC0, 0xC64F}, //5278 #HANGUL SYLLABLE IEUNG WA RIEULHIEUH + {0x9EC1, 0xC652}, //5279 #HANGUL SYLLABLE IEUNG WA PIEUPSIOS + {0x9EC2, 0xC656}, //5280 #HANGUL SYLLABLE IEUNG WA CIEUC + {0x9EC3, 0xC657}, //5281 #HANGUL SYLLABLE IEUNG WA CHIEUCH + {0x9EC4, 0xC658}, //5282 #HANGUL SYLLABLE IEUNG WA KHIEUKH + {0x9EC5, 0xC659}, //5283 #HANGUL SYLLABLE IEUNG WA THIEUTH + {0x9EC6, 0xC65A}, //5284 #HANGUL SYLLABLE IEUNG WA PHIEUPH + {0x9EC7, 0xC65B}, //5285 #HANGUL SYLLABLE IEUNG WA HIEUH + {0x9EC8, 0xC65E}, //5286 #HANGUL SYLLABLE IEUNG WAE SSANGKIYEOK + {0x9EC9, 0xC65F}, //5287 #HANGUL SYLLABLE IEUNG WAE KIYEOKSIOS + {0x9ECA, 0xC661}, //5288 #HANGUL SYLLABLE IEUNG WAE NIEUNCIEUC + {0x9ECB, 0xC662}, //5289 #HANGUL SYLLABLE IEUNG WAE NIEUNHIEUH + {0x9ECC, 0xC663}, //5290 #HANGUL SYLLABLE IEUNG WAE TIKEUT + {0x9ECD, 0xC664}, //5291 #HANGUL SYLLABLE IEUNG WAE RIEUL + {0x9ECE, 0xC665}, //5292 #HANGUL SYLLABLE IEUNG WAE RIEULKIYEOK + {0x9ECF, 0xC666}, //5293 #HANGUL SYLLABLE IEUNG WAE RIEULMIEUM + {0x9ED0, 0xC667}, //5294 #HANGUL SYLLABLE IEUNG WAE RIEULPIEUP + {0x9ED1, 0xC668}, //5295 #HANGUL SYLLABLE IEUNG WAE RIEULSIOS + {0x9ED2, 0xC669}, //5296 #HANGUL SYLLABLE IEUNG WAE RIEULTHIEUTH + {0x9ED3, 0xC66A}, //5297 #HANGUL SYLLABLE IEUNG WAE RIEULPHIEUPH + {0x9ED4, 0xC66B}, //5298 #HANGUL SYLLABLE IEUNG WAE RIEULHIEUH + {0x9ED5, 0xC66D}, //5299 #HANGUL SYLLABLE IEUNG WAE PIEUP + {0x9ED6, 0xC66E}, //5300 #HANGUL SYLLABLE IEUNG WAE PIEUPSIOS + {0x9ED7, 0xC670}, //5301 #HANGUL SYLLABLE IEUNG WAE SSANGSIOS + {0x9ED8, 0xC672}, //5302 #HANGUL SYLLABLE IEUNG WAE CIEUC + {0x9ED9, 0xC673}, //5303 #HANGUL SYLLABLE IEUNG WAE CHIEUCH + {0x9EDA, 0xC674}, //5304 #HANGUL SYLLABLE IEUNG WAE KHIEUKH + {0x9EDB, 0xC675}, //5305 #HANGUL SYLLABLE IEUNG WAE THIEUTH + {0x9EDC, 0xC676}, //5306 #HANGUL SYLLABLE IEUNG WAE PHIEUPH + {0x9EDD, 0xC677}, //5307 #HANGUL SYLLABLE IEUNG WAE HIEUH + {0x9EDE, 0xC67A}, //5308 #HANGUL SYLLABLE IEUNG OE SSANGKIYEOK + {0x9EDF, 0xC67B}, //5309 #HANGUL SYLLABLE IEUNG OE KIYEOKSIOS + {0x9EE0, 0xC67D}, //5310 #HANGUL SYLLABLE IEUNG OE NIEUNCIEUC + {0x9EE1, 0xC67E}, //5311 #HANGUL SYLLABLE IEUNG OE NIEUNHIEUH + {0x9EE2, 0xC67F}, //5312 #HANGUL SYLLABLE IEUNG OE TIKEUT + {0x9EE3, 0xC681}, //5313 #HANGUL SYLLABLE IEUNG OE RIEULKIYEOK + {0x9EE4, 0xC682}, //5314 #HANGUL SYLLABLE IEUNG OE RIEULMIEUM + {0x9EE5, 0xC683}, //5315 #HANGUL SYLLABLE IEUNG OE RIEULPIEUP + {0x9EE6, 0xC684}, //5316 #HANGUL SYLLABLE IEUNG OE RIEULSIOS + {0x9EE7, 0xC685}, //5317 #HANGUL SYLLABLE IEUNG OE RIEULTHIEUTH + {0x9EE8, 0xC686}, //5318 #HANGUL SYLLABLE IEUNG OE RIEULPHIEUPH + {0x9EE9, 0xC687}, //5319 #HANGUL SYLLABLE IEUNG OE RIEULHIEUH + {0x9EEA, 0xC68A}, //5320 #HANGUL SYLLABLE IEUNG OE PIEUPSIOS + {0x9EEB, 0xC68C}, //5321 #HANGUL SYLLABLE IEUNG OE SSANGSIOS + {0x9EEC, 0xC68E}, //5322 #HANGUL SYLLABLE IEUNG OE CIEUC + {0x9EED, 0xC68F}, //5323 #HANGUL SYLLABLE IEUNG OE CHIEUCH + {0x9EEE, 0xC690}, //5324 #HANGUL SYLLABLE IEUNG OE KHIEUKH + {0x9EEF, 0xC691}, //5325 #HANGUL SYLLABLE IEUNG OE THIEUTH + {0x9EF0, 0xC692}, //5326 #HANGUL SYLLABLE IEUNG OE PHIEUPH + {0x9EF1, 0xC693}, //5327 #HANGUL SYLLABLE IEUNG OE HIEUH + {0x9EF2, 0xC696}, //5328 #HANGUL SYLLABLE IEUNG YO SSANGKIYEOK + {0x9EF3, 0xC697}, //5329 #HANGUL SYLLABLE IEUNG YO KIYEOKSIOS + {0x9EF4, 0xC699}, //5330 #HANGUL SYLLABLE IEUNG YO NIEUNCIEUC + {0x9EF5, 0xC69A}, //5331 #HANGUL SYLLABLE IEUNG YO NIEUNHIEUH + {0x9EF6, 0xC69B}, //5332 #HANGUL SYLLABLE IEUNG YO TIKEUT + {0x9EF7, 0xC69D}, //5333 #HANGUL SYLLABLE IEUNG YO RIEULKIYEOK + {0x9EF8, 0xC69E}, //5334 #HANGUL SYLLABLE IEUNG YO RIEULMIEUM + {0x9EF9, 0xC69F}, //5335 #HANGUL SYLLABLE IEUNG YO RIEULPIEUP + {0x9EFA, 0xC6A0}, //5336 #HANGUL SYLLABLE IEUNG YO RIEULSIOS + {0x9EFB, 0xC6A1}, //5337 #HANGUL SYLLABLE IEUNG YO RIEULTHIEUTH + {0x9EFC, 0xC6A2}, //5338 #HANGUL SYLLABLE IEUNG YO RIEULPHIEUPH + {0x9EFD, 0xC6A3}, //5339 #HANGUL SYLLABLE IEUNG YO RIEULHIEUH + {0x9EFE, 0xC6A6}, //5340 #HANGUL SYLLABLE IEUNG YO PIEUPSIOS + {0x9F41, 0xC6A8}, //5341 #HANGUL SYLLABLE IEUNG YO SSANGSIOS + {0x9F42, 0xC6AA}, //5342 #HANGUL SYLLABLE IEUNG YO CIEUC + {0x9F43, 0xC6AB}, //5343 #HANGUL SYLLABLE IEUNG YO CHIEUCH + {0x9F44, 0xC6AC}, //5344 #HANGUL SYLLABLE IEUNG YO KHIEUKH + {0x9F45, 0xC6AD}, //5345 #HANGUL SYLLABLE IEUNG YO THIEUTH + {0x9F46, 0xC6AE}, //5346 #HANGUL SYLLABLE IEUNG YO PHIEUPH + {0x9F47, 0xC6AF}, //5347 #HANGUL SYLLABLE IEUNG YO HIEUH + {0x9F48, 0xC6B2}, //5348 #HANGUL SYLLABLE IEUNG U SSANGKIYEOK + {0x9F49, 0xC6B3}, //5349 #HANGUL SYLLABLE IEUNG U KIYEOKSIOS + {0x9F4A, 0xC6B5}, //5350 #HANGUL SYLLABLE IEUNG U NIEUNCIEUC + {0x9F4B, 0xC6B6}, //5351 #HANGUL SYLLABLE IEUNG U NIEUNHIEUH + {0x9F4C, 0xC6B7}, //5352 #HANGUL SYLLABLE IEUNG U TIKEUT + {0x9F4D, 0xC6BB}, //5353 #HANGUL SYLLABLE IEUNG U RIEULPIEUP + {0x9F4E, 0xC6BC}, //5354 #HANGUL SYLLABLE IEUNG U RIEULSIOS + {0x9F4F, 0xC6BD}, //5355 #HANGUL SYLLABLE IEUNG U RIEULTHIEUTH + {0x9F50, 0xC6BE}, //5356 #HANGUL SYLLABLE IEUNG U RIEULPHIEUPH + {0x9F51, 0xC6BF}, //5357 #HANGUL SYLLABLE IEUNG U RIEULHIEUH + {0x9F52, 0xC6C2}, //5358 #HANGUL SYLLABLE IEUNG U PIEUPSIOS + {0x9F53, 0xC6C4}, //5359 #HANGUL SYLLABLE IEUNG U SSANGSIOS + {0x9F54, 0xC6C6}, //5360 #HANGUL SYLLABLE IEUNG U CIEUC + {0x9F55, 0xC6C7}, //5361 #HANGUL SYLLABLE IEUNG U CHIEUCH + {0x9F56, 0xC6C8}, //5362 #HANGUL SYLLABLE IEUNG U KHIEUKH + {0x9F57, 0xC6C9}, //5363 #HANGUL SYLLABLE IEUNG U THIEUTH + {0x9F58, 0xC6CA}, //5364 #HANGUL SYLLABLE IEUNG U PHIEUPH + {0x9F59, 0xC6CB}, //5365 #HANGUL SYLLABLE IEUNG U HIEUH + {0x9F5A, 0xC6CE}, //5366 #HANGUL SYLLABLE IEUNG WEO SSANGKIYEOK + {0x9F61, 0xC6CF}, //5367 #HANGUL SYLLABLE IEUNG WEO KIYEOKSIOS + {0x9F62, 0xC6D1}, //5368 #HANGUL SYLLABLE IEUNG WEO NIEUNCIEUC + {0x9F63, 0xC6D2}, //5369 #HANGUL SYLLABLE IEUNG WEO NIEUNHIEUH + {0x9F64, 0xC6D3}, //5370 #HANGUL SYLLABLE IEUNG WEO TIKEUT + {0x9F65, 0xC6D5}, //5371 #HANGUL SYLLABLE IEUNG WEO RIEULKIYEOK + {0x9F66, 0xC6D6}, //5372 #HANGUL SYLLABLE IEUNG WEO RIEULMIEUM + {0x9F67, 0xC6D7}, //5373 #HANGUL SYLLABLE IEUNG WEO RIEULPIEUP + {0x9F68, 0xC6D8}, //5374 #HANGUL SYLLABLE IEUNG WEO RIEULSIOS + {0x9F69, 0xC6D9}, //5375 #HANGUL SYLLABLE IEUNG WEO RIEULTHIEUTH + {0x9F6A, 0xC6DA}, //5376 #HANGUL SYLLABLE IEUNG WEO RIEULPHIEUPH + {0x9F6B, 0xC6DB}, //5377 #HANGUL SYLLABLE IEUNG WEO RIEULHIEUH + {0x9F6C, 0xC6DE}, //5378 #HANGUL SYLLABLE IEUNG WEO PIEUPSIOS + {0x9F6D, 0xC6DF}, //5379 #HANGUL SYLLABLE IEUNG WEO SIOS + {0x9F6E, 0xC6E2}, //5380 #HANGUL SYLLABLE IEUNG WEO CIEUC + {0x9F6F, 0xC6E3}, //5381 #HANGUL SYLLABLE IEUNG WEO CHIEUCH + {0x9F70, 0xC6E4}, //5382 #HANGUL SYLLABLE IEUNG WEO KHIEUKH + {0x9F71, 0xC6E5}, //5383 #HANGUL SYLLABLE IEUNG WEO THIEUTH + {0x9F72, 0xC6E6}, //5384 #HANGUL SYLLABLE IEUNG WEO PHIEUPH + {0x9F73, 0xC6E7}, //5385 #HANGUL SYLLABLE IEUNG WEO HIEUH + {0x9F74, 0xC6EA}, //5386 #HANGUL SYLLABLE IEUNG WE SSANGKIYEOK + {0x9F75, 0xC6EB}, //5387 #HANGUL SYLLABLE IEUNG WE KIYEOKSIOS + {0x9F76, 0xC6ED}, //5388 #HANGUL SYLLABLE IEUNG WE NIEUNCIEUC + {0x9F77, 0xC6EE}, //5389 #HANGUL SYLLABLE IEUNG WE NIEUNHIEUH + {0x9F78, 0xC6EF}, //5390 #HANGUL SYLLABLE IEUNG WE TIKEUT + {0x9F79, 0xC6F1}, //5391 #HANGUL SYLLABLE IEUNG WE RIEULKIYEOK + {0x9F7A, 0xC6F2}, //5392 #HANGUL SYLLABLE IEUNG WE RIEULMIEUM + {0x9F81, 0xC6F3}, //5393 #HANGUL SYLLABLE IEUNG WE RIEULPIEUP + {0x9F82, 0xC6F4}, //5394 #HANGUL SYLLABLE IEUNG WE RIEULSIOS + {0x9F83, 0xC6F5}, //5395 #HANGUL SYLLABLE IEUNG WE RIEULTHIEUTH + {0x9F84, 0xC6F6}, //5396 #HANGUL SYLLABLE IEUNG WE RIEULPHIEUPH + {0x9F85, 0xC6F7}, //5397 #HANGUL SYLLABLE IEUNG WE RIEULHIEUH + {0x9F86, 0xC6FA}, //5398 #HANGUL SYLLABLE IEUNG WE PIEUPSIOS + {0x9F87, 0xC6FB}, //5399 #HANGUL SYLLABLE IEUNG WE SIOS + {0x9F88, 0xC6FC}, //5400 #HANGUL SYLLABLE IEUNG WE SSANGSIOS + {0x9F89, 0xC6FE}, //5401 #HANGUL SYLLABLE IEUNG WE CIEUC + {0x9F8A, 0xC6FF}, //5402 #HANGUL SYLLABLE IEUNG WE CHIEUCH + {0x9F8B, 0xC700}, //5403 #HANGUL SYLLABLE IEUNG WE KHIEUKH + {0x9F8C, 0xC701}, //5404 #HANGUL SYLLABLE IEUNG WE THIEUTH + {0x9F8D, 0xC702}, //5405 #HANGUL SYLLABLE IEUNG WE PHIEUPH + {0x9F8E, 0xC703}, //5406 #HANGUL SYLLABLE IEUNG WE HIEUH + {0x9F8F, 0xC706}, //5407 #HANGUL SYLLABLE IEUNG WI SSANGKIYEOK + {0x9F90, 0xC707}, //5408 #HANGUL SYLLABLE IEUNG WI KIYEOKSIOS + {0x9F91, 0xC709}, //5409 #HANGUL SYLLABLE IEUNG WI NIEUNCIEUC + {0x9F92, 0xC70A}, //5410 #HANGUL SYLLABLE IEUNG WI NIEUNHIEUH + {0x9F93, 0xC70B}, //5411 #HANGUL SYLLABLE IEUNG WI TIKEUT + {0x9F94, 0xC70D}, //5412 #HANGUL SYLLABLE IEUNG WI RIEULKIYEOK + {0x9F95, 0xC70E}, //5413 #HANGUL SYLLABLE IEUNG WI RIEULMIEUM + {0x9F96, 0xC70F}, //5414 #HANGUL SYLLABLE IEUNG WI RIEULPIEUP + {0x9F97, 0xC710}, //5415 #HANGUL SYLLABLE IEUNG WI RIEULSIOS + {0x9F98, 0xC711}, //5416 #HANGUL SYLLABLE IEUNG WI RIEULTHIEUTH + {0x9F99, 0xC712}, //5417 #HANGUL SYLLABLE IEUNG WI RIEULPHIEUPH + {0x9F9A, 0xC713}, //5418 #HANGUL SYLLABLE IEUNG WI RIEULHIEUH + {0x9F9B, 0xC716}, //5419 #HANGUL SYLLABLE IEUNG WI PIEUPSIOS + {0x9F9C, 0xC718}, //5420 #HANGUL SYLLABLE IEUNG WI SSANGSIOS + {0x9F9D, 0xC71A}, //5421 #HANGUL SYLLABLE IEUNG WI CIEUC + {0x9F9E, 0xC71B}, //5422 #HANGUL SYLLABLE IEUNG WI CHIEUCH + {0x9F9F, 0xC71C}, //5423 #HANGUL SYLLABLE IEUNG WI KHIEUKH + {0x9FA0, 0xC71D}, //5424 #HANGUL SYLLABLE IEUNG WI THIEUTH + {0x9FA1, 0xC71E}, //5425 #HANGUL SYLLABLE IEUNG WI PHIEUPH + {0x9FA2, 0xC71F}, //5426 #HANGUL SYLLABLE IEUNG WI HIEUH + {0x9FA3, 0xC722}, //5427 #HANGUL SYLLABLE IEUNG YU SSANGKIYEOK + {0x9FA4, 0xC723}, //5428 #HANGUL SYLLABLE IEUNG YU KIYEOKSIOS + {0x9FA5, 0xC725}, //5429 #HANGUL SYLLABLE IEUNG YU NIEUNCIEUC + {0x9FA6, 0xC726}, //5430 #HANGUL SYLLABLE IEUNG YU NIEUNHIEUH + {0x9FA7, 0xC727}, //5431 #HANGUL SYLLABLE IEUNG YU TIKEUT + {0x9FA8, 0xC729}, //5432 #HANGUL SYLLABLE IEUNG YU RIEULKIYEOK + {0x9FA9, 0xC72A}, //5433 #HANGUL SYLLABLE IEUNG YU RIEULMIEUM + {0x9FAA, 0xC72B}, //5434 #HANGUL SYLLABLE IEUNG YU RIEULPIEUP + {0x9FAB, 0xC72C}, //5435 #HANGUL SYLLABLE IEUNG YU RIEULSIOS + {0x9FAC, 0xC72D}, //5436 #HANGUL SYLLABLE IEUNG YU RIEULTHIEUTH + {0x9FAD, 0xC72E}, //5437 #HANGUL SYLLABLE IEUNG YU RIEULPHIEUPH + {0x9FAE, 0xC72F}, //5438 #HANGUL SYLLABLE IEUNG YU RIEULHIEUH + {0x9FAF, 0xC732}, //5439 #HANGUL SYLLABLE IEUNG YU PIEUPSIOS + {0x9FB0, 0xC734}, //5440 #HANGUL SYLLABLE IEUNG YU SSANGSIOS + {0x9FB1, 0xC736}, //5441 #HANGUL SYLLABLE IEUNG YU CIEUC + {0x9FB2, 0xC738}, //5442 #HANGUL SYLLABLE IEUNG YU KHIEUKH + {0x9FB3, 0xC739}, //5443 #HANGUL SYLLABLE IEUNG YU THIEUTH + {0x9FB4, 0xC73A}, //5444 #HANGUL SYLLABLE IEUNG YU PHIEUPH + {0x9FB5, 0xC73B}, //5445 #HANGUL SYLLABLE IEUNG YU HIEUH + {0x9FB6, 0xC73E}, //5446 #HANGUL SYLLABLE IEUNG EU SSANGKIYEOK + {0x9FB7, 0xC73F}, //5447 #HANGUL SYLLABLE IEUNG EU KIYEOKSIOS + {0x9FB8, 0xC741}, //5448 #HANGUL SYLLABLE IEUNG EU NIEUNCIEUC + {0x9FB9, 0xC742}, //5449 #HANGUL SYLLABLE IEUNG EU NIEUNHIEUH + {0x9FBA, 0xC743}, //5450 #HANGUL SYLLABLE IEUNG EU TIKEUT + {0x9FBB, 0xC745}, //5451 #HANGUL SYLLABLE IEUNG EU RIEULKIYEOK + {0x9FBC, 0xC746}, //5452 #HANGUL SYLLABLE IEUNG EU RIEULMIEUM + {0x9FBD, 0xC747}, //5453 #HANGUL SYLLABLE IEUNG EU RIEULPIEUP + {0x9FBE, 0xC748}, //5454 #HANGUL SYLLABLE IEUNG EU RIEULSIOS + {0x9FBF, 0xC749}, //5455 #HANGUL SYLLABLE IEUNG EU RIEULTHIEUTH + {0x9FC0, 0xC74B}, //5456 #HANGUL SYLLABLE IEUNG EU RIEULHIEUH + {0x9FC1, 0xC74E}, //5457 #HANGUL SYLLABLE IEUNG EU PIEUPSIOS + {0x9FC2, 0xC750}, //5458 #HANGUL SYLLABLE IEUNG EU SSANGSIOS + {0x9FC3, 0xC759}, //5459 #HANGUL SYLLABLE IEUNG YI KIYEOK + {0x9FC4, 0xC75A}, //5460 #HANGUL SYLLABLE IEUNG YI SSANGKIYEOK + {0x9FC5, 0xC75B}, //5461 #HANGUL SYLLABLE IEUNG YI KIYEOKSIOS + {0x9FC6, 0xC75D}, //5462 #HANGUL SYLLABLE IEUNG YI NIEUNCIEUC + {0x9FC7, 0xC75E}, //5463 #HANGUL SYLLABLE IEUNG YI NIEUNHIEUH + {0x9FC8, 0xC75F}, //5464 #HANGUL SYLLABLE IEUNG YI TIKEUT + {0x9FC9, 0xC761}, //5465 #HANGUL SYLLABLE IEUNG YI RIEULKIYEOK + {0x9FCA, 0xC762}, //5466 #HANGUL SYLLABLE IEUNG YI RIEULMIEUM + {0x9FCB, 0xC763}, //5467 #HANGUL SYLLABLE IEUNG YI RIEULPIEUP + {0x9FCC, 0xC764}, //5468 #HANGUL SYLLABLE IEUNG YI RIEULSIOS + {0x9FCD, 0xC765}, //5469 #HANGUL SYLLABLE IEUNG YI RIEULTHIEUTH + {0x9FCE, 0xC766}, //5470 #HANGUL SYLLABLE IEUNG YI RIEULPHIEUPH + {0x9FCF, 0xC767}, //5471 #HANGUL SYLLABLE IEUNG YI RIEULHIEUH + {0x9FD0, 0xC769}, //5472 #HANGUL SYLLABLE IEUNG YI PIEUP + {0x9FD1, 0xC76A}, //5473 #HANGUL SYLLABLE IEUNG YI PIEUPSIOS + {0x9FD2, 0xC76C}, //5474 #HANGUL SYLLABLE IEUNG YI SSANGSIOS + {0x9FD3, 0xC76D}, //5475 #HANGUL SYLLABLE IEUNG YI IEUNG + {0x9FD4, 0xC76E}, //5476 #HANGUL SYLLABLE IEUNG YI CIEUC + {0x9FD5, 0xC76F}, //5477 #HANGUL SYLLABLE IEUNG YI CHIEUCH + {0x9FD6, 0xC770}, //5478 #HANGUL SYLLABLE IEUNG YI KHIEUKH + {0x9FD7, 0xC771}, //5479 #HANGUL SYLLABLE IEUNG YI THIEUTH + {0x9FD8, 0xC772}, //5480 #HANGUL SYLLABLE IEUNG YI PHIEUPH + {0x9FD9, 0xC773}, //5481 #HANGUL SYLLABLE IEUNG YI HIEUH + {0x9FDA, 0xC776}, //5482 #HANGUL SYLLABLE IEUNG I SSANGKIYEOK + {0x9FDB, 0xC777}, //5483 #HANGUL SYLLABLE IEUNG I KIYEOKSIOS + {0x9FDC, 0xC779}, //5484 #HANGUL SYLLABLE IEUNG I NIEUNCIEUC + {0x9FDD, 0xC77A}, //5485 #HANGUL SYLLABLE IEUNG I NIEUNHIEUH + {0x9FDE, 0xC77B}, //5486 #HANGUL SYLLABLE IEUNG I TIKEUT + {0x9FDF, 0xC77F}, //5487 #HANGUL SYLLABLE IEUNG I RIEULPIEUP + {0x9FE0, 0xC780}, //5488 #HANGUL SYLLABLE IEUNG I RIEULSIOS + {0x9FE1, 0xC781}, //5489 #HANGUL SYLLABLE IEUNG I RIEULTHIEUTH + {0x9FE2, 0xC782}, //5490 #HANGUL SYLLABLE IEUNG I RIEULPHIEUPH + {0x9FE3, 0xC786}, //5491 #HANGUL SYLLABLE IEUNG I PIEUPSIOS + {0x9FE4, 0xC78B}, //5492 #HANGUL SYLLABLE IEUNG I CHIEUCH + {0x9FE5, 0xC78C}, //5493 #HANGUL SYLLABLE IEUNG I KHIEUKH + {0x9FE6, 0xC78D}, //5494 #HANGUL SYLLABLE IEUNG I THIEUTH + {0x9FE7, 0xC78F}, //5495 #HANGUL SYLLABLE IEUNG I HIEUH + {0x9FE8, 0xC792}, //5496 #HANGUL SYLLABLE CIEUC A SSANGKIYEOK + {0x9FE9, 0xC793}, //5497 #HANGUL SYLLABLE CIEUC A KIYEOKSIOS + {0x9FEA, 0xC795}, //5498 #HANGUL SYLLABLE CIEUC A NIEUNCIEUC + {0x9FEB, 0xC799}, //5499 #HANGUL SYLLABLE CIEUC A RIEULKIYEOK + {0x9FEC, 0xC79B}, //5500 #HANGUL SYLLABLE CIEUC A RIEULPIEUP + {0x9FED, 0xC79C}, //5501 #HANGUL SYLLABLE CIEUC A RIEULSIOS + {0x9FEE, 0xC79D}, //5502 #HANGUL SYLLABLE CIEUC A RIEULTHIEUTH + {0x9FEF, 0xC79E}, //5503 #HANGUL SYLLABLE CIEUC A RIEULPHIEUPH + {0x9FF0, 0xC79F}, //5504 #HANGUL SYLLABLE CIEUC A RIEULHIEUH + {0x9FF1, 0xC7A2}, //5505 #HANGUL SYLLABLE CIEUC A PIEUPSIOS + {0x9FF2, 0xC7A7}, //5506 #HANGUL SYLLABLE CIEUC A CHIEUCH + {0x9FF3, 0xC7A8}, //5507 #HANGUL SYLLABLE CIEUC A KHIEUKH + {0x9FF4, 0xC7A9}, //5508 #HANGUL SYLLABLE CIEUC A THIEUTH + {0x9FF5, 0xC7AA}, //5509 #HANGUL SYLLABLE CIEUC A PHIEUPH + {0x9FF6, 0xC7AB}, //5510 #HANGUL SYLLABLE CIEUC A HIEUH + {0x9FF7, 0xC7AE}, //5511 #HANGUL SYLLABLE CIEUC AE SSANGKIYEOK + {0x9FF8, 0xC7AF}, //5512 #HANGUL SYLLABLE CIEUC AE KIYEOKSIOS + {0x9FF9, 0xC7B1}, //5513 #HANGUL SYLLABLE CIEUC AE NIEUNCIEUC + {0x9FFA, 0xC7B2}, //5514 #HANGUL SYLLABLE CIEUC AE NIEUNHIEUH + {0x9FFB, 0xC7B3}, //5515 #HANGUL SYLLABLE CIEUC AE TIKEUT + {0x9FFC, 0xC7B5}, //5516 #HANGUL SYLLABLE CIEUC AE RIEULKIYEOK + {0x9FFD, 0xC7B6}, //5517 #HANGUL SYLLABLE CIEUC AE RIEULMIEUM + {0x9FFE, 0xC7B7}, //5518 #HANGUL SYLLABLE CIEUC AE RIEULPIEUP + {0xA041, 0xC7B8}, //5519 #HANGUL SYLLABLE CIEUC AE RIEULSIOS + {0xA042, 0xC7B9}, //5520 #HANGUL SYLLABLE CIEUC AE RIEULTHIEUTH + {0xA043, 0xC7BA}, //5521 #HANGUL SYLLABLE CIEUC AE RIEULPHIEUPH + {0xA044, 0xC7BB}, //5522 #HANGUL SYLLABLE CIEUC AE RIEULHIEUH + {0xA045, 0xC7BE}, //5523 #HANGUL SYLLABLE CIEUC AE PIEUPSIOS + {0xA046, 0xC7C2}, //5524 #HANGUL SYLLABLE CIEUC AE CIEUC + {0xA047, 0xC7C3}, //5525 #HANGUL SYLLABLE CIEUC AE CHIEUCH + {0xA048, 0xC7C4}, //5526 #HANGUL SYLLABLE CIEUC AE KHIEUKH + {0xA049, 0xC7C5}, //5527 #HANGUL SYLLABLE CIEUC AE THIEUTH + {0xA04A, 0xC7C6}, //5528 #HANGUL SYLLABLE CIEUC AE PHIEUPH + {0xA04B, 0xC7C7}, //5529 #HANGUL SYLLABLE CIEUC AE HIEUH + {0xA04C, 0xC7CA}, //5530 #HANGUL SYLLABLE CIEUC YA SSANGKIYEOK + {0xA04D, 0xC7CB}, //5531 #HANGUL SYLLABLE CIEUC YA KIYEOKSIOS + {0xA04E, 0xC7CD}, //5532 #HANGUL SYLLABLE CIEUC YA NIEUNCIEUC + {0xA04F, 0xC7CF}, //5533 #HANGUL SYLLABLE CIEUC YA TIKEUT + {0xA050, 0xC7D1}, //5534 #HANGUL SYLLABLE CIEUC YA RIEULKIYEOK + {0xA051, 0xC7D2}, //5535 #HANGUL SYLLABLE CIEUC YA RIEULMIEUM + {0xA052, 0xC7D3}, //5536 #HANGUL SYLLABLE CIEUC YA RIEULPIEUP + {0xA053, 0xC7D4}, //5537 #HANGUL SYLLABLE CIEUC YA RIEULSIOS + {0xA054, 0xC7D5}, //5538 #HANGUL SYLLABLE CIEUC YA RIEULTHIEUTH + {0xA055, 0xC7D6}, //5539 #HANGUL SYLLABLE CIEUC YA RIEULPHIEUPH + {0xA056, 0xC7D7}, //5540 #HANGUL SYLLABLE CIEUC YA RIEULHIEUH + {0xA057, 0xC7D9}, //5541 #HANGUL SYLLABLE CIEUC YA PIEUP + {0xA058, 0xC7DA}, //5542 #HANGUL SYLLABLE CIEUC YA PIEUPSIOS + {0xA059, 0xC7DB}, //5543 #HANGUL SYLLABLE CIEUC YA SIOS + {0xA05A, 0xC7DC}, //5544 #HANGUL SYLLABLE CIEUC YA SSANGSIOS + {0xA061, 0xC7DE}, //5545 #HANGUL SYLLABLE CIEUC YA CIEUC + {0xA062, 0xC7DF}, //5546 #HANGUL SYLLABLE CIEUC YA CHIEUCH + {0xA063, 0xC7E0}, //5547 #HANGUL SYLLABLE CIEUC YA KHIEUKH + {0xA064, 0xC7E1}, //5548 #HANGUL SYLLABLE CIEUC YA THIEUTH + {0xA065, 0xC7E2}, //5549 #HANGUL SYLLABLE CIEUC YA PHIEUPH + {0xA066, 0xC7E3}, //5550 #HANGUL SYLLABLE CIEUC YA HIEUH + {0xA067, 0xC7E5}, //5551 #HANGUL SYLLABLE CIEUC YAE KIYEOK + {0xA068, 0xC7E6}, //5552 #HANGUL SYLLABLE CIEUC YAE SSANGKIYEOK + {0xA069, 0xC7E7}, //5553 #HANGUL SYLLABLE CIEUC YAE KIYEOKSIOS + {0xA06A, 0xC7E9}, //5554 #HANGUL SYLLABLE CIEUC YAE NIEUNCIEUC + {0xA06B, 0xC7EA}, //5555 #HANGUL SYLLABLE CIEUC YAE NIEUNHIEUH + {0xA06C, 0xC7EB}, //5556 #HANGUL SYLLABLE CIEUC YAE TIKEUT + {0xA06D, 0xC7ED}, //5557 #HANGUL SYLLABLE CIEUC YAE RIEULKIYEOK + {0xA06E, 0xC7EE}, //5558 #HANGUL SYLLABLE CIEUC YAE RIEULMIEUM + {0xA06F, 0xC7EF}, //5559 #HANGUL SYLLABLE CIEUC YAE RIEULPIEUP + {0xA070, 0xC7F0}, //5560 #HANGUL SYLLABLE CIEUC YAE RIEULSIOS + {0xA071, 0xC7F1}, //5561 #HANGUL SYLLABLE CIEUC YAE RIEULTHIEUTH + {0xA072, 0xC7F2}, //5562 #HANGUL SYLLABLE CIEUC YAE RIEULPHIEUPH + {0xA073, 0xC7F3}, //5563 #HANGUL SYLLABLE CIEUC YAE RIEULHIEUH + {0xA074, 0xC7F4}, //5564 #HANGUL SYLLABLE CIEUC YAE MIEUM + {0xA075, 0xC7F5}, //5565 #HANGUL SYLLABLE CIEUC YAE PIEUP + {0xA076, 0xC7F6}, //5566 #HANGUL SYLLABLE CIEUC YAE PIEUPSIOS + {0xA077, 0xC7F7}, //5567 #HANGUL SYLLABLE CIEUC YAE SIOS + {0xA078, 0xC7F8}, //5568 #HANGUL SYLLABLE CIEUC YAE SSANGSIOS + {0xA079, 0xC7F9}, //5569 #HANGUL SYLLABLE CIEUC YAE IEUNG + {0xA07A, 0xC7FA}, //5570 #HANGUL SYLLABLE CIEUC YAE CIEUC + {0xA081, 0xC7FB}, //5571 #HANGUL SYLLABLE CIEUC YAE CHIEUCH + {0xA082, 0xC7FC}, //5572 #HANGUL SYLLABLE CIEUC YAE KHIEUKH + {0xA083, 0xC7FD}, //5573 #HANGUL SYLLABLE CIEUC YAE THIEUTH + {0xA084, 0xC7FE}, //5574 #HANGUL SYLLABLE CIEUC YAE PHIEUPH + {0xA085, 0xC7FF}, //5575 #HANGUL SYLLABLE CIEUC YAE HIEUH + {0xA086, 0xC802}, //5576 #HANGUL SYLLABLE CIEUC EO SSANGKIYEOK + {0xA087, 0xC803}, //5577 #HANGUL SYLLABLE CIEUC EO KIYEOKSIOS + {0xA088, 0xC805}, //5578 #HANGUL SYLLABLE CIEUC EO NIEUNCIEUC + {0xA089, 0xC806}, //5579 #HANGUL SYLLABLE CIEUC EO NIEUNHIEUH + {0xA08A, 0xC807}, //5580 #HANGUL SYLLABLE CIEUC EO TIKEUT + {0xA08B, 0xC809}, //5581 #HANGUL SYLLABLE CIEUC EO RIEULKIYEOK + {0xA08C, 0xC80B}, //5582 #HANGUL SYLLABLE CIEUC EO RIEULPIEUP + {0xA08D, 0xC80C}, //5583 #HANGUL SYLLABLE CIEUC EO RIEULSIOS + {0xA08E, 0xC80D}, //5584 #HANGUL SYLLABLE CIEUC EO RIEULTHIEUTH + {0xA08F, 0xC80E}, //5585 #HANGUL SYLLABLE CIEUC EO RIEULPHIEUPH + {0xA090, 0xC80F}, //5586 #HANGUL SYLLABLE CIEUC EO RIEULHIEUH + {0xA091, 0xC812}, //5587 #HANGUL SYLLABLE CIEUC EO PIEUPSIOS + {0xA092, 0xC814}, //5588 #HANGUL SYLLABLE CIEUC EO SSANGSIOS + {0xA093, 0xC817}, //5589 #HANGUL SYLLABLE CIEUC EO CHIEUCH + {0xA094, 0xC818}, //5590 #HANGUL SYLLABLE CIEUC EO KHIEUKH + {0xA095, 0xC819}, //5591 #HANGUL SYLLABLE CIEUC EO THIEUTH + {0xA096, 0xC81A}, //5592 #HANGUL SYLLABLE CIEUC EO PHIEUPH + {0xA097, 0xC81B}, //5593 #HANGUL SYLLABLE CIEUC EO HIEUH + {0xA098, 0xC81E}, //5594 #HANGUL SYLLABLE CIEUC E SSANGKIYEOK + {0xA099, 0xC81F}, //5595 #HANGUL SYLLABLE CIEUC E KIYEOKSIOS + {0xA09A, 0xC821}, //5596 #HANGUL SYLLABLE CIEUC E NIEUNCIEUC + {0xA09B, 0xC822}, //5597 #HANGUL SYLLABLE CIEUC E NIEUNHIEUH + {0xA09C, 0xC823}, //5598 #HANGUL SYLLABLE CIEUC E TIKEUT + {0xA09D, 0xC825}, //5599 #HANGUL SYLLABLE CIEUC E RIEULKIYEOK + {0xA09E, 0xC826}, //5600 #HANGUL SYLLABLE CIEUC E RIEULMIEUM + {0xA09F, 0xC827}, //5601 #HANGUL SYLLABLE CIEUC E RIEULPIEUP + {0xA0A0, 0xC828}, //5602 #HANGUL SYLLABLE CIEUC E RIEULSIOS + {0xA0A1, 0xC829}, //5603 #HANGUL SYLLABLE CIEUC E RIEULTHIEUTH + {0xA0A2, 0xC82A}, //5604 #HANGUL SYLLABLE CIEUC E RIEULPHIEUPH + {0xA0A3, 0xC82B}, //5605 #HANGUL SYLLABLE CIEUC E RIEULHIEUH + {0xA0A4, 0xC82E}, //5606 #HANGUL SYLLABLE CIEUC E PIEUPSIOS + {0xA0A5, 0xC830}, //5607 #HANGUL SYLLABLE CIEUC E SSANGSIOS + {0xA0A6, 0xC832}, //5608 #HANGUL SYLLABLE CIEUC E CIEUC + {0xA0A7, 0xC833}, //5609 #HANGUL SYLLABLE CIEUC E CHIEUCH + {0xA0A8, 0xC834}, //5610 #HANGUL SYLLABLE CIEUC E KHIEUKH + {0xA0A9, 0xC835}, //5611 #HANGUL SYLLABLE CIEUC E THIEUTH + {0xA0AA, 0xC836}, //5612 #HANGUL SYLLABLE CIEUC E PHIEUPH + {0xA0AB, 0xC837}, //5613 #HANGUL SYLLABLE CIEUC E HIEUH + {0xA0AC, 0xC839}, //5614 #HANGUL SYLLABLE CIEUC YEO KIYEOK + {0xA0AD, 0xC83A}, //5615 #HANGUL SYLLABLE CIEUC YEO SSANGKIYEOK + {0xA0AE, 0xC83B}, //5616 #HANGUL SYLLABLE CIEUC YEO KIYEOKSIOS + {0xA0AF, 0xC83D}, //5617 #HANGUL SYLLABLE CIEUC YEO NIEUNCIEUC + {0xA0B0, 0xC83E}, //5618 #HANGUL SYLLABLE CIEUC YEO NIEUNHIEUH + {0xA0B1, 0xC83F}, //5619 #HANGUL SYLLABLE CIEUC YEO TIKEUT + {0xA0B2, 0xC841}, //5620 #HANGUL SYLLABLE CIEUC YEO RIEULKIYEOK + {0xA0B3, 0xC842}, //5621 #HANGUL SYLLABLE CIEUC YEO RIEULMIEUM + {0xA0B4, 0xC843}, //5622 #HANGUL SYLLABLE CIEUC YEO RIEULPIEUP + {0xA0B5, 0xC844}, //5623 #HANGUL SYLLABLE CIEUC YEO RIEULSIOS + {0xA0B6, 0xC845}, //5624 #HANGUL SYLLABLE CIEUC YEO RIEULTHIEUTH + {0xA0B7, 0xC846}, //5625 #HANGUL SYLLABLE CIEUC YEO RIEULPHIEUPH + {0xA0B8, 0xC847}, //5626 #HANGUL SYLLABLE CIEUC YEO RIEULHIEUH + {0xA0B9, 0xC84A}, //5627 #HANGUL SYLLABLE CIEUC YEO PIEUPSIOS + {0xA0BA, 0xC84B}, //5628 #HANGUL SYLLABLE CIEUC YEO SIOS + {0xA0BB, 0xC84E}, //5629 #HANGUL SYLLABLE CIEUC YEO CIEUC + {0xA0BC, 0xC84F}, //5630 #HANGUL SYLLABLE CIEUC YEO CHIEUCH + {0xA0BD, 0xC850}, //5631 #HANGUL SYLLABLE CIEUC YEO KHIEUKH + {0xA0BE, 0xC851}, //5632 #HANGUL SYLLABLE CIEUC YEO THIEUTH + {0xA0BF, 0xC852}, //5633 #HANGUL SYLLABLE CIEUC YEO PHIEUPH + {0xA0C0, 0xC853}, //5634 #HANGUL SYLLABLE CIEUC YEO HIEUH + {0xA0C1, 0xC855}, //5635 #HANGUL SYLLABLE CIEUC YE KIYEOK + {0xA0C2, 0xC856}, //5636 #HANGUL SYLLABLE CIEUC YE SSANGKIYEOK + {0xA0C3, 0xC857}, //5637 #HANGUL SYLLABLE CIEUC YE KIYEOKSIOS + {0xA0C4, 0xC858}, //5638 #HANGUL SYLLABLE CIEUC YE NIEUN + {0xA0C5, 0xC859}, //5639 #HANGUL SYLLABLE CIEUC YE NIEUNCIEUC + {0xA0C6, 0xC85A}, //5640 #HANGUL SYLLABLE CIEUC YE NIEUNHIEUH + {0xA0C7, 0xC85B}, //5641 #HANGUL SYLLABLE CIEUC YE TIKEUT + {0xA0C8, 0xC85C}, //5642 #HANGUL SYLLABLE CIEUC YE RIEUL + {0xA0C9, 0xC85D}, //5643 #HANGUL SYLLABLE CIEUC YE RIEULKIYEOK + {0xA0CA, 0xC85E}, //5644 #HANGUL SYLLABLE CIEUC YE RIEULMIEUM + {0xA0CB, 0xC85F}, //5645 #HANGUL SYLLABLE CIEUC YE RIEULPIEUP + {0xA0CC, 0xC860}, //5646 #HANGUL SYLLABLE CIEUC YE RIEULSIOS + {0xA0CD, 0xC861}, //5647 #HANGUL SYLLABLE CIEUC YE RIEULTHIEUTH + {0xA0CE, 0xC862}, //5648 #HANGUL SYLLABLE CIEUC YE RIEULPHIEUPH + {0xA0CF, 0xC863}, //5649 #HANGUL SYLLABLE CIEUC YE RIEULHIEUH + {0xA0D0, 0xC864}, //5650 #HANGUL SYLLABLE CIEUC YE MIEUM + {0xA0D1, 0xC865}, //5651 #HANGUL SYLLABLE CIEUC YE PIEUP + {0xA0D2, 0xC866}, //5652 #HANGUL SYLLABLE CIEUC YE PIEUPSIOS + {0xA0D3, 0xC867}, //5653 #HANGUL SYLLABLE CIEUC YE SIOS + {0xA0D4, 0xC868}, //5654 #HANGUL SYLLABLE CIEUC YE SSANGSIOS + {0xA0D5, 0xC869}, //5655 #HANGUL SYLLABLE CIEUC YE IEUNG + {0xA0D6, 0xC86A}, //5656 #HANGUL SYLLABLE CIEUC YE CIEUC + {0xA0D7, 0xC86B}, //5657 #HANGUL SYLLABLE CIEUC YE CHIEUCH + {0xA0D8, 0xC86C}, //5658 #HANGUL SYLLABLE CIEUC YE KHIEUKH + {0xA0D9, 0xC86D}, //5659 #HANGUL SYLLABLE CIEUC YE THIEUTH + {0xA0DA, 0xC86E}, //5660 #HANGUL SYLLABLE CIEUC YE PHIEUPH + {0xA0DB, 0xC86F}, //5661 #HANGUL SYLLABLE CIEUC YE HIEUH + {0xA0DC, 0xC872}, //5662 #HANGUL SYLLABLE CIEUC O SSANGKIYEOK + {0xA0DD, 0xC873}, //5663 #HANGUL SYLLABLE CIEUC O KIYEOKSIOS + {0xA0DE, 0xC875}, //5664 #HANGUL SYLLABLE CIEUC O NIEUNCIEUC + {0xA0DF, 0xC876}, //5665 #HANGUL SYLLABLE CIEUC O NIEUNHIEUH + {0xA0E0, 0xC877}, //5666 #HANGUL SYLLABLE CIEUC O TIKEUT + {0xA0E1, 0xC879}, //5667 #HANGUL SYLLABLE CIEUC O RIEULKIYEOK + {0xA0E2, 0xC87B}, //5668 #HANGUL SYLLABLE CIEUC O RIEULPIEUP + {0xA0E3, 0xC87C}, //5669 #HANGUL SYLLABLE CIEUC O RIEULSIOS + {0xA0E4, 0xC87D}, //5670 #HANGUL SYLLABLE CIEUC O RIEULTHIEUTH + {0xA0E5, 0xC87E}, //5671 #HANGUL SYLLABLE CIEUC O RIEULPHIEUPH + {0xA0E6, 0xC87F}, //5672 #HANGUL SYLLABLE CIEUC O RIEULHIEUH + {0xA0E7, 0xC882}, //5673 #HANGUL SYLLABLE CIEUC O PIEUPSIOS + {0xA0E8, 0xC884}, //5674 #HANGUL SYLLABLE CIEUC O SSANGSIOS + {0xA0E9, 0xC888}, //5675 #HANGUL SYLLABLE CIEUC O KHIEUKH + {0xA0EA, 0xC889}, //5676 #HANGUL SYLLABLE CIEUC O THIEUTH + {0xA0EB, 0xC88A}, //5677 #HANGUL SYLLABLE CIEUC O PHIEUPH + {0xA0EC, 0xC88E}, //5678 #HANGUL SYLLABLE CIEUC WA SSANGKIYEOK + {0xA0ED, 0xC88F}, //5679 #HANGUL SYLLABLE CIEUC WA KIYEOKSIOS + {0xA0EE, 0xC890}, //5680 #HANGUL SYLLABLE CIEUC WA NIEUN + {0xA0EF, 0xC891}, //5681 #HANGUL SYLLABLE CIEUC WA NIEUNCIEUC + {0xA0F0, 0xC892}, //5682 #HANGUL SYLLABLE CIEUC WA NIEUNHIEUH + {0xA0F1, 0xC893}, //5683 #HANGUL SYLLABLE CIEUC WA TIKEUT + {0xA0F2, 0xC895}, //5684 #HANGUL SYLLABLE CIEUC WA RIEULKIYEOK + {0xA0F3, 0xC896}, //5685 #HANGUL SYLLABLE CIEUC WA RIEULMIEUM + {0xA0F4, 0xC897}, //5686 #HANGUL SYLLABLE CIEUC WA RIEULPIEUP + {0xA0F5, 0xC898}, //5687 #HANGUL SYLLABLE CIEUC WA RIEULSIOS + {0xA0F6, 0xC899}, //5688 #HANGUL SYLLABLE CIEUC WA RIEULTHIEUTH + {0xA0F7, 0xC89A}, //5689 #HANGUL SYLLABLE CIEUC WA RIEULPHIEUPH + {0xA0F8, 0xC89B}, //5690 #HANGUL SYLLABLE CIEUC WA RIEULHIEUH + {0xA0F9, 0xC89C}, //5691 #HANGUL SYLLABLE CIEUC WA MIEUM + {0xA0FA, 0xC89E}, //5692 #HANGUL SYLLABLE CIEUC WA PIEUPSIOS + {0xA0FB, 0xC8A0}, //5693 #HANGUL SYLLABLE CIEUC WA SSANGSIOS + {0xA0FC, 0xC8A2}, //5694 #HANGUL SYLLABLE CIEUC WA CIEUC + {0xA0FD, 0xC8A3}, //5695 #HANGUL SYLLABLE CIEUC WA CHIEUCH + {0xA0FE, 0xC8A4}, //5696 #HANGUL SYLLABLE CIEUC WA KHIEUKH + {0xA141, 0xC8A5}, //5697 #HANGUL SYLLABLE CIEUC WA THIEUTH + {0xA142, 0xC8A6}, //5698 #HANGUL SYLLABLE CIEUC WA PHIEUPH + {0xA143, 0xC8A7}, //5699 #HANGUL SYLLABLE CIEUC WA HIEUH + {0xA144, 0xC8A9}, //5700 #HANGUL SYLLABLE CIEUC WAE KIYEOK + {0xA145, 0xC8AA}, //5701 #HANGUL SYLLABLE CIEUC WAE SSANGKIYEOK + {0xA146, 0xC8AB}, //5702 #HANGUL SYLLABLE CIEUC WAE KIYEOKSIOS + {0xA147, 0xC8AC}, //5703 #HANGUL SYLLABLE CIEUC WAE NIEUN + {0xA148, 0xC8AD}, //5704 #HANGUL SYLLABLE CIEUC WAE NIEUNCIEUC + {0xA149, 0xC8AE}, //5705 #HANGUL SYLLABLE CIEUC WAE NIEUNHIEUH + {0xA14A, 0xC8AF}, //5706 #HANGUL SYLLABLE CIEUC WAE TIKEUT + {0xA14B, 0xC8B0}, //5707 #HANGUL SYLLABLE CIEUC WAE RIEUL + {0xA14C, 0xC8B1}, //5708 #HANGUL SYLLABLE CIEUC WAE RIEULKIYEOK + {0xA14D, 0xC8B2}, //5709 #HANGUL SYLLABLE CIEUC WAE RIEULMIEUM + {0xA14E, 0xC8B3}, //5710 #HANGUL SYLLABLE CIEUC WAE RIEULPIEUP + {0xA14F, 0xC8B4}, //5711 #HANGUL SYLLABLE CIEUC WAE RIEULSIOS + {0xA150, 0xC8B5}, //5712 #HANGUL SYLLABLE CIEUC WAE RIEULTHIEUTH + {0xA151, 0xC8B6}, //5713 #HANGUL SYLLABLE CIEUC WAE RIEULPHIEUPH + {0xA152, 0xC8B7}, //5714 #HANGUL SYLLABLE CIEUC WAE RIEULHIEUH + {0xA153, 0xC8B8}, //5715 #HANGUL SYLLABLE CIEUC WAE MIEUM + {0xA154, 0xC8B9}, //5716 #HANGUL SYLLABLE CIEUC WAE PIEUP + {0xA155, 0xC8BA}, //5717 #HANGUL SYLLABLE CIEUC WAE PIEUPSIOS + {0xA156, 0xC8BB}, //5718 #HANGUL SYLLABLE CIEUC WAE SIOS + {0xA157, 0xC8BE}, //5719 #HANGUL SYLLABLE CIEUC WAE CIEUC + {0xA158, 0xC8BF}, //5720 #HANGUL SYLLABLE CIEUC WAE CHIEUCH + {0xA159, 0xC8C0}, //5721 #HANGUL SYLLABLE CIEUC WAE KHIEUKH + {0xA15A, 0xC8C1}, //5722 #HANGUL SYLLABLE CIEUC WAE THIEUTH + {0xA161, 0xC8C2}, //5723 #HANGUL SYLLABLE CIEUC WAE PHIEUPH + {0xA162, 0xC8C3}, //5724 #HANGUL SYLLABLE CIEUC WAE HIEUH + {0xA163, 0xC8C5}, //5725 #HANGUL SYLLABLE CIEUC OE KIYEOK + {0xA164, 0xC8C6}, //5726 #HANGUL SYLLABLE CIEUC OE SSANGKIYEOK + {0xA165, 0xC8C7}, //5727 #HANGUL SYLLABLE CIEUC OE KIYEOKSIOS + {0xA166, 0xC8C9}, //5728 #HANGUL SYLLABLE CIEUC OE NIEUNCIEUC + {0xA167, 0xC8CA}, //5729 #HANGUL SYLLABLE CIEUC OE NIEUNHIEUH + {0xA168, 0xC8CB}, //5730 #HANGUL SYLLABLE CIEUC OE TIKEUT + {0xA169, 0xC8CD}, //5731 #HANGUL SYLLABLE CIEUC OE RIEULKIYEOK + {0xA16A, 0xC8CE}, //5732 #HANGUL SYLLABLE CIEUC OE RIEULMIEUM + {0xA16B, 0xC8CF}, //5733 #HANGUL SYLLABLE CIEUC OE RIEULPIEUP + {0xA16C, 0xC8D0}, //5734 #HANGUL SYLLABLE CIEUC OE RIEULSIOS + {0xA16D, 0xC8D1}, //5735 #HANGUL SYLLABLE CIEUC OE RIEULTHIEUTH + {0xA16E, 0xC8D2}, //5736 #HANGUL SYLLABLE CIEUC OE RIEULPHIEUPH + {0xA16F, 0xC8D3}, //5737 #HANGUL SYLLABLE CIEUC OE RIEULHIEUH + {0xA170, 0xC8D6}, //5738 #HANGUL SYLLABLE CIEUC OE PIEUPSIOS + {0xA171, 0xC8D8}, //5739 #HANGUL SYLLABLE CIEUC OE SSANGSIOS + {0xA172, 0xC8DA}, //5740 #HANGUL SYLLABLE CIEUC OE CIEUC + {0xA173, 0xC8DB}, //5741 #HANGUL SYLLABLE CIEUC OE CHIEUCH + {0xA174, 0xC8DC}, //5742 #HANGUL SYLLABLE CIEUC OE KHIEUKH + {0xA175, 0xC8DD}, //5743 #HANGUL SYLLABLE CIEUC OE THIEUTH + {0xA176, 0xC8DE}, //5744 #HANGUL SYLLABLE CIEUC OE PHIEUPH + {0xA177, 0xC8DF}, //5745 #HANGUL SYLLABLE CIEUC OE HIEUH + {0xA178, 0xC8E2}, //5746 #HANGUL SYLLABLE CIEUC YO SSANGKIYEOK + {0xA179, 0xC8E3}, //5747 #HANGUL SYLLABLE CIEUC YO KIYEOKSIOS + {0xA17A, 0xC8E5}, //5748 #HANGUL SYLLABLE CIEUC YO NIEUNCIEUC + {0xA181, 0xC8E6}, //5749 #HANGUL SYLLABLE CIEUC YO NIEUNHIEUH + {0xA182, 0xC8E7}, //5750 #HANGUL SYLLABLE CIEUC YO TIKEUT + {0xA183, 0xC8E8}, //5751 #HANGUL SYLLABLE CIEUC YO RIEUL + {0xA184, 0xC8E9}, //5752 #HANGUL SYLLABLE CIEUC YO RIEULKIYEOK + {0xA185, 0xC8EA}, //5753 #HANGUL SYLLABLE CIEUC YO RIEULMIEUM + {0xA186, 0xC8EB}, //5754 #HANGUL SYLLABLE CIEUC YO RIEULPIEUP + {0xA187, 0xC8EC}, //5755 #HANGUL SYLLABLE CIEUC YO RIEULSIOS + {0xA188, 0xC8ED}, //5756 #HANGUL SYLLABLE CIEUC YO RIEULTHIEUTH + {0xA189, 0xC8EE}, //5757 #HANGUL SYLLABLE CIEUC YO RIEULPHIEUPH + {0xA18A, 0xC8EF}, //5758 #HANGUL SYLLABLE CIEUC YO RIEULHIEUH + {0xA18B, 0xC8F0}, //5759 #HANGUL SYLLABLE CIEUC YO MIEUM + {0xA18C, 0xC8F1}, //5760 #HANGUL SYLLABLE CIEUC YO PIEUP + {0xA18D, 0xC8F2}, //5761 #HANGUL SYLLABLE CIEUC YO PIEUPSIOS + {0xA18E, 0xC8F3}, //5762 #HANGUL SYLLABLE CIEUC YO SIOS + {0xA18F, 0xC8F4}, //5763 #HANGUL SYLLABLE CIEUC YO SSANGSIOS + {0xA190, 0xC8F6}, //5764 #HANGUL SYLLABLE CIEUC YO CIEUC + {0xA191, 0xC8F7}, //5765 #HANGUL SYLLABLE CIEUC YO CHIEUCH + {0xA192, 0xC8F8}, //5766 #HANGUL SYLLABLE CIEUC YO KHIEUKH + {0xA193, 0xC8F9}, //5767 #HANGUL SYLLABLE CIEUC YO THIEUTH + {0xA194, 0xC8FA}, //5768 #HANGUL SYLLABLE CIEUC YO PHIEUPH + {0xA195, 0xC8FB}, //5769 #HANGUL SYLLABLE CIEUC YO HIEUH + {0xA196, 0xC8FE}, //5770 #HANGUL SYLLABLE CIEUC U SSANGKIYEOK + {0xA197, 0xC8FF}, //5771 #HANGUL SYLLABLE CIEUC U KIYEOKSIOS + {0xA198, 0xC901}, //5772 #HANGUL SYLLABLE CIEUC U NIEUNCIEUC + {0xA199, 0xC902}, //5773 #HANGUL SYLLABLE CIEUC U NIEUNHIEUH + {0xA19A, 0xC903}, //5774 #HANGUL SYLLABLE CIEUC U TIKEUT + {0xA19B, 0xC907}, //5775 #HANGUL SYLLABLE CIEUC U RIEULPIEUP + {0xA19C, 0xC908}, //5776 #HANGUL SYLLABLE CIEUC U RIEULSIOS + {0xA19D, 0xC909}, //5777 #HANGUL SYLLABLE CIEUC U RIEULTHIEUTH + {0xA19E, 0xC90A}, //5778 #HANGUL SYLLABLE CIEUC U RIEULPHIEUPH + {0xA19F, 0xC90B}, //5779 #HANGUL SYLLABLE CIEUC U RIEULHIEUH + {0xA1A0, 0xC90E}, //5780 #HANGUL SYLLABLE CIEUC U PIEUPSIOS + {0xA1A1, 0x3000}, //5781 #IDEOGRAPHIC SPACE + {0xA1A2, 0x3001}, //5782 #IDEOGRAPHIC COMMA + {0xA1A3, 0x3002}, //5783 #IDEOGRAPHIC FULL STOP + {0xA1A4, 0x00B7}, //5784 #MIDDLE DOT + {0xA1A5, 0x2025}, //5785 #TWO DOT LEADER + {0xA1A6, 0x2026}, //5786 #HORIZONTAL ELLIPSIS + {0xA1A7, 0x00A8}, //5787 #DIAERESIS + {0xA1A8, 0x3003}, //5788 #DITTO MARK + {0xA1A9, 0x00AD}, //5789 #SOFT HYPHEN + {0xA1AA, 0x2015}, //5790 #HORIZONTAL BAR + {0xA1AB, 0x2225}, //5791 #PARALLEL TO + {0xA1AC, 0xFF3C}, //5792 #FULLWIDTH REVERSE SOLIDUS + {0xA1AD, 0x223C}, //5793 #TILDE OPERATOR + {0xA1AE, 0x2018}, //5794 #LEFT SINGLE QUOTATION MARK + {0xA1AF, 0x2019}, //5795 #RIGHT SINGLE QUOTATION MARK + {0xA1B0, 0x201C}, //5796 #LEFT DOUBLE QUOTATION MARK + {0xA1B1, 0x201D}, //5797 #RIGHT DOUBLE QUOTATION MARK + {0xA1B2, 0x3014}, //5798 #LEFT TORTOISE SHELL BRACKET + {0xA1B3, 0x3015}, //5799 #RIGHT TORTOISE SHELL BRACKET + {0xA1B4, 0x3008}, //5800 #LEFT ANGLE BRACKET + {0xA1B5, 0x3009}, //5801 #RIGHT ANGLE BRACKET + {0xA1B6, 0x300A}, //5802 #LEFT DOUBLE ANGLE BRACKET + {0xA1B7, 0x300B}, //5803 #RIGHT DOUBLE ANGLE BRACKET + {0xA1B8, 0x300C}, //5804 #LEFT CORNER BRACKET + {0xA1B9, 0x300D}, //5805 #RIGHT CORNER BRACKET + {0xA1BA, 0x300E}, //5806 #LEFT WHITE CORNER BRACKET + {0xA1BB, 0x300F}, //5807 #RIGHT WHITE CORNER BRACKET + {0xA1BC, 0x3010}, //5808 #LEFT BLACK LENTICULAR BRACKET + {0xA1BD, 0x3011}, //5809 #RIGHT BLACK LENTICULAR BRACKET + {0xA1BE, 0x00B1}, //5810 #PLUS-MINUS SIGN + {0xA1BF, 0x00D7}, //5811 #MULTIPLICATION SIGN + {0xA1C0, 0x00F7}, //5812 #DIVISION SIGN + {0xA1C1, 0x2260}, //5813 #NOT EQUAL TO + {0xA1C2, 0x2264}, //5814 #LESS-THAN OR EQUAL TO + {0xA1C3, 0x2265}, //5815 #GREATER-THAN OR EQUAL TO + {0xA1C4, 0x221E}, //5816 #INFINITY + {0xA1C5, 0x2234}, //5817 #THEREFORE + {0xA1C6, 0x00B0}, //5818 #DEGREE SIGN + {0xA1C7, 0x2032}, //5819 #PRIME + {0xA1C8, 0x2033}, //5820 #DOUBLE PRIME + {0xA1C9, 0x2103}, //5821 #DEGREE CELSIUS + {0xA1CA, 0x212B}, //5822 #ANGSTROM SIGN + {0xA1CB, 0xFFE0}, //5823 #FULLWIDTH CENT SIGN + {0xA1CC, 0xFFE1}, //5824 #FULLWIDTH POUND SIGN + {0xA1CD, 0xFFE5}, //5825 #FULLWIDTH YEN SIGN + {0xA1CE, 0x2642}, //5826 #MALE SIGN + {0xA1CF, 0x2640}, //5827 #FEMALE SIGN + {0xA1D0, 0x2220}, //5828 #ANGLE + {0xA1D1, 0x22A5}, //5829 #UP TACK + {0xA1D2, 0x2312}, //5830 #ARC + {0xA1D3, 0x2202}, //5831 #PARTIAL DIFFERENTIAL + {0xA1D4, 0x2207}, //5832 #NABLA + {0xA1D5, 0x2261}, //5833 #IDENTICAL TO + {0xA1D6, 0x2252}, //5834 #APPROXIMATELY EQUAL TO OR THE IMAGE OF + {0xA1D7, 0x00A7}, //5835 #SECTION SIGN + {0xA1D8, 0x203B}, //5836 #REFERENCE MARK + {0xA1D9, 0x2606}, //5837 #WHITE STAR + {0xA1DA, 0x2605}, //5838 #BLACK STAR + {0xA1DB, 0x25CB}, //5839 #WHITE CIRCLE + {0xA1DC, 0x25CF}, //5840 #BLACK CIRCLE + {0xA1DD, 0x25CE}, //5841 #BULLSEYE + {0xA1DE, 0x25C7}, //5842 #WHITE DIAMOND + {0xA1DF, 0x25C6}, //5843 #BLACK DIAMOND + {0xA1E0, 0x25A1}, //5844 #WHITE SQUARE + {0xA1E1, 0x25A0}, //5845 #BLACK SQUARE + {0xA1E2, 0x25B3}, //5846 #WHITE UP-POINTING TRIANGLE + {0xA1E3, 0x25B2}, //5847 #BLACK UP-POINTING TRIANGLE + {0xA1E4, 0x25BD}, //5848 #WHITE DOWN-POINTING TRIANGLE + {0xA1E5, 0x25BC}, //5849 #BLACK DOWN-POINTING TRIANGLE + {0xA1E6, 0x2192}, //5850 #RIGHTWARDS ARROW + {0xA1E7, 0x2190}, //5851 #LEFTWARDS ARROW + {0xA1E8, 0x2191}, //5852 #UPWARDS ARROW + {0xA1E9, 0x2193}, //5853 #DOWNWARDS ARROW + {0xA1EA, 0x2194}, //5854 #LEFT RIGHT ARROW + {0xA1EB, 0x3013}, //5855 #GETA MARK + {0xA1EC, 0x226A}, //5856 #MUCH LESS-THAN + {0xA1ED, 0x226B}, //5857 #MUCH GREATER-THAN + {0xA1EE, 0x221A}, //5858 #SQUARE ROOT + {0xA1EF, 0x223D}, //5859 #REVERSED TILDE + {0xA1F0, 0x221D}, //5860 #PROPORTIONAL TO + {0xA1F1, 0x2235}, //5861 #BECAUSE + {0xA1F2, 0x222B}, //5862 #INTEGRAL + {0xA1F3, 0x222C}, //5863 #DOUBLE INTEGRAL + {0xA1F4, 0x2208}, //5864 #ELEMENT OF + {0xA1F5, 0x220B}, //5865 #CONTAINS AS MEMBER + {0xA1F6, 0x2286}, //5866 #SUBSET OF OR EQUAL TO + {0xA1F7, 0x2287}, //5867 #SUPERSET OF OR EQUAL TO + {0xA1F8, 0x2282}, //5868 #SUBSET OF + {0xA1F9, 0x2283}, //5869 #SUPERSET OF + {0xA1FA, 0x222A}, //5870 #UNION + {0xA1FB, 0x2229}, //5871 #INTERSECTION + {0xA1FC, 0x2227}, //5872 #LOGICAL AND + {0xA1FD, 0x2228}, //5873 #LOGICAL OR + {0xA1FE, 0xFFE2}, //5874 #FULLWIDTH NOT SIGN + {0xA241, 0xC910}, //5875 #HANGUL SYLLABLE CIEUC U SSANGSIOS + {0xA242, 0xC912}, //5876 #HANGUL SYLLABLE CIEUC U CIEUC + {0xA243, 0xC913}, //5877 #HANGUL SYLLABLE CIEUC U CHIEUCH + {0xA244, 0xC914}, //5878 #HANGUL SYLLABLE CIEUC U KHIEUKH + {0xA245, 0xC915}, //5879 #HANGUL SYLLABLE CIEUC U THIEUTH + {0xA246, 0xC916}, //5880 #HANGUL SYLLABLE CIEUC U PHIEUPH + {0xA247, 0xC917}, //5881 #HANGUL SYLLABLE CIEUC U HIEUH + {0xA248, 0xC919}, //5882 #HANGUL SYLLABLE CIEUC WEO KIYEOK + {0xA249, 0xC91A}, //5883 #HANGUL SYLLABLE CIEUC WEO SSANGKIYEOK + {0xA24A, 0xC91B}, //5884 #HANGUL SYLLABLE CIEUC WEO KIYEOKSIOS + {0xA24B, 0xC91C}, //5885 #HANGUL SYLLABLE CIEUC WEO NIEUN + {0xA24C, 0xC91D}, //5886 #HANGUL SYLLABLE CIEUC WEO NIEUNCIEUC + {0xA24D, 0xC91E}, //5887 #HANGUL SYLLABLE CIEUC WEO NIEUNHIEUH + {0xA24E, 0xC91F}, //5888 #HANGUL SYLLABLE CIEUC WEO TIKEUT + {0xA24F, 0xC920}, //5889 #HANGUL SYLLABLE CIEUC WEO RIEUL + {0xA250, 0xC921}, //5890 #HANGUL SYLLABLE CIEUC WEO RIEULKIYEOK + {0xA251, 0xC922}, //5891 #HANGUL SYLLABLE CIEUC WEO RIEULMIEUM + {0xA252, 0xC923}, //5892 #HANGUL SYLLABLE CIEUC WEO RIEULPIEUP + {0xA253, 0xC924}, //5893 #HANGUL SYLLABLE CIEUC WEO RIEULSIOS + {0xA254, 0xC925}, //5894 #HANGUL SYLLABLE CIEUC WEO RIEULTHIEUTH + {0xA255, 0xC926}, //5895 #HANGUL SYLLABLE CIEUC WEO RIEULPHIEUPH + {0xA256, 0xC927}, //5896 #HANGUL SYLLABLE CIEUC WEO RIEULHIEUH + {0xA257, 0xC928}, //5897 #HANGUL SYLLABLE CIEUC WEO MIEUM + {0xA258, 0xC929}, //5898 #HANGUL SYLLABLE CIEUC WEO PIEUP + {0xA259, 0xC92A}, //5899 #HANGUL SYLLABLE CIEUC WEO PIEUPSIOS + {0xA25A, 0xC92B}, //5900 #HANGUL SYLLABLE CIEUC WEO SIOS + {0xA261, 0xC92D}, //5901 #HANGUL SYLLABLE CIEUC WEO IEUNG + {0xA262, 0xC92E}, //5902 #HANGUL SYLLABLE CIEUC WEO CIEUC + {0xA263, 0xC92F}, //5903 #HANGUL SYLLABLE CIEUC WEO CHIEUCH + {0xA264, 0xC930}, //5904 #HANGUL SYLLABLE CIEUC WEO KHIEUKH + {0xA265, 0xC931}, //5905 #HANGUL SYLLABLE CIEUC WEO THIEUTH + {0xA266, 0xC932}, //5906 #HANGUL SYLLABLE CIEUC WEO PHIEUPH + {0xA267, 0xC933}, //5907 #HANGUL SYLLABLE CIEUC WEO HIEUH + {0xA268, 0xC935}, //5908 #HANGUL SYLLABLE CIEUC WE KIYEOK + {0xA269, 0xC936}, //5909 #HANGUL SYLLABLE CIEUC WE SSANGKIYEOK + {0xA26A, 0xC937}, //5910 #HANGUL SYLLABLE CIEUC WE KIYEOKSIOS + {0xA26B, 0xC938}, //5911 #HANGUL SYLLABLE CIEUC WE NIEUN + {0xA26C, 0xC939}, //5912 #HANGUL SYLLABLE CIEUC WE NIEUNCIEUC + {0xA26D, 0xC93A}, //5913 #HANGUL SYLLABLE CIEUC WE NIEUNHIEUH + {0xA26E, 0xC93B}, //5914 #HANGUL SYLLABLE CIEUC WE TIKEUT + {0xA26F, 0xC93C}, //5915 #HANGUL SYLLABLE CIEUC WE RIEUL + {0xA270, 0xC93D}, //5916 #HANGUL SYLLABLE CIEUC WE RIEULKIYEOK + {0xA271, 0xC93E}, //5917 #HANGUL SYLLABLE CIEUC WE RIEULMIEUM + {0xA272, 0xC93F}, //5918 #HANGUL SYLLABLE CIEUC WE RIEULPIEUP + {0xA273, 0xC940}, //5919 #HANGUL SYLLABLE CIEUC WE RIEULSIOS + {0xA274, 0xC941}, //5920 #HANGUL SYLLABLE CIEUC WE RIEULTHIEUTH + {0xA275, 0xC942}, //5921 #HANGUL SYLLABLE CIEUC WE RIEULPHIEUPH + {0xA276, 0xC943}, //5922 #HANGUL SYLLABLE CIEUC WE RIEULHIEUH + {0xA277, 0xC944}, //5923 #HANGUL SYLLABLE CIEUC WE MIEUM + {0xA278, 0xC945}, //5924 #HANGUL SYLLABLE CIEUC WE PIEUP + {0xA279, 0xC946}, //5925 #HANGUL SYLLABLE CIEUC WE PIEUPSIOS + {0xA27A, 0xC947}, //5926 #HANGUL SYLLABLE CIEUC WE SIOS + {0xA281, 0xC948}, //5927 #HANGUL SYLLABLE CIEUC WE SSANGSIOS + {0xA282, 0xC949}, //5928 #HANGUL SYLLABLE CIEUC WE IEUNG + {0xA283, 0xC94A}, //5929 #HANGUL SYLLABLE CIEUC WE CIEUC + {0xA284, 0xC94B}, //5930 #HANGUL SYLLABLE CIEUC WE CHIEUCH + {0xA285, 0xC94C}, //5931 #HANGUL SYLLABLE CIEUC WE KHIEUKH + {0xA286, 0xC94D}, //5932 #HANGUL SYLLABLE CIEUC WE THIEUTH + {0xA287, 0xC94E}, //5933 #HANGUL SYLLABLE CIEUC WE PHIEUPH + {0xA288, 0xC94F}, //5934 #HANGUL SYLLABLE CIEUC WE HIEUH + {0xA289, 0xC952}, //5935 #HANGUL SYLLABLE CIEUC WI SSANGKIYEOK + {0xA28A, 0xC953}, //5936 #HANGUL SYLLABLE CIEUC WI KIYEOKSIOS + {0xA28B, 0xC955}, //5937 #HANGUL SYLLABLE CIEUC WI NIEUNCIEUC + {0xA28C, 0xC956}, //5938 #HANGUL SYLLABLE CIEUC WI NIEUNHIEUH + {0xA28D, 0xC957}, //5939 #HANGUL SYLLABLE CIEUC WI TIKEUT + {0xA28E, 0xC959}, //5940 #HANGUL SYLLABLE CIEUC WI RIEULKIYEOK + {0xA28F, 0xC95A}, //5941 #HANGUL SYLLABLE CIEUC WI RIEULMIEUM + {0xA290, 0xC95B}, //5942 #HANGUL SYLLABLE CIEUC WI RIEULPIEUP + {0xA291, 0xC95C}, //5943 #HANGUL SYLLABLE CIEUC WI RIEULSIOS + {0xA292, 0xC95D}, //5944 #HANGUL SYLLABLE CIEUC WI RIEULTHIEUTH + {0xA293, 0xC95E}, //5945 #HANGUL SYLLABLE CIEUC WI RIEULPHIEUPH + {0xA294, 0xC95F}, //5946 #HANGUL SYLLABLE CIEUC WI RIEULHIEUH + {0xA295, 0xC962}, //5947 #HANGUL SYLLABLE CIEUC WI PIEUPSIOS + {0xA296, 0xC964}, //5948 #HANGUL SYLLABLE CIEUC WI SSANGSIOS + {0xA297, 0xC965}, //5949 #HANGUL SYLLABLE CIEUC WI IEUNG + {0xA298, 0xC966}, //5950 #HANGUL SYLLABLE CIEUC WI CIEUC + {0xA299, 0xC967}, //5951 #HANGUL SYLLABLE CIEUC WI CHIEUCH + {0xA29A, 0xC968}, //5952 #HANGUL SYLLABLE CIEUC WI KHIEUKH + {0xA29B, 0xC969}, //5953 #HANGUL SYLLABLE CIEUC WI THIEUTH + {0xA29C, 0xC96A}, //5954 #HANGUL SYLLABLE CIEUC WI PHIEUPH + {0xA29D, 0xC96B}, //5955 #HANGUL SYLLABLE CIEUC WI HIEUH + {0xA29E, 0xC96D}, //5956 #HANGUL SYLLABLE CIEUC YU KIYEOK + {0xA29F, 0xC96E}, //5957 #HANGUL SYLLABLE CIEUC YU SSANGKIYEOK + {0xA2A0, 0xC96F}, //5958 #HANGUL SYLLABLE CIEUC YU KIYEOKSIOS + {0xA2A1, 0x21D2}, //5959 #RIGHTWARDS DOUBLE ARROW + {0xA2A2, 0x21D4}, //5960 #LEFT RIGHT DOUBLE ARROW + {0xA2A3, 0x2200}, //5961 #FOR ALL + {0xA2A4, 0x2203}, //5962 #THERE EXISTS + {0xA2A5, 0x00B4}, //5963 #ACUTE ACCENT + {0xA2A6, 0xFF5E}, //5964 #FULLWIDTH TILDE + {0xA2A7, 0x02C7}, //5965 #CARON + {0xA2A8, 0x02D8}, //5966 #BREVE + {0xA2A9, 0x02DD}, //5967 #DOUBLE ACUTE ACCENT + {0xA2AA, 0x02DA}, //5968 #RING ABOVE + {0xA2AB, 0x02D9}, //5969 #DOT ABOVE + {0xA2AC, 0x00B8}, //5970 #CEDILLA + {0xA2AD, 0x02DB}, //5971 #OGONEK + {0xA2AE, 0x00A1}, //5972 #INVERTED EXCLAMATION MARK + {0xA2AF, 0x00BF}, //5973 #INVERTED QUESTION MARK + {0xA2B0, 0x02D0}, //5974 #MODIFIER LETTER TRIANGULAR COLON + {0xA2B1, 0x222E}, //5975 #CONTOUR INTEGRAL + {0xA2B2, 0x2211}, //5976 #N-ARY SUMMATION + {0xA2B3, 0x220F}, //5977 #N-ARY PRODUCT + {0xA2B4, 0x00A4}, //5978 #CURRENCY SIGN + {0xA2B5, 0x2109}, //5979 #DEGREE FAHRENHEIT + {0xA2B6, 0x2030}, //5980 #PER MILLE SIGN + {0xA2B7, 0x25C1}, //5981 #WHITE LEFT-POINTING TRIANGLE + {0xA2B8, 0x25C0}, //5982 #BLACK LEFT-POINTING TRIANGLE + {0xA2B9, 0x25B7}, //5983 #WHITE RIGHT-POINTING TRIANGLE + {0xA2BA, 0x25B6}, //5984 #BLACK RIGHT-POINTING TRIANGLE + {0xA2BB, 0x2664}, //5985 #WHITE SPADE SUIT + {0xA2BC, 0x2660}, //5986 #BLACK SPADE SUIT + {0xA2BD, 0x2661}, //5987 #WHITE HEART SUIT + {0xA2BE, 0x2665}, //5988 #BLACK HEART SUIT + {0xA2BF, 0x2667}, //5989 #WHITE CLUB SUIT + {0xA2C0, 0x2663}, //5990 #BLACK CLUB SUIT + {0xA2C1, 0x2299}, //5991 #CIRCLED DOT OPERATOR + {0xA2C2, 0x25C8}, //5992 #WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND + {0xA2C3, 0x25A3}, //5993 #WHITE SQUARE CONTAINING BLACK SMALL SQUARE + {0xA2C4, 0x25D0}, //5994 #CIRCLE WITH LEFT HALF BLACK + {0xA2C5, 0x25D1}, //5995 #CIRCLE WITH RIGHT HALF BLACK + {0xA2C6, 0x2592}, //5996 #MEDIUM SHADE + {0xA2C7, 0x25A4}, //5997 #SQUARE WITH HORIZONTAL FILL + {0xA2C8, 0x25A5}, //5998 #SQUARE WITH VERTICAL FILL + {0xA2C9, 0x25A8}, //5999 #SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL + {0xA2CA, 0x25A7}, //6000 #SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL + {0xA2CB, 0x25A6}, //6001 #SQUARE WITH ORTHOGONAL CROSSHATCH FILL + {0xA2CC, 0x25A9}, //6002 #SQUARE WITH DIAGONAL CROSSHATCH FILL + {0xA2CD, 0x2668}, //6003 #HOT SPRINGS + {0xA2CE, 0x260F}, //6004 #WHITE TELEPHONE + {0xA2CF, 0x260E}, //6005 #BLACK TELEPHONE + {0xA2D0, 0x261C}, //6006 #WHITE LEFT POINTING INDEX + {0xA2D1, 0x261E}, //6007 #WHITE RIGHT POINTING INDEX + {0xA2D2, 0x00B6}, //6008 #PILCROW SIGN + {0xA2D3, 0x2020}, //6009 #DAGGER + {0xA2D4, 0x2021}, //6010 #DOUBLE DAGGER + {0xA2D5, 0x2195}, //6011 #UP DOWN ARROW + {0xA2D6, 0x2197}, //6012 #NORTH EAST ARROW + {0xA2D7, 0x2199}, //6013 #SOUTH WEST ARROW + {0xA2D8, 0x2196}, //6014 #NORTH WEST ARROW + {0xA2D9, 0x2198}, //6015 #SOUTH EAST ARROW + {0xA2DA, 0x266D}, //6016 #MUSIC FLAT SIGN + {0xA2DB, 0x2669}, //6017 #QUARTER NOTE + {0xA2DC, 0x266A}, //6018 #EIGHTH NOTE + {0xA2DD, 0x266C}, //6019 #BEAMED SIXTEENTH NOTES + {0xA2DE, 0x327F}, //6020 #KOREAN STANDARD SYMBOL + {0xA2DF, 0x321C}, //6021 #PARENTHESIZED HANGUL CIEUC U + {0xA2E0, 0x2116}, //6022 #NUMERO SIGN + {0xA2E1, 0x33C7}, //6023 #SQUARE CO + {0xA2E2, 0x2122}, //6024 #TRADE MARK SIGN + {0xA2E3, 0x33C2}, //6025 #SQUARE AM + {0xA2E4, 0x33D8}, //6026 #SQUARE PM + {0xA2E5, 0x2121}, //6027 #TELEPHONE SIGN + {0xA2E6, 0x20AC}, //6028 #EURO SIGN + {0xA2E7, 0x00AE}, //6029 #REGISTERED SIGN + {0xA341, 0xC971}, //6030 #HANGUL SYLLABLE CIEUC YU NIEUNCIEUC + {0xA342, 0xC972}, //6031 #HANGUL SYLLABLE CIEUC YU NIEUNHIEUH + {0xA343, 0xC973}, //6032 #HANGUL SYLLABLE CIEUC YU TIKEUT + {0xA344, 0xC975}, //6033 #HANGUL SYLLABLE CIEUC YU RIEULKIYEOK + {0xA345, 0xC976}, //6034 #HANGUL SYLLABLE CIEUC YU RIEULMIEUM + {0xA346, 0xC977}, //6035 #HANGUL SYLLABLE CIEUC YU RIEULPIEUP + {0xA347, 0xC978}, //6036 #HANGUL SYLLABLE CIEUC YU RIEULSIOS + {0xA348, 0xC979}, //6037 #HANGUL SYLLABLE CIEUC YU RIEULTHIEUTH + {0xA349, 0xC97A}, //6038 #HANGUL SYLLABLE CIEUC YU RIEULPHIEUPH + {0xA34A, 0xC97B}, //6039 #HANGUL SYLLABLE CIEUC YU RIEULHIEUH + {0xA34B, 0xC97D}, //6040 #HANGUL SYLLABLE CIEUC YU PIEUP + {0xA34C, 0xC97E}, //6041 #HANGUL SYLLABLE CIEUC YU PIEUPSIOS + {0xA34D, 0xC97F}, //6042 #HANGUL SYLLABLE CIEUC YU SIOS + {0xA34E, 0xC980}, //6043 #HANGUL SYLLABLE CIEUC YU SSANGSIOS + {0xA34F, 0xC981}, //6044 #HANGUL SYLLABLE CIEUC YU IEUNG + {0xA350, 0xC982}, //6045 #HANGUL SYLLABLE CIEUC YU CIEUC + {0xA351, 0xC983}, //6046 #HANGUL SYLLABLE CIEUC YU CHIEUCH + {0xA352, 0xC984}, //6047 #HANGUL SYLLABLE CIEUC YU KHIEUKH + {0xA353, 0xC985}, //6048 #HANGUL SYLLABLE CIEUC YU THIEUTH + {0xA354, 0xC986}, //6049 #HANGUL SYLLABLE CIEUC YU PHIEUPH + {0xA355, 0xC987}, //6050 #HANGUL SYLLABLE CIEUC YU HIEUH + {0xA356, 0xC98A}, //6051 #HANGUL SYLLABLE CIEUC EU SSANGKIYEOK + {0xA357, 0xC98B}, //6052 #HANGUL SYLLABLE CIEUC EU KIYEOKSIOS + {0xA358, 0xC98D}, //6053 #HANGUL SYLLABLE CIEUC EU NIEUNCIEUC + {0xA359, 0xC98E}, //6054 #HANGUL SYLLABLE CIEUC EU NIEUNHIEUH + {0xA35A, 0xC98F}, //6055 #HANGUL SYLLABLE CIEUC EU TIKEUT + {0xA361, 0xC991}, //6056 #HANGUL SYLLABLE CIEUC EU RIEULKIYEOK + {0xA362, 0xC992}, //6057 #HANGUL SYLLABLE CIEUC EU RIEULMIEUM + {0xA363, 0xC993}, //6058 #HANGUL SYLLABLE CIEUC EU RIEULPIEUP + {0xA364, 0xC994}, //6059 #HANGUL SYLLABLE CIEUC EU RIEULSIOS + {0xA365, 0xC995}, //6060 #HANGUL SYLLABLE CIEUC EU RIEULTHIEUTH + {0xA366, 0xC996}, //6061 #HANGUL SYLLABLE CIEUC EU RIEULPHIEUPH + {0xA367, 0xC997}, //6062 #HANGUL SYLLABLE CIEUC EU RIEULHIEUH + {0xA368, 0xC99A}, //6063 #HANGUL SYLLABLE CIEUC EU PIEUPSIOS + {0xA369, 0xC99C}, //6064 #HANGUL SYLLABLE CIEUC EU SSANGSIOS + {0xA36A, 0xC99E}, //6065 #HANGUL SYLLABLE CIEUC EU CIEUC + {0xA36B, 0xC99F}, //6066 #HANGUL SYLLABLE CIEUC EU CHIEUCH + {0xA36C, 0xC9A0}, //6067 #HANGUL SYLLABLE CIEUC EU KHIEUKH + {0xA36D, 0xC9A1}, //6068 #HANGUL SYLLABLE CIEUC EU THIEUTH + {0xA36E, 0xC9A2}, //6069 #HANGUL SYLLABLE CIEUC EU PHIEUPH + {0xA36F, 0xC9A3}, //6070 #HANGUL SYLLABLE CIEUC EU HIEUH + {0xA370, 0xC9A4}, //6071 #HANGUL SYLLABLE CIEUC YI + {0xA371, 0xC9A5}, //6072 #HANGUL SYLLABLE CIEUC YI KIYEOK + {0xA372, 0xC9A6}, //6073 #HANGUL SYLLABLE CIEUC YI SSANGKIYEOK + {0xA373, 0xC9A7}, //6074 #HANGUL SYLLABLE CIEUC YI KIYEOKSIOS + {0xA374, 0xC9A8}, //6075 #HANGUL SYLLABLE CIEUC YI NIEUN + {0xA375, 0xC9A9}, //6076 #HANGUL SYLLABLE CIEUC YI NIEUNCIEUC + {0xA376, 0xC9AA}, //6077 #HANGUL SYLLABLE CIEUC YI NIEUNHIEUH + {0xA377, 0xC9AB}, //6078 #HANGUL SYLLABLE CIEUC YI TIKEUT + {0xA378, 0xC9AC}, //6079 #HANGUL SYLLABLE CIEUC YI RIEUL + {0xA379, 0xC9AD}, //6080 #HANGUL SYLLABLE CIEUC YI RIEULKIYEOK + {0xA37A, 0xC9AE}, //6081 #HANGUL SYLLABLE CIEUC YI RIEULMIEUM + {0xA381, 0xC9AF}, //6082 #HANGUL SYLLABLE CIEUC YI RIEULPIEUP + {0xA382, 0xC9B0}, //6083 #HANGUL SYLLABLE CIEUC YI RIEULSIOS + {0xA383, 0xC9B1}, //6084 #HANGUL SYLLABLE CIEUC YI RIEULTHIEUTH + {0xA384, 0xC9B2}, //6085 #HANGUL SYLLABLE CIEUC YI RIEULPHIEUPH + {0xA385, 0xC9B3}, //6086 #HANGUL SYLLABLE CIEUC YI RIEULHIEUH + {0xA386, 0xC9B4}, //6087 #HANGUL SYLLABLE CIEUC YI MIEUM + {0xA387, 0xC9B5}, //6088 #HANGUL SYLLABLE CIEUC YI PIEUP + {0xA388, 0xC9B6}, //6089 #HANGUL SYLLABLE CIEUC YI PIEUPSIOS + {0xA389, 0xC9B7}, //6090 #HANGUL SYLLABLE CIEUC YI SIOS + {0xA38A, 0xC9B8}, //6091 #HANGUL SYLLABLE CIEUC YI SSANGSIOS + {0xA38B, 0xC9B9}, //6092 #HANGUL SYLLABLE CIEUC YI IEUNG + {0xA38C, 0xC9BA}, //6093 #HANGUL SYLLABLE CIEUC YI CIEUC + {0xA38D, 0xC9BB}, //6094 #HANGUL SYLLABLE CIEUC YI CHIEUCH + {0xA38E, 0xC9BC}, //6095 #HANGUL SYLLABLE CIEUC YI KHIEUKH + {0xA38F, 0xC9BD}, //6096 #HANGUL SYLLABLE CIEUC YI THIEUTH + {0xA390, 0xC9BE}, //6097 #HANGUL SYLLABLE CIEUC YI PHIEUPH + {0xA391, 0xC9BF}, //6098 #HANGUL SYLLABLE CIEUC YI HIEUH + {0xA392, 0xC9C2}, //6099 #HANGUL SYLLABLE CIEUC I SSANGKIYEOK + {0xA393, 0xC9C3}, //6100 #HANGUL SYLLABLE CIEUC I KIYEOKSIOS + {0xA394, 0xC9C5}, //6101 #HANGUL SYLLABLE CIEUC I NIEUNCIEUC + {0xA395, 0xC9C6}, //6102 #HANGUL SYLLABLE CIEUC I NIEUNHIEUH + {0xA396, 0xC9C9}, //6103 #HANGUL SYLLABLE CIEUC I RIEULKIYEOK + {0xA397, 0xC9CB}, //6104 #HANGUL SYLLABLE CIEUC I RIEULPIEUP + {0xA398, 0xC9CC}, //6105 #HANGUL SYLLABLE CIEUC I RIEULSIOS + {0xA399, 0xC9CD}, //6106 #HANGUL SYLLABLE CIEUC I RIEULTHIEUTH + {0xA39A, 0xC9CE}, //6107 #HANGUL SYLLABLE CIEUC I RIEULPHIEUPH + {0xA39B, 0xC9CF}, //6108 #HANGUL SYLLABLE CIEUC I RIEULHIEUH + {0xA39C, 0xC9D2}, //6109 #HANGUL SYLLABLE CIEUC I PIEUPSIOS + {0xA39D, 0xC9D4}, //6110 #HANGUL SYLLABLE CIEUC I SSANGSIOS + {0xA39E, 0xC9D7}, //6111 #HANGUL SYLLABLE CIEUC I CHIEUCH + {0xA39F, 0xC9D8}, //6112 #HANGUL SYLLABLE CIEUC I KHIEUKH + {0xA3A0, 0xC9DB}, //6113 #HANGUL SYLLABLE CIEUC I HIEUH + {0xA3A1, 0xFF01}, //6114 #FULLWIDTH EXCLAMATION MARK + {0xA3A2, 0xFF02}, //6115 #FULLWIDTH QUOTATION MARK + {0xA3A3, 0xFF03}, //6116 #FULLWIDTH NUMBER SIGN + {0xA3A4, 0xFF04}, //6117 #FULLWIDTH DOLLAR SIGN + {0xA3A5, 0xFF05}, //6118 #FULLWIDTH PERCENT SIGN + {0xA3A6, 0xFF06}, //6119 #FULLWIDTH AMPERSAND + {0xA3A7, 0xFF07}, //6120 #FULLWIDTH APOSTROPHE + {0xA3A8, 0xFF08}, //6121 #FULLWIDTH LEFT PARENTHESIS + {0xA3A9, 0xFF09}, //6122 #FULLWIDTH RIGHT PARENTHESIS + {0xA3AA, 0xFF0A}, //6123 #FULLWIDTH ASTERISK + {0xA3AB, 0xFF0B}, //6124 #FULLWIDTH PLUS SIGN + {0xA3AC, 0xFF0C}, //6125 #FULLWIDTH COMMA + {0xA3AD, 0xFF0D}, //6126 #FULLWIDTH HYPHEN-MINUS + {0xA3AE, 0xFF0E}, //6127 #FULLWIDTH FULL STOP + {0xA3AF, 0xFF0F}, //6128 #FULLWIDTH SOLIDUS + {0xA3B0, 0xFF10}, //6129 #FULLWIDTH DIGIT ZERO + {0xA3B1, 0xFF11}, //6130 #FULLWIDTH DIGIT ONE + {0xA3B2, 0xFF12}, //6131 #FULLWIDTH DIGIT TWO + {0xA3B3, 0xFF13}, //6132 #FULLWIDTH DIGIT THREE + {0xA3B4, 0xFF14}, //6133 #FULLWIDTH DIGIT FOUR + {0xA3B5, 0xFF15}, //6134 #FULLWIDTH DIGIT FIVE + {0xA3B6, 0xFF16}, //6135 #FULLWIDTH DIGIT SIX + {0xA3B7, 0xFF17}, //6136 #FULLWIDTH DIGIT SEVEN + {0xA3B8, 0xFF18}, //6137 #FULLWIDTH DIGIT EIGHT + {0xA3B9, 0xFF19}, //6138 #FULLWIDTH DIGIT NINE + {0xA3BA, 0xFF1A}, //6139 #FULLWIDTH COLON + {0xA3BB, 0xFF1B}, //6140 #FULLWIDTH SEMICOLON + {0xA3BC, 0xFF1C}, //6141 #FULLWIDTH LESS-THAN SIGN + {0xA3BD, 0xFF1D}, //6142 #FULLWIDTH EQUALS SIGN + {0xA3BE, 0xFF1E}, //6143 #FULLWIDTH GREATER-THAN SIGN + {0xA3BF, 0xFF1F}, //6144 #FULLWIDTH QUESTION MARK + {0xA3C0, 0xFF20}, //6145 #FULLWIDTH COMMERCIAL AT + {0xA3C1, 0xFF21}, //6146 #FULLWIDTH LATIN CAPITAL LETTER A + {0xA3C2, 0xFF22}, //6147 #FULLWIDTH LATIN CAPITAL LETTER B + {0xA3C3, 0xFF23}, //6148 #FULLWIDTH LATIN CAPITAL LETTER C + {0xA3C4, 0xFF24}, //6149 #FULLWIDTH LATIN CAPITAL LETTER D + {0xA3C5, 0xFF25}, //6150 #FULLWIDTH LATIN CAPITAL LETTER E + {0xA3C6, 0xFF26}, //6151 #FULLWIDTH LATIN CAPITAL LETTER F + {0xA3C7, 0xFF27}, //6152 #FULLWIDTH LATIN CAPITAL LETTER G + {0xA3C8, 0xFF28}, //6153 #FULLWIDTH LATIN CAPITAL LETTER H + {0xA3C9, 0xFF29}, //6154 #FULLWIDTH LATIN CAPITAL LETTER I + {0xA3CA, 0xFF2A}, //6155 #FULLWIDTH LATIN CAPITAL LETTER J + {0xA3CB, 0xFF2B}, //6156 #FULLWIDTH LATIN CAPITAL LETTER K + {0xA3CC, 0xFF2C}, //6157 #FULLWIDTH LATIN CAPITAL LETTER L + {0xA3CD, 0xFF2D}, //6158 #FULLWIDTH LATIN CAPITAL LETTER M + {0xA3CE, 0xFF2E}, //6159 #FULLWIDTH LATIN CAPITAL LETTER N + {0xA3CF, 0xFF2F}, //6160 #FULLWIDTH LATIN CAPITAL LETTER O + {0xA3D0, 0xFF30}, //6161 #FULLWIDTH LATIN CAPITAL LETTER P + {0xA3D1, 0xFF31}, //6162 #FULLWIDTH LATIN CAPITAL LETTER Q + {0xA3D2, 0xFF32}, //6163 #FULLWIDTH LATIN CAPITAL LETTER R + {0xA3D3, 0xFF33}, //6164 #FULLWIDTH LATIN CAPITAL LETTER S + {0xA3D4, 0xFF34}, //6165 #FULLWIDTH LATIN CAPITAL LETTER T + {0xA3D5, 0xFF35}, //6166 #FULLWIDTH LATIN CAPITAL LETTER U + {0xA3D6, 0xFF36}, //6167 #FULLWIDTH LATIN CAPITAL LETTER V + {0xA3D7, 0xFF37}, //6168 #FULLWIDTH LATIN CAPITAL LETTER W + {0xA3D8, 0xFF38}, //6169 #FULLWIDTH LATIN CAPITAL LETTER X + {0xA3D9, 0xFF39}, //6170 #FULLWIDTH LATIN CAPITAL LETTER Y + {0xA3DA, 0xFF3A}, //6171 #FULLWIDTH LATIN CAPITAL LETTER Z + {0xA3DB, 0xFF3B}, //6172 #FULLWIDTH LEFT SQUARE BRACKET + {0xA3DC, 0xFFE6}, //6173 #FULLWIDTH WON SIGN + {0xA3DD, 0xFF3D}, //6174 #FULLWIDTH RIGHT SQUARE BRACKET + {0xA3DE, 0xFF3E}, //6175 #FULLWIDTH CIRCUMFLEX ACCENT + {0xA3DF, 0xFF3F}, //6176 #FULLWIDTH LOW LINE + {0xA3E0, 0xFF40}, //6177 #FULLWIDTH GRAVE ACCENT + {0xA3E1, 0xFF41}, //6178 #FULLWIDTH LATIN SMALL LETTER A + {0xA3E2, 0xFF42}, //6179 #FULLWIDTH LATIN SMALL LETTER B + {0xA3E3, 0xFF43}, //6180 #FULLWIDTH LATIN SMALL LETTER C + {0xA3E4, 0xFF44}, //6181 #FULLWIDTH LATIN SMALL LETTER D + {0xA3E5, 0xFF45}, //6182 #FULLWIDTH LATIN SMALL LETTER E + {0xA3E6, 0xFF46}, //6183 #FULLWIDTH LATIN SMALL LETTER F + {0xA3E7, 0xFF47}, //6184 #FULLWIDTH LATIN SMALL LETTER G + {0xA3E8, 0xFF48}, //6185 #FULLWIDTH LATIN SMALL LETTER H + {0xA3E9, 0xFF49}, //6186 #FULLWIDTH LATIN SMALL LETTER I + {0xA3EA, 0xFF4A}, //6187 #FULLWIDTH LATIN SMALL LETTER J + {0xA3EB, 0xFF4B}, //6188 #FULLWIDTH LATIN SMALL LETTER K + {0xA3EC, 0xFF4C}, //6189 #FULLWIDTH LATIN SMALL LETTER L + {0xA3ED, 0xFF4D}, //6190 #FULLWIDTH LATIN SMALL LETTER M + {0xA3EE, 0xFF4E}, //6191 #FULLWIDTH LATIN SMALL LETTER N + {0xA3EF, 0xFF4F}, //6192 #FULLWIDTH LATIN SMALL LETTER O + {0xA3F0, 0xFF50}, //6193 #FULLWIDTH LATIN SMALL LETTER P + {0xA3F1, 0xFF51}, //6194 #FULLWIDTH LATIN SMALL LETTER Q + {0xA3F2, 0xFF52}, //6195 #FULLWIDTH LATIN SMALL LETTER R + {0xA3F3, 0xFF53}, //6196 #FULLWIDTH LATIN SMALL LETTER S + {0xA3F4, 0xFF54}, //6197 #FULLWIDTH LATIN SMALL LETTER T + {0xA3F5, 0xFF55}, //6198 #FULLWIDTH LATIN SMALL LETTER U + {0xA3F6, 0xFF56}, //6199 #FULLWIDTH LATIN SMALL LETTER V + {0xA3F7, 0xFF57}, //6200 #FULLWIDTH LATIN SMALL LETTER W + {0xA3F8, 0xFF58}, //6201 #FULLWIDTH LATIN SMALL LETTER X + {0xA3F9, 0xFF59}, //6202 #FULLWIDTH LATIN SMALL LETTER Y + {0xA3FA, 0xFF5A}, //6203 #FULLWIDTH LATIN SMALL LETTER Z + {0xA3FB, 0xFF5B}, //6204 #FULLWIDTH LEFT CURLY BRACKET + {0xA3FC, 0xFF5C}, //6205 #FULLWIDTH VERTICAL LINE + {0xA3FD, 0xFF5D}, //6206 #FULLWIDTH RIGHT CURLY BRACKET + {0xA3FE, 0xFFE3}, //6207 #FULLWIDTH MACRON + {0xA441, 0xC9DE}, //6208 #HANGUL SYLLABLE SSANGCIEUC A SSANGKIYEOK + {0xA442, 0xC9DF}, //6209 #HANGUL SYLLABLE SSANGCIEUC A KIYEOKSIOS + {0xA443, 0xC9E1}, //6210 #HANGUL SYLLABLE SSANGCIEUC A NIEUNCIEUC + {0xA444, 0xC9E3}, //6211 #HANGUL SYLLABLE SSANGCIEUC A TIKEUT + {0xA445, 0xC9E5}, //6212 #HANGUL SYLLABLE SSANGCIEUC A RIEULKIYEOK + {0xA446, 0xC9E6}, //6213 #HANGUL SYLLABLE SSANGCIEUC A RIEULMIEUM + {0xA447, 0xC9E8}, //6214 #HANGUL SYLLABLE SSANGCIEUC A RIEULSIOS + {0xA448, 0xC9E9}, //6215 #HANGUL SYLLABLE SSANGCIEUC A RIEULTHIEUTH + {0xA449, 0xC9EA}, //6216 #HANGUL SYLLABLE SSANGCIEUC A RIEULPHIEUPH + {0xA44A, 0xC9EB}, //6217 #HANGUL SYLLABLE SSANGCIEUC A RIEULHIEUH + {0xA44B, 0xC9EE}, //6218 #HANGUL SYLLABLE SSANGCIEUC A PIEUPSIOS + {0xA44C, 0xC9F2}, //6219 #HANGUL SYLLABLE SSANGCIEUC A CIEUC + {0xA44D, 0xC9F3}, //6220 #HANGUL SYLLABLE SSANGCIEUC A CHIEUCH + {0xA44E, 0xC9F4}, //6221 #HANGUL SYLLABLE SSANGCIEUC A KHIEUKH + {0xA44F, 0xC9F5}, //6222 #HANGUL SYLLABLE SSANGCIEUC A THIEUTH + {0xA450, 0xC9F6}, //6223 #HANGUL SYLLABLE SSANGCIEUC A PHIEUPH + {0xA451, 0xC9F7}, //6224 #HANGUL SYLLABLE SSANGCIEUC A HIEUH + {0xA452, 0xC9FA}, //6225 #HANGUL SYLLABLE SSANGCIEUC AE SSANGKIYEOK + {0xA453, 0xC9FB}, //6226 #HANGUL SYLLABLE SSANGCIEUC AE KIYEOKSIOS + {0xA454, 0xC9FD}, //6227 #HANGUL SYLLABLE SSANGCIEUC AE NIEUNCIEUC + {0xA455, 0xC9FE}, //6228 #HANGUL SYLLABLE SSANGCIEUC AE NIEUNHIEUH + {0xA456, 0xC9FF}, //6229 #HANGUL SYLLABLE SSANGCIEUC AE TIKEUT + {0xA457, 0xCA01}, //6230 #HANGUL SYLLABLE SSANGCIEUC AE RIEULKIYEOK + {0xA458, 0xCA02}, //6231 #HANGUL SYLLABLE SSANGCIEUC AE RIEULMIEUM + {0xA459, 0xCA03}, //6232 #HANGUL SYLLABLE SSANGCIEUC AE RIEULPIEUP + {0xA45A, 0xCA04}, //6233 #HANGUL SYLLABLE SSANGCIEUC AE RIEULSIOS + {0xA461, 0xCA05}, //6234 #HANGUL SYLLABLE SSANGCIEUC AE RIEULTHIEUTH + {0xA462, 0xCA06}, //6235 #HANGUL SYLLABLE SSANGCIEUC AE RIEULPHIEUPH + {0xA463, 0xCA07}, //6236 #HANGUL SYLLABLE SSANGCIEUC AE RIEULHIEUH + {0xA464, 0xCA0A}, //6237 #HANGUL SYLLABLE SSANGCIEUC AE PIEUPSIOS + {0xA465, 0xCA0E}, //6238 #HANGUL SYLLABLE SSANGCIEUC AE CIEUC + {0xA466, 0xCA0F}, //6239 #HANGUL SYLLABLE SSANGCIEUC AE CHIEUCH + {0xA467, 0xCA10}, //6240 #HANGUL SYLLABLE SSANGCIEUC AE KHIEUKH + {0xA468, 0xCA11}, //6241 #HANGUL SYLLABLE SSANGCIEUC AE THIEUTH + {0xA469, 0xCA12}, //6242 #HANGUL SYLLABLE SSANGCIEUC AE PHIEUPH + {0xA46A, 0xCA13}, //6243 #HANGUL SYLLABLE SSANGCIEUC AE HIEUH + {0xA46B, 0xCA15}, //6244 #HANGUL SYLLABLE SSANGCIEUC YA KIYEOK + {0xA46C, 0xCA16}, //6245 #HANGUL SYLLABLE SSANGCIEUC YA SSANGKIYEOK + {0xA46D, 0xCA17}, //6246 #HANGUL SYLLABLE SSANGCIEUC YA KIYEOKSIOS + {0xA46E, 0xCA19}, //6247 #HANGUL SYLLABLE SSANGCIEUC YA NIEUNCIEUC + {0xA46F, 0xCA1A}, //6248 #HANGUL SYLLABLE SSANGCIEUC YA NIEUNHIEUH + {0xA470, 0xCA1B}, //6249 #HANGUL SYLLABLE SSANGCIEUC YA TIKEUT + {0xA471, 0xCA1C}, //6250 #HANGUL SYLLABLE SSANGCIEUC YA RIEUL + {0xA472, 0xCA1D}, //6251 #HANGUL SYLLABLE SSANGCIEUC YA RIEULKIYEOK + {0xA473, 0xCA1E}, //6252 #HANGUL SYLLABLE SSANGCIEUC YA RIEULMIEUM + {0xA474, 0xCA1F}, //6253 #HANGUL SYLLABLE SSANGCIEUC YA RIEULPIEUP + {0xA475, 0xCA20}, //6254 #HANGUL SYLLABLE SSANGCIEUC YA RIEULSIOS + {0xA476, 0xCA21}, //6255 #HANGUL SYLLABLE SSANGCIEUC YA RIEULTHIEUTH + {0xA477, 0xCA22}, //6256 #HANGUL SYLLABLE SSANGCIEUC YA RIEULPHIEUPH + {0xA478, 0xCA23}, //6257 #HANGUL SYLLABLE SSANGCIEUC YA RIEULHIEUH + {0xA479, 0xCA24}, //6258 #HANGUL SYLLABLE SSANGCIEUC YA MIEUM + {0xA47A, 0xCA25}, //6259 #HANGUL SYLLABLE SSANGCIEUC YA PIEUP + {0xA481, 0xCA26}, //6260 #HANGUL SYLLABLE SSANGCIEUC YA PIEUPSIOS + {0xA482, 0xCA27}, //6261 #HANGUL SYLLABLE SSANGCIEUC YA SIOS + {0xA483, 0xCA28}, //6262 #HANGUL SYLLABLE SSANGCIEUC YA SSANGSIOS + {0xA484, 0xCA2A}, //6263 #HANGUL SYLLABLE SSANGCIEUC YA CIEUC + {0xA485, 0xCA2B}, //6264 #HANGUL SYLLABLE SSANGCIEUC YA CHIEUCH + {0xA486, 0xCA2C}, //6265 #HANGUL SYLLABLE SSANGCIEUC YA KHIEUKH + {0xA487, 0xCA2D}, //6266 #HANGUL SYLLABLE SSANGCIEUC YA THIEUTH + {0xA488, 0xCA2E}, //6267 #HANGUL SYLLABLE SSANGCIEUC YA PHIEUPH + {0xA489, 0xCA2F}, //6268 #HANGUL SYLLABLE SSANGCIEUC YA HIEUH + {0xA48A, 0xCA30}, //6269 #HANGUL SYLLABLE SSANGCIEUC YAE + {0xA48B, 0xCA31}, //6270 #HANGUL SYLLABLE SSANGCIEUC YAE KIYEOK + {0xA48C, 0xCA32}, //6271 #HANGUL SYLLABLE SSANGCIEUC YAE SSANGKIYEOK + {0xA48D, 0xCA33}, //6272 #HANGUL SYLLABLE SSANGCIEUC YAE KIYEOKSIOS + {0xA48E, 0xCA34}, //6273 #HANGUL SYLLABLE SSANGCIEUC YAE NIEUN + {0xA48F, 0xCA35}, //6274 #HANGUL SYLLABLE SSANGCIEUC YAE NIEUNCIEUC + {0xA490, 0xCA36}, //6275 #HANGUL SYLLABLE SSANGCIEUC YAE NIEUNHIEUH + {0xA491, 0xCA37}, //6276 #HANGUL SYLLABLE SSANGCIEUC YAE TIKEUT + {0xA492, 0xCA38}, //6277 #HANGUL SYLLABLE SSANGCIEUC YAE RIEUL + {0xA493, 0xCA39}, //6278 #HANGUL SYLLABLE SSANGCIEUC YAE RIEULKIYEOK + {0xA494, 0xCA3A}, //6279 #HANGUL SYLLABLE SSANGCIEUC YAE RIEULMIEUM + {0xA495, 0xCA3B}, //6280 #HANGUL SYLLABLE SSANGCIEUC YAE RIEULPIEUP + {0xA496, 0xCA3C}, //6281 #HANGUL SYLLABLE SSANGCIEUC YAE RIEULSIOS + {0xA497, 0xCA3D}, //6282 #HANGUL SYLLABLE SSANGCIEUC YAE RIEULTHIEUTH + {0xA498, 0xCA3E}, //6283 #HANGUL SYLLABLE SSANGCIEUC YAE RIEULPHIEUPH + {0xA499, 0xCA3F}, //6284 #HANGUL SYLLABLE SSANGCIEUC YAE RIEULHIEUH + {0xA49A, 0xCA40}, //6285 #HANGUL SYLLABLE SSANGCIEUC YAE MIEUM + {0xA49B, 0xCA41}, //6286 #HANGUL SYLLABLE SSANGCIEUC YAE PIEUP + {0xA49C, 0xCA42}, //6287 #HANGUL SYLLABLE SSANGCIEUC YAE PIEUPSIOS + {0xA49D, 0xCA43}, //6288 #HANGUL SYLLABLE SSANGCIEUC YAE SIOS + {0xA49E, 0xCA44}, //6289 #HANGUL SYLLABLE SSANGCIEUC YAE SSANGSIOS + {0xA49F, 0xCA45}, //6290 #HANGUL SYLLABLE SSANGCIEUC YAE IEUNG + {0xA4A0, 0xCA46}, //6291 #HANGUL SYLLABLE SSANGCIEUC YAE CIEUC + {0xA4A1, 0x3131}, //6292 #HANGUL LETTER KIYEOK + {0xA4A2, 0x3132}, //6293 #HANGUL LETTER SSANGKIYEOK + {0xA4A3, 0x3133}, //6294 #HANGUL LETTER KIYEOK-SIOS + {0xA4A4, 0x3134}, //6295 #HANGUL LETTER NIEUN + {0xA4A5, 0x3135}, //6296 #HANGUL LETTER NIEUN-CIEUC + {0xA4A6, 0x3136}, //6297 #HANGUL LETTER NIEUN-HIEUH + {0xA4A7, 0x3137}, //6298 #HANGUL LETTER TIKEUT + {0xA4A8, 0x3138}, //6299 #HANGUL LETTER SSANGTIKEUT + {0xA4A9, 0x3139}, //6300 #HANGUL LETTER RIEUL + {0xA4AA, 0x313A}, //6301 #HANGUL LETTER RIEUL-KIYEOK + {0xA4AB, 0x313B}, //6302 #HANGUL LETTER RIEUL-MIEUM + {0xA4AC, 0x313C}, //6303 #HANGUL LETTER RIEUL-PIEUP + {0xA4AD, 0x313D}, //6304 #HANGUL LETTER RIEUL-SIOS + {0xA4AE, 0x313E}, //6305 #HANGUL LETTER RIEUL-THIEUTH + {0xA4AF, 0x313F}, //6306 #HANGUL LETTER RIEUL-PHIEUPH + {0xA4B0, 0x3140}, //6307 #HANGUL LETTER RIEUL-HIEUH + {0xA4B1, 0x3141}, //6308 #HANGUL LETTER MIEUM + {0xA4B2, 0x3142}, //6309 #HANGUL LETTER PIEUP + {0xA4B3, 0x3143}, //6310 #HANGUL LETTER SSANGPIEUP + {0xA4B4, 0x3144}, //6311 #HANGUL LETTER PIEUP-SIOS + {0xA4B5, 0x3145}, //6312 #HANGUL LETTER SIOS + {0xA4B6, 0x3146}, //6313 #HANGUL LETTER SSANGSIOS + {0xA4B7, 0x3147}, //6314 #HANGUL LETTER IEUNG + {0xA4B8, 0x3148}, //6315 #HANGUL LETTER CIEUC + {0xA4B9, 0x3149}, //6316 #HANGUL LETTER SSANGCIEUC + {0xA4BA, 0x314A}, //6317 #HANGUL LETTER CHIEUCH + {0xA4BB, 0x314B}, //6318 #HANGUL LETTER KHIEUKH + {0xA4BC, 0x314C}, //6319 #HANGUL LETTER THIEUTH + {0xA4BD, 0x314D}, //6320 #HANGUL LETTER PHIEUPH + {0xA4BE, 0x314E}, //6321 #HANGUL LETTER HIEUH + {0xA4BF, 0x314F}, //6322 #HANGUL LETTER A + {0xA4C0, 0x3150}, //6323 #HANGUL LETTER AE + {0xA4C1, 0x3151}, //6324 #HANGUL LETTER YA + {0xA4C2, 0x3152}, //6325 #HANGUL LETTER YAE + {0xA4C3, 0x3153}, //6326 #HANGUL LETTER EO + {0xA4C4, 0x3154}, //6327 #HANGUL LETTER E + {0xA4C5, 0x3155}, //6328 #HANGUL LETTER YEO + {0xA4C6, 0x3156}, //6329 #HANGUL LETTER YE + {0xA4C7, 0x3157}, //6330 #HANGUL LETTER O + {0xA4C8, 0x3158}, //6331 #HANGUL LETTER WA + {0xA4C9, 0x3159}, //6332 #HANGUL LETTER WAE + {0xA4CA, 0x315A}, //6333 #HANGUL LETTER OE + {0xA4CB, 0x315B}, //6334 #HANGUL LETTER YO + {0xA4CC, 0x315C}, //6335 #HANGUL LETTER U + {0xA4CD, 0x315D}, //6336 #HANGUL LETTER WEO + {0xA4CE, 0x315E}, //6337 #HANGUL LETTER WE + {0xA4CF, 0x315F}, //6338 #HANGUL LETTER WI + {0xA4D0, 0x3160}, //6339 #HANGUL LETTER YU + {0xA4D1, 0x3161}, //6340 #HANGUL LETTER EU + {0xA4D2, 0x3162}, //6341 #HANGUL LETTER YI + {0xA4D3, 0x3163}, //6342 #HANGUL LETTER I + {0xA4D4, 0x3164}, //6343 #HANGUL FILLER + {0xA4D5, 0x3165}, //6344 #HANGUL LETTER SSANGNIEUN + {0xA4D6, 0x3166}, //6345 #HANGUL LETTER NIEUN-TIKEUT + {0xA4D7, 0x3167}, //6346 #HANGUL LETTER NIEUN-SIOS + {0xA4D8, 0x3168}, //6347 #HANGUL LETTER NIEUN-PANSIOS + {0xA4D9, 0x3169}, //6348 #HANGUL LETTER RIEUL-KIYEOK-SIOS + {0xA4DA, 0x316A}, //6349 #HANGUL LETTER RIEUL-TIKEUT + {0xA4DB, 0x316B}, //6350 #HANGUL LETTER RIEUL-PIEUP-SIOS + {0xA4DC, 0x316C}, //6351 #HANGUL LETTER RIEUL-PANSIOS + {0xA4DD, 0x316D}, //6352 #HANGUL LETTER RIEUL-YEORINHIEUH + {0xA4DE, 0x316E}, //6353 #HANGUL LETTER MIEUM-PIEUP + {0xA4DF, 0x316F}, //6354 #HANGUL LETTER MIEUM-SIOS + {0xA4E0, 0x3170}, //6355 #HANGUL LETTER MIEUM-PANSIOS + {0xA4E1, 0x3171}, //6356 #HANGUL LETTER KAPYEOUNMIEUM + {0xA4E2, 0x3172}, //6357 #HANGUL LETTER PIEUP-KIYEOK + {0xA4E3, 0x3173}, //6358 #HANGUL LETTER PIEUP-TIKEUT + {0xA4E4, 0x3174}, //6359 #HANGUL LETTER PIEUP-SIOS-KIYEOK + {0xA4E5, 0x3175}, //6360 #HANGUL LETTER PIEUP-SIOS-TIKEUT + {0xA4E6, 0x3176}, //6361 #HANGUL LETTER PIEUP-CIEUC + {0xA4E7, 0x3177}, //6362 #HANGUL LETTER PIEUP-THIEUTH + {0xA4E8, 0x3178}, //6363 #HANGUL LETTER KAPYEOUNPIEUP + {0xA4E9, 0x3179}, //6364 #HANGUL LETTER KAPYEOUNSSANGPIEUP + {0xA4EA, 0x317A}, //6365 #HANGUL LETTER SIOS-KIYEOK + {0xA4EB, 0x317B}, //6366 #HANGUL LETTER SIOS-NIEUN + {0xA4EC, 0x317C}, //6367 #HANGUL LETTER SIOS-TIKEUT + {0xA4ED, 0x317D}, //6368 #HANGUL LETTER SIOS-PIEUP + {0xA4EE, 0x317E}, //6369 #HANGUL LETTER SIOS-CIEUC + {0xA4EF, 0x317F}, //6370 #HANGUL LETTER PANSIOS + {0xA4F0, 0x3180}, //6371 #HANGUL LETTER SSANGIEUNG + {0xA4F1, 0x3181}, //6372 #HANGUL LETTER YESIEUNG + {0xA4F2, 0x3182}, //6373 #HANGUL LETTER YESIEUNG-SIOS + {0xA4F3, 0x3183}, //6374 #HANGUL LETTER YESIEUNG-PANSIOS + {0xA4F4, 0x3184}, //6375 #HANGUL LETTER KAPYEOUNPHIEUPH + {0xA4F5, 0x3185}, //6376 #HANGUL LETTER SSANGHIEUH + {0xA4F6, 0x3186}, //6377 #HANGUL LETTER YEORINHIEUH + {0xA4F7, 0x3187}, //6378 #HANGUL LETTER YO-YA + {0xA4F8, 0x3188}, //6379 #HANGUL LETTER YO-YAE + {0xA4F9, 0x3189}, //6380 #HANGUL LETTER YO-I + {0xA4FA, 0x318A}, //6381 #HANGUL LETTER YU-YEO + {0xA4FB, 0x318B}, //6382 #HANGUL LETTER YU-YE + {0xA4FC, 0x318C}, //6383 #HANGUL LETTER YU-I + {0xA4FD, 0x318D}, //6384 #HANGUL LETTER ARAEA + {0xA4FE, 0x318E}, //6385 #HANGUL LETTER ARAEAE + {0xA541, 0xCA47}, //6386 #HANGUL SYLLABLE SSANGCIEUC YAE CHIEUCH + {0xA542, 0xCA48}, //6387 #HANGUL SYLLABLE SSANGCIEUC YAE KHIEUKH + {0xA543, 0xCA49}, //6388 #HANGUL SYLLABLE SSANGCIEUC YAE THIEUTH + {0xA544, 0xCA4A}, //6389 #HANGUL SYLLABLE SSANGCIEUC YAE PHIEUPH + {0xA545, 0xCA4B}, //6390 #HANGUL SYLLABLE SSANGCIEUC YAE HIEUH + {0xA546, 0xCA4E}, //6391 #HANGUL SYLLABLE SSANGCIEUC EO SSANGKIYEOK + {0xA547, 0xCA4F}, //6392 #HANGUL SYLLABLE SSANGCIEUC EO KIYEOKSIOS + {0xA548, 0xCA51}, //6393 #HANGUL SYLLABLE SSANGCIEUC EO NIEUNCIEUC + {0xA549, 0xCA52}, //6394 #HANGUL SYLLABLE SSANGCIEUC EO NIEUNHIEUH + {0xA54A, 0xCA53}, //6395 #HANGUL SYLLABLE SSANGCIEUC EO TIKEUT + {0xA54B, 0xCA55}, //6396 #HANGUL SYLLABLE SSANGCIEUC EO RIEULKIYEOK + {0xA54C, 0xCA56}, //6397 #HANGUL SYLLABLE SSANGCIEUC EO RIEULMIEUM + {0xA54D, 0xCA57}, //6398 #HANGUL SYLLABLE SSANGCIEUC EO RIEULPIEUP + {0xA54E, 0xCA58}, //6399 #HANGUL SYLLABLE SSANGCIEUC EO RIEULSIOS + {0xA54F, 0xCA59}, //6400 #HANGUL SYLLABLE SSANGCIEUC EO RIEULTHIEUTH + {0xA550, 0xCA5A}, //6401 #HANGUL SYLLABLE SSANGCIEUC EO RIEULPHIEUPH + {0xA551, 0xCA5B}, //6402 #HANGUL SYLLABLE SSANGCIEUC EO RIEULHIEUH + {0xA552, 0xCA5E}, //6403 #HANGUL SYLLABLE SSANGCIEUC EO PIEUPSIOS + {0xA553, 0xCA62}, //6404 #HANGUL SYLLABLE SSANGCIEUC EO CIEUC + {0xA554, 0xCA63}, //6405 #HANGUL SYLLABLE SSANGCIEUC EO CHIEUCH + {0xA555, 0xCA64}, //6406 #HANGUL SYLLABLE SSANGCIEUC EO KHIEUKH + {0xA556, 0xCA65}, //6407 #HANGUL SYLLABLE SSANGCIEUC EO THIEUTH + {0xA557, 0xCA66}, //6408 #HANGUL SYLLABLE SSANGCIEUC EO PHIEUPH + {0xA558, 0xCA67}, //6409 #HANGUL SYLLABLE SSANGCIEUC EO HIEUH + {0xA559, 0xCA69}, //6410 #HANGUL SYLLABLE SSANGCIEUC E KIYEOK + {0xA55A, 0xCA6A}, //6411 #HANGUL SYLLABLE SSANGCIEUC E SSANGKIYEOK + {0xA561, 0xCA6B}, //6412 #HANGUL SYLLABLE SSANGCIEUC E KIYEOKSIOS + {0xA562, 0xCA6C}, //6413 #HANGUL SYLLABLE SSANGCIEUC E NIEUN + {0xA563, 0xCA6D}, //6414 #HANGUL SYLLABLE SSANGCIEUC E NIEUNCIEUC + {0xA564, 0xCA6E}, //6415 #HANGUL SYLLABLE SSANGCIEUC E NIEUNHIEUH + {0xA565, 0xCA6F}, //6416 #HANGUL SYLLABLE SSANGCIEUC E TIKEUT + {0xA566, 0xCA70}, //6417 #HANGUL SYLLABLE SSANGCIEUC E RIEUL + {0xA567, 0xCA71}, //6418 #HANGUL SYLLABLE SSANGCIEUC E RIEULKIYEOK + {0xA568, 0xCA72}, //6419 #HANGUL SYLLABLE SSANGCIEUC E RIEULMIEUM + {0xA569, 0xCA73}, //6420 #HANGUL SYLLABLE SSANGCIEUC E RIEULPIEUP + {0xA56A, 0xCA74}, //6421 #HANGUL SYLLABLE SSANGCIEUC E RIEULSIOS + {0xA56B, 0xCA75}, //6422 #HANGUL SYLLABLE SSANGCIEUC E RIEULTHIEUTH + {0xA56C, 0xCA76}, //6423 #HANGUL SYLLABLE SSANGCIEUC E RIEULPHIEUPH + {0xA56D, 0xCA77}, //6424 #HANGUL SYLLABLE SSANGCIEUC E RIEULHIEUH + {0xA56E, 0xCA78}, //6425 #HANGUL SYLLABLE SSANGCIEUC E MIEUM + {0xA56F, 0xCA79}, //6426 #HANGUL SYLLABLE SSANGCIEUC E PIEUP + {0xA570, 0xCA7A}, //6427 #HANGUL SYLLABLE SSANGCIEUC E PIEUPSIOS + {0xA571, 0xCA7B}, //6428 #HANGUL SYLLABLE SSANGCIEUC E SIOS + {0xA572, 0xCA7C}, //6429 #HANGUL SYLLABLE SSANGCIEUC E SSANGSIOS + {0xA573, 0xCA7E}, //6430 #HANGUL SYLLABLE SSANGCIEUC E CIEUC + {0xA574, 0xCA7F}, //6431 #HANGUL SYLLABLE SSANGCIEUC E CHIEUCH + {0xA575, 0xCA80}, //6432 #HANGUL SYLLABLE SSANGCIEUC E KHIEUKH + {0xA576, 0xCA81}, //6433 #HANGUL SYLLABLE SSANGCIEUC E THIEUTH + {0xA577, 0xCA82}, //6434 #HANGUL SYLLABLE SSANGCIEUC E PHIEUPH + {0xA578, 0xCA83}, //6435 #HANGUL SYLLABLE SSANGCIEUC E HIEUH + {0xA579, 0xCA85}, //6436 #HANGUL SYLLABLE SSANGCIEUC YEO KIYEOK + {0xA57A, 0xCA86}, //6437 #HANGUL SYLLABLE SSANGCIEUC YEO SSANGKIYEOK + {0xA581, 0xCA87}, //6438 #HANGUL SYLLABLE SSANGCIEUC YEO KIYEOKSIOS + {0xA582, 0xCA88}, //6439 #HANGUL SYLLABLE SSANGCIEUC YEO NIEUN + {0xA583, 0xCA89}, //6440 #HANGUL SYLLABLE SSANGCIEUC YEO NIEUNCIEUC + {0xA584, 0xCA8A}, //6441 #HANGUL SYLLABLE SSANGCIEUC YEO NIEUNHIEUH + {0xA585, 0xCA8B}, //6442 #HANGUL SYLLABLE SSANGCIEUC YEO TIKEUT + {0xA586, 0xCA8C}, //6443 #HANGUL SYLLABLE SSANGCIEUC YEO RIEUL + {0xA587, 0xCA8D}, //6444 #HANGUL SYLLABLE SSANGCIEUC YEO RIEULKIYEOK + {0xA588, 0xCA8E}, //6445 #HANGUL SYLLABLE SSANGCIEUC YEO RIEULMIEUM + {0xA589, 0xCA8F}, //6446 #HANGUL SYLLABLE SSANGCIEUC YEO RIEULPIEUP + {0xA58A, 0xCA90}, //6447 #HANGUL SYLLABLE SSANGCIEUC YEO RIEULSIOS + {0xA58B, 0xCA91}, //6448 #HANGUL SYLLABLE SSANGCIEUC YEO RIEULTHIEUTH + {0xA58C, 0xCA92}, //6449 #HANGUL SYLLABLE SSANGCIEUC YEO RIEULPHIEUPH + {0xA58D, 0xCA93}, //6450 #HANGUL SYLLABLE SSANGCIEUC YEO RIEULHIEUH + {0xA58E, 0xCA94}, //6451 #HANGUL SYLLABLE SSANGCIEUC YEO MIEUM + {0xA58F, 0xCA95}, //6452 #HANGUL SYLLABLE SSANGCIEUC YEO PIEUP + {0xA590, 0xCA96}, //6453 #HANGUL SYLLABLE SSANGCIEUC YEO PIEUPSIOS + {0xA591, 0xCA97}, //6454 #HANGUL SYLLABLE SSANGCIEUC YEO SIOS + {0xA592, 0xCA99}, //6455 #HANGUL SYLLABLE SSANGCIEUC YEO IEUNG + {0xA593, 0xCA9A}, //6456 #HANGUL SYLLABLE SSANGCIEUC YEO CIEUC + {0xA594, 0xCA9B}, //6457 #HANGUL SYLLABLE SSANGCIEUC YEO CHIEUCH + {0xA595, 0xCA9C}, //6458 #HANGUL SYLLABLE SSANGCIEUC YEO KHIEUKH + {0xA596, 0xCA9D}, //6459 #HANGUL SYLLABLE SSANGCIEUC YEO THIEUTH + {0xA597, 0xCA9E}, //6460 #HANGUL SYLLABLE SSANGCIEUC YEO PHIEUPH + {0xA598, 0xCA9F}, //6461 #HANGUL SYLLABLE SSANGCIEUC YEO HIEUH + {0xA599, 0xCAA0}, //6462 #HANGUL SYLLABLE SSANGCIEUC YE + {0xA59A, 0xCAA1}, //6463 #HANGUL SYLLABLE SSANGCIEUC YE KIYEOK + {0xA59B, 0xCAA2}, //6464 #HANGUL SYLLABLE SSANGCIEUC YE SSANGKIYEOK + {0xA59C, 0xCAA3}, //6465 #HANGUL SYLLABLE SSANGCIEUC YE KIYEOKSIOS + {0xA59D, 0xCAA4}, //6466 #HANGUL SYLLABLE SSANGCIEUC YE NIEUN + {0xA59E, 0xCAA5}, //6467 #HANGUL SYLLABLE SSANGCIEUC YE NIEUNCIEUC + {0xA59F, 0xCAA6}, //6468 #HANGUL SYLLABLE SSANGCIEUC YE NIEUNHIEUH + {0xA5A0, 0xCAA7}, //6469 #HANGUL SYLLABLE SSANGCIEUC YE TIKEUT + {0xA5A1, 0x2170}, //6470 #SMALL ROMAN NUMERAL ONE + {0xA5A2, 0x2171}, //6471 #SMALL ROMAN NUMERAL TWO + {0xA5A3, 0x2172}, //6472 #SMALL ROMAN NUMERAL THREE + {0xA5A4, 0x2173}, //6473 #SMALL ROMAN NUMERAL FOUR + {0xA5A5, 0x2174}, //6474 #SMALL ROMAN NUMERAL FIVE + {0xA5A6, 0x2175}, //6475 #SMALL ROMAN NUMERAL SIX + {0xA5A7, 0x2176}, //6476 #SMALL ROMAN NUMERAL SEVEN + {0xA5A8, 0x2177}, //6477 #SMALL ROMAN NUMERAL EIGHT + {0xA5A9, 0x2178}, //6478 #SMALL ROMAN NUMERAL NINE + {0xA5AA, 0x2179}, //6479 #SMALL ROMAN NUMERAL TEN + {0xA5B0, 0x2160}, //6480 #ROMAN NUMERAL ONE + {0xA5B1, 0x2161}, //6481 #ROMAN NUMERAL TWO + {0xA5B2, 0x2162}, //6482 #ROMAN NUMERAL THREE + {0xA5B3, 0x2163}, //6483 #ROMAN NUMERAL FOUR + {0xA5B4, 0x2164}, //6484 #ROMAN NUMERAL FIVE + {0xA5B5, 0x2165}, //6485 #ROMAN NUMERAL SIX + {0xA5B6, 0x2166}, //6486 #ROMAN NUMERAL SEVEN + {0xA5B7, 0x2167}, //6487 #ROMAN NUMERAL EIGHT + {0xA5B8, 0x2168}, //6488 #ROMAN NUMERAL NINE + {0xA5B9, 0x2169}, //6489 #ROMAN NUMERAL TEN + {0xA5C1, 0x0391}, //6490 #GREEK CAPITAL LETTER ALPHA + {0xA5C2, 0x0392}, //6491 #GREEK CAPITAL LETTER BETA + {0xA5C3, 0x0393}, //6492 #GREEK CAPITAL LETTER GAMMA + {0xA5C4, 0x0394}, //6493 #GREEK CAPITAL LETTER DELTA + {0xA5C5, 0x0395}, //6494 #GREEK CAPITAL LETTER EPSILON + {0xA5C6, 0x0396}, //6495 #GREEK CAPITAL LETTER ZETA + {0xA5C7, 0x0397}, //6496 #GREEK CAPITAL LETTER ETA + {0xA5C8, 0x0398}, //6497 #GREEK CAPITAL LETTER THETA + {0xA5C9, 0x0399}, //6498 #GREEK CAPITAL LETTER IOTA + {0xA5CA, 0x039A}, //6499 #GREEK CAPITAL LETTER KAPPA + {0xA5CB, 0x039B}, //6500 #GREEK CAPITAL LETTER LAMDA + {0xA5CC, 0x039C}, //6501 #GREEK CAPITAL LETTER MU + {0xA5CD, 0x039D}, //6502 #GREEK CAPITAL LETTER NU + {0xA5CE, 0x039E}, //6503 #GREEK CAPITAL LETTER XI + {0xA5CF, 0x039F}, //6504 #GREEK CAPITAL LETTER OMICRON + {0xA5D0, 0x03A0}, //6505 #GREEK CAPITAL LETTER PI + {0xA5D1, 0x03A1}, //6506 #GREEK CAPITAL LETTER RHO + {0xA5D2, 0x03A3}, //6507 #GREEK CAPITAL LETTER SIGMA + {0xA5D3, 0x03A4}, //6508 #GREEK CAPITAL LETTER TAU + {0xA5D4, 0x03A5}, //6509 #GREEK CAPITAL LETTER UPSILON + {0xA5D5, 0x03A6}, //6510 #GREEK CAPITAL LETTER PHI + {0xA5D6, 0x03A7}, //6511 #GREEK CAPITAL LETTER CHI + {0xA5D7, 0x03A8}, //6512 #GREEK CAPITAL LETTER PSI + {0xA5D8, 0x03A9}, //6513 #GREEK CAPITAL LETTER OMEGA + {0xA5E1, 0x03B1}, //6514 #GREEK SMALL LETTER ALPHA + {0xA5E2, 0x03B2}, //6515 #GREEK SMALL LETTER BETA + {0xA5E3, 0x03B3}, //6516 #GREEK SMALL LETTER GAMMA + {0xA5E4, 0x03B4}, //6517 #GREEK SMALL LETTER DELTA + {0xA5E5, 0x03B5}, //6518 #GREEK SMALL LETTER EPSILON + {0xA5E6, 0x03B6}, //6519 #GREEK SMALL LETTER ZETA + {0xA5E7, 0x03B7}, //6520 #GREEK SMALL LETTER ETA + {0xA5E8, 0x03B8}, //6521 #GREEK SMALL LETTER THETA + {0xA5E9, 0x03B9}, //6522 #GREEK SMALL LETTER IOTA + {0xA5EA, 0x03BA}, //6523 #GREEK SMALL LETTER KAPPA + {0xA5EB, 0x03BB}, //6524 #GREEK SMALL LETTER LAMDA + {0xA5EC, 0x03BC}, //6525 #GREEK SMALL LETTER MU + {0xA5ED, 0x03BD}, //6526 #GREEK SMALL LETTER NU + {0xA5EE, 0x03BE}, //6527 #GREEK SMALL LETTER XI + {0xA5EF, 0x03BF}, //6528 #GREEK SMALL LETTER OMICRON + {0xA5F0, 0x03C0}, //6529 #GREEK SMALL LETTER PI + {0xA5F1, 0x03C1}, //6530 #GREEK SMALL LETTER RHO + {0xA5F2, 0x03C3}, //6531 #GREEK SMALL LETTER SIGMA + {0xA5F3, 0x03C4}, //6532 #GREEK SMALL LETTER TAU + {0xA5F4, 0x03C5}, //6533 #GREEK SMALL LETTER UPSILON + {0xA5F5, 0x03C6}, //6534 #GREEK SMALL LETTER PHI + {0xA5F6, 0x03C7}, //6535 #GREEK SMALL LETTER CHI + {0xA5F7, 0x03C8}, //6536 #GREEK SMALL LETTER PSI + {0xA5F8, 0x03C9}, //6537 #GREEK SMALL LETTER OMEGA + {0xA641, 0xCAA8}, //6538 #HANGUL SYLLABLE SSANGCIEUC YE RIEUL + {0xA642, 0xCAA9}, //6539 #HANGUL SYLLABLE SSANGCIEUC YE RIEULKIYEOK + {0xA643, 0xCAAA}, //6540 #HANGUL SYLLABLE SSANGCIEUC YE RIEULMIEUM + {0xA644, 0xCAAB}, //6541 #HANGUL SYLLABLE SSANGCIEUC YE RIEULPIEUP + {0xA645, 0xCAAC}, //6542 #HANGUL SYLLABLE SSANGCIEUC YE RIEULSIOS + {0xA646, 0xCAAD}, //6543 #HANGUL SYLLABLE SSANGCIEUC YE RIEULTHIEUTH + {0xA647, 0xCAAE}, //6544 #HANGUL SYLLABLE SSANGCIEUC YE RIEULPHIEUPH + {0xA648, 0xCAAF}, //6545 #HANGUL SYLLABLE SSANGCIEUC YE RIEULHIEUH + {0xA649, 0xCAB0}, //6546 #HANGUL SYLLABLE SSANGCIEUC YE MIEUM + {0xA64A, 0xCAB1}, //6547 #HANGUL SYLLABLE SSANGCIEUC YE PIEUP + {0xA64B, 0xCAB2}, //6548 #HANGUL SYLLABLE SSANGCIEUC YE PIEUPSIOS + {0xA64C, 0xCAB3}, //6549 #HANGUL SYLLABLE SSANGCIEUC YE SIOS + {0xA64D, 0xCAB4}, //6550 #HANGUL SYLLABLE SSANGCIEUC YE SSANGSIOS + {0xA64E, 0xCAB5}, //6551 #HANGUL SYLLABLE SSANGCIEUC YE IEUNG + {0xA64F, 0xCAB6}, //6552 #HANGUL SYLLABLE SSANGCIEUC YE CIEUC + {0xA650, 0xCAB7}, //6553 #HANGUL SYLLABLE SSANGCIEUC YE CHIEUCH + {0xA651, 0xCAB8}, //6554 #HANGUL SYLLABLE SSANGCIEUC YE KHIEUKH + {0xA652, 0xCAB9}, //6555 #HANGUL SYLLABLE SSANGCIEUC YE THIEUTH + {0xA653, 0xCABA}, //6556 #HANGUL SYLLABLE SSANGCIEUC YE PHIEUPH + {0xA654, 0xCABB}, //6557 #HANGUL SYLLABLE SSANGCIEUC YE HIEUH + {0xA655, 0xCABE}, //6558 #HANGUL SYLLABLE SSANGCIEUC O SSANGKIYEOK + {0xA656, 0xCABF}, //6559 #HANGUL SYLLABLE SSANGCIEUC O KIYEOKSIOS + {0xA657, 0xCAC1}, //6560 #HANGUL SYLLABLE SSANGCIEUC O NIEUNCIEUC + {0xA658, 0xCAC2}, //6561 #HANGUL SYLLABLE SSANGCIEUC O NIEUNHIEUH + {0xA659, 0xCAC3}, //6562 #HANGUL SYLLABLE SSANGCIEUC O TIKEUT + {0xA65A, 0xCAC5}, //6563 #HANGUL SYLLABLE SSANGCIEUC O RIEULKIYEOK + {0xA661, 0xCAC6}, //6564 #HANGUL SYLLABLE SSANGCIEUC O RIEULMIEUM + {0xA662, 0xCAC7}, //6565 #HANGUL SYLLABLE SSANGCIEUC O RIEULPIEUP + {0xA663, 0xCAC8}, //6566 #HANGUL SYLLABLE SSANGCIEUC O RIEULSIOS + {0xA664, 0xCAC9}, //6567 #HANGUL SYLLABLE SSANGCIEUC O RIEULTHIEUTH + {0xA665, 0xCACA}, //6568 #HANGUL SYLLABLE SSANGCIEUC O RIEULPHIEUPH + {0xA666, 0xCACB}, //6569 #HANGUL SYLLABLE SSANGCIEUC O RIEULHIEUH + {0xA667, 0xCACE}, //6570 #HANGUL SYLLABLE SSANGCIEUC O PIEUPSIOS + {0xA668, 0xCAD0}, //6571 #HANGUL SYLLABLE SSANGCIEUC O SSANGSIOS + {0xA669, 0xCAD2}, //6572 #HANGUL SYLLABLE SSANGCIEUC O CIEUC + {0xA66A, 0xCAD4}, //6573 #HANGUL SYLLABLE SSANGCIEUC O KHIEUKH + {0xA66B, 0xCAD5}, //6574 #HANGUL SYLLABLE SSANGCIEUC O THIEUTH + {0xA66C, 0xCAD6}, //6575 #HANGUL SYLLABLE SSANGCIEUC O PHIEUPH + {0xA66D, 0xCAD7}, //6576 #HANGUL SYLLABLE SSANGCIEUC O HIEUH + {0xA66E, 0xCADA}, //6577 #HANGUL SYLLABLE SSANGCIEUC WA SSANGKIYEOK + {0xA66F, 0xCADB}, //6578 #HANGUL SYLLABLE SSANGCIEUC WA KIYEOKSIOS + {0xA670, 0xCADC}, //6579 #HANGUL SYLLABLE SSANGCIEUC WA NIEUN + {0xA671, 0xCADD}, //6580 #HANGUL SYLLABLE SSANGCIEUC WA NIEUNCIEUC + {0xA672, 0xCADE}, //6581 #HANGUL SYLLABLE SSANGCIEUC WA NIEUNHIEUH + {0xA673, 0xCADF}, //6582 #HANGUL SYLLABLE SSANGCIEUC WA TIKEUT + {0xA674, 0xCAE1}, //6583 #HANGUL SYLLABLE SSANGCIEUC WA RIEULKIYEOK + {0xA675, 0xCAE2}, //6584 #HANGUL SYLLABLE SSANGCIEUC WA RIEULMIEUM + {0xA676, 0xCAE3}, //6585 #HANGUL SYLLABLE SSANGCIEUC WA RIEULPIEUP + {0xA677, 0xCAE4}, //6586 #HANGUL SYLLABLE SSANGCIEUC WA RIEULSIOS + {0xA678, 0xCAE5}, //6587 #HANGUL SYLLABLE SSANGCIEUC WA RIEULTHIEUTH + {0xA679, 0xCAE6}, //6588 #HANGUL SYLLABLE SSANGCIEUC WA RIEULPHIEUPH + {0xA67A, 0xCAE7}, //6589 #HANGUL SYLLABLE SSANGCIEUC WA RIEULHIEUH + {0xA681, 0xCAE8}, //6590 #HANGUL SYLLABLE SSANGCIEUC WA MIEUM + {0xA682, 0xCAE9}, //6591 #HANGUL SYLLABLE SSANGCIEUC WA PIEUP + {0xA683, 0xCAEA}, //6592 #HANGUL SYLLABLE SSANGCIEUC WA PIEUPSIOS + {0xA684, 0xCAEB}, //6593 #HANGUL SYLLABLE SSANGCIEUC WA SIOS + {0xA685, 0xCAED}, //6594 #HANGUL SYLLABLE SSANGCIEUC WA IEUNG + {0xA686, 0xCAEE}, //6595 #HANGUL SYLLABLE SSANGCIEUC WA CIEUC + {0xA687, 0xCAEF}, //6596 #HANGUL SYLLABLE SSANGCIEUC WA CHIEUCH + {0xA688, 0xCAF0}, //6597 #HANGUL SYLLABLE SSANGCIEUC WA KHIEUKH + {0xA689, 0xCAF1}, //6598 #HANGUL SYLLABLE SSANGCIEUC WA THIEUTH + {0xA68A, 0xCAF2}, //6599 #HANGUL SYLLABLE SSANGCIEUC WA PHIEUPH + {0xA68B, 0xCAF3}, //6600 #HANGUL SYLLABLE SSANGCIEUC WA HIEUH + {0xA68C, 0xCAF5}, //6601 #HANGUL SYLLABLE SSANGCIEUC WAE KIYEOK + {0xA68D, 0xCAF6}, //6602 #HANGUL SYLLABLE SSANGCIEUC WAE SSANGKIYEOK + {0xA68E, 0xCAF7}, //6603 #HANGUL SYLLABLE SSANGCIEUC WAE KIYEOKSIOS + {0xA68F, 0xCAF8}, //6604 #HANGUL SYLLABLE SSANGCIEUC WAE NIEUN + {0xA690, 0xCAF9}, //6605 #HANGUL SYLLABLE SSANGCIEUC WAE NIEUNCIEUC + {0xA691, 0xCAFA}, //6606 #HANGUL SYLLABLE SSANGCIEUC WAE NIEUNHIEUH + {0xA692, 0xCAFB}, //6607 #HANGUL SYLLABLE SSANGCIEUC WAE TIKEUT + {0xA693, 0xCAFC}, //6608 #HANGUL SYLLABLE SSANGCIEUC WAE RIEUL + {0xA694, 0xCAFD}, //6609 #HANGUL SYLLABLE SSANGCIEUC WAE RIEULKIYEOK + {0xA695, 0xCAFE}, //6610 #HANGUL SYLLABLE SSANGCIEUC WAE RIEULMIEUM + {0xA696, 0xCAFF}, //6611 #HANGUL SYLLABLE SSANGCIEUC WAE RIEULPIEUP + {0xA697, 0xCB00}, //6612 #HANGUL SYLLABLE SSANGCIEUC WAE RIEULSIOS + {0xA698, 0xCB01}, //6613 #HANGUL SYLLABLE SSANGCIEUC WAE RIEULTHIEUTH + {0xA699, 0xCB02}, //6614 #HANGUL SYLLABLE SSANGCIEUC WAE RIEULPHIEUPH + {0xA69A, 0xCB03}, //6615 #HANGUL SYLLABLE SSANGCIEUC WAE RIEULHIEUH + {0xA69B, 0xCB04}, //6616 #HANGUL SYLLABLE SSANGCIEUC WAE MIEUM + {0xA69C, 0xCB05}, //6617 #HANGUL SYLLABLE SSANGCIEUC WAE PIEUP + {0xA69D, 0xCB06}, //6618 #HANGUL SYLLABLE SSANGCIEUC WAE PIEUPSIOS + {0xA69E, 0xCB07}, //6619 #HANGUL SYLLABLE SSANGCIEUC WAE SIOS + {0xA69F, 0xCB09}, //6620 #HANGUL SYLLABLE SSANGCIEUC WAE IEUNG + {0xA6A0, 0xCB0A}, //6621 #HANGUL SYLLABLE SSANGCIEUC WAE CIEUC + {0xA6A1, 0x2500}, //6622 #BOX DRAWINGS LIGHT HORIZONTAL + {0xA6A2, 0x2502}, //6623 #BOX DRAWINGS LIGHT VERTICAL + {0xA6A3, 0x250C}, //6624 #BOX DRAWINGS LIGHT DOWN AND RIGHT + {0xA6A4, 0x2510}, //6625 #BOX DRAWINGS LIGHT DOWN AND LEFT + {0xA6A5, 0x2518}, //6626 #BOX DRAWINGS LIGHT UP AND LEFT + {0xA6A6, 0x2514}, //6627 #BOX DRAWINGS LIGHT UP AND RIGHT + {0xA6A7, 0x251C}, //6628 #BOX DRAWINGS LIGHT VERTICAL AND RIGHT + {0xA6A8, 0x252C}, //6629 #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + {0xA6A9, 0x2524}, //6630 #BOX DRAWINGS LIGHT VERTICAL AND LEFT + {0xA6AA, 0x2534}, //6631 #BOX DRAWINGS LIGHT UP AND HORIZONTAL + {0xA6AB, 0x253C}, //6632 #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + {0xA6AC, 0x2501}, //6633 #BOX DRAWINGS HEAVY HORIZONTAL + {0xA6AD, 0x2503}, //6634 #BOX DRAWINGS HEAVY VERTICAL + {0xA6AE, 0x250F}, //6635 #BOX DRAWINGS HEAVY DOWN AND RIGHT + {0xA6AF, 0x2513}, //6636 #BOX DRAWINGS HEAVY DOWN AND LEFT + {0xA6B0, 0x251B}, //6637 #BOX DRAWINGS HEAVY UP AND LEFT + {0xA6B1, 0x2517}, //6638 #BOX DRAWINGS HEAVY UP AND RIGHT + {0xA6B2, 0x2523}, //6639 #BOX DRAWINGS HEAVY VERTICAL AND RIGHT + {0xA6B3, 0x2533}, //6640 #BOX DRAWINGS HEAVY DOWN AND HORIZONTAL + {0xA6B4, 0x252B}, //6641 #BOX DRAWINGS HEAVY VERTICAL AND LEFT + {0xA6B5, 0x253B}, //6642 #BOX DRAWINGS HEAVY UP AND HORIZONTAL + {0xA6B6, 0x254B}, //6643 #BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL + {0xA6B7, 0x2520}, //6644 #BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT + {0xA6B8, 0x252F}, //6645 #BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY + {0xA6B9, 0x2528}, //6646 #BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT + {0xA6BA, 0x2537}, //6647 #BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY + {0xA6BB, 0x253F}, //6648 #BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY + {0xA6BC, 0x251D}, //6649 #BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY + {0xA6BD, 0x2530}, //6650 #BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT + {0xA6BE, 0x2525}, //6651 #BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY + {0xA6BF, 0x2538}, //6652 #BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT + {0xA6C0, 0x2542}, //6653 #BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT + {0xA6C1, 0x2512}, //6654 #BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT + {0xA6C2, 0x2511}, //6655 #BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY + {0xA6C3, 0x251A}, //6656 #BOX DRAWINGS UP HEAVY AND LEFT LIGHT + {0xA6C4, 0x2519}, //6657 #BOX DRAWINGS UP LIGHT AND LEFT HEAVY + {0xA6C5, 0x2516}, //6658 #BOX DRAWINGS UP HEAVY AND RIGHT LIGHT + {0xA6C6, 0x2515}, //6659 #BOX DRAWINGS UP LIGHT AND RIGHT HEAVY + {0xA6C7, 0x250E}, //6660 #BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT + {0xA6C8, 0x250D}, //6661 #BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY + {0xA6C9, 0x251E}, //6662 #BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT + {0xA6CA, 0x251F}, //6663 #BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT + {0xA6CB, 0x2521}, //6664 #BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY + {0xA6CC, 0x2522}, //6665 #BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY + {0xA6CD, 0x2526}, //6666 #BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT + {0xA6CE, 0x2527}, //6667 #BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT + {0xA6CF, 0x2529}, //6668 #BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY + {0xA6D0, 0x252A}, //6669 #BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY + {0xA6D1, 0x252D}, //6670 #BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT + {0xA6D2, 0x252E}, //6671 #BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT + {0xA6D3, 0x2531}, //6672 #BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY + {0xA6D4, 0x2532}, //6673 #BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY + {0xA6D5, 0x2535}, //6674 #BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT + {0xA6D6, 0x2536}, //6675 #BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT + {0xA6D7, 0x2539}, //6676 #BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY + {0xA6D8, 0x253A}, //6677 #BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY + {0xA6D9, 0x253D}, //6678 #BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT + {0xA6DA, 0x253E}, //6679 #BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT + {0xA6DB, 0x2540}, //6680 #BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT + {0xA6DC, 0x2541}, //6681 #BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT + {0xA6DD, 0x2543}, //6682 #BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT + {0xA6DE, 0x2544}, //6683 #BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT + {0xA6DF, 0x2545}, //6684 #BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT + {0xA6E0, 0x2546}, //6685 #BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT + {0xA6E1, 0x2547}, //6686 #BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY + {0xA6E2, 0x2548}, //6687 #BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY + {0xA6E3, 0x2549}, //6688 #BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY + {0xA6E4, 0x254A}, //6689 #BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY + {0xA741, 0xCB0B}, //6690 #HANGUL SYLLABLE SSANGCIEUC WAE CHIEUCH + {0xA742, 0xCB0C}, //6691 #HANGUL SYLLABLE SSANGCIEUC WAE KHIEUKH + {0xA743, 0xCB0D}, //6692 #HANGUL SYLLABLE SSANGCIEUC WAE THIEUTH + {0xA744, 0xCB0E}, //6693 #HANGUL SYLLABLE SSANGCIEUC WAE PHIEUPH + {0xA745, 0xCB0F}, //6694 #HANGUL SYLLABLE SSANGCIEUC WAE HIEUH + {0xA746, 0xCB11}, //6695 #HANGUL SYLLABLE SSANGCIEUC OE KIYEOK + {0xA747, 0xCB12}, //6696 #HANGUL SYLLABLE SSANGCIEUC OE SSANGKIYEOK + {0xA748, 0xCB13}, //6697 #HANGUL SYLLABLE SSANGCIEUC OE KIYEOKSIOS + {0xA749, 0xCB15}, //6698 #HANGUL SYLLABLE SSANGCIEUC OE NIEUNCIEUC + {0xA74A, 0xCB16}, //6699 #HANGUL SYLLABLE SSANGCIEUC OE NIEUNHIEUH + {0xA74B, 0xCB17}, //6700 #HANGUL SYLLABLE SSANGCIEUC OE TIKEUT + {0xA74C, 0xCB19}, //6701 #HANGUL SYLLABLE SSANGCIEUC OE RIEULKIYEOK + {0xA74D, 0xCB1A}, //6702 #HANGUL SYLLABLE SSANGCIEUC OE RIEULMIEUM + {0xA74E, 0xCB1B}, //6703 #HANGUL SYLLABLE SSANGCIEUC OE RIEULPIEUP + {0xA74F, 0xCB1C}, //6704 #HANGUL SYLLABLE SSANGCIEUC OE RIEULSIOS + {0xA750, 0xCB1D}, //6705 #HANGUL SYLLABLE SSANGCIEUC OE RIEULTHIEUTH + {0xA751, 0xCB1E}, //6706 #HANGUL SYLLABLE SSANGCIEUC OE RIEULPHIEUPH + {0xA752, 0xCB1F}, //6707 #HANGUL SYLLABLE SSANGCIEUC OE RIEULHIEUH + {0xA753, 0xCB22}, //6708 #HANGUL SYLLABLE SSANGCIEUC OE PIEUPSIOS + {0xA754, 0xCB23}, //6709 #HANGUL SYLLABLE SSANGCIEUC OE SIOS + {0xA755, 0xCB24}, //6710 #HANGUL SYLLABLE SSANGCIEUC OE SSANGSIOS + {0xA756, 0xCB25}, //6711 #HANGUL SYLLABLE SSANGCIEUC OE IEUNG + {0xA757, 0xCB26}, //6712 #HANGUL SYLLABLE SSANGCIEUC OE CIEUC + {0xA758, 0xCB27}, //6713 #HANGUL SYLLABLE SSANGCIEUC OE CHIEUCH + {0xA759, 0xCB28}, //6714 #HANGUL SYLLABLE SSANGCIEUC OE KHIEUKH + {0xA75A, 0xCB29}, //6715 #HANGUL SYLLABLE SSANGCIEUC OE THIEUTH + {0xA761, 0xCB2A}, //6716 #HANGUL SYLLABLE SSANGCIEUC OE PHIEUPH + {0xA762, 0xCB2B}, //6717 #HANGUL SYLLABLE SSANGCIEUC OE HIEUH + {0xA763, 0xCB2C}, //6718 #HANGUL SYLLABLE SSANGCIEUC YO + {0xA764, 0xCB2D}, //6719 #HANGUL SYLLABLE SSANGCIEUC YO KIYEOK + {0xA765, 0xCB2E}, //6720 #HANGUL SYLLABLE SSANGCIEUC YO SSANGKIYEOK + {0xA766, 0xCB2F}, //6721 #HANGUL SYLLABLE SSANGCIEUC YO KIYEOKSIOS + {0xA767, 0xCB30}, //6722 #HANGUL SYLLABLE SSANGCIEUC YO NIEUN + {0xA768, 0xCB31}, //6723 #HANGUL SYLLABLE SSANGCIEUC YO NIEUNCIEUC + {0xA769, 0xCB32}, //6724 #HANGUL SYLLABLE SSANGCIEUC YO NIEUNHIEUH + {0xA76A, 0xCB33}, //6725 #HANGUL SYLLABLE SSANGCIEUC YO TIKEUT + {0xA76B, 0xCB34}, //6726 #HANGUL SYLLABLE SSANGCIEUC YO RIEUL + {0xA76C, 0xCB35}, //6727 #HANGUL SYLLABLE SSANGCIEUC YO RIEULKIYEOK + {0xA76D, 0xCB36}, //6728 #HANGUL SYLLABLE SSANGCIEUC YO RIEULMIEUM + {0xA76E, 0xCB37}, //6729 #HANGUL SYLLABLE SSANGCIEUC YO RIEULPIEUP + {0xA76F, 0xCB38}, //6730 #HANGUL SYLLABLE SSANGCIEUC YO RIEULSIOS + {0xA770, 0xCB39}, //6731 #HANGUL SYLLABLE SSANGCIEUC YO RIEULTHIEUTH + {0xA771, 0xCB3A}, //6732 #HANGUL SYLLABLE SSANGCIEUC YO RIEULPHIEUPH + {0xA772, 0xCB3B}, //6733 #HANGUL SYLLABLE SSANGCIEUC YO RIEULHIEUH + {0xA773, 0xCB3C}, //6734 #HANGUL SYLLABLE SSANGCIEUC YO MIEUM + {0xA774, 0xCB3D}, //6735 #HANGUL SYLLABLE SSANGCIEUC YO PIEUP + {0xA775, 0xCB3E}, //6736 #HANGUL SYLLABLE SSANGCIEUC YO PIEUPSIOS + {0xA776, 0xCB3F}, //6737 #HANGUL SYLLABLE SSANGCIEUC YO SIOS + {0xA777, 0xCB40}, //6738 #HANGUL SYLLABLE SSANGCIEUC YO SSANGSIOS + {0xA778, 0xCB42}, //6739 #HANGUL SYLLABLE SSANGCIEUC YO CIEUC + {0xA779, 0xCB43}, //6740 #HANGUL SYLLABLE SSANGCIEUC YO CHIEUCH + {0xA77A, 0xCB44}, //6741 #HANGUL SYLLABLE SSANGCIEUC YO KHIEUKH + {0xA781, 0xCB45}, //6742 #HANGUL SYLLABLE SSANGCIEUC YO THIEUTH + {0xA782, 0xCB46}, //6743 #HANGUL SYLLABLE SSANGCIEUC YO PHIEUPH + {0xA783, 0xCB47}, //6744 #HANGUL SYLLABLE SSANGCIEUC YO HIEUH + {0xA784, 0xCB4A}, //6745 #HANGUL SYLLABLE SSANGCIEUC U SSANGKIYEOK + {0xA785, 0xCB4B}, //6746 #HANGUL SYLLABLE SSANGCIEUC U KIYEOKSIOS + {0xA786, 0xCB4D}, //6747 #HANGUL SYLLABLE SSANGCIEUC U NIEUNCIEUC + {0xA787, 0xCB4E}, //6748 #HANGUL SYLLABLE SSANGCIEUC U NIEUNHIEUH + {0xA788, 0xCB4F}, //6749 #HANGUL SYLLABLE SSANGCIEUC U TIKEUT + {0xA789, 0xCB51}, //6750 #HANGUL SYLLABLE SSANGCIEUC U RIEULKIYEOK + {0xA78A, 0xCB52}, //6751 #HANGUL SYLLABLE SSANGCIEUC U RIEULMIEUM + {0xA78B, 0xCB53}, //6752 #HANGUL SYLLABLE SSANGCIEUC U RIEULPIEUP + {0xA78C, 0xCB54}, //6753 #HANGUL SYLLABLE SSANGCIEUC U RIEULSIOS + {0xA78D, 0xCB55}, //6754 #HANGUL SYLLABLE SSANGCIEUC U RIEULTHIEUTH + {0xA78E, 0xCB56}, //6755 #HANGUL SYLLABLE SSANGCIEUC U RIEULPHIEUPH + {0xA78F, 0xCB57}, //6756 #HANGUL SYLLABLE SSANGCIEUC U RIEULHIEUH + {0xA790, 0xCB5A}, //6757 #HANGUL SYLLABLE SSANGCIEUC U PIEUPSIOS + {0xA791, 0xCB5B}, //6758 #HANGUL SYLLABLE SSANGCIEUC U SIOS + {0xA792, 0xCB5C}, //6759 #HANGUL SYLLABLE SSANGCIEUC U SSANGSIOS + {0xA793, 0xCB5E}, //6760 #HANGUL SYLLABLE SSANGCIEUC U CIEUC + {0xA794, 0xCB5F}, //6761 #HANGUL SYLLABLE SSANGCIEUC U CHIEUCH + {0xA795, 0xCB60}, //6762 #HANGUL SYLLABLE SSANGCIEUC U KHIEUKH + {0xA796, 0xCB61}, //6763 #HANGUL SYLLABLE SSANGCIEUC U THIEUTH + {0xA797, 0xCB62}, //6764 #HANGUL SYLLABLE SSANGCIEUC U PHIEUPH + {0xA798, 0xCB63}, //6765 #HANGUL SYLLABLE SSANGCIEUC U HIEUH + {0xA799, 0xCB65}, //6766 #HANGUL SYLLABLE SSANGCIEUC WEO KIYEOK + {0xA79A, 0xCB66}, //6767 #HANGUL SYLLABLE SSANGCIEUC WEO SSANGKIYEOK + {0xA79B, 0xCB67}, //6768 #HANGUL SYLLABLE SSANGCIEUC WEO KIYEOKSIOS + {0xA79C, 0xCB68}, //6769 #HANGUL SYLLABLE SSANGCIEUC WEO NIEUN + {0xA79D, 0xCB69}, //6770 #HANGUL SYLLABLE SSANGCIEUC WEO NIEUNCIEUC + {0xA79E, 0xCB6A}, //6771 #HANGUL SYLLABLE SSANGCIEUC WEO NIEUNHIEUH + {0xA79F, 0xCB6B}, //6772 #HANGUL SYLLABLE SSANGCIEUC WEO TIKEUT + {0xA7A0, 0xCB6C}, //6773 #HANGUL SYLLABLE SSANGCIEUC WEO RIEUL + {0xA7A1, 0x3395}, //6774 #SQUARE MU L + {0xA7A2, 0x3396}, //6775 #SQUARE ML + {0xA7A3, 0x3397}, //6776 #SQUARE DL + {0xA7A4, 0x2113}, //6777 #SCRIPT SMALL L + {0xA7A5, 0x3398}, //6778 #SQUARE KL + {0xA7A6, 0x33C4}, //6779 #SQUARE CC + {0xA7A7, 0x33A3}, //6780 #SQUARE MM CUBED + {0xA7A8, 0x33A4}, //6781 #SQUARE CM CUBED + {0xA7A9, 0x33A5}, //6782 #SQUARE M CUBED + {0xA7AA, 0x33A6}, //6783 #SQUARE KM CUBED + {0xA7AB, 0x3399}, //6784 #SQUARE FM + {0xA7AC, 0x339A}, //6785 #SQUARE NM + {0xA7AD, 0x339B}, //6786 #SQUARE MU M + {0xA7AE, 0x339C}, //6787 #SQUARE MM + {0xA7AF, 0x339D}, //6788 #SQUARE CM + {0xA7B0, 0x339E}, //6789 #SQUARE KM + {0xA7B1, 0x339F}, //6790 #SQUARE MM SQUARED + {0xA7B2, 0x33A0}, //6791 #SQUARE CM SQUARED + {0xA7B3, 0x33A1}, //6792 #SQUARE M SQUARED + {0xA7B4, 0x33A2}, //6793 #SQUARE KM SQUARED + {0xA7B5, 0x33CA}, //6794 #SQUARE HA + {0xA7B6, 0x338D}, //6795 #SQUARE MU G + {0xA7B7, 0x338E}, //6796 #SQUARE MG + {0xA7B8, 0x338F}, //6797 #SQUARE KG + {0xA7B9, 0x33CF}, //6798 #SQUARE KT + {0xA7BA, 0x3388}, //6799 #SQUARE CAL + {0xA7BB, 0x3389}, //6800 #SQUARE KCAL + {0xA7BC, 0x33C8}, //6801 #SQUARE DB + {0xA7BD, 0x33A7}, //6802 #SQUARE M OVER S + {0xA7BE, 0x33A8}, //6803 #SQUARE M OVER S SQUARED + {0xA7BF, 0x33B0}, //6804 #SQUARE PS + {0xA7C0, 0x33B1}, //6805 #SQUARE NS + {0xA7C1, 0x33B2}, //6806 #SQUARE MU S + {0xA7C2, 0x33B3}, //6807 #SQUARE MS + {0xA7C3, 0x33B4}, //6808 #SQUARE PV + {0xA7C4, 0x33B5}, //6809 #SQUARE NV + {0xA7C5, 0x33B6}, //6810 #SQUARE MU V + {0xA7C6, 0x33B7}, //6811 #SQUARE MV + {0xA7C7, 0x33B8}, //6812 #SQUARE KV + {0xA7C8, 0x33B9}, //6813 #SQUARE MV MEGA + {0xA7C9, 0x3380}, //6814 #SQUARE PA AMPS + {0xA7CA, 0x3381}, //6815 #SQUARE NA + {0xA7CB, 0x3382}, //6816 #SQUARE MU A + {0xA7CC, 0x3383}, //6817 #SQUARE MA + {0xA7CD, 0x3384}, //6818 #SQUARE KA + {0xA7CE, 0x33BA}, //6819 #SQUARE PW + {0xA7CF, 0x33BB}, //6820 #SQUARE NW + {0xA7D0, 0x33BC}, //6821 #SQUARE MU W + {0xA7D1, 0x33BD}, //6822 #SQUARE MW + {0xA7D2, 0x33BE}, //6823 #SQUARE KW + {0xA7D3, 0x33BF}, //6824 #SQUARE MW MEGA + {0xA7D4, 0x3390}, //6825 #SQUARE HZ + {0xA7D5, 0x3391}, //6826 #SQUARE KHZ + {0xA7D6, 0x3392}, //6827 #SQUARE MHZ + {0xA7D7, 0x3393}, //6828 #SQUARE GHZ + {0xA7D8, 0x3394}, //6829 #SQUARE THZ + {0xA7D9, 0x2126}, //6830 #OHM SIGN + {0xA7DA, 0x33C0}, //6831 #SQUARE K OHM + {0xA7DB, 0x33C1}, //6832 #SQUARE M OHM + {0xA7DC, 0x338A}, //6833 #SQUARE PF + {0xA7DD, 0x338B}, //6834 #SQUARE NF + {0xA7DE, 0x338C}, //6835 #SQUARE MU F + {0xA7DF, 0x33D6}, //6836 #SQUARE MOL + {0xA7E0, 0x33C5}, //6837 #SQUARE CD + {0xA7E1, 0x33AD}, //6838 #SQUARE RAD + {0xA7E2, 0x33AE}, //6839 #SQUARE RAD OVER S + {0xA7E3, 0x33AF}, //6840 #SQUARE RAD OVER S SQUARED + {0xA7E4, 0x33DB}, //6841 #SQUARE SR + {0xA7E5, 0x33A9}, //6842 #SQUARE PA + {0xA7E6, 0x33AA}, //6843 #SQUARE KPA + {0xA7E7, 0x33AB}, //6844 #SQUARE MPA + {0xA7E8, 0x33AC}, //6845 #SQUARE GPA + {0xA7E9, 0x33DD}, //6846 #SQUARE WB + {0xA7EA, 0x33D0}, //6847 #SQUARE LM + {0xA7EB, 0x33D3}, //6848 #SQUARE LX + {0xA7EC, 0x33C3}, //6849 #SQUARE BQ + {0xA7ED, 0x33C9}, //6850 #SQUARE GY + {0xA7EE, 0x33DC}, //6851 #SQUARE SV + {0xA7EF, 0x33C6}, //6852 #SQUARE C OVER KG + {0xA841, 0xCB6D}, //6853 #HANGUL SYLLABLE SSANGCIEUC WEO RIEULKIYEOK + {0xA842, 0xCB6E}, //6854 #HANGUL SYLLABLE SSANGCIEUC WEO RIEULMIEUM + {0xA843, 0xCB6F}, //6855 #HANGUL SYLLABLE SSANGCIEUC WEO RIEULPIEUP + {0xA844, 0xCB70}, //6856 #HANGUL SYLLABLE SSANGCIEUC WEO RIEULSIOS + {0xA845, 0xCB71}, //6857 #HANGUL SYLLABLE SSANGCIEUC WEO RIEULTHIEUTH + {0xA846, 0xCB72}, //6858 #HANGUL SYLLABLE SSANGCIEUC WEO RIEULPHIEUPH + {0xA847, 0xCB73}, //6859 #HANGUL SYLLABLE SSANGCIEUC WEO RIEULHIEUH + {0xA848, 0xCB74}, //6860 #HANGUL SYLLABLE SSANGCIEUC WEO MIEUM + {0xA849, 0xCB75}, //6861 #HANGUL SYLLABLE SSANGCIEUC WEO PIEUP + {0xA84A, 0xCB76}, //6862 #HANGUL SYLLABLE SSANGCIEUC WEO PIEUPSIOS + {0xA84B, 0xCB77}, //6863 #HANGUL SYLLABLE SSANGCIEUC WEO SIOS + {0xA84C, 0xCB7A}, //6864 #HANGUL SYLLABLE SSANGCIEUC WEO CIEUC + {0xA84D, 0xCB7B}, //6865 #HANGUL SYLLABLE SSANGCIEUC WEO CHIEUCH + {0xA84E, 0xCB7C}, //6866 #HANGUL SYLLABLE SSANGCIEUC WEO KHIEUKH + {0xA84F, 0xCB7D}, //6867 #HANGUL SYLLABLE SSANGCIEUC WEO THIEUTH + {0xA850, 0xCB7E}, //6868 #HANGUL SYLLABLE SSANGCIEUC WEO PHIEUPH + {0xA851, 0xCB7F}, //6869 #HANGUL SYLLABLE SSANGCIEUC WEO HIEUH + {0xA852, 0xCB80}, //6870 #HANGUL SYLLABLE SSANGCIEUC WE + {0xA853, 0xCB81}, //6871 #HANGUL SYLLABLE SSANGCIEUC WE KIYEOK + {0xA854, 0xCB82}, //6872 #HANGUL SYLLABLE SSANGCIEUC WE SSANGKIYEOK + {0xA855, 0xCB83}, //6873 #HANGUL SYLLABLE SSANGCIEUC WE KIYEOKSIOS + {0xA856, 0xCB84}, //6874 #HANGUL SYLLABLE SSANGCIEUC WE NIEUN + {0xA857, 0xCB85}, //6875 #HANGUL SYLLABLE SSANGCIEUC WE NIEUNCIEUC + {0xA858, 0xCB86}, //6876 #HANGUL SYLLABLE SSANGCIEUC WE NIEUNHIEUH + {0xA859, 0xCB87}, //6877 #HANGUL SYLLABLE SSANGCIEUC WE TIKEUT + {0xA85A, 0xCB88}, //6878 #HANGUL SYLLABLE SSANGCIEUC WE RIEUL + {0xA861, 0xCB89}, //6879 #HANGUL SYLLABLE SSANGCIEUC WE RIEULKIYEOK + {0xA862, 0xCB8A}, //6880 #HANGUL SYLLABLE SSANGCIEUC WE RIEULMIEUM + {0xA863, 0xCB8B}, //6881 #HANGUL SYLLABLE SSANGCIEUC WE RIEULPIEUP + {0xA864, 0xCB8C}, //6882 #HANGUL SYLLABLE SSANGCIEUC WE RIEULSIOS + {0xA865, 0xCB8D}, //6883 #HANGUL SYLLABLE SSANGCIEUC WE RIEULTHIEUTH + {0xA866, 0xCB8E}, //6884 #HANGUL SYLLABLE SSANGCIEUC WE RIEULPHIEUPH + {0xA867, 0xCB8F}, //6885 #HANGUL SYLLABLE SSANGCIEUC WE RIEULHIEUH + {0xA868, 0xCB90}, //6886 #HANGUL SYLLABLE SSANGCIEUC WE MIEUM + {0xA869, 0xCB91}, //6887 #HANGUL SYLLABLE SSANGCIEUC WE PIEUP + {0xA86A, 0xCB92}, //6888 #HANGUL SYLLABLE SSANGCIEUC WE PIEUPSIOS + {0xA86B, 0xCB93}, //6889 #HANGUL SYLLABLE SSANGCIEUC WE SIOS + {0xA86C, 0xCB94}, //6890 #HANGUL SYLLABLE SSANGCIEUC WE SSANGSIOS + {0xA86D, 0xCB95}, //6891 #HANGUL SYLLABLE SSANGCIEUC WE IEUNG + {0xA86E, 0xCB96}, //6892 #HANGUL SYLLABLE SSANGCIEUC WE CIEUC + {0xA86F, 0xCB97}, //6893 #HANGUL SYLLABLE SSANGCIEUC WE CHIEUCH + {0xA870, 0xCB98}, //6894 #HANGUL SYLLABLE SSANGCIEUC WE KHIEUKH + {0xA871, 0xCB99}, //6895 #HANGUL SYLLABLE SSANGCIEUC WE THIEUTH + {0xA872, 0xCB9A}, //6896 #HANGUL SYLLABLE SSANGCIEUC WE PHIEUPH + {0xA873, 0xCB9B}, //6897 #HANGUL SYLLABLE SSANGCIEUC WE HIEUH + {0xA874, 0xCB9D}, //6898 #HANGUL SYLLABLE SSANGCIEUC WI KIYEOK + {0xA875, 0xCB9E}, //6899 #HANGUL SYLLABLE SSANGCIEUC WI SSANGKIYEOK + {0xA876, 0xCB9F}, //6900 #HANGUL SYLLABLE SSANGCIEUC WI KIYEOKSIOS + {0xA877, 0xCBA0}, //6901 #HANGUL SYLLABLE SSANGCIEUC WI NIEUN + {0xA878, 0xCBA1}, //6902 #HANGUL SYLLABLE SSANGCIEUC WI NIEUNCIEUC + {0xA879, 0xCBA2}, //6903 #HANGUL SYLLABLE SSANGCIEUC WI NIEUNHIEUH + {0xA87A, 0xCBA3}, //6904 #HANGUL SYLLABLE SSANGCIEUC WI TIKEUT + {0xA881, 0xCBA4}, //6905 #HANGUL SYLLABLE SSANGCIEUC WI RIEUL + {0xA882, 0xCBA5}, //6906 #HANGUL SYLLABLE SSANGCIEUC WI RIEULKIYEOK + {0xA883, 0xCBA6}, //6907 #HANGUL SYLLABLE SSANGCIEUC WI RIEULMIEUM + {0xA884, 0xCBA7}, //6908 #HANGUL SYLLABLE SSANGCIEUC WI RIEULPIEUP + {0xA885, 0xCBA8}, //6909 #HANGUL SYLLABLE SSANGCIEUC WI RIEULSIOS + {0xA886, 0xCBA9}, //6910 #HANGUL SYLLABLE SSANGCIEUC WI RIEULTHIEUTH + {0xA887, 0xCBAA}, //6911 #HANGUL SYLLABLE SSANGCIEUC WI RIEULPHIEUPH + {0xA888, 0xCBAB}, //6912 #HANGUL SYLLABLE SSANGCIEUC WI RIEULHIEUH + {0xA889, 0xCBAC}, //6913 #HANGUL SYLLABLE SSANGCIEUC WI MIEUM + {0xA88A, 0xCBAD}, //6914 #HANGUL SYLLABLE SSANGCIEUC WI PIEUP + {0xA88B, 0xCBAE}, //6915 #HANGUL SYLLABLE SSANGCIEUC WI PIEUPSIOS + {0xA88C, 0xCBAF}, //6916 #HANGUL SYLLABLE SSANGCIEUC WI SIOS + {0xA88D, 0xCBB0}, //6917 #HANGUL SYLLABLE SSANGCIEUC WI SSANGSIOS + {0xA88E, 0xCBB1}, //6918 #HANGUL SYLLABLE SSANGCIEUC WI IEUNG + {0xA88F, 0xCBB2}, //6919 #HANGUL SYLLABLE SSANGCIEUC WI CIEUC + {0xA890, 0xCBB3}, //6920 #HANGUL SYLLABLE SSANGCIEUC WI CHIEUCH + {0xA891, 0xCBB4}, //6921 #HANGUL SYLLABLE SSANGCIEUC WI KHIEUKH + {0xA892, 0xCBB5}, //6922 #HANGUL SYLLABLE SSANGCIEUC WI THIEUTH + {0xA893, 0xCBB6}, //6923 #HANGUL SYLLABLE SSANGCIEUC WI PHIEUPH + {0xA894, 0xCBB7}, //6924 #HANGUL SYLLABLE SSANGCIEUC WI HIEUH + {0xA895, 0xCBB9}, //6925 #HANGUL SYLLABLE SSANGCIEUC YU KIYEOK + {0xA896, 0xCBBA}, //6926 #HANGUL SYLLABLE SSANGCIEUC YU SSANGKIYEOK + {0xA897, 0xCBBB}, //6927 #HANGUL SYLLABLE SSANGCIEUC YU KIYEOKSIOS + {0xA898, 0xCBBC}, //6928 #HANGUL SYLLABLE SSANGCIEUC YU NIEUN + {0xA899, 0xCBBD}, //6929 #HANGUL SYLLABLE SSANGCIEUC YU NIEUNCIEUC + {0xA89A, 0xCBBE}, //6930 #HANGUL SYLLABLE SSANGCIEUC YU NIEUNHIEUH + {0xA89B, 0xCBBF}, //6931 #HANGUL SYLLABLE SSANGCIEUC YU TIKEUT + {0xA89C, 0xCBC0}, //6932 #HANGUL SYLLABLE SSANGCIEUC YU RIEUL + {0xA89D, 0xCBC1}, //6933 #HANGUL SYLLABLE SSANGCIEUC YU RIEULKIYEOK + {0xA89E, 0xCBC2}, //6934 #HANGUL SYLLABLE SSANGCIEUC YU RIEULMIEUM + {0xA89F, 0xCBC3}, //6935 #HANGUL SYLLABLE SSANGCIEUC YU RIEULPIEUP + {0xA8A0, 0xCBC4}, //6936 #HANGUL SYLLABLE SSANGCIEUC YU RIEULSIOS + {0xA8A1, 0x00C6}, //6937 #LATIN CAPITAL LETTER AE + {0xA8A2, 0x00D0}, //6938 #LATIN CAPITAL LETTER ETH + {0xA8A3, 0x00AA}, //6939 #FEMININE ORDINAL INDICATOR + {0xA8A4, 0x0126}, //6940 #LATIN CAPITAL LETTER H WITH STROKE + {0xA8A6, 0x0132}, //6941 #LATIN CAPITAL LIGATURE IJ + {0xA8A8, 0x013F}, //6942 #LATIN CAPITAL LETTER L WITH MIDDLE DOT + {0xA8A9, 0x0141}, //6943 #LATIN CAPITAL LETTER L WITH STROKE + {0xA8AA, 0x00D8}, //6944 #LATIN CAPITAL LETTER O WITH STROKE + {0xA8AB, 0x0152}, //6945 #LATIN CAPITAL LIGATURE OE + {0xA8AC, 0x00BA}, //6946 #MASCULINE ORDINAL INDICATOR + {0xA8AD, 0x00DE}, //6947 #LATIN CAPITAL LETTER THORN + {0xA8AE, 0x0166}, //6948 #LATIN CAPITAL LETTER T WITH STROKE + {0xA8AF, 0x014A}, //6949 #LATIN CAPITAL LETTER ENG + {0xA8B1, 0x3260}, //6950 #CIRCLED HANGUL KIYEOK + {0xA8B2, 0x3261}, //6951 #CIRCLED HANGUL NIEUN + {0xA8B3, 0x3262}, //6952 #CIRCLED HANGUL TIKEUT + {0xA8B4, 0x3263}, //6953 #CIRCLED HANGUL RIEUL + {0xA8B5, 0x3264}, //6954 #CIRCLED HANGUL MIEUM + {0xA8B6, 0x3265}, //6955 #CIRCLED HANGUL PIEUP + {0xA8B7, 0x3266}, //6956 #CIRCLED HANGUL SIOS + {0xA8B8, 0x3267}, //6957 #CIRCLED HANGUL IEUNG + {0xA8B9, 0x3268}, //6958 #CIRCLED HANGUL CIEUC + {0xA8BA, 0x3269}, //6959 #CIRCLED HANGUL CHIEUCH + {0xA8BB, 0x326A}, //6960 #CIRCLED HANGUL KHIEUKH + {0xA8BC, 0x326B}, //6961 #CIRCLED HANGUL THIEUTH + {0xA8BD, 0x326C}, //6962 #CIRCLED HANGUL PHIEUPH + {0xA8BE, 0x326D}, //6963 #CIRCLED HANGUL HIEUH + {0xA8BF, 0x326E}, //6964 #CIRCLED HANGUL KIYEOK A + {0xA8C0, 0x326F}, //6965 #CIRCLED HANGUL NIEUN A + {0xA8C1, 0x3270}, //6966 #CIRCLED HANGUL TIKEUT A + {0xA8C2, 0x3271}, //6967 #CIRCLED HANGUL RIEUL A + {0xA8C3, 0x3272}, //6968 #CIRCLED HANGUL MIEUM A + {0xA8C4, 0x3273}, //6969 #CIRCLED HANGUL PIEUP A + {0xA8C5, 0x3274}, //6970 #CIRCLED HANGUL SIOS A + {0xA8C6, 0x3275}, //6971 #CIRCLED HANGUL IEUNG A + {0xA8C7, 0x3276}, //6972 #CIRCLED HANGUL CIEUC A + {0xA8C8, 0x3277}, //6973 #CIRCLED HANGUL CHIEUCH A + {0xA8C9, 0x3278}, //6974 #CIRCLED HANGUL KHIEUKH A + {0xA8CA, 0x3279}, //6975 #CIRCLED HANGUL THIEUTH A + {0xA8CB, 0x327A}, //6976 #CIRCLED HANGUL PHIEUPH A + {0xA8CC, 0x327B}, //6977 #CIRCLED HANGUL HIEUH A + {0xA8CD, 0x24D0}, //6978 #CIRCLED LATIN SMALL LETTER A + {0xA8CE, 0x24D1}, //6979 #CIRCLED LATIN SMALL LETTER B + {0xA8CF, 0x24D2}, //6980 #CIRCLED LATIN SMALL LETTER C + {0xA8D0, 0x24D3}, //6981 #CIRCLED LATIN SMALL LETTER D + {0xA8D1, 0x24D4}, //6982 #CIRCLED LATIN SMALL LETTER E + {0xA8D2, 0x24D5}, //6983 #CIRCLED LATIN SMALL LETTER F + {0xA8D3, 0x24D6}, //6984 #CIRCLED LATIN SMALL LETTER G + {0xA8D4, 0x24D7}, //6985 #CIRCLED LATIN SMALL LETTER H + {0xA8D5, 0x24D8}, //6986 #CIRCLED LATIN SMALL LETTER I + {0xA8D6, 0x24D9}, //6987 #CIRCLED LATIN SMALL LETTER J + {0xA8D7, 0x24DA}, //6988 #CIRCLED LATIN SMALL LETTER K + {0xA8D8, 0x24DB}, //6989 #CIRCLED LATIN SMALL LETTER L + {0xA8D9, 0x24DC}, //6990 #CIRCLED LATIN SMALL LETTER M + {0xA8DA, 0x24DD}, //6991 #CIRCLED LATIN SMALL LETTER N + {0xA8DB, 0x24DE}, //6992 #CIRCLED LATIN SMALL LETTER O + {0xA8DC, 0x24DF}, //6993 #CIRCLED LATIN SMALL LETTER P + {0xA8DD, 0x24E0}, //6994 #CIRCLED LATIN SMALL LETTER Q + {0xA8DE, 0x24E1}, //6995 #CIRCLED LATIN SMALL LETTER R + {0xA8DF, 0x24E2}, //6996 #CIRCLED LATIN SMALL LETTER S + {0xA8E0, 0x24E3}, //6997 #CIRCLED LATIN SMALL LETTER T + {0xA8E1, 0x24E4}, //6998 #CIRCLED LATIN SMALL LETTER U + {0xA8E2, 0x24E5}, //6999 #CIRCLED LATIN SMALL LETTER V + {0xA8E3, 0x24E6}, //7000 #CIRCLED LATIN SMALL LETTER W + {0xA8E4, 0x24E7}, //7001 #CIRCLED LATIN SMALL LETTER X + {0xA8E5, 0x24E8}, //7002 #CIRCLED LATIN SMALL LETTER Y + {0xA8E6, 0x24E9}, //7003 #CIRCLED LATIN SMALL LETTER Z + {0xA8E7, 0x2460}, //7004 #CIRCLED DIGIT ONE + {0xA8E8, 0x2461}, //7005 #CIRCLED DIGIT TWO + {0xA8E9, 0x2462}, //7006 #CIRCLED DIGIT THREE + {0xA8EA, 0x2463}, //7007 #CIRCLED DIGIT FOUR + {0xA8EB, 0x2464}, //7008 #CIRCLED DIGIT FIVE + {0xA8EC, 0x2465}, //7009 #CIRCLED DIGIT SIX + {0xA8ED, 0x2466}, //7010 #CIRCLED DIGIT SEVEN + {0xA8EE, 0x2467}, //7011 #CIRCLED DIGIT EIGHT + {0xA8EF, 0x2468}, //7012 #CIRCLED DIGIT NINE + {0xA8F0, 0x2469}, //7013 #CIRCLED NUMBER TEN + {0xA8F1, 0x246A}, //7014 #CIRCLED NUMBER ELEVEN + {0xA8F2, 0x246B}, //7015 #CIRCLED NUMBER TWELVE + {0xA8F3, 0x246C}, //7016 #CIRCLED NUMBER THIRTEEN + {0xA8F4, 0x246D}, //7017 #CIRCLED NUMBER FOURTEEN + {0xA8F5, 0x246E}, //7018 #CIRCLED NUMBER FIFTEEN + {0xA8F6, 0x00BD}, //7019 #VULGAR FRACTION ONE HALF + {0xA8F7, 0x2153}, //7020 #VULGAR FRACTION ONE THIRD + {0xA8F8, 0x2154}, //7021 #VULGAR FRACTION TWO THIRDS + {0xA8F9, 0x00BC}, //7022 #VULGAR FRACTION ONE QUARTER + {0xA8FA, 0x00BE}, //7023 #VULGAR FRACTION THREE QUARTERS + {0xA8FB, 0x215B}, //7024 #VULGAR FRACTION ONE EIGHTH + {0xA8FC, 0x215C}, //7025 #VULGAR FRACTION THREE EIGHTHS + {0xA8FD, 0x215D}, //7026 #VULGAR FRACTION FIVE EIGHTHS + {0xA8FE, 0x215E}, //7027 #VULGAR FRACTION SEVEN EIGHTHS + {0xA941, 0xCBC5}, //7028 #HANGUL SYLLABLE SSANGCIEUC YU RIEULTHIEUTH + {0xA942, 0xCBC6}, //7029 #HANGUL SYLLABLE SSANGCIEUC YU RIEULPHIEUPH + {0xA943, 0xCBC7}, //7030 #HANGUL SYLLABLE SSANGCIEUC YU RIEULHIEUH + {0xA944, 0xCBC8}, //7031 #HANGUL SYLLABLE SSANGCIEUC YU MIEUM + {0xA945, 0xCBC9}, //7032 #HANGUL SYLLABLE SSANGCIEUC YU PIEUP + {0xA946, 0xCBCA}, //7033 #HANGUL SYLLABLE SSANGCIEUC YU PIEUPSIOS + {0xA947, 0xCBCB}, //7034 #HANGUL SYLLABLE SSANGCIEUC YU SIOS + {0xA948, 0xCBCC}, //7035 #HANGUL SYLLABLE SSANGCIEUC YU SSANGSIOS + {0xA949, 0xCBCD}, //7036 #HANGUL SYLLABLE SSANGCIEUC YU IEUNG + {0xA94A, 0xCBCE}, //7037 #HANGUL SYLLABLE SSANGCIEUC YU CIEUC + {0xA94B, 0xCBCF}, //7038 #HANGUL SYLLABLE SSANGCIEUC YU CHIEUCH + {0xA94C, 0xCBD0}, //7039 #HANGUL SYLLABLE SSANGCIEUC YU KHIEUKH + {0xA94D, 0xCBD1}, //7040 #HANGUL SYLLABLE SSANGCIEUC YU THIEUTH + {0xA94E, 0xCBD2}, //7041 #HANGUL SYLLABLE SSANGCIEUC YU PHIEUPH + {0xA94F, 0xCBD3}, //7042 #HANGUL SYLLABLE SSANGCIEUC YU HIEUH + {0xA950, 0xCBD5}, //7043 #HANGUL SYLLABLE SSANGCIEUC EU KIYEOK + {0xA951, 0xCBD6}, //7044 #HANGUL SYLLABLE SSANGCIEUC EU SSANGKIYEOK + {0xA952, 0xCBD7}, //7045 #HANGUL SYLLABLE SSANGCIEUC EU KIYEOKSIOS + {0xA953, 0xCBD8}, //7046 #HANGUL SYLLABLE SSANGCIEUC EU NIEUN + {0xA954, 0xCBD9}, //7047 #HANGUL SYLLABLE SSANGCIEUC EU NIEUNCIEUC + {0xA955, 0xCBDA}, //7048 #HANGUL SYLLABLE SSANGCIEUC EU NIEUNHIEUH + {0xA956, 0xCBDB}, //7049 #HANGUL SYLLABLE SSANGCIEUC EU TIKEUT + {0xA957, 0xCBDC}, //7050 #HANGUL SYLLABLE SSANGCIEUC EU RIEUL + {0xA958, 0xCBDD}, //7051 #HANGUL SYLLABLE SSANGCIEUC EU RIEULKIYEOK + {0xA959, 0xCBDE}, //7052 #HANGUL SYLLABLE SSANGCIEUC EU RIEULMIEUM + {0xA95A, 0xCBDF}, //7053 #HANGUL SYLLABLE SSANGCIEUC EU RIEULPIEUP + {0xA961, 0xCBE0}, //7054 #HANGUL SYLLABLE SSANGCIEUC EU RIEULSIOS + {0xA962, 0xCBE1}, //7055 #HANGUL SYLLABLE SSANGCIEUC EU RIEULTHIEUTH + {0xA963, 0xCBE2}, //7056 #HANGUL SYLLABLE SSANGCIEUC EU RIEULPHIEUPH + {0xA964, 0xCBE3}, //7057 #HANGUL SYLLABLE SSANGCIEUC EU RIEULHIEUH + {0xA965, 0xCBE5}, //7058 #HANGUL SYLLABLE SSANGCIEUC EU PIEUP + {0xA966, 0xCBE6}, //7059 #HANGUL SYLLABLE SSANGCIEUC EU PIEUPSIOS + {0xA967, 0xCBE8}, //7060 #HANGUL SYLLABLE SSANGCIEUC EU SSANGSIOS + {0xA968, 0xCBEA}, //7061 #HANGUL SYLLABLE SSANGCIEUC EU CIEUC + {0xA969, 0xCBEB}, //7062 #HANGUL SYLLABLE SSANGCIEUC EU CHIEUCH + {0xA96A, 0xCBEC}, //7063 #HANGUL SYLLABLE SSANGCIEUC EU KHIEUKH + {0xA96B, 0xCBED}, //7064 #HANGUL SYLLABLE SSANGCIEUC EU THIEUTH + {0xA96C, 0xCBEE}, //7065 #HANGUL SYLLABLE SSANGCIEUC EU PHIEUPH + {0xA96D, 0xCBEF}, //7066 #HANGUL SYLLABLE SSANGCIEUC EU HIEUH + {0xA96E, 0xCBF0}, //7067 #HANGUL SYLLABLE SSANGCIEUC YI + {0xA96F, 0xCBF1}, //7068 #HANGUL SYLLABLE SSANGCIEUC YI KIYEOK + {0xA970, 0xCBF2}, //7069 #HANGUL SYLLABLE SSANGCIEUC YI SSANGKIYEOK + {0xA971, 0xCBF3}, //7070 #HANGUL SYLLABLE SSANGCIEUC YI KIYEOKSIOS + {0xA972, 0xCBF4}, //7071 #HANGUL SYLLABLE SSANGCIEUC YI NIEUN + {0xA973, 0xCBF5}, //7072 #HANGUL SYLLABLE SSANGCIEUC YI NIEUNCIEUC + {0xA974, 0xCBF6}, //7073 #HANGUL SYLLABLE SSANGCIEUC YI NIEUNHIEUH + {0xA975, 0xCBF7}, //7074 #HANGUL SYLLABLE SSANGCIEUC YI TIKEUT + {0xA976, 0xCBF8}, //7075 #HANGUL SYLLABLE SSANGCIEUC YI RIEUL + {0xA977, 0xCBF9}, //7076 #HANGUL SYLLABLE SSANGCIEUC YI RIEULKIYEOK + {0xA978, 0xCBFA}, //7077 #HANGUL SYLLABLE SSANGCIEUC YI RIEULMIEUM + {0xA979, 0xCBFB}, //7078 #HANGUL SYLLABLE SSANGCIEUC YI RIEULPIEUP + {0xA97A, 0xCBFC}, //7079 #HANGUL SYLLABLE SSANGCIEUC YI RIEULSIOS + {0xA981, 0xCBFD}, //7080 #HANGUL SYLLABLE SSANGCIEUC YI RIEULTHIEUTH + {0xA982, 0xCBFE}, //7081 #HANGUL SYLLABLE SSANGCIEUC YI RIEULPHIEUPH + {0xA983, 0xCBFF}, //7082 #HANGUL SYLLABLE SSANGCIEUC YI RIEULHIEUH + {0xA984, 0xCC00}, //7083 #HANGUL SYLLABLE SSANGCIEUC YI MIEUM + {0xA985, 0xCC01}, //7084 #HANGUL SYLLABLE SSANGCIEUC YI PIEUP + {0xA986, 0xCC02}, //7085 #HANGUL SYLLABLE SSANGCIEUC YI PIEUPSIOS + {0xA987, 0xCC03}, //7086 #HANGUL SYLLABLE SSANGCIEUC YI SIOS + {0xA988, 0xCC04}, //7087 #HANGUL SYLLABLE SSANGCIEUC YI SSANGSIOS + {0xA989, 0xCC05}, //7088 #HANGUL SYLLABLE SSANGCIEUC YI IEUNG + {0xA98A, 0xCC06}, //7089 #HANGUL SYLLABLE SSANGCIEUC YI CIEUC + {0xA98B, 0xCC07}, //7090 #HANGUL SYLLABLE SSANGCIEUC YI CHIEUCH + {0xA98C, 0xCC08}, //7091 #HANGUL SYLLABLE SSANGCIEUC YI KHIEUKH + {0xA98D, 0xCC09}, //7092 #HANGUL SYLLABLE SSANGCIEUC YI THIEUTH + {0xA98E, 0xCC0A}, //7093 #HANGUL SYLLABLE SSANGCIEUC YI PHIEUPH + {0xA98F, 0xCC0B}, //7094 #HANGUL SYLLABLE SSANGCIEUC YI HIEUH + {0xA990, 0xCC0E}, //7095 #HANGUL SYLLABLE SSANGCIEUC I SSANGKIYEOK + {0xA991, 0xCC0F}, //7096 #HANGUL SYLLABLE SSANGCIEUC I KIYEOKSIOS + {0xA992, 0xCC11}, //7097 #HANGUL SYLLABLE SSANGCIEUC I NIEUNCIEUC + {0xA993, 0xCC12}, //7098 #HANGUL SYLLABLE SSANGCIEUC I NIEUNHIEUH + {0xA994, 0xCC13}, //7099 #HANGUL SYLLABLE SSANGCIEUC I TIKEUT + {0xA995, 0xCC15}, //7100 #HANGUL SYLLABLE SSANGCIEUC I RIEULKIYEOK + {0xA996, 0xCC16}, //7101 #HANGUL SYLLABLE SSANGCIEUC I RIEULMIEUM + {0xA997, 0xCC17}, //7102 #HANGUL SYLLABLE SSANGCIEUC I RIEULPIEUP + {0xA998, 0xCC18}, //7103 #HANGUL SYLLABLE SSANGCIEUC I RIEULSIOS + {0xA999, 0xCC19}, //7104 #HANGUL SYLLABLE SSANGCIEUC I RIEULTHIEUTH + {0xA99A, 0xCC1A}, //7105 #HANGUL SYLLABLE SSANGCIEUC I RIEULPHIEUPH + {0xA99B, 0xCC1B}, //7106 #HANGUL SYLLABLE SSANGCIEUC I RIEULHIEUH + {0xA99C, 0xCC1E}, //7107 #HANGUL SYLLABLE SSANGCIEUC I PIEUPSIOS + {0xA99D, 0xCC1F}, //7108 #HANGUL SYLLABLE SSANGCIEUC I SIOS + {0xA99E, 0xCC20}, //7109 #HANGUL SYLLABLE SSANGCIEUC I SSANGSIOS + {0xA99F, 0xCC23}, //7110 #HANGUL SYLLABLE SSANGCIEUC I CHIEUCH + {0xA9A0, 0xCC24}, //7111 #HANGUL SYLLABLE SSANGCIEUC I KHIEUKH + {0xA9A1, 0x00E6}, //7112 #LATIN SMALL LETTER AE + {0xA9A2, 0x0111}, //7113 #LATIN SMALL LETTER D WITH STROKE + {0xA9A3, 0x00F0}, //7114 #LATIN SMALL LETTER ETH + {0xA9A4, 0x0127}, //7115 #LATIN SMALL LETTER H WITH STROKE + {0xA9A5, 0x0131}, //7116 #LATIN SMALL LETTER DOTLESS I + {0xA9A6, 0x0133}, //7117 #LATIN SMALL LIGATURE IJ + {0xA9A7, 0x0138}, //7118 #LATIN SMALL LETTER KRA + {0xA9A8, 0x0140}, //7119 #LATIN SMALL LETTER L WITH MIDDLE DOT + {0xA9A9, 0x0142}, //7120 #LATIN SMALL LETTER L WITH STROKE + {0xA9AA, 0x00F8}, //7121 #LATIN SMALL LETTER O WITH STROKE + {0xA9AB, 0x0153}, //7122 #LATIN SMALL LIGATURE OE + {0xA9AC, 0x00DF}, //7123 #LATIN SMALL LETTER SHARP S + {0xA9AD, 0x00FE}, //7124 #LATIN SMALL LETTER THORN + {0xA9AE, 0x0167}, //7125 #LATIN SMALL LETTER T WITH STROKE + {0xA9AF, 0x014B}, //7126 #LATIN SMALL LETTER ENG + {0xA9B0, 0x0149}, //7127 #LATIN SMALL LETTER N PRECEDED BY APOSTROPHE + {0xA9B1, 0x3200}, //7128 #PARENTHESIZED HANGUL KIYEOK + {0xA9B2, 0x3201}, //7129 #PARENTHESIZED HANGUL NIEUN + {0xA9B3, 0x3202}, //7130 #PARENTHESIZED HANGUL TIKEUT + {0xA9B4, 0x3203}, //7131 #PARENTHESIZED HANGUL RIEUL + {0xA9B5, 0x3204}, //7132 #PARENTHESIZED HANGUL MIEUM + {0xA9B6, 0x3205}, //7133 #PARENTHESIZED HANGUL PIEUP + {0xA9B7, 0x3206}, //7134 #PARENTHESIZED HANGUL SIOS + {0xA9B8, 0x3207}, //7135 #PARENTHESIZED HANGUL IEUNG + {0xA9B9, 0x3208}, //7136 #PARENTHESIZED HANGUL CIEUC + {0xA9BA, 0x3209}, //7137 #PARENTHESIZED HANGUL CHIEUCH + {0xA9BB, 0x320A}, //7138 #PARENTHESIZED HANGUL KHIEUKH + {0xA9BC, 0x320B}, //7139 #PARENTHESIZED HANGUL THIEUTH + {0xA9BD, 0x320C}, //7140 #PARENTHESIZED HANGUL PHIEUPH + {0xA9BE, 0x320D}, //7141 #PARENTHESIZED HANGUL HIEUH + {0xA9BF, 0x320E}, //7142 #PARENTHESIZED HANGUL KIYEOK A + {0xA9C0, 0x320F}, //7143 #PARENTHESIZED HANGUL NIEUN A + {0xA9C1, 0x3210}, //7144 #PARENTHESIZED HANGUL TIKEUT A + {0xA9C2, 0x3211}, //7145 #PARENTHESIZED HANGUL RIEUL A + {0xA9C3, 0x3212}, //7146 #PARENTHESIZED HANGUL MIEUM A + {0xA9C4, 0x3213}, //7147 #PARENTHESIZED HANGUL PIEUP A + {0xA9C5, 0x3214}, //7148 #PARENTHESIZED HANGUL SIOS A + {0xA9C6, 0x3215}, //7149 #PARENTHESIZED HANGUL IEUNG A + {0xA9C7, 0x3216}, //7150 #PARENTHESIZED HANGUL CIEUC A + {0xA9C8, 0x3217}, //7151 #PARENTHESIZED HANGUL CHIEUCH A + {0xA9C9, 0x3218}, //7152 #PARENTHESIZED HANGUL KHIEUKH A + {0xA9CA, 0x3219}, //7153 #PARENTHESIZED HANGUL THIEUTH A + {0xA9CB, 0x321A}, //7154 #PARENTHESIZED HANGUL PHIEUPH A + {0xA9CC, 0x321B}, //7155 #PARENTHESIZED HANGUL HIEUH A + {0xA9CD, 0x249C}, //7156 #PARENTHESIZED LATIN SMALL LETTER A + {0xA9CE, 0x249D}, //7157 #PARENTHESIZED LATIN SMALL LETTER B + {0xA9CF, 0x249E}, //7158 #PARENTHESIZED LATIN SMALL LETTER C + {0xA9D0, 0x249F}, //7159 #PARENTHESIZED LATIN SMALL LETTER D + {0xA9D1, 0x24A0}, //7160 #PARENTHESIZED LATIN SMALL LETTER E + {0xA9D2, 0x24A1}, //7161 #PARENTHESIZED LATIN SMALL LETTER F + {0xA9D3, 0x24A2}, //7162 #PARENTHESIZED LATIN SMALL LETTER G + {0xA9D4, 0x24A3}, //7163 #PARENTHESIZED LATIN SMALL LETTER H + {0xA9D5, 0x24A4}, //7164 #PARENTHESIZED LATIN SMALL LETTER I + {0xA9D6, 0x24A5}, //7165 #PARENTHESIZED LATIN SMALL LETTER J + {0xA9D7, 0x24A6}, //7166 #PARENTHESIZED LATIN SMALL LETTER K + {0xA9D8, 0x24A7}, //7167 #PARENTHESIZED LATIN SMALL LETTER L + {0xA9D9, 0x24A8}, //7168 #PARENTHESIZED LATIN SMALL LETTER M + {0xA9DA, 0x24A9}, //7169 #PARENTHESIZED LATIN SMALL LETTER N + {0xA9DB, 0x24AA}, //7170 #PARENTHESIZED LATIN SMALL LETTER O + {0xA9DC, 0x24AB}, //7171 #PARENTHESIZED LATIN SMALL LETTER P + {0xA9DD, 0x24AC}, //7172 #PARENTHESIZED LATIN SMALL LETTER Q + {0xA9DE, 0x24AD}, //7173 #PARENTHESIZED LATIN SMALL LETTER R + {0xA9DF, 0x24AE}, //7174 #PARENTHESIZED LATIN SMALL LETTER S + {0xA9E0, 0x24AF}, //7175 #PARENTHESIZED LATIN SMALL LETTER T + {0xA9E1, 0x24B0}, //7176 #PARENTHESIZED LATIN SMALL LETTER U + {0xA9E2, 0x24B1}, //7177 #PARENTHESIZED LATIN SMALL LETTER V + {0xA9E3, 0x24B2}, //7178 #PARENTHESIZED LATIN SMALL LETTER W + {0xA9E4, 0x24B3}, //7179 #PARENTHESIZED LATIN SMALL LETTER X + {0xA9E5, 0x24B4}, //7180 #PARENTHESIZED LATIN SMALL LETTER Y + {0xA9E6, 0x24B5}, //7181 #PARENTHESIZED LATIN SMALL LETTER Z + {0xA9E7, 0x2474}, //7182 #PARENTHESIZED DIGIT ONE + {0xA9E8, 0x2475}, //7183 #PARENTHESIZED DIGIT TWO + {0xA9E9, 0x2476}, //7184 #PARENTHESIZED DIGIT THREE + {0xA9EA, 0x2477}, //7185 #PARENTHESIZED DIGIT FOUR + {0xA9EB, 0x2478}, //7186 #PARENTHESIZED DIGIT FIVE + {0xA9EC, 0x2479}, //7187 #PARENTHESIZED DIGIT SIX + {0xA9ED, 0x247A}, //7188 #PARENTHESIZED DIGIT SEVEN + {0xA9EE, 0x247B}, //7189 #PARENTHESIZED DIGIT EIGHT + {0xA9EF, 0x247C}, //7190 #PARENTHESIZED DIGIT NINE + {0xA9F0, 0x247D}, //7191 #PARENTHESIZED NUMBER TEN + {0xA9F1, 0x247E}, //7192 #PARENTHESIZED NUMBER ELEVEN + {0xA9F2, 0x247F}, //7193 #PARENTHESIZED NUMBER TWELVE + {0xA9F3, 0x2480}, //7194 #PARENTHESIZED NUMBER THIRTEEN + {0xA9F4, 0x2481}, //7195 #PARENTHESIZED NUMBER FOURTEEN + {0xA9F5, 0x2482}, //7196 #PARENTHESIZED NUMBER FIFTEEN + {0xA9F6, 0x00B9}, //7197 #SUPERSCRIPT ONE + {0xA9F7, 0x00B2}, //7198 #SUPERSCRIPT TWO + {0xA9F8, 0x00B3}, //7199 #SUPERSCRIPT THREE + {0xA9F9, 0x2074}, //7200 #SUPERSCRIPT FOUR + {0xA9FA, 0x207F}, //7201 #SUPERSCRIPT LATIN SMALL LETTER N + {0xA9FB, 0x2081}, //7202 #SUBSCRIPT ONE + {0xA9FC, 0x2082}, //7203 #SUBSCRIPT TWO + {0xA9FD, 0x2083}, //7204 #SUBSCRIPT THREE + {0xA9FE, 0x2084}, //7205 #SUBSCRIPT FOUR + {0xAA41, 0xCC25}, //7206 #HANGUL SYLLABLE SSANGCIEUC I THIEUTH + {0xAA42, 0xCC26}, //7207 #HANGUL SYLLABLE SSANGCIEUC I PHIEUPH + {0xAA43, 0xCC2A}, //7208 #HANGUL SYLLABLE CHIEUCH A SSANGKIYEOK + {0xAA44, 0xCC2B}, //7209 #HANGUL SYLLABLE CHIEUCH A KIYEOKSIOS + {0xAA45, 0xCC2D}, //7210 #HANGUL SYLLABLE CHIEUCH A NIEUNCIEUC + {0xAA46, 0xCC2F}, //7211 #HANGUL SYLLABLE CHIEUCH A TIKEUT + {0xAA47, 0xCC31}, //7212 #HANGUL SYLLABLE CHIEUCH A RIEULKIYEOK + {0xAA48, 0xCC32}, //7213 #HANGUL SYLLABLE CHIEUCH A RIEULMIEUM + {0xAA49, 0xCC33}, //7214 #HANGUL SYLLABLE CHIEUCH A RIEULPIEUP + {0xAA4A, 0xCC34}, //7215 #HANGUL SYLLABLE CHIEUCH A RIEULSIOS + {0xAA4B, 0xCC35}, //7216 #HANGUL SYLLABLE CHIEUCH A RIEULTHIEUTH + {0xAA4C, 0xCC36}, //7217 #HANGUL SYLLABLE CHIEUCH A RIEULPHIEUPH + {0xAA4D, 0xCC37}, //7218 #HANGUL SYLLABLE CHIEUCH A RIEULHIEUH + {0xAA4E, 0xCC3A}, //7219 #HANGUL SYLLABLE CHIEUCH A PIEUPSIOS + {0xAA4F, 0xCC3F}, //7220 #HANGUL SYLLABLE CHIEUCH A CHIEUCH + {0xAA50, 0xCC40}, //7221 #HANGUL SYLLABLE CHIEUCH A KHIEUKH + {0xAA51, 0xCC41}, //7222 #HANGUL SYLLABLE CHIEUCH A THIEUTH + {0xAA52, 0xCC42}, //7223 #HANGUL SYLLABLE CHIEUCH A PHIEUPH + {0xAA53, 0xCC43}, //7224 #HANGUL SYLLABLE CHIEUCH A HIEUH + {0xAA54, 0xCC46}, //7225 #HANGUL SYLLABLE CHIEUCH AE SSANGKIYEOK + {0xAA55, 0xCC47}, //7226 #HANGUL SYLLABLE CHIEUCH AE KIYEOKSIOS + {0xAA56, 0xCC49}, //7227 #HANGUL SYLLABLE CHIEUCH AE NIEUNCIEUC + {0xAA57, 0xCC4A}, //7228 #HANGUL SYLLABLE CHIEUCH AE NIEUNHIEUH + {0xAA58, 0xCC4B}, //7229 #HANGUL SYLLABLE CHIEUCH AE TIKEUT + {0xAA59, 0xCC4D}, //7230 #HANGUL SYLLABLE CHIEUCH AE RIEULKIYEOK + {0xAA5A, 0xCC4E}, //7231 #HANGUL SYLLABLE CHIEUCH AE RIEULMIEUM + {0xAA61, 0xCC4F}, //7232 #HANGUL SYLLABLE CHIEUCH AE RIEULPIEUP + {0xAA62, 0xCC50}, //7233 #HANGUL SYLLABLE CHIEUCH AE RIEULSIOS + {0xAA63, 0xCC51}, //7234 #HANGUL SYLLABLE CHIEUCH AE RIEULTHIEUTH + {0xAA64, 0xCC52}, //7235 #HANGUL SYLLABLE CHIEUCH AE RIEULPHIEUPH + {0xAA65, 0xCC53}, //7236 #HANGUL SYLLABLE CHIEUCH AE RIEULHIEUH + {0xAA66, 0xCC56}, //7237 #HANGUL SYLLABLE CHIEUCH AE PIEUPSIOS + {0xAA67, 0xCC5A}, //7238 #HANGUL SYLLABLE CHIEUCH AE CIEUC + {0xAA68, 0xCC5B}, //7239 #HANGUL SYLLABLE CHIEUCH AE CHIEUCH + {0xAA69, 0xCC5C}, //7240 #HANGUL SYLLABLE CHIEUCH AE KHIEUKH + {0xAA6A, 0xCC5D}, //7241 #HANGUL SYLLABLE CHIEUCH AE THIEUTH + {0xAA6B, 0xCC5E}, //7242 #HANGUL SYLLABLE CHIEUCH AE PHIEUPH + {0xAA6C, 0xCC5F}, //7243 #HANGUL SYLLABLE CHIEUCH AE HIEUH + {0xAA6D, 0xCC61}, //7244 #HANGUL SYLLABLE CHIEUCH YA KIYEOK + {0xAA6E, 0xCC62}, //7245 #HANGUL SYLLABLE CHIEUCH YA SSANGKIYEOK + {0xAA6F, 0xCC63}, //7246 #HANGUL SYLLABLE CHIEUCH YA KIYEOKSIOS + {0xAA70, 0xCC65}, //7247 #HANGUL SYLLABLE CHIEUCH YA NIEUNCIEUC + {0xAA71, 0xCC67}, //7248 #HANGUL SYLLABLE CHIEUCH YA TIKEUT + {0xAA72, 0xCC69}, //7249 #HANGUL SYLLABLE CHIEUCH YA RIEULKIYEOK + {0xAA73, 0xCC6A}, //7250 #HANGUL SYLLABLE CHIEUCH YA RIEULMIEUM + {0xAA74, 0xCC6B}, //7251 #HANGUL SYLLABLE CHIEUCH YA RIEULPIEUP + {0xAA75, 0xCC6C}, //7252 #HANGUL SYLLABLE CHIEUCH YA RIEULSIOS + {0xAA76, 0xCC6D}, //7253 #HANGUL SYLLABLE CHIEUCH YA RIEULTHIEUTH + {0xAA77, 0xCC6E}, //7254 #HANGUL SYLLABLE CHIEUCH YA RIEULPHIEUPH + {0xAA78, 0xCC6F}, //7255 #HANGUL SYLLABLE CHIEUCH YA RIEULHIEUH + {0xAA79, 0xCC71}, //7256 #HANGUL SYLLABLE CHIEUCH YA PIEUP + {0xAA7A, 0xCC72}, //7257 #HANGUL SYLLABLE CHIEUCH YA PIEUPSIOS + {0xAA81, 0xCC73}, //7258 #HANGUL SYLLABLE CHIEUCH YA SIOS + {0xAA82, 0xCC74}, //7259 #HANGUL SYLLABLE CHIEUCH YA SSANGSIOS + {0xAA83, 0xCC76}, //7260 #HANGUL SYLLABLE CHIEUCH YA CIEUC + {0xAA84, 0xCC77}, //7261 #HANGUL SYLLABLE CHIEUCH YA CHIEUCH + {0xAA85, 0xCC78}, //7262 #HANGUL SYLLABLE CHIEUCH YA KHIEUKH + {0xAA86, 0xCC79}, //7263 #HANGUL SYLLABLE CHIEUCH YA THIEUTH + {0xAA87, 0xCC7A}, //7264 #HANGUL SYLLABLE CHIEUCH YA PHIEUPH + {0xAA88, 0xCC7B}, //7265 #HANGUL SYLLABLE CHIEUCH YA HIEUH + {0xAA89, 0xCC7C}, //7266 #HANGUL SYLLABLE CHIEUCH YAE + {0xAA8A, 0xCC7D}, //7267 #HANGUL SYLLABLE CHIEUCH YAE KIYEOK + {0xAA8B, 0xCC7E}, //7268 #HANGUL SYLLABLE CHIEUCH YAE SSANGKIYEOK + {0xAA8C, 0xCC7F}, //7269 #HANGUL SYLLABLE CHIEUCH YAE KIYEOKSIOS + {0xAA8D, 0xCC80}, //7270 #HANGUL SYLLABLE CHIEUCH YAE NIEUN + {0xAA8E, 0xCC81}, //7271 #HANGUL SYLLABLE CHIEUCH YAE NIEUNCIEUC + {0xAA8F, 0xCC82}, //7272 #HANGUL SYLLABLE CHIEUCH YAE NIEUNHIEUH + {0xAA90, 0xCC83}, //7273 #HANGUL SYLLABLE CHIEUCH YAE TIKEUT + {0xAA91, 0xCC84}, //7274 #HANGUL SYLLABLE CHIEUCH YAE RIEUL + {0xAA92, 0xCC85}, //7275 #HANGUL SYLLABLE CHIEUCH YAE RIEULKIYEOK + {0xAA93, 0xCC86}, //7276 #HANGUL SYLLABLE CHIEUCH YAE RIEULMIEUM + {0xAA94, 0xCC87}, //7277 #HANGUL SYLLABLE CHIEUCH YAE RIEULPIEUP + {0xAA95, 0xCC88}, //7278 #HANGUL SYLLABLE CHIEUCH YAE RIEULSIOS + {0xAA96, 0xCC89}, //7279 #HANGUL SYLLABLE CHIEUCH YAE RIEULTHIEUTH + {0xAA97, 0xCC8A}, //7280 #HANGUL SYLLABLE CHIEUCH YAE RIEULPHIEUPH + {0xAA98, 0xCC8B}, //7281 #HANGUL SYLLABLE CHIEUCH YAE RIEULHIEUH + {0xAA99, 0xCC8C}, //7282 #HANGUL SYLLABLE CHIEUCH YAE MIEUM + {0xAA9A, 0xCC8D}, //7283 #HANGUL SYLLABLE CHIEUCH YAE PIEUP + {0xAA9B, 0xCC8E}, //7284 #HANGUL SYLLABLE CHIEUCH YAE PIEUPSIOS + {0xAA9C, 0xCC8F}, //7285 #HANGUL SYLLABLE CHIEUCH YAE SIOS + {0xAA9D, 0xCC90}, //7286 #HANGUL SYLLABLE CHIEUCH YAE SSANGSIOS + {0xAA9E, 0xCC91}, //7287 #HANGUL SYLLABLE CHIEUCH YAE IEUNG + {0xAA9F, 0xCC92}, //7288 #HANGUL SYLLABLE CHIEUCH YAE CIEUC + {0xAAA0, 0xCC93}, //7289 #HANGUL SYLLABLE CHIEUCH YAE CHIEUCH + {0xAAA1, 0x3041}, //7290 #HIRAGANA LETTER SMALL A + {0xAAA2, 0x3042}, //7291 #HIRAGANA LETTER A + {0xAAA3, 0x3043}, //7292 #HIRAGANA LETTER SMALL I + {0xAAA4, 0x3044}, //7293 #HIRAGANA LETTER I + {0xAAA5, 0x3045}, //7294 #HIRAGANA LETTER SMALL U + {0xAAA6, 0x3046}, //7295 #HIRAGANA LETTER U + {0xAAA7, 0x3047}, //7296 #HIRAGANA LETTER SMALL E + {0xAAA8, 0x3048}, //7297 #HIRAGANA LETTER E + {0xAAA9, 0x3049}, //7298 #HIRAGANA LETTER SMALL O + {0xAAAA, 0x304A}, //7299 #HIRAGANA LETTER O + {0xAAAB, 0x304B}, //7300 #HIRAGANA LETTER KA + {0xAAAC, 0x304C}, //7301 #HIRAGANA LETTER GA + {0xAAAD, 0x304D}, //7302 #HIRAGANA LETTER KI + {0xAAAE, 0x304E}, //7303 #HIRAGANA LETTER GI + {0xAAAF, 0x304F}, //7304 #HIRAGANA LETTER KU + {0xAAB0, 0x3050}, //7305 #HIRAGANA LETTER GU + {0xAAB1, 0x3051}, //7306 #HIRAGANA LETTER KE + {0xAAB2, 0x3052}, //7307 #HIRAGANA LETTER GE + {0xAAB3, 0x3053}, //7308 #HIRAGANA LETTER KO + {0xAAB4, 0x3054}, //7309 #HIRAGANA LETTER GO + {0xAAB5, 0x3055}, //7310 #HIRAGANA LETTER SA + {0xAAB6, 0x3056}, //7311 #HIRAGANA LETTER ZA + {0xAAB7, 0x3057}, //7312 #HIRAGANA LETTER SI + {0xAAB8, 0x3058}, //7313 #HIRAGANA LETTER ZI + {0xAAB9, 0x3059}, //7314 #HIRAGANA LETTER SU + {0xAABA, 0x305A}, //7315 #HIRAGANA LETTER ZU + {0xAABB, 0x305B}, //7316 #HIRAGANA LETTER SE + {0xAABC, 0x305C}, //7317 #HIRAGANA LETTER ZE + {0xAABD, 0x305D}, //7318 #HIRAGANA LETTER SO + {0xAABE, 0x305E}, //7319 #HIRAGANA LETTER ZO + {0xAABF, 0x305F}, //7320 #HIRAGANA LETTER TA + {0xAAC0, 0x3060}, //7321 #HIRAGANA LETTER DA + {0xAAC1, 0x3061}, //7322 #HIRAGANA LETTER TI + {0xAAC2, 0x3062}, //7323 #HIRAGANA LETTER DI + {0xAAC3, 0x3063}, //7324 #HIRAGANA LETTER SMALL TU + {0xAAC4, 0x3064}, //7325 #HIRAGANA LETTER TU + {0xAAC5, 0x3065}, //7326 #HIRAGANA LETTER DU + {0xAAC6, 0x3066}, //7327 #HIRAGANA LETTER TE + {0xAAC7, 0x3067}, //7328 #HIRAGANA LETTER DE + {0xAAC8, 0x3068}, //7329 #HIRAGANA LETTER TO + {0xAAC9, 0x3069}, //7330 #HIRAGANA LETTER DO + {0xAACA, 0x306A}, //7331 #HIRAGANA LETTER NA + {0xAACB, 0x306B}, //7332 #HIRAGANA LETTER NI + {0xAACC, 0x306C}, //7333 #HIRAGANA LETTER NU + {0xAACD, 0x306D}, //7334 #HIRAGANA LETTER NE + {0xAACE, 0x306E}, //7335 #HIRAGANA LETTER NO + {0xAACF, 0x306F}, //7336 #HIRAGANA LETTER HA + {0xAAD0, 0x3070}, //7337 #HIRAGANA LETTER BA + {0xAAD1, 0x3071}, //7338 #HIRAGANA LETTER PA + {0xAAD2, 0x3072}, //7339 #HIRAGANA LETTER HI + {0xAAD3, 0x3073}, //7340 #HIRAGANA LETTER BI + {0xAAD4, 0x3074}, //7341 #HIRAGANA LETTER PI + {0xAAD5, 0x3075}, //7342 #HIRAGANA LETTER HU + {0xAAD6, 0x3076}, //7343 #HIRAGANA LETTER BU + {0xAAD7, 0x3077}, //7344 #HIRAGANA LETTER PU + {0xAAD8, 0x3078}, //7345 #HIRAGANA LETTER HE + {0xAAD9, 0x3079}, //7346 #HIRAGANA LETTER BE + {0xAADA, 0x307A}, //7347 #HIRAGANA LETTER PE + {0xAADB, 0x307B}, //7348 #HIRAGANA LETTER HO + {0xAADC, 0x307C}, //7349 #HIRAGANA LETTER BO + {0xAADD, 0x307D}, //7350 #HIRAGANA LETTER PO + {0xAADE, 0x307E}, //7351 #HIRAGANA LETTER MA + {0xAADF, 0x307F}, //7352 #HIRAGANA LETTER MI + {0xAAE0, 0x3080}, //7353 #HIRAGANA LETTER MU + {0xAAE1, 0x3081}, //7354 #HIRAGANA LETTER ME + {0xAAE2, 0x3082}, //7355 #HIRAGANA LETTER MO + {0xAAE3, 0x3083}, //7356 #HIRAGANA LETTER SMALL YA + {0xAAE4, 0x3084}, //7357 #HIRAGANA LETTER YA + {0xAAE5, 0x3085}, //7358 #HIRAGANA LETTER SMALL YU + {0xAAE6, 0x3086}, //7359 #HIRAGANA LETTER YU + {0xAAE7, 0x3087}, //7360 #HIRAGANA LETTER SMALL YO + {0xAAE8, 0x3088}, //7361 #HIRAGANA LETTER YO + {0xAAE9, 0x3089}, //7362 #HIRAGANA LETTER RA + {0xAAEA, 0x308A}, //7363 #HIRAGANA LETTER RI + {0xAAEB, 0x308B}, //7364 #HIRAGANA LETTER RU + {0xAAEC, 0x308C}, //7365 #HIRAGANA LETTER RE + {0xAAED, 0x308D}, //7366 #HIRAGANA LETTER RO + {0xAAEE, 0x308E}, //7367 #HIRAGANA LETTER SMALL WA + {0xAAEF, 0x308F}, //7368 #HIRAGANA LETTER WA + {0xAAF0, 0x3090}, //7369 #HIRAGANA LETTER WI + {0xAAF1, 0x3091}, //7370 #HIRAGANA LETTER WE + {0xAAF2, 0x3092}, //7371 #HIRAGANA LETTER WO + {0xAAF3, 0x3093}, //7372 #HIRAGANA LETTER N + {0xAB41, 0xCC94}, //7373 #HANGUL SYLLABLE CHIEUCH YAE KHIEUKH + {0xAB42, 0xCC95}, //7374 #HANGUL SYLLABLE CHIEUCH YAE THIEUTH + {0xAB43, 0xCC96}, //7375 #HANGUL SYLLABLE CHIEUCH YAE PHIEUPH + {0xAB44, 0xCC97}, //7376 #HANGUL SYLLABLE CHIEUCH YAE HIEUH + {0xAB45, 0xCC9A}, //7377 #HANGUL SYLLABLE CHIEUCH EO SSANGKIYEOK + {0xAB46, 0xCC9B}, //7378 #HANGUL SYLLABLE CHIEUCH EO KIYEOKSIOS + {0xAB47, 0xCC9D}, //7379 #HANGUL SYLLABLE CHIEUCH EO NIEUNCIEUC + {0xAB48, 0xCC9E}, //7380 #HANGUL SYLLABLE CHIEUCH EO NIEUNHIEUH + {0xAB49, 0xCC9F}, //7381 #HANGUL SYLLABLE CHIEUCH EO TIKEUT + {0xAB4A, 0xCCA1}, //7382 #HANGUL SYLLABLE CHIEUCH EO RIEULKIYEOK + {0xAB4B, 0xCCA2}, //7383 #HANGUL SYLLABLE CHIEUCH EO RIEULMIEUM + {0xAB4C, 0xCCA3}, //7384 #HANGUL SYLLABLE CHIEUCH EO RIEULPIEUP + {0xAB4D, 0xCCA4}, //7385 #HANGUL SYLLABLE CHIEUCH EO RIEULSIOS + {0xAB4E, 0xCCA5}, //7386 #HANGUL SYLLABLE CHIEUCH EO RIEULTHIEUTH + {0xAB4F, 0xCCA6}, //7387 #HANGUL SYLLABLE CHIEUCH EO RIEULPHIEUPH + {0xAB50, 0xCCA7}, //7388 #HANGUL SYLLABLE CHIEUCH EO RIEULHIEUH + {0xAB51, 0xCCAA}, //7389 #HANGUL SYLLABLE CHIEUCH EO PIEUPSIOS + {0xAB52, 0xCCAE}, //7390 #HANGUL SYLLABLE CHIEUCH EO CIEUC + {0xAB53, 0xCCAF}, //7391 #HANGUL SYLLABLE CHIEUCH EO CHIEUCH + {0xAB54, 0xCCB0}, //7392 #HANGUL SYLLABLE CHIEUCH EO KHIEUKH + {0xAB55, 0xCCB1}, //7393 #HANGUL SYLLABLE CHIEUCH EO THIEUTH + {0xAB56, 0xCCB2}, //7394 #HANGUL SYLLABLE CHIEUCH EO PHIEUPH + {0xAB57, 0xCCB3}, //7395 #HANGUL SYLLABLE CHIEUCH EO HIEUH + {0xAB58, 0xCCB6}, //7396 #HANGUL SYLLABLE CHIEUCH E SSANGKIYEOK + {0xAB59, 0xCCB7}, //7397 #HANGUL SYLLABLE CHIEUCH E KIYEOKSIOS + {0xAB5A, 0xCCB9}, //7398 #HANGUL SYLLABLE CHIEUCH E NIEUNCIEUC + {0xAB61, 0xCCBA}, //7399 #HANGUL SYLLABLE CHIEUCH E NIEUNHIEUH + {0xAB62, 0xCCBB}, //7400 #HANGUL SYLLABLE CHIEUCH E TIKEUT + {0xAB63, 0xCCBD}, //7401 #HANGUL SYLLABLE CHIEUCH E RIEULKIYEOK + {0xAB64, 0xCCBE}, //7402 #HANGUL SYLLABLE CHIEUCH E RIEULMIEUM + {0xAB65, 0xCCBF}, //7403 #HANGUL SYLLABLE CHIEUCH E RIEULPIEUP + {0xAB66, 0xCCC0}, //7404 #HANGUL SYLLABLE CHIEUCH E RIEULSIOS + {0xAB67, 0xCCC1}, //7405 #HANGUL SYLLABLE CHIEUCH E RIEULTHIEUTH + {0xAB68, 0xCCC2}, //7406 #HANGUL SYLLABLE CHIEUCH E RIEULPHIEUPH + {0xAB69, 0xCCC3}, //7407 #HANGUL SYLLABLE CHIEUCH E RIEULHIEUH + {0xAB6A, 0xCCC6}, //7408 #HANGUL SYLLABLE CHIEUCH E PIEUPSIOS + {0xAB6B, 0xCCC8}, //7409 #HANGUL SYLLABLE CHIEUCH E SSANGSIOS + {0xAB6C, 0xCCCA}, //7410 #HANGUL SYLLABLE CHIEUCH E CIEUC + {0xAB6D, 0xCCCB}, //7411 #HANGUL SYLLABLE CHIEUCH E CHIEUCH + {0xAB6E, 0xCCCC}, //7412 #HANGUL SYLLABLE CHIEUCH E KHIEUKH + {0xAB6F, 0xCCCD}, //7413 #HANGUL SYLLABLE CHIEUCH E THIEUTH + {0xAB70, 0xCCCE}, //7414 #HANGUL SYLLABLE CHIEUCH E PHIEUPH + {0xAB71, 0xCCCF}, //7415 #HANGUL SYLLABLE CHIEUCH E HIEUH + {0xAB72, 0xCCD1}, //7416 #HANGUL SYLLABLE CHIEUCH YEO KIYEOK + {0xAB73, 0xCCD2}, //7417 #HANGUL SYLLABLE CHIEUCH YEO SSANGKIYEOK + {0xAB74, 0xCCD3}, //7418 #HANGUL SYLLABLE CHIEUCH YEO KIYEOKSIOS + {0xAB75, 0xCCD5}, //7419 #HANGUL SYLLABLE CHIEUCH YEO NIEUNCIEUC + {0xAB76, 0xCCD6}, //7420 #HANGUL SYLLABLE CHIEUCH YEO NIEUNHIEUH + {0xAB77, 0xCCD7}, //7421 #HANGUL SYLLABLE CHIEUCH YEO TIKEUT + {0xAB78, 0xCCD8}, //7422 #HANGUL SYLLABLE CHIEUCH YEO RIEUL + {0xAB79, 0xCCD9}, //7423 #HANGUL SYLLABLE CHIEUCH YEO RIEULKIYEOK + {0xAB7A, 0xCCDA}, //7424 #HANGUL SYLLABLE CHIEUCH YEO RIEULMIEUM + {0xAB81, 0xCCDB}, //7425 #HANGUL SYLLABLE CHIEUCH YEO RIEULPIEUP + {0xAB82, 0xCCDC}, //7426 #HANGUL SYLLABLE CHIEUCH YEO RIEULSIOS + {0xAB83, 0xCCDD}, //7427 #HANGUL SYLLABLE CHIEUCH YEO RIEULTHIEUTH + {0xAB84, 0xCCDE}, //7428 #HANGUL SYLLABLE CHIEUCH YEO RIEULPHIEUPH + {0xAB85, 0xCCDF}, //7429 #HANGUL SYLLABLE CHIEUCH YEO RIEULHIEUH + {0xAB86, 0xCCE0}, //7430 #HANGUL SYLLABLE CHIEUCH YEO MIEUM + {0xAB87, 0xCCE1}, //7431 #HANGUL SYLLABLE CHIEUCH YEO PIEUP + {0xAB88, 0xCCE2}, //7432 #HANGUL SYLLABLE CHIEUCH YEO PIEUPSIOS + {0xAB89, 0xCCE3}, //7433 #HANGUL SYLLABLE CHIEUCH YEO SIOS + {0xAB8A, 0xCCE5}, //7434 #HANGUL SYLLABLE CHIEUCH YEO IEUNG + {0xAB8B, 0xCCE6}, //7435 #HANGUL SYLLABLE CHIEUCH YEO CIEUC + {0xAB8C, 0xCCE7}, //7436 #HANGUL SYLLABLE CHIEUCH YEO CHIEUCH + {0xAB8D, 0xCCE8}, //7437 #HANGUL SYLLABLE CHIEUCH YEO KHIEUKH + {0xAB8E, 0xCCE9}, //7438 #HANGUL SYLLABLE CHIEUCH YEO THIEUTH + {0xAB8F, 0xCCEA}, //7439 #HANGUL SYLLABLE CHIEUCH YEO PHIEUPH + {0xAB90, 0xCCEB}, //7440 #HANGUL SYLLABLE CHIEUCH YEO HIEUH + {0xAB91, 0xCCED}, //7441 #HANGUL SYLLABLE CHIEUCH YE KIYEOK + {0xAB92, 0xCCEE}, //7442 #HANGUL SYLLABLE CHIEUCH YE SSANGKIYEOK + {0xAB93, 0xCCEF}, //7443 #HANGUL SYLLABLE CHIEUCH YE KIYEOKSIOS + {0xAB94, 0xCCF1}, //7444 #HANGUL SYLLABLE CHIEUCH YE NIEUNCIEUC + {0xAB95, 0xCCF2}, //7445 #HANGUL SYLLABLE CHIEUCH YE NIEUNHIEUH + {0xAB96, 0xCCF3}, //7446 #HANGUL SYLLABLE CHIEUCH YE TIKEUT + {0xAB97, 0xCCF4}, //7447 #HANGUL SYLLABLE CHIEUCH YE RIEUL + {0xAB98, 0xCCF5}, //7448 #HANGUL SYLLABLE CHIEUCH YE RIEULKIYEOK + {0xAB99, 0xCCF6}, //7449 #HANGUL SYLLABLE CHIEUCH YE RIEULMIEUM + {0xAB9A, 0xCCF7}, //7450 #HANGUL SYLLABLE CHIEUCH YE RIEULPIEUP + {0xAB9B, 0xCCF8}, //7451 #HANGUL SYLLABLE CHIEUCH YE RIEULSIOS + {0xAB9C, 0xCCF9}, //7452 #HANGUL SYLLABLE CHIEUCH YE RIEULTHIEUTH + {0xAB9D, 0xCCFA}, //7453 #HANGUL SYLLABLE CHIEUCH YE RIEULPHIEUPH + {0xAB9E, 0xCCFB}, //7454 #HANGUL SYLLABLE CHIEUCH YE RIEULHIEUH + {0xAB9F, 0xCCFC}, //7455 #HANGUL SYLLABLE CHIEUCH YE MIEUM + {0xABA0, 0xCCFD}, //7456 #HANGUL SYLLABLE CHIEUCH YE PIEUP + {0xABA1, 0x30A1}, //7457 #KATAKANA LETTER SMALL A + {0xABA2, 0x30A2}, //7458 #KATAKANA LETTER A + {0xABA3, 0x30A3}, //7459 #KATAKANA LETTER SMALL I + {0xABA4, 0x30A4}, //7460 #KATAKANA LETTER I + {0xABA5, 0x30A5}, //7461 #KATAKANA LETTER SMALL U + {0xABA6, 0x30A6}, //7462 #KATAKANA LETTER U + {0xABA7, 0x30A7}, //7463 #KATAKANA LETTER SMALL E + {0xABA8, 0x30A8}, //7464 #KATAKANA LETTER E + {0xABA9, 0x30A9}, //7465 #KATAKANA LETTER SMALL O + {0xABAA, 0x30AA}, //7466 #KATAKANA LETTER O + {0xABAB, 0x30AB}, //7467 #KATAKANA LETTER KA + {0xABAC, 0x30AC}, //7468 #KATAKANA LETTER GA + {0xABAD, 0x30AD}, //7469 #KATAKANA LETTER KI + {0xABAE, 0x30AE}, //7470 #KATAKANA LETTER GI + {0xABAF, 0x30AF}, //7471 #KATAKANA LETTER KU + {0xABB0, 0x30B0}, //7472 #KATAKANA LETTER GU + {0xABB1, 0x30B1}, //7473 #KATAKANA LETTER KE + {0xABB2, 0x30B2}, //7474 #KATAKANA LETTER GE + {0xABB3, 0x30B3}, //7475 #KATAKANA LETTER KO + {0xABB4, 0x30B4}, //7476 #KATAKANA LETTER GO + {0xABB5, 0x30B5}, //7477 #KATAKANA LETTER SA + {0xABB6, 0x30B6}, //7478 #KATAKANA LETTER ZA + {0xABB7, 0x30B7}, //7479 #KATAKANA LETTER SI + {0xABB8, 0x30B8}, //7480 #KATAKANA LETTER ZI + {0xABB9, 0x30B9}, //7481 #KATAKANA LETTER SU + {0xABBA, 0x30BA}, //7482 #KATAKANA LETTER ZU + {0xABBB, 0x30BB}, //7483 #KATAKANA LETTER SE + {0xABBC, 0x30BC}, //7484 #KATAKANA LETTER ZE + {0xABBD, 0x30BD}, //7485 #KATAKANA LETTER SO + {0xABBE, 0x30BE}, //7486 #KATAKANA LETTER ZO + {0xABBF, 0x30BF}, //7487 #KATAKANA LETTER TA + {0xABC0, 0x30C0}, //7488 #KATAKANA LETTER DA + {0xABC1, 0x30C1}, //7489 #KATAKANA LETTER TI + {0xABC2, 0x30C2}, //7490 #KATAKANA LETTER DI + {0xABC3, 0x30C3}, //7491 #KATAKANA LETTER SMALL TU + {0xABC4, 0x30C4}, //7492 #KATAKANA LETTER TU + {0xABC5, 0x30C5}, //7493 #KATAKANA LETTER DU + {0xABC6, 0x30C6}, //7494 #KATAKANA LETTER TE + {0xABC7, 0x30C7}, //7495 #KATAKANA LETTER DE + {0xABC8, 0x30C8}, //7496 #KATAKANA LETTER TO + {0xABC9, 0x30C9}, //7497 #KATAKANA LETTER DO + {0xABCA, 0x30CA}, //7498 #KATAKANA LETTER NA + {0xABCB, 0x30CB}, //7499 #KATAKANA LETTER NI + {0xABCC, 0x30CC}, //7500 #KATAKANA LETTER NU + {0xABCD, 0x30CD}, //7501 #KATAKANA LETTER NE + {0xABCE, 0x30CE}, //7502 #KATAKANA LETTER NO + {0xABCF, 0x30CF}, //7503 #KATAKANA LETTER HA + {0xABD0, 0x30D0}, //7504 #KATAKANA LETTER BA + {0xABD1, 0x30D1}, //7505 #KATAKANA LETTER PA + {0xABD2, 0x30D2}, //7506 #KATAKANA LETTER HI + {0xABD3, 0x30D3}, //7507 #KATAKANA LETTER BI + {0xABD4, 0x30D4}, //7508 #KATAKANA LETTER PI + {0xABD5, 0x30D5}, //7509 #KATAKANA LETTER HU + {0xABD6, 0x30D6}, //7510 #KATAKANA LETTER BU + {0xABD7, 0x30D7}, //7511 #KATAKANA LETTER PU + {0xABD8, 0x30D8}, //7512 #KATAKANA LETTER HE + {0xABD9, 0x30D9}, //7513 #KATAKANA LETTER BE + {0xABDA, 0x30DA}, //7514 #KATAKANA LETTER PE + {0xABDB, 0x30DB}, //7515 #KATAKANA LETTER HO + {0xABDC, 0x30DC}, //7516 #KATAKANA LETTER BO + {0xABDD, 0x30DD}, //7517 #KATAKANA LETTER PO + {0xABDE, 0x30DE}, //7518 #KATAKANA LETTER MA + {0xABDF, 0x30DF}, //7519 #KATAKANA LETTER MI + {0xABE0, 0x30E0}, //7520 #KATAKANA LETTER MU + {0xABE1, 0x30E1}, //7521 #KATAKANA LETTER ME + {0xABE2, 0x30E2}, //7522 #KATAKANA LETTER MO + {0xABE3, 0x30E3}, //7523 #KATAKANA LETTER SMALL YA + {0xABE4, 0x30E4}, //7524 #KATAKANA LETTER YA + {0xABE5, 0x30E5}, //7525 #KATAKANA LETTER SMALL YU + {0xABE6, 0x30E6}, //7526 #KATAKANA LETTER YU + {0xABE7, 0x30E7}, //7527 #KATAKANA LETTER SMALL YO + {0xABE8, 0x30E8}, //7528 #KATAKANA LETTER YO + {0xABE9, 0x30E9}, //7529 #KATAKANA LETTER RA + {0xABEA, 0x30EA}, //7530 #KATAKANA LETTER RI + {0xABEB, 0x30EB}, //7531 #KATAKANA LETTER RU + {0xABEC, 0x30EC}, //7532 #KATAKANA LETTER RE + {0xABED, 0x30ED}, //7533 #KATAKANA LETTER RO + {0xABEE, 0x30EE}, //7534 #KATAKANA LETTER SMALL WA + {0xABEF, 0x30EF}, //7535 #KATAKANA LETTER WA + {0xABF0, 0x30F0}, //7536 #KATAKANA LETTER WI + {0xABF1, 0x30F1}, //7537 #KATAKANA LETTER WE + {0xABF2, 0x30F2}, //7538 #KATAKANA LETTER WO + {0xABF3, 0x30F3}, //7539 #KATAKANA LETTER N + {0xABF4, 0x30F4}, //7540 #KATAKANA LETTER VU + {0xABF5, 0x30F5}, //7541 #KATAKANA LETTER SMALL KA + {0xABF6, 0x30F6}, //7542 #KATAKANA LETTER SMALL KE + {0xAC41, 0xCCFE}, //7543 #HANGUL SYLLABLE CHIEUCH YE PIEUPSIOS + {0xAC42, 0xCCFF}, //7544 #HANGUL SYLLABLE CHIEUCH YE SIOS + {0xAC43, 0xCD00}, //7545 #HANGUL SYLLABLE CHIEUCH YE SSANGSIOS + {0xAC44, 0xCD02}, //7546 #HANGUL SYLLABLE CHIEUCH YE CIEUC + {0xAC45, 0xCD03}, //7547 #HANGUL SYLLABLE CHIEUCH YE CHIEUCH + {0xAC46, 0xCD04}, //7548 #HANGUL SYLLABLE CHIEUCH YE KHIEUKH + {0xAC47, 0xCD05}, //7549 #HANGUL SYLLABLE CHIEUCH YE THIEUTH + {0xAC48, 0xCD06}, //7550 #HANGUL SYLLABLE CHIEUCH YE PHIEUPH + {0xAC49, 0xCD07}, //7551 #HANGUL SYLLABLE CHIEUCH YE HIEUH + {0xAC4A, 0xCD0A}, //7552 #HANGUL SYLLABLE CHIEUCH O SSANGKIYEOK + {0xAC4B, 0xCD0B}, //7553 #HANGUL SYLLABLE CHIEUCH O KIYEOKSIOS + {0xAC4C, 0xCD0D}, //7554 #HANGUL SYLLABLE CHIEUCH O NIEUNCIEUC + {0xAC4D, 0xCD0E}, //7555 #HANGUL SYLLABLE CHIEUCH O NIEUNHIEUH + {0xAC4E, 0xCD0F}, //7556 #HANGUL SYLLABLE CHIEUCH O TIKEUT + {0xAC4F, 0xCD11}, //7557 #HANGUL SYLLABLE CHIEUCH O RIEULKIYEOK + {0xAC50, 0xCD12}, //7558 #HANGUL SYLLABLE CHIEUCH O RIEULMIEUM + {0xAC51, 0xCD13}, //7559 #HANGUL SYLLABLE CHIEUCH O RIEULPIEUP + {0xAC52, 0xCD14}, //7560 #HANGUL SYLLABLE CHIEUCH O RIEULSIOS + {0xAC53, 0xCD15}, //7561 #HANGUL SYLLABLE CHIEUCH O RIEULTHIEUTH + {0xAC54, 0xCD16}, //7562 #HANGUL SYLLABLE CHIEUCH O RIEULPHIEUPH + {0xAC55, 0xCD17}, //7563 #HANGUL SYLLABLE CHIEUCH O RIEULHIEUH + {0xAC56, 0xCD1A}, //7564 #HANGUL SYLLABLE CHIEUCH O PIEUPSIOS + {0xAC57, 0xCD1C}, //7565 #HANGUL SYLLABLE CHIEUCH O SSANGSIOS + {0xAC58, 0xCD1E}, //7566 #HANGUL SYLLABLE CHIEUCH O CIEUC + {0xAC59, 0xCD1F}, //7567 #HANGUL SYLLABLE CHIEUCH O CHIEUCH + {0xAC5A, 0xCD20}, //7568 #HANGUL SYLLABLE CHIEUCH O KHIEUKH + {0xAC61, 0xCD21}, //7569 #HANGUL SYLLABLE CHIEUCH O THIEUTH + {0xAC62, 0xCD22}, //7570 #HANGUL SYLLABLE CHIEUCH O PHIEUPH + {0xAC63, 0xCD23}, //7571 #HANGUL SYLLABLE CHIEUCH O HIEUH + {0xAC64, 0xCD25}, //7572 #HANGUL SYLLABLE CHIEUCH WA KIYEOK + {0xAC65, 0xCD26}, //7573 #HANGUL SYLLABLE CHIEUCH WA SSANGKIYEOK + {0xAC66, 0xCD27}, //7574 #HANGUL SYLLABLE CHIEUCH WA KIYEOKSIOS + {0xAC67, 0xCD29}, //7575 #HANGUL SYLLABLE CHIEUCH WA NIEUNCIEUC + {0xAC68, 0xCD2A}, //7576 #HANGUL SYLLABLE CHIEUCH WA NIEUNHIEUH + {0xAC69, 0xCD2B}, //7577 #HANGUL SYLLABLE CHIEUCH WA TIKEUT + {0xAC6A, 0xCD2D}, //7578 #HANGUL SYLLABLE CHIEUCH WA RIEULKIYEOK + {0xAC6B, 0xCD2E}, //7579 #HANGUL SYLLABLE CHIEUCH WA RIEULMIEUM + {0xAC6C, 0xCD2F}, //7580 #HANGUL SYLLABLE CHIEUCH WA RIEULPIEUP + {0xAC6D, 0xCD30}, //7581 #HANGUL SYLLABLE CHIEUCH WA RIEULSIOS + {0xAC6E, 0xCD31}, //7582 #HANGUL SYLLABLE CHIEUCH WA RIEULTHIEUTH + {0xAC6F, 0xCD32}, //7583 #HANGUL SYLLABLE CHIEUCH WA RIEULPHIEUPH + {0xAC70, 0xCD33}, //7584 #HANGUL SYLLABLE CHIEUCH WA RIEULHIEUH + {0xAC71, 0xCD34}, //7585 #HANGUL SYLLABLE CHIEUCH WA MIEUM + {0xAC72, 0xCD35}, //7586 #HANGUL SYLLABLE CHIEUCH WA PIEUP + {0xAC73, 0xCD36}, //7587 #HANGUL SYLLABLE CHIEUCH WA PIEUPSIOS + {0xAC74, 0xCD37}, //7588 #HANGUL SYLLABLE CHIEUCH WA SIOS + {0xAC75, 0xCD38}, //7589 #HANGUL SYLLABLE CHIEUCH WA SSANGSIOS + {0xAC76, 0xCD3A}, //7590 #HANGUL SYLLABLE CHIEUCH WA CIEUC + {0xAC77, 0xCD3B}, //7591 #HANGUL SYLLABLE CHIEUCH WA CHIEUCH + {0xAC78, 0xCD3C}, //7592 #HANGUL SYLLABLE CHIEUCH WA KHIEUKH + {0xAC79, 0xCD3D}, //7593 #HANGUL SYLLABLE CHIEUCH WA THIEUTH + {0xAC7A, 0xCD3E}, //7594 #HANGUL SYLLABLE CHIEUCH WA PHIEUPH + {0xAC81, 0xCD3F}, //7595 #HANGUL SYLLABLE CHIEUCH WA HIEUH + {0xAC82, 0xCD40}, //7596 #HANGUL SYLLABLE CHIEUCH WAE + {0xAC83, 0xCD41}, //7597 #HANGUL SYLLABLE CHIEUCH WAE KIYEOK + {0xAC84, 0xCD42}, //7598 #HANGUL SYLLABLE CHIEUCH WAE SSANGKIYEOK + {0xAC85, 0xCD43}, //7599 #HANGUL SYLLABLE CHIEUCH WAE KIYEOKSIOS + {0xAC86, 0xCD44}, //7600 #HANGUL SYLLABLE CHIEUCH WAE NIEUN + {0xAC87, 0xCD45}, //7601 #HANGUL SYLLABLE CHIEUCH WAE NIEUNCIEUC + {0xAC88, 0xCD46}, //7602 #HANGUL SYLLABLE CHIEUCH WAE NIEUNHIEUH + {0xAC89, 0xCD47}, //7603 #HANGUL SYLLABLE CHIEUCH WAE TIKEUT + {0xAC8A, 0xCD48}, //7604 #HANGUL SYLLABLE CHIEUCH WAE RIEUL + {0xAC8B, 0xCD49}, //7605 #HANGUL SYLLABLE CHIEUCH WAE RIEULKIYEOK + {0xAC8C, 0xCD4A}, //7606 #HANGUL SYLLABLE CHIEUCH WAE RIEULMIEUM + {0xAC8D, 0xCD4B}, //7607 #HANGUL SYLLABLE CHIEUCH WAE RIEULPIEUP + {0xAC8E, 0xCD4C}, //7608 #HANGUL SYLLABLE CHIEUCH WAE RIEULSIOS + {0xAC8F, 0xCD4D}, //7609 #HANGUL SYLLABLE CHIEUCH WAE RIEULTHIEUTH + {0xAC90, 0xCD4E}, //7610 #HANGUL SYLLABLE CHIEUCH WAE RIEULPHIEUPH + {0xAC91, 0xCD4F}, //7611 #HANGUL SYLLABLE CHIEUCH WAE RIEULHIEUH + {0xAC92, 0xCD50}, //7612 #HANGUL SYLLABLE CHIEUCH WAE MIEUM + {0xAC93, 0xCD51}, //7613 #HANGUL SYLLABLE CHIEUCH WAE PIEUP + {0xAC94, 0xCD52}, //7614 #HANGUL SYLLABLE CHIEUCH WAE PIEUPSIOS + {0xAC95, 0xCD53}, //7615 #HANGUL SYLLABLE CHIEUCH WAE SIOS + {0xAC96, 0xCD54}, //7616 #HANGUL SYLLABLE CHIEUCH WAE SSANGSIOS + {0xAC97, 0xCD55}, //7617 #HANGUL SYLLABLE CHIEUCH WAE IEUNG + {0xAC98, 0xCD56}, //7618 #HANGUL SYLLABLE CHIEUCH WAE CIEUC + {0xAC99, 0xCD57}, //7619 #HANGUL SYLLABLE CHIEUCH WAE CHIEUCH + {0xAC9A, 0xCD58}, //7620 #HANGUL SYLLABLE CHIEUCH WAE KHIEUKH + {0xAC9B, 0xCD59}, //7621 #HANGUL SYLLABLE CHIEUCH WAE THIEUTH + {0xAC9C, 0xCD5A}, //7622 #HANGUL SYLLABLE CHIEUCH WAE PHIEUPH + {0xAC9D, 0xCD5B}, //7623 #HANGUL SYLLABLE CHIEUCH WAE HIEUH + {0xAC9E, 0xCD5D}, //7624 #HANGUL SYLLABLE CHIEUCH OE KIYEOK + {0xAC9F, 0xCD5E}, //7625 #HANGUL SYLLABLE CHIEUCH OE SSANGKIYEOK + {0xACA0, 0xCD5F}, //7626 #HANGUL SYLLABLE CHIEUCH OE KIYEOKSIOS + {0xACA1, 0x0410}, //7627 #CYRILLIC CAPITAL LETTER A + {0xACA2, 0x0411}, //7628 #CYRILLIC CAPITAL LETTER BE + {0xACA3, 0x0412}, //7629 #CYRILLIC CAPITAL LETTER VE + {0xACA4, 0x0413}, //7630 #CYRILLIC CAPITAL LETTER GHE + {0xACA5, 0x0414}, //7631 #CYRILLIC CAPITAL LETTER DE + {0xACA6, 0x0415}, //7632 #CYRILLIC CAPITAL LETTER IE + {0xACA7, 0x0401}, //7633 #CYRILLIC CAPITAL LETTER IO + {0xACA8, 0x0416}, //7634 #CYRILLIC CAPITAL LETTER ZHE + {0xACA9, 0x0417}, //7635 #CYRILLIC CAPITAL LETTER ZE + {0xACAA, 0x0418}, //7636 #CYRILLIC CAPITAL LETTER I + {0xACAB, 0x0419}, //7637 #CYRILLIC CAPITAL LETTER SHORT I + {0xACAC, 0x041A}, //7638 #CYRILLIC CAPITAL LETTER KA + {0xACAD, 0x041B}, //7639 #CYRILLIC CAPITAL LETTER EL + {0xACAE, 0x041C}, //7640 #CYRILLIC CAPITAL LETTER EM + {0xACAF, 0x041D}, //7641 #CYRILLIC CAPITAL LETTER EN + {0xACB0, 0x041E}, //7642 #CYRILLIC CAPITAL LETTER O + {0xACB1, 0x041F}, //7643 #CYRILLIC CAPITAL LETTER PE + {0xACB2, 0x0420}, //7644 #CYRILLIC CAPITAL LETTER ER + {0xACB3, 0x0421}, //7645 #CYRILLIC CAPITAL LETTER ES + {0xACB4, 0x0422}, //7646 #CYRILLIC CAPITAL LETTER TE + {0xACB5, 0x0423}, //7647 #CYRILLIC CAPITAL LETTER U + {0xACB6, 0x0424}, //7648 #CYRILLIC CAPITAL LETTER EF + {0xACB7, 0x0425}, //7649 #CYRILLIC CAPITAL LETTER HA + {0xACB8, 0x0426}, //7650 #CYRILLIC CAPITAL LETTER TSE + {0xACB9, 0x0427}, //7651 #CYRILLIC CAPITAL LETTER CHE + {0xACBA, 0x0428}, //7652 #CYRILLIC CAPITAL LETTER SHA + {0xACBB, 0x0429}, //7653 #CYRILLIC CAPITAL LETTER SHCHA + {0xACBC, 0x042A}, //7654 #CYRILLIC CAPITAL LETTER HARD SIGN + {0xACBD, 0x042B}, //7655 #CYRILLIC CAPITAL LETTER YERU + {0xACBE, 0x042C}, //7656 #CYRILLIC CAPITAL LETTER SOFT SIGN + {0xACBF, 0x042D}, //7657 #CYRILLIC CAPITAL LETTER E + {0xACC0, 0x042E}, //7658 #CYRILLIC CAPITAL LETTER YU + {0xACC1, 0x042F}, //7659 #CYRILLIC CAPITAL LETTER YA + {0xACD1, 0x0430}, //7660 #CYRILLIC SMALL LETTER A + {0xACD2, 0x0431}, //7661 #CYRILLIC SMALL LETTER BE + {0xACD3, 0x0432}, //7662 #CYRILLIC SMALL LETTER VE + {0xACD4, 0x0433}, //7663 #CYRILLIC SMALL LETTER GHE + {0xACD5, 0x0434}, //7664 #CYRILLIC SMALL LETTER DE + {0xACD6, 0x0435}, //7665 #CYRILLIC SMALL LETTER IE + {0xACD7, 0x0451}, //7666 #CYRILLIC SMALL LETTER IO + {0xACD8, 0x0436}, //7667 #CYRILLIC SMALL LETTER ZHE + {0xACD9, 0x0437}, //7668 #CYRILLIC SMALL LETTER ZE + {0xACDA, 0x0438}, //7669 #CYRILLIC SMALL LETTER I + {0xACDB, 0x0439}, //7670 #CYRILLIC SMALL LETTER SHORT I + {0xACDC, 0x043A}, //7671 #CYRILLIC SMALL LETTER KA + {0xACDD, 0x043B}, //7672 #CYRILLIC SMALL LETTER EL + {0xACDE, 0x043C}, //7673 #CYRILLIC SMALL LETTER EM + {0xACDF, 0x043D}, //7674 #CYRILLIC SMALL LETTER EN + {0xACE0, 0x043E}, //7675 #CYRILLIC SMALL LETTER O + {0xACE1, 0x043F}, //7676 #CYRILLIC SMALL LETTER PE + {0xACE2, 0x0440}, //7677 #CYRILLIC SMALL LETTER ER + {0xACE3, 0x0441}, //7678 #CYRILLIC SMALL LETTER ES + {0xACE4, 0x0442}, //7679 #CYRILLIC SMALL LETTER TE + {0xACE5, 0x0443}, //7680 #CYRILLIC SMALL LETTER U + {0xACE6, 0x0444}, //7681 #CYRILLIC SMALL LETTER EF + {0xACE7, 0x0445}, //7682 #CYRILLIC SMALL LETTER HA + {0xACE8, 0x0446}, //7683 #CYRILLIC SMALL LETTER TSE + {0xACE9, 0x0447}, //7684 #CYRILLIC SMALL LETTER CHE + {0xACEA, 0x0448}, //7685 #CYRILLIC SMALL LETTER SHA + {0xACEB, 0x0449}, //7686 #CYRILLIC SMALL LETTER SHCHA + {0xACEC, 0x044A}, //7687 #CYRILLIC SMALL LETTER HARD SIGN + {0xACED, 0x044B}, //7688 #CYRILLIC SMALL LETTER YERU + {0xACEE, 0x044C}, //7689 #CYRILLIC SMALL LETTER SOFT SIGN + {0xACEF, 0x044D}, //7690 #CYRILLIC SMALL LETTER E + {0xACF0, 0x044E}, //7691 #CYRILLIC SMALL LETTER YU + {0xACF1, 0x044F}, //7692 #CYRILLIC SMALL LETTER YA + {0xAD41, 0xCD61}, //7693 #HANGUL SYLLABLE CHIEUCH OE NIEUNCIEUC + {0xAD42, 0xCD62}, //7694 #HANGUL SYLLABLE CHIEUCH OE NIEUNHIEUH + {0xAD43, 0xCD63}, //7695 #HANGUL SYLLABLE CHIEUCH OE TIKEUT + {0xAD44, 0xCD65}, //7696 #HANGUL SYLLABLE CHIEUCH OE RIEULKIYEOK + {0xAD45, 0xCD66}, //7697 #HANGUL SYLLABLE CHIEUCH OE RIEULMIEUM + {0xAD46, 0xCD67}, //7698 #HANGUL SYLLABLE CHIEUCH OE RIEULPIEUP + {0xAD47, 0xCD68}, //7699 #HANGUL SYLLABLE CHIEUCH OE RIEULSIOS + {0xAD48, 0xCD69}, //7700 #HANGUL SYLLABLE CHIEUCH OE RIEULTHIEUTH + {0xAD49, 0xCD6A}, //7701 #HANGUL SYLLABLE CHIEUCH OE RIEULPHIEUPH + {0xAD4A, 0xCD6B}, //7702 #HANGUL SYLLABLE CHIEUCH OE RIEULHIEUH + {0xAD4B, 0xCD6E}, //7703 #HANGUL SYLLABLE CHIEUCH OE PIEUPSIOS + {0xAD4C, 0xCD70}, //7704 #HANGUL SYLLABLE CHIEUCH OE SSANGSIOS + {0xAD4D, 0xCD72}, //7705 #HANGUL SYLLABLE CHIEUCH OE CIEUC + {0xAD4E, 0xCD73}, //7706 #HANGUL SYLLABLE CHIEUCH OE CHIEUCH + {0xAD4F, 0xCD74}, //7707 #HANGUL SYLLABLE CHIEUCH OE KHIEUKH + {0xAD50, 0xCD75}, //7708 #HANGUL SYLLABLE CHIEUCH OE THIEUTH + {0xAD51, 0xCD76}, //7709 #HANGUL SYLLABLE CHIEUCH OE PHIEUPH + {0xAD52, 0xCD77}, //7710 #HANGUL SYLLABLE CHIEUCH OE HIEUH + {0xAD53, 0xCD79}, //7711 #HANGUL SYLLABLE CHIEUCH YO KIYEOK + {0xAD54, 0xCD7A}, //7712 #HANGUL SYLLABLE CHIEUCH YO SSANGKIYEOK + {0xAD55, 0xCD7B}, //7713 #HANGUL SYLLABLE CHIEUCH YO KIYEOKSIOS + {0xAD56, 0xCD7C}, //7714 #HANGUL SYLLABLE CHIEUCH YO NIEUN + {0xAD57, 0xCD7D}, //7715 #HANGUL SYLLABLE CHIEUCH YO NIEUNCIEUC + {0xAD58, 0xCD7E}, //7716 #HANGUL SYLLABLE CHIEUCH YO NIEUNHIEUH + {0xAD59, 0xCD7F}, //7717 #HANGUL SYLLABLE CHIEUCH YO TIKEUT + {0xAD5A, 0xCD80}, //7718 #HANGUL SYLLABLE CHIEUCH YO RIEUL + {0xAD61, 0xCD81}, //7719 #HANGUL SYLLABLE CHIEUCH YO RIEULKIYEOK + {0xAD62, 0xCD82}, //7720 #HANGUL SYLLABLE CHIEUCH YO RIEULMIEUM + {0xAD63, 0xCD83}, //7721 #HANGUL SYLLABLE CHIEUCH YO RIEULPIEUP + {0xAD64, 0xCD84}, //7722 #HANGUL SYLLABLE CHIEUCH YO RIEULSIOS + {0xAD65, 0xCD85}, //7723 #HANGUL SYLLABLE CHIEUCH YO RIEULTHIEUTH + {0xAD66, 0xCD86}, //7724 #HANGUL SYLLABLE CHIEUCH YO RIEULPHIEUPH + {0xAD67, 0xCD87}, //7725 #HANGUL SYLLABLE CHIEUCH YO RIEULHIEUH + {0xAD68, 0xCD89}, //7726 #HANGUL SYLLABLE CHIEUCH YO PIEUP + {0xAD69, 0xCD8A}, //7727 #HANGUL SYLLABLE CHIEUCH YO PIEUPSIOS + {0xAD6A, 0xCD8B}, //7728 #HANGUL SYLLABLE CHIEUCH YO SIOS + {0xAD6B, 0xCD8C}, //7729 #HANGUL SYLLABLE CHIEUCH YO SSANGSIOS + {0xAD6C, 0xCD8D}, //7730 #HANGUL SYLLABLE CHIEUCH YO IEUNG + {0xAD6D, 0xCD8E}, //7731 #HANGUL SYLLABLE CHIEUCH YO CIEUC + {0xAD6E, 0xCD8F}, //7732 #HANGUL SYLLABLE CHIEUCH YO CHIEUCH + {0xAD6F, 0xCD90}, //7733 #HANGUL SYLLABLE CHIEUCH YO KHIEUKH + {0xAD70, 0xCD91}, //7734 #HANGUL SYLLABLE CHIEUCH YO THIEUTH + {0xAD71, 0xCD92}, //7735 #HANGUL SYLLABLE CHIEUCH YO PHIEUPH + {0xAD72, 0xCD93}, //7736 #HANGUL SYLLABLE CHIEUCH YO HIEUH + {0xAD73, 0xCD96}, //7737 #HANGUL SYLLABLE CHIEUCH U SSANGKIYEOK + {0xAD74, 0xCD97}, //7738 #HANGUL SYLLABLE CHIEUCH U KIYEOKSIOS + {0xAD75, 0xCD99}, //7739 #HANGUL SYLLABLE CHIEUCH U NIEUNCIEUC + {0xAD76, 0xCD9A}, //7740 #HANGUL SYLLABLE CHIEUCH U NIEUNHIEUH + {0xAD77, 0xCD9B}, //7741 #HANGUL SYLLABLE CHIEUCH U TIKEUT + {0xAD78, 0xCD9D}, //7742 #HANGUL SYLLABLE CHIEUCH U RIEULKIYEOK + {0xAD79, 0xCD9E}, //7743 #HANGUL SYLLABLE CHIEUCH U RIEULMIEUM + {0xAD7A, 0xCD9F}, //7744 #HANGUL SYLLABLE CHIEUCH U RIEULPIEUP + {0xAD81, 0xCDA0}, //7745 #HANGUL SYLLABLE CHIEUCH U RIEULSIOS + {0xAD82, 0xCDA1}, //7746 #HANGUL SYLLABLE CHIEUCH U RIEULTHIEUTH + {0xAD83, 0xCDA2}, //7747 #HANGUL SYLLABLE CHIEUCH U RIEULPHIEUPH + {0xAD84, 0xCDA3}, //7748 #HANGUL SYLLABLE CHIEUCH U RIEULHIEUH + {0xAD85, 0xCDA6}, //7749 #HANGUL SYLLABLE CHIEUCH U PIEUPSIOS + {0xAD86, 0xCDA8}, //7750 #HANGUL SYLLABLE CHIEUCH U SSANGSIOS + {0xAD87, 0xCDAA}, //7751 #HANGUL SYLLABLE CHIEUCH U CIEUC + {0xAD88, 0xCDAB}, //7752 #HANGUL SYLLABLE CHIEUCH U CHIEUCH + {0xAD89, 0xCDAC}, //7753 #HANGUL SYLLABLE CHIEUCH U KHIEUKH + {0xAD8A, 0xCDAD}, //7754 #HANGUL SYLLABLE CHIEUCH U THIEUTH + {0xAD8B, 0xCDAE}, //7755 #HANGUL SYLLABLE CHIEUCH U PHIEUPH + {0xAD8C, 0xCDAF}, //7756 #HANGUL SYLLABLE CHIEUCH U HIEUH + {0xAD8D, 0xCDB1}, //7757 #HANGUL SYLLABLE CHIEUCH WEO KIYEOK + {0xAD8E, 0xCDB2}, //7758 #HANGUL SYLLABLE CHIEUCH WEO SSANGKIYEOK + {0xAD8F, 0xCDB3}, //7759 #HANGUL SYLLABLE CHIEUCH WEO KIYEOKSIOS + {0xAD90, 0xCDB4}, //7760 #HANGUL SYLLABLE CHIEUCH WEO NIEUN + {0xAD91, 0xCDB5}, //7761 #HANGUL SYLLABLE CHIEUCH WEO NIEUNCIEUC + {0xAD92, 0xCDB6}, //7762 #HANGUL SYLLABLE CHIEUCH WEO NIEUNHIEUH + {0xAD93, 0xCDB7}, //7763 #HANGUL SYLLABLE CHIEUCH WEO TIKEUT + {0xAD94, 0xCDB8}, //7764 #HANGUL SYLLABLE CHIEUCH WEO RIEUL + {0xAD95, 0xCDB9}, //7765 #HANGUL SYLLABLE CHIEUCH WEO RIEULKIYEOK + {0xAD96, 0xCDBA}, //7766 #HANGUL SYLLABLE CHIEUCH WEO RIEULMIEUM + {0xAD97, 0xCDBB}, //7767 #HANGUL SYLLABLE CHIEUCH WEO RIEULPIEUP + {0xAD98, 0xCDBC}, //7768 #HANGUL SYLLABLE CHIEUCH WEO RIEULSIOS + {0xAD99, 0xCDBD}, //7769 #HANGUL SYLLABLE CHIEUCH WEO RIEULTHIEUTH + {0xAD9A, 0xCDBE}, //7770 #HANGUL SYLLABLE CHIEUCH WEO RIEULPHIEUPH + {0xAD9B, 0xCDBF}, //7771 #HANGUL SYLLABLE CHIEUCH WEO RIEULHIEUH + {0xAD9C, 0xCDC0}, //7772 #HANGUL SYLLABLE CHIEUCH WEO MIEUM + {0xAD9D, 0xCDC1}, //7773 #HANGUL SYLLABLE CHIEUCH WEO PIEUP + {0xAD9E, 0xCDC2}, //7774 #HANGUL SYLLABLE CHIEUCH WEO PIEUPSIOS + {0xAD9F, 0xCDC3}, //7775 #HANGUL SYLLABLE CHIEUCH WEO SIOS + {0xADA0, 0xCDC5}, //7776 #HANGUL SYLLABLE CHIEUCH WEO IEUNG + {0xAE41, 0xCDC6}, //7777 #HANGUL SYLLABLE CHIEUCH WEO CIEUC + {0xAE42, 0xCDC7}, //7778 #HANGUL SYLLABLE CHIEUCH WEO CHIEUCH + {0xAE43, 0xCDC8}, //7779 #HANGUL SYLLABLE CHIEUCH WEO KHIEUKH + {0xAE44, 0xCDC9}, //7780 #HANGUL SYLLABLE CHIEUCH WEO THIEUTH + {0xAE45, 0xCDCA}, //7781 #HANGUL SYLLABLE CHIEUCH WEO PHIEUPH + {0xAE46, 0xCDCB}, //7782 #HANGUL SYLLABLE CHIEUCH WEO HIEUH + {0xAE47, 0xCDCD}, //7783 #HANGUL SYLLABLE CHIEUCH WE KIYEOK + {0xAE48, 0xCDCE}, //7784 #HANGUL SYLLABLE CHIEUCH WE SSANGKIYEOK + {0xAE49, 0xCDCF}, //7785 #HANGUL SYLLABLE CHIEUCH WE KIYEOKSIOS + {0xAE4A, 0xCDD1}, //7786 #HANGUL SYLLABLE CHIEUCH WE NIEUNCIEUC + {0xAE4B, 0xCDD2}, //7787 #HANGUL SYLLABLE CHIEUCH WE NIEUNHIEUH + {0xAE4C, 0xCDD3}, //7788 #HANGUL SYLLABLE CHIEUCH WE TIKEUT + {0xAE4D, 0xCDD4}, //7789 #HANGUL SYLLABLE CHIEUCH WE RIEUL + {0xAE4E, 0xCDD5}, //7790 #HANGUL SYLLABLE CHIEUCH WE RIEULKIYEOK + {0xAE4F, 0xCDD6}, //7791 #HANGUL SYLLABLE CHIEUCH WE RIEULMIEUM + {0xAE50, 0xCDD7}, //7792 #HANGUL SYLLABLE CHIEUCH WE RIEULPIEUP + {0xAE51, 0xCDD8}, //7793 #HANGUL SYLLABLE CHIEUCH WE RIEULSIOS + {0xAE52, 0xCDD9}, //7794 #HANGUL SYLLABLE CHIEUCH WE RIEULTHIEUTH + {0xAE53, 0xCDDA}, //7795 #HANGUL SYLLABLE CHIEUCH WE RIEULPHIEUPH + {0xAE54, 0xCDDB}, //7796 #HANGUL SYLLABLE CHIEUCH WE RIEULHIEUH + {0xAE55, 0xCDDC}, //7797 #HANGUL SYLLABLE CHIEUCH WE MIEUM + {0xAE56, 0xCDDD}, //7798 #HANGUL SYLLABLE CHIEUCH WE PIEUP + {0xAE57, 0xCDDE}, //7799 #HANGUL SYLLABLE CHIEUCH WE PIEUPSIOS + {0xAE58, 0xCDDF}, //7800 #HANGUL SYLLABLE CHIEUCH WE SIOS + {0xAE59, 0xCDE0}, //7801 #HANGUL SYLLABLE CHIEUCH WE SSANGSIOS + {0xAE5A, 0xCDE1}, //7802 #HANGUL SYLLABLE CHIEUCH WE IEUNG + {0xAE61, 0xCDE2}, //7803 #HANGUL SYLLABLE CHIEUCH WE CIEUC + {0xAE62, 0xCDE3}, //7804 #HANGUL SYLLABLE CHIEUCH WE CHIEUCH + {0xAE63, 0xCDE4}, //7805 #HANGUL SYLLABLE CHIEUCH WE KHIEUKH + {0xAE64, 0xCDE5}, //7806 #HANGUL SYLLABLE CHIEUCH WE THIEUTH + {0xAE65, 0xCDE6}, //7807 #HANGUL SYLLABLE CHIEUCH WE PHIEUPH + {0xAE66, 0xCDE7}, //7808 #HANGUL SYLLABLE CHIEUCH WE HIEUH + {0xAE67, 0xCDE9}, //7809 #HANGUL SYLLABLE CHIEUCH WI KIYEOK + {0xAE68, 0xCDEA}, //7810 #HANGUL SYLLABLE CHIEUCH WI SSANGKIYEOK + {0xAE69, 0xCDEB}, //7811 #HANGUL SYLLABLE CHIEUCH WI KIYEOKSIOS + {0xAE6A, 0xCDED}, //7812 #HANGUL SYLLABLE CHIEUCH WI NIEUNCIEUC + {0xAE6B, 0xCDEE}, //7813 #HANGUL SYLLABLE CHIEUCH WI NIEUNHIEUH + {0xAE6C, 0xCDEF}, //7814 #HANGUL SYLLABLE CHIEUCH WI TIKEUT + {0xAE6D, 0xCDF1}, //7815 #HANGUL SYLLABLE CHIEUCH WI RIEULKIYEOK + {0xAE6E, 0xCDF2}, //7816 #HANGUL SYLLABLE CHIEUCH WI RIEULMIEUM + {0xAE6F, 0xCDF3}, //7817 #HANGUL SYLLABLE CHIEUCH WI RIEULPIEUP + {0xAE70, 0xCDF4}, //7818 #HANGUL SYLLABLE CHIEUCH WI RIEULSIOS + {0xAE71, 0xCDF5}, //7819 #HANGUL SYLLABLE CHIEUCH WI RIEULTHIEUTH + {0xAE72, 0xCDF6}, //7820 #HANGUL SYLLABLE CHIEUCH WI RIEULPHIEUPH + {0xAE73, 0xCDF7}, //7821 #HANGUL SYLLABLE CHIEUCH WI RIEULHIEUH + {0xAE74, 0xCDFA}, //7822 #HANGUL SYLLABLE CHIEUCH WI PIEUPSIOS + {0xAE75, 0xCDFC}, //7823 #HANGUL SYLLABLE CHIEUCH WI SSANGSIOS + {0xAE76, 0xCDFE}, //7824 #HANGUL SYLLABLE CHIEUCH WI CIEUC + {0xAE77, 0xCDFF}, //7825 #HANGUL SYLLABLE CHIEUCH WI CHIEUCH + {0xAE78, 0xCE00}, //7826 #HANGUL SYLLABLE CHIEUCH WI KHIEUKH + {0xAE79, 0xCE01}, //7827 #HANGUL SYLLABLE CHIEUCH WI THIEUTH + {0xAE7A, 0xCE02}, //7828 #HANGUL SYLLABLE CHIEUCH WI PHIEUPH + {0xAE81, 0xCE03}, //7829 #HANGUL SYLLABLE CHIEUCH WI HIEUH + {0xAE82, 0xCE05}, //7830 #HANGUL SYLLABLE CHIEUCH YU KIYEOK + {0xAE83, 0xCE06}, //7831 #HANGUL SYLLABLE CHIEUCH YU SSANGKIYEOK + {0xAE84, 0xCE07}, //7832 #HANGUL SYLLABLE CHIEUCH YU KIYEOKSIOS + {0xAE85, 0xCE09}, //7833 #HANGUL SYLLABLE CHIEUCH YU NIEUNCIEUC + {0xAE86, 0xCE0A}, //7834 #HANGUL SYLLABLE CHIEUCH YU NIEUNHIEUH + {0xAE87, 0xCE0B}, //7835 #HANGUL SYLLABLE CHIEUCH YU TIKEUT + {0xAE88, 0xCE0D}, //7836 #HANGUL SYLLABLE CHIEUCH YU RIEULKIYEOK + {0xAE89, 0xCE0E}, //7837 #HANGUL SYLLABLE CHIEUCH YU RIEULMIEUM + {0xAE8A, 0xCE0F}, //7838 #HANGUL SYLLABLE CHIEUCH YU RIEULPIEUP + {0xAE8B, 0xCE10}, //7839 #HANGUL SYLLABLE CHIEUCH YU RIEULSIOS + {0xAE8C, 0xCE11}, //7840 #HANGUL SYLLABLE CHIEUCH YU RIEULTHIEUTH + {0xAE8D, 0xCE12}, //7841 #HANGUL SYLLABLE CHIEUCH YU RIEULPHIEUPH + {0xAE8E, 0xCE13}, //7842 #HANGUL SYLLABLE CHIEUCH YU RIEULHIEUH + {0xAE8F, 0xCE15}, //7843 #HANGUL SYLLABLE CHIEUCH YU PIEUP + {0xAE90, 0xCE16}, //7844 #HANGUL SYLLABLE CHIEUCH YU PIEUPSIOS + {0xAE91, 0xCE17}, //7845 #HANGUL SYLLABLE CHIEUCH YU SIOS + {0xAE92, 0xCE18}, //7846 #HANGUL SYLLABLE CHIEUCH YU SSANGSIOS + {0xAE93, 0xCE1A}, //7847 #HANGUL SYLLABLE CHIEUCH YU CIEUC + {0xAE94, 0xCE1B}, //7848 #HANGUL SYLLABLE CHIEUCH YU CHIEUCH + {0xAE95, 0xCE1C}, //7849 #HANGUL SYLLABLE CHIEUCH YU KHIEUKH + {0xAE96, 0xCE1D}, //7850 #HANGUL SYLLABLE CHIEUCH YU THIEUTH + {0xAE97, 0xCE1E}, //7851 #HANGUL SYLLABLE CHIEUCH YU PHIEUPH + {0xAE98, 0xCE1F}, //7852 #HANGUL SYLLABLE CHIEUCH YU HIEUH + {0xAE99, 0xCE22}, //7853 #HANGUL SYLLABLE CHIEUCH EU SSANGKIYEOK + {0xAE9A, 0xCE23}, //7854 #HANGUL SYLLABLE CHIEUCH EU KIYEOKSIOS + {0xAE9B, 0xCE25}, //7855 #HANGUL SYLLABLE CHIEUCH EU NIEUNCIEUC + {0xAE9C, 0xCE26}, //7856 #HANGUL SYLLABLE CHIEUCH EU NIEUNHIEUH + {0xAE9D, 0xCE27}, //7857 #HANGUL SYLLABLE CHIEUCH EU TIKEUT + {0xAE9E, 0xCE29}, //7858 #HANGUL SYLLABLE CHIEUCH EU RIEULKIYEOK + {0xAE9F, 0xCE2A}, //7859 #HANGUL SYLLABLE CHIEUCH EU RIEULMIEUM + {0xAEA0, 0xCE2B}, //7860 #HANGUL SYLLABLE CHIEUCH EU RIEULPIEUP + {0xAF41, 0xCE2C}, //7861 #HANGUL SYLLABLE CHIEUCH EU RIEULSIOS + {0xAF42, 0xCE2D}, //7862 #HANGUL SYLLABLE CHIEUCH EU RIEULTHIEUTH + {0xAF43, 0xCE2E}, //7863 #HANGUL SYLLABLE CHIEUCH EU RIEULPHIEUPH + {0xAF44, 0xCE2F}, //7864 #HANGUL SYLLABLE CHIEUCH EU RIEULHIEUH + {0xAF45, 0xCE32}, //7865 #HANGUL SYLLABLE CHIEUCH EU PIEUPSIOS + {0xAF46, 0xCE34}, //7866 #HANGUL SYLLABLE CHIEUCH EU SSANGSIOS + {0xAF47, 0xCE36}, //7867 #HANGUL SYLLABLE CHIEUCH EU CIEUC + {0xAF48, 0xCE37}, //7868 #HANGUL SYLLABLE CHIEUCH EU CHIEUCH + {0xAF49, 0xCE38}, //7869 #HANGUL SYLLABLE CHIEUCH EU KHIEUKH + {0xAF4A, 0xCE39}, //7870 #HANGUL SYLLABLE CHIEUCH EU THIEUTH + {0xAF4B, 0xCE3A}, //7871 #HANGUL SYLLABLE CHIEUCH EU PHIEUPH + {0xAF4C, 0xCE3B}, //7872 #HANGUL SYLLABLE CHIEUCH EU HIEUH + {0xAF4D, 0xCE3C}, //7873 #HANGUL SYLLABLE CHIEUCH YI + {0xAF4E, 0xCE3D}, //7874 #HANGUL SYLLABLE CHIEUCH YI KIYEOK + {0xAF4F, 0xCE3E}, //7875 #HANGUL SYLLABLE CHIEUCH YI SSANGKIYEOK + {0xAF50, 0xCE3F}, //7876 #HANGUL SYLLABLE CHIEUCH YI KIYEOKSIOS + {0xAF51, 0xCE40}, //7877 #HANGUL SYLLABLE CHIEUCH YI NIEUN + {0xAF52, 0xCE41}, //7878 #HANGUL SYLLABLE CHIEUCH YI NIEUNCIEUC + {0xAF53, 0xCE42}, //7879 #HANGUL SYLLABLE CHIEUCH YI NIEUNHIEUH + {0xAF54, 0xCE43}, //7880 #HANGUL SYLLABLE CHIEUCH YI TIKEUT + {0xAF55, 0xCE44}, //7881 #HANGUL SYLLABLE CHIEUCH YI RIEUL + {0xAF56, 0xCE45}, //7882 #HANGUL SYLLABLE CHIEUCH YI RIEULKIYEOK + {0xAF57, 0xCE46}, //7883 #HANGUL SYLLABLE CHIEUCH YI RIEULMIEUM + {0xAF58, 0xCE47}, //7884 #HANGUL SYLLABLE CHIEUCH YI RIEULPIEUP + {0xAF59, 0xCE48}, //7885 #HANGUL SYLLABLE CHIEUCH YI RIEULSIOS + {0xAF5A, 0xCE49}, //7886 #HANGUL SYLLABLE CHIEUCH YI RIEULTHIEUTH + {0xAF61, 0xCE4A}, //7887 #HANGUL SYLLABLE CHIEUCH YI RIEULPHIEUPH + {0xAF62, 0xCE4B}, //7888 #HANGUL SYLLABLE CHIEUCH YI RIEULHIEUH + {0xAF63, 0xCE4C}, //7889 #HANGUL SYLLABLE CHIEUCH YI MIEUM + {0xAF64, 0xCE4D}, //7890 #HANGUL SYLLABLE CHIEUCH YI PIEUP + {0xAF65, 0xCE4E}, //7891 #HANGUL SYLLABLE CHIEUCH YI PIEUPSIOS + {0xAF66, 0xCE4F}, //7892 #HANGUL SYLLABLE CHIEUCH YI SIOS + {0xAF67, 0xCE50}, //7893 #HANGUL SYLLABLE CHIEUCH YI SSANGSIOS + {0xAF68, 0xCE51}, //7894 #HANGUL SYLLABLE CHIEUCH YI IEUNG + {0xAF69, 0xCE52}, //7895 #HANGUL SYLLABLE CHIEUCH YI CIEUC + {0xAF6A, 0xCE53}, //7896 #HANGUL SYLLABLE CHIEUCH YI CHIEUCH + {0xAF6B, 0xCE54}, //7897 #HANGUL SYLLABLE CHIEUCH YI KHIEUKH + {0xAF6C, 0xCE55}, //7898 #HANGUL SYLLABLE CHIEUCH YI THIEUTH + {0xAF6D, 0xCE56}, //7899 #HANGUL SYLLABLE CHIEUCH YI PHIEUPH + {0xAF6E, 0xCE57}, //7900 #HANGUL SYLLABLE CHIEUCH YI HIEUH + {0xAF6F, 0xCE5A}, //7901 #HANGUL SYLLABLE CHIEUCH I SSANGKIYEOK + {0xAF70, 0xCE5B}, //7902 #HANGUL SYLLABLE CHIEUCH I KIYEOKSIOS + {0xAF71, 0xCE5D}, //7903 #HANGUL SYLLABLE CHIEUCH I NIEUNCIEUC + {0xAF72, 0xCE5E}, //7904 #HANGUL SYLLABLE CHIEUCH I NIEUNHIEUH + {0xAF73, 0xCE62}, //7905 #HANGUL SYLLABLE CHIEUCH I RIEULMIEUM + {0xAF74, 0xCE63}, //7906 #HANGUL SYLLABLE CHIEUCH I RIEULPIEUP + {0xAF75, 0xCE64}, //7907 #HANGUL SYLLABLE CHIEUCH I RIEULSIOS + {0xAF76, 0xCE65}, //7908 #HANGUL SYLLABLE CHIEUCH I RIEULTHIEUTH + {0xAF77, 0xCE66}, //7909 #HANGUL SYLLABLE CHIEUCH I RIEULPHIEUPH + {0xAF78, 0xCE67}, //7910 #HANGUL SYLLABLE CHIEUCH I RIEULHIEUH + {0xAF79, 0xCE6A}, //7911 #HANGUL SYLLABLE CHIEUCH I PIEUPSIOS + {0xAF7A, 0xCE6C}, //7912 #HANGUL SYLLABLE CHIEUCH I SSANGSIOS + {0xAF81, 0xCE6E}, //7913 #HANGUL SYLLABLE CHIEUCH I CIEUC + {0xAF82, 0xCE6F}, //7914 #HANGUL SYLLABLE CHIEUCH I CHIEUCH + {0xAF83, 0xCE70}, //7915 #HANGUL SYLLABLE CHIEUCH I KHIEUKH + {0xAF84, 0xCE71}, //7916 #HANGUL SYLLABLE CHIEUCH I THIEUTH + {0xAF85, 0xCE72}, //7917 #HANGUL SYLLABLE CHIEUCH I PHIEUPH + {0xAF86, 0xCE73}, //7918 #HANGUL SYLLABLE CHIEUCH I HIEUH + {0xAF87, 0xCE76}, //7919 #HANGUL SYLLABLE KHIEUKH A SSANGKIYEOK + {0xAF88, 0xCE77}, //7920 #HANGUL SYLLABLE KHIEUKH A KIYEOKSIOS + {0xAF89, 0xCE79}, //7921 #HANGUL SYLLABLE KHIEUKH A NIEUNCIEUC + {0xAF8A, 0xCE7A}, //7922 #HANGUL SYLLABLE KHIEUKH A NIEUNHIEUH + {0xAF8B, 0xCE7B}, //7923 #HANGUL SYLLABLE KHIEUKH A TIKEUT + {0xAF8C, 0xCE7D}, //7924 #HANGUL SYLLABLE KHIEUKH A RIEULKIYEOK + {0xAF8D, 0xCE7E}, //7925 #HANGUL SYLLABLE KHIEUKH A RIEULMIEUM + {0xAF8E, 0xCE7F}, //7926 #HANGUL SYLLABLE KHIEUKH A RIEULPIEUP + {0xAF8F, 0xCE80}, //7927 #HANGUL SYLLABLE KHIEUKH A RIEULSIOS + {0xAF90, 0xCE81}, //7928 #HANGUL SYLLABLE KHIEUKH A RIEULTHIEUTH + {0xAF91, 0xCE82}, //7929 #HANGUL SYLLABLE KHIEUKH A RIEULPHIEUPH + {0xAF92, 0xCE83}, //7930 #HANGUL SYLLABLE KHIEUKH A RIEULHIEUH + {0xAF93, 0xCE86}, //7931 #HANGUL SYLLABLE KHIEUKH A PIEUPSIOS + {0xAF94, 0xCE88}, //7932 #HANGUL SYLLABLE KHIEUKH A SSANGSIOS + {0xAF95, 0xCE8A}, //7933 #HANGUL SYLLABLE KHIEUKH A CIEUC + {0xAF96, 0xCE8B}, //7934 #HANGUL SYLLABLE KHIEUKH A CHIEUCH + {0xAF97, 0xCE8C}, //7935 #HANGUL SYLLABLE KHIEUKH A KHIEUKH + {0xAF98, 0xCE8D}, //7936 #HANGUL SYLLABLE KHIEUKH A THIEUTH + {0xAF99, 0xCE8E}, //7937 #HANGUL SYLLABLE KHIEUKH A PHIEUPH + {0xAF9A, 0xCE8F}, //7938 #HANGUL SYLLABLE KHIEUKH A HIEUH + {0xAF9B, 0xCE92}, //7939 #HANGUL SYLLABLE KHIEUKH AE SSANGKIYEOK + {0xAF9C, 0xCE93}, //7940 #HANGUL SYLLABLE KHIEUKH AE KIYEOKSIOS + {0xAF9D, 0xCE95}, //7941 #HANGUL SYLLABLE KHIEUKH AE NIEUNCIEUC + {0xAF9E, 0xCE96}, //7942 #HANGUL SYLLABLE KHIEUKH AE NIEUNHIEUH + {0xAF9F, 0xCE97}, //7943 #HANGUL SYLLABLE KHIEUKH AE TIKEUT + {0xAFA0, 0xCE99}, //7944 #HANGUL SYLLABLE KHIEUKH AE RIEULKIYEOK + {0xB041, 0xCE9A}, //7945 #HANGUL SYLLABLE KHIEUKH AE RIEULMIEUM + {0xB042, 0xCE9B}, //7946 #HANGUL SYLLABLE KHIEUKH AE RIEULPIEUP + {0xB043, 0xCE9C}, //7947 #HANGUL SYLLABLE KHIEUKH AE RIEULSIOS + {0xB044, 0xCE9D}, //7948 #HANGUL SYLLABLE KHIEUKH AE RIEULTHIEUTH + {0xB045, 0xCE9E}, //7949 #HANGUL SYLLABLE KHIEUKH AE RIEULPHIEUPH + {0xB046, 0xCE9F}, //7950 #HANGUL SYLLABLE KHIEUKH AE RIEULHIEUH + {0xB047, 0xCEA2}, //7951 #HANGUL SYLLABLE KHIEUKH AE PIEUPSIOS + {0xB048, 0xCEA6}, //7952 #HANGUL SYLLABLE KHIEUKH AE CIEUC + {0xB049, 0xCEA7}, //7953 #HANGUL SYLLABLE KHIEUKH AE CHIEUCH + {0xB04A, 0xCEA8}, //7954 #HANGUL SYLLABLE KHIEUKH AE KHIEUKH + {0xB04B, 0xCEA9}, //7955 #HANGUL SYLLABLE KHIEUKH AE THIEUTH + {0xB04C, 0xCEAA}, //7956 #HANGUL SYLLABLE KHIEUKH AE PHIEUPH + {0xB04D, 0xCEAB}, //7957 #HANGUL SYLLABLE KHIEUKH AE HIEUH + {0xB04E, 0xCEAE}, //7958 #HANGUL SYLLABLE KHIEUKH YA SSANGKIYEOK + {0xB04F, 0xCEAF}, //7959 #HANGUL SYLLABLE KHIEUKH YA KIYEOKSIOS + {0xB050, 0xCEB0}, //7960 #HANGUL SYLLABLE KHIEUKH YA NIEUN + {0xB051, 0xCEB1}, //7961 #HANGUL SYLLABLE KHIEUKH YA NIEUNCIEUC + {0xB052, 0xCEB2}, //7962 #HANGUL SYLLABLE KHIEUKH YA NIEUNHIEUH + {0xB053, 0xCEB3}, //7963 #HANGUL SYLLABLE KHIEUKH YA TIKEUT + {0xB054, 0xCEB4}, //7964 #HANGUL SYLLABLE KHIEUKH YA RIEUL + {0xB055, 0xCEB5}, //7965 #HANGUL SYLLABLE KHIEUKH YA RIEULKIYEOK + {0xB056, 0xCEB6}, //7966 #HANGUL SYLLABLE KHIEUKH YA RIEULMIEUM + {0xB057, 0xCEB7}, //7967 #HANGUL SYLLABLE KHIEUKH YA RIEULPIEUP + {0xB058, 0xCEB8}, //7968 #HANGUL SYLLABLE KHIEUKH YA RIEULSIOS + {0xB059, 0xCEB9}, //7969 #HANGUL SYLLABLE KHIEUKH YA RIEULTHIEUTH + {0xB05A, 0xCEBA}, //7970 #HANGUL SYLLABLE KHIEUKH YA RIEULPHIEUPH + {0xB061, 0xCEBB}, //7971 #HANGUL SYLLABLE KHIEUKH YA RIEULHIEUH + {0xB062, 0xCEBC}, //7972 #HANGUL SYLLABLE KHIEUKH YA MIEUM + {0xB063, 0xCEBD}, //7973 #HANGUL SYLLABLE KHIEUKH YA PIEUP + {0xB064, 0xCEBE}, //7974 #HANGUL SYLLABLE KHIEUKH YA PIEUPSIOS + {0xB065, 0xCEBF}, //7975 #HANGUL SYLLABLE KHIEUKH YA SIOS + {0xB066, 0xCEC0}, //7976 #HANGUL SYLLABLE KHIEUKH YA SSANGSIOS + {0xB067, 0xCEC2}, //7977 #HANGUL SYLLABLE KHIEUKH YA CIEUC + {0xB068, 0xCEC3}, //7978 #HANGUL SYLLABLE KHIEUKH YA CHIEUCH + {0xB069, 0xCEC4}, //7979 #HANGUL SYLLABLE KHIEUKH YA KHIEUKH + {0xB06A, 0xCEC5}, //7980 #HANGUL SYLLABLE KHIEUKH YA THIEUTH + {0xB06B, 0xCEC6}, //7981 #HANGUL SYLLABLE KHIEUKH YA PHIEUPH + {0xB06C, 0xCEC7}, //7982 #HANGUL SYLLABLE KHIEUKH YA HIEUH + {0xB06D, 0xCEC8}, //7983 #HANGUL SYLLABLE KHIEUKH YAE + {0xB06E, 0xCEC9}, //7984 #HANGUL SYLLABLE KHIEUKH YAE KIYEOK + {0xB06F, 0xCECA}, //7985 #HANGUL SYLLABLE KHIEUKH YAE SSANGKIYEOK + {0xB070, 0xCECB}, //7986 #HANGUL SYLLABLE KHIEUKH YAE KIYEOKSIOS + {0xB071, 0xCECC}, //7987 #HANGUL SYLLABLE KHIEUKH YAE NIEUN + {0xB072, 0xCECD}, //7988 #HANGUL SYLLABLE KHIEUKH YAE NIEUNCIEUC + {0xB073, 0xCECE}, //7989 #HANGUL SYLLABLE KHIEUKH YAE NIEUNHIEUH + {0xB074, 0xCECF}, //7990 #HANGUL SYLLABLE KHIEUKH YAE TIKEUT + {0xB075, 0xCED0}, //7991 #HANGUL SYLLABLE KHIEUKH YAE RIEUL + {0xB076, 0xCED1}, //7992 #HANGUL SYLLABLE KHIEUKH YAE RIEULKIYEOK + {0xB077, 0xCED2}, //7993 #HANGUL SYLLABLE KHIEUKH YAE RIEULMIEUM + {0xB078, 0xCED3}, //7994 #HANGUL SYLLABLE KHIEUKH YAE RIEULPIEUP + {0xB079, 0xCED4}, //7995 #HANGUL SYLLABLE KHIEUKH YAE RIEULSIOS + {0xB07A, 0xCED5}, //7996 #HANGUL SYLLABLE KHIEUKH YAE RIEULTHIEUTH + {0xB081, 0xCED6}, //7997 #HANGUL SYLLABLE KHIEUKH YAE RIEULPHIEUPH + {0xB082, 0xCED7}, //7998 #HANGUL SYLLABLE KHIEUKH YAE RIEULHIEUH + {0xB083, 0xCED8}, //7999 #HANGUL SYLLABLE KHIEUKH YAE MIEUM + {0xB084, 0xCED9}, //8000 #HANGUL SYLLABLE KHIEUKH YAE PIEUP + {0xB085, 0xCEDA}, //8001 #HANGUL SYLLABLE KHIEUKH YAE PIEUPSIOS + {0xB086, 0xCEDB}, //8002 #HANGUL SYLLABLE KHIEUKH YAE SIOS + {0xB087, 0xCEDC}, //8003 #HANGUL SYLLABLE KHIEUKH YAE SSANGSIOS + {0xB088, 0xCEDD}, //8004 #HANGUL SYLLABLE KHIEUKH YAE IEUNG + {0xB089, 0xCEDE}, //8005 #HANGUL SYLLABLE KHIEUKH YAE CIEUC + {0xB08A, 0xCEDF}, //8006 #HANGUL SYLLABLE KHIEUKH YAE CHIEUCH + {0xB08B, 0xCEE0}, //8007 #HANGUL SYLLABLE KHIEUKH YAE KHIEUKH + {0xB08C, 0xCEE1}, //8008 #HANGUL SYLLABLE KHIEUKH YAE THIEUTH + {0xB08D, 0xCEE2}, //8009 #HANGUL SYLLABLE KHIEUKH YAE PHIEUPH + {0xB08E, 0xCEE3}, //8010 #HANGUL SYLLABLE KHIEUKH YAE HIEUH + {0xB08F, 0xCEE6}, //8011 #HANGUL SYLLABLE KHIEUKH EO SSANGKIYEOK + {0xB090, 0xCEE7}, //8012 #HANGUL SYLLABLE KHIEUKH EO KIYEOKSIOS + {0xB091, 0xCEE9}, //8013 #HANGUL SYLLABLE KHIEUKH EO NIEUNCIEUC + {0xB092, 0xCEEA}, //8014 #HANGUL SYLLABLE KHIEUKH EO NIEUNHIEUH + {0xB093, 0xCEED}, //8015 #HANGUL SYLLABLE KHIEUKH EO RIEULKIYEOK + {0xB094, 0xCEEE}, //8016 #HANGUL SYLLABLE KHIEUKH EO RIEULMIEUM + {0xB095, 0xCEEF}, //8017 #HANGUL SYLLABLE KHIEUKH EO RIEULPIEUP + {0xB096, 0xCEF0}, //8018 #HANGUL SYLLABLE KHIEUKH EO RIEULSIOS + {0xB097, 0xCEF1}, //8019 #HANGUL SYLLABLE KHIEUKH EO RIEULTHIEUTH + {0xB098, 0xCEF2}, //8020 #HANGUL SYLLABLE KHIEUKH EO RIEULPHIEUPH + {0xB099, 0xCEF3}, //8021 #HANGUL SYLLABLE KHIEUKH EO RIEULHIEUH + {0xB09A, 0xCEF6}, //8022 #HANGUL SYLLABLE KHIEUKH EO PIEUPSIOS + {0xB09B, 0xCEFA}, //8023 #HANGUL SYLLABLE KHIEUKH EO CIEUC + {0xB09C, 0xCEFB}, //8024 #HANGUL SYLLABLE KHIEUKH EO CHIEUCH + {0xB09D, 0xCEFC}, //8025 #HANGUL SYLLABLE KHIEUKH EO KHIEUKH + {0xB09E, 0xCEFD}, //8026 #HANGUL SYLLABLE KHIEUKH EO THIEUTH + {0xB09F, 0xCEFE}, //8027 #HANGUL SYLLABLE KHIEUKH EO PHIEUPH + {0xB0A0, 0xCEFF}, //8028 #HANGUL SYLLABLE KHIEUKH EO HIEUH + {0xB0A1, 0xAC00}, //8029 #HANGUL SYLLABLE KIYEOK A + {0xB0A2, 0xAC01}, //8030 #HANGUL SYLLABLE KIYEOK A KIYEOK + {0xB0A3, 0xAC04}, //8031 #HANGUL SYLLABLE KIYEOK A NIEUN + {0xB0A4, 0xAC07}, //8032 #HANGUL SYLLABLE KIYEOK A TIKEUT + {0xB0A5, 0xAC08}, //8033 #HANGUL SYLLABLE KIYEOK A RIEUL + {0xB0A6, 0xAC09}, //8034 #HANGUL SYLLABLE KIYEOK A RIEULKIYEOK + {0xB0A7, 0xAC0A}, //8035 #HANGUL SYLLABLE KIYEOK A RIEULMIEUM + {0xB0A8, 0xAC10}, //8036 #HANGUL SYLLABLE KIYEOK A MIEUM + {0xB0A9, 0xAC11}, //8037 #HANGUL SYLLABLE KIYEOK A PIEUP + {0xB0AA, 0xAC12}, //8038 #HANGUL SYLLABLE KIYEOK A PIEUPSIOS + {0xB0AB, 0xAC13}, //8039 #HANGUL SYLLABLE KIYEOK A SIOS + {0xB0AC, 0xAC14}, //8040 #HANGUL SYLLABLE KIYEOK A SSANGSIOS + {0xB0AD, 0xAC15}, //8041 #HANGUL SYLLABLE KIYEOK A IEUNG + {0xB0AE, 0xAC16}, //8042 #HANGUL SYLLABLE KIYEOK A CIEUC + {0xB0AF, 0xAC17}, //8043 #HANGUL SYLLABLE KIYEOK A CHIEUCH + {0xB0B0, 0xAC19}, //8044 #HANGUL SYLLABLE KIYEOK A THIEUTH + {0xB0B1, 0xAC1A}, //8045 #HANGUL SYLLABLE KIYEOK A PHIEUPH + {0xB0B2, 0xAC1B}, //8046 #HANGUL SYLLABLE KIYEOK A HIEUH + {0xB0B3, 0xAC1C}, //8047 #HANGUL SYLLABLE KIYEOK AE + {0xB0B4, 0xAC1D}, //8048 #HANGUL SYLLABLE KIYEOK AE KIYEOK + {0xB0B5, 0xAC20}, //8049 #HANGUL SYLLABLE KIYEOK AE NIEUN + {0xB0B6, 0xAC24}, //8050 #HANGUL SYLLABLE KIYEOK AE RIEUL + {0xB0B7, 0xAC2C}, //8051 #HANGUL SYLLABLE KIYEOK AE MIEUM + {0xB0B8, 0xAC2D}, //8052 #HANGUL SYLLABLE KIYEOK AE PIEUP + {0xB0B9, 0xAC2F}, //8053 #HANGUL SYLLABLE KIYEOK AE SIOS + {0xB0BA, 0xAC30}, //8054 #HANGUL SYLLABLE KIYEOK AE SSANGSIOS + {0xB0BB, 0xAC31}, //8055 #HANGUL SYLLABLE KIYEOK AE IEUNG + {0xB0BC, 0xAC38}, //8056 #HANGUL SYLLABLE KIYEOK YA + {0xB0BD, 0xAC39}, //8057 #HANGUL SYLLABLE KIYEOK YA KIYEOK + {0xB0BE, 0xAC3C}, //8058 #HANGUL SYLLABLE KIYEOK YA NIEUN + {0xB0BF, 0xAC40}, //8059 #HANGUL SYLLABLE KIYEOK YA RIEUL + {0xB0C0, 0xAC4B}, //8060 #HANGUL SYLLABLE KIYEOK YA SIOS + {0xB0C1, 0xAC4D}, //8061 #HANGUL SYLLABLE KIYEOK YA IEUNG + {0xB0C2, 0xAC54}, //8062 #HANGUL SYLLABLE KIYEOK YAE + {0xB0C3, 0xAC58}, //8063 #HANGUL SYLLABLE KIYEOK YAE NIEUN + {0xB0C4, 0xAC5C}, //8064 #HANGUL SYLLABLE KIYEOK YAE RIEUL + {0xB0C5, 0xAC70}, //8065 #HANGUL SYLLABLE KIYEOK EO + {0xB0C6, 0xAC71}, //8066 #HANGUL SYLLABLE KIYEOK EO KIYEOK + {0xB0C7, 0xAC74}, //8067 #HANGUL SYLLABLE KIYEOK EO NIEUN + {0xB0C8, 0xAC77}, //8068 #HANGUL SYLLABLE KIYEOK EO TIKEUT + {0xB0C9, 0xAC78}, //8069 #HANGUL SYLLABLE KIYEOK EO RIEUL + {0xB0CA, 0xAC7A}, //8070 #HANGUL SYLLABLE KIYEOK EO RIEULMIEUM + {0xB0CB, 0xAC80}, //8071 #HANGUL SYLLABLE KIYEOK EO MIEUM + {0xB0CC, 0xAC81}, //8072 #HANGUL SYLLABLE KIYEOK EO PIEUP + {0xB0CD, 0xAC83}, //8073 #HANGUL SYLLABLE KIYEOK EO SIOS + {0xB0CE, 0xAC84}, //8074 #HANGUL SYLLABLE KIYEOK EO SSANGSIOS + {0xB0CF, 0xAC85}, //8075 #HANGUL SYLLABLE KIYEOK EO IEUNG + {0xB0D0, 0xAC86}, //8076 #HANGUL SYLLABLE KIYEOK EO CIEUC + {0xB0D1, 0xAC89}, //8077 #HANGUL SYLLABLE KIYEOK EO THIEUTH + {0xB0D2, 0xAC8A}, //8078 #HANGUL SYLLABLE KIYEOK EO PHIEUPH + {0xB0D3, 0xAC8B}, //8079 #HANGUL SYLLABLE KIYEOK EO HIEUH + {0xB0D4, 0xAC8C}, //8080 #HANGUL SYLLABLE KIYEOK E + {0xB0D5, 0xAC90}, //8081 #HANGUL SYLLABLE KIYEOK E NIEUN + {0xB0D6, 0xAC94}, //8082 #HANGUL SYLLABLE KIYEOK E RIEUL + {0xB0D7, 0xAC9C}, //8083 #HANGUL SYLLABLE KIYEOK E MIEUM + {0xB0D8, 0xAC9D}, //8084 #HANGUL SYLLABLE KIYEOK E PIEUP + {0xB0D9, 0xAC9F}, //8085 #HANGUL SYLLABLE KIYEOK E SIOS + {0xB0DA, 0xACA0}, //8086 #HANGUL SYLLABLE KIYEOK E SSANGSIOS + {0xB0DB, 0xACA1}, //8087 #HANGUL SYLLABLE KIYEOK E IEUNG + {0xB0DC, 0xACA8}, //8088 #HANGUL SYLLABLE KIYEOK YEO + {0xB0DD, 0xACA9}, //8089 #HANGUL SYLLABLE KIYEOK YEO KIYEOK + {0xB0DE, 0xACAA}, //8090 #HANGUL SYLLABLE KIYEOK YEO SSANGKIYEOK + {0xB0DF, 0xACAC}, //8091 #HANGUL SYLLABLE KIYEOK YEO NIEUN + {0xB0E0, 0xACAF}, //8092 #HANGUL SYLLABLE KIYEOK YEO TIKEUT + {0xB0E1, 0xACB0}, //8093 #HANGUL SYLLABLE KIYEOK YEO RIEUL + {0xB0E2, 0xACB8}, //8094 #HANGUL SYLLABLE KIYEOK YEO MIEUM + {0xB0E3, 0xACB9}, //8095 #HANGUL SYLLABLE KIYEOK YEO PIEUP + {0xB0E4, 0xACBB}, //8096 #HANGUL SYLLABLE KIYEOK YEO SIOS + {0xB0E5, 0xACBC}, //8097 #HANGUL SYLLABLE KIYEOK YEO SSANGSIOS + {0xB0E6, 0xACBD}, //8098 #HANGUL SYLLABLE KIYEOK YEO IEUNG + {0xB0E7, 0xACC1}, //8099 #HANGUL SYLLABLE KIYEOK YEO THIEUTH + {0xB0E8, 0xACC4}, //8100 #HANGUL SYLLABLE KIYEOK YE + {0xB0E9, 0xACC8}, //8101 #HANGUL SYLLABLE KIYEOK YE NIEUN + {0xB0EA, 0xACCC}, //8102 #HANGUL SYLLABLE KIYEOK YE RIEUL + {0xB0EB, 0xACD5}, //8103 #HANGUL SYLLABLE KIYEOK YE PIEUP + {0xB0EC, 0xACD7}, //8104 #HANGUL SYLLABLE KIYEOK YE SIOS + {0xB0ED, 0xACE0}, //8105 #HANGUL SYLLABLE KIYEOK O + {0xB0EE, 0xACE1}, //8106 #HANGUL SYLLABLE KIYEOK O KIYEOK + {0xB0EF, 0xACE4}, //8107 #HANGUL SYLLABLE KIYEOK O NIEUN + {0xB0F0, 0xACE7}, //8108 #HANGUL SYLLABLE KIYEOK O TIKEUT + {0xB0F1, 0xACE8}, //8109 #HANGUL SYLLABLE KIYEOK O RIEUL + {0xB0F2, 0xACEA}, //8110 #HANGUL SYLLABLE KIYEOK O RIEULMIEUM + {0xB0F3, 0xACEC}, //8111 #HANGUL SYLLABLE KIYEOK O RIEULSIOS + {0xB0F4, 0xACEF}, //8112 #HANGUL SYLLABLE KIYEOK O RIEULHIEUH + {0xB0F5, 0xACF0}, //8113 #HANGUL SYLLABLE KIYEOK O MIEUM + {0xB0F6, 0xACF1}, //8114 #HANGUL SYLLABLE KIYEOK O PIEUP + {0xB0F7, 0xACF3}, //8115 #HANGUL SYLLABLE KIYEOK O SIOS + {0xB0F8, 0xACF5}, //8116 #HANGUL SYLLABLE KIYEOK O IEUNG + {0xB0F9, 0xACF6}, //8117 #HANGUL SYLLABLE KIYEOK O CIEUC + {0xB0FA, 0xACFC}, //8118 #HANGUL SYLLABLE KIYEOK WA + {0xB0FB, 0xACFD}, //8119 #HANGUL SYLLABLE KIYEOK WA KIYEOK + {0xB0FC, 0xAD00}, //8120 #HANGUL SYLLABLE KIYEOK WA NIEUN + {0xB0FD, 0xAD04}, //8121 #HANGUL SYLLABLE KIYEOK WA RIEUL + {0xB0FE, 0xAD06}, //8122 #HANGUL SYLLABLE KIYEOK WA RIEULMIEUM + {0xB141, 0xCF02}, //8123 #HANGUL SYLLABLE KHIEUKH E SSANGKIYEOK + {0xB142, 0xCF03}, //8124 #HANGUL SYLLABLE KHIEUKH E KIYEOKSIOS + {0xB143, 0xCF05}, //8125 #HANGUL SYLLABLE KHIEUKH E NIEUNCIEUC + {0xB144, 0xCF06}, //8126 #HANGUL SYLLABLE KHIEUKH E NIEUNHIEUH + {0xB145, 0xCF07}, //8127 #HANGUL SYLLABLE KHIEUKH E TIKEUT + {0xB146, 0xCF09}, //8128 #HANGUL SYLLABLE KHIEUKH E RIEULKIYEOK + {0xB147, 0xCF0A}, //8129 #HANGUL SYLLABLE KHIEUKH E RIEULMIEUM + {0xB148, 0xCF0B}, //8130 #HANGUL SYLLABLE KHIEUKH E RIEULPIEUP + {0xB149, 0xCF0C}, //8131 #HANGUL SYLLABLE KHIEUKH E RIEULSIOS + {0xB14A, 0xCF0D}, //8132 #HANGUL SYLLABLE KHIEUKH E RIEULTHIEUTH + {0xB14B, 0xCF0E}, //8133 #HANGUL SYLLABLE KHIEUKH E RIEULPHIEUPH + {0xB14C, 0xCF0F}, //8134 #HANGUL SYLLABLE KHIEUKH E RIEULHIEUH + {0xB14D, 0xCF12}, //8135 #HANGUL SYLLABLE KHIEUKH E PIEUPSIOS + {0xB14E, 0xCF14}, //8136 #HANGUL SYLLABLE KHIEUKH E SSANGSIOS + {0xB14F, 0xCF16}, //8137 #HANGUL SYLLABLE KHIEUKH E CIEUC + {0xB150, 0xCF17}, //8138 #HANGUL SYLLABLE KHIEUKH E CHIEUCH + {0xB151, 0xCF18}, //8139 #HANGUL SYLLABLE KHIEUKH E KHIEUKH + {0xB152, 0xCF19}, //8140 #HANGUL SYLLABLE KHIEUKH E THIEUTH + {0xB153, 0xCF1A}, //8141 #HANGUL SYLLABLE KHIEUKH E PHIEUPH + {0xB154, 0xCF1B}, //8142 #HANGUL SYLLABLE KHIEUKH E HIEUH + {0xB155, 0xCF1D}, //8143 #HANGUL SYLLABLE KHIEUKH YEO KIYEOK + {0xB156, 0xCF1E}, //8144 #HANGUL SYLLABLE KHIEUKH YEO SSANGKIYEOK + {0xB157, 0xCF1F}, //8145 #HANGUL SYLLABLE KHIEUKH YEO KIYEOKSIOS + {0xB158, 0xCF21}, //8146 #HANGUL SYLLABLE KHIEUKH YEO NIEUNCIEUC + {0xB159, 0xCF22}, //8147 #HANGUL SYLLABLE KHIEUKH YEO NIEUNHIEUH + {0xB15A, 0xCF23}, //8148 #HANGUL SYLLABLE KHIEUKH YEO TIKEUT + {0xB161, 0xCF25}, //8149 #HANGUL SYLLABLE KHIEUKH YEO RIEULKIYEOK + {0xB162, 0xCF26}, //8150 #HANGUL SYLLABLE KHIEUKH YEO RIEULMIEUM + {0xB163, 0xCF27}, //8151 #HANGUL SYLLABLE KHIEUKH YEO RIEULPIEUP + {0xB164, 0xCF28}, //8152 #HANGUL SYLLABLE KHIEUKH YEO RIEULSIOS + {0xB165, 0xCF29}, //8153 #HANGUL SYLLABLE KHIEUKH YEO RIEULTHIEUTH + {0xB166, 0xCF2A}, //8154 #HANGUL SYLLABLE KHIEUKH YEO RIEULPHIEUPH + {0xB167, 0xCF2B}, //8155 #HANGUL SYLLABLE KHIEUKH YEO RIEULHIEUH + {0xB168, 0xCF2E}, //8156 #HANGUL SYLLABLE KHIEUKH YEO PIEUPSIOS + {0xB169, 0xCF32}, //8157 #HANGUL SYLLABLE KHIEUKH YEO CIEUC + {0xB16A, 0xCF33}, //8158 #HANGUL SYLLABLE KHIEUKH YEO CHIEUCH + {0xB16B, 0xCF34}, //8159 #HANGUL SYLLABLE KHIEUKH YEO KHIEUKH + {0xB16C, 0xCF35}, //8160 #HANGUL SYLLABLE KHIEUKH YEO THIEUTH + {0xB16D, 0xCF36}, //8161 #HANGUL SYLLABLE KHIEUKH YEO PHIEUPH + {0xB16E, 0xCF37}, //8162 #HANGUL SYLLABLE KHIEUKH YEO HIEUH + {0xB16F, 0xCF39}, //8163 #HANGUL SYLLABLE KHIEUKH YE KIYEOK + {0xB170, 0xCF3A}, //8164 #HANGUL SYLLABLE KHIEUKH YE SSANGKIYEOK + {0xB171, 0xCF3B}, //8165 #HANGUL SYLLABLE KHIEUKH YE KIYEOKSIOS + {0xB172, 0xCF3C}, //8166 #HANGUL SYLLABLE KHIEUKH YE NIEUN + {0xB173, 0xCF3D}, //8167 #HANGUL SYLLABLE KHIEUKH YE NIEUNCIEUC + {0xB174, 0xCF3E}, //8168 #HANGUL SYLLABLE KHIEUKH YE NIEUNHIEUH + {0xB175, 0xCF3F}, //8169 #HANGUL SYLLABLE KHIEUKH YE TIKEUT + {0xB176, 0xCF40}, //8170 #HANGUL SYLLABLE KHIEUKH YE RIEUL + {0xB177, 0xCF41}, //8171 #HANGUL SYLLABLE KHIEUKH YE RIEULKIYEOK + {0xB178, 0xCF42}, //8172 #HANGUL SYLLABLE KHIEUKH YE RIEULMIEUM + {0xB179, 0xCF43}, //8173 #HANGUL SYLLABLE KHIEUKH YE RIEULPIEUP + {0xB17A, 0xCF44}, //8174 #HANGUL SYLLABLE KHIEUKH YE RIEULSIOS + {0xB181, 0xCF45}, //8175 #HANGUL SYLLABLE KHIEUKH YE RIEULTHIEUTH + {0xB182, 0xCF46}, //8176 #HANGUL SYLLABLE KHIEUKH YE RIEULPHIEUPH + {0xB183, 0xCF47}, //8177 #HANGUL SYLLABLE KHIEUKH YE RIEULHIEUH + {0xB184, 0xCF48}, //8178 #HANGUL SYLLABLE KHIEUKH YE MIEUM + {0xB185, 0xCF49}, //8179 #HANGUL SYLLABLE KHIEUKH YE PIEUP + {0xB186, 0xCF4A}, //8180 #HANGUL SYLLABLE KHIEUKH YE PIEUPSIOS + {0xB187, 0xCF4B}, //8181 #HANGUL SYLLABLE KHIEUKH YE SIOS + {0xB188, 0xCF4C}, //8182 #HANGUL SYLLABLE KHIEUKH YE SSANGSIOS + {0xB189, 0xCF4D}, //8183 #HANGUL SYLLABLE KHIEUKH YE IEUNG + {0xB18A, 0xCF4E}, //8184 #HANGUL SYLLABLE KHIEUKH YE CIEUC + {0xB18B, 0xCF4F}, //8185 #HANGUL SYLLABLE KHIEUKH YE CHIEUCH + {0xB18C, 0xCF50}, //8186 #HANGUL SYLLABLE KHIEUKH YE KHIEUKH + {0xB18D, 0xCF51}, //8187 #HANGUL SYLLABLE KHIEUKH YE THIEUTH + {0xB18E, 0xCF52}, //8188 #HANGUL SYLLABLE KHIEUKH YE PHIEUPH + {0xB18F, 0xCF53}, //8189 #HANGUL SYLLABLE KHIEUKH YE HIEUH + {0xB190, 0xCF56}, //8190 #HANGUL SYLLABLE KHIEUKH O SSANGKIYEOK + {0xB191, 0xCF57}, //8191 #HANGUL SYLLABLE KHIEUKH O KIYEOKSIOS + {0xB192, 0xCF59}, //8192 #HANGUL SYLLABLE KHIEUKH O NIEUNCIEUC + {0xB193, 0xCF5A}, //8193 #HANGUL SYLLABLE KHIEUKH O NIEUNHIEUH + {0xB194, 0xCF5B}, //8194 #HANGUL SYLLABLE KHIEUKH O TIKEUT + {0xB195, 0xCF5D}, //8195 #HANGUL SYLLABLE KHIEUKH O RIEULKIYEOK + {0xB196, 0xCF5E}, //8196 #HANGUL SYLLABLE KHIEUKH O RIEULMIEUM + {0xB197, 0xCF5F}, //8197 #HANGUL SYLLABLE KHIEUKH O RIEULPIEUP + {0xB198, 0xCF60}, //8198 #HANGUL SYLLABLE KHIEUKH O RIEULSIOS + {0xB199, 0xCF61}, //8199 #HANGUL SYLLABLE KHIEUKH O RIEULTHIEUTH + {0xB19A, 0xCF62}, //8200 #HANGUL SYLLABLE KHIEUKH O RIEULPHIEUPH + {0xB19B, 0xCF63}, //8201 #HANGUL SYLLABLE KHIEUKH O RIEULHIEUH + {0xB19C, 0xCF66}, //8202 #HANGUL SYLLABLE KHIEUKH O PIEUPSIOS + {0xB19D, 0xCF68}, //8203 #HANGUL SYLLABLE KHIEUKH O SSANGSIOS + {0xB19E, 0xCF6A}, //8204 #HANGUL SYLLABLE KHIEUKH O CIEUC + {0xB19F, 0xCF6B}, //8205 #HANGUL SYLLABLE KHIEUKH O CHIEUCH + {0xB1A0, 0xCF6C}, //8206 #HANGUL SYLLABLE KHIEUKH O KHIEUKH + {0xB1A1, 0xAD0C}, //8207 #HANGUL SYLLABLE KIYEOK WA MIEUM + {0xB1A2, 0xAD0D}, //8208 #HANGUL SYLLABLE KIYEOK WA PIEUP + {0xB1A3, 0xAD0F}, //8209 #HANGUL SYLLABLE KIYEOK WA SIOS + {0xB1A4, 0xAD11}, //8210 #HANGUL SYLLABLE KIYEOK WA IEUNG + {0xB1A5, 0xAD18}, //8211 #HANGUL SYLLABLE KIYEOK WAE + {0xB1A6, 0xAD1C}, //8212 #HANGUL SYLLABLE KIYEOK WAE NIEUN + {0xB1A7, 0xAD20}, //8213 #HANGUL SYLLABLE KIYEOK WAE RIEUL + {0xB1A8, 0xAD29}, //8214 #HANGUL SYLLABLE KIYEOK WAE PIEUP + {0xB1A9, 0xAD2C}, //8215 #HANGUL SYLLABLE KIYEOK WAE SSANGSIOS + {0xB1AA, 0xAD2D}, //8216 #HANGUL SYLLABLE KIYEOK WAE IEUNG + {0xB1AB, 0xAD34}, //8217 #HANGUL SYLLABLE KIYEOK OE + {0xB1AC, 0xAD35}, //8218 #HANGUL SYLLABLE KIYEOK OE KIYEOK + {0xB1AD, 0xAD38}, //8219 #HANGUL SYLLABLE KIYEOK OE NIEUN + {0xB1AE, 0xAD3C}, //8220 #HANGUL SYLLABLE KIYEOK OE RIEUL + {0xB1AF, 0xAD44}, //8221 #HANGUL SYLLABLE KIYEOK OE MIEUM + {0xB1B0, 0xAD45}, //8222 #HANGUL SYLLABLE KIYEOK OE PIEUP + {0xB1B1, 0xAD47}, //8223 #HANGUL SYLLABLE KIYEOK OE SIOS + {0xB1B2, 0xAD49}, //8224 #HANGUL SYLLABLE KIYEOK OE IEUNG + {0xB1B3, 0xAD50}, //8225 #HANGUL SYLLABLE KIYEOK YO + {0xB1B4, 0xAD54}, //8226 #HANGUL SYLLABLE KIYEOK YO NIEUN + {0xB1B5, 0xAD58}, //8227 #HANGUL SYLLABLE KIYEOK YO RIEUL + {0xB1B6, 0xAD61}, //8228 #HANGUL SYLLABLE KIYEOK YO PIEUP + {0xB1B7, 0xAD63}, //8229 #HANGUL SYLLABLE KIYEOK YO SIOS + {0xB1B8, 0xAD6C}, //8230 #HANGUL SYLLABLE KIYEOK U + {0xB1B9, 0xAD6D}, //8231 #HANGUL SYLLABLE KIYEOK U KIYEOK + {0xB1BA, 0xAD70}, //8232 #HANGUL SYLLABLE KIYEOK U NIEUN + {0xB1BB, 0xAD73}, //8233 #HANGUL SYLLABLE KIYEOK U TIKEUT + {0xB1BC, 0xAD74}, //8234 #HANGUL SYLLABLE KIYEOK U RIEUL + {0xB1BD, 0xAD75}, //8235 #HANGUL SYLLABLE KIYEOK U RIEULKIYEOK + {0xB1BE, 0xAD76}, //8236 #HANGUL SYLLABLE KIYEOK U RIEULMIEUM + {0xB1BF, 0xAD7B}, //8237 #HANGUL SYLLABLE KIYEOK U RIEULHIEUH + {0xB1C0, 0xAD7C}, //8238 #HANGUL SYLLABLE KIYEOK U MIEUM + {0xB1C1, 0xAD7D}, //8239 #HANGUL SYLLABLE KIYEOK U PIEUP + {0xB1C2, 0xAD7F}, //8240 #HANGUL SYLLABLE KIYEOK U SIOS + {0xB1C3, 0xAD81}, //8241 #HANGUL SYLLABLE KIYEOK U IEUNG + {0xB1C4, 0xAD82}, //8242 #HANGUL SYLLABLE KIYEOK U CIEUC + {0xB1C5, 0xAD88}, //8243 #HANGUL SYLLABLE KIYEOK WEO + {0xB1C6, 0xAD89}, //8244 #HANGUL SYLLABLE KIYEOK WEO KIYEOK + {0xB1C7, 0xAD8C}, //8245 #HANGUL SYLLABLE KIYEOK WEO NIEUN + {0xB1C8, 0xAD90}, //8246 #HANGUL SYLLABLE KIYEOK WEO RIEUL + {0xB1C9, 0xAD9C}, //8247 #HANGUL SYLLABLE KIYEOK WEO SSANGSIOS + {0xB1CA, 0xAD9D}, //8248 #HANGUL SYLLABLE KIYEOK WEO IEUNG + {0xB1CB, 0xADA4}, //8249 #HANGUL SYLLABLE KIYEOK WE + {0xB1CC, 0xADB7}, //8250 #HANGUL SYLLABLE KIYEOK WE SIOS + {0xB1CD, 0xADC0}, //8251 #HANGUL SYLLABLE KIYEOK WI + {0xB1CE, 0xADC1}, //8252 #HANGUL SYLLABLE KIYEOK WI KIYEOK + {0xB1CF, 0xADC4}, //8253 #HANGUL SYLLABLE KIYEOK WI NIEUN + {0xB1D0, 0xADC8}, //8254 #HANGUL SYLLABLE KIYEOK WI RIEUL + {0xB1D1, 0xADD0}, //8255 #HANGUL SYLLABLE KIYEOK WI MIEUM + {0xB1D2, 0xADD1}, //8256 #HANGUL SYLLABLE KIYEOK WI PIEUP + {0xB1D3, 0xADD3}, //8257 #HANGUL SYLLABLE KIYEOK WI SIOS + {0xB1D4, 0xADDC}, //8258 #HANGUL SYLLABLE KIYEOK YU + {0xB1D5, 0xADE0}, //8259 #HANGUL SYLLABLE KIYEOK YU NIEUN + {0xB1D6, 0xADE4}, //8260 #HANGUL SYLLABLE KIYEOK YU RIEUL + {0xB1D7, 0xADF8}, //8261 #HANGUL SYLLABLE KIYEOK EU + {0xB1D8, 0xADF9}, //8262 #HANGUL SYLLABLE KIYEOK EU KIYEOK + {0xB1D9, 0xADFC}, //8263 #HANGUL SYLLABLE KIYEOK EU NIEUN + {0xB1DA, 0xADFF}, //8264 #HANGUL SYLLABLE KIYEOK EU TIKEUT + {0xB1DB, 0xAE00}, //8265 #HANGUL SYLLABLE KIYEOK EU RIEUL + {0xB1DC, 0xAE01}, //8266 #HANGUL SYLLABLE KIYEOK EU RIEULKIYEOK + {0xB1DD, 0xAE08}, //8267 #HANGUL SYLLABLE KIYEOK EU MIEUM + {0xB1DE, 0xAE09}, //8268 #HANGUL SYLLABLE KIYEOK EU PIEUP + {0xB1DF, 0xAE0B}, //8269 #HANGUL SYLLABLE KIYEOK EU SIOS + {0xB1E0, 0xAE0D}, //8270 #HANGUL SYLLABLE KIYEOK EU IEUNG + {0xB1E1, 0xAE14}, //8271 #HANGUL SYLLABLE KIYEOK YI + {0xB1E2, 0xAE30}, //8272 #HANGUL SYLLABLE KIYEOK I + {0xB1E3, 0xAE31}, //8273 #HANGUL SYLLABLE KIYEOK I KIYEOK + {0xB1E4, 0xAE34}, //8274 #HANGUL SYLLABLE KIYEOK I NIEUN + {0xB1E5, 0xAE37}, //8275 #HANGUL SYLLABLE KIYEOK I TIKEUT + {0xB1E6, 0xAE38}, //8276 #HANGUL SYLLABLE KIYEOK I RIEUL + {0xB1E7, 0xAE3A}, //8277 #HANGUL SYLLABLE KIYEOK I RIEULMIEUM + {0xB1E8, 0xAE40}, //8278 #HANGUL SYLLABLE KIYEOK I MIEUM + {0xB1E9, 0xAE41}, //8279 #HANGUL SYLLABLE KIYEOK I PIEUP + {0xB1EA, 0xAE43}, //8280 #HANGUL SYLLABLE KIYEOK I SIOS + {0xB1EB, 0xAE45}, //8281 #HANGUL SYLLABLE KIYEOK I IEUNG + {0xB1EC, 0xAE46}, //8282 #HANGUL SYLLABLE KIYEOK I CIEUC + {0xB1ED, 0xAE4A}, //8283 #HANGUL SYLLABLE KIYEOK I PHIEUPH + {0xB1EE, 0xAE4C}, //8284 #HANGUL SYLLABLE SSANGKIYEOK A + {0xB1EF, 0xAE4D}, //8285 #HANGUL SYLLABLE SSANGKIYEOK A KIYEOK + {0xB1F0, 0xAE4E}, //8286 #HANGUL SYLLABLE SSANGKIYEOK A SSANGKIYEOK + {0xB1F1, 0xAE50}, //8287 #HANGUL SYLLABLE SSANGKIYEOK A NIEUN + {0xB1F2, 0xAE54}, //8288 #HANGUL SYLLABLE SSANGKIYEOK A RIEUL + {0xB1F3, 0xAE56}, //8289 #HANGUL SYLLABLE SSANGKIYEOK A RIEULMIEUM + {0xB1F4, 0xAE5C}, //8290 #HANGUL SYLLABLE SSANGKIYEOK A MIEUM + {0xB1F5, 0xAE5D}, //8291 #HANGUL SYLLABLE SSANGKIYEOK A PIEUP + {0xB1F6, 0xAE5F}, //8292 #HANGUL SYLLABLE SSANGKIYEOK A SIOS + {0xB1F7, 0xAE60}, //8293 #HANGUL SYLLABLE SSANGKIYEOK A SSANGSIOS + {0xB1F8, 0xAE61}, //8294 #HANGUL SYLLABLE SSANGKIYEOK A IEUNG + {0xB1F9, 0xAE65}, //8295 #HANGUL SYLLABLE SSANGKIYEOK A THIEUTH + {0xB1FA, 0xAE68}, //8296 #HANGUL SYLLABLE SSANGKIYEOK AE + {0xB1FB, 0xAE69}, //8297 #HANGUL SYLLABLE SSANGKIYEOK AE KIYEOK + {0xB1FC, 0xAE6C}, //8298 #HANGUL SYLLABLE SSANGKIYEOK AE NIEUN + {0xB1FD, 0xAE70}, //8299 #HANGUL SYLLABLE SSANGKIYEOK AE RIEUL + {0xB1FE, 0xAE78}, //8300 #HANGUL SYLLABLE SSANGKIYEOK AE MIEUM + {0xB241, 0xCF6D}, //8301 #HANGUL SYLLABLE KHIEUKH O THIEUTH + {0xB242, 0xCF6E}, //8302 #HANGUL SYLLABLE KHIEUKH O PHIEUPH + {0xB243, 0xCF6F}, //8303 #HANGUL SYLLABLE KHIEUKH O HIEUH + {0xB244, 0xCF72}, //8304 #HANGUL SYLLABLE KHIEUKH WA SSANGKIYEOK + {0xB245, 0xCF73}, //8305 #HANGUL SYLLABLE KHIEUKH WA KIYEOKSIOS + {0xB246, 0xCF75}, //8306 #HANGUL SYLLABLE KHIEUKH WA NIEUNCIEUC + {0xB247, 0xCF76}, //8307 #HANGUL SYLLABLE KHIEUKH WA NIEUNHIEUH + {0xB248, 0xCF77}, //8308 #HANGUL SYLLABLE KHIEUKH WA TIKEUT + {0xB249, 0xCF79}, //8309 #HANGUL SYLLABLE KHIEUKH WA RIEULKIYEOK + {0xB24A, 0xCF7A}, //8310 #HANGUL SYLLABLE KHIEUKH WA RIEULMIEUM + {0xB24B, 0xCF7B}, //8311 #HANGUL SYLLABLE KHIEUKH WA RIEULPIEUP + {0xB24C, 0xCF7C}, //8312 #HANGUL SYLLABLE KHIEUKH WA RIEULSIOS + {0xB24D, 0xCF7D}, //8313 #HANGUL SYLLABLE KHIEUKH WA RIEULTHIEUTH + {0xB24E, 0xCF7E}, //8314 #HANGUL SYLLABLE KHIEUKH WA RIEULPHIEUPH + {0xB24F, 0xCF7F}, //8315 #HANGUL SYLLABLE KHIEUKH WA RIEULHIEUH + {0xB250, 0xCF81}, //8316 #HANGUL SYLLABLE KHIEUKH WA PIEUP + {0xB251, 0xCF82}, //8317 #HANGUL SYLLABLE KHIEUKH WA PIEUPSIOS + {0xB252, 0xCF83}, //8318 #HANGUL SYLLABLE KHIEUKH WA SIOS + {0xB253, 0xCF84}, //8319 #HANGUL SYLLABLE KHIEUKH WA SSANGSIOS + {0xB254, 0xCF86}, //8320 #HANGUL SYLLABLE KHIEUKH WA CIEUC + {0xB255, 0xCF87}, //8321 #HANGUL SYLLABLE KHIEUKH WA CHIEUCH + {0xB256, 0xCF88}, //8322 #HANGUL SYLLABLE KHIEUKH WA KHIEUKH + {0xB257, 0xCF89}, //8323 #HANGUL SYLLABLE KHIEUKH WA THIEUTH + {0xB258, 0xCF8A}, //8324 #HANGUL SYLLABLE KHIEUKH WA PHIEUPH + {0xB259, 0xCF8B}, //8325 #HANGUL SYLLABLE KHIEUKH WA HIEUH + {0xB25A, 0xCF8D}, //8326 #HANGUL SYLLABLE KHIEUKH WAE KIYEOK + {0xB261, 0xCF8E}, //8327 #HANGUL SYLLABLE KHIEUKH WAE SSANGKIYEOK + {0xB262, 0xCF8F}, //8328 #HANGUL SYLLABLE KHIEUKH WAE KIYEOKSIOS + {0xB263, 0xCF90}, //8329 #HANGUL SYLLABLE KHIEUKH WAE NIEUN + {0xB264, 0xCF91}, //8330 #HANGUL SYLLABLE KHIEUKH WAE NIEUNCIEUC + {0xB265, 0xCF92}, //8331 #HANGUL SYLLABLE KHIEUKH WAE NIEUNHIEUH + {0xB266, 0xCF93}, //8332 #HANGUL SYLLABLE KHIEUKH WAE TIKEUT + {0xB267, 0xCF94}, //8333 #HANGUL SYLLABLE KHIEUKH WAE RIEUL + {0xB268, 0xCF95}, //8334 #HANGUL SYLLABLE KHIEUKH WAE RIEULKIYEOK + {0xB269, 0xCF96}, //8335 #HANGUL SYLLABLE KHIEUKH WAE RIEULMIEUM + {0xB26A, 0xCF97}, //8336 #HANGUL SYLLABLE KHIEUKH WAE RIEULPIEUP + {0xB26B, 0xCF98}, //8337 #HANGUL SYLLABLE KHIEUKH WAE RIEULSIOS + {0xB26C, 0xCF99}, //8338 #HANGUL SYLLABLE KHIEUKH WAE RIEULTHIEUTH + {0xB26D, 0xCF9A}, //8339 #HANGUL SYLLABLE KHIEUKH WAE RIEULPHIEUPH + {0xB26E, 0xCF9B}, //8340 #HANGUL SYLLABLE KHIEUKH WAE RIEULHIEUH + {0xB26F, 0xCF9C}, //8341 #HANGUL SYLLABLE KHIEUKH WAE MIEUM + {0xB270, 0xCF9D}, //8342 #HANGUL SYLLABLE KHIEUKH WAE PIEUP + {0xB271, 0xCF9E}, //8343 #HANGUL SYLLABLE KHIEUKH WAE PIEUPSIOS + {0xB272, 0xCF9F}, //8344 #HANGUL SYLLABLE KHIEUKH WAE SIOS + {0xB273, 0xCFA0}, //8345 #HANGUL SYLLABLE KHIEUKH WAE SSANGSIOS + {0xB274, 0xCFA2}, //8346 #HANGUL SYLLABLE KHIEUKH WAE CIEUC + {0xB275, 0xCFA3}, //8347 #HANGUL SYLLABLE KHIEUKH WAE CHIEUCH + {0xB276, 0xCFA4}, //8348 #HANGUL SYLLABLE KHIEUKH WAE KHIEUKH + {0xB277, 0xCFA5}, //8349 #HANGUL SYLLABLE KHIEUKH WAE THIEUTH + {0xB278, 0xCFA6}, //8350 #HANGUL SYLLABLE KHIEUKH WAE PHIEUPH + {0xB279, 0xCFA7}, //8351 #HANGUL SYLLABLE KHIEUKH WAE HIEUH + {0xB27A, 0xCFA9}, //8352 #HANGUL SYLLABLE KHIEUKH OE KIYEOK + {0xB281, 0xCFAA}, //8353 #HANGUL SYLLABLE KHIEUKH OE SSANGKIYEOK + {0xB282, 0xCFAB}, //8354 #HANGUL SYLLABLE KHIEUKH OE KIYEOKSIOS + {0xB283, 0xCFAC}, //8355 #HANGUL SYLLABLE KHIEUKH OE NIEUN + {0xB284, 0xCFAD}, //8356 #HANGUL SYLLABLE KHIEUKH OE NIEUNCIEUC + {0xB285, 0xCFAE}, //8357 #HANGUL SYLLABLE KHIEUKH OE NIEUNHIEUH + {0xB286, 0xCFAF}, //8358 #HANGUL SYLLABLE KHIEUKH OE TIKEUT + {0xB287, 0xCFB1}, //8359 #HANGUL SYLLABLE KHIEUKH OE RIEULKIYEOK + {0xB288, 0xCFB2}, //8360 #HANGUL SYLLABLE KHIEUKH OE RIEULMIEUM + {0xB289, 0xCFB3}, //8361 #HANGUL SYLLABLE KHIEUKH OE RIEULPIEUP + {0xB28A, 0xCFB4}, //8362 #HANGUL SYLLABLE KHIEUKH OE RIEULSIOS + {0xB28B, 0xCFB5}, //8363 #HANGUL SYLLABLE KHIEUKH OE RIEULTHIEUTH + {0xB28C, 0xCFB6}, //8364 #HANGUL SYLLABLE KHIEUKH OE RIEULPHIEUPH + {0xB28D, 0xCFB7}, //8365 #HANGUL SYLLABLE KHIEUKH OE RIEULHIEUH + {0xB28E, 0xCFB8}, //8366 #HANGUL SYLLABLE KHIEUKH OE MIEUM + {0xB28F, 0xCFB9}, //8367 #HANGUL SYLLABLE KHIEUKH OE PIEUP + {0xB290, 0xCFBA}, //8368 #HANGUL SYLLABLE KHIEUKH OE PIEUPSIOS + {0xB291, 0xCFBB}, //8369 #HANGUL SYLLABLE KHIEUKH OE SIOS + {0xB292, 0xCFBC}, //8370 #HANGUL SYLLABLE KHIEUKH OE SSANGSIOS + {0xB293, 0xCFBD}, //8371 #HANGUL SYLLABLE KHIEUKH OE IEUNG + {0xB294, 0xCFBE}, //8372 #HANGUL SYLLABLE KHIEUKH OE CIEUC + {0xB295, 0xCFBF}, //8373 #HANGUL SYLLABLE KHIEUKH OE CHIEUCH + {0xB296, 0xCFC0}, //8374 #HANGUL SYLLABLE KHIEUKH OE KHIEUKH + {0xB297, 0xCFC1}, //8375 #HANGUL SYLLABLE KHIEUKH OE THIEUTH + {0xB298, 0xCFC2}, //8376 #HANGUL SYLLABLE KHIEUKH OE PHIEUPH + {0xB299, 0xCFC3}, //8377 #HANGUL SYLLABLE KHIEUKH OE HIEUH + {0xB29A, 0xCFC5}, //8378 #HANGUL SYLLABLE KHIEUKH YO KIYEOK + {0xB29B, 0xCFC6}, //8379 #HANGUL SYLLABLE KHIEUKH YO SSANGKIYEOK + {0xB29C, 0xCFC7}, //8380 #HANGUL SYLLABLE KHIEUKH YO KIYEOKSIOS + {0xB29D, 0xCFC8}, //8381 #HANGUL SYLLABLE KHIEUKH YO NIEUN + {0xB29E, 0xCFC9}, //8382 #HANGUL SYLLABLE KHIEUKH YO NIEUNCIEUC + {0xB29F, 0xCFCA}, //8383 #HANGUL SYLLABLE KHIEUKH YO NIEUNHIEUH + {0xB2A0, 0xCFCB}, //8384 #HANGUL SYLLABLE KHIEUKH YO TIKEUT + {0xB2A1, 0xAE79}, //8385 #HANGUL SYLLABLE SSANGKIYEOK AE PIEUP + {0xB2A2, 0xAE7B}, //8386 #HANGUL SYLLABLE SSANGKIYEOK AE SIOS + {0xB2A3, 0xAE7C}, //8387 #HANGUL SYLLABLE SSANGKIYEOK AE SSANGSIOS + {0xB2A4, 0xAE7D}, //8388 #HANGUL SYLLABLE SSANGKIYEOK AE IEUNG + {0xB2A5, 0xAE84}, //8389 #HANGUL SYLLABLE SSANGKIYEOK YA + {0xB2A6, 0xAE85}, //8390 #HANGUL SYLLABLE SSANGKIYEOK YA KIYEOK + {0xB2A7, 0xAE8C}, //8391 #HANGUL SYLLABLE SSANGKIYEOK YA RIEUL + {0xB2A8, 0xAEBC}, //8392 #HANGUL SYLLABLE SSANGKIYEOK EO + {0xB2A9, 0xAEBD}, //8393 #HANGUL SYLLABLE SSANGKIYEOK EO KIYEOK + {0xB2AA, 0xAEBE}, //8394 #HANGUL SYLLABLE SSANGKIYEOK EO SSANGKIYEOK + {0xB2AB, 0xAEC0}, //8395 #HANGUL SYLLABLE SSANGKIYEOK EO NIEUN + {0xB2AC, 0xAEC4}, //8396 #HANGUL SYLLABLE SSANGKIYEOK EO RIEUL + {0xB2AD, 0xAECC}, //8397 #HANGUL SYLLABLE SSANGKIYEOK EO MIEUM + {0xB2AE, 0xAECD}, //8398 #HANGUL SYLLABLE SSANGKIYEOK EO PIEUP + {0xB2AF, 0xAECF}, //8399 #HANGUL SYLLABLE SSANGKIYEOK EO SIOS + {0xB2B0, 0xAED0}, //8400 #HANGUL SYLLABLE SSANGKIYEOK EO SSANGSIOS + {0xB2B1, 0xAED1}, //8401 #HANGUL SYLLABLE SSANGKIYEOK EO IEUNG + {0xB2B2, 0xAED8}, //8402 #HANGUL SYLLABLE SSANGKIYEOK E + {0xB2B3, 0xAED9}, //8403 #HANGUL SYLLABLE SSANGKIYEOK E KIYEOK + {0xB2B4, 0xAEDC}, //8404 #HANGUL SYLLABLE SSANGKIYEOK E NIEUN + {0xB2B5, 0xAEE8}, //8405 #HANGUL SYLLABLE SSANGKIYEOK E MIEUM + {0xB2B6, 0xAEEB}, //8406 #HANGUL SYLLABLE SSANGKIYEOK E SIOS + {0xB2B7, 0xAEED}, //8407 #HANGUL SYLLABLE SSANGKIYEOK E IEUNG + {0xB2B8, 0xAEF4}, //8408 #HANGUL SYLLABLE SSANGKIYEOK YEO + {0xB2B9, 0xAEF8}, //8409 #HANGUL SYLLABLE SSANGKIYEOK YEO NIEUN + {0xB2BA, 0xAEFC}, //8410 #HANGUL SYLLABLE SSANGKIYEOK YEO RIEUL + {0xB2BB, 0xAF07}, //8411 #HANGUL SYLLABLE SSANGKIYEOK YEO SIOS + {0xB2BC, 0xAF08}, //8412 #HANGUL SYLLABLE SSANGKIYEOK YEO SSANGSIOS + {0xB2BD, 0xAF0D}, //8413 #HANGUL SYLLABLE SSANGKIYEOK YEO THIEUTH + {0xB2BE, 0xAF10}, //8414 #HANGUL SYLLABLE SSANGKIYEOK YE + {0xB2BF, 0xAF2C}, //8415 #HANGUL SYLLABLE SSANGKIYEOK O + {0xB2C0, 0xAF2D}, //8416 #HANGUL SYLLABLE SSANGKIYEOK O KIYEOK + {0xB2C1, 0xAF30}, //8417 #HANGUL SYLLABLE SSANGKIYEOK O NIEUN + {0xB2C2, 0xAF32}, //8418 #HANGUL SYLLABLE SSANGKIYEOK O NIEUNHIEUH + {0xB2C3, 0xAF34}, //8419 #HANGUL SYLLABLE SSANGKIYEOK O RIEUL + {0xB2C4, 0xAF3C}, //8420 #HANGUL SYLLABLE SSANGKIYEOK O MIEUM + {0xB2C5, 0xAF3D}, //8421 #HANGUL SYLLABLE SSANGKIYEOK O PIEUP + {0xB2C6, 0xAF3F}, //8422 #HANGUL SYLLABLE SSANGKIYEOK O SIOS + {0xB2C7, 0xAF41}, //8423 #HANGUL SYLLABLE SSANGKIYEOK O IEUNG + {0xB2C8, 0xAF42}, //8424 #HANGUL SYLLABLE SSANGKIYEOK O CIEUC + {0xB2C9, 0xAF43}, //8425 #HANGUL SYLLABLE SSANGKIYEOK O CHIEUCH + {0xB2CA, 0xAF48}, //8426 #HANGUL SYLLABLE SSANGKIYEOK WA + {0xB2CB, 0xAF49}, //8427 #HANGUL SYLLABLE SSANGKIYEOK WA KIYEOK + {0xB2CC, 0xAF50}, //8428 #HANGUL SYLLABLE SSANGKIYEOK WA RIEUL + {0xB2CD, 0xAF5C}, //8429 #HANGUL SYLLABLE SSANGKIYEOK WA SSANGSIOS + {0xB2CE, 0xAF5D}, //8430 #HANGUL SYLLABLE SSANGKIYEOK WA IEUNG + {0xB2CF, 0xAF64}, //8431 #HANGUL SYLLABLE SSANGKIYEOK WAE + {0xB2D0, 0xAF65}, //8432 #HANGUL SYLLABLE SSANGKIYEOK WAE KIYEOK + {0xB2D1, 0xAF79}, //8433 #HANGUL SYLLABLE SSANGKIYEOK WAE IEUNG + {0xB2D2, 0xAF80}, //8434 #HANGUL SYLLABLE SSANGKIYEOK OE + {0xB2D3, 0xAF84}, //8435 #HANGUL SYLLABLE SSANGKIYEOK OE NIEUN + {0xB2D4, 0xAF88}, //8436 #HANGUL SYLLABLE SSANGKIYEOK OE RIEUL + {0xB2D5, 0xAF90}, //8437 #HANGUL SYLLABLE SSANGKIYEOK OE MIEUM + {0xB2D6, 0xAF91}, //8438 #HANGUL SYLLABLE SSANGKIYEOK OE PIEUP + {0xB2D7, 0xAF95}, //8439 #HANGUL SYLLABLE SSANGKIYEOK OE IEUNG + {0xB2D8, 0xAF9C}, //8440 #HANGUL SYLLABLE SSANGKIYEOK YO + {0xB2D9, 0xAFB8}, //8441 #HANGUL SYLLABLE SSANGKIYEOK U + {0xB2DA, 0xAFB9}, //8442 #HANGUL SYLLABLE SSANGKIYEOK U KIYEOK + {0xB2DB, 0xAFBC}, //8443 #HANGUL SYLLABLE SSANGKIYEOK U NIEUN + {0xB2DC, 0xAFC0}, //8444 #HANGUL SYLLABLE SSANGKIYEOK U RIEUL + {0xB2DD, 0xAFC7}, //8445 #HANGUL SYLLABLE SSANGKIYEOK U RIEULHIEUH + {0xB2DE, 0xAFC8}, //8446 #HANGUL SYLLABLE SSANGKIYEOK U MIEUM + {0xB2DF, 0xAFC9}, //8447 #HANGUL SYLLABLE SSANGKIYEOK U PIEUP + {0xB2E0, 0xAFCB}, //8448 #HANGUL SYLLABLE SSANGKIYEOK U SIOS + {0xB2E1, 0xAFCD}, //8449 #HANGUL SYLLABLE SSANGKIYEOK U IEUNG + {0xB2E2, 0xAFCE}, //8450 #HANGUL SYLLABLE SSANGKIYEOK U CIEUC + {0xB2E3, 0xAFD4}, //8451 #HANGUL SYLLABLE SSANGKIYEOK WEO + {0xB2E4, 0xAFDC}, //8452 #HANGUL SYLLABLE SSANGKIYEOK WEO RIEUL + {0xB2E5, 0xAFE8}, //8453 #HANGUL SYLLABLE SSANGKIYEOK WEO SSANGSIOS + {0xB2E6, 0xAFE9}, //8454 #HANGUL SYLLABLE SSANGKIYEOK WEO IEUNG + {0xB2E7, 0xAFF0}, //8455 #HANGUL SYLLABLE SSANGKIYEOK WE + {0xB2E8, 0xAFF1}, //8456 #HANGUL SYLLABLE SSANGKIYEOK WE KIYEOK + {0xB2E9, 0xAFF4}, //8457 #HANGUL SYLLABLE SSANGKIYEOK WE NIEUN + {0xB2EA, 0xAFF8}, //8458 #HANGUL SYLLABLE SSANGKIYEOK WE RIEUL + {0xB2EB, 0xB000}, //8459 #HANGUL SYLLABLE SSANGKIYEOK WE MIEUM + {0xB2EC, 0xB001}, //8460 #HANGUL SYLLABLE SSANGKIYEOK WE PIEUP + {0xB2ED, 0xB004}, //8461 #HANGUL SYLLABLE SSANGKIYEOK WE SSANGSIOS + {0xB2EE, 0xB00C}, //8462 #HANGUL SYLLABLE SSANGKIYEOK WI + {0xB2EF, 0xB010}, //8463 #HANGUL SYLLABLE SSANGKIYEOK WI NIEUN + {0xB2F0, 0xB014}, //8464 #HANGUL SYLLABLE SSANGKIYEOK WI RIEUL + {0xB2F1, 0xB01C}, //8465 #HANGUL SYLLABLE SSANGKIYEOK WI MIEUM + {0xB2F2, 0xB01D}, //8466 #HANGUL SYLLABLE SSANGKIYEOK WI PIEUP + {0xB2F3, 0xB028}, //8467 #HANGUL SYLLABLE SSANGKIYEOK YU + {0xB2F4, 0xB044}, //8468 #HANGUL SYLLABLE SSANGKIYEOK EU + {0xB2F5, 0xB045}, //8469 #HANGUL SYLLABLE SSANGKIYEOK EU KIYEOK + {0xB2F6, 0xB048}, //8470 #HANGUL SYLLABLE SSANGKIYEOK EU NIEUN + {0xB2F7, 0xB04A}, //8471 #HANGUL SYLLABLE SSANGKIYEOK EU NIEUNHIEUH + {0xB2F8, 0xB04C}, //8472 #HANGUL SYLLABLE SSANGKIYEOK EU RIEUL + {0xB2F9, 0xB04E}, //8473 #HANGUL SYLLABLE SSANGKIYEOK EU RIEULMIEUM + {0xB2FA, 0xB053}, //8474 #HANGUL SYLLABLE SSANGKIYEOK EU RIEULHIEUH + {0xB2FB, 0xB054}, //8475 #HANGUL SYLLABLE SSANGKIYEOK EU MIEUM + {0xB2FC, 0xB055}, //8476 #HANGUL SYLLABLE SSANGKIYEOK EU PIEUP + {0xB2FD, 0xB057}, //8477 #HANGUL SYLLABLE SSANGKIYEOK EU SIOS + {0xB2FE, 0xB059}, //8478 #HANGUL SYLLABLE SSANGKIYEOK EU IEUNG + {0xB341, 0xCFCC}, //8479 #HANGUL SYLLABLE KHIEUKH YO RIEUL + {0xB342, 0xCFCD}, //8480 #HANGUL SYLLABLE KHIEUKH YO RIEULKIYEOK + {0xB343, 0xCFCE}, //8481 #HANGUL SYLLABLE KHIEUKH YO RIEULMIEUM + {0xB344, 0xCFCF}, //8482 #HANGUL SYLLABLE KHIEUKH YO RIEULPIEUP + {0xB345, 0xCFD0}, //8483 #HANGUL SYLLABLE KHIEUKH YO RIEULSIOS + {0xB346, 0xCFD1}, //8484 #HANGUL SYLLABLE KHIEUKH YO RIEULTHIEUTH + {0xB347, 0xCFD2}, //8485 #HANGUL SYLLABLE KHIEUKH YO RIEULPHIEUPH + {0xB348, 0xCFD3}, //8486 #HANGUL SYLLABLE KHIEUKH YO RIEULHIEUH + {0xB349, 0xCFD4}, //8487 #HANGUL SYLLABLE KHIEUKH YO MIEUM + {0xB34A, 0xCFD5}, //8488 #HANGUL SYLLABLE KHIEUKH YO PIEUP + {0xB34B, 0xCFD6}, //8489 #HANGUL SYLLABLE KHIEUKH YO PIEUPSIOS + {0xB34C, 0xCFD7}, //8490 #HANGUL SYLLABLE KHIEUKH YO SIOS + {0xB34D, 0xCFD8}, //8491 #HANGUL SYLLABLE KHIEUKH YO SSANGSIOS + {0xB34E, 0xCFD9}, //8492 #HANGUL SYLLABLE KHIEUKH YO IEUNG + {0xB34F, 0xCFDA}, //8493 #HANGUL SYLLABLE KHIEUKH YO CIEUC + {0xB350, 0xCFDB}, //8494 #HANGUL SYLLABLE KHIEUKH YO CHIEUCH + {0xB351, 0xCFDC}, //8495 #HANGUL SYLLABLE KHIEUKH YO KHIEUKH + {0xB352, 0xCFDD}, //8496 #HANGUL SYLLABLE KHIEUKH YO THIEUTH + {0xB353, 0xCFDE}, //8497 #HANGUL SYLLABLE KHIEUKH YO PHIEUPH + {0xB354, 0xCFDF}, //8498 #HANGUL SYLLABLE KHIEUKH YO HIEUH + {0xB355, 0xCFE2}, //8499 #HANGUL SYLLABLE KHIEUKH U SSANGKIYEOK + {0xB356, 0xCFE3}, //8500 #HANGUL SYLLABLE KHIEUKH U KIYEOKSIOS + {0xB357, 0xCFE5}, //8501 #HANGUL SYLLABLE KHIEUKH U NIEUNCIEUC + {0xB358, 0xCFE6}, //8502 #HANGUL SYLLABLE KHIEUKH U NIEUNHIEUH + {0xB359, 0xCFE7}, //8503 #HANGUL SYLLABLE KHIEUKH U TIKEUT + {0xB35A, 0xCFE9}, //8504 #HANGUL SYLLABLE KHIEUKH U RIEULKIYEOK + {0xB361, 0xCFEA}, //8505 #HANGUL SYLLABLE KHIEUKH U RIEULMIEUM + {0xB362, 0xCFEB}, //8506 #HANGUL SYLLABLE KHIEUKH U RIEULPIEUP + {0xB363, 0xCFEC}, //8507 #HANGUL SYLLABLE KHIEUKH U RIEULSIOS + {0xB364, 0xCFED}, //8508 #HANGUL SYLLABLE KHIEUKH U RIEULTHIEUTH + {0xB365, 0xCFEE}, //8509 #HANGUL SYLLABLE KHIEUKH U RIEULPHIEUPH + {0xB366, 0xCFEF}, //8510 #HANGUL SYLLABLE KHIEUKH U RIEULHIEUH + {0xB367, 0xCFF2}, //8511 #HANGUL SYLLABLE KHIEUKH U PIEUPSIOS + {0xB368, 0xCFF4}, //8512 #HANGUL SYLLABLE KHIEUKH U SSANGSIOS + {0xB369, 0xCFF6}, //8513 #HANGUL SYLLABLE KHIEUKH U CIEUC + {0xB36A, 0xCFF7}, //8514 #HANGUL SYLLABLE KHIEUKH U CHIEUCH + {0xB36B, 0xCFF8}, //8515 #HANGUL SYLLABLE KHIEUKH U KHIEUKH + {0xB36C, 0xCFF9}, //8516 #HANGUL SYLLABLE KHIEUKH U THIEUTH + {0xB36D, 0xCFFA}, //8517 #HANGUL SYLLABLE KHIEUKH U PHIEUPH + {0xB36E, 0xCFFB}, //8518 #HANGUL SYLLABLE KHIEUKH U HIEUH + {0xB36F, 0xCFFD}, //8519 #HANGUL SYLLABLE KHIEUKH WEO KIYEOK + {0xB370, 0xCFFE}, //8520 #HANGUL SYLLABLE KHIEUKH WEO SSANGKIYEOK + {0xB371, 0xCFFF}, //8521 #HANGUL SYLLABLE KHIEUKH WEO KIYEOKSIOS + {0xB372, 0xD001}, //8522 #HANGUL SYLLABLE KHIEUKH WEO NIEUNCIEUC + {0xB373, 0xD002}, //8523 #HANGUL SYLLABLE KHIEUKH WEO NIEUNHIEUH + {0xB374, 0xD003}, //8524 #HANGUL SYLLABLE KHIEUKH WEO TIKEUT + {0xB375, 0xD005}, //8525 #HANGUL SYLLABLE KHIEUKH WEO RIEULKIYEOK + {0xB376, 0xD006}, //8526 #HANGUL SYLLABLE KHIEUKH WEO RIEULMIEUM + {0xB377, 0xD007}, //8527 #HANGUL SYLLABLE KHIEUKH WEO RIEULPIEUP + {0xB378, 0xD008}, //8528 #HANGUL SYLLABLE KHIEUKH WEO RIEULSIOS + {0xB379, 0xD009}, //8529 #HANGUL SYLLABLE KHIEUKH WEO RIEULTHIEUTH + {0xB37A, 0xD00A}, //8530 #HANGUL SYLLABLE KHIEUKH WEO RIEULPHIEUPH + {0xB381, 0xD00B}, //8531 #HANGUL SYLLABLE KHIEUKH WEO RIEULHIEUH + {0xB382, 0xD00C}, //8532 #HANGUL SYLLABLE KHIEUKH WEO MIEUM + {0xB383, 0xD00D}, //8533 #HANGUL SYLLABLE KHIEUKH WEO PIEUP + {0xB384, 0xD00E}, //8534 #HANGUL SYLLABLE KHIEUKH WEO PIEUPSIOS + {0xB385, 0xD00F}, //8535 #HANGUL SYLLABLE KHIEUKH WEO SIOS + {0xB386, 0xD010}, //8536 #HANGUL SYLLABLE KHIEUKH WEO SSANGSIOS + {0xB387, 0xD012}, //8537 #HANGUL SYLLABLE KHIEUKH WEO CIEUC + {0xB388, 0xD013}, //8538 #HANGUL SYLLABLE KHIEUKH WEO CHIEUCH + {0xB389, 0xD014}, //8539 #HANGUL SYLLABLE KHIEUKH WEO KHIEUKH + {0xB38A, 0xD015}, //8540 #HANGUL SYLLABLE KHIEUKH WEO THIEUTH + {0xB38B, 0xD016}, //8541 #HANGUL SYLLABLE KHIEUKH WEO PHIEUPH + {0xB38C, 0xD017}, //8542 #HANGUL SYLLABLE KHIEUKH WEO HIEUH + {0xB38D, 0xD019}, //8543 #HANGUL SYLLABLE KHIEUKH WE KIYEOK + {0xB38E, 0xD01A}, //8544 #HANGUL SYLLABLE KHIEUKH WE SSANGKIYEOK + {0xB38F, 0xD01B}, //8545 #HANGUL SYLLABLE KHIEUKH WE KIYEOKSIOS + {0xB390, 0xD01C}, //8546 #HANGUL SYLLABLE KHIEUKH WE NIEUN + {0xB391, 0xD01D}, //8547 #HANGUL SYLLABLE KHIEUKH WE NIEUNCIEUC + {0xB392, 0xD01E}, //8548 #HANGUL SYLLABLE KHIEUKH WE NIEUNHIEUH + {0xB393, 0xD01F}, //8549 #HANGUL SYLLABLE KHIEUKH WE TIKEUT + {0xB394, 0xD020}, //8550 #HANGUL SYLLABLE KHIEUKH WE RIEUL + {0xB395, 0xD021}, //8551 #HANGUL SYLLABLE KHIEUKH WE RIEULKIYEOK + {0xB396, 0xD022}, //8552 #HANGUL SYLLABLE KHIEUKH WE RIEULMIEUM + {0xB397, 0xD023}, //8553 #HANGUL SYLLABLE KHIEUKH WE RIEULPIEUP + {0xB398, 0xD024}, //8554 #HANGUL SYLLABLE KHIEUKH WE RIEULSIOS + {0xB399, 0xD025}, //8555 #HANGUL SYLLABLE KHIEUKH WE RIEULTHIEUTH + {0xB39A, 0xD026}, //8556 #HANGUL SYLLABLE KHIEUKH WE RIEULPHIEUPH + {0xB39B, 0xD027}, //8557 #HANGUL SYLLABLE KHIEUKH WE RIEULHIEUH + {0xB39C, 0xD028}, //8558 #HANGUL SYLLABLE KHIEUKH WE MIEUM + {0xB39D, 0xD029}, //8559 #HANGUL SYLLABLE KHIEUKH WE PIEUP + {0xB39E, 0xD02A}, //8560 #HANGUL SYLLABLE KHIEUKH WE PIEUPSIOS + {0xB39F, 0xD02B}, //8561 #HANGUL SYLLABLE KHIEUKH WE SIOS + {0xB3A0, 0xD02C}, //8562 #HANGUL SYLLABLE KHIEUKH WE SSANGSIOS + {0xB3A1, 0xB05D}, //8563 #HANGUL SYLLABLE SSANGKIYEOK EU THIEUTH + {0xB3A2, 0xB07C}, //8564 #HANGUL SYLLABLE SSANGKIYEOK I + {0xB3A3, 0xB07D}, //8565 #HANGUL SYLLABLE SSANGKIYEOK I KIYEOK + {0xB3A4, 0xB080}, //8566 #HANGUL SYLLABLE SSANGKIYEOK I NIEUN + {0xB3A5, 0xB084}, //8567 #HANGUL SYLLABLE SSANGKIYEOK I RIEUL + {0xB3A6, 0xB08C}, //8568 #HANGUL SYLLABLE SSANGKIYEOK I MIEUM + {0xB3A7, 0xB08D}, //8569 #HANGUL SYLLABLE SSANGKIYEOK I PIEUP + {0xB3A8, 0xB08F}, //8570 #HANGUL SYLLABLE SSANGKIYEOK I SIOS + {0xB3A9, 0xB091}, //8571 #HANGUL SYLLABLE SSANGKIYEOK I IEUNG + {0xB3AA, 0xB098}, //8572 #HANGUL SYLLABLE NIEUN A + {0xB3AB, 0xB099}, //8573 #HANGUL SYLLABLE NIEUN A KIYEOK + {0xB3AC, 0xB09A}, //8574 #HANGUL SYLLABLE NIEUN A SSANGKIYEOK + {0xB3AD, 0xB09C}, //8575 #HANGUL SYLLABLE NIEUN A NIEUN + {0xB3AE, 0xB09F}, //8576 #HANGUL SYLLABLE NIEUN A TIKEUT + {0xB3AF, 0xB0A0}, //8577 #HANGUL SYLLABLE NIEUN A RIEUL + {0xB3B0, 0xB0A1}, //8578 #HANGUL SYLLABLE NIEUN A RIEULKIYEOK + {0xB3B1, 0xB0A2}, //8579 #HANGUL SYLLABLE NIEUN A RIEULMIEUM + {0xB3B2, 0xB0A8}, //8580 #HANGUL SYLLABLE NIEUN A MIEUM + {0xB3B3, 0xB0A9}, //8581 #HANGUL SYLLABLE NIEUN A PIEUP + {0xB3B4, 0xB0AB}, //8582 #HANGUL SYLLABLE NIEUN A SIOS + {0xB3B5, 0xB0AC}, //8583 #HANGUL SYLLABLE NIEUN A SSANGSIOS + {0xB3B6, 0xB0AD}, //8584 #HANGUL SYLLABLE NIEUN A IEUNG + {0xB3B7, 0xB0AE}, //8585 #HANGUL SYLLABLE NIEUN A CIEUC + {0xB3B8, 0xB0AF}, //8586 #HANGUL SYLLABLE NIEUN A CHIEUCH + {0xB3B9, 0xB0B1}, //8587 #HANGUL SYLLABLE NIEUN A THIEUTH + {0xB3BA, 0xB0B3}, //8588 #HANGUL SYLLABLE NIEUN A HIEUH + {0xB3BB, 0xB0B4}, //8589 #HANGUL SYLLABLE NIEUN AE + {0xB3BC, 0xB0B5}, //8590 #HANGUL SYLLABLE NIEUN AE KIYEOK + {0xB3BD, 0xB0B8}, //8591 #HANGUL SYLLABLE NIEUN AE NIEUN + {0xB3BE, 0xB0BC}, //8592 #HANGUL SYLLABLE NIEUN AE RIEUL + {0xB3BF, 0xB0C4}, //8593 #HANGUL SYLLABLE NIEUN AE MIEUM + {0xB3C0, 0xB0C5}, //8594 #HANGUL SYLLABLE NIEUN AE PIEUP + {0xB3C1, 0xB0C7}, //8595 #HANGUL SYLLABLE NIEUN AE SIOS + {0xB3C2, 0xB0C8}, //8596 #HANGUL SYLLABLE NIEUN AE SSANGSIOS + {0xB3C3, 0xB0C9}, //8597 #HANGUL SYLLABLE NIEUN AE IEUNG + {0xB3C4, 0xB0D0}, //8598 #HANGUL SYLLABLE NIEUN YA + {0xB3C5, 0xB0D1}, //8599 #HANGUL SYLLABLE NIEUN YA KIYEOK + {0xB3C6, 0xB0D4}, //8600 #HANGUL SYLLABLE NIEUN YA NIEUN + {0xB3C7, 0xB0D8}, //8601 #HANGUL SYLLABLE NIEUN YA RIEUL + {0xB3C8, 0xB0E0}, //8602 #HANGUL SYLLABLE NIEUN YA MIEUM + {0xB3C9, 0xB0E5}, //8603 #HANGUL SYLLABLE NIEUN YA IEUNG + {0xB3CA, 0xB108}, //8604 #HANGUL SYLLABLE NIEUN EO + {0xB3CB, 0xB109}, //8605 #HANGUL SYLLABLE NIEUN EO KIYEOK + {0xB3CC, 0xB10B}, //8606 #HANGUL SYLLABLE NIEUN EO KIYEOKSIOS + {0xB3CD, 0xB10C}, //8607 #HANGUL SYLLABLE NIEUN EO NIEUN + {0xB3CE, 0xB110}, //8608 #HANGUL SYLLABLE NIEUN EO RIEUL + {0xB3CF, 0xB112}, //8609 #HANGUL SYLLABLE NIEUN EO RIEULMIEUM + {0xB3D0, 0xB113}, //8610 #HANGUL SYLLABLE NIEUN EO RIEULPIEUP + {0xB3D1, 0xB118}, //8611 #HANGUL SYLLABLE NIEUN EO MIEUM + {0xB3D2, 0xB119}, //8612 #HANGUL SYLLABLE NIEUN EO PIEUP + {0xB3D3, 0xB11B}, //8613 #HANGUL SYLLABLE NIEUN EO SIOS + {0xB3D4, 0xB11C}, //8614 #HANGUL SYLLABLE NIEUN EO SSANGSIOS + {0xB3D5, 0xB11D}, //8615 #HANGUL SYLLABLE NIEUN EO IEUNG + {0xB3D6, 0xB123}, //8616 #HANGUL SYLLABLE NIEUN EO HIEUH + {0xB3D7, 0xB124}, //8617 #HANGUL SYLLABLE NIEUN E + {0xB3D8, 0xB125}, //8618 #HANGUL SYLLABLE NIEUN E KIYEOK + {0xB3D9, 0xB128}, //8619 #HANGUL SYLLABLE NIEUN E NIEUN + {0xB3DA, 0xB12C}, //8620 #HANGUL SYLLABLE NIEUN E RIEUL + {0xB3DB, 0xB134}, //8621 #HANGUL SYLLABLE NIEUN E MIEUM + {0xB3DC, 0xB135}, //8622 #HANGUL SYLLABLE NIEUN E PIEUP + {0xB3DD, 0xB137}, //8623 #HANGUL SYLLABLE NIEUN E SIOS + {0xB3DE, 0xB138}, //8624 #HANGUL SYLLABLE NIEUN E SSANGSIOS + {0xB3DF, 0xB139}, //8625 #HANGUL SYLLABLE NIEUN E IEUNG + {0xB3E0, 0xB140}, //8626 #HANGUL SYLLABLE NIEUN YEO + {0xB3E1, 0xB141}, //8627 #HANGUL SYLLABLE NIEUN YEO KIYEOK + {0xB3E2, 0xB144}, //8628 #HANGUL SYLLABLE NIEUN YEO NIEUN + {0xB3E3, 0xB148}, //8629 #HANGUL SYLLABLE NIEUN YEO RIEUL + {0xB3E4, 0xB150}, //8630 #HANGUL SYLLABLE NIEUN YEO MIEUM + {0xB3E5, 0xB151}, //8631 #HANGUL SYLLABLE NIEUN YEO PIEUP + {0xB3E6, 0xB154}, //8632 #HANGUL SYLLABLE NIEUN YEO SSANGSIOS + {0xB3E7, 0xB155}, //8633 #HANGUL SYLLABLE NIEUN YEO IEUNG + {0xB3E8, 0xB158}, //8634 #HANGUL SYLLABLE NIEUN YEO KHIEUKH + {0xB3E9, 0xB15C}, //8635 #HANGUL SYLLABLE NIEUN YE + {0xB3EA, 0xB160}, //8636 #HANGUL SYLLABLE NIEUN YE NIEUN + {0xB3EB, 0xB178}, //8637 #HANGUL SYLLABLE NIEUN O + {0xB3EC, 0xB179}, //8638 #HANGUL SYLLABLE NIEUN O KIYEOK + {0xB3ED, 0xB17C}, //8639 #HANGUL SYLLABLE NIEUN O NIEUN + {0xB3EE, 0xB180}, //8640 #HANGUL SYLLABLE NIEUN O RIEUL + {0xB3EF, 0xB182}, //8641 #HANGUL SYLLABLE NIEUN O RIEULMIEUM + {0xB3F0, 0xB188}, //8642 #HANGUL SYLLABLE NIEUN O MIEUM + {0xB3F1, 0xB189}, //8643 #HANGUL SYLLABLE NIEUN O PIEUP + {0xB3F2, 0xB18B}, //8644 #HANGUL SYLLABLE NIEUN O SIOS + {0xB3F3, 0xB18D}, //8645 #HANGUL SYLLABLE NIEUN O IEUNG + {0xB3F4, 0xB192}, //8646 #HANGUL SYLLABLE NIEUN O PHIEUPH + {0xB3F5, 0xB193}, //8647 #HANGUL SYLLABLE NIEUN O HIEUH + {0xB3F6, 0xB194}, //8648 #HANGUL SYLLABLE NIEUN WA + {0xB3F7, 0xB198}, //8649 #HANGUL SYLLABLE NIEUN WA NIEUN + {0xB3F8, 0xB19C}, //8650 #HANGUL SYLLABLE NIEUN WA RIEUL + {0xB3F9, 0xB1A8}, //8651 #HANGUL SYLLABLE NIEUN WA SSANGSIOS + {0xB3FA, 0xB1CC}, //8652 #HANGUL SYLLABLE NIEUN OE + {0xB3FB, 0xB1D0}, //8653 #HANGUL SYLLABLE NIEUN OE NIEUN + {0xB3FC, 0xB1D4}, //8654 #HANGUL SYLLABLE NIEUN OE RIEUL + {0xB3FD, 0xB1DC}, //8655 #HANGUL SYLLABLE NIEUN OE MIEUM + {0xB3FE, 0xB1DD}, //8656 #HANGUL SYLLABLE NIEUN OE PIEUP + {0xB441, 0xD02E}, //8657 #HANGUL SYLLABLE KHIEUKH WE CIEUC + {0xB442, 0xD02F}, //8658 #HANGUL SYLLABLE KHIEUKH WE CHIEUCH + {0xB443, 0xD030}, //8659 #HANGUL SYLLABLE KHIEUKH WE KHIEUKH + {0xB444, 0xD031}, //8660 #HANGUL SYLLABLE KHIEUKH WE THIEUTH + {0xB445, 0xD032}, //8661 #HANGUL SYLLABLE KHIEUKH WE PHIEUPH + {0xB446, 0xD033}, //8662 #HANGUL SYLLABLE KHIEUKH WE HIEUH + {0xB447, 0xD036}, //8663 #HANGUL SYLLABLE KHIEUKH WI SSANGKIYEOK + {0xB448, 0xD037}, //8664 #HANGUL SYLLABLE KHIEUKH WI KIYEOKSIOS + {0xB449, 0xD039}, //8665 #HANGUL SYLLABLE KHIEUKH WI NIEUNCIEUC + {0xB44A, 0xD03A}, //8666 #HANGUL SYLLABLE KHIEUKH WI NIEUNHIEUH + {0xB44B, 0xD03B}, //8667 #HANGUL SYLLABLE KHIEUKH WI TIKEUT + {0xB44C, 0xD03D}, //8668 #HANGUL SYLLABLE KHIEUKH WI RIEULKIYEOK + {0xB44D, 0xD03E}, //8669 #HANGUL SYLLABLE KHIEUKH WI RIEULMIEUM + {0xB44E, 0xD03F}, //8670 #HANGUL SYLLABLE KHIEUKH WI RIEULPIEUP + {0xB44F, 0xD040}, //8671 #HANGUL SYLLABLE KHIEUKH WI RIEULSIOS + {0xB450, 0xD041}, //8672 #HANGUL SYLLABLE KHIEUKH WI RIEULTHIEUTH + {0xB451, 0xD042}, //8673 #HANGUL SYLLABLE KHIEUKH WI RIEULPHIEUPH + {0xB452, 0xD043}, //8674 #HANGUL SYLLABLE KHIEUKH WI RIEULHIEUH + {0xB453, 0xD046}, //8675 #HANGUL SYLLABLE KHIEUKH WI PIEUPSIOS + {0xB454, 0xD048}, //8676 #HANGUL SYLLABLE KHIEUKH WI SSANGSIOS + {0xB455, 0xD04A}, //8677 #HANGUL SYLLABLE KHIEUKH WI CIEUC + {0xB456, 0xD04B}, //8678 #HANGUL SYLLABLE KHIEUKH WI CHIEUCH + {0xB457, 0xD04C}, //8679 #HANGUL SYLLABLE KHIEUKH WI KHIEUKH + {0xB458, 0xD04D}, //8680 #HANGUL SYLLABLE KHIEUKH WI THIEUTH + {0xB459, 0xD04E}, //8681 #HANGUL SYLLABLE KHIEUKH WI PHIEUPH + {0xB45A, 0xD04F}, //8682 #HANGUL SYLLABLE KHIEUKH WI HIEUH + {0xB461, 0xD051}, //8683 #HANGUL SYLLABLE KHIEUKH YU KIYEOK + {0xB462, 0xD052}, //8684 #HANGUL SYLLABLE KHIEUKH YU SSANGKIYEOK + {0xB463, 0xD053}, //8685 #HANGUL SYLLABLE KHIEUKH YU KIYEOKSIOS + {0xB464, 0xD055}, //8686 #HANGUL SYLLABLE KHIEUKH YU NIEUNCIEUC + {0xB465, 0xD056}, //8687 #HANGUL SYLLABLE KHIEUKH YU NIEUNHIEUH + {0xB466, 0xD057}, //8688 #HANGUL SYLLABLE KHIEUKH YU TIKEUT + {0xB467, 0xD059}, //8689 #HANGUL SYLLABLE KHIEUKH YU RIEULKIYEOK + {0xB468, 0xD05A}, //8690 #HANGUL SYLLABLE KHIEUKH YU RIEULMIEUM + {0xB469, 0xD05B}, //8691 #HANGUL SYLLABLE KHIEUKH YU RIEULPIEUP + {0xB46A, 0xD05C}, //8692 #HANGUL SYLLABLE KHIEUKH YU RIEULSIOS + {0xB46B, 0xD05D}, //8693 #HANGUL SYLLABLE KHIEUKH YU RIEULTHIEUTH + {0xB46C, 0xD05E}, //8694 #HANGUL SYLLABLE KHIEUKH YU RIEULPHIEUPH + {0xB46D, 0xD05F}, //8695 #HANGUL SYLLABLE KHIEUKH YU RIEULHIEUH + {0xB46E, 0xD061}, //8696 #HANGUL SYLLABLE KHIEUKH YU PIEUP + {0xB46F, 0xD062}, //8697 #HANGUL SYLLABLE KHIEUKH YU PIEUPSIOS + {0xB470, 0xD063}, //8698 #HANGUL SYLLABLE KHIEUKH YU SIOS + {0xB471, 0xD064}, //8699 #HANGUL SYLLABLE KHIEUKH YU SSANGSIOS + {0xB472, 0xD065}, //8700 #HANGUL SYLLABLE KHIEUKH YU IEUNG + {0xB473, 0xD066}, //8701 #HANGUL SYLLABLE KHIEUKH YU CIEUC + {0xB474, 0xD067}, //8702 #HANGUL SYLLABLE KHIEUKH YU CHIEUCH + {0xB475, 0xD068}, //8703 #HANGUL SYLLABLE KHIEUKH YU KHIEUKH + {0xB476, 0xD069}, //8704 #HANGUL SYLLABLE KHIEUKH YU THIEUTH + {0xB477, 0xD06A}, //8705 #HANGUL SYLLABLE KHIEUKH YU PHIEUPH + {0xB478, 0xD06B}, //8706 #HANGUL SYLLABLE KHIEUKH YU HIEUH + {0xB479, 0xD06E}, //8707 #HANGUL SYLLABLE KHIEUKH EU SSANGKIYEOK + {0xB47A, 0xD06F}, //8708 #HANGUL SYLLABLE KHIEUKH EU KIYEOKSIOS + {0xB481, 0xD071}, //8709 #HANGUL SYLLABLE KHIEUKH EU NIEUNCIEUC + {0xB482, 0xD072}, //8710 #HANGUL SYLLABLE KHIEUKH EU NIEUNHIEUH + {0xB483, 0xD073}, //8711 #HANGUL SYLLABLE KHIEUKH EU TIKEUT + {0xB484, 0xD075}, //8712 #HANGUL SYLLABLE KHIEUKH EU RIEULKIYEOK + {0xB485, 0xD076}, //8713 #HANGUL SYLLABLE KHIEUKH EU RIEULMIEUM + {0xB486, 0xD077}, //8714 #HANGUL SYLLABLE KHIEUKH EU RIEULPIEUP + {0xB487, 0xD078}, //8715 #HANGUL SYLLABLE KHIEUKH EU RIEULSIOS + {0xB488, 0xD079}, //8716 #HANGUL SYLLABLE KHIEUKH EU RIEULTHIEUTH + {0xB489, 0xD07A}, //8717 #HANGUL SYLLABLE KHIEUKH EU RIEULPHIEUPH + {0xB48A, 0xD07B}, //8718 #HANGUL SYLLABLE KHIEUKH EU RIEULHIEUH + {0xB48B, 0xD07E}, //8719 #HANGUL SYLLABLE KHIEUKH EU PIEUPSIOS + {0xB48C, 0xD07F}, //8720 #HANGUL SYLLABLE KHIEUKH EU SIOS + {0xB48D, 0xD080}, //8721 #HANGUL SYLLABLE KHIEUKH EU SSANGSIOS + {0xB48E, 0xD082}, //8722 #HANGUL SYLLABLE KHIEUKH EU CIEUC + {0xB48F, 0xD083}, //8723 #HANGUL SYLLABLE KHIEUKH EU CHIEUCH + {0xB490, 0xD084}, //8724 #HANGUL SYLLABLE KHIEUKH EU KHIEUKH + {0xB491, 0xD085}, //8725 #HANGUL SYLLABLE KHIEUKH EU THIEUTH + {0xB492, 0xD086}, //8726 #HANGUL SYLLABLE KHIEUKH EU PHIEUPH + {0xB493, 0xD087}, //8727 #HANGUL SYLLABLE KHIEUKH EU HIEUH + {0xB494, 0xD088}, //8728 #HANGUL SYLLABLE KHIEUKH YI + {0xB495, 0xD089}, //8729 #HANGUL SYLLABLE KHIEUKH YI KIYEOK + {0xB496, 0xD08A}, //8730 #HANGUL SYLLABLE KHIEUKH YI SSANGKIYEOK + {0xB497, 0xD08B}, //8731 #HANGUL SYLLABLE KHIEUKH YI KIYEOKSIOS + {0xB498, 0xD08C}, //8732 #HANGUL SYLLABLE KHIEUKH YI NIEUN + {0xB499, 0xD08D}, //8733 #HANGUL SYLLABLE KHIEUKH YI NIEUNCIEUC + {0xB49A, 0xD08E}, //8734 #HANGUL SYLLABLE KHIEUKH YI NIEUNHIEUH + {0xB49B, 0xD08F}, //8735 #HANGUL SYLLABLE KHIEUKH YI TIKEUT + {0xB49C, 0xD090}, //8736 #HANGUL SYLLABLE KHIEUKH YI RIEUL + {0xB49D, 0xD091}, //8737 #HANGUL SYLLABLE KHIEUKH YI RIEULKIYEOK + {0xB49E, 0xD092}, //8738 #HANGUL SYLLABLE KHIEUKH YI RIEULMIEUM + {0xB49F, 0xD093}, //8739 #HANGUL SYLLABLE KHIEUKH YI RIEULPIEUP + {0xB4A0, 0xD094}, //8740 #HANGUL SYLLABLE KHIEUKH YI RIEULSIOS + {0xB4A1, 0xB1DF}, //8741 #HANGUL SYLLABLE NIEUN OE SIOS + {0xB4A2, 0xB1E8}, //8742 #HANGUL SYLLABLE NIEUN YO + {0xB4A3, 0xB1E9}, //8743 #HANGUL SYLLABLE NIEUN YO KIYEOK + {0xB4A4, 0xB1EC}, //8744 #HANGUL SYLLABLE NIEUN YO NIEUN + {0xB4A5, 0xB1F0}, //8745 #HANGUL SYLLABLE NIEUN YO RIEUL + {0xB4A6, 0xB1F9}, //8746 #HANGUL SYLLABLE NIEUN YO PIEUP + {0xB4A7, 0xB1FB}, //8747 #HANGUL SYLLABLE NIEUN YO SIOS + {0xB4A8, 0xB1FD}, //8748 #HANGUL SYLLABLE NIEUN YO IEUNG + {0xB4A9, 0xB204}, //8749 #HANGUL SYLLABLE NIEUN U + {0xB4AA, 0xB205}, //8750 #HANGUL SYLLABLE NIEUN U KIYEOK + {0xB4AB, 0xB208}, //8751 #HANGUL SYLLABLE NIEUN U NIEUN + {0xB4AC, 0xB20B}, //8752 #HANGUL SYLLABLE NIEUN U TIKEUT + {0xB4AD, 0xB20C}, //8753 #HANGUL SYLLABLE NIEUN U RIEUL + {0xB4AE, 0xB214}, //8754 #HANGUL SYLLABLE NIEUN U MIEUM + {0xB4AF, 0xB215}, //8755 #HANGUL SYLLABLE NIEUN U PIEUP + {0xB4B0, 0xB217}, //8756 #HANGUL SYLLABLE NIEUN U SIOS + {0xB4B1, 0xB219}, //8757 #HANGUL SYLLABLE NIEUN U IEUNG + {0xB4B2, 0xB220}, //8758 #HANGUL SYLLABLE NIEUN WEO + {0xB4B3, 0xB234}, //8759 #HANGUL SYLLABLE NIEUN WEO SSANGSIOS + {0xB4B4, 0xB23C}, //8760 #HANGUL SYLLABLE NIEUN WE + {0xB4B5, 0xB258}, //8761 #HANGUL SYLLABLE NIEUN WI + {0xB4B6, 0xB25C}, //8762 #HANGUL SYLLABLE NIEUN WI NIEUN + {0xB4B7, 0xB260}, //8763 #HANGUL SYLLABLE NIEUN WI RIEUL + {0xB4B8, 0xB268}, //8764 #HANGUL SYLLABLE NIEUN WI MIEUM + {0xB4B9, 0xB269}, //8765 #HANGUL SYLLABLE NIEUN WI PIEUP + {0xB4BA, 0xB274}, //8766 #HANGUL SYLLABLE NIEUN YU + {0xB4BB, 0xB275}, //8767 #HANGUL SYLLABLE NIEUN YU KIYEOK + {0xB4BC, 0xB27C}, //8768 #HANGUL SYLLABLE NIEUN YU RIEUL + {0xB4BD, 0xB284}, //8769 #HANGUL SYLLABLE NIEUN YU MIEUM + {0xB4BE, 0xB285}, //8770 #HANGUL SYLLABLE NIEUN YU PIEUP + {0xB4BF, 0xB289}, //8771 #HANGUL SYLLABLE NIEUN YU IEUNG + {0xB4C0, 0xB290}, //8772 #HANGUL SYLLABLE NIEUN EU + {0xB4C1, 0xB291}, //8773 #HANGUL SYLLABLE NIEUN EU KIYEOK + {0xB4C2, 0xB294}, //8774 #HANGUL SYLLABLE NIEUN EU NIEUN + {0xB4C3, 0xB298}, //8775 #HANGUL SYLLABLE NIEUN EU RIEUL + {0xB4C4, 0xB299}, //8776 #HANGUL SYLLABLE NIEUN EU RIEULKIYEOK + {0xB4C5, 0xB29A}, //8777 #HANGUL SYLLABLE NIEUN EU RIEULMIEUM + {0xB4C6, 0xB2A0}, //8778 #HANGUL SYLLABLE NIEUN EU MIEUM + {0xB4C7, 0xB2A1}, //8779 #HANGUL SYLLABLE NIEUN EU PIEUP + {0xB4C8, 0xB2A3}, //8780 #HANGUL SYLLABLE NIEUN EU SIOS + {0xB4C9, 0xB2A5}, //8781 #HANGUL SYLLABLE NIEUN EU IEUNG + {0xB4CA, 0xB2A6}, //8782 #HANGUL SYLLABLE NIEUN EU CIEUC + {0xB4CB, 0xB2AA}, //8783 #HANGUL SYLLABLE NIEUN EU PHIEUPH + {0xB4CC, 0xB2AC}, //8784 #HANGUL SYLLABLE NIEUN YI + {0xB4CD, 0xB2B0}, //8785 #HANGUL SYLLABLE NIEUN YI NIEUN + {0xB4CE, 0xB2B4}, //8786 #HANGUL SYLLABLE NIEUN YI RIEUL + {0xB4CF, 0xB2C8}, //8787 #HANGUL SYLLABLE NIEUN I + {0xB4D0, 0xB2C9}, //8788 #HANGUL SYLLABLE NIEUN I KIYEOK + {0xB4D1, 0xB2CC}, //8789 #HANGUL SYLLABLE NIEUN I NIEUN + {0xB4D2, 0xB2D0}, //8790 #HANGUL SYLLABLE NIEUN I RIEUL + {0xB4D3, 0xB2D2}, //8791 #HANGUL SYLLABLE NIEUN I RIEULMIEUM + {0xB4D4, 0xB2D8}, //8792 #HANGUL SYLLABLE NIEUN I MIEUM + {0xB4D5, 0xB2D9}, //8793 #HANGUL SYLLABLE NIEUN I PIEUP + {0xB4D6, 0xB2DB}, //8794 #HANGUL SYLLABLE NIEUN I SIOS + {0xB4D7, 0xB2DD}, //8795 #HANGUL SYLLABLE NIEUN I IEUNG + {0xB4D8, 0xB2E2}, //8796 #HANGUL SYLLABLE NIEUN I PHIEUPH + {0xB4D9, 0xB2E4}, //8797 #HANGUL SYLLABLE TIKEUT A + {0xB4DA, 0xB2E5}, //8798 #HANGUL SYLLABLE TIKEUT A KIYEOK + {0xB4DB, 0xB2E6}, //8799 #HANGUL SYLLABLE TIKEUT A SSANGKIYEOK + {0xB4DC, 0xB2E8}, //8800 #HANGUL SYLLABLE TIKEUT A NIEUN + {0xB4DD, 0xB2EB}, //8801 #HANGUL SYLLABLE TIKEUT A TIKEUT + {0xB4DE, 0xB2EC}, //8802 #HANGUL SYLLABLE TIKEUT A RIEUL + {0xB4DF, 0xB2ED}, //8803 #HANGUL SYLLABLE TIKEUT A RIEULKIYEOK + {0xB4E0, 0xB2EE}, //8804 #HANGUL SYLLABLE TIKEUT A RIEULMIEUM + {0xB4E1, 0xB2EF}, //8805 #HANGUL SYLLABLE TIKEUT A RIEULPIEUP + {0xB4E2, 0xB2F3}, //8806 #HANGUL SYLLABLE TIKEUT A RIEULHIEUH + {0xB4E3, 0xB2F4}, //8807 #HANGUL SYLLABLE TIKEUT A MIEUM + {0xB4E4, 0xB2F5}, //8808 #HANGUL SYLLABLE TIKEUT A PIEUP + {0xB4E5, 0xB2F7}, //8809 #HANGUL SYLLABLE TIKEUT A SIOS + {0xB4E6, 0xB2F8}, //8810 #HANGUL SYLLABLE TIKEUT A SSANGSIOS + {0xB4E7, 0xB2F9}, //8811 #HANGUL SYLLABLE TIKEUT A IEUNG + {0xB4E8, 0xB2FA}, //8812 #HANGUL SYLLABLE TIKEUT A CIEUC + {0xB4E9, 0xB2FB}, //8813 #HANGUL SYLLABLE TIKEUT A CHIEUCH + {0xB4EA, 0xB2FF}, //8814 #HANGUL SYLLABLE TIKEUT A HIEUH + {0xB4EB, 0xB300}, //8815 #HANGUL SYLLABLE TIKEUT AE + {0xB4EC, 0xB301}, //8816 #HANGUL SYLLABLE TIKEUT AE KIYEOK + {0xB4ED, 0xB304}, //8817 #HANGUL SYLLABLE TIKEUT AE NIEUN + {0xB4EE, 0xB308}, //8818 #HANGUL SYLLABLE TIKEUT AE RIEUL + {0xB4EF, 0xB310}, //8819 #HANGUL SYLLABLE TIKEUT AE MIEUM + {0xB4F0, 0xB311}, //8820 #HANGUL SYLLABLE TIKEUT AE PIEUP + {0xB4F1, 0xB313}, //8821 #HANGUL SYLLABLE TIKEUT AE SIOS + {0xB4F2, 0xB314}, //8822 #HANGUL SYLLABLE TIKEUT AE SSANGSIOS + {0xB4F3, 0xB315}, //8823 #HANGUL SYLLABLE TIKEUT AE IEUNG + {0xB4F4, 0xB31C}, //8824 #HANGUL SYLLABLE TIKEUT YA + {0xB4F5, 0xB354}, //8825 #HANGUL SYLLABLE TIKEUT EO + {0xB4F6, 0xB355}, //8826 #HANGUL SYLLABLE TIKEUT EO KIYEOK + {0xB4F7, 0xB356}, //8827 #HANGUL SYLLABLE TIKEUT EO SSANGKIYEOK + {0xB4F8, 0xB358}, //8828 #HANGUL SYLLABLE TIKEUT EO NIEUN + {0xB4F9, 0xB35B}, //8829 #HANGUL SYLLABLE TIKEUT EO TIKEUT + {0xB4FA, 0xB35C}, //8830 #HANGUL SYLLABLE TIKEUT EO RIEUL + {0xB4FB, 0xB35E}, //8831 #HANGUL SYLLABLE TIKEUT EO RIEULMIEUM + {0xB4FC, 0xB35F}, //8832 #HANGUL SYLLABLE TIKEUT EO RIEULPIEUP + {0xB4FD, 0xB364}, //8833 #HANGUL SYLLABLE TIKEUT EO MIEUM + {0xB4FE, 0xB365}, //8834 #HANGUL SYLLABLE TIKEUT EO PIEUP + {0xB541, 0xD095}, //8835 #HANGUL SYLLABLE KHIEUKH YI RIEULTHIEUTH + {0xB542, 0xD096}, //8836 #HANGUL SYLLABLE KHIEUKH YI RIEULPHIEUPH + {0xB543, 0xD097}, //8837 #HANGUL SYLLABLE KHIEUKH YI RIEULHIEUH + {0xB544, 0xD098}, //8838 #HANGUL SYLLABLE KHIEUKH YI MIEUM + {0xB545, 0xD099}, //8839 #HANGUL SYLLABLE KHIEUKH YI PIEUP + {0xB546, 0xD09A}, //8840 #HANGUL SYLLABLE KHIEUKH YI PIEUPSIOS + {0xB547, 0xD09B}, //8841 #HANGUL SYLLABLE KHIEUKH YI SIOS + {0xB548, 0xD09C}, //8842 #HANGUL SYLLABLE KHIEUKH YI SSANGSIOS + {0xB549, 0xD09D}, //8843 #HANGUL SYLLABLE KHIEUKH YI IEUNG + {0xB54A, 0xD09E}, //8844 #HANGUL SYLLABLE KHIEUKH YI CIEUC + {0xB54B, 0xD09F}, //8845 #HANGUL SYLLABLE KHIEUKH YI CHIEUCH + {0xB54C, 0xD0A0}, //8846 #HANGUL SYLLABLE KHIEUKH YI KHIEUKH + {0xB54D, 0xD0A1}, //8847 #HANGUL SYLLABLE KHIEUKH YI THIEUTH + {0xB54E, 0xD0A2}, //8848 #HANGUL SYLLABLE KHIEUKH YI PHIEUPH + {0xB54F, 0xD0A3}, //8849 #HANGUL SYLLABLE KHIEUKH YI HIEUH + {0xB550, 0xD0A6}, //8850 #HANGUL SYLLABLE KHIEUKH I SSANGKIYEOK + {0xB551, 0xD0A7}, //8851 #HANGUL SYLLABLE KHIEUKH I KIYEOKSIOS + {0xB552, 0xD0A9}, //8852 #HANGUL SYLLABLE KHIEUKH I NIEUNCIEUC + {0xB553, 0xD0AA}, //8853 #HANGUL SYLLABLE KHIEUKH I NIEUNHIEUH + {0xB554, 0xD0AB}, //8854 #HANGUL SYLLABLE KHIEUKH I TIKEUT + {0xB555, 0xD0AD}, //8855 #HANGUL SYLLABLE KHIEUKH I RIEULKIYEOK + {0xB556, 0xD0AE}, //8856 #HANGUL SYLLABLE KHIEUKH I RIEULMIEUM + {0xB557, 0xD0AF}, //8857 #HANGUL SYLLABLE KHIEUKH I RIEULPIEUP + {0xB558, 0xD0B0}, //8858 #HANGUL SYLLABLE KHIEUKH I RIEULSIOS + {0xB559, 0xD0B1}, //8859 #HANGUL SYLLABLE KHIEUKH I RIEULTHIEUTH + {0xB55A, 0xD0B2}, //8860 #HANGUL SYLLABLE KHIEUKH I RIEULPHIEUPH + {0xB561, 0xD0B3}, //8861 #HANGUL SYLLABLE KHIEUKH I RIEULHIEUH + {0xB562, 0xD0B6}, //8862 #HANGUL SYLLABLE KHIEUKH I PIEUPSIOS + {0xB563, 0xD0B8}, //8863 #HANGUL SYLLABLE KHIEUKH I SSANGSIOS + {0xB564, 0xD0BA}, //8864 #HANGUL SYLLABLE KHIEUKH I CIEUC + {0xB565, 0xD0BB}, //8865 #HANGUL SYLLABLE KHIEUKH I CHIEUCH + {0xB566, 0xD0BC}, //8866 #HANGUL SYLLABLE KHIEUKH I KHIEUKH + {0xB567, 0xD0BD}, //8867 #HANGUL SYLLABLE KHIEUKH I THIEUTH + {0xB568, 0xD0BE}, //8868 #HANGUL SYLLABLE KHIEUKH I PHIEUPH + {0xB569, 0xD0BF}, //8869 #HANGUL SYLLABLE KHIEUKH I HIEUH + {0xB56A, 0xD0C2}, //8870 #HANGUL SYLLABLE THIEUTH A SSANGKIYEOK + {0xB56B, 0xD0C3}, //8871 #HANGUL SYLLABLE THIEUTH A KIYEOKSIOS + {0xB56C, 0xD0C5}, //8872 #HANGUL SYLLABLE THIEUTH A NIEUNCIEUC + {0xB56D, 0xD0C6}, //8873 #HANGUL SYLLABLE THIEUTH A NIEUNHIEUH + {0xB56E, 0xD0C7}, //8874 #HANGUL SYLLABLE THIEUTH A TIKEUT + {0xB56F, 0xD0CA}, //8875 #HANGUL SYLLABLE THIEUTH A RIEULMIEUM + {0xB570, 0xD0CB}, //8876 #HANGUL SYLLABLE THIEUTH A RIEULPIEUP + {0xB571, 0xD0CC}, //8877 #HANGUL SYLLABLE THIEUTH A RIEULSIOS + {0xB572, 0xD0CD}, //8878 #HANGUL SYLLABLE THIEUTH A RIEULTHIEUTH + {0xB573, 0xD0CE}, //8879 #HANGUL SYLLABLE THIEUTH A RIEULPHIEUPH + {0xB574, 0xD0CF}, //8880 #HANGUL SYLLABLE THIEUTH A RIEULHIEUH + {0xB575, 0xD0D2}, //8881 #HANGUL SYLLABLE THIEUTH A PIEUPSIOS + {0xB576, 0xD0D6}, //8882 #HANGUL SYLLABLE THIEUTH A CIEUC + {0xB577, 0xD0D7}, //8883 #HANGUL SYLLABLE THIEUTH A CHIEUCH + {0xB578, 0xD0D8}, //8884 #HANGUL SYLLABLE THIEUTH A KHIEUKH + {0xB579, 0xD0D9}, //8885 #HANGUL SYLLABLE THIEUTH A THIEUTH + {0xB57A, 0xD0DA}, //8886 #HANGUL SYLLABLE THIEUTH A PHIEUPH + {0xB581, 0xD0DB}, //8887 #HANGUL SYLLABLE THIEUTH A HIEUH + {0xB582, 0xD0DE}, //8888 #HANGUL SYLLABLE THIEUTH AE SSANGKIYEOK + {0xB583, 0xD0DF}, //8889 #HANGUL SYLLABLE THIEUTH AE KIYEOKSIOS + {0xB584, 0xD0E1}, //8890 #HANGUL SYLLABLE THIEUTH AE NIEUNCIEUC + {0xB585, 0xD0E2}, //8891 #HANGUL SYLLABLE THIEUTH AE NIEUNHIEUH + {0xB586, 0xD0E3}, //8892 #HANGUL SYLLABLE THIEUTH AE TIKEUT + {0xB587, 0xD0E5}, //8893 #HANGUL SYLLABLE THIEUTH AE RIEULKIYEOK + {0xB588, 0xD0E6}, //8894 #HANGUL SYLLABLE THIEUTH AE RIEULMIEUM + {0xB589, 0xD0E7}, //8895 #HANGUL SYLLABLE THIEUTH AE RIEULPIEUP + {0xB58A, 0xD0E8}, //8896 #HANGUL SYLLABLE THIEUTH AE RIEULSIOS + {0xB58B, 0xD0E9}, //8897 #HANGUL SYLLABLE THIEUTH AE RIEULTHIEUTH + {0xB58C, 0xD0EA}, //8898 #HANGUL SYLLABLE THIEUTH AE RIEULPHIEUPH + {0xB58D, 0xD0EB}, //8899 #HANGUL SYLLABLE THIEUTH AE RIEULHIEUH + {0xB58E, 0xD0EE}, //8900 #HANGUL SYLLABLE THIEUTH AE PIEUPSIOS + {0xB58F, 0xD0F2}, //8901 #HANGUL SYLLABLE THIEUTH AE CIEUC + {0xB590, 0xD0F3}, //8902 #HANGUL SYLLABLE THIEUTH AE CHIEUCH + {0xB591, 0xD0F4}, //8903 #HANGUL SYLLABLE THIEUTH AE KHIEUKH + {0xB592, 0xD0F5}, //8904 #HANGUL SYLLABLE THIEUTH AE THIEUTH + {0xB593, 0xD0F6}, //8905 #HANGUL SYLLABLE THIEUTH AE PHIEUPH + {0xB594, 0xD0F7}, //8906 #HANGUL SYLLABLE THIEUTH AE HIEUH + {0xB595, 0xD0F9}, //8907 #HANGUL SYLLABLE THIEUTH YA KIYEOK + {0xB596, 0xD0FA}, //8908 #HANGUL SYLLABLE THIEUTH YA SSANGKIYEOK + {0xB597, 0xD0FB}, //8909 #HANGUL SYLLABLE THIEUTH YA KIYEOKSIOS + {0xB598, 0xD0FC}, //8910 #HANGUL SYLLABLE THIEUTH YA NIEUN + {0xB599, 0xD0FD}, //8911 #HANGUL SYLLABLE THIEUTH YA NIEUNCIEUC + {0xB59A, 0xD0FE}, //8912 #HANGUL SYLLABLE THIEUTH YA NIEUNHIEUH + {0xB59B, 0xD0FF}, //8913 #HANGUL SYLLABLE THIEUTH YA TIKEUT + {0xB59C, 0xD100}, //8914 #HANGUL SYLLABLE THIEUTH YA RIEUL + {0xB59D, 0xD101}, //8915 #HANGUL SYLLABLE THIEUTH YA RIEULKIYEOK + {0xB59E, 0xD102}, //8916 #HANGUL SYLLABLE THIEUTH YA RIEULMIEUM + {0xB59F, 0xD103}, //8917 #HANGUL SYLLABLE THIEUTH YA RIEULPIEUP + {0xB5A0, 0xD104}, //8918 #HANGUL SYLLABLE THIEUTH YA RIEULSIOS + {0xB5A1, 0xB367}, //8919 #HANGUL SYLLABLE TIKEUT EO SIOS + {0xB5A2, 0xB369}, //8920 #HANGUL SYLLABLE TIKEUT EO IEUNG + {0xB5A3, 0xB36B}, //8921 #HANGUL SYLLABLE TIKEUT EO CHIEUCH + {0xB5A4, 0xB36E}, //8922 #HANGUL SYLLABLE TIKEUT EO PHIEUPH + {0xB5A5, 0xB370}, //8923 #HANGUL SYLLABLE TIKEUT E + {0xB5A6, 0xB371}, //8924 #HANGUL SYLLABLE TIKEUT E KIYEOK + {0xB5A7, 0xB374}, //8925 #HANGUL SYLLABLE TIKEUT E NIEUN + {0xB5A8, 0xB378}, //8926 #HANGUL SYLLABLE TIKEUT E RIEUL + {0xB5A9, 0xB380}, //8927 #HANGUL SYLLABLE TIKEUT E MIEUM + {0xB5AA, 0xB381}, //8928 #HANGUL SYLLABLE TIKEUT E PIEUP + {0xB5AB, 0xB383}, //8929 #HANGUL SYLLABLE TIKEUT E SIOS + {0xB5AC, 0xB384}, //8930 #HANGUL SYLLABLE TIKEUT E SSANGSIOS + {0xB5AD, 0xB385}, //8931 #HANGUL SYLLABLE TIKEUT E IEUNG + {0xB5AE, 0xB38C}, //8932 #HANGUL SYLLABLE TIKEUT YEO + {0xB5AF, 0xB390}, //8933 #HANGUL SYLLABLE TIKEUT YEO NIEUN + {0xB5B0, 0xB394}, //8934 #HANGUL SYLLABLE TIKEUT YEO RIEUL + {0xB5B1, 0xB3A0}, //8935 #HANGUL SYLLABLE TIKEUT YEO SSANGSIOS + {0xB5B2, 0xB3A1}, //8936 #HANGUL SYLLABLE TIKEUT YEO IEUNG + {0xB5B3, 0xB3A8}, //8937 #HANGUL SYLLABLE TIKEUT YE + {0xB5B4, 0xB3AC}, //8938 #HANGUL SYLLABLE TIKEUT YE NIEUN + {0xB5B5, 0xB3C4}, //8939 #HANGUL SYLLABLE TIKEUT O + {0xB5B6, 0xB3C5}, //8940 #HANGUL SYLLABLE TIKEUT O KIYEOK + {0xB5B7, 0xB3C8}, //8941 #HANGUL SYLLABLE TIKEUT O NIEUN + {0xB5B8, 0xB3CB}, //8942 #HANGUL SYLLABLE TIKEUT O TIKEUT + {0xB5B9, 0xB3CC}, //8943 #HANGUL SYLLABLE TIKEUT O RIEUL + {0xB5BA, 0xB3CE}, //8944 #HANGUL SYLLABLE TIKEUT O RIEULMIEUM + {0xB5BB, 0xB3D0}, //8945 #HANGUL SYLLABLE TIKEUT O RIEULSIOS + {0xB5BC, 0xB3D4}, //8946 #HANGUL SYLLABLE TIKEUT O MIEUM + {0xB5BD, 0xB3D5}, //8947 #HANGUL SYLLABLE TIKEUT O PIEUP + {0xB5BE, 0xB3D7}, //8948 #HANGUL SYLLABLE TIKEUT O SIOS + {0xB5BF, 0xB3D9}, //8949 #HANGUL SYLLABLE TIKEUT O IEUNG + {0xB5C0, 0xB3DB}, //8950 #HANGUL SYLLABLE TIKEUT O CHIEUCH + {0xB5C1, 0xB3DD}, //8951 #HANGUL SYLLABLE TIKEUT O THIEUTH + {0xB5C2, 0xB3E0}, //8952 #HANGUL SYLLABLE TIKEUT WA + {0xB5C3, 0xB3E4}, //8953 #HANGUL SYLLABLE TIKEUT WA NIEUN + {0xB5C4, 0xB3E8}, //8954 #HANGUL SYLLABLE TIKEUT WA RIEUL + {0xB5C5, 0xB3FC}, //8955 #HANGUL SYLLABLE TIKEUT WAE + {0xB5C6, 0xB410}, //8956 #HANGUL SYLLABLE TIKEUT WAE SSANGSIOS + {0xB5C7, 0xB418}, //8957 #HANGUL SYLLABLE TIKEUT OE + {0xB5C8, 0xB41C}, //8958 #HANGUL SYLLABLE TIKEUT OE NIEUN + {0xB5C9, 0xB420}, //8959 #HANGUL SYLLABLE TIKEUT OE RIEUL + {0xB5CA, 0xB428}, //8960 #HANGUL SYLLABLE TIKEUT OE MIEUM + {0xB5CB, 0xB429}, //8961 #HANGUL SYLLABLE TIKEUT OE PIEUP + {0xB5CC, 0xB42B}, //8962 #HANGUL SYLLABLE TIKEUT OE SIOS + {0xB5CD, 0xB434}, //8963 #HANGUL SYLLABLE TIKEUT YO + {0xB5CE, 0xB450}, //8964 #HANGUL SYLLABLE TIKEUT U + {0xB5CF, 0xB451}, //8965 #HANGUL SYLLABLE TIKEUT U KIYEOK + {0xB5D0, 0xB454}, //8966 #HANGUL SYLLABLE TIKEUT U NIEUN + {0xB5D1, 0xB458}, //8967 #HANGUL SYLLABLE TIKEUT U RIEUL + {0xB5D2, 0xB460}, //8968 #HANGUL SYLLABLE TIKEUT U MIEUM + {0xB5D3, 0xB461}, //8969 #HANGUL SYLLABLE TIKEUT U PIEUP + {0xB5D4, 0xB463}, //8970 #HANGUL SYLLABLE TIKEUT U SIOS + {0xB5D5, 0xB465}, //8971 #HANGUL SYLLABLE TIKEUT U IEUNG + {0xB5D6, 0xB46C}, //8972 #HANGUL SYLLABLE TIKEUT WEO + {0xB5D7, 0xB480}, //8973 #HANGUL SYLLABLE TIKEUT WEO SSANGSIOS + {0xB5D8, 0xB488}, //8974 #HANGUL SYLLABLE TIKEUT WE + {0xB5D9, 0xB49D}, //8975 #HANGUL SYLLABLE TIKEUT WE IEUNG + {0xB5DA, 0xB4A4}, //8976 #HANGUL SYLLABLE TIKEUT WI + {0xB5DB, 0xB4A8}, //8977 #HANGUL SYLLABLE TIKEUT WI NIEUN + {0xB5DC, 0xB4AC}, //8978 #HANGUL SYLLABLE TIKEUT WI RIEUL + {0xB5DD, 0xB4B5}, //8979 #HANGUL SYLLABLE TIKEUT WI PIEUP + {0xB5DE, 0xB4B7}, //8980 #HANGUL SYLLABLE TIKEUT WI SIOS + {0xB5DF, 0xB4B9}, //8981 #HANGUL SYLLABLE TIKEUT WI IEUNG + {0xB5E0, 0xB4C0}, //8982 #HANGUL SYLLABLE TIKEUT YU + {0xB5E1, 0xB4C4}, //8983 #HANGUL SYLLABLE TIKEUT YU NIEUN + {0xB5E2, 0xB4C8}, //8984 #HANGUL SYLLABLE TIKEUT YU RIEUL + {0xB5E3, 0xB4D0}, //8985 #HANGUL SYLLABLE TIKEUT YU MIEUM + {0xB5E4, 0xB4D5}, //8986 #HANGUL SYLLABLE TIKEUT YU IEUNG + {0xB5E5, 0xB4DC}, //8987 #HANGUL SYLLABLE TIKEUT EU + {0xB5E6, 0xB4DD}, //8988 #HANGUL SYLLABLE TIKEUT EU KIYEOK + {0xB5E7, 0xB4E0}, //8989 #HANGUL SYLLABLE TIKEUT EU NIEUN + {0xB5E8, 0xB4E3}, //8990 #HANGUL SYLLABLE TIKEUT EU TIKEUT + {0xB5E9, 0xB4E4}, //8991 #HANGUL SYLLABLE TIKEUT EU RIEUL + {0xB5EA, 0xB4E6}, //8992 #HANGUL SYLLABLE TIKEUT EU RIEULMIEUM + {0xB5EB, 0xB4EC}, //8993 #HANGUL SYLLABLE TIKEUT EU MIEUM + {0xB5EC, 0xB4ED}, //8994 #HANGUL SYLLABLE TIKEUT EU PIEUP + {0xB5ED, 0xB4EF}, //8995 #HANGUL SYLLABLE TIKEUT EU SIOS + {0xB5EE, 0xB4F1}, //8996 #HANGUL SYLLABLE TIKEUT EU IEUNG + {0xB5EF, 0xB4F8}, //8997 #HANGUL SYLLABLE TIKEUT YI + {0xB5F0, 0xB514}, //8998 #HANGUL SYLLABLE TIKEUT I + {0xB5F1, 0xB515}, //8999 #HANGUL SYLLABLE TIKEUT I KIYEOK + {0xB5F2, 0xB518}, //9000 #HANGUL SYLLABLE TIKEUT I NIEUN + {0xB5F3, 0xB51B}, //9001 #HANGUL SYLLABLE TIKEUT I TIKEUT + {0xB5F4, 0xB51C}, //9002 #HANGUL SYLLABLE TIKEUT I RIEUL + {0xB5F5, 0xB524}, //9003 #HANGUL SYLLABLE TIKEUT I MIEUM + {0xB5F6, 0xB525}, //9004 #HANGUL SYLLABLE TIKEUT I PIEUP + {0xB5F7, 0xB527}, //9005 #HANGUL SYLLABLE TIKEUT I SIOS + {0xB5F8, 0xB528}, //9006 #HANGUL SYLLABLE TIKEUT I SSANGSIOS + {0xB5F9, 0xB529}, //9007 #HANGUL SYLLABLE TIKEUT I IEUNG + {0xB5FA, 0xB52A}, //9008 #HANGUL SYLLABLE TIKEUT I CIEUC + {0xB5FB, 0xB530}, //9009 #HANGUL SYLLABLE SSANGTIKEUT A + {0xB5FC, 0xB531}, //9010 #HANGUL SYLLABLE SSANGTIKEUT A KIYEOK + {0xB5FD, 0xB534}, //9011 #HANGUL SYLLABLE SSANGTIKEUT A NIEUN + {0xB5FE, 0xB538}, //9012 #HANGUL SYLLABLE SSANGTIKEUT A RIEUL + {0xB641, 0xD105}, //9013 #HANGUL SYLLABLE THIEUTH YA RIEULTHIEUTH + {0xB642, 0xD106}, //9014 #HANGUL SYLLABLE THIEUTH YA RIEULPHIEUPH + {0xB643, 0xD107}, //9015 #HANGUL SYLLABLE THIEUTH YA RIEULHIEUH + {0xB644, 0xD108}, //9016 #HANGUL SYLLABLE THIEUTH YA MIEUM + {0xB645, 0xD109}, //9017 #HANGUL SYLLABLE THIEUTH YA PIEUP + {0xB646, 0xD10A}, //9018 #HANGUL SYLLABLE THIEUTH YA PIEUPSIOS + {0xB647, 0xD10B}, //9019 #HANGUL SYLLABLE THIEUTH YA SIOS + {0xB648, 0xD10C}, //9020 #HANGUL SYLLABLE THIEUTH YA SSANGSIOS + {0xB649, 0xD10E}, //9021 #HANGUL SYLLABLE THIEUTH YA CIEUC + {0xB64A, 0xD10F}, //9022 #HANGUL SYLLABLE THIEUTH YA CHIEUCH + {0xB64B, 0xD110}, //9023 #HANGUL SYLLABLE THIEUTH YA KHIEUKH + {0xB64C, 0xD111}, //9024 #HANGUL SYLLABLE THIEUTH YA THIEUTH + {0xB64D, 0xD112}, //9025 #HANGUL SYLLABLE THIEUTH YA PHIEUPH + {0xB64E, 0xD113}, //9026 #HANGUL SYLLABLE THIEUTH YA HIEUH + {0xB64F, 0xD114}, //9027 #HANGUL SYLLABLE THIEUTH YAE + {0xB650, 0xD115}, //9028 #HANGUL SYLLABLE THIEUTH YAE KIYEOK + {0xB651, 0xD116}, //9029 #HANGUL SYLLABLE THIEUTH YAE SSANGKIYEOK + {0xB652, 0xD117}, //9030 #HANGUL SYLLABLE THIEUTH YAE KIYEOKSIOS + {0xB653, 0xD118}, //9031 #HANGUL SYLLABLE THIEUTH YAE NIEUN + {0xB654, 0xD119}, //9032 #HANGUL SYLLABLE THIEUTH YAE NIEUNCIEUC + {0xB655, 0xD11A}, //9033 #HANGUL SYLLABLE THIEUTH YAE NIEUNHIEUH + {0xB656, 0xD11B}, //9034 #HANGUL SYLLABLE THIEUTH YAE TIKEUT + {0xB657, 0xD11C}, //9035 #HANGUL SYLLABLE THIEUTH YAE RIEUL + {0xB658, 0xD11D}, //9036 #HANGUL SYLLABLE THIEUTH YAE RIEULKIYEOK + {0xB659, 0xD11E}, //9037 #HANGUL SYLLABLE THIEUTH YAE RIEULMIEUM + {0xB65A, 0xD11F}, //9038 #HANGUL SYLLABLE THIEUTH YAE RIEULPIEUP + {0xB661, 0xD120}, //9039 #HANGUL SYLLABLE THIEUTH YAE RIEULSIOS + {0xB662, 0xD121}, //9040 #HANGUL SYLLABLE THIEUTH YAE RIEULTHIEUTH + {0xB663, 0xD122}, //9041 #HANGUL SYLLABLE THIEUTH YAE RIEULPHIEUPH + {0xB664, 0xD123}, //9042 #HANGUL SYLLABLE THIEUTH YAE RIEULHIEUH + {0xB665, 0xD124}, //9043 #HANGUL SYLLABLE THIEUTH YAE MIEUM + {0xB666, 0xD125}, //9044 #HANGUL SYLLABLE THIEUTH YAE PIEUP + {0xB667, 0xD126}, //9045 #HANGUL SYLLABLE THIEUTH YAE PIEUPSIOS + {0xB668, 0xD127}, //9046 #HANGUL SYLLABLE THIEUTH YAE SIOS + {0xB669, 0xD128}, //9047 #HANGUL SYLLABLE THIEUTH YAE SSANGSIOS + {0xB66A, 0xD129}, //9048 #HANGUL SYLLABLE THIEUTH YAE IEUNG + {0xB66B, 0xD12A}, //9049 #HANGUL SYLLABLE THIEUTH YAE CIEUC + {0xB66C, 0xD12B}, //9050 #HANGUL SYLLABLE THIEUTH YAE CHIEUCH + {0xB66D, 0xD12C}, //9051 #HANGUL SYLLABLE THIEUTH YAE KHIEUKH + {0xB66E, 0xD12D}, //9052 #HANGUL SYLLABLE THIEUTH YAE THIEUTH + {0xB66F, 0xD12E}, //9053 #HANGUL SYLLABLE THIEUTH YAE PHIEUPH + {0xB670, 0xD12F}, //9054 #HANGUL SYLLABLE THIEUTH YAE HIEUH + {0xB671, 0xD132}, //9055 #HANGUL SYLLABLE THIEUTH EO SSANGKIYEOK + {0xB672, 0xD133}, //9056 #HANGUL SYLLABLE THIEUTH EO KIYEOKSIOS + {0xB673, 0xD135}, //9057 #HANGUL SYLLABLE THIEUTH EO NIEUNCIEUC + {0xB674, 0xD136}, //9058 #HANGUL SYLLABLE THIEUTH EO NIEUNHIEUH + {0xB675, 0xD137}, //9059 #HANGUL SYLLABLE THIEUTH EO TIKEUT + {0xB676, 0xD139}, //9060 #HANGUL SYLLABLE THIEUTH EO RIEULKIYEOK + {0xB677, 0xD13B}, //9061 #HANGUL SYLLABLE THIEUTH EO RIEULPIEUP + {0xB678, 0xD13C}, //9062 #HANGUL SYLLABLE THIEUTH EO RIEULSIOS + {0xB679, 0xD13D}, //9063 #HANGUL SYLLABLE THIEUTH EO RIEULTHIEUTH + {0xB67A, 0xD13E}, //9064 #HANGUL SYLLABLE THIEUTH EO RIEULPHIEUPH + {0xB681, 0xD13F}, //9065 #HANGUL SYLLABLE THIEUTH EO RIEULHIEUH + {0xB682, 0xD142}, //9066 #HANGUL SYLLABLE THIEUTH EO PIEUPSIOS + {0xB683, 0xD146}, //9067 #HANGUL SYLLABLE THIEUTH EO CIEUC + {0xB684, 0xD147}, //9068 #HANGUL SYLLABLE THIEUTH EO CHIEUCH + {0xB685, 0xD148}, //9069 #HANGUL SYLLABLE THIEUTH EO KHIEUKH + {0xB686, 0xD149}, //9070 #HANGUL SYLLABLE THIEUTH EO THIEUTH + {0xB687, 0xD14A}, //9071 #HANGUL SYLLABLE THIEUTH EO PHIEUPH + {0xB688, 0xD14B}, //9072 #HANGUL SYLLABLE THIEUTH EO HIEUH + {0xB689, 0xD14E}, //9073 #HANGUL SYLLABLE THIEUTH E SSANGKIYEOK + {0xB68A, 0xD14F}, //9074 #HANGUL SYLLABLE THIEUTH E KIYEOKSIOS + {0xB68B, 0xD151}, //9075 #HANGUL SYLLABLE THIEUTH E NIEUNCIEUC + {0xB68C, 0xD152}, //9076 #HANGUL SYLLABLE THIEUTH E NIEUNHIEUH + {0xB68D, 0xD153}, //9077 #HANGUL SYLLABLE THIEUTH E TIKEUT + {0xB68E, 0xD155}, //9078 #HANGUL SYLLABLE THIEUTH E RIEULKIYEOK + {0xB68F, 0xD156}, //9079 #HANGUL SYLLABLE THIEUTH E RIEULMIEUM + {0xB690, 0xD157}, //9080 #HANGUL SYLLABLE THIEUTH E RIEULPIEUP + {0xB691, 0xD158}, //9081 #HANGUL SYLLABLE THIEUTH E RIEULSIOS + {0xB692, 0xD159}, //9082 #HANGUL SYLLABLE THIEUTH E RIEULTHIEUTH + {0xB693, 0xD15A}, //9083 #HANGUL SYLLABLE THIEUTH E RIEULPHIEUPH + {0xB694, 0xD15B}, //9084 #HANGUL SYLLABLE THIEUTH E RIEULHIEUH + {0xB695, 0xD15E}, //9085 #HANGUL SYLLABLE THIEUTH E PIEUPSIOS + {0xB696, 0xD160}, //9086 #HANGUL SYLLABLE THIEUTH E SSANGSIOS + {0xB697, 0xD162}, //9087 #HANGUL SYLLABLE THIEUTH E CIEUC + {0xB698, 0xD163}, //9088 #HANGUL SYLLABLE THIEUTH E CHIEUCH + {0xB699, 0xD164}, //9089 #HANGUL SYLLABLE THIEUTH E KHIEUKH + {0xB69A, 0xD165}, //9090 #HANGUL SYLLABLE THIEUTH E THIEUTH + {0xB69B, 0xD166}, //9091 #HANGUL SYLLABLE THIEUTH E PHIEUPH + {0xB69C, 0xD167}, //9092 #HANGUL SYLLABLE THIEUTH E HIEUH + {0xB69D, 0xD169}, //9093 #HANGUL SYLLABLE THIEUTH YEO KIYEOK + {0xB69E, 0xD16A}, //9094 #HANGUL SYLLABLE THIEUTH YEO SSANGKIYEOK + {0xB69F, 0xD16B}, //9095 #HANGUL SYLLABLE THIEUTH YEO KIYEOKSIOS + {0xB6A0, 0xD16D}, //9096 #HANGUL SYLLABLE THIEUTH YEO NIEUNCIEUC + {0xB6A1, 0xB540}, //9097 #HANGUL SYLLABLE SSANGTIKEUT A MIEUM + {0xB6A2, 0xB541}, //9098 #HANGUL SYLLABLE SSANGTIKEUT A PIEUP + {0xB6A3, 0xB543}, //9099 #HANGUL SYLLABLE SSANGTIKEUT A SIOS + {0xB6A4, 0xB544}, //9100 #HANGUL SYLLABLE SSANGTIKEUT A SSANGSIOS + {0xB6A5, 0xB545}, //9101 #HANGUL SYLLABLE SSANGTIKEUT A IEUNG + {0xB6A6, 0xB54B}, //9102 #HANGUL SYLLABLE SSANGTIKEUT A HIEUH + {0xB6A7, 0xB54C}, //9103 #HANGUL SYLLABLE SSANGTIKEUT AE + {0xB6A8, 0xB54D}, //9104 #HANGUL SYLLABLE SSANGTIKEUT AE KIYEOK + {0xB6A9, 0xB550}, //9105 #HANGUL SYLLABLE SSANGTIKEUT AE NIEUN + {0xB6AA, 0xB554}, //9106 #HANGUL SYLLABLE SSANGTIKEUT AE RIEUL + {0xB6AB, 0xB55C}, //9107 #HANGUL SYLLABLE SSANGTIKEUT AE MIEUM + {0xB6AC, 0xB55D}, //9108 #HANGUL SYLLABLE SSANGTIKEUT AE PIEUP + {0xB6AD, 0xB55F}, //9109 #HANGUL SYLLABLE SSANGTIKEUT AE SIOS + {0xB6AE, 0xB560}, //9110 #HANGUL SYLLABLE SSANGTIKEUT AE SSANGSIOS + {0xB6AF, 0xB561}, //9111 #HANGUL SYLLABLE SSANGTIKEUT AE IEUNG + {0xB6B0, 0xB5A0}, //9112 #HANGUL SYLLABLE SSANGTIKEUT EO + {0xB6B1, 0xB5A1}, //9113 #HANGUL SYLLABLE SSANGTIKEUT EO KIYEOK + {0xB6B2, 0xB5A4}, //9114 #HANGUL SYLLABLE SSANGTIKEUT EO NIEUN + {0xB6B3, 0xB5A8}, //9115 #HANGUL SYLLABLE SSANGTIKEUT EO RIEUL + {0xB6B4, 0xB5AA}, //9116 #HANGUL SYLLABLE SSANGTIKEUT EO RIEULMIEUM + {0xB6B5, 0xB5AB}, //9117 #HANGUL SYLLABLE SSANGTIKEUT EO RIEULPIEUP + {0xB6B6, 0xB5B0}, //9118 #HANGUL SYLLABLE SSANGTIKEUT EO MIEUM + {0xB6B7, 0xB5B1}, //9119 #HANGUL SYLLABLE SSANGTIKEUT EO PIEUP + {0xB6B8, 0xB5B3}, //9120 #HANGUL SYLLABLE SSANGTIKEUT EO SIOS + {0xB6B9, 0xB5B4}, //9121 #HANGUL SYLLABLE SSANGTIKEUT EO SSANGSIOS + {0xB6BA, 0xB5B5}, //9122 #HANGUL SYLLABLE SSANGTIKEUT EO IEUNG + {0xB6BB, 0xB5BB}, //9123 #HANGUL SYLLABLE SSANGTIKEUT EO HIEUH + {0xB6BC, 0xB5BC}, //9124 #HANGUL SYLLABLE SSANGTIKEUT E + {0xB6BD, 0xB5BD}, //9125 #HANGUL SYLLABLE SSANGTIKEUT E KIYEOK + {0xB6BE, 0xB5C0}, //9126 #HANGUL SYLLABLE SSANGTIKEUT E NIEUN + {0xB6BF, 0xB5C4}, //9127 #HANGUL SYLLABLE SSANGTIKEUT E RIEUL + {0xB6C0, 0xB5CC}, //9128 #HANGUL SYLLABLE SSANGTIKEUT E MIEUM + {0xB6C1, 0xB5CD}, //9129 #HANGUL SYLLABLE SSANGTIKEUT E PIEUP + {0xB6C2, 0xB5CF}, //9130 #HANGUL SYLLABLE SSANGTIKEUT E SIOS + {0xB6C3, 0xB5D0}, //9131 #HANGUL SYLLABLE SSANGTIKEUT E SSANGSIOS + {0xB6C4, 0xB5D1}, //9132 #HANGUL SYLLABLE SSANGTIKEUT E IEUNG + {0xB6C5, 0xB5D8}, //9133 #HANGUL SYLLABLE SSANGTIKEUT YEO + {0xB6C6, 0xB5EC}, //9134 #HANGUL SYLLABLE SSANGTIKEUT YEO SSANGSIOS + {0xB6C7, 0xB610}, //9135 #HANGUL SYLLABLE SSANGTIKEUT O + {0xB6C8, 0xB611}, //9136 #HANGUL SYLLABLE SSANGTIKEUT O KIYEOK + {0xB6C9, 0xB614}, //9137 #HANGUL SYLLABLE SSANGTIKEUT O NIEUN + {0xB6CA, 0xB618}, //9138 #HANGUL SYLLABLE SSANGTIKEUT O RIEUL + {0xB6CB, 0xB625}, //9139 #HANGUL SYLLABLE SSANGTIKEUT O IEUNG + {0xB6CC, 0xB62C}, //9140 #HANGUL SYLLABLE SSANGTIKEUT WA + {0xB6CD, 0xB634}, //9141 #HANGUL SYLLABLE SSANGTIKEUT WA RIEUL + {0xB6CE, 0xB648}, //9142 #HANGUL SYLLABLE SSANGTIKEUT WAE + {0xB6CF, 0xB664}, //9143 #HANGUL SYLLABLE SSANGTIKEUT OE + {0xB6D0, 0xB668}, //9144 #HANGUL SYLLABLE SSANGTIKEUT OE NIEUN + {0xB6D1, 0xB69C}, //9145 #HANGUL SYLLABLE SSANGTIKEUT U + {0xB6D2, 0xB69D}, //9146 #HANGUL SYLLABLE SSANGTIKEUT U KIYEOK + {0xB6D3, 0xB6A0}, //9147 #HANGUL SYLLABLE SSANGTIKEUT U NIEUN + {0xB6D4, 0xB6A4}, //9148 #HANGUL SYLLABLE SSANGTIKEUT U RIEUL + {0xB6D5, 0xB6AB}, //9149 #HANGUL SYLLABLE SSANGTIKEUT U RIEULHIEUH + {0xB6D6, 0xB6AC}, //9150 #HANGUL SYLLABLE SSANGTIKEUT U MIEUM + {0xB6D7, 0xB6B1}, //9151 #HANGUL SYLLABLE SSANGTIKEUT U IEUNG + {0xB6D8, 0xB6D4}, //9152 #HANGUL SYLLABLE SSANGTIKEUT WE + {0xB6D9, 0xB6F0}, //9153 #HANGUL SYLLABLE SSANGTIKEUT WI + {0xB6DA, 0xB6F4}, //9154 #HANGUL SYLLABLE SSANGTIKEUT WI NIEUN + {0xB6DB, 0xB6F8}, //9155 #HANGUL SYLLABLE SSANGTIKEUT WI RIEUL + {0xB6DC, 0xB700}, //9156 #HANGUL SYLLABLE SSANGTIKEUT WI MIEUM + {0xB6DD, 0xB701}, //9157 #HANGUL SYLLABLE SSANGTIKEUT WI PIEUP + {0xB6DE, 0xB705}, //9158 #HANGUL SYLLABLE SSANGTIKEUT WI IEUNG + {0xB6DF, 0xB728}, //9159 #HANGUL SYLLABLE SSANGTIKEUT EU + {0xB6E0, 0xB729}, //9160 #HANGUL SYLLABLE SSANGTIKEUT EU KIYEOK + {0xB6E1, 0xB72C}, //9161 #HANGUL SYLLABLE SSANGTIKEUT EU NIEUN + {0xB6E2, 0xB72F}, //9162 #HANGUL SYLLABLE SSANGTIKEUT EU TIKEUT + {0xB6E3, 0xB730}, //9163 #HANGUL SYLLABLE SSANGTIKEUT EU RIEUL + {0xB6E4, 0xB738}, //9164 #HANGUL SYLLABLE SSANGTIKEUT EU MIEUM + {0xB6E5, 0xB739}, //9165 #HANGUL SYLLABLE SSANGTIKEUT EU PIEUP + {0xB6E6, 0xB73B}, //9166 #HANGUL SYLLABLE SSANGTIKEUT EU SIOS + {0xB6E7, 0xB744}, //9167 #HANGUL SYLLABLE SSANGTIKEUT YI + {0xB6E8, 0xB748}, //9168 #HANGUL SYLLABLE SSANGTIKEUT YI NIEUN + {0xB6E9, 0xB74C}, //9169 #HANGUL SYLLABLE SSANGTIKEUT YI RIEUL + {0xB6EA, 0xB754}, //9170 #HANGUL SYLLABLE SSANGTIKEUT YI MIEUM + {0xB6EB, 0xB755}, //9171 #HANGUL SYLLABLE SSANGTIKEUT YI PIEUP + {0xB6EC, 0xB760}, //9172 #HANGUL SYLLABLE SSANGTIKEUT I + {0xB6ED, 0xB764}, //9173 #HANGUL SYLLABLE SSANGTIKEUT I NIEUN + {0xB6EE, 0xB768}, //9174 #HANGUL SYLLABLE SSANGTIKEUT I RIEUL + {0xB6EF, 0xB770}, //9175 #HANGUL SYLLABLE SSANGTIKEUT I MIEUM + {0xB6F0, 0xB771}, //9176 #HANGUL SYLLABLE SSANGTIKEUT I PIEUP + {0xB6F1, 0xB773}, //9177 #HANGUL SYLLABLE SSANGTIKEUT I SIOS + {0xB6F2, 0xB775}, //9178 #HANGUL SYLLABLE SSANGTIKEUT I IEUNG + {0xB6F3, 0xB77C}, //9179 #HANGUL SYLLABLE RIEUL A + {0xB6F4, 0xB77D}, //9180 #HANGUL SYLLABLE RIEUL A KIYEOK + {0xB6F5, 0xB780}, //9181 #HANGUL SYLLABLE RIEUL A NIEUN + {0xB6F6, 0xB784}, //9182 #HANGUL SYLLABLE RIEUL A RIEUL + {0xB6F7, 0xB78C}, //9183 #HANGUL SYLLABLE RIEUL A MIEUM + {0xB6F8, 0xB78D}, //9184 #HANGUL SYLLABLE RIEUL A PIEUP + {0xB6F9, 0xB78F}, //9185 #HANGUL SYLLABLE RIEUL A SIOS + {0xB6FA, 0xB790}, //9186 #HANGUL SYLLABLE RIEUL A SSANGSIOS + {0xB6FB, 0xB791}, //9187 #HANGUL SYLLABLE RIEUL A IEUNG + {0xB6FC, 0xB792}, //9188 #HANGUL SYLLABLE RIEUL A CIEUC + {0xB6FD, 0xB796}, //9189 #HANGUL SYLLABLE RIEUL A PHIEUPH + {0xB6FE, 0xB797}, //9190 #HANGUL SYLLABLE RIEUL A HIEUH + {0xB741, 0xD16E}, //9191 #HANGUL SYLLABLE THIEUTH YEO NIEUNHIEUH + {0xB742, 0xD16F}, //9192 #HANGUL SYLLABLE THIEUTH YEO TIKEUT + {0xB743, 0xD170}, //9193 #HANGUL SYLLABLE THIEUTH YEO RIEUL + {0xB744, 0xD171}, //9194 #HANGUL SYLLABLE THIEUTH YEO RIEULKIYEOK + {0xB745, 0xD172}, //9195 #HANGUL SYLLABLE THIEUTH YEO RIEULMIEUM + {0xB746, 0xD173}, //9196 #HANGUL SYLLABLE THIEUTH YEO RIEULPIEUP + {0xB747, 0xD174}, //9197 #HANGUL SYLLABLE THIEUTH YEO RIEULSIOS + {0xB748, 0xD175}, //9198 #HANGUL SYLLABLE THIEUTH YEO RIEULTHIEUTH + {0xB749, 0xD176}, //9199 #HANGUL SYLLABLE THIEUTH YEO RIEULPHIEUPH + {0xB74A, 0xD177}, //9200 #HANGUL SYLLABLE THIEUTH YEO RIEULHIEUH + {0xB74B, 0xD178}, //9201 #HANGUL SYLLABLE THIEUTH YEO MIEUM + {0xB74C, 0xD179}, //9202 #HANGUL SYLLABLE THIEUTH YEO PIEUP + {0xB74D, 0xD17A}, //9203 #HANGUL SYLLABLE THIEUTH YEO PIEUPSIOS + {0xB74E, 0xD17B}, //9204 #HANGUL SYLLABLE THIEUTH YEO SIOS + {0xB74F, 0xD17D}, //9205 #HANGUL SYLLABLE THIEUTH YEO IEUNG + {0xB750, 0xD17E}, //9206 #HANGUL SYLLABLE THIEUTH YEO CIEUC + {0xB751, 0xD17F}, //9207 #HANGUL SYLLABLE THIEUTH YEO CHIEUCH + {0xB752, 0xD180}, //9208 #HANGUL SYLLABLE THIEUTH YEO KHIEUKH + {0xB753, 0xD181}, //9209 #HANGUL SYLLABLE THIEUTH YEO THIEUTH + {0xB754, 0xD182}, //9210 #HANGUL SYLLABLE THIEUTH YEO PHIEUPH + {0xB755, 0xD183}, //9211 #HANGUL SYLLABLE THIEUTH YEO HIEUH + {0xB756, 0xD185}, //9212 #HANGUL SYLLABLE THIEUTH YE KIYEOK + {0xB757, 0xD186}, //9213 #HANGUL SYLLABLE THIEUTH YE SSANGKIYEOK + {0xB758, 0xD187}, //9214 #HANGUL SYLLABLE THIEUTH YE KIYEOKSIOS + {0xB759, 0xD189}, //9215 #HANGUL SYLLABLE THIEUTH YE NIEUNCIEUC + {0xB75A, 0xD18A}, //9216 #HANGUL SYLLABLE THIEUTH YE NIEUNHIEUH + {0xB761, 0xD18B}, //9217 #HANGUL SYLLABLE THIEUTH YE TIKEUT + {0xB762, 0xD18C}, //9218 #HANGUL SYLLABLE THIEUTH YE RIEUL + {0xB763, 0xD18D}, //9219 #HANGUL SYLLABLE THIEUTH YE RIEULKIYEOK + {0xB764, 0xD18E}, //9220 #HANGUL SYLLABLE THIEUTH YE RIEULMIEUM + {0xB765, 0xD18F}, //9221 #HANGUL SYLLABLE THIEUTH YE RIEULPIEUP + {0xB766, 0xD190}, //9222 #HANGUL SYLLABLE THIEUTH YE RIEULSIOS + {0xB767, 0xD191}, //9223 #HANGUL SYLLABLE THIEUTH YE RIEULTHIEUTH + {0xB768, 0xD192}, //9224 #HANGUL SYLLABLE THIEUTH YE RIEULPHIEUPH + {0xB769, 0xD193}, //9225 #HANGUL SYLLABLE THIEUTH YE RIEULHIEUH + {0xB76A, 0xD194}, //9226 #HANGUL SYLLABLE THIEUTH YE MIEUM + {0xB76B, 0xD195}, //9227 #HANGUL SYLLABLE THIEUTH YE PIEUP + {0xB76C, 0xD196}, //9228 #HANGUL SYLLABLE THIEUTH YE PIEUPSIOS + {0xB76D, 0xD197}, //9229 #HANGUL SYLLABLE THIEUTH YE SIOS + {0xB76E, 0xD198}, //9230 #HANGUL SYLLABLE THIEUTH YE SSANGSIOS + {0xB76F, 0xD199}, //9231 #HANGUL SYLLABLE THIEUTH YE IEUNG + {0xB770, 0xD19A}, //9232 #HANGUL SYLLABLE THIEUTH YE CIEUC + {0xB771, 0xD19B}, //9233 #HANGUL SYLLABLE THIEUTH YE CHIEUCH + {0xB772, 0xD19C}, //9234 #HANGUL SYLLABLE THIEUTH YE KHIEUKH + {0xB773, 0xD19D}, //9235 #HANGUL SYLLABLE THIEUTH YE THIEUTH + {0xB774, 0xD19E}, //9236 #HANGUL SYLLABLE THIEUTH YE PHIEUPH + {0xB775, 0xD19F}, //9237 #HANGUL SYLLABLE THIEUTH YE HIEUH + {0xB776, 0xD1A2}, //9238 #HANGUL SYLLABLE THIEUTH O SSANGKIYEOK + {0xB777, 0xD1A3}, //9239 #HANGUL SYLLABLE THIEUTH O KIYEOKSIOS + {0xB778, 0xD1A5}, //9240 #HANGUL SYLLABLE THIEUTH O NIEUNCIEUC + {0xB779, 0xD1A6}, //9241 #HANGUL SYLLABLE THIEUTH O NIEUNHIEUH + {0xB77A, 0xD1A7}, //9242 #HANGUL SYLLABLE THIEUTH O TIKEUT + {0xB781, 0xD1A9}, //9243 #HANGUL SYLLABLE THIEUTH O RIEULKIYEOK + {0xB782, 0xD1AA}, //9244 #HANGUL SYLLABLE THIEUTH O RIEULMIEUM + {0xB783, 0xD1AB}, //9245 #HANGUL SYLLABLE THIEUTH O RIEULPIEUP + {0xB784, 0xD1AC}, //9246 #HANGUL SYLLABLE THIEUTH O RIEULSIOS + {0xB785, 0xD1AD}, //9247 #HANGUL SYLLABLE THIEUTH O RIEULTHIEUTH + {0xB786, 0xD1AE}, //9248 #HANGUL SYLLABLE THIEUTH O RIEULPHIEUPH + {0xB787, 0xD1AF}, //9249 #HANGUL SYLLABLE THIEUTH O RIEULHIEUH + {0xB788, 0xD1B2}, //9250 #HANGUL SYLLABLE THIEUTH O PIEUPSIOS + {0xB789, 0xD1B4}, //9251 #HANGUL SYLLABLE THIEUTH O SSANGSIOS + {0xB78A, 0xD1B6}, //9252 #HANGUL SYLLABLE THIEUTH O CIEUC + {0xB78B, 0xD1B7}, //9253 #HANGUL SYLLABLE THIEUTH O CHIEUCH + {0xB78C, 0xD1B8}, //9254 #HANGUL SYLLABLE THIEUTH O KHIEUKH + {0xB78D, 0xD1B9}, //9255 #HANGUL SYLLABLE THIEUTH O THIEUTH + {0xB78E, 0xD1BB}, //9256 #HANGUL SYLLABLE THIEUTH O HIEUH + {0xB78F, 0xD1BD}, //9257 #HANGUL SYLLABLE THIEUTH WA KIYEOK + {0xB790, 0xD1BE}, //9258 #HANGUL SYLLABLE THIEUTH WA SSANGKIYEOK + {0xB791, 0xD1BF}, //9259 #HANGUL SYLLABLE THIEUTH WA KIYEOKSIOS + {0xB792, 0xD1C1}, //9260 #HANGUL SYLLABLE THIEUTH WA NIEUNCIEUC + {0xB793, 0xD1C2}, //9261 #HANGUL SYLLABLE THIEUTH WA NIEUNHIEUH + {0xB794, 0xD1C3}, //9262 #HANGUL SYLLABLE THIEUTH WA TIKEUT + {0xB795, 0xD1C4}, //9263 #HANGUL SYLLABLE THIEUTH WA RIEUL + {0xB796, 0xD1C5}, //9264 #HANGUL SYLLABLE THIEUTH WA RIEULKIYEOK + {0xB797, 0xD1C6}, //9265 #HANGUL SYLLABLE THIEUTH WA RIEULMIEUM + {0xB798, 0xD1C7}, //9266 #HANGUL SYLLABLE THIEUTH WA RIEULPIEUP + {0xB799, 0xD1C8}, //9267 #HANGUL SYLLABLE THIEUTH WA RIEULSIOS + {0xB79A, 0xD1C9}, //9268 #HANGUL SYLLABLE THIEUTH WA RIEULTHIEUTH + {0xB79B, 0xD1CA}, //9269 #HANGUL SYLLABLE THIEUTH WA RIEULPHIEUPH + {0xB79C, 0xD1CB}, //9270 #HANGUL SYLLABLE THIEUTH WA RIEULHIEUH + {0xB79D, 0xD1CC}, //9271 #HANGUL SYLLABLE THIEUTH WA MIEUM + {0xB79E, 0xD1CD}, //9272 #HANGUL SYLLABLE THIEUTH WA PIEUP + {0xB79F, 0xD1CE}, //9273 #HANGUL SYLLABLE THIEUTH WA PIEUPSIOS + {0xB7A0, 0xD1CF}, //9274 #HANGUL SYLLABLE THIEUTH WA SIOS + {0xB7A1, 0xB798}, //9275 #HANGUL SYLLABLE RIEUL AE + {0xB7A2, 0xB799}, //9276 #HANGUL SYLLABLE RIEUL AE KIYEOK + {0xB7A3, 0xB79C}, //9277 #HANGUL SYLLABLE RIEUL AE NIEUN + {0xB7A4, 0xB7A0}, //9278 #HANGUL SYLLABLE RIEUL AE RIEUL + {0xB7A5, 0xB7A8}, //9279 #HANGUL SYLLABLE RIEUL AE MIEUM + {0xB7A6, 0xB7A9}, //9280 #HANGUL SYLLABLE RIEUL AE PIEUP + {0xB7A7, 0xB7AB}, //9281 #HANGUL SYLLABLE RIEUL AE SIOS + {0xB7A8, 0xB7AC}, //9282 #HANGUL SYLLABLE RIEUL AE SSANGSIOS + {0xB7A9, 0xB7AD}, //9283 #HANGUL SYLLABLE RIEUL AE IEUNG + {0xB7AA, 0xB7B4}, //9284 #HANGUL SYLLABLE RIEUL YA + {0xB7AB, 0xB7B5}, //9285 #HANGUL SYLLABLE RIEUL YA KIYEOK + {0xB7AC, 0xB7B8}, //9286 #HANGUL SYLLABLE RIEUL YA NIEUN + {0xB7AD, 0xB7C7}, //9287 #HANGUL SYLLABLE RIEUL YA SIOS + {0xB7AE, 0xB7C9}, //9288 #HANGUL SYLLABLE RIEUL YA IEUNG + {0xB7AF, 0xB7EC}, //9289 #HANGUL SYLLABLE RIEUL EO + {0xB7B0, 0xB7ED}, //9290 #HANGUL SYLLABLE RIEUL EO KIYEOK + {0xB7B1, 0xB7F0}, //9291 #HANGUL SYLLABLE RIEUL EO NIEUN + {0xB7B2, 0xB7F4}, //9292 #HANGUL SYLLABLE RIEUL EO RIEUL + {0xB7B3, 0xB7FC}, //9293 #HANGUL SYLLABLE RIEUL EO MIEUM + {0xB7B4, 0xB7FD}, //9294 #HANGUL SYLLABLE RIEUL EO PIEUP + {0xB7B5, 0xB7FF}, //9295 #HANGUL SYLLABLE RIEUL EO SIOS + {0xB7B6, 0xB800}, //9296 #HANGUL SYLLABLE RIEUL EO SSANGSIOS + {0xB7B7, 0xB801}, //9297 #HANGUL SYLLABLE RIEUL EO IEUNG + {0xB7B8, 0xB807}, //9298 #HANGUL SYLLABLE RIEUL EO HIEUH + {0xB7B9, 0xB808}, //9299 #HANGUL SYLLABLE RIEUL E + {0xB7BA, 0xB809}, //9300 #HANGUL SYLLABLE RIEUL E KIYEOK + {0xB7BB, 0xB80C}, //9301 #HANGUL SYLLABLE RIEUL E NIEUN + {0xB7BC, 0xB810}, //9302 #HANGUL SYLLABLE RIEUL E RIEUL + {0xB7BD, 0xB818}, //9303 #HANGUL SYLLABLE RIEUL E MIEUM + {0xB7BE, 0xB819}, //9304 #HANGUL SYLLABLE RIEUL E PIEUP + {0xB7BF, 0xB81B}, //9305 #HANGUL SYLLABLE RIEUL E SIOS + {0xB7C0, 0xB81D}, //9306 #HANGUL SYLLABLE RIEUL E IEUNG + {0xB7C1, 0xB824}, //9307 #HANGUL SYLLABLE RIEUL YEO + {0xB7C2, 0xB825}, //9308 #HANGUL SYLLABLE RIEUL YEO KIYEOK + {0xB7C3, 0xB828}, //9309 #HANGUL SYLLABLE RIEUL YEO NIEUN + {0xB7C4, 0xB82C}, //9310 #HANGUL SYLLABLE RIEUL YEO RIEUL + {0xB7C5, 0xB834}, //9311 #HANGUL SYLLABLE RIEUL YEO MIEUM + {0xB7C6, 0xB835}, //9312 #HANGUL SYLLABLE RIEUL YEO PIEUP + {0xB7C7, 0xB837}, //9313 #HANGUL SYLLABLE RIEUL YEO SIOS + {0xB7C8, 0xB838}, //9314 #HANGUL SYLLABLE RIEUL YEO SSANGSIOS + {0xB7C9, 0xB839}, //9315 #HANGUL SYLLABLE RIEUL YEO IEUNG + {0xB7CA, 0xB840}, //9316 #HANGUL SYLLABLE RIEUL YE + {0xB7CB, 0xB844}, //9317 #HANGUL SYLLABLE RIEUL YE NIEUN + {0xB7CC, 0xB851}, //9318 #HANGUL SYLLABLE RIEUL YE PIEUP + {0xB7CD, 0xB853}, //9319 #HANGUL SYLLABLE RIEUL YE SIOS + {0xB7CE, 0xB85C}, //9320 #HANGUL SYLLABLE RIEUL O + {0xB7CF, 0xB85D}, //9321 #HANGUL SYLLABLE RIEUL O KIYEOK + {0xB7D0, 0xB860}, //9322 #HANGUL SYLLABLE RIEUL O NIEUN + {0xB7D1, 0xB864}, //9323 #HANGUL SYLLABLE RIEUL O RIEUL + {0xB7D2, 0xB86C}, //9324 #HANGUL SYLLABLE RIEUL O MIEUM + {0xB7D3, 0xB86D}, //9325 #HANGUL SYLLABLE RIEUL O PIEUP + {0xB7D4, 0xB86F}, //9326 #HANGUL SYLLABLE RIEUL O SIOS + {0xB7D5, 0xB871}, //9327 #HANGUL SYLLABLE RIEUL O IEUNG + {0xB7D6, 0xB878}, //9328 #HANGUL SYLLABLE RIEUL WA + {0xB7D7, 0xB87C}, //9329 #HANGUL SYLLABLE RIEUL WA NIEUN + {0xB7D8, 0xB88D}, //9330 #HANGUL SYLLABLE RIEUL WA IEUNG + {0xB7D9, 0xB8A8}, //9331 #HANGUL SYLLABLE RIEUL WAE SSANGSIOS + {0xB7DA, 0xB8B0}, //9332 #HANGUL SYLLABLE RIEUL OE + {0xB7DB, 0xB8B4}, //9333 #HANGUL SYLLABLE RIEUL OE NIEUN + {0xB7DC, 0xB8B8}, //9334 #HANGUL SYLLABLE RIEUL OE RIEUL + {0xB7DD, 0xB8C0}, //9335 #HANGUL SYLLABLE RIEUL OE MIEUM + {0xB7DE, 0xB8C1}, //9336 #HANGUL SYLLABLE RIEUL OE PIEUP + {0xB7DF, 0xB8C3}, //9337 #HANGUL SYLLABLE RIEUL OE SIOS + {0xB7E0, 0xB8C5}, //9338 #HANGUL SYLLABLE RIEUL OE IEUNG + {0xB7E1, 0xB8CC}, //9339 #HANGUL SYLLABLE RIEUL YO + {0xB7E2, 0xB8D0}, //9340 #HANGUL SYLLABLE RIEUL YO NIEUN + {0xB7E3, 0xB8D4}, //9341 #HANGUL SYLLABLE RIEUL YO RIEUL + {0xB7E4, 0xB8DD}, //9342 #HANGUL SYLLABLE RIEUL YO PIEUP + {0xB7E5, 0xB8DF}, //9343 #HANGUL SYLLABLE RIEUL YO SIOS + {0xB7E6, 0xB8E1}, //9344 #HANGUL SYLLABLE RIEUL YO IEUNG + {0xB7E7, 0xB8E8}, //9345 #HANGUL SYLLABLE RIEUL U + {0xB7E8, 0xB8E9}, //9346 #HANGUL SYLLABLE RIEUL U KIYEOK + {0xB7E9, 0xB8EC}, //9347 #HANGUL SYLLABLE RIEUL U NIEUN + {0xB7EA, 0xB8F0}, //9348 #HANGUL SYLLABLE RIEUL U RIEUL + {0xB7EB, 0xB8F8}, //9349 #HANGUL SYLLABLE RIEUL U MIEUM + {0xB7EC, 0xB8F9}, //9350 #HANGUL SYLLABLE RIEUL U PIEUP + {0xB7ED, 0xB8FB}, //9351 #HANGUL SYLLABLE RIEUL U SIOS + {0xB7EE, 0xB8FD}, //9352 #HANGUL SYLLABLE RIEUL U IEUNG + {0xB7EF, 0xB904}, //9353 #HANGUL SYLLABLE RIEUL WEO + {0xB7F0, 0xB918}, //9354 #HANGUL SYLLABLE RIEUL WEO SSANGSIOS + {0xB7F1, 0xB920}, //9355 #HANGUL SYLLABLE RIEUL WE + {0xB7F2, 0xB93C}, //9356 #HANGUL SYLLABLE RIEUL WI + {0xB7F3, 0xB93D}, //9357 #HANGUL SYLLABLE RIEUL WI KIYEOK + {0xB7F4, 0xB940}, //9358 #HANGUL SYLLABLE RIEUL WI NIEUN + {0xB7F5, 0xB944}, //9359 #HANGUL SYLLABLE RIEUL WI RIEUL + {0xB7F6, 0xB94C}, //9360 #HANGUL SYLLABLE RIEUL WI MIEUM + {0xB7F7, 0xB94F}, //9361 #HANGUL SYLLABLE RIEUL WI SIOS + {0xB7F8, 0xB951}, //9362 #HANGUL SYLLABLE RIEUL WI IEUNG + {0xB7F9, 0xB958}, //9363 #HANGUL SYLLABLE RIEUL YU + {0xB7FA, 0xB959}, //9364 #HANGUL SYLLABLE RIEUL YU KIYEOK + {0xB7FB, 0xB95C}, //9365 #HANGUL SYLLABLE RIEUL YU NIEUN + {0xB7FC, 0xB960}, //9366 #HANGUL SYLLABLE RIEUL YU RIEUL + {0xB7FD, 0xB968}, //9367 #HANGUL SYLLABLE RIEUL YU MIEUM + {0xB7FE, 0xB969}, //9368 #HANGUL SYLLABLE RIEUL YU PIEUP + {0xB841, 0xD1D0}, //9369 #HANGUL SYLLABLE THIEUTH WA SSANGSIOS + {0xB842, 0xD1D1}, //9370 #HANGUL SYLLABLE THIEUTH WA IEUNG + {0xB843, 0xD1D2}, //9371 #HANGUL SYLLABLE THIEUTH WA CIEUC + {0xB844, 0xD1D3}, //9372 #HANGUL SYLLABLE THIEUTH WA CHIEUCH + {0xB845, 0xD1D4}, //9373 #HANGUL SYLLABLE THIEUTH WA KHIEUKH + {0xB846, 0xD1D5}, //9374 #HANGUL SYLLABLE THIEUTH WA THIEUTH + {0xB847, 0xD1D6}, //9375 #HANGUL SYLLABLE THIEUTH WA PHIEUPH + {0xB848, 0xD1D7}, //9376 #HANGUL SYLLABLE THIEUTH WA HIEUH + {0xB849, 0xD1D9}, //9377 #HANGUL SYLLABLE THIEUTH WAE KIYEOK + {0xB84A, 0xD1DA}, //9378 #HANGUL SYLLABLE THIEUTH WAE SSANGKIYEOK + {0xB84B, 0xD1DB}, //9379 #HANGUL SYLLABLE THIEUTH WAE KIYEOKSIOS + {0xB84C, 0xD1DC}, //9380 #HANGUL SYLLABLE THIEUTH WAE NIEUN + {0xB84D, 0xD1DD}, //9381 #HANGUL SYLLABLE THIEUTH WAE NIEUNCIEUC + {0xB84E, 0xD1DE}, //9382 #HANGUL SYLLABLE THIEUTH WAE NIEUNHIEUH + {0xB84F, 0xD1DF}, //9383 #HANGUL SYLLABLE THIEUTH WAE TIKEUT + {0xB850, 0xD1E0}, //9384 #HANGUL SYLLABLE THIEUTH WAE RIEUL + {0xB851, 0xD1E1}, //9385 #HANGUL SYLLABLE THIEUTH WAE RIEULKIYEOK + {0xB852, 0xD1E2}, //9386 #HANGUL SYLLABLE THIEUTH WAE RIEULMIEUM + {0xB853, 0xD1E3}, //9387 #HANGUL SYLLABLE THIEUTH WAE RIEULPIEUP + {0xB854, 0xD1E4}, //9388 #HANGUL SYLLABLE THIEUTH WAE RIEULSIOS + {0xB855, 0xD1E5}, //9389 #HANGUL SYLLABLE THIEUTH WAE RIEULTHIEUTH + {0xB856, 0xD1E6}, //9390 #HANGUL SYLLABLE THIEUTH WAE RIEULPHIEUPH + {0xB857, 0xD1E7}, //9391 #HANGUL SYLLABLE THIEUTH WAE RIEULHIEUH + {0xB858, 0xD1E8}, //9392 #HANGUL SYLLABLE THIEUTH WAE MIEUM + {0xB859, 0xD1E9}, //9393 #HANGUL SYLLABLE THIEUTH WAE PIEUP + {0xB85A, 0xD1EA}, //9394 #HANGUL SYLLABLE THIEUTH WAE PIEUPSIOS + {0xB861, 0xD1EB}, //9395 #HANGUL SYLLABLE THIEUTH WAE SIOS + {0xB862, 0xD1EC}, //9396 #HANGUL SYLLABLE THIEUTH WAE SSANGSIOS + {0xB863, 0xD1ED}, //9397 #HANGUL SYLLABLE THIEUTH WAE IEUNG + {0xB864, 0xD1EE}, //9398 #HANGUL SYLLABLE THIEUTH WAE CIEUC + {0xB865, 0xD1EF}, //9399 #HANGUL SYLLABLE THIEUTH WAE CHIEUCH + {0xB866, 0xD1F0}, //9400 #HANGUL SYLLABLE THIEUTH WAE KHIEUKH + {0xB867, 0xD1F1}, //9401 #HANGUL SYLLABLE THIEUTH WAE THIEUTH + {0xB868, 0xD1F2}, //9402 #HANGUL SYLLABLE THIEUTH WAE PHIEUPH + {0xB869, 0xD1F3}, //9403 #HANGUL SYLLABLE THIEUTH WAE HIEUH + {0xB86A, 0xD1F5}, //9404 #HANGUL SYLLABLE THIEUTH OE KIYEOK + {0xB86B, 0xD1F6}, //9405 #HANGUL SYLLABLE THIEUTH OE SSANGKIYEOK + {0xB86C, 0xD1F7}, //9406 #HANGUL SYLLABLE THIEUTH OE KIYEOKSIOS + {0xB86D, 0xD1F9}, //9407 #HANGUL SYLLABLE THIEUTH OE NIEUNCIEUC + {0xB86E, 0xD1FA}, //9408 #HANGUL SYLLABLE THIEUTH OE NIEUNHIEUH + {0xB86F, 0xD1FB}, //9409 #HANGUL SYLLABLE THIEUTH OE TIKEUT + {0xB870, 0xD1FC}, //9410 #HANGUL SYLLABLE THIEUTH OE RIEUL + {0xB871, 0xD1FD}, //9411 #HANGUL SYLLABLE THIEUTH OE RIEULKIYEOK + {0xB872, 0xD1FE}, //9412 #HANGUL SYLLABLE THIEUTH OE RIEULMIEUM + {0xB873, 0xD1FF}, //9413 #HANGUL SYLLABLE THIEUTH OE RIEULPIEUP + {0xB874, 0xD200}, //9414 #HANGUL SYLLABLE THIEUTH OE RIEULSIOS + {0xB875, 0xD201}, //9415 #HANGUL SYLLABLE THIEUTH OE RIEULTHIEUTH + {0xB876, 0xD202}, //9416 #HANGUL SYLLABLE THIEUTH OE RIEULPHIEUPH + {0xB877, 0xD203}, //9417 #HANGUL SYLLABLE THIEUTH OE RIEULHIEUH + {0xB878, 0xD204}, //9418 #HANGUL SYLLABLE THIEUTH OE MIEUM + {0xB879, 0xD205}, //9419 #HANGUL SYLLABLE THIEUTH OE PIEUP + {0xB87A, 0xD206}, //9420 #HANGUL SYLLABLE THIEUTH OE PIEUPSIOS + {0xB881, 0xD208}, //9421 #HANGUL SYLLABLE THIEUTH OE SSANGSIOS + {0xB882, 0xD20A}, //9422 #HANGUL SYLLABLE THIEUTH OE CIEUC + {0xB883, 0xD20B}, //9423 #HANGUL SYLLABLE THIEUTH OE CHIEUCH + {0xB884, 0xD20C}, //9424 #HANGUL SYLLABLE THIEUTH OE KHIEUKH + {0xB885, 0xD20D}, //9425 #HANGUL SYLLABLE THIEUTH OE THIEUTH + {0xB886, 0xD20E}, //9426 #HANGUL SYLLABLE THIEUTH OE PHIEUPH + {0xB887, 0xD20F}, //9427 #HANGUL SYLLABLE THIEUTH OE HIEUH + {0xB888, 0xD211}, //9428 #HANGUL SYLLABLE THIEUTH YO KIYEOK + {0xB889, 0xD212}, //9429 #HANGUL SYLLABLE THIEUTH YO SSANGKIYEOK + {0xB88A, 0xD213}, //9430 #HANGUL SYLLABLE THIEUTH YO KIYEOKSIOS + {0xB88B, 0xD214}, //9431 #HANGUL SYLLABLE THIEUTH YO NIEUN + {0xB88C, 0xD215}, //9432 #HANGUL SYLLABLE THIEUTH YO NIEUNCIEUC + {0xB88D, 0xD216}, //9433 #HANGUL SYLLABLE THIEUTH YO NIEUNHIEUH + {0xB88E, 0xD217}, //9434 #HANGUL SYLLABLE THIEUTH YO TIKEUT + {0xB88F, 0xD218}, //9435 #HANGUL SYLLABLE THIEUTH YO RIEUL + {0xB890, 0xD219}, //9436 #HANGUL SYLLABLE THIEUTH YO RIEULKIYEOK + {0xB891, 0xD21A}, //9437 #HANGUL SYLLABLE THIEUTH YO RIEULMIEUM + {0xB892, 0xD21B}, //9438 #HANGUL SYLLABLE THIEUTH YO RIEULPIEUP + {0xB893, 0xD21C}, //9439 #HANGUL SYLLABLE THIEUTH YO RIEULSIOS + {0xB894, 0xD21D}, //9440 #HANGUL SYLLABLE THIEUTH YO RIEULTHIEUTH + {0xB895, 0xD21E}, //9441 #HANGUL SYLLABLE THIEUTH YO RIEULPHIEUPH + {0xB896, 0xD21F}, //9442 #HANGUL SYLLABLE THIEUTH YO RIEULHIEUH + {0xB897, 0xD220}, //9443 #HANGUL SYLLABLE THIEUTH YO MIEUM + {0xB898, 0xD221}, //9444 #HANGUL SYLLABLE THIEUTH YO PIEUP + {0xB899, 0xD222}, //9445 #HANGUL SYLLABLE THIEUTH YO PIEUPSIOS + {0xB89A, 0xD223}, //9446 #HANGUL SYLLABLE THIEUTH YO SIOS + {0xB89B, 0xD224}, //9447 #HANGUL SYLLABLE THIEUTH YO SSANGSIOS + {0xB89C, 0xD225}, //9448 #HANGUL SYLLABLE THIEUTH YO IEUNG + {0xB89D, 0xD226}, //9449 #HANGUL SYLLABLE THIEUTH YO CIEUC + {0xB89E, 0xD227}, //9450 #HANGUL SYLLABLE THIEUTH YO CHIEUCH + {0xB89F, 0xD228}, //9451 #HANGUL SYLLABLE THIEUTH YO KHIEUKH + {0xB8A0, 0xD229}, //9452 #HANGUL SYLLABLE THIEUTH YO THIEUTH + {0xB8A1, 0xB96B}, //9453 #HANGUL SYLLABLE RIEUL YU SIOS + {0xB8A2, 0xB96D}, //9454 #HANGUL SYLLABLE RIEUL YU IEUNG + {0xB8A3, 0xB974}, //9455 #HANGUL SYLLABLE RIEUL EU + {0xB8A4, 0xB975}, //9456 #HANGUL SYLLABLE RIEUL EU KIYEOK + {0xB8A5, 0xB978}, //9457 #HANGUL SYLLABLE RIEUL EU NIEUN + {0xB8A6, 0xB97C}, //9458 #HANGUL SYLLABLE RIEUL EU RIEUL + {0xB8A7, 0xB984}, //9459 #HANGUL SYLLABLE RIEUL EU MIEUM + {0xB8A8, 0xB985}, //9460 #HANGUL SYLLABLE RIEUL EU PIEUP + {0xB8A9, 0xB987}, //9461 #HANGUL SYLLABLE RIEUL EU SIOS + {0xB8AA, 0xB989}, //9462 #HANGUL SYLLABLE RIEUL EU IEUNG + {0xB8AB, 0xB98A}, //9463 #HANGUL SYLLABLE RIEUL EU CIEUC + {0xB8AC, 0xB98D}, //9464 #HANGUL SYLLABLE RIEUL EU THIEUTH + {0xB8AD, 0xB98E}, //9465 #HANGUL SYLLABLE RIEUL EU PHIEUPH + {0xB8AE, 0xB9AC}, //9466 #HANGUL SYLLABLE RIEUL I + {0xB8AF, 0xB9AD}, //9467 #HANGUL SYLLABLE RIEUL I KIYEOK + {0xB8B0, 0xB9B0}, //9468 #HANGUL SYLLABLE RIEUL I NIEUN + {0xB8B1, 0xB9B4}, //9469 #HANGUL SYLLABLE RIEUL I RIEUL + {0xB8B2, 0xB9BC}, //9470 #HANGUL SYLLABLE RIEUL I MIEUM + {0xB8B3, 0xB9BD}, //9471 #HANGUL SYLLABLE RIEUL I PIEUP + {0xB8B4, 0xB9BF}, //9472 #HANGUL SYLLABLE RIEUL I SIOS + {0xB8B5, 0xB9C1}, //9473 #HANGUL SYLLABLE RIEUL I IEUNG + {0xB8B6, 0xB9C8}, //9474 #HANGUL SYLLABLE MIEUM A + {0xB8B7, 0xB9C9}, //9475 #HANGUL SYLLABLE MIEUM A KIYEOK + {0xB8B8, 0xB9CC}, //9476 #HANGUL SYLLABLE MIEUM A NIEUN + {0xB8B9, 0xB9CE}, //9477 #HANGUL SYLLABLE MIEUM A NIEUNHIEUH + {0xB8BA, 0xB9CF}, //9478 #HANGUL SYLLABLE MIEUM A TIKEUT + {0xB8BB, 0xB9D0}, //9479 #HANGUL SYLLABLE MIEUM A RIEUL + {0xB8BC, 0xB9D1}, //9480 #HANGUL SYLLABLE MIEUM A RIEULKIYEOK + {0xB8BD, 0xB9D2}, //9481 #HANGUL SYLLABLE MIEUM A RIEULMIEUM + {0xB8BE, 0xB9D8}, //9482 #HANGUL SYLLABLE MIEUM A MIEUM + {0xB8BF, 0xB9D9}, //9483 #HANGUL SYLLABLE MIEUM A PIEUP + {0xB8C0, 0xB9DB}, //9484 #HANGUL SYLLABLE MIEUM A SIOS + {0xB8C1, 0xB9DD}, //9485 #HANGUL SYLLABLE MIEUM A IEUNG + {0xB8C2, 0xB9DE}, //9486 #HANGUL SYLLABLE MIEUM A CIEUC + {0xB8C3, 0xB9E1}, //9487 #HANGUL SYLLABLE MIEUM A THIEUTH + {0xB8C4, 0xB9E3}, //9488 #HANGUL SYLLABLE MIEUM A HIEUH + {0xB8C5, 0xB9E4}, //9489 #HANGUL SYLLABLE MIEUM AE + {0xB8C6, 0xB9E5}, //9490 #HANGUL SYLLABLE MIEUM AE KIYEOK + {0xB8C7, 0xB9E8}, //9491 #HANGUL SYLLABLE MIEUM AE NIEUN + {0xB8C8, 0xB9EC}, //9492 #HANGUL SYLLABLE MIEUM AE RIEUL + {0xB8C9, 0xB9F4}, //9493 #HANGUL SYLLABLE MIEUM AE MIEUM + {0xB8CA, 0xB9F5}, //9494 #HANGUL SYLLABLE MIEUM AE PIEUP + {0xB8CB, 0xB9F7}, //9495 #HANGUL SYLLABLE MIEUM AE SIOS + {0xB8CC, 0xB9F8}, //9496 #HANGUL SYLLABLE MIEUM AE SSANGSIOS + {0xB8CD, 0xB9F9}, //9497 #HANGUL SYLLABLE MIEUM AE IEUNG + {0xB8CE, 0xB9FA}, //9498 #HANGUL SYLLABLE MIEUM AE CIEUC + {0xB8CF, 0xBA00}, //9499 #HANGUL SYLLABLE MIEUM YA + {0xB8D0, 0xBA01}, //9500 #HANGUL SYLLABLE MIEUM YA KIYEOK + {0xB8D1, 0xBA08}, //9501 #HANGUL SYLLABLE MIEUM YA RIEUL + {0xB8D2, 0xBA15}, //9502 #HANGUL SYLLABLE MIEUM YA IEUNG + {0xB8D3, 0xBA38}, //9503 #HANGUL SYLLABLE MIEUM EO + {0xB8D4, 0xBA39}, //9504 #HANGUL SYLLABLE MIEUM EO KIYEOK + {0xB8D5, 0xBA3C}, //9505 #HANGUL SYLLABLE MIEUM EO NIEUN + {0xB8D6, 0xBA40}, //9506 #HANGUL SYLLABLE MIEUM EO RIEUL + {0xB8D7, 0xBA42}, //9507 #HANGUL SYLLABLE MIEUM EO RIEULMIEUM + {0xB8D8, 0xBA48}, //9508 #HANGUL SYLLABLE MIEUM EO MIEUM + {0xB8D9, 0xBA49}, //9509 #HANGUL SYLLABLE MIEUM EO PIEUP + {0xB8DA, 0xBA4B}, //9510 #HANGUL SYLLABLE MIEUM EO SIOS + {0xB8DB, 0xBA4D}, //9511 #HANGUL SYLLABLE MIEUM EO IEUNG + {0xB8DC, 0xBA4E}, //9512 #HANGUL SYLLABLE MIEUM EO CIEUC + {0xB8DD, 0xBA53}, //9513 #HANGUL SYLLABLE MIEUM EO HIEUH + {0xB8DE, 0xBA54}, //9514 #HANGUL SYLLABLE MIEUM E + {0xB8DF, 0xBA55}, //9515 #HANGUL SYLLABLE MIEUM E KIYEOK + {0xB8E0, 0xBA58}, //9516 #HANGUL SYLLABLE MIEUM E NIEUN + {0xB8E1, 0xBA5C}, //9517 #HANGUL SYLLABLE MIEUM E RIEUL + {0xB8E2, 0xBA64}, //9518 #HANGUL SYLLABLE MIEUM E MIEUM + {0xB8E3, 0xBA65}, //9519 #HANGUL SYLLABLE MIEUM E PIEUP + {0xB8E4, 0xBA67}, //9520 #HANGUL SYLLABLE MIEUM E SIOS + {0xB8E5, 0xBA68}, //9521 #HANGUL SYLLABLE MIEUM E SSANGSIOS + {0xB8E6, 0xBA69}, //9522 #HANGUL SYLLABLE MIEUM E IEUNG + {0xB8E7, 0xBA70}, //9523 #HANGUL SYLLABLE MIEUM YEO + {0xB8E8, 0xBA71}, //9524 #HANGUL SYLLABLE MIEUM YEO KIYEOK + {0xB8E9, 0xBA74}, //9525 #HANGUL SYLLABLE MIEUM YEO NIEUN + {0xB8EA, 0xBA78}, //9526 #HANGUL SYLLABLE MIEUM YEO RIEUL + {0xB8EB, 0xBA83}, //9527 #HANGUL SYLLABLE MIEUM YEO SIOS + {0xB8EC, 0xBA84}, //9528 #HANGUL SYLLABLE MIEUM YEO SSANGSIOS + {0xB8ED, 0xBA85}, //9529 #HANGUL SYLLABLE MIEUM YEO IEUNG + {0xB8EE, 0xBA87}, //9530 #HANGUL SYLLABLE MIEUM YEO CHIEUCH + {0xB8EF, 0xBA8C}, //9531 #HANGUL SYLLABLE MIEUM YE + {0xB8F0, 0xBAA8}, //9532 #HANGUL SYLLABLE MIEUM O + {0xB8F1, 0xBAA9}, //9533 #HANGUL SYLLABLE MIEUM O KIYEOK + {0xB8F2, 0xBAAB}, //9534 #HANGUL SYLLABLE MIEUM O KIYEOKSIOS + {0xB8F3, 0xBAAC}, //9535 #HANGUL SYLLABLE MIEUM O NIEUN + {0xB8F4, 0xBAB0}, //9536 #HANGUL SYLLABLE MIEUM O RIEUL + {0xB8F5, 0xBAB2}, //9537 #HANGUL SYLLABLE MIEUM O RIEULMIEUM + {0xB8F6, 0xBAB8}, //9538 #HANGUL SYLLABLE MIEUM O MIEUM + {0xB8F7, 0xBAB9}, //9539 #HANGUL SYLLABLE MIEUM O PIEUP + {0xB8F8, 0xBABB}, //9540 #HANGUL SYLLABLE MIEUM O SIOS + {0xB8F9, 0xBABD}, //9541 #HANGUL SYLLABLE MIEUM O IEUNG + {0xB8FA, 0xBAC4}, //9542 #HANGUL SYLLABLE MIEUM WA + {0xB8FB, 0xBAC8}, //9543 #HANGUL SYLLABLE MIEUM WA NIEUN + {0xB8FC, 0xBAD8}, //9544 #HANGUL SYLLABLE MIEUM WA SSANGSIOS + {0xB8FD, 0xBAD9}, //9545 #HANGUL SYLLABLE MIEUM WA IEUNG + {0xB8FE, 0xBAFC}, //9546 #HANGUL SYLLABLE MIEUM OE + {0xB941, 0xD22A}, //9547 #HANGUL SYLLABLE THIEUTH YO PHIEUPH + {0xB942, 0xD22B}, //9548 #HANGUL SYLLABLE THIEUTH YO HIEUH + {0xB943, 0xD22E}, //9549 #HANGUL SYLLABLE THIEUTH U SSANGKIYEOK + {0xB944, 0xD22F}, //9550 #HANGUL SYLLABLE THIEUTH U KIYEOKSIOS + {0xB945, 0xD231}, //9551 #HANGUL SYLLABLE THIEUTH U NIEUNCIEUC + {0xB946, 0xD232}, //9552 #HANGUL SYLLABLE THIEUTH U NIEUNHIEUH + {0xB947, 0xD233}, //9553 #HANGUL SYLLABLE THIEUTH U TIKEUT + {0xB948, 0xD235}, //9554 #HANGUL SYLLABLE THIEUTH U RIEULKIYEOK + {0xB949, 0xD236}, //9555 #HANGUL SYLLABLE THIEUTH U RIEULMIEUM + {0xB94A, 0xD237}, //9556 #HANGUL SYLLABLE THIEUTH U RIEULPIEUP + {0xB94B, 0xD238}, //9557 #HANGUL SYLLABLE THIEUTH U RIEULSIOS + {0xB94C, 0xD239}, //9558 #HANGUL SYLLABLE THIEUTH U RIEULTHIEUTH + {0xB94D, 0xD23A}, //9559 #HANGUL SYLLABLE THIEUTH U RIEULPHIEUPH + {0xB94E, 0xD23B}, //9560 #HANGUL SYLLABLE THIEUTH U RIEULHIEUH + {0xB94F, 0xD23E}, //9561 #HANGUL SYLLABLE THIEUTH U PIEUPSIOS + {0xB950, 0xD240}, //9562 #HANGUL SYLLABLE THIEUTH U SSANGSIOS + {0xB951, 0xD242}, //9563 #HANGUL SYLLABLE THIEUTH U CIEUC + {0xB952, 0xD243}, //9564 #HANGUL SYLLABLE THIEUTH U CHIEUCH + {0xB953, 0xD244}, //9565 #HANGUL SYLLABLE THIEUTH U KHIEUKH + {0xB954, 0xD245}, //9566 #HANGUL SYLLABLE THIEUTH U THIEUTH + {0xB955, 0xD246}, //9567 #HANGUL SYLLABLE THIEUTH U PHIEUPH + {0xB956, 0xD247}, //9568 #HANGUL SYLLABLE THIEUTH U HIEUH + {0xB957, 0xD249}, //9569 #HANGUL SYLLABLE THIEUTH WEO KIYEOK + {0xB958, 0xD24A}, //9570 #HANGUL SYLLABLE THIEUTH WEO SSANGKIYEOK + {0xB959, 0xD24B}, //9571 #HANGUL SYLLABLE THIEUTH WEO KIYEOKSIOS + {0xB95A, 0xD24C}, //9572 #HANGUL SYLLABLE THIEUTH WEO NIEUN + {0xB961, 0xD24D}, //9573 #HANGUL SYLLABLE THIEUTH WEO NIEUNCIEUC + {0xB962, 0xD24E}, //9574 #HANGUL SYLLABLE THIEUTH WEO NIEUNHIEUH + {0xB963, 0xD24F}, //9575 #HANGUL SYLLABLE THIEUTH WEO TIKEUT + {0xB964, 0xD250}, //9576 #HANGUL SYLLABLE THIEUTH WEO RIEUL + {0xB965, 0xD251}, //9577 #HANGUL SYLLABLE THIEUTH WEO RIEULKIYEOK + {0xB966, 0xD252}, //9578 #HANGUL SYLLABLE THIEUTH WEO RIEULMIEUM + {0xB967, 0xD253}, //9579 #HANGUL SYLLABLE THIEUTH WEO RIEULPIEUP + {0xB968, 0xD254}, //9580 #HANGUL SYLLABLE THIEUTH WEO RIEULSIOS + {0xB969, 0xD255}, //9581 #HANGUL SYLLABLE THIEUTH WEO RIEULTHIEUTH + {0xB96A, 0xD256}, //9582 #HANGUL SYLLABLE THIEUTH WEO RIEULPHIEUPH + {0xB96B, 0xD257}, //9583 #HANGUL SYLLABLE THIEUTH WEO RIEULHIEUH + {0xB96C, 0xD258}, //9584 #HANGUL SYLLABLE THIEUTH WEO MIEUM + {0xB96D, 0xD259}, //9585 #HANGUL SYLLABLE THIEUTH WEO PIEUP + {0xB96E, 0xD25A}, //9586 #HANGUL SYLLABLE THIEUTH WEO PIEUPSIOS + {0xB96F, 0xD25B}, //9587 #HANGUL SYLLABLE THIEUTH WEO SIOS + {0xB970, 0xD25D}, //9588 #HANGUL SYLLABLE THIEUTH WEO IEUNG + {0xB971, 0xD25E}, //9589 #HANGUL SYLLABLE THIEUTH WEO CIEUC + {0xB972, 0xD25F}, //9590 #HANGUL SYLLABLE THIEUTH WEO CHIEUCH + {0xB973, 0xD260}, //9591 #HANGUL SYLLABLE THIEUTH WEO KHIEUKH + {0xB974, 0xD261}, //9592 #HANGUL SYLLABLE THIEUTH WEO THIEUTH + {0xB975, 0xD262}, //9593 #HANGUL SYLLABLE THIEUTH WEO PHIEUPH + {0xB976, 0xD263}, //9594 #HANGUL SYLLABLE THIEUTH WEO HIEUH + {0xB977, 0xD265}, //9595 #HANGUL SYLLABLE THIEUTH WE KIYEOK + {0xB978, 0xD266}, //9596 #HANGUL SYLLABLE THIEUTH WE SSANGKIYEOK + {0xB979, 0xD267}, //9597 #HANGUL SYLLABLE THIEUTH WE KIYEOKSIOS + {0xB97A, 0xD268}, //9598 #HANGUL SYLLABLE THIEUTH WE NIEUN + {0xB981, 0xD269}, //9599 #HANGUL SYLLABLE THIEUTH WE NIEUNCIEUC + {0xB982, 0xD26A}, //9600 #HANGUL SYLLABLE THIEUTH WE NIEUNHIEUH + {0xB983, 0xD26B}, //9601 #HANGUL SYLLABLE THIEUTH WE TIKEUT + {0xB984, 0xD26C}, //9602 #HANGUL SYLLABLE THIEUTH WE RIEUL + {0xB985, 0xD26D}, //9603 #HANGUL SYLLABLE THIEUTH WE RIEULKIYEOK + {0xB986, 0xD26E}, //9604 #HANGUL SYLLABLE THIEUTH WE RIEULMIEUM + {0xB987, 0xD26F}, //9605 #HANGUL SYLLABLE THIEUTH WE RIEULPIEUP + {0xB988, 0xD270}, //9606 #HANGUL SYLLABLE THIEUTH WE RIEULSIOS + {0xB989, 0xD271}, //9607 #HANGUL SYLLABLE THIEUTH WE RIEULTHIEUTH + {0xB98A, 0xD272}, //9608 #HANGUL SYLLABLE THIEUTH WE RIEULPHIEUPH + {0xB98B, 0xD273}, //9609 #HANGUL SYLLABLE THIEUTH WE RIEULHIEUH + {0xB98C, 0xD274}, //9610 #HANGUL SYLLABLE THIEUTH WE MIEUM + {0xB98D, 0xD275}, //9611 #HANGUL SYLLABLE THIEUTH WE PIEUP + {0xB98E, 0xD276}, //9612 #HANGUL SYLLABLE THIEUTH WE PIEUPSIOS + {0xB98F, 0xD277}, //9613 #HANGUL SYLLABLE THIEUTH WE SIOS + {0xB990, 0xD278}, //9614 #HANGUL SYLLABLE THIEUTH WE SSANGSIOS + {0xB991, 0xD279}, //9615 #HANGUL SYLLABLE THIEUTH WE IEUNG + {0xB992, 0xD27A}, //9616 #HANGUL SYLLABLE THIEUTH WE CIEUC + {0xB993, 0xD27B}, //9617 #HANGUL SYLLABLE THIEUTH WE CHIEUCH + {0xB994, 0xD27C}, //9618 #HANGUL SYLLABLE THIEUTH WE KHIEUKH + {0xB995, 0xD27D}, //9619 #HANGUL SYLLABLE THIEUTH WE THIEUTH + {0xB996, 0xD27E}, //9620 #HANGUL SYLLABLE THIEUTH WE PHIEUPH + {0xB997, 0xD27F}, //9621 #HANGUL SYLLABLE THIEUTH WE HIEUH + {0xB998, 0xD282}, //9622 #HANGUL SYLLABLE THIEUTH WI SSANGKIYEOK + {0xB999, 0xD283}, //9623 #HANGUL SYLLABLE THIEUTH WI KIYEOKSIOS + {0xB99A, 0xD285}, //9624 #HANGUL SYLLABLE THIEUTH WI NIEUNCIEUC + {0xB99B, 0xD286}, //9625 #HANGUL SYLLABLE THIEUTH WI NIEUNHIEUH + {0xB99C, 0xD287}, //9626 #HANGUL SYLLABLE THIEUTH WI TIKEUT + {0xB99D, 0xD289}, //9627 #HANGUL SYLLABLE THIEUTH WI RIEULKIYEOK + {0xB99E, 0xD28A}, //9628 #HANGUL SYLLABLE THIEUTH WI RIEULMIEUM + {0xB99F, 0xD28B}, //9629 #HANGUL SYLLABLE THIEUTH WI RIEULPIEUP + {0xB9A0, 0xD28C}, //9630 #HANGUL SYLLABLE THIEUTH WI RIEULSIOS + {0xB9A1, 0xBB00}, //9631 #HANGUL SYLLABLE MIEUM OE NIEUN + {0xB9A2, 0xBB04}, //9632 #HANGUL SYLLABLE MIEUM OE RIEUL + {0xB9A3, 0xBB0D}, //9633 #HANGUL SYLLABLE MIEUM OE PIEUP + {0xB9A4, 0xBB0F}, //9634 #HANGUL SYLLABLE MIEUM OE SIOS + {0xB9A5, 0xBB11}, //9635 #HANGUL SYLLABLE MIEUM OE IEUNG + {0xB9A6, 0xBB18}, //9636 #HANGUL SYLLABLE MIEUM YO + {0xB9A7, 0xBB1C}, //9637 #HANGUL SYLLABLE MIEUM YO NIEUN + {0xB9A8, 0xBB20}, //9638 #HANGUL SYLLABLE MIEUM YO RIEUL + {0xB9A9, 0xBB29}, //9639 #HANGUL SYLLABLE MIEUM YO PIEUP + {0xB9AA, 0xBB2B}, //9640 #HANGUL SYLLABLE MIEUM YO SIOS + {0xB9AB, 0xBB34}, //9641 #HANGUL SYLLABLE MIEUM U + {0xB9AC, 0xBB35}, //9642 #HANGUL SYLLABLE MIEUM U KIYEOK + {0xB9AD, 0xBB36}, //9643 #HANGUL SYLLABLE MIEUM U SSANGKIYEOK + {0xB9AE, 0xBB38}, //9644 #HANGUL SYLLABLE MIEUM U NIEUN + {0xB9AF, 0xBB3B}, //9645 #HANGUL SYLLABLE MIEUM U TIKEUT + {0xB9B0, 0xBB3C}, //9646 #HANGUL SYLLABLE MIEUM U RIEUL + {0xB9B1, 0xBB3D}, //9647 #HANGUL SYLLABLE MIEUM U RIEULKIYEOK + {0xB9B2, 0xBB3E}, //9648 #HANGUL SYLLABLE MIEUM U RIEULMIEUM + {0xB9B3, 0xBB44}, //9649 #HANGUL SYLLABLE MIEUM U MIEUM + {0xB9B4, 0xBB45}, //9650 #HANGUL SYLLABLE MIEUM U PIEUP + {0xB9B5, 0xBB47}, //9651 #HANGUL SYLLABLE MIEUM U SIOS + {0xB9B6, 0xBB49}, //9652 #HANGUL SYLLABLE MIEUM U IEUNG + {0xB9B7, 0xBB4D}, //9653 #HANGUL SYLLABLE MIEUM U THIEUTH + {0xB9B8, 0xBB4F}, //9654 #HANGUL SYLLABLE MIEUM U HIEUH + {0xB9B9, 0xBB50}, //9655 #HANGUL SYLLABLE MIEUM WEO + {0xB9BA, 0xBB54}, //9656 #HANGUL SYLLABLE MIEUM WEO NIEUN + {0xB9BB, 0xBB58}, //9657 #HANGUL SYLLABLE MIEUM WEO RIEUL + {0xB9BC, 0xBB61}, //9658 #HANGUL SYLLABLE MIEUM WEO PIEUP + {0xB9BD, 0xBB63}, //9659 #HANGUL SYLLABLE MIEUM WEO SIOS + {0xB9BE, 0xBB6C}, //9660 #HANGUL SYLLABLE MIEUM WE + {0xB9BF, 0xBB88}, //9661 #HANGUL SYLLABLE MIEUM WI + {0xB9C0, 0xBB8C}, //9662 #HANGUL SYLLABLE MIEUM WI NIEUN + {0xB9C1, 0xBB90}, //9663 #HANGUL SYLLABLE MIEUM WI RIEUL + {0xB9C2, 0xBBA4}, //9664 #HANGUL SYLLABLE MIEUM YU + {0xB9C3, 0xBBA8}, //9665 #HANGUL SYLLABLE MIEUM YU NIEUN + {0xB9C4, 0xBBAC}, //9666 #HANGUL SYLLABLE MIEUM YU RIEUL + {0xB9C5, 0xBBB4}, //9667 #HANGUL SYLLABLE MIEUM YU MIEUM + {0xB9C6, 0xBBB7}, //9668 #HANGUL SYLLABLE MIEUM YU SIOS + {0xB9C7, 0xBBC0}, //9669 #HANGUL SYLLABLE MIEUM EU + {0xB9C8, 0xBBC4}, //9670 #HANGUL SYLLABLE MIEUM EU NIEUN + {0xB9C9, 0xBBC8}, //9671 #HANGUL SYLLABLE MIEUM EU RIEUL + {0xB9CA, 0xBBD0}, //9672 #HANGUL SYLLABLE MIEUM EU MIEUM + {0xB9CB, 0xBBD3}, //9673 #HANGUL SYLLABLE MIEUM EU SIOS + {0xB9CC, 0xBBF8}, //9674 #HANGUL SYLLABLE MIEUM I + {0xB9CD, 0xBBF9}, //9675 #HANGUL SYLLABLE MIEUM I KIYEOK + {0xB9CE, 0xBBFC}, //9676 #HANGUL SYLLABLE MIEUM I NIEUN + {0xB9CF, 0xBBFF}, //9677 #HANGUL SYLLABLE MIEUM I TIKEUT + {0xB9D0, 0xBC00}, //9678 #HANGUL SYLLABLE MIEUM I RIEUL + {0xB9D1, 0xBC02}, //9679 #HANGUL SYLLABLE MIEUM I RIEULMIEUM + {0xB9D2, 0xBC08}, //9680 #HANGUL SYLLABLE MIEUM I MIEUM + {0xB9D3, 0xBC09}, //9681 #HANGUL SYLLABLE MIEUM I PIEUP + {0xB9D4, 0xBC0B}, //9682 #HANGUL SYLLABLE MIEUM I SIOS + {0xB9D5, 0xBC0C}, //9683 #HANGUL SYLLABLE MIEUM I SSANGSIOS + {0xB9D6, 0xBC0D}, //9684 #HANGUL SYLLABLE MIEUM I IEUNG + {0xB9D7, 0xBC0F}, //9685 #HANGUL SYLLABLE MIEUM I CHIEUCH + {0xB9D8, 0xBC11}, //9686 #HANGUL SYLLABLE MIEUM I THIEUTH + {0xB9D9, 0xBC14}, //9687 #HANGUL SYLLABLE PIEUP A + {0xB9DA, 0xBC15}, //9688 #HANGUL SYLLABLE PIEUP A KIYEOK + {0xB9DB, 0xBC16}, //9689 #HANGUL SYLLABLE PIEUP A SSANGKIYEOK + {0xB9DC, 0xBC17}, //9690 #HANGUL SYLLABLE PIEUP A KIYEOKSIOS + {0xB9DD, 0xBC18}, //9691 #HANGUL SYLLABLE PIEUP A NIEUN + {0xB9DE, 0xBC1B}, //9692 #HANGUL SYLLABLE PIEUP A TIKEUT + {0xB9DF, 0xBC1C}, //9693 #HANGUL SYLLABLE PIEUP A RIEUL + {0xB9E0, 0xBC1D}, //9694 #HANGUL SYLLABLE PIEUP A RIEULKIYEOK + {0xB9E1, 0xBC1E}, //9695 #HANGUL SYLLABLE PIEUP A RIEULMIEUM + {0xB9E2, 0xBC1F}, //9696 #HANGUL SYLLABLE PIEUP A RIEULPIEUP + {0xB9E3, 0xBC24}, //9697 #HANGUL SYLLABLE PIEUP A MIEUM + {0xB9E4, 0xBC25}, //9698 #HANGUL SYLLABLE PIEUP A PIEUP + {0xB9E5, 0xBC27}, //9699 #HANGUL SYLLABLE PIEUP A SIOS + {0xB9E6, 0xBC29}, //9700 #HANGUL SYLLABLE PIEUP A IEUNG + {0xB9E7, 0xBC2D}, //9701 #HANGUL SYLLABLE PIEUP A THIEUTH + {0xB9E8, 0xBC30}, //9702 #HANGUL SYLLABLE PIEUP AE + {0xB9E9, 0xBC31}, //9703 #HANGUL SYLLABLE PIEUP AE KIYEOK + {0xB9EA, 0xBC34}, //9704 #HANGUL SYLLABLE PIEUP AE NIEUN + {0xB9EB, 0xBC38}, //9705 #HANGUL SYLLABLE PIEUP AE RIEUL + {0xB9EC, 0xBC40}, //9706 #HANGUL SYLLABLE PIEUP AE MIEUM + {0xB9ED, 0xBC41}, //9707 #HANGUL SYLLABLE PIEUP AE PIEUP + {0xB9EE, 0xBC43}, //9708 #HANGUL SYLLABLE PIEUP AE SIOS + {0xB9EF, 0xBC44}, //9709 #HANGUL SYLLABLE PIEUP AE SSANGSIOS + {0xB9F0, 0xBC45}, //9710 #HANGUL SYLLABLE PIEUP AE IEUNG + {0xB9F1, 0xBC49}, //9711 #HANGUL SYLLABLE PIEUP AE THIEUTH + {0xB9F2, 0xBC4C}, //9712 #HANGUL SYLLABLE PIEUP YA + {0xB9F3, 0xBC4D}, //9713 #HANGUL SYLLABLE PIEUP YA KIYEOK + {0xB9F4, 0xBC50}, //9714 #HANGUL SYLLABLE PIEUP YA NIEUN + {0xB9F5, 0xBC5D}, //9715 #HANGUL SYLLABLE PIEUP YA PIEUP + {0xB9F6, 0xBC84}, //9716 #HANGUL SYLLABLE PIEUP EO + {0xB9F7, 0xBC85}, //9717 #HANGUL SYLLABLE PIEUP EO KIYEOK + {0xB9F8, 0xBC88}, //9718 #HANGUL SYLLABLE PIEUP EO NIEUN + {0xB9F9, 0xBC8B}, //9719 #HANGUL SYLLABLE PIEUP EO TIKEUT + {0xB9FA, 0xBC8C}, //9720 #HANGUL SYLLABLE PIEUP EO RIEUL + {0xB9FB, 0xBC8E}, //9721 #HANGUL SYLLABLE PIEUP EO RIEULMIEUM + {0xB9FC, 0xBC94}, //9722 #HANGUL SYLLABLE PIEUP EO MIEUM + {0xB9FD, 0xBC95}, //9723 #HANGUL SYLLABLE PIEUP EO PIEUP + {0xB9FE, 0xBC97}, //9724 #HANGUL SYLLABLE PIEUP EO SIOS + {0xBA41, 0xD28D}, //9725 #HANGUL SYLLABLE THIEUTH WI RIEULTHIEUTH + {0xBA42, 0xD28E}, //9726 #HANGUL SYLLABLE THIEUTH WI RIEULPHIEUPH + {0xBA43, 0xD28F}, //9727 #HANGUL SYLLABLE THIEUTH WI RIEULHIEUH + {0xBA44, 0xD292}, //9728 #HANGUL SYLLABLE THIEUTH WI PIEUPSIOS + {0xBA45, 0xD293}, //9729 #HANGUL SYLLABLE THIEUTH WI SIOS + {0xBA46, 0xD294}, //9730 #HANGUL SYLLABLE THIEUTH WI SSANGSIOS + {0xBA47, 0xD296}, //9731 #HANGUL SYLLABLE THIEUTH WI CIEUC + {0xBA48, 0xD297}, //9732 #HANGUL SYLLABLE THIEUTH WI CHIEUCH + {0xBA49, 0xD298}, //9733 #HANGUL SYLLABLE THIEUTH WI KHIEUKH + {0xBA4A, 0xD299}, //9734 #HANGUL SYLLABLE THIEUTH WI THIEUTH + {0xBA4B, 0xD29A}, //9735 #HANGUL SYLLABLE THIEUTH WI PHIEUPH + {0xBA4C, 0xD29B}, //9736 #HANGUL SYLLABLE THIEUTH WI HIEUH + {0xBA4D, 0xD29D}, //9737 #HANGUL SYLLABLE THIEUTH YU KIYEOK + {0xBA4E, 0xD29E}, //9738 #HANGUL SYLLABLE THIEUTH YU SSANGKIYEOK + {0xBA4F, 0xD29F}, //9739 #HANGUL SYLLABLE THIEUTH YU KIYEOKSIOS + {0xBA50, 0xD2A1}, //9740 #HANGUL SYLLABLE THIEUTH YU NIEUNCIEUC + {0xBA51, 0xD2A2}, //9741 #HANGUL SYLLABLE THIEUTH YU NIEUNHIEUH + {0xBA52, 0xD2A3}, //9742 #HANGUL SYLLABLE THIEUTH YU TIKEUT + {0xBA53, 0xD2A5}, //9743 #HANGUL SYLLABLE THIEUTH YU RIEULKIYEOK + {0xBA54, 0xD2A6}, //9744 #HANGUL SYLLABLE THIEUTH YU RIEULMIEUM + {0xBA55, 0xD2A7}, //9745 #HANGUL SYLLABLE THIEUTH YU RIEULPIEUP + {0xBA56, 0xD2A8}, //9746 #HANGUL SYLLABLE THIEUTH YU RIEULSIOS + {0xBA57, 0xD2A9}, //9747 #HANGUL SYLLABLE THIEUTH YU RIEULTHIEUTH + {0xBA58, 0xD2AA}, //9748 #HANGUL SYLLABLE THIEUTH YU RIEULPHIEUPH + {0xBA59, 0xD2AB}, //9749 #HANGUL SYLLABLE THIEUTH YU RIEULHIEUH + {0xBA5A, 0xD2AD}, //9750 #HANGUL SYLLABLE THIEUTH YU PIEUP + {0xBA61, 0xD2AE}, //9751 #HANGUL SYLLABLE THIEUTH YU PIEUPSIOS + {0xBA62, 0xD2AF}, //9752 #HANGUL SYLLABLE THIEUTH YU SIOS + {0xBA63, 0xD2B0}, //9753 #HANGUL SYLLABLE THIEUTH YU SSANGSIOS + {0xBA64, 0xD2B2}, //9754 #HANGUL SYLLABLE THIEUTH YU CIEUC + {0xBA65, 0xD2B3}, //9755 #HANGUL SYLLABLE THIEUTH YU CHIEUCH + {0xBA66, 0xD2B4}, //9756 #HANGUL SYLLABLE THIEUTH YU KHIEUKH + {0xBA67, 0xD2B5}, //9757 #HANGUL SYLLABLE THIEUTH YU THIEUTH + {0xBA68, 0xD2B6}, //9758 #HANGUL SYLLABLE THIEUTH YU PHIEUPH + {0xBA69, 0xD2B7}, //9759 #HANGUL SYLLABLE THIEUTH YU HIEUH + {0xBA6A, 0xD2BA}, //9760 #HANGUL SYLLABLE THIEUTH EU SSANGKIYEOK + {0xBA6B, 0xD2BB}, //9761 #HANGUL SYLLABLE THIEUTH EU KIYEOKSIOS + {0xBA6C, 0xD2BD}, //9762 #HANGUL SYLLABLE THIEUTH EU NIEUNCIEUC + {0xBA6D, 0xD2BE}, //9763 #HANGUL SYLLABLE THIEUTH EU NIEUNHIEUH + {0xBA6E, 0xD2C1}, //9764 #HANGUL SYLLABLE THIEUTH EU RIEULKIYEOK + {0xBA6F, 0xD2C3}, //9765 #HANGUL SYLLABLE THIEUTH EU RIEULPIEUP + {0xBA70, 0xD2C4}, //9766 #HANGUL SYLLABLE THIEUTH EU RIEULSIOS + {0xBA71, 0xD2C5}, //9767 #HANGUL SYLLABLE THIEUTH EU RIEULTHIEUTH + {0xBA72, 0xD2C6}, //9768 #HANGUL SYLLABLE THIEUTH EU RIEULPHIEUPH + {0xBA73, 0xD2C7}, //9769 #HANGUL SYLLABLE THIEUTH EU RIEULHIEUH + {0xBA74, 0xD2CA}, //9770 #HANGUL SYLLABLE THIEUTH EU PIEUPSIOS + {0xBA75, 0xD2CC}, //9771 #HANGUL SYLLABLE THIEUTH EU SSANGSIOS + {0xBA76, 0xD2CD}, //9772 #HANGUL SYLLABLE THIEUTH EU IEUNG + {0xBA77, 0xD2CE}, //9773 #HANGUL SYLLABLE THIEUTH EU CIEUC + {0xBA78, 0xD2CF}, //9774 #HANGUL SYLLABLE THIEUTH EU CHIEUCH + {0xBA79, 0xD2D0}, //9775 #HANGUL SYLLABLE THIEUTH EU KHIEUKH + {0xBA7A, 0xD2D1}, //9776 #HANGUL SYLLABLE THIEUTH EU THIEUTH + {0xBA81, 0xD2D2}, //9777 #HANGUL SYLLABLE THIEUTH EU PHIEUPH + {0xBA82, 0xD2D3}, //9778 #HANGUL SYLLABLE THIEUTH EU HIEUH + {0xBA83, 0xD2D5}, //9779 #HANGUL SYLLABLE THIEUTH YI KIYEOK + {0xBA84, 0xD2D6}, //9780 #HANGUL SYLLABLE THIEUTH YI SSANGKIYEOK + {0xBA85, 0xD2D7}, //9781 #HANGUL SYLLABLE THIEUTH YI KIYEOKSIOS + {0xBA86, 0xD2D9}, //9782 #HANGUL SYLLABLE THIEUTH YI NIEUNCIEUC + {0xBA87, 0xD2DA}, //9783 #HANGUL SYLLABLE THIEUTH YI NIEUNHIEUH + {0xBA88, 0xD2DB}, //9784 #HANGUL SYLLABLE THIEUTH YI TIKEUT + {0xBA89, 0xD2DD}, //9785 #HANGUL SYLLABLE THIEUTH YI RIEULKIYEOK + {0xBA8A, 0xD2DE}, //9786 #HANGUL SYLLABLE THIEUTH YI RIEULMIEUM + {0xBA8B, 0xD2DF}, //9787 #HANGUL SYLLABLE THIEUTH YI RIEULPIEUP + {0xBA8C, 0xD2E0}, //9788 #HANGUL SYLLABLE THIEUTH YI RIEULSIOS + {0xBA8D, 0xD2E1}, //9789 #HANGUL SYLLABLE THIEUTH YI RIEULTHIEUTH + {0xBA8E, 0xD2E2}, //9790 #HANGUL SYLLABLE THIEUTH YI RIEULPHIEUPH + {0xBA8F, 0xD2E3}, //9791 #HANGUL SYLLABLE THIEUTH YI RIEULHIEUH + {0xBA90, 0xD2E6}, //9792 #HANGUL SYLLABLE THIEUTH YI PIEUPSIOS + {0xBA91, 0xD2E7}, //9793 #HANGUL SYLLABLE THIEUTH YI SIOS + {0xBA92, 0xD2E8}, //9794 #HANGUL SYLLABLE THIEUTH YI SSANGSIOS + {0xBA93, 0xD2E9}, //9795 #HANGUL SYLLABLE THIEUTH YI IEUNG + {0xBA94, 0xD2EA}, //9796 #HANGUL SYLLABLE THIEUTH YI CIEUC + {0xBA95, 0xD2EB}, //9797 #HANGUL SYLLABLE THIEUTH YI CHIEUCH + {0xBA96, 0xD2EC}, //9798 #HANGUL SYLLABLE THIEUTH YI KHIEUKH + {0xBA97, 0xD2ED}, //9799 #HANGUL SYLLABLE THIEUTH YI THIEUTH + {0xBA98, 0xD2EE}, //9800 #HANGUL SYLLABLE THIEUTH YI PHIEUPH + {0xBA99, 0xD2EF}, //9801 #HANGUL SYLLABLE THIEUTH YI HIEUH + {0xBA9A, 0xD2F2}, //9802 #HANGUL SYLLABLE THIEUTH I SSANGKIYEOK + {0xBA9B, 0xD2F3}, //9803 #HANGUL SYLLABLE THIEUTH I KIYEOKSIOS + {0xBA9C, 0xD2F5}, //9804 #HANGUL SYLLABLE THIEUTH I NIEUNCIEUC + {0xBA9D, 0xD2F6}, //9805 #HANGUL SYLLABLE THIEUTH I NIEUNHIEUH + {0xBA9E, 0xD2F7}, //9806 #HANGUL SYLLABLE THIEUTH I TIKEUT + {0xBA9F, 0xD2F9}, //9807 #HANGUL SYLLABLE THIEUTH I RIEULKIYEOK + {0xBAA0, 0xD2FA}, //9808 #HANGUL SYLLABLE THIEUTH I RIEULMIEUM + {0xBAA1, 0xBC99}, //9809 #HANGUL SYLLABLE PIEUP EO IEUNG + {0xBAA2, 0xBC9A}, //9810 #HANGUL SYLLABLE PIEUP EO CIEUC + {0xBAA3, 0xBCA0}, //9811 #HANGUL SYLLABLE PIEUP E + {0xBAA4, 0xBCA1}, //9812 #HANGUL SYLLABLE PIEUP E KIYEOK + {0xBAA5, 0xBCA4}, //9813 #HANGUL SYLLABLE PIEUP E NIEUN + {0xBAA6, 0xBCA7}, //9814 #HANGUL SYLLABLE PIEUP E TIKEUT + {0xBAA7, 0xBCA8}, //9815 #HANGUL SYLLABLE PIEUP E RIEUL + {0xBAA8, 0xBCB0}, //9816 #HANGUL SYLLABLE PIEUP E MIEUM + {0xBAA9, 0xBCB1}, //9817 #HANGUL SYLLABLE PIEUP E PIEUP + {0xBAAA, 0xBCB3}, //9818 #HANGUL SYLLABLE PIEUP E SIOS + {0xBAAB, 0xBCB4}, //9819 #HANGUL SYLLABLE PIEUP E SSANGSIOS + {0xBAAC, 0xBCB5}, //9820 #HANGUL SYLLABLE PIEUP E IEUNG + {0xBAAD, 0xBCBC}, //9821 #HANGUL SYLLABLE PIEUP YEO + {0xBAAE, 0xBCBD}, //9822 #HANGUL SYLLABLE PIEUP YEO KIYEOK + {0xBAAF, 0xBCC0}, //9823 #HANGUL SYLLABLE PIEUP YEO NIEUN + {0xBAB0, 0xBCC4}, //9824 #HANGUL SYLLABLE PIEUP YEO RIEUL + {0xBAB1, 0xBCCD}, //9825 #HANGUL SYLLABLE PIEUP YEO PIEUP + {0xBAB2, 0xBCCF}, //9826 #HANGUL SYLLABLE PIEUP YEO SIOS + {0xBAB3, 0xBCD0}, //9827 #HANGUL SYLLABLE PIEUP YEO SSANGSIOS + {0xBAB4, 0xBCD1}, //9828 #HANGUL SYLLABLE PIEUP YEO IEUNG + {0xBAB5, 0xBCD5}, //9829 #HANGUL SYLLABLE PIEUP YEO THIEUTH + {0xBAB6, 0xBCD8}, //9830 #HANGUL SYLLABLE PIEUP YE + {0xBAB7, 0xBCDC}, //9831 #HANGUL SYLLABLE PIEUP YE NIEUN + {0xBAB8, 0xBCF4}, //9832 #HANGUL SYLLABLE PIEUP O + {0xBAB9, 0xBCF5}, //9833 #HANGUL SYLLABLE PIEUP O KIYEOK + {0xBABA, 0xBCF6}, //9834 #HANGUL SYLLABLE PIEUP O SSANGKIYEOK + {0xBABB, 0xBCF8}, //9835 #HANGUL SYLLABLE PIEUP O NIEUN + {0xBABC, 0xBCFC}, //9836 #HANGUL SYLLABLE PIEUP O RIEUL + {0xBABD, 0xBD04}, //9837 #HANGUL SYLLABLE PIEUP O MIEUM + {0xBABE, 0xBD05}, //9838 #HANGUL SYLLABLE PIEUP O PIEUP + {0xBABF, 0xBD07}, //9839 #HANGUL SYLLABLE PIEUP O SIOS + {0xBAC0, 0xBD09}, //9840 #HANGUL SYLLABLE PIEUP O IEUNG + {0xBAC1, 0xBD10}, //9841 #HANGUL SYLLABLE PIEUP WA + {0xBAC2, 0xBD14}, //9842 #HANGUL SYLLABLE PIEUP WA NIEUN + {0xBAC3, 0xBD24}, //9843 #HANGUL SYLLABLE PIEUP WA SSANGSIOS + {0xBAC4, 0xBD2C}, //9844 #HANGUL SYLLABLE PIEUP WAE + {0xBAC5, 0xBD40}, //9845 #HANGUL SYLLABLE PIEUP WAE SSANGSIOS + {0xBAC6, 0xBD48}, //9846 #HANGUL SYLLABLE PIEUP OE + {0xBAC7, 0xBD49}, //9847 #HANGUL SYLLABLE PIEUP OE KIYEOK + {0xBAC8, 0xBD4C}, //9848 #HANGUL SYLLABLE PIEUP OE NIEUN + {0xBAC9, 0xBD50}, //9849 #HANGUL SYLLABLE PIEUP OE RIEUL + {0xBACA, 0xBD58}, //9850 #HANGUL SYLLABLE PIEUP OE MIEUM + {0xBACB, 0xBD59}, //9851 #HANGUL SYLLABLE PIEUP OE PIEUP + {0xBACC, 0xBD64}, //9852 #HANGUL SYLLABLE PIEUP YO + {0xBACD, 0xBD68}, //9853 #HANGUL SYLLABLE PIEUP YO NIEUN + {0xBACE, 0xBD80}, //9854 #HANGUL SYLLABLE PIEUP U + {0xBACF, 0xBD81}, //9855 #HANGUL SYLLABLE PIEUP U KIYEOK + {0xBAD0, 0xBD84}, //9856 #HANGUL SYLLABLE PIEUP U NIEUN + {0xBAD1, 0xBD87}, //9857 #HANGUL SYLLABLE PIEUP U TIKEUT + {0xBAD2, 0xBD88}, //9858 #HANGUL SYLLABLE PIEUP U RIEUL + {0xBAD3, 0xBD89}, //9859 #HANGUL SYLLABLE PIEUP U RIEULKIYEOK + {0xBAD4, 0xBD8A}, //9860 #HANGUL SYLLABLE PIEUP U RIEULMIEUM + {0xBAD5, 0xBD90}, //9861 #HANGUL SYLLABLE PIEUP U MIEUM + {0xBAD6, 0xBD91}, //9862 #HANGUL SYLLABLE PIEUP U PIEUP + {0xBAD7, 0xBD93}, //9863 #HANGUL SYLLABLE PIEUP U SIOS + {0xBAD8, 0xBD95}, //9864 #HANGUL SYLLABLE PIEUP U IEUNG + {0xBAD9, 0xBD99}, //9865 #HANGUL SYLLABLE PIEUP U THIEUTH + {0xBADA, 0xBD9A}, //9866 #HANGUL SYLLABLE PIEUP U PHIEUPH + {0xBADB, 0xBD9C}, //9867 #HANGUL SYLLABLE PIEUP WEO + {0xBADC, 0xBDA4}, //9868 #HANGUL SYLLABLE PIEUP WEO RIEUL + {0xBADD, 0xBDB0}, //9869 #HANGUL SYLLABLE PIEUP WEO SSANGSIOS + {0xBADE, 0xBDB8}, //9870 #HANGUL SYLLABLE PIEUP WE + {0xBADF, 0xBDD4}, //9871 #HANGUL SYLLABLE PIEUP WI + {0xBAE0, 0xBDD5}, //9872 #HANGUL SYLLABLE PIEUP WI KIYEOK + {0xBAE1, 0xBDD8}, //9873 #HANGUL SYLLABLE PIEUP WI NIEUN + {0xBAE2, 0xBDDC}, //9874 #HANGUL SYLLABLE PIEUP WI RIEUL + {0xBAE3, 0xBDE9}, //9875 #HANGUL SYLLABLE PIEUP WI IEUNG + {0xBAE4, 0xBDF0}, //9876 #HANGUL SYLLABLE PIEUP YU + {0xBAE5, 0xBDF4}, //9877 #HANGUL SYLLABLE PIEUP YU NIEUN + {0xBAE6, 0xBDF8}, //9878 #HANGUL SYLLABLE PIEUP YU RIEUL + {0xBAE7, 0xBE00}, //9879 #HANGUL SYLLABLE PIEUP YU MIEUM + {0xBAE8, 0xBE03}, //9880 #HANGUL SYLLABLE PIEUP YU SIOS + {0xBAE9, 0xBE05}, //9881 #HANGUL SYLLABLE PIEUP YU IEUNG + {0xBAEA, 0xBE0C}, //9882 #HANGUL SYLLABLE PIEUP EU + {0xBAEB, 0xBE0D}, //9883 #HANGUL SYLLABLE PIEUP EU KIYEOK + {0xBAEC, 0xBE10}, //9884 #HANGUL SYLLABLE PIEUP EU NIEUN + {0xBAED, 0xBE14}, //9885 #HANGUL SYLLABLE PIEUP EU RIEUL + {0xBAEE, 0xBE1C}, //9886 #HANGUL SYLLABLE PIEUP EU MIEUM + {0xBAEF, 0xBE1D}, //9887 #HANGUL SYLLABLE PIEUP EU PIEUP + {0xBAF0, 0xBE1F}, //9888 #HANGUL SYLLABLE PIEUP EU SIOS + {0xBAF1, 0xBE44}, //9889 #HANGUL SYLLABLE PIEUP I + {0xBAF2, 0xBE45}, //9890 #HANGUL SYLLABLE PIEUP I KIYEOK + {0xBAF3, 0xBE48}, //9891 #HANGUL SYLLABLE PIEUP I NIEUN + {0xBAF4, 0xBE4C}, //9892 #HANGUL SYLLABLE PIEUP I RIEUL + {0xBAF5, 0xBE4E}, //9893 #HANGUL SYLLABLE PIEUP I RIEULMIEUM + {0xBAF6, 0xBE54}, //9894 #HANGUL SYLLABLE PIEUP I MIEUM + {0xBAF7, 0xBE55}, //9895 #HANGUL SYLLABLE PIEUP I PIEUP + {0xBAF8, 0xBE57}, //9896 #HANGUL SYLLABLE PIEUP I SIOS + {0xBAF9, 0xBE59}, //9897 #HANGUL SYLLABLE PIEUP I IEUNG + {0xBAFA, 0xBE5A}, //9898 #HANGUL SYLLABLE PIEUP I CIEUC + {0xBAFB, 0xBE5B}, //9899 #HANGUL SYLLABLE PIEUP I CHIEUCH + {0xBAFC, 0xBE60}, //9900 #HANGUL SYLLABLE SSANGPIEUP A + {0xBAFD, 0xBE61}, //9901 #HANGUL SYLLABLE SSANGPIEUP A KIYEOK + {0xBAFE, 0xBE64}, //9902 #HANGUL SYLLABLE SSANGPIEUP A NIEUN + {0xBB41, 0xD2FB}, //9903 #HANGUL SYLLABLE THIEUTH I RIEULPIEUP + {0xBB42, 0xD2FC}, //9904 #HANGUL SYLLABLE THIEUTH I RIEULSIOS + {0xBB43, 0xD2FD}, //9905 #HANGUL SYLLABLE THIEUTH I RIEULTHIEUTH + {0xBB44, 0xD2FE}, //9906 #HANGUL SYLLABLE THIEUTH I RIEULPHIEUPH + {0xBB45, 0xD2FF}, //9907 #HANGUL SYLLABLE THIEUTH I RIEULHIEUH + {0xBB46, 0xD302}, //9908 #HANGUL SYLLABLE THIEUTH I PIEUPSIOS + {0xBB47, 0xD304}, //9909 #HANGUL SYLLABLE THIEUTH I SSANGSIOS + {0xBB48, 0xD306}, //9910 #HANGUL SYLLABLE THIEUTH I CIEUC + {0xBB49, 0xD307}, //9911 #HANGUL SYLLABLE THIEUTH I CHIEUCH + {0xBB4A, 0xD308}, //9912 #HANGUL SYLLABLE THIEUTH I KHIEUKH + {0xBB4B, 0xD309}, //9913 #HANGUL SYLLABLE THIEUTH I THIEUTH + {0xBB4C, 0xD30A}, //9914 #HANGUL SYLLABLE THIEUTH I PHIEUPH + {0xBB4D, 0xD30B}, //9915 #HANGUL SYLLABLE THIEUTH I HIEUH + {0xBB4E, 0xD30F}, //9916 #HANGUL SYLLABLE PHIEUPH A KIYEOKSIOS + {0xBB4F, 0xD311}, //9917 #HANGUL SYLLABLE PHIEUPH A NIEUNCIEUC + {0xBB50, 0xD312}, //9918 #HANGUL SYLLABLE PHIEUPH A NIEUNHIEUH + {0xBB51, 0xD313}, //9919 #HANGUL SYLLABLE PHIEUPH A TIKEUT + {0xBB52, 0xD315}, //9920 #HANGUL SYLLABLE PHIEUPH A RIEULKIYEOK + {0xBB53, 0xD317}, //9921 #HANGUL SYLLABLE PHIEUPH A RIEULPIEUP + {0xBB54, 0xD318}, //9922 #HANGUL SYLLABLE PHIEUPH A RIEULSIOS + {0xBB55, 0xD319}, //9923 #HANGUL SYLLABLE PHIEUPH A RIEULTHIEUTH + {0xBB56, 0xD31A}, //9924 #HANGUL SYLLABLE PHIEUPH A RIEULPHIEUPH + {0xBB57, 0xD31B}, //9925 #HANGUL SYLLABLE PHIEUPH A RIEULHIEUH + {0xBB58, 0xD31E}, //9926 #HANGUL SYLLABLE PHIEUPH A PIEUPSIOS + {0xBB59, 0xD322}, //9927 #HANGUL SYLLABLE PHIEUPH A CIEUC + {0xBB5A, 0xD323}, //9928 #HANGUL SYLLABLE PHIEUPH A CHIEUCH + {0xBB61, 0xD324}, //9929 #HANGUL SYLLABLE PHIEUPH A KHIEUKH + {0xBB62, 0xD326}, //9930 #HANGUL SYLLABLE PHIEUPH A PHIEUPH + {0xBB63, 0xD327}, //9931 #HANGUL SYLLABLE PHIEUPH A HIEUH + {0xBB64, 0xD32A}, //9932 #HANGUL SYLLABLE PHIEUPH AE SSANGKIYEOK + {0xBB65, 0xD32B}, //9933 #HANGUL SYLLABLE PHIEUPH AE KIYEOKSIOS + {0xBB66, 0xD32D}, //9934 #HANGUL SYLLABLE PHIEUPH AE NIEUNCIEUC + {0xBB67, 0xD32E}, //9935 #HANGUL SYLLABLE PHIEUPH AE NIEUNHIEUH + {0xBB68, 0xD32F}, //9936 #HANGUL SYLLABLE PHIEUPH AE TIKEUT + {0xBB69, 0xD331}, //9937 #HANGUL SYLLABLE PHIEUPH AE RIEULKIYEOK + {0xBB6A, 0xD332}, //9938 #HANGUL SYLLABLE PHIEUPH AE RIEULMIEUM + {0xBB6B, 0xD333}, //9939 #HANGUL SYLLABLE PHIEUPH AE RIEULPIEUP + {0xBB6C, 0xD334}, //9940 #HANGUL SYLLABLE PHIEUPH AE RIEULSIOS + {0xBB6D, 0xD335}, //9941 #HANGUL SYLLABLE PHIEUPH AE RIEULTHIEUTH + {0xBB6E, 0xD336}, //9942 #HANGUL SYLLABLE PHIEUPH AE RIEULPHIEUPH + {0xBB6F, 0xD337}, //9943 #HANGUL SYLLABLE PHIEUPH AE RIEULHIEUH + {0xBB70, 0xD33A}, //9944 #HANGUL SYLLABLE PHIEUPH AE PIEUPSIOS + {0xBB71, 0xD33E}, //9945 #HANGUL SYLLABLE PHIEUPH AE CIEUC + {0xBB72, 0xD33F}, //9946 #HANGUL SYLLABLE PHIEUPH AE CHIEUCH + {0xBB73, 0xD340}, //9947 #HANGUL SYLLABLE PHIEUPH AE KHIEUKH + {0xBB74, 0xD341}, //9948 #HANGUL SYLLABLE PHIEUPH AE THIEUTH + {0xBB75, 0xD342}, //9949 #HANGUL SYLLABLE PHIEUPH AE PHIEUPH + {0xBB76, 0xD343}, //9950 #HANGUL SYLLABLE PHIEUPH AE HIEUH + {0xBB77, 0xD346}, //9951 #HANGUL SYLLABLE PHIEUPH YA SSANGKIYEOK + {0xBB78, 0xD347}, //9952 #HANGUL SYLLABLE PHIEUPH YA KIYEOKSIOS + {0xBB79, 0xD348}, //9953 #HANGUL SYLLABLE PHIEUPH YA NIEUN + {0xBB7A, 0xD349}, //9954 #HANGUL SYLLABLE PHIEUPH YA NIEUNCIEUC + {0xBB81, 0xD34A}, //9955 #HANGUL SYLLABLE PHIEUPH YA NIEUNHIEUH + {0xBB82, 0xD34B}, //9956 #HANGUL SYLLABLE PHIEUPH YA TIKEUT + {0xBB83, 0xD34C}, //9957 #HANGUL SYLLABLE PHIEUPH YA RIEUL + {0xBB84, 0xD34D}, //9958 #HANGUL SYLLABLE PHIEUPH YA RIEULKIYEOK + {0xBB85, 0xD34E}, //9959 #HANGUL SYLLABLE PHIEUPH YA RIEULMIEUM + {0xBB86, 0xD34F}, //9960 #HANGUL SYLLABLE PHIEUPH YA RIEULPIEUP + {0xBB87, 0xD350}, //9961 #HANGUL SYLLABLE PHIEUPH YA RIEULSIOS + {0xBB88, 0xD351}, //9962 #HANGUL SYLLABLE PHIEUPH YA RIEULTHIEUTH + {0xBB89, 0xD352}, //9963 #HANGUL SYLLABLE PHIEUPH YA RIEULPHIEUPH + {0xBB8A, 0xD353}, //9964 #HANGUL SYLLABLE PHIEUPH YA RIEULHIEUH + {0xBB8B, 0xD354}, //9965 #HANGUL SYLLABLE PHIEUPH YA MIEUM + {0xBB8C, 0xD355}, //9966 #HANGUL SYLLABLE PHIEUPH YA PIEUP + {0xBB8D, 0xD356}, //9967 #HANGUL SYLLABLE PHIEUPH YA PIEUPSIOS + {0xBB8E, 0xD357}, //9968 #HANGUL SYLLABLE PHIEUPH YA SIOS + {0xBB8F, 0xD358}, //9969 #HANGUL SYLLABLE PHIEUPH YA SSANGSIOS + {0xBB90, 0xD359}, //9970 #HANGUL SYLLABLE PHIEUPH YA IEUNG + {0xBB91, 0xD35A}, //9971 #HANGUL SYLLABLE PHIEUPH YA CIEUC + {0xBB92, 0xD35B}, //9972 #HANGUL SYLLABLE PHIEUPH YA CHIEUCH + {0xBB93, 0xD35C}, //9973 #HANGUL SYLLABLE PHIEUPH YA KHIEUKH + {0xBB94, 0xD35D}, //9974 #HANGUL SYLLABLE PHIEUPH YA THIEUTH + {0xBB95, 0xD35E}, //9975 #HANGUL SYLLABLE PHIEUPH YA PHIEUPH + {0xBB96, 0xD35F}, //9976 #HANGUL SYLLABLE PHIEUPH YA HIEUH + {0xBB97, 0xD360}, //9977 #HANGUL SYLLABLE PHIEUPH YAE + {0xBB98, 0xD361}, //9978 #HANGUL SYLLABLE PHIEUPH YAE KIYEOK + {0xBB99, 0xD362}, //9979 #HANGUL SYLLABLE PHIEUPH YAE SSANGKIYEOK + {0xBB9A, 0xD363}, //9980 #HANGUL SYLLABLE PHIEUPH YAE KIYEOKSIOS + {0xBB9B, 0xD364}, //9981 #HANGUL SYLLABLE PHIEUPH YAE NIEUN + {0xBB9C, 0xD365}, //9982 #HANGUL SYLLABLE PHIEUPH YAE NIEUNCIEUC + {0xBB9D, 0xD366}, //9983 #HANGUL SYLLABLE PHIEUPH YAE NIEUNHIEUH + {0xBB9E, 0xD367}, //9984 #HANGUL SYLLABLE PHIEUPH YAE TIKEUT + {0xBB9F, 0xD368}, //9985 #HANGUL SYLLABLE PHIEUPH YAE RIEUL + {0xBBA0, 0xD369}, //9986 #HANGUL SYLLABLE PHIEUPH YAE RIEULKIYEOK + {0xBBA1, 0xBE68}, //9987 #HANGUL SYLLABLE SSANGPIEUP A RIEUL + {0xBBA2, 0xBE6A}, //9988 #HANGUL SYLLABLE SSANGPIEUP A RIEULMIEUM + {0xBBA3, 0xBE70}, //9989 #HANGUL SYLLABLE SSANGPIEUP A MIEUM + {0xBBA4, 0xBE71}, //9990 #HANGUL SYLLABLE SSANGPIEUP A PIEUP + {0xBBA5, 0xBE73}, //9991 #HANGUL SYLLABLE SSANGPIEUP A SIOS + {0xBBA6, 0xBE74}, //9992 #HANGUL SYLLABLE SSANGPIEUP A SSANGSIOS + {0xBBA7, 0xBE75}, //9993 #HANGUL SYLLABLE SSANGPIEUP A IEUNG + {0xBBA8, 0xBE7B}, //9994 #HANGUL SYLLABLE SSANGPIEUP A HIEUH + {0xBBA9, 0xBE7C}, //9995 #HANGUL SYLLABLE SSANGPIEUP AE + {0xBBAA, 0xBE7D}, //9996 #HANGUL SYLLABLE SSANGPIEUP AE KIYEOK + {0xBBAB, 0xBE80}, //9997 #HANGUL SYLLABLE SSANGPIEUP AE NIEUN + {0xBBAC, 0xBE84}, //9998 #HANGUL SYLLABLE SSANGPIEUP AE RIEUL + {0xBBAD, 0xBE8C}, //9999 #HANGUL SYLLABLE SSANGPIEUP AE MIEUM + {0xBBAE, 0xBE8D}, //10000 #HANGUL SYLLABLE SSANGPIEUP AE PIEUP + {0xBBAF, 0xBE8F}, //10001 #HANGUL SYLLABLE SSANGPIEUP AE SIOS + {0xBBB0, 0xBE90}, //10002 #HANGUL SYLLABLE SSANGPIEUP AE SSANGSIOS + {0xBBB1, 0xBE91}, //10003 #HANGUL SYLLABLE SSANGPIEUP AE IEUNG + {0xBBB2, 0xBE98}, //10004 #HANGUL SYLLABLE SSANGPIEUP YA + {0xBBB3, 0xBE99}, //10005 #HANGUL SYLLABLE SSANGPIEUP YA KIYEOK + {0xBBB4, 0xBEA8}, //10006 #HANGUL SYLLABLE SSANGPIEUP YA MIEUM + {0xBBB5, 0xBED0}, //10007 #HANGUL SYLLABLE SSANGPIEUP EO + {0xBBB6, 0xBED1}, //10008 #HANGUL SYLLABLE SSANGPIEUP EO KIYEOK + {0xBBB7, 0xBED4}, //10009 #HANGUL SYLLABLE SSANGPIEUP EO NIEUN + {0xBBB8, 0xBED7}, //10010 #HANGUL SYLLABLE SSANGPIEUP EO TIKEUT + {0xBBB9, 0xBED8}, //10011 #HANGUL SYLLABLE SSANGPIEUP EO RIEUL + {0xBBBA, 0xBEE0}, //10012 #HANGUL SYLLABLE SSANGPIEUP EO MIEUM + {0xBBBB, 0xBEE3}, //10013 #HANGUL SYLLABLE SSANGPIEUP EO SIOS + {0xBBBC, 0xBEE4}, //10014 #HANGUL SYLLABLE SSANGPIEUP EO SSANGSIOS + {0xBBBD, 0xBEE5}, //10015 #HANGUL SYLLABLE SSANGPIEUP EO IEUNG + {0xBBBE, 0xBEEC}, //10016 #HANGUL SYLLABLE SSANGPIEUP E + {0xBBBF, 0xBF01}, //10017 #HANGUL SYLLABLE SSANGPIEUP E IEUNG + {0xBBC0, 0xBF08}, //10018 #HANGUL SYLLABLE SSANGPIEUP YEO + {0xBBC1, 0xBF09}, //10019 #HANGUL SYLLABLE SSANGPIEUP YEO KIYEOK + {0xBBC2, 0xBF18}, //10020 #HANGUL SYLLABLE SSANGPIEUP YEO MIEUM + {0xBBC3, 0xBF19}, //10021 #HANGUL SYLLABLE SSANGPIEUP YEO PIEUP + {0xBBC4, 0xBF1B}, //10022 #HANGUL SYLLABLE SSANGPIEUP YEO SIOS + {0xBBC5, 0xBF1C}, //10023 #HANGUL SYLLABLE SSANGPIEUP YEO SSANGSIOS + {0xBBC6, 0xBF1D}, //10024 #HANGUL SYLLABLE SSANGPIEUP YEO IEUNG + {0xBBC7, 0xBF40}, //10025 #HANGUL SYLLABLE SSANGPIEUP O + {0xBBC8, 0xBF41}, //10026 #HANGUL SYLLABLE SSANGPIEUP O KIYEOK + {0xBBC9, 0xBF44}, //10027 #HANGUL SYLLABLE SSANGPIEUP O NIEUN + {0xBBCA, 0xBF48}, //10028 #HANGUL SYLLABLE SSANGPIEUP O RIEUL + {0xBBCB, 0xBF50}, //10029 #HANGUL SYLLABLE SSANGPIEUP O MIEUM + {0xBBCC, 0xBF51}, //10030 #HANGUL SYLLABLE SSANGPIEUP O PIEUP + {0xBBCD, 0xBF55}, //10031 #HANGUL SYLLABLE SSANGPIEUP O IEUNG + {0xBBCE, 0xBF94}, //10032 #HANGUL SYLLABLE SSANGPIEUP OE + {0xBBCF, 0xBFB0}, //10033 #HANGUL SYLLABLE SSANGPIEUP YO + {0xBBD0, 0xBFC5}, //10034 #HANGUL SYLLABLE SSANGPIEUP YO IEUNG + {0xBBD1, 0xBFCC}, //10035 #HANGUL SYLLABLE SSANGPIEUP U + {0xBBD2, 0xBFCD}, //10036 #HANGUL SYLLABLE SSANGPIEUP U KIYEOK + {0xBBD3, 0xBFD0}, //10037 #HANGUL SYLLABLE SSANGPIEUP U NIEUN + {0xBBD4, 0xBFD4}, //10038 #HANGUL SYLLABLE SSANGPIEUP U RIEUL + {0xBBD5, 0xBFDC}, //10039 #HANGUL SYLLABLE SSANGPIEUP U MIEUM + {0xBBD6, 0xBFDF}, //10040 #HANGUL SYLLABLE SSANGPIEUP U SIOS + {0xBBD7, 0xBFE1}, //10041 #HANGUL SYLLABLE SSANGPIEUP U IEUNG + {0xBBD8, 0xC03C}, //10042 #HANGUL SYLLABLE SSANGPIEUP YU + {0xBBD9, 0xC051}, //10043 #HANGUL SYLLABLE SSANGPIEUP YU IEUNG + {0xBBDA, 0xC058}, //10044 #HANGUL SYLLABLE SSANGPIEUP EU + {0xBBDB, 0xC05C}, //10045 #HANGUL SYLLABLE SSANGPIEUP EU NIEUN + {0xBBDC, 0xC060}, //10046 #HANGUL SYLLABLE SSANGPIEUP EU RIEUL + {0xBBDD, 0xC068}, //10047 #HANGUL SYLLABLE SSANGPIEUP EU MIEUM + {0xBBDE, 0xC069}, //10048 #HANGUL SYLLABLE SSANGPIEUP EU PIEUP + {0xBBDF, 0xC090}, //10049 #HANGUL SYLLABLE SSANGPIEUP I + {0xBBE0, 0xC091}, //10050 #HANGUL SYLLABLE SSANGPIEUP I KIYEOK + {0xBBE1, 0xC094}, //10051 #HANGUL SYLLABLE SSANGPIEUP I NIEUN + {0xBBE2, 0xC098}, //10052 #HANGUL SYLLABLE SSANGPIEUP I RIEUL + {0xBBE3, 0xC0A0}, //10053 #HANGUL SYLLABLE SSANGPIEUP I MIEUM + {0xBBE4, 0xC0A1}, //10054 #HANGUL SYLLABLE SSANGPIEUP I PIEUP + {0xBBE5, 0xC0A3}, //10055 #HANGUL SYLLABLE SSANGPIEUP I SIOS + {0xBBE6, 0xC0A5}, //10056 #HANGUL SYLLABLE SSANGPIEUP I IEUNG + {0xBBE7, 0xC0AC}, //10057 #HANGUL SYLLABLE SIOS A + {0xBBE8, 0xC0AD}, //10058 #HANGUL SYLLABLE SIOS A KIYEOK + {0xBBE9, 0xC0AF}, //10059 #HANGUL SYLLABLE SIOS A KIYEOKSIOS + {0xBBEA, 0xC0B0}, //10060 #HANGUL SYLLABLE SIOS A NIEUN + {0xBBEB, 0xC0B3}, //10061 #HANGUL SYLLABLE SIOS A TIKEUT + {0xBBEC, 0xC0B4}, //10062 #HANGUL SYLLABLE SIOS A RIEUL + {0xBBED, 0xC0B5}, //10063 #HANGUL SYLLABLE SIOS A RIEULKIYEOK + {0xBBEE, 0xC0B6}, //10064 #HANGUL SYLLABLE SIOS A RIEULMIEUM + {0xBBEF, 0xC0BC}, //10065 #HANGUL SYLLABLE SIOS A MIEUM + {0xBBF0, 0xC0BD}, //10066 #HANGUL SYLLABLE SIOS A PIEUP + {0xBBF1, 0xC0BF}, //10067 #HANGUL SYLLABLE SIOS A SIOS + {0xBBF2, 0xC0C0}, //10068 #HANGUL SYLLABLE SIOS A SSANGSIOS + {0xBBF3, 0xC0C1}, //10069 #HANGUL SYLLABLE SIOS A IEUNG + {0xBBF4, 0xC0C5}, //10070 #HANGUL SYLLABLE SIOS A THIEUTH + {0xBBF5, 0xC0C8}, //10071 #HANGUL SYLLABLE SIOS AE + {0xBBF6, 0xC0C9}, //10072 #HANGUL SYLLABLE SIOS AE KIYEOK + {0xBBF7, 0xC0CC}, //10073 #HANGUL SYLLABLE SIOS AE NIEUN + {0xBBF8, 0xC0D0}, //10074 #HANGUL SYLLABLE SIOS AE RIEUL + {0xBBF9, 0xC0D8}, //10075 #HANGUL SYLLABLE SIOS AE MIEUM + {0xBBFA, 0xC0D9}, //10076 #HANGUL SYLLABLE SIOS AE PIEUP + {0xBBFB, 0xC0DB}, //10077 #HANGUL SYLLABLE SIOS AE SIOS + {0xBBFC, 0xC0DC}, //10078 #HANGUL SYLLABLE SIOS AE SSANGSIOS + {0xBBFD, 0xC0DD}, //10079 #HANGUL SYLLABLE SIOS AE IEUNG + {0xBBFE, 0xC0E4}, //10080 #HANGUL SYLLABLE SIOS YA + {0xBC41, 0xD36A}, //10081 #HANGUL SYLLABLE PHIEUPH YAE RIEULMIEUM + {0xBC42, 0xD36B}, //10082 #HANGUL SYLLABLE PHIEUPH YAE RIEULPIEUP + {0xBC43, 0xD36C}, //10083 #HANGUL SYLLABLE PHIEUPH YAE RIEULSIOS + {0xBC44, 0xD36D}, //10084 #HANGUL SYLLABLE PHIEUPH YAE RIEULTHIEUTH + {0xBC45, 0xD36E}, //10085 #HANGUL SYLLABLE PHIEUPH YAE RIEULPHIEUPH + {0xBC46, 0xD36F}, //10086 #HANGUL SYLLABLE PHIEUPH YAE RIEULHIEUH + {0xBC47, 0xD370}, //10087 #HANGUL SYLLABLE PHIEUPH YAE MIEUM + {0xBC48, 0xD371}, //10088 #HANGUL SYLLABLE PHIEUPH YAE PIEUP + {0xBC49, 0xD372}, //10089 #HANGUL SYLLABLE PHIEUPH YAE PIEUPSIOS + {0xBC4A, 0xD373}, //10090 #HANGUL SYLLABLE PHIEUPH YAE SIOS + {0xBC4B, 0xD374}, //10091 #HANGUL SYLLABLE PHIEUPH YAE SSANGSIOS + {0xBC4C, 0xD375}, //10092 #HANGUL SYLLABLE PHIEUPH YAE IEUNG + {0xBC4D, 0xD376}, //10093 #HANGUL SYLLABLE PHIEUPH YAE CIEUC + {0xBC4E, 0xD377}, //10094 #HANGUL SYLLABLE PHIEUPH YAE CHIEUCH + {0xBC4F, 0xD378}, //10095 #HANGUL SYLLABLE PHIEUPH YAE KHIEUKH + {0xBC50, 0xD379}, //10096 #HANGUL SYLLABLE PHIEUPH YAE THIEUTH + {0xBC51, 0xD37A}, //10097 #HANGUL SYLLABLE PHIEUPH YAE PHIEUPH + {0xBC52, 0xD37B}, //10098 #HANGUL SYLLABLE PHIEUPH YAE HIEUH + {0xBC53, 0xD37E}, //10099 #HANGUL SYLLABLE PHIEUPH EO SSANGKIYEOK + {0xBC54, 0xD37F}, //10100 #HANGUL SYLLABLE PHIEUPH EO KIYEOKSIOS + {0xBC55, 0xD381}, //10101 #HANGUL SYLLABLE PHIEUPH EO NIEUNCIEUC + {0xBC56, 0xD382}, //10102 #HANGUL SYLLABLE PHIEUPH EO NIEUNHIEUH + {0xBC57, 0xD383}, //10103 #HANGUL SYLLABLE PHIEUPH EO TIKEUT + {0xBC58, 0xD385}, //10104 #HANGUL SYLLABLE PHIEUPH EO RIEULKIYEOK + {0xBC59, 0xD386}, //10105 #HANGUL SYLLABLE PHIEUPH EO RIEULMIEUM + {0xBC5A, 0xD387}, //10106 #HANGUL SYLLABLE PHIEUPH EO RIEULPIEUP + {0xBC61, 0xD388}, //10107 #HANGUL SYLLABLE PHIEUPH EO RIEULSIOS + {0xBC62, 0xD389}, //10108 #HANGUL SYLLABLE PHIEUPH EO RIEULTHIEUTH + {0xBC63, 0xD38A}, //10109 #HANGUL SYLLABLE PHIEUPH EO RIEULPHIEUPH + {0xBC64, 0xD38B}, //10110 #HANGUL SYLLABLE PHIEUPH EO RIEULHIEUH + {0xBC65, 0xD38E}, //10111 #HANGUL SYLLABLE PHIEUPH EO PIEUPSIOS + {0xBC66, 0xD392}, //10112 #HANGUL SYLLABLE PHIEUPH EO CIEUC + {0xBC67, 0xD393}, //10113 #HANGUL SYLLABLE PHIEUPH EO CHIEUCH + {0xBC68, 0xD394}, //10114 #HANGUL SYLLABLE PHIEUPH EO KHIEUKH + {0xBC69, 0xD395}, //10115 #HANGUL SYLLABLE PHIEUPH EO THIEUTH + {0xBC6A, 0xD396}, //10116 #HANGUL SYLLABLE PHIEUPH EO PHIEUPH + {0xBC6B, 0xD397}, //10117 #HANGUL SYLLABLE PHIEUPH EO HIEUH + {0xBC6C, 0xD39A}, //10118 #HANGUL SYLLABLE PHIEUPH E SSANGKIYEOK + {0xBC6D, 0xD39B}, //10119 #HANGUL SYLLABLE PHIEUPH E KIYEOKSIOS + {0xBC6E, 0xD39D}, //10120 #HANGUL SYLLABLE PHIEUPH E NIEUNCIEUC + {0xBC6F, 0xD39E}, //10121 #HANGUL SYLLABLE PHIEUPH E NIEUNHIEUH + {0xBC70, 0xD39F}, //10122 #HANGUL SYLLABLE PHIEUPH E TIKEUT + {0xBC71, 0xD3A1}, //10123 #HANGUL SYLLABLE PHIEUPH E RIEULKIYEOK + {0xBC72, 0xD3A2}, //10124 #HANGUL SYLLABLE PHIEUPH E RIEULMIEUM + {0xBC73, 0xD3A3}, //10125 #HANGUL SYLLABLE PHIEUPH E RIEULPIEUP + {0xBC74, 0xD3A4}, //10126 #HANGUL SYLLABLE PHIEUPH E RIEULSIOS + {0xBC75, 0xD3A5}, //10127 #HANGUL SYLLABLE PHIEUPH E RIEULTHIEUTH + {0xBC76, 0xD3A6}, //10128 #HANGUL SYLLABLE PHIEUPH E RIEULPHIEUPH + {0xBC77, 0xD3A7}, //10129 #HANGUL SYLLABLE PHIEUPH E RIEULHIEUH + {0xBC78, 0xD3AA}, //10130 #HANGUL SYLLABLE PHIEUPH E PIEUPSIOS + {0xBC79, 0xD3AC}, //10131 #HANGUL SYLLABLE PHIEUPH E SSANGSIOS + {0xBC7A, 0xD3AE}, //10132 #HANGUL SYLLABLE PHIEUPH E CIEUC + {0xBC81, 0xD3AF}, //10133 #HANGUL SYLLABLE PHIEUPH E CHIEUCH + {0xBC82, 0xD3B0}, //10134 #HANGUL SYLLABLE PHIEUPH E KHIEUKH + {0xBC83, 0xD3B1}, //10135 #HANGUL SYLLABLE PHIEUPH E THIEUTH + {0xBC84, 0xD3B2}, //10136 #HANGUL SYLLABLE PHIEUPH E PHIEUPH + {0xBC85, 0xD3B3}, //10137 #HANGUL SYLLABLE PHIEUPH E HIEUH + {0xBC86, 0xD3B5}, //10138 #HANGUL SYLLABLE PHIEUPH YEO KIYEOK + {0xBC87, 0xD3B6}, //10139 #HANGUL SYLLABLE PHIEUPH YEO SSANGKIYEOK + {0xBC88, 0xD3B7}, //10140 #HANGUL SYLLABLE PHIEUPH YEO KIYEOKSIOS + {0xBC89, 0xD3B9}, //10141 #HANGUL SYLLABLE PHIEUPH YEO NIEUNCIEUC + {0xBC8A, 0xD3BA}, //10142 #HANGUL SYLLABLE PHIEUPH YEO NIEUNHIEUH + {0xBC8B, 0xD3BB}, //10143 #HANGUL SYLLABLE PHIEUPH YEO TIKEUT + {0xBC8C, 0xD3BD}, //10144 #HANGUL SYLLABLE PHIEUPH YEO RIEULKIYEOK + {0xBC8D, 0xD3BE}, //10145 #HANGUL SYLLABLE PHIEUPH YEO RIEULMIEUM + {0xBC8E, 0xD3BF}, //10146 #HANGUL SYLLABLE PHIEUPH YEO RIEULPIEUP + {0xBC8F, 0xD3C0}, //10147 #HANGUL SYLLABLE PHIEUPH YEO RIEULSIOS + {0xBC90, 0xD3C1}, //10148 #HANGUL SYLLABLE PHIEUPH YEO RIEULTHIEUTH + {0xBC91, 0xD3C2}, //10149 #HANGUL SYLLABLE PHIEUPH YEO RIEULPHIEUPH + {0xBC92, 0xD3C3}, //10150 #HANGUL SYLLABLE PHIEUPH YEO RIEULHIEUH + {0xBC93, 0xD3C6}, //10151 #HANGUL SYLLABLE PHIEUPH YEO PIEUPSIOS + {0xBC94, 0xD3C7}, //10152 #HANGUL SYLLABLE PHIEUPH YEO SIOS + {0xBC95, 0xD3CA}, //10153 #HANGUL SYLLABLE PHIEUPH YEO CIEUC + {0xBC96, 0xD3CB}, //10154 #HANGUL SYLLABLE PHIEUPH YEO CHIEUCH + {0xBC97, 0xD3CC}, //10155 #HANGUL SYLLABLE PHIEUPH YEO KHIEUKH + {0xBC98, 0xD3CD}, //10156 #HANGUL SYLLABLE PHIEUPH YEO THIEUTH + {0xBC99, 0xD3CE}, //10157 #HANGUL SYLLABLE PHIEUPH YEO PHIEUPH + {0xBC9A, 0xD3CF}, //10158 #HANGUL SYLLABLE PHIEUPH YEO HIEUH + {0xBC9B, 0xD3D1}, //10159 #HANGUL SYLLABLE PHIEUPH YE KIYEOK + {0xBC9C, 0xD3D2}, //10160 #HANGUL SYLLABLE PHIEUPH YE SSANGKIYEOK + {0xBC9D, 0xD3D3}, //10161 #HANGUL SYLLABLE PHIEUPH YE KIYEOKSIOS + {0xBC9E, 0xD3D4}, //10162 #HANGUL SYLLABLE PHIEUPH YE NIEUN + {0xBC9F, 0xD3D5}, //10163 #HANGUL SYLLABLE PHIEUPH YE NIEUNCIEUC + {0xBCA0, 0xD3D6}, //10164 #HANGUL SYLLABLE PHIEUPH YE NIEUNHIEUH + {0xBCA1, 0xC0E5}, //10165 #HANGUL SYLLABLE SIOS YA KIYEOK + {0xBCA2, 0xC0E8}, //10166 #HANGUL SYLLABLE SIOS YA NIEUN + {0xBCA3, 0xC0EC}, //10167 #HANGUL SYLLABLE SIOS YA RIEUL + {0xBCA4, 0xC0F4}, //10168 #HANGUL SYLLABLE SIOS YA MIEUM + {0xBCA5, 0xC0F5}, //10169 #HANGUL SYLLABLE SIOS YA PIEUP + {0xBCA6, 0xC0F7}, //10170 #HANGUL SYLLABLE SIOS YA SIOS + {0xBCA7, 0xC0F9}, //10171 #HANGUL SYLLABLE SIOS YA IEUNG + {0xBCA8, 0xC100}, //10172 #HANGUL SYLLABLE SIOS YAE + {0xBCA9, 0xC104}, //10173 #HANGUL SYLLABLE SIOS YAE NIEUN + {0xBCAA, 0xC108}, //10174 #HANGUL SYLLABLE SIOS YAE RIEUL + {0xBCAB, 0xC110}, //10175 #HANGUL SYLLABLE SIOS YAE MIEUM + {0xBCAC, 0xC115}, //10176 #HANGUL SYLLABLE SIOS YAE IEUNG + {0xBCAD, 0xC11C}, //10177 #HANGUL SYLLABLE SIOS EO + {0xBCAE, 0xC11D}, //10178 #HANGUL SYLLABLE SIOS EO KIYEOK + {0xBCAF, 0xC11E}, //10179 #HANGUL SYLLABLE SIOS EO SSANGKIYEOK + {0xBCB0, 0xC11F}, //10180 #HANGUL SYLLABLE SIOS EO KIYEOKSIOS + {0xBCB1, 0xC120}, //10181 #HANGUL SYLLABLE SIOS EO NIEUN + {0xBCB2, 0xC123}, //10182 #HANGUL SYLLABLE SIOS EO TIKEUT + {0xBCB3, 0xC124}, //10183 #HANGUL SYLLABLE SIOS EO RIEUL + {0xBCB4, 0xC126}, //10184 #HANGUL SYLLABLE SIOS EO RIEULMIEUM + {0xBCB5, 0xC127}, //10185 #HANGUL SYLLABLE SIOS EO RIEULPIEUP + {0xBCB6, 0xC12C}, //10186 #HANGUL SYLLABLE SIOS EO MIEUM + {0xBCB7, 0xC12D}, //10187 #HANGUL SYLLABLE SIOS EO PIEUP + {0xBCB8, 0xC12F}, //10188 #HANGUL SYLLABLE SIOS EO SIOS + {0xBCB9, 0xC130}, //10189 #HANGUL SYLLABLE SIOS EO SSANGSIOS + {0xBCBA, 0xC131}, //10190 #HANGUL SYLLABLE SIOS EO IEUNG + {0xBCBB, 0xC136}, //10191 #HANGUL SYLLABLE SIOS EO PHIEUPH + {0xBCBC, 0xC138}, //10192 #HANGUL SYLLABLE SIOS E + {0xBCBD, 0xC139}, //10193 #HANGUL SYLLABLE SIOS E KIYEOK + {0xBCBE, 0xC13C}, //10194 #HANGUL SYLLABLE SIOS E NIEUN + {0xBCBF, 0xC140}, //10195 #HANGUL SYLLABLE SIOS E RIEUL + {0xBCC0, 0xC148}, //10196 #HANGUL SYLLABLE SIOS E MIEUM + {0xBCC1, 0xC149}, //10197 #HANGUL SYLLABLE SIOS E PIEUP + {0xBCC2, 0xC14B}, //10198 #HANGUL SYLLABLE SIOS E SIOS + {0xBCC3, 0xC14C}, //10199 #HANGUL SYLLABLE SIOS E SSANGSIOS + {0xBCC4, 0xC14D}, //10200 #HANGUL SYLLABLE SIOS E IEUNG + {0xBCC5, 0xC154}, //10201 #HANGUL SYLLABLE SIOS YEO + {0xBCC6, 0xC155}, //10202 #HANGUL SYLLABLE SIOS YEO KIYEOK + {0xBCC7, 0xC158}, //10203 #HANGUL SYLLABLE SIOS YEO NIEUN + {0xBCC8, 0xC15C}, //10204 #HANGUL SYLLABLE SIOS YEO RIEUL + {0xBCC9, 0xC164}, //10205 #HANGUL SYLLABLE SIOS YEO MIEUM + {0xBCCA, 0xC165}, //10206 #HANGUL SYLLABLE SIOS YEO PIEUP + {0xBCCB, 0xC167}, //10207 #HANGUL SYLLABLE SIOS YEO SIOS + {0xBCCC, 0xC168}, //10208 #HANGUL SYLLABLE SIOS YEO SSANGSIOS + {0xBCCD, 0xC169}, //10209 #HANGUL SYLLABLE SIOS YEO IEUNG + {0xBCCE, 0xC170}, //10210 #HANGUL SYLLABLE SIOS YE + {0xBCCF, 0xC174}, //10211 #HANGUL SYLLABLE SIOS YE NIEUN + {0xBCD0, 0xC178}, //10212 #HANGUL SYLLABLE SIOS YE RIEUL + {0xBCD1, 0xC185}, //10213 #HANGUL SYLLABLE SIOS YE IEUNG + {0xBCD2, 0xC18C}, //10214 #HANGUL SYLLABLE SIOS O + {0xBCD3, 0xC18D}, //10215 #HANGUL SYLLABLE SIOS O KIYEOK + {0xBCD4, 0xC18E}, //10216 #HANGUL SYLLABLE SIOS O SSANGKIYEOK + {0xBCD5, 0xC190}, //10217 #HANGUL SYLLABLE SIOS O NIEUN + {0xBCD6, 0xC194}, //10218 #HANGUL SYLLABLE SIOS O RIEUL + {0xBCD7, 0xC196}, //10219 #HANGUL SYLLABLE SIOS O RIEULMIEUM + {0xBCD8, 0xC19C}, //10220 #HANGUL SYLLABLE SIOS O MIEUM + {0xBCD9, 0xC19D}, //10221 #HANGUL SYLLABLE SIOS O PIEUP + {0xBCDA, 0xC19F}, //10222 #HANGUL SYLLABLE SIOS O SIOS + {0xBCDB, 0xC1A1}, //10223 #HANGUL SYLLABLE SIOS O IEUNG + {0xBCDC, 0xC1A5}, //10224 #HANGUL SYLLABLE SIOS O THIEUTH + {0xBCDD, 0xC1A8}, //10225 #HANGUL SYLLABLE SIOS WA + {0xBCDE, 0xC1A9}, //10226 #HANGUL SYLLABLE SIOS WA KIYEOK + {0xBCDF, 0xC1AC}, //10227 #HANGUL SYLLABLE SIOS WA NIEUN + {0xBCE0, 0xC1B0}, //10228 #HANGUL SYLLABLE SIOS WA RIEUL + {0xBCE1, 0xC1BD}, //10229 #HANGUL SYLLABLE SIOS WA IEUNG + {0xBCE2, 0xC1C4}, //10230 #HANGUL SYLLABLE SIOS WAE + {0xBCE3, 0xC1C8}, //10231 #HANGUL SYLLABLE SIOS WAE NIEUN + {0xBCE4, 0xC1CC}, //10232 #HANGUL SYLLABLE SIOS WAE RIEUL + {0xBCE5, 0xC1D4}, //10233 #HANGUL SYLLABLE SIOS WAE MIEUM + {0xBCE6, 0xC1D7}, //10234 #HANGUL SYLLABLE SIOS WAE SIOS + {0xBCE7, 0xC1D8}, //10235 #HANGUL SYLLABLE SIOS WAE SSANGSIOS + {0xBCE8, 0xC1E0}, //10236 #HANGUL SYLLABLE SIOS OE + {0xBCE9, 0xC1E4}, //10237 #HANGUL SYLLABLE SIOS OE NIEUN + {0xBCEA, 0xC1E8}, //10238 #HANGUL SYLLABLE SIOS OE RIEUL + {0xBCEB, 0xC1F0}, //10239 #HANGUL SYLLABLE SIOS OE MIEUM + {0xBCEC, 0xC1F1}, //10240 #HANGUL SYLLABLE SIOS OE PIEUP + {0xBCED, 0xC1F3}, //10241 #HANGUL SYLLABLE SIOS OE SIOS + {0xBCEE, 0xC1FC}, //10242 #HANGUL SYLLABLE SIOS YO + {0xBCEF, 0xC1FD}, //10243 #HANGUL SYLLABLE SIOS YO KIYEOK + {0xBCF0, 0xC200}, //10244 #HANGUL SYLLABLE SIOS YO NIEUN + {0xBCF1, 0xC204}, //10245 #HANGUL SYLLABLE SIOS YO RIEUL + {0xBCF2, 0xC20C}, //10246 #HANGUL SYLLABLE SIOS YO MIEUM + {0xBCF3, 0xC20D}, //10247 #HANGUL SYLLABLE SIOS YO PIEUP + {0xBCF4, 0xC20F}, //10248 #HANGUL SYLLABLE SIOS YO SIOS + {0xBCF5, 0xC211}, //10249 #HANGUL SYLLABLE SIOS YO IEUNG + {0xBCF6, 0xC218}, //10250 #HANGUL SYLLABLE SIOS U + {0xBCF7, 0xC219}, //10251 #HANGUL SYLLABLE SIOS U KIYEOK + {0xBCF8, 0xC21C}, //10252 #HANGUL SYLLABLE SIOS U NIEUN + {0xBCF9, 0xC21F}, //10253 #HANGUL SYLLABLE SIOS U TIKEUT + {0xBCFA, 0xC220}, //10254 #HANGUL SYLLABLE SIOS U RIEUL + {0xBCFB, 0xC228}, //10255 #HANGUL SYLLABLE SIOS U MIEUM + {0xBCFC, 0xC229}, //10256 #HANGUL SYLLABLE SIOS U PIEUP + {0xBCFD, 0xC22B}, //10257 #HANGUL SYLLABLE SIOS U SIOS + {0xBCFE, 0xC22D}, //10258 #HANGUL SYLLABLE SIOS U IEUNG + {0xBD41, 0xD3D7}, //10259 #HANGUL SYLLABLE PHIEUPH YE TIKEUT + {0xBD42, 0xD3D9}, //10260 #HANGUL SYLLABLE PHIEUPH YE RIEULKIYEOK + {0xBD43, 0xD3DA}, //10261 #HANGUL SYLLABLE PHIEUPH YE RIEULMIEUM + {0xBD44, 0xD3DB}, //10262 #HANGUL SYLLABLE PHIEUPH YE RIEULPIEUP + {0xBD45, 0xD3DC}, //10263 #HANGUL SYLLABLE PHIEUPH YE RIEULSIOS + {0xBD46, 0xD3DD}, //10264 #HANGUL SYLLABLE PHIEUPH YE RIEULTHIEUTH + {0xBD47, 0xD3DE}, //10265 #HANGUL SYLLABLE PHIEUPH YE RIEULPHIEUPH + {0xBD48, 0xD3DF}, //10266 #HANGUL SYLLABLE PHIEUPH YE RIEULHIEUH + {0xBD49, 0xD3E0}, //10267 #HANGUL SYLLABLE PHIEUPH YE MIEUM + {0xBD4A, 0xD3E2}, //10268 #HANGUL SYLLABLE PHIEUPH YE PIEUPSIOS + {0xBD4B, 0xD3E4}, //10269 #HANGUL SYLLABLE PHIEUPH YE SSANGSIOS + {0xBD4C, 0xD3E5}, //10270 #HANGUL SYLLABLE PHIEUPH YE IEUNG + {0xBD4D, 0xD3E6}, //10271 #HANGUL SYLLABLE PHIEUPH YE CIEUC + {0xBD4E, 0xD3E7}, //10272 #HANGUL SYLLABLE PHIEUPH YE CHIEUCH + {0xBD4F, 0xD3E8}, //10273 #HANGUL SYLLABLE PHIEUPH YE KHIEUKH + {0xBD50, 0xD3E9}, //10274 #HANGUL SYLLABLE PHIEUPH YE THIEUTH + {0xBD51, 0xD3EA}, //10275 #HANGUL SYLLABLE PHIEUPH YE PHIEUPH + {0xBD52, 0xD3EB}, //10276 #HANGUL SYLLABLE PHIEUPH YE HIEUH + {0xBD53, 0xD3EE}, //10277 #HANGUL SYLLABLE PHIEUPH O SSANGKIYEOK + {0xBD54, 0xD3EF}, //10278 #HANGUL SYLLABLE PHIEUPH O KIYEOKSIOS + {0xBD55, 0xD3F1}, //10279 #HANGUL SYLLABLE PHIEUPH O NIEUNCIEUC + {0xBD56, 0xD3F2}, //10280 #HANGUL SYLLABLE PHIEUPH O NIEUNHIEUH + {0xBD57, 0xD3F3}, //10281 #HANGUL SYLLABLE PHIEUPH O TIKEUT + {0xBD58, 0xD3F5}, //10282 #HANGUL SYLLABLE PHIEUPH O RIEULKIYEOK + {0xBD59, 0xD3F6}, //10283 #HANGUL SYLLABLE PHIEUPH O RIEULMIEUM + {0xBD5A, 0xD3F7}, //10284 #HANGUL SYLLABLE PHIEUPH O RIEULPIEUP + {0xBD61, 0xD3F8}, //10285 #HANGUL SYLLABLE PHIEUPH O RIEULSIOS + {0xBD62, 0xD3F9}, //10286 #HANGUL SYLLABLE PHIEUPH O RIEULTHIEUTH + {0xBD63, 0xD3FA}, //10287 #HANGUL SYLLABLE PHIEUPH O RIEULPHIEUPH + {0xBD64, 0xD3FB}, //10288 #HANGUL SYLLABLE PHIEUPH O RIEULHIEUH + {0xBD65, 0xD3FE}, //10289 #HANGUL SYLLABLE PHIEUPH O PIEUPSIOS + {0xBD66, 0xD400}, //10290 #HANGUL SYLLABLE PHIEUPH O SSANGSIOS + {0xBD67, 0xD402}, //10291 #HANGUL SYLLABLE PHIEUPH O CIEUC + {0xBD68, 0xD403}, //10292 #HANGUL SYLLABLE PHIEUPH O CHIEUCH + {0xBD69, 0xD404}, //10293 #HANGUL SYLLABLE PHIEUPH O KHIEUKH + {0xBD6A, 0xD405}, //10294 #HANGUL SYLLABLE PHIEUPH O THIEUTH + {0xBD6B, 0xD406}, //10295 #HANGUL SYLLABLE PHIEUPH O PHIEUPH + {0xBD6C, 0xD407}, //10296 #HANGUL SYLLABLE PHIEUPH O HIEUH + {0xBD6D, 0xD409}, //10297 #HANGUL SYLLABLE PHIEUPH WA KIYEOK + {0xBD6E, 0xD40A}, //10298 #HANGUL SYLLABLE PHIEUPH WA SSANGKIYEOK + {0xBD6F, 0xD40B}, //10299 #HANGUL SYLLABLE PHIEUPH WA KIYEOKSIOS + {0xBD70, 0xD40C}, //10300 #HANGUL SYLLABLE PHIEUPH WA NIEUN + {0xBD71, 0xD40D}, //10301 #HANGUL SYLLABLE PHIEUPH WA NIEUNCIEUC + {0xBD72, 0xD40E}, //10302 #HANGUL SYLLABLE PHIEUPH WA NIEUNHIEUH + {0xBD73, 0xD40F}, //10303 #HANGUL SYLLABLE PHIEUPH WA TIKEUT + {0xBD74, 0xD410}, //10304 #HANGUL SYLLABLE PHIEUPH WA RIEUL + {0xBD75, 0xD411}, //10305 #HANGUL SYLLABLE PHIEUPH WA RIEULKIYEOK + {0xBD76, 0xD412}, //10306 #HANGUL SYLLABLE PHIEUPH WA RIEULMIEUM + {0xBD77, 0xD413}, //10307 #HANGUL SYLLABLE PHIEUPH WA RIEULPIEUP + {0xBD78, 0xD414}, //10308 #HANGUL SYLLABLE PHIEUPH WA RIEULSIOS + {0xBD79, 0xD415}, //10309 #HANGUL SYLLABLE PHIEUPH WA RIEULTHIEUTH + {0xBD7A, 0xD416}, //10310 #HANGUL SYLLABLE PHIEUPH WA RIEULPHIEUPH + {0xBD81, 0xD417}, //10311 #HANGUL SYLLABLE PHIEUPH WA RIEULHIEUH + {0xBD82, 0xD418}, //10312 #HANGUL SYLLABLE PHIEUPH WA MIEUM + {0xBD83, 0xD419}, //10313 #HANGUL SYLLABLE PHIEUPH WA PIEUP + {0xBD84, 0xD41A}, //10314 #HANGUL SYLLABLE PHIEUPH WA PIEUPSIOS + {0xBD85, 0xD41B}, //10315 #HANGUL SYLLABLE PHIEUPH WA SIOS + {0xBD86, 0xD41C}, //10316 #HANGUL SYLLABLE PHIEUPH WA SSANGSIOS + {0xBD87, 0xD41E}, //10317 #HANGUL SYLLABLE PHIEUPH WA CIEUC + {0xBD88, 0xD41F}, //10318 #HANGUL SYLLABLE PHIEUPH WA CHIEUCH + {0xBD89, 0xD420}, //10319 #HANGUL SYLLABLE PHIEUPH WA KHIEUKH + {0xBD8A, 0xD421}, //10320 #HANGUL SYLLABLE PHIEUPH WA THIEUTH + {0xBD8B, 0xD422}, //10321 #HANGUL SYLLABLE PHIEUPH WA PHIEUPH + {0xBD8C, 0xD423}, //10322 #HANGUL SYLLABLE PHIEUPH WA HIEUH + {0xBD8D, 0xD424}, //10323 #HANGUL SYLLABLE PHIEUPH WAE + {0xBD8E, 0xD425}, //10324 #HANGUL SYLLABLE PHIEUPH WAE KIYEOK + {0xBD8F, 0xD426}, //10325 #HANGUL SYLLABLE PHIEUPH WAE SSANGKIYEOK + {0xBD90, 0xD427}, //10326 #HANGUL SYLLABLE PHIEUPH WAE KIYEOKSIOS + {0xBD91, 0xD428}, //10327 #HANGUL SYLLABLE PHIEUPH WAE NIEUN + {0xBD92, 0xD429}, //10328 #HANGUL SYLLABLE PHIEUPH WAE NIEUNCIEUC + {0xBD93, 0xD42A}, //10329 #HANGUL SYLLABLE PHIEUPH WAE NIEUNHIEUH + {0xBD94, 0xD42B}, //10330 #HANGUL SYLLABLE PHIEUPH WAE TIKEUT + {0xBD95, 0xD42C}, //10331 #HANGUL SYLLABLE PHIEUPH WAE RIEUL + {0xBD96, 0xD42D}, //10332 #HANGUL SYLLABLE PHIEUPH WAE RIEULKIYEOK + {0xBD97, 0xD42E}, //10333 #HANGUL SYLLABLE PHIEUPH WAE RIEULMIEUM + {0xBD98, 0xD42F}, //10334 #HANGUL SYLLABLE PHIEUPH WAE RIEULPIEUP + {0xBD99, 0xD430}, //10335 #HANGUL SYLLABLE PHIEUPH WAE RIEULSIOS + {0xBD9A, 0xD431}, //10336 #HANGUL SYLLABLE PHIEUPH WAE RIEULTHIEUTH + {0xBD9B, 0xD432}, //10337 #HANGUL SYLLABLE PHIEUPH WAE RIEULPHIEUPH + {0xBD9C, 0xD433}, //10338 #HANGUL SYLLABLE PHIEUPH WAE RIEULHIEUH + {0xBD9D, 0xD434}, //10339 #HANGUL SYLLABLE PHIEUPH WAE MIEUM + {0xBD9E, 0xD435}, //10340 #HANGUL SYLLABLE PHIEUPH WAE PIEUP + {0xBD9F, 0xD436}, //10341 #HANGUL SYLLABLE PHIEUPH WAE PIEUPSIOS + {0xBDA0, 0xD437}, //10342 #HANGUL SYLLABLE PHIEUPH WAE SIOS + {0xBDA1, 0xC22F}, //10343 #HANGUL SYLLABLE SIOS U CHIEUCH + {0xBDA2, 0xC231}, //10344 #HANGUL SYLLABLE SIOS U THIEUTH + {0xBDA3, 0xC232}, //10345 #HANGUL SYLLABLE SIOS U PHIEUPH + {0xBDA4, 0xC234}, //10346 #HANGUL SYLLABLE SIOS WEO + {0xBDA5, 0xC248}, //10347 #HANGUL SYLLABLE SIOS WEO SSANGSIOS + {0xBDA6, 0xC250}, //10348 #HANGUL SYLLABLE SIOS WE + {0xBDA7, 0xC251}, //10349 #HANGUL SYLLABLE SIOS WE KIYEOK + {0xBDA8, 0xC254}, //10350 #HANGUL SYLLABLE SIOS WE NIEUN + {0xBDA9, 0xC258}, //10351 #HANGUL SYLLABLE SIOS WE RIEUL + {0xBDAA, 0xC260}, //10352 #HANGUL SYLLABLE SIOS WE MIEUM + {0xBDAB, 0xC265}, //10353 #HANGUL SYLLABLE SIOS WE IEUNG + {0xBDAC, 0xC26C}, //10354 #HANGUL SYLLABLE SIOS WI + {0xBDAD, 0xC26D}, //10355 #HANGUL SYLLABLE SIOS WI KIYEOK + {0xBDAE, 0xC270}, //10356 #HANGUL SYLLABLE SIOS WI NIEUN + {0xBDAF, 0xC274}, //10357 #HANGUL SYLLABLE SIOS WI RIEUL + {0xBDB0, 0xC27C}, //10358 #HANGUL SYLLABLE SIOS WI MIEUM + {0xBDB1, 0xC27D}, //10359 #HANGUL SYLLABLE SIOS WI PIEUP + {0xBDB2, 0xC27F}, //10360 #HANGUL SYLLABLE SIOS WI SIOS + {0xBDB3, 0xC281}, //10361 #HANGUL SYLLABLE SIOS WI IEUNG + {0xBDB4, 0xC288}, //10362 #HANGUL SYLLABLE SIOS YU + {0xBDB5, 0xC289}, //10363 #HANGUL SYLLABLE SIOS YU KIYEOK + {0xBDB6, 0xC290}, //10364 #HANGUL SYLLABLE SIOS YU RIEUL + {0xBDB7, 0xC298}, //10365 #HANGUL SYLLABLE SIOS YU MIEUM + {0xBDB8, 0xC29B}, //10366 #HANGUL SYLLABLE SIOS YU SIOS + {0xBDB9, 0xC29D}, //10367 #HANGUL SYLLABLE SIOS YU IEUNG + {0xBDBA, 0xC2A4}, //10368 #HANGUL SYLLABLE SIOS EU + {0xBDBB, 0xC2A5}, //10369 #HANGUL SYLLABLE SIOS EU KIYEOK + {0xBDBC, 0xC2A8}, //10370 #HANGUL SYLLABLE SIOS EU NIEUN + {0xBDBD, 0xC2AC}, //10371 #HANGUL SYLLABLE SIOS EU RIEUL + {0xBDBE, 0xC2AD}, //10372 #HANGUL SYLLABLE SIOS EU RIEULKIYEOK + {0xBDBF, 0xC2B4}, //10373 #HANGUL SYLLABLE SIOS EU MIEUM + {0xBDC0, 0xC2B5}, //10374 #HANGUL SYLLABLE SIOS EU PIEUP + {0xBDC1, 0xC2B7}, //10375 #HANGUL SYLLABLE SIOS EU SIOS + {0xBDC2, 0xC2B9}, //10376 #HANGUL SYLLABLE SIOS EU IEUNG + {0xBDC3, 0xC2DC}, //10377 #HANGUL SYLLABLE SIOS I + {0xBDC4, 0xC2DD}, //10378 #HANGUL SYLLABLE SIOS I KIYEOK + {0xBDC5, 0xC2E0}, //10379 #HANGUL SYLLABLE SIOS I NIEUN + {0xBDC6, 0xC2E3}, //10380 #HANGUL SYLLABLE SIOS I TIKEUT + {0xBDC7, 0xC2E4}, //10381 #HANGUL SYLLABLE SIOS I RIEUL + {0xBDC8, 0xC2EB}, //10382 #HANGUL SYLLABLE SIOS I RIEULHIEUH + {0xBDC9, 0xC2EC}, //10383 #HANGUL SYLLABLE SIOS I MIEUM + {0xBDCA, 0xC2ED}, //10384 #HANGUL SYLLABLE SIOS I PIEUP + {0xBDCB, 0xC2EF}, //10385 #HANGUL SYLLABLE SIOS I SIOS + {0xBDCC, 0xC2F1}, //10386 #HANGUL SYLLABLE SIOS I IEUNG + {0xBDCD, 0xC2F6}, //10387 #HANGUL SYLLABLE SIOS I PHIEUPH + {0xBDCE, 0xC2F8}, //10388 #HANGUL SYLLABLE SSANGSIOS A + {0xBDCF, 0xC2F9}, //10389 #HANGUL SYLLABLE SSANGSIOS A KIYEOK + {0xBDD0, 0xC2FB}, //10390 #HANGUL SYLLABLE SSANGSIOS A KIYEOKSIOS + {0xBDD1, 0xC2FC}, //10391 #HANGUL SYLLABLE SSANGSIOS A NIEUN + {0xBDD2, 0xC300}, //10392 #HANGUL SYLLABLE SSANGSIOS A RIEUL + {0xBDD3, 0xC308}, //10393 #HANGUL SYLLABLE SSANGSIOS A MIEUM + {0xBDD4, 0xC309}, //10394 #HANGUL SYLLABLE SSANGSIOS A PIEUP + {0xBDD5, 0xC30C}, //10395 #HANGUL SYLLABLE SSANGSIOS A SSANGSIOS + {0xBDD6, 0xC30D}, //10396 #HANGUL SYLLABLE SSANGSIOS A IEUNG + {0xBDD7, 0xC313}, //10397 #HANGUL SYLLABLE SSANGSIOS A HIEUH + {0xBDD8, 0xC314}, //10398 #HANGUL SYLLABLE SSANGSIOS AE + {0xBDD9, 0xC315}, //10399 #HANGUL SYLLABLE SSANGSIOS AE KIYEOK + {0xBDDA, 0xC318}, //10400 #HANGUL SYLLABLE SSANGSIOS AE NIEUN + {0xBDDB, 0xC31C}, //10401 #HANGUL SYLLABLE SSANGSIOS AE RIEUL + {0xBDDC, 0xC324}, //10402 #HANGUL SYLLABLE SSANGSIOS AE MIEUM + {0xBDDD, 0xC325}, //10403 #HANGUL SYLLABLE SSANGSIOS AE PIEUP + {0xBDDE, 0xC328}, //10404 #HANGUL SYLLABLE SSANGSIOS AE SSANGSIOS + {0xBDDF, 0xC329}, //10405 #HANGUL SYLLABLE SSANGSIOS AE IEUNG + {0xBDE0, 0xC345}, //10406 #HANGUL SYLLABLE SSANGSIOS YA IEUNG + {0xBDE1, 0xC368}, //10407 #HANGUL SYLLABLE SSANGSIOS EO + {0xBDE2, 0xC369}, //10408 #HANGUL SYLLABLE SSANGSIOS EO KIYEOK + {0xBDE3, 0xC36C}, //10409 #HANGUL SYLLABLE SSANGSIOS EO NIEUN + {0xBDE4, 0xC370}, //10410 #HANGUL SYLLABLE SSANGSIOS EO RIEUL + {0xBDE5, 0xC372}, //10411 #HANGUL SYLLABLE SSANGSIOS EO RIEULMIEUM + {0xBDE6, 0xC378}, //10412 #HANGUL SYLLABLE SSANGSIOS EO MIEUM + {0xBDE7, 0xC379}, //10413 #HANGUL SYLLABLE SSANGSIOS EO PIEUP + {0xBDE8, 0xC37C}, //10414 #HANGUL SYLLABLE SSANGSIOS EO SSANGSIOS + {0xBDE9, 0xC37D}, //10415 #HANGUL SYLLABLE SSANGSIOS EO IEUNG + {0xBDEA, 0xC384}, //10416 #HANGUL SYLLABLE SSANGSIOS E + {0xBDEB, 0xC388}, //10417 #HANGUL SYLLABLE SSANGSIOS E NIEUN + {0xBDEC, 0xC38C}, //10418 #HANGUL SYLLABLE SSANGSIOS E RIEUL + {0xBDED, 0xC3C0}, //10419 #HANGUL SYLLABLE SSANGSIOS YE NIEUN + {0xBDEE, 0xC3D8}, //10420 #HANGUL SYLLABLE SSANGSIOS O + {0xBDEF, 0xC3D9}, //10421 #HANGUL SYLLABLE SSANGSIOS O KIYEOK + {0xBDF0, 0xC3DC}, //10422 #HANGUL SYLLABLE SSANGSIOS O NIEUN + {0xBDF1, 0xC3DF}, //10423 #HANGUL SYLLABLE SSANGSIOS O TIKEUT + {0xBDF2, 0xC3E0}, //10424 #HANGUL SYLLABLE SSANGSIOS O RIEUL + {0xBDF3, 0xC3E2}, //10425 #HANGUL SYLLABLE SSANGSIOS O RIEULMIEUM + {0xBDF4, 0xC3E8}, //10426 #HANGUL SYLLABLE SSANGSIOS O MIEUM + {0xBDF5, 0xC3E9}, //10427 #HANGUL SYLLABLE SSANGSIOS O PIEUP + {0xBDF6, 0xC3ED}, //10428 #HANGUL SYLLABLE SSANGSIOS O IEUNG + {0xBDF7, 0xC3F4}, //10429 #HANGUL SYLLABLE SSANGSIOS WA + {0xBDF8, 0xC3F5}, //10430 #HANGUL SYLLABLE SSANGSIOS WA KIYEOK + {0xBDF9, 0xC3F8}, //10431 #HANGUL SYLLABLE SSANGSIOS WA NIEUN + {0xBDFA, 0xC408}, //10432 #HANGUL SYLLABLE SSANGSIOS WA SSANGSIOS + {0xBDFB, 0xC410}, //10433 #HANGUL SYLLABLE SSANGSIOS WAE + {0xBDFC, 0xC424}, //10434 #HANGUL SYLLABLE SSANGSIOS WAE SSANGSIOS + {0xBDFD, 0xC42C}, //10435 #HANGUL SYLLABLE SSANGSIOS OE + {0xBDFE, 0xC430}, //10436 #HANGUL SYLLABLE SSANGSIOS OE NIEUN + {0xBE41, 0xD438}, //10437 #HANGUL SYLLABLE PHIEUPH WAE SSANGSIOS + {0xBE42, 0xD439}, //10438 #HANGUL SYLLABLE PHIEUPH WAE IEUNG + {0xBE43, 0xD43A}, //10439 #HANGUL SYLLABLE PHIEUPH WAE CIEUC + {0xBE44, 0xD43B}, //10440 #HANGUL SYLLABLE PHIEUPH WAE CHIEUCH + {0xBE45, 0xD43C}, //10441 #HANGUL SYLLABLE PHIEUPH WAE KHIEUKH + {0xBE46, 0xD43D}, //10442 #HANGUL SYLLABLE PHIEUPH WAE THIEUTH + {0xBE47, 0xD43E}, //10443 #HANGUL SYLLABLE PHIEUPH WAE PHIEUPH + {0xBE48, 0xD43F}, //10444 #HANGUL SYLLABLE PHIEUPH WAE HIEUH + {0xBE49, 0xD441}, //10445 #HANGUL SYLLABLE PHIEUPH OE KIYEOK + {0xBE4A, 0xD442}, //10446 #HANGUL SYLLABLE PHIEUPH OE SSANGKIYEOK + {0xBE4B, 0xD443}, //10447 #HANGUL SYLLABLE PHIEUPH OE KIYEOKSIOS + {0xBE4C, 0xD445}, //10448 #HANGUL SYLLABLE PHIEUPH OE NIEUNCIEUC + {0xBE4D, 0xD446}, //10449 #HANGUL SYLLABLE PHIEUPH OE NIEUNHIEUH + {0xBE4E, 0xD447}, //10450 #HANGUL SYLLABLE PHIEUPH OE TIKEUT + {0xBE4F, 0xD448}, //10451 #HANGUL SYLLABLE PHIEUPH OE RIEUL + {0xBE50, 0xD449}, //10452 #HANGUL SYLLABLE PHIEUPH OE RIEULKIYEOK + {0xBE51, 0xD44A}, //10453 #HANGUL SYLLABLE PHIEUPH OE RIEULMIEUM + {0xBE52, 0xD44B}, //10454 #HANGUL SYLLABLE PHIEUPH OE RIEULPIEUP + {0xBE53, 0xD44C}, //10455 #HANGUL SYLLABLE PHIEUPH OE RIEULSIOS + {0xBE54, 0xD44D}, //10456 #HANGUL SYLLABLE PHIEUPH OE RIEULTHIEUTH + {0xBE55, 0xD44E}, //10457 #HANGUL SYLLABLE PHIEUPH OE RIEULPHIEUPH + {0xBE56, 0xD44F}, //10458 #HANGUL SYLLABLE PHIEUPH OE RIEULHIEUH + {0xBE57, 0xD450}, //10459 #HANGUL SYLLABLE PHIEUPH OE MIEUM + {0xBE58, 0xD451}, //10460 #HANGUL SYLLABLE PHIEUPH OE PIEUP + {0xBE59, 0xD452}, //10461 #HANGUL SYLLABLE PHIEUPH OE PIEUPSIOS + {0xBE5A, 0xD453}, //10462 #HANGUL SYLLABLE PHIEUPH OE SIOS + {0xBE61, 0xD454}, //10463 #HANGUL SYLLABLE PHIEUPH OE SSANGSIOS + {0xBE62, 0xD455}, //10464 #HANGUL SYLLABLE PHIEUPH OE IEUNG + {0xBE63, 0xD456}, //10465 #HANGUL SYLLABLE PHIEUPH OE CIEUC + {0xBE64, 0xD457}, //10466 #HANGUL SYLLABLE PHIEUPH OE CHIEUCH + {0xBE65, 0xD458}, //10467 #HANGUL SYLLABLE PHIEUPH OE KHIEUKH + {0xBE66, 0xD459}, //10468 #HANGUL SYLLABLE PHIEUPH OE THIEUTH + {0xBE67, 0xD45A}, //10469 #HANGUL SYLLABLE PHIEUPH OE PHIEUPH + {0xBE68, 0xD45B}, //10470 #HANGUL SYLLABLE PHIEUPH OE HIEUH + {0xBE69, 0xD45D}, //10471 #HANGUL SYLLABLE PHIEUPH YO KIYEOK + {0xBE6A, 0xD45E}, //10472 #HANGUL SYLLABLE PHIEUPH YO SSANGKIYEOK + {0xBE6B, 0xD45F}, //10473 #HANGUL SYLLABLE PHIEUPH YO KIYEOKSIOS + {0xBE6C, 0xD461}, //10474 #HANGUL SYLLABLE PHIEUPH YO NIEUNCIEUC + {0xBE6D, 0xD462}, //10475 #HANGUL SYLLABLE PHIEUPH YO NIEUNHIEUH + {0xBE6E, 0xD463}, //10476 #HANGUL SYLLABLE PHIEUPH YO TIKEUT + {0xBE6F, 0xD465}, //10477 #HANGUL SYLLABLE PHIEUPH YO RIEULKIYEOK + {0xBE70, 0xD466}, //10478 #HANGUL SYLLABLE PHIEUPH YO RIEULMIEUM + {0xBE71, 0xD467}, //10479 #HANGUL SYLLABLE PHIEUPH YO RIEULPIEUP + {0xBE72, 0xD468}, //10480 #HANGUL SYLLABLE PHIEUPH YO RIEULSIOS + {0xBE73, 0xD469}, //10481 #HANGUL SYLLABLE PHIEUPH YO RIEULTHIEUTH + {0xBE74, 0xD46A}, //10482 #HANGUL SYLLABLE PHIEUPH YO RIEULPHIEUPH + {0xBE75, 0xD46B}, //10483 #HANGUL SYLLABLE PHIEUPH YO RIEULHIEUH + {0xBE76, 0xD46C}, //10484 #HANGUL SYLLABLE PHIEUPH YO MIEUM + {0xBE77, 0xD46E}, //10485 #HANGUL SYLLABLE PHIEUPH YO PIEUPSIOS + {0xBE78, 0xD470}, //10486 #HANGUL SYLLABLE PHIEUPH YO SSANGSIOS + {0xBE79, 0xD471}, //10487 #HANGUL SYLLABLE PHIEUPH YO IEUNG + {0xBE7A, 0xD472}, //10488 #HANGUL SYLLABLE PHIEUPH YO CIEUC + {0xBE81, 0xD473}, //10489 #HANGUL SYLLABLE PHIEUPH YO CHIEUCH + {0xBE82, 0xD474}, //10490 #HANGUL SYLLABLE PHIEUPH YO KHIEUKH + {0xBE83, 0xD475}, //10491 #HANGUL SYLLABLE PHIEUPH YO THIEUTH + {0xBE84, 0xD476}, //10492 #HANGUL SYLLABLE PHIEUPH YO PHIEUPH + {0xBE85, 0xD477}, //10493 #HANGUL SYLLABLE PHIEUPH YO HIEUH + {0xBE86, 0xD47A}, //10494 #HANGUL SYLLABLE PHIEUPH U SSANGKIYEOK + {0xBE87, 0xD47B}, //10495 #HANGUL SYLLABLE PHIEUPH U KIYEOKSIOS + {0xBE88, 0xD47D}, //10496 #HANGUL SYLLABLE PHIEUPH U NIEUNCIEUC + {0xBE89, 0xD47E}, //10497 #HANGUL SYLLABLE PHIEUPH U NIEUNHIEUH + {0xBE8A, 0xD481}, //10498 #HANGUL SYLLABLE PHIEUPH U RIEULKIYEOK + {0xBE8B, 0xD483}, //10499 #HANGUL SYLLABLE PHIEUPH U RIEULPIEUP + {0xBE8C, 0xD484}, //10500 #HANGUL SYLLABLE PHIEUPH U RIEULSIOS + {0xBE8D, 0xD485}, //10501 #HANGUL SYLLABLE PHIEUPH U RIEULTHIEUTH + {0xBE8E, 0xD486}, //10502 #HANGUL SYLLABLE PHIEUPH U RIEULPHIEUPH + {0xBE8F, 0xD487}, //10503 #HANGUL SYLLABLE PHIEUPH U RIEULHIEUH + {0xBE90, 0xD48A}, //10504 #HANGUL SYLLABLE PHIEUPH U PIEUPSIOS + {0xBE91, 0xD48C}, //10505 #HANGUL SYLLABLE PHIEUPH U SSANGSIOS + {0xBE92, 0xD48E}, //10506 #HANGUL SYLLABLE PHIEUPH U CIEUC + {0xBE93, 0xD48F}, //10507 #HANGUL SYLLABLE PHIEUPH U CHIEUCH + {0xBE94, 0xD490}, //10508 #HANGUL SYLLABLE PHIEUPH U KHIEUKH + {0xBE95, 0xD491}, //10509 #HANGUL SYLLABLE PHIEUPH U THIEUTH + {0xBE96, 0xD492}, //10510 #HANGUL SYLLABLE PHIEUPH U PHIEUPH + {0xBE97, 0xD493}, //10511 #HANGUL SYLLABLE PHIEUPH U HIEUH + {0xBE98, 0xD495}, //10512 #HANGUL SYLLABLE PHIEUPH WEO KIYEOK + {0xBE99, 0xD496}, //10513 #HANGUL SYLLABLE PHIEUPH WEO SSANGKIYEOK + {0xBE9A, 0xD497}, //10514 #HANGUL SYLLABLE PHIEUPH WEO KIYEOKSIOS + {0xBE9B, 0xD498}, //10515 #HANGUL SYLLABLE PHIEUPH WEO NIEUN + {0xBE9C, 0xD499}, //10516 #HANGUL SYLLABLE PHIEUPH WEO NIEUNCIEUC + {0xBE9D, 0xD49A}, //10517 #HANGUL SYLLABLE PHIEUPH WEO NIEUNHIEUH + {0xBE9E, 0xD49B}, //10518 #HANGUL SYLLABLE PHIEUPH WEO TIKEUT + {0xBE9F, 0xD49C}, //10519 #HANGUL SYLLABLE PHIEUPH WEO RIEUL + {0xBEA0, 0xD49D}, //10520 #HANGUL SYLLABLE PHIEUPH WEO RIEULKIYEOK + {0xBEA1, 0xC434}, //10521 #HANGUL SYLLABLE SSANGSIOS OE RIEUL + {0xBEA2, 0xC43C}, //10522 #HANGUL SYLLABLE SSANGSIOS OE MIEUM + {0xBEA3, 0xC43D}, //10523 #HANGUL SYLLABLE SSANGSIOS OE PIEUP + {0xBEA4, 0xC448}, //10524 #HANGUL SYLLABLE SSANGSIOS YO + {0xBEA5, 0xC464}, //10525 #HANGUL SYLLABLE SSANGSIOS U + {0xBEA6, 0xC465}, //10526 #HANGUL SYLLABLE SSANGSIOS U KIYEOK + {0xBEA7, 0xC468}, //10527 #HANGUL SYLLABLE SSANGSIOS U NIEUN + {0xBEA8, 0xC46C}, //10528 #HANGUL SYLLABLE SSANGSIOS U RIEUL + {0xBEA9, 0xC474}, //10529 #HANGUL SYLLABLE SSANGSIOS U MIEUM + {0xBEAA, 0xC475}, //10530 #HANGUL SYLLABLE SSANGSIOS U PIEUP + {0xBEAB, 0xC479}, //10531 #HANGUL SYLLABLE SSANGSIOS U IEUNG + {0xBEAC, 0xC480}, //10532 #HANGUL SYLLABLE SSANGSIOS WEO + {0xBEAD, 0xC494}, //10533 #HANGUL SYLLABLE SSANGSIOS WEO SSANGSIOS + {0xBEAE, 0xC49C}, //10534 #HANGUL SYLLABLE SSANGSIOS WE + {0xBEAF, 0xC4B8}, //10535 #HANGUL SYLLABLE SSANGSIOS WI + {0xBEB0, 0xC4BC}, //10536 #HANGUL SYLLABLE SSANGSIOS WI NIEUN + {0xBEB1, 0xC4E9}, //10537 #HANGUL SYLLABLE SSANGSIOS YU IEUNG + {0xBEB2, 0xC4F0}, //10538 #HANGUL SYLLABLE SSANGSIOS EU + {0xBEB3, 0xC4F1}, //10539 #HANGUL SYLLABLE SSANGSIOS EU KIYEOK + {0xBEB4, 0xC4F4}, //10540 #HANGUL SYLLABLE SSANGSIOS EU NIEUN + {0xBEB5, 0xC4F8}, //10541 #HANGUL SYLLABLE SSANGSIOS EU RIEUL + {0xBEB6, 0xC4FA}, //10542 #HANGUL SYLLABLE SSANGSIOS EU RIEULMIEUM + {0xBEB7, 0xC4FF}, //10543 #HANGUL SYLLABLE SSANGSIOS EU RIEULHIEUH + {0xBEB8, 0xC500}, //10544 #HANGUL SYLLABLE SSANGSIOS EU MIEUM + {0xBEB9, 0xC501}, //10545 #HANGUL SYLLABLE SSANGSIOS EU PIEUP + {0xBEBA, 0xC50C}, //10546 #HANGUL SYLLABLE SSANGSIOS YI + {0xBEBB, 0xC510}, //10547 #HANGUL SYLLABLE SSANGSIOS YI NIEUN + {0xBEBC, 0xC514}, //10548 #HANGUL SYLLABLE SSANGSIOS YI RIEUL + {0xBEBD, 0xC51C}, //10549 #HANGUL SYLLABLE SSANGSIOS YI MIEUM + {0xBEBE, 0xC528}, //10550 #HANGUL SYLLABLE SSANGSIOS I + {0xBEBF, 0xC529}, //10551 #HANGUL SYLLABLE SSANGSIOS I KIYEOK + {0xBEC0, 0xC52C}, //10552 #HANGUL SYLLABLE SSANGSIOS I NIEUN + {0xBEC1, 0xC530}, //10553 #HANGUL SYLLABLE SSANGSIOS I RIEUL + {0xBEC2, 0xC538}, //10554 #HANGUL SYLLABLE SSANGSIOS I MIEUM + {0xBEC3, 0xC539}, //10555 #HANGUL SYLLABLE SSANGSIOS I PIEUP + {0xBEC4, 0xC53B}, //10556 #HANGUL SYLLABLE SSANGSIOS I SIOS + {0xBEC5, 0xC53D}, //10557 #HANGUL SYLLABLE SSANGSIOS I IEUNG + {0xBEC6, 0xC544}, //10558 #HANGUL SYLLABLE IEUNG A + {0xBEC7, 0xC545}, //10559 #HANGUL SYLLABLE IEUNG A KIYEOK + {0xBEC8, 0xC548}, //10560 #HANGUL SYLLABLE IEUNG A NIEUN + {0xBEC9, 0xC549}, //10561 #HANGUL SYLLABLE IEUNG A NIEUNCIEUC + {0xBECA, 0xC54A}, //10562 #HANGUL SYLLABLE IEUNG A NIEUNHIEUH + {0xBECB, 0xC54C}, //10563 #HANGUL SYLLABLE IEUNG A RIEUL + {0xBECC, 0xC54D}, //10564 #HANGUL SYLLABLE IEUNG A RIEULKIYEOK + {0xBECD, 0xC54E}, //10565 #HANGUL SYLLABLE IEUNG A RIEULMIEUM + {0xBECE, 0xC553}, //10566 #HANGUL SYLLABLE IEUNG A RIEULHIEUH + {0xBECF, 0xC554}, //10567 #HANGUL SYLLABLE IEUNG A MIEUM + {0xBED0, 0xC555}, //10568 #HANGUL SYLLABLE IEUNG A PIEUP + {0xBED1, 0xC557}, //10569 #HANGUL SYLLABLE IEUNG A SIOS + {0xBED2, 0xC558}, //10570 #HANGUL SYLLABLE IEUNG A SSANGSIOS + {0xBED3, 0xC559}, //10571 #HANGUL SYLLABLE IEUNG A IEUNG + {0xBED4, 0xC55D}, //10572 #HANGUL SYLLABLE IEUNG A THIEUTH + {0xBED5, 0xC55E}, //10573 #HANGUL SYLLABLE IEUNG A PHIEUPH + {0xBED6, 0xC560}, //10574 #HANGUL SYLLABLE IEUNG AE + {0xBED7, 0xC561}, //10575 #HANGUL SYLLABLE IEUNG AE KIYEOK + {0xBED8, 0xC564}, //10576 #HANGUL SYLLABLE IEUNG AE NIEUN + {0xBED9, 0xC568}, //10577 #HANGUL SYLLABLE IEUNG AE RIEUL + {0xBEDA, 0xC570}, //10578 #HANGUL SYLLABLE IEUNG AE MIEUM + {0xBEDB, 0xC571}, //10579 #HANGUL SYLLABLE IEUNG AE PIEUP + {0xBEDC, 0xC573}, //10580 #HANGUL SYLLABLE IEUNG AE SIOS + {0xBEDD, 0xC574}, //10581 #HANGUL SYLLABLE IEUNG AE SSANGSIOS + {0xBEDE, 0xC575}, //10582 #HANGUL SYLLABLE IEUNG AE IEUNG + {0xBEDF, 0xC57C}, //10583 #HANGUL SYLLABLE IEUNG YA + {0xBEE0, 0xC57D}, //10584 #HANGUL SYLLABLE IEUNG YA KIYEOK + {0xBEE1, 0xC580}, //10585 #HANGUL SYLLABLE IEUNG YA NIEUN + {0xBEE2, 0xC584}, //10586 #HANGUL SYLLABLE IEUNG YA RIEUL + {0xBEE3, 0xC587}, //10587 #HANGUL SYLLABLE IEUNG YA RIEULPIEUP + {0xBEE4, 0xC58C}, //10588 #HANGUL SYLLABLE IEUNG YA MIEUM + {0xBEE5, 0xC58D}, //10589 #HANGUL SYLLABLE IEUNG YA PIEUP + {0xBEE6, 0xC58F}, //10590 #HANGUL SYLLABLE IEUNG YA SIOS + {0xBEE7, 0xC591}, //10591 #HANGUL SYLLABLE IEUNG YA IEUNG + {0xBEE8, 0xC595}, //10592 #HANGUL SYLLABLE IEUNG YA THIEUTH + {0xBEE9, 0xC597}, //10593 #HANGUL SYLLABLE IEUNG YA HIEUH + {0xBEEA, 0xC598}, //10594 #HANGUL SYLLABLE IEUNG YAE + {0xBEEB, 0xC59C}, //10595 #HANGUL SYLLABLE IEUNG YAE NIEUN + {0xBEEC, 0xC5A0}, //10596 #HANGUL SYLLABLE IEUNG YAE RIEUL + {0xBEED, 0xC5A9}, //10597 #HANGUL SYLLABLE IEUNG YAE PIEUP + {0xBEEE, 0xC5B4}, //10598 #HANGUL SYLLABLE IEUNG EO + {0xBEEF, 0xC5B5}, //10599 #HANGUL SYLLABLE IEUNG EO KIYEOK + {0xBEF0, 0xC5B8}, //10600 #HANGUL SYLLABLE IEUNG EO NIEUN + {0xBEF1, 0xC5B9}, //10601 #HANGUL SYLLABLE IEUNG EO NIEUNCIEUC + {0xBEF2, 0xC5BB}, //10602 #HANGUL SYLLABLE IEUNG EO TIKEUT + {0xBEF3, 0xC5BC}, //10603 #HANGUL SYLLABLE IEUNG EO RIEUL + {0xBEF4, 0xC5BD}, //10604 #HANGUL SYLLABLE IEUNG EO RIEULKIYEOK + {0xBEF5, 0xC5BE}, //10605 #HANGUL SYLLABLE IEUNG EO RIEULMIEUM + {0xBEF6, 0xC5C4}, //10606 #HANGUL SYLLABLE IEUNG EO MIEUM + {0xBEF7, 0xC5C5}, //10607 #HANGUL SYLLABLE IEUNG EO PIEUP + {0xBEF8, 0xC5C6}, //10608 #HANGUL SYLLABLE IEUNG EO PIEUPSIOS + {0xBEF9, 0xC5C7}, //10609 #HANGUL SYLLABLE IEUNG EO SIOS + {0xBEFA, 0xC5C8}, //10610 #HANGUL SYLLABLE IEUNG EO SSANGSIOS + {0xBEFB, 0xC5C9}, //10611 #HANGUL SYLLABLE IEUNG EO IEUNG + {0xBEFC, 0xC5CA}, //10612 #HANGUL SYLLABLE IEUNG EO CIEUC + {0xBEFD, 0xC5CC}, //10613 #HANGUL SYLLABLE IEUNG EO KHIEUKH + {0xBEFE, 0xC5CE}, //10614 #HANGUL SYLLABLE IEUNG EO PHIEUPH + {0xBF41, 0xD49E}, //10615 #HANGUL SYLLABLE PHIEUPH WEO RIEULMIEUM + {0xBF42, 0xD49F}, //10616 #HANGUL SYLLABLE PHIEUPH WEO RIEULPIEUP + {0xBF43, 0xD4A0}, //10617 #HANGUL SYLLABLE PHIEUPH WEO RIEULSIOS + {0xBF44, 0xD4A1}, //10618 #HANGUL SYLLABLE PHIEUPH WEO RIEULTHIEUTH + {0xBF45, 0xD4A2}, //10619 #HANGUL SYLLABLE PHIEUPH WEO RIEULPHIEUPH + {0xBF46, 0xD4A3}, //10620 #HANGUL SYLLABLE PHIEUPH WEO RIEULHIEUH + {0xBF47, 0xD4A4}, //10621 #HANGUL SYLLABLE PHIEUPH WEO MIEUM + {0xBF48, 0xD4A5}, //10622 #HANGUL SYLLABLE PHIEUPH WEO PIEUP + {0xBF49, 0xD4A6}, //10623 #HANGUL SYLLABLE PHIEUPH WEO PIEUPSIOS + {0xBF4A, 0xD4A7}, //10624 #HANGUL SYLLABLE PHIEUPH WEO SIOS + {0xBF4B, 0xD4A8}, //10625 #HANGUL SYLLABLE PHIEUPH WEO SSANGSIOS + {0xBF4C, 0xD4AA}, //10626 #HANGUL SYLLABLE PHIEUPH WEO CIEUC + {0xBF4D, 0xD4AB}, //10627 #HANGUL SYLLABLE PHIEUPH WEO CHIEUCH + {0xBF4E, 0xD4AC}, //10628 #HANGUL SYLLABLE PHIEUPH WEO KHIEUKH + {0xBF4F, 0xD4AD}, //10629 #HANGUL SYLLABLE PHIEUPH WEO THIEUTH + {0xBF50, 0xD4AE}, //10630 #HANGUL SYLLABLE PHIEUPH WEO PHIEUPH + {0xBF51, 0xD4AF}, //10631 #HANGUL SYLLABLE PHIEUPH WEO HIEUH + {0xBF52, 0xD4B0}, //10632 #HANGUL SYLLABLE PHIEUPH WE + {0xBF53, 0xD4B1}, //10633 #HANGUL SYLLABLE PHIEUPH WE KIYEOK + {0xBF54, 0xD4B2}, //10634 #HANGUL SYLLABLE PHIEUPH WE SSANGKIYEOK + {0xBF55, 0xD4B3}, //10635 #HANGUL SYLLABLE PHIEUPH WE KIYEOKSIOS + {0xBF56, 0xD4B4}, //10636 #HANGUL SYLLABLE PHIEUPH WE NIEUN + {0xBF57, 0xD4B5}, //10637 #HANGUL SYLLABLE PHIEUPH WE NIEUNCIEUC + {0xBF58, 0xD4B6}, //10638 #HANGUL SYLLABLE PHIEUPH WE NIEUNHIEUH + {0xBF59, 0xD4B7}, //10639 #HANGUL SYLLABLE PHIEUPH WE TIKEUT + {0xBF5A, 0xD4B8}, //10640 #HANGUL SYLLABLE PHIEUPH WE RIEUL + {0xBF61, 0xD4B9}, //10641 #HANGUL SYLLABLE PHIEUPH WE RIEULKIYEOK + {0xBF62, 0xD4BA}, //10642 #HANGUL SYLLABLE PHIEUPH WE RIEULMIEUM + {0xBF63, 0xD4BB}, //10643 #HANGUL SYLLABLE PHIEUPH WE RIEULPIEUP + {0xBF64, 0xD4BC}, //10644 #HANGUL SYLLABLE PHIEUPH WE RIEULSIOS + {0xBF65, 0xD4BD}, //10645 #HANGUL SYLLABLE PHIEUPH WE RIEULTHIEUTH + {0xBF66, 0xD4BE}, //10646 #HANGUL SYLLABLE PHIEUPH WE RIEULPHIEUPH + {0xBF67, 0xD4BF}, //10647 #HANGUL SYLLABLE PHIEUPH WE RIEULHIEUH + {0xBF68, 0xD4C0}, //10648 #HANGUL SYLLABLE PHIEUPH WE MIEUM + {0xBF69, 0xD4C1}, //10649 #HANGUL SYLLABLE PHIEUPH WE PIEUP + {0xBF6A, 0xD4C2}, //10650 #HANGUL SYLLABLE PHIEUPH WE PIEUPSIOS + {0xBF6B, 0xD4C3}, //10651 #HANGUL SYLLABLE PHIEUPH WE SIOS + {0xBF6C, 0xD4C4}, //10652 #HANGUL SYLLABLE PHIEUPH WE SSANGSIOS + {0xBF6D, 0xD4C5}, //10653 #HANGUL SYLLABLE PHIEUPH WE IEUNG + {0xBF6E, 0xD4C6}, //10654 #HANGUL SYLLABLE PHIEUPH WE CIEUC + {0xBF6F, 0xD4C7}, //10655 #HANGUL SYLLABLE PHIEUPH WE CHIEUCH + {0xBF70, 0xD4C8}, //10656 #HANGUL SYLLABLE PHIEUPH WE KHIEUKH + {0xBF71, 0xD4C9}, //10657 #HANGUL SYLLABLE PHIEUPH WE THIEUTH + {0xBF72, 0xD4CA}, //10658 #HANGUL SYLLABLE PHIEUPH WE PHIEUPH + {0xBF73, 0xD4CB}, //10659 #HANGUL SYLLABLE PHIEUPH WE HIEUH + {0xBF74, 0xD4CD}, //10660 #HANGUL SYLLABLE PHIEUPH WI KIYEOK + {0xBF75, 0xD4CE}, //10661 #HANGUL SYLLABLE PHIEUPH WI SSANGKIYEOK + {0xBF76, 0xD4CF}, //10662 #HANGUL SYLLABLE PHIEUPH WI KIYEOKSIOS + {0xBF77, 0xD4D1}, //10663 #HANGUL SYLLABLE PHIEUPH WI NIEUNCIEUC + {0xBF78, 0xD4D2}, //10664 #HANGUL SYLLABLE PHIEUPH WI NIEUNHIEUH + {0xBF79, 0xD4D3}, //10665 #HANGUL SYLLABLE PHIEUPH WI TIKEUT + {0xBF7A, 0xD4D5}, //10666 #HANGUL SYLLABLE PHIEUPH WI RIEULKIYEOK + {0xBF81, 0xD4D6}, //10667 #HANGUL SYLLABLE PHIEUPH WI RIEULMIEUM + {0xBF82, 0xD4D7}, //10668 #HANGUL SYLLABLE PHIEUPH WI RIEULPIEUP + {0xBF83, 0xD4D8}, //10669 #HANGUL SYLLABLE PHIEUPH WI RIEULSIOS + {0xBF84, 0xD4D9}, //10670 #HANGUL SYLLABLE PHIEUPH WI RIEULTHIEUTH + {0xBF85, 0xD4DA}, //10671 #HANGUL SYLLABLE PHIEUPH WI RIEULPHIEUPH + {0xBF86, 0xD4DB}, //10672 #HANGUL SYLLABLE PHIEUPH WI RIEULHIEUH + {0xBF87, 0xD4DD}, //10673 #HANGUL SYLLABLE PHIEUPH WI PIEUP + {0xBF88, 0xD4DE}, //10674 #HANGUL SYLLABLE PHIEUPH WI PIEUPSIOS + {0xBF89, 0xD4E0}, //10675 #HANGUL SYLLABLE PHIEUPH WI SSANGSIOS + {0xBF8A, 0xD4E1}, //10676 #HANGUL SYLLABLE PHIEUPH WI IEUNG + {0xBF8B, 0xD4E2}, //10677 #HANGUL SYLLABLE PHIEUPH WI CIEUC + {0xBF8C, 0xD4E3}, //10678 #HANGUL SYLLABLE PHIEUPH WI CHIEUCH + {0xBF8D, 0xD4E4}, //10679 #HANGUL SYLLABLE PHIEUPH WI KHIEUKH + {0xBF8E, 0xD4E5}, //10680 #HANGUL SYLLABLE PHIEUPH WI THIEUTH + {0xBF8F, 0xD4E6}, //10681 #HANGUL SYLLABLE PHIEUPH WI PHIEUPH + {0xBF90, 0xD4E7}, //10682 #HANGUL SYLLABLE PHIEUPH WI HIEUH + {0xBF91, 0xD4E9}, //10683 #HANGUL SYLLABLE PHIEUPH YU KIYEOK + {0xBF92, 0xD4EA}, //10684 #HANGUL SYLLABLE PHIEUPH YU SSANGKIYEOK + {0xBF93, 0xD4EB}, //10685 #HANGUL SYLLABLE PHIEUPH YU KIYEOKSIOS + {0xBF94, 0xD4ED}, //10686 #HANGUL SYLLABLE PHIEUPH YU NIEUNCIEUC + {0xBF95, 0xD4EE}, //10687 #HANGUL SYLLABLE PHIEUPH YU NIEUNHIEUH + {0xBF96, 0xD4EF}, //10688 #HANGUL SYLLABLE PHIEUPH YU TIKEUT + {0xBF97, 0xD4F1}, //10689 #HANGUL SYLLABLE PHIEUPH YU RIEULKIYEOK + {0xBF98, 0xD4F2}, //10690 #HANGUL SYLLABLE PHIEUPH YU RIEULMIEUM + {0xBF99, 0xD4F3}, //10691 #HANGUL SYLLABLE PHIEUPH YU RIEULPIEUP + {0xBF9A, 0xD4F4}, //10692 #HANGUL SYLLABLE PHIEUPH YU RIEULSIOS + {0xBF9B, 0xD4F5}, //10693 #HANGUL SYLLABLE PHIEUPH YU RIEULTHIEUTH + {0xBF9C, 0xD4F6}, //10694 #HANGUL SYLLABLE PHIEUPH YU RIEULPHIEUPH + {0xBF9D, 0xD4F7}, //10695 #HANGUL SYLLABLE PHIEUPH YU RIEULHIEUH + {0xBF9E, 0xD4F9}, //10696 #HANGUL SYLLABLE PHIEUPH YU PIEUP + {0xBF9F, 0xD4FA}, //10697 #HANGUL SYLLABLE PHIEUPH YU PIEUPSIOS + {0xBFA0, 0xD4FC}, //10698 #HANGUL SYLLABLE PHIEUPH YU SSANGSIOS + {0xBFA1, 0xC5D0}, //10699 #HANGUL SYLLABLE IEUNG E + {0xBFA2, 0xC5D1}, //10700 #HANGUL SYLLABLE IEUNG E KIYEOK + {0xBFA3, 0xC5D4}, //10701 #HANGUL SYLLABLE IEUNG E NIEUN + {0xBFA4, 0xC5D8}, //10702 #HANGUL SYLLABLE IEUNG E RIEUL + {0xBFA5, 0xC5E0}, //10703 #HANGUL SYLLABLE IEUNG E MIEUM + {0xBFA6, 0xC5E1}, //10704 #HANGUL SYLLABLE IEUNG E PIEUP + {0xBFA7, 0xC5E3}, //10705 #HANGUL SYLLABLE IEUNG E SIOS + {0xBFA8, 0xC5E5}, //10706 #HANGUL SYLLABLE IEUNG E IEUNG + {0xBFA9, 0xC5EC}, //10707 #HANGUL SYLLABLE IEUNG YEO + {0xBFAA, 0xC5ED}, //10708 #HANGUL SYLLABLE IEUNG YEO KIYEOK + {0xBFAB, 0xC5EE}, //10709 #HANGUL SYLLABLE IEUNG YEO SSANGKIYEOK + {0xBFAC, 0xC5F0}, //10710 #HANGUL SYLLABLE IEUNG YEO NIEUN + {0xBFAD, 0xC5F4}, //10711 #HANGUL SYLLABLE IEUNG YEO RIEUL + {0xBFAE, 0xC5F6}, //10712 #HANGUL SYLLABLE IEUNG YEO RIEULMIEUM + {0xBFAF, 0xC5F7}, //10713 #HANGUL SYLLABLE IEUNG YEO RIEULPIEUP + {0xBFB0, 0xC5FC}, //10714 #HANGUL SYLLABLE IEUNG YEO MIEUM + {0xBFB1, 0xC5FD}, //10715 #HANGUL SYLLABLE IEUNG YEO PIEUP + {0xBFB2, 0xC5FE}, //10716 #HANGUL SYLLABLE IEUNG YEO PIEUPSIOS + {0xBFB3, 0xC5FF}, //10717 #HANGUL SYLLABLE IEUNG YEO SIOS + {0xBFB4, 0xC600}, //10718 #HANGUL SYLLABLE IEUNG YEO SSANGSIOS + {0xBFB5, 0xC601}, //10719 #HANGUL SYLLABLE IEUNG YEO IEUNG + {0xBFB6, 0xC605}, //10720 #HANGUL SYLLABLE IEUNG YEO THIEUTH + {0xBFB7, 0xC606}, //10721 #HANGUL SYLLABLE IEUNG YEO PHIEUPH + {0xBFB8, 0xC607}, //10722 #HANGUL SYLLABLE IEUNG YEO HIEUH + {0xBFB9, 0xC608}, //10723 #HANGUL SYLLABLE IEUNG YE + {0xBFBA, 0xC60C}, //10724 #HANGUL SYLLABLE IEUNG YE NIEUN + {0xBFBB, 0xC610}, //10725 #HANGUL SYLLABLE IEUNG YE RIEUL + {0xBFBC, 0xC618}, //10726 #HANGUL SYLLABLE IEUNG YE MIEUM + {0xBFBD, 0xC619}, //10727 #HANGUL SYLLABLE IEUNG YE PIEUP + {0xBFBE, 0xC61B}, //10728 #HANGUL SYLLABLE IEUNG YE SIOS + {0xBFBF, 0xC61C}, //10729 #HANGUL SYLLABLE IEUNG YE SSANGSIOS + {0xBFC0, 0xC624}, //10730 #HANGUL SYLLABLE IEUNG O + {0xBFC1, 0xC625}, //10731 #HANGUL SYLLABLE IEUNG O KIYEOK + {0xBFC2, 0xC628}, //10732 #HANGUL SYLLABLE IEUNG O NIEUN + {0xBFC3, 0xC62C}, //10733 #HANGUL SYLLABLE IEUNG O RIEUL + {0xBFC4, 0xC62D}, //10734 #HANGUL SYLLABLE IEUNG O RIEULKIYEOK + {0xBFC5, 0xC62E}, //10735 #HANGUL SYLLABLE IEUNG O RIEULMIEUM + {0xBFC6, 0xC630}, //10736 #HANGUL SYLLABLE IEUNG O RIEULSIOS + {0xBFC7, 0xC633}, //10737 #HANGUL SYLLABLE IEUNG O RIEULHIEUH + {0xBFC8, 0xC634}, //10738 #HANGUL SYLLABLE IEUNG O MIEUM + {0xBFC9, 0xC635}, //10739 #HANGUL SYLLABLE IEUNG O PIEUP + {0xBFCA, 0xC637}, //10740 #HANGUL SYLLABLE IEUNG O SIOS + {0xBFCB, 0xC639}, //10741 #HANGUL SYLLABLE IEUNG O IEUNG + {0xBFCC, 0xC63B}, //10742 #HANGUL SYLLABLE IEUNG O CHIEUCH + {0xBFCD, 0xC640}, //10743 #HANGUL SYLLABLE IEUNG WA + {0xBFCE, 0xC641}, //10744 #HANGUL SYLLABLE IEUNG WA KIYEOK + {0xBFCF, 0xC644}, //10745 #HANGUL SYLLABLE IEUNG WA NIEUN + {0xBFD0, 0xC648}, //10746 #HANGUL SYLLABLE IEUNG WA RIEUL + {0xBFD1, 0xC650}, //10747 #HANGUL SYLLABLE IEUNG WA MIEUM + {0xBFD2, 0xC651}, //10748 #HANGUL SYLLABLE IEUNG WA PIEUP + {0xBFD3, 0xC653}, //10749 #HANGUL SYLLABLE IEUNG WA SIOS + {0xBFD4, 0xC654}, //10750 #HANGUL SYLLABLE IEUNG WA SSANGSIOS + {0xBFD5, 0xC655}, //10751 #HANGUL SYLLABLE IEUNG WA IEUNG + {0xBFD6, 0xC65C}, //10752 #HANGUL SYLLABLE IEUNG WAE + {0xBFD7, 0xC65D}, //10753 #HANGUL SYLLABLE IEUNG WAE KIYEOK + {0xBFD8, 0xC660}, //10754 #HANGUL SYLLABLE IEUNG WAE NIEUN + {0xBFD9, 0xC66C}, //10755 #HANGUL SYLLABLE IEUNG WAE MIEUM + {0xBFDA, 0xC66F}, //10756 #HANGUL SYLLABLE IEUNG WAE SIOS + {0xBFDB, 0xC671}, //10757 #HANGUL SYLLABLE IEUNG WAE IEUNG + {0xBFDC, 0xC678}, //10758 #HANGUL SYLLABLE IEUNG OE + {0xBFDD, 0xC679}, //10759 #HANGUL SYLLABLE IEUNG OE KIYEOK + {0xBFDE, 0xC67C}, //10760 #HANGUL SYLLABLE IEUNG OE NIEUN + {0xBFDF, 0xC680}, //10761 #HANGUL SYLLABLE IEUNG OE RIEUL + {0xBFE0, 0xC688}, //10762 #HANGUL SYLLABLE IEUNG OE MIEUM + {0xBFE1, 0xC689}, //10763 #HANGUL SYLLABLE IEUNG OE PIEUP + {0xBFE2, 0xC68B}, //10764 #HANGUL SYLLABLE IEUNG OE SIOS + {0xBFE3, 0xC68D}, //10765 #HANGUL SYLLABLE IEUNG OE IEUNG + {0xBFE4, 0xC694}, //10766 #HANGUL SYLLABLE IEUNG YO + {0xBFE5, 0xC695}, //10767 #HANGUL SYLLABLE IEUNG YO KIYEOK + {0xBFE6, 0xC698}, //10768 #HANGUL SYLLABLE IEUNG YO NIEUN + {0xBFE7, 0xC69C}, //10769 #HANGUL SYLLABLE IEUNG YO RIEUL + {0xBFE8, 0xC6A4}, //10770 #HANGUL SYLLABLE IEUNG YO MIEUM + {0xBFE9, 0xC6A5}, //10771 #HANGUL SYLLABLE IEUNG YO PIEUP + {0xBFEA, 0xC6A7}, //10772 #HANGUL SYLLABLE IEUNG YO SIOS + {0xBFEB, 0xC6A9}, //10773 #HANGUL SYLLABLE IEUNG YO IEUNG + {0xBFEC, 0xC6B0}, //10774 #HANGUL SYLLABLE IEUNG U + {0xBFED, 0xC6B1}, //10775 #HANGUL SYLLABLE IEUNG U KIYEOK + {0xBFEE, 0xC6B4}, //10776 #HANGUL SYLLABLE IEUNG U NIEUN + {0xBFEF, 0xC6B8}, //10777 #HANGUL SYLLABLE IEUNG U RIEUL + {0xBFF0, 0xC6B9}, //10778 #HANGUL SYLLABLE IEUNG U RIEULKIYEOK + {0xBFF1, 0xC6BA}, //10779 #HANGUL SYLLABLE IEUNG U RIEULMIEUM + {0xBFF2, 0xC6C0}, //10780 #HANGUL SYLLABLE IEUNG U MIEUM + {0xBFF3, 0xC6C1}, //10781 #HANGUL SYLLABLE IEUNG U PIEUP + {0xBFF4, 0xC6C3}, //10782 #HANGUL SYLLABLE IEUNG U SIOS + {0xBFF5, 0xC6C5}, //10783 #HANGUL SYLLABLE IEUNG U IEUNG + {0xBFF6, 0xC6CC}, //10784 #HANGUL SYLLABLE IEUNG WEO + {0xBFF7, 0xC6CD}, //10785 #HANGUL SYLLABLE IEUNG WEO KIYEOK + {0xBFF8, 0xC6D0}, //10786 #HANGUL SYLLABLE IEUNG WEO NIEUN + {0xBFF9, 0xC6D4}, //10787 #HANGUL SYLLABLE IEUNG WEO RIEUL + {0xBFFA, 0xC6DC}, //10788 #HANGUL SYLLABLE IEUNG WEO MIEUM + {0xBFFB, 0xC6DD}, //10789 #HANGUL SYLLABLE IEUNG WEO PIEUP + {0xBFFC, 0xC6E0}, //10790 #HANGUL SYLLABLE IEUNG WEO SSANGSIOS + {0xBFFD, 0xC6E1}, //10791 #HANGUL SYLLABLE IEUNG WEO IEUNG + {0xBFFE, 0xC6E8}, //10792 #HANGUL SYLLABLE IEUNG WE + {0xC041, 0xD4FE}, //10793 #HANGUL SYLLABLE PHIEUPH YU CIEUC + {0xC042, 0xD4FF}, //10794 #HANGUL SYLLABLE PHIEUPH YU CHIEUCH + {0xC043, 0xD500}, //10795 #HANGUL SYLLABLE PHIEUPH YU KHIEUKH + {0xC044, 0xD501}, //10796 #HANGUL SYLLABLE PHIEUPH YU THIEUTH + {0xC045, 0xD502}, //10797 #HANGUL SYLLABLE PHIEUPH YU PHIEUPH + {0xC046, 0xD503}, //10798 #HANGUL SYLLABLE PHIEUPH YU HIEUH + {0xC047, 0xD505}, //10799 #HANGUL SYLLABLE PHIEUPH EU KIYEOK + {0xC048, 0xD506}, //10800 #HANGUL SYLLABLE PHIEUPH EU SSANGKIYEOK + {0xC049, 0xD507}, //10801 #HANGUL SYLLABLE PHIEUPH EU KIYEOKSIOS + {0xC04A, 0xD509}, //10802 #HANGUL SYLLABLE PHIEUPH EU NIEUNCIEUC + {0xC04B, 0xD50A}, //10803 #HANGUL SYLLABLE PHIEUPH EU NIEUNHIEUH + {0xC04C, 0xD50B}, //10804 #HANGUL SYLLABLE PHIEUPH EU TIKEUT + {0xC04D, 0xD50D}, //10805 #HANGUL SYLLABLE PHIEUPH EU RIEULKIYEOK + {0xC04E, 0xD50E}, //10806 #HANGUL SYLLABLE PHIEUPH EU RIEULMIEUM + {0xC04F, 0xD50F}, //10807 #HANGUL SYLLABLE PHIEUPH EU RIEULPIEUP + {0xC050, 0xD510}, //10808 #HANGUL SYLLABLE PHIEUPH EU RIEULSIOS + {0xC051, 0xD511}, //10809 #HANGUL SYLLABLE PHIEUPH EU RIEULTHIEUTH + {0xC052, 0xD512}, //10810 #HANGUL SYLLABLE PHIEUPH EU RIEULPHIEUPH + {0xC053, 0xD513}, //10811 #HANGUL SYLLABLE PHIEUPH EU RIEULHIEUH + {0xC054, 0xD516}, //10812 #HANGUL SYLLABLE PHIEUPH EU PIEUPSIOS + {0xC055, 0xD518}, //10813 #HANGUL SYLLABLE PHIEUPH EU SSANGSIOS + {0xC056, 0xD519}, //10814 #HANGUL SYLLABLE PHIEUPH EU IEUNG + {0xC057, 0xD51A}, //10815 #HANGUL SYLLABLE PHIEUPH EU CIEUC + {0xC058, 0xD51B}, //10816 #HANGUL SYLLABLE PHIEUPH EU CHIEUCH + {0xC059, 0xD51C}, //10817 #HANGUL SYLLABLE PHIEUPH EU KHIEUKH + {0xC05A, 0xD51D}, //10818 #HANGUL SYLLABLE PHIEUPH EU THIEUTH + {0xC061, 0xD51E}, //10819 #HANGUL SYLLABLE PHIEUPH EU PHIEUPH + {0xC062, 0xD51F}, //10820 #HANGUL SYLLABLE PHIEUPH EU HIEUH + {0xC063, 0xD520}, //10821 #HANGUL SYLLABLE PHIEUPH YI + {0xC064, 0xD521}, //10822 #HANGUL SYLLABLE PHIEUPH YI KIYEOK + {0xC065, 0xD522}, //10823 #HANGUL SYLLABLE PHIEUPH YI SSANGKIYEOK + {0xC066, 0xD523}, //10824 #HANGUL SYLLABLE PHIEUPH YI KIYEOKSIOS + {0xC067, 0xD524}, //10825 #HANGUL SYLLABLE PHIEUPH YI NIEUN + {0xC068, 0xD525}, //10826 #HANGUL SYLLABLE PHIEUPH YI NIEUNCIEUC + {0xC069, 0xD526}, //10827 #HANGUL SYLLABLE PHIEUPH YI NIEUNHIEUH + {0xC06A, 0xD527}, //10828 #HANGUL SYLLABLE PHIEUPH YI TIKEUT + {0xC06B, 0xD528}, //10829 #HANGUL SYLLABLE PHIEUPH YI RIEUL + {0xC06C, 0xD529}, //10830 #HANGUL SYLLABLE PHIEUPH YI RIEULKIYEOK + {0xC06D, 0xD52A}, //10831 #HANGUL SYLLABLE PHIEUPH YI RIEULMIEUM + {0xC06E, 0xD52B}, //10832 #HANGUL SYLLABLE PHIEUPH YI RIEULPIEUP + {0xC06F, 0xD52C}, //10833 #HANGUL SYLLABLE PHIEUPH YI RIEULSIOS + {0xC070, 0xD52D}, //10834 #HANGUL SYLLABLE PHIEUPH YI RIEULTHIEUTH + {0xC071, 0xD52E}, //10835 #HANGUL SYLLABLE PHIEUPH YI RIEULPHIEUPH + {0xC072, 0xD52F}, //10836 #HANGUL SYLLABLE PHIEUPH YI RIEULHIEUH + {0xC073, 0xD530}, //10837 #HANGUL SYLLABLE PHIEUPH YI MIEUM + {0xC074, 0xD531}, //10838 #HANGUL SYLLABLE PHIEUPH YI PIEUP + {0xC075, 0xD532}, //10839 #HANGUL SYLLABLE PHIEUPH YI PIEUPSIOS + {0xC076, 0xD533}, //10840 #HANGUL SYLLABLE PHIEUPH YI SIOS + {0xC077, 0xD534}, //10841 #HANGUL SYLLABLE PHIEUPH YI SSANGSIOS + {0xC078, 0xD535}, //10842 #HANGUL SYLLABLE PHIEUPH YI IEUNG + {0xC079, 0xD536}, //10843 #HANGUL SYLLABLE PHIEUPH YI CIEUC + {0xC07A, 0xD537}, //10844 #HANGUL SYLLABLE PHIEUPH YI CHIEUCH + {0xC081, 0xD538}, //10845 #HANGUL SYLLABLE PHIEUPH YI KHIEUKH + {0xC082, 0xD539}, //10846 #HANGUL SYLLABLE PHIEUPH YI THIEUTH + {0xC083, 0xD53A}, //10847 #HANGUL SYLLABLE PHIEUPH YI PHIEUPH + {0xC084, 0xD53B}, //10848 #HANGUL SYLLABLE PHIEUPH YI HIEUH + {0xC085, 0xD53E}, //10849 #HANGUL SYLLABLE PHIEUPH I SSANGKIYEOK + {0xC086, 0xD53F}, //10850 #HANGUL SYLLABLE PHIEUPH I KIYEOKSIOS + {0xC087, 0xD541}, //10851 #HANGUL SYLLABLE PHIEUPH I NIEUNCIEUC + {0xC088, 0xD542}, //10852 #HANGUL SYLLABLE PHIEUPH I NIEUNHIEUH + {0xC089, 0xD543}, //10853 #HANGUL SYLLABLE PHIEUPH I TIKEUT + {0xC08A, 0xD545}, //10854 #HANGUL SYLLABLE PHIEUPH I RIEULKIYEOK + {0xC08B, 0xD546}, //10855 #HANGUL SYLLABLE PHIEUPH I RIEULMIEUM + {0xC08C, 0xD547}, //10856 #HANGUL SYLLABLE PHIEUPH I RIEULPIEUP + {0xC08D, 0xD548}, //10857 #HANGUL SYLLABLE PHIEUPH I RIEULSIOS + {0xC08E, 0xD549}, //10858 #HANGUL SYLLABLE PHIEUPH I RIEULTHIEUTH + {0xC08F, 0xD54A}, //10859 #HANGUL SYLLABLE PHIEUPH I RIEULPHIEUPH + {0xC090, 0xD54B}, //10860 #HANGUL SYLLABLE PHIEUPH I RIEULHIEUH + {0xC091, 0xD54E}, //10861 #HANGUL SYLLABLE PHIEUPH I PIEUPSIOS + {0xC092, 0xD550}, //10862 #HANGUL SYLLABLE PHIEUPH I SSANGSIOS + {0xC093, 0xD552}, //10863 #HANGUL SYLLABLE PHIEUPH I CIEUC + {0xC094, 0xD553}, //10864 #HANGUL SYLLABLE PHIEUPH I CHIEUCH + {0xC095, 0xD554}, //10865 #HANGUL SYLLABLE PHIEUPH I KHIEUKH + {0xC096, 0xD555}, //10866 #HANGUL SYLLABLE PHIEUPH I THIEUTH + {0xC097, 0xD556}, //10867 #HANGUL SYLLABLE PHIEUPH I PHIEUPH + {0xC098, 0xD557}, //10868 #HANGUL SYLLABLE PHIEUPH I HIEUH + {0xC099, 0xD55A}, //10869 #HANGUL SYLLABLE HIEUH A SSANGKIYEOK + {0xC09A, 0xD55B}, //10870 #HANGUL SYLLABLE HIEUH A KIYEOKSIOS + {0xC09B, 0xD55D}, //10871 #HANGUL SYLLABLE HIEUH A NIEUNCIEUC + {0xC09C, 0xD55E}, //10872 #HANGUL SYLLABLE HIEUH A NIEUNHIEUH + {0xC09D, 0xD55F}, //10873 #HANGUL SYLLABLE HIEUH A TIKEUT + {0xC09E, 0xD561}, //10874 #HANGUL SYLLABLE HIEUH A RIEULKIYEOK + {0xC09F, 0xD562}, //10875 #HANGUL SYLLABLE HIEUH A RIEULMIEUM + {0xC0A0, 0xD563}, //10876 #HANGUL SYLLABLE HIEUH A RIEULPIEUP + {0xC0A1, 0xC6E9}, //10877 #HANGUL SYLLABLE IEUNG WE KIYEOK + {0xC0A2, 0xC6EC}, //10878 #HANGUL SYLLABLE IEUNG WE NIEUN + {0xC0A3, 0xC6F0}, //10879 #HANGUL SYLLABLE IEUNG WE RIEUL + {0xC0A4, 0xC6F8}, //10880 #HANGUL SYLLABLE IEUNG WE MIEUM + {0xC0A5, 0xC6F9}, //10881 #HANGUL SYLLABLE IEUNG WE PIEUP + {0xC0A6, 0xC6FD}, //10882 #HANGUL SYLLABLE IEUNG WE IEUNG + {0xC0A7, 0xC704}, //10883 #HANGUL SYLLABLE IEUNG WI + {0xC0A8, 0xC705}, //10884 #HANGUL SYLLABLE IEUNG WI KIYEOK + {0xC0A9, 0xC708}, //10885 #HANGUL SYLLABLE IEUNG WI NIEUN + {0xC0AA, 0xC70C}, //10886 #HANGUL SYLLABLE IEUNG WI RIEUL + {0xC0AB, 0xC714}, //10887 #HANGUL SYLLABLE IEUNG WI MIEUM + {0xC0AC, 0xC715}, //10888 #HANGUL SYLLABLE IEUNG WI PIEUP + {0xC0AD, 0xC717}, //10889 #HANGUL SYLLABLE IEUNG WI SIOS + {0xC0AE, 0xC719}, //10890 #HANGUL SYLLABLE IEUNG WI IEUNG + {0xC0AF, 0xC720}, //10891 #HANGUL SYLLABLE IEUNG YU + {0xC0B0, 0xC721}, //10892 #HANGUL SYLLABLE IEUNG YU KIYEOK + {0xC0B1, 0xC724}, //10893 #HANGUL SYLLABLE IEUNG YU NIEUN + {0xC0B2, 0xC728}, //10894 #HANGUL SYLLABLE IEUNG YU RIEUL + {0xC0B3, 0xC730}, //10895 #HANGUL SYLLABLE IEUNG YU MIEUM + {0xC0B4, 0xC731}, //10896 #HANGUL SYLLABLE IEUNG YU PIEUP + {0xC0B5, 0xC733}, //10897 #HANGUL SYLLABLE IEUNG YU SIOS + {0xC0B6, 0xC735}, //10898 #HANGUL SYLLABLE IEUNG YU IEUNG + {0xC0B7, 0xC737}, //10899 #HANGUL SYLLABLE IEUNG YU CHIEUCH + {0xC0B8, 0xC73C}, //10900 #HANGUL SYLLABLE IEUNG EU + {0xC0B9, 0xC73D}, //10901 #HANGUL SYLLABLE IEUNG EU KIYEOK + {0xC0BA, 0xC740}, //10902 #HANGUL SYLLABLE IEUNG EU NIEUN + {0xC0BB, 0xC744}, //10903 #HANGUL SYLLABLE IEUNG EU RIEUL + {0xC0BC, 0xC74A}, //10904 #HANGUL SYLLABLE IEUNG EU RIEULPHIEUPH + {0xC0BD, 0xC74C}, //10905 #HANGUL SYLLABLE IEUNG EU MIEUM + {0xC0BE, 0xC74D}, //10906 #HANGUL SYLLABLE IEUNG EU PIEUP + {0xC0BF, 0xC74F}, //10907 #HANGUL SYLLABLE IEUNG EU SIOS + {0xC0C0, 0xC751}, //10908 #HANGUL SYLLABLE IEUNG EU IEUNG + {0xC0C1, 0xC752}, //10909 #HANGUL SYLLABLE IEUNG EU CIEUC + {0xC0C2, 0xC753}, //10910 #HANGUL SYLLABLE IEUNG EU CHIEUCH + {0xC0C3, 0xC754}, //10911 #HANGUL SYLLABLE IEUNG EU KHIEUKH + {0xC0C4, 0xC755}, //10912 #HANGUL SYLLABLE IEUNG EU THIEUTH + {0xC0C5, 0xC756}, //10913 #HANGUL SYLLABLE IEUNG EU PHIEUPH + {0xC0C6, 0xC757}, //10914 #HANGUL SYLLABLE IEUNG EU HIEUH + {0xC0C7, 0xC758}, //10915 #HANGUL SYLLABLE IEUNG YI + {0xC0C8, 0xC75C}, //10916 #HANGUL SYLLABLE IEUNG YI NIEUN + {0xC0C9, 0xC760}, //10917 #HANGUL SYLLABLE IEUNG YI RIEUL + {0xC0CA, 0xC768}, //10918 #HANGUL SYLLABLE IEUNG YI MIEUM + {0xC0CB, 0xC76B}, //10919 #HANGUL SYLLABLE IEUNG YI SIOS + {0xC0CC, 0xC774}, //10920 #HANGUL SYLLABLE IEUNG I + {0xC0CD, 0xC775}, //10921 #HANGUL SYLLABLE IEUNG I KIYEOK + {0xC0CE, 0xC778}, //10922 #HANGUL SYLLABLE IEUNG I NIEUN + {0xC0CF, 0xC77C}, //10923 #HANGUL SYLLABLE IEUNG I RIEUL + {0xC0D0, 0xC77D}, //10924 #HANGUL SYLLABLE IEUNG I RIEULKIYEOK + {0xC0D1, 0xC77E}, //10925 #HANGUL SYLLABLE IEUNG I RIEULMIEUM + {0xC0D2, 0xC783}, //10926 #HANGUL SYLLABLE IEUNG I RIEULHIEUH + {0xC0D3, 0xC784}, //10927 #HANGUL SYLLABLE IEUNG I MIEUM + {0xC0D4, 0xC785}, //10928 #HANGUL SYLLABLE IEUNG I PIEUP + {0xC0D5, 0xC787}, //10929 #HANGUL SYLLABLE IEUNG I SIOS + {0xC0D6, 0xC788}, //10930 #HANGUL SYLLABLE IEUNG I SSANGSIOS + {0xC0D7, 0xC789}, //10931 #HANGUL SYLLABLE IEUNG I IEUNG + {0xC0D8, 0xC78A}, //10932 #HANGUL SYLLABLE IEUNG I CIEUC + {0xC0D9, 0xC78E}, //10933 #HANGUL SYLLABLE IEUNG I PHIEUPH + {0xC0DA, 0xC790}, //10934 #HANGUL SYLLABLE CIEUC A + {0xC0DB, 0xC791}, //10935 #HANGUL SYLLABLE CIEUC A KIYEOK + {0xC0DC, 0xC794}, //10936 #HANGUL SYLLABLE CIEUC A NIEUN + {0xC0DD, 0xC796}, //10937 #HANGUL SYLLABLE CIEUC A NIEUNHIEUH + {0xC0DE, 0xC797}, //10938 #HANGUL SYLLABLE CIEUC A TIKEUT + {0xC0DF, 0xC798}, //10939 #HANGUL SYLLABLE CIEUC A RIEUL + {0xC0E0, 0xC79A}, //10940 #HANGUL SYLLABLE CIEUC A RIEULMIEUM + {0xC0E1, 0xC7A0}, //10941 #HANGUL SYLLABLE CIEUC A MIEUM + {0xC0E2, 0xC7A1}, //10942 #HANGUL SYLLABLE CIEUC A PIEUP + {0xC0E3, 0xC7A3}, //10943 #HANGUL SYLLABLE CIEUC A SIOS + {0xC0E4, 0xC7A4}, //10944 #HANGUL SYLLABLE CIEUC A SSANGSIOS + {0xC0E5, 0xC7A5}, //10945 #HANGUL SYLLABLE CIEUC A IEUNG + {0xC0E6, 0xC7A6}, //10946 #HANGUL SYLLABLE CIEUC A CIEUC + {0xC0E7, 0xC7AC}, //10947 #HANGUL SYLLABLE CIEUC AE + {0xC0E8, 0xC7AD}, //10948 #HANGUL SYLLABLE CIEUC AE KIYEOK + {0xC0E9, 0xC7B0}, //10949 #HANGUL SYLLABLE CIEUC AE NIEUN + {0xC0EA, 0xC7B4}, //10950 #HANGUL SYLLABLE CIEUC AE RIEUL + {0xC0EB, 0xC7BC}, //10951 #HANGUL SYLLABLE CIEUC AE MIEUM + {0xC0EC, 0xC7BD}, //10952 #HANGUL SYLLABLE CIEUC AE PIEUP + {0xC0ED, 0xC7BF}, //10953 #HANGUL SYLLABLE CIEUC AE SIOS + {0xC0EE, 0xC7C0}, //10954 #HANGUL SYLLABLE CIEUC AE SSANGSIOS + {0xC0EF, 0xC7C1}, //10955 #HANGUL SYLLABLE CIEUC AE IEUNG + {0xC0F0, 0xC7C8}, //10956 #HANGUL SYLLABLE CIEUC YA + {0xC0F1, 0xC7C9}, //10957 #HANGUL SYLLABLE CIEUC YA KIYEOK + {0xC0F2, 0xC7CC}, //10958 #HANGUL SYLLABLE CIEUC YA NIEUN + {0xC0F3, 0xC7CE}, //10959 #HANGUL SYLLABLE CIEUC YA NIEUNHIEUH + {0xC0F4, 0xC7D0}, //10960 #HANGUL SYLLABLE CIEUC YA RIEUL + {0xC0F5, 0xC7D8}, //10961 #HANGUL SYLLABLE CIEUC YA MIEUM + {0xC0F6, 0xC7DD}, //10962 #HANGUL SYLLABLE CIEUC YA IEUNG + {0xC0F7, 0xC7E4}, //10963 #HANGUL SYLLABLE CIEUC YAE + {0xC0F8, 0xC7E8}, //10964 #HANGUL SYLLABLE CIEUC YAE NIEUN + {0xC0F9, 0xC7EC}, //10965 #HANGUL SYLLABLE CIEUC YAE RIEUL + {0xC0FA, 0xC800}, //10966 #HANGUL SYLLABLE CIEUC EO + {0xC0FB, 0xC801}, //10967 #HANGUL SYLLABLE CIEUC EO KIYEOK + {0xC0FC, 0xC804}, //10968 #HANGUL SYLLABLE CIEUC EO NIEUN + {0xC0FD, 0xC808}, //10969 #HANGUL SYLLABLE CIEUC EO RIEUL + {0xC0FE, 0xC80A}, //10970 #HANGUL SYLLABLE CIEUC EO RIEULMIEUM + {0xC141, 0xD564}, //10971 #HANGUL SYLLABLE HIEUH A RIEULSIOS + {0xC142, 0xD566}, //10972 #HANGUL SYLLABLE HIEUH A RIEULPHIEUPH + {0xC143, 0xD567}, //10973 #HANGUL SYLLABLE HIEUH A RIEULHIEUH + {0xC144, 0xD56A}, //10974 #HANGUL SYLLABLE HIEUH A PIEUPSIOS + {0xC145, 0xD56C}, //10975 #HANGUL SYLLABLE HIEUH A SSANGSIOS + {0xC146, 0xD56E}, //10976 #HANGUL SYLLABLE HIEUH A CIEUC + {0xC147, 0xD56F}, //10977 #HANGUL SYLLABLE HIEUH A CHIEUCH + {0xC148, 0xD570}, //10978 #HANGUL SYLLABLE HIEUH A KHIEUKH + {0xC149, 0xD571}, //10979 #HANGUL SYLLABLE HIEUH A THIEUTH + {0xC14A, 0xD572}, //10980 #HANGUL SYLLABLE HIEUH A PHIEUPH + {0xC14B, 0xD573}, //10981 #HANGUL SYLLABLE HIEUH A HIEUH + {0xC14C, 0xD576}, //10982 #HANGUL SYLLABLE HIEUH AE SSANGKIYEOK + {0xC14D, 0xD577}, //10983 #HANGUL SYLLABLE HIEUH AE KIYEOKSIOS + {0xC14E, 0xD579}, //10984 #HANGUL SYLLABLE HIEUH AE NIEUNCIEUC + {0xC14F, 0xD57A}, //10985 #HANGUL SYLLABLE HIEUH AE NIEUNHIEUH + {0xC150, 0xD57B}, //10986 #HANGUL SYLLABLE HIEUH AE TIKEUT + {0xC151, 0xD57D}, //10987 #HANGUL SYLLABLE HIEUH AE RIEULKIYEOK + {0xC152, 0xD57E}, //10988 #HANGUL SYLLABLE HIEUH AE RIEULMIEUM + {0xC153, 0xD57F}, //10989 #HANGUL SYLLABLE HIEUH AE RIEULPIEUP + {0xC154, 0xD580}, //10990 #HANGUL SYLLABLE HIEUH AE RIEULSIOS + {0xC155, 0xD581}, //10991 #HANGUL SYLLABLE HIEUH AE RIEULTHIEUTH + {0xC156, 0xD582}, //10992 #HANGUL SYLLABLE HIEUH AE RIEULPHIEUPH + {0xC157, 0xD583}, //10993 #HANGUL SYLLABLE HIEUH AE RIEULHIEUH + {0xC158, 0xD586}, //10994 #HANGUL SYLLABLE HIEUH AE PIEUPSIOS + {0xC159, 0xD58A}, //10995 #HANGUL SYLLABLE HIEUH AE CIEUC + {0xC15A, 0xD58B}, //10996 #HANGUL SYLLABLE HIEUH AE CHIEUCH + {0xC161, 0xD58C}, //10997 #HANGUL SYLLABLE HIEUH AE KHIEUKH + {0xC162, 0xD58D}, //10998 #HANGUL SYLLABLE HIEUH AE THIEUTH + {0xC163, 0xD58E}, //10999 #HANGUL SYLLABLE HIEUH AE PHIEUPH + {0xC164, 0xD58F}, //11000 #HANGUL SYLLABLE HIEUH AE HIEUH + {0xC165, 0xD591}, //11001 #HANGUL SYLLABLE HIEUH YA KIYEOK + {0xC166, 0xD592}, //11002 #HANGUL SYLLABLE HIEUH YA SSANGKIYEOK + {0xC167, 0xD593}, //11003 #HANGUL SYLLABLE HIEUH YA KIYEOKSIOS + {0xC168, 0xD594}, //11004 #HANGUL SYLLABLE HIEUH YA NIEUN + {0xC169, 0xD595}, //11005 #HANGUL SYLLABLE HIEUH YA NIEUNCIEUC + {0xC16A, 0xD596}, //11006 #HANGUL SYLLABLE HIEUH YA NIEUNHIEUH + {0xC16B, 0xD597}, //11007 #HANGUL SYLLABLE HIEUH YA TIKEUT + {0xC16C, 0xD598}, //11008 #HANGUL SYLLABLE HIEUH YA RIEUL + {0xC16D, 0xD599}, //11009 #HANGUL SYLLABLE HIEUH YA RIEULKIYEOK + {0xC16E, 0xD59A}, //11010 #HANGUL SYLLABLE HIEUH YA RIEULMIEUM + {0xC16F, 0xD59B}, //11011 #HANGUL SYLLABLE HIEUH YA RIEULPIEUP + {0xC170, 0xD59C}, //11012 #HANGUL SYLLABLE HIEUH YA RIEULSIOS + {0xC171, 0xD59D}, //11013 #HANGUL SYLLABLE HIEUH YA RIEULTHIEUTH + {0xC172, 0xD59E}, //11014 #HANGUL SYLLABLE HIEUH YA RIEULPHIEUPH + {0xC173, 0xD59F}, //11015 #HANGUL SYLLABLE HIEUH YA RIEULHIEUH + {0xC174, 0xD5A0}, //11016 #HANGUL SYLLABLE HIEUH YA MIEUM + {0xC175, 0xD5A1}, //11017 #HANGUL SYLLABLE HIEUH YA PIEUP + {0xC176, 0xD5A2}, //11018 #HANGUL SYLLABLE HIEUH YA PIEUPSIOS + {0xC177, 0xD5A3}, //11019 #HANGUL SYLLABLE HIEUH YA SIOS + {0xC178, 0xD5A4}, //11020 #HANGUL SYLLABLE HIEUH YA SSANGSIOS + {0xC179, 0xD5A6}, //11021 #HANGUL SYLLABLE HIEUH YA CIEUC + {0xC17A, 0xD5A7}, //11022 #HANGUL SYLLABLE HIEUH YA CHIEUCH + {0xC181, 0xD5A8}, //11023 #HANGUL SYLLABLE HIEUH YA KHIEUKH + {0xC182, 0xD5A9}, //11024 #HANGUL SYLLABLE HIEUH YA THIEUTH + {0xC183, 0xD5AA}, //11025 #HANGUL SYLLABLE HIEUH YA PHIEUPH + {0xC184, 0xD5AB}, //11026 #HANGUL SYLLABLE HIEUH YA HIEUH + {0xC185, 0xD5AC}, //11027 #HANGUL SYLLABLE HIEUH YAE + {0xC186, 0xD5AD}, //11028 #HANGUL SYLLABLE HIEUH YAE KIYEOK + {0xC187, 0xD5AE}, //11029 #HANGUL SYLLABLE HIEUH YAE SSANGKIYEOK + {0xC188, 0xD5AF}, //11030 #HANGUL SYLLABLE HIEUH YAE KIYEOKSIOS + {0xC189, 0xD5B0}, //11031 #HANGUL SYLLABLE HIEUH YAE NIEUN + {0xC18A, 0xD5B1}, //11032 #HANGUL SYLLABLE HIEUH YAE NIEUNCIEUC + {0xC18B, 0xD5B2}, //11033 #HANGUL SYLLABLE HIEUH YAE NIEUNHIEUH + {0xC18C, 0xD5B3}, //11034 #HANGUL SYLLABLE HIEUH YAE TIKEUT + {0xC18D, 0xD5B4}, //11035 #HANGUL SYLLABLE HIEUH YAE RIEUL + {0xC18E, 0xD5B5}, //11036 #HANGUL SYLLABLE HIEUH YAE RIEULKIYEOK + {0xC18F, 0xD5B6}, //11037 #HANGUL SYLLABLE HIEUH YAE RIEULMIEUM + {0xC190, 0xD5B7}, //11038 #HANGUL SYLLABLE HIEUH YAE RIEULPIEUP + {0xC191, 0xD5B8}, //11039 #HANGUL SYLLABLE HIEUH YAE RIEULSIOS + {0xC192, 0xD5B9}, //11040 #HANGUL SYLLABLE HIEUH YAE RIEULTHIEUTH + {0xC193, 0xD5BA}, //11041 #HANGUL SYLLABLE HIEUH YAE RIEULPHIEUPH + {0xC194, 0xD5BB}, //11042 #HANGUL SYLLABLE HIEUH YAE RIEULHIEUH + {0xC195, 0xD5BC}, //11043 #HANGUL SYLLABLE HIEUH YAE MIEUM + {0xC196, 0xD5BD}, //11044 #HANGUL SYLLABLE HIEUH YAE PIEUP + {0xC197, 0xD5BE}, //11045 #HANGUL SYLLABLE HIEUH YAE PIEUPSIOS + {0xC198, 0xD5BF}, //11046 #HANGUL SYLLABLE HIEUH YAE SIOS + {0xC199, 0xD5C0}, //11047 #HANGUL SYLLABLE HIEUH YAE SSANGSIOS + {0xC19A, 0xD5C1}, //11048 #HANGUL SYLLABLE HIEUH YAE IEUNG + {0xC19B, 0xD5C2}, //11049 #HANGUL SYLLABLE HIEUH YAE CIEUC + {0xC19C, 0xD5C3}, //11050 #HANGUL SYLLABLE HIEUH YAE CHIEUCH + {0xC19D, 0xD5C4}, //11051 #HANGUL SYLLABLE HIEUH YAE KHIEUKH + {0xC19E, 0xD5C5}, //11052 #HANGUL SYLLABLE HIEUH YAE THIEUTH + {0xC19F, 0xD5C6}, //11053 #HANGUL SYLLABLE HIEUH YAE PHIEUPH + {0xC1A0, 0xD5C7}, //11054 #HANGUL SYLLABLE HIEUH YAE HIEUH + {0xC1A1, 0xC810}, //11055 #HANGUL SYLLABLE CIEUC EO MIEUM + {0xC1A2, 0xC811}, //11056 #HANGUL SYLLABLE CIEUC EO PIEUP + {0xC1A3, 0xC813}, //11057 #HANGUL SYLLABLE CIEUC EO SIOS + {0xC1A4, 0xC815}, //11058 #HANGUL SYLLABLE CIEUC EO IEUNG + {0xC1A5, 0xC816}, //11059 #HANGUL SYLLABLE CIEUC EO CIEUC + {0xC1A6, 0xC81C}, //11060 #HANGUL SYLLABLE CIEUC E + {0xC1A7, 0xC81D}, //11061 #HANGUL SYLLABLE CIEUC E KIYEOK + {0xC1A8, 0xC820}, //11062 #HANGUL SYLLABLE CIEUC E NIEUN + {0xC1A9, 0xC824}, //11063 #HANGUL SYLLABLE CIEUC E RIEUL + {0xC1AA, 0xC82C}, //11064 #HANGUL SYLLABLE CIEUC E MIEUM + {0xC1AB, 0xC82D}, //11065 #HANGUL SYLLABLE CIEUC E PIEUP + {0xC1AC, 0xC82F}, //11066 #HANGUL SYLLABLE CIEUC E SIOS + {0xC1AD, 0xC831}, //11067 #HANGUL SYLLABLE CIEUC E IEUNG + {0xC1AE, 0xC838}, //11068 #HANGUL SYLLABLE CIEUC YEO + {0xC1AF, 0xC83C}, //11069 #HANGUL SYLLABLE CIEUC YEO NIEUN + {0xC1B0, 0xC840}, //11070 #HANGUL SYLLABLE CIEUC YEO RIEUL + {0xC1B1, 0xC848}, //11071 #HANGUL SYLLABLE CIEUC YEO MIEUM + {0xC1B2, 0xC849}, //11072 #HANGUL SYLLABLE CIEUC YEO PIEUP + {0xC1B3, 0xC84C}, //11073 #HANGUL SYLLABLE CIEUC YEO SSANGSIOS + {0xC1B4, 0xC84D}, //11074 #HANGUL SYLLABLE CIEUC YEO IEUNG + {0xC1B5, 0xC854}, //11075 #HANGUL SYLLABLE CIEUC YE + {0xC1B6, 0xC870}, //11076 #HANGUL SYLLABLE CIEUC O + {0xC1B7, 0xC871}, //11077 #HANGUL SYLLABLE CIEUC O KIYEOK + {0xC1B8, 0xC874}, //11078 #HANGUL SYLLABLE CIEUC O NIEUN + {0xC1B9, 0xC878}, //11079 #HANGUL SYLLABLE CIEUC O RIEUL + {0xC1BA, 0xC87A}, //11080 #HANGUL SYLLABLE CIEUC O RIEULMIEUM + {0xC1BB, 0xC880}, //11081 #HANGUL SYLLABLE CIEUC O MIEUM + {0xC1BC, 0xC881}, //11082 #HANGUL SYLLABLE CIEUC O PIEUP + {0xC1BD, 0xC883}, //11083 #HANGUL SYLLABLE CIEUC O SIOS + {0xC1BE, 0xC885}, //11084 #HANGUL SYLLABLE CIEUC O IEUNG + {0xC1BF, 0xC886}, //11085 #HANGUL SYLLABLE CIEUC O CIEUC + {0xC1C0, 0xC887}, //11086 #HANGUL SYLLABLE CIEUC O CHIEUCH + {0xC1C1, 0xC88B}, //11087 #HANGUL SYLLABLE CIEUC O HIEUH + {0xC1C2, 0xC88C}, //11088 #HANGUL SYLLABLE CIEUC WA + {0xC1C3, 0xC88D}, //11089 #HANGUL SYLLABLE CIEUC WA KIYEOK + {0xC1C4, 0xC894}, //11090 #HANGUL SYLLABLE CIEUC WA RIEUL + {0xC1C5, 0xC89D}, //11091 #HANGUL SYLLABLE CIEUC WA PIEUP + {0xC1C6, 0xC89F}, //11092 #HANGUL SYLLABLE CIEUC WA SIOS + {0xC1C7, 0xC8A1}, //11093 #HANGUL SYLLABLE CIEUC WA IEUNG + {0xC1C8, 0xC8A8}, //11094 #HANGUL SYLLABLE CIEUC WAE + {0xC1C9, 0xC8BC}, //11095 #HANGUL SYLLABLE CIEUC WAE SSANGSIOS + {0xC1CA, 0xC8BD}, //11096 #HANGUL SYLLABLE CIEUC WAE IEUNG + {0xC1CB, 0xC8C4}, //11097 #HANGUL SYLLABLE CIEUC OE + {0xC1CC, 0xC8C8}, //11098 #HANGUL SYLLABLE CIEUC OE NIEUN + {0xC1CD, 0xC8CC}, //11099 #HANGUL SYLLABLE CIEUC OE RIEUL + {0xC1CE, 0xC8D4}, //11100 #HANGUL SYLLABLE CIEUC OE MIEUM + {0xC1CF, 0xC8D5}, //11101 #HANGUL SYLLABLE CIEUC OE PIEUP + {0xC1D0, 0xC8D7}, //11102 #HANGUL SYLLABLE CIEUC OE SIOS + {0xC1D1, 0xC8D9}, //11103 #HANGUL SYLLABLE CIEUC OE IEUNG + {0xC1D2, 0xC8E0}, //11104 #HANGUL SYLLABLE CIEUC YO + {0xC1D3, 0xC8E1}, //11105 #HANGUL SYLLABLE CIEUC YO KIYEOK + {0xC1D4, 0xC8E4}, //11106 #HANGUL SYLLABLE CIEUC YO NIEUN + {0xC1D5, 0xC8F5}, //11107 #HANGUL SYLLABLE CIEUC YO IEUNG + {0xC1D6, 0xC8FC}, //11108 #HANGUL SYLLABLE CIEUC U + {0xC1D7, 0xC8FD}, //11109 #HANGUL SYLLABLE CIEUC U KIYEOK + {0xC1D8, 0xC900}, //11110 #HANGUL SYLLABLE CIEUC U NIEUN + {0xC1D9, 0xC904}, //11111 #HANGUL SYLLABLE CIEUC U RIEUL + {0xC1DA, 0xC905}, //11112 #HANGUL SYLLABLE CIEUC U RIEULKIYEOK + {0xC1DB, 0xC906}, //11113 #HANGUL SYLLABLE CIEUC U RIEULMIEUM + {0xC1DC, 0xC90C}, //11114 #HANGUL SYLLABLE CIEUC U MIEUM + {0xC1DD, 0xC90D}, //11115 #HANGUL SYLLABLE CIEUC U PIEUP + {0xC1DE, 0xC90F}, //11116 #HANGUL SYLLABLE CIEUC U SIOS + {0xC1DF, 0xC911}, //11117 #HANGUL SYLLABLE CIEUC U IEUNG + {0xC1E0, 0xC918}, //11118 #HANGUL SYLLABLE CIEUC WEO + {0xC1E1, 0xC92C}, //11119 #HANGUL SYLLABLE CIEUC WEO SSANGSIOS + {0xC1E2, 0xC934}, //11120 #HANGUL SYLLABLE CIEUC WE + {0xC1E3, 0xC950}, //11121 #HANGUL SYLLABLE CIEUC WI + {0xC1E4, 0xC951}, //11122 #HANGUL SYLLABLE CIEUC WI KIYEOK + {0xC1E5, 0xC954}, //11123 #HANGUL SYLLABLE CIEUC WI NIEUN + {0xC1E6, 0xC958}, //11124 #HANGUL SYLLABLE CIEUC WI RIEUL + {0xC1E7, 0xC960}, //11125 #HANGUL SYLLABLE CIEUC WI MIEUM + {0xC1E8, 0xC961}, //11126 #HANGUL SYLLABLE CIEUC WI PIEUP + {0xC1E9, 0xC963}, //11127 #HANGUL SYLLABLE CIEUC WI SIOS + {0xC1EA, 0xC96C}, //11128 #HANGUL SYLLABLE CIEUC YU + {0xC1EB, 0xC970}, //11129 #HANGUL SYLLABLE CIEUC YU NIEUN + {0xC1EC, 0xC974}, //11130 #HANGUL SYLLABLE CIEUC YU RIEUL + {0xC1ED, 0xC97C}, //11131 #HANGUL SYLLABLE CIEUC YU MIEUM + {0xC1EE, 0xC988}, //11132 #HANGUL SYLLABLE CIEUC EU + {0xC1EF, 0xC989}, //11133 #HANGUL SYLLABLE CIEUC EU KIYEOK + {0xC1F0, 0xC98C}, //11134 #HANGUL SYLLABLE CIEUC EU NIEUN + {0xC1F1, 0xC990}, //11135 #HANGUL SYLLABLE CIEUC EU RIEUL + {0xC1F2, 0xC998}, //11136 #HANGUL SYLLABLE CIEUC EU MIEUM + {0xC1F3, 0xC999}, //11137 #HANGUL SYLLABLE CIEUC EU PIEUP + {0xC1F4, 0xC99B}, //11138 #HANGUL SYLLABLE CIEUC EU SIOS + {0xC1F5, 0xC99D}, //11139 #HANGUL SYLLABLE CIEUC EU IEUNG + {0xC1F6, 0xC9C0}, //11140 #HANGUL SYLLABLE CIEUC I + {0xC1F7, 0xC9C1}, //11141 #HANGUL SYLLABLE CIEUC I KIYEOK + {0xC1F8, 0xC9C4}, //11142 #HANGUL SYLLABLE CIEUC I NIEUN + {0xC1F9, 0xC9C7}, //11143 #HANGUL SYLLABLE CIEUC I TIKEUT + {0xC1FA, 0xC9C8}, //11144 #HANGUL SYLLABLE CIEUC I RIEUL + {0xC1FB, 0xC9CA}, //11145 #HANGUL SYLLABLE CIEUC I RIEULMIEUM + {0xC1FC, 0xC9D0}, //11146 #HANGUL SYLLABLE CIEUC I MIEUM + {0xC1FD, 0xC9D1}, //11147 #HANGUL SYLLABLE CIEUC I PIEUP + {0xC1FE, 0xC9D3}, //11148 #HANGUL SYLLABLE CIEUC I SIOS + {0xC241, 0xD5CA}, //11149 #HANGUL SYLLABLE HIEUH EO SSANGKIYEOK + {0xC242, 0xD5CB}, //11150 #HANGUL SYLLABLE HIEUH EO KIYEOKSIOS + {0xC243, 0xD5CD}, //11151 #HANGUL SYLLABLE HIEUH EO NIEUNCIEUC + {0xC244, 0xD5CE}, //11152 #HANGUL SYLLABLE HIEUH EO NIEUNHIEUH + {0xC245, 0xD5CF}, //11153 #HANGUL SYLLABLE HIEUH EO TIKEUT + {0xC246, 0xD5D1}, //11154 #HANGUL SYLLABLE HIEUH EO RIEULKIYEOK + {0xC247, 0xD5D3}, //11155 #HANGUL SYLLABLE HIEUH EO RIEULPIEUP + {0xC248, 0xD5D4}, //11156 #HANGUL SYLLABLE HIEUH EO RIEULSIOS + {0xC249, 0xD5D5}, //11157 #HANGUL SYLLABLE HIEUH EO RIEULTHIEUTH + {0xC24A, 0xD5D6}, //11158 #HANGUL SYLLABLE HIEUH EO RIEULPHIEUPH + {0xC24B, 0xD5D7}, //11159 #HANGUL SYLLABLE HIEUH EO RIEULHIEUH + {0xC24C, 0xD5DA}, //11160 #HANGUL SYLLABLE HIEUH EO PIEUPSIOS + {0xC24D, 0xD5DC}, //11161 #HANGUL SYLLABLE HIEUH EO SSANGSIOS + {0xC24E, 0xD5DE}, //11162 #HANGUL SYLLABLE HIEUH EO CIEUC + {0xC24F, 0xD5DF}, //11163 #HANGUL SYLLABLE HIEUH EO CHIEUCH + {0xC250, 0xD5E0}, //11164 #HANGUL SYLLABLE HIEUH EO KHIEUKH + {0xC251, 0xD5E1}, //11165 #HANGUL SYLLABLE HIEUH EO THIEUTH + {0xC252, 0xD5E2}, //11166 #HANGUL SYLLABLE HIEUH EO PHIEUPH + {0xC253, 0xD5E3}, //11167 #HANGUL SYLLABLE HIEUH EO HIEUH + {0xC254, 0xD5E6}, //11168 #HANGUL SYLLABLE HIEUH E SSANGKIYEOK + {0xC255, 0xD5E7}, //11169 #HANGUL SYLLABLE HIEUH E KIYEOKSIOS + {0xC256, 0xD5E9}, //11170 #HANGUL SYLLABLE HIEUH E NIEUNCIEUC + {0xC257, 0xD5EA}, //11171 #HANGUL SYLLABLE HIEUH E NIEUNHIEUH + {0xC258, 0xD5EB}, //11172 #HANGUL SYLLABLE HIEUH E TIKEUT + {0xC259, 0xD5ED}, //11173 #HANGUL SYLLABLE HIEUH E RIEULKIYEOK + {0xC25A, 0xD5EE}, //11174 #HANGUL SYLLABLE HIEUH E RIEULMIEUM + {0xC261, 0xD5EF}, //11175 #HANGUL SYLLABLE HIEUH E RIEULPIEUP + {0xC262, 0xD5F0}, //11176 #HANGUL SYLLABLE HIEUH E RIEULSIOS + {0xC263, 0xD5F1}, //11177 #HANGUL SYLLABLE HIEUH E RIEULTHIEUTH + {0xC264, 0xD5F2}, //11178 #HANGUL SYLLABLE HIEUH E RIEULPHIEUPH + {0xC265, 0xD5F3}, //11179 #HANGUL SYLLABLE HIEUH E RIEULHIEUH + {0xC266, 0xD5F6}, //11180 #HANGUL SYLLABLE HIEUH E PIEUPSIOS + {0xC267, 0xD5F8}, //11181 #HANGUL SYLLABLE HIEUH E SSANGSIOS + {0xC268, 0xD5FA}, //11182 #HANGUL SYLLABLE HIEUH E CIEUC + {0xC269, 0xD5FB}, //11183 #HANGUL SYLLABLE HIEUH E CHIEUCH + {0xC26A, 0xD5FC}, //11184 #HANGUL SYLLABLE HIEUH E KHIEUKH + {0xC26B, 0xD5FD}, //11185 #HANGUL SYLLABLE HIEUH E THIEUTH + {0xC26C, 0xD5FE}, //11186 #HANGUL SYLLABLE HIEUH E PHIEUPH + {0xC26D, 0xD5FF}, //11187 #HANGUL SYLLABLE HIEUH E HIEUH + {0xC26E, 0xD602}, //11188 #HANGUL SYLLABLE HIEUH YEO SSANGKIYEOK + {0xC26F, 0xD603}, //11189 #HANGUL SYLLABLE HIEUH YEO KIYEOKSIOS + {0xC270, 0xD605}, //11190 #HANGUL SYLLABLE HIEUH YEO NIEUNCIEUC + {0xC271, 0xD606}, //11191 #HANGUL SYLLABLE HIEUH YEO NIEUNHIEUH + {0xC272, 0xD607}, //11192 #HANGUL SYLLABLE HIEUH YEO TIKEUT + {0xC273, 0xD609}, //11193 #HANGUL SYLLABLE HIEUH YEO RIEULKIYEOK + {0xC274, 0xD60A}, //11194 #HANGUL SYLLABLE HIEUH YEO RIEULMIEUM + {0xC275, 0xD60B}, //11195 #HANGUL SYLLABLE HIEUH YEO RIEULPIEUP + {0xC276, 0xD60C}, //11196 #HANGUL SYLLABLE HIEUH YEO RIEULSIOS + {0xC277, 0xD60D}, //11197 #HANGUL SYLLABLE HIEUH YEO RIEULTHIEUTH + {0xC278, 0xD60E}, //11198 #HANGUL SYLLABLE HIEUH YEO RIEULPHIEUPH + {0xC279, 0xD60F}, //11199 #HANGUL SYLLABLE HIEUH YEO RIEULHIEUH + {0xC27A, 0xD612}, //11200 #HANGUL SYLLABLE HIEUH YEO PIEUPSIOS + {0xC281, 0xD616}, //11201 #HANGUL SYLLABLE HIEUH YEO CIEUC + {0xC282, 0xD617}, //11202 #HANGUL SYLLABLE HIEUH YEO CHIEUCH + {0xC283, 0xD618}, //11203 #HANGUL SYLLABLE HIEUH YEO KHIEUKH + {0xC284, 0xD619}, //11204 #HANGUL SYLLABLE HIEUH YEO THIEUTH + {0xC285, 0xD61A}, //11205 #HANGUL SYLLABLE HIEUH YEO PHIEUPH + {0xC286, 0xD61B}, //11206 #HANGUL SYLLABLE HIEUH YEO HIEUH + {0xC287, 0xD61D}, //11207 #HANGUL SYLLABLE HIEUH YE KIYEOK + {0xC288, 0xD61E}, //11208 #HANGUL SYLLABLE HIEUH YE SSANGKIYEOK + {0xC289, 0xD61F}, //11209 #HANGUL SYLLABLE HIEUH YE KIYEOKSIOS + {0xC28A, 0xD621}, //11210 #HANGUL SYLLABLE HIEUH YE NIEUNCIEUC + {0xC28B, 0xD622}, //11211 #HANGUL SYLLABLE HIEUH YE NIEUNHIEUH + {0xC28C, 0xD623}, //11212 #HANGUL SYLLABLE HIEUH YE TIKEUT + {0xC28D, 0xD625}, //11213 #HANGUL SYLLABLE HIEUH YE RIEULKIYEOK + {0xC28E, 0xD626}, //11214 #HANGUL SYLLABLE HIEUH YE RIEULMIEUM + {0xC28F, 0xD627}, //11215 #HANGUL SYLLABLE HIEUH YE RIEULPIEUP + {0xC290, 0xD628}, //11216 #HANGUL SYLLABLE HIEUH YE RIEULSIOS + {0xC291, 0xD629}, //11217 #HANGUL SYLLABLE HIEUH YE RIEULTHIEUTH + {0xC292, 0xD62A}, //11218 #HANGUL SYLLABLE HIEUH YE RIEULPHIEUPH + {0xC293, 0xD62B}, //11219 #HANGUL SYLLABLE HIEUH YE RIEULHIEUH + {0xC294, 0xD62C}, //11220 #HANGUL SYLLABLE HIEUH YE MIEUM + {0xC295, 0xD62E}, //11221 #HANGUL SYLLABLE HIEUH YE PIEUPSIOS + {0xC296, 0xD62F}, //11222 #HANGUL SYLLABLE HIEUH YE SIOS + {0xC297, 0xD630}, //11223 #HANGUL SYLLABLE HIEUH YE SSANGSIOS + {0xC298, 0xD631}, //11224 #HANGUL SYLLABLE HIEUH YE IEUNG + {0xC299, 0xD632}, //11225 #HANGUL SYLLABLE HIEUH YE CIEUC + {0xC29A, 0xD633}, //11226 #HANGUL SYLLABLE HIEUH YE CHIEUCH + {0xC29B, 0xD634}, //11227 #HANGUL SYLLABLE HIEUH YE KHIEUKH + {0xC29C, 0xD635}, //11228 #HANGUL SYLLABLE HIEUH YE THIEUTH + {0xC29D, 0xD636}, //11229 #HANGUL SYLLABLE HIEUH YE PHIEUPH + {0xC29E, 0xD637}, //11230 #HANGUL SYLLABLE HIEUH YE HIEUH + {0xC29F, 0xD63A}, //11231 #HANGUL SYLLABLE HIEUH O SSANGKIYEOK + {0xC2A0, 0xD63B}, //11232 #HANGUL SYLLABLE HIEUH O KIYEOKSIOS + {0xC2A1, 0xC9D5}, //11233 #HANGUL SYLLABLE CIEUC I IEUNG + {0xC2A2, 0xC9D6}, //11234 #HANGUL SYLLABLE CIEUC I CIEUC + {0xC2A3, 0xC9D9}, //11235 #HANGUL SYLLABLE CIEUC I THIEUTH + {0xC2A4, 0xC9DA}, //11236 #HANGUL SYLLABLE CIEUC I PHIEUPH + {0xC2A5, 0xC9DC}, //11237 #HANGUL SYLLABLE SSANGCIEUC A + {0xC2A6, 0xC9DD}, //11238 #HANGUL SYLLABLE SSANGCIEUC A KIYEOK + {0xC2A7, 0xC9E0}, //11239 #HANGUL SYLLABLE SSANGCIEUC A NIEUN + {0xC2A8, 0xC9E2}, //11240 #HANGUL SYLLABLE SSANGCIEUC A NIEUNHIEUH + {0xC2A9, 0xC9E4}, //11241 #HANGUL SYLLABLE SSANGCIEUC A RIEUL + {0xC2AA, 0xC9E7}, //11242 #HANGUL SYLLABLE SSANGCIEUC A RIEULPIEUP + {0xC2AB, 0xC9EC}, //11243 #HANGUL SYLLABLE SSANGCIEUC A MIEUM + {0xC2AC, 0xC9ED}, //11244 #HANGUL SYLLABLE SSANGCIEUC A PIEUP + {0xC2AD, 0xC9EF}, //11245 #HANGUL SYLLABLE SSANGCIEUC A SIOS + {0xC2AE, 0xC9F0}, //11246 #HANGUL SYLLABLE SSANGCIEUC A SSANGSIOS + {0xC2AF, 0xC9F1}, //11247 #HANGUL SYLLABLE SSANGCIEUC A IEUNG + {0xC2B0, 0xC9F8}, //11248 #HANGUL SYLLABLE SSANGCIEUC AE + {0xC2B1, 0xC9F9}, //11249 #HANGUL SYLLABLE SSANGCIEUC AE KIYEOK + {0xC2B2, 0xC9FC}, //11250 #HANGUL SYLLABLE SSANGCIEUC AE NIEUN + {0xC2B3, 0xCA00}, //11251 #HANGUL SYLLABLE SSANGCIEUC AE RIEUL + {0xC2B4, 0xCA08}, //11252 #HANGUL SYLLABLE SSANGCIEUC AE MIEUM + {0xC2B5, 0xCA09}, //11253 #HANGUL SYLLABLE SSANGCIEUC AE PIEUP + {0xC2B6, 0xCA0B}, //11254 #HANGUL SYLLABLE SSANGCIEUC AE SIOS + {0xC2B7, 0xCA0C}, //11255 #HANGUL SYLLABLE SSANGCIEUC AE SSANGSIOS + {0xC2B8, 0xCA0D}, //11256 #HANGUL SYLLABLE SSANGCIEUC AE IEUNG + {0xC2B9, 0xCA14}, //11257 #HANGUL SYLLABLE SSANGCIEUC YA + {0xC2BA, 0xCA18}, //11258 #HANGUL SYLLABLE SSANGCIEUC YA NIEUN + {0xC2BB, 0xCA29}, //11259 #HANGUL SYLLABLE SSANGCIEUC YA IEUNG + {0xC2BC, 0xCA4C}, //11260 #HANGUL SYLLABLE SSANGCIEUC EO + {0xC2BD, 0xCA4D}, //11261 #HANGUL SYLLABLE SSANGCIEUC EO KIYEOK + {0xC2BE, 0xCA50}, //11262 #HANGUL SYLLABLE SSANGCIEUC EO NIEUN + {0xC2BF, 0xCA54}, //11263 #HANGUL SYLLABLE SSANGCIEUC EO RIEUL + {0xC2C0, 0xCA5C}, //11264 #HANGUL SYLLABLE SSANGCIEUC EO MIEUM + {0xC2C1, 0xCA5D}, //11265 #HANGUL SYLLABLE SSANGCIEUC EO PIEUP + {0xC2C2, 0xCA5F}, //11266 #HANGUL SYLLABLE SSANGCIEUC EO SIOS + {0xC2C3, 0xCA60}, //11267 #HANGUL SYLLABLE SSANGCIEUC EO SSANGSIOS + {0xC2C4, 0xCA61}, //11268 #HANGUL SYLLABLE SSANGCIEUC EO IEUNG + {0xC2C5, 0xCA68}, //11269 #HANGUL SYLLABLE SSANGCIEUC E + {0xC2C6, 0xCA7D}, //11270 #HANGUL SYLLABLE SSANGCIEUC E IEUNG + {0xC2C7, 0xCA84}, //11271 #HANGUL SYLLABLE SSANGCIEUC YEO + {0xC2C8, 0xCA98}, //11272 #HANGUL SYLLABLE SSANGCIEUC YEO SSANGSIOS + {0xC2C9, 0xCABC}, //11273 #HANGUL SYLLABLE SSANGCIEUC O + {0xC2CA, 0xCABD}, //11274 #HANGUL SYLLABLE SSANGCIEUC O KIYEOK + {0xC2CB, 0xCAC0}, //11275 #HANGUL SYLLABLE SSANGCIEUC O NIEUN + {0xC2CC, 0xCAC4}, //11276 #HANGUL SYLLABLE SSANGCIEUC O RIEUL + {0xC2CD, 0xCACC}, //11277 #HANGUL SYLLABLE SSANGCIEUC O MIEUM + {0xC2CE, 0xCACD}, //11278 #HANGUL SYLLABLE SSANGCIEUC O PIEUP + {0xC2CF, 0xCACF}, //11279 #HANGUL SYLLABLE SSANGCIEUC O SIOS + {0xC2D0, 0xCAD1}, //11280 #HANGUL SYLLABLE SSANGCIEUC O IEUNG + {0xC2D1, 0xCAD3}, //11281 #HANGUL SYLLABLE SSANGCIEUC O CHIEUCH + {0xC2D2, 0xCAD8}, //11282 #HANGUL SYLLABLE SSANGCIEUC WA + {0xC2D3, 0xCAD9}, //11283 #HANGUL SYLLABLE SSANGCIEUC WA KIYEOK + {0xC2D4, 0xCAE0}, //11284 #HANGUL SYLLABLE SSANGCIEUC WA RIEUL + {0xC2D5, 0xCAEC}, //11285 #HANGUL SYLLABLE SSANGCIEUC WA SSANGSIOS + {0xC2D6, 0xCAF4}, //11286 #HANGUL SYLLABLE SSANGCIEUC WAE + {0xC2D7, 0xCB08}, //11287 #HANGUL SYLLABLE SSANGCIEUC WAE SSANGSIOS + {0xC2D8, 0xCB10}, //11288 #HANGUL SYLLABLE SSANGCIEUC OE + {0xC2D9, 0xCB14}, //11289 #HANGUL SYLLABLE SSANGCIEUC OE NIEUN + {0xC2DA, 0xCB18}, //11290 #HANGUL SYLLABLE SSANGCIEUC OE RIEUL + {0xC2DB, 0xCB20}, //11291 #HANGUL SYLLABLE SSANGCIEUC OE MIEUM + {0xC2DC, 0xCB21}, //11292 #HANGUL SYLLABLE SSANGCIEUC OE PIEUP + {0xC2DD, 0xCB41}, //11293 #HANGUL SYLLABLE SSANGCIEUC YO IEUNG + {0xC2DE, 0xCB48}, //11294 #HANGUL SYLLABLE SSANGCIEUC U + {0xC2DF, 0xCB49}, //11295 #HANGUL SYLLABLE SSANGCIEUC U KIYEOK + {0xC2E0, 0xCB4C}, //11296 #HANGUL SYLLABLE SSANGCIEUC U NIEUN + {0xC2E1, 0xCB50}, //11297 #HANGUL SYLLABLE SSANGCIEUC U RIEUL + {0xC2E2, 0xCB58}, //11298 #HANGUL SYLLABLE SSANGCIEUC U MIEUM + {0xC2E3, 0xCB59}, //11299 #HANGUL SYLLABLE SSANGCIEUC U PIEUP + {0xC2E4, 0xCB5D}, //11300 #HANGUL SYLLABLE SSANGCIEUC U IEUNG + {0xC2E5, 0xCB64}, //11301 #HANGUL SYLLABLE SSANGCIEUC WEO + {0xC2E6, 0xCB78}, //11302 #HANGUL SYLLABLE SSANGCIEUC WEO SSANGSIOS + {0xC2E7, 0xCB79}, //11303 #HANGUL SYLLABLE SSANGCIEUC WEO IEUNG + {0xC2E8, 0xCB9C}, //11304 #HANGUL SYLLABLE SSANGCIEUC WI + {0xC2E9, 0xCBB8}, //11305 #HANGUL SYLLABLE SSANGCIEUC YU + {0xC2EA, 0xCBD4}, //11306 #HANGUL SYLLABLE SSANGCIEUC EU + {0xC2EB, 0xCBE4}, //11307 #HANGUL SYLLABLE SSANGCIEUC EU MIEUM + {0xC2EC, 0xCBE7}, //11308 #HANGUL SYLLABLE SSANGCIEUC EU SIOS + {0xC2ED, 0xCBE9}, //11309 #HANGUL SYLLABLE SSANGCIEUC EU IEUNG + {0xC2EE, 0xCC0C}, //11310 #HANGUL SYLLABLE SSANGCIEUC I + {0xC2EF, 0xCC0D}, //11311 #HANGUL SYLLABLE SSANGCIEUC I KIYEOK + {0xC2F0, 0xCC10}, //11312 #HANGUL SYLLABLE SSANGCIEUC I NIEUN + {0xC2F1, 0xCC14}, //11313 #HANGUL SYLLABLE SSANGCIEUC I RIEUL + {0xC2F2, 0xCC1C}, //11314 #HANGUL SYLLABLE SSANGCIEUC I MIEUM + {0xC2F3, 0xCC1D}, //11315 #HANGUL SYLLABLE SSANGCIEUC I PIEUP + {0xC2F4, 0xCC21}, //11316 #HANGUL SYLLABLE SSANGCIEUC I IEUNG + {0xC2F5, 0xCC22}, //11317 #HANGUL SYLLABLE SSANGCIEUC I CIEUC + {0xC2F6, 0xCC27}, //11318 #HANGUL SYLLABLE SSANGCIEUC I HIEUH + {0xC2F7, 0xCC28}, //11319 #HANGUL SYLLABLE CHIEUCH A + {0xC2F8, 0xCC29}, //11320 #HANGUL SYLLABLE CHIEUCH A KIYEOK + {0xC2F9, 0xCC2C}, //11321 #HANGUL SYLLABLE CHIEUCH A NIEUN + {0xC2FA, 0xCC2E}, //11322 #HANGUL SYLLABLE CHIEUCH A NIEUNHIEUH + {0xC2FB, 0xCC30}, //11323 #HANGUL SYLLABLE CHIEUCH A RIEUL + {0xC2FC, 0xCC38}, //11324 #HANGUL SYLLABLE CHIEUCH A MIEUM + {0xC2FD, 0xCC39}, //11325 #HANGUL SYLLABLE CHIEUCH A PIEUP + {0xC2FE, 0xCC3B}, //11326 #HANGUL SYLLABLE CHIEUCH A SIOS + {0xC341, 0xD63D}, //11327 #HANGUL SYLLABLE HIEUH O NIEUNCIEUC + {0xC342, 0xD63E}, //11328 #HANGUL SYLLABLE HIEUH O NIEUNHIEUH + {0xC343, 0xD63F}, //11329 #HANGUL SYLLABLE HIEUH O TIKEUT + {0xC344, 0xD641}, //11330 #HANGUL SYLLABLE HIEUH O RIEULKIYEOK + {0xC345, 0xD642}, //11331 #HANGUL SYLLABLE HIEUH O RIEULMIEUM + {0xC346, 0xD643}, //11332 #HANGUL SYLLABLE HIEUH O RIEULPIEUP + {0xC347, 0xD644}, //11333 #HANGUL SYLLABLE HIEUH O RIEULSIOS + {0xC348, 0xD646}, //11334 #HANGUL SYLLABLE HIEUH O RIEULPHIEUPH + {0xC349, 0xD647}, //11335 #HANGUL SYLLABLE HIEUH O RIEULHIEUH + {0xC34A, 0xD64A}, //11336 #HANGUL SYLLABLE HIEUH O PIEUPSIOS + {0xC34B, 0xD64C}, //11337 #HANGUL SYLLABLE HIEUH O SSANGSIOS + {0xC34C, 0xD64E}, //11338 #HANGUL SYLLABLE HIEUH O CIEUC + {0xC34D, 0xD64F}, //11339 #HANGUL SYLLABLE HIEUH O CHIEUCH + {0xC34E, 0xD650}, //11340 #HANGUL SYLLABLE HIEUH O KHIEUKH + {0xC34F, 0xD652}, //11341 #HANGUL SYLLABLE HIEUH O PHIEUPH + {0xC350, 0xD653}, //11342 #HANGUL SYLLABLE HIEUH O HIEUH + {0xC351, 0xD656}, //11343 #HANGUL SYLLABLE HIEUH WA SSANGKIYEOK + {0xC352, 0xD657}, //11344 #HANGUL SYLLABLE HIEUH WA KIYEOKSIOS + {0xC353, 0xD659}, //11345 #HANGUL SYLLABLE HIEUH WA NIEUNCIEUC + {0xC354, 0xD65A}, //11346 #HANGUL SYLLABLE HIEUH WA NIEUNHIEUH + {0xC355, 0xD65B}, //11347 #HANGUL SYLLABLE HIEUH WA TIKEUT + {0xC356, 0xD65D}, //11348 #HANGUL SYLLABLE HIEUH WA RIEULKIYEOK + {0xC357, 0xD65E}, //11349 #HANGUL SYLLABLE HIEUH WA RIEULMIEUM + {0xC358, 0xD65F}, //11350 #HANGUL SYLLABLE HIEUH WA RIEULPIEUP + {0xC359, 0xD660}, //11351 #HANGUL SYLLABLE HIEUH WA RIEULSIOS + {0xC35A, 0xD661}, //11352 #HANGUL SYLLABLE HIEUH WA RIEULTHIEUTH + {0xC361, 0xD662}, //11353 #HANGUL SYLLABLE HIEUH WA RIEULPHIEUPH + {0xC362, 0xD663}, //11354 #HANGUL SYLLABLE HIEUH WA RIEULHIEUH + {0xC363, 0xD664}, //11355 #HANGUL SYLLABLE HIEUH WA MIEUM + {0xC364, 0xD665}, //11356 #HANGUL SYLLABLE HIEUH WA PIEUP + {0xC365, 0xD666}, //11357 #HANGUL SYLLABLE HIEUH WA PIEUPSIOS + {0xC366, 0xD668}, //11358 #HANGUL SYLLABLE HIEUH WA SSANGSIOS + {0xC367, 0xD66A}, //11359 #HANGUL SYLLABLE HIEUH WA CIEUC + {0xC368, 0xD66B}, //11360 #HANGUL SYLLABLE HIEUH WA CHIEUCH + {0xC369, 0xD66C}, //11361 #HANGUL SYLLABLE HIEUH WA KHIEUKH + {0xC36A, 0xD66D}, //11362 #HANGUL SYLLABLE HIEUH WA THIEUTH + {0xC36B, 0xD66E}, //11363 #HANGUL SYLLABLE HIEUH WA PHIEUPH + {0xC36C, 0xD66F}, //11364 #HANGUL SYLLABLE HIEUH WA HIEUH + {0xC36D, 0xD672}, //11365 #HANGUL SYLLABLE HIEUH WAE SSANGKIYEOK + {0xC36E, 0xD673}, //11366 #HANGUL SYLLABLE HIEUH WAE KIYEOKSIOS + {0xC36F, 0xD675}, //11367 #HANGUL SYLLABLE HIEUH WAE NIEUNCIEUC + {0xC370, 0xD676}, //11368 #HANGUL SYLLABLE HIEUH WAE NIEUNHIEUH + {0xC371, 0xD677}, //11369 #HANGUL SYLLABLE HIEUH WAE TIKEUT + {0xC372, 0xD678}, //11370 #HANGUL SYLLABLE HIEUH WAE RIEUL + {0xC373, 0xD679}, //11371 #HANGUL SYLLABLE HIEUH WAE RIEULKIYEOK + {0xC374, 0xD67A}, //11372 #HANGUL SYLLABLE HIEUH WAE RIEULMIEUM + {0xC375, 0xD67B}, //11373 #HANGUL SYLLABLE HIEUH WAE RIEULPIEUP + {0xC376, 0xD67C}, //11374 #HANGUL SYLLABLE HIEUH WAE RIEULSIOS + {0xC377, 0xD67D}, //11375 #HANGUL SYLLABLE HIEUH WAE RIEULTHIEUTH + {0xC378, 0xD67E}, //11376 #HANGUL SYLLABLE HIEUH WAE RIEULPHIEUPH + {0xC379, 0xD67F}, //11377 #HANGUL SYLLABLE HIEUH WAE RIEULHIEUH + {0xC37A, 0xD680}, //11378 #HANGUL SYLLABLE HIEUH WAE MIEUM + {0xC381, 0xD681}, //11379 #HANGUL SYLLABLE HIEUH WAE PIEUP + {0xC382, 0xD682}, //11380 #HANGUL SYLLABLE HIEUH WAE PIEUPSIOS + {0xC383, 0xD684}, //11381 #HANGUL SYLLABLE HIEUH WAE SSANGSIOS + {0xC384, 0xD686}, //11382 #HANGUL SYLLABLE HIEUH WAE CIEUC + {0xC385, 0xD687}, //11383 #HANGUL SYLLABLE HIEUH WAE CHIEUCH + {0xC386, 0xD688}, //11384 #HANGUL SYLLABLE HIEUH WAE KHIEUKH + {0xC387, 0xD689}, //11385 #HANGUL SYLLABLE HIEUH WAE THIEUTH + {0xC388, 0xD68A}, //11386 #HANGUL SYLLABLE HIEUH WAE PHIEUPH + {0xC389, 0xD68B}, //11387 #HANGUL SYLLABLE HIEUH WAE HIEUH + {0xC38A, 0xD68E}, //11388 #HANGUL SYLLABLE HIEUH OE SSANGKIYEOK + {0xC38B, 0xD68F}, //11389 #HANGUL SYLLABLE HIEUH OE KIYEOKSIOS + {0xC38C, 0xD691}, //11390 #HANGUL SYLLABLE HIEUH OE NIEUNCIEUC + {0xC38D, 0xD692}, //11391 #HANGUL SYLLABLE HIEUH OE NIEUNHIEUH + {0xC38E, 0xD693}, //11392 #HANGUL SYLLABLE HIEUH OE TIKEUT + {0xC38F, 0xD695}, //11393 #HANGUL SYLLABLE HIEUH OE RIEULKIYEOK + {0xC390, 0xD696}, //11394 #HANGUL SYLLABLE HIEUH OE RIEULMIEUM + {0xC391, 0xD697}, //11395 #HANGUL SYLLABLE HIEUH OE RIEULPIEUP + {0xC392, 0xD698}, //11396 #HANGUL SYLLABLE HIEUH OE RIEULSIOS + {0xC393, 0xD699}, //11397 #HANGUL SYLLABLE HIEUH OE RIEULTHIEUTH + {0xC394, 0xD69A}, //11398 #HANGUL SYLLABLE HIEUH OE RIEULPHIEUPH + {0xC395, 0xD69B}, //11399 #HANGUL SYLLABLE HIEUH OE RIEULHIEUH + {0xC396, 0xD69C}, //11400 #HANGUL SYLLABLE HIEUH OE MIEUM + {0xC397, 0xD69E}, //11401 #HANGUL SYLLABLE HIEUH OE PIEUPSIOS + {0xC398, 0xD6A0}, //11402 #HANGUL SYLLABLE HIEUH OE SSANGSIOS + {0xC399, 0xD6A2}, //11403 #HANGUL SYLLABLE HIEUH OE CIEUC + {0xC39A, 0xD6A3}, //11404 #HANGUL SYLLABLE HIEUH OE CHIEUCH + {0xC39B, 0xD6A4}, //11405 #HANGUL SYLLABLE HIEUH OE KHIEUKH + {0xC39C, 0xD6A5}, //11406 #HANGUL SYLLABLE HIEUH OE THIEUTH + {0xC39D, 0xD6A6}, //11407 #HANGUL SYLLABLE HIEUH OE PHIEUPH + {0xC39E, 0xD6A7}, //11408 #HANGUL SYLLABLE HIEUH OE HIEUH + {0xC39F, 0xD6A9}, //11409 #HANGUL SYLLABLE HIEUH YO KIYEOK + {0xC3A0, 0xD6AA}, //11410 #HANGUL SYLLABLE HIEUH YO SSANGKIYEOK + {0xC3A1, 0xCC3C}, //11411 #HANGUL SYLLABLE CHIEUCH A SSANGSIOS + {0xC3A2, 0xCC3D}, //11412 #HANGUL SYLLABLE CHIEUCH A IEUNG + {0xC3A3, 0xCC3E}, //11413 #HANGUL SYLLABLE CHIEUCH A CIEUC + {0xC3A4, 0xCC44}, //11414 #HANGUL SYLLABLE CHIEUCH AE + {0xC3A5, 0xCC45}, //11415 #HANGUL SYLLABLE CHIEUCH AE KIYEOK + {0xC3A6, 0xCC48}, //11416 #HANGUL SYLLABLE CHIEUCH AE NIEUN + {0xC3A7, 0xCC4C}, //11417 #HANGUL SYLLABLE CHIEUCH AE RIEUL + {0xC3A8, 0xCC54}, //11418 #HANGUL SYLLABLE CHIEUCH AE MIEUM + {0xC3A9, 0xCC55}, //11419 #HANGUL SYLLABLE CHIEUCH AE PIEUP + {0xC3AA, 0xCC57}, //11420 #HANGUL SYLLABLE CHIEUCH AE SIOS + {0xC3AB, 0xCC58}, //11421 #HANGUL SYLLABLE CHIEUCH AE SSANGSIOS + {0xC3AC, 0xCC59}, //11422 #HANGUL SYLLABLE CHIEUCH AE IEUNG + {0xC3AD, 0xCC60}, //11423 #HANGUL SYLLABLE CHIEUCH YA + {0xC3AE, 0xCC64}, //11424 #HANGUL SYLLABLE CHIEUCH YA NIEUN + {0xC3AF, 0xCC66}, //11425 #HANGUL SYLLABLE CHIEUCH YA NIEUNHIEUH + {0xC3B0, 0xCC68}, //11426 #HANGUL SYLLABLE CHIEUCH YA RIEUL + {0xC3B1, 0xCC70}, //11427 #HANGUL SYLLABLE CHIEUCH YA MIEUM + {0xC3B2, 0xCC75}, //11428 #HANGUL SYLLABLE CHIEUCH YA IEUNG + {0xC3B3, 0xCC98}, //11429 #HANGUL SYLLABLE CHIEUCH EO + {0xC3B4, 0xCC99}, //11430 #HANGUL SYLLABLE CHIEUCH EO KIYEOK + {0xC3B5, 0xCC9C}, //11431 #HANGUL SYLLABLE CHIEUCH EO NIEUN + {0xC3B6, 0xCCA0}, //11432 #HANGUL SYLLABLE CHIEUCH EO RIEUL + {0xC3B7, 0xCCA8}, //11433 #HANGUL SYLLABLE CHIEUCH EO MIEUM + {0xC3B8, 0xCCA9}, //11434 #HANGUL SYLLABLE CHIEUCH EO PIEUP + {0xC3B9, 0xCCAB}, //11435 #HANGUL SYLLABLE CHIEUCH EO SIOS + {0xC3BA, 0xCCAC}, //11436 #HANGUL SYLLABLE CHIEUCH EO SSANGSIOS + {0xC3BB, 0xCCAD}, //11437 #HANGUL SYLLABLE CHIEUCH EO IEUNG + {0xC3BC, 0xCCB4}, //11438 #HANGUL SYLLABLE CHIEUCH E + {0xC3BD, 0xCCB5}, //11439 #HANGUL SYLLABLE CHIEUCH E KIYEOK + {0xC3BE, 0xCCB8}, //11440 #HANGUL SYLLABLE CHIEUCH E NIEUN + {0xC3BF, 0xCCBC}, //11441 #HANGUL SYLLABLE CHIEUCH E RIEUL + {0xC3C0, 0xCCC4}, //11442 #HANGUL SYLLABLE CHIEUCH E MIEUM + {0xC3C1, 0xCCC5}, //11443 #HANGUL SYLLABLE CHIEUCH E PIEUP + {0xC3C2, 0xCCC7}, //11444 #HANGUL SYLLABLE CHIEUCH E SIOS + {0xC3C3, 0xCCC9}, //11445 #HANGUL SYLLABLE CHIEUCH E IEUNG + {0xC3C4, 0xCCD0}, //11446 #HANGUL SYLLABLE CHIEUCH YEO + {0xC3C5, 0xCCD4}, //11447 #HANGUL SYLLABLE CHIEUCH YEO NIEUN + {0xC3C6, 0xCCE4}, //11448 #HANGUL SYLLABLE CHIEUCH YEO SSANGSIOS + {0xC3C7, 0xCCEC}, //11449 #HANGUL SYLLABLE CHIEUCH YE + {0xC3C8, 0xCCF0}, //11450 #HANGUL SYLLABLE CHIEUCH YE NIEUN + {0xC3C9, 0xCD01}, //11451 #HANGUL SYLLABLE CHIEUCH YE IEUNG + {0xC3CA, 0xCD08}, //11452 #HANGUL SYLLABLE CHIEUCH O + {0xC3CB, 0xCD09}, //11453 #HANGUL SYLLABLE CHIEUCH O KIYEOK + {0xC3CC, 0xCD0C}, //11454 #HANGUL SYLLABLE CHIEUCH O NIEUN + {0xC3CD, 0xCD10}, //11455 #HANGUL SYLLABLE CHIEUCH O RIEUL + {0xC3CE, 0xCD18}, //11456 #HANGUL SYLLABLE CHIEUCH O MIEUM + {0xC3CF, 0xCD19}, //11457 #HANGUL SYLLABLE CHIEUCH O PIEUP + {0xC3D0, 0xCD1B}, //11458 #HANGUL SYLLABLE CHIEUCH O SIOS + {0xC3D1, 0xCD1D}, //11459 #HANGUL SYLLABLE CHIEUCH O IEUNG + {0xC3D2, 0xCD24}, //11460 #HANGUL SYLLABLE CHIEUCH WA + {0xC3D3, 0xCD28}, //11461 #HANGUL SYLLABLE CHIEUCH WA NIEUN + {0xC3D4, 0xCD2C}, //11462 #HANGUL SYLLABLE CHIEUCH WA RIEUL + {0xC3D5, 0xCD39}, //11463 #HANGUL SYLLABLE CHIEUCH WA IEUNG + {0xC3D6, 0xCD5C}, //11464 #HANGUL SYLLABLE CHIEUCH OE + {0xC3D7, 0xCD60}, //11465 #HANGUL SYLLABLE CHIEUCH OE NIEUN + {0xC3D8, 0xCD64}, //11466 #HANGUL SYLLABLE CHIEUCH OE RIEUL + {0xC3D9, 0xCD6C}, //11467 #HANGUL SYLLABLE CHIEUCH OE MIEUM + {0xC3DA, 0xCD6D}, //11468 #HANGUL SYLLABLE CHIEUCH OE PIEUP + {0xC3DB, 0xCD6F}, //11469 #HANGUL SYLLABLE CHIEUCH OE SIOS + {0xC3DC, 0xCD71}, //11470 #HANGUL SYLLABLE CHIEUCH OE IEUNG + {0xC3DD, 0xCD78}, //11471 #HANGUL SYLLABLE CHIEUCH YO + {0xC3DE, 0xCD88}, //11472 #HANGUL SYLLABLE CHIEUCH YO MIEUM + {0xC3DF, 0xCD94}, //11473 #HANGUL SYLLABLE CHIEUCH U + {0xC3E0, 0xCD95}, //11474 #HANGUL SYLLABLE CHIEUCH U KIYEOK + {0xC3E1, 0xCD98}, //11475 #HANGUL SYLLABLE CHIEUCH U NIEUN + {0xC3E2, 0xCD9C}, //11476 #HANGUL SYLLABLE CHIEUCH U RIEUL + {0xC3E3, 0xCDA4}, //11477 #HANGUL SYLLABLE CHIEUCH U MIEUM + {0xC3E4, 0xCDA5}, //11478 #HANGUL SYLLABLE CHIEUCH U PIEUP + {0xC3E5, 0xCDA7}, //11479 #HANGUL SYLLABLE CHIEUCH U SIOS + {0xC3E6, 0xCDA9}, //11480 #HANGUL SYLLABLE CHIEUCH U IEUNG + {0xC3E7, 0xCDB0}, //11481 #HANGUL SYLLABLE CHIEUCH WEO + {0xC3E8, 0xCDC4}, //11482 #HANGUL SYLLABLE CHIEUCH WEO SSANGSIOS + {0xC3E9, 0xCDCC}, //11483 #HANGUL SYLLABLE CHIEUCH WE + {0xC3EA, 0xCDD0}, //11484 #HANGUL SYLLABLE CHIEUCH WE NIEUN + {0xC3EB, 0xCDE8}, //11485 #HANGUL SYLLABLE CHIEUCH WI + {0xC3EC, 0xCDEC}, //11486 #HANGUL SYLLABLE CHIEUCH WI NIEUN + {0xC3ED, 0xCDF0}, //11487 #HANGUL SYLLABLE CHIEUCH WI RIEUL + {0xC3EE, 0xCDF8}, //11488 #HANGUL SYLLABLE CHIEUCH WI MIEUM + {0xC3EF, 0xCDF9}, //11489 #HANGUL SYLLABLE CHIEUCH WI PIEUP + {0xC3F0, 0xCDFB}, //11490 #HANGUL SYLLABLE CHIEUCH WI SIOS + {0xC3F1, 0xCDFD}, //11491 #HANGUL SYLLABLE CHIEUCH WI IEUNG + {0xC3F2, 0xCE04}, //11492 #HANGUL SYLLABLE CHIEUCH YU + {0xC3F3, 0xCE08}, //11493 #HANGUL SYLLABLE CHIEUCH YU NIEUN + {0xC3F4, 0xCE0C}, //11494 #HANGUL SYLLABLE CHIEUCH YU RIEUL + {0xC3F5, 0xCE14}, //11495 #HANGUL SYLLABLE CHIEUCH YU MIEUM + {0xC3F6, 0xCE19}, //11496 #HANGUL SYLLABLE CHIEUCH YU IEUNG + {0xC3F7, 0xCE20}, //11497 #HANGUL SYLLABLE CHIEUCH EU + {0xC3F8, 0xCE21}, //11498 #HANGUL SYLLABLE CHIEUCH EU KIYEOK + {0xC3F9, 0xCE24}, //11499 #HANGUL SYLLABLE CHIEUCH EU NIEUN + {0xC3FA, 0xCE28}, //11500 #HANGUL SYLLABLE CHIEUCH EU RIEUL + {0xC3FB, 0xCE30}, //11501 #HANGUL SYLLABLE CHIEUCH EU MIEUM + {0xC3FC, 0xCE31}, //11502 #HANGUL SYLLABLE CHIEUCH EU PIEUP + {0xC3FD, 0xCE33}, //11503 #HANGUL SYLLABLE CHIEUCH EU SIOS + {0xC3FE, 0xCE35}, //11504 #HANGUL SYLLABLE CHIEUCH EU IEUNG + {0xC441, 0xD6AB}, //11505 #HANGUL SYLLABLE HIEUH YO KIYEOKSIOS + {0xC442, 0xD6AD}, //11506 #HANGUL SYLLABLE HIEUH YO NIEUNCIEUC + {0xC443, 0xD6AE}, //11507 #HANGUL SYLLABLE HIEUH YO NIEUNHIEUH + {0xC444, 0xD6AF}, //11508 #HANGUL SYLLABLE HIEUH YO TIKEUT + {0xC445, 0xD6B1}, //11509 #HANGUL SYLLABLE HIEUH YO RIEULKIYEOK + {0xC446, 0xD6B2}, //11510 #HANGUL SYLLABLE HIEUH YO RIEULMIEUM + {0xC447, 0xD6B3}, //11511 #HANGUL SYLLABLE HIEUH YO RIEULPIEUP + {0xC448, 0xD6B4}, //11512 #HANGUL SYLLABLE HIEUH YO RIEULSIOS + {0xC449, 0xD6B5}, //11513 #HANGUL SYLLABLE HIEUH YO RIEULTHIEUTH + {0xC44A, 0xD6B6}, //11514 #HANGUL SYLLABLE HIEUH YO RIEULPHIEUPH + {0xC44B, 0xD6B7}, //11515 #HANGUL SYLLABLE HIEUH YO RIEULHIEUH + {0xC44C, 0xD6B8}, //11516 #HANGUL SYLLABLE HIEUH YO MIEUM + {0xC44D, 0xD6BA}, //11517 #HANGUL SYLLABLE HIEUH YO PIEUPSIOS + {0xC44E, 0xD6BC}, //11518 #HANGUL SYLLABLE HIEUH YO SSANGSIOS + {0xC44F, 0xD6BD}, //11519 #HANGUL SYLLABLE HIEUH YO IEUNG + {0xC450, 0xD6BE}, //11520 #HANGUL SYLLABLE HIEUH YO CIEUC + {0xC451, 0xD6BF}, //11521 #HANGUL SYLLABLE HIEUH YO CHIEUCH + {0xC452, 0xD6C0}, //11522 #HANGUL SYLLABLE HIEUH YO KHIEUKH + {0xC453, 0xD6C1}, //11523 #HANGUL SYLLABLE HIEUH YO THIEUTH + {0xC454, 0xD6C2}, //11524 #HANGUL SYLLABLE HIEUH YO PHIEUPH + {0xC455, 0xD6C3}, //11525 #HANGUL SYLLABLE HIEUH YO HIEUH + {0xC456, 0xD6C6}, //11526 #HANGUL SYLLABLE HIEUH U SSANGKIYEOK + {0xC457, 0xD6C7}, //11527 #HANGUL SYLLABLE HIEUH U KIYEOKSIOS + {0xC458, 0xD6C9}, //11528 #HANGUL SYLLABLE HIEUH U NIEUNCIEUC + {0xC459, 0xD6CA}, //11529 #HANGUL SYLLABLE HIEUH U NIEUNHIEUH + {0xC45A, 0xD6CB}, //11530 #HANGUL SYLLABLE HIEUH U TIKEUT + {0xC461, 0xD6CD}, //11531 #HANGUL SYLLABLE HIEUH U RIEULKIYEOK + {0xC462, 0xD6CE}, //11532 #HANGUL SYLLABLE HIEUH U RIEULMIEUM + {0xC463, 0xD6CF}, //11533 #HANGUL SYLLABLE HIEUH U RIEULPIEUP + {0xC464, 0xD6D0}, //11534 #HANGUL SYLLABLE HIEUH U RIEULSIOS + {0xC465, 0xD6D2}, //11535 #HANGUL SYLLABLE HIEUH U RIEULPHIEUPH + {0xC466, 0xD6D3}, //11536 #HANGUL SYLLABLE HIEUH U RIEULHIEUH + {0xC467, 0xD6D5}, //11537 #HANGUL SYLLABLE HIEUH U PIEUP + {0xC468, 0xD6D6}, //11538 #HANGUL SYLLABLE HIEUH U PIEUPSIOS + {0xC469, 0xD6D8}, //11539 #HANGUL SYLLABLE HIEUH U SSANGSIOS + {0xC46A, 0xD6DA}, //11540 #HANGUL SYLLABLE HIEUH U CIEUC + {0xC46B, 0xD6DB}, //11541 #HANGUL SYLLABLE HIEUH U CHIEUCH + {0xC46C, 0xD6DC}, //11542 #HANGUL SYLLABLE HIEUH U KHIEUKH + {0xC46D, 0xD6DD}, //11543 #HANGUL SYLLABLE HIEUH U THIEUTH + {0xC46E, 0xD6DE}, //11544 #HANGUL SYLLABLE HIEUH U PHIEUPH + {0xC46F, 0xD6DF}, //11545 #HANGUL SYLLABLE HIEUH U HIEUH + {0xC470, 0xD6E1}, //11546 #HANGUL SYLLABLE HIEUH WEO KIYEOK + {0xC471, 0xD6E2}, //11547 #HANGUL SYLLABLE HIEUH WEO SSANGKIYEOK + {0xC472, 0xD6E3}, //11548 #HANGUL SYLLABLE HIEUH WEO KIYEOKSIOS + {0xC473, 0xD6E5}, //11549 #HANGUL SYLLABLE HIEUH WEO NIEUNCIEUC + {0xC474, 0xD6E6}, //11550 #HANGUL SYLLABLE HIEUH WEO NIEUNHIEUH + {0xC475, 0xD6E7}, //11551 #HANGUL SYLLABLE HIEUH WEO TIKEUT + {0xC476, 0xD6E9}, //11552 #HANGUL SYLLABLE HIEUH WEO RIEULKIYEOK + {0xC477, 0xD6EA}, //11553 #HANGUL SYLLABLE HIEUH WEO RIEULMIEUM + {0xC478, 0xD6EB}, //11554 #HANGUL SYLLABLE HIEUH WEO RIEULPIEUP + {0xC479, 0xD6EC}, //11555 #HANGUL SYLLABLE HIEUH WEO RIEULSIOS + {0xC47A, 0xD6ED}, //11556 #HANGUL SYLLABLE HIEUH WEO RIEULTHIEUTH + {0xC481, 0xD6EE}, //11557 #HANGUL SYLLABLE HIEUH WEO RIEULPHIEUPH + {0xC482, 0xD6EF}, //11558 #HANGUL SYLLABLE HIEUH WEO RIEULHIEUH + {0xC483, 0xD6F1}, //11559 #HANGUL SYLLABLE HIEUH WEO PIEUP + {0xC484, 0xD6F2}, //11560 #HANGUL SYLLABLE HIEUH WEO PIEUPSIOS + {0xC485, 0xD6F3}, //11561 #HANGUL SYLLABLE HIEUH WEO SIOS + {0xC486, 0xD6F4}, //11562 #HANGUL SYLLABLE HIEUH WEO SSANGSIOS + {0xC487, 0xD6F6}, //11563 #HANGUL SYLLABLE HIEUH WEO CIEUC + {0xC488, 0xD6F7}, //11564 #HANGUL SYLLABLE HIEUH WEO CHIEUCH + {0xC489, 0xD6F8}, //11565 #HANGUL SYLLABLE HIEUH WEO KHIEUKH + {0xC48A, 0xD6F9}, //11566 #HANGUL SYLLABLE HIEUH WEO THIEUTH + {0xC48B, 0xD6FA}, //11567 #HANGUL SYLLABLE HIEUH WEO PHIEUPH + {0xC48C, 0xD6FB}, //11568 #HANGUL SYLLABLE HIEUH WEO HIEUH + {0xC48D, 0xD6FE}, //11569 #HANGUL SYLLABLE HIEUH WE SSANGKIYEOK + {0xC48E, 0xD6FF}, //11570 #HANGUL SYLLABLE HIEUH WE KIYEOKSIOS + {0xC48F, 0xD701}, //11571 #HANGUL SYLLABLE HIEUH WE NIEUNCIEUC + {0xC490, 0xD702}, //11572 #HANGUL SYLLABLE HIEUH WE NIEUNHIEUH + {0xC491, 0xD703}, //11573 #HANGUL SYLLABLE HIEUH WE TIKEUT + {0xC492, 0xD705}, //11574 #HANGUL SYLLABLE HIEUH WE RIEULKIYEOK + {0xC493, 0xD706}, //11575 #HANGUL SYLLABLE HIEUH WE RIEULMIEUM + {0xC494, 0xD707}, //11576 #HANGUL SYLLABLE HIEUH WE RIEULPIEUP + {0xC495, 0xD708}, //11577 #HANGUL SYLLABLE HIEUH WE RIEULSIOS + {0xC496, 0xD709}, //11578 #HANGUL SYLLABLE HIEUH WE RIEULTHIEUTH + {0xC497, 0xD70A}, //11579 #HANGUL SYLLABLE HIEUH WE RIEULPHIEUPH + {0xC498, 0xD70B}, //11580 #HANGUL SYLLABLE HIEUH WE RIEULHIEUH + {0xC499, 0xD70C}, //11581 #HANGUL SYLLABLE HIEUH WE MIEUM + {0xC49A, 0xD70D}, //11582 #HANGUL SYLLABLE HIEUH WE PIEUP + {0xC49B, 0xD70E}, //11583 #HANGUL SYLLABLE HIEUH WE PIEUPSIOS + {0xC49C, 0xD70F}, //11584 #HANGUL SYLLABLE HIEUH WE SIOS + {0xC49D, 0xD710}, //11585 #HANGUL SYLLABLE HIEUH WE SSANGSIOS + {0xC49E, 0xD712}, //11586 #HANGUL SYLLABLE HIEUH WE CIEUC + {0xC49F, 0xD713}, //11587 #HANGUL SYLLABLE HIEUH WE CHIEUCH + {0xC4A0, 0xD714}, //11588 #HANGUL SYLLABLE HIEUH WE KHIEUKH + {0xC4A1, 0xCE58}, //11589 #HANGUL SYLLABLE CHIEUCH I + {0xC4A2, 0xCE59}, //11590 #HANGUL SYLLABLE CHIEUCH I KIYEOK + {0xC4A3, 0xCE5C}, //11591 #HANGUL SYLLABLE CHIEUCH I NIEUN + {0xC4A4, 0xCE5F}, //11592 #HANGUL SYLLABLE CHIEUCH I TIKEUT + {0xC4A5, 0xCE60}, //11593 #HANGUL SYLLABLE CHIEUCH I RIEUL + {0xC4A6, 0xCE61}, //11594 #HANGUL SYLLABLE CHIEUCH I RIEULKIYEOK + {0xC4A7, 0xCE68}, //11595 #HANGUL SYLLABLE CHIEUCH I MIEUM + {0xC4A8, 0xCE69}, //11596 #HANGUL SYLLABLE CHIEUCH I PIEUP + {0xC4A9, 0xCE6B}, //11597 #HANGUL SYLLABLE CHIEUCH I SIOS + {0xC4AA, 0xCE6D}, //11598 #HANGUL SYLLABLE CHIEUCH I IEUNG + {0xC4AB, 0xCE74}, //11599 #HANGUL SYLLABLE KHIEUKH A + {0xC4AC, 0xCE75}, //11600 #HANGUL SYLLABLE KHIEUKH A KIYEOK + {0xC4AD, 0xCE78}, //11601 #HANGUL SYLLABLE KHIEUKH A NIEUN + {0xC4AE, 0xCE7C}, //11602 #HANGUL SYLLABLE KHIEUKH A RIEUL + {0xC4AF, 0xCE84}, //11603 #HANGUL SYLLABLE KHIEUKH A MIEUM + {0xC4B0, 0xCE85}, //11604 #HANGUL SYLLABLE KHIEUKH A PIEUP + {0xC4B1, 0xCE87}, //11605 #HANGUL SYLLABLE KHIEUKH A SIOS + {0xC4B2, 0xCE89}, //11606 #HANGUL SYLLABLE KHIEUKH A IEUNG + {0xC4B3, 0xCE90}, //11607 #HANGUL SYLLABLE KHIEUKH AE + {0xC4B4, 0xCE91}, //11608 #HANGUL SYLLABLE KHIEUKH AE KIYEOK + {0xC4B5, 0xCE94}, //11609 #HANGUL SYLLABLE KHIEUKH AE NIEUN + {0xC4B6, 0xCE98}, //11610 #HANGUL SYLLABLE KHIEUKH AE RIEUL + {0xC4B7, 0xCEA0}, //11611 #HANGUL SYLLABLE KHIEUKH AE MIEUM + {0xC4B8, 0xCEA1}, //11612 #HANGUL SYLLABLE KHIEUKH AE PIEUP + {0xC4B9, 0xCEA3}, //11613 #HANGUL SYLLABLE KHIEUKH AE SIOS + {0xC4BA, 0xCEA4}, //11614 #HANGUL SYLLABLE KHIEUKH AE SSANGSIOS + {0xC4BB, 0xCEA5}, //11615 #HANGUL SYLLABLE KHIEUKH AE IEUNG + {0xC4BC, 0xCEAC}, //11616 #HANGUL SYLLABLE KHIEUKH YA + {0xC4BD, 0xCEAD}, //11617 #HANGUL SYLLABLE KHIEUKH YA KIYEOK + {0xC4BE, 0xCEC1}, //11618 #HANGUL SYLLABLE KHIEUKH YA IEUNG + {0xC4BF, 0xCEE4}, //11619 #HANGUL SYLLABLE KHIEUKH EO + {0xC4C0, 0xCEE5}, //11620 #HANGUL SYLLABLE KHIEUKH EO KIYEOK + {0xC4C1, 0xCEE8}, //11621 #HANGUL SYLLABLE KHIEUKH EO NIEUN + {0xC4C2, 0xCEEB}, //11622 #HANGUL SYLLABLE KHIEUKH EO TIKEUT + {0xC4C3, 0xCEEC}, //11623 #HANGUL SYLLABLE KHIEUKH EO RIEUL + {0xC4C4, 0xCEF4}, //11624 #HANGUL SYLLABLE KHIEUKH EO MIEUM + {0xC4C5, 0xCEF5}, //11625 #HANGUL SYLLABLE KHIEUKH EO PIEUP + {0xC4C6, 0xCEF7}, //11626 #HANGUL SYLLABLE KHIEUKH EO SIOS + {0xC4C7, 0xCEF8}, //11627 #HANGUL SYLLABLE KHIEUKH EO SSANGSIOS + {0xC4C8, 0xCEF9}, //11628 #HANGUL SYLLABLE KHIEUKH EO IEUNG + {0xC4C9, 0xCF00}, //11629 #HANGUL SYLLABLE KHIEUKH E + {0xC4CA, 0xCF01}, //11630 #HANGUL SYLLABLE KHIEUKH E KIYEOK + {0xC4CB, 0xCF04}, //11631 #HANGUL SYLLABLE KHIEUKH E NIEUN + {0xC4CC, 0xCF08}, //11632 #HANGUL SYLLABLE KHIEUKH E RIEUL + {0xC4CD, 0xCF10}, //11633 #HANGUL SYLLABLE KHIEUKH E MIEUM + {0xC4CE, 0xCF11}, //11634 #HANGUL SYLLABLE KHIEUKH E PIEUP + {0xC4CF, 0xCF13}, //11635 #HANGUL SYLLABLE KHIEUKH E SIOS + {0xC4D0, 0xCF15}, //11636 #HANGUL SYLLABLE KHIEUKH E IEUNG + {0xC4D1, 0xCF1C}, //11637 #HANGUL SYLLABLE KHIEUKH YEO + {0xC4D2, 0xCF20}, //11638 #HANGUL SYLLABLE KHIEUKH YEO NIEUN + {0xC4D3, 0xCF24}, //11639 #HANGUL SYLLABLE KHIEUKH YEO RIEUL + {0xC4D4, 0xCF2C}, //11640 #HANGUL SYLLABLE KHIEUKH YEO MIEUM + {0xC4D5, 0xCF2D}, //11641 #HANGUL SYLLABLE KHIEUKH YEO PIEUP + {0xC4D6, 0xCF2F}, //11642 #HANGUL SYLLABLE KHIEUKH YEO SIOS + {0xC4D7, 0xCF30}, //11643 #HANGUL SYLLABLE KHIEUKH YEO SSANGSIOS + {0xC4D8, 0xCF31}, //11644 #HANGUL SYLLABLE KHIEUKH YEO IEUNG + {0xC4D9, 0xCF38}, //11645 #HANGUL SYLLABLE KHIEUKH YE + {0xC4DA, 0xCF54}, //11646 #HANGUL SYLLABLE KHIEUKH O + {0xC4DB, 0xCF55}, //11647 #HANGUL SYLLABLE KHIEUKH O KIYEOK + {0xC4DC, 0xCF58}, //11648 #HANGUL SYLLABLE KHIEUKH O NIEUN + {0xC4DD, 0xCF5C}, //11649 #HANGUL SYLLABLE KHIEUKH O RIEUL + {0xC4DE, 0xCF64}, //11650 #HANGUL SYLLABLE KHIEUKH O MIEUM + {0xC4DF, 0xCF65}, //11651 #HANGUL SYLLABLE KHIEUKH O PIEUP + {0xC4E0, 0xCF67}, //11652 #HANGUL SYLLABLE KHIEUKH O SIOS + {0xC4E1, 0xCF69}, //11653 #HANGUL SYLLABLE KHIEUKH O IEUNG + {0xC4E2, 0xCF70}, //11654 #HANGUL SYLLABLE KHIEUKH WA + {0xC4E3, 0xCF71}, //11655 #HANGUL SYLLABLE KHIEUKH WA KIYEOK + {0xC4E4, 0xCF74}, //11656 #HANGUL SYLLABLE KHIEUKH WA NIEUN + {0xC4E5, 0xCF78}, //11657 #HANGUL SYLLABLE KHIEUKH WA RIEUL + {0xC4E6, 0xCF80}, //11658 #HANGUL SYLLABLE KHIEUKH WA MIEUM + {0xC4E7, 0xCF85}, //11659 #HANGUL SYLLABLE KHIEUKH WA IEUNG + {0xC4E8, 0xCF8C}, //11660 #HANGUL SYLLABLE KHIEUKH WAE + {0xC4E9, 0xCFA1}, //11661 #HANGUL SYLLABLE KHIEUKH WAE IEUNG + {0xC4EA, 0xCFA8}, //11662 #HANGUL SYLLABLE KHIEUKH OE + {0xC4EB, 0xCFB0}, //11663 #HANGUL SYLLABLE KHIEUKH OE RIEUL + {0xC4EC, 0xCFC4}, //11664 #HANGUL SYLLABLE KHIEUKH YO + {0xC4ED, 0xCFE0}, //11665 #HANGUL SYLLABLE KHIEUKH U + {0xC4EE, 0xCFE1}, //11666 #HANGUL SYLLABLE KHIEUKH U KIYEOK + {0xC4EF, 0xCFE4}, //11667 #HANGUL SYLLABLE KHIEUKH U NIEUN + {0xC4F0, 0xCFE8}, //11668 #HANGUL SYLLABLE KHIEUKH U RIEUL + {0xC4F1, 0xCFF0}, //11669 #HANGUL SYLLABLE KHIEUKH U MIEUM + {0xC4F2, 0xCFF1}, //11670 #HANGUL SYLLABLE KHIEUKH U PIEUP + {0xC4F3, 0xCFF3}, //11671 #HANGUL SYLLABLE KHIEUKH U SIOS + {0xC4F4, 0xCFF5}, //11672 #HANGUL SYLLABLE KHIEUKH U IEUNG + {0xC4F5, 0xCFFC}, //11673 #HANGUL SYLLABLE KHIEUKH WEO + {0xC4F6, 0xD000}, //11674 #HANGUL SYLLABLE KHIEUKH WEO NIEUN + {0xC4F7, 0xD004}, //11675 #HANGUL SYLLABLE KHIEUKH WEO RIEUL + {0xC4F8, 0xD011}, //11676 #HANGUL SYLLABLE KHIEUKH WEO IEUNG + {0xC4F9, 0xD018}, //11677 #HANGUL SYLLABLE KHIEUKH WE + {0xC4FA, 0xD02D}, //11678 #HANGUL SYLLABLE KHIEUKH WE IEUNG + {0xC4FB, 0xD034}, //11679 #HANGUL SYLLABLE KHIEUKH WI + {0xC4FC, 0xD035}, //11680 #HANGUL SYLLABLE KHIEUKH WI KIYEOK + {0xC4FD, 0xD038}, //11681 #HANGUL SYLLABLE KHIEUKH WI NIEUN + {0xC4FE, 0xD03C}, //11682 #HANGUL SYLLABLE KHIEUKH WI RIEUL + {0xC541, 0xD715}, //11683 #HANGUL SYLLABLE HIEUH WE THIEUTH + {0xC542, 0xD716}, //11684 #HANGUL SYLLABLE HIEUH WE PHIEUPH + {0xC543, 0xD717}, //11685 #HANGUL SYLLABLE HIEUH WE HIEUH + {0xC544, 0xD71A}, //11686 #HANGUL SYLLABLE HIEUH WI SSANGKIYEOK + {0xC545, 0xD71B}, //11687 #HANGUL SYLLABLE HIEUH WI KIYEOKSIOS + {0xC546, 0xD71D}, //11688 #HANGUL SYLLABLE HIEUH WI NIEUNCIEUC + {0xC547, 0xD71E}, //11689 #HANGUL SYLLABLE HIEUH WI NIEUNHIEUH + {0xC548, 0xD71F}, //11690 #HANGUL SYLLABLE HIEUH WI TIKEUT + {0xC549, 0xD721}, //11691 #HANGUL SYLLABLE HIEUH WI RIEULKIYEOK + {0xC54A, 0xD722}, //11692 #HANGUL SYLLABLE HIEUH WI RIEULMIEUM + {0xC54B, 0xD723}, //11693 #HANGUL SYLLABLE HIEUH WI RIEULPIEUP + {0xC54C, 0xD724}, //11694 #HANGUL SYLLABLE HIEUH WI RIEULSIOS + {0xC54D, 0xD725}, //11695 #HANGUL SYLLABLE HIEUH WI RIEULTHIEUTH + {0xC54E, 0xD726}, //11696 #HANGUL SYLLABLE HIEUH WI RIEULPHIEUPH + {0xC54F, 0xD727}, //11697 #HANGUL SYLLABLE HIEUH WI RIEULHIEUH + {0xC550, 0xD72A}, //11698 #HANGUL SYLLABLE HIEUH WI PIEUPSIOS + {0xC551, 0xD72C}, //11699 #HANGUL SYLLABLE HIEUH WI SSANGSIOS + {0xC552, 0xD72E}, //11700 #HANGUL SYLLABLE HIEUH WI CIEUC + {0xC553, 0xD72F}, //11701 #HANGUL SYLLABLE HIEUH WI CHIEUCH + {0xC554, 0xD730}, //11702 #HANGUL SYLLABLE HIEUH WI KHIEUKH + {0xC555, 0xD731}, //11703 #HANGUL SYLLABLE HIEUH WI THIEUTH + {0xC556, 0xD732}, //11704 #HANGUL SYLLABLE HIEUH WI PHIEUPH + {0xC557, 0xD733}, //11705 #HANGUL SYLLABLE HIEUH WI HIEUH + {0xC558, 0xD736}, //11706 #HANGUL SYLLABLE HIEUH YU SSANGKIYEOK + {0xC559, 0xD737}, //11707 #HANGUL SYLLABLE HIEUH YU KIYEOKSIOS + {0xC55A, 0xD739}, //11708 #HANGUL SYLLABLE HIEUH YU NIEUNCIEUC + {0xC561, 0xD73A}, //11709 #HANGUL SYLLABLE HIEUH YU NIEUNHIEUH + {0xC562, 0xD73B}, //11710 #HANGUL SYLLABLE HIEUH YU TIKEUT + {0xC563, 0xD73D}, //11711 #HANGUL SYLLABLE HIEUH YU RIEULKIYEOK + {0xC564, 0xD73E}, //11712 #HANGUL SYLLABLE HIEUH YU RIEULMIEUM + {0xC565, 0xD73F}, //11713 #HANGUL SYLLABLE HIEUH YU RIEULPIEUP + {0xC566, 0xD740}, //11714 #HANGUL SYLLABLE HIEUH YU RIEULSIOS + {0xC567, 0xD741}, //11715 #HANGUL SYLLABLE HIEUH YU RIEULTHIEUTH + {0xC568, 0xD742}, //11716 #HANGUL SYLLABLE HIEUH YU RIEULPHIEUPH + {0xC569, 0xD743}, //11717 #HANGUL SYLLABLE HIEUH YU RIEULHIEUH + {0xC56A, 0xD745}, //11718 #HANGUL SYLLABLE HIEUH YU PIEUP + {0xC56B, 0xD746}, //11719 #HANGUL SYLLABLE HIEUH YU PIEUPSIOS + {0xC56C, 0xD748}, //11720 #HANGUL SYLLABLE HIEUH YU SSANGSIOS + {0xC56D, 0xD74A}, //11721 #HANGUL SYLLABLE HIEUH YU CIEUC + {0xC56E, 0xD74B}, //11722 #HANGUL SYLLABLE HIEUH YU CHIEUCH + {0xC56F, 0xD74C}, //11723 #HANGUL SYLLABLE HIEUH YU KHIEUKH + {0xC570, 0xD74D}, //11724 #HANGUL SYLLABLE HIEUH YU THIEUTH + {0xC571, 0xD74E}, //11725 #HANGUL SYLLABLE HIEUH YU PHIEUPH + {0xC572, 0xD74F}, //11726 #HANGUL SYLLABLE HIEUH YU HIEUH + {0xC573, 0xD752}, //11727 #HANGUL SYLLABLE HIEUH EU SSANGKIYEOK + {0xC574, 0xD753}, //11728 #HANGUL SYLLABLE HIEUH EU KIYEOKSIOS + {0xC575, 0xD755}, //11729 #HANGUL SYLLABLE HIEUH EU NIEUNCIEUC + {0xC576, 0xD75A}, //11730 #HANGUL SYLLABLE HIEUH EU RIEULMIEUM + {0xC577, 0xD75B}, //11731 #HANGUL SYLLABLE HIEUH EU RIEULPIEUP + {0xC578, 0xD75C}, //11732 #HANGUL SYLLABLE HIEUH EU RIEULSIOS + {0xC579, 0xD75D}, //11733 #HANGUL SYLLABLE HIEUH EU RIEULTHIEUTH + {0xC57A, 0xD75E}, //11734 #HANGUL SYLLABLE HIEUH EU RIEULPHIEUPH + {0xC581, 0xD75F}, //11735 #HANGUL SYLLABLE HIEUH EU RIEULHIEUH + {0xC582, 0xD762}, //11736 #HANGUL SYLLABLE HIEUH EU PIEUPSIOS + {0xC583, 0xD764}, //11737 #HANGUL SYLLABLE HIEUH EU SSANGSIOS + {0xC584, 0xD766}, //11738 #HANGUL SYLLABLE HIEUH EU CIEUC + {0xC585, 0xD767}, //11739 #HANGUL SYLLABLE HIEUH EU CHIEUCH + {0xC586, 0xD768}, //11740 #HANGUL SYLLABLE HIEUH EU KHIEUKH + {0xC587, 0xD76A}, //11741 #HANGUL SYLLABLE HIEUH EU PHIEUPH + {0xC588, 0xD76B}, //11742 #HANGUL SYLLABLE HIEUH EU HIEUH + {0xC589, 0xD76D}, //11743 #HANGUL SYLLABLE HIEUH YI KIYEOK + {0xC58A, 0xD76E}, //11744 #HANGUL SYLLABLE HIEUH YI SSANGKIYEOK + {0xC58B, 0xD76F}, //11745 #HANGUL SYLLABLE HIEUH YI KIYEOKSIOS + {0xC58C, 0xD771}, //11746 #HANGUL SYLLABLE HIEUH YI NIEUNCIEUC + {0xC58D, 0xD772}, //11747 #HANGUL SYLLABLE HIEUH YI NIEUNHIEUH + {0xC58E, 0xD773}, //11748 #HANGUL SYLLABLE HIEUH YI TIKEUT + {0xC58F, 0xD775}, //11749 #HANGUL SYLLABLE HIEUH YI RIEULKIYEOK + {0xC590, 0xD776}, //11750 #HANGUL SYLLABLE HIEUH YI RIEULMIEUM + {0xC591, 0xD777}, //11751 #HANGUL SYLLABLE HIEUH YI RIEULPIEUP + {0xC592, 0xD778}, //11752 #HANGUL SYLLABLE HIEUH YI RIEULSIOS + {0xC593, 0xD779}, //11753 #HANGUL SYLLABLE HIEUH YI RIEULTHIEUTH + {0xC594, 0xD77A}, //11754 #HANGUL SYLLABLE HIEUH YI RIEULPHIEUPH + {0xC595, 0xD77B}, //11755 #HANGUL SYLLABLE HIEUH YI RIEULHIEUH + {0xC596, 0xD77E}, //11756 #HANGUL SYLLABLE HIEUH YI PIEUPSIOS + {0xC597, 0xD77F}, //11757 #HANGUL SYLLABLE HIEUH YI SIOS + {0xC598, 0xD780}, //11758 #HANGUL SYLLABLE HIEUH YI SSANGSIOS + {0xC599, 0xD782}, //11759 #HANGUL SYLLABLE HIEUH YI CIEUC + {0xC59A, 0xD783}, //11760 #HANGUL SYLLABLE HIEUH YI CHIEUCH + {0xC59B, 0xD784}, //11761 #HANGUL SYLLABLE HIEUH YI KHIEUKH + {0xC59C, 0xD785}, //11762 #HANGUL SYLLABLE HIEUH YI THIEUTH + {0xC59D, 0xD786}, //11763 #HANGUL SYLLABLE HIEUH YI PHIEUPH + {0xC59E, 0xD787}, //11764 #HANGUL SYLLABLE HIEUH YI HIEUH + {0xC59F, 0xD78A}, //11765 #HANGUL SYLLABLE HIEUH I SSANGKIYEOK + {0xC5A0, 0xD78B}, //11766 #HANGUL SYLLABLE HIEUH I KIYEOKSIOS + {0xC5A1, 0xD044}, //11767 #HANGUL SYLLABLE KHIEUKH WI MIEUM + {0xC5A2, 0xD045}, //11768 #HANGUL SYLLABLE KHIEUKH WI PIEUP + {0xC5A3, 0xD047}, //11769 #HANGUL SYLLABLE KHIEUKH WI SIOS + {0xC5A4, 0xD049}, //11770 #HANGUL SYLLABLE KHIEUKH WI IEUNG + {0xC5A5, 0xD050}, //11771 #HANGUL SYLLABLE KHIEUKH YU + {0xC5A6, 0xD054}, //11772 #HANGUL SYLLABLE KHIEUKH YU NIEUN + {0xC5A7, 0xD058}, //11773 #HANGUL SYLLABLE KHIEUKH YU RIEUL + {0xC5A8, 0xD060}, //11774 #HANGUL SYLLABLE KHIEUKH YU MIEUM + {0xC5A9, 0xD06C}, //11775 #HANGUL SYLLABLE KHIEUKH EU + {0xC5AA, 0xD06D}, //11776 #HANGUL SYLLABLE KHIEUKH EU KIYEOK + {0xC5AB, 0xD070}, //11777 #HANGUL SYLLABLE KHIEUKH EU NIEUN + {0xC5AC, 0xD074}, //11778 #HANGUL SYLLABLE KHIEUKH EU RIEUL + {0xC5AD, 0xD07C}, //11779 #HANGUL SYLLABLE KHIEUKH EU MIEUM + {0xC5AE, 0xD07D}, //11780 #HANGUL SYLLABLE KHIEUKH EU PIEUP + {0xC5AF, 0xD081}, //11781 #HANGUL SYLLABLE KHIEUKH EU IEUNG + {0xC5B0, 0xD0A4}, //11782 #HANGUL SYLLABLE KHIEUKH I + {0xC5B1, 0xD0A5}, //11783 #HANGUL SYLLABLE KHIEUKH I KIYEOK + {0xC5B2, 0xD0A8}, //11784 #HANGUL SYLLABLE KHIEUKH I NIEUN + {0xC5B3, 0xD0AC}, //11785 #HANGUL SYLLABLE KHIEUKH I RIEUL + {0xC5B4, 0xD0B4}, //11786 #HANGUL SYLLABLE KHIEUKH I MIEUM + {0xC5B5, 0xD0B5}, //11787 #HANGUL SYLLABLE KHIEUKH I PIEUP + {0xC5B6, 0xD0B7}, //11788 #HANGUL SYLLABLE KHIEUKH I SIOS + {0xC5B7, 0xD0B9}, //11789 #HANGUL SYLLABLE KHIEUKH I IEUNG + {0xC5B8, 0xD0C0}, //11790 #HANGUL SYLLABLE THIEUTH A + {0xC5B9, 0xD0C1}, //11791 #HANGUL SYLLABLE THIEUTH A KIYEOK + {0xC5BA, 0xD0C4}, //11792 #HANGUL SYLLABLE THIEUTH A NIEUN + {0xC5BB, 0xD0C8}, //11793 #HANGUL SYLLABLE THIEUTH A RIEUL + {0xC5BC, 0xD0C9}, //11794 #HANGUL SYLLABLE THIEUTH A RIEULKIYEOK + {0xC5BD, 0xD0D0}, //11795 #HANGUL SYLLABLE THIEUTH A MIEUM + {0xC5BE, 0xD0D1}, //11796 #HANGUL SYLLABLE THIEUTH A PIEUP + {0xC5BF, 0xD0D3}, //11797 #HANGUL SYLLABLE THIEUTH A SIOS + {0xC5C0, 0xD0D4}, //11798 #HANGUL SYLLABLE THIEUTH A SSANGSIOS + {0xC5C1, 0xD0D5}, //11799 #HANGUL SYLLABLE THIEUTH A IEUNG + {0xC5C2, 0xD0DC}, //11800 #HANGUL SYLLABLE THIEUTH AE + {0xC5C3, 0xD0DD}, //11801 #HANGUL SYLLABLE THIEUTH AE KIYEOK + {0xC5C4, 0xD0E0}, //11802 #HANGUL SYLLABLE THIEUTH AE NIEUN + {0xC5C5, 0xD0E4}, //11803 #HANGUL SYLLABLE THIEUTH AE RIEUL + {0xC5C6, 0xD0EC}, //11804 #HANGUL SYLLABLE THIEUTH AE MIEUM + {0xC5C7, 0xD0ED}, //11805 #HANGUL SYLLABLE THIEUTH AE PIEUP + {0xC5C8, 0xD0EF}, //11806 #HANGUL SYLLABLE THIEUTH AE SIOS + {0xC5C9, 0xD0F0}, //11807 #HANGUL SYLLABLE THIEUTH AE SSANGSIOS + {0xC5CA, 0xD0F1}, //11808 #HANGUL SYLLABLE THIEUTH AE IEUNG + {0xC5CB, 0xD0F8}, //11809 #HANGUL SYLLABLE THIEUTH YA + {0xC5CC, 0xD10D}, //11810 #HANGUL SYLLABLE THIEUTH YA IEUNG + {0xC5CD, 0xD130}, //11811 #HANGUL SYLLABLE THIEUTH EO + {0xC5CE, 0xD131}, //11812 #HANGUL SYLLABLE THIEUTH EO KIYEOK + {0xC5CF, 0xD134}, //11813 #HANGUL SYLLABLE THIEUTH EO NIEUN + {0xC5D0, 0xD138}, //11814 #HANGUL SYLLABLE THIEUTH EO RIEUL + {0xC5D1, 0xD13A}, //11815 #HANGUL SYLLABLE THIEUTH EO RIEULMIEUM + {0xC5D2, 0xD140}, //11816 #HANGUL SYLLABLE THIEUTH EO MIEUM + {0xC5D3, 0xD141}, //11817 #HANGUL SYLLABLE THIEUTH EO PIEUP + {0xC5D4, 0xD143}, //11818 #HANGUL SYLLABLE THIEUTH EO SIOS + {0xC5D5, 0xD144}, //11819 #HANGUL SYLLABLE THIEUTH EO SSANGSIOS + {0xC5D6, 0xD145}, //11820 #HANGUL SYLLABLE THIEUTH EO IEUNG + {0xC5D7, 0xD14C}, //11821 #HANGUL SYLLABLE THIEUTH E + {0xC5D8, 0xD14D}, //11822 #HANGUL SYLLABLE THIEUTH E KIYEOK + {0xC5D9, 0xD150}, //11823 #HANGUL SYLLABLE THIEUTH E NIEUN + {0xC5DA, 0xD154}, //11824 #HANGUL SYLLABLE THIEUTH E RIEUL + {0xC5DB, 0xD15C}, //11825 #HANGUL SYLLABLE THIEUTH E MIEUM + {0xC5DC, 0xD15D}, //11826 #HANGUL SYLLABLE THIEUTH E PIEUP + {0xC5DD, 0xD15F}, //11827 #HANGUL SYLLABLE THIEUTH E SIOS + {0xC5DE, 0xD161}, //11828 #HANGUL SYLLABLE THIEUTH E IEUNG + {0xC5DF, 0xD168}, //11829 #HANGUL SYLLABLE THIEUTH YEO + {0xC5E0, 0xD16C}, //11830 #HANGUL SYLLABLE THIEUTH YEO NIEUN + {0xC5E1, 0xD17C}, //11831 #HANGUL SYLLABLE THIEUTH YEO SSANGSIOS + {0xC5E2, 0xD184}, //11832 #HANGUL SYLLABLE THIEUTH YE + {0xC5E3, 0xD188}, //11833 #HANGUL SYLLABLE THIEUTH YE NIEUN + {0xC5E4, 0xD1A0}, //11834 #HANGUL SYLLABLE THIEUTH O + {0xC5E5, 0xD1A1}, //11835 #HANGUL SYLLABLE THIEUTH O KIYEOK + {0xC5E6, 0xD1A4}, //11836 #HANGUL SYLLABLE THIEUTH O NIEUN + {0xC5E7, 0xD1A8}, //11837 #HANGUL SYLLABLE THIEUTH O RIEUL + {0xC5E8, 0xD1B0}, //11838 #HANGUL SYLLABLE THIEUTH O MIEUM + {0xC5E9, 0xD1B1}, //11839 #HANGUL SYLLABLE THIEUTH O PIEUP + {0xC5EA, 0xD1B3}, //11840 #HANGUL SYLLABLE THIEUTH O SIOS + {0xC5EB, 0xD1B5}, //11841 #HANGUL SYLLABLE THIEUTH O IEUNG + {0xC5EC, 0xD1BA}, //11842 #HANGUL SYLLABLE THIEUTH O PHIEUPH + {0xC5ED, 0xD1BC}, //11843 #HANGUL SYLLABLE THIEUTH WA + {0xC5EE, 0xD1C0}, //11844 #HANGUL SYLLABLE THIEUTH WA NIEUN + {0xC5EF, 0xD1D8}, //11845 #HANGUL SYLLABLE THIEUTH WAE + {0xC5F0, 0xD1F4}, //11846 #HANGUL SYLLABLE THIEUTH OE + {0xC5F1, 0xD1F8}, //11847 #HANGUL SYLLABLE THIEUTH OE NIEUN + {0xC5F2, 0xD207}, //11848 #HANGUL SYLLABLE THIEUTH OE SIOS + {0xC5F3, 0xD209}, //11849 #HANGUL SYLLABLE THIEUTH OE IEUNG + {0xC5F4, 0xD210}, //11850 #HANGUL SYLLABLE THIEUTH YO + {0xC5F5, 0xD22C}, //11851 #HANGUL SYLLABLE THIEUTH U + {0xC5F6, 0xD22D}, //11852 #HANGUL SYLLABLE THIEUTH U KIYEOK + {0xC5F7, 0xD230}, //11853 #HANGUL SYLLABLE THIEUTH U NIEUN + {0xC5F8, 0xD234}, //11854 #HANGUL SYLLABLE THIEUTH U RIEUL + {0xC5F9, 0xD23C}, //11855 #HANGUL SYLLABLE THIEUTH U MIEUM + {0xC5FA, 0xD23D}, //11856 #HANGUL SYLLABLE THIEUTH U PIEUP + {0xC5FB, 0xD23F}, //11857 #HANGUL SYLLABLE THIEUTH U SIOS + {0xC5FC, 0xD241}, //11858 #HANGUL SYLLABLE THIEUTH U IEUNG + {0xC5FD, 0xD248}, //11859 #HANGUL SYLLABLE THIEUTH WEO + {0xC5FE, 0xD25C}, //11860 #HANGUL SYLLABLE THIEUTH WEO SSANGSIOS + {0xC641, 0xD78D}, //11861 #HANGUL SYLLABLE HIEUH I NIEUNCIEUC + {0xC642, 0xD78E}, //11862 #HANGUL SYLLABLE HIEUH I NIEUNHIEUH + {0xC643, 0xD78F}, //11863 #HANGUL SYLLABLE HIEUH I TIKEUT + {0xC644, 0xD791}, //11864 #HANGUL SYLLABLE HIEUH I RIEULKIYEOK + {0xC645, 0xD792}, //11865 #HANGUL SYLLABLE HIEUH I RIEULMIEUM + {0xC646, 0xD793}, //11866 #HANGUL SYLLABLE HIEUH I RIEULPIEUP + {0xC647, 0xD794}, //11867 #HANGUL SYLLABLE HIEUH I RIEULSIOS + {0xC648, 0xD795}, //11868 #HANGUL SYLLABLE HIEUH I RIEULTHIEUTH + {0xC649, 0xD796}, //11869 #HANGUL SYLLABLE HIEUH I RIEULPHIEUPH + {0xC64A, 0xD797}, //11870 #HANGUL SYLLABLE HIEUH I RIEULHIEUH + {0xC64B, 0xD79A}, //11871 #HANGUL SYLLABLE HIEUH I PIEUPSIOS + {0xC64C, 0xD79C}, //11872 #HANGUL SYLLABLE HIEUH I SSANGSIOS + {0xC64D, 0xD79E}, //11873 #HANGUL SYLLABLE HIEUH I CIEUC + {0xC64E, 0xD79F}, //11874 #HANGUL SYLLABLE HIEUH I CHIEUCH + {0xC64F, 0xD7A0}, //11875 #HANGUL SYLLABLE HIEUH I KHIEUKH + {0xC650, 0xD7A1}, //11876 #HANGUL SYLLABLE HIEUH I THIEUTH + {0xC651, 0xD7A2}, //11877 #HANGUL SYLLABLE HIEUH I PHIEUPH + {0xC652, 0xD7A3}, //11878 #HANGUL SYLLABLE HIEUH I HIEUH + {0xC6A1, 0xD264}, //11879 #HANGUL SYLLABLE THIEUTH WE + {0xC6A2, 0xD280}, //11880 #HANGUL SYLLABLE THIEUTH WI + {0xC6A3, 0xD281}, //11881 #HANGUL SYLLABLE THIEUTH WI KIYEOK + {0xC6A4, 0xD284}, //11882 #HANGUL SYLLABLE THIEUTH WI NIEUN + {0xC6A5, 0xD288}, //11883 #HANGUL SYLLABLE THIEUTH WI RIEUL + {0xC6A6, 0xD290}, //11884 #HANGUL SYLLABLE THIEUTH WI MIEUM + {0xC6A7, 0xD291}, //11885 #HANGUL SYLLABLE THIEUTH WI PIEUP + {0xC6A8, 0xD295}, //11886 #HANGUL SYLLABLE THIEUTH WI IEUNG + {0xC6A9, 0xD29C}, //11887 #HANGUL SYLLABLE THIEUTH YU + {0xC6AA, 0xD2A0}, //11888 #HANGUL SYLLABLE THIEUTH YU NIEUN + {0xC6AB, 0xD2A4}, //11889 #HANGUL SYLLABLE THIEUTH YU RIEUL + {0xC6AC, 0xD2AC}, //11890 #HANGUL SYLLABLE THIEUTH YU MIEUM + {0xC6AD, 0xD2B1}, //11891 #HANGUL SYLLABLE THIEUTH YU IEUNG + {0xC6AE, 0xD2B8}, //11892 #HANGUL SYLLABLE THIEUTH EU + {0xC6AF, 0xD2B9}, //11893 #HANGUL SYLLABLE THIEUTH EU KIYEOK + {0xC6B0, 0xD2BC}, //11894 #HANGUL SYLLABLE THIEUTH EU NIEUN + {0xC6B1, 0xD2BF}, //11895 #HANGUL SYLLABLE THIEUTH EU TIKEUT + {0xC6B2, 0xD2C0}, //11896 #HANGUL SYLLABLE THIEUTH EU RIEUL + {0xC6B3, 0xD2C2}, //11897 #HANGUL SYLLABLE THIEUTH EU RIEULMIEUM + {0xC6B4, 0xD2C8}, //11898 #HANGUL SYLLABLE THIEUTH EU MIEUM + {0xC6B5, 0xD2C9}, //11899 #HANGUL SYLLABLE THIEUTH EU PIEUP + {0xC6B6, 0xD2CB}, //11900 #HANGUL SYLLABLE THIEUTH EU SIOS + {0xC6B7, 0xD2D4}, //11901 #HANGUL SYLLABLE THIEUTH YI + {0xC6B8, 0xD2D8}, //11902 #HANGUL SYLLABLE THIEUTH YI NIEUN + {0xC6B9, 0xD2DC}, //11903 #HANGUL SYLLABLE THIEUTH YI RIEUL + {0xC6BA, 0xD2E4}, //11904 #HANGUL SYLLABLE THIEUTH YI MIEUM + {0xC6BB, 0xD2E5}, //11905 #HANGUL SYLLABLE THIEUTH YI PIEUP + {0xC6BC, 0xD2F0}, //11906 #HANGUL SYLLABLE THIEUTH I + {0xC6BD, 0xD2F1}, //11907 #HANGUL SYLLABLE THIEUTH I KIYEOK + {0xC6BE, 0xD2F4}, //11908 #HANGUL SYLLABLE THIEUTH I NIEUN + {0xC6BF, 0xD2F8}, //11909 #HANGUL SYLLABLE THIEUTH I RIEUL + {0xC6C0, 0xD300}, //11910 #HANGUL SYLLABLE THIEUTH I MIEUM + {0xC6C1, 0xD301}, //11911 #HANGUL SYLLABLE THIEUTH I PIEUP + {0xC6C2, 0xD303}, //11912 #HANGUL SYLLABLE THIEUTH I SIOS + {0xC6C3, 0xD305}, //11913 #HANGUL SYLLABLE THIEUTH I IEUNG + {0xC6C4, 0xD30C}, //11914 #HANGUL SYLLABLE PHIEUPH A + {0xC6C5, 0xD30D}, //11915 #HANGUL SYLLABLE PHIEUPH A KIYEOK + {0xC6C6, 0xD30E}, //11916 #HANGUL SYLLABLE PHIEUPH A SSANGKIYEOK + {0xC6C7, 0xD310}, //11917 #HANGUL SYLLABLE PHIEUPH A NIEUN + {0xC6C8, 0xD314}, //11918 #HANGUL SYLLABLE PHIEUPH A RIEUL + {0xC6C9, 0xD316}, //11919 #HANGUL SYLLABLE PHIEUPH A RIEULMIEUM + {0xC6CA, 0xD31C}, //11920 #HANGUL SYLLABLE PHIEUPH A MIEUM + {0xC6CB, 0xD31D}, //11921 #HANGUL SYLLABLE PHIEUPH A PIEUP + {0xC6CC, 0xD31F}, //11922 #HANGUL SYLLABLE PHIEUPH A SIOS + {0xC6CD, 0xD320}, //11923 #HANGUL SYLLABLE PHIEUPH A SSANGSIOS + {0xC6CE, 0xD321}, //11924 #HANGUL SYLLABLE PHIEUPH A IEUNG + {0xC6CF, 0xD325}, //11925 #HANGUL SYLLABLE PHIEUPH A THIEUTH + {0xC6D0, 0xD328}, //11926 #HANGUL SYLLABLE PHIEUPH AE + {0xC6D1, 0xD329}, //11927 #HANGUL SYLLABLE PHIEUPH AE KIYEOK + {0xC6D2, 0xD32C}, //11928 #HANGUL SYLLABLE PHIEUPH AE NIEUN + {0xC6D3, 0xD330}, //11929 #HANGUL SYLLABLE PHIEUPH AE RIEUL + {0xC6D4, 0xD338}, //11930 #HANGUL SYLLABLE PHIEUPH AE MIEUM + {0xC6D5, 0xD339}, //11931 #HANGUL SYLLABLE PHIEUPH AE PIEUP + {0xC6D6, 0xD33B}, //11932 #HANGUL SYLLABLE PHIEUPH AE SIOS + {0xC6D7, 0xD33C}, //11933 #HANGUL SYLLABLE PHIEUPH AE SSANGSIOS + {0xC6D8, 0xD33D}, //11934 #HANGUL SYLLABLE PHIEUPH AE IEUNG + {0xC6D9, 0xD344}, //11935 #HANGUL SYLLABLE PHIEUPH YA + {0xC6DA, 0xD345}, //11936 #HANGUL SYLLABLE PHIEUPH YA KIYEOK + {0xC6DB, 0xD37C}, //11937 #HANGUL SYLLABLE PHIEUPH EO + {0xC6DC, 0xD37D}, //11938 #HANGUL SYLLABLE PHIEUPH EO KIYEOK + {0xC6DD, 0xD380}, //11939 #HANGUL SYLLABLE PHIEUPH EO NIEUN + {0xC6DE, 0xD384}, //11940 #HANGUL SYLLABLE PHIEUPH EO RIEUL + {0xC6DF, 0xD38C}, //11941 #HANGUL SYLLABLE PHIEUPH EO MIEUM + {0xC6E0, 0xD38D}, //11942 #HANGUL SYLLABLE PHIEUPH EO PIEUP + {0xC6E1, 0xD38F}, //11943 #HANGUL SYLLABLE PHIEUPH EO SIOS + {0xC6E2, 0xD390}, //11944 #HANGUL SYLLABLE PHIEUPH EO SSANGSIOS + {0xC6E3, 0xD391}, //11945 #HANGUL SYLLABLE PHIEUPH EO IEUNG + {0xC6E4, 0xD398}, //11946 #HANGUL SYLLABLE PHIEUPH E + {0xC6E5, 0xD399}, //11947 #HANGUL SYLLABLE PHIEUPH E KIYEOK + {0xC6E6, 0xD39C}, //11948 #HANGUL SYLLABLE PHIEUPH E NIEUN + {0xC6E7, 0xD3A0}, //11949 #HANGUL SYLLABLE PHIEUPH E RIEUL + {0xC6E8, 0xD3A8}, //11950 #HANGUL SYLLABLE PHIEUPH E MIEUM + {0xC6E9, 0xD3A9}, //11951 #HANGUL SYLLABLE PHIEUPH E PIEUP + {0xC6EA, 0xD3AB}, //11952 #HANGUL SYLLABLE PHIEUPH E SIOS + {0xC6EB, 0xD3AD}, //11953 #HANGUL SYLLABLE PHIEUPH E IEUNG + {0xC6EC, 0xD3B4}, //11954 #HANGUL SYLLABLE PHIEUPH YEO + {0xC6ED, 0xD3B8}, //11955 #HANGUL SYLLABLE PHIEUPH YEO NIEUN + {0xC6EE, 0xD3BC}, //11956 #HANGUL SYLLABLE PHIEUPH YEO RIEUL + {0xC6EF, 0xD3C4}, //11957 #HANGUL SYLLABLE PHIEUPH YEO MIEUM + {0xC6F0, 0xD3C5}, //11958 #HANGUL SYLLABLE PHIEUPH YEO PIEUP + {0xC6F1, 0xD3C8}, //11959 #HANGUL SYLLABLE PHIEUPH YEO SSANGSIOS + {0xC6F2, 0xD3C9}, //11960 #HANGUL SYLLABLE PHIEUPH YEO IEUNG + {0xC6F3, 0xD3D0}, //11961 #HANGUL SYLLABLE PHIEUPH YE + {0xC6F4, 0xD3D8}, //11962 #HANGUL SYLLABLE PHIEUPH YE RIEUL + {0xC6F5, 0xD3E1}, //11963 #HANGUL SYLLABLE PHIEUPH YE PIEUP + {0xC6F6, 0xD3E3}, //11964 #HANGUL SYLLABLE PHIEUPH YE SIOS + {0xC6F7, 0xD3EC}, //11965 #HANGUL SYLLABLE PHIEUPH O + {0xC6F8, 0xD3ED}, //11966 #HANGUL SYLLABLE PHIEUPH O KIYEOK + {0xC6F9, 0xD3F0}, //11967 #HANGUL SYLLABLE PHIEUPH O NIEUN + {0xC6FA, 0xD3F4}, //11968 #HANGUL SYLLABLE PHIEUPH O RIEUL + {0xC6FB, 0xD3FC}, //11969 #HANGUL SYLLABLE PHIEUPH O MIEUM + {0xC6FC, 0xD3FD}, //11970 #HANGUL SYLLABLE PHIEUPH O PIEUP + {0xC6FD, 0xD3FF}, //11971 #HANGUL SYLLABLE PHIEUPH O SIOS + {0xC6FE, 0xD401}, //11972 #HANGUL SYLLABLE PHIEUPH O IEUNG + {0xC7A1, 0xD408}, //11973 #HANGUL SYLLABLE PHIEUPH WA + {0xC7A2, 0xD41D}, //11974 #HANGUL SYLLABLE PHIEUPH WA IEUNG + {0xC7A3, 0xD440}, //11975 #HANGUL SYLLABLE PHIEUPH OE + {0xC7A4, 0xD444}, //11976 #HANGUL SYLLABLE PHIEUPH OE NIEUN + {0xC7A5, 0xD45C}, //11977 #HANGUL SYLLABLE PHIEUPH YO + {0xC7A6, 0xD460}, //11978 #HANGUL SYLLABLE PHIEUPH YO NIEUN + {0xC7A7, 0xD464}, //11979 #HANGUL SYLLABLE PHIEUPH YO RIEUL + {0xC7A8, 0xD46D}, //11980 #HANGUL SYLLABLE PHIEUPH YO PIEUP + {0xC7A9, 0xD46F}, //11981 #HANGUL SYLLABLE PHIEUPH YO SIOS + {0xC7AA, 0xD478}, //11982 #HANGUL SYLLABLE PHIEUPH U + {0xC7AB, 0xD479}, //11983 #HANGUL SYLLABLE PHIEUPH U KIYEOK + {0xC7AC, 0xD47C}, //11984 #HANGUL SYLLABLE PHIEUPH U NIEUN + {0xC7AD, 0xD47F}, //11985 #HANGUL SYLLABLE PHIEUPH U TIKEUT + {0xC7AE, 0xD480}, //11986 #HANGUL SYLLABLE PHIEUPH U RIEUL + {0xC7AF, 0xD482}, //11987 #HANGUL SYLLABLE PHIEUPH U RIEULMIEUM + {0xC7B0, 0xD488}, //11988 #HANGUL SYLLABLE PHIEUPH U MIEUM + {0xC7B1, 0xD489}, //11989 #HANGUL SYLLABLE PHIEUPH U PIEUP + {0xC7B2, 0xD48B}, //11990 #HANGUL SYLLABLE PHIEUPH U SIOS + {0xC7B3, 0xD48D}, //11991 #HANGUL SYLLABLE PHIEUPH U IEUNG + {0xC7B4, 0xD494}, //11992 #HANGUL SYLLABLE PHIEUPH WEO + {0xC7B5, 0xD4A9}, //11993 #HANGUL SYLLABLE PHIEUPH WEO IEUNG + {0xC7B6, 0xD4CC}, //11994 #HANGUL SYLLABLE PHIEUPH WI + {0xC7B7, 0xD4D0}, //11995 #HANGUL SYLLABLE PHIEUPH WI NIEUN + {0xC7B8, 0xD4D4}, //11996 #HANGUL SYLLABLE PHIEUPH WI RIEUL + {0xC7B9, 0xD4DC}, //11997 #HANGUL SYLLABLE PHIEUPH WI MIEUM + {0xC7BA, 0xD4DF}, //11998 #HANGUL SYLLABLE PHIEUPH WI SIOS + {0xC7BB, 0xD4E8}, //11999 #HANGUL SYLLABLE PHIEUPH YU + {0xC7BC, 0xD4EC}, //12000 #HANGUL SYLLABLE PHIEUPH YU NIEUN + {0xC7BD, 0xD4F0}, //12001 #HANGUL SYLLABLE PHIEUPH YU RIEUL + {0xC7BE, 0xD4F8}, //12002 #HANGUL SYLLABLE PHIEUPH YU MIEUM + {0xC7BF, 0xD4FB}, //12003 #HANGUL SYLLABLE PHIEUPH YU SIOS + {0xC7C0, 0xD4FD}, //12004 #HANGUL SYLLABLE PHIEUPH YU IEUNG + {0xC7C1, 0xD504}, //12005 #HANGUL SYLLABLE PHIEUPH EU + {0xC7C2, 0xD508}, //12006 #HANGUL SYLLABLE PHIEUPH EU NIEUN + {0xC7C3, 0xD50C}, //12007 #HANGUL SYLLABLE PHIEUPH EU RIEUL + {0xC7C4, 0xD514}, //12008 #HANGUL SYLLABLE PHIEUPH EU MIEUM + {0xC7C5, 0xD515}, //12009 #HANGUL SYLLABLE PHIEUPH EU PIEUP + {0xC7C6, 0xD517}, //12010 #HANGUL SYLLABLE PHIEUPH EU SIOS + {0xC7C7, 0xD53C}, //12011 #HANGUL SYLLABLE PHIEUPH I + {0xC7C8, 0xD53D}, //12012 #HANGUL SYLLABLE PHIEUPH I KIYEOK + {0xC7C9, 0xD540}, //12013 #HANGUL SYLLABLE PHIEUPH I NIEUN + {0xC7CA, 0xD544}, //12014 #HANGUL SYLLABLE PHIEUPH I RIEUL + {0xC7CB, 0xD54C}, //12015 #HANGUL SYLLABLE PHIEUPH I MIEUM + {0xC7CC, 0xD54D}, //12016 #HANGUL SYLLABLE PHIEUPH I PIEUP + {0xC7CD, 0xD54F}, //12017 #HANGUL SYLLABLE PHIEUPH I SIOS + {0xC7CE, 0xD551}, //12018 #HANGUL SYLLABLE PHIEUPH I IEUNG + {0xC7CF, 0xD558}, //12019 #HANGUL SYLLABLE HIEUH A + {0xC7D0, 0xD559}, //12020 #HANGUL SYLLABLE HIEUH A KIYEOK + {0xC7D1, 0xD55C}, //12021 #HANGUL SYLLABLE HIEUH A NIEUN + {0xC7D2, 0xD560}, //12022 #HANGUL SYLLABLE HIEUH A RIEUL + {0xC7D3, 0xD565}, //12023 #HANGUL SYLLABLE HIEUH A RIEULTHIEUTH + {0xC7D4, 0xD568}, //12024 #HANGUL SYLLABLE HIEUH A MIEUM + {0xC7D5, 0xD569}, //12025 #HANGUL SYLLABLE HIEUH A PIEUP + {0xC7D6, 0xD56B}, //12026 #HANGUL SYLLABLE HIEUH A SIOS + {0xC7D7, 0xD56D}, //12027 #HANGUL SYLLABLE HIEUH A IEUNG + {0xC7D8, 0xD574}, //12028 #HANGUL SYLLABLE HIEUH AE + {0xC7D9, 0xD575}, //12029 #HANGUL SYLLABLE HIEUH AE KIYEOK + {0xC7DA, 0xD578}, //12030 #HANGUL SYLLABLE HIEUH AE NIEUN + {0xC7DB, 0xD57C}, //12031 #HANGUL SYLLABLE HIEUH AE RIEUL + {0xC7DC, 0xD584}, //12032 #HANGUL SYLLABLE HIEUH AE MIEUM + {0xC7DD, 0xD585}, //12033 #HANGUL SYLLABLE HIEUH AE PIEUP + {0xC7DE, 0xD587}, //12034 #HANGUL SYLLABLE HIEUH AE SIOS + {0xC7DF, 0xD588}, //12035 #HANGUL SYLLABLE HIEUH AE SSANGSIOS + {0xC7E0, 0xD589}, //12036 #HANGUL SYLLABLE HIEUH AE IEUNG + {0xC7E1, 0xD590}, //12037 #HANGUL SYLLABLE HIEUH YA + {0xC7E2, 0xD5A5}, //12038 #HANGUL SYLLABLE HIEUH YA IEUNG + {0xC7E3, 0xD5C8}, //12039 #HANGUL SYLLABLE HIEUH EO + {0xC7E4, 0xD5C9}, //12040 #HANGUL SYLLABLE HIEUH EO KIYEOK + {0xC7E5, 0xD5CC}, //12041 #HANGUL SYLLABLE HIEUH EO NIEUN + {0xC7E6, 0xD5D0}, //12042 #HANGUL SYLLABLE HIEUH EO RIEUL + {0xC7E7, 0xD5D2}, //12043 #HANGUL SYLLABLE HIEUH EO RIEULMIEUM + {0xC7E8, 0xD5D8}, //12044 #HANGUL SYLLABLE HIEUH EO MIEUM + {0xC7E9, 0xD5D9}, //12045 #HANGUL SYLLABLE HIEUH EO PIEUP + {0xC7EA, 0xD5DB}, //12046 #HANGUL SYLLABLE HIEUH EO SIOS + {0xC7EB, 0xD5DD}, //12047 #HANGUL SYLLABLE HIEUH EO IEUNG + {0xC7EC, 0xD5E4}, //12048 #HANGUL SYLLABLE HIEUH E + {0xC7ED, 0xD5E5}, //12049 #HANGUL SYLLABLE HIEUH E KIYEOK + {0xC7EE, 0xD5E8}, //12050 #HANGUL SYLLABLE HIEUH E NIEUN + {0xC7EF, 0xD5EC}, //12051 #HANGUL SYLLABLE HIEUH E RIEUL + {0xC7F0, 0xD5F4}, //12052 #HANGUL SYLLABLE HIEUH E MIEUM + {0xC7F1, 0xD5F5}, //12053 #HANGUL SYLLABLE HIEUH E PIEUP + {0xC7F2, 0xD5F7}, //12054 #HANGUL SYLLABLE HIEUH E SIOS + {0xC7F3, 0xD5F9}, //12055 #HANGUL SYLLABLE HIEUH E IEUNG + {0xC7F4, 0xD600}, //12056 #HANGUL SYLLABLE HIEUH YEO + {0xC7F5, 0xD601}, //12057 #HANGUL SYLLABLE HIEUH YEO KIYEOK + {0xC7F6, 0xD604}, //12058 #HANGUL SYLLABLE HIEUH YEO NIEUN + {0xC7F7, 0xD608}, //12059 #HANGUL SYLLABLE HIEUH YEO RIEUL + {0xC7F8, 0xD610}, //12060 #HANGUL SYLLABLE HIEUH YEO MIEUM + {0xC7F9, 0xD611}, //12061 #HANGUL SYLLABLE HIEUH YEO PIEUP + {0xC7FA, 0xD613}, //12062 #HANGUL SYLLABLE HIEUH YEO SIOS + {0xC7FB, 0xD614}, //12063 #HANGUL SYLLABLE HIEUH YEO SSANGSIOS + {0xC7FC, 0xD615}, //12064 #HANGUL SYLLABLE HIEUH YEO IEUNG + {0xC7FD, 0xD61C}, //12065 #HANGUL SYLLABLE HIEUH YE + {0xC7FE, 0xD620}, //12066 #HANGUL SYLLABLE HIEUH YE NIEUN + {0xC8A1, 0xD624}, //12067 #HANGUL SYLLABLE HIEUH YE RIEUL + {0xC8A2, 0xD62D}, //12068 #HANGUL SYLLABLE HIEUH YE PIEUP + {0xC8A3, 0xD638}, //12069 #HANGUL SYLLABLE HIEUH O + {0xC8A4, 0xD639}, //12070 #HANGUL SYLLABLE HIEUH O KIYEOK + {0xC8A5, 0xD63C}, //12071 #HANGUL SYLLABLE HIEUH O NIEUN + {0xC8A6, 0xD640}, //12072 #HANGUL SYLLABLE HIEUH O RIEUL + {0xC8A7, 0xD645}, //12073 #HANGUL SYLLABLE HIEUH O RIEULTHIEUTH + {0xC8A8, 0xD648}, //12074 #HANGUL SYLLABLE HIEUH O MIEUM + {0xC8A9, 0xD649}, //12075 #HANGUL SYLLABLE HIEUH O PIEUP + {0xC8AA, 0xD64B}, //12076 #HANGUL SYLLABLE HIEUH O SIOS + {0xC8AB, 0xD64D}, //12077 #HANGUL SYLLABLE HIEUH O IEUNG + {0xC8AC, 0xD651}, //12078 #HANGUL SYLLABLE HIEUH O THIEUTH + {0xC8AD, 0xD654}, //12079 #HANGUL SYLLABLE HIEUH WA + {0xC8AE, 0xD655}, //12080 #HANGUL SYLLABLE HIEUH WA KIYEOK + {0xC8AF, 0xD658}, //12081 #HANGUL SYLLABLE HIEUH WA NIEUN + {0xC8B0, 0xD65C}, //12082 #HANGUL SYLLABLE HIEUH WA RIEUL + {0xC8B1, 0xD667}, //12083 #HANGUL SYLLABLE HIEUH WA SIOS + {0xC8B2, 0xD669}, //12084 #HANGUL SYLLABLE HIEUH WA IEUNG + {0xC8B3, 0xD670}, //12085 #HANGUL SYLLABLE HIEUH WAE + {0xC8B4, 0xD671}, //12086 #HANGUL SYLLABLE HIEUH WAE KIYEOK + {0xC8B5, 0xD674}, //12087 #HANGUL SYLLABLE HIEUH WAE NIEUN + {0xC8B6, 0xD683}, //12088 #HANGUL SYLLABLE HIEUH WAE SIOS + {0xC8B7, 0xD685}, //12089 #HANGUL SYLLABLE HIEUH WAE IEUNG + {0xC8B8, 0xD68C}, //12090 #HANGUL SYLLABLE HIEUH OE + {0xC8B9, 0xD68D}, //12091 #HANGUL SYLLABLE HIEUH OE KIYEOK + {0xC8BA, 0xD690}, //12092 #HANGUL SYLLABLE HIEUH OE NIEUN + {0xC8BB, 0xD694}, //12093 #HANGUL SYLLABLE HIEUH OE RIEUL + {0xC8BC, 0xD69D}, //12094 #HANGUL SYLLABLE HIEUH OE PIEUP + {0xC8BD, 0xD69F}, //12095 #HANGUL SYLLABLE HIEUH OE SIOS + {0xC8BE, 0xD6A1}, //12096 #HANGUL SYLLABLE HIEUH OE IEUNG + {0xC8BF, 0xD6A8}, //12097 #HANGUL SYLLABLE HIEUH YO + {0xC8C0, 0xD6AC}, //12098 #HANGUL SYLLABLE HIEUH YO NIEUN + {0xC8C1, 0xD6B0}, //12099 #HANGUL SYLLABLE HIEUH YO RIEUL + {0xC8C2, 0xD6B9}, //12100 #HANGUL SYLLABLE HIEUH YO PIEUP + {0xC8C3, 0xD6BB}, //12101 #HANGUL SYLLABLE HIEUH YO SIOS + {0xC8C4, 0xD6C4}, //12102 #HANGUL SYLLABLE HIEUH U + {0xC8C5, 0xD6C5}, //12103 #HANGUL SYLLABLE HIEUH U KIYEOK + {0xC8C6, 0xD6C8}, //12104 #HANGUL SYLLABLE HIEUH U NIEUN + {0xC8C7, 0xD6CC}, //12105 #HANGUL SYLLABLE HIEUH U RIEUL + {0xC8C8, 0xD6D1}, //12106 #HANGUL SYLLABLE HIEUH U RIEULTHIEUTH + {0xC8C9, 0xD6D4}, //12107 #HANGUL SYLLABLE HIEUH U MIEUM + {0xC8CA, 0xD6D7}, //12108 #HANGUL SYLLABLE HIEUH U SIOS + {0xC8CB, 0xD6D9}, //12109 #HANGUL SYLLABLE HIEUH U IEUNG + {0xC8CC, 0xD6E0}, //12110 #HANGUL SYLLABLE HIEUH WEO + {0xC8CD, 0xD6E4}, //12111 #HANGUL SYLLABLE HIEUH WEO NIEUN + {0xC8CE, 0xD6E8}, //12112 #HANGUL SYLLABLE HIEUH WEO RIEUL + {0xC8CF, 0xD6F0}, //12113 #HANGUL SYLLABLE HIEUH WEO MIEUM + {0xC8D0, 0xD6F5}, //12114 #HANGUL SYLLABLE HIEUH WEO IEUNG + {0xC8D1, 0xD6FC}, //12115 #HANGUL SYLLABLE HIEUH WE + {0xC8D2, 0xD6FD}, //12116 #HANGUL SYLLABLE HIEUH WE KIYEOK + {0xC8D3, 0xD700}, //12117 #HANGUL SYLLABLE HIEUH WE NIEUN + {0xC8D4, 0xD704}, //12118 #HANGUL SYLLABLE HIEUH WE RIEUL + {0xC8D5, 0xD711}, //12119 #HANGUL SYLLABLE HIEUH WE IEUNG + {0xC8D6, 0xD718}, //12120 #HANGUL SYLLABLE HIEUH WI + {0xC8D7, 0xD719}, //12121 #HANGUL SYLLABLE HIEUH WI KIYEOK + {0xC8D8, 0xD71C}, //12122 #HANGUL SYLLABLE HIEUH WI NIEUN + {0xC8D9, 0xD720}, //12123 #HANGUL SYLLABLE HIEUH WI RIEUL + {0xC8DA, 0xD728}, //12124 #HANGUL SYLLABLE HIEUH WI MIEUM + {0xC8DB, 0xD729}, //12125 #HANGUL SYLLABLE HIEUH WI PIEUP + {0xC8DC, 0xD72B}, //12126 #HANGUL SYLLABLE HIEUH WI SIOS + {0xC8DD, 0xD72D}, //12127 #HANGUL SYLLABLE HIEUH WI IEUNG + {0xC8DE, 0xD734}, //12128 #HANGUL SYLLABLE HIEUH YU + {0xC8DF, 0xD735}, //12129 #HANGUL SYLLABLE HIEUH YU KIYEOK + {0xC8E0, 0xD738}, //12130 #HANGUL SYLLABLE HIEUH YU NIEUN + {0xC8E1, 0xD73C}, //12131 #HANGUL SYLLABLE HIEUH YU RIEUL + {0xC8E2, 0xD744}, //12132 #HANGUL SYLLABLE HIEUH YU MIEUM + {0xC8E3, 0xD747}, //12133 #HANGUL SYLLABLE HIEUH YU SIOS + {0xC8E4, 0xD749}, //12134 #HANGUL SYLLABLE HIEUH YU IEUNG + {0xC8E5, 0xD750}, //12135 #HANGUL SYLLABLE HIEUH EU + {0xC8E6, 0xD751}, //12136 #HANGUL SYLLABLE HIEUH EU KIYEOK + {0xC8E7, 0xD754}, //12137 #HANGUL SYLLABLE HIEUH EU NIEUN + {0xC8E8, 0xD756}, //12138 #HANGUL SYLLABLE HIEUH EU NIEUNHIEUH + {0xC8E9, 0xD757}, //12139 #HANGUL SYLLABLE HIEUH EU TIKEUT + {0xC8EA, 0xD758}, //12140 #HANGUL SYLLABLE HIEUH EU RIEUL + {0xC8EB, 0xD759}, //12141 #HANGUL SYLLABLE HIEUH EU RIEULKIYEOK + {0xC8EC, 0xD760}, //12142 #HANGUL SYLLABLE HIEUH EU MIEUM + {0xC8ED, 0xD761}, //12143 #HANGUL SYLLABLE HIEUH EU PIEUP + {0xC8EE, 0xD763}, //12144 #HANGUL SYLLABLE HIEUH EU SIOS + {0xC8EF, 0xD765}, //12145 #HANGUL SYLLABLE HIEUH EU IEUNG + {0xC8F0, 0xD769}, //12146 #HANGUL SYLLABLE HIEUH EU THIEUTH + {0xC8F1, 0xD76C}, //12147 #HANGUL SYLLABLE HIEUH YI + {0xC8F2, 0xD770}, //12148 #HANGUL SYLLABLE HIEUH YI NIEUN + {0xC8F3, 0xD774}, //12149 #HANGUL SYLLABLE HIEUH YI RIEUL + {0xC8F4, 0xD77C}, //12150 #HANGUL SYLLABLE HIEUH YI MIEUM + {0xC8F5, 0xD77D}, //12151 #HANGUL SYLLABLE HIEUH YI PIEUP + {0xC8F6, 0xD781}, //12152 #HANGUL SYLLABLE HIEUH YI IEUNG + {0xC8F7, 0xD788}, //12153 #HANGUL SYLLABLE HIEUH I + {0xC8F8, 0xD789}, //12154 #HANGUL SYLLABLE HIEUH I KIYEOK + {0xC8F9, 0xD78C}, //12155 #HANGUL SYLLABLE HIEUH I NIEUN + {0xC8FA, 0xD790}, //12156 #HANGUL SYLLABLE HIEUH I RIEUL + {0xC8FB, 0xD798}, //12157 #HANGUL SYLLABLE HIEUH I MIEUM + {0xC8FC, 0xD799}, //12158 #HANGUL SYLLABLE HIEUH I PIEUP + {0xC8FD, 0xD79B}, //12159 #HANGUL SYLLABLE HIEUH I SIOS + {0xC8FE, 0xD79D}, //12160 #HANGUL SYLLABLE HIEUH I IEUNG + {0xCAA1, 0x4F3D}, //12161 #CJK UNIFIED IDEOGRAPH + {0xCAA2, 0x4F73}, //12162 #CJK UNIFIED IDEOGRAPH + {0xCAA3, 0x5047}, //12163 #CJK UNIFIED IDEOGRAPH + {0xCAA4, 0x50F9}, //12164 #CJK UNIFIED IDEOGRAPH + {0xCAA5, 0x52A0}, //12165 #CJK UNIFIED IDEOGRAPH + {0xCAA6, 0x53EF}, //12166 #CJK UNIFIED IDEOGRAPH + {0xCAA7, 0x5475}, //12167 #CJK UNIFIED IDEOGRAPH + {0xCAA8, 0x54E5}, //12168 #CJK UNIFIED IDEOGRAPH + {0xCAA9, 0x5609}, //12169 #CJK UNIFIED IDEOGRAPH + {0xCAAA, 0x5AC1}, //12170 #CJK UNIFIED IDEOGRAPH + {0xCAAB, 0x5BB6}, //12171 #CJK UNIFIED IDEOGRAPH + {0xCAAC, 0x6687}, //12172 #CJK UNIFIED IDEOGRAPH + {0xCAAD, 0x67B6}, //12173 #CJK UNIFIED IDEOGRAPH + {0xCAAE, 0x67B7}, //12174 #CJK UNIFIED IDEOGRAPH + {0xCAAF, 0x67EF}, //12175 #CJK UNIFIED IDEOGRAPH + {0xCAB0, 0x6B4C}, //12176 #CJK UNIFIED IDEOGRAPH + {0xCAB1, 0x73C2}, //12177 #CJK UNIFIED IDEOGRAPH + {0xCAB2, 0x75C2}, //12178 #CJK UNIFIED IDEOGRAPH + {0xCAB3, 0x7A3C}, //12179 #CJK UNIFIED IDEOGRAPH + {0xCAB4, 0x82DB}, //12180 #CJK UNIFIED IDEOGRAPH + {0xCAB5, 0x8304}, //12181 #CJK UNIFIED IDEOGRAPH + {0xCAB6, 0x8857}, //12182 #CJK UNIFIED IDEOGRAPH + {0xCAB7, 0x8888}, //12183 #CJK UNIFIED IDEOGRAPH + {0xCAB8, 0x8A36}, //12184 #CJK UNIFIED IDEOGRAPH + {0xCAB9, 0x8CC8}, //12185 #CJK UNIFIED IDEOGRAPH + {0xCABA, 0x8DCF}, //12186 #CJK UNIFIED IDEOGRAPH + {0xCABB, 0x8EFB}, //12187 #CJK UNIFIED IDEOGRAPH + {0xCABC, 0x8FE6}, //12188 #CJK UNIFIED IDEOGRAPH + {0xCABD, 0x99D5}, //12189 #CJK UNIFIED IDEOGRAPH + {0xCABE, 0x523B}, //12190 #CJK UNIFIED IDEOGRAPH + {0xCABF, 0x5374}, //12191 #CJK UNIFIED IDEOGRAPH + {0xCAC0, 0x5404}, //12192 #CJK UNIFIED IDEOGRAPH + {0xCAC1, 0x606A}, //12193 #CJK UNIFIED IDEOGRAPH + {0xCAC2, 0x6164}, //12194 #CJK UNIFIED IDEOGRAPH + {0xCAC3, 0x6BBC}, //12195 #CJK UNIFIED IDEOGRAPH + {0xCAC4, 0x73CF}, //12196 #CJK UNIFIED IDEOGRAPH + {0xCAC5, 0x811A}, //12197 #CJK UNIFIED IDEOGRAPH + {0xCAC6, 0x89BA}, //12198 #CJK UNIFIED IDEOGRAPH + {0xCAC7, 0x89D2}, //12199 #CJK UNIFIED IDEOGRAPH + {0xCAC8, 0x95A3}, //12200 #CJK UNIFIED IDEOGRAPH + {0xCAC9, 0x4F83}, //12201 #CJK UNIFIED IDEOGRAPH + {0xCACA, 0x520A}, //12202 #CJK UNIFIED IDEOGRAPH + {0xCACB, 0x58BE}, //12203 #CJK UNIFIED IDEOGRAPH + {0xCACC, 0x5978}, //12204 #CJK UNIFIED IDEOGRAPH + {0xCACD, 0x59E6}, //12205 #CJK UNIFIED IDEOGRAPH + {0xCACE, 0x5E72}, //12206 #CJK UNIFIED IDEOGRAPH + {0xCACF, 0x5E79}, //12207 #CJK UNIFIED IDEOGRAPH + {0xCAD0, 0x61C7}, //12208 #CJK UNIFIED IDEOGRAPH + {0xCAD1, 0x63C0}, //12209 #CJK UNIFIED IDEOGRAPH + {0xCAD2, 0x6746}, //12210 #CJK UNIFIED IDEOGRAPH + {0xCAD3, 0x67EC}, //12211 #CJK UNIFIED IDEOGRAPH + {0xCAD4, 0x687F}, //12212 #CJK UNIFIED IDEOGRAPH + {0xCAD5, 0x6F97}, //12213 #CJK UNIFIED IDEOGRAPH + {0xCAD6, 0x764E}, //12214 #CJK UNIFIED IDEOGRAPH + {0xCAD7, 0x770B}, //12215 #CJK UNIFIED IDEOGRAPH + {0xCAD8, 0x78F5}, //12216 #CJK UNIFIED IDEOGRAPH + {0xCAD9, 0x7A08}, //12217 #CJK UNIFIED IDEOGRAPH + {0xCADA, 0x7AFF}, //12218 #CJK UNIFIED IDEOGRAPH + {0xCADB, 0x7C21}, //12219 #CJK UNIFIED IDEOGRAPH + {0xCADC, 0x809D}, //12220 #CJK UNIFIED IDEOGRAPH + {0xCADD, 0x826E}, //12221 #CJK UNIFIED IDEOGRAPH + {0xCADE, 0x8271}, //12222 #CJK UNIFIED IDEOGRAPH + {0xCADF, 0x8AEB}, //12223 #CJK UNIFIED IDEOGRAPH + {0xCAE0, 0x9593}, //12224 #CJK UNIFIED IDEOGRAPH + {0xCAE1, 0x4E6B}, //12225 #CJK UNIFIED IDEOGRAPH + {0xCAE2, 0x559D}, //12226 #CJK UNIFIED IDEOGRAPH + {0xCAE3, 0x66F7}, //12227 #CJK UNIFIED IDEOGRAPH + {0xCAE4, 0x6E34}, //12228 #CJK UNIFIED IDEOGRAPH + {0xCAE5, 0x78A3}, //12229 #CJK UNIFIED IDEOGRAPH + {0xCAE6, 0x7AED}, //12230 #CJK UNIFIED IDEOGRAPH + {0xCAE7, 0x845B}, //12231 #CJK UNIFIED IDEOGRAPH + {0xCAE8, 0x8910}, //12232 #CJK UNIFIED IDEOGRAPH + {0xCAE9, 0x874E}, //12233 #CJK UNIFIED IDEOGRAPH + {0xCAEA, 0x97A8}, //12234 #CJK UNIFIED IDEOGRAPH + {0xCAEB, 0x52D8}, //12235 #CJK UNIFIED IDEOGRAPH + {0xCAEC, 0x574E}, //12236 #CJK UNIFIED IDEOGRAPH + {0xCAED, 0x582A}, //12237 #CJK UNIFIED IDEOGRAPH + {0xCAEE, 0x5D4C}, //12238 #CJK UNIFIED IDEOGRAPH + {0xCAEF, 0x611F}, //12239 #CJK UNIFIED IDEOGRAPH + {0xCAF0, 0x61BE}, //12240 #CJK UNIFIED IDEOGRAPH + {0xCAF1, 0x6221}, //12241 #CJK UNIFIED IDEOGRAPH + {0xCAF2, 0x6562}, //12242 #CJK UNIFIED IDEOGRAPH + {0xCAF3, 0x67D1}, //12243 #CJK UNIFIED IDEOGRAPH + {0xCAF4, 0x6A44}, //12244 #CJK UNIFIED IDEOGRAPH + {0xCAF5, 0x6E1B}, //12245 #CJK UNIFIED IDEOGRAPH + {0xCAF6, 0x7518}, //12246 #CJK UNIFIED IDEOGRAPH + {0xCAF7, 0x75B3}, //12247 #CJK UNIFIED IDEOGRAPH + {0xCAF8, 0x76E3}, //12248 #CJK UNIFIED IDEOGRAPH + {0xCAF9, 0x77B0}, //12249 #CJK UNIFIED IDEOGRAPH + {0xCAFA, 0x7D3A}, //12250 #CJK UNIFIED IDEOGRAPH + {0xCAFB, 0x90AF}, //12251 #CJK UNIFIED IDEOGRAPH + {0xCAFC, 0x9451}, //12252 #CJK UNIFIED IDEOGRAPH + {0xCAFD, 0x9452}, //12253 #CJK UNIFIED IDEOGRAPH + {0xCAFE, 0x9F95}, //12254 #CJK UNIFIED IDEOGRAPH + {0xCBA1, 0x5323}, //12255 #CJK UNIFIED IDEOGRAPH + {0xCBA2, 0x5CAC}, //12256 #CJK UNIFIED IDEOGRAPH + {0xCBA3, 0x7532}, //12257 #CJK UNIFIED IDEOGRAPH + {0xCBA4, 0x80DB}, //12258 #CJK UNIFIED IDEOGRAPH + {0xCBA5, 0x9240}, //12259 #CJK UNIFIED IDEOGRAPH + {0xCBA6, 0x9598}, //12260 #CJK UNIFIED IDEOGRAPH + {0xCBA7, 0x525B}, //12261 #CJK UNIFIED IDEOGRAPH + {0xCBA8, 0x5808}, //12262 #CJK UNIFIED IDEOGRAPH + {0xCBA9, 0x59DC}, //12263 #CJK UNIFIED IDEOGRAPH + {0xCBAA, 0x5CA1}, //12264 #CJK UNIFIED IDEOGRAPH + {0xCBAB, 0x5D17}, //12265 #CJK UNIFIED IDEOGRAPH + {0xCBAC, 0x5EB7}, //12266 #CJK UNIFIED IDEOGRAPH + {0xCBAD, 0x5F3A}, //12267 #CJK UNIFIED IDEOGRAPH + {0xCBAE, 0x5F4A}, //12268 #CJK UNIFIED IDEOGRAPH + {0xCBAF, 0x6177}, //12269 #CJK UNIFIED IDEOGRAPH + {0xCBB0, 0x6C5F}, //12270 #CJK UNIFIED IDEOGRAPH + {0xCBB1, 0x757A}, //12271 #CJK UNIFIED IDEOGRAPH + {0xCBB2, 0x7586}, //12272 #CJK UNIFIED IDEOGRAPH + {0xCBB3, 0x7CE0}, //12273 #CJK UNIFIED IDEOGRAPH + {0xCBB4, 0x7D73}, //12274 #CJK UNIFIED IDEOGRAPH + {0xCBB5, 0x7DB1}, //12275 #CJK UNIFIED IDEOGRAPH + {0xCBB6, 0x7F8C}, //12276 #CJK UNIFIED IDEOGRAPH + {0xCBB7, 0x8154}, //12277 #CJK UNIFIED IDEOGRAPH + {0xCBB8, 0x8221}, //12278 #CJK UNIFIED IDEOGRAPH + {0xCBB9, 0x8591}, //12279 #CJK UNIFIED IDEOGRAPH + {0xCBBA, 0x8941}, //12280 #CJK UNIFIED IDEOGRAPH + {0xCBBB, 0x8B1B}, //12281 #CJK UNIFIED IDEOGRAPH + {0xCBBC, 0x92FC}, //12282 #CJK UNIFIED IDEOGRAPH + {0xCBBD, 0x964D}, //12283 #CJK UNIFIED IDEOGRAPH + {0xCBBE, 0x9C47}, //12284 #CJK UNIFIED IDEOGRAPH + {0xCBBF, 0x4ECB}, //12285 #CJK UNIFIED IDEOGRAPH + {0xCBC0, 0x4EF7}, //12286 #CJK UNIFIED IDEOGRAPH + {0xCBC1, 0x500B}, //12287 #CJK UNIFIED IDEOGRAPH + {0xCBC2, 0x51F1}, //12288 #CJK UNIFIED IDEOGRAPH + {0xCBC3, 0x584F}, //12289 #CJK UNIFIED IDEOGRAPH + {0xCBC4, 0x6137}, //12290 #CJK UNIFIED IDEOGRAPH + {0xCBC5, 0x613E}, //12291 #CJK UNIFIED IDEOGRAPH + {0xCBC6, 0x6168}, //12292 #CJK UNIFIED IDEOGRAPH + {0xCBC7, 0x6539}, //12293 #CJK UNIFIED IDEOGRAPH + {0xCBC8, 0x69EA}, //12294 #CJK UNIFIED IDEOGRAPH + {0xCBC9, 0x6F11}, //12295 #CJK UNIFIED IDEOGRAPH + {0xCBCA, 0x75A5}, //12296 #CJK UNIFIED IDEOGRAPH + {0xCBCB, 0x7686}, //12297 #CJK UNIFIED IDEOGRAPH + {0xCBCC, 0x76D6}, //12298 #CJK UNIFIED IDEOGRAPH + {0xCBCD, 0x7B87}, //12299 #CJK UNIFIED IDEOGRAPH + {0xCBCE, 0x82A5}, //12300 #CJK UNIFIED IDEOGRAPH + {0xCBCF, 0x84CB}, //12301 #CJK UNIFIED IDEOGRAPH + {0xCBD0, 0xF900}, //12302 #CJK COMPATIBILITY IDEOGRAPH + {0xCBD1, 0x93A7}, //12303 #CJK UNIFIED IDEOGRAPH + {0xCBD2, 0x958B}, //12304 #CJK UNIFIED IDEOGRAPH + {0xCBD3, 0x5580}, //12305 #CJK UNIFIED IDEOGRAPH + {0xCBD4, 0x5BA2}, //12306 #CJK UNIFIED IDEOGRAPH + {0xCBD5, 0x5751}, //12307 #CJK UNIFIED IDEOGRAPH + {0xCBD6, 0xF901}, //12308 #CJK COMPATIBILITY IDEOGRAPH + {0xCBD7, 0x7CB3}, //12309 #CJK UNIFIED IDEOGRAPH + {0xCBD8, 0x7FB9}, //12310 #CJK UNIFIED IDEOGRAPH + {0xCBD9, 0x91B5}, //12311 #CJK UNIFIED IDEOGRAPH + {0xCBDA, 0x5028}, //12312 #CJK UNIFIED IDEOGRAPH + {0xCBDB, 0x53BB}, //12313 #CJK UNIFIED IDEOGRAPH + {0xCBDC, 0x5C45}, //12314 #CJK UNIFIED IDEOGRAPH + {0xCBDD, 0x5DE8}, //12315 #CJK UNIFIED IDEOGRAPH + {0xCBDE, 0x62D2}, //12316 #CJK UNIFIED IDEOGRAPH + {0xCBDF, 0x636E}, //12317 #CJK UNIFIED IDEOGRAPH + {0xCBE0, 0x64DA}, //12318 #CJK UNIFIED IDEOGRAPH + {0xCBE1, 0x64E7}, //12319 #CJK UNIFIED IDEOGRAPH + {0xCBE2, 0x6E20}, //12320 #CJK UNIFIED IDEOGRAPH + {0xCBE3, 0x70AC}, //12321 #CJK UNIFIED IDEOGRAPH + {0xCBE4, 0x795B}, //12322 #CJK UNIFIED IDEOGRAPH + {0xCBE5, 0x8DDD}, //12323 #CJK UNIFIED IDEOGRAPH + {0xCBE6, 0x8E1E}, //12324 #CJK UNIFIED IDEOGRAPH + {0xCBE7, 0xF902}, //12325 #CJK COMPATIBILITY IDEOGRAPH + {0xCBE8, 0x907D}, //12326 #CJK UNIFIED IDEOGRAPH + {0xCBE9, 0x9245}, //12327 #CJK UNIFIED IDEOGRAPH + {0xCBEA, 0x92F8}, //12328 #CJK UNIFIED IDEOGRAPH + {0xCBEB, 0x4E7E}, //12329 #CJK UNIFIED IDEOGRAPH + {0xCBEC, 0x4EF6}, //12330 #CJK UNIFIED IDEOGRAPH + {0xCBED, 0x5065}, //12331 #CJK UNIFIED IDEOGRAPH + {0xCBEE, 0x5DFE}, //12332 #CJK UNIFIED IDEOGRAPH + {0xCBEF, 0x5EFA}, //12333 #CJK UNIFIED IDEOGRAPH + {0xCBF0, 0x6106}, //12334 #CJK UNIFIED IDEOGRAPH + {0xCBF1, 0x6957}, //12335 #CJK UNIFIED IDEOGRAPH + {0xCBF2, 0x8171}, //12336 #CJK UNIFIED IDEOGRAPH + {0xCBF3, 0x8654}, //12337 #CJK UNIFIED IDEOGRAPH + {0xCBF4, 0x8E47}, //12338 #CJK UNIFIED IDEOGRAPH + {0xCBF5, 0x9375}, //12339 #CJK UNIFIED IDEOGRAPH + {0xCBF6, 0x9A2B}, //12340 #CJK UNIFIED IDEOGRAPH + {0xCBF7, 0x4E5E}, //12341 #CJK UNIFIED IDEOGRAPH + {0xCBF8, 0x5091}, //12342 #CJK UNIFIED IDEOGRAPH + {0xCBF9, 0x6770}, //12343 #CJK UNIFIED IDEOGRAPH + {0xCBFA, 0x6840}, //12344 #CJK UNIFIED IDEOGRAPH + {0xCBFB, 0x5109}, //12345 #CJK UNIFIED IDEOGRAPH + {0xCBFC, 0x528D}, //12346 #CJK UNIFIED IDEOGRAPH + {0xCBFD, 0x5292}, //12347 #CJK UNIFIED IDEOGRAPH + {0xCBFE, 0x6AA2}, //12348 #CJK UNIFIED IDEOGRAPH + {0xCCA1, 0x77BC}, //12349 #CJK UNIFIED IDEOGRAPH + {0xCCA2, 0x9210}, //12350 #CJK UNIFIED IDEOGRAPH + {0xCCA3, 0x9ED4}, //12351 #CJK UNIFIED IDEOGRAPH + {0xCCA4, 0x52AB}, //12352 #CJK UNIFIED IDEOGRAPH + {0xCCA5, 0x602F}, //12353 #CJK UNIFIED IDEOGRAPH + {0xCCA6, 0x8FF2}, //12354 #CJK UNIFIED IDEOGRAPH + {0xCCA7, 0x5048}, //12355 #CJK UNIFIED IDEOGRAPH + {0xCCA8, 0x61A9}, //12356 #CJK UNIFIED IDEOGRAPH + {0xCCA9, 0x63ED}, //12357 #CJK UNIFIED IDEOGRAPH + {0xCCAA, 0x64CA}, //12358 #CJK UNIFIED IDEOGRAPH + {0xCCAB, 0x683C}, //12359 #CJK UNIFIED IDEOGRAPH + {0xCCAC, 0x6A84}, //12360 #CJK UNIFIED IDEOGRAPH + {0xCCAD, 0x6FC0}, //12361 #CJK UNIFIED IDEOGRAPH + {0xCCAE, 0x8188}, //12362 #CJK UNIFIED IDEOGRAPH + {0xCCAF, 0x89A1}, //12363 #CJK UNIFIED IDEOGRAPH + {0xCCB0, 0x9694}, //12364 #CJK UNIFIED IDEOGRAPH + {0xCCB1, 0x5805}, //12365 #CJK UNIFIED IDEOGRAPH + {0xCCB2, 0x727D}, //12366 #CJK UNIFIED IDEOGRAPH + {0xCCB3, 0x72AC}, //12367 #CJK UNIFIED IDEOGRAPH + {0xCCB4, 0x7504}, //12368 #CJK UNIFIED IDEOGRAPH + {0xCCB5, 0x7D79}, //12369 #CJK UNIFIED IDEOGRAPH + {0xCCB6, 0x7E6D}, //12370 #CJK UNIFIED IDEOGRAPH + {0xCCB7, 0x80A9}, //12371 #CJK UNIFIED IDEOGRAPH + {0xCCB8, 0x898B}, //12372 #CJK UNIFIED IDEOGRAPH + {0xCCB9, 0x8B74}, //12373 #CJK UNIFIED IDEOGRAPH + {0xCCBA, 0x9063}, //12374 #CJK UNIFIED IDEOGRAPH + {0xCCBB, 0x9D51}, //12375 #CJK UNIFIED IDEOGRAPH + {0xCCBC, 0x6289}, //12376 #CJK UNIFIED IDEOGRAPH + {0xCCBD, 0x6C7A}, //12377 #CJK UNIFIED IDEOGRAPH + {0xCCBE, 0x6F54}, //12378 #CJK UNIFIED IDEOGRAPH + {0xCCBF, 0x7D50}, //12379 #CJK UNIFIED IDEOGRAPH + {0xCCC0, 0x7F3A}, //12380 #CJK UNIFIED IDEOGRAPH + {0xCCC1, 0x8A23}, //12381 #CJK UNIFIED IDEOGRAPH + {0xCCC2, 0x517C}, //12382 #CJK UNIFIED IDEOGRAPH + {0xCCC3, 0x614A}, //12383 #CJK UNIFIED IDEOGRAPH + {0xCCC4, 0x7B9D}, //12384 #CJK UNIFIED IDEOGRAPH + {0xCCC5, 0x8B19}, //12385 #CJK UNIFIED IDEOGRAPH + {0xCCC6, 0x9257}, //12386 #CJK UNIFIED IDEOGRAPH + {0xCCC7, 0x938C}, //12387 #CJK UNIFIED IDEOGRAPH + {0xCCC8, 0x4EAC}, //12388 #CJK UNIFIED IDEOGRAPH + {0xCCC9, 0x4FD3}, //12389 #CJK UNIFIED IDEOGRAPH + {0xCCCA, 0x501E}, //12390 #CJK UNIFIED IDEOGRAPH + {0xCCCB, 0x50BE}, //12391 #CJK UNIFIED IDEOGRAPH + {0xCCCC, 0x5106}, //12392 #CJK UNIFIED IDEOGRAPH + {0xCCCD, 0x52C1}, //12393 #CJK UNIFIED IDEOGRAPH + {0xCCCE, 0x52CD}, //12394 #CJK UNIFIED IDEOGRAPH + {0xCCCF, 0x537F}, //12395 #CJK UNIFIED IDEOGRAPH + {0xCCD0, 0x5770}, //12396 #CJK UNIFIED IDEOGRAPH + {0xCCD1, 0x5883}, //12397 #CJK UNIFIED IDEOGRAPH + {0xCCD2, 0x5E9A}, //12398 #CJK UNIFIED IDEOGRAPH + {0xCCD3, 0x5F91}, //12399 #CJK UNIFIED IDEOGRAPH + {0xCCD4, 0x6176}, //12400 #CJK UNIFIED IDEOGRAPH + {0xCCD5, 0x61AC}, //12401 #CJK UNIFIED IDEOGRAPH + {0xCCD6, 0x64CE}, //12402 #CJK UNIFIED IDEOGRAPH + {0xCCD7, 0x656C}, //12403 #CJK UNIFIED IDEOGRAPH + {0xCCD8, 0x666F}, //12404 #CJK UNIFIED IDEOGRAPH + {0xCCD9, 0x66BB}, //12405 #CJK UNIFIED IDEOGRAPH + {0xCCDA, 0x66F4}, //12406 #CJK UNIFIED IDEOGRAPH + {0xCCDB, 0x6897}, //12407 #CJK UNIFIED IDEOGRAPH + {0xCCDC, 0x6D87}, //12408 #CJK UNIFIED IDEOGRAPH + {0xCCDD, 0x7085}, //12409 #CJK UNIFIED IDEOGRAPH + {0xCCDE, 0x70F1}, //12410 #CJK UNIFIED IDEOGRAPH + {0xCCDF, 0x749F}, //12411 #CJK UNIFIED IDEOGRAPH + {0xCCE0, 0x74A5}, //12412 #CJK UNIFIED IDEOGRAPH + {0xCCE1, 0x74CA}, //12413 #CJK UNIFIED IDEOGRAPH + {0xCCE2, 0x75D9}, //12414 #CJK UNIFIED IDEOGRAPH + {0xCCE3, 0x786C}, //12415 #CJK UNIFIED IDEOGRAPH + {0xCCE4, 0x78EC}, //12416 #CJK UNIFIED IDEOGRAPH + {0xCCE5, 0x7ADF}, //12417 #CJK UNIFIED IDEOGRAPH + {0xCCE6, 0x7AF6}, //12418 #CJK UNIFIED IDEOGRAPH + {0xCCE7, 0x7D45}, //12419 #CJK UNIFIED IDEOGRAPH + {0xCCE8, 0x7D93}, //12420 #CJK UNIFIED IDEOGRAPH + {0xCCE9, 0x8015}, //12421 #CJK UNIFIED IDEOGRAPH + {0xCCEA, 0x803F}, //12422 #CJK UNIFIED IDEOGRAPH + {0xCCEB, 0x811B}, //12423 #CJK UNIFIED IDEOGRAPH + {0xCCEC, 0x8396}, //12424 #CJK UNIFIED IDEOGRAPH + {0xCCED, 0x8B66}, //12425 #CJK UNIFIED IDEOGRAPH + {0xCCEE, 0x8F15}, //12426 #CJK UNIFIED IDEOGRAPH + {0xCCEF, 0x9015}, //12427 #CJK UNIFIED IDEOGRAPH + {0xCCF0, 0x93E1}, //12428 #CJK UNIFIED IDEOGRAPH + {0xCCF1, 0x9803}, //12429 #CJK UNIFIED IDEOGRAPH + {0xCCF2, 0x9838}, //12430 #CJK UNIFIED IDEOGRAPH + {0xCCF3, 0x9A5A}, //12431 #CJK UNIFIED IDEOGRAPH + {0xCCF4, 0x9BE8}, //12432 #CJK UNIFIED IDEOGRAPH + {0xCCF5, 0x4FC2}, //12433 #CJK UNIFIED IDEOGRAPH + {0xCCF6, 0x5553}, //12434 #CJK UNIFIED IDEOGRAPH + {0xCCF7, 0x583A}, //12435 #CJK UNIFIED IDEOGRAPH + {0xCCF8, 0x5951}, //12436 #CJK UNIFIED IDEOGRAPH + {0xCCF9, 0x5B63}, //12437 #CJK UNIFIED IDEOGRAPH + {0xCCFA, 0x5C46}, //12438 #CJK UNIFIED IDEOGRAPH + {0xCCFB, 0x60B8}, //12439 #CJK UNIFIED IDEOGRAPH + {0xCCFC, 0x6212}, //12440 #CJK UNIFIED IDEOGRAPH + {0xCCFD, 0x6842}, //12441 #CJK UNIFIED IDEOGRAPH + {0xCCFE, 0x68B0}, //12442 #CJK UNIFIED IDEOGRAPH + {0xCDA1, 0x68E8}, //12443 #CJK UNIFIED IDEOGRAPH + {0xCDA2, 0x6EAA}, //12444 #CJK UNIFIED IDEOGRAPH + {0xCDA3, 0x754C}, //12445 #CJK UNIFIED IDEOGRAPH + {0xCDA4, 0x7678}, //12446 #CJK UNIFIED IDEOGRAPH + {0xCDA5, 0x78CE}, //12447 #CJK UNIFIED IDEOGRAPH + {0xCDA6, 0x7A3D}, //12448 #CJK UNIFIED IDEOGRAPH + {0xCDA7, 0x7CFB}, //12449 #CJK UNIFIED IDEOGRAPH + {0xCDA8, 0x7E6B}, //12450 #CJK UNIFIED IDEOGRAPH + {0xCDA9, 0x7E7C}, //12451 #CJK UNIFIED IDEOGRAPH + {0xCDAA, 0x8A08}, //12452 #CJK UNIFIED IDEOGRAPH + {0xCDAB, 0x8AA1}, //12453 #CJK UNIFIED IDEOGRAPH + {0xCDAC, 0x8C3F}, //12454 #CJK UNIFIED IDEOGRAPH + {0xCDAD, 0x968E}, //12455 #CJK UNIFIED IDEOGRAPH + {0xCDAE, 0x9DC4}, //12456 #CJK UNIFIED IDEOGRAPH + {0xCDAF, 0x53E4}, //12457 #CJK UNIFIED IDEOGRAPH + {0xCDB0, 0x53E9}, //12458 #CJK UNIFIED IDEOGRAPH + {0xCDB1, 0x544A}, //12459 #CJK UNIFIED IDEOGRAPH + {0xCDB2, 0x5471}, //12460 #CJK UNIFIED IDEOGRAPH + {0xCDB3, 0x56FA}, //12461 #CJK UNIFIED IDEOGRAPH + {0xCDB4, 0x59D1}, //12462 #CJK UNIFIED IDEOGRAPH + {0xCDB5, 0x5B64}, //12463 #CJK UNIFIED IDEOGRAPH + {0xCDB6, 0x5C3B}, //12464 #CJK UNIFIED IDEOGRAPH + {0xCDB7, 0x5EAB}, //12465 #CJK UNIFIED IDEOGRAPH + {0xCDB8, 0x62F7}, //12466 #CJK UNIFIED IDEOGRAPH + {0xCDB9, 0x6537}, //12467 #CJK UNIFIED IDEOGRAPH + {0xCDBA, 0x6545}, //12468 #CJK UNIFIED IDEOGRAPH + {0xCDBB, 0x6572}, //12469 #CJK UNIFIED IDEOGRAPH + {0xCDBC, 0x66A0}, //12470 #CJK UNIFIED IDEOGRAPH + {0xCDBD, 0x67AF}, //12471 #CJK UNIFIED IDEOGRAPH + {0xCDBE, 0x69C1}, //12472 #CJK UNIFIED IDEOGRAPH + {0xCDBF, 0x6CBD}, //12473 #CJK UNIFIED IDEOGRAPH + {0xCDC0, 0x75FC}, //12474 #CJK UNIFIED IDEOGRAPH + {0xCDC1, 0x7690}, //12475 #CJK UNIFIED IDEOGRAPH + {0xCDC2, 0x777E}, //12476 #CJK UNIFIED IDEOGRAPH + {0xCDC3, 0x7A3F}, //12477 #CJK UNIFIED IDEOGRAPH + {0xCDC4, 0x7F94}, //12478 #CJK UNIFIED IDEOGRAPH + {0xCDC5, 0x8003}, //12479 #CJK UNIFIED IDEOGRAPH + {0xCDC6, 0x80A1}, //12480 #CJK UNIFIED IDEOGRAPH + {0xCDC7, 0x818F}, //12481 #CJK UNIFIED IDEOGRAPH + {0xCDC8, 0x82E6}, //12482 #CJK UNIFIED IDEOGRAPH + {0xCDC9, 0x82FD}, //12483 #CJK UNIFIED IDEOGRAPH + {0xCDCA, 0x83F0}, //12484 #CJK UNIFIED IDEOGRAPH + {0xCDCB, 0x85C1}, //12485 #CJK UNIFIED IDEOGRAPH + {0xCDCC, 0x8831}, //12486 #CJK UNIFIED IDEOGRAPH + {0xCDCD, 0x88B4}, //12487 #CJK UNIFIED IDEOGRAPH + {0xCDCE, 0x8AA5}, //12488 #CJK UNIFIED IDEOGRAPH + {0xCDCF, 0xF903}, //12489 #CJK COMPATIBILITY IDEOGRAPH + {0xCDD0, 0x8F9C}, //12490 #CJK UNIFIED IDEOGRAPH + {0xCDD1, 0x932E}, //12491 #CJK UNIFIED IDEOGRAPH + {0xCDD2, 0x96C7}, //12492 #CJK UNIFIED IDEOGRAPH + {0xCDD3, 0x9867}, //12493 #CJK UNIFIED IDEOGRAPH + {0xCDD4, 0x9AD8}, //12494 #CJK UNIFIED IDEOGRAPH + {0xCDD5, 0x9F13}, //12495 #CJK UNIFIED IDEOGRAPH + {0xCDD6, 0x54ED}, //12496 #CJK UNIFIED IDEOGRAPH + {0xCDD7, 0x659B}, //12497 #CJK UNIFIED IDEOGRAPH + {0xCDD8, 0x66F2}, //12498 #CJK UNIFIED IDEOGRAPH + {0xCDD9, 0x688F}, //12499 #CJK UNIFIED IDEOGRAPH + {0xCDDA, 0x7A40}, //12500 #CJK UNIFIED IDEOGRAPH + {0xCDDB, 0x8C37}, //12501 #CJK UNIFIED IDEOGRAPH + {0xCDDC, 0x9D60}, //12502 #CJK UNIFIED IDEOGRAPH + {0xCDDD, 0x56F0}, //12503 #CJK UNIFIED IDEOGRAPH + {0xCDDE, 0x5764}, //12504 #CJK UNIFIED IDEOGRAPH + {0xCDDF, 0x5D11}, //12505 #CJK UNIFIED IDEOGRAPH + {0xCDE0, 0x6606}, //12506 #CJK UNIFIED IDEOGRAPH + {0xCDE1, 0x68B1}, //12507 #CJK UNIFIED IDEOGRAPH + {0xCDE2, 0x68CD}, //12508 #CJK UNIFIED IDEOGRAPH + {0xCDE3, 0x6EFE}, //12509 #CJK UNIFIED IDEOGRAPH + {0xCDE4, 0x7428}, //12510 #CJK UNIFIED IDEOGRAPH + {0xCDE5, 0x889E}, //12511 #CJK UNIFIED IDEOGRAPH + {0xCDE6, 0x9BE4}, //12512 #CJK UNIFIED IDEOGRAPH + {0xCDE7, 0x6C68}, //12513 #CJK UNIFIED IDEOGRAPH + {0xCDE8, 0xF904}, //12514 #CJK COMPATIBILITY IDEOGRAPH + {0xCDE9, 0x9AA8}, //12515 #CJK UNIFIED IDEOGRAPH + {0xCDEA, 0x4F9B}, //12516 #CJK UNIFIED IDEOGRAPH + {0xCDEB, 0x516C}, //12517 #CJK UNIFIED IDEOGRAPH + {0xCDEC, 0x5171}, //12518 #CJK UNIFIED IDEOGRAPH + {0xCDED, 0x529F}, //12519 #CJK UNIFIED IDEOGRAPH + {0xCDEE, 0x5B54}, //12520 #CJK UNIFIED IDEOGRAPH + {0xCDEF, 0x5DE5}, //12521 #CJK UNIFIED IDEOGRAPH + {0xCDF0, 0x6050}, //12522 #CJK UNIFIED IDEOGRAPH + {0xCDF1, 0x606D}, //12523 #CJK UNIFIED IDEOGRAPH + {0xCDF2, 0x62F1}, //12524 #CJK UNIFIED IDEOGRAPH + {0xCDF3, 0x63A7}, //12525 #CJK UNIFIED IDEOGRAPH + {0xCDF4, 0x653B}, //12526 #CJK UNIFIED IDEOGRAPH + {0xCDF5, 0x73D9}, //12527 #CJK UNIFIED IDEOGRAPH + {0xCDF6, 0x7A7A}, //12528 #CJK UNIFIED IDEOGRAPH + {0xCDF7, 0x86A3}, //12529 #CJK UNIFIED IDEOGRAPH + {0xCDF8, 0x8CA2}, //12530 #CJK UNIFIED IDEOGRAPH + {0xCDF9, 0x978F}, //12531 #CJK UNIFIED IDEOGRAPH + {0xCDFA, 0x4E32}, //12532 #CJK UNIFIED IDEOGRAPH + {0xCDFB, 0x5BE1}, //12533 #CJK UNIFIED IDEOGRAPH + {0xCDFC, 0x6208}, //12534 #CJK UNIFIED IDEOGRAPH + {0xCDFD, 0x679C}, //12535 #CJK UNIFIED IDEOGRAPH + {0xCDFE, 0x74DC}, //12536 #CJK UNIFIED IDEOGRAPH + {0xCEA1, 0x79D1}, //12537 #CJK UNIFIED IDEOGRAPH + {0xCEA2, 0x83D3}, //12538 #CJK UNIFIED IDEOGRAPH + {0xCEA3, 0x8A87}, //12539 #CJK UNIFIED IDEOGRAPH + {0xCEA4, 0x8AB2}, //12540 #CJK UNIFIED IDEOGRAPH + {0xCEA5, 0x8DE8}, //12541 #CJK UNIFIED IDEOGRAPH + {0xCEA6, 0x904E}, //12542 #CJK UNIFIED IDEOGRAPH + {0xCEA7, 0x934B}, //12543 #CJK UNIFIED IDEOGRAPH + {0xCEA8, 0x9846}, //12544 #CJK UNIFIED IDEOGRAPH + {0xCEA9, 0x5ED3}, //12545 #CJK UNIFIED IDEOGRAPH + {0xCEAA, 0x69E8}, //12546 #CJK UNIFIED IDEOGRAPH + {0xCEAB, 0x85FF}, //12547 #CJK UNIFIED IDEOGRAPH + {0xCEAC, 0x90ED}, //12548 #CJK UNIFIED IDEOGRAPH + {0xCEAD, 0xF905}, //12549 #CJK COMPATIBILITY IDEOGRAPH + {0xCEAE, 0x51A0}, //12550 #CJK UNIFIED IDEOGRAPH + {0xCEAF, 0x5B98}, //12551 #CJK UNIFIED IDEOGRAPH + {0xCEB0, 0x5BEC}, //12552 #CJK UNIFIED IDEOGRAPH + {0xCEB1, 0x6163}, //12553 #CJK UNIFIED IDEOGRAPH + {0xCEB2, 0x68FA}, //12554 #CJK UNIFIED IDEOGRAPH + {0xCEB3, 0x6B3E}, //12555 #CJK UNIFIED IDEOGRAPH + {0xCEB4, 0x704C}, //12556 #CJK UNIFIED IDEOGRAPH + {0xCEB5, 0x742F}, //12557 #CJK UNIFIED IDEOGRAPH + {0xCEB6, 0x74D8}, //12558 #CJK UNIFIED IDEOGRAPH + {0xCEB7, 0x7BA1}, //12559 #CJK UNIFIED IDEOGRAPH + {0xCEB8, 0x7F50}, //12560 #CJK UNIFIED IDEOGRAPH + {0xCEB9, 0x83C5}, //12561 #CJK UNIFIED IDEOGRAPH + {0xCEBA, 0x89C0}, //12562 #CJK UNIFIED IDEOGRAPH + {0xCEBB, 0x8CAB}, //12563 #CJK UNIFIED IDEOGRAPH + {0xCEBC, 0x95DC}, //12564 #CJK UNIFIED IDEOGRAPH + {0xCEBD, 0x9928}, //12565 #CJK UNIFIED IDEOGRAPH + {0xCEBE, 0x522E}, //12566 #CJK UNIFIED IDEOGRAPH + {0xCEBF, 0x605D}, //12567 #CJK UNIFIED IDEOGRAPH + {0xCEC0, 0x62EC}, //12568 #CJK UNIFIED IDEOGRAPH + {0xCEC1, 0x9002}, //12569 #CJK UNIFIED IDEOGRAPH + {0xCEC2, 0x4F8A}, //12570 #CJK UNIFIED IDEOGRAPH + {0xCEC3, 0x5149}, //12571 #CJK UNIFIED IDEOGRAPH + {0xCEC4, 0x5321}, //12572 #CJK UNIFIED IDEOGRAPH + {0xCEC5, 0x58D9}, //12573 #CJK UNIFIED IDEOGRAPH + {0xCEC6, 0x5EE3}, //12574 #CJK UNIFIED IDEOGRAPH + {0xCEC7, 0x66E0}, //12575 #CJK UNIFIED IDEOGRAPH + {0xCEC8, 0x6D38}, //12576 #CJK UNIFIED IDEOGRAPH + {0xCEC9, 0x709A}, //12577 #CJK UNIFIED IDEOGRAPH + {0xCECA, 0x72C2}, //12578 #CJK UNIFIED IDEOGRAPH + {0xCECB, 0x73D6}, //12579 #CJK UNIFIED IDEOGRAPH + {0xCECC, 0x7B50}, //12580 #CJK UNIFIED IDEOGRAPH + {0xCECD, 0x80F1}, //12581 #CJK UNIFIED IDEOGRAPH + {0xCECE, 0x945B}, //12582 #CJK UNIFIED IDEOGRAPH + {0xCECF, 0x5366}, //12583 #CJK UNIFIED IDEOGRAPH + {0xCED0, 0x639B}, //12584 #CJK UNIFIED IDEOGRAPH + {0xCED1, 0x7F6B}, //12585 #CJK UNIFIED IDEOGRAPH + {0xCED2, 0x4E56}, //12586 #CJK UNIFIED IDEOGRAPH + {0xCED3, 0x5080}, //12587 #CJK UNIFIED IDEOGRAPH + {0xCED4, 0x584A}, //12588 #CJK UNIFIED IDEOGRAPH + {0xCED5, 0x58DE}, //12589 #CJK UNIFIED IDEOGRAPH + {0xCED6, 0x602A}, //12590 #CJK UNIFIED IDEOGRAPH + {0xCED7, 0x6127}, //12591 #CJK UNIFIED IDEOGRAPH + {0xCED8, 0x62D0}, //12592 #CJK UNIFIED IDEOGRAPH + {0xCED9, 0x69D0}, //12593 #CJK UNIFIED IDEOGRAPH + {0xCEDA, 0x9B41}, //12594 #CJK UNIFIED IDEOGRAPH + {0xCEDB, 0x5B8F}, //12595 #CJK UNIFIED IDEOGRAPH + {0xCEDC, 0x7D18}, //12596 #CJK UNIFIED IDEOGRAPH + {0xCEDD, 0x80B1}, //12597 #CJK UNIFIED IDEOGRAPH + {0xCEDE, 0x8F5F}, //12598 #CJK UNIFIED IDEOGRAPH + {0xCEDF, 0x4EA4}, //12599 #CJK UNIFIED IDEOGRAPH + {0xCEE0, 0x50D1}, //12600 #CJK UNIFIED IDEOGRAPH + {0xCEE1, 0x54AC}, //12601 #CJK UNIFIED IDEOGRAPH + {0xCEE2, 0x55AC}, //12602 #CJK UNIFIED IDEOGRAPH + {0xCEE3, 0x5B0C}, //12603 #CJK UNIFIED IDEOGRAPH + {0xCEE4, 0x5DA0}, //12604 #CJK UNIFIED IDEOGRAPH + {0xCEE5, 0x5DE7}, //12605 #CJK UNIFIED IDEOGRAPH + {0xCEE6, 0x652A}, //12606 #CJK UNIFIED IDEOGRAPH + {0xCEE7, 0x654E}, //12607 #CJK UNIFIED IDEOGRAPH + {0xCEE8, 0x6821}, //12608 #CJK UNIFIED IDEOGRAPH + {0xCEE9, 0x6A4B}, //12609 #CJK UNIFIED IDEOGRAPH + {0xCEEA, 0x72E1}, //12610 #CJK UNIFIED IDEOGRAPH + {0xCEEB, 0x768E}, //12611 #CJK UNIFIED IDEOGRAPH + {0xCEEC, 0x77EF}, //12612 #CJK UNIFIED IDEOGRAPH + {0xCEED, 0x7D5E}, //12613 #CJK UNIFIED IDEOGRAPH + {0xCEEE, 0x7FF9}, //12614 #CJK UNIFIED IDEOGRAPH + {0xCEEF, 0x81A0}, //12615 #CJK UNIFIED IDEOGRAPH + {0xCEF0, 0x854E}, //12616 #CJK UNIFIED IDEOGRAPH + {0xCEF1, 0x86DF}, //12617 #CJK UNIFIED IDEOGRAPH + {0xCEF2, 0x8F03}, //12618 #CJK UNIFIED IDEOGRAPH + {0xCEF3, 0x8F4E}, //12619 #CJK UNIFIED IDEOGRAPH + {0xCEF4, 0x90CA}, //12620 #CJK UNIFIED IDEOGRAPH + {0xCEF5, 0x9903}, //12621 #CJK UNIFIED IDEOGRAPH + {0xCEF6, 0x9A55}, //12622 #CJK UNIFIED IDEOGRAPH + {0xCEF7, 0x9BAB}, //12623 #CJK UNIFIED IDEOGRAPH + {0xCEF8, 0x4E18}, //12624 #CJK UNIFIED IDEOGRAPH + {0xCEF9, 0x4E45}, //12625 #CJK UNIFIED IDEOGRAPH + {0xCEFA, 0x4E5D}, //12626 #CJK UNIFIED IDEOGRAPH + {0xCEFB, 0x4EC7}, //12627 #CJK UNIFIED IDEOGRAPH + {0xCEFC, 0x4FF1}, //12628 #CJK UNIFIED IDEOGRAPH + {0xCEFD, 0x5177}, //12629 #CJK UNIFIED IDEOGRAPH + {0xCEFE, 0x52FE}, //12630 #CJK UNIFIED IDEOGRAPH + {0xCFA1, 0x5340}, //12631 #CJK UNIFIED IDEOGRAPH + {0xCFA2, 0x53E3}, //12632 #CJK UNIFIED IDEOGRAPH + {0xCFA3, 0x53E5}, //12633 #CJK UNIFIED IDEOGRAPH + {0xCFA4, 0x548E}, //12634 #CJK UNIFIED IDEOGRAPH + {0xCFA5, 0x5614}, //12635 #CJK UNIFIED IDEOGRAPH + {0xCFA6, 0x5775}, //12636 #CJK UNIFIED IDEOGRAPH + {0xCFA7, 0x57A2}, //12637 #CJK UNIFIED IDEOGRAPH + {0xCFA8, 0x5BC7}, //12638 #CJK UNIFIED IDEOGRAPH + {0xCFA9, 0x5D87}, //12639 #CJK UNIFIED IDEOGRAPH + {0xCFAA, 0x5ED0}, //12640 #CJK UNIFIED IDEOGRAPH + {0xCFAB, 0x61FC}, //12641 #CJK UNIFIED IDEOGRAPH + {0xCFAC, 0x62D8}, //12642 #CJK UNIFIED IDEOGRAPH + {0xCFAD, 0x6551}, //12643 #CJK UNIFIED IDEOGRAPH + {0xCFAE, 0x67B8}, //12644 #CJK UNIFIED IDEOGRAPH + {0xCFAF, 0x67E9}, //12645 #CJK UNIFIED IDEOGRAPH + {0xCFB0, 0x69CB}, //12646 #CJK UNIFIED IDEOGRAPH + {0xCFB1, 0x6B50}, //12647 #CJK UNIFIED IDEOGRAPH + {0xCFB2, 0x6BC6}, //12648 #CJK UNIFIED IDEOGRAPH + {0xCFB3, 0x6BEC}, //12649 #CJK UNIFIED IDEOGRAPH + {0xCFB4, 0x6C42}, //12650 #CJK UNIFIED IDEOGRAPH + {0xCFB5, 0x6E9D}, //12651 #CJK UNIFIED IDEOGRAPH + {0xCFB6, 0x7078}, //12652 #CJK UNIFIED IDEOGRAPH + {0xCFB7, 0x72D7}, //12653 #CJK UNIFIED IDEOGRAPH + {0xCFB8, 0x7396}, //12654 #CJK UNIFIED IDEOGRAPH + {0xCFB9, 0x7403}, //12655 #CJK UNIFIED IDEOGRAPH + {0xCFBA, 0x77BF}, //12656 #CJK UNIFIED IDEOGRAPH + {0xCFBB, 0x77E9}, //12657 #CJK UNIFIED IDEOGRAPH + {0xCFBC, 0x7A76}, //12658 #CJK UNIFIED IDEOGRAPH + {0xCFBD, 0x7D7F}, //12659 #CJK UNIFIED IDEOGRAPH + {0xCFBE, 0x8009}, //12660 #CJK UNIFIED IDEOGRAPH + {0xCFBF, 0x81FC}, //12661 #CJK UNIFIED IDEOGRAPH + {0xCFC0, 0x8205}, //12662 #CJK UNIFIED IDEOGRAPH + {0xCFC1, 0x820A}, //12663 #CJK UNIFIED IDEOGRAPH + {0xCFC2, 0x82DF}, //12664 #CJK UNIFIED IDEOGRAPH + {0xCFC3, 0x8862}, //12665 #CJK UNIFIED IDEOGRAPH + {0xCFC4, 0x8B33}, //12666 #CJK UNIFIED IDEOGRAPH + {0xCFC5, 0x8CFC}, //12667 #CJK UNIFIED IDEOGRAPH + {0xCFC6, 0x8EC0}, //12668 #CJK UNIFIED IDEOGRAPH + {0xCFC7, 0x9011}, //12669 #CJK UNIFIED IDEOGRAPH + {0xCFC8, 0x90B1}, //12670 #CJK UNIFIED IDEOGRAPH + {0xCFC9, 0x9264}, //12671 #CJK UNIFIED IDEOGRAPH + {0xCFCA, 0x92B6}, //12672 #CJK UNIFIED IDEOGRAPH + {0xCFCB, 0x99D2}, //12673 #CJK UNIFIED IDEOGRAPH + {0xCFCC, 0x9A45}, //12674 #CJK UNIFIED IDEOGRAPH + {0xCFCD, 0x9CE9}, //12675 #CJK UNIFIED IDEOGRAPH + {0xCFCE, 0x9DD7}, //12676 #CJK UNIFIED IDEOGRAPH + {0xCFCF, 0x9F9C}, //12677 #CJK UNIFIED IDEOGRAPH + {0xCFD0, 0x570B}, //12678 #CJK UNIFIED IDEOGRAPH + {0xCFD1, 0x5C40}, //12679 #CJK UNIFIED IDEOGRAPH + {0xCFD2, 0x83CA}, //12680 #CJK UNIFIED IDEOGRAPH + {0xCFD3, 0x97A0}, //12681 #CJK UNIFIED IDEOGRAPH + {0xCFD4, 0x97AB}, //12682 #CJK UNIFIED IDEOGRAPH + {0xCFD5, 0x9EB4}, //12683 #CJK UNIFIED IDEOGRAPH + {0xCFD6, 0x541B}, //12684 #CJK UNIFIED IDEOGRAPH + {0xCFD7, 0x7A98}, //12685 #CJK UNIFIED IDEOGRAPH + {0xCFD8, 0x7FA4}, //12686 #CJK UNIFIED IDEOGRAPH + {0xCFD9, 0x88D9}, //12687 #CJK UNIFIED IDEOGRAPH + {0xCFDA, 0x8ECD}, //12688 #CJK UNIFIED IDEOGRAPH + {0xCFDB, 0x90E1}, //12689 #CJK UNIFIED IDEOGRAPH + {0xCFDC, 0x5800}, //12690 #CJK UNIFIED IDEOGRAPH + {0xCFDD, 0x5C48}, //12691 #CJK UNIFIED IDEOGRAPH + {0xCFDE, 0x6398}, //12692 #CJK UNIFIED IDEOGRAPH + {0xCFDF, 0x7A9F}, //12693 #CJK UNIFIED IDEOGRAPH + {0xCFE0, 0x5BAE}, //12694 #CJK UNIFIED IDEOGRAPH + {0xCFE1, 0x5F13}, //12695 #CJK UNIFIED IDEOGRAPH + {0xCFE2, 0x7A79}, //12696 #CJK UNIFIED IDEOGRAPH + {0xCFE3, 0x7AAE}, //12697 #CJK UNIFIED IDEOGRAPH + {0xCFE4, 0x828E}, //12698 #CJK UNIFIED IDEOGRAPH + {0xCFE5, 0x8EAC}, //12699 #CJK UNIFIED IDEOGRAPH + {0xCFE6, 0x5026}, //12700 #CJK UNIFIED IDEOGRAPH + {0xCFE7, 0x5238}, //12701 #CJK UNIFIED IDEOGRAPH + {0xCFE8, 0x52F8}, //12702 #CJK UNIFIED IDEOGRAPH + {0xCFE9, 0x5377}, //12703 #CJK UNIFIED IDEOGRAPH + {0xCFEA, 0x5708}, //12704 #CJK UNIFIED IDEOGRAPH + {0xCFEB, 0x62F3}, //12705 #CJK UNIFIED IDEOGRAPH + {0xCFEC, 0x6372}, //12706 #CJK UNIFIED IDEOGRAPH + {0xCFED, 0x6B0A}, //12707 #CJK UNIFIED IDEOGRAPH + {0xCFEE, 0x6DC3}, //12708 #CJK UNIFIED IDEOGRAPH + {0xCFEF, 0x7737}, //12709 #CJK UNIFIED IDEOGRAPH + {0xCFF0, 0x53A5}, //12710 #CJK UNIFIED IDEOGRAPH + {0xCFF1, 0x7357}, //12711 #CJK UNIFIED IDEOGRAPH + {0xCFF2, 0x8568}, //12712 #CJK UNIFIED IDEOGRAPH + {0xCFF3, 0x8E76}, //12713 #CJK UNIFIED IDEOGRAPH + {0xCFF4, 0x95D5}, //12714 #CJK UNIFIED IDEOGRAPH + {0xCFF5, 0x673A}, //12715 #CJK UNIFIED IDEOGRAPH + {0xCFF6, 0x6AC3}, //12716 #CJK UNIFIED IDEOGRAPH + {0xCFF7, 0x6F70}, //12717 #CJK UNIFIED IDEOGRAPH + {0xCFF8, 0x8A6D}, //12718 #CJK UNIFIED IDEOGRAPH + {0xCFF9, 0x8ECC}, //12719 #CJK UNIFIED IDEOGRAPH + {0xCFFA, 0x994B}, //12720 #CJK UNIFIED IDEOGRAPH + {0xCFFB, 0xF906}, //12721 #CJK COMPATIBILITY IDEOGRAPH + {0xCFFC, 0x6677}, //12722 #CJK UNIFIED IDEOGRAPH + {0xCFFD, 0x6B78}, //12723 #CJK UNIFIED IDEOGRAPH + {0xCFFE, 0x8CB4}, //12724 #CJK UNIFIED IDEOGRAPH + {0xD0A1, 0x9B3C}, //12725 #CJK UNIFIED IDEOGRAPH + {0xD0A2, 0xF907}, //12726 #CJK COMPATIBILITY IDEOGRAPH + {0xD0A3, 0x53EB}, //12727 #CJK UNIFIED IDEOGRAPH + {0xD0A4, 0x572D}, //12728 #CJK UNIFIED IDEOGRAPH + {0xD0A5, 0x594E}, //12729 #CJK UNIFIED IDEOGRAPH + {0xD0A6, 0x63C6}, //12730 #CJK UNIFIED IDEOGRAPH + {0xD0A7, 0x69FB}, //12731 #CJK UNIFIED IDEOGRAPH + {0xD0A8, 0x73EA}, //12732 #CJK UNIFIED IDEOGRAPH + {0xD0A9, 0x7845}, //12733 #CJK UNIFIED IDEOGRAPH + {0xD0AA, 0x7ABA}, //12734 #CJK UNIFIED IDEOGRAPH + {0xD0AB, 0x7AC5}, //12735 #CJK UNIFIED IDEOGRAPH + {0xD0AC, 0x7CFE}, //12736 #CJK UNIFIED IDEOGRAPH + {0xD0AD, 0x8475}, //12737 #CJK UNIFIED IDEOGRAPH + {0xD0AE, 0x898F}, //12738 #CJK UNIFIED IDEOGRAPH + {0xD0AF, 0x8D73}, //12739 #CJK UNIFIED IDEOGRAPH + {0xD0B0, 0x9035}, //12740 #CJK UNIFIED IDEOGRAPH + {0xD0B1, 0x95A8}, //12741 #CJK UNIFIED IDEOGRAPH + {0xD0B2, 0x52FB}, //12742 #CJK UNIFIED IDEOGRAPH + {0xD0B3, 0x5747}, //12743 #CJK UNIFIED IDEOGRAPH + {0xD0B4, 0x7547}, //12744 #CJK UNIFIED IDEOGRAPH + {0xD0B5, 0x7B60}, //12745 #CJK UNIFIED IDEOGRAPH + {0xD0B6, 0x83CC}, //12746 #CJK UNIFIED IDEOGRAPH + {0xD0B7, 0x921E}, //12747 #CJK UNIFIED IDEOGRAPH + {0xD0B8, 0xF908}, //12748 #CJK COMPATIBILITY IDEOGRAPH + {0xD0B9, 0x6A58}, //12749 #CJK UNIFIED IDEOGRAPH + {0xD0BA, 0x514B}, //12750 #CJK UNIFIED IDEOGRAPH + {0xD0BB, 0x524B}, //12751 #CJK UNIFIED IDEOGRAPH + {0xD0BC, 0x5287}, //12752 #CJK UNIFIED IDEOGRAPH + {0xD0BD, 0x621F}, //12753 #CJK UNIFIED IDEOGRAPH + {0xD0BE, 0x68D8}, //12754 #CJK UNIFIED IDEOGRAPH + {0xD0BF, 0x6975}, //12755 #CJK UNIFIED IDEOGRAPH + {0xD0C0, 0x9699}, //12756 #CJK UNIFIED IDEOGRAPH + {0xD0C1, 0x50C5}, //12757 #CJK UNIFIED IDEOGRAPH + {0xD0C2, 0x52A4}, //12758 #CJK UNIFIED IDEOGRAPH + {0xD0C3, 0x52E4}, //12759 #CJK UNIFIED IDEOGRAPH + {0xD0C4, 0x61C3}, //12760 #CJK UNIFIED IDEOGRAPH + {0xD0C5, 0x65A4}, //12761 #CJK UNIFIED IDEOGRAPH + {0xD0C6, 0x6839}, //12762 #CJK UNIFIED IDEOGRAPH + {0xD0C7, 0x69FF}, //12763 #CJK UNIFIED IDEOGRAPH + {0xD0C8, 0x747E}, //12764 #CJK UNIFIED IDEOGRAPH + {0xD0C9, 0x7B4B}, //12765 #CJK UNIFIED IDEOGRAPH + {0xD0CA, 0x82B9}, //12766 #CJK UNIFIED IDEOGRAPH + {0xD0CB, 0x83EB}, //12767 #CJK UNIFIED IDEOGRAPH + {0xD0CC, 0x89B2}, //12768 #CJK UNIFIED IDEOGRAPH + {0xD0CD, 0x8B39}, //12769 #CJK UNIFIED IDEOGRAPH + {0xD0CE, 0x8FD1}, //12770 #CJK UNIFIED IDEOGRAPH + {0xD0CF, 0x9949}, //12771 #CJK UNIFIED IDEOGRAPH + {0xD0D0, 0xF909}, //12772 #CJK COMPATIBILITY IDEOGRAPH + {0xD0D1, 0x4ECA}, //12773 #CJK UNIFIED IDEOGRAPH + {0xD0D2, 0x5997}, //12774 #CJK UNIFIED IDEOGRAPH + {0xD0D3, 0x64D2}, //12775 #CJK UNIFIED IDEOGRAPH + {0xD0D4, 0x6611}, //12776 #CJK UNIFIED IDEOGRAPH + {0xD0D5, 0x6A8E}, //12777 #CJK UNIFIED IDEOGRAPH + {0xD0D6, 0x7434}, //12778 #CJK UNIFIED IDEOGRAPH + {0xD0D7, 0x7981}, //12779 #CJK UNIFIED IDEOGRAPH + {0xD0D8, 0x79BD}, //12780 #CJK UNIFIED IDEOGRAPH + {0xD0D9, 0x82A9}, //12781 #CJK UNIFIED IDEOGRAPH + {0xD0DA, 0x887E}, //12782 #CJK UNIFIED IDEOGRAPH + {0xD0DB, 0x887F}, //12783 #CJK UNIFIED IDEOGRAPH + {0xD0DC, 0x895F}, //12784 #CJK UNIFIED IDEOGRAPH + {0xD0DD, 0xF90A}, //12785 #CJK COMPATIBILITY IDEOGRAPH + {0xD0DE, 0x9326}, //12786 #CJK UNIFIED IDEOGRAPH + {0xD0DF, 0x4F0B}, //12787 #CJK UNIFIED IDEOGRAPH + {0xD0E0, 0x53CA}, //12788 #CJK UNIFIED IDEOGRAPH + {0xD0E1, 0x6025}, //12789 #CJK UNIFIED IDEOGRAPH + {0xD0E2, 0x6271}, //12790 #CJK UNIFIED IDEOGRAPH + {0xD0E3, 0x6C72}, //12791 #CJK UNIFIED IDEOGRAPH + {0xD0E4, 0x7D1A}, //12792 #CJK UNIFIED IDEOGRAPH + {0xD0E5, 0x7D66}, //12793 #CJK UNIFIED IDEOGRAPH + {0xD0E6, 0x4E98}, //12794 #CJK UNIFIED IDEOGRAPH + {0xD0E7, 0x5162}, //12795 #CJK UNIFIED IDEOGRAPH + {0xD0E8, 0x77DC}, //12796 #CJK UNIFIED IDEOGRAPH + {0xD0E9, 0x80AF}, //12797 #CJK UNIFIED IDEOGRAPH + {0xD0EA, 0x4F01}, //12798 #CJK UNIFIED IDEOGRAPH + {0xD0EB, 0x4F0E}, //12799 #CJK UNIFIED IDEOGRAPH + {0xD0EC, 0x5176}, //12800 #CJK UNIFIED IDEOGRAPH + {0xD0ED, 0x5180}, //12801 #CJK UNIFIED IDEOGRAPH + {0xD0EE, 0x55DC}, //12802 #CJK UNIFIED IDEOGRAPH + {0xD0EF, 0x5668}, //12803 #CJK UNIFIED IDEOGRAPH + {0xD0F0, 0x573B}, //12804 #CJK UNIFIED IDEOGRAPH + {0xD0F1, 0x57FA}, //12805 #CJK UNIFIED IDEOGRAPH + {0xD0F2, 0x57FC}, //12806 #CJK UNIFIED IDEOGRAPH + {0xD0F3, 0x5914}, //12807 #CJK UNIFIED IDEOGRAPH + {0xD0F4, 0x5947}, //12808 #CJK UNIFIED IDEOGRAPH + {0xD0F5, 0x5993}, //12809 #CJK UNIFIED IDEOGRAPH + {0xD0F6, 0x5BC4}, //12810 #CJK UNIFIED IDEOGRAPH + {0xD0F7, 0x5C90}, //12811 #CJK UNIFIED IDEOGRAPH + {0xD0F8, 0x5D0E}, //12812 #CJK UNIFIED IDEOGRAPH + {0xD0F9, 0x5DF1}, //12813 #CJK UNIFIED IDEOGRAPH + {0xD0FA, 0x5E7E}, //12814 #CJK UNIFIED IDEOGRAPH + {0xD0FB, 0x5FCC}, //12815 #CJK UNIFIED IDEOGRAPH + {0xD0FC, 0x6280}, //12816 #CJK UNIFIED IDEOGRAPH + {0xD0FD, 0x65D7}, //12817 #CJK UNIFIED IDEOGRAPH + {0xD0FE, 0x65E3}, //12818 #CJK UNIFIED IDEOGRAPH + {0xD1A1, 0x671E}, //12819 #CJK UNIFIED IDEOGRAPH + {0xD1A2, 0x671F}, //12820 #CJK UNIFIED IDEOGRAPH + {0xD1A3, 0x675E}, //12821 #CJK UNIFIED IDEOGRAPH + {0xD1A4, 0x68CB}, //12822 #CJK UNIFIED IDEOGRAPH + {0xD1A5, 0x68C4}, //12823 #CJK UNIFIED IDEOGRAPH + {0xD1A6, 0x6A5F}, //12824 #CJK UNIFIED IDEOGRAPH + {0xD1A7, 0x6B3A}, //12825 #CJK UNIFIED IDEOGRAPH + {0xD1A8, 0x6C23}, //12826 #CJK UNIFIED IDEOGRAPH + {0xD1A9, 0x6C7D}, //12827 #CJK UNIFIED IDEOGRAPH + {0xD1AA, 0x6C82}, //12828 #CJK UNIFIED IDEOGRAPH + {0xD1AB, 0x6DC7}, //12829 #CJK UNIFIED IDEOGRAPH + {0xD1AC, 0x7398}, //12830 #CJK UNIFIED IDEOGRAPH + {0xD1AD, 0x7426}, //12831 #CJK UNIFIED IDEOGRAPH + {0xD1AE, 0x742A}, //12832 #CJK UNIFIED IDEOGRAPH + {0xD1AF, 0x7482}, //12833 #CJK UNIFIED IDEOGRAPH + {0xD1B0, 0x74A3}, //12834 #CJK UNIFIED IDEOGRAPH + {0xD1B1, 0x7578}, //12835 #CJK UNIFIED IDEOGRAPH + {0xD1B2, 0x757F}, //12836 #CJK UNIFIED IDEOGRAPH + {0xD1B3, 0x7881}, //12837 #CJK UNIFIED IDEOGRAPH + {0xD1B4, 0x78EF}, //12838 #CJK UNIFIED IDEOGRAPH + {0xD1B5, 0x7941}, //12839 #CJK UNIFIED IDEOGRAPH + {0xD1B6, 0x7947}, //12840 #CJK UNIFIED IDEOGRAPH + {0xD1B7, 0x7948}, //12841 #CJK UNIFIED IDEOGRAPH + {0xD1B8, 0x797A}, //12842 #CJK UNIFIED IDEOGRAPH + {0xD1B9, 0x7B95}, //12843 #CJK UNIFIED IDEOGRAPH + {0xD1BA, 0x7D00}, //12844 #CJK UNIFIED IDEOGRAPH + {0xD1BB, 0x7DBA}, //12845 #CJK UNIFIED IDEOGRAPH + {0xD1BC, 0x7F88}, //12846 #CJK UNIFIED IDEOGRAPH + {0xD1BD, 0x8006}, //12847 #CJK UNIFIED IDEOGRAPH + {0xD1BE, 0x802D}, //12848 #CJK UNIFIED IDEOGRAPH + {0xD1BF, 0x808C}, //12849 #CJK UNIFIED IDEOGRAPH + {0xD1C0, 0x8A18}, //12850 #CJK UNIFIED IDEOGRAPH + {0xD1C1, 0x8B4F}, //12851 #CJK UNIFIED IDEOGRAPH + {0xD1C2, 0x8C48}, //12852 #CJK UNIFIED IDEOGRAPH + {0xD1C3, 0x8D77}, //12853 #CJK UNIFIED IDEOGRAPH + {0xD1C4, 0x9321}, //12854 #CJK UNIFIED IDEOGRAPH + {0xD1C5, 0x9324}, //12855 #CJK UNIFIED IDEOGRAPH + {0xD1C6, 0x98E2}, //12856 #CJK UNIFIED IDEOGRAPH + {0xD1C7, 0x9951}, //12857 #CJK UNIFIED IDEOGRAPH + {0xD1C8, 0x9A0E}, //12858 #CJK UNIFIED IDEOGRAPH + {0xD1C9, 0x9A0F}, //12859 #CJK UNIFIED IDEOGRAPH + {0xD1CA, 0x9A65}, //12860 #CJK UNIFIED IDEOGRAPH + {0xD1CB, 0x9E92}, //12861 #CJK UNIFIED IDEOGRAPH + {0xD1CC, 0x7DCA}, //12862 #CJK UNIFIED IDEOGRAPH + {0xD1CD, 0x4F76}, //12863 #CJK UNIFIED IDEOGRAPH + {0xD1CE, 0x5409}, //12864 #CJK UNIFIED IDEOGRAPH + {0xD1CF, 0x62EE}, //12865 #CJK UNIFIED IDEOGRAPH + {0xD1D0, 0x6854}, //12866 #CJK UNIFIED IDEOGRAPH + {0xD1D1, 0x91D1}, //12867 #CJK UNIFIED IDEOGRAPH + {0xD1D2, 0x55AB}, //12868 #CJK UNIFIED IDEOGRAPH + {0xD1D3, 0x513A}, //12869 #CJK UNIFIED IDEOGRAPH + {0xD1D4, 0xF90B}, //12870 #CJK COMPATIBILITY IDEOGRAPH + {0xD1D5, 0xF90C}, //12871 #CJK COMPATIBILITY IDEOGRAPH + {0xD1D6, 0x5A1C}, //12872 #CJK UNIFIED IDEOGRAPH + {0xD1D7, 0x61E6}, //12873 #CJK UNIFIED IDEOGRAPH + {0xD1D8, 0xF90D}, //12874 #CJK COMPATIBILITY IDEOGRAPH + {0xD1D9, 0x62CF}, //12875 #CJK UNIFIED IDEOGRAPH + {0xD1DA, 0x62FF}, //12876 #CJK UNIFIED IDEOGRAPH + {0xD1DB, 0xF90E}, //12877 #CJK COMPATIBILITY IDEOGRAPH + {0xD1DC, 0xF90F}, //12878 #CJK COMPATIBILITY IDEOGRAPH + {0xD1DD, 0xF910}, //12879 #CJK COMPATIBILITY IDEOGRAPH + {0xD1DE, 0xF911}, //12880 #CJK COMPATIBILITY IDEOGRAPH + {0xD1DF, 0xF912}, //12881 #CJK COMPATIBILITY IDEOGRAPH + {0xD1E0, 0xF913}, //12882 #CJK COMPATIBILITY IDEOGRAPH + {0xD1E1, 0x90A3}, //12883 #CJK UNIFIED IDEOGRAPH + {0xD1E2, 0xF914}, //12884 #CJK COMPATIBILITY IDEOGRAPH + {0xD1E3, 0xF915}, //12885 #CJK COMPATIBILITY IDEOGRAPH + {0xD1E4, 0xF916}, //12886 #CJK COMPATIBILITY IDEOGRAPH + {0xD1E5, 0xF917}, //12887 #CJK COMPATIBILITY IDEOGRAPH + {0xD1E6, 0xF918}, //12888 #CJK COMPATIBILITY IDEOGRAPH + {0xD1E7, 0x8AFE}, //12889 #CJK UNIFIED IDEOGRAPH + {0xD1E8, 0xF919}, //12890 #CJK COMPATIBILITY IDEOGRAPH + {0xD1E9, 0xF91A}, //12891 #CJK COMPATIBILITY IDEOGRAPH + {0xD1EA, 0xF91B}, //12892 #CJK COMPATIBILITY IDEOGRAPH + {0xD1EB, 0xF91C}, //12893 #CJK COMPATIBILITY IDEOGRAPH + {0xD1EC, 0x6696}, //12894 #CJK UNIFIED IDEOGRAPH + {0xD1ED, 0xF91D}, //12895 #CJK COMPATIBILITY IDEOGRAPH + {0xD1EE, 0x7156}, //12896 #CJK UNIFIED IDEOGRAPH + {0xD1EF, 0xF91E}, //12897 #CJK COMPATIBILITY IDEOGRAPH + {0xD1F0, 0xF91F}, //12898 #CJK COMPATIBILITY IDEOGRAPH + {0xD1F1, 0x96E3}, //12899 #CJK UNIFIED IDEOGRAPH + {0xD1F2, 0xF920}, //12900 #CJK COMPATIBILITY IDEOGRAPH + {0xD1F3, 0x634F}, //12901 #CJK UNIFIED IDEOGRAPH + {0xD1F4, 0x637A}, //12902 #CJK UNIFIED IDEOGRAPH + {0xD1F5, 0x5357}, //12903 #CJK UNIFIED IDEOGRAPH + {0xD1F6, 0xF921}, //12904 #CJK COMPATIBILITY IDEOGRAPH + {0xD1F7, 0x678F}, //12905 #CJK UNIFIED IDEOGRAPH + {0xD1F8, 0x6960}, //12906 #CJK UNIFIED IDEOGRAPH + {0xD1F9, 0x6E73}, //12907 #CJK UNIFIED IDEOGRAPH + {0xD1FA, 0xF922}, //12908 #CJK COMPATIBILITY IDEOGRAPH + {0xD1FB, 0x7537}, //12909 #CJK UNIFIED IDEOGRAPH + {0xD1FC, 0xF923}, //12910 #CJK COMPATIBILITY IDEOGRAPH + {0xD1FD, 0xF924}, //12911 #CJK COMPATIBILITY IDEOGRAPH + {0xD1FE, 0xF925}, //12912 #CJK COMPATIBILITY IDEOGRAPH + {0xD2A1, 0x7D0D}, //12913 #CJK UNIFIED IDEOGRAPH + {0xD2A2, 0xF926}, //12914 #CJK COMPATIBILITY IDEOGRAPH + {0xD2A3, 0xF927}, //12915 #CJK COMPATIBILITY IDEOGRAPH + {0xD2A4, 0x8872}, //12916 #CJK UNIFIED IDEOGRAPH + {0xD2A5, 0x56CA}, //12917 #CJK UNIFIED IDEOGRAPH + {0xD2A6, 0x5A18}, //12918 #CJK UNIFIED IDEOGRAPH + {0xD2A7, 0xF928}, //12919 #CJK COMPATIBILITY IDEOGRAPH + {0xD2A8, 0xF929}, //12920 #CJK COMPATIBILITY IDEOGRAPH + {0xD2A9, 0xF92A}, //12921 #CJK COMPATIBILITY IDEOGRAPH + {0xD2AA, 0xF92B}, //12922 #CJK COMPATIBILITY IDEOGRAPH + {0xD2AB, 0xF92C}, //12923 #CJK COMPATIBILITY IDEOGRAPH + {0xD2AC, 0x4E43}, //12924 #CJK UNIFIED IDEOGRAPH + {0xD2AD, 0xF92D}, //12925 #CJK COMPATIBILITY IDEOGRAPH + {0xD2AE, 0x5167}, //12926 #CJK UNIFIED IDEOGRAPH + {0xD2AF, 0x5948}, //12927 #CJK UNIFIED IDEOGRAPH + {0xD2B0, 0x67F0}, //12928 #CJK UNIFIED IDEOGRAPH + {0xD2B1, 0x8010}, //12929 #CJK UNIFIED IDEOGRAPH + {0xD2B2, 0xF92E}, //12930 #CJK COMPATIBILITY IDEOGRAPH + {0xD2B3, 0x5973}, //12931 #CJK UNIFIED IDEOGRAPH + {0xD2B4, 0x5E74}, //12932 #CJK UNIFIED IDEOGRAPH + {0xD2B5, 0x649A}, //12933 #CJK UNIFIED IDEOGRAPH + {0xD2B6, 0x79CA}, //12934 #CJK UNIFIED IDEOGRAPH + {0xD2B7, 0x5FF5}, //12935 #CJK UNIFIED IDEOGRAPH + {0xD2B8, 0x606C}, //12936 #CJK UNIFIED IDEOGRAPH + {0xD2B9, 0x62C8}, //12937 #CJK UNIFIED IDEOGRAPH + {0xD2BA, 0x637B}, //12938 #CJK UNIFIED IDEOGRAPH + {0xD2BB, 0x5BE7}, //12939 #CJK UNIFIED IDEOGRAPH + {0xD2BC, 0x5BD7}, //12940 #CJK UNIFIED IDEOGRAPH + {0xD2BD, 0x52AA}, //12941 #CJK UNIFIED IDEOGRAPH + {0xD2BE, 0xF92F}, //12942 #CJK COMPATIBILITY IDEOGRAPH + {0xD2BF, 0x5974}, //12943 #CJK UNIFIED IDEOGRAPH + {0xD2C0, 0x5F29}, //12944 #CJK UNIFIED IDEOGRAPH + {0xD2C1, 0x6012}, //12945 #CJK UNIFIED IDEOGRAPH + {0xD2C2, 0xF930}, //12946 #CJK COMPATIBILITY IDEOGRAPH + {0xD2C3, 0xF931}, //12947 #CJK COMPATIBILITY IDEOGRAPH + {0xD2C4, 0xF932}, //12948 #CJK COMPATIBILITY IDEOGRAPH + {0xD2C5, 0x7459}, //12949 #CJK UNIFIED IDEOGRAPH + {0xD2C6, 0xF933}, //12950 #CJK COMPATIBILITY IDEOGRAPH + {0xD2C7, 0xF934}, //12951 #CJK COMPATIBILITY IDEOGRAPH + {0xD2C8, 0xF935}, //12952 #CJK COMPATIBILITY IDEOGRAPH + {0xD2C9, 0xF936}, //12953 #CJK COMPATIBILITY IDEOGRAPH + {0xD2CA, 0xF937}, //12954 #CJK COMPATIBILITY IDEOGRAPH + {0xD2CB, 0xF938}, //12955 #CJK COMPATIBILITY IDEOGRAPH + {0xD2CC, 0x99D1}, //12956 #CJK UNIFIED IDEOGRAPH + {0xD2CD, 0xF939}, //12957 #CJK COMPATIBILITY IDEOGRAPH + {0xD2CE, 0xF93A}, //12958 #CJK COMPATIBILITY IDEOGRAPH + {0xD2CF, 0xF93B}, //12959 #CJK COMPATIBILITY IDEOGRAPH + {0xD2D0, 0xF93C}, //12960 #CJK COMPATIBILITY IDEOGRAPH + {0xD2D1, 0xF93D}, //12961 #CJK COMPATIBILITY IDEOGRAPH + {0xD2D2, 0xF93E}, //12962 #CJK COMPATIBILITY IDEOGRAPH + {0xD2D3, 0xF93F}, //12963 #CJK COMPATIBILITY IDEOGRAPH + {0xD2D4, 0xF940}, //12964 #CJK COMPATIBILITY IDEOGRAPH + {0xD2D5, 0xF941}, //12965 #CJK COMPATIBILITY IDEOGRAPH + {0xD2D6, 0xF942}, //12966 #CJK COMPATIBILITY IDEOGRAPH + {0xD2D7, 0xF943}, //12967 #CJK COMPATIBILITY IDEOGRAPH + {0xD2D8, 0x6FC3}, //12968 #CJK UNIFIED IDEOGRAPH + {0xD2D9, 0xF944}, //12969 #CJK COMPATIBILITY IDEOGRAPH + {0xD2DA, 0xF945}, //12970 #CJK COMPATIBILITY IDEOGRAPH + {0xD2DB, 0x81BF}, //12971 #CJK UNIFIED IDEOGRAPH + {0xD2DC, 0x8FB2}, //12972 #CJK UNIFIED IDEOGRAPH + {0xD2DD, 0x60F1}, //12973 #CJK UNIFIED IDEOGRAPH + {0xD2DE, 0xF946}, //12974 #CJK COMPATIBILITY IDEOGRAPH + {0xD2DF, 0xF947}, //12975 #CJK COMPATIBILITY IDEOGRAPH + {0xD2E0, 0x8166}, //12976 #CJK UNIFIED IDEOGRAPH + {0xD2E1, 0xF948}, //12977 #CJK COMPATIBILITY IDEOGRAPH + {0xD2E2, 0xF949}, //12978 #CJK COMPATIBILITY IDEOGRAPH + {0xD2E3, 0x5C3F}, //12979 #CJK UNIFIED IDEOGRAPH + {0xD2E4, 0xF94A}, //12980 #CJK COMPATIBILITY IDEOGRAPH + {0xD2E5, 0xF94B}, //12981 #CJK COMPATIBILITY IDEOGRAPH + {0xD2E6, 0xF94C}, //12982 #CJK COMPATIBILITY IDEOGRAPH + {0xD2E7, 0xF94D}, //12983 #CJK COMPATIBILITY IDEOGRAPH + {0xD2E8, 0xF94E}, //12984 #CJK COMPATIBILITY IDEOGRAPH + {0xD2E9, 0xF94F}, //12985 #CJK COMPATIBILITY IDEOGRAPH + {0xD2EA, 0xF950}, //12986 #CJK COMPATIBILITY IDEOGRAPH + {0xD2EB, 0xF951}, //12987 #CJK COMPATIBILITY IDEOGRAPH + {0xD2EC, 0x5AE9}, //12988 #CJK UNIFIED IDEOGRAPH + {0xD2ED, 0x8A25}, //12989 #CJK UNIFIED IDEOGRAPH + {0xD2EE, 0x677B}, //12990 #CJK UNIFIED IDEOGRAPH + {0xD2EF, 0x7D10}, //12991 #CJK UNIFIED IDEOGRAPH + {0xD2F0, 0xF952}, //12992 #CJK COMPATIBILITY IDEOGRAPH + {0xD2F1, 0xF953}, //12993 #CJK COMPATIBILITY IDEOGRAPH + {0xD2F2, 0xF954}, //12994 #CJK COMPATIBILITY IDEOGRAPH + {0xD2F3, 0xF955}, //12995 #CJK COMPATIBILITY IDEOGRAPH + {0xD2F4, 0xF956}, //12996 #CJK COMPATIBILITY IDEOGRAPH + {0xD2F5, 0xF957}, //12997 #CJK COMPATIBILITY IDEOGRAPH + {0xD2F6, 0x80FD}, //12998 #CJK UNIFIED IDEOGRAPH + {0xD2F7, 0xF958}, //12999 #CJK COMPATIBILITY IDEOGRAPH + {0xD2F8, 0xF959}, //13000 #CJK COMPATIBILITY IDEOGRAPH + {0xD2F9, 0x5C3C}, //13001 #CJK UNIFIED IDEOGRAPH + {0xD2FA, 0x6CE5}, //13002 #CJK UNIFIED IDEOGRAPH + {0xD2FB, 0x533F}, //13003 #CJK UNIFIED IDEOGRAPH + {0xD2FC, 0x6EBA}, //13004 #CJK UNIFIED IDEOGRAPH + {0xD2FD, 0x591A}, //13005 #CJK UNIFIED IDEOGRAPH + {0xD2FE, 0x8336}, //13006 #CJK UNIFIED IDEOGRAPH + {0xD3A1, 0x4E39}, //13007 #CJK UNIFIED IDEOGRAPH + {0xD3A2, 0x4EB6}, //13008 #CJK UNIFIED IDEOGRAPH + {0xD3A3, 0x4F46}, //13009 #CJK UNIFIED IDEOGRAPH + {0xD3A4, 0x55AE}, //13010 #CJK UNIFIED IDEOGRAPH + {0xD3A5, 0x5718}, //13011 #CJK UNIFIED IDEOGRAPH + {0xD3A6, 0x58C7}, //13012 #CJK UNIFIED IDEOGRAPH + {0xD3A7, 0x5F56}, //13013 #CJK UNIFIED IDEOGRAPH + {0xD3A8, 0x65B7}, //13014 #CJK UNIFIED IDEOGRAPH + {0xD3A9, 0x65E6}, //13015 #CJK UNIFIED IDEOGRAPH + {0xD3AA, 0x6A80}, //13016 #CJK UNIFIED IDEOGRAPH + {0xD3AB, 0x6BB5}, //13017 #CJK UNIFIED IDEOGRAPH + {0xD3AC, 0x6E4D}, //13018 #CJK UNIFIED IDEOGRAPH + {0xD3AD, 0x77ED}, //13019 #CJK UNIFIED IDEOGRAPH + {0xD3AE, 0x7AEF}, //13020 #CJK UNIFIED IDEOGRAPH + {0xD3AF, 0x7C1E}, //13021 #CJK UNIFIED IDEOGRAPH + {0xD3B0, 0x7DDE}, //13022 #CJK UNIFIED IDEOGRAPH + {0xD3B1, 0x86CB}, //13023 #CJK UNIFIED IDEOGRAPH + {0xD3B2, 0x8892}, //13024 #CJK UNIFIED IDEOGRAPH + {0xD3B3, 0x9132}, //13025 #CJK UNIFIED IDEOGRAPH + {0xD3B4, 0x935B}, //13026 #CJK UNIFIED IDEOGRAPH + {0xD3B5, 0x64BB}, //13027 #CJK UNIFIED IDEOGRAPH + {0xD3B6, 0x6FBE}, //13028 #CJK UNIFIED IDEOGRAPH + {0xD3B7, 0x737A}, //13029 #CJK UNIFIED IDEOGRAPH + {0xD3B8, 0x75B8}, //13030 #CJK UNIFIED IDEOGRAPH + {0xD3B9, 0x9054}, //13031 #CJK UNIFIED IDEOGRAPH + {0xD3BA, 0x5556}, //13032 #CJK UNIFIED IDEOGRAPH + {0xD3BB, 0x574D}, //13033 #CJK UNIFIED IDEOGRAPH + {0xD3BC, 0x61BA}, //13034 #CJK UNIFIED IDEOGRAPH + {0xD3BD, 0x64D4}, //13035 #CJK UNIFIED IDEOGRAPH + {0xD3BE, 0x66C7}, //13036 #CJK UNIFIED IDEOGRAPH + {0xD3BF, 0x6DE1}, //13037 #CJK UNIFIED IDEOGRAPH + {0xD3C0, 0x6E5B}, //13038 #CJK UNIFIED IDEOGRAPH + {0xD3C1, 0x6F6D}, //13039 #CJK UNIFIED IDEOGRAPH + {0xD3C2, 0x6FB9}, //13040 #CJK UNIFIED IDEOGRAPH + {0xD3C3, 0x75F0}, //13041 #CJK UNIFIED IDEOGRAPH + {0xD3C4, 0x8043}, //13042 #CJK UNIFIED IDEOGRAPH + {0xD3C5, 0x81BD}, //13043 #CJK UNIFIED IDEOGRAPH + {0xD3C6, 0x8541}, //13044 #CJK UNIFIED IDEOGRAPH + {0xD3C7, 0x8983}, //13045 #CJK UNIFIED IDEOGRAPH + {0xD3C8, 0x8AC7}, //13046 #CJK UNIFIED IDEOGRAPH + {0xD3C9, 0x8B5A}, //13047 #CJK UNIFIED IDEOGRAPH + {0xD3CA, 0x931F}, //13048 #CJK UNIFIED IDEOGRAPH + {0xD3CB, 0x6C93}, //13049 #CJK UNIFIED IDEOGRAPH + {0xD3CC, 0x7553}, //13050 #CJK UNIFIED IDEOGRAPH + {0xD3CD, 0x7B54}, //13051 #CJK UNIFIED IDEOGRAPH + {0xD3CE, 0x8E0F}, //13052 #CJK UNIFIED IDEOGRAPH + {0xD3CF, 0x905D}, //13053 #CJK UNIFIED IDEOGRAPH + {0xD3D0, 0x5510}, //13054 #CJK UNIFIED IDEOGRAPH + {0xD3D1, 0x5802}, //13055 #CJK UNIFIED IDEOGRAPH + {0xD3D2, 0x5858}, //13056 #CJK UNIFIED IDEOGRAPH + {0xD3D3, 0x5E62}, //13057 #CJK UNIFIED IDEOGRAPH + {0xD3D4, 0x6207}, //13058 #CJK UNIFIED IDEOGRAPH + {0xD3D5, 0x649E}, //13059 #CJK UNIFIED IDEOGRAPH + {0xD3D6, 0x68E0}, //13060 #CJK UNIFIED IDEOGRAPH + {0xD3D7, 0x7576}, //13061 #CJK UNIFIED IDEOGRAPH + {0xD3D8, 0x7CD6}, //13062 #CJK UNIFIED IDEOGRAPH + {0xD3D9, 0x87B3}, //13063 #CJK UNIFIED IDEOGRAPH + {0xD3DA, 0x9EE8}, //13064 #CJK UNIFIED IDEOGRAPH + {0xD3DB, 0x4EE3}, //13065 #CJK UNIFIED IDEOGRAPH + {0xD3DC, 0x5788}, //13066 #CJK UNIFIED IDEOGRAPH + {0xD3DD, 0x576E}, //13067 #CJK UNIFIED IDEOGRAPH + {0xD3DE, 0x5927}, //13068 #CJK UNIFIED IDEOGRAPH + {0xD3DF, 0x5C0D}, //13069 #CJK UNIFIED IDEOGRAPH + {0xD3E0, 0x5CB1}, //13070 #CJK UNIFIED IDEOGRAPH + {0xD3E1, 0x5E36}, //13071 #CJK UNIFIED IDEOGRAPH + {0xD3E2, 0x5F85}, //13072 #CJK UNIFIED IDEOGRAPH + {0xD3E3, 0x6234}, //13073 #CJK UNIFIED IDEOGRAPH + {0xD3E4, 0x64E1}, //13074 #CJK UNIFIED IDEOGRAPH + {0xD3E5, 0x73B3}, //13075 #CJK UNIFIED IDEOGRAPH + {0xD3E6, 0x81FA}, //13076 #CJK UNIFIED IDEOGRAPH + {0xD3E7, 0x888B}, //13077 #CJK UNIFIED IDEOGRAPH + {0xD3E8, 0x8CB8}, //13078 #CJK UNIFIED IDEOGRAPH + {0xD3E9, 0x968A}, //13079 #CJK UNIFIED IDEOGRAPH + {0xD3EA, 0x9EDB}, //13080 #CJK UNIFIED IDEOGRAPH + {0xD3EB, 0x5B85}, //13081 #CJK UNIFIED IDEOGRAPH + {0xD3EC, 0x5FB7}, //13082 #CJK UNIFIED IDEOGRAPH + {0xD3ED, 0x60B3}, //13083 #CJK UNIFIED IDEOGRAPH + {0xD3EE, 0x5012}, //13084 #CJK UNIFIED IDEOGRAPH + {0xD3EF, 0x5200}, //13085 #CJK UNIFIED IDEOGRAPH + {0xD3F0, 0x5230}, //13086 #CJK UNIFIED IDEOGRAPH + {0xD3F1, 0x5716}, //13087 #CJK UNIFIED IDEOGRAPH + {0xD3F2, 0x5835}, //13088 #CJK UNIFIED IDEOGRAPH + {0xD3F3, 0x5857}, //13089 #CJK UNIFIED IDEOGRAPH + {0xD3F4, 0x5C0E}, //13090 #CJK UNIFIED IDEOGRAPH + {0xD3F5, 0x5C60}, //13091 #CJK UNIFIED IDEOGRAPH + {0xD3F6, 0x5CF6}, //13092 #CJK UNIFIED IDEOGRAPH + {0xD3F7, 0x5D8B}, //13093 #CJK UNIFIED IDEOGRAPH + {0xD3F8, 0x5EA6}, //13094 #CJK UNIFIED IDEOGRAPH + {0xD3F9, 0x5F92}, //13095 #CJK UNIFIED IDEOGRAPH + {0xD3FA, 0x60BC}, //13096 #CJK UNIFIED IDEOGRAPH + {0xD3FB, 0x6311}, //13097 #CJK UNIFIED IDEOGRAPH + {0xD3FC, 0x6389}, //13098 #CJK UNIFIED IDEOGRAPH + {0xD3FD, 0x6417}, //13099 #CJK UNIFIED IDEOGRAPH + {0xD3FE, 0x6843}, //13100 #CJK UNIFIED IDEOGRAPH + {0xD4A1, 0x68F9}, //13101 #CJK UNIFIED IDEOGRAPH + {0xD4A2, 0x6AC2}, //13102 #CJK UNIFIED IDEOGRAPH + {0xD4A3, 0x6DD8}, //13103 #CJK UNIFIED IDEOGRAPH + {0xD4A4, 0x6E21}, //13104 #CJK UNIFIED IDEOGRAPH + {0xD4A5, 0x6ED4}, //13105 #CJK UNIFIED IDEOGRAPH + {0xD4A6, 0x6FE4}, //13106 #CJK UNIFIED IDEOGRAPH + {0xD4A7, 0x71FE}, //13107 #CJK UNIFIED IDEOGRAPH + {0xD4A8, 0x76DC}, //13108 #CJK UNIFIED IDEOGRAPH + {0xD4A9, 0x7779}, //13109 #CJK UNIFIED IDEOGRAPH + {0xD4AA, 0x79B1}, //13110 #CJK UNIFIED IDEOGRAPH + {0xD4AB, 0x7A3B}, //13111 #CJK UNIFIED IDEOGRAPH + {0xD4AC, 0x8404}, //13112 #CJK UNIFIED IDEOGRAPH + {0xD4AD, 0x89A9}, //13113 #CJK UNIFIED IDEOGRAPH + {0xD4AE, 0x8CED}, //13114 #CJK UNIFIED IDEOGRAPH + {0xD4AF, 0x8DF3}, //13115 #CJK UNIFIED IDEOGRAPH + {0xD4B0, 0x8E48}, //13116 #CJK UNIFIED IDEOGRAPH + {0xD4B1, 0x9003}, //13117 #CJK UNIFIED IDEOGRAPH + {0xD4B2, 0x9014}, //13118 #CJK UNIFIED IDEOGRAPH + {0xD4B3, 0x9053}, //13119 #CJK UNIFIED IDEOGRAPH + {0xD4B4, 0x90FD}, //13120 #CJK UNIFIED IDEOGRAPH + {0xD4B5, 0x934D}, //13121 #CJK UNIFIED IDEOGRAPH + {0xD4B6, 0x9676}, //13122 #CJK UNIFIED IDEOGRAPH + {0xD4B7, 0x97DC}, //13123 #CJK UNIFIED IDEOGRAPH + {0xD4B8, 0x6BD2}, //13124 #CJK UNIFIED IDEOGRAPH + {0xD4B9, 0x7006}, //13125 #CJK UNIFIED IDEOGRAPH + {0xD4BA, 0x7258}, //13126 #CJK UNIFIED IDEOGRAPH + {0xD4BB, 0x72A2}, //13127 #CJK UNIFIED IDEOGRAPH + {0xD4BC, 0x7368}, //13128 #CJK UNIFIED IDEOGRAPH + {0xD4BD, 0x7763}, //13129 #CJK UNIFIED IDEOGRAPH + {0xD4BE, 0x79BF}, //13130 #CJK UNIFIED IDEOGRAPH + {0xD4BF, 0x7BE4}, //13131 #CJK UNIFIED IDEOGRAPH + {0xD4C0, 0x7E9B}, //13132 #CJK UNIFIED IDEOGRAPH + {0xD4C1, 0x8B80}, //13133 #CJK UNIFIED IDEOGRAPH + {0xD4C2, 0x58A9}, //13134 #CJK UNIFIED IDEOGRAPH + {0xD4C3, 0x60C7}, //13135 #CJK UNIFIED IDEOGRAPH + {0xD4C4, 0x6566}, //13136 #CJK UNIFIED IDEOGRAPH + {0xD4C5, 0x65FD}, //13137 #CJK UNIFIED IDEOGRAPH + {0xD4C6, 0x66BE}, //13138 #CJK UNIFIED IDEOGRAPH + {0xD4C7, 0x6C8C}, //13139 #CJK UNIFIED IDEOGRAPH + {0xD4C8, 0x711E}, //13140 #CJK UNIFIED IDEOGRAPH + {0xD4C9, 0x71C9}, //13141 #CJK UNIFIED IDEOGRAPH + {0xD4CA, 0x8C5A}, //13142 #CJK UNIFIED IDEOGRAPH + {0xD4CB, 0x9813}, //13143 #CJK UNIFIED IDEOGRAPH + {0xD4CC, 0x4E6D}, //13144 #CJK UNIFIED IDEOGRAPH + {0xD4CD, 0x7A81}, //13145 #CJK UNIFIED IDEOGRAPH + {0xD4CE, 0x4EDD}, //13146 #CJK UNIFIED IDEOGRAPH + {0xD4CF, 0x51AC}, //13147 #CJK UNIFIED IDEOGRAPH + {0xD4D0, 0x51CD}, //13148 #CJK UNIFIED IDEOGRAPH + {0xD4D1, 0x52D5}, //13149 #CJK UNIFIED IDEOGRAPH + {0xD4D2, 0x540C}, //13150 #CJK UNIFIED IDEOGRAPH + {0xD4D3, 0x61A7}, //13151 #CJK UNIFIED IDEOGRAPH + {0xD4D4, 0x6771}, //13152 #CJK UNIFIED IDEOGRAPH + {0xD4D5, 0x6850}, //13153 #CJK UNIFIED IDEOGRAPH + {0xD4D6, 0x68DF}, //13154 #CJK UNIFIED IDEOGRAPH + {0xD4D7, 0x6D1E}, //13155 #CJK UNIFIED IDEOGRAPH + {0xD4D8, 0x6F7C}, //13156 #CJK UNIFIED IDEOGRAPH + {0xD4D9, 0x75BC}, //13157 #CJK UNIFIED IDEOGRAPH + {0xD4DA, 0x77B3}, //13158 #CJK UNIFIED IDEOGRAPH + {0xD4DB, 0x7AE5}, //13159 #CJK UNIFIED IDEOGRAPH + {0xD4DC, 0x80F4}, //13160 #CJK UNIFIED IDEOGRAPH + {0xD4DD, 0x8463}, //13161 #CJK UNIFIED IDEOGRAPH + {0xD4DE, 0x9285}, //13162 #CJK UNIFIED IDEOGRAPH + {0xD4DF, 0x515C}, //13163 #CJK UNIFIED IDEOGRAPH + {0xD4E0, 0x6597}, //13164 #CJK UNIFIED IDEOGRAPH + {0xD4E1, 0x675C}, //13165 #CJK UNIFIED IDEOGRAPH + {0xD4E2, 0x6793}, //13166 #CJK UNIFIED IDEOGRAPH + {0xD4E3, 0x75D8}, //13167 #CJK UNIFIED IDEOGRAPH + {0xD4E4, 0x7AC7}, //13168 #CJK UNIFIED IDEOGRAPH + {0xD4E5, 0x8373}, //13169 #CJK UNIFIED IDEOGRAPH + {0xD4E6, 0xF95A}, //13170 #CJK COMPATIBILITY IDEOGRAPH + {0xD4E7, 0x8C46}, //13171 #CJK UNIFIED IDEOGRAPH + {0xD4E8, 0x9017}, //13172 #CJK UNIFIED IDEOGRAPH + {0xD4E9, 0x982D}, //13173 #CJK UNIFIED IDEOGRAPH + {0xD4EA, 0x5C6F}, //13174 #CJK UNIFIED IDEOGRAPH + {0xD4EB, 0x81C0}, //13175 #CJK UNIFIED IDEOGRAPH + {0xD4EC, 0x829A}, //13176 #CJK UNIFIED IDEOGRAPH + {0xD4ED, 0x9041}, //13177 #CJK UNIFIED IDEOGRAPH + {0xD4EE, 0x906F}, //13178 #CJK UNIFIED IDEOGRAPH + {0xD4EF, 0x920D}, //13179 #CJK UNIFIED IDEOGRAPH + {0xD4F0, 0x5F97}, //13180 #CJK UNIFIED IDEOGRAPH + {0xD4F1, 0x5D9D}, //13181 #CJK UNIFIED IDEOGRAPH + {0xD4F2, 0x6A59}, //13182 #CJK UNIFIED IDEOGRAPH + {0xD4F3, 0x71C8}, //13183 #CJK UNIFIED IDEOGRAPH + {0xD4F4, 0x767B}, //13184 #CJK UNIFIED IDEOGRAPH + {0xD4F5, 0x7B49}, //13185 #CJK UNIFIED IDEOGRAPH + {0xD4F6, 0x85E4}, //13186 #CJK UNIFIED IDEOGRAPH + {0xD4F7, 0x8B04}, //13187 #CJK UNIFIED IDEOGRAPH + {0xD4F8, 0x9127}, //13188 #CJK UNIFIED IDEOGRAPH + {0xD4F9, 0x9A30}, //13189 #CJK UNIFIED IDEOGRAPH + {0xD4FA, 0x5587}, //13190 #CJK UNIFIED IDEOGRAPH + {0xD4FB, 0x61F6}, //13191 #CJK UNIFIED IDEOGRAPH + {0xD4FC, 0xF95B}, //13192 #CJK COMPATIBILITY IDEOGRAPH + {0xD4FD, 0x7669}, //13193 #CJK UNIFIED IDEOGRAPH + {0xD4FE, 0x7F85}, //13194 #CJK UNIFIED IDEOGRAPH + {0xD5A1, 0x863F}, //13195 #CJK UNIFIED IDEOGRAPH + {0xD5A2, 0x87BA}, //13196 #CJK UNIFIED IDEOGRAPH + {0xD5A3, 0x88F8}, //13197 #CJK UNIFIED IDEOGRAPH + {0xD5A4, 0x908F}, //13198 #CJK UNIFIED IDEOGRAPH + {0xD5A5, 0xF95C}, //13199 #CJK COMPATIBILITY IDEOGRAPH + {0xD5A6, 0x6D1B}, //13200 #CJK UNIFIED IDEOGRAPH + {0xD5A7, 0x70D9}, //13201 #CJK UNIFIED IDEOGRAPH + {0xD5A8, 0x73DE}, //13202 #CJK UNIFIED IDEOGRAPH + {0xD5A9, 0x7D61}, //13203 #CJK UNIFIED IDEOGRAPH + {0xD5AA, 0x843D}, //13204 #CJK UNIFIED IDEOGRAPH + {0xD5AB, 0xF95D}, //13205 #CJK COMPATIBILITY IDEOGRAPH + {0xD5AC, 0x916A}, //13206 #CJK UNIFIED IDEOGRAPH + {0xD5AD, 0x99F1}, //13207 #CJK UNIFIED IDEOGRAPH + {0xD5AE, 0xF95E}, //13208 #CJK COMPATIBILITY IDEOGRAPH + {0xD5AF, 0x4E82}, //13209 #CJK UNIFIED IDEOGRAPH + {0xD5B0, 0x5375}, //13210 #CJK UNIFIED IDEOGRAPH + {0xD5B1, 0x6B04}, //13211 #CJK UNIFIED IDEOGRAPH + {0xD5B2, 0x6B12}, //13212 #CJK UNIFIED IDEOGRAPH + {0xD5B3, 0x703E}, //13213 #CJK UNIFIED IDEOGRAPH + {0xD5B4, 0x721B}, //13214 #CJK UNIFIED IDEOGRAPH + {0xD5B5, 0x862D}, //13215 #CJK UNIFIED IDEOGRAPH + {0xD5B6, 0x9E1E}, //13216 #CJK UNIFIED IDEOGRAPH + {0xD5B7, 0x524C}, //13217 #CJK UNIFIED IDEOGRAPH + {0xD5B8, 0x8FA3}, //13218 #CJK UNIFIED IDEOGRAPH + {0xD5B9, 0x5D50}, //13219 #CJK UNIFIED IDEOGRAPH + {0xD5BA, 0x64E5}, //13220 #CJK UNIFIED IDEOGRAPH + {0xD5BB, 0x652C}, //13221 #CJK UNIFIED IDEOGRAPH + {0xD5BC, 0x6B16}, //13222 #CJK UNIFIED IDEOGRAPH + {0xD5BD, 0x6FEB}, //13223 #CJK UNIFIED IDEOGRAPH + {0xD5BE, 0x7C43}, //13224 #CJK UNIFIED IDEOGRAPH + {0xD5BF, 0x7E9C}, //13225 #CJK UNIFIED IDEOGRAPH + {0xD5C0, 0x85CD}, //13226 #CJK UNIFIED IDEOGRAPH + {0xD5C1, 0x8964}, //13227 #CJK UNIFIED IDEOGRAPH + {0xD5C2, 0x89BD}, //13228 #CJK UNIFIED IDEOGRAPH + {0xD5C3, 0x62C9}, //13229 #CJK UNIFIED IDEOGRAPH + {0xD5C4, 0x81D8}, //13230 #CJK UNIFIED IDEOGRAPH + {0xD5C5, 0x881F}, //13231 #CJK UNIFIED IDEOGRAPH + {0xD5C6, 0x5ECA}, //13232 #CJK UNIFIED IDEOGRAPH + {0xD5C7, 0x6717}, //13233 #CJK UNIFIED IDEOGRAPH + {0xD5C8, 0x6D6A}, //13234 #CJK UNIFIED IDEOGRAPH + {0xD5C9, 0x72FC}, //13235 #CJK UNIFIED IDEOGRAPH + {0xD5CA, 0x7405}, //13236 #CJK UNIFIED IDEOGRAPH + {0xD5CB, 0x746F}, //13237 #CJK UNIFIED IDEOGRAPH + {0xD5CC, 0x8782}, //13238 #CJK UNIFIED IDEOGRAPH + {0xD5CD, 0x90DE}, //13239 #CJK UNIFIED IDEOGRAPH + {0xD5CE, 0x4F86}, //13240 #CJK UNIFIED IDEOGRAPH + {0xD5CF, 0x5D0D}, //13241 #CJK UNIFIED IDEOGRAPH + {0xD5D0, 0x5FA0}, //13242 #CJK UNIFIED IDEOGRAPH + {0xD5D1, 0x840A}, //13243 #CJK UNIFIED IDEOGRAPH + {0xD5D2, 0x51B7}, //13244 #CJK UNIFIED IDEOGRAPH + {0xD5D3, 0x63A0}, //13245 #CJK UNIFIED IDEOGRAPH + {0xD5D4, 0x7565}, //13246 #CJK UNIFIED IDEOGRAPH + {0xD5D5, 0x4EAE}, //13247 #CJK UNIFIED IDEOGRAPH + {0xD5D6, 0x5006}, //13248 #CJK UNIFIED IDEOGRAPH + {0xD5D7, 0x5169}, //13249 #CJK UNIFIED IDEOGRAPH + {0xD5D8, 0x51C9}, //13250 #CJK UNIFIED IDEOGRAPH + {0xD5D9, 0x6881}, //13251 #CJK UNIFIED IDEOGRAPH + {0xD5DA, 0x6A11}, //13252 #CJK UNIFIED IDEOGRAPH + {0xD5DB, 0x7CAE}, //13253 #CJK UNIFIED IDEOGRAPH + {0xD5DC, 0x7CB1}, //13254 #CJK UNIFIED IDEOGRAPH + {0xD5DD, 0x7CE7}, //13255 #CJK UNIFIED IDEOGRAPH + {0xD5DE, 0x826F}, //13256 #CJK UNIFIED IDEOGRAPH + {0xD5DF, 0x8AD2}, //13257 #CJK UNIFIED IDEOGRAPH + {0xD5E0, 0x8F1B}, //13258 #CJK UNIFIED IDEOGRAPH + {0xD5E1, 0x91CF}, //13259 #CJK UNIFIED IDEOGRAPH + {0xD5E2, 0x4FB6}, //13260 #CJK UNIFIED IDEOGRAPH + {0xD5E3, 0x5137}, //13261 #CJK UNIFIED IDEOGRAPH + {0xD5E4, 0x52F5}, //13262 #CJK UNIFIED IDEOGRAPH + {0xD5E5, 0x5442}, //13263 #CJK UNIFIED IDEOGRAPH + {0xD5E6, 0x5EEC}, //13264 #CJK UNIFIED IDEOGRAPH + {0xD5E7, 0x616E}, //13265 #CJK UNIFIED IDEOGRAPH + {0xD5E8, 0x623E}, //13266 #CJK UNIFIED IDEOGRAPH + {0xD5E9, 0x65C5}, //13267 #CJK UNIFIED IDEOGRAPH + {0xD5EA, 0x6ADA}, //13268 #CJK UNIFIED IDEOGRAPH + {0xD5EB, 0x6FFE}, //13269 #CJK UNIFIED IDEOGRAPH + {0xD5EC, 0x792A}, //13270 #CJK UNIFIED IDEOGRAPH + {0xD5ED, 0x85DC}, //13271 #CJK UNIFIED IDEOGRAPH + {0xD5EE, 0x8823}, //13272 #CJK UNIFIED IDEOGRAPH + {0xD5EF, 0x95AD}, //13273 #CJK UNIFIED IDEOGRAPH + {0xD5F0, 0x9A62}, //13274 #CJK UNIFIED IDEOGRAPH + {0xD5F1, 0x9A6A}, //13275 #CJK UNIFIED IDEOGRAPH + {0xD5F2, 0x9E97}, //13276 #CJK UNIFIED IDEOGRAPH + {0xD5F3, 0x9ECE}, //13277 #CJK UNIFIED IDEOGRAPH + {0xD5F4, 0x529B}, //13278 #CJK UNIFIED IDEOGRAPH + {0xD5F5, 0x66C6}, //13279 #CJK UNIFIED IDEOGRAPH + {0xD5F6, 0x6B77}, //13280 #CJK UNIFIED IDEOGRAPH + {0xD5F7, 0x701D}, //13281 #CJK UNIFIED IDEOGRAPH + {0xD5F8, 0x792B}, //13282 #CJK UNIFIED IDEOGRAPH + {0xD5F9, 0x8F62}, //13283 #CJK UNIFIED IDEOGRAPH + {0xD5FA, 0x9742}, //13284 #CJK UNIFIED IDEOGRAPH + {0xD5FB, 0x6190}, //13285 #CJK UNIFIED IDEOGRAPH + {0xD5FC, 0x6200}, //13286 #CJK UNIFIED IDEOGRAPH + {0xD5FD, 0x6523}, //13287 #CJK UNIFIED IDEOGRAPH + {0xD5FE, 0x6F23}, //13288 #CJK UNIFIED IDEOGRAPH + {0xD6A1, 0x7149}, //13289 #CJK UNIFIED IDEOGRAPH + {0xD6A2, 0x7489}, //13290 #CJK UNIFIED IDEOGRAPH + {0xD6A3, 0x7DF4}, //13291 #CJK UNIFIED IDEOGRAPH + {0xD6A4, 0x806F}, //13292 #CJK UNIFIED IDEOGRAPH + {0xD6A5, 0x84EE}, //13293 #CJK UNIFIED IDEOGRAPH + {0xD6A6, 0x8F26}, //13294 #CJK UNIFIED IDEOGRAPH + {0xD6A7, 0x9023}, //13295 #CJK UNIFIED IDEOGRAPH + {0xD6A8, 0x934A}, //13296 #CJK UNIFIED IDEOGRAPH + {0xD6A9, 0x51BD}, //13297 #CJK UNIFIED IDEOGRAPH + {0xD6AA, 0x5217}, //13298 #CJK UNIFIED IDEOGRAPH + {0xD6AB, 0x52A3}, //13299 #CJK UNIFIED IDEOGRAPH + {0xD6AC, 0x6D0C}, //13300 #CJK UNIFIED IDEOGRAPH + {0xD6AD, 0x70C8}, //13301 #CJK UNIFIED IDEOGRAPH + {0xD6AE, 0x88C2}, //13302 #CJK UNIFIED IDEOGRAPH + {0xD6AF, 0x5EC9}, //13303 #CJK UNIFIED IDEOGRAPH + {0xD6B0, 0x6582}, //13304 #CJK UNIFIED IDEOGRAPH + {0xD6B1, 0x6BAE}, //13305 #CJK UNIFIED IDEOGRAPH + {0xD6B2, 0x6FC2}, //13306 #CJK UNIFIED IDEOGRAPH + {0xD6B3, 0x7C3E}, //13307 #CJK UNIFIED IDEOGRAPH + {0xD6B4, 0x7375}, //13308 #CJK UNIFIED IDEOGRAPH + {0xD6B5, 0x4EE4}, //13309 #CJK UNIFIED IDEOGRAPH + {0xD6B6, 0x4F36}, //13310 #CJK UNIFIED IDEOGRAPH + {0xD6B7, 0x56F9}, //13311 #CJK UNIFIED IDEOGRAPH + {0xD6B8, 0xF95F}, //13312 #CJK COMPATIBILITY IDEOGRAPH + {0xD6B9, 0x5CBA}, //13313 #CJK UNIFIED IDEOGRAPH + {0xD6BA, 0x5DBA}, //13314 #CJK UNIFIED IDEOGRAPH + {0xD6BB, 0x601C}, //13315 #CJK UNIFIED IDEOGRAPH + {0xD6BC, 0x73B2}, //13316 #CJK UNIFIED IDEOGRAPH + {0xD6BD, 0x7B2D}, //13317 #CJK UNIFIED IDEOGRAPH + {0xD6BE, 0x7F9A}, //13318 #CJK UNIFIED IDEOGRAPH + {0xD6BF, 0x7FCE}, //13319 #CJK UNIFIED IDEOGRAPH + {0xD6C0, 0x8046}, //13320 #CJK UNIFIED IDEOGRAPH + {0xD6C1, 0x901E}, //13321 #CJK UNIFIED IDEOGRAPH + {0xD6C2, 0x9234}, //13322 #CJK UNIFIED IDEOGRAPH + {0xD6C3, 0x96F6}, //13323 #CJK UNIFIED IDEOGRAPH + {0xD6C4, 0x9748}, //13324 #CJK UNIFIED IDEOGRAPH + {0xD6C5, 0x9818}, //13325 #CJK UNIFIED IDEOGRAPH + {0xD6C6, 0x9F61}, //13326 #CJK UNIFIED IDEOGRAPH + {0xD6C7, 0x4F8B}, //13327 #CJK UNIFIED IDEOGRAPH + {0xD6C8, 0x6FA7}, //13328 #CJK UNIFIED IDEOGRAPH + {0xD6C9, 0x79AE}, //13329 #CJK UNIFIED IDEOGRAPH + {0xD6CA, 0x91B4}, //13330 #CJK UNIFIED IDEOGRAPH + {0xD6CB, 0x96B7}, //13331 #CJK UNIFIED IDEOGRAPH + {0xD6CC, 0x52DE}, //13332 #CJK UNIFIED IDEOGRAPH + {0xD6CD, 0xF960}, //13333 #CJK COMPATIBILITY IDEOGRAPH + {0xD6CE, 0x6488}, //13334 #CJK UNIFIED IDEOGRAPH + {0xD6CF, 0x64C4}, //13335 #CJK UNIFIED IDEOGRAPH + {0xD6D0, 0x6AD3}, //13336 #CJK UNIFIED IDEOGRAPH + {0xD6D1, 0x6F5E}, //13337 #CJK UNIFIED IDEOGRAPH + {0xD6D2, 0x7018}, //13338 #CJK UNIFIED IDEOGRAPH + {0xD6D3, 0x7210}, //13339 #CJK UNIFIED IDEOGRAPH + {0xD6D4, 0x76E7}, //13340 #CJK UNIFIED IDEOGRAPH + {0xD6D5, 0x8001}, //13341 #CJK UNIFIED IDEOGRAPH + {0xD6D6, 0x8606}, //13342 #CJK UNIFIED IDEOGRAPH + {0xD6D7, 0x865C}, //13343 #CJK UNIFIED IDEOGRAPH + {0xD6D8, 0x8DEF}, //13344 #CJK UNIFIED IDEOGRAPH + {0xD6D9, 0x8F05}, //13345 #CJK UNIFIED IDEOGRAPH + {0xD6DA, 0x9732}, //13346 #CJK UNIFIED IDEOGRAPH + {0xD6DB, 0x9B6F}, //13347 #CJK UNIFIED IDEOGRAPH + {0xD6DC, 0x9DFA}, //13348 #CJK UNIFIED IDEOGRAPH + {0xD6DD, 0x9E75}, //13349 #CJK UNIFIED IDEOGRAPH + {0xD6DE, 0x788C}, //13350 #CJK UNIFIED IDEOGRAPH + {0xD6DF, 0x797F}, //13351 #CJK UNIFIED IDEOGRAPH + {0xD6E0, 0x7DA0}, //13352 #CJK UNIFIED IDEOGRAPH + {0xD6E1, 0x83C9}, //13353 #CJK UNIFIED IDEOGRAPH + {0xD6E2, 0x9304}, //13354 #CJK UNIFIED IDEOGRAPH + {0xD6E3, 0x9E7F}, //13355 #CJK UNIFIED IDEOGRAPH + {0xD6E4, 0x9E93}, //13356 #CJK UNIFIED IDEOGRAPH + {0xD6E5, 0x8AD6}, //13357 #CJK UNIFIED IDEOGRAPH + {0xD6E6, 0x58DF}, //13358 #CJK UNIFIED IDEOGRAPH + {0xD6E7, 0x5F04}, //13359 #CJK UNIFIED IDEOGRAPH + {0xD6E8, 0x6727}, //13360 #CJK UNIFIED IDEOGRAPH + {0xD6E9, 0x7027}, //13361 #CJK UNIFIED IDEOGRAPH + {0xD6EA, 0x74CF}, //13362 #CJK UNIFIED IDEOGRAPH + {0xD6EB, 0x7C60}, //13363 #CJK UNIFIED IDEOGRAPH + {0xD6EC, 0x807E}, //13364 #CJK UNIFIED IDEOGRAPH + {0xD6ED, 0x5121}, //13365 #CJK UNIFIED IDEOGRAPH + {0xD6EE, 0x7028}, //13366 #CJK UNIFIED IDEOGRAPH + {0xD6EF, 0x7262}, //13367 #CJK UNIFIED IDEOGRAPH + {0xD6F0, 0x78CA}, //13368 #CJK UNIFIED IDEOGRAPH + {0xD6F1, 0x8CC2}, //13369 #CJK UNIFIED IDEOGRAPH + {0xD6F2, 0x8CDA}, //13370 #CJK UNIFIED IDEOGRAPH + {0xD6F3, 0x8CF4}, //13371 #CJK UNIFIED IDEOGRAPH + {0xD6F4, 0x96F7}, //13372 #CJK UNIFIED IDEOGRAPH + {0xD6F5, 0x4E86}, //13373 #CJK UNIFIED IDEOGRAPH + {0xD6F6, 0x50DA}, //13374 #CJK UNIFIED IDEOGRAPH + {0xD6F7, 0x5BEE}, //13375 #CJK UNIFIED IDEOGRAPH + {0xD6F8, 0x5ED6}, //13376 #CJK UNIFIED IDEOGRAPH + {0xD6F9, 0x6599}, //13377 #CJK UNIFIED IDEOGRAPH + {0xD6FA, 0x71CE}, //13378 #CJK UNIFIED IDEOGRAPH + {0xD6FB, 0x7642}, //13379 #CJK UNIFIED IDEOGRAPH + {0xD6FC, 0x77AD}, //13380 #CJK UNIFIED IDEOGRAPH + {0xD6FD, 0x804A}, //13381 #CJK UNIFIED IDEOGRAPH + {0xD6FE, 0x84FC}, //13382 #CJK UNIFIED IDEOGRAPH + {0xD7A1, 0x907C}, //13383 #CJK UNIFIED IDEOGRAPH + {0xD7A2, 0x9B27}, //13384 #CJK UNIFIED IDEOGRAPH + {0xD7A3, 0x9F8D}, //13385 #CJK UNIFIED IDEOGRAPH + {0xD7A4, 0x58D8}, //13386 #CJK UNIFIED IDEOGRAPH + {0xD7A5, 0x5A41}, //13387 #CJK UNIFIED IDEOGRAPH + {0xD7A6, 0x5C62}, //13388 #CJK UNIFIED IDEOGRAPH + {0xD7A7, 0x6A13}, //13389 #CJK UNIFIED IDEOGRAPH + {0xD7A8, 0x6DDA}, //13390 #CJK UNIFIED IDEOGRAPH + {0xD7A9, 0x6F0F}, //13391 #CJK UNIFIED IDEOGRAPH + {0xD7AA, 0x763B}, //13392 #CJK UNIFIED IDEOGRAPH + {0xD7AB, 0x7D2F}, //13393 #CJK UNIFIED IDEOGRAPH + {0xD7AC, 0x7E37}, //13394 #CJK UNIFIED IDEOGRAPH + {0xD7AD, 0x851E}, //13395 #CJK UNIFIED IDEOGRAPH + {0xD7AE, 0x8938}, //13396 #CJK UNIFIED IDEOGRAPH + {0xD7AF, 0x93E4}, //13397 #CJK UNIFIED IDEOGRAPH + {0xD7B0, 0x964B}, //13398 #CJK UNIFIED IDEOGRAPH + {0xD7B1, 0x5289}, //13399 #CJK UNIFIED IDEOGRAPH + {0xD7B2, 0x65D2}, //13400 #CJK UNIFIED IDEOGRAPH + {0xD7B3, 0x67F3}, //13401 #CJK UNIFIED IDEOGRAPH + {0xD7B4, 0x69B4}, //13402 #CJK UNIFIED IDEOGRAPH + {0xD7B5, 0x6D41}, //13403 #CJK UNIFIED IDEOGRAPH + {0xD7B6, 0x6E9C}, //13404 #CJK UNIFIED IDEOGRAPH + {0xD7B7, 0x700F}, //13405 #CJK UNIFIED IDEOGRAPH + {0xD7B8, 0x7409}, //13406 #CJK UNIFIED IDEOGRAPH + {0xD7B9, 0x7460}, //13407 #CJK UNIFIED IDEOGRAPH + {0xD7BA, 0x7559}, //13408 #CJK UNIFIED IDEOGRAPH + {0xD7BB, 0x7624}, //13409 #CJK UNIFIED IDEOGRAPH + {0xD7BC, 0x786B}, //13410 #CJK UNIFIED IDEOGRAPH + {0xD7BD, 0x8B2C}, //13411 #CJK UNIFIED IDEOGRAPH + {0xD7BE, 0x985E}, //13412 #CJK UNIFIED IDEOGRAPH + {0xD7BF, 0x516D}, //13413 #CJK UNIFIED IDEOGRAPH + {0xD7C0, 0x622E}, //13414 #CJK UNIFIED IDEOGRAPH + {0xD7C1, 0x9678}, //13415 #CJK UNIFIED IDEOGRAPH + {0xD7C2, 0x4F96}, //13416 #CJK UNIFIED IDEOGRAPH + {0xD7C3, 0x502B}, //13417 #CJK UNIFIED IDEOGRAPH + {0xD7C4, 0x5D19}, //13418 #CJK UNIFIED IDEOGRAPH + {0xD7C5, 0x6DEA}, //13419 #CJK UNIFIED IDEOGRAPH + {0xD7C6, 0x7DB8}, //13420 #CJK UNIFIED IDEOGRAPH + {0xD7C7, 0x8F2A}, //13421 #CJK UNIFIED IDEOGRAPH + {0xD7C8, 0x5F8B}, //13422 #CJK UNIFIED IDEOGRAPH + {0xD7C9, 0x6144}, //13423 #CJK UNIFIED IDEOGRAPH + {0xD7CA, 0x6817}, //13424 #CJK UNIFIED IDEOGRAPH + {0xD7CB, 0xF961}, //13425 #CJK COMPATIBILITY IDEOGRAPH + {0xD7CC, 0x9686}, //13426 #CJK UNIFIED IDEOGRAPH + {0xD7CD, 0x52D2}, //13427 #CJK UNIFIED IDEOGRAPH + {0xD7CE, 0x808B}, //13428 #CJK UNIFIED IDEOGRAPH + {0xD7CF, 0x51DC}, //13429 #CJK UNIFIED IDEOGRAPH + {0xD7D0, 0x51CC}, //13430 #CJK UNIFIED IDEOGRAPH + {0xD7D1, 0x695E}, //13431 #CJK UNIFIED IDEOGRAPH + {0xD7D2, 0x7A1C}, //13432 #CJK UNIFIED IDEOGRAPH + {0xD7D3, 0x7DBE}, //13433 #CJK UNIFIED IDEOGRAPH + {0xD7D4, 0x83F1}, //13434 #CJK UNIFIED IDEOGRAPH + {0xD7D5, 0x9675}, //13435 #CJK UNIFIED IDEOGRAPH + {0xD7D6, 0x4FDA}, //13436 #CJK UNIFIED IDEOGRAPH + {0xD7D7, 0x5229}, //13437 #CJK UNIFIED IDEOGRAPH + {0xD7D8, 0x5398}, //13438 #CJK UNIFIED IDEOGRAPH + {0xD7D9, 0x540F}, //13439 #CJK UNIFIED IDEOGRAPH + {0xD7DA, 0x550E}, //13440 #CJK UNIFIED IDEOGRAPH + {0xD7DB, 0x5C65}, //13441 #CJK UNIFIED IDEOGRAPH + {0xD7DC, 0x60A7}, //13442 #CJK UNIFIED IDEOGRAPH + {0xD7DD, 0x674E}, //13443 #CJK UNIFIED IDEOGRAPH + {0xD7DE, 0x68A8}, //13444 #CJK UNIFIED IDEOGRAPH + {0xD7DF, 0x6D6C}, //13445 #CJK UNIFIED IDEOGRAPH + {0xD7E0, 0x7281}, //13446 #CJK UNIFIED IDEOGRAPH + {0xD7E1, 0x72F8}, //13447 #CJK UNIFIED IDEOGRAPH + {0xD7E2, 0x7406}, //13448 #CJK UNIFIED IDEOGRAPH + {0xD7E3, 0x7483}, //13449 #CJK UNIFIED IDEOGRAPH + {0xD7E4, 0xF962}, //13450 #CJK COMPATIBILITY IDEOGRAPH + {0xD7E5, 0x75E2}, //13451 #CJK UNIFIED IDEOGRAPH + {0xD7E6, 0x7C6C}, //13452 #CJK UNIFIED IDEOGRAPH + {0xD7E7, 0x7F79}, //13453 #CJK UNIFIED IDEOGRAPH + {0xD7E8, 0x7FB8}, //13454 #CJK UNIFIED IDEOGRAPH + {0xD7E9, 0x8389}, //13455 #CJK UNIFIED IDEOGRAPH + {0xD7EA, 0x88CF}, //13456 #CJK UNIFIED IDEOGRAPH + {0xD7EB, 0x88E1}, //13457 #CJK UNIFIED IDEOGRAPH + {0xD7EC, 0x91CC}, //13458 #CJK UNIFIED IDEOGRAPH + {0xD7ED, 0x91D0}, //13459 #CJK UNIFIED IDEOGRAPH + {0xD7EE, 0x96E2}, //13460 #CJK UNIFIED IDEOGRAPH + {0xD7EF, 0x9BC9}, //13461 #CJK UNIFIED IDEOGRAPH + {0xD7F0, 0x541D}, //13462 #CJK UNIFIED IDEOGRAPH + {0xD7F1, 0x6F7E}, //13463 #CJK UNIFIED IDEOGRAPH + {0xD7F2, 0x71D0}, //13464 #CJK UNIFIED IDEOGRAPH + {0xD7F3, 0x7498}, //13465 #CJK UNIFIED IDEOGRAPH + {0xD7F4, 0x85FA}, //13466 #CJK UNIFIED IDEOGRAPH + {0xD7F5, 0x8EAA}, //13467 #CJK UNIFIED IDEOGRAPH + {0xD7F6, 0x96A3}, //13468 #CJK UNIFIED IDEOGRAPH + {0xD7F7, 0x9C57}, //13469 #CJK UNIFIED IDEOGRAPH + {0xD7F8, 0x9E9F}, //13470 #CJK UNIFIED IDEOGRAPH + {0xD7F9, 0x6797}, //13471 #CJK UNIFIED IDEOGRAPH + {0xD7FA, 0x6DCB}, //13472 #CJK UNIFIED IDEOGRAPH + {0xD7FB, 0x7433}, //13473 #CJK UNIFIED IDEOGRAPH + {0xD7FC, 0x81E8}, //13474 #CJK UNIFIED IDEOGRAPH + {0xD7FD, 0x9716}, //13475 #CJK UNIFIED IDEOGRAPH + {0xD7FE, 0x782C}, //13476 #CJK UNIFIED IDEOGRAPH + {0xD8A1, 0x7ACB}, //13477 #CJK UNIFIED IDEOGRAPH + {0xD8A2, 0x7B20}, //13478 #CJK UNIFIED IDEOGRAPH + {0xD8A3, 0x7C92}, //13479 #CJK UNIFIED IDEOGRAPH + {0xD8A4, 0x6469}, //13480 #CJK UNIFIED IDEOGRAPH + {0xD8A5, 0x746A}, //13481 #CJK UNIFIED IDEOGRAPH + {0xD8A6, 0x75F2}, //13482 #CJK UNIFIED IDEOGRAPH + {0xD8A7, 0x78BC}, //13483 #CJK UNIFIED IDEOGRAPH + {0xD8A8, 0x78E8}, //13484 #CJK UNIFIED IDEOGRAPH + {0xD8A9, 0x99AC}, //13485 #CJK UNIFIED IDEOGRAPH + {0xD8AA, 0x9B54}, //13486 #CJK UNIFIED IDEOGRAPH + {0xD8AB, 0x9EBB}, //13487 #CJK UNIFIED IDEOGRAPH + {0xD8AC, 0x5BDE}, //13488 #CJK UNIFIED IDEOGRAPH + {0xD8AD, 0x5E55}, //13489 #CJK UNIFIED IDEOGRAPH + {0xD8AE, 0x6F20}, //13490 #CJK UNIFIED IDEOGRAPH + {0xD8AF, 0x819C}, //13491 #CJK UNIFIED IDEOGRAPH + {0xD8B0, 0x83AB}, //13492 #CJK UNIFIED IDEOGRAPH + {0xD8B1, 0x9088}, //13493 #CJK UNIFIED IDEOGRAPH + {0xD8B2, 0x4E07}, //13494 #CJK UNIFIED IDEOGRAPH + {0xD8B3, 0x534D}, //13495 #CJK UNIFIED IDEOGRAPH + {0xD8B4, 0x5A29}, //13496 #CJK UNIFIED IDEOGRAPH + {0xD8B5, 0x5DD2}, //13497 #CJK UNIFIED IDEOGRAPH + {0xD8B6, 0x5F4E}, //13498 #CJK UNIFIED IDEOGRAPH + {0xD8B7, 0x6162}, //13499 #CJK UNIFIED IDEOGRAPH + {0xD8B8, 0x633D}, //13500 #CJK UNIFIED IDEOGRAPH + {0xD8B9, 0x6669}, //13501 #CJK UNIFIED IDEOGRAPH + {0xD8BA, 0x66FC}, //13502 #CJK UNIFIED IDEOGRAPH + {0xD8BB, 0x6EFF}, //13503 #CJK UNIFIED IDEOGRAPH + {0xD8BC, 0x6F2B}, //13504 #CJK UNIFIED IDEOGRAPH + {0xD8BD, 0x7063}, //13505 #CJK UNIFIED IDEOGRAPH + {0xD8BE, 0x779E}, //13506 #CJK UNIFIED IDEOGRAPH + {0xD8BF, 0x842C}, //13507 #CJK UNIFIED IDEOGRAPH + {0xD8C0, 0x8513}, //13508 #CJK UNIFIED IDEOGRAPH + {0xD8C1, 0x883B}, //13509 #CJK UNIFIED IDEOGRAPH + {0xD8C2, 0x8F13}, //13510 #CJK UNIFIED IDEOGRAPH + {0xD8C3, 0x9945}, //13511 #CJK UNIFIED IDEOGRAPH + {0xD8C4, 0x9C3B}, //13512 #CJK UNIFIED IDEOGRAPH + {0xD8C5, 0x551C}, //13513 #CJK UNIFIED IDEOGRAPH + {0xD8C6, 0x62B9}, //13514 #CJK UNIFIED IDEOGRAPH + {0xD8C7, 0x672B}, //13515 #CJK UNIFIED IDEOGRAPH + {0xD8C8, 0x6CAB}, //13516 #CJK UNIFIED IDEOGRAPH + {0xD8C9, 0x8309}, //13517 #CJK UNIFIED IDEOGRAPH + {0xD8CA, 0x896A}, //13518 #CJK UNIFIED IDEOGRAPH + {0xD8CB, 0x977A}, //13519 #CJK UNIFIED IDEOGRAPH + {0xD8CC, 0x4EA1}, //13520 #CJK UNIFIED IDEOGRAPH + {0xD8CD, 0x5984}, //13521 #CJK UNIFIED IDEOGRAPH + {0xD8CE, 0x5FD8}, //13522 #CJK UNIFIED IDEOGRAPH + {0xD8CF, 0x5FD9}, //13523 #CJK UNIFIED IDEOGRAPH + {0xD8D0, 0x671B}, //13524 #CJK UNIFIED IDEOGRAPH + {0xD8D1, 0x7DB2}, //13525 #CJK UNIFIED IDEOGRAPH + {0xD8D2, 0x7F54}, //13526 #CJK UNIFIED IDEOGRAPH + {0xD8D3, 0x8292}, //13527 #CJK UNIFIED IDEOGRAPH + {0xD8D4, 0x832B}, //13528 #CJK UNIFIED IDEOGRAPH + {0xD8D5, 0x83BD}, //13529 #CJK UNIFIED IDEOGRAPH + {0xD8D6, 0x8F1E}, //13530 #CJK UNIFIED IDEOGRAPH + {0xD8D7, 0x9099}, //13531 #CJK UNIFIED IDEOGRAPH + {0xD8D8, 0x57CB}, //13532 #CJK UNIFIED IDEOGRAPH + {0xD8D9, 0x59B9}, //13533 #CJK UNIFIED IDEOGRAPH + {0xD8DA, 0x5A92}, //13534 #CJK UNIFIED IDEOGRAPH + {0xD8DB, 0x5BD0}, //13535 #CJK UNIFIED IDEOGRAPH + {0xD8DC, 0x6627}, //13536 #CJK UNIFIED IDEOGRAPH + {0xD8DD, 0x679A}, //13537 #CJK UNIFIED IDEOGRAPH + {0xD8DE, 0x6885}, //13538 #CJK UNIFIED IDEOGRAPH + {0xD8DF, 0x6BCF}, //13539 #CJK UNIFIED IDEOGRAPH + {0xD8E0, 0x7164}, //13540 #CJK UNIFIED IDEOGRAPH + {0xD8E1, 0x7F75}, //13541 #CJK UNIFIED IDEOGRAPH + {0xD8E2, 0x8CB7}, //13542 #CJK UNIFIED IDEOGRAPH + {0xD8E3, 0x8CE3}, //13543 #CJK UNIFIED IDEOGRAPH + {0xD8E4, 0x9081}, //13544 #CJK UNIFIED IDEOGRAPH + {0xD8E5, 0x9B45}, //13545 #CJK UNIFIED IDEOGRAPH + {0xD8E6, 0x8108}, //13546 #CJK UNIFIED IDEOGRAPH + {0xD8E7, 0x8C8A}, //13547 #CJK UNIFIED IDEOGRAPH + {0xD8E8, 0x964C}, //13548 #CJK UNIFIED IDEOGRAPH + {0xD8E9, 0x9A40}, //13549 #CJK UNIFIED IDEOGRAPH + {0xD8EA, 0x9EA5}, //13550 #CJK UNIFIED IDEOGRAPH + {0xD8EB, 0x5B5F}, //13551 #CJK UNIFIED IDEOGRAPH + {0xD8EC, 0x6C13}, //13552 #CJK UNIFIED IDEOGRAPH + {0xD8ED, 0x731B}, //13553 #CJK UNIFIED IDEOGRAPH + {0xD8EE, 0x76F2}, //13554 #CJK UNIFIED IDEOGRAPH + {0xD8EF, 0x76DF}, //13555 #CJK UNIFIED IDEOGRAPH + {0xD8F0, 0x840C}, //13556 #CJK UNIFIED IDEOGRAPH + {0xD8F1, 0x51AA}, //13557 #CJK UNIFIED IDEOGRAPH + {0xD8F2, 0x8993}, //13558 #CJK UNIFIED IDEOGRAPH + {0xD8F3, 0x514D}, //13559 #CJK UNIFIED IDEOGRAPH + {0xD8F4, 0x5195}, //13560 #CJK UNIFIED IDEOGRAPH + {0xD8F5, 0x52C9}, //13561 #CJK UNIFIED IDEOGRAPH + {0xD8F6, 0x68C9}, //13562 #CJK UNIFIED IDEOGRAPH + {0xD8F7, 0x6C94}, //13563 #CJK UNIFIED IDEOGRAPH + {0xD8F8, 0x7704}, //13564 #CJK UNIFIED IDEOGRAPH + {0xD8F9, 0x7720}, //13565 #CJK UNIFIED IDEOGRAPH + {0xD8FA, 0x7DBF}, //13566 #CJK UNIFIED IDEOGRAPH + {0xD8FB, 0x7DEC}, //13567 #CJK UNIFIED IDEOGRAPH + {0xD8FC, 0x9762}, //13568 #CJK UNIFIED IDEOGRAPH + {0xD8FD, 0x9EB5}, //13569 #CJK UNIFIED IDEOGRAPH + {0xD8FE, 0x6EC5}, //13570 #CJK UNIFIED IDEOGRAPH + {0xD9A1, 0x8511}, //13571 #CJK UNIFIED IDEOGRAPH + {0xD9A2, 0x51A5}, //13572 #CJK UNIFIED IDEOGRAPH + {0xD9A3, 0x540D}, //13573 #CJK UNIFIED IDEOGRAPH + {0xD9A4, 0x547D}, //13574 #CJK UNIFIED IDEOGRAPH + {0xD9A5, 0x660E}, //13575 #CJK UNIFIED IDEOGRAPH + {0xD9A6, 0x669D}, //13576 #CJK UNIFIED IDEOGRAPH + {0xD9A7, 0x6927}, //13577 #CJK UNIFIED IDEOGRAPH + {0xD9A8, 0x6E9F}, //13578 #CJK UNIFIED IDEOGRAPH + {0xD9A9, 0x76BF}, //13579 #CJK UNIFIED IDEOGRAPH + {0xD9AA, 0x7791}, //13580 #CJK UNIFIED IDEOGRAPH + {0xD9AB, 0x8317}, //13581 #CJK UNIFIED IDEOGRAPH + {0xD9AC, 0x84C2}, //13582 #CJK UNIFIED IDEOGRAPH + {0xD9AD, 0x879F}, //13583 #CJK UNIFIED IDEOGRAPH + {0xD9AE, 0x9169}, //13584 #CJK UNIFIED IDEOGRAPH + {0xD9AF, 0x9298}, //13585 #CJK UNIFIED IDEOGRAPH + {0xD9B0, 0x9CF4}, //13586 #CJK UNIFIED IDEOGRAPH + {0xD9B1, 0x8882}, //13587 #CJK UNIFIED IDEOGRAPH + {0xD9B2, 0x4FAE}, //13588 #CJK UNIFIED IDEOGRAPH + {0xD9B3, 0x5192}, //13589 #CJK UNIFIED IDEOGRAPH + {0xD9B4, 0x52DF}, //13590 #CJK UNIFIED IDEOGRAPH + {0xD9B5, 0x59C6}, //13591 #CJK UNIFIED IDEOGRAPH + {0xD9B6, 0x5E3D}, //13592 #CJK UNIFIED IDEOGRAPH + {0xD9B7, 0x6155}, //13593 #CJK UNIFIED IDEOGRAPH + {0xD9B8, 0x6478}, //13594 #CJK UNIFIED IDEOGRAPH + {0xD9B9, 0x6479}, //13595 #CJK UNIFIED IDEOGRAPH + {0xD9BA, 0x66AE}, //13596 #CJK UNIFIED IDEOGRAPH + {0xD9BB, 0x67D0}, //13597 #CJK UNIFIED IDEOGRAPH + {0xD9BC, 0x6A21}, //13598 #CJK UNIFIED IDEOGRAPH + {0xD9BD, 0x6BCD}, //13599 #CJK UNIFIED IDEOGRAPH + {0xD9BE, 0x6BDB}, //13600 #CJK UNIFIED IDEOGRAPH + {0xD9BF, 0x725F}, //13601 #CJK UNIFIED IDEOGRAPH + {0xD9C0, 0x7261}, //13602 #CJK UNIFIED IDEOGRAPH + {0xD9C1, 0x7441}, //13603 #CJK UNIFIED IDEOGRAPH + {0xD9C2, 0x7738}, //13604 #CJK UNIFIED IDEOGRAPH + {0xD9C3, 0x77DB}, //13605 #CJK UNIFIED IDEOGRAPH + {0xD9C4, 0x8017}, //13606 #CJK UNIFIED IDEOGRAPH + {0xD9C5, 0x82BC}, //13607 #CJK UNIFIED IDEOGRAPH + {0xD9C6, 0x8305}, //13608 #CJK UNIFIED IDEOGRAPH + {0xD9C7, 0x8B00}, //13609 #CJK UNIFIED IDEOGRAPH + {0xD9C8, 0x8B28}, //13610 #CJK UNIFIED IDEOGRAPH + {0xD9C9, 0x8C8C}, //13611 #CJK UNIFIED IDEOGRAPH + {0xD9CA, 0x6728}, //13612 #CJK UNIFIED IDEOGRAPH + {0xD9CB, 0x6C90}, //13613 #CJK UNIFIED IDEOGRAPH + {0xD9CC, 0x7267}, //13614 #CJK UNIFIED IDEOGRAPH + {0xD9CD, 0x76EE}, //13615 #CJK UNIFIED IDEOGRAPH + {0xD9CE, 0x7766}, //13616 #CJK UNIFIED IDEOGRAPH + {0xD9CF, 0x7A46}, //13617 #CJK UNIFIED IDEOGRAPH + {0xD9D0, 0x9DA9}, //13618 #CJK UNIFIED IDEOGRAPH + {0xD9D1, 0x6B7F}, //13619 #CJK UNIFIED IDEOGRAPH + {0xD9D2, 0x6C92}, //13620 #CJK UNIFIED IDEOGRAPH + {0xD9D3, 0x5922}, //13621 #CJK UNIFIED IDEOGRAPH + {0xD9D4, 0x6726}, //13622 #CJK UNIFIED IDEOGRAPH + {0xD9D5, 0x8499}, //13623 #CJK UNIFIED IDEOGRAPH + {0xD9D6, 0x536F}, //13624 #CJK UNIFIED IDEOGRAPH + {0xD9D7, 0x5893}, //13625 #CJK UNIFIED IDEOGRAPH + {0xD9D8, 0x5999}, //13626 #CJK UNIFIED IDEOGRAPH + {0xD9D9, 0x5EDF}, //13627 #CJK UNIFIED IDEOGRAPH + {0xD9DA, 0x63CF}, //13628 #CJK UNIFIED IDEOGRAPH + {0xD9DB, 0x6634}, //13629 #CJK UNIFIED IDEOGRAPH + {0xD9DC, 0x6773}, //13630 #CJK UNIFIED IDEOGRAPH + {0xD9DD, 0x6E3A}, //13631 #CJK UNIFIED IDEOGRAPH + {0xD9DE, 0x732B}, //13632 #CJK UNIFIED IDEOGRAPH + {0xD9DF, 0x7AD7}, //13633 #CJK UNIFIED IDEOGRAPH + {0xD9E0, 0x82D7}, //13634 #CJK UNIFIED IDEOGRAPH + {0xD9E1, 0x9328}, //13635 #CJK UNIFIED IDEOGRAPH + {0xD9E2, 0x52D9}, //13636 #CJK UNIFIED IDEOGRAPH + {0xD9E3, 0x5DEB}, //13637 #CJK UNIFIED IDEOGRAPH + {0xD9E4, 0x61AE}, //13638 #CJK UNIFIED IDEOGRAPH + {0xD9E5, 0x61CB}, //13639 #CJK UNIFIED IDEOGRAPH + {0xD9E6, 0x620A}, //13640 #CJK UNIFIED IDEOGRAPH + {0xD9E7, 0x62C7}, //13641 #CJK UNIFIED IDEOGRAPH + {0xD9E8, 0x64AB}, //13642 #CJK UNIFIED IDEOGRAPH + {0xD9E9, 0x65E0}, //13643 #CJK UNIFIED IDEOGRAPH + {0xD9EA, 0x6959}, //13644 #CJK UNIFIED IDEOGRAPH + {0xD9EB, 0x6B66}, //13645 #CJK UNIFIED IDEOGRAPH + {0xD9EC, 0x6BCB}, //13646 #CJK UNIFIED IDEOGRAPH + {0xD9ED, 0x7121}, //13647 #CJK UNIFIED IDEOGRAPH + {0xD9EE, 0x73F7}, //13648 #CJK UNIFIED IDEOGRAPH + {0xD9EF, 0x755D}, //13649 #CJK UNIFIED IDEOGRAPH + {0xD9F0, 0x7E46}, //13650 #CJK UNIFIED IDEOGRAPH + {0xD9F1, 0x821E}, //13651 #CJK UNIFIED IDEOGRAPH + {0xD9F2, 0x8302}, //13652 #CJK UNIFIED IDEOGRAPH + {0xD9F3, 0x856A}, //13653 #CJK UNIFIED IDEOGRAPH + {0xD9F4, 0x8AA3}, //13654 #CJK UNIFIED IDEOGRAPH + {0xD9F5, 0x8CBF}, //13655 #CJK UNIFIED IDEOGRAPH + {0xD9F6, 0x9727}, //13656 #CJK UNIFIED IDEOGRAPH + {0xD9F7, 0x9D61}, //13657 #CJK UNIFIED IDEOGRAPH + {0xD9F8, 0x58A8}, //13658 #CJK UNIFIED IDEOGRAPH + {0xD9F9, 0x9ED8}, //13659 #CJK UNIFIED IDEOGRAPH + {0xD9FA, 0x5011}, //13660 #CJK UNIFIED IDEOGRAPH + {0xD9FB, 0x520E}, //13661 #CJK UNIFIED IDEOGRAPH + {0xD9FC, 0x543B}, //13662 #CJK UNIFIED IDEOGRAPH + {0xD9FD, 0x554F}, //13663 #CJK UNIFIED IDEOGRAPH + {0xD9FE, 0x6587}, //13664 #CJK UNIFIED IDEOGRAPH + {0xDAA1, 0x6C76}, //13665 #CJK UNIFIED IDEOGRAPH + {0xDAA2, 0x7D0A}, //13666 #CJK UNIFIED IDEOGRAPH + {0xDAA3, 0x7D0B}, //13667 #CJK UNIFIED IDEOGRAPH + {0xDAA4, 0x805E}, //13668 #CJK UNIFIED IDEOGRAPH + {0xDAA5, 0x868A}, //13669 #CJK UNIFIED IDEOGRAPH + {0xDAA6, 0x9580}, //13670 #CJK UNIFIED IDEOGRAPH + {0xDAA7, 0x96EF}, //13671 #CJK UNIFIED IDEOGRAPH + {0xDAA8, 0x52FF}, //13672 #CJK UNIFIED IDEOGRAPH + {0xDAA9, 0x6C95}, //13673 #CJK UNIFIED IDEOGRAPH + {0xDAAA, 0x7269}, //13674 #CJK UNIFIED IDEOGRAPH + {0xDAAB, 0x5473}, //13675 #CJK UNIFIED IDEOGRAPH + {0xDAAC, 0x5A9A}, //13676 #CJK UNIFIED IDEOGRAPH + {0xDAAD, 0x5C3E}, //13677 #CJK UNIFIED IDEOGRAPH + {0xDAAE, 0x5D4B}, //13678 #CJK UNIFIED IDEOGRAPH + {0xDAAF, 0x5F4C}, //13679 #CJK UNIFIED IDEOGRAPH + {0xDAB0, 0x5FAE}, //13680 #CJK UNIFIED IDEOGRAPH + {0xDAB1, 0x672A}, //13681 #CJK UNIFIED IDEOGRAPH + {0xDAB2, 0x68B6}, //13682 #CJK UNIFIED IDEOGRAPH + {0xDAB3, 0x6963}, //13683 #CJK UNIFIED IDEOGRAPH + {0xDAB4, 0x6E3C}, //13684 #CJK UNIFIED IDEOGRAPH + {0xDAB5, 0x6E44}, //13685 #CJK UNIFIED IDEOGRAPH + {0xDAB6, 0x7709}, //13686 #CJK UNIFIED IDEOGRAPH + {0xDAB7, 0x7C73}, //13687 #CJK UNIFIED IDEOGRAPH + {0xDAB8, 0x7F8E}, //13688 #CJK UNIFIED IDEOGRAPH + {0xDAB9, 0x8587}, //13689 #CJK UNIFIED IDEOGRAPH + {0xDABA, 0x8B0E}, //13690 #CJK UNIFIED IDEOGRAPH + {0xDABB, 0x8FF7}, //13691 #CJK UNIFIED IDEOGRAPH + {0xDABC, 0x9761}, //13692 #CJK UNIFIED IDEOGRAPH + {0xDABD, 0x9EF4}, //13693 #CJK UNIFIED IDEOGRAPH + {0xDABE, 0x5CB7}, //13694 #CJK UNIFIED IDEOGRAPH + {0xDABF, 0x60B6}, //13695 #CJK UNIFIED IDEOGRAPH + {0xDAC0, 0x610D}, //13696 #CJK UNIFIED IDEOGRAPH + {0xDAC1, 0x61AB}, //13697 #CJK UNIFIED IDEOGRAPH + {0xDAC2, 0x654F}, //13698 #CJK UNIFIED IDEOGRAPH + {0xDAC3, 0x65FB}, //13699 #CJK UNIFIED IDEOGRAPH + {0xDAC4, 0x65FC}, //13700 #CJK UNIFIED IDEOGRAPH + {0xDAC5, 0x6C11}, //13701 #CJK UNIFIED IDEOGRAPH + {0xDAC6, 0x6CEF}, //13702 #CJK UNIFIED IDEOGRAPH + {0xDAC7, 0x739F}, //13703 #CJK UNIFIED IDEOGRAPH + {0xDAC8, 0x73C9}, //13704 #CJK UNIFIED IDEOGRAPH + {0xDAC9, 0x7DE1}, //13705 #CJK UNIFIED IDEOGRAPH + {0xDACA, 0x9594}, //13706 #CJK UNIFIED IDEOGRAPH + {0xDACB, 0x5BC6}, //13707 #CJK UNIFIED IDEOGRAPH + {0xDACC, 0x871C}, //13708 #CJK UNIFIED IDEOGRAPH + {0xDACD, 0x8B10}, //13709 #CJK UNIFIED IDEOGRAPH + {0xDACE, 0x525D}, //13710 #CJK UNIFIED IDEOGRAPH + {0xDACF, 0x535A}, //13711 #CJK UNIFIED IDEOGRAPH + {0xDAD0, 0x62CD}, //13712 #CJK UNIFIED IDEOGRAPH + {0xDAD1, 0x640F}, //13713 #CJK UNIFIED IDEOGRAPH + {0xDAD2, 0x64B2}, //13714 #CJK UNIFIED IDEOGRAPH + {0xDAD3, 0x6734}, //13715 #CJK UNIFIED IDEOGRAPH + {0xDAD4, 0x6A38}, //13716 #CJK UNIFIED IDEOGRAPH + {0xDAD5, 0x6CCA}, //13717 #CJK UNIFIED IDEOGRAPH + {0xDAD6, 0x73C0}, //13718 #CJK UNIFIED IDEOGRAPH + {0xDAD7, 0x749E}, //13719 #CJK UNIFIED IDEOGRAPH + {0xDAD8, 0x7B94}, //13720 #CJK UNIFIED IDEOGRAPH + {0xDAD9, 0x7C95}, //13721 #CJK UNIFIED IDEOGRAPH + {0xDADA, 0x7E1B}, //13722 #CJK UNIFIED IDEOGRAPH + {0xDADB, 0x818A}, //13723 #CJK UNIFIED IDEOGRAPH + {0xDADC, 0x8236}, //13724 #CJK UNIFIED IDEOGRAPH + {0xDADD, 0x8584}, //13725 #CJK UNIFIED IDEOGRAPH + {0xDADE, 0x8FEB}, //13726 #CJK UNIFIED IDEOGRAPH + {0xDADF, 0x96F9}, //13727 #CJK UNIFIED IDEOGRAPH + {0xDAE0, 0x99C1}, //13728 #CJK UNIFIED IDEOGRAPH + {0xDAE1, 0x4F34}, //13729 #CJK UNIFIED IDEOGRAPH + {0xDAE2, 0x534A}, //13730 #CJK UNIFIED IDEOGRAPH + {0xDAE3, 0x53CD}, //13731 #CJK UNIFIED IDEOGRAPH + {0xDAE4, 0x53DB}, //13732 #CJK UNIFIED IDEOGRAPH + {0xDAE5, 0x62CC}, //13733 #CJK UNIFIED IDEOGRAPH + {0xDAE6, 0x642C}, //13734 #CJK UNIFIED IDEOGRAPH + {0xDAE7, 0x6500}, //13735 #CJK UNIFIED IDEOGRAPH + {0xDAE8, 0x6591}, //13736 #CJK UNIFIED IDEOGRAPH + {0xDAE9, 0x69C3}, //13737 #CJK UNIFIED IDEOGRAPH + {0xDAEA, 0x6CEE}, //13738 #CJK UNIFIED IDEOGRAPH + {0xDAEB, 0x6F58}, //13739 #CJK UNIFIED IDEOGRAPH + {0xDAEC, 0x73ED}, //13740 #CJK UNIFIED IDEOGRAPH + {0xDAED, 0x7554}, //13741 #CJK UNIFIED IDEOGRAPH + {0xDAEE, 0x7622}, //13742 #CJK UNIFIED IDEOGRAPH + {0xDAEF, 0x76E4}, //13743 #CJK UNIFIED IDEOGRAPH + {0xDAF0, 0x76FC}, //13744 #CJK UNIFIED IDEOGRAPH + {0xDAF1, 0x78D0}, //13745 #CJK UNIFIED IDEOGRAPH + {0xDAF2, 0x78FB}, //13746 #CJK UNIFIED IDEOGRAPH + {0xDAF3, 0x792C}, //13747 #CJK UNIFIED IDEOGRAPH + {0xDAF4, 0x7D46}, //13748 #CJK UNIFIED IDEOGRAPH + {0xDAF5, 0x822C}, //13749 #CJK UNIFIED IDEOGRAPH + {0xDAF6, 0x87E0}, //13750 #CJK UNIFIED IDEOGRAPH + {0xDAF7, 0x8FD4}, //13751 #CJK UNIFIED IDEOGRAPH + {0xDAF8, 0x9812}, //13752 #CJK UNIFIED IDEOGRAPH + {0xDAF9, 0x98EF}, //13753 #CJK UNIFIED IDEOGRAPH + {0xDAFA, 0x52C3}, //13754 #CJK UNIFIED IDEOGRAPH + {0xDAFB, 0x62D4}, //13755 #CJK UNIFIED IDEOGRAPH + {0xDAFC, 0x64A5}, //13756 #CJK UNIFIED IDEOGRAPH + {0xDAFD, 0x6E24}, //13757 #CJK UNIFIED IDEOGRAPH + {0xDAFE, 0x6F51}, //13758 #CJK UNIFIED IDEOGRAPH + {0xDBA1, 0x767C}, //13759 #CJK UNIFIED IDEOGRAPH + {0xDBA2, 0x8DCB}, //13760 #CJK UNIFIED IDEOGRAPH + {0xDBA3, 0x91B1}, //13761 #CJK UNIFIED IDEOGRAPH + {0xDBA4, 0x9262}, //13762 #CJK UNIFIED IDEOGRAPH + {0xDBA5, 0x9AEE}, //13763 #CJK UNIFIED IDEOGRAPH + {0xDBA6, 0x9B43}, //13764 #CJK UNIFIED IDEOGRAPH + {0xDBA7, 0x5023}, //13765 #CJK UNIFIED IDEOGRAPH + {0xDBA8, 0x508D}, //13766 #CJK UNIFIED IDEOGRAPH + {0xDBA9, 0x574A}, //13767 #CJK UNIFIED IDEOGRAPH + {0xDBAA, 0x59A8}, //13768 #CJK UNIFIED IDEOGRAPH + {0xDBAB, 0x5C28}, //13769 #CJK UNIFIED IDEOGRAPH + {0xDBAC, 0x5E47}, //13770 #CJK UNIFIED IDEOGRAPH + {0xDBAD, 0x5F77}, //13771 #CJK UNIFIED IDEOGRAPH + {0xDBAE, 0x623F}, //13772 #CJK UNIFIED IDEOGRAPH + {0xDBAF, 0x653E}, //13773 #CJK UNIFIED IDEOGRAPH + {0xDBB0, 0x65B9}, //13774 #CJK UNIFIED IDEOGRAPH + {0xDBB1, 0x65C1}, //13775 #CJK UNIFIED IDEOGRAPH + {0xDBB2, 0x6609}, //13776 #CJK UNIFIED IDEOGRAPH + {0xDBB3, 0x678B}, //13777 #CJK UNIFIED IDEOGRAPH + {0xDBB4, 0x699C}, //13778 #CJK UNIFIED IDEOGRAPH + {0xDBB5, 0x6EC2}, //13779 #CJK UNIFIED IDEOGRAPH + {0xDBB6, 0x78C5}, //13780 #CJK UNIFIED IDEOGRAPH + {0xDBB7, 0x7D21}, //13781 #CJK UNIFIED IDEOGRAPH + {0xDBB8, 0x80AA}, //13782 #CJK UNIFIED IDEOGRAPH + {0xDBB9, 0x8180}, //13783 #CJK UNIFIED IDEOGRAPH + {0xDBBA, 0x822B}, //13784 #CJK UNIFIED IDEOGRAPH + {0xDBBB, 0x82B3}, //13785 #CJK UNIFIED IDEOGRAPH + {0xDBBC, 0x84A1}, //13786 #CJK UNIFIED IDEOGRAPH + {0xDBBD, 0x868C}, //13787 #CJK UNIFIED IDEOGRAPH + {0xDBBE, 0x8A2A}, //13788 #CJK UNIFIED IDEOGRAPH + {0xDBBF, 0x8B17}, //13789 #CJK UNIFIED IDEOGRAPH + {0xDBC0, 0x90A6}, //13790 #CJK UNIFIED IDEOGRAPH + {0xDBC1, 0x9632}, //13791 #CJK UNIFIED IDEOGRAPH + {0xDBC2, 0x9F90}, //13792 #CJK UNIFIED IDEOGRAPH + {0xDBC3, 0x500D}, //13793 #CJK UNIFIED IDEOGRAPH + {0xDBC4, 0x4FF3}, //13794 #CJK UNIFIED IDEOGRAPH + {0xDBC5, 0xF963}, //13795 #CJK COMPATIBILITY IDEOGRAPH + {0xDBC6, 0x57F9}, //13796 #CJK UNIFIED IDEOGRAPH + {0xDBC7, 0x5F98}, //13797 #CJK UNIFIED IDEOGRAPH + {0xDBC8, 0x62DC}, //13798 #CJK UNIFIED IDEOGRAPH + {0xDBC9, 0x6392}, //13799 #CJK UNIFIED IDEOGRAPH + {0xDBCA, 0x676F}, //13800 #CJK UNIFIED IDEOGRAPH + {0xDBCB, 0x6E43}, //13801 #CJK UNIFIED IDEOGRAPH + {0xDBCC, 0x7119}, //13802 #CJK UNIFIED IDEOGRAPH + {0xDBCD, 0x76C3}, //13803 #CJK UNIFIED IDEOGRAPH + {0xDBCE, 0x80CC}, //13804 #CJK UNIFIED IDEOGRAPH + {0xDBCF, 0x80DA}, //13805 #CJK UNIFIED IDEOGRAPH + {0xDBD0, 0x88F4}, //13806 #CJK UNIFIED IDEOGRAPH + {0xDBD1, 0x88F5}, //13807 #CJK UNIFIED IDEOGRAPH + {0xDBD2, 0x8919}, //13808 #CJK UNIFIED IDEOGRAPH + {0xDBD3, 0x8CE0}, //13809 #CJK UNIFIED IDEOGRAPH + {0xDBD4, 0x8F29}, //13810 #CJK UNIFIED IDEOGRAPH + {0xDBD5, 0x914D}, //13811 #CJK UNIFIED IDEOGRAPH + {0xDBD6, 0x966A}, //13812 #CJK UNIFIED IDEOGRAPH + {0xDBD7, 0x4F2F}, //13813 #CJK UNIFIED IDEOGRAPH + {0xDBD8, 0x4F70}, //13814 #CJK UNIFIED IDEOGRAPH + {0xDBD9, 0x5E1B}, //13815 #CJK UNIFIED IDEOGRAPH + {0xDBDA, 0x67CF}, //13816 #CJK UNIFIED IDEOGRAPH + {0xDBDB, 0x6822}, //13817 #CJK UNIFIED IDEOGRAPH + {0xDBDC, 0x767D}, //13818 #CJK UNIFIED IDEOGRAPH + {0xDBDD, 0x767E}, //13819 #CJK UNIFIED IDEOGRAPH + {0xDBDE, 0x9B44}, //13820 #CJK UNIFIED IDEOGRAPH + {0xDBDF, 0x5E61}, //13821 #CJK UNIFIED IDEOGRAPH + {0xDBE0, 0x6A0A}, //13822 #CJK UNIFIED IDEOGRAPH + {0xDBE1, 0x7169}, //13823 #CJK UNIFIED IDEOGRAPH + {0xDBE2, 0x71D4}, //13824 #CJK UNIFIED IDEOGRAPH + {0xDBE3, 0x756A}, //13825 #CJK UNIFIED IDEOGRAPH + {0xDBE4, 0xF964}, //13826 #CJK COMPATIBILITY IDEOGRAPH + {0xDBE5, 0x7E41}, //13827 #CJK UNIFIED IDEOGRAPH + {0xDBE6, 0x8543}, //13828 #CJK UNIFIED IDEOGRAPH + {0xDBE7, 0x85E9}, //13829 #CJK UNIFIED IDEOGRAPH + {0xDBE8, 0x98DC}, //13830 #CJK UNIFIED IDEOGRAPH + {0xDBE9, 0x4F10}, //13831 #CJK UNIFIED IDEOGRAPH + {0xDBEA, 0x7B4F}, //13832 #CJK UNIFIED IDEOGRAPH + {0xDBEB, 0x7F70}, //13833 #CJK UNIFIED IDEOGRAPH + {0xDBEC, 0x95A5}, //13834 #CJK UNIFIED IDEOGRAPH + {0xDBED, 0x51E1}, //13835 #CJK UNIFIED IDEOGRAPH + {0xDBEE, 0x5E06}, //13836 #CJK UNIFIED IDEOGRAPH + {0xDBEF, 0x68B5}, //13837 #CJK UNIFIED IDEOGRAPH + {0xDBF0, 0x6C3E}, //13838 #CJK UNIFIED IDEOGRAPH + {0xDBF1, 0x6C4E}, //13839 #CJK UNIFIED IDEOGRAPH + {0xDBF2, 0x6CDB}, //13840 #CJK UNIFIED IDEOGRAPH + {0xDBF3, 0x72AF}, //13841 #CJK UNIFIED IDEOGRAPH + {0xDBF4, 0x7BC4}, //13842 #CJK UNIFIED IDEOGRAPH + {0xDBF5, 0x8303}, //13843 #CJK UNIFIED IDEOGRAPH + {0xDBF6, 0x6CD5}, //13844 #CJK UNIFIED IDEOGRAPH + {0xDBF7, 0x743A}, //13845 #CJK UNIFIED IDEOGRAPH + {0xDBF8, 0x50FB}, //13846 #CJK UNIFIED IDEOGRAPH + {0xDBF9, 0x5288}, //13847 #CJK UNIFIED IDEOGRAPH + {0xDBFA, 0x58C1}, //13848 #CJK UNIFIED IDEOGRAPH + {0xDBFB, 0x64D8}, //13849 #CJK UNIFIED IDEOGRAPH + {0xDBFC, 0x6A97}, //13850 #CJK UNIFIED IDEOGRAPH + {0xDBFD, 0x74A7}, //13851 #CJK UNIFIED IDEOGRAPH + {0xDBFE, 0x7656}, //13852 #CJK UNIFIED IDEOGRAPH + {0xDCA1, 0x78A7}, //13853 #CJK UNIFIED IDEOGRAPH + {0xDCA2, 0x8617}, //13854 #CJK UNIFIED IDEOGRAPH + {0xDCA3, 0x95E2}, //13855 #CJK UNIFIED IDEOGRAPH + {0xDCA4, 0x9739}, //13856 #CJK UNIFIED IDEOGRAPH + {0xDCA5, 0xF965}, //13857 #CJK COMPATIBILITY IDEOGRAPH + {0xDCA6, 0x535E}, //13858 #CJK UNIFIED IDEOGRAPH + {0xDCA7, 0x5F01}, //13859 #CJK UNIFIED IDEOGRAPH + {0xDCA8, 0x8B8A}, //13860 #CJK UNIFIED IDEOGRAPH + {0xDCA9, 0x8FA8}, //13861 #CJK UNIFIED IDEOGRAPH + {0xDCAA, 0x8FAF}, //13862 #CJK UNIFIED IDEOGRAPH + {0xDCAB, 0x908A}, //13863 #CJK UNIFIED IDEOGRAPH + {0xDCAC, 0x5225}, //13864 #CJK UNIFIED IDEOGRAPH + {0xDCAD, 0x77A5}, //13865 #CJK UNIFIED IDEOGRAPH + {0xDCAE, 0x9C49}, //13866 #CJK UNIFIED IDEOGRAPH + {0xDCAF, 0x9F08}, //13867 #CJK UNIFIED IDEOGRAPH + {0xDCB0, 0x4E19}, //13868 #CJK UNIFIED IDEOGRAPH + {0xDCB1, 0x5002}, //13869 #CJK UNIFIED IDEOGRAPH + {0xDCB2, 0x5175}, //13870 #CJK UNIFIED IDEOGRAPH + {0xDCB3, 0x5C5B}, //13871 #CJK UNIFIED IDEOGRAPH + {0xDCB4, 0x5E77}, //13872 #CJK UNIFIED IDEOGRAPH + {0xDCB5, 0x661E}, //13873 #CJK UNIFIED IDEOGRAPH + {0xDCB6, 0x663A}, //13874 #CJK UNIFIED IDEOGRAPH + {0xDCB7, 0x67C4}, //13875 #CJK UNIFIED IDEOGRAPH + {0xDCB8, 0x68C5}, //13876 #CJK UNIFIED IDEOGRAPH + {0xDCB9, 0x70B3}, //13877 #CJK UNIFIED IDEOGRAPH + {0xDCBA, 0x7501}, //13878 #CJK UNIFIED IDEOGRAPH + {0xDCBB, 0x75C5}, //13879 #CJK UNIFIED IDEOGRAPH + {0xDCBC, 0x79C9}, //13880 #CJK UNIFIED IDEOGRAPH + {0xDCBD, 0x7ADD}, //13881 #CJK UNIFIED IDEOGRAPH + {0xDCBE, 0x8F27}, //13882 #CJK UNIFIED IDEOGRAPH + {0xDCBF, 0x9920}, //13883 #CJK UNIFIED IDEOGRAPH + {0xDCC0, 0x9A08}, //13884 #CJK UNIFIED IDEOGRAPH + {0xDCC1, 0x4FDD}, //13885 #CJK UNIFIED IDEOGRAPH + {0xDCC2, 0x5821}, //13886 #CJK UNIFIED IDEOGRAPH + {0xDCC3, 0x5831}, //13887 #CJK UNIFIED IDEOGRAPH + {0xDCC4, 0x5BF6}, //13888 #CJK UNIFIED IDEOGRAPH + {0xDCC5, 0x666E}, //13889 #CJK UNIFIED IDEOGRAPH + {0xDCC6, 0x6B65}, //13890 #CJK UNIFIED IDEOGRAPH + {0xDCC7, 0x6D11}, //13891 #CJK UNIFIED IDEOGRAPH + {0xDCC8, 0x6E7A}, //13892 #CJK UNIFIED IDEOGRAPH + {0xDCC9, 0x6F7D}, //13893 #CJK UNIFIED IDEOGRAPH + {0xDCCA, 0x73E4}, //13894 #CJK UNIFIED IDEOGRAPH + {0xDCCB, 0x752B}, //13895 #CJK UNIFIED IDEOGRAPH + {0xDCCC, 0x83E9}, //13896 #CJK UNIFIED IDEOGRAPH + {0xDCCD, 0x88DC}, //13897 #CJK UNIFIED IDEOGRAPH + {0xDCCE, 0x8913}, //13898 #CJK UNIFIED IDEOGRAPH + {0xDCCF, 0x8B5C}, //13899 #CJK UNIFIED IDEOGRAPH + {0xDCD0, 0x8F14}, //13900 #CJK UNIFIED IDEOGRAPH + {0xDCD1, 0x4F0F}, //13901 #CJK UNIFIED IDEOGRAPH + {0xDCD2, 0x50D5}, //13902 #CJK UNIFIED IDEOGRAPH + {0xDCD3, 0x5310}, //13903 #CJK UNIFIED IDEOGRAPH + {0xDCD4, 0x535C}, //13904 #CJK UNIFIED IDEOGRAPH + {0xDCD5, 0x5B93}, //13905 #CJK UNIFIED IDEOGRAPH + {0xDCD6, 0x5FA9}, //13906 #CJK UNIFIED IDEOGRAPH + {0xDCD7, 0x670D}, //13907 #CJK UNIFIED IDEOGRAPH + {0xDCD8, 0x798F}, //13908 #CJK UNIFIED IDEOGRAPH + {0xDCD9, 0x8179}, //13909 #CJK UNIFIED IDEOGRAPH + {0xDCDA, 0x832F}, //13910 #CJK UNIFIED IDEOGRAPH + {0xDCDB, 0x8514}, //13911 #CJK UNIFIED IDEOGRAPH + {0xDCDC, 0x8907}, //13912 #CJK UNIFIED IDEOGRAPH + {0xDCDD, 0x8986}, //13913 #CJK UNIFIED IDEOGRAPH + {0xDCDE, 0x8F39}, //13914 #CJK UNIFIED IDEOGRAPH + {0xDCDF, 0x8F3B}, //13915 #CJK UNIFIED IDEOGRAPH + {0xDCE0, 0x99A5}, //13916 #CJK UNIFIED IDEOGRAPH + {0xDCE1, 0x9C12}, //13917 #CJK UNIFIED IDEOGRAPH + {0xDCE2, 0x672C}, //13918 #CJK UNIFIED IDEOGRAPH + {0xDCE3, 0x4E76}, //13919 #CJK UNIFIED IDEOGRAPH + {0xDCE4, 0x4FF8}, //13920 #CJK UNIFIED IDEOGRAPH + {0xDCE5, 0x5949}, //13921 #CJK UNIFIED IDEOGRAPH + {0xDCE6, 0x5C01}, //13922 #CJK UNIFIED IDEOGRAPH + {0xDCE7, 0x5CEF}, //13923 #CJK UNIFIED IDEOGRAPH + {0xDCE8, 0x5CF0}, //13924 #CJK UNIFIED IDEOGRAPH + {0xDCE9, 0x6367}, //13925 #CJK UNIFIED IDEOGRAPH + {0xDCEA, 0x68D2}, //13926 #CJK UNIFIED IDEOGRAPH + {0xDCEB, 0x70FD}, //13927 #CJK UNIFIED IDEOGRAPH + {0xDCEC, 0x71A2}, //13928 #CJK UNIFIED IDEOGRAPH + {0xDCED, 0x742B}, //13929 #CJK UNIFIED IDEOGRAPH + {0xDCEE, 0x7E2B}, //13930 #CJK UNIFIED IDEOGRAPH + {0xDCEF, 0x84EC}, //13931 #CJK UNIFIED IDEOGRAPH + {0xDCF0, 0x8702}, //13932 #CJK UNIFIED IDEOGRAPH + {0xDCF1, 0x9022}, //13933 #CJK UNIFIED IDEOGRAPH + {0xDCF2, 0x92D2}, //13934 #CJK UNIFIED IDEOGRAPH + {0xDCF3, 0x9CF3}, //13935 #CJK UNIFIED IDEOGRAPH + {0xDCF4, 0x4E0D}, //13936 #CJK UNIFIED IDEOGRAPH + {0xDCF5, 0x4ED8}, //13937 #CJK UNIFIED IDEOGRAPH + {0xDCF6, 0x4FEF}, //13938 #CJK UNIFIED IDEOGRAPH + {0xDCF7, 0x5085}, //13939 #CJK UNIFIED IDEOGRAPH + {0xDCF8, 0x5256}, //13940 #CJK UNIFIED IDEOGRAPH + {0xDCF9, 0x526F}, //13941 #CJK UNIFIED IDEOGRAPH + {0xDCFA, 0x5426}, //13942 #CJK UNIFIED IDEOGRAPH + {0xDCFB, 0x5490}, //13943 #CJK UNIFIED IDEOGRAPH + {0xDCFC, 0x57E0}, //13944 #CJK UNIFIED IDEOGRAPH + {0xDCFD, 0x592B}, //13945 #CJK UNIFIED IDEOGRAPH + {0xDCFE, 0x5A66}, //13946 #CJK UNIFIED IDEOGRAPH + {0xDDA1, 0x5B5A}, //13947 #CJK UNIFIED IDEOGRAPH + {0xDDA2, 0x5B75}, //13948 #CJK UNIFIED IDEOGRAPH + {0xDDA3, 0x5BCC}, //13949 #CJK UNIFIED IDEOGRAPH + {0xDDA4, 0x5E9C}, //13950 #CJK UNIFIED IDEOGRAPH + {0xDDA5, 0xF966}, //13951 #CJK COMPATIBILITY IDEOGRAPH + {0xDDA6, 0x6276}, //13952 #CJK UNIFIED IDEOGRAPH + {0xDDA7, 0x6577}, //13953 #CJK UNIFIED IDEOGRAPH + {0xDDA8, 0x65A7}, //13954 #CJK UNIFIED IDEOGRAPH + {0xDDA9, 0x6D6E}, //13955 #CJK UNIFIED IDEOGRAPH + {0xDDAA, 0x6EA5}, //13956 #CJK UNIFIED IDEOGRAPH + {0xDDAB, 0x7236}, //13957 #CJK UNIFIED IDEOGRAPH + {0xDDAC, 0x7B26}, //13958 #CJK UNIFIED IDEOGRAPH + {0xDDAD, 0x7C3F}, //13959 #CJK UNIFIED IDEOGRAPH + {0xDDAE, 0x7F36}, //13960 #CJK UNIFIED IDEOGRAPH + {0xDDAF, 0x8150}, //13961 #CJK UNIFIED IDEOGRAPH + {0xDDB0, 0x8151}, //13962 #CJK UNIFIED IDEOGRAPH + {0xDDB1, 0x819A}, //13963 #CJK UNIFIED IDEOGRAPH + {0xDDB2, 0x8240}, //13964 #CJK UNIFIED IDEOGRAPH + {0xDDB3, 0x8299}, //13965 #CJK UNIFIED IDEOGRAPH + {0xDDB4, 0x83A9}, //13966 #CJK UNIFIED IDEOGRAPH + {0xDDB5, 0x8A03}, //13967 #CJK UNIFIED IDEOGRAPH + {0xDDB6, 0x8CA0}, //13968 #CJK UNIFIED IDEOGRAPH + {0xDDB7, 0x8CE6}, //13969 #CJK UNIFIED IDEOGRAPH + {0xDDB8, 0x8CFB}, //13970 #CJK UNIFIED IDEOGRAPH + {0xDDB9, 0x8D74}, //13971 #CJK UNIFIED IDEOGRAPH + {0xDDBA, 0x8DBA}, //13972 #CJK UNIFIED IDEOGRAPH + {0xDDBB, 0x90E8}, //13973 #CJK UNIFIED IDEOGRAPH + {0xDDBC, 0x91DC}, //13974 #CJK UNIFIED IDEOGRAPH + {0xDDBD, 0x961C}, //13975 #CJK UNIFIED IDEOGRAPH + {0xDDBE, 0x9644}, //13976 #CJK UNIFIED IDEOGRAPH + {0xDDBF, 0x99D9}, //13977 #CJK UNIFIED IDEOGRAPH + {0xDDC0, 0x9CE7}, //13978 #CJK UNIFIED IDEOGRAPH + {0xDDC1, 0x5317}, //13979 #CJK UNIFIED IDEOGRAPH + {0xDDC2, 0x5206}, //13980 #CJK UNIFIED IDEOGRAPH + {0xDDC3, 0x5429}, //13981 #CJK UNIFIED IDEOGRAPH + {0xDDC4, 0x5674}, //13982 #CJK UNIFIED IDEOGRAPH + {0xDDC5, 0x58B3}, //13983 #CJK UNIFIED IDEOGRAPH + {0xDDC6, 0x5954}, //13984 #CJK UNIFIED IDEOGRAPH + {0xDDC7, 0x596E}, //13985 #CJK UNIFIED IDEOGRAPH + {0xDDC8, 0x5FFF}, //13986 #CJK UNIFIED IDEOGRAPH + {0xDDC9, 0x61A4}, //13987 #CJK UNIFIED IDEOGRAPH + {0xDDCA, 0x626E}, //13988 #CJK UNIFIED IDEOGRAPH + {0xDDCB, 0x6610}, //13989 #CJK UNIFIED IDEOGRAPH + {0xDDCC, 0x6C7E}, //13990 #CJK UNIFIED IDEOGRAPH + {0xDDCD, 0x711A}, //13991 #CJK UNIFIED IDEOGRAPH + {0xDDCE, 0x76C6}, //13992 #CJK UNIFIED IDEOGRAPH + {0xDDCF, 0x7C89}, //13993 #CJK UNIFIED IDEOGRAPH + {0xDDD0, 0x7CDE}, //13994 #CJK UNIFIED IDEOGRAPH + {0xDDD1, 0x7D1B}, //13995 #CJK UNIFIED IDEOGRAPH + {0xDDD2, 0x82AC}, //13996 #CJK UNIFIED IDEOGRAPH + {0xDDD3, 0x8CC1}, //13997 #CJK UNIFIED IDEOGRAPH + {0xDDD4, 0x96F0}, //13998 #CJK UNIFIED IDEOGRAPH + {0xDDD5, 0xF967}, //13999 #CJK COMPATIBILITY IDEOGRAPH + {0xDDD6, 0x4F5B}, //14000 #CJK UNIFIED IDEOGRAPH + {0xDDD7, 0x5F17}, //14001 #CJK UNIFIED IDEOGRAPH + {0xDDD8, 0x5F7F}, //14002 #CJK UNIFIED IDEOGRAPH + {0xDDD9, 0x62C2}, //14003 #CJK UNIFIED IDEOGRAPH + {0xDDDA, 0x5D29}, //14004 #CJK UNIFIED IDEOGRAPH + {0xDDDB, 0x670B}, //14005 #CJK UNIFIED IDEOGRAPH + {0xDDDC, 0x68DA}, //14006 #CJK UNIFIED IDEOGRAPH + {0xDDDD, 0x787C}, //14007 #CJK UNIFIED IDEOGRAPH + {0xDDDE, 0x7E43}, //14008 #CJK UNIFIED IDEOGRAPH + {0xDDDF, 0x9D6C}, //14009 #CJK UNIFIED IDEOGRAPH + {0xDDE0, 0x4E15}, //14010 #CJK UNIFIED IDEOGRAPH + {0xDDE1, 0x5099}, //14011 #CJK UNIFIED IDEOGRAPH + {0xDDE2, 0x5315}, //14012 #CJK UNIFIED IDEOGRAPH + {0xDDE3, 0x532A}, //14013 #CJK UNIFIED IDEOGRAPH + {0xDDE4, 0x5351}, //14014 #CJK UNIFIED IDEOGRAPH + {0xDDE5, 0x5983}, //14015 #CJK UNIFIED IDEOGRAPH + {0xDDE6, 0x5A62}, //14016 #CJK UNIFIED IDEOGRAPH + {0xDDE7, 0x5E87}, //14017 #CJK UNIFIED IDEOGRAPH + {0xDDE8, 0x60B2}, //14018 #CJK UNIFIED IDEOGRAPH + {0xDDE9, 0x618A}, //14019 #CJK UNIFIED IDEOGRAPH + {0xDDEA, 0x6249}, //14020 #CJK UNIFIED IDEOGRAPH + {0xDDEB, 0x6279}, //14021 #CJK UNIFIED IDEOGRAPH + {0xDDEC, 0x6590}, //14022 #CJK UNIFIED IDEOGRAPH + {0xDDED, 0x6787}, //14023 #CJK UNIFIED IDEOGRAPH + {0xDDEE, 0x69A7}, //14024 #CJK UNIFIED IDEOGRAPH + {0xDDEF, 0x6BD4}, //14025 #CJK UNIFIED IDEOGRAPH + {0xDDF0, 0x6BD6}, //14026 #CJK UNIFIED IDEOGRAPH + {0xDDF1, 0x6BD7}, //14027 #CJK UNIFIED IDEOGRAPH + {0xDDF2, 0x6BD8}, //14028 #CJK UNIFIED IDEOGRAPH + {0xDDF3, 0x6CB8}, //14029 #CJK UNIFIED IDEOGRAPH + {0xDDF4, 0xF968}, //14030 #CJK COMPATIBILITY IDEOGRAPH + {0xDDF5, 0x7435}, //14031 #CJK UNIFIED IDEOGRAPH + {0xDDF6, 0x75FA}, //14032 #CJK UNIFIED IDEOGRAPH + {0xDDF7, 0x7812}, //14033 #CJK UNIFIED IDEOGRAPH + {0xDDF8, 0x7891}, //14034 #CJK UNIFIED IDEOGRAPH + {0xDDF9, 0x79D5}, //14035 #CJK UNIFIED IDEOGRAPH + {0xDDFA, 0x79D8}, //14036 #CJK UNIFIED IDEOGRAPH + {0xDDFB, 0x7C83}, //14037 #CJK UNIFIED IDEOGRAPH + {0xDDFC, 0x7DCB}, //14038 #CJK UNIFIED IDEOGRAPH + {0xDDFD, 0x7FE1}, //14039 #CJK UNIFIED IDEOGRAPH + {0xDDFE, 0x80A5}, //14040 #CJK UNIFIED IDEOGRAPH + {0xDEA1, 0x813E}, //14041 #CJK UNIFIED IDEOGRAPH + {0xDEA2, 0x81C2}, //14042 #CJK UNIFIED IDEOGRAPH + {0xDEA3, 0x83F2}, //14043 #CJK UNIFIED IDEOGRAPH + {0xDEA4, 0x871A}, //14044 #CJK UNIFIED IDEOGRAPH + {0xDEA5, 0x88E8}, //14045 #CJK UNIFIED IDEOGRAPH + {0xDEA6, 0x8AB9}, //14046 #CJK UNIFIED IDEOGRAPH + {0xDEA7, 0x8B6C}, //14047 #CJK UNIFIED IDEOGRAPH + {0xDEA8, 0x8CBB}, //14048 #CJK UNIFIED IDEOGRAPH + {0xDEA9, 0x9119}, //14049 #CJK UNIFIED IDEOGRAPH + {0xDEAA, 0x975E}, //14050 #CJK UNIFIED IDEOGRAPH + {0xDEAB, 0x98DB}, //14051 #CJK UNIFIED IDEOGRAPH + {0xDEAC, 0x9F3B}, //14052 #CJK UNIFIED IDEOGRAPH + {0xDEAD, 0x56AC}, //14053 #CJK UNIFIED IDEOGRAPH + {0xDEAE, 0x5B2A}, //14054 #CJK UNIFIED IDEOGRAPH + {0xDEAF, 0x5F6C}, //14055 #CJK UNIFIED IDEOGRAPH + {0xDEB0, 0x658C}, //14056 #CJK UNIFIED IDEOGRAPH + {0xDEB1, 0x6AB3}, //14057 #CJK UNIFIED IDEOGRAPH + {0xDEB2, 0x6BAF}, //14058 #CJK UNIFIED IDEOGRAPH + {0xDEB3, 0x6D5C}, //14059 #CJK UNIFIED IDEOGRAPH + {0xDEB4, 0x6FF1}, //14060 #CJK UNIFIED IDEOGRAPH + {0xDEB5, 0x7015}, //14061 #CJK UNIFIED IDEOGRAPH + {0xDEB6, 0x725D}, //14062 #CJK UNIFIED IDEOGRAPH + {0xDEB7, 0x73AD}, //14063 #CJK UNIFIED IDEOGRAPH + {0xDEB8, 0x8CA7}, //14064 #CJK UNIFIED IDEOGRAPH + {0xDEB9, 0x8CD3}, //14065 #CJK UNIFIED IDEOGRAPH + {0xDEBA, 0x983B}, //14066 #CJK UNIFIED IDEOGRAPH + {0xDEBB, 0x6191}, //14067 #CJK UNIFIED IDEOGRAPH + {0xDEBC, 0x6C37}, //14068 #CJK UNIFIED IDEOGRAPH + {0xDEBD, 0x8058}, //14069 #CJK UNIFIED IDEOGRAPH + {0xDEBE, 0x9A01}, //14070 #CJK UNIFIED IDEOGRAPH + {0xDEBF, 0x4E4D}, //14071 #CJK UNIFIED IDEOGRAPH + {0xDEC0, 0x4E8B}, //14072 #CJK UNIFIED IDEOGRAPH + {0xDEC1, 0x4E9B}, //14073 #CJK UNIFIED IDEOGRAPH + {0xDEC2, 0x4ED5}, //14074 #CJK UNIFIED IDEOGRAPH + {0xDEC3, 0x4F3A}, //14075 #CJK UNIFIED IDEOGRAPH + {0xDEC4, 0x4F3C}, //14076 #CJK UNIFIED IDEOGRAPH + {0xDEC5, 0x4F7F}, //14077 #CJK UNIFIED IDEOGRAPH + {0xDEC6, 0x4FDF}, //14078 #CJK UNIFIED IDEOGRAPH + {0xDEC7, 0x50FF}, //14079 #CJK UNIFIED IDEOGRAPH + {0xDEC8, 0x53F2}, //14080 #CJK UNIFIED IDEOGRAPH + {0xDEC9, 0x53F8}, //14081 #CJK UNIFIED IDEOGRAPH + {0xDECA, 0x5506}, //14082 #CJK UNIFIED IDEOGRAPH + {0xDECB, 0x55E3}, //14083 #CJK UNIFIED IDEOGRAPH + {0xDECC, 0x56DB}, //14084 #CJK UNIFIED IDEOGRAPH + {0xDECD, 0x58EB}, //14085 #CJK UNIFIED IDEOGRAPH + {0xDECE, 0x5962}, //14086 #CJK UNIFIED IDEOGRAPH + {0xDECF, 0x5A11}, //14087 #CJK UNIFIED IDEOGRAPH + {0xDED0, 0x5BEB}, //14088 #CJK UNIFIED IDEOGRAPH + {0xDED1, 0x5BFA}, //14089 #CJK UNIFIED IDEOGRAPH + {0xDED2, 0x5C04}, //14090 #CJK UNIFIED IDEOGRAPH + {0xDED3, 0x5DF3}, //14091 #CJK UNIFIED IDEOGRAPH + {0xDED4, 0x5E2B}, //14092 #CJK UNIFIED IDEOGRAPH + {0xDED5, 0x5F99}, //14093 #CJK UNIFIED IDEOGRAPH + {0xDED6, 0x601D}, //14094 #CJK UNIFIED IDEOGRAPH + {0xDED7, 0x6368}, //14095 #CJK UNIFIED IDEOGRAPH + {0xDED8, 0x659C}, //14096 #CJK UNIFIED IDEOGRAPH + {0xDED9, 0x65AF}, //14097 #CJK UNIFIED IDEOGRAPH + {0xDEDA, 0x67F6}, //14098 #CJK UNIFIED IDEOGRAPH + {0xDEDB, 0x67FB}, //14099 #CJK UNIFIED IDEOGRAPH + {0xDEDC, 0x68AD}, //14100 #CJK UNIFIED IDEOGRAPH + {0xDEDD, 0x6B7B}, //14101 #CJK UNIFIED IDEOGRAPH + {0xDEDE, 0x6C99}, //14102 #CJK UNIFIED IDEOGRAPH + {0xDEDF, 0x6CD7}, //14103 #CJK UNIFIED IDEOGRAPH + {0xDEE0, 0x6E23}, //14104 #CJK UNIFIED IDEOGRAPH + {0xDEE1, 0x7009}, //14105 #CJK UNIFIED IDEOGRAPH + {0xDEE2, 0x7345}, //14106 #CJK UNIFIED IDEOGRAPH + {0xDEE3, 0x7802}, //14107 #CJK UNIFIED IDEOGRAPH + {0xDEE4, 0x793E}, //14108 #CJK UNIFIED IDEOGRAPH + {0xDEE5, 0x7940}, //14109 #CJK UNIFIED IDEOGRAPH + {0xDEE6, 0x7960}, //14110 #CJK UNIFIED IDEOGRAPH + {0xDEE7, 0x79C1}, //14111 #CJK UNIFIED IDEOGRAPH + {0xDEE8, 0x7BE9}, //14112 #CJK UNIFIED IDEOGRAPH + {0xDEE9, 0x7D17}, //14113 #CJK UNIFIED IDEOGRAPH + {0xDEEA, 0x7D72}, //14114 #CJK UNIFIED IDEOGRAPH + {0xDEEB, 0x8086}, //14115 #CJK UNIFIED IDEOGRAPH + {0xDEEC, 0x820D}, //14116 #CJK UNIFIED IDEOGRAPH + {0xDEED, 0x838E}, //14117 #CJK UNIFIED IDEOGRAPH + {0xDEEE, 0x84D1}, //14118 #CJK UNIFIED IDEOGRAPH + {0xDEEF, 0x86C7}, //14119 #CJK UNIFIED IDEOGRAPH + {0xDEF0, 0x88DF}, //14120 #CJK UNIFIED IDEOGRAPH + {0xDEF1, 0x8A50}, //14121 #CJK UNIFIED IDEOGRAPH + {0xDEF2, 0x8A5E}, //14122 #CJK UNIFIED IDEOGRAPH + {0xDEF3, 0x8B1D}, //14123 #CJK UNIFIED IDEOGRAPH + {0xDEF4, 0x8CDC}, //14124 #CJK UNIFIED IDEOGRAPH + {0xDEF5, 0x8D66}, //14125 #CJK UNIFIED IDEOGRAPH + {0xDEF6, 0x8FAD}, //14126 #CJK UNIFIED IDEOGRAPH + {0xDEF7, 0x90AA}, //14127 #CJK UNIFIED IDEOGRAPH + {0xDEF8, 0x98FC}, //14128 #CJK UNIFIED IDEOGRAPH + {0xDEF9, 0x99DF}, //14129 #CJK UNIFIED IDEOGRAPH + {0xDEFA, 0x9E9D}, //14130 #CJK UNIFIED IDEOGRAPH + {0xDEFB, 0x524A}, //14131 #CJK UNIFIED IDEOGRAPH + {0xDEFC, 0xF969}, //14132 #CJK COMPATIBILITY IDEOGRAPH + {0xDEFD, 0x6714}, //14133 #CJK UNIFIED IDEOGRAPH + {0xDEFE, 0xF96A}, //14134 #CJK COMPATIBILITY IDEOGRAPH + {0xDFA1, 0x5098}, //14135 #CJK UNIFIED IDEOGRAPH + {0xDFA2, 0x522A}, //14136 #CJK UNIFIED IDEOGRAPH + {0xDFA3, 0x5C71}, //14137 #CJK UNIFIED IDEOGRAPH + {0xDFA4, 0x6563}, //14138 #CJK UNIFIED IDEOGRAPH + {0xDFA5, 0x6C55}, //14139 #CJK UNIFIED IDEOGRAPH + {0xDFA6, 0x73CA}, //14140 #CJK UNIFIED IDEOGRAPH + {0xDFA7, 0x7523}, //14141 #CJK UNIFIED IDEOGRAPH + {0xDFA8, 0x759D}, //14142 #CJK UNIFIED IDEOGRAPH + {0xDFA9, 0x7B97}, //14143 #CJK UNIFIED IDEOGRAPH + {0xDFAA, 0x849C}, //14144 #CJK UNIFIED IDEOGRAPH + {0xDFAB, 0x9178}, //14145 #CJK UNIFIED IDEOGRAPH + {0xDFAC, 0x9730}, //14146 #CJK UNIFIED IDEOGRAPH + {0xDFAD, 0x4E77}, //14147 #CJK UNIFIED IDEOGRAPH + {0xDFAE, 0x6492}, //14148 #CJK UNIFIED IDEOGRAPH + {0xDFAF, 0x6BBA}, //14149 #CJK UNIFIED IDEOGRAPH + {0xDFB0, 0x715E}, //14150 #CJK UNIFIED IDEOGRAPH + {0xDFB1, 0x85A9}, //14151 #CJK UNIFIED IDEOGRAPH + {0xDFB2, 0x4E09}, //14152 #CJK UNIFIED IDEOGRAPH + {0xDFB3, 0xF96B}, //14153 #CJK COMPATIBILITY IDEOGRAPH + {0xDFB4, 0x6749}, //14154 #CJK UNIFIED IDEOGRAPH + {0xDFB5, 0x68EE}, //14155 #CJK UNIFIED IDEOGRAPH + {0xDFB6, 0x6E17}, //14156 #CJK UNIFIED IDEOGRAPH + {0xDFB7, 0x829F}, //14157 #CJK UNIFIED IDEOGRAPH + {0xDFB8, 0x8518}, //14158 #CJK UNIFIED IDEOGRAPH + {0xDFB9, 0x886B}, //14159 #CJK UNIFIED IDEOGRAPH + {0xDFBA, 0x63F7}, //14160 #CJK UNIFIED IDEOGRAPH + {0xDFBB, 0x6F81}, //14161 #CJK UNIFIED IDEOGRAPH + {0xDFBC, 0x9212}, //14162 #CJK UNIFIED IDEOGRAPH + {0xDFBD, 0x98AF}, //14163 #CJK UNIFIED IDEOGRAPH + {0xDFBE, 0x4E0A}, //14164 #CJK UNIFIED IDEOGRAPH + {0xDFBF, 0x50B7}, //14165 #CJK UNIFIED IDEOGRAPH + {0xDFC0, 0x50CF}, //14166 #CJK UNIFIED IDEOGRAPH + {0xDFC1, 0x511F}, //14167 #CJK UNIFIED IDEOGRAPH + {0xDFC2, 0x5546}, //14168 #CJK UNIFIED IDEOGRAPH + {0xDFC3, 0x55AA}, //14169 #CJK UNIFIED IDEOGRAPH + {0xDFC4, 0x5617}, //14170 #CJK UNIFIED IDEOGRAPH + {0xDFC5, 0x5B40}, //14171 #CJK UNIFIED IDEOGRAPH + {0xDFC6, 0x5C19}, //14172 #CJK UNIFIED IDEOGRAPH + {0xDFC7, 0x5CE0}, //14173 #CJK UNIFIED IDEOGRAPH + {0xDFC8, 0x5E38}, //14174 #CJK UNIFIED IDEOGRAPH + {0xDFC9, 0x5E8A}, //14175 #CJK UNIFIED IDEOGRAPH + {0xDFCA, 0x5EA0}, //14176 #CJK UNIFIED IDEOGRAPH + {0xDFCB, 0x5EC2}, //14177 #CJK UNIFIED IDEOGRAPH + {0xDFCC, 0x60F3}, //14178 #CJK UNIFIED IDEOGRAPH + {0xDFCD, 0x6851}, //14179 #CJK UNIFIED IDEOGRAPH + {0xDFCE, 0x6A61}, //14180 #CJK UNIFIED IDEOGRAPH + {0xDFCF, 0x6E58}, //14181 #CJK UNIFIED IDEOGRAPH + {0xDFD0, 0x723D}, //14182 #CJK UNIFIED IDEOGRAPH + {0xDFD1, 0x7240}, //14183 #CJK UNIFIED IDEOGRAPH + {0xDFD2, 0x72C0}, //14184 #CJK UNIFIED IDEOGRAPH + {0xDFD3, 0x76F8}, //14185 #CJK UNIFIED IDEOGRAPH + {0xDFD4, 0x7965}, //14186 #CJK UNIFIED IDEOGRAPH + {0xDFD5, 0x7BB1}, //14187 #CJK UNIFIED IDEOGRAPH + {0xDFD6, 0x7FD4}, //14188 #CJK UNIFIED IDEOGRAPH + {0xDFD7, 0x88F3}, //14189 #CJK UNIFIED IDEOGRAPH + {0xDFD8, 0x89F4}, //14190 #CJK UNIFIED IDEOGRAPH + {0xDFD9, 0x8A73}, //14191 #CJK UNIFIED IDEOGRAPH + {0xDFDA, 0x8C61}, //14192 #CJK UNIFIED IDEOGRAPH + {0xDFDB, 0x8CDE}, //14193 #CJK UNIFIED IDEOGRAPH + {0xDFDC, 0x971C}, //14194 #CJK UNIFIED IDEOGRAPH + {0xDFDD, 0x585E}, //14195 #CJK UNIFIED IDEOGRAPH + {0xDFDE, 0x74BD}, //14196 #CJK UNIFIED IDEOGRAPH + {0xDFDF, 0x8CFD}, //14197 #CJK UNIFIED IDEOGRAPH + {0xDFE0, 0x55C7}, //14198 #CJK UNIFIED IDEOGRAPH + {0xDFE1, 0xF96C}, //14199 #CJK COMPATIBILITY IDEOGRAPH + {0xDFE2, 0x7A61}, //14200 #CJK UNIFIED IDEOGRAPH + {0xDFE3, 0x7D22}, //14201 #CJK UNIFIED IDEOGRAPH + {0xDFE4, 0x8272}, //14202 #CJK UNIFIED IDEOGRAPH + {0xDFE5, 0x7272}, //14203 #CJK UNIFIED IDEOGRAPH + {0xDFE6, 0x751F}, //14204 #CJK UNIFIED IDEOGRAPH + {0xDFE7, 0x7525}, //14205 #CJK UNIFIED IDEOGRAPH + {0xDFE8, 0xF96D}, //14206 #CJK COMPATIBILITY IDEOGRAPH + {0xDFE9, 0x7B19}, //14207 #CJK UNIFIED IDEOGRAPH + {0xDFEA, 0x5885}, //14208 #CJK UNIFIED IDEOGRAPH + {0xDFEB, 0x58FB}, //14209 #CJK UNIFIED IDEOGRAPH + {0xDFEC, 0x5DBC}, //14210 #CJK UNIFIED IDEOGRAPH + {0xDFED, 0x5E8F}, //14211 #CJK UNIFIED IDEOGRAPH + {0xDFEE, 0x5EB6}, //14212 #CJK UNIFIED IDEOGRAPH + {0xDFEF, 0x5F90}, //14213 #CJK UNIFIED IDEOGRAPH + {0xDFF0, 0x6055}, //14214 #CJK UNIFIED IDEOGRAPH + {0xDFF1, 0x6292}, //14215 #CJK UNIFIED IDEOGRAPH + {0xDFF2, 0x637F}, //14216 #CJK UNIFIED IDEOGRAPH + {0xDFF3, 0x654D}, //14217 #CJK UNIFIED IDEOGRAPH + {0xDFF4, 0x6691}, //14218 #CJK UNIFIED IDEOGRAPH + {0xDFF5, 0x66D9}, //14219 #CJK UNIFIED IDEOGRAPH + {0xDFF6, 0x66F8}, //14220 #CJK UNIFIED IDEOGRAPH + {0xDFF7, 0x6816}, //14221 #CJK UNIFIED IDEOGRAPH + {0xDFF8, 0x68F2}, //14222 #CJK UNIFIED IDEOGRAPH + {0xDFF9, 0x7280}, //14223 #CJK UNIFIED IDEOGRAPH + {0xDFFA, 0x745E}, //14224 #CJK UNIFIED IDEOGRAPH + {0xDFFB, 0x7B6E}, //14225 #CJK UNIFIED IDEOGRAPH + {0xDFFC, 0x7D6E}, //14226 #CJK UNIFIED IDEOGRAPH + {0xDFFD, 0x7DD6}, //14227 #CJK UNIFIED IDEOGRAPH + {0xDFFE, 0x7F72}, //14228 #CJK UNIFIED IDEOGRAPH + {0xE0A1, 0x80E5}, //14229 #CJK UNIFIED IDEOGRAPH + {0xE0A2, 0x8212}, //14230 #CJK UNIFIED IDEOGRAPH + {0xE0A3, 0x85AF}, //14231 #CJK UNIFIED IDEOGRAPH + {0xE0A4, 0x897F}, //14232 #CJK UNIFIED IDEOGRAPH + {0xE0A5, 0x8A93}, //14233 #CJK UNIFIED IDEOGRAPH + {0xE0A6, 0x901D}, //14234 #CJK UNIFIED IDEOGRAPH + {0xE0A7, 0x92E4}, //14235 #CJK UNIFIED IDEOGRAPH + {0xE0A8, 0x9ECD}, //14236 #CJK UNIFIED IDEOGRAPH + {0xE0A9, 0x9F20}, //14237 #CJK UNIFIED IDEOGRAPH + {0xE0AA, 0x5915}, //14238 #CJK UNIFIED IDEOGRAPH + {0xE0AB, 0x596D}, //14239 #CJK UNIFIED IDEOGRAPH + {0xE0AC, 0x5E2D}, //14240 #CJK UNIFIED IDEOGRAPH + {0xE0AD, 0x60DC}, //14241 #CJK UNIFIED IDEOGRAPH + {0xE0AE, 0x6614}, //14242 #CJK UNIFIED IDEOGRAPH + {0xE0AF, 0x6673}, //14243 #CJK UNIFIED IDEOGRAPH + {0xE0B0, 0x6790}, //14244 #CJK UNIFIED IDEOGRAPH + {0xE0B1, 0x6C50}, //14245 #CJK UNIFIED IDEOGRAPH + {0xE0B2, 0x6DC5}, //14246 #CJK UNIFIED IDEOGRAPH + {0xE0B3, 0x6F5F}, //14247 #CJK UNIFIED IDEOGRAPH + {0xE0B4, 0x77F3}, //14248 #CJK UNIFIED IDEOGRAPH + {0xE0B5, 0x78A9}, //14249 #CJK UNIFIED IDEOGRAPH + {0xE0B6, 0x84C6}, //14250 #CJK UNIFIED IDEOGRAPH + {0xE0B7, 0x91CB}, //14251 #CJK UNIFIED IDEOGRAPH + {0xE0B8, 0x932B}, //14252 #CJK UNIFIED IDEOGRAPH + {0xE0B9, 0x4ED9}, //14253 #CJK UNIFIED IDEOGRAPH + {0xE0BA, 0x50CA}, //14254 #CJK UNIFIED IDEOGRAPH + {0xE0BB, 0x5148}, //14255 #CJK UNIFIED IDEOGRAPH + {0xE0BC, 0x5584}, //14256 #CJK UNIFIED IDEOGRAPH + {0xE0BD, 0x5B0B}, //14257 #CJK UNIFIED IDEOGRAPH + {0xE0BE, 0x5BA3}, //14258 #CJK UNIFIED IDEOGRAPH + {0xE0BF, 0x6247}, //14259 #CJK UNIFIED IDEOGRAPH + {0xE0C0, 0x657E}, //14260 #CJK UNIFIED IDEOGRAPH + {0xE0C1, 0x65CB}, //14261 #CJK UNIFIED IDEOGRAPH + {0xE0C2, 0x6E32}, //14262 #CJK UNIFIED IDEOGRAPH + {0xE0C3, 0x717D}, //14263 #CJK UNIFIED IDEOGRAPH + {0xE0C4, 0x7401}, //14264 #CJK UNIFIED IDEOGRAPH + {0xE0C5, 0x7444}, //14265 #CJK UNIFIED IDEOGRAPH + {0xE0C6, 0x7487}, //14266 #CJK UNIFIED IDEOGRAPH + {0xE0C7, 0x74BF}, //14267 #CJK UNIFIED IDEOGRAPH + {0xE0C8, 0x766C}, //14268 #CJK UNIFIED IDEOGRAPH + {0xE0C9, 0x79AA}, //14269 #CJK UNIFIED IDEOGRAPH + {0xE0CA, 0x7DDA}, //14270 #CJK UNIFIED IDEOGRAPH + {0xE0CB, 0x7E55}, //14271 #CJK UNIFIED IDEOGRAPH + {0xE0CC, 0x7FA8}, //14272 #CJK UNIFIED IDEOGRAPH + {0xE0CD, 0x817A}, //14273 #CJK UNIFIED IDEOGRAPH + {0xE0CE, 0x81B3}, //14274 #CJK UNIFIED IDEOGRAPH + {0xE0CF, 0x8239}, //14275 #CJK UNIFIED IDEOGRAPH + {0xE0D0, 0x861A}, //14276 #CJK UNIFIED IDEOGRAPH + {0xE0D1, 0x87EC}, //14277 #CJK UNIFIED IDEOGRAPH + {0xE0D2, 0x8A75}, //14278 #CJK UNIFIED IDEOGRAPH + {0xE0D3, 0x8DE3}, //14279 #CJK UNIFIED IDEOGRAPH + {0xE0D4, 0x9078}, //14280 #CJK UNIFIED IDEOGRAPH + {0xE0D5, 0x9291}, //14281 #CJK UNIFIED IDEOGRAPH + {0xE0D6, 0x9425}, //14282 #CJK UNIFIED IDEOGRAPH + {0xE0D7, 0x994D}, //14283 #CJK UNIFIED IDEOGRAPH + {0xE0D8, 0x9BAE}, //14284 #CJK UNIFIED IDEOGRAPH + {0xE0D9, 0x5368}, //14285 #CJK UNIFIED IDEOGRAPH + {0xE0DA, 0x5C51}, //14286 #CJK UNIFIED IDEOGRAPH + {0xE0DB, 0x6954}, //14287 #CJK UNIFIED IDEOGRAPH + {0xE0DC, 0x6CC4}, //14288 #CJK UNIFIED IDEOGRAPH + {0xE0DD, 0x6D29}, //14289 #CJK UNIFIED IDEOGRAPH + {0xE0DE, 0x6E2B}, //14290 #CJK UNIFIED IDEOGRAPH + {0xE0DF, 0x820C}, //14291 #CJK UNIFIED IDEOGRAPH + {0xE0E0, 0x859B}, //14292 #CJK UNIFIED IDEOGRAPH + {0xE0E1, 0x893B}, //14293 #CJK UNIFIED IDEOGRAPH + {0xE0E2, 0x8A2D}, //14294 #CJK UNIFIED IDEOGRAPH + {0xE0E3, 0x8AAA}, //14295 #CJK UNIFIED IDEOGRAPH + {0xE0E4, 0x96EA}, //14296 #CJK UNIFIED IDEOGRAPH + {0xE0E5, 0x9F67}, //14297 #CJK UNIFIED IDEOGRAPH + {0xE0E6, 0x5261}, //14298 #CJK UNIFIED IDEOGRAPH + {0xE0E7, 0x66B9}, //14299 #CJK UNIFIED IDEOGRAPH + {0xE0E8, 0x6BB2}, //14300 #CJK UNIFIED IDEOGRAPH + {0xE0E9, 0x7E96}, //14301 #CJK UNIFIED IDEOGRAPH + {0xE0EA, 0x87FE}, //14302 #CJK UNIFIED IDEOGRAPH + {0xE0EB, 0x8D0D}, //14303 #CJK UNIFIED IDEOGRAPH + {0xE0EC, 0x9583}, //14304 #CJK UNIFIED IDEOGRAPH + {0xE0ED, 0x965D}, //14305 #CJK UNIFIED IDEOGRAPH + {0xE0EE, 0x651D}, //14306 #CJK UNIFIED IDEOGRAPH + {0xE0EF, 0x6D89}, //14307 #CJK UNIFIED IDEOGRAPH + {0xE0F0, 0x71EE}, //14308 #CJK UNIFIED IDEOGRAPH + {0xE0F1, 0xF96E}, //14309 #CJK COMPATIBILITY IDEOGRAPH + {0xE0F2, 0x57CE}, //14310 #CJK UNIFIED IDEOGRAPH + {0xE0F3, 0x59D3}, //14311 #CJK UNIFIED IDEOGRAPH + {0xE0F4, 0x5BAC}, //14312 #CJK UNIFIED IDEOGRAPH + {0xE0F5, 0x6027}, //14313 #CJK UNIFIED IDEOGRAPH + {0xE0F6, 0x60FA}, //14314 #CJK UNIFIED IDEOGRAPH + {0xE0F7, 0x6210}, //14315 #CJK UNIFIED IDEOGRAPH + {0xE0F8, 0x661F}, //14316 #CJK UNIFIED IDEOGRAPH + {0xE0F9, 0x665F}, //14317 #CJK UNIFIED IDEOGRAPH + {0xE0FA, 0x7329}, //14318 #CJK UNIFIED IDEOGRAPH + {0xE0FB, 0x73F9}, //14319 #CJK UNIFIED IDEOGRAPH + {0xE0FC, 0x76DB}, //14320 #CJK UNIFIED IDEOGRAPH + {0xE0FD, 0x7701}, //14321 #CJK UNIFIED IDEOGRAPH + {0xE0FE, 0x7B6C}, //14322 #CJK UNIFIED IDEOGRAPH + {0xE1A1, 0x8056}, //14323 #CJK UNIFIED IDEOGRAPH + {0xE1A2, 0x8072}, //14324 #CJK UNIFIED IDEOGRAPH + {0xE1A3, 0x8165}, //14325 #CJK UNIFIED IDEOGRAPH + {0xE1A4, 0x8AA0}, //14326 #CJK UNIFIED IDEOGRAPH + {0xE1A5, 0x9192}, //14327 #CJK UNIFIED IDEOGRAPH + {0xE1A6, 0x4E16}, //14328 #CJK UNIFIED IDEOGRAPH + {0xE1A7, 0x52E2}, //14329 #CJK UNIFIED IDEOGRAPH + {0xE1A8, 0x6B72}, //14330 #CJK UNIFIED IDEOGRAPH + {0xE1A9, 0x6D17}, //14331 #CJK UNIFIED IDEOGRAPH + {0xE1AA, 0x7A05}, //14332 #CJK UNIFIED IDEOGRAPH + {0xE1AB, 0x7B39}, //14333 #CJK UNIFIED IDEOGRAPH + {0xE1AC, 0x7D30}, //14334 #CJK UNIFIED IDEOGRAPH + {0xE1AD, 0xF96F}, //14335 #CJK COMPATIBILITY IDEOGRAPH + {0xE1AE, 0x8CB0}, //14336 #CJK UNIFIED IDEOGRAPH + {0xE1AF, 0x53EC}, //14337 #CJK UNIFIED IDEOGRAPH + {0xE1B0, 0x562F}, //14338 #CJK UNIFIED IDEOGRAPH + {0xE1B1, 0x5851}, //14339 #CJK UNIFIED IDEOGRAPH + {0xE1B2, 0x5BB5}, //14340 #CJK UNIFIED IDEOGRAPH + {0xE1B3, 0x5C0F}, //14341 #CJK UNIFIED IDEOGRAPH + {0xE1B4, 0x5C11}, //14342 #CJK UNIFIED IDEOGRAPH + {0xE1B5, 0x5DE2}, //14343 #CJK UNIFIED IDEOGRAPH + {0xE1B6, 0x6240}, //14344 #CJK UNIFIED IDEOGRAPH + {0xE1B7, 0x6383}, //14345 #CJK UNIFIED IDEOGRAPH + {0xE1B8, 0x6414}, //14346 #CJK UNIFIED IDEOGRAPH + {0xE1B9, 0x662D}, //14347 #CJK UNIFIED IDEOGRAPH + {0xE1BA, 0x68B3}, //14348 #CJK UNIFIED IDEOGRAPH + {0xE1BB, 0x6CBC}, //14349 #CJK UNIFIED IDEOGRAPH + {0xE1BC, 0x6D88}, //14350 #CJK UNIFIED IDEOGRAPH + {0xE1BD, 0x6EAF}, //14351 #CJK UNIFIED IDEOGRAPH + {0xE1BE, 0x701F}, //14352 #CJK UNIFIED IDEOGRAPH + {0xE1BF, 0x70A4}, //14353 #CJK UNIFIED IDEOGRAPH + {0xE1C0, 0x71D2}, //14354 #CJK UNIFIED IDEOGRAPH + {0xE1C1, 0x7526}, //14355 #CJK UNIFIED IDEOGRAPH + {0xE1C2, 0x758F}, //14356 #CJK UNIFIED IDEOGRAPH + {0xE1C3, 0x758E}, //14357 #CJK UNIFIED IDEOGRAPH + {0xE1C4, 0x7619}, //14358 #CJK UNIFIED IDEOGRAPH + {0xE1C5, 0x7B11}, //14359 #CJK UNIFIED IDEOGRAPH + {0xE1C6, 0x7BE0}, //14360 #CJK UNIFIED IDEOGRAPH + {0xE1C7, 0x7C2B}, //14361 #CJK UNIFIED IDEOGRAPH + {0xE1C8, 0x7D20}, //14362 #CJK UNIFIED IDEOGRAPH + {0xE1C9, 0x7D39}, //14363 #CJK UNIFIED IDEOGRAPH + {0xE1CA, 0x852C}, //14364 #CJK UNIFIED IDEOGRAPH + {0xE1CB, 0x856D}, //14365 #CJK UNIFIED IDEOGRAPH + {0xE1CC, 0x8607}, //14366 #CJK UNIFIED IDEOGRAPH + {0xE1CD, 0x8A34}, //14367 #CJK UNIFIED IDEOGRAPH + {0xE1CE, 0x900D}, //14368 #CJK UNIFIED IDEOGRAPH + {0xE1CF, 0x9061}, //14369 #CJK UNIFIED IDEOGRAPH + {0xE1D0, 0x90B5}, //14370 #CJK UNIFIED IDEOGRAPH + {0xE1D1, 0x92B7}, //14371 #CJK UNIFIED IDEOGRAPH + {0xE1D2, 0x97F6}, //14372 #CJK UNIFIED IDEOGRAPH + {0xE1D3, 0x9A37}, //14373 #CJK UNIFIED IDEOGRAPH + {0xE1D4, 0x4FD7}, //14374 #CJK UNIFIED IDEOGRAPH + {0xE1D5, 0x5C6C}, //14375 #CJK UNIFIED IDEOGRAPH + {0xE1D6, 0x675F}, //14376 #CJK UNIFIED IDEOGRAPH + {0xE1D7, 0x6D91}, //14377 #CJK UNIFIED IDEOGRAPH + {0xE1D8, 0x7C9F}, //14378 #CJK UNIFIED IDEOGRAPH + {0xE1D9, 0x7E8C}, //14379 #CJK UNIFIED IDEOGRAPH + {0xE1DA, 0x8B16}, //14380 #CJK UNIFIED IDEOGRAPH + {0xE1DB, 0x8D16}, //14381 #CJK UNIFIED IDEOGRAPH + {0xE1DC, 0x901F}, //14382 #CJK UNIFIED IDEOGRAPH + {0xE1DD, 0x5B6B}, //14383 #CJK UNIFIED IDEOGRAPH + {0xE1DE, 0x5DFD}, //14384 #CJK UNIFIED IDEOGRAPH + {0xE1DF, 0x640D}, //14385 #CJK UNIFIED IDEOGRAPH + {0xE1E0, 0x84C0}, //14386 #CJK UNIFIED IDEOGRAPH + {0xE1E1, 0x905C}, //14387 #CJK UNIFIED IDEOGRAPH + {0xE1E2, 0x98E1}, //14388 #CJK UNIFIED IDEOGRAPH + {0xE1E3, 0x7387}, //14389 #CJK UNIFIED IDEOGRAPH + {0xE1E4, 0x5B8B}, //14390 #CJK UNIFIED IDEOGRAPH + {0xE1E5, 0x609A}, //14391 #CJK UNIFIED IDEOGRAPH + {0xE1E6, 0x677E}, //14392 #CJK UNIFIED IDEOGRAPH + {0xE1E7, 0x6DDE}, //14393 #CJK UNIFIED IDEOGRAPH + {0xE1E8, 0x8A1F}, //14394 #CJK UNIFIED IDEOGRAPH + {0xE1E9, 0x8AA6}, //14395 #CJK UNIFIED IDEOGRAPH + {0xE1EA, 0x9001}, //14396 #CJK UNIFIED IDEOGRAPH + {0xE1EB, 0x980C}, //14397 #CJK UNIFIED IDEOGRAPH + {0xE1EC, 0x5237}, //14398 #CJK UNIFIED IDEOGRAPH + {0xE1ED, 0xF970}, //14399 #CJK COMPATIBILITY IDEOGRAPH + {0xE1EE, 0x7051}, //14400 #CJK UNIFIED IDEOGRAPH + {0xE1EF, 0x788E}, //14401 #CJK UNIFIED IDEOGRAPH + {0xE1F0, 0x9396}, //14402 #CJK UNIFIED IDEOGRAPH + {0xE1F1, 0x8870}, //14403 #CJK UNIFIED IDEOGRAPH + {0xE1F2, 0x91D7}, //14404 #CJK UNIFIED IDEOGRAPH + {0xE1F3, 0x4FEE}, //14405 #CJK UNIFIED IDEOGRAPH + {0xE1F4, 0x53D7}, //14406 #CJK UNIFIED IDEOGRAPH + {0xE1F5, 0x55FD}, //14407 #CJK UNIFIED IDEOGRAPH + {0xE1F6, 0x56DA}, //14408 #CJK UNIFIED IDEOGRAPH + {0xE1F7, 0x5782}, //14409 #CJK UNIFIED IDEOGRAPH + {0xE1F8, 0x58FD}, //14410 #CJK UNIFIED IDEOGRAPH + {0xE1F9, 0x5AC2}, //14411 #CJK UNIFIED IDEOGRAPH + {0xE1FA, 0x5B88}, //14412 #CJK UNIFIED IDEOGRAPH + {0xE1FB, 0x5CAB}, //14413 #CJK UNIFIED IDEOGRAPH + {0xE1FC, 0x5CC0}, //14414 #CJK UNIFIED IDEOGRAPH + {0xE1FD, 0x5E25}, //14415 #CJK UNIFIED IDEOGRAPH + {0xE1FE, 0x6101}, //14416 #CJK UNIFIED IDEOGRAPH + {0xE2A1, 0x620D}, //14417 #CJK UNIFIED IDEOGRAPH + {0xE2A2, 0x624B}, //14418 #CJK UNIFIED IDEOGRAPH + {0xE2A3, 0x6388}, //14419 #CJK UNIFIED IDEOGRAPH + {0xE2A4, 0x641C}, //14420 #CJK UNIFIED IDEOGRAPH + {0xE2A5, 0x6536}, //14421 #CJK UNIFIED IDEOGRAPH + {0xE2A6, 0x6578}, //14422 #CJK UNIFIED IDEOGRAPH + {0xE2A7, 0x6A39}, //14423 #CJK UNIFIED IDEOGRAPH + {0xE2A8, 0x6B8A}, //14424 #CJK UNIFIED IDEOGRAPH + {0xE2A9, 0x6C34}, //14425 #CJK UNIFIED IDEOGRAPH + {0xE2AA, 0x6D19}, //14426 #CJK UNIFIED IDEOGRAPH + {0xE2AB, 0x6F31}, //14427 #CJK UNIFIED IDEOGRAPH + {0xE2AC, 0x71E7}, //14428 #CJK UNIFIED IDEOGRAPH + {0xE2AD, 0x72E9}, //14429 #CJK UNIFIED IDEOGRAPH + {0xE2AE, 0x7378}, //14430 #CJK UNIFIED IDEOGRAPH + {0xE2AF, 0x7407}, //14431 #CJK UNIFIED IDEOGRAPH + {0xE2B0, 0x74B2}, //14432 #CJK UNIFIED IDEOGRAPH + {0xE2B1, 0x7626}, //14433 #CJK UNIFIED IDEOGRAPH + {0xE2B2, 0x7761}, //14434 #CJK UNIFIED IDEOGRAPH + {0xE2B3, 0x79C0}, //14435 #CJK UNIFIED IDEOGRAPH + {0xE2B4, 0x7A57}, //14436 #CJK UNIFIED IDEOGRAPH + {0xE2B5, 0x7AEA}, //14437 #CJK UNIFIED IDEOGRAPH + {0xE2B6, 0x7CB9}, //14438 #CJK UNIFIED IDEOGRAPH + {0xE2B7, 0x7D8F}, //14439 #CJK UNIFIED IDEOGRAPH + {0xE2B8, 0x7DAC}, //14440 #CJK UNIFIED IDEOGRAPH + {0xE2B9, 0x7E61}, //14441 #CJK UNIFIED IDEOGRAPH + {0xE2BA, 0x7F9E}, //14442 #CJK UNIFIED IDEOGRAPH + {0xE2BB, 0x8129}, //14443 #CJK UNIFIED IDEOGRAPH + {0xE2BC, 0x8331}, //14444 #CJK UNIFIED IDEOGRAPH + {0xE2BD, 0x8490}, //14445 #CJK UNIFIED IDEOGRAPH + {0xE2BE, 0x84DA}, //14446 #CJK UNIFIED IDEOGRAPH + {0xE2BF, 0x85EA}, //14447 #CJK UNIFIED IDEOGRAPH + {0xE2C0, 0x8896}, //14448 #CJK UNIFIED IDEOGRAPH + {0xE2C1, 0x8AB0}, //14449 #CJK UNIFIED IDEOGRAPH + {0xE2C2, 0x8B90}, //14450 #CJK UNIFIED IDEOGRAPH + {0xE2C3, 0x8F38}, //14451 #CJK UNIFIED IDEOGRAPH + {0xE2C4, 0x9042}, //14452 #CJK UNIFIED IDEOGRAPH + {0xE2C5, 0x9083}, //14453 #CJK UNIFIED IDEOGRAPH + {0xE2C6, 0x916C}, //14454 #CJK UNIFIED IDEOGRAPH + {0xE2C7, 0x9296}, //14455 #CJK UNIFIED IDEOGRAPH + {0xE2C8, 0x92B9}, //14456 #CJK UNIFIED IDEOGRAPH + {0xE2C9, 0x968B}, //14457 #CJK UNIFIED IDEOGRAPH + {0xE2CA, 0x96A7}, //14458 #CJK UNIFIED IDEOGRAPH + {0xE2CB, 0x96A8}, //14459 #CJK UNIFIED IDEOGRAPH + {0xE2CC, 0x96D6}, //14460 #CJK UNIFIED IDEOGRAPH + {0xE2CD, 0x9700}, //14461 #CJK UNIFIED IDEOGRAPH + {0xE2CE, 0x9808}, //14462 #CJK UNIFIED IDEOGRAPH + {0xE2CF, 0x9996}, //14463 #CJK UNIFIED IDEOGRAPH + {0xE2D0, 0x9AD3}, //14464 #CJK UNIFIED IDEOGRAPH + {0xE2D1, 0x9B1A}, //14465 #CJK UNIFIED IDEOGRAPH + {0xE2D2, 0x53D4}, //14466 #CJK UNIFIED IDEOGRAPH + {0xE2D3, 0x587E}, //14467 #CJK UNIFIED IDEOGRAPH + {0xE2D4, 0x5919}, //14468 #CJK UNIFIED IDEOGRAPH + {0xE2D5, 0x5B70}, //14469 #CJK UNIFIED IDEOGRAPH + {0xE2D6, 0x5BBF}, //14470 #CJK UNIFIED IDEOGRAPH + {0xE2D7, 0x6DD1}, //14471 #CJK UNIFIED IDEOGRAPH + {0xE2D8, 0x6F5A}, //14472 #CJK UNIFIED IDEOGRAPH + {0xE2D9, 0x719F}, //14473 #CJK UNIFIED IDEOGRAPH + {0xE2DA, 0x7421}, //14474 #CJK UNIFIED IDEOGRAPH + {0xE2DB, 0x74B9}, //14475 #CJK UNIFIED IDEOGRAPH + {0xE2DC, 0x8085}, //14476 #CJK UNIFIED IDEOGRAPH + {0xE2DD, 0x83FD}, //14477 #CJK UNIFIED IDEOGRAPH + {0xE2DE, 0x5DE1}, //14478 #CJK UNIFIED IDEOGRAPH + {0xE2DF, 0x5F87}, //14479 #CJK UNIFIED IDEOGRAPH + {0xE2E0, 0x5FAA}, //14480 #CJK UNIFIED IDEOGRAPH + {0xE2E1, 0x6042}, //14481 #CJK UNIFIED IDEOGRAPH + {0xE2E2, 0x65EC}, //14482 #CJK UNIFIED IDEOGRAPH + {0xE2E3, 0x6812}, //14483 #CJK UNIFIED IDEOGRAPH + {0xE2E4, 0x696F}, //14484 #CJK UNIFIED IDEOGRAPH + {0xE2E5, 0x6A53}, //14485 #CJK UNIFIED IDEOGRAPH + {0xE2E6, 0x6B89}, //14486 #CJK UNIFIED IDEOGRAPH + {0xE2E7, 0x6D35}, //14487 #CJK UNIFIED IDEOGRAPH + {0xE2E8, 0x6DF3}, //14488 #CJK UNIFIED IDEOGRAPH + {0xE2E9, 0x73E3}, //14489 #CJK UNIFIED IDEOGRAPH + {0xE2EA, 0x76FE}, //14490 #CJK UNIFIED IDEOGRAPH + {0xE2EB, 0x77AC}, //14491 #CJK UNIFIED IDEOGRAPH + {0xE2EC, 0x7B4D}, //14492 #CJK UNIFIED IDEOGRAPH + {0xE2ED, 0x7D14}, //14493 #CJK UNIFIED IDEOGRAPH + {0xE2EE, 0x8123}, //14494 #CJK UNIFIED IDEOGRAPH + {0xE2EF, 0x821C}, //14495 #CJK UNIFIED IDEOGRAPH + {0xE2F0, 0x8340}, //14496 #CJK UNIFIED IDEOGRAPH + {0xE2F1, 0x84F4}, //14497 #CJK UNIFIED IDEOGRAPH + {0xE2F2, 0x8563}, //14498 #CJK UNIFIED IDEOGRAPH + {0xE2F3, 0x8A62}, //14499 #CJK UNIFIED IDEOGRAPH + {0xE2F4, 0x8AC4}, //14500 #CJK UNIFIED IDEOGRAPH + {0xE2F5, 0x9187}, //14501 #CJK UNIFIED IDEOGRAPH + {0xE2F6, 0x931E}, //14502 #CJK UNIFIED IDEOGRAPH + {0xE2F7, 0x9806}, //14503 #CJK UNIFIED IDEOGRAPH + {0xE2F8, 0x99B4}, //14504 #CJK UNIFIED IDEOGRAPH + {0xE2F9, 0x620C}, //14505 #CJK UNIFIED IDEOGRAPH + {0xE2FA, 0x8853}, //14506 #CJK UNIFIED IDEOGRAPH + {0xE2FB, 0x8FF0}, //14507 #CJK UNIFIED IDEOGRAPH + {0xE2FC, 0x9265}, //14508 #CJK UNIFIED IDEOGRAPH + {0xE2FD, 0x5D07}, //14509 #CJK UNIFIED IDEOGRAPH + {0xE2FE, 0x5D27}, //14510 #CJK UNIFIED IDEOGRAPH + {0xE3A1, 0x5D69}, //14511 #CJK UNIFIED IDEOGRAPH + {0xE3A2, 0x745F}, //14512 #CJK UNIFIED IDEOGRAPH + {0xE3A3, 0x819D}, //14513 #CJK UNIFIED IDEOGRAPH + {0xE3A4, 0x8768}, //14514 #CJK UNIFIED IDEOGRAPH + {0xE3A5, 0x6FD5}, //14515 #CJK UNIFIED IDEOGRAPH + {0xE3A6, 0x62FE}, //14516 #CJK UNIFIED IDEOGRAPH + {0xE3A7, 0x7FD2}, //14517 #CJK UNIFIED IDEOGRAPH + {0xE3A8, 0x8936}, //14518 #CJK UNIFIED IDEOGRAPH + {0xE3A9, 0x8972}, //14519 #CJK UNIFIED IDEOGRAPH + {0xE3AA, 0x4E1E}, //14520 #CJK UNIFIED IDEOGRAPH + {0xE3AB, 0x4E58}, //14521 #CJK UNIFIED IDEOGRAPH + {0xE3AC, 0x50E7}, //14522 #CJK UNIFIED IDEOGRAPH + {0xE3AD, 0x52DD}, //14523 #CJK UNIFIED IDEOGRAPH + {0xE3AE, 0x5347}, //14524 #CJK UNIFIED IDEOGRAPH + {0xE3AF, 0x627F}, //14525 #CJK UNIFIED IDEOGRAPH + {0xE3B0, 0x6607}, //14526 #CJK UNIFIED IDEOGRAPH + {0xE3B1, 0x7E69}, //14527 #CJK UNIFIED IDEOGRAPH + {0xE3B2, 0x8805}, //14528 #CJK UNIFIED IDEOGRAPH + {0xE3B3, 0x965E}, //14529 #CJK UNIFIED IDEOGRAPH + {0xE3B4, 0x4F8D}, //14530 #CJK UNIFIED IDEOGRAPH + {0xE3B5, 0x5319}, //14531 #CJK UNIFIED IDEOGRAPH + {0xE3B6, 0x5636}, //14532 #CJK UNIFIED IDEOGRAPH + {0xE3B7, 0x59CB}, //14533 #CJK UNIFIED IDEOGRAPH + {0xE3B8, 0x5AA4}, //14534 #CJK UNIFIED IDEOGRAPH + {0xE3B9, 0x5C38}, //14535 #CJK UNIFIED IDEOGRAPH + {0xE3BA, 0x5C4E}, //14536 #CJK UNIFIED IDEOGRAPH + {0xE3BB, 0x5C4D}, //14537 #CJK UNIFIED IDEOGRAPH + {0xE3BC, 0x5E02}, //14538 #CJK UNIFIED IDEOGRAPH + {0xE3BD, 0x5F11}, //14539 #CJK UNIFIED IDEOGRAPH + {0xE3BE, 0x6043}, //14540 #CJK UNIFIED IDEOGRAPH + {0xE3BF, 0x65BD}, //14541 #CJK UNIFIED IDEOGRAPH + {0xE3C0, 0x662F}, //14542 #CJK UNIFIED IDEOGRAPH + {0xE3C1, 0x6642}, //14543 #CJK UNIFIED IDEOGRAPH + {0xE3C2, 0x67BE}, //14544 #CJK UNIFIED IDEOGRAPH + {0xE3C3, 0x67F4}, //14545 #CJK UNIFIED IDEOGRAPH + {0xE3C4, 0x731C}, //14546 #CJK UNIFIED IDEOGRAPH + {0xE3C5, 0x77E2}, //14547 #CJK UNIFIED IDEOGRAPH + {0xE3C6, 0x793A}, //14548 #CJK UNIFIED IDEOGRAPH + {0xE3C7, 0x7FC5}, //14549 #CJK UNIFIED IDEOGRAPH + {0xE3C8, 0x8494}, //14550 #CJK UNIFIED IDEOGRAPH + {0xE3C9, 0x84CD}, //14551 #CJK UNIFIED IDEOGRAPH + {0xE3CA, 0x8996}, //14552 #CJK UNIFIED IDEOGRAPH + {0xE3CB, 0x8A66}, //14553 #CJK UNIFIED IDEOGRAPH + {0xE3CC, 0x8A69}, //14554 #CJK UNIFIED IDEOGRAPH + {0xE3CD, 0x8AE1}, //14555 #CJK UNIFIED IDEOGRAPH + {0xE3CE, 0x8C55}, //14556 #CJK UNIFIED IDEOGRAPH + {0xE3CF, 0x8C7A}, //14557 #CJK UNIFIED IDEOGRAPH + {0xE3D0, 0x57F4}, //14558 #CJK UNIFIED IDEOGRAPH + {0xE3D1, 0x5BD4}, //14559 #CJK UNIFIED IDEOGRAPH + {0xE3D2, 0x5F0F}, //14560 #CJK UNIFIED IDEOGRAPH + {0xE3D3, 0x606F}, //14561 #CJK UNIFIED IDEOGRAPH + {0xE3D4, 0x62ED}, //14562 #CJK UNIFIED IDEOGRAPH + {0xE3D5, 0x690D}, //14563 #CJK UNIFIED IDEOGRAPH + {0xE3D6, 0x6B96}, //14564 #CJK UNIFIED IDEOGRAPH + {0xE3D7, 0x6E5C}, //14565 #CJK UNIFIED IDEOGRAPH + {0xE3D8, 0x7184}, //14566 #CJK UNIFIED IDEOGRAPH + {0xE3D9, 0x7BD2}, //14567 #CJK UNIFIED IDEOGRAPH + {0xE3DA, 0x8755}, //14568 #CJK UNIFIED IDEOGRAPH + {0xE3DB, 0x8B58}, //14569 #CJK UNIFIED IDEOGRAPH + {0xE3DC, 0x8EFE}, //14570 #CJK UNIFIED IDEOGRAPH + {0xE3DD, 0x98DF}, //14571 #CJK UNIFIED IDEOGRAPH + {0xE3DE, 0x98FE}, //14572 #CJK UNIFIED IDEOGRAPH + {0xE3DF, 0x4F38}, //14573 #CJK UNIFIED IDEOGRAPH + {0xE3E0, 0x4F81}, //14574 #CJK UNIFIED IDEOGRAPH + {0xE3E1, 0x4FE1}, //14575 #CJK UNIFIED IDEOGRAPH + {0xE3E2, 0x547B}, //14576 #CJK UNIFIED IDEOGRAPH + {0xE3E3, 0x5A20}, //14577 #CJK UNIFIED IDEOGRAPH + {0xE3E4, 0x5BB8}, //14578 #CJK UNIFIED IDEOGRAPH + {0xE3E5, 0x613C}, //14579 #CJK UNIFIED IDEOGRAPH + {0xE3E6, 0x65B0}, //14580 #CJK UNIFIED IDEOGRAPH + {0xE3E7, 0x6668}, //14581 #CJK UNIFIED IDEOGRAPH + {0xE3E8, 0x71FC}, //14582 #CJK UNIFIED IDEOGRAPH + {0xE3E9, 0x7533}, //14583 #CJK UNIFIED IDEOGRAPH + {0xE3EA, 0x795E}, //14584 #CJK UNIFIED IDEOGRAPH + {0xE3EB, 0x7D33}, //14585 #CJK UNIFIED IDEOGRAPH + {0xE3EC, 0x814E}, //14586 #CJK UNIFIED IDEOGRAPH + {0xE3ED, 0x81E3}, //14587 #CJK UNIFIED IDEOGRAPH + {0xE3EE, 0x8398}, //14588 #CJK UNIFIED IDEOGRAPH + {0xE3EF, 0x85AA}, //14589 #CJK UNIFIED IDEOGRAPH + {0xE3F0, 0x85CE}, //14590 #CJK UNIFIED IDEOGRAPH + {0xE3F1, 0x8703}, //14591 #CJK UNIFIED IDEOGRAPH + {0xE3F2, 0x8A0A}, //14592 #CJK UNIFIED IDEOGRAPH + {0xE3F3, 0x8EAB}, //14593 #CJK UNIFIED IDEOGRAPH + {0xE3F4, 0x8F9B}, //14594 #CJK UNIFIED IDEOGRAPH + {0xE3F5, 0xF971}, //14595 #CJK COMPATIBILITY IDEOGRAPH + {0xE3F6, 0x8FC5}, //14596 #CJK UNIFIED IDEOGRAPH + {0xE3F7, 0x5931}, //14597 #CJK UNIFIED IDEOGRAPH + {0xE3F8, 0x5BA4}, //14598 #CJK UNIFIED IDEOGRAPH + {0xE3F9, 0x5BE6}, //14599 #CJK UNIFIED IDEOGRAPH + {0xE3FA, 0x6089}, //14600 #CJK UNIFIED IDEOGRAPH + {0xE3FB, 0x5BE9}, //14601 #CJK UNIFIED IDEOGRAPH + {0xE3FC, 0x5C0B}, //14602 #CJK UNIFIED IDEOGRAPH + {0xE3FD, 0x5FC3}, //14603 #CJK UNIFIED IDEOGRAPH + {0xE3FE, 0x6C81}, //14604 #CJK UNIFIED IDEOGRAPH + {0xE4A1, 0xF972}, //14605 #CJK COMPATIBILITY IDEOGRAPH + {0xE4A2, 0x6DF1}, //14606 #CJK UNIFIED IDEOGRAPH + {0xE4A3, 0x700B}, //14607 #CJK UNIFIED IDEOGRAPH + {0xE4A4, 0x751A}, //14608 #CJK UNIFIED IDEOGRAPH + {0xE4A5, 0x82AF}, //14609 #CJK UNIFIED IDEOGRAPH + {0xE4A6, 0x8AF6}, //14610 #CJK UNIFIED IDEOGRAPH + {0xE4A7, 0x4EC0}, //14611 #CJK UNIFIED IDEOGRAPH + {0xE4A8, 0x5341}, //14612 #CJK UNIFIED IDEOGRAPH + {0xE4A9, 0xF973}, //14613 #CJK COMPATIBILITY IDEOGRAPH + {0xE4AA, 0x96D9}, //14614 #CJK UNIFIED IDEOGRAPH + {0xE4AB, 0x6C0F}, //14615 #CJK UNIFIED IDEOGRAPH + {0xE4AC, 0x4E9E}, //14616 #CJK UNIFIED IDEOGRAPH + {0xE4AD, 0x4FC4}, //14617 #CJK UNIFIED IDEOGRAPH + {0xE4AE, 0x5152}, //14618 #CJK UNIFIED IDEOGRAPH + {0xE4AF, 0x555E}, //14619 #CJK UNIFIED IDEOGRAPH + {0xE4B0, 0x5A25}, //14620 #CJK UNIFIED IDEOGRAPH + {0xE4B1, 0x5CE8}, //14621 #CJK UNIFIED IDEOGRAPH + {0xE4B2, 0x6211}, //14622 #CJK UNIFIED IDEOGRAPH + {0xE4B3, 0x7259}, //14623 #CJK UNIFIED IDEOGRAPH + {0xE4B4, 0x82BD}, //14624 #CJK UNIFIED IDEOGRAPH + {0xE4B5, 0x83AA}, //14625 #CJK UNIFIED IDEOGRAPH + {0xE4B6, 0x86FE}, //14626 #CJK UNIFIED IDEOGRAPH + {0xE4B7, 0x8859}, //14627 #CJK UNIFIED IDEOGRAPH + {0xE4B8, 0x8A1D}, //14628 #CJK UNIFIED IDEOGRAPH + {0xE4B9, 0x963F}, //14629 #CJK UNIFIED IDEOGRAPH + {0xE4BA, 0x96C5}, //14630 #CJK UNIFIED IDEOGRAPH + {0xE4BB, 0x9913}, //14631 #CJK UNIFIED IDEOGRAPH + {0xE4BC, 0x9D09}, //14632 #CJK UNIFIED IDEOGRAPH + {0xE4BD, 0x9D5D}, //14633 #CJK UNIFIED IDEOGRAPH + {0xE4BE, 0x580A}, //14634 #CJK UNIFIED IDEOGRAPH + {0xE4BF, 0x5CB3}, //14635 #CJK UNIFIED IDEOGRAPH + {0xE4C0, 0x5DBD}, //14636 #CJK UNIFIED IDEOGRAPH + {0xE4C1, 0x5E44}, //14637 #CJK UNIFIED IDEOGRAPH + {0xE4C2, 0x60E1}, //14638 #CJK UNIFIED IDEOGRAPH + {0xE4C3, 0x6115}, //14639 #CJK UNIFIED IDEOGRAPH + {0xE4C4, 0x63E1}, //14640 #CJK UNIFIED IDEOGRAPH + {0xE4C5, 0x6A02}, //14641 #CJK UNIFIED IDEOGRAPH + {0xE4C6, 0x6E25}, //14642 #CJK UNIFIED IDEOGRAPH + {0xE4C7, 0x9102}, //14643 #CJK UNIFIED IDEOGRAPH + {0xE4C8, 0x9354}, //14644 #CJK UNIFIED IDEOGRAPH + {0xE4C9, 0x984E}, //14645 #CJK UNIFIED IDEOGRAPH + {0xE4CA, 0x9C10}, //14646 #CJK UNIFIED IDEOGRAPH + {0xE4CB, 0x9F77}, //14647 #CJK UNIFIED IDEOGRAPH + {0xE4CC, 0x5B89}, //14648 #CJK UNIFIED IDEOGRAPH + {0xE4CD, 0x5CB8}, //14649 #CJK UNIFIED IDEOGRAPH + {0xE4CE, 0x6309}, //14650 #CJK UNIFIED IDEOGRAPH + {0xE4CF, 0x664F}, //14651 #CJK UNIFIED IDEOGRAPH + {0xE4D0, 0x6848}, //14652 #CJK UNIFIED IDEOGRAPH + {0xE4D1, 0x773C}, //14653 #CJK UNIFIED IDEOGRAPH + {0xE4D2, 0x96C1}, //14654 #CJK UNIFIED IDEOGRAPH + {0xE4D3, 0x978D}, //14655 #CJK UNIFIED IDEOGRAPH + {0xE4D4, 0x9854}, //14656 #CJK UNIFIED IDEOGRAPH + {0xE4D5, 0x9B9F}, //14657 #CJK UNIFIED IDEOGRAPH + {0xE4D6, 0x65A1}, //14658 #CJK UNIFIED IDEOGRAPH + {0xE4D7, 0x8B01}, //14659 #CJK UNIFIED IDEOGRAPH + {0xE4D8, 0x8ECB}, //14660 #CJK UNIFIED IDEOGRAPH + {0xE4D9, 0x95BC}, //14661 #CJK UNIFIED IDEOGRAPH + {0xE4DA, 0x5535}, //14662 #CJK UNIFIED IDEOGRAPH + {0xE4DB, 0x5CA9}, //14663 #CJK UNIFIED IDEOGRAPH + {0xE4DC, 0x5DD6}, //14664 #CJK UNIFIED IDEOGRAPH + {0xE4DD, 0x5EB5}, //14665 #CJK UNIFIED IDEOGRAPH + {0xE4DE, 0x6697}, //14666 #CJK UNIFIED IDEOGRAPH + {0xE4DF, 0x764C}, //14667 #CJK UNIFIED IDEOGRAPH + {0xE4E0, 0x83F4}, //14668 #CJK UNIFIED IDEOGRAPH + {0xE4E1, 0x95C7}, //14669 #CJK UNIFIED IDEOGRAPH + {0xE4E2, 0x58D3}, //14670 #CJK UNIFIED IDEOGRAPH + {0xE4E3, 0x62BC}, //14671 #CJK UNIFIED IDEOGRAPH + {0xE4E4, 0x72CE}, //14672 #CJK UNIFIED IDEOGRAPH + {0xE4E5, 0x9D28}, //14673 #CJK UNIFIED IDEOGRAPH + {0xE4E6, 0x4EF0}, //14674 #CJK UNIFIED IDEOGRAPH + {0xE4E7, 0x592E}, //14675 #CJK UNIFIED IDEOGRAPH + {0xE4E8, 0x600F}, //14676 #CJK UNIFIED IDEOGRAPH + {0xE4E9, 0x663B}, //14677 #CJK UNIFIED IDEOGRAPH + {0xE4EA, 0x6B83}, //14678 #CJK UNIFIED IDEOGRAPH + {0xE4EB, 0x79E7}, //14679 #CJK UNIFIED IDEOGRAPH + {0xE4EC, 0x9D26}, //14680 #CJK UNIFIED IDEOGRAPH + {0xE4ED, 0x5393}, //14681 #CJK UNIFIED IDEOGRAPH + {0xE4EE, 0x54C0}, //14682 #CJK UNIFIED IDEOGRAPH + {0xE4EF, 0x57C3}, //14683 #CJK UNIFIED IDEOGRAPH + {0xE4F0, 0x5D16}, //14684 #CJK UNIFIED IDEOGRAPH + {0xE4F1, 0x611B}, //14685 #CJK UNIFIED IDEOGRAPH + {0xE4F2, 0x66D6}, //14686 #CJK UNIFIED IDEOGRAPH + {0xE4F3, 0x6DAF}, //14687 #CJK UNIFIED IDEOGRAPH + {0xE4F4, 0x788D}, //14688 #CJK UNIFIED IDEOGRAPH + {0xE4F5, 0x827E}, //14689 #CJK UNIFIED IDEOGRAPH + {0xE4F6, 0x9698}, //14690 #CJK UNIFIED IDEOGRAPH + {0xE4F7, 0x9744}, //14691 #CJK UNIFIED IDEOGRAPH + {0xE4F8, 0x5384}, //14692 #CJK UNIFIED IDEOGRAPH + {0xE4F9, 0x627C}, //14693 #CJK UNIFIED IDEOGRAPH + {0xE4FA, 0x6396}, //14694 #CJK UNIFIED IDEOGRAPH + {0xE4FB, 0x6DB2}, //14695 #CJK UNIFIED IDEOGRAPH + {0xE4FC, 0x7E0A}, //14696 #CJK UNIFIED IDEOGRAPH + {0xE4FD, 0x814B}, //14697 #CJK UNIFIED IDEOGRAPH + {0xE4FE, 0x984D}, //14698 #CJK UNIFIED IDEOGRAPH + {0xE5A1, 0x6AFB}, //14699 #CJK UNIFIED IDEOGRAPH + {0xE5A2, 0x7F4C}, //14700 #CJK UNIFIED IDEOGRAPH + {0xE5A3, 0x9DAF}, //14701 #CJK UNIFIED IDEOGRAPH + {0xE5A4, 0x9E1A}, //14702 #CJK UNIFIED IDEOGRAPH + {0xE5A5, 0x4E5F}, //14703 #CJK UNIFIED IDEOGRAPH + {0xE5A6, 0x503B}, //14704 #CJK UNIFIED IDEOGRAPH + {0xE5A7, 0x51B6}, //14705 #CJK UNIFIED IDEOGRAPH + {0xE5A8, 0x591C}, //14706 #CJK UNIFIED IDEOGRAPH + {0xE5A9, 0x60F9}, //14707 #CJK UNIFIED IDEOGRAPH + {0xE5AA, 0x63F6}, //14708 #CJK UNIFIED IDEOGRAPH + {0xE5AB, 0x6930}, //14709 #CJK UNIFIED IDEOGRAPH + {0xE5AC, 0x723A}, //14710 #CJK UNIFIED IDEOGRAPH + {0xE5AD, 0x8036}, //14711 #CJK UNIFIED IDEOGRAPH + {0xE5AE, 0xF974}, //14712 #CJK COMPATIBILITY IDEOGRAPH + {0xE5AF, 0x91CE}, //14713 #CJK UNIFIED IDEOGRAPH + {0xE5B0, 0x5F31}, //14714 #CJK UNIFIED IDEOGRAPH + {0xE5B1, 0xF975}, //14715 #CJK COMPATIBILITY IDEOGRAPH + {0xE5B2, 0xF976}, //14716 #CJK COMPATIBILITY IDEOGRAPH + {0xE5B3, 0x7D04}, //14717 #CJK UNIFIED IDEOGRAPH + {0xE5B4, 0x82E5}, //14718 #CJK UNIFIED IDEOGRAPH + {0xE5B5, 0x846F}, //14719 #CJK UNIFIED IDEOGRAPH + {0xE5B6, 0x84BB}, //14720 #CJK UNIFIED IDEOGRAPH + {0xE5B7, 0x85E5}, //14721 #CJK UNIFIED IDEOGRAPH + {0xE5B8, 0x8E8D}, //14722 #CJK UNIFIED IDEOGRAPH + {0xE5B9, 0xF977}, //14723 #CJK COMPATIBILITY IDEOGRAPH + {0xE5BA, 0x4F6F}, //14724 #CJK UNIFIED IDEOGRAPH + {0xE5BB, 0xF978}, //14725 #CJK COMPATIBILITY IDEOGRAPH + {0xE5BC, 0xF979}, //14726 #CJK COMPATIBILITY IDEOGRAPH + {0xE5BD, 0x58E4}, //14727 #CJK UNIFIED IDEOGRAPH + {0xE5BE, 0x5B43}, //14728 #CJK UNIFIED IDEOGRAPH + {0xE5BF, 0x6059}, //14729 #CJK UNIFIED IDEOGRAPH + {0xE5C0, 0x63DA}, //14730 #CJK UNIFIED IDEOGRAPH + {0xE5C1, 0x6518}, //14731 #CJK UNIFIED IDEOGRAPH + {0xE5C2, 0x656D}, //14732 #CJK UNIFIED IDEOGRAPH + {0xE5C3, 0x6698}, //14733 #CJK UNIFIED IDEOGRAPH + {0xE5C4, 0xF97A}, //14734 #CJK COMPATIBILITY IDEOGRAPH + {0xE5C5, 0x694A}, //14735 #CJK UNIFIED IDEOGRAPH + {0xE5C6, 0x6A23}, //14736 #CJK UNIFIED IDEOGRAPH + {0xE5C7, 0x6D0B}, //14737 #CJK UNIFIED IDEOGRAPH + {0xE5C8, 0x7001}, //14738 #CJK UNIFIED IDEOGRAPH + {0xE5C9, 0x716C}, //14739 #CJK UNIFIED IDEOGRAPH + {0xE5CA, 0x75D2}, //14740 #CJK UNIFIED IDEOGRAPH + {0xE5CB, 0x760D}, //14741 #CJK UNIFIED IDEOGRAPH + {0xE5CC, 0x79B3}, //14742 #CJK UNIFIED IDEOGRAPH + {0xE5CD, 0x7A70}, //14743 #CJK UNIFIED IDEOGRAPH + {0xE5CE, 0xF97B}, //14744 #CJK COMPATIBILITY IDEOGRAPH + {0xE5CF, 0x7F8A}, //14745 #CJK UNIFIED IDEOGRAPH + {0xE5D0, 0xF97C}, //14746 #CJK COMPATIBILITY IDEOGRAPH + {0xE5D1, 0x8944}, //14747 #CJK UNIFIED IDEOGRAPH + {0xE5D2, 0xF97D}, //14748 #CJK COMPATIBILITY IDEOGRAPH + {0xE5D3, 0x8B93}, //14749 #CJK UNIFIED IDEOGRAPH + {0xE5D4, 0x91C0}, //14750 #CJK UNIFIED IDEOGRAPH + {0xE5D5, 0x967D}, //14751 #CJK UNIFIED IDEOGRAPH + {0xE5D6, 0xF97E}, //14752 #CJK COMPATIBILITY IDEOGRAPH + {0xE5D7, 0x990A}, //14753 #CJK UNIFIED IDEOGRAPH + {0xE5D8, 0x5704}, //14754 #CJK UNIFIED IDEOGRAPH + {0xE5D9, 0x5FA1}, //14755 #CJK UNIFIED IDEOGRAPH + {0xE5DA, 0x65BC}, //14756 #CJK UNIFIED IDEOGRAPH + {0xE5DB, 0x6F01}, //14757 #CJK UNIFIED IDEOGRAPH + {0xE5DC, 0x7600}, //14758 #CJK UNIFIED IDEOGRAPH + {0xE5DD, 0x79A6}, //14759 #CJK UNIFIED IDEOGRAPH + {0xE5DE, 0x8A9E}, //14760 #CJK UNIFIED IDEOGRAPH + {0xE5DF, 0x99AD}, //14761 #CJK UNIFIED IDEOGRAPH + {0xE5E0, 0x9B5A}, //14762 #CJK UNIFIED IDEOGRAPH + {0xE5E1, 0x9F6C}, //14763 #CJK UNIFIED IDEOGRAPH + {0xE5E2, 0x5104}, //14764 #CJK UNIFIED IDEOGRAPH + {0xE5E3, 0x61B6}, //14765 #CJK UNIFIED IDEOGRAPH + {0xE5E4, 0x6291}, //14766 #CJK UNIFIED IDEOGRAPH + {0xE5E5, 0x6A8D}, //14767 #CJK UNIFIED IDEOGRAPH + {0xE5E6, 0x81C6}, //14768 #CJK UNIFIED IDEOGRAPH + {0xE5E7, 0x5043}, //14769 #CJK UNIFIED IDEOGRAPH + {0xE5E8, 0x5830}, //14770 #CJK UNIFIED IDEOGRAPH + {0xE5E9, 0x5F66}, //14771 #CJK UNIFIED IDEOGRAPH + {0xE5EA, 0x7109}, //14772 #CJK UNIFIED IDEOGRAPH + {0xE5EB, 0x8A00}, //14773 #CJK UNIFIED IDEOGRAPH + {0xE5EC, 0x8AFA}, //14774 #CJK UNIFIED IDEOGRAPH + {0xE5ED, 0x5B7C}, //14775 #CJK UNIFIED IDEOGRAPH + {0xE5EE, 0x8616}, //14776 #CJK UNIFIED IDEOGRAPH + {0xE5EF, 0x4FFA}, //14777 #CJK UNIFIED IDEOGRAPH + {0xE5F0, 0x513C}, //14778 #CJK UNIFIED IDEOGRAPH + {0xE5F1, 0x56B4}, //14779 #CJK UNIFIED IDEOGRAPH + {0xE5F2, 0x5944}, //14780 #CJK UNIFIED IDEOGRAPH + {0xE5F3, 0x63A9}, //14781 #CJK UNIFIED IDEOGRAPH + {0xE5F4, 0x6DF9}, //14782 #CJK UNIFIED IDEOGRAPH + {0xE5F5, 0x5DAA}, //14783 #CJK UNIFIED IDEOGRAPH + {0xE5F6, 0x696D}, //14784 #CJK UNIFIED IDEOGRAPH + {0xE5F7, 0x5186}, //14785 #CJK UNIFIED IDEOGRAPH + {0xE5F8, 0x4E88}, //14786 #CJK UNIFIED IDEOGRAPH + {0xE5F9, 0x4F59}, //14787 #CJK UNIFIED IDEOGRAPH + {0xE5FA, 0xF97F}, //14788 #CJK COMPATIBILITY IDEOGRAPH + {0xE5FB, 0xF980}, //14789 #CJK COMPATIBILITY IDEOGRAPH + {0xE5FC, 0xF981}, //14790 #CJK COMPATIBILITY IDEOGRAPH + {0xE5FD, 0x5982}, //14791 #CJK UNIFIED IDEOGRAPH + {0xE5FE, 0xF982}, //14792 #CJK COMPATIBILITY IDEOGRAPH + {0xE6A1, 0xF983}, //14793 #CJK COMPATIBILITY IDEOGRAPH + {0xE6A2, 0x6B5F}, //14794 #CJK UNIFIED IDEOGRAPH + {0xE6A3, 0x6C5D}, //14795 #CJK UNIFIED IDEOGRAPH + {0xE6A4, 0xF984}, //14796 #CJK COMPATIBILITY IDEOGRAPH + {0xE6A5, 0x74B5}, //14797 #CJK UNIFIED IDEOGRAPH + {0xE6A6, 0x7916}, //14798 #CJK UNIFIED IDEOGRAPH + {0xE6A7, 0xF985}, //14799 #CJK COMPATIBILITY IDEOGRAPH + {0xE6A8, 0x8207}, //14800 #CJK UNIFIED IDEOGRAPH + {0xE6A9, 0x8245}, //14801 #CJK UNIFIED IDEOGRAPH + {0xE6AA, 0x8339}, //14802 #CJK UNIFIED IDEOGRAPH + {0xE6AB, 0x8F3F}, //14803 #CJK UNIFIED IDEOGRAPH + {0xE6AC, 0x8F5D}, //14804 #CJK UNIFIED IDEOGRAPH + {0xE6AD, 0xF986}, //14805 #CJK COMPATIBILITY IDEOGRAPH + {0xE6AE, 0x9918}, //14806 #CJK UNIFIED IDEOGRAPH + {0xE6AF, 0xF987}, //14807 #CJK COMPATIBILITY IDEOGRAPH + {0xE6B0, 0xF988}, //14808 #CJK COMPATIBILITY IDEOGRAPH + {0xE6B1, 0xF989}, //14809 #CJK COMPATIBILITY IDEOGRAPH + {0xE6B2, 0x4EA6}, //14810 #CJK UNIFIED IDEOGRAPH + {0xE6B3, 0xF98A}, //14811 #CJK COMPATIBILITY IDEOGRAPH + {0xE6B4, 0x57DF}, //14812 #CJK UNIFIED IDEOGRAPH + {0xE6B5, 0x5F79}, //14813 #CJK UNIFIED IDEOGRAPH + {0xE6B6, 0x6613}, //14814 #CJK UNIFIED IDEOGRAPH + {0xE6B7, 0xF98B}, //14815 #CJK COMPATIBILITY IDEOGRAPH + {0xE6B8, 0xF98C}, //14816 #CJK COMPATIBILITY IDEOGRAPH + {0xE6B9, 0x75AB}, //14817 #CJK UNIFIED IDEOGRAPH + {0xE6BA, 0x7E79}, //14818 #CJK UNIFIED IDEOGRAPH + {0xE6BB, 0x8B6F}, //14819 #CJK UNIFIED IDEOGRAPH + {0xE6BC, 0xF98D}, //14820 #CJK COMPATIBILITY IDEOGRAPH + {0xE6BD, 0x9006}, //14821 #CJK UNIFIED IDEOGRAPH + {0xE6BE, 0x9A5B}, //14822 #CJK UNIFIED IDEOGRAPH + {0xE6BF, 0x56A5}, //14823 #CJK UNIFIED IDEOGRAPH + {0xE6C0, 0x5827}, //14824 #CJK UNIFIED IDEOGRAPH + {0xE6C1, 0x59F8}, //14825 #CJK UNIFIED IDEOGRAPH + {0xE6C2, 0x5A1F}, //14826 #CJK UNIFIED IDEOGRAPH + {0xE6C3, 0x5BB4}, //14827 #CJK UNIFIED IDEOGRAPH + {0xE6C4, 0xF98E}, //14828 #CJK COMPATIBILITY IDEOGRAPH + {0xE6C5, 0x5EF6}, //14829 #CJK UNIFIED IDEOGRAPH + {0xE6C6, 0xF98F}, //14830 #CJK COMPATIBILITY IDEOGRAPH + {0xE6C7, 0xF990}, //14831 #CJK COMPATIBILITY IDEOGRAPH + {0xE6C8, 0x6350}, //14832 #CJK UNIFIED IDEOGRAPH + {0xE6C9, 0x633B}, //14833 #CJK UNIFIED IDEOGRAPH + {0xE6CA, 0xF991}, //14834 #CJK COMPATIBILITY IDEOGRAPH + {0xE6CB, 0x693D}, //14835 #CJK UNIFIED IDEOGRAPH + {0xE6CC, 0x6C87}, //14836 #CJK UNIFIED IDEOGRAPH + {0xE6CD, 0x6CBF}, //14837 #CJK UNIFIED IDEOGRAPH + {0xE6CE, 0x6D8E}, //14838 #CJK UNIFIED IDEOGRAPH + {0xE6CF, 0x6D93}, //14839 #CJK UNIFIED IDEOGRAPH + {0xE6D0, 0x6DF5}, //14840 #CJK UNIFIED IDEOGRAPH + {0xE6D1, 0x6F14}, //14841 #CJK UNIFIED IDEOGRAPH + {0xE6D2, 0xF992}, //14842 #CJK COMPATIBILITY IDEOGRAPH + {0xE6D3, 0x70DF}, //14843 #CJK UNIFIED IDEOGRAPH + {0xE6D4, 0x7136}, //14844 #CJK UNIFIED IDEOGRAPH + {0xE6D5, 0x7159}, //14845 #CJK UNIFIED IDEOGRAPH + {0xE6D6, 0xF993}, //14846 #CJK COMPATIBILITY IDEOGRAPH + {0xE6D7, 0x71C3}, //14847 #CJK UNIFIED IDEOGRAPH + {0xE6D8, 0x71D5}, //14848 #CJK UNIFIED IDEOGRAPH + {0xE6D9, 0xF994}, //14849 #CJK COMPATIBILITY IDEOGRAPH + {0xE6DA, 0x784F}, //14850 #CJK UNIFIED IDEOGRAPH + {0xE6DB, 0x786F}, //14851 #CJK UNIFIED IDEOGRAPH + {0xE6DC, 0xF995}, //14852 #CJK COMPATIBILITY IDEOGRAPH + {0xE6DD, 0x7B75}, //14853 #CJK UNIFIED IDEOGRAPH + {0xE6DE, 0x7DE3}, //14854 #CJK UNIFIED IDEOGRAPH + {0xE6DF, 0xF996}, //14855 #CJK COMPATIBILITY IDEOGRAPH + {0xE6E0, 0x7E2F}, //14856 #CJK UNIFIED IDEOGRAPH + {0xE6E1, 0xF997}, //14857 #CJK COMPATIBILITY IDEOGRAPH + {0xE6E2, 0x884D}, //14858 #CJK UNIFIED IDEOGRAPH + {0xE6E3, 0x8EDF}, //14859 #CJK UNIFIED IDEOGRAPH + {0xE6E4, 0xF998}, //14860 #CJK COMPATIBILITY IDEOGRAPH + {0xE6E5, 0xF999}, //14861 #CJK COMPATIBILITY IDEOGRAPH + {0xE6E6, 0xF99A}, //14862 #CJK COMPATIBILITY IDEOGRAPH + {0xE6E7, 0x925B}, //14863 #CJK UNIFIED IDEOGRAPH + {0xE6E8, 0xF99B}, //14864 #CJK COMPATIBILITY IDEOGRAPH + {0xE6E9, 0x9CF6}, //14865 #CJK UNIFIED IDEOGRAPH + {0xE6EA, 0xF99C}, //14866 #CJK COMPATIBILITY IDEOGRAPH + {0xE6EB, 0xF99D}, //14867 #CJK COMPATIBILITY IDEOGRAPH + {0xE6EC, 0xF99E}, //14868 #CJK COMPATIBILITY IDEOGRAPH + {0xE6ED, 0x6085}, //14869 #CJK UNIFIED IDEOGRAPH + {0xE6EE, 0x6D85}, //14870 #CJK UNIFIED IDEOGRAPH + {0xE6EF, 0xF99F}, //14871 #CJK COMPATIBILITY IDEOGRAPH + {0xE6F0, 0x71B1}, //14872 #CJK UNIFIED IDEOGRAPH + {0xE6F1, 0xF9A0}, //14873 #CJK COMPATIBILITY IDEOGRAPH + {0xE6F2, 0xF9A1}, //14874 #CJK COMPATIBILITY IDEOGRAPH + {0xE6F3, 0x95B1}, //14875 #CJK UNIFIED IDEOGRAPH + {0xE6F4, 0x53AD}, //14876 #CJK UNIFIED IDEOGRAPH + {0xE6F5, 0xF9A2}, //14877 #CJK COMPATIBILITY IDEOGRAPH + {0xE6F6, 0xF9A3}, //14878 #CJK COMPATIBILITY IDEOGRAPH + {0xE6F7, 0xF9A4}, //14879 #CJK COMPATIBILITY IDEOGRAPH + {0xE6F8, 0x67D3}, //14880 #CJK UNIFIED IDEOGRAPH + {0xE6F9, 0xF9A5}, //14881 #CJK COMPATIBILITY IDEOGRAPH + {0xE6FA, 0x708E}, //14882 #CJK UNIFIED IDEOGRAPH + {0xE6FB, 0x7130}, //14883 #CJK UNIFIED IDEOGRAPH + {0xE6FC, 0x7430}, //14884 #CJK UNIFIED IDEOGRAPH + {0xE6FD, 0x8276}, //14885 #CJK UNIFIED IDEOGRAPH + {0xE6FE, 0x82D2}, //14886 #CJK UNIFIED IDEOGRAPH + {0xE7A1, 0xF9A6}, //14887 #CJK COMPATIBILITY IDEOGRAPH + {0xE7A2, 0x95BB}, //14888 #CJK UNIFIED IDEOGRAPH + {0xE7A3, 0x9AE5}, //14889 #CJK UNIFIED IDEOGRAPH + {0xE7A4, 0x9E7D}, //14890 #CJK UNIFIED IDEOGRAPH + {0xE7A5, 0x66C4}, //14891 #CJK UNIFIED IDEOGRAPH + {0xE7A6, 0xF9A7}, //14892 #CJK COMPATIBILITY IDEOGRAPH + {0xE7A7, 0x71C1}, //14893 #CJK UNIFIED IDEOGRAPH + {0xE7A8, 0x8449}, //14894 #CJK UNIFIED IDEOGRAPH + {0xE7A9, 0xF9A8}, //14895 #CJK COMPATIBILITY IDEOGRAPH + {0xE7AA, 0xF9A9}, //14896 #CJK COMPATIBILITY IDEOGRAPH + {0xE7AB, 0x584B}, //14897 #CJK UNIFIED IDEOGRAPH + {0xE7AC, 0xF9AA}, //14898 #CJK COMPATIBILITY IDEOGRAPH + {0xE7AD, 0xF9AB}, //14899 #CJK COMPATIBILITY IDEOGRAPH + {0xE7AE, 0x5DB8}, //14900 #CJK UNIFIED IDEOGRAPH + {0xE7AF, 0x5F71}, //14901 #CJK UNIFIED IDEOGRAPH + {0xE7B0, 0xF9AC}, //14902 #CJK COMPATIBILITY IDEOGRAPH + {0xE7B1, 0x6620}, //14903 #CJK UNIFIED IDEOGRAPH + {0xE7B2, 0x668E}, //14904 #CJK UNIFIED IDEOGRAPH + {0xE7B3, 0x6979}, //14905 #CJK UNIFIED IDEOGRAPH + {0xE7B4, 0x69AE}, //14906 #CJK UNIFIED IDEOGRAPH + {0xE7B5, 0x6C38}, //14907 #CJK UNIFIED IDEOGRAPH + {0xE7B6, 0x6CF3}, //14908 #CJK UNIFIED IDEOGRAPH + {0xE7B7, 0x6E36}, //14909 #CJK UNIFIED IDEOGRAPH + {0xE7B8, 0x6F41}, //14910 #CJK UNIFIED IDEOGRAPH + {0xE7B9, 0x6FDA}, //14911 #CJK UNIFIED IDEOGRAPH + {0xE7BA, 0x701B}, //14912 #CJK UNIFIED IDEOGRAPH + {0xE7BB, 0x702F}, //14913 #CJK UNIFIED IDEOGRAPH + {0xE7BC, 0x7150}, //14914 #CJK UNIFIED IDEOGRAPH + {0xE7BD, 0x71DF}, //14915 #CJK UNIFIED IDEOGRAPH + {0xE7BE, 0x7370}, //14916 #CJK UNIFIED IDEOGRAPH + {0xE7BF, 0xF9AD}, //14917 #CJK COMPATIBILITY IDEOGRAPH + {0xE7C0, 0x745B}, //14918 #CJK UNIFIED IDEOGRAPH + {0xE7C1, 0xF9AE}, //14919 #CJK COMPATIBILITY IDEOGRAPH + {0xE7C2, 0x74D4}, //14920 #CJK UNIFIED IDEOGRAPH + {0xE7C3, 0x76C8}, //14921 #CJK UNIFIED IDEOGRAPH + {0xE7C4, 0x7A4E}, //14922 #CJK UNIFIED IDEOGRAPH + {0xE7C5, 0x7E93}, //14923 #CJK UNIFIED IDEOGRAPH + {0xE7C6, 0xF9AF}, //14924 #CJK COMPATIBILITY IDEOGRAPH + {0xE7C7, 0xF9B0}, //14925 #CJK COMPATIBILITY IDEOGRAPH + {0xE7C8, 0x82F1}, //14926 #CJK UNIFIED IDEOGRAPH + {0xE7C9, 0x8A60}, //14927 #CJK UNIFIED IDEOGRAPH + {0xE7CA, 0x8FCE}, //14928 #CJK UNIFIED IDEOGRAPH + {0xE7CB, 0xF9B1}, //14929 #CJK COMPATIBILITY IDEOGRAPH + {0xE7CC, 0x9348}, //14930 #CJK UNIFIED IDEOGRAPH + {0xE7CD, 0xF9B2}, //14931 #CJK COMPATIBILITY IDEOGRAPH + {0xE7CE, 0x9719}, //14932 #CJK UNIFIED IDEOGRAPH + {0xE7CF, 0xF9B3}, //14933 #CJK COMPATIBILITY IDEOGRAPH + {0xE7D0, 0xF9B4}, //14934 #CJK COMPATIBILITY IDEOGRAPH + {0xE7D1, 0x4E42}, //14935 #CJK UNIFIED IDEOGRAPH + {0xE7D2, 0x502A}, //14936 #CJK UNIFIED IDEOGRAPH + {0xE7D3, 0xF9B5}, //14937 #CJK COMPATIBILITY IDEOGRAPH + {0xE7D4, 0x5208}, //14938 #CJK UNIFIED IDEOGRAPH + {0xE7D5, 0x53E1}, //14939 #CJK UNIFIED IDEOGRAPH + {0xE7D6, 0x66F3}, //14940 #CJK UNIFIED IDEOGRAPH + {0xE7D7, 0x6C6D}, //14941 #CJK UNIFIED IDEOGRAPH + {0xE7D8, 0x6FCA}, //14942 #CJK UNIFIED IDEOGRAPH + {0xE7D9, 0x730A}, //14943 #CJK UNIFIED IDEOGRAPH + {0xE7DA, 0x777F}, //14944 #CJK UNIFIED IDEOGRAPH + {0xE7DB, 0x7A62}, //14945 #CJK UNIFIED IDEOGRAPH + {0xE7DC, 0x82AE}, //14946 #CJK UNIFIED IDEOGRAPH + {0xE7DD, 0x85DD}, //14947 #CJK UNIFIED IDEOGRAPH + {0xE7DE, 0x8602}, //14948 #CJK UNIFIED IDEOGRAPH + {0xE7DF, 0xF9B6}, //14949 #CJK COMPATIBILITY IDEOGRAPH + {0xE7E0, 0x88D4}, //14950 #CJK UNIFIED IDEOGRAPH + {0xE7E1, 0x8A63}, //14951 #CJK UNIFIED IDEOGRAPH + {0xE7E2, 0x8B7D}, //14952 #CJK UNIFIED IDEOGRAPH + {0xE7E3, 0x8C6B}, //14953 #CJK UNIFIED IDEOGRAPH + {0xE7E4, 0xF9B7}, //14954 #CJK COMPATIBILITY IDEOGRAPH + {0xE7E5, 0x92B3}, //14955 #CJK UNIFIED IDEOGRAPH + {0xE7E6, 0xF9B8}, //14956 #CJK COMPATIBILITY IDEOGRAPH + {0xE7E7, 0x9713}, //14957 #CJK UNIFIED IDEOGRAPH + {0xE7E8, 0x9810}, //14958 #CJK UNIFIED IDEOGRAPH + {0xE7E9, 0x4E94}, //14959 #CJK UNIFIED IDEOGRAPH + {0xE7EA, 0x4F0D}, //14960 #CJK UNIFIED IDEOGRAPH + {0xE7EB, 0x4FC9}, //14961 #CJK UNIFIED IDEOGRAPH + {0xE7EC, 0x50B2}, //14962 #CJK UNIFIED IDEOGRAPH + {0xE7ED, 0x5348}, //14963 #CJK UNIFIED IDEOGRAPH + {0xE7EE, 0x543E}, //14964 #CJK UNIFIED IDEOGRAPH + {0xE7EF, 0x5433}, //14965 #CJK UNIFIED IDEOGRAPH + {0xE7F0, 0x55DA}, //14966 #CJK UNIFIED IDEOGRAPH + {0xE7F1, 0x5862}, //14967 #CJK UNIFIED IDEOGRAPH + {0xE7F2, 0x58BA}, //14968 #CJK UNIFIED IDEOGRAPH + {0xE7F3, 0x5967}, //14969 #CJK UNIFIED IDEOGRAPH + {0xE7F4, 0x5A1B}, //14970 #CJK UNIFIED IDEOGRAPH + {0xE7F5, 0x5BE4}, //14971 #CJK UNIFIED IDEOGRAPH + {0xE7F6, 0x609F}, //14972 #CJK UNIFIED IDEOGRAPH + {0xE7F7, 0xF9B9}, //14973 #CJK COMPATIBILITY IDEOGRAPH + {0xE7F8, 0x61CA}, //14974 #CJK UNIFIED IDEOGRAPH + {0xE7F9, 0x6556}, //14975 #CJK UNIFIED IDEOGRAPH + {0xE7FA, 0x65FF}, //14976 #CJK UNIFIED IDEOGRAPH + {0xE7FB, 0x6664}, //14977 #CJK UNIFIED IDEOGRAPH + {0xE7FC, 0x68A7}, //14978 #CJK UNIFIED IDEOGRAPH + {0xE7FD, 0x6C5A}, //14979 #CJK UNIFIED IDEOGRAPH + {0xE7FE, 0x6FB3}, //14980 #CJK UNIFIED IDEOGRAPH + {0xE8A1, 0x70CF}, //14981 #CJK UNIFIED IDEOGRAPH + {0xE8A2, 0x71AC}, //14982 #CJK UNIFIED IDEOGRAPH + {0xE8A3, 0x7352}, //14983 #CJK UNIFIED IDEOGRAPH + {0xE8A4, 0x7B7D}, //14984 #CJK UNIFIED IDEOGRAPH + {0xE8A5, 0x8708}, //14985 #CJK UNIFIED IDEOGRAPH + {0xE8A6, 0x8AA4}, //14986 #CJK UNIFIED IDEOGRAPH + {0xE8A7, 0x9C32}, //14987 #CJK UNIFIED IDEOGRAPH + {0xE8A8, 0x9F07}, //14988 #CJK UNIFIED IDEOGRAPH + {0xE8A9, 0x5C4B}, //14989 #CJK UNIFIED IDEOGRAPH + {0xE8AA, 0x6C83}, //14990 #CJK UNIFIED IDEOGRAPH + {0xE8AB, 0x7344}, //14991 #CJK UNIFIED IDEOGRAPH + {0xE8AC, 0x7389}, //14992 #CJK UNIFIED IDEOGRAPH + {0xE8AD, 0x923A}, //14993 #CJK UNIFIED IDEOGRAPH + {0xE8AE, 0x6EAB}, //14994 #CJK UNIFIED IDEOGRAPH + {0xE8AF, 0x7465}, //14995 #CJK UNIFIED IDEOGRAPH + {0xE8B0, 0x761F}, //14996 #CJK UNIFIED IDEOGRAPH + {0xE8B1, 0x7A69}, //14997 #CJK UNIFIED IDEOGRAPH + {0xE8B2, 0x7E15}, //14998 #CJK UNIFIED IDEOGRAPH + {0xE8B3, 0x860A}, //14999 #CJK UNIFIED IDEOGRAPH + {0xE8B4, 0x5140}, //15000 #CJK UNIFIED IDEOGRAPH + {0xE8B5, 0x58C5}, //15001 #CJK UNIFIED IDEOGRAPH + {0xE8B6, 0x64C1}, //15002 #CJK UNIFIED IDEOGRAPH + {0xE8B7, 0x74EE}, //15003 #CJK UNIFIED IDEOGRAPH + {0xE8B8, 0x7515}, //15004 #CJK UNIFIED IDEOGRAPH + {0xE8B9, 0x7670}, //15005 #CJK UNIFIED IDEOGRAPH + {0xE8BA, 0x7FC1}, //15006 #CJK UNIFIED IDEOGRAPH + {0xE8BB, 0x9095}, //15007 #CJK UNIFIED IDEOGRAPH + {0xE8BC, 0x96CD}, //15008 #CJK UNIFIED IDEOGRAPH + {0xE8BD, 0x9954}, //15009 #CJK UNIFIED IDEOGRAPH + {0xE8BE, 0x6E26}, //15010 #CJK UNIFIED IDEOGRAPH + {0xE8BF, 0x74E6}, //15011 #CJK UNIFIED IDEOGRAPH + {0xE8C0, 0x7AA9}, //15012 #CJK UNIFIED IDEOGRAPH + {0xE8C1, 0x7AAA}, //15013 #CJK UNIFIED IDEOGRAPH + {0xE8C2, 0x81E5}, //15014 #CJK UNIFIED IDEOGRAPH + {0xE8C3, 0x86D9}, //15015 #CJK UNIFIED IDEOGRAPH + {0xE8C4, 0x8778}, //15016 #CJK UNIFIED IDEOGRAPH + {0xE8C5, 0x8A1B}, //15017 #CJK UNIFIED IDEOGRAPH + {0xE8C6, 0x5A49}, //15018 #CJK UNIFIED IDEOGRAPH + {0xE8C7, 0x5B8C}, //15019 #CJK UNIFIED IDEOGRAPH + {0xE8C8, 0x5B9B}, //15020 #CJK UNIFIED IDEOGRAPH + {0xE8C9, 0x68A1}, //15021 #CJK UNIFIED IDEOGRAPH + {0xE8CA, 0x6900}, //15022 #CJK UNIFIED IDEOGRAPH + {0xE8CB, 0x6D63}, //15023 #CJK UNIFIED IDEOGRAPH + {0xE8CC, 0x73A9}, //15024 #CJK UNIFIED IDEOGRAPH + {0xE8CD, 0x7413}, //15025 #CJK UNIFIED IDEOGRAPH + {0xE8CE, 0x742C}, //15026 #CJK UNIFIED IDEOGRAPH + {0xE8CF, 0x7897}, //15027 #CJK UNIFIED IDEOGRAPH + {0xE8D0, 0x7DE9}, //15028 #CJK UNIFIED IDEOGRAPH + {0xE8D1, 0x7FEB}, //15029 #CJK UNIFIED IDEOGRAPH + {0xE8D2, 0x8118}, //15030 #CJK UNIFIED IDEOGRAPH + {0xE8D3, 0x8155}, //15031 #CJK UNIFIED IDEOGRAPH + {0xE8D4, 0x839E}, //15032 #CJK UNIFIED IDEOGRAPH + {0xE8D5, 0x8C4C}, //15033 #CJK UNIFIED IDEOGRAPH + {0xE8D6, 0x962E}, //15034 #CJK UNIFIED IDEOGRAPH + {0xE8D7, 0x9811}, //15035 #CJK UNIFIED IDEOGRAPH + {0xE8D8, 0x66F0}, //15036 #CJK UNIFIED IDEOGRAPH + {0xE8D9, 0x5F80}, //15037 #CJK UNIFIED IDEOGRAPH + {0xE8DA, 0x65FA}, //15038 #CJK UNIFIED IDEOGRAPH + {0xE8DB, 0x6789}, //15039 #CJK UNIFIED IDEOGRAPH + {0xE8DC, 0x6C6A}, //15040 #CJK UNIFIED IDEOGRAPH + {0xE8DD, 0x738B}, //15041 #CJK UNIFIED IDEOGRAPH + {0xE8DE, 0x502D}, //15042 #CJK UNIFIED IDEOGRAPH + {0xE8DF, 0x5A03}, //15043 #CJK UNIFIED IDEOGRAPH + {0xE8E0, 0x6B6A}, //15044 #CJK UNIFIED IDEOGRAPH + {0xE8E1, 0x77EE}, //15045 #CJK UNIFIED IDEOGRAPH + {0xE8E2, 0x5916}, //15046 #CJK UNIFIED IDEOGRAPH + {0xE8E3, 0x5D6C}, //15047 #CJK UNIFIED IDEOGRAPH + {0xE8E4, 0x5DCD}, //15048 #CJK UNIFIED IDEOGRAPH + {0xE8E5, 0x7325}, //15049 #CJK UNIFIED IDEOGRAPH + {0xE8E6, 0x754F}, //15050 #CJK UNIFIED IDEOGRAPH + {0xE8E7, 0xF9BA}, //15051 #CJK COMPATIBILITY IDEOGRAPH + {0xE8E8, 0xF9BB}, //15052 #CJK COMPATIBILITY IDEOGRAPH + {0xE8E9, 0x50E5}, //15053 #CJK UNIFIED IDEOGRAPH + {0xE8EA, 0x51F9}, //15054 #CJK UNIFIED IDEOGRAPH + {0xE8EB, 0x582F}, //15055 #CJK UNIFIED IDEOGRAPH + {0xE8EC, 0x592D}, //15056 #CJK UNIFIED IDEOGRAPH + {0xE8ED, 0x5996}, //15057 #CJK UNIFIED IDEOGRAPH + {0xE8EE, 0x59DA}, //15058 #CJK UNIFIED IDEOGRAPH + {0xE8EF, 0x5BE5}, //15059 #CJK UNIFIED IDEOGRAPH + {0xE8F0, 0xF9BC}, //15060 #CJK COMPATIBILITY IDEOGRAPH + {0xE8F1, 0xF9BD}, //15061 #CJK COMPATIBILITY IDEOGRAPH + {0xE8F2, 0x5DA2}, //15062 #CJK UNIFIED IDEOGRAPH + {0xE8F3, 0x62D7}, //15063 #CJK UNIFIED IDEOGRAPH + {0xE8F4, 0x6416}, //15064 #CJK UNIFIED IDEOGRAPH + {0xE8F5, 0x6493}, //15065 #CJK UNIFIED IDEOGRAPH + {0xE8F6, 0x64FE}, //15066 #CJK UNIFIED IDEOGRAPH + {0xE8F7, 0xF9BE}, //15067 #CJK COMPATIBILITY IDEOGRAPH + {0xE8F8, 0x66DC}, //15068 #CJK UNIFIED IDEOGRAPH + {0xE8F9, 0xF9BF}, //15069 #CJK COMPATIBILITY IDEOGRAPH + {0xE8FA, 0x6A48}, //15070 #CJK UNIFIED IDEOGRAPH + {0xE8FB, 0xF9C0}, //15071 #CJK COMPATIBILITY IDEOGRAPH + {0xE8FC, 0x71FF}, //15072 #CJK UNIFIED IDEOGRAPH + {0xE8FD, 0x7464}, //15073 #CJK UNIFIED IDEOGRAPH + {0xE8FE, 0xF9C1}, //15074 #CJK COMPATIBILITY IDEOGRAPH + {0xE9A1, 0x7A88}, //15075 #CJK UNIFIED IDEOGRAPH + {0xE9A2, 0x7AAF}, //15076 #CJK UNIFIED IDEOGRAPH + {0xE9A3, 0x7E47}, //15077 #CJK UNIFIED IDEOGRAPH + {0xE9A4, 0x7E5E}, //15078 #CJK UNIFIED IDEOGRAPH + {0xE9A5, 0x8000}, //15079 #CJK UNIFIED IDEOGRAPH + {0xE9A6, 0x8170}, //15080 #CJK UNIFIED IDEOGRAPH + {0xE9A7, 0xF9C2}, //15081 #CJK COMPATIBILITY IDEOGRAPH + {0xE9A8, 0x87EF}, //15082 #CJK UNIFIED IDEOGRAPH + {0xE9A9, 0x8981}, //15083 #CJK UNIFIED IDEOGRAPH + {0xE9AA, 0x8B20}, //15084 #CJK UNIFIED IDEOGRAPH + {0xE9AB, 0x9059}, //15085 #CJK UNIFIED IDEOGRAPH + {0xE9AC, 0xF9C3}, //15086 #CJK COMPATIBILITY IDEOGRAPH + {0xE9AD, 0x9080}, //15087 #CJK UNIFIED IDEOGRAPH + {0xE9AE, 0x9952}, //15088 #CJK UNIFIED IDEOGRAPH + {0xE9AF, 0x617E}, //15089 #CJK UNIFIED IDEOGRAPH + {0xE9B0, 0x6B32}, //15090 #CJK UNIFIED IDEOGRAPH + {0xE9B1, 0x6D74}, //15091 #CJK UNIFIED IDEOGRAPH + {0xE9B2, 0x7E1F}, //15092 #CJK UNIFIED IDEOGRAPH + {0xE9B3, 0x8925}, //15093 #CJK UNIFIED IDEOGRAPH + {0xE9B4, 0x8FB1}, //15094 #CJK UNIFIED IDEOGRAPH + {0xE9B5, 0x4FD1}, //15095 #CJK UNIFIED IDEOGRAPH + {0xE9B6, 0x50AD}, //15096 #CJK UNIFIED IDEOGRAPH + {0xE9B7, 0x5197}, //15097 #CJK UNIFIED IDEOGRAPH + {0xE9B8, 0x52C7}, //15098 #CJK UNIFIED IDEOGRAPH + {0xE9B9, 0x57C7}, //15099 #CJK UNIFIED IDEOGRAPH + {0xE9BA, 0x5889}, //15100 #CJK UNIFIED IDEOGRAPH + {0xE9BB, 0x5BB9}, //15101 #CJK UNIFIED IDEOGRAPH + {0xE9BC, 0x5EB8}, //15102 #CJK UNIFIED IDEOGRAPH + {0xE9BD, 0x6142}, //15103 #CJK UNIFIED IDEOGRAPH + {0xE9BE, 0x6995}, //15104 #CJK UNIFIED IDEOGRAPH + {0xE9BF, 0x6D8C}, //15105 #CJK UNIFIED IDEOGRAPH + {0xE9C0, 0x6E67}, //15106 #CJK UNIFIED IDEOGRAPH + {0xE9C1, 0x6EB6}, //15107 #CJK UNIFIED IDEOGRAPH + {0xE9C2, 0x7194}, //15108 #CJK UNIFIED IDEOGRAPH + {0xE9C3, 0x7462}, //15109 #CJK UNIFIED IDEOGRAPH + {0xE9C4, 0x7528}, //15110 #CJK UNIFIED IDEOGRAPH + {0xE9C5, 0x752C}, //15111 #CJK UNIFIED IDEOGRAPH + {0xE9C6, 0x8073}, //15112 #CJK UNIFIED IDEOGRAPH + {0xE9C7, 0x8338}, //15113 #CJK UNIFIED IDEOGRAPH + {0xE9C8, 0x84C9}, //15114 #CJK UNIFIED IDEOGRAPH + {0xE9C9, 0x8E0A}, //15115 #CJK UNIFIED IDEOGRAPH + {0xE9CA, 0x9394}, //15116 #CJK UNIFIED IDEOGRAPH + {0xE9CB, 0x93DE}, //15117 #CJK UNIFIED IDEOGRAPH + {0xE9CC, 0xF9C4}, //15118 #CJK COMPATIBILITY IDEOGRAPH + {0xE9CD, 0x4E8E}, //15119 #CJK UNIFIED IDEOGRAPH + {0xE9CE, 0x4F51}, //15120 #CJK UNIFIED IDEOGRAPH + {0xE9CF, 0x5076}, //15121 #CJK UNIFIED IDEOGRAPH + {0xE9D0, 0x512A}, //15122 #CJK UNIFIED IDEOGRAPH + {0xE9D1, 0x53C8}, //15123 #CJK UNIFIED IDEOGRAPH + {0xE9D2, 0x53CB}, //15124 #CJK UNIFIED IDEOGRAPH + {0xE9D3, 0x53F3}, //15125 #CJK UNIFIED IDEOGRAPH + {0xE9D4, 0x5B87}, //15126 #CJK UNIFIED IDEOGRAPH + {0xE9D5, 0x5BD3}, //15127 #CJK UNIFIED IDEOGRAPH + {0xE9D6, 0x5C24}, //15128 #CJK UNIFIED IDEOGRAPH + {0xE9D7, 0x611A}, //15129 #CJK UNIFIED IDEOGRAPH + {0xE9D8, 0x6182}, //15130 #CJK UNIFIED IDEOGRAPH + {0xE9D9, 0x65F4}, //15131 #CJK UNIFIED IDEOGRAPH + {0xE9DA, 0x725B}, //15132 #CJK UNIFIED IDEOGRAPH + {0xE9DB, 0x7397}, //15133 #CJK UNIFIED IDEOGRAPH + {0xE9DC, 0x7440}, //15134 #CJK UNIFIED IDEOGRAPH + {0xE9DD, 0x76C2}, //15135 #CJK UNIFIED IDEOGRAPH + {0xE9DE, 0x7950}, //15136 #CJK UNIFIED IDEOGRAPH + {0xE9DF, 0x7991}, //15137 #CJK UNIFIED IDEOGRAPH + {0xE9E0, 0x79B9}, //15138 #CJK UNIFIED IDEOGRAPH + {0xE9E1, 0x7D06}, //15139 #CJK UNIFIED IDEOGRAPH + {0xE9E2, 0x7FBD}, //15140 #CJK UNIFIED IDEOGRAPH + {0xE9E3, 0x828B}, //15141 #CJK UNIFIED IDEOGRAPH + {0xE9E4, 0x85D5}, //15142 #CJK UNIFIED IDEOGRAPH + {0xE9E5, 0x865E}, //15143 #CJK UNIFIED IDEOGRAPH + {0xE9E6, 0x8FC2}, //15144 #CJK UNIFIED IDEOGRAPH + {0xE9E7, 0x9047}, //15145 #CJK UNIFIED IDEOGRAPH + {0xE9E8, 0x90F5}, //15146 #CJK UNIFIED IDEOGRAPH + {0xE9E9, 0x91EA}, //15147 #CJK UNIFIED IDEOGRAPH + {0xE9EA, 0x9685}, //15148 #CJK UNIFIED IDEOGRAPH + {0xE9EB, 0x96E8}, //15149 #CJK UNIFIED IDEOGRAPH + {0xE9EC, 0x96E9}, //15150 #CJK UNIFIED IDEOGRAPH + {0xE9ED, 0x52D6}, //15151 #CJK UNIFIED IDEOGRAPH + {0xE9EE, 0x5F67}, //15152 #CJK UNIFIED IDEOGRAPH + {0xE9EF, 0x65ED}, //15153 #CJK UNIFIED IDEOGRAPH + {0xE9F0, 0x6631}, //15154 #CJK UNIFIED IDEOGRAPH + {0xE9F1, 0x682F}, //15155 #CJK UNIFIED IDEOGRAPH + {0xE9F2, 0x715C}, //15156 #CJK UNIFIED IDEOGRAPH + {0xE9F3, 0x7A36}, //15157 #CJK UNIFIED IDEOGRAPH + {0xE9F4, 0x90C1}, //15158 #CJK UNIFIED IDEOGRAPH + {0xE9F5, 0x980A}, //15159 #CJK UNIFIED IDEOGRAPH + {0xE9F6, 0x4E91}, //15160 #CJK UNIFIED IDEOGRAPH + {0xE9F7, 0xF9C5}, //15161 #CJK COMPATIBILITY IDEOGRAPH + {0xE9F8, 0x6A52}, //15162 #CJK UNIFIED IDEOGRAPH + {0xE9F9, 0x6B9E}, //15163 #CJK UNIFIED IDEOGRAPH + {0xE9FA, 0x6F90}, //15164 #CJK UNIFIED IDEOGRAPH + {0xE9FB, 0x7189}, //15165 #CJK UNIFIED IDEOGRAPH + {0xE9FC, 0x8018}, //15166 #CJK UNIFIED IDEOGRAPH + {0xE9FD, 0x82B8}, //15167 #CJK UNIFIED IDEOGRAPH + {0xE9FE, 0x8553}, //15168 #CJK UNIFIED IDEOGRAPH + {0xEAA1, 0x904B}, //15169 #CJK UNIFIED IDEOGRAPH + {0xEAA2, 0x9695}, //15170 #CJK UNIFIED IDEOGRAPH + {0xEAA3, 0x96F2}, //15171 #CJK UNIFIED IDEOGRAPH + {0xEAA4, 0x97FB}, //15172 #CJK UNIFIED IDEOGRAPH + {0xEAA5, 0x851A}, //15173 #CJK UNIFIED IDEOGRAPH + {0xEAA6, 0x9B31}, //15174 #CJK UNIFIED IDEOGRAPH + {0xEAA7, 0x4E90}, //15175 #CJK UNIFIED IDEOGRAPH + {0xEAA8, 0x718A}, //15176 #CJK UNIFIED IDEOGRAPH + {0xEAA9, 0x96C4}, //15177 #CJK UNIFIED IDEOGRAPH + {0xEAAA, 0x5143}, //15178 #CJK UNIFIED IDEOGRAPH + {0xEAAB, 0x539F}, //15179 #CJK UNIFIED IDEOGRAPH + {0xEAAC, 0x54E1}, //15180 #CJK UNIFIED IDEOGRAPH + {0xEAAD, 0x5713}, //15181 #CJK UNIFIED IDEOGRAPH + {0xEAAE, 0x5712}, //15182 #CJK UNIFIED IDEOGRAPH + {0xEAAF, 0x57A3}, //15183 #CJK UNIFIED IDEOGRAPH + {0xEAB0, 0x5A9B}, //15184 #CJK UNIFIED IDEOGRAPH + {0xEAB1, 0x5AC4}, //15185 #CJK UNIFIED IDEOGRAPH + {0xEAB2, 0x5BC3}, //15186 #CJK UNIFIED IDEOGRAPH + {0xEAB3, 0x6028}, //15187 #CJK UNIFIED IDEOGRAPH + {0xEAB4, 0x613F}, //15188 #CJK UNIFIED IDEOGRAPH + {0xEAB5, 0x63F4}, //15189 #CJK UNIFIED IDEOGRAPH + {0xEAB6, 0x6C85}, //15190 #CJK UNIFIED IDEOGRAPH + {0xEAB7, 0x6D39}, //15191 #CJK UNIFIED IDEOGRAPH + {0xEAB8, 0x6E72}, //15192 #CJK UNIFIED IDEOGRAPH + {0xEAB9, 0x6E90}, //15193 #CJK UNIFIED IDEOGRAPH + {0xEABA, 0x7230}, //15194 #CJK UNIFIED IDEOGRAPH + {0xEABB, 0x733F}, //15195 #CJK UNIFIED IDEOGRAPH + {0xEABC, 0x7457}, //15196 #CJK UNIFIED IDEOGRAPH + {0xEABD, 0x82D1}, //15197 #CJK UNIFIED IDEOGRAPH + {0xEABE, 0x8881}, //15198 #CJK UNIFIED IDEOGRAPH + {0xEABF, 0x8F45}, //15199 #CJK UNIFIED IDEOGRAPH + {0xEAC0, 0x9060}, //15200 #CJK UNIFIED IDEOGRAPH + {0xEAC1, 0xF9C6}, //15201 #CJK COMPATIBILITY IDEOGRAPH + {0xEAC2, 0x9662}, //15202 #CJK UNIFIED IDEOGRAPH + {0xEAC3, 0x9858}, //15203 #CJK UNIFIED IDEOGRAPH + {0xEAC4, 0x9D1B}, //15204 #CJK UNIFIED IDEOGRAPH + {0xEAC5, 0x6708}, //15205 #CJK UNIFIED IDEOGRAPH + {0xEAC6, 0x8D8A}, //15206 #CJK UNIFIED IDEOGRAPH + {0xEAC7, 0x925E}, //15207 #CJK UNIFIED IDEOGRAPH + {0xEAC8, 0x4F4D}, //15208 #CJK UNIFIED IDEOGRAPH + {0xEAC9, 0x5049}, //15209 #CJK UNIFIED IDEOGRAPH + {0xEACA, 0x50DE}, //15210 #CJK UNIFIED IDEOGRAPH + {0xEACB, 0x5371}, //15211 #CJK UNIFIED IDEOGRAPH + {0xEACC, 0x570D}, //15212 #CJK UNIFIED IDEOGRAPH + {0xEACD, 0x59D4}, //15213 #CJK UNIFIED IDEOGRAPH + {0xEACE, 0x5A01}, //15214 #CJK UNIFIED IDEOGRAPH + {0xEACF, 0x5C09}, //15215 #CJK UNIFIED IDEOGRAPH + {0xEAD0, 0x6170}, //15216 #CJK UNIFIED IDEOGRAPH + {0xEAD1, 0x6690}, //15217 #CJK UNIFIED IDEOGRAPH + {0xEAD2, 0x6E2D}, //15218 #CJK UNIFIED IDEOGRAPH + {0xEAD3, 0x7232}, //15219 #CJK UNIFIED IDEOGRAPH + {0xEAD4, 0x744B}, //15220 #CJK UNIFIED IDEOGRAPH + {0xEAD5, 0x7DEF}, //15221 #CJK UNIFIED IDEOGRAPH + {0xEAD6, 0x80C3}, //15222 #CJK UNIFIED IDEOGRAPH + {0xEAD7, 0x840E}, //15223 #CJK UNIFIED IDEOGRAPH + {0xEAD8, 0x8466}, //15224 #CJK UNIFIED IDEOGRAPH + {0xEAD9, 0x853F}, //15225 #CJK UNIFIED IDEOGRAPH + {0xEADA, 0x875F}, //15226 #CJK UNIFIED IDEOGRAPH + {0xEADB, 0x885B}, //15227 #CJK UNIFIED IDEOGRAPH + {0xEADC, 0x8918}, //15228 #CJK UNIFIED IDEOGRAPH + {0xEADD, 0x8B02}, //15229 #CJK UNIFIED IDEOGRAPH + {0xEADE, 0x9055}, //15230 #CJK UNIFIED IDEOGRAPH + {0xEADF, 0x97CB}, //15231 #CJK UNIFIED IDEOGRAPH + {0xEAE0, 0x9B4F}, //15232 #CJK UNIFIED IDEOGRAPH + {0xEAE1, 0x4E73}, //15233 #CJK UNIFIED IDEOGRAPH + {0xEAE2, 0x4F91}, //15234 #CJK UNIFIED IDEOGRAPH + {0xEAE3, 0x5112}, //15235 #CJK UNIFIED IDEOGRAPH + {0xEAE4, 0x516A}, //15236 #CJK UNIFIED IDEOGRAPH + {0xEAE5, 0xF9C7}, //15237 #CJK COMPATIBILITY IDEOGRAPH + {0xEAE6, 0x552F}, //15238 #CJK UNIFIED IDEOGRAPH + {0xEAE7, 0x55A9}, //15239 #CJK UNIFIED IDEOGRAPH + {0xEAE8, 0x5B7A}, //15240 #CJK UNIFIED IDEOGRAPH + {0xEAE9, 0x5BA5}, //15241 #CJK UNIFIED IDEOGRAPH + {0xEAEA, 0x5E7C}, //15242 #CJK UNIFIED IDEOGRAPH + {0xEAEB, 0x5E7D}, //15243 #CJK UNIFIED IDEOGRAPH + {0xEAEC, 0x5EBE}, //15244 #CJK UNIFIED IDEOGRAPH + {0xEAED, 0x60A0}, //15245 #CJK UNIFIED IDEOGRAPH + {0xEAEE, 0x60DF}, //15246 #CJK UNIFIED IDEOGRAPH + {0xEAEF, 0x6108}, //15247 #CJK UNIFIED IDEOGRAPH + {0xEAF0, 0x6109}, //15248 #CJK UNIFIED IDEOGRAPH + {0xEAF1, 0x63C4}, //15249 #CJK UNIFIED IDEOGRAPH + {0xEAF2, 0x6538}, //15250 #CJK UNIFIED IDEOGRAPH + {0xEAF3, 0x6709}, //15251 #CJK UNIFIED IDEOGRAPH + {0xEAF4, 0xF9C8}, //15252 #CJK COMPATIBILITY IDEOGRAPH + {0xEAF5, 0x67D4}, //15253 #CJK UNIFIED IDEOGRAPH + {0xEAF6, 0x67DA}, //15254 #CJK UNIFIED IDEOGRAPH + {0xEAF7, 0xF9C9}, //15255 #CJK COMPATIBILITY IDEOGRAPH + {0xEAF8, 0x6961}, //15256 #CJK UNIFIED IDEOGRAPH + {0xEAF9, 0x6962}, //15257 #CJK UNIFIED IDEOGRAPH + {0xEAFA, 0x6CB9}, //15258 #CJK UNIFIED IDEOGRAPH + {0xEAFB, 0x6D27}, //15259 #CJK UNIFIED IDEOGRAPH + {0xEAFC, 0xF9CA}, //15260 #CJK COMPATIBILITY IDEOGRAPH + {0xEAFD, 0x6E38}, //15261 #CJK UNIFIED IDEOGRAPH + {0xEAFE, 0xF9CB}, //15262 #CJK COMPATIBILITY IDEOGRAPH + {0xEBA1, 0x6FE1}, //15263 #CJK UNIFIED IDEOGRAPH + {0xEBA2, 0x7336}, //15264 #CJK UNIFIED IDEOGRAPH + {0xEBA3, 0x7337}, //15265 #CJK UNIFIED IDEOGRAPH + {0xEBA4, 0xF9CC}, //15266 #CJK COMPATIBILITY IDEOGRAPH + {0xEBA5, 0x745C}, //15267 #CJK UNIFIED IDEOGRAPH + {0xEBA6, 0x7531}, //15268 #CJK UNIFIED IDEOGRAPH + {0xEBA7, 0xF9CD}, //15269 #CJK COMPATIBILITY IDEOGRAPH + {0xEBA8, 0x7652}, //15270 #CJK UNIFIED IDEOGRAPH + {0xEBA9, 0xF9CE}, //15271 #CJK COMPATIBILITY IDEOGRAPH + {0xEBAA, 0xF9CF}, //15272 #CJK COMPATIBILITY IDEOGRAPH + {0xEBAB, 0x7DAD}, //15273 #CJK UNIFIED IDEOGRAPH + {0xEBAC, 0x81FE}, //15274 #CJK UNIFIED IDEOGRAPH + {0xEBAD, 0x8438}, //15275 #CJK UNIFIED IDEOGRAPH + {0xEBAE, 0x88D5}, //15276 #CJK UNIFIED IDEOGRAPH + {0xEBAF, 0x8A98}, //15277 #CJK UNIFIED IDEOGRAPH + {0xEBB0, 0x8ADB}, //15278 #CJK UNIFIED IDEOGRAPH + {0xEBB1, 0x8AED}, //15279 #CJK UNIFIED IDEOGRAPH + {0xEBB2, 0x8E30}, //15280 #CJK UNIFIED IDEOGRAPH + {0xEBB3, 0x8E42}, //15281 #CJK UNIFIED IDEOGRAPH + {0xEBB4, 0x904A}, //15282 #CJK UNIFIED IDEOGRAPH + {0xEBB5, 0x903E}, //15283 #CJK UNIFIED IDEOGRAPH + {0xEBB6, 0x907A}, //15284 #CJK UNIFIED IDEOGRAPH + {0xEBB7, 0x9149}, //15285 #CJK UNIFIED IDEOGRAPH + {0xEBB8, 0x91C9}, //15286 #CJK UNIFIED IDEOGRAPH + {0xEBB9, 0x936E}, //15287 #CJK UNIFIED IDEOGRAPH + {0xEBBA, 0xF9D0}, //15288 #CJK COMPATIBILITY IDEOGRAPH + {0xEBBB, 0xF9D1}, //15289 #CJK COMPATIBILITY IDEOGRAPH + {0xEBBC, 0x5809}, //15290 #CJK UNIFIED IDEOGRAPH + {0xEBBD, 0xF9D2}, //15291 #CJK COMPATIBILITY IDEOGRAPH + {0xEBBE, 0x6BD3}, //15292 #CJK UNIFIED IDEOGRAPH + {0xEBBF, 0x8089}, //15293 #CJK UNIFIED IDEOGRAPH + {0xEBC0, 0x80B2}, //15294 #CJK UNIFIED IDEOGRAPH + {0xEBC1, 0xF9D3}, //15295 #CJK COMPATIBILITY IDEOGRAPH + {0xEBC2, 0xF9D4}, //15296 #CJK COMPATIBILITY IDEOGRAPH + {0xEBC3, 0x5141}, //15297 #CJK UNIFIED IDEOGRAPH + {0xEBC4, 0x596B}, //15298 #CJK UNIFIED IDEOGRAPH + {0xEBC5, 0x5C39}, //15299 #CJK UNIFIED IDEOGRAPH + {0xEBC6, 0xF9D5}, //15300 #CJK COMPATIBILITY IDEOGRAPH + {0xEBC7, 0xF9D6}, //15301 #CJK COMPATIBILITY IDEOGRAPH + {0xEBC8, 0x6F64}, //15302 #CJK UNIFIED IDEOGRAPH + {0xEBC9, 0x73A7}, //15303 #CJK UNIFIED IDEOGRAPH + {0xEBCA, 0x80E4}, //15304 #CJK UNIFIED IDEOGRAPH + {0xEBCB, 0x8D07}, //15305 #CJK UNIFIED IDEOGRAPH + {0xEBCC, 0xF9D7}, //15306 #CJK COMPATIBILITY IDEOGRAPH + {0xEBCD, 0x9217}, //15307 #CJK UNIFIED IDEOGRAPH + {0xEBCE, 0x958F}, //15308 #CJK UNIFIED IDEOGRAPH + {0xEBCF, 0xF9D8}, //15309 #CJK COMPATIBILITY IDEOGRAPH + {0xEBD0, 0xF9D9}, //15310 #CJK COMPATIBILITY IDEOGRAPH + {0xEBD1, 0xF9DA}, //15311 #CJK COMPATIBILITY IDEOGRAPH + {0xEBD2, 0xF9DB}, //15312 #CJK COMPATIBILITY IDEOGRAPH + {0xEBD3, 0x807F}, //15313 #CJK UNIFIED IDEOGRAPH + {0xEBD4, 0x620E}, //15314 #CJK UNIFIED IDEOGRAPH + {0xEBD5, 0x701C}, //15315 #CJK UNIFIED IDEOGRAPH + {0xEBD6, 0x7D68}, //15316 #CJK UNIFIED IDEOGRAPH + {0xEBD7, 0x878D}, //15317 #CJK UNIFIED IDEOGRAPH + {0xEBD8, 0xF9DC}, //15318 #CJK COMPATIBILITY IDEOGRAPH + {0xEBD9, 0x57A0}, //15319 #CJK UNIFIED IDEOGRAPH + {0xEBDA, 0x6069}, //15320 #CJK UNIFIED IDEOGRAPH + {0xEBDB, 0x6147}, //15321 #CJK UNIFIED IDEOGRAPH + {0xEBDC, 0x6BB7}, //15322 #CJK UNIFIED IDEOGRAPH + {0xEBDD, 0x8ABE}, //15323 #CJK UNIFIED IDEOGRAPH + {0xEBDE, 0x9280}, //15324 #CJK UNIFIED IDEOGRAPH + {0xEBDF, 0x96B1}, //15325 #CJK UNIFIED IDEOGRAPH + {0xEBE0, 0x4E59}, //15326 #CJK UNIFIED IDEOGRAPH + {0xEBE1, 0x541F}, //15327 #CJK UNIFIED IDEOGRAPH + {0xEBE2, 0x6DEB}, //15328 #CJK UNIFIED IDEOGRAPH + {0xEBE3, 0x852D}, //15329 #CJK UNIFIED IDEOGRAPH + {0xEBE4, 0x9670}, //15330 #CJK UNIFIED IDEOGRAPH + {0xEBE5, 0x97F3}, //15331 #CJK UNIFIED IDEOGRAPH + {0xEBE6, 0x98EE}, //15332 #CJK UNIFIED IDEOGRAPH + {0xEBE7, 0x63D6}, //15333 #CJK UNIFIED IDEOGRAPH + {0xEBE8, 0x6CE3}, //15334 #CJK UNIFIED IDEOGRAPH + {0xEBE9, 0x9091}, //15335 #CJK UNIFIED IDEOGRAPH + {0xEBEA, 0x51DD}, //15336 #CJK UNIFIED IDEOGRAPH + {0xEBEB, 0x61C9}, //15337 #CJK UNIFIED IDEOGRAPH + {0xEBEC, 0x81BA}, //15338 #CJK UNIFIED IDEOGRAPH + {0xEBED, 0x9DF9}, //15339 #CJK UNIFIED IDEOGRAPH + {0xEBEE, 0x4F9D}, //15340 #CJK UNIFIED IDEOGRAPH + {0xEBEF, 0x501A}, //15341 #CJK UNIFIED IDEOGRAPH + {0xEBF0, 0x5100}, //15342 #CJK UNIFIED IDEOGRAPH + {0xEBF1, 0x5B9C}, //15343 #CJK UNIFIED IDEOGRAPH + {0xEBF2, 0x610F}, //15344 #CJK UNIFIED IDEOGRAPH + {0xEBF3, 0x61FF}, //15345 #CJK UNIFIED IDEOGRAPH + {0xEBF4, 0x64EC}, //15346 #CJK UNIFIED IDEOGRAPH + {0xEBF5, 0x6905}, //15347 #CJK UNIFIED IDEOGRAPH + {0xEBF6, 0x6BC5}, //15348 #CJK UNIFIED IDEOGRAPH + {0xEBF7, 0x7591}, //15349 #CJK UNIFIED IDEOGRAPH + {0xEBF8, 0x77E3}, //15350 #CJK UNIFIED IDEOGRAPH + {0xEBF9, 0x7FA9}, //15351 #CJK UNIFIED IDEOGRAPH + {0xEBFA, 0x8264}, //15352 #CJK UNIFIED IDEOGRAPH + {0xEBFB, 0x858F}, //15353 #CJK UNIFIED IDEOGRAPH + {0xEBFC, 0x87FB}, //15354 #CJK UNIFIED IDEOGRAPH + {0xEBFD, 0x8863}, //15355 #CJK UNIFIED IDEOGRAPH + {0xEBFE, 0x8ABC}, //15356 #CJK UNIFIED IDEOGRAPH + {0xECA1, 0x8B70}, //15357 #CJK UNIFIED IDEOGRAPH + {0xECA2, 0x91AB}, //15358 #CJK UNIFIED IDEOGRAPH + {0xECA3, 0x4E8C}, //15359 #CJK UNIFIED IDEOGRAPH + {0xECA4, 0x4EE5}, //15360 #CJK UNIFIED IDEOGRAPH + {0xECA5, 0x4F0A}, //15361 #CJK UNIFIED IDEOGRAPH + {0xECA6, 0xF9DD}, //15362 #CJK COMPATIBILITY IDEOGRAPH + {0xECA7, 0xF9DE}, //15363 #CJK COMPATIBILITY IDEOGRAPH + {0xECA8, 0x5937}, //15364 #CJK UNIFIED IDEOGRAPH + {0xECA9, 0x59E8}, //15365 #CJK UNIFIED IDEOGRAPH + {0xECAA, 0xF9DF}, //15366 #CJK COMPATIBILITY IDEOGRAPH + {0xECAB, 0x5DF2}, //15367 #CJK UNIFIED IDEOGRAPH + {0xECAC, 0x5F1B}, //15368 #CJK UNIFIED IDEOGRAPH + {0xECAD, 0x5F5B}, //15369 #CJK UNIFIED IDEOGRAPH + {0xECAE, 0x6021}, //15370 #CJK UNIFIED IDEOGRAPH + {0xECAF, 0xF9E0}, //15371 #CJK COMPATIBILITY IDEOGRAPH + {0xECB0, 0xF9E1}, //15372 #CJK COMPATIBILITY IDEOGRAPH + {0xECB1, 0xF9E2}, //15373 #CJK COMPATIBILITY IDEOGRAPH + {0xECB2, 0xF9E3}, //15374 #CJK COMPATIBILITY IDEOGRAPH + {0xECB3, 0x723E}, //15375 #CJK UNIFIED IDEOGRAPH + {0xECB4, 0x73E5}, //15376 #CJK UNIFIED IDEOGRAPH + {0xECB5, 0xF9E4}, //15377 #CJK COMPATIBILITY IDEOGRAPH + {0xECB6, 0x7570}, //15378 #CJK UNIFIED IDEOGRAPH + {0xECB7, 0x75CD}, //15379 #CJK UNIFIED IDEOGRAPH + {0xECB8, 0xF9E5}, //15380 #CJK COMPATIBILITY IDEOGRAPH + {0xECB9, 0x79FB}, //15381 #CJK UNIFIED IDEOGRAPH + {0xECBA, 0xF9E6}, //15382 #CJK COMPATIBILITY IDEOGRAPH + {0xECBB, 0x800C}, //15383 #CJK UNIFIED IDEOGRAPH + {0xECBC, 0x8033}, //15384 #CJK UNIFIED IDEOGRAPH + {0xECBD, 0x8084}, //15385 #CJK UNIFIED IDEOGRAPH + {0xECBE, 0x82E1}, //15386 #CJK UNIFIED IDEOGRAPH + {0xECBF, 0x8351}, //15387 #CJK UNIFIED IDEOGRAPH + {0xECC0, 0xF9E7}, //15388 #CJK COMPATIBILITY IDEOGRAPH + {0xECC1, 0xF9E8}, //15389 #CJK COMPATIBILITY IDEOGRAPH + {0xECC2, 0x8CBD}, //15390 #CJK UNIFIED IDEOGRAPH + {0xECC3, 0x8CB3}, //15391 #CJK UNIFIED IDEOGRAPH + {0xECC4, 0x9087}, //15392 #CJK UNIFIED IDEOGRAPH + {0xECC5, 0xF9E9}, //15393 #CJK COMPATIBILITY IDEOGRAPH + {0xECC6, 0xF9EA}, //15394 #CJK COMPATIBILITY IDEOGRAPH + {0xECC7, 0x98F4}, //15395 #CJK UNIFIED IDEOGRAPH + {0xECC8, 0x990C}, //15396 #CJK UNIFIED IDEOGRAPH + {0xECC9, 0xF9EB}, //15397 #CJK COMPATIBILITY IDEOGRAPH + {0xECCA, 0xF9EC}, //15398 #CJK COMPATIBILITY IDEOGRAPH + {0xECCB, 0x7037}, //15399 #CJK UNIFIED IDEOGRAPH + {0xECCC, 0x76CA}, //15400 #CJK UNIFIED IDEOGRAPH + {0xECCD, 0x7FCA}, //15401 #CJK UNIFIED IDEOGRAPH + {0xECCE, 0x7FCC}, //15402 #CJK UNIFIED IDEOGRAPH + {0xECCF, 0x7FFC}, //15403 #CJK UNIFIED IDEOGRAPH + {0xECD0, 0x8B1A}, //15404 #CJK UNIFIED IDEOGRAPH + {0xECD1, 0x4EBA}, //15405 #CJK UNIFIED IDEOGRAPH + {0xECD2, 0x4EC1}, //15406 #CJK UNIFIED IDEOGRAPH + {0xECD3, 0x5203}, //15407 #CJK UNIFIED IDEOGRAPH + {0xECD4, 0x5370}, //15408 #CJK UNIFIED IDEOGRAPH + {0xECD5, 0xF9ED}, //15409 #CJK COMPATIBILITY IDEOGRAPH + {0xECD6, 0x54BD}, //15410 #CJK UNIFIED IDEOGRAPH + {0xECD7, 0x56E0}, //15411 #CJK UNIFIED IDEOGRAPH + {0xECD8, 0x59FB}, //15412 #CJK UNIFIED IDEOGRAPH + {0xECD9, 0x5BC5}, //15413 #CJK UNIFIED IDEOGRAPH + {0xECDA, 0x5F15}, //15414 #CJK UNIFIED IDEOGRAPH + {0xECDB, 0x5FCD}, //15415 #CJK UNIFIED IDEOGRAPH + {0xECDC, 0x6E6E}, //15416 #CJK UNIFIED IDEOGRAPH + {0xECDD, 0xF9EE}, //15417 #CJK COMPATIBILITY IDEOGRAPH + {0xECDE, 0xF9EF}, //15418 #CJK COMPATIBILITY IDEOGRAPH + {0xECDF, 0x7D6A}, //15419 #CJK UNIFIED IDEOGRAPH + {0xECE0, 0x8335}, //15420 #CJK UNIFIED IDEOGRAPH + {0xECE1, 0xF9F0}, //15421 #CJK COMPATIBILITY IDEOGRAPH + {0xECE2, 0x8693}, //15422 #CJK UNIFIED IDEOGRAPH + {0xECE3, 0x8A8D}, //15423 #CJK UNIFIED IDEOGRAPH + {0xECE4, 0xF9F1}, //15424 #CJK COMPATIBILITY IDEOGRAPH + {0xECE5, 0x976D}, //15425 #CJK UNIFIED IDEOGRAPH + {0xECE6, 0x9777}, //15426 #CJK UNIFIED IDEOGRAPH + {0xECE7, 0xF9F2}, //15427 #CJK COMPATIBILITY IDEOGRAPH + {0xECE8, 0xF9F3}, //15428 #CJK COMPATIBILITY IDEOGRAPH + {0xECE9, 0x4E00}, //15429 #CJK UNIFIED IDEOGRAPH + {0xECEA, 0x4F5A}, //15430 #CJK UNIFIED IDEOGRAPH + {0xECEB, 0x4F7E}, //15431 #CJK UNIFIED IDEOGRAPH + {0xECEC, 0x58F9}, //15432 #CJK UNIFIED IDEOGRAPH + {0xECED, 0x65E5}, //15433 #CJK UNIFIED IDEOGRAPH + {0xECEE, 0x6EA2}, //15434 #CJK UNIFIED IDEOGRAPH + {0xECEF, 0x9038}, //15435 #CJK UNIFIED IDEOGRAPH + {0xECF0, 0x93B0}, //15436 #CJK UNIFIED IDEOGRAPH + {0xECF1, 0x99B9}, //15437 #CJK UNIFIED IDEOGRAPH + {0xECF2, 0x4EFB}, //15438 #CJK UNIFIED IDEOGRAPH + {0xECF3, 0x58EC}, //15439 #CJK UNIFIED IDEOGRAPH + {0xECF4, 0x598A}, //15440 #CJK UNIFIED IDEOGRAPH + {0xECF5, 0x59D9}, //15441 #CJK UNIFIED IDEOGRAPH + {0xECF6, 0x6041}, //15442 #CJK UNIFIED IDEOGRAPH + {0xECF7, 0xF9F4}, //15443 #CJK COMPATIBILITY IDEOGRAPH + {0xECF8, 0xF9F5}, //15444 #CJK COMPATIBILITY IDEOGRAPH + {0xECF9, 0x7A14}, //15445 #CJK UNIFIED IDEOGRAPH + {0xECFA, 0xF9F6}, //15446 #CJK COMPATIBILITY IDEOGRAPH + {0xECFB, 0x834F}, //15447 #CJK UNIFIED IDEOGRAPH + {0xECFC, 0x8CC3}, //15448 #CJK UNIFIED IDEOGRAPH + {0xECFD, 0x5165}, //15449 #CJK UNIFIED IDEOGRAPH + {0xECFE, 0x5344}, //15450 #CJK UNIFIED IDEOGRAPH + {0xEDA1, 0xF9F7}, //15451 #CJK COMPATIBILITY IDEOGRAPH + {0xEDA2, 0xF9F8}, //15452 #CJK COMPATIBILITY IDEOGRAPH + {0xEDA3, 0xF9F9}, //15453 #CJK COMPATIBILITY IDEOGRAPH + {0xEDA4, 0x4ECD}, //15454 #CJK UNIFIED IDEOGRAPH + {0xEDA5, 0x5269}, //15455 #CJK UNIFIED IDEOGRAPH + {0xEDA6, 0x5B55}, //15456 #CJK UNIFIED IDEOGRAPH + {0xEDA7, 0x82BF}, //15457 #CJK UNIFIED IDEOGRAPH + {0xEDA8, 0x4ED4}, //15458 #CJK UNIFIED IDEOGRAPH + {0xEDA9, 0x523A}, //15459 #CJK UNIFIED IDEOGRAPH + {0xEDAA, 0x54A8}, //15460 #CJK UNIFIED IDEOGRAPH + {0xEDAB, 0x59C9}, //15461 #CJK UNIFIED IDEOGRAPH + {0xEDAC, 0x59FF}, //15462 #CJK UNIFIED IDEOGRAPH + {0xEDAD, 0x5B50}, //15463 #CJK UNIFIED IDEOGRAPH + {0xEDAE, 0x5B57}, //15464 #CJK UNIFIED IDEOGRAPH + {0xEDAF, 0x5B5C}, //15465 #CJK UNIFIED IDEOGRAPH + {0xEDB0, 0x6063}, //15466 #CJK UNIFIED IDEOGRAPH + {0xEDB1, 0x6148}, //15467 #CJK UNIFIED IDEOGRAPH + {0xEDB2, 0x6ECB}, //15468 #CJK UNIFIED IDEOGRAPH + {0xEDB3, 0x7099}, //15469 #CJK UNIFIED IDEOGRAPH + {0xEDB4, 0x716E}, //15470 #CJK UNIFIED IDEOGRAPH + {0xEDB5, 0x7386}, //15471 #CJK UNIFIED IDEOGRAPH + {0xEDB6, 0x74F7}, //15472 #CJK UNIFIED IDEOGRAPH + {0xEDB7, 0x75B5}, //15473 #CJK UNIFIED IDEOGRAPH + {0xEDB8, 0x78C1}, //15474 #CJK UNIFIED IDEOGRAPH + {0xEDB9, 0x7D2B}, //15475 #CJK UNIFIED IDEOGRAPH + {0xEDBA, 0x8005}, //15476 #CJK UNIFIED IDEOGRAPH + {0xEDBB, 0x81EA}, //15477 #CJK UNIFIED IDEOGRAPH + {0xEDBC, 0x8328}, //15478 #CJK UNIFIED IDEOGRAPH + {0xEDBD, 0x8517}, //15479 #CJK UNIFIED IDEOGRAPH + {0xEDBE, 0x85C9}, //15480 #CJK UNIFIED IDEOGRAPH + {0xEDBF, 0x8AEE}, //15481 #CJK UNIFIED IDEOGRAPH + {0xEDC0, 0x8CC7}, //15482 #CJK UNIFIED IDEOGRAPH + {0xEDC1, 0x96CC}, //15483 #CJK UNIFIED IDEOGRAPH + {0xEDC2, 0x4F5C}, //15484 #CJK UNIFIED IDEOGRAPH + {0xEDC3, 0x52FA}, //15485 #CJK UNIFIED IDEOGRAPH + {0xEDC4, 0x56BC}, //15486 #CJK UNIFIED IDEOGRAPH + {0xEDC5, 0x65AB}, //15487 #CJK UNIFIED IDEOGRAPH + {0xEDC6, 0x6628}, //15488 #CJK UNIFIED IDEOGRAPH + {0xEDC7, 0x707C}, //15489 #CJK UNIFIED IDEOGRAPH + {0xEDC8, 0x70B8}, //15490 #CJK UNIFIED IDEOGRAPH + {0xEDC9, 0x7235}, //15491 #CJK UNIFIED IDEOGRAPH + {0xEDCA, 0x7DBD}, //15492 #CJK UNIFIED IDEOGRAPH + {0xEDCB, 0x828D}, //15493 #CJK UNIFIED IDEOGRAPH + {0xEDCC, 0x914C}, //15494 #CJK UNIFIED IDEOGRAPH + {0xEDCD, 0x96C0}, //15495 #CJK UNIFIED IDEOGRAPH + {0xEDCE, 0x9D72}, //15496 #CJK UNIFIED IDEOGRAPH + {0xEDCF, 0x5B71}, //15497 #CJK UNIFIED IDEOGRAPH + {0xEDD0, 0x68E7}, //15498 #CJK UNIFIED IDEOGRAPH + {0xEDD1, 0x6B98}, //15499 #CJK UNIFIED IDEOGRAPH + {0xEDD2, 0x6F7A}, //15500 #CJK UNIFIED IDEOGRAPH + {0xEDD3, 0x76DE}, //15501 #CJK UNIFIED IDEOGRAPH + {0xEDD4, 0x5C91}, //15502 #CJK UNIFIED IDEOGRAPH + {0xEDD5, 0x66AB}, //15503 #CJK UNIFIED IDEOGRAPH + {0xEDD6, 0x6F5B}, //15504 #CJK UNIFIED IDEOGRAPH + {0xEDD7, 0x7BB4}, //15505 #CJK UNIFIED IDEOGRAPH + {0xEDD8, 0x7C2A}, //15506 #CJK UNIFIED IDEOGRAPH + {0xEDD9, 0x8836}, //15507 #CJK UNIFIED IDEOGRAPH + {0xEDDA, 0x96DC}, //15508 #CJK UNIFIED IDEOGRAPH + {0xEDDB, 0x4E08}, //15509 #CJK UNIFIED IDEOGRAPH + {0xEDDC, 0x4ED7}, //15510 #CJK UNIFIED IDEOGRAPH + {0xEDDD, 0x5320}, //15511 #CJK UNIFIED IDEOGRAPH + {0xEDDE, 0x5834}, //15512 #CJK UNIFIED IDEOGRAPH + {0xEDDF, 0x58BB}, //15513 #CJK UNIFIED IDEOGRAPH + {0xEDE0, 0x58EF}, //15514 #CJK UNIFIED IDEOGRAPH + {0xEDE1, 0x596C}, //15515 #CJK UNIFIED IDEOGRAPH + {0xEDE2, 0x5C07}, //15516 #CJK UNIFIED IDEOGRAPH + {0xEDE3, 0x5E33}, //15517 #CJK UNIFIED IDEOGRAPH + {0xEDE4, 0x5E84}, //15518 #CJK UNIFIED IDEOGRAPH + {0xEDE5, 0x5F35}, //15519 #CJK UNIFIED IDEOGRAPH + {0xEDE6, 0x638C}, //15520 #CJK UNIFIED IDEOGRAPH + {0xEDE7, 0x66B2}, //15521 #CJK UNIFIED IDEOGRAPH + {0xEDE8, 0x6756}, //15522 #CJK UNIFIED IDEOGRAPH + {0xEDE9, 0x6A1F}, //15523 #CJK UNIFIED IDEOGRAPH + {0xEDEA, 0x6AA3}, //15524 #CJK UNIFIED IDEOGRAPH + {0xEDEB, 0x6B0C}, //15525 #CJK UNIFIED IDEOGRAPH + {0xEDEC, 0x6F3F}, //15526 #CJK UNIFIED IDEOGRAPH + {0xEDED, 0x7246}, //15527 #CJK UNIFIED IDEOGRAPH + {0xEDEE, 0xF9FA}, //15528 #CJK COMPATIBILITY IDEOGRAPH + {0xEDEF, 0x7350}, //15529 #CJK UNIFIED IDEOGRAPH + {0xEDF0, 0x748B}, //15530 #CJK UNIFIED IDEOGRAPH + {0xEDF1, 0x7AE0}, //15531 #CJK UNIFIED IDEOGRAPH + {0xEDF2, 0x7CA7}, //15532 #CJK UNIFIED IDEOGRAPH + {0xEDF3, 0x8178}, //15533 #CJK UNIFIED IDEOGRAPH + {0xEDF4, 0x81DF}, //15534 #CJK UNIFIED IDEOGRAPH + {0xEDF5, 0x81E7}, //15535 #CJK UNIFIED IDEOGRAPH + {0xEDF6, 0x838A}, //15536 #CJK UNIFIED IDEOGRAPH + {0xEDF7, 0x846C}, //15537 #CJK UNIFIED IDEOGRAPH + {0xEDF8, 0x8523}, //15538 #CJK UNIFIED IDEOGRAPH + {0xEDF9, 0x8594}, //15539 #CJK UNIFIED IDEOGRAPH + {0xEDFA, 0x85CF}, //15540 #CJK UNIFIED IDEOGRAPH + {0xEDFB, 0x88DD}, //15541 #CJK UNIFIED IDEOGRAPH + {0xEDFC, 0x8D13}, //15542 #CJK UNIFIED IDEOGRAPH + {0xEDFD, 0x91AC}, //15543 #CJK UNIFIED IDEOGRAPH + {0xEDFE, 0x9577}, //15544 #CJK UNIFIED IDEOGRAPH + {0xEEA1, 0x969C}, //15545 #CJK UNIFIED IDEOGRAPH + {0xEEA2, 0x518D}, //15546 #CJK UNIFIED IDEOGRAPH + {0xEEA3, 0x54C9}, //15547 #CJK UNIFIED IDEOGRAPH + {0xEEA4, 0x5728}, //15548 #CJK UNIFIED IDEOGRAPH + {0xEEA5, 0x5BB0}, //15549 #CJK UNIFIED IDEOGRAPH + {0xEEA6, 0x624D}, //15550 #CJK UNIFIED IDEOGRAPH + {0xEEA7, 0x6750}, //15551 #CJK UNIFIED IDEOGRAPH + {0xEEA8, 0x683D}, //15552 #CJK UNIFIED IDEOGRAPH + {0xEEA9, 0x6893}, //15553 #CJK UNIFIED IDEOGRAPH + {0xEEAA, 0x6E3D}, //15554 #CJK UNIFIED IDEOGRAPH + {0xEEAB, 0x6ED3}, //15555 #CJK UNIFIED IDEOGRAPH + {0xEEAC, 0x707D}, //15556 #CJK UNIFIED IDEOGRAPH + {0xEEAD, 0x7E21}, //15557 #CJK UNIFIED IDEOGRAPH + {0xEEAE, 0x88C1}, //15558 #CJK UNIFIED IDEOGRAPH + {0xEEAF, 0x8CA1}, //15559 #CJK UNIFIED IDEOGRAPH + {0xEEB0, 0x8F09}, //15560 #CJK UNIFIED IDEOGRAPH + {0xEEB1, 0x9F4B}, //15561 #CJK UNIFIED IDEOGRAPH + {0xEEB2, 0x9F4E}, //15562 #CJK UNIFIED IDEOGRAPH + {0xEEB3, 0x722D}, //15563 #CJK UNIFIED IDEOGRAPH + {0xEEB4, 0x7B8F}, //15564 #CJK UNIFIED IDEOGRAPH + {0xEEB5, 0x8ACD}, //15565 #CJK UNIFIED IDEOGRAPH + {0xEEB6, 0x931A}, //15566 #CJK UNIFIED IDEOGRAPH + {0xEEB7, 0x4F47}, //15567 #CJK UNIFIED IDEOGRAPH + {0xEEB8, 0x4F4E}, //15568 #CJK UNIFIED IDEOGRAPH + {0xEEB9, 0x5132}, //15569 #CJK UNIFIED IDEOGRAPH + {0xEEBA, 0x5480}, //15570 #CJK UNIFIED IDEOGRAPH + {0xEEBB, 0x59D0}, //15571 #CJK UNIFIED IDEOGRAPH + {0xEEBC, 0x5E95}, //15572 #CJK UNIFIED IDEOGRAPH + {0xEEBD, 0x62B5}, //15573 #CJK UNIFIED IDEOGRAPH + {0xEEBE, 0x6775}, //15574 #CJK UNIFIED IDEOGRAPH + {0xEEBF, 0x696E}, //15575 #CJK UNIFIED IDEOGRAPH + {0xEEC0, 0x6A17}, //15576 #CJK UNIFIED IDEOGRAPH + {0xEEC1, 0x6CAE}, //15577 #CJK UNIFIED IDEOGRAPH + {0xEEC2, 0x6E1A}, //15578 #CJK UNIFIED IDEOGRAPH + {0xEEC3, 0x72D9}, //15579 #CJK UNIFIED IDEOGRAPH + {0xEEC4, 0x732A}, //15580 #CJK UNIFIED IDEOGRAPH + {0xEEC5, 0x75BD}, //15581 #CJK UNIFIED IDEOGRAPH + {0xEEC6, 0x7BB8}, //15582 #CJK UNIFIED IDEOGRAPH + {0xEEC7, 0x7D35}, //15583 #CJK UNIFIED IDEOGRAPH + {0xEEC8, 0x82E7}, //15584 #CJK UNIFIED IDEOGRAPH + {0xEEC9, 0x83F9}, //15585 #CJK UNIFIED IDEOGRAPH + {0xEECA, 0x8457}, //15586 #CJK UNIFIED IDEOGRAPH + {0xEECB, 0x85F7}, //15587 #CJK UNIFIED IDEOGRAPH + {0xEECC, 0x8A5B}, //15588 #CJK UNIFIED IDEOGRAPH + {0xEECD, 0x8CAF}, //15589 #CJK UNIFIED IDEOGRAPH + {0xEECE, 0x8E87}, //15590 #CJK UNIFIED IDEOGRAPH + {0xEECF, 0x9019}, //15591 #CJK UNIFIED IDEOGRAPH + {0xEED0, 0x90B8}, //15592 #CJK UNIFIED IDEOGRAPH + {0xEED1, 0x96CE}, //15593 #CJK UNIFIED IDEOGRAPH + {0xEED2, 0x9F5F}, //15594 #CJK UNIFIED IDEOGRAPH + {0xEED3, 0x52E3}, //15595 #CJK UNIFIED IDEOGRAPH + {0xEED4, 0x540A}, //15596 #CJK UNIFIED IDEOGRAPH + {0xEED5, 0x5AE1}, //15597 #CJK UNIFIED IDEOGRAPH + {0xEED6, 0x5BC2}, //15598 #CJK UNIFIED IDEOGRAPH + {0xEED7, 0x6458}, //15599 #CJK UNIFIED IDEOGRAPH + {0xEED8, 0x6575}, //15600 #CJK UNIFIED IDEOGRAPH + {0xEED9, 0x6EF4}, //15601 #CJK UNIFIED IDEOGRAPH + {0xEEDA, 0x72C4}, //15602 #CJK UNIFIED IDEOGRAPH + {0xEEDB, 0xF9FB}, //15603 #CJK COMPATIBILITY IDEOGRAPH + {0xEEDC, 0x7684}, //15604 #CJK UNIFIED IDEOGRAPH + {0xEEDD, 0x7A4D}, //15605 #CJK UNIFIED IDEOGRAPH + {0xEEDE, 0x7B1B}, //15606 #CJK UNIFIED IDEOGRAPH + {0xEEDF, 0x7C4D}, //15607 #CJK UNIFIED IDEOGRAPH + {0xEEE0, 0x7E3E}, //15608 #CJK UNIFIED IDEOGRAPH + {0xEEE1, 0x7FDF}, //15609 #CJK UNIFIED IDEOGRAPH + {0xEEE2, 0x837B}, //15610 #CJK UNIFIED IDEOGRAPH + {0xEEE3, 0x8B2B}, //15611 #CJK UNIFIED IDEOGRAPH + {0xEEE4, 0x8CCA}, //15612 #CJK UNIFIED IDEOGRAPH + {0xEEE5, 0x8D64}, //15613 #CJK UNIFIED IDEOGRAPH + {0xEEE6, 0x8DE1}, //15614 #CJK UNIFIED IDEOGRAPH + {0xEEE7, 0x8E5F}, //15615 #CJK UNIFIED IDEOGRAPH + {0xEEE8, 0x8FEA}, //15616 #CJK UNIFIED IDEOGRAPH + {0xEEE9, 0x8FF9}, //15617 #CJK UNIFIED IDEOGRAPH + {0xEEEA, 0x9069}, //15618 #CJK UNIFIED IDEOGRAPH + {0xEEEB, 0x93D1}, //15619 #CJK UNIFIED IDEOGRAPH + {0xEEEC, 0x4F43}, //15620 #CJK UNIFIED IDEOGRAPH + {0xEEED, 0x4F7A}, //15621 #CJK UNIFIED IDEOGRAPH + {0xEEEE, 0x50B3}, //15622 #CJK UNIFIED IDEOGRAPH + {0xEEEF, 0x5168}, //15623 #CJK UNIFIED IDEOGRAPH + {0xEEF0, 0x5178}, //15624 #CJK UNIFIED IDEOGRAPH + {0xEEF1, 0x524D}, //15625 #CJK UNIFIED IDEOGRAPH + {0xEEF2, 0x526A}, //15626 #CJK UNIFIED IDEOGRAPH + {0xEEF3, 0x5861}, //15627 #CJK UNIFIED IDEOGRAPH + {0xEEF4, 0x587C}, //15628 #CJK UNIFIED IDEOGRAPH + {0xEEF5, 0x5960}, //15629 #CJK UNIFIED IDEOGRAPH + {0xEEF6, 0x5C08}, //15630 #CJK UNIFIED IDEOGRAPH + {0xEEF7, 0x5C55}, //15631 #CJK UNIFIED IDEOGRAPH + {0xEEF8, 0x5EDB}, //15632 #CJK UNIFIED IDEOGRAPH + {0xEEF9, 0x609B}, //15633 #CJK UNIFIED IDEOGRAPH + {0xEEFA, 0x6230}, //15634 #CJK UNIFIED IDEOGRAPH + {0xEEFB, 0x6813}, //15635 #CJK UNIFIED IDEOGRAPH + {0xEEFC, 0x6BBF}, //15636 #CJK UNIFIED IDEOGRAPH + {0xEEFD, 0x6C08}, //15637 #CJK UNIFIED IDEOGRAPH + {0xEEFE, 0x6FB1}, //15638 #CJK UNIFIED IDEOGRAPH + {0xEFA1, 0x714E}, //15639 #CJK UNIFIED IDEOGRAPH + {0xEFA2, 0x7420}, //15640 #CJK UNIFIED IDEOGRAPH + {0xEFA3, 0x7530}, //15641 #CJK UNIFIED IDEOGRAPH + {0xEFA4, 0x7538}, //15642 #CJK UNIFIED IDEOGRAPH + {0xEFA5, 0x7551}, //15643 #CJK UNIFIED IDEOGRAPH + {0xEFA6, 0x7672}, //15644 #CJK UNIFIED IDEOGRAPH + {0xEFA7, 0x7B4C}, //15645 #CJK UNIFIED IDEOGRAPH + {0xEFA8, 0x7B8B}, //15646 #CJK UNIFIED IDEOGRAPH + {0xEFA9, 0x7BAD}, //15647 #CJK UNIFIED IDEOGRAPH + {0xEFAA, 0x7BC6}, //15648 #CJK UNIFIED IDEOGRAPH + {0xEFAB, 0x7E8F}, //15649 #CJK UNIFIED IDEOGRAPH + {0xEFAC, 0x8A6E}, //15650 #CJK UNIFIED IDEOGRAPH + {0xEFAD, 0x8F3E}, //15651 #CJK UNIFIED IDEOGRAPH + {0xEFAE, 0x8F49}, //15652 #CJK UNIFIED IDEOGRAPH + {0xEFAF, 0x923F}, //15653 #CJK UNIFIED IDEOGRAPH + {0xEFB0, 0x9293}, //15654 #CJK UNIFIED IDEOGRAPH + {0xEFB1, 0x9322}, //15655 #CJK UNIFIED IDEOGRAPH + {0xEFB2, 0x942B}, //15656 #CJK UNIFIED IDEOGRAPH + {0xEFB3, 0x96FB}, //15657 #CJK UNIFIED IDEOGRAPH + {0xEFB4, 0x985A}, //15658 #CJK UNIFIED IDEOGRAPH + {0xEFB5, 0x986B}, //15659 #CJK UNIFIED IDEOGRAPH + {0xEFB6, 0x991E}, //15660 #CJK UNIFIED IDEOGRAPH + {0xEFB7, 0x5207}, //15661 #CJK UNIFIED IDEOGRAPH + {0xEFB8, 0x622A}, //15662 #CJK UNIFIED IDEOGRAPH + {0xEFB9, 0x6298}, //15663 #CJK UNIFIED IDEOGRAPH + {0xEFBA, 0x6D59}, //15664 #CJK UNIFIED IDEOGRAPH + {0xEFBB, 0x7664}, //15665 #CJK UNIFIED IDEOGRAPH + {0xEFBC, 0x7ACA}, //15666 #CJK UNIFIED IDEOGRAPH + {0xEFBD, 0x7BC0}, //15667 #CJK UNIFIED IDEOGRAPH + {0xEFBE, 0x7D76}, //15668 #CJK UNIFIED IDEOGRAPH + {0xEFBF, 0x5360}, //15669 #CJK UNIFIED IDEOGRAPH + {0xEFC0, 0x5CBE}, //15670 #CJK UNIFIED IDEOGRAPH + {0xEFC1, 0x5E97}, //15671 #CJK UNIFIED IDEOGRAPH + {0xEFC2, 0x6F38}, //15672 #CJK UNIFIED IDEOGRAPH + {0xEFC3, 0x70B9}, //15673 #CJK UNIFIED IDEOGRAPH + {0xEFC4, 0x7C98}, //15674 #CJK UNIFIED IDEOGRAPH + {0xEFC5, 0x9711}, //15675 #CJK UNIFIED IDEOGRAPH + {0xEFC6, 0x9B8E}, //15676 #CJK UNIFIED IDEOGRAPH + {0xEFC7, 0x9EDE}, //15677 #CJK UNIFIED IDEOGRAPH + {0xEFC8, 0x63A5}, //15678 #CJK UNIFIED IDEOGRAPH + {0xEFC9, 0x647A}, //15679 #CJK UNIFIED IDEOGRAPH + {0xEFCA, 0x8776}, //15680 #CJK UNIFIED IDEOGRAPH + {0xEFCB, 0x4E01}, //15681 #CJK UNIFIED IDEOGRAPH + {0xEFCC, 0x4E95}, //15682 #CJK UNIFIED IDEOGRAPH + {0xEFCD, 0x4EAD}, //15683 #CJK UNIFIED IDEOGRAPH + {0xEFCE, 0x505C}, //15684 #CJK UNIFIED IDEOGRAPH + {0xEFCF, 0x5075}, //15685 #CJK UNIFIED IDEOGRAPH + {0xEFD0, 0x5448}, //15686 #CJK UNIFIED IDEOGRAPH + {0xEFD1, 0x59C3}, //15687 #CJK UNIFIED IDEOGRAPH + {0xEFD2, 0x5B9A}, //15688 #CJK UNIFIED IDEOGRAPH + {0xEFD3, 0x5E40}, //15689 #CJK UNIFIED IDEOGRAPH + {0xEFD4, 0x5EAD}, //15690 #CJK UNIFIED IDEOGRAPH + {0xEFD5, 0x5EF7}, //15691 #CJK UNIFIED IDEOGRAPH + {0xEFD6, 0x5F81}, //15692 #CJK UNIFIED IDEOGRAPH + {0xEFD7, 0x60C5}, //15693 #CJK UNIFIED IDEOGRAPH + {0xEFD8, 0x633A}, //15694 #CJK UNIFIED IDEOGRAPH + {0xEFD9, 0x653F}, //15695 #CJK UNIFIED IDEOGRAPH + {0xEFDA, 0x6574}, //15696 #CJK UNIFIED IDEOGRAPH + {0xEFDB, 0x65CC}, //15697 #CJK UNIFIED IDEOGRAPH + {0xEFDC, 0x6676}, //15698 #CJK UNIFIED IDEOGRAPH + {0xEFDD, 0x6678}, //15699 #CJK UNIFIED IDEOGRAPH + {0xEFDE, 0x67FE}, //15700 #CJK UNIFIED IDEOGRAPH + {0xEFDF, 0x6968}, //15701 #CJK UNIFIED IDEOGRAPH + {0xEFE0, 0x6A89}, //15702 #CJK UNIFIED IDEOGRAPH + {0xEFE1, 0x6B63}, //15703 #CJK UNIFIED IDEOGRAPH + {0xEFE2, 0x6C40}, //15704 #CJK UNIFIED IDEOGRAPH + {0xEFE3, 0x6DC0}, //15705 #CJK UNIFIED IDEOGRAPH + {0xEFE4, 0x6DE8}, //15706 #CJK UNIFIED IDEOGRAPH + {0xEFE5, 0x6E1F}, //15707 #CJK UNIFIED IDEOGRAPH + {0xEFE6, 0x6E5E}, //15708 #CJK UNIFIED IDEOGRAPH + {0xEFE7, 0x701E}, //15709 #CJK UNIFIED IDEOGRAPH + {0xEFE8, 0x70A1}, //15710 #CJK UNIFIED IDEOGRAPH + {0xEFE9, 0x738E}, //15711 #CJK UNIFIED IDEOGRAPH + {0xEFEA, 0x73FD}, //15712 #CJK UNIFIED IDEOGRAPH + {0xEFEB, 0x753A}, //15713 #CJK UNIFIED IDEOGRAPH + {0xEFEC, 0x775B}, //15714 #CJK UNIFIED IDEOGRAPH + {0xEFED, 0x7887}, //15715 #CJK UNIFIED IDEOGRAPH + {0xEFEE, 0x798E}, //15716 #CJK UNIFIED IDEOGRAPH + {0xEFEF, 0x7A0B}, //15717 #CJK UNIFIED IDEOGRAPH + {0xEFF0, 0x7A7D}, //15718 #CJK UNIFIED IDEOGRAPH + {0xEFF1, 0x7CBE}, //15719 #CJK UNIFIED IDEOGRAPH + {0xEFF2, 0x7D8E}, //15720 #CJK UNIFIED IDEOGRAPH + {0xEFF3, 0x8247}, //15721 #CJK UNIFIED IDEOGRAPH + {0xEFF4, 0x8A02}, //15722 #CJK UNIFIED IDEOGRAPH + {0xEFF5, 0x8AEA}, //15723 #CJK UNIFIED IDEOGRAPH + {0xEFF6, 0x8C9E}, //15724 #CJK UNIFIED IDEOGRAPH + {0xEFF7, 0x912D}, //15725 #CJK UNIFIED IDEOGRAPH + {0xEFF8, 0x914A}, //15726 #CJK UNIFIED IDEOGRAPH + {0xEFF9, 0x91D8}, //15727 #CJK UNIFIED IDEOGRAPH + {0xEFFA, 0x9266}, //15728 #CJK UNIFIED IDEOGRAPH + {0xEFFB, 0x92CC}, //15729 #CJK UNIFIED IDEOGRAPH + {0xEFFC, 0x9320}, //15730 #CJK UNIFIED IDEOGRAPH + {0xEFFD, 0x9706}, //15731 #CJK UNIFIED IDEOGRAPH + {0xEFFE, 0x9756}, //15732 #CJK UNIFIED IDEOGRAPH + {0xF0A1, 0x975C}, //15733 #CJK UNIFIED IDEOGRAPH + {0xF0A2, 0x9802}, //15734 #CJK UNIFIED IDEOGRAPH + {0xF0A3, 0x9F0E}, //15735 #CJK UNIFIED IDEOGRAPH + {0xF0A4, 0x5236}, //15736 #CJK UNIFIED IDEOGRAPH + {0xF0A5, 0x5291}, //15737 #CJK UNIFIED IDEOGRAPH + {0xF0A6, 0x557C}, //15738 #CJK UNIFIED IDEOGRAPH + {0xF0A7, 0x5824}, //15739 #CJK UNIFIED IDEOGRAPH + {0xF0A8, 0x5E1D}, //15740 #CJK UNIFIED IDEOGRAPH + {0xF0A9, 0x5F1F}, //15741 #CJK UNIFIED IDEOGRAPH + {0xF0AA, 0x608C}, //15742 #CJK UNIFIED IDEOGRAPH + {0xF0AB, 0x63D0}, //15743 #CJK UNIFIED IDEOGRAPH + {0xF0AC, 0x68AF}, //15744 #CJK UNIFIED IDEOGRAPH + {0xF0AD, 0x6FDF}, //15745 #CJK UNIFIED IDEOGRAPH + {0xF0AE, 0x796D}, //15746 #CJK UNIFIED IDEOGRAPH + {0xF0AF, 0x7B2C}, //15747 #CJK UNIFIED IDEOGRAPH + {0xF0B0, 0x81CD}, //15748 #CJK UNIFIED IDEOGRAPH + {0xF0B1, 0x85BA}, //15749 #CJK UNIFIED IDEOGRAPH + {0xF0B2, 0x88FD}, //15750 #CJK UNIFIED IDEOGRAPH + {0xF0B3, 0x8AF8}, //15751 #CJK UNIFIED IDEOGRAPH + {0xF0B4, 0x8E44}, //15752 #CJK UNIFIED IDEOGRAPH + {0xF0B5, 0x918D}, //15753 #CJK UNIFIED IDEOGRAPH + {0xF0B6, 0x9664}, //15754 #CJK UNIFIED IDEOGRAPH + {0xF0B7, 0x969B}, //15755 #CJK UNIFIED IDEOGRAPH + {0xF0B8, 0x973D}, //15756 #CJK UNIFIED IDEOGRAPH + {0xF0B9, 0x984C}, //15757 #CJK UNIFIED IDEOGRAPH + {0xF0BA, 0x9F4A}, //15758 #CJK UNIFIED IDEOGRAPH + {0xF0BB, 0x4FCE}, //15759 #CJK UNIFIED IDEOGRAPH + {0xF0BC, 0x5146}, //15760 #CJK UNIFIED IDEOGRAPH + {0xF0BD, 0x51CB}, //15761 #CJK UNIFIED IDEOGRAPH + {0xF0BE, 0x52A9}, //15762 #CJK UNIFIED IDEOGRAPH + {0xF0BF, 0x5632}, //15763 #CJK UNIFIED IDEOGRAPH + {0xF0C0, 0x5F14}, //15764 #CJK UNIFIED IDEOGRAPH + {0xF0C1, 0x5F6B}, //15765 #CJK UNIFIED IDEOGRAPH + {0xF0C2, 0x63AA}, //15766 #CJK UNIFIED IDEOGRAPH + {0xF0C3, 0x64CD}, //15767 #CJK UNIFIED IDEOGRAPH + {0xF0C4, 0x65E9}, //15768 #CJK UNIFIED IDEOGRAPH + {0xF0C5, 0x6641}, //15769 #CJK UNIFIED IDEOGRAPH + {0xF0C6, 0x66FA}, //15770 #CJK UNIFIED IDEOGRAPH + {0xF0C7, 0x66F9}, //15771 #CJK UNIFIED IDEOGRAPH + {0xF0C8, 0x671D}, //15772 #CJK UNIFIED IDEOGRAPH + {0xF0C9, 0x689D}, //15773 #CJK UNIFIED IDEOGRAPH + {0xF0CA, 0x68D7}, //15774 #CJK UNIFIED IDEOGRAPH + {0xF0CB, 0x69FD}, //15775 #CJK UNIFIED IDEOGRAPH + {0xF0CC, 0x6F15}, //15776 #CJK UNIFIED IDEOGRAPH + {0xF0CD, 0x6F6E}, //15777 #CJK UNIFIED IDEOGRAPH + {0xF0CE, 0x7167}, //15778 #CJK UNIFIED IDEOGRAPH + {0xF0CF, 0x71E5}, //15779 #CJK UNIFIED IDEOGRAPH + {0xF0D0, 0x722A}, //15780 #CJK UNIFIED IDEOGRAPH + {0xF0D1, 0x74AA}, //15781 #CJK UNIFIED IDEOGRAPH + {0xF0D2, 0x773A}, //15782 #CJK UNIFIED IDEOGRAPH + {0xF0D3, 0x7956}, //15783 #CJK UNIFIED IDEOGRAPH + {0xF0D4, 0x795A}, //15784 #CJK UNIFIED IDEOGRAPH + {0xF0D5, 0x79DF}, //15785 #CJK UNIFIED IDEOGRAPH + {0xF0D6, 0x7A20}, //15786 #CJK UNIFIED IDEOGRAPH + {0xF0D7, 0x7A95}, //15787 #CJK UNIFIED IDEOGRAPH + {0xF0D8, 0x7C97}, //15788 #CJK UNIFIED IDEOGRAPH + {0xF0D9, 0x7CDF}, //15789 #CJK UNIFIED IDEOGRAPH + {0xF0DA, 0x7D44}, //15790 #CJK UNIFIED IDEOGRAPH + {0xF0DB, 0x7E70}, //15791 #CJK UNIFIED IDEOGRAPH + {0xF0DC, 0x8087}, //15792 #CJK UNIFIED IDEOGRAPH + {0xF0DD, 0x85FB}, //15793 #CJK UNIFIED IDEOGRAPH + {0xF0DE, 0x86A4}, //15794 #CJK UNIFIED IDEOGRAPH + {0xF0DF, 0x8A54}, //15795 #CJK UNIFIED IDEOGRAPH + {0xF0E0, 0x8ABF}, //15796 #CJK UNIFIED IDEOGRAPH + {0xF0E1, 0x8D99}, //15797 #CJK UNIFIED IDEOGRAPH + {0xF0E2, 0x8E81}, //15798 #CJK UNIFIED IDEOGRAPH + {0xF0E3, 0x9020}, //15799 #CJK UNIFIED IDEOGRAPH + {0xF0E4, 0x906D}, //15800 #CJK UNIFIED IDEOGRAPH + {0xF0E5, 0x91E3}, //15801 #CJK UNIFIED IDEOGRAPH + {0xF0E6, 0x963B}, //15802 #CJK UNIFIED IDEOGRAPH + {0xF0E7, 0x96D5}, //15803 #CJK UNIFIED IDEOGRAPH + {0xF0E8, 0x9CE5}, //15804 #CJK UNIFIED IDEOGRAPH + {0xF0E9, 0x65CF}, //15805 #CJK UNIFIED IDEOGRAPH + {0xF0EA, 0x7C07}, //15806 #CJK UNIFIED IDEOGRAPH + {0xF0EB, 0x8DB3}, //15807 #CJK UNIFIED IDEOGRAPH + {0xF0EC, 0x93C3}, //15808 #CJK UNIFIED IDEOGRAPH + {0xF0ED, 0x5B58}, //15809 #CJK UNIFIED IDEOGRAPH + {0xF0EE, 0x5C0A}, //15810 #CJK UNIFIED IDEOGRAPH + {0xF0EF, 0x5352}, //15811 #CJK UNIFIED IDEOGRAPH + {0xF0F0, 0x62D9}, //15812 #CJK UNIFIED IDEOGRAPH + {0xF0F1, 0x731D}, //15813 #CJK UNIFIED IDEOGRAPH + {0xF0F2, 0x5027}, //15814 #CJK UNIFIED IDEOGRAPH + {0xF0F3, 0x5B97}, //15815 #CJK UNIFIED IDEOGRAPH + {0xF0F4, 0x5F9E}, //15816 #CJK UNIFIED IDEOGRAPH + {0xF0F5, 0x60B0}, //15817 #CJK UNIFIED IDEOGRAPH + {0xF0F6, 0x616B}, //15818 #CJK UNIFIED IDEOGRAPH + {0xF0F7, 0x68D5}, //15819 #CJK UNIFIED IDEOGRAPH + {0xF0F8, 0x6DD9}, //15820 #CJK UNIFIED IDEOGRAPH + {0xF0F9, 0x742E}, //15821 #CJK UNIFIED IDEOGRAPH + {0xF0FA, 0x7A2E}, //15822 #CJK UNIFIED IDEOGRAPH + {0xF0FB, 0x7D42}, //15823 #CJK UNIFIED IDEOGRAPH + {0xF0FC, 0x7D9C}, //15824 #CJK UNIFIED IDEOGRAPH + {0xF0FD, 0x7E31}, //15825 #CJK UNIFIED IDEOGRAPH + {0xF0FE, 0x816B}, //15826 #CJK UNIFIED IDEOGRAPH + {0xF1A1, 0x8E2A}, //15827 #CJK UNIFIED IDEOGRAPH + {0xF1A2, 0x8E35}, //15828 #CJK UNIFIED IDEOGRAPH + {0xF1A3, 0x937E}, //15829 #CJK UNIFIED IDEOGRAPH + {0xF1A4, 0x9418}, //15830 #CJK UNIFIED IDEOGRAPH + {0xF1A5, 0x4F50}, //15831 #CJK UNIFIED IDEOGRAPH + {0xF1A6, 0x5750}, //15832 #CJK UNIFIED IDEOGRAPH + {0xF1A7, 0x5DE6}, //15833 #CJK UNIFIED IDEOGRAPH + {0xF1A8, 0x5EA7}, //15834 #CJK UNIFIED IDEOGRAPH + {0xF1A9, 0x632B}, //15835 #CJK UNIFIED IDEOGRAPH + {0xF1AA, 0x7F6A}, //15836 #CJK UNIFIED IDEOGRAPH + {0xF1AB, 0x4E3B}, //15837 #CJK UNIFIED IDEOGRAPH + {0xF1AC, 0x4F4F}, //15838 #CJK UNIFIED IDEOGRAPH + {0xF1AD, 0x4F8F}, //15839 #CJK UNIFIED IDEOGRAPH + {0xF1AE, 0x505A}, //15840 #CJK UNIFIED IDEOGRAPH + {0xF1AF, 0x59DD}, //15841 #CJK UNIFIED IDEOGRAPH + {0xF1B0, 0x80C4}, //15842 #CJK UNIFIED IDEOGRAPH + {0xF1B1, 0x546A}, //15843 #CJK UNIFIED IDEOGRAPH + {0xF1B2, 0x5468}, //15844 #CJK UNIFIED IDEOGRAPH + {0xF1B3, 0x55FE}, //15845 #CJK UNIFIED IDEOGRAPH + {0xF1B4, 0x594F}, //15846 #CJK UNIFIED IDEOGRAPH + {0xF1B5, 0x5B99}, //15847 #CJK UNIFIED IDEOGRAPH + {0xF1B6, 0x5DDE}, //15848 #CJK UNIFIED IDEOGRAPH + {0xF1B7, 0x5EDA}, //15849 #CJK UNIFIED IDEOGRAPH + {0xF1B8, 0x665D}, //15850 #CJK UNIFIED IDEOGRAPH + {0xF1B9, 0x6731}, //15851 #CJK UNIFIED IDEOGRAPH + {0xF1BA, 0x67F1}, //15852 #CJK UNIFIED IDEOGRAPH + {0xF1BB, 0x682A}, //15853 #CJK UNIFIED IDEOGRAPH + {0xF1BC, 0x6CE8}, //15854 #CJK UNIFIED IDEOGRAPH + {0xF1BD, 0x6D32}, //15855 #CJK UNIFIED IDEOGRAPH + {0xF1BE, 0x6E4A}, //15856 #CJK UNIFIED IDEOGRAPH + {0xF1BF, 0x6F8D}, //15857 #CJK UNIFIED IDEOGRAPH + {0xF1C0, 0x70B7}, //15858 #CJK UNIFIED IDEOGRAPH + {0xF1C1, 0x73E0}, //15859 #CJK UNIFIED IDEOGRAPH + {0xF1C2, 0x7587}, //15860 #CJK UNIFIED IDEOGRAPH + {0xF1C3, 0x7C4C}, //15861 #CJK UNIFIED IDEOGRAPH + {0xF1C4, 0x7D02}, //15862 #CJK UNIFIED IDEOGRAPH + {0xF1C5, 0x7D2C}, //15863 #CJK UNIFIED IDEOGRAPH + {0xF1C6, 0x7DA2}, //15864 #CJK UNIFIED IDEOGRAPH + {0xF1C7, 0x821F}, //15865 #CJK UNIFIED IDEOGRAPH + {0xF1C8, 0x86DB}, //15866 #CJK UNIFIED IDEOGRAPH + {0xF1C9, 0x8A3B}, //15867 #CJK UNIFIED IDEOGRAPH + {0xF1CA, 0x8A85}, //15868 #CJK UNIFIED IDEOGRAPH + {0xF1CB, 0x8D70}, //15869 #CJK UNIFIED IDEOGRAPH + {0xF1CC, 0x8E8A}, //15870 #CJK UNIFIED IDEOGRAPH + {0xF1CD, 0x8F33}, //15871 #CJK UNIFIED IDEOGRAPH + {0xF1CE, 0x9031}, //15872 #CJK UNIFIED IDEOGRAPH + {0xF1CF, 0x914E}, //15873 #CJK UNIFIED IDEOGRAPH + {0xF1D0, 0x9152}, //15874 #CJK UNIFIED IDEOGRAPH + {0xF1D1, 0x9444}, //15875 #CJK UNIFIED IDEOGRAPH + {0xF1D2, 0x99D0}, //15876 #CJK UNIFIED IDEOGRAPH + {0xF1D3, 0x7AF9}, //15877 #CJK UNIFIED IDEOGRAPH + {0xF1D4, 0x7CA5}, //15878 #CJK UNIFIED IDEOGRAPH + {0xF1D5, 0x4FCA}, //15879 #CJK UNIFIED IDEOGRAPH + {0xF1D6, 0x5101}, //15880 #CJK UNIFIED IDEOGRAPH + {0xF1D7, 0x51C6}, //15881 #CJK UNIFIED IDEOGRAPH + {0xF1D8, 0x57C8}, //15882 #CJK UNIFIED IDEOGRAPH + {0xF1D9, 0x5BEF}, //15883 #CJK UNIFIED IDEOGRAPH + {0xF1DA, 0x5CFB}, //15884 #CJK UNIFIED IDEOGRAPH + {0xF1DB, 0x6659}, //15885 #CJK UNIFIED IDEOGRAPH + {0xF1DC, 0x6A3D}, //15886 #CJK UNIFIED IDEOGRAPH + {0xF1DD, 0x6D5A}, //15887 #CJK UNIFIED IDEOGRAPH + {0xF1DE, 0x6E96}, //15888 #CJK UNIFIED IDEOGRAPH + {0xF1DF, 0x6FEC}, //15889 #CJK UNIFIED IDEOGRAPH + {0xF1E0, 0x710C}, //15890 #CJK UNIFIED IDEOGRAPH + {0xF1E1, 0x756F}, //15891 #CJK UNIFIED IDEOGRAPH + {0xF1E2, 0x7AE3}, //15892 #CJK UNIFIED IDEOGRAPH + {0xF1E3, 0x8822}, //15893 #CJK UNIFIED IDEOGRAPH + {0xF1E4, 0x9021}, //15894 #CJK UNIFIED IDEOGRAPH + {0xF1E5, 0x9075}, //15895 #CJK UNIFIED IDEOGRAPH + {0xF1E6, 0x96CB}, //15896 #CJK UNIFIED IDEOGRAPH + {0xF1E7, 0x99FF}, //15897 #CJK UNIFIED IDEOGRAPH + {0xF1E8, 0x8301}, //15898 #CJK UNIFIED IDEOGRAPH + {0xF1E9, 0x4E2D}, //15899 #CJK UNIFIED IDEOGRAPH + {0xF1EA, 0x4EF2}, //15900 #CJK UNIFIED IDEOGRAPH + {0xF1EB, 0x8846}, //15901 #CJK UNIFIED IDEOGRAPH + {0xF1EC, 0x91CD}, //15902 #CJK UNIFIED IDEOGRAPH + {0xF1ED, 0x537D}, //15903 #CJK UNIFIED IDEOGRAPH + {0xF1EE, 0x6ADB}, //15904 #CJK UNIFIED IDEOGRAPH + {0xF1EF, 0x696B}, //15905 #CJK UNIFIED IDEOGRAPH + {0xF1F0, 0x6C41}, //15906 #CJK UNIFIED IDEOGRAPH + {0xF1F1, 0x847A}, //15907 #CJK UNIFIED IDEOGRAPH + {0xF1F2, 0x589E}, //15908 #CJK UNIFIED IDEOGRAPH + {0xF1F3, 0x618E}, //15909 #CJK UNIFIED IDEOGRAPH + {0xF1F4, 0x66FE}, //15910 #CJK UNIFIED IDEOGRAPH + {0xF1F5, 0x62EF}, //15911 #CJK UNIFIED IDEOGRAPH + {0xF1F6, 0x70DD}, //15912 #CJK UNIFIED IDEOGRAPH + {0xF1F7, 0x7511}, //15913 #CJK UNIFIED IDEOGRAPH + {0xF1F8, 0x75C7}, //15914 #CJK UNIFIED IDEOGRAPH + {0xF1F9, 0x7E52}, //15915 #CJK UNIFIED IDEOGRAPH + {0xF1FA, 0x84B8}, //15916 #CJK UNIFIED IDEOGRAPH + {0xF1FB, 0x8B49}, //15917 #CJK UNIFIED IDEOGRAPH + {0xF1FC, 0x8D08}, //15918 #CJK UNIFIED IDEOGRAPH + {0xF1FD, 0x4E4B}, //15919 #CJK UNIFIED IDEOGRAPH + {0xF1FE, 0x53EA}, //15920 #CJK UNIFIED IDEOGRAPH + {0xF2A1, 0x54AB}, //15921 #CJK UNIFIED IDEOGRAPH + {0xF2A2, 0x5730}, //15922 #CJK UNIFIED IDEOGRAPH + {0xF2A3, 0x5740}, //15923 #CJK UNIFIED IDEOGRAPH + {0xF2A4, 0x5FD7}, //15924 #CJK UNIFIED IDEOGRAPH + {0xF2A5, 0x6301}, //15925 #CJK UNIFIED IDEOGRAPH + {0xF2A6, 0x6307}, //15926 #CJK UNIFIED IDEOGRAPH + {0xF2A7, 0x646F}, //15927 #CJK UNIFIED IDEOGRAPH + {0xF2A8, 0x652F}, //15928 #CJK UNIFIED IDEOGRAPH + {0xF2A9, 0x65E8}, //15929 #CJK UNIFIED IDEOGRAPH + {0xF2AA, 0x667A}, //15930 #CJK UNIFIED IDEOGRAPH + {0xF2AB, 0x679D}, //15931 #CJK UNIFIED IDEOGRAPH + {0xF2AC, 0x67B3}, //15932 #CJK UNIFIED IDEOGRAPH + {0xF2AD, 0x6B62}, //15933 #CJK UNIFIED IDEOGRAPH + {0xF2AE, 0x6C60}, //15934 #CJK UNIFIED IDEOGRAPH + {0xF2AF, 0x6C9A}, //15935 #CJK UNIFIED IDEOGRAPH + {0xF2B0, 0x6F2C}, //15936 #CJK UNIFIED IDEOGRAPH + {0xF2B1, 0x77E5}, //15937 #CJK UNIFIED IDEOGRAPH + {0xF2B2, 0x7825}, //15938 #CJK UNIFIED IDEOGRAPH + {0xF2B3, 0x7949}, //15939 #CJK UNIFIED IDEOGRAPH + {0xF2B4, 0x7957}, //15940 #CJK UNIFIED IDEOGRAPH + {0xF2B5, 0x7D19}, //15941 #CJK UNIFIED IDEOGRAPH + {0xF2B6, 0x80A2}, //15942 #CJK UNIFIED IDEOGRAPH + {0xF2B7, 0x8102}, //15943 #CJK UNIFIED IDEOGRAPH + {0xF2B8, 0x81F3}, //15944 #CJK UNIFIED IDEOGRAPH + {0xF2B9, 0x829D}, //15945 #CJK UNIFIED IDEOGRAPH + {0xF2BA, 0x82B7}, //15946 #CJK UNIFIED IDEOGRAPH + {0xF2BB, 0x8718}, //15947 #CJK UNIFIED IDEOGRAPH + {0xF2BC, 0x8A8C}, //15948 #CJK UNIFIED IDEOGRAPH + {0xF2BD, 0xF9FC}, //15949 #CJK COMPATIBILITY IDEOGRAPH + {0xF2BE, 0x8D04}, //15950 #CJK UNIFIED IDEOGRAPH + {0xF2BF, 0x8DBE}, //15951 #CJK UNIFIED IDEOGRAPH + {0xF2C0, 0x9072}, //15952 #CJK UNIFIED IDEOGRAPH + {0xF2C1, 0x76F4}, //15953 #CJK UNIFIED IDEOGRAPH + {0xF2C2, 0x7A19}, //15954 #CJK UNIFIED IDEOGRAPH + {0xF2C3, 0x7A37}, //15955 #CJK UNIFIED IDEOGRAPH + {0xF2C4, 0x7E54}, //15956 #CJK UNIFIED IDEOGRAPH + {0xF2C5, 0x8077}, //15957 #CJK UNIFIED IDEOGRAPH + {0xF2C6, 0x5507}, //15958 #CJK UNIFIED IDEOGRAPH + {0xF2C7, 0x55D4}, //15959 #CJK UNIFIED IDEOGRAPH + {0xF2C8, 0x5875}, //15960 #CJK UNIFIED IDEOGRAPH + {0xF2C9, 0x632F}, //15961 #CJK UNIFIED IDEOGRAPH + {0xF2CA, 0x6422}, //15962 #CJK UNIFIED IDEOGRAPH + {0xF2CB, 0x6649}, //15963 #CJK UNIFIED IDEOGRAPH + {0xF2CC, 0x664B}, //15964 #CJK UNIFIED IDEOGRAPH + {0xF2CD, 0x686D}, //15965 #CJK UNIFIED IDEOGRAPH + {0xF2CE, 0x699B}, //15966 #CJK UNIFIED IDEOGRAPH + {0xF2CF, 0x6B84}, //15967 #CJK UNIFIED IDEOGRAPH + {0xF2D0, 0x6D25}, //15968 #CJK UNIFIED IDEOGRAPH + {0xF2D1, 0x6EB1}, //15969 #CJK UNIFIED IDEOGRAPH + {0xF2D2, 0x73CD}, //15970 #CJK UNIFIED IDEOGRAPH + {0xF2D3, 0x7468}, //15971 #CJK UNIFIED IDEOGRAPH + {0xF2D4, 0x74A1}, //15972 #CJK UNIFIED IDEOGRAPH + {0xF2D5, 0x755B}, //15973 #CJK UNIFIED IDEOGRAPH + {0xF2D6, 0x75B9}, //15974 #CJK UNIFIED IDEOGRAPH + {0xF2D7, 0x76E1}, //15975 #CJK UNIFIED IDEOGRAPH + {0xF2D8, 0x771E}, //15976 #CJK UNIFIED IDEOGRAPH + {0xF2D9, 0x778B}, //15977 #CJK UNIFIED IDEOGRAPH + {0xF2DA, 0x79E6}, //15978 #CJK UNIFIED IDEOGRAPH + {0xF2DB, 0x7E09}, //15979 #CJK UNIFIED IDEOGRAPH + {0xF2DC, 0x7E1D}, //15980 #CJK UNIFIED IDEOGRAPH + {0xF2DD, 0x81FB}, //15981 #CJK UNIFIED IDEOGRAPH + {0xF2DE, 0x852F}, //15982 #CJK UNIFIED IDEOGRAPH + {0xF2DF, 0x8897}, //15983 #CJK UNIFIED IDEOGRAPH + {0xF2E0, 0x8A3A}, //15984 #CJK UNIFIED IDEOGRAPH + {0xF2E1, 0x8CD1}, //15985 #CJK UNIFIED IDEOGRAPH + {0xF2E2, 0x8EEB}, //15986 #CJK UNIFIED IDEOGRAPH + {0xF2E3, 0x8FB0}, //15987 #CJK UNIFIED IDEOGRAPH + {0xF2E4, 0x9032}, //15988 #CJK UNIFIED IDEOGRAPH + {0xF2E5, 0x93AD}, //15989 #CJK UNIFIED IDEOGRAPH + {0xF2E6, 0x9663}, //15990 #CJK UNIFIED IDEOGRAPH + {0xF2E7, 0x9673}, //15991 #CJK UNIFIED IDEOGRAPH + {0xF2E8, 0x9707}, //15992 #CJK UNIFIED IDEOGRAPH + {0xF2E9, 0x4F84}, //15993 #CJK UNIFIED IDEOGRAPH + {0xF2EA, 0x53F1}, //15994 #CJK UNIFIED IDEOGRAPH + {0xF2EB, 0x59EA}, //15995 #CJK UNIFIED IDEOGRAPH + {0xF2EC, 0x5AC9}, //15996 #CJK UNIFIED IDEOGRAPH + {0xF2ED, 0x5E19}, //15997 #CJK UNIFIED IDEOGRAPH + {0xF2EE, 0x684E}, //15998 #CJK UNIFIED IDEOGRAPH + {0xF2EF, 0x74C6}, //15999 #CJK UNIFIED IDEOGRAPH + {0xF2F0, 0x75BE}, //16000 #CJK UNIFIED IDEOGRAPH + {0xF2F1, 0x79E9}, //16001 #CJK UNIFIED IDEOGRAPH + {0xF2F2, 0x7A92}, //16002 #CJK UNIFIED IDEOGRAPH + {0xF2F3, 0x81A3}, //16003 #CJK UNIFIED IDEOGRAPH + {0xF2F4, 0x86ED}, //16004 #CJK UNIFIED IDEOGRAPH + {0xF2F5, 0x8CEA}, //16005 #CJK UNIFIED IDEOGRAPH + {0xF2F6, 0x8DCC}, //16006 #CJK UNIFIED IDEOGRAPH + {0xF2F7, 0x8FED}, //16007 #CJK UNIFIED IDEOGRAPH + {0xF2F8, 0x659F}, //16008 #CJK UNIFIED IDEOGRAPH + {0xF2F9, 0x6715}, //16009 #CJK UNIFIED IDEOGRAPH + {0xF2FA, 0xF9FD}, //16010 #CJK COMPATIBILITY IDEOGRAPH + {0xF2FB, 0x57F7}, //16011 #CJK UNIFIED IDEOGRAPH + {0xF2FC, 0x6F57}, //16012 #CJK UNIFIED IDEOGRAPH + {0xF2FD, 0x7DDD}, //16013 #CJK UNIFIED IDEOGRAPH + {0xF2FE, 0x8F2F}, //16014 #CJK UNIFIED IDEOGRAPH + {0xF3A1, 0x93F6}, //16015 #CJK UNIFIED IDEOGRAPH + {0xF3A2, 0x96C6}, //16016 #CJK UNIFIED IDEOGRAPH + {0xF3A3, 0x5FB5}, //16017 #CJK UNIFIED IDEOGRAPH + {0xF3A4, 0x61F2}, //16018 #CJK UNIFIED IDEOGRAPH + {0xF3A5, 0x6F84}, //16019 #CJK UNIFIED IDEOGRAPH + {0xF3A6, 0x4E14}, //16020 #CJK UNIFIED IDEOGRAPH + {0xF3A7, 0x4F98}, //16021 #CJK UNIFIED IDEOGRAPH + {0xF3A8, 0x501F}, //16022 #CJK UNIFIED IDEOGRAPH + {0xF3A9, 0x53C9}, //16023 #CJK UNIFIED IDEOGRAPH + {0xF3AA, 0x55DF}, //16024 #CJK UNIFIED IDEOGRAPH + {0xF3AB, 0x5D6F}, //16025 #CJK UNIFIED IDEOGRAPH + {0xF3AC, 0x5DEE}, //16026 #CJK UNIFIED IDEOGRAPH + {0xF3AD, 0x6B21}, //16027 #CJK UNIFIED IDEOGRAPH + {0xF3AE, 0x6B64}, //16028 #CJK UNIFIED IDEOGRAPH + {0xF3AF, 0x78CB}, //16029 #CJK UNIFIED IDEOGRAPH + {0xF3B0, 0x7B9A}, //16030 #CJK UNIFIED IDEOGRAPH + {0xF3B1, 0xF9FE}, //16031 #CJK COMPATIBILITY IDEOGRAPH + {0xF3B2, 0x8E49}, //16032 #CJK UNIFIED IDEOGRAPH + {0xF3B3, 0x8ECA}, //16033 #CJK UNIFIED IDEOGRAPH + {0xF3B4, 0x906E}, //16034 #CJK UNIFIED IDEOGRAPH + {0xF3B5, 0x6349}, //16035 #CJK UNIFIED IDEOGRAPH + {0xF3B6, 0x643E}, //16036 #CJK UNIFIED IDEOGRAPH + {0xF3B7, 0x7740}, //16037 #CJK UNIFIED IDEOGRAPH + {0xF3B8, 0x7A84}, //16038 #CJK UNIFIED IDEOGRAPH + {0xF3B9, 0x932F}, //16039 #CJK UNIFIED IDEOGRAPH + {0xF3BA, 0x947F}, //16040 #CJK UNIFIED IDEOGRAPH + {0xF3BB, 0x9F6A}, //16041 #CJK UNIFIED IDEOGRAPH + {0xF3BC, 0x64B0}, //16042 #CJK UNIFIED IDEOGRAPH + {0xF3BD, 0x6FAF}, //16043 #CJK UNIFIED IDEOGRAPH + {0xF3BE, 0x71E6}, //16044 #CJK UNIFIED IDEOGRAPH + {0xF3BF, 0x74A8}, //16045 #CJK UNIFIED IDEOGRAPH + {0xF3C0, 0x74DA}, //16046 #CJK UNIFIED IDEOGRAPH + {0xF3C1, 0x7AC4}, //16047 #CJK UNIFIED IDEOGRAPH + {0xF3C2, 0x7C12}, //16048 #CJK UNIFIED IDEOGRAPH + {0xF3C3, 0x7E82}, //16049 #CJK UNIFIED IDEOGRAPH + {0xF3C4, 0x7CB2}, //16050 #CJK UNIFIED IDEOGRAPH + {0xF3C5, 0x7E98}, //16051 #CJK UNIFIED IDEOGRAPH + {0xF3C6, 0x8B9A}, //16052 #CJK UNIFIED IDEOGRAPH + {0xF3C7, 0x8D0A}, //16053 #CJK UNIFIED IDEOGRAPH + {0xF3C8, 0x947D}, //16054 #CJK UNIFIED IDEOGRAPH + {0xF3C9, 0x9910}, //16055 #CJK UNIFIED IDEOGRAPH + {0xF3CA, 0x994C}, //16056 #CJK UNIFIED IDEOGRAPH + {0xF3CB, 0x5239}, //16057 #CJK UNIFIED IDEOGRAPH + {0xF3CC, 0x5BDF}, //16058 #CJK UNIFIED IDEOGRAPH + {0xF3CD, 0x64E6}, //16059 #CJK UNIFIED IDEOGRAPH + {0xF3CE, 0x672D}, //16060 #CJK UNIFIED IDEOGRAPH + {0xF3CF, 0x7D2E}, //16061 #CJK UNIFIED IDEOGRAPH + {0xF3D0, 0x50ED}, //16062 #CJK UNIFIED IDEOGRAPH + {0xF3D1, 0x53C3}, //16063 #CJK UNIFIED IDEOGRAPH + {0xF3D2, 0x5879}, //16064 #CJK UNIFIED IDEOGRAPH + {0xF3D3, 0x6158}, //16065 #CJK UNIFIED IDEOGRAPH + {0xF3D4, 0x6159}, //16066 #CJK UNIFIED IDEOGRAPH + {0xF3D5, 0x61FA}, //16067 #CJK UNIFIED IDEOGRAPH + {0xF3D6, 0x65AC}, //16068 #CJK UNIFIED IDEOGRAPH + {0xF3D7, 0x7AD9}, //16069 #CJK UNIFIED IDEOGRAPH + {0xF3D8, 0x8B92}, //16070 #CJK UNIFIED IDEOGRAPH + {0xF3D9, 0x8B96}, //16071 #CJK UNIFIED IDEOGRAPH + {0xF3DA, 0x5009}, //16072 #CJK UNIFIED IDEOGRAPH + {0xF3DB, 0x5021}, //16073 #CJK UNIFIED IDEOGRAPH + {0xF3DC, 0x5275}, //16074 #CJK UNIFIED IDEOGRAPH + {0xF3DD, 0x5531}, //16075 #CJK UNIFIED IDEOGRAPH + {0xF3DE, 0x5A3C}, //16076 #CJK UNIFIED IDEOGRAPH + {0xF3DF, 0x5EE0}, //16077 #CJK UNIFIED IDEOGRAPH + {0xF3E0, 0x5F70}, //16078 #CJK UNIFIED IDEOGRAPH + {0xF3E1, 0x6134}, //16079 #CJK UNIFIED IDEOGRAPH + {0xF3E2, 0x655E}, //16080 #CJK UNIFIED IDEOGRAPH + {0xF3E3, 0x660C}, //16081 #CJK UNIFIED IDEOGRAPH + {0xF3E4, 0x6636}, //16082 #CJK UNIFIED IDEOGRAPH + {0xF3E5, 0x66A2}, //16083 #CJK UNIFIED IDEOGRAPH + {0xF3E6, 0x69CD}, //16084 #CJK UNIFIED IDEOGRAPH + {0xF3E7, 0x6EC4}, //16085 #CJK UNIFIED IDEOGRAPH + {0xF3E8, 0x6F32}, //16086 #CJK UNIFIED IDEOGRAPH + {0xF3E9, 0x7316}, //16087 #CJK UNIFIED IDEOGRAPH + {0xF3EA, 0x7621}, //16088 #CJK UNIFIED IDEOGRAPH + {0xF3EB, 0x7A93}, //16089 #CJK UNIFIED IDEOGRAPH + {0xF3EC, 0x8139}, //16090 #CJK UNIFIED IDEOGRAPH + {0xF3ED, 0x8259}, //16091 #CJK UNIFIED IDEOGRAPH + {0xF3EE, 0x83D6}, //16092 #CJK UNIFIED IDEOGRAPH + {0xF3EF, 0x84BC}, //16093 #CJK UNIFIED IDEOGRAPH + {0xF3F0, 0x50B5}, //16094 #CJK UNIFIED IDEOGRAPH + {0xF3F1, 0x57F0}, //16095 #CJK UNIFIED IDEOGRAPH + {0xF3F2, 0x5BC0}, //16096 #CJK UNIFIED IDEOGRAPH + {0xF3F3, 0x5BE8}, //16097 #CJK UNIFIED IDEOGRAPH + {0xF3F4, 0x5F69}, //16098 #CJK UNIFIED IDEOGRAPH + {0xF3F5, 0x63A1}, //16099 #CJK UNIFIED IDEOGRAPH + {0xF3F6, 0x7826}, //16100 #CJK UNIFIED IDEOGRAPH + {0xF3F7, 0x7DB5}, //16101 #CJK UNIFIED IDEOGRAPH + {0xF3F8, 0x83DC}, //16102 #CJK UNIFIED IDEOGRAPH + {0xF3F9, 0x8521}, //16103 #CJK UNIFIED IDEOGRAPH + {0xF3FA, 0x91C7}, //16104 #CJK UNIFIED IDEOGRAPH + {0xF3FB, 0x91F5}, //16105 #CJK UNIFIED IDEOGRAPH + {0xF3FC, 0x518A}, //16106 #CJK UNIFIED IDEOGRAPH + {0xF3FD, 0x67F5}, //16107 #CJK UNIFIED IDEOGRAPH + {0xF3FE, 0x7B56}, //16108 #CJK UNIFIED IDEOGRAPH + {0xF4A1, 0x8CAC}, //16109 #CJK UNIFIED IDEOGRAPH + {0xF4A2, 0x51C4}, //16110 #CJK UNIFIED IDEOGRAPH + {0xF4A3, 0x59BB}, //16111 #CJK UNIFIED IDEOGRAPH + {0xF4A4, 0x60BD}, //16112 #CJK UNIFIED IDEOGRAPH + {0xF4A5, 0x8655}, //16113 #CJK UNIFIED IDEOGRAPH + {0xF4A6, 0x501C}, //16114 #CJK UNIFIED IDEOGRAPH + {0xF4A7, 0xF9FF}, //16115 #CJK COMPATIBILITY IDEOGRAPH + {0xF4A8, 0x5254}, //16116 #CJK UNIFIED IDEOGRAPH + {0xF4A9, 0x5C3A}, //16117 #CJK UNIFIED IDEOGRAPH + {0xF4AA, 0x617D}, //16118 #CJK UNIFIED IDEOGRAPH + {0xF4AB, 0x621A}, //16119 #CJK UNIFIED IDEOGRAPH + {0xF4AC, 0x62D3}, //16120 #CJK UNIFIED IDEOGRAPH + {0xF4AD, 0x64F2}, //16121 #CJK UNIFIED IDEOGRAPH + {0xF4AE, 0x65A5}, //16122 #CJK UNIFIED IDEOGRAPH + {0xF4AF, 0x6ECC}, //16123 #CJK UNIFIED IDEOGRAPH + {0xF4B0, 0x7620}, //16124 #CJK UNIFIED IDEOGRAPH + {0xF4B1, 0x810A}, //16125 #CJK UNIFIED IDEOGRAPH + {0xF4B2, 0x8E60}, //16126 #CJK UNIFIED IDEOGRAPH + {0xF4B3, 0x965F}, //16127 #CJK UNIFIED IDEOGRAPH + {0xF4B4, 0x96BB}, //16128 #CJK UNIFIED IDEOGRAPH + {0xF4B5, 0x4EDF}, //16129 #CJK UNIFIED IDEOGRAPH + {0xF4B6, 0x5343}, //16130 #CJK UNIFIED IDEOGRAPH + {0xF4B7, 0x5598}, //16131 #CJK UNIFIED IDEOGRAPH + {0xF4B8, 0x5929}, //16132 #CJK UNIFIED IDEOGRAPH + {0xF4B9, 0x5DDD}, //16133 #CJK UNIFIED IDEOGRAPH + {0xF4BA, 0x64C5}, //16134 #CJK UNIFIED IDEOGRAPH + {0xF4BB, 0x6CC9}, //16135 #CJK UNIFIED IDEOGRAPH + {0xF4BC, 0x6DFA}, //16136 #CJK UNIFIED IDEOGRAPH + {0xF4BD, 0x7394}, //16137 #CJK UNIFIED IDEOGRAPH + {0xF4BE, 0x7A7F}, //16138 #CJK UNIFIED IDEOGRAPH + {0xF4BF, 0x821B}, //16139 #CJK UNIFIED IDEOGRAPH + {0xF4C0, 0x85A6}, //16140 #CJK UNIFIED IDEOGRAPH + {0xF4C1, 0x8CE4}, //16141 #CJK UNIFIED IDEOGRAPH + {0xF4C2, 0x8E10}, //16142 #CJK UNIFIED IDEOGRAPH + {0xF4C3, 0x9077}, //16143 #CJK UNIFIED IDEOGRAPH + {0xF4C4, 0x91E7}, //16144 #CJK UNIFIED IDEOGRAPH + {0xF4C5, 0x95E1}, //16145 #CJK UNIFIED IDEOGRAPH + {0xF4C6, 0x9621}, //16146 #CJK UNIFIED IDEOGRAPH + {0xF4C7, 0x97C6}, //16147 #CJK UNIFIED IDEOGRAPH + {0xF4C8, 0x51F8}, //16148 #CJK UNIFIED IDEOGRAPH + {0xF4C9, 0x54F2}, //16149 #CJK UNIFIED IDEOGRAPH + {0xF4CA, 0x5586}, //16150 #CJK UNIFIED IDEOGRAPH + {0xF4CB, 0x5FB9}, //16151 #CJK UNIFIED IDEOGRAPH + {0xF4CC, 0x64A4}, //16152 #CJK UNIFIED IDEOGRAPH + {0xF4CD, 0x6F88}, //16153 #CJK UNIFIED IDEOGRAPH + {0xF4CE, 0x7DB4}, //16154 #CJK UNIFIED IDEOGRAPH + {0xF4CF, 0x8F1F}, //16155 #CJK UNIFIED IDEOGRAPH + {0xF4D0, 0x8F4D}, //16156 #CJK UNIFIED IDEOGRAPH + {0xF4D1, 0x9435}, //16157 #CJK UNIFIED IDEOGRAPH + {0xF4D2, 0x50C9}, //16158 #CJK UNIFIED IDEOGRAPH + {0xF4D3, 0x5C16}, //16159 #CJK UNIFIED IDEOGRAPH + {0xF4D4, 0x6CBE}, //16160 #CJK UNIFIED IDEOGRAPH + {0xF4D5, 0x6DFB}, //16161 #CJK UNIFIED IDEOGRAPH + {0xF4D6, 0x751B}, //16162 #CJK UNIFIED IDEOGRAPH + {0xF4D7, 0x77BB}, //16163 #CJK UNIFIED IDEOGRAPH + {0xF4D8, 0x7C3D}, //16164 #CJK UNIFIED IDEOGRAPH + {0xF4D9, 0x7C64}, //16165 #CJK UNIFIED IDEOGRAPH + {0xF4DA, 0x8A79}, //16166 #CJK UNIFIED IDEOGRAPH + {0xF4DB, 0x8AC2}, //16167 #CJK UNIFIED IDEOGRAPH + {0xF4DC, 0x581E}, //16168 #CJK UNIFIED IDEOGRAPH + {0xF4DD, 0x59BE}, //16169 #CJK UNIFIED IDEOGRAPH + {0xF4DE, 0x5E16}, //16170 #CJK UNIFIED IDEOGRAPH + {0xF4DF, 0x6377}, //16171 #CJK UNIFIED IDEOGRAPH + {0xF4E0, 0x7252}, //16172 #CJK UNIFIED IDEOGRAPH + {0xF4E1, 0x758A}, //16173 #CJK UNIFIED IDEOGRAPH + {0xF4E2, 0x776B}, //16174 #CJK UNIFIED IDEOGRAPH + {0xF4E3, 0x8ADC}, //16175 #CJK UNIFIED IDEOGRAPH + {0xF4E4, 0x8CBC}, //16176 #CJK UNIFIED IDEOGRAPH + {0xF4E5, 0x8F12}, //16177 #CJK UNIFIED IDEOGRAPH + {0xF4E6, 0x5EF3}, //16178 #CJK UNIFIED IDEOGRAPH + {0xF4E7, 0x6674}, //16179 #CJK UNIFIED IDEOGRAPH + {0xF4E8, 0x6DF8}, //16180 #CJK UNIFIED IDEOGRAPH + {0xF4E9, 0x807D}, //16181 #CJK UNIFIED IDEOGRAPH + {0xF4EA, 0x83C1}, //16182 #CJK UNIFIED IDEOGRAPH + {0xF4EB, 0x8ACB}, //16183 #CJK UNIFIED IDEOGRAPH + {0xF4EC, 0x9751}, //16184 #CJK UNIFIED IDEOGRAPH + {0xF4ED, 0x9BD6}, //16185 #CJK UNIFIED IDEOGRAPH + {0xF4EE, 0xFA00}, //16186 #CJK COMPATIBILITY IDEOGRAPH + {0xF4EF, 0x5243}, //16187 #CJK UNIFIED IDEOGRAPH + {0xF4F0, 0x66FF}, //16188 #CJK UNIFIED IDEOGRAPH + {0xF4F1, 0x6D95}, //16189 #CJK UNIFIED IDEOGRAPH + {0xF4F2, 0x6EEF}, //16190 #CJK UNIFIED IDEOGRAPH + {0xF4F3, 0x7DE0}, //16191 #CJK UNIFIED IDEOGRAPH + {0xF4F4, 0x8AE6}, //16192 #CJK UNIFIED IDEOGRAPH + {0xF4F5, 0x902E}, //16193 #CJK UNIFIED IDEOGRAPH + {0xF4F6, 0x905E}, //16194 #CJK UNIFIED IDEOGRAPH + {0xF4F7, 0x9AD4}, //16195 #CJK UNIFIED IDEOGRAPH + {0xF4F8, 0x521D}, //16196 #CJK UNIFIED IDEOGRAPH + {0xF4F9, 0x527F}, //16197 #CJK UNIFIED IDEOGRAPH + {0xF4FA, 0x54E8}, //16198 #CJK UNIFIED IDEOGRAPH + {0xF4FB, 0x6194}, //16199 #CJK UNIFIED IDEOGRAPH + {0xF4FC, 0x6284}, //16200 #CJK UNIFIED IDEOGRAPH + {0xF4FD, 0x62DB}, //16201 #CJK UNIFIED IDEOGRAPH + {0xF4FE, 0x68A2}, //16202 #CJK UNIFIED IDEOGRAPH + {0xF5A1, 0x6912}, //16203 #CJK UNIFIED IDEOGRAPH + {0xF5A2, 0x695A}, //16204 #CJK UNIFIED IDEOGRAPH + {0xF5A3, 0x6A35}, //16205 #CJK UNIFIED IDEOGRAPH + {0xF5A4, 0x7092}, //16206 #CJK UNIFIED IDEOGRAPH + {0xF5A5, 0x7126}, //16207 #CJK UNIFIED IDEOGRAPH + {0xF5A6, 0x785D}, //16208 #CJK UNIFIED IDEOGRAPH + {0xF5A7, 0x7901}, //16209 #CJK UNIFIED IDEOGRAPH + {0xF5A8, 0x790E}, //16210 #CJK UNIFIED IDEOGRAPH + {0xF5A9, 0x79D2}, //16211 #CJK UNIFIED IDEOGRAPH + {0xF5AA, 0x7A0D}, //16212 #CJK UNIFIED IDEOGRAPH + {0xF5AB, 0x8096}, //16213 #CJK UNIFIED IDEOGRAPH + {0xF5AC, 0x8278}, //16214 #CJK UNIFIED IDEOGRAPH + {0xF5AD, 0x82D5}, //16215 #CJK UNIFIED IDEOGRAPH + {0xF5AE, 0x8349}, //16216 #CJK UNIFIED IDEOGRAPH + {0xF5AF, 0x8549}, //16217 #CJK UNIFIED IDEOGRAPH + {0xF5B0, 0x8C82}, //16218 #CJK UNIFIED IDEOGRAPH + {0xF5B1, 0x8D85}, //16219 #CJK UNIFIED IDEOGRAPH + {0xF5B2, 0x9162}, //16220 #CJK UNIFIED IDEOGRAPH + {0xF5B3, 0x918B}, //16221 #CJK UNIFIED IDEOGRAPH + {0xF5B4, 0x91AE}, //16222 #CJK UNIFIED IDEOGRAPH + {0xF5B5, 0x4FC3}, //16223 #CJK UNIFIED IDEOGRAPH + {0xF5B6, 0x56D1}, //16224 #CJK UNIFIED IDEOGRAPH + {0xF5B7, 0x71ED}, //16225 #CJK UNIFIED IDEOGRAPH + {0xF5B8, 0x77D7}, //16226 #CJK UNIFIED IDEOGRAPH + {0xF5B9, 0x8700}, //16227 #CJK UNIFIED IDEOGRAPH + {0xF5BA, 0x89F8}, //16228 #CJK UNIFIED IDEOGRAPH + {0xF5BB, 0x5BF8}, //16229 #CJK UNIFIED IDEOGRAPH + {0xF5BC, 0x5FD6}, //16230 #CJK UNIFIED IDEOGRAPH + {0xF5BD, 0x6751}, //16231 #CJK UNIFIED IDEOGRAPH + {0xF5BE, 0x90A8}, //16232 #CJK UNIFIED IDEOGRAPH + {0xF5BF, 0x53E2}, //16233 #CJK UNIFIED IDEOGRAPH + {0xF5C0, 0x585A}, //16234 #CJK UNIFIED IDEOGRAPH + {0xF5C1, 0x5BF5}, //16235 #CJK UNIFIED IDEOGRAPH + {0xF5C2, 0x60A4}, //16236 #CJK UNIFIED IDEOGRAPH + {0xF5C3, 0x6181}, //16237 #CJK UNIFIED IDEOGRAPH + {0xF5C4, 0x6460}, //16238 #CJK UNIFIED IDEOGRAPH + {0xF5C5, 0x7E3D}, //16239 #CJK UNIFIED IDEOGRAPH + {0xF5C6, 0x8070}, //16240 #CJK UNIFIED IDEOGRAPH + {0xF5C7, 0x8525}, //16241 #CJK UNIFIED IDEOGRAPH + {0xF5C8, 0x9283}, //16242 #CJK UNIFIED IDEOGRAPH + {0xF5C9, 0x64AE}, //16243 #CJK UNIFIED IDEOGRAPH + {0xF5CA, 0x50AC}, //16244 #CJK UNIFIED IDEOGRAPH + {0xF5CB, 0x5D14}, //16245 #CJK UNIFIED IDEOGRAPH + {0xF5CC, 0x6700}, //16246 #CJK UNIFIED IDEOGRAPH + {0xF5CD, 0x589C}, //16247 #CJK UNIFIED IDEOGRAPH + {0xF5CE, 0x62BD}, //16248 #CJK UNIFIED IDEOGRAPH + {0xF5CF, 0x63A8}, //16249 #CJK UNIFIED IDEOGRAPH + {0xF5D0, 0x690E}, //16250 #CJK UNIFIED IDEOGRAPH + {0xF5D1, 0x6978}, //16251 #CJK UNIFIED IDEOGRAPH + {0xF5D2, 0x6A1E}, //16252 #CJK UNIFIED IDEOGRAPH + {0xF5D3, 0x6E6B}, //16253 #CJK UNIFIED IDEOGRAPH + {0xF5D4, 0x76BA}, //16254 #CJK UNIFIED IDEOGRAPH + {0xF5D5, 0x79CB}, //16255 #CJK UNIFIED IDEOGRAPH + {0xF5D6, 0x82BB}, //16256 #CJK UNIFIED IDEOGRAPH + {0xF5D7, 0x8429}, //16257 #CJK UNIFIED IDEOGRAPH + {0xF5D8, 0x8ACF}, //16258 #CJK UNIFIED IDEOGRAPH + {0xF5D9, 0x8DA8}, //16259 #CJK UNIFIED IDEOGRAPH + {0xF5DA, 0x8FFD}, //16260 #CJK UNIFIED IDEOGRAPH + {0xF5DB, 0x9112}, //16261 #CJK UNIFIED IDEOGRAPH + {0xF5DC, 0x914B}, //16262 #CJK UNIFIED IDEOGRAPH + {0xF5DD, 0x919C}, //16263 #CJK UNIFIED IDEOGRAPH + {0xF5DE, 0x9310}, //16264 #CJK UNIFIED IDEOGRAPH + {0xF5DF, 0x9318}, //16265 #CJK UNIFIED IDEOGRAPH + {0xF5E0, 0x939A}, //16266 #CJK UNIFIED IDEOGRAPH + {0xF5E1, 0x96DB}, //16267 #CJK UNIFIED IDEOGRAPH + {0xF5E2, 0x9A36}, //16268 #CJK UNIFIED IDEOGRAPH + {0xF5E3, 0x9C0D}, //16269 #CJK UNIFIED IDEOGRAPH + {0xF5E4, 0x4E11}, //16270 #CJK UNIFIED IDEOGRAPH + {0xF5E5, 0x755C}, //16271 #CJK UNIFIED IDEOGRAPH + {0xF5E6, 0x795D}, //16272 #CJK UNIFIED IDEOGRAPH + {0xF5E7, 0x7AFA}, //16273 #CJK UNIFIED IDEOGRAPH + {0xF5E8, 0x7B51}, //16274 #CJK UNIFIED IDEOGRAPH + {0xF5E9, 0x7BC9}, //16275 #CJK UNIFIED IDEOGRAPH + {0xF5EA, 0x7E2E}, //16276 #CJK UNIFIED IDEOGRAPH + {0xF5EB, 0x84C4}, //16277 #CJK UNIFIED IDEOGRAPH + {0xF5EC, 0x8E59}, //16278 #CJK UNIFIED IDEOGRAPH + {0xF5ED, 0x8E74}, //16279 #CJK UNIFIED IDEOGRAPH + {0xF5EE, 0x8EF8}, //16280 #CJK UNIFIED IDEOGRAPH + {0xF5EF, 0x9010}, //16281 #CJK UNIFIED IDEOGRAPH + {0xF5F0, 0x6625}, //16282 #CJK UNIFIED IDEOGRAPH + {0xF5F1, 0x693F}, //16283 #CJK UNIFIED IDEOGRAPH + {0xF5F2, 0x7443}, //16284 #CJK UNIFIED IDEOGRAPH + {0xF5F3, 0x51FA}, //16285 #CJK UNIFIED IDEOGRAPH + {0xF5F4, 0x672E}, //16286 #CJK UNIFIED IDEOGRAPH + {0xF5F5, 0x9EDC}, //16287 #CJK UNIFIED IDEOGRAPH + {0xF5F6, 0x5145}, //16288 #CJK UNIFIED IDEOGRAPH + {0xF5F7, 0x5FE0}, //16289 #CJK UNIFIED IDEOGRAPH + {0xF5F8, 0x6C96}, //16290 #CJK UNIFIED IDEOGRAPH + {0xF5F9, 0x87F2}, //16291 #CJK UNIFIED IDEOGRAPH + {0xF5FA, 0x885D}, //16292 #CJK UNIFIED IDEOGRAPH + {0xF5FB, 0x8877}, //16293 #CJK UNIFIED IDEOGRAPH + {0xF5FC, 0x60B4}, //16294 #CJK UNIFIED IDEOGRAPH + {0xF5FD, 0x81B5}, //16295 #CJK UNIFIED IDEOGRAPH + {0xF5FE, 0x8403}, //16296 #CJK UNIFIED IDEOGRAPH + {0xF6A1, 0x8D05}, //16297 #CJK UNIFIED IDEOGRAPH + {0xF6A2, 0x53D6}, //16298 #CJK UNIFIED IDEOGRAPH + {0xF6A3, 0x5439}, //16299 #CJK UNIFIED IDEOGRAPH + {0xF6A4, 0x5634}, //16300 #CJK UNIFIED IDEOGRAPH + {0xF6A5, 0x5A36}, //16301 #CJK UNIFIED IDEOGRAPH + {0xF6A6, 0x5C31}, //16302 #CJK UNIFIED IDEOGRAPH + {0xF6A7, 0x708A}, //16303 #CJK UNIFIED IDEOGRAPH + {0xF6A8, 0x7FE0}, //16304 #CJK UNIFIED IDEOGRAPH + {0xF6A9, 0x805A}, //16305 #CJK UNIFIED IDEOGRAPH + {0xF6AA, 0x8106}, //16306 #CJK UNIFIED IDEOGRAPH + {0xF6AB, 0x81ED}, //16307 #CJK UNIFIED IDEOGRAPH + {0xF6AC, 0x8DA3}, //16308 #CJK UNIFIED IDEOGRAPH + {0xF6AD, 0x9189}, //16309 #CJK UNIFIED IDEOGRAPH + {0xF6AE, 0x9A5F}, //16310 #CJK UNIFIED IDEOGRAPH + {0xF6AF, 0x9DF2}, //16311 #CJK UNIFIED IDEOGRAPH + {0xF6B0, 0x5074}, //16312 #CJK UNIFIED IDEOGRAPH + {0xF6B1, 0x4EC4}, //16313 #CJK UNIFIED IDEOGRAPH + {0xF6B2, 0x53A0}, //16314 #CJK UNIFIED IDEOGRAPH + {0xF6B3, 0x60FB}, //16315 #CJK UNIFIED IDEOGRAPH + {0xF6B4, 0x6E2C}, //16316 #CJK UNIFIED IDEOGRAPH + {0xF6B5, 0x5C64}, //16317 #CJK UNIFIED IDEOGRAPH + {0xF6B6, 0x4F88}, //16318 #CJK UNIFIED IDEOGRAPH + {0xF6B7, 0x5024}, //16319 #CJK UNIFIED IDEOGRAPH + {0xF6B8, 0x55E4}, //16320 #CJK UNIFIED IDEOGRAPH + {0xF6B9, 0x5CD9}, //16321 #CJK UNIFIED IDEOGRAPH + {0xF6BA, 0x5E5F}, //16322 #CJK UNIFIED IDEOGRAPH + {0xF6BB, 0x6065}, //16323 #CJK UNIFIED IDEOGRAPH + {0xF6BC, 0x6894}, //16324 #CJK UNIFIED IDEOGRAPH + {0xF6BD, 0x6CBB}, //16325 #CJK UNIFIED IDEOGRAPH + {0xF6BE, 0x6DC4}, //16326 #CJK UNIFIED IDEOGRAPH + {0xF6BF, 0x71BE}, //16327 #CJK UNIFIED IDEOGRAPH + {0xF6C0, 0x75D4}, //16328 #CJK UNIFIED IDEOGRAPH + {0xF6C1, 0x75F4}, //16329 #CJK UNIFIED IDEOGRAPH + {0xF6C2, 0x7661}, //16330 #CJK UNIFIED IDEOGRAPH + {0xF6C3, 0x7A1A}, //16331 #CJK UNIFIED IDEOGRAPH + {0xF6C4, 0x7A49}, //16332 #CJK UNIFIED IDEOGRAPH + {0xF6C5, 0x7DC7}, //16333 #CJK UNIFIED IDEOGRAPH + {0xF6C6, 0x7DFB}, //16334 #CJK UNIFIED IDEOGRAPH + {0xF6C7, 0x7F6E}, //16335 #CJK UNIFIED IDEOGRAPH + {0xF6C8, 0x81F4}, //16336 #CJK UNIFIED IDEOGRAPH + {0xF6C9, 0x86A9}, //16337 #CJK UNIFIED IDEOGRAPH + {0xF6CA, 0x8F1C}, //16338 #CJK UNIFIED IDEOGRAPH + {0xF6CB, 0x96C9}, //16339 #CJK UNIFIED IDEOGRAPH + {0xF6CC, 0x99B3}, //16340 #CJK UNIFIED IDEOGRAPH + {0xF6CD, 0x9F52}, //16341 #CJK UNIFIED IDEOGRAPH + {0xF6CE, 0x5247}, //16342 #CJK UNIFIED IDEOGRAPH + {0xF6CF, 0x52C5}, //16343 #CJK UNIFIED IDEOGRAPH + {0xF6D0, 0x98ED}, //16344 #CJK UNIFIED IDEOGRAPH + {0xF6D1, 0x89AA}, //16345 #CJK UNIFIED IDEOGRAPH + {0xF6D2, 0x4E03}, //16346 #CJK UNIFIED IDEOGRAPH + {0xF6D3, 0x67D2}, //16347 #CJK UNIFIED IDEOGRAPH + {0xF6D4, 0x6F06}, //16348 #CJK UNIFIED IDEOGRAPH + {0xF6D5, 0x4FB5}, //16349 #CJK UNIFIED IDEOGRAPH + {0xF6D6, 0x5BE2}, //16350 #CJK UNIFIED IDEOGRAPH + {0xF6D7, 0x6795}, //16351 #CJK UNIFIED IDEOGRAPH + {0xF6D8, 0x6C88}, //16352 #CJK UNIFIED IDEOGRAPH + {0xF6D9, 0x6D78}, //16353 #CJK UNIFIED IDEOGRAPH + {0xF6DA, 0x741B}, //16354 #CJK UNIFIED IDEOGRAPH + {0xF6DB, 0x7827}, //16355 #CJK UNIFIED IDEOGRAPH + {0xF6DC, 0x91DD}, //16356 #CJK UNIFIED IDEOGRAPH + {0xF6DD, 0x937C}, //16357 #CJK UNIFIED IDEOGRAPH + {0xF6DE, 0x87C4}, //16358 #CJK UNIFIED IDEOGRAPH + {0xF6DF, 0x79E4}, //16359 #CJK UNIFIED IDEOGRAPH + {0xF6E0, 0x7A31}, //16360 #CJK UNIFIED IDEOGRAPH + {0xF6E1, 0x5FEB}, //16361 #CJK UNIFIED IDEOGRAPH + {0xF6E2, 0x4ED6}, //16362 #CJK UNIFIED IDEOGRAPH + {0xF6E3, 0x54A4}, //16363 #CJK UNIFIED IDEOGRAPH + {0xF6E4, 0x553E}, //16364 #CJK UNIFIED IDEOGRAPH + {0xF6E5, 0x58AE}, //16365 #CJK UNIFIED IDEOGRAPH + {0xF6E6, 0x59A5}, //16366 #CJK UNIFIED IDEOGRAPH + {0xF6E7, 0x60F0}, //16367 #CJK UNIFIED IDEOGRAPH + {0xF6E8, 0x6253}, //16368 #CJK UNIFIED IDEOGRAPH + {0xF6E9, 0x62D6}, //16369 #CJK UNIFIED IDEOGRAPH + {0xF6EA, 0x6736}, //16370 #CJK UNIFIED IDEOGRAPH + {0xF6EB, 0x6955}, //16371 #CJK UNIFIED IDEOGRAPH + {0xF6EC, 0x8235}, //16372 #CJK UNIFIED IDEOGRAPH + {0xF6ED, 0x9640}, //16373 #CJK UNIFIED IDEOGRAPH + {0xF6EE, 0x99B1}, //16374 #CJK UNIFIED IDEOGRAPH + {0xF6EF, 0x99DD}, //16375 #CJK UNIFIED IDEOGRAPH + {0xF6F0, 0x502C}, //16376 #CJK UNIFIED IDEOGRAPH + {0xF6F1, 0x5353}, //16377 #CJK UNIFIED IDEOGRAPH + {0xF6F2, 0x5544}, //16378 #CJK UNIFIED IDEOGRAPH + {0xF6F3, 0x577C}, //16379 #CJK UNIFIED IDEOGRAPH + {0xF6F4, 0xFA01}, //16380 #CJK COMPATIBILITY IDEOGRAPH + {0xF6F5, 0x6258}, //16381 #CJK UNIFIED IDEOGRAPH + {0xF6F6, 0xFA02}, //16382 #CJK COMPATIBILITY IDEOGRAPH + {0xF6F7, 0x64E2}, //16383 #CJK UNIFIED IDEOGRAPH + {0xF6F8, 0x666B}, //16384 #CJK UNIFIED IDEOGRAPH + {0xF6F9, 0x67DD}, //16385 #CJK UNIFIED IDEOGRAPH + {0xF6FA, 0x6FC1}, //16386 #CJK UNIFIED IDEOGRAPH + {0xF6FB, 0x6FEF}, //16387 #CJK UNIFIED IDEOGRAPH + {0xF6FC, 0x7422}, //16388 #CJK UNIFIED IDEOGRAPH + {0xF6FD, 0x7438}, //16389 #CJK UNIFIED IDEOGRAPH + {0xF6FE, 0x8A17}, //16390 #CJK UNIFIED IDEOGRAPH + {0xF7A1, 0x9438}, //16391 #CJK UNIFIED IDEOGRAPH + {0xF7A2, 0x5451}, //16392 #CJK UNIFIED IDEOGRAPH + {0xF7A3, 0x5606}, //16393 #CJK UNIFIED IDEOGRAPH + {0xF7A4, 0x5766}, //16394 #CJK UNIFIED IDEOGRAPH + {0xF7A5, 0x5F48}, //16395 #CJK UNIFIED IDEOGRAPH + {0xF7A6, 0x619A}, //16396 #CJK UNIFIED IDEOGRAPH + {0xF7A7, 0x6B4E}, //16397 #CJK UNIFIED IDEOGRAPH + {0xF7A8, 0x7058}, //16398 #CJK UNIFIED IDEOGRAPH + {0xF7A9, 0x70AD}, //16399 #CJK UNIFIED IDEOGRAPH + {0xF7AA, 0x7DBB}, //16400 #CJK UNIFIED IDEOGRAPH + {0xF7AB, 0x8A95}, //16401 #CJK UNIFIED IDEOGRAPH + {0xF7AC, 0x596A}, //16402 #CJK UNIFIED IDEOGRAPH + {0xF7AD, 0x812B}, //16403 #CJK UNIFIED IDEOGRAPH + {0xF7AE, 0x63A2}, //16404 #CJK UNIFIED IDEOGRAPH + {0xF7AF, 0x7708}, //16405 #CJK UNIFIED IDEOGRAPH + {0xF7B0, 0x803D}, //16406 #CJK UNIFIED IDEOGRAPH + {0xF7B1, 0x8CAA}, //16407 #CJK UNIFIED IDEOGRAPH + {0xF7B2, 0x5854}, //16408 #CJK UNIFIED IDEOGRAPH + {0xF7B3, 0x642D}, //16409 #CJK UNIFIED IDEOGRAPH + {0xF7B4, 0x69BB}, //16410 #CJK UNIFIED IDEOGRAPH + {0xF7B5, 0x5B95}, //16411 #CJK UNIFIED IDEOGRAPH + {0xF7B6, 0x5E11}, //16412 #CJK UNIFIED IDEOGRAPH + {0xF7B7, 0x6E6F}, //16413 #CJK UNIFIED IDEOGRAPH + {0xF7B8, 0xFA03}, //16414 #CJK COMPATIBILITY IDEOGRAPH + {0xF7B9, 0x8569}, //16415 #CJK UNIFIED IDEOGRAPH + {0xF7BA, 0x514C}, //16416 #CJK UNIFIED IDEOGRAPH + {0xF7BB, 0x53F0}, //16417 #CJK UNIFIED IDEOGRAPH + {0xF7BC, 0x592A}, //16418 #CJK UNIFIED IDEOGRAPH + {0xF7BD, 0x6020}, //16419 #CJK UNIFIED IDEOGRAPH + {0xF7BE, 0x614B}, //16420 #CJK UNIFIED IDEOGRAPH + {0xF7BF, 0x6B86}, //16421 #CJK UNIFIED IDEOGRAPH + {0xF7C0, 0x6C70}, //16422 #CJK UNIFIED IDEOGRAPH + {0xF7C1, 0x6CF0}, //16423 #CJK UNIFIED IDEOGRAPH + {0xF7C2, 0x7B1E}, //16424 #CJK UNIFIED IDEOGRAPH + {0xF7C3, 0x80CE}, //16425 #CJK UNIFIED IDEOGRAPH + {0xF7C4, 0x82D4}, //16426 #CJK UNIFIED IDEOGRAPH + {0xF7C5, 0x8DC6}, //16427 #CJK UNIFIED IDEOGRAPH + {0xF7C6, 0x90B0}, //16428 #CJK UNIFIED IDEOGRAPH + {0xF7C7, 0x98B1}, //16429 #CJK UNIFIED IDEOGRAPH + {0xF7C8, 0xFA04}, //16430 #CJK COMPATIBILITY IDEOGRAPH + {0xF7C9, 0x64C7}, //16431 #CJK UNIFIED IDEOGRAPH + {0xF7CA, 0x6FA4}, //16432 #CJK UNIFIED IDEOGRAPH + {0xF7CB, 0x6491}, //16433 #CJK UNIFIED IDEOGRAPH + {0xF7CC, 0x6504}, //16434 #CJK UNIFIED IDEOGRAPH + {0xF7CD, 0x514E}, //16435 #CJK UNIFIED IDEOGRAPH + {0xF7CE, 0x5410}, //16436 #CJK UNIFIED IDEOGRAPH + {0xF7CF, 0x571F}, //16437 #CJK UNIFIED IDEOGRAPH + {0xF7D0, 0x8A0E}, //16438 #CJK UNIFIED IDEOGRAPH + {0xF7D1, 0x615F}, //16439 #CJK UNIFIED IDEOGRAPH + {0xF7D2, 0x6876}, //16440 #CJK UNIFIED IDEOGRAPH + {0xF7D3, 0xFA05}, //16441 #CJK COMPATIBILITY IDEOGRAPH + {0xF7D4, 0x75DB}, //16442 #CJK UNIFIED IDEOGRAPH + {0xF7D5, 0x7B52}, //16443 #CJK UNIFIED IDEOGRAPH + {0xF7D6, 0x7D71}, //16444 #CJK UNIFIED IDEOGRAPH + {0xF7D7, 0x901A}, //16445 #CJK UNIFIED IDEOGRAPH + {0xF7D8, 0x5806}, //16446 #CJK UNIFIED IDEOGRAPH + {0xF7D9, 0x69CC}, //16447 #CJK UNIFIED IDEOGRAPH + {0xF7DA, 0x817F}, //16448 #CJK UNIFIED IDEOGRAPH + {0xF7DB, 0x892A}, //16449 #CJK UNIFIED IDEOGRAPH + {0xF7DC, 0x9000}, //16450 #CJK UNIFIED IDEOGRAPH + {0xF7DD, 0x9839}, //16451 #CJK UNIFIED IDEOGRAPH + {0xF7DE, 0x5078}, //16452 #CJK UNIFIED IDEOGRAPH + {0xF7DF, 0x5957}, //16453 #CJK UNIFIED IDEOGRAPH + {0xF7E0, 0x59AC}, //16454 #CJK UNIFIED IDEOGRAPH + {0xF7E1, 0x6295}, //16455 #CJK UNIFIED IDEOGRAPH + {0xF7E2, 0x900F}, //16456 #CJK UNIFIED IDEOGRAPH + {0xF7E3, 0x9B2A}, //16457 #CJK UNIFIED IDEOGRAPH + {0xF7E4, 0x615D}, //16458 #CJK UNIFIED IDEOGRAPH + {0xF7E5, 0x7279}, //16459 #CJK UNIFIED IDEOGRAPH + {0xF7E6, 0x95D6}, //16460 #CJK UNIFIED IDEOGRAPH + {0xF7E7, 0x5761}, //16461 #CJK UNIFIED IDEOGRAPH + {0xF7E8, 0x5A46}, //16462 #CJK UNIFIED IDEOGRAPH + {0xF7E9, 0x5DF4}, //16463 #CJK UNIFIED IDEOGRAPH + {0xF7EA, 0x628A}, //16464 #CJK UNIFIED IDEOGRAPH + {0xF7EB, 0x64AD}, //16465 #CJK UNIFIED IDEOGRAPH + {0xF7EC, 0x64FA}, //16466 #CJK UNIFIED IDEOGRAPH + {0xF7ED, 0x6777}, //16467 #CJK UNIFIED IDEOGRAPH + {0xF7EE, 0x6CE2}, //16468 #CJK UNIFIED IDEOGRAPH + {0xF7EF, 0x6D3E}, //16469 #CJK UNIFIED IDEOGRAPH + {0xF7F0, 0x722C}, //16470 #CJK UNIFIED IDEOGRAPH + {0xF7F1, 0x7436}, //16471 #CJK UNIFIED IDEOGRAPH + {0xF7F2, 0x7834}, //16472 #CJK UNIFIED IDEOGRAPH + {0xF7F3, 0x7F77}, //16473 #CJK UNIFIED IDEOGRAPH + {0xF7F4, 0x82AD}, //16474 #CJK UNIFIED IDEOGRAPH + {0xF7F5, 0x8DDB}, //16475 #CJK UNIFIED IDEOGRAPH + {0xF7F6, 0x9817}, //16476 #CJK UNIFIED IDEOGRAPH + {0xF7F7, 0x5224}, //16477 #CJK UNIFIED IDEOGRAPH + {0xF7F8, 0x5742}, //16478 #CJK UNIFIED IDEOGRAPH + {0xF7F9, 0x677F}, //16479 #CJK UNIFIED IDEOGRAPH + {0xF7FA, 0x7248}, //16480 #CJK UNIFIED IDEOGRAPH + {0xF7FB, 0x74E3}, //16481 #CJK UNIFIED IDEOGRAPH + {0xF7FC, 0x8CA9}, //16482 #CJK UNIFIED IDEOGRAPH + {0xF7FD, 0x8FA6}, //16483 #CJK UNIFIED IDEOGRAPH + {0xF7FE, 0x9211}, //16484 #CJK UNIFIED IDEOGRAPH + {0xF8A1, 0x962A}, //16485 #CJK UNIFIED IDEOGRAPH + {0xF8A2, 0x516B}, //16486 #CJK UNIFIED IDEOGRAPH + {0xF8A3, 0x53ED}, //16487 #CJK UNIFIED IDEOGRAPH + {0xF8A4, 0x634C}, //16488 #CJK UNIFIED IDEOGRAPH + {0xF8A5, 0x4F69}, //16489 #CJK UNIFIED IDEOGRAPH + {0xF8A6, 0x5504}, //16490 #CJK UNIFIED IDEOGRAPH + {0xF8A7, 0x6096}, //16491 #CJK UNIFIED IDEOGRAPH + {0xF8A8, 0x6557}, //16492 #CJK UNIFIED IDEOGRAPH + {0xF8A9, 0x6C9B}, //16493 #CJK UNIFIED IDEOGRAPH + {0xF8AA, 0x6D7F}, //16494 #CJK UNIFIED IDEOGRAPH + {0xF8AB, 0x724C}, //16495 #CJK UNIFIED IDEOGRAPH + {0xF8AC, 0x72FD}, //16496 #CJK UNIFIED IDEOGRAPH + {0xF8AD, 0x7A17}, //16497 #CJK UNIFIED IDEOGRAPH + {0xF8AE, 0x8987}, //16498 #CJK UNIFIED IDEOGRAPH + {0xF8AF, 0x8C9D}, //16499 #CJK UNIFIED IDEOGRAPH + {0xF8B0, 0x5F6D}, //16500 #CJK UNIFIED IDEOGRAPH + {0xF8B1, 0x6F8E}, //16501 #CJK UNIFIED IDEOGRAPH + {0xF8B2, 0x70F9}, //16502 #CJK UNIFIED IDEOGRAPH + {0xF8B3, 0x81A8}, //16503 #CJK UNIFIED IDEOGRAPH + {0xF8B4, 0x610E}, //16504 #CJK UNIFIED IDEOGRAPH + {0xF8B5, 0x4FBF}, //16505 #CJK UNIFIED IDEOGRAPH + {0xF8B6, 0x504F}, //16506 #CJK UNIFIED IDEOGRAPH + {0xF8B7, 0x6241}, //16507 #CJK UNIFIED IDEOGRAPH + {0xF8B8, 0x7247}, //16508 #CJK UNIFIED IDEOGRAPH + {0xF8B9, 0x7BC7}, //16509 #CJK UNIFIED IDEOGRAPH + {0xF8BA, 0x7DE8}, //16510 #CJK UNIFIED IDEOGRAPH + {0xF8BB, 0x7FE9}, //16511 #CJK UNIFIED IDEOGRAPH + {0xF8BC, 0x904D}, //16512 #CJK UNIFIED IDEOGRAPH + {0xF8BD, 0x97AD}, //16513 #CJK UNIFIED IDEOGRAPH + {0xF8BE, 0x9A19}, //16514 #CJK UNIFIED IDEOGRAPH + {0xF8BF, 0x8CB6}, //16515 #CJK UNIFIED IDEOGRAPH + {0xF8C0, 0x576A}, //16516 #CJK UNIFIED IDEOGRAPH + {0xF8C1, 0x5E73}, //16517 #CJK UNIFIED IDEOGRAPH + {0xF8C2, 0x67B0}, //16518 #CJK UNIFIED IDEOGRAPH + {0xF8C3, 0x840D}, //16519 #CJK UNIFIED IDEOGRAPH + {0xF8C4, 0x8A55}, //16520 #CJK UNIFIED IDEOGRAPH + {0xF8C5, 0x5420}, //16521 #CJK UNIFIED IDEOGRAPH + {0xF8C6, 0x5B16}, //16522 #CJK UNIFIED IDEOGRAPH + {0xF8C7, 0x5E63}, //16523 #CJK UNIFIED IDEOGRAPH + {0xF8C8, 0x5EE2}, //16524 #CJK UNIFIED IDEOGRAPH + {0xF8C9, 0x5F0A}, //16525 #CJK UNIFIED IDEOGRAPH + {0xF8CA, 0x6583}, //16526 #CJK UNIFIED IDEOGRAPH + {0xF8CB, 0x80BA}, //16527 #CJK UNIFIED IDEOGRAPH + {0xF8CC, 0x853D}, //16528 #CJK UNIFIED IDEOGRAPH + {0xF8CD, 0x9589}, //16529 #CJK UNIFIED IDEOGRAPH + {0xF8CE, 0x965B}, //16530 #CJK UNIFIED IDEOGRAPH + {0xF8CF, 0x4F48}, //16531 #CJK UNIFIED IDEOGRAPH + {0xF8D0, 0x5305}, //16532 #CJK UNIFIED IDEOGRAPH + {0xF8D1, 0x530D}, //16533 #CJK UNIFIED IDEOGRAPH + {0xF8D2, 0x530F}, //16534 #CJK UNIFIED IDEOGRAPH + {0xF8D3, 0x5486}, //16535 #CJK UNIFIED IDEOGRAPH + {0xF8D4, 0x54FA}, //16536 #CJK UNIFIED IDEOGRAPH + {0xF8D5, 0x5703}, //16537 #CJK UNIFIED IDEOGRAPH + {0xF8D6, 0x5E03}, //16538 #CJK UNIFIED IDEOGRAPH + {0xF8D7, 0x6016}, //16539 #CJK UNIFIED IDEOGRAPH + {0xF8D8, 0x629B}, //16540 #CJK UNIFIED IDEOGRAPH + {0xF8D9, 0x62B1}, //16541 #CJK UNIFIED IDEOGRAPH + {0xF8DA, 0x6355}, //16542 #CJK UNIFIED IDEOGRAPH + {0xF8DB, 0xFA06}, //16543 #CJK COMPATIBILITY IDEOGRAPH + {0xF8DC, 0x6CE1}, //16544 #CJK UNIFIED IDEOGRAPH + {0xF8DD, 0x6D66}, //16545 #CJK UNIFIED IDEOGRAPH + {0xF8DE, 0x75B1}, //16546 #CJK UNIFIED IDEOGRAPH + {0xF8DF, 0x7832}, //16547 #CJK UNIFIED IDEOGRAPH + {0xF8E0, 0x80DE}, //16548 #CJK UNIFIED IDEOGRAPH + {0xF8E1, 0x812F}, //16549 #CJK UNIFIED IDEOGRAPH + {0xF8E2, 0x82DE}, //16550 #CJK UNIFIED IDEOGRAPH + {0xF8E3, 0x8461}, //16551 #CJK UNIFIED IDEOGRAPH + {0xF8E4, 0x84B2}, //16552 #CJK UNIFIED IDEOGRAPH + {0xF8E5, 0x888D}, //16553 #CJK UNIFIED IDEOGRAPH + {0xF8E6, 0x8912}, //16554 #CJK UNIFIED IDEOGRAPH + {0xF8E7, 0x900B}, //16555 #CJK UNIFIED IDEOGRAPH + {0xF8E8, 0x92EA}, //16556 #CJK UNIFIED IDEOGRAPH + {0xF8E9, 0x98FD}, //16557 #CJK UNIFIED IDEOGRAPH + {0xF8EA, 0x9B91}, //16558 #CJK UNIFIED IDEOGRAPH + {0xF8EB, 0x5E45}, //16559 #CJK UNIFIED IDEOGRAPH + {0xF8EC, 0x66B4}, //16560 #CJK UNIFIED IDEOGRAPH + {0xF8ED, 0x66DD}, //16561 #CJK UNIFIED IDEOGRAPH + {0xF8EE, 0x7011}, //16562 #CJK UNIFIED IDEOGRAPH + {0xF8EF, 0x7206}, //16563 #CJK UNIFIED IDEOGRAPH + {0xF8F0, 0xFA07}, //16564 #CJK COMPATIBILITY IDEOGRAPH + {0xF8F1, 0x4FF5}, //16565 #CJK UNIFIED IDEOGRAPH + {0xF8F2, 0x527D}, //16566 #CJK UNIFIED IDEOGRAPH + {0xF8F3, 0x5F6A}, //16567 #CJK UNIFIED IDEOGRAPH + {0xF8F4, 0x6153}, //16568 #CJK UNIFIED IDEOGRAPH + {0xF8F5, 0x6753}, //16569 #CJK UNIFIED IDEOGRAPH + {0xF8F6, 0x6A19}, //16570 #CJK UNIFIED IDEOGRAPH + {0xF8F7, 0x6F02}, //16571 #CJK UNIFIED IDEOGRAPH + {0xF8F8, 0x74E2}, //16572 #CJK UNIFIED IDEOGRAPH + {0xF8F9, 0x7968}, //16573 #CJK UNIFIED IDEOGRAPH + {0xF8FA, 0x8868}, //16574 #CJK UNIFIED IDEOGRAPH + {0xF8FB, 0x8C79}, //16575 #CJK UNIFIED IDEOGRAPH + {0xF8FC, 0x98C7}, //16576 #CJK UNIFIED IDEOGRAPH + {0xF8FD, 0x98C4}, //16577 #CJK UNIFIED IDEOGRAPH + {0xF8FE, 0x9A43}, //16578 #CJK UNIFIED IDEOGRAPH + {0xF9A1, 0x54C1}, //16579 #CJK UNIFIED IDEOGRAPH + {0xF9A2, 0x7A1F}, //16580 #CJK UNIFIED IDEOGRAPH + {0xF9A3, 0x6953}, //16581 #CJK UNIFIED IDEOGRAPH + {0xF9A4, 0x8AF7}, //16582 #CJK UNIFIED IDEOGRAPH + {0xF9A5, 0x8C4A}, //16583 #CJK UNIFIED IDEOGRAPH + {0xF9A6, 0x98A8}, //16584 #CJK UNIFIED IDEOGRAPH + {0xF9A7, 0x99AE}, //16585 #CJK UNIFIED IDEOGRAPH + {0xF9A8, 0x5F7C}, //16586 #CJK UNIFIED IDEOGRAPH + {0xF9A9, 0x62AB}, //16587 #CJK UNIFIED IDEOGRAPH + {0xF9AA, 0x75B2}, //16588 #CJK UNIFIED IDEOGRAPH + {0xF9AB, 0x76AE}, //16589 #CJK UNIFIED IDEOGRAPH + {0xF9AC, 0x88AB}, //16590 #CJK UNIFIED IDEOGRAPH + {0xF9AD, 0x907F}, //16591 #CJK UNIFIED IDEOGRAPH + {0xF9AE, 0x9642}, //16592 #CJK UNIFIED IDEOGRAPH + {0xF9AF, 0x5339}, //16593 #CJK UNIFIED IDEOGRAPH + {0xF9B0, 0x5F3C}, //16594 #CJK UNIFIED IDEOGRAPH + {0xF9B1, 0x5FC5}, //16595 #CJK UNIFIED IDEOGRAPH + {0xF9B2, 0x6CCC}, //16596 #CJK UNIFIED IDEOGRAPH + {0xF9B3, 0x73CC}, //16597 #CJK UNIFIED IDEOGRAPH + {0xF9B4, 0x7562}, //16598 #CJK UNIFIED IDEOGRAPH + {0xF9B5, 0x758B}, //16599 #CJK UNIFIED IDEOGRAPH + {0xF9B6, 0x7B46}, //16600 #CJK UNIFIED IDEOGRAPH + {0xF9B7, 0x82FE}, //16601 #CJK UNIFIED IDEOGRAPH + {0xF9B8, 0x999D}, //16602 #CJK UNIFIED IDEOGRAPH + {0xF9B9, 0x4E4F}, //16603 #CJK UNIFIED IDEOGRAPH + {0xF9BA, 0x903C}, //16604 #CJK UNIFIED IDEOGRAPH + {0xF9BB, 0x4E0B}, //16605 #CJK UNIFIED IDEOGRAPH + {0xF9BC, 0x4F55}, //16606 #CJK UNIFIED IDEOGRAPH + {0xF9BD, 0x53A6}, //16607 #CJK UNIFIED IDEOGRAPH + {0xF9BE, 0x590F}, //16608 #CJK UNIFIED IDEOGRAPH + {0xF9BF, 0x5EC8}, //16609 #CJK UNIFIED IDEOGRAPH + {0xF9C0, 0x6630}, //16610 #CJK UNIFIED IDEOGRAPH + {0xF9C1, 0x6CB3}, //16611 #CJK UNIFIED IDEOGRAPH + {0xF9C2, 0x7455}, //16612 #CJK UNIFIED IDEOGRAPH + {0xF9C3, 0x8377}, //16613 #CJK UNIFIED IDEOGRAPH + {0xF9C4, 0x8766}, //16614 #CJK UNIFIED IDEOGRAPH + {0xF9C5, 0x8CC0}, //16615 #CJK UNIFIED IDEOGRAPH + {0xF9C6, 0x9050}, //16616 #CJK UNIFIED IDEOGRAPH + {0xF9C7, 0x971E}, //16617 #CJK UNIFIED IDEOGRAPH + {0xF9C8, 0x9C15}, //16618 #CJK UNIFIED IDEOGRAPH + {0xF9C9, 0x58D1}, //16619 #CJK UNIFIED IDEOGRAPH + {0xF9CA, 0x5B78}, //16620 #CJK UNIFIED IDEOGRAPH + {0xF9CB, 0x8650}, //16621 #CJK UNIFIED IDEOGRAPH + {0xF9CC, 0x8B14}, //16622 #CJK UNIFIED IDEOGRAPH + {0xF9CD, 0x9DB4}, //16623 #CJK UNIFIED IDEOGRAPH + {0xF9CE, 0x5BD2}, //16624 #CJK UNIFIED IDEOGRAPH + {0xF9CF, 0x6068}, //16625 #CJK UNIFIED IDEOGRAPH + {0xF9D0, 0x608D}, //16626 #CJK UNIFIED IDEOGRAPH + {0xF9D1, 0x65F1}, //16627 #CJK UNIFIED IDEOGRAPH + {0xF9D2, 0x6C57}, //16628 #CJK UNIFIED IDEOGRAPH + {0xF9D3, 0x6F22}, //16629 #CJK UNIFIED IDEOGRAPH + {0xF9D4, 0x6FA3}, //16630 #CJK UNIFIED IDEOGRAPH + {0xF9D5, 0x701A}, //16631 #CJK UNIFIED IDEOGRAPH + {0xF9D6, 0x7F55}, //16632 #CJK UNIFIED IDEOGRAPH + {0xF9D7, 0x7FF0}, //16633 #CJK UNIFIED IDEOGRAPH + {0xF9D8, 0x9591}, //16634 #CJK UNIFIED IDEOGRAPH + {0xF9D9, 0x9592}, //16635 #CJK UNIFIED IDEOGRAPH + {0xF9DA, 0x9650}, //16636 #CJK UNIFIED IDEOGRAPH + {0xF9DB, 0x97D3}, //16637 #CJK UNIFIED IDEOGRAPH + {0xF9DC, 0x5272}, //16638 #CJK UNIFIED IDEOGRAPH + {0xF9DD, 0x8F44}, //16639 #CJK UNIFIED IDEOGRAPH + {0xF9DE, 0x51FD}, //16640 #CJK UNIFIED IDEOGRAPH + {0xF9DF, 0x542B}, //16641 #CJK UNIFIED IDEOGRAPH + {0xF9E0, 0x54B8}, //16642 #CJK UNIFIED IDEOGRAPH + {0xF9E1, 0x5563}, //16643 #CJK UNIFIED IDEOGRAPH + {0xF9E2, 0x558A}, //16644 #CJK UNIFIED IDEOGRAPH + {0xF9E3, 0x6ABB}, //16645 #CJK UNIFIED IDEOGRAPH + {0xF9E4, 0x6DB5}, //16646 #CJK UNIFIED IDEOGRAPH + {0xF9E5, 0x7DD8}, //16647 #CJK UNIFIED IDEOGRAPH + {0xF9E6, 0x8266}, //16648 #CJK UNIFIED IDEOGRAPH + {0xF9E7, 0x929C}, //16649 #CJK UNIFIED IDEOGRAPH + {0xF9E8, 0x9677}, //16650 #CJK UNIFIED IDEOGRAPH + {0xF9E9, 0x9E79}, //16651 #CJK UNIFIED IDEOGRAPH + {0xF9EA, 0x5408}, //16652 #CJK UNIFIED IDEOGRAPH + {0xF9EB, 0x54C8}, //16653 #CJK UNIFIED IDEOGRAPH + {0xF9EC, 0x76D2}, //16654 #CJK UNIFIED IDEOGRAPH + {0xF9ED, 0x86E4}, //16655 #CJK UNIFIED IDEOGRAPH + {0xF9EE, 0x95A4}, //16656 #CJK UNIFIED IDEOGRAPH + {0xF9EF, 0x95D4}, //16657 #CJK UNIFIED IDEOGRAPH + {0xF9F0, 0x965C}, //16658 #CJK UNIFIED IDEOGRAPH + {0xF9F1, 0x4EA2}, //16659 #CJK UNIFIED IDEOGRAPH + {0xF9F2, 0x4F09}, //16660 #CJK UNIFIED IDEOGRAPH + {0xF9F3, 0x59EE}, //16661 #CJK UNIFIED IDEOGRAPH + {0xF9F4, 0x5AE6}, //16662 #CJK UNIFIED IDEOGRAPH + {0xF9F5, 0x5DF7}, //16663 #CJK UNIFIED IDEOGRAPH + {0xF9F6, 0x6052}, //16664 #CJK UNIFIED IDEOGRAPH + {0xF9F7, 0x6297}, //16665 #CJK UNIFIED IDEOGRAPH + {0xF9F8, 0x676D}, //16666 #CJK UNIFIED IDEOGRAPH + {0xF9F9, 0x6841}, //16667 #CJK UNIFIED IDEOGRAPH + {0xF9FA, 0x6C86}, //16668 #CJK UNIFIED IDEOGRAPH + {0xF9FB, 0x6E2F}, //16669 #CJK UNIFIED IDEOGRAPH + {0xF9FC, 0x7F38}, //16670 #CJK UNIFIED IDEOGRAPH + {0xF9FD, 0x809B}, //16671 #CJK UNIFIED IDEOGRAPH + {0xF9FE, 0x822A}, //16672 #CJK UNIFIED IDEOGRAPH + {0xFAA1, 0xFA08}, //16673 #CJK COMPATIBILITY IDEOGRAPH + {0xFAA2, 0xFA09}, //16674 #CJK COMPATIBILITY IDEOGRAPH + {0xFAA3, 0x9805}, //16675 #CJK UNIFIED IDEOGRAPH + {0xFAA4, 0x4EA5}, //16676 #CJK UNIFIED IDEOGRAPH + {0xFAA5, 0x5055}, //16677 #CJK UNIFIED IDEOGRAPH + {0xFAA6, 0x54B3}, //16678 #CJK UNIFIED IDEOGRAPH + {0xFAA7, 0x5793}, //16679 #CJK UNIFIED IDEOGRAPH + {0xFAA8, 0x595A}, //16680 #CJK UNIFIED IDEOGRAPH + {0xFAA9, 0x5B69}, //16681 #CJK UNIFIED IDEOGRAPH + {0xFAAA, 0x5BB3}, //16682 #CJK UNIFIED IDEOGRAPH + {0xFAAB, 0x61C8}, //16683 #CJK UNIFIED IDEOGRAPH + {0xFAAC, 0x6977}, //16684 #CJK UNIFIED IDEOGRAPH + {0xFAAD, 0x6D77}, //16685 #CJK UNIFIED IDEOGRAPH + {0xFAAE, 0x7023}, //16686 #CJK UNIFIED IDEOGRAPH + {0xFAAF, 0x87F9}, //16687 #CJK UNIFIED IDEOGRAPH + {0xFAB0, 0x89E3}, //16688 #CJK UNIFIED IDEOGRAPH + {0xFAB1, 0x8A72}, //16689 #CJK UNIFIED IDEOGRAPH + {0xFAB2, 0x8AE7}, //16690 #CJK UNIFIED IDEOGRAPH + {0xFAB3, 0x9082}, //16691 #CJK UNIFIED IDEOGRAPH + {0xFAB4, 0x99ED}, //16692 #CJK UNIFIED IDEOGRAPH + {0xFAB5, 0x9AB8}, //16693 #CJK UNIFIED IDEOGRAPH + {0xFAB6, 0x52BE}, //16694 #CJK UNIFIED IDEOGRAPH + {0xFAB7, 0x6838}, //16695 #CJK UNIFIED IDEOGRAPH + {0xFAB8, 0x5016}, //16696 #CJK UNIFIED IDEOGRAPH + {0xFAB9, 0x5E78}, //16697 #CJK UNIFIED IDEOGRAPH + {0xFABA, 0x674F}, //16698 #CJK UNIFIED IDEOGRAPH + {0xFABB, 0x8347}, //16699 #CJK UNIFIED IDEOGRAPH + {0xFABC, 0x884C}, //16700 #CJK UNIFIED IDEOGRAPH + {0xFABD, 0x4EAB}, //16701 #CJK UNIFIED IDEOGRAPH + {0xFABE, 0x5411}, //16702 #CJK UNIFIED IDEOGRAPH + {0xFABF, 0x56AE}, //16703 #CJK UNIFIED IDEOGRAPH + {0xFAC0, 0x73E6}, //16704 #CJK UNIFIED IDEOGRAPH + {0xFAC1, 0x9115}, //16705 #CJK UNIFIED IDEOGRAPH + {0xFAC2, 0x97FF}, //16706 #CJK UNIFIED IDEOGRAPH + {0xFAC3, 0x9909}, //16707 #CJK UNIFIED IDEOGRAPH + {0xFAC4, 0x9957}, //16708 #CJK UNIFIED IDEOGRAPH + {0xFAC5, 0x9999}, //16709 #CJK UNIFIED IDEOGRAPH + {0xFAC6, 0x5653}, //16710 #CJK UNIFIED IDEOGRAPH + {0xFAC7, 0x589F}, //16711 #CJK UNIFIED IDEOGRAPH + {0xFAC8, 0x865B}, //16712 #CJK UNIFIED IDEOGRAPH + {0xFAC9, 0x8A31}, //16713 #CJK UNIFIED IDEOGRAPH + {0xFACA, 0x61B2}, //16714 #CJK UNIFIED IDEOGRAPH + {0xFACB, 0x6AF6}, //16715 #CJK UNIFIED IDEOGRAPH + {0xFACC, 0x737B}, //16716 #CJK UNIFIED IDEOGRAPH + {0xFACD, 0x8ED2}, //16717 #CJK UNIFIED IDEOGRAPH + {0xFACE, 0x6B47}, //16718 #CJK UNIFIED IDEOGRAPH + {0xFACF, 0x96AA}, //16719 #CJK UNIFIED IDEOGRAPH + {0xFAD0, 0x9A57}, //16720 #CJK UNIFIED IDEOGRAPH + {0xFAD1, 0x5955}, //16721 #CJK UNIFIED IDEOGRAPH + {0xFAD2, 0x7200}, //16722 #CJK UNIFIED IDEOGRAPH + {0xFAD3, 0x8D6B}, //16723 #CJK UNIFIED IDEOGRAPH + {0xFAD4, 0x9769}, //16724 #CJK UNIFIED IDEOGRAPH + {0xFAD5, 0x4FD4}, //16725 #CJK UNIFIED IDEOGRAPH + {0xFAD6, 0x5CF4}, //16726 #CJK UNIFIED IDEOGRAPH + {0xFAD7, 0x5F26}, //16727 #CJK UNIFIED IDEOGRAPH + {0xFAD8, 0x61F8}, //16728 #CJK UNIFIED IDEOGRAPH + {0xFAD9, 0x665B}, //16729 #CJK UNIFIED IDEOGRAPH + {0xFADA, 0x6CEB}, //16730 #CJK UNIFIED IDEOGRAPH + {0xFADB, 0x70AB}, //16731 #CJK UNIFIED IDEOGRAPH + {0xFADC, 0x7384}, //16732 #CJK UNIFIED IDEOGRAPH + {0xFADD, 0x73B9}, //16733 #CJK UNIFIED IDEOGRAPH + {0xFADE, 0x73FE}, //16734 #CJK UNIFIED IDEOGRAPH + {0xFADF, 0x7729}, //16735 #CJK UNIFIED IDEOGRAPH + {0xFAE0, 0x774D}, //16736 #CJK UNIFIED IDEOGRAPH + {0xFAE1, 0x7D43}, //16737 #CJK UNIFIED IDEOGRAPH + {0xFAE2, 0x7D62}, //16738 #CJK UNIFIED IDEOGRAPH + {0xFAE3, 0x7E23}, //16739 #CJK UNIFIED IDEOGRAPH + {0xFAE4, 0x8237}, //16740 #CJK UNIFIED IDEOGRAPH + {0xFAE5, 0x8852}, //16741 #CJK UNIFIED IDEOGRAPH + {0xFAE6, 0xFA0A}, //16742 #CJK COMPATIBILITY IDEOGRAPH + {0xFAE7, 0x8CE2}, //16743 #CJK UNIFIED IDEOGRAPH + {0xFAE8, 0x9249}, //16744 #CJK UNIFIED IDEOGRAPH + {0xFAE9, 0x986F}, //16745 #CJK UNIFIED IDEOGRAPH + {0xFAEA, 0x5B51}, //16746 #CJK UNIFIED IDEOGRAPH + {0xFAEB, 0x7A74}, //16747 #CJK UNIFIED IDEOGRAPH + {0xFAEC, 0x8840}, //16748 #CJK UNIFIED IDEOGRAPH + {0xFAED, 0x9801}, //16749 #CJK UNIFIED IDEOGRAPH + {0xFAEE, 0x5ACC}, //16750 #CJK UNIFIED IDEOGRAPH + {0xFAEF, 0x4FE0}, //16751 #CJK UNIFIED IDEOGRAPH + {0xFAF0, 0x5354}, //16752 #CJK UNIFIED IDEOGRAPH + {0xFAF1, 0x593E}, //16753 #CJK UNIFIED IDEOGRAPH + {0xFAF2, 0x5CFD}, //16754 #CJK UNIFIED IDEOGRAPH + {0xFAF3, 0x633E}, //16755 #CJK UNIFIED IDEOGRAPH + {0xFAF4, 0x6D79}, //16756 #CJK UNIFIED IDEOGRAPH + {0xFAF5, 0x72F9}, //16757 #CJK UNIFIED IDEOGRAPH + {0xFAF6, 0x8105}, //16758 #CJK UNIFIED IDEOGRAPH + {0xFAF7, 0x8107}, //16759 #CJK UNIFIED IDEOGRAPH + {0xFAF8, 0x83A2}, //16760 #CJK UNIFIED IDEOGRAPH + {0xFAF9, 0x92CF}, //16761 #CJK UNIFIED IDEOGRAPH + {0xFAFA, 0x9830}, //16762 #CJK UNIFIED IDEOGRAPH + {0xFAFB, 0x4EA8}, //16763 #CJK UNIFIED IDEOGRAPH + {0xFAFC, 0x5144}, //16764 #CJK UNIFIED IDEOGRAPH + {0xFAFD, 0x5211}, //16765 #CJK UNIFIED IDEOGRAPH + {0xFAFE, 0x578B}, //16766 #CJK UNIFIED IDEOGRAPH + {0xFBA1, 0x5F62}, //16767 #CJK UNIFIED IDEOGRAPH + {0xFBA2, 0x6CC2}, //16768 #CJK UNIFIED IDEOGRAPH + {0xFBA3, 0x6ECE}, //16769 #CJK UNIFIED IDEOGRAPH + {0xFBA4, 0x7005}, //16770 #CJK UNIFIED IDEOGRAPH + {0xFBA5, 0x7050}, //16771 #CJK UNIFIED IDEOGRAPH + {0xFBA6, 0x70AF}, //16772 #CJK UNIFIED IDEOGRAPH + {0xFBA7, 0x7192}, //16773 #CJK UNIFIED IDEOGRAPH + {0xFBA8, 0x73E9}, //16774 #CJK UNIFIED IDEOGRAPH + {0xFBA9, 0x7469}, //16775 #CJK UNIFIED IDEOGRAPH + {0xFBAA, 0x834A}, //16776 #CJK UNIFIED IDEOGRAPH + {0xFBAB, 0x87A2}, //16777 #CJK UNIFIED IDEOGRAPH + {0xFBAC, 0x8861}, //16778 #CJK UNIFIED IDEOGRAPH + {0xFBAD, 0x9008}, //16779 #CJK UNIFIED IDEOGRAPH + {0xFBAE, 0x90A2}, //16780 #CJK UNIFIED IDEOGRAPH + {0xFBAF, 0x93A3}, //16781 #CJK UNIFIED IDEOGRAPH + {0xFBB0, 0x99A8}, //16782 #CJK UNIFIED IDEOGRAPH + {0xFBB1, 0x516E}, //16783 #CJK UNIFIED IDEOGRAPH + {0xFBB2, 0x5F57}, //16784 #CJK UNIFIED IDEOGRAPH + {0xFBB3, 0x60E0}, //16785 #CJK UNIFIED IDEOGRAPH + {0xFBB4, 0x6167}, //16786 #CJK UNIFIED IDEOGRAPH + {0xFBB5, 0x66B3}, //16787 #CJK UNIFIED IDEOGRAPH + {0xFBB6, 0x8559}, //16788 #CJK UNIFIED IDEOGRAPH + {0xFBB7, 0x8E4A}, //16789 #CJK UNIFIED IDEOGRAPH + {0xFBB8, 0x91AF}, //16790 #CJK UNIFIED IDEOGRAPH + {0xFBB9, 0x978B}, //16791 #CJK UNIFIED IDEOGRAPH + {0xFBBA, 0x4E4E}, //16792 #CJK UNIFIED IDEOGRAPH + {0xFBBB, 0x4E92}, //16793 #CJK UNIFIED IDEOGRAPH + {0xFBBC, 0x547C}, //16794 #CJK UNIFIED IDEOGRAPH + {0xFBBD, 0x58D5}, //16795 #CJK UNIFIED IDEOGRAPH + {0xFBBE, 0x58FA}, //16796 #CJK UNIFIED IDEOGRAPH + {0xFBBF, 0x597D}, //16797 #CJK UNIFIED IDEOGRAPH + {0xFBC0, 0x5CB5}, //16798 #CJK UNIFIED IDEOGRAPH + {0xFBC1, 0x5F27}, //16799 #CJK UNIFIED IDEOGRAPH + {0xFBC2, 0x6236}, //16800 #CJK UNIFIED IDEOGRAPH + {0xFBC3, 0x6248}, //16801 #CJK UNIFIED IDEOGRAPH + {0xFBC4, 0x660A}, //16802 #CJK UNIFIED IDEOGRAPH + {0xFBC5, 0x6667}, //16803 #CJK UNIFIED IDEOGRAPH + {0xFBC6, 0x6BEB}, //16804 #CJK UNIFIED IDEOGRAPH + {0xFBC7, 0x6D69}, //16805 #CJK UNIFIED IDEOGRAPH + {0xFBC8, 0x6DCF}, //16806 #CJK UNIFIED IDEOGRAPH + {0xFBC9, 0x6E56}, //16807 #CJK UNIFIED IDEOGRAPH + {0xFBCA, 0x6EF8}, //16808 #CJK UNIFIED IDEOGRAPH + {0xFBCB, 0x6F94}, //16809 #CJK UNIFIED IDEOGRAPH + {0xFBCC, 0x6FE0}, //16810 #CJK UNIFIED IDEOGRAPH + {0xFBCD, 0x6FE9}, //16811 #CJK UNIFIED IDEOGRAPH + {0xFBCE, 0x705D}, //16812 #CJK UNIFIED IDEOGRAPH + {0xFBCF, 0x72D0}, //16813 #CJK UNIFIED IDEOGRAPH + {0xFBD0, 0x7425}, //16814 #CJK UNIFIED IDEOGRAPH + {0xFBD1, 0x745A}, //16815 #CJK UNIFIED IDEOGRAPH + {0xFBD2, 0x74E0}, //16816 #CJK UNIFIED IDEOGRAPH + {0xFBD3, 0x7693}, //16817 #CJK UNIFIED IDEOGRAPH + {0xFBD4, 0x795C}, //16818 #CJK UNIFIED IDEOGRAPH + {0xFBD5, 0x7CCA}, //16819 #CJK UNIFIED IDEOGRAPH + {0xFBD6, 0x7E1E}, //16820 #CJK UNIFIED IDEOGRAPH + {0xFBD7, 0x80E1}, //16821 #CJK UNIFIED IDEOGRAPH + {0xFBD8, 0x82A6}, //16822 #CJK UNIFIED IDEOGRAPH + {0xFBD9, 0x846B}, //16823 #CJK UNIFIED IDEOGRAPH + {0xFBDA, 0x84BF}, //16824 #CJK UNIFIED IDEOGRAPH + {0xFBDB, 0x864E}, //16825 #CJK UNIFIED IDEOGRAPH + {0xFBDC, 0x865F}, //16826 #CJK UNIFIED IDEOGRAPH + {0xFBDD, 0x8774}, //16827 #CJK UNIFIED IDEOGRAPH + {0xFBDE, 0x8B77}, //16828 #CJK UNIFIED IDEOGRAPH + {0xFBDF, 0x8C6A}, //16829 #CJK UNIFIED IDEOGRAPH + {0xFBE0, 0x93AC}, //16830 #CJK UNIFIED IDEOGRAPH + {0xFBE1, 0x9800}, //16831 #CJK UNIFIED IDEOGRAPH + {0xFBE2, 0x9865}, //16832 #CJK UNIFIED IDEOGRAPH + {0xFBE3, 0x60D1}, //16833 #CJK UNIFIED IDEOGRAPH + {0xFBE4, 0x6216}, //16834 #CJK UNIFIED IDEOGRAPH + {0xFBE5, 0x9177}, //16835 #CJK UNIFIED IDEOGRAPH + {0xFBE6, 0x5A5A}, //16836 #CJK UNIFIED IDEOGRAPH + {0xFBE7, 0x660F}, //16837 #CJK UNIFIED IDEOGRAPH + {0xFBE8, 0x6DF7}, //16838 #CJK UNIFIED IDEOGRAPH + {0xFBE9, 0x6E3E}, //16839 #CJK UNIFIED IDEOGRAPH + {0xFBEA, 0x743F}, //16840 #CJK UNIFIED IDEOGRAPH + {0xFBEB, 0x9B42}, //16841 #CJK UNIFIED IDEOGRAPH + {0xFBEC, 0x5FFD}, //16842 #CJK UNIFIED IDEOGRAPH + {0xFBED, 0x60DA}, //16843 #CJK UNIFIED IDEOGRAPH + {0xFBEE, 0x7B0F}, //16844 #CJK UNIFIED IDEOGRAPH + {0xFBEF, 0x54C4}, //16845 #CJK UNIFIED IDEOGRAPH + {0xFBF0, 0x5F18}, //16846 #CJK UNIFIED IDEOGRAPH + {0xFBF1, 0x6C5E}, //16847 #CJK UNIFIED IDEOGRAPH + {0xFBF2, 0x6CD3}, //16848 #CJK UNIFIED IDEOGRAPH + {0xFBF3, 0x6D2A}, //16849 #CJK UNIFIED IDEOGRAPH + {0xFBF4, 0x70D8}, //16850 #CJK UNIFIED IDEOGRAPH + {0xFBF5, 0x7D05}, //16851 #CJK UNIFIED IDEOGRAPH + {0xFBF6, 0x8679}, //16852 #CJK UNIFIED IDEOGRAPH + {0xFBF7, 0x8A0C}, //16853 #CJK UNIFIED IDEOGRAPH + {0xFBF8, 0x9D3B}, //16854 #CJK UNIFIED IDEOGRAPH + {0xFBF9, 0x5316}, //16855 #CJK UNIFIED IDEOGRAPH + {0xFBFA, 0x548C}, //16856 #CJK UNIFIED IDEOGRAPH + {0xFBFB, 0x5B05}, //16857 #CJK UNIFIED IDEOGRAPH + {0xFBFC, 0x6A3A}, //16858 #CJK UNIFIED IDEOGRAPH + {0xFBFD, 0x706B}, //16859 #CJK UNIFIED IDEOGRAPH + {0xFBFE, 0x7575}, //16860 #CJK UNIFIED IDEOGRAPH + {0xFCA1, 0x798D}, //16861 #CJK UNIFIED IDEOGRAPH + {0xFCA2, 0x79BE}, //16862 #CJK UNIFIED IDEOGRAPH + {0xFCA3, 0x82B1}, //16863 #CJK UNIFIED IDEOGRAPH + {0xFCA4, 0x83EF}, //16864 #CJK UNIFIED IDEOGRAPH + {0xFCA5, 0x8A71}, //16865 #CJK UNIFIED IDEOGRAPH + {0xFCA6, 0x8B41}, //16866 #CJK UNIFIED IDEOGRAPH + {0xFCA7, 0x8CA8}, //16867 #CJK UNIFIED IDEOGRAPH + {0xFCA8, 0x9774}, //16868 #CJK UNIFIED IDEOGRAPH + {0xFCA9, 0xFA0B}, //16869 #CJK COMPATIBILITY IDEOGRAPH + {0xFCAA, 0x64F4}, //16870 #CJK UNIFIED IDEOGRAPH + {0xFCAB, 0x652B}, //16871 #CJK UNIFIED IDEOGRAPH + {0xFCAC, 0x78BA}, //16872 #CJK UNIFIED IDEOGRAPH + {0xFCAD, 0x78BB}, //16873 #CJK UNIFIED IDEOGRAPH + {0xFCAE, 0x7A6B}, //16874 #CJK UNIFIED IDEOGRAPH + {0xFCAF, 0x4E38}, //16875 #CJK UNIFIED IDEOGRAPH + {0xFCB0, 0x559A}, //16876 #CJK UNIFIED IDEOGRAPH + {0xFCB1, 0x5950}, //16877 #CJK UNIFIED IDEOGRAPH + {0xFCB2, 0x5BA6}, //16878 #CJK UNIFIED IDEOGRAPH + {0xFCB3, 0x5E7B}, //16879 #CJK UNIFIED IDEOGRAPH + {0xFCB4, 0x60A3}, //16880 #CJK UNIFIED IDEOGRAPH + {0xFCB5, 0x63DB}, //16881 #CJK UNIFIED IDEOGRAPH + {0xFCB6, 0x6B61}, //16882 #CJK UNIFIED IDEOGRAPH + {0xFCB7, 0x6665}, //16883 #CJK UNIFIED IDEOGRAPH + {0xFCB8, 0x6853}, //16884 #CJK UNIFIED IDEOGRAPH + {0xFCB9, 0x6E19}, //16885 #CJK UNIFIED IDEOGRAPH + {0xFCBA, 0x7165}, //16886 #CJK UNIFIED IDEOGRAPH + {0xFCBB, 0x74B0}, //16887 #CJK UNIFIED IDEOGRAPH + {0xFCBC, 0x7D08}, //16888 #CJK UNIFIED IDEOGRAPH + {0xFCBD, 0x9084}, //16889 #CJK UNIFIED IDEOGRAPH + {0xFCBE, 0x9A69}, //16890 #CJK UNIFIED IDEOGRAPH + {0xFCBF, 0x9C25}, //16891 #CJK UNIFIED IDEOGRAPH + {0xFCC0, 0x6D3B}, //16892 #CJK UNIFIED IDEOGRAPH + {0xFCC1, 0x6ED1}, //16893 #CJK UNIFIED IDEOGRAPH + {0xFCC2, 0x733E}, //16894 #CJK UNIFIED IDEOGRAPH + {0xFCC3, 0x8C41}, //16895 #CJK UNIFIED IDEOGRAPH + {0xFCC4, 0x95CA}, //16896 #CJK UNIFIED IDEOGRAPH + {0xFCC5, 0x51F0}, //16897 #CJK UNIFIED IDEOGRAPH + {0xFCC6, 0x5E4C}, //16898 #CJK UNIFIED IDEOGRAPH + {0xFCC7, 0x5FA8}, //16899 #CJK UNIFIED IDEOGRAPH + {0xFCC8, 0x604D}, //16900 #CJK UNIFIED IDEOGRAPH + {0xFCC9, 0x60F6}, //16901 #CJK UNIFIED IDEOGRAPH + {0xFCCA, 0x6130}, //16902 #CJK UNIFIED IDEOGRAPH + {0xFCCB, 0x614C}, //16903 #CJK UNIFIED IDEOGRAPH + {0xFCCC, 0x6643}, //16904 #CJK UNIFIED IDEOGRAPH + {0xFCCD, 0x6644}, //16905 #CJK UNIFIED IDEOGRAPH + {0xFCCE, 0x69A5}, //16906 #CJK UNIFIED IDEOGRAPH + {0xFCCF, 0x6CC1}, //16907 #CJK UNIFIED IDEOGRAPH + {0xFCD0, 0x6E5F}, //16908 #CJK UNIFIED IDEOGRAPH + {0xFCD1, 0x6EC9}, //16909 #CJK UNIFIED IDEOGRAPH + {0xFCD2, 0x6F62}, //16910 #CJK UNIFIED IDEOGRAPH + {0xFCD3, 0x714C}, //16911 #CJK UNIFIED IDEOGRAPH + {0xFCD4, 0x749C}, //16912 #CJK UNIFIED IDEOGRAPH + {0xFCD5, 0x7687}, //16913 #CJK UNIFIED IDEOGRAPH + {0xFCD6, 0x7BC1}, //16914 #CJK UNIFIED IDEOGRAPH + {0xFCD7, 0x7C27}, //16915 #CJK UNIFIED IDEOGRAPH + {0xFCD8, 0x8352}, //16916 #CJK UNIFIED IDEOGRAPH + {0xFCD9, 0x8757}, //16917 #CJK UNIFIED IDEOGRAPH + {0xFCDA, 0x9051}, //16918 #CJK UNIFIED IDEOGRAPH + {0xFCDB, 0x968D}, //16919 #CJK UNIFIED IDEOGRAPH + {0xFCDC, 0x9EC3}, //16920 #CJK UNIFIED IDEOGRAPH + {0xFCDD, 0x532F}, //16921 #CJK UNIFIED IDEOGRAPH + {0xFCDE, 0x56DE}, //16922 #CJK UNIFIED IDEOGRAPH + {0xFCDF, 0x5EFB}, //16923 #CJK UNIFIED IDEOGRAPH + {0xFCE0, 0x5F8A}, //16924 #CJK UNIFIED IDEOGRAPH + {0xFCE1, 0x6062}, //16925 #CJK UNIFIED IDEOGRAPH + {0xFCE2, 0x6094}, //16926 #CJK UNIFIED IDEOGRAPH + {0xFCE3, 0x61F7}, //16927 #CJK UNIFIED IDEOGRAPH + {0xFCE4, 0x6666}, //16928 #CJK UNIFIED IDEOGRAPH + {0xFCE5, 0x6703}, //16929 #CJK UNIFIED IDEOGRAPH + {0xFCE6, 0x6A9C}, //16930 #CJK UNIFIED IDEOGRAPH + {0xFCE7, 0x6DEE}, //16931 #CJK UNIFIED IDEOGRAPH + {0xFCE8, 0x6FAE}, //16932 #CJK UNIFIED IDEOGRAPH + {0xFCE9, 0x7070}, //16933 #CJK UNIFIED IDEOGRAPH + {0xFCEA, 0x736A}, //16934 #CJK UNIFIED IDEOGRAPH + {0xFCEB, 0x7E6A}, //16935 #CJK UNIFIED IDEOGRAPH + {0xFCEC, 0x81BE}, //16936 #CJK UNIFIED IDEOGRAPH + {0xFCED, 0x8334}, //16937 #CJK UNIFIED IDEOGRAPH + {0xFCEE, 0x86D4}, //16938 #CJK UNIFIED IDEOGRAPH + {0xFCEF, 0x8AA8}, //16939 #CJK UNIFIED IDEOGRAPH + {0xFCF0, 0x8CC4}, //16940 #CJK UNIFIED IDEOGRAPH + {0xFCF1, 0x5283}, //16941 #CJK UNIFIED IDEOGRAPH + {0xFCF2, 0x7372}, //16942 #CJK UNIFIED IDEOGRAPH + {0xFCF3, 0x5B96}, //16943 #CJK UNIFIED IDEOGRAPH + {0xFCF4, 0x6A6B}, //16944 #CJK UNIFIED IDEOGRAPH + {0xFCF5, 0x9404}, //16945 #CJK UNIFIED IDEOGRAPH + {0xFCF6, 0x54EE}, //16946 #CJK UNIFIED IDEOGRAPH + {0xFCF7, 0x5686}, //16947 #CJK UNIFIED IDEOGRAPH + {0xFCF8, 0x5B5D}, //16948 #CJK UNIFIED IDEOGRAPH + {0xFCF9, 0x6548}, //16949 #CJK UNIFIED IDEOGRAPH + {0xFCFA, 0x6585}, //16950 #CJK UNIFIED IDEOGRAPH + {0xFCFB, 0x66C9}, //16951 #CJK UNIFIED IDEOGRAPH + {0xFCFC, 0x689F}, //16952 #CJK UNIFIED IDEOGRAPH + {0xFCFD, 0x6D8D}, //16953 #CJK UNIFIED IDEOGRAPH + {0xFCFE, 0x6DC6}, //16954 #CJK UNIFIED IDEOGRAPH + {0xFDA1, 0x723B}, //16955 #CJK UNIFIED IDEOGRAPH + {0xFDA2, 0x80B4}, //16956 #CJK UNIFIED IDEOGRAPH + {0xFDA3, 0x9175}, //16957 #CJK UNIFIED IDEOGRAPH + {0xFDA4, 0x9A4D}, //16958 #CJK UNIFIED IDEOGRAPH + {0xFDA5, 0x4FAF}, //16959 #CJK UNIFIED IDEOGRAPH + {0xFDA6, 0x5019}, //16960 #CJK UNIFIED IDEOGRAPH + {0xFDA7, 0x539A}, //16961 #CJK UNIFIED IDEOGRAPH + {0xFDA8, 0x540E}, //16962 #CJK UNIFIED IDEOGRAPH + {0xFDA9, 0x543C}, //16963 #CJK UNIFIED IDEOGRAPH + {0xFDAA, 0x5589}, //16964 #CJK UNIFIED IDEOGRAPH + {0xFDAB, 0x55C5}, //16965 #CJK UNIFIED IDEOGRAPH + {0xFDAC, 0x5E3F}, //16966 #CJK UNIFIED IDEOGRAPH + {0xFDAD, 0x5F8C}, //16967 #CJK UNIFIED IDEOGRAPH + {0xFDAE, 0x673D}, //16968 #CJK UNIFIED IDEOGRAPH + {0xFDAF, 0x7166}, //16969 #CJK UNIFIED IDEOGRAPH + {0xFDB0, 0x73DD}, //16970 #CJK UNIFIED IDEOGRAPH + {0xFDB1, 0x9005}, //16971 #CJK UNIFIED IDEOGRAPH + {0xFDB2, 0x52DB}, //16972 #CJK UNIFIED IDEOGRAPH + {0xFDB3, 0x52F3}, //16973 #CJK UNIFIED IDEOGRAPH + {0xFDB4, 0x5864}, //16974 #CJK UNIFIED IDEOGRAPH + {0xFDB5, 0x58CE}, //16975 #CJK UNIFIED IDEOGRAPH + {0xFDB6, 0x7104}, //16976 #CJK UNIFIED IDEOGRAPH + {0xFDB7, 0x718F}, //16977 #CJK UNIFIED IDEOGRAPH + {0xFDB8, 0x71FB}, //16978 #CJK UNIFIED IDEOGRAPH + {0xFDB9, 0x85B0}, //16979 #CJK UNIFIED IDEOGRAPH + {0xFDBA, 0x8A13}, //16980 #CJK UNIFIED IDEOGRAPH + {0xFDBB, 0x6688}, //16981 #CJK UNIFIED IDEOGRAPH + {0xFDBC, 0x85A8}, //16982 #CJK UNIFIED IDEOGRAPH + {0xFDBD, 0x55A7}, //16983 #CJK UNIFIED IDEOGRAPH + {0xFDBE, 0x6684}, //16984 #CJK UNIFIED IDEOGRAPH + {0xFDBF, 0x714A}, //16985 #CJK UNIFIED IDEOGRAPH + {0xFDC0, 0x8431}, //16986 #CJK UNIFIED IDEOGRAPH + {0xFDC1, 0x5349}, //16987 #CJK UNIFIED IDEOGRAPH + {0xFDC2, 0x5599}, //16988 #CJK UNIFIED IDEOGRAPH + {0xFDC3, 0x6BC1}, //16989 #CJK UNIFIED IDEOGRAPH + {0xFDC4, 0x5F59}, //16990 #CJK UNIFIED IDEOGRAPH + {0xFDC5, 0x5FBD}, //16991 #CJK UNIFIED IDEOGRAPH + {0xFDC6, 0x63EE}, //16992 #CJK UNIFIED IDEOGRAPH + {0xFDC7, 0x6689}, //16993 #CJK UNIFIED IDEOGRAPH + {0xFDC8, 0x7147}, //16994 #CJK UNIFIED IDEOGRAPH + {0xFDC9, 0x8AF1}, //16995 #CJK UNIFIED IDEOGRAPH + {0xFDCA, 0x8F1D}, //16996 #CJK UNIFIED IDEOGRAPH + {0xFDCB, 0x9EBE}, //16997 #CJK UNIFIED IDEOGRAPH + {0xFDCC, 0x4F11}, //16998 #CJK UNIFIED IDEOGRAPH + {0xFDCD, 0x643A}, //16999 #CJK UNIFIED IDEOGRAPH + {0xFDCE, 0x70CB}, //17000 #CJK UNIFIED IDEOGRAPH + {0xFDCF, 0x7566}, //17001 #CJK UNIFIED IDEOGRAPH + {0xFDD0, 0x8667}, //17002 #CJK UNIFIED IDEOGRAPH + {0xFDD1, 0x6064}, //17003 #CJK UNIFIED IDEOGRAPH + {0xFDD2, 0x8B4E}, //17004 #CJK UNIFIED IDEOGRAPH + {0xFDD3, 0x9DF8}, //17005 #CJK UNIFIED IDEOGRAPH + {0xFDD4, 0x5147}, //17006 #CJK UNIFIED IDEOGRAPH + {0xFDD5, 0x51F6}, //17007 #CJK UNIFIED IDEOGRAPH + {0xFDD6, 0x5308}, //17008 #CJK UNIFIED IDEOGRAPH + {0xFDD7, 0x6D36}, //17009 #CJK UNIFIED IDEOGRAPH + {0xFDD8, 0x80F8}, //17010 #CJK UNIFIED IDEOGRAPH + {0xFDD9, 0x9ED1}, //17011 #CJK UNIFIED IDEOGRAPH + {0xFDDA, 0x6615}, //17012 #CJK UNIFIED IDEOGRAPH + {0xFDDB, 0x6B23}, //17013 #CJK UNIFIED IDEOGRAPH + {0xFDDC, 0x7098}, //17014 #CJK UNIFIED IDEOGRAPH + {0xFDDD, 0x75D5}, //17015 #CJK UNIFIED IDEOGRAPH + {0xFDDE, 0x5403}, //17016 #CJK UNIFIED IDEOGRAPH + {0xFDDF, 0x5C79}, //17017 #CJK UNIFIED IDEOGRAPH + {0xFDE0, 0x7D07}, //17018 #CJK UNIFIED IDEOGRAPH + {0xFDE1, 0x8A16}, //17019 #CJK UNIFIED IDEOGRAPH + {0xFDE2, 0x6B20}, //17020 #CJK UNIFIED IDEOGRAPH + {0xFDE3, 0x6B3D}, //17021 #CJK UNIFIED IDEOGRAPH + {0xFDE4, 0x6B46}, //17022 #CJK UNIFIED IDEOGRAPH + {0xFDE5, 0x5438}, //17023 #CJK UNIFIED IDEOGRAPH + {0xFDE6, 0x6070}, //17024 #CJK UNIFIED IDEOGRAPH + {0xFDE7, 0x6D3D}, //17025 #CJK UNIFIED IDEOGRAPH + {0xFDE8, 0x7FD5}, //17026 #CJK UNIFIED IDEOGRAPH + {0xFDE9, 0x8208}, //17027 #CJK UNIFIED IDEOGRAPH + {0xFDEA, 0x50D6}, //17028 #CJK UNIFIED IDEOGRAPH + {0xFDEB, 0x51DE}, //17029 #CJK UNIFIED IDEOGRAPH + {0xFDEC, 0x559C}, //17030 #CJK UNIFIED IDEOGRAPH + {0xFDED, 0x566B}, //17031 #CJK UNIFIED IDEOGRAPH + {0xFDEE, 0x56CD}, //17032 #CJK UNIFIED IDEOGRAPH + {0xFDEF, 0x59EC}, //17033 #CJK UNIFIED IDEOGRAPH + {0xFDF0, 0x5B09}, //17034 #CJK UNIFIED IDEOGRAPH + {0xFDF1, 0x5E0C}, //17035 #CJK UNIFIED IDEOGRAPH + {0xFDF2, 0x6199}, //17036 #CJK UNIFIED IDEOGRAPH + {0xFDF3, 0x6198}, //17037 #CJK UNIFIED IDEOGRAPH + {0xFDF4, 0x6231}, //17038 #CJK UNIFIED IDEOGRAPH + {0xFDF5, 0x665E}, //17039 #CJK UNIFIED IDEOGRAPH + {0xFDF6, 0x66E6}, //17040 #CJK UNIFIED IDEOGRAPH + {0xFDF7, 0x7199}, //17041 #CJK UNIFIED IDEOGRAPH + {0xFDF8, 0x71B9}, //17042 #CJK UNIFIED IDEOGRAPH + {0xFDF9, 0x71BA}, //17043 #CJK UNIFIED IDEOGRAPH + {0xFDFA, 0x72A7}, //17044 #CJK UNIFIED IDEOGRAPH + {0xFDFB, 0x79A7}, //17045 #CJK UNIFIED IDEOGRAPH + {0xFDFC, 0x7A00}, //17046 #CJK UNIFIED IDEOGRAPH + {0xFDFD, 0x7FB2}, //17047 #CJK UNIFIED IDEOGRAPH + {0xFDFE, 0x8A70}, //17048 #CJK UNIFIED IDEOGRAPH +}; + +#endif // DRW_CPTABLE949_H diff --git a/extlib/libdxfrw/intern/drw_cptable950.h b/extlib/libdxfrw/intern/drw_cptable950.h new file mode 100644 index 0000000..3adc1e8 --- /dev/null +++ b/extlib/libdxfrw/intern/drw_cptable950.h @@ -0,0 +1,13654 @@ +#ifndef DRW_CPTABLE950_H +#define DRW_CPTABLE950_H + +//Chinese (Taiwan, Hong Kong SAR) + +//first entry in this table are 0x80 +#define CPOFFSET950 0x80 +#define CPLENGTH950 13503 +#define NOTFOUND950 0x003F + +//Table 950 one byte +static const int DRW_Table950[1] = { +}; + +//Table 950 lead byte +//pairs of start/end in DRW_DoubleTable950 +static const int DRW_LeadTable950[] = { + 0, //1#DBCS LEAD BYTE 0x81, empty + 0, //2#DBCS LEAD BYTE 0x82, empty + 0, //3#DBCS LEAD BYTE 0x83, empty + 0, //4#DBCS LEAD BYTE 0x84, empty + 0, //5#DBCS LEAD BYTE 0x85, empty + 0, //6#DBCS LEAD BYTE 0x86, empty + 0, //7#DBCS LEAD BYTE 0x87, empty + 0, //8#DBCS LEAD BYTE 0x88, empty + 0, //9#DBCS LEAD BYTE 0x89, empty + 0, //10#DBCS LEAD BYTE 0x8A, empty + 0, //11#DBCS LEAD BYTE 0x8B, empty + 0, //12#DBCS LEAD BYTE 0x8C, empty + 0, //13#DBCS LEAD BYTE 0x8D, empty + 0, //14#DBCS LEAD BYTE 0x8E, empty + 0, //15#DBCS LEAD BYTE 0x8F, empty + 0, //16#DBCS LEAD BYTE 0x90, empty + 0, //17#DBCS LEAD BYTE 0x91, empty + 0, //18#DBCS LEAD BYTE 0x92, empty + 0, //19#DBCS LEAD BYTE 0x93, empty + 0, //20#DBCS LEAD BYTE 0x94, empty + 0, //21#DBCS LEAD BYTE 0x95, empty + 0, //22#DBCS LEAD BYTE 0x96, empty + 0, //23#DBCS LEAD BYTE 0x97, empty + 0, //24#DBCS LEAD BYTE 0x98, empty + 0, //25#DBCS LEAD BYTE 0x99, empty + 0, //26#DBCS LEAD BYTE 0x9A, empty + 0, //27#DBCS LEAD BYTE 0x9B, empty + 0, //28#DBCS LEAD BYTE 0x9C, empty + 0, //29#DBCS LEAD BYTE 0x9D, empty + 0, //30#DBCS LEAD BYTE 0x9E, empty + 0, //31#DBCS LEAD BYTE 0x9F, empty + 0, //32#DBCS LEAD BYTE 0xA0, empty + 0, //33#DBCS LEAD BYTE 0xA1 + 157, //34#DBCS LEAD BYTE 0xA2 + 314, //35#DBCS LEAD BYTE 0xA3 + 409, //36#DBCS LEAD BYTE 0xA4 + 566, //37#DBCS LEAD BYTE 0xA5 + 723, //38#DBCS LEAD BYTE 0xA6 + 880, //39#DBCS LEAD BYTE 0xA7 + 1037, //40#DBCS LEAD BYTE 0xA8 + 1194, //41#DBCS LEAD BYTE 0xA9 + 1351, //42#DBCS LEAD BYTE 0xAA + 1508, //43#DBCS LEAD BYTE 0xAB + 1665, //44#DBCS LEAD BYTE 0xAC + 1822, //45#DBCS LEAD BYTE 0xAD + 1979, //46#DBCS LEAD BYTE 0xAE + 2136, //47#DBCS LEAD BYTE 0xAF + 2293, //48#DBCS LEAD BYTE 0xB0 + 2450, //49#DBCS LEAD BYTE 0xB1 + 2607, //50#DBCS LEAD BYTE 0xB2 + 2764, //51#DBCS LEAD BYTE 0xB3 + 2921, //52#DBCS LEAD BYTE 0xB4 + 3078, //53#DBCS LEAD BYTE 0xB5 + 3235, //54#DBCS LEAD BYTE 0xB6 + 3392, //55#DBCS LEAD BYTE 0xB7 + 3549, //56#DBCS LEAD BYTE 0xB8 + 3706, //57#DBCS LEAD BYTE 0xB9 + 3863, //58#DBCS LEAD BYTE 0xBA + 4020, //59#DBCS LEAD BYTE 0xBB + 4177, //60#DBCS LEAD BYTE 0xBC + 4334, //61#DBCS LEAD BYTE 0xBD + 4491, //62#DBCS LEAD BYTE 0xBE + 4648, //63#DBCS LEAD BYTE 0xBF + 4805, //64#DBCS LEAD BYTE 0xC0 + 4962, //65#DBCS LEAD BYTE 0xC1 + 5119, //66#DBCS LEAD BYTE 0xC2 + 5276, //67#DBCS LEAD BYTE 0xC3 + 5443, //68#DBCS LEAD BYTE 0xC4 + 5590, //69#DBCS LEAD BYTE 0xC5 + 5747, //70#DBCS LEAD BYTE 0xC6 + 5810, //71#DBCS LEAD BYTE 0xC7, empty + 5810, //72#DBCS LEAD BYTE 0xC8, empty + 5810, //73#DBCS LEAD BYTE 0xC9 + 5967, //74#DBCS LEAD BYTE 0xCA + 6124, //75#DBCS LEAD BYTE 0xCB + 6281, //76#DBCS LEAD BYTE 0xCC + 6438, //77#DBCS LEAD BYTE 0xCD + 6595, //78#DBCS LEAD BYTE 0xCE + 6752, //79#DBCS LEAD BYTE 0xCF + 6909, //80#DBCS LEAD BYTE 0xD0 + 7066, //81#DBCS LEAD BYTE 0xD1 + 7223, //82#DBCS LEAD BYTE 0xD2 + 7380, //83#DBCS LEAD BYTE 0xD3 + 7537, //84#DBCS LEAD BYTE 0xD4 + 7694, //85#DBCS LEAD BYTE 0xD5 + 7851, //86#DBCS LEAD BYTE 0xD6 + 8008, //87#DBCS LEAD BYTE 0xD7 + 8165, //88#DBCS LEAD BYTE 0xD8 + 8322, //89#DBCS LEAD BYTE 0xD9 + 8479, //90#DBCS LEAD BYTE 0xDA + 8636, //91#DBCS LEAD BYTE 0xDB + 8793, //92#DBCS LEAD BYTE 0xDC + 8950, //93#DBCS LEAD BYTE 0xDD + 9107, //94#DBCS LEAD BYTE 0xDE + 9264, //95#DBCS LEAD BYTE 0xDF + 9421, //96#DBCS LEAD BYTE 0xE0 + 9578, //97#DBCS LEAD BYTE 0xE1 + 9735, //98#DBCS LEAD BYTE 0xE2 + 9892, //99#DBCS LEAD BYTE 0xE3 + 10049, //100#DBCS LEAD BYTE 0xE4 + 10206, //101#DBCS LEAD BYTE 0xE5 + 10363, //102#DBCS LEAD BYTE 0xE6 + 10520, //103#DBCS LEAD BYTE 0xE7 + 10677, //104#DBCS LEAD BYTE 0xE8 + 10834, //105#DBCS LEAD BYTE 0xE9 + 10991, //106#DBCS LEAD BYTE 0xEA + 11148, //107#DBCS LEAD BYTE 0xEB + 11305, //108#DBCS LEAD BYTE 0xEC + 11462, //109#DBCS LEAD BYTE 0xED + 11619, //110#DBCS LEAD BYTE 0xEE + 11776, //111#DBCS LEAD BYTE 0xEF + 11933, //112#DBCS LEAD BYTE 0xF0 + 12090, //113#DBCS LEAD BYTE 0xF1 + 12247, //114#DBCS LEAD BYTE 0xF2 + 12404, //115#DBCS LEAD BYTE 0xF3 + 12561, //116#DBCS LEAD BYTE 0xF4 + 12718, //117#DBCS LEAD BYTE 0xF5 + 12875, //118#DBCS LEAD BYTE 0xF6 + 13032, //119#DBCS LEAD BYTE 0xF7 + 13189, //120#DBCS LEAD BYTE 0xF8 + 13346, //121#DBCS LEAD BYTE 0xF9 + 13502, //122#DBCS LEAD BYTE 0xFA, empty + 13502, //123#DBCS LEAD BYTE 0xFB, empty + 13502, //124#DBCS LEAD BYTE 0xFC, empty + 13502, //125#DBCS LEAD BYTE 0xFD, empty + 13502, //126#DBCS LEAD BYTE 0xFE, empty + 13502, //127#UNDEFINED 0xFF, END OF TABLE +}; + +//Table 950 tail byte +static const int DRW_DoubleTable950[][2] = { + {0xA140, 0x3000}, //1 #IDEOGRAPHIC SPACE + {0xA141, 0xFF0C}, //2 #FULLWIDTH COMMA + {0xA142, 0x3001}, //3 #IDEOGRAPHIC COMMA + {0xA143, 0x3002}, //4 #IDEOGRAPHIC FULL STOP + {0xA144, 0xFF0E}, //5 #FULLWIDTH FULL STOP + {0xA145, 0x2027}, //6 #HYPHENATION POINT + {0xA146, 0xFF1B}, //7 #FULLWIDTH SEMICOLON + {0xA147, 0xFF1A}, //8 #FULLWIDTH COLON + {0xA148, 0xFF1F}, //9 #FULLWIDTH QUESTION MARK + {0xA149, 0xFF01}, //10 #FULLWIDTH EXCLAMATION MARK + {0xA14A, 0xFE30}, //11 #PRESENTATION FORM FOR VERTICAL TWO DOT LEADER + {0xA14B, 0x2026}, //12 #HORIZONTAL ELLIPSIS + {0xA14C, 0x2025}, //13 #TWO DOT LEADER + {0xA14D, 0xFE50}, //14 #SMALL COMMA + {0xA14E, 0xFE51}, //15 #SMALL IDEOGRAPHIC COMMA + {0xA14F, 0xFE52}, //16 #SMALL FULL STOP + {0xA150, 0x00B7}, //17 #MIDDLE DOT + {0xA151, 0xFE54}, //18 #SMALL SEMICOLON + {0xA152, 0xFE55}, //19 #SMALL COLON + {0xA153, 0xFE56}, //20 #SMALL QUESTION MARK + {0xA154, 0xFE57}, //21 #SMALL EXCLAMATION MARK + {0xA155, 0xFF5C}, //22 #FULLWIDTH VERTICAL LINE + {0xA156, 0x2013}, //23 #EN DASH + {0xA157, 0xFE31}, //24 #PRESENTATION FORM FOR VERTICAL EM DASH + {0xA158, 0x2014}, //25 #EM DASH + {0xA159, 0xFE33}, //26 #PRESENTATION FORM FOR VERTICAL LOW LINE + {0xA15A, 0x2574}, //27 #BOX DRAWINGS LIGHT LEFT + {0xA15B, 0xFE34}, //28 #PRESENTATION FORM FOR VERTICAL WAVY LOW LINE + {0xA15C, 0xFE4F}, //29 #WAVY LOW LINE + {0xA15D, 0xFF08}, //30 #FULLWIDTH LEFT PARENTHESIS + {0xA15E, 0xFF09}, //31 #FULLWIDTH RIGHT PARENTHESIS + {0xA15F, 0xFE35}, //32 #PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS + {0xA160, 0xFE36}, //33 #PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS + {0xA161, 0xFF5B}, //34 #FULLWIDTH LEFT CURLY BRACKET + {0xA162, 0xFF5D}, //35 #FULLWIDTH RIGHT CURLY BRACKET + {0xA163, 0xFE37}, //36 #PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET + {0xA164, 0xFE38}, //37 #PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET + {0xA165, 0x3014}, //38 #LEFT TORTOISE SHELL BRACKET + {0xA166, 0x3015}, //39 #RIGHT TORTOISE SHELL BRACKET + {0xA167, 0xFE39}, //40 #PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET + {0xA168, 0xFE3A}, //41 #PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET + {0xA169, 0x3010}, //42 #LEFT BLACK LENTICULAR BRACKET + {0xA16A, 0x3011}, //43 #RIGHT BLACK LENTICULAR BRACKET + {0xA16B, 0xFE3B}, //44 #PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET + {0xA16C, 0xFE3C}, //45 #PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET + {0xA16D, 0x300A}, //46 #LEFT DOUBLE ANGLE BRACKET + {0xA16E, 0x300B}, //47 #RIGHT DOUBLE ANGLE BRACKET + {0xA16F, 0xFE3D}, //48 #PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET + {0xA170, 0xFE3E}, //49 #PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET + {0xA171, 0x3008}, //50 #LEFT ANGLE BRACKET + {0xA172, 0x3009}, //51 #RIGHT ANGLE BRACKET + {0xA173, 0xFE3F}, //52 #PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET + {0xA174, 0xFE40}, //53 #PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET + {0xA175, 0x300C}, //54 #LEFT CORNER BRACKET + {0xA176, 0x300D}, //55 #RIGHT CORNER BRACKET + {0xA177, 0xFE41}, //56 #PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET + {0xA178, 0xFE42}, //57 #PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET + {0xA179, 0x300E}, //58 #LEFT WHITE CORNER BRACKET + {0xA17A, 0x300F}, //59 #RIGHT WHITE CORNER BRACKET + {0xA17B, 0xFE43}, //60 #PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET + {0xA17C, 0xFE44}, //61 #PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET + {0xA17D, 0xFE59}, //62 #SMALL LEFT PARENTHESIS + {0xA17E, 0xFE5A}, //63 #SMALL RIGHT PARENTHESIS + {0xA1A1, 0xFE5B}, //64 #SMALL LEFT CURLY BRACKET + {0xA1A2, 0xFE5C}, //65 #SMALL RIGHT CURLY BRACKET + {0xA1A3, 0xFE5D}, //66 #SMALL LEFT TORTOISE SHELL BRACKET + {0xA1A4, 0xFE5E}, //67 #SMALL RIGHT TORTOISE SHELL BRACKET + {0xA1A5, 0x2018}, //68 #LEFT SINGLE QUOTATION MARK + {0xA1A6, 0x2019}, //69 #RIGHT SINGLE QUOTATION MARK + {0xA1A7, 0x201C}, //70 #LEFT DOUBLE QUOTATION MARK + {0xA1A8, 0x201D}, //71 #RIGHT DOUBLE QUOTATION MARK + {0xA1A9, 0x301D}, //72 #REVERSED DOUBLE PRIME QUOTATION MARK + {0xA1AA, 0x301E}, //73 #DOUBLE PRIME QUOTATION MARK + {0xA1AB, 0x2035}, //74 #REVERSED PRIME + {0xA1AC, 0x2032}, //75 #PRIME + {0xA1AD, 0xFF03}, //76 #FULLWIDTH NUMBER SIGN + {0xA1AE, 0xFF06}, //77 #FULLWIDTH AMPERSAND + {0xA1AF, 0xFF0A}, //78 #FULLWIDTH ASTERISK + {0xA1B0, 0x203B}, //79 #REFERENCE MARK + {0xA1B1, 0x00A7}, //80 #SECTION SIGN + {0xA1B2, 0x3003}, //81 #DITTO MARK + {0xA1B3, 0x25CB}, //82 #WHITE CIRCLE + {0xA1B4, 0x25CF}, //83 #BLACK CIRCLE + {0xA1B5, 0x25B3}, //84 #WHITE UP-POINTING TRIANGLE + {0xA1B6, 0x25B2}, //85 #BLACK UP-POINTING TRIANGLE + {0xA1B7, 0x25CE}, //86 #BULLSEYE + {0xA1B8, 0x2606}, //87 #WHITE STAR + {0xA1B9, 0x2605}, //88 #BLACK STAR + {0xA1BA, 0x25C7}, //89 #WHITE DIAMOND + {0xA1BB, 0x25C6}, //90 #BLACK DIAMOND + {0xA1BC, 0x25A1}, //91 #WHITE SQUARE + {0xA1BD, 0x25A0}, //92 #BLACK SQUARE + {0xA1BE, 0x25BD}, //93 #WHITE DOWN-POINTING TRIANGLE + {0xA1BF, 0x25BC}, //94 #BLACK DOWN-POINTING TRIANGLE + {0xA1C0, 0x32A3}, //95 #CIRCLED IDEOGRAPH CORRECT + {0xA1C1, 0x2105}, //96 #CARE OF + {0xA1C2, 0x00AF}, //97 #MACRON + {0xA1C3, 0xFFE3}, //98 #FULLWIDTH MACRON + {0xA1C4, 0xFF3F}, //99 #FULLWIDTH LOW LINE + {0xA1C5, 0x02CD}, //100 #MODIFIER LETTER LOW MACRON + {0xA1C6, 0xFE49}, //101 #DASHED OVERLINE + {0xA1C7, 0xFE4A}, //102 #CENTRELINE OVERLINE + {0xA1C8, 0xFE4D}, //103 #DASHED LOW LINE + {0xA1C9, 0xFE4E}, //104 #CENTRELINE LOW LINE + {0xA1CA, 0xFE4B}, //105 #WAVY OVERLINE + {0xA1CB, 0xFE4C}, //106 #DOUBLE WAVY OVERLINE + {0xA1CC, 0xFE5F}, //107 #SMALL NUMBER SIGN + {0xA1CD, 0xFE60}, //108 #SMALL AMPERSAND + {0xA1CE, 0xFE61}, //109 #SMALL ASTERISK + {0xA1CF, 0xFF0B}, //110 #FULLWIDTH PLUS SIGN + {0xA1D0, 0xFF0D}, //111 #FULLWIDTH HYPHEN-MINUS + {0xA1D1, 0x00D7}, //112 #MULTIPLICATION SIGN + {0xA1D2, 0x00F7}, //113 #DIVISION SIGN + {0xA1D3, 0x00B1}, //114 #PLUS-MINUS SIGN + {0xA1D4, 0x221A}, //115 #SQUARE ROOT + {0xA1D5, 0xFF1C}, //116 #FULLWIDTH LESS-THAN SIGN + {0xA1D6, 0xFF1E}, //117 #FULLWIDTH GREATER-THAN SIGN + {0xA1D7, 0xFF1D}, //118 #FULLWIDTH EQUALS SIGN + {0xA1D8, 0x2266}, //119 #LESS-THAN OVER EQUAL TO + {0xA1D9, 0x2267}, //120 #GREATER-THAN OVER EQUAL TO + {0xA1DA, 0x2260}, //121 #NOT EQUAL TO + {0xA1DB, 0x221E}, //122 #INFINITY + {0xA1DC, 0x2252}, //123 #APPROXIMATELY EQUAL TO OR THE IMAGE OF + {0xA1DD, 0x2261}, //124 #IDENTICAL TO + {0xA1DE, 0xFE62}, //125 #SMALL PLUS SIGN + {0xA1DF, 0xFE63}, //126 #SMALL HYPHEN-MINUS + {0xA1E0, 0xFE64}, //127 #SMALL LESS-THAN SIGN + {0xA1E1, 0xFE65}, //128 #SMALL GREATER-THAN SIGN + {0xA1E2, 0xFE66}, //129 #SMALL EQUALS SIGN + {0xA1E3, 0xFF5E}, //130 #FULLWIDTH TILDE + {0xA1E4, 0x2229}, //131 #INTERSECTION + {0xA1E5, 0x222A}, //132 #UNION + {0xA1E6, 0x22A5}, //133 #UP TACK + {0xA1E7, 0x2220}, //134 #ANGLE + {0xA1E8, 0x221F}, //135 #RIGHT ANGLE + {0xA1E9, 0x22BF}, //136 #RIGHT TRIANGLE + {0xA1EA, 0x33D2}, //137 #SQUARE LOG + {0xA1EB, 0x33D1}, //138 #SQUARE LN + {0xA1EC, 0x222B}, //139 #INTEGRAL + {0xA1ED, 0x222E}, //140 #CONTOUR INTEGRAL + {0xA1EE, 0x2235}, //141 #BECAUSE + {0xA1EF, 0x2234}, //142 #THEREFORE + {0xA1F0, 0x2640}, //143 #FEMALE SIGN + {0xA1F1, 0x2642}, //144 #MALE SIGN + {0xA1F2, 0x2295}, //145 #CIRCLED PLUS + {0xA1F3, 0x2299}, //146 #CIRCLED DOT OPERATOR + {0xA1F4, 0x2191}, //147 #UPWARDS ARROW + {0xA1F5, 0x2193}, //148 #DOWNWARDS ARROW + {0xA1F6, 0x2190}, //149 #LEFTWARDS ARROW + {0xA1F7, 0x2192}, //150 #RIGHTWARDS ARROW + {0xA1F8, 0x2196}, //151 #NORTH WEST ARROW + {0xA1F9, 0x2197}, //152 #NORTH EAST ARROW + {0xA1FA, 0x2199}, //153 #SOUTH WEST ARROW + {0xA1FB, 0x2198}, //154 #SOUTH EAST ARROW + {0xA1FC, 0x2225}, //155 #PARALLEL TO + {0xA1FD, 0x2223}, //156 #DIVIDES + {0xA1FE, 0xFF0F}, //157 #FULLWIDTH SOLIDUS + {0xA240, 0xFF3C}, //158 #FULLWIDTH REVERSE SOLIDUS + {0xA241, 0x2215}, //159 #DIVISION SLASH + {0xA242, 0xFE68}, //160 #SMALL REVERSE SOLIDUS + {0xA243, 0xFF04}, //161 #FULLWIDTH DOLLAR SIGN + {0xA244, 0xFFE5}, //162 #FULLWIDTH YEN SIGN + {0xA245, 0x3012}, //163 #POSTAL MARK + {0xA246, 0xFFE0}, //164 #FULLWIDTH CENT SIGN + {0xA247, 0xFFE1}, //165 #FULLWIDTH POUND SIGN + {0xA248, 0xFF05}, //166 #FULLWIDTH PERCENT SIGN + {0xA249, 0xFF20}, //167 #FULLWIDTH COMMERCIAL AT + {0xA24A, 0x2103}, //168 #DEGREE CELSIUS + {0xA24B, 0x2109}, //169 #DEGREE FAHRENHEIT + {0xA24C, 0xFE69}, //170 #SMALL DOLLAR SIGN + {0xA24D, 0xFE6A}, //171 #SMALL PERCENT SIGN + {0xA24E, 0xFE6B}, //172 #SMALL COMMERCIAL AT + {0xA24F, 0x33D5}, //173 #SQUARE MIL + {0xA250, 0x339C}, //174 #SQUARE MM + {0xA251, 0x339D}, //175 #SQUARE CM + {0xA252, 0x339E}, //176 #SQUARE KM + {0xA253, 0x33CE}, //177 #SQUARE KM CAPITAL + {0xA254, 0x33A1}, //178 #SQUARE M SQUARED + {0xA255, 0x338E}, //179 #SQUARE MG + {0xA256, 0x338F}, //180 #SQUARE KG + {0xA257, 0x33C4}, //181 #SQUARE CC + {0xA258, 0x00B0}, //182 #DEGREE SIGN + {0xA259, 0x5159}, //183 #CJK UNIFIED IDEOGRAPH + {0xA25A, 0x515B}, //184 #CJK UNIFIED IDEOGRAPH + {0xA25B, 0x515E}, //185 #CJK UNIFIED IDEOGRAPH + {0xA25C, 0x515D}, //186 #CJK UNIFIED IDEOGRAPH + {0xA25D, 0x5161}, //187 #CJK UNIFIED IDEOGRAPH + {0xA25E, 0x5163}, //188 #CJK UNIFIED IDEOGRAPH + {0xA25F, 0x55E7}, //189 #CJK UNIFIED IDEOGRAPH + {0xA260, 0x74E9}, //190 #CJK UNIFIED IDEOGRAPH + {0xA261, 0x7CCE}, //191 #CJK UNIFIED IDEOGRAPH + {0xA262, 0x2581}, //192 #LOWER ONE EIGHTH BLOCK + {0xA263, 0x2582}, //193 #LOWER ONE QUARTER BLOCK + {0xA264, 0x2583}, //194 #LOWER THREE EIGHTHS BLOCK + {0xA265, 0x2584}, //195 #LOWER HALF BLOCK + {0xA266, 0x2585}, //196 #LOWER FIVE EIGHTHS BLOCK + {0xA267, 0x2586}, //197 #LOWER THREE QUARTERS BLOCK + {0xA268, 0x2587}, //198 #LOWER SEVEN EIGHTHS BLOCK + {0xA269, 0x2588}, //199 #FULL BLOCK + {0xA26A, 0x258F}, //200 #LEFT ONE EIGHTH BLOCK + {0xA26B, 0x258E}, //201 #LEFT ONE QUARTER BLOCK + {0xA26C, 0x258D}, //202 #LEFT THREE EIGHTHS BLOCK + {0xA26D, 0x258C}, //203 #LEFT HALF BLOCK + {0xA26E, 0x258B}, //204 #LEFT FIVE EIGHTHS BLOCK + {0xA26F, 0x258A}, //205 #LEFT THREE QUARTERS BLOCK + {0xA270, 0x2589}, //206 #LEFT SEVEN EIGHTHS BLOCK + {0xA271, 0x253C}, //207 #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + {0xA272, 0x2534}, //208 #BOX DRAWINGS LIGHT UP AND HORIZONTAL + {0xA273, 0x252C}, //209 #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + {0xA274, 0x2524}, //210 #BOX DRAWINGS LIGHT VERTICAL AND LEFT + {0xA275, 0x251C}, //211 #BOX DRAWINGS LIGHT VERTICAL AND RIGHT + {0xA276, 0x2594}, //212 #UPPER ONE EIGHTH BLOCK + {0xA277, 0x2500}, //213 #BOX DRAWINGS LIGHT HORIZONTAL + {0xA278, 0x2502}, //214 #BOX DRAWINGS LIGHT VERTICAL + {0xA279, 0x2595}, //215 #RIGHT ONE EIGHTH BLOCK + {0xA27A, 0x250C}, //216 #BOX DRAWINGS LIGHT DOWN AND RIGHT + {0xA27B, 0x2510}, //217 #BOX DRAWINGS LIGHT DOWN AND LEFT + {0xA27C, 0x2514}, //218 #BOX DRAWINGS LIGHT UP AND RIGHT + {0xA27D, 0x2518}, //219 #BOX DRAWINGS LIGHT UP AND LEFT + {0xA27E, 0x256D}, //220 #BOX DRAWINGS LIGHT ARC DOWN AND RIGHT + {0xA2A1, 0x256E}, //221 #BOX DRAWINGS LIGHT ARC DOWN AND LEFT + {0xA2A2, 0x2570}, //222 #BOX DRAWINGS LIGHT ARC UP AND RIGHT + {0xA2A3, 0x256F}, //223 #BOX DRAWINGS LIGHT ARC UP AND LEFT + {0xA2A4, 0x2550}, //224 #BOX DRAWINGS DOUBLE HORIZONTAL + {0xA2A5, 0x255E}, //225 #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + {0xA2A6, 0x256A}, //226 #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + {0xA2A7, 0x2561}, //227 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + {0xA2A8, 0x25E2}, //228 #BLACK LOWER RIGHT TRIANGLE + {0xA2A9, 0x25E3}, //229 #BLACK LOWER LEFT TRIANGLE + {0xA2AA, 0x25E5}, //230 #BLACK UPPER RIGHT TRIANGLE + {0xA2AB, 0x25E4}, //231 #BLACK UPPER LEFT TRIANGLE + {0xA2AC, 0x2571}, //232 #BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT + {0xA2AD, 0x2572}, //233 #BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT + {0xA2AE, 0x2573}, //234 #BOX DRAWINGS LIGHT DIAGONAL CROSS + {0xA2AF, 0xFF10}, //235 #FULLWIDTH DIGIT ZERO + {0xA2B0, 0xFF11}, //236 #FULLWIDTH DIGIT ONE + {0xA2B1, 0xFF12}, //237 #FULLWIDTH DIGIT TWO + {0xA2B2, 0xFF13}, //238 #FULLWIDTH DIGIT THREE + {0xA2B3, 0xFF14}, //239 #FULLWIDTH DIGIT FOUR + {0xA2B4, 0xFF15}, //240 #FULLWIDTH DIGIT FIVE + {0xA2B5, 0xFF16}, //241 #FULLWIDTH DIGIT SIX + {0xA2B6, 0xFF17}, //242 #FULLWIDTH DIGIT SEVEN + {0xA2B7, 0xFF18}, //243 #FULLWIDTH DIGIT EIGHT + {0xA2B8, 0xFF19}, //244 #FULLWIDTH DIGIT NINE + {0xA2B9, 0x2160}, //245 #ROMAN NUMERAL ONE + {0xA2BA, 0x2161}, //246 #ROMAN NUMERAL TWO + {0xA2BB, 0x2162}, //247 #ROMAN NUMERAL THREE + {0xA2BC, 0x2163}, //248 #ROMAN NUMERAL FOUR + {0xA2BD, 0x2164}, //249 #ROMAN NUMERAL FIVE + {0xA2BE, 0x2165}, //250 #ROMAN NUMERAL SIX + {0xA2BF, 0x2166}, //251 #ROMAN NUMERAL SEVEN + {0xA2C0, 0x2167}, //252 #ROMAN NUMERAL EIGHT + {0xA2C1, 0x2168}, //253 #ROMAN NUMERAL NINE + {0xA2C2, 0x2169}, //254 #ROMAN NUMERAL TEN + {0xA2C3, 0x3021}, //255 #HANGZHOU NUMERAL ONE + {0xA2C4, 0x3022}, //256 #HANGZHOU NUMERAL TWO + {0xA2C5, 0x3023}, //257 #HANGZHOU NUMERAL THREE + {0xA2C6, 0x3024}, //258 #HANGZHOU NUMERAL FOUR + {0xA2C7, 0x3025}, //259 #HANGZHOU NUMERAL FIVE + {0xA2C8, 0x3026}, //260 #HANGZHOU NUMERAL SIX + {0xA2C9, 0x3027}, //261 #HANGZHOU NUMERAL SEVEN + {0xA2CA, 0x3028}, //262 #HANGZHOU NUMERAL EIGHT + {0xA2CB, 0x3029}, //263 #HANGZHOU NUMERAL NINE + {0xA2CC, 0x5341}, //264 #CJK UNIFIED IDEOGRAPH + {0xA2CD, 0x5344}, //265 #CJK UNIFIED IDEOGRAPH + {0xA2CE, 0x5345}, //266 #CJK UNIFIED IDEOGRAPH + {0xA2CF, 0xFF21}, //267 #FULLWIDTH LATIN CAPITAL LETTER A + {0xA2D0, 0xFF22}, //268 #FULLWIDTH LATIN CAPITAL LETTER B + {0xA2D1, 0xFF23}, //269 #FULLWIDTH LATIN CAPITAL LETTER C + {0xA2D2, 0xFF24}, //270 #FULLWIDTH LATIN CAPITAL LETTER D + {0xA2D3, 0xFF25}, //271 #FULLWIDTH LATIN CAPITAL LETTER E + {0xA2D4, 0xFF26}, //272 #FULLWIDTH LATIN CAPITAL LETTER F + {0xA2D5, 0xFF27}, //273 #FULLWIDTH LATIN CAPITAL LETTER G + {0xA2D6, 0xFF28}, //274 #FULLWIDTH LATIN CAPITAL LETTER H + {0xA2D7, 0xFF29}, //275 #FULLWIDTH LATIN CAPITAL LETTER I + {0xA2D8, 0xFF2A}, //276 #FULLWIDTH LATIN CAPITAL LETTER J + {0xA2D9, 0xFF2B}, //277 #FULLWIDTH LATIN CAPITAL LETTER K + {0xA2DA, 0xFF2C}, //278 #FULLWIDTH LATIN CAPITAL LETTER L + {0xA2DB, 0xFF2D}, //279 #FULLWIDTH LATIN CAPITAL LETTER M + {0xA2DC, 0xFF2E}, //280 #FULLWIDTH LATIN CAPITAL LETTER N + {0xA2DD, 0xFF2F}, //281 #FULLWIDTH LATIN CAPITAL LETTER O + {0xA2DE, 0xFF30}, //282 #FULLWIDTH LATIN CAPITAL LETTER P + {0xA2DF, 0xFF31}, //283 #FULLWIDTH LATIN CAPITAL LETTER Q + {0xA2E0, 0xFF32}, //284 #FULLWIDTH LATIN CAPITAL LETTER R + {0xA2E1, 0xFF33}, //285 #FULLWIDTH LATIN CAPITAL LETTER S + {0xA2E2, 0xFF34}, //286 #FULLWIDTH LATIN CAPITAL LETTER T + {0xA2E3, 0xFF35}, //287 #FULLWIDTH LATIN CAPITAL LETTER U + {0xA2E4, 0xFF36}, //288 #FULLWIDTH LATIN CAPITAL LETTER V + {0xA2E5, 0xFF37}, //289 #FULLWIDTH LATIN CAPITAL LETTER W + {0xA2E6, 0xFF38}, //290 #FULLWIDTH LATIN CAPITAL LETTER X + {0xA2E7, 0xFF39}, //291 #FULLWIDTH LATIN CAPITAL LETTER Y + {0xA2E8, 0xFF3A}, //292 #FULLWIDTH LATIN CAPITAL LETTER Z + {0xA2E9, 0xFF41}, //293 #FULLWIDTH LATIN SMALL LETTER A + {0xA2EA, 0xFF42}, //294 #FULLWIDTH LATIN SMALL LETTER B + {0xA2EB, 0xFF43}, //295 #FULLWIDTH LATIN SMALL LETTER C + {0xA2EC, 0xFF44}, //296 #FULLWIDTH LATIN SMALL LETTER D + {0xA2ED, 0xFF45}, //297 #FULLWIDTH LATIN SMALL LETTER E + {0xA2EE, 0xFF46}, //298 #FULLWIDTH LATIN SMALL LETTER F + {0xA2EF, 0xFF47}, //299 #FULLWIDTH LATIN SMALL LETTER G + {0xA2F0, 0xFF48}, //300 #FULLWIDTH LATIN SMALL LETTER H + {0xA2F1, 0xFF49}, //301 #FULLWIDTH LATIN SMALL LETTER I + {0xA2F2, 0xFF4A}, //302 #FULLWIDTH LATIN SMALL LETTER J + {0xA2F3, 0xFF4B}, //303 #FULLWIDTH LATIN SMALL LETTER K + {0xA2F4, 0xFF4C}, //304 #FULLWIDTH LATIN SMALL LETTER L + {0xA2F5, 0xFF4D}, //305 #FULLWIDTH LATIN SMALL LETTER M + {0xA2F6, 0xFF4E}, //306 #FULLWIDTH LATIN SMALL LETTER N + {0xA2F7, 0xFF4F}, //307 #FULLWIDTH LATIN SMALL LETTER O + {0xA2F8, 0xFF50}, //308 #FULLWIDTH LATIN SMALL LETTER P + {0xA2F9, 0xFF51}, //309 #FULLWIDTH LATIN SMALL LETTER Q + {0xA2FA, 0xFF52}, //310 #FULLWIDTH LATIN SMALL LETTER R + {0xA2FB, 0xFF53}, //311 #FULLWIDTH LATIN SMALL LETTER S + {0xA2FC, 0xFF54}, //312 #FULLWIDTH LATIN SMALL LETTER T + {0xA2FD, 0xFF55}, //313 #FULLWIDTH LATIN SMALL LETTER U + {0xA2FE, 0xFF56}, //314 #FULLWIDTH LATIN SMALL LETTER V + {0xA340, 0xFF57}, //315 #FULLWIDTH LATIN SMALL LETTER W + {0xA341, 0xFF58}, //316 #FULLWIDTH LATIN SMALL LETTER X + {0xA342, 0xFF59}, //317 #FULLWIDTH LATIN SMALL LETTER Y + {0xA343, 0xFF5A}, //318 #FULLWIDTH LATIN SMALL LETTER Z + {0xA344, 0x0391}, //319 #GREEK CAPITAL LETTER ALPHA + {0xA345, 0x0392}, //320 #GREEK CAPITAL LETTER BETA + {0xA346, 0x0393}, //321 #GREEK CAPITAL LETTER GAMMA + {0xA347, 0x0394}, //322 #GREEK CAPITAL LETTER DELTA + {0xA348, 0x0395}, //323 #GREEK CAPITAL LETTER EPSILON + {0xA349, 0x0396}, //324 #GREEK CAPITAL LETTER ZETA + {0xA34A, 0x0397}, //325 #GREEK CAPITAL LETTER ETA + {0xA34B, 0x0398}, //326 #GREEK CAPITAL LETTER THETA + {0xA34C, 0x0399}, //327 #GREEK CAPITAL LETTER IOTA + {0xA34D, 0x039A}, //328 #GREEK CAPITAL LETTER KAPPA + {0xA34E, 0x039B}, //329 #GREEK CAPITAL LETTER LAMDA + {0xA34F, 0x039C}, //330 #GREEK CAPITAL LETTER MU + {0xA350, 0x039D}, //331 #GREEK CAPITAL LETTER NU + {0xA351, 0x039E}, //332 #GREEK CAPITAL LETTER XI + {0xA352, 0x039F}, //333 #GREEK CAPITAL LETTER OMICRON + {0xA353, 0x03A0}, //334 #GREEK CAPITAL LETTER PI + {0xA354, 0x03A1}, //335 #GREEK CAPITAL LETTER RHO + {0xA355, 0x03A3}, //336 #GREEK CAPITAL LETTER SIGMA + {0xA356, 0x03A4}, //337 #GREEK CAPITAL LETTER TAU + {0xA357, 0x03A5}, //338 #GREEK CAPITAL LETTER UPSILON + {0xA358, 0x03A6}, //339 #GREEK CAPITAL LETTER PHI + {0xA359, 0x03A7}, //340 #GREEK CAPITAL LETTER CHI + {0xA35A, 0x03A8}, //341 #GREEK CAPITAL LETTER PSI + {0xA35B, 0x03A9}, //342 #GREEK CAPITAL LETTER OMEGA + {0xA35C, 0x03B1}, //343 #GREEK SMALL LETTER ALPHA + {0xA35D, 0x03B2}, //344 #GREEK SMALL LETTER BETA + {0xA35E, 0x03B3}, //345 #GREEK SMALL LETTER GAMMA + {0xA35F, 0x03B4}, //346 #GREEK SMALL LETTER DELTA + {0xA360, 0x03B5}, //347 #GREEK SMALL LETTER EPSILON + {0xA361, 0x03B6}, //348 #GREEK SMALL LETTER ZETA + {0xA362, 0x03B7}, //349 #GREEK SMALL LETTER ETA + {0xA363, 0x03B8}, //350 #GREEK SMALL LETTER THETA + {0xA364, 0x03B9}, //351 #GREEK SMALL LETTER IOTA + {0xA365, 0x03BA}, //352 #GREEK SMALL LETTER KAPPA + {0xA366, 0x03BB}, //353 #GREEK SMALL LETTER LAMDA + {0xA367, 0x03BC}, //354 #GREEK SMALL LETTER MU + {0xA368, 0x03BD}, //355 #GREEK SMALL LETTER NU + {0xA369, 0x03BE}, //356 #GREEK SMALL LETTER XI + {0xA36A, 0x03BF}, //357 #GREEK SMALL LETTER OMICRON + {0xA36B, 0x03C0}, //358 #GREEK SMALL LETTER PI + {0xA36C, 0x03C1}, //359 #GREEK SMALL LETTER RHO + {0xA36D, 0x03C3}, //360 #GREEK SMALL LETTER SIGMA + {0xA36E, 0x03C4}, //361 #GREEK SMALL LETTER TAU + {0xA36F, 0x03C5}, //362 #GREEK SMALL LETTER UPSILON + {0xA370, 0x03C6}, //363 #GREEK SMALL LETTER PHI + {0xA371, 0x03C7}, //364 #GREEK SMALL LETTER CHI + {0xA372, 0x03C8}, //365 #GREEK SMALL LETTER PSI + {0xA373, 0x03C9}, //366 #GREEK SMALL LETTER OMEGA + {0xA374, 0x3105}, //367 #BOPOMOFO LETTER B + {0xA375, 0x3106}, //368 #BOPOMOFO LETTER P + {0xA376, 0x3107}, //369 #BOPOMOFO LETTER M + {0xA377, 0x3108}, //370 #BOPOMOFO LETTER F + {0xA378, 0x3109}, //371 #BOPOMOFO LETTER D + {0xA379, 0x310A}, //372 #BOPOMOFO LETTER T + {0xA37A, 0x310B}, //373 #BOPOMOFO LETTER N + {0xA37B, 0x310C}, //374 #BOPOMOFO LETTER L + {0xA37C, 0x310D}, //375 #BOPOMOFO LETTER G + {0xA37D, 0x310E}, //376 #BOPOMOFO LETTER K + {0xA37E, 0x310F}, //377 #BOPOMOFO LETTER H + {0xA3A1, 0x3110}, //378 #BOPOMOFO LETTER J + {0xA3A2, 0x3111}, //379 #BOPOMOFO LETTER Q + {0xA3A3, 0x3112}, //380 #BOPOMOFO LETTER X + {0xA3A4, 0x3113}, //381 #BOPOMOFO LETTER ZH + {0xA3A5, 0x3114}, //382 #BOPOMOFO LETTER CH + {0xA3A6, 0x3115}, //383 #BOPOMOFO LETTER SH + {0xA3A7, 0x3116}, //384 #BOPOMOFO LETTER R + {0xA3A8, 0x3117}, //385 #BOPOMOFO LETTER Z + {0xA3A9, 0x3118}, //386 #BOPOMOFO LETTER C + {0xA3AA, 0x3119}, //387 #BOPOMOFO LETTER S + {0xA3AB, 0x311A}, //388 #BOPOMOFO LETTER A + {0xA3AC, 0x311B}, //389 #BOPOMOFO LETTER O + {0xA3AD, 0x311C}, //390 #BOPOMOFO LETTER E + {0xA3AE, 0x311D}, //391 #BOPOMOFO LETTER EH + {0xA3AF, 0x311E}, //392 #BOPOMOFO LETTER AI + {0xA3B0, 0x311F}, //393 #BOPOMOFO LETTER EI + {0xA3B1, 0x3120}, //394 #BOPOMOFO LETTER AU + {0xA3B2, 0x3121}, //395 #BOPOMOFO LETTER OU + {0xA3B3, 0x3122}, //396 #BOPOMOFO LETTER AN + {0xA3B4, 0x3123}, //397 #BOPOMOFO LETTER EN + {0xA3B5, 0x3124}, //398 #BOPOMOFO LETTER ANG + {0xA3B6, 0x3125}, //399 #BOPOMOFO LETTER ENG + {0xA3B7, 0x3126}, //400 #BOPOMOFO LETTER ER + {0xA3B8, 0x3127}, //401 #BOPOMOFO LETTER I + {0xA3B9, 0x3128}, //402 #BOPOMOFO LETTER U + {0xA3BA, 0x3129}, //403 #BOPOMOFO LETTER IU + {0xA3BB, 0x02D9}, //404 #DOT ABOVE + {0xA3BC, 0x02C9}, //405 #MODIFIER LETTER MACRON + {0xA3BD, 0x02CA}, //406 #MODIFIER LETTER ACUTE ACCENT + {0xA3BE, 0x02C7}, //407 #CARON + {0xA3BF, 0x02CB}, //408 #MODIFIER LETTER GRAVE ACCENT + {0xA3E1, 0x20AC}, //409 #EURO SIGN + {0xA440, 0x4E00}, //410 #CJK UNIFIED IDEOGRAPH + {0xA441, 0x4E59}, //411 #CJK UNIFIED IDEOGRAPH + {0xA442, 0x4E01}, //412 #CJK UNIFIED IDEOGRAPH + {0xA443, 0x4E03}, //413 #CJK UNIFIED IDEOGRAPH + {0xA444, 0x4E43}, //414 #CJK UNIFIED IDEOGRAPH + {0xA445, 0x4E5D}, //415 #CJK UNIFIED IDEOGRAPH + {0xA446, 0x4E86}, //416 #CJK UNIFIED IDEOGRAPH + {0xA447, 0x4E8C}, //417 #CJK UNIFIED IDEOGRAPH + {0xA448, 0x4EBA}, //418 #CJK UNIFIED IDEOGRAPH + {0xA449, 0x513F}, //419 #CJK UNIFIED IDEOGRAPH + {0xA44A, 0x5165}, //420 #CJK UNIFIED IDEOGRAPH + {0xA44B, 0x516B}, //421 #CJK UNIFIED IDEOGRAPH + {0xA44C, 0x51E0}, //422 #CJK UNIFIED IDEOGRAPH + {0xA44D, 0x5200}, //423 #CJK UNIFIED IDEOGRAPH + {0xA44E, 0x5201}, //424 #CJK UNIFIED IDEOGRAPH + {0xA44F, 0x529B}, //425 #CJK UNIFIED IDEOGRAPH + {0xA450, 0x5315}, //426 #CJK UNIFIED IDEOGRAPH + {0xA451, 0x5341}, //427 #CJK UNIFIED IDEOGRAPH + {0xA452, 0x535C}, //428 #CJK UNIFIED IDEOGRAPH + {0xA453, 0x53C8}, //429 #CJK UNIFIED IDEOGRAPH + {0xA454, 0x4E09}, //430 #CJK UNIFIED IDEOGRAPH + {0xA455, 0x4E0B}, //431 #CJK UNIFIED IDEOGRAPH + {0xA456, 0x4E08}, //432 #CJK UNIFIED IDEOGRAPH + {0xA457, 0x4E0A}, //433 #CJK UNIFIED IDEOGRAPH + {0xA458, 0x4E2B}, //434 #CJK UNIFIED IDEOGRAPH + {0xA459, 0x4E38}, //435 #CJK UNIFIED IDEOGRAPH + {0xA45A, 0x51E1}, //436 #CJK UNIFIED IDEOGRAPH + {0xA45B, 0x4E45}, //437 #CJK UNIFIED IDEOGRAPH + {0xA45C, 0x4E48}, //438 #CJK UNIFIED IDEOGRAPH + {0xA45D, 0x4E5F}, //439 #CJK UNIFIED IDEOGRAPH + {0xA45E, 0x4E5E}, //440 #CJK UNIFIED IDEOGRAPH + {0xA45F, 0x4E8E}, //441 #CJK UNIFIED IDEOGRAPH + {0xA460, 0x4EA1}, //442 #CJK UNIFIED IDEOGRAPH + {0xA461, 0x5140}, //443 #CJK UNIFIED IDEOGRAPH + {0xA462, 0x5203}, //444 #CJK UNIFIED IDEOGRAPH + {0xA463, 0x52FA}, //445 #CJK UNIFIED IDEOGRAPH + {0xA464, 0x5343}, //446 #CJK UNIFIED IDEOGRAPH + {0xA465, 0x53C9}, //447 #CJK UNIFIED IDEOGRAPH + {0xA466, 0x53E3}, //448 #CJK UNIFIED IDEOGRAPH + {0xA467, 0x571F}, //449 #CJK UNIFIED IDEOGRAPH + {0xA468, 0x58EB}, //450 #CJK UNIFIED IDEOGRAPH + {0xA469, 0x5915}, //451 #CJK UNIFIED IDEOGRAPH + {0xA46A, 0x5927}, //452 #CJK UNIFIED IDEOGRAPH + {0xA46B, 0x5973}, //453 #CJK UNIFIED IDEOGRAPH + {0xA46C, 0x5B50}, //454 #CJK UNIFIED IDEOGRAPH + {0xA46D, 0x5B51}, //455 #CJK UNIFIED IDEOGRAPH + {0xA46E, 0x5B53}, //456 #CJK UNIFIED IDEOGRAPH + {0xA46F, 0x5BF8}, //457 #CJK UNIFIED IDEOGRAPH + {0xA470, 0x5C0F}, //458 #CJK UNIFIED IDEOGRAPH + {0xA471, 0x5C22}, //459 #CJK UNIFIED IDEOGRAPH + {0xA472, 0x5C38}, //460 #CJK UNIFIED IDEOGRAPH + {0xA473, 0x5C71}, //461 #CJK UNIFIED IDEOGRAPH + {0xA474, 0x5DDD}, //462 #CJK UNIFIED IDEOGRAPH + {0xA475, 0x5DE5}, //463 #CJK UNIFIED IDEOGRAPH + {0xA476, 0x5DF1}, //464 #CJK UNIFIED IDEOGRAPH + {0xA477, 0x5DF2}, //465 #CJK UNIFIED IDEOGRAPH + {0xA478, 0x5DF3}, //466 #CJK UNIFIED IDEOGRAPH + {0xA479, 0x5DFE}, //467 #CJK UNIFIED IDEOGRAPH + {0xA47A, 0x5E72}, //468 #CJK UNIFIED IDEOGRAPH + {0xA47B, 0x5EFE}, //469 #CJK UNIFIED IDEOGRAPH + {0xA47C, 0x5F0B}, //470 #CJK UNIFIED IDEOGRAPH + {0xA47D, 0x5F13}, //471 #CJK UNIFIED IDEOGRAPH + {0xA47E, 0x624D}, //472 #CJK UNIFIED IDEOGRAPH + {0xA4A1, 0x4E11}, //473 #CJK UNIFIED IDEOGRAPH + {0xA4A2, 0x4E10}, //474 #CJK UNIFIED IDEOGRAPH + {0xA4A3, 0x4E0D}, //475 #CJK UNIFIED IDEOGRAPH + {0xA4A4, 0x4E2D}, //476 #CJK UNIFIED IDEOGRAPH + {0xA4A5, 0x4E30}, //477 #CJK UNIFIED IDEOGRAPH + {0xA4A6, 0x4E39}, //478 #CJK UNIFIED IDEOGRAPH + {0xA4A7, 0x4E4B}, //479 #CJK UNIFIED IDEOGRAPH + {0xA4A8, 0x5C39}, //480 #CJK UNIFIED IDEOGRAPH + {0xA4A9, 0x4E88}, //481 #CJK UNIFIED IDEOGRAPH + {0xA4AA, 0x4E91}, //482 #CJK UNIFIED IDEOGRAPH + {0xA4AB, 0x4E95}, //483 #CJK UNIFIED IDEOGRAPH + {0xA4AC, 0x4E92}, //484 #CJK UNIFIED IDEOGRAPH + {0xA4AD, 0x4E94}, //485 #CJK UNIFIED IDEOGRAPH + {0xA4AE, 0x4EA2}, //486 #CJK UNIFIED IDEOGRAPH + {0xA4AF, 0x4EC1}, //487 #CJK UNIFIED IDEOGRAPH + {0xA4B0, 0x4EC0}, //488 #CJK UNIFIED IDEOGRAPH + {0xA4B1, 0x4EC3}, //489 #CJK UNIFIED IDEOGRAPH + {0xA4B2, 0x4EC6}, //490 #CJK UNIFIED IDEOGRAPH + {0xA4B3, 0x4EC7}, //491 #CJK UNIFIED IDEOGRAPH + {0xA4B4, 0x4ECD}, //492 #CJK UNIFIED IDEOGRAPH + {0xA4B5, 0x4ECA}, //493 #CJK UNIFIED IDEOGRAPH + {0xA4B6, 0x4ECB}, //494 #CJK UNIFIED IDEOGRAPH + {0xA4B7, 0x4EC4}, //495 #CJK UNIFIED IDEOGRAPH + {0xA4B8, 0x5143}, //496 #CJK UNIFIED IDEOGRAPH + {0xA4B9, 0x5141}, //497 #CJK UNIFIED IDEOGRAPH + {0xA4BA, 0x5167}, //498 #CJK UNIFIED IDEOGRAPH + {0xA4BB, 0x516D}, //499 #CJK UNIFIED IDEOGRAPH + {0xA4BC, 0x516E}, //500 #CJK UNIFIED IDEOGRAPH + {0xA4BD, 0x516C}, //501 #CJK UNIFIED IDEOGRAPH + {0xA4BE, 0x5197}, //502 #CJK UNIFIED IDEOGRAPH + {0xA4BF, 0x51F6}, //503 #CJK UNIFIED IDEOGRAPH + {0xA4C0, 0x5206}, //504 #CJK UNIFIED IDEOGRAPH + {0xA4C1, 0x5207}, //505 #CJK UNIFIED IDEOGRAPH + {0xA4C2, 0x5208}, //506 #CJK UNIFIED IDEOGRAPH + {0xA4C3, 0x52FB}, //507 #CJK UNIFIED IDEOGRAPH + {0xA4C4, 0x52FE}, //508 #CJK UNIFIED IDEOGRAPH + {0xA4C5, 0x52FF}, //509 #CJK UNIFIED IDEOGRAPH + {0xA4C6, 0x5316}, //510 #CJK UNIFIED IDEOGRAPH + {0xA4C7, 0x5339}, //511 #CJK UNIFIED IDEOGRAPH + {0xA4C8, 0x5348}, //512 #CJK UNIFIED IDEOGRAPH + {0xA4C9, 0x5347}, //513 #CJK UNIFIED IDEOGRAPH + {0xA4CA, 0x5345}, //514 #CJK UNIFIED IDEOGRAPH + {0xA4CB, 0x535E}, //515 #CJK UNIFIED IDEOGRAPH + {0xA4CC, 0x5384}, //516 #CJK UNIFIED IDEOGRAPH + {0xA4CD, 0x53CB}, //517 #CJK UNIFIED IDEOGRAPH + {0xA4CE, 0x53CA}, //518 #CJK UNIFIED IDEOGRAPH + {0xA4CF, 0x53CD}, //519 #CJK UNIFIED IDEOGRAPH + {0xA4D0, 0x58EC}, //520 #CJK UNIFIED IDEOGRAPH + {0xA4D1, 0x5929}, //521 #CJK UNIFIED IDEOGRAPH + {0xA4D2, 0x592B}, //522 #CJK UNIFIED IDEOGRAPH + {0xA4D3, 0x592A}, //523 #CJK UNIFIED IDEOGRAPH + {0xA4D4, 0x592D}, //524 #CJK UNIFIED IDEOGRAPH + {0xA4D5, 0x5B54}, //525 #CJK UNIFIED IDEOGRAPH + {0xA4D6, 0x5C11}, //526 #CJK UNIFIED IDEOGRAPH + {0xA4D7, 0x5C24}, //527 #CJK UNIFIED IDEOGRAPH + {0xA4D8, 0x5C3A}, //528 #CJK UNIFIED IDEOGRAPH + {0xA4D9, 0x5C6F}, //529 #CJK UNIFIED IDEOGRAPH + {0xA4DA, 0x5DF4}, //530 #CJK UNIFIED IDEOGRAPH + {0xA4DB, 0x5E7B}, //531 #CJK UNIFIED IDEOGRAPH + {0xA4DC, 0x5EFF}, //532 #CJK UNIFIED IDEOGRAPH + {0xA4DD, 0x5F14}, //533 #CJK UNIFIED IDEOGRAPH + {0xA4DE, 0x5F15}, //534 #CJK UNIFIED IDEOGRAPH + {0xA4DF, 0x5FC3}, //535 #CJK UNIFIED IDEOGRAPH + {0xA4E0, 0x6208}, //536 #CJK UNIFIED IDEOGRAPH + {0xA4E1, 0x6236}, //537 #CJK UNIFIED IDEOGRAPH + {0xA4E2, 0x624B}, //538 #CJK UNIFIED IDEOGRAPH + {0xA4E3, 0x624E}, //539 #CJK UNIFIED IDEOGRAPH + {0xA4E4, 0x652F}, //540 #CJK UNIFIED IDEOGRAPH + {0xA4E5, 0x6587}, //541 #CJK UNIFIED IDEOGRAPH + {0xA4E6, 0x6597}, //542 #CJK UNIFIED IDEOGRAPH + {0xA4E7, 0x65A4}, //543 #CJK UNIFIED IDEOGRAPH + {0xA4E8, 0x65B9}, //544 #CJK UNIFIED IDEOGRAPH + {0xA4E9, 0x65E5}, //545 #CJK UNIFIED IDEOGRAPH + {0xA4EA, 0x66F0}, //546 #CJK UNIFIED IDEOGRAPH + {0xA4EB, 0x6708}, //547 #CJK UNIFIED IDEOGRAPH + {0xA4EC, 0x6728}, //548 #CJK UNIFIED IDEOGRAPH + {0xA4ED, 0x6B20}, //549 #CJK UNIFIED IDEOGRAPH + {0xA4EE, 0x6B62}, //550 #CJK UNIFIED IDEOGRAPH + {0xA4EF, 0x6B79}, //551 #CJK UNIFIED IDEOGRAPH + {0xA4F0, 0x6BCB}, //552 #CJK UNIFIED IDEOGRAPH + {0xA4F1, 0x6BD4}, //553 #CJK UNIFIED IDEOGRAPH + {0xA4F2, 0x6BDB}, //554 #CJK UNIFIED IDEOGRAPH + {0xA4F3, 0x6C0F}, //555 #CJK UNIFIED IDEOGRAPH + {0xA4F4, 0x6C34}, //556 #CJK UNIFIED IDEOGRAPH + {0xA4F5, 0x706B}, //557 #CJK UNIFIED IDEOGRAPH + {0xA4F6, 0x722A}, //558 #CJK UNIFIED IDEOGRAPH + {0xA4F7, 0x7236}, //559 #CJK UNIFIED IDEOGRAPH + {0xA4F8, 0x723B}, //560 #CJK UNIFIED IDEOGRAPH + {0xA4F9, 0x7247}, //561 #CJK UNIFIED IDEOGRAPH + {0xA4FA, 0x7259}, //562 #CJK UNIFIED IDEOGRAPH + {0xA4FB, 0x725B}, //563 #CJK UNIFIED IDEOGRAPH + {0xA4FC, 0x72AC}, //564 #CJK UNIFIED IDEOGRAPH + {0xA4FD, 0x738B}, //565 #CJK UNIFIED IDEOGRAPH + {0xA4FE, 0x4E19}, //566 #CJK UNIFIED IDEOGRAPH + {0xA540, 0x4E16}, //567 #CJK UNIFIED IDEOGRAPH + {0xA541, 0x4E15}, //568 #CJK UNIFIED IDEOGRAPH + {0xA542, 0x4E14}, //569 #CJK UNIFIED IDEOGRAPH + {0xA543, 0x4E18}, //570 #CJK UNIFIED IDEOGRAPH + {0xA544, 0x4E3B}, //571 #CJK UNIFIED IDEOGRAPH + {0xA545, 0x4E4D}, //572 #CJK UNIFIED IDEOGRAPH + {0xA546, 0x4E4F}, //573 #CJK UNIFIED IDEOGRAPH + {0xA547, 0x4E4E}, //574 #CJK UNIFIED IDEOGRAPH + {0xA548, 0x4EE5}, //575 #CJK UNIFIED IDEOGRAPH + {0xA549, 0x4ED8}, //576 #CJK UNIFIED IDEOGRAPH + {0xA54A, 0x4ED4}, //577 #CJK UNIFIED IDEOGRAPH + {0xA54B, 0x4ED5}, //578 #CJK UNIFIED IDEOGRAPH + {0xA54C, 0x4ED6}, //579 #CJK UNIFIED IDEOGRAPH + {0xA54D, 0x4ED7}, //580 #CJK UNIFIED IDEOGRAPH + {0xA54E, 0x4EE3}, //581 #CJK UNIFIED IDEOGRAPH + {0xA54F, 0x4EE4}, //582 #CJK UNIFIED IDEOGRAPH + {0xA550, 0x4ED9}, //583 #CJK UNIFIED IDEOGRAPH + {0xA551, 0x4EDE}, //584 #CJK UNIFIED IDEOGRAPH + {0xA552, 0x5145}, //585 #CJK UNIFIED IDEOGRAPH + {0xA553, 0x5144}, //586 #CJK UNIFIED IDEOGRAPH + {0xA554, 0x5189}, //587 #CJK UNIFIED IDEOGRAPH + {0xA555, 0x518A}, //588 #CJK UNIFIED IDEOGRAPH + {0xA556, 0x51AC}, //589 #CJK UNIFIED IDEOGRAPH + {0xA557, 0x51F9}, //590 #CJK UNIFIED IDEOGRAPH + {0xA558, 0x51FA}, //591 #CJK UNIFIED IDEOGRAPH + {0xA559, 0x51F8}, //592 #CJK UNIFIED IDEOGRAPH + {0xA55A, 0x520A}, //593 #CJK UNIFIED IDEOGRAPH + {0xA55B, 0x52A0}, //594 #CJK UNIFIED IDEOGRAPH + {0xA55C, 0x529F}, //595 #CJK UNIFIED IDEOGRAPH + {0xA55D, 0x5305}, //596 #CJK UNIFIED IDEOGRAPH + {0xA55E, 0x5306}, //597 #CJK UNIFIED IDEOGRAPH + {0xA55F, 0x5317}, //598 #CJK UNIFIED IDEOGRAPH + {0xA560, 0x531D}, //599 #CJK UNIFIED IDEOGRAPH + {0xA561, 0x4EDF}, //600 #CJK UNIFIED IDEOGRAPH + {0xA562, 0x534A}, //601 #CJK UNIFIED IDEOGRAPH + {0xA563, 0x5349}, //602 #CJK UNIFIED IDEOGRAPH + {0xA564, 0x5361}, //603 #CJK UNIFIED IDEOGRAPH + {0xA565, 0x5360}, //604 #CJK UNIFIED IDEOGRAPH + {0xA566, 0x536F}, //605 #CJK UNIFIED IDEOGRAPH + {0xA567, 0x536E}, //606 #CJK UNIFIED IDEOGRAPH + {0xA568, 0x53BB}, //607 #CJK UNIFIED IDEOGRAPH + {0xA569, 0x53EF}, //608 #CJK UNIFIED IDEOGRAPH + {0xA56A, 0x53E4}, //609 #CJK UNIFIED IDEOGRAPH + {0xA56B, 0x53F3}, //610 #CJK UNIFIED IDEOGRAPH + {0xA56C, 0x53EC}, //611 #CJK UNIFIED IDEOGRAPH + {0xA56D, 0x53EE}, //612 #CJK UNIFIED IDEOGRAPH + {0xA56E, 0x53E9}, //613 #CJK UNIFIED IDEOGRAPH + {0xA56F, 0x53E8}, //614 #CJK UNIFIED IDEOGRAPH + {0xA570, 0x53FC}, //615 #CJK UNIFIED IDEOGRAPH + {0xA571, 0x53F8}, //616 #CJK UNIFIED IDEOGRAPH + {0xA572, 0x53F5}, //617 #CJK UNIFIED IDEOGRAPH + {0xA573, 0x53EB}, //618 #CJK UNIFIED IDEOGRAPH + {0xA574, 0x53E6}, //619 #CJK UNIFIED IDEOGRAPH + {0xA575, 0x53EA}, //620 #CJK UNIFIED IDEOGRAPH + {0xA576, 0x53F2}, //621 #CJK UNIFIED IDEOGRAPH + {0xA577, 0x53F1}, //622 #CJK UNIFIED IDEOGRAPH + {0xA578, 0x53F0}, //623 #CJK UNIFIED IDEOGRAPH + {0xA579, 0x53E5}, //624 #CJK UNIFIED IDEOGRAPH + {0xA57A, 0x53ED}, //625 #CJK UNIFIED IDEOGRAPH + {0xA57B, 0x53FB}, //626 #CJK UNIFIED IDEOGRAPH + {0xA57C, 0x56DB}, //627 #CJK UNIFIED IDEOGRAPH + {0xA57D, 0x56DA}, //628 #CJK UNIFIED IDEOGRAPH + {0xA57E, 0x5916}, //629 #CJK UNIFIED IDEOGRAPH + {0xA5A1, 0x592E}, //630 #CJK UNIFIED IDEOGRAPH + {0xA5A2, 0x5931}, //631 #CJK UNIFIED IDEOGRAPH + {0xA5A3, 0x5974}, //632 #CJK UNIFIED IDEOGRAPH + {0xA5A4, 0x5976}, //633 #CJK UNIFIED IDEOGRAPH + {0xA5A5, 0x5B55}, //634 #CJK UNIFIED IDEOGRAPH + {0xA5A6, 0x5B83}, //635 #CJK UNIFIED IDEOGRAPH + {0xA5A7, 0x5C3C}, //636 #CJK UNIFIED IDEOGRAPH + {0xA5A8, 0x5DE8}, //637 #CJK UNIFIED IDEOGRAPH + {0xA5A9, 0x5DE7}, //638 #CJK UNIFIED IDEOGRAPH + {0xA5AA, 0x5DE6}, //639 #CJK UNIFIED IDEOGRAPH + {0xA5AB, 0x5E02}, //640 #CJK UNIFIED IDEOGRAPH + {0xA5AC, 0x5E03}, //641 #CJK UNIFIED IDEOGRAPH + {0xA5AD, 0x5E73}, //642 #CJK UNIFIED IDEOGRAPH + {0xA5AE, 0x5E7C}, //643 #CJK UNIFIED IDEOGRAPH + {0xA5AF, 0x5F01}, //644 #CJK UNIFIED IDEOGRAPH + {0xA5B0, 0x5F18}, //645 #CJK UNIFIED IDEOGRAPH + {0xA5B1, 0x5F17}, //646 #CJK UNIFIED IDEOGRAPH + {0xA5B2, 0x5FC5}, //647 #CJK UNIFIED IDEOGRAPH + {0xA5B3, 0x620A}, //648 #CJK UNIFIED IDEOGRAPH + {0xA5B4, 0x6253}, //649 #CJK UNIFIED IDEOGRAPH + {0xA5B5, 0x6254}, //650 #CJK UNIFIED IDEOGRAPH + {0xA5B6, 0x6252}, //651 #CJK UNIFIED IDEOGRAPH + {0xA5B7, 0x6251}, //652 #CJK UNIFIED IDEOGRAPH + {0xA5B8, 0x65A5}, //653 #CJK UNIFIED IDEOGRAPH + {0xA5B9, 0x65E6}, //654 #CJK UNIFIED IDEOGRAPH + {0xA5BA, 0x672E}, //655 #CJK UNIFIED IDEOGRAPH + {0xA5BB, 0x672C}, //656 #CJK UNIFIED IDEOGRAPH + {0xA5BC, 0x672A}, //657 #CJK UNIFIED IDEOGRAPH + {0xA5BD, 0x672B}, //658 #CJK UNIFIED IDEOGRAPH + {0xA5BE, 0x672D}, //659 #CJK UNIFIED IDEOGRAPH + {0xA5BF, 0x6B63}, //660 #CJK UNIFIED IDEOGRAPH + {0xA5C0, 0x6BCD}, //661 #CJK UNIFIED IDEOGRAPH + {0xA5C1, 0x6C11}, //662 #CJK UNIFIED IDEOGRAPH + {0xA5C2, 0x6C10}, //663 #CJK UNIFIED IDEOGRAPH + {0xA5C3, 0x6C38}, //664 #CJK UNIFIED IDEOGRAPH + {0xA5C4, 0x6C41}, //665 #CJK UNIFIED IDEOGRAPH + {0xA5C5, 0x6C40}, //666 #CJK UNIFIED IDEOGRAPH + {0xA5C6, 0x6C3E}, //667 #CJK UNIFIED IDEOGRAPH + {0xA5C7, 0x72AF}, //668 #CJK UNIFIED IDEOGRAPH + {0xA5C8, 0x7384}, //669 #CJK UNIFIED IDEOGRAPH + {0xA5C9, 0x7389}, //670 #CJK UNIFIED IDEOGRAPH + {0xA5CA, 0x74DC}, //671 #CJK UNIFIED IDEOGRAPH + {0xA5CB, 0x74E6}, //672 #CJK UNIFIED IDEOGRAPH + {0xA5CC, 0x7518}, //673 #CJK UNIFIED IDEOGRAPH + {0xA5CD, 0x751F}, //674 #CJK UNIFIED IDEOGRAPH + {0xA5CE, 0x7528}, //675 #CJK UNIFIED IDEOGRAPH + {0xA5CF, 0x7529}, //676 #CJK UNIFIED IDEOGRAPH + {0xA5D0, 0x7530}, //677 #CJK UNIFIED IDEOGRAPH + {0xA5D1, 0x7531}, //678 #CJK UNIFIED IDEOGRAPH + {0xA5D2, 0x7532}, //679 #CJK UNIFIED IDEOGRAPH + {0xA5D3, 0x7533}, //680 #CJK UNIFIED IDEOGRAPH + {0xA5D4, 0x758B}, //681 #CJK UNIFIED IDEOGRAPH + {0xA5D5, 0x767D}, //682 #CJK UNIFIED IDEOGRAPH + {0xA5D6, 0x76AE}, //683 #CJK UNIFIED IDEOGRAPH + {0xA5D7, 0x76BF}, //684 #CJK UNIFIED IDEOGRAPH + {0xA5D8, 0x76EE}, //685 #CJK UNIFIED IDEOGRAPH + {0xA5D9, 0x77DB}, //686 #CJK UNIFIED IDEOGRAPH + {0xA5DA, 0x77E2}, //687 #CJK UNIFIED IDEOGRAPH + {0xA5DB, 0x77F3}, //688 #CJK UNIFIED IDEOGRAPH + {0xA5DC, 0x793A}, //689 #CJK UNIFIED IDEOGRAPH + {0xA5DD, 0x79BE}, //690 #CJK UNIFIED IDEOGRAPH + {0xA5DE, 0x7A74}, //691 #CJK UNIFIED IDEOGRAPH + {0xA5DF, 0x7ACB}, //692 #CJK UNIFIED IDEOGRAPH + {0xA5E0, 0x4E1E}, //693 #CJK UNIFIED IDEOGRAPH + {0xA5E1, 0x4E1F}, //694 #CJK UNIFIED IDEOGRAPH + {0xA5E2, 0x4E52}, //695 #CJK UNIFIED IDEOGRAPH + {0xA5E3, 0x4E53}, //696 #CJK UNIFIED IDEOGRAPH + {0xA5E4, 0x4E69}, //697 #CJK UNIFIED IDEOGRAPH + {0xA5E5, 0x4E99}, //698 #CJK UNIFIED IDEOGRAPH + {0xA5E6, 0x4EA4}, //699 #CJK UNIFIED IDEOGRAPH + {0xA5E7, 0x4EA6}, //700 #CJK UNIFIED IDEOGRAPH + {0xA5E8, 0x4EA5}, //701 #CJK UNIFIED IDEOGRAPH + {0xA5E9, 0x4EFF}, //702 #CJK UNIFIED IDEOGRAPH + {0xA5EA, 0x4F09}, //703 #CJK UNIFIED IDEOGRAPH + {0xA5EB, 0x4F19}, //704 #CJK UNIFIED IDEOGRAPH + {0xA5EC, 0x4F0A}, //705 #CJK UNIFIED IDEOGRAPH + {0xA5ED, 0x4F15}, //706 #CJK UNIFIED IDEOGRAPH + {0xA5EE, 0x4F0D}, //707 #CJK UNIFIED IDEOGRAPH + {0xA5EF, 0x4F10}, //708 #CJK UNIFIED IDEOGRAPH + {0xA5F0, 0x4F11}, //709 #CJK UNIFIED IDEOGRAPH + {0xA5F1, 0x4F0F}, //710 #CJK UNIFIED IDEOGRAPH + {0xA5F2, 0x4EF2}, //711 #CJK UNIFIED IDEOGRAPH + {0xA5F3, 0x4EF6}, //712 #CJK UNIFIED IDEOGRAPH + {0xA5F4, 0x4EFB}, //713 #CJK UNIFIED IDEOGRAPH + {0xA5F5, 0x4EF0}, //714 #CJK UNIFIED IDEOGRAPH + {0xA5F6, 0x4EF3}, //715 #CJK UNIFIED IDEOGRAPH + {0xA5F7, 0x4EFD}, //716 #CJK UNIFIED IDEOGRAPH + {0xA5F8, 0x4F01}, //717 #CJK UNIFIED IDEOGRAPH + {0xA5F9, 0x4F0B}, //718 #CJK UNIFIED IDEOGRAPH + {0xA5FA, 0x5149}, //719 #CJK UNIFIED IDEOGRAPH + {0xA5FB, 0x5147}, //720 #CJK UNIFIED IDEOGRAPH + {0xA5FC, 0x5146}, //721 #CJK UNIFIED IDEOGRAPH + {0xA5FD, 0x5148}, //722 #CJK UNIFIED IDEOGRAPH + {0xA5FE, 0x5168}, //723 #CJK UNIFIED IDEOGRAPH + {0xA640, 0x5171}, //724 #CJK UNIFIED IDEOGRAPH + {0xA641, 0x518D}, //725 #CJK UNIFIED IDEOGRAPH + {0xA642, 0x51B0}, //726 #CJK UNIFIED IDEOGRAPH + {0xA643, 0x5217}, //727 #CJK UNIFIED IDEOGRAPH + {0xA644, 0x5211}, //728 #CJK UNIFIED IDEOGRAPH + {0xA645, 0x5212}, //729 #CJK UNIFIED IDEOGRAPH + {0xA646, 0x520E}, //730 #CJK UNIFIED IDEOGRAPH + {0xA647, 0x5216}, //731 #CJK UNIFIED IDEOGRAPH + {0xA648, 0x52A3}, //732 #CJK UNIFIED IDEOGRAPH + {0xA649, 0x5308}, //733 #CJK UNIFIED IDEOGRAPH + {0xA64A, 0x5321}, //734 #CJK UNIFIED IDEOGRAPH + {0xA64B, 0x5320}, //735 #CJK UNIFIED IDEOGRAPH + {0xA64C, 0x5370}, //736 #CJK UNIFIED IDEOGRAPH + {0xA64D, 0x5371}, //737 #CJK UNIFIED IDEOGRAPH + {0xA64E, 0x5409}, //738 #CJK UNIFIED IDEOGRAPH + {0xA64F, 0x540F}, //739 #CJK UNIFIED IDEOGRAPH + {0xA650, 0x540C}, //740 #CJK UNIFIED IDEOGRAPH + {0xA651, 0x540A}, //741 #CJK UNIFIED IDEOGRAPH + {0xA652, 0x5410}, //742 #CJK UNIFIED IDEOGRAPH + {0xA653, 0x5401}, //743 #CJK UNIFIED IDEOGRAPH + {0xA654, 0x540B}, //744 #CJK UNIFIED IDEOGRAPH + {0xA655, 0x5404}, //745 #CJK UNIFIED IDEOGRAPH + {0xA656, 0x5411}, //746 #CJK UNIFIED IDEOGRAPH + {0xA657, 0x540D}, //747 #CJK UNIFIED IDEOGRAPH + {0xA658, 0x5408}, //748 #CJK UNIFIED IDEOGRAPH + {0xA659, 0x5403}, //749 #CJK UNIFIED IDEOGRAPH + {0xA65A, 0x540E}, //750 #CJK UNIFIED IDEOGRAPH + {0xA65B, 0x5406}, //751 #CJK UNIFIED IDEOGRAPH + {0xA65C, 0x5412}, //752 #CJK UNIFIED IDEOGRAPH + {0xA65D, 0x56E0}, //753 #CJK UNIFIED IDEOGRAPH + {0xA65E, 0x56DE}, //754 #CJK UNIFIED IDEOGRAPH + {0xA65F, 0x56DD}, //755 #CJK UNIFIED IDEOGRAPH + {0xA660, 0x5733}, //756 #CJK UNIFIED IDEOGRAPH + {0xA661, 0x5730}, //757 #CJK UNIFIED IDEOGRAPH + {0xA662, 0x5728}, //758 #CJK UNIFIED IDEOGRAPH + {0xA663, 0x572D}, //759 #CJK UNIFIED IDEOGRAPH + {0xA664, 0x572C}, //760 #CJK UNIFIED IDEOGRAPH + {0xA665, 0x572F}, //761 #CJK UNIFIED IDEOGRAPH + {0xA666, 0x5729}, //762 #CJK UNIFIED IDEOGRAPH + {0xA667, 0x5919}, //763 #CJK UNIFIED IDEOGRAPH + {0xA668, 0x591A}, //764 #CJK UNIFIED IDEOGRAPH + {0xA669, 0x5937}, //765 #CJK UNIFIED IDEOGRAPH + {0xA66A, 0x5938}, //766 #CJK UNIFIED IDEOGRAPH + {0xA66B, 0x5984}, //767 #CJK UNIFIED IDEOGRAPH + {0xA66C, 0x5978}, //768 #CJK UNIFIED IDEOGRAPH + {0xA66D, 0x5983}, //769 #CJK UNIFIED IDEOGRAPH + {0xA66E, 0x597D}, //770 #CJK UNIFIED IDEOGRAPH + {0xA66F, 0x5979}, //771 #CJK UNIFIED IDEOGRAPH + {0xA670, 0x5982}, //772 #CJK UNIFIED IDEOGRAPH + {0xA671, 0x5981}, //773 #CJK UNIFIED IDEOGRAPH + {0xA672, 0x5B57}, //774 #CJK UNIFIED IDEOGRAPH + {0xA673, 0x5B58}, //775 #CJK UNIFIED IDEOGRAPH + {0xA674, 0x5B87}, //776 #CJK UNIFIED IDEOGRAPH + {0xA675, 0x5B88}, //777 #CJK UNIFIED IDEOGRAPH + {0xA676, 0x5B85}, //778 #CJK UNIFIED IDEOGRAPH + {0xA677, 0x5B89}, //779 #CJK UNIFIED IDEOGRAPH + {0xA678, 0x5BFA}, //780 #CJK UNIFIED IDEOGRAPH + {0xA679, 0x5C16}, //781 #CJK UNIFIED IDEOGRAPH + {0xA67A, 0x5C79}, //782 #CJK UNIFIED IDEOGRAPH + {0xA67B, 0x5DDE}, //783 #CJK UNIFIED IDEOGRAPH + {0xA67C, 0x5E06}, //784 #CJK UNIFIED IDEOGRAPH + {0xA67D, 0x5E76}, //785 #CJK UNIFIED IDEOGRAPH + {0xA67E, 0x5E74}, //786 #CJK UNIFIED IDEOGRAPH + {0xA6A1, 0x5F0F}, //787 #CJK UNIFIED IDEOGRAPH + {0xA6A2, 0x5F1B}, //788 #CJK UNIFIED IDEOGRAPH + {0xA6A3, 0x5FD9}, //789 #CJK UNIFIED IDEOGRAPH + {0xA6A4, 0x5FD6}, //790 #CJK UNIFIED IDEOGRAPH + {0xA6A5, 0x620E}, //791 #CJK UNIFIED IDEOGRAPH + {0xA6A6, 0x620C}, //792 #CJK UNIFIED IDEOGRAPH + {0xA6A7, 0x620D}, //793 #CJK UNIFIED IDEOGRAPH + {0xA6A8, 0x6210}, //794 #CJK UNIFIED IDEOGRAPH + {0xA6A9, 0x6263}, //795 #CJK UNIFIED IDEOGRAPH + {0xA6AA, 0x625B}, //796 #CJK UNIFIED IDEOGRAPH + {0xA6AB, 0x6258}, //797 #CJK UNIFIED IDEOGRAPH + {0xA6AC, 0x6536}, //798 #CJK UNIFIED IDEOGRAPH + {0xA6AD, 0x65E9}, //799 #CJK UNIFIED IDEOGRAPH + {0xA6AE, 0x65E8}, //800 #CJK UNIFIED IDEOGRAPH + {0xA6AF, 0x65EC}, //801 #CJK UNIFIED IDEOGRAPH + {0xA6B0, 0x65ED}, //802 #CJK UNIFIED IDEOGRAPH + {0xA6B1, 0x66F2}, //803 #CJK UNIFIED IDEOGRAPH + {0xA6B2, 0x66F3}, //804 #CJK UNIFIED IDEOGRAPH + {0xA6B3, 0x6709}, //805 #CJK UNIFIED IDEOGRAPH + {0xA6B4, 0x673D}, //806 #CJK UNIFIED IDEOGRAPH + {0xA6B5, 0x6734}, //807 #CJK UNIFIED IDEOGRAPH + {0xA6B6, 0x6731}, //808 #CJK UNIFIED IDEOGRAPH + {0xA6B7, 0x6735}, //809 #CJK UNIFIED IDEOGRAPH + {0xA6B8, 0x6B21}, //810 #CJK UNIFIED IDEOGRAPH + {0xA6B9, 0x6B64}, //811 #CJK UNIFIED IDEOGRAPH + {0xA6BA, 0x6B7B}, //812 #CJK UNIFIED IDEOGRAPH + {0xA6BB, 0x6C16}, //813 #CJK UNIFIED IDEOGRAPH + {0xA6BC, 0x6C5D}, //814 #CJK UNIFIED IDEOGRAPH + {0xA6BD, 0x6C57}, //815 #CJK UNIFIED IDEOGRAPH + {0xA6BE, 0x6C59}, //816 #CJK UNIFIED IDEOGRAPH + {0xA6BF, 0x6C5F}, //817 #CJK UNIFIED IDEOGRAPH + {0xA6C0, 0x6C60}, //818 #CJK UNIFIED IDEOGRAPH + {0xA6C1, 0x6C50}, //819 #CJK UNIFIED IDEOGRAPH + {0xA6C2, 0x6C55}, //820 #CJK UNIFIED IDEOGRAPH + {0xA6C3, 0x6C61}, //821 #CJK UNIFIED IDEOGRAPH + {0xA6C4, 0x6C5B}, //822 #CJK UNIFIED IDEOGRAPH + {0xA6C5, 0x6C4D}, //823 #CJK UNIFIED IDEOGRAPH + {0xA6C6, 0x6C4E}, //824 #CJK UNIFIED IDEOGRAPH + {0xA6C7, 0x7070}, //825 #CJK UNIFIED IDEOGRAPH + {0xA6C8, 0x725F}, //826 #CJK UNIFIED IDEOGRAPH + {0xA6C9, 0x725D}, //827 #CJK UNIFIED IDEOGRAPH + {0xA6CA, 0x767E}, //828 #CJK UNIFIED IDEOGRAPH + {0xA6CB, 0x7AF9}, //829 #CJK UNIFIED IDEOGRAPH + {0xA6CC, 0x7C73}, //830 #CJK UNIFIED IDEOGRAPH + {0xA6CD, 0x7CF8}, //831 #CJK UNIFIED IDEOGRAPH + {0xA6CE, 0x7F36}, //832 #CJK UNIFIED IDEOGRAPH + {0xA6CF, 0x7F8A}, //833 #CJK UNIFIED IDEOGRAPH + {0xA6D0, 0x7FBD}, //834 #CJK UNIFIED IDEOGRAPH + {0xA6D1, 0x8001}, //835 #CJK UNIFIED IDEOGRAPH + {0xA6D2, 0x8003}, //836 #CJK UNIFIED IDEOGRAPH + {0xA6D3, 0x800C}, //837 #CJK UNIFIED IDEOGRAPH + {0xA6D4, 0x8012}, //838 #CJK UNIFIED IDEOGRAPH + {0xA6D5, 0x8033}, //839 #CJK UNIFIED IDEOGRAPH + {0xA6D6, 0x807F}, //840 #CJK UNIFIED IDEOGRAPH + {0xA6D7, 0x8089}, //841 #CJK UNIFIED IDEOGRAPH + {0xA6D8, 0x808B}, //842 #CJK UNIFIED IDEOGRAPH + {0xA6D9, 0x808C}, //843 #CJK UNIFIED IDEOGRAPH + {0xA6DA, 0x81E3}, //844 #CJK UNIFIED IDEOGRAPH + {0xA6DB, 0x81EA}, //845 #CJK UNIFIED IDEOGRAPH + {0xA6DC, 0x81F3}, //846 #CJK UNIFIED IDEOGRAPH + {0xA6DD, 0x81FC}, //847 #CJK UNIFIED IDEOGRAPH + {0xA6DE, 0x820C}, //848 #CJK UNIFIED IDEOGRAPH + {0xA6DF, 0x821B}, //849 #CJK UNIFIED IDEOGRAPH + {0xA6E0, 0x821F}, //850 #CJK UNIFIED IDEOGRAPH + {0xA6E1, 0x826E}, //851 #CJK UNIFIED IDEOGRAPH + {0xA6E2, 0x8272}, //852 #CJK UNIFIED IDEOGRAPH + {0xA6E3, 0x827E}, //853 #CJK UNIFIED IDEOGRAPH + {0xA6E4, 0x866B}, //854 #CJK UNIFIED IDEOGRAPH + {0xA6E5, 0x8840}, //855 #CJK UNIFIED IDEOGRAPH + {0xA6E6, 0x884C}, //856 #CJK UNIFIED IDEOGRAPH + {0xA6E7, 0x8863}, //857 #CJK UNIFIED IDEOGRAPH + {0xA6E8, 0x897F}, //858 #CJK UNIFIED IDEOGRAPH + {0xA6E9, 0x9621}, //859 #CJK UNIFIED IDEOGRAPH + {0xA6EA, 0x4E32}, //860 #CJK UNIFIED IDEOGRAPH + {0xA6EB, 0x4EA8}, //861 #CJK UNIFIED IDEOGRAPH + {0xA6EC, 0x4F4D}, //862 #CJK UNIFIED IDEOGRAPH + {0xA6ED, 0x4F4F}, //863 #CJK UNIFIED IDEOGRAPH + {0xA6EE, 0x4F47}, //864 #CJK UNIFIED IDEOGRAPH + {0xA6EF, 0x4F57}, //865 #CJK UNIFIED IDEOGRAPH + {0xA6F0, 0x4F5E}, //866 #CJK UNIFIED IDEOGRAPH + {0xA6F1, 0x4F34}, //867 #CJK UNIFIED IDEOGRAPH + {0xA6F2, 0x4F5B}, //868 #CJK UNIFIED IDEOGRAPH + {0xA6F3, 0x4F55}, //869 #CJK UNIFIED IDEOGRAPH + {0xA6F4, 0x4F30}, //870 #CJK UNIFIED IDEOGRAPH + {0xA6F5, 0x4F50}, //871 #CJK UNIFIED IDEOGRAPH + {0xA6F6, 0x4F51}, //872 #CJK UNIFIED IDEOGRAPH + {0xA6F7, 0x4F3D}, //873 #CJK UNIFIED IDEOGRAPH + {0xA6F8, 0x4F3A}, //874 #CJK UNIFIED IDEOGRAPH + {0xA6F9, 0x4F38}, //875 #CJK UNIFIED IDEOGRAPH + {0xA6FA, 0x4F43}, //876 #CJK UNIFIED IDEOGRAPH + {0xA6FB, 0x4F54}, //877 #CJK UNIFIED IDEOGRAPH + {0xA6FC, 0x4F3C}, //878 #CJK UNIFIED IDEOGRAPH + {0xA6FD, 0x4F46}, //879 #CJK UNIFIED IDEOGRAPH + {0xA6FE, 0x4F63}, //880 #CJK UNIFIED IDEOGRAPH + {0xA740, 0x4F5C}, //881 #CJK UNIFIED IDEOGRAPH + {0xA741, 0x4F60}, //882 #CJK UNIFIED IDEOGRAPH + {0xA742, 0x4F2F}, //883 #CJK UNIFIED IDEOGRAPH + {0xA743, 0x4F4E}, //884 #CJK UNIFIED IDEOGRAPH + {0xA744, 0x4F36}, //885 #CJK UNIFIED IDEOGRAPH + {0xA745, 0x4F59}, //886 #CJK UNIFIED IDEOGRAPH + {0xA746, 0x4F5D}, //887 #CJK UNIFIED IDEOGRAPH + {0xA747, 0x4F48}, //888 #CJK UNIFIED IDEOGRAPH + {0xA748, 0x4F5A}, //889 #CJK UNIFIED IDEOGRAPH + {0xA749, 0x514C}, //890 #CJK UNIFIED IDEOGRAPH + {0xA74A, 0x514B}, //891 #CJK UNIFIED IDEOGRAPH + {0xA74B, 0x514D}, //892 #CJK UNIFIED IDEOGRAPH + {0xA74C, 0x5175}, //893 #CJK UNIFIED IDEOGRAPH + {0xA74D, 0x51B6}, //894 #CJK UNIFIED IDEOGRAPH + {0xA74E, 0x51B7}, //895 #CJK UNIFIED IDEOGRAPH + {0xA74F, 0x5225}, //896 #CJK UNIFIED IDEOGRAPH + {0xA750, 0x5224}, //897 #CJK UNIFIED IDEOGRAPH + {0xA751, 0x5229}, //898 #CJK UNIFIED IDEOGRAPH + {0xA752, 0x522A}, //899 #CJK UNIFIED IDEOGRAPH + {0xA753, 0x5228}, //900 #CJK UNIFIED IDEOGRAPH + {0xA754, 0x52AB}, //901 #CJK UNIFIED IDEOGRAPH + {0xA755, 0x52A9}, //902 #CJK UNIFIED IDEOGRAPH + {0xA756, 0x52AA}, //903 #CJK UNIFIED IDEOGRAPH + {0xA757, 0x52AC}, //904 #CJK UNIFIED IDEOGRAPH + {0xA758, 0x5323}, //905 #CJK UNIFIED IDEOGRAPH + {0xA759, 0x5373}, //906 #CJK UNIFIED IDEOGRAPH + {0xA75A, 0x5375}, //907 #CJK UNIFIED IDEOGRAPH + {0xA75B, 0x541D}, //908 #CJK UNIFIED IDEOGRAPH + {0xA75C, 0x542D}, //909 #CJK UNIFIED IDEOGRAPH + {0xA75D, 0x541E}, //910 #CJK UNIFIED IDEOGRAPH + {0xA75E, 0x543E}, //911 #CJK UNIFIED IDEOGRAPH + {0xA75F, 0x5426}, //912 #CJK UNIFIED IDEOGRAPH + {0xA760, 0x544E}, //913 #CJK UNIFIED IDEOGRAPH + {0xA761, 0x5427}, //914 #CJK UNIFIED IDEOGRAPH + {0xA762, 0x5446}, //915 #CJK UNIFIED IDEOGRAPH + {0xA763, 0x5443}, //916 #CJK UNIFIED IDEOGRAPH + {0xA764, 0x5433}, //917 #CJK UNIFIED IDEOGRAPH + {0xA765, 0x5448}, //918 #CJK UNIFIED IDEOGRAPH + {0xA766, 0x5442}, //919 #CJK UNIFIED IDEOGRAPH + {0xA767, 0x541B}, //920 #CJK UNIFIED IDEOGRAPH + {0xA768, 0x5429}, //921 #CJK UNIFIED IDEOGRAPH + {0xA769, 0x544A}, //922 #CJK UNIFIED IDEOGRAPH + {0xA76A, 0x5439}, //923 #CJK UNIFIED IDEOGRAPH + {0xA76B, 0x543B}, //924 #CJK UNIFIED IDEOGRAPH + {0xA76C, 0x5438}, //925 #CJK UNIFIED IDEOGRAPH + {0xA76D, 0x542E}, //926 #CJK UNIFIED IDEOGRAPH + {0xA76E, 0x5435}, //927 #CJK UNIFIED IDEOGRAPH + {0xA76F, 0x5436}, //928 #CJK UNIFIED IDEOGRAPH + {0xA770, 0x5420}, //929 #CJK UNIFIED IDEOGRAPH + {0xA771, 0x543C}, //930 #CJK UNIFIED IDEOGRAPH + {0xA772, 0x5440}, //931 #CJK UNIFIED IDEOGRAPH + {0xA773, 0x5431}, //932 #CJK UNIFIED IDEOGRAPH + {0xA774, 0x542B}, //933 #CJK UNIFIED IDEOGRAPH + {0xA775, 0x541F}, //934 #CJK UNIFIED IDEOGRAPH + {0xA776, 0x542C}, //935 #CJK UNIFIED IDEOGRAPH + {0xA777, 0x56EA}, //936 #CJK UNIFIED IDEOGRAPH + {0xA778, 0x56F0}, //937 #CJK UNIFIED IDEOGRAPH + {0xA779, 0x56E4}, //938 #CJK UNIFIED IDEOGRAPH + {0xA77A, 0x56EB}, //939 #CJK UNIFIED IDEOGRAPH + {0xA77B, 0x574A}, //940 #CJK UNIFIED IDEOGRAPH + {0xA77C, 0x5751}, //941 #CJK UNIFIED IDEOGRAPH + {0xA77D, 0x5740}, //942 #CJK UNIFIED IDEOGRAPH + {0xA77E, 0x574D}, //943 #CJK UNIFIED IDEOGRAPH + {0xA7A1, 0x5747}, //944 #CJK UNIFIED IDEOGRAPH + {0xA7A2, 0x574E}, //945 #CJK UNIFIED IDEOGRAPH + {0xA7A3, 0x573E}, //946 #CJK UNIFIED IDEOGRAPH + {0xA7A4, 0x5750}, //947 #CJK UNIFIED IDEOGRAPH + {0xA7A5, 0x574F}, //948 #CJK UNIFIED IDEOGRAPH + {0xA7A6, 0x573B}, //949 #CJK UNIFIED IDEOGRAPH + {0xA7A7, 0x58EF}, //950 #CJK UNIFIED IDEOGRAPH + {0xA7A8, 0x593E}, //951 #CJK UNIFIED IDEOGRAPH + {0xA7A9, 0x599D}, //952 #CJK UNIFIED IDEOGRAPH + {0xA7AA, 0x5992}, //953 #CJK UNIFIED IDEOGRAPH + {0xA7AB, 0x59A8}, //954 #CJK UNIFIED IDEOGRAPH + {0xA7AC, 0x599E}, //955 #CJK UNIFIED IDEOGRAPH + {0xA7AD, 0x59A3}, //956 #CJK UNIFIED IDEOGRAPH + {0xA7AE, 0x5999}, //957 #CJK UNIFIED IDEOGRAPH + {0xA7AF, 0x5996}, //958 #CJK UNIFIED IDEOGRAPH + {0xA7B0, 0x598D}, //959 #CJK UNIFIED IDEOGRAPH + {0xA7B1, 0x59A4}, //960 #CJK UNIFIED IDEOGRAPH + {0xA7B2, 0x5993}, //961 #CJK UNIFIED IDEOGRAPH + {0xA7B3, 0x598A}, //962 #CJK UNIFIED IDEOGRAPH + {0xA7B4, 0x59A5}, //963 #CJK UNIFIED IDEOGRAPH + {0xA7B5, 0x5B5D}, //964 #CJK UNIFIED IDEOGRAPH + {0xA7B6, 0x5B5C}, //965 #CJK UNIFIED IDEOGRAPH + {0xA7B7, 0x5B5A}, //966 #CJK UNIFIED IDEOGRAPH + {0xA7B8, 0x5B5B}, //967 #CJK UNIFIED IDEOGRAPH + {0xA7B9, 0x5B8C}, //968 #CJK UNIFIED IDEOGRAPH + {0xA7BA, 0x5B8B}, //969 #CJK UNIFIED IDEOGRAPH + {0xA7BB, 0x5B8F}, //970 #CJK UNIFIED IDEOGRAPH + {0xA7BC, 0x5C2C}, //971 #CJK UNIFIED IDEOGRAPH + {0xA7BD, 0x5C40}, //972 #CJK UNIFIED IDEOGRAPH + {0xA7BE, 0x5C41}, //973 #CJK UNIFIED IDEOGRAPH + {0xA7BF, 0x5C3F}, //974 #CJK UNIFIED IDEOGRAPH + {0xA7C0, 0x5C3E}, //975 #CJK UNIFIED IDEOGRAPH + {0xA7C1, 0x5C90}, //976 #CJK UNIFIED IDEOGRAPH + {0xA7C2, 0x5C91}, //977 #CJK UNIFIED IDEOGRAPH + {0xA7C3, 0x5C94}, //978 #CJK UNIFIED IDEOGRAPH + {0xA7C4, 0x5C8C}, //979 #CJK UNIFIED IDEOGRAPH + {0xA7C5, 0x5DEB}, //980 #CJK UNIFIED IDEOGRAPH + {0xA7C6, 0x5E0C}, //981 #CJK UNIFIED IDEOGRAPH + {0xA7C7, 0x5E8F}, //982 #CJK UNIFIED IDEOGRAPH + {0xA7C8, 0x5E87}, //983 #CJK UNIFIED IDEOGRAPH + {0xA7C9, 0x5E8A}, //984 #CJK UNIFIED IDEOGRAPH + {0xA7CA, 0x5EF7}, //985 #CJK UNIFIED IDEOGRAPH + {0xA7CB, 0x5F04}, //986 #CJK UNIFIED IDEOGRAPH + {0xA7CC, 0x5F1F}, //987 #CJK UNIFIED IDEOGRAPH + {0xA7CD, 0x5F64}, //988 #CJK UNIFIED IDEOGRAPH + {0xA7CE, 0x5F62}, //989 #CJK UNIFIED IDEOGRAPH + {0xA7CF, 0x5F77}, //990 #CJK UNIFIED IDEOGRAPH + {0xA7D0, 0x5F79}, //991 #CJK UNIFIED IDEOGRAPH + {0xA7D1, 0x5FD8}, //992 #CJK UNIFIED IDEOGRAPH + {0xA7D2, 0x5FCC}, //993 #CJK UNIFIED IDEOGRAPH + {0xA7D3, 0x5FD7}, //994 #CJK UNIFIED IDEOGRAPH + {0xA7D4, 0x5FCD}, //995 #CJK UNIFIED IDEOGRAPH + {0xA7D5, 0x5FF1}, //996 #CJK UNIFIED IDEOGRAPH + {0xA7D6, 0x5FEB}, //997 #CJK UNIFIED IDEOGRAPH + {0xA7D7, 0x5FF8}, //998 #CJK UNIFIED IDEOGRAPH + {0xA7D8, 0x5FEA}, //999 #CJK UNIFIED IDEOGRAPH + {0xA7D9, 0x6212}, //1000 #CJK UNIFIED IDEOGRAPH + {0xA7DA, 0x6211}, //1001 #CJK UNIFIED IDEOGRAPH + {0xA7DB, 0x6284}, //1002 #CJK UNIFIED IDEOGRAPH + {0xA7DC, 0x6297}, //1003 #CJK UNIFIED IDEOGRAPH + {0xA7DD, 0x6296}, //1004 #CJK UNIFIED IDEOGRAPH + {0xA7DE, 0x6280}, //1005 #CJK UNIFIED IDEOGRAPH + {0xA7DF, 0x6276}, //1006 #CJK UNIFIED IDEOGRAPH + {0xA7E0, 0x6289}, //1007 #CJK UNIFIED IDEOGRAPH + {0xA7E1, 0x626D}, //1008 #CJK UNIFIED IDEOGRAPH + {0xA7E2, 0x628A}, //1009 #CJK UNIFIED IDEOGRAPH + {0xA7E3, 0x627C}, //1010 #CJK UNIFIED IDEOGRAPH + {0xA7E4, 0x627E}, //1011 #CJK UNIFIED IDEOGRAPH + {0xA7E5, 0x6279}, //1012 #CJK UNIFIED IDEOGRAPH + {0xA7E6, 0x6273}, //1013 #CJK UNIFIED IDEOGRAPH + {0xA7E7, 0x6292}, //1014 #CJK UNIFIED IDEOGRAPH + {0xA7E8, 0x626F}, //1015 #CJK UNIFIED IDEOGRAPH + {0xA7E9, 0x6298}, //1016 #CJK UNIFIED IDEOGRAPH + {0xA7EA, 0x626E}, //1017 #CJK UNIFIED IDEOGRAPH + {0xA7EB, 0x6295}, //1018 #CJK UNIFIED IDEOGRAPH + {0xA7EC, 0x6293}, //1019 #CJK UNIFIED IDEOGRAPH + {0xA7ED, 0x6291}, //1020 #CJK UNIFIED IDEOGRAPH + {0xA7EE, 0x6286}, //1021 #CJK UNIFIED IDEOGRAPH + {0xA7EF, 0x6539}, //1022 #CJK UNIFIED IDEOGRAPH + {0xA7F0, 0x653B}, //1023 #CJK UNIFIED IDEOGRAPH + {0xA7F1, 0x6538}, //1024 #CJK UNIFIED IDEOGRAPH + {0xA7F2, 0x65F1}, //1025 #CJK UNIFIED IDEOGRAPH + {0xA7F3, 0x66F4}, //1026 #CJK UNIFIED IDEOGRAPH + {0xA7F4, 0x675F}, //1027 #CJK UNIFIED IDEOGRAPH + {0xA7F5, 0x674E}, //1028 #CJK UNIFIED IDEOGRAPH + {0xA7F6, 0x674F}, //1029 #CJK UNIFIED IDEOGRAPH + {0xA7F7, 0x6750}, //1030 #CJK UNIFIED IDEOGRAPH + {0xA7F8, 0x6751}, //1031 #CJK UNIFIED IDEOGRAPH + {0xA7F9, 0x675C}, //1032 #CJK UNIFIED IDEOGRAPH + {0xA7FA, 0x6756}, //1033 #CJK UNIFIED IDEOGRAPH + {0xA7FB, 0x675E}, //1034 #CJK UNIFIED IDEOGRAPH + {0xA7FC, 0x6749}, //1035 #CJK UNIFIED IDEOGRAPH + {0xA7FD, 0x6746}, //1036 #CJK UNIFIED IDEOGRAPH + {0xA7FE, 0x6760}, //1037 #CJK UNIFIED IDEOGRAPH + {0xA840, 0x6753}, //1038 #CJK UNIFIED IDEOGRAPH + {0xA841, 0x6757}, //1039 #CJK UNIFIED IDEOGRAPH + {0xA842, 0x6B65}, //1040 #CJK UNIFIED IDEOGRAPH + {0xA843, 0x6BCF}, //1041 #CJK UNIFIED IDEOGRAPH + {0xA844, 0x6C42}, //1042 #CJK UNIFIED IDEOGRAPH + {0xA845, 0x6C5E}, //1043 #CJK UNIFIED IDEOGRAPH + {0xA846, 0x6C99}, //1044 #CJK UNIFIED IDEOGRAPH + {0xA847, 0x6C81}, //1045 #CJK UNIFIED IDEOGRAPH + {0xA848, 0x6C88}, //1046 #CJK UNIFIED IDEOGRAPH + {0xA849, 0x6C89}, //1047 #CJK UNIFIED IDEOGRAPH + {0xA84A, 0x6C85}, //1048 #CJK UNIFIED IDEOGRAPH + {0xA84B, 0x6C9B}, //1049 #CJK UNIFIED IDEOGRAPH + {0xA84C, 0x6C6A}, //1050 #CJK UNIFIED IDEOGRAPH + {0xA84D, 0x6C7A}, //1051 #CJK UNIFIED IDEOGRAPH + {0xA84E, 0x6C90}, //1052 #CJK UNIFIED IDEOGRAPH + {0xA84F, 0x6C70}, //1053 #CJK UNIFIED IDEOGRAPH + {0xA850, 0x6C8C}, //1054 #CJK UNIFIED IDEOGRAPH + {0xA851, 0x6C68}, //1055 #CJK UNIFIED IDEOGRAPH + {0xA852, 0x6C96}, //1056 #CJK UNIFIED IDEOGRAPH + {0xA853, 0x6C92}, //1057 #CJK UNIFIED IDEOGRAPH + {0xA854, 0x6C7D}, //1058 #CJK UNIFIED IDEOGRAPH + {0xA855, 0x6C83}, //1059 #CJK UNIFIED IDEOGRAPH + {0xA856, 0x6C72}, //1060 #CJK UNIFIED IDEOGRAPH + {0xA857, 0x6C7E}, //1061 #CJK UNIFIED IDEOGRAPH + {0xA858, 0x6C74}, //1062 #CJK UNIFIED IDEOGRAPH + {0xA859, 0x6C86}, //1063 #CJK UNIFIED IDEOGRAPH + {0xA85A, 0x6C76}, //1064 #CJK UNIFIED IDEOGRAPH + {0xA85B, 0x6C8D}, //1065 #CJK UNIFIED IDEOGRAPH + {0xA85C, 0x6C94}, //1066 #CJK UNIFIED IDEOGRAPH + {0xA85D, 0x6C98}, //1067 #CJK UNIFIED IDEOGRAPH + {0xA85E, 0x6C82}, //1068 #CJK UNIFIED IDEOGRAPH + {0xA85F, 0x7076}, //1069 #CJK UNIFIED IDEOGRAPH + {0xA860, 0x707C}, //1070 #CJK UNIFIED IDEOGRAPH + {0xA861, 0x707D}, //1071 #CJK UNIFIED IDEOGRAPH + {0xA862, 0x7078}, //1072 #CJK UNIFIED IDEOGRAPH + {0xA863, 0x7262}, //1073 #CJK UNIFIED IDEOGRAPH + {0xA864, 0x7261}, //1074 #CJK UNIFIED IDEOGRAPH + {0xA865, 0x7260}, //1075 #CJK UNIFIED IDEOGRAPH + {0xA866, 0x72C4}, //1076 #CJK UNIFIED IDEOGRAPH + {0xA867, 0x72C2}, //1077 #CJK UNIFIED IDEOGRAPH + {0xA868, 0x7396}, //1078 #CJK UNIFIED IDEOGRAPH + {0xA869, 0x752C}, //1079 #CJK UNIFIED IDEOGRAPH + {0xA86A, 0x752B}, //1080 #CJK UNIFIED IDEOGRAPH + {0xA86B, 0x7537}, //1081 #CJK UNIFIED IDEOGRAPH + {0xA86C, 0x7538}, //1082 #CJK UNIFIED IDEOGRAPH + {0xA86D, 0x7682}, //1083 #CJK UNIFIED IDEOGRAPH + {0xA86E, 0x76EF}, //1084 #CJK UNIFIED IDEOGRAPH + {0xA86F, 0x77E3}, //1085 #CJK UNIFIED IDEOGRAPH + {0xA870, 0x79C1}, //1086 #CJK UNIFIED IDEOGRAPH + {0xA871, 0x79C0}, //1087 #CJK UNIFIED IDEOGRAPH + {0xA872, 0x79BF}, //1088 #CJK UNIFIED IDEOGRAPH + {0xA873, 0x7A76}, //1089 #CJK UNIFIED IDEOGRAPH + {0xA874, 0x7CFB}, //1090 #CJK UNIFIED IDEOGRAPH + {0xA875, 0x7F55}, //1091 #CJK UNIFIED IDEOGRAPH + {0xA876, 0x8096}, //1092 #CJK UNIFIED IDEOGRAPH + {0xA877, 0x8093}, //1093 #CJK UNIFIED IDEOGRAPH + {0xA878, 0x809D}, //1094 #CJK UNIFIED IDEOGRAPH + {0xA879, 0x8098}, //1095 #CJK UNIFIED IDEOGRAPH + {0xA87A, 0x809B}, //1096 #CJK UNIFIED IDEOGRAPH + {0xA87B, 0x809A}, //1097 #CJK UNIFIED IDEOGRAPH + {0xA87C, 0x80B2}, //1098 #CJK UNIFIED IDEOGRAPH + {0xA87D, 0x826F}, //1099 #CJK UNIFIED IDEOGRAPH + {0xA87E, 0x8292}, //1100 #CJK UNIFIED IDEOGRAPH + {0xA8A1, 0x828B}, //1101 #CJK UNIFIED IDEOGRAPH + {0xA8A2, 0x828D}, //1102 #CJK UNIFIED IDEOGRAPH + {0xA8A3, 0x898B}, //1103 #CJK UNIFIED IDEOGRAPH + {0xA8A4, 0x89D2}, //1104 #CJK UNIFIED IDEOGRAPH + {0xA8A5, 0x8A00}, //1105 #CJK UNIFIED IDEOGRAPH + {0xA8A6, 0x8C37}, //1106 #CJK UNIFIED IDEOGRAPH + {0xA8A7, 0x8C46}, //1107 #CJK UNIFIED IDEOGRAPH + {0xA8A8, 0x8C55}, //1108 #CJK UNIFIED IDEOGRAPH + {0xA8A9, 0x8C9D}, //1109 #CJK UNIFIED IDEOGRAPH + {0xA8AA, 0x8D64}, //1110 #CJK UNIFIED IDEOGRAPH + {0xA8AB, 0x8D70}, //1111 #CJK UNIFIED IDEOGRAPH + {0xA8AC, 0x8DB3}, //1112 #CJK UNIFIED IDEOGRAPH + {0xA8AD, 0x8EAB}, //1113 #CJK UNIFIED IDEOGRAPH + {0xA8AE, 0x8ECA}, //1114 #CJK UNIFIED IDEOGRAPH + {0xA8AF, 0x8F9B}, //1115 #CJK UNIFIED IDEOGRAPH + {0xA8B0, 0x8FB0}, //1116 #CJK UNIFIED IDEOGRAPH + {0xA8B1, 0x8FC2}, //1117 #CJK UNIFIED IDEOGRAPH + {0xA8B2, 0x8FC6}, //1118 #CJK UNIFIED IDEOGRAPH + {0xA8B3, 0x8FC5}, //1119 #CJK UNIFIED IDEOGRAPH + {0xA8B4, 0x8FC4}, //1120 #CJK UNIFIED IDEOGRAPH + {0xA8B5, 0x5DE1}, //1121 #CJK UNIFIED IDEOGRAPH + {0xA8B6, 0x9091}, //1122 #CJK UNIFIED IDEOGRAPH + {0xA8B7, 0x90A2}, //1123 #CJK UNIFIED IDEOGRAPH + {0xA8B8, 0x90AA}, //1124 #CJK UNIFIED IDEOGRAPH + {0xA8B9, 0x90A6}, //1125 #CJK UNIFIED IDEOGRAPH + {0xA8BA, 0x90A3}, //1126 #CJK UNIFIED IDEOGRAPH + {0xA8BB, 0x9149}, //1127 #CJK UNIFIED IDEOGRAPH + {0xA8BC, 0x91C6}, //1128 #CJK UNIFIED IDEOGRAPH + {0xA8BD, 0x91CC}, //1129 #CJK UNIFIED IDEOGRAPH + {0xA8BE, 0x9632}, //1130 #CJK UNIFIED IDEOGRAPH + {0xA8BF, 0x962E}, //1131 #CJK UNIFIED IDEOGRAPH + {0xA8C0, 0x9631}, //1132 #CJK UNIFIED IDEOGRAPH + {0xA8C1, 0x962A}, //1133 #CJK UNIFIED IDEOGRAPH + {0xA8C2, 0x962C}, //1134 #CJK UNIFIED IDEOGRAPH + {0xA8C3, 0x4E26}, //1135 #CJK UNIFIED IDEOGRAPH + {0xA8C4, 0x4E56}, //1136 #CJK UNIFIED IDEOGRAPH + {0xA8C5, 0x4E73}, //1137 #CJK UNIFIED IDEOGRAPH + {0xA8C6, 0x4E8B}, //1138 #CJK UNIFIED IDEOGRAPH + {0xA8C7, 0x4E9B}, //1139 #CJK UNIFIED IDEOGRAPH + {0xA8C8, 0x4E9E}, //1140 #CJK UNIFIED IDEOGRAPH + {0xA8C9, 0x4EAB}, //1141 #CJK UNIFIED IDEOGRAPH + {0xA8CA, 0x4EAC}, //1142 #CJK UNIFIED IDEOGRAPH + {0xA8CB, 0x4F6F}, //1143 #CJK UNIFIED IDEOGRAPH + {0xA8CC, 0x4F9D}, //1144 #CJK UNIFIED IDEOGRAPH + {0xA8CD, 0x4F8D}, //1145 #CJK UNIFIED IDEOGRAPH + {0xA8CE, 0x4F73}, //1146 #CJK UNIFIED IDEOGRAPH + {0xA8CF, 0x4F7F}, //1147 #CJK UNIFIED IDEOGRAPH + {0xA8D0, 0x4F6C}, //1148 #CJK UNIFIED IDEOGRAPH + {0xA8D1, 0x4F9B}, //1149 #CJK UNIFIED IDEOGRAPH + {0xA8D2, 0x4F8B}, //1150 #CJK UNIFIED IDEOGRAPH + {0xA8D3, 0x4F86}, //1151 #CJK UNIFIED IDEOGRAPH + {0xA8D4, 0x4F83}, //1152 #CJK UNIFIED IDEOGRAPH + {0xA8D5, 0x4F70}, //1153 #CJK UNIFIED IDEOGRAPH + {0xA8D6, 0x4F75}, //1154 #CJK UNIFIED IDEOGRAPH + {0xA8D7, 0x4F88}, //1155 #CJK UNIFIED IDEOGRAPH + {0xA8D8, 0x4F69}, //1156 #CJK UNIFIED IDEOGRAPH + {0xA8D9, 0x4F7B}, //1157 #CJK UNIFIED IDEOGRAPH + {0xA8DA, 0x4F96}, //1158 #CJK UNIFIED IDEOGRAPH + {0xA8DB, 0x4F7E}, //1159 #CJK UNIFIED IDEOGRAPH + {0xA8DC, 0x4F8F}, //1160 #CJK UNIFIED IDEOGRAPH + {0xA8DD, 0x4F91}, //1161 #CJK UNIFIED IDEOGRAPH + {0xA8DE, 0x4F7A}, //1162 #CJK UNIFIED IDEOGRAPH + {0xA8DF, 0x5154}, //1163 #CJK UNIFIED IDEOGRAPH + {0xA8E0, 0x5152}, //1164 #CJK UNIFIED IDEOGRAPH + {0xA8E1, 0x5155}, //1165 #CJK UNIFIED IDEOGRAPH + {0xA8E2, 0x5169}, //1166 #CJK UNIFIED IDEOGRAPH + {0xA8E3, 0x5177}, //1167 #CJK UNIFIED IDEOGRAPH + {0xA8E4, 0x5176}, //1168 #CJK UNIFIED IDEOGRAPH + {0xA8E5, 0x5178}, //1169 #CJK UNIFIED IDEOGRAPH + {0xA8E6, 0x51BD}, //1170 #CJK UNIFIED IDEOGRAPH + {0xA8E7, 0x51FD}, //1171 #CJK UNIFIED IDEOGRAPH + {0xA8E8, 0x523B}, //1172 #CJK UNIFIED IDEOGRAPH + {0xA8E9, 0x5238}, //1173 #CJK UNIFIED IDEOGRAPH + {0xA8EA, 0x5237}, //1174 #CJK UNIFIED IDEOGRAPH + {0xA8EB, 0x523A}, //1175 #CJK UNIFIED IDEOGRAPH + {0xA8EC, 0x5230}, //1176 #CJK UNIFIED IDEOGRAPH + {0xA8ED, 0x522E}, //1177 #CJK UNIFIED IDEOGRAPH + {0xA8EE, 0x5236}, //1178 #CJK UNIFIED IDEOGRAPH + {0xA8EF, 0x5241}, //1179 #CJK UNIFIED IDEOGRAPH + {0xA8F0, 0x52BE}, //1180 #CJK UNIFIED IDEOGRAPH + {0xA8F1, 0x52BB}, //1181 #CJK UNIFIED IDEOGRAPH + {0xA8F2, 0x5352}, //1182 #CJK UNIFIED IDEOGRAPH + {0xA8F3, 0x5354}, //1183 #CJK UNIFIED IDEOGRAPH + {0xA8F4, 0x5353}, //1184 #CJK UNIFIED IDEOGRAPH + {0xA8F5, 0x5351}, //1185 #CJK UNIFIED IDEOGRAPH + {0xA8F6, 0x5366}, //1186 #CJK UNIFIED IDEOGRAPH + {0xA8F7, 0x5377}, //1187 #CJK UNIFIED IDEOGRAPH + {0xA8F8, 0x5378}, //1188 #CJK UNIFIED IDEOGRAPH + {0xA8F9, 0x5379}, //1189 #CJK UNIFIED IDEOGRAPH + {0xA8FA, 0x53D6}, //1190 #CJK UNIFIED IDEOGRAPH + {0xA8FB, 0x53D4}, //1191 #CJK UNIFIED IDEOGRAPH + {0xA8FC, 0x53D7}, //1192 #CJK UNIFIED IDEOGRAPH + {0xA8FD, 0x5473}, //1193 #CJK UNIFIED IDEOGRAPH + {0xA8FE, 0x5475}, //1194 #CJK UNIFIED IDEOGRAPH + {0xA940, 0x5496}, //1195 #CJK UNIFIED IDEOGRAPH + {0xA941, 0x5478}, //1196 #CJK UNIFIED IDEOGRAPH + {0xA942, 0x5495}, //1197 #CJK UNIFIED IDEOGRAPH + {0xA943, 0x5480}, //1198 #CJK UNIFIED IDEOGRAPH + {0xA944, 0x547B}, //1199 #CJK UNIFIED IDEOGRAPH + {0xA945, 0x5477}, //1200 #CJK UNIFIED IDEOGRAPH + {0xA946, 0x5484}, //1201 #CJK UNIFIED IDEOGRAPH + {0xA947, 0x5492}, //1202 #CJK UNIFIED IDEOGRAPH + {0xA948, 0x5486}, //1203 #CJK UNIFIED IDEOGRAPH + {0xA949, 0x547C}, //1204 #CJK UNIFIED IDEOGRAPH + {0xA94A, 0x5490}, //1205 #CJK UNIFIED IDEOGRAPH + {0xA94B, 0x5471}, //1206 #CJK UNIFIED IDEOGRAPH + {0xA94C, 0x5476}, //1207 #CJK UNIFIED IDEOGRAPH + {0xA94D, 0x548C}, //1208 #CJK UNIFIED IDEOGRAPH + {0xA94E, 0x549A}, //1209 #CJK UNIFIED IDEOGRAPH + {0xA94F, 0x5462}, //1210 #CJK UNIFIED IDEOGRAPH + {0xA950, 0x5468}, //1211 #CJK UNIFIED IDEOGRAPH + {0xA951, 0x548B}, //1212 #CJK UNIFIED IDEOGRAPH + {0xA952, 0x547D}, //1213 #CJK UNIFIED IDEOGRAPH + {0xA953, 0x548E}, //1214 #CJK UNIFIED IDEOGRAPH + {0xA954, 0x56FA}, //1215 #CJK UNIFIED IDEOGRAPH + {0xA955, 0x5783}, //1216 #CJK UNIFIED IDEOGRAPH + {0xA956, 0x5777}, //1217 #CJK UNIFIED IDEOGRAPH + {0xA957, 0x576A}, //1218 #CJK UNIFIED IDEOGRAPH + {0xA958, 0x5769}, //1219 #CJK UNIFIED IDEOGRAPH + {0xA959, 0x5761}, //1220 #CJK UNIFIED IDEOGRAPH + {0xA95A, 0x5766}, //1221 #CJK UNIFIED IDEOGRAPH + {0xA95B, 0x5764}, //1222 #CJK UNIFIED IDEOGRAPH + {0xA95C, 0x577C}, //1223 #CJK UNIFIED IDEOGRAPH + {0xA95D, 0x591C}, //1224 #CJK UNIFIED IDEOGRAPH + {0xA95E, 0x5949}, //1225 #CJK UNIFIED IDEOGRAPH + {0xA95F, 0x5947}, //1226 #CJK UNIFIED IDEOGRAPH + {0xA960, 0x5948}, //1227 #CJK UNIFIED IDEOGRAPH + {0xA961, 0x5944}, //1228 #CJK UNIFIED IDEOGRAPH + {0xA962, 0x5954}, //1229 #CJK UNIFIED IDEOGRAPH + {0xA963, 0x59BE}, //1230 #CJK UNIFIED IDEOGRAPH + {0xA964, 0x59BB}, //1231 #CJK UNIFIED IDEOGRAPH + {0xA965, 0x59D4}, //1232 #CJK UNIFIED IDEOGRAPH + {0xA966, 0x59B9}, //1233 #CJK UNIFIED IDEOGRAPH + {0xA967, 0x59AE}, //1234 #CJK UNIFIED IDEOGRAPH + {0xA968, 0x59D1}, //1235 #CJK UNIFIED IDEOGRAPH + {0xA969, 0x59C6}, //1236 #CJK UNIFIED IDEOGRAPH + {0xA96A, 0x59D0}, //1237 #CJK UNIFIED IDEOGRAPH + {0xA96B, 0x59CD}, //1238 #CJK UNIFIED IDEOGRAPH + {0xA96C, 0x59CB}, //1239 #CJK UNIFIED IDEOGRAPH + {0xA96D, 0x59D3}, //1240 #CJK UNIFIED IDEOGRAPH + {0xA96E, 0x59CA}, //1241 #CJK UNIFIED IDEOGRAPH + {0xA96F, 0x59AF}, //1242 #CJK UNIFIED IDEOGRAPH + {0xA970, 0x59B3}, //1243 #CJK UNIFIED IDEOGRAPH + {0xA971, 0x59D2}, //1244 #CJK UNIFIED IDEOGRAPH + {0xA972, 0x59C5}, //1245 #CJK UNIFIED IDEOGRAPH + {0xA973, 0x5B5F}, //1246 #CJK UNIFIED IDEOGRAPH + {0xA974, 0x5B64}, //1247 #CJK UNIFIED IDEOGRAPH + {0xA975, 0x5B63}, //1248 #CJK UNIFIED IDEOGRAPH + {0xA976, 0x5B97}, //1249 #CJK UNIFIED IDEOGRAPH + {0xA977, 0x5B9A}, //1250 #CJK UNIFIED IDEOGRAPH + {0xA978, 0x5B98}, //1251 #CJK UNIFIED IDEOGRAPH + {0xA979, 0x5B9C}, //1252 #CJK UNIFIED IDEOGRAPH + {0xA97A, 0x5B99}, //1253 #CJK UNIFIED IDEOGRAPH + {0xA97B, 0x5B9B}, //1254 #CJK UNIFIED IDEOGRAPH + {0xA97C, 0x5C1A}, //1255 #CJK UNIFIED IDEOGRAPH + {0xA97D, 0x5C48}, //1256 #CJK UNIFIED IDEOGRAPH + {0xA97E, 0x5C45}, //1257 #CJK UNIFIED IDEOGRAPH + {0xA9A1, 0x5C46}, //1258 #CJK UNIFIED IDEOGRAPH + {0xA9A2, 0x5CB7}, //1259 #CJK UNIFIED IDEOGRAPH + {0xA9A3, 0x5CA1}, //1260 #CJK UNIFIED IDEOGRAPH + {0xA9A4, 0x5CB8}, //1261 #CJK UNIFIED IDEOGRAPH + {0xA9A5, 0x5CA9}, //1262 #CJK UNIFIED IDEOGRAPH + {0xA9A6, 0x5CAB}, //1263 #CJK UNIFIED IDEOGRAPH + {0xA9A7, 0x5CB1}, //1264 #CJK UNIFIED IDEOGRAPH + {0xA9A8, 0x5CB3}, //1265 #CJK UNIFIED IDEOGRAPH + {0xA9A9, 0x5E18}, //1266 #CJK UNIFIED IDEOGRAPH + {0xA9AA, 0x5E1A}, //1267 #CJK UNIFIED IDEOGRAPH + {0xA9AB, 0x5E16}, //1268 #CJK UNIFIED IDEOGRAPH + {0xA9AC, 0x5E15}, //1269 #CJK UNIFIED IDEOGRAPH + {0xA9AD, 0x5E1B}, //1270 #CJK UNIFIED IDEOGRAPH + {0xA9AE, 0x5E11}, //1271 #CJK UNIFIED IDEOGRAPH + {0xA9AF, 0x5E78}, //1272 #CJK UNIFIED IDEOGRAPH + {0xA9B0, 0x5E9A}, //1273 #CJK UNIFIED IDEOGRAPH + {0xA9B1, 0x5E97}, //1274 #CJK UNIFIED IDEOGRAPH + {0xA9B2, 0x5E9C}, //1275 #CJK UNIFIED IDEOGRAPH + {0xA9B3, 0x5E95}, //1276 #CJK UNIFIED IDEOGRAPH + {0xA9B4, 0x5E96}, //1277 #CJK UNIFIED IDEOGRAPH + {0xA9B5, 0x5EF6}, //1278 #CJK UNIFIED IDEOGRAPH + {0xA9B6, 0x5F26}, //1279 #CJK UNIFIED IDEOGRAPH + {0xA9B7, 0x5F27}, //1280 #CJK UNIFIED IDEOGRAPH + {0xA9B8, 0x5F29}, //1281 #CJK UNIFIED IDEOGRAPH + {0xA9B9, 0x5F80}, //1282 #CJK UNIFIED IDEOGRAPH + {0xA9BA, 0x5F81}, //1283 #CJK UNIFIED IDEOGRAPH + {0xA9BB, 0x5F7F}, //1284 #CJK UNIFIED IDEOGRAPH + {0xA9BC, 0x5F7C}, //1285 #CJK UNIFIED IDEOGRAPH + {0xA9BD, 0x5FDD}, //1286 #CJK UNIFIED IDEOGRAPH + {0xA9BE, 0x5FE0}, //1287 #CJK UNIFIED IDEOGRAPH + {0xA9BF, 0x5FFD}, //1288 #CJK UNIFIED IDEOGRAPH + {0xA9C0, 0x5FF5}, //1289 #CJK UNIFIED IDEOGRAPH + {0xA9C1, 0x5FFF}, //1290 #CJK UNIFIED IDEOGRAPH + {0xA9C2, 0x600F}, //1291 #CJK UNIFIED IDEOGRAPH + {0xA9C3, 0x6014}, //1292 #CJK UNIFIED IDEOGRAPH + {0xA9C4, 0x602F}, //1293 #CJK UNIFIED IDEOGRAPH + {0xA9C5, 0x6035}, //1294 #CJK UNIFIED IDEOGRAPH + {0xA9C6, 0x6016}, //1295 #CJK UNIFIED IDEOGRAPH + {0xA9C7, 0x602A}, //1296 #CJK UNIFIED IDEOGRAPH + {0xA9C8, 0x6015}, //1297 #CJK UNIFIED IDEOGRAPH + {0xA9C9, 0x6021}, //1298 #CJK UNIFIED IDEOGRAPH + {0xA9CA, 0x6027}, //1299 #CJK UNIFIED IDEOGRAPH + {0xA9CB, 0x6029}, //1300 #CJK UNIFIED IDEOGRAPH + {0xA9CC, 0x602B}, //1301 #CJK UNIFIED IDEOGRAPH + {0xA9CD, 0x601B}, //1302 #CJK UNIFIED IDEOGRAPH + {0xA9CE, 0x6216}, //1303 #CJK UNIFIED IDEOGRAPH + {0xA9CF, 0x6215}, //1304 #CJK UNIFIED IDEOGRAPH + {0xA9D0, 0x623F}, //1305 #CJK UNIFIED IDEOGRAPH + {0xA9D1, 0x623E}, //1306 #CJK UNIFIED IDEOGRAPH + {0xA9D2, 0x6240}, //1307 #CJK UNIFIED IDEOGRAPH + {0xA9D3, 0x627F}, //1308 #CJK UNIFIED IDEOGRAPH + {0xA9D4, 0x62C9}, //1309 #CJK UNIFIED IDEOGRAPH + {0xA9D5, 0x62CC}, //1310 #CJK UNIFIED IDEOGRAPH + {0xA9D6, 0x62C4}, //1311 #CJK UNIFIED IDEOGRAPH + {0xA9D7, 0x62BF}, //1312 #CJK UNIFIED IDEOGRAPH + {0xA9D8, 0x62C2}, //1313 #CJK UNIFIED IDEOGRAPH + {0xA9D9, 0x62B9}, //1314 #CJK UNIFIED IDEOGRAPH + {0xA9DA, 0x62D2}, //1315 #CJK UNIFIED IDEOGRAPH + {0xA9DB, 0x62DB}, //1316 #CJK UNIFIED IDEOGRAPH + {0xA9DC, 0x62AB}, //1317 #CJK UNIFIED IDEOGRAPH + {0xA9DD, 0x62D3}, //1318 #CJK UNIFIED IDEOGRAPH + {0xA9DE, 0x62D4}, //1319 #CJK UNIFIED IDEOGRAPH + {0xA9DF, 0x62CB}, //1320 #CJK UNIFIED IDEOGRAPH + {0xA9E0, 0x62C8}, //1321 #CJK UNIFIED IDEOGRAPH + {0xA9E1, 0x62A8}, //1322 #CJK UNIFIED IDEOGRAPH + {0xA9E2, 0x62BD}, //1323 #CJK UNIFIED IDEOGRAPH + {0xA9E3, 0x62BC}, //1324 #CJK UNIFIED IDEOGRAPH + {0xA9E4, 0x62D0}, //1325 #CJK UNIFIED IDEOGRAPH + {0xA9E5, 0x62D9}, //1326 #CJK UNIFIED IDEOGRAPH + {0xA9E6, 0x62C7}, //1327 #CJK UNIFIED IDEOGRAPH + {0xA9E7, 0x62CD}, //1328 #CJK UNIFIED IDEOGRAPH + {0xA9E8, 0x62B5}, //1329 #CJK UNIFIED IDEOGRAPH + {0xA9E9, 0x62DA}, //1330 #CJK UNIFIED IDEOGRAPH + {0xA9EA, 0x62B1}, //1331 #CJK UNIFIED IDEOGRAPH + {0xA9EB, 0x62D8}, //1332 #CJK UNIFIED IDEOGRAPH + {0xA9EC, 0x62D6}, //1333 #CJK UNIFIED IDEOGRAPH + {0xA9ED, 0x62D7}, //1334 #CJK UNIFIED IDEOGRAPH + {0xA9EE, 0x62C6}, //1335 #CJK UNIFIED IDEOGRAPH + {0xA9EF, 0x62AC}, //1336 #CJK UNIFIED IDEOGRAPH + {0xA9F0, 0x62CE}, //1337 #CJK UNIFIED IDEOGRAPH + {0xA9F1, 0x653E}, //1338 #CJK UNIFIED IDEOGRAPH + {0xA9F2, 0x65A7}, //1339 #CJK UNIFIED IDEOGRAPH + {0xA9F3, 0x65BC}, //1340 #CJK UNIFIED IDEOGRAPH + {0xA9F4, 0x65FA}, //1341 #CJK UNIFIED IDEOGRAPH + {0xA9F5, 0x6614}, //1342 #CJK UNIFIED IDEOGRAPH + {0xA9F6, 0x6613}, //1343 #CJK UNIFIED IDEOGRAPH + {0xA9F7, 0x660C}, //1344 #CJK UNIFIED IDEOGRAPH + {0xA9F8, 0x6606}, //1345 #CJK UNIFIED IDEOGRAPH + {0xA9F9, 0x6602}, //1346 #CJK UNIFIED IDEOGRAPH + {0xA9FA, 0x660E}, //1347 #CJK UNIFIED IDEOGRAPH + {0xA9FB, 0x6600}, //1348 #CJK UNIFIED IDEOGRAPH + {0xA9FC, 0x660F}, //1349 #CJK UNIFIED IDEOGRAPH + {0xA9FD, 0x6615}, //1350 #CJK UNIFIED IDEOGRAPH + {0xA9FE, 0x660A}, //1351 #CJK UNIFIED IDEOGRAPH + {0xAA40, 0x6607}, //1352 #CJK UNIFIED IDEOGRAPH + {0xAA41, 0x670D}, //1353 #CJK UNIFIED IDEOGRAPH + {0xAA42, 0x670B}, //1354 #CJK UNIFIED IDEOGRAPH + {0xAA43, 0x676D}, //1355 #CJK UNIFIED IDEOGRAPH + {0xAA44, 0x678B}, //1356 #CJK UNIFIED IDEOGRAPH + {0xAA45, 0x6795}, //1357 #CJK UNIFIED IDEOGRAPH + {0xAA46, 0x6771}, //1358 #CJK UNIFIED IDEOGRAPH + {0xAA47, 0x679C}, //1359 #CJK UNIFIED IDEOGRAPH + {0xAA48, 0x6773}, //1360 #CJK UNIFIED IDEOGRAPH + {0xAA49, 0x6777}, //1361 #CJK UNIFIED IDEOGRAPH + {0xAA4A, 0x6787}, //1362 #CJK UNIFIED IDEOGRAPH + {0xAA4B, 0x679D}, //1363 #CJK UNIFIED IDEOGRAPH + {0xAA4C, 0x6797}, //1364 #CJK UNIFIED IDEOGRAPH + {0xAA4D, 0x676F}, //1365 #CJK UNIFIED IDEOGRAPH + {0xAA4E, 0x6770}, //1366 #CJK UNIFIED IDEOGRAPH + {0xAA4F, 0x677F}, //1367 #CJK UNIFIED IDEOGRAPH + {0xAA50, 0x6789}, //1368 #CJK UNIFIED IDEOGRAPH + {0xAA51, 0x677E}, //1369 #CJK UNIFIED IDEOGRAPH + {0xAA52, 0x6790}, //1370 #CJK UNIFIED IDEOGRAPH + {0xAA53, 0x6775}, //1371 #CJK UNIFIED IDEOGRAPH + {0xAA54, 0x679A}, //1372 #CJK UNIFIED IDEOGRAPH + {0xAA55, 0x6793}, //1373 #CJK UNIFIED IDEOGRAPH + {0xAA56, 0x677C}, //1374 #CJK UNIFIED IDEOGRAPH + {0xAA57, 0x676A}, //1375 #CJK UNIFIED IDEOGRAPH + {0xAA58, 0x6772}, //1376 #CJK UNIFIED IDEOGRAPH + {0xAA59, 0x6B23}, //1377 #CJK UNIFIED IDEOGRAPH + {0xAA5A, 0x6B66}, //1378 #CJK UNIFIED IDEOGRAPH + {0xAA5B, 0x6B67}, //1379 #CJK UNIFIED IDEOGRAPH + {0xAA5C, 0x6B7F}, //1380 #CJK UNIFIED IDEOGRAPH + {0xAA5D, 0x6C13}, //1381 #CJK UNIFIED IDEOGRAPH + {0xAA5E, 0x6C1B}, //1382 #CJK UNIFIED IDEOGRAPH + {0xAA5F, 0x6CE3}, //1383 #CJK UNIFIED IDEOGRAPH + {0xAA60, 0x6CE8}, //1384 #CJK UNIFIED IDEOGRAPH + {0xAA61, 0x6CF3}, //1385 #CJK UNIFIED IDEOGRAPH + {0xAA62, 0x6CB1}, //1386 #CJK UNIFIED IDEOGRAPH + {0xAA63, 0x6CCC}, //1387 #CJK UNIFIED IDEOGRAPH + {0xAA64, 0x6CE5}, //1388 #CJK UNIFIED IDEOGRAPH + {0xAA65, 0x6CB3}, //1389 #CJK UNIFIED IDEOGRAPH + {0xAA66, 0x6CBD}, //1390 #CJK UNIFIED IDEOGRAPH + {0xAA67, 0x6CBE}, //1391 #CJK UNIFIED IDEOGRAPH + {0xAA68, 0x6CBC}, //1392 #CJK UNIFIED IDEOGRAPH + {0xAA69, 0x6CE2}, //1393 #CJK UNIFIED IDEOGRAPH + {0xAA6A, 0x6CAB}, //1394 #CJK UNIFIED IDEOGRAPH + {0xAA6B, 0x6CD5}, //1395 #CJK UNIFIED IDEOGRAPH + {0xAA6C, 0x6CD3}, //1396 #CJK UNIFIED IDEOGRAPH + {0xAA6D, 0x6CB8}, //1397 #CJK UNIFIED IDEOGRAPH + {0xAA6E, 0x6CC4}, //1398 #CJK UNIFIED IDEOGRAPH + {0xAA6F, 0x6CB9}, //1399 #CJK UNIFIED IDEOGRAPH + {0xAA70, 0x6CC1}, //1400 #CJK UNIFIED IDEOGRAPH + {0xAA71, 0x6CAE}, //1401 #CJK UNIFIED IDEOGRAPH + {0xAA72, 0x6CD7}, //1402 #CJK UNIFIED IDEOGRAPH + {0xAA73, 0x6CC5}, //1403 #CJK UNIFIED IDEOGRAPH + {0xAA74, 0x6CF1}, //1404 #CJK UNIFIED IDEOGRAPH + {0xAA75, 0x6CBF}, //1405 #CJK UNIFIED IDEOGRAPH + {0xAA76, 0x6CBB}, //1406 #CJK UNIFIED IDEOGRAPH + {0xAA77, 0x6CE1}, //1407 #CJK UNIFIED IDEOGRAPH + {0xAA78, 0x6CDB}, //1408 #CJK UNIFIED IDEOGRAPH + {0xAA79, 0x6CCA}, //1409 #CJK UNIFIED IDEOGRAPH + {0xAA7A, 0x6CAC}, //1410 #CJK UNIFIED IDEOGRAPH + {0xAA7B, 0x6CEF}, //1411 #CJK UNIFIED IDEOGRAPH + {0xAA7C, 0x6CDC}, //1412 #CJK UNIFIED IDEOGRAPH + {0xAA7D, 0x6CD6}, //1413 #CJK UNIFIED IDEOGRAPH + {0xAA7E, 0x6CE0}, //1414 #CJK UNIFIED IDEOGRAPH + {0xAAA1, 0x7095}, //1415 #CJK UNIFIED IDEOGRAPH + {0xAAA2, 0x708E}, //1416 #CJK UNIFIED IDEOGRAPH + {0xAAA3, 0x7092}, //1417 #CJK UNIFIED IDEOGRAPH + {0xAAA4, 0x708A}, //1418 #CJK UNIFIED IDEOGRAPH + {0xAAA5, 0x7099}, //1419 #CJK UNIFIED IDEOGRAPH + {0xAAA6, 0x722C}, //1420 #CJK UNIFIED IDEOGRAPH + {0xAAA7, 0x722D}, //1421 #CJK UNIFIED IDEOGRAPH + {0xAAA8, 0x7238}, //1422 #CJK UNIFIED IDEOGRAPH + {0xAAA9, 0x7248}, //1423 #CJK UNIFIED IDEOGRAPH + {0xAAAA, 0x7267}, //1424 #CJK UNIFIED IDEOGRAPH + {0xAAAB, 0x7269}, //1425 #CJK UNIFIED IDEOGRAPH + {0xAAAC, 0x72C0}, //1426 #CJK UNIFIED IDEOGRAPH + {0xAAAD, 0x72CE}, //1427 #CJK UNIFIED IDEOGRAPH + {0xAAAE, 0x72D9}, //1428 #CJK UNIFIED IDEOGRAPH + {0xAAAF, 0x72D7}, //1429 #CJK UNIFIED IDEOGRAPH + {0xAAB0, 0x72D0}, //1430 #CJK UNIFIED IDEOGRAPH + {0xAAB1, 0x73A9}, //1431 #CJK UNIFIED IDEOGRAPH + {0xAAB2, 0x73A8}, //1432 #CJK UNIFIED IDEOGRAPH + {0xAAB3, 0x739F}, //1433 #CJK UNIFIED IDEOGRAPH + {0xAAB4, 0x73AB}, //1434 #CJK UNIFIED IDEOGRAPH + {0xAAB5, 0x73A5}, //1435 #CJK UNIFIED IDEOGRAPH + {0xAAB6, 0x753D}, //1436 #CJK UNIFIED IDEOGRAPH + {0xAAB7, 0x759D}, //1437 #CJK UNIFIED IDEOGRAPH + {0xAAB8, 0x7599}, //1438 #CJK UNIFIED IDEOGRAPH + {0xAAB9, 0x759A}, //1439 #CJK UNIFIED IDEOGRAPH + {0xAABA, 0x7684}, //1440 #CJK UNIFIED IDEOGRAPH + {0xAABB, 0x76C2}, //1441 #CJK UNIFIED IDEOGRAPH + {0xAABC, 0x76F2}, //1442 #CJK UNIFIED IDEOGRAPH + {0xAABD, 0x76F4}, //1443 #CJK UNIFIED IDEOGRAPH + {0xAABE, 0x77E5}, //1444 #CJK UNIFIED IDEOGRAPH + {0xAABF, 0x77FD}, //1445 #CJK UNIFIED IDEOGRAPH + {0xAAC0, 0x793E}, //1446 #CJK UNIFIED IDEOGRAPH + {0xAAC1, 0x7940}, //1447 #CJK UNIFIED IDEOGRAPH + {0xAAC2, 0x7941}, //1448 #CJK UNIFIED IDEOGRAPH + {0xAAC3, 0x79C9}, //1449 #CJK UNIFIED IDEOGRAPH + {0xAAC4, 0x79C8}, //1450 #CJK UNIFIED IDEOGRAPH + {0xAAC5, 0x7A7A}, //1451 #CJK UNIFIED IDEOGRAPH + {0xAAC6, 0x7A79}, //1452 #CJK UNIFIED IDEOGRAPH + {0xAAC7, 0x7AFA}, //1453 #CJK UNIFIED IDEOGRAPH + {0xAAC8, 0x7CFE}, //1454 #CJK UNIFIED IDEOGRAPH + {0xAAC9, 0x7F54}, //1455 #CJK UNIFIED IDEOGRAPH + {0xAACA, 0x7F8C}, //1456 #CJK UNIFIED IDEOGRAPH + {0xAACB, 0x7F8B}, //1457 #CJK UNIFIED IDEOGRAPH + {0xAACC, 0x8005}, //1458 #CJK UNIFIED IDEOGRAPH + {0xAACD, 0x80BA}, //1459 #CJK UNIFIED IDEOGRAPH + {0xAACE, 0x80A5}, //1460 #CJK UNIFIED IDEOGRAPH + {0xAACF, 0x80A2}, //1461 #CJK UNIFIED IDEOGRAPH + {0xAAD0, 0x80B1}, //1462 #CJK UNIFIED IDEOGRAPH + {0xAAD1, 0x80A1}, //1463 #CJK UNIFIED IDEOGRAPH + {0xAAD2, 0x80AB}, //1464 #CJK UNIFIED IDEOGRAPH + {0xAAD3, 0x80A9}, //1465 #CJK UNIFIED IDEOGRAPH + {0xAAD4, 0x80B4}, //1466 #CJK UNIFIED IDEOGRAPH + {0xAAD5, 0x80AA}, //1467 #CJK UNIFIED IDEOGRAPH + {0xAAD6, 0x80AF}, //1468 #CJK UNIFIED IDEOGRAPH + {0xAAD7, 0x81E5}, //1469 #CJK UNIFIED IDEOGRAPH + {0xAAD8, 0x81FE}, //1470 #CJK UNIFIED IDEOGRAPH + {0xAAD9, 0x820D}, //1471 #CJK UNIFIED IDEOGRAPH + {0xAADA, 0x82B3}, //1472 #CJK UNIFIED IDEOGRAPH + {0xAADB, 0x829D}, //1473 #CJK UNIFIED IDEOGRAPH + {0xAADC, 0x8299}, //1474 #CJK UNIFIED IDEOGRAPH + {0xAADD, 0x82AD}, //1475 #CJK UNIFIED IDEOGRAPH + {0xAADE, 0x82BD}, //1476 #CJK UNIFIED IDEOGRAPH + {0xAADF, 0x829F}, //1477 #CJK UNIFIED IDEOGRAPH + {0xAAE0, 0x82B9}, //1478 #CJK UNIFIED IDEOGRAPH + {0xAAE1, 0x82B1}, //1479 #CJK UNIFIED IDEOGRAPH + {0xAAE2, 0x82AC}, //1480 #CJK UNIFIED IDEOGRAPH + {0xAAE3, 0x82A5}, //1481 #CJK UNIFIED IDEOGRAPH + {0xAAE4, 0x82AF}, //1482 #CJK UNIFIED IDEOGRAPH + {0xAAE5, 0x82B8}, //1483 #CJK UNIFIED IDEOGRAPH + {0xAAE6, 0x82A3}, //1484 #CJK UNIFIED IDEOGRAPH + {0xAAE7, 0x82B0}, //1485 #CJK UNIFIED IDEOGRAPH + {0xAAE8, 0x82BE}, //1486 #CJK UNIFIED IDEOGRAPH + {0xAAE9, 0x82B7}, //1487 #CJK UNIFIED IDEOGRAPH + {0xAAEA, 0x864E}, //1488 #CJK UNIFIED IDEOGRAPH + {0xAAEB, 0x8671}, //1489 #CJK UNIFIED IDEOGRAPH + {0xAAEC, 0x521D}, //1490 #CJK UNIFIED IDEOGRAPH + {0xAAED, 0x8868}, //1491 #CJK UNIFIED IDEOGRAPH + {0xAAEE, 0x8ECB}, //1492 #CJK UNIFIED IDEOGRAPH + {0xAAEF, 0x8FCE}, //1493 #CJK UNIFIED IDEOGRAPH + {0xAAF0, 0x8FD4}, //1494 #CJK UNIFIED IDEOGRAPH + {0xAAF1, 0x8FD1}, //1495 #CJK UNIFIED IDEOGRAPH + {0xAAF2, 0x90B5}, //1496 #CJK UNIFIED IDEOGRAPH + {0xAAF3, 0x90B8}, //1497 #CJK UNIFIED IDEOGRAPH + {0xAAF4, 0x90B1}, //1498 #CJK UNIFIED IDEOGRAPH + {0xAAF5, 0x90B6}, //1499 #CJK UNIFIED IDEOGRAPH + {0xAAF6, 0x91C7}, //1500 #CJK UNIFIED IDEOGRAPH + {0xAAF7, 0x91D1}, //1501 #CJK UNIFIED IDEOGRAPH + {0xAAF8, 0x9577}, //1502 #CJK UNIFIED IDEOGRAPH + {0xAAF9, 0x9580}, //1503 #CJK UNIFIED IDEOGRAPH + {0xAAFA, 0x961C}, //1504 #CJK UNIFIED IDEOGRAPH + {0xAAFB, 0x9640}, //1505 #CJK UNIFIED IDEOGRAPH + {0xAAFC, 0x963F}, //1506 #CJK UNIFIED IDEOGRAPH + {0xAAFD, 0x963B}, //1507 #CJK UNIFIED IDEOGRAPH + {0xAAFE, 0x9644}, //1508 #CJK UNIFIED IDEOGRAPH + {0xAB40, 0x9642}, //1509 #CJK UNIFIED IDEOGRAPH + {0xAB41, 0x96B9}, //1510 #CJK UNIFIED IDEOGRAPH + {0xAB42, 0x96E8}, //1511 #CJK UNIFIED IDEOGRAPH + {0xAB43, 0x9752}, //1512 #CJK UNIFIED IDEOGRAPH + {0xAB44, 0x975E}, //1513 #CJK UNIFIED IDEOGRAPH + {0xAB45, 0x4E9F}, //1514 #CJK UNIFIED IDEOGRAPH + {0xAB46, 0x4EAD}, //1515 #CJK UNIFIED IDEOGRAPH + {0xAB47, 0x4EAE}, //1516 #CJK UNIFIED IDEOGRAPH + {0xAB48, 0x4FE1}, //1517 #CJK UNIFIED IDEOGRAPH + {0xAB49, 0x4FB5}, //1518 #CJK UNIFIED IDEOGRAPH + {0xAB4A, 0x4FAF}, //1519 #CJK UNIFIED IDEOGRAPH + {0xAB4B, 0x4FBF}, //1520 #CJK UNIFIED IDEOGRAPH + {0xAB4C, 0x4FE0}, //1521 #CJK UNIFIED IDEOGRAPH + {0xAB4D, 0x4FD1}, //1522 #CJK UNIFIED IDEOGRAPH + {0xAB4E, 0x4FCF}, //1523 #CJK UNIFIED IDEOGRAPH + {0xAB4F, 0x4FDD}, //1524 #CJK UNIFIED IDEOGRAPH + {0xAB50, 0x4FC3}, //1525 #CJK UNIFIED IDEOGRAPH + {0xAB51, 0x4FB6}, //1526 #CJK UNIFIED IDEOGRAPH + {0xAB52, 0x4FD8}, //1527 #CJK UNIFIED IDEOGRAPH + {0xAB53, 0x4FDF}, //1528 #CJK UNIFIED IDEOGRAPH + {0xAB54, 0x4FCA}, //1529 #CJK UNIFIED IDEOGRAPH + {0xAB55, 0x4FD7}, //1530 #CJK UNIFIED IDEOGRAPH + {0xAB56, 0x4FAE}, //1531 #CJK UNIFIED IDEOGRAPH + {0xAB57, 0x4FD0}, //1532 #CJK UNIFIED IDEOGRAPH + {0xAB58, 0x4FC4}, //1533 #CJK UNIFIED IDEOGRAPH + {0xAB59, 0x4FC2}, //1534 #CJK UNIFIED IDEOGRAPH + {0xAB5A, 0x4FDA}, //1535 #CJK UNIFIED IDEOGRAPH + {0xAB5B, 0x4FCE}, //1536 #CJK UNIFIED IDEOGRAPH + {0xAB5C, 0x4FDE}, //1537 #CJK UNIFIED IDEOGRAPH + {0xAB5D, 0x4FB7}, //1538 #CJK UNIFIED IDEOGRAPH + {0xAB5E, 0x5157}, //1539 #CJK UNIFIED IDEOGRAPH + {0xAB5F, 0x5192}, //1540 #CJK UNIFIED IDEOGRAPH + {0xAB60, 0x5191}, //1541 #CJK UNIFIED IDEOGRAPH + {0xAB61, 0x51A0}, //1542 #CJK UNIFIED IDEOGRAPH + {0xAB62, 0x524E}, //1543 #CJK UNIFIED IDEOGRAPH + {0xAB63, 0x5243}, //1544 #CJK UNIFIED IDEOGRAPH + {0xAB64, 0x524A}, //1545 #CJK UNIFIED IDEOGRAPH + {0xAB65, 0x524D}, //1546 #CJK UNIFIED IDEOGRAPH + {0xAB66, 0x524C}, //1547 #CJK UNIFIED IDEOGRAPH + {0xAB67, 0x524B}, //1548 #CJK UNIFIED IDEOGRAPH + {0xAB68, 0x5247}, //1549 #CJK UNIFIED IDEOGRAPH + {0xAB69, 0x52C7}, //1550 #CJK UNIFIED IDEOGRAPH + {0xAB6A, 0x52C9}, //1551 #CJK UNIFIED IDEOGRAPH + {0xAB6B, 0x52C3}, //1552 #CJK UNIFIED IDEOGRAPH + {0xAB6C, 0x52C1}, //1553 #CJK UNIFIED IDEOGRAPH + {0xAB6D, 0x530D}, //1554 #CJK UNIFIED IDEOGRAPH + {0xAB6E, 0x5357}, //1555 #CJK UNIFIED IDEOGRAPH + {0xAB6F, 0x537B}, //1556 #CJK UNIFIED IDEOGRAPH + {0xAB70, 0x539A}, //1557 #CJK UNIFIED IDEOGRAPH + {0xAB71, 0x53DB}, //1558 #CJK UNIFIED IDEOGRAPH + {0xAB72, 0x54AC}, //1559 #CJK UNIFIED IDEOGRAPH + {0xAB73, 0x54C0}, //1560 #CJK UNIFIED IDEOGRAPH + {0xAB74, 0x54A8}, //1561 #CJK UNIFIED IDEOGRAPH + {0xAB75, 0x54CE}, //1562 #CJK UNIFIED IDEOGRAPH + {0xAB76, 0x54C9}, //1563 #CJK UNIFIED IDEOGRAPH + {0xAB77, 0x54B8}, //1564 #CJK UNIFIED IDEOGRAPH + {0xAB78, 0x54A6}, //1565 #CJK UNIFIED IDEOGRAPH + {0xAB79, 0x54B3}, //1566 #CJK UNIFIED IDEOGRAPH + {0xAB7A, 0x54C7}, //1567 #CJK UNIFIED IDEOGRAPH + {0xAB7B, 0x54C2}, //1568 #CJK UNIFIED IDEOGRAPH + {0xAB7C, 0x54BD}, //1569 #CJK UNIFIED IDEOGRAPH + {0xAB7D, 0x54AA}, //1570 #CJK UNIFIED IDEOGRAPH + {0xAB7E, 0x54C1}, //1571 #CJK UNIFIED IDEOGRAPH + {0xABA1, 0x54C4}, //1572 #CJK UNIFIED IDEOGRAPH + {0xABA2, 0x54C8}, //1573 #CJK UNIFIED IDEOGRAPH + {0xABA3, 0x54AF}, //1574 #CJK UNIFIED IDEOGRAPH + {0xABA4, 0x54AB}, //1575 #CJK UNIFIED IDEOGRAPH + {0xABA5, 0x54B1}, //1576 #CJK UNIFIED IDEOGRAPH + {0xABA6, 0x54BB}, //1577 #CJK UNIFIED IDEOGRAPH + {0xABA7, 0x54A9}, //1578 #CJK UNIFIED IDEOGRAPH + {0xABA8, 0x54A7}, //1579 #CJK UNIFIED IDEOGRAPH + {0xABA9, 0x54BF}, //1580 #CJK UNIFIED IDEOGRAPH + {0xABAA, 0x56FF}, //1581 #CJK UNIFIED IDEOGRAPH + {0xABAB, 0x5782}, //1582 #CJK UNIFIED IDEOGRAPH + {0xABAC, 0x578B}, //1583 #CJK UNIFIED IDEOGRAPH + {0xABAD, 0x57A0}, //1584 #CJK UNIFIED IDEOGRAPH + {0xABAE, 0x57A3}, //1585 #CJK UNIFIED IDEOGRAPH + {0xABAF, 0x57A2}, //1586 #CJK UNIFIED IDEOGRAPH + {0xABB0, 0x57CE}, //1587 #CJK UNIFIED IDEOGRAPH + {0xABB1, 0x57AE}, //1588 #CJK UNIFIED IDEOGRAPH + {0xABB2, 0x5793}, //1589 #CJK UNIFIED IDEOGRAPH + {0xABB3, 0x5955}, //1590 #CJK UNIFIED IDEOGRAPH + {0xABB4, 0x5951}, //1591 #CJK UNIFIED IDEOGRAPH + {0xABB5, 0x594F}, //1592 #CJK UNIFIED IDEOGRAPH + {0xABB6, 0x594E}, //1593 #CJK UNIFIED IDEOGRAPH + {0xABB7, 0x5950}, //1594 #CJK UNIFIED IDEOGRAPH + {0xABB8, 0x59DC}, //1595 #CJK UNIFIED IDEOGRAPH + {0xABB9, 0x59D8}, //1596 #CJK UNIFIED IDEOGRAPH + {0xABBA, 0x59FF}, //1597 #CJK UNIFIED IDEOGRAPH + {0xABBB, 0x59E3}, //1598 #CJK UNIFIED IDEOGRAPH + {0xABBC, 0x59E8}, //1599 #CJK UNIFIED IDEOGRAPH + {0xABBD, 0x5A03}, //1600 #CJK UNIFIED IDEOGRAPH + {0xABBE, 0x59E5}, //1601 #CJK UNIFIED IDEOGRAPH + {0xABBF, 0x59EA}, //1602 #CJK UNIFIED IDEOGRAPH + {0xABC0, 0x59DA}, //1603 #CJK UNIFIED IDEOGRAPH + {0xABC1, 0x59E6}, //1604 #CJK UNIFIED IDEOGRAPH + {0xABC2, 0x5A01}, //1605 #CJK UNIFIED IDEOGRAPH + {0xABC3, 0x59FB}, //1606 #CJK UNIFIED IDEOGRAPH + {0xABC4, 0x5B69}, //1607 #CJK UNIFIED IDEOGRAPH + {0xABC5, 0x5BA3}, //1608 #CJK UNIFIED IDEOGRAPH + {0xABC6, 0x5BA6}, //1609 #CJK UNIFIED IDEOGRAPH + {0xABC7, 0x5BA4}, //1610 #CJK UNIFIED IDEOGRAPH + {0xABC8, 0x5BA2}, //1611 #CJK UNIFIED IDEOGRAPH + {0xABC9, 0x5BA5}, //1612 #CJK UNIFIED IDEOGRAPH + {0xABCA, 0x5C01}, //1613 #CJK UNIFIED IDEOGRAPH + {0xABCB, 0x5C4E}, //1614 #CJK UNIFIED IDEOGRAPH + {0xABCC, 0x5C4F}, //1615 #CJK UNIFIED IDEOGRAPH + {0xABCD, 0x5C4D}, //1616 #CJK UNIFIED IDEOGRAPH + {0xABCE, 0x5C4B}, //1617 #CJK UNIFIED IDEOGRAPH + {0xABCF, 0x5CD9}, //1618 #CJK UNIFIED IDEOGRAPH + {0xABD0, 0x5CD2}, //1619 #CJK UNIFIED IDEOGRAPH + {0xABD1, 0x5DF7}, //1620 #CJK UNIFIED IDEOGRAPH + {0xABD2, 0x5E1D}, //1621 #CJK UNIFIED IDEOGRAPH + {0xABD3, 0x5E25}, //1622 #CJK UNIFIED IDEOGRAPH + {0xABD4, 0x5E1F}, //1623 #CJK UNIFIED IDEOGRAPH + {0xABD5, 0x5E7D}, //1624 #CJK UNIFIED IDEOGRAPH + {0xABD6, 0x5EA0}, //1625 #CJK UNIFIED IDEOGRAPH + {0xABD7, 0x5EA6}, //1626 #CJK UNIFIED IDEOGRAPH + {0xABD8, 0x5EFA}, //1627 #CJK UNIFIED IDEOGRAPH + {0xABD9, 0x5F08}, //1628 #CJK UNIFIED IDEOGRAPH + {0xABDA, 0x5F2D}, //1629 #CJK UNIFIED IDEOGRAPH + {0xABDB, 0x5F65}, //1630 #CJK UNIFIED IDEOGRAPH + {0xABDC, 0x5F88}, //1631 #CJK UNIFIED IDEOGRAPH + {0xABDD, 0x5F85}, //1632 #CJK UNIFIED IDEOGRAPH + {0xABDE, 0x5F8A}, //1633 #CJK UNIFIED IDEOGRAPH + {0xABDF, 0x5F8B}, //1634 #CJK UNIFIED IDEOGRAPH + {0xABE0, 0x5F87}, //1635 #CJK UNIFIED IDEOGRAPH + {0xABE1, 0x5F8C}, //1636 #CJK UNIFIED IDEOGRAPH + {0xABE2, 0x5F89}, //1637 #CJK UNIFIED IDEOGRAPH + {0xABE3, 0x6012}, //1638 #CJK UNIFIED IDEOGRAPH + {0xABE4, 0x601D}, //1639 #CJK UNIFIED IDEOGRAPH + {0xABE5, 0x6020}, //1640 #CJK UNIFIED IDEOGRAPH + {0xABE6, 0x6025}, //1641 #CJK UNIFIED IDEOGRAPH + {0xABE7, 0x600E}, //1642 #CJK UNIFIED IDEOGRAPH + {0xABE8, 0x6028}, //1643 #CJK UNIFIED IDEOGRAPH + {0xABE9, 0x604D}, //1644 #CJK UNIFIED IDEOGRAPH + {0xABEA, 0x6070}, //1645 #CJK UNIFIED IDEOGRAPH + {0xABEB, 0x6068}, //1646 #CJK UNIFIED IDEOGRAPH + {0xABEC, 0x6062}, //1647 #CJK UNIFIED IDEOGRAPH + {0xABED, 0x6046}, //1648 #CJK UNIFIED IDEOGRAPH + {0xABEE, 0x6043}, //1649 #CJK UNIFIED IDEOGRAPH + {0xABEF, 0x606C}, //1650 #CJK UNIFIED IDEOGRAPH + {0xABF0, 0x606B}, //1651 #CJK UNIFIED IDEOGRAPH + {0xABF1, 0x606A}, //1652 #CJK UNIFIED IDEOGRAPH + {0xABF2, 0x6064}, //1653 #CJK UNIFIED IDEOGRAPH + {0xABF3, 0x6241}, //1654 #CJK UNIFIED IDEOGRAPH + {0xABF4, 0x62DC}, //1655 #CJK UNIFIED IDEOGRAPH + {0xABF5, 0x6316}, //1656 #CJK UNIFIED IDEOGRAPH + {0xABF6, 0x6309}, //1657 #CJK UNIFIED IDEOGRAPH + {0xABF7, 0x62FC}, //1658 #CJK UNIFIED IDEOGRAPH + {0xABF8, 0x62ED}, //1659 #CJK UNIFIED IDEOGRAPH + {0xABF9, 0x6301}, //1660 #CJK UNIFIED IDEOGRAPH + {0xABFA, 0x62EE}, //1661 #CJK UNIFIED IDEOGRAPH + {0xABFB, 0x62FD}, //1662 #CJK UNIFIED IDEOGRAPH + {0xABFC, 0x6307}, //1663 #CJK UNIFIED IDEOGRAPH + {0xABFD, 0x62F1}, //1664 #CJK UNIFIED IDEOGRAPH + {0xABFE, 0x62F7}, //1665 #CJK UNIFIED IDEOGRAPH + {0xAC40, 0x62EF}, //1666 #CJK UNIFIED IDEOGRAPH + {0xAC41, 0x62EC}, //1667 #CJK UNIFIED IDEOGRAPH + {0xAC42, 0x62FE}, //1668 #CJK UNIFIED IDEOGRAPH + {0xAC43, 0x62F4}, //1669 #CJK UNIFIED IDEOGRAPH + {0xAC44, 0x6311}, //1670 #CJK UNIFIED IDEOGRAPH + {0xAC45, 0x6302}, //1671 #CJK UNIFIED IDEOGRAPH + {0xAC46, 0x653F}, //1672 #CJK UNIFIED IDEOGRAPH + {0xAC47, 0x6545}, //1673 #CJK UNIFIED IDEOGRAPH + {0xAC48, 0x65AB}, //1674 #CJK UNIFIED IDEOGRAPH + {0xAC49, 0x65BD}, //1675 #CJK UNIFIED IDEOGRAPH + {0xAC4A, 0x65E2}, //1676 #CJK UNIFIED IDEOGRAPH + {0xAC4B, 0x6625}, //1677 #CJK UNIFIED IDEOGRAPH + {0xAC4C, 0x662D}, //1678 #CJK UNIFIED IDEOGRAPH + {0xAC4D, 0x6620}, //1679 #CJK UNIFIED IDEOGRAPH + {0xAC4E, 0x6627}, //1680 #CJK UNIFIED IDEOGRAPH + {0xAC4F, 0x662F}, //1681 #CJK UNIFIED IDEOGRAPH + {0xAC50, 0x661F}, //1682 #CJK UNIFIED IDEOGRAPH + {0xAC51, 0x6628}, //1683 #CJK UNIFIED IDEOGRAPH + {0xAC52, 0x6631}, //1684 #CJK UNIFIED IDEOGRAPH + {0xAC53, 0x6624}, //1685 #CJK UNIFIED IDEOGRAPH + {0xAC54, 0x66F7}, //1686 #CJK UNIFIED IDEOGRAPH + {0xAC55, 0x67FF}, //1687 #CJK UNIFIED IDEOGRAPH + {0xAC56, 0x67D3}, //1688 #CJK UNIFIED IDEOGRAPH + {0xAC57, 0x67F1}, //1689 #CJK UNIFIED IDEOGRAPH + {0xAC58, 0x67D4}, //1690 #CJK UNIFIED IDEOGRAPH + {0xAC59, 0x67D0}, //1691 #CJK UNIFIED IDEOGRAPH + {0xAC5A, 0x67EC}, //1692 #CJK UNIFIED IDEOGRAPH + {0xAC5B, 0x67B6}, //1693 #CJK UNIFIED IDEOGRAPH + {0xAC5C, 0x67AF}, //1694 #CJK UNIFIED IDEOGRAPH + {0xAC5D, 0x67F5}, //1695 #CJK UNIFIED IDEOGRAPH + {0xAC5E, 0x67E9}, //1696 #CJK UNIFIED IDEOGRAPH + {0xAC5F, 0x67EF}, //1697 #CJK UNIFIED IDEOGRAPH + {0xAC60, 0x67C4}, //1698 #CJK UNIFIED IDEOGRAPH + {0xAC61, 0x67D1}, //1699 #CJK UNIFIED IDEOGRAPH + {0xAC62, 0x67B4}, //1700 #CJK UNIFIED IDEOGRAPH + {0xAC63, 0x67DA}, //1701 #CJK UNIFIED IDEOGRAPH + {0xAC64, 0x67E5}, //1702 #CJK UNIFIED IDEOGRAPH + {0xAC65, 0x67B8}, //1703 #CJK UNIFIED IDEOGRAPH + {0xAC66, 0x67CF}, //1704 #CJK UNIFIED IDEOGRAPH + {0xAC67, 0x67DE}, //1705 #CJK UNIFIED IDEOGRAPH + {0xAC68, 0x67F3}, //1706 #CJK UNIFIED IDEOGRAPH + {0xAC69, 0x67B0}, //1707 #CJK UNIFIED IDEOGRAPH + {0xAC6A, 0x67D9}, //1708 #CJK UNIFIED IDEOGRAPH + {0xAC6B, 0x67E2}, //1709 #CJK UNIFIED IDEOGRAPH + {0xAC6C, 0x67DD}, //1710 #CJK UNIFIED IDEOGRAPH + {0xAC6D, 0x67D2}, //1711 #CJK UNIFIED IDEOGRAPH + {0xAC6E, 0x6B6A}, //1712 #CJK UNIFIED IDEOGRAPH + {0xAC6F, 0x6B83}, //1713 #CJK UNIFIED IDEOGRAPH + {0xAC70, 0x6B86}, //1714 #CJK UNIFIED IDEOGRAPH + {0xAC71, 0x6BB5}, //1715 #CJK UNIFIED IDEOGRAPH + {0xAC72, 0x6BD2}, //1716 #CJK UNIFIED IDEOGRAPH + {0xAC73, 0x6BD7}, //1717 #CJK UNIFIED IDEOGRAPH + {0xAC74, 0x6C1F}, //1718 #CJK UNIFIED IDEOGRAPH + {0xAC75, 0x6CC9}, //1719 #CJK UNIFIED IDEOGRAPH + {0xAC76, 0x6D0B}, //1720 #CJK UNIFIED IDEOGRAPH + {0xAC77, 0x6D32}, //1721 #CJK UNIFIED IDEOGRAPH + {0xAC78, 0x6D2A}, //1722 #CJK UNIFIED IDEOGRAPH + {0xAC79, 0x6D41}, //1723 #CJK UNIFIED IDEOGRAPH + {0xAC7A, 0x6D25}, //1724 #CJK UNIFIED IDEOGRAPH + {0xAC7B, 0x6D0C}, //1725 #CJK UNIFIED IDEOGRAPH + {0xAC7C, 0x6D31}, //1726 #CJK UNIFIED IDEOGRAPH + {0xAC7D, 0x6D1E}, //1727 #CJK UNIFIED IDEOGRAPH + {0xAC7E, 0x6D17}, //1728 #CJK UNIFIED IDEOGRAPH + {0xACA1, 0x6D3B}, //1729 #CJK UNIFIED IDEOGRAPH + {0xACA2, 0x6D3D}, //1730 #CJK UNIFIED IDEOGRAPH + {0xACA3, 0x6D3E}, //1731 #CJK UNIFIED IDEOGRAPH + {0xACA4, 0x6D36}, //1732 #CJK UNIFIED IDEOGRAPH + {0xACA5, 0x6D1B}, //1733 #CJK UNIFIED IDEOGRAPH + {0xACA6, 0x6CF5}, //1734 #CJK UNIFIED IDEOGRAPH + {0xACA7, 0x6D39}, //1735 #CJK UNIFIED IDEOGRAPH + {0xACA8, 0x6D27}, //1736 #CJK UNIFIED IDEOGRAPH + {0xACA9, 0x6D38}, //1737 #CJK UNIFIED IDEOGRAPH + {0xACAA, 0x6D29}, //1738 #CJK UNIFIED IDEOGRAPH + {0xACAB, 0x6D2E}, //1739 #CJK UNIFIED IDEOGRAPH + {0xACAC, 0x6D35}, //1740 #CJK UNIFIED IDEOGRAPH + {0xACAD, 0x6D0E}, //1741 #CJK UNIFIED IDEOGRAPH + {0xACAE, 0x6D2B}, //1742 #CJK UNIFIED IDEOGRAPH + {0xACAF, 0x70AB}, //1743 #CJK UNIFIED IDEOGRAPH + {0xACB0, 0x70BA}, //1744 #CJK UNIFIED IDEOGRAPH + {0xACB1, 0x70B3}, //1745 #CJK UNIFIED IDEOGRAPH + {0xACB2, 0x70AC}, //1746 #CJK UNIFIED IDEOGRAPH + {0xACB3, 0x70AF}, //1747 #CJK UNIFIED IDEOGRAPH + {0xACB4, 0x70AD}, //1748 #CJK UNIFIED IDEOGRAPH + {0xACB5, 0x70B8}, //1749 #CJK UNIFIED IDEOGRAPH + {0xACB6, 0x70AE}, //1750 #CJK UNIFIED IDEOGRAPH + {0xACB7, 0x70A4}, //1751 #CJK UNIFIED IDEOGRAPH + {0xACB8, 0x7230}, //1752 #CJK UNIFIED IDEOGRAPH + {0xACB9, 0x7272}, //1753 #CJK UNIFIED IDEOGRAPH + {0xACBA, 0x726F}, //1754 #CJK UNIFIED IDEOGRAPH + {0xACBB, 0x7274}, //1755 #CJK UNIFIED IDEOGRAPH + {0xACBC, 0x72E9}, //1756 #CJK UNIFIED IDEOGRAPH + {0xACBD, 0x72E0}, //1757 #CJK UNIFIED IDEOGRAPH + {0xACBE, 0x72E1}, //1758 #CJK UNIFIED IDEOGRAPH + {0xACBF, 0x73B7}, //1759 #CJK UNIFIED IDEOGRAPH + {0xACC0, 0x73CA}, //1760 #CJK UNIFIED IDEOGRAPH + {0xACC1, 0x73BB}, //1761 #CJK UNIFIED IDEOGRAPH + {0xACC2, 0x73B2}, //1762 #CJK UNIFIED IDEOGRAPH + {0xACC3, 0x73CD}, //1763 #CJK UNIFIED IDEOGRAPH + {0xACC4, 0x73C0}, //1764 #CJK UNIFIED IDEOGRAPH + {0xACC5, 0x73B3}, //1765 #CJK UNIFIED IDEOGRAPH + {0xACC6, 0x751A}, //1766 #CJK UNIFIED IDEOGRAPH + {0xACC7, 0x752D}, //1767 #CJK UNIFIED IDEOGRAPH + {0xACC8, 0x754F}, //1768 #CJK UNIFIED IDEOGRAPH + {0xACC9, 0x754C}, //1769 #CJK UNIFIED IDEOGRAPH + {0xACCA, 0x754E}, //1770 #CJK UNIFIED IDEOGRAPH + {0xACCB, 0x754B}, //1771 #CJK UNIFIED IDEOGRAPH + {0xACCC, 0x75AB}, //1772 #CJK UNIFIED IDEOGRAPH + {0xACCD, 0x75A4}, //1773 #CJK UNIFIED IDEOGRAPH + {0xACCE, 0x75A5}, //1774 #CJK UNIFIED IDEOGRAPH + {0xACCF, 0x75A2}, //1775 #CJK UNIFIED IDEOGRAPH + {0xACD0, 0x75A3}, //1776 #CJK UNIFIED IDEOGRAPH + {0xACD1, 0x7678}, //1777 #CJK UNIFIED IDEOGRAPH + {0xACD2, 0x7686}, //1778 #CJK UNIFIED IDEOGRAPH + {0xACD3, 0x7687}, //1779 #CJK UNIFIED IDEOGRAPH + {0xACD4, 0x7688}, //1780 #CJK UNIFIED IDEOGRAPH + {0xACD5, 0x76C8}, //1781 #CJK UNIFIED IDEOGRAPH + {0xACD6, 0x76C6}, //1782 #CJK UNIFIED IDEOGRAPH + {0xACD7, 0x76C3}, //1783 #CJK UNIFIED IDEOGRAPH + {0xACD8, 0x76C5}, //1784 #CJK UNIFIED IDEOGRAPH + {0xACD9, 0x7701}, //1785 #CJK UNIFIED IDEOGRAPH + {0xACDA, 0x76F9}, //1786 #CJK UNIFIED IDEOGRAPH + {0xACDB, 0x76F8}, //1787 #CJK UNIFIED IDEOGRAPH + {0xACDC, 0x7709}, //1788 #CJK UNIFIED IDEOGRAPH + {0xACDD, 0x770B}, //1789 #CJK UNIFIED IDEOGRAPH + {0xACDE, 0x76FE}, //1790 #CJK UNIFIED IDEOGRAPH + {0xACDF, 0x76FC}, //1791 #CJK UNIFIED IDEOGRAPH + {0xACE0, 0x7707}, //1792 #CJK UNIFIED IDEOGRAPH + {0xACE1, 0x77DC}, //1793 #CJK UNIFIED IDEOGRAPH + {0xACE2, 0x7802}, //1794 #CJK UNIFIED IDEOGRAPH + {0xACE3, 0x7814}, //1795 #CJK UNIFIED IDEOGRAPH + {0xACE4, 0x780C}, //1796 #CJK UNIFIED IDEOGRAPH + {0xACE5, 0x780D}, //1797 #CJK UNIFIED IDEOGRAPH + {0xACE6, 0x7946}, //1798 #CJK UNIFIED IDEOGRAPH + {0xACE7, 0x7949}, //1799 #CJK UNIFIED IDEOGRAPH + {0xACE8, 0x7948}, //1800 #CJK UNIFIED IDEOGRAPH + {0xACE9, 0x7947}, //1801 #CJK UNIFIED IDEOGRAPH + {0xACEA, 0x79B9}, //1802 #CJK UNIFIED IDEOGRAPH + {0xACEB, 0x79BA}, //1803 #CJK UNIFIED IDEOGRAPH + {0xACEC, 0x79D1}, //1804 #CJK UNIFIED IDEOGRAPH + {0xACED, 0x79D2}, //1805 #CJK UNIFIED IDEOGRAPH + {0xACEE, 0x79CB}, //1806 #CJK UNIFIED IDEOGRAPH + {0xACEF, 0x7A7F}, //1807 #CJK UNIFIED IDEOGRAPH + {0xACF0, 0x7A81}, //1808 #CJK UNIFIED IDEOGRAPH + {0xACF1, 0x7AFF}, //1809 #CJK UNIFIED IDEOGRAPH + {0xACF2, 0x7AFD}, //1810 #CJK UNIFIED IDEOGRAPH + {0xACF3, 0x7C7D}, //1811 #CJK UNIFIED IDEOGRAPH + {0xACF4, 0x7D02}, //1812 #CJK UNIFIED IDEOGRAPH + {0xACF5, 0x7D05}, //1813 #CJK UNIFIED IDEOGRAPH + {0xACF6, 0x7D00}, //1814 #CJK UNIFIED IDEOGRAPH + {0xACF7, 0x7D09}, //1815 #CJK UNIFIED IDEOGRAPH + {0xACF8, 0x7D07}, //1816 #CJK UNIFIED IDEOGRAPH + {0xACF9, 0x7D04}, //1817 #CJK UNIFIED IDEOGRAPH + {0xACFA, 0x7D06}, //1818 #CJK UNIFIED IDEOGRAPH + {0xACFB, 0x7F38}, //1819 #CJK UNIFIED IDEOGRAPH + {0xACFC, 0x7F8E}, //1820 #CJK UNIFIED IDEOGRAPH + {0xACFD, 0x7FBF}, //1821 #CJK UNIFIED IDEOGRAPH + {0xACFE, 0x8004}, //1822 #CJK UNIFIED IDEOGRAPH + {0xAD40, 0x8010}, //1823 #CJK UNIFIED IDEOGRAPH + {0xAD41, 0x800D}, //1824 #CJK UNIFIED IDEOGRAPH + {0xAD42, 0x8011}, //1825 #CJK UNIFIED IDEOGRAPH + {0xAD43, 0x8036}, //1826 #CJK UNIFIED IDEOGRAPH + {0xAD44, 0x80D6}, //1827 #CJK UNIFIED IDEOGRAPH + {0xAD45, 0x80E5}, //1828 #CJK UNIFIED IDEOGRAPH + {0xAD46, 0x80DA}, //1829 #CJK UNIFIED IDEOGRAPH + {0xAD47, 0x80C3}, //1830 #CJK UNIFIED IDEOGRAPH + {0xAD48, 0x80C4}, //1831 #CJK UNIFIED IDEOGRAPH + {0xAD49, 0x80CC}, //1832 #CJK UNIFIED IDEOGRAPH + {0xAD4A, 0x80E1}, //1833 #CJK UNIFIED IDEOGRAPH + {0xAD4B, 0x80DB}, //1834 #CJK UNIFIED IDEOGRAPH + {0xAD4C, 0x80CE}, //1835 #CJK UNIFIED IDEOGRAPH + {0xAD4D, 0x80DE}, //1836 #CJK UNIFIED IDEOGRAPH + {0xAD4E, 0x80E4}, //1837 #CJK UNIFIED IDEOGRAPH + {0xAD4F, 0x80DD}, //1838 #CJK UNIFIED IDEOGRAPH + {0xAD50, 0x81F4}, //1839 #CJK UNIFIED IDEOGRAPH + {0xAD51, 0x8222}, //1840 #CJK UNIFIED IDEOGRAPH + {0xAD52, 0x82E7}, //1841 #CJK UNIFIED IDEOGRAPH + {0xAD53, 0x8303}, //1842 #CJK UNIFIED IDEOGRAPH + {0xAD54, 0x8305}, //1843 #CJK UNIFIED IDEOGRAPH + {0xAD55, 0x82E3}, //1844 #CJK UNIFIED IDEOGRAPH + {0xAD56, 0x82DB}, //1845 #CJK UNIFIED IDEOGRAPH + {0xAD57, 0x82E6}, //1846 #CJK UNIFIED IDEOGRAPH + {0xAD58, 0x8304}, //1847 #CJK UNIFIED IDEOGRAPH + {0xAD59, 0x82E5}, //1848 #CJK UNIFIED IDEOGRAPH + {0xAD5A, 0x8302}, //1849 #CJK UNIFIED IDEOGRAPH + {0xAD5B, 0x8309}, //1850 #CJK UNIFIED IDEOGRAPH + {0xAD5C, 0x82D2}, //1851 #CJK UNIFIED IDEOGRAPH + {0xAD5D, 0x82D7}, //1852 #CJK UNIFIED IDEOGRAPH + {0xAD5E, 0x82F1}, //1853 #CJK UNIFIED IDEOGRAPH + {0xAD5F, 0x8301}, //1854 #CJK UNIFIED IDEOGRAPH + {0xAD60, 0x82DC}, //1855 #CJK UNIFIED IDEOGRAPH + {0xAD61, 0x82D4}, //1856 #CJK UNIFIED IDEOGRAPH + {0xAD62, 0x82D1}, //1857 #CJK UNIFIED IDEOGRAPH + {0xAD63, 0x82DE}, //1858 #CJK UNIFIED IDEOGRAPH + {0xAD64, 0x82D3}, //1859 #CJK UNIFIED IDEOGRAPH + {0xAD65, 0x82DF}, //1860 #CJK UNIFIED IDEOGRAPH + {0xAD66, 0x82EF}, //1861 #CJK UNIFIED IDEOGRAPH + {0xAD67, 0x8306}, //1862 #CJK UNIFIED IDEOGRAPH + {0xAD68, 0x8650}, //1863 #CJK UNIFIED IDEOGRAPH + {0xAD69, 0x8679}, //1864 #CJK UNIFIED IDEOGRAPH + {0xAD6A, 0x867B}, //1865 #CJK UNIFIED IDEOGRAPH + {0xAD6B, 0x867A}, //1866 #CJK UNIFIED IDEOGRAPH + {0xAD6C, 0x884D}, //1867 #CJK UNIFIED IDEOGRAPH + {0xAD6D, 0x886B}, //1868 #CJK UNIFIED IDEOGRAPH + {0xAD6E, 0x8981}, //1869 #CJK UNIFIED IDEOGRAPH + {0xAD6F, 0x89D4}, //1870 #CJK UNIFIED IDEOGRAPH + {0xAD70, 0x8A08}, //1871 #CJK UNIFIED IDEOGRAPH + {0xAD71, 0x8A02}, //1872 #CJK UNIFIED IDEOGRAPH + {0xAD72, 0x8A03}, //1873 #CJK UNIFIED IDEOGRAPH + {0xAD73, 0x8C9E}, //1874 #CJK UNIFIED IDEOGRAPH + {0xAD74, 0x8CA0}, //1875 #CJK UNIFIED IDEOGRAPH + {0xAD75, 0x8D74}, //1876 #CJK UNIFIED IDEOGRAPH + {0xAD76, 0x8D73}, //1877 #CJK UNIFIED IDEOGRAPH + {0xAD77, 0x8DB4}, //1878 #CJK UNIFIED IDEOGRAPH + {0xAD78, 0x8ECD}, //1879 #CJK UNIFIED IDEOGRAPH + {0xAD79, 0x8ECC}, //1880 #CJK UNIFIED IDEOGRAPH + {0xAD7A, 0x8FF0}, //1881 #CJK UNIFIED IDEOGRAPH + {0xAD7B, 0x8FE6}, //1882 #CJK UNIFIED IDEOGRAPH + {0xAD7C, 0x8FE2}, //1883 #CJK UNIFIED IDEOGRAPH + {0xAD7D, 0x8FEA}, //1884 #CJK UNIFIED IDEOGRAPH + {0xAD7E, 0x8FE5}, //1885 #CJK UNIFIED IDEOGRAPH + {0xADA1, 0x8FED}, //1886 #CJK UNIFIED IDEOGRAPH + {0xADA2, 0x8FEB}, //1887 #CJK UNIFIED IDEOGRAPH + {0xADA3, 0x8FE4}, //1888 #CJK UNIFIED IDEOGRAPH + {0xADA4, 0x8FE8}, //1889 #CJK UNIFIED IDEOGRAPH + {0xADA5, 0x90CA}, //1890 #CJK UNIFIED IDEOGRAPH + {0xADA6, 0x90CE}, //1891 #CJK UNIFIED IDEOGRAPH + {0xADA7, 0x90C1}, //1892 #CJK UNIFIED IDEOGRAPH + {0xADA8, 0x90C3}, //1893 #CJK UNIFIED IDEOGRAPH + {0xADA9, 0x914B}, //1894 #CJK UNIFIED IDEOGRAPH + {0xADAA, 0x914A}, //1895 #CJK UNIFIED IDEOGRAPH + {0xADAB, 0x91CD}, //1896 #CJK UNIFIED IDEOGRAPH + {0xADAC, 0x9582}, //1897 #CJK UNIFIED IDEOGRAPH + {0xADAD, 0x9650}, //1898 #CJK UNIFIED IDEOGRAPH + {0xADAE, 0x964B}, //1899 #CJK UNIFIED IDEOGRAPH + {0xADAF, 0x964C}, //1900 #CJK UNIFIED IDEOGRAPH + {0xADB0, 0x964D}, //1901 #CJK UNIFIED IDEOGRAPH + {0xADB1, 0x9762}, //1902 #CJK UNIFIED IDEOGRAPH + {0xADB2, 0x9769}, //1903 #CJK UNIFIED IDEOGRAPH + {0xADB3, 0x97CB}, //1904 #CJK UNIFIED IDEOGRAPH + {0xADB4, 0x97ED}, //1905 #CJK UNIFIED IDEOGRAPH + {0xADB5, 0x97F3}, //1906 #CJK UNIFIED IDEOGRAPH + {0xADB6, 0x9801}, //1907 #CJK UNIFIED IDEOGRAPH + {0xADB7, 0x98A8}, //1908 #CJK UNIFIED IDEOGRAPH + {0xADB8, 0x98DB}, //1909 #CJK UNIFIED IDEOGRAPH + {0xADB9, 0x98DF}, //1910 #CJK UNIFIED IDEOGRAPH + {0xADBA, 0x9996}, //1911 #CJK UNIFIED IDEOGRAPH + {0xADBB, 0x9999}, //1912 #CJK UNIFIED IDEOGRAPH + {0xADBC, 0x4E58}, //1913 #CJK UNIFIED IDEOGRAPH + {0xADBD, 0x4EB3}, //1914 #CJK UNIFIED IDEOGRAPH + {0xADBE, 0x500C}, //1915 #CJK UNIFIED IDEOGRAPH + {0xADBF, 0x500D}, //1916 #CJK UNIFIED IDEOGRAPH + {0xADC0, 0x5023}, //1917 #CJK UNIFIED IDEOGRAPH + {0xADC1, 0x4FEF}, //1918 #CJK UNIFIED IDEOGRAPH + {0xADC2, 0x5026}, //1919 #CJK UNIFIED IDEOGRAPH + {0xADC3, 0x5025}, //1920 #CJK UNIFIED IDEOGRAPH + {0xADC4, 0x4FF8}, //1921 #CJK UNIFIED IDEOGRAPH + {0xADC5, 0x5029}, //1922 #CJK UNIFIED IDEOGRAPH + {0xADC6, 0x5016}, //1923 #CJK UNIFIED IDEOGRAPH + {0xADC7, 0x5006}, //1924 #CJK UNIFIED IDEOGRAPH + {0xADC8, 0x503C}, //1925 #CJK UNIFIED IDEOGRAPH + {0xADC9, 0x501F}, //1926 #CJK UNIFIED IDEOGRAPH + {0xADCA, 0x501A}, //1927 #CJK UNIFIED IDEOGRAPH + {0xADCB, 0x5012}, //1928 #CJK UNIFIED IDEOGRAPH + {0xADCC, 0x5011}, //1929 #CJK UNIFIED IDEOGRAPH + {0xADCD, 0x4FFA}, //1930 #CJK UNIFIED IDEOGRAPH + {0xADCE, 0x5000}, //1931 #CJK UNIFIED IDEOGRAPH + {0xADCF, 0x5014}, //1932 #CJK UNIFIED IDEOGRAPH + {0xADD0, 0x5028}, //1933 #CJK UNIFIED IDEOGRAPH + {0xADD1, 0x4FF1}, //1934 #CJK UNIFIED IDEOGRAPH + {0xADD2, 0x5021}, //1935 #CJK UNIFIED IDEOGRAPH + {0xADD3, 0x500B}, //1936 #CJK UNIFIED IDEOGRAPH + {0xADD4, 0x5019}, //1937 #CJK UNIFIED IDEOGRAPH + {0xADD5, 0x5018}, //1938 #CJK UNIFIED IDEOGRAPH + {0xADD6, 0x4FF3}, //1939 #CJK UNIFIED IDEOGRAPH + {0xADD7, 0x4FEE}, //1940 #CJK UNIFIED IDEOGRAPH + {0xADD8, 0x502D}, //1941 #CJK UNIFIED IDEOGRAPH + {0xADD9, 0x502A}, //1942 #CJK UNIFIED IDEOGRAPH + {0xADDA, 0x4FFE}, //1943 #CJK UNIFIED IDEOGRAPH + {0xADDB, 0x502B}, //1944 #CJK UNIFIED IDEOGRAPH + {0xADDC, 0x5009}, //1945 #CJK UNIFIED IDEOGRAPH + {0xADDD, 0x517C}, //1946 #CJK UNIFIED IDEOGRAPH + {0xADDE, 0x51A4}, //1947 #CJK UNIFIED IDEOGRAPH + {0xADDF, 0x51A5}, //1948 #CJK UNIFIED IDEOGRAPH + {0xADE0, 0x51A2}, //1949 #CJK UNIFIED IDEOGRAPH + {0xADE1, 0x51CD}, //1950 #CJK UNIFIED IDEOGRAPH + {0xADE2, 0x51CC}, //1951 #CJK UNIFIED IDEOGRAPH + {0xADE3, 0x51C6}, //1952 #CJK UNIFIED IDEOGRAPH + {0xADE4, 0x51CB}, //1953 #CJK UNIFIED IDEOGRAPH + {0xADE5, 0x5256}, //1954 #CJK UNIFIED IDEOGRAPH + {0xADE6, 0x525C}, //1955 #CJK UNIFIED IDEOGRAPH + {0xADE7, 0x5254}, //1956 #CJK UNIFIED IDEOGRAPH + {0xADE8, 0x525B}, //1957 #CJK UNIFIED IDEOGRAPH + {0xADE9, 0x525D}, //1958 #CJK UNIFIED IDEOGRAPH + {0xADEA, 0x532A}, //1959 #CJK UNIFIED IDEOGRAPH + {0xADEB, 0x537F}, //1960 #CJK UNIFIED IDEOGRAPH + {0xADEC, 0x539F}, //1961 #CJK UNIFIED IDEOGRAPH + {0xADED, 0x539D}, //1962 #CJK UNIFIED IDEOGRAPH + {0xADEE, 0x53DF}, //1963 #CJK UNIFIED IDEOGRAPH + {0xADEF, 0x54E8}, //1964 #CJK UNIFIED IDEOGRAPH + {0xADF0, 0x5510}, //1965 #CJK UNIFIED IDEOGRAPH + {0xADF1, 0x5501}, //1966 #CJK UNIFIED IDEOGRAPH + {0xADF2, 0x5537}, //1967 #CJK UNIFIED IDEOGRAPH + {0xADF3, 0x54FC}, //1968 #CJK UNIFIED IDEOGRAPH + {0xADF4, 0x54E5}, //1969 #CJK UNIFIED IDEOGRAPH + {0xADF5, 0x54F2}, //1970 #CJK UNIFIED IDEOGRAPH + {0xADF6, 0x5506}, //1971 #CJK UNIFIED IDEOGRAPH + {0xADF7, 0x54FA}, //1972 #CJK UNIFIED IDEOGRAPH + {0xADF8, 0x5514}, //1973 #CJK UNIFIED IDEOGRAPH + {0xADF9, 0x54E9}, //1974 #CJK UNIFIED IDEOGRAPH + {0xADFA, 0x54ED}, //1975 #CJK UNIFIED IDEOGRAPH + {0xADFB, 0x54E1}, //1976 #CJK UNIFIED IDEOGRAPH + {0xADFC, 0x5509}, //1977 #CJK UNIFIED IDEOGRAPH + {0xADFD, 0x54EE}, //1978 #CJK UNIFIED IDEOGRAPH + {0xADFE, 0x54EA}, //1979 #CJK UNIFIED IDEOGRAPH + {0xAE40, 0x54E6}, //1980 #CJK UNIFIED IDEOGRAPH + {0xAE41, 0x5527}, //1981 #CJK UNIFIED IDEOGRAPH + {0xAE42, 0x5507}, //1982 #CJK UNIFIED IDEOGRAPH + {0xAE43, 0x54FD}, //1983 #CJK UNIFIED IDEOGRAPH + {0xAE44, 0x550F}, //1984 #CJK UNIFIED IDEOGRAPH + {0xAE45, 0x5703}, //1985 #CJK UNIFIED IDEOGRAPH + {0xAE46, 0x5704}, //1986 #CJK UNIFIED IDEOGRAPH + {0xAE47, 0x57C2}, //1987 #CJK UNIFIED IDEOGRAPH + {0xAE48, 0x57D4}, //1988 #CJK UNIFIED IDEOGRAPH + {0xAE49, 0x57CB}, //1989 #CJK UNIFIED IDEOGRAPH + {0xAE4A, 0x57C3}, //1990 #CJK UNIFIED IDEOGRAPH + {0xAE4B, 0x5809}, //1991 #CJK UNIFIED IDEOGRAPH + {0xAE4C, 0x590F}, //1992 #CJK UNIFIED IDEOGRAPH + {0xAE4D, 0x5957}, //1993 #CJK UNIFIED IDEOGRAPH + {0xAE4E, 0x5958}, //1994 #CJK UNIFIED IDEOGRAPH + {0xAE4F, 0x595A}, //1995 #CJK UNIFIED IDEOGRAPH + {0xAE50, 0x5A11}, //1996 #CJK UNIFIED IDEOGRAPH + {0xAE51, 0x5A18}, //1997 #CJK UNIFIED IDEOGRAPH + {0xAE52, 0x5A1C}, //1998 #CJK UNIFIED IDEOGRAPH + {0xAE53, 0x5A1F}, //1999 #CJK UNIFIED IDEOGRAPH + {0xAE54, 0x5A1B}, //2000 #CJK UNIFIED IDEOGRAPH + {0xAE55, 0x5A13}, //2001 #CJK UNIFIED IDEOGRAPH + {0xAE56, 0x59EC}, //2002 #CJK UNIFIED IDEOGRAPH + {0xAE57, 0x5A20}, //2003 #CJK UNIFIED IDEOGRAPH + {0xAE58, 0x5A23}, //2004 #CJK UNIFIED IDEOGRAPH + {0xAE59, 0x5A29}, //2005 #CJK UNIFIED IDEOGRAPH + {0xAE5A, 0x5A25}, //2006 #CJK UNIFIED IDEOGRAPH + {0xAE5B, 0x5A0C}, //2007 #CJK UNIFIED IDEOGRAPH + {0xAE5C, 0x5A09}, //2008 #CJK UNIFIED IDEOGRAPH + {0xAE5D, 0x5B6B}, //2009 #CJK UNIFIED IDEOGRAPH + {0xAE5E, 0x5C58}, //2010 #CJK UNIFIED IDEOGRAPH + {0xAE5F, 0x5BB0}, //2011 #CJK UNIFIED IDEOGRAPH + {0xAE60, 0x5BB3}, //2012 #CJK UNIFIED IDEOGRAPH + {0xAE61, 0x5BB6}, //2013 #CJK UNIFIED IDEOGRAPH + {0xAE62, 0x5BB4}, //2014 #CJK UNIFIED IDEOGRAPH + {0xAE63, 0x5BAE}, //2015 #CJK UNIFIED IDEOGRAPH + {0xAE64, 0x5BB5}, //2016 #CJK UNIFIED IDEOGRAPH + {0xAE65, 0x5BB9}, //2017 #CJK UNIFIED IDEOGRAPH + {0xAE66, 0x5BB8}, //2018 #CJK UNIFIED IDEOGRAPH + {0xAE67, 0x5C04}, //2019 #CJK UNIFIED IDEOGRAPH + {0xAE68, 0x5C51}, //2020 #CJK UNIFIED IDEOGRAPH + {0xAE69, 0x5C55}, //2021 #CJK UNIFIED IDEOGRAPH + {0xAE6A, 0x5C50}, //2022 #CJK UNIFIED IDEOGRAPH + {0xAE6B, 0x5CED}, //2023 #CJK UNIFIED IDEOGRAPH + {0xAE6C, 0x5CFD}, //2024 #CJK UNIFIED IDEOGRAPH + {0xAE6D, 0x5CFB}, //2025 #CJK UNIFIED IDEOGRAPH + {0xAE6E, 0x5CEA}, //2026 #CJK UNIFIED IDEOGRAPH + {0xAE6F, 0x5CE8}, //2027 #CJK UNIFIED IDEOGRAPH + {0xAE70, 0x5CF0}, //2028 #CJK UNIFIED IDEOGRAPH + {0xAE71, 0x5CF6}, //2029 #CJK UNIFIED IDEOGRAPH + {0xAE72, 0x5D01}, //2030 #CJK UNIFIED IDEOGRAPH + {0xAE73, 0x5CF4}, //2031 #CJK UNIFIED IDEOGRAPH + {0xAE74, 0x5DEE}, //2032 #CJK UNIFIED IDEOGRAPH + {0xAE75, 0x5E2D}, //2033 #CJK UNIFIED IDEOGRAPH + {0xAE76, 0x5E2B}, //2034 #CJK UNIFIED IDEOGRAPH + {0xAE77, 0x5EAB}, //2035 #CJK UNIFIED IDEOGRAPH + {0xAE78, 0x5EAD}, //2036 #CJK UNIFIED IDEOGRAPH + {0xAE79, 0x5EA7}, //2037 #CJK UNIFIED IDEOGRAPH + {0xAE7A, 0x5F31}, //2038 #CJK UNIFIED IDEOGRAPH + {0xAE7B, 0x5F92}, //2039 #CJK UNIFIED IDEOGRAPH + {0xAE7C, 0x5F91}, //2040 #CJK UNIFIED IDEOGRAPH + {0xAE7D, 0x5F90}, //2041 #CJK UNIFIED IDEOGRAPH + {0xAE7E, 0x6059}, //2042 #CJK UNIFIED IDEOGRAPH + {0xAEA1, 0x6063}, //2043 #CJK UNIFIED IDEOGRAPH + {0xAEA2, 0x6065}, //2044 #CJK UNIFIED IDEOGRAPH + {0xAEA3, 0x6050}, //2045 #CJK UNIFIED IDEOGRAPH + {0xAEA4, 0x6055}, //2046 #CJK UNIFIED IDEOGRAPH + {0xAEA5, 0x606D}, //2047 #CJK UNIFIED IDEOGRAPH + {0xAEA6, 0x6069}, //2048 #CJK UNIFIED IDEOGRAPH + {0xAEA7, 0x606F}, //2049 #CJK UNIFIED IDEOGRAPH + {0xAEA8, 0x6084}, //2050 #CJK UNIFIED IDEOGRAPH + {0xAEA9, 0x609F}, //2051 #CJK UNIFIED IDEOGRAPH + {0xAEAA, 0x609A}, //2052 #CJK UNIFIED IDEOGRAPH + {0xAEAB, 0x608D}, //2053 #CJK UNIFIED IDEOGRAPH + {0xAEAC, 0x6094}, //2054 #CJK UNIFIED IDEOGRAPH + {0xAEAD, 0x608C}, //2055 #CJK UNIFIED IDEOGRAPH + {0xAEAE, 0x6085}, //2056 #CJK UNIFIED IDEOGRAPH + {0xAEAF, 0x6096}, //2057 #CJK UNIFIED IDEOGRAPH + {0xAEB0, 0x6247}, //2058 #CJK UNIFIED IDEOGRAPH + {0xAEB1, 0x62F3}, //2059 #CJK UNIFIED IDEOGRAPH + {0xAEB2, 0x6308}, //2060 #CJK UNIFIED IDEOGRAPH + {0xAEB3, 0x62FF}, //2061 #CJK UNIFIED IDEOGRAPH + {0xAEB4, 0x634E}, //2062 #CJK UNIFIED IDEOGRAPH + {0xAEB5, 0x633E}, //2063 #CJK UNIFIED IDEOGRAPH + {0xAEB6, 0x632F}, //2064 #CJK UNIFIED IDEOGRAPH + {0xAEB7, 0x6355}, //2065 #CJK UNIFIED IDEOGRAPH + {0xAEB8, 0x6342}, //2066 #CJK UNIFIED IDEOGRAPH + {0xAEB9, 0x6346}, //2067 #CJK UNIFIED IDEOGRAPH + {0xAEBA, 0x634F}, //2068 #CJK UNIFIED IDEOGRAPH + {0xAEBB, 0x6349}, //2069 #CJK UNIFIED IDEOGRAPH + {0xAEBC, 0x633A}, //2070 #CJK UNIFIED IDEOGRAPH + {0xAEBD, 0x6350}, //2071 #CJK UNIFIED IDEOGRAPH + {0xAEBE, 0x633D}, //2072 #CJK UNIFIED IDEOGRAPH + {0xAEBF, 0x632A}, //2073 #CJK UNIFIED IDEOGRAPH + {0xAEC0, 0x632B}, //2074 #CJK UNIFIED IDEOGRAPH + {0xAEC1, 0x6328}, //2075 #CJK UNIFIED IDEOGRAPH + {0xAEC2, 0x634D}, //2076 #CJK UNIFIED IDEOGRAPH + {0xAEC3, 0x634C}, //2077 #CJK UNIFIED IDEOGRAPH + {0xAEC4, 0x6548}, //2078 #CJK UNIFIED IDEOGRAPH + {0xAEC5, 0x6549}, //2079 #CJK UNIFIED IDEOGRAPH + {0xAEC6, 0x6599}, //2080 #CJK UNIFIED IDEOGRAPH + {0xAEC7, 0x65C1}, //2081 #CJK UNIFIED IDEOGRAPH + {0xAEC8, 0x65C5}, //2082 #CJK UNIFIED IDEOGRAPH + {0xAEC9, 0x6642}, //2083 #CJK UNIFIED IDEOGRAPH + {0xAECA, 0x6649}, //2084 #CJK UNIFIED IDEOGRAPH + {0xAECB, 0x664F}, //2085 #CJK UNIFIED IDEOGRAPH + {0xAECC, 0x6643}, //2086 #CJK UNIFIED IDEOGRAPH + {0xAECD, 0x6652}, //2087 #CJK UNIFIED IDEOGRAPH + {0xAECE, 0x664C}, //2088 #CJK UNIFIED IDEOGRAPH + {0xAECF, 0x6645}, //2089 #CJK UNIFIED IDEOGRAPH + {0xAED0, 0x6641}, //2090 #CJK UNIFIED IDEOGRAPH + {0xAED1, 0x66F8}, //2091 #CJK UNIFIED IDEOGRAPH + {0xAED2, 0x6714}, //2092 #CJK UNIFIED IDEOGRAPH + {0xAED3, 0x6715}, //2093 #CJK UNIFIED IDEOGRAPH + {0xAED4, 0x6717}, //2094 #CJK UNIFIED IDEOGRAPH + {0xAED5, 0x6821}, //2095 #CJK UNIFIED IDEOGRAPH + {0xAED6, 0x6838}, //2096 #CJK UNIFIED IDEOGRAPH + {0xAED7, 0x6848}, //2097 #CJK UNIFIED IDEOGRAPH + {0xAED8, 0x6846}, //2098 #CJK UNIFIED IDEOGRAPH + {0xAED9, 0x6853}, //2099 #CJK UNIFIED IDEOGRAPH + {0xAEDA, 0x6839}, //2100 #CJK UNIFIED IDEOGRAPH + {0xAEDB, 0x6842}, //2101 #CJK UNIFIED IDEOGRAPH + {0xAEDC, 0x6854}, //2102 #CJK UNIFIED IDEOGRAPH + {0xAEDD, 0x6829}, //2103 #CJK UNIFIED IDEOGRAPH + {0xAEDE, 0x68B3}, //2104 #CJK UNIFIED IDEOGRAPH + {0xAEDF, 0x6817}, //2105 #CJK UNIFIED IDEOGRAPH + {0xAEE0, 0x684C}, //2106 #CJK UNIFIED IDEOGRAPH + {0xAEE1, 0x6851}, //2107 #CJK UNIFIED IDEOGRAPH + {0xAEE2, 0x683D}, //2108 #CJK UNIFIED IDEOGRAPH + {0xAEE3, 0x67F4}, //2109 #CJK UNIFIED IDEOGRAPH + {0xAEE4, 0x6850}, //2110 #CJK UNIFIED IDEOGRAPH + {0xAEE5, 0x6840}, //2111 #CJK UNIFIED IDEOGRAPH + {0xAEE6, 0x683C}, //2112 #CJK UNIFIED IDEOGRAPH + {0xAEE7, 0x6843}, //2113 #CJK UNIFIED IDEOGRAPH + {0xAEE8, 0x682A}, //2114 #CJK UNIFIED IDEOGRAPH + {0xAEE9, 0x6845}, //2115 #CJK UNIFIED IDEOGRAPH + {0xAEEA, 0x6813}, //2116 #CJK UNIFIED IDEOGRAPH + {0xAEEB, 0x6818}, //2117 #CJK UNIFIED IDEOGRAPH + {0xAEEC, 0x6841}, //2118 #CJK UNIFIED IDEOGRAPH + {0xAEED, 0x6B8A}, //2119 #CJK UNIFIED IDEOGRAPH + {0xAEEE, 0x6B89}, //2120 #CJK UNIFIED IDEOGRAPH + {0xAEEF, 0x6BB7}, //2121 #CJK UNIFIED IDEOGRAPH + {0xAEF0, 0x6C23}, //2122 #CJK UNIFIED IDEOGRAPH + {0xAEF1, 0x6C27}, //2123 #CJK UNIFIED IDEOGRAPH + {0xAEF2, 0x6C28}, //2124 #CJK UNIFIED IDEOGRAPH + {0xAEF3, 0x6C26}, //2125 #CJK UNIFIED IDEOGRAPH + {0xAEF4, 0x6C24}, //2126 #CJK UNIFIED IDEOGRAPH + {0xAEF5, 0x6CF0}, //2127 #CJK UNIFIED IDEOGRAPH + {0xAEF6, 0x6D6A}, //2128 #CJK UNIFIED IDEOGRAPH + {0xAEF7, 0x6D95}, //2129 #CJK UNIFIED IDEOGRAPH + {0xAEF8, 0x6D88}, //2130 #CJK UNIFIED IDEOGRAPH + {0xAEF9, 0x6D87}, //2131 #CJK UNIFIED IDEOGRAPH + {0xAEFA, 0x6D66}, //2132 #CJK UNIFIED IDEOGRAPH + {0xAEFB, 0x6D78}, //2133 #CJK UNIFIED IDEOGRAPH + {0xAEFC, 0x6D77}, //2134 #CJK UNIFIED IDEOGRAPH + {0xAEFD, 0x6D59}, //2135 #CJK UNIFIED IDEOGRAPH + {0xAEFE, 0x6D93}, //2136 #CJK UNIFIED IDEOGRAPH + {0xAF40, 0x6D6C}, //2137 #CJK UNIFIED IDEOGRAPH + {0xAF41, 0x6D89}, //2138 #CJK UNIFIED IDEOGRAPH + {0xAF42, 0x6D6E}, //2139 #CJK UNIFIED IDEOGRAPH + {0xAF43, 0x6D5A}, //2140 #CJK UNIFIED IDEOGRAPH + {0xAF44, 0x6D74}, //2141 #CJK UNIFIED IDEOGRAPH + {0xAF45, 0x6D69}, //2142 #CJK UNIFIED IDEOGRAPH + {0xAF46, 0x6D8C}, //2143 #CJK UNIFIED IDEOGRAPH + {0xAF47, 0x6D8A}, //2144 #CJK UNIFIED IDEOGRAPH + {0xAF48, 0x6D79}, //2145 #CJK UNIFIED IDEOGRAPH + {0xAF49, 0x6D85}, //2146 #CJK UNIFIED IDEOGRAPH + {0xAF4A, 0x6D65}, //2147 #CJK UNIFIED IDEOGRAPH + {0xAF4B, 0x6D94}, //2148 #CJK UNIFIED IDEOGRAPH + {0xAF4C, 0x70CA}, //2149 #CJK UNIFIED IDEOGRAPH + {0xAF4D, 0x70D8}, //2150 #CJK UNIFIED IDEOGRAPH + {0xAF4E, 0x70E4}, //2151 #CJK UNIFIED IDEOGRAPH + {0xAF4F, 0x70D9}, //2152 #CJK UNIFIED IDEOGRAPH + {0xAF50, 0x70C8}, //2153 #CJK UNIFIED IDEOGRAPH + {0xAF51, 0x70CF}, //2154 #CJK UNIFIED IDEOGRAPH + {0xAF52, 0x7239}, //2155 #CJK UNIFIED IDEOGRAPH + {0xAF53, 0x7279}, //2156 #CJK UNIFIED IDEOGRAPH + {0xAF54, 0x72FC}, //2157 #CJK UNIFIED IDEOGRAPH + {0xAF55, 0x72F9}, //2158 #CJK UNIFIED IDEOGRAPH + {0xAF56, 0x72FD}, //2159 #CJK UNIFIED IDEOGRAPH + {0xAF57, 0x72F8}, //2160 #CJK UNIFIED IDEOGRAPH + {0xAF58, 0x72F7}, //2161 #CJK UNIFIED IDEOGRAPH + {0xAF59, 0x7386}, //2162 #CJK UNIFIED IDEOGRAPH + {0xAF5A, 0x73ED}, //2163 #CJK UNIFIED IDEOGRAPH + {0xAF5B, 0x7409}, //2164 #CJK UNIFIED IDEOGRAPH + {0xAF5C, 0x73EE}, //2165 #CJK UNIFIED IDEOGRAPH + {0xAF5D, 0x73E0}, //2166 #CJK UNIFIED IDEOGRAPH + {0xAF5E, 0x73EA}, //2167 #CJK UNIFIED IDEOGRAPH + {0xAF5F, 0x73DE}, //2168 #CJK UNIFIED IDEOGRAPH + {0xAF60, 0x7554}, //2169 #CJK UNIFIED IDEOGRAPH + {0xAF61, 0x755D}, //2170 #CJK UNIFIED IDEOGRAPH + {0xAF62, 0x755C}, //2171 #CJK UNIFIED IDEOGRAPH + {0xAF63, 0x755A}, //2172 #CJK UNIFIED IDEOGRAPH + {0xAF64, 0x7559}, //2173 #CJK UNIFIED IDEOGRAPH + {0xAF65, 0x75BE}, //2174 #CJK UNIFIED IDEOGRAPH + {0xAF66, 0x75C5}, //2175 #CJK UNIFIED IDEOGRAPH + {0xAF67, 0x75C7}, //2176 #CJK UNIFIED IDEOGRAPH + {0xAF68, 0x75B2}, //2177 #CJK UNIFIED IDEOGRAPH + {0xAF69, 0x75B3}, //2178 #CJK UNIFIED IDEOGRAPH + {0xAF6A, 0x75BD}, //2179 #CJK UNIFIED IDEOGRAPH + {0xAF6B, 0x75BC}, //2180 #CJK UNIFIED IDEOGRAPH + {0xAF6C, 0x75B9}, //2181 #CJK UNIFIED IDEOGRAPH + {0xAF6D, 0x75C2}, //2182 #CJK UNIFIED IDEOGRAPH + {0xAF6E, 0x75B8}, //2183 #CJK UNIFIED IDEOGRAPH + {0xAF6F, 0x768B}, //2184 #CJK UNIFIED IDEOGRAPH + {0xAF70, 0x76B0}, //2185 #CJK UNIFIED IDEOGRAPH + {0xAF71, 0x76CA}, //2186 #CJK UNIFIED IDEOGRAPH + {0xAF72, 0x76CD}, //2187 #CJK UNIFIED IDEOGRAPH + {0xAF73, 0x76CE}, //2188 #CJK UNIFIED IDEOGRAPH + {0xAF74, 0x7729}, //2189 #CJK UNIFIED IDEOGRAPH + {0xAF75, 0x771F}, //2190 #CJK UNIFIED IDEOGRAPH + {0xAF76, 0x7720}, //2191 #CJK UNIFIED IDEOGRAPH + {0xAF77, 0x7728}, //2192 #CJK UNIFIED IDEOGRAPH + {0xAF78, 0x77E9}, //2193 #CJK UNIFIED IDEOGRAPH + {0xAF79, 0x7830}, //2194 #CJK UNIFIED IDEOGRAPH + {0xAF7A, 0x7827}, //2195 #CJK UNIFIED IDEOGRAPH + {0xAF7B, 0x7838}, //2196 #CJK UNIFIED IDEOGRAPH + {0xAF7C, 0x781D}, //2197 #CJK UNIFIED IDEOGRAPH + {0xAF7D, 0x7834}, //2198 #CJK UNIFIED IDEOGRAPH + {0xAF7E, 0x7837}, //2199 #CJK UNIFIED IDEOGRAPH + {0xAFA1, 0x7825}, //2200 #CJK UNIFIED IDEOGRAPH + {0xAFA2, 0x782D}, //2201 #CJK UNIFIED IDEOGRAPH + {0xAFA3, 0x7820}, //2202 #CJK UNIFIED IDEOGRAPH + {0xAFA4, 0x781F}, //2203 #CJK UNIFIED IDEOGRAPH + {0xAFA5, 0x7832}, //2204 #CJK UNIFIED IDEOGRAPH + {0xAFA6, 0x7955}, //2205 #CJK UNIFIED IDEOGRAPH + {0xAFA7, 0x7950}, //2206 #CJK UNIFIED IDEOGRAPH + {0xAFA8, 0x7960}, //2207 #CJK UNIFIED IDEOGRAPH + {0xAFA9, 0x795F}, //2208 #CJK UNIFIED IDEOGRAPH + {0xAFAA, 0x7956}, //2209 #CJK UNIFIED IDEOGRAPH + {0xAFAB, 0x795E}, //2210 #CJK UNIFIED IDEOGRAPH + {0xAFAC, 0x795D}, //2211 #CJK UNIFIED IDEOGRAPH + {0xAFAD, 0x7957}, //2212 #CJK UNIFIED IDEOGRAPH + {0xAFAE, 0x795A}, //2213 #CJK UNIFIED IDEOGRAPH + {0xAFAF, 0x79E4}, //2214 #CJK UNIFIED IDEOGRAPH + {0xAFB0, 0x79E3}, //2215 #CJK UNIFIED IDEOGRAPH + {0xAFB1, 0x79E7}, //2216 #CJK UNIFIED IDEOGRAPH + {0xAFB2, 0x79DF}, //2217 #CJK UNIFIED IDEOGRAPH + {0xAFB3, 0x79E6}, //2218 #CJK UNIFIED IDEOGRAPH + {0xAFB4, 0x79E9}, //2219 #CJK UNIFIED IDEOGRAPH + {0xAFB5, 0x79D8}, //2220 #CJK UNIFIED IDEOGRAPH + {0xAFB6, 0x7A84}, //2221 #CJK UNIFIED IDEOGRAPH + {0xAFB7, 0x7A88}, //2222 #CJK UNIFIED IDEOGRAPH + {0xAFB8, 0x7AD9}, //2223 #CJK UNIFIED IDEOGRAPH + {0xAFB9, 0x7B06}, //2224 #CJK UNIFIED IDEOGRAPH + {0xAFBA, 0x7B11}, //2225 #CJK UNIFIED IDEOGRAPH + {0xAFBB, 0x7C89}, //2226 #CJK UNIFIED IDEOGRAPH + {0xAFBC, 0x7D21}, //2227 #CJK UNIFIED IDEOGRAPH + {0xAFBD, 0x7D17}, //2228 #CJK UNIFIED IDEOGRAPH + {0xAFBE, 0x7D0B}, //2229 #CJK UNIFIED IDEOGRAPH + {0xAFBF, 0x7D0A}, //2230 #CJK UNIFIED IDEOGRAPH + {0xAFC0, 0x7D20}, //2231 #CJK UNIFIED IDEOGRAPH + {0xAFC1, 0x7D22}, //2232 #CJK UNIFIED IDEOGRAPH + {0xAFC2, 0x7D14}, //2233 #CJK UNIFIED IDEOGRAPH + {0xAFC3, 0x7D10}, //2234 #CJK UNIFIED IDEOGRAPH + {0xAFC4, 0x7D15}, //2235 #CJK UNIFIED IDEOGRAPH + {0xAFC5, 0x7D1A}, //2236 #CJK UNIFIED IDEOGRAPH + {0xAFC6, 0x7D1C}, //2237 #CJK UNIFIED IDEOGRAPH + {0xAFC7, 0x7D0D}, //2238 #CJK UNIFIED IDEOGRAPH + {0xAFC8, 0x7D19}, //2239 #CJK UNIFIED IDEOGRAPH + {0xAFC9, 0x7D1B}, //2240 #CJK UNIFIED IDEOGRAPH + {0xAFCA, 0x7F3A}, //2241 #CJK UNIFIED IDEOGRAPH + {0xAFCB, 0x7F5F}, //2242 #CJK UNIFIED IDEOGRAPH + {0xAFCC, 0x7F94}, //2243 #CJK UNIFIED IDEOGRAPH + {0xAFCD, 0x7FC5}, //2244 #CJK UNIFIED IDEOGRAPH + {0xAFCE, 0x7FC1}, //2245 #CJK UNIFIED IDEOGRAPH + {0xAFCF, 0x8006}, //2246 #CJK UNIFIED IDEOGRAPH + {0xAFD0, 0x8018}, //2247 #CJK UNIFIED IDEOGRAPH + {0xAFD1, 0x8015}, //2248 #CJK UNIFIED IDEOGRAPH + {0xAFD2, 0x8019}, //2249 #CJK UNIFIED IDEOGRAPH + {0xAFD3, 0x8017}, //2250 #CJK UNIFIED IDEOGRAPH + {0xAFD4, 0x803D}, //2251 #CJK UNIFIED IDEOGRAPH + {0xAFD5, 0x803F}, //2252 #CJK UNIFIED IDEOGRAPH + {0xAFD6, 0x80F1}, //2253 #CJK UNIFIED IDEOGRAPH + {0xAFD7, 0x8102}, //2254 #CJK UNIFIED IDEOGRAPH + {0xAFD8, 0x80F0}, //2255 #CJK UNIFIED IDEOGRAPH + {0xAFD9, 0x8105}, //2256 #CJK UNIFIED IDEOGRAPH + {0xAFDA, 0x80ED}, //2257 #CJK UNIFIED IDEOGRAPH + {0xAFDB, 0x80F4}, //2258 #CJK UNIFIED IDEOGRAPH + {0xAFDC, 0x8106}, //2259 #CJK UNIFIED IDEOGRAPH + {0xAFDD, 0x80F8}, //2260 #CJK UNIFIED IDEOGRAPH + {0xAFDE, 0x80F3}, //2261 #CJK UNIFIED IDEOGRAPH + {0xAFDF, 0x8108}, //2262 #CJK UNIFIED IDEOGRAPH + {0xAFE0, 0x80FD}, //2263 #CJK UNIFIED IDEOGRAPH + {0xAFE1, 0x810A}, //2264 #CJK UNIFIED IDEOGRAPH + {0xAFE2, 0x80FC}, //2265 #CJK UNIFIED IDEOGRAPH + {0xAFE3, 0x80EF}, //2266 #CJK UNIFIED IDEOGRAPH + {0xAFE4, 0x81ED}, //2267 #CJK UNIFIED IDEOGRAPH + {0xAFE5, 0x81EC}, //2268 #CJK UNIFIED IDEOGRAPH + {0xAFE6, 0x8200}, //2269 #CJK UNIFIED IDEOGRAPH + {0xAFE7, 0x8210}, //2270 #CJK UNIFIED IDEOGRAPH + {0xAFE8, 0x822A}, //2271 #CJK UNIFIED IDEOGRAPH + {0xAFE9, 0x822B}, //2272 #CJK UNIFIED IDEOGRAPH + {0xAFEA, 0x8228}, //2273 #CJK UNIFIED IDEOGRAPH + {0xAFEB, 0x822C}, //2274 #CJK UNIFIED IDEOGRAPH + {0xAFEC, 0x82BB}, //2275 #CJK UNIFIED IDEOGRAPH + {0xAFED, 0x832B}, //2276 #CJK UNIFIED IDEOGRAPH + {0xAFEE, 0x8352}, //2277 #CJK UNIFIED IDEOGRAPH + {0xAFEF, 0x8354}, //2278 #CJK UNIFIED IDEOGRAPH + {0xAFF0, 0x834A}, //2279 #CJK UNIFIED IDEOGRAPH + {0xAFF1, 0x8338}, //2280 #CJK UNIFIED IDEOGRAPH + {0xAFF2, 0x8350}, //2281 #CJK UNIFIED IDEOGRAPH + {0xAFF3, 0x8349}, //2282 #CJK UNIFIED IDEOGRAPH + {0xAFF4, 0x8335}, //2283 #CJK UNIFIED IDEOGRAPH + {0xAFF5, 0x8334}, //2284 #CJK UNIFIED IDEOGRAPH + {0xAFF6, 0x834F}, //2285 #CJK UNIFIED IDEOGRAPH + {0xAFF7, 0x8332}, //2286 #CJK UNIFIED IDEOGRAPH + {0xAFF8, 0x8339}, //2287 #CJK UNIFIED IDEOGRAPH + {0xAFF9, 0x8336}, //2288 #CJK UNIFIED IDEOGRAPH + {0xAFFA, 0x8317}, //2289 #CJK UNIFIED IDEOGRAPH + {0xAFFB, 0x8340}, //2290 #CJK UNIFIED IDEOGRAPH + {0xAFFC, 0x8331}, //2291 #CJK UNIFIED IDEOGRAPH + {0xAFFD, 0x8328}, //2292 #CJK UNIFIED IDEOGRAPH + {0xAFFE, 0x8343}, //2293 #CJK UNIFIED IDEOGRAPH + {0xB040, 0x8654}, //2294 #CJK UNIFIED IDEOGRAPH + {0xB041, 0x868A}, //2295 #CJK UNIFIED IDEOGRAPH + {0xB042, 0x86AA}, //2296 #CJK UNIFIED IDEOGRAPH + {0xB043, 0x8693}, //2297 #CJK UNIFIED IDEOGRAPH + {0xB044, 0x86A4}, //2298 #CJK UNIFIED IDEOGRAPH + {0xB045, 0x86A9}, //2299 #CJK UNIFIED IDEOGRAPH + {0xB046, 0x868C}, //2300 #CJK UNIFIED IDEOGRAPH + {0xB047, 0x86A3}, //2301 #CJK UNIFIED IDEOGRAPH + {0xB048, 0x869C}, //2302 #CJK UNIFIED IDEOGRAPH + {0xB049, 0x8870}, //2303 #CJK UNIFIED IDEOGRAPH + {0xB04A, 0x8877}, //2304 #CJK UNIFIED IDEOGRAPH + {0xB04B, 0x8881}, //2305 #CJK UNIFIED IDEOGRAPH + {0xB04C, 0x8882}, //2306 #CJK UNIFIED IDEOGRAPH + {0xB04D, 0x887D}, //2307 #CJK UNIFIED IDEOGRAPH + {0xB04E, 0x8879}, //2308 #CJK UNIFIED IDEOGRAPH + {0xB04F, 0x8A18}, //2309 #CJK UNIFIED IDEOGRAPH + {0xB050, 0x8A10}, //2310 #CJK UNIFIED IDEOGRAPH + {0xB051, 0x8A0E}, //2311 #CJK UNIFIED IDEOGRAPH + {0xB052, 0x8A0C}, //2312 #CJK UNIFIED IDEOGRAPH + {0xB053, 0x8A15}, //2313 #CJK UNIFIED IDEOGRAPH + {0xB054, 0x8A0A}, //2314 #CJK UNIFIED IDEOGRAPH + {0xB055, 0x8A17}, //2315 #CJK UNIFIED IDEOGRAPH + {0xB056, 0x8A13}, //2316 #CJK UNIFIED IDEOGRAPH + {0xB057, 0x8A16}, //2317 #CJK UNIFIED IDEOGRAPH + {0xB058, 0x8A0F}, //2318 #CJK UNIFIED IDEOGRAPH + {0xB059, 0x8A11}, //2319 #CJK UNIFIED IDEOGRAPH + {0xB05A, 0x8C48}, //2320 #CJK UNIFIED IDEOGRAPH + {0xB05B, 0x8C7A}, //2321 #CJK UNIFIED IDEOGRAPH + {0xB05C, 0x8C79}, //2322 #CJK UNIFIED IDEOGRAPH + {0xB05D, 0x8CA1}, //2323 #CJK UNIFIED IDEOGRAPH + {0xB05E, 0x8CA2}, //2324 #CJK UNIFIED IDEOGRAPH + {0xB05F, 0x8D77}, //2325 #CJK UNIFIED IDEOGRAPH + {0xB060, 0x8EAC}, //2326 #CJK UNIFIED IDEOGRAPH + {0xB061, 0x8ED2}, //2327 #CJK UNIFIED IDEOGRAPH + {0xB062, 0x8ED4}, //2328 #CJK UNIFIED IDEOGRAPH + {0xB063, 0x8ECF}, //2329 #CJK UNIFIED IDEOGRAPH + {0xB064, 0x8FB1}, //2330 #CJK UNIFIED IDEOGRAPH + {0xB065, 0x9001}, //2331 #CJK UNIFIED IDEOGRAPH + {0xB066, 0x9006}, //2332 #CJK UNIFIED IDEOGRAPH + {0xB067, 0x8FF7}, //2333 #CJK UNIFIED IDEOGRAPH + {0xB068, 0x9000}, //2334 #CJK UNIFIED IDEOGRAPH + {0xB069, 0x8FFA}, //2335 #CJK UNIFIED IDEOGRAPH + {0xB06A, 0x8FF4}, //2336 #CJK UNIFIED IDEOGRAPH + {0xB06B, 0x9003}, //2337 #CJK UNIFIED IDEOGRAPH + {0xB06C, 0x8FFD}, //2338 #CJK UNIFIED IDEOGRAPH + {0xB06D, 0x9005}, //2339 #CJK UNIFIED IDEOGRAPH + {0xB06E, 0x8FF8}, //2340 #CJK UNIFIED IDEOGRAPH + {0xB06F, 0x9095}, //2341 #CJK UNIFIED IDEOGRAPH + {0xB070, 0x90E1}, //2342 #CJK UNIFIED IDEOGRAPH + {0xB071, 0x90DD}, //2343 #CJK UNIFIED IDEOGRAPH + {0xB072, 0x90E2}, //2344 #CJK UNIFIED IDEOGRAPH + {0xB073, 0x9152}, //2345 #CJK UNIFIED IDEOGRAPH + {0xB074, 0x914D}, //2346 #CJK UNIFIED IDEOGRAPH + {0xB075, 0x914C}, //2347 #CJK UNIFIED IDEOGRAPH + {0xB076, 0x91D8}, //2348 #CJK UNIFIED IDEOGRAPH + {0xB077, 0x91DD}, //2349 #CJK UNIFIED IDEOGRAPH + {0xB078, 0x91D7}, //2350 #CJK UNIFIED IDEOGRAPH + {0xB079, 0x91DC}, //2351 #CJK UNIFIED IDEOGRAPH + {0xB07A, 0x91D9}, //2352 #CJK UNIFIED IDEOGRAPH + {0xB07B, 0x9583}, //2353 #CJK UNIFIED IDEOGRAPH + {0xB07C, 0x9662}, //2354 #CJK UNIFIED IDEOGRAPH + {0xB07D, 0x9663}, //2355 #CJK UNIFIED IDEOGRAPH + {0xB07E, 0x9661}, //2356 #CJK UNIFIED IDEOGRAPH + {0xB0A1, 0x965B}, //2357 #CJK UNIFIED IDEOGRAPH + {0xB0A2, 0x965D}, //2358 #CJK UNIFIED IDEOGRAPH + {0xB0A3, 0x9664}, //2359 #CJK UNIFIED IDEOGRAPH + {0xB0A4, 0x9658}, //2360 #CJK UNIFIED IDEOGRAPH + {0xB0A5, 0x965E}, //2361 #CJK UNIFIED IDEOGRAPH + {0xB0A6, 0x96BB}, //2362 #CJK UNIFIED IDEOGRAPH + {0xB0A7, 0x98E2}, //2363 #CJK UNIFIED IDEOGRAPH + {0xB0A8, 0x99AC}, //2364 #CJK UNIFIED IDEOGRAPH + {0xB0A9, 0x9AA8}, //2365 #CJK UNIFIED IDEOGRAPH + {0xB0AA, 0x9AD8}, //2366 #CJK UNIFIED IDEOGRAPH + {0xB0AB, 0x9B25}, //2367 #CJK UNIFIED IDEOGRAPH + {0xB0AC, 0x9B32}, //2368 #CJK UNIFIED IDEOGRAPH + {0xB0AD, 0x9B3C}, //2369 #CJK UNIFIED IDEOGRAPH + {0xB0AE, 0x4E7E}, //2370 #CJK UNIFIED IDEOGRAPH + {0xB0AF, 0x507A}, //2371 #CJK UNIFIED IDEOGRAPH + {0xB0B0, 0x507D}, //2372 #CJK UNIFIED IDEOGRAPH + {0xB0B1, 0x505C}, //2373 #CJK UNIFIED IDEOGRAPH + {0xB0B2, 0x5047}, //2374 #CJK UNIFIED IDEOGRAPH + {0xB0B3, 0x5043}, //2375 #CJK UNIFIED IDEOGRAPH + {0xB0B4, 0x504C}, //2376 #CJK UNIFIED IDEOGRAPH + {0xB0B5, 0x505A}, //2377 #CJK UNIFIED IDEOGRAPH + {0xB0B6, 0x5049}, //2378 #CJK UNIFIED IDEOGRAPH + {0xB0B7, 0x5065}, //2379 #CJK UNIFIED IDEOGRAPH + {0xB0B8, 0x5076}, //2380 #CJK UNIFIED IDEOGRAPH + {0xB0B9, 0x504E}, //2381 #CJK UNIFIED IDEOGRAPH + {0xB0BA, 0x5055}, //2382 #CJK UNIFIED IDEOGRAPH + {0xB0BB, 0x5075}, //2383 #CJK UNIFIED IDEOGRAPH + {0xB0BC, 0x5074}, //2384 #CJK UNIFIED IDEOGRAPH + {0xB0BD, 0x5077}, //2385 #CJK UNIFIED IDEOGRAPH + {0xB0BE, 0x504F}, //2386 #CJK UNIFIED IDEOGRAPH + {0xB0BF, 0x500F}, //2387 #CJK UNIFIED IDEOGRAPH + {0xB0C0, 0x506F}, //2388 #CJK UNIFIED IDEOGRAPH + {0xB0C1, 0x506D}, //2389 #CJK UNIFIED IDEOGRAPH + {0xB0C2, 0x515C}, //2390 #CJK UNIFIED IDEOGRAPH + {0xB0C3, 0x5195}, //2391 #CJK UNIFIED IDEOGRAPH + {0xB0C4, 0x51F0}, //2392 #CJK UNIFIED IDEOGRAPH + {0xB0C5, 0x526A}, //2393 #CJK UNIFIED IDEOGRAPH + {0xB0C6, 0x526F}, //2394 #CJK UNIFIED IDEOGRAPH + {0xB0C7, 0x52D2}, //2395 #CJK UNIFIED IDEOGRAPH + {0xB0C8, 0x52D9}, //2396 #CJK UNIFIED IDEOGRAPH + {0xB0C9, 0x52D8}, //2397 #CJK UNIFIED IDEOGRAPH + {0xB0CA, 0x52D5}, //2398 #CJK UNIFIED IDEOGRAPH + {0xB0CB, 0x5310}, //2399 #CJK UNIFIED IDEOGRAPH + {0xB0CC, 0x530F}, //2400 #CJK UNIFIED IDEOGRAPH + {0xB0CD, 0x5319}, //2401 #CJK UNIFIED IDEOGRAPH + {0xB0CE, 0x533F}, //2402 #CJK UNIFIED IDEOGRAPH + {0xB0CF, 0x5340}, //2403 #CJK UNIFIED IDEOGRAPH + {0xB0D0, 0x533E}, //2404 #CJK UNIFIED IDEOGRAPH + {0xB0D1, 0x53C3}, //2405 #CJK UNIFIED IDEOGRAPH + {0xB0D2, 0x66FC}, //2406 #CJK UNIFIED IDEOGRAPH + {0xB0D3, 0x5546}, //2407 #CJK UNIFIED IDEOGRAPH + {0xB0D4, 0x556A}, //2408 #CJK UNIFIED IDEOGRAPH + {0xB0D5, 0x5566}, //2409 #CJK UNIFIED IDEOGRAPH + {0xB0D6, 0x5544}, //2410 #CJK UNIFIED IDEOGRAPH + {0xB0D7, 0x555E}, //2411 #CJK UNIFIED IDEOGRAPH + {0xB0D8, 0x5561}, //2412 #CJK UNIFIED IDEOGRAPH + {0xB0D9, 0x5543}, //2413 #CJK UNIFIED IDEOGRAPH + {0xB0DA, 0x554A}, //2414 #CJK UNIFIED IDEOGRAPH + {0xB0DB, 0x5531}, //2415 #CJK UNIFIED IDEOGRAPH + {0xB0DC, 0x5556}, //2416 #CJK UNIFIED IDEOGRAPH + {0xB0DD, 0x554F}, //2417 #CJK UNIFIED IDEOGRAPH + {0xB0DE, 0x5555}, //2418 #CJK UNIFIED IDEOGRAPH + {0xB0DF, 0x552F}, //2419 #CJK UNIFIED IDEOGRAPH + {0xB0E0, 0x5564}, //2420 #CJK UNIFIED IDEOGRAPH + {0xB0E1, 0x5538}, //2421 #CJK UNIFIED IDEOGRAPH + {0xB0E2, 0x552E}, //2422 #CJK UNIFIED IDEOGRAPH + {0xB0E3, 0x555C}, //2423 #CJK UNIFIED IDEOGRAPH + {0xB0E4, 0x552C}, //2424 #CJK UNIFIED IDEOGRAPH + {0xB0E5, 0x5563}, //2425 #CJK UNIFIED IDEOGRAPH + {0xB0E6, 0x5533}, //2426 #CJK UNIFIED IDEOGRAPH + {0xB0E7, 0x5541}, //2427 #CJK UNIFIED IDEOGRAPH + {0xB0E8, 0x5557}, //2428 #CJK UNIFIED IDEOGRAPH + {0xB0E9, 0x5708}, //2429 #CJK UNIFIED IDEOGRAPH + {0xB0EA, 0x570B}, //2430 #CJK UNIFIED IDEOGRAPH + {0xB0EB, 0x5709}, //2431 #CJK UNIFIED IDEOGRAPH + {0xB0EC, 0x57DF}, //2432 #CJK UNIFIED IDEOGRAPH + {0xB0ED, 0x5805}, //2433 #CJK UNIFIED IDEOGRAPH + {0xB0EE, 0x580A}, //2434 #CJK UNIFIED IDEOGRAPH + {0xB0EF, 0x5806}, //2435 #CJK UNIFIED IDEOGRAPH + {0xB0F0, 0x57E0}, //2436 #CJK UNIFIED IDEOGRAPH + {0xB0F1, 0x57E4}, //2437 #CJK UNIFIED IDEOGRAPH + {0xB0F2, 0x57FA}, //2438 #CJK UNIFIED IDEOGRAPH + {0xB0F3, 0x5802}, //2439 #CJK UNIFIED IDEOGRAPH + {0xB0F4, 0x5835}, //2440 #CJK UNIFIED IDEOGRAPH + {0xB0F5, 0x57F7}, //2441 #CJK UNIFIED IDEOGRAPH + {0xB0F6, 0x57F9}, //2442 #CJK UNIFIED IDEOGRAPH + {0xB0F7, 0x5920}, //2443 #CJK UNIFIED IDEOGRAPH + {0xB0F8, 0x5962}, //2444 #CJK UNIFIED IDEOGRAPH + {0xB0F9, 0x5A36}, //2445 #CJK UNIFIED IDEOGRAPH + {0xB0FA, 0x5A41}, //2446 #CJK UNIFIED IDEOGRAPH + {0xB0FB, 0x5A49}, //2447 #CJK UNIFIED IDEOGRAPH + {0xB0FC, 0x5A66}, //2448 #CJK UNIFIED IDEOGRAPH + {0xB0FD, 0x5A6A}, //2449 #CJK UNIFIED IDEOGRAPH + {0xB0FE, 0x5A40}, //2450 #CJK UNIFIED IDEOGRAPH + {0xB140, 0x5A3C}, //2451 #CJK UNIFIED IDEOGRAPH + {0xB141, 0x5A62}, //2452 #CJK UNIFIED IDEOGRAPH + {0xB142, 0x5A5A}, //2453 #CJK UNIFIED IDEOGRAPH + {0xB143, 0x5A46}, //2454 #CJK UNIFIED IDEOGRAPH + {0xB144, 0x5A4A}, //2455 #CJK UNIFIED IDEOGRAPH + {0xB145, 0x5B70}, //2456 #CJK UNIFIED IDEOGRAPH + {0xB146, 0x5BC7}, //2457 #CJK UNIFIED IDEOGRAPH + {0xB147, 0x5BC5}, //2458 #CJK UNIFIED IDEOGRAPH + {0xB148, 0x5BC4}, //2459 #CJK UNIFIED IDEOGRAPH + {0xB149, 0x5BC2}, //2460 #CJK UNIFIED IDEOGRAPH + {0xB14A, 0x5BBF}, //2461 #CJK UNIFIED IDEOGRAPH + {0xB14B, 0x5BC6}, //2462 #CJK UNIFIED IDEOGRAPH + {0xB14C, 0x5C09}, //2463 #CJK UNIFIED IDEOGRAPH + {0xB14D, 0x5C08}, //2464 #CJK UNIFIED IDEOGRAPH + {0xB14E, 0x5C07}, //2465 #CJK UNIFIED IDEOGRAPH + {0xB14F, 0x5C60}, //2466 #CJK UNIFIED IDEOGRAPH + {0xB150, 0x5C5C}, //2467 #CJK UNIFIED IDEOGRAPH + {0xB151, 0x5C5D}, //2468 #CJK UNIFIED IDEOGRAPH + {0xB152, 0x5D07}, //2469 #CJK UNIFIED IDEOGRAPH + {0xB153, 0x5D06}, //2470 #CJK UNIFIED IDEOGRAPH + {0xB154, 0x5D0E}, //2471 #CJK UNIFIED IDEOGRAPH + {0xB155, 0x5D1B}, //2472 #CJK UNIFIED IDEOGRAPH + {0xB156, 0x5D16}, //2473 #CJK UNIFIED IDEOGRAPH + {0xB157, 0x5D22}, //2474 #CJK UNIFIED IDEOGRAPH + {0xB158, 0x5D11}, //2475 #CJK UNIFIED IDEOGRAPH + {0xB159, 0x5D29}, //2476 #CJK UNIFIED IDEOGRAPH + {0xB15A, 0x5D14}, //2477 #CJK UNIFIED IDEOGRAPH + {0xB15B, 0x5D19}, //2478 #CJK UNIFIED IDEOGRAPH + {0xB15C, 0x5D24}, //2479 #CJK UNIFIED IDEOGRAPH + {0xB15D, 0x5D27}, //2480 #CJK UNIFIED IDEOGRAPH + {0xB15E, 0x5D17}, //2481 #CJK UNIFIED IDEOGRAPH + {0xB15F, 0x5DE2}, //2482 #CJK UNIFIED IDEOGRAPH + {0xB160, 0x5E38}, //2483 #CJK UNIFIED IDEOGRAPH + {0xB161, 0x5E36}, //2484 #CJK UNIFIED IDEOGRAPH + {0xB162, 0x5E33}, //2485 #CJK UNIFIED IDEOGRAPH + {0xB163, 0x5E37}, //2486 #CJK UNIFIED IDEOGRAPH + {0xB164, 0x5EB7}, //2487 #CJK UNIFIED IDEOGRAPH + {0xB165, 0x5EB8}, //2488 #CJK UNIFIED IDEOGRAPH + {0xB166, 0x5EB6}, //2489 #CJK UNIFIED IDEOGRAPH + {0xB167, 0x5EB5}, //2490 #CJK UNIFIED IDEOGRAPH + {0xB168, 0x5EBE}, //2491 #CJK UNIFIED IDEOGRAPH + {0xB169, 0x5F35}, //2492 #CJK UNIFIED IDEOGRAPH + {0xB16A, 0x5F37}, //2493 #CJK UNIFIED IDEOGRAPH + {0xB16B, 0x5F57}, //2494 #CJK UNIFIED IDEOGRAPH + {0xB16C, 0x5F6C}, //2495 #CJK UNIFIED IDEOGRAPH + {0xB16D, 0x5F69}, //2496 #CJK UNIFIED IDEOGRAPH + {0xB16E, 0x5F6B}, //2497 #CJK UNIFIED IDEOGRAPH + {0xB16F, 0x5F97}, //2498 #CJK UNIFIED IDEOGRAPH + {0xB170, 0x5F99}, //2499 #CJK UNIFIED IDEOGRAPH + {0xB171, 0x5F9E}, //2500 #CJK UNIFIED IDEOGRAPH + {0xB172, 0x5F98}, //2501 #CJK UNIFIED IDEOGRAPH + {0xB173, 0x5FA1}, //2502 #CJK UNIFIED IDEOGRAPH + {0xB174, 0x5FA0}, //2503 #CJK UNIFIED IDEOGRAPH + {0xB175, 0x5F9C}, //2504 #CJK UNIFIED IDEOGRAPH + {0xB176, 0x607F}, //2505 #CJK UNIFIED IDEOGRAPH + {0xB177, 0x60A3}, //2506 #CJK UNIFIED IDEOGRAPH + {0xB178, 0x6089}, //2507 #CJK UNIFIED IDEOGRAPH + {0xB179, 0x60A0}, //2508 #CJK UNIFIED IDEOGRAPH + {0xB17A, 0x60A8}, //2509 #CJK UNIFIED IDEOGRAPH + {0xB17B, 0x60CB}, //2510 #CJK UNIFIED IDEOGRAPH + {0xB17C, 0x60B4}, //2511 #CJK UNIFIED IDEOGRAPH + {0xB17D, 0x60E6}, //2512 #CJK UNIFIED IDEOGRAPH + {0xB17E, 0x60BD}, //2513 #CJK UNIFIED IDEOGRAPH + {0xB1A1, 0x60C5}, //2514 #CJK UNIFIED IDEOGRAPH + {0xB1A2, 0x60BB}, //2515 #CJK UNIFIED IDEOGRAPH + {0xB1A3, 0x60B5}, //2516 #CJK UNIFIED IDEOGRAPH + {0xB1A4, 0x60DC}, //2517 #CJK UNIFIED IDEOGRAPH + {0xB1A5, 0x60BC}, //2518 #CJK UNIFIED IDEOGRAPH + {0xB1A6, 0x60D8}, //2519 #CJK UNIFIED IDEOGRAPH + {0xB1A7, 0x60D5}, //2520 #CJK UNIFIED IDEOGRAPH + {0xB1A8, 0x60C6}, //2521 #CJK UNIFIED IDEOGRAPH + {0xB1A9, 0x60DF}, //2522 #CJK UNIFIED IDEOGRAPH + {0xB1AA, 0x60B8}, //2523 #CJK UNIFIED IDEOGRAPH + {0xB1AB, 0x60DA}, //2524 #CJK UNIFIED IDEOGRAPH + {0xB1AC, 0x60C7}, //2525 #CJK UNIFIED IDEOGRAPH + {0xB1AD, 0x621A}, //2526 #CJK UNIFIED IDEOGRAPH + {0xB1AE, 0x621B}, //2527 #CJK UNIFIED IDEOGRAPH + {0xB1AF, 0x6248}, //2528 #CJK UNIFIED IDEOGRAPH + {0xB1B0, 0x63A0}, //2529 #CJK UNIFIED IDEOGRAPH + {0xB1B1, 0x63A7}, //2530 #CJK UNIFIED IDEOGRAPH + {0xB1B2, 0x6372}, //2531 #CJK UNIFIED IDEOGRAPH + {0xB1B3, 0x6396}, //2532 #CJK UNIFIED IDEOGRAPH + {0xB1B4, 0x63A2}, //2533 #CJK UNIFIED IDEOGRAPH + {0xB1B5, 0x63A5}, //2534 #CJK UNIFIED IDEOGRAPH + {0xB1B6, 0x6377}, //2535 #CJK UNIFIED IDEOGRAPH + {0xB1B7, 0x6367}, //2536 #CJK UNIFIED IDEOGRAPH + {0xB1B8, 0x6398}, //2537 #CJK UNIFIED IDEOGRAPH + {0xB1B9, 0x63AA}, //2538 #CJK UNIFIED IDEOGRAPH + {0xB1BA, 0x6371}, //2539 #CJK UNIFIED IDEOGRAPH + {0xB1BB, 0x63A9}, //2540 #CJK UNIFIED IDEOGRAPH + {0xB1BC, 0x6389}, //2541 #CJK UNIFIED IDEOGRAPH + {0xB1BD, 0x6383}, //2542 #CJK UNIFIED IDEOGRAPH + {0xB1BE, 0x639B}, //2543 #CJK UNIFIED IDEOGRAPH + {0xB1BF, 0x636B}, //2544 #CJK UNIFIED IDEOGRAPH + {0xB1C0, 0x63A8}, //2545 #CJK UNIFIED IDEOGRAPH + {0xB1C1, 0x6384}, //2546 #CJK UNIFIED IDEOGRAPH + {0xB1C2, 0x6388}, //2547 #CJK UNIFIED IDEOGRAPH + {0xB1C3, 0x6399}, //2548 #CJK UNIFIED IDEOGRAPH + {0xB1C4, 0x63A1}, //2549 #CJK UNIFIED IDEOGRAPH + {0xB1C5, 0x63AC}, //2550 #CJK UNIFIED IDEOGRAPH + {0xB1C6, 0x6392}, //2551 #CJK UNIFIED IDEOGRAPH + {0xB1C7, 0x638F}, //2552 #CJK UNIFIED IDEOGRAPH + {0xB1C8, 0x6380}, //2553 #CJK UNIFIED IDEOGRAPH + {0xB1C9, 0x637B}, //2554 #CJK UNIFIED IDEOGRAPH + {0xB1CA, 0x6369}, //2555 #CJK UNIFIED IDEOGRAPH + {0xB1CB, 0x6368}, //2556 #CJK UNIFIED IDEOGRAPH + {0xB1CC, 0x637A}, //2557 #CJK UNIFIED IDEOGRAPH + {0xB1CD, 0x655D}, //2558 #CJK UNIFIED IDEOGRAPH + {0xB1CE, 0x6556}, //2559 #CJK UNIFIED IDEOGRAPH + {0xB1CF, 0x6551}, //2560 #CJK UNIFIED IDEOGRAPH + {0xB1D0, 0x6559}, //2561 #CJK UNIFIED IDEOGRAPH + {0xB1D1, 0x6557}, //2562 #CJK UNIFIED IDEOGRAPH + {0xB1D2, 0x555F}, //2563 #CJK UNIFIED IDEOGRAPH + {0xB1D3, 0x654F}, //2564 #CJK UNIFIED IDEOGRAPH + {0xB1D4, 0x6558}, //2565 #CJK UNIFIED IDEOGRAPH + {0xB1D5, 0x6555}, //2566 #CJK UNIFIED IDEOGRAPH + {0xB1D6, 0x6554}, //2567 #CJK UNIFIED IDEOGRAPH + {0xB1D7, 0x659C}, //2568 #CJK UNIFIED IDEOGRAPH + {0xB1D8, 0x659B}, //2569 #CJK UNIFIED IDEOGRAPH + {0xB1D9, 0x65AC}, //2570 #CJK UNIFIED IDEOGRAPH + {0xB1DA, 0x65CF}, //2571 #CJK UNIFIED IDEOGRAPH + {0xB1DB, 0x65CB}, //2572 #CJK UNIFIED IDEOGRAPH + {0xB1DC, 0x65CC}, //2573 #CJK UNIFIED IDEOGRAPH + {0xB1DD, 0x65CE}, //2574 #CJK UNIFIED IDEOGRAPH + {0xB1DE, 0x665D}, //2575 #CJK UNIFIED IDEOGRAPH + {0xB1DF, 0x665A}, //2576 #CJK UNIFIED IDEOGRAPH + {0xB1E0, 0x6664}, //2577 #CJK UNIFIED IDEOGRAPH + {0xB1E1, 0x6668}, //2578 #CJK UNIFIED IDEOGRAPH + {0xB1E2, 0x6666}, //2579 #CJK UNIFIED IDEOGRAPH + {0xB1E3, 0x665E}, //2580 #CJK UNIFIED IDEOGRAPH + {0xB1E4, 0x66F9}, //2581 #CJK UNIFIED IDEOGRAPH + {0xB1E5, 0x52D7}, //2582 #CJK UNIFIED IDEOGRAPH + {0xB1E6, 0x671B}, //2583 #CJK UNIFIED IDEOGRAPH + {0xB1E7, 0x6881}, //2584 #CJK UNIFIED IDEOGRAPH + {0xB1E8, 0x68AF}, //2585 #CJK UNIFIED IDEOGRAPH + {0xB1E9, 0x68A2}, //2586 #CJK UNIFIED IDEOGRAPH + {0xB1EA, 0x6893}, //2587 #CJK UNIFIED IDEOGRAPH + {0xB1EB, 0x68B5}, //2588 #CJK UNIFIED IDEOGRAPH + {0xB1EC, 0x687F}, //2589 #CJK UNIFIED IDEOGRAPH + {0xB1ED, 0x6876}, //2590 #CJK UNIFIED IDEOGRAPH + {0xB1EE, 0x68B1}, //2591 #CJK UNIFIED IDEOGRAPH + {0xB1EF, 0x68A7}, //2592 #CJK UNIFIED IDEOGRAPH + {0xB1F0, 0x6897}, //2593 #CJK UNIFIED IDEOGRAPH + {0xB1F1, 0x68B0}, //2594 #CJK UNIFIED IDEOGRAPH + {0xB1F2, 0x6883}, //2595 #CJK UNIFIED IDEOGRAPH + {0xB1F3, 0x68C4}, //2596 #CJK UNIFIED IDEOGRAPH + {0xB1F4, 0x68AD}, //2597 #CJK UNIFIED IDEOGRAPH + {0xB1F5, 0x6886}, //2598 #CJK UNIFIED IDEOGRAPH + {0xB1F6, 0x6885}, //2599 #CJK UNIFIED IDEOGRAPH + {0xB1F7, 0x6894}, //2600 #CJK UNIFIED IDEOGRAPH + {0xB1F8, 0x689D}, //2601 #CJK UNIFIED IDEOGRAPH + {0xB1F9, 0x68A8}, //2602 #CJK UNIFIED IDEOGRAPH + {0xB1FA, 0x689F}, //2603 #CJK UNIFIED IDEOGRAPH + {0xB1FB, 0x68A1}, //2604 #CJK UNIFIED IDEOGRAPH + {0xB1FC, 0x6882}, //2605 #CJK UNIFIED IDEOGRAPH + {0xB1FD, 0x6B32}, //2606 #CJK UNIFIED IDEOGRAPH + {0xB1FE, 0x6BBA}, //2607 #CJK UNIFIED IDEOGRAPH + {0xB240, 0x6BEB}, //2608 #CJK UNIFIED IDEOGRAPH + {0xB241, 0x6BEC}, //2609 #CJK UNIFIED IDEOGRAPH + {0xB242, 0x6C2B}, //2610 #CJK UNIFIED IDEOGRAPH + {0xB243, 0x6D8E}, //2611 #CJK UNIFIED IDEOGRAPH + {0xB244, 0x6DBC}, //2612 #CJK UNIFIED IDEOGRAPH + {0xB245, 0x6DF3}, //2613 #CJK UNIFIED IDEOGRAPH + {0xB246, 0x6DD9}, //2614 #CJK UNIFIED IDEOGRAPH + {0xB247, 0x6DB2}, //2615 #CJK UNIFIED IDEOGRAPH + {0xB248, 0x6DE1}, //2616 #CJK UNIFIED IDEOGRAPH + {0xB249, 0x6DCC}, //2617 #CJK UNIFIED IDEOGRAPH + {0xB24A, 0x6DE4}, //2618 #CJK UNIFIED IDEOGRAPH + {0xB24B, 0x6DFB}, //2619 #CJK UNIFIED IDEOGRAPH + {0xB24C, 0x6DFA}, //2620 #CJK UNIFIED IDEOGRAPH + {0xB24D, 0x6E05}, //2621 #CJK UNIFIED IDEOGRAPH + {0xB24E, 0x6DC7}, //2622 #CJK UNIFIED IDEOGRAPH + {0xB24F, 0x6DCB}, //2623 #CJK UNIFIED IDEOGRAPH + {0xB250, 0x6DAF}, //2624 #CJK UNIFIED IDEOGRAPH + {0xB251, 0x6DD1}, //2625 #CJK UNIFIED IDEOGRAPH + {0xB252, 0x6DAE}, //2626 #CJK UNIFIED IDEOGRAPH + {0xB253, 0x6DDE}, //2627 #CJK UNIFIED IDEOGRAPH + {0xB254, 0x6DF9}, //2628 #CJK UNIFIED IDEOGRAPH + {0xB255, 0x6DB8}, //2629 #CJK UNIFIED IDEOGRAPH + {0xB256, 0x6DF7}, //2630 #CJK UNIFIED IDEOGRAPH + {0xB257, 0x6DF5}, //2631 #CJK UNIFIED IDEOGRAPH + {0xB258, 0x6DC5}, //2632 #CJK UNIFIED IDEOGRAPH + {0xB259, 0x6DD2}, //2633 #CJK UNIFIED IDEOGRAPH + {0xB25A, 0x6E1A}, //2634 #CJK UNIFIED IDEOGRAPH + {0xB25B, 0x6DB5}, //2635 #CJK UNIFIED IDEOGRAPH + {0xB25C, 0x6DDA}, //2636 #CJK UNIFIED IDEOGRAPH + {0xB25D, 0x6DEB}, //2637 #CJK UNIFIED IDEOGRAPH + {0xB25E, 0x6DD8}, //2638 #CJK UNIFIED IDEOGRAPH + {0xB25F, 0x6DEA}, //2639 #CJK UNIFIED IDEOGRAPH + {0xB260, 0x6DF1}, //2640 #CJK UNIFIED IDEOGRAPH + {0xB261, 0x6DEE}, //2641 #CJK UNIFIED IDEOGRAPH + {0xB262, 0x6DE8}, //2642 #CJK UNIFIED IDEOGRAPH + {0xB263, 0x6DC6}, //2643 #CJK UNIFIED IDEOGRAPH + {0xB264, 0x6DC4}, //2644 #CJK UNIFIED IDEOGRAPH + {0xB265, 0x6DAA}, //2645 #CJK UNIFIED IDEOGRAPH + {0xB266, 0x6DEC}, //2646 #CJK UNIFIED IDEOGRAPH + {0xB267, 0x6DBF}, //2647 #CJK UNIFIED IDEOGRAPH + {0xB268, 0x6DE6}, //2648 #CJK UNIFIED IDEOGRAPH + {0xB269, 0x70F9}, //2649 #CJK UNIFIED IDEOGRAPH + {0xB26A, 0x7109}, //2650 #CJK UNIFIED IDEOGRAPH + {0xB26B, 0x710A}, //2651 #CJK UNIFIED IDEOGRAPH + {0xB26C, 0x70FD}, //2652 #CJK UNIFIED IDEOGRAPH + {0xB26D, 0x70EF}, //2653 #CJK UNIFIED IDEOGRAPH + {0xB26E, 0x723D}, //2654 #CJK UNIFIED IDEOGRAPH + {0xB26F, 0x727D}, //2655 #CJK UNIFIED IDEOGRAPH + {0xB270, 0x7281}, //2656 #CJK UNIFIED IDEOGRAPH + {0xB271, 0x731C}, //2657 #CJK UNIFIED IDEOGRAPH + {0xB272, 0x731B}, //2658 #CJK UNIFIED IDEOGRAPH + {0xB273, 0x7316}, //2659 #CJK UNIFIED IDEOGRAPH + {0xB274, 0x7313}, //2660 #CJK UNIFIED IDEOGRAPH + {0xB275, 0x7319}, //2661 #CJK UNIFIED IDEOGRAPH + {0xB276, 0x7387}, //2662 #CJK UNIFIED IDEOGRAPH + {0xB277, 0x7405}, //2663 #CJK UNIFIED IDEOGRAPH + {0xB278, 0x740A}, //2664 #CJK UNIFIED IDEOGRAPH + {0xB279, 0x7403}, //2665 #CJK UNIFIED IDEOGRAPH + {0xB27A, 0x7406}, //2666 #CJK UNIFIED IDEOGRAPH + {0xB27B, 0x73FE}, //2667 #CJK UNIFIED IDEOGRAPH + {0xB27C, 0x740D}, //2668 #CJK UNIFIED IDEOGRAPH + {0xB27D, 0x74E0}, //2669 #CJK UNIFIED IDEOGRAPH + {0xB27E, 0x74F6}, //2670 #CJK UNIFIED IDEOGRAPH + {0xB2A1, 0x74F7}, //2671 #CJK UNIFIED IDEOGRAPH + {0xB2A2, 0x751C}, //2672 #CJK UNIFIED IDEOGRAPH + {0xB2A3, 0x7522}, //2673 #CJK UNIFIED IDEOGRAPH + {0xB2A4, 0x7565}, //2674 #CJK UNIFIED IDEOGRAPH + {0xB2A5, 0x7566}, //2675 #CJK UNIFIED IDEOGRAPH + {0xB2A6, 0x7562}, //2676 #CJK UNIFIED IDEOGRAPH + {0xB2A7, 0x7570}, //2677 #CJK UNIFIED IDEOGRAPH + {0xB2A8, 0x758F}, //2678 #CJK UNIFIED IDEOGRAPH + {0xB2A9, 0x75D4}, //2679 #CJK UNIFIED IDEOGRAPH + {0xB2AA, 0x75D5}, //2680 #CJK UNIFIED IDEOGRAPH + {0xB2AB, 0x75B5}, //2681 #CJK UNIFIED IDEOGRAPH + {0xB2AC, 0x75CA}, //2682 #CJK UNIFIED IDEOGRAPH + {0xB2AD, 0x75CD}, //2683 #CJK UNIFIED IDEOGRAPH + {0xB2AE, 0x768E}, //2684 #CJK UNIFIED IDEOGRAPH + {0xB2AF, 0x76D4}, //2685 #CJK UNIFIED IDEOGRAPH + {0xB2B0, 0x76D2}, //2686 #CJK UNIFIED IDEOGRAPH + {0xB2B1, 0x76DB}, //2687 #CJK UNIFIED IDEOGRAPH + {0xB2B2, 0x7737}, //2688 #CJK UNIFIED IDEOGRAPH + {0xB2B3, 0x773E}, //2689 #CJK UNIFIED IDEOGRAPH + {0xB2B4, 0x773C}, //2690 #CJK UNIFIED IDEOGRAPH + {0xB2B5, 0x7736}, //2691 #CJK UNIFIED IDEOGRAPH + {0xB2B6, 0x7738}, //2692 #CJK UNIFIED IDEOGRAPH + {0xB2B7, 0x773A}, //2693 #CJK UNIFIED IDEOGRAPH + {0xB2B8, 0x786B}, //2694 #CJK UNIFIED IDEOGRAPH + {0xB2B9, 0x7843}, //2695 #CJK UNIFIED IDEOGRAPH + {0xB2BA, 0x784E}, //2696 #CJK UNIFIED IDEOGRAPH + {0xB2BB, 0x7965}, //2697 #CJK UNIFIED IDEOGRAPH + {0xB2BC, 0x7968}, //2698 #CJK UNIFIED IDEOGRAPH + {0xB2BD, 0x796D}, //2699 #CJK UNIFIED IDEOGRAPH + {0xB2BE, 0x79FB}, //2700 #CJK UNIFIED IDEOGRAPH + {0xB2BF, 0x7A92}, //2701 #CJK UNIFIED IDEOGRAPH + {0xB2C0, 0x7A95}, //2702 #CJK UNIFIED IDEOGRAPH + {0xB2C1, 0x7B20}, //2703 #CJK UNIFIED IDEOGRAPH + {0xB2C2, 0x7B28}, //2704 #CJK UNIFIED IDEOGRAPH + {0xB2C3, 0x7B1B}, //2705 #CJK UNIFIED IDEOGRAPH + {0xB2C4, 0x7B2C}, //2706 #CJK UNIFIED IDEOGRAPH + {0xB2C5, 0x7B26}, //2707 #CJK UNIFIED IDEOGRAPH + {0xB2C6, 0x7B19}, //2708 #CJK UNIFIED IDEOGRAPH + {0xB2C7, 0x7B1E}, //2709 #CJK UNIFIED IDEOGRAPH + {0xB2C8, 0x7B2E}, //2710 #CJK UNIFIED IDEOGRAPH + {0xB2C9, 0x7C92}, //2711 #CJK UNIFIED IDEOGRAPH + {0xB2CA, 0x7C97}, //2712 #CJK UNIFIED IDEOGRAPH + {0xB2CB, 0x7C95}, //2713 #CJK UNIFIED IDEOGRAPH + {0xB2CC, 0x7D46}, //2714 #CJK UNIFIED IDEOGRAPH + {0xB2CD, 0x7D43}, //2715 #CJK UNIFIED IDEOGRAPH + {0xB2CE, 0x7D71}, //2716 #CJK UNIFIED IDEOGRAPH + {0xB2CF, 0x7D2E}, //2717 #CJK UNIFIED IDEOGRAPH + {0xB2D0, 0x7D39}, //2718 #CJK UNIFIED IDEOGRAPH + {0xB2D1, 0x7D3C}, //2719 #CJK UNIFIED IDEOGRAPH + {0xB2D2, 0x7D40}, //2720 #CJK UNIFIED IDEOGRAPH + {0xB2D3, 0x7D30}, //2721 #CJK UNIFIED IDEOGRAPH + {0xB2D4, 0x7D33}, //2722 #CJK UNIFIED IDEOGRAPH + {0xB2D5, 0x7D44}, //2723 #CJK UNIFIED IDEOGRAPH + {0xB2D6, 0x7D2F}, //2724 #CJK UNIFIED IDEOGRAPH + {0xB2D7, 0x7D42}, //2725 #CJK UNIFIED IDEOGRAPH + {0xB2D8, 0x7D32}, //2726 #CJK UNIFIED IDEOGRAPH + {0xB2D9, 0x7D31}, //2727 #CJK UNIFIED IDEOGRAPH + {0xB2DA, 0x7F3D}, //2728 #CJK UNIFIED IDEOGRAPH + {0xB2DB, 0x7F9E}, //2729 #CJK UNIFIED IDEOGRAPH + {0xB2DC, 0x7F9A}, //2730 #CJK UNIFIED IDEOGRAPH + {0xB2DD, 0x7FCC}, //2731 #CJK UNIFIED IDEOGRAPH + {0xB2DE, 0x7FCE}, //2732 #CJK UNIFIED IDEOGRAPH + {0xB2DF, 0x7FD2}, //2733 #CJK UNIFIED IDEOGRAPH + {0xB2E0, 0x801C}, //2734 #CJK UNIFIED IDEOGRAPH + {0xB2E1, 0x804A}, //2735 #CJK UNIFIED IDEOGRAPH + {0xB2E2, 0x8046}, //2736 #CJK UNIFIED IDEOGRAPH + {0xB2E3, 0x812F}, //2737 #CJK UNIFIED IDEOGRAPH + {0xB2E4, 0x8116}, //2738 #CJK UNIFIED IDEOGRAPH + {0xB2E5, 0x8123}, //2739 #CJK UNIFIED IDEOGRAPH + {0xB2E6, 0x812B}, //2740 #CJK UNIFIED IDEOGRAPH + {0xB2E7, 0x8129}, //2741 #CJK UNIFIED IDEOGRAPH + {0xB2E8, 0x8130}, //2742 #CJK UNIFIED IDEOGRAPH + {0xB2E9, 0x8124}, //2743 #CJK UNIFIED IDEOGRAPH + {0xB2EA, 0x8202}, //2744 #CJK UNIFIED IDEOGRAPH + {0xB2EB, 0x8235}, //2745 #CJK UNIFIED IDEOGRAPH + {0xB2EC, 0x8237}, //2746 #CJK UNIFIED IDEOGRAPH + {0xB2ED, 0x8236}, //2747 #CJK UNIFIED IDEOGRAPH + {0xB2EE, 0x8239}, //2748 #CJK UNIFIED IDEOGRAPH + {0xB2EF, 0x838E}, //2749 #CJK UNIFIED IDEOGRAPH + {0xB2F0, 0x839E}, //2750 #CJK UNIFIED IDEOGRAPH + {0xB2F1, 0x8398}, //2751 #CJK UNIFIED IDEOGRAPH + {0xB2F2, 0x8378}, //2752 #CJK UNIFIED IDEOGRAPH + {0xB2F3, 0x83A2}, //2753 #CJK UNIFIED IDEOGRAPH + {0xB2F4, 0x8396}, //2754 #CJK UNIFIED IDEOGRAPH + {0xB2F5, 0x83BD}, //2755 #CJK UNIFIED IDEOGRAPH + {0xB2F6, 0x83AB}, //2756 #CJK UNIFIED IDEOGRAPH + {0xB2F7, 0x8392}, //2757 #CJK UNIFIED IDEOGRAPH + {0xB2F8, 0x838A}, //2758 #CJK UNIFIED IDEOGRAPH + {0xB2F9, 0x8393}, //2759 #CJK UNIFIED IDEOGRAPH + {0xB2FA, 0x8389}, //2760 #CJK UNIFIED IDEOGRAPH + {0xB2FB, 0x83A0}, //2761 #CJK UNIFIED IDEOGRAPH + {0xB2FC, 0x8377}, //2762 #CJK UNIFIED IDEOGRAPH + {0xB2FD, 0x837B}, //2763 #CJK UNIFIED IDEOGRAPH + {0xB2FE, 0x837C}, //2764 #CJK UNIFIED IDEOGRAPH + {0xB340, 0x8386}, //2765 #CJK UNIFIED IDEOGRAPH + {0xB341, 0x83A7}, //2766 #CJK UNIFIED IDEOGRAPH + {0xB342, 0x8655}, //2767 #CJK UNIFIED IDEOGRAPH + {0xB343, 0x5F6A}, //2768 #CJK UNIFIED IDEOGRAPH + {0xB344, 0x86C7}, //2769 #CJK UNIFIED IDEOGRAPH + {0xB345, 0x86C0}, //2770 #CJK UNIFIED IDEOGRAPH + {0xB346, 0x86B6}, //2771 #CJK UNIFIED IDEOGRAPH + {0xB347, 0x86C4}, //2772 #CJK UNIFIED IDEOGRAPH + {0xB348, 0x86B5}, //2773 #CJK UNIFIED IDEOGRAPH + {0xB349, 0x86C6}, //2774 #CJK UNIFIED IDEOGRAPH + {0xB34A, 0x86CB}, //2775 #CJK UNIFIED IDEOGRAPH + {0xB34B, 0x86B1}, //2776 #CJK UNIFIED IDEOGRAPH + {0xB34C, 0x86AF}, //2777 #CJK UNIFIED IDEOGRAPH + {0xB34D, 0x86C9}, //2778 #CJK UNIFIED IDEOGRAPH + {0xB34E, 0x8853}, //2779 #CJK UNIFIED IDEOGRAPH + {0xB34F, 0x889E}, //2780 #CJK UNIFIED IDEOGRAPH + {0xB350, 0x8888}, //2781 #CJK UNIFIED IDEOGRAPH + {0xB351, 0x88AB}, //2782 #CJK UNIFIED IDEOGRAPH + {0xB352, 0x8892}, //2783 #CJK UNIFIED IDEOGRAPH + {0xB353, 0x8896}, //2784 #CJK UNIFIED IDEOGRAPH + {0xB354, 0x888D}, //2785 #CJK UNIFIED IDEOGRAPH + {0xB355, 0x888B}, //2786 #CJK UNIFIED IDEOGRAPH + {0xB356, 0x8993}, //2787 #CJK UNIFIED IDEOGRAPH + {0xB357, 0x898F}, //2788 #CJK UNIFIED IDEOGRAPH + {0xB358, 0x8A2A}, //2789 #CJK UNIFIED IDEOGRAPH + {0xB359, 0x8A1D}, //2790 #CJK UNIFIED IDEOGRAPH + {0xB35A, 0x8A23}, //2791 #CJK UNIFIED IDEOGRAPH + {0xB35B, 0x8A25}, //2792 #CJK UNIFIED IDEOGRAPH + {0xB35C, 0x8A31}, //2793 #CJK UNIFIED IDEOGRAPH + {0xB35D, 0x8A2D}, //2794 #CJK UNIFIED IDEOGRAPH + {0xB35E, 0x8A1F}, //2795 #CJK UNIFIED IDEOGRAPH + {0xB35F, 0x8A1B}, //2796 #CJK UNIFIED IDEOGRAPH + {0xB360, 0x8A22}, //2797 #CJK UNIFIED IDEOGRAPH + {0xB361, 0x8C49}, //2798 #CJK UNIFIED IDEOGRAPH + {0xB362, 0x8C5A}, //2799 #CJK UNIFIED IDEOGRAPH + {0xB363, 0x8CA9}, //2800 #CJK UNIFIED IDEOGRAPH + {0xB364, 0x8CAC}, //2801 #CJK UNIFIED IDEOGRAPH + {0xB365, 0x8CAB}, //2802 #CJK UNIFIED IDEOGRAPH + {0xB366, 0x8CA8}, //2803 #CJK UNIFIED IDEOGRAPH + {0xB367, 0x8CAA}, //2804 #CJK UNIFIED IDEOGRAPH + {0xB368, 0x8CA7}, //2805 #CJK UNIFIED IDEOGRAPH + {0xB369, 0x8D67}, //2806 #CJK UNIFIED IDEOGRAPH + {0xB36A, 0x8D66}, //2807 #CJK UNIFIED IDEOGRAPH + {0xB36B, 0x8DBE}, //2808 #CJK UNIFIED IDEOGRAPH + {0xB36C, 0x8DBA}, //2809 #CJK UNIFIED IDEOGRAPH + {0xB36D, 0x8EDB}, //2810 #CJK UNIFIED IDEOGRAPH + {0xB36E, 0x8EDF}, //2811 #CJK UNIFIED IDEOGRAPH + {0xB36F, 0x9019}, //2812 #CJK UNIFIED IDEOGRAPH + {0xB370, 0x900D}, //2813 #CJK UNIFIED IDEOGRAPH + {0xB371, 0x901A}, //2814 #CJK UNIFIED IDEOGRAPH + {0xB372, 0x9017}, //2815 #CJK UNIFIED IDEOGRAPH + {0xB373, 0x9023}, //2816 #CJK UNIFIED IDEOGRAPH + {0xB374, 0x901F}, //2817 #CJK UNIFIED IDEOGRAPH + {0xB375, 0x901D}, //2818 #CJK UNIFIED IDEOGRAPH + {0xB376, 0x9010}, //2819 #CJK UNIFIED IDEOGRAPH + {0xB377, 0x9015}, //2820 #CJK UNIFIED IDEOGRAPH + {0xB378, 0x901E}, //2821 #CJK UNIFIED IDEOGRAPH + {0xB379, 0x9020}, //2822 #CJK UNIFIED IDEOGRAPH + {0xB37A, 0x900F}, //2823 #CJK UNIFIED IDEOGRAPH + {0xB37B, 0x9022}, //2824 #CJK UNIFIED IDEOGRAPH + {0xB37C, 0x9016}, //2825 #CJK UNIFIED IDEOGRAPH + {0xB37D, 0x901B}, //2826 #CJK UNIFIED IDEOGRAPH + {0xB37E, 0x9014}, //2827 #CJK UNIFIED IDEOGRAPH + {0xB3A1, 0x90E8}, //2828 #CJK UNIFIED IDEOGRAPH + {0xB3A2, 0x90ED}, //2829 #CJK UNIFIED IDEOGRAPH + {0xB3A3, 0x90FD}, //2830 #CJK UNIFIED IDEOGRAPH + {0xB3A4, 0x9157}, //2831 #CJK UNIFIED IDEOGRAPH + {0xB3A5, 0x91CE}, //2832 #CJK UNIFIED IDEOGRAPH + {0xB3A6, 0x91F5}, //2833 #CJK UNIFIED IDEOGRAPH + {0xB3A7, 0x91E6}, //2834 #CJK UNIFIED IDEOGRAPH + {0xB3A8, 0x91E3}, //2835 #CJK UNIFIED IDEOGRAPH + {0xB3A9, 0x91E7}, //2836 #CJK UNIFIED IDEOGRAPH + {0xB3AA, 0x91ED}, //2837 #CJK UNIFIED IDEOGRAPH + {0xB3AB, 0x91E9}, //2838 #CJK UNIFIED IDEOGRAPH + {0xB3AC, 0x9589}, //2839 #CJK UNIFIED IDEOGRAPH + {0xB3AD, 0x966A}, //2840 #CJK UNIFIED IDEOGRAPH + {0xB3AE, 0x9675}, //2841 #CJK UNIFIED IDEOGRAPH + {0xB3AF, 0x9673}, //2842 #CJK UNIFIED IDEOGRAPH + {0xB3B0, 0x9678}, //2843 #CJK UNIFIED IDEOGRAPH + {0xB3B1, 0x9670}, //2844 #CJK UNIFIED IDEOGRAPH + {0xB3B2, 0x9674}, //2845 #CJK UNIFIED IDEOGRAPH + {0xB3B3, 0x9676}, //2846 #CJK UNIFIED IDEOGRAPH + {0xB3B4, 0x9677}, //2847 #CJK UNIFIED IDEOGRAPH + {0xB3B5, 0x966C}, //2848 #CJK UNIFIED IDEOGRAPH + {0xB3B6, 0x96C0}, //2849 #CJK UNIFIED IDEOGRAPH + {0xB3B7, 0x96EA}, //2850 #CJK UNIFIED IDEOGRAPH + {0xB3B8, 0x96E9}, //2851 #CJK UNIFIED IDEOGRAPH + {0xB3B9, 0x7AE0}, //2852 #CJK UNIFIED IDEOGRAPH + {0xB3BA, 0x7ADF}, //2853 #CJK UNIFIED IDEOGRAPH + {0xB3BB, 0x9802}, //2854 #CJK UNIFIED IDEOGRAPH + {0xB3BC, 0x9803}, //2855 #CJK UNIFIED IDEOGRAPH + {0xB3BD, 0x9B5A}, //2856 #CJK UNIFIED IDEOGRAPH + {0xB3BE, 0x9CE5}, //2857 #CJK UNIFIED IDEOGRAPH + {0xB3BF, 0x9E75}, //2858 #CJK UNIFIED IDEOGRAPH + {0xB3C0, 0x9E7F}, //2859 #CJK UNIFIED IDEOGRAPH + {0xB3C1, 0x9EA5}, //2860 #CJK UNIFIED IDEOGRAPH + {0xB3C2, 0x9EBB}, //2861 #CJK UNIFIED IDEOGRAPH + {0xB3C3, 0x50A2}, //2862 #CJK UNIFIED IDEOGRAPH + {0xB3C4, 0x508D}, //2863 #CJK UNIFIED IDEOGRAPH + {0xB3C5, 0x5085}, //2864 #CJK UNIFIED IDEOGRAPH + {0xB3C6, 0x5099}, //2865 #CJK UNIFIED IDEOGRAPH + {0xB3C7, 0x5091}, //2866 #CJK UNIFIED IDEOGRAPH + {0xB3C8, 0x5080}, //2867 #CJK UNIFIED IDEOGRAPH + {0xB3C9, 0x5096}, //2868 #CJK UNIFIED IDEOGRAPH + {0xB3CA, 0x5098}, //2869 #CJK UNIFIED IDEOGRAPH + {0xB3CB, 0x509A}, //2870 #CJK UNIFIED IDEOGRAPH + {0xB3CC, 0x6700}, //2871 #CJK UNIFIED IDEOGRAPH + {0xB3CD, 0x51F1}, //2872 #CJK UNIFIED IDEOGRAPH + {0xB3CE, 0x5272}, //2873 #CJK UNIFIED IDEOGRAPH + {0xB3CF, 0x5274}, //2874 #CJK UNIFIED IDEOGRAPH + {0xB3D0, 0x5275}, //2875 #CJK UNIFIED IDEOGRAPH + {0xB3D1, 0x5269}, //2876 #CJK UNIFIED IDEOGRAPH + {0xB3D2, 0x52DE}, //2877 #CJK UNIFIED IDEOGRAPH + {0xB3D3, 0x52DD}, //2878 #CJK UNIFIED IDEOGRAPH + {0xB3D4, 0x52DB}, //2879 #CJK UNIFIED IDEOGRAPH + {0xB3D5, 0x535A}, //2880 #CJK UNIFIED IDEOGRAPH + {0xB3D6, 0x53A5}, //2881 #CJK UNIFIED IDEOGRAPH + {0xB3D7, 0x557B}, //2882 #CJK UNIFIED IDEOGRAPH + {0xB3D8, 0x5580}, //2883 #CJK UNIFIED IDEOGRAPH + {0xB3D9, 0x55A7}, //2884 #CJK UNIFIED IDEOGRAPH + {0xB3DA, 0x557C}, //2885 #CJK UNIFIED IDEOGRAPH + {0xB3DB, 0x558A}, //2886 #CJK UNIFIED IDEOGRAPH + {0xB3DC, 0x559D}, //2887 #CJK UNIFIED IDEOGRAPH + {0xB3DD, 0x5598}, //2888 #CJK UNIFIED IDEOGRAPH + {0xB3DE, 0x5582}, //2889 #CJK UNIFIED IDEOGRAPH + {0xB3DF, 0x559C}, //2890 #CJK UNIFIED IDEOGRAPH + {0xB3E0, 0x55AA}, //2891 #CJK UNIFIED IDEOGRAPH + {0xB3E1, 0x5594}, //2892 #CJK UNIFIED IDEOGRAPH + {0xB3E2, 0x5587}, //2893 #CJK UNIFIED IDEOGRAPH + {0xB3E3, 0x558B}, //2894 #CJK UNIFIED IDEOGRAPH + {0xB3E4, 0x5583}, //2895 #CJK UNIFIED IDEOGRAPH + {0xB3E5, 0x55B3}, //2896 #CJK UNIFIED IDEOGRAPH + {0xB3E6, 0x55AE}, //2897 #CJK UNIFIED IDEOGRAPH + {0xB3E7, 0x559F}, //2898 #CJK UNIFIED IDEOGRAPH + {0xB3E8, 0x553E}, //2899 #CJK UNIFIED IDEOGRAPH + {0xB3E9, 0x55B2}, //2900 #CJK UNIFIED IDEOGRAPH + {0xB3EA, 0x559A}, //2901 #CJK UNIFIED IDEOGRAPH + {0xB3EB, 0x55BB}, //2902 #CJK UNIFIED IDEOGRAPH + {0xB3EC, 0x55AC}, //2903 #CJK UNIFIED IDEOGRAPH + {0xB3ED, 0x55B1}, //2904 #CJK UNIFIED IDEOGRAPH + {0xB3EE, 0x557E}, //2905 #CJK UNIFIED IDEOGRAPH + {0xB3EF, 0x5589}, //2906 #CJK UNIFIED IDEOGRAPH + {0xB3F0, 0x55AB}, //2907 #CJK UNIFIED IDEOGRAPH + {0xB3F1, 0x5599}, //2908 #CJK UNIFIED IDEOGRAPH + {0xB3F2, 0x570D}, //2909 #CJK UNIFIED IDEOGRAPH + {0xB3F3, 0x582F}, //2910 #CJK UNIFIED IDEOGRAPH + {0xB3F4, 0x582A}, //2911 #CJK UNIFIED IDEOGRAPH + {0xB3F5, 0x5834}, //2912 #CJK UNIFIED IDEOGRAPH + {0xB3F6, 0x5824}, //2913 #CJK UNIFIED IDEOGRAPH + {0xB3F7, 0x5830}, //2914 #CJK UNIFIED IDEOGRAPH + {0xB3F8, 0x5831}, //2915 #CJK UNIFIED IDEOGRAPH + {0xB3F9, 0x5821}, //2916 #CJK UNIFIED IDEOGRAPH + {0xB3FA, 0x581D}, //2917 #CJK UNIFIED IDEOGRAPH + {0xB3FB, 0x5820}, //2918 #CJK UNIFIED IDEOGRAPH + {0xB3FC, 0x58F9}, //2919 #CJK UNIFIED IDEOGRAPH + {0xB3FD, 0x58FA}, //2920 #CJK UNIFIED IDEOGRAPH + {0xB3FE, 0x5960}, //2921 #CJK UNIFIED IDEOGRAPH + {0xB440, 0x5A77}, //2922 #CJK UNIFIED IDEOGRAPH + {0xB441, 0x5A9A}, //2923 #CJK UNIFIED IDEOGRAPH + {0xB442, 0x5A7F}, //2924 #CJK UNIFIED IDEOGRAPH + {0xB443, 0x5A92}, //2925 #CJK UNIFIED IDEOGRAPH + {0xB444, 0x5A9B}, //2926 #CJK UNIFIED IDEOGRAPH + {0xB445, 0x5AA7}, //2927 #CJK UNIFIED IDEOGRAPH + {0xB446, 0x5B73}, //2928 #CJK UNIFIED IDEOGRAPH + {0xB447, 0x5B71}, //2929 #CJK UNIFIED IDEOGRAPH + {0xB448, 0x5BD2}, //2930 #CJK UNIFIED IDEOGRAPH + {0xB449, 0x5BCC}, //2931 #CJK UNIFIED IDEOGRAPH + {0xB44A, 0x5BD3}, //2932 #CJK UNIFIED IDEOGRAPH + {0xB44B, 0x5BD0}, //2933 #CJK UNIFIED IDEOGRAPH + {0xB44C, 0x5C0A}, //2934 #CJK UNIFIED IDEOGRAPH + {0xB44D, 0x5C0B}, //2935 #CJK UNIFIED IDEOGRAPH + {0xB44E, 0x5C31}, //2936 #CJK UNIFIED IDEOGRAPH + {0xB44F, 0x5D4C}, //2937 #CJK UNIFIED IDEOGRAPH + {0xB450, 0x5D50}, //2938 #CJK UNIFIED IDEOGRAPH + {0xB451, 0x5D34}, //2939 #CJK UNIFIED IDEOGRAPH + {0xB452, 0x5D47}, //2940 #CJK UNIFIED IDEOGRAPH + {0xB453, 0x5DFD}, //2941 #CJK UNIFIED IDEOGRAPH + {0xB454, 0x5E45}, //2942 #CJK UNIFIED IDEOGRAPH + {0xB455, 0x5E3D}, //2943 #CJK UNIFIED IDEOGRAPH + {0xB456, 0x5E40}, //2944 #CJK UNIFIED IDEOGRAPH + {0xB457, 0x5E43}, //2945 #CJK UNIFIED IDEOGRAPH + {0xB458, 0x5E7E}, //2946 #CJK UNIFIED IDEOGRAPH + {0xB459, 0x5ECA}, //2947 #CJK UNIFIED IDEOGRAPH + {0xB45A, 0x5EC1}, //2948 #CJK UNIFIED IDEOGRAPH + {0xB45B, 0x5EC2}, //2949 #CJK UNIFIED IDEOGRAPH + {0xB45C, 0x5EC4}, //2950 #CJK UNIFIED IDEOGRAPH + {0xB45D, 0x5F3C}, //2951 #CJK UNIFIED IDEOGRAPH + {0xB45E, 0x5F6D}, //2952 #CJK UNIFIED IDEOGRAPH + {0xB45F, 0x5FA9}, //2953 #CJK UNIFIED IDEOGRAPH + {0xB460, 0x5FAA}, //2954 #CJK UNIFIED IDEOGRAPH + {0xB461, 0x5FA8}, //2955 #CJK UNIFIED IDEOGRAPH + {0xB462, 0x60D1}, //2956 #CJK UNIFIED IDEOGRAPH + {0xB463, 0x60E1}, //2957 #CJK UNIFIED IDEOGRAPH + {0xB464, 0x60B2}, //2958 #CJK UNIFIED IDEOGRAPH + {0xB465, 0x60B6}, //2959 #CJK UNIFIED IDEOGRAPH + {0xB466, 0x60E0}, //2960 #CJK UNIFIED IDEOGRAPH + {0xB467, 0x611C}, //2961 #CJK UNIFIED IDEOGRAPH + {0xB468, 0x6123}, //2962 #CJK UNIFIED IDEOGRAPH + {0xB469, 0x60FA}, //2963 #CJK UNIFIED IDEOGRAPH + {0xB46A, 0x6115}, //2964 #CJK UNIFIED IDEOGRAPH + {0xB46B, 0x60F0}, //2965 #CJK UNIFIED IDEOGRAPH + {0xB46C, 0x60FB}, //2966 #CJK UNIFIED IDEOGRAPH + {0xB46D, 0x60F4}, //2967 #CJK UNIFIED IDEOGRAPH + {0xB46E, 0x6168}, //2968 #CJK UNIFIED IDEOGRAPH + {0xB46F, 0x60F1}, //2969 #CJK UNIFIED IDEOGRAPH + {0xB470, 0x610E}, //2970 #CJK UNIFIED IDEOGRAPH + {0xB471, 0x60F6}, //2971 #CJK UNIFIED IDEOGRAPH + {0xB472, 0x6109}, //2972 #CJK UNIFIED IDEOGRAPH + {0xB473, 0x6100}, //2973 #CJK UNIFIED IDEOGRAPH + {0xB474, 0x6112}, //2974 #CJK UNIFIED IDEOGRAPH + {0xB475, 0x621F}, //2975 #CJK UNIFIED IDEOGRAPH + {0xB476, 0x6249}, //2976 #CJK UNIFIED IDEOGRAPH + {0xB477, 0x63A3}, //2977 #CJK UNIFIED IDEOGRAPH + {0xB478, 0x638C}, //2978 #CJK UNIFIED IDEOGRAPH + {0xB479, 0x63CF}, //2979 #CJK UNIFIED IDEOGRAPH + {0xB47A, 0x63C0}, //2980 #CJK UNIFIED IDEOGRAPH + {0xB47B, 0x63E9}, //2981 #CJK UNIFIED IDEOGRAPH + {0xB47C, 0x63C9}, //2982 #CJK UNIFIED IDEOGRAPH + {0xB47D, 0x63C6}, //2983 #CJK UNIFIED IDEOGRAPH + {0xB47E, 0x63CD}, //2984 #CJK UNIFIED IDEOGRAPH + {0xB4A1, 0x63D2}, //2985 #CJK UNIFIED IDEOGRAPH + {0xB4A2, 0x63E3}, //2986 #CJK UNIFIED IDEOGRAPH + {0xB4A3, 0x63D0}, //2987 #CJK UNIFIED IDEOGRAPH + {0xB4A4, 0x63E1}, //2988 #CJK UNIFIED IDEOGRAPH + {0xB4A5, 0x63D6}, //2989 #CJK UNIFIED IDEOGRAPH + {0xB4A6, 0x63ED}, //2990 #CJK UNIFIED IDEOGRAPH + {0xB4A7, 0x63EE}, //2991 #CJK UNIFIED IDEOGRAPH + {0xB4A8, 0x6376}, //2992 #CJK UNIFIED IDEOGRAPH + {0xB4A9, 0x63F4}, //2993 #CJK UNIFIED IDEOGRAPH + {0xB4AA, 0x63EA}, //2994 #CJK UNIFIED IDEOGRAPH + {0xB4AB, 0x63DB}, //2995 #CJK UNIFIED IDEOGRAPH + {0xB4AC, 0x6452}, //2996 #CJK UNIFIED IDEOGRAPH + {0xB4AD, 0x63DA}, //2997 #CJK UNIFIED IDEOGRAPH + {0xB4AE, 0x63F9}, //2998 #CJK UNIFIED IDEOGRAPH + {0xB4AF, 0x655E}, //2999 #CJK UNIFIED IDEOGRAPH + {0xB4B0, 0x6566}, //3000 #CJK UNIFIED IDEOGRAPH + {0xB4B1, 0x6562}, //3001 #CJK UNIFIED IDEOGRAPH + {0xB4B2, 0x6563}, //3002 #CJK UNIFIED IDEOGRAPH + {0xB4B3, 0x6591}, //3003 #CJK UNIFIED IDEOGRAPH + {0xB4B4, 0x6590}, //3004 #CJK UNIFIED IDEOGRAPH + {0xB4B5, 0x65AF}, //3005 #CJK UNIFIED IDEOGRAPH + {0xB4B6, 0x666E}, //3006 #CJK UNIFIED IDEOGRAPH + {0xB4B7, 0x6670}, //3007 #CJK UNIFIED IDEOGRAPH + {0xB4B8, 0x6674}, //3008 #CJK UNIFIED IDEOGRAPH + {0xB4B9, 0x6676}, //3009 #CJK UNIFIED IDEOGRAPH + {0xB4BA, 0x666F}, //3010 #CJK UNIFIED IDEOGRAPH + {0xB4BB, 0x6691}, //3011 #CJK UNIFIED IDEOGRAPH + {0xB4BC, 0x667A}, //3012 #CJK UNIFIED IDEOGRAPH + {0xB4BD, 0x667E}, //3013 #CJK UNIFIED IDEOGRAPH + {0xB4BE, 0x6677}, //3014 #CJK UNIFIED IDEOGRAPH + {0xB4BF, 0x66FE}, //3015 #CJK UNIFIED IDEOGRAPH + {0xB4C0, 0x66FF}, //3016 #CJK UNIFIED IDEOGRAPH + {0xB4C1, 0x671F}, //3017 #CJK UNIFIED IDEOGRAPH + {0xB4C2, 0x671D}, //3018 #CJK UNIFIED IDEOGRAPH + {0xB4C3, 0x68FA}, //3019 #CJK UNIFIED IDEOGRAPH + {0xB4C4, 0x68D5}, //3020 #CJK UNIFIED IDEOGRAPH + {0xB4C5, 0x68E0}, //3021 #CJK UNIFIED IDEOGRAPH + {0xB4C6, 0x68D8}, //3022 #CJK UNIFIED IDEOGRAPH + {0xB4C7, 0x68D7}, //3023 #CJK UNIFIED IDEOGRAPH + {0xB4C8, 0x6905}, //3024 #CJK UNIFIED IDEOGRAPH + {0xB4C9, 0x68DF}, //3025 #CJK UNIFIED IDEOGRAPH + {0xB4CA, 0x68F5}, //3026 #CJK UNIFIED IDEOGRAPH + {0xB4CB, 0x68EE}, //3027 #CJK UNIFIED IDEOGRAPH + {0xB4CC, 0x68E7}, //3028 #CJK UNIFIED IDEOGRAPH + {0xB4CD, 0x68F9}, //3029 #CJK UNIFIED IDEOGRAPH + {0xB4CE, 0x68D2}, //3030 #CJK UNIFIED IDEOGRAPH + {0xB4CF, 0x68F2}, //3031 #CJK UNIFIED IDEOGRAPH + {0xB4D0, 0x68E3}, //3032 #CJK UNIFIED IDEOGRAPH + {0xB4D1, 0x68CB}, //3033 #CJK UNIFIED IDEOGRAPH + {0xB4D2, 0x68CD}, //3034 #CJK UNIFIED IDEOGRAPH + {0xB4D3, 0x690D}, //3035 #CJK UNIFIED IDEOGRAPH + {0xB4D4, 0x6912}, //3036 #CJK UNIFIED IDEOGRAPH + {0xB4D5, 0x690E}, //3037 #CJK UNIFIED IDEOGRAPH + {0xB4D6, 0x68C9}, //3038 #CJK UNIFIED IDEOGRAPH + {0xB4D7, 0x68DA}, //3039 #CJK UNIFIED IDEOGRAPH + {0xB4D8, 0x696E}, //3040 #CJK UNIFIED IDEOGRAPH + {0xB4D9, 0x68FB}, //3041 #CJK UNIFIED IDEOGRAPH + {0xB4DA, 0x6B3E}, //3042 #CJK UNIFIED IDEOGRAPH + {0xB4DB, 0x6B3A}, //3043 #CJK UNIFIED IDEOGRAPH + {0xB4DC, 0x6B3D}, //3044 #CJK UNIFIED IDEOGRAPH + {0xB4DD, 0x6B98}, //3045 #CJK UNIFIED IDEOGRAPH + {0xB4DE, 0x6B96}, //3046 #CJK UNIFIED IDEOGRAPH + {0xB4DF, 0x6BBC}, //3047 #CJK UNIFIED IDEOGRAPH + {0xB4E0, 0x6BEF}, //3048 #CJK UNIFIED IDEOGRAPH + {0xB4E1, 0x6C2E}, //3049 #CJK UNIFIED IDEOGRAPH + {0xB4E2, 0x6C2F}, //3050 #CJK UNIFIED IDEOGRAPH + {0xB4E3, 0x6C2C}, //3051 #CJK UNIFIED IDEOGRAPH + {0xB4E4, 0x6E2F}, //3052 #CJK UNIFIED IDEOGRAPH + {0xB4E5, 0x6E38}, //3053 #CJK UNIFIED IDEOGRAPH + {0xB4E6, 0x6E54}, //3054 #CJK UNIFIED IDEOGRAPH + {0xB4E7, 0x6E21}, //3055 #CJK UNIFIED IDEOGRAPH + {0xB4E8, 0x6E32}, //3056 #CJK UNIFIED IDEOGRAPH + {0xB4E9, 0x6E67}, //3057 #CJK UNIFIED IDEOGRAPH + {0xB4EA, 0x6E4A}, //3058 #CJK UNIFIED IDEOGRAPH + {0xB4EB, 0x6E20}, //3059 #CJK UNIFIED IDEOGRAPH + {0xB4EC, 0x6E25}, //3060 #CJK UNIFIED IDEOGRAPH + {0xB4ED, 0x6E23}, //3061 #CJK UNIFIED IDEOGRAPH + {0xB4EE, 0x6E1B}, //3062 #CJK UNIFIED IDEOGRAPH + {0xB4EF, 0x6E5B}, //3063 #CJK UNIFIED IDEOGRAPH + {0xB4F0, 0x6E58}, //3064 #CJK UNIFIED IDEOGRAPH + {0xB4F1, 0x6E24}, //3065 #CJK UNIFIED IDEOGRAPH + {0xB4F2, 0x6E56}, //3066 #CJK UNIFIED IDEOGRAPH + {0xB4F3, 0x6E6E}, //3067 #CJK UNIFIED IDEOGRAPH + {0xB4F4, 0x6E2D}, //3068 #CJK UNIFIED IDEOGRAPH + {0xB4F5, 0x6E26}, //3069 #CJK UNIFIED IDEOGRAPH + {0xB4F6, 0x6E6F}, //3070 #CJK UNIFIED IDEOGRAPH + {0xB4F7, 0x6E34}, //3071 #CJK UNIFIED IDEOGRAPH + {0xB4F8, 0x6E4D}, //3072 #CJK UNIFIED IDEOGRAPH + {0xB4F9, 0x6E3A}, //3073 #CJK UNIFIED IDEOGRAPH + {0xB4FA, 0x6E2C}, //3074 #CJK UNIFIED IDEOGRAPH + {0xB4FB, 0x6E43}, //3075 #CJK UNIFIED IDEOGRAPH + {0xB4FC, 0x6E1D}, //3076 #CJK UNIFIED IDEOGRAPH + {0xB4FD, 0x6E3E}, //3077 #CJK UNIFIED IDEOGRAPH + {0xB4FE, 0x6ECB}, //3078 #CJK UNIFIED IDEOGRAPH + {0xB540, 0x6E89}, //3079 #CJK UNIFIED IDEOGRAPH + {0xB541, 0x6E19}, //3080 #CJK UNIFIED IDEOGRAPH + {0xB542, 0x6E4E}, //3081 #CJK UNIFIED IDEOGRAPH + {0xB543, 0x6E63}, //3082 #CJK UNIFIED IDEOGRAPH + {0xB544, 0x6E44}, //3083 #CJK UNIFIED IDEOGRAPH + {0xB545, 0x6E72}, //3084 #CJK UNIFIED IDEOGRAPH + {0xB546, 0x6E69}, //3085 #CJK UNIFIED IDEOGRAPH + {0xB547, 0x6E5F}, //3086 #CJK UNIFIED IDEOGRAPH + {0xB548, 0x7119}, //3087 #CJK UNIFIED IDEOGRAPH + {0xB549, 0x711A}, //3088 #CJK UNIFIED IDEOGRAPH + {0xB54A, 0x7126}, //3089 #CJK UNIFIED IDEOGRAPH + {0xB54B, 0x7130}, //3090 #CJK UNIFIED IDEOGRAPH + {0xB54C, 0x7121}, //3091 #CJK UNIFIED IDEOGRAPH + {0xB54D, 0x7136}, //3092 #CJK UNIFIED IDEOGRAPH + {0xB54E, 0x716E}, //3093 #CJK UNIFIED IDEOGRAPH + {0xB54F, 0x711C}, //3094 #CJK UNIFIED IDEOGRAPH + {0xB550, 0x724C}, //3095 #CJK UNIFIED IDEOGRAPH + {0xB551, 0x7284}, //3096 #CJK UNIFIED IDEOGRAPH + {0xB552, 0x7280}, //3097 #CJK UNIFIED IDEOGRAPH + {0xB553, 0x7336}, //3098 #CJK UNIFIED IDEOGRAPH + {0xB554, 0x7325}, //3099 #CJK UNIFIED IDEOGRAPH + {0xB555, 0x7334}, //3100 #CJK UNIFIED IDEOGRAPH + {0xB556, 0x7329}, //3101 #CJK UNIFIED IDEOGRAPH + {0xB557, 0x743A}, //3102 #CJK UNIFIED IDEOGRAPH + {0xB558, 0x742A}, //3103 #CJK UNIFIED IDEOGRAPH + {0xB559, 0x7433}, //3104 #CJK UNIFIED IDEOGRAPH + {0xB55A, 0x7422}, //3105 #CJK UNIFIED IDEOGRAPH + {0xB55B, 0x7425}, //3106 #CJK UNIFIED IDEOGRAPH + {0xB55C, 0x7435}, //3107 #CJK UNIFIED IDEOGRAPH + {0xB55D, 0x7436}, //3108 #CJK UNIFIED IDEOGRAPH + {0xB55E, 0x7434}, //3109 #CJK UNIFIED IDEOGRAPH + {0xB55F, 0x742F}, //3110 #CJK UNIFIED IDEOGRAPH + {0xB560, 0x741B}, //3111 #CJK UNIFIED IDEOGRAPH + {0xB561, 0x7426}, //3112 #CJK UNIFIED IDEOGRAPH + {0xB562, 0x7428}, //3113 #CJK UNIFIED IDEOGRAPH + {0xB563, 0x7525}, //3114 #CJK UNIFIED IDEOGRAPH + {0xB564, 0x7526}, //3115 #CJK UNIFIED IDEOGRAPH + {0xB565, 0x756B}, //3116 #CJK UNIFIED IDEOGRAPH + {0xB566, 0x756A}, //3117 #CJK UNIFIED IDEOGRAPH + {0xB567, 0x75E2}, //3118 #CJK UNIFIED IDEOGRAPH + {0xB568, 0x75DB}, //3119 #CJK UNIFIED IDEOGRAPH + {0xB569, 0x75E3}, //3120 #CJK UNIFIED IDEOGRAPH + {0xB56A, 0x75D9}, //3121 #CJK UNIFIED IDEOGRAPH + {0xB56B, 0x75D8}, //3122 #CJK UNIFIED IDEOGRAPH + {0xB56C, 0x75DE}, //3123 #CJK UNIFIED IDEOGRAPH + {0xB56D, 0x75E0}, //3124 #CJK UNIFIED IDEOGRAPH + {0xB56E, 0x767B}, //3125 #CJK UNIFIED IDEOGRAPH + {0xB56F, 0x767C}, //3126 #CJK UNIFIED IDEOGRAPH + {0xB570, 0x7696}, //3127 #CJK UNIFIED IDEOGRAPH + {0xB571, 0x7693}, //3128 #CJK UNIFIED IDEOGRAPH + {0xB572, 0x76B4}, //3129 #CJK UNIFIED IDEOGRAPH + {0xB573, 0x76DC}, //3130 #CJK UNIFIED IDEOGRAPH + {0xB574, 0x774F}, //3131 #CJK UNIFIED IDEOGRAPH + {0xB575, 0x77ED}, //3132 #CJK UNIFIED IDEOGRAPH + {0xB576, 0x785D}, //3133 #CJK UNIFIED IDEOGRAPH + {0xB577, 0x786C}, //3134 #CJK UNIFIED IDEOGRAPH + {0xB578, 0x786F}, //3135 #CJK UNIFIED IDEOGRAPH + {0xB579, 0x7A0D}, //3136 #CJK UNIFIED IDEOGRAPH + {0xB57A, 0x7A08}, //3137 #CJK UNIFIED IDEOGRAPH + {0xB57B, 0x7A0B}, //3138 #CJK UNIFIED IDEOGRAPH + {0xB57C, 0x7A05}, //3139 #CJK UNIFIED IDEOGRAPH + {0xB57D, 0x7A00}, //3140 #CJK UNIFIED IDEOGRAPH + {0xB57E, 0x7A98}, //3141 #CJK UNIFIED IDEOGRAPH + {0xB5A1, 0x7A97}, //3142 #CJK UNIFIED IDEOGRAPH + {0xB5A2, 0x7A96}, //3143 #CJK UNIFIED IDEOGRAPH + {0xB5A3, 0x7AE5}, //3144 #CJK UNIFIED IDEOGRAPH + {0xB5A4, 0x7AE3}, //3145 #CJK UNIFIED IDEOGRAPH + {0xB5A5, 0x7B49}, //3146 #CJK UNIFIED IDEOGRAPH + {0xB5A6, 0x7B56}, //3147 #CJK UNIFIED IDEOGRAPH + {0xB5A7, 0x7B46}, //3148 #CJK UNIFIED IDEOGRAPH + {0xB5A8, 0x7B50}, //3149 #CJK UNIFIED IDEOGRAPH + {0xB5A9, 0x7B52}, //3150 #CJK UNIFIED IDEOGRAPH + {0xB5AA, 0x7B54}, //3151 #CJK UNIFIED IDEOGRAPH + {0xB5AB, 0x7B4D}, //3152 #CJK UNIFIED IDEOGRAPH + {0xB5AC, 0x7B4B}, //3153 #CJK UNIFIED IDEOGRAPH + {0xB5AD, 0x7B4F}, //3154 #CJK UNIFIED IDEOGRAPH + {0xB5AE, 0x7B51}, //3155 #CJK UNIFIED IDEOGRAPH + {0xB5AF, 0x7C9F}, //3156 #CJK UNIFIED IDEOGRAPH + {0xB5B0, 0x7CA5}, //3157 #CJK UNIFIED IDEOGRAPH + {0xB5B1, 0x7D5E}, //3158 #CJK UNIFIED IDEOGRAPH + {0xB5B2, 0x7D50}, //3159 #CJK UNIFIED IDEOGRAPH + {0xB5B3, 0x7D68}, //3160 #CJK UNIFIED IDEOGRAPH + {0xB5B4, 0x7D55}, //3161 #CJK UNIFIED IDEOGRAPH + {0xB5B5, 0x7D2B}, //3162 #CJK UNIFIED IDEOGRAPH + {0xB5B6, 0x7D6E}, //3163 #CJK UNIFIED IDEOGRAPH + {0xB5B7, 0x7D72}, //3164 #CJK UNIFIED IDEOGRAPH + {0xB5B8, 0x7D61}, //3165 #CJK UNIFIED IDEOGRAPH + {0xB5B9, 0x7D66}, //3166 #CJK UNIFIED IDEOGRAPH + {0xB5BA, 0x7D62}, //3167 #CJK UNIFIED IDEOGRAPH + {0xB5BB, 0x7D70}, //3168 #CJK UNIFIED IDEOGRAPH + {0xB5BC, 0x7D73}, //3169 #CJK UNIFIED IDEOGRAPH + {0xB5BD, 0x5584}, //3170 #CJK UNIFIED IDEOGRAPH + {0xB5BE, 0x7FD4}, //3171 #CJK UNIFIED IDEOGRAPH + {0xB5BF, 0x7FD5}, //3172 #CJK UNIFIED IDEOGRAPH + {0xB5C0, 0x800B}, //3173 #CJK UNIFIED IDEOGRAPH + {0xB5C1, 0x8052}, //3174 #CJK UNIFIED IDEOGRAPH + {0xB5C2, 0x8085}, //3175 #CJK UNIFIED IDEOGRAPH + {0xB5C3, 0x8155}, //3176 #CJK UNIFIED IDEOGRAPH + {0xB5C4, 0x8154}, //3177 #CJK UNIFIED IDEOGRAPH + {0xB5C5, 0x814B}, //3178 #CJK UNIFIED IDEOGRAPH + {0xB5C6, 0x8151}, //3179 #CJK UNIFIED IDEOGRAPH + {0xB5C7, 0x814E}, //3180 #CJK UNIFIED IDEOGRAPH + {0xB5C8, 0x8139}, //3181 #CJK UNIFIED IDEOGRAPH + {0xB5C9, 0x8146}, //3182 #CJK UNIFIED IDEOGRAPH + {0xB5CA, 0x813E}, //3183 #CJK UNIFIED IDEOGRAPH + {0xB5CB, 0x814C}, //3184 #CJK UNIFIED IDEOGRAPH + {0xB5CC, 0x8153}, //3185 #CJK UNIFIED IDEOGRAPH + {0xB5CD, 0x8174}, //3186 #CJK UNIFIED IDEOGRAPH + {0xB5CE, 0x8212}, //3187 #CJK UNIFIED IDEOGRAPH + {0xB5CF, 0x821C}, //3188 #CJK UNIFIED IDEOGRAPH + {0xB5D0, 0x83E9}, //3189 #CJK UNIFIED IDEOGRAPH + {0xB5D1, 0x8403}, //3190 #CJK UNIFIED IDEOGRAPH + {0xB5D2, 0x83F8}, //3191 #CJK UNIFIED IDEOGRAPH + {0xB5D3, 0x840D}, //3192 #CJK UNIFIED IDEOGRAPH + {0xB5D4, 0x83E0}, //3193 #CJK UNIFIED IDEOGRAPH + {0xB5D5, 0x83C5}, //3194 #CJK UNIFIED IDEOGRAPH + {0xB5D6, 0x840B}, //3195 #CJK UNIFIED IDEOGRAPH + {0xB5D7, 0x83C1}, //3196 #CJK UNIFIED IDEOGRAPH + {0xB5D8, 0x83EF}, //3197 #CJK UNIFIED IDEOGRAPH + {0xB5D9, 0x83F1}, //3198 #CJK UNIFIED IDEOGRAPH + {0xB5DA, 0x83F4}, //3199 #CJK UNIFIED IDEOGRAPH + {0xB5DB, 0x8457}, //3200 #CJK UNIFIED IDEOGRAPH + {0xB5DC, 0x840A}, //3201 #CJK UNIFIED IDEOGRAPH + {0xB5DD, 0x83F0}, //3202 #CJK UNIFIED IDEOGRAPH + {0xB5DE, 0x840C}, //3203 #CJK UNIFIED IDEOGRAPH + {0xB5DF, 0x83CC}, //3204 #CJK UNIFIED IDEOGRAPH + {0xB5E0, 0x83FD}, //3205 #CJK UNIFIED IDEOGRAPH + {0xB5E1, 0x83F2}, //3206 #CJK UNIFIED IDEOGRAPH + {0xB5E2, 0x83CA}, //3207 #CJK UNIFIED IDEOGRAPH + {0xB5E3, 0x8438}, //3208 #CJK UNIFIED IDEOGRAPH + {0xB5E4, 0x840E}, //3209 #CJK UNIFIED IDEOGRAPH + {0xB5E5, 0x8404}, //3210 #CJK UNIFIED IDEOGRAPH + {0xB5E6, 0x83DC}, //3211 #CJK UNIFIED IDEOGRAPH + {0xB5E7, 0x8407}, //3212 #CJK UNIFIED IDEOGRAPH + {0xB5E8, 0x83D4}, //3213 #CJK UNIFIED IDEOGRAPH + {0xB5E9, 0x83DF}, //3214 #CJK UNIFIED IDEOGRAPH + {0xB5EA, 0x865B}, //3215 #CJK UNIFIED IDEOGRAPH + {0xB5EB, 0x86DF}, //3216 #CJK UNIFIED IDEOGRAPH + {0xB5EC, 0x86D9}, //3217 #CJK UNIFIED IDEOGRAPH + {0xB5ED, 0x86ED}, //3218 #CJK UNIFIED IDEOGRAPH + {0xB5EE, 0x86D4}, //3219 #CJK UNIFIED IDEOGRAPH + {0xB5EF, 0x86DB}, //3220 #CJK UNIFIED IDEOGRAPH + {0xB5F0, 0x86E4}, //3221 #CJK UNIFIED IDEOGRAPH + {0xB5F1, 0x86D0}, //3222 #CJK UNIFIED IDEOGRAPH + {0xB5F2, 0x86DE}, //3223 #CJK UNIFIED IDEOGRAPH + {0xB5F3, 0x8857}, //3224 #CJK UNIFIED IDEOGRAPH + {0xB5F4, 0x88C1}, //3225 #CJK UNIFIED IDEOGRAPH + {0xB5F5, 0x88C2}, //3226 #CJK UNIFIED IDEOGRAPH + {0xB5F6, 0x88B1}, //3227 #CJK UNIFIED IDEOGRAPH + {0xB5F7, 0x8983}, //3228 #CJK UNIFIED IDEOGRAPH + {0xB5F8, 0x8996}, //3229 #CJK UNIFIED IDEOGRAPH + {0xB5F9, 0x8A3B}, //3230 #CJK UNIFIED IDEOGRAPH + {0xB5FA, 0x8A60}, //3231 #CJK UNIFIED IDEOGRAPH + {0xB5FB, 0x8A55}, //3232 #CJK UNIFIED IDEOGRAPH + {0xB5FC, 0x8A5E}, //3233 #CJK UNIFIED IDEOGRAPH + {0xB5FD, 0x8A3C}, //3234 #CJK UNIFIED IDEOGRAPH + {0xB5FE, 0x8A41}, //3235 #CJK UNIFIED IDEOGRAPH + {0xB640, 0x8A54}, //3236 #CJK UNIFIED IDEOGRAPH + {0xB641, 0x8A5B}, //3237 #CJK UNIFIED IDEOGRAPH + {0xB642, 0x8A50}, //3238 #CJK UNIFIED IDEOGRAPH + {0xB643, 0x8A46}, //3239 #CJK UNIFIED IDEOGRAPH + {0xB644, 0x8A34}, //3240 #CJK UNIFIED IDEOGRAPH + {0xB645, 0x8A3A}, //3241 #CJK UNIFIED IDEOGRAPH + {0xB646, 0x8A36}, //3242 #CJK UNIFIED IDEOGRAPH + {0xB647, 0x8A56}, //3243 #CJK UNIFIED IDEOGRAPH + {0xB648, 0x8C61}, //3244 #CJK UNIFIED IDEOGRAPH + {0xB649, 0x8C82}, //3245 #CJK UNIFIED IDEOGRAPH + {0xB64A, 0x8CAF}, //3246 #CJK UNIFIED IDEOGRAPH + {0xB64B, 0x8CBC}, //3247 #CJK UNIFIED IDEOGRAPH + {0xB64C, 0x8CB3}, //3248 #CJK UNIFIED IDEOGRAPH + {0xB64D, 0x8CBD}, //3249 #CJK UNIFIED IDEOGRAPH + {0xB64E, 0x8CC1}, //3250 #CJK UNIFIED IDEOGRAPH + {0xB64F, 0x8CBB}, //3251 #CJK UNIFIED IDEOGRAPH + {0xB650, 0x8CC0}, //3252 #CJK UNIFIED IDEOGRAPH + {0xB651, 0x8CB4}, //3253 #CJK UNIFIED IDEOGRAPH + {0xB652, 0x8CB7}, //3254 #CJK UNIFIED IDEOGRAPH + {0xB653, 0x8CB6}, //3255 #CJK UNIFIED IDEOGRAPH + {0xB654, 0x8CBF}, //3256 #CJK UNIFIED IDEOGRAPH + {0xB655, 0x8CB8}, //3257 #CJK UNIFIED IDEOGRAPH + {0xB656, 0x8D8A}, //3258 #CJK UNIFIED IDEOGRAPH + {0xB657, 0x8D85}, //3259 #CJK UNIFIED IDEOGRAPH + {0xB658, 0x8D81}, //3260 #CJK UNIFIED IDEOGRAPH + {0xB659, 0x8DCE}, //3261 #CJK UNIFIED IDEOGRAPH + {0xB65A, 0x8DDD}, //3262 #CJK UNIFIED IDEOGRAPH + {0xB65B, 0x8DCB}, //3263 #CJK UNIFIED IDEOGRAPH + {0xB65C, 0x8DDA}, //3264 #CJK UNIFIED IDEOGRAPH + {0xB65D, 0x8DD1}, //3265 #CJK UNIFIED IDEOGRAPH + {0xB65E, 0x8DCC}, //3266 #CJK UNIFIED IDEOGRAPH + {0xB65F, 0x8DDB}, //3267 #CJK UNIFIED IDEOGRAPH + {0xB660, 0x8DC6}, //3268 #CJK UNIFIED IDEOGRAPH + {0xB661, 0x8EFB}, //3269 #CJK UNIFIED IDEOGRAPH + {0xB662, 0x8EF8}, //3270 #CJK UNIFIED IDEOGRAPH + {0xB663, 0x8EFC}, //3271 #CJK UNIFIED IDEOGRAPH + {0xB664, 0x8F9C}, //3272 #CJK UNIFIED IDEOGRAPH + {0xB665, 0x902E}, //3273 #CJK UNIFIED IDEOGRAPH + {0xB666, 0x9035}, //3274 #CJK UNIFIED IDEOGRAPH + {0xB667, 0x9031}, //3275 #CJK UNIFIED IDEOGRAPH + {0xB668, 0x9038}, //3276 #CJK UNIFIED IDEOGRAPH + {0xB669, 0x9032}, //3277 #CJK UNIFIED IDEOGRAPH + {0xB66A, 0x9036}, //3278 #CJK UNIFIED IDEOGRAPH + {0xB66B, 0x9102}, //3279 #CJK UNIFIED IDEOGRAPH + {0xB66C, 0x90F5}, //3280 #CJK UNIFIED IDEOGRAPH + {0xB66D, 0x9109}, //3281 #CJK UNIFIED IDEOGRAPH + {0xB66E, 0x90FE}, //3282 #CJK UNIFIED IDEOGRAPH + {0xB66F, 0x9163}, //3283 #CJK UNIFIED IDEOGRAPH + {0xB670, 0x9165}, //3284 #CJK UNIFIED IDEOGRAPH + {0xB671, 0x91CF}, //3285 #CJK UNIFIED IDEOGRAPH + {0xB672, 0x9214}, //3286 #CJK UNIFIED IDEOGRAPH + {0xB673, 0x9215}, //3287 #CJK UNIFIED IDEOGRAPH + {0xB674, 0x9223}, //3288 #CJK UNIFIED IDEOGRAPH + {0xB675, 0x9209}, //3289 #CJK UNIFIED IDEOGRAPH + {0xB676, 0x921E}, //3290 #CJK UNIFIED IDEOGRAPH + {0xB677, 0x920D}, //3291 #CJK UNIFIED IDEOGRAPH + {0xB678, 0x9210}, //3292 #CJK UNIFIED IDEOGRAPH + {0xB679, 0x9207}, //3293 #CJK UNIFIED IDEOGRAPH + {0xB67A, 0x9211}, //3294 #CJK UNIFIED IDEOGRAPH + {0xB67B, 0x9594}, //3295 #CJK UNIFIED IDEOGRAPH + {0xB67C, 0x958F}, //3296 #CJK UNIFIED IDEOGRAPH + {0xB67D, 0x958B}, //3297 #CJK UNIFIED IDEOGRAPH + {0xB67E, 0x9591}, //3298 #CJK UNIFIED IDEOGRAPH + {0xB6A1, 0x9593}, //3299 #CJK UNIFIED IDEOGRAPH + {0xB6A2, 0x9592}, //3300 #CJK UNIFIED IDEOGRAPH + {0xB6A3, 0x958E}, //3301 #CJK UNIFIED IDEOGRAPH + {0xB6A4, 0x968A}, //3302 #CJK UNIFIED IDEOGRAPH + {0xB6A5, 0x968E}, //3303 #CJK UNIFIED IDEOGRAPH + {0xB6A6, 0x968B}, //3304 #CJK UNIFIED IDEOGRAPH + {0xB6A7, 0x967D}, //3305 #CJK UNIFIED IDEOGRAPH + {0xB6A8, 0x9685}, //3306 #CJK UNIFIED IDEOGRAPH + {0xB6A9, 0x9686}, //3307 #CJK UNIFIED IDEOGRAPH + {0xB6AA, 0x968D}, //3308 #CJK UNIFIED IDEOGRAPH + {0xB6AB, 0x9672}, //3309 #CJK UNIFIED IDEOGRAPH + {0xB6AC, 0x9684}, //3310 #CJK UNIFIED IDEOGRAPH + {0xB6AD, 0x96C1}, //3311 #CJK UNIFIED IDEOGRAPH + {0xB6AE, 0x96C5}, //3312 #CJK UNIFIED IDEOGRAPH + {0xB6AF, 0x96C4}, //3313 #CJK UNIFIED IDEOGRAPH + {0xB6B0, 0x96C6}, //3314 #CJK UNIFIED IDEOGRAPH + {0xB6B1, 0x96C7}, //3315 #CJK UNIFIED IDEOGRAPH + {0xB6B2, 0x96EF}, //3316 #CJK UNIFIED IDEOGRAPH + {0xB6B3, 0x96F2}, //3317 #CJK UNIFIED IDEOGRAPH + {0xB6B4, 0x97CC}, //3318 #CJK UNIFIED IDEOGRAPH + {0xB6B5, 0x9805}, //3319 #CJK UNIFIED IDEOGRAPH + {0xB6B6, 0x9806}, //3320 #CJK UNIFIED IDEOGRAPH + {0xB6B7, 0x9808}, //3321 #CJK UNIFIED IDEOGRAPH + {0xB6B8, 0x98E7}, //3322 #CJK UNIFIED IDEOGRAPH + {0xB6B9, 0x98EA}, //3323 #CJK UNIFIED IDEOGRAPH + {0xB6BA, 0x98EF}, //3324 #CJK UNIFIED IDEOGRAPH + {0xB6BB, 0x98E9}, //3325 #CJK UNIFIED IDEOGRAPH + {0xB6BC, 0x98F2}, //3326 #CJK UNIFIED IDEOGRAPH + {0xB6BD, 0x98ED}, //3327 #CJK UNIFIED IDEOGRAPH + {0xB6BE, 0x99AE}, //3328 #CJK UNIFIED IDEOGRAPH + {0xB6BF, 0x99AD}, //3329 #CJK UNIFIED IDEOGRAPH + {0xB6C0, 0x9EC3}, //3330 #CJK UNIFIED IDEOGRAPH + {0xB6C1, 0x9ECD}, //3331 #CJK UNIFIED IDEOGRAPH + {0xB6C2, 0x9ED1}, //3332 #CJK UNIFIED IDEOGRAPH + {0xB6C3, 0x4E82}, //3333 #CJK UNIFIED IDEOGRAPH + {0xB6C4, 0x50AD}, //3334 #CJK UNIFIED IDEOGRAPH + {0xB6C5, 0x50B5}, //3335 #CJK UNIFIED IDEOGRAPH + {0xB6C6, 0x50B2}, //3336 #CJK UNIFIED IDEOGRAPH + {0xB6C7, 0x50B3}, //3337 #CJK UNIFIED IDEOGRAPH + {0xB6C8, 0x50C5}, //3338 #CJK UNIFIED IDEOGRAPH + {0xB6C9, 0x50BE}, //3339 #CJK UNIFIED IDEOGRAPH + {0xB6CA, 0x50AC}, //3340 #CJK UNIFIED IDEOGRAPH + {0xB6CB, 0x50B7}, //3341 #CJK UNIFIED IDEOGRAPH + {0xB6CC, 0x50BB}, //3342 #CJK UNIFIED IDEOGRAPH + {0xB6CD, 0x50AF}, //3343 #CJK UNIFIED IDEOGRAPH + {0xB6CE, 0x50C7}, //3344 #CJK UNIFIED IDEOGRAPH + {0xB6CF, 0x527F}, //3345 #CJK UNIFIED IDEOGRAPH + {0xB6D0, 0x5277}, //3346 #CJK UNIFIED IDEOGRAPH + {0xB6D1, 0x527D}, //3347 #CJK UNIFIED IDEOGRAPH + {0xB6D2, 0x52DF}, //3348 #CJK UNIFIED IDEOGRAPH + {0xB6D3, 0x52E6}, //3349 #CJK UNIFIED IDEOGRAPH + {0xB6D4, 0x52E4}, //3350 #CJK UNIFIED IDEOGRAPH + {0xB6D5, 0x52E2}, //3351 #CJK UNIFIED IDEOGRAPH + {0xB6D6, 0x52E3}, //3352 #CJK UNIFIED IDEOGRAPH + {0xB6D7, 0x532F}, //3353 #CJK UNIFIED IDEOGRAPH + {0xB6D8, 0x55DF}, //3354 #CJK UNIFIED IDEOGRAPH + {0xB6D9, 0x55E8}, //3355 #CJK UNIFIED IDEOGRAPH + {0xB6DA, 0x55D3}, //3356 #CJK UNIFIED IDEOGRAPH + {0xB6DB, 0x55E6}, //3357 #CJK UNIFIED IDEOGRAPH + {0xB6DC, 0x55CE}, //3358 #CJK UNIFIED IDEOGRAPH + {0xB6DD, 0x55DC}, //3359 #CJK UNIFIED IDEOGRAPH + {0xB6DE, 0x55C7}, //3360 #CJK UNIFIED IDEOGRAPH + {0xB6DF, 0x55D1}, //3361 #CJK UNIFIED IDEOGRAPH + {0xB6E0, 0x55E3}, //3362 #CJK UNIFIED IDEOGRAPH + {0xB6E1, 0x55E4}, //3363 #CJK UNIFIED IDEOGRAPH + {0xB6E2, 0x55EF}, //3364 #CJK UNIFIED IDEOGRAPH + {0xB6E3, 0x55DA}, //3365 #CJK UNIFIED IDEOGRAPH + {0xB6E4, 0x55E1}, //3366 #CJK UNIFIED IDEOGRAPH + {0xB6E5, 0x55C5}, //3367 #CJK UNIFIED IDEOGRAPH + {0xB6E6, 0x55C6}, //3368 #CJK UNIFIED IDEOGRAPH + {0xB6E7, 0x55E5}, //3369 #CJK UNIFIED IDEOGRAPH + {0xB6E8, 0x55C9}, //3370 #CJK UNIFIED IDEOGRAPH + {0xB6E9, 0x5712}, //3371 #CJK UNIFIED IDEOGRAPH + {0xB6EA, 0x5713}, //3372 #CJK UNIFIED IDEOGRAPH + {0xB6EB, 0x585E}, //3373 #CJK UNIFIED IDEOGRAPH + {0xB6EC, 0x5851}, //3374 #CJK UNIFIED IDEOGRAPH + {0xB6ED, 0x5858}, //3375 #CJK UNIFIED IDEOGRAPH + {0xB6EE, 0x5857}, //3376 #CJK UNIFIED IDEOGRAPH + {0xB6EF, 0x585A}, //3377 #CJK UNIFIED IDEOGRAPH + {0xB6F0, 0x5854}, //3378 #CJK UNIFIED IDEOGRAPH + {0xB6F1, 0x586B}, //3379 #CJK UNIFIED IDEOGRAPH + {0xB6F2, 0x584C}, //3380 #CJK UNIFIED IDEOGRAPH + {0xB6F3, 0x586D}, //3381 #CJK UNIFIED IDEOGRAPH + {0xB6F4, 0x584A}, //3382 #CJK UNIFIED IDEOGRAPH + {0xB6F5, 0x5862}, //3383 #CJK UNIFIED IDEOGRAPH + {0xB6F6, 0x5852}, //3384 #CJK UNIFIED IDEOGRAPH + {0xB6F7, 0x584B}, //3385 #CJK UNIFIED IDEOGRAPH + {0xB6F8, 0x5967}, //3386 #CJK UNIFIED IDEOGRAPH + {0xB6F9, 0x5AC1}, //3387 #CJK UNIFIED IDEOGRAPH + {0xB6FA, 0x5AC9}, //3388 #CJK UNIFIED IDEOGRAPH + {0xB6FB, 0x5ACC}, //3389 #CJK UNIFIED IDEOGRAPH + {0xB6FC, 0x5ABE}, //3390 #CJK UNIFIED IDEOGRAPH + {0xB6FD, 0x5ABD}, //3391 #CJK UNIFIED IDEOGRAPH + {0xB6FE, 0x5ABC}, //3392 #CJK UNIFIED IDEOGRAPH + {0xB740, 0x5AB3}, //3393 #CJK UNIFIED IDEOGRAPH + {0xB741, 0x5AC2}, //3394 #CJK UNIFIED IDEOGRAPH + {0xB742, 0x5AB2}, //3395 #CJK UNIFIED IDEOGRAPH + {0xB743, 0x5D69}, //3396 #CJK UNIFIED IDEOGRAPH + {0xB744, 0x5D6F}, //3397 #CJK UNIFIED IDEOGRAPH + {0xB745, 0x5E4C}, //3398 #CJK UNIFIED IDEOGRAPH + {0xB746, 0x5E79}, //3399 #CJK UNIFIED IDEOGRAPH + {0xB747, 0x5EC9}, //3400 #CJK UNIFIED IDEOGRAPH + {0xB748, 0x5EC8}, //3401 #CJK UNIFIED IDEOGRAPH + {0xB749, 0x5F12}, //3402 #CJK UNIFIED IDEOGRAPH + {0xB74A, 0x5F59}, //3403 #CJK UNIFIED IDEOGRAPH + {0xB74B, 0x5FAC}, //3404 #CJK UNIFIED IDEOGRAPH + {0xB74C, 0x5FAE}, //3405 #CJK UNIFIED IDEOGRAPH + {0xB74D, 0x611A}, //3406 #CJK UNIFIED IDEOGRAPH + {0xB74E, 0x610F}, //3407 #CJK UNIFIED IDEOGRAPH + {0xB74F, 0x6148}, //3408 #CJK UNIFIED IDEOGRAPH + {0xB750, 0x611F}, //3409 #CJK UNIFIED IDEOGRAPH + {0xB751, 0x60F3}, //3410 #CJK UNIFIED IDEOGRAPH + {0xB752, 0x611B}, //3411 #CJK UNIFIED IDEOGRAPH + {0xB753, 0x60F9}, //3412 #CJK UNIFIED IDEOGRAPH + {0xB754, 0x6101}, //3413 #CJK UNIFIED IDEOGRAPH + {0xB755, 0x6108}, //3414 #CJK UNIFIED IDEOGRAPH + {0xB756, 0x614E}, //3415 #CJK UNIFIED IDEOGRAPH + {0xB757, 0x614C}, //3416 #CJK UNIFIED IDEOGRAPH + {0xB758, 0x6144}, //3417 #CJK UNIFIED IDEOGRAPH + {0xB759, 0x614D}, //3418 #CJK UNIFIED IDEOGRAPH + {0xB75A, 0x613E}, //3419 #CJK UNIFIED IDEOGRAPH + {0xB75B, 0x6134}, //3420 #CJK UNIFIED IDEOGRAPH + {0xB75C, 0x6127}, //3421 #CJK UNIFIED IDEOGRAPH + {0xB75D, 0x610D}, //3422 #CJK UNIFIED IDEOGRAPH + {0xB75E, 0x6106}, //3423 #CJK UNIFIED IDEOGRAPH + {0xB75F, 0x6137}, //3424 #CJK UNIFIED IDEOGRAPH + {0xB760, 0x6221}, //3425 #CJK UNIFIED IDEOGRAPH + {0xB761, 0x6222}, //3426 #CJK UNIFIED IDEOGRAPH + {0xB762, 0x6413}, //3427 #CJK UNIFIED IDEOGRAPH + {0xB763, 0x643E}, //3428 #CJK UNIFIED IDEOGRAPH + {0xB764, 0x641E}, //3429 #CJK UNIFIED IDEOGRAPH + {0xB765, 0x642A}, //3430 #CJK UNIFIED IDEOGRAPH + {0xB766, 0x642D}, //3431 #CJK UNIFIED IDEOGRAPH + {0xB767, 0x643D}, //3432 #CJK UNIFIED IDEOGRAPH + {0xB768, 0x642C}, //3433 #CJK UNIFIED IDEOGRAPH + {0xB769, 0x640F}, //3434 #CJK UNIFIED IDEOGRAPH + {0xB76A, 0x641C}, //3435 #CJK UNIFIED IDEOGRAPH + {0xB76B, 0x6414}, //3436 #CJK UNIFIED IDEOGRAPH + {0xB76C, 0x640D}, //3437 #CJK UNIFIED IDEOGRAPH + {0xB76D, 0x6436}, //3438 #CJK UNIFIED IDEOGRAPH + {0xB76E, 0x6416}, //3439 #CJK UNIFIED IDEOGRAPH + {0xB76F, 0x6417}, //3440 #CJK UNIFIED IDEOGRAPH + {0xB770, 0x6406}, //3441 #CJK UNIFIED IDEOGRAPH + {0xB771, 0x656C}, //3442 #CJK UNIFIED IDEOGRAPH + {0xB772, 0x659F}, //3443 #CJK UNIFIED IDEOGRAPH + {0xB773, 0x65B0}, //3444 #CJK UNIFIED IDEOGRAPH + {0xB774, 0x6697}, //3445 #CJK UNIFIED IDEOGRAPH + {0xB775, 0x6689}, //3446 #CJK UNIFIED IDEOGRAPH + {0xB776, 0x6687}, //3447 #CJK UNIFIED IDEOGRAPH + {0xB777, 0x6688}, //3448 #CJK UNIFIED IDEOGRAPH + {0xB778, 0x6696}, //3449 #CJK UNIFIED IDEOGRAPH + {0xB779, 0x6684}, //3450 #CJK UNIFIED IDEOGRAPH + {0xB77A, 0x6698}, //3451 #CJK UNIFIED IDEOGRAPH + {0xB77B, 0x668D}, //3452 #CJK UNIFIED IDEOGRAPH + {0xB77C, 0x6703}, //3453 #CJK UNIFIED IDEOGRAPH + {0xB77D, 0x6994}, //3454 #CJK UNIFIED IDEOGRAPH + {0xB77E, 0x696D}, //3455 #CJK UNIFIED IDEOGRAPH + {0xB7A1, 0x695A}, //3456 #CJK UNIFIED IDEOGRAPH + {0xB7A2, 0x6977}, //3457 #CJK UNIFIED IDEOGRAPH + {0xB7A3, 0x6960}, //3458 #CJK UNIFIED IDEOGRAPH + {0xB7A4, 0x6954}, //3459 #CJK UNIFIED IDEOGRAPH + {0xB7A5, 0x6975}, //3460 #CJK UNIFIED IDEOGRAPH + {0xB7A6, 0x6930}, //3461 #CJK UNIFIED IDEOGRAPH + {0xB7A7, 0x6982}, //3462 #CJK UNIFIED IDEOGRAPH + {0xB7A8, 0x694A}, //3463 #CJK UNIFIED IDEOGRAPH + {0xB7A9, 0x6968}, //3464 #CJK UNIFIED IDEOGRAPH + {0xB7AA, 0x696B}, //3465 #CJK UNIFIED IDEOGRAPH + {0xB7AB, 0x695E}, //3466 #CJK UNIFIED IDEOGRAPH + {0xB7AC, 0x6953}, //3467 #CJK UNIFIED IDEOGRAPH + {0xB7AD, 0x6979}, //3468 #CJK UNIFIED IDEOGRAPH + {0xB7AE, 0x6986}, //3469 #CJK UNIFIED IDEOGRAPH + {0xB7AF, 0x695D}, //3470 #CJK UNIFIED IDEOGRAPH + {0xB7B0, 0x6963}, //3471 #CJK UNIFIED IDEOGRAPH + {0xB7B1, 0x695B}, //3472 #CJK UNIFIED IDEOGRAPH + {0xB7B2, 0x6B47}, //3473 #CJK UNIFIED IDEOGRAPH + {0xB7B3, 0x6B72}, //3474 #CJK UNIFIED IDEOGRAPH + {0xB7B4, 0x6BC0}, //3475 #CJK UNIFIED IDEOGRAPH + {0xB7B5, 0x6BBF}, //3476 #CJK UNIFIED IDEOGRAPH + {0xB7B6, 0x6BD3}, //3477 #CJK UNIFIED IDEOGRAPH + {0xB7B7, 0x6BFD}, //3478 #CJK UNIFIED IDEOGRAPH + {0xB7B8, 0x6EA2}, //3479 #CJK UNIFIED IDEOGRAPH + {0xB7B9, 0x6EAF}, //3480 #CJK UNIFIED IDEOGRAPH + {0xB7BA, 0x6ED3}, //3481 #CJK UNIFIED IDEOGRAPH + {0xB7BB, 0x6EB6}, //3482 #CJK UNIFIED IDEOGRAPH + {0xB7BC, 0x6EC2}, //3483 #CJK UNIFIED IDEOGRAPH + {0xB7BD, 0x6E90}, //3484 #CJK UNIFIED IDEOGRAPH + {0xB7BE, 0x6E9D}, //3485 #CJK UNIFIED IDEOGRAPH + {0xB7BF, 0x6EC7}, //3486 #CJK UNIFIED IDEOGRAPH + {0xB7C0, 0x6EC5}, //3487 #CJK UNIFIED IDEOGRAPH + {0xB7C1, 0x6EA5}, //3488 #CJK UNIFIED IDEOGRAPH + {0xB7C2, 0x6E98}, //3489 #CJK UNIFIED IDEOGRAPH + {0xB7C3, 0x6EBC}, //3490 #CJK UNIFIED IDEOGRAPH + {0xB7C4, 0x6EBA}, //3491 #CJK UNIFIED IDEOGRAPH + {0xB7C5, 0x6EAB}, //3492 #CJK UNIFIED IDEOGRAPH + {0xB7C6, 0x6ED1}, //3493 #CJK UNIFIED IDEOGRAPH + {0xB7C7, 0x6E96}, //3494 #CJK UNIFIED IDEOGRAPH + {0xB7C8, 0x6E9C}, //3495 #CJK UNIFIED IDEOGRAPH + {0xB7C9, 0x6EC4}, //3496 #CJK UNIFIED IDEOGRAPH + {0xB7CA, 0x6ED4}, //3497 #CJK UNIFIED IDEOGRAPH + {0xB7CB, 0x6EAA}, //3498 #CJK UNIFIED IDEOGRAPH + {0xB7CC, 0x6EA7}, //3499 #CJK UNIFIED IDEOGRAPH + {0xB7CD, 0x6EB4}, //3500 #CJK UNIFIED IDEOGRAPH + {0xB7CE, 0x714E}, //3501 #CJK UNIFIED IDEOGRAPH + {0xB7CF, 0x7159}, //3502 #CJK UNIFIED IDEOGRAPH + {0xB7D0, 0x7169}, //3503 #CJK UNIFIED IDEOGRAPH + {0xB7D1, 0x7164}, //3504 #CJK UNIFIED IDEOGRAPH + {0xB7D2, 0x7149}, //3505 #CJK UNIFIED IDEOGRAPH + {0xB7D3, 0x7167}, //3506 #CJK UNIFIED IDEOGRAPH + {0xB7D4, 0x715C}, //3507 #CJK UNIFIED IDEOGRAPH + {0xB7D5, 0x716C}, //3508 #CJK UNIFIED IDEOGRAPH + {0xB7D6, 0x7166}, //3509 #CJK UNIFIED IDEOGRAPH + {0xB7D7, 0x714C}, //3510 #CJK UNIFIED IDEOGRAPH + {0xB7D8, 0x7165}, //3511 #CJK UNIFIED IDEOGRAPH + {0xB7D9, 0x715E}, //3512 #CJK UNIFIED IDEOGRAPH + {0xB7DA, 0x7146}, //3513 #CJK UNIFIED IDEOGRAPH + {0xB7DB, 0x7168}, //3514 #CJK UNIFIED IDEOGRAPH + {0xB7DC, 0x7156}, //3515 #CJK UNIFIED IDEOGRAPH + {0xB7DD, 0x723A}, //3516 #CJK UNIFIED IDEOGRAPH + {0xB7DE, 0x7252}, //3517 #CJK UNIFIED IDEOGRAPH + {0xB7DF, 0x7337}, //3518 #CJK UNIFIED IDEOGRAPH + {0xB7E0, 0x7345}, //3519 #CJK UNIFIED IDEOGRAPH + {0xB7E1, 0x733F}, //3520 #CJK UNIFIED IDEOGRAPH + {0xB7E2, 0x733E}, //3521 #CJK UNIFIED IDEOGRAPH + {0xB7E3, 0x746F}, //3522 #CJK UNIFIED IDEOGRAPH + {0xB7E4, 0x745A}, //3523 #CJK UNIFIED IDEOGRAPH + {0xB7E5, 0x7455}, //3524 #CJK UNIFIED IDEOGRAPH + {0xB7E6, 0x745F}, //3525 #CJK UNIFIED IDEOGRAPH + {0xB7E7, 0x745E}, //3526 #CJK UNIFIED IDEOGRAPH + {0xB7E8, 0x7441}, //3527 #CJK UNIFIED IDEOGRAPH + {0xB7E9, 0x743F}, //3528 #CJK UNIFIED IDEOGRAPH + {0xB7EA, 0x7459}, //3529 #CJK UNIFIED IDEOGRAPH + {0xB7EB, 0x745B}, //3530 #CJK UNIFIED IDEOGRAPH + {0xB7EC, 0x745C}, //3531 #CJK UNIFIED IDEOGRAPH + {0xB7ED, 0x7576}, //3532 #CJK UNIFIED IDEOGRAPH + {0xB7EE, 0x7578}, //3533 #CJK UNIFIED IDEOGRAPH + {0xB7EF, 0x7600}, //3534 #CJK UNIFIED IDEOGRAPH + {0xB7F0, 0x75F0}, //3535 #CJK UNIFIED IDEOGRAPH + {0xB7F1, 0x7601}, //3536 #CJK UNIFIED IDEOGRAPH + {0xB7F2, 0x75F2}, //3537 #CJK UNIFIED IDEOGRAPH + {0xB7F3, 0x75F1}, //3538 #CJK UNIFIED IDEOGRAPH + {0xB7F4, 0x75FA}, //3539 #CJK UNIFIED IDEOGRAPH + {0xB7F5, 0x75FF}, //3540 #CJK UNIFIED IDEOGRAPH + {0xB7F6, 0x75F4}, //3541 #CJK UNIFIED IDEOGRAPH + {0xB7F7, 0x75F3}, //3542 #CJK UNIFIED IDEOGRAPH + {0xB7F8, 0x76DE}, //3543 #CJK UNIFIED IDEOGRAPH + {0xB7F9, 0x76DF}, //3544 #CJK UNIFIED IDEOGRAPH + {0xB7FA, 0x775B}, //3545 #CJK UNIFIED IDEOGRAPH + {0xB7FB, 0x776B}, //3546 #CJK UNIFIED IDEOGRAPH + {0xB7FC, 0x7766}, //3547 #CJK UNIFIED IDEOGRAPH + {0xB7FD, 0x775E}, //3548 #CJK UNIFIED IDEOGRAPH + {0xB7FE, 0x7763}, //3549 #CJK UNIFIED IDEOGRAPH + {0xB840, 0x7779}, //3550 #CJK UNIFIED IDEOGRAPH + {0xB841, 0x776A}, //3551 #CJK UNIFIED IDEOGRAPH + {0xB842, 0x776C}, //3552 #CJK UNIFIED IDEOGRAPH + {0xB843, 0x775C}, //3553 #CJK UNIFIED IDEOGRAPH + {0xB844, 0x7765}, //3554 #CJK UNIFIED IDEOGRAPH + {0xB845, 0x7768}, //3555 #CJK UNIFIED IDEOGRAPH + {0xB846, 0x7762}, //3556 #CJK UNIFIED IDEOGRAPH + {0xB847, 0x77EE}, //3557 #CJK UNIFIED IDEOGRAPH + {0xB848, 0x788E}, //3558 #CJK UNIFIED IDEOGRAPH + {0xB849, 0x78B0}, //3559 #CJK UNIFIED IDEOGRAPH + {0xB84A, 0x7897}, //3560 #CJK UNIFIED IDEOGRAPH + {0xB84B, 0x7898}, //3561 #CJK UNIFIED IDEOGRAPH + {0xB84C, 0x788C}, //3562 #CJK UNIFIED IDEOGRAPH + {0xB84D, 0x7889}, //3563 #CJK UNIFIED IDEOGRAPH + {0xB84E, 0x787C}, //3564 #CJK UNIFIED IDEOGRAPH + {0xB84F, 0x7891}, //3565 #CJK UNIFIED IDEOGRAPH + {0xB850, 0x7893}, //3566 #CJK UNIFIED IDEOGRAPH + {0xB851, 0x787F}, //3567 #CJK UNIFIED IDEOGRAPH + {0xB852, 0x797A}, //3568 #CJK UNIFIED IDEOGRAPH + {0xB853, 0x797F}, //3569 #CJK UNIFIED IDEOGRAPH + {0xB854, 0x7981}, //3570 #CJK UNIFIED IDEOGRAPH + {0xB855, 0x842C}, //3571 #CJK UNIFIED IDEOGRAPH + {0xB856, 0x79BD}, //3572 #CJK UNIFIED IDEOGRAPH + {0xB857, 0x7A1C}, //3573 #CJK UNIFIED IDEOGRAPH + {0xB858, 0x7A1A}, //3574 #CJK UNIFIED IDEOGRAPH + {0xB859, 0x7A20}, //3575 #CJK UNIFIED IDEOGRAPH + {0xB85A, 0x7A14}, //3576 #CJK UNIFIED IDEOGRAPH + {0xB85B, 0x7A1F}, //3577 #CJK UNIFIED IDEOGRAPH + {0xB85C, 0x7A1E}, //3578 #CJK UNIFIED IDEOGRAPH + {0xB85D, 0x7A9F}, //3579 #CJK UNIFIED IDEOGRAPH + {0xB85E, 0x7AA0}, //3580 #CJK UNIFIED IDEOGRAPH + {0xB85F, 0x7B77}, //3581 #CJK UNIFIED IDEOGRAPH + {0xB860, 0x7BC0}, //3582 #CJK UNIFIED IDEOGRAPH + {0xB861, 0x7B60}, //3583 #CJK UNIFIED IDEOGRAPH + {0xB862, 0x7B6E}, //3584 #CJK UNIFIED IDEOGRAPH + {0xB863, 0x7B67}, //3585 #CJK UNIFIED IDEOGRAPH + {0xB864, 0x7CB1}, //3586 #CJK UNIFIED IDEOGRAPH + {0xB865, 0x7CB3}, //3587 #CJK UNIFIED IDEOGRAPH + {0xB866, 0x7CB5}, //3588 #CJK UNIFIED IDEOGRAPH + {0xB867, 0x7D93}, //3589 #CJK UNIFIED IDEOGRAPH + {0xB868, 0x7D79}, //3590 #CJK UNIFIED IDEOGRAPH + {0xB869, 0x7D91}, //3591 #CJK UNIFIED IDEOGRAPH + {0xB86A, 0x7D81}, //3592 #CJK UNIFIED IDEOGRAPH + {0xB86B, 0x7D8F}, //3593 #CJK UNIFIED IDEOGRAPH + {0xB86C, 0x7D5B}, //3594 #CJK UNIFIED IDEOGRAPH + {0xB86D, 0x7F6E}, //3595 #CJK UNIFIED IDEOGRAPH + {0xB86E, 0x7F69}, //3596 #CJK UNIFIED IDEOGRAPH + {0xB86F, 0x7F6A}, //3597 #CJK UNIFIED IDEOGRAPH + {0xB870, 0x7F72}, //3598 #CJK UNIFIED IDEOGRAPH + {0xB871, 0x7FA9}, //3599 #CJK UNIFIED IDEOGRAPH + {0xB872, 0x7FA8}, //3600 #CJK UNIFIED IDEOGRAPH + {0xB873, 0x7FA4}, //3601 #CJK UNIFIED IDEOGRAPH + {0xB874, 0x8056}, //3602 #CJK UNIFIED IDEOGRAPH + {0xB875, 0x8058}, //3603 #CJK UNIFIED IDEOGRAPH + {0xB876, 0x8086}, //3604 #CJK UNIFIED IDEOGRAPH + {0xB877, 0x8084}, //3605 #CJK UNIFIED IDEOGRAPH + {0xB878, 0x8171}, //3606 #CJK UNIFIED IDEOGRAPH + {0xB879, 0x8170}, //3607 #CJK UNIFIED IDEOGRAPH + {0xB87A, 0x8178}, //3608 #CJK UNIFIED IDEOGRAPH + {0xB87B, 0x8165}, //3609 #CJK UNIFIED IDEOGRAPH + {0xB87C, 0x816E}, //3610 #CJK UNIFIED IDEOGRAPH + {0xB87D, 0x8173}, //3611 #CJK UNIFIED IDEOGRAPH + {0xB87E, 0x816B}, //3612 #CJK UNIFIED IDEOGRAPH + {0xB8A1, 0x8179}, //3613 #CJK UNIFIED IDEOGRAPH + {0xB8A2, 0x817A}, //3614 #CJK UNIFIED IDEOGRAPH + {0xB8A3, 0x8166}, //3615 #CJK UNIFIED IDEOGRAPH + {0xB8A4, 0x8205}, //3616 #CJK UNIFIED IDEOGRAPH + {0xB8A5, 0x8247}, //3617 #CJK UNIFIED IDEOGRAPH + {0xB8A6, 0x8482}, //3618 #CJK UNIFIED IDEOGRAPH + {0xB8A7, 0x8477}, //3619 #CJK UNIFIED IDEOGRAPH + {0xB8A8, 0x843D}, //3620 #CJK UNIFIED IDEOGRAPH + {0xB8A9, 0x8431}, //3621 #CJK UNIFIED IDEOGRAPH + {0xB8AA, 0x8475}, //3622 #CJK UNIFIED IDEOGRAPH + {0xB8AB, 0x8466}, //3623 #CJK UNIFIED IDEOGRAPH + {0xB8AC, 0x846B}, //3624 #CJK UNIFIED IDEOGRAPH + {0xB8AD, 0x8449}, //3625 #CJK UNIFIED IDEOGRAPH + {0xB8AE, 0x846C}, //3626 #CJK UNIFIED IDEOGRAPH + {0xB8AF, 0x845B}, //3627 #CJK UNIFIED IDEOGRAPH + {0xB8B0, 0x843C}, //3628 #CJK UNIFIED IDEOGRAPH + {0xB8B1, 0x8435}, //3629 #CJK UNIFIED IDEOGRAPH + {0xB8B2, 0x8461}, //3630 #CJK UNIFIED IDEOGRAPH + {0xB8B3, 0x8463}, //3631 #CJK UNIFIED IDEOGRAPH + {0xB8B4, 0x8469}, //3632 #CJK UNIFIED IDEOGRAPH + {0xB8B5, 0x846D}, //3633 #CJK UNIFIED IDEOGRAPH + {0xB8B6, 0x8446}, //3634 #CJK UNIFIED IDEOGRAPH + {0xB8B7, 0x865E}, //3635 #CJK UNIFIED IDEOGRAPH + {0xB8B8, 0x865C}, //3636 #CJK UNIFIED IDEOGRAPH + {0xB8B9, 0x865F}, //3637 #CJK UNIFIED IDEOGRAPH + {0xB8BA, 0x86F9}, //3638 #CJK UNIFIED IDEOGRAPH + {0xB8BB, 0x8713}, //3639 #CJK UNIFIED IDEOGRAPH + {0xB8BC, 0x8708}, //3640 #CJK UNIFIED IDEOGRAPH + {0xB8BD, 0x8707}, //3641 #CJK UNIFIED IDEOGRAPH + {0xB8BE, 0x8700}, //3642 #CJK UNIFIED IDEOGRAPH + {0xB8BF, 0x86FE}, //3643 #CJK UNIFIED IDEOGRAPH + {0xB8C0, 0x86FB}, //3644 #CJK UNIFIED IDEOGRAPH + {0xB8C1, 0x8702}, //3645 #CJK UNIFIED IDEOGRAPH + {0xB8C2, 0x8703}, //3646 #CJK UNIFIED IDEOGRAPH + {0xB8C3, 0x8706}, //3647 #CJK UNIFIED IDEOGRAPH + {0xB8C4, 0x870A}, //3648 #CJK UNIFIED IDEOGRAPH + {0xB8C5, 0x8859}, //3649 #CJK UNIFIED IDEOGRAPH + {0xB8C6, 0x88DF}, //3650 #CJK UNIFIED IDEOGRAPH + {0xB8C7, 0x88D4}, //3651 #CJK UNIFIED IDEOGRAPH + {0xB8C8, 0x88D9}, //3652 #CJK UNIFIED IDEOGRAPH + {0xB8C9, 0x88DC}, //3653 #CJK UNIFIED IDEOGRAPH + {0xB8CA, 0x88D8}, //3654 #CJK UNIFIED IDEOGRAPH + {0xB8CB, 0x88DD}, //3655 #CJK UNIFIED IDEOGRAPH + {0xB8CC, 0x88E1}, //3656 #CJK UNIFIED IDEOGRAPH + {0xB8CD, 0x88CA}, //3657 #CJK UNIFIED IDEOGRAPH + {0xB8CE, 0x88D5}, //3658 #CJK UNIFIED IDEOGRAPH + {0xB8CF, 0x88D2}, //3659 #CJK UNIFIED IDEOGRAPH + {0xB8D0, 0x899C}, //3660 #CJK UNIFIED IDEOGRAPH + {0xB8D1, 0x89E3}, //3661 #CJK UNIFIED IDEOGRAPH + {0xB8D2, 0x8A6B}, //3662 #CJK UNIFIED IDEOGRAPH + {0xB8D3, 0x8A72}, //3663 #CJK UNIFIED IDEOGRAPH + {0xB8D4, 0x8A73}, //3664 #CJK UNIFIED IDEOGRAPH + {0xB8D5, 0x8A66}, //3665 #CJK UNIFIED IDEOGRAPH + {0xB8D6, 0x8A69}, //3666 #CJK UNIFIED IDEOGRAPH + {0xB8D7, 0x8A70}, //3667 #CJK UNIFIED IDEOGRAPH + {0xB8D8, 0x8A87}, //3668 #CJK UNIFIED IDEOGRAPH + {0xB8D9, 0x8A7C}, //3669 #CJK UNIFIED IDEOGRAPH + {0xB8DA, 0x8A63}, //3670 #CJK UNIFIED IDEOGRAPH + {0xB8DB, 0x8AA0}, //3671 #CJK UNIFIED IDEOGRAPH + {0xB8DC, 0x8A71}, //3672 #CJK UNIFIED IDEOGRAPH + {0xB8DD, 0x8A85}, //3673 #CJK UNIFIED IDEOGRAPH + {0xB8DE, 0x8A6D}, //3674 #CJK UNIFIED IDEOGRAPH + {0xB8DF, 0x8A62}, //3675 #CJK UNIFIED IDEOGRAPH + {0xB8E0, 0x8A6E}, //3676 #CJK UNIFIED IDEOGRAPH + {0xB8E1, 0x8A6C}, //3677 #CJK UNIFIED IDEOGRAPH + {0xB8E2, 0x8A79}, //3678 #CJK UNIFIED IDEOGRAPH + {0xB8E3, 0x8A7B}, //3679 #CJK UNIFIED IDEOGRAPH + {0xB8E4, 0x8A3E}, //3680 #CJK UNIFIED IDEOGRAPH + {0xB8E5, 0x8A68}, //3681 #CJK UNIFIED IDEOGRAPH + {0xB8E6, 0x8C62}, //3682 #CJK UNIFIED IDEOGRAPH + {0xB8E7, 0x8C8A}, //3683 #CJK UNIFIED IDEOGRAPH + {0xB8E8, 0x8C89}, //3684 #CJK UNIFIED IDEOGRAPH + {0xB8E9, 0x8CCA}, //3685 #CJK UNIFIED IDEOGRAPH + {0xB8EA, 0x8CC7}, //3686 #CJK UNIFIED IDEOGRAPH + {0xB8EB, 0x8CC8}, //3687 #CJK UNIFIED IDEOGRAPH + {0xB8EC, 0x8CC4}, //3688 #CJK UNIFIED IDEOGRAPH + {0xB8ED, 0x8CB2}, //3689 #CJK UNIFIED IDEOGRAPH + {0xB8EE, 0x8CC3}, //3690 #CJK UNIFIED IDEOGRAPH + {0xB8EF, 0x8CC2}, //3691 #CJK UNIFIED IDEOGRAPH + {0xB8F0, 0x8CC5}, //3692 #CJK UNIFIED IDEOGRAPH + {0xB8F1, 0x8DE1}, //3693 #CJK UNIFIED IDEOGRAPH + {0xB8F2, 0x8DDF}, //3694 #CJK UNIFIED IDEOGRAPH + {0xB8F3, 0x8DE8}, //3695 #CJK UNIFIED IDEOGRAPH + {0xB8F4, 0x8DEF}, //3696 #CJK UNIFIED IDEOGRAPH + {0xB8F5, 0x8DF3}, //3697 #CJK UNIFIED IDEOGRAPH + {0xB8F6, 0x8DFA}, //3698 #CJK UNIFIED IDEOGRAPH + {0xB8F7, 0x8DEA}, //3699 #CJK UNIFIED IDEOGRAPH + {0xB8F8, 0x8DE4}, //3700 #CJK UNIFIED IDEOGRAPH + {0xB8F9, 0x8DE6}, //3701 #CJK UNIFIED IDEOGRAPH + {0xB8FA, 0x8EB2}, //3702 #CJK UNIFIED IDEOGRAPH + {0xB8FB, 0x8F03}, //3703 #CJK UNIFIED IDEOGRAPH + {0xB8FC, 0x8F09}, //3704 #CJK UNIFIED IDEOGRAPH + {0xB8FD, 0x8EFE}, //3705 #CJK UNIFIED IDEOGRAPH + {0xB8FE, 0x8F0A}, //3706 #CJK UNIFIED IDEOGRAPH + {0xB940, 0x8F9F}, //3707 #CJK UNIFIED IDEOGRAPH + {0xB941, 0x8FB2}, //3708 #CJK UNIFIED IDEOGRAPH + {0xB942, 0x904B}, //3709 #CJK UNIFIED IDEOGRAPH + {0xB943, 0x904A}, //3710 #CJK UNIFIED IDEOGRAPH + {0xB944, 0x9053}, //3711 #CJK UNIFIED IDEOGRAPH + {0xB945, 0x9042}, //3712 #CJK UNIFIED IDEOGRAPH + {0xB946, 0x9054}, //3713 #CJK UNIFIED IDEOGRAPH + {0xB947, 0x903C}, //3714 #CJK UNIFIED IDEOGRAPH + {0xB948, 0x9055}, //3715 #CJK UNIFIED IDEOGRAPH + {0xB949, 0x9050}, //3716 #CJK UNIFIED IDEOGRAPH + {0xB94A, 0x9047}, //3717 #CJK UNIFIED IDEOGRAPH + {0xB94B, 0x904F}, //3718 #CJK UNIFIED IDEOGRAPH + {0xB94C, 0x904E}, //3719 #CJK UNIFIED IDEOGRAPH + {0xB94D, 0x904D}, //3720 #CJK UNIFIED IDEOGRAPH + {0xB94E, 0x9051}, //3721 #CJK UNIFIED IDEOGRAPH + {0xB94F, 0x903E}, //3722 #CJK UNIFIED IDEOGRAPH + {0xB950, 0x9041}, //3723 #CJK UNIFIED IDEOGRAPH + {0xB951, 0x9112}, //3724 #CJK UNIFIED IDEOGRAPH + {0xB952, 0x9117}, //3725 #CJK UNIFIED IDEOGRAPH + {0xB953, 0x916C}, //3726 #CJK UNIFIED IDEOGRAPH + {0xB954, 0x916A}, //3727 #CJK UNIFIED IDEOGRAPH + {0xB955, 0x9169}, //3728 #CJK UNIFIED IDEOGRAPH + {0xB956, 0x91C9}, //3729 #CJK UNIFIED IDEOGRAPH + {0xB957, 0x9237}, //3730 #CJK UNIFIED IDEOGRAPH + {0xB958, 0x9257}, //3731 #CJK UNIFIED IDEOGRAPH + {0xB959, 0x9238}, //3732 #CJK UNIFIED IDEOGRAPH + {0xB95A, 0x923D}, //3733 #CJK UNIFIED IDEOGRAPH + {0xB95B, 0x9240}, //3734 #CJK UNIFIED IDEOGRAPH + {0xB95C, 0x923E}, //3735 #CJK UNIFIED IDEOGRAPH + {0xB95D, 0x925B}, //3736 #CJK UNIFIED IDEOGRAPH + {0xB95E, 0x924B}, //3737 #CJK UNIFIED IDEOGRAPH + {0xB95F, 0x9264}, //3738 #CJK UNIFIED IDEOGRAPH + {0xB960, 0x9251}, //3739 #CJK UNIFIED IDEOGRAPH + {0xB961, 0x9234}, //3740 #CJK UNIFIED IDEOGRAPH + {0xB962, 0x9249}, //3741 #CJK UNIFIED IDEOGRAPH + {0xB963, 0x924D}, //3742 #CJK UNIFIED IDEOGRAPH + {0xB964, 0x9245}, //3743 #CJK UNIFIED IDEOGRAPH + {0xB965, 0x9239}, //3744 #CJK UNIFIED IDEOGRAPH + {0xB966, 0x923F}, //3745 #CJK UNIFIED IDEOGRAPH + {0xB967, 0x925A}, //3746 #CJK UNIFIED IDEOGRAPH + {0xB968, 0x9598}, //3747 #CJK UNIFIED IDEOGRAPH + {0xB969, 0x9698}, //3748 #CJK UNIFIED IDEOGRAPH + {0xB96A, 0x9694}, //3749 #CJK UNIFIED IDEOGRAPH + {0xB96B, 0x9695}, //3750 #CJK UNIFIED IDEOGRAPH + {0xB96C, 0x96CD}, //3751 #CJK UNIFIED IDEOGRAPH + {0xB96D, 0x96CB}, //3752 #CJK UNIFIED IDEOGRAPH + {0xB96E, 0x96C9}, //3753 #CJK UNIFIED IDEOGRAPH + {0xB96F, 0x96CA}, //3754 #CJK UNIFIED IDEOGRAPH + {0xB970, 0x96F7}, //3755 #CJK UNIFIED IDEOGRAPH + {0xB971, 0x96FB}, //3756 #CJK UNIFIED IDEOGRAPH + {0xB972, 0x96F9}, //3757 #CJK UNIFIED IDEOGRAPH + {0xB973, 0x96F6}, //3758 #CJK UNIFIED IDEOGRAPH + {0xB974, 0x9756}, //3759 #CJK UNIFIED IDEOGRAPH + {0xB975, 0x9774}, //3760 #CJK UNIFIED IDEOGRAPH + {0xB976, 0x9776}, //3761 #CJK UNIFIED IDEOGRAPH + {0xB977, 0x9810}, //3762 #CJK UNIFIED IDEOGRAPH + {0xB978, 0x9811}, //3763 #CJK UNIFIED IDEOGRAPH + {0xB979, 0x9813}, //3764 #CJK UNIFIED IDEOGRAPH + {0xB97A, 0x980A}, //3765 #CJK UNIFIED IDEOGRAPH + {0xB97B, 0x9812}, //3766 #CJK UNIFIED IDEOGRAPH + {0xB97C, 0x980C}, //3767 #CJK UNIFIED IDEOGRAPH + {0xB97D, 0x98FC}, //3768 #CJK UNIFIED IDEOGRAPH + {0xB97E, 0x98F4}, //3769 #CJK UNIFIED IDEOGRAPH + {0xB9A1, 0x98FD}, //3770 #CJK UNIFIED IDEOGRAPH + {0xB9A2, 0x98FE}, //3771 #CJK UNIFIED IDEOGRAPH + {0xB9A3, 0x99B3}, //3772 #CJK UNIFIED IDEOGRAPH + {0xB9A4, 0x99B1}, //3773 #CJK UNIFIED IDEOGRAPH + {0xB9A5, 0x99B4}, //3774 #CJK UNIFIED IDEOGRAPH + {0xB9A6, 0x9AE1}, //3775 #CJK UNIFIED IDEOGRAPH + {0xB9A7, 0x9CE9}, //3776 #CJK UNIFIED IDEOGRAPH + {0xB9A8, 0x9E82}, //3777 #CJK UNIFIED IDEOGRAPH + {0xB9A9, 0x9F0E}, //3778 #CJK UNIFIED IDEOGRAPH + {0xB9AA, 0x9F13}, //3779 #CJK UNIFIED IDEOGRAPH + {0xB9AB, 0x9F20}, //3780 #CJK UNIFIED IDEOGRAPH + {0xB9AC, 0x50E7}, //3781 #CJK UNIFIED IDEOGRAPH + {0xB9AD, 0x50EE}, //3782 #CJK UNIFIED IDEOGRAPH + {0xB9AE, 0x50E5}, //3783 #CJK UNIFIED IDEOGRAPH + {0xB9AF, 0x50D6}, //3784 #CJK UNIFIED IDEOGRAPH + {0xB9B0, 0x50ED}, //3785 #CJK UNIFIED IDEOGRAPH + {0xB9B1, 0x50DA}, //3786 #CJK UNIFIED IDEOGRAPH + {0xB9B2, 0x50D5}, //3787 #CJK UNIFIED IDEOGRAPH + {0xB9B3, 0x50CF}, //3788 #CJK UNIFIED IDEOGRAPH + {0xB9B4, 0x50D1}, //3789 #CJK UNIFIED IDEOGRAPH + {0xB9B5, 0x50F1}, //3790 #CJK UNIFIED IDEOGRAPH + {0xB9B6, 0x50CE}, //3791 #CJK UNIFIED IDEOGRAPH + {0xB9B7, 0x50E9}, //3792 #CJK UNIFIED IDEOGRAPH + {0xB9B8, 0x5162}, //3793 #CJK UNIFIED IDEOGRAPH + {0xB9B9, 0x51F3}, //3794 #CJK UNIFIED IDEOGRAPH + {0xB9BA, 0x5283}, //3795 #CJK UNIFIED IDEOGRAPH + {0xB9BB, 0x5282}, //3796 #CJK UNIFIED IDEOGRAPH + {0xB9BC, 0x5331}, //3797 #CJK UNIFIED IDEOGRAPH + {0xB9BD, 0x53AD}, //3798 #CJK UNIFIED IDEOGRAPH + {0xB9BE, 0x55FE}, //3799 #CJK UNIFIED IDEOGRAPH + {0xB9BF, 0x5600}, //3800 #CJK UNIFIED IDEOGRAPH + {0xB9C0, 0x561B}, //3801 #CJK UNIFIED IDEOGRAPH + {0xB9C1, 0x5617}, //3802 #CJK UNIFIED IDEOGRAPH + {0xB9C2, 0x55FD}, //3803 #CJK UNIFIED IDEOGRAPH + {0xB9C3, 0x5614}, //3804 #CJK UNIFIED IDEOGRAPH + {0xB9C4, 0x5606}, //3805 #CJK UNIFIED IDEOGRAPH + {0xB9C5, 0x5609}, //3806 #CJK UNIFIED IDEOGRAPH + {0xB9C6, 0x560D}, //3807 #CJK UNIFIED IDEOGRAPH + {0xB9C7, 0x560E}, //3808 #CJK UNIFIED IDEOGRAPH + {0xB9C8, 0x55F7}, //3809 #CJK UNIFIED IDEOGRAPH + {0xB9C9, 0x5616}, //3810 #CJK UNIFIED IDEOGRAPH + {0xB9CA, 0x561F}, //3811 #CJK UNIFIED IDEOGRAPH + {0xB9CB, 0x5608}, //3812 #CJK UNIFIED IDEOGRAPH + {0xB9CC, 0x5610}, //3813 #CJK UNIFIED IDEOGRAPH + {0xB9CD, 0x55F6}, //3814 #CJK UNIFIED IDEOGRAPH + {0xB9CE, 0x5718}, //3815 #CJK UNIFIED IDEOGRAPH + {0xB9CF, 0x5716}, //3816 #CJK UNIFIED IDEOGRAPH + {0xB9D0, 0x5875}, //3817 #CJK UNIFIED IDEOGRAPH + {0xB9D1, 0x587E}, //3818 #CJK UNIFIED IDEOGRAPH + {0xB9D2, 0x5883}, //3819 #CJK UNIFIED IDEOGRAPH + {0xB9D3, 0x5893}, //3820 #CJK UNIFIED IDEOGRAPH + {0xB9D4, 0x588A}, //3821 #CJK UNIFIED IDEOGRAPH + {0xB9D5, 0x5879}, //3822 #CJK UNIFIED IDEOGRAPH + {0xB9D6, 0x5885}, //3823 #CJK UNIFIED IDEOGRAPH + {0xB9D7, 0x587D}, //3824 #CJK UNIFIED IDEOGRAPH + {0xB9D8, 0x58FD}, //3825 #CJK UNIFIED IDEOGRAPH + {0xB9D9, 0x5925}, //3826 #CJK UNIFIED IDEOGRAPH + {0xB9DA, 0x5922}, //3827 #CJK UNIFIED IDEOGRAPH + {0xB9DB, 0x5924}, //3828 #CJK UNIFIED IDEOGRAPH + {0xB9DC, 0x596A}, //3829 #CJK UNIFIED IDEOGRAPH + {0xB9DD, 0x5969}, //3830 #CJK UNIFIED IDEOGRAPH + {0xB9DE, 0x5AE1}, //3831 #CJK UNIFIED IDEOGRAPH + {0xB9DF, 0x5AE6}, //3832 #CJK UNIFIED IDEOGRAPH + {0xB9E0, 0x5AE9}, //3833 #CJK UNIFIED IDEOGRAPH + {0xB9E1, 0x5AD7}, //3834 #CJK UNIFIED IDEOGRAPH + {0xB9E2, 0x5AD6}, //3835 #CJK UNIFIED IDEOGRAPH + {0xB9E3, 0x5AD8}, //3836 #CJK UNIFIED IDEOGRAPH + {0xB9E4, 0x5AE3}, //3837 #CJK UNIFIED IDEOGRAPH + {0xB9E5, 0x5B75}, //3838 #CJK UNIFIED IDEOGRAPH + {0xB9E6, 0x5BDE}, //3839 #CJK UNIFIED IDEOGRAPH + {0xB9E7, 0x5BE7}, //3840 #CJK UNIFIED IDEOGRAPH + {0xB9E8, 0x5BE1}, //3841 #CJK UNIFIED IDEOGRAPH + {0xB9E9, 0x5BE5}, //3842 #CJK UNIFIED IDEOGRAPH + {0xB9EA, 0x5BE6}, //3843 #CJK UNIFIED IDEOGRAPH + {0xB9EB, 0x5BE8}, //3844 #CJK UNIFIED IDEOGRAPH + {0xB9EC, 0x5BE2}, //3845 #CJK UNIFIED IDEOGRAPH + {0xB9ED, 0x5BE4}, //3846 #CJK UNIFIED IDEOGRAPH + {0xB9EE, 0x5BDF}, //3847 #CJK UNIFIED IDEOGRAPH + {0xB9EF, 0x5C0D}, //3848 #CJK UNIFIED IDEOGRAPH + {0xB9F0, 0x5C62}, //3849 #CJK UNIFIED IDEOGRAPH + {0xB9F1, 0x5D84}, //3850 #CJK UNIFIED IDEOGRAPH + {0xB9F2, 0x5D87}, //3851 #CJK UNIFIED IDEOGRAPH + {0xB9F3, 0x5E5B}, //3852 #CJK UNIFIED IDEOGRAPH + {0xB9F4, 0x5E63}, //3853 #CJK UNIFIED IDEOGRAPH + {0xB9F5, 0x5E55}, //3854 #CJK UNIFIED IDEOGRAPH + {0xB9F6, 0x5E57}, //3855 #CJK UNIFIED IDEOGRAPH + {0xB9F7, 0x5E54}, //3856 #CJK UNIFIED IDEOGRAPH + {0xB9F8, 0x5ED3}, //3857 #CJK UNIFIED IDEOGRAPH + {0xB9F9, 0x5ED6}, //3858 #CJK UNIFIED IDEOGRAPH + {0xB9FA, 0x5F0A}, //3859 #CJK UNIFIED IDEOGRAPH + {0xB9FB, 0x5F46}, //3860 #CJK UNIFIED IDEOGRAPH + {0xB9FC, 0x5F70}, //3861 #CJK UNIFIED IDEOGRAPH + {0xB9FD, 0x5FB9}, //3862 #CJK UNIFIED IDEOGRAPH + {0xB9FE, 0x6147}, //3863 #CJK UNIFIED IDEOGRAPH + {0xBA40, 0x613F}, //3864 #CJK UNIFIED IDEOGRAPH + {0xBA41, 0x614B}, //3865 #CJK UNIFIED IDEOGRAPH + {0xBA42, 0x6177}, //3866 #CJK UNIFIED IDEOGRAPH + {0xBA43, 0x6162}, //3867 #CJK UNIFIED IDEOGRAPH + {0xBA44, 0x6163}, //3868 #CJK UNIFIED IDEOGRAPH + {0xBA45, 0x615F}, //3869 #CJK UNIFIED IDEOGRAPH + {0xBA46, 0x615A}, //3870 #CJK UNIFIED IDEOGRAPH + {0xBA47, 0x6158}, //3871 #CJK UNIFIED IDEOGRAPH + {0xBA48, 0x6175}, //3872 #CJK UNIFIED IDEOGRAPH + {0xBA49, 0x622A}, //3873 #CJK UNIFIED IDEOGRAPH + {0xBA4A, 0x6487}, //3874 #CJK UNIFIED IDEOGRAPH + {0xBA4B, 0x6458}, //3875 #CJK UNIFIED IDEOGRAPH + {0xBA4C, 0x6454}, //3876 #CJK UNIFIED IDEOGRAPH + {0xBA4D, 0x64A4}, //3877 #CJK UNIFIED IDEOGRAPH + {0xBA4E, 0x6478}, //3878 #CJK UNIFIED IDEOGRAPH + {0xBA4F, 0x645F}, //3879 #CJK UNIFIED IDEOGRAPH + {0xBA50, 0x647A}, //3880 #CJK UNIFIED IDEOGRAPH + {0xBA51, 0x6451}, //3881 #CJK UNIFIED IDEOGRAPH + {0xBA52, 0x6467}, //3882 #CJK UNIFIED IDEOGRAPH + {0xBA53, 0x6434}, //3883 #CJK UNIFIED IDEOGRAPH + {0xBA54, 0x646D}, //3884 #CJK UNIFIED IDEOGRAPH + {0xBA55, 0x647B}, //3885 #CJK UNIFIED IDEOGRAPH + {0xBA56, 0x6572}, //3886 #CJK UNIFIED IDEOGRAPH + {0xBA57, 0x65A1}, //3887 #CJK UNIFIED IDEOGRAPH + {0xBA58, 0x65D7}, //3888 #CJK UNIFIED IDEOGRAPH + {0xBA59, 0x65D6}, //3889 #CJK UNIFIED IDEOGRAPH + {0xBA5A, 0x66A2}, //3890 #CJK UNIFIED IDEOGRAPH + {0xBA5B, 0x66A8}, //3891 #CJK UNIFIED IDEOGRAPH + {0xBA5C, 0x669D}, //3892 #CJK UNIFIED IDEOGRAPH + {0xBA5D, 0x699C}, //3893 #CJK UNIFIED IDEOGRAPH + {0xBA5E, 0x69A8}, //3894 #CJK UNIFIED IDEOGRAPH + {0xBA5F, 0x6995}, //3895 #CJK UNIFIED IDEOGRAPH + {0xBA60, 0x69C1}, //3896 #CJK UNIFIED IDEOGRAPH + {0xBA61, 0x69AE}, //3897 #CJK UNIFIED IDEOGRAPH + {0xBA62, 0x69D3}, //3898 #CJK UNIFIED IDEOGRAPH + {0xBA63, 0x69CB}, //3899 #CJK UNIFIED IDEOGRAPH + {0xBA64, 0x699B}, //3900 #CJK UNIFIED IDEOGRAPH + {0xBA65, 0x69B7}, //3901 #CJK UNIFIED IDEOGRAPH + {0xBA66, 0x69BB}, //3902 #CJK UNIFIED IDEOGRAPH + {0xBA67, 0x69AB}, //3903 #CJK UNIFIED IDEOGRAPH + {0xBA68, 0x69B4}, //3904 #CJK UNIFIED IDEOGRAPH + {0xBA69, 0x69D0}, //3905 #CJK UNIFIED IDEOGRAPH + {0xBA6A, 0x69CD}, //3906 #CJK UNIFIED IDEOGRAPH + {0xBA6B, 0x69AD}, //3907 #CJK UNIFIED IDEOGRAPH + {0xBA6C, 0x69CC}, //3908 #CJK UNIFIED IDEOGRAPH + {0xBA6D, 0x69A6}, //3909 #CJK UNIFIED IDEOGRAPH + {0xBA6E, 0x69C3}, //3910 #CJK UNIFIED IDEOGRAPH + {0xBA6F, 0x69A3}, //3911 #CJK UNIFIED IDEOGRAPH + {0xBA70, 0x6B49}, //3912 #CJK UNIFIED IDEOGRAPH + {0xBA71, 0x6B4C}, //3913 #CJK UNIFIED IDEOGRAPH + {0xBA72, 0x6C33}, //3914 #CJK UNIFIED IDEOGRAPH + {0xBA73, 0x6F33}, //3915 #CJK UNIFIED IDEOGRAPH + {0xBA74, 0x6F14}, //3916 #CJK UNIFIED IDEOGRAPH + {0xBA75, 0x6EFE}, //3917 #CJK UNIFIED IDEOGRAPH + {0xBA76, 0x6F13}, //3918 #CJK UNIFIED IDEOGRAPH + {0xBA77, 0x6EF4}, //3919 #CJK UNIFIED IDEOGRAPH + {0xBA78, 0x6F29}, //3920 #CJK UNIFIED IDEOGRAPH + {0xBA79, 0x6F3E}, //3921 #CJK UNIFIED IDEOGRAPH + {0xBA7A, 0x6F20}, //3922 #CJK UNIFIED IDEOGRAPH + {0xBA7B, 0x6F2C}, //3923 #CJK UNIFIED IDEOGRAPH + {0xBA7C, 0x6F0F}, //3924 #CJK UNIFIED IDEOGRAPH + {0xBA7D, 0x6F02}, //3925 #CJK UNIFIED IDEOGRAPH + {0xBA7E, 0x6F22}, //3926 #CJK UNIFIED IDEOGRAPH + {0xBAA1, 0x6EFF}, //3927 #CJK UNIFIED IDEOGRAPH + {0xBAA2, 0x6EEF}, //3928 #CJK UNIFIED IDEOGRAPH + {0xBAA3, 0x6F06}, //3929 #CJK UNIFIED IDEOGRAPH + {0xBAA4, 0x6F31}, //3930 #CJK UNIFIED IDEOGRAPH + {0xBAA5, 0x6F38}, //3931 #CJK UNIFIED IDEOGRAPH + {0xBAA6, 0x6F32}, //3932 #CJK UNIFIED IDEOGRAPH + {0xBAA7, 0x6F23}, //3933 #CJK UNIFIED IDEOGRAPH + {0xBAA8, 0x6F15}, //3934 #CJK UNIFIED IDEOGRAPH + {0xBAA9, 0x6F2B}, //3935 #CJK UNIFIED IDEOGRAPH + {0xBAAA, 0x6F2F}, //3936 #CJK UNIFIED IDEOGRAPH + {0xBAAB, 0x6F88}, //3937 #CJK UNIFIED IDEOGRAPH + {0xBAAC, 0x6F2A}, //3938 #CJK UNIFIED IDEOGRAPH + {0xBAAD, 0x6EEC}, //3939 #CJK UNIFIED IDEOGRAPH + {0xBAAE, 0x6F01}, //3940 #CJK UNIFIED IDEOGRAPH + {0xBAAF, 0x6EF2}, //3941 #CJK UNIFIED IDEOGRAPH + {0xBAB0, 0x6ECC}, //3942 #CJK UNIFIED IDEOGRAPH + {0xBAB1, 0x6EF7}, //3943 #CJK UNIFIED IDEOGRAPH + {0xBAB2, 0x7194}, //3944 #CJK UNIFIED IDEOGRAPH + {0xBAB3, 0x7199}, //3945 #CJK UNIFIED IDEOGRAPH + {0xBAB4, 0x717D}, //3946 #CJK UNIFIED IDEOGRAPH + {0xBAB5, 0x718A}, //3947 #CJK UNIFIED IDEOGRAPH + {0xBAB6, 0x7184}, //3948 #CJK UNIFIED IDEOGRAPH + {0xBAB7, 0x7192}, //3949 #CJK UNIFIED IDEOGRAPH + {0xBAB8, 0x723E}, //3950 #CJK UNIFIED IDEOGRAPH + {0xBAB9, 0x7292}, //3951 #CJK UNIFIED IDEOGRAPH + {0xBABA, 0x7296}, //3952 #CJK UNIFIED IDEOGRAPH + {0xBABB, 0x7344}, //3953 #CJK UNIFIED IDEOGRAPH + {0xBABC, 0x7350}, //3954 #CJK UNIFIED IDEOGRAPH + {0xBABD, 0x7464}, //3955 #CJK UNIFIED IDEOGRAPH + {0xBABE, 0x7463}, //3956 #CJK UNIFIED IDEOGRAPH + {0xBABF, 0x746A}, //3957 #CJK UNIFIED IDEOGRAPH + {0xBAC0, 0x7470}, //3958 #CJK UNIFIED IDEOGRAPH + {0xBAC1, 0x746D}, //3959 #CJK UNIFIED IDEOGRAPH + {0xBAC2, 0x7504}, //3960 #CJK UNIFIED IDEOGRAPH + {0xBAC3, 0x7591}, //3961 #CJK UNIFIED IDEOGRAPH + {0xBAC4, 0x7627}, //3962 #CJK UNIFIED IDEOGRAPH + {0xBAC5, 0x760D}, //3963 #CJK UNIFIED IDEOGRAPH + {0xBAC6, 0x760B}, //3964 #CJK UNIFIED IDEOGRAPH + {0xBAC7, 0x7609}, //3965 #CJK UNIFIED IDEOGRAPH + {0xBAC8, 0x7613}, //3966 #CJK UNIFIED IDEOGRAPH + {0xBAC9, 0x76E1}, //3967 #CJK UNIFIED IDEOGRAPH + {0xBACA, 0x76E3}, //3968 #CJK UNIFIED IDEOGRAPH + {0xBACB, 0x7784}, //3969 #CJK UNIFIED IDEOGRAPH + {0xBACC, 0x777D}, //3970 #CJK UNIFIED IDEOGRAPH + {0xBACD, 0x777F}, //3971 #CJK UNIFIED IDEOGRAPH + {0xBACE, 0x7761}, //3972 #CJK UNIFIED IDEOGRAPH + {0xBACF, 0x78C1}, //3973 #CJK UNIFIED IDEOGRAPH + {0xBAD0, 0x789F}, //3974 #CJK UNIFIED IDEOGRAPH + {0xBAD1, 0x78A7}, //3975 #CJK UNIFIED IDEOGRAPH + {0xBAD2, 0x78B3}, //3976 #CJK UNIFIED IDEOGRAPH + {0xBAD3, 0x78A9}, //3977 #CJK UNIFIED IDEOGRAPH + {0xBAD4, 0x78A3}, //3978 #CJK UNIFIED IDEOGRAPH + {0xBAD5, 0x798E}, //3979 #CJK UNIFIED IDEOGRAPH + {0xBAD6, 0x798F}, //3980 #CJK UNIFIED IDEOGRAPH + {0xBAD7, 0x798D}, //3981 #CJK UNIFIED IDEOGRAPH + {0xBAD8, 0x7A2E}, //3982 #CJK UNIFIED IDEOGRAPH + {0xBAD9, 0x7A31}, //3983 #CJK UNIFIED IDEOGRAPH + {0xBADA, 0x7AAA}, //3984 #CJK UNIFIED IDEOGRAPH + {0xBADB, 0x7AA9}, //3985 #CJK UNIFIED IDEOGRAPH + {0xBADC, 0x7AED}, //3986 #CJK UNIFIED IDEOGRAPH + {0xBADD, 0x7AEF}, //3987 #CJK UNIFIED IDEOGRAPH + {0xBADE, 0x7BA1}, //3988 #CJK UNIFIED IDEOGRAPH + {0xBADF, 0x7B95}, //3989 #CJK UNIFIED IDEOGRAPH + {0xBAE0, 0x7B8B}, //3990 #CJK UNIFIED IDEOGRAPH + {0xBAE1, 0x7B75}, //3991 #CJK UNIFIED IDEOGRAPH + {0xBAE2, 0x7B97}, //3992 #CJK UNIFIED IDEOGRAPH + {0xBAE3, 0x7B9D}, //3993 #CJK UNIFIED IDEOGRAPH + {0xBAE4, 0x7B94}, //3994 #CJK UNIFIED IDEOGRAPH + {0xBAE5, 0x7B8F}, //3995 #CJK UNIFIED IDEOGRAPH + {0xBAE6, 0x7BB8}, //3996 #CJK UNIFIED IDEOGRAPH + {0xBAE7, 0x7B87}, //3997 #CJK UNIFIED IDEOGRAPH + {0xBAE8, 0x7B84}, //3998 #CJK UNIFIED IDEOGRAPH + {0xBAE9, 0x7CB9}, //3999 #CJK UNIFIED IDEOGRAPH + {0xBAEA, 0x7CBD}, //4000 #CJK UNIFIED IDEOGRAPH + {0xBAEB, 0x7CBE}, //4001 #CJK UNIFIED IDEOGRAPH + {0xBAEC, 0x7DBB}, //4002 #CJK UNIFIED IDEOGRAPH + {0xBAED, 0x7DB0}, //4003 #CJK UNIFIED IDEOGRAPH + {0xBAEE, 0x7D9C}, //4004 #CJK UNIFIED IDEOGRAPH + {0xBAEF, 0x7DBD}, //4005 #CJK UNIFIED IDEOGRAPH + {0xBAF0, 0x7DBE}, //4006 #CJK UNIFIED IDEOGRAPH + {0xBAF1, 0x7DA0}, //4007 #CJK UNIFIED IDEOGRAPH + {0xBAF2, 0x7DCA}, //4008 #CJK UNIFIED IDEOGRAPH + {0xBAF3, 0x7DB4}, //4009 #CJK UNIFIED IDEOGRAPH + {0xBAF4, 0x7DB2}, //4010 #CJK UNIFIED IDEOGRAPH + {0xBAF5, 0x7DB1}, //4011 #CJK UNIFIED IDEOGRAPH + {0xBAF6, 0x7DBA}, //4012 #CJK UNIFIED IDEOGRAPH + {0xBAF7, 0x7DA2}, //4013 #CJK UNIFIED IDEOGRAPH + {0xBAF8, 0x7DBF}, //4014 #CJK UNIFIED IDEOGRAPH + {0xBAF9, 0x7DB5}, //4015 #CJK UNIFIED IDEOGRAPH + {0xBAFA, 0x7DB8}, //4016 #CJK UNIFIED IDEOGRAPH + {0xBAFB, 0x7DAD}, //4017 #CJK UNIFIED IDEOGRAPH + {0xBAFC, 0x7DD2}, //4018 #CJK UNIFIED IDEOGRAPH + {0xBAFD, 0x7DC7}, //4019 #CJK UNIFIED IDEOGRAPH + {0xBAFE, 0x7DAC}, //4020 #CJK UNIFIED IDEOGRAPH + {0xBB40, 0x7F70}, //4021 #CJK UNIFIED IDEOGRAPH + {0xBB41, 0x7FE0}, //4022 #CJK UNIFIED IDEOGRAPH + {0xBB42, 0x7FE1}, //4023 #CJK UNIFIED IDEOGRAPH + {0xBB43, 0x7FDF}, //4024 #CJK UNIFIED IDEOGRAPH + {0xBB44, 0x805E}, //4025 #CJK UNIFIED IDEOGRAPH + {0xBB45, 0x805A}, //4026 #CJK UNIFIED IDEOGRAPH + {0xBB46, 0x8087}, //4027 #CJK UNIFIED IDEOGRAPH + {0xBB47, 0x8150}, //4028 #CJK UNIFIED IDEOGRAPH + {0xBB48, 0x8180}, //4029 #CJK UNIFIED IDEOGRAPH + {0xBB49, 0x818F}, //4030 #CJK UNIFIED IDEOGRAPH + {0xBB4A, 0x8188}, //4031 #CJK UNIFIED IDEOGRAPH + {0xBB4B, 0x818A}, //4032 #CJK UNIFIED IDEOGRAPH + {0xBB4C, 0x817F}, //4033 #CJK UNIFIED IDEOGRAPH + {0xBB4D, 0x8182}, //4034 #CJK UNIFIED IDEOGRAPH + {0xBB4E, 0x81E7}, //4035 #CJK UNIFIED IDEOGRAPH + {0xBB4F, 0x81FA}, //4036 #CJK UNIFIED IDEOGRAPH + {0xBB50, 0x8207}, //4037 #CJK UNIFIED IDEOGRAPH + {0xBB51, 0x8214}, //4038 #CJK UNIFIED IDEOGRAPH + {0xBB52, 0x821E}, //4039 #CJK UNIFIED IDEOGRAPH + {0xBB53, 0x824B}, //4040 #CJK UNIFIED IDEOGRAPH + {0xBB54, 0x84C9}, //4041 #CJK UNIFIED IDEOGRAPH + {0xBB55, 0x84BF}, //4042 #CJK UNIFIED IDEOGRAPH + {0xBB56, 0x84C6}, //4043 #CJK UNIFIED IDEOGRAPH + {0xBB57, 0x84C4}, //4044 #CJK UNIFIED IDEOGRAPH + {0xBB58, 0x8499}, //4045 #CJK UNIFIED IDEOGRAPH + {0xBB59, 0x849E}, //4046 #CJK UNIFIED IDEOGRAPH + {0xBB5A, 0x84B2}, //4047 #CJK UNIFIED IDEOGRAPH + {0xBB5B, 0x849C}, //4048 #CJK UNIFIED IDEOGRAPH + {0xBB5C, 0x84CB}, //4049 #CJK UNIFIED IDEOGRAPH + {0xBB5D, 0x84B8}, //4050 #CJK UNIFIED IDEOGRAPH + {0xBB5E, 0x84C0}, //4051 #CJK UNIFIED IDEOGRAPH + {0xBB5F, 0x84D3}, //4052 #CJK UNIFIED IDEOGRAPH + {0xBB60, 0x8490}, //4053 #CJK UNIFIED IDEOGRAPH + {0xBB61, 0x84BC}, //4054 #CJK UNIFIED IDEOGRAPH + {0xBB62, 0x84D1}, //4055 #CJK UNIFIED IDEOGRAPH + {0xBB63, 0x84CA}, //4056 #CJK UNIFIED IDEOGRAPH + {0xBB64, 0x873F}, //4057 #CJK UNIFIED IDEOGRAPH + {0xBB65, 0x871C}, //4058 #CJK UNIFIED IDEOGRAPH + {0xBB66, 0x873B}, //4059 #CJK UNIFIED IDEOGRAPH + {0xBB67, 0x8722}, //4060 #CJK UNIFIED IDEOGRAPH + {0xBB68, 0x8725}, //4061 #CJK UNIFIED IDEOGRAPH + {0xBB69, 0x8734}, //4062 #CJK UNIFIED IDEOGRAPH + {0xBB6A, 0x8718}, //4063 #CJK UNIFIED IDEOGRAPH + {0xBB6B, 0x8755}, //4064 #CJK UNIFIED IDEOGRAPH + {0xBB6C, 0x8737}, //4065 #CJK UNIFIED IDEOGRAPH + {0xBB6D, 0x8729}, //4066 #CJK UNIFIED IDEOGRAPH + {0xBB6E, 0x88F3}, //4067 #CJK UNIFIED IDEOGRAPH + {0xBB6F, 0x8902}, //4068 #CJK UNIFIED IDEOGRAPH + {0xBB70, 0x88F4}, //4069 #CJK UNIFIED IDEOGRAPH + {0xBB71, 0x88F9}, //4070 #CJK UNIFIED IDEOGRAPH + {0xBB72, 0x88F8}, //4071 #CJK UNIFIED IDEOGRAPH + {0xBB73, 0x88FD}, //4072 #CJK UNIFIED IDEOGRAPH + {0xBB74, 0x88E8}, //4073 #CJK UNIFIED IDEOGRAPH + {0xBB75, 0x891A}, //4074 #CJK UNIFIED IDEOGRAPH + {0xBB76, 0x88EF}, //4075 #CJK UNIFIED IDEOGRAPH + {0xBB77, 0x8AA6}, //4076 #CJK UNIFIED IDEOGRAPH + {0xBB78, 0x8A8C}, //4077 #CJK UNIFIED IDEOGRAPH + {0xBB79, 0x8A9E}, //4078 #CJK UNIFIED IDEOGRAPH + {0xBB7A, 0x8AA3}, //4079 #CJK UNIFIED IDEOGRAPH + {0xBB7B, 0x8A8D}, //4080 #CJK UNIFIED IDEOGRAPH + {0xBB7C, 0x8AA1}, //4081 #CJK UNIFIED IDEOGRAPH + {0xBB7D, 0x8A93}, //4082 #CJK UNIFIED IDEOGRAPH + {0xBB7E, 0x8AA4}, //4083 #CJK UNIFIED IDEOGRAPH + {0xBBA1, 0x8AAA}, //4084 #CJK UNIFIED IDEOGRAPH + {0xBBA2, 0x8AA5}, //4085 #CJK UNIFIED IDEOGRAPH + {0xBBA3, 0x8AA8}, //4086 #CJK UNIFIED IDEOGRAPH + {0xBBA4, 0x8A98}, //4087 #CJK UNIFIED IDEOGRAPH + {0xBBA5, 0x8A91}, //4088 #CJK UNIFIED IDEOGRAPH + {0xBBA6, 0x8A9A}, //4089 #CJK UNIFIED IDEOGRAPH + {0xBBA7, 0x8AA7}, //4090 #CJK UNIFIED IDEOGRAPH + {0xBBA8, 0x8C6A}, //4091 #CJK UNIFIED IDEOGRAPH + {0xBBA9, 0x8C8D}, //4092 #CJK UNIFIED IDEOGRAPH + {0xBBAA, 0x8C8C}, //4093 #CJK UNIFIED IDEOGRAPH + {0xBBAB, 0x8CD3}, //4094 #CJK UNIFIED IDEOGRAPH + {0xBBAC, 0x8CD1}, //4095 #CJK UNIFIED IDEOGRAPH + {0xBBAD, 0x8CD2}, //4096 #CJK UNIFIED IDEOGRAPH + {0xBBAE, 0x8D6B}, //4097 #CJK UNIFIED IDEOGRAPH + {0xBBAF, 0x8D99}, //4098 #CJK UNIFIED IDEOGRAPH + {0xBBB0, 0x8D95}, //4099 #CJK UNIFIED IDEOGRAPH + {0xBBB1, 0x8DFC}, //4100 #CJK UNIFIED IDEOGRAPH + {0xBBB2, 0x8F14}, //4101 #CJK UNIFIED IDEOGRAPH + {0xBBB3, 0x8F12}, //4102 #CJK UNIFIED IDEOGRAPH + {0xBBB4, 0x8F15}, //4103 #CJK UNIFIED IDEOGRAPH + {0xBBB5, 0x8F13}, //4104 #CJK UNIFIED IDEOGRAPH + {0xBBB6, 0x8FA3}, //4105 #CJK UNIFIED IDEOGRAPH + {0xBBB7, 0x9060}, //4106 #CJK UNIFIED IDEOGRAPH + {0xBBB8, 0x9058}, //4107 #CJK UNIFIED IDEOGRAPH + {0xBBB9, 0x905C}, //4108 #CJK UNIFIED IDEOGRAPH + {0xBBBA, 0x9063}, //4109 #CJK UNIFIED IDEOGRAPH + {0xBBBB, 0x9059}, //4110 #CJK UNIFIED IDEOGRAPH + {0xBBBC, 0x905E}, //4111 #CJK UNIFIED IDEOGRAPH + {0xBBBD, 0x9062}, //4112 #CJK UNIFIED IDEOGRAPH + {0xBBBE, 0x905D}, //4113 #CJK UNIFIED IDEOGRAPH + {0xBBBF, 0x905B}, //4114 #CJK UNIFIED IDEOGRAPH + {0xBBC0, 0x9119}, //4115 #CJK UNIFIED IDEOGRAPH + {0xBBC1, 0x9118}, //4116 #CJK UNIFIED IDEOGRAPH + {0xBBC2, 0x911E}, //4117 #CJK UNIFIED IDEOGRAPH + {0xBBC3, 0x9175}, //4118 #CJK UNIFIED IDEOGRAPH + {0xBBC4, 0x9178}, //4119 #CJK UNIFIED IDEOGRAPH + {0xBBC5, 0x9177}, //4120 #CJK UNIFIED IDEOGRAPH + {0xBBC6, 0x9174}, //4121 #CJK UNIFIED IDEOGRAPH + {0xBBC7, 0x9278}, //4122 #CJK UNIFIED IDEOGRAPH + {0xBBC8, 0x9280}, //4123 #CJK UNIFIED IDEOGRAPH + {0xBBC9, 0x9285}, //4124 #CJK UNIFIED IDEOGRAPH + {0xBBCA, 0x9298}, //4125 #CJK UNIFIED IDEOGRAPH + {0xBBCB, 0x9296}, //4126 #CJK UNIFIED IDEOGRAPH + {0xBBCC, 0x927B}, //4127 #CJK UNIFIED IDEOGRAPH + {0xBBCD, 0x9293}, //4128 #CJK UNIFIED IDEOGRAPH + {0xBBCE, 0x929C}, //4129 #CJK UNIFIED IDEOGRAPH + {0xBBCF, 0x92A8}, //4130 #CJK UNIFIED IDEOGRAPH + {0xBBD0, 0x927C}, //4131 #CJK UNIFIED IDEOGRAPH + {0xBBD1, 0x9291}, //4132 #CJK UNIFIED IDEOGRAPH + {0xBBD2, 0x95A1}, //4133 #CJK UNIFIED IDEOGRAPH + {0xBBD3, 0x95A8}, //4134 #CJK UNIFIED IDEOGRAPH + {0xBBD4, 0x95A9}, //4135 #CJK UNIFIED IDEOGRAPH + {0xBBD5, 0x95A3}, //4136 #CJK UNIFIED IDEOGRAPH + {0xBBD6, 0x95A5}, //4137 #CJK UNIFIED IDEOGRAPH + {0xBBD7, 0x95A4}, //4138 #CJK UNIFIED IDEOGRAPH + {0xBBD8, 0x9699}, //4139 #CJK UNIFIED IDEOGRAPH + {0xBBD9, 0x969C}, //4140 #CJK UNIFIED IDEOGRAPH + {0xBBDA, 0x969B}, //4141 #CJK UNIFIED IDEOGRAPH + {0xBBDB, 0x96CC}, //4142 #CJK UNIFIED IDEOGRAPH + {0xBBDC, 0x96D2}, //4143 #CJK UNIFIED IDEOGRAPH + {0xBBDD, 0x9700}, //4144 #CJK UNIFIED IDEOGRAPH + {0xBBDE, 0x977C}, //4145 #CJK UNIFIED IDEOGRAPH + {0xBBDF, 0x9785}, //4146 #CJK UNIFIED IDEOGRAPH + {0xBBE0, 0x97F6}, //4147 #CJK UNIFIED IDEOGRAPH + {0xBBE1, 0x9817}, //4148 #CJK UNIFIED IDEOGRAPH + {0xBBE2, 0x9818}, //4149 #CJK UNIFIED IDEOGRAPH + {0xBBE3, 0x98AF}, //4150 #CJK UNIFIED IDEOGRAPH + {0xBBE4, 0x98B1}, //4151 #CJK UNIFIED IDEOGRAPH + {0xBBE5, 0x9903}, //4152 #CJK UNIFIED IDEOGRAPH + {0xBBE6, 0x9905}, //4153 #CJK UNIFIED IDEOGRAPH + {0xBBE7, 0x990C}, //4154 #CJK UNIFIED IDEOGRAPH + {0xBBE8, 0x9909}, //4155 #CJK UNIFIED IDEOGRAPH + {0xBBE9, 0x99C1}, //4156 #CJK UNIFIED IDEOGRAPH + {0xBBEA, 0x9AAF}, //4157 #CJK UNIFIED IDEOGRAPH + {0xBBEB, 0x9AB0}, //4158 #CJK UNIFIED IDEOGRAPH + {0xBBEC, 0x9AE6}, //4159 #CJK UNIFIED IDEOGRAPH + {0xBBED, 0x9B41}, //4160 #CJK UNIFIED IDEOGRAPH + {0xBBEE, 0x9B42}, //4161 #CJK UNIFIED IDEOGRAPH + {0xBBEF, 0x9CF4}, //4162 #CJK UNIFIED IDEOGRAPH + {0xBBF0, 0x9CF6}, //4163 #CJK UNIFIED IDEOGRAPH + {0xBBF1, 0x9CF3}, //4164 #CJK UNIFIED IDEOGRAPH + {0xBBF2, 0x9EBC}, //4165 #CJK UNIFIED IDEOGRAPH + {0xBBF3, 0x9F3B}, //4166 #CJK UNIFIED IDEOGRAPH + {0xBBF4, 0x9F4A}, //4167 #CJK UNIFIED IDEOGRAPH + {0xBBF5, 0x5104}, //4168 #CJK UNIFIED IDEOGRAPH + {0xBBF6, 0x5100}, //4169 #CJK UNIFIED IDEOGRAPH + {0xBBF7, 0x50FB}, //4170 #CJK UNIFIED IDEOGRAPH + {0xBBF8, 0x50F5}, //4171 #CJK UNIFIED IDEOGRAPH + {0xBBF9, 0x50F9}, //4172 #CJK UNIFIED IDEOGRAPH + {0xBBFA, 0x5102}, //4173 #CJK UNIFIED IDEOGRAPH + {0xBBFB, 0x5108}, //4174 #CJK UNIFIED IDEOGRAPH + {0xBBFC, 0x5109}, //4175 #CJK UNIFIED IDEOGRAPH + {0xBBFD, 0x5105}, //4176 #CJK UNIFIED IDEOGRAPH + {0xBBFE, 0x51DC}, //4177 #CJK UNIFIED IDEOGRAPH + {0xBC40, 0x5287}, //4178 #CJK UNIFIED IDEOGRAPH + {0xBC41, 0x5288}, //4179 #CJK UNIFIED IDEOGRAPH + {0xBC42, 0x5289}, //4180 #CJK UNIFIED IDEOGRAPH + {0xBC43, 0x528D}, //4181 #CJK UNIFIED IDEOGRAPH + {0xBC44, 0x528A}, //4182 #CJK UNIFIED IDEOGRAPH + {0xBC45, 0x52F0}, //4183 #CJK UNIFIED IDEOGRAPH + {0xBC46, 0x53B2}, //4184 #CJK UNIFIED IDEOGRAPH + {0xBC47, 0x562E}, //4185 #CJK UNIFIED IDEOGRAPH + {0xBC48, 0x563B}, //4186 #CJK UNIFIED IDEOGRAPH + {0xBC49, 0x5639}, //4187 #CJK UNIFIED IDEOGRAPH + {0xBC4A, 0x5632}, //4188 #CJK UNIFIED IDEOGRAPH + {0xBC4B, 0x563F}, //4189 #CJK UNIFIED IDEOGRAPH + {0xBC4C, 0x5634}, //4190 #CJK UNIFIED IDEOGRAPH + {0xBC4D, 0x5629}, //4191 #CJK UNIFIED IDEOGRAPH + {0xBC4E, 0x5653}, //4192 #CJK UNIFIED IDEOGRAPH + {0xBC4F, 0x564E}, //4193 #CJK UNIFIED IDEOGRAPH + {0xBC50, 0x5657}, //4194 #CJK UNIFIED IDEOGRAPH + {0xBC51, 0x5674}, //4195 #CJK UNIFIED IDEOGRAPH + {0xBC52, 0x5636}, //4196 #CJK UNIFIED IDEOGRAPH + {0xBC53, 0x562F}, //4197 #CJK UNIFIED IDEOGRAPH + {0xBC54, 0x5630}, //4198 #CJK UNIFIED IDEOGRAPH + {0xBC55, 0x5880}, //4199 #CJK UNIFIED IDEOGRAPH + {0xBC56, 0x589F}, //4200 #CJK UNIFIED IDEOGRAPH + {0xBC57, 0x589E}, //4201 #CJK UNIFIED IDEOGRAPH + {0xBC58, 0x58B3}, //4202 #CJK UNIFIED IDEOGRAPH + {0xBC59, 0x589C}, //4203 #CJK UNIFIED IDEOGRAPH + {0xBC5A, 0x58AE}, //4204 #CJK UNIFIED IDEOGRAPH + {0xBC5B, 0x58A9}, //4205 #CJK UNIFIED IDEOGRAPH + {0xBC5C, 0x58A6}, //4206 #CJK UNIFIED IDEOGRAPH + {0xBC5D, 0x596D}, //4207 #CJK UNIFIED IDEOGRAPH + {0xBC5E, 0x5B09}, //4208 #CJK UNIFIED IDEOGRAPH + {0xBC5F, 0x5AFB}, //4209 #CJK UNIFIED IDEOGRAPH + {0xBC60, 0x5B0B}, //4210 #CJK UNIFIED IDEOGRAPH + {0xBC61, 0x5AF5}, //4211 #CJK UNIFIED IDEOGRAPH + {0xBC62, 0x5B0C}, //4212 #CJK UNIFIED IDEOGRAPH + {0xBC63, 0x5B08}, //4213 #CJK UNIFIED IDEOGRAPH + {0xBC64, 0x5BEE}, //4214 #CJK UNIFIED IDEOGRAPH + {0xBC65, 0x5BEC}, //4215 #CJK UNIFIED IDEOGRAPH + {0xBC66, 0x5BE9}, //4216 #CJK UNIFIED IDEOGRAPH + {0xBC67, 0x5BEB}, //4217 #CJK UNIFIED IDEOGRAPH + {0xBC68, 0x5C64}, //4218 #CJK UNIFIED IDEOGRAPH + {0xBC69, 0x5C65}, //4219 #CJK UNIFIED IDEOGRAPH + {0xBC6A, 0x5D9D}, //4220 #CJK UNIFIED IDEOGRAPH + {0xBC6B, 0x5D94}, //4221 #CJK UNIFIED IDEOGRAPH + {0xBC6C, 0x5E62}, //4222 #CJK UNIFIED IDEOGRAPH + {0xBC6D, 0x5E5F}, //4223 #CJK UNIFIED IDEOGRAPH + {0xBC6E, 0x5E61}, //4224 #CJK UNIFIED IDEOGRAPH + {0xBC6F, 0x5EE2}, //4225 #CJK UNIFIED IDEOGRAPH + {0xBC70, 0x5EDA}, //4226 #CJK UNIFIED IDEOGRAPH + {0xBC71, 0x5EDF}, //4227 #CJK UNIFIED IDEOGRAPH + {0xBC72, 0x5EDD}, //4228 #CJK UNIFIED IDEOGRAPH + {0xBC73, 0x5EE3}, //4229 #CJK UNIFIED IDEOGRAPH + {0xBC74, 0x5EE0}, //4230 #CJK UNIFIED IDEOGRAPH + {0xBC75, 0x5F48}, //4231 #CJK UNIFIED IDEOGRAPH + {0xBC76, 0x5F71}, //4232 #CJK UNIFIED IDEOGRAPH + {0xBC77, 0x5FB7}, //4233 #CJK UNIFIED IDEOGRAPH + {0xBC78, 0x5FB5}, //4234 #CJK UNIFIED IDEOGRAPH + {0xBC79, 0x6176}, //4235 #CJK UNIFIED IDEOGRAPH + {0xBC7A, 0x6167}, //4236 #CJK UNIFIED IDEOGRAPH + {0xBC7B, 0x616E}, //4237 #CJK UNIFIED IDEOGRAPH + {0xBC7C, 0x615D}, //4238 #CJK UNIFIED IDEOGRAPH + {0xBC7D, 0x6155}, //4239 #CJK UNIFIED IDEOGRAPH + {0xBC7E, 0x6182}, //4240 #CJK UNIFIED IDEOGRAPH + {0xBCA1, 0x617C}, //4241 #CJK UNIFIED IDEOGRAPH + {0xBCA2, 0x6170}, //4242 #CJK UNIFIED IDEOGRAPH + {0xBCA3, 0x616B}, //4243 #CJK UNIFIED IDEOGRAPH + {0xBCA4, 0x617E}, //4244 #CJK UNIFIED IDEOGRAPH + {0xBCA5, 0x61A7}, //4245 #CJK UNIFIED IDEOGRAPH + {0xBCA6, 0x6190}, //4246 #CJK UNIFIED IDEOGRAPH + {0xBCA7, 0x61AB}, //4247 #CJK UNIFIED IDEOGRAPH + {0xBCA8, 0x618E}, //4248 #CJK UNIFIED IDEOGRAPH + {0xBCA9, 0x61AC}, //4249 #CJK UNIFIED IDEOGRAPH + {0xBCAA, 0x619A}, //4250 #CJK UNIFIED IDEOGRAPH + {0xBCAB, 0x61A4}, //4251 #CJK UNIFIED IDEOGRAPH + {0xBCAC, 0x6194}, //4252 #CJK UNIFIED IDEOGRAPH + {0xBCAD, 0x61AE}, //4253 #CJK UNIFIED IDEOGRAPH + {0xBCAE, 0x622E}, //4254 #CJK UNIFIED IDEOGRAPH + {0xBCAF, 0x6469}, //4255 #CJK UNIFIED IDEOGRAPH + {0xBCB0, 0x646F}, //4256 #CJK UNIFIED IDEOGRAPH + {0xBCB1, 0x6479}, //4257 #CJK UNIFIED IDEOGRAPH + {0xBCB2, 0x649E}, //4258 #CJK UNIFIED IDEOGRAPH + {0xBCB3, 0x64B2}, //4259 #CJK UNIFIED IDEOGRAPH + {0xBCB4, 0x6488}, //4260 #CJK UNIFIED IDEOGRAPH + {0xBCB5, 0x6490}, //4261 #CJK UNIFIED IDEOGRAPH + {0xBCB6, 0x64B0}, //4262 #CJK UNIFIED IDEOGRAPH + {0xBCB7, 0x64A5}, //4263 #CJK UNIFIED IDEOGRAPH + {0xBCB8, 0x6493}, //4264 #CJK UNIFIED IDEOGRAPH + {0xBCB9, 0x6495}, //4265 #CJK UNIFIED IDEOGRAPH + {0xBCBA, 0x64A9}, //4266 #CJK UNIFIED IDEOGRAPH + {0xBCBB, 0x6492}, //4267 #CJK UNIFIED IDEOGRAPH + {0xBCBC, 0x64AE}, //4268 #CJK UNIFIED IDEOGRAPH + {0xBCBD, 0x64AD}, //4269 #CJK UNIFIED IDEOGRAPH + {0xBCBE, 0x64AB}, //4270 #CJK UNIFIED IDEOGRAPH + {0xBCBF, 0x649A}, //4271 #CJK UNIFIED IDEOGRAPH + {0xBCC0, 0x64AC}, //4272 #CJK UNIFIED IDEOGRAPH + {0xBCC1, 0x6499}, //4273 #CJK UNIFIED IDEOGRAPH + {0xBCC2, 0x64A2}, //4274 #CJK UNIFIED IDEOGRAPH + {0xBCC3, 0x64B3}, //4275 #CJK UNIFIED IDEOGRAPH + {0xBCC4, 0x6575}, //4276 #CJK UNIFIED IDEOGRAPH + {0xBCC5, 0x6577}, //4277 #CJK UNIFIED IDEOGRAPH + {0xBCC6, 0x6578}, //4278 #CJK UNIFIED IDEOGRAPH + {0xBCC7, 0x66AE}, //4279 #CJK UNIFIED IDEOGRAPH + {0xBCC8, 0x66AB}, //4280 #CJK UNIFIED IDEOGRAPH + {0xBCC9, 0x66B4}, //4281 #CJK UNIFIED IDEOGRAPH + {0xBCCA, 0x66B1}, //4282 #CJK UNIFIED IDEOGRAPH + {0xBCCB, 0x6A23}, //4283 #CJK UNIFIED IDEOGRAPH + {0xBCCC, 0x6A1F}, //4284 #CJK UNIFIED IDEOGRAPH + {0xBCCD, 0x69E8}, //4285 #CJK UNIFIED IDEOGRAPH + {0xBCCE, 0x6A01}, //4286 #CJK UNIFIED IDEOGRAPH + {0xBCCF, 0x6A1E}, //4287 #CJK UNIFIED IDEOGRAPH + {0xBCD0, 0x6A19}, //4288 #CJK UNIFIED IDEOGRAPH + {0xBCD1, 0x69FD}, //4289 #CJK UNIFIED IDEOGRAPH + {0xBCD2, 0x6A21}, //4290 #CJK UNIFIED IDEOGRAPH + {0xBCD3, 0x6A13}, //4291 #CJK UNIFIED IDEOGRAPH + {0xBCD4, 0x6A0A}, //4292 #CJK UNIFIED IDEOGRAPH + {0xBCD5, 0x69F3}, //4293 #CJK UNIFIED IDEOGRAPH + {0xBCD6, 0x6A02}, //4294 #CJK UNIFIED IDEOGRAPH + {0xBCD7, 0x6A05}, //4295 #CJK UNIFIED IDEOGRAPH + {0xBCD8, 0x69ED}, //4296 #CJK UNIFIED IDEOGRAPH + {0xBCD9, 0x6A11}, //4297 #CJK UNIFIED IDEOGRAPH + {0xBCDA, 0x6B50}, //4298 #CJK UNIFIED IDEOGRAPH + {0xBCDB, 0x6B4E}, //4299 #CJK UNIFIED IDEOGRAPH + {0xBCDC, 0x6BA4}, //4300 #CJK UNIFIED IDEOGRAPH + {0xBCDD, 0x6BC5}, //4301 #CJK UNIFIED IDEOGRAPH + {0xBCDE, 0x6BC6}, //4302 #CJK UNIFIED IDEOGRAPH + {0xBCDF, 0x6F3F}, //4303 #CJK UNIFIED IDEOGRAPH + {0xBCE0, 0x6F7C}, //4304 #CJK UNIFIED IDEOGRAPH + {0xBCE1, 0x6F84}, //4305 #CJK UNIFIED IDEOGRAPH + {0xBCE2, 0x6F51}, //4306 #CJK UNIFIED IDEOGRAPH + {0xBCE3, 0x6F66}, //4307 #CJK UNIFIED IDEOGRAPH + {0xBCE4, 0x6F54}, //4308 #CJK UNIFIED IDEOGRAPH + {0xBCE5, 0x6F86}, //4309 #CJK UNIFIED IDEOGRAPH + {0xBCE6, 0x6F6D}, //4310 #CJK UNIFIED IDEOGRAPH + {0xBCE7, 0x6F5B}, //4311 #CJK UNIFIED IDEOGRAPH + {0xBCE8, 0x6F78}, //4312 #CJK UNIFIED IDEOGRAPH + {0xBCE9, 0x6F6E}, //4313 #CJK UNIFIED IDEOGRAPH + {0xBCEA, 0x6F8E}, //4314 #CJK UNIFIED IDEOGRAPH + {0xBCEB, 0x6F7A}, //4315 #CJK UNIFIED IDEOGRAPH + {0xBCEC, 0x6F70}, //4316 #CJK UNIFIED IDEOGRAPH + {0xBCED, 0x6F64}, //4317 #CJK UNIFIED IDEOGRAPH + {0xBCEE, 0x6F97}, //4318 #CJK UNIFIED IDEOGRAPH + {0xBCEF, 0x6F58}, //4319 #CJK UNIFIED IDEOGRAPH + {0xBCF0, 0x6ED5}, //4320 #CJK UNIFIED IDEOGRAPH + {0xBCF1, 0x6F6F}, //4321 #CJK UNIFIED IDEOGRAPH + {0xBCF2, 0x6F60}, //4322 #CJK UNIFIED IDEOGRAPH + {0xBCF3, 0x6F5F}, //4323 #CJK UNIFIED IDEOGRAPH + {0xBCF4, 0x719F}, //4324 #CJK UNIFIED IDEOGRAPH + {0xBCF5, 0x71AC}, //4325 #CJK UNIFIED IDEOGRAPH + {0xBCF6, 0x71B1}, //4326 #CJK UNIFIED IDEOGRAPH + {0xBCF7, 0x71A8}, //4327 #CJK UNIFIED IDEOGRAPH + {0xBCF8, 0x7256}, //4328 #CJK UNIFIED IDEOGRAPH + {0xBCF9, 0x729B}, //4329 #CJK UNIFIED IDEOGRAPH + {0xBCFA, 0x734E}, //4330 #CJK UNIFIED IDEOGRAPH + {0xBCFB, 0x7357}, //4331 #CJK UNIFIED IDEOGRAPH + {0xBCFC, 0x7469}, //4332 #CJK UNIFIED IDEOGRAPH + {0xBCFD, 0x748B}, //4333 #CJK UNIFIED IDEOGRAPH + {0xBCFE, 0x7483}, //4334 #CJK UNIFIED IDEOGRAPH + {0xBD40, 0x747E}, //4335 #CJK UNIFIED IDEOGRAPH + {0xBD41, 0x7480}, //4336 #CJK UNIFIED IDEOGRAPH + {0xBD42, 0x757F}, //4337 #CJK UNIFIED IDEOGRAPH + {0xBD43, 0x7620}, //4338 #CJK UNIFIED IDEOGRAPH + {0xBD44, 0x7629}, //4339 #CJK UNIFIED IDEOGRAPH + {0xBD45, 0x761F}, //4340 #CJK UNIFIED IDEOGRAPH + {0xBD46, 0x7624}, //4341 #CJK UNIFIED IDEOGRAPH + {0xBD47, 0x7626}, //4342 #CJK UNIFIED IDEOGRAPH + {0xBD48, 0x7621}, //4343 #CJK UNIFIED IDEOGRAPH + {0xBD49, 0x7622}, //4344 #CJK UNIFIED IDEOGRAPH + {0xBD4A, 0x769A}, //4345 #CJK UNIFIED IDEOGRAPH + {0xBD4B, 0x76BA}, //4346 #CJK UNIFIED IDEOGRAPH + {0xBD4C, 0x76E4}, //4347 #CJK UNIFIED IDEOGRAPH + {0xBD4D, 0x778E}, //4348 #CJK UNIFIED IDEOGRAPH + {0xBD4E, 0x7787}, //4349 #CJK UNIFIED IDEOGRAPH + {0xBD4F, 0x778C}, //4350 #CJK UNIFIED IDEOGRAPH + {0xBD50, 0x7791}, //4351 #CJK UNIFIED IDEOGRAPH + {0xBD51, 0x778B}, //4352 #CJK UNIFIED IDEOGRAPH + {0xBD52, 0x78CB}, //4353 #CJK UNIFIED IDEOGRAPH + {0xBD53, 0x78C5}, //4354 #CJK UNIFIED IDEOGRAPH + {0xBD54, 0x78BA}, //4355 #CJK UNIFIED IDEOGRAPH + {0xBD55, 0x78CA}, //4356 #CJK UNIFIED IDEOGRAPH + {0xBD56, 0x78BE}, //4357 #CJK UNIFIED IDEOGRAPH + {0xBD57, 0x78D5}, //4358 #CJK UNIFIED IDEOGRAPH + {0xBD58, 0x78BC}, //4359 #CJK UNIFIED IDEOGRAPH + {0xBD59, 0x78D0}, //4360 #CJK UNIFIED IDEOGRAPH + {0xBD5A, 0x7A3F}, //4361 #CJK UNIFIED IDEOGRAPH + {0xBD5B, 0x7A3C}, //4362 #CJK UNIFIED IDEOGRAPH + {0xBD5C, 0x7A40}, //4363 #CJK UNIFIED IDEOGRAPH + {0xBD5D, 0x7A3D}, //4364 #CJK UNIFIED IDEOGRAPH + {0xBD5E, 0x7A37}, //4365 #CJK UNIFIED IDEOGRAPH + {0xBD5F, 0x7A3B}, //4366 #CJK UNIFIED IDEOGRAPH + {0xBD60, 0x7AAF}, //4367 #CJK UNIFIED IDEOGRAPH + {0xBD61, 0x7AAE}, //4368 #CJK UNIFIED IDEOGRAPH + {0xBD62, 0x7BAD}, //4369 #CJK UNIFIED IDEOGRAPH + {0xBD63, 0x7BB1}, //4370 #CJK UNIFIED IDEOGRAPH + {0xBD64, 0x7BC4}, //4371 #CJK UNIFIED IDEOGRAPH + {0xBD65, 0x7BB4}, //4372 #CJK UNIFIED IDEOGRAPH + {0xBD66, 0x7BC6}, //4373 #CJK UNIFIED IDEOGRAPH + {0xBD67, 0x7BC7}, //4374 #CJK UNIFIED IDEOGRAPH + {0xBD68, 0x7BC1}, //4375 #CJK UNIFIED IDEOGRAPH + {0xBD69, 0x7BA0}, //4376 #CJK UNIFIED IDEOGRAPH + {0xBD6A, 0x7BCC}, //4377 #CJK UNIFIED IDEOGRAPH + {0xBD6B, 0x7CCA}, //4378 #CJK UNIFIED IDEOGRAPH + {0xBD6C, 0x7DE0}, //4379 #CJK UNIFIED IDEOGRAPH + {0xBD6D, 0x7DF4}, //4380 #CJK UNIFIED IDEOGRAPH + {0xBD6E, 0x7DEF}, //4381 #CJK UNIFIED IDEOGRAPH + {0xBD6F, 0x7DFB}, //4382 #CJK UNIFIED IDEOGRAPH + {0xBD70, 0x7DD8}, //4383 #CJK UNIFIED IDEOGRAPH + {0xBD71, 0x7DEC}, //4384 #CJK UNIFIED IDEOGRAPH + {0xBD72, 0x7DDD}, //4385 #CJK UNIFIED IDEOGRAPH + {0xBD73, 0x7DE8}, //4386 #CJK UNIFIED IDEOGRAPH + {0xBD74, 0x7DE3}, //4387 #CJK UNIFIED IDEOGRAPH + {0xBD75, 0x7DDA}, //4388 #CJK UNIFIED IDEOGRAPH + {0xBD76, 0x7DDE}, //4389 #CJK UNIFIED IDEOGRAPH + {0xBD77, 0x7DE9}, //4390 #CJK UNIFIED IDEOGRAPH + {0xBD78, 0x7D9E}, //4391 #CJK UNIFIED IDEOGRAPH + {0xBD79, 0x7DD9}, //4392 #CJK UNIFIED IDEOGRAPH + {0xBD7A, 0x7DF2}, //4393 #CJK UNIFIED IDEOGRAPH + {0xBD7B, 0x7DF9}, //4394 #CJK UNIFIED IDEOGRAPH + {0xBD7C, 0x7F75}, //4395 #CJK UNIFIED IDEOGRAPH + {0xBD7D, 0x7F77}, //4396 #CJK UNIFIED IDEOGRAPH + {0xBD7E, 0x7FAF}, //4397 #CJK UNIFIED IDEOGRAPH + {0xBDA1, 0x7FE9}, //4398 #CJK UNIFIED IDEOGRAPH + {0xBDA2, 0x8026}, //4399 #CJK UNIFIED IDEOGRAPH + {0xBDA3, 0x819B}, //4400 #CJK UNIFIED IDEOGRAPH + {0xBDA4, 0x819C}, //4401 #CJK UNIFIED IDEOGRAPH + {0xBDA5, 0x819D}, //4402 #CJK UNIFIED IDEOGRAPH + {0xBDA6, 0x81A0}, //4403 #CJK UNIFIED IDEOGRAPH + {0xBDA7, 0x819A}, //4404 #CJK UNIFIED IDEOGRAPH + {0xBDA8, 0x8198}, //4405 #CJK UNIFIED IDEOGRAPH + {0xBDA9, 0x8517}, //4406 #CJK UNIFIED IDEOGRAPH + {0xBDAA, 0x853D}, //4407 #CJK UNIFIED IDEOGRAPH + {0xBDAB, 0x851A}, //4408 #CJK UNIFIED IDEOGRAPH + {0xBDAC, 0x84EE}, //4409 #CJK UNIFIED IDEOGRAPH + {0xBDAD, 0x852C}, //4410 #CJK UNIFIED IDEOGRAPH + {0xBDAE, 0x852D}, //4411 #CJK UNIFIED IDEOGRAPH + {0xBDAF, 0x8513}, //4412 #CJK UNIFIED IDEOGRAPH + {0xBDB0, 0x8511}, //4413 #CJK UNIFIED IDEOGRAPH + {0xBDB1, 0x8523}, //4414 #CJK UNIFIED IDEOGRAPH + {0xBDB2, 0x8521}, //4415 #CJK UNIFIED IDEOGRAPH + {0xBDB3, 0x8514}, //4416 #CJK UNIFIED IDEOGRAPH + {0xBDB4, 0x84EC}, //4417 #CJK UNIFIED IDEOGRAPH + {0xBDB5, 0x8525}, //4418 #CJK UNIFIED IDEOGRAPH + {0xBDB6, 0x84FF}, //4419 #CJK UNIFIED IDEOGRAPH + {0xBDB7, 0x8506}, //4420 #CJK UNIFIED IDEOGRAPH + {0xBDB8, 0x8782}, //4421 #CJK UNIFIED IDEOGRAPH + {0xBDB9, 0x8774}, //4422 #CJK UNIFIED IDEOGRAPH + {0xBDBA, 0x8776}, //4423 #CJK UNIFIED IDEOGRAPH + {0xBDBB, 0x8760}, //4424 #CJK UNIFIED IDEOGRAPH + {0xBDBC, 0x8766}, //4425 #CJK UNIFIED IDEOGRAPH + {0xBDBD, 0x8778}, //4426 #CJK UNIFIED IDEOGRAPH + {0xBDBE, 0x8768}, //4427 #CJK UNIFIED IDEOGRAPH + {0xBDBF, 0x8759}, //4428 #CJK UNIFIED IDEOGRAPH + {0xBDC0, 0x8757}, //4429 #CJK UNIFIED IDEOGRAPH + {0xBDC1, 0x874C}, //4430 #CJK UNIFIED IDEOGRAPH + {0xBDC2, 0x8753}, //4431 #CJK UNIFIED IDEOGRAPH + {0xBDC3, 0x885B}, //4432 #CJK UNIFIED IDEOGRAPH + {0xBDC4, 0x885D}, //4433 #CJK UNIFIED IDEOGRAPH + {0xBDC5, 0x8910}, //4434 #CJK UNIFIED IDEOGRAPH + {0xBDC6, 0x8907}, //4435 #CJK UNIFIED IDEOGRAPH + {0xBDC7, 0x8912}, //4436 #CJK UNIFIED IDEOGRAPH + {0xBDC8, 0x8913}, //4437 #CJK UNIFIED IDEOGRAPH + {0xBDC9, 0x8915}, //4438 #CJK UNIFIED IDEOGRAPH + {0xBDCA, 0x890A}, //4439 #CJK UNIFIED IDEOGRAPH + {0xBDCB, 0x8ABC}, //4440 #CJK UNIFIED IDEOGRAPH + {0xBDCC, 0x8AD2}, //4441 #CJK UNIFIED IDEOGRAPH + {0xBDCD, 0x8AC7}, //4442 #CJK UNIFIED IDEOGRAPH + {0xBDCE, 0x8AC4}, //4443 #CJK UNIFIED IDEOGRAPH + {0xBDCF, 0x8A95}, //4444 #CJK UNIFIED IDEOGRAPH + {0xBDD0, 0x8ACB}, //4445 #CJK UNIFIED IDEOGRAPH + {0xBDD1, 0x8AF8}, //4446 #CJK UNIFIED IDEOGRAPH + {0xBDD2, 0x8AB2}, //4447 #CJK UNIFIED IDEOGRAPH + {0xBDD3, 0x8AC9}, //4448 #CJK UNIFIED IDEOGRAPH + {0xBDD4, 0x8AC2}, //4449 #CJK UNIFIED IDEOGRAPH + {0xBDD5, 0x8ABF}, //4450 #CJK UNIFIED IDEOGRAPH + {0xBDD6, 0x8AB0}, //4451 #CJK UNIFIED IDEOGRAPH + {0xBDD7, 0x8AD6}, //4452 #CJK UNIFIED IDEOGRAPH + {0xBDD8, 0x8ACD}, //4453 #CJK UNIFIED IDEOGRAPH + {0xBDD9, 0x8AB6}, //4454 #CJK UNIFIED IDEOGRAPH + {0xBDDA, 0x8AB9}, //4455 #CJK UNIFIED IDEOGRAPH + {0xBDDB, 0x8ADB}, //4456 #CJK UNIFIED IDEOGRAPH + {0xBDDC, 0x8C4C}, //4457 #CJK UNIFIED IDEOGRAPH + {0xBDDD, 0x8C4E}, //4458 #CJK UNIFIED IDEOGRAPH + {0xBDDE, 0x8C6C}, //4459 #CJK UNIFIED IDEOGRAPH + {0xBDDF, 0x8CE0}, //4460 #CJK UNIFIED IDEOGRAPH + {0xBDE0, 0x8CDE}, //4461 #CJK UNIFIED IDEOGRAPH + {0xBDE1, 0x8CE6}, //4462 #CJK UNIFIED IDEOGRAPH + {0xBDE2, 0x8CE4}, //4463 #CJK UNIFIED IDEOGRAPH + {0xBDE3, 0x8CEC}, //4464 #CJK UNIFIED IDEOGRAPH + {0xBDE4, 0x8CED}, //4465 #CJK UNIFIED IDEOGRAPH + {0xBDE5, 0x8CE2}, //4466 #CJK UNIFIED IDEOGRAPH + {0xBDE6, 0x8CE3}, //4467 #CJK UNIFIED IDEOGRAPH + {0xBDE7, 0x8CDC}, //4468 #CJK UNIFIED IDEOGRAPH + {0xBDE8, 0x8CEA}, //4469 #CJK UNIFIED IDEOGRAPH + {0xBDE9, 0x8CE1}, //4470 #CJK UNIFIED IDEOGRAPH + {0xBDEA, 0x8D6D}, //4471 #CJK UNIFIED IDEOGRAPH + {0xBDEB, 0x8D9F}, //4472 #CJK UNIFIED IDEOGRAPH + {0xBDEC, 0x8DA3}, //4473 #CJK UNIFIED IDEOGRAPH + {0xBDED, 0x8E2B}, //4474 #CJK UNIFIED IDEOGRAPH + {0xBDEE, 0x8E10}, //4475 #CJK UNIFIED IDEOGRAPH + {0xBDEF, 0x8E1D}, //4476 #CJK UNIFIED IDEOGRAPH + {0xBDF0, 0x8E22}, //4477 #CJK UNIFIED IDEOGRAPH + {0xBDF1, 0x8E0F}, //4478 #CJK UNIFIED IDEOGRAPH + {0xBDF2, 0x8E29}, //4479 #CJK UNIFIED IDEOGRAPH + {0xBDF3, 0x8E1F}, //4480 #CJK UNIFIED IDEOGRAPH + {0xBDF4, 0x8E21}, //4481 #CJK UNIFIED IDEOGRAPH + {0xBDF5, 0x8E1E}, //4482 #CJK UNIFIED IDEOGRAPH + {0xBDF6, 0x8EBA}, //4483 #CJK UNIFIED IDEOGRAPH + {0xBDF7, 0x8F1D}, //4484 #CJK UNIFIED IDEOGRAPH + {0xBDF8, 0x8F1B}, //4485 #CJK UNIFIED IDEOGRAPH + {0xBDF9, 0x8F1F}, //4486 #CJK UNIFIED IDEOGRAPH + {0xBDFA, 0x8F29}, //4487 #CJK UNIFIED IDEOGRAPH + {0xBDFB, 0x8F26}, //4488 #CJK UNIFIED IDEOGRAPH + {0xBDFC, 0x8F2A}, //4489 #CJK UNIFIED IDEOGRAPH + {0xBDFD, 0x8F1C}, //4490 #CJK UNIFIED IDEOGRAPH + {0xBDFE, 0x8F1E}, //4491 #CJK UNIFIED IDEOGRAPH + {0xBE40, 0x8F25}, //4492 #CJK UNIFIED IDEOGRAPH + {0xBE41, 0x9069}, //4493 #CJK UNIFIED IDEOGRAPH + {0xBE42, 0x906E}, //4494 #CJK UNIFIED IDEOGRAPH + {0xBE43, 0x9068}, //4495 #CJK UNIFIED IDEOGRAPH + {0xBE44, 0x906D}, //4496 #CJK UNIFIED IDEOGRAPH + {0xBE45, 0x9077}, //4497 #CJK UNIFIED IDEOGRAPH + {0xBE46, 0x9130}, //4498 #CJK UNIFIED IDEOGRAPH + {0xBE47, 0x912D}, //4499 #CJK UNIFIED IDEOGRAPH + {0xBE48, 0x9127}, //4500 #CJK UNIFIED IDEOGRAPH + {0xBE49, 0x9131}, //4501 #CJK UNIFIED IDEOGRAPH + {0xBE4A, 0x9187}, //4502 #CJK UNIFIED IDEOGRAPH + {0xBE4B, 0x9189}, //4503 #CJK UNIFIED IDEOGRAPH + {0xBE4C, 0x918B}, //4504 #CJK UNIFIED IDEOGRAPH + {0xBE4D, 0x9183}, //4505 #CJK UNIFIED IDEOGRAPH + {0xBE4E, 0x92C5}, //4506 #CJK UNIFIED IDEOGRAPH + {0xBE4F, 0x92BB}, //4507 #CJK UNIFIED IDEOGRAPH + {0xBE50, 0x92B7}, //4508 #CJK UNIFIED IDEOGRAPH + {0xBE51, 0x92EA}, //4509 #CJK UNIFIED IDEOGRAPH + {0xBE52, 0x92AC}, //4510 #CJK UNIFIED IDEOGRAPH + {0xBE53, 0x92E4}, //4511 #CJK UNIFIED IDEOGRAPH + {0xBE54, 0x92C1}, //4512 #CJK UNIFIED IDEOGRAPH + {0xBE55, 0x92B3}, //4513 #CJK UNIFIED IDEOGRAPH + {0xBE56, 0x92BC}, //4514 #CJK UNIFIED IDEOGRAPH + {0xBE57, 0x92D2}, //4515 #CJK UNIFIED IDEOGRAPH + {0xBE58, 0x92C7}, //4516 #CJK UNIFIED IDEOGRAPH + {0xBE59, 0x92F0}, //4517 #CJK UNIFIED IDEOGRAPH + {0xBE5A, 0x92B2}, //4518 #CJK UNIFIED IDEOGRAPH + {0xBE5B, 0x95AD}, //4519 #CJK UNIFIED IDEOGRAPH + {0xBE5C, 0x95B1}, //4520 #CJK UNIFIED IDEOGRAPH + {0xBE5D, 0x9704}, //4521 #CJK UNIFIED IDEOGRAPH + {0xBE5E, 0x9706}, //4522 #CJK UNIFIED IDEOGRAPH + {0xBE5F, 0x9707}, //4523 #CJK UNIFIED IDEOGRAPH + {0xBE60, 0x9709}, //4524 #CJK UNIFIED IDEOGRAPH + {0xBE61, 0x9760}, //4525 #CJK UNIFIED IDEOGRAPH + {0xBE62, 0x978D}, //4526 #CJK UNIFIED IDEOGRAPH + {0xBE63, 0x978B}, //4527 #CJK UNIFIED IDEOGRAPH + {0xBE64, 0x978F}, //4528 #CJK UNIFIED IDEOGRAPH + {0xBE65, 0x9821}, //4529 #CJK UNIFIED IDEOGRAPH + {0xBE66, 0x982B}, //4530 #CJK UNIFIED IDEOGRAPH + {0xBE67, 0x981C}, //4531 #CJK UNIFIED IDEOGRAPH + {0xBE68, 0x98B3}, //4532 #CJK UNIFIED IDEOGRAPH + {0xBE69, 0x990A}, //4533 #CJK UNIFIED IDEOGRAPH + {0xBE6A, 0x9913}, //4534 #CJK UNIFIED IDEOGRAPH + {0xBE6B, 0x9912}, //4535 #CJK UNIFIED IDEOGRAPH + {0xBE6C, 0x9918}, //4536 #CJK UNIFIED IDEOGRAPH + {0xBE6D, 0x99DD}, //4537 #CJK UNIFIED IDEOGRAPH + {0xBE6E, 0x99D0}, //4538 #CJK UNIFIED IDEOGRAPH + {0xBE6F, 0x99DF}, //4539 #CJK UNIFIED IDEOGRAPH + {0xBE70, 0x99DB}, //4540 #CJK UNIFIED IDEOGRAPH + {0xBE71, 0x99D1}, //4541 #CJK UNIFIED IDEOGRAPH + {0xBE72, 0x99D5}, //4542 #CJK UNIFIED IDEOGRAPH + {0xBE73, 0x99D2}, //4543 #CJK UNIFIED IDEOGRAPH + {0xBE74, 0x99D9}, //4544 #CJK UNIFIED IDEOGRAPH + {0xBE75, 0x9AB7}, //4545 #CJK UNIFIED IDEOGRAPH + {0xBE76, 0x9AEE}, //4546 #CJK UNIFIED IDEOGRAPH + {0xBE77, 0x9AEF}, //4547 #CJK UNIFIED IDEOGRAPH + {0xBE78, 0x9B27}, //4548 #CJK UNIFIED IDEOGRAPH + {0xBE79, 0x9B45}, //4549 #CJK UNIFIED IDEOGRAPH + {0xBE7A, 0x9B44}, //4550 #CJK UNIFIED IDEOGRAPH + {0xBE7B, 0x9B77}, //4551 #CJK UNIFIED IDEOGRAPH + {0xBE7C, 0x9B6F}, //4552 #CJK UNIFIED IDEOGRAPH + {0xBE7D, 0x9D06}, //4553 #CJK UNIFIED IDEOGRAPH + {0xBE7E, 0x9D09}, //4554 #CJK UNIFIED IDEOGRAPH + {0xBEA1, 0x9D03}, //4555 #CJK UNIFIED IDEOGRAPH + {0xBEA2, 0x9EA9}, //4556 #CJK UNIFIED IDEOGRAPH + {0xBEA3, 0x9EBE}, //4557 #CJK UNIFIED IDEOGRAPH + {0xBEA4, 0x9ECE}, //4558 #CJK UNIFIED IDEOGRAPH + {0xBEA5, 0x58A8}, //4559 #CJK UNIFIED IDEOGRAPH + {0xBEA6, 0x9F52}, //4560 #CJK UNIFIED IDEOGRAPH + {0xBEA7, 0x5112}, //4561 #CJK UNIFIED IDEOGRAPH + {0xBEA8, 0x5118}, //4562 #CJK UNIFIED IDEOGRAPH + {0xBEA9, 0x5114}, //4563 #CJK UNIFIED IDEOGRAPH + {0xBEAA, 0x5110}, //4564 #CJK UNIFIED IDEOGRAPH + {0xBEAB, 0x5115}, //4565 #CJK UNIFIED IDEOGRAPH + {0xBEAC, 0x5180}, //4566 #CJK UNIFIED IDEOGRAPH + {0xBEAD, 0x51AA}, //4567 #CJK UNIFIED IDEOGRAPH + {0xBEAE, 0x51DD}, //4568 #CJK UNIFIED IDEOGRAPH + {0xBEAF, 0x5291}, //4569 #CJK UNIFIED IDEOGRAPH + {0xBEB0, 0x5293}, //4570 #CJK UNIFIED IDEOGRAPH + {0xBEB1, 0x52F3}, //4571 #CJK UNIFIED IDEOGRAPH + {0xBEB2, 0x5659}, //4572 #CJK UNIFIED IDEOGRAPH + {0xBEB3, 0x566B}, //4573 #CJK UNIFIED IDEOGRAPH + {0xBEB4, 0x5679}, //4574 #CJK UNIFIED IDEOGRAPH + {0xBEB5, 0x5669}, //4575 #CJK UNIFIED IDEOGRAPH + {0xBEB6, 0x5664}, //4576 #CJK UNIFIED IDEOGRAPH + {0xBEB7, 0x5678}, //4577 #CJK UNIFIED IDEOGRAPH + {0xBEB8, 0x566A}, //4578 #CJK UNIFIED IDEOGRAPH + {0xBEB9, 0x5668}, //4579 #CJK UNIFIED IDEOGRAPH + {0xBEBA, 0x5665}, //4580 #CJK UNIFIED IDEOGRAPH + {0xBEBB, 0x5671}, //4581 #CJK UNIFIED IDEOGRAPH + {0xBEBC, 0x566F}, //4582 #CJK UNIFIED IDEOGRAPH + {0xBEBD, 0x566C}, //4583 #CJK UNIFIED IDEOGRAPH + {0xBEBE, 0x5662}, //4584 #CJK UNIFIED IDEOGRAPH + {0xBEBF, 0x5676}, //4585 #CJK UNIFIED IDEOGRAPH + {0xBEC0, 0x58C1}, //4586 #CJK UNIFIED IDEOGRAPH + {0xBEC1, 0x58BE}, //4587 #CJK UNIFIED IDEOGRAPH + {0xBEC2, 0x58C7}, //4588 #CJK UNIFIED IDEOGRAPH + {0xBEC3, 0x58C5}, //4589 #CJK UNIFIED IDEOGRAPH + {0xBEC4, 0x596E}, //4590 #CJK UNIFIED IDEOGRAPH + {0xBEC5, 0x5B1D}, //4591 #CJK UNIFIED IDEOGRAPH + {0xBEC6, 0x5B34}, //4592 #CJK UNIFIED IDEOGRAPH + {0xBEC7, 0x5B78}, //4593 #CJK UNIFIED IDEOGRAPH + {0xBEC8, 0x5BF0}, //4594 #CJK UNIFIED IDEOGRAPH + {0xBEC9, 0x5C0E}, //4595 #CJK UNIFIED IDEOGRAPH + {0xBECA, 0x5F4A}, //4596 #CJK UNIFIED IDEOGRAPH + {0xBECB, 0x61B2}, //4597 #CJK UNIFIED IDEOGRAPH + {0xBECC, 0x6191}, //4598 #CJK UNIFIED IDEOGRAPH + {0xBECD, 0x61A9}, //4599 #CJK UNIFIED IDEOGRAPH + {0xBECE, 0x618A}, //4600 #CJK UNIFIED IDEOGRAPH + {0xBECF, 0x61CD}, //4601 #CJK UNIFIED IDEOGRAPH + {0xBED0, 0x61B6}, //4602 #CJK UNIFIED IDEOGRAPH + {0xBED1, 0x61BE}, //4603 #CJK UNIFIED IDEOGRAPH + {0xBED2, 0x61CA}, //4604 #CJK UNIFIED IDEOGRAPH + {0xBED3, 0x61C8}, //4605 #CJK UNIFIED IDEOGRAPH + {0xBED4, 0x6230}, //4606 #CJK UNIFIED IDEOGRAPH + {0xBED5, 0x64C5}, //4607 #CJK UNIFIED IDEOGRAPH + {0xBED6, 0x64C1}, //4608 #CJK UNIFIED IDEOGRAPH + {0xBED7, 0x64CB}, //4609 #CJK UNIFIED IDEOGRAPH + {0xBED8, 0x64BB}, //4610 #CJK UNIFIED IDEOGRAPH + {0xBED9, 0x64BC}, //4611 #CJK UNIFIED IDEOGRAPH + {0xBEDA, 0x64DA}, //4612 #CJK UNIFIED IDEOGRAPH + {0xBEDB, 0x64C4}, //4613 #CJK UNIFIED IDEOGRAPH + {0xBEDC, 0x64C7}, //4614 #CJK UNIFIED IDEOGRAPH + {0xBEDD, 0x64C2}, //4615 #CJK UNIFIED IDEOGRAPH + {0xBEDE, 0x64CD}, //4616 #CJK UNIFIED IDEOGRAPH + {0xBEDF, 0x64BF}, //4617 #CJK UNIFIED IDEOGRAPH + {0xBEE0, 0x64D2}, //4618 #CJK UNIFIED IDEOGRAPH + {0xBEE1, 0x64D4}, //4619 #CJK UNIFIED IDEOGRAPH + {0xBEE2, 0x64BE}, //4620 #CJK UNIFIED IDEOGRAPH + {0xBEE3, 0x6574}, //4621 #CJK UNIFIED IDEOGRAPH + {0xBEE4, 0x66C6}, //4622 #CJK UNIFIED IDEOGRAPH + {0xBEE5, 0x66C9}, //4623 #CJK UNIFIED IDEOGRAPH + {0xBEE6, 0x66B9}, //4624 #CJK UNIFIED IDEOGRAPH + {0xBEE7, 0x66C4}, //4625 #CJK UNIFIED IDEOGRAPH + {0xBEE8, 0x66C7}, //4626 #CJK UNIFIED IDEOGRAPH + {0xBEE9, 0x66B8}, //4627 #CJK UNIFIED IDEOGRAPH + {0xBEEA, 0x6A3D}, //4628 #CJK UNIFIED IDEOGRAPH + {0xBEEB, 0x6A38}, //4629 #CJK UNIFIED IDEOGRAPH + {0xBEEC, 0x6A3A}, //4630 #CJK UNIFIED IDEOGRAPH + {0xBEED, 0x6A59}, //4631 #CJK UNIFIED IDEOGRAPH + {0xBEEE, 0x6A6B}, //4632 #CJK UNIFIED IDEOGRAPH + {0xBEEF, 0x6A58}, //4633 #CJK UNIFIED IDEOGRAPH + {0xBEF0, 0x6A39}, //4634 #CJK UNIFIED IDEOGRAPH + {0xBEF1, 0x6A44}, //4635 #CJK UNIFIED IDEOGRAPH + {0xBEF2, 0x6A62}, //4636 #CJK UNIFIED IDEOGRAPH + {0xBEF3, 0x6A61}, //4637 #CJK UNIFIED IDEOGRAPH + {0xBEF4, 0x6A4B}, //4638 #CJK UNIFIED IDEOGRAPH + {0xBEF5, 0x6A47}, //4639 #CJK UNIFIED IDEOGRAPH + {0xBEF6, 0x6A35}, //4640 #CJK UNIFIED IDEOGRAPH + {0xBEF7, 0x6A5F}, //4641 #CJK UNIFIED IDEOGRAPH + {0xBEF8, 0x6A48}, //4642 #CJK UNIFIED IDEOGRAPH + {0xBEF9, 0x6B59}, //4643 #CJK UNIFIED IDEOGRAPH + {0xBEFA, 0x6B77}, //4644 #CJK UNIFIED IDEOGRAPH + {0xBEFB, 0x6C05}, //4645 #CJK UNIFIED IDEOGRAPH + {0xBEFC, 0x6FC2}, //4646 #CJK UNIFIED IDEOGRAPH + {0xBEFD, 0x6FB1}, //4647 #CJK UNIFIED IDEOGRAPH + {0xBEFE, 0x6FA1}, //4648 #CJK UNIFIED IDEOGRAPH + {0xBF40, 0x6FC3}, //4649 #CJK UNIFIED IDEOGRAPH + {0xBF41, 0x6FA4}, //4650 #CJK UNIFIED IDEOGRAPH + {0xBF42, 0x6FC1}, //4651 #CJK UNIFIED IDEOGRAPH + {0xBF43, 0x6FA7}, //4652 #CJK UNIFIED IDEOGRAPH + {0xBF44, 0x6FB3}, //4653 #CJK UNIFIED IDEOGRAPH + {0xBF45, 0x6FC0}, //4654 #CJK UNIFIED IDEOGRAPH + {0xBF46, 0x6FB9}, //4655 #CJK UNIFIED IDEOGRAPH + {0xBF47, 0x6FB6}, //4656 #CJK UNIFIED IDEOGRAPH + {0xBF48, 0x6FA6}, //4657 #CJK UNIFIED IDEOGRAPH + {0xBF49, 0x6FA0}, //4658 #CJK UNIFIED IDEOGRAPH + {0xBF4A, 0x6FB4}, //4659 #CJK UNIFIED IDEOGRAPH + {0xBF4B, 0x71BE}, //4660 #CJK UNIFIED IDEOGRAPH + {0xBF4C, 0x71C9}, //4661 #CJK UNIFIED IDEOGRAPH + {0xBF4D, 0x71D0}, //4662 #CJK UNIFIED IDEOGRAPH + {0xBF4E, 0x71D2}, //4663 #CJK UNIFIED IDEOGRAPH + {0xBF4F, 0x71C8}, //4664 #CJK UNIFIED IDEOGRAPH + {0xBF50, 0x71D5}, //4665 #CJK UNIFIED IDEOGRAPH + {0xBF51, 0x71B9}, //4666 #CJK UNIFIED IDEOGRAPH + {0xBF52, 0x71CE}, //4667 #CJK UNIFIED IDEOGRAPH + {0xBF53, 0x71D9}, //4668 #CJK UNIFIED IDEOGRAPH + {0xBF54, 0x71DC}, //4669 #CJK UNIFIED IDEOGRAPH + {0xBF55, 0x71C3}, //4670 #CJK UNIFIED IDEOGRAPH + {0xBF56, 0x71C4}, //4671 #CJK UNIFIED IDEOGRAPH + {0xBF57, 0x7368}, //4672 #CJK UNIFIED IDEOGRAPH + {0xBF58, 0x749C}, //4673 #CJK UNIFIED IDEOGRAPH + {0xBF59, 0x74A3}, //4674 #CJK UNIFIED IDEOGRAPH + {0xBF5A, 0x7498}, //4675 #CJK UNIFIED IDEOGRAPH + {0xBF5B, 0x749F}, //4676 #CJK UNIFIED IDEOGRAPH + {0xBF5C, 0x749E}, //4677 #CJK UNIFIED IDEOGRAPH + {0xBF5D, 0x74E2}, //4678 #CJK UNIFIED IDEOGRAPH + {0xBF5E, 0x750C}, //4679 #CJK UNIFIED IDEOGRAPH + {0xBF5F, 0x750D}, //4680 #CJK UNIFIED IDEOGRAPH + {0xBF60, 0x7634}, //4681 #CJK UNIFIED IDEOGRAPH + {0xBF61, 0x7638}, //4682 #CJK UNIFIED IDEOGRAPH + {0xBF62, 0x763A}, //4683 #CJK UNIFIED IDEOGRAPH + {0xBF63, 0x76E7}, //4684 #CJK UNIFIED IDEOGRAPH + {0xBF64, 0x76E5}, //4685 #CJK UNIFIED IDEOGRAPH + {0xBF65, 0x77A0}, //4686 #CJK UNIFIED IDEOGRAPH + {0xBF66, 0x779E}, //4687 #CJK UNIFIED IDEOGRAPH + {0xBF67, 0x779F}, //4688 #CJK UNIFIED IDEOGRAPH + {0xBF68, 0x77A5}, //4689 #CJK UNIFIED IDEOGRAPH + {0xBF69, 0x78E8}, //4690 #CJK UNIFIED IDEOGRAPH + {0xBF6A, 0x78DA}, //4691 #CJK UNIFIED IDEOGRAPH + {0xBF6B, 0x78EC}, //4692 #CJK UNIFIED IDEOGRAPH + {0xBF6C, 0x78E7}, //4693 #CJK UNIFIED IDEOGRAPH + {0xBF6D, 0x79A6}, //4694 #CJK UNIFIED IDEOGRAPH + {0xBF6E, 0x7A4D}, //4695 #CJK UNIFIED IDEOGRAPH + {0xBF6F, 0x7A4E}, //4696 #CJK UNIFIED IDEOGRAPH + {0xBF70, 0x7A46}, //4697 #CJK UNIFIED IDEOGRAPH + {0xBF71, 0x7A4C}, //4698 #CJK UNIFIED IDEOGRAPH + {0xBF72, 0x7A4B}, //4699 #CJK UNIFIED IDEOGRAPH + {0xBF73, 0x7ABA}, //4700 #CJK UNIFIED IDEOGRAPH + {0xBF74, 0x7BD9}, //4701 #CJK UNIFIED IDEOGRAPH + {0xBF75, 0x7C11}, //4702 #CJK UNIFIED IDEOGRAPH + {0xBF76, 0x7BC9}, //4703 #CJK UNIFIED IDEOGRAPH + {0xBF77, 0x7BE4}, //4704 #CJK UNIFIED IDEOGRAPH + {0xBF78, 0x7BDB}, //4705 #CJK UNIFIED IDEOGRAPH + {0xBF79, 0x7BE1}, //4706 #CJK UNIFIED IDEOGRAPH + {0xBF7A, 0x7BE9}, //4707 #CJK UNIFIED IDEOGRAPH + {0xBF7B, 0x7BE6}, //4708 #CJK UNIFIED IDEOGRAPH + {0xBF7C, 0x7CD5}, //4709 #CJK UNIFIED IDEOGRAPH + {0xBF7D, 0x7CD6}, //4710 #CJK UNIFIED IDEOGRAPH + {0xBF7E, 0x7E0A}, //4711 #CJK UNIFIED IDEOGRAPH + {0xBFA1, 0x7E11}, //4712 #CJK UNIFIED IDEOGRAPH + {0xBFA2, 0x7E08}, //4713 #CJK UNIFIED IDEOGRAPH + {0xBFA3, 0x7E1B}, //4714 #CJK UNIFIED IDEOGRAPH + {0xBFA4, 0x7E23}, //4715 #CJK UNIFIED IDEOGRAPH + {0xBFA5, 0x7E1E}, //4716 #CJK UNIFIED IDEOGRAPH + {0xBFA6, 0x7E1D}, //4717 #CJK UNIFIED IDEOGRAPH + {0xBFA7, 0x7E09}, //4718 #CJK UNIFIED IDEOGRAPH + {0xBFA8, 0x7E10}, //4719 #CJK UNIFIED IDEOGRAPH + {0xBFA9, 0x7F79}, //4720 #CJK UNIFIED IDEOGRAPH + {0xBFAA, 0x7FB2}, //4721 #CJK UNIFIED IDEOGRAPH + {0xBFAB, 0x7FF0}, //4722 #CJK UNIFIED IDEOGRAPH + {0xBFAC, 0x7FF1}, //4723 #CJK UNIFIED IDEOGRAPH + {0xBFAD, 0x7FEE}, //4724 #CJK UNIFIED IDEOGRAPH + {0xBFAE, 0x8028}, //4725 #CJK UNIFIED IDEOGRAPH + {0xBFAF, 0x81B3}, //4726 #CJK UNIFIED IDEOGRAPH + {0xBFB0, 0x81A9}, //4727 #CJK UNIFIED IDEOGRAPH + {0xBFB1, 0x81A8}, //4728 #CJK UNIFIED IDEOGRAPH + {0xBFB2, 0x81FB}, //4729 #CJK UNIFIED IDEOGRAPH + {0xBFB3, 0x8208}, //4730 #CJK UNIFIED IDEOGRAPH + {0xBFB4, 0x8258}, //4731 #CJK UNIFIED IDEOGRAPH + {0xBFB5, 0x8259}, //4732 #CJK UNIFIED IDEOGRAPH + {0xBFB6, 0x854A}, //4733 #CJK UNIFIED IDEOGRAPH + {0xBFB7, 0x8559}, //4734 #CJK UNIFIED IDEOGRAPH + {0xBFB8, 0x8548}, //4735 #CJK UNIFIED IDEOGRAPH + {0xBFB9, 0x8568}, //4736 #CJK UNIFIED IDEOGRAPH + {0xBFBA, 0x8569}, //4737 #CJK UNIFIED IDEOGRAPH + {0xBFBB, 0x8543}, //4738 #CJK UNIFIED IDEOGRAPH + {0xBFBC, 0x8549}, //4739 #CJK UNIFIED IDEOGRAPH + {0xBFBD, 0x856D}, //4740 #CJK UNIFIED IDEOGRAPH + {0xBFBE, 0x856A}, //4741 #CJK UNIFIED IDEOGRAPH + {0xBFBF, 0x855E}, //4742 #CJK UNIFIED IDEOGRAPH + {0xBFC0, 0x8783}, //4743 #CJK UNIFIED IDEOGRAPH + {0xBFC1, 0x879F}, //4744 #CJK UNIFIED IDEOGRAPH + {0xBFC2, 0x879E}, //4745 #CJK UNIFIED IDEOGRAPH + {0xBFC3, 0x87A2}, //4746 #CJK UNIFIED IDEOGRAPH + {0xBFC4, 0x878D}, //4747 #CJK UNIFIED IDEOGRAPH + {0xBFC5, 0x8861}, //4748 #CJK UNIFIED IDEOGRAPH + {0xBFC6, 0x892A}, //4749 #CJK UNIFIED IDEOGRAPH + {0xBFC7, 0x8932}, //4750 #CJK UNIFIED IDEOGRAPH + {0xBFC8, 0x8925}, //4751 #CJK UNIFIED IDEOGRAPH + {0xBFC9, 0x892B}, //4752 #CJK UNIFIED IDEOGRAPH + {0xBFCA, 0x8921}, //4753 #CJK UNIFIED IDEOGRAPH + {0xBFCB, 0x89AA}, //4754 #CJK UNIFIED IDEOGRAPH + {0xBFCC, 0x89A6}, //4755 #CJK UNIFIED IDEOGRAPH + {0xBFCD, 0x8AE6}, //4756 #CJK UNIFIED IDEOGRAPH + {0xBFCE, 0x8AFA}, //4757 #CJK UNIFIED IDEOGRAPH + {0xBFCF, 0x8AEB}, //4758 #CJK UNIFIED IDEOGRAPH + {0xBFD0, 0x8AF1}, //4759 #CJK UNIFIED IDEOGRAPH + {0xBFD1, 0x8B00}, //4760 #CJK UNIFIED IDEOGRAPH + {0xBFD2, 0x8ADC}, //4761 #CJK UNIFIED IDEOGRAPH + {0xBFD3, 0x8AE7}, //4762 #CJK UNIFIED IDEOGRAPH + {0xBFD4, 0x8AEE}, //4763 #CJK UNIFIED IDEOGRAPH + {0xBFD5, 0x8AFE}, //4764 #CJK UNIFIED IDEOGRAPH + {0xBFD6, 0x8B01}, //4765 #CJK UNIFIED IDEOGRAPH + {0xBFD7, 0x8B02}, //4766 #CJK UNIFIED IDEOGRAPH + {0xBFD8, 0x8AF7}, //4767 #CJK UNIFIED IDEOGRAPH + {0xBFD9, 0x8AED}, //4768 #CJK UNIFIED IDEOGRAPH + {0xBFDA, 0x8AF3}, //4769 #CJK UNIFIED IDEOGRAPH + {0xBFDB, 0x8AF6}, //4770 #CJK UNIFIED IDEOGRAPH + {0xBFDC, 0x8AFC}, //4771 #CJK UNIFIED IDEOGRAPH + {0xBFDD, 0x8C6B}, //4772 #CJK UNIFIED IDEOGRAPH + {0xBFDE, 0x8C6D}, //4773 #CJK UNIFIED IDEOGRAPH + {0xBFDF, 0x8C93}, //4774 #CJK UNIFIED IDEOGRAPH + {0xBFE0, 0x8CF4}, //4775 #CJK UNIFIED IDEOGRAPH + {0xBFE1, 0x8E44}, //4776 #CJK UNIFIED IDEOGRAPH + {0xBFE2, 0x8E31}, //4777 #CJK UNIFIED IDEOGRAPH + {0xBFE3, 0x8E34}, //4778 #CJK UNIFIED IDEOGRAPH + {0xBFE4, 0x8E42}, //4779 #CJK UNIFIED IDEOGRAPH + {0xBFE5, 0x8E39}, //4780 #CJK UNIFIED IDEOGRAPH + {0xBFE6, 0x8E35}, //4781 #CJK UNIFIED IDEOGRAPH + {0xBFE7, 0x8F3B}, //4782 #CJK UNIFIED IDEOGRAPH + {0xBFE8, 0x8F2F}, //4783 #CJK UNIFIED IDEOGRAPH + {0xBFE9, 0x8F38}, //4784 #CJK UNIFIED IDEOGRAPH + {0xBFEA, 0x8F33}, //4785 #CJK UNIFIED IDEOGRAPH + {0xBFEB, 0x8FA8}, //4786 #CJK UNIFIED IDEOGRAPH + {0xBFEC, 0x8FA6}, //4787 #CJK UNIFIED IDEOGRAPH + {0xBFED, 0x9075}, //4788 #CJK UNIFIED IDEOGRAPH + {0xBFEE, 0x9074}, //4789 #CJK UNIFIED IDEOGRAPH + {0xBFEF, 0x9078}, //4790 #CJK UNIFIED IDEOGRAPH + {0xBFF0, 0x9072}, //4791 #CJK UNIFIED IDEOGRAPH + {0xBFF1, 0x907C}, //4792 #CJK UNIFIED IDEOGRAPH + {0xBFF2, 0x907A}, //4793 #CJK UNIFIED IDEOGRAPH + {0xBFF3, 0x9134}, //4794 #CJK UNIFIED IDEOGRAPH + {0xBFF4, 0x9192}, //4795 #CJK UNIFIED IDEOGRAPH + {0xBFF5, 0x9320}, //4796 #CJK UNIFIED IDEOGRAPH + {0xBFF6, 0x9336}, //4797 #CJK UNIFIED IDEOGRAPH + {0xBFF7, 0x92F8}, //4798 #CJK UNIFIED IDEOGRAPH + {0xBFF8, 0x9333}, //4799 #CJK UNIFIED IDEOGRAPH + {0xBFF9, 0x932F}, //4800 #CJK UNIFIED IDEOGRAPH + {0xBFFA, 0x9322}, //4801 #CJK UNIFIED IDEOGRAPH + {0xBFFB, 0x92FC}, //4802 #CJK UNIFIED IDEOGRAPH + {0xBFFC, 0x932B}, //4803 #CJK UNIFIED IDEOGRAPH + {0xBFFD, 0x9304}, //4804 #CJK UNIFIED IDEOGRAPH + {0xBFFE, 0x931A}, //4805 #CJK UNIFIED IDEOGRAPH + {0xC040, 0x9310}, //4806 #CJK UNIFIED IDEOGRAPH + {0xC041, 0x9326}, //4807 #CJK UNIFIED IDEOGRAPH + {0xC042, 0x9321}, //4808 #CJK UNIFIED IDEOGRAPH + {0xC043, 0x9315}, //4809 #CJK UNIFIED IDEOGRAPH + {0xC044, 0x932E}, //4810 #CJK UNIFIED IDEOGRAPH + {0xC045, 0x9319}, //4811 #CJK UNIFIED IDEOGRAPH + {0xC046, 0x95BB}, //4812 #CJK UNIFIED IDEOGRAPH + {0xC047, 0x96A7}, //4813 #CJK UNIFIED IDEOGRAPH + {0xC048, 0x96A8}, //4814 #CJK UNIFIED IDEOGRAPH + {0xC049, 0x96AA}, //4815 #CJK UNIFIED IDEOGRAPH + {0xC04A, 0x96D5}, //4816 #CJK UNIFIED IDEOGRAPH + {0xC04B, 0x970E}, //4817 #CJK UNIFIED IDEOGRAPH + {0xC04C, 0x9711}, //4818 #CJK UNIFIED IDEOGRAPH + {0xC04D, 0x9716}, //4819 #CJK UNIFIED IDEOGRAPH + {0xC04E, 0x970D}, //4820 #CJK UNIFIED IDEOGRAPH + {0xC04F, 0x9713}, //4821 #CJK UNIFIED IDEOGRAPH + {0xC050, 0x970F}, //4822 #CJK UNIFIED IDEOGRAPH + {0xC051, 0x975B}, //4823 #CJK UNIFIED IDEOGRAPH + {0xC052, 0x975C}, //4824 #CJK UNIFIED IDEOGRAPH + {0xC053, 0x9766}, //4825 #CJK UNIFIED IDEOGRAPH + {0xC054, 0x9798}, //4826 #CJK UNIFIED IDEOGRAPH + {0xC055, 0x9830}, //4827 #CJK UNIFIED IDEOGRAPH + {0xC056, 0x9838}, //4828 #CJK UNIFIED IDEOGRAPH + {0xC057, 0x983B}, //4829 #CJK UNIFIED IDEOGRAPH + {0xC058, 0x9837}, //4830 #CJK UNIFIED IDEOGRAPH + {0xC059, 0x982D}, //4831 #CJK UNIFIED IDEOGRAPH + {0xC05A, 0x9839}, //4832 #CJK UNIFIED IDEOGRAPH + {0xC05B, 0x9824}, //4833 #CJK UNIFIED IDEOGRAPH + {0xC05C, 0x9910}, //4834 #CJK UNIFIED IDEOGRAPH + {0xC05D, 0x9928}, //4835 #CJK UNIFIED IDEOGRAPH + {0xC05E, 0x991E}, //4836 #CJK UNIFIED IDEOGRAPH + {0xC05F, 0x991B}, //4837 #CJK UNIFIED IDEOGRAPH + {0xC060, 0x9921}, //4838 #CJK UNIFIED IDEOGRAPH + {0xC061, 0x991A}, //4839 #CJK UNIFIED IDEOGRAPH + {0xC062, 0x99ED}, //4840 #CJK UNIFIED IDEOGRAPH + {0xC063, 0x99E2}, //4841 #CJK UNIFIED IDEOGRAPH + {0xC064, 0x99F1}, //4842 #CJK UNIFIED IDEOGRAPH + {0xC065, 0x9AB8}, //4843 #CJK UNIFIED IDEOGRAPH + {0xC066, 0x9ABC}, //4844 #CJK UNIFIED IDEOGRAPH + {0xC067, 0x9AFB}, //4845 #CJK UNIFIED IDEOGRAPH + {0xC068, 0x9AED}, //4846 #CJK UNIFIED IDEOGRAPH + {0xC069, 0x9B28}, //4847 #CJK UNIFIED IDEOGRAPH + {0xC06A, 0x9B91}, //4848 #CJK UNIFIED IDEOGRAPH + {0xC06B, 0x9D15}, //4849 #CJK UNIFIED IDEOGRAPH + {0xC06C, 0x9D23}, //4850 #CJK UNIFIED IDEOGRAPH + {0xC06D, 0x9D26}, //4851 #CJK UNIFIED IDEOGRAPH + {0xC06E, 0x9D28}, //4852 #CJK UNIFIED IDEOGRAPH + {0xC06F, 0x9D12}, //4853 #CJK UNIFIED IDEOGRAPH + {0xC070, 0x9D1B}, //4854 #CJK UNIFIED IDEOGRAPH + {0xC071, 0x9ED8}, //4855 #CJK UNIFIED IDEOGRAPH + {0xC072, 0x9ED4}, //4856 #CJK UNIFIED IDEOGRAPH + {0xC073, 0x9F8D}, //4857 #CJK UNIFIED IDEOGRAPH + {0xC074, 0x9F9C}, //4858 #CJK UNIFIED IDEOGRAPH + {0xC075, 0x512A}, //4859 #CJK UNIFIED IDEOGRAPH + {0xC076, 0x511F}, //4860 #CJK UNIFIED IDEOGRAPH + {0xC077, 0x5121}, //4861 #CJK UNIFIED IDEOGRAPH + {0xC078, 0x5132}, //4862 #CJK UNIFIED IDEOGRAPH + {0xC079, 0x52F5}, //4863 #CJK UNIFIED IDEOGRAPH + {0xC07A, 0x568E}, //4864 #CJK UNIFIED IDEOGRAPH + {0xC07B, 0x5680}, //4865 #CJK UNIFIED IDEOGRAPH + {0xC07C, 0x5690}, //4866 #CJK UNIFIED IDEOGRAPH + {0xC07D, 0x5685}, //4867 #CJK UNIFIED IDEOGRAPH + {0xC07E, 0x5687}, //4868 #CJK UNIFIED IDEOGRAPH + {0xC0A1, 0x568F}, //4869 #CJK UNIFIED IDEOGRAPH + {0xC0A2, 0x58D5}, //4870 #CJK UNIFIED IDEOGRAPH + {0xC0A3, 0x58D3}, //4871 #CJK UNIFIED IDEOGRAPH + {0xC0A4, 0x58D1}, //4872 #CJK UNIFIED IDEOGRAPH + {0xC0A5, 0x58CE}, //4873 #CJK UNIFIED IDEOGRAPH + {0xC0A6, 0x5B30}, //4874 #CJK UNIFIED IDEOGRAPH + {0xC0A7, 0x5B2A}, //4875 #CJK UNIFIED IDEOGRAPH + {0xC0A8, 0x5B24}, //4876 #CJK UNIFIED IDEOGRAPH + {0xC0A9, 0x5B7A}, //4877 #CJK UNIFIED IDEOGRAPH + {0xC0AA, 0x5C37}, //4878 #CJK UNIFIED IDEOGRAPH + {0xC0AB, 0x5C68}, //4879 #CJK UNIFIED IDEOGRAPH + {0xC0AC, 0x5DBC}, //4880 #CJK UNIFIED IDEOGRAPH + {0xC0AD, 0x5DBA}, //4881 #CJK UNIFIED IDEOGRAPH + {0xC0AE, 0x5DBD}, //4882 #CJK UNIFIED IDEOGRAPH + {0xC0AF, 0x5DB8}, //4883 #CJK UNIFIED IDEOGRAPH + {0xC0B0, 0x5E6B}, //4884 #CJK UNIFIED IDEOGRAPH + {0xC0B1, 0x5F4C}, //4885 #CJK UNIFIED IDEOGRAPH + {0xC0B2, 0x5FBD}, //4886 #CJK UNIFIED IDEOGRAPH + {0xC0B3, 0x61C9}, //4887 #CJK UNIFIED IDEOGRAPH + {0xC0B4, 0x61C2}, //4888 #CJK UNIFIED IDEOGRAPH + {0xC0B5, 0x61C7}, //4889 #CJK UNIFIED IDEOGRAPH + {0xC0B6, 0x61E6}, //4890 #CJK UNIFIED IDEOGRAPH + {0xC0B7, 0x61CB}, //4891 #CJK UNIFIED IDEOGRAPH + {0xC0B8, 0x6232}, //4892 #CJK UNIFIED IDEOGRAPH + {0xC0B9, 0x6234}, //4893 #CJK UNIFIED IDEOGRAPH + {0xC0BA, 0x64CE}, //4894 #CJK UNIFIED IDEOGRAPH + {0xC0BB, 0x64CA}, //4895 #CJK UNIFIED IDEOGRAPH + {0xC0BC, 0x64D8}, //4896 #CJK UNIFIED IDEOGRAPH + {0xC0BD, 0x64E0}, //4897 #CJK UNIFIED IDEOGRAPH + {0xC0BE, 0x64F0}, //4898 #CJK UNIFIED IDEOGRAPH + {0xC0BF, 0x64E6}, //4899 #CJK UNIFIED IDEOGRAPH + {0xC0C0, 0x64EC}, //4900 #CJK UNIFIED IDEOGRAPH + {0xC0C1, 0x64F1}, //4901 #CJK UNIFIED IDEOGRAPH + {0xC0C2, 0x64E2}, //4902 #CJK UNIFIED IDEOGRAPH + {0xC0C3, 0x64ED}, //4903 #CJK UNIFIED IDEOGRAPH + {0xC0C4, 0x6582}, //4904 #CJK UNIFIED IDEOGRAPH + {0xC0C5, 0x6583}, //4905 #CJK UNIFIED IDEOGRAPH + {0xC0C6, 0x66D9}, //4906 #CJK UNIFIED IDEOGRAPH + {0xC0C7, 0x66D6}, //4907 #CJK UNIFIED IDEOGRAPH + {0xC0C8, 0x6A80}, //4908 #CJK UNIFIED IDEOGRAPH + {0xC0C9, 0x6A94}, //4909 #CJK UNIFIED IDEOGRAPH + {0xC0CA, 0x6A84}, //4910 #CJK UNIFIED IDEOGRAPH + {0xC0CB, 0x6AA2}, //4911 #CJK UNIFIED IDEOGRAPH + {0xC0CC, 0x6A9C}, //4912 #CJK UNIFIED IDEOGRAPH + {0xC0CD, 0x6ADB}, //4913 #CJK UNIFIED IDEOGRAPH + {0xC0CE, 0x6AA3}, //4914 #CJK UNIFIED IDEOGRAPH + {0xC0CF, 0x6A7E}, //4915 #CJK UNIFIED IDEOGRAPH + {0xC0D0, 0x6A97}, //4916 #CJK UNIFIED IDEOGRAPH + {0xC0D1, 0x6A90}, //4917 #CJK UNIFIED IDEOGRAPH + {0xC0D2, 0x6AA0}, //4918 #CJK UNIFIED IDEOGRAPH + {0xC0D3, 0x6B5C}, //4919 #CJK UNIFIED IDEOGRAPH + {0xC0D4, 0x6BAE}, //4920 #CJK UNIFIED IDEOGRAPH + {0xC0D5, 0x6BDA}, //4921 #CJK UNIFIED IDEOGRAPH + {0xC0D6, 0x6C08}, //4922 #CJK UNIFIED IDEOGRAPH + {0xC0D7, 0x6FD8}, //4923 #CJK UNIFIED IDEOGRAPH + {0xC0D8, 0x6FF1}, //4924 #CJK UNIFIED IDEOGRAPH + {0xC0D9, 0x6FDF}, //4925 #CJK UNIFIED IDEOGRAPH + {0xC0DA, 0x6FE0}, //4926 #CJK UNIFIED IDEOGRAPH + {0xC0DB, 0x6FDB}, //4927 #CJK UNIFIED IDEOGRAPH + {0xC0DC, 0x6FE4}, //4928 #CJK UNIFIED IDEOGRAPH + {0xC0DD, 0x6FEB}, //4929 #CJK UNIFIED IDEOGRAPH + {0xC0DE, 0x6FEF}, //4930 #CJK UNIFIED IDEOGRAPH + {0xC0DF, 0x6F80}, //4931 #CJK UNIFIED IDEOGRAPH + {0xC0E0, 0x6FEC}, //4932 #CJK UNIFIED IDEOGRAPH + {0xC0E1, 0x6FE1}, //4933 #CJK UNIFIED IDEOGRAPH + {0xC0E2, 0x6FE9}, //4934 #CJK UNIFIED IDEOGRAPH + {0xC0E3, 0x6FD5}, //4935 #CJK UNIFIED IDEOGRAPH + {0xC0E4, 0x6FEE}, //4936 #CJK UNIFIED IDEOGRAPH + {0xC0E5, 0x6FF0}, //4937 #CJK UNIFIED IDEOGRAPH + {0xC0E6, 0x71E7}, //4938 #CJK UNIFIED IDEOGRAPH + {0xC0E7, 0x71DF}, //4939 #CJK UNIFIED IDEOGRAPH + {0xC0E8, 0x71EE}, //4940 #CJK UNIFIED IDEOGRAPH + {0xC0E9, 0x71E6}, //4941 #CJK UNIFIED IDEOGRAPH + {0xC0EA, 0x71E5}, //4942 #CJK UNIFIED IDEOGRAPH + {0xC0EB, 0x71ED}, //4943 #CJK UNIFIED IDEOGRAPH + {0xC0EC, 0x71EC}, //4944 #CJK UNIFIED IDEOGRAPH + {0xC0ED, 0x71F4}, //4945 #CJK UNIFIED IDEOGRAPH + {0xC0EE, 0x71E0}, //4946 #CJK UNIFIED IDEOGRAPH + {0xC0EF, 0x7235}, //4947 #CJK UNIFIED IDEOGRAPH + {0xC0F0, 0x7246}, //4948 #CJK UNIFIED IDEOGRAPH + {0xC0F1, 0x7370}, //4949 #CJK UNIFIED IDEOGRAPH + {0xC0F2, 0x7372}, //4950 #CJK UNIFIED IDEOGRAPH + {0xC0F3, 0x74A9}, //4951 #CJK UNIFIED IDEOGRAPH + {0xC0F4, 0x74B0}, //4952 #CJK UNIFIED IDEOGRAPH + {0xC0F5, 0x74A6}, //4953 #CJK UNIFIED IDEOGRAPH + {0xC0F6, 0x74A8}, //4954 #CJK UNIFIED IDEOGRAPH + {0xC0F7, 0x7646}, //4955 #CJK UNIFIED IDEOGRAPH + {0xC0F8, 0x7642}, //4956 #CJK UNIFIED IDEOGRAPH + {0xC0F9, 0x764C}, //4957 #CJK UNIFIED IDEOGRAPH + {0xC0FA, 0x76EA}, //4958 #CJK UNIFIED IDEOGRAPH + {0xC0FB, 0x77B3}, //4959 #CJK UNIFIED IDEOGRAPH + {0xC0FC, 0x77AA}, //4960 #CJK UNIFIED IDEOGRAPH + {0xC0FD, 0x77B0}, //4961 #CJK UNIFIED IDEOGRAPH + {0xC0FE, 0x77AC}, //4962 #CJK UNIFIED IDEOGRAPH + {0xC140, 0x77A7}, //4963 #CJK UNIFIED IDEOGRAPH + {0xC141, 0x77AD}, //4964 #CJK UNIFIED IDEOGRAPH + {0xC142, 0x77EF}, //4965 #CJK UNIFIED IDEOGRAPH + {0xC143, 0x78F7}, //4966 #CJK UNIFIED IDEOGRAPH + {0xC144, 0x78FA}, //4967 #CJK UNIFIED IDEOGRAPH + {0xC145, 0x78F4}, //4968 #CJK UNIFIED IDEOGRAPH + {0xC146, 0x78EF}, //4969 #CJK UNIFIED IDEOGRAPH + {0xC147, 0x7901}, //4970 #CJK UNIFIED IDEOGRAPH + {0xC148, 0x79A7}, //4971 #CJK UNIFIED IDEOGRAPH + {0xC149, 0x79AA}, //4972 #CJK UNIFIED IDEOGRAPH + {0xC14A, 0x7A57}, //4973 #CJK UNIFIED IDEOGRAPH + {0xC14B, 0x7ABF}, //4974 #CJK UNIFIED IDEOGRAPH + {0xC14C, 0x7C07}, //4975 #CJK UNIFIED IDEOGRAPH + {0xC14D, 0x7C0D}, //4976 #CJK UNIFIED IDEOGRAPH + {0xC14E, 0x7BFE}, //4977 #CJK UNIFIED IDEOGRAPH + {0xC14F, 0x7BF7}, //4978 #CJK UNIFIED IDEOGRAPH + {0xC150, 0x7C0C}, //4979 #CJK UNIFIED IDEOGRAPH + {0xC151, 0x7BE0}, //4980 #CJK UNIFIED IDEOGRAPH + {0xC152, 0x7CE0}, //4981 #CJK UNIFIED IDEOGRAPH + {0xC153, 0x7CDC}, //4982 #CJK UNIFIED IDEOGRAPH + {0xC154, 0x7CDE}, //4983 #CJK UNIFIED IDEOGRAPH + {0xC155, 0x7CE2}, //4984 #CJK UNIFIED IDEOGRAPH + {0xC156, 0x7CDF}, //4985 #CJK UNIFIED IDEOGRAPH + {0xC157, 0x7CD9}, //4986 #CJK UNIFIED IDEOGRAPH + {0xC158, 0x7CDD}, //4987 #CJK UNIFIED IDEOGRAPH + {0xC159, 0x7E2E}, //4988 #CJK UNIFIED IDEOGRAPH + {0xC15A, 0x7E3E}, //4989 #CJK UNIFIED IDEOGRAPH + {0xC15B, 0x7E46}, //4990 #CJK UNIFIED IDEOGRAPH + {0xC15C, 0x7E37}, //4991 #CJK UNIFIED IDEOGRAPH + {0xC15D, 0x7E32}, //4992 #CJK UNIFIED IDEOGRAPH + {0xC15E, 0x7E43}, //4993 #CJK UNIFIED IDEOGRAPH + {0xC15F, 0x7E2B}, //4994 #CJK UNIFIED IDEOGRAPH + {0xC160, 0x7E3D}, //4995 #CJK UNIFIED IDEOGRAPH + {0xC161, 0x7E31}, //4996 #CJK UNIFIED IDEOGRAPH + {0xC162, 0x7E45}, //4997 #CJK UNIFIED IDEOGRAPH + {0xC163, 0x7E41}, //4998 #CJK UNIFIED IDEOGRAPH + {0xC164, 0x7E34}, //4999 #CJK UNIFIED IDEOGRAPH + {0xC165, 0x7E39}, //5000 #CJK UNIFIED IDEOGRAPH + {0xC166, 0x7E48}, //5001 #CJK UNIFIED IDEOGRAPH + {0xC167, 0x7E35}, //5002 #CJK UNIFIED IDEOGRAPH + {0xC168, 0x7E3F}, //5003 #CJK UNIFIED IDEOGRAPH + {0xC169, 0x7E2F}, //5004 #CJK UNIFIED IDEOGRAPH + {0xC16A, 0x7F44}, //5005 #CJK UNIFIED IDEOGRAPH + {0xC16B, 0x7FF3}, //5006 #CJK UNIFIED IDEOGRAPH + {0xC16C, 0x7FFC}, //5007 #CJK UNIFIED IDEOGRAPH + {0xC16D, 0x8071}, //5008 #CJK UNIFIED IDEOGRAPH + {0xC16E, 0x8072}, //5009 #CJK UNIFIED IDEOGRAPH + {0xC16F, 0x8070}, //5010 #CJK UNIFIED IDEOGRAPH + {0xC170, 0x806F}, //5011 #CJK UNIFIED IDEOGRAPH + {0xC171, 0x8073}, //5012 #CJK UNIFIED IDEOGRAPH + {0xC172, 0x81C6}, //5013 #CJK UNIFIED IDEOGRAPH + {0xC173, 0x81C3}, //5014 #CJK UNIFIED IDEOGRAPH + {0xC174, 0x81BA}, //5015 #CJK UNIFIED IDEOGRAPH + {0xC175, 0x81C2}, //5016 #CJK UNIFIED IDEOGRAPH + {0xC176, 0x81C0}, //5017 #CJK UNIFIED IDEOGRAPH + {0xC177, 0x81BF}, //5018 #CJK UNIFIED IDEOGRAPH + {0xC178, 0x81BD}, //5019 #CJK UNIFIED IDEOGRAPH + {0xC179, 0x81C9}, //5020 #CJK UNIFIED IDEOGRAPH + {0xC17A, 0x81BE}, //5021 #CJK UNIFIED IDEOGRAPH + {0xC17B, 0x81E8}, //5022 #CJK UNIFIED IDEOGRAPH + {0xC17C, 0x8209}, //5023 #CJK UNIFIED IDEOGRAPH + {0xC17D, 0x8271}, //5024 #CJK UNIFIED IDEOGRAPH + {0xC17E, 0x85AA}, //5025 #CJK UNIFIED IDEOGRAPH + {0xC1A1, 0x8584}, //5026 #CJK UNIFIED IDEOGRAPH + {0xC1A2, 0x857E}, //5027 #CJK UNIFIED IDEOGRAPH + {0xC1A3, 0x859C}, //5028 #CJK UNIFIED IDEOGRAPH + {0xC1A4, 0x8591}, //5029 #CJK UNIFIED IDEOGRAPH + {0xC1A5, 0x8594}, //5030 #CJK UNIFIED IDEOGRAPH + {0xC1A6, 0x85AF}, //5031 #CJK UNIFIED IDEOGRAPH + {0xC1A7, 0x859B}, //5032 #CJK UNIFIED IDEOGRAPH + {0xC1A8, 0x8587}, //5033 #CJK UNIFIED IDEOGRAPH + {0xC1A9, 0x85A8}, //5034 #CJK UNIFIED IDEOGRAPH + {0xC1AA, 0x858A}, //5035 #CJK UNIFIED IDEOGRAPH + {0xC1AB, 0x8667}, //5036 #CJK UNIFIED IDEOGRAPH + {0xC1AC, 0x87C0}, //5037 #CJK UNIFIED IDEOGRAPH + {0xC1AD, 0x87D1}, //5038 #CJK UNIFIED IDEOGRAPH + {0xC1AE, 0x87B3}, //5039 #CJK UNIFIED IDEOGRAPH + {0xC1AF, 0x87D2}, //5040 #CJK UNIFIED IDEOGRAPH + {0xC1B0, 0x87C6}, //5041 #CJK UNIFIED IDEOGRAPH + {0xC1B1, 0x87AB}, //5042 #CJK UNIFIED IDEOGRAPH + {0xC1B2, 0x87BB}, //5043 #CJK UNIFIED IDEOGRAPH + {0xC1B3, 0x87BA}, //5044 #CJK UNIFIED IDEOGRAPH + {0xC1B4, 0x87C8}, //5045 #CJK UNIFIED IDEOGRAPH + {0xC1B5, 0x87CB}, //5046 #CJK UNIFIED IDEOGRAPH + {0xC1B6, 0x893B}, //5047 #CJK UNIFIED IDEOGRAPH + {0xC1B7, 0x8936}, //5048 #CJK UNIFIED IDEOGRAPH + {0xC1B8, 0x8944}, //5049 #CJK UNIFIED IDEOGRAPH + {0xC1B9, 0x8938}, //5050 #CJK UNIFIED IDEOGRAPH + {0xC1BA, 0x893D}, //5051 #CJK UNIFIED IDEOGRAPH + {0xC1BB, 0x89AC}, //5052 #CJK UNIFIED IDEOGRAPH + {0xC1BC, 0x8B0E}, //5053 #CJK UNIFIED IDEOGRAPH + {0xC1BD, 0x8B17}, //5054 #CJK UNIFIED IDEOGRAPH + {0xC1BE, 0x8B19}, //5055 #CJK UNIFIED IDEOGRAPH + {0xC1BF, 0x8B1B}, //5056 #CJK UNIFIED IDEOGRAPH + {0xC1C0, 0x8B0A}, //5057 #CJK UNIFIED IDEOGRAPH + {0xC1C1, 0x8B20}, //5058 #CJK UNIFIED IDEOGRAPH + {0xC1C2, 0x8B1D}, //5059 #CJK UNIFIED IDEOGRAPH + {0xC1C3, 0x8B04}, //5060 #CJK UNIFIED IDEOGRAPH + {0xC1C4, 0x8B10}, //5061 #CJK UNIFIED IDEOGRAPH + {0xC1C5, 0x8C41}, //5062 #CJK UNIFIED IDEOGRAPH + {0xC1C6, 0x8C3F}, //5063 #CJK UNIFIED IDEOGRAPH + {0xC1C7, 0x8C73}, //5064 #CJK UNIFIED IDEOGRAPH + {0xC1C8, 0x8CFA}, //5065 #CJK UNIFIED IDEOGRAPH + {0xC1C9, 0x8CFD}, //5066 #CJK UNIFIED IDEOGRAPH + {0xC1CA, 0x8CFC}, //5067 #CJK UNIFIED IDEOGRAPH + {0xC1CB, 0x8CF8}, //5068 #CJK UNIFIED IDEOGRAPH + {0xC1CC, 0x8CFB}, //5069 #CJK UNIFIED IDEOGRAPH + {0xC1CD, 0x8DA8}, //5070 #CJK UNIFIED IDEOGRAPH + {0xC1CE, 0x8E49}, //5071 #CJK UNIFIED IDEOGRAPH + {0xC1CF, 0x8E4B}, //5072 #CJK UNIFIED IDEOGRAPH + {0xC1D0, 0x8E48}, //5073 #CJK UNIFIED IDEOGRAPH + {0xC1D1, 0x8E4A}, //5074 #CJK UNIFIED IDEOGRAPH + {0xC1D2, 0x8F44}, //5075 #CJK UNIFIED IDEOGRAPH + {0xC1D3, 0x8F3E}, //5076 #CJK UNIFIED IDEOGRAPH + {0xC1D4, 0x8F42}, //5077 #CJK UNIFIED IDEOGRAPH + {0xC1D5, 0x8F45}, //5078 #CJK UNIFIED IDEOGRAPH + {0xC1D6, 0x8F3F}, //5079 #CJK UNIFIED IDEOGRAPH + {0xC1D7, 0x907F}, //5080 #CJK UNIFIED IDEOGRAPH + {0xC1D8, 0x907D}, //5081 #CJK UNIFIED IDEOGRAPH + {0xC1D9, 0x9084}, //5082 #CJK UNIFIED IDEOGRAPH + {0xC1DA, 0x9081}, //5083 #CJK UNIFIED IDEOGRAPH + {0xC1DB, 0x9082}, //5084 #CJK UNIFIED IDEOGRAPH + {0xC1DC, 0x9080}, //5085 #CJK UNIFIED IDEOGRAPH + {0xC1DD, 0x9139}, //5086 #CJK UNIFIED IDEOGRAPH + {0xC1DE, 0x91A3}, //5087 #CJK UNIFIED IDEOGRAPH + {0xC1DF, 0x919E}, //5088 #CJK UNIFIED IDEOGRAPH + {0xC1E0, 0x919C}, //5089 #CJK UNIFIED IDEOGRAPH + {0xC1E1, 0x934D}, //5090 #CJK UNIFIED IDEOGRAPH + {0xC1E2, 0x9382}, //5091 #CJK UNIFIED IDEOGRAPH + {0xC1E3, 0x9328}, //5092 #CJK UNIFIED IDEOGRAPH + {0xC1E4, 0x9375}, //5093 #CJK UNIFIED IDEOGRAPH + {0xC1E5, 0x934A}, //5094 #CJK UNIFIED IDEOGRAPH + {0xC1E6, 0x9365}, //5095 #CJK UNIFIED IDEOGRAPH + {0xC1E7, 0x934B}, //5096 #CJK UNIFIED IDEOGRAPH + {0xC1E8, 0x9318}, //5097 #CJK UNIFIED IDEOGRAPH + {0xC1E9, 0x937E}, //5098 #CJK UNIFIED IDEOGRAPH + {0xC1EA, 0x936C}, //5099 #CJK UNIFIED IDEOGRAPH + {0xC1EB, 0x935B}, //5100 #CJK UNIFIED IDEOGRAPH + {0xC1EC, 0x9370}, //5101 #CJK UNIFIED IDEOGRAPH + {0xC1ED, 0x935A}, //5102 #CJK UNIFIED IDEOGRAPH + {0xC1EE, 0x9354}, //5103 #CJK UNIFIED IDEOGRAPH + {0xC1EF, 0x95CA}, //5104 #CJK UNIFIED IDEOGRAPH + {0xC1F0, 0x95CB}, //5105 #CJK UNIFIED IDEOGRAPH + {0xC1F1, 0x95CC}, //5106 #CJK UNIFIED IDEOGRAPH + {0xC1F2, 0x95C8}, //5107 #CJK UNIFIED IDEOGRAPH + {0xC1F3, 0x95C6}, //5108 #CJK UNIFIED IDEOGRAPH + {0xC1F4, 0x96B1}, //5109 #CJK UNIFIED IDEOGRAPH + {0xC1F5, 0x96B8}, //5110 #CJK UNIFIED IDEOGRAPH + {0xC1F6, 0x96D6}, //5111 #CJK UNIFIED IDEOGRAPH + {0xC1F7, 0x971C}, //5112 #CJK UNIFIED IDEOGRAPH + {0xC1F8, 0x971E}, //5113 #CJK UNIFIED IDEOGRAPH + {0xC1F9, 0x97A0}, //5114 #CJK UNIFIED IDEOGRAPH + {0xC1FA, 0x97D3}, //5115 #CJK UNIFIED IDEOGRAPH + {0xC1FB, 0x9846}, //5116 #CJK UNIFIED IDEOGRAPH + {0xC1FC, 0x98B6}, //5117 #CJK UNIFIED IDEOGRAPH + {0xC1FD, 0x9935}, //5118 #CJK UNIFIED IDEOGRAPH + {0xC1FE, 0x9A01}, //5119 #CJK UNIFIED IDEOGRAPH + {0xC240, 0x99FF}, //5120 #CJK UNIFIED IDEOGRAPH + {0xC241, 0x9BAE}, //5121 #CJK UNIFIED IDEOGRAPH + {0xC242, 0x9BAB}, //5122 #CJK UNIFIED IDEOGRAPH + {0xC243, 0x9BAA}, //5123 #CJK UNIFIED IDEOGRAPH + {0xC244, 0x9BAD}, //5124 #CJK UNIFIED IDEOGRAPH + {0xC245, 0x9D3B}, //5125 #CJK UNIFIED IDEOGRAPH + {0xC246, 0x9D3F}, //5126 #CJK UNIFIED IDEOGRAPH + {0xC247, 0x9E8B}, //5127 #CJK UNIFIED IDEOGRAPH + {0xC248, 0x9ECF}, //5128 #CJK UNIFIED IDEOGRAPH + {0xC249, 0x9EDE}, //5129 #CJK UNIFIED IDEOGRAPH + {0xC24A, 0x9EDC}, //5130 #CJK UNIFIED IDEOGRAPH + {0xC24B, 0x9EDD}, //5131 #CJK UNIFIED IDEOGRAPH + {0xC24C, 0x9EDB}, //5132 #CJK UNIFIED IDEOGRAPH + {0xC24D, 0x9F3E}, //5133 #CJK UNIFIED IDEOGRAPH + {0xC24E, 0x9F4B}, //5134 #CJK UNIFIED IDEOGRAPH + {0xC24F, 0x53E2}, //5135 #CJK UNIFIED IDEOGRAPH + {0xC250, 0x5695}, //5136 #CJK UNIFIED IDEOGRAPH + {0xC251, 0x56AE}, //5137 #CJK UNIFIED IDEOGRAPH + {0xC252, 0x58D9}, //5138 #CJK UNIFIED IDEOGRAPH + {0xC253, 0x58D8}, //5139 #CJK UNIFIED IDEOGRAPH + {0xC254, 0x5B38}, //5140 #CJK UNIFIED IDEOGRAPH + {0xC255, 0x5F5D}, //5141 #CJK UNIFIED IDEOGRAPH + {0xC256, 0x61E3}, //5142 #CJK UNIFIED IDEOGRAPH + {0xC257, 0x6233}, //5143 #CJK UNIFIED IDEOGRAPH + {0xC258, 0x64F4}, //5144 #CJK UNIFIED IDEOGRAPH + {0xC259, 0x64F2}, //5145 #CJK UNIFIED IDEOGRAPH + {0xC25A, 0x64FE}, //5146 #CJK UNIFIED IDEOGRAPH + {0xC25B, 0x6506}, //5147 #CJK UNIFIED IDEOGRAPH + {0xC25C, 0x64FA}, //5148 #CJK UNIFIED IDEOGRAPH + {0xC25D, 0x64FB}, //5149 #CJK UNIFIED IDEOGRAPH + {0xC25E, 0x64F7}, //5150 #CJK UNIFIED IDEOGRAPH + {0xC25F, 0x65B7}, //5151 #CJK UNIFIED IDEOGRAPH + {0xC260, 0x66DC}, //5152 #CJK UNIFIED IDEOGRAPH + {0xC261, 0x6726}, //5153 #CJK UNIFIED IDEOGRAPH + {0xC262, 0x6AB3}, //5154 #CJK UNIFIED IDEOGRAPH + {0xC263, 0x6AAC}, //5155 #CJK UNIFIED IDEOGRAPH + {0xC264, 0x6AC3}, //5156 #CJK UNIFIED IDEOGRAPH + {0xC265, 0x6ABB}, //5157 #CJK UNIFIED IDEOGRAPH + {0xC266, 0x6AB8}, //5158 #CJK UNIFIED IDEOGRAPH + {0xC267, 0x6AC2}, //5159 #CJK UNIFIED IDEOGRAPH + {0xC268, 0x6AAE}, //5160 #CJK UNIFIED IDEOGRAPH + {0xC269, 0x6AAF}, //5161 #CJK UNIFIED IDEOGRAPH + {0xC26A, 0x6B5F}, //5162 #CJK UNIFIED IDEOGRAPH + {0xC26B, 0x6B78}, //5163 #CJK UNIFIED IDEOGRAPH + {0xC26C, 0x6BAF}, //5164 #CJK UNIFIED IDEOGRAPH + {0xC26D, 0x7009}, //5165 #CJK UNIFIED IDEOGRAPH + {0xC26E, 0x700B}, //5166 #CJK UNIFIED IDEOGRAPH + {0xC26F, 0x6FFE}, //5167 #CJK UNIFIED IDEOGRAPH + {0xC270, 0x7006}, //5168 #CJK UNIFIED IDEOGRAPH + {0xC271, 0x6FFA}, //5169 #CJK UNIFIED IDEOGRAPH + {0xC272, 0x7011}, //5170 #CJK UNIFIED IDEOGRAPH + {0xC273, 0x700F}, //5171 #CJK UNIFIED IDEOGRAPH + {0xC274, 0x71FB}, //5172 #CJK UNIFIED IDEOGRAPH + {0xC275, 0x71FC}, //5173 #CJK UNIFIED IDEOGRAPH + {0xC276, 0x71FE}, //5174 #CJK UNIFIED IDEOGRAPH + {0xC277, 0x71F8}, //5175 #CJK UNIFIED IDEOGRAPH + {0xC278, 0x7377}, //5176 #CJK UNIFIED IDEOGRAPH + {0xC279, 0x7375}, //5177 #CJK UNIFIED IDEOGRAPH + {0xC27A, 0x74A7}, //5178 #CJK UNIFIED IDEOGRAPH + {0xC27B, 0x74BF}, //5179 #CJK UNIFIED IDEOGRAPH + {0xC27C, 0x7515}, //5180 #CJK UNIFIED IDEOGRAPH + {0xC27D, 0x7656}, //5181 #CJK UNIFIED IDEOGRAPH + {0xC27E, 0x7658}, //5182 #CJK UNIFIED IDEOGRAPH + {0xC2A1, 0x7652}, //5183 #CJK UNIFIED IDEOGRAPH + {0xC2A2, 0x77BD}, //5184 #CJK UNIFIED IDEOGRAPH + {0xC2A3, 0x77BF}, //5185 #CJK UNIFIED IDEOGRAPH + {0xC2A4, 0x77BB}, //5186 #CJK UNIFIED IDEOGRAPH + {0xC2A5, 0x77BC}, //5187 #CJK UNIFIED IDEOGRAPH + {0xC2A6, 0x790E}, //5188 #CJK UNIFIED IDEOGRAPH + {0xC2A7, 0x79AE}, //5189 #CJK UNIFIED IDEOGRAPH + {0xC2A8, 0x7A61}, //5190 #CJK UNIFIED IDEOGRAPH + {0xC2A9, 0x7A62}, //5191 #CJK UNIFIED IDEOGRAPH + {0xC2AA, 0x7A60}, //5192 #CJK UNIFIED IDEOGRAPH + {0xC2AB, 0x7AC4}, //5193 #CJK UNIFIED IDEOGRAPH + {0xC2AC, 0x7AC5}, //5194 #CJK UNIFIED IDEOGRAPH + {0xC2AD, 0x7C2B}, //5195 #CJK UNIFIED IDEOGRAPH + {0xC2AE, 0x7C27}, //5196 #CJK UNIFIED IDEOGRAPH + {0xC2AF, 0x7C2A}, //5197 #CJK UNIFIED IDEOGRAPH + {0xC2B0, 0x7C1E}, //5198 #CJK UNIFIED IDEOGRAPH + {0xC2B1, 0x7C23}, //5199 #CJK UNIFIED IDEOGRAPH + {0xC2B2, 0x7C21}, //5200 #CJK UNIFIED IDEOGRAPH + {0xC2B3, 0x7CE7}, //5201 #CJK UNIFIED IDEOGRAPH + {0xC2B4, 0x7E54}, //5202 #CJK UNIFIED IDEOGRAPH + {0xC2B5, 0x7E55}, //5203 #CJK UNIFIED IDEOGRAPH + {0xC2B6, 0x7E5E}, //5204 #CJK UNIFIED IDEOGRAPH + {0xC2B7, 0x7E5A}, //5205 #CJK UNIFIED IDEOGRAPH + {0xC2B8, 0x7E61}, //5206 #CJK UNIFIED IDEOGRAPH + {0xC2B9, 0x7E52}, //5207 #CJK UNIFIED IDEOGRAPH + {0xC2BA, 0x7E59}, //5208 #CJK UNIFIED IDEOGRAPH + {0xC2BB, 0x7F48}, //5209 #CJK UNIFIED IDEOGRAPH + {0xC2BC, 0x7FF9}, //5210 #CJK UNIFIED IDEOGRAPH + {0xC2BD, 0x7FFB}, //5211 #CJK UNIFIED IDEOGRAPH + {0xC2BE, 0x8077}, //5212 #CJK UNIFIED IDEOGRAPH + {0xC2BF, 0x8076}, //5213 #CJK UNIFIED IDEOGRAPH + {0xC2C0, 0x81CD}, //5214 #CJK UNIFIED IDEOGRAPH + {0xC2C1, 0x81CF}, //5215 #CJK UNIFIED IDEOGRAPH + {0xC2C2, 0x820A}, //5216 #CJK UNIFIED IDEOGRAPH + {0xC2C3, 0x85CF}, //5217 #CJK UNIFIED IDEOGRAPH + {0xC2C4, 0x85A9}, //5218 #CJK UNIFIED IDEOGRAPH + {0xC2C5, 0x85CD}, //5219 #CJK UNIFIED IDEOGRAPH + {0xC2C6, 0x85D0}, //5220 #CJK UNIFIED IDEOGRAPH + {0xC2C7, 0x85C9}, //5221 #CJK UNIFIED IDEOGRAPH + {0xC2C8, 0x85B0}, //5222 #CJK UNIFIED IDEOGRAPH + {0xC2C9, 0x85BA}, //5223 #CJK UNIFIED IDEOGRAPH + {0xC2CA, 0x85B9}, //5224 #CJK UNIFIED IDEOGRAPH + {0xC2CB, 0x85A6}, //5225 #CJK UNIFIED IDEOGRAPH + {0xC2CC, 0x87EF}, //5226 #CJK UNIFIED IDEOGRAPH + {0xC2CD, 0x87EC}, //5227 #CJK UNIFIED IDEOGRAPH + {0xC2CE, 0x87F2}, //5228 #CJK UNIFIED IDEOGRAPH + {0xC2CF, 0x87E0}, //5229 #CJK UNIFIED IDEOGRAPH + {0xC2D0, 0x8986}, //5230 #CJK UNIFIED IDEOGRAPH + {0xC2D1, 0x89B2}, //5231 #CJK UNIFIED IDEOGRAPH + {0xC2D2, 0x89F4}, //5232 #CJK UNIFIED IDEOGRAPH + {0xC2D3, 0x8B28}, //5233 #CJK UNIFIED IDEOGRAPH + {0xC2D4, 0x8B39}, //5234 #CJK UNIFIED IDEOGRAPH + {0xC2D5, 0x8B2C}, //5235 #CJK UNIFIED IDEOGRAPH + {0xC2D6, 0x8B2B}, //5236 #CJK UNIFIED IDEOGRAPH + {0xC2D7, 0x8C50}, //5237 #CJK UNIFIED IDEOGRAPH + {0xC2D8, 0x8D05}, //5238 #CJK UNIFIED IDEOGRAPH + {0xC2D9, 0x8E59}, //5239 #CJK UNIFIED IDEOGRAPH + {0xC2DA, 0x8E63}, //5240 #CJK UNIFIED IDEOGRAPH + {0xC2DB, 0x8E66}, //5241 #CJK UNIFIED IDEOGRAPH + {0xC2DC, 0x8E64}, //5242 #CJK UNIFIED IDEOGRAPH + {0xC2DD, 0x8E5F}, //5243 #CJK UNIFIED IDEOGRAPH + {0xC2DE, 0x8E55}, //5244 #CJK UNIFIED IDEOGRAPH + {0xC2DF, 0x8EC0}, //5245 #CJK UNIFIED IDEOGRAPH + {0xC2E0, 0x8F49}, //5246 #CJK UNIFIED IDEOGRAPH + {0xC2E1, 0x8F4D}, //5247 #CJK UNIFIED IDEOGRAPH + {0xC2E2, 0x9087}, //5248 #CJK UNIFIED IDEOGRAPH + {0xC2E3, 0x9083}, //5249 #CJK UNIFIED IDEOGRAPH + {0xC2E4, 0x9088}, //5250 #CJK UNIFIED IDEOGRAPH + {0xC2E5, 0x91AB}, //5251 #CJK UNIFIED IDEOGRAPH + {0xC2E6, 0x91AC}, //5252 #CJK UNIFIED IDEOGRAPH + {0xC2E7, 0x91D0}, //5253 #CJK UNIFIED IDEOGRAPH + {0xC2E8, 0x9394}, //5254 #CJK UNIFIED IDEOGRAPH + {0xC2E9, 0x938A}, //5255 #CJK UNIFIED IDEOGRAPH + {0xC2EA, 0x9396}, //5256 #CJK UNIFIED IDEOGRAPH + {0xC2EB, 0x93A2}, //5257 #CJK UNIFIED IDEOGRAPH + {0xC2EC, 0x93B3}, //5258 #CJK UNIFIED IDEOGRAPH + {0xC2ED, 0x93AE}, //5259 #CJK UNIFIED IDEOGRAPH + {0xC2EE, 0x93AC}, //5260 #CJK UNIFIED IDEOGRAPH + {0xC2EF, 0x93B0}, //5261 #CJK UNIFIED IDEOGRAPH + {0xC2F0, 0x9398}, //5262 #CJK UNIFIED IDEOGRAPH + {0xC2F1, 0x939A}, //5263 #CJK UNIFIED IDEOGRAPH + {0xC2F2, 0x9397}, //5264 #CJK UNIFIED IDEOGRAPH + {0xC2F3, 0x95D4}, //5265 #CJK UNIFIED IDEOGRAPH + {0xC2F4, 0x95D6}, //5266 #CJK UNIFIED IDEOGRAPH + {0xC2F5, 0x95D0}, //5267 #CJK UNIFIED IDEOGRAPH + {0xC2F6, 0x95D5}, //5268 #CJK UNIFIED IDEOGRAPH + {0xC2F7, 0x96E2}, //5269 #CJK UNIFIED IDEOGRAPH + {0xC2F8, 0x96DC}, //5270 #CJK UNIFIED IDEOGRAPH + {0xC2F9, 0x96D9}, //5271 #CJK UNIFIED IDEOGRAPH + {0xC2FA, 0x96DB}, //5272 #CJK UNIFIED IDEOGRAPH + {0xC2FB, 0x96DE}, //5273 #CJK UNIFIED IDEOGRAPH + {0xC2FC, 0x9724}, //5274 #CJK UNIFIED IDEOGRAPH + {0xC2FD, 0x97A3}, //5275 #CJK UNIFIED IDEOGRAPH + {0xC2FE, 0x97A6}, //5276 #CJK UNIFIED IDEOGRAPH + {0xC340, 0x97AD}, //5277 #CJK UNIFIED IDEOGRAPH + {0xC341, 0x97F9}, //5278 #CJK UNIFIED IDEOGRAPH + {0xC342, 0x984D}, //5279 #CJK UNIFIED IDEOGRAPH + {0xC343, 0x984F}, //5280 #CJK UNIFIED IDEOGRAPH + {0xC344, 0x984C}, //5281 #CJK UNIFIED IDEOGRAPH + {0xC345, 0x984E}, //5282 #CJK UNIFIED IDEOGRAPH + {0xC346, 0x9853}, //5283 #CJK UNIFIED IDEOGRAPH + {0xC347, 0x98BA}, //5284 #CJK UNIFIED IDEOGRAPH + {0xC348, 0x993E}, //5285 #CJK UNIFIED IDEOGRAPH + {0xC349, 0x993F}, //5286 #CJK UNIFIED IDEOGRAPH + {0xC34A, 0x993D}, //5287 #CJK UNIFIED IDEOGRAPH + {0xC34B, 0x992E}, //5288 #CJK UNIFIED IDEOGRAPH + {0xC34C, 0x99A5}, //5289 #CJK UNIFIED IDEOGRAPH + {0xC34D, 0x9A0E}, //5290 #CJK UNIFIED IDEOGRAPH + {0xC34E, 0x9AC1}, //5291 #CJK UNIFIED IDEOGRAPH + {0xC34F, 0x9B03}, //5292 #CJK UNIFIED IDEOGRAPH + {0xC350, 0x9B06}, //5293 #CJK UNIFIED IDEOGRAPH + {0xC351, 0x9B4F}, //5294 #CJK UNIFIED IDEOGRAPH + {0xC352, 0x9B4E}, //5295 #CJK UNIFIED IDEOGRAPH + {0xC353, 0x9B4D}, //5296 #CJK UNIFIED IDEOGRAPH + {0xC354, 0x9BCA}, //5297 #CJK UNIFIED IDEOGRAPH + {0xC355, 0x9BC9}, //5298 #CJK UNIFIED IDEOGRAPH + {0xC356, 0x9BFD}, //5299 #CJK UNIFIED IDEOGRAPH + {0xC357, 0x9BC8}, //5300 #CJK UNIFIED IDEOGRAPH + {0xC358, 0x9BC0}, //5301 #CJK UNIFIED IDEOGRAPH + {0xC359, 0x9D51}, //5302 #CJK UNIFIED IDEOGRAPH + {0xC35A, 0x9D5D}, //5303 #CJK UNIFIED IDEOGRAPH + {0xC35B, 0x9D60}, //5304 #CJK UNIFIED IDEOGRAPH + {0xC35C, 0x9EE0}, //5305 #CJK UNIFIED IDEOGRAPH + {0xC35D, 0x9F15}, //5306 #CJK UNIFIED IDEOGRAPH + {0xC35E, 0x9F2C}, //5307 #CJK UNIFIED IDEOGRAPH + {0xC35F, 0x5133}, //5308 #CJK UNIFIED IDEOGRAPH + {0xC360, 0x56A5}, //5309 #CJK UNIFIED IDEOGRAPH + {0xC361, 0x58DE}, //5310 #CJK UNIFIED IDEOGRAPH + {0xC362, 0x58DF}, //5311 #CJK UNIFIED IDEOGRAPH + {0xC363, 0x58E2}, //5312 #CJK UNIFIED IDEOGRAPH + {0xC364, 0x5BF5}, //5313 #CJK UNIFIED IDEOGRAPH + {0xC365, 0x9F90}, //5314 #CJK UNIFIED IDEOGRAPH + {0xC366, 0x5EEC}, //5315 #CJK UNIFIED IDEOGRAPH + {0xC367, 0x61F2}, //5316 #CJK UNIFIED IDEOGRAPH + {0xC368, 0x61F7}, //5317 #CJK UNIFIED IDEOGRAPH + {0xC369, 0x61F6}, //5318 #CJK UNIFIED IDEOGRAPH + {0xC36A, 0x61F5}, //5319 #CJK UNIFIED IDEOGRAPH + {0xC36B, 0x6500}, //5320 #CJK UNIFIED IDEOGRAPH + {0xC36C, 0x650F}, //5321 #CJK UNIFIED IDEOGRAPH + {0xC36D, 0x66E0}, //5322 #CJK UNIFIED IDEOGRAPH + {0xC36E, 0x66DD}, //5323 #CJK UNIFIED IDEOGRAPH + {0xC36F, 0x6AE5}, //5324 #CJK UNIFIED IDEOGRAPH + {0xC370, 0x6ADD}, //5325 #CJK UNIFIED IDEOGRAPH + {0xC371, 0x6ADA}, //5326 #CJK UNIFIED IDEOGRAPH + {0xC372, 0x6AD3}, //5327 #CJK UNIFIED IDEOGRAPH + {0xC373, 0x701B}, //5328 #CJK UNIFIED IDEOGRAPH + {0xC374, 0x701F}, //5329 #CJK UNIFIED IDEOGRAPH + {0xC375, 0x7028}, //5330 #CJK UNIFIED IDEOGRAPH + {0xC376, 0x701A}, //5331 #CJK UNIFIED IDEOGRAPH + {0xC377, 0x701D}, //5332 #CJK UNIFIED IDEOGRAPH + {0xC378, 0x7015}, //5333 #CJK UNIFIED IDEOGRAPH + {0xC379, 0x7018}, //5334 #CJK UNIFIED IDEOGRAPH + {0xC37A, 0x7206}, //5335 #CJK UNIFIED IDEOGRAPH + {0xC37B, 0x720D}, //5336 #CJK UNIFIED IDEOGRAPH + {0xC37C, 0x7258}, //5337 #CJK UNIFIED IDEOGRAPH + {0xC37D, 0x72A2}, //5338 #CJK UNIFIED IDEOGRAPH + {0xC37E, 0x7378}, //5339 #CJK UNIFIED IDEOGRAPH + {0xC3A1, 0x737A}, //5340 #CJK UNIFIED IDEOGRAPH + {0xC3A2, 0x74BD}, //5341 #CJK UNIFIED IDEOGRAPH + {0xC3A3, 0x74CA}, //5342 #CJK UNIFIED IDEOGRAPH + {0xC3A4, 0x74E3}, //5343 #CJK UNIFIED IDEOGRAPH + {0xC3A5, 0x7587}, //5344 #CJK UNIFIED IDEOGRAPH + {0xC3A6, 0x7586}, //5345 #CJK UNIFIED IDEOGRAPH + {0xC3A7, 0x765F}, //5346 #CJK UNIFIED IDEOGRAPH + {0xC3A8, 0x7661}, //5347 #CJK UNIFIED IDEOGRAPH + {0xC3A9, 0x77C7}, //5348 #CJK UNIFIED IDEOGRAPH + {0xC3AA, 0x7919}, //5349 #CJK UNIFIED IDEOGRAPH + {0xC3AB, 0x79B1}, //5350 #CJK UNIFIED IDEOGRAPH + {0xC3AC, 0x7A6B}, //5351 #CJK UNIFIED IDEOGRAPH + {0xC3AD, 0x7A69}, //5352 #CJK UNIFIED IDEOGRAPH + {0xC3AE, 0x7C3E}, //5353 #CJK UNIFIED IDEOGRAPH + {0xC3AF, 0x7C3F}, //5354 #CJK UNIFIED IDEOGRAPH + {0xC3B0, 0x7C38}, //5355 #CJK UNIFIED IDEOGRAPH + {0xC3B1, 0x7C3D}, //5356 #CJK UNIFIED IDEOGRAPH + {0xC3B2, 0x7C37}, //5357 #CJK UNIFIED IDEOGRAPH + {0xC3B3, 0x7C40}, //5358 #CJK UNIFIED IDEOGRAPH + {0xC3B4, 0x7E6B}, //5359 #CJK UNIFIED IDEOGRAPH + {0xC3B5, 0x7E6D}, //5360 #CJK UNIFIED IDEOGRAPH + {0xC3B6, 0x7E79}, //5361 #CJK UNIFIED IDEOGRAPH + {0xC3B7, 0x7E69}, //5362 #CJK UNIFIED IDEOGRAPH + {0xC3B8, 0x7E6A}, //5363 #CJK UNIFIED IDEOGRAPH + {0xC3B9, 0x7F85}, //5364 #CJK UNIFIED IDEOGRAPH + {0xC3BA, 0x7E73}, //5365 #CJK UNIFIED IDEOGRAPH + {0xC3BB, 0x7FB6}, //5366 #CJK UNIFIED IDEOGRAPH + {0xC3BC, 0x7FB9}, //5367 #CJK UNIFIED IDEOGRAPH + {0xC3BD, 0x7FB8}, //5368 #CJK UNIFIED IDEOGRAPH + {0xC3BE, 0x81D8}, //5369 #CJK UNIFIED IDEOGRAPH + {0xC3BF, 0x85E9}, //5370 #CJK UNIFIED IDEOGRAPH + {0xC3C0, 0x85DD}, //5371 #CJK UNIFIED IDEOGRAPH + {0xC3C1, 0x85EA}, //5372 #CJK UNIFIED IDEOGRAPH + {0xC3C2, 0x85D5}, //5373 #CJK UNIFIED IDEOGRAPH + {0xC3C3, 0x85E4}, //5374 #CJK UNIFIED IDEOGRAPH + {0xC3C4, 0x85E5}, //5375 #CJK UNIFIED IDEOGRAPH + {0xC3C5, 0x85F7}, //5376 #CJK UNIFIED IDEOGRAPH + {0xC3C6, 0x87FB}, //5377 #CJK UNIFIED IDEOGRAPH + {0xC3C7, 0x8805}, //5378 #CJK UNIFIED IDEOGRAPH + {0xC3C8, 0x880D}, //5379 #CJK UNIFIED IDEOGRAPH + {0xC3C9, 0x87F9}, //5380 #CJK UNIFIED IDEOGRAPH + {0xC3CA, 0x87FE}, //5381 #CJK UNIFIED IDEOGRAPH + {0xC3CB, 0x8960}, //5382 #CJK UNIFIED IDEOGRAPH + {0xC3CC, 0x895F}, //5383 #CJK UNIFIED IDEOGRAPH + {0xC3CD, 0x8956}, //5384 #CJK UNIFIED IDEOGRAPH + {0xC3CE, 0x895E}, //5385 #CJK UNIFIED IDEOGRAPH + {0xC3CF, 0x8B41}, //5386 #CJK UNIFIED IDEOGRAPH + {0xC3D0, 0x8B5C}, //5387 #CJK UNIFIED IDEOGRAPH + {0xC3D1, 0x8B58}, //5388 #CJK UNIFIED IDEOGRAPH + {0xC3D2, 0x8B49}, //5389 #CJK UNIFIED IDEOGRAPH + {0xC3D3, 0x8B5A}, //5390 #CJK UNIFIED IDEOGRAPH + {0xC3D4, 0x8B4E}, //5391 #CJK UNIFIED IDEOGRAPH + {0xC3D5, 0x8B4F}, //5392 #CJK UNIFIED IDEOGRAPH + {0xC3D6, 0x8B46}, //5393 #CJK UNIFIED IDEOGRAPH + {0xC3D7, 0x8B59}, //5394 #CJK UNIFIED IDEOGRAPH + {0xC3D8, 0x8D08}, //5395 #CJK UNIFIED IDEOGRAPH + {0xC3D9, 0x8D0A}, //5396 #CJK UNIFIED IDEOGRAPH + {0xC3DA, 0x8E7C}, //5397 #CJK UNIFIED IDEOGRAPH + {0xC3DB, 0x8E72}, //5398 #CJK UNIFIED IDEOGRAPH + {0xC3DC, 0x8E87}, //5399 #CJK UNIFIED IDEOGRAPH + {0xC3DD, 0x8E76}, //5400 #CJK UNIFIED IDEOGRAPH + {0xC3DE, 0x8E6C}, //5401 #CJK UNIFIED IDEOGRAPH + {0xC3DF, 0x8E7A}, //5402 #CJK UNIFIED IDEOGRAPH + {0xC3E0, 0x8E74}, //5403 #CJK UNIFIED IDEOGRAPH + {0xC3E1, 0x8F54}, //5404 #CJK UNIFIED IDEOGRAPH + {0xC3E2, 0x8F4E}, //5405 #CJK UNIFIED IDEOGRAPH + {0xC3E3, 0x8FAD}, //5406 #CJK UNIFIED IDEOGRAPH + {0xC3E4, 0x908A}, //5407 #CJK UNIFIED IDEOGRAPH + {0xC3E5, 0x908B}, //5408 #CJK UNIFIED IDEOGRAPH + {0xC3E6, 0x91B1}, //5409 #CJK UNIFIED IDEOGRAPH + {0xC3E7, 0x91AE}, //5410 #CJK UNIFIED IDEOGRAPH + {0xC3E8, 0x93E1}, //5411 #CJK UNIFIED IDEOGRAPH + {0xC3E9, 0x93D1}, //5412 #CJK UNIFIED IDEOGRAPH + {0xC3EA, 0x93DF}, //5413 #CJK UNIFIED IDEOGRAPH + {0xC3EB, 0x93C3}, //5414 #CJK UNIFIED IDEOGRAPH + {0xC3EC, 0x93C8}, //5415 #CJK UNIFIED IDEOGRAPH + {0xC3ED, 0x93DC}, //5416 #CJK UNIFIED IDEOGRAPH + {0xC3EE, 0x93DD}, //5417 #CJK UNIFIED IDEOGRAPH + {0xC3EF, 0x93D6}, //5418 #CJK UNIFIED IDEOGRAPH + {0xC3F0, 0x93E2}, //5419 #CJK UNIFIED IDEOGRAPH + {0xC3F1, 0x93CD}, //5420 #CJK UNIFIED IDEOGRAPH + {0xC3F2, 0x93D8}, //5421 #CJK UNIFIED IDEOGRAPH + {0xC3F3, 0x93E4}, //5422 #CJK UNIFIED IDEOGRAPH + {0xC3F4, 0x93D7}, //5423 #CJK UNIFIED IDEOGRAPH + {0xC3F5, 0x93E8}, //5424 #CJK UNIFIED IDEOGRAPH + {0xC3F6, 0x95DC}, //5425 #CJK UNIFIED IDEOGRAPH + {0xC3F7, 0x96B4}, //5426 #CJK UNIFIED IDEOGRAPH + {0xC3F8, 0x96E3}, //5427 #CJK UNIFIED IDEOGRAPH + {0xC3F9, 0x972A}, //5428 #CJK UNIFIED IDEOGRAPH + {0xC3FA, 0x9727}, //5429 #CJK UNIFIED IDEOGRAPH + {0xC3FB, 0x9761}, //5430 #CJK UNIFIED IDEOGRAPH + {0xC3FC, 0x97DC}, //5431 #CJK UNIFIED IDEOGRAPH + {0xC3FD, 0x97FB}, //5432 #CJK UNIFIED IDEOGRAPH + {0xC3FE, 0x985E}, //5433 #CJK UNIFIED IDEOGRAPH + {0xC440, 0x9858}, //5434 #CJK UNIFIED IDEOGRAPH + {0xC441, 0x985B}, //5435 #CJK UNIFIED IDEOGRAPH + {0xC442, 0x98BC}, //5436 #CJK UNIFIED IDEOGRAPH + {0xC443, 0x9945}, //5437 #CJK UNIFIED IDEOGRAPH + {0xC444, 0x9949}, //5438 #CJK UNIFIED IDEOGRAPH + {0xC445, 0x9A16}, //5439 #CJK UNIFIED IDEOGRAPH + {0xC446, 0x9A19}, //5440 #CJK UNIFIED IDEOGRAPH + {0xC447, 0x9B0D}, //5441 #CJK UNIFIED IDEOGRAPH + {0xC448, 0x9BE8}, //5442 #CJK UNIFIED IDEOGRAPH + {0xC449, 0x9BE7}, //5443 #CJK UNIFIED IDEOGRAPH + {0xC44A, 0x9BD6}, //5444 #CJK UNIFIED IDEOGRAPH + {0xC44B, 0x9BDB}, //5445 #CJK UNIFIED IDEOGRAPH + {0xC44C, 0x9D89}, //5446 #CJK UNIFIED IDEOGRAPH + {0xC44D, 0x9D61}, //5447 #CJK UNIFIED IDEOGRAPH + {0xC44E, 0x9D72}, //5448 #CJK UNIFIED IDEOGRAPH + {0xC44F, 0x9D6A}, //5449 #CJK UNIFIED IDEOGRAPH + {0xC450, 0x9D6C}, //5450 #CJK UNIFIED IDEOGRAPH + {0xC451, 0x9E92}, //5451 #CJK UNIFIED IDEOGRAPH + {0xC452, 0x9E97}, //5452 #CJK UNIFIED IDEOGRAPH + {0xC453, 0x9E93}, //5453 #CJK UNIFIED IDEOGRAPH + {0xC454, 0x9EB4}, //5454 #CJK UNIFIED IDEOGRAPH + {0xC455, 0x52F8}, //5455 #CJK UNIFIED IDEOGRAPH + {0xC456, 0x56A8}, //5456 #CJK UNIFIED IDEOGRAPH + {0xC457, 0x56B7}, //5457 #CJK UNIFIED IDEOGRAPH + {0xC458, 0x56B6}, //5458 #CJK UNIFIED IDEOGRAPH + {0xC459, 0x56B4}, //5459 #CJK UNIFIED IDEOGRAPH + {0xC45A, 0x56BC}, //5460 #CJK UNIFIED IDEOGRAPH + {0xC45B, 0x58E4}, //5461 #CJK UNIFIED IDEOGRAPH + {0xC45C, 0x5B40}, //5462 #CJK UNIFIED IDEOGRAPH + {0xC45D, 0x5B43}, //5463 #CJK UNIFIED IDEOGRAPH + {0xC45E, 0x5B7D}, //5464 #CJK UNIFIED IDEOGRAPH + {0xC45F, 0x5BF6}, //5465 #CJK UNIFIED IDEOGRAPH + {0xC460, 0x5DC9}, //5466 #CJK UNIFIED IDEOGRAPH + {0xC461, 0x61F8}, //5467 #CJK UNIFIED IDEOGRAPH + {0xC462, 0x61FA}, //5468 #CJK UNIFIED IDEOGRAPH + {0xC463, 0x6518}, //5469 #CJK UNIFIED IDEOGRAPH + {0xC464, 0x6514}, //5470 #CJK UNIFIED IDEOGRAPH + {0xC465, 0x6519}, //5471 #CJK UNIFIED IDEOGRAPH + {0xC466, 0x66E6}, //5472 #CJK UNIFIED IDEOGRAPH + {0xC467, 0x6727}, //5473 #CJK UNIFIED IDEOGRAPH + {0xC468, 0x6AEC}, //5474 #CJK UNIFIED IDEOGRAPH + {0xC469, 0x703E}, //5475 #CJK UNIFIED IDEOGRAPH + {0xC46A, 0x7030}, //5476 #CJK UNIFIED IDEOGRAPH + {0xC46B, 0x7032}, //5477 #CJK UNIFIED IDEOGRAPH + {0xC46C, 0x7210}, //5478 #CJK UNIFIED IDEOGRAPH + {0xC46D, 0x737B}, //5479 #CJK UNIFIED IDEOGRAPH + {0xC46E, 0x74CF}, //5480 #CJK UNIFIED IDEOGRAPH + {0xC46F, 0x7662}, //5481 #CJK UNIFIED IDEOGRAPH + {0xC470, 0x7665}, //5482 #CJK UNIFIED IDEOGRAPH + {0xC471, 0x7926}, //5483 #CJK UNIFIED IDEOGRAPH + {0xC472, 0x792A}, //5484 #CJK UNIFIED IDEOGRAPH + {0xC473, 0x792C}, //5485 #CJK UNIFIED IDEOGRAPH + {0xC474, 0x792B}, //5486 #CJK UNIFIED IDEOGRAPH + {0xC475, 0x7AC7}, //5487 #CJK UNIFIED IDEOGRAPH + {0xC476, 0x7AF6}, //5488 #CJK UNIFIED IDEOGRAPH + {0xC477, 0x7C4C}, //5489 #CJK UNIFIED IDEOGRAPH + {0xC478, 0x7C43}, //5490 #CJK UNIFIED IDEOGRAPH + {0xC479, 0x7C4D}, //5491 #CJK UNIFIED IDEOGRAPH + {0xC47A, 0x7CEF}, //5492 #CJK UNIFIED IDEOGRAPH + {0xC47B, 0x7CF0}, //5493 #CJK UNIFIED IDEOGRAPH + {0xC47C, 0x8FAE}, //5494 #CJK UNIFIED IDEOGRAPH + {0xC47D, 0x7E7D}, //5495 #CJK UNIFIED IDEOGRAPH + {0xC47E, 0x7E7C}, //5496 #CJK UNIFIED IDEOGRAPH + {0xC4A1, 0x7E82}, //5497 #CJK UNIFIED IDEOGRAPH + {0xC4A2, 0x7F4C}, //5498 #CJK UNIFIED IDEOGRAPH + {0xC4A3, 0x8000}, //5499 #CJK UNIFIED IDEOGRAPH + {0xC4A4, 0x81DA}, //5500 #CJK UNIFIED IDEOGRAPH + {0xC4A5, 0x8266}, //5501 #CJK UNIFIED IDEOGRAPH + {0xC4A6, 0x85FB}, //5502 #CJK UNIFIED IDEOGRAPH + {0xC4A7, 0x85F9}, //5503 #CJK UNIFIED IDEOGRAPH + {0xC4A8, 0x8611}, //5504 #CJK UNIFIED IDEOGRAPH + {0xC4A9, 0x85FA}, //5505 #CJK UNIFIED IDEOGRAPH + {0xC4AA, 0x8606}, //5506 #CJK UNIFIED IDEOGRAPH + {0xC4AB, 0x860B}, //5507 #CJK UNIFIED IDEOGRAPH + {0xC4AC, 0x8607}, //5508 #CJK UNIFIED IDEOGRAPH + {0xC4AD, 0x860A}, //5509 #CJK UNIFIED IDEOGRAPH + {0xC4AE, 0x8814}, //5510 #CJK UNIFIED IDEOGRAPH + {0xC4AF, 0x8815}, //5511 #CJK UNIFIED IDEOGRAPH + {0xC4B0, 0x8964}, //5512 #CJK UNIFIED IDEOGRAPH + {0xC4B1, 0x89BA}, //5513 #CJK UNIFIED IDEOGRAPH + {0xC4B2, 0x89F8}, //5514 #CJK UNIFIED IDEOGRAPH + {0xC4B3, 0x8B70}, //5515 #CJK UNIFIED IDEOGRAPH + {0xC4B4, 0x8B6C}, //5516 #CJK UNIFIED IDEOGRAPH + {0xC4B5, 0x8B66}, //5517 #CJK UNIFIED IDEOGRAPH + {0xC4B6, 0x8B6F}, //5518 #CJK UNIFIED IDEOGRAPH + {0xC4B7, 0x8B5F}, //5519 #CJK UNIFIED IDEOGRAPH + {0xC4B8, 0x8B6B}, //5520 #CJK UNIFIED IDEOGRAPH + {0xC4B9, 0x8D0F}, //5521 #CJK UNIFIED IDEOGRAPH + {0xC4BA, 0x8D0D}, //5522 #CJK UNIFIED IDEOGRAPH + {0xC4BB, 0x8E89}, //5523 #CJK UNIFIED IDEOGRAPH + {0xC4BC, 0x8E81}, //5524 #CJK UNIFIED IDEOGRAPH + {0xC4BD, 0x8E85}, //5525 #CJK UNIFIED IDEOGRAPH + {0xC4BE, 0x8E82}, //5526 #CJK UNIFIED IDEOGRAPH + {0xC4BF, 0x91B4}, //5527 #CJK UNIFIED IDEOGRAPH + {0xC4C0, 0x91CB}, //5528 #CJK UNIFIED IDEOGRAPH + {0xC4C1, 0x9418}, //5529 #CJK UNIFIED IDEOGRAPH + {0xC4C2, 0x9403}, //5530 #CJK UNIFIED IDEOGRAPH + {0xC4C3, 0x93FD}, //5531 #CJK UNIFIED IDEOGRAPH + {0xC4C4, 0x95E1}, //5532 #CJK UNIFIED IDEOGRAPH + {0xC4C5, 0x9730}, //5533 #CJK UNIFIED IDEOGRAPH + {0xC4C6, 0x98C4}, //5534 #CJK UNIFIED IDEOGRAPH + {0xC4C7, 0x9952}, //5535 #CJK UNIFIED IDEOGRAPH + {0xC4C8, 0x9951}, //5536 #CJK UNIFIED IDEOGRAPH + {0xC4C9, 0x99A8}, //5537 #CJK UNIFIED IDEOGRAPH + {0xC4CA, 0x9A2B}, //5538 #CJK UNIFIED IDEOGRAPH + {0xC4CB, 0x9A30}, //5539 #CJK UNIFIED IDEOGRAPH + {0xC4CC, 0x9A37}, //5540 #CJK UNIFIED IDEOGRAPH + {0xC4CD, 0x9A35}, //5541 #CJK UNIFIED IDEOGRAPH + {0xC4CE, 0x9C13}, //5542 #CJK UNIFIED IDEOGRAPH + {0xC4CF, 0x9C0D}, //5543 #CJK UNIFIED IDEOGRAPH + {0xC4D0, 0x9E79}, //5544 #CJK UNIFIED IDEOGRAPH + {0xC4D1, 0x9EB5}, //5545 #CJK UNIFIED IDEOGRAPH + {0xC4D2, 0x9EE8}, //5546 #CJK UNIFIED IDEOGRAPH + {0xC4D3, 0x9F2F}, //5547 #CJK UNIFIED IDEOGRAPH + {0xC4D4, 0x9F5F}, //5548 #CJK UNIFIED IDEOGRAPH + {0xC4D5, 0x9F63}, //5549 #CJK UNIFIED IDEOGRAPH + {0xC4D6, 0x9F61}, //5550 #CJK UNIFIED IDEOGRAPH + {0xC4D7, 0x5137}, //5551 #CJK UNIFIED IDEOGRAPH + {0xC4D8, 0x5138}, //5552 #CJK UNIFIED IDEOGRAPH + {0xC4D9, 0x56C1}, //5553 #CJK UNIFIED IDEOGRAPH + {0xC4DA, 0x56C0}, //5554 #CJK UNIFIED IDEOGRAPH + {0xC4DB, 0x56C2}, //5555 #CJK UNIFIED IDEOGRAPH + {0xC4DC, 0x5914}, //5556 #CJK UNIFIED IDEOGRAPH + {0xC4DD, 0x5C6C}, //5557 #CJK UNIFIED IDEOGRAPH + {0xC4DE, 0x5DCD}, //5558 #CJK UNIFIED IDEOGRAPH + {0xC4DF, 0x61FC}, //5559 #CJK UNIFIED IDEOGRAPH + {0xC4E0, 0x61FE}, //5560 #CJK UNIFIED IDEOGRAPH + {0xC4E1, 0x651D}, //5561 #CJK UNIFIED IDEOGRAPH + {0xC4E2, 0x651C}, //5562 #CJK UNIFIED IDEOGRAPH + {0xC4E3, 0x6595}, //5563 #CJK UNIFIED IDEOGRAPH + {0xC4E4, 0x66E9}, //5564 #CJK UNIFIED IDEOGRAPH + {0xC4E5, 0x6AFB}, //5565 #CJK UNIFIED IDEOGRAPH + {0xC4E6, 0x6B04}, //5566 #CJK UNIFIED IDEOGRAPH + {0xC4E7, 0x6AFA}, //5567 #CJK UNIFIED IDEOGRAPH + {0xC4E8, 0x6BB2}, //5568 #CJK UNIFIED IDEOGRAPH + {0xC4E9, 0x704C}, //5569 #CJK UNIFIED IDEOGRAPH + {0xC4EA, 0x721B}, //5570 #CJK UNIFIED IDEOGRAPH + {0xC4EB, 0x72A7}, //5571 #CJK UNIFIED IDEOGRAPH + {0xC4EC, 0x74D6}, //5572 #CJK UNIFIED IDEOGRAPH + {0xC4ED, 0x74D4}, //5573 #CJK UNIFIED IDEOGRAPH + {0xC4EE, 0x7669}, //5574 #CJK UNIFIED IDEOGRAPH + {0xC4EF, 0x77D3}, //5575 #CJK UNIFIED IDEOGRAPH + {0xC4F0, 0x7C50}, //5576 #CJK UNIFIED IDEOGRAPH + {0xC4F1, 0x7E8F}, //5577 #CJK UNIFIED IDEOGRAPH + {0xC4F2, 0x7E8C}, //5578 #CJK UNIFIED IDEOGRAPH + {0xC4F3, 0x7FBC}, //5579 #CJK UNIFIED IDEOGRAPH + {0xC4F4, 0x8617}, //5580 #CJK UNIFIED IDEOGRAPH + {0xC4F5, 0x862D}, //5581 #CJK UNIFIED IDEOGRAPH + {0xC4F6, 0x861A}, //5582 #CJK UNIFIED IDEOGRAPH + {0xC4F7, 0x8823}, //5583 #CJK UNIFIED IDEOGRAPH + {0xC4F8, 0x8822}, //5584 #CJK UNIFIED IDEOGRAPH + {0xC4F9, 0x8821}, //5585 #CJK UNIFIED IDEOGRAPH + {0xC4FA, 0x881F}, //5586 #CJK UNIFIED IDEOGRAPH + {0xC4FB, 0x896A}, //5587 #CJK UNIFIED IDEOGRAPH + {0xC4FC, 0x896C}, //5588 #CJK UNIFIED IDEOGRAPH + {0xC4FD, 0x89BD}, //5589 #CJK UNIFIED IDEOGRAPH + {0xC4FE, 0x8B74}, //5590 #CJK UNIFIED IDEOGRAPH + {0xC540, 0x8B77}, //5591 #CJK UNIFIED IDEOGRAPH + {0xC541, 0x8B7D}, //5592 #CJK UNIFIED IDEOGRAPH + {0xC542, 0x8D13}, //5593 #CJK UNIFIED IDEOGRAPH + {0xC543, 0x8E8A}, //5594 #CJK UNIFIED IDEOGRAPH + {0xC544, 0x8E8D}, //5595 #CJK UNIFIED IDEOGRAPH + {0xC545, 0x8E8B}, //5596 #CJK UNIFIED IDEOGRAPH + {0xC546, 0x8F5F}, //5597 #CJK UNIFIED IDEOGRAPH + {0xC547, 0x8FAF}, //5598 #CJK UNIFIED IDEOGRAPH + {0xC548, 0x91BA}, //5599 #CJK UNIFIED IDEOGRAPH + {0xC549, 0x942E}, //5600 #CJK UNIFIED IDEOGRAPH + {0xC54A, 0x9433}, //5601 #CJK UNIFIED IDEOGRAPH + {0xC54B, 0x9435}, //5602 #CJK UNIFIED IDEOGRAPH + {0xC54C, 0x943A}, //5603 #CJK UNIFIED IDEOGRAPH + {0xC54D, 0x9438}, //5604 #CJK UNIFIED IDEOGRAPH + {0xC54E, 0x9432}, //5605 #CJK UNIFIED IDEOGRAPH + {0xC54F, 0x942B}, //5606 #CJK UNIFIED IDEOGRAPH + {0xC550, 0x95E2}, //5607 #CJK UNIFIED IDEOGRAPH + {0xC551, 0x9738}, //5608 #CJK UNIFIED IDEOGRAPH + {0xC552, 0x9739}, //5609 #CJK UNIFIED IDEOGRAPH + {0xC553, 0x9732}, //5610 #CJK UNIFIED IDEOGRAPH + {0xC554, 0x97FF}, //5611 #CJK UNIFIED IDEOGRAPH + {0xC555, 0x9867}, //5612 #CJK UNIFIED IDEOGRAPH + {0xC556, 0x9865}, //5613 #CJK UNIFIED IDEOGRAPH + {0xC557, 0x9957}, //5614 #CJK UNIFIED IDEOGRAPH + {0xC558, 0x9A45}, //5615 #CJK UNIFIED IDEOGRAPH + {0xC559, 0x9A43}, //5616 #CJK UNIFIED IDEOGRAPH + {0xC55A, 0x9A40}, //5617 #CJK UNIFIED IDEOGRAPH + {0xC55B, 0x9A3E}, //5618 #CJK UNIFIED IDEOGRAPH + {0xC55C, 0x9ACF}, //5619 #CJK UNIFIED IDEOGRAPH + {0xC55D, 0x9B54}, //5620 #CJK UNIFIED IDEOGRAPH + {0xC55E, 0x9B51}, //5621 #CJK UNIFIED IDEOGRAPH + {0xC55F, 0x9C2D}, //5622 #CJK UNIFIED IDEOGRAPH + {0xC560, 0x9C25}, //5623 #CJK UNIFIED IDEOGRAPH + {0xC561, 0x9DAF}, //5624 #CJK UNIFIED IDEOGRAPH + {0xC562, 0x9DB4}, //5625 #CJK UNIFIED IDEOGRAPH + {0xC563, 0x9DC2}, //5626 #CJK UNIFIED IDEOGRAPH + {0xC564, 0x9DB8}, //5627 #CJK UNIFIED IDEOGRAPH + {0xC565, 0x9E9D}, //5628 #CJK UNIFIED IDEOGRAPH + {0xC566, 0x9EEF}, //5629 #CJK UNIFIED IDEOGRAPH + {0xC567, 0x9F19}, //5630 #CJK UNIFIED IDEOGRAPH + {0xC568, 0x9F5C}, //5631 #CJK UNIFIED IDEOGRAPH + {0xC569, 0x9F66}, //5632 #CJK UNIFIED IDEOGRAPH + {0xC56A, 0x9F67}, //5633 #CJK UNIFIED IDEOGRAPH + {0xC56B, 0x513C}, //5634 #CJK UNIFIED IDEOGRAPH + {0xC56C, 0x513B}, //5635 #CJK UNIFIED IDEOGRAPH + {0xC56D, 0x56C8}, //5636 #CJK UNIFIED IDEOGRAPH + {0xC56E, 0x56CA}, //5637 #CJK UNIFIED IDEOGRAPH + {0xC56F, 0x56C9}, //5638 #CJK UNIFIED IDEOGRAPH + {0xC570, 0x5B7F}, //5639 #CJK UNIFIED IDEOGRAPH + {0xC571, 0x5DD4}, //5640 #CJK UNIFIED IDEOGRAPH + {0xC572, 0x5DD2}, //5641 #CJK UNIFIED IDEOGRAPH + {0xC573, 0x5F4E}, //5642 #CJK UNIFIED IDEOGRAPH + {0xC574, 0x61FF}, //5643 #CJK UNIFIED IDEOGRAPH + {0xC575, 0x6524}, //5644 #CJK UNIFIED IDEOGRAPH + {0xC576, 0x6B0A}, //5645 #CJK UNIFIED IDEOGRAPH + {0xC577, 0x6B61}, //5646 #CJK UNIFIED IDEOGRAPH + {0xC578, 0x7051}, //5647 #CJK UNIFIED IDEOGRAPH + {0xC579, 0x7058}, //5648 #CJK UNIFIED IDEOGRAPH + {0xC57A, 0x7380}, //5649 #CJK UNIFIED IDEOGRAPH + {0xC57B, 0x74E4}, //5650 #CJK UNIFIED IDEOGRAPH + {0xC57C, 0x758A}, //5651 #CJK UNIFIED IDEOGRAPH + {0xC57D, 0x766E}, //5652 #CJK UNIFIED IDEOGRAPH + {0xC57E, 0x766C}, //5653 #CJK UNIFIED IDEOGRAPH + {0xC5A1, 0x79B3}, //5654 #CJK UNIFIED IDEOGRAPH + {0xC5A2, 0x7C60}, //5655 #CJK UNIFIED IDEOGRAPH + {0xC5A3, 0x7C5F}, //5656 #CJK UNIFIED IDEOGRAPH + {0xC5A4, 0x807E}, //5657 #CJK UNIFIED IDEOGRAPH + {0xC5A5, 0x807D}, //5658 #CJK UNIFIED IDEOGRAPH + {0xC5A6, 0x81DF}, //5659 #CJK UNIFIED IDEOGRAPH + {0xC5A7, 0x8972}, //5660 #CJK UNIFIED IDEOGRAPH + {0xC5A8, 0x896F}, //5661 #CJK UNIFIED IDEOGRAPH + {0xC5A9, 0x89FC}, //5662 #CJK UNIFIED IDEOGRAPH + {0xC5AA, 0x8B80}, //5663 #CJK UNIFIED IDEOGRAPH + {0xC5AB, 0x8D16}, //5664 #CJK UNIFIED IDEOGRAPH + {0xC5AC, 0x8D17}, //5665 #CJK UNIFIED IDEOGRAPH + {0xC5AD, 0x8E91}, //5666 #CJK UNIFIED IDEOGRAPH + {0xC5AE, 0x8E93}, //5667 #CJK UNIFIED IDEOGRAPH + {0xC5AF, 0x8F61}, //5668 #CJK UNIFIED IDEOGRAPH + {0xC5B0, 0x9148}, //5669 #CJK UNIFIED IDEOGRAPH + {0xC5B1, 0x9444}, //5670 #CJK UNIFIED IDEOGRAPH + {0xC5B2, 0x9451}, //5671 #CJK UNIFIED IDEOGRAPH + {0xC5B3, 0x9452}, //5672 #CJK UNIFIED IDEOGRAPH + {0xC5B4, 0x973D}, //5673 #CJK UNIFIED IDEOGRAPH + {0xC5B5, 0x973E}, //5674 #CJK UNIFIED IDEOGRAPH + {0xC5B6, 0x97C3}, //5675 #CJK UNIFIED IDEOGRAPH + {0xC5B7, 0x97C1}, //5676 #CJK UNIFIED IDEOGRAPH + {0xC5B8, 0x986B}, //5677 #CJK UNIFIED IDEOGRAPH + {0xC5B9, 0x9955}, //5678 #CJK UNIFIED IDEOGRAPH + {0xC5BA, 0x9A55}, //5679 #CJK UNIFIED IDEOGRAPH + {0xC5BB, 0x9A4D}, //5680 #CJK UNIFIED IDEOGRAPH + {0xC5BC, 0x9AD2}, //5681 #CJK UNIFIED IDEOGRAPH + {0xC5BD, 0x9B1A}, //5682 #CJK UNIFIED IDEOGRAPH + {0xC5BE, 0x9C49}, //5683 #CJK UNIFIED IDEOGRAPH + {0xC5BF, 0x9C31}, //5684 #CJK UNIFIED IDEOGRAPH + {0xC5C0, 0x9C3E}, //5685 #CJK UNIFIED IDEOGRAPH + {0xC5C1, 0x9C3B}, //5686 #CJK UNIFIED IDEOGRAPH + {0xC5C2, 0x9DD3}, //5687 #CJK UNIFIED IDEOGRAPH + {0xC5C3, 0x9DD7}, //5688 #CJK UNIFIED IDEOGRAPH + {0xC5C4, 0x9F34}, //5689 #CJK UNIFIED IDEOGRAPH + {0xC5C5, 0x9F6C}, //5690 #CJK UNIFIED IDEOGRAPH + {0xC5C6, 0x9F6A}, //5691 #CJK UNIFIED IDEOGRAPH + {0xC5C7, 0x9F94}, //5692 #CJK UNIFIED IDEOGRAPH + {0xC5C8, 0x56CC}, //5693 #CJK UNIFIED IDEOGRAPH + {0xC5C9, 0x5DD6}, //5694 #CJK UNIFIED IDEOGRAPH + {0xC5CA, 0x6200}, //5695 #CJK UNIFIED IDEOGRAPH + {0xC5CB, 0x6523}, //5696 #CJK UNIFIED IDEOGRAPH + {0xC5CC, 0x652B}, //5697 #CJK UNIFIED IDEOGRAPH + {0xC5CD, 0x652A}, //5698 #CJK UNIFIED IDEOGRAPH + {0xC5CE, 0x66EC}, //5699 #CJK UNIFIED IDEOGRAPH + {0xC5CF, 0x6B10}, //5700 #CJK UNIFIED IDEOGRAPH + {0xC5D0, 0x74DA}, //5701 #CJK UNIFIED IDEOGRAPH + {0xC5D1, 0x7ACA}, //5702 #CJK UNIFIED IDEOGRAPH + {0xC5D2, 0x7C64}, //5703 #CJK UNIFIED IDEOGRAPH + {0xC5D3, 0x7C63}, //5704 #CJK UNIFIED IDEOGRAPH + {0xC5D4, 0x7C65}, //5705 #CJK UNIFIED IDEOGRAPH + {0xC5D5, 0x7E93}, //5706 #CJK UNIFIED IDEOGRAPH + {0xC5D6, 0x7E96}, //5707 #CJK UNIFIED IDEOGRAPH + {0xC5D7, 0x7E94}, //5708 #CJK UNIFIED IDEOGRAPH + {0xC5D8, 0x81E2}, //5709 #CJK UNIFIED IDEOGRAPH + {0xC5D9, 0x8638}, //5710 #CJK UNIFIED IDEOGRAPH + {0xC5DA, 0x863F}, //5711 #CJK UNIFIED IDEOGRAPH + {0xC5DB, 0x8831}, //5712 #CJK UNIFIED IDEOGRAPH + {0xC5DC, 0x8B8A}, //5713 #CJK UNIFIED IDEOGRAPH + {0xC5DD, 0x9090}, //5714 #CJK UNIFIED IDEOGRAPH + {0xC5DE, 0x908F}, //5715 #CJK UNIFIED IDEOGRAPH + {0xC5DF, 0x9463}, //5716 #CJK UNIFIED IDEOGRAPH + {0xC5E0, 0x9460}, //5717 #CJK UNIFIED IDEOGRAPH + {0xC5E1, 0x9464}, //5718 #CJK UNIFIED IDEOGRAPH + {0xC5E2, 0x9768}, //5719 #CJK UNIFIED IDEOGRAPH + {0xC5E3, 0x986F}, //5720 #CJK UNIFIED IDEOGRAPH + {0xC5E4, 0x995C}, //5721 #CJK UNIFIED IDEOGRAPH + {0xC5E5, 0x9A5A}, //5722 #CJK UNIFIED IDEOGRAPH + {0xC5E6, 0x9A5B}, //5723 #CJK UNIFIED IDEOGRAPH + {0xC5E7, 0x9A57}, //5724 #CJK UNIFIED IDEOGRAPH + {0xC5E8, 0x9AD3}, //5725 #CJK UNIFIED IDEOGRAPH + {0xC5E9, 0x9AD4}, //5726 #CJK UNIFIED IDEOGRAPH + {0xC5EA, 0x9AD1}, //5727 #CJK UNIFIED IDEOGRAPH + {0xC5EB, 0x9C54}, //5728 #CJK UNIFIED IDEOGRAPH + {0xC5EC, 0x9C57}, //5729 #CJK UNIFIED IDEOGRAPH + {0xC5ED, 0x9C56}, //5730 #CJK UNIFIED IDEOGRAPH + {0xC5EE, 0x9DE5}, //5731 #CJK UNIFIED IDEOGRAPH + {0xC5EF, 0x9E9F}, //5732 #CJK UNIFIED IDEOGRAPH + {0xC5F0, 0x9EF4}, //5733 #CJK UNIFIED IDEOGRAPH + {0xC5F1, 0x56D1}, //5734 #CJK UNIFIED IDEOGRAPH + {0xC5F2, 0x58E9}, //5735 #CJK UNIFIED IDEOGRAPH + {0xC5F3, 0x652C}, //5736 #CJK UNIFIED IDEOGRAPH + {0xC5F4, 0x705E}, //5737 #CJK UNIFIED IDEOGRAPH + {0xC5F5, 0x7671}, //5738 #CJK UNIFIED IDEOGRAPH + {0xC5F6, 0x7672}, //5739 #CJK UNIFIED IDEOGRAPH + {0xC5F7, 0x77D7}, //5740 #CJK UNIFIED IDEOGRAPH + {0xC5F8, 0x7F50}, //5741 #CJK UNIFIED IDEOGRAPH + {0xC5F9, 0x7F88}, //5742 #CJK UNIFIED IDEOGRAPH + {0xC5FA, 0x8836}, //5743 #CJK UNIFIED IDEOGRAPH + {0xC5FB, 0x8839}, //5744 #CJK UNIFIED IDEOGRAPH + {0xC5FC, 0x8862}, //5745 #CJK UNIFIED IDEOGRAPH + {0xC5FD, 0x8B93}, //5746 #CJK UNIFIED IDEOGRAPH + {0xC5FE, 0x8B92}, //5747 #CJK UNIFIED IDEOGRAPH + {0xC640, 0x8B96}, //5748 #CJK UNIFIED IDEOGRAPH + {0xC641, 0x8277}, //5749 #CJK UNIFIED IDEOGRAPH + {0xC642, 0x8D1B}, //5750 #CJK UNIFIED IDEOGRAPH + {0xC643, 0x91C0}, //5751 #CJK UNIFIED IDEOGRAPH + {0xC644, 0x946A}, //5752 #CJK UNIFIED IDEOGRAPH + {0xC645, 0x9742}, //5753 #CJK UNIFIED IDEOGRAPH + {0xC646, 0x9748}, //5754 #CJK UNIFIED IDEOGRAPH + {0xC647, 0x9744}, //5755 #CJK UNIFIED IDEOGRAPH + {0xC648, 0x97C6}, //5756 #CJK UNIFIED IDEOGRAPH + {0xC649, 0x9870}, //5757 #CJK UNIFIED IDEOGRAPH + {0xC64A, 0x9A5F}, //5758 #CJK UNIFIED IDEOGRAPH + {0xC64B, 0x9B22}, //5759 #CJK UNIFIED IDEOGRAPH + {0xC64C, 0x9B58}, //5760 #CJK UNIFIED IDEOGRAPH + {0xC64D, 0x9C5F}, //5761 #CJK UNIFIED IDEOGRAPH + {0xC64E, 0x9DF9}, //5762 #CJK UNIFIED IDEOGRAPH + {0xC64F, 0x9DFA}, //5763 #CJK UNIFIED IDEOGRAPH + {0xC650, 0x9E7C}, //5764 #CJK UNIFIED IDEOGRAPH + {0xC651, 0x9E7D}, //5765 #CJK UNIFIED IDEOGRAPH + {0xC652, 0x9F07}, //5766 #CJK UNIFIED IDEOGRAPH + {0xC653, 0x9F77}, //5767 #CJK UNIFIED IDEOGRAPH + {0xC654, 0x9F72}, //5768 #CJK UNIFIED IDEOGRAPH + {0xC655, 0x5EF3}, //5769 #CJK UNIFIED IDEOGRAPH + {0xC656, 0x6B16}, //5770 #CJK UNIFIED IDEOGRAPH + {0xC657, 0x7063}, //5771 #CJK UNIFIED IDEOGRAPH + {0xC658, 0x7C6C}, //5772 #CJK UNIFIED IDEOGRAPH + {0xC659, 0x7C6E}, //5773 #CJK UNIFIED IDEOGRAPH + {0xC65A, 0x883B}, //5774 #CJK UNIFIED IDEOGRAPH + {0xC65B, 0x89C0}, //5775 #CJK UNIFIED IDEOGRAPH + {0xC65C, 0x8EA1}, //5776 #CJK UNIFIED IDEOGRAPH + {0xC65D, 0x91C1}, //5777 #CJK UNIFIED IDEOGRAPH + {0xC65E, 0x9472}, //5778 #CJK UNIFIED IDEOGRAPH + {0xC65F, 0x9470}, //5779 #CJK UNIFIED IDEOGRAPH + {0xC660, 0x9871}, //5780 #CJK UNIFIED IDEOGRAPH + {0xC661, 0x995E}, //5781 #CJK UNIFIED IDEOGRAPH + {0xC662, 0x9AD6}, //5782 #CJK UNIFIED IDEOGRAPH + {0xC663, 0x9B23}, //5783 #CJK UNIFIED IDEOGRAPH + {0xC664, 0x9ECC}, //5784 #CJK UNIFIED IDEOGRAPH + {0xC665, 0x7064}, //5785 #CJK UNIFIED IDEOGRAPH + {0xC666, 0x77DA}, //5786 #CJK UNIFIED IDEOGRAPH + {0xC667, 0x8B9A}, //5787 #CJK UNIFIED IDEOGRAPH + {0xC668, 0x9477}, //5788 #CJK UNIFIED IDEOGRAPH + {0xC669, 0x97C9}, //5789 #CJK UNIFIED IDEOGRAPH + {0xC66A, 0x9A62}, //5790 #CJK UNIFIED IDEOGRAPH + {0xC66B, 0x9A65}, //5791 #CJK UNIFIED IDEOGRAPH + {0xC66C, 0x7E9C}, //5792 #CJK UNIFIED IDEOGRAPH + {0xC66D, 0x8B9C}, //5793 #CJK UNIFIED IDEOGRAPH + {0xC66E, 0x8EAA}, //5794 #CJK UNIFIED IDEOGRAPH + {0xC66F, 0x91C5}, //5795 #CJK UNIFIED IDEOGRAPH + {0xC670, 0x947D}, //5796 #CJK UNIFIED IDEOGRAPH + {0xC671, 0x947E}, //5797 #CJK UNIFIED IDEOGRAPH + {0xC672, 0x947C}, //5798 #CJK UNIFIED IDEOGRAPH + {0xC673, 0x9C77}, //5799 #CJK UNIFIED IDEOGRAPH + {0xC674, 0x9C78}, //5800 #CJK UNIFIED IDEOGRAPH + {0xC675, 0x9EF7}, //5801 #CJK UNIFIED IDEOGRAPH + {0xC676, 0x8C54}, //5802 #CJK UNIFIED IDEOGRAPH + {0xC677, 0x947F}, //5803 #CJK UNIFIED IDEOGRAPH + {0xC678, 0x9E1A}, //5804 #CJK UNIFIED IDEOGRAPH + {0xC679, 0x7228}, //5805 #CJK UNIFIED IDEOGRAPH + {0xC67A, 0x9A6A}, //5806 #CJK UNIFIED IDEOGRAPH + {0xC67B, 0x9B31}, //5807 #CJK UNIFIED IDEOGRAPH + {0xC67C, 0x9E1B}, //5808 #CJK UNIFIED IDEOGRAPH + {0xC67D, 0x9E1E}, //5809 #CJK UNIFIED IDEOGRAPH + {0xC67E, 0x7C72}, //5810 #CJK UNIFIED IDEOGRAPH + {0xC940, 0x4E42}, //5811 #CJK UNIFIED IDEOGRAPH + {0xC941, 0x4E5C}, //5812 #CJK UNIFIED IDEOGRAPH + {0xC942, 0x51F5}, //5813 #CJK UNIFIED IDEOGRAPH + {0xC943, 0x531A}, //5814 #CJK UNIFIED IDEOGRAPH + {0xC944, 0x5382}, //5815 #CJK UNIFIED IDEOGRAPH + {0xC945, 0x4E07}, //5816 #CJK UNIFIED IDEOGRAPH + {0xC946, 0x4E0C}, //5817 #CJK UNIFIED IDEOGRAPH + {0xC947, 0x4E47}, //5818 #CJK UNIFIED IDEOGRAPH + {0xC948, 0x4E8D}, //5819 #CJK UNIFIED IDEOGRAPH + {0xC949, 0x56D7}, //5820 #CJK UNIFIED IDEOGRAPH + {0xC94A, 0xFA0C}, //5821 #CJK COMPATIBILITY IDEOGRAPH + {0xC94B, 0x5C6E}, //5822 #CJK UNIFIED IDEOGRAPH + {0xC94C, 0x5F73}, //5823 #CJK UNIFIED IDEOGRAPH + {0xC94D, 0x4E0F}, //5824 #CJK UNIFIED IDEOGRAPH + {0xC94E, 0x5187}, //5825 #CJK UNIFIED IDEOGRAPH + {0xC94F, 0x4E0E}, //5826 #CJK UNIFIED IDEOGRAPH + {0xC950, 0x4E2E}, //5827 #CJK UNIFIED IDEOGRAPH + {0xC951, 0x4E93}, //5828 #CJK UNIFIED IDEOGRAPH + {0xC952, 0x4EC2}, //5829 #CJK UNIFIED IDEOGRAPH + {0xC953, 0x4EC9}, //5830 #CJK UNIFIED IDEOGRAPH + {0xC954, 0x4EC8}, //5831 #CJK UNIFIED IDEOGRAPH + {0xC955, 0x5198}, //5832 #CJK UNIFIED IDEOGRAPH + {0xC956, 0x52FC}, //5833 #CJK UNIFIED IDEOGRAPH + {0xC957, 0x536C}, //5834 #CJK UNIFIED IDEOGRAPH + {0xC958, 0x53B9}, //5835 #CJK UNIFIED IDEOGRAPH + {0xC959, 0x5720}, //5836 #CJK UNIFIED IDEOGRAPH + {0xC95A, 0x5903}, //5837 #CJK UNIFIED IDEOGRAPH + {0xC95B, 0x592C}, //5838 #CJK UNIFIED IDEOGRAPH + {0xC95C, 0x5C10}, //5839 #CJK UNIFIED IDEOGRAPH + {0xC95D, 0x5DFF}, //5840 #CJK UNIFIED IDEOGRAPH + {0xC95E, 0x65E1}, //5841 #CJK UNIFIED IDEOGRAPH + {0xC95F, 0x6BB3}, //5842 #CJK UNIFIED IDEOGRAPH + {0xC960, 0x6BCC}, //5843 #CJK UNIFIED IDEOGRAPH + {0xC961, 0x6C14}, //5844 #CJK UNIFIED IDEOGRAPH + {0xC962, 0x723F}, //5845 #CJK UNIFIED IDEOGRAPH + {0xC963, 0x4E31}, //5846 #CJK UNIFIED IDEOGRAPH + {0xC964, 0x4E3C}, //5847 #CJK UNIFIED IDEOGRAPH + {0xC965, 0x4EE8}, //5848 #CJK UNIFIED IDEOGRAPH + {0xC966, 0x4EDC}, //5849 #CJK UNIFIED IDEOGRAPH + {0xC967, 0x4EE9}, //5850 #CJK UNIFIED IDEOGRAPH + {0xC968, 0x4EE1}, //5851 #CJK UNIFIED IDEOGRAPH + {0xC969, 0x4EDD}, //5852 #CJK UNIFIED IDEOGRAPH + {0xC96A, 0x4EDA}, //5853 #CJK UNIFIED IDEOGRAPH + {0xC96B, 0x520C}, //5854 #CJK UNIFIED IDEOGRAPH + {0xC96C, 0x531C}, //5855 #CJK UNIFIED IDEOGRAPH + {0xC96D, 0x534C}, //5856 #CJK UNIFIED IDEOGRAPH + {0xC96E, 0x5722}, //5857 #CJK UNIFIED IDEOGRAPH + {0xC96F, 0x5723}, //5858 #CJK UNIFIED IDEOGRAPH + {0xC970, 0x5917}, //5859 #CJK UNIFIED IDEOGRAPH + {0xC971, 0x592F}, //5860 #CJK UNIFIED IDEOGRAPH + {0xC972, 0x5B81}, //5861 #CJK UNIFIED IDEOGRAPH + {0xC973, 0x5B84}, //5862 #CJK UNIFIED IDEOGRAPH + {0xC974, 0x5C12}, //5863 #CJK UNIFIED IDEOGRAPH + {0xC975, 0x5C3B}, //5864 #CJK UNIFIED IDEOGRAPH + {0xC976, 0x5C74}, //5865 #CJK UNIFIED IDEOGRAPH + {0xC977, 0x5C73}, //5866 #CJK UNIFIED IDEOGRAPH + {0xC978, 0x5E04}, //5867 #CJK UNIFIED IDEOGRAPH + {0xC979, 0x5E80}, //5868 #CJK UNIFIED IDEOGRAPH + {0xC97A, 0x5E82}, //5869 #CJK UNIFIED IDEOGRAPH + {0xC97B, 0x5FC9}, //5870 #CJK UNIFIED IDEOGRAPH + {0xC97C, 0x6209}, //5871 #CJK UNIFIED IDEOGRAPH + {0xC97D, 0x6250}, //5872 #CJK UNIFIED IDEOGRAPH + {0xC97E, 0x6C15}, //5873 #CJK UNIFIED IDEOGRAPH + {0xC9A1, 0x6C36}, //5874 #CJK UNIFIED IDEOGRAPH + {0xC9A2, 0x6C43}, //5875 #CJK UNIFIED IDEOGRAPH + {0xC9A3, 0x6C3F}, //5876 #CJK UNIFIED IDEOGRAPH + {0xC9A4, 0x6C3B}, //5877 #CJK UNIFIED IDEOGRAPH + {0xC9A5, 0x72AE}, //5878 #CJK UNIFIED IDEOGRAPH + {0xC9A6, 0x72B0}, //5879 #CJK UNIFIED IDEOGRAPH + {0xC9A7, 0x738A}, //5880 #CJK UNIFIED IDEOGRAPH + {0xC9A8, 0x79B8}, //5881 #CJK UNIFIED IDEOGRAPH + {0xC9A9, 0x808A}, //5882 #CJK UNIFIED IDEOGRAPH + {0xC9AA, 0x961E}, //5883 #CJK UNIFIED IDEOGRAPH + {0xC9AB, 0x4F0E}, //5884 #CJK UNIFIED IDEOGRAPH + {0xC9AC, 0x4F18}, //5885 #CJK UNIFIED IDEOGRAPH + {0xC9AD, 0x4F2C}, //5886 #CJK UNIFIED IDEOGRAPH + {0xC9AE, 0x4EF5}, //5887 #CJK UNIFIED IDEOGRAPH + {0xC9AF, 0x4F14}, //5888 #CJK UNIFIED IDEOGRAPH + {0xC9B0, 0x4EF1}, //5889 #CJK UNIFIED IDEOGRAPH + {0xC9B1, 0x4F00}, //5890 #CJK UNIFIED IDEOGRAPH + {0xC9B2, 0x4EF7}, //5891 #CJK UNIFIED IDEOGRAPH + {0xC9B3, 0x4F08}, //5892 #CJK UNIFIED IDEOGRAPH + {0xC9B4, 0x4F1D}, //5893 #CJK UNIFIED IDEOGRAPH + {0xC9B5, 0x4F02}, //5894 #CJK UNIFIED IDEOGRAPH + {0xC9B6, 0x4F05}, //5895 #CJK UNIFIED IDEOGRAPH + {0xC9B7, 0x4F22}, //5896 #CJK UNIFIED IDEOGRAPH + {0xC9B8, 0x4F13}, //5897 #CJK UNIFIED IDEOGRAPH + {0xC9B9, 0x4F04}, //5898 #CJK UNIFIED IDEOGRAPH + {0xC9BA, 0x4EF4}, //5899 #CJK UNIFIED IDEOGRAPH + {0xC9BB, 0x4F12}, //5900 #CJK UNIFIED IDEOGRAPH + {0xC9BC, 0x51B1}, //5901 #CJK UNIFIED IDEOGRAPH + {0xC9BD, 0x5213}, //5902 #CJK UNIFIED IDEOGRAPH + {0xC9BE, 0x5209}, //5903 #CJK UNIFIED IDEOGRAPH + {0xC9BF, 0x5210}, //5904 #CJK UNIFIED IDEOGRAPH + {0xC9C0, 0x52A6}, //5905 #CJK UNIFIED IDEOGRAPH + {0xC9C1, 0x5322}, //5906 #CJK UNIFIED IDEOGRAPH + {0xC9C2, 0x531F}, //5907 #CJK UNIFIED IDEOGRAPH + {0xC9C3, 0x534D}, //5908 #CJK UNIFIED IDEOGRAPH + {0xC9C4, 0x538A}, //5909 #CJK UNIFIED IDEOGRAPH + {0xC9C5, 0x5407}, //5910 #CJK UNIFIED IDEOGRAPH + {0xC9C6, 0x56E1}, //5911 #CJK UNIFIED IDEOGRAPH + {0xC9C7, 0x56DF}, //5912 #CJK UNIFIED IDEOGRAPH + {0xC9C8, 0x572E}, //5913 #CJK UNIFIED IDEOGRAPH + {0xC9C9, 0x572A}, //5914 #CJK UNIFIED IDEOGRAPH + {0xC9CA, 0x5734}, //5915 #CJK UNIFIED IDEOGRAPH + {0xC9CB, 0x593C}, //5916 #CJK UNIFIED IDEOGRAPH + {0xC9CC, 0x5980}, //5917 #CJK UNIFIED IDEOGRAPH + {0xC9CD, 0x597C}, //5918 #CJK UNIFIED IDEOGRAPH + {0xC9CE, 0x5985}, //5919 #CJK UNIFIED IDEOGRAPH + {0xC9CF, 0x597B}, //5920 #CJK UNIFIED IDEOGRAPH + {0xC9D0, 0x597E}, //5921 #CJK UNIFIED IDEOGRAPH + {0xC9D1, 0x5977}, //5922 #CJK UNIFIED IDEOGRAPH + {0xC9D2, 0x597F}, //5923 #CJK UNIFIED IDEOGRAPH + {0xC9D3, 0x5B56}, //5924 #CJK UNIFIED IDEOGRAPH + {0xC9D4, 0x5C15}, //5925 #CJK UNIFIED IDEOGRAPH + {0xC9D5, 0x5C25}, //5926 #CJK UNIFIED IDEOGRAPH + {0xC9D6, 0x5C7C}, //5927 #CJK UNIFIED IDEOGRAPH + {0xC9D7, 0x5C7A}, //5928 #CJK UNIFIED IDEOGRAPH + {0xC9D8, 0x5C7B}, //5929 #CJK UNIFIED IDEOGRAPH + {0xC9D9, 0x5C7E}, //5930 #CJK UNIFIED IDEOGRAPH + {0xC9DA, 0x5DDF}, //5931 #CJK UNIFIED IDEOGRAPH + {0xC9DB, 0x5E75}, //5932 #CJK UNIFIED IDEOGRAPH + {0xC9DC, 0x5E84}, //5933 #CJK UNIFIED IDEOGRAPH + {0xC9DD, 0x5F02}, //5934 #CJK UNIFIED IDEOGRAPH + {0xC9DE, 0x5F1A}, //5935 #CJK UNIFIED IDEOGRAPH + {0xC9DF, 0x5F74}, //5936 #CJK UNIFIED IDEOGRAPH + {0xC9E0, 0x5FD5}, //5937 #CJK UNIFIED IDEOGRAPH + {0xC9E1, 0x5FD4}, //5938 #CJK UNIFIED IDEOGRAPH + {0xC9E2, 0x5FCF}, //5939 #CJK UNIFIED IDEOGRAPH + {0xC9E3, 0x625C}, //5940 #CJK UNIFIED IDEOGRAPH + {0xC9E4, 0x625E}, //5941 #CJK UNIFIED IDEOGRAPH + {0xC9E5, 0x6264}, //5942 #CJK UNIFIED IDEOGRAPH + {0xC9E6, 0x6261}, //5943 #CJK UNIFIED IDEOGRAPH + {0xC9E7, 0x6266}, //5944 #CJK UNIFIED IDEOGRAPH + {0xC9E8, 0x6262}, //5945 #CJK UNIFIED IDEOGRAPH + {0xC9E9, 0x6259}, //5946 #CJK UNIFIED IDEOGRAPH + {0xC9EA, 0x6260}, //5947 #CJK UNIFIED IDEOGRAPH + {0xC9EB, 0x625A}, //5948 #CJK UNIFIED IDEOGRAPH + {0xC9EC, 0x6265}, //5949 #CJK UNIFIED IDEOGRAPH + {0xC9ED, 0x65EF}, //5950 #CJK UNIFIED IDEOGRAPH + {0xC9EE, 0x65EE}, //5951 #CJK UNIFIED IDEOGRAPH + {0xC9EF, 0x673E}, //5952 #CJK UNIFIED IDEOGRAPH + {0xC9F0, 0x6739}, //5953 #CJK UNIFIED IDEOGRAPH + {0xC9F1, 0x6738}, //5954 #CJK UNIFIED IDEOGRAPH + {0xC9F2, 0x673B}, //5955 #CJK UNIFIED IDEOGRAPH + {0xC9F3, 0x673A}, //5956 #CJK UNIFIED IDEOGRAPH + {0xC9F4, 0x673F}, //5957 #CJK UNIFIED IDEOGRAPH + {0xC9F5, 0x673C}, //5958 #CJK UNIFIED IDEOGRAPH + {0xC9F6, 0x6733}, //5959 #CJK UNIFIED IDEOGRAPH + {0xC9F7, 0x6C18}, //5960 #CJK UNIFIED IDEOGRAPH + {0xC9F8, 0x6C46}, //5961 #CJK UNIFIED IDEOGRAPH + {0xC9F9, 0x6C52}, //5962 #CJK UNIFIED IDEOGRAPH + {0xC9FA, 0x6C5C}, //5963 #CJK UNIFIED IDEOGRAPH + {0xC9FB, 0x6C4F}, //5964 #CJK UNIFIED IDEOGRAPH + {0xC9FC, 0x6C4A}, //5965 #CJK UNIFIED IDEOGRAPH + {0xC9FD, 0x6C54}, //5966 #CJK UNIFIED IDEOGRAPH + {0xC9FE, 0x6C4B}, //5967 #CJK UNIFIED IDEOGRAPH + {0xCA40, 0x6C4C}, //5968 #CJK UNIFIED IDEOGRAPH + {0xCA41, 0x7071}, //5969 #CJK UNIFIED IDEOGRAPH + {0xCA42, 0x725E}, //5970 #CJK UNIFIED IDEOGRAPH + {0xCA43, 0x72B4}, //5971 #CJK UNIFIED IDEOGRAPH + {0xCA44, 0x72B5}, //5972 #CJK UNIFIED IDEOGRAPH + {0xCA45, 0x738E}, //5973 #CJK UNIFIED IDEOGRAPH + {0xCA46, 0x752A}, //5974 #CJK UNIFIED IDEOGRAPH + {0xCA47, 0x767F}, //5975 #CJK UNIFIED IDEOGRAPH + {0xCA48, 0x7A75}, //5976 #CJK UNIFIED IDEOGRAPH + {0xCA49, 0x7F51}, //5977 #CJK UNIFIED IDEOGRAPH + {0xCA4A, 0x8278}, //5978 #CJK UNIFIED IDEOGRAPH + {0xCA4B, 0x827C}, //5979 #CJK UNIFIED IDEOGRAPH + {0xCA4C, 0x8280}, //5980 #CJK UNIFIED IDEOGRAPH + {0xCA4D, 0x827D}, //5981 #CJK UNIFIED IDEOGRAPH + {0xCA4E, 0x827F}, //5982 #CJK UNIFIED IDEOGRAPH + {0xCA4F, 0x864D}, //5983 #CJK UNIFIED IDEOGRAPH + {0xCA50, 0x897E}, //5984 #CJK UNIFIED IDEOGRAPH + {0xCA51, 0x9099}, //5985 #CJK UNIFIED IDEOGRAPH + {0xCA52, 0x9097}, //5986 #CJK UNIFIED IDEOGRAPH + {0xCA53, 0x9098}, //5987 #CJK UNIFIED IDEOGRAPH + {0xCA54, 0x909B}, //5988 #CJK UNIFIED IDEOGRAPH + {0xCA55, 0x9094}, //5989 #CJK UNIFIED IDEOGRAPH + {0xCA56, 0x9622}, //5990 #CJK UNIFIED IDEOGRAPH + {0xCA57, 0x9624}, //5991 #CJK UNIFIED IDEOGRAPH + {0xCA58, 0x9620}, //5992 #CJK UNIFIED IDEOGRAPH + {0xCA59, 0x9623}, //5993 #CJK UNIFIED IDEOGRAPH + {0xCA5A, 0x4F56}, //5994 #CJK UNIFIED IDEOGRAPH + {0xCA5B, 0x4F3B}, //5995 #CJK UNIFIED IDEOGRAPH + {0xCA5C, 0x4F62}, //5996 #CJK UNIFIED IDEOGRAPH + {0xCA5D, 0x4F49}, //5997 #CJK UNIFIED IDEOGRAPH + {0xCA5E, 0x4F53}, //5998 #CJK UNIFIED IDEOGRAPH + {0xCA5F, 0x4F64}, //5999 #CJK UNIFIED IDEOGRAPH + {0xCA60, 0x4F3E}, //6000 #CJK UNIFIED IDEOGRAPH + {0xCA61, 0x4F67}, //6001 #CJK UNIFIED IDEOGRAPH + {0xCA62, 0x4F52}, //6002 #CJK UNIFIED IDEOGRAPH + {0xCA63, 0x4F5F}, //6003 #CJK UNIFIED IDEOGRAPH + {0xCA64, 0x4F41}, //6004 #CJK UNIFIED IDEOGRAPH + {0xCA65, 0x4F58}, //6005 #CJK UNIFIED IDEOGRAPH + {0xCA66, 0x4F2D}, //6006 #CJK UNIFIED IDEOGRAPH + {0xCA67, 0x4F33}, //6007 #CJK UNIFIED IDEOGRAPH + {0xCA68, 0x4F3F}, //6008 #CJK UNIFIED IDEOGRAPH + {0xCA69, 0x4F61}, //6009 #CJK UNIFIED IDEOGRAPH + {0xCA6A, 0x518F}, //6010 #CJK UNIFIED IDEOGRAPH + {0xCA6B, 0x51B9}, //6011 #CJK UNIFIED IDEOGRAPH + {0xCA6C, 0x521C}, //6012 #CJK UNIFIED IDEOGRAPH + {0xCA6D, 0x521E}, //6013 #CJK UNIFIED IDEOGRAPH + {0xCA6E, 0x5221}, //6014 #CJK UNIFIED IDEOGRAPH + {0xCA6F, 0x52AD}, //6015 #CJK UNIFIED IDEOGRAPH + {0xCA70, 0x52AE}, //6016 #CJK UNIFIED IDEOGRAPH + {0xCA71, 0x5309}, //6017 #CJK UNIFIED IDEOGRAPH + {0xCA72, 0x5363}, //6018 #CJK UNIFIED IDEOGRAPH + {0xCA73, 0x5372}, //6019 #CJK UNIFIED IDEOGRAPH + {0xCA74, 0x538E}, //6020 #CJK UNIFIED IDEOGRAPH + {0xCA75, 0x538F}, //6021 #CJK UNIFIED IDEOGRAPH + {0xCA76, 0x5430}, //6022 #CJK UNIFIED IDEOGRAPH + {0xCA77, 0x5437}, //6023 #CJK UNIFIED IDEOGRAPH + {0xCA78, 0x542A}, //6024 #CJK UNIFIED IDEOGRAPH + {0xCA79, 0x5454}, //6025 #CJK UNIFIED IDEOGRAPH + {0xCA7A, 0x5445}, //6026 #CJK UNIFIED IDEOGRAPH + {0xCA7B, 0x5419}, //6027 #CJK UNIFIED IDEOGRAPH + {0xCA7C, 0x541C}, //6028 #CJK UNIFIED IDEOGRAPH + {0xCA7D, 0x5425}, //6029 #CJK UNIFIED IDEOGRAPH + {0xCA7E, 0x5418}, //6030 #CJK UNIFIED IDEOGRAPH + {0xCAA1, 0x543D}, //6031 #CJK UNIFIED IDEOGRAPH + {0xCAA2, 0x544F}, //6032 #CJK UNIFIED IDEOGRAPH + {0xCAA3, 0x5441}, //6033 #CJK UNIFIED IDEOGRAPH + {0xCAA4, 0x5428}, //6034 #CJK UNIFIED IDEOGRAPH + {0xCAA5, 0x5424}, //6035 #CJK UNIFIED IDEOGRAPH + {0xCAA6, 0x5447}, //6036 #CJK UNIFIED IDEOGRAPH + {0xCAA7, 0x56EE}, //6037 #CJK UNIFIED IDEOGRAPH + {0xCAA8, 0x56E7}, //6038 #CJK UNIFIED IDEOGRAPH + {0xCAA9, 0x56E5}, //6039 #CJK UNIFIED IDEOGRAPH + {0xCAAA, 0x5741}, //6040 #CJK UNIFIED IDEOGRAPH + {0xCAAB, 0x5745}, //6041 #CJK UNIFIED IDEOGRAPH + {0xCAAC, 0x574C}, //6042 #CJK UNIFIED IDEOGRAPH + {0xCAAD, 0x5749}, //6043 #CJK UNIFIED IDEOGRAPH + {0xCAAE, 0x574B}, //6044 #CJK UNIFIED IDEOGRAPH + {0xCAAF, 0x5752}, //6045 #CJK UNIFIED IDEOGRAPH + {0xCAB0, 0x5906}, //6046 #CJK UNIFIED IDEOGRAPH + {0xCAB1, 0x5940}, //6047 #CJK UNIFIED IDEOGRAPH + {0xCAB2, 0x59A6}, //6048 #CJK UNIFIED IDEOGRAPH + {0xCAB3, 0x5998}, //6049 #CJK UNIFIED IDEOGRAPH + {0xCAB4, 0x59A0}, //6050 #CJK UNIFIED IDEOGRAPH + {0xCAB5, 0x5997}, //6051 #CJK UNIFIED IDEOGRAPH + {0xCAB6, 0x598E}, //6052 #CJK UNIFIED IDEOGRAPH + {0xCAB7, 0x59A2}, //6053 #CJK UNIFIED IDEOGRAPH + {0xCAB8, 0x5990}, //6054 #CJK UNIFIED IDEOGRAPH + {0xCAB9, 0x598F}, //6055 #CJK UNIFIED IDEOGRAPH + {0xCABA, 0x59A7}, //6056 #CJK UNIFIED IDEOGRAPH + {0xCABB, 0x59A1}, //6057 #CJK UNIFIED IDEOGRAPH + {0xCABC, 0x5B8E}, //6058 #CJK UNIFIED IDEOGRAPH + {0xCABD, 0x5B92}, //6059 #CJK UNIFIED IDEOGRAPH + {0xCABE, 0x5C28}, //6060 #CJK UNIFIED IDEOGRAPH + {0xCABF, 0x5C2A}, //6061 #CJK UNIFIED IDEOGRAPH + {0xCAC0, 0x5C8D}, //6062 #CJK UNIFIED IDEOGRAPH + {0xCAC1, 0x5C8F}, //6063 #CJK UNIFIED IDEOGRAPH + {0xCAC2, 0x5C88}, //6064 #CJK UNIFIED IDEOGRAPH + {0xCAC3, 0x5C8B}, //6065 #CJK UNIFIED IDEOGRAPH + {0xCAC4, 0x5C89}, //6066 #CJK UNIFIED IDEOGRAPH + {0xCAC5, 0x5C92}, //6067 #CJK UNIFIED IDEOGRAPH + {0xCAC6, 0x5C8A}, //6068 #CJK UNIFIED IDEOGRAPH + {0xCAC7, 0x5C86}, //6069 #CJK UNIFIED IDEOGRAPH + {0xCAC8, 0x5C93}, //6070 #CJK UNIFIED IDEOGRAPH + {0xCAC9, 0x5C95}, //6071 #CJK UNIFIED IDEOGRAPH + {0xCACA, 0x5DE0}, //6072 #CJK UNIFIED IDEOGRAPH + {0xCACB, 0x5E0A}, //6073 #CJK UNIFIED IDEOGRAPH + {0xCACC, 0x5E0E}, //6074 #CJK UNIFIED IDEOGRAPH + {0xCACD, 0x5E8B}, //6075 #CJK UNIFIED IDEOGRAPH + {0xCACE, 0x5E89}, //6076 #CJK UNIFIED IDEOGRAPH + {0xCACF, 0x5E8C}, //6077 #CJK UNIFIED IDEOGRAPH + {0xCAD0, 0x5E88}, //6078 #CJK UNIFIED IDEOGRAPH + {0xCAD1, 0x5E8D}, //6079 #CJK UNIFIED IDEOGRAPH + {0xCAD2, 0x5F05}, //6080 #CJK UNIFIED IDEOGRAPH + {0xCAD3, 0x5F1D}, //6081 #CJK UNIFIED IDEOGRAPH + {0xCAD4, 0x5F78}, //6082 #CJK UNIFIED IDEOGRAPH + {0xCAD5, 0x5F76}, //6083 #CJK UNIFIED IDEOGRAPH + {0xCAD6, 0x5FD2}, //6084 #CJK UNIFIED IDEOGRAPH + {0xCAD7, 0x5FD1}, //6085 #CJK UNIFIED IDEOGRAPH + {0xCAD8, 0x5FD0}, //6086 #CJK UNIFIED IDEOGRAPH + {0xCAD9, 0x5FED}, //6087 #CJK UNIFIED IDEOGRAPH + {0xCADA, 0x5FE8}, //6088 #CJK UNIFIED IDEOGRAPH + {0xCADB, 0x5FEE}, //6089 #CJK UNIFIED IDEOGRAPH + {0xCADC, 0x5FF3}, //6090 #CJK UNIFIED IDEOGRAPH + {0xCADD, 0x5FE1}, //6091 #CJK UNIFIED IDEOGRAPH + {0xCADE, 0x5FE4}, //6092 #CJK UNIFIED IDEOGRAPH + {0xCADF, 0x5FE3}, //6093 #CJK UNIFIED IDEOGRAPH + {0xCAE0, 0x5FFA}, //6094 #CJK UNIFIED IDEOGRAPH + {0xCAE1, 0x5FEF}, //6095 #CJK UNIFIED IDEOGRAPH + {0xCAE2, 0x5FF7}, //6096 #CJK UNIFIED IDEOGRAPH + {0xCAE3, 0x5FFB}, //6097 #CJK UNIFIED IDEOGRAPH + {0xCAE4, 0x6000}, //6098 #CJK UNIFIED IDEOGRAPH + {0xCAE5, 0x5FF4}, //6099 #CJK UNIFIED IDEOGRAPH + {0xCAE6, 0x623A}, //6100 #CJK UNIFIED IDEOGRAPH + {0xCAE7, 0x6283}, //6101 #CJK UNIFIED IDEOGRAPH + {0xCAE8, 0x628C}, //6102 #CJK UNIFIED IDEOGRAPH + {0xCAE9, 0x628E}, //6103 #CJK UNIFIED IDEOGRAPH + {0xCAEA, 0x628F}, //6104 #CJK UNIFIED IDEOGRAPH + {0xCAEB, 0x6294}, //6105 #CJK UNIFIED IDEOGRAPH + {0xCAEC, 0x6287}, //6106 #CJK UNIFIED IDEOGRAPH + {0xCAED, 0x6271}, //6107 #CJK UNIFIED IDEOGRAPH + {0xCAEE, 0x627B}, //6108 #CJK UNIFIED IDEOGRAPH + {0xCAEF, 0x627A}, //6109 #CJK UNIFIED IDEOGRAPH + {0xCAF0, 0x6270}, //6110 #CJK UNIFIED IDEOGRAPH + {0xCAF1, 0x6281}, //6111 #CJK UNIFIED IDEOGRAPH + {0xCAF2, 0x6288}, //6112 #CJK UNIFIED IDEOGRAPH + {0xCAF3, 0x6277}, //6113 #CJK UNIFIED IDEOGRAPH + {0xCAF4, 0x627D}, //6114 #CJK UNIFIED IDEOGRAPH + {0xCAF5, 0x6272}, //6115 #CJK UNIFIED IDEOGRAPH + {0xCAF6, 0x6274}, //6116 #CJK UNIFIED IDEOGRAPH + {0xCAF7, 0x6537}, //6117 #CJK UNIFIED IDEOGRAPH + {0xCAF8, 0x65F0}, //6118 #CJK UNIFIED IDEOGRAPH + {0xCAF9, 0x65F4}, //6119 #CJK UNIFIED IDEOGRAPH + {0xCAFA, 0x65F3}, //6120 #CJK UNIFIED IDEOGRAPH + {0xCAFB, 0x65F2}, //6121 #CJK UNIFIED IDEOGRAPH + {0xCAFC, 0x65F5}, //6122 #CJK UNIFIED IDEOGRAPH + {0xCAFD, 0x6745}, //6123 #CJK UNIFIED IDEOGRAPH + {0xCAFE, 0x6747}, //6124 #CJK UNIFIED IDEOGRAPH + {0xCB40, 0x6759}, //6125 #CJK UNIFIED IDEOGRAPH + {0xCB41, 0x6755}, //6126 #CJK UNIFIED IDEOGRAPH + {0xCB42, 0x674C}, //6127 #CJK UNIFIED IDEOGRAPH + {0xCB43, 0x6748}, //6128 #CJK UNIFIED IDEOGRAPH + {0xCB44, 0x675D}, //6129 #CJK UNIFIED IDEOGRAPH + {0xCB45, 0x674D}, //6130 #CJK UNIFIED IDEOGRAPH + {0xCB46, 0x675A}, //6131 #CJK UNIFIED IDEOGRAPH + {0xCB47, 0x674B}, //6132 #CJK UNIFIED IDEOGRAPH + {0xCB48, 0x6BD0}, //6133 #CJK UNIFIED IDEOGRAPH + {0xCB49, 0x6C19}, //6134 #CJK UNIFIED IDEOGRAPH + {0xCB4A, 0x6C1A}, //6135 #CJK UNIFIED IDEOGRAPH + {0xCB4B, 0x6C78}, //6136 #CJK UNIFIED IDEOGRAPH + {0xCB4C, 0x6C67}, //6137 #CJK UNIFIED IDEOGRAPH + {0xCB4D, 0x6C6B}, //6138 #CJK UNIFIED IDEOGRAPH + {0xCB4E, 0x6C84}, //6139 #CJK UNIFIED IDEOGRAPH + {0xCB4F, 0x6C8B}, //6140 #CJK UNIFIED IDEOGRAPH + {0xCB50, 0x6C8F}, //6141 #CJK UNIFIED IDEOGRAPH + {0xCB51, 0x6C71}, //6142 #CJK UNIFIED IDEOGRAPH + {0xCB52, 0x6C6F}, //6143 #CJK UNIFIED IDEOGRAPH + {0xCB53, 0x6C69}, //6144 #CJK UNIFIED IDEOGRAPH + {0xCB54, 0x6C9A}, //6145 #CJK UNIFIED IDEOGRAPH + {0xCB55, 0x6C6D}, //6146 #CJK UNIFIED IDEOGRAPH + {0xCB56, 0x6C87}, //6147 #CJK UNIFIED IDEOGRAPH + {0xCB57, 0x6C95}, //6148 #CJK UNIFIED IDEOGRAPH + {0xCB58, 0x6C9C}, //6149 #CJK UNIFIED IDEOGRAPH + {0xCB59, 0x6C66}, //6150 #CJK UNIFIED IDEOGRAPH + {0xCB5A, 0x6C73}, //6151 #CJK UNIFIED IDEOGRAPH + {0xCB5B, 0x6C65}, //6152 #CJK UNIFIED IDEOGRAPH + {0xCB5C, 0x6C7B}, //6153 #CJK UNIFIED IDEOGRAPH + {0xCB5D, 0x6C8E}, //6154 #CJK UNIFIED IDEOGRAPH + {0xCB5E, 0x7074}, //6155 #CJK UNIFIED IDEOGRAPH + {0xCB5F, 0x707A}, //6156 #CJK UNIFIED IDEOGRAPH + {0xCB60, 0x7263}, //6157 #CJK UNIFIED IDEOGRAPH + {0xCB61, 0x72BF}, //6158 #CJK UNIFIED IDEOGRAPH + {0xCB62, 0x72BD}, //6159 #CJK UNIFIED IDEOGRAPH + {0xCB63, 0x72C3}, //6160 #CJK UNIFIED IDEOGRAPH + {0xCB64, 0x72C6}, //6161 #CJK UNIFIED IDEOGRAPH + {0xCB65, 0x72C1}, //6162 #CJK UNIFIED IDEOGRAPH + {0xCB66, 0x72BA}, //6163 #CJK UNIFIED IDEOGRAPH + {0xCB67, 0x72C5}, //6164 #CJK UNIFIED IDEOGRAPH + {0xCB68, 0x7395}, //6165 #CJK UNIFIED IDEOGRAPH + {0xCB69, 0x7397}, //6166 #CJK UNIFIED IDEOGRAPH + {0xCB6A, 0x7393}, //6167 #CJK UNIFIED IDEOGRAPH + {0xCB6B, 0x7394}, //6168 #CJK UNIFIED IDEOGRAPH + {0xCB6C, 0x7392}, //6169 #CJK UNIFIED IDEOGRAPH + {0xCB6D, 0x753A}, //6170 #CJK UNIFIED IDEOGRAPH + {0xCB6E, 0x7539}, //6171 #CJK UNIFIED IDEOGRAPH + {0xCB6F, 0x7594}, //6172 #CJK UNIFIED IDEOGRAPH + {0xCB70, 0x7595}, //6173 #CJK UNIFIED IDEOGRAPH + {0xCB71, 0x7681}, //6174 #CJK UNIFIED IDEOGRAPH + {0xCB72, 0x793D}, //6175 #CJK UNIFIED IDEOGRAPH + {0xCB73, 0x8034}, //6176 #CJK UNIFIED IDEOGRAPH + {0xCB74, 0x8095}, //6177 #CJK UNIFIED IDEOGRAPH + {0xCB75, 0x8099}, //6178 #CJK UNIFIED IDEOGRAPH + {0xCB76, 0x8090}, //6179 #CJK UNIFIED IDEOGRAPH + {0xCB77, 0x8092}, //6180 #CJK UNIFIED IDEOGRAPH + {0xCB78, 0x809C}, //6181 #CJK UNIFIED IDEOGRAPH + {0xCB79, 0x8290}, //6182 #CJK UNIFIED IDEOGRAPH + {0xCB7A, 0x828F}, //6183 #CJK UNIFIED IDEOGRAPH + {0xCB7B, 0x8285}, //6184 #CJK UNIFIED IDEOGRAPH + {0xCB7C, 0x828E}, //6185 #CJK UNIFIED IDEOGRAPH + {0xCB7D, 0x8291}, //6186 #CJK UNIFIED IDEOGRAPH + {0xCB7E, 0x8293}, //6187 #CJK UNIFIED IDEOGRAPH + {0xCBA1, 0x828A}, //6188 #CJK UNIFIED IDEOGRAPH + {0xCBA2, 0x8283}, //6189 #CJK UNIFIED IDEOGRAPH + {0xCBA3, 0x8284}, //6190 #CJK UNIFIED IDEOGRAPH + {0xCBA4, 0x8C78}, //6191 #CJK UNIFIED IDEOGRAPH + {0xCBA5, 0x8FC9}, //6192 #CJK UNIFIED IDEOGRAPH + {0xCBA6, 0x8FBF}, //6193 #CJK UNIFIED IDEOGRAPH + {0xCBA7, 0x909F}, //6194 #CJK UNIFIED IDEOGRAPH + {0xCBA8, 0x90A1}, //6195 #CJK UNIFIED IDEOGRAPH + {0xCBA9, 0x90A5}, //6196 #CJK UNIFIED IDEOGRAPH + {0xCBAA, 0x909E}, //6197 #CJK UNIFIED IDEOGRAPH + {0xCBAB, 0x90A7}, //6198 #CJK UNIFIED IDEOGRAPH + {0xCBAC, 0x90A0}, //6199 #CJK UNIFIED IDEOGRAPH + {0xCBAD, 0x9630}, //6200 #CJK UNIFIED IDEOGRAPH + {0xCBAE, 0x9628}, //6201 #CJK UNIFIED IDEOGRAPH + {0xCBAF, 0x962F}, //6202 #CJK UNIFIED IDEOGRAPH + {0xCBB0, 0x962D}, //6203 #CJK UNIFIED IDEOGRAPH + {0xCBB1, 0x4E33}, //6204 #CJK UNIFIED IDEOGRAPH + {0xCBB2, 0x4F98}, //6205 #CJK UNIFIED IDEOGRAPH + {0xCBB3, 0x4F7C}, //6206 #CJK UNIFIED IDEOGRAPH + {0xCBB4, 0x4F85}, //6207 #CJK UNIFIED IDEOGRAPH + {0xCBB5, 0x4F7D}, //6208 #CJK UNIFIED IDEOGRAPH + {0xCBB6, 0x4F80}, //6209 #CJK UNIFIED IDEOGRAPH + {0xCBB7, 0x4F87}, //6210 #CJK UNIFIED IDEOGRAPH + {0xCBB8, 0x4F76}, //6211 #CJK UNIFIED IDEOGRAPH + {0xCBB9, 0x4F74}, //6212 #CJK UNIFIED IDEOGRAPH + {0xCBBA, 0x4F89}, //6213 #CJK UNIFIED IDEOGRAPH + {0xCBBB, 0x4F84}, //6214 #CJK UNIFIED IDEOGRAPH + {0xCBBC, 0x4F77}, //6215 #CJK UNIFIED IDEOGRAPH + {0xCBBD, 0x4F4C}, //6216 #CJK UNIFIED IDEOGRAPH + {0xCBBE, 0x4F97}, //6217 #CJK UNIFIED IDEOGRAPH + {0xCBBF, 0x4F6A}, //6218 #CJK UNIFIED IDEOGRAPH + {0xCBC0, 0x4F9A}, //6219 #CJK UNIFIED IDEOGRAPH + {0xCBC1, 0x4F79}, //6220 #CJK UNIFIED IDEOGRAPH + {0xCBC2, 0x4F81}, //6221 #CJK UNIFIED IDEOGRAPH + {0xCBC3, 0x4F78}, //6222 #CJK UNIFIED IDEOGRAPH + {0xCBC4, 0x4F90}, //6223 #CJK UNIFIED IDEOGRAPH + {0xCBC5, 0x4F9C}, //6224 #CJK UNIFIED IDEOGRAPH + {0xCBC6, 0x4F94}, //6225 #CJK UNIFIED IDEOGRAPH + {0xCBC7, 0x4F9E}, //6226 #CJK UNIFIED IDEOGRAPH + {0xCBC8, 0x4F92}, //6227 #CJK UNIFIED IDEOGRAPH + {0xCBC9, 0x4F82}, //6228 #CJK UNIFIED IDEOGRAPH + {0xCBCA, 0x4F95}, //6229 #CJK UNIFIED IDEOGRAPH + {0xCBCB, 0x4F6B}, //6230 #CJK UNIFIED IDEOGRAPH + {0xCBCC, 0x4F6E}, //6231 #CJK UNIFIED IDEOGRAPH + {0xCBCD, 0x519E}, //6232 #CJK UNIFIED IDEOGRAPH + {0xCBCE, 0x51BC}, //6233 #CJK UNIFIED IDEOGRAPH + {0xCBCF, 0x51BE}, //6234 #CJK UNIFIED IDEOGRAPH + {0xCBD0, 0x5235}, //6235 #CJK UNIFIED IDEOGRAPH + {0xCBD1, 0x5232}, //6236 #CJK UNIFIED IDEOGRAPH + {0xCBD2, 0x5233}, //6237 #CJK UNIFIED IDEOGRAPH + {0xCBD3, 0x5246}, //6238 #CJK UNIFIED IDEOGRAPH + {0xCBD4, 0x5231}, //6239 #CJK UNIFIED IDEOGRAPH + {0xCBD5, 0x52BC}, //6240 #CJK UNIFIED IDEOGRAPH + {0xCBD6, 0x530A}, //6241 #CJK UNIFIED IDEOGRAPH + {0xCBD7, 0x530B}, //6242 #CJK UNIFIED IDEOGRAPH + {0xCBD8, 0x533C}, //6243 #CJK UNIFIED IDEOGRAPH + {0xCBD9, 0x5392}, //6244 #CJK UNIFIED IDEOGRAPH + {0xCBDA, 0x5394}, //6245 #CJK UNIFIED IDEOGRAPH + {0xCBDB, 0x5487}, //6246 #CJK UNIFIED IDEOGRAPH + {0xCBDC, 0x547F}, //6247 #CJK UNIFIED IDEOGRAPH + {0xCBDD, 0x5481}, //6248 #CJK UNIFIED IDEOGRAPH + {0xCBDE, 0x5491}, //6249 #CJK UNIFIED IDEOGRAPH + {0xCBDF, 0x5482}, //6250 #CJK UNIFIED IDEOGRAPH + {0xCBE0, 0x5488}, //6251 #CJK UNIFIED IDEOGRAPH + {0xCBE1, 0x546B}, //6252 #CJK UNIFIED IDEOGRAPH + {0xCBE2, 0x547A}, //6253 #CJK UNIFIED IDEOGRAPH + {0xCBE3, 0x547E}, //6254 #CJK UNIFIED IDEOGRAPH + {0xCBE4, 0x5465}, //6255 #CJK UNIFIED IDEOGRAPH + {0xCBE5, 0x546C}, //6256 #CJK UNIFIED IDEOGRAPH + {0xCBE6, 0x5474}, //6257 #CJK UNIFIED IDEOGRAPH + {0xCBE7, 0x5466}, //6258 #CJK UNIFIED IDEOGRAPH + {0xCBE8, 0x548D}, //6259 #CJK UNIFIED IDEOGRAPH + {0xCBE9, 0x546F}, //6260 #CJK UNIFIED IDEOGRAPH + {0xCBEA, 0x5461}, //6261 #CJK UNIFIED IDEOGRAPH + {0xCBEB, 0x5460}, //6262 #CJK UNIFIED IDEOGRAPH + {0xCBEC, 0x5498}, //6263 #CJK UNIFIED IDEOGRAPH + {0xCBED, 0x5463}, //6264 #CJK UNIFIED IDEOGRAPH + {0xCBEE, 0x5467}, //6265 #CJK UNIFIED IDEOGRAPH + {0xCBEF, 0x5464}, //6266 #CJK UNIFIED IDEOGRAPH + {0xCBF0, 0x56F7}, //6267 #CJK UNIFIED IDEOGRAPH + {0xCBF1, 0x56F9}, //6268 #CJK UNIFIED IDEOGRAPH + {0xCBF2, 0x576F}, //6269 #CJK UNIFIED IDEOGRAPH + {0xCBF3, 0x5772}, //6270 #CJK UNIFIED IDEOGRAPH + {0xCBF4, 0x576D}, //6271 #CJK UNIFIED IDEOGRAPH + {0xCBF5, 0x576B}, //6272 #CJK UNIFIED IDEOGRAPH + {0xCBF6, 0x5771}, //6273 #CJK UNIFIED IDEOGRAPH + {0xCBF7, 0x5770}, //6274 #CJK UNIFIED IDEOGRAPH + {0xCBF8, 0x5776}, //6275 #CJK UNIFIED IDEOGRAPH + {0xCBF9, 0x5780}, //6276 #CJK UNIFIED IDEOGRAPH + {0xCBFA, 0x5775}, //6277 #CJK UNIFIED IDEOGRAPH + {0xCBFB, 0x577B}, //6278 #CJK UNIFIED IDEOGRAPH + {0xCBFC, 0x5773}, //6279 #CJK UNIFIED IDEOGRAPH + {0xCBFD, 0x5774}, //6280 #CJK UNIFIED IDEOGRAPH + {0xCBFE, 0x5762}, //6281 #CJK UNIFIED IDEOGRAPH + {0xCC40, 0x5768}, //6282 #CJK UNIFIED IDEOGRAPH + {0xCC41, 0x577D}, //6283 #CJK UNIFIED IDEOGRAPH + {0xCC42, 0x590C}, //6284 #CJK UNIFIED IDEOGRAPH + {0xCC43, 0x5945}, //6285 #CJK UNIFIED IDEOGRAPH + {0xCC44, 0x59B5}, //6286 #CJK UNIFIED IDEOGRAPH + {0xCC45, 0x59BA}, //6287 #CJK UNIFIED IDEOGRAPH + {0xCC46, 0x59CF}, //6288 #CJK UNIFIED IDEOGRAPH + {0xCC47, 0x59CE}, //6289 #CJK UNIFIED IDEOGRAPH + {0xCC48, 0x59B2}, //6290 #CJK UNIFIED IDEOGRAPH + {0xCC49, 0x59CC}, //6291 #CJK UNIFIED IDEOGRAPH + {0xCC4A, 0x59C1}, //6292 #CJK UNIFIED IDEOGRAPH + {0xCC4B, 0x59B6}, //6293 #CJK UNIFIED IDEOGRAPH + {0xCC4C, 0x59BC}, //6294 #CJK UNIFIED IDEOGRAPH + {0xCC4D, 0x59C3}, //6295 #CJK UNIFIED IDEOGRAPH + {0xCC4E, 0x59D6}, //6296 #CJK UNIFIED IDEOGRAPH + {0xCC4F, 0x59B1}, //6297 #CJK UNIFIED IDEOGRAPH + {0xCC50, 0x59BD}, //6298 #CJK UNIFIED IDEOGRAPH + {0xCC51, 0x59C0}, //6299 #CJK UNIFIED IDEOGRAPH + {0xCC52, 0x59C8}, //6300 #CJK UNIFIED IDEOGRAPH + {0xCC53, 0x59B4}, //6301 #CJK UNIFIED IDEOGRAPH + {0xCC54, 0x59C7}, //6302 #CJK UNIFIED IDEOGRAPH + {0xCC55, 0x5B62}, //6303 #CJK UNIFIED IDEOGRAPH + {0xCC56, 0x5B65}, //6304 #CJK UNIFIED IDEOGRAPH + {0xCC57, 0x5B93}, //6305 #CJK UNIFIED IDEOGRAPH + {0xCC58, 0x5B95}, //6306 #CJK UNIFIED IDEOGRAPH + {0xCC59, 0x5C44}, //6307 #CJK UNIFIED IDEOGRAPH + {0xCC5A, 0x5C47}, //6308 #CJK UNIFIED IDEOGRAPH + {0xCC5B, 0x5CAE}, //6309 #CJK UNIFIED IDEOGRAPH + {0xCC5C, 0x5CA4}, //6310 #CJK UNIFIED IDEOGRAPH + {0xCC5D, 0x5CA0}, //6311 #CJK UNIFIED IDEOGRAPH + {0xCC5E, 0x5CB5}, //6312 #CJK UNIFIED IDEOGRAPH + {0xCC5F, 0x5CAF}, //6313 #CJK UNIFIED IDEOGRAPH + {0xCC60, 0x5CA8}, //6314 #CJK UNIFIED IDEOGRAPH + {0xCC61, 0x5CAC}, //6315 #CJK UNIFIED IDEOGRAPH + {0xCC62, 0x5C9F}, //6316 #CJK UNIFIED IDEOGRAPH + {0xCC63, 0x5CA3}, //6317 #CJK UNIFIED IDEOGRAPH + {0xCC64, 0x5CAD}, //6318 #CJK UNIFIED IDEOGRAPH + {0xCC65, 0x5CA2}, //6319 #CJK UNIFIED IDEOGRAPH + {0xCC66, 0x5CAA}, //6320 #CJK UNIFIED IDEOGRAPH + {0xCC67, 0x5CA7}, //6321 #CJK UNIFIED IDEOGRAPH + {0xCC68, 0x5C9D}, //6322 #CJK UNIFIED IDEOGRAPH + {0xCC69, 0x5CA5}, //6323 #CJK UNIFIED IDEOGRAPH + {0xCC6A, 0x5CB6}, //6324 #CJK UNIFIED IDEOGRAPH + {0xCC6B, 0x5CB0}, //6325 #CJK UNIFIED IDEOGRAPH + {0xCC6C, 0x5CA6}, //6326 #CJK UNIFIED IDEOGRAPH + {0xCC6D, 0x5E17}, //6327 #CJK UNIFIED IDEOGRAPH + {0xCC6E, 0x5E14}, //6328 #CJK UNIFIED IDEOGRAPH + {0xCC6F, 0x5E19}, //6329 #CJK UNIFIED IDEOGRAPH + {0xCC70, 0x5F28}, //6330 #CJK UNIFIED IDEOGRAPH + {0xCC71, 0x5F22}, //6331 #CJK UNIFIED IDEOGRAPH + {0xCC72, 0x5F23}, //6332 #CJK UNIFIED IDEOGRAPH + {0xCC73, 0x5F24}, //6333 #CJK UNIFIED IDEOGRAPH + {0xCC74, 0x5F54}, //6334 #CJK UNIFIED IDEOGRAPH + {0xCC75, 0x5F82}, //6335 #CJK UNIFIED IDEOGRAPH + {0xCC76, 0x5F7E}, //6336 #CJK UNIFIED IDEOGRAPH + {0xCC77, 0x5F7D}, //6337 #CJK UNIFIED IDEOGRAPH + {0xCC78, 0x5FDE}, //6338 #CJK UNIFIED IDEOGRAPH + {0xCC79, 0x5FE5}, //6339 #CJK UNIFIED IDEOGRAPH + {0xCC7A, 0x602D}, //6340 #CJK UNIFIED IDEOGRAPH + {0xCC7B, 0x6026}, //6341 #CJK UNIFIED IDEOGRAPH + {0xCC7C, 0x6019}, //6342 #CJK UNIFIED IDEOGRAPH + {0xCC7D, 0x6032}, //6343 #CJK UNIFIED IDEOGRAPH + {0xCC7E, 0x600B}, //6344 #CJK UNIFIED IDEOGRAPH + {0xCCA1, 0x6034}, //6345 #CJK UNIFIED IDEOGRAPH + {0xCCA2, 0x600A}, //6346 #CJK UNIFIED IDEOGRAPH + {0xCCA3, 0x6017}, //6347 #CJK UNIFIED IDEOGRAPH + {0xCCA4, 0x6033}, //6348 #CJK UNIFIED IDEOGRAPH + {0xCCA5, 0x601A}, //6349 #CJK UNIFIED IDEOGRAPH + {0xCCA6, 0x601E}, //6350 #CJK UNIFIED IDEOGRAPH + {0xCCA7, 0x602C}, //6351 #CJK UNIFIED IDEOGRAPH + {0xCCA8, 0x6022}, //6352 #CJK UNIFIED IDEOGRAPH + {0xCCA9, 0x600D}, //6353 #CJK UNIFIED IDEOGRAPH + {0xCCAA, 0x6010}, //6354 #CJK UNIFIED IDEOGRAPH + {0xCCAB, 0x602E}, //6355 #CJK UNIFIED IDEOGRAPH + {0xCCAC, 0x6013}, //6356 #CJK UNIFIED IDEOGRAPH + {0xCCAD, 0x6011}, //6357 #CJK UNIFIED IDEOGRAPH + {0xCCAE, 0x600C}, //6358 #CJK UNIFIED IDEOGRAPH + {0xCCAF, 0x6009}, //6359 #CJK UNIFIED IDEOGRAPH + {0xCCB0, 0x601C}, //6360 #CJK UNIFIED IDEOGRAPH + {0xCCB1, 0x6214}, //6361 #CJK UNIFIED IDEOGRAPH + {0xCCB2, 0x623D}, //6362 #CJK UNIFIED IDEOGRAPH + {0xCCB3, 0x62AD}, //6363 #CJK UNIFIED IDEOGRAPH + {0xCCB4, 0x62B4}, //6364 #CJK UNIFIED IDEOGRAPH + {0xCCB5, 0x62D1}, //6365 #CJK UNIFIED IDEOGRAPH + {0xCCB6, 0x62BE}, //6366 #CJK UNIFIED IDEOGRAPH + {0xCCB7, 0x62AA}, //6367 #CJK UNIFIED IDEOGRAPH + {0xCCB8, 0x62B6}, //6368 #CJK UNIFIED IDEOGRAPH + {0xCCB9, 0x62CA}, //6369 #CJK UNIFIED IDEOGRAPH + {0xCCBA, 0x62AE}, //6370 #CJK UNIFIED IDEOGRAPH + {0xCCBB, 0x62B3}, //6371 #CJK UNIFIED IDEOGRAPH + {0xCCBC, 0x62AF}, //6372 #CJK UNIFIED IDEOGRAPH + {0xCCBD, 0x62BB}, //6373 #CJK UNIFIED IDEOGRAPH + {0xCCBE, 0x62A9}, //6374 #CJK UNIFIED IDEOGRAPH + {0xCCBF, 0x62B0}, //6375 #CJK UNIFIED IDEOGRAPH + {0xCCC0, 0x62B8}, //6376 #CJK UNIFIED IDEOGRAPH + {0xCCC1, 0x653D}, //6377 #CJK UNIFIED IDEOGRAPH + {0xCCC2, 0x65A8}, //6378 #CJK UNIFIED IDEOGRAPH + {0xCCC3, 0x65BB}, //6379 #CJK UNIFIED IDEOGRAPH + {0xCCC4, 0x6609}, //6380 #CJK UNIFIED IDEOGRAPH + {0xCCC5, 0x65FC}, //6381 #CJK UNIFIED IDEOGRAPH + {0xCCC6, 0x6604}, //6382 #CJK UNIFIED IDEOGRAPH + {0xCCC7, 0x6612}, //6383 #CJK UNIFIED IDEOGRAPH + {0xCCC8, 0x6608}, //6384 #CJK UNIFIED IDEOGRAPH + {0xCCC9, 0x65FB}, //6385 #CJK UNIFIED IDEOGRAPH + {0xCCCA, 0x6603}, //6386 #CJK UNIFIED IDEOGRAPH + {0xCCCB, 0x660B}, //6387 #CJK UNIFIED IDEOGRAPH + {0xCCCC, 0x660D}, //6388 #CJK UNIFIED IDEOGRAPH + {0xCCCD, 0x6605}, //6389 #CJK UNIFIED IDEOGRAPH + {0xCCCE, 0x65FD}, //6390 #CJK UNIFIED IDEOGRAPH + {0xCCCF, 0x6611}, //6391 #CJK UNIFIED IDEOGRAPH + {0xCCD0, 0x6610}, //6392 #CJK UNIFIED IDEOGRAPH + {0xCCD1, 0x66F6}, //6393 #CJK UNIFIED IDEOGRAPH + {0xCCD2, 0x670A}, //6394 #CJK UNIFIED IDEOGRAPH + {0xCCD3, 0x6785}, //6395 #CJK UNIFIED IDEOGRAPH + {0xCCD4, 0x676C}, //6396 #CJK UNIFIED IDEOGRAPH + {0xCCD5, 0x678E}, //6397 #CJK UNIFIED IDEOGRAPH + {0xCCD6, 0x6792}, //6398 #CJK UNIFIED IDEOGRAPH + {0xCCD7, 0x6776}, //6399 #CJK UNIFIED IDEOGRAPH + {0xCCD8, 0x677B}, //6400 #CJK UNIFIED IDEOGRAPH + {0xCCD9, 0x6798}, //6401 #CJK UNIFIED IDEOGRAPH + {0xCCDA, 0x6786}, //6402 #CJK UNIFIED IDEOGRAPH + {0xCCDB, 0x6784}, //6403 #CJK UNIFIED IDEOGRAPH + {0xCCDC, 0x6774}, //6404 #CJK UNIFIED IDEOGRAPH + {0xCCDD, 0x678D}, //6405 #CJK UNIFIED IDEOGRAPH + {0xCCDE, 0x678C}, //6406 #CJK UNIFIED IDEOGRAPH + {0xCCDF, 0x677A}, //6407 #CJK UNIFIED IDEOGRAPH + {0xCCE0, 0x679F}, //6408 #CJK UNIFIED IDEOGRAPH + {0xCCE1, 0x6791}, //6409 #CJK UNIFIED IDEOGRAPH + {0xCCE2, 0x6799}, //6410 #CJK UNIFIED IDEOGRAPH + {0xCCE3, 0x6783}, //6411 #CJK UNIFIED IDEOGRAPH + {0xCCE4, 0x677D}, //6412 #CJK UNIFIED IDEOGRAPH + {0xCCE5, 0x6781}, //6413 #CJK UNIFIED IDEOGRAPH + {0xCCE6, 0x6778}, //6414 #CJK UNIFIED IDEOGRAPH + {0xCCE7, 0x6779}, //6415 #CJK UNIFIED IDEOGRAPH + {0xCCE8, 0x6794}, //6416 #CJK UNIFIED IDEOGRAPH + {0xCCE9, 0x6B25}, //6417 #CJK UNIFIED IDEOGRAPH + {0xCCEA, 0x6B80}, //6418 #CJK UNIFIED IDEOGRAPH + {0xCCEB, 0x6B7E}, //6419 #CJK UNIFIED IDEOGRAPH + {0xCCEC, 0x6BDE}, //6420 #CJK UNIFIED IDEOGRAPH + {0xCCED, 0x6C1D}, //6421 #CJK UNIFIED IDEOGRAPH + {0xCCEE, 0x6C93}, //6422 #CJK UNIFIED IDEOGRAPH + {0xCCEF, 0x6CEC}, //6423 #CJK UNIFIED IDEOGRAPH + {0xCCF0, 0x6CEB}, //6424 #CJK UNIFIED IDEOGRAPH + {0xCCF1, 0x6CEE}, //6425 #CJK UNIFIED IDEOGRAPH + {0xCCF2, 0x6CD9}, //6426 #CJK UNIFIED IDEOGRAPH + {0xCCF3, 0x6CB6}, //6427 #CJK UNIFIED IDEOGRAPH + {0xCCF4, 0x6CD4}, //6428 #CJK UNIFIED IDEOGRAPH + {0xCCF5, 0x6CAD}, //6429 #CJK UNIFIED IDEOGRAPH + {0xCCF6, 0x6CE7}, //6430 #CJK UNIFIED IDEOGRAPH + {0xCCF7, 0x6CB7}, //6431 #CJK UNIFIED IDEOGRAPH + {0xCCF8, 0x6CD0}, //6432 #CJK UNIFIED IDEOGRAPH + {0xCCF9, 0x6CC2}, //6433 #CJK UNIFIED IDEOGRAPH + {0xCCFA, 0x6CBA}, //6434 #CJK UNIFIED IDEOGRAPH + {0xCCFB, 0x6CC3}, //6435 #CJK UNIFIED IDEOGRAPH + {0xCCFC, 0x6CC6}, //6436 #CJK UNIFIED IDEOGRAPH + {0xCCFD, 0x6CED}, //6437 #CJK UNIFIED IDEOGRAPH + {0xCCFE, 0x6CF2}, //6438 #CJK UNIFIED IDEOGRAPH + {0xCD40, 0x6CD2}, //6439 #CJK UNIFIED IDEOGRAPH + {0xCD41, 0x6CDD}, //6440 #CJK UNIFIED IDEOGRAPH + {0xCD42, 0x6CB4}, //6441 #CJK UNIFIED IDEOGRAPH + {0xCD43, 0x6C8A}, //6442 #CJK UNIFIED IDEOGRAPH + {0xCD44, 0x6C9D}, //6443 #CJK UNIFIED IDEOGRAPH + {0xCD45, 0x6C80}, //6444 #CJK UNIFIED IDEOGRAPH + {0xCD46, 0x6CDE}, //6445 #CJK UNIFIED IDEOGRAPH + {0xCD47, 0x6CC0}, //6446 #CJK UNIFIED IDEOGRAPH + {0xCD48, 0x6D30}, //6447 #CJK UNIFIED IDEOGRAPH + {0xCD49, 0x6CCD}, //6448 #CJK UNIFIED IDEOGRAPH + {0xCD4A, 0x6CC7}, //6449 #CJK UNIFIED IDEOGRAPH + {0xCD4B, 0x6CB0}, //6450 #CJK UNIFIED IDEOGRAPH + {0xCD4C, 0x6CF9}, //6451 #CJK UNIFIED IDEOGRAPH + {0xCD4D, 0x6CCF}, //6452 #CJK UNIFIED IDEOGRAPH + {0xCD4E, 0x6CE9}, //6453 #CJK UNIFIED IDEOGRAPH + {0xCD4F, 0x6CD1}, //6454 #CJK UNIFIED IDEOGRAPH + {0xCD50, 0x7094}, //6455 #CJK UNIFIED IDEOGRAPH + {0xCD51, 0x7098}, //6456 #CJK UNIFIED IDEOGRAPH + {0xCD52, 0x7085}, //6457 #CJK UNIFIED IDEOGRAPH + {0xCD53, 0x7093}, //6458 #CJK UNIFIED IDEOGRAPH + {0xCD54, 0x7086}, //6459 #CJK UNIFIED IDEOGRAPH + {0xCD55, 0x7084}, //6460 #CJK UNIFIED IDEOGRAPH + {0xCD56, 0x7091}, //6461 #CJK UNIFIED IDEOGRAPH + {0xCD57, 0x7096}, //6462 #CJK UNIFIED IDEOGRAPH + {0xCD58, 0x7082}, //6463 #CJK UNIFIED IDEOGRAPH + {0xCD59, 0x709A}, //6464 #CJK UNIFIED IDEOGRAPH + {0xCD5A, 0x7083}, //6465 #CJK UNIFIED IDEOGRAPH + {0xCD5B, 0x726A}, //6466 #CJK UNIFIED IDEOGRAPH + {0xCD5C, 0x72D6}, //6467 #CJK UNIFIED IDEOGRAPH + {0xCD5D, 0x72CB}, //6468 #CJK UNIFIED IDEOGRAPH + {0xCD5E, 0x72D8}, //6469 #CJK UNIFIED IDEOGRAPH + {0xCD5F, 0x72C9}, //6470 #CJK UNIFIED IDEOGRAPH + {0xCD60, 0x72DC}, //6471 #CJK UNIFIED IDEOGRAPH + {0xCD61, 0x72D2}, //6472 #CJK UNIFIED IDEOGRAPH + {0xCD62, 0x72D4}, //6473 #CJK UNIFIED IDEOGRAPH + {0xCD63, 0x72DA}, //6474 #CJK UNIFIED IDEOGRAPH + {0xCD64, 0x72CC}, //6475 #CJK UNIFIED IDEOGRAPH + {0xCD65, 0x72D1}, //6476 #CJK UNIFIED IDEOGRAPH + {0xCD66, 0x73A4}, //6477 #CJK UNIFIED IDEOGRAPH + {0xCD67, 0x73A1}, //6478 #CJK UNIFIED IDEOGRAPH + {0xCD68, 0x73AD}, //6479 #CJK UNIFIED IDEOGRAPH + {0xCD69, 0x73A6}, //6480 #CJK UNIFIED IDEOGRAPH + {0xCD6A, 0x73A2}, //6481 #CJK UNIFIED IDEOGRAPH + {0xCD6B, 0x73A0}, //6482 #CJK UNIFIED IDEOGRAPH + {0xCD6C, 0x73AC}, //6483 #CJK UNIFIED IDEOGRAPH + {0xCD6D, 0x739D}, //6484 #CJK UNIFIED IDEOGRAPH + {0xCD6E, 0x74DD}, //6485 #CJK UNIFIED IDEOGRAPH + {0xCD6F, 0x74E8}, //6486 #CJK UNIFIED IDEOGRAPH + {0xCD70, 0x753F}, //6487 #CJK UNIFIED IDEOGRAPH + {0xCD71, 0x7540}, //6488 #CJK UNIFIED IDEOGRAPH + {0xCD72, 0x753E}, //6489 #CJK UNIFIED IDEOGRAPH + {0xCD73, 0x758C}, //6490 #CJK UNIFIED IDEOGRAPH + {0xCD74, 0x7598}, //6491 #CJK UNIFIED IDEOGRAPH + {0xCD75, 0x76AF}, //6492 #CJK UNIFIED IDEOGRAPH + {0xCD76, 0x76F3}, //6493 #CJK UNIFIED IDEOGRAPH + {0xCD77, 0x76F1}, //6494 #CJK UNIFIED IDEOGRAPH + {0xCD78, 0x76F0}, //6495 #CJK UNIFIED IDEOGRAPH + {0xCD79, 0x76F5}, //6496 #CJK UNIFIED IDEOGRAPH + {0xCD7A, 0x77F8}, //6497 #CJK UNIFIED IDEOGRAPH + {0xCD7B, 0x77FC}, //6498 #CJK UNIFIED IDEOGRAPH + {0xCD7C, 0x77F9}, //6499 #CJK UNIFIED IDEOGRAPH + {0xCD7D, 0x77FB}, //6500 #CJK UNIFIED IDEOGRAPH + {0xCD7E, 0x77FA}, //6501 #CJK UNIFIED IDEOGRAPH + {0xCDA1, 0x77F7}, //6502 #CJK UNIFIED IDEOGRAPH + {0xCDA2, 0x7942}, //6503 #CJK UNIFIED IDEOGRAPH + {0xCDA3, 0x793F}, //6504 #CJK UNIFIED IDEOGRAPH + {0xCDA4, 0x79C5}, //6505 #CJK UNIFIED IDEOGRAPH + {0xCDA5, 0x7A78}, //6506 #CJK UNIFIED IDEOGRAPH + {0xCDA6, 0x7A7B}, //6507 #CJK UNIFIED IDEOGRAPH + {0xCDA7, 0x7AFB}, //6508 #CJK UNIFIED IDEOGRAPH + {0xCDA8, 0x7C75}, //6509 #CJK UNIFIED IDEOGRAPH + {0xCDA9, 0x7CFD}, //6510 #CJK UNIFIED IDEOGRAPH + {0xCDAA, 0x8035}, //6511 #CJK UNIFIED IDEOGRAPH + {0xCDAB, 0x808F}, //6512 #CJK UNIFIED IDEOGRAPH + {0xCDAC, 0x80AE}, //6513 #CJK UNIFIED IDEOGRAPH + {0xCDAD, 0x80A3}, //6514 #CJK UNIFIED IDEOGRAPH + {0xCDAE, 0x80B8}, //6515 #CJK UNIFIED IDEOGRAPH + {0xCDAF, 0x80B5}, //6516 #CJK UNIFIED IDEOGRAPH + {0xCDB0, 0x80AD}, //6517 #CJK UNIFIED IDEOGRAPH + {0xCDB1, 0x8220}, //6518 #CJK UNIFIED IDEOGRAPH + {0xCDB2, 0x82A0}, //6519 #CJK UNIFIED IDEOGRAPH + {0xCDB3, 0x82C0}, //6520 #CJK UNIFIED IDEOGRAPH + {0xCDB4, 0x82AB}, //6521 #CJK UNIFIED IDEOGRAPH + {0xCDB5, 0x829A}, //6522 #CJK UNIFIED IDEOGRAPH + {0xCDB6, 0x8298}, //6523 #CJK UNIFIED IDEOGRAPH + {0xCDB7, 0x829B}, //6524 #CJK UNIFIED IDEOGRAPH + {0xCDB8, 0x82B5}, //6525 #CJK UNIFIED IDEOGRAPH + {0xCDB9, 0x82A7}, //6526 #CJK UNIFIED IDEOGRAPH + {0xCDBA, 0x82AE}, //6527 #CJK UNIFIED IDEOGRAPH + {0xCDBB, 0x82BC}, //6528 #CJK UNIFIED IDEOGRAPH + {0xCDBC, 0x829E}, //6529 #CJK UNIFIED IDEOGRAPH + {0xCDBD, 0x82BA}, //6530 #CJK UNIFIED IDEOGRAPH + {0xCDBE, 0x82B4}, //6531 #CJK UNIFIED IDEOGRAPH + {0xCDBF, 0x82A8}, //6532 #CJK UNIFIED IDEOGRAPH + {0xCDC0, 0x82A1}, //6533 #CJK UNIFIED IDEOGRAPH + {0xCDC1, 0x82A9}, //6534 #CJK UNIFIED IDEOGRAPH + {0xCDC2, 0x82C2}, //6535 #CJK UNIFIED IDEOGRAPH + {0xCDC3, 0x82A4}, //6536 #CJK UNIFIED IDEOGRAPH + {0xCDC4, 0x82C3}, //6537 #CJK UNIFIED IDEOGRAPH + {0xCDC5, 0x82B6}, //6538 #CJK UNIFIED IDEOGRAPH + {0xCDC6, 0x82A2}, //6539 #CJK UNIFIED IDEOGRAPH + {0xCDC7, 0x8670}, //6540 #CJK UNIFIED IDEOGRAPH + {0xCDC8, 0x866F}, //6541 #CJK UNIFIED IDEOGRAPH + {0xCDC9, 0x866D}, //6542 #CJK UNIFIED IDEOGRAPH + {0xCDCA, 0x866E}, //6543 #CJK UNIFIED IDEOGRAPH + {0xCDCB, 0x8C56}, //6544 #CJK UNIFIED IDEOGRAPH + {0xCDCC, 0x8FD2}, //6545 #CJK UNIFIED IDEOGRAPH + {0xCDCD, 0x8FCB}, //6546 #CJK UNIFIED IDEOGRAPH + {0xCDCE, 0x8FD3}, //6547 #CJK UNIFIED IDEOGRAPH + {0xCDCF, 0x8FCD}, //6548 #CJK UNIFIED IDEOGRAPH + {0xCDD0, 0x8FD6}, //6549 #CJK UNIFIED IDEOGRAPH + {0xCDD1, 0x8FD5}, //6550 #CJK UNIFIED IDEOGRAPH + {0xCDD2, 0x8FD7}, //6551 #CJK UNIFIED IDEOGRAPH + {0xCDD3, 0x90B2}, //6552 #CJK UNIFIED IDEOGRAPH + {0xCDD4, 0x90B4}, //6553 #CJK UNIFIED IDEOGRAPH + {0xCDD5, 0x90AF}, //6554 #CJK UNIFIED IDEOGRAPH + {0xCDD6, 0x90B3}, //6555 #CJK UNIFIED IDEOGRAPH + {0xCDD7, 0x90B0}, //6556 #CJK UNIFIED IDEOGRAPH + {0xCDD8, 0x9639}, //6557 #CJK UNIFIED IDEOGRAPH + {0xCDD9, 0x963D}, //6558 #CJK UNIFIED IDEOGRAPH + {0xCDDA, 0x963C}, //6559 #CJK UNIFIED IDEOGRAPH + {0xCDDB, 0x963A}, //6560 #CJK UNIFIED IDEOGRAPH + {0xCDDC, 0x9643}, //6561 #CJK UNIFIED IDEOGRAPH + {0xCDDD, 0x4FCD}, //6562 #CJK UNIFIED IDEOGRAPH + {0xCDDE, 0x4FC5}, //6563 #CJK UNIFIED IDEOGRAPH + {0xCDDF, 0x4FD3}, //6564 #CJK UNIFIED IDEOGRAPH + {0xCDE0, 0x4FB2}, //6565 #CJK UNIFIED IDEOGRAPH + {0xCDE1, 0x4FC9}, //6566 #CJK UNIFIED IDEOGRAPH + {0xCDE2, 0x4FCB}, //6567 #CJK UNIFIED IDEOGRAPH + {0xCDE3, 0x4FC1}, //6568 #CJK UNIFIED IDEOGRAPH + {0xCDE4, 0x4FD4}, //6569 #CJK UNIFIED IDEOGRAPH + {0xCDE5, 0x4FDC}, //6570 #CJK UNIFIED IDEOGRAPH + {0xCDE6, 0x4FD9}, //6571 #CJK UNIFIED IDEOGRAPH + {0xCDE7, 0x4FBB}, //6572 #CJK UNIFIED IDEOGRAPH + {0xCDE8, 0x4FB3}, //6573 #CJK UNIFIED IDEOGRAPH + {0xCDE9, 0x4FDB}, //6574 #CJK UNIFIED IDEOGRAPH + {0xCDEA, 0x4FC7}, //6575 #CJK UNIFIED IDEOGRAPH + {0xCDEB, 0x4FD6}, //6576 #CJK UNIFIED IDEOGRAPH + {0xCDEC, 0x4FBA}, //6577 #CJK UNIFIED IDEOGRAPH + {0xCDED, 0x4FC0}, //6578 #CJK UNIFIED IDEOGRAPH + {0xCDEE, 0x4FB9}, //6579 #CJK UNIFIED IDEOGRAPH + {0xCDEF, 0x4FEC}, //6580 #CJK UNIFIED IDEOGRAPH + {0xCDF0, 0x5244}, //6581 #CJK UNIFIED IDEOGRAPH + {0xCDF1, 0x5249}, //6582 #CJK UNIFIED IDEOGRAPH + {0xCDF2, 0x52C0}, //6583 #CJK UNIFIED IDEOGRAPH + {0xCDF3, 0x52C2}, //6584 #CJK UNIFIED IDEOGRAPH + {0xCDF4, 0x533D}, //6585 #CJK UNIFIED IDEOGRAPH + {0xCDF5, 0x537C}, //6586 #CJK UNIFIED IDEOGRAPH + {0xCDF6, 0x5397}, //6587 #CJK UNIFIED IDEOGRAPH + {0xCDF7, 0x5396}, //6588 #CJK UNIFIED IDEOGRAPH + {0xCDF8, 0x5399}, //6589 #CJK UNIFIED IDEOGRAPH + {0xCDF9, 0x5398}, //6590 #CJK UNIFIED IDEOGRAPH + {0xCDFA, 0x54BA}, //6591 #CJK UNIFIED IDEOGRAPH + {0xCDFB, 0x54A1}, //6592 #CJK UNIFIED IDEOGRAPH + {0xCDFC, 0x54AD}, //6593 #CJK UNIFIED IDEOGRAPH + {0xCDFD, 0x54A5}, //6594 #CJK UNIFIED IDEOGRAPH + {0xCDFE, 0x54CF}, //6595 #CJK UNIFIED IDEOGRAPH + {0xCE40, 0x54C3}, //6596 #CJK UNIFIED IDEOGRAPH + {0xCE41, 0x830D}, //6597 #CJK UNIFIED IDEOGRAPH + {0xCE42, 0x54B7}, //6598 #CJK UNIFIED IDEOGRAPH + {0xCE43, 0x54AE}, //6599 #CJK UNIFIED IDEOGRAPH + {0xCE44, 0x54D6}, //6600 #CJK UNIFIED IDEOGRAPH + {0xCE45, 0x54B6}, //6601 #CJK UNIFIED IDEOGRAPH + {0xCE46, 0x54C5}, //6602 #CJK UNIFIED IDEOGRAPH + {0xCE47, 0x54C6}, //6603 #CJK UNIFIED IDEOGRAPH + {0xCE48, 0x54A0}, //6604 #CJK UNIFIED IDEOGRAPH + {0xCE49, 0x5470}, //6605 #CJK UNIFIED IDEOGRAPH + {0xCE4A, 0x54BC}, //6606 #CJK UNIFIED IDEOGRAPH + {0xCE4B, 0x54A2}, //6607 #CJK UNIFIED IDEOGRAPH + {0xCE4C, 0x54BE}, //6608 #CJK UNIFIED IDEOGRAPH + {0xCE4D, 0x5472}, //6609 #CJK UNIFIED IDEOGRAPH + {0xCE4E, 0x54DE}, //6610 #CJK UNIFIED IDEOGRAPH + {0xCE4F, 0x54B0}, //6611 #CJK UNIFIED IDEOGRAPH + {0xCE50, 0x57B5}, //6612 #CJK UNIFIED IDEOGRAPH + {0xCE51, 0x579E}, //6613 #CJK UNIFIED IDEOGRAPH + {0xCE52, 0x579F}, //6614 #CJK UNIFIED IDEOGRAPH + {0xCE53, 0x57A4}, //6615 #CJK UNIFIED IDEOGRAPH + {0xCE54, 0x578C}, //6616 #CJK UNIFIED IDEOGRAPH + {0xCE55, 0x5797}, //6617 #CJK UNIFIED IDEOGRAPH + {0xCE56, 0x579D}, //6618 #CJK UNIFIED IDEOGRAPH + {0xCE57, 0x579B}, //6619 #CJK UNIFIED IDEOGRAPH + {0xCE58, 0x5794}, //6620 #CJK UNIFIED IDEOGRAPH + {0xCE59, 0x5798}, //6621 #CJK UNIFIED IDEOGRAPH + {0xCE5A, 0x578F}, //6622 #CJK UNIFIED IDEOGRAPH + {0xCE5B, 0x5799}, //6623 #CJK UNIFIED IDEOGRAPH + {0xCE5C, 0x57A5}, //6624 #CJK UNIFIED IDEOGRAPH + {0xCE5D, 0x579A}, //6625 #CJK UNIFIED IDEOGRAPH + {0xCE5E, 0x5795}, //6626 #CJK UNIFIED IDEOGRAPH + {0xCE5F, 0x58F4}, //6627 #CJK UNIFIED IDEOGRAPH + {0xCE60, 0x590D}, //6628 #CJK UNIFIED IDEOGRAPH + {0xCE61, 0x5953}, //6629 #CJK UNIFIED IDEOGRAPH + {0xCE62, 0x59E1}, //6630 #CJK UNIFIED IDEOGRAPH + {0xCE63, 0x59DE}, //6631 #CJK UNIFIED IDEOGRAPH + {0xCE64, 0x59EE}, //6632 #CJK UNIFIED IDEOGRAPH + {0xCE65, 0x5A00}, //6633 #CJK UNIFIED IDEOGRAPH + {0xCE66, 0x59F1}, //6634 #CJK UNIFIED IDEOGRAPH + {0xCE67, 0x59DD}, //6635 #CJK UNIFIED IDEOGRAPH + {0xCE68, 0x59FA}, //6636 #CJK UNIFIED IDEOGRAPH + {0xCE69, 0x59FD}, //6637 #CJK UNIFIED IDEOGRAPH + {0xCE6A, 0x59FC}, //6638 #CJK UNIFIED IDEOGRAPH + {0xCE6B, 0x59F6}, //6639 #CJK UNIFIED IDEOGRAPH + {0xCE6C, 0x59E4}, //6640 #CJK UNIFIED IDEOGRAPH + {0xCE6D, 0x59F2}, //6641 #CJK UNIFIED IDEOGRAPH + {0xCE6E, 0x59F7}, //6642 #CJK UNIFIED IDEOGRAPH + {0xCE6F, 0x59DB}, //6643 #CJK UNIFIED IDEOGRAPH + {0xCE70, 0x59E9}, //6644 #CJK UNIFIED IDEOGRAPH + {0xCE71, 0x59F3}, //6645 #CJK UNIFIED IDEOGRAPH + {0xCE72, 0x59F5}, //6646 #CJK UNIFIED IDEOGRAPH + {0xCE73, 0x59E0}, //6647 #CJK UNIFIED IDEOGRAPH + {0xCE74, 0x59FE}, //6648 #CJK UNIFIED IDEOGRAPH + {0xCE75, 0x59F4}, //6649 #CJK UNIFIED IDEOGRAPH + {0xCE76, 0x59ED}, //6650 #CJK UNIFIED IDEOGRAPH + {0xCE77, 0x5BA8}, //6651 #CJK UNIFIED IDEOGRAPH + {0xCE78, 0x5C4C}, //6652 #CJK UNIFIED IDEOGRAPH + {0xCE79, 0x5CD0}, //6653 #CJK UNIFIED IDEOGRAPH + {0xCE7A, 0x5CD8}, //6654 #CJK UNIFIED IDEOGRAPH + {0xCE7B, 0x5CCC}, //6655 #CJK UNIFIED IDEOGRAPH + {0xCE7C, 0x5CD7}, //6656 #CJK UNIFIED IDEOGRAPH + {0xCE7D, 0x5CCB}, //6657 #CJK UNIFIED IDEOGRAPH + {0xCE7E, 0x5CDB}, //6658 #CJK UNIFIED IDEOGRAPH + {0xCEA1, 0x5CDE}, //6659 #CJK UNIFIED IDEOGRAPH + {0xCEA2, 0x5CDA}, //6660 #CJK UNIFIED IDEOGRAPH + {0xCEA3, 0x5CC9}, //6661 #CJK UNIFIED IDEOGRAPH + {0xCEA4, 0x5CC7}, //6662 #CJK UNIFIED IDEOGRAPH + {0xCEA5, 0x5CCA}, //6663 #CJK UNIFIED IDEOGRAPH + {0xCEA6, 0x5CD6}, //6664 #CJK UNIFIED IDEOGRAPH + {0xCEA7, 0x5CD3}, //6665 #CJK UNIFIED IDEOGRAPH + {0xCEA8, 0x5CD4}, //6666 #CJK UNIFIED IDEOGRAPH + {0xCEA9, 0x5CCF}, //6667 #CJK UNIFIED IDEOGRAPH + {0xCEAA, 0x5CC8}, //6668 #CJK UNIFIED IDEOGRAPH + {0xCEAB, 0x5CC6}, //6669 #CJK UNIFIED IDEOGRAPH + {0xCEAC, 0x5CCE}, //6670 #CJK UNIFIED IDEOGRAPH + {0xCEAD, 0x5CDF}, //6671 #CJK UNIFIED IDEOGRAPH + {0xCEAE, 0x5CF8}, //6672 #CJK UNIFIED IDEOGRAPH + {0xCEAF, 0x5DF9}, //6673 #CJK UNIFIED IDEOGRAPH + {0xCEB0, 0x5E21}, //6674 #CJK UNIFIED IDEOGRAPH + {0xCEB1, 0x5E22}, //6675 #CJK UNIFIED IDEOGRAPH + {0xCEB2, 0x5E23}, //6676 #CJK UNIFIED IDEOGRAPH + {0xCEB3, 0x5E20}, //6677 #CJK UNIFIED IDEOGRAPH + {0xCEB4, 0x5E24}, //6678 #CJK UNIFIED IDEOGRAPH + {0xCEB5, 0x5EB0}, //6679 #CJK UNIFIED IDEOGRAPH + {0xCEB6, 0x5EA4}, //6680 #CJK UNIFIED IDEOGRAPH + {0xCEB7, 0x5EA2}, //6681 #CJK UNIFIED IDEOGRAPH + {0xCEB8, 0x5E9B}, //6682 #CJK UNIFIED IDEOGRAPH + {0xCEB9, 0x5EA3}, //6683 #CJK UNIFIED IDEOGRAPH + {0xCEBA, 0x5EA5}, //6684 #CJK UNIFIED IDEOGRAPH + {0xCEBB, 0x5F07}, //6685 #CJK UNIFIED IDEOGRAPH + {0xCEBC, 0x5F2E}, //6686 #CJK UNIFIED IDEOGRAPH + {0xCEBD, 0x5F56}, //6687 #CJK UNIFIED IDEOGRAPH + {0xCEBE, 0x5F86}, //6688 #CJK UNIFIED IDEOGRAPH + {0xCEBF, 0x6037}, //6689 #CJK UNIFIED IDEOGRAPH + {0xCEC0, 0x6039}, //6690 #CJK UNIFIED IDEOGRAPH + {0xCEC1, 0x6054}, //6691 #CJK UNIFIED IDEOGRAPH + {0xCEC2, 0x6072}, //6692 #CJK UNIFIED IDEOGRAPH + {0xCEC3, 0x605E}, //6693 #CJK UNIFIED IDEOGRAPH + {0xCEC4, 0x6045}, //6694 #CJK UNIFIED IDEOGRAPH + {0xCEC5, 0x6053}, //6695 #CJK UNIFIED IDEOGRAPH + {0xCEC6, 0x6047}, //6696 #CJK UNIFIED IDEOGRAPH + {0xCEC7, 0x6049}, //6697 #CJK UNIFIED IDEOGRAPH + {0xCEC8, 0x605B}, //6698 #CJK UNIFIED IDEOGRAPH + {0xCEC9, 0x604C}, //6699 #CJK UNIFIED IDEOGRAPH + {0xCECA, 0x6040}, //6700 #CJK UNIFIED IDEOGRAPH + {0xCECB, 0x6042}, //6701 #CJK UNIFIED IDEOGRAPH + {0xCECC, 0x605F}, //6702 #CJK UNIFIED IDEOGRAPH + {0xCECD, 0x6024}, //6703 #CJK UNIFIED IDEOGRAPH + {0xCECE, 0x6044}, //6704 #CJK UNIFIED IDEOGRAPH + {0xCECF, 0x6058}, //6705 #CJK UNIFIED IDEOGRAPH + {0xCED0, 0x6066}, //6706 #CJK UNIFIED IDEOGRAPH + {0xCED1, 0x606E}, //6707 #CJK UNIFIED IDEOGRAPH + {0xCED2, 0x6242}, //6708 #CJK UNIFIED IDEOGRAPH + {0xCED3, 0x6243}, //6709 #CJK UNIFIED IDEOGRAPH + {0xCED4, 0x62CF}, //6710 #CJK UNIFIED IDEOGRAPH + {0xCED5, 0x630D}, //6711 #CJK UNIFIED IDEOGRAPH + {0xCED6, 0x630B}, //6712 #CJK UNIFIED IDEOGRAPH + {0xCED7, 0x62F5}, //6713 #CJK UNIFIED IDEOGRAPH + {0xCED8, 0x630E}, //6714 #CJK UNIFIED IDEOGRAPH + {0xCED9, 0x6303}, //6715 #CJK UNIFIED IDEOGRAPH + {0xCEDA, 0x62EB}, //6716 #CJK UNIFIED IDEOGRAPH + {0xCEDB, 0x62F9}, //6717 #CJK UNIFIED IDEOGRAPH + {0xCEDC, 0x630F}, //6718 #CJK UNIFIED IDEOGRAPH + {0xCEDD, 0x630C}, //6719 #CJK UNIFIED IDEOGRAPH + {0xCEDE, 0x62F8}, //6720 #CJK UNIFIED IDEOGRAPH + {0xCEDF, 0x62F6}, //6721 #CJK UNIFIED IDEOGRAPH + {0xCEE0, 0x6300}, //6722 #CJK UNIFIED IDEOGRAPH + {0xCEE1, 0x6313}, //6723 #CJK UNIFIED IDEOGRAPH + {0xCEE2, 0x6314}, //6724 #CJK UNIFIED IDEOGRAPH + {0xCEE3, 0x62FA}, //6725 #CJK UNIFIED IDEOGRAPH + {0xCEE4, 0x6315}, //6726 #CJK UNIFIED IDEOGRAPH + {0xCEE5, 0x62FB}, //6727 #CJK UNIFIED IDEOGRAPH + {0xCEE6, 0x62F0}, //6728 #CJK UNIFIED IDEOGRAPH + {0xCEE7, 0x6541}, //6729 #CJK UNIFIED IDEOGRAPH + {0xCEE8, 0x6543}, //6730 #CJK UNIFIED IDEOGRAPH + {0xCEE9, 0x65AA}, //6731 #CJK UNIFIED IDEOGRAPH + {0xCEEA, 0x65BF}, //6732 #CJK UNIFIED IDEOGRAPH + {0xCEEB, 0x6636}, //6733 #CJK UNIFIED IDEOGRAPH + {0xCEEC, 0x6621}, //6734 #CJK UNIFIED IDEOGRAPH + {0xCEED, 0x6632}, //6735 #CJK UNIFIED IDEOGRAPH + {0xCEEE, 0x6635}, //6736 #CJK UNIFIED IDEOGRAPH + {0xCEEF, 0x661C}, //6737 #CJK UNIFIED IDEOGRAPH + {0xCEF0, 0x6626}, //6738 #CJK UNIFIED IDEOGRAPH + {0xCEF1, 0x6622}, //6739 #CJK UNIFIED IDEOGRAPH + {0xCEF2, 0x6633}, //6740 #CJK UNIFIED IDEOGRAPH + {0xCEF3, 0x662B}, //6741 #CJK UNIFIED IDEOGRAPH + {0xCEF4, 0x663A}, //6742 #CJK UNIFIED IDEOGRAPH + {0xCEF5, 0x661D}, //6743 #CJK UNIFIED IDEOGRAPH + {0xCEF6, 0x6634}, //6744 #CJK UNIFIED IDEOGRAPH + {0xCEF7, 0x6639}, //6745 #CJK UNIFIED IDEOGRAPH + {0xCEF8, 0x662E}, //6746 #CJK UNIFIED IDEOGRAPH + {0xCEF9, 0x670F}, //6747 #CJK UNIFIED IDEOGRAPH + {0xCEFA, 0x6710}, //6748 #CJK UNIFIED IDEOGRAPH + {0xCEFB, 0x67C1}, //6749 #CJK UNIFIED IDEOGRAPH + {0xCEFC, 0x67F2}, //6750 #CJK UNIFIED IDEOGRAPH + {0xCEFD, 0x67C8}, //6751 #CJK UNIFIED IDEOGRAPH + {0xCEFE, 0x67BA}, //6752 #CJK UNIFIED IDEOGRAPH + {0xCF40, 0x67DC}, //6753 #CJK UNIFIED IDEOGRAPH + {0xCF41, 0x67BB}, //6754 #CJK UNIFIED IDEOGRAPH + {0xCF42, 0x67F8}, //6755 #CJK UNIFIED IDEOGRAPH + {0xCF43, 0x67D8}, //6756 #CJK UNIFIED IDEOGRAPH + {0xCF44, 0x67C0}, //6757 #CJK UNIFIED IDEOGRAPH + {0xCF45, 0x67B7}, //6758 #CJK UNIFIED IDEOGRAPH + {0xCF46, 0x67C5}, //6759 #CJK UNIFIED IDEOGRAPH + {0xCF47, 0x67EB}, //6760 #CJK UNIFIED IDEOGRAPH + {0xCF48, 0x67E4}, //6761 #CJK UNIFIED IDEOGRAPH + {0xCF49, 0x67DF}, //6762 #CJK UNIFIED IDEOGRAPH + {0xCF4A, 0x67B5}, //6763 #CJK UNIFIED IDEOGRAPH + {0xCF4B, 0x67CD}, //6764 #CJK UNIFIED IDEOGRAPH + {0xCF4C, 0x67B3}, //6765 #CJK UNIFIED IDEOGRAPH + {0xCF4D, 0x67F7}, //6766 #CJK UNIFIED IDEOGRAPH + {0xCF4E, 0x67F6}, //6767 #CJK UNIFIED IDEOGRAPH + {0xCF4F, 0x67EE}, //6768 #CJK UNIFIED IDEOGRAPH + {0xCF50, 0x67E3}, //6769 #CJK UNIFIED IDEOGRAPH + {0xCF51, 0x67C2}, //6770 #CJK UNIFIED IDEOGRAPH + {0xCF52, 0x67B9}, //6771 #CJK UNIFIED IDEOGRAPH + {0xCF53, 0x67CE}, //6772 #CJK UNIFIED IDEOGRAPH + {0xCF54, 0x67E7}, //6773 #CJK UNIFIED IDEOGRAPH + {0xCF55, 0x67F0}, //6774 #CJK UNIFIED IDEOGRAPH + {0xCF56, 0x67B2}, //6775 #CJK UNIFIED IDEOGRAPH + {0xCF57, 0x67FC}, //6776 #CJK UNIFIED IDEOGRAPH + {0xCF58, 0x67C6}, //6777 #CJK UNIFIED IDEOGRAPH + {0xCF59, 0x67ED}, //6778 #CJK UNIFIED IDEOGRAPH + {0xCF5A, 0x67CC}, //6779 #CJK UNIFIED IDEOGRAPH + {0xCF5B, 0x67AE}, //6780 #CJK UNIFIED IDEOGRAPH + {0xCF5C, 0x67E6}, //6781 #CJK UNIFIED IDEOGRAPH + {0xCF5D, 0x67DB}, //6782 #CJK UNIFIED IDEOGRAPH + {0xCF5E, 0x67FA}, //6783 #CJK UNIFIED IDEOGRAPH + {0xCF5F, 0x67C9}, //6784 #CJK UNIFIED IDEOGRAPH + {0xCF60, 0x67CA}, //6785 #CJK UNIFIED IDEOGRAPH + {0xCF61, 0x67C3}, //6786 #CJK UNIFIED IDEOGRAPH + {0xCF62, 0x67EA}, //6787 #CJK UNIFIED IDEOGRAPH + {0xCF63, 0x67CB}, //6788 #CJK UNIFIED IDEOGRAPH + {0xCF64, 0x6B28}, //6789 #CJK UNIFIED IDEOGRAPH + {0xCF65, 0x6B82}, //6790 #CJK UNIFIED IDEOGRAPH + {0xCF66, 0x6B84}, //6791 #CJK UNIFIED IDEOGRAPH + {0xCF67, 0x6BB6}, //6792 #CJK UNIFIED IDEOGRAPH + {0xCF68, 0x6BD6}, //6793 #CJK UNIFIED IDEOGRAPH + {0xCF69, 0x6BD8}, //6794 #CJK UNIFIED IDEOGRAPH + {0xCF6A, 0x6BE0}, //6795 #CJK UNIFIED IDEOGRAPH + {0xCF6B, 0x6C20}, //6796 #CJK UNIFIED IDEOGRAPH + {0xCF6C, 0x6C21}, //6797 #CJK UNIFIED IDEOGRAPH + {0xCF6D, 0x6D28}, //6798 #CJK UNIFIED IDEOGRAPH + {0xCF6E, 0x6D34}, //6799 #CJK UNIFIED IDEOGRAPH + {0xCF6F, 0x6D2D}, //6800 #CJK UNIFIED IDEOGRAPH + {0xCF70, 0x6D1F}, //6801 #CJK UNIFIED IDEOGRAPH + {0xCF71, 0x6D3C}, //6802 #CJK UNIFIED IDEOGRAPH + {0xCF72, 0x6D3F}, //6803 #CJK UNIFIED IDEOGRAPH + {0xCF73, 0x6D12}, //6804 #CJK UNIFIED IDEOGRAPH + {0xCF74, 0x6D0A}, //6805 #CJK UNIFIED IDEOGRAPH + {0xCF75, 0x6CDA}, //6806 #CJK UNIFIED IDEOGRAPH + {0xCF76, 0x6D33}, //6807 #CJK UNIFIED IDEOGRAPH + {0xCF77, 0x6D04}, //6808 #CJK UNIFIED IDEOGRAPH + {0xCF78, 0x6D19}, //6809 #CJK UNIFIED IDEOGRAPH + {0xCF79, 0x6D3A}, //6810 #CJK UNIFIED IDEOGRAPH + {0xCF7A, 0x6D1A}, //6811 #CJK UNIFIED IDEOGRAPH + {0xCF7B, 0x6D11}, //6812 #CJK UNIFIED IDEOGRAPH + {0xCF7C, 0x6D00}, //6813 #CJK UNIFIED IDEOGRAPH + {0xCF7D, 0x6D1D}, //6814 #CJK UNIFIED IDEOGRAPH + {0xCF7E, 0x6D42}, //6815 #CJK UNIFIED IDEOGRAPH + {0xCFA1, 0x6D01}, //6816 #CJK UNIFIED IDEOGRAPH + {0xCFA2, 0x6D18}, //6817 #CJK UNIFIED IDEOGRAPH + {0xCFA3, 0x6D37}, //6818 #CJK UNIFIED IDEOGRAPH + {0xCFA4, 0x6D03}, //6819 #CJK UNIFIED IDEOGRAPH + {0xCFA5, 0x6D0F}, //6820 #CJK UNIFIED IDEOGRAPH + {0xCFA6, 0x6D40}, //6821 #CJK UNIFIED IDEOGRAPH + {0xCFA7, 0x6D07}, //6822 #CJK UNIFIED IDEOGRAPH + {0xCFA8, 0x6D20}, //6823 #CJK UNIFIED IDEOGRAPH + {0xCFA9, 0x6D2C}, //6824 #CJK UNIFIED IDEOGRAPH + {0xCFAA, 0x6D08}, //6825 #CJK UNIFIED IDEOGRAPH + {0xCFAB, 0x6D22}, //6826 #CJK UNIFIED IDEOGRAPH + {0xCFAC, 0x6D09}, //6827 #CJK UNIFIED IDEOGRAPH + {0xCFAD, 0x6D10}, //6828 #CJK UNIFIED IDEOGRAPH + {0xCFAE, 0x70B7}, //6829 #CJK UNIFIED IDEOGRAPH + {0xCFAF, 0x709F}, //6830 #CJK UNIFIED IDEOGRAPH + {0xCFB0, 0x70BE}, //6831 #CJK UNIFIED IDEOGRAPH + {0xCFB1, 0x70B1}, //6832 #CJK UNIFIED IDEOGRAPH + {0xCFB2, 0x70B0}, //6833 #CJK UNIFIED IDEOGRAPH + {0xCFB3, 0x70A1}, //6834 #CJK UNIFIED IDEOGRAPH + {0xCFB4, 0x70B4}, //6835 #CJK UNIFIED IDEOGRAPH + {0xCFB5, 0x70B5}, //6836 #CJK UNIFIED IDEOGRAPH + {0xCFB6, 0x70A9}, //6837 #CJK UNIFIED IDEOGRAPH + {0xCFB7, 0x7241}, //6838 #CJK UNIFIED IDEOGRAPH + {0xCFB8, 0x7249}, //6839 #CJK UNIFIED IDEOGRAPH + {0xCFB9, 0x724A}, //6840 #CJK UNIFIED IDEOGRAPH + {0xCFBA, 0x726C}, //6841 #CJK UNIFIED IDEOGRAPH + {0xCFBB, 0x7270}, //6842 #CJK UNIFIED IDEOGRAPH + {0xCFBC, 0x7273}, //6843 #CJK UNIFIED IDEOGRAPH + {0xCFBD, 0x726E}, //6844 #CJK UNIFIED IDEOGRAPH + {0xCFBE, 0x72CA}, //6845 #CJK UNIFIED IDEOGRAPH + {0xCFBF, 0x72E4}, //6846 #CJK UNIFIED IDEOGRAPH + {0xCFC0, 0x72E8}, //6847 #CJK UNIFIED IDEOGRAPH + {0xCFC1, 0x72EB}, //6848 #CJK UNIFIED IDEOGRAPH + {0xCFC2, 0x72DF}, //6849 #CJK UNIFIED IDEOGRAPH + {0xCFC3, 0x72EA}, //6850 #CJK UNIFIED IDEOGRAPH + {0xCFC4, 0x72E6}, //6851 #CJK UNIFIED IDEOGRAPH + {0xCFC5, 0x72E3}, //6852 #CJK UNIFIED IDEOGRAPH + {0xCFC6, 0x7385}, //6853 #CJK UNIFIED IDEOGRAPH + {0xCFC7, 0x73CC}, //6854 #CJK UNIFIED IDEOGRAPH + {0xCFC8, 0x73C2}, //6855 #CJK UNIFIED IDEOGRAPH + {0xCFC9, 0x73C8}, //6856 #CJK UNIFIED IDEOGRAPH + {0xCFCA, 0x73C5}, //6857 #CJK UNIFIED IDEOGRAPH + {0xCFCB, 0x73B9}, //6858 #CJK UNIFIED IDEOGRAPH + {0xCFCC, 0x73B6}, //6859 #CJK UNIFIED IDEOGRAPH + {0xCFCD, 0x73B5}, //6860 #CJK UNIFIED IDEOGRAPH + {0xCFCE, 0x73B4}, //6861 #CJK UNIFIED IDEOGRAPH + {0xCFCF, 0x73EB}, //6862 #CJK UNIFIED IDEOGRAPH + {0xCFD0, 0x73BF}, //6863 #CJK UNIFIED IDEOGRAPH + {0xCFD1, 0x73C7}, //6864 #CJK UNIFIED IDEOGRAPH + {0xCFD2, 0x73BE}, //6865 #CJK UNIFIED IDEOGRAPH + {0xCFD3, 0x73C3}, //6866 #CJK UNIFIED IDEOGRAPH + {0xCFD4, 0x73C6}, //6867 #CJK UNIFIED IDEOGRAPH + {0xCFD5, 0x73B8}, //6868 #CJK UNIFIED IDEOGRAPH + {0xCFD6, 0x73CB}, //6869 #CJK UNIFIED IDEOGRAPH + {0xCFD7, 0x74EC}, //6870 #CJK UNIFIED IDEOGRAPH + {0xCFD8, 0x74EE}, //6871 #CJK UNIFIED IDEOGRAPH + {0xCFD9, 0x752E}, //6872 #CJK UNIFIED IDEOGRAPH + {0xCFDA, 0x7547}, //6873 #CJK UNIFIED IDEOGRAPH + {0xCFDB, 0x7548}, //6874 #CJK UNIFIED IDEOGRAPH + {0xCFDC, 0x75A7}, //6875 #CJK UNIFIED IDEOGRAPH + {0xCFDD, 0x75AA}, //6876 #CJK UNIFIED IDEOGRAPH + {0xCFDE, 0x7679}, //6877 #CJK UNIFIED IDEOGRAPH + {0xCFDF, 0x76C4}, //6878 #CJK UNIFIED IDEOGRAPH + {0xCFE0, 0x7708}, //6879 #CJK UNIFIED IDEOGRAPH + {0xCFE1, 0x7703}, //6880 #CJK UNIFIED IDEOGRAPH + {0xCFE2, 0x7704}, //6881 #CJK UNIFIED IDEOGRAPH + {0xCFE3, 0x7705}, //6882 #CJK UNIFIED IDEOGRAPH + {0xCFE4, 0x770A}, //6883 #CJK UNIFIED IDEOGRAPH + {0xCFE5, 0x76F7}, //6884 #CJK UNIFIED IDEOGRAPH + {0xCFE6, 0x76FB}, //6885 #CJK UNIFIED IDEOGRAPH + {0xCFE7, 0x76FA}, //6886 #CJK UNIFIED IDEOGRAPH + {0xCFE8, 0x77E7}, //6887 #CJK UNIFIED IDEOGRAPH + {0xCFE9, 0x77E8}, //6888 #CJK UNIFIED IDEOGRAPH + {0xCFEA, 0x7806}, //6889 #CJK UNIFIED IDEOGRAPH + {0xCFEB, 0x7811}, //6890 #CJK UNIFIED IDEOGRAPH + {0xCFEC, 0x7812}, //6891 #CJK UNIFIED IDEOGRAPH + {0xCFED, 0x7805}, //6892 #CJK UNIFIED IDEOGRAPH + {0xCFEE, 0x7810}, //6893 #CJK UNIFIED IDEOGRAPH + {0xCFEF, 0x780F}, //6894 #CJK UNIFIED IDEOGRAPH + {0xCFF0, 0x780E}, //6895 #CJK UNIFIED IDEOGRAPH + {0xCFF1, 0x7809}, //6896 #CJK UNIFIED IDEOGRAPH + {0xCFF2, 0x7803}, //6897 #CJK UNIFIED IDEOGRAPH + {0xCFF3, 0x7813}, //6898 #CJK UNIFIED IDEOGRAPH + {0xCFF4, 0x794A}, //6899 #CJK UNIFIED IDEOGRAPH + {0xCFF5, 0x794C}, //6900 #CJK UNIFIED IDEOGRAPH + {0xCFF6, 0x794B}, //6901 #CJK UNIFIED IDEOGRAPH + {0xCFF7, 0x7945}, //6902 #CJK UNIFIED IDEOGRAPH + {0xCFF8, 0x7944}, //6903 #CJK UNIFIED IDEOGRAPH + {0xCFF9, 0x79D5}, //6904 #CJK UNIFIED IDEOGRAPH + {0xCFFA, 0x79CD}, //6905 #CJK UNIFIED IDEOGRAPH + {0xCFFB, 0x79CF}, //6906 #CJK UNIFIED IDEOGRAPH + {0xCFFC, 0x79D6}, //6907 #CJK UNIFIED IDEOGRAPH + {0xCFFD, 0x79CE}, //6908 #CJK UNIFIED IDEOGRAPH + {0xCFFE, 0x7A80}, //6909 #CJK UNIFIED IDEOGRAPH + {0xD040, 0x7A7E}, //6910 #CJK UNIFIED IDEOGRAPH + {0xD041, 0x7AD1}, //6911 #CJK UNIFIED IDEOGRAPH + {0xD042, 0x7B00}, //6912 #CJK UNIFIED IDEOGRAPH + {0xD043, 0x7B01}, //6913 #CJK UNIFIED IDEOGRAPH + {0xD044, 0x7C7A}, //6914 #CJK UNIFIED IDEOGRAPH + {0xD045, 0x7C78}, //6915 #CJK UNIFIED IDEOGRAPH + {0xD046, 0x7C79}, //6916 #CJK UNIFIED IDEOGRAPH + {0xD047, 0x7C7F}, //6917 #CJK UNIFIED IDEOGRAPH + {0xD048, 0x7C80}, //6918 #CJK UNIFIED IDEOGRAPH + {0xD049, 0x7C81}, //6919 #CJK UNIFIED IDEOGRAPH + {0xD04A, 0x7D03}, //6920 #CJK UNIFIED IDEOGRAPH + {0xD04B, 0x7D08}, //6921 #CJK UNIFIED IDEOGRAPH + {0xD04C, 0x7D01}, //6922 #CJK UNIFIED IDEOGRAPH + {0xD04D, 0x7F58}, //6923 #CJK UNIFIED IDEOGRAPH + {0xD04E, 0x7F91}, //6924 #CJK UNIFIED IDEOGRAPH + {0xD04F, 0x7F8D}, //6925 #CJK UNIFIED IDEOGRAPH + {0xD050, 0x7FBE}, //6926 #CJK UNIFIED IDEOGRAPH + {0xD051, 0x8007}, //6927 #CJK UNIFIED IDEOGRAPH + {0xD052, 0x800E}, //6928 #CJK UNIFIED IDEOGRAPH + {0xD053, 0x800F}, //6929 #CJK UNIFIED IDEOGRAPH + {0xD054, 0x8014}, //6930 #CJK UNIFIED IDEOGRAPH + {0xD055, 0x8037}, //6931 #CJK UNIFIED IDEOGRAPH + {0xD056, 0x80D8}, //6932 #CJK UNIFIED IDEOGRAPH + {0xD057, 0x80C7}, //6933 #CJK UNIFIED IDEOGRAPH + {0xD058, 0x80E0}, //6934 #CJK UNIFIED IDEOGRAPH + {0xD059, 0x80D1}, //6935 #CJK UNIFIED IDEOGRAPH + {0xD05A, 0x80C8}, //6936 #CJK UNIFIED IDEOGRAPH + {0xD05B, 0x80C2}, //6937 #CJK UNIFIED IDEOGRAPH + {0xD05C, 0x80D0}, //6938 #CJK UNIFIED IDEOGRAPH + {0xD05D, 0x80C5}, //6939 #CJK UNIFIED IDEOGRAPH + {0xD05E, 0x80E3}, //6940 #CJK UNIFIED IDEOGRAPH + {0xD05F, 0x80D9}, //6941 #CJK UNIFIED IDEOGRAPH + {0xD060, 0x80DC}, //6942 #CJK UNIFIED IDEOGRAPH + {0xD061, 0x80CA}, //6943 #CJK UNIFIED IDEOGRAPH + {0xD062, 0x80D5}, //6944 #CJK UNIFIED IDEOGRAPH + {0xD063, 0x80C9}, //6945 #CJK UNIFIED IDEOGRAPH + {0xD064, 0x80CF}, //6946 #CJK UNIFIED IDEOGRAPH + {0xD065, 0x80D7}, //6947 #CJK UNIFIED IDEOGRAPH + {0xD066, 0x80E6}, //6948 #CJK UNIFIED IDEOGRAPH + {0xD067, 0x80CD}, //6949 #CJK UNIFIED IDEOGRAPH + {0xD068, 0x81FF}, //6950 #CJK UNIFIED IDEOGRAPH + {0xD069, 0x8221}, //6951 #CJK UNIFIED IDEOGRAPH + {0xD06A, 0x8294}, //6952 #CJK UNIFIED IDEOGRAPH + {0xD06B, 0x82D9}, //6953 #CJK UNIFIED IDEOGRAPH + {0xD06C, 0x82FE}, //6954 #CJK UNIFIED IDEOGRAPH + {0xD06D, 0x82F9}, //6955 #CJK UNIFIED IDEOGRAPH + {0xD06E, 0x8307}, //6956 #CJK UNIFIED IDEOGRAPH + {0xD06F, 0x82E8}, //6957 #CJK UNIFIED IDEOGRAPH + {0xD070, 0x8300}, //6958 #CJK UNIFIED IDEOGRAPH + {0xD071, 0x82D5}, //6959 #CJK UNIFIED IDEOGRAPH + {0xD072, 0x833A}, //6960 #CJK UNIFIED IDEOGRAPH + {0xD073, 0x82EB}, //6961 #CJK UNIFIED IDEOGRAPH + {0xD074, 0x82D6}, //6962 #CJK UNIFIED IDEOGRAPH + {0xD075, 0x82F4}, //6963 #CJK UNIFIED IDEOGRAPH + {0xD076, 0x82EC}, //6964 #CJK UNIFIED IDEOGRAPH + {0xD077, 0x82E1}, //6965 #CJK UNIFIED IDEOGRAPH + {0xD078, 0x82F2}, //6966 #CJK UNIFIED IDEOGRAPH + {0xD079, 0x82F5}, //6967 #CJK UNIFIED IDEOGRAPH + {0xD07A, 0x830C}, //6968 #CJK UNIFIED IDEOGRAPH + {0xD07B, 0x82FB}, //6969 #CJK UNIFIED IDEOGRAPH + {0xD07C, 0x82F6}, //6970 #CJK UNIFIED IDEOGRAPH + {0xD07D, 0x82F0}, //6971 #CJK UNIFIED IDEOGRAPH + {0xD07E, 0x82EA}, //6972 #CJK UNIFIED IDEOGRAPH + {0xD0A1, 0x82E4}, //6973 #CJK UNIFIED IDEOGRAPH + {0xD0A2, 0x82E0}, //6974 #CJK UNIFIED IDEOGRAPH + {0xD0A3, 0x82FA}, //6975 #CJK UNIFIED IDEOGRAPH + {0xD0A4, 0x82F3}, //6976 #CJK UNIFIED IDEOGRAPH + {0xD0A5, 0x82ED}, //6977 #CJK UNIFIED IDEOGRAPH + {0xD0A6, 0x8677}, //6978 #CJK UNIFIED IDEOGRAPH + {0xD0A7, 0x8674}, //6979 #CJK UNIFIED IDEOGRAPH + {0xD0A8, 0x867C}, //6980 #CJK UNIFIED IDEOGRAPH + {0xD0A9, 0x8673}, //6981 #CJK UNIFIED IDEOGRAPH + {0xD0AA, 0x8841}, //6982 #CJK UNIFIED IDEOGRAPH + {0xD0AB, 0x884E}, //6983 #CJK UNIFIED IDEOGRAPH + {0xD0AC, 0x8867}, //6984 #CJK UNIFIED IDEOGRAPH + {0xD0AD, 0x886A}, //6985 #CJK UNIFIED IDEOGRAPH + {0xD0AE, 0x8869}, //6986 #CJK UNIFIED IDEOGRAPH + {0xD0AF, 0x89D3}, //6987 #CJK UNIFIED IDEOGRAPH + {0xD0B0, 0x8A04}, //6988 #CJK UNIFIED IDEOGRAPH + {0xD0B1, 0x8A07}, //6989 #CJK UNIFIED IDEOGRAPH + {0xD0B2, 0x8D72}, //6990 #CJK UNIFIED IDEOGRAPH + {0xD0B3, 0x8FE3}, //6991 #CJK UNIFIED IDEOGRAPH + {0xD0B4, 0x8FE1}, //6992 #CJK UNIFIED IDEOGRAPH + {0xD0B5, 0x8FEE}, //6993 #CJK UNIFIED IDEOGRAPH + {0xD0B6, 0x8FE0}, //6994 #CJK UNIFIED IDEOGRAPH + {0xD0B7, 0x90F1}, //6995 #CJK UNIFIED IDEOGRAPH + {0xD0B8, 0x90BD}, //6996 #CJK UNIFIED IDEOGRAPH + {0xD0B9, 0x90BF}, //6997 #CJK UNIFIED IDEOGRAPH + {0xD0BA, 0x90D5}, //6998 #CJK UNIFIED IDEOGRAPH + {0xD0BB, 0x90C5}, //6999 #CJK UNIFIED IDEOGRAPH + {0xD0BC, 0x90BE}, //7000 #CJK UNIFIED IDEOGRAPH + {0xD0BD, 0x90C7}, //7001 #CJK UNIFIED IDEOGRAPH + {0xD0BE, 0x90CB}, //7002 #CJK UNIFIED IDEOGRAPH + {0xD0BF, 0x90C8}, //7003 #CJK UNIFIED IDEOGRAPH + {0xD0C0, 0x91D4}, //7004 #CJK UNIFIED IDEOGRAPH + {0xD0C1, 0x91D3}, //7005 #CJK UNIFIED IDEOGRAPH + {0xD0C2, 0x9654}, //7006 #CJK UNIFIED IDEOGRAPH + {0xD0C3, 0x964F}, //7007 #CJK UNIFIED IDEOGRAPH + {0xD0C4, 0x9651}, //7008 #CJK UNIFIED IDEOGRAPH + {0xD0C5, 0x9653}, //7009 #CJK UNIFIED IDEOGRAPH + {0xD0C6, 0x964A}, //7010 #CJK UNIFIED IDEOGRAPH + {0xD0C7, 0x964E}, //7011 #CJK UNIFIED IDEOGRAPH + {0xD0C8, 0x501E}, //7012 #CJK UNIFIED IDEOGRAPH + {0xD0C9, 0x5005}, //7013 #CJK UNIFIED IDEOGRAPH + {0xD0CA, 0x5007}, //7014 #CJK UNIFIED IDEOGRAPH + {0xD0CB, 0x5013}, //7015 #CJK UNIFIED IDEOGRAPH + {0xD0CC, 0x5022}, //7016 #CJK UNIFIED IDEOGRAPH + {0xD0CD, 0x5030}, //7017 #CJK UNIFIED IDEOGRAPH + {0xD0CE, 0x501B}, //7018 #CJK UNIFIED IDEOGRAPH + {0xD0CF, 0x4FF5}, //7019 #CJK UNIFIED IDEOGRAPH + {0xD0D0, 0x4FF4}, //7020 #CJK UNIFIED IDEOGRAPH + {0xD0D1, 0x5033}, //7021 #CJK UNIFIED IDEOGRAPH + {0xD0D2, 0x5037}, //7022 #CJK UNIFIED IDEOGRAPH + {0xD0D3, 0x502C}, //7023 #CJK UNIFIED IDEOGRAPH + {0xD0D4, 0x4FF6}, //7024 #CJK UNIFIED IDEOGRAPH + {0xD0D5, 0x4FF7}, //7025 #CJK UNIFIED IDEOGRAPH + {0xD0D6, 0x5017}, //7026 #CJK UNIFIED IDEOGRAPH + {0xD0D7, 0x501C}, //7027 #CJK UNIFIED IDEOGRAPH + {0xD0D8, 0x5020}, //7028 #CJK UNIFIED IDEOGRAPH + {0xD0D9, 0x5027}, //7029 #CJK UNIFIED IDEOGRAPH + {0xD0DA, 0x5035}, //7030 #CJK UNIFIED IDEOGRAPH + {0xD0DB, 0x502F}, //7031 #CJK UNIFIED IDEOGRAPH + {0xD0DC, 0x5031}, //7032 #CJK UNIFIED IDEOGRAPH + {0xD0DD, 0x500E}, //7033 #CJK UNIFIED IDEOGRAPH + {0xD0DE, 0x515A}, //7034 #CJK UNIFIED IDEOGRAPH + {0xD0DF, 0x5194}, //7035 #CJK UNIFIED IDEOGRAPH + {0xD0E0, 0x5193}, //7036 #CJK UNIFIED IDEOGRAPH + {0xD0E1, 0x51CA}, //7037 #CJK UNIFIED IDEOGRAPH + {0xD0E2, 0x51C4}, //7038 #CJK UNIFIED IDEOGRAPH + {0xD0E3, 0x51C5}, //7039 #CJK UNIFIED IDEOGRAPH + {0xD0E4, 0x51C8}, //7040 #CJK UNIFIED IDEOGRAPH + {0xD0E5, 0x51CE}, //7041 #CJK UNIFIED IDEOGRAPH + {0xD0E6, 0x5261}, //7042 #CJK UNIFIED IDEOGRAPH + {0xD0E7, 0x525A}, //7043 #CJK UNIFIED IDEOGRAPH + {0xD0E8, 0x5252}, //7044 #CJK UNIFIED IDEOGRAPH + {0xD0E9, 0x525E}, //7045 #CJK UNIFIED IDEOGRAPH + {0xD0EA, 0x525F}, //7046 #CJK UNIFIED IDEOGRAPH + {0xD0EB, 0x5255}, //7047 #CJK UNIFIED IDEOGRAPH + {0xD0EC, 0x5262}, //7048 #CJK UNIFIED IDEOGRAPH + {0xD0ED, 0x52CD}, //7049 #CJK UNIFIED IDEOGRAPH + {0xD0EE, 0x530E}, //7050 #CJK UNIFIED IDEOGRAPH + {0xD0EF, 0x539E}, //7051 #CJK UNIFIED IDEOGRAPH + {0xD0F0, 0x5526}, //7052 #CJK UNIFIED IDEOGRAPH + {0xD0F1, 0x54E2}, //7053 #CJK UNIFIED IDEOGRAPH + {0xD0F2, 0x5517}, //7054 #CJK UNIFIED IDEOGRAPH + {0xD0F3, 0x5512}, //7055 #CJK UNIFIED IDEOGRAPH + {0xD0F4, 0x54E7}, //7056 #CJK UNIFIED IDEOGRAPH + {0xD0F5, 0x54F3}, //7057 #CJK UNIFIED IDEOGRAPH + {0xD0F6, 0x54E4}, //7058 #CJK UNIFIED IDEOGRAPH + {0xD0F7, 0x551A}, //7059 #CJK UNIFIED IDEOGRAPH + {0xD0F8, 0x54FF}, //7060 #CJK UNIFIED IDEOGRAPH + {0xD0F9, 0x5504}, //7061 #CJK UNIFIED IDEOGRAPH + {0xD0FA, 0x5508}, //7062 #CJK UNIFIED IDEOGRAPH + {0xD0FB, 0x54EB}, //7063 #CJK UNIFIED IDEOGRAPH + {0xD0FC, 0x5511}, //7064 #CJK UNIFIED IDEOGRAPH + {0xD0FD, 0x5505}, //7065 #CJK UNIFIED IDEOGRAPH + {0xD0FE, 0x54F1}, //7066 #CJK UNIFIED IDEOGRAPH + {0xD140, 0x550A}, //7067 #CJK UNIFIED IDEOGRAPH + {0xD141, 0x54FB}, //7068 #CJK UNIFIED IDEOGRAPH + {0xD142, 0x54F7}, //7069 #CJK UNIFIED IDEOGRAPH + {0xD143, 0x54F8}, //7070 #CJK UNIFIED IDEOGRAPH + {0xD144, 0x54E0}, //7071 #CJK UNIFIED IDEOGRAPH + {0xD145, 0x550E}, //7072 #CJK UNIFIED IDEOGRAPH + {0xD146, 0x5503}, //7073 #CJK UNIFIED IDEOGRAPH + {0xD147, 0x550B}, //7074 #CJK UNIFIED IDEOGRAPH + {0xD148, 0x5701}, //7075 #CJK UNIFIED IDEOGRAPH + {0xD149, 0x5702}, //7076 #CJK UNIFIED IDEOGRAPH + {0xD14A, 0x57CC}, //7077 #CJK UNIFIED IDEOGRAPH + {0xD14B, 0x5832}, //7078 #CJK UNIFIED IDEOGRAPH + {0xD14C, 0x57D5}, //7079 #CJK UNIFIED IDEOGRAPH + {0xD14D, 0x57D2}, //7080 #CJK UNIFIED IDEOGRAPH + {0xD14E, 0x57BA}, //7081 #CJK UNIFIED IDEOGRAPH + {0xD14F, 0x57C6}, //7082 #CJK UNIFIED IDEOGRAPH + {0xD150, 0x57BD}, //7083 #CJK UNIFIED IDEOGRAPH + {0xD151, 0x57BC}, //7084 #CJK UNIFIED IDEOGRAPH + {0xD152, 0x57B8}, //7085 #CJK UNIFIED IDEOGRAPH + {0xD153, 0x57B6}, //7086 #CJK UNIFIED IDEOGRAPH + {0xD154, 0x57BF}, //7087 #CJK UNIFIED IDEOGRAPH + {0xD155, 0x57C7}, //7088 #CJK UNIFIED IDEOGRAPH + {0xD156, 0x57D0}, //7089 #CJK UNIFIED IDEOGRAPH + {0xD157, 0x57B9}, //7090 #CJK UNIFIED IDEOGRAPH + {0xD158, 0x57C1}, //7091 #CJK UNIFIED IDEOGRAPH + {0xD159, 0x590E}, //7092 #CJK UNIFIED IDEOGRAPH + {0xD15A, 0x594A}, //7093 #CJK UNIFIED IDEOGRAPH + {0xD15B, 0x5A19}, //7094 #CJK UNIFIED IDEOGRAPH + {0xD15C, 0x5A16}, //7095 #CJK UNIFIED IDEOGRAPH + {0xD15D, 0x5A2D}, //7096 #CJK UNIFIED IDEOGRAPH + {0xD15E, 0x5A2E}, //7097 #CJK UNIFIED IDEOGRAPH + {0xD15F, 0x5A15}, //7098 #CJK UNIFIED IDEOGRAPH + {0xD160, 0x5A0F}, //7099 #CJK UNIFIED IDEOGRAPH + {0xD161, 0x5A17}, //7100 #CJK UNIFIED IDEOGRAPH + {0xD162, 0x5A0A}, //7101 #CJK UNIFIED IDEOGRAPH + {0xD163, 0x5A1E}, //7102 #CJK UNIFIED IDEOGRAPH + {0xD164, 0x5A33}, //7103 #CJK UNIFIED IDEOGRAPH + {0xD165, 0x5B6C}, //7104 #CJK UNIFIED IDEOGRAPH + {0xD166, 0x5BA7}, //7105 #CJK UNIFIED IDEOGRAPH + {0xD167, 0x5BAD}, //7106 #CJK UNIFIED IDEOGRAPH + {0xD168, 0x5BAC}, //7107 #CJK UNIFIED IDEOGRAPH + {0xD169, 0x5C03}, //7108 #CJK UNIFIED IDEOGRAPH + {0xD16A, 0x5C56}, //7109 #CJK UNIFIED IDEOGRAPH + {0xD16B, 0x5C54}, //7110 #CJK UNIFIED IDEOGRAPH + {0xD16C, 0x5CEC}, //7111 #CJK UNIFIED IDEOGRAPH + {0xD16D, 0x5CFF}, //7112 #CJK UNIFIED IDEOGRAPH + {0xD16E, 0x5CEE}, //7113 #CJK UNIFIED IDEOGRAPH + {0xD16F, 0x5CF1}, //7114 #CJK UNIFIED IDEOGRAPH + {0xD170, 0x5CF7}, //7115 #CJK UNIFIED IDEOGRAPH + {0xD171, 0x5D00}, //7116 #CJK UNIFIED IDEOGRAPH + {0xD172, 0x5CF9}, //7117 #CJK UNIFIED IDEOGRAPH + {0xD173, 0x5E29}, //7118 #CJK UNIFIED IDEOGRAPH + {0xD174, 0x5E28}, //7119 #CJK UNIFIED IDEOGRAPH + {0xD175, 0x5EA8}, //7120 #CJK UNIFIED IDEOGRAPH + {0xD176, 0x5EAE}, //7121 #CJK UNIFIED IDEOGRAPH + {0xD177, 0x5EAA}, //7122 #CJK UNIFIED IDEOGRAPH + {0xD178, 0x5EAC}, //7123 #CJK UNIFIED IDEOGRAPH + {0xD179, 0x5F33}, //7124 #CJK UNIFIED IDEOGRAPH + {0xD17A, 0x5F30}, //7125 #CJK UNIFIED IDEOGRAPH + {0xD17B, 0x5F67}, //7126 #CJK UNIFIED IDEOGRAPH + {0xD17C, 0x605D}, //7127 #CJK UNIFIED IDEOGRAPH + {0xD17D, 0x605A}, //7128 #CJK UNIFIED IDEOGRAPH + {0xD17E, 0x6067}, //7129 #CJK UNIFIED IDEOGRAPH + {0xD1A1, 0x6041}, //7130 #CJK UNIFIED IDEOGRAPH + {0xD1A2, 0x60A2}, //7131 #CJK UNIFIED IDEOGRAPH + {0xD1A3, 0x6088}, //7132 #CJK UNIFIED IDEOGRAPH + {0xD1A4, 0x6080}, //7133 #CJK UNIFIED IDEOGRAPH + {0xD1A5, 0x6092}, //7134 #CJK UNIFIED IDEOGRAPH + {0xD1A6, 0x6081}, //7135 #CJK UNIFIED IDEOGRAPH + {0xD1A7, 0x609D}, //7136 #CJK UNIFIED IDEOGRAPH + {0xD1A8, 0x6083}, //7137 #CJK UNIFIED IDEOGRAPH + {0xD1A9, 0x6095}, //7138 #CJK UNIFIED IDEOGRAPH + {0xD1AA, 0x609B}, //7139 #CJK UNIFIED IDEOGRAPH + {0xD1AB, 0x6097}, //7140 #CJK UNIFIED IDEOGRAPH + {0xD1AC, 0x6087}, //7141 #CJK UNIFIED IDEOGRAPH + {0xD1AD, 0x609C}, //7142 #CJK UNIFIED IDEOGRAPH + {0xD1AE, 0x608E}, //7143 #CJK UNIFIED IDEOGRAPH + {0xD1AF, 0x6219}, //7144 #CJK UNIFIED IDEOGRAPH + {0xD1B0, 0x6246}, //7145 #CJK UNIFIED IDEOGRAPH + {0xD1B1, 0x62F2}, //7146 #CJK UNIFIED IDEOGRAPH + {0xD1B2, 0x6310}, //7147 #CJK UNIFIED IDEOGRAPH + {0xD1B3, 0x6356}, //7148 #CJK UNIFIED IDEOGRAPH + {0xD1B4, 0x632C}, //7149 #CJK UNIFIED IDEOGRAPH + {0xD1B5, 0x6344}, //7150 #CJK UNIFIED IDEOGRAPH + {0xD1B6, 0x6345}, //7151 #CJK UNIFIED IDEOGRAPH + {0xD1B7, 0x6336}, //7152 #CJK UNIFIED IDEOGRAPH + {0xD1B8, 0x6343}, //7153 #CJK UNIFIED IDEOGRAPH + {0xD1B9, 0x63E4}, //7154 #CJK UNIFIED IDEOGRAPH + {0xD1BA, 0x6339}, //7155 #CJK UNIFIED IDEOGRAPH + {0xD1BB, 0x634B}, //7156 #CJK UNIFIED IDEOGRAPH + {0xD1BC, 0x634A}, //7157 #CJK UNIFIED IDEOGRAPH + {0xD1BD, 0x633C}, //7158 #CJK UNIFIED IDEOGRAPH + {0xD1BE, 0x6329}, //7159 #CJK UNIFIED IDEOGRAPH + {0xD1BF, 0x6341}, //7160 #CJK UNIFIED IDEOGRAPH + {0xD1C0, 0x6334}, //7161 #CJK UNIFIED IDEOGRAPH + {0xD1C1, 0x6358}, //7162 #CJK UNIFIED IDEOGRAPH + {0xD1C2, 0x6354}, //7163 #CJK UNIFIED IDEOGRAPH + {0xD1C3, 0x6359}, //7164 #CJK UNIFIED IDEOGRAPH + {0xD1C4, 0x632D}, //7165 #CJK UNIFIED IDEOGRAPH + {0xD1C5, 0x6347}, //7166 #CJK UNIFIED IDEOGRAPH + {0xD1C6, 0x6333}, //7167 #CJK UNIFIED IDEOGRAPH + {0xD1C7, 0x635A}, //7168 #CJK UNIFIED IDEOGRAPH + {0xD1C8, 0x6351}, //7169 #CJK UNIFIED IDEOGRAPH + {0xD1C9, 0x6338}, //7170 #CJK UNIFIED IDEOGRAPH + {0xD1CA, 0x6357}, //7171 #CJK UNIFIED IDEOGRAPH + {0xD1CB, 0x6340}, //7172 #CJK UNIFIED IDEOGRAPH + {0xD1CC, 0x6348}, //7173 #CJK UNIFIED IDEOGRAPH + {0xD1CD, 0x654A}, //7174 #CJK UNIFIED IDEOGRAPH + {0xD1CE, 0x6546}, //7175 #CJK UNIFIED IDEOGRAPH + {0xD1CF, 0x65C6}, //7176 #CJK UNIFIED IDEOGRAPH + {0xD1D0, 0x65C3}, //7177 #CJK UNIFIED IDEOGRAPH + {0xD1D1, 0x65C4}, //7178 #CJK UNIFIED IDEOGRAPH + {0xD1D2, 0x65C2}, //7179 #CJK UNIFIED IDEOGRAPH + {0xD1D3, 0x664A}, //7180 #CJK UNIFIED IDEOGRAPH + {0xD1D4, 0x665F}, //7181 #CJK UNIFIED IDEOGRAPH + {0xD1D5, 0x6647}, //7182 #CJK UNIFIED IDEOGRAPH + {0xD1D6, 0x6651}, //7183 #CJK UNIFIED IDEOGRAPH + {0xD1D7, 0x6712}, //7184 #CJK UNIFIED IDEOGRAPH + {0xD1D8, 0x6713}, //7185 #CJK UNIFIED IDEOGRAPH + {0xD1D9, 0x681F}, //7186 #CJK UNIFIED IDEOGRAPH + {0xD1DA, 0x681A}, //7187 #CJK UNIFIED IDEOGRAPH + {0xD1DB, 0x6849}, //7188 #CJK UNIFIED IDEOGRAPH + {0xD1DC, 0x6832}, //7189 #CJK UNIFIED IDEOGRAPH + {0xD1DD, 0x6833}, //7190 #CJK UNIFIED IDEOGRAPH + {0xD1DE, 0x683B}, //7191 #CJK UNIFIED IDEOGRAPH + {0xD1DF, 0x684B}, //7192 #CJK UNIFIED IDEOGRAPH + {0xD1E0, 0x684F}, //7193 #CJK UNIFIED IDEOGRAPH + {0xD1E1, 0x6816}, //7194 #CJK UNIFIED IDEOGRAPH + {0xD1E2, 0x6831}, //7195 #CJK UNIFIED IDEOGRAPH + {0xD1E3, 0x681C}, //7196 #CJK UNIFIED IDEOGRAPH + {0xD1E4, 0x6835}, //7197 #CJK UNIFIED IDEOGRAPH + {0xD1E5, 0x682B}, //7198 #CJK UNIFIED IDEOGRAPH + {0xD1E6, 0x682D}, //7199 #CJK UNIFIED IDEOGRAPH + {0xD1E7, 0x682F}, //7200 #CJK UNIFIED IDEOGRAPH + {0xD1E8, 0x684E}, //7201 #CJK UNIFIED IDEOGRAPH + {0xD1E9, 0x6844}, //7202 #CJK UNIFIED IDEOGRAPH + {0xD1EA, 0x6834}, //7203 #CJK UNIFIED IDEOGRAPH + {0xD1EB, 0x681D}, //7204 #CJK UNIFIED IDEOGRAPH + {0xD1EC, 0x6812}, //7205 #CJK UNIFIED IDEOGRAPH + {0xD1ED, 0x6814}, //7206 #CJK UNIFIED IDEOGRAPH + {0xD1EE, 0x6826}, //7207 #CJK UNIFIED IDEOGRAPH + {0xD1EF, 0x6828}, //7208 #CJK UNIFIED IDEOGRAPH + {0xD1F0, 0x682E}, //7209 #CJK UNIFIED IDEOGRAPH + {0xD1F1, 0x684D}, //7210 #CJK UNIFIED IDEOGRAPH + {0xD1F2, 0x683A}, //7211 #CJK UNIFIED IDEOGRAPH + {0xD1F3, 0x6825}, //7212 #CJK UNIFIED IDEOGRAPH + {0xD1F4, 0x6820}, //7213 #CJK UNIFIED IDEOGRAPH + {0xD1F5, 0x6B2C}, //7214 #CJK UNIFIED IDEOGRAPH + {0xD1F6, 0x6B2F}, //7215 #CJK UNIFIED IDEOGRAPH + {0xD1F7, 0x6B2D}, //7216 #CJK UNIFIED IDEOGRAPH + {0xD1F8, 0x6B31}, //7217 #CJK UNIFIED IDEOGRAPH + {0xD1F9, 0x6B34}, //7218 #CJK UNIFIED IDEOGRAPH + {0xD1FA, 0x6B6D}, //7219 #CJK UNIFIED IDEOGRAPH + {0xD1FB, 0x8082}, //7220 #CJK UNIFIED IDEOGRAPH + {0xD1FC, 0x6B88}, //7221 #CJK UNIFIED IDEOGRAPH + {0xD1FD, 0x6BE6}, //7222 #CJK UNIFIED IDEOGRAPH + {0xD1FE, 0x6BE4}, //7223 #CJK UNIFIED IDEOGRAPH + {0xD240, 0x6BE8}, //7224 #CJK UNIFIED IDEOGRAPH + {0xD241, 0x6BE3}, //7225 #CJK UNIFIED IDEOGRAPH + {0xD242, 0x6BE2}, //7226 #CJK UNIFIED IDEOGRAPH + {0xD243, 0x6BE7}, //7227 #CJK UNIFIED IDEOGRAPH + {0xD244, 0x6C25}, //7228 #CJK UNIFIED IDEOGRAPH + {0xD245, 0x6D7A}, //7229 #CJK UNIFIED IDEOGRAPH + {0xD246, 0x6D63}, //7230 #CJK UNIFIED IDEOGRAPH + {0xD247, 0x6D64}, //7231 #CJK UNIFIED IDEOGRAPH + {0xD248, 0x6D76}, //7232 #CJK UNIFIED IDEOGRAPH + {0xD249, 0x6D0D}, //7233 #CJK UNIFIED IDEOGRAPH + {0xD24A, 0x6D61}, //7234 #CJK UNIFIED IDEOGRAPH + {0xD24B, 0x6D92}, //7235 #CJK UNIFIED IDEOGRAPH + {0xD24C, 0x6D58}, //7236 #CJK UNIFIED IDEOGRAPH + {0xD24D, 0x6D62}, //7237 #CJK UNIFIED IDEOGRAPH + {0xD24E, 0x6D6D}, //7238 #CJK UNIFIED IDEOGRAPH + {0xD24F, 0x6D6F}, //7239 #CJK UNIFIED IDEOGRAPH + {0xD250, 0x6D91}, //7240 #CJK UNIFIED IDEOGRAPH + {0xD251, 0x6D8D}, //7241 #CJK UNIFIED IDEOGRAPH + {0xD252, 0x6DEF}, //7242 #CJK UNIFIED IDEOGRAPH + {0xD253, 0x6D7F}, //7243 #CJK UNIFIED IDEOGRAPH + {0xD254, 0x6D86}, //7244 #CJK UNIFIED IDEOGRAPH + {0xD255, 0x6D5E}, //7245 #CJK UNIFIED IDEOGRAPH + {0xD256, 0x6D67}, //7246 #CJK UNIFIED IDEOGRAPH + {0xD257, 0x6D60}, //7247 #CJK UNIFIED IDEOGRAPH + {0xD258, 0x6D97}, //7248 #CJK UNIFIED IDEOGRAPH + {0xD259, 0x6D70}, //7249 #CJK UNIFIED IDEOGRAPH + {0xD25A, 0x6D7C}, //7250 #CJK UNIFIED IDEOGRAPH + {0xD25B, 0x6D5F}, //7251 #CJK UNIFIED IDEOGRAPH + {0xD25C, 0x6D82}, //7252 #CJK UNIFIED IDEOGRAPH + {0xD25D, 0x6D98}, //7253 #CJK UNIFIED IDEOGRAPH + {0xD25E, 0x6D2F}, //7254 #CJK UNIFIED IDEOGRAPH + {0xD25F, 0x6D68}, //7255 #CJK UNIFIED IDEOGRAPH + {0xD260, 0x6D8B}, //7256 #CJK UNIFIED IDEOGRAPH + {0xD261, 0x6D7E}, //7257 #CJK UNIFIED IDEOGRAPH + {0xD262, 0x6D80}, //7258 #CJK UNIFIED IDEOGRAPH + {0xD263, 0x6D84}, //7259 #CJK UNIFIED IDEOGRAPH + {0xD264, 0x6D16}, //7260 #CJK UNIFIED IDEOGRAPH + {0xD265, 0x6D83}, //7261 #CJK UNIFIED IDEOGRAPH + {0xD266, 0x6D7B}, //7262 #CJK UNIFIED IDEOGRAPH + {0xD267, 0x6D7D}, //7263 #CJK UNIFIED IDEOGRAPH + {0xD268, 0x6D75}, //7264 #CJK UNIFIED IDEOGRAPH + {0xD269, 0x6D90}, //7265 #CJK UNIFIED IDEOGRAPH + {0xD26A, 0x70DC}, //7266 #CJK UNIFIED IDEOGRAPH + {0xD26B, 0x70D3}, //7267 #CJK UNIFIED IDEOGRAPH + {0xD26C, 0x70D1}, //7268 #CJK UNIFIED IDEOGRAPH + {0xD26D, 0x70DD}, //7269 #CJK UNIFIED IDEOGRAPH + {0xD26E, 0x70CB}, //7270 #CJK UNIFIED IDEOGRAPH + {0xD26F, 0x7F39}, //7271 #CJK UNIFIED IDEOGRAPH + {0xD270, 0x70E2}, //7272 #CJK UNIFIED IDEOGRAPH + {0xD271, 0x70D7}, //7273 #CJK UNIFIED IDEOGRAPH + {0xD272, 0x70D2}, //7274 #CJK UNIFIED IDEOGRAPH + {0xD273, 0x70DE}, //7275 #CJK UNIFIED IDEOGRAPH + {0xD274, 0x70E0}, //7276 #CJK UNIFIED IDEOGRAPH + {0xD275, 0x70D4}, //7277 #CJK UNIFIED IDEOGRAPH + {0xD276, 0x70CD}, //7278 #CJK UNIFIED IDEOGRAPH + {0xD277, 0x70C5}, //7279 #CJK UNIFIED IDEOGRAPH + {0xD278, 0x70C6}, //7280 #CJK UNIFIED IDEOGRAPH + {0xD279, 0x70C7}, //7281 #CJK UNIFIED IDEOGRAPH + {0xD27A, 0x70DA}, //7282 #CJK UNIFIED IDEOGRAPH + {0xD27B, 0x70CE}, //7283 #CJK UNIFIED IDEOGRAPH + {0xD27C, 0x70E1}, //7284 #CJK UNIFIED IDEOGRAPH + {0xD27D, 0x7242}, //7285 #CJK UNIFIED IDEOGRAPH + {0xD27E, 0x7278}, //7286 #CJK UNIFIED IDEOGRAPH + {0xD2A1, 0x7277}, //7287 #CJK UNIFIED IDEOGRAPH + {0xD2A2, 0x7276}, //7288 #CJK UNIFIED IDEOGRAPH + {0xD2A3, 0x7300}, //7289 #CJK UNIFIED IDEOGRAPH + {0xD2A4, 0x72FA}, //7290 #CJK UNIFIED IDEOGRAPH + {0xD2A5, 0x72F4}, //7291 #CJK UNIFIED IDEOGRAPH + {0xD2A6, 0x72FE}, //7292 #CJK UNIFIED IDEOGRAPH + {0xD2A7, 0x72F6}, //7293 #CJK UNIFIED IDEOGRAPH + {0xD2A8, 0x72F3}, //7294 #CJK UNIFIED IDEOGRAPH + {0xD2A9, 0x72FB}, //7295 #CJK UNIFIED IDEOGRAPH + {0xD2AA, 0x7301}, //7296 #CJK UNIFIED IDEOGRAPH + {0xD2AB, 0x73D3}, //7297 #CJK UNIFIED IDEOGRAPH + {0xD2AC, 0x73D9}, //7298 #CJK UNIFIED IDEOGRAPH + {0xD2AD, 0x73E5}, //7299 #CJK UNIFIED IDEOGRAPH + {0xD2AE, 0x73D6}, //7300 #CJK UNIFIED IDEOGRAPH + {0xD2AF, 0x73BC}, //7301 #CJK UNIFIED IDEOGRAPH + {0xD2B0, 0x73E7}, //7302 #CJK UNIFIED IDEOGRAPH + {0xD2B1, 0x73E3}, //7303 #CJK UNIFIED IDEOGRAPH + {0xD2B2, 0x73E9}, //7304 #CJK UNIFIED IDEOGRAPH + {0xD2B3, 0x73DC}, //7305 #CJK UNIFIED IDEOGRAPH + {0xD2B4, 0x73D2}, //7306 #CJK UNIFIED IDEOGRAPH + {0xD2B5, 0x73DB}, //7307 #CJK UNIFIED IDEOGRAPH + {0xD2B6, 0x73D4}, //7308 #CJK UNIFIED IDEOGRAPH + {0xD2B7, 0x73DD}, //7309 #CJK UNIFIED IDEOGRAPH + {0xD2B8, 0x73DA}, //7310 #CJK UNIFIED IDEOGRAPH + {0xD2B9, 0x73D7}, //7311 #CJK UNIFIED IDEOGRAPH + {0xD2BA, 0x73D8}, //7312 #CJK UNIFIED IDEOGRAPH + {0xD2BB, 0x73E8}, //7313 #CJK UNIFIED IDEOGRAPH + {0xD2BC, 0x74DE}, //7314 #CJK UNIFIED IDEOGRAPH + {0xD2BD, 0x74DF}, //7315 #CJK UNIFIED IDEOGRAPH + {0xD2BE, 0x74F4}, //7316 #CJK UNIFIED IDEOGRAPH + {0xD2BF, 0x74F5}, //7317 #CJK UNIFIED IDEOGRAPH + {0xD2C0, 0x7521}, //7318 #CJK UNIFIED IDEOGRAPH + {0xD2C1, 0x755B}, //7319 #CJK UNIFIED IDEOGRAPH + {0xD2C2, 0x755F}, //7320 #CJK UNIFIED IDEOGRAPH + {0xD2C3, 0x75B0}, //7321 #CJK UNIFIED IDEOGRAPH + {0xD2C4, 0x75C1}, //7322 #CJK UNIFIED IDEOGRAPH + {0xD2C5, 0x75BB}, //7323 #CJK UNIFIED IDEOGRAPH + {0xD2C6, 0x75C4}, //7324 #CJK UNIFIED IDEOGRAPH + {0xD2C7, 0x75C0}, //7325 #CJK UNIFIED IDEOGRAPH + {0xD2C8, 0x75BF}, //7326 #CJK UNIFIED IDEOGRAPH + {0xD2C9, 0x75B6}, //7327 #CJK UNIFIED IDEOGRAPH + {0xD2CA, 0x75BA}, //7328 #CJK UNIFIED IDEOGRAPH + {0xD2CB, 0x768A}, //7329 #CJK UNIFIED IDEOGRAPH + {0xD2CC, 0x76C9}, //7330 #CJK UNIFIED IDEOGRAPH + {0xD2CD, 0x771D}, //7331 #CJK UNIFIED IDEOGRAPH + {0xD2CE, 0x771B}, //7332 #CJK UNIFIED IDEOGRAPH + {0xD2CF, 0x7710}, //7333 #CJK UNIFIED IDEOGRAPH + {0xD2D0, 0x7713}, //7334 #CJK UNIFIED IDEOGRAPH + {0xD2D1, 0x7712}, //7335 #CJK UNIFIED IDEOGRAPH + {0xD2D2, 0x7723}, //7336 #CJK UNIFIED IDEOGRAPH + {0xD2D3, 0x7711}, //7337 #CJK UNIFIED IDEOGRAPH + {0xD2D4, 0x7715}, //7338 #CJK UNIFIED IDEOGRAPH + {0xD2D5, 0x7719}, //7339 #CJK UNIFIED IDEOGRAPH + {0xD2D6, 0x771A}, //7340 #CJK UNIFIED IDEOGRAPH + {0xD2D7, 0x7722}, //7341 #CJK UNIFIED IDEOGRAPH + {0xD2D8, 0x7727}, //7342 #CJK UNIFIED IDEOGRAPH + {0xD2D9, 0x7823}, //7343 #CJK UNIFIED IDEOGRAPH + {0xD2DA, 0x782C}, //7344 #CJK UNIFIED IDEOGRAPH + {0xD2DB, 0x7822}, //7345 #CJK UNIFIED IDEOGRAPH + {0xD2DC, 0x7835}, //7346 #CJK UNIFIED IDEOGRAPH + {0xD2DD, 0x782F}, //7347 #CJK UNIFIED IDEOGRAPH + {0xD2DE, 0x7828}, //7348 #CJK UNIFIED IDEOGRAPH + {0xD2DF, 0x782E}, //7349 #CJK UNIFIED IDEOGRAPH + {0xD2E0, 0x782B}, //7350 #CJK UNIFIED IDEOGRAPH + {0xD2E1, 0x7821}, //7351 #CJK UNIFIED IDEOGRAPH + {0xD2E2, 0x7829}, //7352 #CJK UNIFIED IDEOGRAPH + {0xD2E3, 0x7833}, //7353 #CJK UNIFIED IDEOGRAPH + {0xD2E4, 0x782A}, //7354 #CJK UNIFIED IDEOGRAPH + {0xD2E5, 0x7831}, //7355 #CJK UNIFIED IDEOGRAPH + {0xD2E6, 0x7954}, //7356 #CJK UNIFIED IDEOGRAPH + {0xD2E7, 0x795B}, //7357 #CJK UNIFIED IDEOGRAPH + {0xD2E8, 0x794F}, //7358 #CJK UNIFIED IDEOGRAPH + {0xD2E9, 0x795C}, //7359 #CJK UNIFIED IDEOGRAPH + {0xD2EA, 0x7953}, //7360 #CJK UNIFIED IDEOGRAPH + {0xD2EB, 0x7952}, //7361 #CJK UNIFIED IDEOGRAPH + {0xD2EC, 0x7951}, //7362 #CJK UNIFIED IDEOGRAPH + {0xD2ED, 0x79EB}, //7363 #CJK UNIFIED IDEOGRAPH + {0xD2EE, 0x79EC}, //7364 #CJK UNIFIED IDEOGRAPH + {0xD2EF, 0x79E0}, //7365 #CJK UNIFIED IDEOGRAPH + {0xD2F0, 0x79EE}, //7366 #CJK UNIFIED IDEOGRAPH + {0xD2F1, 0x79ED}, //7367 #CJK UNIFIED IDEOGRAPH + {0xD2F2, 0x79EA}, //7368 #CJK UNIFIED IDEOGRAPH + {0xD2F3, 0x79DC}, //7369 #CJK UNIFIED IDEOGRAPH + {0xD2F4, 0x79DE}, //7370 #CJK UNIFIED IDEOGRAPH + {0xD2F5, 0x79DD}, //7371 #CJK UNIFIED IDEOGRAPH + {0xD2F6, 0x7A86}, //7372 #CJK UNIFIED IDEOGRAPH + {0xD2F7, 0x7A89}, //7373 #CJK UNIFIED IDEOGRAPH + {0xD2F8, 0x7A85}, //7374 #CJK UNIFIED IDEOGRAPH + {0xD2F9, 0x7A8B}, //7375 #CJK UNIFIED IDEOGRAPH + {0xD2FA, 0x7A8C}, //7376 #CJK UNIFIED IDEOGRAPH + {0xD2FB, 0x7A8A}, //7377 #CJK UNIFIED IDEOGRAPH + {0xD2FC, 0x7A87}, //7378 #CJK UNIFIED IDEOGRAPH + {0xD2FD, 0x7AD8}, //7379 #CJK UNIFIED IDEOGRAPH + {0xD2FE, 0x7B10}, //7380 #CJK UNIFIED IDEOGRAPH + {0xD340, 0x7B04}, //7381 #CJK UNIFIED IDEOGRAPH + {0xD341, 0x7B13}, //7382 #CJK UNIFIED IDEOGRAPH + {0xD342, 0x7B05}, //7383 #CJK UNIFIED IDEOGRAPH + {0xD343, 0x7B0F}, //7384 #CJK UNIFIED IDEOGRAPH + {0xD344, 0x7B08}, //7385 #CJK UNIFIED IDEOGRAPH + {0xD345, 0x7B0A}, //7386 #CJK UNIFIED IDEOGRAPH + {0xD346, 0x7B0E}, //7387 #CJK UNIFIED IDEOGRAPH + {0xD347, 0x7B09}, //7388 #CJK UNIFIED IDEOGRAPH + {0xD348, 0x7B12}, //7389 #CJK UNIFIED IDEOGRAPH + {0xD349, 0x7C84}, //7390 #CJK UNIFIED IDEOGRAPH + {0xD34A, 0x7C91}, //7391 #CJK UNIFIED IDEOGRAPH + {0xD34B, 0x7C8A}, //7392 #CJK UNIFIED IDEOGRAPH + {0xD34C, 0x7C8C}, //7393 #CJK UNIFIED IDEOGRAPH + {0xD34D, 0x7C88}, //7394 #CJK UNIFIED IDEOGRAPH + {0xD34E, 0x7C8D}, //7395 #CJK UNIFIED IDEOGRAPH + {0xD34F, 0x7C85}, //7396 #CJK UNIFIED IDEOGRAPH + {0xD350, 0x7D1E}, //7397 #CJK UNIFIED IDEOGRAPH + {0xD351, 0x7D1D}, //7398 #CJK UNIFIED IDEOGRAPH + {0xD352, 0x7D11}, //7399 #CJK UNIFIED IDEOGRAPH + {0xD353, 0x7D0E}, //7400 #CJK UNIFIED IDEOGRAPH + {0xD354, 0x7D18}, //7401 #CJK UNIFIED IDEOGRAPH + {0xD355, 0x7D16}, //7402 #CJK UNIFIED IDEOGRAPH + {0xD356, 0x7D13}, //7403 #CJK UNIFIED IDEOGRAPH + {0xD357, 0x7D1F}, //7404 #CJK UNIFIED IDEOGRAPH + {0xD358, 0x7D12}, //7405 #CJK UNIFIED IDEOGRAPH + {0xD359, 0x7D0F}, //7406 #CJK UNIFIED IDEOGRAPH + {0xD35A, 0x7D0C}, //7407 #CJK UNIFIED IDEOGRAPH + {0xD35B, 0x7F5C}, //7408 #CJK UNIFIED IDEOGRAPH + {0xD35C, 0x7F61}, //7409 #CJK UNIFIED IDEOGRAPH + {0xD35D, 0x7F5E}, //7410 #CJK UNIFIED IDEOGRAPH + {0xD35E, 0x7F60}, //7411 #CJK UNIFIED IDEOGRAPH + {0xD35F, 0x7F5D}, //7412 #CJK UNIFIED IDEOGRAPH + {0xD360, 0x7F5B}, //7413 #CJK UNIFIED IDEOGRAPH + {0xD361, 0x7F96}, //7414 #CJK UNIFIED IDEOGRAPH + {0xD362, 0x7F92}, //7415 #CJK UNIFIED IDEOGRAPH + {0xD363, 0x7FC3}, //7416 #CJK UNIFIED IDEOGRAPH + {0xD364, 0x7FC2}, //7417 #CJK UNIFIED IDEOGRAPH + {0xD365, 0x7FC0}, //7418 #CJK UNIFIED IDEOGRAPH + {0xD366, 0x8016}, //7419 #CJK UNIFIED IDEOGRAPH + {0xD367, 0x803E}, //7420 #CJK UNIFIED IDEOGRAPH + {0xD368, 0x8039}, //7421 #CJK UNIFIED IDEOGRAPH + {0xD369, 0x80FA}, //7422 #CJK UNIFIED IDEOGRAPH + {0xD36A, 0x80F2}, //7423 #CJK UNIFIED IDEOGRAPH + {0xD36B, 0x80F9}, //7424 #CJK UNIFIED IDEOGRAPH + {0xD36C, 0x80F5}, //7425 #CJK UNIFIED IDEOGRAPH + {0xD36D, 0x8101}, //7426 #CJK UNIFIED IDEOGRAPH + {0xD36E, 0x80FB}, //7427 #CJK UNIFIED IDEOGRAPH + {0xD36F, 0x8100}, //7428 #CJK UNIFIED IDEOGRAPH + {0xD370, 0x8201}, //7429 #CJK UNIFIED IDEOGRAPH + {0xD371, 0x822F}, //7430 #CJK UNIFIED IDEOGRAPH + {0xD372, 0x8225}, //7431 #CJK UNIFIED IDEOGRAPH + {0xD373, 0x8333}, //7432 #CJK UNIFIED IDEOGRAPH + {0xD374, 0x832D}, //7433 #CJK UNIFIED IDEOGRAPH + {0xD375, 0x8344}, //7434 #CJK UNIFIED IDEOGRAPH + {0xD376, 0x8319}, //7435 #CJK UNIFIED IDEOGRAPH + {0xD377, 0x8351}, //7436 #CJK UNIFIED IDEOGRAPH + {0xD378, 0x8325}, //7437 #CJK UNIFIED IDEOGRAPH + {0xD379, 0x8356}, //7438 #CJK UNIFIED IDEOGRAPH + {0xD37A, 0x833F}, //7439 #CJK UNIFIED IDEOGRAPH + {0xD37B, 0x8341}, //7440 #CJK UNIFIED IDEOGRAPH + {0xD37C, 0x8326}, //7441 #CJK UNIFIED IDEOGRAPH + {0xD37D, 0x831C}, //7442 #CJK UNIFIED IDEOGRAPH + {0xD37E, 0x8322}, //7443 #CJK UNIFIED IDEOGRAPH + {0xD3A1, 0x8342}, //7444 #CJK UNIFIED IDEOGRAPH + {0xD3A2, 0x834E}, //7445 #CJK UNIFIED IDEOGRAPH + {0xD3A3, 0x831B}, //7446 #CJK UNIFIED IDEOGRAPH + {0xD3A4, 0x832A}, //7447 #CJK UNIFIED IDEOGRAPH + {0xD3A5, 0x8308}, //7448 #CJK UNIFIED IDEOGRAPH + {0xD3A6, 0x833C}, //7449 #CJK UNIFIED IDEOGRAPH + {0xD3A7, 0x834D}, //7450 #CJK UNIFIED IDEOGRAPH + {0xD3A8, 0x8316}, //7451 #CJK UNIFIED IDEOGRAPH + {0xD3A9, 0x8324}, //7452 #CJK UNIFIED IDEOGRAPH + {0xD3AA, 0x8320}, //7453 #CJK UNIFIED IDEOGRAPH + {0xD3AB, 0x8337}, //7454 #CJK UNIFIED IDEOGRAPH + {0xD3AC, 0x832F}, //7455 #CJK UNIFIED IDEOGRAPH + {0xD3AD, 0x8329}, //7456 #CJK UNIFIED IDEOGRAPH + {0xD3AE, 0x8347}, //7457 #CJK UNIFIED IDEOGRAPH + {0xD3AF, 0x8345}, //7458 #CJK UNIFIED IDEOGRAPH + {0xD3B0, 0x834C}, //7459 #CJK UNIFIED IDEOGRAPH + {0xD3B1, 0x8353}, //7460 #CJK UNIFIED IDEOGRAPH + {0xD3B2, 0x831E}, //7461 #CJK UNIFIED IDEOGRAPH + {0xD3B3, 0x832C}, //7462 #CJK UNIFIED IDEOGRAPH + {0xD3B4, 0x834B}, //7463 #CJK UNIFIED IDEOGRAPH + {0xD3B5, 0x8327}, //7464 #CJK UNIFIED IDEOGRAPH + {0xD3B6, 0x8348}, //7465 #CJK UNIFIED IDEOGRAPH + {0xD3B7, 0x8653}, //7466 #CJK UNIFIED IDEOGRAPH + {0xD3B8, 0x8652}, //7467 #CJK UNIFIED IDEOGRAPH + {0xD3B9, 0x86A2}, //7468 #CJK UNIFIED IDEOGRAPH + {0xD3BA, 0x86A8}, //7469 #CJK UNIFIED IDEOGRAPH + {0xD3BB, 0x8696}, //7470 #CJK UNIFIED IDEOGRAPH + {0xD3BC, 0x868D}, //7471 #CJK UNIFIED IDEOGRAPH + {0xD3BD, 0x8691}, //7472 #CJK UNIFIED IDEOGRAPH + {0xD3BE, 0x869E}, //7473 #CJK UNIFIED IDEOGRAPH + {0xD3BF, 0x8687}, //7474 #CJK UNIFIED IDEOGRAPH + {0xD3C0, 0x8697}, //7475 #CJK UNIFIED IDEOGRAPH + {0xD3C1, 0x8686}, //7476 #CJK UNIFIED IDEOGRAPH + {0xD3C2, 0x868B}, //7477 #CJK UNIFIED IDEOGRAPH + {0xD3C3, 0x869A}, //7478 #CJK UNIFIED IDEOGRAPH + {0xD3C4, 0x8685}, //7479 #CJK UNIFIED IDEOGRAPH + {0xD3C5, 0x86A5}, //7480 #CJK UNIFIED IDEOGRAPH + {0xD3C6, 0x8699}, //7481 #CJK UNIFIED IDEOGRAPH + {0xD3C7, 0x86A1}, //7482 #CJK UNIFIED IDEOGRAPH + {0xD3C8, 0x86A7}, //7483 #CJK UNIFIED IDEOGRAPH + {0xD3C9, 0x8695}, //7484 #CJK UNIFIED IDEOGRAPH + {0xD3CA, 0x8698}, //7485 #CJK UNIFIED IDEOGRAPH + {0xD3CB, 0x868E}, //7486 #CJK UNIFIED IDEOGRAPH + {0xD3CC, 0x869D}, //7487 #CJK UNIFIED IDEOGRAPH + {0xD3CD, 0x8690}, //7488 #CJK UNIFIED IDEOGRAPH + {0xD3CE, 0x8694}, //7489 #CJK UNIFIED IDEOGRAPH + {0xD3CF, 0x8843}, //7490 #CJK UNIFIED IDEOGRAPH + {0xD3D0, 0x8844}, //7491 #CJK UNIFIED IDEOGRAPH + {0xD3D1, 0x886D}, //7492 #CJK UNIFIED IDEOGRAPH + {0xD3D2, 0x8875}, //7493 #CJK UNIFIED IDEOGRAPH + {0xD3D3, 0x8876}, //7494 #CJK UNIFIED IDEOGRAPH + {0xD3D4, 0x8872}, //7495 #CJK UNIFIED IDEOGRAPH + {0xD3D5, 0x8880}, //7496 #CJK UNIFIED IDEOGRAPH + {0xD3D6, 0x8871}, //7497 #CJK UNIFIED IDEOGRAPH + {0xD3D7, 0x887F}, //7498 #CJK UNIFIED IDEOGRAPH + {0xD3D8, 0x886F}, //7499 #CJK UNIFIED IDEOGRAPH + {0xD3D9, 0x8883}, //7500 #CJK UNIFIED IDEOGRAPH + {0xD3DA, 0x887E}, //7501 #CJK UNIFIED IDEOGRAPH + {0xD3DB, 0x8874}, //7502 #CJK UNIFIED IDEOGRAPH + {0xD3DC, 0x887C}, //7503 #CJK UNIFIED IDEOGRAPH + {0xD3DD, 0x8A12}, //7504 #CJK UNIFIED IDEOGRAPH + {0xD3DE, 0x8C47}, //7505 #CJK UNIFIED IDEOGRAPH + {0xD3DF, 0x8C57}, //7506 #CJK UNIFIED IDEOGRAPH + {0xD3E0, 0x8C7B}, //7507 #CJK UNIFIED IDEOGRAPH + {0xD3E1, 0x8CA4}, //7508 #CJK UNIFIED IDEOGRAPH + {0xD3E2, 0x8CA3}, //7509 #CJK UNIFIED IDEOGRAPH + {0xD3E3, 0x8D76}, //7510 #CJK UNIFIED IDEOGRAPH + {0xD3E4, 0x8D78}, //7511 #CJK UNIFIED IDEOGRAPH + {0xD3E5, 0x8DB5}, //7512 #CJK UNIFIED IDEOGRAPH + {0xD3E6, 0x8DB7}, //7513 #CJK UNIFIED IDEOGRAPH + {0xD3E7, 0x8DB6}, //7514 #CJK UNIFIED IDEOGRAPH + {0xD3E8, 0x8ED1}, //7515 #CJK UNIFIED IDEOGRAPH + {0xD3E9, 0x8ED3}, //7516 #CJK UNIFIED IDEOGRAPH + {0xD3EA, 0x8FFE}, //7517 #CJK UNIFIED IDEOGRAPH + {0xD3EB, 0x8FF5}, //7518 #CJK UNIFIED IDEOGRAPH + {0xD3EC, 0x9002}, //7519 #CJK UNIFIED IDEOGRAPH + {0xD3ED, 0x8FFF}, //7520 #CJK UNIFIED IDEOGRAPH + {0xD3EE, 0x8FFB}, //7521 #CJK UNIFIED IDEOGRAPH + {0xD3EF, 0x9004}, //7522 #CJK UNIFIED IDEOGRAPH + {0xD3F0, 0x8FFC}, //7523 #CJK UNIFIED IDEOGRAPH + {0xD3F1, 0x8FF6}, //7524 #CJK UNIFIED IDEOGRAPH + {0xD3F2, 0x90D6}, //7525 #CJK UNIFIED IDEOGRAPH + {0xD3F3, 0x90E0}, //7526 #CJK UNIFIED IDEOGRAPH + {0xD3F4, 0x90D9}, //7527 #CJK UNIFIED IDEOGRAPH + {0xD3F5, 0x90DA}, //7528 #CJK UNIFIED IDEOGRAPH + {0xD3F6, 0x90E3}, //7529 #CJK UNIFIED IDEOGRAPH + {0xD3F7, 0x90DF}, //7530 #CJK UNIFIED IDEOGRAPH + {0xD3F8, 0x90E5}, //7531 #CJK UNIFIED IDEOGRAPH + {0xD3F9, 0x90D8}, //7532 #CJK UNIFIED IDEOGRAPH + {0xD3FA, 0x90DB}, //7533 #CJK UNIFIED IDEOGRAPH + {0xD3FB, 0x90D7}, //7534 #CJK UNIFIED IDEOGRAPH + {0xD3FC, 0x90DC}, //7535 #CJK UNIFIED IDEOGRAPH + {0xD3FD, 0x90E4}, //7536 #CJK UNIFIED IDEOGRAPH + {0xD3FE, 0x9150}, //7537 #CJK UNIFIED IDEOGRAPH + {0xD440, 0x914E}, //7538 #CJK UNIFIED IDEOGRAPH + {0xD441, 0x914F}, //7539 #CJK UNIFIED IDEOGRAPH + {0xD442, 0x91D5}, //7540 #CJK UNIFIED IDEOGRAPH + {0xD443, 0x91E2}, //7541 #CJK UNIFIED IDEOGRAPH + {0xD444, 0x91DA}, //7542 #CJK UNIFIED IDEOGRAPH + {0xD445, 0x965C}, //7543 #CJK UNIFIED IDEOGRAPH + {0xD446, 0x965F}, //7544 #CJK UNIFIED IDEOGRAPH + {0xD447, 0x96BC}, //7545 #CJK UNIFIED IDEOGRAPH + {0xD448, 0x98E3}, //7546 #CJK UNIFIED IDEOGRAPH + {0xD449, 0x9ADF}, //7547 #CJK UNIFIED IDEOGRAPH + {0xD44A, 0x9B2F}, //7548 #CJK UNIFIED IDEOGRAPH + {0xD44B, 0x4E7F}, //7549 #CJK UNIFIED IDEOGRAPH + {0xD44C, 0x5070}, //7550 #CJK UNIFIED IDEOGRAPH + {0xD44D, 0x506A}, //7551 #CJK UNIFIED IDEOGRAPH + {0xD44E, 0x5061}, //7552 #CJK UNIFIED IDEOGRAPH + {0xD44F, 0x505E}, //7553 #CJK UNIFIED IDEOGRAPH + {0xD450, 0x5060}, //7554 #CJK UNIFIED IDEOGRAPH + {0xD451, 0x5053}, //7555 #CJK UNIFIED IDEOGRAPH + {0xD452, 0x504B}, //7556 #CJK UNIFIED IDEOGRAPH + {0xD453, 0x505D}, //7557 #CJK UNIFIED IDEOGRAPH + {0xD454, 0x5072}, //7558 #CJK UNIFIED IDEOGRAPH + {0xD455, 0x5048}, //7559 #CJK UNIFIED IDEOGRAPH + {0xD456, 0x504D}, //7560 #CJK UNIFIED IDEOGRAPH + {0xD457, 0x5041}, //7561 #CJK UNIFIED IDEOGRAPH + {0xD458, 0x505B}, //7562 #CJK UNIFIED IDEOGRAPH + {0xD459, 0x504A}, //7563 #CJK UNIFIED IDEOGRAPH + {0xD45A, 0x5062}, //7564 #CJK UNIFIED IDEOGRAPH + {0xD45B, 0x5015}, //7565 #CJK UNIFIED IDEOGRAPH + {0xD45C, 0x5045}, //7566 #CJK UNIFIED IDEOGRAPH + {0xD45D, 0x505F}, //7567 #CJK UNIFIED IDEOGRAPH + {0xD45E, 0x5069}, //7568 #CJK UNIFIED IDEOGRAPH + {0xD45F, 0x506B}, //7569 #CJK UNIFIED IDEOGRAPH + {0xD460, 0x5063}, //7570 #CJK UNIFIED IDEOGRAPH + {0xD461, 0x5064}, //7571 #CJK UNIFIED IDEOGRAPH + {0xD462, 0x5046}, //7572 #CJK UNIFIED IDEOGRAPH + {0xD463, 0x5040}, //7573 #CJK UNIFIED IDEOGRAPH + {0xD464, 0x506E}, //7574 #CJK UNIFIED IDEOGRAPH + {0xD465, 0x5073}, //7575 #CJK UNIFIED IDEOGRAPH + {0xD466, 0x5057}, //7576 #CJK UNIFIED IDEOGRAPH + {0xD467, 0x5051}, //7577 #CJK UNIFIED IDEOGRAPH + {0xD468, 0x51D0}, //7578 #CJK UNIFIED IDEOGRAPH + {0xD469, 0x526B}, //7579 #CJK UNIFIED IDEOGRAPH + {0xD46A, 0x526D}, //7580 #CJK UNIFIED IDEOGRAPH + {0xD46B, 0x526C}, //7581 #CJK UNIFIED IDEOGRAPH + {0xD46C, 0x526E}, //7582 #CJK UNIFIED IDEOGRAPH + {0xD46D, 0x52D6}, //7583 #CJK UNIFIED IDEOGRAPH + {0xD46E, 0x52D3}, //7584 #CJK UNIFIED IDEOGRAPH + {0xD46F, 0x532D}, //7585 #CJK UNIFIED IDEOGRAPH + {0xD470, 0x539C}, //7586 #CJK UNIFIED IDEOGRAPH + {0xD471, 0x5575}, //7587 #CJK UNIFIED IDEOGRAPH + {0xD472, 0x5576}, //7588 #CJK UNIFIED IDEOGRAPH + {0xD473, 0x553C}, //7589 #CJK UNIFIED IDEOGRAPH + {0xD474, 0x554D}, //7590 #CJK UNIFIED IDEOGRAPH + {0xD475, 0x5550}, //7591 #CJK UNIFIED IDEOGRAPH + {0xD476, 0x5534}, //7592 #CJK UNIFIED IDEOGRAPH + {0xD477, 0x552A}, //7593 #CJK UNIFIED IDEOGRAPH + {0xD478, 0x5551}, //7594 #CJK UNIFIED IDEOGRAPH + {0xD479, 0x5562}, //7595 #CJK UNIFIED IDEOGRAPH + {0xD47A, 0x5536}, //7596 #CJK UNIFIED IDEOGRAPH + {0xD47B, 0x5535}, //7597 #CJK UNIFIED IDEOGRAPH + {0xD47C, 0x5530}, //7598 #CJK UNIFIED IDEOGRAPH + {0xD47D, 0x5552}, //7599 #CJK UNIFIED IDEOGRAPH + {0xD47E, 0x5545}, //7600 #CJK UNIFIED IDEOGRAPH + {0xD4A1, 0x550C}, //7601 #CJK UNIFIED IDEOGRAPH + {0xD4A2, 0x5532}, //7602 #CJK UNIFIED IDEOGRAPH + {0xD4A3, 0x5565}, //7603 #CJK UNIFIED IDEOGRAPH + {0xD4A4, 0x554E}, //7604 #CJK UNIFIED IDEOGRAPH + {0xD4A5, 0x5539}, //7605 #CJK UNIFIED IDEOGRAPH + {0xD4A6, 0x5548}, //7606 #CJK UNIFIED IDEOGRAPH + {0xD4A7, 0x552D}, //7607 #CJK UNIFIED IDEOGRAPH + {0xD4A8, 0x553B}, //7608 #CJK UNIFIED IDEOGRAPH + {0xD4A9, 0x5540}, //7609 #CJK UNIFIED IDEOGRAPH + {0xD4AA, 0x554B}, //7610 #CJK UNIFIED IDEOGRAPH + {0xD4AB, 0x570A}, //7611 #CJK UNIFIED IDEOGRAPH + {0xD4AC, 0x5707}, //7612 #CJK UNIFIED IDEOGRAPH + {0xD4AD, 0x57FB}, //7613 #CJK UNIFIED IDEOGRAPH + {0xD4AE, 0x5814}, //7614 #CJK UNIFIED IDEOGRAPH + {0xD4AF, 0x57E2}, //7615 #CJK UNIFIED IDEOGRAPH + {0xD4B0, 0x57F6}, //7616 #CJK UNIFIED IDEOGRAPH + {0xD4B1, 0x57DC}, //7617 #CJK UNIFIED IDEOGRAPH + {0xD4B2, 0x57F4}, //7618 #CJK UNIFIED IDEOGRAPH + {0xD4B3, 0x5800}, //7619 #CJK UNIFIED IDEOGRAPH + {0xD4B4, 0x57ED}, //7620 #CJK UNIFIED IDEOGRAPH + {0xD4B5, 0x57FD}, //7621 #CJK UNIFIED IDEOGRAPH + {0xD4B6, 0x5808}, //7622 #CJK UNIFIED IDEOGRAPH + {0xD4B7, 0x57F8}, //7623 #CJK UNIFIED IDEOGRAPH + {0xD4B8, 0x580B}, //7624 #CJK UNIFIED IDEOGRAPH + {0xD4B9, 0x57F3}, //7625 #CJK UNIFIED IDEOGRAPH + {0xD4BA, 0x57CF}, //7626 #CJK UNIFIED IDEOGRAPH + {0xD4BB, 0x5807}, //7627 #CJK UNIFIED IDEOGRAPH + {0xD4BC, 0x57EE}, //7628 #CJK UNIFIED IDEOGRAPH + {0xD4BD, 0x57E3}, //7629 #CJK UNIFIED IDEOGRAPH + {0xD4BE, 0x57F2}, //7630 #CJK UNIFIED IDEOGRAPH + {0xD4BF, 0x57E5}, //7631 #CJK UNIFIED IDEOGRAPH + {0xD4C0, 0x57EC}, //7632 #CJK UNIFIED IDEOGRAPH + {0xD4C1, 0x57E1}, //7633 #CJK UNIFIED IDEOGRAPH + {0xD4C2, 0x580E}, //7634 #CJK UNIFIED IDEOGRAPH + {0xD4C3, 0x57FC}, //7635 #CJK UNIFIED IDEOGRAPH + {0xD4C4, 0x5810}, //7636 #CJK UNIFIED IDEOGRAPH + {0xD4C5, 0x57E7}, //7637 #CJK UNIFIED IDEOGRAPH + {0xD4C6, 0x5801}, //7638 #CJK UNIFIED IDEOGRAPH + {0xD4C7, 0x580C}, //7639 #CJK UNIFIED IDEOGRAPH + {0xD4C8, 0x57F1}, //7640 #CJK UNIFIED IDEOGRAPH + {0xD4C9, 0x57E9}, //7641 #CJK UNIFIED IDEOGRAPH + {0xD4CA, 0x57F0}, //7642 #CJK UNIFIED IDEOGRAPH + {0xD4CB, 0x580D}, //7643 #CJK UNIFIED IDEOGRAPH + {0xD4CC, 0x5804}, //7644 #CJK UNIFIED IDEOGRAPH + {0xD4CD, 0x595C}, //7645 #CJK UNIFIED IDEOGRAPH + {0xD4CE, 0x5A60}, //7646 #CJK UNIFIED IDEOGRAPH + {0xD4CF, 0x5A58}, //7647 #CJK UNIFIED IDEOGRAPH + {0xD4D0, 0x5A55}, //7648 #CJK UNIFIED IDEOGRAPH + {0xD4D1, 0x5A67}, //7649 #CJK UNIFIED IDEOGRAPH + {0xD4D2, 0x5A5E}, //7650 #CJK UNIFIED IDEOGRAPH + {0xD4D3, 0x5A38}, //7651 #CJK UNIFIED IDEOGRAPH + {0xD4D4, 0x5A35}, //7652 #CJK UNIFIED IDEOGRAPH + {0xD4D5, 0x5A6D}, //7653 #CJK UNIFIED IDEOGRAPH + {0xD4D6, 0x5A50}, //7654 #CJK UNIFIED IDEOGRAPH + {0xD4D7, 0x5A5F}, //7655 #CJK UNIFIED IDEOGRAPH + {0xD4D8, 0x5A65}, //7656 #CJK UNIFIED IDEOGRAPH + {0xD4D9, 0x5A6C}, //7657 #CJK UNIFIED IDEOGRAPH + {0xD4DA, 0x5A53}, //7658 #CJK UNIFIED IDEOGRAPH + {0xD4DB, 0x5A64}, //7659 #CJK UNIFIED IDEOGRAPH + {0xD4DC, 0x5A57}, //7660 #CJK UNIFIED IDEOGRAPH + {0xD4DD, 0x5A43}, //7661 #CJK UNIFIED IDEOGRAPH + {0xD4DE, 0x5A5D}, //7662 #CJK UNIFIED IDEOGRAPH + {0xD4DF, 0x5A52}, //7663 #CJK UNIFIED IDEOGRAPH + {0xD4E0, 0x5A44}, //7664 #CJK UNIFIED IDEOGRAPH + {0xD4E1, 0x5A5B}, //7665 #CJK UNIFIED IDEOGRAPH + {0xD4E2, 0x5A48}, //7666 #CJK UNIFIED IDEOGRAPH + {0xD4E3, 0x5A8E}, //7667 #CJK UNIFIED IDEOGRAPH + {0xD4E4, 0x5A3E}, //7668 #CJK UNIFIED IDEOGRAPH + {0xD4E5, 0x5A4D}, //7669 #CJK UNIFIED IDEOGRAPH + {0xD4E6, 0x5A39}, //7670 #CJK UNIFIED IDEOGRAPH + {0xD4E7, 0x5A4C}, //7671 #CJK UNIFIED IDEOGRAPH + {0xD4E8, 0x5A70}, //7672 #CJK UNIFIED IDEOGRAPH + {0xD4E9, 0x5A69}, //7673 #CJK UNIFIED IDEOGRAPH + {0xD4EA, 0x5A47}, //7674 #CJK UNIFIED IDEOGRAPH + {0xD4EB, 0x5A51}, //7675 #CJK UNIFIED IDEOGRAPH + {0xD4EC, 0x5A56}, //7676 #CJK UNIFIED IDEOGRAPH + {0xD4ED, 0x5A42}, //7677 #CJK UNIFIED IDEOGRAPH + {0xD4EE, 0x5A5C}, //7678 #CJK UNIFIED IDEOGRAPH + {0xD4EF, 0x5B72}, //7679 #CJK UNIFIED IDEOGRAPH + {0xD4F0, 0x5B6E}, //7680 #CJK UNIFIED IDEOGRAPH + {0xD4F1, 0x5BC1}, //7681 #CJK UNIFIED IDEOGRAPH + {0xD4F2, 0x5BC0}, //7682 #CJK UNIFIED IDEOGRAPH + {0xD4F3, 0x5C59}, //7683 #CJK UNIFIED IDEOGRAPH + {0xD4F4, 0x5D1E}, //7684 #CJK UNIFIED IDEOGRAPH + {0xD4F5, 0x5D0B}, //7685 #CJK UNIFIED IDEOGRAPH + {0xD4F6, 0x5D1D}, //7686 #CJK UNIFIED IDEOGRAPH + {0xD4F7, 0x5D1A}, //7687 #CJK UNIFIED IDEOGRAPH + {0xD4F8, 0x5D20}, //7688 #CJK UNIFIED IDEOGRAPH + {0xD4F9, 0x5D0C}, //7689 #CJK UNIFIED IDEOGRAPH + {0xD4FA, 0x5D28}, //7690 #CJK UNIFIED IDEOGRAPH + {0xD4FB, 0x5D0D}, //7691 #CJK UNIFIED IDEOGRAPH + {0xD4FC, 0x5D26}, //7692 #CJK UNIFIED IDEOGRAPH + {0xD4FD, 0x5D25}, //7693 #CJK UNIFIED IDEOGRAPH + {0xD4FE, 0x5D0F}, //7694 #CJK UNIFIED IDEOGRAPH + {0xD540, 0x5D30}, //7695 #CJK UNIFIED IDEOGRAPH + {0xD541, 0x5D12}, //7696 #CJK UNIFIED IDEOGRAPH + {0xD542, 0x5D23}, //7697 #CJK UNIFIED IDEOGRAPH + {0xD543, 0x5D1F}, //7698 #CJK UNIFIED IDEOGRAPH + {0xD544, 0x5D2E}, //7699 #CJK UNIFIED IDEOGRAPH + {0xD545, 0x5E3E}, //7700 #CJK UNIFIED IDEOGRAPH + {0xD546, 0x5E34}, //7701 #CJK UNIFIED IDEOGRAPH + {0xD547, 0x5EB1}, //7702 #CJK UNIFIED IDEOGRAPH + {0xD548, 0x5EB4}, //7703 #CJK UNIFIED IDEOGRAPH + {0xD549, 0x5EB9}, //7704 #CJK UNIFIED IDEOGRAPH + {0xD54A, 0x5EB2}, //7705 #CJK UNIFIED IDEOGRAPH + {0xD54B, 0x5EB3}, //7706 #CJK UNIFIED IDEOGRAPH + {0xD54C, 0x5F36}, //7707 #CJK UNIFIED IDEOGRAPH + {0xD54D, 0x5F38}, //7708 #CJK UNIFIED IDEOGRAPH + {0xD54E, 0x5F9B}, //7709 #CJK UNIFIED IDEOGRAPH + {0xD54F, 0x5F96}, //7710 #CJK UNIFIED IDEOGRAPH + {0xD550, 0x5F9F}, //7711 #CJK UNIFIED IDEOGRAPH + {0xD551, 0x608A}, //7712 #CJK UNIFIED IDEOGRAPH + {0xD552, 0x6090}, //7713 #CJK UNIFIED IDEOGRAPH + {0xD553, 0x6086}, //7714 #CJK UNIFIED IDEOGRAPH + {0xD554, 0x60BE}, //7715 #CJK UNIFIED IDEOGRAPH + {0xD555, 0x60B0}, //7716 #CJK UNIFIED IDEOGRAPH + {0xD556, 0x60BA}, //7717 #CJK UNIFIED IDEOGRAPH + {0xD557, 0x60D3}, //7718 #CJK UNIFIED IDEOGRAPH + {0xD558, 0x60D4}, //7719 #CJK UNIFIED IDEOGRAPH + {0xD559, 0x60CF}, //7720 #CJK UNIFIED IDEOGRAPH + {0xD55A, 0x60E4}, //7721 #CJK UNIFIED IDEOGRAPH + {0xD55B, 0x60D9}, //7722 #CJK UNIFIED IDEOGRAPH + {0xD55C, 0x60DD}, //7723 #CJK UNIFIED IDEOGRAPH + {0xD55D, 0x60C8}, //7724 #CJK UNIFIED IDEOGRAPH + {0xD55E, 0x60B1}, //7725 #CJK UNIFIED IDEOGRAPH + {0xD55F, 0x60DB}, //7726 #CJK UNIFIED IDEOGRAPH + {0xD560, 0x60B7}, //7727 #CJK UNIFIED IDEOGRAPH + {0xD561, 0x60CA}, //7728 #CJK UNIFIED IDEOGRAPH + {0xD562, 0x60BF}, //7729 #CJK UNIFIED IDEOGRAPH + {0xD563, 0x60C3}, //7730 #CJK UNIFIED IDEOGRAPH + {0xD564, 0x60CD}, //7731 #CJK UNIFIED IDEOGRAPH + {0xD565, 0x60C0}, //7732 #CJK UNIFIED IDEOGRAPH + {0xD566, 0x6332}, //7733 #CJK UNIFIED IDEOGRAPH + {0xD567, 0x6365}, //7734 #CJK UNIFIED IDEOGRAPH + {0xD568, 0x638A}, //7735 #CJK UNIFIED IDEOGRAPH + {0xD569, 0x6382}, //7736 #CJK UNIFIED IDEOGRAPH + {0xD56A, 0x637D}, //7737 #CJK UNIFIED IDEOGRAPH + {0xD56B, 0x63BD}, //7738 #CJK UNIFIED IDEOGRAPH + {0xD56C, 0x639E}, //7739 #CJK UNIFIED IDEOGRAPH + {0xD56D, 0x63AD}, //7740 #CJK UNIFIED IDEOGRAPH + {0xD56E, 0x639D}, //7741 #CJK UNIFIED IDEOGRAPH + {0xD56F, 0x6397}, //7742 #CJK UNIFIED IDEOGRAPH + {0xD570, 0x63AB}, //7743 #CJK UNIFIED IDEOGRAPH + {0xD571, 0x638E}, //7744 #CJK UNIFIED IDEOGRAPH + {0xD572, 0x636F}, //7745 #CJK UNIFIED IDEOGRAPH + {0xD573, 0x6387}, //7746 #CJK UNIFIED IDEOGRAPH + {0xD574, 0x6390}, //7747 #CJK UNIFIED IDEOGRAPH + {0xD575, 0x636E}, //7748 #CJK UNIFIED IDEOGRAPH + {0xD576, 0x63AF}, //7749 #CJK UNIFIED IDEOGRAPH + {0xD577, 0x6375}, //7750 #CJK UNIFIED IDEOGRAPH + {0xD578, 0x639C}, //7751 #CJK UNIFIED IDEOGRAPH + {0xD579, 0x636D}, //7752 #CJK UNIFIED IDEOGRAPH + {0xD57A, 0x63AE}, //7753 #CJK UNIFIED IDEOGRAPH + {0xD57B, 0x637C}, //7754 #CJK UNIFIED IDEOGRAPH + {0xD57C, 0x63A4}, //7755 #CJK UNIFIED IDEOGRAPH + {0xD57D, 0x633B}, //7756 #CJK UNIFIED IDEOGRAPH + {0xD57E, 0x639F}, //7757 #CJK UNIFIED IDEOGRAPH + {0xD5A1, 0x6378}, //7758 #CJK UNIFIED IDEOGRAPH + {0xD5A2, 0x6385}, //7759 #CJK UNIFIED IDEOGRAPH + {0xD5A3, 0x6381}, //7760 #CJK UNIFIED IDEOGRAPH + {0xD5A4, 0x6391}, //7761 #CJK UNIFIED IDEOGRAPH + {0xD5A5, 0x638D}, //7762 #CJK UNIFIED IDEOGRAPH + {0xD5A6, 0x6370}, //7763 #CJK UNIFIED IDEOGRAPH + {0xD5A7, 0x6553}, //7764 #CJK UNIFIED IDEOGRAPH + {0xD5A8, 0x65CD}, //7765 #CJK UNIFIED IDEOGRAPH + {0xD5A9, 0x6665}, //7766 #CJK UNIFIED IDEOGRAPH + {0xD5AA, 0x6661}, //7767 #CJK UNIFIED IDEOGRAPH + {0xD5AB, 0x665B}, //7768 #CJK UNIFIED IDEOGRAPH + {0xD5AC, 0x6659}, //7769 #CJK UNIFIED IDEOGRAPH + {0xD5AD, 0x665C}, //7770 #CJK UNIFIED IDEOGRAPH + {0xD5AE, 0x6662}, //7771 #CJK UNIFIED IDEOGRAPH + {0xD5AF, 0x6718}, //7772 #CJK UNIFIED IDEOGRAPH + {0xD5B0, 0x6879}, //7773 #CJK UNIFIED IDEOGRAPH + {0xD5B1, 0x6887}, //7774 #CJK UNIFIED IDEOGRAPH + {0xD5B2, 0x6890}, //7775 #CJK UNIFIED IDEOGRAPH + {0xD5B3, 0x689C}, //7776 #CJK UNIFIED IDEOGRAPH + {0xD5B4, 0x686D}, //7777 #CJK UNIFIED IDEOGRAPH + {0xD5B5, 0x686E}, //7778 #CJK UNIFIED IDEOGRAPH + {0xD5B6, 0x68AE}, //7779 #CJK UNIFIED IDEOGRAPH + {0xD5B7, 0x68AB}, //7780 #CJK UNIFIED IDEOGRAPH + {0xD5B8, 0x6956}, //7781 #CJK UNIFIED IDEOGRAPH + {0xD5B9, 0x686F}, //7782 #CJK UNIFIED IDEOGRAPH + {0xD5BA, 0x68A3}, //7783 #CJK UNIFIED IDEOGRAPH + {0xD5BB, 0x68AC}, //7784 #CJK UNIFIED IDEOGRAPH + {0xD5BC, 0x68A9}, //7785 #CJK UNIFIED IDEOGRAPH + {0xD5BD, 0x6875}, //7786 #CJK UNIFIED IDEOGRAPH + {0xD5BE, 0x6874}, //7787 #CJK UNIFIED IDEOGRAPH + {0xD5BF, 0x68B2}, //7788 #CJK UNIFIED IDEOGRAPH + {0xD5C0, 0x688F}, //7789 #CJK UNIFIED IDEOGRAPH + {0xD5C1, 0x6877}, //7790 #CJK UNIFIED IDEOGRAPH + {0xD5C2, 0x6892}, //7791 #CJK UNIFIED IDEOGRAPH + {0xD5C3, 0x687C}, //7792 #CJK UNIFIED IDEOGRAPH + {0xD5C4, 0x686B}, //7793 #CJK UNIFIED IDEOGRAPH + {0xD5C5, 0x6872}, //7794 #CJK UNIFIED IDEOGRAPH + {0xD5C6, 0x68AA}, //7795 #CJK UNIFIED IDEOGRAPH + {0xD5C7, 0x6880}, //7796 #CJK UNIFIED IDEOGRAPH + {0xD5C8, 0x6871}, //7797 #CJK UNIFIED IDEOGRAPH + {0xD5C9, 0x687E}, //7798 #CJK UNIFIED IDEOGRAPH + {0xD5CA, 0x689B}, //7799 #CJK UNIFIED IDEOGRAPH + {0xD5CB, 0x6896}, //7800 #CJK UNIFIED IDEOGRAPH + {0xD5CC, 0x688B}, //7801 #CJK UNIFIED IDEOGRAPH + {0xD5CD, 0x68A0}, //7802 #CJK UNIFIED IDEOGRAPH + {0xD5CE, 0x6889}, //7803 #CJK UNIFIED IDEOGRAPH + {0xD5CF, 0x68A4}, //7804 #CJK UNIFIED IDEOGRAPH + {0xD5D0, 0x6878}, //7805 #CJK UNIFIED IDEOGRAPH + {0xD5D1, 0x687B}, //7806 #CJK UNIFIED IDEOGRAPH + {0xD5D2, 0x6891}, //7807 #CJK UNIFIED IDEOGRAPH + {0xD5D3, 0x688C}, //7808 #CJK UNIFIED IDEOGRAPH + {0xD5D4, 0x688A}, //7809 #CJK UNIFIED IDEOGRAPH + {0xD5D5, 0x687D}, //7810 #CJK UNIFIED IDEOGRAPH + {0xD5D6, 0x6B36}, //7811 #CJK UNIFIED IDEOGRAPH + {0xD5D7, 0x6B33}, //7812 #CJK UNIFIED IDEOGRAPH + {0xD5D8, 0x6B37}, //7813 #CJK UNIFIED IDEOGRAPH + {0xD5D9, 0x6B38}, //7814 #CJK UNIFIED IDEOGRAPH + {0xD5DA, 0x6B91}, //7815 #CJK UNIFIED IDEOGRAPH + {0xD5DB, 0x6B8F}, //7816 #CJK UNIFIED IDEOGRAPH + {0xD5DC, 0x6B8D}, //7817 #CJK UNIFIED IDEOGRAPH + {0xD5DD, 0x6B8E}, //7818 #CJK UNIFIED IDEOGRAPH + {0xD5DE, 0x6B8C}, //7819 #CJK UNIFIED IDEOGRAPH + {0xD5DF, 0x6C2A}, //7820 #CJK UNIFIED IDEOGRAPH + {0xD5E0, 0x6DC0}, //7821 #CJK UNIFIED IDEOGRAPH + {0xD5E1, 0x6DAB}, //7822 #CJK UNIFIED IDEOGRAPH + {0xD5E2, 0x6DB4}, //7823 #CJK UNIFIED IDEOGRAPH + {0xD5E3, 0x6DB3}, //7824 #CJK UNIFIED IDEOGRAPH + {0xD5E4, 0x6E74}, //7825 #CJK UNIFIED IDEOGRAPH + {0xD5E5, 0x6DAC}, //7826 #CJK UNIFIED IDEOGRAPH + {0xD5E6, 0x6DE9}, //7827 #CJK UNIFIED IDEOGRAPH + {0xD5E7, 0x6DE2}, //7828 #CJK UNIFIED IDEOGRAPH + {0xD5E8, 0x6DB7}, //7829 #CJK UNIFIED IDEOGRAPH + {0xD5E9, 0x6DF6}, //7830 #CJK UNIFIED IDEOGRAPH + {0xD5EA, 0x6DD4}, //7831 #CJK UNIFIED IDEOGRAPH + {0xD5EB, 0x6E00}, //7832 #CJK UNIFIED IDEOGRAPH + {0xD5EC, 0x6DC8}, //7833 #CJK UNIFIED IDEOGRAPH + {0xD5ED, 0x6DE0}, //7834 #CJK UNIFIED IDEOGRAPH + {0xD5EE, 0x6DDF}, //7835 #CJK UNIFIED IDEOGRAPH + {0xD5EF, 0x6DD6}, //7836 #CJK UNIFIED IDEOGRAPH + {0xD5F0, 0x6DBE}, //7837 #CJK UNIFIED IDEOGRAPH + {0xD5F1, 0x6DE5}, //7838 #CJK UNIFIED IDEOGRAPH + {0xD5F2, 0x6DDC}, //7839 #CJK UNIFIED IDEOGRAPH + {0xD5F3, 0x6DDD}, //7840 #CJK UNIFIED IDEOGRAPH + {0xD5F4, 0x6DDB}, //7841 #CJK UNIFIED IDEOGRAPH + {0xD5F5, 0x6DF4}, //7842 #CJK UNIFIED IDEOGRAPH + {0xD5F6, 0x6DCA}, //7843 #CJK UNIFIED IDEOGRAPH + {0xD5F7, 0x6DBD}, //7844 #CJK UNIFIED IDEOGRAPH + {0xD5F8, 0x6DED}, //7845 #CJK UNIFIED IDEOGRAPH + {0xD5F9, 0x6DF0}, //7846 #CJK UNIFIED IDEOGRAPH + {0xD5FA, 0x6DBA}, //7847 #CJK UNIFIED IDEOGRAPH + {0xD5FB, 0x6DD5}, //7848 #CJK UNIFIED IDEOGRAPH + {0xD5FC, 0x6DC2}, //7849 #CJK UNIFIED IDEOGRAPH + {0xD5FD, 0x6DCF}, //7850 #CJK UNIFIED IDEOGRAPH + {0xD5FE, 0x6DC9}, //7851 #CJK UNIFIED IDEOGRAPH + {0xD640, 0x6DD0}, //7852 #CJK UNIFIED IDEOGRAPH + {0xD641, 0x6DF2}, //7853 #CJK UNIFIED IDEOGRAPH + {0xD642, 0x6DD3}, //7854 #CJK UNIFIED IDEOGRAPH + {0xD643, 0x6DFD}, //7855 #CJK UNIFIED IDEOGRAPH + {0xD644, 0x6DD7}, //7856 #CJK UNIFIED IDEOGRAPH + {0xD645, 0x6DCD}, //7857 #CJK UNIFIED IDEOGRAPH + {0xD646, 0x6DE3}, //7858 #CJK UNIFIED IDEOGRAPH + {0xD647, 0x6DBB}, //7859 #CJK UNIFIED IDEOGRAPH + {0xD648, 0x70FA}, //7860 #CJK UNIFIED IDEOGRAPH + {0xD649, 0x710D}, //7861 #CJK UNIFIED IDEOGRAPH + {0xD64A, 0x70F7}, //7862 #CJK UNIFIED IDEOGRAPH + {0xD64B, 0x7117}, //7863 #CJK UNIFIED IDEOGRAPH + {0xD64C, 0x70F4}, //7864 #CJK UNIFIED IDEOGRAPH + {0xD64D, 0x710C}, //7865 #CJK UNIFIED IDEOGRAPH + {0xD64E, 0x70F0}, //7866 #CJK UNIFIED IDEOGRAPH + {0xD64F, 0x7104}, //7867 #CJK UNIFIED IDEOGRAPH + {0xD650, 0x70F3}, //7868 #CJK UNIFIED IDEOGRAPH + {0xD651, 0x7110}, //7869 #CJK UNIFIED IDEOGRAPH + {0xD652, 0x70FC}, //7870 #CJK UNIFIED IDEOGRAPH + {0xD653, 0x70FF}, //7871 #CJK UNIFIED IDEOGRAPH + {0xD654, 0x7106}, //7872 #CJK UNIFIED IDEOGRAPH + {0xD655, 0x7113}, //7873 #CJK UNIFIED IDEOGRAPH + {0xD656, 0x7100}, //7874 #CJK UNIFIED IDEOGRAPH + {0xD657, 0x70F8}, //7875 #CJK UNIFIED IDEOGRAPH + {0xD658, 0x70F6}, //7876 #CJK UNIFIED IDEOGRAPH + {0xD659, 0x710B}, //7877 #CJK UNIFIED IDEOGRAPH + {0xD65A, 0x7102}, //7878 #CJK UNIFIED IDEOGRAPH + {0xD65B, 0x710E}, //7879 #CJK UNIFIED IDEOGRAPH + {0xD65C, 0x727E}, //7880 #CJK UNIFIED IDEOGRAPH + {0xD65D, 0x727B}, //7881 #CJK UNIFIED IDEOGRAPH + {0xD65E, 0x727C}, //7882 #CJK UNIFIED IDEOGRAPH + {0xD65F, 0x727F}, //7883 #CJK UNIFIED IDEOGRAPH + {0xD660, 0x731D}, //7884 #CJK UNIFIED IDEOGRAPH + {0xD661, 0x7317}, //7885 #CJK UNIFIED IDEOGRAPH + {0xD662, 0x7307}, //7886 #CJK UNIFIED IDEOGRAPH + {0xD663, 0x7311}, //7887 #CJK UNIFIED IDEOGRAPH + {0xD664, 0x7318}, //7888 #CJK UNIFIED IDEOGRAPH + {0xD665, 0x730A}, //7889 #CJK UNIFIED IDEOGRAPH + {0xD666, 0x7308}, //7890 #CJK UNIFIED IDEOGRAPH + {0xD667, 0x72FF}, //7891 #CJK UNIFIED IDEOGRAPH + {0xD668, 0x730F}, //7892 #CJK UNIFIED IDEOGRAPH + {0xD669, 0x731E}, //7893 #CJK UNIFIED IDEOGRAPH + {0xD66A, 0x7388}, //7894 #CJK UNIFIED IDEOGRAPH + {0xD66B, 0x73F6}, //7895 #CJK UNIFIED IDEOGRAPH + {0xD66C, 0x73F8}, //7896 #CJK UNIFIED IDEOGRAPH + {0xD66D, 0x73F5}, //7897 #CJK UNIFIED IDEOGRAPH + {0xD66E, 0x7404}, //7898 #CJK UNIFIED IDEOGRAPH + {0xD66F, 0x7401}, //7899 #CJK UNIFIED IDEOGRAPH + {0xD670, 0x73FD}, //7900 #CJK UNIFIED IDEOGRAPH + {0xD671, 0x7407}, //7901 #CJK UNIFIED IDEOGRAPH + {0xD672, 0x7400}, //7902 #CJK UNIFIED IDEOGRAPH + {0xD673, 0x73FA}, //7903 #CJK UNIFIED IDEOGRAPH + {0xD674, 0x73FC}, //7904 #CJK UNIFIED IDEOGRAPH + {0xD675, 0x73FF}, //7905 #CJK UNIFIED IDEOGRAPH + {0xD676, 0x740C}, //7906 #CJK UNIFIED IDEOGRAPH + {0xD677, 0x740B}, //7907 #CJK UNIFIED IDEOGRAPH + {0xD678, 0x73F4}, //7908 #CJK UNIFIED IDEOGRAPH + {0xD679, 0x7408}, //7909 #CJK UNIFIED IDEOGRAPH + {0xD67A, 0x7564}, //7910 #CJK UNIFIED IDEOGRAPH + {0xD67B, 0x7563}, //7911 #CJK UNIFIED IDEOGRAPH + {0xD67C, 0x75CE}, //7912 #CJK UNIFIED IDEOGRAPH + {0xD67D, 0x75D2}, //7913 #CJK UNIFIED IDEOGRAPH + {0xD67E, 0x75CF}, //7914 #CJK UNIFIED IDEOGRAPH + {0xD6A1, 0x75CB}, //7915 #CJK UNIFIED IDEOGRAPH + {0xD6A2, 0x75CC}, //7916 #CJK UNIFIED IDEOGRAPH + {0xD6A3, 0x75D1}, //7917 #CJK UNIFIED IDEOGRAPH + {0xD6A4, 0x75D0}, //7918 #CJK UNIFIED IDEOGRAPH + {0xD6A5, 0x768F}, //7919 #CJK UNIFIED IDEOGRAPH + {0xD6A6, 0x7689}, //7920 #CJK UNIFIED IDEOGRAPH + {0xD6A7, 0x76D3}, //7921 #CJK UNIFIED IDEOGRAPH + {0xD6A8, 0x7739}, //7922 #CJK UNIFIED IDEOGRAPH + {0xD6A9, 0x772F}, //7923 #CJK UNIFIED IDEOGRAPH + {0xD6AA, 0x772D}, //7924 #CJK UNIFIED IDEOGRAPH + {0xD6AB, 0x7731}, //7925 #CJK UNIFIED IDEOGRAPH + {0xD6AC, 0x7732}, //7926 #CJK UNIFIED IDEOGRAPH + {0xD6AD, 0x7734}, //7927 #CJK UNIFIED IDEOGRAPH + {0xD6AE, 0x7733}, //7928 #CJK UNIFIED IDEOGRAPH + {0xD6AF, 0x773D}, //7929 #CJK UNIFIED IDEOGRAPH + {0xD6B0, 0x7725}, //7930 #CJK UNIFIED IDEOGRAPH + {0xD6B1, 0x773B}, //7931 #CJK UNIFIED IDEOGRAPH + {0xD6B2, 0x7735}, //7932 #CJK UNIFIED IDEOGRAPH + {0xD6B3, 0x7848}, //7933 #CJK UNIFIED IDEOGRAPH + {0xD6B4, 0x7852}, //7934 #CJK UNIFIED IDEOGRAPH + {0xD6B5, 0x7849}, //7935 #CJK UNIFIED IDEOGRAPH + {0xD6B6, 0x784D}, //7936 #CJK UNIFIED IDEOGRAPH + {0xD6B7, 0x784A}, //7937 #CJK UNIFIED IDEOGRAPH + {0xD6B8, 0x784C}, //7938 #CJK UNIFIED IDEOGRAPH + {0xD6B9, 0x7826}, //7939 #CJK UNIFIED IDEOGRAPH + {0xD6BA, 0x7845}, //7940 #CJK UNIFIED IDEOGRAPH + {0xD6BB, 0x7850}, //7941 #CJK UNIFIED IDEOGRAPH + {0xD6BC, 0x7964}, //7942 #CJK UNIFIED IDEOGRAPH + {0xD6BD, 0x7967}, //7943 #CJK UNIFIED IDEOGRAPH + {0xD6BE, 0x7969}, //7944 #CJK UNIFIED IDEOGRAPH + {0xD6BF, 0x796A}, //7945 #CJK UNIFIED IDEOGRAPH + {0xD6C0, 0x7963}, //7946 #CJK UNIFIED IDEOGRAPH + {0xD6C1, 0x796B}, //7947 #CJK UNIFIED IDEOGRAPH + {0xD6C2, 0x7961}, //7948 #CJK UNIFIED IDEOGRAPH + {0xD6C3, 0x79BB}, //7949 #CJK UNIFIED IDEOGRAPH + {0xD6C4, 0x79FA}, //7950 #CJK UNIFIED IDEOGRAPH + {0xD6C5, 0x79F8}, //7951 #CJK UNIFIED IDEOGRAPH + {0xD6C6, 0x79F6}, //7952 #CJK UNIFIED IDEOGRAPH + {0xD6C7, 0x79F7}, //7953 #CJK UNIFIED IDEOGRAPH + {0xD6C8, 0x7A8F}, //7954 #CJK UNIFIED IDEOGRAPH + {0xD6C9, 0x7A94}, //7955 #CJK UNIFIED IDEOGRAPH + {0xD6CA, 0x7A90}, //7956 #CJK UNIFIED IDEOGRAPH + {0xD6CB, 0x7B35}, //7957 #CJK UNIFIED IDEOGRAPH + {0xD6CC, 0x7B47}, //7958 #CJK UNIFIED IDEOGRAPH + {0xD6CD, 0x7B34}, //7959 #CJK UNIFIED IDEOGRAPH + {0xD6CE, 0x7B25}, //7960 #CJK UNIFIED IDEOGRAPH + {0xD6CF, 0x7B30}, //7961 #CJK UNIFIED IDEOGRAPH + {0xD6D0, 0x7B22}, //7962 #CJK UNIFIED IDEOGRAPH + {0xD6D1, 0x7B24}, //7963 #CJK UNIFIED IDEOGRAPH + {0xD6D2, 0x7B33}, //7964 #CJK UNIFIED IDEOGRAPH + {0xD6D3, 0x7B18}, //7965 #CJK UNIFIED IDEOGRAPH + {0xD6D4, 0x7B2A}, //7966 #CJK UNIFIED IDEOGRAPH + {0xD6D5, 0x7B1D}, //7967 #CJK UNIFIED IDEOGRAPH + {0xD6D6, 0x7B31}, //7968 #CJK UNIFIED IDEOGRAPH + {0xD6D7, 0x7B2B}, //7969 #CJK UNIFIED IDEOGRAPH + {0xD6D8, 0x7B2D}, //7970 #CJK UNIFIED IDEOGRAPH + {0xD6D9, 0x7B2F}, //7971 #CJK UNIFIED IDEOGRAPH + {0xD6DA, 0x7B32}, //7972 #CJK UNIFIED IDEOGRAPH + {0xD6DB, 0x7B38}, //7973 #CJK UNIFIED IDEOGRAPH + {0xD6DC, 0x7B1A}, //7974 #CJK UNIFIED IDEOGRAPH + {0xD6DD, 0x7B23}, //7975 #CJK UNIFIED IDEOGRAPH + {0xD6DE, 0x7C94}, //7976 #CJK UNIFIED IDEOGRAPH + {0xD6DF, 0x7C98}, //7977 #CJK UNIFIED IDEOGRAPH + {0xD6E0, 0x7C96}, //7978 #CJK UNIFIED IDEOGRAPH + {0xD6E1, 0x7CA3}, //7979 #CJK UNIFIED IDEOGRAPH + {0xD6E2, 0x7D35}, //7980 #CJK UNIFIED IDEOGRAPH + {0xD6E3, 0x7D3D}, //7981 #CJK UNIFIED IDEOGRAPH + {0xD6E4, 0x7D38}, //7982 #CJK UNIFIED IDEOGRAPH + {0xD6E5, 0x7D36}, //7983 #CJK UNIFIED IDEOGRAPH + {0xD6E6, 0x7D3A}, //7984 #CJK UNIFIED IDEOGRAPH + {0xD6E7, 0x7D45}, //7985 #CJK UNIFIED IDEOGRAPH + {0xD6E8, 0x7D2C}, //7986 #CJK UNIFIED IDEOGRAPH + {0xD6E9, 0x7D29}, //7987 #CJK UNIFIED IDEOGRAPH + {0xD6EA, 0x7D41}, //7988 #CJK UNIFIED IDEOGRAPH + {0xD6EB, 0x7D47}, //7989 #CJK UNIFIED IDEOGRAPH + {0xD6EC, 0x7D3E}, //7990 #CJK UNIFIED IDEOGRAPH + {0xD6ED, 0x7D3F}, //7991 #CJK UNIFIED IDEOGRAPH + {0xD6EE, 0x7D4A}, //7992 #CJK UNIFIED IDEOGRAPH + {0xD6EF, 0x7D3B}, //7993 #CJK UNIFIED IDEOGRAPH + {0xD6F0, 0x7D28}, //7994 #CJK UNIFIED IDEOGRAPH + {0xD6F1, 0x7F63}, //7995 #CJK UNIFIED IDEOGRAPH + {0xD6F2, 0x7F95}, //7996 #CJK UNIFIED IDEOGRAPH + {0xD6F3, 0x7F9C}, //7997 #CJK UNIFIED IDEOGRAPH + {0xD6F4, 0x7F9D}, //7998 #CJK UNIFIED IDEOGRAPH + {0xD6F5, 0x7F9B}, //7999 #CJK UNIFIED IDEOGRAPH + {0xD6F6, 0x7FCA}, //8000 #CJK UNIFIED IDEOGRAPH + {0xD6F7, 0x7FCB}, //8001 #CJK UNIFIED IDEOGRAPH + {0xD6F8, 0x7FCD}, //8002 #CJK UNIFIED IDEOGRAPH + {0xD6F9, 0x7FD0}, //8003 #CJK UNIFIED IDEOGRAPH + {0xD6FA, 0x7FD1}, //8004 #CJK UNIFIED IDEOGRAPH + {0xD6FB, 0x7FC7}, //8005 #CJK UNIFIED IDEOGRAPH + {0xD6FC, 0x7FCF}, //8006 #CJK UNIFIED IDEOGRAPH + {0xD6FD, 0x7FC9}, //8007 #CJK UNIFIED IDEOGRAPH + {0xD6FE, 0x801F}, //8008 #CJK UNIFIED IDEOGRAPH + {0xD740, 0x801E}, //8009 #CJK UNIFIED IDEOGRAPH + {0xD741, 0x801B}, //8010 #CJK UNIFIED IDEOGRAPH + {0xD742, 0x8047}, //8011 #CJK UNIFIED IDEOGRAPH + {0xD743, 0x8043}, //8012 #CJK UNIFIED IDEOGRAPH + {0xD744, 0x8048}, //8013 #CJK UNIFIED IDEOGRAPH + {0xD745, 0x8118}, //8014 #CJK UNIFIED IDEOGRAPH + {0xD746, 0x8125}, //8015 #CJK UNIFIED IDEOGRAPH + {0xD747, 0x8119}, //8016 #CJK UNIFIED IDEOGRAPH + {0xD748, 0x811B}, //8017 #CJK UNIFIED IDEOGRAPH + {0xD749, 0x812D}, //8018 #CJK UNIFIED IDEOGRAPH + {0xD74A, 0x811F}, //8019 #CJK UNIFIED IDEOGRAPH + {0xD74B, 0x812C}, //8020 #CJK UNIFIED IDEOGRAPH + {0xD74C, 0x811E}, //8021 #CJK UNIFIED IDEOGRAPH + {0xD74D, 0x8121}, //8022 #CJK UNIFIED IDEOGRAPH + {0xD74E, 0x8115}, //8023 #CJK UNIFIED IDEOGRAPH + {0xD74F, 0x8127}, //8024 #CJK UNIFIED IDEOGRAPH + {0xD750, 0x811D}, //8025 #CJK UNIFIED IDEOGRAPH + {0xD751, 0x8122}, //8026 #CJK UNIFIED IDEOGRAPH + {0xD752, 0x8211}, //8027 #CJK UNIFIED IDEOGRAPH + {0xD753, 0x8238}, //8028 #CJK UNIFIED IDEOGRAPH + {0xD754, 0x8233}, //8029 #CJK UNIFIED IDEOGRAPH + {0xD755, 0x823A}, //8030 #CJK UNIFIED IDEOGRAPH + {0xD756, 0x8234}, //8031 #CJK UNIFIED IDEOGRAPH + {0xD757, 0x8232}, //8032 #CJK UNIFIED IDEOGRAPH + {0xD758, 0x8274}, //8033 #CJK UNIFIED IDEOGRAPH + {0xD759, 0x8390}, //8034 #CJK UNIFIED IDEOGRAPH + {0xD75A, 0x83A3}, //8035 #CJK UNIFIED IDEOGRAPH + {0xD75B, 0x83A8}, //8036 #CJK UNIFIED IDEOGRAPH + {0xD75C, 0x838D}, //8037 #CJK UNIFIED IDEOGRAPH + {0xD75D, 0x837A}, //8038 #CJK UNIFIED IDEOGRAPH + {0xD75E, 0x8373}, //8039 #CJK UNIFIED IDEOGRAPH + {0xD75F, 0x83A4}, //8040 #CJK UNIFIED IDEOGRAPH + {0xD760, 0x8374}, //8041 #CJK UNIFIED IDEOGRAPH + {0xD761, 0x838F}, //8042 #CJK UNIFIED IDEOGRAPH + {0xD762, 0x8381}, //8043 #CJK UNIFIED IDEOGRAPH + {0xD763, 0x8395}, //8044 #CJK UNIFIED IDEOGRAPH + {0xD764, 0x8399}, //8045 #CJK UNIFIED IDEOGRAPH + {0xD765, 0x8375}, //8046 #CJK UNIFIED IDEOGRAPH + {0xD766, 0x8394}, //8047 #CJK UNIFIED IDEOGRAPH + {0xD767, 0x83A9}, //8048 #CJK UNIFIED IDEOGRAPH + {0xD768, 0x837D}, //8049 #CJK UNIFIED IDEOGRAPH + {0xD769, 0x8383}, //8050 #CJK UNIFIED IDEOGRAPH + {0xD76A, 0x838C}, //8051 #CJK UNIFIED IDEOGRAPH + {0xD76B, 0x839D}, //8052 #CJK UNIFIED IDEOGRAPH + {0xD76C, 0x839B}, //8053 #CJK UNIFIED IDEOGRAPH + {0xD76D, 0x83AA}, //8054 #CJK UNIFIED IDEOGRAPH + {0xD76E, 0x838B}, //8055 #CJK UNIFIED IDEOGRAPH + {0xD76F, 0x837E}, //8056 #CJK UNIFIED IDEOGRAPH + {0xD770, 0x83A5}, //8057 #CJK UNIFIED IDEOGRAPH + {0xD771, 0x83AF}, //8058 #CJK UNIFIED IDEOGRAPH + {0xD772, 0x8388}, //8059 #CJK UNIFIED IDEOGRAPH + {0xD773, 0x8397}, //8060 #CJK UNIFIED IDEOGRAPH + {0xD774, 0x83B0}, //8061 #CJK UNIFIED IDEOGRAPH + {0xD775, 0x837F}, //8062 #CJK UNIFIED IDEOGRAPH + {0xD776, 0x83A6}, //8063 #CJK UNIFIED IDEOGRAPH + {0xD777, 0x8387}, //8064 #CJK UNIFIED IDEOGRAPH + {0xD778, 0x83AE}, //8065 #CJK UNIFIED IDEOGRAPH + {0xD779, 0x8376}, //8066 #CJK UNIFIED IDEOGRAPH + {0xD77A, 0x839A}, //8067 #CJK UNIFIED IDEOGRAPH + {0xD77B, 0x8659}, //8068 #CJK UNIFIED IDEOGRAPH + {0xD77C, 0x8656}, //8069 #CJK UNIFIED IDEOGRAPH + {0xD77D, 0x86BF}, //8070 #CJK UNIFIED IDEOGRAPH + {0xD77E, 0x86B7}, //8071 #CJK UNIFIED IDEOGRAPH + {0xD7A1, 0x86C2}, //8072 #CJK UNIFIED IDEOGRAPH + {0xD7A2, 0x86C1}, //8073 #CJK UNIFIED IDEOGRAPH + {0xD7A3, 0x86C5}, //8074 #CJK UNIFIED IDEOGRAPH + {0xD7A4, 0x86BA}, //8075 #CJK UNIFIED IDEOGRAPH + {0xD7A5, 0x86B0}, //8076 #CJK UNIFIED IDEOGRAPH + {0xD7A6, 0x86C8}, //8077 #CJK UNIFIED IDEOGRAPH + {0xD7A7, 0x86B9}, //8078 #CJK UNIFIED IDEOGRAPH + {0xD7A8, 0x86B3}, //8079 #CJK UNIFIED IDEOGRAPH + {0xD7A9, 0x86B8}, //8080 #CJK UNIFIED IDEOGRAPH + {0xD7AA, 0x86CC}, //8081 #CJK UNIFIED IDEOGRAPH + {0xD7AB, 0x86B4}, //8082 #CJK UNIFIED IDEOGRAPH + {0xD7AC, 0x86BB}, //8083 #CJK UNIFIED IDEOGRAPH + {0xD7AD, 0x86BC}, //8084 #CJK UNIFIED IDEOGRAPH + {0xD7AE, 0x86C3}, //8085 #CJK UNIFIED IDEOGRAPH + {0xD7AF, 0x86BD}, //8086 #CJK UNIFIED IDEOGRAPH + {0xD7B0, 0x86BE}, //8087 #CJK UNIFIED IDEOGRAPH + {0xD7B1, 0x8852}, //8088 #CJK UNIFIED IDEOGRAPH + {0xD7B2, 0x8889}, //8089 #CJK UNIFIED IDEOGRAPH + {0xD7B3, 0x8895}, //8090 #CJK UNIFIED IDEOGRAPH + {0xD7B4, 0x88A8}, //8091 #CJK UNIFIED IDEOGRAPH + {0xD7B5, 0x88A2}, //8092 #CJK UNIFIED IDEOGRAPH + {0xD7B6, 0x88AA}, //8093 #CJK UNIFIED IDEOGRAPH + {0xD7B7, 0x889A}, //8094 #CJK UNIFIED IDEOGRAPH + {0xD7B8, 0x8891}, //8095 #CJK UNIFIED IDEOGRAPH + {0xD7B9, 0x88A1}, //8096 #CJK UNIFIED IDEOGRAPH + {0xD7BA, 0x889F}, //8097 #CJK UNIFIED IDEOGRAPH + {0xD7BB, 0x8898}, //8098 #CJK UNIFIED IDEOGRAPH + {0xD7BC, 0x88A7}, //8099 #CJK UNIFIED IDEOGRAPH + {0xD7BD, 0x8899}, //8100 #CJK UNIFIED IDEOGRAPH + {0xD7BE, 0x889B}, //8101 #CJK UNIFIED IDEOGRAPH + {0xD7BF, 0x8897}, //8102 #CJK UNIFIED IDEOGRAPH + {0xD7C0, 0x88A4}, //8103 #CJK UNIFIED IDEOGRAPH + {0xD7C1, 0x88AC}, //8104 #CJK UNIFIED IDEOGRAPH + {0xD7C2, 0x888C}, //8105 #CJK UNIFIED IDEOGRAPH + {0xD7C3, 0x8893}, //8106 #CJK UNIFIED IDEOGRAPH + {0xD7C4, 0x888E}, //8107 #CJK UNIFIED IDEOGRAPH + {0xD7C5, 0x8982}, //8108 #CJK UNIFIED IDEOGRAPH + {0xD7C6, 0x89D6}, //8109 #CJK UNIFIED IDEOGRAPH + {0xD7C7, 0x89D9}, //8110 #CJK UNIFIED IDEOGRAPH + {0xD7C8, 0x89D5}, //8111 #CJK UNIFIED IDEOGRAPH + {0xD7C9, 0x8A30}, //8112 #CJK UNIFIED IDEOGRAPH + {0xD7CA, 0x8A27}, //8113 #CJK UNIFIED IDEOGRAPH + {0xD7CB, 0x8A2C}, //8114 #CJK UNIFIED IDEOGRAPH + {0xD7CC, 0x8A1E}, //8115 #CJK UNIFIED IDEOGRAPH + {0xD7CD, 0x8C39}, //8116 #CJK UNIFIED IDEOGRAPH + {0xD7CE, 0x8C3B}, //8117 #CJK UNIFIED IDEOGRAPH + {0xD7CF, 0x8C5C}, //8118 #CJK UNIFIED IDEOGRAPH + {0xD7D0, 0x8C5D}, //8119 #CJK UNIFIED IDEOGRAPH + {0xD7D1, 0x8C7D}, //8120 #CJK UNIFIED IDEOGRAPH + {0xD7D2, 0x8CA5}, //8121 #CJK UNIFIED IDEOGRAPH + {0xD7D3, 0x8D7D}, //8122 #CJK UNIFIED IDEOGRAPH + {0xD7D4, 0x8D7B}, //8123 #CJK UNIFIED IDEOGRAPH + {0xD7D5, 0x8D79}, //8124 #CJK UNIFIED IDEOGRAPH + {0xD7D6, 0x8DBC}, //8125 #CJK UNIFIED IDEOGRAPH + {0xD7D7, 0x8DC2}, //8126 #CJK UNIFIED IDEOGRAPH + {0xD7D8, 0x8DB9}, //8127 #CJK UNIFIED IDEOGRAPH + {0xD7D9, 0x8DBF}, //8128 #CJK UNIFIED IDEOGRAPH + {0xD7DA, 0x8DC1}, //8129 #CJK UNIFIED IDEOGRAPH + {0xD7DB, 0x8ED8}, //8130 #CJK UNIFIED IDEOGRAPH + {0xD7DC, 0x8EDE}, //8131 #CJK UNIFIED IDEOGRAPH + {0xD7DD, 0x8EDD}, //8132 #CJK UNIFIED IDEOGRAPH + {0xD7DE, 0x8EDC}, //8133 #CJK UNIFIED IDEOGRAPH + {0xD7DF, 0x8ED7}, //8134 #CJK UNIFIED IDEOGRAPH + {0xD7E0, 0x8EE0}, //8135 #CJK UNIFIED IDEOGRAPH + {0xD7E1, 0x8EE1}, //8136 #CJK UNIFIED IDEOGRAPH + {0xD7E2, 0x9024}, //8137 #CJK UNIFIED IDEOGRAPH + {0xD7E3, 0x900B}, //8138 #CJK UNIFIED IDEOGRAPH + {0xD7E4, 0x9011}, //8139 #CJK UNIFIED IDEOGRAPH + {0xD7E5, 0x901C}, //8140 #CJK UNIFIED IDEOGRAPH + {0xD7E6, 0x900C}, //8141 #CJK UNIFIED IDEOGRAPH + {0xD7E7, 0x9021}, //8142 #CJK UNIFIED IDEOGRAPH + {0xD7E8, 0x90EF}, //8143 #CJK UNIFIED IDEOGRAPH + {0xD7E9, 0x90EA}, //8144 #CJK UNIFIED IDEOGRAPH + {0xD7EA, 0x90F0}, //8145 #CJK UNIFIED IDEOGRAPH + {0xD7EB, 0x90F4}, //8146 #CJK UNIFIED IDEOGRAPH + {0xD7EC, 0x90F2}, //8147 #CJK UNIFIED IDEOGRAPH + {0xD7ED, 0x90F3}, //8148 #CJK UNIFIED IDEOGRAPH + {0xD7EE, 0x90D4}, //8149 #CJK UNIFIED IDEOGRAPH + {0xD7EF, 0x90EB}, //8150 #CJK UNIFIED IDEOGRAPH + {0xD7F0, 0x90EC}, //8151 #CJK UNIFIED IDEOGRAPH + {0xD7F1, 0x90E9}, //8152 #CJK UNIFIED IDEOGRAPH + {0xD7F2, 0x9156}, //8153 #CJK UNIFIED IDEOGRAPH + {0xD7F3, 0x9158}, //8154 #CJK UNIFIED IDEOGRAPH + {0xD7F4, 0x915A}, //8155 #CJK UNIFIED IDEOGRAPH + {0xD7F5, 0x9153}, //8156 #CJK UNIFIED IDEOGRAPH + {0xD7F6, 0x9155}, //8157 #CJK UNIFIED IDEOGRAPH + {0xD7F7, 0x91EC}, //8158 #CJK UNIFIED IDEOGRAPH + {0xD7F8, 0x91F4}, //8159 #CJK UNIFIED IDEOGRAPH + {0xD7F9, 0x91F1}, //8160 #CJK UNIFIED IDEOGRAPH + {0xD7FA, 0x91F3}, //8161 #CJK UNIFIED IDEOGRAPH + {0xD7FB, 0x91F8}, //8162 #CJK UNIFIED IDEOGRAPH + {0xD7FC, 0x91E4}, //8163 #CJK UNIFIED IDEOGRAPH + {0xD7FD, 0x91F9}, //8164 #CJK UNIFIED IDEOGRAPH + {0xD7FE, 0x91EA}, //8165 #CJK UNIFIED IDEOGRAPH + {0xD840, 0x91EB}, //8166 #CJK UNIFIED IDEOGRAPH + {0xD841, 0x91F7}, //8167 #CJK UNIFIED IDEOGRAPH + {0xD842, 0x91E8}, //8168 #CJK UNIFIED IDEOGRAPH + {0xD843, 0x91EE}, //8169 #CJK UNIFIED IDEOGRAPH + {0xD844, 0x957A}, //8170 #CJK UNIFIED IDEOGRAPH + {0xD845, 0x9586}, //8171 #CJK UNIFIED IDEOGRAPH + {0xD846, 0x9588}, //8172 #CJK UNIFIED IDEOGRAPH + {0xD847, 0x967C}, //8173 #CJK UNIFIED IDEOGRAPH + {0xD848, 0x966D}, //8174 #CJK UNIFIED IDEOGRAPH + {0xD849, 0x966B}, //8175 #CJK UNIFIED IDEOGRAPH + {0xD84A, 0x9671}, //8176 #CJK UNIFIED IDEOGRAPH + {0xD84B, 0x966F}, //8177 #CJK UNIFIED IDEOGRAPH + {0xD84C, 0x96BF}, //8178 #CJK UNIFIED IDEOGRAPH + {0xD84D, 0x976A}, //8179 #CJK UNIFIED IDEOGRAPH + {0xD84E, 0x9804}, //8180 #CJK UNIFIED IDEOGRAPH + {0xD84F, 0x98E5}, //8181 #CJK UNIFIED IDEOGRAPH + {0xD850, 0x9997}, //8182 #CJK UNIFIED IDEOGRAPH + {0xD851, 0x509B}, //8183 #CJK UNIFIED IDEOGRAPH + {0xD852, 0x5095}, //8184 #CJK UNIFIED IDEOGRAPH + {0xD853, 0x5094}, //8185 #CJK UNIFIED IDEOGRAPH + {0xD854, 0x509E}, //8186 #CJK UNIFIED IDEOGRAPH + {0xD855, 0x508B}, //8187 #CJK UNIFIED IDEOGRAPH + {0xD856, 0x50A3}, //8188 #CJK UNIFIED IDEOGRAPH + {0xD857, 0x5083}, //8189 #CJK UNIFIED IDEOGRAPH + {0xD858, 0x508C}, //8190 #CJK UNIFIED IDEOGRAPH + {0xD859, 0x508E}, //8191 #CJK UNIFIED IDEOGRAPH + {0xD85A, 0x509D}, //8192 #CJK UNIFIED IDEOGRAPH + {0xD85B, 0x5068}, //8193 #CJK UNIFIED IDEOGRAPH + {0xD85C, 0x509C}, //8194 #CJK UNIFIED IDEOGRAPH + {0xD85D, 0x5092}, //8195 #CJK UNIFIED IDEOGRAPH + {0xD85E, 0x5082}, //8196 #CJK UNIFIED IDEOGRAPH + {0xD85F, 0x5087}, //8197 #CJK UNIFIED IDEOGRAPH + {0xD860, 0x515F}, //8198 #CJK UNIFIED IDEOGRAPH + {0xD861, 0x51D4}, //8199 #CJK UNIFIED IDEOGRAPH + {0xD862, 0x5312}, //8200 #CJK UNIFIED IDEOGRAPH + {0xD863, 0x5311}, //8201 #CJK UNIFIED IDEOGRAPH + {0xD864, 0x53A4}, //8202 #CJK UNIFIED IDEOGRAPH + {0xD865, 0x53A7}, //8203 #CJK UNIFIED IDEOGRAPH + {0xD866, 0x5591}, //8204 #CJK UNIFIED IDEOGRAPH + {0xD867, 0x55A8}, //8205 #CJK UNIFIED IDEOGRAPH + {0xD868, 0x55A5}, //8206 #CJK UNIFIED IDEOGRAPH + {0xD869, 0x55AD}, //8207 #CJK UNIFIED IDEOGRAPH + {0xD86A, 0x5577}, //8208 #CJK UNIFIED IDEOGRAPH + {0xD86B, 0x5645}, //8209 #CJK UNIFIED IDEOGRAPH + {0xD86C, 0x55A2}, //8210 #CJK UNIFIED IDEOGRAPH + {0xD86D, 0x5593}, //8211 #CJK UNIFIED IDEOGRAPH + {0xD86E, 0x5588}, //8212 #CJK UNIFIED IDEOGRAPH + {0xD86F, 0x558F}, //8213 #CJK UNIFIED IDEOGRAPH + {0xD870, 0x55B5}, //8214 #CJK UNIFIED IDEOGRAPH + {0xD871, 0x5581}, //8215 #CJK UNIFIED IDEOGRAPH + {0xD872, 0x55A3}, //8216 #CJK UNIFIED IDEOGRAPH + {0xD873, 0x5592}, //8217 #CJK UNIFIED IDEOGRAPH + {0xD874, 0x55A4}, //8218 #CJK UNIFIED IDEOGRAPH + {0xD875, 0x557D}, //8219 #CJK UNIFIED IDEOGRAPH + {0xD876, 0x558C}, //8220 #CJK UNIFIED IDEOGRAPH + {0xD877, 0x55A6}, //8221 #CJK UNIFIED IDEOGRAPH + {0xD878, 0x557F}, //8222 #CJK UNIFIED IDEOGRAPH + {0xD879, 0x5595}, //8223 #CJK UNIFIED IDEOGRAPH + {0xD87A, 0x55A1}, //8224 #CJK UNIFIED IDEOGRAPH + {0xD87B, 0x558E}, //8225 #CJK UNIFIED IDEOGRAPH + {0xD87C, 0x570C}, //8226 #CJK UNIFIED IDEOGRAPH + {0xD87D, 0x5829}, //8227 #CJK UNIFIED IDEOGRAPH + {0xD87E, 0x5837}, //8228 #CJK UNIFIED IDEOGRAPH + {0xD8A1, 0x5819}, //8229 #CJK UNIFIED IDEOGRAPH + {0xD8A2, 0x581E}, //8230 #CJK UNIFIED IDEOGRAPH + {0xD8A3, 0x5827}, //8231 #CJK UNIFIED IDEOGRAPH + {0xD8A4, 0x5823}, //8232 #CJK UNIFIED IDEOGRAPH + {0xD8A5, 0x5828}, //8233 #CJK UNIFIED IDEOGRAPH + {0xD8A6, 0x57F5}, //8234 #CJK UNIFIED IDEOGRAPH + {0xD8A7, 0x5848}, //8235 #CJK UNIFIED IDEOGRAPH + {0xD8A8, 0x5825}, //8236 #CJK UNIFIED IDEOGRAPH + {0xD8A9, 0x581C}, //8237 #CJK UNIFIED IDEOGRAPH + {0xD8AA, 0x581B}, //8238 #CJK UNIFIED IDEOGRAPH + {0xD8AB, 0x5833}, //8239 #CJK UNIFIED IDEOGRAPH + {0xD8AC, 0x583F}, //8240 #CJK UNIFIED IDEOGRAPH + {0xD8AD, 0x5836}, //8241 #CJK UNIFIED IDEOGRAPH + {0xD8AE, 0x582E}, //8242 #CJK UNIFIED IDEOGRAPH + {0xD8AF, 0x5839}, //8243 #CJK UNIFIED IDEOGRAPH + {0xD8B0, 0x5838}, //8244 #CJK UNIFIED IDEOGRAPH + {0xD8B1, 0x582D}, //8245 #CJK UNIFIED IDEOGRAPH + {0xD8B2, 0x582C}, //8246 #CJK UNIFIED IDEOGRAPH + {0xD8B3, 0x583B}, //8247 #CJK UNIFIED IDEOGRAPH + {0xD8B4, 0x5961}, //8248 #CJK UNIFIED IDEOGRAPH + {0xD8B5, 0x5AAF}, //8249 #CJK UNIFIED IDEOGRAPH + {0xD8B6, 0x5A94}, //8250 #CJK UNIFIED IDEOGRAPH + {0xD8B7, 0x5A9F}, //8251 #CJK UNIFIED IDEOGRAPH + {0xD8B8, 0x5A7A}, //8252 #CJK UNIFIED IDEOGRAPH + {0xD8B9, 0x5AA2}, //8253 #CJK UNIFIED IDEOGRAPH + {0xD8BA, 0x5A9E}, //8254 #CJK UNIFIED IDEOGRAPH + {0xD8BB, 0x5A78}, //8255 #CJK UNIFIED IDEOGRAPH + {0xD8BC, 0x5AA6}, //8256 #CJK UNIFIED IDEOGRAPH + {0xD8BD, 0x5A7C}, //8257 #CJK UNIFIED IDEOGRAPH + {0xD8BE, 0x5AA5}, //8258 #CJK UNIFIED IDEOGRAPH + {0xD8BF, 0x5AAC}, //8259 #CJK UNIFIED IDEOGRAPH + {0xD8C0, 0x5A95}, //8260 #CJK UNIFIED IDEOGRAPH + {0xD8C1, 0x5AAE}, //8261 #CJK UNIFIED IDEOGRAPH + {0xD8C2, 0x5A37}, //8262 #CJK UNIFIED IDEOGRAPH + {0xD8C3, 0x5A84}, //8263 #CJK UNIFIED IDEOGRAPH + {0xD8C4, 0x5A8A}, //8264 #CJK UNIFIED IDEOGRAPH + {0xD8C5, 0x5A97}, //8265 #CJK UNIFIED IDEOGRAPH + {0xD8C6, 0x5A83}, //8266 #CJK UNIFIED IDEOGRAPH + {0xD8C7, 0x5A8B}, //8267 #CJK UNIFIED IDEOGRAPH + {0xD8C8, 0x5AA9}, //8268 #CJK UNIFIED IDEOGRAPH + {0xD8C9, 0x5A7B}, //8269 #CJK UNIFIED IDEOGRAPH + {0xD8CA, 0x5A7D}, //8270 #CJK UNIFIED IDEOGRAPH + {0xD8CB, 0x5A8C}, //8271 #CJK UNIFIED IDEOGRAPH + {0xD8CC, 0x5A9C}, //8272 #CJK UNIFIED IDEOGRAPH + {0xD8CD, 0x5A8F}, //8273 #CJK UNIFIED IDEOGRAPH + {0xD8CE, 0x5A93}, //8274 #CJK UNIFIED IDEOGRAPH + {0xD8CF, 0x5A9D}, //8275 #CJK UNIFIED IDEOGRAPH + {0xD8D0, 0x5BEA}, //8276 #CJK UNIFIED IDEOGRAPH + {0xD8D1, 0x5BCD}, //8277 #CJK UNIFIED IDEOGRAPH + {0xD8D2, 0x5BCB}, //8278 #CJK UNIFIED IDEOGRAPH + {0xD8D3, 0x5BD4}, //8279 #CJK UNIFIED IDEOGRAPH + {0xD8D4, 0x5BD1}, //8280 #CJK UNIFIED IDEOGRAPH + {0xD8D5, 0x5BCA}, //8281 #CJK UNIFIED IDEOGRAPH + {0xD8D6, 0x5BCE}, //8282 #CJK UNIFIED IDEOGRAPH + {0xD8D7, 0x5C0C}, //8283 #CJK UNIFIED IDEOGRAPH + {0xD8D8, 0x5C30}, //8284 #CJK UNIFIED IDEOGRAPH + {0xD8D9, 0x5D37}, //8285 #CJK UNIFIED IDEOGRAPH + {0xD8DA, 0x5D43}, //8286 #CJK UNIFIED IDEOGRAPH + {0xD8DB, 0x5D6B}, //8287 #CJK UNIFIED IDEOGRAPH + {0xD8DC, 0x5D41}, //8288 #CJK UNIFIED IDEOGRAPH + {0xD8DD, 0x5D4B}, //8289 #CJK UNIFIED IDEOGRAPH + {0xD8DE, 0x5D3F}, //8290 #CJK UNIFIED IDEOGRAPH + {0xD8DF, 0x5D35}, //8291 #CJK UNIFIED IDEOGRAPH + {0xD8E0, 0x5D51}, //8292 #CJK UNIFIED IDEOGRAPH + {0xD8E1, 0x5D4E}, //8293 #CJK UNIFIED IDEOGRAPH + {0xD8E2, 0x5D55}, //8294 #CJK UNIFIED IDEOGRAPH + {0xD8E3, 0x5D33}, //8295 #CJK UNIFIED IDEOGRAPH + {0xD8E4, 0x5D3A}, //8296 #CJK UNIFIED IDEOGRAPH + {0xD8E5, 0x5D52}, //8297 #CJK UNIFIED IDEOGRAPH + {0xD8E6, 0x5D3D}, //8298 #CJK UNIFIED IDEOGRAPH + {0xD8E7, 0x5D31}, //8299 #CJK UNIFIED IDEOGRAPH + {0xD8E8, 0x5D59}, //8300 #CJK UNIFIED IDEOGRAPH + {0xD8E9, 0x5D42}, //8301 #CJK UNIFIED IDEOGRAPH + {0xD8EA, 0x5D39}, //8302 #CJK UNIFIED IDEOGRAPH + {0xD8EB, 0x5D49}, //8303 #CJK UNIFIED IDEOGRAPH + {0xD8EC, 0x5D38}, //8304 #CJK UNIFIED IDEOGRAPH + {0xD8ED, 0x5D3C}, //8305 #CJK UNIFIED IDEOGRAPH + {0xD8EE, 0x5D32}, //8306 #CJK UNIFIED IDEOGRAPH + {0xD8EF, 0x5D36}, //8307 #CJK UNIFIED IDEOGRAPH + {0xD8F0, 0x5D40}, //8308 #CJK UNIFIED IDEOGRAPH + {0xD8F1, 0x5D45}, //8309 #CJK UNIFIED IDEOGRAPH + {0xD8F2, 0x5E44}, //8310 #CJK UNIFIED IDEOGRAPH + {0xD8F3, 0x5E41}, //8311 #CJK UNIFIED IDEOGRAPH + {0xD8F4, 0x5F58}, //8312 #CJK UNIFIED IDEOGRAPH + {0xD8F5, 0x5FA6}, //8313 #CJK UNIFIED IDEOGRAPH + {0xD8F6, 0x5FA5}, //8314 #CJK UNIFIED IDEOGRAPH + {0xD8F7, 0x5FAB}, //8315 #CJK UNIFIED IDEOGRAPH + {0xD8F8, 0x60C9}, //8316 #CJK UNIFIED IDEOGRAPH + {0xD8F9, 0x60B9}, //8317 #CJK UNIFIED IDEOGRAPH + {0xD8FA, 0x60CC}, //8318 #CJK UNIFIED IDEOGRAPH + {0xD8FB, 0x60E2}, //8319 #CJK UNIFIED IDEOGRAPH + {0xD8FC, 0x60CE}, //8320 #CJK UNIFIED IDEOGRAPH + {0xD8FD, 0x60C4}, //8321 #CJK UNIFIED IDEOGRAPH + {0xD8FE, 0x6114}, //8322 #CJK UNIFIED IDEOGRAPH + {0xD940, 0x60F2}, //8323 #CJK UNIFIED IDEOGRAPH + {0xD941, 0x610A}, //8324 #CJK UNIFIED IDEOGRAPH + {0xD942, 0x6116}, //8325 #CJK UNIFIED IDEOGRAPH + {0xD943, 0x6105}, //8326 #CJK UNIFIED IDEOGRAPH + {0xD944, 0x60F5}, //8327 #CJK UNIFIED IDEOGRAPH + {0xD945, 0x6113}, //8328 #CJK UNIFIED IDEOGRAPH + {0xD946, 0x60F8}, //8329 #CJK UNIFIED IDEOGRAPH + {0xD947, 0x60FC}, //8330 #CJK UNIFIED IDEOGRAPH + {0xD948, 0x60FE}, //8331 #CJK UNIFIED IDEOGRAPH + {0xD949, 0x60C1}, //8332 #CJK UNIFIED IDEOGRAPH + {0xD94A, 0x6103}, //8333 #CJK UNIFIED IDEOGRAPH + {0xD94B, 0x6118}, //8334 #CJK UNIFIED IDEOGRAPH + {0xD94C, 0x611D}, //8335 #CJK UNIFIED IDEOGRAPH + {0xD94D, 0x6110}, //8336 #CJK UNIFIED IDEOGRAPH + {0xD94E, 0x60FF}, //8337 #CJK UNIFIED IDEOGRAPH + {0xD94F, 0x6104}, //8338 #CJK UNIFIED IDEOGRAPH + {0xD950, 0x610B}, //8339 #CJK UNIFIED IDEOGRAPH + {0xD951, 0x624A}, //8340 #CJK UNIFIED IDEOGRAPH + {0xD952, 0x6394}, //8341 #CJK UNIFIED IDEOGRAPH + {0xD953, 0x63B1}, //8342 #CJK UNIFIED IDEOGRAPH + {0xD954, 0x63B0}, //8343 #CJK UNIFIED IDEOGRAPH + {0xD955, 0x63CE}, //8344 #CJK UNIFIED IDEOGRAPH + {0xD956, 0x63E5}, //8345 #CJK UNIFIED IDEOGRAPH + {0xD957, 0x63E8}, //8346 #CJK UNIFIED IDEOGRAPH + {0xD958, 0x63EF}, //8347 #CJK UNIFIED IDEOGRAPH + {0xD959, 0x63C3}, //8348 #CJK UNIFIED IDEOGRAPH + {0xD95A, 0x649D}, //8349 #CJK UNIFIED IDEOGRAPH + {0xD95B, 0x63F3}, //8350 #CJK UNIFIED IDEOGRAPH + {0xD95C, 0x63CA}, //8351 #CJK UNIFIED IDEOGRAPH + {0xD95D, 0x63E0}, //8352 #CJK UNIFIED IDEOGRAPH + {0xD95E, 0x63F6}, //8353 #CJK UNIFIED IDEOGRAPH + {0xD95F, 0x63D5}, //8354 #CJK UNIFIED IDEOGRAPH + {0xD960, 0x63F2}, //8355 #CJK UNIFIED IDEOGRAPH + {0xD961, 0x63F5}, //8356 #CJK UNIFIED IDEOGRAPH + {0xD962, 0x6461}, //8357 #CJK UNIFIED IDEOGRAPH + {0xD963, 0x63DF}, //8358 #CJK UNIFIED IDEOGRAPH + {0xD964, 0x63BE}, //8359 #CJK UNIFIED IDEOGRAPH + {0xD965, 0x63DD}, //8360 #CJK UNIFIED IDEOGRAPH + {0xD966, 0x63DC}, //8361 #CJK UNIFIED IDEOGRAPH + {0xD967, 0x63C4}, //8362 #CJK UNIFIED IDEOGRAPH + {0xD968, 0x63D8}, //8363 #CJK UNIFIED IDEOGRAPH + {0xD969, 0x63D3}, //8364 #CJK UNIFIED IDEOGRAPH + {0xD96A, 0x63C2}, //8365 #CJK UNIFIED IDEOGRAPH + {0xD96B, 0x63C7}, //8366 #CJK UNIFIED IDEOGRAPH + {0xD96C, 0x63CC}, //8367 #CJK UNIFIED IDEOGRAPH + {0xD96D, 0x63CB}, //8368 #CJK UNIFIED IDEOGRAPH + {0xD96E, 0x63C8}, //8369 #CJK UNIFIED IDEOGRAPH + {0xD96F, 0x63F0}, //8370 #CJK UNIFIED IDEOGRAPH + {0xD970, 0x63D7}, //8371 #CJK UNIFIED IDEOGRAPH + {0xD971, 0x63D9}, //8372 #CJK UNIFIED IDEOGRAPH + {0xD972, 0x6532}, //8373 #CJK UNIFIED IDEOGRAPH + {0xD973, 0x6567}, //8374 #CJK UNIFIED IDEOGRAPH + {0xD974, 0x656A}, //8375 #CJK UNIFIED IDEOGRAPH + {0xD975, 0x6564}, //8376 #CJK UNIFIED IDEOGRAPH + {0xD976, 0x655C}, //8377 #CJK UNIFIED IDEOGRAPH + {0xD977, 0x6568}, //8378 #CJK UNIFIED IDEOGRAPH + {0xD978, 0x6565}, //8379 #CJK UNIFIED IDEOGRAPH + {0xD979, 0x658C}, //8380 #CJK UNIFIED IDEOGRAPH + {0xD97A, 0x659D}, //8381 #CJK UNIFIED IDEOGRAPH + {0xD97B, 0x659E}, //8382 #CJK UNIFIED IDEOGRAPH + {0xD97C, 0x65AE}, //8383 #CJK UNIFIED IDEOGRAPH + {0xD97D, 0x65D0}, //8384 #CJK UNIFIED IDEOGRAPH + {0xD97E, 0x65D2}, //8385 #CJK UNIFIED IDEOGRAPH + {0xD9A1, 0x667C}, //8386 #CJK UNIFIED IDEOGRAPH + {0xD9A2, 0x666C}, //8387 #CJK UNIFIED IDEOGRAPH + {0xD9A3, 0x667B}, //8388 #CJK UNIFIED IDEOGRAPH + {0xD9A4, 0x6680}, //8389 #CJK UNIFIED IDEOGRAPH + {0xD9A5, 0x6671}, //8390 #CJK UNIFIED IDEOGRAPH + {0xD9A6, 0x6679}, //8391 #CJK UNIFIED IDEOGRAPH + {0xD9A7, 0x666A}, //8392 #CJK UNIFIED IDEOGRAPH + {0xD9A8, 0x6672}, //8393 #CJK UNIFIED IDEOGRAPH + {0xD9A9, 0x6701}, //8394 #CJK UNIFIED IDEOGRAPH + {0xD9AA, 0x690C}, //8395 #CJK UNIFIED IDEOGRAPH + {0xD9AB, 0x68D3}, //8396 #CJK UNIFIED IDEOGRAPH + {0xD9AC, 0x6904}, //8397 #CJK UNIFIED IDEOGRAPH + {0xD9AD, 0x68DC}, //8398 #CJK UNIFIED IDEOGRAPH + {0xD9AE, 0x692A}, //8399 #CJK UNIFIED IDEOGRAPH + {0xD9AF, 0x68EC}, //8400 #CJK UNIFIED IDEOGRAPH + {0xD9B0, 0x68EA}, //8401 #CJK UNIFIED IDEOGRAPH + {0xD9B1, 0x68F1}, //8402 #CJK UNIFIED IDEOGRAPH + {0xD9B2, 0x690F}, //8403 #CJK UNIFIED IDEOGRAPH + {0xD9B3, 0x68D6}, //8404 #CJK UNIFIED IDEOGRAPH + {0xD9B4, 0x68F7}, //8405 #CJK UNIFIED IDEOGRAPH + {0xD9B5, 0x68EB}, //8406 #CJK UNIFIED IDEOGRAPH + {0xD9B6, 0x68E4}, //8407 #CJK UNIFIED IDEOGRAPH + {0xD9B7, 0x68F6}, //8408 #CJK UNIFIED IDEOGRAPH + {0xD9B8, 0x6913}, //8409 #CJK UNIFIED IDEOGRAPH + {0xD9B9, 0x6910}, //8410 #CJK UNIFIED IDEOGRAPH + {0xD9BA, 0x68F3}, //8411 #CJK UNIFIED IDEOGRAPH + {0xD9BB, 0x68E1}, //8412 #CJK UNIFIED IDEOGRAPH + {0xD9BC, 0x6907}, //8413 #CJK UNIFIED IDEOGRAPH + {0xD9BD, 0x68CC}, //8414 #CJK UNIFIED IDEOGRAPH + {0xD9BE, 0x6908}, //8415 #CJK UNIFIED IDEOGRAPH + {0xD9BF, 0x6970}, //8416 #CJK UNIFIED IDEOGRAPH + {0xD9C0, 0x68B4}, //8417 #CJK UNIFIED IDEOGRAPH + {0xD9C1, 0x6911}, //8418 #CJK UNIFIED IDEOGRAPH + {0xD9C2, 0x68EF}, //8419 #CJK UNIFIED IDEOGRAPH + {0xD9C3, 0x68C6}, //8420 #CJK UNIFIED IDEOGRAPH + {0xD9C4, 0x6914}, //8421 #CJK UNIFIED IDEOGRAPH + {0xD9C5, 0x68F8}, //8422 #CJK UNIFIED IDEOGRAPH + {0xD9C6, 0x68D0}, //8423 #CJK UNIFIED IDEOGRAPH + {0xD9C7, 0x68FD}, //8424 #CJK UNIFIED IDEOGRAPH + {0xD9C8, 0x68FC}, //8425 #CJK UNIFIED IDEOGRAPH + {0xD9C9, 0x68E8}, //8426 #CJK UNIFIED IDEOGRAPH + {0xD9CA, 0x690B}, //8427 #CJK UNIFIED IDEOGRAPH + {0xD9CB, 0x690A}, //8428 #CJK UNIFIED IDEOGRAPH + {0xD9CC, 0x6917}, //8429 #CJK UNIFIED IDEOGRAPH + {0xD9CD, 0x68CE}, //8430 #CJK UNIFIED IDEOGRAPH + {0xD9CE, 0x68C8}, //8431 #CJK UNIFIED IDEOGRAPH + {0xD9CF, 0x68DD}, //8432 #CJK UNIFIED IDEOGRAPH + {0xD9D0, 0x68DE}, //8433 #CJK UNIFIED IDEOGRAPH + {0xD9D1, 0x68E6}, //8434 #CJK UNIFIED IDEOGRAPH + {0xD9D2, 0x68F4}, //8435 #CJK UNIFIED IDEOGRAPH + {0xD9D3, 0x68D1}, //8436 #CJK UNIFIED IDEOGRAPH + {0xD9D4, 0x6906}, //8437 #CJK UNIFIED IDEOGRAPH + {0xD9D5, 0x68D4}, //8438 #CJK UNIFIED IDEOGRAPH + {0xD9D6, 0x68E9}, //8439 #CJK UNIFIED IDEOGRAPH + {0xD9D7, 0x6915}, //8440 #CJK UNIFIED IDEOGRAPH + {0xD9D8, 0x6925}, //8441 #CJK UNIFIED IDEOGRAPH + {0xD9D9, 0x68C7}, //8442 #CJK UNIFIED IDEOGRAPH + {0xD9DA, 0x6B39}, //8443 #CJK UNIFIED IDEOGRAPH + {0xD9DB, 0x6B3B}, //8444 #CJK UNIFIED IDEOGRAPH + {0xD9DC, 0x6B3F}, //8445 #CJK UNIFIED IDEOGRAPH + {0xD9DD, 0x6B3C}, //8446 #CJK UNIFIED IDEOGRAPH + {0xD9DE, 0x6B94}, //8447 #CJK UNIFIED IDEOGRAPH + {0xD9DF, 0x6B97}, //8448 #CJK UNIFIED IDEOGRAPH + {0xD9E0, 0x6B99}, //8449 #CJK UNIFIED IDEOGRAPH + {0xD9E1, 0x6B95}, //8450 #CJK UNIFIED IDEOGRAPH + {0xD9E2, 0x6BBD}, //8451 #CJK UNIFIED IDEOGRAPH + {0xD9E3, 0x6BF0}, //8452 #CJK UNIFIED IDEOGRAPH + {0xD9E4, 0x6BF2}, //8453 #CJK UNIFIED IDEOGRAPH + {0xD9E5, 0x6BF3}, //8454 #CJK UNIFIED IDEOGRAPH + {0xD9E6, 0x6C30}, //8455 #CJK UNIFIED IDEOGRAPH + {0xD9E7, 0x6DFC}, //8456 #CJK UNIFIED IDEOGRAPH + {0xD9E8, 0x6E46}, //8457 #CJK UNIFIED IDEOGRAPH + {0xD9E9, 0x6E47}, //8458 #CJK UNIFIED IDEOGRAPH + {0xD9EA, 0x6E1F}, //8459 #CJK UNIFIED IDEOGRAPH + {0xD9EB, 0x6E49}, //8460 #CJK UNIFIED IDEOGRAPH + {0xD9EC, 0x6E88}, //8461 #CJK UNIFIED IDEOGRAPH + {0xD9ED, 0x6E3C}, //8462 #CJK UNIFIED IDEOGRAPH + {0xD9EE, 0x6E3D}, //8463 #CJK UNIFIED IDEOGRAPH + {0xD9EF, 0x6E45}, //8464 #CJK UNIFIED IDEOGRAPH + {0xD9F0, 0x6E62}, //8465 #CJK UNIFIED IDEOGRAPH + {0xD9F1, 0x6E2B}, //8466 #CJK UNIFIED IDEOGRAPH + {0xD9F2, 0x6E3F}, //8467 #CJK UNIFIED IDEOGRAPH + {0xD9F3, 0x6E41}, //8468 #CJK UNIFIED IDEOGRAPH + {0xD9F4, 0x6E5D}, //8469 #CJK UNIFIED IDEOGRAPH + {0xD9F5, 0x6E73}, //8470 #CJK UNIFIED IDEOGRAPH + {0xD9F6, 0x6E1C}, //8471 #CJK UNIFIED IDEOGRAPH + {0xD9F7, 0x6E33}, //8472 #CJK UNIFIED IDEOGRAPH + {0xD9F8, 0x6E4B}, //8473 #CJK UNIFIED IDEOGRAPH + {0xD9F9, 0x6E40}, //8474 #CJK UNIFIED IDEOGRAPH + {0xD9FA, 0x6E51}, //8475 #CJK UNIFIED IDEOGRAPH + {0xD9FB, 0x6E3B}, //8476 #CJK UNIFIED IDEOGRAPH + {0xD9FC, 0x6E03}, //8477 #CJK UNIFIED IDEOGRAPH + {0xD9FD, 0x6E2E}, //8478 #CJK UNIFIED IDEOGRAPH + {0xD9FE, 0x6E5E}, //8479 #CJK UNIFIED IDEOGRAPH + {0xDA40, 0x6E68}, //8480 #CJK UNIFIED IDEOGRAPH + {0xDA41, 0x6E5C}, //8481 #CJK UNIFIED IDEOGRAPH + {0xDA42, 0x6E61}, //8482 #CJK UNIFIED IDEOGRAPH + {0xDA43, 0x6E31}, //8483 #CJK UNIFIED IDEOGRAPH + {0xDA44, 0x6E28}, //8484 #CJK UNIFIED IDEOGRAPH + {0xDA45, 0x6E60}, //8485 #CJK UNIFIED IDEOGRAPH + {0xDA46, 0x6E71}, //8486 #CJK UNIFIED IDEOGRAPH + {0xDA47, 0x6E6B}, //8487 #CJK UNIFIED IDEOGRAPH + {0xDA48, 0x6E39}, //8488 #CJK UNIFIED IDEOGRAPH + {0xDA49, 0x6E22}, //8489 #CJK UNIFIED IDEOGRAPH + {0xDA4A, 0x6E30}, //8490 #CJK UNIFIED IDEOGRAPH + {0xDA4B, 0x6E53}, //8491 #CJK UNIFIED IDEOGRAPH + {0xDA4C, 0x6E65}, //8492 #CJK UNIFIED IDEOGRAPH + {0xDA4D, 0x6E27}, //8493 #CJK UNIFIED IDEOGRAPH + {0xDA4E, 0x6E78}, //8494 #CJK UNIFIED IDEOGRAPH + {0xDA4F, 0x6E64}, //8495 #CJK UNIFIED IDEOGRAPH + {0xDA50, 0x6E77}, //8496 #CJK UNIFIED IDEOGRAPH + {0xDA51, 0x6E55}, //8497 #CJK UNIFIED IDEOGRAPH + {0xDA52, 0x6E79}, //8498 #CJK UNIFIED IDEOGRAPH + {0xDA53, 0x6E52}, //8499 #CJK UNIFIED IDEOGRAPH + {0xDA54, 0x6E66}, //8500 #CJK UNIFIED IDEOGRAPH + {0xDA55, 0x6E35}, //8501 #CJK UNIFIED IDEOGRAPH + {0xDA56, 0x6E36}, //8502 #CJK UNIFIED IDEOGRAPH + {0xDA57, 0x6E5A}, //8503 #CJK UNIFIED IDEOGRAPH + {0xDA58, 0x7120}, //8504 #CJK UNIFIED IDEOGRAPH + {0xDA59, 0x711E}, //8505 #CJK UNIFIED IDEOGRAPH + {0xDA5A, 0x712F}, //8506 #CJK UNIFIED IDEOGRAPH + {0xDA5B, 0x70FB}, //8507 #CJK UNIFIED IDEOGRAPH + {0xDA5C, 0x712E}, //8508 #CJK UNIFIED IDEOGRAPH + {0xDA5D, 0x7131}, //8509 #CJK UNIFIED IDEOGRAPH + {0xDA5E, 0x7123}, //8510 #CJK UNIFIED IDEOGRAPH + {0xDA5F, 0x7125}, //8511 #CJK UNIFIED IDEOGRAPH + {0xDA60, 0x7122}, //8512 #CJK UNIFIED IDEOGRAPH + {0xDA61, 0x7132}, //8513 #CJK UNIFIED IDEOGRAPH + {0xDA62, 0x711F}, //8514 #CJK UNIFIED IDEOGRAPH + {0xDA63, 0x7128}, //8515 #CJK UNIFIED IDEOGRAPH + {0xDA64, 0x713A}, //8516 #CJK UNIFIED IDEOGRAPH + {0xDA65, 0x711B}, //8517 #CJK UNIFIED IDEOGRAPH + {0xDA66, 0x724B}, //8518 #CJK UNIFIED IDEOGRAPH + {0xDA67, 0x725A}, //8519 #CJK UNIFIED IDEOGRAPH + {0xDA68, 0x7288}, //8520 #CJK UNIFIED IDEOGRAPH + {0xDA69, 0x7289}, //8521 #CJK UNIFIED IDEOGRAPH + {0xDA6A, 0x7286}, //8522 #CJK UNIFIED IDEOGRAPH + {0xDA6B, 0x7285}, //8523 #CJK UNIFIED IDEOGRAPH + {0xDA6C, 0x728B}, //8524 #CJK UNIFIED IDEOGRAPH + {0xDA6D, 0x7312}, //8525 #CJK UNIFIED IDEOGRAPH + {0xDA6E, 0x730B}, //8526 #CJK UNIFIED IDEOGRAPH + {0xDA6F, 0x7330}, //8527 #CJK UNIFIED IDEOGRAPH + {0xDA70, 0x7322}, //8528 #CJK UNIFIED IDEOGRAPH + {0xDA71, 0x7331}, //8529 #CJK UNIFIED IDEOGRAPH + {0xDA72, 0x7333}, //8530 #CJK UNIFIED IDEOGRAPH + {0xDA73, 0x7327}, //8531 #CJK UNIFIED IDEOGRAPH + {0xDA74, 0x7332}, //8532 #CJK UNIFIED IDEOGRAPH + {0xDA75, 0x732D}, //8533 #CJK UNIFIED IDEOGRAPH + {0xDA76, 0x7326}, //8534 #CJK UNIFIED IDEOGRAPH + {0xDA77, 0x7323}, //8535 #CJK UNIFIED IDEOGRAPH + {0xDA78, 0x7335}, //8536 #CJK UNIFIED IDEOGRAPH + {0xDA79, 0x730C}, //8537 #CJK UNIFIED IDEOGRAPH + {0xDA7A, 0x742E}, //8538 #CJK UNIFIED IDEOGRAPH + {0xDA7B, 0x742C}, //8539 #CJK UNIFIED IDEOGRAPH + {0xDA7C, 0x7430}, //8540 #CJK UNIFIED IDEOGRAPH + {0xDA7D, 0x742B}, //8541 #CJK UNIFIED IDEOGRAPH + {0xDA7E, 0x7416}, //8542 #CJK UNIFIED IDEOGRAPH + {0xDAA1, 0x741A}, //8543 #CJK UNIFIED IDEOGRAPH + {0xDAA2, 0x7421}, //8544 #CJK UNIFIED IDEOGRAPH + {0xDAA3, 0x742D}, //8545 #CJK UNIFIED IDEOGRAPH + {0xDAA4, 0x7431}, //8546 #CJK UNIFIED IDEOGRAPH + {0xDAA5, 0x7424}, //8547 #CJK UNIFIED IDEOGRAPH + {0xDAA6, 0x7423}, //8548 #CJK UNIFIED IDEOGRAPH + {0xDAA7, 0x741D}, //8549 #CJK UNIFIED IDEOGRAPH + {0xDAA8, 0x7429}, //8550 #CJK UNIFIED IDEOGRAPH + {0xDAA9, 0x7420}, //8551 #CJK UNIFIED IDEOGRAPH + {0xDAAA, 0x7432}, //8552 #CJK UNIFIED IDEOGRAPH + {0xDAAB, 0x74FB}, //8553 #CJK UNIFIED IDEOGRAPH + {0xDAAC, 0x752F}, //8554 #CJK UNIFIED IDEOGRAPH + {0xDAAD, 0x756F}, //8555 #CJK UNIFIED IDEOGRAPH + {0xDAAE, 0x756C}, //8556 #CJK UNIFIED IDEOGRAPH + {0xDAAF, 0x75E7}, //8557 #CJK UNIFIED IDEOGRAPH + {0xDAB0, 0x75DA}, //8558 #CJK UNIFIED IDEOGRAPH + {0xDAB1, 0x75E1}, //8559 #CJK UNIFIED IDEOGRAPH + {0xDAB2, 0x75E6}, //8560 #CJK UNIFIED IDEOGRAPH + {0xDAB3, 0x75DD}, //8561 #CJK UNIFIED IDEOGRAPH + {0xDAB4, 0x75DF}, //8562 #CJK UNIFIED IDEOGRAPH + {0xDAB5, 0x75E4}, //8563 #CJK UNIFIED IDEOGRAPH + {0xDAB6, 0x75D7}, //8564 #CJK UNIFIED IDEOGRAPH + {0xDAB7, 0x7695}, //8565 #CJK UNIFIED IDEOGRAPH + {0xDAB8, 0x7692}, //8566 #CJK UNIFIED IDEOGRAPH + {0xDAB9, 0x76DA}, //8567 #CJK UNIFIED IDEOGRAPH + {0xDABA, 0x7746}, //8568 #CJK UNIFIED IDEOGRAPH + {0xDABB, 0x7747}, //8569 #CJK UNIFIED IDEOGRAPH + {0xDABC, 0x7744}, //8570 #CJK UNIFIED IDEOGRAPH + {0xDABD, 0x774D}, //8571 #CJK UNIFIED IDEOGRAPH + {0xDABE, 0x7745}, //8572 #CJK UNIFIED IDEOGRAPH + {0xDABF, 0x774A}, //8573 #CJK UNIFIED IDEOGRAPH + {0xDAC0, 0x774E}, //8574 #CJK UNIFIED IDEOGRAPH + {0xDAC1, 0x774B}, //8575 #CJK UNIFIED IDEOGRAPH + {0xDAC2, 0x774C}, //8576 #CJK UNIFIED IDEOGRAPH + {0xDAC3, 0x77DE}, //8577 #CJK UNIFIED IDEOGRAPH + {0xDAC4, 0x77EC}, //8578 #CJK UNIFIED IDEOGRAPH + {0xDAC5, 0x7860}, //8579 #CJK UNIFIED IDEOGRAPH + {0xDAC6, 0x7864}, //8580 #CJK UNIFIED IDEOGRAPH + {0xDAC7, 0x7865}, //8581 #CJK UNIFIED IDEOGRAPH + {0xDAC8, 0x785C}, //8582 #CJK UNIFIED IDEOGRAPH + {0xDAC9, 0x786D}, //8583 #CJK UNIFIED IDEOGRAPH + {0xDACA, 0x7871}, //8584 #CJK UNIFIED IDEOGRAPH + {0xDACB, 0x786A}, //8585 #CJK UNIFIED IDEOGRAPH + {0xDACC, 0x786E}, //8586 #CJK UNIFIED IDEOGRAPH + {0xDACD, 0x7870}, //8587 #CJK UNIFIED IDEOGRAPH + {0xDACE, 0x7869}, //8588 #CJK UNIFIED IDEOGRAPH + {0xDACF, 0x7868}, //8589 #CJK UNIFIED IDEOGRAPH + {0xDAD0, 0x785E}, //8590 #CJK UNIFIED IDEOGRAPH + {0xDAD1, 0x7862}, //8591 #CJK UNIFIED IDEOGRAPH + {0xDAD2, 0x7974}, //8592 #CJK UNIFIED IDEOGRAPH + {0xDAD3, 0x7973}, //8593 #CJK UNIFIED IDEOGRAPH + {0xDAD4, 0x7972}, //8594 #CJK UNIFIED IDEOGRAPH + {0xDAD5, 0x7970}, //8595 #CJK UNIFIED IDEOGRAPH + {0xDAD6, 0x7A02}, //8596 #CJK UNIFIED IDEOGRAPH + {0xDAD7, 0x7A0A}, //8597 #CJK UNIFIED IDEOGRAPH + {0xDAD8, 0x7A03}, //8598 #CJK UNIFIED IDEOGRAPH + {0xDAD9, 0x7A0C}, //8599 #CJK UNIFIED IDEOGRAPH + {0xDADA, 0x7A04}, //8600 #CJK UNIFIED IDEOGRAPH + {0xDADB, 0x7A99}, //8601 #CJK UNIFIED IDEOGRAPH + {0xDADC, 0x7AE6}, //8602 #CJK UNIFIED IDEOGRAPH + {0xDADD, 0x7AE4}, //8603 #CJK UNIFIED IDEOGRAPH + {0xDADE, 0x7B4A}, //8604 #CJK UNIFIED IDEOGRAPH + {0xDADF, 0x7B3B}, //8605 #CJK UNIFIED IDEOGRAPH + {0xDAE0, 0x7B44}, //8606 #CJK UNIFIED IDEOGRAPH + {0xDAE1, 0x7B48}, //8607 #CJK UNIFIED IDEOGRAPH + {0xDAE2, 0x7B4C}, //8608 #CJK UNIFIED IDEOGRAPH + {0xDAE3, 0x7B4E}, //8609 #CJK UNIFIED IDEOGRAPH + {0xDAE4, 0x7B40}, //8610 #CJK UNIFIED IDEOGRAPH + {0xDAE5, 0x7B58}, //8611 #CJK UNIFIED IDEOGRAPH + {0xDAE6, 0x7B45}, //8612 #CJK UNIFIED IDEOGRAPH + {0xDAE7, 0x7CA2}, //8613 #CJK UNIFIED IDEOGRAPH + {0xDAE8, 0x7C9E}, //8614 #CJK UNIFIED IDEOGRAPH + {0xDAE9, 0x7CA8}, //8615 #CJK UNIFIED IDEOGRAPH + {0xDAEA, 0x7CA1}, //8616 #CJK UNIFIED IDEOGRAPH + {0xDAEB, 0x7D58}, //8617 #CJK UNIFIED IDEOGRAPH + {0xDAEC, 0x7D6F}, //8618 #CJK UNIFIED IDEOGRAPH + {0xDAED, 0x7D63}, //8619 #CJK UNIFIED IDEOGRAPH + {0xDAEE, 0x7D53}, //8620 #CJK UNIFIED IDEOGRAPH + {0xDAEF, 0x7D56}, //8621 #CJK UNIFIED IDEOGRAPH + {0xDAF0, 0x7D67}, //8622 #CJK UNIFIED IDEOGRAPH + {0xDAF1, 0x7D6A}, //8623 #CJK UNIFIED IDEOGRAPH + {0xDAF2, 0x7D4F}, //8624 #CJK UNIFIED IDEOGRAPH + {0xDAF3, 0x7D6D}, //8625 #CJK UNIFIED IDEOGRAPH + {0xDAF4, 0x7D5C}, //8626 #CJK UNIFIED IDEOGRAPH + {0xDAF5, 0x7D6B}, //8627 #CJK UNIFIED IDEOGRAPH + {0xDAF6, 0x7D52}, //8628 #CJK UNIFIED IDEOGRAPH + {0xDAF7, 0x7D54}, //8629 #CJK UNIFIED IDEOGRAPH + {0xDAF8, 0x7D69}, //8630 #CJK UNIFIED IDEOGRAPH + {0xDAF9, 0x7D51}, //8631 #CJK UNIFIED IDEOGRAPH + {0xDAFA, 0x7D5F}, //8632 #CJK UNIFIED IDEOGRAPH + {0xDAFB, 0x7D4E}, //8633 #CJK UNIFIED IDEOGRAPH + {0xDAFC, 0x7F3E}, //8634 #CJK UNIFIED IDEOGRAPH + {0xDAFD, 0x7F3F}, //8635 #CJK UNIFIED IDEOGRAPH + {0xDAFE, 0x7F65}, //8636 #CJK UNIFIED IDEOGRAPH + {0xDB40, 0x7F66}, //8637 #CJK UNIFIED IDEOGRAPH + {0xDB41, 0x7FA2}, //8638 #CJK UNIFIED IDEOGRAPH + {0xDB42, 0x7FA0}, //8639 #CJK UNIFIED IDEOGRAPH + {0xDB43, 0x7FA1}, //8640 #CJK UNIFIED IDEOGRAPH + {0xDB44, 0x7FD7}, //8641 #CJK UNIFIED IDEOGRAPH + {0xDB45, 0x8051}, //8642 #CJK UNIFIED IDEOGRAPH + {0xDB46, 0x804F}, //8643 #CJK UNIFIED IDEOGRAPH + {0xDB47, 0x8050}, //8644 #CJK UNIFIED IDEOGRAPH + {0xDB48, 0x80FE}, //8645 #CJK UNIFIED IDEOGRAPH + {0xDB49, 0x80D4}, //8646 #CJK UNIFIED IDEOGRAPH + {0xDB4A, 0x8143}, //8647 #CJK UNIFIED IDEOGRAPH + {0xDB4B, 0x814A}, //8648 #CJK UNIFIED IDEOGRAPH + {0xDB4C, 0x8152}, //8649 #CJK UNIFIED IDEOGRAPH + {0xDB4D, 0x814F}, //8650 #CJK UNIFIED IDEOGRAPH + {0xDB4E, 0x8147}, //8651 #CJK UNIFIED IDEOGRAPH + {0xDB4F, 0x813D}, //8652 #CJK UNIFIED IDEOGRAPH + {0xDB50, 0x814D}, //8653 #CJK UNIFIED IDEOGRAPH + {0xDB51, 0x813A}, //8654 #CJK UNIFIED IDEOGRAPH + {0xDB52, 0x81E6}, //8655 #CJK UNIFIED IDEOGRAPH + {0xDB53, 0x81EE}, //8656 #CJK UNIFIED IDEOGRAPH + {0xDB54, 0x81F7}, //8657 #CJK UNIFIED IDEOGRAPH + {0xDB55, 0x81F8}, //8658 #CJK UNIFIED IDEOGRAPH + {0xDB56, 0x81F9}, //8659 #CJK UNIFIED IDEOGRAPH + {0xDB57, 0x8204}, //8660 #CJK UNIFIED IDEOGRAPH + {0xDB58, 0x823C}, //8661 #CJK UNIFIED IDEOGRAPH + {0xDB59, 0x823D}, //8662 #CJK UNIFIED IDEOGRAPH + {0xDB5A, 0x823F}, //8663 #CJK UNIFIED IDEOGRAPH + {0xDB5B, 0x8275}, //8664 #CJK UNIFIED IDEOGRAPH + {0xDB5C, 0x833B}, //8665 #CJK UNIFIED IDEOGRAPH + {0xDB5D, 0x83CF}, //8666 #CJK UNIFIED IDEOGRAPH + {0xDB5E, 0x83F9}, //8667 #CJK UNIFIED IDEOGRAPH + {0xDB5F, 0x8423}, //8668 #CJK UNIFIED IDEOGRAPH + {0xDB60, 0x83C0}, //8669 #CJK UNIFIED IDEOGRAPH + {0xDB61, 0x83E8}, //8670 #CJK UNIFIED IDEOGRAPH + {0xDB62, 0x8412}, //8671 #CJK UNIFIED IDEOGRAPH + {0xDB63, 0x83E7}, //8672 #CJK UNIFIED IDEOGRAPH + {0xDB64, 0x83E4}, //8673 #CJK UNIFIED IDEOGRAPH + {0xDB65, 0x83FC}, //8674 #CJK UNIFIED IDEOGRAPH + {0xDB66, 0x83F6}, //8675 #CJK UNIFIED IDEOGRAPH + {0xDB67, 0x8410}, //8676 #CJK UNIFIED IDEOGRAPH + {0xDB68, 0x83C6}, //8677 #CJK UNIFIED IDEOGRAPH + {0xDB69, 0x83C8}, //8678 #CJK UNIFIED IDEOGRAPH + {0xDB6A, 0x83EB}, //8679 #CJK UNIFIED IDEOGRAPH + {0xDB6B, 0x83E3}, //8680 #CJK UNIFIED IDEOGRAPH + {0xDB6C, 0x83BF}, //8681 #CJK UNIFIED IDEOGRAPH + {0xDB6D, 0x8401}, //8682 #CJK UNIFIED IDEOGRAPH + {0xDB6E, 0x83DD}, //8683 #CJK UNIFIED IDEOGRAPH + {0xDB6F, 0x83E5}, //8684 #CJK UNIFIED IDEOGRAPH + {0xDB70, 0x83D8}, //8685 #CJK UNIFIED IDEOGRAPH + {0xDB71, 0x83FF}, //8686 #CJK UNIFIED IDEOGRAPH + {0xDB72, 0x83E1}, //8687 #CJK UNIFIED IDEOGRAPH + {0xDB73, 0x83CB}, //8688 #CJK UNIFIED IDEOGRAPH + {0xDB74, 0x83CE}, //8689 #CJK UNIFIED IDEOGRAPH + {0xDB75, 0x83D6}, //8690 #CJK UNIFIED IDEOGRAPH + {0xDB76, 0x83F5}, //8691 #CJK UNIFIED IDEOGRAPH + {0xDB77, 0x83C9}, //8692 #CJK UNIFIED IDEOGRAPH + {0xDB78, 0x8409}, //8693 #CJK UNIFIED IDEOGRAPH + {0xDB79, 0x840F}, //8694 #CJK UNIFIED IDEOGRAPH + {0xDB7A, 0x83DE}, //8695 #CJK UNIFIED IDEOGRAPH + {0xDB7B, 0x8411}, //8696 #CJK UNIFIED IDEOGRAPH + {0xDB7C, 0x8406}, //8697 #CJK UNIFIED IDEOGRAPH + {0xDB7D, 0x83C2}, //8698 #CJK UNIFIED IDEOGRAPH + {0xDB7E, 0x83F3}, //8699 #CJK UNIFIED IDEOGRAPH + {0xDBA1, 0x83D5}, //8700 #CJK UNIFIED IDEOGRAPH + {0xDBA2, 0x83FA}, //8701 #CJK UNIFIED IDEOGRAPH + {0xDBA3, 0x83C7}, //8702 #CJK UNIFIED IDEOGRAPH + {0xDBA4, 0x83D1}, //8703 #CJK UNIFIED IDEOGRAPH + {0xDBA5, 0x83EA}, //8704 #CJK UNIFIED IDEOGRAPH + {0xDBA6, 0x8413}, //8705 #CJK UNIFIED IDEOGRAPH + {0xDBA7, 0x83C3}, //8706 #CJK UNIFIED IDEOGRAPH + {0xDBA8, 0x83EC}, //8707 #CJK UNIFIED IDEOGRAPH + {0xDBA9, 0x83EE}, //8708 #CJK UNIFIED IDEOGRAPH + {0xDBAA, 0x83C4}, //8709 #CJK UNIFIED IDEOGRAPH + {0xDBAB, 0x83FB}, //8710 #CJK UNIFIED IDEOGRAPH + {0xDBAC, 0x83D7}, //8711 #CJK UNIFIED IDEOGRAPH + {0xDBAD, 0x83E2}, //8712 #CJK UNIFIED IDEOGRAPH + {0xDBAE, 0x841B}, //8713 #CJK UNIFIED IDEOGRAPH + {0xDBAF, 0x83DB}, //8714 #CJK UNIFIED IDEOGRAPH + {0xDBB0, 0x83FE}, //8715 #CJK UNIFIED IDEOGRAPH + {0xDBB1, 0x86D8}, //8716 #CJK UNIFIED IDEOGRAPH + {0xDBB2, 0x86E2}, //8717 #CJK UNIFIED IDEOGRAPH + {0xDBB3, 0x86E6}, //8718 #CJK UNIFIED IDEOGRAPH + {0xDBB4, 0x86D3}, //8719 #CJK UNIFIED IDEOGRAPH + {0xDBB5, 0x86E3}, //8720 #CJK UNIFIED IDEOGRAPH + {0xDBB6, 0x86DA}, //8721 #CJK UNIFIED IDEOGRAPH + {0xDBB7, 0x86EA}, //8722 #CJK UNIFIED IDEOGRAPH + {0xDBB8, 0x86DD}, //8723 #CJK UNIFIED IDEOGRAPH + {0xDBB9, 0x86EB}, //8724 #CJK UNIFIED IDEOGRAPH + {0xDBBA, 0x86DC}, //8725 #CJK UNIFIED IDEOGRAPH + {0xDBBB, 0x86EC}, //8726 #CJK UNIFIED IDEOGRAPH + {0xDBBC, 0x86E9}, //8727 #CJK UNIFIED IDEOGRAPH + {0xDBBD, 0x86D7}, //8728 #CJK UNIFIED IDEOGRAPH + {0xDBBE, 0x86E8}, //8729 #CJK UNIFIED IDEOGRAPH + {0xDBBF, 0x86D1}, //8730 #CJK UNIFIED IDEOGRAPH + {0xDBC0, 0x8848}, //8731 #CJK UNIFIED IDEOGRAPH + {0xDBC1, 0x8856}, //8732 #CJK UNIFIED IDEOGRAPH + {0xDBC2, 0x8855}, //8733 #CJK UNIFIED IDEOGRAPH + {0xDBC3, 0x88BA}, //8734 #CJK UNIFIED IDEOGRAPH + {0xDBC4, 0x88D7}, //8735 #CJK UNIFIED IDEOGRAPH + {0xDBC5, 0x88B9}, //8736 #CJK UNIFIED IDEOGRAPH + {0xDBC6, 0x88B8}, //8737 #CJK UNIFIED IDEOGRAPH + {0xDBC7, 0x88C0}, //8738 #CJK UNIFIED IDEOGRAPH + {0xDBC8, 0x88BE}, //8739 #CJK UNIFIED IDEOGRAPH + {0xDBC9, 0x88B6}, //8740 #CJK UNIFIED IDEOGRAPH + {0xDBCA, 0x88BC}, //8741 #CJK UNIFIED IDEOGRAPH + {0xDBCB, 0x88B7}, //8742 #CJK UNIFIED IDEOGRAPH + {0xDBCC, 0x88BD}, //8743 #CJK UNIFIED IDEOGRAPH + {0xDBCD, 0x88B2}, //8744 #CJK UNIFIED IDEOGRAPH + {0xDBCE, 0x8901}, //8745 #CJK UNIFIED IDEOGRAPH + {0xDBCF, 0x88C9}, //8746 #CJK UNIFIED IDEOGRAPH + {0xDBD0, 0x8995}, //8747 #CJK UNIFIED IDEOGRAPH + {0xDBD1, 0x8998}, //8748 #CJK UNIFIED IDEOGRAPH + {0xDBD2, 0x8997}, //8749 #CJK UNIFIED IDEOGRAPH + {0xDBD3, 0x89DD}, //8750 #CJK UNIFIED IDEOGRAPH + {0xDBD4, 0x89DA}, //8751 #CJK UNIFIED IDEOGRAPH + {0xDBD5, 0x89DB}, //8752 #CJK UNIFIED IDEOGRAPH + {0xDBD6, 0x8A4E}, //8753 #CJK UNIFIED IDEOGRAPH + {0xDBD7, 0x8A4D}, //8754 #CJK UNIFIED IDEOGRAPH + {0xDBD8, 0x8A39}, //8755 #CJK UNIFIED IDEOGRAPH + {0xDBD9, 0x8A59}, //8756 #CJK UNIFIED IDEOGRAPH + {0xDBDA, 0x8A40}, //8757 #CJK UNIFIED IDEOGRAPH + {0xDBDB, 0x8A57}, //8758 #CJK UNIFIED IDEOGRAPH + {0xDBDC, 0x8A58}, //8759 #CJK UNIFIED IDEOGRAPH + {0xDBDD, 0x8A44}, //8760 #CJK UNIFIED IDEOGRAPH + {0xDBDE, 0x8A45}, //8761 #CJK UNIFIED IDEOGRAPH + {0xDBDF, 0x8A52}, //8762 #CJK UNIFIED IDEOGRAPH + {0xDBE0, 0x8A48}, //8763 #CJK UNIFIED IDEOGRAPH + {0xDBE1, 0x8A51}, //8764 #CJK UNIFIED IDEOGRAPH + {0xDBE2, 0x8A4A}, //8765 #CJK UNIFIED IDEOGRAPH + {0xDBE3, 0x8A4C}, //8766 #CJK UNIFIED IDEOGRAPH + {0xDBE4, 0x8A4F}, //8767 #CJK UNIFIED IDEOGRAPH + {0xDBE5, 0x8C5F}, //8768 #CJK UNIFIED IDEOGRAPH + {0xDBE6, 0x8C81}, //8769 #CJK UNIFIED IDEOGRAPH + {0xDBE7, 0x8C80}, //8770 #CJK UNIFIED IDEOGRAPH + {0xDBE8, 0x8CBA}, //8771 #CJK UNIFIED IDEOGRAPH + {0xDBE9, 0x8CBE}, //8772 #CJK UNIFIED IDEOGRAPH + {0xDBEA, 0x8CB0}, //8773 #CJK UNIFIED IDEOGRAPH + {0xDBEB, 0x8CB9}, //8774 #CJK UNIFIED IDEOGRAPH + {0xDBEC, 0x8CB5}, //8775 #CJK UNIFIED IDEOGRAPH + {0xDBED, 0x8D84}, //8776 #CJK UNIFIED IDEOGRAPH + {0xDBEE, 0x8D80}, //8777 #CJK UNIFIED IDEOGRAPH + {0xDBEF, 0x8D89}, //8778 #CJK UNIFIED IDEOGRAPH + {0xDBF0, 0x8DD8}, //8779 #CJK UNIFIED IDEOGRAPH + {0xDBF1, 0x8DD3}, //8780 #CJK UNIFIED IDEOGRAPH + {0xDBF2, 0x8DCD}, //8781 #CJK UNIFIED IDEOGRAPH + {0xDBF3, 0x8DC7}, //8782 #CJK UNIFIED IDEOGRAPH + {0xDBF4, 0x8DD6}, //8783 #CJK UNIFIED IDEOGRAPH + {0xDBF5, 0x8DDC}, //8784 #CJK UNIFIED IDEOGRAPH + {0xDBF6, 0x8DCF}, //8785 #CJK UNIFIED IDEOGRAPH + {0xDBF7, 0x8DD5}, //8786 #CJK UNIFIED IDEOGRAPH + {0xDBF8, 0x8DD9}, //8787 #CJK UNIFIED IDEOGRAPH + {0xDBF9, 0x8DC8}, //8788 #CJK UNIFIED IDEOGRAPH + {0xDBFA, 0x8DD7}, //8789 #CJK UNIFIED IDEOGRAPH + {0xDBFB, 0x8DC5}, //8790 #CJK UNIFIED IDEOGRAPH + {0xDBFC, 0x8EEF}, //8791 #CJK UNIFIED IDEOGRAPH + {0xDBFD, 0x8EF7}, //8792 #CJK UNIFIED IDEOGRAPH + {0xDBFE, 0x8EFA}, //8793 #CJK UNIFIED IDEOGRAPH + {0xDC40, 0x8EF9}, //8794 #CJK UNIFIED IDEOGRAPH + {0xDC41, 0x8EE6}, //8795 #CJK UNIFIED IDEOGRAPH + {0xDC42, 0x8EEE}, //8796 #CJK UNIFIED IDEOGRAPH + {0xDC43, 0x8EE5}, //8797 #CJK UNIFIED IDEOGRAPH + {0xDC44, 0x8EF5}, //8798 #CJK UNIFIED IDEOGRAPH + {0xDC45, 0x8EE7}, //8799 #CJK UNIFIED IDEOGRAPH + {0xDC46, 0x8EE8}, //8800 #CJK UNIFIED IDEOGRAPH + {0xDC47, 0x8EF6}, //8801 #CJK UNIFIED IDEOGRAPH + {0xDC48, 0x8EEB}, //8802 #CJK UNIFIED IDEOGRAPH + {0xDC49, 0x8EF1}, //8803 #CJK UNIFIED IDEOGRAPH + {0xDC4A, 0x8EEC}, //8804 #CJK UNIFIED IDEOGRAPH + {0xDC4B, 0x8EF4}, //8805 #CJK UNIFIED IDEOGRAPH + {0xDC4C, 0x8EE9}, //8806 #CJK UNIFIED IDEOGRAPH + {0xDC4D, 0x902D}, //8807 #CJK UNIFIED IDEOGRAPH + {0xDC4E, 0x9034}, //8808 #CJK UNIFIED IDEOGRAPH + {0xDC4F, 0x902F}, //8809 #CJK UNIFIED IDEOGRAPH + {0xDC50, 0x9106}, //8810 #CJK UNIFIED IDEOGRAPH + {0xDC51, 0x912C}, //8811 #CJK UNIFIED IDEOGRAPH + {0xDC52, 0x9104}, //8812 #CJK UNIFIED IDEOGRAPH + {0xDC53, 0x90FF}, //8813 #CJK UNIFIED IDEOGRAPH + {0xDC54, 0x90FC}, //8814 #CJK UNIFIED IDEOGRAPH + {0xDC55, 0x9108}, //8815 #CJK UNIFIED IDEOGRAPH + {0xDC56, 0x90F9}, //8816 #CJK UNIFIED IDEOGRAPH + {0xDC57, 0x90FB}, //8817 #CJK UNIFIED IDEOGRAPH + {0xDC58, 0x9101}, //8818 #CJK UNIFIED IDEOGRAPH + {0xDC59, 0x9100}, //8819 #CJK UNIFIED IDEOGRAPH + {0xDC5A, 0x9107}, //8820 #CJK UNIFIED IDEOGRAPH + {0xDC5B, 0x9105}, //8821 #CJK UNIFIED IDEOGRAPH + {0xDC5C, 0x9103}, //8822 #CJK UNIFIED IDEOGRAPH + {0xDC5D, 0x9161}, //8823 #CJK UNIFIED IDEOGRAPH + {0xDC5E, 0x9164}, //8824 #CJK UNIFIED IDEOGRAPH + {0xDC5F, 0x915F}, //8825 #CJK UNIFIED IDEOGRAPH + {0xDC60, 0x9162}, //8826 #CJK UNIFIED IDEOGRAPH + {0xDC61, 0x9160}, //8827 #CJK UNIFIED IDEOGRAPH + {0xDC62, 0x9201}, //8828 #CJK UNIFIED IDEOGRAPH + {0xDC63, 0x920A}, //8829 #CJK UNIFIED IDEOGRAPH + {0xDC64, 0x9225}, //8830 #CJK UNIFIED IDEOGRAPH + {0xDC65, 0x9203}, //8831 #CJK UNIFIED IDEOGRAPH + {0xDC66, 0x921A}, //8832 #CJK UNIFIED IDEOGRAPH + {0xDC67, 0x9226}, //8833 #CJK UNIFIED IDEOGRAPH + {0xDC68, 0x920F}, //8834 #CJK UNIFIED IDEOGRAPH + {0xDC69, 0x920C}, //8835 #CJK UNIFIED IDEOGRAPH + {0xDC6A, 0x9200}, //8836 #CJK UNIFIED IDEOGRAPH + {0xDC6B, 0x9212}, //8837 #CJK UNIFIED IDEOGRAPH + {0xDC6C, 0x91FF}, //8838 #CJK UNIFIED IDEOGRAPH + {0xDC6D, 0x91FD}, //8839 #CJK UNIFIED IDEOGRAPH + {0xDC6E, 0x9206}, //8840 #CJK UNIFIED IDEOGRAPH + {0xDC6F, 0x9204}, //8841 #CJK UNIFIED IDEOGRAPH + {0xDC70, 0x9227}, //8842 #CJK UNIFIED IDEOGRAPH + {0xDC71, 0x9202}, //8843 #CJK UNIFIED IDEOGRAPH + {0xDC72, 0x921C}, //8844 #CJK UNIFIED IDEOGRAPH + {0xDC73, 0x9224}, //8845 #CJK UNIFIED IDEOGRAPH + {0xDC74, 0x9219}, //8846 #CJK UNIFIED IDEOGRAPH + {0xDC75, 0x9217}, //8847 #CJK UNIFIED IDEOGRAPH + {0xDC76, 0x9205}, //8848 #CJK UNIFIED IDEOGRAPH + {0xDC77, 0x9216}, //8849 #CJK UNIFIED IDEOGRAPH + {0xDC78, 0x957B}, //8850 #CJK UNIFIED IDEOGRAPH + {0xDC79, 0x958D}, //8851 #CJK UNIFIED IDEOGRAPH + {0xDC7A, 0x958C}, //8852 #CJK UNIFIED IDEOGRAPH + {0xDC7B, 0x9590}, //8853 #CJK UNIFIED IDEOGRAPH + {0xDC7C, 0x9687}, //8854 #CJK UNIFIED IDEOGRAPH + {0xDC7D, 0x967E}, //8855 #CJK UNIFIED IDEOGRAPH + {0xDC7E, 0x9688}, //8856 #CJK UNIFIED IDEOGRAPH + {0xDCA1, 0x9689}, //8857 #CJK UNIFIED IDEOGRAPH + {0xDCA2, 0x9683}, //8858 #CJK UNIFIED IDEOGRAPH + {0xDCA3, 0x9680}, //8859 #CJK UNIFIED IDEOGRAPH + {0xDCA4, 0x96C2}, //8860 #CJK UNIFIED IDEOGRAPH + {0xDCA5, 0x96C8}, //8861 #CJK UNIFIED IDEOGRAPH + {0xDCA6, 0x96C3}, //8862 #CJK UNIFIED IDEOGRAPH + {0xDCA7, 0x96F1}, //8863 #CJK UNIFIED IDEOGRAPH + {0xDCA8, 0x96F0}, //8864 #CJK UNIFIED IDEOGRAPH + {0xDCA9, 0x976C}, //8865 #CJK UNIFIED IDEOGRAPH + {0xDCAA, 0x9770}, //8866 #CJK UNIFIED IDEOGRAPH + {0xDCAB, 0x976E}, //8867 #CJK UNIFIED IDEOGRAPH + {0xDCAC, 0x9807}, //8868 #CJK UNIFIED IDEOGRAPH + {0xDCAD, 0x98A9}, //8869 #CJK UNIFIED IDEOGRAPH + {0xDCAE, 0x98EB}, //8870 #CJK UNIFIED IDEOGRAPH + {0xDCAF, 0x9CE6}, //8871 #CJK UNIFIED IDEOGRAPH + {0xDCB0, 0x9EF9}, //8872 #CJK UNIFIED IDEOGRAPH + {0xDCB1, 0x4E83}, //8873 #CJK UNIFIED IDEOGRAPH + {0xDCB2, 0x4E84}, //8874 #CJK UNIFIED IDEOGRAPH + {0xDCB3, 0x4EB6}, //8875 #CJK UNIFIED IDEOGRAPH + {0xDCB4, 0x50BD}, //8876 #CJK UNIFIED IDEOGRAPH + {0xDCB5, 0x50BF}, //8877 #CJK UNIFIED IDEOGRAPH + {0xDCB6, 0x50C6}, //8878 #CJK UNIFIED IDEOGRAPH + {0xDCB7, 0x50AE}, //8879 #CJK UNIFIED IDEOGRAPH + {0xDCB8, 0x50C4}, //8880 #CJK UNIFIED IDEOGRAPH + {0xDCB9, 0x50CA}, //8881 #CJK UNIFIED IDEOGRAPH + {0xDCBA, 0x50B4}, //8882 #CJK UNIFIED IDEOGRAPH + {0xDCBB, 0x50C8}, //8883 #CJK UNIFIED IDEOGRAPH + {0xDCBC, 0x50C2}, //8884 #CJK UNIFIED IDEOGRAPH + {0xDCBD, 0x50B0}, //8885 #CJK UNIFIED IDEOGRAPH + {0xDCBE, 0x50C1}, //8886 #CJK UNIFIED IDEOGRAPH + {0xDCBF, 0x50BA}, //8887 #CJK UNIFIED IDEOGRAPH + {0xDCC0, 0x50B1}, //8888 #CJK UNIFIED IDEOGRAPH + {0xDCC1, 0x50CB}, //8889 #CJK UNIFIED IDEOGRAPH + {0xDCC2, 0x50C9}, //8890 #CJK UNIFIED IDEOGRAPH + {0xDCC3, 0x50B6}, //8891 #CJK UNIFIED IDEOGRAPH + {0xDCC4, 0x50B8}, //8892 #CJK UNIFIED IDEOGRAPH + {0xDCC5, 0x51D7}, //8893 #CJK UNIFIED IDEOGRAPH + {0xDCC6, 0x527A}, //8894 #CJK UNIFIED IDEOGRAPH + {0xDCC7, 0x5278}, //8895 #CJK UNIFIED IDEOGRAPH + {0xDCC8, 0x527B}, //8896 #CJK UNIFIED IDEOGRAPH + {0xDCC9, 0x527C}, //8897 #CJK UNIFIED IDEOGRAPH + {0xDCCA, 0x55C3}, //8898 #CJK UNIFIED IDEOGRAPH + {0xDCCB, 0x55DB}, //8899 #CJK UNIFIED IDEOGRAPH + {0xDCCC, 0x55CC}, //8900 #CJK UNIFIED IDEOGRAPH + {0xDCCD, 0x55D0}, //8901 #CJK UNIFIED IDEOGRAPH + {0xDCCE, 0x55CB}, //8902 #CJK UNIFIED IDEOGRAPH + {0xDCCF, 0x55CA}, //8903 #CJK UNIFIED IDEOGRAPH + {0xDCD0, 0x55DD}, //8904 #CJK UNIFIED IDEOGRAPH + {0xDCD1, 0x55C0}, //8905 #CJK UNIFIED IDEOGRAPH + {0xDCD2, 0x55D4}, //8906 #CJK UNIFIED IDEOGRAPH + {0xDCD3, 0x55C4}, //8907 #CJK UNIFIED IDEOGRAPH + {0xDCD4, 0x55E9}, //8908 #CJK UNIFIED IDEOGRAPH + {0xDCD5, 0x55BF}, //8909 #CJK UNIFIED IDEOGRAPH + {0xDCD6, 0x55D2}, //8910 #CJK UNIFIED IDEOGRAPH + {0xDCD7, 0x558D}, //8911 #CJK UNIFIED IDEOGRAPH + {0xDCD8, 0x55CF}, //8912 #CJK UNIFIED IDEOGRAPH + {0xDCD9, 0x55D5}, //8913 #CJK UNIFIED IDEOGRAPH + {0xDCDA, 0x55E2}, //8914 #CJK UNIFIED IDEOGRAPH + {0xDCDB, 0x55D6}, //8915 #CJK UNIFIED IDEOGRAPH + {0xDCDC, 0x55C8}, //8916 #CJK UNIFIED IDEOGRAPH + {0xDCDD, 0x55F2}, //8917 #CJK UNIFIED IDEOGRAPH + {0xDCDE, 0x55CD}, //8918 #CJK UNIFIED IDEOGRAPH + {0xDCDF, 0x55D9}, //8919 #CJK UNIFIED IDEOGRAPH + {0xDCE0, 0x55C2}, //8920 #CJK UNIFIED IDEOGRAPH + {0xDCE1, 0x5714}, //8921 #CJK UNIFIED IDEOGRAPH + {0xDCE2, 0x5853}, //8922 #CJK UNIFIED IDEOGRAPH + {0xDCE3, 0x5868}, //8923 #CJK UNIFIED IDEOGRAPH + {0xDCE4, 0x5864}, //8924 #CJK UNIFIED IDEOGRAPH + {0xDCE5, 0x584F}, //8925 #CJK UNIFIED IDEOGRAPH + {0xDCE6, 0x584D}, //8926 #CJK UNIFIED IDEOGRAPH + {0xDCE7, 0x5849}, //8927 #CJK UNIFIED IDEOGRAPH + {0xDCE8, 0x586F}, //8928 #CJK UNIFIED IDEOGRAPH + {0xDCE9, 0x5855}, //8929 #CJK UNIFIED IDEOGRAPH + {0xDCEA, 0x584E}, //8930 #CJK UNIFIED IDEOGRAPH + {0xDCEB, 0x585D}, //8931 #CJK UNIFIED IDEOGRAPH + {0xDCEC, 0x5859}, //8932 #CJK UNIFIED IDEOGRAPH + {0xDCED, 0x5865}, //8933 #CJK UNIFIED IDEOGRAPH + {0xDCEE, 0x585B}, //8934 #CJK UNIFIED IDEOGRAPH + {0xDCEF, 0x583D}, //8935 #CJK UNIFIED IDEOGRAPH + {0xDCF0, 0x5863}, //8936 #CJK UNIFIED IDEOGRAPH + {0xDCF1, 0x5871}, //8937 #CJK UNIFIED IDEOGRAPH + {0xDCF2, 0x58FC}, //8938 #CJK UNIFIED IDEOGRAPH + {0xDCF3, 0x5AC7}, //8939 #CJK UNIFIED IDEOGRAPH + {0xDCF4, 0x5AC4}, //8940 #CJK UNIFIED IDEOGRAPH + {0xDCF5, 0x5ACB}, //8941 #CJK UNIFIED IDEOGRAPH + {0xDCF6, 0x5ABA}, //8942 #CJK UNIFIED IDEOGRAPH + {0xDCF7, 0x5AB8}, //8943 #CJK UNIFIED IDEOGRAPH + {0xDCF8, 0x5AB1}, //8944 #CJK UNIFIED IDEOGRAPH + {0xDCF9, 0x5AB5}, //8945 #CJK UNIFIED IDEOGRAPH + {0xDCFA, 0x5AB0}, //8946 #CJK UNIFIED IDEOGRAPH + {0xDCFB, 0x5ABF}, //8947 #CJK UNIFIED IDEOGRAPH + {0xDCFC, 0x5AC8}, //8948 #CJK UNIFIED IDEOGRAPH + {0xDCFD, 0x5ABB}, //8949 #CJK UNIFIED IDEOGRAPH + {0xDCFE, 0x5AC6}, //8950 #CJK UNIFIED IDEOGRAPH + {0xDD40, 0x5AB7}, //8951 #CJK UNIFIED IDEOGRAPH + {0xDD41, 0x5AC0}, //8952 #CJK UNIFIED IDEOGRAPH + {0xDD42, 0x5ACA}, //8953 #CJK UNIFIED IDEOGRAPH + {0xDD43, 0x5AB4}, //8954 #CJK UNIFIED IDEOGRAPH + {0xDD44, 0x5AB6}, //8955 #CJK UNIFIED IDEOGRAPH + {0xDD45, 0x5ACD}, //8956 #CJK UNIFIED IDEOGRAPH + {0xDD46, 0x5AB9}, //8957 #CJK UNIFIED IDEOGRAPH + {0xDD47, 0x5A90}, //8958 #CJK UNIFIED IDEOGRAPH + {0xDD48, 0x5BD6}, //8959 #CJK UNIFIED IDEOGRAPH + {0xDD49, 0x5BD8}, //8960 #CJK UNIFIED IDEOGRAPH + {0xDD4A, 0x5BD9}, //8961 #CJK UNIFIED IDEOGRAPH + {0xDD4B, 0x5C1F}, //8962 #CJK UNIFIED IDEOGRAPH + {0xDD4C, 0x5C33}, //8963 #CJK UNIFIED IDEOGRAPH + {0xDD4D, 0x5D71}, //8964 #CJK UNIFIED IDEOGRAPH + {0xDD4E, 0x5D63}, //8965 #CJK UNIFIED IDEOGRAPH + {0xDD4F, 0x5D4A}, //8966 #CJK UNIFIED IDEOGRAPH + {0xDD50, 0x5D65}, //8967 #CJK UNIFIED IDEOGRAPH + {0xDD51, 0x5D72}, //8968 #CJK UNIFIED IDEOGRAPH + {0xDD52, 0x5D6C}, //8969 #CJK UNIFIED IDEOGRAPH + {0xDD53, 0x5D5E}, //8970 #CJK UNIFIED IDEOGRAPH + {0xDD54, 0x5D68}, //8971 #CJK UNIFIED IDEOGRAPH + {0xDD55, 0x5D67}, //8972 #CJK UNIFIED IDEOGRAPH + {0xDD56, 0x5D62}, //8973 #CJK UNIFIED IDEOGRAPH + {0xDD57, 0x5DF0}, //8974 #CJK UNIFIED IDEOGRAPH + {0xDD58, 0x5E4F}, //8975 #CJK UNIFIED IDEOGRAPH + {0xDD59, 0x5E4E}, //8976 #CJK UNIFIED IDEOGRAPH + {0xDD5A, 0x5E4A}, //8977 #CJK UNIFIED IDEOGRAPH + {0xDD5B, 0x5E4D}, //8978 #CJK UNIFIED IDEOGRAPH + {0xDD5C, 0x5E4B}, //8979 #CJK UNIFIED IDEOGRAPH + {0xDD5D, 0x5EC5}, //8980 #CJK UNIFIED IDEOGRAPH + {0xDD5E, 0x5ECC}, //8981 #CJK UNIFIED IDEOGRAPH + {0xDD5F, 0x5EC6}, //8982 #CJK UNIFIED IDEOGRAPH + {0xDD60, 0x5ECB}, //8983 #CJK UNIFIED IDEOGRAPH + {0xDD61, 0x5EC7}, //8984 #CJK UNIFIED IDEOGRAPH + {0xDD62, 0x5F40}, //8985 #CJK UNIFIED IDEOGRAPH + {0xDD63, 0x5FAF}, //8986 #CJK UNIFIED IDEOGRAPH + {0xDD64, 0x5FAD}, //8987 #CJK UNIFIED IDEOGRAPH + {0xDD65, 0x60F7}, //8988 #CJK UNIFIED IDEOGRAPH + {0xDD66, 0x6149}, //8989 #CJK UNIFIED IDEOGRAPH + {0xDD67, 0x614A}, //8990 #CJK UNIFIED IDEOGRAPH + {0xDD68, 0x612B}, //8991 #CJK UNIFIED IDEOGRAPH + {0xDD69, 0x6145}, //8992 #CJK UNIFIED IDEOGRAPH + {0xDD6A, 0x6136}, //8993 #CJK UNIFIED IDEOGRAPH + {0xDD6B, 0x6132}, //8994 #CJK UNIFIED IDEOGRAPH + {0xDD6C, 0x612E}, //8995 #CJK UNIFIED IDEOGRAPH + {0xDD6D, 0x6146}, //8996 #CJK UNIFIED IDEOGRAPH + {0xDD6E, 0x612F}, //8997 #CJK UNIFIED IDEOGRAPH + {0xDD6F, 0x614F}, //8998 #CJK UNIFIED IDEOGRAPH + {0xDD70, 0x6129}, //8999 #CJK UNIFIED IDEOGRAPH + {0xDD71, 0x6140}, //9000 #CJK UNIFIED IDEOGRAPH + {0xDD72, 0x6220}, //9001 #CJK UNIFIED IDEOGRAPH + {0xDD73, 0x9168}, //9002 #CJK UNIFIED IDEOGRAPH + {0xDD74, 0x6223}, //9003 #CJK UNIFIED IDEOGRAPH + {0xDD75, 0x6225}, //9004 #CJK UNIFIED IDEOGRAPH + {0xDD76, 0x6224}, //9005 #CJK UNIFIED IDEOGRAPH + {0xDD77, 0x63C5}, //9006 #CJK UNIFIED IDEOGRAPH + {0xDD78, 0x63F1}, //9007 #CJK UNIFIED IDEOGRAPH + {0xDD79, 0x63EB}, //9008 #CJK UNIFIED IDEOGRAPH + {0xDD7A, 0x6410}, //9009 #CJK UNIFIED IDEOGRAPH + {0xDD7B, 0x6412}, //9010 #CJK UNIFIED IDEOGRAPH + {0xDD7C, 0x6409}, //9011 #CJK UNIFIED IDEOGRAPH + {0xDD7D, 0x6420}, //9012 #CJK UNIFIED IDEOGRAPH + {0xDD7E, 0x6424}, //9013 #CJK UNIFIED IDEOGRAPH + {0xDDA1, 0x6433}, //9014 #CJK UNIFIED IDEOGRAPH + {0xDDA2, 0x6443}, //9015 #CJK UNIFIED IDEOGRAPH + {0xDDA3, 0x641F}, //9016 #CJK UNIFIED IDEOGRAPH + {0xDDA4, 0x6415}, //9017 #CJK UNIFIED IDEOGRAPH + {0xDDA5, 0x6418}, //9018 #CJK UNIFIED IDEOGRAPH + {0xDDA6, 0x6439}, //9019 #CJK UNIFIED IDEOGRAPH + {0xDDA7, 0x6437}, //9020 #CJK UNIFIED IDEOGRAPH + {0xDDA8, 0x6422}, //9021 #CJK UNIFIED IDEOGRAPH + {0xDDA9, 0x6423}, //9022 #CJK UNIFIED IDEOGRAPH + {0xDDAA, 0x640C}, //9023 #CJK UNIFIED IDEOGRAPH + {0xDDAB, 0x6426}, //9024 #CJK UNIFIED IDEOGRAPH + {0xDDAC, 0x6430}, //9025 #CJK UNIFIED IDEOGRAPH + {0xDDAD, 0x6428}, //9026 #CJK UNIFIED IDEOGRAPH + {0xDDAE, 0x6441}, //9027 #CJK UNIFIED IDEOGRAPH + {0xDDAF, 0x6435}, //9028 #CJK UNIFIED IDEOGRAPH + {0xDDB0, 0x642F}, //9029 #CJK UNIFIED IDEOGRAPH + {0xDDB1, 0x640A}, //9030 #CJK UNIFIED IDEOGRAPH + {0xDDB2, 0x641A}, //9031 #CJK UNIFIED IDEOGRAPH + {0xDDB3, 0x6440}, //9032 #CJK UNIFIED IDEOGRAPH + {0xDDB4, 0x6425}, //9033 #CJK UNIFIED IDEOGRAPH + {0xDDB5, 0x6427}, //9034 #CJK UNIFIED IDEOGRAPH + {0xDDB6, 0x640B}, //9035 #CJK UNIFIED IDEOGRAPH + {0xDDB7, 0x63E7}, //9036 #CJK UNIFIED IDEOGRAPH + {0xDDB8, 0x641B}, //9037 #CJK UNIFIED IDEOGRAPH + {0xDDB9, 0x642E}, //9038 #CJK UNIFIED IDEOGRAPH + {0xDDBA, 0x6421}, //9039 #CJK UNIFIED IDEOGRAPH + {0xDDBB, 0x640E}, //9040 #CJK UNIFIED IDEOGRAPH + {0xDDBC, 0x656F}, //9041 #CJK UNIFIED IDEOGRAPH + {0xDDBD, 0x6592}, //9042 #CJK UNIFIED IDEOGRAPH + {0xDDBE, 0x65D3}, //9043 #CJK UNIFIED IDEOGRAPH + {0xDDBF, 0x6686}, //9044 #CJK UNIFIED IDEOGRAPH + {0xDDC0, 0x668C}, //9045 #CJK UNIFIED IDEOGRAPH + {0xDDC1, 0x6695}, //9046 #CJK UNIFIED IDEOGRAPH + {0xDDC2, 0x6690}, //9047 #CJK UNIFIED IDEOGRAPH + {0xDDC3, 0x668B}, //9048 #CJK UNIFIED IDEOGRAPH + {0xDDC4, 0x668A}, //9049 #CJK UNIFIED IDEOGRAPH + {0xDDC5, 0x6699}, //9050 #CJK UNIFIED IDEOGRAPH + {0xDDC6, 0x6694}, //9051 #CJK UNIFIED IDEOGRAPH + {0xDDC7, 0x6678}, //9052 #CJK UNIFIED IDEOGRAPH + {0xDDC8, 0x6720}, //9053 #CJK UNIFIED IDEOGRAPH + {0xDDC9, 0x6966}, //9054 #CJK UNIFIED IDEOGRAPH + {0xDDCA, 0x695F}, //9055 #CJK UNIFIED IDEOGRAPH + {0xDDCB, 0x6938}, //9056 #CJK UNIFIED IDEOGRAPH + {0xDDCC, 0x694E}, //9057 #CJK UNIFIED IDEOGRAPH + {0xDDCD, 0x6962}, //9058 #CJK UNIFIED IDEOGRAPH + {0xDDCE, 0x6971}, //9059 #CJK UNIFIED IDEOGRAPH + {0xDDCF, 0x693F}, //9060 #CJK UNIFIED IDEOGRAPH + {0xDDD0, 0x6945}, //9061 #CJK UNIFIED IDEOGRAPH + {0xDDD1, 0x696A}, //9062 #CJK UNIFIED IDEOGRAPH + {0xDDD2, 0x6939}, //9063 #CJK UNIFIED IDEOGRAPH + {0xDDD3, 0x6942}, //9064 #CJK UNIFIED IDEOGRAPH + {0xDDD4, 0x6957}, //9065 #CJK UNIFIED IDEOGRAPH + {0xDDD5, 0x6959}, //9066 #CJK UNIFIED IDEOGRAPH + {0xDDD6, 0x697A}, //9067 #CJK UNIFIED IDEOGRAPH + {0xDDD7, 0x6948}, //9068 #CJK UNIFIED IDEOGRAPH + {0xDDD8, 0x6949}, //9069 #CJK UNIFIED IDEOGRAPH + {0xDDD9, 0x6935}, //9070 #CJK UNIFIED IDEOGRAPH + {0xDDDA, 0x696C}, //9071 #CJK UNIFIED IDEOGRAPH + {0xDDDB, 0x6933}, //9072 #CJK UNIFIED IDEOGRAPH + {0xDDDC, 0x693D}, //9073 #CJK UNIFIED IDEOGRAPH + {0xDDDD, 0x6965}, //9074 #CJK UNIFIED IDEOGRAPH + {0xDDDE, 0x68F0}, //9075 #CJK UNIFIED IDEOGRAPH + {0xDDDF, 0x6978}, //9076 #CJK UNIFIED IDEOGRAPH + {0xDDE0, 0x6934}, //9077 #CJK UNIFIED IDEOGRAPH + {0xDDE1, 0x6969}, //9078 #CJK UNIFIED IDEOGRAPH + {0xDDE2, 0x6940}, //9079 #CJK UNIFIED IDEOGRAPH + {0xDDE3, 0x696F}, //9080 #CJK UNIFIED IDEOGRAPH + {0xDDE4, 0x6944}, //9081 #CJK UNIFIED IDEOGRAPH + {0xDDE5, 0x6976}, //9082 #CJK UNIFIED IDEOGRAPH + {0xDDE6, 0x6958}, //9083 #CJK UNIFIED IDEOGRAPH + {0xDDE7, 0x6941}, //9084 #CJK UNIFIED IDEOGRAPH + {0xDDE8, 0x6974}, //9085 #CJK UNIFIED IDEOGRAPH + {0xDDE9, 0x694C}, //9086 #CJK UNIFIED IDEOGRAPH + {0xDDEA, 0x693B}, //9087 #CJK UNIFIED IDEOGRAPH + {0xDDEB, 0x694B}, //9088 #CJK UNIFIED IDEOGRAPH + {0xDDEC, 0x6937}, //9089 #CJK UNIFIED IDEOGRAPH + {0xDDED, 0x695C}, //9090 #CJK UNIFIED IDEOGRAPH + {0xDDEE, 0x694F}, //9091 #CJK UNIFIED IDEOGRAPH + {0xDDEF, 0x6951}, //9092 #CJK UNIFIED IDEOGRAPH + {0xDDF0, 0x6932}, //9093 #CJK UNIFIED IDEOGRAPH + {0xDDF1, 0x6952}, //9094 #CJK UNIFIED IDEOGRAPH + {0xDDF2, 0x692F}, //9095 #CJK UNIFIED IDEOGRAPH + {0xDDF3, 0x697B}, //9096 #CJK UNIFIED IDEOGRAPH + {0xDDF4, 0x693C}, //9097 #CJK UNIFIED IDEOGRAPH + {0xDDF5, 0x6B46}, //9098 #CJK UNIFIED IDEOGRAPH + {0xDDF6, 0x6B45}, //9099 #CJK UNIFIED IDEOGRAPH + {0xDDF7, 0x6B43}, //9100 #CJK UNIFIED IDEOGRAPH + {0xDDF8, 0x6B42}, //9101 #CJK UNIFIED IDEOGRAPH + {0xDDF9, 0x6B48}, //9102 #CJK UNIFIED IDEOGRAPH + {0xDDFA, 0x6B41}, //9103 #CJK UNIFIED IDEOGRAPH + {0xDDFB, 0x6B9B}, //9104 #CJK UNIFIED IDEOGRAPH + {0xDDFC, 0xFA0D}, //9105 #CJK COMPATIBILITY IDEOGRAPH + {0xDDFD, 0x6BFB}, //9106 #CJK UNIFIED IDEOGRAPH + {0xDDFE, 0x6BFC}, //9107 #CJK UNIFIED IDEOGRAPH + {0xDE40, 0x6BF9}, //9108 #CJK UNIFIED IDEOGRAPH + {0xDE41, 0x6BF7}, //9109 #CJK UNIFIED IDEOGRAPH + {0xDE42, 0x6BF8}, //9110 #CJK UNIFIED IDEOGRAPH + {0xDE43, 0x6E9B}, //9111 #CJK UNIFIED IDEOGRAPH + {0xDE44, 0x6ED6}, //9112 #CJK UNIFIED IDEOGRAPH + {0xDE45, 0x6EC8}, //9113 #CJK UNIFIED IDEOGRAPH + {0xDE46, 0x6E8F}, //9114 #CJK UNIFIED IDEOGRAPH + {0xDE47, 0x6EC0}, //9115 #CJK UNIFIED IDEOGRAPH + {0xDE48, 0x6E9F}, //9116 #CJK UNIFIED IDEOGRAPH + {0xDE49, 0x6E93}, //9117 #CJK UNIFIED IDEOGRAPH + {0xDE4A, 0x6E94}, //9118 #CJK UNIFIED IDEOGRAPH + {0xDE4B, 0x6EA0}, //9119 #CJK UNIFIED IDEOGRAPH + {0xDE4C, 0x6EB1}, //9120 #CJK UNIFIED IDEOGRAPH + {0xDE4D, 0x6EB9}, //9121 #CJK UNIFIED IDEOGRAPH + {0xDE4E, 0x6EC6}, //9122 #CJK UNIFIED IDEOGRAPH + {0xDE4F, 0x6ED2}, //9123 #CJK UNIFIED IDEOGRAPH + {0xDE50, 0x6EBD}, //9124 #CJK UNIFIED IDEOGRAPH + {0xDE51, 0x6EC1}, //9125 #CJK UNIFIED IDEOGRAPH + {0xDE52, 0x6E9E}, //9126 #CJK UNIFIED IDEOGRAPH + {0xDE53, 0x6EC9}, //9127 #CJK UNIFIED IDEOGRAPH + {0xDE54, 0x6EB7}, //9128 #CJK UNIFIED IDEOGRAPH + {0xDE55, 0x6EB0}, //9129 #CJK UNIFIED IDEOGRAPH + {0xDE56, 0x6ECD}, //9130 #CJK UNIFIED IDEOGRAPH + {0xDE57, 0x6EA6}, //9131 #CJK UNIFIED IDEOGRAPH + {0xDE58, 0x6ECF}, //9132 #CJK UNIFIED IDEOGRAPH + {0xDE59, 0x6EB2}, //9133 #CJK UNIFIED IDEOGRAPH + {0xDE5A, 0x6EBE}, //9134 #CJK UNIFIED IDEOGRAPH + {0xDE5B, 0x6EC3}, //9135 #CJK UNIFIED IDEOGRAPH + {0xDE5C, 0x6EDC}, //9136 #CJK UNIFIED IDEOGRAPH + {0xDE5D, 0x6ED8}, //9137 #CJK UNIFIED IDEOGRAPH + {0xDE5E, 0x6E99}, //9138 #CJK UNIFIED IDEOGRAPH + {0xDE5F, 0x6E92}, //9139 #CJK UNIFIED IDEOGRAPH + {0xDE60, 0x6E8E}, //9140 #CJK UNIFIED IDEOGRAPH + {0xDE61, 0x6E8D}, //9141 #CJK UNIFIED IDEOGRAPH + {0xDE62, 0x6EA4}, //9142 #CJK UNIFIED IDEOGRAPH + {0xDE63, 0x6EA1}, //9143 #CJK UNIFIED IDEOGRAPH + {0xDE64, 0x6EBF}, //9144 #CJK UNIFIED IDEOGRAPH + {0xDE65, 0x6EB3}, //9145 #CJK UNIFIED IDEOGRAPH + {0xDE66, 0x6ED0}, //9146 #CJK UNIFIED IDEOGRAPH + {0xDE67, 0x6ECA}, //9147 #CJK UNIFIED IDEOGRAPH + {0xDE68, 0x6E97}, //9148 #CJK UNIFIED IDEOGRAPH + {0xDE69, 0x6EAE}, //9149 #CJK UNIFIED IDEOGRAPH + {0xDE6A, 0x6EA3}, //9150 #CJK UNIFIED IDEOGRAPH + {0xDE6B, 0x7147}, //9151 #CJK UNIFIED IDEOGRAPH + {0xDE6C, 0x7154}, //9152 #CJK UNIFIED IDEOGRAPH + {0xDE6D, 0x7152}, //9153 #CJK UNIFIED IDEOGRAPH + {0xDE6E, 0x7163}, //9154 #CJK UNIFIED IDEOGRAPH + {0xDE6F, 0x7160}, //9155 #CJK UNIFIED IDEOGRAPH + {0xDE70, 0x7141}, //9156 #CJK UNIFIED IDEOGRAPH + {0xDE71, 0x715D}, //9157 #CJK UNIFIED IDEOGRAPH + {0xDE72, 0x7162}, //9158 #CJK UNIFIED IDEOGRAPH + {0xDE73, 0x7172}, //9159 #CJK UNIFIED IDEOGRAPH + {0xDE74, 0x7178}, //9160 #CJK UNIFIED IDEOGRAPH + {0xDE75, 0x716A}, //9161 #CJK UNIFIED IDEOGRAPH + {0xDE76, 0x7161}, //9162 #CJK UNIFIED IDEOGRAPH + {0xDE77, 0x7142}, //9163 #CJK UNIFIED IDEOGRAPH + {0xDE78, 0x7158}, //9164 #CJK UNIFIED IDEOGRAPH + {0xDE79, 0x7143}, //9165 #CJK UNIFIED IDEOGRAPH + {0xDE7A, 0x714B}, //9166 #CJK UNIFIED IDEOGRAPH + {0xDE7B, 0x7170}, //9167 #CJK UNIFIED IDEOGRAPH + {0xDE7C, 0x715F}, //9168 #CJK UNIFIED IDEOGRAPH + {0xDE7D, 0x7150}, //9169 #CJK UNIFIED IDEOGRAPH + {0xDE7E, 0x7153}, //9170 #CJK UNIFIED IDEOGRAPH + {0xDEA1, 0x7144}, //9171 #CJK UNIFIED IDEOGRAPH + {0xDEA2, 0x714D}, //9172 #CJK UNIFIED IDEOGRAPH + {0xDEA3, 0x715A}, //9173 #CJK UNIFIED IDEOGRAPH + {0xDEA4, 0x724F}, //9174 #CJK UNIFIED IDEOGRAPH + {0xDEA5, 0x728D}, //9175 #CJK UNIFIED IDEOGRAPH + {0xDEA6, 0x728C}, //9176 #CJK UNIFIED IDEOGRAPH + {0xDEA7, 0x7291}, //9177 #CJK UNIFIED IDEOGRAPH + {0xDEA8, 0x7290}, //9178 #CJK UNIFIED IDEOGRAPH + {0xDEA9, 0x728E}, //9179 #CJK UNIFIED IDEOGRAPH + {0xDEAA, 0x733C}, //9180 #CJK UNIFIED IDEOGRAPH + {0xDEAB, 0x7342}, //9181 #CJK UNIFIED IDEOGRAPH + {0xDEAC, 0x733B}, //9182 #CJK UNIFIED IDEOGRAPH + {0xDEAD, 0x733A}, //9183 #CJK UNIFIED IDEOGRAPH + {0xDEAE, 0x7340}, //9184 #CJK UNIFIED IDEOGRAPH + {0xDEAF, 0x734A}, //9185 #CJK UNIFIED IDEOGRAPH + {0xDEB0, 0x7349}, //9186 #CJK UNIFIED IDEOGRAPH + {0xDEB1, 0x7444}, //9187 #CJK UNIFIED IDEOGRAPH + {0xDEB2, 0x744A}, //9188 #CJK UNIFIED IDEOGRAPH + {0xDEB3, 0x744B}, //9189 #CJK UNIFIED IDEOGRAPH + {0xDEB4, 0x7452}, //9190 #CJK UNIFIED IDEOGRAPH + {0xDEB5, 0x7451}, //9191 #CJK UNIFIED IDEOGRAPH + {0xDEB6, 0x7457}, //9192 #CJK UNIFIED IDEOGRAPH + {0xDEB7, 0x7440}, //9193 #CJK UNIFIED IDEOGRAPH + {0xDEB8, 0x744F}, //9194 #CJK UNIFIED IDEOGRAPH + {0xDEB9, 0x7450}, //9195 #CJK UNIFIED IDEOGRAPH + {0xDEBA, 0x744E}, //9196 #CJK UNIFIED IDEOGRAPH + {0xDEBB, 0x7442}, //9197 #CJK UNIFIED IDEOGRAPH + {0xDEBC, 0x7446}, //9198 #CJK UNIFIED IDEOGRAPH + {0xDEBD, 0x744D}, //9199 #CJK UNIFIED IDEOGRAPH + {0xDEBE, 0x7454}, //9200 #CJK UNIFIED IDEOGRAPH + {0xDEBF, 0x74E1}, //9201 #CJK UNIFIED IDEOGRAPH + {0xDEC0, 0x74FF}, //9202 #CJK UNIFIED IDEOGRAPH + {0xDEC1, 0x74FE}, //9203 #CJK UNIFIED IDEOGRAPH + {0xDEC2, 0x74FD}, //9204 #CJK UNIFIED IDEOGRAPH + {0xDEC3, 0x751D}, //9205 #CJK UNIFIED IDEOGRAPH + {0xDEC4, 0x7579}, //9206 #CJK UNIFIED IDEOGRAPH + {0xDEC5, 0x7577}, //9207 #CJK UNIFIED IDEOGRAPH + {0xDEC6, 0x6983}, //9208 #CJK UNIFIED IDEOGRAPH + {0xDEC7, 0x75EF}, //9209 #CJK UNIFIED IDEOGRAPH + {0xDEC8, 0x760F}, //9210 #CJK UNIFIED IDEOGRAPH + {0xDEC9, 0x7603}, //9211 #CJK UNIFIED IDEOGRAPH + {0xDECA, 0x75F7}, //9212 #CJK UNIFIED IDEOGRAPH + {0xDECB, 0x75FE}, //9213 #CJK UNIFIED IDEOGRAPH + {0xDECC, 0x75FC}, //9214 #CJK UNIFIED IDEOGRAPH + {0xDECD, 0x75F9}, //9215 #CJK UNIFIED IDEOGRAPH + {0xDECE, 0x75F8}, //9216 #CJK UNIFIED IDEOGRAPH + {0xDECF, 0x7610}, //9217 #CJK UNIFIED IDEOGRAPH + {0xDED0, 0x75FB}, //9218 #CJK UNIFIED IDEOGRAPH + {0xDED1, 0x75F6}, //9219 #CJK UNIFIED IDEOGRAPH + {0xDED2, 0x75ED}, //9220 #CJK UNIFIED IDEOGRAPH + {0xDED3, 0x75F5}, //9221 #CJK UNIFIED IDEOGRAPH + {0xDED4, 0x75FD}, //9222 #CJK UNIFIED IDEOGRAPH + {0xDED5, 0x7699}, //9223 #CJK UNIFIED IDEOGRAPH + {0xDED6, 0x76B5}, //9224 #CJK UNIFIED IDEOGRAPH + {0xDED7, 0x76DD}, //9225 #CJK UNIFIED IDEOGRAPH + {0xDED8, 0x7755}, //9226 #CJK UNIFIED IDEOGRAPH + {0xDED9, 0x775F}, //9227 #CJK UNIFIED IDEOGRAPH + {0xDEDA, 0x7760}, //9228 #CJK UNIFIED IDEOGRAPH + {0xDEDB, 0x7752}, //9229 #CJK UNIFIED IDEOGRAPH + {0xDEDC, 0x7756}, //9230 #CJK UNIFIED IDEOGRAPH + {0xDEDD, 0x775A}, //9231 #CJK UNIFIED IDEOGRAPH + {0xDEDE, 0x7769}, //9232 #CJK UNIFIED IDEOGRAPH + {0xDEDF, 0x7767}, //9233 #CJK UNIFIED IDEOGRAPH + {0xDEE0, 0x7754}, //9234 #CJK UNIFIED IDEOGRAPH + {0xDEE1, 0x7759}, //9235 #CJK UNIFIED IDEOGRAPH + {0xDEE2, 0x776D}, //9236 #CJK UNIFIED IDEOGRAPH + {0xDEE3, 0x77E0}, //9237 #CJK UNIFIED IDEOGRAPH + {0xDEE4, 0x7887}, //9238 #CJK UNIFIED IDEOGRAPH + {0xDEE5, 0x789A}, //9239 #CJK UNIFIED IDEOGRAPH + {0xDEE6, 0x7894}, //9240 #CJK UNIFIED IDEOGRAPH + {0xDEE7, 0x788F}, //9241 #CJK UNIFIED IDEOGRAPH + {0xDEE8, 0x7884}, //9242 #CJK UNIFIED IDEOGRAPH + {0xDEE9, 0x7895}, //9243 #CJK UNIFIED IDEOGRAPH + {0xDEEA, 0x7885}, //9244 #CJK UNIFIED IDEOGRAPH + {0xDEEB, 0x7886}, //9245 #CJK UNIFIED IDEOGRAPH + {0xDEEC, 0x78A1}, //9246 #CJK UNIFIED IDEOGRAPH + {0xDEED, 0x7883}, //9247 #CJK UNIFIED IDEOGRAPH + {0xDEEE, 0x7879}, //9248 #CJK UNIFIED IDEOGRAPH + {0xDEEF, 0x7899}, //9249 #CJK UNIFIED IDEOGRAPH + {0xDEF0, 0x7880}, //9250 #CJK UNIFIED IDEOGRAPH + {0xDEF1, 0x7896}, //9251 #CJK UNIFIED IDEOGRAPH + {0xDEF2, 0x787B}, //9252 #CJK UNIFIED IDEOGRAPH + {0xDEF3, 0x797C}, //9253 #CJK UNIFIED IDEOGRAPH + {0xDEF4, 0x7982}, //9254 #CJK UNIFIED IDEOGRAPH + {0xDEF5, 0x797D}, //9255 #CJK UNIFIED IDEOGRAPH + {0xDEF6, 0x7979}, //9256 #CJK UNIFIED IDEOGRAPH + {0xDEF7, 0x7A11}, //9257 #CJK UNIFIED IDEOGRAPH + {0xDEF8, 0x7A18}, //9258 #CJK UNIFIED IDEOGRAPH + {0xDEF9, 0x7A19}, //9259 #CJK UNIFIED IDEOGRAPH + {0xDEFA, 0x7A12}, //9260 #CJK UNIFIED IDEOGRAPH + {0xDEFB, 0x7A17}, //9261 #CJK UNIFIED IDEOGRAPH + {0xDEFC, 0x7A15}, //9262 #CJK UNIFIED IDEOGRAPH + {0xDEFD, 0x7A22}, //9263 #CJK UNIFIED IDEOGRAPH + {0xDEFE, 0x7A13}, //9264 #CJK UNIFIED IDEOGRAPH + {0xDF40, 0x7A1B}, //9265 #CJK UNIFIED IDEOGRAPH + {0xDF41, 0x7A10}, //9266 #CJK UNIFIED IDEOGRAPH + {0xDF42, 0x7AA3}, //9267 #CJK UNIFIED IDEOGRAPH + {0xDF43, 0x7AA2}, //9268 #CJK UNIFIED IDEOGRAPH + {0xDF44, 0x7A9E}, //9269 #CJK UNIFIED IDEOGRAPH + {0xDF45, 0x7AEB}, //9270 #CJK UNIFIED IDEOGRAPH + {0xDF46, 0x7B66}, //9271 #CJK UNIFIED IDEOGRAPH + {0xDF47, 0x7B64}, //9272 #CJK UNIFIED IDEOGRAPH + {0xDF48, 0x7B6D}, //9273 #CJK UNIFIED IDEOGRAPH + {0xDF49, 0x7B74}, //9274 #CJK UNIFIED IDEOGRAPH + {0xDF4A, 0x7B69}, //9275 #CJK UNIFIED IDEOGRAPH + {0xDF4B, 0x7B72}, //9276 #CJK UNIFIED IDEOGRAPH + {0xDF4C, 0x7B65}, //9277 #CJK UNIFIED IDEOGRAPH + {0xDF4D, 0x7B73}, //9278 #CJK UNIFIED IDEOGRAPH + {0xDF4E, 0x7B71}, //9279 #CJK UNIFIED IDEOGRAPH + {0xDF4F, 0x7B70}, //9280 #CJK UNIFIED IDEOGRAPH + {0xDF50, 0x7B61}, //9281 #CJK UNIFIED IDEOGRAPH + {0xDF51, 0x7B78}, //9282 #CJK UNIFIED IDEOGRAPH + {0xDF52, 0x7B76}, //9283 #CJK UNIFIED IDEOGRAPH + {0xDF53, 0x7B63}, //9284 #CJK UNIFIED IDEOGRAPH + {0xDF54, 0x7CB2}, //9285 #CJK UNIFIED IDEOGRAPH + {0xDF55, 0x7CB4}, //9286 #CJK UNIFIED IDEOGRAPH + {0xDF56, 0x7CAF}, //9287 #CJK UNIFIED IDEOGRAPH + {0xDF57, 0x7D88}, //9288 #CJK UNIFIED IDEOGRAPH + {0xDF58, 0x7D86}, //9289 #CJK UNIFIED IDEOGRAPH + {0xDF59, 0x7D80}, //9290 #CJK UNIFIED IDEOGRAPH + {0xDF5A, 0x7D8D}, //9291 #CJK UNIFIED IDEOGRAPH + {0xDF5B, 0x7D7F}, //9292 #CJK UNIFIED IDEOGRAPH + {0xDF5C, 0x7D85}, //9293 #CJK UNIFIED IDEOGRAPH + {0xDF5D, 0x7D7A}, //9294 #CJK UNIFIED IDEOGRAPH + {0xDF5E, 0x7D8E}, //9295 #CJK UNIFIED IDEOGRAPH + {0xDF5F, 0x7D7B}, //9296 #CJK UNIFIED IDEOGRAPH + {0xDF60, 0x7D83}, //9297 #CJK UNIFIED IDEOGRAPH + {0xDF61, 0x7D7C}, //9298 #CJK UNIFIED IDEOGRAPH + {0xDF62, 0x7D8C}, //9299 #CJK UNIFIED IDEOGRAPH + {0xDF63, 0x7D94}, //9300 #CJK UNIFIED IDEOGRAPH + {0xDF64, 0x7D84}, //9301 #CJK UNIFIED IDEOGRAPH + {0xDF65, 0x7D7D}, //9302 #CJK UNIFIED IDEOGRAPH + {0xDF66, 0x7D92}, //9303 #CJK UNIFIED IDEOGRAPH + {0xDF67, 0x7F6D}, //9304 #CJK UNIFIED IDEOGRAPH + {0xDF68, 0x7F6B}, //9305 #CJK UNIFIED IDEOGRAPH + {0xDF69, 0x7F67}, //9306 #CJK UNIFIED IDEOGRAPH + {0xDF6A, 0x7F68}, //9307 #CJK UNIFIED IDEOGRAPH + {0xDF6B, 0x7F6C}, //9308 #CJK UNIFIED IDEOGRAPH + {0xDF6C, 0x7FA6}, //9309 #CJK UNIFIED IDEOGRAPH + {0xDF6D, 0x7FA5}, //9310 #CJK UNIFIED IDEOGRAPH + {0xDF6E, 0x7FA7}, //9311 #CJK UNIFIED IDEOGRAPH + {0xDF6F, 0x7FDB}, //9312 #CJK UNIFIED IDEOGRAPH + {0xDF70, 0x7FDC}, //9313 #CJK UNIFIED IDEOGRAPH + {0xDF71, 0x8021}, //9314 #CJK UNIFIED IDEOGRAPH + {0xDF72, 0x8164}, //9315 #CJK UNIFIED IDEOGRAPH + {0xDF73, 0x8160}, //9316 #CJK UNIFIED IDEOGRAPH + {0xDF74, 0x8177}, //9317 #CJK UNIFIED IDEOGRAPH + {0xDF75, 0x815C}, //9318 #CJK UNIFIED IDEOGRAPH + {0xDF76, 0x8169}, //9319 #CJK UNIFIED IDEOGRAPH + {0xDF77, 0x815B}, //9320 #CJK UNIFIED IDEOGRAPH + {0xDF78, 0x8162}, //9321 #CJK UNIFIED IDEOGRAPH + {0xDF79, 0x8172}, //9322 #CJK UNIFIED IDEOGRAPH + {0xDF7A, 0x6721}, //9323 #CJK UNIFIED IDEOGRAPH + {0xDF7B, 0x815E}, //9324 #CJK UNIFIED IDEOGRAPH + {0xDF7C, 0x8176}, //9325 #CJK UNIFIED IDEOGRAPH + {0xDF7D, 0x8167}, //9326 #CJK UNIFIED IDEOGRAPH + {0xDF7E, 0x816F}, //9327 #CJK UNIFIED IDEOGRAPH + {0xDFA1, 0x8144}, //9328 #CJK UNIFIED IDEOGRAPH + {0xDFA2, 0x8161}, //9329 #CJK UNIFIED IDEOGRAPH + {0xDFA3, 0x821D}, //9330 #CJK UNIFIED IDEOGRAPH + {0xDFA4, 0x8249}, //9331 #CJK UNIFIED IDEOGRAPH + {0xDFA5, 0x8244}, //9332 #CJK UNIFIED IDEOGRAPH + {0xDFA6, 0x8240}, //9333 #CJK UNIFIED IDEOGRAPH + {0xDFA7, 0x8242}, //9334 #CJK UNIFIED IDEOGRAPH + {0xDFA8, 0x8245}, //9335 #CJK UNIFIED IDEOGRAPH + {0xDFA9, 0x84F1}, //9336 #CJK UNIFIED IDEOGRAPH + {0xDFAA, 0x843F}, //9337 #CJK UNIFIED IDEOGRAPH + {0xDFAB, 0x8456}, //9338 #CJK UNIFIED IDEOGRAPH + {0xDFAC, 0x8476}, //9339 #CJK UNIFIED IDEOGRAPH + {0xDFAD, 0x8479}, //9340 #CJK UNIFIED IDEOGRAPH + {0xDFAE, 0x848F}, //9341 #CJK UNIFIED IDEOGRAPH + {0xDFAF, 0x848D}, //9342 #CJK UNIFIED IDEOGRAPH + {0xDFB0, 0x8465}, //9343 #CJK UNIFIED IDEOGRAPH + {0xDFB1, 0x8451}, //9344 #CJK UNIFIED IDEOGRAPH + {0xDFB2, 0x8440}, //9345 #CJK UNIFIED IDEOGRAPH + {0xDFB3, 0x8486}, //9346 #CJK UNIFIED IDEOGRAPH + {0xDFB4, 0x8467}, //9347 #CJK UNIFIED IDEOGRAPH + {0xDFB5, 0x8430}, //9348 #CJK UNIFIED IDEOGRAPH + {0xDFB6, 0x844D}, //9349 #CJK UNIFIED IDEOGRAPH + {0xDFB7, 0x847D}, //9350 #CJK UNIFIED IDEOGRAPH + {0xDFB8, 0x845A}, //9351 #CJK UNIFIED IDEOGRAPH + {0xDFB9, 0x8459}, //9352 #CJK UNIFIED IDEOGRAPH + {0xDFBA, 0x8474}, //9353 #CJK UNIFIED IDEOGRAPH + {0xDFBB, 0x8473}, //9354 #CJK UNIFIED IDEOGRAPH + {0xDFBC, 0x845D}, //9355 #CJK UNIFIED IDEOGRAPH + {0xDFBD, 0x8507}, //9356 #CJK UNIFIED IDEOGRAPH + {0xDFBE, 0x845E}, //9357 #CJK UNIFIED IDEOGRAPH + {0xDFBF, 0x8437}, //9358 #CJK UNIFIED IDEOGRAPH + {0xDFC0, 0x843A}, //9359 #CJK UNIFIED IDEOGRAPH + {0xDFC1, 0x8434}, //9360 #CJK UNIFIED IDEOGRAPH + {0xDFC2, 0x847A}, //9361 #CJK UNIFIED IDEOGRAPH + {0xDFC3, 0x8443}, //9362 #CJK UNIFIED IDEOGRAPH + {0xDFC4, 0x8478}, //9363 #CJK UNIFIED IDEOGRAPH + {0xDFC5, 0x8432}, //9364 #CJK UNIFIED IDEOGRAPH + {0xDFC6, 0x8445}, //9365 #CJK UNIFIED IDEOGRAPH + {0xDFC7, 0x8429}, //9366 #CJK UNIFIED IDEOGRAPH + {0xDFC8, 0x83D9}, //9367 #CJK UNIFIED IDEOGRAPH + {0xDFC9, 0x844B}, //9368 #CJK UNIFIED IDEOGRAPH + {0xDFCA, 0x842F}, //9369 #CJK UNIFIED IDEOGRAPH + {0xDFCB, 0x8442}, //9370 #CJK UNIFIED IDEOGRAPH + {0xDFCC, 0x842D}, //9371 #CJK UNIFIED IDEOGRAPH + {0xDFCD, 0x845F}, //9372 #CJK UNIFIED IDEOGRAPH + {0xDFCE, 0x8470}, //9373 #CJK UNIFIED IDEOGRAPH + {0xDFCF, 0x8439}, //9374 #CJK UNIFIED IDEOGRAPH + {0xDFD0, 0x844E}, //9375 #CJK UNIFIED IDEOGRAPH + {0xDFD1, 0x844C}, //9376 #CJK UNIFIED IDEOGRAPH + {0xDFD2, 0x8452}, //9377 #CJK UNIFIED IDEOGRAPH + {0xDFD3, 0x846F}, //9378 #CJK UNIFIED IDEOGRAPH + {0xDFD4, 0x84C5}, //9379 #CJK UNIFIED IDEOGRAPH + {0xDFD5, 0x848E}, //9380 #CJK UNIFIED IDEOGRAPH + {0xDFD6, 0x843B}, //9381 #CJK UNIFIED IDEOGRAPH + {0xDFD7, 0x8447}, //9382 #CJK UNIFIED IDEOGRAPH + {0xDFD8, 0x8436}, //9383 #CJK UNIFIED IDEOGRAPH + {0xDFD9, 0x8433}, //9384 #CJK UNIFIED IDEOGRAPH + {0xDFDA, 0x8468}, //9385 #CJK UNIFIED IDEOGRAPH + {0xDFDB, 0x847E}, //9386 #CJK UNIFIED IDEOGRAPH + {0xDFDC, 0x8444}, //9387 #CJK UNIFIED IDEOGRAPH + {0xDFDD, 0x842B}, //9388 #CJK UNIFIED IDEOGRAPH + {0xDFDE, 0x8460}, //9389 #CJK UNIFIED IDEOGRAPH + {0xDFDF, 0x8454}, //9390 #CJK UNIFIED IDEOGRAPH + {0xDFE0, 0x846E}, //9391 #CJK UNIFIED IDEOGRAPH + {0xDFE1, 0x8450}, //9392 #CJK UNIFIED IDEOGRAPH + {0xDFE2, 0x870B}, //9393 #CJK UNIFIED IDEOGRAPH + {0xDFE3, 0x8704}, //9394 #CJK UNIFIED IDEOGRAPH + {0xDFE4, 0x86F7}, //9395 #CJK UNIFIED IDEOGRAPH + {0xDFE5, 0x870C}, //9396 #CJK UNIFIED IDEOGRAPH + {0xDFE6, 0x86FA}, //9397 #CJK UNIFIED IDEOGRAPH + {0xDFE7, 0x86D6}, //9398 #CJK UNIFIED IDEOGRAPH + {0xDFE8, 0x86F5}, //9399 #CJK UNIFIED IDEOGRAPH + {0xDFE9, 0x874D}, //9400 #CJK UNIFIED IDEOGRAPH + {0xDFEA, 0x86F8}, //9401 #CJK UNIFIED IDEOGRAPH + {0xDFEB, 0x870E}, //9402 #CJK UNIFIED IDEOGRAPH + {0xDFEC, 0x8709}, //9403 #CJK UNIFIED IDEOGRAPH + {0xDFED, 0x8701}, //9404 #CJK UNIFIED IDEOGRAPH + {0xDFEE, 0x86F6}, //9405 #CJK UNIFIED IDEOGRAPH + {0xDFEF, 0x870D}, //9406 #CJK UNIFIED IDEOGRAPH + {0xDFF0, 0x8705}, //9407 #CJK UNIFIED IDEOGRAPH + {0xDFF1, 0x88D6}, //9408 #CJK UNIFIED IDEOGRAPH + {0xDFF2, 0x88CB}, //9409 #CJK UNIFIED IDEOGRAPH + {0xDFF3, 0x88CD}, //9410 #CJK UNIFIED IDEOGRAPH + {0xDFF4, 0x88CE}, //9411 #CJK UNIFIED IDEOGRAPH + {0xDFF5, 0x88DE}, //9412 #CJK UNIFIED IDEOGRAPH + {0xDFF6, 0x88DB}, //9413 #CJK UNIFIED IDEOGRAPH + {0xDFF7, 0x88DA}, //9414 #CJK UNIFIED IDEOGRAPH + {0xDFF8, 0x88CC}, //9415 #CJK UNIFIED IDEOGRAPH + {0xDFF9, 0x88D0}, //9416 #CJK UNIFIED IDEOGRAPH + {0xDFFA, 0x8985}, //9417 #CJK UNIFIED IDEOGRAPH + {0xDFFB, 0x899B}, //9418 #CJK UNIFIED IDEOGRAPH + {0xDFFC, 0x89DF}, //9419 #CJK UNIFIED IDEOGRAPH + {0xDFFD, 0x89E5}, //9420 #CJK UNIFIED IDEOGRAPH + {0xDFFE, 0x89E4}, //9421 #CJK UNIFIED IDEOGRAPH + {0xE040, 0x89E1}, //9422 #CJK UNIFIED IDEOGRAPH + {0xE041, 0x89E0}, //9423 #CJK UNIFIED IDEOGRAPH + {0xE042, 0x89E2}, //9424 #CJK UNIFIED IDEOGRAPH + {0xE043, 0x89DC}, //9425 #CJK UNIFIED IDEOGRAPH + {0xE044, 0x89E6}, //9426 #CJK UNIFIED IDEOGRAPH + {0xE045, 0x8A76}, //9427 #CJK UNIFIED IDEOGRAPH + {0xE046, 0x8A86}, //9428 #CJK UNIFIED IDEOGRAPH + {0xE047, 0x8A7F}, //9429 #CJK UNIFIED IDEOGRAPH + {0xE048, 0x8A61}, //9430 #CJK UNIFIED IDEOGRAPH + {0xE049, 0x8A3F}, //9431 #CJK UNIFIED IDEOGRAPH + {0xE04A, 0x8A77}, //9432 #CJK UNIFIED IDEOGRAPH + {0xE04B, 0x8A82}, //9433 #CJK UNIFIED IDEOGRAPH + {0xE04C, 0x8A84}, //9434 #CJK UNIFIED IDEOGRAPH + {0xE04D, 0x8A75}, //9435 #CJK UNIFIED IDEOGRAPH + {0xE04E, 0x8A83}, //9436 #CJK UNIFIED IDEOGRAPH + {0xE04F, 0x8A81}, //9437 #CJK UNIFIED IDEOGRAPH + {0xE050, 0x8A74}, //9438 #CJK UNIFIED IDEOGRAPH + {0xE051, 0x8A7A}, //9439 #CJK UNIFIED IDEOGRAPH + {0xE052, 0x8C3C}, //9440 #CJK UNIFIED IDEOGRAPH + {0xE053, 0x8C4B}, //9441 #CJK UNIFIED IDEOGRAPH + {0xE054, 0x8C4A}, //9442 #CJK UNIFIED IDEOGRAPH + {0xE055, 0x8C65}, //9443 #CJK UNIFIED IDEOGRAPH + {0xE056, 0x8C64}, //9444 #CJK UNIFIED IDEOGRAPH + {0xE057, 0x8C66}, //9445 #CJK UNIFIED IDEOGRAPH + {0xE058, 0x8C86}, //9446 #CJK UNIFIED IDEOGRAPH + {0xE059, 0x8C84}, //9447 #CJK UNIFIED IDEOGRAPH + {0xE05A, 0x8C85}, //9448 #CJK UNIFIED IDEOGRAPH + {0xE05B, 0x8CCC}, //9449 #CJK UNIFIED IDEOGRAPH + {0xE05C, 0x8D68}, //9450 #CJK UNIFIED IDEOGRAPH + {0xE05D, 0x8D69}, //9451 #CJK UNIFIED IDEOGRAPH + {0xE05E, 0x8D91}, //9452 #CJK UNIFIED IDEOGRAPH + {0xE05F, 0x8D8C}, //9453 #CJK UNIFIED IDEOGRAPH + {0xE060, 0x8D8E}, //9454 #CJK UNIFIED IDEOGRAPH + {0xE061, 0x8D8F}, //9455 #CJK UNIFIED IDEOGRAPH + {0xE062, 0x8D8D}, //9456 #CJK UNIFIED IDEOGRAPH + {0xE063, 0x8D93}, //9457 #CJK UNIFIED IDEOGRAPH + {0xE064, 0x8D94}, //9458 #CJK UNIFIED IDEOGRAPH + {0xE065, 0x8D90}, //9459 #CJK UNIFIED IDEOGRAPH + {0xE066, 0x8D92}, //9460 #CJK UNIFIED IDEOGRAPH + {0xE067, 0x8DF0}, //9461 #CJK UNIFIED IDEOGRAPH + {0xE068, 0x8DE0}, //9462 #CJK UNIFIED IDEOGRAPH + {0xE069, 0x8DEC}, //9463 #CJK UNIFIED IDEOGRAPH + {0xE06A, 0x8DF1}, //9464 #CJK UNIFIED IDEOGRAPH + {0xE06B, 0x8DEE}, //9465 #CJK UNIFIED IDEOGRAPH + {0xE06C, 0x8DD0}, //9466 #CJK UNIFIED IDEOGRAPH + {0xE06D, 0x8DE9}, //9467 #CJK UNIFIED IDEOGRAPH + {0xE06E, 0x8DE3}, //9468 #CJK UNIFIED IDEOGRAPH + {0xE06F, 0x8DE2}, //9469 #CJK UNIFIED IDEOGRAPH + {0xE070, 0x8DE7}, //9470 #CJK UNIFIED IDEOGRAPH + {0xE071, 0x8DF2}, //9471 #CJK UNIFIED IDEOGRAPH + {0xE072, 0x8DEB}, //9472 #CJK UNIFIED IDEOGRAPH + {0xE073, 0x8DF4}, //9473 #CJK UNIFIED IDEOGRAPH + {0xE074, 0x8F06}, //9474 #CJK UNIFIED IDEOGRAPH + {0xE075, 0x8EFF}, //9475 #CJK UNIFIED IDEOGRAPH + {0xE076, 0x8F01}, //9476 #CJK UNIFIED IDEOGRAPH + {0xE077, 0x8F00}, //9477 #CJK UNIFIED IDEOGRAPH + {0xE078, 0x8F05}, //9478 #CJK UNIFIED IDEOGRAPH + {0xE079, 0x8F07}, //9479 #CJK UNIFIED IDEOGRAPH + {0xE07A, 0x8F08}, //9480 #CJK UNIFIED IDEOGRAPH + {0xE07B, 0x8F02}, //9481 #CJK UNIFIED IDEOGRAPH + {0xE07C, 0x8F0B}, //9482 #CJK UNIFIED IDEOGRAPH + {0xE07D, 0x9052}, //9483 #CJK UNIFIED IDEOGRAPH + {0xE07E, 0x903F}, //9484 #CJK UNIFIED IDEOGRAPH + {0xE0A1, 0x9044}, //9485 #CJK UNIFIED IDEOGRAPH + {0xE0A2, 0x9049}, //9486 #CJK UNIFIED IDEOGRAPH + {0xE0A3, 0x903D}, //9487 #CJK UNIFIED IDEOGRAPH + {0xE0A4, 0x9110}, //9488 #CJK UNIFIED IDEOGRAPH + {0xE0A5, 0x910D}, //9489 #CJK UNIFIED IDEOGRAPH + {0xE0A6, 0x910F}, //9490 #CJK UNIFIED IDEOGRAPH + {0xE0A7, 0x9111}, //9491 #CJK UNIFIED IDEOGRAPH + {0xE0A8, 0x9116}, //9492 #CJK UNIFIED IDEOGRAPH + {0xE0A9, 0x9114}, //9493 #CJK UNIFIED IDEOGRAPH + {0xE0AA, 0x910B}, //9494 #CJK UNIFIED IDEOGRAPH + {0xE0AB, 0x910E}, //9495 #CJK UNIFIED IDEOGRAPH + {0xE0AC, 0x916E}, //9496 #CJK UNIFIED IDEOGRAPH + {0xE0AD, 0x916F}, //9497 #CJK UNIFIED IDEOGRAPH + {0xE0AE, 0x9248}, //9498 #CJK UNIFIED IDEOGRAPH + {0xE0AF, 0x9252}, //9499 #CJK UNIFIED IDEOGRAPH + {0xE0B0, 0x9230}, //9500 #CJK UNIFIED IDEOGRAPH + {0xE0B1, 0x923A}, //9501 #CJK UNIFIED IDEOGRAPH + {0xE0B2, 0x9266}, //9502 #CJK UNIFIED IDEOGRAPH + {0xE0B3, 0x9233}, //9503 #CJK UNIFIED IDEOGRAPH + {0xE0B4, 0x9265}, //9504 #CJK UNIFIED IDEOGRAPH + {0xE0B5, 0x925E}, //9505 #CJK UNIFIED IDEOGRAPH + {0xE0B6, 0x9283}, //9506 #CJK UNIFIED IDEOGRAPH + {0xE0B7, 0x922E}, //9507 #CJK UNIFIED IDEOGRAPH + {0xE0B8, 0x924A}, //9508 #CJK UNIFIED IDEOGRAPH + {0xE0B9, 0x9246}, //9509 #CJK UNIFIED IDEOGRAPH + {0xE0BA, 0x926D}, //9510 #CJK UNIFIED IDEOGRAPH + {0xE0BB, 0x926C}, //9511 #CJK UNIFIED IDEOGRAPH + {0xE0BC, 0x924F}, //9512 #CJK UNIFIED IDEOGRAPH + {0xE0BD, 0x9260}, //9513 #CJK UNIFIED IDEOGRAPH + {0xE0BE, 0x9267}, //9514 #CJK UNIFIED IDEOGRAPH + {0xE0BF, 0x926F}, //9515 #CJK UNIFIED IDEOGRAPH + {0xE0C0, 0x9236}, //9516 #CJK UNIFIED IDEOGRAPH + {0xE0C1, 0x9261}, //9517 #CJK UNIFIED IDEOGRAPH + {0xE0C2, 0x9270}, //9518 #CJK UNIFIED IDEOGRAPH + {0xE0C3, 0x9231}, //9519 #CJK UNIFIED IDEOGRAPH + {0xE0C4, 0x9254}, //9520 #CJK UNIFIED IDEOGRAPH + {0xE0C5, 0x9263}, //9521 #CJK UNIFIED IDEOGRAPH + {0xE0C6, 0x9250}, //9522 #CJK UNIFIED IDEOGRAPH + {0xE0C7, 0x9272}, //9523 #CJK UNIFIED IDEOGRAPH + {0xE0C8, 0x924E}, //9524 #CJK UNIFIED IDEOGRAPH + {0xE0C9, 0x9253}, //9525 #CJK UNIFIED IDEOGRAPH + {0xE0CA, 0x924C}, //9526 #CJK UNIFIED IDEOGRAPH + {0xE0CB, 0x9256}, //9527 #CJK UNIFIED IDEOGRAPH + {0xE0CC, 0x9232}, //9528 #CJK UNIFIED IDEOGRAPH + {0xE0CD, 0x959F}, //9529 #CJK UNIFIED IDEOGRAPH + {0xE0CE, 0x959C}, //9530 #CJK UNIFIED IDEOGRAPH + {0xE0CF, 0x959E}, //9531 #CJK UNIFIED IDEOGRAPH + {0xE0D0, 0x959B}, //9532 #CJK UNIFIED IDEOGRAPH + {0xE0D1, 0x9692}, //9533 #CJK UNIFIED IDEOGRAPH + {0xE0D2, 0x9693}, //9534 #CJK UNIFIED IDEOGRAPH + {0xE0D3, 0x9691}, //9535 #CJK UNIFIED IDEOGRAPH + {0xE0D4, 0x9697}, //9536 #CJK UNIFIED IDEOGRAPH + {0xE0D5, 0x96CE}, //9537 #CJK UNIFIED IDEOGRAPH + {0xE0D6, 0x96FA}, //9538 #CJK UNIFIED IDEOGRAPH + {0xE0D7, 0x96FD}, //9539 #CJK UNIFIED IDEOGRAPH + {0xE0D8, 0x96F8}, //9540 #CJK UNIFIED IDEOGRAPH + {0xE0D9, 0x96F5}, //9541 #CJK UNIFIED IDEOGRAPH + {0xE0DA, 0x9773}, //9542 #CJK UNIFIED IDEOGRAPH + {0xE0DB, 0x9777}, //9543 #CJK UNIFIED IDEOGRAPH + {0xE0DC, 0x9778}, //9544 #CJK UNIFIED IDEOGRAPH + {0xE0DD, 0x9772}, //9545 #CJK UNIFIED IDEOGRAPH + {0xE0DE, 0x980F}, //9546 #CJK UNIFIED IDEOGRAPH + {0xE0DF, 0x980D}, //9547 #CJK UNIFIED IDEOGRAPH + {0xE0E0, 0x980E}, //9548 #CJK UNIFIED IDEOGRAPH + {0xE0E1, 0x98AC}, //9549 #CJK UNIFIED IDEOGRAPH + {0xE0E2, 0x98F6}, //9550 #CJK UNIFIED IDEOGRAPH + {0xE0E3, 0x98F9}, //9551 #CJK UNIFIED IDEOGRAPH + {0xE0E4, 0x99AF}, //9552 #CJK UNIFIED IDEOGRAPH + {0xE0E5, 0x99B2}, //9553 #CJK UNIFIED IDEOGRAPH + {0xE0E6, 0x99B0}, //9554 #CJK UNIFIED IDEOGRAPH + {0xE0E7, 0x99B5}, //9555 #CJK UNIFIED IDEOGRAPH + {0xE0E8, 0x9AAD}, //9556 #CJK UNIFIED IDEOGRAPH + {0xE0E9, 0x9AAB}, //9557 #CJK UNIFIED IDEOGRAPH + {0xE0EA, 0x9B5B}, //9558 #CJK UNIFIED IDEOGRAPH + {0xE0EB, 0x9CEA}, //9559 #CJK UNIFIED IDEOGRAPH + {0xE0EC, 0x9CED}, //9560 #CJK UNIFIED IDEOGRAPH + {0xE0ED, 0x9CE7}, //9561 #CJK UNIFIED IDEOGRAPH + {0xE0EE, 0x9E80}, //9562 #CJK UNIFIED IDEOGRAPH + {0xE0EF, 0x9EFD}, //9563 #CJK UNIFIED IDEOGRAPH + {0xE0F0, 0x50E6}, //9564 #CJK UNIFIED IDEOGRAPH + {0xE0F1, 0x50D4}, //9565 #CJK UNIFIED IDEOGRAPH + {0xE0F2, 0x50D7}, //9566 #CJK UNIFIED IDEOGRAPH + {0xE0F3, 0x50E8}, //9567 #CJK UNIFIED IDEOGRAPH + {0xE0F4, 0x50F3}, //9568 #CJK UNIFIED IDEOGRAPH + {0xE0F5, 0x50DB}, //9569 #CJK UNIFIED IDEOGRAPH + {0xE0F6, 0x50EA}, //9570 #CJK UNIFIED IDEOGRAPH + {0xE0F7, 0x50DD}, //9571 #CJK UNIFIED IDEOGRAPH + {0xE0F8, 0x50E4}, //9572 #CJK UNIFIED IDEOGRAPH + {0xE0F9, 0x50D3}, //9573 #CJK UNIFIED IDEOGRAPH + {0xE0FA, 0x50EC}, //9574 #CJK UNIFIED IDEOGRAPH + {0xE0FB, 0x50F0}, //9575 #CJK UNIFIED IDEOGRAPH + {0xE0FC, 0x50EF}, //9576 #CJK UNIFIED IDEOGRAPH + {0xE0FD, 0x50E3}, //9577 #CJK UNIFIED IDEOGRAPH + {0xE0FE, 0x50E0}, //9578 #CJK UNIFIED IDEOGRAPH + {0xE140, 0x51D8}, //9579 #CJK UNIFIED IDEOGRAPH + {0xE141, 0x5280}, //9580 #CJK UNIFIED IDEOGRAPH + {0xE142, 0x5281}, //9581 #CJK UNIFIED IDEOGRAPH + {0xE143, 0x52E9}, //9582 #CJK UNIFIED IDEOGRAPH + {0xE144, 0x52EB}, //9583 #CJK UNIFIED IDEOGRAPH + {0xE145, 0x5330}, //9584 #CJK UNIFIED IDEOGRAPH + {0xE146, 0x53AC}, //9585 #CJK UNIFIED IDEOGRAPH + {0xE147, 0x5627}, //9586 #CJK UNIFIED IDEOGRAPH + {0xE148, 0x5615}, //9587 #CJK UNIFIED IDEOGRAPH + {0xE149, 0x560C}, //9588 #CJK UNIFIED IDEOGRAPH + {0xE14A, 0x5612}, //9589 #CJK UNIFIED IDEOGRAPH + {0xE14B, 0x55FC}, //9590 #CJK UNIFIED IDEOGRAPH + {0xE14C, 0x560F}, //9591 #CJK UNIFIED IDEOGRAPH + {0xE14D, 0x561C}, //9592 #CJK UNIFIED IDEOGRAPH + {0xE14E, 0x5601}, //9593 #CJK UNIFIED IDEOGRAPH + {0xE14F, 0x5613}, //9594 #CJK UNIFIED IDEOGRAPH + {0xE150, 0x5602}, //9595 #CJK UNIFIED IDEOGRAPH + {0xE151, 0x55FA}, //9596 #CJK UNIFIED IDEOGRAPH + {0xE152, 0x561D}, //9597 #CJK UNIFIED IDEOGRAPH + {0xE153, 0x5604}, //9598 #CJK UNIFIED IDEOGRAPH + {0xE154, 0x55FF}, //9599 #CJK UNIFIED IDEOGRAPH + {0xE155, 0x55F9}, //9600 #CJK UNIFIED IDEOGRAPH + {0xE156, 0x5889}, //9601 #CJK UNIFIED IDEOGRAPH + {0xE157, 0x587C}, //9602 #CJK UNIFIED IDEOGRAPH + {0xE158, 0x5890}, //9603 #CJK UNIFIED IDEOGRAPH + {0xE159, 0x5898}, //9604 #CJK UNIFIED IDEOGRAPH + {0xE15A, 0x5886}, //9605 #CJK UNIFIED IDEOGRAPH + {0xE15B, 0x5881}, //9606 #CJK UNIFIED IDEOGRAPH + {0xE15C, 0x587F}, //9607 #CJK UNIFIED IDEOGRAPH + {0xE15D, 0x5874}, //9608 #CJK UNIFIED IDEOGRAPH + {0xE15E, 0x588B}, //9609 #CJK UNIFIED IDEOGRAPH + {0xE15F, 0x587A}, //9610 #CJK UNIFIED IDEOGRAPH + {0xE160, 0x5887}, //9611 #CJK UNIFIED IDEOGRAPH + {0xE161, 0x5891}, //9612 #CJK UNIFIED IDEOGRAPH + {0xE162, 0x588E}, //9613 #CJK UNIFIED IDEOGRAPH + {0xE163, 0x5876}, //9614 #CJK UNIFIED IDEOGRAPH + {0xE164, 0x5882}, //9615 #CJK UNIFIED IDEOGRAPH + {0xE165, 0x5888}, //9616 #CJK UNIFIED IDEOGRAPH + {0xE166, 0x587B}, //9617 #CJK UNIFIED IDEOGRAPH + {0xE167, 0x5894}, //9618 #CJK UNIFIED IDEOGRAPH + {0xE168, 0x588F}, //9619 #CJK UNIFIED IDEOGRAPH + {0xE169, 0x58FE}, //9620 #CJK UNIFIED IDEOGRAPH + {0xE16A, 0x596B}, //9621 #CJK UNIFIED IDEOGRAPH + {0xE16B, 0x5ADC}, //9622 #CJK UNIFIED IDEOGRAPH + {0xE16C, 0x5AEE}, //9623 #CJK UNIFIED IDEOGRAPH + {0xE16D, 0x5AE5}, //9624 #CJK UNIFIED IDEOGRAPH + {0xE16E, 0x5AD5}, //9625 #CJK UNIFIED IDEOGRAPH + {0xE16F, 0x5AEA}, //9626 #CJK UNIFIED IDEOGRAPH + {0xE170, 0x5ADA}, //9627 #CJK UNIFIED IDEOGRAPH + {0xE171, 0x5AED}, //9628 #CJK UNIFIED IDEOGRAPH + {0xE172, 0x5AEB}, //9629 #CJK UNIFIED IDEOGRAPH + {0xE173, 0x5AF3}, //9630 #CJK UNIFIED IDEOGRAPH + {0xE174, 0x5AE2}, //9631 #CJK UNIFIED IDEOGRAPH + {0xE175, 0x5AE0}, //9632 #CJK UNIFIED IDEOGRAPH + {0xE176, 0x5ADB}, //9633 #CJK UNIFIED IDEOGRAPH + {0xE177, 0x5AEC}, //9634 #CJK UNIFIED IDEOGRAPH + {0xE178, 0x5ADE}, //9635 #CJK UNIFIED IDEOGRAPH + {0xE179, 0x5ADD}, //9636 #CJK UNIFIED IDEOGRAPH + {0xE17A, 0x5AD9}, //9637 #CJK UNIFIED IDEOGRAPH + {0xE17B, 0x5AE8}, //9638 #CJK UNIFIED IDEOGRAPH + {0xE17C, 0x5ADF}, //9639 #CJK UNIFIED IDEOGRAPH + {0xE17D, 0x5B77}, //9640 #CJK UNIFIED IDEOGRAPH + {0xE17E, 0x5BE0}, //9641 #CJK UNIFIED IDEOGRAPH + {0xE1A1, 0x5BE3}, //9642 #CJK UNIFIED IDEOGRAPH + {0xE1A2, 0x5C63}, //9643 #CJK UNIFIED IDEOGRAPH + {0xE1A3, 0x5D82}, //9644 #CJK UNIFIED IDEOGRAPH + {0xE1A4, 0x5D80}, //9645 #CJK UNIFIED IDEOGRAPH + {0xE1A5, 0x5D7D}, //9646 #CJK UNIFIED IDEOGRAPH + {0xE1A6, 0x5D86}, //9647 #CJK UNIFIED IDEOGRAPH + {0xE1A7, 0x5D7A}, //9648 #CJK UNIFIED IDEOGRAPH + {0xE1A8, 0x5D81}, //9649 #CJK UNIFIED IDEOGRAPH + {0xE1A9, 0x5D77}, //9650 #CJK UNIFIED IDEOGRAPH + {0xE1AA, 0x5D8A}, //9651 #CJK UNIFIED IDEOGRAPH + {0xE1AB, 0x5D89}, //9652 #CJK UNIFIED IDEOGRAPH + {0xE1AC, 0x5D88}, //9653 #CJK UNIFIED IDEOGRAPH + {0xE1AD, 0x5D7E}, //9654 #CJK UNIFIED IDEOGRAPH + {0xE1AE, 0x5D7C}, //9655 #CJK UNIFIED IDEOGRAPH + {0xE1AF, 0x5D8D}, //9656 #CJK UNIFIED IDEOGRAPH + {0xE1B0, 0x5D79}, //9657 #CJK UNIFIED IDEOGRAPH + {0xE1B1, 0x5D7F}, //9658 #CJK UNIFIED IDEOGRAPH + {0xE1B2, 0x5E58}, //9659 #CJK UNIFIED IDEOGRAPH + {0xE1B3, 0x5E59}, //9660 #CJK UNIFIED IDEOGRAPH + {0xE1B4, 0x5E53}, //9661 #CJK UNIFIED IDEOGRAPH + {0xE1B5, 0x5ED8}, //9662 #CJK UNIFIED IDEOGRAPH + {0xE1B6, 0x5ED1}, //9663 #CJK UNIFIED IDEOGRAPH + {0xE1B7, 0x5ED7}, //9664 #CJK UNIFIED IDEOGRAPH + {0xE1B8, 0x5ECE}, //9665 #CJK UNIFIED IDEOGRAPH + {0xE1B9, 0x5EDC}, //9666 #CJK UNIFIED IDEOGRAPH + {0xE1BA, 0x5ED5}, //9667 #CJK UNIFIED IDEOGRAPH + {0xE1BB, 0x5ED9}, //9668 #CJK UNIFIED IDEOGRAPH + {0xE1BC, 0x5ED2}, //9669 #CJK UNIFIED IDEOGRAPH + {0xE1BD, 0x5ED4}, //9670 #CJK UNIFIED IDEOGRAPH + {0xE1BE, 0x5F44}, //9671 #CJK UNIFIED IDEOGRAPH + {0xE1BF, 0x5F43}, //9672 #CJK UNIFIED IDEOGRAPH + {0xE1C0, 0x5F6F}, //9673 #CJK UNIFIED IDEOGRAPH + {0xE1C1, 0x5FB6}, //9674 #CJK UNIFIED IDEOGRAPH + {0xE1C2, 0x612C}, //9675 #CJK UNIFIED IDEOGRAPH + {0xE1C3, 0x6128}, //9676 #CJK UNIFIED IDEOGRAPH + {0xE1C4, 0x6141}, //9677 #CJK UNIFIED IDEOGRAPH + {0xE1C5, 0x615E}, //9678 #CJK UNIFIED IDEOGRAPH + {0xE1C6, 0x6171}, //9679 #CJK UNIFIED IDEOGRAPH + {0xE1C7, 0x6173}, //9680 #CJK UNIFIED IDEOGRAPH + {0xE1C8, 0x6152}, //9681 #CJK UNIFIED IDEOGRAPH + {0xE1C9, 0x6153}, //9682 #CJK UNIFIED IDEOGRAPH + {0xE1CA, 0x6172}, //9683 #CJK UNIFIED IDEOGRAPH + {0xE1CB, 0x616C}, //9684 #CJK UNIFIED IDEOGRAPH + {0xE1CC, 0x6180}, //9685 #CJK UNIFIED IDEOGRAPH + {0xE1CD, 0x6174}, //9686 #CJK UNIFIED IDEOGRAPH + {0xE1CE, 0x6154}, //9687 #CJK UNIFIED IDEOGRAPH + {0xE1CF, 0x617A}, //9688 #CJK UNIFIED IDEOGRAPH + {0xE1D0, 0x615B}, //9689 #CJK UNIFIED IDEOGRAPH + {0xE1D1, 0x6165}, //9690 #CJK UNIFIED IDEOGRAPH + {0xE1D2, 0x613B}, //9691 #CJK UNIFIED IDEOGRAPH + {0xE1D3, 0x616A}, //9692 #CJK UNIFIED IDEOGRAPH + {0xE1D4, 0x6161}, //9693 #CJK UNIFIED IDEOGRAPH + {0xE1D5, 0x6156}, //9694 #CJK UNIFIED IDEOGRAPH + {0xE1D6, 0x6229}, //9695 #CJK UNIFIED IDEOGRAPH + {0xE1D7, 0x6227}, //9696 #CJK UNIFIED IDEOGRAPH + {0xE1D8, 0x622B}, //9697 #CJK UNIFIED IDEOGRAPH + {0xE1D9, 0x642B}, //9698 #CJK UNIFIED IDEOGRAPH + {0xE1DA, 0x644D}, //9699 #CJK UNIFIED IDEOGRAPH + {0xE1DB, 0x645B}, //9700 #CJK UNIFIED IDEOGRAPH + {0xE1DC, 0x645D}, //9701 #CJK UNIFIED IDEOGRAPH + {0xE1DD, 0x6474}, //9702 #CJK UNIFIED IDEOGRAPH + {0xE1DE, 0x6476}, //9703 #CJK UNIFIED IDEOGRAPH + {0xE1DF, 0x6472}, //9704 #CJK UNIFIED IDEOGRAPH + {0xE1E0, 0x6473}, //9705 #CJK UNIFIED IDEOGRAPH + {0xE1E1, 0x647D}, //9706 #CJK UNIFIED IDEOGRAPH + {0xE1E2, 0x6475}, //9707 #CJK UNIFIED IDEOGRAPH + {0xE1E3, 0x6466}, //9708 #CJK UNIFIED IDEOGRAPH + {0xE1E4, 0x64A6}, //9709 #CJK UNIFIED IDEOGRAPH + {0xE1E5, 0x644E}, //9710 #CJK UNIFIED IDEOGRAPH + {0xE1E6, 0x6482}, //9711 #CJK UNIFIED IDEOGRAPH + {0xE1E7, 0x645E}, //9712 #CJK UNIFIED IDEOGRAPH + {0xE1E8, 0x645C}, //9713 #CJK UNIFIED IDEOGRAPH + {0xE1E9, 0x644B}, //9714 #CJK UNIFIED IDEOGRAPH + {0xE1EA, 0x6453}, //9715 #CJK UNIFIED IDEOGRAPH + {0xE1EB, 0x6460}, //9716 #CJK UNIFIED IDEOGRAPH + {0xE1EC, 0x6450}, //9717 #CJK UNIFIED IDEOGRAPH + {0xE1ED, 0x647F}, //9718 #CJK UNIFIED IDEOGRAPH + {0xE1EE, 0x643F}, //9719 #CJK UNIFIED IDEOGRAPH + {0xE1EF, 0x646C}, //9720 #CJK UNIFIED IDEOGRAPH + {0xE1F0, 0x646B}, //9721 #CJK UNIFIED IDEOGRAPH + {0xE1F1, 0x6459}, //9722 #CJK UNIFIED IDEOGRAPH + {0xE1F2, 0x6465}, //9723 #CJK UNIFIED IDEOGRAPH + {0xE1F3, 0x6477}, //9724 #CJK UNIFIED IDEOGRAPH + {0xE1F4, 0x6573}, //9725 #CJK UNIFIED IDEOGRAPH + {0xE1F5, 0x65A0}, //9726 #CJK UNIFIED IDEOGRAPH + {0xE1F6, 0x66A1}, //9727 #CJK UNIFIED IDEOGRAPH + {0xE1F7, 0x66A0}, //9728 #CJK UNIFIED IDEOGRAPH + {0xE1F8, 0x669F}, //9729 #CJK UNIFIED IDEOGRAPH + {0xE1F9, 0x6705}, //9730 #CJK UNIFIED IDEOGRAPH + {0xE1FA, 0x6704}, //9731 #CJK UNIFIED IDEOGRAPH + {0xE1FB, 0x6722}, //9732 #CJK UNIFIED IDEOGRAPH + {0xE1FC, 0x69B1}, //9733 #CJK UNIFIED IDEOGRAPH + {0xE1FD, 0x69B6}, //9734 #CJK UNIFIED IDEOGRAPH + {0xE1FE, 0x69C9}, //9735 #CJK UNIFIED IDEOGRAPH + {0xE240, 0x69A0}, //9736 #CJK UNIFIED IDEOGRAPH + {0xE241, 0x69CE}, //9737 #CJK UNIFIED IDEOGRAPH + {0xE242, 0x6996}, //9738 #CJK UNIFIED IDEOGRAPH + {0xE243, 0x69B0}, //9739 #CJK UNIFIED IDEOGRAPH + {0xE244, 0x69AC}, //9740 #CJK UNIFIED IDEOGRAPH + {0xE245, 0x69BC}, //9741 #CJK UNIFIED IDEOGRAPH + {0xE246, 0x6991}, //9742 #CJK UNIFIED IDEOGRAPH + {0xE247, 0x6999}, //9743 #CJK UNIFIED IDEOGRAPH + {0xE248, 0x698E}, //9744 #CJK UNIFIED IDEOGRAPH + {0xE249, 0x69A7}, //9745 #CJK UNIFIED IDEOGRAPH + {0xE24A, 0x698D}, //9746 #CJK UNIFIED IDEOGRAPH + {0xE24B, 0x69A9}, //9747 #CJK UNIFIED IDEOGRAPH + {0xE24C, 0x69BE}, //9748 #CJK UNIFIED IDEOGRAPH + {0xE24D, 0x69AF}, //9749 #CJK UNIFIED IDEOGRAPH + {0xE24E, 0x69BF}, //9750 #CJK UNIFIED IDEOGRAPH + {0xE24F, 0x69C4}, //9751 #CJK UNIFIED IDEOGRAPH + {0xE250, 0x69BD}, //9752 #CJK UNIFIED IDEOGRAPH + {0xE251, 0x69A4}, //9753 #CJK UNIFIED IDEOGRAPH + {0xE252, 0x69D4}, //9754 #CJK UNIFIED IDEOGRAPH + {0xE253, 0x69B9}, //9755 #CJK UNIFIED IDEOGRAPH + {0xE254, 0x69CA}, //9756 #CJK UNIFIED IDEOGRAPH + {0xE255, 0x699A}, //9757 #CJK UNIFIED IDEOGRAPH + {0xE256, 0x69CF}, //9758 #CJK UNIFIED IDEOGRAPH + {0xE257, 0x69B3}, //9759 #CJK UNIFIED IDEOGRAPH + {0xE258, 0x6993}, //9760 #CJK UNIFIED IDEOGRAPH + {0xE259, 0x69AA}, //9761 #CJK UNIFIED IDEOGRAPH + {0xE25A, 0x69A1}, //9762 #CJK UNIFIED IDEOGRAPH + {0xE25B, 0x699E}, //9763 #CJK UNIFIED IDEOGRAPH + {0xE25C, 0x69D9}, //9764 #CJK UNIFIED IDEOGRAPH + {0xE25D, 0x6997}, //9765 #CJK UNIFIED IDEOGRAPH + {0xE25E, 0x6990}, //9766 #CJK UNIFIED IDEOGRAPH + {0xE25F, 0x69C2}, //9767 #CJK UNIFIED IDEOGRAPH + {0xE260, 0x69B5}, //9768 #CJK UNIFIED IDEOGRAPH + {0xE261, 0x69A5}, //9769 #CJK UNIFIED IDEOGRAPH + {0xE262, 0x69C6}, //9770 #CJK UNIFIED IDEOGRAPH + {0xE263, 0x6B4A}, //9771 #CJK UNIFIED IDEOGRAPH + {0xE264, 0x6B4D}, //9772 #CJK UNIFIED IDEOGRAPH + {0xE265, 0x6B4B}, //9773 #CJK UNIFIED IDEOGRAPH + {0xE266, 0x6B9E}, //9774 #CJK UNIFIED IDEOGRAPH + {0xE267, 0x6B9F}, //9775 #CJK UNIFIED IDEOGRAPH + {0xE268, 0x6BA0}, //9776 #CJK UNIFIED IDEOGRAPH + {0xE269, 0x6BC3}, //9777 #CJK UNIFIED IDEOGRAPH + {0xE26A, 0x6BC4}, //9778 #CJK UNIFIED IDEOGRAPH + {0xE26B, 0x6BFE}, //9779 #CJK UNIFIED IDEOGRAPH + {0xE26C, 0x6ECE}, //9780 #CJK UNIFIED IDEOGRAPH + {0xE26D, 0x6EF5}, //9781 #CJK UNIFIED IDEOGRAPH + {0xE26E, 0x6EF1}, //9782 #CJK UNIFIED IDEOGRAPH + {0xE26F, 0x6F03}, //9783 #CJK UNIFIED IDEOGRAPH + {0xE270, 0x6F25}, //9784 #CJK UNIFIED IDEOGRAPH + {0xE271, 0x6EF8}, //9785 #CJK UNIFIED IDEOGRAPH + {0xE272, 0x6F37}, //9786 #CJK UNIFIED IDEOGRAPH + {0xE273, 0x6EFB}, //9787 #CJK UNIFIED IDEOGRAPH + {0xE274, 0x6F2E}, //9788 #CJK UNIFIED IDEOGRAPH + {0xE275, 0x6F09}, //9789 #CJK UNIFIED IDEOGRAPH + {0xE276, 0x6F4E}, //9790 #CJK UNIFIED IDEOGRAPH + {0xE277, 0x6F19}, //9791 #CJK UNIFIED IDEOGRAPH + {0xE278, 0x6F1A}, //9792 #CJK UNIFIED IDEOGRAPH + {0xE279, 0x6F27}, //9793 #CJK UNIFIED IDEOGRAPH + {0xE27A, 0x6F18}, //9794 #CJK UNIFIED IDEOGRAPH + {0xE27B, 0x6F3B}, //9795 #CJK UNIFIED IDEOGRAPH + {0xE27C, 0x6F12}, //9796 #CJK UNIFIED IDEOGRAPH + {0xE27D, 0x6EED}, //9797 #CJK UNIFIED IDEOGRAPH + {0xE27E, 0x6F0A}, //9798 #CJK UNIFIED IDEOGRAPH + {0xE2A1, 0x6F36}, //9799 #CJK UNIFIED IDEOGRAPH + {0xE2A2, 0x6F73}, //9800 #CJK UNIFIED IDEOGRAPH + {0xE2A3, 0x6EF9}, //9801 #CJK UNIFIED IDEOGRAPH + {0xE2A4, 0x6EEE}, //9802 #CJK UNIFIED IDEOGRAPH + {0xE2A5, 0x6F2D}, //9803 #CJK UNIFIED IDEOGRAPH + {0xE2A6, 0x6F40}, //9804 #CJK UNIFIED IDEOGRAPH + {0xE2A7, 0x6F30}, //9805 #CJK UNIFIED IDEOGRAPH + {0xE2A8, 0x6F3C}, //9806 #CJK UNIFIED IDEOGRAPH + {0xE2A9, 0x6F35}, //9807 #CJK UNIFIED IDEOGRAPH + {0xE2AA, 0x6EEB}, //9808 #CJK UNIFIED IDEOGRAPH + {0xE2AB, 0x6F07}, //9809 #CJK UNIFIED IDEOGRAPH + {0xE2AC, 0x6F0E}, //9810 #CJK UNIFIED IDEOGRAPH + {0xE2AD, 0x6F43}, //9811 #CJK UNIFIED IDEOGRAPH + {0xE2AE, 0x6F05}, //9812 #CJK UNIFIED IDEOGRAPH + {0xE2AF, 0x6EFD}, //9813 #CJK UNIFIED IDEOGRAPH + {0xE2B0, 0x6EF6}, //9814 #CJK UNIFIED IDEOGRAPH + {0xE2B1, 0x6F39}, //9815 #CJK UNIFIED IDEOGRAPH + {0xE2B2, 0x6F1C}, //9816 #CJK UNIFIED IDEOGRAPH + {0xE2B3, 0x6EFC}, //9817 #CJK UNIFIED IDEOGRAPH + {0xE2B4, 0x6F3A}, //9818 #CJK UNIFIED IDEOGRAPH + {0xE2B5, 0x6F1F}, //9819 #CJK UNIFIED IDEOGRAPH + {0xE2B6, 0x6F0D}, //9820 #CJK UNIFIED IDEOGRAPH + {0xE2B7, 0x6F1E}, //9821 #CJK UNIFIED IDEOGRAPH + {0xE2B8, 0x6F08}, //9822 #CJK UNIFIED IDEOGRAPH + {0xE2B9, 0x6F21}, //9823 #CJK UNIFIED IDEOGRAPH + {0xE2BA, 0x7187}, //9824 #CJK UNIFIED IDEOGRAPH + {0xE2BB, 0x7190}, //9825 #CJK UNIFIED IDEOGRAPH + {0xE2BC, 0x7189}, //9826 #CJK UNIFIED IDEOGRAPH + {0xE2BD, 0x7180}, //9827 #CJK UNIFIED IDEOGRAPH + {0xE2BE, 0x7185}, //9828 #CJK UNIFIED IDEOGRAPH + {0xE2BF, 0x7182}, //9829 #CJK UNIFIED IDEOGRAPH + {0xE2C0, 0x718F}, //9830 #CJK UNIFIED IDEOGRAPH + {0xE2C1, 0x717B}, //9831 #CJK UNIFIED IDEOGRAPH + {0xE2C2, 0x7186}, //9832 #CJK UNIFIED IDEOGRAPH + {0xE2C3, 0x7181}, //9833 #CJK UNIFIED IDEOGRAPH + {0xE2C4, 0x7197}, //9834 #CJK UNIFIED IDEOGRAPH + {0xE2C5, 0x7244}, //9835 #CJK UNIFIED IDEOGRAPH + {0xE2C6, 0x7253}, //9836 #CJK UNIFIED IDEOGRAPH + {0xE2C7, 0x7297}, //9837 #CJK UNIFIED IDEOGRAPH + {0xE2C8, 0x7295}, //9838 #CJK UNIFIED IDEOGRAPH + {0xE2C9, 0x7293}, //9839 #CJK UNIFIED IDEOGRAPH + {0xE2CA, 0x7343}, //9840 #CJK UNIFIED IDEOGRAPH + {0xE2CB, 0x734D}, //9841 #CJK UNIFIED IDEOGRAPH + {0xE2CC, 0x7351}, //9842 #CJK UNIFIED IDEOGRAPH + {0xE2CD, 0x734C}, //9843 #CJK UNIFIED IDEOGRAPH + {0xE2CE, 0x7462}, //9844 #CJK UNIFIED IDEOGRAPH + {0xE2CF, 0x7473}, //9845 #CJK UNIFIED IDEOGRAPH + {0xE2D0, 0x7471}, //9846 #CJK UNIFIED IDEOGRAPH + {0xE2D1, 0x7475}, //9847 #CJK UNIFIED IDEOGRAPH + {0xE2D2, 0x7472}, //9848 #CJK UNIFIED IDEOGRAPH + {0xE2D3, 0x7467}, //9849 #CJK UNIFIED IDEOGRAPH + {0xE2D4, 0x746E}, //9850 #CJK UNIFIED IDEOGRAPH + {0xE2D5, 0x7500}, //9851 #CJK UNIFIED IDEOGRAPH + {0xE2D6, 0x7502}, //9852 #CJK UNIFIED IDEOGRAPH + {0xE2D7, 0x7503}, //9853 #CJK UNIFIED IDEOGRAPH + {0xE2D8, 0x757D}, //9854 #CJK UNIFIED IDEOGRAPH + {0xE2D9, 0x7590}, //9855 #CJK UNIFIED IDEOGRAPH + {0xE2DA, 0x7616}, //9856 #CJK UNIFIED IDEOGRAPH + {0xE2DB, 0x7608}, //9857 #CJK UNIFIED IDEOGRAPH + {0xE2DC, 0x760C}, //9858 #CJK UNIFIED IDEOGRAPH + {0xE2DD, 0x7615}, //9859 #CJK UNIFIED IDEOGRAPH + {0xE2DE, 0x7611}, //9860 #CJK UNIFIED IDEOGRAPH + {0xE2DF, 0x760A}, //9861 #CJK UNIFIED IDEOGRAPH + {0xE2E0, 0x7614}, //9862 #CJK UNIFIED IDEOGRAPH + {0xE2E1, 0x76B8}, //9863 #CJK UNIFIED IDEOGRAPH + {0xE2E2, 0x7781}, //9864 #CJK UNIFIED IDEOGRAPH + {0xE2E3, 0x777C}, //9865 #CJK UNIFIED IDEOGRAPH + {0xE2E4, 0x7785}, //9866 #CJK UNIFIED IDEOGRAPH + {0xE2E5, 0x7782}, //9867 #CJK UNIFIED IDEOGRAPH + {0xE2E6, 0x776E}, //9868 #CJK UNIFIED IDEOGRAPH + {0xE2E7, 0x7780}, //9869 #CJK UNIFIED IDEOGRAPH + {0xE2E8, 0x776F}, //9870 #CJK UNIFIED IDEOGRAPH + {0xE2E9, 0x777E}, //9871 #CJK UNIFIED IDEOGRAPH + {0xE2EA, 0x7783}, //9872 #CJK UNIFIED IDEOGRAPH + {0xE2EB, 0x78B2}, //9873 #CJK UNIFIED IDEOGRAPH + {0xE2EC, 0x78AA}, //9874 #CJK UNIFIED IDEOGRAPH + {0xE2ED, 0x78B4}, //9875 #CJK UNIFIED IDEOGRAPH + {0xE2EE, 0x78AD}, //9876 #CJK UNIFIED IDEOGRAPH + {0xE2EF, 0x78A8}, //9877 #CJK UNIFIED IDEOGRAPH + {0xE2F0, 0x787E}, //9878 #CJK UNIFIED IDEOGRAPH + {0xE2F1, 0x78AB}, //9879 #CJK UNIFIED IDEOGRAPH + {0xE2F2, 0x789E}, //9880 #CJK UNIFIED IDEOGRAPH + {0xE2F3, 0x78A5}, //9881 #CJK UNIFIED IDEOGRAPH + {0xE2F4, 0x78A0}, //9882 #CJK UNIFIED IDEOGRAPH + {0xE2F5, 0x78AC}, //9883 #CJK UNIFIED IDEOGRAPH + {0xE2F6, 0x78A2}, //9884 #CJK UNIFIED IDEOGRAPH + {0xE2F7, 0x78A4}, //9885 #CJK UNIFIED IDEOGRAPH + {0xE2F8, 0x7998}, //9886 #CJK UNIFIED IDEOGRAPH + {0xE2F9, 0x798A}, //9887 #CJK UNIFIED IDEOGRAPH + {0xE2FA, 0x798B}, //9888 #CJK UNIFIED IDEOGRAPH + {0xE2FB, 0x7996}, //9889 #CJK UNIFIED IDEOGRAPH + {0xE2FC, 0x7995}, //9890 #CJK UNIFIED IDEOGRAPH + {0xE2FD, 0x7994}, //9891 #CJK UNIFIED IDEOGRAPH + {0xE2FE, 0x7993}, //9892 #CJK UNIFIED IDEOGRAPH + {0xE340, 0x7997}, //9893 #CJK UNIFIED IDEOGRAPH + {0xE341, 0x7988}, //9894 #CJK UNIFIED IDEOGRAPH + {0xE342, 0x7992}, //9895 #CJK UNIFIED IDEOGRAPH + {0xE343, 0x7990}, //9896 #CJK UNIFIED IDEOGRAPH + {0xE344, 0x7A2B}, //9897 #CJK UNIFIED IDEOGRAPH + {0xE345, 0x7A4A}, //9898 #CJK UNIFIED IDEOGRAPH + {0xE346, 0x7A30}, //9899 #CJK UNIFIED IDEOGRAPH + {0xE347, 0x7A2F}, //9900 #CJK UNIFIED IDEOGRAPH + {0xE348, 0x7A28}, //9901 #CJK UNIFIED IDEOGRAPH + {0xE349, 0x7A26}, //9902 #CJK UNIFIED IDEOGRAPH + {0xE34A, 0x7AA8}, //9903 #CJK UNIFIED IDEOGRAPH + {0xE34B, 0x7AAB}, //9904 #CJK UNIFIED IDEOGRAPH + {0xE34C, 0x7AAC}, //9905 #CJK UNIFIED IDEOGRAPH + {0xE34D, 0x7AEE}, //9906 #CJK UNIFIED IDEOGRAPH + {0xE34E, 0x7B88}, //9907 #CJK UNIFIED IDEOGRAPH + {0xE34F, 0x7B9C}, //9908 #CJK UNIFIED IDEOGRAPH + {0xE350, 0x7B8A}, //9909 #CJK UNIFIED IDEOGRAPH + {0xE351, 0x7B91}, //9910 #CJK UNIFIED IDEOGRAPH + {0xE352, 0x7B90}, //9911 #CJK UNIFIED IDEOGRAPH + {0xE353, 0x7B96}, //9912 #CJK UNIFIED IDEOGRAPH + {0xE354, 0x7B8D}, //9913 #CJK UNIFIED IDEOGRAPH + {0xE355, 0x7B8C}, //9914 #CJK UNIFIED IDEOGRAPH + {0xE356, 0x7B9B}, //9915 #CJK UNIFIED IDEOGRAPH + {0xE357, 0x7B8E}, //9916 #CJK UNIFIED IDEOGRAPH + {0xE358, 0x7B85}, //9917 #CJK UNIFIED IDEOGRAPH + {0xE359, 0x7B98}, //9918 #CJK UNIFIED IDEOGRAPH + {0xE35A, 0x5284}, //9919 #CJK UNIFIED IDEOGRAPH + {0xE35B, 0x7B99}, //9920 #CJK UNIFIED IDEOGRAPH + {0xE35C, 0x7BA4}, //9921 #CJK UNIFIED IDEOGRAPH + {0xE35D, 0x7B82}, //9922 #CJK UNIFIED IDEOGRAPH + {0xE35E, 0x7CBB}, //9923 #CJK UNIFIED IDEOGRAPH + {0xE35F, 0x7CBF}, //9924 #CJK UNIFIED IDEOGRAPH + {0xE360, 0x7CBC}, //9925 #CJK UNIFIED IDEOGRAPH + {0xE361, 0x7CBA}, //9926 #CJK UNIFIED IDEOGRAPH + {0xE362, 0x7DA7}, //9927 #CJK UNIFIED IDEOGRAPH + {0xE363, 0x7DB7}, //9928 #CJK UNIFIED IDEOGRAPH + {0xE364, 0x7DC2}, //9929 #CJK UNIFIED IDEOGRAPH + {0xE365, 0x7DA3}, //9930 #CJK UNIFIED IDEOGRAPH + {0xE366, 0x7DAA}, //9931 #CJK UNIFIED IDEOGRAPH + {0xE367, 0x7DC1}, //9932 #CJK UNIFIED IDEOGRAPH + {0xE368, 0x7DC0}, //9933 #CJK UNIFIED IDEOGRAPH + {0xE369, 0x7DC5}, //9934 #CJK UNIFIED IDEOGRAPH + {0xE36A, 0x7D9D}, //9935 #CJK UNIFIED IDEOGRAPH + {0xE36B, 0x7DCE}, //9936 #CJK UNIFIED IDEOGRAPH + {0xE36C, 0x7DC4}, //9937 #CJK UNIFIED IDEOGRAPH + {0xE36D, 0x7DC6}, //9938 #CJK UNIFIED IDEOGRAPH + {0xE36E, 0x7DCB}, //9939 #CJK UNIFIED IDEOGRAPH + {0xE36F, 0x7DCC}, //9940 #CJK UNIFIED IDEOGRAPH + {0xE370, 0x7DAF}, //9941 #CJK UNIFIED IDEOGRAPH + {0xE371, 0x7DB9}, //9942 #CJK UNIFIED IDEOGRAPH + {0xE372, 0x7D96}, //9943 #CJK UNIFIED IDEOGRAPH + {0xE373, 0x7DBC}, //9944 #CJK UNIFIED IDEOGRAPH + {0xE374, 0x7D9F}, //9945 #CJK UNIFIED IDEOGRAPH + {0xE375, 0x7DA6}, //9946 #CJK UNIFIED IDEOGRAPH + {0xE376, 0x7DAE}, //9947 #CJK UNIFIED IDEOGRAPH + {0xE377, 0x7DA9}, //9948 #CJK UNIFIED IDEOGRAPH + {0xE378, 0x7DA1}, //9949 #CJK UNIFIED IDEOGRAPH + {0xE379, 0x7DC9}, //9950 #CJK UNIFIED IDEOGRAPH + {0xE37A, 0x7F73}, //9951 #CJK UNIFIED IDEOGRAPH + {0xE37B, 0x7FE2}, //9952 #CJK UNIFIED IDEOGRAPH + {0xE37C, 0x7FE3}, //9953 #CJK UNIFIED IDEOGRAPH + {0xE37D, 0x7FE5}, //9954 #CJK UNIFIED IDEOGRAPH + {0xE37E, 0x7FDE}, //9955 #CJK UNIFIED IDEOGRAPH + {0xE3A1, 0x8024}, //9956 #CJK UNIFIED IDEOGRAPH + {0xE3A2, 0x805D}, //9957 #CJK UNIFIED IDEOGRAPH + {0xE3A3, 0x805C}, //9958 #CJK UNIFIED IDEOGRAPH + {0xE3A4, 0x8189}, //9959 #CJK UNIFIED IDEOGRAPH + {0xE3A5, 0x8186}, //9960 #CJK UNIFIED IDEOGRAPH + {0xE3A6, 0x8183}, //9961 #CJK UNIFIED IDEOGRAPH + {0xE3A7, 0x8187}, //9962 #CJK UNIFIED IDEOGRAPH + {0xE3A8, 0x818D}, //9963 #CJK UNIFIED IDEOGRAPH + {0xE3A9, 0x818C}, //9964 #CJK UNIFIED IDEOGRAPH + {0xE3AA, 0x818B}, //9965 #CJK UNIFIED IDEOGRAPH + {0xE3AB, 0x8215}, //9966 #CJK UNIFIED IDEOGRAPH + {0xE3AC, 0x8497}, //9967 #CJK UNIFIED IDEOGRAPH + {0xE3AD, 0x84A4}, //9968 #CJK UNIFIED IDEOGRAPH + {0xE3AE, 0x84A1}, //9969 #CJK UNIFIED IDEOGRAPH + {0xE3AF, 0x849F}, //9970 #CJK UNIFIED IDEOGRAPH + {0xE3B0, 0x84BA}, //9971 #CJK UNIFIED IDEOGRAPH + {0xE3B1, 0x84CE}, //9972 #CJK UNIFIED IDEOGRAPH + {0xE3B2, 0x84C2}, //9973 #CJK UNIFIED IDEOGRAPH + {0xE3B3, 0x84AC}, //9974 #CJK UNIFIED IDEOGRAPH + {0xE3B4, 0x84AE}, //9975 #CJK UNIFIED IDEOGRAPH + {0xE3B5, 0x84AB}, //9976 #CJK UNIFIED IDEOGRAPH + {0xE3B6, 0x84B9}, //9977 #CJK UNIFIED IDEOGRAPH + {0xE3B7, 0x84B4}, //9978 #CJK UNIFIED IDEOGRAPH + {0xE3B8, 0x84C1}, //9979 #CJK UNIFIED IDEOGRAPH + {0xE3B9, 0x84CD}, //9980 #CJK UNIFIED IDEOGRAPH + {0xE3BA, 0x84AA}, //9981 #CJK UNIFIED IDEOGRAPH + {0xE3BB, 0x849A}, //9982 #CJK UNIFIED IDEOGRAPH + {0xE3BC, 0x84B1}, //9983 #CJK UNIFIED IDEOGRAPH + {0xE3BD, 0x84D0}, //9984 #CJK UNIFIED IDEOGRAPH + {0xE3BE, 0x849D}, //9985 #CJK UNIFIED IDEOGRAPH + {0xE3BF, 0x84A7}, //9986 #CJK UNIFIED IDEOGRAPH + {0xE3C0, 0x84BB}, //9987 #CJK UNIFIED IDEOGRAPH + {0xE3C1, 0x84A2}, //9988 #CJK UNIFIED IDEOGRAPH + {0xE3C2, 0x8494}, //9989 #CJK UNIFIED IDEOGRAPH + {0xE3C3, 0x84C7}, //9990 #CJK UNIFIED IDEOGRAPH + {0xE3C4, 0x84CC}, //9991 #CJK UNIFIED IDEOGRAPH + {0xE3C5, 0x849B}, //9992 #CJK UNIFIED IDEOGRAPH + {0xE3C6, 0x84A9}, //9993 #CJK UNIFIED IDEOGRAPH + {0xE3C7, 0x84AF}, //9994 #CJK UNIFIED IDEOGRAPH + {0xE3C8, 0x84A8}, //9995 #CJK UNIFIED IDEOGRAPH + {0xE3C9, 0x84D6}, //9996 #CJK UNIFIED IDEOGRAPH + {0xE3CA, 0x8498}, //9997 #CJK UNIFIED IDEOGRAPH + {0xE3CB, 0x84B6}, //9998 #CJK UNIFIED IDEOGRAPH + {0xE3CC, 0x84CF}, //9999 #CJK UNIFIED IDEOGRAPH + {0xE3CD, 0x84A0}, //10000 #CJK UNIFIED IDEOGRAPH + {0xE3CE, 0x84D7}, //10001 #CJK UNIFIED IDEOGRAPH + {0xE3CF, 0x84D4}, //10002 #CJK UNIFIED IDEOGRAPH + {0xE3D0, 0x84D2}, //10003 #CJK UNIFIED IDEOGRAPH + {0xE3D1, 0x84DB}, //10004 #CJK UNIFIED IDEOGRAPH + {0xE3D2, 0x84B0}, //10005 #CJK UNIFIED IDEOGRAPH + {0xE3D3, 0x8491}, //10006 #CJK UNIFIED IDEOGRAPH + {0xE3D4, 0x8661}, //10007 #CJK UNIFIED IDEOGRAPH + {0xE3D5, 0x8733}, //10008 #CJK UNIFIED IDEOGRAPH + {0xE3D6, 0x8723}, //10009 #CJK UNIFIED IDEOGRAPH + {0xE3D7, 0x8728}, //10010 #CJK UNIFIED IDEOGRAPH + {0xE3D8, 0x876B}, //10011 #CJK UNIFIED IDEOGRAPH + {0xE3D9, 0x8740}, //10012 #CJK UNIFIED IDEOGRAPH + {0xE3DA, 0x872E}, //10013 #CJK UNIFIED IDEOGRAPH + {0xE3DB, 0x871E}, //10014 #CJK UNIFIED IDEOGRAPH + {0xE3DC, 0x8721}, //10015 #CJK UNIFIED IDEOGRAPH + {0xE3DD, 0x8719}, //10016 #CJK UNIFIED IDEOGRAPH + {0xE3DE, 0x871B}, //10017 #CJK UNIFIED IDEOGRAPH + {0xE3DF, 0x8743}, //10018 #CJK UNIFIED IDEOGRAPH + {0xE3E0, 0x872C}, //10019 #CJK UNIFIED IDEOGRAPH + {0xE3E1, 0x8741}, //10020 #CJK UNIFIED IDEOGRAPH + {0xE3E2, 0x873E}, //10021 #CJK UNIFIED IDEOGRAPH + {0xE3E3, 0x8746}, //10022 #CJK UNIFIED IDEOGRAPH + {0xE3E4, 0x8720}, //10023 #CJK UNIFIED IDEOGRAPH + {0xE3E5, 0x8732}, //10024 #CJK UNIFIED IDEOGRAPH + {0xE3E6, 0x872A}, //10025 #CJK UNIFIED IDEOGRAPH + {0xE3E7, 0x872D}, //10026 #CJK UNIFIED IDEOGRAPH + {0xE3E8, 0x873C}, //10027 #CJK UNIFIED IDEOGRAPH + {0xE3E9, 0x8712}, //10028 #CJK UNIFIED IDEOGRAPH + {0xE3EA, 0x873A}, //10029 #CJK UNIFIED IDEOGRAPH + {0xE3EB, 0x8731}, //10030 #CJK UNIFIED IDEOGRAPH + {0xE3EC, 0x8735}, //10031 #CJK UNIFIED IDEOGRAPH + {0xE3ED, 0x8742}, //10032 #CJK UNIFIED IDEOGRAPH + {0xE3EE, 0x8726}, //10033 #CJK UNIFIED IDEOGRAPH + {0xE3EF, 0x8727}, //10034 #CJK UNIFIED IDEOGRAPH + {0xE3F0, 0x8738}, //10035 #CJK UNIFIED IDEOGRAPH + {0xE3F1, 0x8724}, //10036 #CJK UNIFIED IDEOGRAPH + {0xE3F2, 0x871A}, //10037 #CJK UNIFIED IDEOGRAPH + {0xE3F3, 0x8730}, //10038 #CJK UNIFIED IDEOGRAPH + {0xE3F4, 0x8711}, //10039 #CJK UNIFIED IDEOGRAPH + {0xE3F5, 0x88F7}, //10040 #CJK UNIFIED IDEOGRAPH + {0xE3F6, 0x88E7}, //10041 #CJK UNIFIED IDEOGRAPH + {0xE3F7, 0x88F1}, //10042 #CJK UNIFIED IDEOGRAPH + {0xE3F8, 0x88F2}, //10043 #CJK UNIFIED IDEOGRAPH + {0xE3F9, 0x88FA}, //10044 #CJK UNIFIED IDEOGRAPH + {0xE3FA, 0x88FE}, //10045 #CJK UNIFIED IDEOGRAPH + {0xE3FB, 0x88EE}, //10046 #CJK UNIFIED IDEOGRAPH + {0xE3FC, 0x88FC}, //10047 #CJK UNIFIED IDEOGRAPH + {0xE3FD, 0x88F6}, //10048 #CJK UNIFIED IDEOGRAPH + {0xE3FE, 0x88FB}, //10049 #CJK UNIFIED IDEOGRAPH + {0xE440, 0x88F0}, //10050 #CJK UNIFIED IDEOGRAPH + {0xE441, 0x88EC}, //10051 #CJK UNIFIED IDEOGRAPH + {0xE442, 0x88EB}, //10052 #CJK UNIFIED IDEOGRAPH + {0xE443, 0x899D}, //10053 #CJK UNIFIED IDEOGRAPH + {0xE444, 0x89A1}, //10054 #CJK UNIFIED IDEOGRAPH + {0xE445, 0x899F}, //10055 #CJK UNIFIED IDEOGRAPH + {0xE446, 0x899E}, //10056 #CJK UNIFIED IDEOGRAPH + {0xE447, 0x89E9}, //10057 #CJK UNIFIED IDEOGRAPH + {0xE448, 0x89EB}, //10058 #CJK UNIFIED IDEOGRAPH + {0xE449, 0x89E8}, //10059 #CJK UNIFIED IDEOGRAPH + {0xE44A, 0x8AAB}, //10060 #CJK UNIFIED IDEOGRAPH + {0xE44B, 0x8A99}, //10061 #CJK UNIFIED IDEOGRAPH + {0xE44C, 0x8A8B}, //10062 #CJK UNIFIED IDEOGRAPH + {0xE44D, 0x8A92}, //10063 #CJK UNIFIED IDEOGRAPH + {0xE44E, 0x8A8F}, //10064 #CJK UNIFIED IDEOGRAPH + {0xE44F, 0x8A96}, //10065 #CJK UNIFIED IDEOGRAPH + {0xE450, 0x8C3D}, //10066 #CJK UNIFIED IDEOGRAPH + {0xE451, 0x8C68}, //10067 #CJK UNIFIED IDEOGRAPH + {0xE452, 0x8C69}, //10068 #CJK UNIFIED IDEOGRAPH + {0xE453, 0x8CD5}, //10069 #CJK UNIFIED IDEOGRAPH + {0xE454, 0x8CCF}, //10070 #CJK UNIFIED IDEOGRAPH + {0xE455, 0x8CD7}, //10071 #CJK UNIFIED IDEOGRAPH + {0xE456, 0x8D96}, //10072 #CJK UNIFIED IDEOGRAPH + {0xE457, 0x8E09}, //10073 #CJK UNIFIED IDEOGRAPH + {0xE458, 0x8E02}, //10074 #CJK UNIFIED IDEOGRAPH + {0xE459, 0x8DFF}, //10075 #CJK UNIFIED IDEOGRAPH + {0xE45A, 0x8E0D}, //10076 #CJK UNIFIED IDEOGRAPH + {0xE45B, 0x8DFD}, //10077 #CJK UNIFIED IDEOGRAPH + {0xE45C, 0x8E0A}, //10078 #CJK UNIFIED IDEOGRAPH + {0xE45D, 0x8E03}, //10079 #CJK UNIFIED IDEOGRAPH + {0xE45E, 0x8E07}, //10080 #CJK UNIFIED IDEOGRAPH + {0xE45F, 0x8E06}, //10081 #CJK UNIFIED IDEOGRAPH + {0xE460, 0x8E05}, //10082 #CJK UNIFIED IDEOGRAPH + {0xE461, 0x8DFE}, //10083 #CJK UNIFIED IDEOGRAPH + {0xE462, 0x8E00}, //10084 #CJK UNIFIED IDEOGRAPH + {0xE463, 0x8E04}, //10085 #CJK UNIFIED IDEOGRAPH + {0xE464, 0x8F10}, //10086 #CJK UNIFIED IDEOGRAPH + {0xE465, 0x8F11}, //10087 #CJK UNIFIED IDEOGRAPH + {0xE466, 0x8F0E}, //10088 #CJK UNIFIED IDEOGRAPH + {0xE467, 0x8F0D}, //10089 #CJK UNIFIED IDEOGRAPH + {0xE468, 0x9123}, //10090 #CJK UNIFIED IDEOGRAPH + {0xE469, 0x911C}, //10091 #CJK UNIFIED IDEOGRAPH + {0xE46A, 0x9120}, //10092 #CJK UNIFIED IDEOGRAPH + {0xE46B, 0x9122}, //10093 #CJK UNIFIED IDEOGRAPH + {0xE46C, 0x911F}, //10094 #CJK UNIFIED IDEOGRAPH + {0xE46D, 0x911D}, //10095 #CJK UNIFIED IDEOGRAPH + {0xE46E, 0x911A}, //10096 #CJK UNIFIED IDEOGRAPH + {0xE46F, 0x9124}, //10097 #CJK UNIFIED IDEOGRAPH + {0xE470, 0x9121}, //10098 #CJK UNIFIED IDEOGRAPH + {0xE471, 0x911B}, //10099 #CJK UNIFIED IDEOGRAPH + {0xE472, 0x917A}, //10100 #CJK UNIFIED IDEOGRAPH + {0xE473, 0x9172}, //10101 #CJK UNIFIED IDEOGRAPH + {0xE474, 0x9179}, //10102 #CJK UNIFIED IDEOGRAPH + {0xE475, 0x9173}, //10103 #CJK UNIFIED IDEOGRAPH + {0xE476, 0x92A5}, //10104 #CJK UNIFIED IDEOGRAPH + {0xE477, 0x92A4}, //10105 #CJK UNIFIED IDEOGRAPH + {0xE478, 0x9276}, //10106 #CJK UNIFIED IDEOGRAPH + {0xE479, 0x929B}, //10107 #CJK UNIFIED IDEOGRAPH + {0xE47A, 0x927A}, //10108 #CJK UNIFIED IDEOGRAPH + {0xE47B, 0x92A0}, //10109 #CJK UNIFIED IDEOGRAPH + {0xE47C, 0x9294}, //10110 #CJK UNIFIED IDEOGRAPH + {0xE47D, 0x92AA}, //10111 #CJK UNIFIED IDEOGRAPH + {0xE47E, 0x928D}, //10112 #CJK UNIFIED IDEOGRAPH + {0xE4A1, 0x92A6}, //10113 #CJK UNIFIED IDEOGRAPH + {0xE4A2, 0x929A}, //10114 #CJK UNIFIED IDEOGRAPH + {0xE4A3, 0x92AB}, //10115 #CJK UNIFIED IDEOGRAPH + {0xE4A4, 0x9279}, //10116 #CJK UNIFIED IDEOGRAPH + {0xE4A5, 0x9297}, //10117 #CJK UNIFIED IDEOGRAPH + {0xE4A6, 0x927F}, //10118 #CJK UNIFIED IDEOGRAPH + {0xE4A7, 0x92A3}, //10119 #CJK UNIFIED IDEOGRAPH + {0xE4A8, 0x92EE}, //10120 #CJK UNIFIED IDEOGRAPH + {0xE4A9, 0x928E}, //10121 #CJK UNIFIED IDEOGRAPH + {0xE4AA, 0x9282}, //10122 #CJK UNIFIED IDEOGRAPH + {0xE4AB, 0x9295}, //10123 #CJK UNIFIED IDEOGRAPH + {0xE4AC, 0x92A2}, //10124 #CJK UNIFIED IDEOGRAPH + {0xE4AD, 0x927D}, //10125 #CJK UNIFIED IDEOGRAPH + {0xE4AE, 0x9288}, //10126 #CJK UNIFIED IDEOGRAPH + {0xE4AF, 0x92A1}, //10127 #CJK UNIFIED IDEOGRAPH + {0xE4B0, 0x928A}, //10128 #CJK UNIFIED IDEOGRAPH + {0xE4B1, 0x9286}, //10129 #CJK UNIFIED IDEOGRAPH + {0xE4B2, 0x928C}, //10130 #CJK UNIFIED IDEOGRAPH + {0xE4B3, 0x9299}, //10131 #CJK UNIFIED IDEOGRAPH + {0xE4B4, 0x92A7}, //10132 #CJK UNIFIED IDEOGRAPH + {0xE4B5, 0x927E}, //10133 #CJK UNIFIED IDEOGRAPH + {0xE4B6, 0x9287}, //10134 #CJK UNIFIED IDEOGRAPH + {0xE4B7, 0x92A9}, //10135 #CJK UNIFIED IDEOGRAPH + {0xE4B8, 0x929D}, //10136 #CJK UNIFIED IDEOGRAPH + {0xE4B9, 0x928B}, //10137 #CJK UNIFIED IDEOGRAPH + {0xE4BA, 0x922D}, //10138 #CJK UNIFIED IDEOGRAPH + {0xE4BB, 0x969E}, //10139 #CJK UNIFIED IDEOGRAPH + {0xE4BC, 0x96A1}, //10140 #CJK UNIFIED IDEOGRAPH + {0xE4BD, 0x96FF}, //10141 #CJK UNIFIED IDEOGRAPH + {0xE4BE, 0x9758}, //10142 #CJK UNIFIED IDEOGRAPH + {0xE4BF, 0x977D}, //10143 #CJK UNIFIED IDEOGRAPH + {0xE4C0, 0x977A}, //10144 #CJK UNIFIED IDEOGRAPH + {0xE4C1, 0x977E}, //10145 #CJK UNIFIED IDEOGRAPH + {0xE4C2, 0x9783}, //10146 #CJK UNIFIED IDEOGRAPH + {0xE4C3, 0x9780}, //10147 #CJK UNIFIED IDEOGRAPH + {0xE4C4, 0x9782}, //10148 #CJK UNIFIED IDEOGRAPH + {0xE4C5, 0x977B}, //10149 #CJK UNIFIED IDEOGRAPH + {0xE4C6, 0x9784}, //10150 #CJK UNIFIED IDEOGRAPH + {0xE4C7, 0x9781}, //10151 #CJK UNIFIED IDEOGRAPH + {0xE4C8, 0x977F}, //10152 #CJK UNIFIED IDEOGRAPH + {0xE4C9, 0x97CE}, //10153 #CJK UNIFIED IDEOGRAPH + {0xE4CA, 0x97CD}, //10154 #CJK UNIFIED IDEOGRAPH + {0xE4CB, 0x9816}, //10155 #CJK UNIFIED IDEOGRAPH + {0xE4CC, 0x98AD}, //10156 #CJK UNIFIED IDEOGRAPH + {0xE4CD, 0x98AE}, //10157 #CJK UNIFIED IDEOGRAPH + {0xE4CE, 0x9902}, //10158 #CJK UNIFIED IDEOGRAPH + {0xE4CF, 0x9900}, //10159 #CJK UNIFIED IDEOGRAPH + {0xE4D0, 0x9907}, //10160 #CJK UNIFIED IDEOGRAPH + {0xE4D1, 0x999D}, //10161 #CJK UNIFIED IDEOGRAPH + {0xE4D2, 0x999C}, //10162 #CJK UNIFIED IDEOGRAPH + {0xE4D3, 0x99C3}, //10163 #CJK UNIFIED IDEOGRAPH + {0xE4D4, 0x99B9}, //10164 #CJK UNIFIED IDEOGRAPH + {0xE4D5, 0x99BB}, //10165 #CJK UNIFIED IDEOGRAPH + {0xE4D6, 0x99BA}, //10166 #CJK UNIFIED IDEOGRAPH + {0xE4D7, 0x99C2}, //10167 #CJK UNIFIED IDEOGRAPH + {0xE4D8, 0x99BD}, //10168 #CJK UNIFIED IDEOGRAPH + {0xE4D9, 0x99C7}, //10169 #CJK UNIFIED IDEOGRAPH + {0xE4DA, 0x9AB1}, //10170 #CJK UNIFIED IDEOGRAPH + {0xE4DB, 0x9AE3}, //10171 #CJK UNIFIED IDEOGRAPH + {0xE4DC, 0x9AE7}, //10172 #CJK UNIFIED IDEOGRAPH + {0xE4DD, 0x9B3E}, //10173 #CJK UNIFIED IDEOGRAPH + {0xE4DE, 0x9B3F}, //10174 #CJK UNIFIED IDEOGRAPH + {0xE4DF, 0x9B60}, //10175 #CJK UNIFIED IDEOGRAPH + {0xE4E0, 0x9B61}, //10176 #CJK UNIFIED IDEOGRAPH + {0xE4E1, 0x9B5F}, //10177 #CJK UNIFIED IDEOGRAPH + {0xE4E2, 0x9CF1}, //10178 #CJK UNIFIED IDEOGRAPH + {0xE4E3, 0x9CF2}, //10179 #CJK UNIFIED IDEOGRAPH + {0xE4E4, 0x9CF5}, //10180 #CJK UNIFIED IDEOGRAPH + {0xE4E5, 0x9EA7}, //10181 #CJK UNIFIED IDEOGRAPH + {0xE4E6, 0x50FF}, //10182 #CJK UNIFIED IDEOGRAPH + {0xE4E7, 0x5103}, //10183 #CJK UNIFIED IDEOGRAPH + {0xE4E8, 0x5130}, //10184 #CJK UNIFIED IDEOGRAPH + {0xE4E9, 0x50F8}, //10185 #CJK UNIFIED IDEOGRAPH + {0xE4EA, 0x5106}, //10186 #CJK UNIFIED IDEOGRAPH + {0xE4EB, 0x5107}, //10187 #CJK UNIFIED IDEOGRAPH + {0xE4EC, 0x50F6}, //10188 #CJK UNIFIED IDEOGRAPH + {0xE4ED, 0x50FE}, //10189 #CJK UNIFIED IDEOGRAPH + {0xE4EE, 0x510B}, //10190 #CJK UNIFIED IDEOGRAPH + {0xE4EF, 0x510C}, //10191 #CJK UNIFIED IDEOGRAPH + {0xE4F0, 0x50FD}, //10192 #CJK UNIFIED IDEOGRAPH + {0xE4F1, 0x510A}, //10193 #CJK UNIFIED IDEOGRAPH + {0xE4F2, 0x528B}, //10194 #CJK UNIFIED IDEOGRAPH + {0xE4F3, 0x528C}, //10195 #CJK UNIFIED IDEOGRAPH + {0xE4F4, 0x52F1}, //10196 #CJK UNIFIED IDEOGRAPH + {0xE4F5, 0x52EF}, //10197 #CJK UNIFIED IDEOGRAPH + {0xE4F6, 0x5648}, //10198 #CJK UNIFIED IDEOGRAPH + {0xE4F7, 0x5642}, //10199 #CJK UNIFIED IDEOGRAPH + {0xE4F8, 0x564C}, //10200 #CJK UNIFIED IDEOGRAPH + {0xE4F9, 0x5635}, //10201 #CJK UNIFIED IDEOGRAPH + {0xE4FA, 0x5641}, //10202 #CJK UNIFIED IDEOGRAPH + {0xE4FB, 0x564A}, //10203 #CJK UNIFIED IDEOGRAPH + {0xE4FC, 0x5649}, //10204 #CJK UNIFIED IDEOGRAPH + {0xE4FD, 0x5646}, //10205 #CJK UNIFIED IDEOGRAPH + {0xE4FE, 0x5658}, //10206 #CJK UNIFIED IDEOGRAPH + {0xE540, 0x565A}, //10207 #CJK UNIFIED IDEOGRAPH + {0xE541, 0x5640}, //10208 #CJK UNIFIED IDEOGRAPH + {0xE542, 0x5633}, //10209 #CJK UNIFIED IDEOGRAPH + {0xE543, 0x563D}, //10210 #CJK UNIFIED IDEOGRAPH + {0xE544, 0x562C}, //10211 #CJK UNIFIED IDEOGRAPH + {0xE545, 0x563E}, //10212 #CJK UNIFIED IDEOGRAPH + {0xE546, 0x5638}, //10213 #CJK UNIFIED IDEOGRAPH + {0xE547, 0x562A}, //10214 #CJK UNIFIED IDEOGRAPH + {0xE548, 0x563A}, //10215 #CJK UNIFIED IDEOGRAPH + {0xE549, 0x571A}, //10216 #CJK UNIFIED IDEOGRAPH + {0xE54A, 0x58AB}, //10217 #CJK UNIFIED IDEOGRAPH + {0xE54B, 0x589D}, //10218 #CJK UNIFIED IDEOGRAPH + {0xE54C, 0x58B1}, //10219 #CJK UNIFIED IDEOGRAPH + {0xE54D, 0x58A0}, //10220 #CJK UNIFIED IDEOGRAPH + {0xE54E, 0x58A3}, //10221 #CJK UNIFIED IDEOGRAPH + {0xE54F, 0x58AF}, //10222 #CJK UNIFIED IDEOGRAPH + {0xE550, 0x58AC}, //10223 #CJK UNIFIED IDEOGRAPH + {0xE551, 0x58A5}, //10224 #CJK UNIFIED IDEOGRAPH + {0xE552, 0x58A1}, //10225 #CJK UNIFIED IDEOGRAPH + {0xE553, 0x58FF}, //10226 #CJK UNIFIED IDEOGRAPH + {0xE554, 0x5AFF}, //10227 #CJK UNIFIED IDEOGRAPH + {0xE555, 0x5AF4}, //10228 #CJK UNIFIED IDEOGRAPH + {0xE556, 0x5AFD}, //10229 #CJK UNIFIED IDEOGRAPH + {0xE557, 0x5AF7}, //10230 #CJK UNIFIED IDEOGRAPH + {0xE558, 0x5AF6}, //10231 #CJK UNIFIED IDEOGRAPH + {0xE559, 0x5B03}, //10232 #CJK UNIFIED IDEOGRAPH + {0xE55A, 0x5AF8}, //10233 #CJK UNIFIED IDEOGRAPH + {0xE55B, 0x5B02}, //10234 #CJK UNIFIED IDEOGRAPH + {0xE55C, 0x5AF9}, //10235 #CJK UNIFIED IDEOGRAPH + {0xE55D, 0x5B01}, //10236 #CJK UNIFIED IDEOGRAPH + {0xE55E, 0x5B07}, //10237 #CJK UNIFIED IDEOGRAPH + {0xE55F, 0x5B05}, //10238 #CJK UNIFIED IDEOGRAPH + {0xE560, 0x5B0F}, //10239 #CJK UNIFIED IDEOGRAPH + {0xE561, 0x5C67}, //10240 #CJK UNIFIED IDEOGRAPH + {0xE562, 0x5D99}, //10241 #CJK UNIFIED IDEOGRAPH + {0xE563, 0x5D97}, //10242 #CJK UNIFIED IDEOGRAPH + {0xE564, 0x5D9F}, //10243 #CJK UNIFIED IDEOGRAPH + {0xE565, 0x5D92}, //10244 #CJK UNIFIED IDEOGRAPH + {0xE566, 0x5DA2}, //10245 #CJK UNIFIED IDEOGRAPH + {0xE567, 0x5D93}, //10246 #CJK UNIFIED IDEOGRAPH + {0xE568, 0x5D95}, //10247 #CJK UNIFIED IDEOGRAPH + {0xE569, 0x5DA0}, //10248 #CJK UNIFIED IDEOGRAPH + {0xE56A, 0x5D9C}, //10249 #CJK UNIFIED IDEOGRAPH + {0xE56B, 0x5DA1}, //10250 #CJK UNIFIED IDEOGRAPH + {0xE56C, 0x5D9A}, //10251 #CJK UNIFIED IDEOGRAPH + {0xE56D, 0x5D9E}, //10252 #CJK UNIFIED IDEOGRAPH + {0xE56E, 0x5E69}, //10253 #CJK UNIFIED IDEOGRAPH + {0xE56F, 0x5E5D}, //10254 #CJK UNIFIED IDEOGRAPH + {0xE570, 0x5E60}, //10255 #CJK UNIFIED IDEOGRAPH + {0xE571, 0x5E5C}, //10256 #CJK UNIFIED IDEOGRAPH + {0xE572, 0x7DF3}, //10257 #CJK UNIFIED IDEOGRAPH + {0xE573, 0x5EDB}, //10258 #CJK UNIFIED IDEOGRAPH + {0xE574, 0x5EDE}, //10259 #CJK UNIFIED IDEOGRAPH + {0xE575, 0x5EE1}, //10260 #CJK UNIFIED IDEOGRAPH + {0xE576, 0x5F49}, //10261 #CJK UNIFIED IDEOGRAPH + {0xE577, 0x5FB2}, //10262 #CJK UNIFIED IDEOGRAPH + {0xE578, 0x618B}, //10263 #CJK UNIFIED IDEOGRAPH + {0xE579, 0x6183}, //10264 #CJK UNIFIED IDEOGRAPH + {0xE57A, 0x6179}, //10265 #CJK UNIFIED IDEOGRAPH + {0xE57B, 0x61B1}, //10266 #CJK UNIFIED IDEOGRAPH + {0xE57C, 0x61B0}, //10267 #CJK UNIFIED IDEOGRAPH + {0xE57D, 0x61A2}, //10268 #CJK UNIFIED IDEOGRAPH + {0xE57E, 0x6189}, //10269 #CJK UNIFIED IDEOGRAPH + {0xE5A1, 0x619B}, //10270 #CJK UNIFIED IDEOGRAPH + {0xE5A2, 0x6193}, //10271 #CJK UNIFIED IDEOGRAPH + {0xE5A3, 0x61AF}, //10272 #CJK UNIFIED IDEOGRAPH + {0xE5A4, 0x61AD}, //10273 #CJK UNIFIED IDEOGRAPH + {0xE5A5, 0x619F}, //10274 #CJK UNIFIED IDEOGRAPH + {0xE5A6, 0x6192}, //10275 #CJK UNIFIED IDEOGRAPH + {0xE5A7, 0x61AA}, //10276 #CJK UNIFIED IDEOGRAPH + {0xE5A8, 0x61A1}, //10277 #CJK UNIFIED IDEOGRAPH + {0xE5A9, 0x618D}, //10278 #CJK UNIFIED IDEOGRAPH + {0xE5AA, 0x6166}, //10279 #CJK UNIFIED IDEOGRAPH + {0xE5AB, 0x61B3}, //10280 #CJK UNIFIED IDEOGRAPH + {0xE5AC, 0x622D}, //10281 #CJK UNIFIED IDEOGRAPH + {0xE5AD, 0x646E}, //10282 #CJK UNIFIED IDEOGRAPH + {0xE5AE, 0x6470}, //10283 #CJK UNIFIED IDEOGRAPH + {0xE5AF, 0x6496}, //10284 #CJK UNIFIED IDEOGRAPH + {0xE5B0, 0x64A0}, //10285 #CJK UNIFIED IDEOGRAPH + {0xE5B1, 0x6485}, //10286 #CJK UNIFIED IDEOGRAPH + {0xE5B2, 0x6497}, //10287 #CJK UNIFIED IDEOGRAPH + {0xE5B3, 0x649C}, //10288 #CJK UNIFIED IDEOGRAPH + {0xE5B4, 0x648F}, //10289 #CJK UNIFIED IDEOGRAPH + {0xE5B5, 0x648B}, //10290 #CJK UNIFIED IDEOGRAPH + {0xE5B6, 0x648A}, //10291 #CJK UNIFIED IDEOGRAPH + {0xE5B7, 0x648C}, //10292 #CJK UNIFIED IDEOGRAPH + {0xE5B8, 0x64A3}, //10293 #CJK UNIFIED IDEOGRAPH + {0xE5B9, 0x649F}, //10294 #CJK UNIFIED IDEOGRAPH + {0xE5BA, 0x6468}, //10295 #CJK UNIFIED IDEOGRAPH + {0xE5BB, 0x64B1}, //10296 #CJK UNIFIED IDEOGRAPH + {0xE5BC, 0x6498}, //10297 #CJK UNIFIED IDEOGRAPH + {0xE5BD, 0x6576}, //10298 #CJK UNIFIED IDEOGRAPH + {0xE5BE, 0x657A}, //10299 #CJK UNIFIED IDEOGRAPH + {0xE5BF, 0x6579}, //10300 #CJK UNIFIED IDEOGRAPH + {0xE5C0, 0x657B}, //10301 #CJK UNIFIED IDEOGRAPH + {0xE5C1, 0x65B2}, //10302 #CJK UNIFIED IDEOGRAPH + {0xE5C2, 0x65B3}, //10303 #CJK UNIFIED IDEOGRAPH + {0xE5C3, 0x66B5}, //10304 #CJK UNIFIED IDEOGRAPH + {0xE5C4, 0x66B0}, //10305 #CJK UNIFIED IDEOGRAPH + {0xE5C5, 0x66A9}, //10306 #CJK UNIFIED IDEOGRAPH + {0xE5C6, 0x66B2}, //10307 #CJK UNIFIED IDEOGRAPH + {0xE5C7, 0x66B7}, //10308 #CJK UNIFIED IDEOGRAPH + {0xE5C8, 0x66AA}, //10309 #CJK UNIFIED IDEOGRAPH + {0xE5C9, 0x66AF}, //10310 #CJK UNIFIED IDEOGRAPH + {0xE5CA, 0x6A00}, //10311 #CJK UNIFIED IDEOGRAPH + {0xE5CB, 0x6A06}, //10312 #CJK UNIFIED IDEOGRAPH + {0xE5CC, 0x6A17}, //10313 #CJK UNIFIED IDEOGRAPH + {0xE5CD, 0x69E5}, //10314 #CJK UNIFIED IDEOGRAPH + {0xE5CE, 0x69F8}, //10315 #CJK UNIFIED IDEOGRAPH + {0xE5CF, 0x6A15}, //10316 #CJK UNIFIED IDEOGRAPH + {0xE5D0, 0x69F1}, //10317 #CJK UNIFIED IDEOGRAPH + {0xE5D1, 0x69E4}, //10318 #CJK UNIFIED IDEOGRAPH + {0xE5D2, 0x6A20}, //10319 #CJK UNIFIED IDEOGRAPH + {0xE5D3, 0x69FF}, //10320 #CJK UNIFIED IDEOGRAPH + {0xE5D4, 0x69EC}, //10321 #CJK UNIFIED IDEOGRAPH + {0xE5D5, 0x69E2}, //10322 #CJK UNIFIED IDEOGRAPH + {0xE5D6, 0x6A1B}, //10323 #CJK UNIFIED IDEOGRAPH + {0xE5D7, 0x6A1D}, //10324 #CJK UNIFIED IDEOGRAPH + {0xE5D8, 0x69FE}, //10325 #CJK UNIFIED IDEOGRAPH + {0xE5D9, 0x6A27}, //10326 #CJK UNIFIED IDEOGRAPH + {0xE5DA, 0x69F2}, //10327 #CJK UNIFIED IDEOGRAPH + {0xE5DB, 0x69EE}, //10328 #CJK UNIFIED IDEOGRAPH + {0xE5DC, 0x6A14}, //10329 #CJK UNIFIED IDEOGRAPH + {0xE5DD, 0x69F7}, //10330 #CJK UNIFIED IDEOGRAPH + {0xE5DE, 0x69E7}, //10331 #CJK UNIFIED IDEOGRAPH + {0xE5DF, 0x6A40}, //10332 #CJK UNIFIED IDEOGRAPH + {0xE5E0, 0x6A08}, //10333 #CJK UNIFIED IDEOGRAPH + {0xE5E1, 0x69E6}, //10334 #CJK UNIFIED IDEOGRAPH + {0xE5E2, 0x69FB}, //10335 #CJK UNIFIED IDEOGRAPH + {0xE5E3, 0x6A0D}, //10336 #CJK UNIFIED IDEOGRAPH + {0xE5E4, 0x69FC}, //10337 #CJK UNIFIED IDEOGRAPH + {0xE5E5, 0x69EB}, //10338 #CJK UNIFIED IDEOGRAPH + {0xE5E6, 0x6A09}, //10339 #CJK UNIFIED IDEOGRAPH + {0xE5E7, 0x6A04}, //10340 #CJK UNIFIED IDEOGRAPH + {0xE5E8, 0x6A18}, //10341 #CJK UNIFIED IDEOGRAPH + {0xE5E9, 0x6A25}, //10342 #CJK UNIFIED IDEOGRAPH + {0xE5EA, 0x6A0F}, //10343 #CJK UNIFIED IDEOGRAPH + {0xE5EB, 0x69F6}, //10344 #CJK UNIFIED IDEOGRAPH + {0xE5EC, 0x6A26}, //10345 #CJK UNIFIED IDEOGRAPH + {0xE5ED, 0x6A07}, //10346 #CJK UNIFIED IDEOGRAPH + {0xE5EE, 0x69F4}, //10347 #CJK UNIFIED IDEOGRAPH + {0xE5EF, 0x6A16}, //10348 #CJK UNIFIED IDEOGRAPH + {0xE5F0, 0x6B51}, //10349 #CJK UNIFIED IDEOGRAPH + {0xE5F1, 0x6BA5}, //10350 #CJK UNIFIED IDEOGRAPH + {0xE5F2, 0x6BA3}, //10351 #CJK UNIFIED IDEOGRAPH + {0xE5F3, 0x6BA2}, //10352 #CJK UNIFIED IDEOGRAPH + {0xE5F4, 0x6BA6}, //10353 #CJK UNIFIED IDEOGRAPH + {0xE5F5, 0x6C01}, //10354 #CJK UNIFIED IDEOGRAPH + {0xE5F6, 0x6C00}, //10355 #CJK UNIFIED IDEOGRAPH + {0xE5F7, 0x6BFF}, //10356 #CJK UNIFIED IDEOGRAPH + {0xE5F8, 0x6C02}, //10357 #CJK UNIFIED IDEOGRAPH + {0xE5F9, 0x6F41}, //10358 #CJK UNIFIED IDEOGRAPH + {0xE5FA, 0x6F26}, //10359 #CJK UNIFIED IDEOGRAPH + {0xE5FB, 0x6F7E}, //10360 #CJK UNIFIED IDEOGRAPH + {0xE5FC, 0x6F87}, //10361 #CJK UNIFIED IDEOGRAPH + {0xE5FD, 0x6FC6}, //10362 #CJK UNIFIED IDEOGRAPH + {0xE5FE, 0x6F92}, //10363 #CJK UNIFIED IDEOGRAPH + {0xE640, 0x6F8D}, //10364 #CJK UNIFIED IDEOGRAPH + {0xE641, 0x6F89}, //10365 #CJK UNIFIED IDEOGRAPH + {0xE642, 0x6F8C}, //10366 #CJK UNIFIED IDEOGRAPH + {0xE643, 0x6F62}, //10367 #CJK UNIFIED IDEOGRAPH + {0xE644, 0x6F4F}, //10368 #CJK UNIFIED IDEOGRAPH + {0xE645, 0x6F85}, //10369 #CJK UNIFIED IDEOGRAPH + {0xE646, 0x6F5A}, //10370 #CJK UNIFIED IDEOGRAPH + {0xE647, 0x6F96}, //10371 #CJK UNIFIED IDEOGRAPH + {0xE648, 0x6F76}, //10372 #CJK UNIFIED IDEOGRAPH + {0xE649, 0x6F6C}, //10373 #CJK UNIFIED IDEOGRAPH + {0xE64A, 0x6F82}, //10374 #CJK UNIFIED IDEOGRAPH + {0xE64B, 0x6F55}, //10375 #CJK UNIFIED IDEOGRAPH + {0xE64C, 0x6F72}, //10376 #CJK UNIFIED IDEOGRAPH + {0xE64D, 0x6F52}, //10377 #CJK UNIFIED IDEOGRAPH + {0xE64E, 0x6F50}, //10378 #CJK UNIFIED IDEOGRAPH + {0xE64F, 0x6F57}, //10379 #CJK UNIFIED IDEOGRAPH + {0xE650, 0x6F94}, //10380 #CJK UNIFIED IDEOGRAPH + {0xE651, 0x6F93}, //10381 #CJK UNIFIED IDEOGRAPH + {0xE652, 0x6F5D}, //10382 #CJK UNIFIED IDEOGRAPH + {0xE653, 0x6F00}, //10383 #CJK UNIFIED IDEOGRAPH + {0xE654, 0x6F61}, //10384 #CJK UNIFIED IDEOGRAPH + {0xE655, 0x6F6B}, //10385 #CJK UNIFIED IDEOGRAPH + {0xE656, 0x6F7D}, //10386 #CJK UNIFIED IDEOGRAPH + {0xE657, 0x6F67}, //10387 #CJK UNIFIED IDEOGRAPH + {0xE658, 0x6F90}, //10388 #CJK UNIFIED IDEOGRAPH + {0xE659, 0x6F53}, //10389 #CJK UNIFIED IDEOGRAPH + {0xE65A, 0x6F8B}, //10390 #CJK UNIFIED IDEOGRAPH + {0xE65B, 0x6F69}, //10391 #CJK UNIFIED IDEOGRAPH + {0xE65C, 0x6F7F}, //10392 #CJK UNIFIED IDEOGRAPH + {0xE65D, 0x6F95}, //10393 #CJK UNIFIED IDEOGRAPH + {0xE65E, 0x6F63}, //10394 #CJK UNIFIED IDEOGRAPH + {0xE65F, 0x6F77}, //10395 #CJK UNIFIED IDEOGRAPH + {0xE660, 0x6F6A}, //10396 #CJK UNIFIED IDEOGRAPH + {0xE661, 0x6F7B}, //10397 #CJK UNIFIED IDEOGRAPH + {0xE662, 0x71B2}, //10398 #CJK UNIFIED IDEOGRAPH + {0xE663, 0x71AF}, //10399 #CJK UNIFIED IDEOGRAPH + {0xE664, 0x719B}, //10400 #CJK UNIFIED IDEOGRAPH + {0xE665, 0x71B0}, //10401 #CJK UNIFIED IDEOGRAPH + {0xE666, 0x71A0}, //10402 #CJK UNIFIED IDEOGRAPH + {0xE667, 0x719A}, //10403 #CJK UNIFIED IDEOGRAPH + {0xE668, 0x71A9}, //10404 #CJK UNIFIED IDEOGRAPH + {0xE669, 0x71B5}, //10405 #CJK UNIFIED IDEOGRAPH + {0xE66A, 0x719D}, //10406 #CJK UNIFIED IDEOGRAPH + {0xE66B, 0x71A5}, //10407 #CJK UNIFIED IDEOGRAPH + {0xE66C, 0x719E}, //10408 #CJK UNIFIED IDEOGRAPH + {0xE66D, 0x71A4}, //10409 #CJK UNIFIED IDEOGRAPH + {0xE66E, 0x71A1}, //10410 #CJK UNIFIED IDEOGRAPH + {0xE66F, 0x71AA}, //10411 #CJK UNIFIED IDEOGRAPH + {0xE670, 0x719C}, //10412 #CJK UNIFIED IDEOGRAPH + {0xE671, 0x71A7}, //10413 #CJK UNIFIED IDEOGRAPH + {0xE672, 0x71B3}, //10414 #CJK UNIFIED IDEOGRAPH + {0xE673, 0x7298}, //10415 #CJK UNIFIED IDEOGRAPH + {0xE674, 0x729A}, //10416 #CJK UNIFIED IDEOGRAPH + {0xE675, 0x7358}, //10417 #CJK UNIFIED IDEOGRAPH + {0xE676, 0x7352}, //10418 #CJK UNIFIED IDEOGRAPH + {0xE677, 0x735E}, //10419 #CJK UNIFIED IDEOGRAPH + {0xE678, 0x735F}, //10420 #CJK UNIFIED IDEOGRAPH + {0xE679, 0x7360}, //10421 #CJK UNIFIED IDEOGRAPH + {0xE67A, 0x735D}, //10422 #CJK UNIFIED IDEOGRAPH + {0xE67B, 0x735B}, //10423 #CJK UNIFIED IDEOGRAPH + {0xE67C, 0x7361}, //10424 #CJK UNIFIED IDEOGRAPH + {0xE67D, 0x735A}, //10425 #CJK UNIFIED IDEOGRAPH + {0xE67E, 0x7359}, //10426 #CJK UNIFIED IDEOGRAPH + {0xE6A1, 0x7362}, //10427 #CJK UNIFIED IDEOGRAPH + {0xE6A2, 0x7487}, //10428 #CJK UNIFIED IDEOGRAPH + {0xE6A3, 0x7489}, //10429 #CJK UNIFIED IDEOGRAPH + {0xE6A4, 0x748A}, //10430 #CJK UNIFIED IDEOGRAPH + {0xE6A5, 0x7486}, //10431 #CJK UNIFIED IDEOGRAPH + {0xE6A6, 0x7481}, //10432 #CJK UNIFIED IDEOGRAPH + {0xE6A7, 0x747D}, //10433 #CJK UNIFIED IDEOGRAPH + {0xE6A8, 0x7485}, //10434 #CJK UNIFIED IDEOGRAPH + {0xE6A9, 0x7488}, //10435 #CJK UNIFIED IDEOGRAPH + {0xE6AA, 0x747C}, //10436 #CJK UNIFIED IDEOGRAPH + {0xE6AB, 0x7479}, //10437 #CJK UNIFIED IDEOGRAPH + {0xE6AC, 0x7508}, //10438 #CJK UNIFIED IDEOGRAPH + {0xE6AD, 0x7507}, //10439 #CJK UNIFIED IDEOGRAPH + {0xE6AE, 0x757E}, //10440 #CJK UNIFIED IDEOGRAPH + {0xE6AF, 0x7625}, //10441 #CJK UNIFIED IDEOGRAPH + {0xE6B0, 0x761E}, //10442 #CJK UNIFIED IDEOGRAPH + {0xE6B1, 0x7619}, //10443 #CJK UNIFIED IDEOGRAPH + {0xE6B2, 0x761D}, //10444 #CJK UNIFIED IDEOGRAPH + {0xE6B3, 0x761C}, //10445 #CJK UNIFIED IDEOGRAPH + {0xE6B4, 0x7623}, //10446 #CJK UNIFIED IDEOGRAPH + {0xE6B5, 0x761A}, //10447 #CJK UNIFIED IDEOGRAPH + {0xE6B6, 0x7628}, //10448 #CJK UNIFIED IDEOGRAPH + {0xE6B7, 0x761B}, //10449 #CJK UNIFIED IDEOGRAPH + {0xE6B8, 0x769C}, //10450 #CJK UNIFIED IDEOGRAPH + {0xE6B9, 0x769D}, //10451 #CJK UNIFIED IDEOGRAPH + {0xE6BA, 0x769E}, //10452 #CJK UNIFIED IDEOGRAPH + {0xE6BB, 0x769B}, //10453 #CJK UNIFIED IDEOGRAPH + {0xE6BC, 0x778D}, //10454 #CJK UNIFIED IDEOGRAPH + {0xE6BD, 0x778F}, //10455 #CJK UNIFIED IDEOGRAPH + {0xE6BE, 0x7789}, //10456 #CJK UNIFIED IDEOGRAPH + {0xE6BF, 0x7788}, //10457 #CJK UNIFIED IDEOGRAPH + {0xE6C0, 0x78CD}, //10458 #CJK UNIFIED IDEOGRAPH + {0xE6C1, 0x78BB}, //10459 #CJK UNIFIED IDEOGRAPH + {0xE6C2, 0x78CF}, //10460 #CJK UNIFIED IDEOGRAPH + {0xE6C3, 0x78CC}, //10461 #CJK UNIFIED IDEOGRAPH + {0xE6C4, 0x78D1}, //10462 #CJK UNIFIED IDEOGRAPH + {0xE6C5, 0x78CE}, //10463 #CJK UNIFIED IDEOGRAPH + {0xE6C6, 0x78D4}, //10464 #CJK UNIFIED IDEOGRAPH + {0xE6C7, 0x78C8}, //10465 #CJK UNIFIED IDEOGRAPH + {0xE6C8, 0x78C3}, //10466 #CJK UNIFIED IDEOGRAPH + {0xE6C9, 0x78C4}, //10467 #CJK UNIFIED IDEOGRAPH + {0xE6CA, 0x78C9}, //10468 #CJK UNIFIED IDEOGRAPH + {0xE6CB, 0x799A}, //10469 #CJK UNIFIED IDEOGRAPH + {0xE6CC, 0x79A1}, //10470 #CJK UNIFIED IDEOGRAPH + {0xE6CD, 0x79A0}, //10471 #CJK UNIFIED IDEOGRAPH + {0xE6CE, 0x799C}, //10472 #CJK UNIFIED IDEOGRAPH + {0xE6CF, 0x79A2}, //10473 #CJK UNIFIED IDEOGRAPH + {0xE6D0, 0x799B}, //10474 #CJK UNIFIED IDEOGRAPH + {0xE6D1, 0x6B76}, //10475 #CJK UNIFIED IDEOGRAPH + {0xE6D2, 0x7A39}, //10476 #CJK UNIFIED IDEOGRAPH + {0xE6D3, 0x7AB2}, //10477 #CJK UNIFIED IDEOGRAPH + {0xE6D4, 0x7AB4}, //10478 #CJK UNIFIED IDEOGRAPH + {0xE6D5, 0x7AB3}, //10479 #CJK UNIFIED IDEOGRAPH + {0xE6D6, 0x7BB7}, //10480 #CJK UNIFIED IDEOGRAPH + {0xE6D7, 0x7BCB}, //10481 #CJK UNIFIED IDEOGRAPH + {0xE6D8, 0x7BBE}, //10482 #CJK UNIFIED IDEOGRAPH + {0xE6D9, 0x7BAC}, //10483 #CJK UNIFIED IDEOGRAPH + {0xE6DA, 0x7BCE}, //10484 #CJK UNIFIED IDEOGRAPH + {0xE6DB, 0x7BAF}, //10485 #CJK UNIFIED IDEOGRAPH + {0xE6DC, 0x7BB9}, //10486 #CJK UNIFIED IDEOGRAPH + {0xE6DD, 0x7BCA}, //10487 #CJK UNIFIED IDEOGRAPH + {0xE6DE, 0x7BB5}, //10488 #CJK UNIFIED IDEOGRAPH + {0xE6DF, 0x7CC5}, //10489 #CJK UNIFIED IDEOGRAPH + {0xE6E0, 0x7CC8}, //10490 #CJK UNIFIED IDEOGRAPH + {0xE6E1, 0x7CCC}, //10491 #CJK UNIFIED IDEOGRAPH + {0xE6E2, 0x7CCB}, //10492 #CJK UNIFIED IDEOGRAPH + {0xE6E3, 0x7DF7}, //10493 #CJK UNIFIED IDEOGRAPH + {0xE6E4, 0x7DDB}, //10494 #CJK UNIFIED IDEOGRAPH + {0xE6E5, 0x7DEA}, //10495 #CJK UNIFIED IDEOGRAPH + {0xE6E6, 0x7DE7}, //10496 #CJK UNIFIED IDEOGRAPH + {0xE6E7, 0x7DD7}, //10497 #CJK UNIFIED IDEOGRAPH + {0xE6E8, 0x7DE1}, //10498 #CJK UNIFIED IDEOGRAPH + {0xE6E9, 0x7E03}, //10499 #CJK UNIFIED IDEOGRAPH + {0xE6EA, 0x7DFA}, //10500 #CJK UNIFIED IDEOGRAPH + {0xE6EB, 0x7DE6}, //10501 #CJK UNIFIED IDEOGRAPH + {0xE6EC, 0x7DF6}, //10502 #CJK UNIFIED IDEOGRAPH + {0xE6ED, 0x7DF1}, //10503 #CJK UNIFIED IDEOGRAPH + {0xE6EE, 0x7DF0}, //10504 #CJK UNIFIED IDEOGRAPH + {0xE6EF, 0x7DEE}, //10505 #CJK UNIFIED IDEOGRAPH + {0xE6F0, 0x7DDF}, //10506 #CJK UNIFIED IDEOGRAPH + {0xE6F1, 0x7F76}, //10507 #CJK UNIFIED IDEOGRAPH + {0xE6F2, 0x7FAC}, //10508 #CJK UNIFIED IDEOGRAPH + {0xE6F3, 0x7FB0}, //10509 #CJK UNIFIED IDEOGRAPH + {0xE6F4, 0x7FAD}, //10510 #CJK UNIFIED IDEOGRAPH + {0xE6F5, 0x7FED}, //10511 #CJK UNIFIED IDEOGRAPH + {0xE6F6, 0x7FEB}, //10512 #CJK UNIFIED IDEOGRAPH + {0xE6F7, 0x7FEA}, //10513 #CJK UNIFIED IDEOGRAPH + {0xE6F8, 0x7FEC}, //10514 #CJK UNIFIED IDEOGRAPH + {0xE6F9, 0x7FE6}, //10515 #CJK UNIFIED IDEOGRAPH + {0xE6FA, 0x7FE8}, //10516 #CJK UNIFIED IDEOGRAPH + {0xE6FB, 0x8064}, //10517 #CJK UNIFIED IDEOGRAPH + {0xE6FC, 0x8067}, //10518 #CJK UNIFIED IDEOGRAPH + {0xE6FD, 0x81A3}, //10519 #CJK UNIFIED IDEOGRAPH + {0xE6FE, 0x819F}, //10520 #CJK UNIFIED IDEOGRAPH + {0xE740, 0x819E}, //10521 #CJK UNIFIED IDEOGRAPH + {0xE741, 0x8195}, //10522 #CJK UNIFIED IDEOGRAPH + {0xE742, 0x81A2}, //10523 #CJK UNIFIED IDEOGRAPH + {0xE743, 0x8199}, //10524 #CJK UNIFIED IDEOGRAPH + {0xE744, 0x8197}, //10525 #CJK UNIFIED IDEOGRAPH + {0xE745, 0x8216}, //10526 #CJK UNIFIED IDEOGRAPH + {0xE746, 0x824F}, //10527 #CJK UNIFIED IDEOGRAPH + {0xE747, 0x8253}, //10528 #CJK UNIFIED IDEOGRAPH + {0xE748, 0x8252}, //10529 #CJK UNIFIED IDEOGRAPH + {0xE749, 0x8250}, //10530 #CJK UNIFIED IDEOGRAPH + {0xE74A, 0x824E}, //10531 #CJK UNIFIED IDEOGRAPH + {0xE74B, 0x8251}, //10532 #CJK UNIFIED IDEOGRAPH + {0xE74C, 0x8524}, //10533 #CJK UNIFIED IDEOGRAPH + {0xE74D, 0x853B}, //10534 #CJK UNIFIED IDEOGRAPH + {0xE74E, 0x850F}, //10535 #CJK UNIFIED IDEOGRAPH + {0xE74F, 0x8500}, //10536 #CJK UNIFIED IDEOGRAPH + {0xE750, 0x8529}, //10537 #CJK UNIFIED IDEOGRAPH + {0xE751, 0x850E}, //10538 #CJK UNIFIED IDEOGRAPH + {0xE752, 0x8509}, //10539 #CJK UNIFIED IDEOGRAPH + {0xE753, 0x850D}, //10540 #CJK UNIFIED IDEOGRAPH + {0xE754, 0x851F}, //10541 #CJK UNIFIED IDEOGRAPH + {0xE755, 0x850A}, //10542 #CJK UNIFIED IDEOGRAPH + {0xE756, 0x8527}, //10543 #CJK UNIFIED IDEOGRAPH + {0xE757, 0x851C}, //10544 #CJK UNIFIED IDEOGRAPH + {0xE758, 0x84FB}, //10545 #CJK UNIFIED IDEOGRAPH + {0xE759, 0x852B}, //10546 #CJK UNIFIED IDEOGRAPH + {0xE75A, 0x84FA}, //10547 #CJK UNIFIED IDEOGRAPH + {0xE75B, 0x8508}, //10548 #CJK UNIFIED IDEOGRAPH + {0xE75C, 0x850C}, //10549 #CJK UNIFIED IDEOGRAPH + {0xE75D, 0x84F4}, //10550 #CJK UNIFIED IDEOGRAPH + {0xE75E, 0x852A}, //10551 #CJK UNIFIED IDEOGRAPH + {0xE75F, 0x84F2}, //10552 #CJK UNIFIED IDEOGRAPH + {0xE760, 0x8515}, //10553 #CJK UNIFIED IDEOGRAPH + {0xE761, 0x84F7}, //10554 #CJK UNIFIED IDEOGRAPH + {0xE762, 0x84EB}, //10555 #CJK UNIFIED IDEOGRAPH + {0xE763, 0x84F3}, //10556 #CJK UNIFIED IDEOGRAPH + {0xE764, 0x84FC}, //10557 #CJK UNIFIED IDEOGRAPH + {0xE765, 0x8512}, //10558 #CJK UNIFIED IDEOGRAPH + {0xE766, 0x84EA}, //10559 #CJK UNIFIED IDEOGRAPH + {0xE767, 0x84E9}, //10560 #CJK UNIFIED IDEOGRAPH + {0xE768, 0x8516}, //10561 #CJK UNIFIED IDEOGRAPH + {0xE769, 0x84FE}, //10562 #CJK UNIFIED IDEOGRAPH + {0xE76A, 0x8528}, //10563 #CJK UNIFIED IDEOGRAPH + {0xE76B, 0x851D}, //10564 #CJK UNIFIED IDEOGRAPH + {0xE76C, 0x852E}, //10565 #CJK UNIFIED IDEOGRAPH + {0xE76D, 0x8502}, //10566 #CJK UNIFIED IDEOGRAPH + {0xE76E, 0x84FD}, //10567 #CJK UNIFIED IDEOGRAPH + {0xE76F, 0x851E}, //10568 #CJK UNIFIED IDEOGRAPH + {0xE770, 0x84F6}, //10569 #CJK UNIFIED IDEOGRAPH + {0xE771, 0x8531}, //10570 #CJK UNIFIED IDEOGRAPH + {0xE772, 0x8526}, //10571 #CJK UNIFIED IDEOGRAPH + {0xE773, 0x84E7}, //10572 #CJK UNIFIED IDEOGRAPH + {0xE774, 0x84E8}, //10573 #CJK UNIFIED IDEOGRAPH + {0xE775, 0x84F0}, //10574 #CJK UNIFIED IDEOGRAPH + {0xE776, 0x84EF}, //10575 #CJK UNIFIED IDEOGRAPH + {0xE777, 0x84F9}, //10576 #CJK UNIFIED IDEOGRAPH + {0xE778, 0x8518}, //10577 #CJK UNIFIED IDEOGRAPH + {0xE779, 0x8520}, //10578 #CJK UNIFIED IDEOGRAPH + {0xE77A, 0x8530}, //10579 #CJK UNIFIED IDEOGRAPH + {0xE77B, 0x850B}, //10580 #CJK UNIFIED IDEOGRAPH + {0xE77C, 0x8519}, //10581 #CJK UNIFIED IDEOGRAPH + {0xE77D, 0x852F}, //10582 #CJK UNIFIED IDEOGRAPH + {0xE77E, 0x8662}, //10583 #CJK UNIFIED IDEOGRAPH + {0xE7A1, 0x8756}, //10584 #CJK UNIFIED IDEOGRAPH + {0xE7A2, 0x8763}, //10585 #CJK UNIFIED IDEOGRAPH + {0xE7A3, 0x8764}, //10586 #CJK UNIFIED IDEOGRAPH + {0xE7A4, 0x8777}, //10587 #CJK UNIFIED IDEOGRAPH + {0xE7A5, 0x87E1}, //10588 #CJK UNIFIED IDEOGRAPH + {0xE7A6, 0x8773}, //10589 #CJK UNIFIED IDEOGRAPH + {0xE7A7, 0x8758}, //10590 #CJK UNIFIED IDEOGRAPH + {0xE7A8, 0x8754}, //10591 #CJK UNIFIED IDEOGRAPH + {0xE7A9, 0x875B}, //10592 #CJK UNIFIED IDEOGRAPH + {0xE7AA, 0x8752}, //10593 #CJK UNIFIED IDEOGRAPH + {0xE7AB, 0x8761}, //10594 #CJK UNIFIED IDEOGRAPH + {0xE7AC, 0x875A}, //10595 #CJK UNIFIED IDEOGRAPH + {0xE7AD, 0x8751}, //10596 #CJK UNIFIED IDEOGRAPH + {0xE7AE, 0x875E}, //10597 #CJK UNIFIED IDEOGRAPH + {0xE7AF, 0x876D}, //10598 #CJK UNIFIED IDEOGRAPH + {0xE7B0, 0x876A}, //10599 #CJK UNIFIED IDEOGRAPH + {0xE7B1, 0x8750}, //10600 #CJK UNIFIED IDEOGRAPH + {0xE7B2, 0x874E}, //10601 #CJK UNIFIED IDEOGRAPH + {0xE7B3, 0x875F}, //10602 #CJK UNIFIED IDEOGRAPH + {0xE7B4, 0x875D}, //10603 #CJK UNIFIED IDEOGRAPH + {0xE7B5, 0x876F}, //10604 #CJK UNIFIED IDEOGRAPH + {0xE7B6, 0x876C}, //10605 #CJK UNIFIED IDEOGRAPH + {0xE7B7, 0x877A}, //10606 #CJK UNIFIED IDEOGRAPH + {0xE7B8, 0x876E}, //10607 #CJK UNIFIED IDEOGRAPH + {0xE7B9, 0x875C}, //10608 #CJK UNIFIED IDEOGRAPH + {0xE7BA, 0x8765}, //10609 #CJK UNIFIED IDEOGRAPH + {0xE7BB, 0x874F}, //10610 #CJK UNIFIED IDEOGRAPH + {0xE7BC, 0x877B}, //10611 #CJK UNIFIED IDEOGRAPH + {0xE7BD, 0x8775}, //10612 #CJK UNIFIED IDEOGRAPH + {0xE7BE, 0x8762}, //10613 #CJK UNIFIED IDEOGRAPH + {0xE7BF, 0x8767}, //10614 #CJK UNIFIED IDEOGRAPH + {0xE7C0, 0x8769}, //10615 #CJK UNIFIED IDEOGRAPH + {0xE7C1, 0x885A}, //10616 #CJK UNIFIED IDEOGRAPH + {0xE7C2, 0x8905}, //10617 #CJK UNIFIED IDEOGRAPH + {0xE7C3, 0x890C}, //10618 #CJK UNIFIED IDEOGRAPH + {0xE7C4, 0x8914}, //10619 #CJK UNIFIED IDEOGRAPH + {0xE7C5, 0x890B}, //10620 #CJK UNIFIED IDEOGRAPH + {0xE7C6, 0x8917}, //10621 #CJK UNIFIED IDEOGRAPH + {0xE7C7, 0x8918}, //10622 #CJK UNIFIED IDEOGRAPH + {0xE7C8, 0x8919}, //10623 #CJK UNIFIED IDEOGRAPH + {0xE7C9, 0x8906}, //10624 #CJK UNIFIED IDEOGRAPH + {0xE7CA, 0x8916}, //10625 #CJK UNIFIED IDEOGRAPH + {0xE7CB, 0x8911}, //10626 #CJK UNIFIED IDEOGRAPH + {0xE7CC, 0x890E}, //10627 #CJK UNIFIED IDEOGRAPH + {0xE7CD, 0x8909}, //10628 #CJK UNIFIED IDEOGRAPH + {0xE7CE, 0x89A2}, //10629 #CJK UNIFIED IDEOGRAPH + {0xE7CF, 0x89A4}, //10630 #CJK UNIFIED IDEOGRAPH + {0xE7D0, 0x89A3}, //10631 #CJK UNIFIED IDEOGRAPH + {0xE7D1, 0x89ED}, //10632 #CJK UNIFIED IDEOGRAPH + {0xE7D2, 0x89F0}, //10633 #CJK UNIFIED IDEOGRAPH + {0xE7D3, 0x89EC}, //10634 #CJK UNIFIED IDEOGRAPH + {0xE7D4, 0x8ACF}, //10635 #CJK UNIFIED IDEOGRAPH + {0xE7D5, 0x8AC6}, //10636 #CJK UNIFIED IDEOGRAPH + {0xE7D6, 0x8AB8}, //10637 #CJK UNIFIED IDEOGRAPH + {0xE7D7, 0x8AD3}, //10638 #CJK UNIFIED IDEOGRAPH + {0xE7D8, 0x8AD1}, //10639 #CJK UNIFIED IDEOGRAPH + {0xE7D9, 0x8AD4}, //10640 #CJK UNIFIED IDEOGRAPH + {0xE7DA, 0x8AD5}, //10641 #CJK UNIFIED IDEOGRAPH + {0xE7DB, 0x8ABB}, //10642 #CJK UNIFIED IDEOGRAPH + {0xE7DC, 0x8AD7}, //10643 #CJK UNIFIED IDEOGRAPH + {0xE7DD, 0x8ABE}, //10644 #CJK UNIFIED IDEOGRAPH + {0xE7DE, 0x8AC0}, //10645 #CJK UNIFIED IDEOGRAPH + {0xE7DF, 0x8AC5}, //10646 #CJK UNIFIED IDEOGRAPH + {0xE7E0, 0x8AD8}, //10647 #CJK UNIFIED IDEOGRAPH + {0xE7E1, 0x8AC3}, //10648 #CJK UNIFIED IDEOGRAPH + {0xE7E2, 0x8ABA}, //10649 #CJK UNIFIED IDEOGRAPH + {0xE7E3, 0x8ABD}, //10650 #CJK UNIFIED IDEOGRAPH + {0xE7E4, 0x8AD9}, //10651 #CJK UNIFIED IDEOGRAPH + {0xE7E5, 0x8C3E}, //10652 #CJK UNIFIED IDEOGRAPH + {0xE7E6, 0x8C4D}, //10653 #CJK UNIFIED IDEOGRAPH + {0xE7E7, 0x8C8F}, //10654 #CJK UNIFIED IDEOGRAPH + {0xE7E8, 0x8CE5}, //10655 #CJK UNIFIED IDEOGRAPH + {0xE7E9, 0x8CDF}, //10656 #CJK UNIFIED IDEOGRAPH + {0xE7EA, 0x8CD9}, //10657 #CJK UNIFIED IDEOGRAPH + {0xE7EB, 0x8CE8}, //10658 #CJK UNIFIED IDEOGRAPH + {0xE7EC, 0x8CDA}, //10659 #CJK UNIFIED IDEOGRAPH + {0xE7ED, 0x8CDD}, //10660 #CJK UNIFIED IDEOGRAPH + {0xE7EE, 0x8CE7}, //10661 #CJK UNIFIED IDEOGRAPH + {0xE7EF, 0x8DA0}, //10662 #CJK UNIFIED IDEOGRAPH + {0xE7F0, 0x8D9C}, //10663 #CJK UNIFIED IDEOGRAPH + {0xE7F1, 0x8DA1}, //10664 #CJK UNIFIED IDEOGRAPH + {0xE7F2, 0x8D9B}, //10665 #CJK UNIFIED IDEOGRAPH + {0xE7F3, 0x8E20}, //10666 #CJK UNIFIED IDEOGRAPH + {0xE7F4, 0x8E23}, //10667 #CJK UNIFIED IDEOGRAPH + {0xE7F5, 0x8E25}, //10668 #CJK UNIFIED IDEOGRAPH + {0xE7F6, 0x8E24}, //10669 #CJK UNIFIED IDEOGRAPH + {0xE7F7, 0x8E2E}, //10670 #CJK UNIFIED IDEOGRAPH + {0xE7F8, 0x8E15}, //10671 #CJK UNIFIED IDEOGRAPH + {0xE7F9, 0x8E1B}, //10672 #CJK UNIFIED IDEOGRAPH + {0xE7FA, 0x8E16}, //10673 #CJK UNIFIED IDEOGRAPH + {0xE7FB, 0x8E11}, //10674 #CJK UNIFIED IDEOGRAPH + {0xE7FC, 0x8E19}, //10675 #CJK UNIFIED IDEOGRAPH + {0xE7FD, 0x8E26}, //10676 #CJK UNIFIED IDEOGRAPH + {0xE7FE, 0x8E27}, //10677 #CJK UNIFIED IDEOGRAPH + {0xE840, 0x8E14}, //10678 #CJK UNIFIED IDEOGRAPH + {0xE841, 0x8E12}, //10679 #CJK UNIFIED IDEOGRAPH + {0xE842, 0x8E18}, //10680 #CJK UNIFIED IDEOGRAPH + {0xE843, 0x8E13}, //10681 #CJK UNIFIED IDEOGRAPH + {0xE844, 0x8E1C}, //10682 #CJK UNIFIED IDEOGRAPH + {0xE845, 0x8E17}, //10683 #CJK UNIFIED IDEOGRAPH + {0xE846, 0x8E1A}, //10684 #CJK UNIFIED IDEOGRAPH + {0xE847, 0x8F2C}, //10685 #CJK UNIFIED IDEOGRAPH + {0xE848, 0x8F24}, //10686 #CJK UNIFIED IDEOGRAPH + {0xE849, 0x8F18}, //10687 #CJK UNIFIED IDEOGRAPH + {0xE84A, 0x8F1A}, //10688 #CJK UNIFIED IDEOGRAPH + {0xE84B, 0x8F20}, //10689 #CJK UNIFIED IDEOGRAPH + {0xE84C, 0x8F23}, //10690 #CJK UNIFIED IDEOGRAPH + {0xE84D, 0x8F16}, //10691 #CJK UNIFIED IDEOGRAPH + {0xE84E, 0x8F17}, //10692 #CJK UNIFIED IDEOGRAPH + {0xE84F, 0x9073}, //10693 #CJK UNIFIED IDEOGRAPH + {0xE850, 0x9070}, //10694 #CJK UNIFIED IDEOGRAPH + {0xE851, 0x906F}, //10695 #CJK UNIFIED IDEOGRAPH + {0xE852, 0x9067}, //10696 #CJK UNIFIED IDEOGRAPH + {0xE853, 0x906B}, //10697 #CJK UNIFIED IDEOGRAPH + {0xE854, 0x912F}, //10698 #CJK UNIFIED IDEOGRAPH + {0xE855, 0x912B}, //10699 #CJK UNIFIED IDEOGRAPH + {0xE856, 0x9129}, //10700 #CJK UNIFIED IDEOGRAPH + {0xE857, 0x912A}, //10701 #CJK UNIFIED IDEOGRAPH + {0xE858, 0x9132}, //10702 #CJK UNIFIED IDEOGRAPH + {0xE859, 0x9126}, //10703 #CJK UNIFIED IDEOGRAPH + {0xE85A, 0x912E}, //10704 #CJK UNIFIED IDEOGRAPH + {0xE85B, 0x9185}, //10705 #CJK UNIFIED IDEOGRAPH + {0xE85C, 0x9186}, //10706 #CJK UNIFIED IDEOGRAPH + {0xE85D, 0x918A}, //10707 #CJK UNIFIED IDEOGRAPH + {0xE85E, 0x9181}, //10708 #CJK UNIFIED IDEOGRAPH + {0xE85F, 0x9182}, //10709 #CJK UNIFIED IDEOGRAPH + {0xE860, 0x9184}, //10710 #CJK UNIFIED IDEOGRAPH + {0xE861, 0x9180}, //10711 #CJK UNIFIED IDEOGRAPH + {0xE862, 0x92D0}, //10712 #CJK UNIFIED IDEOGRAPH + {0xE863, 0x92C3}, //10713 #CJK UNIFIED IDEOGRAPH + {0xE864, 0x92C4}, //10714 #CJK UNIFIED IDEOGRAPH + {0xE865, 0x92C0}, //10715 #CJK UNIFIED IDEOGRAPH + {0xE866, 0x92D9}, //10716 #CJK UNIFIED IDEOGRAPH + {0xE867, 0x92B6}, //10717 #CJK UNIFIED IDEOGRAPH + {0xE868, 0x92CF}, //10718 #CJK UNIFIED IDEOGRAPH + {0xE869, 0x92F1}, //10719 #CJK UNIFIED IDEOGRAPH + {0xE86A, 0x92DF}, //10720 #CJK UNIFIED IDEOGRAPH + {0xE86B, 0x92D8}, //10721 #CJK UNIFIED IDEOGRAPH + {0xE86C, 0x92E9}, //10722 #CJK UNIFIED IDEOGRAPH + {0xE86D, 0x92D7}, //10723 #CJK UNIFIED IDEOGRAPH + {0xE86E, 0x92DD}, //10724 #CJK UNIFIED IDEOGRAPH + {0xE86F, 0x92CC}, //10725 #CJK UNIFIED IDEOGRAPH + {0xE870, 0x92EF}, //10726 #CJK UNIFIED IDEOGRAPH + {0xE871, 0x92C2}, //10727 #CJK UNIFIED IDEOGRAPH + {0xE872, 0x92E8}, //10728 #CJK UNIFIED IDEOGRAPH + {0xE873, 0x92CA}, //10729 #CJK UNIFIED IDEOGRAPH + {0xE874, 0x92C8}, //10730 #CJK UNIFIED IDEOGRAPH + {0xE875, 0x92CE}, //10731 #CJK UNIFIED IDEOGRAPH + {0xE876, 0x92E6}, //10732 #CJK UNIFIED IDEOGRAPH + {0xE877, 0x92CD}, //10733 #CJK UNIFIED IDEOGRAPH + {0xE878, 0x92D5}, //10734 #CJK UNIFIED IDEOGRAPH + {0xE879, 0x92C9}, //10735 #CJK UNIFIED IDEOGRAPH + {0xE87A, 0x92E0}, //10736 #CJK UNIFIED IDEOGRAPH + {0xE87B, 0x92DE}, //10737 #CJK UNIFIED IDEOGRAPH + {0xE87C, 0x92E7}, //10738 #CJK UNIFIED IDEOGRAPH + {0xE87D, 0x92D1}, //10739 #CJK UNIFIED IDEOGRAPH + {0xE87E, 0x92D3}, //10740 #CJK UNIFIED IDEOGRAPH + {0xE8A1, 0x92B5}, //10741 #CJK UNIFIED IDEOGRAPH + {0xE8A2, 0x92E1}, //10742 #CJK UNIFIED IDEOGRAPH + {0xE8A3, 0x92C6}, //10743 #CJK UNIFIED IDEOGRAPH + {0xE8A4, 0x92B4}, //10744 #CJK UNIFIED IDEOGRAPH + {0xE8A5, 0x957C}, //10745 #CJK UNIFIED IDEOGRAPH + {0xE8A6, 0x95AC}, //10746 #CJK UNIFIED IDEOGRAPH + {0xE8A7, 0x95AB}, //10747 #CJK UNIFIED IDEOGRAPH + {0xE8A8, 0x95AE}, //10748 #CJK UNIFIED IDEOGRAPH + {0xE8A9, 0x95B0}, //10749 #CJK UNIFIED IDEOGRAPH + {0xE8AA, 0x96A4}, //10750 #CJK UNIFIED IDEOGRAPH + {0xE8AB, 0x96A2}, //10751 #CJK UNIFIED IDEOGRAPH + {0xE8AC, 0x96D3}, //10752 #CJK UNIFIED IDEOGRAPH + {0xE8AD, 0x9705}, //10753 #CJK UNIFIED IDEOGRAPH + {0xE8AE, 0x9708}, //10754 #CJK UNIFIED IDEOGRAPH + {0xE8AF, 0x9702}, //10755 #CJK UNIFIED IDEOGRAPH + {0xE8B0, 0x975A}, //10756 #CJK UNIFIED IDEOGRAPH + {0xE8B1, 0x978A}, //10757 #CJK UNIFIED IDEOGRAPH + {0xE8B2, 0x978E}, //10758 #CJK UNIFIED IDEOGRAPH + {0xE8B3, 0x9788}, //10759 #CJK UNIFIED IDEOGRAPH + {0xE8B4, 0x97D0}, //10760 #CJK UNIFIED IDEOGRAPH + {0xE8B5, 0x97CF}, //10761 #CJK UNIFIED IDEOGRAPH + {0xE8B6, 0x981E}, //10762 #CJK UNIFIED IDEOGRAPH + {0xE8B7, 0x981D}, //10763 #CJK UNIFIED IDEOGRAPH + {0xE8B8, 0x9826}, //10764 #CJK UNIFIED IDEOGRAPH + {0xE8B9, 0x9829}, //10765 #CJK UNIFIED IDEOGRAPH + {0xE8BA, 0x9828}, //10766 #CJK UNIFIED IDEOGRAPH + {0xE8BB, 0x9820}, //10767 #CJK UNIFIED IDEOGRAPH + {0xE8BC, 0x981B}, //10768 #CJK UNIFIED IDEOGRAPH + {0xE8BD, 0x9827}, //10769 #CJK UNIFIED IDEOGRAPH + {0xE8BE, 0x98B2}, //10770 #CJK UNIFIED IDEOGRAPH + {0xE8BF, 0x9908}, //10771 #CJK UNIFIED IDEOGRAPH + {0xE8C0, 0x98FA}, //10772 #CJK UNIFIED IDEOGRAPH + {0xE8C1, 0x9911}, //10773 #CJK UNIFIED IDEOGRAPH + {0xE8C2, 0x9914}, //10774 #CJK UNIFIED IDEOGRAPH + {0xE8C3, 0x9916}, //10775 #CJK UNIFIED IDEOGRAPH + {0xE8C4, 0x9917}, //10776 #CJK UNIFIED IDEOGRAPH + {0xE8C5, 0x9915}, //10777 #CJK UNIFIED IDEOGRAPH + {0xE8C6, 0x99DC}, //10778 #CJK UNIFIED IDEOGRAPH + {0xE8C7, 0x99CD}, //10779 #CJK UNIFIED IDEOGRAPH + {0xE8C8, 0x99CF}, //10780 #CJK UNIFIED IDEOGRAPH + {0xE8C9, 0x99D3}, //10781 #CJK UNIFIED IDEOGRAPH + {0xE8CA, 0x99D4}, //10782 #CJK UNIFIED IDEOGRAPH + {0xE8CB, 0x99CE}, //10783 #CJK UNIFIED IDEOGRAPH + {0xE8CC, 0x99C9}, //10784 #CJK UNIFIED IDEOGRAPH + {0xE8CD, 0x99D6}, //10785 #CJK UNIFIED IDEOGRAPH + {0xE8CE, 0x99D8}, //10786 #CJK UNIFIED IDEOGRAPH + {0xE8CF, 0x99CB}, //10787 #CJK UNIFIED IDEOGRAPH + {0xE8D0, 0x99D7}, //10788 #CJK UNIFIED IDEOGRAPH + {0xE8D1, 0x99CC}, //10789 #CJK UNIFIED IDEOGRAPH + {0xE8D2, 0x9AB3}, //10790 #CJK UNIFIED IDEOGRAPH + {0xE8D3, 0x9AEC}, //10791 #CJK UNIFIED IDEOGRAPH + {0xE8D4, 0x9AEB}, //10792 #CJK UNIFIED IDEOGRAPH + {0xE8D5, 0x9AF3}, //10793 #CJK UNIFIED IDEOGRAPH + {0xE8D6, 0x9AF2}, //10794 #CJK UNIFIED IDEOGRAPH + {0xE8D7, 0x9AF1}, //10795 #CJK UNIFIED IDEOGRAPH + {0xE8D8, 0x9B46}, //10796 #CJK UNIFIED IDEOGRAPH + {0xE8D9, 0x9B43}, //10797 #CJK UNIFIED IDEOGRAPH + {0xE8DA, 0x9B67}, //10798 #CJK UNIFIED IDEOGRAPH + {0xE8DB, 0x9B74}, //10799 #CJK UNIFIED IDEOGRAPH + {0xE8DC, 0x9B71}, //10800 #CJK UNIFIED IDEOGRAPH + {0xE8DD, 0x9B66}, //10801 #CJK UNIFIED IDEOGRAPH + {0xE8DE, 0x9B76}, //10802 #CJK UNIFIED IDEOGRAPH + {0xE8DF, 0x9B75}, //10803 #CJK UNIFIED IDEOGRAPH + {0xE8E0, 0x9B70}, //10804 #CJK UNIFIED IDEOGRAPH + {0xE8E1, 0x9B68}, //10805 #CJK UNIFIED IDEOGRAPH + {0xE8E2, 0x9B64}, //10806 #CJK UNIFIED IDEOGRAPH + {0xE8E3, 0x9B6C}, //10807 #CJK UNIFIED IDEOGRAPH + {0xE8E4, 0x9CFC}, //10808 #CJK UNIFIED IDEOGRAPH + {0xE8E5, 0x9CFA}, //10809 #CJK UNIFIED IDEOGRAPH + {0xE8E6, 0x9CFD}, //10810 #CJK UNIFIED IDEOGRAPH + {0xE8E7, 0x9CFF}, //10811 #CJK UNIFIED IDEOGRAPH + {0xE8E8, 0x9CF7}, //10812 #CJK UNIFIED IDEOGRAPH + {0xE8E9, 0x9D07}, //10813 #CJK UNIFIED IDEOGRAPH + {0xE8EA, 0x9D00}, //10814 #CJK UNIFIED IDEOGRAPH + {0xE8EB, 0x9CF9}, //10815 #CJK UNIFIED IDEOGRAPH + {0xE8EC, 0x9CFB}, //10816 #CJK UNIFIED IDEOGRAPH + {0xE8ED, 0x9D08}, //10817 #CJK UNIFIED IDEOGRAPH + {0xE8EE, 0x9D05}, //10818 #CJK UNIFIED IDEOGRAPH + {0xE8EF, 0x9D04}, //10819 #CJK UNIFIED IDEOGRAPH + {0xE8F0, 0x9E83}, //10820 #CJK UNIFIED IDEOGRAPH + {0xE8F1, 0x9ED3}, //10821 #CJK UNIFIED IDEOGRAPH + {0xE8F2, 0x9F0F}, //10822 #CJK UNIFIED IDEOGRAPH + {0xE8F3, 0x9F10}, //10823 #CJK UNIFIED IDEOGRAPH + {0xE8F4, 0x511C}, //10824 #CJK UNIFIED IDEOGRAPH + {0xE8F5, 0x5113}, //10825 #CJK UNIFIED IDEOGRAPH + {0xE8F6, 0x5117}, //10826 #CJK UNIFIED IDEOGRAPH + {0xE8F7, 0x511A}, //10827 #CJK UNIFIED IDEOGRAPH + {0xE8F8, 0x5111}, //10828 #CJK UNIFIED IDEOGRAPH + {0xE8F9, 0x51DE}, //10829 #CJK UNIFIED IDEOGRAPH + {0xE8FA, 0x5334}, //10830 #CJK UNIFIED IDEOGRAPH + {0xE8FB, 0x53E1}, //10831 #CJK UNIFIED IDEOGRAPH + {0xE8FC, 0x5670}, //10832 #CJK UNIFIED IDEOGRAPH + {0xE8FD, 0x5660}, //10833 #CJK UNIFIED IDEOGRAPH + {0xE8FE, 0x566E}, //10834 #CJK UNIFIED IDEOGRAPH + {0xE940, 0x5673}, //10835 #CJK UNIFIED IDEOGRAPH + {0xE941, 0x5666}, //10836 #CJK UNIFIED IDEOGRAPH + {0xE942, 0x5663}, //10837 #CJK UNIFIED IDEOGRAPH + {0xE943, 0x566D}, //10838 #CJK UNIFIED IDEOGRAPH + {0xE944, 0x5672}, //10839 #CJK UNIFIED IDEOGRAPH + {0xE945, 0x565E}, //10840 #CJK UNIFIED IDEOGRAPH + {0xE946, 0x5677}, //10841 #CJK UNIFIED IDEOGRAPH + {0xE947, 0x571C}, //10842 #CJK UNIFIED IDEOGRAPH + {0xE948, 0x571B}, //10843 #CJK UNIFIED IDEOGRAPH + {0xE949, 0x58C8}, //10844 #CJK UNIFIED IDEOGRAPH + {0xE94A, 0x58BD}, //10845 #CJK UNIFIED IDEOGRAPH + {0xE94B, 0x58C9}, //10846 #CJK UNIFIED IDEOGRAPH + {0xE94C, 0x58BF}, //10847 #CJK UNIFIED IDEOGRAPH + {0xE94D, 0x58BA}, //10848 #CJK UNIFIED IDEOGRAPH + {0xE94E, 0x58C2}, //10849 #CJK UNIFIED IDEOGRAPH + {0xE94F, 0x58BC}, //10850 #CJK UNIFIED IDEOGRAPH + {0xE950, 0x58C6}, //10851 #CJK UNIFIED IDEOGRAPH + {0xE951, 0x5B17}, //10852 #CJK UNIFIED IDEOGRAPH + {0xE952, 0x5B19}, //10853 #CJK UNIFIED IDEOGRAPH + {0xE953, 0x5B1B}, //10854 #CJK UNIFIED IDEOGRAPH + {0xE954, 0x5B21}, //10855 #CJK UNIFIED IDEOGRAPH + {0xE955, 0x5B14}, //10856 #CJK UNIFIED IDEOGRAPH + {0xE956, 0x5B13}, //10857 #CJK UNIFIED IDEOGRAPH + {0xE957, 0x5B10}, //10858 #CJK UNIFIED IDEOGRAPH + {0xE958, 0x5B16}, //10859 #CJK UNIFIED IDEOGRAPH + {0xE959, 0x5B28}, //10860 #CJK UNIFIED IDEOGRAPH + {0xE95A, 0x5B1A}, //10861 #CJK UNIFIED IDEOGRAPH + {0xE95B, 0x5B20}, //10862 #CJK UNIFIED IDEOGRAPH + {0xE95C, 0x5B1E}, //10863 #CJK UNIFIED IDEOGRAPH + {0xE95D, 0x5BEF}, //10864 #CJK UNIFIED IDEOGRAPH + {0xE95E, 0x5DAC}, //10865 #CJK UNIFIED IDEOGRAPH + {0xE95F, 0x5DB1}, //10866 #CJK UNIFIED IDEOGRAPH + {0xE960, 0x5DA9}, //10867 #CJK UNIFIED IDEOGRAPH + {0xE961, 0x5DA7}, //10868 #CJK UNIFIED IDEOGRAPH + {0xE962, 0x5DB5}, //10869 #CJK UNIFIED IDEOGRAPH + {0xE963, 0x5DB0}, //10870 #CJK UNIFIED IDEOGRAPH + {0xE964, 0x5DAE}, //10871 #CJK UNIFIED IDEOGRAPH + {0xE965, 0x5DAA}, //10872 #CJK UNIFIED IDEOGRAPH + {0xE966, 0x5DA8}, //10873 #CJK UNIFIED IDEOGRAPH + {0xE967, 0x5DB2}, //10874 #CJK UNIFIED IDEOGRAPH + {0xE968, 0x5DAD}, //10875 #CJK UNIFIED IDEOGRAPH + {0xE969, 0x5DAF}, //10876 #CJK UNIFIED IDEOGRAPH + {0xE96A, 0x5DB4}, //10877 #CJK UNIFIED IDEOGRAPH + {0xE96B, 0x5E67}, //10878 #CJK UNIFIED IDEOGRAPH + {0xE96C, 0x5E68}, //10879 #CJK UNIFIED IDEOGRAPH + {0xE96D, 0x5E66}, //10880 #CJK UNIFIED IDEOGRAPH + {0xE96E, 0x5E6F}, //10881 #CJK UNIFIED IDEOGRAPH + {0xE96F, 0x5EE9}, //10882 #CJK UNIFIED IDEOGRAPH + {0xE970, 0x5EE7}, //10883 #CJK UNIFIED IDEOGRAPH + {0xE971, 0x5EE6}, //10884 #CJK UNIFIED IDEOGRAPH + {0xE972, 0x5EE8}, //10885 #CJK UNIFIED IDEOGRAPH + {0xE973, 0x5EE5}, //10886 #CJK UNIFIED IDEOGRAPH + {0xE974, 0x5F4B}, //10887 #CJK UNIFIED IDEOGRAPH + {0xE975, 0x5FBC}, //10888 #CJK UNIFIED IDEOGRAPH + {0xE976, 0x619D}, //10889 #CJK UNIFIED IDEOGRAPH + {0xE977, 0x61A8}, //10890 #CJK UNIFIED IDEOGRAPH + {0xE978, 0x6196}, //10891 #CJK UNIFIED IDEOGRAPH + {0xE979, 0x61C5}, //10892 #CJK UNIFIED IDEOGRAPH + {0xE97A, 0x61B4}, //10893 #CJK UNIFIED IDEOGRAPH + {0xE97B, 0x61C6}, //10894 #CJK UNIFIED IDEOGRAPH + {0xE97C, 0x61C1}, //10895 #CJK UNIFIED IDEOGRAPH + {0xE97D, 0x61CC}, //10896 #CJK UNIFIED IDEOGRAPH + {0xE97E, 0x61BA}, //10897 #CJK UNIFIED IDEOGRAPH + {0xE9A1, 0x61BF}, //10898 #CJK UNIFIED IDEOGRAPH + {0xE9A2, 0x61B8}, //10899 #CJK UNIFIED IDEOGRAPH + {0xE9A3, 0x618C}, //10900 #CJK UNIFIED IDEOGRAPH + {0xE9A4, 0x64D7}, //10901 #CJK UNIFIED IDEOGRAPH + {0xE9A5, 0x64D6}, //10902 #CJK UNIFIED IDEOGRAPH + {0xE9A6, 0x64D0}, //10903 #CJK UNIFIED IDEOGRAPH + {0xE9A7, 0x64CF}, //10904 #CJK UNIFIED IDEOGRAPH + {0xE9A8, 0x64C9}, //10905 #CJK UNIFIED IDEOGRAPH + {0xE9A9, 0x64BD}, //10906 #CJK UNIFIED IDEOGRAPH + {0xE9AA, 0x6489}, //10907 #CJK UNIFIED IDEOGRAPH + {0xE9AB, 0x64C3}, //10908 #CJK UNIFIED IDEOGRAPH + {0xE9AC, 0x64DB}, //10909 #CJK UNIFIED IDEOGRAPH + {0xE9AD, 0x64F3}, //10910 #CJK UNIFIED IDEOGRAPH + {0xE9AE, 0x64D9}, //10911 #CJK UNIFIED IDEOGRAPH + {0xE9AF, 0x6533}, //10912 #CJK UNIFIED IDEOGRAPH + {0xE9B0, 0x657F}, //10913 #CJK UNIFIED IDEOGRAPH + {0xE9B1, 0x657C}, //10914 #CJK UNIFIED IDEOGRAPH + {0xE9B2, 0x65A2}, //10915 #CJK UNIFIED IDEOGRAPH + {0xE9B3, 0x66C8}, //10916 #CJK UNIFIED IDEOGRAPH + {0xE9B4, 0x66BE}, //10917 #CJK UNIFIED IDEOGRAPH + {0xE9B5, 0x66C0}, //10918 #CJK UNIFIED IDEOGRAPH + {0xE9B6, 0x66CA}, //10919 #CJK UNIFIED IDEOGRAPH + {0xE9B7, 0x66CB}, //10920 #CJK UNIFIED IDEOGRAPH + {0xE9B8, 0x66CF}, //10921 #CJK UNIFIED IDEOGRAPH + {0xE9B9, 0x66BD}, //10922 #CJK UNIFIED IDEOGRAPH + {0xE9BA, 0x66BB}, //10923 #CJK UNIFIED IDEOGRAPH + {0xE9BB, 0x66BA}, //10924 #CJK UNIFIED IDEOGRAPH + {0xE9BC, 0x66CC}, //10925 #CJK UNIFIED IDEOGRAPH + {0xE9BD, 0x6723}, //10926 #CJK UNIFIED IDEOGRAPH + {0xE9BE, 0x6A34}, //10927 #CJK UNIFIED IDEOGRAPH + {0xE9BF, 0x6A66}, //10928 #CJK UNIFIED IDEOGRAPH + {0xE9C0, 0x6A49}, //10929 #CJK UNIFIED IDEOGRAPH + {0xE9C1, 0x6A67}, //10930 #CJK UNIFIED IDEOGRAPH + {0xE9C2, 0x6A32}, //10931 #CJK UNIFIED IDEOGRAPH + {0xE9C3, 0x6A68}, //10932 #CJK UNIFIED IDEOGRAPH + {0xE9C4, 0x6A3E}, //10933 #CJK UNIFIED IDEOGRAPH + {0xE9C5, 0x6A5D}, //10934 #CJK UNIFIED IDEOGRAPH + {0xE9C6, 0x6A6D}, //10935 #CJK UNIFIED IDEOGRAPH + {0xE9C7, 0x6A76}, //10936 #CJK UNIFIED IDEOGRAPH + {0xE9C8, 0x6A5B}, //10937 #CJK UNIFIED IDEOGRAPH + {0xE9C9, 0x6A51}, //10938 #CJK UNIFIED IDEOGRAPH + {0xE9CA, 0x6A28}, //10939 #CJK UNIFIED IDEOGRAPH + {0xE9CB, 0x6A5A}, //10940 #CJK UNIFIED IDEOGRAPH + {0xE9CC, 0x6A3B}, //10941 #CJK UNIFIED IDEOGRAPH + {0xE9CD, 0x6A3F}, //10942 #CJK UNIFIED IDEOGRAPH + {0xE9CE, 0x6A41}, //10943 #CJK UNIFIED IDEOGRAPH + {0xE9CF, 0x6A6A}, //10944 #CJK UNIFIED IDEOGRAPH + {0xE9D0, 0x6A64}, //10945 #CJK UNIFIED IDEOGRAPH + {0xE9D1, 0x6A50}, //10946 #CJK UNIFIED IDEOGRAPH + {0xE9D2, 0x6A4F}, //10947 #CJK UNIFIED IDEOGRAPH + {0xE9D3, 0x6A54}, //10948 #CJK UNIFIED IDEOGRAPH + {0xE9D4, 0x6A6F}, //10949 #CJK UNIFIED IDEOGRAPH + {0xE9D5, 0x6A69}, //10950 #CJK UNIFIED IDEOGRAPH + {0xE9D6, 0x6A60}, //10951 #CJK UNIFIED IDEOGRAPH + {0xE9D7, 0x6A3C}, //10952 #CJK UNIFIED IDEOGRAPH + {0xE9D8, 0x6A5E}, //10953 #CJK UNIFIED IDEOGRAPH + {0xE9D9, 0x6A56}, //10954 #CJK UNIFIED IDEOGRAPH + {0xE9DA, 0x6A55}, //10955 #CJK UNIFIED IDEOGRAPH + {0xE9DB, 0x6A4D}, //10956 #CJK UNIFIED IDEOGRAPH + {0xE9DC, 0x6A4E}, //10957 #CJK UNIFIED IDEOGRAPH + {0xE9DD, 0x6A46}, //10958 #CJK UNIFIED IDEOGRAPH + {0xE9DE, 0x6B55}, //10959 #CJK UNIFIED IDEOGRAPH + {0xE9DF, 0x6B54}, //10960 #CJK UNIFIED IDEOGRAPH + {0xE9E0, 0x6B56}, //10961 #CJK UNIFIED IDEOGRAPH + {0xE9E1, 0x6BA7}, //10962 #CJK UNIFIED IDEOGRAPH + {0xE9E2, 0x6BAA}, //10963 #CJK UNIFIED IDEOGRAPH + {0xE9E3, 0x6BAB}, //10964 #CJK UNIFIED IDEOGRAPH + {0xE9E4, 0x6BC8}, //10965 #CJK UNIFIED IDEOGRAPH + {0xE9E5, 0x6BC7}, //10966 #CJK UNIFIED IDEOGRAPH + {0xE9E6, 0x6C04}, //10967 #CJK UNIFIED IDEOGRAPH + {0xE9E7, 0x6C03}, //10968 #CJK UNIFIED IDEOGRAPH + {0xE9E8, 0x6C06}, //10969 #CJK UNIFIED IDEOGRAPH + {0xE9E9, 0x6FAD}, //10970 #CJK UNIFIED IDEOGRAPH + {0xE9EA, 0x6FCB}, //10971 #CJK UNIFIED IDEOGRAPH + {0xE9EB, 0x6FA3}, //10972 #CJK UNIFIED IDEOGRAPH + {0xE9EC, 0x6FC7}, //10973 #CJK UNIFIED IDEOGRAPH + {0xE9ED, 0x6FBC}, //10974 #CJK UNIFIED IDEOGRAPH + {0xE9EE, 0x6FCE}, //10975 #CJK UNIFIED IDEOGRAPH + {0xE9EF, 0x6FC8}, //10976 #CJK UNIFIED IDEOGRAPH + {0xE9F0, 0x6F5E}, //10977 #CJK UNIFIED IDEOGRAPH + {0xE9F1, 0x6FC4}, //10978 #CJK UNIFIED IDEOGRAPH + {0xE9F2, 0x6FBD}, //10979 #CJK UNIFIED IDEOGRAPH + {0xE9F3, 0x6F9E}, //10980 #CJK UNIFIED IDEOGRAPH + {0xE9F4, 0x6FCA}, //10981 #CJK UNIFIED IDEOGRAPH + {0xE9F5, 0x6FA8}, //10982 #CJK UNIFIED IDEOGRAPH + {0xE9F6, 0x7004}, //10983 #CJK UNIFIED IDEOGRAPH + {0xE9F7, 0x6FA5}, //10984 #CJK UNIFIED IDEOGRAPH + {0xE9F8, 0x6FAE}, //10985 #CJK UNIFIED IDEOGRAPH + {0xE9F9, 0x6FBA}, //10986 #CJK UNIFIED IDEOGRAPH + {0xE9FA, 0x6FAC}, //10987 #CJK UNIFIED IDEOGRAPH + {0xE9FB, 0x6FAA}, //10988 #CJK UNIFIED IDEOGRAPH + {0xE9FC, 0x6FCF}, //10989 #CJK UNIFIED IDEOGRAPH + {0xE9FD, 0x6FBF}, //10990 #CJK UNIFIED IDEOGRAPH + {0xE9FE, 0x6FB8}, //10991 #CJK UNIFIED IDEOGRAPH + {0xEA40, 0x6FA2}, //10992 #CJK UNIFIED IDEOGRAPH + {0xEA41, 0x6FC9}, //10993 #CJK UNIFIED IDEOGRAPH + {0xEA42, 0x6FAB}, //10994 #CJK UNIFIED IDEOGRAPH + {0xEA43, 0x6FCD}, //10995 #CJK UNIFIED IDEOGRAPH + {0xEA44, 0x6FAF}, //10996 #CJK UNIFIED IDEOGRAPH + {0xEA45, 0x6FB2}, //10997 #CJK UNIFIED IDEOGRAPH + {0xEA46, 0x6FB0}, //10998 #CJK UNIFIED IDEOGRAPH + {0xEA47, 0x71C5}, //10999 #CJK UNIFIED IDEOGRAPH + {0xEA48, 0x71C2}, //11000 #CJK UNIFIED IDEOGRAPH + {0xEA49, 0x71BF}, //11001 #CJK UNIFIED IDEOGRAPH + {0xEA4A, 0x71B8}, //11002 #CJK UNIFIED IDEOGRAPH + {0xEA4B, 0x71D6}, //11003 #CJK UNIFIED IDEOGRAPH + {0xEA4C, 0x71C0}, //11004 #CJK UNIFIED IDEOGRAPH + {0xEA4D, 0x71C1}, //11005 #CJK UNIFIED IDEOGRAPH + {0xEA4E, 0x71CB}, //11006 #CJK UNIFIED IDEOGRAPH + {0xEA4F, 0x71D4}, //11007 #CJK UNIFIED IDEOGRAPH + {0xEA50, 0x71CA}, //11008 #CJK UNIFIED IDEOGRAPH + {0xEA51, 0x71C7}, //11009 #CJK UNIFIED IDEOGRAPH + {0xEA52, 0x71CF}, //11010 #CJK UNIFIED IDEOGRAPH + {0xEA53, 0x71BD}, //11011 #CJK UNIFIED IDEOGRAPH + {0xEA54, 0x71D8}, //11012 #CJK UNIFIED IDEOGRAPH + {0xEA55, 0x71BC}, //11013 #CJK UNIFIED IDEOGRAPH + {0xEA56, 0x71C6}, //11014 #CJK UNIFIED IDEOGRAPH + {0xEA57, 0x71DA}, //11015 #CJK UNIFIED IDEOGRAPH + {0xEA58, 0x71DB}, //11016 #CJK UNIFIED IDEOGRAPH + {0xEA59, 0x729D}, //11017 #CJK UNIFIED IDEOGRAPH + {0xEA5A, 0x729E}, //11018 #CJK UNIFIED IDEOGRAPH + {0xEA5B, 0x7369}, //11019 #CJK UNIFIED IDEOGRAPH + {0xEA5C, 0x7366}, //11020 #CJK UNIFIED IDEOGRAPH + {0xEA5D, 0x7367}, //11021 #CJK UNIFIED IDEOGRAPH + {0xEA5E, 0x736C}, //11022 #CJK UNIFIED IDEOGRAPH + {0xEA5F, 0x7365}, //11023 #CJK UNIFIED IDEOGRAPH + {0xEA60, 0x736B}, //11024 #CJK UNIFIED IDEOGRAPH + {0xEA61, 0x736A}, //11025 #CJK UNIFIED IDEOGRAPH + {0xEA62, 0x747F}, //11026 #CJK UNIFIED IDEOGRAPH + {0xEA63, 0x749A}, //11027 #CJK UNIFIED IDEOGRAPH + {0xEA64, 0x74A0}, //11028 #CJK UNIFIED IDEOGRAPH + {0xEA65, 0x7494}, //11029 #CJK UNIFIED IDEOGRAPH + {0xEA66, 0x7492}, //11030 #CJK UNIFIED IDEOGRAPH + {0xEA67, 0x7495}, //11031 #CJK UNIFIED IDEOGRAPH + {0xEA68, 0x74A1}, //11032 #CJK UNIFIED IDEOGRAPH + {0xEA69, 0x750B}, //11033 #CJK UNIFIED IDEOGRAPH + {0xEA6A, 0x7580}, //11034 #CJK UNIFIED IDEOGRAPH + {0xEA6B, 0x762F}, //11035 #CJK UNIFIED IDEOGRAPH + {0xEA6C, 0x762D}, //11036 #CJK UNIFIED IDEOGRAPH + {0xEA6D, 0x7631}, //11037 #CJK UNIFIED IDEOGRAPH + {0xEA6E, 0x763D}, //11038 #CJK UNIFIED IDEOGRAPH + {0xEA6F, 0x7633}, //11039 #CJK UNIFIED IDEOGRAPH + {0xEA70, 0x763C}, //11040 #CJK UNIFIED IDEOGRAPH + {0xEA71, 0x7635}, //11041 #CJK UNIFIED IDEOGRAPH + {0xEA72, 0x7632}, //11042 #CJK UNIFIED IDEOGRAPH + {0xEA73, 0x7630}, //11043 #CJK UNIFIED IDEOGRAPH + {0xEA74, 0x76BB}, //11044 #CJK UNIFIED IDEOGRAPH + {0xEA75, 0x76E6}, //11045 #CJK UNIFIED IDEOGRAPH + {0xEA76, 0x779A}, //11046 #CJK UNIFIED IDEOGRAPH + {0xEA77, 0x779D}, //11047 #CJK UNIFIED IDEOGRAPH + {0xEA78, 0x77A1}, //11048 #CJK UNIFIED IDEOGRAPH + {0xEA79, 0x779C}, //11049 #CJK UNIFIED IDEOGRAPH + {0xEA7A, 0x779B}, //11050 #CJK UNIFIED IDEOGRAPH + {0xEA7B, 0x77A2}, //11051 #CJK UNIFIED IDEOGRAPH + {0xEA7C, 0x77A3}, //11052 #CJK UNIFIED IDEOGRAPH + {0xEA7D, 0x7795}, //11053 #CJK UNIFIED IDEOGRAPH + {0xEA7E, 0x7799}, //11054 #CJK UNIFIED IDEOGRAPH + {0xEAA1, 0x7797}, //11055 #CJK UNIFIED IDEOGRAPH + {0xEAA2, 0x78DD}, //11056 #CJK UNIFIED IDEOGRAPH + {0xEAA3, 0x78E9}, //11057 #CJK UNIFIED IDEOGRAPH + {0xEAA4, 0x78E5}, //11058 #CJK UNIFIED IDEOGRAPH + {0xEAA5, 0x78EA}, //11059 #CJK UNIFIED IDEOGRAPH + {0xEAA6, 0x78DE}, //11060 #CJK UNIFIED IDEOGRAPH + {0xEAA7, 0x78E3}, //11061 #CJK UNIFIED IDEOGRAPH + {0xEAA8, 0x78DB}, //11062 #CJK UNIFIED IDEOGRAPH + {0xEAA9, 0x78E1}, //11063 #CJK UNIFIED IDEOGRAPH + {0xEAAA, 0x78E2}, //11064 #CJK UNIFIED IDEOGRAPH + {0xEAAB, 0x78ED}, //11065 #CJK UNIFIED IDEOGRAPH + {0xEAAC, 0x78DF}, //11066 #CJK UNIFIED IDEOGRAPH + {0xEAAD, 0x78E0}, //11067 #CJK UNIFIED IDEOGRAPH + {0xEAAE, 0x79A4}, //11068 #CJK UNIFIED IDEOGRAPH + {0xEAAF, 0x7A44}, //11069 #CJK UNIFIED IDEOGRAPH + {0xEAB0, 0x7A48}, //11070 #CJK UNIFIED IDEOGRAPH + {0xEAB1, 0x7A47}, //11071 #CJK UNIFIED IDEOGRAPH + {0xEAB2, 0x7AB6}, //11072 #CJK UNIFIED IDEOGRAPH + {0xEAB3, 0x7AB8}, //11073 #CJK UNIFIED IDEOGRAPH + {0xEAB4, 0x7AB5}, //11074 #CJK UNIFIED IDEOGRAPH + {0xEAB5, 0x7AB1}, //11075 #CJK UNIFIED IDEOGRAPH + {0xEAB6, 0x7AB7}, //11076 #CJK UNIFIED IDEOGRAPH + {0xEAB7, 0x7BDE}, //11077 #CJK UNIFIED IDEOGRAPH + {0xEAB8, 0x7BE3}, //11078 #CJK UNIFIED IDEOGRAPH + {0xEAB9, 0x7BE7}, //11079 #CJK UNIFIED IDEOGRAPH + {0xEABA, 0x7BDD}, //11080 #CJK UNIFIED IDEOGRAPH + {0xEABB, 0x7BD5}, //11081 #CJK UNIFIED IDEOGRAPH + {0xEABC, 0x7BE5}, //11082 #CJK UNIFIED IDEOGRAPH + {0xEABD, 0x7BDA}, //11083 #CJK UNIFIED IDEOGRAPH + {0xEABE, 0x7BE8}, //11084 #CJK UNIFIED IDEOGRAPH + {0xEABF, 0x7BF9}, //11085 #CJK UNIFIED IDEOGRAPH + {0xEAC0, 0x7BD4}, //11086 #CJK UNIFIED IDEOGRAPH + {0xEAC1, 0x7BEA}, //11087 #CJK UNIFIED IDEOGRAPH + {0xEAC2, 0x7BE2}, //11088 #CJK UNIFIED IDEOGRAPH + {0xEAC3, 0x7BDC}, //11089 #CJK UNIFIED IDEOGRAPH + {0xEAC4, 0x7BEB}, //11090 #CJK UNIFIED IDEOGRAPH + {0xEAC5, 0x7BD8}, //11091 #CJK UNIFIED IDEOGRAPH + {0xEAC6, 0x7BDF}, //11092 #CJK UNIFIED IDEOGRAPH + {0xEAC7, 0x7CD2}, //11093 #CJK UNIFIED IDEOGRAPH + {0xEAC8, 0x7CD4}, //11094 #CJK UNIFIED IDEOGRAPH + {0xEAC9, 0x7CD7}, //11095 #CJK UNIFIED IDEOGRAPH + {0xEACA, 0x7CD0}, //11096 #CJK UNIFIED IDEOGRAPH + {0xEACB, 0x7CD1}, //11097 #CJK UNIFIED IDEOGRAPH + {0xEACC, 0x7E12}, //11098 #CJK UNIFIED IDEOGRAPH + {0xEACD, 0x7E21}, //11099 #CJK UNIFIED IDEOGRAPH + {0xEACE, 0x7E17}, //11100 #CJK UNIFIED IDEOGRAPH + {0xEACF, 0x7E0C}, //11101 #CJK UNIFIED IDEOGRAPH + {0xEAD0, 0x7E1F}, //11102 #CJK UNIFIED IDEOGRAPH + {0xEAD1, 0x7E20}, //11103 #CJK UNIFIED IDEOGRAPH + {0xEAD2, 0x7E13}, //11104 #CJK UNIFIED IDEOGRAPH + {0xEAD3, 0x7E0E}, //11105 #CJK UNIFIED IDEOGRAPH + {0xEAD4, 0x7E1C}, //11106 #CJK UNIFIED IDEOGRAPH + {0xEAD5, 0x7E15}, //11107 #CJK UNIFIED IDEOGRAPH + {0xEAD6, 0x7E1A}, //11108 #CJK UNIFIED IDEOGRAPH + {0xEAD7, 0x7E22}, //11109 #CJK UNIFIED IDEOGRAPH + {0xEAD8, 0x7E0B}, //11110 #CJK UNIFIED IDEOGRAPH + {0xEAD9, 0x7E0F}, //11111 #CJK UNIFIED IDEOGRAPH + {0xEADA, 0x7E16}, //11112 #CJK UNIFIED IDEOGRAPH + {0xEADB, 0x7E0D}, //11113 #CJK UNIFIED IDEOGRAPH + {0xEADC, 0x7E14}, //11114 #CJK UNIFIED IDEOGRAPH + {0xEADD, 0x7E25}, //11115 #CJK UNIFIED IDEOGRAPH + {0xEADE, 0x7E24}, //11116 #CJK UNIFIED IDEOGRAPH + {0xEADF, 0x7F43}, //11117 #CJK UNIFIED IDEOGRAPH + {0xEAE0, 0x7F7B}, //11118 #CJK UNIFIED IDEOGRAPH + {0xEAE1, 0x7F7C}, //11119 #CJK UNIFIED IDEOGRAPH + {0xEAE2, 0x7F7A}, //11120 #CJK UNIFIED IDEOGRAPH + {0xEAE3, 0x7FB1}, //11121 #CJK UNIFIED IDEOGRAPH + {0xEAE4, 0x7FEF}, //11122 #CJK UNIFIED IDEOGRAPH + {0xEAE5, 0x802A}, //11123 #CJK UNIFIED IDEOGRAPH + {0xEAE6, 0x8029}, //11124 #CJK UNIFIED IDEOGRAPH + {0xEAE7, 0x806C}, //11125 #CJK UNIFIED IDEOGRAPH + {0xEAE8, 0x81B1}, //11126 #CJK UNIFIED IDEOGRAPH + {0xEAE9, 0x81A6}, //11127 #CJK UNIFIED IDEOGRAPH + {0xEAEA, 0x81AE}, //11128 #CJK UNIFIED IDEOGRAPH + {0xEAEB, 0x81B9}, //11129 #CJK UNIFIED IDEOGRAPH + {0xEAEC, 0x81B5}, //11130 #CJK UNIFIED IDEOGRAPH + {0xEAED, 0x81AB}, //11131 #CJK UNIFIED IDEOGRAPH + {0xEAEE, 0x81B0}, //11132 #CJK UNIFIED IDEOGRAPH + {0xEAEF, 0x81AC}, //11133 #CJK UNIFIED IDEOGRAPH + {0xEAF0, 0x81B4}, //11134 #CJK UNIFIED IDEOGRAPH + {0xEAF1, 0x81B2}, //11135 #CJK UNIFIED IDEOGRAPH + {0xEAF2, 0x81B7}, //11136 #CJK UNIFIED IDEOGRAPH + {0xEAF3, 0x81A7}, //11137 #CJK UNIFIED IDEOGRAPH + {0xEAF4, 0x81F2}, //11138 #CJK UNIFIED IDEOGRAPH + {0xEAF5, 0x8255}, //11139 #CJK UNIFIED IDEOGRAPH + {0xEAF6, 0x8256}, //11140 #CJK UNIFIED IDEOGRAPH + {0xEAF7, 0x8257}, //11141 #CJK UNIFIED IDEOGRAPH + {0xEAF8, 0x8556}, //11142 #CJK UNIFIED IDEOGRAPH + {0xEAF9, 0x8545}, //11143 #CJK UNIFIED IDEOGRAPH + {0xEAFA, 0x856B}, //11144 #CJK UNIFIED IDEOGRAPH + {0xEAFB, 0x854D}, //11145 #CJK UNIFIED IDEOGRAPH + {0xEAFC, 0x8553}, //11146 #CJK UNIFIED IDEOGRAPH + {0xEAFD, 0x8561}, //11147 #CJK UNIFIED IDEOGRAPH + {0xEAFE, 0x8558}, //11148 #CJK UNIFIED IDEOGRAPH + {0xEB40, 0x8540}, //11149 #CJK UNIFIED IDEOGRAPH + {0xEB41, 0x8546}, //11150 #CJK UNIFIED IDEOGRAPH + {0xEB42, 0x8564}, //11151 #CJK UNIFIED IDEOGRAPH + {0xEB43, 0x8541}, //11152 #CJK UNIFIED IDEOGRAPH + {0xEB44, 0x8562}, //11153 #CJK UNIFIED IDEOGRAPH + {0xEB45, 0x8544}, //11154 #CJK UNIFIED IDEOGRAPH + {0xEB46, 0x8551}, //11155 #CJK UNIFIED IDEOGRAPH + {0xEB47, 0x8547}, //11156 #CJK UNIFIED IDEOGRAPH + {0xEB48, 0x8563}, //11157 #CJK UNIFIED IDEOGRAPH + {0xEB49, 0x853E}, //11158 #CJK UNIFIED IDEOGRAPH + {0xEB4A, 0x855B}, //11159 #CJK UNIFIED IDEOGRAPH + {0xEB4B, 0x8571}, //11160 #CJK UNIFIED IDEOGRAPH + {0xEB4C, 0x854E}, //11161 #CJK UNIFIED IDEOGRAPH + {0xEB4D, 0x856E}, //11162 #CJK UNIFIED IDEOGRAPH + {0xEB4E, 0x8575}, //11163 #CJK UNIFIED IDEOGRAPH + {0xEB4F, 0x8555}, //11164 #CJK UNIFIED IDEOGRAPH + {0xEB50, 0x8567}, //11165 #CJK UNIFIED IDEOGRAPH + {0xEB51, 0x8560}, //11166 #CJK UNIFIED IDEOGRAPH + {0xEB52, 0x858C}, //11167 #CJK UNIFIED IDEOGRAPH + {0xEB53, 0x8566}, //11168 #CJK UNIFIED IDEOGRAPH + {0xEB54, 0x855D}, //11169 #CJK UNIFIED IDEOGRAPH + {0xEB55, 0x8554}, //11170 #CJK UNIFIED IDEOGRAPH + {0xEB56, 0x8565}, //11171 #CJK UNIFIED IDEOGRAPH + {0xEB57, 0x856C}, //11172 #CJK UNIFIED IDEOGRAPH + {0xEB58, 0x8663}, //11173 #CJK UNIFIED IDEOGRAPH + {0xEB59, 0x8665}, //11174 #CJK UNIFIED IDEOGRAPH + {0xEB5A, 0x8664}, //11175 #CJK UNIFIED IDEOGRAPH + {0xEB5B, 0x879B}, //11176 #CJK UNIFIED IDEOGRAPH + {0xEB5C, 0x878F}, //11177 #CJK UNIFIED IDEOGRAPH + {0xEB5D, 0x8797}, //11178 #CJK UNIFIED IDEOGRAPH + {0xEB5E, 0x8793}, //11179 #CJK UNIFIED IDEOGRAPH + {0xEB5F, 0x8792}, //11180 #CJK UNIFIED IDEOGRAPH + {0xEB60, 0x8788}, //11181 #CJK UNIFIED IDEOGRAPH + {0xEB61, 0x8781}, //11182 #CJK UNIFIED IDEOGRAPH + {0xEB62, 0x8796}, //11183 #CJK UNIFIED IDEOGRAPH + {0xEB63, 0x8798}, //11184 #CJK UNIFIED IDEOGRAPH + {0xEB64, 0x8779}, //11185 #CJK UNIFIED IDEOGRAPH + {0xEB65, 0x8787}, //11186 #CJK UNIFIED IDEOGRAPH + {0xEB66, 0x87A3}, //11187 #CJK UNIFIED IDEOGRAPH + {0xEB67, 0x8785}, //11188 #CJK UNIFIED IDEOGRAPH + {0xEB68, 0x8790}, //11189 #CJK UNIFIED IDEOGRAPH + {0xEB69, 0x8791}, //11190 #CJK UNIFIED IDEOGRAPH + {0xEB6A, 0x879D}, //11191 #CJK UNIFIED IDEOGRAPH + {0xEB6B, 0x8784}, //11192 #CJK UNIFIED IDEOGRAPH + {0xEB6C, 0x8794}, //11193 #CJK UNIFIED IDEOGRAPH + {0xEB6D, 0x879C}, //11194 #CJK UNIFIED IDEOGRAPH + {0xEB6E, 0x879A}, //11195 #CJK UNIFIED IDEOGRAPH + {0xEB6F, 0x8789}, //11196 #CJK UNIFIED IDEOGRAPH + {0xEB70, 0x891E}, //11197 #CJK UNIFIED IDEOGRAPH + {0xEB71, 0x8926}, //11198 #CJK UNIFIED IDEOGRAPH + {0xEB72, 0x8930}, //11199 #CJK UNIFIED IDEOGRAPH + {0xEB73, 0x892D}, //11200 #CJK UNIFIED IDEOGRAPH + {0xEB74, 0x892E}, //11201 #CJK UNIFIED IDEOGRAPH + {0xEB75, 0x8927}, //11202 #CJK UNIFIED IDEOGRAPH + {0xEB76, 0x8931}, //11203 #CJK UNIFIED IDEOGRAPH + {0xEB77, 0x8922}, //11204 #CJK UNIFIED IDEOGRAPH + {0xEB78, 0x8929}, //11205 #CJK UNIFIED IDEOGRAPH + {0xEB79, 0x8923}, //11206 #CJK UNIFIED IDEOGRAPH + {0xEB7A, 0x892F}, //11207 #CJK UNIFIED IDEOGRAPH + {0xEB7B, 0x892C}, //11208 #CJK UNIFIED IDEOGRAPH + {0xEB7C, 0x891F}, //11209 #CJK UNIFIED IDEOGRAPH + {0xEB7D, 0x89F1}, //11210 #CJK UNIFIED IDEOGRAPH + {0xEB7E, 0x8AE0}, //11211 #CJK UNIFIED IDEOGRAPH + {0xEBA1, 0x8AE2}, //11212 #CJK UNIFIED IDEOGRAPH + {0xEBA2, 0x8AF2}, //11213 #CJK UNIFIED IDEOGRAPH + {0xEBA3, 0x8AF4}, //11214 #CJK UNIFIED IDEOGRAPH + {0xEBA4, 0x8AF5}, //11215 #CJK UNIFIED IDEOGRAPH + {0xEBA5, 0x8ADD}, //11216 #CJK UNIFIED IDEOGRAPH + {0xEBA6, 0x8B14}, //11217 #CJK UNIFIED IDEOGRAPH + {0xEBA7, 0x8AE4}, //11218 #CJK UNIFIED IDEOGRAPH + {0xEBA8, 0x8ADF}, //11219 #CJK UNIFIED IDEOGRAPH + {0xEBA9, 0x8AF0}, //11220 #CJK UNIFIED IDEOGRAPH + {0xEBAA, 0x8AC8}, //11221 #CJK UNIFIED IDEOGRAPH + {0xEBAB, 0x8ADE}, //11222 #CJK UNIFIED IDEOGRAPH + {0xEBAC, 0x8AE1}, //11223 #CJK UNIFIED IDEOGRAPH + {0xEBAD, 0x8AE8}, //11224 #CJK UNIFIED IDEOGRAPH + {0xEBAE, 0x8AFF}, //11225 #CJK UNIFIED IDEOGRAPH + {0xEBAF, 0x8AEF}, //11226 #CJK UNIFIED IDEOGRAPH + {0xEBB0, 0x8AFB}, //11227 #CJK UNIFIED IDEOGRAPH + {0xEBB1, 0x8C91}, //11228 #CJK UNIFIED IDEOGRAPH + {0xEBB2, 0x8C92}, //11229 #CJK UNIFIED IDEOGRAPH + {0xEBB3, 0x8C90}, //11230 #CJK UNIFIED IDEOGRAPH + {0xEBB4, 0x8CF5}, //11231 #CJK UNIFIED IDEOGRAPH + {0xEBB5, 0x8CEE}, //11232 #CJK UNIFIED IDEOGRAPH + {0xEBB6, 0x8CF1}, //11233 #CJK UNIFIED IDEOGRAPH + {0xEBB7, 0x8CF0}, //11234 #CJK UNIFIED IDEOGRAPH + {0xEBB8, 0x8CF3}, //11235 #CJK UNIFIED IDEOGRAPH + {0xEBB9, 0x8D6C}, //11236 #CJK UNIFIED IDEOGRAPH + {0xEBBA, 0x8D6E}, //11237 #CJK UNIFIED IDEOGRAPH + {0xEBBB, 0x8DA5}, //11238 #CJK UNIFIED IDEOGRAPH + {0xEBBC, 0x8DA7}, //11239 #CJK UNIFIED IDEOGRAPH + {0xEBBD, 0x8E33}, //11240 #CJK UNIFIED IDEOGRAPH + {0xEBBE, 0x8E3E}, //11241 #CJK UNIFIED IDEOGRAPH + {0xEBBF, 0x8E38}, //11242 #CJK UNIFIED IDEOGRAPH + {0xEBC0, 0x8E40}, //11243 #CJK UNIFIED IDEOGRAPH + {0xEBC1, 0x8E45}, //11244 #CJK UNIFIED IDEOGRAPH + {0xEBC2, 0x8E36}, //11245 #CJK UNIFIED IDEOGRAPH + {0xEBC3, 0x8E3C}, //11246 #CJK UNIFIED IDEOGRAPH + {0xEBC4, 0x8E3D}, //11247 #CJK UNIFIED IDEOGRAPH + {0xEBC5, 0x8E41}, //11248 #CJK UNIFIED IDEOGRAPH + {0xEBC6, 0x8E30}, //11249 #CJK UNIFIED IDEOGRAPH + {0xEBC7, 0x8E3F}, //11250 #CJK UNIFIED IDEOGRAPH + {0xEBC8, 0x8EBD}, //11251 #CJK UNIFIED IDEOGRAPH + {0xEBC9, 0x8F36}, //11252 #CJK UNIFIED IDEOGRAPH + {0xEBCA, 0x8F2E}, //11253 #CJK UNIFIED IDEOGRAPH + {0xEBCB, 0x8F35}, //11254 #CJK UNIFIED IDEOGRAPH + {0xEBCC, 0x8F32}, //11255 #CJK UNIFIED IDEOGRAPH + {0xEBCD, 0x8F39}, //11256 #CJK UNIFIED IDEOGRAPH + {0xEBCE, 0x8F37}, //11257 #CJK UNIFIED IDEOGRAPH + {0xEBCF, 0x8F34}, //11258 #CJK UNIFIED IDEOGRAPH + {0xEBD0, 0x9076}, //11259 #CJK UNIFIED IDEOGRAPH + {0xEBD1, 0x9079}, //11260 #CJK UNIFIED IDEOGRAPH + {0xEBD2, 0x907B}, //11261 #CJK UNIFIED IDEOGRAPH + {0xEBD3, 0x9086}, //11262 #CJK UNIFIED IDEOGRAPH + {0xEBD4, 0x90FA}, //11263 #CJK UNIFIED IDEOGRAPH + {0xEBD5, 0x9133}, //11264 #CJK UNIFIED IDEOGRAPH + {0xEBD6, 0x9135}, //11265 #CJK UNIFIED IDEOGRAPH + {0xEBD7, 0x9136}, //11266 #CJK UNIFIED IDEOGRAPH + {0xEBD8, 0x9193}, //11267 #CJK UNIFIED IDEOGRAPH + {0xEBD9, 0x9190}, //11268 #CJK UNIFIED IDEOGRAPH + {0xEBDA, 0x9191}, //11269 #CJK UNIFIED IDEOGRAPH + {0xEBDB, 0x918D}, //11270 #CJK UNIFIED IDEOGRAPH + {0xEBDC, 0x918F}, //11271 #CJK UNIFIED IDEOGRAPH + {0xEBDD, 0x9327}, //11272 #CJK UNIFIED IDEOGRAPH + {0xEBDE, 0x931E}, //11273 #CJK UNIFIED IDEOGRAPH + {0xEBDF, 0x9308}, //11274 #CJK UNIFIED IDEOGRAPH + {0xEBE0, 0x931F}, //11275 #CJK UNIFIED IDEOGRAPH + {0xEBE1, 0x9306}, //11276 #CJK UNIFIED IDEOGRAPH + {0xEBE2, 0x930F}, //11277 #CJK UNIFIED IDEOGRAPH + {0xEBE3, 0x937A}, //11278 #CJK UNIFIED IDEOGRAPH + {0xEBE4, 0x9338}, //11279 #CJK UNIFIED IDEOGRAPH + {0xEBE5, 0x933C}, //11280 #CJK UNIFIED IDEOGRAPH + {0xEBE6, 0x931B}, //11281 #CJK UNIFIED IDEOGRAPH + {0xEBE7, 0x9323}, //11282 #CJK UNIFIED IDEOGRAPH + {0xEBE8, 0x9312}, //11283 #CJK UNIFIED IDEOGRAPH + {0xEBE9, 0x9301}, //11284 #CJK UNIFIED IDEOGRAPH + {0xEBEA, 0x9346}, //11285 #CJK UNIFIED IDEOGRAPH + {0xEBEB, 0x932D}, //11286 #CJK UNIFIED IDEOGRAPH + {0xEBEC, 0x930E}, //11287 #CJK UNIFIED IDEOGRAPH + {0xEBED, 0x930D}, //11288 #CJK UNIFIED IDEOGRAPH + {0xEBEE, 0x92CB}, //11289 #CJK UNIFIED IDEOGRAPH + {0xEBEF, 0x931D}, //11290 #CJK UNIFIED IDEOGRAPH + {0xEBF0, 0x92FA}, //11291 #CJK UNIFIED IDEOGRAPH + {0xEBF1, 0x9325}, //11292 #CJK UNIFIED IDEOGRAPH + {0xEBF2, 0x9313}, //11293 #CJK UNIFIED IDEOGRAPH + {0xEBF3, 0x92F9}, //11294 #CJK UNIFIED IDEOGRAPH + {0xEBF4, 0x92F7}, //11295 #CJK UNIFIED IDEOGRAPH + {0xEBF5, 0x9334}, //11296 #CJK UNIFIED IDEOGRAPH + {0xEBF6, 0x9302}, //11297 #CJK UNIFIED IDEOGRAPH + {0xEBF7, 0x9324}, //11298 #CJK UNIFIED IDEOGRAPH + {0xEBF8, 0x92FF}, //11299 #CJK UNIFIED IDEOGRAPH + {0xEBF9, 0x9329}, //11300 #CJK UNIFIED IDEOGRAPH + {0xEBFA, 0x9339}, //11301 #CJK UNIFIED IDEOGRAPH + {0xEBFB, 0x9335}, //11302 #CJK UNIFIED IDEOGRAPH + {0xEBFC, 0x932A}, //11303 #CJK UNIFIED IDEOGRAPH + {0xEBFD, 0x9314}, //11304 #CJK UNIFIED IDEOGRAPH + {0xEBFE, 0x930C}, //11305 #CJK UNIFIED IDEOGRAPH + {0xEC40, 0x930B}, //11306 #CJK UNIFIED IDEOGRAPH + {0xEC41, 0x92FE}, //11307 #CJK UNIFIED IDEOGRAPH + {0xEC42, 0x9309}, //11308 #CJK UNIFIED IDEOGRAPH + {0xEC43, 0x9300}, //11309 #CJK UNIFIED IDEOGRAPH + {0xEC44, 0x92FB}, //11310 #CJK UNIFIED IDEOGRAPH + {0xEC45, 0x9316}, //11311 #CJK UNIFIED IDEOGRAPH + {0xEC46, 0x95BC}, //11312 #CJK UNIFIED IDEOGRAPH + {0xEC47, 0x95CD}, //11313 #CJK UNIFIED IDEOGRAPH + {0xEC48, 0x95BE}, //11314 #CJK UNIFIED IDEOGRAPH + {0xEC49, 0x95B9}, //11315 #CJK UNIFIED IDEOGRAPH + {0xEC4A, 0x95BA}, //11316 #CJK UNIFIED IDEOGRAPH + {0xEC4B, 0x95B6}, //11317 #CJK UNIFIED IDEOGRAPH + {0xEC4C, 0x95BF}, //11318 #CJK UNIFIED IDEOGRAPH + {0xEC4D, 0x95B5}, //11319 #CJK UNIFIED IDEOGRAPH + {0xEC4E, 0x95BD}, //11320 #CJK UNIFIED IDEOGRAPH + {0xEC4F, 0x96A9}, //11321 #CJK UNIFIED IDEOGRAPH + {0xEC50, 0x96D4}, //11322 #CJK UNIFIED IDEOGRAPH + {0xEC51, 0x970B}, //11323 #CJK UNIFIED IDEOGRAPH + {0xEC52, 0x9712}, //11324 #CJK UNIFIED IDEOGRAPH + {0xEC53, 0x9710}, //11325 #CJK UNIFIED IDEOGRAPH + {0xEC54, 0x9799}, //11326 #CJK UNIFIED IDEOGRAPH + {0xEC55, 0x9797}, //11327 #CJK UNIFIED IDEOGRAPH + {0xEC56, 0x9794}, //11328 #CJK UNIFIED IDEOGRAPH + {0xEC57, 0x97F0}, //11329 #CJK UNIFIED IDEOGRAPH + {0xEC58, 0x97F8}, //11330 #CJK UNIFIED IDEOGRAPH + {0xEC59, 0x9835}, //11331 #CJK UNIFIED IDEOGRAPH + {0xEC5A, 0x982F}, //11332 #CJK UNIFIED IDEOGRAPH + {0xEC5B, 0x9832}, //11333 #CJK UNIFIED IDEOGRAPH + {0xEC5C, 0x9924}, //11334 #CJK UNIFIED IDEOGRAPH + {0xEC5D, 0x991F}, //11335 #CJK UNIFIED IDEOGRAPH + {0xEC5E, 0x9927}, //11336 #CJK UNIFIED IDEOGRAPH + {0xEC5F, 0x9929}, //11337 #CJK UNIFIED IDEOGRAPH + {0xEC60, 0x999E}, //11338 #CJK UNIFIED IDEOGRAPH + {0xEC61, 0x99EE}, //11339 #CJK UNIFIED IDEOGRAPH + {0xEC62, 0x99EC}, //11340 #CJK UNIFIED IDEOGRAPH + {0xEC63, 0x99E5}, //11341 #CJK UNIFIED IDEOGRAPH + {0xEC64, 0x99E4}, //11342 #CJK UNIFIED IDEOGRAPH + {0xEC65, 0x99F0}, //11343 #CJK UNIFIED IDEOGRAPH + {0xEC66, 0x99E3}, //11344 #CJK UNIFIED IDEOGRAPH + {0xEC67, 0x99EA}, //11345 #CJK UNIFIED IDEOGRAPH + {0xEC68, 0x99E9}, //11346 #CJK UNIFIED IDEOGRAPH + {0xEC69, 0x99E7}, //11347 #CJK UNIFIED IDEOGRAPH + {0xEC6A, 0x9AB9}, //11348 #CJK UNIFIED IDEOGRAPH + {0xEC6B, 0x9ABF}, //11349 #CJK UNIFIED IDEOGRAPH + {0xEC6C, 0x9AB4}, //11350 #CJK UNIFIED IDEOGRAPH + {0xEC6D, 0x9ABB}, //11351 #CJK UNIFIED IDEOGRAPH + {0xEC6E, 0x9AF6}, //11352 #CJK UNIFIED IDEOGRAPH + {0xEC6F, 0x9AFA}, //11353 #CJK UNIFIED IDEOGRAPH + {0xEC70, 0x9AF9}, //11354 #CJK UNIFIED IDEOGRAPH + {0xEC71, 0x9AF7}, //11355 #CJK UNIFIED IDEOGRAPH + {0xEC72, 0x9B33}, //11356 #CJK UNIFIED IDEOGRAPH + {0xEC73, 0x9B80}, //11357 #CJK UNIFIED IDEOGRAPH + {0xEC74, 0x9B85}, //11358 #CJK UNIFIED IDEOGRAPH + {0xEC75, 0x9B87}, //11359 #CJK UNIFIED IDEOGRAPH + {0xEC76, 0x9B7C}, //11360 #CJK UNIFIED IDEOGRAPH + {0xEC77, 0x9B7E}, //11361 #CJK UNIFIED IDEOGRAPH + {0xEC78, 0x9B7B}, //11362 #CJK UNIFIED IDEOGRAPH + {0xEC79, 0x9B82}, //11363 #CJK UNIFIED IDEOGRAPH + {0xEC7A, 0x9B93}, //11364 #CJK UNIFIED IDEOGRAPH + {0xEC7B, 0x9B92}, //11365 #CJK UNIFIED IDEOGRAPH + {0xEC7C, 0x9B90}, //11366 #CJK UNIFIED IDEOGRAPH + {0xEC7D, 0x9B7A}, //11367 #CJK UNIFIED IDEOGRAPH + {0xEC7E, 0x9B95}, //11368 #CJK UNIFIED IDEOGRAPH + {0xECA1, 0x9B7D}, //11369 #CJK UNIFIED IDEOGRAPH + {0xECA2, 0x9B88}, //11370 #CJK UNIFIED IDEOGRAPH + {0xECA3, 0x9D25}, //11371 #CJK UNIFIED IDEOGRAPH + {0xECA4, 0x9D17}, //11372 #CJK UNIFIED IDEOGRAPH + {0xECA5, 0x9D20}, //11373 #CJK UNIFIED IDEOGRAPH + {0xECA6, 0x9D1E}, //11374 #CJK UNIFIED IDEOGRAPH + {0xECA7, 0x9D14}, //11375 #CJK UNIFIED IDEOGRAPH + {0xECA8, 0x9D29}, //11376 #CJK UNIFIED IDEOGRAPH + {0xECA9, 0x9D1D}, //11377 #CJK UNIFIED IDEOGRAPH + {0xECAA, 0x9D18}, //11378 #CJK UNIFIED IDEOGRAPH + {0xECAB, 0x9D22}, //11379 #CJK UNIFIED IDEOGRAPH + {0xECAC, 0x9D10}, //11380 #CJK UNIFIED IDEOGRAPH + {0xECAD, 0x9D19}, //11381 #CJK UNIFIED IDEOGRAPH + {0xECAE, 0x9D1F}, //11382 #CJK UNIFIED IDEOGRAPH + {0xECAF, 0x9E88}, //11383 #CJK UNIFIED IDEOGRAPH + {0xECB0, 0x9E86}, //11384 #CJK UNIFIED IDEOGRAPH + {0xECB1, 0x9E87}, //11385 #CJK UNIFIED IDEOGRAPH + {0xECB2, 0x9EAE}, //11386 #CJK UNIFIED IDEOGRAPH + {0xECB3, 0x9EAD}, //11387 #CJK UNIFIED IDEOGRAPH + {0xECB4, 0x9ED5}, //11388 #CJK UNIFIED IDEOGRAPH + {0xECB5, 0x9ED6}, //11389 #CJK UNIFIED IDEOGRAPH + {0xECB6, 0x9EFA}, //11390 #CJK UNIFIED IDEOGRAPH + {0xECB7, 0x9F12}, //11391 #CJK UNIFIED IDEOGRAPH + {0xECB8, 0x9F3D}, //11392 #CJK UNIFIED IDEOGRAPH + {0xECB9, 0x5126}, //11393 #CJK UNIFIED IDEOGRAPH + {0xECBA, 0x5125}, //11394 #CJK UNIFIED IDEOGRAPH + {0xECBB, 0x5122}, //11395 #CJK UNIFIED IDEOGRAPH + {0xECBC, 0x5124}, //11396 #CJK UNIFIED IDEOGRAPH + {0xECBD, 0x5120}, //11397 #CJK UNIFIED IDEOGRAPH + {0xECBE, 0x5129}, //11398 #CJK UNIFIED IDEOGRAPH + {0xECBF, 0x52F4}, //11399 #CJK UNIFIED IDEOGRAPH + {0xECC0, 0x5693}, //11400 #CJK UNIFIED IDEOGRAPH + {0xECC1, 0x568C}, //11401 #CJK UNIFIED IDEOGRAPH + {0xECC2, 0x568D}, //11402 #CJK UNIFIED IDEOGRAPH + {0xECC3, 0x5686}, //11403 #CJK UNIFIED IDEOGRAPH + {0xECC4, 0x5684}, //11404 #CJK UNIFIED IDEOGRAPH + {0xECC5, 0x5683}, //11405 #CJK UNIFIED IDEOGRAPH + {0xECC6, 0x567E}, //11406 #CJK UNIFIED IDEOGRAPH + {0xECC7, 0x5682}, //11407 #CJK UNIFIED IDEOGRAPH + {0xECC8, 0x567F}, //11408 #CJK UNIFIED IDEOGRAPH + {0xECC9, 0x5681}, //11409 #CJK UNIFIED IDEOGRAPH + {0xECCA, 0x58D6}, //11410 #CJK UNIFIED IDEOGRAPH + {0xECCB, 0x58D4}, //11411 #CJK UNIFIED IDEOGRAPH + {0xECCC, 0x58CF}, //11412 #CJK UNIFIED IDEOGRAPH + {0xECCD, 0x58D2}, //11413 #CJK UNIFIED IDEOGRAPH + {0xECCE, 0x5B2D}, //11414 #CJK UNIFIED IDEOGRAPH + {0xECCF, 0x5B25}, //11415 #CJK UNIFIED IDEOGRAPH + {0xECD0, 0x5B32}, //11416 #CJK UNIFIED IDEOGRAPH + {0xECD1, 0x5B23}, //11417 #CJK UNIFIED IDEOGRAPH + {0xECD2, 0x5B2C}, //11418 #CJK UNIFIED IDEOGRAPH + {0xECD3, 0x5B27}, //11419 #CJK UNIFIED IDEOGRAPH + {0xECD4, 0x5B26}, //11420 #CJK UNIFIED IDEOGRAPH + {0xECD5, 0x5B2F}, //11421 #CJK UNIFIED IDEOGRAPH + {0xECD6, 0x5B2E}, //11422 #CJK UNIFIED IDEOGRAPH + {0xECD7, 0x5B7B}, //11423 #CJK UNIFIED IDEOGRAPH + {0xECD8, 0x5BF1}, //11424 #CJK UNIFIED IDEOGRAPH + {0xECD9, 0x5BF2}, //11425 #CJK UNIFIED IDEOGRAPH + {0xECDA, 0x5DB7}, //11426 #CJK UNIFIED IDEOGRAPH + {0xECDB, 0x5E6C}, //11427 #CJK UNIFIED IDEOGRAPH + {0xECDC, 0x5E6A}, //11428 #CJK UNIFIED IDEOGRAPH + {0xECDD, 0x5FBE}, //11429 #CJK UNIFIED IDEOGRAPH + {0xECDE, 0x5FBB}, //11430 #CJK UNIFIED IDEOGRAPH + {0xECDF, 0x61C3}, //11431 #CJK UNIFIED IDEOGRAPH + {0xECE0, 0x61B5}, //11432 #CJK UNIFIED IDEOGRAPH + {0xECE1, 0x61BC}, //11433 #CJK UNIFIED IDEOGRAPH + {0xECE2, 0x61E7}, //11434 #CJK UNIFIED IDEOGRAPH + {0xECE3, 0x61E0}, //11435 #CJK UNIFIED IDEOGRAPH + {0xECE4, 0x61E5}, //11436 #CJK UNIFIED IDEOGRAPH + {0xECE5, 0x61E4}, //11437 #CJK UNIFIED IDEOGRAPH + {0xECE6, 0x61E8}, //11438 #CJK UNIFIED IDEOGRAPH + {0xECE7, 0x61DE}, //11439 #CJK UNIFIED IDEOGRAPH + {0xECE8, 0x64EF}, //11440 #CJK UNIFIED IDEOGRAPH + {0xECE9, 0x64E9}, //11441 #CJK UNIFIED IDEOGRAPH + {0xECEA, 0x64E3}, //11442 #CJK UNIFIED IDEOGRAPH + {0xECEB, 0x64EB}, //11443 #CJK UNIFIED IDEOGRAPH + {0xECEC, 0x64E4}, //11444 #CJK UNIFIED IDEOGRAPH + {0xECED, 0x64E8}, //11445 #CJK UNIFIED IDEOGRAPH + {0xECEE, 0x6581}, //11446 #CJK UNIFIED IDEOGRAPH + {0xECEF, 0x6580}, //11447 #CJK UNIFIED IDEOGRAPH + {0xECF0, 0x65B6}, //11448 #CJK UNIFIED IDEOGRAPH + {0xECF1, 0x65DA}, //11449 #CJK UNIFIED IDEOGRAPH + {0xECF2, 0x66D2}, //11450 #CJK UNIFIED IDEOGRAPH + {0xECF3, 0x6A8D}, //11451 #CJK UNIFIED IDEOGRAPH + {0xECF4, 0x6A96}, //11452 #CJK UNIFIED IDEOGRAPH + {0xECF5, 0x6A81}, //11453 #CJK UNIFIED IDEOGRAPH + {0xECF6, 0x6AA5}, //11454 #CJK UNIFIED IDEOGRAPH + {0xECF7, 0x6A89}, //11455 #CJK UNIFIED IDEOGRAPH + {0xECF8, 0x6A9F}, //11456 #CJK UNIFIED IDEOGRAPH + {0xECF9, 0x6A9B}, //11457 #CJK UNIFIED IDEOGRAPH + {0xECFA, 0x6AA1}, //11458 #CJK UNIFIED IDEOGRAPH + {0xECFB, 0x6A9E}, //11459 #CJK UNIFIED IDEOGRAPH + {0xECFC, 0x6A87}, //11460 #CJK UNIFIED IDEOGRAPH + {0xECFD, 0x6A93}, //11461 #CJK UNIFIED IDEOGRAPH + {0xECFE, 0x6A8E}, //11462 #CJK UNIFIED IDEOGRAPH + {0xED40, 0x6A95}, //11463 #CJK UNIFIED IDEOGRAPH + {0xED41, 0x6A83}, //11464 #CJK UNIFIED IDEOGRAPH + {0xED42, 0x6AA8}, //11465 #CJK UNIFIED IDEOGRAPH + {0xED43, 0x6AA4}, //11466 #CJK UNIFIED IDEOGRAPH + {0xED44, 0x6A91}, //11467 #CJK UNIFIED IDEOGRAPH + {0xED45, 0x6A7F}, //11468 #CJK UNIFIED IDEOGRAPH + {0xED46, 0x6AA6}, //11469 #CJK UNIFIED IDEOGRAPH + {0xED47, 0x6A9A}, //11470 #CJK UNIFIED IDEOGRAPH + {0xED48, 0x6A85}, //11471 #CJK UNIFIED IDEOGRAPH + {0xED49, 0x6A8C}, //11472 #CJK UNIFIED IDEOGRAPH + {0xED4A, 0x6A92}, //11473 #CJK UNIFIED IDEOGRAPH + {0xED4B, 0x6B5B}, //11474 #CJK UNIFIED IDEOGRAPH + {0xED4C, 0x6BAD}, //11475 #CJK UNIFIED IDEOGRAPH + {0xED4D, 0x6C09}, //11476 #CJK UNIFIED IDEOGRAPH + {0xED4E, 0x6FCC}, //11477 #CJK UNIFIED IDEOGRAPH + {0xED4F, 0x6FA9}, //11478 #CJK UNIFIED IDEOGRAPH + {0xED50, 0x6FF4}, //11479 #CJK UNIFIED IDEOGRAPH + {0xED51, 0x6FD4}, //11480 #CJK UNIFIED IDEOGRAPH + {0xED52, 0x6FE3}, //11481 #CJK UNIFIED IDEOGRAPH + {0xED53, 0x6FDC}, //11482 #CJK UNIFIED IDEOGRAPH + {0xED54, 0x6FED}, //11483 #CJK UNIFIED IDEOGRAPH + {0xED55, 0x6FE7}, //11484 #CJK UNIFIED IDEOGRAPH + {0xED56, 0x6FE6}, //11485 #CJK UNIFIED IDEOGRAPH + {0xED57, 0x6FDE}, //11486 #CJK UNIFIED IDEOGRAPH + {0xED58, 0x6FF2}, //11487 #CJK UNIFIED IDEOGRAPH + {0xED59, 0x6FDD}, //11488 #CJK UNIFIED IDEOGRAPH + {0xED5A, 0x6FE2}, //11489 #CJK UNIFIED IDEOGRAPH + {0xED5B, 0x6FE8}, //11490 #CJK UNIFIED IDEOGRAPH + {0xED5C, 0x71E1}, //11491 #CJK UNIFIED IDEOGRAPH + {0xED5D, 0x71F1}, //11492 #CJK UNIFIED IDEOGRAPH + {0xED5E, 0x71E8}, //11493 #CJK UNIFIED IDEOGRAPH + {0xED5F, 0x71F2}, //11494 #CJK UNIFIED IDEOGRAPH + {0xED60, 0x71E4}, //11495 #CJK UNIFIED IDEOGRAPH + {0xED61, 0x71F0}, //11496 #CJK UNIFIED IDEOGRAPH + {0xED62, 0x71E2}, //11497 #CJK UNIFIED IDEOGRAPH + {0xED63, 0x7373}, //11498 #CJK UNIFIED IDEOGRAPH + {0xED64, 0x736E}, //11499 #CJK UNIFIED IDEOGRAPH + {0xED65, 0x736F}, //11500 #CJK UNIFIED IDEOGRAPH + {0xED66, 0x7497}, //11501 #CJK UNIFIED IDEOGRAPH + {0xED67, 0x74B2}, //11502 #CJK UNIFIED IDEOGRAPH + {0xED68, 0x74AB}, //11503 #CJK UNIFIED IDEOGRAPH + {0xED69, 0x7490}, //11504 #CJK UNIFIED IDEOGRAPH + {0xED6A, 0x74AA}, //11505 #CJK UNIFIED IDEOGRAPH + {0xED6B, 0x74AD}, //11506 #CJK UNIFIED IDEOGRAPH + {0xED6C, 0x74B1}, //11507 #CJK UNIFIED IDEOGRAPH + {0xED6D, 0x74A5}, //11508 #CJK UNIFIED IDEOGRAPH + {0xED6E, 0x74AF}, //11509 #CJK UNIFIED IDEOGRAPH + {0xED6F, 0x7510}, //11510 #CJK UNIFIED IDEOGRAPH + {0xED70, 0x7511}, //11511 #CJK UNIFIED IDEOGRAPH + {0xED71, 0x7512}, //11512 #CJK UNIFIED IDEOGRAPH + {0xED72, 0x750F}, //11513 #CJK UNIFIED IDEOGRAPH + {0xED73, 0x7584}, //11514 #CJK UNIFIED IDEOGRAPH + {0xED74, 0x7643}, //11515 #CJK UNIFIED IDEOGRAPH + {0xED75, 0x7648}, //11516 #CJK UNIFIED IDEOGRAPH + {0xED76, 0x7649}, //11517 #CJK UNIFIED IDEOGRAPH + {0xED77, 0x7647}, //11518 #CJK UNIFIED IDEOGRAPH + {0xED78, 0x76A4}, //11519 #CJK UNIFIED IDEOGRAPH + {0xED79, 0x76E9}, //11520 #CJK UNIFIED IDEOGRAPH + {0xED7A, 0x77B5}, //11521 #CJK UNIFIED IDEOGRAPH + {0xED7B, 0x77AB}, //11522 #CJK UNIFIED IDEOGRAPH + {0xED7C, 0x77B2}, //11523 #CJK UNIFIED IDEOGRAPH + {0xED7D, 0x77B7}, //11524 #CJK UNIFIED IDEOGRAPH + {0xED7E, 0x77B6}, //11525 #CJK UNIFIED IDEOGRAPH + {0xEDA1, 0x77B4}, //11526 #CJK UNIFIED IDEOGRAPH + {0xEDA2, 0x77B1}, //11527 #CJK UNIFIED IDEOGRAPH + {0xEDA3, 0x77A8}, //11528 #CJK UNIFIED IDEOGRAPH + {0xEDA4, 0x77F0}, //11529 #CJK UNIFIED IDEOGRAPH + {0xEDA5, 0x78F3}, //11530 #CJK UNIFIED IDEOGRAPH + {0xEDA6, 0x78FD}, //11531 #CJK UNIFIED IDEOGRAPH + {0xEDA7, 0x7902}, //11532 #CJK UNIFIED IDEOGRAPH + {0xEDA8, 0x78FB}, //11533 #CJK UNIFIED IDEOGRAPH + {0xEDA9, 0x78FC}, //11534 #CJK UNIFIED IDEOGRAPH + {0xEDAA, 0x78F2}, //11535 #CJK UNIFIED IDEOGRAPH + {0xEDAB, 0x7905}, //11536 #CJK UNIFIED IDEOGRAPH + {0xEDAC, 0x78F9}, //11537 #CJK UNIFIED IDEOGRAPH + {0xEDAD, 0x78FE}, //11538 #CJK UNIFIED IDEOGRAPH + {0xEDAE, 0x7904}, //11539 #CJK UNIFIED IDEOGRAPH + {0xEDAF, 0x79AB}, //11540 #CJK UNIFIED IDEOGRAPH + {0xEDB0, 0x79A8}, //11541 #CJK UNIFIED IDEOGRAPH + {0xEDB1, 0x7A5C}, //11542 #CJK UNIFIED IDEOGRAPH + {0xEDB2, 0x7A5B}, //11543 #CJK UNIFIED IDEOGRAPH + {0xEDB3, 0x7A56}, //11544 #CJK UNIFIED IDEOGRAPH + {0xEDB4, 0x7A58}, //11545 #CJK UNIFIED IDEOGRAPH + {0xEDB5, 0x7A54}, //11546 #CJK UNIFIED IDEOGRAPH + {0xEDB6, 0x7A5A}, //11547 #CJK UNIFIED IDEOGRAPH + {0xEDB7, 0x7ABE}, //11548 #CJK UNIFIED IDEOGRAPH + {0xEDB8, 0x7AC0}, //11549 #CJK UNIFIED IDEOGRAPH + {0xEDB9, 0x7AC1}, //11550 #CJK UNIFIED IDEOGRAPH + {0xEDBA, 0x7C05}, //11551 #CJK UNIFIED IDEOGRAPH + {0xEDBB, 0x7C0F}, //11552 #CJK UNIFIED IDEOGRAPH + {0xEDBC, 0x7BF2}, //11553 #CJK UNIFIED IDEOGRAPH + {0xEDBD, 0x7C00}, //11554 #CJK UNIFIED IDEOGRAPH + {0xEDBE, 0x7BFF}, //11555 #CJK UNIFIED IDEOGRAPH + {0xEDBF, 0x7BFB}, //11556 #CJK UNIFIED IDEOGRAPH + {0xEDC0, 0x7C0E}, //11557 #CJK UNIFIED IDEOGRAPH + {0xEDC1, 0x7BF4}, //11558 #CJK UNIFIED IDEOGRAPH + {0xEDC2, 0x7C0B}, //11559 #CJK UNIFIED IDEOGRAPH + {0xEDC3, 0x7BF3}, //11560 #CJK UNIFIED IDEOGRAPH + {0xEDC4, 0x7C02}, //11561 #CJK UNIFIED IDEOGRAPH + {0xEDC5, 0x7C09}, //11562 #CJK UNIFIED IDEOGRAPH + {0xEDC6, 0x7C03}, //11563 #CJK UNIFIED IDEOGRAPH + {0xEDC7, 0x7C01}, //11564 #CJK UNIFIED IDEOGRAPH + {0xEDC8, 0x7BF8}, //11565 #CJK UNIFIED IDEOGRAPH + {0xEDC9, 0x7BFD}, //11566 #CJK UNIFIED IDEOGRAPH + {0xEDCA, 0x7C06}, //11567 #CJK UNIFIED IDEOGRAPH + {0xEDCB, 0x7BF0}, //11568 #CJK UNIFIED IDEOGRAPH + {0xEDCC, 0x7BF1}, //11569 #CJK UNIFIED IDEOGRAPH + {0xEDCD, 0x7C10}, //11570 #CJK UNIFIED IDEOGRAPH + {0xEDCE, 0x7C0A}, //11571 #CJK UNIFIED IDEOGRAPH + {0xEDCF, 0x7CE8}, //11572 #CJK UNIFIED IDEOGRAPH + {0xEDD0, 0x7E2D}, //11573 #CJK UNIFIED IDEOGRAPH + {0xEDD1, 0x7E3C}, //11574 #CJK UNIFIED IDEOGRAPH + {0xEDD2, 0x7E42}, //11575 #CJK UNIFIED IDEOGRAPH + {0xEDD3, 0x7E33}, //11576 #CJK UNIFIED IDEOGRAPH + {0xEDD4, 0x9848}, //11577 #CJK UNIFIED IDEOGRAPH + {0xEDD5, 0x7E38}, //11578 #CJK UNIFIED IDEOGRAPH + {0xEDD6, 0x7E2A}, //11579 #CJK UNIFIED IDEOGRAPH + {0xEDD7, 0x7E49}, //11580 #CJK UNIFIED IDEOGRAPH + {0xEDD8, 0x7E40}, //11581 #CJK UNIFIED IDEOGRAPH + {0xEDD9, 0x7E47}, //11582 #CJK UNIFIED IDEOGRAPH + {0xEDDA, 0x7E29}, //11583 #CJK UNIFIED IDEOGRAPH + {0xEDDB, 0x7E4C}, //11584 #CJK UNIFIED IDEOGRAPH + {0xEDDC, 0x7E30}, //11585 #CJK UNIFIED IDEOGRAPH + {0xEDDD, 0x7E3B}, //11586 #CJK UNIFIED IDEOGRAPH + {0xEDDE, 0x7E36}, //11587 #CJK UNIFIED IDEOGRAPH + {0xEDDF, 0x7E44}, //11588 #CJK UNIFIED IDEOGRAPH + {0xEDE0, 0x7E3A}, //11589 #CJK UNIFIED IDEOGRAPH + {0xEDE1, 0x7F45}, //11590 #CJK UNIFIED IDEOGRAPH + {0xEDE2, 0x7F7F}, //11591 #CJK UNIFIED IDEOGRAPH + {0xEDE3, 0x7F7E}, //11592 #CJK UNIFIED IDEOGRAPH + {0xEDE4, 0x7F7D}, //11593 #CJK UNIFIED IDEOGRAPH + {0xEDE5, 0x7FF4}, //11594 #CJK UNIFIED IDEOGRAPH + {0xEDE6, 0x7FF2}, //11595 #CJK UNIFIED IDEOGRAPH + {0xEDE7, 0x802C}, //11596 #CJK UNIFIED IDEOGRAPH + {0xEDE8, 0x81BB}, //11597 #CJK UNIFIED IDEOGRAPH + {0xEDE9, 0x81C4}, //11598 #CJK UNIFIED IDEOGRAPH + {0xEDEA, 0x81CC}, //11599 #CJK UNIFIED IDEOGRAPH + {0xEDEB, 0x81CA}, //11600 #CJK UNIFIED IDEOGRAPH + {0xEDEC, 0x81C5}, //11601 #CJK UNIFIED IDEOGRAPH + {0xEDED, 0x81C7}, //11602 #CJK UNIFIED IDEOGRAPH + {0xEDEE, 0x81BC}, //11603 #CJK UNIFIED IDEOGRAPH + {0xEDEF, 0x81E9}, //11604 #CJK UNIFIED IDEOGRAPH + {0xEDF0, 0x825B}, //11605 #CJK UNIFIED IDEOGRAPH + {0xEDF1, 0x825A}, //11606 #CJK UNIFIED IDEOGRAPH + {0xEDF2, 0x825C}, //11607 #CJK UNIFIED IDEOGRAPH + {0xEDF3, 0x8583}, //11608 #CJK UNIFIED IDEOGRAPH + {0xEDF4, 0x8580}, //11609 #CJK UNIFIED IDEOGRAPH + {0xEDF5, 0x858F}, //11610 #CJK UNIFIED IDEOGRAPH + {0xEDF6, 0x85A7}, //11611 #CJK UNIFIED IDEOGRAPH + {0xEDF7, 0x8595}, //11612 #CJK UNIFIED IDEOGRAPH + {0xEDF8, 0x85A0}, //11613 #CJK UNIFIED IDEOGRAPH + {0xEDF9, 0x858B}, //11614 #CJK UNIFIED IDEOGRAPH + {0xEDFA, 0x85A3}, //11615 #CJK UNIFIED IDEOGRAPH + {0xEDFB, 0x857B}, //11616 #CJK UNIFIED IDEOGRAPH + {0xEDFC, 0x85A4}, //11617 #CJK UNIFIED IDEOGRAPH + {0xEDFD, 0x859A}, //11618 #CJK UNIFIED IDEOGRAPH + {0xEDFE, 0x859E}, //11619 #CJK UNIFIED IDEOGRAPH + {0xEE40, 0x8577}, //11620 #CJK UNIFIED IDEOGRAPH + {0xEE41, 0x857C}, //11621 #CJK UNIFIED IDEOGRAPH + {0xEE42, 0x8589}, //11622 #CJK UNIFIED IDEOGRAPH + {0xEE43, 0x85A1}, //11623 #CJK UNIFIED IDEOGRAPH + {0xEE44, 0x857A}, //11624 #CJK UNIFIED IDEOGRAPH + {0xEE45, 0x8578}, //11625 #CJK UNIFIED IDEOGRAPH + {0xEE46, 0x8557}, //11626 #CJK UNIFIED IDEOGRAPH + {0xEE47, 0x858E}, //11627 #CJK UNIFIED IDEOGRAPH + {0xEE48, 0x8596}, //11628 #CJK UNIFIED IDEOGRAPH + {0xEE49, 0x8586}, //11629 #CJK UNIFIED IDEOGRAPH + {0xEE4A, 0x858D}, //11630 #CJK UNIFIED IDEOGRAPH + {0xEE4B, 0x8599}, //11631 #CJK UNIFIED IDEOGRAPH + {0xEE4C, 0x859D}, //11632 #CJK UNIFIED IDEOGRAPH + {0xEE4D, 0x8581}, //11633 #CJK UNIFIED IDEOGRAPH + {0xEE4E, 0x85A2}, //11634 #CJK UNIFIED IDEOGRAPH + {0xEE4F, 0x8582}, //11635 #CJK UNIFIED IDEOGRAPH + {0xEE50, 0x8588}, //11636 #CJK UNIFIED IDEOGRAPH + {0xEE51, 0x8585}, //11637 #CJK UNIFIED IDEOGRAPH + {0xEE52, 0x8579}, //11638 #CJK UNIFIED IDEOGRAPH + {0xEE53, 0x8576}, //11639 #CJK UNIFIED IDEOGRAPH + {0xEE54, 0x8598}, //11640 #CJK UNIFIED IDEOGRAPH + {0xEE55, 0x8590}, //11641 #CJK UNIFIED IDEOGRAPH + {0xEE56, 0x859F}, //11642 #CJK UNIFIED IDEOGRAPH + {0xEE57, 0x8668}, //11643 #CJK UNIFIED IDEOGRAPH + {0xEE58, 0x87BE}, //11644 #CJK UNIFIED IDEOGRAPH + {0xEE59, 0x87AA}, //11645 #CJK UNIFIED IDEOGRAPH + {0xEE5A, 0x87AD}, //11646 #CJK UNIFIED IDEOGRAPH + {0xEE5B, 0x87C5}, //11647 #CJK UNIFIED IDEOGRAPH + {0xEE5C, 0x87B0}, //11648 #CJK UNIFIED IDEOGRAPH + {0xEE5D, 0x87AC}, //11649 #CJK UNIFIED IDEOGRAPH + {0xEE5E, 0x87B9}, //11650 #CJK UNIFIED IDEOGRAPH + {0xEE5F, 0x87B5}, //11651 #CJK UNIFIED IDEOGRAPH + {0xEE60, 0x87BC}, //11652 #CJK UNIFIED IDEOGRAPH + {0xEE61, 0x87AE}, //11653 #CJK UNIFIED IDEOGRAPH + {0xEE62, 0x87C9}, //11654 #CJK UNIFIED IDEOGRAPH + {0xEE63, 0x87C3}, //11655 #CJK UNIFIED IDEOGRAPH + {0xEE64, 0x87C2}, //11656 #CJK UNIFIED IDEOGRAPH + {0xEE65, 0x87CC}, //11657 #CJK UNIFIED IDEOGRAPH + {0xEE66, 0x87B7}, //11658 #CJK UNIFIED IDEOGRAPH + {0xEE67, 0x87AF}, //11659 #CJK UNIFIED IDEOGRAPH + {0xEE68, 0x87C4}, //11660 #CJK UNIFIED IDEOGRAPH + {0xEE69, 0x87CA}, //11661 #CJK UNIFIED IDEOGRAPH + {0xEE6A, 0x87B4}, //11662 #CJK UNIFIED IDEOGRAPH + {0xEE6B, 0x87B6}, //11663 #CJK UNIFIED IDEOGRAPH + {0xEE6C, 0x87BF}, //11664 #CJK UNIFIED IDEOGRAPH + {0xEE6D, 0x87B8}, //11665 #CJK UNIFIED IDEOGRAPH + {0xEE6E, 0x87BD}, //11666 #CJK UNIFIED IDEOGRAPH + {0xEE6F, 0x87DE}, //11667 #CJK UNIFIED IDEOGRAPH + {0xEE70, 0x87B2}, //11668 #CJK UNIFIED IDEOGRAPH + {0xEE71, 0x8935}, //11669 #CJK UNIFIED IDEOGRAPH + {0xEE72, 0x8933}, //11670 #CJK UNIFIED IDEOGRAPH + {0xEE73, 0x893C}, //11671 #CJK UNIFIED IDEOGRAPH + {0xEE74, 0x893E}, //11672 #CJK UNIFIED IDEOGRAPH + {0xEE75, 0x8941}, //11673 #CJK UNIFIED IDEOGRAPH + {0xEE76, 0x8952}, //11674 #CJK UNIFIED IDEOGRAPH + {0xEE77, 0x8937}, //11675 #CJK UNIFIED IDEOGRAPH + {0xEE78, 0x8942}, //11676 #CJK UNIFIED IDEOGRAPH + {0xEE79, 0x89AD}, //11677 #CJK UNIFIED IDEOGRAPH + {0xEE7A, 0x89AF}, //11678 #CJK UNIFIED IDEOGRAPH + {0xEE7B, 0x89AE}, //11679 #CJK UNIFIED IDEOGRAPH + {0xEE7C, 0x89F2}, //11680 #CJK UNIFIED IDEOGRAPH + {0xEE7D, 0x89F3}, //11681 #CJK UNIFIED IDEOGRAPH + {0xEE7E, 0x8B1E}, //11682 #CJK UNIFIED IDEOGRAPH + {0xEEA1, 0x8B18}, //11683 #CJK UNIFIED IDEOGRAPH + {0xEEA2, 0x8B16}, //11684 #CJK UNIFIED IDEOGRAPH + {0xEEA3, 0x8B11}, //11685 #CJK UNIFIED IDEOGRAPH + {0xEEA4, 0x8B05}, //11686 #CJK UNIFIED IDEOGRAPH + {0xEEA5, 0x8B0B}, //11687 #CJK UNIFIED IDEOGRAPH + {0xEEA6, 0x8B22}, //11688 #CJK UNIFIED IDEOGRAPH + {0xEEA7, 0x8B0F}, //11689 #CJK UNIFIED IDEOGRAPH + {0xEEA8, 0x8B12}, //11690 #CJK UNIFIED IDEOGRAPH + {0xEEA9, 0x8B15}, //11691 #CJK UNIFIED IDEOGRAPH + {0xEEAA, 0x8B07}, //11692 #CJK UNIFIED IDEOGRAPH + {0xEEAB, 0x8B0D}, //11693 #CJK UNIFIED IDEOGRAPH + {0xEEAC, 0x8B08}, //11694 #CJK UNIFIED IDEOGRAPH + {0xEEAD, 0x8B06}, //11695 #CJK UNIFIED IDEOGRAPH + {0xEEAE, 0x8B1C}, //11696 #CJK UNIFIED IDEOGRAPH + {0xEEAF, 0x8B13}, //11697 #CJK UNIFIED IDEOGRAPH + {0xEEB0, 0x8B1A}, //11698 #CJK UNIFIED IDEOGRAPH + {0xEEB1, 0x8C4F}, //11699 #CJK UNIFIED IDEOGRAPH + {0xEEB2, 0x8C70}, //11700 #CJK UNIFIED IDEOGRAPH + {0xEEB3, 0x8C72}, //11701 #CJK UNIFIED IDEOGRAPH + {0xEEB4, 0x8C71}, //11702 #CJK UNIFIED IDEOGRAPH + {0xEEB5, 0x8C6F}, //11703 #CJK UNIFIED IDEOGRAPH + {0xEEB6, 0x8C95}, //11704 #CJK UNIFIED IDEOGRAPH + {0xEEB7, 0x8C94}, //11705 #CJK UNIFIED IDEOGRAPH + {0xEEB8, 0x8CF9}, //11706 #CJK UNIFIED IDEOGRAPH + {0xEEB9, 0x8D6F}, //11707 #CJK UNIFIED IDEOGRAPH + {0xEEBA, 0x8E4E}, //11708 #CJK UNIFIED IDEOGRAPH + {0xEEBB, 0x8E4D}, //11709 #CJK UNIFIED IDEOGRAPH + {0xEEBC, 0x8E53}, //11710 #CJK UNIFIED IDEOGRAPH + {0xEEBD, 0x8E50}, //11711 #CJK UNIFIED IDEOGRAPH + {0xEEBE, 0x8E4C}, //11712 #CJK UNIFIED IDEOGRAPH + {0xEEBF, 0x8E47}, //11713 #CJK UNIFIED IDEOGRAPH + {0xEEC0, 0x8F43}, //11714 #CJK UNIFIED IDEOGRAPH + {0xEEC1, 0x8F40}, //11715 #CJK UNIFIED IDEOGRAPH + {0xEEC2, 0x9085}, //11716 #CJK UNIFIED IDEOGRAPH + {0xEEC3, 0x907E}, //11717 #CJK UNIFIED IDEOGRAPH + {0xEEC4, 0x9138}, //11718 #CJK UNIFIED IDEOGRAPH + {0xEEC5, 0x919A}, //11719 #CJK UNIFIED IDEOGRAPH + {0xEEC6, 0x91A2}, //11720 #CJK UNIFIED IDEOGRAPH + {0xEEC7, 0x919B}, //11721 #CJK UNIFIED IDEOGRAPH + {0xEEC8, 0x9199}, //11722 #CJK UNIFIED IDEOGRAPH + {0xEEC9, 0x919F}, //11723 #CJK UNIFIED IDEOGRAPH + {0xEECA, 0x91A1}, //11724 #CJK UNIFIED IDEOGRAPH + {0xEECB, 0x919D}, //11725 #CJK UNIFIED IDEOGRAPH + {0xEECC, 0x91A0}, //11726 #CJK UNIFIED IDEOGRAPH + {0xEECD, 0x93A1}, //11727 #CJK UNIFIED IDEOGRAPH + {0xEECE, 0x9383}, //11728 #CJK UNIFIED IDEOGRAPH + {0xEECF, 0x93AF}, //11729 #CJK UNIFIED IDEOGRAPH + {0xEED0, 0x9364}, //11730 #CJK UNIFIED IDEOGRAPH + {0xEED1, 0x9356}, //11731 #CJK UNIFIED IDEOGRAPH + {0xEED2, 0x9347}, //11732 #CJK UNIFIED IDEOGRAPH + {0xEED3, 0x937C}, //11733 #CJK UNIFIED IDEOGRAPH + {0xEED4, 0x9358}, //11734 #CJK UNIFIED IDEOGRAPH + {0xEED5, 0x935C}, //11735 #CJK UNIFIED IDEOGRAPH + {0xEED6, 0x9376}, //11736 #CJK UNIFIED IDEOGRAPH + {0xEED7, 0x9349}, //11737 #CJK UNIFIED IDEOGRAPH + {0xEED8, 0x9350}, //11738 #CJK UNIFIED IDEOGRAPH + {0xEED9, 0x9351}, //11739 #CJK UNIFIED IDEOGRAPH + {0xEEDA, 0x9360}, //11740 #CJK UNIFIED IDEOGRAPH + {0xEEDB, 0x936D}, //11741 #CJK UNIFIED IDEOGRAPH + {0xEEDC, 0x938F}, //11742 #CJK UNIFIED IDEOGRAPH + {0xEEDD, 0x934C}, //11743 #CJK UNIFIED IDEOGRAPH + {0xEEDE, 0x936A}, //11744 #CJK UNIFIED IDEOGRAPH + {0xEEDF, 0x9379}, //11745 #CJK UNIFIED IDEOGRAPH + {0xEEE0, 0x9357}, //11746 #CJK UNIFIED IDEOGRAPH + {0xEEE1, 0x9355}, //11747 #CJK UNIFIED IDEOGRAPH + {0xEEE2, 0x9352}, //11748 #CJK UNIFIED IDEOGRAPH + {0xEEE3, 0x934F}, //11749 #CJK UNIFIED IDEOGRAPH + {0xEEE4, 0x9371}, //11750 #CJK UNIFIED IDEOGRAPH + {0xEEE5, 0x9377}, //11751 #CJK UNIFIED IDEOGRAPH + {0xEEE6, 0x937B}, //11752 #CJK UNIFIED IDEOGRAPH + {0xEEE7, 0x9361}, //11753 #CJK UNIFIED IDEOGRAPH + {0xEEE8, 0x935E}, //11754 #CJK UNIFIED IDEOGRAPH + {0xEEE9, 0x9363}, //11755 #CJK UNIFIED IDEOGRAPH + {0xEEEA, 0x9367}, //11756 #CJK UNIFIED IDEOGRAPH + {0xEEEB, 0x9380}, //11757 #CJK UNIFIED IDEOGRAPH + {0xEEEC, 0x934E}, //11758 #CJK UNIFIED IDEOGRAPH + {0xEEED, 0x9359}, //11759 #CJK UNIFIED IDEOGRAPH + {0xEEEE, 0x95C7}, //11760 #CJK UNIFIED IDEOGRAPH + {0xEEEF, 0x95C0}, //11761 #CJK UNIFIED IDEOGRAPH + {0xEEF0, 0x95C9}, //11762 #CJK UNIFIED IDEOGRAPH + {0xEEF1, 0x95C3}, //11763 #CJK UNIFIED IDEOGRAPH + {0xEEF2, 0x95C5}, //11764 #CJK UNIFIED IDEOGRAPH + {0xEEF3, 0x95B7}, //11765 #CJK UNIFIED IDEOGRAPH + {0xEEF4, 0x96AE}, //11766 #CJK UNIFIED IDEOGRAPH + {0xEEF5, 0x96B0}, //11767 #CJK UNIFIED IDEOGRAPH + {0xEEF6, 0x96AC}, //11768 #CJK UNIFIED IDEOGRAPH + {0xEEF7, 0x9720}, //11769 #CJK UNIFIED IDEOGRAPH + {0xEEF8, 0x971F}, //11770 #CJK UNIFIED IDEOGRAPH + {0xEEF9, 0x9718}, //11771 #CJK UNIFIED IDEOGRAPH + {0xEEFA, 0x971D}, //11772 #CJK UNIFIED IDEOGRAPH + {0xEEFB, 0x9719}, //11773 #CJK UNIFIED IDEOGRAPH + {0xEEFC, 0x979A}, //11774 #CJK UNIFIED IDEOGRAPH + {0xEEFD, 0x97A1}, //11775 #CJK UNIFIED IDEOGRAPH + {0xEEFE, 0x979C}, //11776 #CJK UNIFIED IDEOGRAPH + {0xEF40, 0x979E}, //11777 #CJK UNIFIED IDEOGRAPH + {0xEF41, 0x979D}, //11778 #CJK UNIFIED IDEOGRAPH + {0xEF42, 0x97D5}, //11779 #CJK UNIFIED IDEOGRAPH + {0xEF43, 0x97D4}, //11780 #CJK UNIFIED IDEOGRAPH + {0xEF44, 0x97F1}, //11781 #CJK UNIFIED IDEOGRAPH + {0xEF45, 0x9841}, //11782 #CJK UNIFIED IDEOGRAPH + {0xEF46, 0x9844}, //11783 #CJK UNIFIED IDEOGRAPH + {0xEF47, 0x984A}, //11784 #CJK UNIFIED IDEOGRAPH + {0xEF48, 0x9849}, //11785 #CJK UNIFIED IDEOGRAPH + {0xEF49, 0x9845}, //11786 #CJK UNIFIED IDEOGRAPH + {0xEF4A, 0x9843}, //11787 #CJK UNIFIED IDEOGRAPH + {0xEF4B, 0x9925}, //11788 #CJK UNIFIED IDEOGRAPH + {0xEF4C, 0x992B}, //11789 #CJK UNIFIED IDEOGRAPH + {0xEF4D, 0x992C}, //11790 #CJK UNIFIED IDEOGRAPH + {0xEF4E, 0x992A}, //11791 #CJK UNIFIED IDEOGRAPH + {0xEF4F, 0x9933}, //11792 #CJK UNIFIED IDEOGRAPH + {0xEF50, 0x9932}, //11793 #CJK UNIFIED IDEOGRAPH + {0xEF51, 0x992F}, //11794 #CJK UNIFIED IDEOGRAPH + {0xEF52, 0x992D}, //11795 #CJK UNIFIED IDEOGRAPH + {0xEF53, 0x9931}, //11796 #CJK UNIFIED IDEOGRAPH + {0xEF54, 0x9930}, //11797 #CJK UNIFIED IDEOGRAPH + {0xEF55, 0x9998}, //11798 #CJK UNIFIED IDEOGRAPH + {0xEF56, 0x99A3}, //11799 #CJK UNIFIED IDEOGRAPH + {0xEF57, 0x99A1}, //11800 #CJK UNIFIED IDEOGRAPH + {0xEF58, 0x9A02}, //11801 #CJK UNIFIED IDEOGRAPH + {0xEF59, 0x99FA}, //11802 #CJK UNIFIED IDEOGRAPH + {0xEF5A, 0x99F4}, //11803 #CJK UNIFIED IDEOGRAPH + {0xEF5B, 0x99F7}, //11804 #CJK UNIFIED IDEOGRAPH + {0xEF5C, 0x99F9}, //11805 #CJK UNIFIED IDEOGRAPH + {0xEF5D, 0x99F8}, //11806 #CJK UNIFIED IDEOGRAPH + {0xEF5E, 0x99F6}, //11807 #CJK UNIFIED IDEOGRAPH + {0xEF5F, 0x99FB}, //11808 #CJK UNIFIED IDEOGRAPH + {0xEF60, 0x99FD}, //11809 #CJK UNIFIED IDEOGRAPH + {0xEF61, 0x99FE}, //11810 #CJK UNIFIED IDEOGRAPH + {0xEF62, 0x99FC}, //11811 #CJK UNIFIED IDEOGRAPH + {0xEF63, 0x9A03}, //11812 #CJK UNIFIED IDEOGRAPH + {0xEF64, 0x9ABE}, //11813 #CJK UNIFIED IDEOGRAPH + {0xEF65, 0x9AFE}, //11814 #CJK UNIFIED IDEOGRAPH + {0xEF66, 0x9AFD}, //11815 #CJK UNIFIED IDEOGRAPH + {0xEF67, 0x9B01}, //11816 #CJK UNIFIED IDEOGRAPH + {0xEF68, 0x9AFC}, //11817 #CJK UNIFIED IDEOGRAPH + {0xEF69, 0x9B48}, //11818 #CJK UNIFIED IDEOGRAPH + {0xEF6A, 0x9B9A}, //11819 #CJK UNIFIED IDEOGRAPH + {0xEF6B, 0x9BA8}, //11820 #CJK UNIFIED IDEOGRAPH + {0xEF6C, 0x9B9E}, //11821 #CJK UNIFIED IDEOGRAPH + {0xEF6D, 0x9B9B}, //11822 #CJK UNIFIED IDEOGRAPH + {0xEF6E, 0x9BA6}, //11823 #CJK UNIFIED IDEOGRAPH + {0xEF6F, 0x9BA1}, //11824 #CJK UNIFIED IDEOGRAPH + {0xEF70, 0x9BA5}, //11825 #CJK UNIFIED IDEOGRAPH + {0xEF71, 0x9BA4}, //11826 #CJK UNIFIED IDEOGRAPH + {0xEF72, 0x9B86}, //11827 #CJK UNIFIED IDEOGRAPH + {0xEF73, 0x9BA2}, //11828 #CJK UNIFIED IDEOGRAPH + {0xEF74, 0x9BA0}, //11829 #CJK UNIFIED IDEOGRAPH + {0xEF75, 0x9BAF}, //11830 #CJK UNIFIED IDEOGRAPH + {0xEF76, 0x9D33}, //11831 #CJK UNIFIED IDEOGRAPH + {0xEF77, 0x9D41}, //11832 #CJK UNIFIED IDEOGRAPH + {0xEF78, 0x9D67}, //11833 #CJK UNIFIED IDEOGRAPH + {0xEF79, 0x9D36}, //11834 #CJK UNIFIED IDEOGRAPH + {0xEF7A, 0x9D2E}, //11835 #CJK UNIFIED IDEOGRAPH + {0xEF7B, 0x9D2F}, //11836 #CJK UNIFIED IDEOGRAPH + {0xEF7C, 0x9D31}, //11837 #CJK UNIFIED IDEOGRAPH + {0xEF7D, 0x9D38}, //11838 #CJK UNIFIED IDEOGRAPH + {0xEF7E, 0x9D30}, //11839 #CJK UNIFIED IDEOGRAPH + {0xEFA1, 0x9D45}, //11840 #CJK UNIFIED IDEOGRAPH + {0xEFA2, 0x9D42}, //11841 #CJK UNIFIED IDEOGRAPH + {0xEFA3, 0x9D43}, //11842 #CJK UNIFIED IDEOGRAPH + {0xEFA4, 0x9D3E}, //11843 #CJK UNIFIED IDEOGRAPH + {0xEFA5, 0x9D37}, //11844 #CJK UNIFIED IDEOGRAPH + {0xEFA6, 0x9D40}, //11845 #CJK UNIFIED IDEOGRAPH + {0xEFA7, 0x9D3D}, //11846 #CJK UNIFIED IDEOGRAPH + {0xEFA8, 0x7FF5}, //11847 #CJK UNIFIED IDEOGRAPH + {0xEFA9, 0x9D2D}, //11848 #CJK UNIFIED IDEOGRAPH + {0xEFAA, 0x9E8A}, //11849 #CJK UNIFIED IDEOGRAPH + {0xEFAB, 0x9E89}, //11850 #CJK UNIFIED IDEOGRAPH + {0xEFAC, 0x9E8D}, //11851 #CJK UNIFIED IDEOGRAPH + {0xEFAD, 0x9EB0}, //11852 #CJK UNIFIED IDEOGRAPH + {0xEFAE, 0x9EC8}, //11853 #CJK UNIFIED IDEOGRAPH + {0xEFAF, 0x9EDA}, //11854 #CJK UNIFIED IDEOGRAPH + {0xEFB0, 0x9EFB}, //11855 #CJK UNIFIED IDEOGRAPH + {0xEFB1, 0x9EFF}, //11856 #CJK UNIFIED IDEOGRAPH + {0xEFB2, 0x9F24}, //11857 #CJK UNIFIED IDEOGRAPH + {0xEFB3, 0x9F23}, //11858 #CJK UNIFIED IDEOGRAPH + {0xEFB4, 0x9F22}, //11859 #CJK UNIFIED IDEOGRAPH + {0xEFB5, 0x9F54}, //11860 #CJK UNIFIED IDEOGRAPH + {0xEFB6, 0x9FA0}, //11861 #CJK UNIFIED IDEOGRAPH + {0xEFB7, 0x5131}, //11862 #CJK UNIFIED IDEOGRAPH + {0xEFB8, 0x512D}, //11863 #CJK UNIFIED IDEOGRAPH + {0xEFB9, 0x512E}, //11864 #CJK UNIFIED IDEOGRAPH + {0xEFBA, 0x5698}, //11865 #CJK UNIFIED IDEOGRAPH + {0xEFBB, 0x569C}, //11866 #CJK UNIFIED IDEOGRAPH + {0xEFBC, 0x5697}, //11867 #CJK UNIFIED IDEOGRAPH + {0xEFBD, 0x569A}, //11868 #CJK UNIFIED IDEOGRAPH + {0xEFBE, 0x569D}, //11869 #CJK UNIFIED IDEOGRAPH + {0xEFBF, 0x5699}, //11870 #CJK UNIFIED IDEOGRAPH + {0xEFC0, 0x5970}, //11871 #CJK UNIFIED IDEOGRAPH + {0xEFC1, 0x5B3C}, //11872 #CJK UNIFIED IDEOGRAPH + {0xEFC2, 0x5C69}, //11873 #CJK UNIFIED IDEOGRAPH + {0xEFC3, 0x5C6A}, //11874 #CJK UNIFIED IDEOGRAPH + {0xEFC4, 0x5DC0}, //11875 #CJK UNIFIED IDEOGRAPH + {0xEFC5, 0x5E6D}, //11876 #CJK UNIFIED IDEOGRAPH + {0xEFC6, 0x5E6E}, //11877 #CJK UNIFIED IDEOGRAPH + {0xEFC7, 0x61D8}, //11878 #CJK UNIFIED IDEOGRAPH + {0xEFC8, 0x61DF}, //11879 #CJK UNIFIED IDEOGRAPH + {0xEFC9, 0x61ED}, //11880 #CJK UNIFIED IDEOGRAPH + {0xEFCA, 0x61EE}, //11881 #CJK UNIFIED IDEOGRAPH + {0xEFCB, 0x61F1}, //11882 #CJK UNIFIED IDEOGRAPH + {0xEFCC, 0x61EA}, //11883 #CJK UNIFIED IDEOGRAPH + {0xEFCD, 0x61F0}, //11884 #CJK UNIFIED IDEOGRAPH + {0xEFCE, 0x61EB}, //11885 #CJK UNIFIED IDEOGRAPH + {0xEFCF, 0x61D6}, //11886 #CJK UNIFIED IDEOGRAPH + {0xEFD0, 0x61E9}, //11887 #CJK UNIFIED IDEOGRAPH + {0xEFD1, 0x64FF}, //11888 #CJK UNIFIED IDEOGRAPH + {0xEFD2, 0x6504}, //11889 #CJK UNIFIED IDEOGRAPH + {0xEFD3, 0x64FD}, //11890 #CJK UNIFIED IDEOGRAPH + {0xEFD4, 0x64F8}, //11891 #CJK UNIFIED IDEOGRAPH + {0xEFD5, 0x6501}, //11892 #CJK UNIFIED IDEOGRAPH + {0xEFD6, 0x6503}, //11893 #CJK UNIFIED IDEOGRAPH + {0xEFD7, 0x64FC}, //11894 #CJK UNIFIED IDEOGRAPH + {0xEFD8, 0x6594}, //11895 #CJK UNIFIED IDEOGRAPH + {0xEFD9, 0x65DB}, //11896 #CJK UNIFIED IDEOGRAPH + {0xEFDA, 0x66DA}, //11897 #CJK UNIFIED IDEOGRAPH + {0xEFDB, 0x66DB}, //11898 #CJK UNIFIED IDEOGRAPH + {0xEFDC, 0x66D8}, //11899 #CJK UNIFIED IDEOGRAPH + {0xEFDD, 0x6AC5}, //11900 #CJK UNIFIED IDEOGRAPH + {0xEFDE, 0x6AB9}, //11901 #CJK UNIFIED IDEOGRAPH + {0xEFDF, 0x6ABD}, //11902 #CJK UNIFIED IDEOGRAPH + {0xEFE0, 0x6AE1}, //11903 #CJK UNIFIED IDEOGRAPH + {0xEFE1, 0x6AC6}, //11904 #CJK UNIFIED IDEOGRAPH + {0xEFE2, 0x6ABA}, //11905 #CJK UNIFIED IDEOGRAPH + {0xEFE3, 0x6AB6}, //11906 #CJK UNIFIED IDEOGRAPH + {0xEFE4, 0x6AB7}, //11907 #CJK UNIFIED IDEOGRAPH + {0xEFE5, 0x6AC7}, //11908 #CJK UNIFIED IDEOGRAPH + {0xEFE6, 0x6AB4}, //11909 #CJK UNIFIED IDEOGRAPH + {0xEFE7, 0x6AAD}, //11910 #CJK UNIFIED IDEOGRAPH + {0xEFE8, 0x6B5E}, //11911 #CJK UNIFIED IDEOGRAPH + {0xEFE9, 0x6BC9}, //11912 #CJK UNIFIED IDEOGRAPH + {0xEFEA, 0x6C0B}, //11913 #CJK UNIFIED IDEOGRAPH + {0xEFEB, 0x7007}, //11914 #CJK UNIFIED IDEOGRAPH + {0xEFEC, 0x700C}, //11915 #CJK UNIFIED IDEOGRAPH + {0xEFED, 0x700D}, //11916 #CJK UNIFIED IDEOGRAPH + {0xEFEE, 0x7001}, //11917 #CJK UNIFIED IDEOGRAPH + {0xEFEF, 0x7005}, //11918 #CJK UNIFIED IDEOGRAPH + {0xEFF0, 0x7014}, //11919 #CJK UNIFIED IDEOGRAPH + {0xEFF1, 0x700E}, //11920 #CJK UNIFIED IDEOGRAPH + {0xEFF2, 0x6FFF}, //11921 #CJK UNIFIED IDEOGRAPH + {0xEFF3, 0x7000}, //11922 #CJK UNIFIED IDEOGRAPH + {0xEFF4, 0x6FFB}, //11923 #CJK UNIFIED IDEOGRAPH + {0xEFF5, 0x7026}, //11924 #CJK UNIFIED IDEOGRAPH + {0xEFF6, 0x6FFC}, //11925 #CJK UNIFIED IDEOGRAPH + {0xEFF7, 0x6FF7}, //11926 #CJK UNIFIED IDEOGRAPH + {0xEFF8, 0x700A}, //11927 #CJK UNIFIED IDEOGRAPH + {0xEFF9, 0x7201}, //11928 #CJK UNIFIED IDEOGRAPH + {0xEFFA, 0x71FF}, //11929 #CJK UNIFIED IDEOGRAPH + {0xEFFB, 0x71F9}, //11930 #CJK UNIFIED IDEOGRAPH + {0xEFFC, 0x7203}, //11931 #CJK UNIFIED IDEOGRAPH + {0xEFFD, 0x71FD}, //11932 #CJK UNIFIED IDEOGRAPH + {0xEFFE, 0x7376}, //11933 #CJK UNIFIED IDEOGRAPH + {0xF040, 0x74B8}, //11934 #CJK UNIFIED IDEOGRAPH + {0xF041, 0x74C0}, //11935 #CJK UNIFIED IDEOGRAPH + {0xF042, 0x74B5}, //11936 #CJK UNIFIED IDEOGRAPH + {0xF043, 0x74C1}, //11937 #CJK UNIFIED IDEOGRAPH + {0xF044, 0x74BE}, //11938 #CJK UNIFIED IDEOGRAPH + {0xF045, 0x74B6}, //11939 #CJK UNIFIED IDEOGRAPH + {0xF046, 0x74BB}, //11940 #CJK UNIFIED IDEOGRAPH + {0xF047, 0x74C2}, //11941 #CJK UNIFIED IDEOGRAPH + {0xF048, 0x7514}, //11942 #CJK UNIFIED IDEOGRAPH + {0xF049, 0x7513}, //11943 #CJK UNIFIED IDEOGRAPH + {0xF04A, 0x765C}, //11944 #CJK UNIFIED IDEOGRAPH + {0xF04B, 0x7664}, //11945 #CJK UNIFIED IDEOGRAPH + {0xF04C, 0x7659}, //11946 #CJK UNIFIED IDEOGRAPH + {0xF04D, 0x7650}, //11947 #CJK UNIFIED IDEOGRAPH + {0xF04E, 0x7653}, //11948 #CJK UNIFIED IDEOGRAPH + {0xF04F, 0x7657}, //11949 #CJK UNIFIED IDEOGRAPH + {0xF050, 0x765A}, //11950 #CJK UNIFIED IDEOGRAPH + {0xF051, 0x76A6}, //11951 #CJK UNIFIED IDEOGRAPH + {0xF052, 0x76BD}, //11952 #CJK UNIFIED IDEOGRAPH + {0xF053, 0x76EC}, //11953 #CJK UNIFIED IDEOGRAPH + {0xF054, 0x77C2}, //11954 #CJK UNIFIED IDEOGRAPH + {0xF055, 0x77BA}, //11955 #CJK UNIFIED IDEOGRAPH + {0xF056, 0x78FF}, //11956 #CJK UNIFIED IDEOGRAPH + {0xF057, 0x790C}, //11957 #CJK UNIFIED IDEOGRAPH + {0xF058, 0x7913}, //11958 #CJK UNIFIED IDEOGRAPH + {0xF059, 0x7914}, //11959 #CJK UNIFIED IDEOGRAPH + {0xF05A, 0x7909}, //11960 #CJK UNIFIED IDEOGRAPH + {0xF05B, 0x7910}, //11961 #CJK UNIFIED IDEOGRAPH + {0xF05C, 0x7912}, //11962 #CJK UNIFIED IDEOGRAPH + {0xF05D, 0x7911}, //11963 #CJK UNIFIED IDEOGRAPH + {0xF05E, 0x79AD}, //11964 #CJK UNIFIED IDEOGRAPH + {0xF05F, 0x79AC}, //11965 #CJK UNIFIED IDEOGRAPH + {0xF060, 0x7A5F}, //11966 #CJK UNIFIED IDEOGRAPH + {0xF061, 0x7C1C}, //11967 #CJK UNIFIED IDEOGRAPH + {0xF062, 0x7C29}, //11968 #CJK UNIFIED IDEOGRAPH + {0xF063, 0x7C19}, //11969 #CJK UNIFIED IDEOGRAPH + {0xF064, 0x7C20}, //11970 #CJK UNIFIED IDEOGRAPH + {0xF065, 0x7C1F}, //11971 #CJK UNIFIED IDEOGRAPH + {0xF066, 0x7C2D}, //11972 #CJK UNIFIED IDEOGRAPH + {0xF067, 0x7C1D}, //11973 #CJK UNIFIED IDEOGRAPH + {0xF068, 0x7C26}, //11974 #CJK UNIFIED IDEOGRAPH + {0xF069, 0x7C28}, //11975 #CJK UNIFIED IDEOGRAPH + {0xF06A, 0x7C22}, //11976 #CJK UNIFIED IDEOGRAPH + {0xF06B, 0x7C25}, //11977 #CJK UNIFIED IDEOGRAPH + {0xF06C, 0x7C30}, //11978 #CJK UNIFIED IDEOGRAPH + {0xF06D, 0x7E5C}, //11979 #CJK UNIFIED IDEOGRAPH + {0xF06E, 0x7E50}, //11980 #CJK UNIFIED IDEOGRAPH + {0xF06F, 0x7E56}, //11981 #CJK UNIFIED IDEOGRAPH + {0xF070, 0x7E63}, //11982 #CJK UNIFIED IDEOGRAPH + {0xF071, 0x7E58}, //11983 #CJK UNIFIED IDEOGRAPH + {0xF072, 0x7E62}, //11984 #CJK UNIFIED IDEOGRAPH + {0xF073, 0x7E5F}, //11985 #CJK UNIFIED IDEOGRAPH + {0xF074, 0x7E51}, //11986 #CJK UNIFIED IDEOGRAPH + {0xF075, 0x7E60}, //11987 #CJK UNIFIED IDEOGRAPH + {0xF076, 0x7E57}, //11988 #CJK UNIFIED IDEOGRAPH + {0xF077, 0x7E53}, //11989 #CJK UNIFIED IDEOGRAPH + {0xF078, 0x7FB5}, //11990 #CJK UNIFIED IDEOGRAPH + {0xF079, 0x7FB3}, //11991 #CJK UNIFIED IDEOGRAPH + {0xF07A, 0x7FF7}, //11992 #CJK UNIFIED IDEOGRAPH + {0xF07B, 0x7FF8}, //11993 #CJK UNIFIED IDEOGRAPH + {0xF07C, 0x8075}, //11994 #CJK UNIFIED IDEOGRAPH + {0xF07D, 0x81D1}, //11995 #CJK UNIFIED IDEOGRAPH + {0xF07E, 0x81D2}, //11996 #CJK UNIFIED IDEOGRAPH + {0xF0A1, 0x81D0}, //11997 #CJK UNIFIED IDEOGRAPH + {0xF0A2, 0x825F}, //11998 #CJK UNIFIED IDEOGRAPH + {0xF0A3, 0x825E}, //11999 #CJK UNIFIED IDEOGRAPH + {0xF0A4, 0x85B4}, //12000 #CJK UNIFIED IDEOGRAPH + {0xF0A5, 0x85C6}, //12001 #CJK UNIFIED IDEOGRAPH + {0xF0A6, 0x85C0}, //12002 #CJK UNIFIED IDEOGRAPH + {0xF0A7, 0x85C3}, //12003 #CJK UNIFIED IDEOGRAPH + {0xF0A8, 0x85C2}, //12004 #CJK UNIFIED IDEOGRAPH + {0xF0A9, 0x85B3}, //12005 #CJK UNIFIED IDEOGRAPH + {0xF0AA, 0x85B5}, //12006 #CJK UNIFIED IDEOGRAPH + {0xF0AB, 0x85BD}, //12007 #CJK UNIFIED IDEOGRAPH + {0xF0AC, 0x85C7}, //12008 #CJK UNIFIED IDEOGRAPH + {0xF0AD, 0x85C4}, //12009 #CJK UNIFIED IDEOGRAPH + {0xF0AE, 0x85BF}, //12010 #CJK UNIFIED IDEOGRAPH + {0xF0AF, 0x85CB}, //12011 #CJK UNIFIED IDEOGRAPH + {0xF0B0, 0x85CE}, //12012 #CJK UNIFIED IDEOGRAPH + {0xF0B1, 0x85C8}, //12013 #CJK UNIFIED IDEOGRAPH + {0xF0B2, 0x85C5}, //12014 #CJK UNIFIED IDEOGRAPH + {0xF0B3, 0x85B1}, //12015 #CJK UNIFIED IDEOGRAPH + {0xF0B4, 0x85B6}, //12016 #CJK UNIFIED IDEOGRAPH + {0xF0B5, 0x85D2}, //12017 #CJK UNIFIED IDEOGRAPH + {0xF0B6, 0x8624}, //12018 #CJK UNIFIED IDEOGRAPH + {0xF0B7, 0x85B8}, //12019 #CJK UNIFIED IDEOGRAPH + {0xF0B8, 0x85B7}, //12020 #CJK UNIFIED IDEOGRAPH + {0xF0B9, 0x85BE}, //12021 #CJK UNIFIED IDEOGRAPH + {0xF0BA, 0x8669}, //12022 #CJK UNIFIED IDEOGRAPH + {0xF0BB, 0x87E7}, //12023 #CJK UNIFIED IDEOGRAPH + {0xF0BC, 0x87E6}, //12024 #CJK UNIFIED IDEOGRAPH + {0xF0BD, 0x87E2}, //12025 #CJK UNIFIED IDEOGRAPH + {0xF0BE, 0x87DB}, //12026 #CJK UNIFIED IDEOGRAPH + {0xF0BF, 0x87EB}, //12027 #CJK UNIFIED IDEOGRAPH + {0xF0C0, 0x87EA}, //12028 #CJK UNIFIED IDEOGRAPH + {0xF0C1, 0x87E5}, //12029 #CJK UNIFIED IDEOGRAPH + {0xF0C2, 0x87DF}, //12030 #CJK UNIFIED IDEOGRAPH + {0xF0C3, 0x87F3}, //12031 #CJK UNIFIED IDEOGRAPH + {0xF0C4, 0x87E4}, //12032 #CJK UNIFIED IDEOGRAPH + {0xF0C5, 0x87D4}, //12033 #CJK UNIFIED IDEOGRAPH + {0xF0C6, 0x87DC}, //12034 #CJK UNIFIED IDEOGRAPH + {0xF0C7, 0x87D3}, //12035 #CJK UNIFIED IDEOGRAPH + {0xF0C8, 0x87ED}, //12036 #CJK UNIFIED IDEOGRAPH + {0xF0C9, 0x87D8}, //12037 #CJK UNIFIED IDEOGRAPH + {0xF0CA, 0x87E3}, //12038 #CJK UNIFIED IDEOGRAPH + {0xF0CB, 0x87A4}, //12039 #CJK UNIFIED IDEOGRAPH + {0xF0CC, 0x87D7}, //12040 #CJK UNIFIED IDEOGRAPH + {0xF0CD, 0x87D9}, //12041 #CJK UNIFIED IDEOGRAPH + {0xF0CE, 0x8801}, //12042 #CJK UNIFIED IDEOGRAPH + {0xF0CF, 0x87F4}, //12043 #CJK UNIFIED IDEOGRAPH + {0xF0D0, 0x87E8}, //12044 #CJK UNIFIED IDEOGRAPH + {0xF0D1, 0x87DD}, //12045 #CJK UNIFIED IDEOGRAPH + {0xF0D2, 0x8953}, //12046 #CJK UNIFIED IDEOGRAPH + {0xF0D3, 0x894B}, //12047 #CJK UNIFIED IDEOGRAPH + {0xF0D4, 0x894F}, //12048 #CJK UNIFIED IDEOGRAPH + {0xF0D5, 0x894C}, //12049 #CJK UNIFIED IDEOGRAPH + {0xF0D6, 0x8946}, //12050 #CJK UNIFIED IDEOGRAPH + {0xF0D7, 0x8950}, //12051 #CJK UNIFIED IDEOGRAPH + {0xF0D8, 0x8951}, //12052 #CJK UNIFIED IDEOGRAPH + {0xF0D9, 0x8949}, //12053 #CJK UNIFIED IDEOGRAPH + {0xF0DA, 0x8B2A}, //12054 #CJK UNIFIED IDEOGRAPH + {0xF0DB, 0x8B27}, //12055 #CJK UNIFIED IDEOGRAPH + {0xF0DC, 0x8B23}, //12056 #CJK UNIFIED IDEOGRAPH + {0xF0DD, 0x8B33}, //12057 #CJK UNIFIED IDEOGRAPH + {0xF0DE, 0x8B30}, //12058 #CJK UNIFIED IDEOGRAPH + {0xF0DF, 0x8B35}, //12059 #CJK UNIFIED IDEOGRAPH + {0xF0E0, 0x8B47}, //12060 #CJK UNIFIED IDEOGRAPH + {0xF0E1, 0x8B2F}, //12061 #CJK UNIFIED IDEOGRAPH + {0xF0E2, 0x8B3C}, //12062 #CJK UNIFIED IDEOGRAPH + {0xF0E3, 0x8B3E}, //12063 #CJK UNIFIED IDEOGRAPH + {0xF0E4, 0x8B31}, //12064 #CJK UNIFIED IDEOGRAPH + {0xF0E5, 0x8B25}, //12065 #CJK UNIFIED IDEOGRAPH + {0xF0E6, 0x8B37}, //12066 #CJK UNIFIED IDEOGRAPH + {0xF0E7, 0x8B26}, //12067 #CJK UNIFIED IDEOGRAPH + {0xF0E8, 0x8B36}, //12068 #CJK UNIFIED IDEOGRAPH + {0xF0E9, 0x8B2E}, //12069 #CJK UNIFIED IDEOGRAPH + {0xF0EA, 0x8B24}, //12070 #CJK UNIFIED IDEOGRAPH + {0xF0EB, 0x8B3B}, //12071 #CJK UNIFIED IDEOGRAPH + {0xF0EC, 0x8B3D}, //12072 #CJK UNIFIED IDEOGRAPH + {0xF0ED, 0x8B3A}, //12073 #CJK UNIFIED IDEOGRAPH + {0xF0EE, 0x8C42}, //12074 #CJK UNIFIED IDEOGRAPH + {0xF0EF, 0x8C75}, //12075 #CJK UNIFIED IDEOGRAPH + {0xF0F0, 0x8C99}, //12076 #CJK UNIFIED IDEOGRAPH + {0xF0F1, 0x8C98}, //12077 #CJK UNIFIED IDEOGRAPH + {0xF0F2, 0x8C97}, //12078 #CJK UNIFIED IDEOGRAPH + {0xF0F3, 0x8CFE}, //12079 #CJK UNIFIED IDEOGRAPH + {0xF0F4, 0x8D04}, //12080 #CJK UNIFIED IDEOGRAPH + {0xF0F5, 0x8D02}, //12081 #CJK UNIFIED IDEOGRAPH + {0xF0F6, 0x8D00}, //12082 #CJK UNIFIED IDEOGRAPH + {0xF0F7, 0x8E5C}, //12083 #CJK UNIFIED IDEOGRAPH + {0xF0F8, 0x8E62}, //12084 #CJK UNIFIED IDEOGRAPH + {0xF0F9, 0x8E60}, //12085 #CJK UNIFIED IDEOGRAPH + {0xF0FA, 0x8E57}, //12086 #CJK UNIFIED IDEOGRAPH + {0xF0FB, 0x8E56}, //12087 #CJK UNIFIED IDEOGRAPH + {0xF0FC, 0x8E5E}, //12088 #CJK UNIFIED IDEOGRAPH + {0xF0FD, 0x8E65}, //12089 #CJK UNIFIED IDEOGRAPH + {0xF0FE, 0x8E67}, //12090 #CJK UNIFIED IDEOGRAPH + {0xF140, 0x8E5B}, //12091 #CJK UNIFIED IDEOGRAPH + {0xF141, 0x8E5A}, //12092 #CJK UNIFIED IDEOGRAPH + {0xF142, 0x8E61}, //12093 #CJK UNIFIED IDEOGRAPH + {0xF143, 0x8E5D}, //12094 #CJK UNIFIED IDEOGRAPH + {0xF144, 0x8E69}, //12095 #CJK UNIFIED IDEOGRAPH + {0xF145, 0x8E54}, //12096 #CJK UNIFIED IDEOGRAPH + {0xF146, 0x8F46}, //12097 #CJK UNIFIED IDEOGRAPH + {0xF147, 0x8F47}, //12098 #CJK UNIFIED IDEOGRAPH + {0xF148, 0x8F48}, //12099 #CJK UNIFIED IDEOGRAPH + {0xF149, 0x8F4B}, //12100 #CJK UNIFIED IDEOGRAPH + {0xF14A, 0x9128}, //12101 #CJK UNIFIED IDEOGRAPH + {0xF14B, 0x913A}, //12102 #CJK UNIFIED IDEOGRAPH + {0xF14C, 0x913B}, //12103 #CJK UNIFIED IDEOGRAPH + {0xF14D, 0x913E}, //12104 #CJK UNIFIED IDEOGRAPH + {0xF14E, 0x91A8}, //12105 #CJK UNIFIED IDEOGRAPH + {0xF14F, 0x91A5}, //12106 #CJK UNIFIED IDEOGRAPH + {0xF150, 0x91A7}, //12107 #CJK UNIFIED IDEOGRAPH + {0xF151, 0x91AF}, //12108 #CJK UNIFIED IDEOGRAPH + {0xF152, 0x91AA}, //12109 #CJK UNIFIED IDEOGRAPH + {0xF153, 0x93B5}, //12110 #CJK UNIFIED IDEOGRAPH + {0xF154, 0x938C}, //12111 #CJK UNIFIED IDEOGRAPH + {0xF155, 0x9392}, //12112 #CJK UNIFIED IDEOGRAPH + {0xF156, 0x93B7}, //12113 #CJK UNIFIED IDEOGRAPH + {0xF157, 0x939B}, //12114 #CJK UNIFIED IDEOGRAPH + {0xF158, 0x939D}, //12115 #CJK UNIFIED IDEOGRAPH + {0xF159, 0x9389}, //12116 #CJK UNIFIED IDEOGRAPH + {0xF15A, 0x93A7}, //12117 #CJK UNIFIED IDEOGRAPH + {0xF15B, 0x938E}, //12118 #CJK UNIFIED IDEOGRAPH + {0xF15C, 0x93AA}, //12119 #CJK UNIFIED IDEOGRAPH + {0xF15D, 0x939E}, //12120 #CJK UNIFIED IDEOGRAPH + {0xF15E, 0x93A6}, //12121 #CJK UNIFIED IDEOGRAPH + {0xF15F, 0x9395}, //12122 #CJK UNIFIED IDEOGRAPH + {0xF160, 0x9388}, //12123 #CJK UNIFIED IDEOGRAPH + {0xF161, 0x9399}, //12124 #CJK UNIFIED IDEOGRAPH + {0xF162, 0x939F}, //12125 #CJK UNIFIED IDEOGRAPH + {0xF163, 0x938D}, //12126 #CJK UNIFIED IDEOGRAPH + {0xF164, 0x93B1}, //12127 #CJK UNIFIED IDEOGRAPH + {0xF165, 0x9391}, //12128 #CJK UNIFIED IDEOGRAPH + {0xF166, 0x93B2}, //12129 #CJK UNIFIED IDEOGRAPH + {0xF167, 0x93A4}, //12130 #CJK UNIFIED IDEOGRAPH + {0xF168, 0x93A8}, //12131 #CJK UNIFIED IDEOGRAPH + {0xF169, 0x93B4}, //12132 #CJK UNIFIED IDEOGRAPH + {0xF16A, 0x93A3}, //12133 #CJK UNIFIED IDEOGRAPH + {0xF16B, 0x93A5}, //12134 #CJK UNIFIED IDEOGRAPH + {0xF16C, 0x95D2}, //12135 #CJK UNIFIED IDEOGRAPH + {0xF16D, 0x95D3}, //12136 #CJK UNIFIED IDEOGRAPH + {0xF16E, 0x95D1}, //12137 #CJK UNIFIED IDEOGRAPH + {0xF16F, 0x96B3}, //12138 #CJK UNIFIED IDEOGRAPH + {0xF170, 0x96D7}, //12139 #CJK UNIFIED IDEOGRAPH + {0xF171, 0x96DA}, //12140 #CJK UNIFIED IDEOGRAPH + {0xF172, 0x5DC2}, //12141 #CJK UNIFIED IDEOGRAPH + {0xF173, 0x96DF}, //12142 #CJK UNIFIED IDEOGRAPH + {0xF174, 0x96D8}, //12143 #CJK UNIFIED IDEOGRAPH + {0xF175, 0x96DD}, //12144 #CJK UNIFIED IDEOGRAPH + {0xF176, 0x9723}, //12145 #CJK UNIFIED IDEOGRAPH + {0xF177, 0x9722}, //12146 #CJK UNIFIED IDEOGRAPH + {0xF178, 0x9725}, //12147 #CJK UNIFIED IDEOGRAPH + {0xF179, 0x97AC}, //12148 #CJK UNIFIED IDEOGRAPH + {0xF17A, 0x97AE}, //12149 #CJK UNIFIED IDEOGRAPH + {0xF17B, 0x97A8}, //12150 #CJK UNIFIED IDEOGRAPH + {0xF17C, 0x97AB}, //12151 #CJK UNIFIED IDEOGRAPH + {0xF17D, 0x97A4}, //12152 #CJK UNIFIED IDEOGRAPH + {0xF17E, 0x97AA}, //12153 #CJK UNIFIED IDEOGRAPH + {0xF1A1, 0x97A2}, //12154 #CJK UNIFIED IDEOGRAPH + {0xF1A2, 0x97A5}, //12155 #CJK UNIFIED IDEOGRAPH + {0xF1A3, 0x97D7}, //12156 #CJK UNIFIED IDEOGRAPH + {0xF1A4, 0x97D9}, //12157 #CJK UNIFIED IDEOGRAPH + {0xF1A5, 0x97D6}, //12158 #CJK UNIFIED IDEOGRAPH + {0xF1A6, 0x97D8}, //12159 #CJK UNIFIED IDEOGRAPH + {0xF1A7, 0x97FA}, //12160 #CJK UNIFIED IDEOGRAPH + {0xF1A8, 0x9850}, //12161 #CJK UNIFIED IDEOGRAPH + {0xF1A9, 0x9851}, //12162 #CJK UNIFIED IDEOGRAPH + {0xF1AA, 0x9852}, //12163 #CJK UNIFIED IDEOGRAPH + {0xF1AB, 0x98B8}, //12164 #CJK UNIFIED IDEOGRAPH + {0xF1AC, 0x9941}, //12165 #CJK UNIFIED IDEOGRAPH + {0xF1AD, 0x993C}, //12166 #CJK UNIFIED IDEOGRAPH + {0xF1AE, 0x993A}, //12167 #CJK UNIFIED IDEOGRAPH + {0xF1AF, 0x9A0F}, //12168 #CJK UNIFIED IDEOGRAPH + {0xF1B0, 0x9A0B}, //12169 #CJK UNIFIED IDEOGRAPH + {0xF1B1, 0x9A09}, //12170 #CJK UNIFIED IDEOGRAPH + {0xF1B2, 0x9A0D}, //12171 #CJK UNIFIED IDEOGRAPH + {0xF1B3, 0x9A04}, //12172 #CJK UNIFIED IDEOGRAPH + {0xF1B4, 0x9A11}, //12173 #CJK UNIFIED IDEOGRAPH + {0xF1B5, 0x9A0A}, //12174 #CJK UNIFIED IDEOGRAPH + {0xF1B6, 0x9A05}, //12175 #CJK UNIFIED IDEOGRAPH + {0xF1B7, 0x9A07}, //12176 #CJK UNIFIED IDEOGRAPH + {0xF1B8, 0x9A06}, //12177 #CJK UNIFIED IDEOGRAPH + {0xF1B9, 0x9AC0}, //12178 #CJK UNIFIED IDEOGRAPH + {0xF1BA, 0x9ADC}, //12179 #CJK UNIFIED IDEOGRAPH + {0xF1BB, 0x9B08}, //12180 #CJK UNIFIED IDEOGRAPH + {0xF1BC, 0x9B04}, //12181 #CJK UNIFIED IDEOGRAPH + {0xF1BD, 0x9B05}, //12182 #CJK UNIFIED IDEOGRAPH + {0xF1BE, 0x9B29}, //12183 #CJK UNIFIED IDEOGRAPH + {0xF1BF, 0x9B35}, //12184 #CJK UNIFIED IDEOGRAPH + {0xF1C0, 0x9B4A}, //12185 #CJK UNIFIED IDEOGRAPH + {0xF1C1, 0x9B4C}, //12186 #CJK UNIFIED IDEOGRAPH + {0xF1C2, 0x9B4B}, //12187 #CJK UNIFIED IDEOGRAPH + {0xF1C3, 0x9BC7}, //12188 #CJK UNIFIED IDEOGRAPH + {0xF1C4, 0x9BC6}, //12189 #CJK UNIFIED IDEOGRAPH + {0xF1C5, 0x9BC3}, //12190 #CJK UNIFIED IDEOGRAPH + {0xF1C6, 0x9BBF}, //12191 #CJK UNIFIED IDEOGRAPH + {0xF1C7, 0x9BC1}, //12192 #CJK UNIFIED IDEOGRAPH + {0xF1C8, 0x9BB5}, //12193 #CJK UNIFIED IDEOGRAPH + {0xF1C9, 0x9BB8}, //12194 #CJK UNIFIED IDEOGRAPH + {0xF1CA, 0x9BD3}, //12195 #CJK UNIFIED IDEOGRAPH + {0xF1CB, 0x9BB6}, //12196 #CJK UNIFIED IDEOGRAPH + {0xF1CC, 0x9BC4}, //12197 #CJK UNIFIED IDEOGRAPH + {0xF1CD, 0x9BB9}, //12198 #CJK UNIFIED IDEOGRAPH + {0xF1CE, 0x9BBD}, //12199 #CJK UNIFIED IDEOGRAPH + {0xF1CF, 0x9D5C}, //12200 #CJK UNIFIED IDEOGRAPH + {0xF1D0, 0x9D53}, //12201 #CJK UNIFIED IDEOGRAPH + {0xF1D1, 0x9D4F}, //12202 #CJK UNIFIED IDEOGRAPH + {0xF1D2, 0x9D4A}, //12203 #CJK UNIFIED IDEOGRAPH + {0xF1D3, 0x9D5B}, //12204 #CJK UNIFIED IDEOGRAPH + {0xF1D4, 0x9D4B}, //12205 #CJK UNIFIED IDEOGRAPH + {0xF1D5, 0x9D59}, //12206 #CJK UNIFIED IDEOGRAPH + {0xF1D6, 0x9D56}, //12207 #CJK UNIFIED IDEOGRAPH + {0xF1D7, 0x9D4C}, //12208 #CJK UNIFIED IDEOGRAPH + {0xF1D8, 0x9D57}, //12209 #CJK UNIFIED IDEOGRAPH + {0xF1D9, 0x9D52}, //12210 #CJK UNIFIED IDEOGRAPH + {0xF1DA, 0x9D54}, //12211 #CJK UNIFIED IDEOGRAPH + {0xF1DB, 0x9D5F}, //12212 #CJK UNIFIED IDEOGRAPH + {0xF1DC, 0x9D58}, //12213 #CJK UNIFIED IDEOGRAPH + {0xF1DD, 0x9D5A}, //12214 #CJK UNIFIED IDEOGRAPH + {0xF1DE, 0x9E8E}, //12215 #CJK UNIFIED IDEOGRAPH + {0xF1DF, 0x9E8C}, //12216 #CJK UNIFIED IDEOGRAPH + {0xF1E0, 0x9EDF}, //12217 #CJK UNIFIED IDEOGRAPH + {0xF1E1, 0x9F01}, //12218 #CJK UNIFIED IDEOGRAPH + {0xF1E2, 0x9F00}, //12219 #CJK UNIFIED IDEOGRAPH + {0xF1E3, 0x9F16}, //12220 #CJK UNIFIED IDEOGRAPH + {0xF1E4, 0x9F25}, //12221 #CJK UNIFIED IDEOGRAPH + {0xF1E5, 0x9F2B}, //12222 #CJK UNIFIED IDEOGRAPH + {0xF1E6, 0x9F2A}, //12223 #CJK UNIFIED IDEOGRAPH + {0xF1E7, 0x9F29}, //12224 #CJK UNIFIED IDEOGRAPH + {0xF1E8, 0x9F28}, //12225 #CJK UNIFIED IDEOGRAPH + {0xF1E9, 0x9F4C}, //12226 #CJK UNIFIED IDEOGRAPH + {0xF1EA, 0x9F55}, //12227 #CJK UNIFIED IDEOGRAPH + {0xF1EB, 0x5134}, //12228 #CJK UNIFIED IDEOGRAPH + {0xF1EC, 0x5135}, //12229 #CJK UNIFIED IDEOGRAPH + {0xF1ED, 0x5296}, //12230 #CJK UNIFIED IDEOGRAPH + {0xF1EE, 0x52F7}, //12231 #CJK UNIFIED IDEOGRAPH + {0xF1EF, 0x53B4}, //12232 #CJK UNIFIED IDEOGRAPH + {0xF1F0, 0x56AB}, //12233 #CJK UNIFIED IDEOGRAPH + {0xF1F1, 0x56AD}, //12234 #CJK UNIFIED IDEOGRAPH + {0xF1F2, 0x56A6}, //12235 #CJK UNIFIED IDEOGRAPH + {0xF1F3, 0x56A7}, //12236 #CJK UNIFIED IDEOGRAPH + {0xF1F4, 0x56AA}, //12237 #CJK UNIFIED IDEOGRAPH + {0xF1F5, 0x56AC}, //12238 #CJK UNIFIED IDEOGRAPH + {0xF1F6, 0x58DA}, //12239 #CJK UNIFIED IDEOGRAPH + {0xF1F7, 0x58DD}, //12240 #CJK UNIFIED IDEOGRAPH + {0xF1F8, 0x58DB}, //12241 #CJK UNIFIED IDEOGRAPH + {0xF1F9, 0x5912}, //12242 #CJK UNIFIED IDEOGRAPH + {0xF1FA, 0x5B3D}, //12243 #CJK UNIFIED IDEOGRAPH + {0xF1FB, 0x5B3E}, //12244 #CJK UNIFIED IDEOGRAPH + {0xF1FC, 0x5B3F}, //12245 #CJK UNIFIED IDEOGRAPH + {0xF1FD, 0x5DC3}, //12246 #CJK UNIFIED IDEOGRAPH + {0xF1FE, 0x5E70}, //12247 #CJK UNIFIED IDEOGRAPH + {0xF240, 0x5FBF}, //12248 #CJK UNIFIED IDEOGRAPH + {0xF241, 0x61FB}, //12249 #CJK UNIFIED IDEOGRAPH + {0xF242, 0x6507}, //12250 #CJK UNIFIED IDEOGRAPH + {0xF243, 0x6510}, //12251 #CJK UNIFIED IDEOGRAPH + {0xF244, 0x650D}, //12252 #CJK UNIFIED IDEOGRAPH + {0xF245, 0x6509}, //12253 #CJK UNIFIED IDEOGRAPH + {0xF246, 0x650C}, //12254 #CJK UNIFIED IDEOGRAPH + {0xF247, 0x650E}, //12255 #CJK UNIFIED IDEOGRAPH + {0xF248, 0x6584}, //12256 #CJK UNIFIED IDEOGRAPH + {0xF249, 0x65DE}, //12257 #CJK UNIFIED IDEOGRAPH + {0xF24A, 0x65DD}, //12258 #CJK UNIFIED IDEOGRAPH + {0xF24B, 0x66DE}, //12259 #CJK UNIFIED IDEOGRAPH + {0xF24C, 0x6AE7}, //12260 #CJK UNIFIED IDEOGRAPH + {0xF24D, 0x6AE0}, //12261 #CJK UNIFIED IDEOGRAPH + {0xF24E, 0x6ACC}, //12262 #CJK UNIFIED IDEOGRAPH + {0xF24F, 0x6AD1}, //12263 #CJK UNIFIED IDEOGRAPH + {0xF250, 0x6AD9}, //12264 #CJK UNIFIED IDEOGRAPH + {0xF251, 0x6ACB}, //12265 #CJK UNIFIED IDEOGRAPH + {0xF252, 0x6ADF}, //12266 #CJK UNIFIED IDEOGRAPH + {0xF253, 0x6ADC}, //12267 #CJK UNIFIED IDEOGRAPH + {0xF254, 0x6AD0}, //12268 #CJK UNIFIED IDEOGRAPH + {0xF255, 0x6AEB}, //12269 #CJK UNIFIED IDEOGRAPH + {0xF256, 0x6ACF}, //12270 #CJK UNIFIED IDEOGRAPH + {0xF257, 0x6ACD}, //12271 #CJK UNIFIED IDEOGRAPH + {0xF258, 0x6ADE}, //12272 #CJK UNIFIED IDEOGRAPH + {0xF259, 0x6B60}, //12273 #CJK UNIFIED IDEOGRAPH + {0xF25A, 0x6BB0}, //12274 #CJK UNIFIED IDEOGRAPH + {0xF25B, 0x6C0C}, //12275 #CJK UNIFIED IDEOGRAPH + {0xF25C, 0x7019}, //12276 #CJK UNIFIED IDEOGRAPH + {0xF25D, 0x7027}, //12277 #CJK UNIFIED IDEOGRAPH + {0xF25E, 0x7020}, //12278 #CJK UNIFIED IDEOGRAPH + {0xF25F, 0x7016}, //12279 #CJK UNIFIED IDEOGRAPH + {0xF260, 0x702B}, //12280 #CJK UNIFIED IDEOGRAPH + {0xF261, 0x7021}, //12281 #CJK UNIFIED IDEOGRAPH + {0xF262, 0x7022}, //12282 #CJK UNIFIED IDEOGRAPH + {0xF263, 0x7023}, //12283 #CJK UNIFIED IDEOGRAPH + {0xF264, 0x7029}, //12284 #CJK UNIFIED IDEOGRAPH + {0xF265, 0x7017}, //12285 #CJK UNIFIED IDEOGRAPH + {0xF266, 0x7024}, //12286 #CJK UNIFIED IDEOGRAPH + {0xF267, 0x701C}, //12287 #CJK UNIFIED IDEOGRAPH + {0xF268, 0x702A}, //12288 #CJK UNIFIED IDEOGRAPH + {0xF269, 0x720C}, //12289 #CJK UNIFIED IDEOGRAPH + {0xF26A, 0x720A}, //12290 #CJK UNIFIED IDEOGRAPH + {0xF26B, 0x7207}, //12291 #CJK UNIFIED IDEOGRAPH + {0xF26C, 0x7202}, //12292 #CJK UNIFIED IDEOGRAPH + {0xF26D, 0x7205}, //12293 #CJK UNIFIED IDEOGRAPH + {0xF26E, 0x72A5}, //12294 #CJK UNIFIED IDEOGRAPH + {0xF26F, 0x72A6}, //12295 #CJK UNIFIED IDEOGRAPH + {0xF270, 0x72A4}, //12296 #CJK UNIFIED IDEOGRAPH + {0xF271, 0x72A3}, //12297 #CJK UNIFIED IDEOGRAPH + {0xF272, 0x72A1}, //12298 #CJK UNIFIED IDEOGRAPH + {0xF273, 0x74CB}, //12299 #CJK UNIFIED IDEOGRAPH + {0xF274, 0x74C5}, //12300 #CJK UNIFIED IDEOGRAPH + {0xF275, 0x74B7}, //12301 #CJK UNIFIED IDEOGRAPH + {0xF276, 0x74C3}, //12302 #CJK UNIFIED IDEOGRAPH + {0xF277, 0x7516}, //12303 #CJK UNIFIED IDEOGRAPH + {0xF278, 0x7660}, //12304 #CJK UNIFIED IDEOGRAPH + {0xF279, 0x77C9}, //12305 #CJK UNIFIED IDEOGRAPH + {0xF27A, 0x77CA}, //12306 #CJK UNIFIED IDEOGRAPH + {0xF27B, 0x77C4}, //12307 #CJK UNIFIED IDEOGRAPH + {0xF27C, 0x77F1}, //12308 #CJK UNIFIED IDEOGRAPH + {0xF27D, 0x791D}, //12309 #CJK UNIFIED IDEOGRAPH + {0xF27E, 0x791B}, //12310 #CJK UNIFIED IDEOGRAPH + {0xF2A1, 0x7921}, //12311 #CJK UNIFIED IDEOGRAPH + {0xF2A2, 0x791C}, //12312 #CJK UNIFIED IDEOGRAPH + {0xF2A3, 0x7917}, //12313 #CJK UNIFIED IDEOGRAPH + {0xF2A4, 0x791E}, //12314 #CJK UNIFIED IDEOGRAPH + {0xF2A5, 0x79B0}, //12315 #CJK UNIFIED IDEOGRAPH + {0xF2A6, 0x7A67}, //12316 #CJK UNIFIED IDEOGRAPH + {0xF2A7, 0x7A68}, //12317 #CJK UNIFIED IDEOGRAPH + {0xF2A8, 0x7C33}, //12318 #CJK UNIFIED IDEOGRAPH + {0xF2A9, 0x7C3C}, //12319 #CJK UNIFIED IDEOGRAPH + {0xF2AA, 0x7C39}, //12320 #CJK UNIFIED IDEOGRAPH + {0xF2AB, 0x7C2C}, //12321 #CJK UNIFIED IDEOGRAPH + {0xF2AC, 0x7C3B}, //12322 #CJK UNIFIED IDEOGRAPH + {0xF2AD, 0x7CEC}, //12323 #CJK UNIFIED IDEOGRAPH + {0xF2AE, 0x7CEA}, //12324 #CJK UNIFIED IDEOGRAPH + {0xF2AF, 0x7E76}, //12325 #CJK UNIFIED IDEOGRAPH + {0xF2B0, 0x7E75}, //12326 #CJK UNIFIED IDEOGRAPH + {0xF2B1, 0x7E78}, //12327 #CJK UNIFIED IDEOGRAPH + {0xF2B2, 0x7E70}, //12328 #CJK UNIFIED IDEOGRAPH + {0xF2B3, 0x7E77}, //12329 #CJK UNIFIED IDEOGRAPH + {0xF2B4, 0x7E6F}, //12330 #CJK UNIFIED IDEOGRAPH + {0xF2B5, 0x7E7A}, //12331 #CJK UNIFIED IDEOGRAPH + {0xF2B6, 0x7E72}, //12332 #CJK UNIFIED IDEOGRAPH + {0xF2B7, 0x7E74}, //12333 #CJK UNIFIED IDEOGRAPH + {0xF2B8, 0x7E68}, //12334 #CJK UNIFIED IDEOGRAPH + {0xF2B9, 0x7F4B}, //12335 #CJK UNIFIED IDEOGRAPH + {0xF2BA, 0x7F4A}, //12336 #CJK UNIFIED IDEOGRAPH + {0xF2BB, 0x7F83}, //12337 #CJK UNIFIED IDEOGRAPH + {0xF2BC, 0x7F86}, //12338 #CJK UNIFIED IDEOGRAPH + {0xF2BD, 0x7FB7}, //12339 #CJK UNIFIED IDEOGRAPH + {0xF2BE, 0x7FFD}, //12340 #CJK UNIFIED IDEOGRAPH + {0xF2BF, 0x7FFE}, //12341 #CJK UNIFIED IDEOGRAPH + {0xF2C0, 0x8078}, //12342 #CJK UNIFIED IDEOGRAPH + {0xF2C1, 0x81D7}, //12343 #CJK UNIFIED IDEOGRAPH + {0xF2C2, 0x81D5}, //12344 #CJK UNIFIED IDEOGRAPH + {0xF2C3, 0x8264}, //12345 #CJK UNIFIED IDEOGRAPH + {0xF2C4, 0x8261}, //12346 #CJK UNIFIED IDEOGRAPH + {0xF2C5, 0x8263}, //12347 #CJK UNIFIED IDEOGRAPH + {0xF2C6, 0x85EB}, //12348 #CJK UNIFIED IDEOGRAPH + {0xF2C7, 0x85F1}, //12349 #CJK UNIFIED IDEOGRAPH + {0xF2C8, 0x85ED}, //12350 #CJK UNIFIED IDEOGRAPH + {0xF2C9, 0x85D9}, //12351 #CJK UNIFIED IDEOGRAPH + {0xF2CA, 0x85E1}, //12352 #CJK UNIFIED IDEOGRAPH + {0xF2CB, 0x85E8}, //12353 #CJK UNIFIED IDEOGRAPH + {0xF2CC, 0x85DA}, //12354 #CJK UNIFIED IDEOGRAPH + {0xF2CD, 0x85D7}, //12355 #CJK UNIFIED IDEOGRAPH + {0xF2CE, 0x85EC}, //12356 #CJK UNIFIED IDEOGRAPH + {0xF2CF, 0x85F2}, //12357 #CJK UNIFIED IDEOGRAPH + {0xF2D0, 0x85F8}, //12358 #CJK UNIFIED IDEOGRAPH + {0xF2D1, 0x85D8}, //12359 #CJK UNIFIED IDEOGRAPH + {0xF2D2, 0x85DF}, //12360 #CJK UNIFIED IDEOGRAPH + {0xF2D3, 0x85E3}, //12361 #CJK UNIFIED IDEOGRAPH + {0xF2D4, 0x85DC}, //12362 #CJK UNIFIED IDEOGRAPH + {0xF2D5, 0x85D1}, //12363 #CJK UNIFIED IDEOGRAPH + {0xF2D6, 0x85F0}, //12364 #CJK UNIFIED IDEOGRAPH + {0xF2D7, 0x85E6}, //12365 #CJK UNIFIED IDEOGRAPH + {0xF2D8, 0x85EF}, //12366 #CJK UNIFIED IDEOGRAPH + {0xF2D9, 0x85DE}, //12367 #CJK UNIFIED IDEOGRAPH + {0xF2DA, 0x85E2}, //12368 #CJK UNIFIED IDEOGRAPH + {0xF2DB, 0x8800}, //12369 #CJK UNIFIED IDEOGRAPH + {0xF2DC, 0x87FA}, //12370 #CJK UNIFIED IDEOGRAPH + {0xF2DD, 0x8803}, //12371 #CJK UNIFIED IDEOGRAPH + {0xF2DE, 0x87F6}, //12372 #CJK UNIFIED IDEOGRAPH + {0xF2DF, 0x87F7}, //12373 #CJK UNIFIED IDEOGRAPH + {0xF2E0, 0x8809}, //12374 #CJK UNIFIED IDEOGRAPH + {0xF2E1, 0x880C}, //12375 #CJK UNIFIED IDEOGRAPH + {0xF2E2, 0x880B}, //12376 #CJK UNIFIED IDEOGRAPH + {0xF2E3, 0x8806}, //12377 #CJK UNIFIED IDEOGRAPH + {0xF2E4, 0x87FC}, //12378 #CJK UNIFIED IDEOGRAPH + {0xF2E5, 0x8808}, //12379 #CJK UNIFIED IDEOGRAPH + {0xF2E6, 0x87FF}, //12380 #CJK UNIFIED IDEOGRAPH + {0xF2E7, 0x880A}, //12381 #CJK UNIFIED IDEOGRAPH + {0xF2E8, 0x8802}, //12382 #CJK UNIFIED IDEOGRAPH + {0xF2E9, 0x8962}, //12383 #CJK UNIFIED IDEOGRAPH + {0xF2EA, 0x895A}, //12384 #CJK UNIFIED IDEOGRAPH + {0xF2EB, 0x895B}, //12385 #CJK UNIFIED IDEOGRAPH + {0xF2EC, 0x8957}, //12386 #CJK UNIFIED IDEOGRAPH + {0xF2ED, 0x8961}, //12387 #CJK UNIFIED IDEOGRAPH + {0xF2EE, 0x895C}, //12388 #CJK UNIFIED IDEOGRAPH + {0xF2EF, 0x8958}, //12389 #CJK UNIFIED IDEOGRAPH + {0xF2F0, 0x895D}, //12390 #CJK UNIFIED IDEOGRAPH + {0xF2F1, 0x8959}, //12391 #CJK UNIFIED IDEOGRAPH + {0xF2F2, 0x8988}, //12392 #CJK UNIFIED IDEOGRAPH + {0xF2F3, 0x89B7}, //12393 #CJK UNIFIED IDEOGRAPH + {0xF2F4, 0x89B6}, //12394 #CJK UNIFIED IDEOGRAPH + {0xF2F5, 0x89F6}, //12395 #CJK UNIFIED IDEOGRAPH + {0xF2F6, 0x8B50}, //12396 #CJK UNIFIED IDEOGRAPH + {0xF2F7, 0x8B48}, //12397 #CJK UNIFIED IDEOGRAPH + {0xF2F8, 0x8B4A}, //12398 #CJK UNIFIED IDEOGRAPH + {0xF2F9, 0x8B40}, //12399 #CJK UNIFIED IDEOGRAPH + {0xF2FA, 0x8B53}, //12400 #CJK UNIFIED IDEOGRAPH + {0xF2FB, 0x8B56}, //12401 #CJK UNIFIED IDEOGRAPH + {0xF2FC, 0x8B54}, //12402 #CJK UNIFIED IDEOGRAPH + {0xF2FD, 0x8B4B}, //12403 #CJK UNIFIED IDEOGRAPH + {0xF2FE, 0x8B55}, //12404 #CJK UNIFIED IDEOGRAPH + {0xF340, 0x8B51}, //12405 #CJK UNIFIED IDEOGRAPH + {0xF341, 0x8B42}, //12406 #CJK UNIFIED IDEOGRAPH + {0xF342, 0x8B52}, //12407 #CJK UNIFIED IDEOGRAPH + {0xF343, 0x8B57}, //12408 #CJK UNIFIED IDEOGRAPH + {0xF344, 0x8C43}, //12409 #CJK UNIFIED IDEOGRAPH + {0xF345, 0x8C77}, //12410 #CJK UNIFIED IDEOGRAPH + {0xF346, 0x8C76}, //12411 #CJK UNIFIED IDEOGRAPH + {0xF347, 0x8C9A}, //12412 #CJK UNIFIED IDEOGRAPH + {0xF348, 0x8D06}, //12413 #CJK UNIFIED IDEOGRAPH + {0xF349, 0x8D07}, //12414 #CJK UNIFIED IDEOGRAPH + {0xF34A, 0x8D09}, //12415 #CJK UNIFIED IDEOGRAPH + {0xF34B, 0x8DAC}, //12416 #CJK UNIFIED IDEOGRAPH + {0xF34C, 0x8DAA}, //12417 #CJK UNIFIED IDEOGRAPH + {0xF34D, 0x8DAD}, //12418 #CJK UNIFIED IDEOGRAPH + {0xF34E, 0x8DAB}, //12419 #CJK UNIFIED IDEOGRAPH + {0xF34F, 0x8E6D}, //12420 #CJK UNIFIED IDEOGRAPH + {0xF350, 0x8E78}, //12421 #CJK UNIFIED IDEOGRAPH + {0xF351, 0x8E73}, //12422 #CJK UNIFIED IDEOGRAPH + {0xF352, 0x8E6A}, //12423 #CJK UNIFIED IDEOGRAPH + {0xF353, 0x8E6F}, //12424 #CJK UNIFIED IDEOGRAPH + {0xF354, 0x8E7B}, //12425 #CJK UNIFIED IDEOGRAPH + {0xF355, 0x8EC2}, //12426 #CJK UNIFIED IDEOGRAPH + {0xF356, 0x8F52}, //12427 #CJK UNIFIED IDEOGRAPH + {0xF357, 0x8F51}, //12428 #CJK UNIFIED IDEOGRAPH + {0xF358, 0x8F4F}, //12429 #CJK UNIFIED IDEOGRAPH + {0xF359, 0x8F50}, //12430 #CJK UNIFIED IDEOGRAPH + {0xF35A, 0x8F53}, //12431 #CJK UNIFIED IDEOGRAPH + {0xF35B, 0x8FB4}, //12432 #CJK UNIFIED IDEOGRAPH + {0xF35C, 0x9140}, //12433 #CJK UNIFIED IDEOGRAPH + {0xF35D, 0x913F}, //12434 #CJK UNIFIED IDEOGRAPH + {0xF35E, 0x91B0}, //12435 #CJK UNIFIED IDEOGRAPH + {0xF35F, 0x91AD}, //12436 #CJK UNIFIED IDEOGRAPH + {0xF360, 0x93DE}, //12437 #CJK UNIFIED IDEOGRAPH + {0xF361, 0x93C7}, //12438 #CJK UNIFIED IDEOGRAPH + {0xF362, 0x93CF}, //12439 #CJK UNIFIED IDEOGRAPH + {0xF363, 0x93C2}, //12440 #CJK UNIFIED IDEOGRAPH + {0xF364, 0x93DA}, //12441 #CJK UNIFIED IDEOGRAPH + {0xF365, 0x93D0}, //12442 #CJK UNIFIED IDEOGRAPH + {0xF366, 0x93F9}, //12443 #CJK UNIFIED IDEOGRAPH + {0xF367, 0x93EC}, //12444 #CJK UNIFIED IDEOGRAPH + {0xF368, 0x93CC}, //12445 #CJK UNIFIED IDEOGRAPH + {0xF369, 0x93D9}, //12446 #CJK UNIFIED IDEOGRAPH + {0xF36A, 0x93A9}, //12447 #CJK UNIFIED IDEOGRAPH + {0xF36B, 0x93E6}, //12448 #CJK UNIFIED IDEOGRAPH + {0xF36C, 0x93CA}, //12449 #CJK UNIFIED IDEOGRAPH + {0xF36D, 0x93D4}, //12450 #CJK UNIFIED IDEOGRAPH + {0xF36E, 0x93EE}, //12451 #CJK UNIFIED IDEOGRAPH + {0xF36F, 0x93E3}, //12452 #CJK UNIFIED IDEOGRAPH + {0xF370, 0x93D5}, //12453 #CJK UNIFIED IDEOGRAPH + {0xF371, 0x93C4}, //12454 #CJK UNIFIED IDEOGRAPH + {0xF372, 0x93CE}, //12455 #CJK UNIFIED IDEOGRAPH + {0xF373, 0x93C0}, //12456 #CJK UNIFIED IDEOGRAPH + {0xF374, 0x93D2}, //12457 #CJK UNIFIED IDEOGRAPH + {0xF375, 0x93E7}, //12458 #CJK UNIFIED IDEOGRAPH + {0xF376, 0x957D}, //12459 #CJK UNIFIED IDEOGRAPH + {0xF377, 0x95DA}, //12460 #CJK UNIFIED IDEOGRAPH + {0xF378, 0x95DB}, //12461 #CJK UNIFIED IDEOGRAPH + {0xF379, 0x96E1}, //12462 #CJK UNIFIED IDEOGRAPH + {0xF37A, 0x9729}, //12463 #CJK UNIFIED IDEOGRAPH + {0xF37B, 0x972B}, //12464 #CJK UNIFIED IDEOGRAPH + {0xF37C, 0x972C}, //12465 #CJK UNIFIED IDEOGRAPH + {0xF37D, 0x9728}, //12466 #CJK UNIFIED IDEOGRAPH + {0xF37E, 0x9726}, //12467 #CJK UNIFIED IDEOGRAPH + {0xF3A1, 0x97B3}, //12468 #CJK UNIFIED IDEOGRAPH + {0xF3A2, 0x97B7}, //12469 #CJK UNIFIED IDEOGRAPH + {0xF3A3, 0x97B6}, //12470 #CJK UNIFIED IDEOGRAPH + {0xF3A4, 0x97DD}, //12471 #CJK UNIFIED IDEOGRAPH + {0xF3A5, 0x97DE}, //12472 #CJK UNIFIED IDEOGRAPH + {0xF3A6, 0x97DF}, //12473 #CJK UNIFIED IDEOGRAPH + {0xF3A7, 0x985C}, //12474 #CJK UNIFIED IDEOGRAPH + {0xF3A8, 0x9859}, //12475 #CJK UNIFIED IDEOGRAPH + {0xF3A9, 0x985D}, //12476 #CJK UNIFIED IDEOGRAPH + {0xF3AA, 0x9857}, //12477 #CJK UNIFIED IDEOGRAPH + {0xF3AB, 0x98BF}, //12478 #CJK UNIFIED IDEOGRAPH + {0xF3AC, 0x98BD}, //12479 #CJK UNIFIED IDEOGRAPH + {0xF3AD, 0x98BB}, //12480 #CJK UNIFIED IDEOGRAPH + {0xF3AE, 0x98BE}, //12481 #CJK UNIFIED IDEOGRAPH + {0xF3AF, 0x9948}, //12482 #CJK UNIFIED IDEOGRAPH + {0xF3B0, 0x9947}, //12483 #CJK UNIFIED IDEOGRAPH + {0xF3B1, 0x9943}, //12484 #CJK UNIFIED IDEOGRAPH + {0xF3B2, 0x99A6}, //12485 #CJK UNIFIED IDEOGRAPH + {0xF3B3, 0x99A7}, //12486 #CJK UNIFIED IDEOGRAPH + {0xF3B4, 0x9A1A}, //12487 #CJK UNIFIED IDEOGRAPH + {0xF3B5, 0x9A15}, //12488 #CJK UNIFIED IDEOGRAPH + {0xF3B6, 0x9A25}, //12489 #CJK UNIFIED IDEOGRAPH + {0xF3B7, 0x9A1D}, //12490 #CJK UNIFIED IDEOGRAPH + {0xF3B8, 0x9A24}, //12491 #CJK UNIFIED IDEOGRAPH + {0xF3B9, 0x9A1B}, //12492 #CJK UNIFIED IDEOGRAPH + {0xF3BA, 0x9A22}, //12493 #CJK UNIFIED IDEOGRAPH + {0xF3BB, 0x9A20}, //12494 #CJK UNIFIED IDEOGRAPH + {0xF3BC, 0x9A27}, //12495 #CJK UNIFIED IDEOGRAPH + {0xF3BD, 0x9A23}, //12496 #CJK UNIFIED IDEOGRAPH + {0xF3BE, 0x9A1E}, //12497 #CJK UNIFIED IDEOGRAPH + {0xF3BF, 0x9A1C}, //12498 #CJK UNIFIED IDEOGRAPH + {0xF3C0, 0x9A14}, //12499 #CJK UNIFIED IDEOGRAPH + {0xF3C1, 0x9AC2}, //12500 #CJK UNIFIED IDEOGRAPH + {0xF3C2, 0x9B0B}, //12501 #CJK UNIFIED IDEOGRAPH + {0xF3C3, 0x9B0A}, //12502 #CJK UNIFIED IDEOGRAPH + {0xF3C4, 0x9B0E}, //12503 #CJK UNIFIED IDEOGRAPH + {0xF3C5, 0x9B0C}, //12504 #CJK UNIFIED IDEOGRAPH + {0xF3C6, 0x9B37}, //12505 #CJK UNIFIED IDEOGRAPH + {0xF3C7, 0x9BEA}, //12506 #CJK UNIFIED IDEOGRAPH + {0xF3C8, 0x9BEB}, //12507 #CJK UNIFIED IDEOGRAPH + {0xF3C9, 0x9BE0}, //12508 #CJK UNIFIED IDEOGRAPH + {0xF3CA, 0x9BDE}, //12509 #CJK UNIFIED IDEOGRAPH + {0xF3CB, 0x9BE4}, //12510 #CJK UNIFIED IDEOGRAPH + {0xF3CC, 0x9BE6}, //12511 #CJK UNIFIED IDEOGRAPH + {0xF3CD, 0x9BE2}, //12512 #CJK UNIFIED IDEOGRAPH + {0xF3CE, 0x9BF0}, //12513 #CJK UNIFIED IDEOGRAPH + {0xF3CF, 0x9BD4}, //12514 #CJK UNIFIED IDEOGRAPH + {0xF3D0, 0x9BD7}, //12515 #CJK UNIFIED IDEOGRAPH + {0xF3D1, 0x9BEC}, //12516 #CJK UNIFIED IDEOGRAPH + {0xF3D2, 0x9BDC}, //12517 #CJK UNIFIED IDEOGRAPH + {0xF3D3, 0x9BD9}, //12518 #CJK UNIFIED IDEOGRAPH + {0xF3D4, 0x9BE5}, //12519 #CJK UNIFIED IDEOGRAPH + {0xF3D5, 0x9BD5}, //12520 #CJK UNIFIED IDEOGRAPH + {0xF3D6, 0x9BE1}, //12521 #CJK UNIFIED IDEOGRAPH + {0xF3D7, 0x9BDA}, //12522 #CJK UNIFIED IDEOGRAPH + {0xF3D8, 0x9D77}, //12523 #CJK UNIFIED IDEOGRAPH + {0xF3D9, 0x9D81}, //12524 #CJK UNIFIED IDEOGRAPH + {0xF3DA, 0x9D8A}, //12525 #CJK UNIFIED IDEOGRAPH + {0xF3DB, 0x9D84}, //12526 #CJK UNIFIED IDEOGRAPH + {0xF3DC, 0x9D88}, //12527 #CJK UNIFIED IDEOGRAPH + {0xF3DD, 0x9D71}, //12528 #CJK UNIFIED IDEOGRAPH + {0xF3DE, 0x9D80}, //12529 #CJK UNIFIED IDEOGRAPH + {0xF3DF, 0x9D78}, //12530 #CJK UNIFIED IDEOGRAPH + {0xF3E0, 0x9D86}, //12531 #CJK UNIFIED IDEOGRAPH + {0xF3E1, 0x9D8B}, //12532 #CJK UNIFIED IDEOGRAPH + {0xF3E2, 0x9D8C}, //12533 #CJK UNIFIED IDEOGRAPH + {0xF3E3, 0x9D7D}, //12534 #CJK UNIFIED IDEOGRAPH + {0xF3E4, 0x9D6B}, //12535 #CJK UNIFIED IDEOGRAPH + {0xF3E5, 0x9D74}, //12536 #CJK UNIFIED IDEOGRAPH + {0xF3E6, 0x9D75}, //12537 #CJK UNIFIED IDEOGRAPH + {0xF3E7, 0x9D70}, //12538 #CJK UNIFIED IDEOGRAPH + {0xF3E8, 0x9D69}, //12539 #CJK UNIFIED IDEOGRAPH + {0xF3E9, 0x9D85}, //12540 #CJK UNIFIED IDEOGRAPH + {0xF3EA, 0x9D73}, //12541 #CJK UNIFIED IDEOGRAPH + {0xF3EB, 0x9D7B}, //12542 #CJK UNIFIED IDEOGRAPH + {0xF3EC, 0x9D82}, //12543 #CJK UNIFIED IDEOGRAPH + {0xF3ED, 0x9D6F}, //12544 #CJK UNIFIED IDEOGRAPH + {0xF3EE, 0x9D79}, //12545 #CJK UNIFIED IDEOGRAPH + {0xF3EF, 0x9D7F}, //12546 #CJK UNIFIED IDEOGRAPH + {0xF3F0, 0x9D87}, //12547 #CJK UNIFIED IDEOGRAPH + {0xF3F1, 0x9D68}, //12548 #CJK UNIFIED IDEOGRAPH + {0xF3F2, 0x9E94}, //12549 #CJK UNIFIED IDEOGRAPH + {0xF3F3, 0x9E91}, //12550 #CJK UNIFIED IDEOGRAPH + {0xF3F4, 0x9EC0}, //12551 #CJK UNIFIED IDEOGRAPH + {0xF3F5, 0x9EFC}, //12552 #CJK UNIFIED IDEOGRAPH + {0xF3F6, 0x9F2D}, //12553 #CJK UNIFIED IDEOGRAPH + {0xF3F7, 0x9F40}, //12554 #CJK UNIFIED IDEOGRAPH + {0xF3F8, 0x9F41}, //12555 #CJK UNIFIED IDEOGRAPH + {0xF3F9, 0x9F4D}, //12556 #CJK UNIFIED IDEOGRAPH + {0xF3FA, 0x9F56}, //12557 #CJK UNIFIED IDEOGRAPH + {0xF3FB, 0x9F57}, //12558 #CJK UNIFIED IDEOGRAPH + {0xF3FC, 0x9F58}, //12559 #CJK UNIFIED IDEOGRAPH + {0xF3FD, 0x5337}, //12560 #CJK UNIFIED IDEOGRAPH + {0xF3FE, 0x56B2}, //12561 #CJK UNIFIED IDEOGRAPH + {0xF440, 0x56B5}, //12562 #CJK UNIFIED IDEOGRAPH + {0xF441, 0x56B3}, //12563 #CJK UNIFIED IDEOGRAPH + {0xF442, 0x58E3}, //12564 #CJK UNIFIED IDEOGRAPH + {0xF443, 0x5B45}, //12565 #CJK UNIFIED IDEOGRAPH + {0xF444, 0x5DC6}, //12566 #CJK UNIFIED IDEOGRAPH + {0xF445, 0x5DC7}, //12567 #CJK UNIFIED IDEOGRAPH + {0xF446, 0x5EEE}, //12568 #CJK UNIFIED IDEOGRAPH + {0xF447, 0x5EEF}, //12569 #CJK UNIFIED IDEOGRAPH + {0xF448, 0x5FC0}, //12570 #CJK UNIFIED IDEOGRAPH + {0xF449, 0x5FC1}, //12571 #CJK UNIFIED IDEOGRAPH + {0xF44A, 0x61F9}, //12572 #CJK UNIFIED IDEOGRAPH + {0xF44B, 0x6517}, //12573 #CJK UNIFIED IDEOGRAPH + {0xF44C, 0x6516}, //12574 #CJK UNIFIED IDEOGRAPH + {0xF44D, 0x6515}, //12575 #CJK UNIFIED IDEOGRAPH + {0xF44E, 0x6513}, //12576 #CJK UNIFIED IDEOGRAPH + {0xF44F, 0x65DF}, //12577 #CJK UNIFIED IDEOGRAPH + {0xF450, 0x66E8}, //12578 #CJK UNIFIED IDEOGRAPH + {0xF451, 0x66E3}, //12579 #CJK UNIFIED IDEOGRAPH + {0xF452, 0x66E4}, //12580 #CJK UNIFIED IDEOGRAPH + {0xF453, 0x6AF3}, //12581 #CJK UNIFIED IDEOGRAPH + {0xF454, 0x6AF0}, //12582 #CJK UNIFIED IDEOGRAPH + {0xF455, 0x6AEA}, //12583 #CJK UNIFIED IDEOGRAPH + {0xF456, 0x6AE8}, //12584 #CJK UNIFIED IDEOGRAPH + {0xF457, 0x6AF9}, //12585 #CJK UNIFIED IDEOGRAPH + {0xF458, 0x6AF1}, //12586 #CJK UNIFIED IDEOGRAPH + {0xF459, 0x6AEE}, //12587 #CJK UNIFIED IDEOGRAPH + {0xF45A, 0x6AEF}, //12588 #CJK UNIFIED IDEOGRAPH + {0xF45B, 0x703C}, //12589 #CJK UNIFIED IDEOGRAPH + {0xF45C, 0x7035}, //12590 #CJK UNIFIED IDEOGRAPH + {0xF45D, 0x702F}, //12591 #CJK UNIFIED IDEOGRAPH + {0xF45E, 0x7037}, //12592 #CJK UNIFIED IDEOGRAPH + {0xF45F, 0x7034}, //12593 #CJK UNIFIED IDEOGRAPH + {0xF460, 0x7031}, //12594 #CJK UNIFIED IDEOGRAPH + {0xF461, 0x7042}, //12595 #CJK UNIFIED IDEOGRAPH + {0xF462, 0x7038}, //12596 #CJK UNIFIED IDEOGRAPH + {0xF463, 0x703F}, //12597 #CJK UNIFIED IDEOGRAPH + {0xF464, 0x703A}, //12598 #CJK UNIFIED IDEOGRAPH + {0xF465, 0x7039}, //12599 #CJK UNIFIED IDEOGRAPH + {0xF466, 0x7040}, //12600 #CJK UNIFIED IDEOGRAPH + {0xF467, 0x703B}, //12601 #CJK UNIFIED IDEOGRAPH + {0xF468, 0x7033}, //12602 #CJK UNIFIED IDEOGRAPH + {0xF469, 0x7041}, //12603 #CJK UNIFIED IDEOGRAPH + {0xF46A, 0x7213}, //12604 #CJK UNIFIED IDEOGRAPH + {0xF46B, 0x7214}, //12605 #CJK UNIFIED IDEOGRAPH + {0xF46C, 0x72A8}, //12606 #CJK UNIFIED IDEOGRAPH + {0xF46D, 0x737D}, //12607 #CJK UNIFIED IDEOGRAPH + {0xF46E, 0x737C}, //12608 #CJK UNIFIED IDEOGRAPH + {0xF46F, 0x74BA}, //12609 #CJK UNIFIED IDEOGRAPH + {0xF470, 0x76AB}, //12610 #CJK UNIFIED IDEOGRAPH + {0xF471, 0x76AA}, //12611 #CJK UNIFIED IDEOGRAPH + {0xF472, 0x76BE}, //12612 #CJK UNIFIED IDEOGRAPH + {0xF473, 0x76ED}, //12613 #CJK UNIFIED IDEOGRAPH + {0xF474, 0x77CC}, //12614 #CJK UNIFIED IDEOGRAPH + {0xF475, 0x77CE}, //12615 #CJK UNIFIED IDEOGRAPH + {0xF476, 0x77CF}, //12616 #CJK UNIFIED IDEOGRAPH + {0xF477, 0x77CD}, //12617 #CJK UNIFIED IDEOGRAPH + {0xF478, 0x77F2}, //12618 #CJK UNIFIED IDEOGRAPH + {0xF479, 0x7925}, //12619 #CJK UNIFIED IDEOGRAPH + {0xF47A, 0x7923}, //12620 #CJK UNIFIED IDEOGRAPH + {0xF47B, 0x7927}, //12621 #CJK UNIFIED IDEOGRAPH + {0xF47C, 0x7928}, //12622 #CJK UNIFIED IDEOGRAPH + {0xF47D, 0x7924}, //12623 #CJK UNIFIED IDEOGRAPH + {0xF47E, 0x7929}, //12624 #CJK UNIFIED IDEOGRAPH + {0xF4A1, 0x79B2}, //12625 #CJK UNIFIED IDEOGRAPH + {0xF4A2, 0x7A6E}, //12626 #CJK UNIFIED IDEOGRAPH + {0xF4A3, 0x7A6C}, //12627 #CJK UNIFIED IDEOGRAPH + {0xF4A4, 0x7A6D}, //12628 #CJK UNIFIED IDEOGRAPH + {0xF4A5, 0x7AF7}, //12629 #CJK UNIFIED IDEOGRAPH + {0xF4A6, 0x7C49}, //12630 #CJK UNIFIED IDEOGRAPH + {0xF4A7, 0x7C48}, //12631 #CJK UNIFIED IDEOGRAPH + {0xF4A8, 0x7C4A}, //12632 #CJK UNIFIED IDEOGRAPH + {0xF4A9, 0x7C47}, //12633 #CJK UNIFIED IDEOGRAPH + {0xF4AA, 0x7C45}, //12634 #CJK UNIFIED IDEOGRAPH + {0xF4AB, 0x7CEE}, //12635 #CJK UNIFIED IDEOGRAPH + {0xF4AC, 0x7E7B}, //12636 #CJK UNIFIED IDEOGRAPH + {0xF4AD, 0x7E7E}, //12637 #CJK UNIFIED IDEOGRAPH + {0xF4AE, 0x7E81}, //12638 #CJK UNIFIED IDEOGRAPH + {0xF4AF, 0x7E80}, //12639 #CJK UNIFIED IDEOGRAPH + {0xF4B0, 0x7FBA}, //12640 #CJK UNIFIED IDEOGRAPH + {0xF4B1, 0x7FFF}, //12641 #CJK UNIFIED IDEOGRAPH + {0xF4B2, 0x8079}, //12642 #CJK UNIFIED IDEOGRAPH + {0xF4B3, 0x81DB}, //12643 #CJK UNIFIED IDEOGRAPH + {0xF4B4, 0x81D9}, //12644 #CJK UNIFIED IDEOGRAPH + {0xF4B5, 0x820B}, //12645 #CJK UNIFIED IDEOGRAPH + {0xF4B6, 0x8268}, //12646 #CJK UNIFIED IDEOGRAPH + {0xF4B7, 0x8269}, //12647 #CJK UNIFIED IDEOGRAPH + {0xF4B8, 0x8622}, //12648 #CJK UNIFIED IDEOGRAPH + {0xF4B9, 0x85FF}, //12649 #CJK UNIFIED IDEOGRAPH + {0xF4BA, 0x8601}, //12650 #CJK UNIFIED IDEOGRAPH + {0xF4BB, 0x85FE}, //12651 #CJK UNIFIED IDEOGRAPH + {0xF4BC, 0x861B}, //12652 #CJK UNIFIED IDEOGRAPH + {0xF4BD, 0x8600}, //12653 #CJK UNIFIED IDEOGRAPH + {0xF4BE, 0x85F6}, //12654 #CJK UNIFIED IDEOGRAPH + {0xF4BF, 0x8604}, //12655 #CJK UNIFIED IDEOGRAPH + {0xF4C0, 0x8609}, //12656 #CJK UNIFIED IDEOGRAPH + {0xF4C1, 0x8605}, //12657 #CJK UNIFIED IDEOGRAPH + {0xF4C2, 0x860C}, //12658 #CJK UNIFIED IDEOGRAPH + {0xF4C3, 0x85FD}, //12659 #CJK UNIFIED IDEOGRAPH + {0xF4C4, 0x8819}, //12660 #CJK UNIFIED IDEOGRAPH + {0xF4C5, 0x8810}, //12661 #CJK UNIFIED IDEOGRAPH + {0xF4C6, 0x8811}, //12662 #CJK UNIFIED IDEOGRAPH + {0xF4C7, 0x8817}, //12663 #CJK UNIFIED IDEOGRAPH + {0xF4C8, 0x8813}, //12664 #CJK UNIFIED IDEOGRAPH + {0xF4C9, 0x8816}, //12665 #CJK UNIFIED IDEOGRAPH + {0xF4CA, 0x8963}, //12666 #CJK UNIFIED IDEOGRAPH + {0xF4CB, 0x8966}, //12667 #CJK UNIFIED IDEOGRAPH + {0xF4CC, 0x89B9}, //12668 #CJK UNIFIED IDEOGRAPH + {0xF4CD, 0x89F7}, //12669 #CJK UNIFIED IDEOGRAPH + {0xF4CE, 0x8B60}, //12670 #CJK UNIFIED IDEOGRAPH + {0xF4CF, 0x8B6A}, //12671 #CJK UNIFIED IDEOGRAPH + {0xF4D0, 0x8B5D}, //12672 #CJK UNIFIED IDEOGRAPH + {0xF4D1, 0x8B68}, //12673 #CJK UNIFIED IDEOGRAPH + {0xF4D2, 0x8B63}, //12674 #CJK UNIFIED IDEOGRAPH + {0xF4D3, 0x8B65}, //12675 #CJK UNIFIED IDEOGRAPH + {0xF4D4, 0x8B67}, //12676 #CJK UNIFIED IDEOGRAPH + {0xF4D5, 0x8B6D}, //12677 #CJK UNIFIED IDEOGRAPH + {0xF4D6, 0x8DAE}, //12678 #CJK UNIFIED IDEOGRAPH + {0xF4D7, 0x8E86}, //12679 #CJK UNIFIED IDEOGRAPH + {0xF4D8, 0x8E88}, //12680 #CJK UNIFIED IDEOGRAPH + {0xF4D9, 0x8E84}, //12681 #CJK UNIFIED IDEOGRAPH + {0xF4DA, 0x8F59}, //12682 #CJK UNIFIED IDEOGRAPH + {0xF4DB, 0x8F56}, //12683 #CJK UNIFIED IDEOGRAPH + {0xF4DC, 0x8F57}, //12684 #CJK UNIFIED IDEOGRAPH + {0xF4DD, 0x8F55}, //12685 #CJK UNIFIED IDEOGRAPH + {0xF4DE, 0x8F58}, //12686 #CJK UNIFIED IDEOGRAPH + {0xF4DF, 0x8F5A}, //12687 #CJK UNIFIED IDEOGRAPH + {0xF4E0, 0x908D}, //12688 #CJK UNIFIED IDEOGRAPH + {0xF4E1, 0x9143}, //12689 #CJK UNIFIED IDEOGRAPH + {0xF4E2, 0x9141}, //12690 #CJK UNIFIED IDEOGRAPH + {0xF4E3, 0x91B7}, //12691 #CJK UNIFIED IDEOGRAPH + {0xF4E4, 0x91B5}, //12692 #CJK UNIFIED IDEOGRAPH + {0xF4E5, 0x91B2}, //12693 #CJK UNIFIED IDEOGRAPH + {0xF4E6, 0x91B3}, //12694 #CJK UNIFIED IDEOGRAPH + {0xF4E7, 0x940B}, //12695 #CJK UNIFIED IDEOGRAPH + {0xF4E8, 0x9413}, //12696 #CJK UNIFIED IDEOGRAPH + {0xF4E9, 0x93FB}, //12697 #CJK UNIFIED IDEOGRAPH + {0xF4EA, 0x9420}, //12698 #CJK UNIFIED IDEOGRAPH + {0xF4EB, 0x940F}, //12699 #CJK UNIFIED IDEOGRAPH + {0xF4EC, 0x9414}, //12700 #CJK UNIFIED IDEOGRAPH + {0xF4ED, 0x93FE}, //12701 #CJK UNIFIED IDEOGRAPH + {0xF4EE, 0x9415}, //12702 #CJK UNIFIED IDEOGRAPH + {0xF4EF, 0x9410}, //12703 #CJK UNIFIED IDEOGRAPH + {0xF4F0, 0x9428}, //12704 #CJK UNIFIED IDEOGRAPH + {0xF4F1, 0x9419}, //12705 #CJK UNIFIED IDEOGRAPH + {0xF4F2, 0x940D}, //12706 #CJK UNIFIED IDEOGRAPH + {0xF4F3, 0x93F5}, //12707 #CJK UNIFIED IDEOGRAPH + {0xF4F4, 0x9400}, //12708 #CJK UNIFIED IDEOGRAPH + {0xF4F5, 0x93F7}, //12709 #CJK UNIFIED IDEOGRAPH + {0xF4F6, 0x9407}, //12710 #CJK UNIFIED IDEOGRAPH + {0xF4F7, 0x940E}, //12711 #CJK UNIFIED IDEOGRAPH + {0xF4F8, 0x9416}, //12712 #CJK UNIFIED IDEOGRAPH + {0xF4F9, 0x9412}, //12713 #CJK UNIFIED IDEOGRAPH + {0xF4FA, 0x93FA}, //12714 #CJK UNIFIED IDEOGRAPH + {0xF4FB, 0x9409}, //12715 #CJK UNIFIED IDEOGRAPH + {0xF4FC, 0x93F8}, //12716 #CJK UNIFIED IDEOGRAPH + {0xF4FD, 0x940A}, //12717 #CJK UNIFIED IDEOGRAPH + {0xF4FE, 0x93FF}, //12718 #CJK UNIFIED IDEOGRAPH + {0xF540, 0x93FC}, //12719 #CJK UNIFIED IDEOGRAPH + {0xF541, 0x940C}, //12720 #CJK UNIFIED IDEOGRAPH + {0xF542, 0x93F6}, //12721 #CJK UNIFIED IDEOGRAPH + {0xF543, 0x9411}, //12722 #CJK UNIFIED IDEOGRAPH + {0xF544, 0x9406}, //12723 #CJK UNIFIED IDEOGRAPH + {0xF545, 0x95DE}, //12724 #CJK UNIFIED IDEOGRAPH + {0xF546, 0x95E0}, //12725 #CJK UNIFIED IDEOGRAPH + {0xF547, 0x95DF}, //12726 #CJK UNIFIED IDEOGRAPH + {0xF548, 0x972E}, //12727 #CJK UNIFIED IDEOGRAPH + {0xF549, 0x972F}, //12728 #CJK UNIFIED IDEOGRAPH + {0xF54A, 0x97B9}, //12729 #CJK UNIFIED IDEOGRAPH + {0xF54B, 0x97BB}, //12730 #CJK UNIFIED IDEOGRAPH + {0xF54C, 0x97FD}, //12731 #CJK UNIFIED IDEOGRAPH + {0xF54D, 0x97FE}, //12732 #CJK UNIFIED IDEOGRAPH + {0xF54E, 0x9860}, //12733 #CJK UNIFIED IDEOGRAPH + {0xF54F, 0x9862}, //12734 #CJK UNIFIED IDEOGRAPH + {0xF550, 0x9863}, //12735 #CJK UNIFIED IDEOGRAPH + {0xF551, 0x985F}, //12736 #CJK UNIFIED IDEOGRAPH + {0xF552, 0x98C1}, //12737 #CJK UNIFIED IDEOGRAPH + {0xF553, 0x98C2}, //12738 #CJK UNIFIED IDEOGRAPH + {0xF554, 0x9950}, //12739 #CJK UNIFIED IDEOGRAPH + {0xF555, 0x994E}, //12740 #CJK UNIFIED IDEOGRAPH + {0xF556, 0x9959}, //12741 #CJK UNIFIED IDEOGRAPH + {0xF557, 0x994C}, //12742 #CJK UNIFIED IDEOGRAPH + {0xF558, 0x994B}, //12743 #CJK UNIFIED IDEOGRAPH + {0xF559, 0x9953}, //12744 #CJK UNIFIED IDEOGRAPH + {0xF55A, 0x9A32}, //12745 #CJK UNIFIED IDEOGRAPH + {0xF55B, 0x9A34}, //12746 #CJK UNIFIED IDEOGRAPH + {0xF55C, 0x9A31}, //12747 #CJK UNIFIED IDEOGRAPH + {0xF55D, 0x9A2C}, //12748 #CJK UNIFIED IDEOGRAPH + {0xF55E, 0x9A2A}, //12749 #CJK UNIFIED IDEOGRAPH + {0xF55F, 0x9A36}, //12750 #CJK UNIFIED IDEOGRAPH + {0xF560, 0x9A29}, //12751 #CJK UNIFIED IDEOGRAPH + {0xF561, 0x9A2E}, //12752 #CJK UNIFIED IDEOGRAPH + {0xF562, 0x9A38}, //12753 #CJK UNIFIED IDEOGRAPH + {0xF563, 0x9A2D}, //12754 #CJK UNIFIED IDEOGRAPH + {0xF564, 0x9AC7}, //12755 #CJK UNIFIED IDEOGRAPH + {0xF565, 0x9ACA}, //12756 #CJK UNIFIED IDEOGRAPH + {0xF566, 0x9AC6}, //12757 #CJK UNIFIED IDEOGRAPH + {0xF567, 0x9B10}, //12758 #CJK UNIFIED IDEOGRAPH + {0xF568, 0x9B12}, //12759 #CJK UNIFIED IDEOGRAPH + {0xF569, 0x9B11}, //12760 #CJK UNIFIED IDEOGRAPH + {0xF56A, 0x9C0B}, //12761 #CJK UNIFIED IDEOGRAPH + {0xF56B, 0x9C08}, //12762 #CJK UNIFIED IDEOGRAPH + {0xF56C, 0x9BF7}, //12763 #CJK UNIFIED IDEOGRAPH + {0xF56D, 0x9C05}, //12764 #CJK UNIFIED IDEOGRAPH + {0xF56E, 0x9C12}, //12765 #CJK UNIFIED IDEOGRAPH + {0xF56F, 0x9BF8}, //12766 #CJK UNIFIED IDEOGRAPH + {0xF570, 0x9C40}, //12767 #CJK UNIFIED IDEOGRAPH + {0xF571, 0x9C07}, //12768 #CJK UNIFIED IDEOGRAPH + {0xF572, 0x9C0E}, //12769 #CJK UNIFIED IDEOGRAPH + {0xF573, 0x9C06}, //12770 #CJK UNIFIED IDEOGRAPH + {0xF574, 0x9C17}, //12771 #CJK UNIFIED IDEOGRAPH + {0xF575, 0x9C14}, //12772 #CJK UNIFIED IDEOGRAPH + {0xF576, 0x9C09}, //12773 #CJK UNIFIED IDEOGRAPH + {0xF577, 0x9D9F}, //12774 #CJK UNIFIED IDEOGRAPH + {0xF578, 0x9D99}, //12775 #CJK UNIFIED IDEOGRAPH + {0xF579, 0x9DA4}, //12776 #CJK UNIFIED IDEOGRAPH + {0xF57A, 0x9D9D}, //12777 #CJK UNIFIED IDEOGRAPH + {0xF57B, 0x9D92}, //12778 #CJK UNIFIED IDEOGRAPH + {0xF57C, 0x9D98}, //12779 #CJK UNIFIED IDEOGRAPH + {0xF57D, 0x9D90}, //12780 #CJK UNIFIED IDEOGRAPH + {0xF57E, 0x9D9B}, //12781 #CJK UNIFIED IDEOGRAPH + {0xF5A1, 0x9DA0}, //12782 #CJK UNIFIED IDEOGRAPH + {0xF5A2, 0x9D94}, //12783 #CJK UNIFIED IDEOGRAPH + {0xF5A3, 0x9D9C}, //12784 #CJK UNIFIED IDEOGRAPH + {0xF5A4, 0x9DAA}, //12785 #CJK UNIFIED IDEOGRAPH + {0xF5A5, 0x9D97}, //12786 #CJK UNIFIED IDEOGRAPH + {0xF5A6, 0x9DA1}, //12787 #CJK UNIFIED IDEOGRAPH + {0xF5A7, 0x9D9A}, //12788 #CJK UNIFIED IDEOGRAPH + {0xF5A8, 0x9DA2}, //12789 #CJK UNIFIED IDEOGRAPH + {0xF5A9, 0x9DA8}, //12790 #CJK UNIFIED IDEOGRAPH + {0xF5AA, 0x9D9E}, //12791 #CJK UNIFIED IDEOGRAPH + {0xF5AB, 0x9DA3}, //12792 #CJK UNIFIED IDEOGRAPH + {0xF5AC, 0x9DBF}, //12793 #CJK UNIFIED IDEOGRAPH + {0xF5AD, 0x9DA9}, //12794 #CJK UNIFIED IDEOGRAPH + {0xF5AE, 0x9D96}, //12795 #CJK UNIFIED IDEOGRAPH + {0xF5AF, 0x9DA6}, //12796 #CJK UNIFIED IDEOGRAPH + {0xF5B0, 0x9DA7}, //12797 #CJK UNIFIED IDEOGRAPH + {0xF5B1, 0x9E99}, //12798 #CJK UNIFIED IDEOGRAPH + {0xF5B2, 0x9E9B}, //12799 #CJK UNIFIED IDEOGRAPH + {0xF5B3, 0x9E9A}, //12800 #CJK UNIFIED IDEOGRAPH + {0xF5B4, 0x9EE5}, //12801 #CJK UNIFIED IDEOGRAPH + {0xF5B5, 0x9EE4}, //12802 #CJK UNIFIED IDEOGRAPH + {0xF5B6, 0x9EE7}, //12803 #CJK UNIFIED IDEOGRAPH + {0xF5B7, 0x9EE6}, //12804 #CJK UNIFIED IDEOGRAPH + {0xF5B8, 0x9F30}, //12805 #CJK UNIFIED IDEOGRAPH + {0xF5B9, 0x9F2E}, //12806 #CJK UNIFIED IDEOGRAPH + {0xF5BA, 0x9F5B}, //12807 #CJK UNIFIED IDEOGRAPH + {0xF5BB, 0x9F60}, //12808 #CJK UNIFIED IDEOGRAPH + {0xF5BC, 0x9F5E}, //12809 #CJK UNIFIED IDEOGRAPH + {0xF5BD, 0x9F5D}, //12810 #CJK UNIFIED IDEOGRAPH + {0xF5BE, 0x9F59}, //12811 #CJK UNIFIED IDEOGRAPH + {0xF5BF, 0x9F91}, //12812 #CJK UNIFIED IDEOGRAPH + {0xF5C0, 0x513A}, //12813 #CJK UNIFIED IDEOGRAPH + {0xF5C1, 0x5139}, //12814 #CJK UNIFIED IDEOGRAPH + {0xF5C2, 0x5298}, //12815 #CJK UNIFIED IDEOGRAPH + {0xF5C3, 0x5297}, //12816 #CJK UNIFIED IDEOGRAPH + {0xF5C4, 0x56C3}, //12817 #CJK UNIFIED IDEOGRAPH + {0xF5C5, 0x56BD}, //12818 #CJK UNIFIED IDEOGRAPH + {0xF5C6, 0x56BE}, //12819 #CJK UNIFIED IDEOGRAPH + {0xF5C7, 0x5B48}, //12820 #CJK UNIFIED IDEOGRAPH + {0xF5C8, 0x5B47}, //12821 #CJK UNIFIED IDEOGRAPH + {0xF5C9, 0x5DCB}, //12822 #CJK UNIFIED IDEOGRAPH + {0xF5CA, 0x5DCF}, //12823 #CJK UNIFIED IDEOGRAPH + {0xF5CB, 0x5EF1}, //12824 #CJK UNIFIED IDEOGRAPH + {0xF5CC, 0x61FD}, //12825 #CJK UNIFIED IDEOGRAPH + {0xF5CD, 0x651B}, //12826 #CJK UNIFIED IDEOGRAPH + {0xF5CE, 0x6B02}, //12827 #CJK UNIFIED IDEOGRAPH + {0xF5CF, 0x6AFC}, //12828 #CJK UNIFIED IDEOGRAPH + {0xF5D0, 0x6B03}, //12829 #CJK UNIFIED IDEOGRAPH + {0xF5D1, 0x6AF8}, //12830 #CJK UNIFIED IDEOGRAPH + {0xF5D2, 0x6B00}, //12831 #CJK UNIFIED IDEOGRAPH + {0xF5D3, 0x7043}, //12832 #CJK UNIFIED IDEOGRAPH + {0xF5D4, 0x7044}, //12833 #CJK UNIFIED IDEOGRAPH + {0xF5D5, 0x704A}, //12834 #CJK UNIFIED IDEOGRAPH + {0xF5D6, 0x7048}, //12835 #CJK UNIFIED IDEOGRAPH + {0xF5D7, 0x7049}, //12836 #CJK UNIFIED IDEOGRAPH + {0xF5D8, 0x7045}, //12837 #CJK UNIFIED IDEOGRAPH + {0xF5D9, 0x7046}, //12838 #CJK UNIFIED IDEOGRAPH + {0xF5DA, 0x721D}, //12839 #CJK UNIFIED IDEOGRAPH + {0xF5DB, 0x721A}, //12840 #CJK UNIFIED IDEOGRAPH + {0xF5DC, 0x7219}, //12841 #CJK UNIFIED IDEOGRAPH + {0xF5DD, 0x737E}, //12842 #CJK UNIFIED IDEOGRAPH + {0xF5DE, 0x7517}, //12843 #CJK UNIFIED IDEOGRAPH + {0xF5DF, 0x766A}, //12844 #CJK UNIFIED IDEOGRAPH + {0xF5E0, 0x77D0}, //12845 #CJK UNIFIED IDEOGRAPH + {0xF5E1, 0x792D}, //12846 #CJK UNIFIED IDEOGRAPH + {0xF5E2, 0x7931}, //12847 #CJK UNIFIED IDEOGRAPH + {0xF5E3, 0x792F}, //12848 #CJK UNIFIED IDEOGRAPH + {0xF5E4, 0x7C54}, //12849 #CJK UNIFIED IDEOGRAPH + {0xF5E5, 0x7C53}, //12850 #CJK UNIFIED IDEOGRAPH + {0xF5E6, 0x7CF2}, //12851 #CJK UNIFIED IDEOGRAPH + {0xF5E7, 0x7E8A}, //12852 #CJK UNIFIED IDEOGRAPH + {0xF5E8, 0x7E87}, //12853 #CJK UNIFIED IDEOGRAPH + {0xF5E9, 0x7E88}, //12854 #CJK UNIFIED IDEOGRAPH + {0xF5EA, 0x7E8B}, //12855 #CJK UNIFIED IDEOGRAPH + {0xF5EB, 0x7E86}, //12856 #CJK UNIFIED IDEOGRAPH + {0xF5EC, 0x7E8D}, //12857 #CJK UNIFIED IDEOGRAPH + {0xF5ED, 0x7F4D}, //12858 #CJK UNIFIED IDEOGRAPH + {0xF5EE, 0x7FBB}, //12859 #CJK UNIFIED IDEOGRAPH + {0xF5EF, 0x8030}, //12860 #CJK UNIFIED IDEOGRAPH + {0xF5F0, 0x81DD}, //12861 #CJK UNIFIED IDEOGRAPH + {0xF5F1, 0x8618}, //12862 #CJK UNIFIED IDEOGRAPH + {0xF5F2, 0x862A}, //12863 #CJK UNIFIED IDEOGRAPH + {0xF5F3, 0x8626}, //12864 #CJK UNIFIED IDEOGRAPH + {0xF5F4, 0x861F}, //12865 #CJK UNIFIED IDEOGRAPH + {0xF5F5, 0x8623}, //12866 #CJK UNIFIED IDEOGRAPH + {0xF5F6, 0x861C}, //12867 #CJK UNIFIED IDEOGRAPH + {0xF5F7, 0x8619}, //12868 #CJK UNIFIED IDEOGRAPH + {0xF5F8, 0x8627}, //12869 #CJK UNIFIED IDEOGRAPH + {0xF5F9, 0x862E}, //12870 #CJK UNIFIED IDEOGRAPH + {0xF5FA, 0x8621}, //12871 #CJK UNIFIED IDEOGRAPH + {0xF5FB, 0x8620}, //12872 #CJK UNIFIED IDEOGRAPH + {0xF5FC, 0x8629}, //12873 #CJK UNIFIED IDEOGRAPH + {0xF5FD, 0x861E}, //12874 #CJK UNIFIED IDEOGRAPH + {0xF5FE, 0x8625}, //12875 #CJK UNIFIED IDEOGRAPH + {0xF640, 0x8829}, //12876 #CJK UNIFIED IDEOGRAPH + {0xF641, 0x881D}, //12877 #CJK UNIFIED IDEOGRAPH + {0xF642, 0x881B}, //12878 #CJK UNIFIED IDEOGRAPH + {0xF643, 0x8820}, //12879 #CJK UNIFIED IDEOGRAPH + {0xF644, 0x8824}, //12880 #CJK UNIFIED IDEOGRAPH + {0xF645, 0x881C}, //12881 #CJK UNIFIED IDEOGRAPH + {0xF646, 0x882B}, //12882 #CJK UNIFIED IDEOGRAPH + {0xF647, 0x884A}, //12883 #CJK UNIFIED IDEOGRAPH + {0xF648, 0x896D}, //12884 #CJK UNIFIED IDEOGRAPH + {0xF649, 0x8969}, //12885 #CJK UNIFIED IDEOGRAPH + {0xF64A, 0x896E}, //12886 #CJK UNIFIED IDEOGRAPH + {0xF64B, 0x896B}, //12887 #CJK UNIFIED IDEOGRAPH + {0xF64C, 0x89FA}, //12888 #CJK UNIFIED IDEOGRAPH + {0xF64D, 0x8B79}, //12889 #CJK UNIFIED IDEOGRAPH + {0xF64E, 0x8B78}, //12890 #CJK UNIFIED IDEOGRAPH + {0xF64F, 0x8B45}, //12891 #CJK UNIFIED IDEOGRAPH + {0xF650, 0x8B7A}, //12892 #CJK UNIFIED IDEOGRAPH + {0xF651, 0x8B7B}, //12893 #CJK UNIFIED IDEOGRAPH + {0xF652, 0x8D10}, //12894 #CJK UNIFIED IDEOGRAPH + {0xF653, 0x8D14}, //12895 #CJK UNIFIED IDEOGRAPH + {0xF654, 0x8DAF}, //12896 #CJK UNIFIED IDEOGRAPH + {0xF655, 0x8E8E}, //12897 #CJK UNIFIED IDEOGRAPH + {0xF656, 0x8E8C}, //12898 #CJK UNIFIED IDEOGRAPH + {0xF657, 0x8F5E}, //12899 #CJK UNIFIED IDEOGRAPH + {0xF658, 0x8F5B}, //12900 #CJK UNIFIED IDEOGRAPH + {0xF659, 0x8F5D}, //12901 #CJK UNIFIED IDEOGRAPH + {0xF65A, 0x9146}, //12902 #CJK UNIFIED IDEOGRAPH + {0xF65B, 0x9144}, //12903 #CJK UNIFIED IDEOGRAPH + {0xF65C, 0x9145}, //12904 #CJK UNIFIED IDEOGRAPH + {0xF65D, 0x91B9}, //12905 #CJK UNIFIED IDEOGRAPH + {0xF65E, 0x943F}, //12906 #CJK UNIFIED IDEOGRAPH + {0xF65F, 0x943B}, //12907 #CJK UNIFIED IDEOGRAPH + {0xF660, 0x9436}, //12908 #CJK UNIFIED IDEOGRAPH + {0xF661, 0x9429}, //12909 #CJK UNIFIED IDEOGRAPH + {0xF662, 0x943D}, //12910 #CJK UNIFIED IDEOGRAPH + {0xF663, 0x943C}, //12911 #CJK UNIFIED IDEOGRAPH + {0xF664, 0x9430}, //12912 #CJK UNIFIED IDEOGRAPH + {0xF665, 0x9439}, //12913 #CJK UNIFIED IDEOGRAPH + {0xF666, 0x942A}, //12914 #CJK UNIFIED IDEOGRAPH + {0xF667, 0x9437}, //12915 #CJK UNIFIED IDEOGRAPH + {0xF668, 0x942C}, //12916 #CJK UNIFIED IDEOGRAPH + {0xF669, 0x9440}, //12917 #CJK UNIFIED IDEOGRAPH + {0xF66A, 0x9431}, //12918 #CJK UNIFIED IDEOGRAPH + {0xF66B, 0x95E5}, //12919 #CJK UNIFIED IDEOGRAPH + {0xF66C, 0x95E4}, //12920 #CJK UNIFIED IDEOGRAPH + {0xF66D, 0x95E3}, //12921 #CJK UNIFIED IDEOGRAPH + {0xF66E, 0x9735}, //12922 #CJK UNIFIED IDEOGRAPH + {0xF66F, 0x973A}, //12923 #CJK UNIFIED IDEOGRAPH + {0xF670, 0x97BF}, //12924 #CJK UNIFIED IDEOGRAPH + {0xF671, 0x97E1}, //12925 #CJK UNIFIED IDEOGRAPH + {0xF672, 0x9864}, //12926 #CJK UNIFIED IDEOGRAPH + {0xF673, 0x98C9}, //12927 #CJK UNIFIED IDEOGRAPH + {0xF674, 0x98C6}, //12928 #CJK UNIFIED IDEOGRAPH + {0xF675, 0x98C0}, //12929 #CJK UNIFIED IDEOGRAPH + {0xF676, 0x9958}, //12930 #CJK UNIFIED IDEOGRAPH + {0xF677, 0x9956}, //12931 #CJK UNIFIED IDEOGRAPH + {0xF678, 0x9A39}, //12932 #CJK UNIFIED IDEOGRAPH + {0xF679, 0x9A3D}, //12933 #CJK UNIFIED IDEOGRAPH + {0xF67A, 0x9A46}, //12934 #CJK UNIFIED IDEOGRAPH + {0xF67B, 0x9A44}, //12935 #CJK UNIFIED IDEOGRAPH + {0xF67C, 0x9A42}, //12936 #CJK UNIFIED IDEOGRAPH + {0xF67D, 0x9A41}, //12937 #CJK UNIFIED IDEOGRAPH + {0xF67E, 0x9A3A}, //12938 #CJK UNIFIED IDEOGRAPH + {0xF6A1, 0x9A3F}, //12939 #CJK UNIFIED IDEOGRAPH + {0xF6A2, 0x9ACD}, //12940 #CJK UNIFIED IDEOGRAPH + {0xF6A3, 0x9B15}, //12941 #CJK UNIFIED IDEOGRAPH + {0xF6A4, 0x9B17}, //12942 #CJK UNIFIED IDEOGRAPH + {0xF6A5, 0x9B18}, //12943 #CJK UNIFIED IDEOGRAPH + {0xF6A6, 0x9B16}, //12944 #CJK UNIFIED IDEOGRAPH + {0xF6A7, 0x9B3A}, //12945 #CJK UNIFIED IDEOGRAPH + {0xF6A8, 0x9B52}, //12946 #CJK UNIFIED IDEOGRAPH + {0xF6A9, 0x9C2B}, //12947 #CJK UNIFIED IDEOGRAPH + {0xF6AA, 0x9C1D}, //12948 #CJK UNIFIED IDEOGRAPH + {0xF6AB, 0x9C1C}, //12949 #CJK UNIFIED IDEOGRAPH + {0xF6AC, 0x9C2C}, //12950 #CJK UNIFIED IDEOGRAPH + {0xF6AD, 0x9C23}, //12951 #CJK UNIFIED IDEOGRAPH + {0xF6AE, 0x9C28}, //12952 #CJK UNIFIED IDEOGRAPH + {0xF6AF, 0x9C29}, //12953 #CJK UNIFIED IDEOGRAPH + {0xF6B0, 0x9C24}, //12954 #CJK UNIFIED IDEOGRAPH + {0xF6B1, 0x9C21}, //12955 #CJK UNIFIED IDEOGRAPH + {0xF6B2, 0x9DB7}, //12956 #CJK UNIFIED IDEOGRAPH + {0xF6B3, 0x9DB6}, //12957 #CJK UNIFIED IDEOGRAPH + {0xF6B4, 0x9DBC}, //12958 #CJK UNIFIED IDEOGRAPH + {0xF6B5, 0x9DC1}, //12959 #CJK UNIFIED IDEOGRAPH + {0xF6B6, 0x9DC7}, //12960 #CJK UNIFIED IDEOGRAPH + {0xF6B7, 0x9DCA}, //12961 #CJK UNIFIED IDEOGRAPH + {0xF6B8, 0x9DCF}, //12962 #CJK UNIFIED IDEOGRAPH + {0xF6B9, 0x9DBE}, //12963 #CJK UNIFIED IDEOGRAPH + {0xF6BA, 0x9DC5}, //12964 #CJK UNIFIED IDEOGRAPH + {0xF6BB, 0x9DC3}, //12965 #CJK UNIFIED IDEOGRAPH + {0xF6BC, 0x9DBB}, //12966 #CJK UNIFIED IDEOGRAPH + {0xF6BD, 0x9DB5}, //12967 #CJK UNIFIED IDEOGRAPH + {0xF6BE, 0x9DCE}, //12968 #CJK UNIFIED IDEOGRAPH + {0xF6BF, 0x9DB9}, //12969 #CJK UNIFIED IDEOGRAPH + {0xF6C0, 0x9DBA}, //12970 #CJK UNIFIED IDEOGRAPH + {0xF6C1, 0x9DAC}, //12971 #CJK UNIFIED IDEOGRAPH + {0xF6C2, 0x9DC8}, //12972 #CJK UNIFIED IDEOGRAPH + {0xF6C3, 0x9DB1}, //12973 #CJK UNIFIED IDEOGRAPH + {0xF6C4, 0x9DAD}, //12974 #CJK UNIFIED IDEOGRAPH + {0xF6C5, 0x9DCC}, //12975 #CJK UNIFIED IDEOGRAPH + {0xF6C6, 0x9DB3}, //12976 #CJK UNIFIED IDEOGRAPH + {0xF6C7, 0x9DCD}, //12977 #CJK UNIFIED IDEOGRAPH + {0xF6C8, 0x9DB2}, //12978 #CJK UNIFIED IDEOGRAPH + {0xF6C9, 0x9E7A}, //12979 #CJK UNIFIED IDEOGRAPH + {0xF6CA, 0x9E9C}, //12980 #CJK UNIFIED IDEOGRAPH + {0xF6CB, 0x9EEB}, //12981 #CJK UNIFIED IDEOGRAPH + {0xF6CC, 0x9EEE}, //12982 #CJK UNIFIED IDEOGRAPH + {0xF6CD, 0x9EED}, //12983 #CJK UNIFIED IDEOGRAPH + {0xF6CE, 0x9F1B}, //12984 #CJK UNIFIED IDEOGRAPH + {0xF6CF, 0x9F18}, //12985 #CJK UNIFIED IDEOGRAPH + {0xF6D0, 0x9F1A}, //12986 #CJK UNIFIED IDEOGRAPH + {0xF6D1, 0x9F31}, //12987 #CJK UNIFIED IDEOGRAPH + {0xF6D2, 0x9F4E}, //12988 #CJK UNIFIED IDEOGRAPH + {0xF6D3, 0x9F65}, //12989 #CJK UNIFIED IDEOGRAPH + {0xF6D4, 0x9F64}, //12990 #CJK UNIFIED IDEOGRAPH + {0xF6D5, 0x9F92}, //12991 #CJK UNIFIED IDEOGRAPH + {0xF6D6, 0x4EB9}, //12992 #CJK UNIFIED IDEOGRAPH + {0xF6D7, 0x56C6}, //12993 #CJK UNIFIED IDEOGRAPH + {0xF6D8, 0x56C5}, //12994 #CJK UNIFIED IDEOGRAPH + {0xF6D9, 0x56CB}, //12995 #CJK UNIFIED IDEOGRAPH + {0xF6DA, 0x5971}, //12996 #CJK UNIFIED IDEOGRAPH + {0xF6DB, 0x5B4B}, //12997 #CJK UNIFIED IDEOGRAPH + {0xF6DC, 0x5B4C}, //12998 #CJK UNIFIED IDEOGRAPH + {0xF6DD, 0x5DD5}, //12999 #CJK UNIFIED IDEOGRAPH + {0xF6DE, 0x5DD1}, //13000 #CJK UNIFIED IDEOGRAPH + {0xF6DF, 0x5EF2}, //13001 #CJK UNIFIED IDEOGRAPH + {0xF6E0, 0x6521}, //13002 #CJK UNIFIED IDEOGRAPH + {0xF6E1, 0x6520}, //13003 #CJK UNIFIED IDEOGRAPH + {0xF6E2, 0x6526}, //13004 #CJK UNIFIED IDEOGRAPH + {0xF6E3, 0x6522}, //13005 #CJK UNIFIED IDEOGRAPH + {0xF6E4, 0x6B0B}, //13006 #CJK UNIFIED IDEOGRAPH + {0xF6E5, 0x6B08}, //13007 #CJK UNIFIED IDEOGRAPH + {0xF6E6, 0x6B09}, //13008 #CJK UNIFIED IDEOGRAPH + {0xF6E7, 0x6C0D}, //13009 #CJK UNIFIED IDEOGRAPH + {0xF6E8, 0x7055}, //13010 #CJK UNIFIED IDEOGRAPH + {0xF6E9, 0x7056}, //13011 #CJK UNIFIED IDEOGRAPH + {0xF6EA, 0x7057}, //13012 #CJK UNIFIED IDEOGRAPH + {0xF6EB, 0x7052}, //13013 #CJK UNIFIED IDEOGRAPH + {0xF6EC, 0x721E}, //13014 #CJK UNIFIED IDEOGRAPH + {0xF6ED, 0x721F}, //13015 #CJK UNIFIED IDEOGRAPH + {0xF6EE, 0x72A9}, //13016 #CJK UNIFIED IDEOGRAPH + {0xF6EF, 0x737F}, //13017 #CJK UNIFIED IDEOGRAPH + {0xF6F0, 0x74D8}, //13018 #CJK UNIFIED IDEOGRAPH + {0xF6F1, 0x74D5}, //13019 #CJK UNIFIED IDEOGRAPH + {0xF6F2, 0x74D9}, //13020 #CJK UNIFIED IDEOGRAPH + {0xF6F3, 0x74D7}, //13021 #CJK UNIFIED IDEOGRAPH + {0xF6F4, 0x766D}, //13022 #CJK UNIFIED IDEOGRAPH + {0xF6F5, 0x76AD}, //13023 #CJK UNIFIED IDEOGRAPH + {0xF6F6, 0x7935}, //13024 #CJK UNIFIED IDEOGRAPH + {0xF6F7, 0x79B4}, //13025 #CJK UNIFIED IDEOGRAPH + {0xF6F8, 0x7A70}, //13026 #CJK UNIFIED IDEOGRAPH + {0xF6F9, 0x7A71}, //13027 #CJK UNIFIED IDEOGRAPH + {0xF6FA, 0x7C57}, //13028 #CJK UNIFIED IDEOGRAPH + {0xF6FB, 0x7C5C}, //13029 #CJK UNIFIED IDEOGRAPH + {0xF6FC, 0x7C59}, //13030 #CJK UNIFIED IDEOGRAPH + {0xF6FD, 0x7C5B}, //13031 #CJK UNIFIED IDEOGRAPH + {0xF6FE, 0x7C5A}, //13032 #CJK UNIFIED IDEOGRAPH + {0xF740, 0x7CF4}, //13033 #CJK UNIFIED IDEOGRAPH + {0xF741, 0x7CF1}, //13034 #CJK UNIFIED IDEOGRAPH + {0xF742, 0x7E91}, //13035 #CJK UNIFIED IDEOGRAPH + {0xF743, 0x7F4F}, //13036 #CJK UNIFIED IDEOGRAPH + {0xF744, 0x7F87}, //13037 #CJK UNIFIED IDEOGRAPH + {0xF745, 0x81DE}, //13038 #CJK UNIFIED IDEOGRAPH + {0xF746, 0x826B}, //13039 #CJK UNIFIED IDEOGRAPH + {0xF747, 0x8634}, //13040 #CJK UNIFIED IDEOGRAPH + {0xF748, 0x8635}, //13041 #CJK UNIFIED IDEOGRAPH + {0xF749, 0x8633}, //13042 #CJK UNIFIED IDEOGRAPH + {0xF74A, 0x862C}, //13043 #CJK UNIFIED IDEOGRAPH + {0xF74B, 0x8632}, //13044 #CJK UNIFIED IDEOGRAPH + {0xF74C, 0x8636}, //13045 #CJK UNIFIED IDEOGRAPH + {0xF74D, 0x882C}, //13046 #CJK UNIFIED IDEOGRAPH + {0xF74E, 0x8828}, //13047 #CJK UNIFIED IDEOGRAPH + {0xF74F, 0x8826}, //13048 #CJK UNIFIED IDEOGRAPH + {0xF750, 0x882A}, //13049 #CJK UNIFIED IDEOGRAPH + {0xF751, 0x8825}, //13050 #CJK UNIFIED IDEOGRAPH + {0xF752, 0x8971}, //13051 #CJK UNIFIED IDEOGRAPH + {0xF753, 0x89BF}, //13052 #CJK UNIFIED IDEOGRAPH + {0xF754, 0x89BE}, //13053 #CJK UNIFIED IDEOGRAPH + {0xF755, 0x89FB}, //13054 #CJK UNIFIED IDEOGRAPH + {0xF756, 0x8B7E}, //13055 #CJK UNIFIED IDEOGRAPH + {0xF757, 0x8B84}, //13056 #CJK UNIFIED IDEOGRAPH + {0xF758, 0x8B82}, //13057 #CJK UNIFIED IDEOGRAPH + {0xF759, 0x8B86}, //13058 #CJK UNIFIED IDEOGRAPH + {0xF75A, 0x8B85}, //13059 #CJK UNIFIED IDEOGRAPH + {0xF75B, 0x8B7F}, //13060 #CJK UNIFIED IDEOGRAPH + {0xF75C, 0x8D15}, //13061 #CJK UNIFIED IDEOGRAPH + {0xF75D, 0x8E95}, //13062 #CJK UNIFIED IDEOGRAPH + {0xF75E, 0x8E94}, //13063 #CJK UNIFIED IDEOGRAPH + {0xF75F, 0x8E9A}, //13064 #CJK UNIFIED IDEOGRAPH + {0xF760, 0x8E92}, //13065 #CJK UNIFIED IDEOGRAPH + {0xF761, 0x8E90}, //13066 #CJK UNIFIED IDEOGRAPH + {0xF762, 0x8E96}, //13067 #CJK UNIFIED IDEOGRAPH + {0xF763, 0x8E97}, //13068 #CJK UNIFIED IDEOGRAPH + {0xF764, 0x8F60}, //13069 #CJK UNIFIED IDEOGRAPH + {0xF765, 0x8F62}, //13070 #CJK UNIFIED IDEOGRAPH + {0xF766, 0x9147}, //13071 #CJK UNIFIED IDEOGRAPH + {0xF767, 0x944C}, //13072 #CJK UNIFIED IDEOGRAPH + {0xF768, 0x9450}, //13073 #CJK UNIFIED IDEOGRAPH + {0xF769, 0x944A}, //13074 #CJK UNIFIED IDEOGRAPH + {0xF76A, 0x944B}, //13075 #CJK UNIFIED IDEOGRAPH + {0xF76B, 0x944F}, //13076 #CJK UNIFIED IDEOGRAPH + {0xF76C, 0x9447}, //13077 #CJK UNIFIED IDEOGRAPH + {0xF76D, 0x9445}, //13078 #CJK UNIFIED IDEOGRAPH + {0xF76E, 0x9448}, //13079 #CJK UNIFIED IDEOGRAPH + {0xF76F, 0x9449}, //13080 #CJK UNIFIED IDEOGRAPH + {0xF770, 0x9446}, //13081 #CJK UNIFIED IDEOGRAPH + {0xF771, 0x973F}, //13082 #CJK UNIFIED IDEOGRAPH + {0xF772, 0x97E3}, //13083 #CJK UNIFIED IDEOGRAPH + {0xF773, 0x986A}, //13084 #CJK UNIFIED IDEOGRAPH + {0xF774, 0x9869}, //13085 #CJK UNIFIED IDEOGRAPH + {0xF775, 0x98CB}, //13086 #CJK UNIFIED IDEOGRAPH + {0xF776, 0x9954}, //13087 #CJK UNIFIED IDEOGRAPH + {0xF777, 0x995B}, //13088 #CJK UNIFIED IDEOGRAPH + {0xF778, 0x9A4E}, //13089 #CJK UNIFIED IDEOGRAPH + {0xF779, 0x9A53}, //13090 #CJK UNIFIED IDEOGRAPH + {0xF77A, 0x9A54}, //13091 #CJK UNIFIED IDEOGRAPH + {0xF77B, 0x9A4C}, //13092 #CJK UNIFIED IDEOGRAPH + {0xF77C, 0x9A4F}, //13093 #CJK UNIFIED IDEOGRAPH + {0xF77D, 0x9A48}, //13094 #CJK UNIFIED IDEOGRAPH + {0xF77E, 0x9A4A}, //13095 #CJK UNIFIED IDEOGRAPH + {0xF7A1, 0x9A49}, //13096 #CJK UNIFIED IDEOGRAPH + {0xF7A2, 0x9A52}, //13097 #CJK UNIFIED IDEOGRAPH + {0xF7A3, 0x9A50}, //13098 #CJK UNIFIED IDEOGRAPH + {0xF7A4, 0x9AD0}, //13099 #CJK UNIFIED IDEOGRAPH + {0xF7A5, 0x9B19}, //13100 #CJK UNIFIED IDEOGRAPH + {0xF7A6, 0x9B2B}, //13101 #CJK UNIFIED IDEOGRAPH + {0xF7A7, 0x9B3B}, //13102 #CJK UNIFIED IDEOGRAPH + {0xF7A8, 0x9B56}, //13103 #CJK UNIFIED IDEOGRAPH + {0xF7A9, 0x9B55}, //13104 #CJK UNIFIED IDEOGRAPH + {0xF7AA, 0x9C46}, //13105 #CJK UNIFIED IDEOGRAPH + {0xF7AB, 0x9C48}, //13106 #CJK UNIFIED IDEOGRAPH + {0xF7AC, 0x9C3F}, //13107 #CJK UNIFIED IDEOGRAPH + {0xF7AD, 0x9C44}, //13108 #CJK UNIFIED IDEOGRAPH + {0xF7AE, 0x9C39}, //13109 #CJK UNIFIED IDEOGRAPH + {0xF7AF, 0x9C33}, //13110 #CJK UNIFIED IDEOGRAPH + {0xF7B0, 0x9C41}, //13111 #CJK UNIFIED IDEOGRAPH + {0xF7B1, 0x9C3C}, //13112 #CJK UNIFIED IDEOGRAPH + {0xF7B2, 0x9C37}, //13113 #CJK UNIFIED IDEOGRAPH + {0xF7B3, 0x9C34}, //13114 #CJK UNIFIED IDEOGRAPH + {0xF7B4, 0x9C32}, //13115 #CJK UNIFIED IDEOGRAPH + {0xF7B5, 0x9C3D}, //13116 #CJK UNIFIED IDEOGRAPH + {0xF7B6, 0x9C36}, //13117 #CJK UNIFIED IDEOGRAPH + {0xF7B7, 0x9DDB}, //13118 #CJK UNIFIED IDEOGRAPH + {0xF7B8, 0x9DD2}, //13119 #CJK UNIFIED IDEOGRAPH + {0xF7B9, 0x9DDE}, //13120 #CJK UNIFIED IDEOGRAPH + {0xF7BA, 0x9DDA}, //13121 #CJK UNIFIED IDEOGRAPH + {0xF7BB, 0x9DCB}, //13122 #CJK UNIFIED IDEOGRAPH + {0xF7BC, 0x9DD0}, //13123 #CJK UNIFIED IDEOGRAPH + {0xF7BD, 0x9DDC}, //13124 #CJK UNIFIED IDEOGRAPH + {0xF7BE, 0x9DD1}, //13125 #CJK UNIFIED IDEOGRAPH + {0xF7BF, 0x9DDF}, //13126 #CJK UNIFIED IDEOGRAPH + {0xF7C0, 0x9DE9}, //13127 #CJK UNIFIED IDEOGRAPH + {0xF7C1, 0x9DD9}, //13128 #CJK UNIFIED IDEOGRAPH + {0xF7C2, 0x9DD8}, //13129 #CJK UNIFIED IDEOGRAPH + {0xF7C3, 0x9DD6}, //13130 #CJK UNIFIED IDEOGRAPH + {0xF7C4, 0x9DF5}, //13131 #CJK UNIFIED IDEOGRAPH + {0xF7C5, 0x9DD5}, //13132 #CJK UNIFIED IDEOGRAPH + {0xF7C6, 0x9DDD}, //13133 #CJK UNIFIED IDEOGRAPH + {0xF7C7, 0x9EB6}, //13134 #CJK UNIFIED IDEOGRAPH + {0xF7C8, 0x9EF0}, //13135 #CJK UNIFIED IDEOGRAPH + {0xF7C9, 0x9F35}, //13136 #CJK UNIFIED IDEOGRAPH + {0xF7CA, 0x9F33}, //13137 #CJK UNIFIED IDEOGRAPH + {0xF7CB, 0x9F32}, //13138 #CJK UNIFIED IDEOGRAPH + {0xF7CC, 0x9F42}, //13139 #CJK UNIFIED IDEOGRAPH + {0xF7CD, 0x9F6B}, //13140 #CJK UNIFIED IDEOGRAPH + {0xF7CE, 0x9F95}, //13141 #CJK UNIFIED IDEOGRAPH + {0xF7CF, 0x9FA2}, //13142 #CJK UNIFIED IDEOGRAPH + {0xF7D0, 0x513D}, //13143 #CJK UNIFIED IDEOGRAPH + {0xF7D1, 0x5299}, //13144 #CJK UNIFIED IDEOGRAPH + {0xF7D2, 0x58E8}, //13145 #CJK UNIFIED IDEOGRAPH + {0xF7D3, 0x58E7}, //13146 #CJK UNIFIED IDEOGRAPH + {0xF7D4, 0x5972}, //13147 #CJK UNIFIED IDEOGRAPH + {0xF7D5, 0x5B4D}, //13148 #CJK UNIFIED IDEOGRAPH + {0xF7D6, 0x5DD8}, //13149 #CJK UNIFIED IDEOGRAPH + {0xF7D7, 0x882F}, //13150 #CJK UNIFIED IDEOGRAPH + {0xF7D8, 0x5F4F}, //13151 #CJK UNIFIED IDEOGRAPH + {0xF7D9, 0x6201}, //13152 #CJK UNIFIED IDEOGRAPH + {0xF7DA, 0x6203}, //13153 #CJK UNIFIED IDEOGRAPH + {0xF7DB, 0x6204}, //13154 #CJK UNIFIED IDEOGRAPH + {0xF7DC, 0x6529}, //13155 #CJK UNIFIED IDEOGRAPH + {0xF7DD, 0x6525}, //13156 #CJK UNIFIED IDEOGRAPH + {0xF7DE, 0x6596}, //13157 #CJK UNIFIED IDEOGRAPH + {0xF7DF, 0x66EB}, //13158 #CJK UNIFIED IDEOGRAPH + {0xF7E0, 0x6B11}, //13159 #CJK UNIFIED IDEOGRAPH + {0xF7E1, 0x6B12}, //13160 #CJK UNIFIED IDEOGRAPH + {0xF7E2, 0x6B0F}, //13161 #CJK UNIFIED IDEOGRAPH + {0xF7E3, 0x6BCA}, //13162 #CJK UNIFIED IDEOGRAPH + {0xF7E4, 0x705B}, //13163 #CJK UNIFIED IDEOGRAPH + {0xF7E5, 0x705A}, //13164 #CJK UNIFIED IDEOGRAPH + {0xF7E6, 0x7222}, //13165 #CJK UNIFIED IDEOGRAPH + {0xF7E7, 0x7382}, //13166 #CJK UNIFIED IDEOGRAPH + {0xF7E8, 0x7381}, //13167 #CJK UNIFIED IDEOGRAPH + {0xF7E9, 0x7383}, //13168 #CJK UNIFIED IDEOGRAPH + {0xF7EA, 0x7670}, //13169 #CJK UNIFIED IDEOGRAPH + {0xF7EB, 0x77D4}, //13170 #CJK UNIFIED IDEOGRAPH + {0xF7EC, 0x7C67}, //13171 #CJK UNIFIED IDEOGRAPH + {0xF7ED, 0x7C66}, //13172 #CJK UNIFIED IDEOGRAPH + {0xF7EE, 0x7E95}, //13173 #CJK UNIFIED IDEOGRAPH + {0xF7EF, 0x826C}, //13174 #CJK UNIFIED IDEOGRAPH + {0xF7F0, 0x863A}, //13175 #CJK UNIFIED IDEOGRAPH + {0xF7F1, 0x8640}, //13176 #CJK UNIFIED IDEOGRAPH + {0xF7F2, 0x8639}, //13177 #CJK UNIFIED IDEOGRAPH + {0xF7F3, 0x863C}, //13178 #CJK UNIFIED IDEOGRAPH + {0xF7F4, 0x8631}, //13179 #CJK UNIFIED IDEOGRAPH + {0xF7F5, 0x863B}, //13180 #CJK UNIFIED IDEOGRAPH + {0xF7F6, 0x863E}, //13181 #CJK UNIFIED IDEOGRAPH + {0xF7F7, 0x8830}, //13182 #CJK UNIFIED IDEOGRAPH + {0xF7F8, 0x8832}, //13183 #CJK UNIFIED IDEOGRAPH + {0xF7F9, 0x882E}, //13184 #CJK UNIFIED IDEOGRAPH + {0xF7FA, 0x8833}, //13185 #CJK UNIFIED IDEOGRAPH + {0xF7FB, 0x8976}, //13186 #CJK UNIFIED IDEOGRAPH + {0xF7FC, 0x8974}, //13187 #CJK UNIFIED IDEOGRAPH + {0xF7FD, 0x8973}, //13188 #CJK UNIFIED IDEOGRAPH + {0xF7FE, 0x89FE}, //13189 #CJK UNIFIED IDEOGRAPH + {0xF840, 0x8B8C}, //13190 #CJK UNIFIED IDEOGRAPH + {0xF841, 0x8B8E}, //13191 #CJK UNIFIED IDEOGRAPH + {0xF842, 0x8B8B}, //13192 #CJK UNIFIED IDEOGRAPH + {0xF843, 0x8B88}, //13193 #CJK UNIFIED IDEOGRAPH + {0xF844, 0x8C45}, //13194 #CJK UNIFIED IDEOGRAPH + {0xF845, 0x8D19}, //13195 #CJK UNIFIED IDEOGRAPH + {0xF846, 0x8E98}, //13196 #CJK UNIFIED IDEOGRAPH + {0xF847, 0x8F64}, //13197 #CJK UNIFIED IDEOGRAPH + {0xF848, 0x8F63}, //13198 #CJK UNIFIED IDEOGRAPH + {0xF849, 0x91BC}, //13199 #CJK UNIFIED IDEOGRAPH + {0xF84A, 0x9462}, //13200 #CJK UNIFIED IDEOGRAPH + {0xF84B, 0x9455}, //13201 #CJK UNIFIED IDEOGRAPH + {0xF84C, 0x945D}, //13202 #CJK UNIFIED IDEOGRAPH + {0xF84D, 0x9457}, //13203 #CJK UNIFIED IDEOGRAPH + {0xF84E, 0x945E}, //13204 #CJK UNIFIED IDEOGRAPH + {0xF84F, 0x97C4}, //13205 #CJK UNIFIED IDEOGRAPH + {0xF850, 0x97C5}, //13206 #CJK UNIFIED IDEOGRAPH + {0xF851, 0x9800}, //13207 #CJK UNIFIED IDEOGRAPH + {0xF852, 0x9A56}, //13208 #CJK UNIFIED IDEOGRAPH + {0xF853, 0x9A59}, //13209 #CJK UNIFIED IDEOGRAPH + {0xF854, 0x9B1E}, //13210 #CJK UNIFIED IDEOGRAPH + {0xF855, 0x9B1F}, //13211 #CJK UNIFIED IDEOGRAPH + {0xF856, 0x9B20}, //13212 #CJK UNIFIED IDEOGRAPH + {0xF857, 0x9C52}, //13213 #CJK UNIFIED IDEOGRAPH + {0xF858, 0x9C58}, //13214 #CJK UNIFIED IDEOGRAPH + {0xF859, 0x9C50}, //13215 #CJK UNIFIED IDEOGRAPH + {0xF85A, 0x9C4A}, //13216 #CJK UNIFIED IDEOGRAPH + {0xF85B, 0x9C4D}, //13217 #CJK UNIFIED IDEOGRAPH + {0xF85C, 0x9C4B}, //13218 #CJK UNIFIED IDEOGRAPH + {0xF85D, 0x9C55}, //13219 #CJK UNIFIED IDEOGRAPH + {0xF85E, 0x9C59}, //13220 #CJK UNIFIED IDEOGRAPH + {0xF85F, 0x9C4C}, //13221 #CJK UNIFIED IDEOGRAPH + {0xF860, 0x9C4E}, //13222 #CJK UNIFIED IDEOGRAPH + {0xF861, 0x9DFB}, //13223 #CJK UNIFIED IDEOGRAPH + {0xF862, 0x9DF7}, //13224 #CJK UNIFIED IDEOGRAPH + {0xF863, 0x9DEF}, //13225 #CJK UNIFIED IDEOGRAPH + {0xF864, 0x9DE3}, //13226 #CJK UNIFIED IDEOGRAPH + {0xF865, 0x9DEB}, //13227 #CJK UNIFIED IDEOGRAPH + {0xF866, 0x9DF8}, //13228 #CJK UNIFIED IDEOGRAPH + {0xF867, 0x9DE4}, //13229 #CJK UNIFIED IDEOGRAPH + {0xF868, 0x9DF6}, //13230 #CJK UNIFIED IDEOGRAPH + {0xF869, 0x9DE1}, //13231 #CJK UNIFIED IDEOGRAPH + {0xF86A, 0x9DEE}, //13232 #CJK UNIFIED IDEOGRAPH + {0xF86B, 0x9DE6}, //13233 #CJK UNIFIED IDEOGRAPH + {0xF86C, 0x9DF2}, //13234 #CJK UNIFIED IDEOGRAPH + {0xF86D, 0x9DF0}, //13235 #CJK UNIFIED IDEOGRAPH + {0xF86E, 0x9DE2}, //13236 #CJK UNIFIED IDEOGRAPH + {0xF86F, 0x9DEC}, //13237 #CJK UNIFIED IDEOGRAPH + {0xF870, 0x9DF4}, //13238 #CJK UNIFIED IDEOGRAPH + {0xF871, 0x9DF3}, //13239 #CJK UNIFIED IDEOGRAPH + {0xF872, 0x9DE8}, //13240 #CJK UNIFIED IDEOGRAPH + {0xF873, 0x9DED}, //13241 #CJK UNIFIED IDEOGRAPH + {0xF874, 0x9EC2}, //13242 #CJK UNIFIED IDEOGRAPH + {0xF875, 0x9ED0}, //13243 #CJK UNIFIED IDEOGRAPH + {0xF876, 0x9EF2}, //13244 #CJK UNIFIED IDEOGRAPH + {0xF877, 0x9EF3}, //13245 #CJK UNIFIED IDEOGRAPH + {0xF878, 0x9F06}, //13246 #CJK UNIFIED IDEOGRAPH + {0xF879, 0x9F1C}, //13247 #CJK UNIFIED IDEOGRAPH + {0xF87A, 0x9F38}, //13248 #CJK UNIFIED IDEOGRAPH + {0xF87B, 0x9F37}, //13249 #CJK UNIFIED IDEOGRAPH + {0xF87C, 0x9F36}, //13250 #CJK UNIFIED IDEOGRAPH + {0xF87D, 0x9F43}, //13251 #CJK UNIFIED IDEOGRAPH + {0xF87E, 0x9F4F}, //13252 #CJK UNIFIED IDEOGRAPH + {0xF8A1, 0x9F71}, //13253 #CJK UNIFIED IDEOGRAPH + {0xF8A2, 0x9F70}, //13254 #CJK UNIFIED IDEOGRAPH + {0xF8A3, 0x9F6E}, //13255 #CJK UNIFIED IDEOGRAPH + {0xF8A4, 0x9F6F}, //13256 #CJK UNIFIED IDEOGRAPH + {0xF8A5, 0x56D3}, //13257 #CJK UNIFIED IDEOGRAPH + {0xF8A6, 0x56CD}, //13258 #CJK UNIFIED IDEOGRAPH + {0xF8A7, 0x5B4E}, //13259 #CJK UNIFIED IDEOGRAPH + {0xF8A8, 0x5C6D}, //13260 #CJK UNIFIED IDEOGRAPH + {0xF8A9, 0x652D}, //13261 #CJK UNIFIED IDEOGRAPH + {0xF8AA, 0x66ED}, //13262 #CJK UNIFIED IDEOGRAPH + {0xF8AB, 0x66EE}, //13263 #CJK UNIFIED IDEOGRAPH + {0xF8AC, 0x6B13}, //13264 #CJK UNIFIED IDEOGRAPH + {0xF8AD, 0x705F}, //13265 #CJK UNIFIED IDEOGRAPH + {0xF8AE, 0x7061}, //13266 #CJK UNIFIED IDEOGRAPH + {0xF8AF, 0x705D}, //13267 #CJK UNIFIED IDEOGRAPH + {0xF8B0, 0x7060}, //13268 #CJK UNIFIED IDEOGRAPH + {0xF8B1, 0x7223}, //13269 #CJK UNIFIED IDEOGRAPH + {0xF8B2, 0x74DB}, //13270 #CJK UNIFIED IDEOGRAPH + {0xF8B3, 0x74E5}, //13271 #CJK UNIFIED IDEOGRAPH + {0xF8B4, 0x77D5}, //13272 #CJK UNIFIED IDEOGRAPH + {0xF8B5, 0x7938}, //13273 #CJK UNIFIED IDEOGRAPH + {0xF8B6, 0x79B7}, //13274 #CJK UNIFIED IDEOGRAPH + {0xF8B7, 0x79B6}, //13275 #CJK UNIFIED IDEOGRAPH + {0xF8B8, 0x7C6A}, //13276 #CJK UNIFIED IDEOGRAPH + {0xF8B9, 0x7E97}, //13277 #CJK UNIFIED IDEOGRAPH + {0xF8BA, 0x7F89}, //13278 #CJK UNIFIED IDEOGRAPH + {0xF8BB, 0x826D}, //13279 #CJK UNIFIED IDEOGRAPH + {0xF8BC, 0x8643}, //13280 #CJK UNIFIED IDEOGRAPH + {0xF8BD, 0x8838}, //13281 #CJK UNIFIED IDEOGRAPH + {0xF8BE, 0x8837}, //13282 #CJK UNIFIED IDEOGRAPH + {0xF8BF, 0x8835}, //13283 #CJK UNIFIED IDEOGRAPH + {0xF8C0, 0x884B}, //13284 #CJK UNIFIED IDEOGRAPH + {0xF8C1, 0x8B94}, //13285 #CJK UNIFIED IDEOGRAPH + {0xF8C2, 0x8B95}, //13286 #CJK UNIFIED IDEOGRAPH + {0xF8C3, 0x8E9E}, //13287 #CJK UNIFIED IDEOGRAPH + {0xF8C4, 0x8E9F}, //13288 #CJK UNIFIED IDEOGRAPH + {0xF8C5, 0x8EA0}, //13289 #CJK UNIFIED IDEOGRAPH + {0xF8C6, 0x8E9D}, //13290 #CJK UNIFIED IDEOGRAPH + {0xF8C7, 0x91BE}, //13291 #CJK UNIFIED IDEOGRAPH + {0xF8C8, 0x91BD}, //13292 #CJK UNIFIED IDEOGRAPH + {0xF8C9, 0x91C2}, //13293 #CJK UNIFIED IDEOGRAPH + {0xF8CA, 0x946B}, //13294 #CJK UNIFIED IDEOGRAPH + {0xF8CB, 0x9468}, //13295 #CJK UNIFIED IDEOGRAPH + {0xF8CC, 0x9469}, //13296 #CJK UNIFIED IDEOGRAPH + {0xF8CD, 0x96E5}, //13297 #CJK UNIFIED IDEOGRAPH + {0xF8CE, 0x9746}, //13298 #CJK UNIFIED IDEOGRAPH + {0xF8CF, 0x9743}, //13299 #CJK UNIFIED IDEOGRAPH + {0xF8D0, 0x9747}, //13300 #CJK UNIFIED IDEOGRAPH + {0xF8D1, 0x97C7}, //13301 #CJK UNIFIED IDEOGRAPH + {0xF8D2, 0x97E5}, //13302 #CJK UNIFIED IDEOGRAPH + {0xF8D3, 0x9A5E}, //13303 #CJK UNIFIED IDEOGRAPH + {0xF8D4, 0x9AD5}, //13304 #CJK UNIFIED IDEOGRAPH + {0xF8D5, 0x9B59}, //13305 #CJK UNIFIED IDEOGRAPH + {0xF8D6, 0x9C63}, //13306 #CJK UNIFIED IDEOGRAPH + {0xF8D7, 0x9C67}, //13307 #CJK UNIFIED IDEOGRAPH + {0xF8D8, 0x9C66}, //13308 #CJK UNIFIED IDEOGRAPH + {0xF8D9, 0x9C62}, //13309 #CJK UNIFIED IDEOGRAPH + {0xF8DA, 0x9C5E}, //13310 #CJK UNIFIED IDEOGRAPH + {0xF8DB, 0x9C60}, //13311 #CJK UNIFIED IDEOGRAPH + {0xF8DC, 0x9E02}, //13312 #CJK UNIFIED IDEOGRAPH + {0xF8DD, 0x9DFE}, //13313 #CJK UNIFIED IDEOGRAPH + {0xF8DE, 0x9E07}, //13314 #CJK UNIFIED IDEOGRAPH + {0xF8DF, 0x9E03}, //13315 #CJK UNIFIED IDEOGRAPH + {0xF8E0, 0x9E06}, //13316 #CJK UNIFIED IDEOGRAPH + {0xF8E1, 0x9E05}, //13317 #CJK UNIFIED IDEOGRAPH + {0xF8E2, 0x9E00}, //13318 #CJK UNIFIED IDEOGRAPH + {0xF8E3, 0x9E01}, //13319 #CJK UNIFIED IDEOGRAPH + {0xF8E4, 0x9E09}, //13320 #CJK UNIFIED IDEOGRAPH + {0xF8E5, 0x9DFF}, //13321 #CJK UNIFIED IDEOGRAPH + {0xF8E6, 0x9DFD}, //13322 #CJK UNIFIED IDEOGRAPH + {0xF8E7, 0x9E04}, //13323 #CJK UNIFIED IDEOGRAPH + {0xF8E8, 0x9EA0}, //13324 #CJK UNIFIED IDEOGRAPH + {0xF8E9, 0x9F1E}, //13325 #CJK UNIFIED IDEOGRAPH + {0xF8EA, 0x9F46}, //13326 #CJK UNIFIED IDEOGRAPH + {0xF8EB, 0x9F74}, //13327 #CJK UNIFIED IDEOGRAPH + {0xF8EC, 0x9F75}, //13328 #CJK UNIFIED IDEOGRAPH + {0xF8ED, 0x9F76}, //13329 #CJK UNIFIED IDEOGRAPH + {0xF8EE, 0x56D4}, //13330 #CJK UNIFIED IDEOGRAPH + {0xF8EF, 0x652E}, //13331 #CJK UNIFIED IDEOGRAPH + {0xF8F0, 0x65B8}, //13332 #CJK UNIFIED IDEOGRAPH + {0xF8F1, 0x6B18}, //13333 #CJK UNIFIED IDEOGRAPH + {0xF8F2, 0x6B19}, //13334 #CJK UNIFIED IDEOGRAPH + {0xF8F3, 0x6B17}, //13335 #CJK UNIFIED IDEOGRAPH + {0xF8F4, 0x6B1A}, //13336 #CJK UNIFIED IDEOGRAPH + {0xF8F5, 0x7062}, //13337 #CJK UNIFIED IDEOGRAPH + {0xF8F6, 0x7226}, //13338 #CJK UNIFIED IDEOGRAPH + {0xF8F7, 0x72AA}, //13339 #CJK UNIFIED IDEOGRAPH + {0xF8F8, 0x77D8}, //13340 #CJK UNIFIED IDEOGRAPH + {0xF8F9, 0x77D9}, //13341 #CJK UNIFIED IDEOGRAPH + {0xF8FA, 0x7939}, //13342 #CJK UNIFIED IDEOGRAPH + {0xF8FB, 0x7C69}, //13343 #CJK UNIFIED IDEOGRAPH + {0xF8FC, 0x7C6B}, //13344 #CJK UNIFIED IDEOGRAPH + {0xF8FD, 0x7CF6}, //13345 #CJK UNIFIED IDEOGRAPH + {0xF8FE, 0x7E9A}, //13346 #CJK UNIFIED IDEOGRAPH + {0xF940, 0x7E98}, //13347 #CJK UNIFIED IDEOGRAPH + {0xF941, 0x7E9B}, //13348 #CJK UNIFIED IDEOGRAPH + {0xF942, 0x7E99}, //13349 #CJK UNIFIED IDEOGRAPH + {0xF943, 0x81E0}, //13350 #CJK UNIFIED IDEOGRAPH + {0xF944, 0x81E1}, //13351 #CJK UNIFIED IDEOGRAPH + {0xF945, 0x8646}, //13352 #CJK UNIFIED IDEOGRAPH + {0xF946, 0x8647}, //13353 #CJK UNIFIED IDEOGRAPH + {0xF947, 0x8648}, //13354 #CJK UNIFIED IDEOGRAPH + {0xF948, 0x8979}, //13355 #CJK UNIFIED IDEOGRAPH + {0xF949, 0x897A}, //13356 #CJK UNIFIED IDEOGRAPH + {0xF94A, 0x897C}, //13357 #CJK UNIFIED IDEOGRAPH + {0xF94B, 0x897B}, //13358 #CJK UNIFIED IDEOGRAPH + {0xF94C, 0x89FF}, //13359 #CJK UNIFIED IDEOGRAPH + {0xF94D, 0x8B98}, //13360 #CJK UNIFIED IDEOGRAPH + {0xF94E, 0x8B99}, //13361 #CJK UNIFIED IDEOGRAPH + {0xF94F, 0x8EA5}, //13362 #CJK UNIFIED IDEOGRAPH + {0xF950, 0x8EA4}, //13363 #CJK UNIFIED IDEOGRAPH + {0xF951, 0x8EA3}, //13364 #CJK UNIFIED IDEOGRAPH + {0xF952, 0x946E}, //13365 #CJK UNIFIED IDEOGRAPH + {0xF953, 0x946D}, //13366 #CJK UNIFIED IDEOGRAPH + {0xF954, 0x946F}, //13367 #CJK UNIFIED IDEOGRAPH + {0xF955, 0x9471}, //13368 #CJK UNIFIED IDEOGRAPH + {0xF956, 0x9473}, //13369 #CJK UNIFIED IDEOGRAPH + {0xF957, 0x9749}, //13370 #CJK UNIFIED IDEOGRAPH + {0xF958, 0x9872}, //13371 #CJK UNIFIED IDEOGRAPH + {0xF959, 0x995F}, //13372 #CJK UNIFIED IDEOGRAPH + {0xF95A, 0x9C68}, //13373 #CJK UNIFIED IDEOGRAPH + {0xF95B, 0x9C6E}, //13374 #CJK UNIFIED IDEOGRAPH + {0xF95C, 0x9C6D}, //13375 #CJK UNIFIED IDEOGRAPH + {0xF95D, 0x9E0B}, //13376 #CJK UNIFIED IDEOGRAPH + {0xF95E, 0x9E0D}, //13377 #CJK UNIFIED IDEOGRAPH + {0xF95F, 0x9E10}, //13378 #CJK UNIFIED IDEOGRAPH + {0xF960, 0x9E0F}, //13379 #CJK UNIFIED IDEOGRAPH + {0xF961, 0x9E12}, //13380 #CJK UNIFIED IDEOGRAPH + {0xF962, 0x9E11}, //13381 #CJK UNIFIED IDEOGRAPH + {0xF963, 0x9EA1}, //13382 #CJK UNIFIED IDEOGRAPH + {0xF964, 0x9EF5}, //13383 #CJK UNIFIED IDEOGRAPH + {0xF965, 0x9F09}, //13384 #CJK UNIFIED IDEOGRAPH + {0xF966, 0x9F47}, //13385 #CJK UNIFIED IDEOGRAPH + {0xF967, 0x9F78}, //13386 #CJK UNIFIED IDEOGRAPH + {0xF968, 0x9F7B}, //13387 #CJK UNIFIED IDEOGRAPH + {0xF969, 0x9F7A}, //13388 #CJK UNIFIED IDEOGRAPH + {0xF96A, 0x9F79}, //13389 #CJK UNIFIED IDEOGRAPH + {0xF96B, 0x571E}, //13390 #CJK UNIFIED IDEOGRAPH + {0xF96C, 0x7066}, //13391 #CJK UNIFIED IDEOGRAPH + {0xF96D, 0x7C6F}, //13392 #CJK UNIFIED IDEOGRAPH + {0xF96E, 0x883C}, //13393 #CJK UNIFIED IDEOGRAPH + {0xF96F, 0x8DB2}, //13394 #CJK UNIFIED IDEOGRAPH + {0xF970, 0x8EA6}, //13395 #CJK UNIFIED IDEOGRAPH + {0xF971, 0x91C3}, //13396 #CJK UNIFIED IDEOGRAPH + {0xF972, 0x9474}, //13397 #CJK UNIFIED IDEOGRAPH + {0xF973, 0x9478}, //13398 #CJK UNIFIED IDEOGRAPH + {0xF974, 0x9476}, //13399 #CJK UNIFIED IDEOGRAPH + {0xF975, 0x9475}, //13400 #CJK UNIFIED IDEOGRAPH + {0xF976, 0x9A60}, //13401 #CJK UNIFIED IDEOGRAPH + {0xF977, 0x9C74}, //13402 #CJK UNIFIED IDEOGRAPH + {0xF978, 0x9C73}, //13403 #CJK UNIFIED IDEOGRAPH + {0xF979, 0x9C71}, //13404 #CJK UNIFIED IDEOGRAPH + {0xF97A, 0x9C75}, //13405 #CJK UNIFIED IDEOGRAPH + {0xF97B, 0x9E14}, //13406 #CJK UNIFIED IDEOGRAPH + {0xF97C, 0x9E13}, //13407 #CJK UNIFIED IDEOGRAPH + {0xF97D, 0x9EF6}, //13408 #CJK UNIFIED IDEOGRAPH + {0xF97E, 0x9F0A}, //13409 #CJK UNIFIED IDEOGRAPH + {0xF9A1, 0x9FA4}, //13410 #CJK UNIFIED IDEOGRAPH + {0xF9A2, 0x7068}, //13411 #CJK UNIFIED IDEOGRAPH + {0xF9A3, 0x7065}, //13412 #CJK UNIFIED IDEOGRAPH + {0xF9A4, 0x7CF7}, //13413 #CJK UNIFIED IDEOGRAPH + {0xF9A5, 0x866A}, //13414 #CJK UNIFIED IDEOGRAPH + {0xF9A6, 0x883E}, //13415 #CJK UNIFIED IDEOGRAPH + {0xF9A7, 0x883D}, //13416 #CJK UNIFIED IDEOGRAPH + {0xF9A8, 0x883F}, //13417 #CJK UNIFIED IDEOGRAPH + {0xF9A9, 0x8B9E}, //13418 #CJK UNIFIED IDEOGRAPH + {0xF9AA, 0x8C9C}, //13419 #CJK UNIFIED IDEOGRAPH + {0xF9AB, 0x8EA9}, //13420 #CJK UNIFIED IDEOGRAPH + {0xF9AC, 0x8EC9}, //13421 #CJK UNIFIED IDEOGRAPH + {0xF9AD, 0x974B}, //13422 #CJK UNIFIED IDEOGRAPH + {0xF9AE, 0x9873}, //13423 #CJK UNIFIED IDEOGRAPH + {0xF9AF, 0x9874}, //13424 #CJK UNIFIED IDEOGRAPH + {0xF9B0, 0x98CC}, //13425 #CJK UNIFIED IDEOGRAPH + {0xF9B1, 0x9961}, //13426 #CJK UNIFIED IDEOGRAPH + {0xF9B2, 0x99AB}, //13427 #CJK UNIFIED IDEOGRAPH + {0xF9B3, 0x9A64}, //13428 #CJK UNIFIED IDEOGRAPH + {0xF9B4, 0x9A66}, //13429 #CJK UNIFIED IDEOGRAPH + {0xF9B5, 0x9A67}, //13430 #CJK UNIFIED IDEOGRAPH + {0xF9B6, 0x9B24}, //13431 #CJK UNIFIED IDEOGRAPH + {0xF9B7, 0x9E15}, //13432 #CJK UNIFIED IDEOGRAPH + {0xF9B8, 0x9E17}, //13433 #CJK UNIFIED IDEOGRAPH + {0xF9B9, 0x9F48}, //13434 #CJK UNIFIED IDEOGRAPH + {0xF9BA, 0x6207}, //13435 #CJK UNIFIED IDEOGRAPH + {0xF9BB, 0x6B1E}, //13436 #CJK UNIFIED IDEOGRAPH + {0xF9BC, 0x7227}, //13437 #CJK UNIFIED IDEOGRAPH + {0xF9BD, 0x864C}, //13438 #CJK UNIFIED IDEOGRAPH + {0xF9BE, 0x8EA8}, //13439 #CJK UNIFIED IDEOGRAPH + {0xF9BF, 0x9482}, //13440 #CJK UNIFIED IDEOGRAPH + {0xF9C0, 0x9480}, //13441 #CJK UNIFIED IDEOGRAPH + {0xF9C1, 0x9481}, //13442 #CJK UNIFIED IDEOGRAPH + {0xF9C2, 0x9A69}, //13443 #CJK UNIFIED IDEOGRAPH + {0xF9C3, 0x9A68}, //13444 #CJK UNIFIED IDEOGRAPH + {0xF9C4, 0x9B2E}, //13445 #CJK UNIFIED IDEOGRAPH + {0xF9C5, 0x9E19}, //13446 #CJK UNIFIED IDEOGRAPH + {0xF9C6, 0x7229}, //13447 #CJK UNIFIED IDEOGRAPH + {0xF9C7, 0x864B}, //13448 #CJK UNIFIED IDEOGRAPH + {0xF9C8, 0x8B9F}, //13449 #CJK UNIFIED IDEOGRAPH + {0xF9C9, 0x9483}, //13450 #CJK UNIFIED IDEOGRAPH + {0xF9CA, 0x9C79}, //13451 #CJK UNIFIED IDEOGRAPH + {0xF9CB, 0x9EB7}, //13452 #CJK UNIFIED IDEOGRAPH + {0xF9CC, 0x7675}, //13453 #CJK UNIFIED IDEOGRAPH + {0xF9CD, 0x9A6B}, //13454 #CJK UNIFIED IDEOGRAPH + {0xF9CE, 0x9C7A}, //13455 #CJK UNIFIED IDEOGRAPH + {0xF9CF, 0x9E1D}, //13456 #CJK UNIFIED IDEOGRAPH + {0xF9D0, 0x7069}, //13457 #CJK UNIFIED IDEOGRAPH + {0xF9D1, 0x706A}, //13458 #CJK UNIFIED IDEOGRAPH + {0xF9D2, 0x9EA4}, //13459 #CJK UNIFIED IDEOGRAPH + {0xF9D3, 0x9F7E}, //13460 #CJK UNIFIED IDEOGRAPH + {0xF9D4, 0x9F49}, //13461 #CJK UNIFIED IDEOGRAPH + {0xF9D5, 0x9F98}, //13462 #CJK UNIFIED IDEOGRAPH + {0xF9D6, 0x7881}, //13463 #CJK UNIFIED IDEOGRAPH + {0xF9D7, 0x92B9}, //13464 #CJK UNIFIED IDEOGRAPH + {0xF9D8, 0x88CF}, //13465 #CJK UNIFIED IDEOGRAPH + {0xF9D9, 0x58BB}, //13466 #CJK UNIFIED IDEOGRAPH + {0xF9DA, 0x6052}, //13467 #CJK UNIFIED IDEOGRAPH + {0xF9DB, 0x7CA7}, //13468 #CJK UNIFIED IDEOGRAPH + {0xF9DC, 0x5AFA}, //13469 #CJK UNIFIED IDEOGRAPH + {0xF9DD, 0x2554}, //13470 #BOX DRAWINGS DOUBLE DOWN AND RIGHT + {0xF9DE, 0x2566}, //13471 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + {0xF9DF, 0x2557}, //13472 #BOX DRAWINGS DOUBLE DOWN AND LEFT + {0xF9E0, 0x2560}, //13473 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + {0xF9E1, 0x256C}, //13474 #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + {0xF9E2, 0x2563}, //13475 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT + {0xF9E3, 0x255A}, //13476 #BOX DRAWINGS DOUBLE UP AND RIGHT + {0xF9E4, 0x2569}, //13477 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL + {0xF9E5, 0x255D}, //13478 #BOX DRAWINGS DOUBLE UP AND LEFT + {0xF9E6, 0x2552}, //13479 #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + {0xF9E7, 0x2564}, //13480 #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + {0xF9E8, 0x2555}, //13481 #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + {0xF9E9, 0x255E}, //13482 #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + {0xF9EA, 0x256A}, //13483 #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + {0xF9EB, 0x2561}, //13484 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + {0xF9EC, 0x2558}, //13485 #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + {0xF9ED, 0x2567}, //13486 #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + {0xF9EE, 0x255B}, //13487 #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + {0xF9EF, 0x2553}, //13488 #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + {0xF9F0, 0x2565}, //13489 #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + {0xF9F1, 0x2556}, //13490 #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + {0xF9F2, 0x255F}, //13491 #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + {0xF9F3, 0x256B}, //13492 #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + {0xF9F4, 0x2562}, //13493 #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + {0xF9F5, 0x2559}, //13494 #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + {0xF9F6, 0x2568}, //13495 #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + {0xF9F7, 0x255C}, //13496 #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + {0xF9F8, 0x2551}, //13497 #BOX DRAWINGS DOUBLE VERTICAL + {0xF9F9, 0x2550}, //13498 #BOX DRAWINGS DOUBLE HORIZONTAL + {0xF9FA, 0x256D}, //13499 #BOX DRAWINGS LIGHT ARC DOWN AND RIGHT + {0xF9FB, 0x256E}, //13500 #BOX DRAWINGS LIGHT ARC DOWN AND LEFT + {0xF9FC, 0x2570}, //13501 #BOX DRAWINGS LIGHT ARC UP AND RIGHT + {0xF9FD, 0x256F}, //13502 #BOX DRAWINGS LIGHT ARC UP AND LEFT + {0xF9FE, 0x2593}, //13503 #DARK SHADE +}; + +#endif // DRW_CPTABLE950_H diff --git a/extlib/libdxfrw/intern/drw_cptables.h b/extlib/libdxfrw/intern/drw_cptables.h new file mode 100644 index 0000000..7217743 --- /dev/null +++ b/extlib/libdxfrw/intern/drw_cptables.h @@ -0,0 +1,1330 @@ +#ifndef DRW_CPTABLES_H +#define DRW_CPTABLES_H + +//first entry in all tables are 0x80 +#define CPOFFSET 0x80 +#define CPLENGTHCOMMON 128 + +//Table 874 +static const int DRW_Table874[] = { + 0x20AC, //1 #EURO SIGN + 0x00 , //2 #UNDEFINED + 0x00 , //3 #UNDEFINED + 0x00 , //4 #UNDEFINED + 0x00 , //5 #UNDEFINED + 0x2026, //6 #HORIZONTAL ELLIPSIS + 0x00 , //7 #UNDEFINED + 0x00 , //8 #UNDEFINED + 0x00 , //9 #UNDEFINED + 0x00 , //10 #UNDEFINED + 0x00 , //11 #UNDEFINED + 0x00 , //12 #UNDEFINED + 0x00 , //13 #UNDEFINED + 0x00 , //14 #UNDEFINED + 0x00 , //15 #UNDEFINED + 0x00 , //16 #UNDEFINED + 0x00 , //17 #UNDEFINED + 0x2018, //18 #LEFT SINGLE QUOTATION MARK + 0x2019, //19 #RIGHT SINGLE QUOTATION MARK + 0x201C, //20 #LEFT DOUBLE QUOTATION MARK + 0x201D, //21 #RIGHT DOUBLE QUOTATION MARK + 0x2022, //22 #BULLET + 0x2013, //23 #EN DASH + 0x2014, //24 #EM DASH + 0x00 , //25 #UNDEFINED + 0x00 , //26 #UNDEFINED + 0x00 , //27 #UNDEFINED + 0x00 , //28 #UNDEFINED + 0x00 , //29 #UNDEFINED + 0x00 , //30 #UNDEFINED + 0x00 , //31 #UNDEFINED + 0x00 , //32 #UNDEFINED + 0x00A0, //33 #NO-BREAK SPACE + 0x0E01, //34 #THAI CHARACTER KO KAI + 0x0E02, //35 #THAI CHARACTER KHO KHAI + 0x0E03, //36 #THAI CHARACTER KHO KHUAT + 0x0E04, //37 #THAI CHARACTER KHO KHWAI + 0x0E05, //38 #THAI CHARACTER KHO KHON + 0x0E06, //39 #THAI CHARACTER KHO RAKHANG + 0x0E07, //40 #THAI CHARACTER NGO NGU + 0x0E08, //41 #THAI CHARACTER CHO CHAN + 0x0E09, //42 #THAI CHARACTER CHO CHING + 0x0E0A, //43 #THAI CHARACTER CHO CHANG + 0x0E0B, //44 #THAI CHARACTER SO SO + 0x0E0C, //45 #THAI CHARACTER CHO CHOE + 0x0E0D, //46 #THAI CHARACTER YO YING + 0x0E0E, //47 #THAI CHARACTER DO CHADA + 0x0E0F, //48 #THAI CHARACTER TO PATAK + 0x0E10, //49 #THAI CHARACTER THO THAN + 0x0E11, //50 #THAI CHARACTER THO NANGMONTHO + 0x0E12, //51 #THAI CHARACTER THO PHUTHAO + 0x0E13, //52 #THAI CHARACTER NO NEN + 0x0E14, //53 #THAI CHARACTER DO DEK + 0x0E15, //54 #THAI CHARACTER TO TAO + 0x0E16, //55 #THAI CHARACTER THO THUNG + 0x0E17, //56 #THAI CHARACTER THO THAHAN + 0x0E18, //57 #THAI CHARACTER THO THONG + 0x0E19, //58 #THAI CHARACTER NO NU + 0x0E1A, //59 #THAI CHARACTER BO BAIMAI + 0x0E1B, //60 #THAI CHARACTER PO PLA + 0x0E1C, //61 #THAI CHARACTER PHO PHUNG + 0x0E1D, //62 #THAI CHARACTER FO FA + 0x0E1E, //63 #THAI CHARACTER PHO PHAN + 0x0E1F, //64 #THAI CHARACTER FO FAN + 0x0E20, //65 #THAI CHARACTER PHO SAMPHAO + 0x0E21, //66 #THAI CHARACTER MO MA + 0x0E22, //67 #THAI CHARACTER YO YAK + 0x0E23, //68 #THAI CHARACTER RO RUA + 0x0E24, //69 #THAI CHARACTER RU + 0x0E25, //70 #THAI CHARACTER LO LING + 0x0E26, //71 #THAI CHARACTER LU + 0x0E27, //72 #THAI CHARACTER WO WAEN + 0x0E28, //73 #THAI CHARACTER SO SALA + 0x0E29, //74 #THAI CHARACTER SO RUSI + 0x0E2A, //75 #THAI CHARACTER SO SUA + 0x0E2B, //76 #THAI CHARACTER HO HIP + 0x0E2C, //77 #THAI CHARACTER LO CHULA + 0x0E2D, //78 #THAI CHARACTER O ANG + 0x0E2E, //79 #THAI CHARACTER HO NOKHUK + 0x0E2F, //80 #THAI CHARACTER PAIYANNOI + 0x0E30, //81 #THAI CHARACTER SARA A + 0x0E31, //82 #THAI CHARACTER MAI HAN-AKAT + 0x0E32, //83 #THAI CHARACTER SARA AA + 0x0E33, //84 #THAI CHARACTER SARA AM + 0x0E34, //85 #THAI CHARACTER SARA I + 0x0E35, //86 #THAI CHARACTER SARA II + 0x0E36, //87 #THAI CHARACTER SARA UE + 0x0E37, //88 #THAI CHARACTER SARA UEE + 0x0E38, //89 #THAI CHARACTER SARA U + 0x0E39, //90 #THAI CHARACTER SARA UU + 0x0E3A, //91 #THAI CHARACTER PHINTHU + 0x00 , //92 #UNDEFINED + 0x00 , //93 #UNDEFINED + 0x00 , //94 #UNDEFINED + 0x00 , //95 #UNDEFINED + 0x0E3F, //96 #THAI CURRENCY SYMBOL BAHT + 0x0E40, //97 #THAI CHARACTER SARA E + 0x0E41, //98 #THAI CHARACTER SARA AE + 0x0E42, //99 #THAI CHARACTER SARA O + 0x0E43, //100 #THAI CHARACTER SARA AI MAIMUAN + 0x0E44, //101 #THAI CHARACTER SARA AI MAIMALAI + 0x0E45, //102 #THAI CHARACTER LAKKHANGYAO + 0x0E46, //103 #THAI CHARACTER MAIYAMOK + 0x0E47, //104 #THAI CHARACTER MAITAIKHU + 0x0E48, //105 #THAI CHARACTER MAI EK + 0x0E49, //106 #THAI CHARACTER MAI THO + 0x0E4A, //107 #THAI CHARACTER MAI TRI + 0x0E4B, //108 #THAI CHARACTER MAI CHATTAWA + 0x0E4C, //109 #THAI CHARACTER THANTHAKHAT + 0x0E4D, //110 #THAI CHARACTER NIKHAHIT + 0x0E4E, //111 #THAI CHARACTER YAMAKKAN + 0x0E4F, //112 #THAI CHARACTER FONGMAN + 0x0E50, //113 #THAI DIGIT ZERO + 0x0E51, //114 #THAI DIGIT ONE + 0x0E52, //115 #THAI DIGIT TWO + 0x0E53, //116 #THAI DIGIT THREE + 0x0E54, //117 #THAI DIGIT FOUR + 0x0E55, //118 #THAI DIGIT FIVE + 0x0E56, //119 #THAI DIGIT SIX + 0x0E57, //120 #THAI DIGIT SEVEN + 0x0E58, //121 #THAI DIGIT EIGHT + 0x0E59, //122 #THAI DIGIT NINE + 0x0E5A, //123 #THAI CHARACTER ANGKHANKHU + 0x0E5B, //124 #THAI CHARACTER KHOMUT + 0x00 , //125 #UNDEFINED + 0x00 , //126 #UNDEFINED + 0x00 , //127 #UNDEFINED + 0x00 //128 #UNDEFINED +}; + +//Table 1250 +static const int DRW_Table1250[] = { +0x20AC, //1 #EURO SIGN +0x00, //2 #UNDEFINED +0x201A, //3 #SINGLE LOW-9 QUOTATION MARK +0x00, //4 #UNDEFINED +0x201E, //5 #DOUBLE LOW-9 QUOTATION MARK +0x2026, //6 #HORIZONTAL ELLIPSIS +0x2020, //7 #DAGGER +0x2021, //8 #DOUBLE DAGGER +0x00, //9 #UNDEFINED +0x2030, //10 #PER MILLE SIGN +0x0160, //11 #LATIN CAPITAL LETTER S WITH CARON +0x2039, //12 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK +0x015A, //13 #LATIN CAPITAL LETTER S WITH ACUTE +0x0164, //14 #LATIN CAPITAL LETTER T WITH CARON +0x017D, //15 #LATIN CAPITAL LETTER Z WITH CARON +0x0179, //16 #LATIN CAPITAL LETTER Z WITH ACUTE +0x00, //17 #UNDEFINED +0x2018, //18 #LEFT SINGLE QUOTATION MARK +0x2019, //19 #RIGHT SINGLE QUOTATION MARK +0x201C, //20 #LEFT DOUBLE QUOTATION MARK +0x201D, //21 #RIGHT DOUBLE QUOTATION MARK +0x2022, //22 #BULLET +0x2013, //23 #EN DASH +0x2014, //24 #EM DASH +0x00, //25 #UNDEFINED +0x2122, //26 #TRADE MARK SIGN +0x0161, //27 #LATIN SMALL LETTER S WITH CARON +0x203A, //28 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +0x015B, //29 #LATIN SMALL LETTER S WITH ACUTE +0x0165, //30 #LATIN SMALL LETTER T WITH CARON +0x017E, //31 #LATIN SMALL LETTER Z WITH CARON +0x017A, //32 #LATIN SMALL LETTER Z WITH ACUTE +0x00A0, //33 #NO-BREAK SPACE +0x02C7, //34 #CARON +0x02D8, //35 #BREVE +0x0141, //36 #LATIN CAPITAL LETTER L WITH STROKE +0x00A4, //37 #CURRENCY SIGN +0x0104, //38 #LATIN CAPITAL LETTER A WITH OGONEK +0x00A6, //39 #BROKEN BAR +0x00A7, //40 #SECTION SIGN +0x00A8, //41 #DIAERESIS +0x00A9, //42 #COPYRIGHT SIGN +0x015E, //43 #LATIN CAPITAL LETTER S WITH CEDILLA +0x00AB, //44 #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +0x00AC, //45 #NOT SIGN +0x00AD, //46 #SOFT HYPHEN +0x00AE, //47 #REGISTERED SIGN +0x017B, //48 #LATIN CAPITAL LETTER Z WITH DOT ABOVE +0x00B0, //49 #DEGREE SIGN +0x00B1, //50 #PLUS-MINUS SIGN +0x02DB, //51 #OGONEK +0x0142, //52 #LATIN SMALL LETTER L WITH STROKE +0x00B4, //53 #ACUTE ACCENT +0x00B5, //54 #MICRO SIGN +0x00B6, //55 #PILCROW SIGN +0x00B7, //56 #MIDDLE DOT +0x00B8, //57 #CEDILLA +0x0105, //58 #LATIN SMALL LETTER A WITH OGONEK +0x015F, //59 #LATIN SMALL LETTER S WITH CEDILLA +0x00BB, //60 #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +0x013D, //61 #LATIN CAPITAL LETTER L WITH CARON +0x02DD, //62 #DOUBLE ACUTE ACCENT +0x013E, //63 #LATIN SMALL LETTER L WITH CARON +0x017C, //64 #LATIN SMALL LETTER Z WITH DOT ABOVE +0x0154, //65 #LATIN CAPITAL LETTER R WITH ACUTE +0x00C1, //66 #LATIN CAPITAL LETTER A WITH ACUTE +0x00C2, //67 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX +0x0102, //68 #LATIN CAPITAL LETTER A WITH BREVE +0x00C4, //69 #LATIN CAPITAL LETTER A WITH DIAERESIS +0x0139, //70 #LATIN CAPITAL LETTER L WITH ACUTE +0x0106, //71 #LATIN CAPITAL LETTER C WITH ACUTE +0x00C7, //72 #LATIN CAPITAL LETTER C WITH CEDILLA +0x010C, //73 #LATIN CAPITAL LETTER C WITH CARON +0x00C9, //74 #LATIN CAPITAL LETTER E WITH ACUTE +0x0118, //75 #LATIN CAPITAL LETTER E WITH OGONEK +0x00CB, //76 #LATIN CAPITAL LETTER E WITH DIAERESIS +0x011A, //77 #LATIN CAPITAL LETTER E WITH CARON +0x00CD, //78 #LATIN CAPITAL LETTER I WITH ACUTE +0x00CE, //79 #LATIN CAPITAL LETTER I WITH CIRCUMFLEX +0x010E, //80 #LATIN CAPITAL LETTER D WITH CARON +0x0110, //81 #LATIN CAPITAL LETTER D WITH STROKE +0x0143, //82 #LATIN CAPITAL LETTER N WITH ACUTE +0x0147, //83 #LATIN CAPITAL LETTER N WITH CARON +0x00D3, //84 #LATIN CAPITAL LETTER O WITH ACUTE +0x00D4, //85 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX +0x0150, //86 #LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0x00D6, //87 #LATIN CAPITAL LETTER O WITH DIAERESIS +0x00D7, //88 #MULTIPLICATION SIGN +0x0158, //89 #LATIN CAPITAL LETTER R WITH CARON +0x016E, //90 #LATIN CAPITAL LETTER U WITH RING ABOVE +0x00DA, //91 #LATIN CAPITAL LETTER U WITH ACUTE +0x0170, //92 #LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0x00DC, //93 #LATIN CAPITAL LETTER U WITH DIAERESIS +0x00DD, //94 #LATIN CAPITAL LETTER Y WITH ACUTE +0x0162, //95 #LATIN CAPITAL LETTER T WITH CEDILLA +0x00DF, //96 #LATIN SMALL LETTER SHARP S +0x0155, //97 #LATIN SMALL LETTER R WITH ACUTE +0x00E1, //98 #LATIN SMALL LETTER A WITH ACUTE +0x00E2, //99 #LATIN SMALL LETTER A WITH CIRCUMFLEX +0x0103, //100 #LATIN SMALL LETTER A WITH BREVE +0x00E4, //101 #LATIN SMALL LETTER A WITH DIAERESIS +0x013A, //102 #LATIN SMALL LETTER L WITH ACUTE +0x0107, //103 #LATIN SMALL LETTER C WITH ACUTE +0x00E7, //104 #LATIN SMALL LETTER C WITH CEDILLA +0x010D, //105 #LATIN SMALL LETTER C WITH CARON +0x00E9, //106 #LATIN SMALL LETTER E WITH ACUTE +0x0119, //107 #LATIN SMALL LETTER E WITH OGONEK +0x00EB, //108 #LATIN SMALL LETTER E WITH DIAERESIS +0x011B, //109 #LATIN SMALL LETTER E WITH CARON +0x00ED, //110 #LATIN SMALL LETTER I WITH ACUTE +0x00EE, //111 #LATIN SMALL LETTER I WITH CIRCUMFLEX +0x010F, //112 #LATIN SMALL LETTER D WITH CARON +0x0111, //113 #LATIN SMALL LETTER D WITH STROKE +0x0144, //114 #LATIN SMALL LETTER N WITH ACUTE +0x0148, //115 #LATIN SMALL LETTER N WITH CARON +0x00F3, //116 #LATIN SMALL LETTER O WITH ACUTE +0x00F4, //117 #LATIN SMALL LETTER O WITH CIRCUMFLEX +0x0151, //118 #LATIN SMALL LETTER O WITH DOUBLE ACUTE +0x00F6, //119 #LATIN SMALL LETTER O WITH DIAERESIS +0x00F7, //120 #DIVISION SIGN +0x0159, //121 #LATIN SMALL LETTER R WITH CARON +0x016F, //122 #LATIN SMALL LETTER U WITH RING ABOVE +0x00FA, //123 #LATIN SMALL LETTER U WITH ACUTE +0x0171, //124 #LATIN SMALL LETTER U WITH DOUBLE ACUTE +0x00FC, //125 #LATIN SMALL LETTER U WITH DIAERESIS +0x00FD, //126 #LATIN SMALL LETTER Y WITH ACUTE +0x0163, //127 #LATIN SMALL LETTER T WITH CEDILLA +0x02D9 //128 #DOT ABOVE +}; + + +//Table 1251 +static const int DRW_Table1251[] = { + 0x0402, //1 #CYRILLIC CAPITAL LETTER DJE + 0x0403, //2 #CYRILLIC CAPITAL LETTER GJE + 0x201A, //3 #SINGLE LOW-9 QUOTATION MARK + 0x0453, //4 #CYRILLIC SMALL LETTER GJE + 0x201E, //5 #DOUBLE LOW-9 QUOTATION MARK + 0x2026, //6 #HORIZONTAL ELLIPSIS + 0x2020, //7 #DAGGER + 0x2021, //8 #DOUBLE DAGGER + 0x20AC, //9 #EURO SIGN + 0x2030, //10 #PER MILLE SIGN + 0x0409, //11 #CYRILLIC CAPITAL LETTER LJE + 0x2039, //12 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 0x040A, //13 #CYRILLIC CAPITAL LETTER NJE + 0x040C, //14 #CYRILLIC CAPITAL LETTER KJE + 0x040B, //15 #CYRILLIC CAPITAL LETTER TSHE + 0x040F, //16 #CYRILLIC CAPITAL LETTER DZHE + 0x0452, //17 #CYRILLIC SMALL LETTER DJE + 0x2018, //18 #LEFT SINGLE QUOTATION MARK + 0x2019, //19 #RIGHT SINGLE QUOTATION MARK + 0x201C, //20 #LEFT DOUBLE QUOTATION MARK + 0x201D, //21 #RIGHT DOUBLE QUOTATION MARK + 0x2022, //22 #BULLET + 0x2013, //23 #EN DASH + 0x2014, //24 #EM DASH + 0x00, //25 #UNDEFINED + 0x2122, //26 #TRADE MARK SIGN + 0x0459, //27 #CYRILLIC SMALL LETTER LJE + 0x203A, //28 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 0x045A, //29 #CYRILLIC SMALL LETTER NJE + 0x045C, //30 #CYRILLIC SMALL LETTER KJE + 0x045B, //31 #CYRILLIC SMALL LETTER TSHE + 0x045F, //32 #CYRILLIC SMALL LETTER DZHE + 0x00A0, //33 #NO-BREAK SPACE + 0x040E, //34 #CYRILLIC CAPITAL LETTER SHORT U + 0x045E, //35 #CYRILLIC SMALL LETTER SHORT U + 0x0408, //36 #CYRILLIC CAPITAL LETTER JE + 0x00A4, //37 #CURRENCY SIGN + 0x0490, //38 #CYRILLIC CAPITAL LETTER GHE WITH UPTURN + 0x00A6, //39 #BROKEN BAR + 0x00A7, //40 #SECTION SIGN + 0x0401, //41 #CYRILLIC CAPITAL LETTER IO + 0x00A9, //42 #COPYRIGHT SIGN + 0x0404, //43 #CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x00AB, //44 #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00AC, //45 #NOT SIGN + 0x00AD, //46 #SOFT HYPHEN + 0x00AE, //47 #REGISTERED SIGN + 0x0407, //48 #CYRILLIC CAPITAL LETTER YI + 0x00B0, //49 #DEGREE SIGN + 0x00B1, //50 #PLUS-MINUS SIGN + 0x0406, //51 #CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + 0x0456, //52 #CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + 0x0491, //53 #CYRILLIC SMALL LETTER GHE WITH UPTURN + 0x00B5, //54 #MICRO SIGN + 0x00B6, //55 #PILCROW SIGN + 0x00B7, //56 #MIDDLE DOT + 0x0451, //57 #CYRILLIC SMALL LETTER IO + 0x2116, //58 #NUMERO SIGN + 0x0454, //59 #CYRILLIC SMALL LETTER UKRAINIAN IE + 0x00BB, //60 #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x0458, //61 #CYRILLIC SMALL LETTER JE + 0x0405, //62 #CYRILLIC CAPITAL LETTER DZE + 0x0455, //63 #CYRILLIC SMALL LETTER DZE + 0x0457, //64 #CYRILLIC SMALL LETTER YI + 0x0410, //65 #CYRILLIC CAPITAL LETTER A + 0x0411, //66 #CYRILLIC CAPITAL LETTER BE + 0x0412, //67 #CYRILLIC CAPITAL LETTER VE + 0x0413, //68 #CYRILLIC CAPITAL LETTER GHE + 0x0414, //69 #CYRILLIC CAPITAL LETTER DE + 0x0415, //70 #CYRILLIC CAPITAL LETTER IE + 0x0416, //71 #CYRILLIC CAPITAL LETTER ZHE + 0x0417, //72 #CYRILLIC CAPITAL LETTER ZE + 0x0418, //73 #CYRILLIC CAPITAL LETTER I + 0x0419, //74 #CYRILLIC CAPITAL LETTER SHORT I + 0x041A, //75 #CYRILLIC CAPITAL LETTER KA + 0x041B, //76 #CYRILLIC CAPITAL LETTER EL + 0x041C, //77 #CYRILLIC CAPITAL LETTER EM + 0x041D, //78 #CYRILLIC CAPITAL LETTER EN + 0x041E, //79 #CYRILLIC CAPITAL LETTER O + 0x041F, //80 #CYRILLIC CAPITAL LETTER PE + 0x0420, //81 #CYRILLIC CAPITAL LETTER ER + 0x0421, //82 #CYRILLIC CAPITAL LETTER ES + 0x0422, //83 #CYRILLIC CAPITAL LETTER TE + 0x0423, //84 #CYRILLIC CAPITAL LETTER U + 0x0424, //85 #CYRILLIC CAPITAL LETTER EF + 0x0425, //86 #CYRILLIC CAPITAL LETTER HA + 0x0426, //87 #CYRILLIC CAPITAL LETTER TSE + 0x0427, //88 #CYRILLIC CAPITAL LETTER CHE + 0x0428, //89 #CYRILLIC CAPITAL LETTER SHA + 0x0429, //90 #CYRILLIC CAPITAL LETTER SHCHA + 0x042A, //91 #CYRILLIC CAPITAL LETTER HARD SIGN + 0x042B, //92 #CYRILLIC CAPITAL LETTER YERU + 0x042C, //93 #CYRILLIC CAPITAL LETTER SOFT SIGN + 0x042D, //94 #CYRILLIC CAPITAL LETTER E + 0x042E, //95 #CYRILLIC CAPITAL LETTER YU + 0x042F, //96 #CYRILLIC CAPITAL LETTER YA + 0x0430, //97 #CYRILLIC SMALL LETTER A + 0x0431, //98 #CYRILLIC SMALL LETTER BE + 0x0432, //99 #CYRILLIC SMALL LETTER VE + 0x0433, //100 #CYRILLIC SMALL LETTER GHE + 0x0434, //101 #CYRILLIC SMALL LETTER DE + 0x0435, //102 #CYRILLIC SMALL LETTER IE + 0x0436, //103 #CYRILLIC SMALL LETTER ZHE + 0x0437, //104 #CYRILLIC SMALL LETTER ZE + 0x0438, //105 #CYRILLIC SMALL LETTER I + 0x0439, //106 #CYRILLIC SMALL LETTER SHORT I + 0x043A, //107 #CYRILLIC SMALL LETTER KA + 0x043B, //108 #CYRILLIC SMALL LETTER EL + 0x043C, //109 #CYRILLIC SMALL LETTER EM + 0x043D, //110 #CYRILLIC SMALL LETTER EN + 0x043E, //111 #CYRILLIC SMALL LETTER O + 0x043F, //112 #CYRILLIC SMALL LETTER PE + 0x0440, //113 #CYRILLIC SMALL LETTER ER + 0x0441, //114 #CYRILLIC SMALL LETTER ES + 0x0442, //115 #CYRILLIC SMALL LETTER TE + 0x0443, //116 #CYRILLIC SMALL LETTER U + 0x0444, //117 #CYRILLIC SMALL LETTER EF + 0x0445, //118 #CYRILLIC SMALL LETTER HA + 0x0446, //119 #CYRILLIC SMALL LETTER TSE + 0x0447, //120 #CYRILLIC SMALL LETTER CHE + 0x0448, //121 #CYRILLIC SMALL LETTER SHA + 0x0449, //122 #CYRILLIC SMALL LETTER SHCHA + 0x044A, //123 #CYRILLIC SMALL LETTER HARD SIGN + 0x044B, //124 #CYRILLIC SMALL LETTER YERU + 0x044C, //125 #CYRILLIC SMALL LETTER SOFT SIGN + 0x044D, //126 #CYRILLIC SMALL LETTER E + 0x044E, //127 #CYRILLIC SMALL LETTER YU + 0x044F //128 #CYRILLIC SMALL LETTER YA +}; + + +//Table 1252 +static const int DRW_Table1252[] = { + 0x20AC, //1 #EURO SIGN + 0x00, //2 #UNDEFINED + 0x201A, //3 #SINGLE LOW-9 QUOTATION MARK + 0x0192, //4 #LATIN SMALL LETTER F WITH HOOK + 0x201E, //5 #DOUBLE LOW-9 QUOTATION MARK + 0x2026, //6 #HORIZONTAL ELLIPSIS + 0x2020, //7 #DAGGER + 0x2021, //8 #DOUBLE DAGGER + 0x02C6, //9 #MODIFIER LETTER CIRCUMFLEX ACCENT + 0x2030, //10 #PER MILLE SIGN + 0x0160, //11 #LATIN CAPITAL LETTER S WITH CARON + 0x2039, //12 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 0x0152, //13 #LATIN CAPITAL LIGATURE OE + 0x00, //14 #UNDEFINED + 0x017D, //15 #LATIN CAPITAL LETTER Z WITH CARON + 0x00, //16 #UNDEFINED + 0x00, //17 #UNDEFINED + 0x2018, //18 #LEFT SINGLE QUOTATION MARK + 0x2019, //19 #RIGHT SINGLE QUOTATION MARK + 0x201C, //20 #LEFT DOUBLE QUOTATION MARK + 0x201D, //21 #RIGHT DOUBLE QUOTATION MARK + 0x2022, //22 #BULLET + 0x2013, //23 #EN DASH + 0x2014, //24 #EM DASH + 0x02DC, //25 #SMALL TILDE + 0x2122, //26 #TRADE MARK SIGN + 0x0161, //27 #LATIN SMALL LETTER S WITH CARON + 0x203A, //28 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 0x0153, //29 #LATIN SMALL LIGATURE OE + 0x00, //30 #UNDEFINED + 0x017E, //31 #LATIN SMALL LETTER Z WITH CARON + 0x0178, //32 #LATIN CAPITAL LETTER Y WITH DIAERESIS + 0x00A0, //33 #NO-BREAK SPACE + 0x00A1, //34 #INVERTED EXCLAMATION MARK + 0x00A2, //35 #CENT SIGN + 0x00A3, //36 #POUND SIGN + 0x00A4, //37 #CURRENCY SIGN + 0x00A5, //38 #YEN SIGN + 0x00A6, //39 #BROKEN BAR + 0x00A7, //40 #SECTION SIGN + 0x00A8, //41 #DIAERESIS + 0x00A9, //42 #COPYRIGHT SIGN + 0x00AA, //43 #FEMININE ORDINAL INDICATOR + 0x00AB, //44 #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00AC, //45 #NOT SIGN + 0x00AD, //46 #SOFT HYPHEN + 0x00AE, //47 #REGISTERED SIGN + 0x00AF, //48 #MACRON + 0x00B0, //49 #DEGREE SIGN + 0x00B1, //50 #PLUS-MINUS SIGN + 0x00B2, //51 #SUPERSCRIPT TWO + 0x00B3, //52 #SUPERSCRIPT THREE + 0x00B4, //53 #ACUTE ACCENT + 0x00B5, //54 #MICRO SIGN + 0x00B6, //55 #PILCROW SIGN + 0x00B7, //56 #MIDDLE DOT + 0x00B8, //57 #CEDILLA + 0x00B9, //58 #SUPERSCRIPT ONE + 0x00BA, //59 #MASCULINE ORDINAL INDICATOR + 0x00BB, //60 #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00BC, //61 #VULGAR FRACTION ONE QUARTER + 0x00BD, //62 #VULGAR FRACTION ONE HALF + 0x00BE, //63 #VULGAR FRACTION THREE QUARTERS + 0x00BF, //64 #INVERTED QUESTION MARK + 0x00C0, //65 #LATIN CAPITAL LETTER A WITH GRAVE + 0x00C1, //66 #LATIN CAPITAL LETTER A WITH ACUTE + 0x00C2, //67 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00C3, //68 #LATIN CAPITAL LETTER A WITH TILDE + 0x00C4, //69 #LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00C5, //70 #LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00C6, //71 #LATIN CAPITAL LETTER AE + 0x00C7, //72 #LATIN CAPITAL LETTER C WITH CEDILLA + 0x00C8, //73 #LATIN CAPITAL LETTER E WITH GRAVE + 0x00C9, //74 #LATIN CAPITAL LETTER E WITH ACUTE + 0x00CA, //75 #LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00CB, //76 #LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00CC, //77 #LATIN CAPITAL LETTER I WITH GRAVE + 0x00CD, //78 #LATIN CAPITAL LETTER I WITH ACUTE + 0x00CE, //79 #LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00CF, //80 #LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00D0, //81 #LATIN CAPITAL LETTER ETH + 0x00D1, //82 #LATIN CAPITAL LETTER N WITH TILDE + 0x00D2, //83 #LATIN CAPITAL LETTER O WITH GRAVE + 0x00D3, //84 #LATIN CAPITAL LETTER O WITH ACUTE + 0x00D4, //85 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00D5, //86 #LATIN CAPITAL LETTER O WITH TILDE + 0x00D6, //87 #LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00D7, //88 #MULTIPLICATION SIGN + 0x00D8, //89 #LATIN CAPITAL LETTER O WITH STROKE + 0x00D9, //90 #LATIN CAPITAL LETTER U WITH GRAVE + 0x00DA, //91 #LATIN CAPITAL LETTER U WITH ACUTE + 0x00DB, //92 #LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00DC, //93 #LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00DD, //94 #LATIN CAPITAL LETTER Y WITH ACUTE + 0x00DE, //95 #LATIN CAPITAL LETTER THORN + 0x00DF, //96 #LATIN SMALL LETTER SHARP S + 0x00E0, //97 #LATIN SMALL LETTER A WITH GRAVE + 0x00E1, //98 #LATIN SMALL LETTER A WITH ACUTE + 0x00E2, //99 #LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00E3, //100 #LATIN SMALL LETTER A WITH TILDE + 0x00E4, //101 #LATIN SMALL LETTER A WITH DIAERESIS + 0x00E5, //102 #LATIN SMALL LETTER A WITH RING ABOVE + 0x00E6, //103 #LATIN SMALL LETTER AE + 0x00E7, //104 #LATIN SMALL LETTER C WITH CEDILLA + 0x00E8, //105 #LATIN SMALL LETTER E WITH GRAVE + 0x00E9, //106 #LATIN SMALL LETTER E WITH ACUTE + 0x00EA, //107 #LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00EB, //108 #LATIN SMALL LETTER E WITH DIAERESIS + 0x00EC, //109 #LATIN SMALL LETTER I WITH GRAVE + 0x00ED, //110 #LATIN SMALL LETTER I WITH ACUTE + 0x00EE, //111 #LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00EF, //112 #LATIN SMALL LETTER I WITH DIAERESIS + 0x00F0, //113 #LATIN SMALL LETTER ETH + 0x00F1, //114 #LATIN SMALL LETTER N WITH TILDE + 0x00F2, //115 #LATIN SMALL LETTER O WITH GRAVE + 0x00F3, //116 #LATIN SMALL LETTER O WITH ACUTE + 0x00F4, //117 #LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00F5, //118 #LATIN SMALL LETTER O WITH TILDE + 0x00F6, //119 #LATIN SMALL LETTER O WITH DIAERESIS + 0x00F7, //120 #DIVISION SIGN + 0x00F8, //121 #LATIN SMALL LETTER O WITH STROKE + 0x00F9, //122 #LATIN SMALL LETTER U WITH GRAVE + 0x00FA, //123 #LATIN SMALL LETTER U WITH ACUTE + 0x00FB, //124 #LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00FC, //125 #LATIN SMALL LETTER U WITH DIAERESIS + 0x00FD, //126 #LATIN SMALL LETTER Y WITH ACUTE + 0x00FE, //127 #LATIN SMALL LETTER THORN + 0x00FF //128 #LATIN SMALL LETTER Y WITH DIAERESIS +}; + +//Table 1253 +static const int DRW_Table1253[] = { + 0x20AC, //1 #EURO SIGN + 0x00 , //2 #UNDEFINED + 0x201A, //3 #SINGLE LOW-9 QUOTATION MARK + 0x0192, //4 #LATIN SMALL LETTER F WITH HOOK + 0x201E, //5 #DOUBLE LOW-9 QUOTATION MARK + 0x2026, //6 #HORIZONTAL ELLIPSIS + 0x2020, //7 #DAGGER + 0x2021, //8 #DOUBLE DAGGER + 0x00 , //9 #UNDEFINED + 0x2030, //10 #PER MILLE SIGN + 0x00 , //11 #UNDEFINED + 0x2039, //12 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 0x00 , //13 #UNDEFINED + 0x00 , //14 #UNDEFINED + 0x00 , //15 #UNDEFINED + 0x00 , //16 #UNDEFINED + 0x00 , //17 #UNDEFINED + 0x2018, //18 #LEFT SINGLE QUOTATION MARK + 0x2019, //19 #RIGHT SINGLE QUOTATION MARK + 0x201C, //20 #LEFT DOUBLE QUOTATION MARK + 0x201D, //21 #RIGHT DOUBLE QUOTATION MARK + 0x2022, //22 #BULLET + 0x2013, //23 #EN DASH + 0x2014, //24 #EM DASH + 0x00 , //25 #UNDEFINED + 0x2122, //26 #TRADE MARK SIGN + 0x00 , //27 #UNDEFINED + 0x203A, //28 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 0x00 , //29 #UNDEFINED + 0x00 , //30 #UNDEFINED + 0x00 , //31 #UNDEFINED + 0x00 , //32 #UNDEFINED + 0x00A0, //33 #NO-BREAK SPACE + 0x0385, //34 #GREEK DIALYTIKA TONOS + 0x0386, //35 #GREEK CAPITAL LETTER ALPHA WITH TONOS + 0x00A3, //36 #POUND SIGN + 0x00A4, //37 #CURRENCY SIGN + 0x00A5, //38 #YEN SIGN + 0x00A6, //39 #BROKEN BAR + 0x00A7, //40 #SECTION SIGN + 0x00A8, //41 #DIAERESIS + 0x00A9, //42 #COPYRIGHT SIGN + 0x00 , //43 #UNDEFINED + 0x00AB, //44 #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00AC, //45 #NOT SIGN + 0x00AD, //46 #SOFT HYPHEN + 0x00AE, //47 #REGISTERED SIGN + 0x2015, //48 #HORIZONTAL BAR + 0x00B0, //49 #DEGREE SIGN + 0x00B1, //50 #PLUS-MINUS SIGN + 0x00B2, //51 #SUPERSCRIPT TWO + 0x00B3, //52 #SUPERSCRIPT THREE + 0x0384, //53 #GREEK TONOS + 0x00B5, //54 #MICRO SIGN + 0x00B6, //55 #PILCROW SIGN + 0x00B7, //56 #MIDDLE DOT + 0x0388, //57 #GREEK CAPITAL LETTER EPSILON WITH TONOS + 0x0389, //58 #GREEK CAPITAL LETTER ETA WITH TONOS + 0x038A, //59 #GREEK CAPITAL LETTER IOTA WITH TONOS + 0x00BB, //60 #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x038C, //61 #GREEK CAPITAL LETTER OMICRON WITH TONOS + 0x00BD, //62 #VULGAR FRACTION ONE HALF + 0x038E, //63 #GREEK CAPITAL LETTER UPSILON WITH TONOS + 0x038F, //64 #GREEK CAPITAL LETTER OMEGA WITH TONOS + 0x0390, //65 #GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + 0x0391, //66 #GREEK CAPITAL LETTER ALPHA + 0x0392, //67 #GREEK CAPITAL LETTER BETA + 0x0393, //68 #GREEK CAPITAL LETTER GAMMA + 0x0394, //69 #GREEK CAPITAL LETTER DELTA + 0x0395, //70 #GREEK CAPITAL LETTER EPSILON + 0x0396, //71 #GREEK CAPITAL LETTER ZETA + 0x0397, //72 #GREEK CAPITAL LETTER ETA + 0x0398, //73 #GREEK CAPITAL LETTER THETA + 0x0399, //74 #GREEK CAPITAL LETTER IOTA + 0x039A, //75 #GREEK CAPITAL LETTER KAPPA + 0x039B, //76 #GREEK CAPITAL LETTER LAMDA + 0x039C, //77 #GREEK CAPITAL LETTER MU + 0x039D, //78 #GREEK CAPITAL LETTER NU + 0x039E, //79 #GREEK CAPITAL LETTER XI + 0x039F, //80 #GREEK CAPITAL LETTER OMICRON + 0x03A0, //81 #GREEK CAPITAL LETTER PI + 0x03A1, //82 #GREEK CAPITAL LETTER RHO + 0x00 , //83 #UNDEFINED + 0x03A3, //84 #GREEK CAPITAL LETTER SIGMA + 0x03A4, //85 #GREEK CAPITAL LETTER TAU + 0x03A5, //86 #GREEK CAPITAL LETTER UPSILON + 0x03A6, //87 #GREEK CAPITAL LETTER PHI + 0x03A7, //88 #GREEK CAPITAL LETTER CHI + 0x03A8, //89 #GREEK CAPITAL LETTER PSI + 0x03A9, //90 #GREEK CAPITAL LETTER OMEGA + 0x03AA, //91 #GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + 0x03AB, //92 #GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + 0x03AC, //93 #GREEK SMALL LETTER ALPHA WITH TONOS + 0x03AD, //94 #GREEK SMALL LETTER EPSILON WITH TONOS + 0x03AE, //95 #GREEK SMALL LETTER ETA WITH TONOS + 0x03AF, //96 #GREEK SMALL LETTER IOTA WITH TONOS + 0x03B0, //97 #GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + 0x03B1, //98 #GREEK SMALL LETTER ALPHA + 0x03B2, //99 #GREEK SMALL LETTER BETA + 0x03B3, //100 #GREEK SMALL LETTER GAMMA + 0x03B4, //101 #GREEK SMALL LETTER DELTA + 0x03B5, //102 #GREEK SMALL LETTER EPSILON + 0x03B6, //103 #GREEK SMALL LETTER ZETA + 0x03B7, //104 #GREEK SMALL LETTER ETA + 0x03B8, //105 #GREEK SMALL LETTER THETA + 0x03B9, //106 #GREEK SMALL LETTER IOTA + 0x03BA, //107 #GREEK SMALL LETTER KAPPA + 0x03BB, //108 #GREEK SMALL LETTER LAMDA + 0x03BC, //109 #GREEK SMALL LETTER MU + 0x03BD, //110 #GREEK SMALL LETTER NU + 0x03BE, //111 #GREEK SMALL LETTER XI + 0x03BF, //112 #GREEK SMALL LETTER OMICRON + 0x03C0, //113 #GREEK SMALL LETTER PI + 0x03C1, //114 #GREEK SMALL LETTER RHO + 0x03C2, //115 #GREEK SMALL LETTER FINAL SIGMA + 0x03C3, //116 #GREEK SMALL LETTER SIGMA + 0x03C4, //117 #GREEK SMALL LETTER TAU + 0x03C5, //118 #GREEK SMALL LETTER UPSILON + 0x03C6, //119 #GREEK SMALL LETTER PHI + 0x03C7, //120 #GREEK SMALL LETTER CHI + 0x03C8, //121 #GREEK SMALL LETTER PSI + 0x03C9, //122 #GREEK SMALL LETTER OMEGA + 0x03CA, //123 #GREEK SMALL LETTER IOTA WITH DIALYTIKA + 0x03CB, //124 #GREEK SMALL LETTER UPSILON WITH DIALYTIKA + 0x03CC, //125 #GREEK SMALL LETTER OMICRON WITH TONOS + 0x03CD, //126 #GREEK SMALL LETTER UPSILON WITH TONOS + 0x03CE, //127 #GREEK SMALL LETTER OMEGA WITH TONOS + 0x00 //128 #UNDEFINED +}; + +//Table 1254 +static const int DRW_Table1254[] = { + 0x20AC, //1 #EURO SIGN + 0x00 , //2 #UNDEFINED + 0x201A, //3 #SINGLE LOW-9 QUOTATION MARK + 0x0192, //4 #LATIN SMALL LETTER F WITH HOOK + 0x201E, //5 #DOUBLE LOW-9 QUOTATION MARK + 0x2026, //6 #HORIZONTAL ELLIPSIS + 0x2020, //7 #DAGGER + 0x2021, //8 #DOUBLE DAGGER + 0x02C6, //9 #MODIFIER LETTER CIRCUMFLEX ACCENT + 0x2030, //10 #PER MILLE SIGN + 0x0160, //11 #LATIN CAPITAL LETTER S WITH CARON + 0x2039, //12 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 0x0152, //13 #LATIN CAPITAL LIGATURE OE + 0x00 , //14 #UNDEFINED + 0x00 , //15 #UNDEFINED + 0x00 , //16 #UNDEFINED + 0x00 , //17 #UNDEFINED + 0x2018, //18 #LEFT SINGLE QUOTATION MARK + 0x2019, //19 #RIGHT SINGLE QUOTATION MARK + 0x201C, //20 #LEFT DOUBLE QUOTATION MARK + 0x201D, //21 #RIGHT DOUBLE QUOTATION MARK + 0x2022, //22 #BULLET + 0x2013, //23 #EN DASH + 0x2014, //24 #EM DASH + 0x02DC, //25 #SMALL TILDE + 0x2122, //26 #TRADE MARK SIGN + 0x0161, //27 #LATIN SMALL LETTER S WITH CARON + 0x203A, //28 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 0x0153, //29 #LATIN SMALL LIGATURE OE + 0x00 , //30 #UNDEFINED + 0x00 , //31 #UNDEFINED + 0x0178, //32 #LATIN CAPITAL LETTER Y WITH DIAERESIS + 0x00A0, //33 #NO-BREAK SPACE + 0x00A1, //34 #INVERTED EXCLAMATION MARK + 0x00A2, //35 #CENT SIGN + 0x00A3, //36 #POUND SIGN + 0x00A4, //37 #CURRENCY SIGN + 0x00A5, //38 #YEN SIGN + 0x00A6, //39 #BROKEN BAR + 0x00A7, //40 #SECTION SIGN + 0x00A8, //41 #DIAERESIS + 0x00A9, //42 #COPYRIGHT SIGN + 0x00AA, //43 #FEMININE ORDINAL INDICATOR + 0x00AB, //44 #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00AC, //45 #NOT SIGN + 0x00AD, //46 #SOFT HYPHEN + 0x00AE, //47 #REGISTERED SIGN + 0x00AF, //48 #MACRON + 0x00B0, //49 #DEGREE SIGN + 0x00B1, //50 #PLUS-MINUS SIGN + 0x00B2, //51 #SUPERSCRIPT TWO + 0x00B3, //52 #SUPERSCRIPT THREE + 0x00B4, //53 #ACUTE ACCENT + 0x00B5, //54 #MICRO SIGN + 0x00B6, //55 #PILCROW SIGN + 0x00B7, //56 #MIDDLE DOT + 0x00B8, //57 #CEDILLA + 0x00B9, //58 #SUPERSCRIPT ONE + 0x00BA, //59 #MASCULINE ORDINAL INDICATOR + 0x00BB, //60 #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00BC, //61 #VULGAR FRACTION ONE QUARTER + 0x00BD, //62 #VULGAR FRACTION ONE HALF + 0x00BE, //63 #VULGAR FRACTION THREE QUARTERS + 0x00BF, //64 #INVERTED QUESTION MARK + 0x00C0, //65 #LATIN CAPITAL LETTER A WITH GRAVE + 0x00C1, //66 #LATIN CAPITAL LETTER A WITH ACUTE + 0x00C2, //67 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00C3, //68 #LATIN CAPITAL LETTER A WITH TILDE + 0x00C4, //69 #LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00C5, //70 #LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00C6, //71 #LATIN CAPITAL LETTER AE + 0x00C7, //72 #LATIN CAPITAL LETTER C WITH CEDILLA + 0x00C8, //73 #LATIN CAPITAL LETTER E WITH GRAVE + 0x00C9, //74 #LATIN CAPITAL LETTER E WITH ACUTE + 0x00CA, //75 #LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00CB, //76 #LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00CC, //77 #LATIN CAPITAL LETTER I WITH GRAVE + 0x00CD, //78 #LATIN CAPITAL LETTER I WITH ACUTE + 0x00CE, //79 #LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00CF, //80 #LATIN CAPITAL LETTER I WITH DIAERESIS + 0x011E, //81 #LATIN CAPITAL LETTER G WITH BREVE + 0x00D1, //82 #LATIN CAPITAL LETTER N WITH TILDE + 0x00D2, //83 #LATIN CAPITAL LETTER O WITH GRAVE + 0x00D3, //84 #LATIN CAPITAL LETTER O WITH ACUTE + 0x00D4, //85 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00D5, //86 #LATIN CAPITAL LETTER O WITH TILDE + 0x00D6, //87 #LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00D7, //88 #MULTIPLICATION SIGN + 0x00D8, //89 #LATIN CAPITAL LETTER O WITH STROKE + 0x00D9, //90 #LATIN CAPITAL LETTER U WITH GRAVE + 0x00DA, //91 #LATIN CAPITAL LETTER U WITH ACUTE + 0x00DB, //92 #LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00DC, //93 #LATIN CAPITAL LETTER U WITH DIAERESIS + 0x0130, //94 #LATIN CAPITAL LETTER I WITH DOT ABOVE + 0x015E, //95 #LATIN CAPITAL LETTER S WITH CEDILLA + 0x00DF, //96 #LATIN SMALL LETTER SHARP S + 0x00E0, //97 #LATIN SMALL LETTER A WITH GRAVE + 0x00E1, //98 #LATIN SMALL LETTER A WITH ACUTE + 0x00E2, //99 #LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00E3, //100 #LATIN SMALL LETTER A WITH TILDE + 0x00E4, //101 #LATIN SMALL LETTER A WITH DIAERESIS + 0x00E5, //102 #LATIN SMALL LETTER A WITH RING ABOVE + 0x00E6, //103 #LATIN SMALL LETTER AE + 0x00E7, //104 #LATIN SMALL LETTER C WITH CEDILLA + 0x00E8, //105 #LATIN SMALL LETTER E WITH GRAVE + 0x00E9, //106 #LATIN SMALL LETTER E WITH ACUTE + 0x00EA, //107 #LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00EB, //108 #LATIN SMALL LETTER E WITH DIAERESIS + 0x00EC, //109 #LATIN SMALL LETTER I WITH GRAVE + 0x00ED, //110 #LATIN SMALL LETTER I WITH ACUTE + 0x00EE, //111 #LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00EF, //112 #LATIN SMALL LETTER I WITH DIAERESIS + 0x011F, //113 #LATIN SMALL LETTER G WITH BREVE + 0x00F1, //114 #LATIN SMALL LETTER N WITH TILDE + 0x00F2, //115 #LATIN SMALL LETTER O WITH GRAVE + 0x00F3, //116 #LATIN SMALL LETTER O WITH ACUTE + 0x00F4, //117 #LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00F5, //118 #LATIN SMALL LETTER O WITH TILDE + 0x00F6, //119 #LATIN SMALL LETTER O WITH DIAERESIS + 0x00F7, //120 #DIVISION SIGN + 0x00F8, //121 #LATIN SMALL LETTER O WITH STROKE + 0x00F9, //122 #LATIN SMALL LETTER U WITH GRAVE + 0x00FA, //123 #LATIN SMALL LETTER U WITH ACUTE + 0x00FB, //124 #LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00FC, //125 #LATIN SMALL LETTER U WITH DIAERESIS + 0x0131, //126 #LATIN SMALL LETTER DOTLESS I + 0x015F, //127 #LATIN SMALL LETTER S WITH CEDILLA + 0x00FF //128 #LATIN SMALL LETTER Y WITH DIAERESIS +}; + +//Table 1255 +static const int DRW_Table1255[] = { + 0x20AC, //1 #EURO SIGN + 0x00 , //2 #UNDEFINED + 0x201A, //3 #SINGLE LOW-9 QUOTATION MARK + 0x0192, //4 #LATIN SMALL LETTER F WITH HOOK + 0x201E, //5 #DOUBLE LOW-9 QUOTATION MARK + 0x2026, //6 #HORIZONTAL ELLIPSIS + 0x2020, //7 #DAGGER + 0x2021, //8 #DOUBLE DAGGER + 0x02C6, //9 #MODIFIER LETTER CIRCUMFLEX ACCENT + 0x2030, //10 #PER MILLE SIGN + 0x00 , //11 #UNDEFINED + 0x2039, //12 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 0x00 , //13 #UNDEFINED + 0x00 , //14 #UNDEFINED + 0x00 , //15 #UNDEFINED + 0x00 , //16 #UNDEFINED + 0x00 , //17 #UNDEFINED + 0x2018, //18 #LEFT SINGLE QUOTATION MARK + 0x2019, //19 #RIGHT SINGLE QUOTATION MARK + 0x201C, //20 #LEFT DOUBLE QUOTATION MARK + 0x201D, //21 #RIGHT DOUBLE QUOTATION MARK + 0x2022, //22 #BULLET + 0x2013, //23 #EN DASH + 0x2014, //24 #EM DASH + 0x02DC, //25 #SMALL TILDE + 0x2122, //26 #TRADE MARK SIGN + 0x00 , //27 #UNDEFINED + 0x203A, //28 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 0x00 , //29 #UNDEFINED + 0x00 , //30 #UNDEFINED + 0x00 , //31 #UNDEFINED + 0x00 , //32 #UNDEFINED + 0x00A0, //33 #NO-BREAK SPACE + 0x00A1, //34 #INVERTED EXCLAMATION MARK + 0x00A2, //35 #CENT SIGN + 0x00A3, //36 #POUND SIGN + 0x20AA, //37 #NEW SHEQEL SIGN + 0x00A5, //38 #YEN SIGN + 0x00A6, //39 #BROKEN BAR + 0x00A7, //40 #SECTION SIGN + 0x00A8, //41 #DIAERESIS + 0x00A9, //42 #COPYRIGHT SIGN + 0x00D7, //43 #MULTIPLICATION SIGN + 0x00AB, //44 #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00AC, //45 #NOT SIGN + 0x00AD, //46 #SOFT HYPHEN + 0x00AE, //47 #REGISTERED SIGN + 0x00AF, //48 #MACRON + 0x00B0, //49 #DEGREE SIGN + 0x00B1, //50 #PLUS-MINUS SIGN + 0x00B2, //51 #SUPERSCRIPT TWO + 0x00B3, //52 #SUPERSCRIPT THREE + 0x00B4, //53 #ACUTE ACCENT + 0x00B5, //54 #MICRO SIGN + 0x00B6, //55 #PILCROW SIGN + 0x00B7, //56 #MIDDLE DOT + 0x00B8, //57 #CEDILLA + 0x00B9, //58 #SUPERSCRIPT ONE + 0x00F7, //59 #DIVISION SIGN + 0x00BB, //60 #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00BC, //61 #VULGAR FRACTION ONE QUARTER + 0x00BD, //62 #VULGAR FRACTION ONE HALF + 0x00BE, //63 #VULGAR FRACTION THREE QUARTERS + 0x00BF, //64 #INVERTED QUESTION MARK + 0x05B0, //65 #HEBREW POINT SHEVA + 0x05B1, //66 #HEBREW POINT HATAF SEGOL + 0x05B2, //67 #HEBREW POINT HATAF PATAH + 0x05B3, //68 #HEBREW POINT HATAF QAMATS + 0x05B4, //69 #HEBREW POINT HIRIQ + 0x05B5, //70 #HEBREW POINT TSERE + 0x05B6, //71 #HEBREW POINT SEGOL + 0x05B7, //72 #HEBREW POINT PATAH + 0x05B8, //73 #HEBREW POINT QAMATS + 0x05B9, //74 #HEBREW POINT HOLAM + 0x00 , //75 #UNDEFINED + 0x05BB, //76 #HEBREW POINT QUBUTS + 0x05BC, //77 #HEBREW POINT DAGESH OR MAPIQ + 0x05BD, //78 #HEBREW POINT METEG + 0x05BE, //79 #HEBREW PUNCTUATION MAQAF + 0x05BF, //80 #HEBREW POINT RAFE + 0x05C0, //81 #HEBREW PUNCTUATION PASEQ + 0x05C1, //82 #HEBREW POINT SHIN DOT + 0x05C2, //83 #HEBREW POINT SIN DOT + 0x05C3, //84 #HEBREW PUNCTUATION SOF PASUQ + 0x05F0, //85 #HEBREW LIGATURE YIDDISH DOUBLE VAV + 0x05F1, //86 #HEBREW LIGATURE YIDDISH VAV YOD + 0x05F2, //87 #HEBREW LIGATURE YIDDISH DOUBLE YOD + 0x05F3, //88 #HEBREW PUNCTUATION GERESH + 0x05F4, //89 #HEBREW PUNCTUATION GERSHAYIM + 0x00 , //90 #UNDEFINED + 0x00 , //91 #UNDEFINED + 0x00 , //92 #UNDEFINED + 0x00 , //93 #UNDEFINED + 0x00 , //94 #UNDEFINED + 0x00 , //95 #UNDEFINED + 0x00 , //96 #UNDEFINED + 0x05D0, //97 #HEBREW LETTER ALEF + 0x05D1, //98 #HEBREW LETTER BET + 0x05D2, //99 #HEBREW LETTER GIMEL + 0x05D3, //100 #HEBREW LETTER DALET + 0x05D4, //101 #HEBREW LETTER HE + 0x05D5, //102 #HEBREW LETTER VAV + 0x05D6, //103 #HEBREW LETTER ZAYIN + 0x05D7, //104 #HEBREW LETTER HET + 0x05D8, //105 #HEBREW LETTER TET + 0x05D9, //106 #HEBREW LETTER YOD + 0x05DA, //107 #HEBREW LETTER FINAL KAF + 0x05DB, //108 #HEBREW LETTER KAF + 0x05DC, //109 #HEBREW LETTER LAMED + 0x05DD, //110 #HEBREW LETTER FINAL MEM + 0x05DE, //111 #HEBREW LETTER MEM + 0x05DF, //112 #HEBREW LETTER FINAL NUN + 0x05E0, //113 #HEBREW LETTER NUN + 0x05E1, //114 #HEBREW LETTER SAMEKH + 0x05E2, //115 #HEBREW LETTER AYIN + 0x05E3, //116 #HEBREW LETTER FINAL PE + 0x05E4, //117 #HEBREW LETTER PE + 0x05E5, //118 #HEBREW LETTER FINAL TSADI + 0x05E6, //119 #HEBREW LETTER TSADI + 0x05E7, //120 #HEBREW LETTER QOF + 0x05E8, //121 #HEBREW LETTER RESH + 0x05E9, //122 #HEBREW LETTER SHIN + 0x05EA, //123 #HEBREW LETTER TAV + 0x00 , //124 #UNDEFINED + 0x00 , //125 #UNDEFINED + 0x200E, //126 #LEFT-TO-RIGHT MARK + 0x200F, //127 #RIGHT-TO-LEFT MARK + 0x00 //128 #UNDEFINED +}; + +//Table 1256 +static const int DRW_Table1256[] = { + 0x20AC, //1 #EURO SIGN + 0x067E, //2 #ARABIC LETTER PEH + 0x201A, //3 #SINGLE LOW-9 QUOTATION MARK + 0x0192, //4 #LATIN SMALL LETTER F WITH HOOK + 0x201E, //5 #DOUBLE LOW-9 QUOTATION MARK + 0x2026, //6 #HORIZONTAL ELLIPSIS + 0x2020, //7 #DAGGER + 0x2021, //8 #DOUBLE DAGGER + 0x02C6, //9 #MODIFIER LETTER CIRCUMFLEX ACCENT + 0x2030, //10 #PER MILLE SIGN + 0x0679, //11 #ARABIC LETTER TTEH + 0x2039, //12 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 0x0152, //13 #LATIN CAPITAL LIGATURE OE + 0x0686, //14 #ARABIC LETTER TCHEH + 0x0698, //15 #ARABIC LETTER JEH + 0x0688, //16 #ARABIC LETTER DDAL + 0x06AF, //17 #ARABIC LETTER GAF + 0x2018, //18 #LEFT SINGLE QUOTATION MARK + 0x2019, //19 #RIGHT SINGLE QUOTATION MARK + 0x201C, //20 #LEFT DOUBLE QUOTATION MARK + 0x201D, //21 #RIGHT DOUBLE QUOTATION MARK + 0x2022, //22 #BULLET + 0x2013, //23 #EN DASH + 0x2014, //24 #EM DASH + 0x06A9, //25 #ARABIC LETTER KEHEH + 0x2122, //26 #TRADE MARK SIGN + 0x0691, //27 #ARABIC LETTER RREH + 0x203A, //28 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 0x0153, //29 #LATIN SMALL LIGATURE OE + 0x200C, //30 #ZERO WIDTH NON-JOINER + 0x200D, //31 #ZERO WIDTH JOINER + 0x06BA, //32 #ARABIC LETTER NOON GHUNNA + 0x00A0, //33 #NO-BREAK SPACE + 0x060C, //34 #ARABIC COMMA + 0x00A2, //35 #CENT SIGN + 0x00A3, //36 #POUND SIGN + 0x00A4, //37 #CURRENCY SIGN + 0x00A5, //38 #YEN SIGN + 0x00A6, //39 #BROKEN BAR + 0x00A7, //40 #SECTION SIGN + 0x00A8, //41 #DIAERESIS + 0x00A9, //42 #COPYRIGHT SIGN + 0x06BE, //43 #ARABIC LETTER HEH DOACHASHMEE + 0x00AB, //44 #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00AC, //45 #NOT SIGN + 0x00AD, //46 #SOFT HYPHEN + 0x00AE, //47 #REGISTERED SIGN + 0x00AF, //48 #MACRON + 0x00B0, //49 #DEGREE SIGN + 0x00B1, //50 #PLUS-MINUS SIGN + 0x00B2, //51 #SUPERSCRIPT TWO + 0x00B3, //52 #SUPERSCRIPT THREE + 0x00B4, //53 #ACUTE ACCENT + 0x00B5, //54 #MICRO SIGN + 0x00B6, //55 #PILCROW SIGN + 0x00B7, //56 #MIDDLE DOT + 0x00B8, //57 #CEDILLA + 0x00B9, //58 #SUPERSCRIPT ONE + 0x061B, //59 #ARABIC SEMICOLON + 0x00BB, //60 #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00BC, //61 #VULGAR FRACTION ONE QUARTER + 0x00BD, //62 #VULGAR FRACTION ONE HALF + 0x00BE, //63 #VULGAR FRACTION THREE QUARTERS + 0x061F, //64 #ARABIC QUESTION MARK + 0x06C1, //65 #ARABIC LETTER HEH GOAL + 0x0621, //66 #ARABIC LETTER HAMZA + 0x0622, //67 #ARABIC LETTER ALEF WITH MADDA ABOVE + 0x0623, //68 #ARABIC LETTER ALEF WITH HAMZA ABOVE + 0x0624, //69 #ARABIC LETTER WAW WITH HAMZA ABOVE + 0x0625, //70 #ARABIC LETTER ALEF WITH HAMZA BELOW + 0x0626, //71 #ARABIC LETTER YEH WITH HAMZA ABOVE + 0x0627, //72 #ARABIC LETTER ALEF + 0x0628, //73 #ARABIC LETTER BEH + 0x0629, //74 #ARABIC LETTER TEH MARBUTA + 0x062A, //75 #ARABIC LETTER TEH + 0x062B, //76 #ARABIC LETTER THEH + 0x062C, //77 #ARABIC LETTER JEEM + 0x062D, //78 #ARABIC LETTER HAH + 0x062E, //79 #ARABIC LETTER KHAH + 0x062F, //80 #ARABIC LETTER DAL + 0x0630, //81 #ARABIC LETTER THAL + 0x0631, //82 #ARABIC LETTER REH + 0x0632, //83 #ARABIC LETTER ZAIN + 0x0633, //84 #ARABIC LETTER SEEN + 0x0634, //85 #ARABIC LETTER SHEEN + 0x0635, //86 #ARABIC LETTER SAD + 0x0636, //87 #ARABIC LETTER DAD + 0x00D7, //88 #MULTIPLICATION SIGN + 0x0637, //89 #ARABIC LETTER TAH + 0x0638, //90 #ARABIC LETTER ZAH + 0x0639, //91 #ARABIC LETTER AIN + 0x063A, //92 #ARABIC LETTER GHAIN + 0x0640, //93 #ARABIC TATWEEL + 0x0641, //94 #ARABIC LETTER FEH + 0x0642, //95 #ARABIC LETTER QAF + 0x0643, //96 #ARABIC LETTER KAF + 0x00E0, //97 #LATIN SMALL LETTER A WITH GRAVE + 0x0644, //98 #ARABIC LETTER LAM + 0x00E2, //99 #LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0645, //100 #ARABIC LETTER MEEM + 0x0646, //101 #ARABIC LETTER NOON + 0x0647, //102 #ARABIC LETTER HEH + 0x0648, //103 #ARABIC LETTER WAW + 0x00E7, //104 #LATIN SMALL LETTER C WITH CEDILLA + 0x00E8, //105 #LATIN SMALL LETTER E WITH GRAVE + 0x00E9, //106 #LATIN SMALL LETTER E WITH ACUTE + 0x00EA, //107 #LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00EB, //108 #LATIN SMALL LETTER E WITH DIAERESIS + 0x0649, //109 #ARABIC LETTER ALEF MAKSURA + 0x064A, //110 #ARABIC LETTER YEH + 0x00EE, //111 #LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00EF, //112 #LATIN SMALL LETTER I WITH DIAERESIS + 0x064B, //113 #ARABIC FATHATAN + 0x064C, //114 #ARABIC DAMMATAN + 0x064D, //115 #ARABIC KASRATAN + 0x064E, //116 #ARABIC FATHA + 0x00F4, //117 #LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x064F, //118 #ARABIC DAMMA + 0x0650, //119 #ARABIC KASRA + 0x00F7, //120 #DIVISION SIGN + 0x0651, //121 #ARABIC SHADDA + 0x00F9, //122 #LATIN SMALL LETTER U WITH GRAVE + 0x0652, //123 #ARABIC SUKUN + 0x00FB, //124 #LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00FC, //125 #LATIN SMALL LETTER U WITH DIAERESIS + 0x200E, //126 #LEFT-TO-RIGHT MARK + 0x200F, //127 #RIGHT-TO-LEFT MARK + 0x06D2 //128 #ARABIC LETTER YEH BARREE +}; + +//Table 1257 +static const int DRW_Table1257[] = { + 0x20AC, //1 #EURO SIGN + 0x00 , //2 #UNDEFINED + 0x201A, //3 #SINGLE LOW-9 QUOTATION MARK + 0x00 , //4 #UNDEFINED + 0x201E, //5 #DOUBLE LOW-9 QUOTATION MARK + 0x2026, //6 #HORIZONTAL ELLIPSIS + 0x2020, //7 #DAGGER + 0x2021, //8 #DOUBLE DAGGER + 0x00 , //9 #UNDEFINED + 0x2030, //10 #PER MILLE SIGN + 0x00 , //11 #UNDEFINED + 0x2039, //12 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 0x00 , //13 #UNDEFINED + 0x00A8, //14 #DIAERESIS + 0x02C7, //15 #CARON + 0x00B8, //16 #CEDILLA + 0x00 , //17 #UNDEFINED + 0x2018, //18 #LEFT SINGLE QUOTATION MARK + 0x2019, //19 #RIGHT SINGLE QUOTATION MARK + 0x201C, //20 #LEFT DOUBLE QUOTATION MARK + 0x201D, //21 #RIGHT DOUBLE QUOTATION MARK + 0x2022, //22 #BULLET + 0x2013, //23 #EN DASH + 0x2014, //24 #EM DASH + 0x00 , //25 #UNDEFINED + 0x2122, //26 #TRADE MARK SIGN + 0x00 , //27 #UNDEFINED + 0x203A, //28 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 0x00 , //29 #UNDEFINED + 0x00AF, //30 #MACRON + 0x02DB, //31 #OGONEK + 0x00 , //32 #UNDEFINED + 0x00A0, //33 #NO-BREAK SPACE + 0x00 , //34 #UNDEFINED + 0x00A2, //35 #CENT SIGN + 0x00A3, //36 #POUND SIGN + 0x00A4, //37 #CURRENCY SIGN + 0x00 , //38 #UNDEFINED + 0x00A6, //39 #BROKEN BAR + 0x00A7, //40 #SECTION SIGN + 0x00D8, //41 #LATIN CAPITAL LETTER O WITH STROKE + 0x00A9, //42 #COPYRIGHT SIGN + 0x0156, //43 #LATIN CAPITAL LETTER R WITH CEDILLA + 0x00AB, //44 #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00AC, //45 #NOT SIGN + 0x00AD, //46 #SOFT HYPHEN + 0x00AE, //47 #REGISTERED SIGN + 0x00C6, //48 #LATIN CAPITAL LETTER AE + 0x00B0, //49 #DEGREE SIGN + 0x00B1, //50 #PLUS-MINUS SIGN + 0x00B2, //51 #SUPERSCRIPT TWO + 0x00B3, //52 #SUPERSCRIPT THREE + 0x00B4, //53 #ACUTE ACCENT + 0x00B5, //54 #MICRO SIGN + 0x00B6, //55 #PILCROW SIGN + 0x00B7, //56 #MIDDLE DOT + 0x00F8, //57 #LATIN SMALL LETTER O WITH STROKE + 0x00B9, //58 #SUPERSCRIPT ONE + 0x0157, //59 #LATIN SMALL LETTER R WITH CEDILLA + 0x00BB, //60 #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00BC, //61 #VULGAR FRACTION ONE QUARTER + 0x00BD, //62 #VULGAR FRACTION ONE HALF + 0x00BE, //63 #VULGAR FRACTION THREE QUARTERS + 0x00E6, //64 #LATIN SMALL LETTER AE + 0x0104, //65 #LATIN CAPITAL LETTER A WITH OGONEK + 0x012E, //66 #LATIN CAPITAL LETTER I WITH OGONEK + 0x0100, //67 #LATIN CAPITAL LETTER A WITH MACRON + 0x0106, //68 #LATIN CAPITAL LETTER C WITH ACUTE + 0x00C4, //69 #LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00C5, //70 #LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0118, //71 #LATIN CAPITAL LETTER E WITH OGONEK + 0x0112, //72 #LATIN CAPITAL LETTER E WITH MACRON + 0x010C, //73 #LATIN CAPITAL LETTER C WITH CARON + 0x00C9, //74 #LATIN CAPITAL LETTER E WITH ACUTE + 0x0179, //75 #LATIN CAPITAL LETTER Z WITH ACUTE + 0x0116, //76 #LATIN CAPITAL LETTER E WITH DOT ABOVE + 0x0122, //77 #LATIN CAPITAL LETTER G WITH CEDILLA + 0x0136, //78 #LATIN CAPITAL LETTER K WITH CEDILLA + 0x012A, //79 #LATIN CAPITAL LETTER I WITH MACRON + 0x013B, //80 #LATIN CAPITAL LETTER L WITH CEDILLA + 0x0160, //81 #LATIN CAPITAL LETTER S WITH CARON + 0x0143, //82 #LATIN CAPITAL LETTER N WITH ACUTE + 0x0145, //83 #LATIN CAPITAL LETTER N WITH CEDILLA + 0x00D3, //84 #LATIN CAPITAL LETTER O WITH ACUTE + 0x014C, //85 #LATIN CAPITAL LETTER O WITH MACRON + 0x00D5, //86 #LATIN CAPITAL LETTER O WITH TILDE + 0x00D6, //87 #LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00D7, //88 #MULTIPLICATION SIGN + 0x0172, //89 #LATIN CAPITAL LETTER U WITH OGONEK + 0x0141, //90 #LATIN CAPITAL LETTER L WITH STROKE + 0x015A, //91 #LATIN CAPITAL LETTER S WITH ACUTE + 0x016A, //92 #LATIN CAPITAL LETTER U WITH MACRON + 0x00DC, //93 #LATIN CAPITAL LETTER U WITH DIAERESIS + 0x017B, //94 #LATIN CAPITAL LETTER Z WITH DOT ABOVE + 0x017D, //95 #LATIN CAPITAL LETTER Z WITH CARON + 0x00DF, //96 #LATIN SMALL LETTER SHARP S + 0x0105, //97 #LATIN SMALL LETTER A WITH OGONEK + 0x012F, //98 #LATIN SMALL LETTER I WITH OGONEK + 0x0101, //99 #LATIN SMALL LETTER A WITH MACRON + 0x0107, //100 #LATIN SMALL LETTER C WITH ACUTE + 0x00E4, //101 #LATIN SMALL LETTER A WITH DIAERESIS + 0x00E5, //102 #LATIN SMALL LETTER A WITH RING ABOVE + 0x0119, //103 #LATIN SMALL LETTER E WITH OGONEK + 0x0113, //104 #LATIN SMALL LETTER E WITH MACRON + 0x010D, //105 #LATIN SMALL LETTER C WITH CARON + 0x00E9, //106 #LATIN SMALL LETTER E WITH ACUTE + 0x017A, //107 #LATIN SMALL LETTER Z WITH ACUTE + 0x0117, //108 #LATIN SMALL LETTER E WITH DOT ABOVE + 0x0123, //109 #LATIN SMALL LETTER G WITH CEDILLA + 0x0137, //110 #LATIN SMALL LETTER K WITH CEDILLA + 0x012B, //111 #LATIN SMALL LETTER I WITH MACRON + 0x013C, //112 #LATIN SMALL LETTER L WITH CEDILLA + 0x0161, //113 #LATIN SMALL LETTER S WITH CARON + 0x0144, //114 #LATIN SMALL LETTER N WITH ACUTE + 0x0146, //115 #LATIN SMALL LETTER N WITH CEDILLA + 0x00F3, //116 #LATIN SMALL LETTER O WITH ACUTE + 0x014D, //117 #LATIN SMALL LETTER O WITH MACRON + 0x00F5, //118 #LATIN SMALL LETTER O WITH TILDE + 0x00F6, //119 #LATIN SMALL LETTER O WITH DIAERESIS + 0x00F7, //120 #DIVISION SIGN + 0x0173, //121 #LATIN SMALL LETTER U WITH OGONEK + 0x0142, //122 #LATIN SMALL LETTER L WITH STROKE + 0x015B, //123 #LATIN SMALL LETTER S WITH ACUTE + 0x016B, //124 #LATIN SMALL LETTER U WITH MACRON + 0x00FC, //125 #LATIN SMALL LETTER U WITH DIAERESIS + 0x017C, //126 #LATIN SMALL LETTER Z WITH DOT ABOVE + 0x017E, //127 #LATIN SMALL LETTER Z WITH CARON + 0x02D9 //128 #DOT ABOVE +}; + +//Table 1258 +static const int DRW_Table1258[] = { + 0x20AC, //1 #EURO SIGN + 0x00 , //2 #UNDEFINED + 0x201A, //3 #SINGLE LOW-9 QUOTATION MARK + 0x0192, //4 #LATIN SMALL LETTER F WITH HOOK + 0x201E, //5 #DOUBLE LOW-9 QUOTATION MARK + 0x2026, //6 #HORIZONTAL ELLIPSIS + 0x2020, //7 #DAGGER + 0x2021, //8 #DOUBLE DAGGER + 0x02C6, //9 #MODIFIER LETTER CIRCUMFLEX ACCENT + 0x2030, //10 #PER MILLE SIGN + 0x00 , //11 #UNDEFINED + 0x2039, //12 #SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 0x0152, //13 #LATIN CAPITAL LIGATURE OE + 0x00 , //14 #UNDEFINED + 0x00 , //15 #UNDEFINED + 0x00 , //16 #UNDEFINED + 0x00 , //17 #UNDEFINED + 0x2018, //18 #LEFT SINGLE QUOTATION MARK + 0x2019, //19 #RIGHT SINGLE QUOTATION MARK + 0x201C, //20 #LEFT DOUBLE QUOTATION MARK + 0x201D, //21 #RIGHT DOUBLE QUOTATION MARK + 0x2022, //22 #BULLET + 0x2013, //23 #EN DASH + 0x2014, //24 #EM DASH + 0x02DC, //25 #SMALL TILDE + 0x2122, //26 #TRADE MARK SIGN + 0x00 , //27 #UNDEFINED + 0x203A, //28 #SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 0x0153, //29 #LATIN SMALL LIGATURE OE + 0x00 , //30 #UNDEFINED + 0x00 , //31 #UNDEFINED + 0x0178, //32 #LATIN CAPITAL LETTER Y WITH DIAERESIS + 0x00A0, //33 #NO-BREAK SPACE + 0x00A1, //34 #INVERTED EXCLAMATION MARK + 0x00A2, //35 #CENT SIGN + 0x00A3, //36 #POUND SIGN + 0x00A4, //37 #CURRENCY SIGN + 0x00A5, //38 #YEN SIGN + 0x00A6, //39 #BROKEN BAR + 0x00A7, //40 #SECTION SIGN + 0x00A8, //41 #DIAERESIS + 0x00A9, //42 #COPYRIGHT SIGN + 0x00AA, //43 #FEMININE ORDINAL INDICATOR + 0x00AB, //44 #LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00AC, //45 #NOT SIGN + 0x00AD, //46 #SOFT HYPHEN + 0x00AE, //47 #REGISTERED SIGN + 0x00AF, //48 #MACRON + 0x00B0, //49 #DEGREE SIGN + 0x00B1, //50 #PLUS-MINUS SIGN + 0x00B2, //51 #SUPERSCRIPT TWO + 0x00B3, //52 #SUPERSCRIPT THREE + 0x00B4, //53 #ACUTE ACCENT + 0x00B5, //54 #MICRO SIGN + 0x00B6, //55 #PILCROW SIGN + 0x00B7, //56 #MIDDLE DOT + 0x00B8, //57 #CEDILLA + 0x00B9, //58 #SUPERSCRIPT ONE + 0x00BA, //59 #MASCULINE ORDINAL INDICATOR + 0x00BB, //60 #RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00BC, //61 #VULGAR FRACTION ONE QUARTER + 0x00BD, //62 #VULGAR FRACTION ONE HALF + 0x00BE, //63 #VULGAR FRACTION THREE QUARTERS + 0x00BF, //64 #INVERTED QUESTION MARK + 0x00C0, //65 #LATIN CAPITAL LETTER A WITH GRAVE + 0x00C1, //66 #LATIN CAPITAL LETTER A WITH ACUTE + 0x00C2, //67 #LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x0102, //68 #LATIN CAPITAL LETTER A WITH BREVE + 0x00C4, //69 #LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00C5, //70 #LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00C6, //71 #LATIN CAPITAL LETTER AE + 0x00C7, //72 #LATIN CAPITAL LETTER C WITH CEDILLA + 0x00C8, //73 #LATIN CAPITAL LETTER E WITH GRAVE + 0x00C9, //74 #LATIN CAPITAL LETTER E WITH ACUTE + 0x00CA, //75 #LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00CB, //76 #LATIN CAPITAL LETTER E WITH DIAERESIS + 0x0300, //77 #COMBINING GRAVE ACCENT + 0x00CD, //78 #LATIN CAPITAL LETTER I WITH ACUTE + 0x00CE, //79 #LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00CF, //80 #LATIN CAPITAL LETTER I WITH DIAERESIS + 0x0110, //81 #LATIN CAPITAL LETTER D WITH STROKE + 0x00D1, //82 #LATIN CAPITAL LETTER N WITH TILDE + 0x0309, //83 #COMBINING HOOK ABOVE + 0x00D3, //84 #LATIN CAPITAL LETTER O WITH ACUTE + 0x00D4, //85 #LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x01A0, //86 #LATIN CAPITAL LETTER O WITH HORN + 0x00D6, //87 #LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00D7, //88 #MULTIPLICATION SIGN + 0x00D8, //89 #LATIN CAPITAL LETTER O WITH STROKE + 0x00D9, //90 #LATIN CAPITAL LETTER U WITH GRAVE + 0x00DA, //91 #LATIN CAPITAL LETTER U WITH ACUTE + 0x00DB, //92 #LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00DC, //93 #LATIN CAPITAL LETTER U WITH DIAERESIS + 0x01AF, //94 #LATIN CAPITAL LETTER U WITH HORN + 0x0303, //95 #COMBINING TILDE + 0x00DF, //96 #LATIN SMALL LETTER SHARP S + 0x00E0, //97 #LATIN SMALL LETTER A WITH GRAVE + 0x00E1, //98 #LATIN SMALL LETTER A WITH ACUTE + 0x00E2, //99 #LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0103, //100 #LATIN SMALL LETTER A WITH BREVE + 0x00E4, //101 #LATIN SMALL LETTER A WITH DIAERESIS + 0x00E5, //102 #LATIN SMALL LETTER A WITH RING ABOVE + 0x00E6, //103 #LATIN SMALL LETTER AE + 0x00E7, //104 #LATIN SMALL LETTER C WITH CEDILLA + 0x00E8, //105 #LATIN SMALL LETTER E WITH GRAVE + 0x00E9, //106 #LATIN SMALL LETTER E WITH ACUTE + 0x00EA, //107 #LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00EB, //108 #LATIN SMALL LETTER E WITH DIAERESIS + 0x0301, //109 #COMBINING ACUTE ACCENT + 0x00ED, //110 #LATIN SMALL LETTER I WITH ACUTE + 0x00EE, //111 #LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00EF, //112 #LATIN SMALL LETTER I WITH DIAERESIS + 0x0111, //113 #LATIN SMALL LETTER D WITH STROKE + 0x00F1, //114 #LATIN SMALL LETTER N WITH TILDE + 0x0323, //115 #COMBINING DOT BELOW + 0x00F3, //116 #LATIN SMALL LETTER O WITH ACUTE + 0x00F4, //117 #LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x01A1, //118 #LATIN SMALL LETTER O WITH HORN + 0x00F6, //119 #LATIN SMALL LETTER O WITH DIAERESIS + 0x00F7, //120 #DIVISION SIGN + 0x00F8, //121 #LATIN SMALL LETTER O WITH STROKE + 0x00F9, //122 #LATIN SMALL LETTER U WITH GRAVE + 0x00FA, //123 #LATIN SMALL LETTER U WITH ACUTE + 0x00FB, //124 #LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00FC, //125 #LATIN SMALL LETTER U WITH DIAERESIS + 0x01B0, //126 #LATIN SMALL LETTER U WITH HORN + 0x20AB, //127 #DONG SIGN + 0x00FF //128 #LATIN SMALL LETTER Y WITH DIAERESIS +}; + +#endif // DRW_CPTABLES_H diff --git a/extlib/libdxfrw/intern/drw_dbg.cpp b/extlib/libdxfrw/intern/drw_dbg.cpp new file mode 100644 index 0000000..d999edf --- /dev/null +++ b/extlib/libdxfrw/intern/drw_dbg.cpp @@ -0,0 +1,164 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include +#include +#include "drw_dbg.h" + +DRW_dbg *DRW_dbg::instance= NULL; + +/*********private clases*************/ +class print_none { +public: + virtual void printS(std::string s){(void)s;} + virtual void printI(long long int i){(void)i;} + virtual void printUI(long long unsigned int i){(void)i;} + virtual void printD(double d){(void)d;} + virtual void printH(long long int i){(void)i;} + virtual void printB(int i){(void)i;} + virtual void printHL(int c, int s, int h){(void)c;(void)s;(void)h;} + virtual void printPT(double x, double y, double z){(void)x;(void)y;(void)z;} + print_none(){} + virtual ~print_none(){} +}; + +class print_debug : public print_none { +public: + virtual void printS(std::string s); + virtual void printI(long long int i); + virtual void printUI(long long unsigned int i); + virtual void printD(double d); + virtual void printH(long long int i); + virtual void printB(int i); + virtual void printHL(int c, int s, int h); + virtual void printPT(double x, double y, double z); + print_debug(); + virtual ~print_debug(){} +private: + std::ios_base::fmtflags flags; +}; + +/********* debug class *************/ +DRW_dbg *DRW_dbg::getInstance(){ + if (instance == NULL){ + instance = new DRW_dbg; + } + return instance; +} + +DRW_dbg::DRW_dbg(){ + level = NONE; + prClass = new print_none; + flags = std::cerr.flags(); +} + +void DRW_dbg::setLevel(LEVEL lvl){ + level = lvl; + delete prClass; + switch (level){ + case DEBUG: + prClass = new print_debug; + break; + default: + prClass = new print_none; + } +} + +DRW_dbg::LEVEL DRW_dbg::getLevel(){ + return level; +} + +void DRW_dbg::print(std::string s){ + prClass->printS(s); +} + +void DRW_dbg::print(int i){ + prClass->printI(i); +} + +void DRW_dbg::print(unsigned int i){ + prClass->printUI(i); +} + +void DRW_dbg::print(long long int i){ + prClass->printI(i); +} + +void DRW_dbg::print(long unsigned int i){ + prClass->printUI(i); +} + +void DRW_dbg::print(long long unsigned int i){ + prClass->printUI(i); +} + +void DRW_dbg::print(double d){ + prClass->printD(d); +} + +void DRW_dbg::printH(long long int i){ + prClass->printH(i); +} + +void DRW_dbg::printB(int i){ + prClass->printB(i); +} +void DRW_dbg::printHL(int c, int s, int h){ + prClass->printHL(c, s, h); +} + +void DRW_dbg::printPT(double x, double y, double z){ + prClass->printPT(x, y, z); +} + +print_debug::print_debug(){ + flags = std::cerr.flags(); +} + +void print_debug::printS(std::string s){ + std::cerr << s; +} + +void print_debug::printI(long long int i){ + std::cerr << i; +} + +void print_debug::printUI(long long unsigned int i){ + std::cerr << i; +} + +void print_debug::printD(double d){ + std::cerr << std::fixed << d; +} + +void print_debug::printH(long long i){ + std::cerr << "0x" << std::setw(2) << std::setfill('0'); + std::cerr << std::hex << i; + std::cerr.flags(flags); +} + +void print_debug::printB(int i){ + std::cerr << std::setw(8) << std::setfill('0'); + std::cerr << std::setbase(2) << i; + std::cerr.flags(flags); +} + +void print_debug::printHL(int c, int s, int h){ + std::cerr << c << '.' << s << '.'; + std::cerr << "0x" << std::setw(2) << std::setfill('0'); + std::cerr << std::hex << h; + std::cerr.flags(flags); +} + +void print_debug::printPT(double x, double y, double z){ + std::cerr << std::fixed << "x: " << x << ", y: " << y << ", z: "<< z; +} diff --git a/extlib/libdxfrw/intern/drw_dbg.h b/extlib/libdxfrw/intern/drw_dbg.h new file mode 100644 index 0000000..a494c9c --- /dev/null +++ b/extlib/libdxfrw/intern/drw_dbg.h @@ -0,0 +1,61 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DRW_DBG_H +#define DRW_DBG_H + +#include +#include +//#include + +#define DRW_DBGSL(a) DRW_dbg::getInstance()->setLevel(a) +#define DRW_DBGGL DRW_dbg::getInstance()->getLevel() +#define DRW_DBG(a) DRW_dbg::getInstance()->print(a) +#define DRW_DBGH(a) DRW_dbg::getInstance()->printH(a) +#define DRW_DBGB(a) DRW_dbg::getInstance()->printB(a) +#define DRW_DBGHL(a, b, c) DRW_dbg::getInstance()->printHL(a, b ,c) +#define DRW_DBGPT(a, b, c) DRW_dbg::getInstance()->printPT(a, b, c) + + +class print_none; + +class DRW_dbg { +public: + enum LEVEL { + NONE, + DEBUG + }; + void setLevel(LEVEL lvl); + LEVEL getLevel(); + static DRW_dbg *getInstance(); + void print(std::string s); + void print(int i); + void print(unsigned int i); + void print(long long int i); + void print(long unsigned int i); + void print(long long unsigned int i); + void print(double d); + void printH(long long int i); + void printB(int i); + void printHL(int c, int s, int h); + void printPT(double x, double y, double z); + +private: + DRW_dbg(); + static DRW_dbg *instance; + LEVEL level; + std::ios_base::fmtflags flags; + print_none* prClass; +}; + + +#endif // DRW_DBG_H diff --git a/extlib/libdxfrw/intern/drw_textcodec.cpp b/extlib/libdxfrw/intern/drw_textcodec.cpp new file mode 100644 index 0000000..39b2912 --- /dev/null +++ b/extlib/libdxfrw/intern/drw_textcodec.cpp @@ -0,0 +1,536 @@ +#include "drw_textcodec.h" +#include +#include +#include +#include "../drw_base.h" +#include "drw_cptables.h" +#include "drw_cptable932.h" +#include "drw_cptable936.h" +#include "drw_cptable949.h" +#include "drw_cptable950.h" + +DRW_TextCodec::DRW_TextCodec() { + version = DRW::AC1021; + conv = new DRW_Converter(NULL, 0); +} + +DRW_TextCodec::~DRW_TextCodec() { + delete conv; +} + +void DRW_TextCodec::setVersion(int v, bool dxfFormat){ + if (v == DRW::AC1009 || v == DRW::AC1006) { + version = DRW::AC1009; + cp = "ANSI_1252"; + setCodePage(&cp, dxfFormat); + } else if (v == DRW::AC1012 || v == DRW::AC1014 + || v == DRW::AC1015 || v == DRW::AC1018) { + version = DRW::AC1015; +// if (cp.empty()) { //codepage not set, initialize + cp = "ANSI_1252"; + setCodePage(&cp, dxfFormat); +// } + } else { + version = DRW::AC1021; + if (dxfFormat) + cp = "UTF-8";//RLZ: can be UCS2 or UTF-16 16bits per char + else + cp = "UTF-16";//RLZ: can be UCS2 or UTF-16 16bits per char + setCodePage(&cp, dxfFormat); + } +} + +void DRW_TextCodec::setVersion(std::string *v, bool dxfFormat){ + std::string versionStr = *v; + if (versionStr == "AC1009" || versionStr == "AC1006") { + setVersion(DRW::AC1009, dxfFormat); + } else if (versionStr == "AC1012" || versionStr == "AC1014" + || versionStr == "AC1015" || versionStr == "AC1018") { + setVersion(DRW::AC1015, dxfFormat); + } else { + setVersion(DRW::AC1021, dxfFormat); + } +} + +void DRW_TextCodec::setCodePage(std::string *c, bool dxfFormat){ + cp = correctCodePage(*c); + delete conv; + if (version == DRW::AC1009 || version == DRW::AC1015) { + if (cp == "ANSI_874") + conv = new DRW_ConvTable(DRW_Table874, CPLENGTHCOMMON); + else if (cp == "ANSI_932") + conv = new DRW_Conv932Table(DRW_Table932, DRW_LeadTable932, + DRW_DoubleTable932, CPLENGTH932); + else if (cp == "ANSI_936") + conv = new DRW_ConvDBCSTable(DRW_Table936, DRW_LeadTable936, + DRW_DoubleTable936, CPLENGTH936); + else if (cp == "ANSI_949") + conv = new DRW_ConvDBCSTable(DRW_Table949, DRW_LeadTable949, + DRW_DoubleTable949, CPLENGTH949); + else if (cp == "ANSI_950") + conv = new DRW_ConvDBCSTable(DRW_Table950, DRW_LeadTable950, + DRW_DoubleTable950, CPLENGTH950); + else if (cp == "ANSI_1250") + conv = new DRW_ConvTable(DRW_Table1250, CPLENGTHCOMMON); + else if (cp == "ANSI_1251") + conv = new DRW_ConvTable(DRW_Table1251, CPLENGTHCOMMON); + else if (cp == "ANSI_1253") + conv = new DRW_ConvTable(DRW_Table1253, CPLENGTHCOMMON); + else if (cp == "ANSI_1254") + conv = new DRW_ConvTable(DRW_Table1254, CPLENGTHCOMMON); + else if (cp == "ANSI_1255") + conv = new DRW_ConvTable(DRW_Table1255, CPLENGTHCOMMON); + else if (cp == "ANSI_1256") + conv = new DRW_ConvTable(DRW_Table1256, CPLENGTHCOMMON); + else if (cp == "ANSI_1257") + conv = new DRW_ConvTable(DRW_Table1257, CPLENGTHCOMMON); + else if (cp == "ANSI_1258") + conv = new DRW_ConvTable(DRW_Table1258, CPLENGTHCOMMON); + else if (cp == "UTF-8") { //DXF older than 2007 are write in win codepages + cp = "ANSI_1252"; + conv = new DRW_Converter(NULL, 0); + } else + conv = new DRW_ConvTable(DRW_Table1252, CPLENGTHCOMMON); + } else { + if (dxfFormat) + conv = new DRW_Converter(NULL, 0);//utf16 to utf8 + else + conv = new DRW_ConvUTF16();//utf16 to utf8 + } +} + +std::string DRW_TextCodec::toUtf8(std::string s) { + return conv->toUtf8(&s); +} + +std::string DRW_TextCodec::fromUtf8(std::string s) { + return conv->fromUtf8(&s); +} + +std::string DRW_Converter::toUtf8(std::string *s) { + std::string result; + int j = 0; + unsigned int i= 0; + for (i=0; i < s->length(); i++) { + unsigned char c = s->at(i); + if (c < 0x80) { //ascii check for /U+???? + if (c == '\\' && i+6 < s->length() && s->at(i+1) == 'U' && s->at(i+2) == '+') { + result += s->substr(j,i-j); + result += encodeText(s->substr(i,7)); + i +=6; + j = i+1; + } + } else if (c < 0xE0 ) {//2 bits + i++; + } else if (c < 0xF0 ) {//3 bits + i +=2; + } else if (c < 0xF8 ) {//4 bits + i +=3; + } + } + result += s->substr(j); + + return result; +} + +std::string DRW_ConvTable::fromUtf8(std::string *s) { + std::string result; + bool notFound; + int code; + + int j = 0; + for (unsigned int i=0; i < s->length(); i++) { + unsigned char c = s->at(i); + if (c > 0x7F) { //need to decode + result += s->substr(j,i-j); + std::string part1 = s->substr(i,4); + int l; + code = decodeNum(part1, &l); + j = i+l; + i = j - 1; + notFound = true; + for (int k=0; ksubstr(j); + + return result; +} + +std::string DRW_ConvTable::toUtf8(std::string *s) { + std::string res; + std::string::iterator it; + for ( it=s->begin() ; it < s->end(); ++it ) { + unsigned char c = *it; + if (c < 0x80) { + //check for \U+ encoded text + if (c == '\\') { + if (it+6 < s->end() && *(it+1) == 'U' && *(it+2) == '+') { + res += encodeText(std::string(it, it+7)); + it +=6; + } else { + res +=c; //no \U+ encoded text write + } + } else + res +=c; //c!='\' ascii char write + } else {//end c < 0x80 + res += encodeNum(table[c-0x80]); //translate from table + } + } //end for + + return res; +} + +std::string DRW_Converter::encodeText(std::string stmp){ + int code; +#if defined(__APPLE__) + int Succeeded = sscanf (&( stmp.substr(3,4)[0]), "%x", &code ); + if ( !Succeeded || Succeeded == EOF ) + code = 0; +#else + std::istringstream sd(stmp.substr(3,4)); + sd >> std::hex >> code; +#endif + return encodeNum(code); +} + +std::string DRW_Converter::decodeText(int c){ + std::string res = "\\U+"; + std::string num; +#if defined(__APPLE__) + std::string str(16, '\0'); + snprintf (&(str[0]), 16, "%04X", c ); + num = str; +#else + std::stringstream ss; + ss << std::uppercase << std::setfill('0') << std::setw(4) << std::hex << c; + ss >> num; +#endif + res += num; + return res; +} + +std::string DRW_Converter::encodeNum(int c){ + unsigned char ret[5]; + if (c < 128) { // 0-7F US-ASCII 7 bits + ret[0] = c; + ret[1] = 0; + } else if (c < 0x800) { //80-07FF 2 bytes + ret[0] = 0xC0 | (c >> 6); + ret[1] = 0x80 | (c & 0x3f); + ret[2] = 0; + } else if (c< 0x10000) { //800-FFFF 3 bytes + ret[0] = 0xe0 | (c >> 12); + ret[1] = 0x80 | ((c >> 6) & 0x3f); + ret[2] = 0x80 | (c & 0x3f); + ret[3] = 0; + } else { //10000-10FFFF 4 bytes + ret[0] = 0xf0 | (c >> 18); + ret[1] = 0x80 | ((c >> 12) & 0x3f); + ret[2] = 0x80 | ((c >> 6) & 0x3f); + ret[3] = 0x80 | (c & 0x3f); + ret[4] = 0; + } + return std::string((char*)ret); +} + +/** 's' is a string with at least 4 bytes length +** returned 'b' is byte length of encoded char: 2,3 or 4 +**/ +int DRW_Converter::decodeNum(std::string s, int *b){ + int code= 0; + unsigned char c = s.at(0); + if ( (c& 0xE0) == 0xC0) { //2 bytes + code = ( c&0x1F)<<6; + code = (s.at(1) &0x3F) | code; + *b = 2; + } else if ( (c& 0xF0) == 0xE0) { //3 bytes + code = ( c&0x0F)<<12; + code = ((s.at(1) &0x3F)<<6) | code; + code = (s.at(2) &0x3F) | code; + *b = 3; + } else if ( (c& 0xF8) == 0xF0) { //4 bytes + code = ( c&0x07)<<18; + code = ((s.at(1) &0x3F)<<12) | code; + code = ((s.at(2) &0x3F)<<6) | code; + code = (s.at(3) &0x3F) | code; + *b = 4; + } + + return code; +} + + +std::string DRW_ConvDBCSTable::fromUtf8(std::string *s) { + std::string result; + bool notFound; + int code; + + int j = 0; + for (unsigned int i=0; i < s->length(); i++) { + unsigned char c = s->at(i); + if (c > 0x7F) { //need to decode + result += s->substr(j,i-j); + std::string part1 = s->substr(i,4); + int l; + code = decodeNum(part1, &l); + j = i+l; + i = j - 1; + notFound = true; + for (int k=0; k> 8; + d[1] = data & 0xFF; + d[2]= '\0'; + result += d; //translate from table + notFound = false; + break; + } + } + if (notFound) + result += decodeText(code); + } //direct conversion + } + result += s->substr(j); + + return result; +} + +std::string DRW_ConvDBCSTable::toUtf8(std::string *s) { + std::string res; + std::string::iterator it; + for ( it=s->begin() ; it < s->end(); ++it ) { + bool notFound = true; + unsigned char c = *it; + if (c < 0x80) { + notFound = false; + //check for \U+ encoded text + if (c == '\\') { + if (it+6 < s->end() && *(it+1) == 'U' && *(it+2) == '+') { + res += encodeText(std::string(it, it+7)); + it +=6; + } else { + res +=c; //no \U+ encoded text write + } + } else + res +=c; //c!='\' ascii char write + } else if(c == 0x80 ){//1 byte table + notFound = false; + res += encodeNum(0x20AC);//euro sign + } else {//2 bytes + ++it; + int code = (c << 8) | (unsigned char )(*it); + int sta = leadTable[c-0x81]; + int end = leadTable[c-0x80]; + for (int k=sta; klength(); i++) { + unsigned char c = s->at(i); + if (c > 0x7F) { //need to decode + result += s->substr(j,i-j); + std::string part1 = s->substr(i,4); + int l; + code = decodeNum(part1, &l); + j = i+l; + i = j - 1; + notFound = true; + // 1 byte table + if (code > 0xff60 && code < 0xFFA0) { + result += code - CPOFFSET932; //translate from table + notFound = false; + } + if (notFound && ( code<0xF8 || (code>0x390 && code<0x542) || + (code>0x200F && code<0x9FA1) || code>0xF928 )) { + for (int k=0; k> 8; + d[1] = data & 0xFF; + d[2]= '\0'; + result += d; //translate from table + notFound = false; + break; + } + } + } + if (notFound) + result += decodeText(code); + } //direct conversion + } + result += s->substr(j); + + return result; +} + +std::string DRW_Conv932Table::toUtf8(std::string *s) { + std::string res; + std::string::iterator it; + for ( it=s->begin() ; it < s->end(); ++it ) { + bool notFound = true; + unsigned char c = *it; + if (c < 0x80) { + notFound = false; + //check for \U+ encoded text + if (c == '\\') { + if (it+6 < s->end() && *(it+1) == 'U' && *(it+2) == '+') { + res += encodeText(std::string(it, it+7)); + it +=6; + } else { + res +=c; //no \U+ encoded text write + } + } else + res +=c; //c!='\' ascii char write + } else if(c > 0xA0 && c < 0xE0 ){//1 byte table + notFound = false; + res += encodeNum(c + CPOFFSET932); //translate from table + } else {//2 bytes + ++it; + int code = (c << 8) | (unsigned char )(*it); + int sta; + int end=0; + if (c > 0x80 && c < 0xA0) { + sta = DRW_LeadTable932[c-0x81]; + end = DRW_LeadTable932[c-0x80]; + } else if (c > 0xDF && c < 0xFD){ + sta = DRW_LeadTable932[c-0xC1]; + end = DRW_LeadTable932[c-0xC0]; + } + if (end > 0) { + for (int k=sta; kbegin() ; it < s->end(); ++it ) { + unsigned char c1 = *it; + unsigned char c2 = *(++it); + duint16 ch = (c2 <<8) | c1; + res +=encodeNum(ch); + } //end for + + return res; +} + +std::string DRW_TextCodec::correctCodePage(const std::string& s) { + //stringstream cause crash in OS/X, bug#3597944 + std::string cp=s; + transform(cp.begin(), cp.end(), cp.begin(), toupper); + //Latin/Thai + if (cp=="ANSI_874" || cp=="CP874" || cp=="ISO8859-11" || cp=="TIS-620") { + return "ANSI_874"; + //Central Europe and Eastern Europe + } else if (cp=="ANSI_1250" || cp=="CP1250" || cp=="ISO8859-2") { + return "ANSI_1250"; + //Cyrillic script + } else if (cp=="ANSI_1251" || cp=="CP1251" || cp=="ISO8859-5" || cp=="KOI8-R" || + cp=="KOI8-U" || cp=="IBM 866") { + return "ANSI_1251"; + //Western Europe + } else if (cp=="ANSI_1252" || cp=="CP1252" || cp=="LATIN1" || cp=="ISO-8859-1" || + cp=="CP819" || cp=="CSISO" || cp=="IBM819" || cp=="ISO_8859-1" || cp=="APPLE ROMAN" || + cp=="ISO8859-1" || cp=="ISO8859-15" || cp=="ISO-IR-100" || cp=="L1" || cp=="IBM 850") { + return "ANSI_1252"; + //Greek + } else if (cp=="ANSI_1253" || cp=="CP1253" || cp=="iso8859-7") { + return "ANSI_1253"; + //Turkish + } else if (cp=="ANSI_1254" || cp=="CP1254" || cp=="iso8859-9" || cp=="iso8859-3") { + return "ANSI_1254"; + //Hebrew + } else if (cp=="ANSI_1255" || cp=="CP1255" || cp=="iso8859-8") { + return "ANSI_1255"; + //Arabic + } else if (cp=="ANSI_1256" || cp=="CP1256" || cp=="ISO8859-6") { + return "ANSI_1256"; + //Baltic + } else if (cp=="ANSI_1257" || cp=="CP1257" || cp=="ISO8859-4" || cp=="ISO8859-10" || cp=="ISO8859-13") { + return "ANSI_1257"; + //Vietnamese + } else if (cp=="ANSI_1258" || cp=="CP1258") { + return "ANSI_1258"; + + //Japanese + } else if (cp=="ANSI_932" || cp=="SHIFT-JIS" || cp=="SHIFT_JIS" || cp=="CSSHIFTJIS" || + cp=="CSWINDOWS31J" || cp=="MS_KANJI" || cp=="X-MS-CP932" || cp=="X-SJIS" || + cp=="EUCJP" || cp=="EUC-JP" || cp=="CSEUCPKDFMTJAPANESE" || cp=="X-EUC" || + cp=="X-EUC-JP" || cp=="JIS7") { + return "ANSI_932"; + //Chinese PRC GBK (XGB) simplified + } else if (cp=="ANSI_936" || cp=="GBK" || cp=="GB2312" || cp=="CHINESE" || cp=="CN-GB" || + cp=="CSGB2312" || cp=="CSGB231280" || cp=="CSISO58BG231280" || + cp=="GB_2312-80" || cp=="GB231280" || cp=="GB2312-80" || + cp=="ISO-IR-58" || cp=="GB18030") { + return "ANSI_936"; + //Korean + } else if (cp=="ANSI_949" || cp=="EUCKR") { + return "ANSI_949"; + //Chinese Big5 (Taiwan, Hong Kong SAR) + } else if (cp=="ANSI_950" || cp=="BIG5" || cp=="CN-BIG5" || cp=="CSBIG5" || + cp=="X-X-BIG5" || cp=="BIG5-HKSCS") { + return "ANSI_950"; + +//celtic +/* } else if (cp=="ISO8859-14") { + return "ISO8859-14"; + } else if (cp=="TSCII") { + return "TSCII"; //tamil + }*/ + + } else if (cp=="UTF-8" || cp=="UTF8" || cp=="UTF8-BIT") { + return "UTF-8"; + } else if (cp=="UTF-16" || cp=="UTF16" || cp=="UTF16-BIT") { + return "UTF-16"; + } + + return "ANSI_1252"; +} diff --git a/extlib/libdxfrw/intern/drw_textcodec.h b/extlib/libdxfrw/intern/drw_textcodec.h new file mode 100644 index 0000000..cc46471 --- /dev/null +++ b/extlib/libdxfrw/intern/drw_textcodec.h @@ -0,0 +1,91 @@ +#ifndef DRW_TEXTCODEC_H +#define DRW_TEXTCODEC_H + +#include + +class DRW_Converter; + +class DRW_TextCodec +{ +public: + DRW_TextCodec(); + ~DRW_TextCodec(); + std::string fromUtf8(std::string s); + std::string toUtf8(std::string s); + int getVersion(){return version;} + void setVersion(std::string *v, bool dxfFormat); + void setVersion(int v, bool dxfFormat); + void setCodePage(std::string *c, bool dxfFormat); + void setCodePage(std::string c, bool dxfFormat){setCodePage(&c, dxfFormat);} + std::string getCodePage(){return cp;} + +private: + std::string correctCodePage(const std::string& s); + +private: + int version; + std::string cp; + DRW_Converter *conv; +}; + +class DRW_Converter +{ +public: + DRW_Converter(const int *t, int l){table = t; + cpLength = l;} + virtual ~DRW_Converter(){} + virtual std::string fromUtf8(std::string *s) {return *s;} + virtual std::string toUtf8(std::string *s); + std::string encodeText(std::string stmp); + std::string decodeText(int c); + std::string encodeNum(int c); + int decodeNum(std::string s, int *b); + const int *table; + int cpLength; +}; + +class DRW_ConvUTF16 : public DRW_Converter { +public: + DRW_ConvUTF16():DRW_Converter(NULL, 0) {} + virtual std::string fromUtf8(std::string *s); + virtual std::string toUtf8(std::string *s); +}; + +class DRW_ConvTable : public DRW_Converter { +public: + DRW_ConvTable(const int *t, int l):DRW_Converter(t, l) {} + virtual std::string fromUtf8(std::string *s); + virtual std::string toUtf8(std::string *s); +}; + +class DRW_ConvDBCSTable : public DRW_Converter { +public: + DRW_ConvDBCSTable(const int *t, const int *lt, const int dt[][2], int l):DRW_Converter(t, l) { + leadTable = lt; + doubleTable = dt; + } + + virtual std::string fromUtf8(std::string *s); + virtual std::string toUtf8(std::string *s); +private: + const int *leadTable; + const int (*doubleTable)[2]; + +}; + +class DRW_Conv932Table : public DRW_Converter { +public: + DRW_Conv932Table(const int *t, const int *lt, const int dt[][2], int l):DRW_Converter(t, l) { + leadTable = lt; + doubleTable = dt; + } + + virtual std::string fromUtf8(std::string *s); + virtual std::string toUtf8(std::string *s); +private: + const int *leadTable; + const int (*doubleTable)[2]; + +}; + +#endif // DRW_TEXTCODEC_H diff --git a/extlib/libdxfrw/intern/dwgbuffer.cpp b/extlib/libdxfrw/intern/dwgbuffer.cpp new file mode 100644 index 0000000..798520d --- /dev/null +++ b/extlib/libdxfrw/intern/dwgbuffer.cpp @@ -0,0 +1,923 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + + +#include "dwgbuffer.h" +#include "../libdwgr.h" +#include "drw_textcodec.h" +#include "drw_dbg.h" +//#include +/*#include +#include +#include +#include "dwgreader.h"*/ +//#include "dxfwriter.h" + + +//#define FIRSTHANDLE 48 + +/*enum sections { + secUnknown, + secHeader, + secTables, + secBlocks, + secEntities, + secObjects +};*/ + +static unsigned int crctable[256]= { +0x0000,0xC0C1,0xC181,0x0140,0xC301,0x03C0,0x0280,0xC241, +0xC601,0x06C0,0x0780,0xC741,0x0500,0xC5C1,0xC481,0x0440, +0xCC01,0x0CC0,0x0D80,0xCD41,0x0F00,0xCFC1,0xCE81,0x0E40, +0x0A00,0xCAC1,0xCB81,0x0B40,0xC901,0x09C0,0x0880,0xC841, +0xD801,0x18C0,0x1980,0xD941,0x1B00,0xDBC1,0xDA81,0x1A40, +0x1E00,0xDEC1,0xDF81,0x1F40,0xDD01,0x1DC0,0x1C80,0xDC41, +0x1400,0xD4C1,0xD581,0x1540,0xD701,0x17C0,0x1680,0xD641, +0xD201,0x12C0,0x1380,0xD341,0x1100,0xD1C1,0xD081,0x1040, +0xF001,0x30C0,0x3180,0xF141,0x3300,0xF3C1,0xF281,0x3240, +0x3600,0xF6C1,0xF781,0x3740,0xF501,0x35C0,0x3480,0xF441, +0x3C00,0xFCC1,0xFD81,0x3D40,0xFF01,0x3FC0,0x3E80,0xFE41, +0xFA01,0x3AC0,0x3B80,0xFB41,0x3900,0xF9C1,0xF881,0x3840, +0x2800,0xE8C1,0xE981,0x2940,0xEB01,0x2BC0,0x2A80,0xEA41, +0xEE01,0x2EC0,0x2F80,0xEF41,0x2D00,0xEDC1,0xEC81,0x2C40, +0xE401,0x24C0,0x2580,0xE541,0x2700,0xE7C1,0xE681,0x2640, +0x2200,0xE2C1,0xE381,0x2340,0xE101,0x21C0,0x2080,0xE041, +0xA001,0x60C0,0x6180,0xA141,0x6300,0xA3C1,0xA281,0x6240, +0x6600,0xA6C1,0xA781,0x6740,0xA501,0x65C0,0x6480,0xA441, +0x6C00,0xACC1,0xAD81,0x6D40,0xAF01,0x6FC0,0x6E80,0xAE41, +0xAA01,0x6AC0,0x6B80,0xAB41,0x6900,0xA9C1,0xA881,0x6840, +0x7800,0xB8C1,0xB981,0x7940,0xBB01,0x7BC0,0x7A80,0xBA41, +0xBE01,0x7EC0,0x7F80,0xBF41,0x7D00,0xBDC1,0xBC81,0x7C40, +0xB401,0x74C0,0x7580,0xB541,0x7700,0xB7C1,0xB681,0x7640, +0x7200,0xB2C1,0xB381,0x7340,0xB101,0x71C0,0x7080,0xB041, +0x5000,0x90C1,0x9181,0x5140,0x9301,0x53C0,0x5280,0x9241, +0x9601,0x56C0,0x5780,0x9741,0x5500,0x95C1,0x9481,0x5440, +0x9C01,0x5CC0,0x5D80,0x9D41,0x5F00,0x9FC1,0x9E81,0x5E40, +0x5A00,0x9AC1,0x9B81,0x5B40,0x9901,0x59C0,0x5880,0x9841, +0x8801,0x48C0,0x4980,0x8941,0x4B00,0x8BC1,0x8A81,0x4A40, +0x4E00,0x8EC1,0x8F81,0x4F40,0x8D01,0x4DC0,0x4C80,0x8C41, +0x4400,0x84C1,0x8581,0x4540,0x8701,0x47C0,0x4680,0x8641, +0x8201,0x42C0,0x4380,0x8341,0x4100,0x81C1,0x8081,0x4040 }; + +static unsigned int crc32Table[256] ={ +0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, +0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, +0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, +0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, +0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, +0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, +0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, +0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, +0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, +0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, +0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, +0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, +0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, +0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, +0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, +0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, +0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, +0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, +0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, +0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, +0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, +0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, +0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, +0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, +0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, +0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, +0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, +0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, +0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, +0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, +0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, +0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; + +union typeCast { + char buf[8]; + duint16 i16; + duint32 i32; + duint64 i64; + ddouble64 d64; +}; + +bool dwgFileStream::setPos(duint64 p){ + if (p >= sz) + return false; + + stream->seekg(p); + return stream->good(); +} + +bool dwgFileStream::read(duint8* s, duint64 n){ + stream->read (reinterpret_cast(s),n); + return stream->good(); +} + +bool dwgCharStream::setPos(duint64 p){ + if (p > size()) { + isOk = false; + return false; + } + + pos = p; + return true; +} + +bool dwgCharStream::read(duint8* s, duint64 n){ + if ( n > (sz - pos) ) { + isOk = false; + return false; + } + for (duint64 i=0; isize(); + bitPos = 0; +} + +dwgBuffer::dwgBuffer( const dwgBuffer& org ){ + filestr = org.filestr->clone(); + decoder = org.decoder; + maxSize = filestr->size(); + currByte = org.currByte; + bitPos = org.bitPos; +} + +dwgBuffer& dwgBuffer::operator=( const dwgBuffer& org ){ + filestr = org.filestr->clone(); + decoder = org.decoder; + maxSize = filestr->size(); + currByte = org.currByte; + bitPos = org.bitPos; + return *this; +} + +dwgBuffer::~dwgBuffer(){ + delete filestr; +} + +/**Gets the current byte position in buffer **/ +duint64 dwgBuffer::getPosition(){ + if (bitPos != 0) + return filestr->getPos() -1; + return filestr->getPos(); + } + +/**Sets the buffer position in pos byte, reset the bit position **/ +bool dwgBuffer::setPosition(duint64 pos){ + bitPos = 0; +/* if (pos>=maxSize) + return false;*/ + return filestr->setPos(pos); +// return true; +} + +//RLZ: Fails if ... ??? +void dwgBuffer::setBitPos(duint8 pos){ + if (pos>7) + return; + if (pos != 0 && bitPos == 0){ + duint8 buffer; + filestr->read (&buffer,1); + currByte = buffer; + } + if (pos == 0 && bitPos != 0){//reset current byte + filestr->setPos(filestr->getPos()-1); + } + bitPos = pos; +} + +bool dwgBuffer::moveBitPos(dint32 size){ + if (size == 0) return true; + + dint32 b= size + bitPos; + filestr->setPos(getPosition() + (b >> 3) ); + bitPos = b & 7; + + if (bitPos != 0){ + filestr->read (&currByte,1); + } + return filestr->good(); +} + +/**Reads one Bit returns a char with value 0/1 (B) **/ +duint8 dwgBuffer::getBit(){ + duint8 buffer; + duint8 ret = 0; + if (bitPos == 0){ + filestr->read (&buffer,1); + currByte = buffer; + } + + ret = (currByte >> (7 - bitPos) & 1); + bitPos +=1; + if (bitPos == 8) + bitPos = 0; + + return ret; +} + +/**Reads one Bit returns a bool value 0==false 1==true (B) **/ +bool dwgBuffer::getBoolBit(){ + return (getBit() != 0); +} + +/**Reads two Bits returns a char (BB) **/ +duint8 dwgBuffer::get2Bits(){ + duint8 buffer; + duint8 ret = 0; + if (bitPos == 0){ + filestr->read (&buffer,1); + currByte = buffer; + } + + bitPos +=2; + if (bitPos < 9) + ret = currByte >>(8 - bitPos); + else {//read one bit per byte + ret = currByte << 1; + filestr->read (&buffer,1); + currByte = buffer; + bitPos = 1; + ret = ret | currByte >> 7; + } + if (bitPos == 8) + bitPos = 0; + ret = ret & 3; + return ret; +} + +/**Reads thee Bits returns a char (3B) **/ +//RLZ: todo verify this +duint8 dwgBuffer::get3Bits(){ + duint8 buffer; + duint8 ret = 0; + if (bitPos == 0){ + filestr->read (&buffer,1); + currByte = buffer; + } + + bitPos +=3; + if (bitPos < 9) + ret = currByte >>(8 - bitPos); + else {//read one bit per byte + ret = currByte << 1; + filestr->read (&buffer,1); + currByte = buffer; + bitPos = 1; + ret = ret | currByte >> 7; + } + if (bitPos == 8) + bitPos = 0; + ret = ret & 7; + return ret; +} + +/**Reads tree Bits returns a char (3B) for R24 **/ +//to be written + +/**Reads compressed Short (max. 16 + 2 bits) little-endian order, returns a UNsigned 16 bits (BS) **/ +duint16 dwgBuffer::getBitShort(){ + duint8 b = get2Bits(); + if (b == 0) + return getRawShort16(); + else if (b== 1) + return getRawChar8(); + else if (b == 2) + return 0; + else + return 256; +} +/**Reads compressed Short (max. 16 + 2 bits) little-endian order, returns a signed 16 bits (BS) **/ +dint16 dwgBuffer::getSBitShort(){ + duint8 b = get2Bits(); + if (b == 0) + return (dint16)getRawShort16(); + else if (b== 1) + return (dint16)getRawChar8(); + else if (b == 2) + return 0; + else + return 256; +} + +/**Reads compressed 32 bits Int (max. 32 + 2 bits) little-endian order, returns a signed 32 bits (BL) **/ +//to be written +dint32 dwgBuffer::getBitLong(){ + dint8 b = get2Bits(); + if (b == 0) + return getRawLong32(); + else if (b== 1) + return getRawChar8(); + else //if (b == 2) + return 0; +} + +/**Reads compressed 64 bits Int (max. 56 + 3 bits) little-endian order, returns a unsigned 64 bits (BLL) **/ +duint64 dwgBuffer::getBitLongLong(){ + dint8 b = get3Bits(); + duint64 ret=0; + for (duint8 i=0; iread (buffer,8); + } + double* ret = reinterpret_cast( buffer ); + return *ret; + } + // if (b == 2) + return 0.0; +} + +/**Reads 3 compressed Double (max. 64 + 2 bits) returns a DRW_Coord of floating point double of 64 bits (3BD) **/ +DRW_Coord dwgBuffer::get3BitDouble(){ + DRW_Coord crd; + crd.x = getBitDouble(); + crd.y = getBitDouble(); + crd.z = getBitDouble(); + return crd; +} + +/**Reads raw char 8 bits returns a unsigned char (RC) **/ +duint8 dwgBuffer::getRawChar8(){ + duint8 ret; + duint8 buffer; + filestr->read (&buffer,1); + if (bitPos == 0) + return buffer; + else { + ret = currByte << bitPos; + currByte = buffer; + ret = ret | (currByte >>(8 - bitPos)); + } + return ret; +} + +/**Reads raw short 16 bits little-endian order, returns a unsigned short (RS) **/ +duint16 dwgBuffer::getRawShort16(){ + duint8 buffer[2]; + duint16 ret; + + filestr->read (buffer,2); + if (bitPos == 0) { + /* no offset directly swap bytes for little-endian */ + ret = (buffer[1] << 8) | (buffer[0] & 0x00FF); + } else { + ret = (buffer[0] << 8) | (buffer[1] & 0x00FF); + /* apply offset */ + ret = ret >> (8 - bitPos); + ret = ret | (currByte << (8 + bitPos)); + currByte = buffer[1]; + /* swap bytes for little-endian */ + ret = (ret << 8) | (ret >> 8); + } + return ret; +} + +/**Reads raw double IEEE standard 64 bits returns a double (RD) **/ +double dwgBuffer::getRawDouble(){ + duint8 buffer[8]; + if (bitPos == 0) + filestr->read (buffer,8); + else { + for (int i = 0; i < 8; i++) + buffer[i] = getRawChar8(); + } + double* nOffset = reinterpret_cast( buffer ); + return *nOffset; +} + +/**Reads 2 raw double IEEE standard 64 bits returns a DRW_Coord of floating point double 64 bits (2RD) **/ +DRW_Coord dwgBuffer::get2RawDouble(){ + DRW_Coord crd; + crd.x = getRawDouble(); + crd.y = getRawDouble(); + return crd; +} + + +/**Reads raw int 32 bits little-endian order, returns a unsigned int (RL) **/ +duint32 dwgBuffer::getRawLong32(){ + duint16 tmp1 = getRawShort16(); + duint16 tmp2 = getRawShort16(); + duint32 ret = (tmp2 << 16) | (tmp1 & 0x0000FFFF); + + return ret; +} + +/**Reads raw int 64 bits little-endian order, returns a unsigned long long (RLL) **/ +duint64 dwgBuffer::getRawLong64(){ + duint32 tmp1 = getRawLong32(); + duint64 tmp2 = getRawLong32(); + duint64 ret = (tmp2 << 32) | (tmp1 & 0x00000000FFFFFFFF); + + return ret; +} + +/**Reads modular unsigner int, char based, compressed form, little-endian order, returns a unsigned int (U-MC) **/ +duint32 dwgBuffer::getUModularChar(){ + std::vector buffer; + duint32 result =0; + for (int i=0; i<4;i++){ + duint8 b= getRawChar8(); + buffer.push_back(b & 0x7F); + if (! (b & 0x80)) + break; + } + int offset = 0; + for (unsigned int i=0; i buffer; + dint32 result =0; + for (int i=0; i<4;i++){ + duint8 b= getRawChar8(); + buffer.push_back(b & 0x7F); + if (! (b & 0x80)) + break; + } + dint8 b= buffer.back(); + if (b & 0x40) { + negative = true; + buffer.pop_back(); + buffer.push_back(b & 0x3F); + } + + int offset = 0; + for (unsigned int i=0; i buffer; + dint32 result =0; + for (int i=0; i<2;i++){ + duint16 b= getRawShort16(); + buffer.push_back(b & 0x7FFF); + if (! (b & 0x8000)) + break; + } + + //only positive ? +/* dint8 b= buffer.back(); + if (! (b & 0x40)) { + negative = true; + buffer.pop_back(); + buffer.push_back(b & 0x3F); + }*/ + + int offset = 0; + for (unsigned int i=0; i> 4) & 0x0F; + hl.size = data & 0x0F; + hl.ref=0; + for (int i=0; i< hl.size;i++){ + hl.ref = (hl.ref << 8) | getRawChar8(); + } + return hl; +} + +dwgHandle dwgBuffer::getOffsetHandle(duint32 href){ //H + dwgHandle hl = getHandle(); + + if (hl.code > 5){ + if (hl.code == 0x0C) + hl.ref = href - hl.ref; + else if (hl.code == 0x0A) + hl.ref = href + hl.ref; + else if (hl.code == 0x08) + hl.ref = href - 1; + else if (hl.code == 0x06) + hl.ref = href + 1; +//all are soft pointer reference change to 7 (without offset) + hl.code = 7; + } + return hl; +} + +//internal until 2004 +std::string dwgBuffer::get8bitStr(){ + duint16 textSize = getBitShort(); + if (textSize == 0) + return std::string(); + duint8 *tmpBuffer = new duint8[textSize]; + bool good = getBytes(tmpBuffer, textSize); + if (!good) + return std::string(); + +/* filestr->read (buffer,textSize); + if (!filestr->good()) + return std::string(); + + duint8 tmp; + if (bitPos != 0){ + for (int i=0; i> (8 - bitPos)); + currByte = tmp; + } + }*/ + std::string str(reinterpret_cast(tmpBuffer), textSize); + delete[]tmpBuffer; + + return str; +} + +//internal since 2007 //pending: are 2 bytes null terminated?? +//nullTerm = true if string are 2 bytes null terminated from the stream +std::string dwgBuffer::get16bitStr(duint16 textSize, bool nullTerm){ + if (textSize == 0) + return std::string(); + textSize *=2; + duint16 ts = textSize; + if (nullTerm) + ts += 2; + duint8 *tmpBuffer = new duint8[textSize + 2]; + bool good = getBytes(tmpBuffer, ts); + if (!good) + return std::string(); + if (!nullTerm) { + tmpBuffer[textSize] = '\0'; + tmpBuffer[textSize + 1] = '\0'; + } + std::string str(reinterpret_cast(tmpBuffer), ts); + delete[]tmpBuffer; + + return str; +} + +//T 8 bit text converted from codepage to utf8 +std::string dwgBuffer::getCP8Text(){ + std::string strData; + strData = get8bitStr();//RLZ correct these function + if (decoder == NULL) + return strData; + + return decoder->toUtf8(strData); +} + +//TU unicode 16 bit (UCS) text converted to utf8 +/**Reads 2-bytes char (UCS2, NULL terminated) and convert to std::string (only for Latin-1) + ts= total input size in bytes. +**/ +std::string dwgBuffer::getUCSStr(duint16 ts){ + std::string strData; + if (ts<4) //at least 1 char + return std::string(); + strData = get16bitStr(ts/2, false); + if (decoder == NULL) + return strData; + + return decoder->toUtf8(strData); +} + +//TU unicode 16 bit (UCS) text converted to utf8 +//nullTerm = true if string are 2 bytes null terminated from the stream +std::string dwgBuffer::getUCSText(bool nullTerm){ + std::string strData; + duint16 ts = getBitShort(); + if (ts == 0) + return std::string(); + + strData = get16bitStr(ts, nullTerm); + if (decoder == NULL) + return strData; + + return decoder->toUtf8(strData); +} + +//RLZ: read a T or TU if version is 2007+ +//nullTerm = true if string are 2 bytes null terminated from the stream +std::string dwgBuffer::getVariableText(DRW::Version v, bool nullTerm){//TV + if (v > DRW::AC1018) + return getUCSText(nullTerm); + return getCP8Text(); +} +duint16 dwgBuffer::getObjType(DRW::Version v){//OT + if (v > DRW::AC1021) { + duint8 b = get2Bits(); + if (b == 0) + return getRawChar8(); + else if (b== 1){ + return (getRawChar8() + 0x01F0); + } else //b == 2 + return getRawShort16(); + } + return getBitShort(); +} + +/* Bit Extrusion +* For R2000+, this is a single bit, If the single bit is 1, +* the extrusion value is assumed to be 0,0,1 and no explicit +* extrusion is stored. If the single bit is 0, then it will +* be followed by 3BD. +* For R13-R14 this is 3BD. +*/ +DRW_Coord dwgBuffer::getExtrusion(bool b_R2000_style) { + DRW_Coord ext(0.0,0.0,1.0); + if ( b_R2000_style ) + /* If the bit is one, the extrusion value is assumed to be 0,0,1*/ + if ( getBit() == 1 ) + return ext; + /*R13-R14 or bit == 0*/ + ext.x = getBitDouble(); + ext.y = getBitDouble(); + ext.z = getBitDouble(); + return ext; +} + +/**Reads compressed Double with default (max. 64 + 2 bits) returns a floating point double of 64 bits (DD) **/ +double dwgBuffer::getDefaultDouble(double d){ + dint8 b = get2Bits(); + if (b == 0) + return d; + else if (b == 1){ + duint8 buffer[4]; + char *tmp; + if (bitPos != 0) { + for (int i = 0; i < 4; i++) + buffer[i] = getRawChar8(); + } else { + filestr->read (buffer,4); + } + tmp = reinterpret_cast(&d); + for (int i = 0; i < 4; i++) + tmp[i] = buffer[i]; + double ret = *reinterpret_cast( tmp ); + return ret; + } else if (b == 2){ + duint8 buffer[6]; + char *tmp; + if (bitPos != 0) { + for (int i = 0; i < 6; i++) + buffer[i] = getRawChar8(); + } else { + filestr->read (buffer,6); + } + tmp = reinterpret_cast(&d); + for (int i = 2; i < 6; i++) + tmp[i-2] = buffer[i]; + tmp[4] = buffer[0]; + tmp[5] = buffer[1]; + double ret = *reinterpret_cast( tmp ); + return ret; + } + // if (b == 3) return a full raw double + return getRawDouble(); +} + + +/* BitThickness +* For R13-R14, this is a BD. +* For R2000+, this is a single bit, If the bit is one, +* the thickness value is assumed to be 0.0, if not a BD follow +*/ +double dwgBuffer::getThickness(bool b_R2000_style) { + if ( b_R2000_style ) + /* If the bit is one, the thickness value is assumed to be 0.0.*/ + if ( getBit() == 1 ) + return 0.0; + /*R13-R14 or bit == 0*/ + return getBitDouble(); +} + +/* CmColor (CMC) +* For R15 and earlier call directly BS as ACIS color. +* For R2004+, can be CMC or ENC +* RGB value, first 4bits 0xC0 => ByLayer, 0xC1 => ByBlock, 0xC2 => RGB, 0xC3 => last 4 are ACIS +*/ +duint32 dwgBuffer::getCmColor(DRW::Version v) { + if (v < DRW::AC1018) //2000- + return getSBitShort(); + duint16 idx = getBitShort(); + duint32 rgb = getBitLong(); + duint8 cb = getRawChar8(); + duint8 type = rgb >> 24; + DRW_DBG("\ntype COLOR: "); DRW_DBGH(type); + DRW_DBG("\nindex COLOR: "); DRW_DBGH(idx); + DRW_DBG("\nRGB COLOR: "); DRW_DBGH(rgb); + DRW_DBG("\nbyte COLOR: "); DRW_DBGH(cb); + if (cb&1){ + std::string colorName = getVariableText(v, false); + DRW_DBG("\ncolorName: "); DRW_DBG(colorName); + } + if (cb&2){ + std::string bookName = getVariableText(v, false); + DRW_DBG("\nbookName: "); DRW_DBG(bookName); + } + switch (type) { + case 0xC0: + return 256;//ByLayer + break; + case 0xC1: + return 0;//ByBlock + break; + case 0xC2: + return 256;//RGB RLZ TODO + break; + case 0xC3: + return rgb&0xFF;//ACIS + break; + default: + break; + } + //check cb if strings follows RLZ TODO + return 256; //default return ByLayer +} + +/* EnColor (ENC) +* For R15 and earlier call directly BS as ACIS color. +* For R2004+, can be CMC or ENC +* RGB value, first 4bits 0xC0 => ByLayer, 0xC1 => ByBlock, 0xC2 => RGB, 0xC3 => last 4 are ACIS +*/ +duint32 dwgBuffer::getEnColor(DRW::Version v) { + if (v < DRW::AC1018) //2000- + return getSBitShort(); + duint32 rgb = 0; + duint32 cb = 0; + duint16 idx = getBitShort(); + DRW_DBG("idx reads COLOR: "); DRW_DBGH(idx); + duint16 flags = idx>>8; + idx = idx & 0x1FF; //RLZ: warning this is correct? + DRW_DBG("\nflag COLOR: "); DRW_DBGH(flags); + DRW_DBG(", index COLOR: "); DRW_DBGH(idx); +// if (flags & 0x80) { +// rgb = getBitLong(); +// DRW_DBG("\nRGB COLOR: "); DRW_DBGH(rgb); +// } + if (flags & 0x20) { + cb = getBitLong(); + DRW_DBG("\nTransparency COLOR: "); DRW_DBGH(cb); + } + if (flags & 0x40) + DRW_DBG("\nacdbColor COLOR are present"); + else { + if (flags & 0x80) { + rgb = getBitLong(); + DRW_DBG("\nRGB COLOR: "); DRW_DBGH(rgb); + } + } + +/* if (flags & 0x80) + return getBitLong();*/ + + return idx; //default return ByLayer +} + + +/**Reads raw short 16 bits big-endian order, returns a unsigned short crc & size **/ +duint16 dwgBuffer::getBERawShort16(){ + char buffer[2]; + buffer[0] = getRawChar8(); + buffer[1] = getRawChar8(); + duint16 size = (buffer[0] << 8) | (buffer[1] & 0xFF); + return size; +} + +/* reads "size" bytes and stores in "buf" return false if fail */ +bool dwgBuffer::getBytes(unsigned char *buf, int size){ + duint8 tmp; + filestr->read (buf,size); + if (!filestr->good()) + return false; + + if (bitPos != 0){ + for (int i=0; i> (8 - bitPos)); + currByte = tmp; + } + } + return true; +} + +duint16 dwgBuffer::crc8(duint16 dx,dint32 start,dint32 end){ + int pos = filestr->getPos(); + filestr->setPos(start); + int n = end-start; + duint8 *tmpBuf = new duint8[n]; + duint8 *p = tmpBuf; + filestr->read (tmpBuf,n); + filestr->setPos(pos); + if (!filestr->good()) + return 0; + + duint8 al; + + while (n-- > 0) { + al = (duint8)((*p) ^ ((dint8)(dx & 0xFF))); + dx = (dx>>8) & 0xFF; + dx = dx ^ crctable[al & 0xFF]; + p++; + } + delete[]tmpBuf; + return(dx); +} + +duint32 dwgBuffer::crc32(duint32 seed,dint32 start,dint32 end){ + int pos = filestr->getPos(); + filestr->setPos(start); + int n = end-start; + duint8 *tmpBuf = new duint8[n]; + duint8 *p = tmpBuf; + filestr->read (tmpBuf,n); + filestr->setPos(pos); + if (!filestr->good()) + return 0; + + duint32 invertedCrc = ~seed; + while (n-- > 0) { + duint8 data = *p++; + invertedCrc = (invertedCrc >> 8) ^ crc32Table[(invertedCrc ^ data) & 0xff]; + } + delete[]tmpBuf; + return ~invertedCrc; +} + + +/*std::string dwgBuffer::getBytes(int size){ + char buffer[size]; + char tmp; + filestr->read (buffer,size); + if (!filestr->good()) + return NULL; + + if (bitPos != 0){ + for (int i=0; i<=size;i++){ + tmp = buffer[i]; + buffer[i] = (currByte << bitPos) | (tmp >> (8 - bitPos)); + currByte = tmp; + } + } + std::string st; + for (int i=0; i. ** +******************************************************************************/ + +#ifndef DWGBUFFER_H +#define DWGBUFFER_H + +#include +#include +#include "../drw_base.h" + +class DRW_Coord; +class DRW_TextCodec; + +class dwgBasicStream{ +protected: + dwgBasicStream(){} +public: + virtual ~dwgBasicStream(){} + virtual bool read(duint8* s, duint64 n) = 0; + virtual duint64 size() = 0; + virtual duint64 getPos() = 0; + virtual bool setPos(duint64 p) = 0; + virtual bool good() = 0; + virtual dwgBasicStream* clone() = 0; +}; + +class dwgFileStream: public dwgBasicStream{ +public: + dwgFileStream(std::istream *s){ + stream =s; + stream->seekg (0, std::ios::end); + sz = stream->tellg(); + stream->seekg(0, std::ios_base::beg); + } + virtual ~dwgFileStream(){} + virtual bool read(duint8* s, duint64 n); + virtual duint64 size(){return sz;} + virtual duint64 getPos(){return stream->tellg();} + virtual bool setPos(duint64 p); + virtual bool good(){return stream->good();} + virtual dwgBasicStream* clone(){return new dwgFileStream(stream);} +private: + std::istream *stream; + duint64 sz; +}; + +class dwgCharStream: public dwgBasicStream{ +public: + dwgCharStream(duint8 *buf, int s){ + stream =buf; + sz = s; + pos = 0; + isOk = true; + } + virtual ~dwgCharStream(){} + virtual bool read(duint8* s, duint64 n); + virtual duint64 size(){return sz;} + virtual duint64 getPos(){return pos;} + virtual bool setPos(duint64 p); + virtual bool good(){return isOk;} + virtual dwgBasicStream* clone(){return new dwgCharStream(stream, sz);} +private: + duint8 *stream; + duint64 sz; + duint64 pos; + bool isOk; +}; + +class dwgBuffer { +public: + dwgBuffer(std::istream *stream, DRW_TextCodec *decoder = NULL); + dwgBuffer(duint8 *buf, int size, DRW_TextCodec *decoder= NULL); + dwgBuffer( const dwgBuffer& org ); + dwgBuffer& operator=( const dwgBuffer& org ); + ~dwgBuffer(); + duint64 size(){return filestr->size();} + bool setPosition(duint64 pos); + duint64 getPosition(); + void resetPosition(){setPosition(0); setBitPos(0);} + void setBitPos(duint8 pos); + duint8 getBitPos(){return bitPos;} + bool moveBitPos(dint32 size); + + duint8 getBit(); //B + bool getBoolBit(); //B as bool + duint8 get2Bits(); //BB + duint8 get3Bits(); //3B + duint16 getBitShort(); //BS + dint16 getSBitShort(); //BS + dint32 getBitLong(); //BL + duint64 getBitLongLong(); //BLL (R24) + double getBitDouble(); //BD + //2BD => call BD 2 times + DRW_Coord get3BitDouble(); //3BD + duint8 getRawChar8(); //RC + duint16 getRawShort16(); //RS + double getRawDouble(); //RD + duint32 getRawLong32(); //RL + duint64 getRawLong64(); //RLL + DRW_Coord get2RawDouble(); //2RD + //3RD => call RD 3 times + duint32 getUModularChar(); //UMC, unsigned for offsets in 1015 + dint32 getModularChar(); //MC + dint32 getModularShort(); //MS + dwgHandle getHandle(); //H + dwgHandle getOffsetHandle(duint32 href); //H converted to hard + UTF8STRING getVariableText(DRW::Version v, bool nullTerm = true); //TV => call TU for 2007+ or T for previous versions + UTF8STRING getCP8Text(); //T 8 bit text converted from codepage to utf8 + UTF8STRING getUCSText(bool nullTerm = true); //TU unicode 16 bit (UCS) text converted to utf8 + UTF8STRING getUCSStr(duint16 ts); + + duint16 getObjType(DRW::Version v); //OT + + //X, U, SN, + + DRW_Coord getExtrusion(bool b_R2000_style); //BE + double getDefaultDouble(double d); //DD + double getThickness(bool b_R2000_style);//BT + //3DD + duint32 getCmColor(DRW::Version v); //CMC + duint32 getEnColor(DRW::Version v); //ENC + //TC + + duint16 getBERawShort16(); //RS big-endian order + + bool isGood(){return filestr->good();} + bool getBytes(duint8 *buf, int size); + int numRemainingBytes(){return (maxSize- filestr->getPos());} + + duint16 crc8(duint16 dx,dint32 start,dint32 end); + duint32 crc32(duint32 seed,dint32 start,dint32 end); + +// duint8 getCurrByte(){return currByte;} + DRW_TextCodec *decoder; + +private: + dwgBasicStream *filestr; + int maxSize; + duint8 currByte; + duint8 bitPos; + + UTF8STRING get8bitStr(); + UTF8STRING get16bitStr(duint16 textSize, bool nullTerm = true); +}; + +#endif // DWGBUFFER_H diff --git a/extlib/libdxfrw/intern/dwgreader.cpp b/extlib/libdxfrw/intern/dwgreader.cpp new file mode 100644 index 0000000..da6ac35 --- /dev/null +++ b/extlib/libdxfrw/intern/dwgreader.cpp @@ -0,0 +1,1294 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "dwgreader.h" +#include "drw_textcodec.h" +#include "drw_dbg.h" + +dwgReader::~dwgReader(){ + for (std::map::iterator it=ltypemap.begin(); it!=ltypemap.end(); ++it) + delete(it->second); + for (std::map::iterator it=layermap.begin(); it!=layermap.end(); ++it) + delete(it->second); + for (std::map::iterator it=blockmap.begin(); it!=blockmap.end(); ++it) + delete(it->second); + for (std::map::iterator it=stylemap.begin(); it!=stylemap.end(); ++it) + delete(it->second); + for (std::map::iterator it=dimstylemap.begin(); it!=dimstylemap.end(); ++it) + delete(it->second); + for (std::map::iterator it=vportmap.begin(); it!=vportmap.end(); ++it) + delete(it->second); + for (std::map::iterator it=classesmap.begin(); it!=classesmap.end(); ++it) + delete(it->second); + for (std::map::iterator it=blockRecordmap.begin(); it!=blockRecordmap.end(); ++it) + delete(it->second); + for (std::map::iterator it=appIdmap.begin(); it!=appIdmap.end(); ++it) + delete(it->second); + + delete fileBuf; +} + +void dwgReader::parseAttribs(DRW_Entity* e){ + if (e != NULL){ + duint32 ltref =e->lTypeH.ref; + duint32 lyref =e->layerH.ref; + std::map::iterator lt_it = ltypemap.find(ltref); + if (lt_it != ltypemap.end()){ + e->lineType = (lt_it->second)->name; + } + std::map::iterator ly_it = layermap.find(lyref); + if (ly_it != layermap.end()){ + e->layer = (ly_it->second)->name; + } + } +} + +std::string dwgReader::findTableName(DRW::TTYPE table, dint32 handle){ + std::string name; + switch (table){ + case DRW::STYLE:{ + std::map::iterator st_it = stylemap.find(handle); + if (st_it != stylemap.end()) + name = (st_it->second)->name; + break;} + case DRW::DIMSTYLE:{ + std::map::iterator ds_it = dimstylemap.find(handle); + if (ds_it != dimstylemap.end()) + name = (ds_it->second)->name; + break;} + case DRW::BLOCK_RECORD:{ //use DRW_Block because name are more correct +// std::map::iterator bk_it = blockmap.find(handle); +// if (bk_it != blockmap.end()) + std::map::iterator bk_it = blockRecordmap.find(handle); + if (bk_it != blockRecordmap.end()) + name = (bk_it->second)->name; + break;} +/* case DRW::VPORT:{ + std::map::iterator vp_it = vportmap.find(handle); + if (vp_it != vportmap.end()) + name = (vp_it->second)->name; + break;}*/ + case DRW::LAYER:{ + std::map::iterator ly_it = layermap.find(handle); + if (ly_it != layermap.end()) + name = (ly_it->second)->name; + break;} + case DRW::LTYPE:{ + std::map::iterator lt_it = ltypemap.find(handle); + if (lt_it != ltypemap.end()) + name = (lt_it->second)->name; + break;} + default: + break; + } + return name; +} + +bool dwgReader::readDwgHeader(DRW_Header& hdr, dwgBuffer *buf, dwgBuffer *hBuf){ + bool ret = hdr.parseDwg(version, buf, hBuf, maintenanceVersion); + //RLZ: copy objectControl handles + return ret; +} + +//RLZ: TODO add check instead print +bool dwgReader::checkSentinel(dwgBuffer *buf, enum secEnum::DWGSection, bool start){ + DRW_UNUSED(start); + for (int i=0; i<16;i++) { + DRW_DBGH(buf->getRawChar8()); DRW_DBG(" "); + } + return true; +} + +/*********** objects map ************************/ +/** Note: object map are split in sections with max size 2035? + * heach section are 2 bytes size + data bytes + 2 bytes crc + * size value are data bytes + 2 and to calculate crc are used + * 2 bytes size + data bytes + * last section are 2 bytes size + 2 bytes crc (size value always 2) +**/ +bool dwgReader::readDwgHandles(dwgBuffer *dbuf, duint32 offset, duint32 size) { + DRW_DBG("\ndwgReader::readDwgHandles\n"); + if (!dbuf->setPosition(offset)) + return false; + + duint32 maxPos = offset + size; + DRW_DBG("\nSection HANDLES offset= "); DRW_DBG(offset); + DRW_DBG("\nSection HANDLES size= "); DRW_DBG(size); + DRW_DBG("\nSection HANDLES maxPos= "); DRW_DBG(maxPos); + + int startPos = offset; + + while (maxPos > dbuf->getPosition()) { + DRW_DBG("\nstart handles section buf->curPosition()= "); DRW_DBG(dbuf->getPosition()); DRW_DBG("\n"); + duint16 size = dbuf->getBERawShort16(); + DRW_DBG("object map section size= "); DRW_DBG(size); DRW_DBG("\n"); + dbuf->setPosition(startPos); + duint8 *tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + if (size != 2){ + buff.setPosition(2); + int lastHandle = 0; + int lastLoc = 0; + //read data + while(buff.getPosition()< size){ + lastHandle += buff.getUModularChar(); + DRW_DBG("object map lastHandle= "); DRW_DBGH(lastHandle); + lastLoc += buff.getModularChar(); + DRW_DBG(" lastLoc= "); DRW_DBG(lastLoc); DRW_DBG("\n"); + ObjectMap[lastHandle]= objHandle(0, lastHandle, lastLoc); + } + } + //verify crc + duint16 crcCalc = buff.crc8(0xc0c1,0,size); + delete[]tmpByteStr; + duint16 crcRead = dbuf->getBERawShort16(); + DRW_DBG("object map section crc8 read= "); DRW_DBG(crcRead); + DRW_DBG("\nobject map section crc8 calculated= "); DRW_DBG(crcCalc); + DRW_DBG("\nobject section buf->curPosition()= "); DRW_DBG(dbuf->getPosition()); DRW_DBG("\n"); + startPos = dbuf->getPosition(); + } + + bool ret = dbuf->isGood(); + return ret; +} + +/*********** objects ************************/ +/** + * Reads all the object referenced in the object map section of the DWG file + * (using their object file offsets) + */ +bool dwgReader::readDwgTables(DRW_Header& hdr, dwgBuffer *dbuf) { + DRW_DBG("\ndwgReader::readDwgTables start\n"); + bool ret = true; + bool ret2 = true; + objHandle oc; + std::map::iterator mit; + dint16 oType; + duint32 bs = 0; //bit size of handle stream 2010+ + duint8 *tmpByteStr; + + //parse linetypes, start with linetype Control + mit = ObjectMap.find(hdr.linetypeCtrl); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: LineType control not found\n"); + ret = false; + } else { + DRW_DBG("\n**********Parsing LineType control*******\n"); + oc = mit->second; + ObjectMap.erase(mit); + DRW_ObjControl ltControl; + dbuf->setPosition(oc.loc); + int csize = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[csize]; + dbuf->getBytes(tmpByteStr, csize); + dwgBuffer cbuff(tmpByteStr, csize, &decoder); + //verify if object are correct + oType = cbuff.getObjType(version); + if (oType != 0x38) { + DRW_DBG("\nWARNING: Not LineType control object, found oType "); + DRW_DBG(oType); DRW_DBG(" instead 0x38\n"); + ret = false; + } else { //reset position + cbuff.resetPosition(); + ret2 = ltControl.parseDwg(version, &cbuff, bs); + if(ret) + ret = ret2; + } + delete[]tmpByteStr; + for (std::list::iterator it=ltControl.hadlesList.begin(); it != ltControl.hadlesList.end(); ++it){ + mit = ObjectMap.find(*it); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: LineType not found\n"); + ret = false; + } else { + oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("\nLineType Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" loc.: "); DRW_DBG(oc.loc); DRW_DBG("\n"); + DRW_LType *lt = new DRW_LType(); + dbuf->setPosition(oc.loc); + int lsize = dbuf->getModularShort(); + DRW_DBG("LineType size in bytes= "); DRW_DBG(lsize); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[lsize]; + dbuf->getBytes(tmpByteStr, lsize); + dwgBuffer lbuff(tmpByteStr, lsize, &decoder); + ret2 = lt->parseDwg(version, &lbuff, bs); + ltypemap[lt->handle] = lt; + if(ret) + ret = ret2; + delete[]tmpByteStr; + } + } + } + + //parse layers, start with layer Control + mit = ObjectMap.find(hdr.layerCtrl); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: Layer control not found\n"); + ret = false; + } else { + DRW_DBG("\n**********Parsing Layer control*******\n"); + oc = mit->second; + ObjectMap.erase(mit); + DRW_ObjControl layControl; + dbuf->setPosition(oc.loc); + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + //verify if object are correct + oType = buff.getObjType(version); + if (oType != 0x32) { + DRW_DBG("\nWARNING: Not Layer control object, found oType "); + DRW_DBG(oType); DRW_DBG(" instead 0x32\n"); + ret = false; + } else { //reset position + buff.resetPosition(); + ret2 = layControl.parseDwg(version, &buff, bs); + if(ret) + ret = ret2; + } + delete[]tmpByteStr; + for (std::list::iterator it=layControl.hadlesList.begin(); it != layControl.hadlesList.end(); ++it){ + mit = ObjectMap.find(*it); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: Layer not found\n"); + ret = false; + } else { + oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("Layer Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n"); + DRW_Layer *la = new DRW_Layer(); + dbuf->setPosition(oc.loc); + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + ret2 = la->parseDwg(version, &buff, bs); + layermap[la->handle] = la; + if(ret) + ret = ret2; + delete[]tmpByteStr; + } + } + } + + //set linetype in layer + for (std::map::iterator it=layermap.begin(); it!=layermap.end(); ++it) { + DRW_Layer *ly = it->second; + duint32 ref =ly->lTypeH.ref; + std::map::iterator lt_it = ltypemap.find(ref); + if (lt_it != ltypemap.end()){ + ly->lineType = (lt_it->second)->name; + } + } + + //parse text styles, start with style Control + mit = ObjectMap.find(hdr.styleCtrl); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: Style control not found\n"); + ret = false; + } else { + DRW_DBG("\n**********Parsing Style control*******\n"); + oc = mit->second; + ObjectMap.erase(mit); + DRW_ObjControl styControl; + dbuf->setPosition(oc.loc); + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + //verify if object are correct + oType = buff.getObjType(version); + if (oType != 0x34) { + DRW_DBG("\nWARNING: Not Text Style control object, found oType "); + DRW_DBG(oType); DRW_DBG(" instead 0x34\n"); + ret = false; + } else { //reset position + buff.resetPosition(); + ret2 = styControl.parseDwg(version, &buff, bs); + if(ret) + ret = ret2; + } + delete[]tmpByteStr; + for (std::list::iterator it=styControl.hadlesList.begin(); it != styControl.hadlesList.end(); ++it){ + mit = ObjectMap.find(*it); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: Style not found\n"); + ret = false; + } else { + oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("Style Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n"); + DRW_Textstyle *sty = new DRW_Textstyle(); + dbuf->setPosition(oc.loc); + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + ret2 = sty->parseDwg(version, &buff, bs); + stylemap[sty->handle] = sty; + if(ret) + ret = ret2; + delete[]tmpByteStr; + } + } + } + + //parse dim styles, start with dimstyle Control + mit = ObjectMap.find(hdr.dimstyleCtrl); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: Dimension Style control not found\n"); + ret = false; + } else { + DRW_DBG("\n**********Parsing Dimension Style control*******\n"); + oc = mit->second; + ObjectMap.erase(mit); + DRW_ObjControl dimstyControl; + dbuf->setPosition(oc.loc); + duint32 size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + //verify if object are correct + oType = buff.getObjType(version); + if (oType != 0x44) { + DRW_DBG("\nWARNING: Not Dim Style control object, found oType "); + DRW_DBG(oType); DRW_DBG(" instead 0x44\n"); + ret = false; + } else { //reset position + buff.resetPosition(); + ret2 = dimstyControl.parseDwg(version, &buff, bs); + if(ret) + ret = ret2; + } + delete[]tmpByteStr; + for (std::list::iterator it=dimstyControl.hadlesList.begin(); it != dimstyControl.hadlesList.end(); ++it){ + mit = ObjectMap.find(*it); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: Dimension Style not found\n"); + ret = false; + } else { + oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("Dimstyle Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n"); + DRW_Dimstyle *sty = new DRW_Dimstyle(); + dbuf->setPosition(oc.loc); + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + ret2 = sty->parseDwg(version, &buff, bs); + dimstylemap[sty->handle] = sty; + if(ret) + ret = ret2; + delete[]tmpByteStr; + } + } + } + + //parse vports, start with vports Control + mit = ObjectMap.find(hdr.vportCtrl); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: vports control not found\n"); + ret = false; + } else { + DRW_DBG("\n**********Parsing vports control*******\n"); + oc = mit->second; + ObjectMap.erase(mit); + DRW_ObjControl vportControl; + dbuf->setPosition(oc.loc); + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + //verify if object are correct + oType = buff.getObjType(version); + if (oType != 0x40) { + DRW_DBG("\nWARNING: Not VPorts control object, found oType: "); + DRW_DBG(oType); DRW_DBG(" instead 0x40\n"); + ret = false; + } else { //reset position + buff.resetPosition(); + ret2 = vportControl.parseDwg(version, &buff, bs); + if(ret) + ret = ret2; + } + delete[]tmpByteStr; + for (std::list::iterator it=vportControl.hadlesList.begin(); it != vportControl.hadlesList.end(); ++it){ + mit = ObjectMap.find(*it); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: vport not found\n"); + ret = false; + } else { + oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("Vport Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n"); + DRW_Vport *vp = new DRW_Vport(); + dbuf->setPosition(oc.loc); + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + ret2 = vp->parseDwg(version, &buff, bs); + vportmap[vp->handle] = vp; + if(ret) + ret = ret2; + delete[]tmpByteStr; + } + } + } + + //parse Block_records , start with Block_record Control + mit = ObjectMap.find(hdr.blockCtrl); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: Block_record control not found\n"); + ret = false; + } else { + DRW_DBG("\n**********Parsing Block_record control*******\n"); + oc = mit->second; + ObjectMap.erase(mit); + DRW_ObjControl blockControl; + dbuf->setPosition(oc.loc); + int csize = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[csize]; + dbuf->getBytes(tmpByteStr, csize); + dwgBuffer buff(tmpByteStr, csize, &decoder); + //verify if object are correct + oType = buff.getObjType(version); + if (oType != 0x30) { + DRW_DBG("\nWARNING: Not Block Record control object, found oType "); + DRW_DBG(oType); DRW_DBG(" instead 0x30\n"); + ret = false; + } else { //reset position + buff.resetPosition(); + ret2 = blockControl.parseDwg(version, &buff, bs); + if(ret) + ret = ret2; + } + delete[]tmpByteStr; + for (std::list::iterator it=blockControl.hadlesList.begin(); it != blockControl.hadlesList.end(); ++it){ + mit = ObjectMap.find(*it); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: block record not found\n"); + ret = false; + } else { + oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("block record Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n"); + DRW_Block_Record *br = new DRW_Block_Record(); + dbuf->setPosition(oc.loc); + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + ret2 = br->parseDwg(version, &buff, bs); + blockRecordmap[br->handle] = br; + if(ret) + ret = ret2; + delete[]tmpByteStr; + } + } + } + + //parse appId , start with appId Control + mit = ObjectMap.find(hdr.appidCtrl); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: AppId control not found\n"); + ret = false; + } else { + DRW_DBG("\n**********Parsing AppId control*******\n"); + oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("AppId Control Obj Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n"); + DRW_ObjControl appIdControl; + dbuf->setPosition(oc.loc); + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + //verify if object are correct + oType = buff.getObjType(version); + if (oType != 0x42) { + DRW_DBG("\nWARNING: Not AppId control object, found oType "); + DRW_DBG(oType); DRW_DBG(" instead 0x42\n"); + ret = false; + } else { //reset position + buff.resetPosition(); + ret2 = appIdControl.parseDwg(version, &buff, bs); + if(ret) + ret = ret2; + } + delete[]tmpByteStr; + for (std::list::iterator it=appIdControl.hadlesList.begin(); it != appIdControl.hadlesList.end(); ++it){ + mit = ObjectMap.find(*it); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: AppId not found\n"); + ret = false; + } else { + oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("AppId Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n"); + DRW_AppId *ai = new DRW_AppId(); + dbuf->setPosition(oc.loc); + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + ret2 = ai->parseDwg(version, &buff, bs); + appIdmap[ai->handle] = ai; + if(ret) + ret = ret2; + delete[]tmpByteStr; + } + } + } + + //RLZ: parse remaining object controls, TODO: implement all + if (DRW_DBGGL == DRW_dbg::DEBUG){ + mit = ObjectMap.find(hdr.viewCtrl); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: View control not found\n"); + ret = false; + } else { + DRW_DBG("\n**********Parsing View control*******\n"); + oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("View Control Obj Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n"); + DRW_ObjControl viewControl; + dbuf->setPosition(oc.loc); + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + //verify if object are correct + oType = buff.getObjType(version); + if (oType != 0x3C) { + DRW_DBG("\nWARNING: Not View control object, found oType "); + DRW_DBG(oType); DRW_DBG(" instead 0x3C\n"); + ret = false; + } else { //reset position + buff.resetPosition(); + ret2 = viewControl.parseDwg(version, &buff, bs); + if(ret) + ret = ret2; + } + delete[]tmpByteStr; + } + + mit = ObjectMap.find(hdr.ucsCtrl); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: Ucs control not found\n"); + ret = false; + } else { + oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("\n**********Parsing Ucs control*******\n"); + DRW_DBG("Ucs Control Obj Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n"); + DRW_ObjControl ucsControl; + dbuf->setPosition(oc.loc); + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + //verify if object are correct + oType = buff.getObjType(version); + if (oType != 0x3E) { + DRW_DBG("\nWARNING: Not Ucs control object, found oType "); + DRW_DBG(oType); DRW_DBG(" instead 0x3E\n"); + ret = false; + } else { //reset position + buff.resetPosition(); + ret2 = ucsControl.parseDwg(version, &buff, bs); + if(ret) + ret = ret2; + } + delete[]tmpByteStr; + } + + if (version < DRW::AC1018) {//r2000- + mit = ObjectMap.find(hdr.vpEntHeaderCtrl); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: vpEntHeader control not found\n"); + ret = false; + } else { + DRW_DBG("\n**********Parsing vpEntHeader control*******\n"); + oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("vpEntHeader Control Obj Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" "); DRW_DBG(oc.loc); DRW_DBG("\n"); + DRW_ObjControl vpEntHeaderCtrl; + dbuf->setPosition(oc.loc); + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + //verify if object are correct + oType = buff.getObjType(version); + if (oType != 0x46) { + DRW_DBG("\nWARNING: Not vpEntHeader control object, found oType "); + DRW_DBG(oType); DRW_DBG(" instead 0x46\n"); + ret = false; + } else { //reset position + buff.resetPosition(); +/* RLZ: writeme ret2 = vpEntHeader.parseDwg(version, &buff, bs); + if(ret) + ret = ret2;*/ + } + delete[]tmpByteStr; + } + } + } + + return ret; +} + +bool dwgReader::readDwgBlocks(DRW_Interface& intfa, dwgBuffer *dbuf){ + bool ret = true; + bool ret2 = true; + duint32 bs =0; + duint8 *tmpByteStr; + std::map::iterator mit; + DRW_DBG("\nobject map total size= "); DRW_DBG(ObjectMap.size()); + + for (std::map::iterator it=blockRecordmap.begin(); it != blockRecordmap.end(); ++it){ + DRW_Block_Record* bkr= it->second; + DRW_DBG("\nParsing Block, record handle= "); DRW_DBGH(it->first); DRW_DBG(" Name= "); DRW_DBG(bkr->name); DRW_DBG("\n"); + DRW_DBG("\nFinding Block, handle= "); DRW_DBGH(bkr->block); DRW_DBG("\n"); + mit = ObjectMap.find(bkr->block); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: block entity not found\n"); + ret = false; + continue; + } + objHandle oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("Block Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" Location: "); DRW_DBG(oc.loc); DRW_DBG("\n"); + if ( !(dbuf->setPosition(oc.loc)) ){ + DRW_DBG("Bad Location reading blocks\n"); + ret = false; + continue; + } + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + DRW_Block bk; + ret2 = bk.parseDwg(version, &buff, bs); + delete[]tmpByteStr; + ret = ret && ret2; + parseAttribs(&bk); + //complete block entity with block record data + bk.basePoint = bkr->basePoint; + bk.flags = bkr->flags; + intfa.addBlock(bk); + //and update block record name + bkr->name = bk.name; + + /**read & send block entities**/ + // in dwg code 330 are not set like dxf in ModelSpace & PaperSpace, set it (RLZ: only tested in 2000) + if (bk.parentHandle == DRW::NoHandle) { + // in dwg code 330 are not set like dxf in ModelSpace & PaperSpace, set it + bk.parentHandle= bkr->handle; + //and do not send block entities like dxf + } else { + if (version < DRW::AC1018) { //pre 2004 + duint32 nextH = bkr->firstEH; + while (nextH != 0){ + mit = ObjectMap.find(nextH); + if (mit==ObjectMap.end()) { + nextH = bkr->lastEH;//end while if entity not foud + DRW_DBG("\nWARNING: Entity of block not found\n"); + ret = false; + continue; + } else {//foud entity reads it + oc = mit->second; + ObjectMap.erase(mit); + ret2 = readDwgEntity(dbuf, oc, intfa); + ret = ret && ret2; + } + if (nextH == bkr->lastEH) + nextH = 0; //redundant, but prevent read errors + else + nextH = nextEntLink; + } + } else {//2004+ + for (std::vector::iterator it = bkr->entMap.begin() ; it != bkr->entMap.end(); ++it){ + duint32 nextH = *it; + mit = ObjectMap.find(nextH); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: Entity of block not found\n"); + ret = false; + continue; + } else {//foud entity reads it + oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("\nBlocks, parsing entity: "); DRW_DBGH(oc.handle); DRW_DBG(", pos: "); DRW_DBG(oc.loc); DRW_DBG("\n"); + ret2 = readDwgEntity(dbuf, oc, intfa); + ret = ret && ret2; + } + } + }//end 2004+ + } + + //end block entity, really needed to parse a dummy entity?? + mit = ObjectMap.find(bkr->endBlock); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: end block entity not found\n"); + ret = false; + continue; + } + oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("End block Handle= "); DRW_DBGH(oc.handle); DRW_DBG(" Location: "); DRW_DBG(oc.loc); DRW_DBG("\n"); + dbuf->setPosition(oc.loc); + size = dbuf->getModularShort(); + if (version > DRW::AC1021) //2010+ + bs = dbuf->getUModularChar(); + else + bs = 0; + tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff1(tmpByteStr, size, &decoder); + DRW_Block end; + end.isEnd = true; + ret2 = end.parseDwg(version, &buff1, bs); + delete[]tmpByteStr; + ret = ret && ret2; + if (bk.parentHandle == DRW::NoHandle) bk.parentHandle= bkr->handle; + parseAttribs(&end); + intfa.endBlock(); + } + + return ret; +} + +bool dwgReader::readPlineVertex(DRW_Polyline& pline, dwgBuffer *dbuf){ + bool ret = true; + bool ret2 = true; + objHandle oc; + duint32 bs = 0; + std::map::iterator mit; + + if (version < DRW::AC1018) { //pre 2004 + duint32 nextH = pline.firstEH; + while (nextH != 0){ + mit = ObjectMap.find(nextH); + if (mit==ObjectMap.end()) { + nextH = pline.lastEH;//end while if entity not foud + DRW_DBG("\nWARNING: pline vertex not found\n"); + ret = false; + continue; + } else {//foud entity reads it + oc = mit->second; + ObjectMap.erase(mit); + DRW_Vertex vt; + dbuf->setPosition(oc.loc); + //RLZ: verify if pos is ok + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) {//2010+ + bs = dbuf->getUModularChar(); + } + duint8 *tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + dint16 oType = buff.getObjType(version); + buff.resetPosition(); + DRW_DBG(" object type= "); DRW_DBG(oType); DRW_DBG("\n"); + ret2 = vt.parseDwg(version, &buff, bs, pline.basePoint.z); + delete[]tmpByteStr; + pline.addVertex(vt); + nextEntLink = vt.nextEntLink; \ + prevEntLink = vt.prevEntLink; + ret = ret && ret2; + } + if (nextH == pline.lastEH) + nextH = 0; //redundant, but prevent read errors + else + nextH = nextEntLink; + } + } else {//2004+ + for (std::list::iterator it = pline.hadlesList.begin() ; it != pline.hadlesList.end(); ++it){ + duint32 nextH = *it; + mit = ObjectMap.find(nextH); + if (mit==ObjectMap.end()) { + DRW_DBG("\nWARNING: Entity of block not found\n"); + ret = false; + continue; + } else {//foud entity reads it + oc = mit->second; + ObjectMap.erase(mit); + DRW_DBG("\nPline vertex, parsing entity: "); DRW_DBGH(oc.handle); DRW_DBG(", pos: "); DRW_DBG(oc.loc); DRW_DBG("\n"); + DRW_Vertex vt; + dbuf->setPosition(oc.loc); + //RLZ: verify if pos is ok + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) {//2010+ + bs = dbuf->getUModularChar(); + } + duint8 *tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + dint16 oType = buff.getObjType(version); + buff.resetPosition(); + DRW_DBG(" object type= "); DRW_DBG(oType); DRW_DBG("\n"); + ret2 = vt.parseDwg(version, &buff, bs, pline.basePoint.z); + delete[]tmpByteStr; + pline.addVertex(vt); + nextEntLink = vt.nextEntLink; \ + prevEntLink = vt.prevEntLink; + ret = ret && ret2; + } + } + }//end 2004+ + DRW_DBG("\nRemoved SEQEND entity: "); DRW_DBGH(pline.seqEndH.ref);DRW_DBG("\n"); + ObjectMap.erase(pline.seqEndH.ref); + + return ret; +} + +bool dwgReader::readDwgEntities(DRW_Interface& intfa, dwgBuffer *dbuf){ + bool ret = true; + bool ret2 = true; + + DRW_DBG("\nobject map total size= "); DRW_DBG(ObjectMap.size()); + std::map::iterator itB=ObjectMap.begin(); + std::map::iterator itE=ObjectMap.end(); + while (itB != itE){ + ret2 = readDwgEntity(dbuf, itB->second, intfa); + ObjectMap.erase(itB); + itB=ObjectMap.begin(); + if (ret) + ret = ret2; + } + return ret; +} + +/** + * Reads a dwg drawing entity (dwg object entity) given its offset in the file + */ +bool dwgReader::readDwgEntity(dwgBuffer *dbuf, objHandle& obj, DRW_Interface& intfa){ + bool ret = true; + duint32 bs = 0; + +#define ENTRY_PARSE(e) \ + ret = e.parseDwg(version, &buff, bs); \ + parseAttribs(&e); \ + nextEntLink = e.nextEntLink; \ + prevEntLink = e.prevEntLink; + + nextEntLink = prevEntLink = 0;// set to 0 to skip unimplemented entities + dbuf->setPosition(obj.loc); + //verify if position is ok: + if (!dbuf->isGood()){ + DRW_DBG(" Warning: readDwgEntity, bad location\n"); + return false; + } + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) {//2010+ + bs = dbuf->getUModularChar(); + } + duint8 *tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + //verify if getBytes is ok: + if (!dbuf->isGood()){ + DRW_DBG(" Warning: readDwgEntity, bad size\n"); + delete[]tmpByteStr; + return false; + } + dwgBuffer buff(tmpByteStr, size, &decoder); + dint16 oType = buff.getObjType(version); + buff.resetPosition(); + + if (oType > 499){ + std::map::iterator it = classesmap.find(oType); + if (it == classesmap.end()){//fail, not found in classes set error + DRW_DBG("Class "); DRW_DBG(oType);DRW_DBG("not found, handle: "); DRW_DBG(obj.handle); DRW_DBG("\n"); + delete[]tmpByteStr; + return false; + } else { + DRW_Class *cl = it->second; + if (cl->dwgType != 0) + oType = cl->dwgType; + } + } + + obj.type = oType; + switch (oType){ + case 17: { + DRW_Arc e; + ENTRY_PARSE(e) + intfa.addArc(e); + break; } + case 18: { + DRW_Circle e; + ENTRY_PARSE(e) + intfa.addCircle(e); + break; } + case 19:{ + DRW_Line e; + ENTRY_PARSE(e) + intfa.addLine(e); + break;} + case 27: { + DRW_Point e; + ENTRY_PARSE(e) + intfa.addPoint(e); + break; } + case 35: { + DRW_Ellipse e; + ENTRY_PARSE(e) + intfa.addEllipse(e); + break; } + case 7: + case 8: {//minsert = 8 + DRW_Insert e; + ENTRY_PARSE(e) + e.name = findTableName(DRW::BLOCK_RECORD, e.blockRecH.ref);//RLZ: find as block or blockrecord (ps & ps0) + intfa.addInsert(e); + break; } + case 77: { + DRW_LWPolyline e; + ENTRY_PARSE(e) + intfa.addLWPolyline(e); + break; } + case 1: { + DRW_Text e; + ENTRY_PARSE(e) + e.style = findTableName(DRW::STYLE, e.styleH.ref); + intfa.addText(e); + break; } + case 44: { + DRW_MText e; + ENTRY_PARSE(e) + e.style = findTableName(DRW::STYLE, e.styleH.ref); + intfa.addMText(e); + break; } + case 28: { + DRW_3Dface e; + ENTRY_PARSE(e) + intfa.add3dFace(e); + break; } + case 20: { + DRW_DimOrdinate e; + ENTRY_PARSE(e) + e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref); + intfa.addDimOrdinate(&e); + break; } + case 21: { + DRW_DimLinear e; + ENTRY_PARSE(e) + e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref); + intfa.addDimLinear(&e); + break; } + case 22: { + DRW_DimAligned e; + ENTRY_PARSE(e) + e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref); + intfa.addDimAlign(&e); + break; } + case 23: { + DRW_DimAngular3p e; + ENTRY_PARSE(e) + e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref); + intfa.addDimAngular3P(&e); + break; } + case 24: { + DRW_DimAngular e; + ENTRY_PARSE(e) + e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref); + intfa.addDimAngular(&e); + break; } + case 25: { + DRW_DimRadial e; + ENTRY_PARSE(e) + e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref); + intfa.addDimRadial(&e); + break; } + case 26: { + DRW_DimDiametric e; + ENTRY_PARSE(e) + e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref); + intfa.addDimDiametric(&e); + break; } + case 45: { + DRW_Leader e; + ENTRY_PARSE(e) + e.style = findTableName(DRW::DIMSTYLE, e.dimStyleH.ref); + intfa.addLeader(&e); + break; } + case 31: { + DRW_Solid e; + ENTRY_PARSE(e) + intfa.addSolid(e); + break; } + case 78: { + DRW_Hatch e; + ENTRY_PARSE(e) + intfa.addHatch(&e); + break; } + case 32: { + DRW_Trace e; + ENTRY_PARSE(e) + intfa.addTrace(e); + break; } + case 34: { + DRW_Viewport e; + ENTRY_PARSE(e) + intfa.addViewport(e); + break; } + case 36: { + DRW_Spline e; + ENTRY_PARSE(e) + intfa.addSpline(&e); + break; } + case 40: { + DRW_Ray e; + ENTRY_PARSE(e) + intfa.addRay(e); + break; } + case 15: // pline 2D + case 16: // pline 3D + case 29: { // pline PFACE + DRW_Polyline e; + ENTRY_PARSE(e) + readPlineVertex(e, dbuf); + intfa.addPolyline(e); + break; } +// case 30: { +// DRW_Polyline e;// MESH (not pline) +// ENTRY_PARSE(e) +// intfa.addRay(e); +// break; } + case 41: { + DRW_Xline e; + ENTRY_PARSE(e) + intfa.addXline(e); + break; } + case 101: { + DRW_Image e; + ENTRY_PARSE(e) + intfa.addImage(&e); + break; } + + default: + //not supported or are object add to remaining map + objObjectMap[obj.handle]= obj; + break; + } + if (!ret){ + DRW_DBG("Warning: Entity type "); DRW_DBG(oType);DRW_DBG("has failed, handle: "); DRW_DBG(obj.handle); DRW_DBG("\n"); + } + delete[]tmpByteStr; + return ret; +} + +bool dwgReader::readDwgObjects(DRW_Interface& intfa, dwgBuffer *dbuf){ + bool ret = true; + bool ret2 = true; + + duint32 i=0; + DRW_DBG("\nentities map total size= "); DRW_DBG(ObjectMap.size()); + DRW_DBG("\nobjects map total size= "); DRW_DBG(objObjectMap.size()); + std::map::iterator itB=objObjectMap.begin(); + std::map::iterator itE=objObjectMap.end(); + while (itB != itE){ + ret2 = readDwgObject(dbuf, itB->second, intfa); + objObjectMap.erase(itB); + itB=objObjectMap.begin(); + if (ret) + ret = ret2; + } + if (DRW_DBGGL == DRW_dbg::DEBUG) { + for (std::map::iterator it=remainingMap.begin(); it != remainingMap.end(); ++it){ + DRW_DBG("\nnum.# "); DRW_DBG(i++); DRW_DBG(" Remaining object Handle, loc, type= "); DRW_DBG(it->first); + DRW_DBG(" "); DRW_DBG(it->second.loc); DRW_DBG(" "); DRW_DBG(it->second.type); + } + DRW_DBG("\n"); + } + return ret; +} + +/** + * Reads a dwg drawing object (dwg object object) given its offset in the file + */ +bool dwgReader::readDwgObject(dwgBuffer *dbuf, objHandle& obj, DRW_Interface& intfa){ + bool ret = true; + duint32 bs = 0; + + dbuf->setPosition(obj.loc); + //verify if position is ok: + if (!dbuf->isGood()){ + DRW_DBG(" Warning: readDwgObject, bad location\n"); + return false; + } + int size = dbuf->getModularShort(); + if (version > DRW::AC1021) {//2010+ + bs = dbuf->getUModularChar(); + } + duint8 *tmpByteStr = new duint8[size]; + dbuf->getBytes(tmpByteStr, size); + //verify if getBytes is ok: + if (!dbuf->isGood()){ + DRW_DBG(" Warning: readDwgObject, bad size\n"); + delete[]tmpByteStr; + return false; + } + dwgBuffer buff(tmpByteStr, size, &decoder); + //oType are set parsing entities + dint16 oType = obj.type; + + switch (oType){ + case 102: { + DRW_ImageDef e; + ret = e.parseDwg(version, &buff, bs); + intfa.linkImage(&e); + break; } + default: + //not supported object or entity add to remaining map for debug + remainingMap[obj.handle]= obj; + break; + } + if (!ret){ + DRW_DBG("Warning: Object type "); DRW_DBG(oType);DRW_DBG("has failed, handle: "); DRW_DBG(obj.handle); DRW_DBG("\n"); + } + delete[]tmpByteStr; + return ret; +} + + + +bool DRW_ObjControl::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ +int unkData=0; + bool ret = DRW_TableEntry::parseDwg(version, buf, NULL, bs); + DRW_DBG("\n***************************** parsing object control entry *********************************************\n"); + if (!ret) + return ret; + //last parsed is: XDic Missing Flag 2004+ + int numEntries = buf->getBitLong(); + DRW_DBG(" num entries: "); DRW_DBG(numEntries); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + +// if (oType == 68 && version== DRW::AC1015){//V2000 dimstyle seems have one unknown byte hard handle counter?? + if (oType == 68 && version > DRW::AC1014){//dimstyle seems have one unknown byte hard handle counter?? + unkData = buf->getRawChar8(); + DRW_DBG(" unknown v2000 byte: "); DRW_DBG( unkData); DRW_DBG("\n"); + } + if (version > DRW::AC1018){//from v2007+ have a bit for strings follows (ObjControl do not have) + int stringBit = buf->getBit(); + DRW_DBG(" string bit for v2007+: "); DRW_DBG( stringBit); DRW_DBG("\n"); + } + + dwgHandle objectH = buf->getHandle(); + DRW_DBG(" NULL Handle: "); DRW_DBGHL(objectH.code, objectH.size, objectH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + +// if (oType == 56 && version== DRW::AC1015){//linetype in 2004 seems not have XDicObjH or NULL handle + if (xDictFlag !=1){//linetype in 2004 seems not have XDicObjH or NULL handle + dwgHandle XDicObjH = buf->getHandle(); + DRW_DBG(" XDicObj control Handle: "); DRW_DBGHL(XDicObjH.code, XDicObjH.size, XDicObjH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } +//add 2 for modelspace, paperspace blocks & bylayer, byblock linetypes + numEntries = ((oType == 48) || (oType == 56)) ? (numEntries +2) : numEntries; + + for (int i =0; i< numEntries; i++){ + objectH = buf->getOffsetHandle(handle); + if (objectH.ref != 0) //in vports R14 I found some NULL handles + hadlesList.push_back (objectH.ref); + DRW_DBG(" objectH Handle: "); DRW_DBGHL(objectH.code, objectH.size, objectH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } + + for (int i =0; i< unkData; i++){ + objectH = buf->getOffsetHandle(handle); + DRW_DBG(" unknown Handle: "); DRW_DBGHL(objectH.code, objectH.size, objectH.ref); DRW_DBG("\n"); + DRW_DBG("Remaining bytes: "); DRW_DBG(buf->numRemainingBytes()); DRW_DBG("\n"); + } + return buf->isGood(); +} diff --git a/extlib/libdxfrw/intern/dwgreader.h b/extlib/libdxfrw/intern/dwgreader.h new file mode 100644 index 0000000..fa84852 --- /dev/null +++ b/extlib/libdxfrw/intern/dwgreader.h @@ -0,0 +1,203 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DWGREADER_H +#define DWGREADER_H + +#include +#include +#include "drw_textcodec.h" +#include "dwgutil.h" +#include "dwgbuffer.h" +#include "../libdwgr.h" + +class objHandle{ +public: + objHandle(){ handle = type = loc = 0; } + objHandle(duint32 t, duint32 h, duint32 l){ + type = t; + handle = h; + loc = l; + } + duint32 type; + duint32 handle; + duint32 loc; +}; + +//until 2000 = 2000- +//since 2004 except 2007 = 2004+ +// 2007 = 2007 +// pages of section +/* 2000-: No pages, only sections + * 2004+: Id, page number (index) + * size, size of page in file stream + * address, address in file stream + * dataSize, data size for this page + * startOffset, start offset for this page + * cSize, compressed size of data + * uSize, uncompressed size of data + * 2007: page Id, pageCount & pages + * size, size in file + * dataSize + * startOffset, start position in decompressed data stream + * cSize, compressed size of data + * uSize, uncompressed size of data + * address, address in file stream + * */ +class dwgPageInfo { +public: + dwgPageInfo(){} + dwgPageInfo(duint64 i, duint64 ad, duint32 sz){ + Id=i; address=ad; size=sz; + } + ~dwgPageInfo(){} + duint64 Id; + duint64 address; //in file stream, for rd18, rd21 + duint64 size; //in file stream, for rd18, rd21 + duint64 dataSize; //for rd18, rd21 + duint32 startOffset; //for rd18, rd21 + duint64 cSize; //compressed page size, for rd21 + duint64 uSize; //uncompressed page size, for rd21 +}; + +// sections of file +/* 2000-: No pages, only section Id, size & address in file + * 2004+: Id, Section Id + * size, total size of uncompressed data + * pageCount & pages, number of pages in section + * maxSize, max decompressed Size per page + * compressed, (1 = no, 2 = yes, normally 2) + * encrypted, (0 = no, 1 = yes, 2 = unknown) + * name, read & stored but not used + * 2007: same as 2004+ except encoding, saved in compressed field + * */ +class dwgSectionInfo { +public: + dwgSectionInfo(){ + compressed = 1;//1=no, 2=yes + encrypted = 0;//??? + pageCount = 0; + Id=-1; + } + ~dwgSectionInfo(){} + dint32 Id; //section Id, 2000- rd15 rd18 + std::string name; //section name rd18 + duint32 compressed;//is compressed? 1=no, 2=yes rd18, rd21(encoding) + duint32 encrypted;//encrypted (doc: 0=no, 1=yes, 2=unkn) on read: objects 0 and encrypted yes rd18 + std::mappages;//index, size, offset + duint64 size;//size of section, 2000- rd15, rd18, rd21 (data size) + duint64 pageCount; //number of pages (dwgPageInfo) in section rd18, rd21 + duint64 maxSize; //max decompressed size (needed??) rd18 rd21 + duint64 address; //address (seek) , 2000- +}; + + +//! Class to handle dwg obj control entries +/*! +* Class to handle dwg obj control entries +* @author Rallaz +*/ +class DRW_ObjControl : public DRW_TableEntry { +public: + DRW_ObjControl() { reset();} + + void reset(){ + } + bool parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs=0); + std::listhadlesList; +}; + + +class dwgReader { + friend class dwgR; +public: + dwgReader(std::istream *stream, dwgR *p){ + fileBuf = new dwgBuffer(stream); + parent = p; + decoder.setVersion(DRW::AC1021, false);//default 2007 in utf8(no convert) + decoder.setCodePage("UTF-16", false); +// blockCtrl=0; //RLZ: temporary +// blockCtrl=layerCtrl=styleCtrl=linetypeCtrl=viewCtrl=0; +// ucsCtrl=vportCtrl=appidCtrl=dimstyleCtrl=vpEntHeaderCtrl=0; + nextEntLink = prevEntLink = 0; + maintenanceVersion=0; + } + virtual ~dwgReader(); + +protected: + virtual bool readMetaData() = 0; + virtual bool readPreview(){return false;} + virtual bool readFileHeader() = 0; + virtual bool readDwgHeader(DRW_Header& hdr)=0; + virtual bool readDwgClasses() = 0; + virtual bool readDwgHandles() = 0; + virtual bool readDwgTables(DRW_Header& hdr)=0; + virtual bool readDwgBlocks(DRW_Interface& intfa) = 0; + virtual bool readDwgEntities(DRW_Interface& intfa) = 0; + virtual bool readDwgObjects(DRW_Interface& intfa) = 0; + + virtual bool readDwgEntity(dwgBuffer *dbuf, objHandle& obj, DRW_Interface& intfa); + bool readDwgObject(dwgBuffer *dbuf, objHandle& obj, DRW_Interface& intfa); + void parseAttribs(DRW_Entity* e); + std::string findTableName(DRW::TTYPE table, dint32 handle); + + void setCodePage(std::string *c){decoder.setCodePage(c, false);} + std::string getCodePage(){ return decoder.getCodePage();} + bool readDwgHeader(DRW_Header& hdr, dwgBuffer *buf, dwgBuffer *hBuf); + bool readDwgHandles(dwgBuffer *dbuf, duint32 offset, duint32 size); + bool readDwgTables(DRW_Header& hdr, dwgBuffer *dbuf); + bool checkSentinel(dwgBuffer *buf, enum secEnum::DWGSection, bool start); + + bool readDwgBlocks(DRW_Interface& intfa, dwgBuffer *dbuf); + bool readDwgEntities(DRW_Interface& intfa, dwgBuffer *dbuf); + bool readDwgObjects(DRW_Interface& intfa, dwgBuffer *dbuf); + bool readPlineVertex(DRW_Polyline& pline, dwgBuffer *dbuf); + +public: + std::mapObjectMap; + std::mapobjObjectMap; //stores the objects & entities not read in readDwgEntities + std::mapremainingMap; //stores the objects & entities not read in all processes, for debug only + std::map ltypemap; + std::map layermap; + std::map blockmap; + std::map stylemap; + std::map dimstylemap; + std::map vportmap; + std::map blockRecordmap; + std::map appIdmap; +// duint32 currBlock; + duint8 maintenanceVersion; + +protected: + dwgBuffer *fileBuf; + dwgR *parent; + DRW::Version version; + +//seeker (position) for the beginning sentinel of the image data (R13 to R15) + duint32 previewImagePos; + +//sections map + std::mapsections; + std::map classesmap; + +protected: + DRW_TextCodec decoder; + +protected: +// duint32 blockCtrl; + duint32 nextEntLink; + duint32 prevEntLink; +}; + + + +#endif // DWGREADER_H diff --git a/extlib/libdxfrw/intern/dwgreader15.cpp b/extlib/libdxfrw/intern/dwgreader15.cpp new file mode 100644 index 0000000..41bbe9b --- /dev/null +++ b/extlib/libdxfrw/intern/dwgreader15.cpp @@ -0,0 +1,198 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "drw_dbg.h" +#include "dwgreader15.h" +#include "drw_textcodec.h" +#include "../libdwgr.h" + +bool dwgReader15::readMetaData() { + version = parent->getVersion(); + decoder.setVersion(version, false); + DRW_DBG("dwgReader15::readMetaData\n"); + if (! fileBuf->setPosition(13)) + return false; + previewImagePos = fileBuf->getRawLong32(); + DRW_DBG("previewImagePos (seekerImageData) = "); DRW_DBG(previewImagePos); + /* MEASUREMENT system variable 2 bytes*/ + duint16 meas = fileBuf->getRawShort16(); + DRW_DBG("\nMEASUREMENT (0 = English, 1 = Metric)= "); DRW_DBG(meas); + duint16 cp = fileBuf->getRawShort16(); + DRW_DBG("\ncodepage= "); DRW_DBG(cp); DRW_DBG("\n"); + if (cp == 29) //TODO RLZ: locate wath code page and correct this + decoder.setCodePage("ANSI_1252", false); + if (cp == 30) + decoder.setCodePage("ANSI_1252", false); + return true; +} + +bool dwgReader15::readFileHeader() { + bool ret = true; + DRW_DBG("dwgReader15::readFileHeader\n"); + if (! fileBuf->setPosition(21)) + return false; + duint32 count = fileBuf->getRawLong32(); + DRW_DBG("count records= "); DRW_DBG(count); DRW_DBG("\n"); + + for (unsigned int i = 0; i < count; i++) { + duint8 rec = fileBuf->getRawChar8(); + duint32 address = fileBuf->getRawLong32(); + duint32 size = fileBuf->getRawLong32(); + dwgSectionInfo si; + si.Id = rec; + si.size = size; + si.address = address; + if (rec == 0) { + DRW_DBG("\nSection HEADERS address= "); + DRW_DBG(address); DRW_DBG(" size= "); DRW_DBG(size); + sections[secEnum::HEADER] = si; + } else if (rec == 1) { + DRW_DBG("\nSection CLASSES address= "); + DRW_DBG(address); DRW_DBG(" size= "); DRW_DBG(size); + sections[secEnum::CLASSES] = si; + } else if (rec == 2) { + DRW_DBG("\nSection OBJECTS (handles) address= "); + DRW_DBG(address); DRW_DBG(" size= "); DRW_DBG(size); + sections[secEnum::HANDLES] = si; + } else if (rec == 3) { + DRW_DBG("\nSection UNKNOWN address= "); + DRW_DBG(address); DRW_DBG(" size= "); DRW_DBG(size); + sections[secEnum::UNKNOWNS] = si; + } else if (rec == 4) { + DRW_DBG("\nSection R14DATA (AcDb:Template) address= "); + DRW_DBG(address); DRW_DBG(" size= "); DRW_DBG(size); + sections[secEnum::TEMPLATE] = si; + } else if (rec == 5) { + DRW_DBG("\nSection R14REC5 (AcDb:AuxHeader) address= "); + DRW_DBG(address); DRW_DBG(" size= "); DRW_DBG(size); + sections[secEnum::AUXHEADER] = si; + } else { + std::cerr << "\nUnsupported section number\n"; + } + } + if (! fileBuf->isGood()) + return false; + DRW_DBG("\nposition after read section locator records= "); DRW_DBG(fileBuf->getPosition()); + DRW_DBG(", bit are= "); DRW_DBG(fileBuf->getBitPos()); + duint32 ckcrc = fileBuf->crc8(0,0,fileBuf->getPosition()); + DRW_DBG("\nfile header crc8 0 result= "); DRW_DBG(ckcrc); + switch (count){ + case 3: + ckcrc = ckcrc ^ 0xA598; + break; + case 4: + ckcrc = ckcrc ^ 0x8101; + break; + case 5: + ckcrc = ckcrc ^ 0x3CC4; + break; + case 6: + ckcrc = ckcrc ^ 0x8461; + } + DRW_DBG("\nfile header crc8 xor result= "); DRW_DBG(ckcrc); + DRW_DBG("\nfile header CRC= "); DRW_DBG(fileBuf->getRawShort16()); + DRW_DBG("\nfile header sentinel= "); + checkSentinel(fileBuf, secEnum::FILEHEADER, false); + + DRW_DBG("\nposition after read file header sentinel= "); DRW_DBG(fileBuf->getPosition()); + DRW_DBG(", bit are= "); DRW_DBG(fileBuf->getBitPos()); + + DRW_DBG("\ndwgReader15::readFileHeader END\n"); + return ret; +} + +bool dwgReader15::readDwgHeader(DRW_Header& hdr){ + DRW_DBG("dwgReader15::readDwgHeader\n"); + dwgSectionInfo si = sections[secEnum::HEADER]; + if (si.Id<0)//not found, ends + return false; + if (!fileBuf->setPosition(si.address)) + return false; + duint8 *tmpByteStr = new duint8[si.size]; + fileBuf->getBytes(tmpByteStr, si.size); + dwgBuffer buff(tmpByteStr, si.size, &decoder); + DRW_DBG("Header section sentinel= "); + checkSentinel(&buff, secEnum::HEADER, true); + bool ret = dwgReader::readDwgHeader(hdr, &buff, &buff); + delete[]tmpByteStr; + return ret; +} + + +bool dwgReader15::readDwgClasses(){ + DRW_DBG("\ndwgReader15::readDwgClasses\n"); + dwgSectionInfo si = sections[secEnum::CLASSES]; + if (si.Id<0)//not found, ends + return false; + if (!fileBuf->setPosition(si.address)) + return false; + + DRW_DBG("classes section sentinel= "); + checkSentinel(fileBuf, secEnum::CLASSES, true); + + duint32 size = fileBuf->getRawLong32(); + if (size != (si.size - 38)) { + DRW_DBG("\nWARNING dwgReader15::readDwgClasses size are "); DRW_DBG(size); + DRW_DBG(" and secSize - 38 are "); DRW_DBG(si.size - 38); DRW_DBG("\n"); + } + duint8 *tmpByteStr = new duint8[size]; + fileBuf->getBytes(tmpByteStr, size); + dwgBuffer buff(tmpByteStr, size, &decoder); + size--; //reduce 1 byte instead of check pos + bitPos + while (size > buff.getPosition()) { + DRW_Class *cl = new DRW_Class(); + cl->parseDwg(version, &buff, &buff); + classesmap[cl->classNum] = cl; + } + DRW_DBG("\nCRC: "); DRW_DBGH(fileBuf->getRawShort16()); + DRW_DBG("\nclasses section end sentinel= "); + checkSentinel(fileBuf, secEnum::CLASSES, false); + bool ret = buff.isGood(); + delete[]tmpByteStr; + return ret; +} + +bool dwgReader15::readDwgHandles() { + DRW_DBG("\ndwgReader15::readDwgHandles\n"); + dwgSectionInfo si = sections[secEnum::HANDLES]; + if (si.Id<0)//not found, ends + return false; + + bool ret = dwgReader::readDwgHandles(fileBuf, si.address, si.size); + return ret; +} + +/*********** objects ************************/ +/** + * Reads all the object referenced in the object map section of the DWG file + * (using their object file offsets) + */ +bool dwgReader15::readDwgTables(DRW_Header& hdr) { + bool ret = dwgReader::readDwgTables(hdr, fileBuf); + + return ret; +} + +/** + * Reads all the object referenced in the object map section of the DWG file + * (using their object file offsets) + */ +bool dwgReader15::readDwgBlocks(DRW_Interface& intfa) { + bool ret = true; + ret = dwgReader::readDwgBlocks(intfa, fileBuf); + return ret; +} diff --git a/extlib/libdxfrw/intern/dwgreader15.h b/extlib/libdxfrw/intern/dwgreader15.h new file mode 100644 index 0000000..e3a1f97 --- /dev/null +++ b/extlib/libdxfrw/intern/dwgreader15.h @@ -0,0 +1,47 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DWGREADER15_H +#define DWGREADER15_H + +#include +#include +#include "drw_textcodec.h" +#include "dwgbuffer.h" +#include "dwgreader.h" + +class dwgReader15 : public dwgReader { +public: + dwgReader15(std::istream *stream, dwgR *p):dwgReader(stream, p){ } + virtual ~dwgReader15() {} + bool readMetaData(); + bool readFileHeader(); + bool readDwgHeader(DRW_Header& hdr); + bool readDwgClasses(); + bool readDwgHandles(); + bool readDwgTables(DRW_Header& hdr); + bool readDwgBlocks(DRW_Interface& intfa); + bool readDwgEntities(DRW_Interface& intfa){ + bool ret = true; + ret = dwgReader::readDwgEntities(intfa, fileBuf); + return ret; + } + bool readDwgObjects(DRW_Interface& intfa){ + bool ret = true; + ret = dwgReader::readDwgObjects(intfa, fileBuf); + return ret; + } +// bool readDwgEntity(objHandle& obj, DRW_Interface& intfa); +}; + + +#endif // DWGREADER15_H diff --git a/extlib/libdxfrw/intern/dwgreader18.cpp b/extlib/libdxfrw/intern/dwgreader18.cpp new file mode 100644 index 0000000..039c2c1 --- /dev/null +++ b/extlib/libdxfrw/intern/dwgreader18.cpp @@ -0,0 +1,594 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "drw_dbg.h" +#include "dwgreader18.h" +#include "dwgutil.h" +#include "drw_textcodec.h" +#include "../libdwgr.h" + +void dwgReader18::genMagicNumber(){ + int size =0x114; + duint8 *tmpMagicStr = new duint8[size]; + duint8 *p = tmpMagicStr; + int rSeed =1; + while (size--) { + rSeed *= 0x343fd; + rSeed += 0x269ec3; + *p++ = static_cast(rSeed >> 0x10); + } + int j = 0; + size =0x114; + for (int i=0; i< size;i++) { + DRW_DBGH(tmpMagicStr[i]); + if (j == 15) { + DRW_DBG("\n"); + j = 0; + } else { + DRW_DBG(", "); + j++; + } + } + delete[]tmpMagicStr; +} + +duint32 dwgReader18::checksum(duint32 seed, duint8* data, duint32 sz){ + duint32 size = sz; + duint32 sum1 = seed & 0xffff; + duint32 sum2 = seed >> 0x10; + while (size != 0) { +// duint32 chunkSize = min(0x15b0, size); + duint32 chunkSize = 0x15b0 < size? 0x15b0:size; + size -= chunkSize; + for (duint32 i = 0; i < chunkSize; i++) { + sum1 += *data++; + sum2 += sum1; + } + sum1 %= 0xFFF1; + sum2 %= 0xFFF1; + } + return (sum2 << 0x10) | (sum1 & 0xffff); +} + + //called: Section page map: 0x41630e3b +void dwgReader18::parseSysPage(duint8 *decompSec, duint32 decompSize){ + DRW_DBG("\nparseSysPage:\n "); + duint32 compSize = fileBuf->getRawLong32(); + DRW_DBG("Compressed size= "); DRW_DBG(compSize); DRW_DBG(", "); DRW_DBGH(compSize); + DRW_DBG("\nCompression type= "); DRW_DBGH(fileBuf->getRawLong32()); + DRW_DBG("\nSection page checksum= "); DRW_DBGH(fileBuf->getRawLong32()); DRW_DBG("\n"); + + duint8 hdrData[20]; + fileBuf->moveBitPos(-160); + fileBuf->getBytes(hdrData, 20); + for (duint8 i= 16; i<20; ++i) + hdrData[i]=0; + duint32 calcsH = checksum(0, hdrData, 20); + DRW_DBG("Calc hdr checksum= "); DRW_DBGH(calcsH); + duint8 *tmpCompSec = new duint8[compSize]; + fileBuf->getBytes(tmpCompSec, compSize); + duint32 calcsD = checksum(calcsH, tmpCompSec, compSize); + DRW_DBG("\nCalc data checksum= "); DRW_DBGH(calcsD); DRW_DBG("\n"); + +#ifdef DRW_DBG_DUMP + for (unsigned int i=0, j=0; i< compSize;i++) { + DRW_DBGH( (unsigned char)compSec[i]); + if (j == 7) { DRW_DBG("\n"); j = 0; + } else { DRW_DBG(", "); j++; } + } DRW_DBG("\n"); +#endif + DRW_DBG("decompressing "); DRW_DBG(compSize); DRW_DBG(" bytes in "); DRW_DBG(decompSize); DRW_DBG(" bytes\n"); + dwgCompressor comp; + comp.decompress18(tmpCompSec, decompSec, compSize, decompSize); +#ifdef DRW_DBG_DUMP + for (unsigned int i=0, j=0; i< decompSize;i++) { + DRW_DBGH( decompSec[i]); + if (j == 7) { DRW_DBG("\n"); j = 0; + } else { DRW_DBG(", "); j++; } + } DRW_DBG("\n"); +#endif + delete[]tmpCompSec; +} + + //called ???: Section map: 0x4163003b +bool dwgReader18::parseDataPage(dwgSectionInfo si/*, duint8 *dData*/){ + DRW_DBG("\nparseDataPage\n "); + objData = new duint8 [si.pageCount * si.maxSize]; + + for (std::map::iterator it=si.pages.begin(); it!=si.pages.end(); ++it){ + dwgPageInfo pi = it->second; + if (!fileBuf->setPosition(pi.address)) + return false; + //decript section header + duint8 hdrData[32]; + fileBuf->getBytes(hdrData, 32); + dwgCompressor::decrypt18Hdr(hdrData, 32, pi.address); + DRW_DBG("Section "); DRW_DBG(si.name); DRW_DBG(" page header=\n"); + for (unsigned int i=0, j=0; i< 32;i++) { + DRW_DBGH( (unsigned char)hdrData[i]); + if (j == 7) { + DRW_DBG("\n"); + j = 0; + } else { + DRW_DBG(", "); + j++; + } + } DRW_DBG("\n"); + + DRW_DBG("\n Page number= "); DRW_DBGH(pi.Id); + DRW_DBG("\n size in file= "); DRW_DBGH(pi.size); + DRW_DBG("\n address in file= "); DRW_DBGH(pi.address); + DRW_DBG("\n Data size= "); DRW_DBGH(pi.dataSize); + DRW_DBG("\n Start offset= "); DRW_DBGH(pi.startOffset); DRW_DBG("\n"); + dwgBuffer bufHdr(hdrData, 32, &decoder); + DRW_DBG(" section page type= "); DRW_DBGH(bufHdr.getRawLong32()); + DRW_DBG("\n section number= "); DRW_DBGH(bufHdr.getRawLong32()); + pi.cSize = bufHdr.getRawLong32(); + DRW_DBG("\n data size (compressed)= "); DRW_DBGH(pi.cSize); DRW_DBG(" dec "); DRW_DBG(pi.cSize); + pi.uSize = bufHdr.getRawLong32(); + DRW_DBG("\n page size (decompressed)= "); DRW_DBGH(pi.uSize); DRW_DBG(" dec "); DRW_DBG(pi.uSize); + DRW_DBG("\n start offset (in decompressed buffer)= "); DRW_DBGH(bufHdr.getRawLong32()); + DRW_DBG("\n unknown= "); DRW_DBGH(bufHdr.getRawLong32()); + DRW_DBG("\n header checksum= "); DRW_DBGH(bufHdr.getRawLong32()); + DRW_DBG("\n data checksum= "); DRW_DBGH(bufHdr.getRawLong32()); DRW_DBG("\n"); + + //get compressed data + duint8 *cData = new duint8[pi.cSize]; + if (!fileBuf->setPosition(pi.address+32)) + return false; + fileBuf->getBytes(cData, pi.cSize); + + //calculate checksum + duint32 calcsD = checksum(0, cData, pi.cSize); + for (duint8 i= 24; i<28; ++i) + hdrData[i]=0; + duint32 calcsH = checksum(calcsD, hdrData, 32); + DRW_DBG("Calc header checksum= "); DRW_DBGH(calcsH); + DRW_DBG("\nCalc data checksum= "); DRW_DBGH(calcsD); DRW_DBG("\n"); + + duint8* oData = objData + pi.startOffset; + pi.uSize = si.maxSize; + DRW_DBG("decompressing "); DRW_DBG(pi.cSize); DRW_DBG(" bytes in "); DRW_DBG(pi.uSize); DRW_DBG(" bytes\n"); + dwgCompressor comp; + comp.decompress18(cData, oData, pi.cSize, pi.uSize); + delete[]cData; + } + return true; +} + +bool dwgReader18::readMetaData() { + version = parent->getVersion(); + decoder.setVersion(version, false); + DRW_DBG("dwgReader18::readMetaData\n"); + if (! fileBuf->setPosition(11)) + return false; + maintenanceVersion = fileBuf->getRawChar8(); + DRW_DBG("maintenance version= "); DRW_DBGH(maintenanceVersion); + DRW_DBG("\nbyte at 0x0C= "); DRW_DBGH(fileBuf->getRawChar8()); + previewImagePos = fileBuf->getRawLong32(); //+ page header size (0x20). + DRW_DBG("\npreviewImagePos (seekerImageData) = "); DRW_DBG(previewImagePos); + DRW_DBG("\napp Dwg version= "); DRW_DBGH(fileBuf->getRawChar8()); DRW_DBG(", "); + DRW_DBG("\napp maintenance version= "); DRW_DBGH(fileBuf->getRawChar8()); + duint16 cp = fileBuf->getRawShort16(); + DRW_DBG("\ncodepage= "); DRW_DBG(cp); + if (cp == 30) + decoder.setCodePage("ANSI_1252", false); + DRW_DBG("\n3 0x00 bytes(seems 0x00, appDwgV & appMaintV) = "); DRW_DBGH(fileBuf->getRawChar8()); DRW_DBG(", "); + DRW_DBGH(fileBuf->getRawChar8()); DRW_DBG(", "); DRW_DBGH(fileBuf->getRawChar8()); + securityFlags = fileBuf->getRawLong32(); + DRW_DBG("\nsecurity flags= "); DRW_DBG(securityFlags); + // UNKNOWN SECTION 4 bytes + duint32 uk = fileBuf->getRawLong32(); + DRW_DBG("\nUNKNOWN SECTION ( 4 bytes) = "); DRW_DBG(uk); + duint32 sumInfoAddr = fileBuf->getRawLong32(); + DRW_DBG("\nsummary Info Address= "); DRW_DBG(sumInfoAddr); + duint32 vbaAdd = fileBuf->getRawLong32(); + DRW_DBG("\nVBA address= "); DRW_DBGH(vbaAdd); + DRW_DBG("\npos 0x28 are 0x00000080= "); DRW_DBGH(fileBuf->getRawLong32()); + DRW_DBG("\n"); + return true; +} + +bool dwgReader18::readFileHeader() { + + if (! fileBuf->setPosition(0x80)) + return false; + +// genMagicNumber(); DBG("\n"); DBG("\n"); + DRW_DBG("Encripted Header Data=\n"); + duint8 byteStr[0x6C]; + int size =0x6C; + for (int i=0, j=0; i< 0x6C;i++) { + duint8 ch = fileBuf->getRawChar8(); + DRW_DBGH(ch); + if (j == 15) { + DRW_DBG("\n"); + j = 0; + } else { + DRW_DBG(", "); + j++; + } + byteStr[i] = DRW_magicNum18[i] ^ ch; + } + DRW_DBG("\n"); + +// size =0x6C; + DRW_DBG("Decripted Header Data=\n"); + for (int i=0, j = 0; i< size;i++) { + DRW_DBGH( (unsigned char)byteStr[i]); + if (j == 15) { + DRW_DBG("\n"); + j = 0; + } else { + DRW_DBG(", "); + j++; + } + } + dwgBuffer buff(byteStr, 0x6C, &decoder); + std::string name = reinterpret_cast(byteStr); + DRW_DBG("\nFile ID string (AcFssFcAJMB)= "); DRW_DBG(name.c_str()); + //ID string + NULL = 12 + buff.setPosition(12); + DRW_DBG("\n0x00 long= "); DRW_DBGH(buff.getRawLong32()); + DRW_DBG("\n0x6c long= "); DRW_DBGH(buff.getRawLong32()); + DRW_DBG("\n0x04 long= "); DRW_DBGH(buff.getRawLong32()); + DRW_DBG("\nRoot tree node gap= "); DRW_DBGH(buff.getRawLong32()); + DRW_DBG("\nLowermost left tree node gap= "); DRW_DBGH(buff.getRawLong32()); + DRW_DBG("\nLowermost right tree node gap= "); DRW_DBGH(buff.getRawLong32()); + DRW_DBG("\nUnknown long (1)= "); DRW_DBGH(buff.getRawLong32()); + DRW_DBG("\nLast section page Id= "); DRW_DBGH(buff.getRawLong32()); + DRW_DBG("\nLast section page end address 64b= "); DRW_DBGH(buff.getRawLong64()); + DRW_DBG("\nStart of second header data address 64b= "); DRW_DBGH(buff.getRawLong64()); + DRW_DBG("\nGap amount= "); DRW_DBGH(buff.getRawLong32()); + DRW_DBG("\nSection page amount= "); DRW_DBGH(buff.getRawLong32()); + DRW_DBG("\n0x20 long= "); DRW_DBGH(buff.getRawLong32()); + DRW_DBG("\n0x80 long= "); DRW_DBGH(buff.getRawLong32()); + DRW_DBG("\n0x40 long= "); DRW_DBGH(buff.getRawLong32()); + dint32 secPageMapId = buff.getRawLong32(); + DRW_DBG("\nSection Page Map Id= "); DRW_DBGH(secPageMapId); + duint64 secPageMapAddr = buff.getRawLong64()+0x100; + DRW_DBG("\nSection Page Map address 64b= "); DRW_DBGH(secPageMapAddr); + DRW_DBG("\nSection Page Map address 64b dec= "); DRW_DBG(secPageMapAddr); + duint32 secMapId = buff.getRawLong32(); + DRW_DBG("\nSection Map Id= "); DRW_DBGH(secMapId); + DRW_DBG("\nSection page array size= "); DRW_DBGH(buff.getRawLong32()); + DRW_DBG("\nGap array size= "); DRW_DBGH(buff.getRawLong32()); + //TODO: verify CRC + DRW_DBG("\nCRC32= "); DRW_DBGH(buff.getRawLong32()); + for (duint8 i = 0x68; i < 0x6c; ++i) + byteStr[i] = '\0'; +// byteStr[i] = '\0'; + duint32 crcCalc = buff.crc32(0x00,0,0x6C); + DRW_DBG("\nCRC32 calculated= "); DRW_DBGH(crcCalc); + + DRW_DBG("\nEnd Encrypted Data. Reads 0x14 bytes, equal to magic number:\n"); + for (int i=0, j=0; i< 0x14;i++) { + DRW_DBG("magic num: "); DRW_DBGH( (unsigned char)DRW_magicNumEnd18[i]); + DRW_DBG(",read "); DRW_DBGH( (unsigned char)fileBuf->getRawChar8()); + if (j == 3) { + DRW_DBG("\n"); + j = 0; + } else { + DRW_DBG(", "); + j++; + } + } +// At this point are parsed the first 256 bytes + DRW_DBG("\nJump to Section Page Map address: "); DRW_DBGH(secPageMapAddr); + + if (! fileBuf->setPosition(secPageMapAddr)) + return false; + duint32 pageType = fileBuf->getRawLong32(); + DRW_DBG("\nSection page type= "); DRW_DBGH(pageType); + duint32 decompSize = fileBuf->getRawLong32(); + DRW_DBG("\nDecompressed size= "); DRW_DBG(decompSize); DRW_DBG(", "); DRW_DBGH(decompSize); + if (pageType != 0x41630e3b){ + //bad page type, ends + DRW_DBG("Warning, bad page type, was expected 0x41630e3b instead of"); DRW_DBGH(pageType); DRW_DBG("\n"); + return false; + } + duint8 *tmpDecompSec = new duint8[decompSize]; + parseSysPage(tmpDecompSec, decompSize); + +//parses "Section page map" decompressed data + dwgBuffer buff2(tmpDecompSec, decompSize, &decoder); + duint32 address = 0x100; + //stores temporaly info of all pages: + std::mapsectionPageMapTmp; + + for (unsigned int i = 0; i < decompSize;) { + dint32 id = buff2.getRawLong32();//RLZ bad can be +/- + duint32 size = buff2.getRawLong32(); + i += 8; + DRW_DBG("Page num= "); DRW_DBG(id); DRW_DBG(" size= "); DRW_DBGH(size); + DRW_DBG(" address= "); DRW_DBGH(address); DRW_DBG("\n"); + //TODO num can be negative indicating gap +// duint64 ind = id > 0 ? id : -id; + if (id < 0){ + DRW_DBG("Parent= "); DRW_DBG(buff2.getRawLong32()); + DRW_DBG("\nLeft= "); DRW_DBG(buff2.getRawLong32()); + DRW_DBG(", Right= "); DRW_DBG(buff2.getRawLong32()); + DRW_DBG(", 0x00= ");DRW_DBGH(buff2.getRawLong32()); DRW_DBG("\n"); + i += 16; + } + + sectionPageMapTmp[id] = dwgPageInfo(id, address, size); + address += size; + } + delete[]tmpDecompSec; + + DRW_DBG("\n*** dwgReader18: Processing Data Section Map ***\n"); + dwgPageInfo sectionMap = sectionPageMapTmp[secMapId]; + if (!fileBuf->setPosition(sectionMap.address)) + return false; + pageType = fileBuf->getRawLong32(); + DRW_DBG("\nSection page type= "); DRW_DBGH(pageType); + decompSize = fileBuf->getRawLong32(); + DRW_DBG("\nDecompressed size= "); DRW_DBG(decompSize); DRW_DBG(", "); DRW_DBGH(decompSize); + if (pageType != 0x4163003b){ + //bad page type, ends + DRW_DBG("Warning, bad page type, was expected 0x4163003b instead of"); DRW_DBGH(pageType); DRW_DBG("\n"); + return false; + } + tmpDecompSec = new duint8[decompSize]; + parseSysPage(tmpDecompSec, decompSize); + +//reads sections: + DRW_DBG("\n*** dwgReader18: reads sections:"); + dwgBuffer buff3(tmpDecompSec, decompSize, &decoder); + duint32 numDescriptions = buff3.getRawLong32(); + DRW_DBG("\nnumDescriptions (sections)= "); DRW_DBG(numDescriptions); + DRW_DBG("\n0x02 long= "); DRW_DBGH(buff3.getRawLong32()); + DRW_DBG("\n0x00007400 long= "); DRW_DBGH(buff3.getRawLong32()); + DRW_DBG("\n0x00 long= "); DRW_DBGH(buff3.getRawLong32()); + DRW_DBG("\nunknown long (numDescriptions?)= "); DRW_DBG(buff3.getRawLong32()); DRW_DBG("\n"); + + for (unsigned int i = 0; i < numDescriptions; i++) { + dwgSectionInfo secInfo; + secInfo.size = buff3.getRawLong64(); + DRW_DBG("\nSize of section= "); DRW_DBGH(secInfo.size); + secInfo.pageCount = buff3.getRawLong32(); + DRW_DBG("\nPage count= "); DRW_DBGH(secInfo.pageCount); + secInfo.maxSize = buff3.getRawLong32(); + DRW_DBG("\nMax Decompressed Size= "); DRW_DBGH(secInfo.maxSize); + DRW_DBG("\nunknown long= "); DRW_DBGH(buff3.getRawLong32()); + secInfo.compressed = buff3.getRawLong32(); + DRW_DBG("\nis Compressed? 1:no, 2:yes= "); DRW_DBGH(secInfo.compressed); + secInfo.Id = buff3.getRawLong32(); + DRW_DBG("\nSection Id= "); DRW_DBGH(secInfo.Id); + secInfo.encrypted = buff3.getRawLong32(); + //encrypted (doc: 0 no, 1 yes, 2 unkn) on read: objects 0 and encrypted yes + DRW_DBG("\nEncrypted= "); DRW_DBGH(secInfo.encrypted); + duint8 nameCStr[64]; + buff3.getBytes(nameCStr, 64); + secInfo.name = reinterpret_cast(nameCStr); + DRW_DBG("\nSection std::Name= "); DRW_DBG( secInfo.name.c_str() ); DRW_DBG("\n"); + for (unsigned int i = 0; i < secInfo.pageCount; i++){ + duint32 pn = buff3.getRawLong32(); + dwgPageInfo pi = sectionPageMapTmp[pn]; //get a copy + DRW_DBG(" reading pag num = "); DRW_DBGH(pn); + pi.dataSize = buff3.getRawLong32(); + pi.startOffset = buff3.getRawLong64(); + secInfo.pages[pn]= pi;//complete copy in secInfo + DRW_DBG("\n Page number= "); DRW_DBGH(secInfo.pages[pn].Id); + DRW_DBG("\n size in file= "); DRW_DBGH(secInfo.pages[pn].size); + DRW_DBG("\n address in file= "); DRW_DBGH(secInfo.pages[pn].address); + DRW_DBG("\n Data size= "); DRW_DBGH(secInfo.pages[pn].dataSize); + DRW_DBG("\n Start offset= "); DRW_DBGH(secInfo.pages[pn].startOffset); DRW_DBG("\n"); + } + //do not save empty section + if (!secInfo.name.empty()) { + DRW_DBG("Saved section Name= "); DRW_DBG( secInfo.name.c_str() ); DRW_DBG("\n"); + sections[secEnum::getEnum(secInfo.name)] = secInfo; + } + } + delete[]tmpDecompSec; + + if (! fileBuf->isGood()) + return false; + DRW_DBG("\ndwgReader18::readFileHeader END\n\n"); + return true; +} + +bool dwgReader18::readDwgHeader(DRW_Header& hdr){ + DRW_DBG("dwgReader18::readDwgHeader\n"); + dwgSectionInfo si = sections[secEnum::HEADER]; + if (si.Id<0)//not found, ends + return false; + bool ret = parseDataPage(si/*, objData*/); + //global store for uncompressed data of all pages + uncompSize=si.size; + if (ret) { + dwgBuffer dataBuf(objData, si.size, &decoder); + DRW_DBG("Header section sentinel= "); + checkSentinel(&dataBuf, secEnum::HEADER, true); + if (version == DRW::AC1018){ + ret = dwgReader::readDwgHeader(hdr, &dataBuf, &dataBuf); + } else { + dwgBuffer handleBuf(objData, si.size, &decoder); + ret = dwgReader::readDwgHeader(hdr, &dataBuf, &handleBuf); + } + } + //Cleanup: global store for uncompressed data of all pages + if (objData != NULL){ + delete[] objData; + objData = NULL; + } + return ret; +} + + +bool dwgReader18::readDwgClasses(){ + DRW_DBG("\ndwgReader18::readDwgClasses\n"); + dwgSectionInfo si = sections[secEnum::CLASSES]; + if (si.Id<0)//not found, ends + return false; + bool ret = parseDataPage(si/*, objData*/); + //global store for uncompressed data of all pages + uncompSize=si.size; + if (ret) { + + dwgBuffer dataBuf(objData, uncompSize, &decoder); + + DRW_DBG("classes section sentinel= "); + checkSentinel(&dataBuf, secEnum::CLASSES, true); + + duint32 size = dataBuf.getRawLong32(); + DRW_DBG("\ndata size in bytes "); DRW_DBG(size); + if (version > DRW::AC1021 && maintenanceVersion > 3) { //2010+ + duint32 hSize = dataBuf.getRawLong32(); + DRW_DBG("\n2010+ & MV> 3, height 32b: "); DRW_DBG(hSize); + } + duint32 bitSize = 0; + if (version > DRW::AC1021) {//2007+ + bitSize = dataBuf.getRawLong32(); + DRW_DBG("\ntotal size in bits "); DRW_DBG(bitSize); +} + duint32 maxClassNum = dataBuf.getBitShort(); + DRW_DBG("\nMaximum class number "); DRW_DBG(maxClassNum); + DRW_DBG("\nRc 1 "); DRW_DBG(dataBuf.getRawChar8()); + DRW_DBG("\nRc 2 "); DRW_DBG(dataBuf.getRawChar8()); + DRW_DBG("\nBit "); DRW_DBG(dataBuf.getBit()); + + /*******************************/ + dwgBuffer *strBuf = &dataBuf; + dwgBuffer strBuff(objData, uncompSize, &decoder); + //prepare string stream for 2007+ + if (version > DRW::AC1021) {//2007+ + strBuf = &strBuff; + duint32 strStartPos = bitSize+191;//size in bits + 24 bytes (sn+size+hSize) - 1 bit (endbit) + DRW_DBG("\nstrStartPos: "); DRW_DBG(strStartPos); + strBuff.setPosition(strStartPos >> 3); + strBuff.setBitPos(strStartPos & 7); + DRW_DBG("\nclasses strings buff.getPosition: "); DRW_DBG(strBuff.getPosition()); + DRW_DBG("\nclasses strings buff.getBitPos: "); DRW_DBG(strBuff.getBitPos()); + DRW_DBG("\nendBit "); DRW_DBG(strBuff.getBit()); + strStartPos -= 16;//decrement 16 bits + DRW_DBG("\nstrStartPos: "); DRW_DBG(strStartPos); + strBuff.setPosition(strStartPos >> 3); + strBuff.setBitPos(strStartPos & 7); + DRW_DBG("\nclasses strings buff.getPosition: "); DRW_DBG(strBuff.getPosition()); + DRW_DBG("\nclasses strings buff.getBitPos: "); DRW_DBG(strBuff.getBitPos()); + duint32 strDataSize = strBuff.getRawShort16(); + DRW_DBG("\nstrDataSize: "); DRW_DBG(strDataSize); + if (strDataSize & 0x8000) { + strStartPos -= 16;//decrement 16 bits + strDataSize &= 0x7FFF; //strip 0x8000; + strBuff.setPosition(strStartPos >> 3); + strBuff.setBitPos(strStartPos & 7); + duint32 hiSize = strBuff.getRawShort16(); + strDataSize |= (hiSize << 15); + } + strStartPos -= strDataSize; + DRW_DBG("\nstrStartPos: "); DRW_DBG(strStartPos); + strBuff.setPosition(strStartPos >> 3); + strBuff.setBitPos(strStartPos & 7); + DRW_DBG("\nclasses strings buff.getPosition: "); DRW_DBG(strBuff.getPosition()); + DRW_DBG("\nclasses strings buff.getBitPos: "); DRW_DBG(strBuff.getBitPos()); + } + + /*******************************/ + + duint32 endDataPos = maxClassNum-499; + DRW_DBG("\nbuff.getPosition: "); DRW_DBG(dataBuf.getPosition()); + for (duint32 i= 0; iparseDwg(version, &dataBuf, strBuf); + classesmap[cl->classNum] = cl; + DRW_DBG("\nbuff.getPosition: "); DRW_DBG(dataBuf.getPosition()); + } + DRW_DBG("\nend classes data buff.getPosition: "); DRW_DBG(dataBuf.getPosition()); + DRW_DBG("\nend classes data buff.getBitPos: "); DRW_DBG(dataBuf.getBitPos()); + DRW_DBG("\nend classes strings buff.getPosition: "); DRW_DBG(strBuf->getPosition()); + DRW_DBG("\nend classes strings buff.getBitPos: "); DRW_DBG(strBuf->getBitPos()); + +/***************/ + + strBuf->setPosition(strBuf->getPosition()+1);//skip remaining bits + DRW_DBG("\nCRC: "); DRW_DBGH(strBuf->getRawShort16()); + if (version > DRW::AC1018){ + DRW_DBG("\nunknown CRC: "); DRW_DBGH(strBuf->getRawShort16()); + } + DRW_DBG("\nclasses section end sentinel= "); + checkSentinel(strBuf, secEnum::CLASSES, false); + + ret = strBuf->isGood(); + } + //Cleanup: global store for uncompressed data of all pages + if (objData != NULL){ + delete[] objData; + objData = NULL; + } + return ret; +} + + +/*********** objects map ************************/ +/** Note: object map are split in sections with max size 2035? + * heach section are 2 bytes size + data bytes + 2 bytes crc + * size value are data bytes + 2 and to calculate crc are used + * 2 bytes size + data bytes + * last section are 2 bytes size + 2 bytes crc (size value always 2) +**/ +bool dwgReader18::readDwgHandles() { + DRW_DBG("\ndwgReader18::readDwgHandles\n"); + dwgSectionInfo si = sections[secEnum::HANDLES]; + if (si.Id<0)//not found, ends + return false; + bool ret = parseDataPage(si); + //global store for uncompressed data of all pages + uncompSize=si.size; + if (ret) { + + dwgBuffer dataBuf(objData, uncompSize, &decoder); + + ret = dwgReader::readDwgHandles(&dataBuf, 0, si.size); + } + //Cleanup: global store for uncompressed data of all pages + if (objData != NULL){ + delete[] objData; + objData = NULL; + uncompSize = 0; + } + return ret; +} + + +/*********** objects ************************/ +/** + * Reads all the object referenced in the object map section of the DWG file + * (using their object file offsets) + */ +bool dwgReader18::readDwgTables(DRW_Header& hdr) { + DRW_DBG("\ndwgReader18::readDwgTables\n"); + dwgSectionInfo si = sections[secEnum::OBJECTS]; + + if (si.Id<0)//not found, ends + return false; + bool ret = parseDataPage(si/*, objData*/); + //global store for uncompressed data of all pages + uncompSize=si.size; + if (ret) { + + dwgBuffer dataBuf(objData, uncompSize, &decoder); + + ret = dwgReader::readDwgTables(hdr, &dataBuf); + + } + //Do not delete objData in this point, needed in the remaining code + return ret; +} diff --git a/extlib/libdxfrw/intern/dwgreader18.h b/extlib/libdxfrw/intern/dwgreader18.h new file mode 100644 index 0000000..f814096 --- /dev/null +++ b/extlib/libdxfrw/intern/dwgreader18.h @@ -0,0 +1,99 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DWGREADER18_H +#define DWGREADER18_H + +#include +#include +#include "dwgreader.h" +//#include "../drw_textcodec.h" +#include "dwgbuffer.h" + +static const int DRW_magicNum18[] = { + 0x29, 0x23, 0xbe, 0x84, 0xe1, 0x6c, 0xd6, 0xae, + 0x52, 0x90, 0x49, 0xf1, 0xf1, 0xbb, 0xe9, 0xeb, + 0xb3, 0xa6, 0xdb, 0x3c, 0x87, 0x0c, 0x3e, 0x99, + 0x24, 0x5e, 0x0d, 0x1c, 0x06, 0xb7, 0x47, 0xde, + 0xb3, 0x12, 0x4d, 0xc8, 0x43, 0xbb, 0x8b, 0xa6, + 0x1f, 0x03, 0x5a, 0x7d, 0x09, 0x38, 0x25, 0x1f, + 0x5d, 0xd4, 0xcb, 0xfc, 0x96, 0xf5, 0x45, 0x3b, + 0x13, 0x0d, 0x89, 0x0a, 0x1c, 0xdb, 0xae, 0x32, + 0x20, 0x9a, 0x50, 0xee, 0x40, 0x78, 0x36, 0xfd, + 0x12, 0x49, 0x32, 0xf6, 0x9e, 0x7d, 0x49, 0xdc, + 0xad, 0x4f, 0x14, 0xf2, 0x44, 0x40, 0x66, 0xd0, + 0x6b, 0xc4, 0x30, 0xb7, 0x32, 0x3b, 0xa1, 0x22, + 0xf6, 0x22, 0x91, 0x9d, 0xe1, 0x8b, 0x1f, 0xda, + 0xb0, 0xca, 0x99, 0x02 +}; + +static const int DRW_magicNumEnd18[] = { + 0xf8, 0x46, 0x6a, 0x04, 0x96, 0x73, 0x0e, 0xd9, + 0x16, 0x2f, 0x67, 0x68, 0xd4, 0xf7, 0x4a, 0x4a, + 0xd0, 0x57, 0x68, 0x76}; + +class dwgReader18 : public dwgReader { +public: + dwgReader18(std::istream *stream, dwgR *p):dwgReader(stream, p){ + objData = NULL; + } + virtual ~dwgReader18(){ + if (objData != NULL) + delete[] objData; + } + bool readMetaData(); + bool readFileHeader(); + bool readDwgHeader(DRW_Header& hdr); + bool readDwgClasses(); + bool readDwgHandles(); + bool readDwgTables(DRW_Header& hdr); + bool readDwgBlocks(DRW_Interface& intfa){ + bool ret = true; + dwgBuffer dataBuf(objData, uncompSize, &decoder); + ret = dwgReader::readDwgBlocks(intfa, &dataBuf); + return ret; + } + + virtual bool readDwgEntities(DRW_Interface& intfa){ + bool ret = true; + dwgBuffer dataBuf(objData, uncompSize, &decoder); + ret = dwgReader::readDwgEntities(intfa, &dataBuf); + return ret; + } + virtual bool readDwgObjects(DRW_Interface& intfa){ + bool ret = true; + dwgBuffer dataBuf(objData, uncompSize, &decoder); + ret = dwgReader::readDwgObjects(intfa, &dataBuf); + return ret; + } + +// bool readDwgEntity(objHandle& obj, DRW_Interface& intfa){ +// bool ret = true; +// return ret; +// } + +protected: + duint8 *objData; + duint64 uncompSize; + +private: + void genMagicNumber(); +// dwgBuffer* bufObj; + void parseSysPage(duint8 *decompSec, duint32 decompSize); //called: Section page map: 0x41630e3b + bool parseDataPage(dwgSectionInfo si/*, duint8 *dData*/); //called ???: Section map: 0x4163003b + duint32 checksum(duint32 seed, duint8* data, duint32 sz); + +private: +duint32 securityFlags; +}; + +#endif // DWGREADER18_H diff --git a/extlib/libdxfrw/intern/dwgreader21.cpp b/extlib/libdxfrw/intern/dwgreader21.cpp new file mode 100644 index 0000000..1a3af93 --- /dev/null +++ b/extlib/libdxfrw/intern/dwgreader21.cpp @@ -0,0 +1,487 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "drw_dbg.h" +#include "dwgreader21.h" +#include "drw_textcodec.h" +#include "../libdwgr.h" + +bool dwgReader21::readMetaData() { + version = parent->getVersion(); + decoder.setVersion(version, false); + DRW_DBG("dwgReader21::readFileHeader()\n"); + DRW_DBG("dwgReader21::parsing metadata\n"); + if (! fileBuf->setPosition(11)) + return false; + maintenanceVersion = fileBuf->getRawChar8(); + DRW_DBG("maintenance version= "); DRW_DBGH(maintenanceVersion); + DRW_DBG("\nbyte at 0x0C= "); DRW_DBG(fileBuf->getRawChar8()); + previewImagePos = fileBuf->getRawLong32(); + DRW_DBG("previewImagePos (seekerImageData) = "); DRW_DBG(previewImagePos); + DRW_DBG("\n\napp writer version= "); DRW_DBGH(fileBuf->getRawChar8()); + DRW_DBG("\napp writer maintenance version= "); DRW_DBGH(fileBuf->getRawChar8()); + duint16 cp = fileBuf->getRawShort16(); + DRW_DBG("\ncodepage= "); DRW_DBG(cp); + if (cp == 30) + decoder.setCodePage("ANSI_1252", false); + /* UNKNOUWN SECTION 2 bytes*/ + DRW_DBG("\nUNKNOWN SECTION= "); DRW_DBG(fileBuf->getRawShort16()); + DRW_DBG("\nUNKNOUWN SECTION 3b= "); DRW_DBG(fileBuf->getRawChar8()); + duint32 secType = fileBuf->getRawLong32(); + DRW_DBG("\nsecurity type flag= "); DRW_DBGH(secType); + /* UNKNOWN2 SECTION 4 bytes*/ + DRW_DBG("\nUNKNOWN SECTION 4bytes= "); DRW_DBG(fileBuf->getRawLong32()); + + DRW_DBG("\nSummary info address= "); DRW_DBGH(fileBuf->getRawLong32()); + DRW_DBG("\nVBA project address= "); DRW_DBGH(fileBuf->getRawLong32()); + DRW_DBG("\n0x00000080 32b= "); DRW_DBGH(fileBuf->getRawLong32()); + DRW_DBG("\nApp info address= "); DRW_DBGH(fileBuf->getRawLong32()); + //current position are 0x30 from here to 0x80 are undocumented + DRW_DBG("\nAnother address? = "); DRW_DBGH(fileBuf->getRawLong32()); + return true; +} + +bool dwgReader21::parseSysPage(duint64 sizeCompressed, duint64 sizeUncompressed, duint64 correctionFactor, duint64 offset, duint8 *decompData){ + //round to 8 + duint64 alsize = (sizeCompressed + 7) &(-8); + //minimum RS chunk: + duint32 chunks = (((alsize * correctionFactor)+238)/239); + duint64 fpsize = chunks * 255; + + if (! fileBuf->setPosition(offset)) + return false; + duint8 *tmpDataRaw = new duint8[fpsize]; + fileBuf->getBytes(tmpDataRaw, fpsize); + duint8 *tmpDataRS = new duint8[fpsize]; + dwgRSCodec::decode239I(tmpDataRaw, tmpDataRS, fpsize/255); + dwgCompressor::decompress21(tmpDataRS, decompData, sizeCompressed, sizeUncompressed); + delete[]tmpDataRaw; + delete[]tmpDataRS; + return true; +} + +bool dwgReader21::parseDataPage(dwgSectionInfo si, duint8 *dData){ + DRW_DBG("parseDataPage, section size: "); DRW_DBG(si.size); + for (std::map::iterator it=si.pages.begin(); it!=si.pages.end(); ++it){ + dwgPageInfo pi = it->second; + if (!fileBuf->setPosition(pi.address)) + return false; + + duint8 *tmpPageRaw = new duint8[pi.size]; + fileBuf->getBytes(tmpPageRaw, pi.size); + #ifdef DRW_DBG_DUMP + DRW_DBG("\nSection OBJECTS raw data=\n"); + for (unsigned int i=0, j=0; i< pi.size;i++) { + DRW_DBGH( (unsigned char)tmpPageRaw[i]); + if (j == 7) { DRW_DBG("\n"); j = 0; + } else { DRW_DBG(", "); j++; } + } DRW_DBG("\n"); + #endif + + duint8 *tmpPageRS = new duint8[pi.size]; + duint8 chunks =pi.size / 255; + dwgRSCodec::decode251I(tmpPageRaw, tmpPageRS, chunks); + #ifdef DRW_DBG_DUMP + DRW_DBG("\nSection OBJECTS RS data=\n"); + for (unsigned int i=0, j=0; i< pi.size;i++) { + DRW_DBGH( (unsigned char)tmpPageRS[i]); + if (j == 7) { DRW_DBG("\n"); j = 0; + } else { DRW_DBG(", "); j++; } + } DRW_DBG("\n"); + #endif + + DRW_DBG("\npage uncomp size: "); DRW_DBG(pi.uSize); DRW_DBG(" comp size: "); DRW_DBG(pi.cSize); + DRW_DBG("\noffset: "); DRW_DBG(pi.startOffset); + duint8 *pageData = dData + pi.startOffset; + dwgCompressor::decompress21(tmpPageRS, pageData, pi.cSize, pi.uSize); + + #ifdef DRW_DBG_DUMP + DRW_DBG("\n\nSection OBJECTS decompressed data=\n"); + for (unsigned int i=0, j=0; i< pi.uSize;i++) { + DRW_DBGH( (unsigned char)pageData[i]); + if (j == 7) { DRW_DBG("\n"); j = 0; + } else { DRW_DBG(", "); j++; } + } DRW_DBG("\n"); + #endif + + delete[]tmpPageRaw; + delete[]tmpPageRS; + } + DRW_DBG("\n"); + return true; +} + +bool dwgReader21::readFileHeader() { + + DRW_DBG("\n\ndwgReader21::parsing file header\n"); + if (! fileBuf->setPosition(0x80)) + return false; + duint8 fileHdrRaw[0x2FD];//0x3D8 + fileBuf->getBytes(fileHdrRaw, 0x2FD); + duint8 fileHdrdRS[0x2CD]; + dwgRSCodec::decode239I(fileHdrRaw, fileHdrdRS, 3); + +#ifdef DRW_DBG_DUMP + DRW_DBG("\ndwgReader21::parsed Reed Solomon decode:\n"); + int j = 0; + for (int i=0, j=0; i<0x2CD; i++){ + DRW_DBGH( (unsigned char)fileHdrdRS[i]); + if (j== 15){ j=0; DRW_DBG("\n"); + } else{ j++; DRW_DBG(", "); } + } DRW_DBG("\n"); +#endif + + dwgBuffer fileHdrBuf(fileHdrdRS, 0x2CD, &decoder); + DRW_DBG("\nCRC 64b= "); DRW_DBGH(fileHdrBuf.getRawLong64()); + DRW_DBG("\nunknown key 64b= "); DRW_DBGH(fileHdrBuf.getRawLong64()); + DRW_DBG("\ncomp data CRC 64b= "); DRW_DBGH(fileHdrBuf.getRawLong64()); + dint32 fileHdrCompLength = fileHdrBuf.getRawLong32(); + DRW_DBG("\ncompr len 4bytes= "); DRW_DBG(fileHdrCompLength); + dint32 fileHdrCompLength2 = fileHdrBuf.getRawLong32(); + DRW_DBG("\nlength2 4bytes= "); DRW_DBG(fileHdrCompLength2); + + int fileHdrDataLength = 0x110; + duint8 *fileHdrData; + if (fileHdrCompLength < 0) { + fileHdrDataLength = fileHdrCompLength * -1; + fileHdrData = new duint8[fileHdrDataLength]; + fileHdrBuf.getBytes(fileHdrData, fileHdrDataLength); + }else { + DRW_DBG("\ndwgReader21:: file header are compressed:\n"); + duint8 *compByteStr = new duint8[fileHdrCompLength]; + fileHdrBuf.getBytes(compByteStr, fileHdrCompLength); + fileHdrData = new duint8[fileHdrDataLength]; + dwgCompressor::decompress21(compByteStr, fileHdrData, fileHdrCompLength, fileHdrDataLength); + delete[] compByteStr; + } + +#ifdef DRW_DBG_DUMP + DRW_DBG("\ndwgReader21::parsed file header:\n"); + for (int i=0, j=0; isectionPageMapTmp; + +// dwgPageInfo *m_pages= new dwgPageInfo[PagesMaxId+1]; + while (PagesMapSizeUncompressed > i ) { + duint64 size = PagesMapBuf.getRawLong64(); + dint64 id = PagesMapBuf.getRawLong64(); + duint64 ind = id > 0 ? id : -id; + i += 16; + + DRW_DBG("Page gap= "); DRW_DBG(id); DRW_DBG(" Page num= "); DRW_DBG(ind); DRW_DBG(" size= "); DRW_DBGH(size); + DRW_DBG(" address= "); DRW_DBGH(address); DRW_DBG("\n"); + sectionPageMapTmp[ind] = dwgPageInfo(ind, address,size); + address += size; + //TODO num can be negative indicating gap +// seek += offset; + } + delete[]PagesMapData; + + DRW_DBG("\n*** dwgReader21: Processing Section Map ***\n"); + duint8 *SectionsMapData = new duint8[SectionsMapSizeUncompressed]; + dwgPageInfo sectionMap = sectionPageMapTmp[SectionsMapId]; + ret = parseSysPage(SectionsMapSizeCompressed, SectionsMapSizeUncompressed, SectionsMapCorrectionFactor, sectionMap.address, SectionsMapData); + if (!ret) + return false; + +//reads sections: + //Note: compressed value are not stored in file then, commpresed field are use to store + // encoding value + dwgBuffer SectionsMapBuf(SectionsMapData, SectionsMapSizeUncompressed, &decoder); + duint8 nextId =1; + while(SectionsMapBuf.getPosition() < SectionsMapBuf.size()){ + dwgSectionInfo secInfo; + secInfo.size = SectionsMapBuf.getRawLong64(); + DRW_DBG("\nSize of section (data size)= "); DRW_DBGH(secInfo.size); + secInfo.maxSize = SectionsMapBuf.getRawLong64(); + DRW_DBG("\nMax Decompressed Size= "); DRW_DBGH(secInfo.maxSize); + secInfo.encrypted = SectionsMapBuf.getRawLong64(); + //encrypted (doc: 0 no, 1 yes, 2 unkn) on read: objects 0 and encrypted yes + DRW_DBG("\nencription= "); DRW_DBGH(secInfo.encrypted); + DRW_DBG("\nHashCode = "); DRW_DBGH(SectionsMapBuf.getRawLong64()); + duint64 SectionNameLength = SectionsMapBuf.getRawLong64(); + DRW_DBG("\nSectionNameLength = "); DRW_DBG(SectionNameLength); + DRW_DBG("\nUnknown = "); DRW_DBGH(SectionsMapBuf.getRawLong64()); + secInfo.compressed = SectionsMapBuf.getRawLong64(); + DRW_DBG("\nEncoding (compressed) = "); DRW_DBGH(secInfo.compressed); + secInfo.pageCount = SectionsMapBuf.getRawLong64(); + DRW_DBG("\nPage count= "); DRW_DBGH(secInfo.pageCount); + secInfo.name = SectionsMapBuf.getUCSStr(SectionNameLength); + DRW_DBG("\nSection name = "); DRW_DBG(secInfo.name); DRW_DBG("\n"); + + for (unsigned int i=0; i< secInfo.pageCount; i++){ + duint64 po = SectionsMapBuf.getRawLong64(); + duint32 ds = SectionsMapBuf.getRawLong64(); + duint32 pn = SectionsMapBuf.getRawLong64(); + DRW_DBG(" pag Id = "); DRW_DBGH(pn); DRW_DBG(" data size = "); DRW_DBGH(ds); + dwgPageInfo pi = sectionPageMapTmp[pn]; //get a copy + pi.dataSize = ds; + pi.startOffset = po; + pi.uSize = SectionsMapBuf.getRawLong64(); + pi.cSize = SectionsMapBuf.getRawLong64(); + secInfo.pages[pn]= pi;//complete copy in secInfo + DRW_DBG("\n Page number= "); DRW_DBGH(secInfo.pages[pn].Id); + DRW_DBG("\n address in file= "); DRW_DBGH(secInfo.pages[pn].address); + DRW_DBG("\n size in file= "); DRW_DBGH(secInfo.pages[pn].size); + DRW_DBG("\n Data size= "); DRW_DBGH(secInfo.pages[pn].dataSize); + DRW_DBG("\n Start offset= "); DRW_DBGH(secInfo.pages[pn].startOffset); + DRW_DBG("\n Page uncompressed size = "); DRW_DBGH(secInfo.pages[pn].uSize); + DRW_DBG("\n Page compressed size = "); DRW_DBGH(secInfo.pages[pn].cSize); + + DRW_DBG("\n Page checksum = "); DRW_DBGH(SectionsMapBuf.getRawLong64()); + DRW_DBG("\n Page CRC = "); DRW_DBGH(SectionsMapBuf.getRawLong64()); DRW_DBG("\n"); + } + + if (!secInfo.name.empty()) { + secInfo.Id = nextId++; + DRW_DBG("Saved section Name= "); DRW_DBG( secInfo.name.c_str() ); DRW_DBG("\n"); + sections[secEnum::getEnum(secInfo.name)] = secInfo; + } + } + delete[]SectionsMapData; + + if (! fileBuf->isGood()) + return false; + + DRW_DBG("\ndwgReader21::readFileHeader END\n"); + return true; +} + +bool dwgReader21::readDwgHeader(DRW_Header& hdr){ + DRW_DBG("\ndwgReader21::readDwgHeader\n"); + dwgSectionInfo si = sections[secEnum::HEADER]; + if (si.Id<0)//not found, ends + return false; + DRW_DBG("\nprepare section of size "); DRW_DBG(si.size);DRW_DBG("\n"); + duint8 *tmpHeaderData = new duint8[si.size]; + bool ret = dwgReader21::parseDataPage(si, tmpHeaderData); + if (!ret) { + delete[]tmpHeaderData; + return ret; + } + + dwgBuffer dataBuf(tmpHeaderData, si.size, &decoder); + dwgBuffer handleBuf(tmpHeaderData, si.size, &decoder); + DRW_DBG("Header section sentinel= "); + checkSentinel(&dataBuf, secEnum::HEADER, true); + ret = dwgReader::readDwgHeader(hdr, &dataBuf, &handleBuf); + delete[]tmpHeaderData; + return ret; +} + +bool dwgReader21::readDwgClasses(){ + DRW_DBG("\ndwgReader21::readDwgClasses"); + dwgSectionInfo si = sections[secEnum::CLASSES]; + if (si.Id<0)//not found, ends + return false; + + DRW_DBG("\nprepare section of size "); DRW_DBG(si.size);DRW_DBG("\n"); + duint8 *tmpClassesData = new duint8[si.size]; + bool ret = dwgReader21::parseDataPage(si, tmpClassesData); + if (!ret) + return ret; + + dwgBuffer buff(tmpClassesData, si.size, &decoder); + DRW_DBG("classes section sentinel= "); + checkSentinel(&buff, secEnum::CLASSES, true); + + duint32 size = buff.getRawLong32(); + DRW_DBG("\ndata size in bytes "); DRW_DBG(size); + + duint32 bitSize = buff.getRawLong32(); + DRW_DBG("\ntotal size in bits "); DRW_DBG(bitSize); + + duint32 maxClassNum = buff.getBitShort(); + DRW_DBG("\nMaximum class number "); DRW_DBG(maxClassNum); + DRW_DBG("\nRc 1 "); DRW_DBG(buff.getRawChar8()); + DRW_DBG("\nRc 2 "); DRW_DBG(buff.getRawChar8()); + DRW_DBG("\nBit "); DRW_DBG(buff.getBit()); + + /*******************************/ + //prepare string stream + dwgBuffer strBuff(tmpClassesData, si.size, &decoder); + duint32 strStartPos = bitSize + 159;//size in bits + 20 bytes (sn+size) - 1 bit (endbit) + DRW_DBG("\nstrStartPos: "); DRW_DBG(strStartPos); + strBuff.setPosition(strStartPos >> 3); + strBuff.setBitPos(strStartPos & 7); + DRW_DBG("\nclasses strings buff.getPosition: "); DRW_DBG(strBuff.getPosition()); + DRW_DBG("\nclasses strings buff.getBitPos: "); DRW_DBG(strBuff.getBitPos()); + DRW_DBG("\nendBit "); DRW_DBG(strBuff.getBit()); + strStartPos -= 16;//decrement 16 bits + DRW_DBG("\nstrStartPos: "); DRW_DBG(strStartPos); + strBuff.setPosition(strStartPos >> 3); + strBuff.setBitPos(strStartPos & 7); + DRW_DBG("\nclasses strings buff.getPosition: "); DRW_DBG(strBuff.getPosition()); + DRW_DBG("\nclasses strings buff.getBitPos: "); DRW_DBG(strBuff.getBitPos()); + duint32 strDataSize = strBuff.getRawShort16(); + DRW_DBG("\nstrDataSize: "); DRW_DBG(strDataSize); + if (strDataSize & 0x8000) { + strStartPos -= 16;//decrement 16 bits + strDataSize &= 0x7FFF; //strip 0x8000; + strBuff.setPosition(strStartPos >> 3); + strBuff.setBitPos(strStartPos & 7); + duint32 hiSize = strBuff.getRawShort16(); + strDataSize |= (hiSize << 15); + } + strStartPos -= strDataSize; + DRW_DBG("\nstrStartPos: "); DRW_DBG(strStartPos); + strBuff.setPosition(strStartPos >> 3); + strBuff.setBitPos(strStartPos & 7); + DRW_DBG("\nclasses strings buff.getPosition: "); DRW_DBG(strBuff.getPosition()); + DRW_DBG("\nclasses strings buff.getBitPos: "); DRW_DBG(strBuff.getBitPos()); + + + /*******************************/ + + duint32 endDataPos = maxClassNum-499; + DRW_DBG("\nbuff.getPosition: "); DRW_DBG(buff.getPosition()); + for (duint32 i= 0; iparseDwg(version, &buff, &strBuff); + classesmap[cl->classNum] = cl; + DRW_DBG("\nbuff.getPosition: "); DRW_DBG(buff.getPosition()); + } + DRW_DBG("\nend classes data buff.getPosition: "); DRW_DBG(buff.getPosition()); + DRW_DBG("\nend classes data buff.getBitPos: "); DRW_DBG(buff.getBitPos()); + + buff.setPosition(size+20);//sizeVal+sn+32bSize + DRW_DBG("\nCRC: "); DRW_DBGH(buff.getRawShort16()); + DRW_DBG("\nclasses section end sentinel= "); + checkSentinel(&buff, secEnum::CLASSES, true); + delete[]tmpClassesData; + return buff.isGood(); +} + + +bool dwgReader21::readDwgHandles(){ + DRW_DBG("\ndwgReader21::readDwgHandles"); + dwgSectionInfo si = sections[secEnum::HANDLES]; + if (si.Id<0)//not found, ends + return false; + + DRW_DBG("\nprepare section of size "); DRW_DBG(si.size);DRW_DBG("\n"); + duint8 *tmpHandlesData = new duint8[si.size]; + bool ret = dwgReader21::parseDataPage(si, tmpHandlesData); + if (!ret) + return ret; + + dwgBuffer dataBuf(tmpHandlesData, si.size, &decoder); + + ret = dwgReader::readDwgHandles(&dataBuf, 0, si.size); + delete[]tmpHandlesData; + return ret; +} + +/*********** objects ************************/ +/** + * Reads all the object referenced in the object map section of the DWG file + * (using their object file offsets) + */ +bool dwgReader21::readDwgTables(DRW_Header& hdr) { + DRW_DBG("\ndwgReader21::readDwgTables\n"); + dwgSectionInfo si = sections[secEnum::OBJECTS]; + if (si.Id<0)//not found, ends + return false; + + DRW_DBG("\nprepare section of size "); DRW_DBG(si.size);DRW_DBG("\n"); + dataSize = si.size; + objData = new duint8 [dataSize]; + bool ret = dwgReader21::parseDataPage(si, objData); + if (!ret) + return ret; + + DRW_DBG("readDwgTables total data size= "); DRW_DBG(dataSize); DRW_DBG("\n"); + dwgBuffer dataBuf(objData, dataSize, &decoder); + ret = dwgReader::readDwgTables(hdr, &dataBuf); + + return ret; +} + + +bool dwgReader21::readDwgBlocks(DRW_Interface& intfa){ + bool ret = true; + dwgBuffer dataBuf(objData, dataSize, &decoder); + ret = dwgReader::readDwgBlocks(intfa, &dataBuf); + return ret; + + return false; +} diff --git a/extlib/libdxfrw/intern/dwgreader21.h b/extlib/libdxfrw/intern/dwgreader21.h new file mode 100644 index 0000000..f95c77a --- /dev/null +++ b/extlib/libdxfrw/intern/dwgreader21.h @@ -0,0 +1,65 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DWGREADER21_H +#define DWGREADER21_H + +#include +#include +#include "drw_textcodec.h" +#include "dwgbuffer.h" +#include "dwgreader.h" + +//reader for AC1021 aka v2007, chapter 5 +class dwgReader21 : public dwgReader { +public: + dwgReader21(std::istream *stream, dwgR *p):dwgReader(stream, p){ + objData = NULL; + dataSize = 0; + } + virtual ~dwgReader21(){ + if (objData != NULL) + delete[] objData; + } + bool readMetaData(); + bool readFileHeader(); + bool readDwgHeader(DRW_Header& hdr); + bool readDwgClasses(); + bool readDwgHandles(); + bool readDwgTables(DRW_Header& hdr); + bool readDwgBlocks(DRW_Interface& intfa); + virtual bool readDwgEntities(DRW_Interface& intfa){ + bool ret = true; + dwgBuffer dataBuf(objData, dataSize, &decoder); + ret = dwgReader::readDwgEntities(intfa, &dataBuf); + return ret; + } + virtual bool readDwgObjects(DRW_Interface& intfa){ + bool ret = true; + dwgBuffer dataBuf(objData, dataSize, &decoder); + ret = dwgReader::readDwgObjects(intfa, &dataBuf); + return ret; + } +//bool readDwgEntity(objHandle& obj, DRW_Interface& intfa){ +// return false; +//} + +private: + bool parseSysPage(duint64 sizeCompressed, duint64 sizeUncompressed, duint64 correctionFactor, duint64 offset, duint8 *decompData); + bool parseDataPage(dwgSectionInfo si, duint8 *dData); + + duint8 *objData; + duint64 dataSize; + +}; + +#endif // DWGREADER21_H diff --git a/extlib/libdxfrw/intern/dwgreader24.cpp b/extlib/libdxfrw/intern/dwgreader24.cpp new file mode 100644 index 0000000..295032c --- /dev/null +++ b/extlib/libdxfrw/intern/dwgreader24.cpp @@ -0,0 +1,43 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "drw_dbg.h" +#include "dwgreader24.h" +#include "drw_textcodec.h" +#include "../libdwgr.h" + + +bool dwgReader24::readFileHeader() { + DRW_DBG("dwgReader24::readFileHeader\n"); + bool ret = dwgReader18::readFileHeader(); + DRW_DBG("dwgReader24::readFileHeader END\n"); + return ret; +} + +bool dwgReader24::readDwgHeader(DRW_Header& hdr){ + DRW_DBG("dwgReader24::readDwgHeader\n"); + bool ret = dwgReader18::readDwgHeader(hdr); + DRW_DBG("dwgReader24::readDwgHeader END\n"); + return ret; +} + +bool dwgReader24::readDwgClasses(){ + DRW_DBG("\ndwgReader24::readDwgClasses"); + bool ret = dwgReader18::readDwgClasses(); + DRW_DBG("\ndwgReader24::readDwgClasses END\n"); + return ret; +} diff --git a/extlib/libdxfrw/intern/dwgreader24.h b/extlib/libdxfrw/intern/dwgreader24.h new file mode 100644 index 0000000..e5fc43a --- /dev/null +++ b/extlib/libdxfrw/intern/dwgreader24.h @@ -0,0 +1,56 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DWGREADER24_H +#define DWGREADER24_H + +#include +#include +#include "drw_textcodec.h" +#include "dwgbuffer.h" +#include "dwgreader18.h" + +class dwgReader24 : public dwgReader18 { +public: + dwgReader24(std::istream *stream, dwgR *p):dwgReader18(stream, p){ } + virtual ~dwgReader24(){} + bool readFileHeader(); + bool readDwgHeader(DRW_Header& hdr); + bool readDwgClasses(); +// bool readDwgHandles(){return false;} +// bool readDwgTables(){return false;} + bool readDwgBlocks(DRW_Interface& intfa){ + bool ret = true; + dwgBuffer dataBuf(objData, uncompSize, &decoder); + ret = dwgReader::readDwgBlocks(intfa, &dataBuf); + return ret; + } + virtual bool readDwgEntities(DRW_Interface& intfa){ + bool ret = true; + dwgBuffer dataBuf(objData, uncompSize, &decoder); + ret = dwgReader::readDwgEntities(intfa, &dataBuf); + return ret; + } + virtual bool readDwgObjects(DRW_Interface& intfa){ + bool ret = true; + dwgBuffer dataBuf(objData, uncompSize, &decoder); + ret = dwgReader::readDwgObjects(intfa, &dataBuf); + return ret; + } + +// bool readDwgEntity(objHandle& obj, DRW_Interface& intfa){ +// DRW_UNUSED(obj); +// DRW_UNUSED(intfa); +// return false;} +}; + +#endif // DWGREADER24_H diff --git a/extlib/libdxfrw/intern/dwgreader27.cpp b/extlib/libdxfrw/intern/dwgreader27.cpp new file mode 100644 index 0000000..dea68f6 --- /dev/null +++ b/extlib/libdxfrw/intern/dwgreader27.cpp @@ -0,0 +1,43 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include +#include +#include +#include +#include +#include "drw_dbg.h" +#include "dwgreader27.h" +#include "drw_textcodec.h" +#include "../libdwgr.h" + + +bool dwgReader27::readFileHeader() { + DRW_DBG("dwgReader27::readFileHeader\n"); + bool ret = dwgReader18::readFileHeader(); + DRW_DBG("dwgReader27::readFileHeader END\n"); + return ret; +} + +bool dwgReader27::readDwgHeader(DRW_Header& hdr){ + DRW_DBG("dwgReader27::readDwgHeader\n"); + bool ret = dwgReader18::readDwgHeader(hdr); + DRW_DBG("dwgReader27::readDwgHeader END\n"); + return ret; +} + +bool dwgReader27::readDwgClasses(){ + DRW_DBG("dwgReader27::readDwgClasses"); + bool ret = dwgReader18::readDwgClasses(); + DRW_DBG("\ndwgReader27::readDwgClasses END\n"); + return ret; +} diff --git a/extlib/libdxfrw/intern/dwgreader27.h b/extlib/libdxfrw/intern/dwgreader27.h new file mode 100644 index 0000000..32c67f6 --- /dev/null +++ b/extlib/libdxfrw/intern/dwgreader27.h @@ -0,0 +1,55 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DWGREADER27_H +#define DWGREADER27_H + +#include +#include +#include "drw_textcodec.h" +#include "dwgbuffer.h" +#include "dwgreader18.h" + +class dwgReader27 : public dwgReader18 { +public: + dwgReader27(std::istream *stream, dwgR *p):dwgReader18(stream, p){ } + virtual ~dwgReader27(){} + bool readFileHeader(); + bool readDwgHeader(DRW_Header& hdr); + bool readDwgClasses(); +// bool readDwgHandles(){return false;} +// bool readDwgTables(){return false;} + bool readDwgBlocks(DRW_Interface& intfa){ + bool ret = true; + dwgBuffer dataBuf(objData, uncompSize, &decoder); + ret = dwgReader::readDwgBlocks(intfa, &dataBuf); + return ret; + } + virtual bool readDwgEntities(DRW_Interface& intfa){ + bool ret = true; + dwgBuffer dataBuf(objData, uncompSize, &decoder); + ret = dwgReader::readDwgEntities(intfa, &dataBuf); + return ret; + } + virtual bool readDwgObjects(DRW_Interface& intfa){ + bool ret = true; + dwgBuffer dataBuf(objData, uncompSize, &decoder); + ret = dwgReader::readDwgObjects(intfa, &dataBuf); + return ret; + } +// bool readDwgEntity(objHandle& obj, DRW_Interface& intfa){ +// DRW_UNUSED(obj); +// DRW_UNUSED(intfa); +// return false;} +}; + +#endif // DWGREADER21_H diff --git a/extlib/libdxfrw/intern/dwgutil.cpp b/extlib/libdxfrw/intern/dwgutil.cpp new file mode 100644 index 0000000..8fc6eb3 --- /dev/null +++ b/extlib/libdxfrw/intern/dwgutil.cpp @@ -0,0 +1,694 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include +#include "drw_dbg.h" +#include "dwgutil.h" +#include "rscodec.h" +#include "../libdwgr.h" + +/** utility function + * convert a int to string in hex + **/ +namespace DRW { +std::string toHexStr(int n){ +#if defined(__APPLE__) + char buffer[9]= {'\0'}; + snprintf(buffer,9, "%X", n); + return std::string(buffer); +#else + std::ostringstream Convert; + Convert << std::uppercase << std::hex << n; + return Convert.str(); +#endif +} +} + +/** + * @brief dwgRSCodec::decode239I + * @param in : input data (at least 255*blk bytes) + * @param out : output data (at least 239*blk bytes) + * @param blk number of codewords ( 1 cw == 255 bytes) + */ +void dwgRSCodec::decode239I(unsigned char *in, unsigned char *out, duint32 blk){ + int k=0; + unsigned char data[255]; + RScodec rsc(0x96, 8, 8); //(255, 239) + for (duint32 i=0; i> 2) | (bufC[pos++] << 6); + *ll = (fb & 0x03); + return cont; +} + +duint32 dwgCompressor::longCompressionOffset(){ + duint32 cont = 0; + duint8 ll = bufC[pos++]; + while (ll == 0x00){ + cont += 0xFF; + ll = bufC[pos++]; + } + cont += ll; + return cont; +} + +duint32 dwgCompressor::long20CompressionOffset(){ +// duint32 cont = 0; + duint32 cont = 0x0F; + duint8 ll = bufC[pos++]; + while (ll == 0x00){ +// cont += 0xFF; + ll = bufC[pos++]; + } + cont += ll; + return cont; +} + +duint32 dwgCompressor::litLength18(){ + duint32 cont=0; + duint8 ll = bufC[pos++]; + //no literal length, this byte is next opCode + if (ll > 0x0F) { + pos--; + return 0; + } + + if (ll == 0x00) { + cont = 0x0F; + ll = bufC[pos++]; + while (ll == 0x00){//repeat until ll != 0x00 + cont +=0xFF; + ll = bufC[pos++]; + } + } + cont +=ll; + cont +=3; //already sum 3 + return cont; +} + +void dwgCompressor::decompress18(duint8 *cbuf, duint8 *dbuf, duint32 csize, duint32 dsize){ + bufC = cbuf; + bufD = dbuf; + sizeC = csize -2; + sizeD = dsize; + DRW_DBG("dwgCompressor::decompress, last 2 bytes: "); + DRW_DBGH(bufC[sizeC]);DRW_DBGH(bufC[sizeC+1]);DRW_DBG("\n"); + sizeC = csize; + + duint32 compBytes; + duint32 compOffset; + duint32 litCount; + + pos=0; //current position in compressed buffer + rpos=0; //current position in resulting decompressed buffer + litCount = litLength18(); + //copy first literal length + for (duint32 i=0; i < litCount; ++i) { + bufD[rpos++] = bufC[pos++]; + } + + while (pos < csize && (rpos < dsize+1)){//rpos < dsize to prevent crash more robust are needed + duint8 oc = bufC[pos++]; //next opcode + if (oc == 0x10){ + compBytes = longCompressionOffset()+ 9; + compOffset = twoByteOffset(&litCount) + 0x3FFF; + if (litCount == 0) + litCount= litLength18(); + } else if (oc > 0x11 && oc< 0x20){ + compBytes = (oc & 0x0F) + 2; + compOffset = twoByteOffset(&litCount) + 0x3FFF; + if (litCount == 0) + litCount= litLength18(); + } else if (oc == 0x20){ + compBytes = longCompressionOffset() + 0x21; + compOffset = twoByteOffset(&litCount); + if (litCount == 0) + litCount= litLength18(); + else + oc = 0x00; + } else if (oc > 0x20 && oc< 0x40){ + compBytes = oc - 0x1E; + compOffset = twoByteOffset(&litCount); + if (litCount == 0) + litCount= litLength18(); + } else if ( oc > 0x3F){ + compBytes = ((oc & 0xF0) >> 4) - 1; + duint8 ll2 = bufC[pos++]; + compOffset = (ll2 << 2) | ((oc & 0x0C) >> 2); + litCount = oc & 0x03; + if (litCount < 1){ + litCount= litLength18();} + } else if (oc == 0x11){ + DRW_DBG("dwgCompressor::decompress, end of input stream, Cpos: "); + DRW_DBG(pos);DRW_DBG(", Dpos: ");DRW_DBG(rpos);DRW_DBG("\n"); + return; //end of input stream + } else { //ll < 0x10 + DRW_DBG("WARNING dwgCompressor::decompress, failed, illegal char, Cpos: "); + DRW_DBG(pos);DRW_DBG(", Dpos: ");DRW_DBG(rpos);DRW_DBG("\n"); + return; //fails, not valid + } + //copy "compressed data", TODO Needed verify out of bounds + duint32 remaining = sizeD - (litCount+rpos); + if (remaining < compBytes){ + compBytes = remaining; + DRW_DBG("WARNING dwgCompressor::decompress, bad compBytes size, Cpos: "); + DRW_DBG(pos);DRW_DBG(", Dpos: ");DRW_DBG(rpos);DRW_DBG("\n"); + } + for (duint32 i=0, j= rpos - compOffset -1; i < compBytes; i++) { + bufD[rpos++] = bufD[j++]; + } + //copy "uncompressed data", TODO Needed verify out of bounds + for (duint32 i=0; i < litCount; i++) { + bufD[rpos++] = bufC[pos++]; + } + } + DRW_DBG("WARNING dwgCompressor::decompress, bad out, Cpos: ");DRW_DBG(pos);DRW_DBG(", Dpos: ");DRW_DBG(rpos);DRW_DBG("\n"); +} + + +void dwgCompressor::decrypt18Hdr(duint8 *buf, duint32 size, duint32 offset){ + duint8 max = size / 4; + duint32 secMask = 0x4164536b ^ offset; + duint32* pHdr = (duint32*)buf; + for (duint8 j = 0; j < max; j++) + *pHdr++ ^= secMask; +} + +/*void dwgCompressor::decrypt18Data(duint8 *buf, duint32 size, duint32 offset){ + duint8 max = size / 4; + duint32 secMask = 0x4164536b ^ offset; + duint32* pHdr = (duint32*)buf; + for (duint8 j = 0; j < max; j++) + *pHdr++ ^= secMask; +}*/ + +duint32 dwgCompressor::litLength21(duint8 *cbuf, duint8 oc, duint32 *si){ + + duint32 srcIndex=*si; + + duint32 length = oc + 8; + if (length == 0x17) { + duint32 n = cbuf[srcIndex++]; + length += n; + if (n == 0xff) { + do { + n = cbuf[srcIndex++]; + n |= (duint32)(cbuf[srcIndex++] << 8); + length += n; + } while (n == 0xffff); + } + } + + *si = srcIndex; + return length; +} + +void dwgCompressor::decompress21(duint8 *cbuf, duint8 *dbuf, duint32 csize, duint32 dsize){ + duint32 srcIndex=0; + duint32 dstIndex=0; + duint32 length=0; + duint32 sourceOffset; + duint8 opCode; + + opCode = cbuf[srcIndex++]; + if ((opCode >> 4) == 2){ + srcIndex = srcIndex +2; + length = cbuf[srcIndex++] & 0x07; + } + + while (srcIndex < csize && (dstIndex < dsize+1)){//dstIndex < dsize to prevent crash more robust are needed + if (length == 0) + length = litLength21(cbuf, opCode, &srcIndex); + copyCompBytes21(cbuf, dbuf, length, srcIndex, dstIndex); + srcIndex += length; + dstIndex += length; + if (dstIndex >=dsize) break; //check if last chunk are compressed & terminate + + length = 0; + opCode = cbuf[srcIndex++]; + readInstructions21(cbuf, &srcIndex, &opCode, &sourceOffset, &length); + while (true) { + //prevent crash with corrupted data + if (sourceOffset > dstIndex){ + DRW_DBG("\nWARNING dwgCompressor::decompress21 => sourceOffset> dstIndex.\n"); + DRW_DBG("csize = "); DRW_DBG(csize); DRW_DBG(" srcIndex = "); DRW_DBG(srcIndex); + DRW_DBG("\ndsize = "); DRW_DBG(dsize); DRW_DBG(" dstIndex = "); DRW_DBG(dstIndex); + sourceOffset = dstIndex; + } + //prevent crash with corrupted data + if (length > dsize - dstIndex){ + DRW_DBG("\nWARNING dwgCompressor::decompress21 => length > dsize - dstIndex.\n"); + DRW_DBG("csize = "); DRW_DBG(csize); DRW_DBG(" srcIndex = "); DRW_DBG(srcIndex); + DRW_DBG("\ndsize = "); DRW_DBG(dsize); DRW_DBG(" dstIndex = "); DRW_DBG(dstIndex); + length = dsize - dstIndex; + srcIndex = csize;//force exit + } + sourceOffset = dstIndex-sourceOffset; + for (duint32 i=0; i< length; i++) + dbuf[dstIndex++] = dbuf[sourceOffset+i]; + + length = opCode & 7; + if ((length != 0) || (srcIndex >= csize)) { + break; + } + opCode = cbuf[srcIndex++]; + if ((opCode >> 4) == 0) { + break; + } + if ((opCode >> 4) == 15) { + opCode &= 15; + } + readInstructions21(cbuf, &srcIndex, &opCode, &sourceOffset, &length); + } + } + DRW_DBG("\ncsize = "); DRW_DBG(csize); DRW_DBG(" srcIndex = "); DRW_DBG(srcIndex); + DRW_DBG("\ndsize = "); DRW_DBG(dsize); DRW_DBG(" dstIndex = "); DRW_DBG(dstIndex);DRW_DBG("\n"); +} + +void dwgCompressor::readInstructions21(duint8 *cbuf, duint32 *si, duint8 *oc, duint32 *so, duint32 *l){ + duint32 length; + duint32 srcIndex = *si; + duint32 sourceOffset; + unsigned char opCode = *oc; + switch ((opCode >> 4)) { + case 0: + length = (opCode & 0xf) + 0x13; + sourceOffset = cbuf[srcIndex++]; + opCode = cbuf[srcIndex++]; + length = ((opCode >> 3) & 0x10) + length; + sourceOffset = ((opCode & 0x78) << 5) + 1 + sourceOffset; + break; + case 1: + length = (opCode & 0xf) + 3; + sourceOffset = cbuf[srcIndex++]; + opCode = cbuf[srcIndex++]; + sourceOffset = ((opCode & 0xf8) << 5) + 1 + sourceOffset; + break; + case 2: + sourceOffset = cbuf[srcIndex++]; + sourceOffset = ((cbuf[srcIndex++] << 8) & 0xff00) | sourceOffset; + length = opCode & 7; + if ((opCode & 8) == 0) { + opCode = cbuf[srcIndex++]; + length = (opCode & 0xf8) + length; + } else { + sourceOffset++; + length = (cbuf[srcIndex++] << 3) + length; + opCode = cbuf[srcIndex++]; + length = (((opCode & 0xf8) << 8) + length) + 0x100; + } + break; + default: + length = opCode >> 4; + sourceOffset = opCode & 15; + opCode = cbuf[srcIndex++]; + sourceOffset = (((opCode & 0xf8) << 1) + sourceOffset) + 1; + break; + } + *oc = opCode; + *si = srcIndex; + *so = sourceOffset; + *l = length; +} + + +void dwgCompressor::copyCompBytes21(duint8 *cbuf, duint8 *dbuf, duint32 l, duint32 si, duint32 di){ + duint32 length =l; + duint32 dix = di; + duint32 six = si; + + while (length > 31){ + //in doc: 16-31, 0-15 + for (duint32 i = six+24; i. ** +******************************************************************************/ + +#ifndef DWGUTIL_H +#define DWGUTIL_H + +#include "../drw_base.h" + +namespace DRW { +std::string toHexStr(int n); +} + +class dwgRSCodec { +public: + dwgRSCodec(){} + ~dwgRSCodec(){} + static void decode239I(duint8 *in, duint8 *out, duint32 blk); + static void decode251I(duint8 *in, duint8 *out, duint32 blk); +}; + +class dwgCompressor { +public: + dwgCompressor(){} + ~dwgCompressor(){} + + void decompress18(duint8 *cbuf, duint8 *dbuf, duint32 csize, duint32 dsize); + static void decrypt18Hdr(duint8 *buf, duint32 size, duint32 offset); +// static void decrypt18Data(duint8 *buf, duint32 size, duint32 offset); + static void decompress21(duint8 *cbuf, duint8 *dbuf, duint32 csize, duint32 dsize); + +private: + duint32 litLength18(); + static duint32 litLength21(duint8 *cbuf, duint8 oc, duint32 *si); + static void copyCompBytes21(duint8 *cbuf, duint8 *dbuf, duint32 l, duint32 si, duint32 di); + static void readInstructions21(duint8 *cbuf, duint32 *si, duint8 *oc, duint32 *so, duint32 *l); + + duint32 longCompressionOffset(); + duint32 long20CompressionOffset(); + duint32 twoByteOffset(duint32 *ll); + + duint8 *bufC; + duint8 *bufD; + duint32 sizeC; + duint32 sizeD; + duint32 pos; + duint32 rpos; + +}; + +class secEnum { +public: + enum DWGSection { + UNKNOWNS, /*!< UNKNOWN section. */ + FILEHEADER, /*!< File Header (in R3-R15*/ + HEADER, /*!< AcDb:Header */ + CLASSES, /*!< AcDb:Classes */ + SUMARYINFO, /*!< AcDb:SummaryInfo */ + PREVIEW, /*!< AcDb:Preview */ + VBAPROY, /*!< AcDb:VBAProject */ + APPINFO, /*!< AcDb:AppInfo */ + FILEDEP, /*!< AcDb:FileDepList */ + REVHISTORY, /*!< AcDb:RevHistory */ + SECURITY, /*!< AcDb:Security */ + OBJECTS, /*!< AcDb:AcDbObjects */ + OBJFREESPACE, /*!< AcDb:ObjFreeSpace */ + TEMPLATE, /*!< AcDb:Template */ + HANDLES, /*!< AcDb:Handles */ + PROTOTYPE, /*!< AcDb:AcDsPrototype_1b */ + AUXHEADER, /*!< AcDb:AuxHeader, in (R13-R15) second file header */ + SIGNATURE, /*!< AcDb:Signature */ + APPINFOHISTORY, /*!< AcDb:AppInfoHistory (in ac1021 may be a renamed section?*/ + EXTEDATA, /*!< Extended Entity Data */ + PROXYGRAPHICS /*!< PROXY ENTITY GRAPHICS */ + }; + + secEnum(){} + ~secEnum(){} + + static DWGSection getEnum(std::string nameSec); +}; + +#endif // DWGUTIL_H diff --git a/extlib/libdxfrw/intern/dxfreader.cpp b/extlib/libdxfrw/intern/dxfreader.cpp new file mode 100644 index 0000000..84f8641 --- /dev/null +++ b/extlib/libdxfrw/intern/dxfreader.cpp @@ -0,0 +1,263 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include +#include +#include +#include +#include "dxfreader.h" +#include "drw_textcodec.h" +#include "drw_dbg.h" + +bool dxfReader::readRec(int *codeData) { +// std::string text; + int code; + + if (!readCode(&code)) + return false; + *codeData = code; + + if (code < 10) + readString(); + else if (code < 60) + readDouble(); + else if (code < 80) + readInt16(); + else if (code > 89 && code < 100) //TODO this is an int 32b + readInt32(); + else if (code == 100 || code == 102 || code == 105) + readString(); + else if (code > 109 && code < 150) //skip not used at the v2012 + readDouble(); + else if (code > 159 && code < 170) //skip not used at the v2012 + readInt64(); + else if (code < 180) + readInt16(); + else if (code > 209 && code < 240) //skip not used at the v2012 + readDouble(); + else if (code > 269 && code < 290) //skip not used at the v2012 + readInt16(); + else if (code < 300) //TODO this is a boolean indicator, int in Binary? + readBool(); + else if (code < 370) + readString(); + else if (code < 390) + readInt16(); + else if (code < 400) + readString(); + else if (code < 410) + readInt16(); + else if (code < 420) + readString(); + else if (code < 430) //TODO this is an int 32b + readInt32(); + else if (code < 440) + readString(); + else if (code < 450) //TODO this is an int 32b + readInt32(); + else if (code < 460) //TODO this is long?? + readInt32(); + else if (code < 470) //TODO this is a floating point double precision?? + readDouble(); + else if (code < 481) + readString(); + else if (code > 998 && code < 1009) //skip not used at the v2012 + readString(); + else if (code < 1060) //TODO this is a floating point double precision?? + readDouble(); + else if (code < 1071) + readInt16(); + else if (code == 1071) //TODO this is an int 32b + readInt32(); + else if (skip) + //skip safely this dxf entry ( ok for ascii dxf) + readString(); + else + //break in binary files because the conduct is unpredictable + return false; + + return (filestr->good()); +} +int dxfReader::getHandleString(){ + int res; +#if defined(__APPLE__) + int Succeeded = sscanf ( strData.c_str(), "%x", &res ); + if ( !Succeeded || Succeeded == EOF ) + res = 0; +#else + std::istringstream Convert(strData); + if ( !(Convert >> std::hex >>res) ) + res = 0; +#endif + return res; +} + +bool dxfReaderBinary::readCode(int *code) { + unsigned short *int16p; + char buffer[2]; + filestr->read(buffer,2); + int16p = (unsigned short *) buffer; +//exist a 32bits int (code 90) with 2 bytes??? + if ((*code == 90) && (*int16p>2000)){ + DRW_DBG(*code); DRW_DBG(" de 16bits\n"); + filestr->seekg(-4, std::ios_base::cur); + filestr->read(buffer,2); + int16p = (unsigned short *) buffer; + } + *code = *int16p; + DRW_DBG(*code); DRW_DBG("\n"); + + return (filestr->good()); +} + +bool dxfReaderBinary::readString() { + type = STRING; + std::getline(*filestr, strData, '\0'); + DRW_DBG(strData); DRW_DBG("\n"); + return (filestr->good()); +} + +bool dxfReaderBinary::readString(std::string *text) { + type = STRING; + std::getline(*filestr, *text, '\0'); + DRW_DBG(*text); DRW_DBG("\n"); + return (filestr->good()); +} + +bool dxfReaderBinary::readInt16() { + type = INT32; + char buffer[2]; + filestr->read(buffer,2); + intData = (int)((buffer[1] << 8) | buffer[0]); + DRW_DBG(intData); DRW_DBG("\n"); + return (filestr->good()); +} + +bool dxfReaderBinary::readInt32() { + type = INT32; + unsigned int *int32p; + char buffer[4]; + filestr->read(buffer,4); + int32p = (unsigned int *) buffer; + intData = *int32p; + DRW_DBG(intData); DRW_DBG("\n"); + return (filestr->good()); +} + +bool dxfReaderBinary::readInt64() { + type = INT64; + unsigned long long int *int64p; //64 bits integer pointer + char buffer[8]; + filestr->read(buffer,8); + int64p = (unsigned long long int *) buffer; + int64 = *int64p; + DRW_DBG(int64); DRW_DBG(" int64\n"); + return (filestr->good()); +} + +bool dxfReaderBinary::readDouble() { + type = DOUBLE; + double *result; + char buffer[8]; + filestr->read(buffer,8); + result = (double *) buffer; + doubleData = *result; + DRW_DBG(doubleData); DRW_DBG("\n"); + return (filestr->good()); +} + +//saved as int or add a bool member?? +bool dxfReaderBinary::readBool() { + char buffer[1]; + filestr->read(buffer,1); + intData = (int)(buffer[0]); + DRW_DBG(intData); DRW_DBG("\n"); + return (filestr->good()); +} + +bool dxfReaderAscii::readCode(int *code) { + std::string text; + std::getline(*filestr, text); + *code = atoi(text.c_str()); + DRW_DBG(*code); DRW_DBG("\n"); + return (filestr->good()); +} +bool dxfReaderAscii::readString(std::string *text) { + type = STRING; + std::getline(*filestr, *text); + if (!text->empty() && text->at(text->size()-1) == '\r') + text->erase(text->size()-1); + return (filestr->good()); +} + +bool dxfReaderAscii::readString() { + type = STRING; + std::getline(*filestr, strData); + if (!strData.empty() && strData.at(strData.size()-1) == '\r') + strData.erase(strData.size()-1); + DRW_DBG(strData); DRW_DBG("\n"); + return (filestr->good()); +} + +bool dxfReaderAscii::readInt16() { + type = INT32; + std::string text; + if (readString(&text)){ + intData = atoi(text.c_str()); + DRW_DBG(intData); DRW_DBG("\n"); + return true; + } else + return false; +} + +bool dxfReaderAscii::readInt32() { + type = INT32; + return readInt16(); +} + +bool dxfReaderAscii::readInt64() { + type = INT64; + return readInt16(); +} + +bool dxfReaderAscii::readDouble() { + type = DOUBLE; + std::string text; + if (readString(&text)){ +#if defined(__APPLE__) + int succeeded=sscanf( & (text[0]), "%lg", &doubleData); + if(succeeded != 1) { + DRW_DBG("dxfReaderAscii::readDouble(): reading double error: "); + DRW_DBG(text); + DRW_DBG('\n'); + } +#else + std::istringstream sd(text); + sd >> doubleData; + DRW_DBG(doubleData); DRW_DBG('\n'); +#endif + return true; + } else + return false; +} + +//saved as int or add a bool member?? +bool dxfReaderAscii::readBool() { + type = BOOL; + std::string text; + if (readString(&text)){ + intData = atoi(text.c_str()); + DRW_DBG(intData); DRW_DBG("\n"); + return true; + } else + return false; +} diff --git a/extlib/libdxfrw/intern/dxfreader.h b/extlib/libdxfrw/intern/dxfreader.h new file mode 100644 index 0000000..71329be --- /dev/null +++ b/extlib/libdxfrw/intern/dxfreader.h @@ -0,0 +1,99 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DXFREADER_H +#define DXFREADER_H + +#include "drw_textcodec.h" + +class dxfReader { +public: + enum TYPE { + STRING, + INT32, + INT64, + DOUBLE, + BOOL, + INVALID + }; + enum TYPE type; +public: + dxfReader(std::istream *stream){ + filestr = stream; + type = INVALID; + } + virtual ~dxfReader(){} + bool readRec(int *code); + + std::string getString() {return strData;} + int getHandleString();//Convert hex string to int + std::string toUtf8String(std::string t) {return decoder.toUtf8(t);} + std::string getUtf8String() {return decoder.toUtf8(strData);} + double getDouble() {return doubleData;} + int getInt32() {return intData;} + unsigned long long int getInt64() {return int64;} + bool getBool() { return (intData==0) ? false : true;} + int getVersion(){return decoder.getVersion();} + void setVersion(std::string *v, bool dxfFormat){decoder.setVersion(v, dxfFormat);} + void setCodePage(std::string *c){decoder.setCodePage(c, true);} + std::string getCodePage(){ return decoder.getCodePage();} + +protected: + virtual bool readCode(int *code) = 0; //return true if successful (not EOF) + virtual bool readString(std::string *text) = 0; + virtual bool readString() = 0; + virtual bool readInt16() = 0; + virtual bool readInt32() = 0; + virtual bool readInt64() = 0; + virtual bool readDouble() = 0; + virtual bool readBool() = 0; + +protected: + std::istream *filestr; + std::string strData; + double doubleData; + signed int intData; //32 bits integer + unsigned long long int int64; //64 bits integer + bool skip; //set to true for ascii dxf, false for binary +private: + DRW_TextCodec decoder; +}; + +class dxfReaderBinary : public dxfReader { +public: + dxfReaderBinary(std::istream *stream):dxfReader(stream){skip = false; } + virtual ~dxfReaderBinary() {} + virtual bool readCode(int *code); + virtual bool readString(std::string *text); + virtual bool readString(); + virtual bool readInt16(); + virtual bool readInt32(); + virtual bool readInt64(); + virtual bool readDouble(); + virtual bool readBool(); +}; + +class dxfReaderAscii : public dxfReader { +public: + dxfReaderAscii(std::istream *stream):dxfReader(stream){skip = true; } + virtual ~dxfReaderAscii(){} + virtual bool readCode(int *code); + virtual bool readString(std::string *text); + virtual bool readString(); + virtual bool readInt16(); + virtual bool readDouble(); + virtual bool readInt32(); + virtual bool readInt64(); + virtual bool readBool(); +}; + +#endif // DXFREADER_H diff --git a/extlib/libdxfrw/intern/dxfwriter.cpp b/extlib/libdxfrw/intern/dxfwriter.cpp new file mode 100644 index 0000000..2276e7c --- /dev/null +++ b/extlib/libdxfrw/intern/dxfwriter.cpp @@ -0,0 +1,269 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#include +#include +#include +#include +#include "dxfwriter.h" + +//RLZ TODO change std::endl to x0D x0A (13 10) +/*bool dxfWriter::readRec(int *codeData, bool skip) { +// std::string text; + int code; + +#ifdef DRW_DBG + count = count+2; //DBG +#endif + + if (!readCode(&code)) + return false; + *codeData = code; + + if (code < 10) + readString(); + else if (code < 60) + readDouble(); + else if (code < 80) + readInt(); + else if (code > 89 && code < 100) //TODO this is an int 32b + readInt32(); + else if (code == 100 || code == 102 || code == 105) + readString(); + else if (code > 109 && code < 150) //skip not used at the v2012 + readDouble(); + else if (code > 159 && code < 170) //skip not used at the v2012 + readInt64(); + else if (code < 180) + readInt(); + else if (code > 209 && code < 240) //skip not used at the v2012 + readDouble(); + else if (code > 269 && code < 290) //skip not used at the v2012 + readInt(); + else if (code < 300) //TODO this is a boolean indicator, int in Binary? + readBool(); + else if (code < 370) + readString(); + else if (code < 390) + readInt(); + else if (code < 400) + readString(); + else if (code < 410) + readInt(); + else if (code < 420) + readString(); + else if (code < 430) //TODO this is an int 32b + readInt32(); + else if (code < 440) + readString(); + else if (code < 450) //TODO this is an int 32b + readInt32(); + else if (code < 460) //TODO this is long?? + readInt(); + else if (code < 470) //TODO this is a floating point double precision?? + readDouble(); + else if (code < 481) + readString(); + else if (code > 998 && code < 1009) //skip not used at the v2012 + readString(); + else if (code < 1060) //TODO this is a floating point double precision?? + readDouble(); + else if (code < 1071) + readInt(); + else if (code == 1071) //TODO this is an int 32b + readInt32(); + else if (skip) + //skip safely this dxf entry ( ok for ascii dxf) + readString(); + else + //break in binary files because the conduct is unpredictable + return false; + + return (filestr->good()); +}*/ + +bool dxfWriter::writeUtf8String(int code, std::string text) { + std::string t = encoder.fromUtf8(text); + return writeString(code, t); +} + +bool dxfWriter::writeUtf8Caps(int code, std::string text) { + std::string strname = text; + std::transform(strname.begin(), strname.end(), strname.begin(),::toupper); + std::string t = encoder.fromUtf8(strname); + return writeString(code, t); +} + +bool dxfWriterBinary::writeString(int code, std::string text) { + char bufcode[2]; + bufcode[0] =code & 0xFF; + bufcode[1] =code >> 8; + filestr->write(bufcode, 2); + *filestr << text << '\0'; + return (filestr->good()); +} + +/*bool dxfWriterBinary::readCode(int *code) { + unsigned short *int16p; + char buffer[2]; + filestr->read(buffer,2); + int16p = (unsigned short *) buffer; +//exist a 32bits int (code 90) with 2 bytes??? + if ((*code == 90) && (*int16p>2000)){ + DBG(*code); DBG(" de 16bits\n"); + filestr->seekg(-4, std::ios_base::cur); + filestr->read(buffer,2); + int16p = (unsigned short *) buffer; + } + *code = *int16p; + DBG(*code); DBG("\n"); + + return (filestr->good()); +}*/ + +/*bool dxfWriterBinary::readString() { + std::getline(*filestr, strData, '\0'); + DBG(strData); DBG("\n"); + return (filestr->good()); +}*/ + +/*bool dxfWriterBinary::readString(std::string *text) { + std::getline(*filestr, *text, '\0'); + DBG(*text); DBG("\n"); + return (filestr->good()); +}*/ + +bool dxfWriterBinary::writeInt16(int code, int data) { + char bufcode[2]; + char buffer[2]; + bufcode[0] =code & 0xFF; + bufcode[1] =code >> 8; + buffer[0] =data & 0xFF; + buffer[1] =data >> 8; + filestr->write(bufcode, 2); + filestr->write(buffer, 2); + return (filestr->good()); +} + +bool dxfWriterBinary::writeInt32(int code, int data) { + char buffer[4]; + buffer[0] =code & 0xFF; + buffer[1] =code >> 8; + filestr->write(buffer, 2); + + buffer[0] =data & 0xFF; + buffer[1] =data >> 8; + buffer[2] =data >> 16; + buffer[3] =data >> 24; + filestr->write(buffer, 4); + return (filestr->good()); +} + +bool dxfWriterBinary::writeInt64(int code, unsigned long long int data) { + char buffer[8]; + buffer[0] =code & 0xFF; + buffer[1] =code >> 8; + filestr->write(buffer, 2); + + buffer[0] =data & 0xFF; + buffer[1] =data >> 8; + buffer[2] =data >> 16; + buffer[3] =data >> 24; + buffer[4] =data >> 32; + buffer[5] =data >> 40; + buffer[6] =data >> 48; + buffer[7] =data >> 56; + filestr->write(buffer, 8); + return (filestr->good()); +} + +bool dxfWriterBinary::writeDouble(int code, double data) { + char bufcode[2]; + char buffer[8]; + bufcode[0] =code & 0xFF; + bufcode[1] =code >> 8; + filestr->write(bufcode, 2); + + unsigned char *val; + val = (unsigned char *) &data; + for (int i=0; i<8; i++) { + buffer[i] =val[i]; + } + filestr->write(buffer, 8); + return (filestr->good()); +} + +//saved as int or add a bool member?? +bool dxfWriterBinary::writeBool(int code, bool data) { + char buffer[1]; + char bufcode[2]; + bufcode[0] =code & 0xFF; + bufcode[1] =code >> 8; + filestr->write(bufcode, 2); + buffer[0] = data; + filestr->write(buffer, 1); + return (filestr->good()); +} + +dxfWriterAscii::dxfWriterAscii(std::ostream *stream):dxfWriter(stream){ + filestr->precision(16); +} + +bool dxfWriterAscii::writeString(int code, std::string text) { +// *filestr << code << std::endl << text << std::endl ; + filestr->width(3); + *filestr << std::right << code << std::endl; + filestr->width(0); + *filestr << std::left << text << std::endl; + /* std::getline(*filestr, strData, '\0'); + DBG(strData); DBG("\n");*/ + return (filestr->good()); +} + +bool dxfWriterAscii::writeInt16(int code, int data) { +// *filestr << std::right << code << std::endl << data << std::endl; + filestr->width(3); + *filestr << std::right << code << std::endl; + filestr->width(5); + *filestr << data << std::endl; + return (filestr->good()); +} + +bool dxfWriterAscii::writeInt32(int code, int data) { + return writeInt16(code, data); +} + +bool dxfWriterAscii::writeInt64(int code, unsigned long long int data) { +// *filestr << code << std::endl << data << std::endl; + filestr->width(3); + *filestr << std::right << code << std::endl; + filestr->width(5); + *filestr << data << std::endl; + return (filestr->good()); +} + +bool dxfWriterAscii::writeDouble(int code, double data) { +// std::streamsize prec = filestr->precision(); +// filestr->precision(12); +// *filestr << code << std::endl << data << std::endl; + filestr->width(3); + *filestr << std::right << code << std::endl; + *filestr << data << std::endl; +// filestr->precision(prec); + return (filestr->good()); +} + +//saved as int or add a bool member?? +bool dxfWriterAscii::writeBool(int code, bool data) { + *filestr << code << std::endl << data << std::endl; + return (filestr->good()); +} diff --git a/extlib/libdxfrw/intern/dxfwriter.h b/extlib/libdxfrw/intern/dxfwriter.h new file mode 100644 index 0000000..adabe02 --- /dev/null +++ b/extlib/libdxfrw/intern/dxfwriter.h @@ -0,0 +1,64 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef DXFWRITER_H +#define DXFWRITER_H + +#include "drw_textcodec.h" + +class dxfWriter { +public: + dxfWriter(std::ostream *stream){filestr = stream; /*count =0;*/} + virtual ~dxfWriter(){} + virtual bool writeString(int code, std::string text) = 0; + bool writeUtf8String(int code, std::string text); + bool writeUtf8Caps(int code, std::string text); + std::string fromUtf8String(std::string t) {return encoder.fromUtf8(t);} + virtual bool writeInt16(int code, int data) = 0; + virtual bool writeInt32(int code, int data) = 0; + virtual bool writeInt64(int code, unsigned long long int data) = 0; + virtual bool writeDouble(int code, double data) = 0; + virtual bool writeBool(int code, bool data) = 0; + void setVersion(std::string *v, bool dxfFormat){encoder.setVersion(v, dxfFormat);} + void setCodePage(std::string *c){encoder.setCodePage(c, true);} + std::string getCodePage(){return encoder.getCodePage();} +protected: + std::ostream *filestr; +private: + DRW_TextCodec encoder; +}; + +class dxfWriterBinary : public dxfWriter { +public: + dxfWriterBinary(std::ostream *stream):dxfWriter(stream){} + virtual ~dxfWriterBinary() {} + virtual bool writeString(int code, std::string text); + virtual bool writeInt16(int code, int data); + virtual bool writeInt32(int code, int data); + virtual bool writeInt64(int code, unsigned long long int data); + virtual bool writeDouble(int code, double data); + virtual bool writeBool(int code, bool data); +}; + +class dxfWriterAscii : public dxfWriter { +public: + dxfWriterAscii(std::ostream *stream); + virtual ~dxfWriterAscii(){} + virtual bool writeString(int code, std::string text); + virtual bool writeInt16(int code, int data); + virtual bool writeInt32(int code, int data); + virtual bool writeInt64(int code, unsigned long long int data); + virtual bool writeDouble(int code, double data); + virtual bool writeBool(int code, bool data); +}; + +#endif // DXFWRITER_H diff --git a/extlib/libdxfrw/intern/rscodec.cpp b/extlib/libdxfrw/intern/rscodec.cpp new file mode 100644 index 0000000..78926f3 --- /dev/null +++ b/extlib/libdxfrw/intern/rscodec.cpp @@ -0,0 +1,401 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2014 J.F. Soriano (Rallaz), rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +/** + * Reed-Solomon codec + * Reed Solomon code lifted from encoder/decoder for Reed-Solomon written by Simon Rockliff + * + * Original code: + * This program may be freely modified and/or given to whoever wants it. + * A condition of such distribution is that the author's contribution be + * acknowledged by his name being left in the comments heading the program, + * however no responsibility is accepted for any financial or other loss which + * may result from some unforseen errors or malfunctioning of the program + * during use. + * Simon Rockliff, 26th June 1991 + */ + + +#include "rscodec.h" +#include // std::nothrow +#include + +RScodec::RScodec(unsigned int pp, int mm, int tt) { + this->mm = mm; + this->tt = tt; + nn = (1<polynomial form alpha_to[] contains j=alpha**i; + polynomial form -> index form index_of[j=alpha**i] = i + alpha=2 is the primitive element of GF(2^mm) +*/ +void RScodec::RSgenerate_gf(unsigned int pp) { + int i, mask ; + int pb; + + mask = 1 ; + alpha_to[mm] = 0 ; + for (i=0; i>(mm-1-i)) & 1; + if (pb!=0) { + alpha_to[mm] ^= mask; + } + mask <<= 1 ; + } + index_of[alpha_to[mm]] = mm ; + mask >>= 1 ; + for (i=mm+1; i= mask) { + alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i-1]^mask)<<1) ; + } else alpha_to[i] = alpha_to[i-1]<<1 ; + index_of[alpha_to[i]] = i ; + } + index_of[0] = -1 ; +} + + +/* Obtain the generator polynomial of the tt-error correcting, length + nn=(2^mm -1) Reed Solomon code from the product of (X+alpha**i), i=1..2*tt +*/ +void RScodec::RSgen_poly() { + int i,j ; + int tmp; + int bb = nn-kk;; //nn-kk length of parity data + + gg[0] = 2 ; /* primitive element alpha = 2 for GF(2**mm) */ + gg[1] = 1 ; /* g(x) = (X+alpha) initially */ + for (i=2; i<=bb; i++) { + gg[i] = 1 ; + for (j=i-1; j>0; j--) + if (gg[j] != 0) { + if (gg[j]<0) { isOk=false; return; } + tmp = (index_of[gg[j]]+i)%nn; + if (tmp<0) { isOk=false; return; } + gg[j] = gg[j-1]^ alpha_to[tmp] ; + } else { + gg[j] = gg[j-1] ; + } + gg[0] = alpha_to[(index_of[gg[0]]+i)%nn] ; /* gg[0] can never be zero */ + } + /* convert gg[] to index form for quicker encoding */ + for (i=0; i<=bb; i++) gg[i] = index_of[gg[i]] ; +} + +int RScodec::calcDecode(unsigned char* data, int* recd, int** elp, int* d, int* l, int* u_lu, int* s, int* root, int* loc, int* z, int* err, int* reg, int bb) +{ + if (!isOk) return -1; + int count = 0; + int syn_error = 0; + int i, j, u, q; + + // for (int i=0; i error */ + s[i] = index_of[s[i]]; + } + + if (!syn_error) { /* if no errors, ends */ + /* no non-zero syndromes => no errors: output is received codeword */ + return 0; + } + + /* errors are present, try and correct */ + /* compute the error location polynomial via the Berlekamp iterative algorithm, + following the terminology of Lin and Costello : d[u] is the 'mu'th + discrepancy, where u='mu'+1 and 'mu' (the Greek letter!) is the step number + ranging from -1 to 2*tt (see L&C), l[u] is the + degree of the elp at that step, and u_l[u] is the difference between the + step number and the degree of the elp. + */ + /* initialise table entries */ + d[0] = 0; /* index form */ + d[1] = s[1]; /* index form */ + elp[0][0] = 0; /* index form */ + elp[1][0] = 1; /* polynomial form */ + for (i = 1; i0)) q--; + /* have found first non-zero d[q] */ + if (q>0) { + j = q; + do { + j--; + if ((d[j] != -1) && (u_lu[q]0); + } + + /* have now found q such that d[u]!=0 and u_lu[q] is maximum */ + /* store degree of new elp polynomial */ + if (l[u]>l[q] + u - q) { + l[u + 1] = l[u]; + } + else { + l[u + 1] = l[q] + u - q; + } + + /* form new elp(x) */ + for (i = 0; itt) { /* elp has degree has degree >tt hence cannot solve */ + return -1; /* just output is received codeword as is */ + } + + /* can correct error */ + /* put elp into index form */ + for (i = 0; i <= l[u]; i++) elp[u][i] = index_of[elp[u][i]]; + + /* find roots of the error location polynomial */ + for (i = 1; i <= l[u]; i++) { + reg[i] = elp[u][i]; + } + count = 0; + for (i = 1; i <= nn; i++) { + q = 1; + for (j = 1; j <= l[u]; j++) { + if (reg[j] != -1) { + reg[j] = (reg[j] + j) % nn; + q ^= alpha_to[reg[j]]; + } + } + if (!q) { /* store root and error location number indices */ + root[count] = i; + loc[count] = nn - i; + count++; + } + } + + if (count != l[u]) { /* no. roots != degree of elp => >tt errors and cannot solve */ + return -1; /* just output is received codeword as is */ + } + + /* no. roots = degree of elp hence <= tt errors */ + /* form polynomial z(x) */ + for (i = 1; i <= l[u]; i++) { /* Z[0] = 1 always - do not need */ + if ((s[i] != -1) && (elp[u][i] != -1)) { + z[i] = alpha_to[s[i]] ^ alpha_to[elp[u][i]]; + } + else if ((s[i] != -1) && (elp[u][i] == -1)) { + z[i] = alpha_to[s[i]]; + } + else if ((s[i] == -1) && (elp[u][i] != -1)) { + z[i] = alpha_to[elp[u][i]]; + } + else { + z[i] = 0; + } + for (j = 1; j=0; i--) { + feedback = index_of[idata[i]^bd[bb-1]] ; + if (feedback != -1) { + for (j=bb-1; j>0; j--) + if (gg[j] != -1) + bd[j] = bd[j-1]^alpha_to[(gg[j]+feedback)%nn] ; + else + bd[j] = bd[j-1] ; + bd[0] = alpha_to[(gg[0]+feedback)%nn] ; + } else { + for (j=bb-1; j>0; j--) + bd[j] = bd[j-1] ; + bd[0] = 0 ; + } + } + return true; +} + + +/* assume we have received bits grouped into mm-bit symbols in recd[i], + i=0..(nn-1), and recd[i] is index form (ie as powers of alpha). + We first compute the 2*tt syndromes by substituting alpha**i into rec(X) and + evaluating, storing the syndromes in s[i], i=1..2tt (leave s[0] zero) . + Then we use the Berlekamp iteration to find the error location polynomial + elp[i]. If the degree of the elp is >tt, we cannot correct all the errors + and hence just put out the information symbols uncorrected. If the degree of + elp is <=tt, we substitute alpha**i , i=1..n into the elp to get the roots, + hence the inverse roots, the error location numbers. If the number of errors + located does not equal the degree of the elp, we have more than tt errors + and cannot correct them. Otherwise, we then solve for the error value at + the error location and correct the error. The procedure is that found in + Lin and Costello. For the cases where the number of errors is known to be too + large to correct, the information symbols as received are output (the + advantage of systematic encoding is that hopefully some of the information + symbols will be okay and that if we are in luck, the errors are in the + parity part of the transmitted codeword). Of course, these insoluble cases + can be returned as error flags to the calling routine if desired. */ +/** return value: number of corrected errors or -1 if can't correct it */ +int RScodec::decode(unsigned char *data) { + if (!isOk) return -1; + int bb = nn-kk;; //nn-kk length of parity data + + int *recd = new (std::nothrow) int[nn]; + int **elp = new int*[bb + 2]; + for (int i = 0; i < bb + 2; ++i) + elp[i] = new int[bb]; + int *d = new int[bb + 2]; + int *l = new int[bb + 2]; + int *u_lu = new int[bb + 2]; + int *s = new int[bb + 1]; + int *root = new int[tt]; + int *loc = new int[tt]; + int *z = new int[tt+1]; + int *err = new int[nn]; + int *reg = new int[tt + 1]; + + int res = calcDecode(data, recd, elp ,d ,l, u_lu, s, root, loc ,z, err, reg, bb); + + delete[] recd; + for (int i = 0; i < bb + 2; ++i) + delete[] elp[i]; + delete[] elp; + delete[] d; + delete[] l; + delete[] u_lu; + delete[] s; + delete[] root; + delete[] loc; + delete[] z; + delete[] err; + delete[] reg; + + return res; +} diff --git a/extlib/libdxfrw/intern/rscodec.h b/extlib/libdxfrw/intern/rscodec.h new file mode 100644 index 0000000..10cb2a8 --- /dev/null +++ b/extlib/libdxfrw/intern/rscodec.h @@ -0,0 +1,69 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2014 J.F. Soriano (Rallaz), rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +/** + * Reed-Solomon codec + * Reed Solomon code lifted from encoder/decoder for Reed-Solomon written by Simon Rockliff + * + * Original code: + * This program may be freely modified and/or given to whoever wants it. + * A condition of such distribution is that the author's contribution be + * acknowledged by his name being left in the comments heading the program, + * however no responsibility is accepted for any financial or other loss which + * may result from some unforseen errors or malfunctioning of the program + * during use. + * Simon Rockliff, 26th June 1991 + */ + + + +#ifndef RSCODEC_H +#define RSCODEC_H +/** +mm: RS code over GF(2^4) +nn: nn= (2^mm) - 1 length of codeword +tt: number of errors that can be corrected +kk: kk = nn-2*tt +pp: irreducible polynomial coeffts, pp [mm] send as int +*/ +class RScodec { +public: + RScodec(unsigned int pp, int mm, int tt); + + ~RScodec(); +// bool encode(int *data, int *parity); +// int decode(int *recd); + bool encode(unsigned char *data, unsigned char *parity); + int decode(unsigned char *data); + bool isOkey(){return isOk;} + const unsigned int* indexOf() {return index_of;} + const int* alphaTo() {return alpha_to;} + +private: + void RSgenerate_gf(unsigned int pp); + void RSgen_poly(); + int calcDecode(unsigned char* data, int* recd, int** elp, int* d, int* l, int* u_lu, int* s, int* root, int* loc, int* z, int* err, int* reg, int bb); + + +private: + int mm; //RS code over GF(2^4) + int tt; //number of errors that can be corrected + int nn; //(2^mm) - 1 length of codeword + int kk; //nn-2*tt length of original data + + int *gg; + bool isOk; + unsigned int *index_of; + int *alpha_to; +}; + +#endif // RSCODEC_H diff --git a/extlib/libdxfrw/libdwgr.cpp b/extlib/libdxfrw/libdwgr.cpp new file mode 100644 index 0000000..adca43c --- /dev/null +++ b/extlib/libdxfrw/libdwgr.cpp @@ -0,0 +1,237 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + + +#include "libdwgr.h" +#include +#include +#include +#include "intern/drw_dbg.h" +#include "intern/drw_textcodec.h" +#include "intern/dwgreader.h" +#include "intern/dwgreader15.h" +#include "intern/dwgreader18.h" +#include "intern/dwgreader21.h" +#include "intern/dwgreader24.h" +#include "intern/dwgreader27.h" + +#define FIRSTHANDLE 48 + +/*enum sections { + secUnknown, + secHeader, + secTables, + secBlocks, + secEntities, + secObjects +};*/ + +dwgR::dwgR(){ + DRW_DBGSL(DRW_dbg::NONE); + reader = NULL; +// writer = NULL; + applyExt = false; + version = DRW::UNKNOWNV; + error = DRW::BAD_NONE; +} + +dwgR::~dwgR(){ + if (reader != NULL) + delete reader; + +} + +void dwgR::setDebug(DRW::DBG_LEVEL lvl){ + switch (lvl){ + case DRW::DEBUG: + DRW_DBGSL(DRW_dbg::DEBUG); + break; + default: + DRW_DBGSL(DRW_dbg::NONE); + } +} + +/*reads metadata and loads image preview*/ +bool dwgR::getPreview(std::istream &stream){ + bool isOk = false; + + isOk = open(&stream); + if (!isOk) + return false; + + isOk = reader->readMetaData(); + if (isOk) { + isOk = reader->readPreview(); + } else + error = DRW::BAD_READ_METADATA; + + if (reader != NULL) { + delete reader; + reader = NULL; + } + return isOk; +} + +bool dwgR::read(std::istream &stream, DRW_Interface *interface_, bool ext){ + applyExt = ext; + iface = interface_; + + bool isOk = false; + + isOk = open(&stream); + if (!isOk) + return false; + + isOk = reader->readMetaData(); + if (isOk) { + isOk = reader->readFileHeader(); + if (isOk) { + isOk = processDwg(); + } else + error = DRW::BAD_READ_FILE_HEADER; + } else + error = DRW::BAD_READ_METADATA; + + if (reader != NULL) { + delete reader; + reader = NULL; + } + + return isOk; +} + +bool dwgR::open(std::istream *stream){ + char line[7]; + stream->read (line, 6); + line[6]='\0'; + DRW_DBG("dwgR::read 2\n"); + DRW_DBG("dwgR::read line version: "); + DRW_DBG(line); + DRW_DBG("\n"); + + if (strcmp(line, "AC1006") == 0) + version = DRW::AC1006; + else if (strcmp(line, "AC1009") == 0) { + version = DRW::AC1009; +// reader = new dwgReader09(&filestr, this); + }else if (strcmp(line, "AC1012") == 0){ + version = DRW::AC1012; + reader = new dwgReader15(stream, this); + } else if (strcmp(line, "AC1014") == 0) { + version = DRW::AC1014; + reader = new dwgReader15(stream, this); + } else if (strcmp(line, "AC1015") == 0) { + version = DRW::AC1015; + reader = new dwgReader15(stream, this); + } else if (strcmp(line, "AC1018") == 0){ + version = DRW::AC1018; + reader = new dwgReader18(stream, this); + } else if (strcmp(line, "AC1021") == 0) { + version = DRW::AC1021; + reader = new dwgReader21(stream, this); + } else if (strcmp(line, "AC1024") == 0) { + version = DRW::AC1024; + reader = new dwgReader24(stream, this); + } else if (strcmp(line, "AC1027") == 0) { + version = DRW::AC1027; + reader = new dwgReader27(stream, this); + } else + version = DRW::UNKNOWNV; + + if (reader == NULL) { + error = DRW::BAD_VERSION; + return false; + } + return true; +} + +/********* Reader Process *********/ + +bool dwgR::processDwg() { + DRW_DBG("dwgR::processDwg() start processing dwg\n"); + bool ret; + bool ret2; + DRW_Header hdr; + ret = reader->readDwgHeader(hdr); + if (!ret) { + error = DRW::BAD_READ_HEADER; + } + + ret2 = reader->readDwgClasses(); + if (ret && !ret2) { + error = DRW::BAD_READ_CLASSES; + ret = ret2; + } + + ret2 = reader->readDwgHandles(); + if (ret && !ret2) { + error = DRW::BAD_READ_HANDLES; + ret = ret2; + } + + ret2 = reader->readDwgTables(hdr); + if (ret && !ret2) { + error = DRW::BAD_READ_TABLES; + ret = ret2; + } + + iface->addHeader(&hdr); + + for (std::map::iterator it=reader->ltypemap.begin(); it!=reader->ltypemap.end(); ++it) { + DRW_LType *lt = it->second; + iface->addLType(const_cast(*lt) ); + } + for (std::map::iterator it=reader->layermap.begin(); it!=reader->layermap.end(); ++it) { + DRW_Layer *ly = it->second; + iface->addLayer(const_cast(*ly)); + } + + for (std::map::iterator it=reader->stylemap.begin(); it!=reader->stylemap.end(); ++it) { + DRW_Textstyle *ly = it->second; + iface->addTextStyle(const_cast(*ly)); + } + + for (std::map::iterator it=reader->dimstylemap.begin(); it!=reader->dimstylemap.end(); ++it) { + DRW_Dimstyle *ly = it->second; + iface->addDimStyle(const_cast(*ly)); + } + + for (std::map::iterator it=reader->vportmap.begin(); it!=reader->vportmap.end(); ++it) { + DRW_Vport *ly = it->second; + iface->addVport(const_cast(*ly)); + } + + for (std::map::iterator it=reader->appIdmap.begin(); it!=reader->appIdmap.end(); ++it) { + DRW_AppId *ly = it->second; + iface->addAppId(const_cast(*ly)); + } + + ret2 = reader->readDwgBlocks(*iface); + if (ret && !ret2) { + error = DRW::BAD_READ_BLOCKS; + ret = ret2; + } + + ret2 = reader->readDwgEntities(*iface); + if (ret && !ret2) { + error = DRW::BAD_READ_ENTITIES; + ret = ret2; + } + + ret2 = reader->readDwgObjects(*iface); + if (ret && !ret2) { + error = DRW::BAD_READ_OBJECTS; + ret = ret2; + } + + return ret; +} diff --git a/extlib/libdxfrw/libdwgr.h b/extlib/libdxfrw/libdwgr.h new file mode 100644 index 0000000..0601004 --- /dev/null +++ b/extlib/libdxfrw/libdwgr.h @@ -0,0 +1,50 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef LIBDWGR_H +#define LIBDWGR_H + +#include +//#include +#include "drw_entities.h" +#include "drw_objects.h" +#include "drw_classes.h" +#include "drw_interface.h" + +class dwgReader; + +class dwgR { +public: + dwgR(); + ~dwgR(); + //read: return true if all ok + bool read(std::istream &stream, DRW_Interface *interface_, bool ext); + bool getPreview(std::istream &stream); + DRW::Version getVersion(){return version;} + DRW::error getError(){return error;} + void setDebug(DRW::DBG_LEVEL lvl); + +private: + bool open(std::istream *stream); + bool processDwg(); +private: + DRW::Version version; + DRW::error error; + std::string fileName; + bool applyExt; /*apply extrusion in entities to conv in 2D?*/ + std::string codePage; + DRW_Interface *iface; + dwgReader *reader; + +}; + +#endif // LIBDWGR_H diff --git a/extlib/libdxfrw/libdxfrw.cpp b/extlib/libdxfrw/libdxfrw.cpp new file mode 100644 index 0000000..ac547ee --- /dev/null +++ b/extlib/libdxfrw/libdxfrw.cpp @@ -0,0 +1,2773 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + + +#include "libdxfrw.h" +#include +#include +#include +#include +#include "intern/drw_textcodec.h" +#include "intern/dxfreader.h" +#include "intern/dxfwriter.h" +#include "intern/drw_dbg.h" + +#define FIRSTHANDLE 48 + +/*enum sections { + secUnknown, + secHeader, + secTables, + secBlocks, + secEntities, + secObjects +};*/ + +dxfRW::dxfRW(){ + DRW_DBGSL(DRW_dbg::NONE); + reader = NULL; + writer = NULL; + applyExt = false; + elParts = 128; //parts munber when convert ellipse to polyline +} +dxfRW::~dxfRW(){ + if (reader != NULL) + delete reader; + if (writer != NULL) + delete writer; + for (std::vector::iterator it=imageDef.begin(); it!=imageDef.end(); ++it) + delete *it; + + imageDef.clear(); +} + +void dxfRW::setDebug(DRW::DBG_LEVEL lvl){ + switch (lvl){ + case DRW::DEBUG: + DRW_DBGSL(DRW_dbg::DEBUG); + break; + default: + DRW_DBGSL(DRW_dbg::NONE); + } +} + +bool dxfRW::read(std::istream &stream, DRW_Interface *interface_, bool ext){ + applyExt = ext; + + if(interface_ == NULL) + return false; + + char line[22]; + char line2[22] = "AutoCAD Binary DXF\r\n"; + line2[20] = (char)26; + line2[21] = '\0'; + stream.read (line, 22); + iface = interface_; + DRW_DBG("dxfRW::read 2\n"); + if (strcmp(line, line2) == 0) { + binFile = true; + reader = new dxfReaderBinary(&stream); + DRW_DBG("dxfRW::read binary file\n"); + } else { + binFile = false; + stream.seekg(0, std::ios::beg); + reader = new dxfReaderAscii(&stream); + } + + bool isOk = processDxf(); + delete reader; + reader = NULL; + return isOk; +} + +bool dxfRW::write(std::ostream &stream, DRW_Interface *interface_, DRW::Version ver, bool bin){ + version = ver; + binFile = bin; + iface = interface_; + if (binFile) { + //write sentinel + stream << "AutoCAD Binary DXF\r\n" << (char)26 << '\0'; + writer = new dxfWriterBinary(&stream); + DRW_DBG("dxfRW::read binary file\n"); + } else { + writer = new dxfWriterAscii(&stream); + std::string comm = std::string("dxfrw ") + std::string(DRW_VERSION); + writer->writeString(999, comm); + } + DRW_Header header; + iface->writeHeader(header); + writer->writeString(0, "SECTION"); + entCount =FIRSTHANDLE; + header.write(writer, version); + writer->writeString(0, "ENDSEC"); + if (ver > DRW::AC1009) { + writer->writeString(0, "SECTION"); + writer->writeString(2, "CLASSES"); + writer->writeString(0, "ENDSEC"); + } + writer->writeString(0, "SECTION"); + writer->writeString(2, "TABLES"); + writeTables(); + writer->writeString(0, "ENDSEC"); + writer->writeString(0, "SECTION"); + writer->writeString(2, "BLOCKS"); + writeBlocks(); + writer->writeString(0, "ENDSEC"); + + writer->writeString(0, "SECTION"); + writer->writeString(2, "ENTITIES"); + iface->writeEntities(); + writer->writeString(0, "ENDSEC"); + + if (version > DRW::AC1009) { + writer->writeString(0, "SECTION"); + writer->writeString(2, "OBJECTS"); + writeObjects(); + writer->writeString(0, "ENDSEC"); + } + writer->writeString(0, "EOF"); + stream.flush(); + delete writer; + writer = NULL; + return true; +} + +bool dxfRW::writeEntity(DRW_Entity *ent) { + ent->handle = ++entCount; + writer->writeString(5, toHexStr(ent->handle)); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbEntity"); + } + if (ent->space == 1) + writer->writeInt16(67, 1); + if (version > DRW::AC1009) { + writer->writeUtf8String(8, ent->layer); + writer->writeUtf8String(6, ent->lineType); + } else { + writer->writeUtf8Caps(8, ent->layer); + writer->writeUtf8Caps(6, ent->lineType); + } + writer->writeInt16(62, ent->color); + if (version > DRW::AC1015 && ent->color24 >= 0) { + writer->writeInt32(420, ent->color24); + } + if (version > DRW::AC1014) { + writer->writeInt16(370, DRW_LW_Conv::lineWidth2dxfInt(ent->lWeight)); + } + return true; +} + +bool dxfRW::writeLineType(DRW_LType *ent){ + std::string strname = ent->name; + + transform(strname.begin(), strname.end(), strname.begin(),::toupper); +//do not write linetypes handled by library + if (strname == "BYLAYER" || strname == "BYBLOCK" || strname == "CONTINUOUS") { + return true; + } + writer->writeString(0, "LTYPE"); + if (version > DRW::AC1009) { + writer->writeString(5, toHexStr(++entCount)); + if (version > DRW::AC1012) { + writer->writeString(330, "5"); + } + writer->writeString(100, "AcDbSymbolTableRecord"); + writer->writeString(100, "AcDbLinetypeTableRecord"); + writer->writeUtf8String(2, ent->name); + } else + writer->writeUtf8Caps(2, ent->name); + writer->writeInt16(70, ent->flags); + writer->writeUtf8String(3, ent->desc); + ent->update(); + writer->writeInt16(72, 65); + writer->writeInt16(73, ent->size); + writer->writeDouble(40, ent->length); + + for (unsigned int i = 0; i< ent->path.size(); i++){ + writer->writeDouble(49, ent->path.at(i)); + if (version > DRW::AC1009) { + writer->writeInt16(74, 0); + } + } + return true; +} + +bool dxfRW::writeLayer(DRW_Layer *ent){ + writer->writeString(0, "LAYER"); + if (!wlayer0 && ent->name == "0") { + wlayer0 = true; + if (version > DRW::AC1009) { + writer->writeString(5, "10"); + } + } else { + if (version > DRW::AC1009) { + writer->writeString(5, toHexStr(++entCount)); + } + } + if (version > DRW::AC1012) { + writer->writeString(330, "2"); + } + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbSymbolTableRecord"); + writer->writeString(100, "AcDbLayerTableRecord"); + writer->writeUtf8String(2, ent->name); + } else { + writer->writeUtf8Caps(2, ent->name); + } + writer->writeInt16(70, ent->flags); + writer->writeInt16(62, ent->color); + if (version > DRW::AC1015 && ent->color24 >= 0) { + writer->writeInt32(420, ent->color24); + } + if (version > DRW::AC1009) { + writer->writeUtf8String(6, ent->lineType); + if (! ent->plotF) + writer->writeBool(290, ent->plotF); + writer->writeInt16(370, DRW_LW_Conv::lineWidth2dxfInt(ent->lWeight)); + writer->writeString(390, "F"); + } else + writer->writeUtf8Caps(6, ent->lineType); + if (!ent->extData.empty()){ + writeExtData(ent->extData); + } +// writer->writeString(347, "10012"); + return true; +} + +bool dxfRW::writeTextstyle(DRW_Textstyle *ent){ + writer->writeString(0, "STYLE"); + if (!dimstyleStd) { + //stringstream cause crash in OS/X, bug#3597944 + std::string name=ent->name; + transform(name.begin(), name.end(), name.begin(), toupper); + if (name == "STANDARD") + dimstyleStd = true; + } + if (version > DRW::AC1009) { + writer->writeString(5, toHexStr(++entCount)); + } + + if (version > DRW::AC1012) { + writer->writeString(330, "2"); + } + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbSymbolTableRecord"); + writer->writeString(100, "AcDbTextStyleTableRecord"); + writer->writeUtf8String(2, ent->name); + } else { + writer->writeUtf8Caps(2, ent->name); + } + writer->writeInt16(70, ent->flags); + writer->writeDouble(40, ent->height); + writer->writeDouble(41, ent->width); + writer->writeDouble(50, ent->oblique); + writer->writeInt16(71, ent->genFlag); + writer->writeDouble(42, ent->lastHeight); + if (version > DRW::AC1009) { + writer->writeUtf8String(3, ent->font); + writer->writeUtf8String(4, ent->bigFont); + if (ent->fontFamily != 0) + writer->writeInt32(1071, ent->fontFamily); + } else { + writer->writeUtf8Caps(3, ent->font); + writer->writeUtf8Caps(4, ent->bigFont); + } + return true; +} + +bool dxfRW::writeVport(DRW_Vport *ent){ + if (!dimstyleStd) { + ent->name = "*ACTIVE"; + dimstyleStd = true; + } + writer->writeString(0, "VPORT"); + if (version > DRW::AC1009) { + writer->writeString(5, toHexStr(++entCount)); + if (version > DRW::AC1012) + writer->writeString(330, "2"); + writer->writeString(100, "AcDbSymbolTableRecord"); + writer->writeString(100, "AcDbViewportTableRecord"); + writer->writeUtf8String(2, ent->name); + } else + writer->writeUtf8Caps(2, ent->name); + writer->writeInt16(70, ent->flags); + writer->writeDouble(10, ent->lowerLeft.x); + writer->writeDouble(20, ent->lowerLeft.y); + writer->writeDouble(11, ent->UpperRight.x); + writer->writeDouble(21, ent->UpperRight.y); + writer->writeDouble(12, ent->center.x); + writer->writeDouble(22, ent->center.y); + writer->writeDouble(13, ent->snapBase.x); + writer->writeDouble(23, ent->snapBase.y); + writer->writeDouble(14, ent->snapSpacing.x); + writer->writeDouble(24, ent->snapSpacing.y); + writer->writeDouble(15, ent->gridSpacing.x); + writer->writeDouble(25, ent->gridSpacing.y); + writer->writeDouble(16, ent->viewDir.x); + writer->writeDouble(26, ent->viewDir.y); + writer->writeDouble(36, ent->viewDir.z); + writer->writeDouble(17, ent->viewTarget.z); + writer->writeDouble(27, ent->viewTarget.z); + writer->writeDouble(37, ent->viewTarget.z); + writer->writeDouble(40, ent->height); + writer->writeDouble(41, ent->ratio); + writer->writeDouble(42, ent->lensHeight); + writer->writeDouble(43, ent->frontClip); + writer->writeDouble(44, ent->backClip); + writer->writeDouble(50, ent->snapAngle); + writer->writeDouble(51, ent->twistAngle); + writer->writeInt16(71, ent->viewMode); + writer->writeInt16(72, ent->circleZoom); + writer->writeInt16(73, ent->fastZoom); + writer->writeInt16(74, ent->ucsIcon); + writer->writeInt16(75, ent->snap); + writer->writeInt16(76, ent->grid); + writer->writeInt16(77, ent->snapStyle); + writer->writeInt16(78, ent->snapIsopair); + if (version > DRW::AC1014) { + writer->writeInt16(281, 0); + writer->writeInt16(65, 1); + writer->writeDouble(110, 0.0); + writer->writeDouble(120, 0.0); + writer->writeDouble(130, 0.0); + writer->writeDouble(111, 1.0); + writer->writeDouble(121, 0.0); + writer->writeDouble(131, 0.0); + writer->writeDouble(112, 0.0); + writer->writeDouble(122, 1.0); + writer->writeDouble(132, 0.0); + writer->writeInt16(79, 0); + writer->writeDouble(146, 0.0); + if (version > DRW::AC1018) { + writer->writeString(348, "10020"); + writer->writeInt16(60, ent->gridBehavior);//v2007 undocummented see DRW_Vport class + writer->writeInt16(61, 5); + writer->writeBool(292, 1); + writer->writeInt16(282, 1); + writer->writeDouble(141, 0.0); + writer->writeDouble(142, 0.0); + writer->writeInt16(63, 250); + writer->writeInt32(421, 3358443); + } + } + return true; +} + +bool dxfRW::writeDimstyle(DRW_Dimstyle *ent){ + writer->writeString(0, "DIMSTYLE"); + if (!dimstyleStd) { + std::string name = ent->name; + std::transform(name.begin(), name.end(), name.begin(),::toupper); + if (name == "STANDARD") + dimstyleStd = true; + } + if (version > DRW::AC1009) { + writer->writeString(105, toHexStr(++entCount)); + } + + if (version > DRW::AC1012) { + writer->writeString(330, "A"); + } + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbSymbolTableRecord"); + writer->writeString(100, "AcDbDimStyleTableRecord"); + writer->writeUtf8String(2, ent->name); + } else + writer->writeUtf8Caps(2, ent->name); + writer->writeInt16(70, ent->flags); + if ( version <= DRW::AC1009 || !(ent->dimpost.empty()) ) + writer->writeUtf8String(3, ent->dimpost); + if ( version <= DRW::AC1009 || !(ent->dimapost.empty()) ) + writer->writeUtf8String(4, ent->dimapost); + if ( version <= DRW::AC1009 || !(ent->dimblk.empty()) ) + writer->writeUtf8String(5, ent->dimblk); + if ( version <= DRW::AC1009 || !(ent->dimblk1.empty()) ) + writer->writeUtf8String(6, ent->dimblk1); + if ( version <= DRW::AC1009 || !(ent->dimblk2.empty()) ) + writer->writeUtf8String(7, ent->dimblk2); + writer->writeDouble(40, ent->dimscale); + writer->writeDouble(41, ent->dimasz); + writer->writeDouble(42, ent->dimexo); + writer->writeDouble(43, ent->dimdli); + writer->writeDouble(44, ent->dimexe); + writer->writeDouble(45, ent->dimrnd); + writer->writeDouble(46, ent->dimdle); + writer->writeDouble(47, ent->dimtp); + writer->writeDouble(48, ent->dimtm); + writer->writeDouble(140, ent->dimtxt); + writer->writeDouble(141, ent->dimcen); + writer->writeDouble(142, ent->dimtsz); + writer->writeDouble(143, ent->dimaltf); + writer->writeDouble(144, ent->dimlfac); + writer->writeDouble(145, ent->dimtvp); + writer->writeDouble(146, ent->dimtfac); + writer->writeDouble(147, ent->dimgap); + if (version > DRW::AC1014) { + writer->writeDouble(148, ent->dimaltrnd); + } + writer->writeInt16(71, ent->dimtol); + writer->writeInt16(72, ent->dimlim); + writer->writeInt16(73, ent->dimtih); + writer->writeInt16(74, ent->dimtoh); + writer->writeInt16(75, ent->dimse1); + writer->writeInt16(76, ent->dimse2); + writer->writeInt16(77, ent->dimtad); + writer->writeInt16(78, ent->dimzin); + if (version > DRW::AC1014) { + writer->writeInt16(79, ent->dimazin); + } + writer->writeInt16(170, ent->dimalt); + writer->writeInt16(171, ent->dimaltd); + writer->writeInt16(172, ent->dimtofl); + writer->writeInt16(173, ent->dimsah); + writer->writeInt16(174, ent->dimtix); + writer->writeInt16(175, ent->dimsoxd); + writer->writeInt16(176, ent->dimclrd); + writer->writeInt16(177, ent->dimclre); + writer->writeInt16(178, ent->dimclrt); + if (version > DRW::AC1014) { + writer->writeInt16(179, ent->dimadec); + } + if (version > DRW::AC1009) { + if (version < DRW::AC1015) + writer->writeInt16(270, ent->dimunit); + writer->writeInt16(271, ent->dimdec); + writer->writeInt16(272, ent->dimtdec); + writer->writeInt16(273, ent->dimaltu); + writer->writeInt16(274, ent->dimalttd); + writer->writeInt16(275, ent->dimaunit); + } + if (version > DRW::AC1014) { + writer->writeInt16(276, ent->dimfrac); + writer->writeInt16(277, ent->dimlunit); + writer->writeInt16(278, ent->dimdsep); + writer->writeInt16(279, ent->dimtmove); + } + if (version > DRW::AC1009) { + writer->writeInt16(280, ent->dimjust); + writer->writeInt16(281, ent->dimsd1); + writer->writeInt16(282, ent->dimsd2); + writer->writeInt16(283, ent->dimtolj); + writer->writeInt16(284, ent->dimtzin); + writer->writeInt16(285, ent->dimaltz); + writer->writeInt16(286, ent->dimaltttz); + if (version < DRW::AC1015) + writer->writeInt16(287, ent->dimfit); + writer->writeInt16(288, ent->dimupt); + } + if (version > DRW::AC1014) { + writer->writeInt16(289, ent->dimatfit); + } + if (version > DRW::AC1009 && !ent->dimtxsty.empty()) { + writer->writeUtf8String(340, ent->dimtxsty); + } + if (version > DRW::AC1014) { + writer->writeUtf8String(341, ent->dimldrblk); + writer->writeInt16(371, ent->dimlwd); + writer->writeInt16(372, ent->dimlwe); + } + return true; +} + +bool dxfRW::writeAppId(DRW_AppId *ent){ + std::string strname = ent->name; + transform(strname.begin(), strname.end(), strname.begin(),::toupper); +//do not write mandatory ACAD appId, handled by library + if (strname == "ACAD") + return true; + writer->writeString(0, "APPID"); + if (version > DRW::AC1009) { + writer->writeString(5, toHexStr(++entCount)); + if (version > DRW::AC1014) { + writer->writeString(330, "9"); + } + writer->writeString(100, "AcDbSymbolTableRecord"); + writer->writeString(100, "AcDbRegAppTableRecord"); + writer->writeUtf8String(2, ent->name); + } else { + writer->writeUtf8Caps(2, ent->name); + } + writer->writeInt16(70, ent->flags); + return true; +} + +bool dxfRW::writePoint(DRW_Point *ent) { + writer->writeString(0, "POINT"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbPoint"); + } + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + if (ent->basePoint.z != 0.0) { + writer->writeDouble(30, ent->basePoint.z); + } + return true; +} + +bool dxfRW::writeLine(DRW_Line *ent) { + writer->writeString(0, "LINE"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbLine"); + } + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + if (ent->basePoint.z != 0.0 || ent->secPoint.z != 0.0) { + writer->writeDouble(30, ent->basePoint.z); + writer->writeDouble(11, ent->secPoint.x); + writer->writeDouble(21, ent->secPoint.y); + writer->writeDouble(31, ent->secPoint.z); + } else { + writer->writeDouble(11, ent->secPoint.x); + writer->writeDouble(21, ent->secPoint.y); + } + return true; +} + +bool dxfRW::writeRay(DRW_Ray *ent) { + writer->writeString(0, "RAY"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbRay"); + } + DRW_Coord crd = ent->secPoint; + crd.unitize(); + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + if (ent->basePoint.z != 0.0 || ent->secPoint.z != 0.0) { + writer->writeDouble(30, ent->basePoint.z); + writer->writeDouble(11, crd.x); + writer->writeDouble(21, crd.y); + writer->writeDouble(31, crd.z); + } else { + writer->writeDouble(11, crd.x); + writer->writeDouble(21, crd.y); + } + return true; +} + +bool dxfRW::writeXline(DRW_Xline *ent) { + writer->writeString(0, "XLINE"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbXline"); + } + DRW_Coord crd = ent->secPoint; + crd.unitize(); + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + if (ent->basePoint.z != 0.0 || ent->secPoint.z != 0.0) { + writer->writeDouble(30, ent->basePoint.z); + writer->writeDouble(11, crd.x); + writer->writeDouble(21, crd.y); + writer->writeDouble(31, crd.z); + } else { + writer->writeDouble(11, crd.x); + writer->writeDouble(21, crd.y); + } + return true; +} + +bool dxfRW::writeCircle(DRW_Circle *ent) { + writer->writeString(0, "CIRCLE"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbCircle"); + } + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + if (ent->basePoint.z != 0.0) { + writer->writeDouble(30, ent->basePoint.z); + } + writer->writeDouble(40, ent->radious); + return true; +} + +bool dxfRW::writeArc(DRW_Arc *ent) { + writer->writeString(0, "ARC"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbCircle"); + } + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + if (ent->basePoint.z != 0.0) { + writer->writeDouble(30, ent->basePoint.z); + } + writer->writeDouble(40, ent->radious); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbArc"); + } + writer->writeDouble(50, ent->staangle*ARAD); + writer->writeDouble(51, ent->endangle*ARAD); + return true; +} + +bool dxfRW::writeEllipse(DRW_Ellipse *ent){ + //verify axis/ratio and params for full ellipse + ent->correctAxis(); + if (version > DRW::AC1009) { + writer->writeString(0, "ELLIPSE"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbEllipse"); + } + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + writer->writeDouble(30, ent->basePoint.z); + writer->writeDouble(11, ent->secPoint.x); + writer->writeDouble(21, ent->secPoint.y); + writer->writeDouble(31, ent->secPoint.z); + writer->writeDouble(40, ent->ratio); + writer->writeDouble(41, ent->staparam); + writer->writeDouble(42, ent->endparam); + } else { + DRW_Polyline pol; + //RLZ: copy properties + ent->toPolyline(&pol, elParts); + writePolyline(&pol); + } + return true; +} + +bool dxfRW::writeTrace(DRW_Trace *ent){ + writer->writeString(0, "TRACE"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbTrace"); + } + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + writer->writeDouble(30, ent->basePoint.z); + writer->writeDouble(11, ent->secPoint.x); + writer->writeDouble(21, ent->secPoint.y); + writer->writeDouble(31, ent->secPoint.z); + writer->writeDouble(12, ent->thirdPoint.x); + writer->writeDouble(22, ent->thirdPoint.y); + writer->writeDouble(32, ent->thirdPoint.z); + writer->writeDouble(13, ent->fourPoint.x); + writer->writeDouble(23, ent->fourPoint.y); + writer->writeDouble(33, ent->fourPoint.z); + return true; +} + +bool dxfRW::writeSolid(DRW_Solid *ent){ + writer->writeString(0, "SOLID"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbTrace"); + } + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + writer->writeDouble(30, ent->basePoint.z); + writer->writeDouble(11, ent->secPoint.x); + writer->writeDouble(21, ent->secPoint.y); + writer->writeDouble(31, ent->secPoint.z); + writer->writeDouble(12, ent->thirdPoint.x); + writer->writeDouble(22, ent->thirdPoint.y); + writer->writeDouble(32, ent->thirdPoint.z); + writer->writeDouble(13, ent->fourPoint.x); + writer->writeDouble(23, ent->fourPoint.y); + writer->writeDouble(33, ent->fourPoint.z); + return true; +} + +bool dxfRW::write3dface(DRW_3Dface *ent){ + writer->writeString(0, "3DFACE"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbFace"); + } + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + writer->writeDouble(30, ent->basePoint.z); + writer->writeDouble(11, ent->secPoint.x); + writer->writeDouble(21, ent->secPoint.y); + writer->writeDouble(31, ent->secPoint.z); + writer->writeDouble(12, ent->thirdPoint.x); + writer->writeDouble(22, ent->thirdPoint.y); + writer->writeDouble(32, ent->thirdPoint.z); + writer->writeDouble(13, ent->fourPoint.x); + writer->writeDouble(23, ent->fourPoint.y); + writer->writeDouble(33, ent->fourPoint.z); + writer->writeInt16(70, ent->invisibleflag); + return true; +} + +bool dxfRW::writeLWPolyline(DRW_LWPolyline *ent){ + if (version > DRW::AC1009) { + writer->writeString(0, "LWPOLYLINE"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbPolyline"); + } + ent->vertexnum = (int)ent->vertlist.size(); + writer->writeInt32(90, ent->vertexnum); + writer->writeInt16(70, ent->flags); + writer->writeDouble(43, ent->width); + if (ent->elevation != 0) + writer->writeDouble(38, ent->elevation); + if (ent->thickness != 0) + writer->writeDouble(39, ent->thickness); + for (int i = 0; i< ent->vertexnum; i++){ + DRW_Vertex2D *v = ent->vertlist.at(i); + writer->writeDouble(10, v->x); + writer->writeDouble(20, v->y); + if (v->stawidth != 0) + writer->writeDouble(40, v->stawidth); + if (v->endwidth != 0) + writer->writeDouble(41, v->endwidth); + if (v->bulge != 0) + writer->writeDouble(42, v->bulge); + } + } else { + //RLZ: TODO convert lwpolyline in polyline (not exist in acad 12) + } + return true; +} + +bool dxfRW::writePolyline(DRW_Polyline *ent) { + writer->writeString(0, "POLYLINE"); + writeEntity(ent); + bool is3d = false; + if (version > DRW::AC1009) { + if (ent->flags & 8 || ent->flags & 16) { + writer->writeString(100, "AcDb3dPolyline"); + is3d = true; + } else { + writer->writeString(100, "AcDb2dPolyline"); + } + } else + writer->writeInt16(66, 1); + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, ent->basePoint.z); + if (ent->thickness != 0) { + writer->writeDouble(39, ent->thickness); + } + writer->writeInt16(70, ent->flags); + if (ent->defstawidth != 0) { + writer->writeDouble(40, ent->defstawidth); + } + if (ent->defendwidth != 0) { + writer->writeDouble(41, ent->defendwidth); + } + if (ent->flags & 16 || ent->flags & 32) { + writer->writeInt16(71, ent->vertexcount); + writer->writeInt16(72, ent->facecount); + } + if (ent->smoothM != 0) { + writer->writeInt16(73, ent->smoothM); + } + if (ent->smoothN != 0) { + writer->writeInt16(74, ent->smoothN); + } + if (ent->curvetype != 0) { + writer->writeInt16(75, ent->curvetype); + } + DRW_Coord crd = ent->extPoint; + if (crd.x != 0 || crd.y != 0 || crd.z != 1) { + writer->writeDouble(210, crd.x); + writer->writeDouble(220, crd.y); + writer->writeDouble(230, crd.z); + } + + size_t vertexnum = ent->vertlist.size(); + for (size_t i = 0; i < vertexnum; i++) { + DRW_Vertex *v = ent->vertlist.at(i); + writer->writeString(0, "VERTEX"); + writeEntity(ent); + if (version > DRW::AC1009) + writer->writeString(100, "AcDbVertex"); + if(is3d) { + writer->writeString(100, "AcDb3dPolylineVertex"); + } else { + writer->writeString(100, "AcDb2dVertex"); + } + if ( (v->flags & 128) && !(v->flags & 64) ) { + writer->writeDouble(10, 0); + writer->writeDouble(20, 0); + writer->writeDouble(30, 0); + } else { + writer->writeDouble(10, v->basePoint.x); + writer->writeDouble(20, v->basePoint.y); + writer->writeDouble(30, v->basePoint.z); + } + if (v->stawidth != 0) + writer->writeDouble(40, v->stawidth); + if (v->endwidth != 0) + writer->writeDouble(41, v->endwidth); + if (v->bulge != 0) + writer->writeDouble(42, v->bulge); + if (v->flags != 0) { + writer->writeInt16(70, ent->flags); + } + if (v->flags & 2) { + writer->writeDouble(50, v->tgdir); + } + if ( v->flags & 128 ) { + if (v->vindex1 != 0) { + writer->writeInt16(71, v->vindex1); + } + if (v->vindex2 != 0) { + writer->writeInt16(72, v->vindex2); + } + if (v->vindex3 != 0) { + writer->writeInt16(73, v->vindex3); + } + if (v->vindex4 != 0) { + writer->writeInt16(74, v->vindex4); + } + if ( !(v->flags & 64) ) { + writer->writeInt32(91, v->identifier); + } + } + } + writer->writeString(0, "SEQEND"); + writeEntity(ent); + return true; +} + +bool dxfRW::writeSpline(DRW_Spline *ent){ + if (version > DRW::AC1009) { + writer->writeString(0, "SPLINE"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbSpline"); + } + writer->writeDouble(210, ent->normalVec.x); + writer->writeDouble(220, ent->normalVec.y); + writer->writeDouble(230, ent->normalVec.z); + writer->writeInt16(70, ent->flags); + writer->writeInt16(71, ent->degree); + writer->writeInt16(72, ent->nknots); + writer->writeInt16(73, ent->ncontrol); + writer->writeInt16(74, ent->nfit); + writer->writeDouble(42, ent->tolknot); + writer->writeDouble(43, ent->tolcontrol); + //RLZ: warning check if nknots are correct and ncontrol + for (int i = 0; i< ent->nknots; i++){ + writer->writeDouble(40, ent->knotslist.at(i)); + } + for (int i = 0; i< (int)ent->weightlist.size(); i++) { + writer->writeDouble(41, ent->weightlist.at(i)); + } + for (int i = 0; i< ent->ncontrol; i++){ + DRW_Coord *crd = ent->controllist.at(i); + writer->writeDouble(10, crd->x); + writer->writeDouble(20, crd->y); + writer->writeDouble(30, crd->z); + } + } else { + //RLZ: TODO convert spline in polyline (not exist in acad 12) + } + return true; +} + +bool dxfRW::writeHatch(DRW_Hatch *ent){ + if (version > DRW::AC1009) { + writer->writeString(0, "HATCH"); + writeEntity(ent); + writer->writeString(100, "AcDbHatch"); + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, ent->basePoint.z); + writer->writeDouble(210, ent->extPoint.x); + writer->writeDouble(220, ent->extPoint.y); + writer->writeDouble(230, ent->extPoint.z); + writer->writeString(2, ent->name); + writer->writeInt16(70, ent->solid); + writer->writeInt16(71, ent->associative); + ent->loopsnum = (int)ent->looplist.size(); + writer->writeInt16(91, ent->loopsnum); + //write paths data + for (int i = 0; i< ent->loopsnum; i++){ + DRW_HatchLoop *loop = ent->looplist.at(i); + writer->writeInt16(92, loop->type); + if ( (loop->type & 2) == 2){ + //RLZ: polyline boundary writeme + } else { + //boundary path + loop->update(); + writer->writeInt16(93, loop->numedges); + for (int j = 0; jnumedges; ++j) { + switch ( (loop->objlist.at(j))->eType) { + case DRW::LINE: { + writer->writeInt16(72, 1); + DRW_Line* l = (DRW_Line*)loop->objlist.at(j); + writer->writeDouble(10, l->basePoint.x); + writer->writeDouble(20, l->basePoint.y); + writer->writeDouble(11, l->secPoint.x); + writer->writeDouble(21, l->secPoint.y); + break; } + case DRW::ARC: { + writer->writeInt16(72, 2); + DRW_Arc* a = (DRW_Arc*)loop->objlist.at(j); + writer->writeDouble(10, a->basePoint.x); + writer->writeDouble(20, a->basePoint.y); + writer->writeDouble(40, a->radious); + writer->writeDouble(50, a->staangle*ARAD); + writer->writeDouble(51, a->endangle*ARAD); + writer->writeInt16(73, a->isccw); + break; } + case DRW::ELLIPSE: { + writer->writeInt16(72, 3); + DRW_Ellipse* a = (DRW_Ellipse*)loop->objlist.at(j); + a->correctAxis(); + writer->writeDouble(10, a->basePoint.x); + writer->writeDouble(20, a->basePoint.y); + writer->writeDouble(11, a->secPoint.x); + writer->writeDouble(21, a->secPoint.y); + writer->writeDouble(40, a->ratio); + writer->writeDouble(50, a->staparam*ARAD); + writer->writeDouble(51, a->endparam*ARAD); + writer->writeInt16(73, a->isccw); + break; } + case DRW::SPLINE: + //RLZ: spline boundary writeme +// writer->writeInt16(72, 4); + break; + default: + break; + } + } + writer->writeInt16(97, 0); + } + } + writer->writeInt16(75, ent->hstyle); + writer->writeInt16(76, ent->hpattern); + if (!ent->solid){ + writer->writeDouble(52, ent->angle); + writer->writeDouble(41, ent->scale); + writer->writeInt16(77, ent->doubleflag); + writer->writeInt16(78, ent->deflines); + } +/* if (ent->deflines > 0){ + writer->writeInt16(78, ent->deflines); + }*/ + writer->writeInt32(98, 0); + } else { + //RLZ: TODO verify in acad12 + } + return true; +} + +bool dxfRW::writeLeader(DRW_Leader *ent){ + if (version > DRW::AC1009) { + writer->writeString(0, "LEADER"); + writeEntity(ent); + writer->writeString(100, "AcDbLeader"); + writer->writeUtf8String(3, ent->style); + writer->writeInt16(71, ent->arrow); + writer->writeInt16(72, ent->leadertype); + writer->writeInt16(73, ent->flag); + writer->writeInt16(74, ent->hookline); + writer->writeInt16(75, ent->hookflag); + writer->writeDouble(40, ent->textheight); + writer->writeDouble(41, ent->textwidth); + writer->writeDouble(76, ent->vertnum); + writer->writeDouble(76, ent->vertexlist.size()); + for (unsigned int i=0; ivertexlist.size(); i++) { + DRW_Coord *vert = ent->vertexlist.at(i); + writer->writeDouble(10, vert->x); + writer->writeDouble(20, vert->y); + writer->writeDouble(30, vert->z); + } + } else { + //RLZ: todo not supported by acad 12 saved as unnamed block + } + return true; +} +bool dxfRW::writeDimension(DRW_Dimension *ent) { + if (version > DRW::AC1009) { + writer->writeString(0, "DIMENSION"); + writeEntity(ent); + writer->writeString(100, "AcDbDimension"); + if (!ent->getName().empty()){ + writer->writeString(2, ent->getName()); + } + writer->writeDouble(10, ent->getDefPoint().x); + writer->writeDouble(20, ent->getDefPoint().y); + writer->writeDouble(30, ent->getDefPoint().z); + writer->writeDouble(11, ent->getTextPoint().x); + writer->writeDouble(21, ent->getTextPoint().y); + writer->writeDouble(31, ent->getTextPoint().z); + if ( !(ent->type & 32)) + ent->type = ent->type +32; + writer->writeInt16(70, ent->type); + if ( !(ent->getText().empty()) ) + writer->writeUtf8String(1, ent->getText()); + writer->writeInt16(71, ent->getAlign()); + if ( ent->getTextLineStyle() != 1) + writer->writeInt16(72, ent->getTextLineStyle()); + if ( ent->getTextLineFactor() != 1) + writer->writeDouble(41, ent->getTextLineFactor()); + writer->writeUtf8String(3, ent->getStyle()); + if ( ent->getTextLineFactor() != 0) + writer->writeDouble(53, ent->getDir()); + writer->writeDouble(210, ent->getExtrusion().x); + writer->writeDouble(220, ent->getExtrusion().y); + writer->writeDouble(230, ent->getExtrusion().z); + if ( ent->hasActualMeasurement()) + writer->writeDouble(42, ent->getActualMeasurement()); + + switch (ent->eType) { + case DRW::DIMALIGNED: + case DRW::DIMLINEAR: { + DRW_DimAligned * dd = (DRW_DimAligned*)ent; + writer->writeString(100, "AcDbAlignedDimension"); + DRW_Coord crd = dd->getClonepoint(); + if (crd.x != 0 || crd.y != 0 || crd.z != 0) { + writer->writeDouble(12, crd.x); + writer->writeDouble(22, crd.y); + writer->writeDouble(32, crd.z); + } + writer->writeDouble(13, dd->getDef1Point().x); + writer->writeDouble(23, dd->getDef1Point().y); + writer->writeDouble(33, dd->getDef1Point().z); + writer->writeDouble(14, dd->getDef2Point().x); + writer->writeDouble(24, dd->getDef2Point().y); + writer->writeDouble(34, dd->getDef2Point().z); + if (ent->eType == DRW::DIMLINEAR) { + DRW_DimLinear * dl = (DRW_DimLinear*)ent; + if (dl->getAngle() != 0) + writer->writeDouble(50, dl->getAngle()); + if (dl->getOblique() != 0) + writer->writeDouble(52, dl->getOblique()); + writer->writeString(100, "AcDbRotatedDimension"); + } + break; } + case DRW::DIMRADIAL: { + DRW_DimRadial * dd = (DRW_DimRadial*)ent; + writer->writeString(100, "AcDbRadialDimension"); + writer->writeDouble(15, dd->getDiameterPoint().x); + writer->writeDouble(25, dd->getDiameterPoint().y); + writer->writeDouble(35, dd->getDiameterPoint().z); + writer->writeDouble(40, dd->getLeaderLength()); + break; } + case DRW::DIMDIAMETRIC: { + DRW_DimDiametric * dd = (DRW_DimDiametric*)ent; + writer->writeString(100, "AcDbDiametricDimension"); + writer->writeDouble(15, dd->getDiameter1Point().x); + writer->writeDouble(25, dd->getDiameter1Point().y); + writer->writeDouble(35, dd->getDiameter1Point().z); + writer->writeDouble(40, dd->getLeaderLength()); + break; } + case DRW::DIMANGULAR: { + DRW_DimAngular * dd = (DRW_DimAngular*)ent; + writer->writeString(100, "AcDb2LineAngularDimension"); + writer->writeDouble(13, dd->getFirstLine1().x); + writer->writeDouble(23, dd->getFirstLine1().y); + writer->writeDouble(33, dd->getFirstLine1().z); + writer->writeDouble(14, dd->getFirstLine2().x); + writer->writeDouble(24, dd->getFirstLine2().y); + writer->writeDouble(34, dd->getFirstLine2().z); + writer->writeDouble(15, dd->getSecondLine1().x); + writer->writeDouble(25, dd->getSecondLine1().y); + writer->writeDouble(35, dd->getSecondLine1().z); + writer->writeDouble(16, dd->getDimPoint().x); + writer->writeDouble(26, dd->getDimPoint().y); + writer->writeDouble(36, dd->getDimPoint().z); + break; } + case DRW::DIMANGULAR3P: { + DRW_DimAngular3p * dd = (DRW_DimAngular3p*)ent; + writer->writeDouble(13, dd->getFirstLine().x); + writer->writeDouble(23, dd->getFirstLine().y); + writer->writeDouble(33, dd->getFirstLine().z); + writer->writeDouble(14, dd->getSecondLine().x); + writer->writeDouble(24, dd->getSecondLine().y); + writer->writeDouble(34, dd->getSecondLine().z); + writer->writeDouble(15, dd->getVertexPoint().x); + writer->writeDouble(25, dd->getVertexPoint().y); + writer->writeDouble(35, dd->getVertexPoint().z); + break; } + case DRW::DIMORDINATE: { + DRW_DimOrdinate * dd = (DRW_DimOrdinate*)ent; + writer->writeString(100, "AcDbOrdinateDimension"); + writer->writeDouble(13, dd->getFirstLine().x); + writer->writeDouble(23, dd->getFirstLine().y); + writer->writeDouble(33, dd->getFirstLine().z); + writer->writeDouble(14, dd->getSecondLine().x); + writer->writeDouble(24, dd->getSecondLine().y); + writer->writeDouble(34, dd->getSecondLine().z); + break; } + default: + break; + } + } else { + //RLZ: todo not supported by acad 12 saved as unnamed block + } + return true; +} + +bool dxfRW::writeInsert(DRW_Insert *ent){ + writer->writeString(0, "INSERT"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbBlockReference"); + writer->writeUtf8String(2, ent->name); + } else + writer->writeUtf8Caps(2, ent->name); + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + writer->writeDouble(30, ent->basePoint.z); + writer->writeDouble(41, ent->xscale); + writer->writeDouble(42, ent->yscale); + writer->writeDouble(43, ent->zscale); + writer->writeDouble(50, (ent->angle)*ARAD); //in dxf angle is writed in degrees + writer->writeInt16(70, ent->colcount); + writer->writeInt16(71, ent->rowcount); + writer->writeDouble(44, ent->colspace); + writer->writeDouble(45, ent->rowspace); + return true; +} + +bool dxfRW::writeText(DRW_Text *ent){ + writer->writeString(0, "TEXT"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbText"); + } +// writer->writeDouble(39, ent->thickness); + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + writer->writeDouble(30, ent->basePoint.z); + writer->writeDouble(40, ent->height); + writer->writeUtf8String(1, ent->text); + writer->writeDouble(50, ent->angle); + writer->writeDouble(41, ent->widthscale); + writer->writeDouble(51, ent->oblique); + if (version > DRW::AC1009) + writer->writeUtf8String(7, ent->style); + else + writer->writeUtf8Caps(7, ent->style); + writer->writeInt16(71, ent->textgen); + if (ent->alignH != DRW_Text::HLeft) { + writer->writeInt16(72, ent->alignH); + } + if (ent->alignH != DRW_Text::HLeft || ent->alignV != DRW_Text::VBaseLine) { + writer->writeDouble(11, ent->secPoint.x); + writer->writeDouble(21, ent->secPoint.y); + writer->writeDouble(31, ent->secPoint.z); + } + writer->writeDouble(210, ent->extPoint.x); + writer->writeDouble(220, ent->extPoint.y); + writer->writeDouble(230, ent->extPoint.z); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbText"); + } + if (ent->alignV != DRW_Text::VBaseLine) { + writer->writeInt16(73, ent->alignV); + } + return true; +} + +bool dxfRW::writeMText(DRW_MText *ent){ + if (version > DRW::AC1009) { + writer->writeString(0, "MTEXT"); + writeEntity(ent); + writer->writeString(100, "AcDbMText"); + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + writer->writeDouble(30, ent->basePoint.z); + writer->writeDouble(40, ent->height); + writer->writeDouble(41, ent->widthscale); + writer->writeInt16(71, ent->textgen); + writer->writeInt16(72, ent->alignH); + std::string text = writer->fromUtf8String(ent->text); + + int i; + for(i =0; (text.size()-i) > 250; ) { + writer->writeString(3, text.substr(i, 250)); + i +=250; + } + writer->writeString(1, text.substr(i)); + writer->writeString(7, ent->style); + writer->writeDouble(210, ent->extPoint.x); + writer->writeDouble(220, ent->extPoint.y); + writer->writeDouble(230, ent->extPoint.z); + writer->writeDouble(50, ent->angle); + writer->writeInt16(73, ent->alignV); + writer->writeDouble(44, ent->interlin); +//RLZ ... 11, 21, 31 needed? + } else { + //RLZ: TODO convert mtext in text lines (not exist in acad 12) + } + return true; +} + +bool dxfRW::writeViewport(DRW_Viewport *ent) { + writer->writeString(0, "VIEWPORT"); + writeEntity(ent); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbViewport"); + } + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + if (ent->basePoint.z != 0.0) + writer->writeDouble(30, ent->basePoint.z); + writer->writeDouble(40, ent->pswidth); + writer->writeDouble(41, ent->psheight); + writer->writeInt16(68, ent->vpstatus); + writer->writeInt16(69, ent->vpID); + writer->writeDouble(12, ent->centerPX);//RLZ: verify if exist in V12 + writer->writeDouble(22, ent->centerPY);//RLZ: verify if exist in V12 + return true; +} + +DRW_ImageDef* dxfRW::writeImage(DRW_Image *ent, std::string name){ + if (version > DRW::AC1009) { + //search if exist imagedef with this mane (image inserted more than 1 time) + //RLZ: imagedef_reactor seem needed to read in acad + DRW_ImageDef *id = NULL; + for (unsigned int i=0; iname == name ) { + id = imageDef.at(i); + continue; + } + } + if (id == NULL) { + id = new DRW_ImageDef(); + imageDef.push_back(id); + id->handle = ++entCount; + } + id->name = name; + std::string idReactor = toHexStr(++entCount); + + writer->writeString(0, "IMAGE"); + writeEntity(ent); + writer->writeString(100, "AcDbRasterImage"); + writer->writeDouble(10, ent->basePoint.x); + writer->writeDouble(20, ent->basePoint.y); + writer->writeDouble(30, ent->basePoint.z); + writer->writeDouble(11, ent->secPoint.x); + writer->writeDouble(21, ent->secPoint.y); + writer->writeDouble(31, ent->secPoint.z); + writer->writeDouble(12, ent->vVector.x); + writer->writeDouble(22, ent->vVector.y); + writer->writeDouble(32, ent->vVector.z); + writer->writeDouble(13, ent->sizeu); + writer->writeDouble(23, ent->sizev); + writer->writeString(340, toHexStr(id->handle)); + writer->writeInt16(70, 1); + writer->writeInt16(280, ent->clip); + writer->writeInt16(281, ent->brightness); + writer->writeInt16(282, ent->contrast); + writer->writeInt16(283, ent->fade); + writer->writeString(360, idReactor); + id->reactors[idReactor] = toHexStr(ent->handle); + return id; + } + return NULL; //not exist in acad 12 +} + +bool dxfRW::writeBlockRecord(std::string name){ + if (version > DRW::AC1009) { + writer->writeString(0, "BLOCK_RECORD"); + writer->writeString(5, toHexStr(++entCount)); + + blockMap[name] = entCount; + entCount = 2+entCount;//reserve 2 for BLOCK & ENDBLOCK + if (version > DRW::AC1014) { + writer->writeString(330, "1"); + } + writer->writeString(100, "AcDbSymbolTableRecord"); + writer->writeString(100, "AcDbBlockTableRecord"); + writer->writeUtf8String(2, name); + if (version > DRW::AC1018) { + // writer->writeInt16(340, 22); + writer->writeInt16(70, 0); + writer->writeInt16(280, 1); + writer->writeInt16(281, 0); + } + } + return true; +} + +bool dxfRW::writeBlock(DRW_Block *bk){ + if (writingBlock) { + writer->writeString(0, "ENDBLK"); + if (version > DRW::AC1009) { + writer->writeString(5, toHexStr(currHandle+2)); + if (version > DRW::AC1014) { + writer->writeString(330, toHexStr(currHandle)); + } + writer->writeString(100, "AcDbEntity"); + } + writer->writeString(8, bk->layer); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbBlockEnd"); + } + } + writingBlock = true; + writer->writeString(0, "BLOCK"); + if (version > DRW::AC1009) { + currHandle = (*(blockMap.find(bk->name))).second; + writer->writeString(5, toHexStr(currHandle+1)); + if (version > DRW::AC1014) { + writer->writeString(330, toHexStr(currHandle)); + } + writer->writeString(100, "AcDbEntity"); + } + writer->writeString(8, bk->layer); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbBlockBegin"); + writer->writeUtf8String(2, bk->name); + } else + writer->writeUtf8Caps(2, bk->name); + writer->writeInt16(70, bk->flags); + writer->writeDouble(10, bk->basePoint.x); + writer->writeDouble(20, bk->basePoint.y); + if (bk->basePoint.z != 0.0) { + writer->writeDouble(30, bk->basePoint.z); + } + if (version > DRW::AC1009) + writer->writeUtf8String(3, bk->name); + else + writer->writeUtf8Caps(3, bk->name); + writer->writeString(1, ""); + + return true; +} + +bool dxfRW::writeTables() { + writer->writeString(0, "TABLE"); + writer->writeString(2, "VPORT"); + if (version > DRW::AC1009) { + writer->writeString(5, "8"); + if (version > DRW::AC1014) { + writer->writeString(330, "0"); + } + writer->writeString(100, "AcDbSymbolTable"); + } + writer->writeInt16(70, 1); //end table def +/*** VPORT ***/ + dimstyleStd =false; + iface->writeVports(); + if (!dimstyleStd) { + DRW_Vport portact; + portact.name = "*ACTIVE"; + writeVport(&portact); + } + writer->writeString(0, "ENDTAB"); +/*** LTYPE ***/ + writer->writeString(0, "TABLE"); + writer->writeString(2, "LTYPE"); + if (version > DRW::AC1009) { + writer->writeString(5, "5"); + if (version > DRW::AC1014) { + writer->writeString(330, "0"); + } + writer->writeString(100, "AcDbSymbolTable"); + } + writer->writeInt16(70, 4); //end table def +//Mandatory linetypes + writer->writeString(0, "LTYPE"); + if (version > DRW::AC1009) { + writer->writeString(5, "14"); + if (version > DRW::AC1014) { + writer->writeString(330, "5"); + } + writer->writeString(100, "AcDbSymbolTableRecord"); + writer->writeString(100, "AcDbLinetypeTableRecord"); + writer->writeString(2, "ByBlock"); + } else + writer->writeString(2, "BYBLOCK"); + writer->writeInt16(70, 0); + writer->writeString(3, ""); + writer->writeInt16(72, 65); + writer->writeInt16(73, 0); + writer->writeDouble(40, 0.0); + + writer->writeString(0, "LTYPE"); + if (version > DRW::AC1009) { + writer->writeString(5, "15"); + if (version > DRW::AC1014) { + writer->writeString(330, "5"); + } + writer->writeString(100, "AcDbSymbolTableRecord"); + writer->writeString(100, "AcDbLinetypeTableRecord"); + writer->writeString(2, "ByLayer"); + } else + writer->writeString(2, "BYLAYER"); + writer->writeInt16(70, 0); + writer->writeString(3, ""); + writer->writeInt16(72, 65); + writer->writeInt16(73, 0); + writer->writeDouble(40, 0.0); + + writer->writeString(0, "LTYPE"); + if (version > DRW::AC1009) { + writer->writeString(5, "16"); + if (version > DRW::AC1014) { + writer->writeString(330, "5"); + } + writer->writeString(100, "AcDbSymbolTableRecord"); + writer->writeString(100, "AcDbLinetypeTableRecord"); + writer->writeString(2, "Continuous"); + } else { + writer->writeString(2, "CONTINUOUS"); + } + writer->writeInt16(70, 0); + writer->writeString(3, "Solid line"); + writer->writeInt16(72, 65); + writer->writeInt16(73, 0); + writer->writeDouble(40, 0.0); +//Application linetypes + iface->writeLTypes(); + writer->writeString(0, "ENDTAB"); +/*** LAYER ***/ + writer->writeString(0, "TABLE"); + writer->writeString(2, "LAYER"); + if (version > DRW::AC1009) { + writer->writeString(5, "2"); + if (version > DRW::AC1014) { + writer->writeString(330, "0"); + } + writer->writeString(100, "AcDbSymbolTable"); + } + writer->writeInt16(70, 1); //end table def + wlayer0 =false; + iface->writeLayers(); + if (!wlayer0 && version > DRW::AC1009) { + DRW_Layer lay0; + lay0.name = "0"; + writeLayer(&lay0); + } + writer->writeString(0, "ENDTAB"); +/*** STYLE ***/ + writer->writeString(0, "TABLE"); + writer->writeString(2, "STYLE"); + if (version > DRW::AC1009) { + writer->writeString(5, "3"); + if (version > DRW::AC1014) { + writer->writeString(330, "0"); + } + writer->writeString(100, "AcDbSymbolTable"); + } + writer->writeInt16(70, 3); //end table def + dimstyleStd =false; + iface->writeTextstyles(); + if (!dimstyleStd) { + DRW_Textstyle tsty; + tsty.name = "Standard"; + writeTextstyle(&tsty); + } + writer->writeString(0, "ENDTAB"); + + writer->writeString(0, "TABLE"); + writer->writeString(2, "VIEW"); + if (version > DRW::AC1009) { + writer->writeString(5, "6"); + if (version > DRW::AC1014) { + writer->writeString(330, "0"); + } + writer->writeString(100, "AcDbSymbolTable"); + } + writer->writeInt16(70, 0); //end table def + writer->writeString(0, "ENDTAB"); + + writer->writeString(0, "TABLE"); + writer->writeString(2, "UCS"); + if (version > DRW::AC1009) { + writer->writeString(5, "7"); + if (version > DRW::AC1014) { + writer->writeString(330, "0"); + } + writer->writeString(100, "AcDbSymbolTable"); + } + writer->writeInt16(70, 0); //end table def + writer->writeString(0, "ENDTAB"); + + writer->writeString(0, "TABLE"); + writer->writeString(2, "APPID"); + if (version > DRW::AC1009) { + writer->writeString(5, "9"); + if (version > DRW::AC1014) { + writer->writeString(330, "0"); + } + writer->writeString(100, "AcDbSymbolTable"); + } + writer->writeInt16(70, 1); //end table def + writer->writeString(0, "APPID"); + if (version > DRW::AC1009) { + writer->writeString(5, "12"); + if (version > DRW::AC1014) { + writer->writeString(330, "9"); + } + writer->writeString(100, "AcDbSymbolTableRecord"); + writer->writeString(100, "AcDbRegAppTableRecord"); + } + writer->writeString(2, "ACAD"); + writer->writeInt16(70, 0); + iface->writeAppId(); + writer->writeString(0, "ENDTAB"); + + writer->writeString(0, "TABLE"); + writer->writeString(2, "DIMSTYLE"); + if (version > DRW::AC1009) { + writer->writeString(5, "A"); + if (version > DRW::AC1014) { + writer->writeString(330, "0"); + } + writer->writeString(100, "AcDbSymbolTable"); + } + writer->writeInt16(70, 1); //end table def + if (version > DRW::AC1014) { + writer->writeString(100, "AcDbDimStyleTable"); + writer->writeInt16(71, 1); //end table def + } + dimstyleStd =false; + iface->writeDimstyles(); + if (!dimstyleStd) { + DRW_Dimstyle dsty; + dsty.name = "Standard"; + writeDimstyle(&dsty); + } + writer->writeString(0, "ENDTAB"); + + if (version > DRW::AC1009) { + writer->writeString(0, "TABLE"); + writer->writeString(2, "BLOCK_RECORD"); + writer->writeString(5, "1"); + if (version > DRW::AC1014) { + writer->writeString(330, "0"); + } + writer->writeString(100, "AcDbSymbolTable"); + writer->writeInt16(70, 2); //end table def + writer->writeString(0, "BLOCK_RECORD"); + writer->writeString(5, "1F"); + if (version > DRW::AC1014) { + writer->writeString(330, "1"); + } + writer->writeString(100, "AcDbSymbolTableRecord"); + writer->writeString(100, "AcDbBlockTableRecord"); + writer->writeString(2, "*Model_Space"); + if (version > DRW::AC1018) { + // writer->writeInt16(340, 22); + writer->writeInt16(70, 0); + writer->writeInt16(280, 1); + writer->writeInt16(281, 0); + } + writer->writeString(0, "BLOCK_RECORD"); + writer->writeString(5, "1E"); + if (version > DRW::AC1014) { + writer->writeString(330, "1"); + } + writer->writeString(100, "AcDbSymbolTableRecord"); + writer->writeString(100, "AcDbBlockTableRecord"); + writer->writeString(2, "*Paper_Space"); + if (version > DRW::AC1018) { + // writer->writeInt16(340, 22); + writer->writeInt16(70, 0); + writer->writeInt16(280, 1); + writer->writeInt16(281, 0); + } + } + /* always call writeBlockRecords to iface for prepare unnamed blocks */ + iface->writeBlockRecords(); + if (version > DRW::AC1009) { + writer->writeString(0, "ENDTAB"); + } +return true; +} + +bool dxfRW::writeBlocks() { + writer->writeString(0, "BLOCK"); + if (version > DRW::AC1009) { + writer->writeString(5, "20"); + if (version > DRW::AC1014) { + writer->writeString(330, "1F"); + } + writer->writeString(100, "AcDbEntity"); + } + writer->writeString(8, "0"); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbBlockBegin"); + writer->writeString(2, "*Model_Space"); + } else + writer->writeString(2, "$MODEL_SPACE"); + writer->writeInt16(70, 0); + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + if (version > DRW::AC1009) + writer->writeString(3, "*Model_Space"); + else + writer->writeString(3, "$MODEL_SPACE"); + writer->writeString(1, ""); + writer->writeString(0, "ENDBLK"); + if (version > DRW::AC1009) { + writer->writeString(5, "21"); + if (version > DRW::AC1014) { + writer->writeString(330, "1F"); + } + writer->writeString(100, "AcDbEntity"); + } + writer->writeString(8, "0"); + if (version > DRW::AC1009) + writer->writeString(100, "AcDbBlockEnd"); + + writer->writeString(0, "BLOCK"); + if (version > DRW::AC1009) { + writer->writeString(5, "1C"); + if (version > DRW::AC1014) { + writer->writeString(330, "1B"); + } + writer->writeString(100, "AcDbEntity"); + } + writer->writeString(8, "0"); + if (version > DRW::AC1009) { + writer->writeString(100, "AcDbBlockBegin"); + writer->writeString(2, "*Paper_Space"); + } else + writer->writeString(2, "$PAPER_SPACE"); + writer->writeInt16(70, 0); + writer->writeDouble(10, 0.0); + writer->writeDouble(20, 0.0); + writer->writeDouble(30, 0.0); + if (version > DRW::AC1009) + writer->writeString(3, "*Paper_Space"); + else + writer->writeString(3, "$PAPER_SPACE"); + writer->writeString(1, ""); + writer->writeString(0, "ENDBLK"); + if (version > DRW::AC1009) { + writer->writeString(5, "1D"); + if (version > DRW::AC1014) { + writer->writeString(330, "1F"); + } + writer->writeString(100, "AcDbEntity"); + } + writer->writeString(8, "0"); + if (version > DRW::AC1009) + writer->writeString(100, "AcDbBlockEnd"); + writingBlock = false; + iface->writeBlocks(); + if (writingBlock) { + writingBlock = false; + writer->writeString(0, "ENDBLK"); + if (version > DRW::AC1009) { + writer->writeString(5, toHexStr(currHandle+2)); +// writer->writeString(5, "1D"); + if (version > DRW::AC1014) { + writer->writeString(330, toHexStr(currHandle)); + } + writer->writeString(100, "AcDbEntity"); + } + writer->writeString(8, "0"); + if (version > DRW::AC1009) + writer->writeString(100, "AcDbBlockEnd"); + } + return true; +} + +bool dxfRW::writeObjects() { + writer->writeString(0, "DICTIONARY"); + std::string imgDictH; + writer->writeString(5, "C"); + if (version > DRW::AC1014) { + writer->writeString(330, "0"); + } + writer->writeString(100, "AcDbDictionary"); + writer->writeInt16(281, 1); + writer->writeString(3, "ACAD_GROUP"); + writer->writeString(350, "D"); + if (imageDef.size() != 0) { + writer->writeString(3, "ACAD_IMAGE_DICT"); + imgDictH = toHexStr(++entCount); + writer->writeString(350, imgDictH); + } + writer->writeString(0, "DICTIONARY"); + writer->writeString(5, "D"); + writer->writeString(330, "C"); + writer->writeString(100, "AcDbDictionary"); + writer->writeInt16(281, 1); +//write IMAGEDEF_REACTOR + for (unsigned int i=0; i::iterator it; + for ( it=id->reactors.begin() ; it != id->reactors.end(); ++it ) { + writer->writeString(0, "IMAGEDEF_REACTOR"); + writer->writeString(5, (*it).first); + writer->writeString(330, (*it).second); + writer->writeString(100, "AcDbRasterImageDefReactor"); + writer->writeInt16(90, 2); //version 2=R14 to v2010 + writer->writeString(330, (*it).second); + } + } + if (imageDef.size() != 0) { + writer->writeString(0, "DICTIONARY"); + writer->writeString(5, imgDictH); + writer->writeString(330, "C"); + writer->writeString(100, "AcDbDictionary"); + writer->writeInt16(281, 1); + for (unsigned int i=0; iname.find_last_of("/\\"); + f2 =imageDef.at(i)->name.find_last_of('.'); + ++f1; + writer->writeString(3, imageDef.at(i)->name.substr(f1,f2-f1)); + writer->writeString(350, toHexStr(imageDef.at(i)->handle) ); + } + } + for (unsigned int i=0; iwriteString(0, "IMAGEDEF"); + writer->writeString(5, toHexStr(id->handle) ); + if (version > DRW::AC1014) { +// writer->writeString(330, "0"); handle to DICTIONARY + } + writer->writeString(102, "{ACAD_REACTORS"); + std::map::iterator it; + for ( it=id->reactors.begin() ; it != id->reactors.end(); ++it ) { + writer->writeString(330, (*it).first); + } + writer->writeString(102, "}"); + writer->writeString(100, "AcDbRasterImageDef"); + writer->writeInt16(90, 0); //version 0=R14 to v2010 + writer->writeUtf8String(1, id->name); + writer->writeDouble(10, id->u); + writer->writeDouble(20, id->v); + writer->writeDouble(11, id->up); + writer->writeDouble(21, id->vp); + writer->writeInt16(280, id->loaded); + writer->writeInt16(281, id->resolution); + } + //no more needed imageDef, delete it + while (!imageDef.empty()) { + imageDef.pop_back(); + } + + return true; +} + +bool dxfRW::writeExtData(const std::vector &ed){ + for (std::vector::const_iterator it=ed.begin(); it!=ed.end(); ++it){ + switch ((*it)->code) { + case 1000: + case 1001: + case 1002: + case 1003: + case 1004: + case 1005: + {int cc = (*it)->code; + if ((*it)->type == DRW_Variant::STRING) + writer->writeUtf8String(cc, *(*it)->content.s); +// writer->writeUtf8String((*it)->code, (*it)->content.s); + break;} + case 1010: + case 1011: + case 1012: + case 1013: + if ((*it)->type == DRW_Variant::COORD) { + writer->writeDouble((*it)->code, (*it)->content.v->x); + writer->writeDouble((*it)->code+10 , (*it)->content.v->y); + writer->writeDouble((*it)->code+20 , (*it)->content.v->z); + } + break; + case 1040: + case 1041: + case 1042: + if ((*it)->type == DRW_Variant::DOUBLE) + writer->writeDouble((*it)->code, (*it)->content.d); + break; + case 1070: + if ((*it)->type == DRW_Variant::INTEGER) + writer->writeInt16((*it)->code, (*it)->content.i); + break; + case 1071: + if ((*it)->type == DRW_Variant::INTEGER) + writer->writeInt32((*it)->code, (*it)->content.i); + break; + default: + break; + } + } + return true; +} + +/********* Reader Process *********/ + +bool dxfRW::processDxf() { + DRW_DBG("dxfRW::processDxf() start processing dxf\n"); + int code; + bool more = true; + std::string sectionstr; +// section = secUnknown; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG(" processDxf\n"); + if (code == 999) { + header.addComment(reader->getString()); + } else if (code == 0) { + sectionstr = reader->getString(); + DRW_DBG(sectionstr); DRW_DBG(" processDxf\n"); + if (sectionstr == "EOF") { + return true; //found EOF terminate + } + if (sectionstr == "SECTION") { + more = reader->readRec(&code); + DRW_DBG(code); DRW_DBG(" processDxf\n"); + if (!more) + return false; //wrong dxf file + if (code == 2) { + sectionstr = reader->getString(); + DRW_DBG(sectionstr); DRW_DBG(" processDxf\n"); + //found section, process it + if (sectionstr == "HEADER") { + processHeader(); + } else if (sectionstr == "CLASSES") { +// processClasses(); + } else if (sectionstr == "TABLES") { + processTables(); + } else if (sectionstr == "BLOCKS") { + processBlocks(); + } else if (sectionstr == "ENTITIES") { + processEntities(false); + } else if (sectionstr == "OBJECTS") { + processObjects(); + } + } + } + } +/* if (!more) + return true;*/ + } + return true; +} + +/********* Header Section *********/ + +bool dxfRW::processHeader() { + DRW_DBG("dxfRW::processHeader\n"); + int code; + std::string sectionstr; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG(" processHeader\n"); + if (code == 0) { + sectionstr = reader->getString(); + DRW_DBG(sectionstr); DRW_DBG(" processHeader\n\n"); + if (sectionstr == "ENDSEC") { + iface->addHeader(&header); + return true; //found ENDSEC terminate + } + } else header.parseCode(code, reader); + } + return true; +} + +/********* Tables Section *********/ + +bool dxfRW::processTables() { + DRW_DBG("dxfRW::processTables\n"); + int code; + std::string sectionstr; + bool more = true; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + if (code == 0) { + sectionstr = reader->getString(); + DRW_DBG(sectionstr); DRW_DBG(" processHeader\n\n"); + if (sectionstr == "TABLE") { + more = reader->readRec(&code); + DRW_DBG(code); DRW_DBG("\n"); + if (!more) + return false; //wrong dxf file + if (code == 2) { + sectionstr = reader->getString(); + DRW_DBG(sectionstr); DRW_DBG(" processHeader\n\n"); + //found section, process it + if (sectionstr == "LTYPE") { + processLType(); + } else if (sectionstr == "LAYER") { + processLayer(); + } else if (sectionstr == "STYLE") { + processTextStyle(); + } else if (sectionstr == "VPORT") { + processVports(); + } else if (sectionstr == "VIEW") { +// processView(); + } else if (sectionstr == "UCS") { +// processUCS(); + } else if (sectionstr == "APPID") { + processAppId(); + } else if (sectionstr == "DIMSTYLE") { + processDimStyle(); + } else if (sectionstr == "BLOCK_RECORD") { +// processBlockRecord(); + } + } + } else if (sectionstr == "ENDSEC") { + return true; //found ENDSEC terminate + } + } + } + return true; +} + +bool dxfRW::processLType() { + DRW_DBG("dxfRW::processLType\n"); + int code; + std::string sectionstr; + bool reading = false; + DRW_LType ltype; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + if (code == 0) { + if (reading) { + ltype.update(); + iface->addLType(ltype); + } + sectionstr = reader->getString(); + DRW_DBG(sectionstr); DRW_DBG("\n"); + if (sectionstr == "LTYPE") { + reading = true; + ltype.reset(); + } else if (sectionstr == "ENDTAB") { + return true; //found ENDTAB terminate + } + } else if (reading) + ltype.parseCode(code, reader); + } + return true; +} + +bool dxfRW::processLayer() { + DRW_DBG("dxfRW::processLayer\n"); + int code; + std::string sectionstr; + bool reading = false; + DRW_Layer layer; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + if (code == 0) { + if (reading) + iface->addLayer(layer); + sectionstr = reader->getString(); + DRW_DBG(sectionstr); DRW_DBG("\n"); + if (sectionstr == "LAYER") { + reading = true; + layer.reset(); + } else if (sectionstr == "ENDTAB") { + return true; //found ENDTAB terminate + } + } else if (reading) + layer.parseCode(code, reader); + } + return true; +} + +bool dxfRW::processDimStyle() { + DRW_DBG("dxfRW::processDimStyle"); + int code; + std::string sectionstr; + bool reading = false; + DRW_Dimstyle dimSty; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + if (code == 0) { + if (reading) + iface->addDimStyle(dimSty); + sectionstr = reader->getString(); + DRW_DBG(sectionstr); DRW_DBG("\n"); + if (sectionstr == "DIMSTYLE") { + reading = true; + dimSty.reset(); + } else if (sectionstr == "ENDTAB") { + return true; //found ENDTAB terminate + } + } else if (reading) + dimSty.parseCode(code, reader); + } + return true; +} + +bool dxfRW::processTextStyle(){ + DRW_DBG("dxfRW::processTextStyle"); + int code; + std::string sectionstr; + bool reading = false; + DRW_Textstyle TxtSty; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + if (code == 0) { + if (reading) + iface->addTextStyle(TxtSty); + sectionstr = reader->getString(); + DRW_DBG(sectionstr); DRW_DBG("\n"); + if (sectionstr == "STYLE") { + reading = true; + TxtSty.reset(); + } else if (sectionstr == "ENDTAB") { + return true; //found ENDTAB terminate + } + } else if (reading) + TxtSty.parseCode(code, reader); + } + return true; +} + +bool dxfRW::processVports(){ + DRW_DBG("dxfRW::processVports"); + int code; + std::string sectionstr; + bool reading = false; + DRW_Vport vp; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + if (code == 0) { + if (reading) + iface->addVport(vp); + sectionstr = reader->getString(); + DRW_DBG(sectionstr); DRW_DBG("\n"); + if (sectionstr == "VPORT") { + reading = true; + vp.reset(); + } else if (sectionstr == "ENDTAB") { + return true; //found ENDTAB terminate + } + } else if (reading) + vp.parseCode(code, reader); + } + return true; +} + +bool dxfRW::processAppId(){ + DRW_DBG("dxfRW::processAppId"); + int code; + std::string sectionstr; + bool reading = false; + DRW_AppId vp; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + if (code == 0) { + if (reading) + iface->addAppId(vp); + sectionstr = reader->getString(); + DRW_DBG(sectionstr); DRW_DBG("\n"); + if (sectionstr == "APPID") { + reading = true; + vp.reset(); + } else if (sectionstr == "ENDTAB") { + return true; //found ENDTAB terminate + } + } else if (reading) + vp.parseCode(code, reader); + } + return true; +} + +/********* Block Section *********/ + +bool dxfRW::processBlocks() { + DRW_DBG("dxfRW::processBlocks\n"); + int code; + std::string sectionstr; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + if (code == 0) { + sectionstr = reader->getString(); + DRW_DBG(sectionstr); DRW_DBG("\n"); + if (sectionstr == "BLOCK") { + processBlock(); + } else if (sectionstr == "ENDSEC") { + return true; //found ENDSEC terminate + } + } + } + return true; +} + +bool dxfRW::processBlock() { + DRW_DBG("dxfRW::processBlock"); + int code; + DRW_Block block; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + iface->addBlock(block); + if (nextentity == "ENDBLK") { + iface->endBlock(); + return true; //found ENDBLK, terminate + } else { + processEntities(true); + iface->endBlock(); + return true; //found ENDBLK, terminate + } + } + default: + block.parseCode(code, reader); + break; + } + } + return true; +} + + +/********* Entities Section *********/ + +bool dxfRW::processEntities(bool isblock) { + DRW_DBG("dxfRW::processEntities\n"); + int code; + if (!reader->readRec(&code)){ + return false; + } + bool next = true; + if (code == 0) { + nextentity = reader->getString(); + } else if (!isblock) { + return false; //first record in entities is 0 + } + do { + if (nextentity == "ENDSEC" || nextentity == "ENDBLK") { + return true; //found ENDSEC or ENDBLK terminate + } else if (nextentity == "POINT") { + processPoint(); + } else if (nextentity == "LINE") { + processLine(); + } else if (nextentity == "CIRCLE") { + processCircle(); + } else if (nextentity == "ARC") { + processArc(); + } else if (nextentity == "ELLIPSE") { + processEllipse(); + } else if (nextentity == "TRACE") { + processTrace(); + } else if (nextentity == "SOLID") { + processSolid(); + } else if (nextentity == "INSERT") { + processInsert(); + } else if (nextentity == "LWPOLYLINE") { + processLWPolyline(); + } else if (nextentity == "POLYLINE") { + processPolyline(); + } else if (nextentity == "TEXT") { + processText(); + } else if (nextentity == "MTEXT") { + processMText(); + } else if (nextentity == "HATCH") { + processHatch(); + } else if (nextentity == "SPLINE") { + processSpline(); + } else if (nextentity == "3DFACE") { + process3dface(); + } else if (nextentity == "VIEWPORT") { + processViewport(); + } else if (nextentity == "IMAGE") { + processImage(); + } else if (nextentity == "DIMENSION") { + processDimension(); + } else if (nextentity == "LEADER") { + processLeader(); + } else if (nextentity == "RAY") { + processRay(); + } else if (nextentity == "XLINE") { + processXline(); + } else { + if (reader->readRec(&code)){ + if (code == 0) + nextentity = reader->getString(); + } else + return false; //end of file without ENDSEC + } + + } while (next); + return true; +} + +bool dxfRW::processEllipse() { + DRW_DBG("dxfRW::processEllipse"); + int code; + DRW_Ellipse ellipse; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + if (applyExt) + ellipse.applyExtrusion(); + iface->addEllipse(ellipse); + return true; //found new entity or ENDSEC, terminate + } + default: + ellipse.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processTrace() { + DRW_DBG("dxfRW::processTrace"); + int code; + DRW_Trace trace; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + if (applyExt) + trace.applyExtrusion(); + iface->addTrace(trace); + return true; //found new entity or ENDSEC, terminate + } + default: + trace.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processSolid() { + DRW_DBG("dxfRW::processSolid"); + int code; + DRW_Solid solid; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + if (applyExt) + solid.applyExtrusion(); + iface->addSolid(solid); + return true; //found new entity or ENDSEC, terminate + } + default: + solid.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::process3dface() { + DRW_DBG("dxfRW::process3dface"); + int code; + DRW_3Dface face; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + iface->add3dFace(face); + return true; //found new entity or ENDSEC, terminate + } + default: + face.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processViewport() { + DRW_DBG("dxfRW::processViewport"); + int code; + DRW_Viewport vp; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + iface->addViewport(vp); + return true; //found new entity or ENDSEC, terminate + } + default: + vp.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processPoint() { + DRW_DBG("dxfRW::processPoint\n"); + int code; + DRW_Point point; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + iface->addPoint(point); + return true; //found new entity or ENDSEC, terminate + } + default: + point.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processLine() { + DRW_DBG("dxfRW::processLine\n"); + int code; + DRW_Line line; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + iface->addLine(line); + return true; //found new entity or ENDSEC, terminate + } + default: + line.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processRay() { + DRW_DBG("dxfRW::processRay\n"); + int code; + DRW_Ray line; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + iface->addRay(line); + return true; //found new entity or ENDSEC, terminate + } + default: + line.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processXline() { + DRW_DBG("dxfRW::processXline\n"); + int code; + DRW_Xline line; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + iface->addXline(line); + return true; //found new entity or ENDSEC, terminate + } + default: + line.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processCircle() { + DRW_DBG("dxfRW::processPoint\n"); + int code; + DRW_Circle circle; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + if (applyExt) + circle.applyExtrusion(); + iface->addCircle(circle); + return true; //found new entity or ENDSEC, terminate + } + default: + circle.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processArc() { + DRW_DBG("dxfRW::processPoint\n"); + int code; + DRW_Arc arc; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + if (applyExt) + arc.applyExtrusion(); + iface->addArc(arc); + return true; //found new entity or ENDSEC, terminate + } + default: + arc.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processInsert() { + DRW_DBG("dxfRW::processInsert"); + int code; + DRW_Insert insert; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + iface->addInsert(insert); + return true; //found new entity or ENDSEC, terminate + } + default: + insert.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processLWPolyline() { + DRW_DBG("dxfRW::processLWPolyline"); + int code; + DRW_LWPolyline pl; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + if (applyExt) + pl.applyExtrusion(); + iface->addLWPolyline(pl); + return true; //found new entity or ENDSEC, terminate + } + default: + pl.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processPolyline() { + DRW_DBG("dxfRW::processPolyline"); + int code; + DRW_Polyline pl; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + if (nextentity != "VERTEX") { + iface->addPolyline(pl); + return true; //found new entity or ENDSEC, terminate + } else { + processVertex(&pl); + } + } + default: + pl.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processVertex(DRW_Polyline *pl) { + DRW_DBG("dxfRW::processVertex"); + int code; + DRW_Vertex *v = new DRW_Vertex(); + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + pl->appendVertex(v); + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + if (nextentity == "SEQEND") { + return true; //found SEQEND no more vertex, terminate + } else if (nextentity == "VERTEX"){ + v = new DRW_Vertex(); //another vertex + } + } + default: + v->parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processText() { + DRW_DBG("dxfRW::processText"); + int code; + DRW_Text txt; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + iface->addText(txt); + return true; //found new entity or ENDSEC, terminate + } + default: + txt.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processMText() { + DRW_DBG("dxfRW::processMText"); + int code; + DRW_MText txt; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + txt.updateAngle(); + iface->addMText(txt); + return true; //found new entity or ENDSEC, terminate + } + default: + txt.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processHatch() { + DRW_DBG("dxfRW::processHatch"); + int code; + DRW_Hatch hatch; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + iface->addHatch(&hatch); + return true; //found new entity or ENDSEC, terminate + } + default: + hatch.parseCode(code, reader); + break; + } + } + return true; +} + + +bool dxfRW::processSpline() { + DRW_DBG("dxfRW::processSpline"); + int code; + DRW_Spline sp; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + iface->addSpline(&sp); + return true; //found new entity or ENDSEC, terminate + } + default: + sp.parseCode(code, reader); + break; + } + } + return true; +} + + +bool dxfRW::processImage() { + DRW_DBG("dxfRW::processImage"); + int code; + DRW_Image img; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + iface->addImage(&img); + return true; //found new entity or ENDSEC, terminate + } + default: + img.parseCode(code, reader); + break; + } + } + return true; +} + + +bool dxfRW::processDimension() { + DRW_DBG("dxfRW::processDimension"); + int code; + DRW_Dimension dim; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + int type = dim.type & 0x0F; + switch (type) { + case 0: { + DRW_DimLinear d(dim); + iface->addDimLinear(&d); + break; } + case 1: { + DRW_DimAligned d(dim); + iface->addDimAlign(&d); + break; } + case 2: { + DRW_DimAngular d(dim); + iface->addDimAngular(&d); + break;} + case 3: { + DRW_DimDiametric d(dim); + iface->addDimDiametric(&d); + break; } + case 4: { + DRW_DimRadial d(dim); + iface->addDimRadial(&d); + break; } + case 5: { + DRW_DimAngular3p d(dim); + iface->addDimAngular3P(&d); + break; } + case 6: { + DRW_DimOrdinate d(dim); + iface->addDimOrdinate(&d); + break; } + } + return true; //found new entity or ENDSEC, terminate + } + default: + dim.parseCode(code, reader); + break; + } + } + return true; +} + +bool dxfRW::processLeader() { + DRW_DBG("dxfRW::processLeader"); + int code; + DRW_Leader leader; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + iface->addLeader(&leader); + return true; //found new entity or ENDSEC, terminate + } + default: + leader.parseCode(code, reader); + break; + } + } + return true; +} + + +/********* Objects Section *********/ + +bool dxfRW::processObjects() { + DRW_DBG("dxfRW::processObjects\n"); + int code; + if (!reader->readRec(&code)){ + return false; + } + bool next = true; + if (code == 0) { + nextentity = reader->getString(); + } else { + return false; //first record in objects is 0 + } + do { + if (nextentity == "ENDSEC") { + return true; //found ENDSEC terminate + } else if (nextentity == "IMAGEDEF") { + processImageDef(); + } else { + if (reader->readRec(&code)){ + if (code == 0) + nextentity = reader->getString(); + } else + return false; //end of file without ENDSEC + } + + } while (next); + return true; +} + +bool dxfRW::processImageDef() { + DRW_DBG("dxfRW::processImageDef"); + int code; + DRW_ImageDef img; + while (reader->readRec(&code)) { + DRW_DBG(code); DRW_DBG("\n"); + switch (code) { + case 0: { + nextentity = reader->getString(); + DRW_DBG(nextentity); DRW_DBG("\n"); + iface->linkImage(&img); + return true; //found new entity or ENDSEC, terminate + } + default: + img.parseCode(code, reader); + break; + } + } + return true; +} + +/** utility function + * convert a int to string in hex + **/ +std::string dxfRW::toHexStr(int n){ +#if defined(__APPLE__) + char buffer[9]= {'\0'}; + snprintf(buffer,9, "%X", n); + return std::string(buffer); +#else + std::ostringstream Convert; + Convert << std::uppercase << std::hex << n; + return Convert.str(); +#endif +} diff --git a/extlib/libdxfrw/libdxfrw.h b/extlib/libdxfrw/libdxfrw.h new file mode 100644 index 0000000..b3de272 --- /dev/null +++ b/extlib/libdxfrw/libdxfrw.h @@ -0,0 +1,148 @@ +/****************************************************************************** +** libDXFrw - Library to read/write DXF files (ascii & binary) ** +** ** +** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com ** +** ** +** This library is free software, licensed under the terms of the GNU ** +** General Public License as published by the Free Software Foundation, ** +** either version 2 of the License, or (at your option) any later version. ** +** You should have received a copy of the GNU General Public License ** +** along with this program. If not, see . ** +******************************************************************************/ + +#ifndef LIBDXFRW_H +#define LIBDXFRW_H + +#include +#include "drw_entities.h" +#include "drw_objects.h" +#include "drw_header.h" +#include "drw_interface.h" + + +class dxfReader; +class dxfWriter; + +class dxfRW { +public: + dxfRW(); + ~dxfRW(); + void setDebug(DRW::DBG_LEVEL lvl); + /// reads the file specified in constructor + /*! + * An interface must be provided. It is used by the class to signal various + * components being added. + * @param interface_ the interface to use + * @param ext should the extrusion be applied to convert in 2D? + * @return true for success + */ + bool read(std::istream &stream, DRW_Interface *interface_, bool ext); + void setBinary(bool b) {binFile = b;} + + bool write(std::ostream &stream, DRW_Interface *interface_, DRW::Version ver, bool bin); + bool writeLineType(DRW_LType *ent); + bool writeLayer(DRW_Layer *ent); + bool writeDimstyle(DRW_Dimstyle *ent); + bool writeTextstyle(DRW_Textstyle *ent); + bool writeVport(DRW_Vport *ent); + bool writeAppId(DRW_AppId *ent); + bool writePoint(DRW_Point *ent); + bool writeLine(DRW_Line *ent); + bool writeRay(DRW_Ray *ent); + bool writeXline(DRW_Xline *ent); + bool writeCircle(DRW_Circle *ent); + bool writeArc(DRW_Arc *ent); + bool writeEllipse(DRW_Ellipse *ent); + bool writeTrace(DRW_Trace *ent); + bool writeSolid(DRW_Solid *ent); + bool write3dface(DRW_3Dface *ent); + bool writeLWPolyline(DRW_LWPolyline *ent); + bool writePolyline(DRW_Polyline *ent); + bool writeSpline(DRW_Spline *ent); + bool writeBlockRecord(std::string name); + bool writeBlock(DRW_Block *ent); + bool writeInsert(DRW_Insert *ent); + bool writeMText(DRW_MText *ent); + bool writeText(DRW_Text *ent); + bool writeHatch(DRW_Hatch *ent); + bool writeViewport(DRW_Viewport *ent); + DRW_ImageDef *writeImage(DRW_Image *ent, std::string name); + bool writeLeader(DRW_Leader *ent); + bool writeDimension(DRW_Dimension *ent); + void setEllipseParts(int parts){elParts = parts;} /*!< set parts munber when convert ellipse to polyline */ + +private: + /// used by read() to parse the content of the file + bool processDxf(); + bool processHeader(); + bool processTables(); + bool processBlocks(); + bool processBlock(); + bool processEntities(bool isblock); + bool processObjects(); + + bool processLType(); + bool processLayer(); + bool processDimStyle(); + bool processTextStyle(); + bool processVports(); + bool processAppId(); + + bool processPoint(); + bool processLine(); + bool processRay(); + bool processXline(); + bool processCircle(); + bool processArc(); + bool processEllipse(); + bool processTrace(); + bool processSolid(); + bool processInsert(); + bool processLWPolyline(); + bool processPolyline(); + bool processVertex(DRW_Polyline* pl); + bool processText(); + bool processMText(); + bool processHatch(); + bool processSpline(); + bool process3dface(); + bool processViewport(); + bool processImage(); + bool processImageDef(); + bool processDimension(); + bool processLeader(); + +// bool writeHeader(); + bool writeEntity(DRW_Entity *ent); + bool writeTables(); + bool writeBlocks(); + bool writeObjects(); + bool writeExtData(const std::vector &ed); + /*use version from dwgutil.h*/ + std::string toHexStr(int n);//RLZ removeme + +private: + DRW::Version version; + std::string fileName; + std::string codePage; + bool binFile; + dxfReader *reader; + dxfWriter *writer; + DRW_Interface *iface; + DRW_Header header; +// int section; + std::string nextentity; + int entCount; + bool wlayer0; + bool dimstyleStd; + bool applyExt; + bool writingBlock; + int elParts; /*!< parts munber when convert ellipse to polyline */ + std::map blockMap; + std::vector imageDef; /*!< imageDef list */ + + int currHandle; + +}; + +#endif // LIBDXFRW_H diff --git a/extlib/mimalloc/.gitattributes b/extlib/mimalloc/.gitattributes new file mode 100644 index 0000000..acdbdbf --- /dev/null +++ b/extlib/mimalloc/.gitattributes @@ -0,0 +1,10 @@ +# default behavior is to always use unix style line endings +* text eol=lf +*.png binary +*.pdn binary +*.sln binary +*.suo binary +*.vcproj binary +*.patch binary +*.dll binary +*.lib binary diff --git a/extlib/mimalloc/.gitignore b/extlib/mimalloc/.gitignore new file mode 100644 index 0000000..3639d32 --- /dev/null +++ b/extlib/mimalloc/.gitignore @@ -0,0 +1,8 @@ +ide/vs20??/*.db +ide/vs20??/*.opendb +ide/vs20??/*.user +ide/vs20??/*.vcxproj.filters +ide/vs20??/.vs +out/ +docs/ +*.zip diff --git a/extlib/mimalloc/CMakeLists.txt b/extlib/mimalloc/CMakeLists.txt new file mode 100644 index 0000000..37616eb --- /dev/null +++ b/extlib/mimalloc/CMakeLists.txt @@ -0,0 +1,361 @@ +cmake_minimum_required(VERSION 3.0) +project(libmimalloc C CXX) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) + +option(MI_SECURE "Use full security mitigations (like guard pages, allocation randomization, double-free mitigation, and free-list corruption detection)" OFF) +option(MI_DEBUG_FULL "Use full internal heap invariant checking in DEBUG mode (expensive)" OFF) +option(MI_PADDING "Enable padding to detect heap block overflow (used only in DEBUG mode)" ON) +option(MI_OVERRIDE "Override the standard malloc interface (e.g. define entry points for malloc() etc)" ON) +option(MI_XMALLOC "Enable abort() call on memory allocation failure by default" OFF) +option(MI_SHOW_ERRORS "Show error and warning messages by default (only enabled by default in DEBUG mode)" OFF) +option(MI_USE_CXX "Use the C++ compiler to compile the library (instead of the C compiler)" OFF) +option(MI_SEE_ASM "Generate assembly files" OFF) +option(MI_INTERPOSE "Use interpose to override standard malloc on macOS" ON) +option(MI_OSX_ZONE "Use malloc zone to override standard malloc on macOS" OFF) # enables interpose as well +option(MI_LOCAL_DYNAMIC_TLS "Use slightly slower, dlopen-compatible TLS mechanism (Unix)" OFF) +option(MI_BUILD_SHARED "Build shared library" ON) +option(MI_BUILD_STATIC "Build static library" ON) +option(MI_BUILD_OBJECT "Build object library" ON) +option(MI_BUILD_TESTS "Build test executables" ON) +option(MI_DEBUG_TSAN "Build with thread sanitizer (needs clang)" OFF) +option(MI_DEBUG_UBSAN "Build with undefined-behavior sanitizer (needs clang++)" OFF) +option(MI_CHECK_FULL "Use full internal invariant checking in DEBUG mode (deprecated, use MI_DEBUG_FULL instead)" OFF) + +include("cmake/mimalloc-config-version.cmake") + +set(mi_sources + src/stats.c + src/random.c + src/os.c + src/arena.c + src/region.c + src/segment.c + src/page.c + src/alloc.c + src/alloc-aligned.c + src/alloc-posix.c + src/heap.c + src/options.c + src/init.c) + +# ----------------------------------------------------------------------------- +# Converience: set default build type depending on the build directory +# ----------------------------------------------------------------------------- + +if (NOT CMAKE_BUILD_TYPE) + if ("${CMAKE_BINARY_DIR}" MATCHES ".*(D|d)ebug$" OR MI_DEBUG_FULL MATCHES "ON") + message(STATUS "No build type selected, default to: Debug") + set(CMAKE_BUILD_TYPE "Debug") + else() + message(STATUS "No build type selected, default to: Release") + set(CMAKE_BUILD_TYPE "Release") + endif() +endif() + +if("${CMAKE_BINARY_DIR}" MATCHES ".*(S|s)ecure$") + message(STATUS "Default to secure build") + set(MI_SECURE "ON") +endif() + +# ----------------------------------------------------------------------------- +# Process options +# ----------------------------------------------------------------------------- + +if(CMAKE_C_COMPILER_ID MATCHES "MSVC|Intel") + set(MI_USE_CXX "ON") +endif() + +if(MI_OVERRIDE MATCHES "ON") + message(STATUS "Override standard malloc (MI_OVERRIDE=ON)") + if(APPLE) + if(MI_OSX_ZONE MATCHES "ON") + # use zone's on macOS + message(STATUS " Use malloc zone to override malloc (MI_OSX_ZONE=ON)") + list(APPEND mi_sources src/alloc-override-osx.c) + list(APPEND mi_defines MI_OSX_ZONE=1) + if(NOT MI_INTERPOSE MATCHES "ON") + message(STATUS " (enabling INTERPOSE as well since zone's require this)") + set(MI_INTERPOSE "ON") + endif() + endif() + if(MI_INTERPOSE MATCHES "ON") + # use interpose on macOS + message(STATUS " Use interpose to override malloc (MI_INTERPOSE=ON)") + list(APPEND mi_defines MI_INTERPOSE) + endif() + endif() +endif() + +if(MI_SECURE MATCHES "ON") + message(STATUS "Set full secure build (MI_SECURE=ON)") + list(APPEND mi_defines MI_SECURE=4) +endif() + +if(MI_SEE_ASM MATCHES "ON") + message(STATUS "Generate assembly listings (MI_SEE_ASM=ON)") + list(APPEND mi_cflags -save-temps) +endif() + +if(MI_CHECK_FULL MATCHES "ON") + message(STATUS "The MI_CHECK_FULL option is deprecated, use MI_DEBUG_FULL instead") + set(MI_DEBUG_FULL "ON") +endif() + +if(MI_DEBUG_FULL MATCHES "ON") + message(STATUS "Set debug level to full internal invariant checking (MI_DEBUG_FULL=ON)") + list(APPEND mi_defines MI_DEBUG=3) # full invariant checking +endif() + +if(MI_PADDING MATCHES "OFF") + message(STATUS "Disable padding of heap blocks in debug mode (MI_PADDING=OFF)") + list(APPEND mi_defines MI_PADDING=0) +endif() + +if(MI_XMALLOC MATCHES "ON") + message(STATUS "Enable abort() calls on memory allocation failure (MI_XMALLOC=ON)") + list(APPEND mi_defines MI_XMALLOC=1) +endif() + +if(MI_SHOW_ERRORS MATCHES "ON") + message(STATUS "Enable printing of error and warning messages by default (MI_SHOW_ERRORS=ON)") + list(APPEND mi_defines MI_SHOW_ERRORS=1) +endif() + +if(MI_DEBUG_TSAN MATCHES "ON") + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + message(STATUS "Build with thread sanitizer (MI_DEBUG_TSAN=ON)") + list(APPEND mi_cflags -fsanitize=thread -g -O1) + list(APPEND CMAKE_EXE_LINKER_FLAGS -fsanitize=thread) + else() + message(WARNING "Can only use thread sanitizer with clang (MI_DEBUG_TSAN=ON but ignored)") + endif() +endif() + +if(MI_DEBUG_UBSAN MATCHES "ON") + if(CMAKE_BUILD_TYPE MATCHES "Debug") + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + message(STATUS "Build with undefined-behavior sanitizer (MI_DEBUG_UBSAN=ON)") + list(APPEND mi_cflags -fsanitize=undefined -g) + list(APPEND CMAKE_EXE_LINKER_FLAGS -fsanitize=undefined) + if (MI_USE_CXX MATCHES "OFF") + message(STATUS "(switch to use C++ due to MI_DEBUG_UBSAN)") + set(MI_USE_CXX "ON") + endif() + else() + message(WARNING "Can only use undefined-behavior sanitizer with clang++ (MI_DEBUG_UBSAN=ON but ignored)") + endif() + else() + message(WARNING "Can only use thread sanitizer with a debug build (CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE})") + endif() +endif() + +if(MI_USE_CXX MATCHES "ON") + message(STATUS "Use the C++ compiler to compile (MI_USE_CXX=ON)") + set_source_files_properties(${mi_sources} PROPERTIES LANGUAGE CXX ) + set_source_files_properties(src/static.c test/test-api.c test/test-stress PROPERTIES LANGUAGE CXX ) + if(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang|Clang") + list(APPEND mi_cflags -Wno-deprecated) + endif() + if(CMAKE_CXX_COMPILER_ID MATCHES "Intel") + list(APPEND mi_cflags -Kc++) + endif() +endif() + +# Compiler flags +if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU") + list(APPEND mi_cflags -Wall -Wextra -Wno-unknown-pragmas -fvisibility=hidden) + if(CMAKE_C_COMPILER_ID MATCHES "GNU") + list(APPEND mi_cflags -Wno-invalid-memory-model) + endif() +endif() + +if(CMAKE_C_COMPILER_ID MATCHES "Intel") + list(APPEND mi_cflags -Wall -fvisibility=hidden) +endif() + +if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU|Intel" AND NOT CMAKE_SYSTEM_NAME MATCHES "Haiku") + if(MI_LOCAL_DYNAMIC_TLS MATCHES "ON") + list(APPEND mi_cflags -ftls-model=local-dynamic) + else() + list(APPEND mi_cflags -ftls-model=initial-exec) + endif() +endif() + +# Architecture flags +if(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "arm") + list(APPEND mi_cflags -march=native) +endif() + +# extra needed libraries +if(WIN32) + list(APPEND mi_libraries psapi shell32 user32 bcrypt) +else() + if(NOT ${CMAKE_C_COMPILER} MATCHES "android") + list(APPEND mi_libraries pthread) + find_library(LIBRT rt) + if(LIBRT) + list(APPEND mi_libraries ${LIBRT}) + endif() + endif() +endif() + +# ----------------------------------------------------------------------------- +# Install and output names +# ----------------------------------------------------------------------------- + +set(mi_install_dir "${CMAKE_INSTALL_PREFIX}/lib/mimalloc-${mi_version}") +if(MI_SECURE MATCHES "ON") + set(mi_basename "mimalloc-secure") +else() + set(mi_basename "mimalloc") +endif() +string(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LC) +if(NOT(CMAKE_BUILD_TYPE_LC MATCHES "^(release|relwithdebinfo|minsizerel)$")) + set(mi_basename "${mi_basename}-${CMAKE_BUILD_TYPE_LC}") #append build type (e.g. -debug) if not a release version +endif() +if(MI_BUILD_SHARED) + list(APPEND mi_build_targets "shared") +endif() +if(MI_BUILD_STATIC) + list(APPEND mi_build_targets "static") +endif() +if(MI_BUILD_OBJECT) + list(APPEND mi_build_targets "object") +endif() +if(MI_BUILD_TESTS) + list(APPEND mi_build_targets "tests") +endif() +message(STATUS "") +message(STATUS "Library base name: ${mi_basename}") +message(STATUS "Build type : ${CMAKE_BUILD_TYPE_LC}") +message(STATUS "Install directory: ${mi_install_dir}") +message(STATUS "Build targets : ${mi_build_targets}") +message(STATUS "") + +# ----------------------------------------------------------------------------- +# Main targets +# ----------------------------------------------------------------------------- + +# shared library +if(MI_BUILD_SHARED) + add_library(mimalloc SHARED ${mi_sources}) + set_target_properties(mimalloc PROPERTIES VERSION ${mi_version} OUTPUT_NAME ${mi_basename} ) + target_compile_definitions(mimalloc PRIVATE ${mi_defines} MI_SHARED_LIB MI_SHARED_LIB_EXPORT) + target_compile_options(mimalloc PRIVATE ${mi_cflags}) + target_link_libraries(mimalloc PUBLIC ${mi_libraries}) + target_include_directories(mimalloc PUBLIC + $ + $ + ) + if(WIN32) + # On windows copy the mimalloc redirection dll too. + target_link_libraries(mimalloc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/bin/mimalloc-redirect.lib) + add_custom_command(TARGET mimalloc POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/bin/mimalloc-redirect.dll" $ + COMMENT "Copy mimalloc-redirect.dll to output directory") + endif() + + install(TARGETS mimalloc EXPORT mimalloc DESTINATION ${mi_install_dir} LIBRARY) + install(EXPORT mimalloc DESTINATION ${mi_install_dir}/cmake) +endif() + +# static library +if (MI_BUILD_STATIC) + add_library(mimalloc-static STATIC ${mi_sources}) + set_property(TARGET mimalloc-static PROPERTY POSITION_INDEPENDENT_CODE ON) + target_compile_definitions(mimalloc-static PRIVATE ${mi_defines} MI_STATIC_LIB) + target_compile_options(mimalloc-static PRIVATE ${mi_cflags}) + target_link_libraries(mimalloc-static PUBLIC ${mi_libraries}) + target_include_directories(mimalloc-static PUBLIC + $ + $ + ) + if(WIN32) + # When building both static and shared libraries on Windows, a static library should use a + # different output name to avoid the conflict with the import library of a shared one. + string(REPLACE "mimalloc" "mimalloc-static" mi_output_name ${mi_basename}) + set_target_properties(mimalloc-static PROPERTIES OUTPUT_NAME ${mi_output_name}) + else() + set_target_properties(mimalloc-static PROPERTIES OUTPUT_NAME ${mi_basename}) + endif() + + install(TARGETS mimalloc-static EXPORT mimalloc DESTINATION ${mi_install_dir}) +endif() + +# install include files +install(FILES include/mimalloc.h DESTINATION ${mi_install_dir}/include) +install(FILES include/mimalloc-override.h DESTINATION ${mi_install_dir}/include) +install(FILES include/mimalloc-new-delete.h DESTINATION ${mi_install_dir}/include) +install(FILES cmake/mimalloc-config.cmake DESTINATION ${mi_install_dir}/cmake) +install(FILES cmake/mimalloc-config-version.cmake DESTINATION ${mi_install_dir}/cmake) + +if(NOT WIN32 AND MI_BUILD_SHARED) + # install a symlink in the /usr/local/lib to the versioned library + set(mi_symlink "${CMAKE_SHARED_MODULE_PREFIX}${mi_basename}${CMAKE_SHARED_LIBRARY_SUFFIX}") + set(mi_soname "mimalloc-${mi_version}/${mi_symlink}.${mi_version}") + install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${mi_soname} ${mi_symlink} WORKING_DIRECTORY ${mi_install_dir}/..)") + install(CODE "MESSAGE(\"-- Symbolic link: ${CMAKE_INSTALL_PREFIX}/lib/${mi_symlink} -> ${mi_soname}\")") +endif() + +# single object file for more predictable static overriding +if (MI_BUILD_OBJECT) + add_library(mimalloc-obj OBJECT src/static.c) + set_property(TARGET mimalloc-obj PROPERTY POSITION_INDEPENDENT_CODE ON) + target_compile_definitions(mimalloc-obj PRIVATE ${mi_defines}) + target_compile_options(mimalloc-obj PRIVATE ${mi_cflags}) + target_include_directories(mimalloc-obj PUBLIC + $ + $ + ) + + # the following seems to lead to cmake warnings/errors on some systems, disable for now :-( + # install(TARGETS mimalloc-obj EXPORT mimalloc DESTINATION ${mi_install_dir}) + + # the FILES expression can also be: $ + # but that fails cmake versions less than 3.10 so we leave it as is for now + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/mimalloc-obj.dir/src/static.c${CMAKE_C_OUTPUT_EXTENSION} + DESTINATION ${mi_install_dir} + RENAME ${mi_basename}${CMAKE_C_OUTPUT_EXTENSION} ) +endif() + +# ----------------------------------------------------------------------------- +# API surface testing +# ----------------------------------------------------------------------------- + +if (MI_BUILD_TESTS MATCHES "ON") + add_executable(mimalloc-test-api test/test-api.c) + target_compile_definitions(mimalloc-test-api PRIVATE ${mi_defines}) + target_compile_options(mimalloc-test-api PRIVATE ${mi_cflags}) + target_include_directories(mimalloc-test-api PRIVATE include) + target_link_libraries(mimalloc-test-api PRIVATE mimalloc-static ${mi_libraries}) + + add_executable(mimalloc-test-stress test/test-stress.c) + target_compile_definitions(mimalloc-test-stress PRIVATE ${mi_defines}) + target_compile_options(mimalloc-test-stress PRIVATE ${mi_cflags}) + target_include_directories(mimalloc-test-stress PRIVATE include) + target_link_libraries(mimalloc-test-stress PRIVATE mimalloc ${mi_libraries}) + + enable_testing() + add_test(test_api, mimalloc-test-api) + add_test(test_stress, mimalloc-test-stress) +endif() + +# ----------------------------------------------------------------------------- +# Set override properties +# ----------------------------------------------------------------------------- +if (MI_OVERRIDE MATCHES "ON") + if (MI_BUILD_SHARED) + target_compile_definitions(mimalloc PRIVATE MI_MALLOC_OVERRIDE) + endif() + if(NOT WIN32) + # It is only possible to override malloc on Windows when building as a DLL. + if (MI_BUILD_STATIC) + target_compile_definitions(mimalloc-static PRIVATE MI_MALLOC_OVERRIDE) + endif() + if (MI_BUILD_OBJECT) + target_compile_definitions(mimalloc-obj PRIVATE MI_MALLOC_OVERRIDE) + endif() + endif() +endif() diff --git a/extlib/mimalloc/LICENSE b/extlib/mimalloc/LICENSE new file mode 100644 index 0000000..4151dbe --- /dev/null +++ b/extlib/mimalloc/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Microsoft Corporation, Daan Leijen + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/extlib/mimalloc/azure-pipelines.yml b/extlib/mimalloc/azure-pipelines.yml new file mode 100644 index 0000000..c81e31b --- /dev/null +++ b/extlib/mimalloc/azure-pipelines.yml @@ -0,0 +1,131 @@ +# Starter pipeline +# Start with a minimal pipeline that you can customize to build and deploy your code. +# Add steps that build, run tests, deploy, and more: +# https://aka.ms/yaml + +trigger: +- master +- dev + +jobs: +- job: + displayName: Windows + pool: + vmImage: + windows-2019 + strategy: + matrix: + Debug: + BuildType: debug + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON + MSBuildConfiguration: Debug + Release: + BuildType: release + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release + MSBuildConfiguration: Release + Secure: + BuildType: secure + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release -DMI_SECURE=ON + MSBuildConfiguration: Release + steps: + - task: CMake@1 + inputs: + workingDirectory: $(BuildType) + cmakeArgs: .. $(cmakeExtraArgs) + - task: MSBuild@1 + inputs: + solution: $(BuildType)/libmimalloc.sln + configuration: '$(MSBuildConfiguration)' + - script: | + cd $(BuildType) + ctest + displayName: CTest +# - upload: $(Build.SourcesDirectory)/$(BuildType) +# artifact: mimalloc-windows-$(BuildType) + +- job: + displayName: Linux + pool: + vmImage: + ubuntu-16.04 + strategy: + matrix: + Debug: + CC: gcc + CXX: g++ + BuildType: debug + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON + Release: + CC: gcc + CXX: g++ + BuildType: release + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release + Secure: + CC: gcc + CXX: g++ + BuildType: secure + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release -DMI_SECURE=ON + Debug++: + CC: gcc + CXX: g++ + BuildType: debug-cxx + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON -DMI_USE_CXX=ON + Debug Clang: + CC: clang + CXX: clang++ + BuildType: debug-clang + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON + Release Clang: + CC: clang + CXX: clang++ + BuildType: release-clang + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release + Secure Clang: + CC: clang + CXX: clang++ + BuildType: secure-clang + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release -DMI_SECURE=ON + Debug++ Clang: + CC: clang + CXX: clang++ + BuildType: debug-clang-cxx + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON -DMI_USE_CXX=ON + steps: + - task: CMake@1 + inputs: + workingDirectory: $(BuildType) + cmakeArgs: .. $(cmakeExtraArgs) + - script: make -j$(nproc) -C $(BuildType) + displayName: Make + - script: make test -C $(BuildType) + displayName: CTest +# - upload: $(Build.SourcesDirectory)/$(BuildType) +# artifact: mimalloc-ubuntu-$(BuildType) + +- job: + displayName: macOS + pool: + vmImage: + macOS-10.14 + strategy: + matrix: + Debug: + BuildType: debug + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_DEBUG_FULL=ON + Release: + BuildType: release + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release + Secure: + BuildType: secure + cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release -DMI_SECURE=ON + steps: + - task: CMake@1 + inputs: + workingDirectory: $(BuildType) + cmakeArgs: .. $(cmakeExtraArgs) + - script: make -j$(sysctl -n hw.ncpu) -C $(BuildType) + displayName: Make + - script: make test -C $(BuildType) + displayName: CTest +# - upload: $(Build.SourcesDirectory)/$(BuildType) +# artifact: mimalloc-macos-$(BuildType) diff --git a/extlib/mimalloc/cmake/mimalloc-config-version.cmake b/extlib/mimalloc/cmake/mimalloc-config-version.cmake new file mode 100644 index 0000000..6454d91 --- /dev/null +++ b/extlib/mimalloc/cmake/mimalloc-config-version.cmake @@ -0,0 +1,16 @@ +set(mi_version_major 1) +set(mi_version_minor 6) +set(mi_version ${mi_version_major}.${mi_version_minor}) + +set(PACKAGE_VERSION ${mi_version}) +if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL "${mi_version_major}") + if ("${PACKAGE_FIND_VERSION_MINOR}" EQUAL "${mi_version_minor}") + set(PACKAGE_VERSION_EXACT TRUE) + elseif("${PACKAGE_FIND_VERSION_MINOR}" LESS "${mi_version_minor}") + set(PACKAGE_VERSION_COMPATIBLE TRUE) + else() + set(PACKAGE_VERSION_UNSUITABLE TRUE) + endif() +else() + set(PACKAGE_VERSION_UNSUITABLE TRUE) +endif() diff --git a/extlib/mimalloc/cmake/mimalloc-config.cmake b/extlib/mimalloc/cmake/mimalloc-config.cmake new file mode 100644 index 0000000..12da076 --- /dev/null +++ b/extlib/mimalloc/cmake/mimalloc-config.cmake @@ -0,0 +1,2 @@ +include(${CMAKE_CURRENT_LIST_DIR}/mimalloc.cmake) +get_filename_component(MIMALLOC_TARGET_DIR "${CMAKE_CURRENT_LIST_DIR}" PATH) diff --git a/extlib/mimalloc/ide/vs2017/mimalloc-override-test.vcxproj b/extlib/mimalloc/ide/vs2017/mimalloc-override-test.vcxproj new file mode 100644 index 0000000..faaa00e --- /dev/null +++ b/extlib/mimalloc/ide/vs2017/mimalloc-override-test.vcxproj @@ -0,0 +1,190 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {FEF7868F-750E-4C21-A04D-22707CC66879} + mimalloc-override-test + 10.0.17134.0 + mimalloc-override-test + + + + Application + true + v141 + + + Application + false + v141 + true + + + Application + true + v141 + + + Application + false + v141 + true + + + + + + + + + + + + + + + + + + + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + + Level3 + Disabled + true + true + ..\..\include + MultiThreadedDebugDLL + false + Default + false + + + Console + kernel32.lib;%(AdditionalDependencies) + + + + + + + + + + Level3 + Disabled + true + true + ..\..\include + MultiThreadedDebugDLL + Sync + Default + false + + + Console + + + kernel32.lib;%(AdditionalDependencies) + + + + + + + + + + Level3 + MaxSpeed + true + true + true + true + ..\..\include + _MBCS;%(PreprocessorDefinitions);NDEBUG + MultiThreadedDLL + + + true + true + Console + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + + + Level3 + MaxSpeed + true + true + true + true + ..\..\include + _MBCS;%(PreprocessorDefinitions);NDEBUG + MultiThreadedDLL + + + true + true + Console + + + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + + + {abb5eae7-b3e6-432e-b636-333449892ea7} + + + + + + + + + \ No newline at end of file diff --git a/extlib/mimalloc/ide/vs2017/mimalloc-override-test.vcxproj.filters b/extlib/mimalloc/ide/vs2017/mimalloc-override-test.vcxproj.filters new file mode 100644 index 0000000..eb5e70b --- /dev/null +++ b/extlib/mimalloc/ide/vs2017/mimalloc-override-test.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/extlib/mimalloc/ide/vs2017/mimalloc-override.vcxproj b/extlib/mimalloc/ide/vs2017/mimalloc-override.vcxproj new file mode 100644 index 0000000..990d6ca --- /dev/null +++ b/extlib/mimalloc/ide/vs2017/mimalloc-override.vcxproj @@ -0,0 +1,254 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {ABB5EAE7-B3E6-432E-B636-333449892EA7} + mimalloc-override + 10.0.17134.0 + mimalloc-override + + + + DynamicLibrary + true + v141 + + + DynamicLibrary + false + v141 + + + DynamicLibrary + true + v141 + + + DynamicLibrary + false + v141 + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .dll + mimalloc-override + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .dll + mimalloc-override + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .dll + mimalloc-override + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .dll + mimalloc-override + + + + Level3 + Disabled + true + true + ../../include + _CRT_SECURE_NO_WARNINGS;MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions); + MultiThreadedDebugDLL + false + Default + + + $(ProjectDir)\..\..\bin\mimalloc-redirect32.lib;%(AdditionalDependencies) + + + + + Default + false + + + COPY /Y $(ProjectDir)..\..\bin\mimalloc-redirect32.dll $(OutputPath) + + + Copy mimalloc-redirect32.dll to the output directory + + + + + Level3 + Disabled + true + true + ../../include + _CRT_SECURE_NO_WARNINGS;MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions); + MultiThreadedDebugDLL + false + Default + + + $(ProjectDir)\..\..\bin\mimalloc-redirect.lib;bcrypt.lib;%(AdditionalDependencies) + + + + + Default + false + + + COPY /Y $(ProjectDir)..\..\bin\mimalloc-redirect.dll $(OutputPath) + + + copy mimalloc-redirect.dll to the output directory + + + + + Level3 + MaxSpeed + true + true + true + ../../include + _CRT_SECURE_NO_WARNINGS;MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);NDEBUG + AssemblyAndSourceCode + $(IntDir) + false + MultiThreadedDLL + Default + false + + + true + true + $(ProjectDir)\..\..\bin\mimalloc-redirect32.lib;%(AdditionalDependencies) + + + Default + false + + + COPY /Y $(ProjectDir)..\..\bin\mimalloc-redirect32.dll $(OutputPath) + + + Copy mimalloc-redirect32.dll to the output directory + + + + + Level3 + MaxSpeed + true + true + true + ../../include + _CRT_SECURE_NO_WARNINGS;MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);NDEBUG + AssemblyAndSourceCode + $(IntDir) + false + MultiThreadedDLL + Default + false + + + true + true + $(ProjectDir)\..\..\bin\mimalloc-redirect.lib;bcrypt.lib;%(AdditionalDependencies) + + + Default + false + + + COPY /Y $(ProjectDir)..\..\bin\mimalloc-redirect.dll $(OutputPath) + + + copy mimalloc-redirect.dll to the output directory + + + + + + + + + + + + + false + false + false + false + + + true + true + true + true + + + + + + + + + + + true + true + true + true + + + + + + + + + + diff --git a/extlib/mimalloc/ide/vs2017/mimalloc-override.vcxproj.filters b/extlib/mimalloc/ide/vs2017/mimalloc-override.vcxproj.filters new file mode 100644 index 0000000..0265265 --- /dev/null +++ b/extlib/mimalloc/ide/vs2017/mimalloc-override.vcxproj.filters @@ -0,0 +1,80 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + diff --git a/extlib/mimalloc/ide/vs2017/mimalloc-test-stress.vcxproj b/extlib/mimalloc/ide/vs2017/mimalloc-test-stress.vcxproj new file mode 100644 index 0000000..b8267d0 --- /dev/null +++ b/extlib/mimalloc/ide/vs2017/mimalloc-test-stress.vcxproj @@ -0,0 +1,159 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {FEF7958F-750E-4C21-A04D-22707CC66878} + mimalloc-test-stress + 10.0.17134.0 + mimalloc-test-stress + + + + Application + true + v141 + + + Application + false + v141 + true + + + Application + true + v141 + + + Application + false + v141 + true + + + + + + + + + + + + + + + + + + + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + + Level3 + Disabled + true + true + ..\..\include + + + Console + + + + + Level3 + Disabled + true + true + ..\..\include + + + Console + + + + + Level3 + MaxSpeed + true + true + true + true + ..\..\include + %(PreprocessorDefinitions);NDEBUG + + + true + true + Console + + + + + Level3 + MaxSpeed + true + true + true + true + ..\..\include + %(PreprocessorDefinitions);NDEBUG + + + true + true + Console + + + + + false + false + false + false + + + + + {abb5eae7-b3e6-432e-b636-333449892ea6} + + + + + + \ No newline at end of file diff --git a/extlib/mimalloc/ide/vs2017/mimalloc-test-stress.vcxproj.filters b/extlib/mimalloc/ide/vs2017/mimalloc-test-stress.vcxproj.filters new file mode 100644 index 0000000..7c5239e --- /dev/null +++ b/extlib/mimalloc/ide/vs2017/mimalloc-test-stress.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/extlib/mimalloc/ide/vs2017/mimalloc-test.vcxproj b/extlib/mimalloc/ide/vs2017/mimalloc-test.vcxproj new file mode 100644 index 0000000..27c7bb6 --- /dev/null +++ b/extlib/mimalloc/ide/vs2017/mimalloc-test.vcxproj @@ -0,0 +1,158 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {FEF7858F-750E-4C21-A04D-22707CC66878} + mimalloctest + 10.0.17134.0 + mimalloc-test + + + + Application + true + v141 + + + Application + false + v141 + true + + + Application + true + v141 + + + Application + false + v141 + true + + + + + + + + + + + + + + + + + + + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + + Level3 + Disabled + true + true + ..\..\include + stdcpp17 + + + Console + + + + + Level3 + Disabled + true + true + ..\..\include + stdcpp17 + + + Console + + + + + Level3 + MaxSpeed + true + true + true + true + ..\..\include + _MBCS;%(PreprocessorDefinitions);NDEBUG + stdcpp17 + + + true + true + Console + + + + + Level3 + MaxSpeed + true + true + true + true + ..\..\include + _MBCS;%(PreprocessorDefinitions);NDEBUG + stdcpp17 + + + true + true + Console + + + + + {abb5eae7-b3e6-432e-b636-333449892ea6} + + + + + + + + + \ No newline at end of file diff --git a/extlib/mimalloc/ide/vs2017/mimalloc-test.vcxproj.filters b/extlib/mimalloc/ide/vs2017/mimalloc-test.vcxproj.filters new file mode 100644 index 0000000..fca75e1 --- /dev/null +++ b/extlib/mimalloc/ide/vs2017/mimalloc-test.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/extlib/mimalloc/ide/vs2017/mimalloc.sln b/extlib/mimalloc/ide/vs2017/mimalloc.sln new file mode 100644 index 0000000..aeab6b8 --- /dev/null +++ b/extlib/mimalloc/ide/vs2017/mimalloc.sln @@ -0,0 +1,71 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2016 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc", "mimalloc.vcxproj", "{ABB5EAE7-B3E6-432E-B636-333449892EA6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test", "mimalloc-test.vcxproj", "{FEF7858F-750E-4C21-A04D-22707CC66878}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-override", "mimalloc-override.vcxproj", "{ABB5EAE7-B3E6-432E-B636-333449892EA7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-override-test", "mimalloc-override-test.vcxproj", "{FEF7868F-750E-4C21-A04D-22707CC66879}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test-stress", "mimalloc-test-stress.vcxproj", "{FEF7958F-750E-4C21-A04D-22707CC66878}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x64.ActiveCfg = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x64.Build.0 = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x86.ActiveCfg = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x86.Build.0 = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x64.ActiveCfg = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x64.Build.0 = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x86.ActiveCfg = Release|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x86.Build.0 = Release|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x64.ActiveCfg = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x64.Build.0 = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x86.ActiveCfg = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x86.Build.0 = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x64.ActiveCfg = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x64.Build.0 = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x86.ActiveCfg = Release|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x86.Build.0 = Release|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x64.ActiveCfg = Debug|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x64.Build.0 = Debug|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x86.ActiveCfg = Debug|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x86.Build.0 = Debug|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.ActiveCfg = Release|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.Build.0 = Release|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.ActiveCfg = Release|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.Build.0 = Release|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4297F93D-486A-4243-995F-7D32F59AE82A} + EndGlobalSection +EndGlobal diff --git a/extlib/mimalloc/ide/vs2017/mimalloc.vcxproj b/extlib/mimalloc/ide/vs2017/mimalloc.vcxproj new file mode 100644 index 0000000..770a87b --- /dev/null +++ b/extlib/mimalloc/ide/vs2017/mimalloc.vcxproj @@ -0,0 +1,260 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {ABB5EAE7-B3E6-432E-B636-333449892EA6} + mimalloc + 10.0.17134.0 + mimalloc + + + + StaticLibrary + true + v141 + + + StaticLibrary + false + v141 + true + + + StaticLibrary + true + v141 + + + StaticLibrary + false + v141 + true + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .lib + mimalloc-static + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .lib + mimalloc-static + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .lib + mimalloc-static + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .lib + mimalloc-static + + + false + + + false + + + false + + + false + + + + Level3 + Disabled + true + true + ../../include + _CRT_SECURE_NO_WARNINGS;MI_DEBUG=3;%(PreprocessorDefinitions); + CompileAsCpp + false + stdcpp17 + + + + + + + + + + + Level4 + Disabled + true + true + ../../include + _CRT_SECURE_NO_WARNINGS;MI_DEBUG=3;%(PreprocessorDefinitions); + CompileAsCpp + false + stdcpp17 + + + + + + + + + + + + + + + + + + + Level3 + MaxSpeed + true + true + ../../include + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);NDEBUG + AssemblyAndSourceCode + $(IntDir) + false + false + Default + CompileAsCpp + true + + + true + true + + + + + + + + + + + Level4 + MaxSpeed + true + true + ../../include + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);NDEBUG + AssemblyAndSourceCode + $(IntDir) + false + false + Default + CompileAsCpp + true + + + true + true + + + + + + + + + + + + + + + + + false + false + false + false + + + true + true + true + true + + + true + true + true + true + + + + + + + + + + true + true + true + true + + + + + + + + + + + + + + + + + + + diff --git a/extlib/mimalloc/ide/vs2017/mimalloc.vcxproj.filters b/extlib/mimalloc/ide/vs2017/mimalloc.vcxproj.filters new file mode 100644 index 0000000..4366051 --- /dev/null +++ b/extlib/mimalloc/ide/vs2017/mimalloc.vcxproj.filters @@ -0,0 +1,83 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + diff --git a/extlib/mimalloc/ide/vs2019/mimalloc-override-test.vcxproj b/extlib/mimalloc/ide/vs2019/mimalloc-override-test.vcxproj new file mode 100644 index 0000000..7a9202f --- /dev/null +++ b/extlib/mimalloc/ide/vs2019/mimalloc-override-test.vcxproj @@ -0,0 +1,190 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {FEF7868F-750E-4C21-A04D-22707CC66879} + mimalloc-override-test + 10.0 + mimalloc-override-test + + + + Application + true + v142 + + + Application + false + v142 + true + + + Application + true + v142 + + + Application + false + v142 + true + + + + + + + + + + + + + + + + + + + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + + Level3 + Disabled + true + true + ..\..\include + MultiThreadedDebugDLL + Sync + Default + false + + + Console + kernel32.lib;%(AdditionalDependencies) + + + + + + + + + + Level3 + Disabled + true + true + ..\..\include + MultiThreadedDebugDLL + Sync + Default + false + + + Console + + + kernel32.lib;%(AdditionalDependencies) + + + + + + + + + + Level3 + MaxSpeed + true + true + true + true + ..\..\include + _MBCS;%(PreprocessorDefinitions);NDEBUG + MultiThreadedDLL + + + true + true + Console + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + + + Level3 + MaxSpeed + true + true + true + true + ..\..\include + _MBCS;%(PreprocessorDefinitions);NDEBUG + MultiThreadedDLL + + + true + true + Console + + + kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies) + + + + + + + + + + + + {abb5eae7-b3e6-432e-b636-333449892ea7} + + + + + + \ No newline at end of file diff --git a/extlib/mimalloc/ide/vs2019/mimalloc-override.vcxproj b/extlib/mimalloc/ide/vs2019/mimalloc-override.vcxproj new file mode 100644 index 0000000..a0e79fb --- /dev/null +++ b/extlib/mimalloc/ide/vs2019/mimalloc-override.vcxproj @@ -0,0 +1,257 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {ABB5EAE7-B3E6-432E-B636-333449892EA7} + mimalloc-override + 10.0 + mimalloc-override + + + + DynamicLibrary + true + v142 + + + DynamicLibrary + false + v142 + + + DynamicLibrary + true + v142 + + + DynamicLibrary + false + v142 + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .dll + mimalloc-override + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .dll + mimalloc-override + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .dll + mimalloc-override + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .dll + mimalloc-override + + + + Level3 + Disabled + true + true + ../../include + MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions); + MultiThreadedDebugDLL + false + Default + + + $(ProjectDir)\..\..\bin\mimalloc-redirect32.lib;%(AdditionalDependencies) + + + + + Default + false + + + COPY /Y $(ProjectDir)..\..\bin\mimalloc-redirect32.dll $(OutputPath) + + + Copy mimalloc-redirect32.dll to the output directory + + + + + Level3 + Disabled + true + true + ../../include + MI_DEBUG=3;MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions); + MultiThreadedDebugDLL + false + Default + + + $(ProjectDir)\..\..\bin\mimalloc-redirect.lib;%(AdditionalDependencies) + + + + + Default + false + + + COPY /Y $(ProjectDir)..\..\bin\mimalloc-redirect.dll $(OutputPath) + + + copy mimalloc-redirect.dll to the output directory + + + + + Level3 + MaxSpeed + true + true + true + ../../include + MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);NDEBUG + AssemblyAndSourceCode + $(IntDir) + false + MultiThreadedDLL + Default + false + + + true + true + $(ProjectDir)\..\..\bin\mimalloc-redirect32.lib;%(AdditionalDependencies) + + + Default + false + + + COPY /Y $(ProjectDir)..\..\bin\mimalloc-redirect32.dll $(OutputPath) + + + Copy mimalloc-redirect32.dll to the output directory + + + + + Level3 + MaxSpeed + true + true + true + ../../include + MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);NDEBUG + AssemblyAndSourceCode + $(IntDir) + false + MultiThreadedDLL + Default + false + + + true + true + $(ProjectDir)\..\..\bin\mimalloc-redirect.lib;%(AdditionalDependencies) + + + Default + false + + + COPY /Y $(ProjectDir)..\..\bin\mimalloc-redirect.dll $(OutputPath) + + + copy mimalloc-redirect.dll to the output directory + + + + + + + + + + + + + false + false + false + false + + + true + true + true + true + + + + + + true + + + + + + + + true + true + true + true + + + + + + + + + + \ No newline at end of file diff --git a/extlib/mimalloc/ide/vs2019/mimalloc-override.vcxproj.filters b/extlib/mimalloc/ide/vs2019/mimalloc-override.vcxproj.filters new file mode 100644 index 0000000..8e36f50 --- /dev/null +++ b/extlib/mimalloc/ide/vs2019/mimalloc-override.vcxproj.filters @@ -0,0 +1,81 @@ + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + {f1fccf27-17b9-42dd-ba51-6070baff85c6} + + + {39cb7e38-69d0-43fb-8406-6a0f7cefc3b4} + + + \ No newline at end of file diff --git a/extlib/mimalloc/ide/vs2019/mimalloc-test-api.vcxproj b/extlib/mimalloc/ide/vs2019/mimalloc-test-api.vcxproj new file mode 100644 index 0000000..812a9cb --- /dev/null +++ b/extlib/mimalloc/ide/vs2019/mimalloc-test-api.vcxproj @@ -0,0 +1,155 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {FFF7958F-750E-4C21-A04D-22707CC66878} + mimalloc-test-api + 10.0 + mimalloc-test-api + + + + Application + true + v142 + + + Application + false + v142 + true + + + Application + true + v142 + + + Application + false + v142 + true + + + + + + + + + + + + + + + + + + + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + + Level3 + Disabled + true + true + ..\..\include + + + Console + + + + + Level3 + Disabled + true + true + ..\..\include + + + Console + + + + + Level3 + MaxSpeed + true + true + true + true + ..\..\include + %(PreprocessorDefinitions);NDEBUG + + + true + true + Console + + + + + Level3 + MaxSpeed + true + true + true + true + ..\..\include + %(PreprocessorDefinitions);NDEBUG + + + true + true + Console + + + + + + + + + {abb5eae7-b3e6-432e-b636-333449892ea6} + + + + + + diff --git a/extlib/mimalloc/ide/vs2019/mimalloc-test-stress.vcxproj b/extlib/mimalloc/ide/vs2019/mimalloc-test-stress.vcxproj new file mode 100644 index 0000000..afbb666 --- /dev/null +++ b/extlib/mimalloc/ide/vs2019/mimalloc-test-stress.vcxproj @@ -0,0 +1,159 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {FEF7958F-750E-4C21-A04D-22707CC66878} + mimalloc-test-stress + 10.0 + mimalloc-test-stress + + + + Application + true + v142 + + + Application + false + v142 + true + + + Application + true + v142 + + + Application + false + v142 + true + + + + + + + + + + + + + + + + + + + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + + Level3 + Disabled + true + true + ..\..\include + + + Console + + + + + Level3 + Disabled + true + true + ..\..\include + + + Console + + + + + Level3 + MaxSpeed + true + true + true + true + ..\..\include + %(PreprocessorDefinitions);NDEBUG + + + true + true + Console + + + + + Level3 + MaxSpeed + true + true + true + true + ..\..\include + %(PreprocessorDefinitions);NDEBUG + + + true + true + Console + + + + + false + false + false + false + + + + + {abb5eae7-b3e6-432e-b636-333449892ea7} + + + + + + \ No newline at end of file diff --git a/extlib/mimalloc/ide/vs2019/mimalloc-test.vcxproj b/extlib/mimalloc/ide/vs2019/mimalloc-test.vcxproj new file mode 100644 index 0000000..13af6ab --- /dev/null +++ b/extlib/mimalloc/ide/vs2019/mimalloc-test.vcxproj @@ -0,0 +1,158 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {FEF7858F-750E-4C21-A04D-22707CC66878} + mimalloctest + 10.0 + mimalloc-test + + + + Application + true + v142 + + + Application + false + v142 + true + + + Application + true + v142 + + + Application + false + v142 + true + + + + + + + + + + + + + + + + + + + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + $(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + + + + Level3 + Disabled + true + true + ..\..\include + stdcpp17 + + + Console + + + + + Level3 + Disabled + true + true + ..\..\include + stdcpp17 + + + Console + + + + + Level3 + MaxSpeed + true + true + true + true + ..\..\include + _MBCS;%(PreprocessorDefinitions);NDEBUG + stdcpp17 + + + true + true + Console + + + + + Level3 + MaxSpeed + true + true + true + true + ..\..\include + _MBCS;%(PreprocessorDefinitions);NDEBUG + stdcpp17 + + + true + true + Console + + + + + {abb5eae7-b3e6-432e-b636-333449892ea6} + + + + + + + + + \ No newline at end of file diff --git a/extlib/mimalloc/ide/vs2019/mimalloc.sln b/extlib/mimalloc/ide/vs2019/mimalloc.sln new file mode 100644 index 0000000..fcb938a --- /dev/null +++ b/extlib/mimalloc/ide/vs2019/mimalloc.sln @@ -0,0 +1,81 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29709.97 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc", "mimalloc.vcxproj", "{ABB5EAE7-B3E6-432E-B636-333449892EA6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test", "mimalloc-test.vcxproj", "{FEF7858F-750E-4C21-A04D-22707CC66878}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-override", "mimalloc-override.vcxproj", "{ABB5EAE7-B3E6-432E-B636-333449892EA7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-override-test", "mimalloc-override-test.vcxproj", "{FEF7868F-750E-4C21-A04D-22707CC66879}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test-stress", "mimalloc-test-stress.vcxproj", "{FEF7958F-750E-4C21-A04D-22707CC66878}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test-api", "mimalloc-test-api.vcxproj", "{FFF7958F-750E-4C21-A04D-22707CC66878}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x64.ActiveCfg = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x64.Build.0 = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x86.ActiveCfg = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x86.Build.0 = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x64.ActiveCfg = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x64.Build.0 = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x86.ActiveCfg = Release|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x86.Build.0 = Release|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32 + {FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x64.ActiveCfg = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x64.Build.0 = Debug|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x86.ActiveCfg = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x86.Build.0 = Debug|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x64.ActiveCfg = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x64.Build.0 = Release|x64 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x86.ActiveCfg = Release|Win32 + {ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x86.Build.0 = Release|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x64.ActiveCfg = Debug|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x64.Build.0 = Debug|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x86.ActiveCfg = Debug|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x86.Build.0 = Debug|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.ActiveCfg = Release|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.Build.0 = Release|x64 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.ActiveCfg = Release|Win32 + {FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.Build.0 = Release|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32 + {FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32 + {FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4297F93D-486A-4243-995F-7D32F59AE82A} + EndGlobalSection +EndGlobal diff --git a/extlib/mimalloc/ide/vs2019/mimalloc.vcxproj b/extlib/mimalloc/ide/vs2019/mimalloc.vcxproj new file mode 100644 index 0000000..e18db0c --- /dev/null +++ b/extlib/mimalloc/ide/vs2019/mimalloc.vcxproj @@ -0,0 +1,253 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {ABB5EAE7-B3E6-432E-B636-333449892EA6} + mimalloc + 10.0 + mimalloc + + + + StaticLibrary + true + v142 + + + StaticLibrary + false + v142 + true + + + StaticLibrary + true + v142 + + + StaticLibrary + false + v142 + true + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .lib + mimalloc-static + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .lib + mimalloc-static + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .lib + mimalloc-static + + + $(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\ + $(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\ + .lib + mimalloc-static + + + + Level3 + Disabled + true + true + ../../include + MI_DEBUG=3;%(PreprocessorDefinitions); + CompileAsCpp + false + Default + + + + + + + + + + + Level4 + Disabled + true + true + ../../include + MI_DEBUG=3;%(PreprocessorDefinitions); + CompileAsCpp + false + Default + + + + + + + + + + + + + + + + + + + Level3 + MaxSpeed + true + true + ../../include + %(PreprocessorDefinitions);NDEBUG + AssemblyAndSourceCode + $(IntDir) + false + false + Default + CompileAsCpp + true + Default + + + true + true + + + + + + + + + + + Level3 + MaxSpeed + true + true + ../../include + %(PreprocessorDefinitions);NDEBUG + AssemblyAndSourceCode + $(IntDir) + false + false + Default + CompileAsCpp + true + Default + + + true + true + + + + + + + + + + + + + + + + + false + false + false + false + + + true + true + true + true + + + true + true + true + true + + + + + + true + + + + + + + true + true + true + true + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/extlib/mimalloc/ide/vs2019/mimalloc.vcxproj.filters b/extlib/mimalloc/ide/vs2019/mimalloc.vcxproj.filters new file mode 100644 index 0000000..4704fb2 --- /dev/null +++ b/extlib/mimalloc/ide/vs2019/mimalloc.vcxproj.filters @@ -0,0 +1,84 @@ + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + {2b556b10-f559-4b2d-896e-142652adbf0c} + + + {852a14ae-6dde-4e95-8077-ca705e97e5af} + + + diff --git a/extlib/mimalloc/include/mimalloc-atomic.h b/extlib/mimalloc/include/mimalloc-atomic.h new file mode 100644 index 0000000..722b6ad --- /dev/null +++ b/extlib/mimalloc/include/mimalloc-atomic.h @@ -0,0 +1,294 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_ATOMIC_H +#define MIMALLOC_ATOMIC_H + +// ------------------------------------------------------ +// Atomics +// We need to be portable between C, C++, and MSVC. +// ------------------------------------------------------ + +#if defined(_MSC_VER) +#define _Atomic(tp) tp +#define ATOMIC_VAR_INIT(x) x +#elif defined(__cplusplus) +#include +#define _Atomic(tp) std::atomic +#else +#include +#endif + +// ------------------------------------------------------ +// Atomic operations specialized for mimalloc +// ------------------------------------------------------ + +// Atomically add a value; returns the previous value. Memory ordering is relaxed. +static inline uintptr_t mi_atomic_add(volatile _Atomic(uintptr_t)* p, uintptr_t add); + +// Atomically "and" a value; returns the previous value. Memory ordering is relaxed. +static inline uintptr_t mi_atomic_and(volatile _Atomic(uintptr_t)* p, uintptr_t x); + +// Atomically "or" a value; returns the previous value. Memory ordering is relaxed. +static inline uintptr_t mi_atomic_or(volatile _Atomic(uintptr_t)* p, uintptr_t x); + +// Atomically compare and exchange a value; returns `true` if successful. +// May fail spuriously. Memory ordering as release on success, and relaxed on failure. +// (Note: expected and desired are in opposite order from atomic_compare_exchange) +static inline bool mi_atomic_cas_weak(volatile _Atomic(uintptr_t)* p, uintptr_t desired, uintptr_t expected); + +// Atomically compare and exchange a value; returns `true` if successful. +// Memory ordering is acquire-release +// (Note: expected and desired are in opposite order from atomic_compare_exchange) +static inline bool mi_atomic_cas_strong(volatile _Atomic(uintptr_t)* p, uintptr_t desired, uintptr_t expected); + +// Atomically exchange a value. Memory ordering is acquire-release. +static inline uintptr_t mi_atomic_exchange(volatile _Atomic(uintptr_t)* p, uintptr_t exchange); + +// Atomically read a value. Memory ordering is relaxed. +static inline uintptr_t mi_atomic_read_relaxed(const volatile _Atomic(uintptr_t)* p); + +// Atomically read a value. Memory ordering is acquire. +static inline uintptr_t mi_atomic_read(const volatile _Atomic(uintptr_t)* p); + +// Atomically write a value. Memory ordering is release. +static inline void mi_atomic_write(volatile _Atomic(uintptr_t)* p, uintptr_t x); + +// Yield +static inline void mi_atomic_yield(void); + +// Atomically add a 64-bit value; returns the previous value. +// Note: not using _Atomic(int64_t) as it is only used for statistics. +static inline void mi_atomic_addi64(volatile int64_t* p, int64_t add); + +// Atomically update `*p` with the maximum of `*p` and `x` as a 64-bit value. +// Returns the previous value. Note: not using _Atomic(int64_t) as it is only used for statistics. +static inline void mi_atomic_maxi64(volatile int64_t* p, int64_t x); + +// Atomically read a 64-bit value +// Note: not using _Atomic(int64_t) as it is only used for statistics. +static inline int64_t mi_atomic_readi64(volatile int64_t* p); + +// Atomically subtract a value; returns the previous value. +static inline uintptr_t mi_atomic_sub(volatile _Atomic(uintptr_t)* p, uintptr_t sub) { + return mi_atomic_add(p, (uintptr_t)(-((intptr_t)sub))); +} + +// Atomically increment a value; returns the incremented result. +static inline uintptr_t mi_atomic_increment(volatile _Atomic(uintptr_t)* p) { + return mi_atomic_add(p, 1); +} + +// Atomically decrement a value; returns the decremented result. +static inline uintptr_t mi_atomic_decrement(volatile _Atomic(uintptr_t)* p) { + return mi_atomic_sub(p, 1); +} + +// Atomically add a signed value; returns the previous value. +static inline intptr_t mi_atomic_addi(volatile _Atomic(intptr_t)* p, intptr_t add) { + return (intptr_t)mi_atomic_add((volatile _Atomic(uintptr_t)*)p, (uintptr_t)add); +} + +// Atomically subtract a signed value; returns the previous value. +static inline intptr_t mi_atomic_subi(volatile _Atomic(intptr_t)* p, intptr_t sub) { + return (intptr_t)mi_atomic_addi(p,-sub); +} + +// Atomically read a pointer; Memory order is relaxed (i.e. no fence, only atomic). +#define mi_atomic_read_ptr_relaxed(T,p) \ + (T*)(mi_atomic_read_relaxed((const volatile _Atomic(uintptr_t)*)(p))) + +// Atomically read a pointer; Memory order is acquire. +#define mi_atomic_read_ptr(T,p) \ + (T*)(mi_atomic_read((const volatile _Atomic(uintptr_t)*)(p))) + +// Atomically write a pointer; Memory order is acquire. +#define mi_atomic_write_ptr(T,p,x) \ + mi_atomic_write((volatile _Atomic(uintptr_t)*)(p), (uintptr_t)((T*)x)) + +// Atomically compare and exchange a pointer; returns `true` if successful. May fail spuriously. +// Memory order is release. (like a write) +// (Note: expected and desired are in opposite order from atomic_compare_exchange) +#define mi_atomic_cas_ptr_weak(T,p,desired,expected) \ + mi_atomic_cas_weak((volatile _Atomic(uintptr_t)*)(p), (uintptr_t)((T*)(desired)), (uintptr_t)((T*)(expected))) + +// Atomically compare and exchange a pointer; returns `true` if successful. Memory order is acquire_release. +// (Note: expected and desired are in opposite order from atomic_compare_exchange) +#define mi_atomic_cas_ptr_strong(T,p,desired,expected) \ + mi_atomic_cas_strong((volatile _Atomic(uintptr_t)*)(p),(uintptr_t)((T*)(desired)), (uintptr_t)((T*)(expected))) + +// Atomically exchange a pointer value. +#define mi_atomic_exchange_ptr(T,p,exchange) \ + (T*)mi_atomic_exchange((volatile _Atomic(uintptr_t)*)(p), (uintptr_t)((T*)exchange)) + + +#ifdef _MSC_VER +#define WIN32_LEAN_AND_MEAN +#include +#include +#ifdef _WIN64 +typedef LONG64 msc_intptr_t; +#define MI_64(f) f##64 +#else +typedef LONG msc_intptr_t; +#define MI_64(f) f +#endif +static inline uintptr_t mi_atomic_add(volatile _Atomic(uintptr_t)* p, uintptr_t add) { + return (uintptr_t)MI_64(_InterlockedExchangeAdd)((volatile msc_intptr_t*)p, (msc_intptr_t)add); +} +static inline uintptr_t mi_atomic_and(volatile _Atomic(uintptr_t)* p, uintptr_t x) { + return (uintptr_t)MI_64(_InterlockedAnd)((volatile msc_intptr_t*)p, (msc_intptr_t)x); +} +static inline uintptr_t mi_atomic_or(volatile _Atomic(uintptr_t)* p, uintptr_t x) { + return (uintptr_t)MI_64(_InterlockedOr)((volatile msc_intptr_t*)p, (msc_intptr_t)x); +} +static inline bool mi_atomic_cas_strong(volatile _Atomic(uintptr_t)* p, uintptr_t desired, uintptr_t expected) { + return (expected == (uintptr_t)MI_64(_InterlockedCompareExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)desired, (msc_intptr_t)expected)); +} +static inline bool mi_atomic_cas_weak(volatile _Atomic(uintptr_t)* p, uintptr_t desired, uintptr_t expected) { + return mi_atomic_cas_strong(p,desired,expected); +} +static inline uintptr_t mi_atomic_exchange(volatile _Atomic(uintptr_t)* p, uintptr_t exchange) { + return (uintptr_t)MI_64(_InterlockedExchange)((volatile msc_intptr_t*)p, (msc_intptr_t)exchange); +} +static inline uintptr_t mi_atomic_read(volatile _Atomic(uintptr_t) const* p) { + return *p; +} +static inline uintptr_t mi_atomic_read_relaxed(volatile _Atomic(uintptr_t) const* p) { + return *p; +} +static inline void mi_atomic_write(volatile _Atomic(uintptr_t)* p, uintptr_t x) { + #if defined(_M_IX86) || defined(_M_X64) + *p = x; + #else + mi_atomic_exchange(p,x); + #endif +} +static inline void mi_atomic_yield(void) { + YieldProcessor(); +} +static inline void mi_atomic_addi64(volatile _Atomic(int64_t)* p, int64_t add) { + #ifdef _WIN64 + mi_atomic_addi(p,add); + #else + int64_t current; + int64_t sum; + do { + current = *p; + sum = current + add; + } while (_InterlockedCompareExchange64(p, sum, current) != current); + #endif +} + +static inline void mi_atomic_maxi64(volatile _Atomic(int64_t)*p, int64_t x) { + int64_t current; + do { + current = *p; + } while (current < x && _InterlockedCompareExchange64(p, x, current) != current); +} + +static inline int64_t mi_atomic_readi64(volatile _Atomic(int64_t)*p) { + #ifdef _WIN64 + return *p; + #else + int64_t current; + do { + current = *p; + } while (_InterlockedCompareExchange64(p, current, current) != current); + return current; + #endif +} + +#else +#ifdef __cplusplus +#define MI_USING_STD using namespace std; +#else +#define MI_USING_STD +#endif +static inline uintptr_t mi_atomic_add(volatile _Atomic(uintptr_t)* p, uintptr_t add) { + MI_USING_STD + return atomic_fetch_add_explicit(p, add, memory_order_relaxed); +} +static inline uintptr_t mi_atomic_and(volatile _Atomic(uintptr_t)* p, uintptr_t x) { + MI_USING_STD + return atomic_fetch_and_explicit(p, x, memory_order_acq_rel); +} +static inline uintptr_t mi_atomic_or(volatile _Atomic(uintptr_t)* p, uintptr_t x) { + MI_USING_STD + return atomic_fetch_or_explicit(p, x, memory_order_acq_rel); +} +static inline bool mi_atomic_cas_weak(volatile _Atomic(uintptr_t)* p, uintptr_t desired, uintptr_t expected) { + MI_USING_STD + return atomic_compare_exchange_weak_explicit(p, &expected, desired, memory_order_acq_rel, memory_order_acquire); +} +static inline bool mi_atomic_cas_strong(volatile _Atomic(uintptr_t)* p, uintptr_t desired, uintptr_t expected) { + MI_USING_STD + return atomic_compare_exchange_strong_explicit(p, &expected, desired, memory_order_acq_rel, memory_order_acquire); +} +static inline uintptr_t mi_atomic_exchange(volatile _Atomic(uintptr_t)* p, uintptr_t exchange) { + MI_USING_STD + return atomic_exchange_explicit(p, exchange, memory_order_acq_rel); +} +static inline uintptr_t mi_atomic_read_relaxed(const volatile _Atomic(uintptr_t)* p) { + MI_USING_STD + return atomic_load_explicit((volatile _Atomic(uintptr_t)*) p, memory_order_relaxed); +} +static inline uintptr_t mi_atomic_read(const volatile _Atomic(uintptr_t)* p) { + MI_USING_STD + return atomic_load_explicit((volatile _Atomic(uintptr_t)*) p, memory_order_acquire); +} +static inline void mi_atomic_write(volatile _Atomic(uintptr_t)* p, uintptr_t x) { + MI_USING_STD + return atomic_store_explicit(p, x, memory_order_release); +} +static inline void mi_atomic_addi64(volatile int64_t* p, int64_t add) { + MI_USING_STD + atomic_fetch_add_explicit((volatile _Atomic(int64_t)*)p, add, memory_order_relaxed); +} +static inline int64_t mi_atomic_readi64(volatile int64_t* p) { + MI_USING_STD + return atomic_load_explicit((volatile _Atomic(int64_t)*) p, memory_order_relaxed); +} +static inline void mi_atomic_maxi64(volatile int64_t* p, int64_t x) { + MI_USING_STD + int64_t current; + do { + current = mi_atomic_readi64(p); + } while (current < x && !atomic_compare_exchange_weak_explicit((volatile _Atomic(int64_t)*)p, ¤t, x, memory_order_acq_rel, memory_order_relaxed)); +} + +#if defined(__cplusplus) + #include + static inline void mi_atomic_yield(void) { + std::this_thread::yield(); + } +#elif (defined(__GNUC__) || defined(__clang__)) && \ + (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)) +#if defined(__x86_64__) || defined(__i386__) + static inline void mi_atomic_yield(void) { + asm volatile ("pause" ::: "memory"); + } +#elif defined(__arm__) || defined(__aarch64__) + static inline void mi_atomic_yield(void) { + asm volatile("yield"); + } +#endif +#elif defined(__wasi__) + #include + static inline void mi_atomic_yield(void) { + sched_yield(); + } +#else + #include + static inline void mi_atomic_yield(void) { + sleep(0); + } +#endif + +#endif + +#endif // __MIMALLOC_ATOMIC_H diff --git a/extlib/mimalloc/include/mimalloc-internal.h b/extlib/mimalloc/include/mimalloc-internal.h new file mode 100644 index 0000000..2dc7e36 --- /dev/null +++ b/extlib/mimalloc/include/mimalloc-internal.h @@ -0,0 +1,748 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_INTERNAL_H +#define MIMALLOC_INTERNAL_H + +#include "mimalloc-types.h" + +#if (MI_DEBUG>0) +#define mi_trace_message(...) _mi_trace_message(__VA_ARGS__) +#else +#define mi_trace_message(...) +#endif + +#define MI_CACHE_LINE 64 +#if defined(_MSC_VER) +#pragma warning(disable:4127) // suppress constant conditional warning (due to MI_SECURE paths) +#define mi_decl_noinline __declspec(noinline) +#define mi_decl_thread __declspec(thread) +#define mi_decl_cache_align __declspec(align(MI_CACHE_LINE)) +#elif (defined(__GNUC__) && (__GNUC__>=3)) // includes clang and icc +#define mi_decl_noinline __attribute__((noinline)) +#define mi_decl_thread __thread +#define mi_decl_cache_align __attribute__((aligned(MI_CACHE_LINE))) +#else +#define mi_decl_noinline +#define mi_decl_thread __thread // hope for the best :-) +#define mi_decl_cache_align +#endif + + +// "options.c" +void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message); +void _mi_fprintf(mi_output_fun* out, void* arg, const char* fmt, ...); +void _mi_warning_message(const char* fmt, ...); +void _mi_verbose_message(const char* fmt, ...); +void _mi_trace_message(const char* fmt, ...); +void _mi_options_init(void); +void _mi_error_message(int err, const char* fmt, ...); + +// random.c +void _mi_random_init(mi_random_ctx_t* ctx); +void _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* new_ctx); +uintptr_t _mi_random_next(mi_random_ctx_t* ctx); +uintptr_t _mi_heap_random_next(mi_heap_t* heap); +uintptr_t _os_random_weak(uintptr_t extra_seed); +static inline uintptr_t _mi_random_shuffle(uintptr_t x); + +// init.c +extern mi_stats_t _mi_stats_main; +extern const mi_page_t _mi_page_empty; +bool _mi_is_main_thread(void); +bool _mi_preloading(); // true while the C runtime is not ready + +// os.c +size_t _mi_os_page_size(void); +void _mi_os_init(void); // called from process init +void* _mi_os_alloc(size_t size, mi_stats_t* stats); // to allocate thread local data +void _mi_os_free(void* p, size_t size, mi_stats_t* stats); // to free thread local data +size_t _mi_os_good_alloc_size(size_t size); + +// memory.c +void* _mi_mem_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_zero, size_t* id, mi_os_tld_t* tld); +void _mi_mem_free(void* p, size_t size, size_t id, bool fully_committed, bool any_reset, mi_os_tld_t* tld); + +bool _mi_mem_reset(void* p, size_t size, mi_os_tld_t* tld); +bool _mi_mem_unreset(void* p, size_t size, bool* is_zero, mi_os_tld_t* tld); +bool _mi_mem_commit(void* p, size_t size, bool* is_zero, mi_os_tld_t* tld); +bool _mi_mem_protect(void* addr, size_t size); +bool _mi_mem_unprotect(void* addr, size_t size); + +void _mi_mem_collect(mi_os_tld_t* tld); + +// "segment.c" +mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_wsize, mi_segments_tld_t* tld, mi_os_tld_t* os_tld); +void _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld); +void _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld); +uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t block_size, size_t* page_size, size_t* pre_size); // page start for any page +void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block); + +void _mi_segment_thread_collect(mi_segments_tld_t* tld); +void _mi_abandoned_reclaim_all(mi_heap_t* heap, mi_segments_tld_t* tld); +void _mi_abandoned_await_readers(void); + + + +// "page.c" +void* _mi_malloc_generic(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc; + +void _mi_page_retire(mi_page_t* page); // free the page if there are no other pages with many free blocks +void _mi_page_unfull(mi_page_t* page); +void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force); // free the page +void _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq); // abandon the page, to be picked up by another thread... +void _mi_heap_delayed_free(mi_heap_t* heap); +void _mi_heap_collect_retired(mi_heap_t* heap, bool force); + +void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never); +size_t _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append); +void _mi_deferred_free(mi_heap_t* heap, bool force); + +void _mi_page_free_collect(mi_page_t* page,bool force); +void _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page); // callback from segments + +size_t _mi_bin_size(uint8_t bin); // for stats +uint8_t _mi_bin(size_t size); // for stats +uint8_t _mi_bsr(uintptr_t x); // bit-scan-right, used on BSD in "os.c" + +// "heap.c" +void _mi_heap_destroy_pages(mi_heap_t* heap); +void _mi_heap_collect_abandon(mi_heap_t* heap); +void _mi_heap_set_default_direct(mi_heap_t* heap); + +// "stats.c" +void _mi_stats_done(mi_stats_t* stats); + +mi_msecs_t _mi_clock_now(void); +mi_msecs_t _mi_clock_end(mi_msecs_t start); +mi_msecs_t _mi_clock_start(void); + +// "alloc.c" +void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size) mi_attr_noexcept; // called from `_mi_malloc_generic` +void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero); +void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero); +mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p); +bool _mi_free_delayed_block(mi_block_t* block); +void _mi_block_zero_init(const mi_page_t* page, void* p, size_t size); + +#if MI_DEBUG>1 +bool _mi_page_is_valid(mi_page_t* page); +#endif + + +// ------------------------------------------------------ +// Branches +// ------------------------------------------------------ + +#if defined(__GNUC__) || defined(__clang__) +#define mi_unlikely(x) __builtin_expect((x),0) +#define mi_likely(x) __builtin_expect((x),1) +#else +#define mi_unlikely(x) (x) +#define mi_likely(x) (x) +#endif + +#ifndef __has_builtin +#define __has_builtin(x) 0 +#endif + + +/* ----------------------------------------------------------- + Error codes passed to `_mi_fatal_error` + All are recoverable but EFAULT is a serious error and aborts by default in secure mode. + For portability define undefined error codes using common Unix codes: + +----------------------------------------------------------- */ +#include +#ifndef EAGAIN // double free +#define EAGAIN (11) +#endif +#ifndef ENOMEM // out of memory +#define ENOMEM (12) +#endif +#ifndef EFAULT // corrupted free-list or meta-data +#define EFAULT (14) +#endif +#ifndef EINVAL // trying to free an invalid pointer +#define EINVAL (22) +#endif +#ifndef EOVERFLOW // count*size overflow +#define EOVERFLOW (75) +#endif + + +/* ----------------------------------------------------------- + Inlined definitions +----------------------------------------------------------- */ +#define UNUSED(x) (void)(x) +#if (MI_DEBUG>0) +#define UNUSED_RELEASE(x) +#else +#define UNUSED_RELEASE(x) UNUSED(x) +#endif + +#define MI_INIT4(x) x(),x(),x(),x() +#define MI_INIT8(x) MI_INIT4(x),MI_INIT4(x) +#define MI_INIT16(x) MI_INIT8(x),MI_INIT8(x) +#define MI_INIT32(x) MI_INIT16(x),MI_INIT16(x) +#define MI_INIT64(x) MI_INIT32(x),MI_INIT32(x) +#define MI_INIT128(x) MI_INIT64(x),MI_INIT64(x) +#define MI_INIT256(x) MI_INIT128(x),MI_INIT128(x) + + +// Is `x` a power of two? (0 is considered a power of two) +static inline bool _mi_is_power_of_two(uintptr_t x) { + return ((x & (x - 1)) == 0); +} + +// Align upwards +static inline uintptr_t _mi_align_up(uintptr_t sz, size_t alignment) { + mi_assert_internal(alignment != 0); + uintptr_t mask = alignment - 1; + if ((alignment & mask) == 0) { // power of two? + return ((sz + mask) & ~mask); + } + else { + return (((sz + mask)/alignment)*alignment); + } +} + +// Divide upwards: `s <= _mi_divide_up(s,d)*d < s+d`. +static inline uintptr_t _mi_divide_up(uintptr_t size, size_t divider) { + mi_assert_internal(divider != 0); + return (divider == 0 ? size : ((size + divider - 1) / divider)); +} + +// Is memory zero initialized? +static inline bool mi_mem_is_zero(void* p, size_t size) { + for (size_t i = 0; i < size; i++) { + if (((uint8_t*)p)[i] != 0) return false; + } + return true; +} + +// Align a byte size to a size in _machine words_, +// i.e. byte size == `wsize*sizeof(void*)`. +static inline size_t _mi_wsize_from_size(size_t size) { + mi_assert_internal(size <= SIZE_MAX - sizeof(uintptr_t)); + return (size + sizeof(uintptr_t) - 1) / sizeof(uintptr_t); +} + +// Does malloc satisfy the alignment constraints already? +static inline bool mi_malloc_satisfies_alignment(size_t alignment, size_t size) { + return (alignment == sizeof(void*) || (alignment == MI_MAX_ALIGN_SIZE && size > (MI_MAX_ALIGN_SIZE/2))); +} + +// Overflow detecting multiply +#if __has_builtin(__builtin_umul_overflow) || __GNUC__ >= 5 +#include // UINT_MAX, ULONG_MAX +#if defined(_CLOCK_T) // for Illumos +#undef _CLOCK_T +#endif +static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) { + #if (SIZE_MAX == UINT_MAX) + return __builtin_umul_overflow(count, size, total); + #elif (SIZE_MAX == ULONG_MAX) + return __builtin_umull_overflow(count, size, total); + #else + return __builtin_umulll_overflow(count, size, total); + #endif +} +#else /* __builtin_umul_overflow is unavailable */ +static inline bool mi_mul_overflow(size_t count, size_t size, size_t* total) { + #define MI_MUL_NO_OVERFLOW ((size_t)1 << (4*sizeof(size_t))) // sqrt(SIZE_MAX) + *total = count * size; + return ((size >= MI_MUL_NO_OVERFLOW || count >= MI_MUL_NO_OVERFLOW) + && size > 0 && (SIZE_MAX / size) < count); +} +#endif + +// Safe multiply `count*size` into `total`; return `true` on overflow. +static inline bool mi_count_size_overflow(size_t count, size_t size, size_t* total) { + if (count==1) { // quick check for the case where count is one (common for C++ allocators) + *total = size; + return false; + } + else if (mi_unlikely(mi_mul_overflow(count, size, total))) { + _mi_error_message(EOVERFLOW, "allocation request is too large (%zu * %zu bytes)\n", count, size); + *total = SIZE_MAX; + return true; + } + else return false; +} + + +/* ---------------------------------------------------------------------------------------- +The thread local default heap: `_mi_get_default_heap` returns the thread local heap. +On most platforms (Windows, Linux, FreeBSD, NetBSD, etc), this just returns a +__thread local variable (`_mi_heap_default`). With the initial-exec TLS model this ensures +that the storage will always be available (allocated on the thread stacks). +On some platforms though we cannot use that when overriding `malloc` since the underlying +TLS implementation (or the loader) will call itself `malloc` on a first access and recurse. +We try to circumvent this in an efficient way: +- macOSX : we use an unused TLS slot from the OS allocated slots (MI_TLS_SLOT). On OSX, the + loader itself calls `malloc` even before the modules are initialized. +- OpenBSD: we use an unused slot from the pthread block (MI_TLS_PTHREAD_SLOT_OFS). +- DragonFly: not yet working. +------------------------------------------------------------------------------------------- */ + +extern const mi_heap_t _mi_heap_empty; // read-only empty heap, initial value of the thread local default heap +extern bool _mi_process_is_initialized; +mi_heap_t* _mi_heap_main_get(void); // statically allocated main backing heap + +#if defined(MI_MALLOC_OVERRIDE) +#if defined(__MACH__) // OSX +#define MI_TLS_SLOT 89 // seems unused? +// other possible unused ones are 9, 29, __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4 (94), __PTK_FRAMEWORK_GC_KEY9 (112) and __PTK_FRAMEWORK_OLDGC_KEY9 (89) +// see +#elif defined(__OpenBSD__) +// use end bytes of a name; goes wrong if anyone uses names > 23 characters (ptrhread specifies 16) +// see +#define MI_TLS_PTHREAD_SLOT_OFS (6*sizeof(int) + 4*sizeof(void*) + 24) +#elif defined(__DragonFly__) +#warning "mimalloc is not working correctly on DragonFly yet." +#define MI_TLS_PTHREAD_SLOT_OFS (4 + 1*sizeof(void*)) // offset `uniqueid` (also used by gdb?) +#endif +#endif + +#if defined(MI_TLS_SLOT) +static inline void* mi_tls_slot(size_t slot) mi_attr_noexcept; // forward declaration +#elif defined(MI_TLS_PTHREAD_SLOT_OFS) +#include +static inline mi_heap_t** mi_tls_pthread_heap_slot(void) { + pthread_t self = pthread_self(); + #if defined(__DragonFly__) + if (self==NULL) { + static mi_heap_t* pheap_main = _mi_heap_main_get(); + return &pheap_main; + } + #endif + return (mi_heap_t**)((uint8_t*)self + MI_TLS_PTHREAD_SLOT_OFS); +} +#elif defined(MI_TLS_PTHREAD) +#include +extern pthread_key_t _mi_heap_default_key; +#else +extern mi_decl_thread mi_heap_t* _mi_heap_default; // default heap to allocate from +#endif + +static inline mi_heap_t* mi_get_default_heap(void) { +#if defined(MI_TLS_SLOT) + mi_heap_t* heap = (mi_heap_t*)mi_tls_slot(MI_TLS_SLOT); + return (mi_unlikely(heap == NULL) ? (mi_heap_t*)&_mi_heap_empty : heap); +#elif defined(MI_TLS_PTHREAD_SLOT_OFS) + mi_heap_t* heap = *mi_tls_pthread_heap_slot(); + return (mi_unlikely(heap == NULL) ? (mi_heap_t*)&_mi_heap_empty : heap); +#elif defined(MI_TLS_PTHREAD) + mi_heap_t* heap = (mi_unlikely(_mi_heap_default_key == (pthread_key_t)(-1)) ? _mi_heap_main_get() : (mi_heap_t*)pthread_getspecific(_mi_heap_default_key)); + return (mi_unlikely(heap == NULL) ? (mi_heap_t*)&_mi_heap_empty : heap); +#else + #if defined(MI_TLS_RECURSE_GUARD) + if (mi_unlikely(!_mi_process_is_initialized)) return _mi_heap_main_get(); + #endif + return _mi_heap_default; +#endif +} + +static inline bool mi_heap_is_default(const mi_heap_t* heap) { + return (heap == mi_get_default_heap()); +} + +static inline bool mi_heap_is_backing(const mi_heap_t* heap) { + return (heap->tld->heap_backing == heap); +} + +static inline bool mi_heap_is_initialized(mi_heap_t* heap) { + mi_assert_internal(heap != NULL); + return (heap != &_mi_heap_empty); +} + +static inline uintptr_t _mi_ptr_cookie(const void* p) { + extern mi_heap_t _mi_heap_main; + mi_assert_internal(_mi_heap_main.cookie != 0); + return ((uintptr_t)p ^ _mi_heap_main.cookie); +} + +/* ----------------------------------------------------------- + Pages +----------------------------------------------------------- */ + +static inline mi_page_t* _mi_heap_get_free_small_page(mi_heap_t* heap, size_t size) { + mi_assert_internal(size <= (MI_SMALL_SIZE_MAX + MI_PADDING_SIZE)); + const size_t idx = _mi_wsize_from_size(size); + mi_assert_internal(idx < MI_PAGES_DIRECT); + return heap->pages_free_direct[idx]; +} + +// Get the page belonging to a certain size class +static inline mi_page_t* _mi_get_free_small_page(size_t size) { + return _mi_heap_get_free_small_page(mi_get_default_heap(), size); +} + +// Segment that contains the pointer +static inline mi_segment_t* _mi_ptr_segment(const void* p) { + // mi_assert_internal(p != NULL); + return (mi_segment_t*)((uintptr_t)p & ~MI_SEGMENT_MASK); +} + +// Segment belonging to a page +static inline mi_segment_t* _mi_page_segment(const mi_page_t* page) { + mi_segment_t* segment = _mi_ptr_segment(page); + mi_assert_internal(segment == NULL || page == &segment->pages[page->segment_idx]); + return segment; +} + +// used internally +static inline uintptr_t _mi_segment_page_idx_of(const mi_segment_t* segment, const void* p) { + // if (segment->page_size > MI_SEGMENT_SIZE) return &segment->pages[0]; // huge pages + ptrdiff_t diff = (uint8_t*)p - (uint8_t*)segment; + mi_assert_internal(diff >= 0 && (size_t)diff < MI_SEGMENT_SIZE); + uintptr_t idx = (uintptr_t)diff >> segment->page_shift; + mi_assert_internal(idx < segment->capacity); + mi_assert_internal(segment->page_kind <= MI_PAGE_MEDIUM || idx == 0); + return idx; +} + +// Get the page containing the pointer +static inline mi_page_t* _mi_segment_page_of(const mi_segment_t* segment, const void* p) { + uintptr_t idx = _mi_segment_page_idx_of(segment, p); + return &((mi_segment_t*)segment)->pages[idx]; +} + +// Quick page start for initialized pages +static inline uint8_t* _mi_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size) { + const size_t bsize = page->xblock_size; + mi_assert_internal(bsize > 0 && (bsize%sizeof(void*)) == 0); + return _mi_segment_page_start(segment, page, bsize, page_size, NULL); +} + +// Get the page containing the pointer +static inline mi_page_t* _mi_ptr_page(void* p) { + return _mi_segment_page_of(_mi_ptr_segment(p), p); +} + +// Get the block size of a page (special cased for huge objects) +static inline size_t mi_page_block_size(const mi_page_t* page) { + const size_t bsize = page->xblock_size; + mi_assert_internal(bsize > 0); + if (mi_likely(bsize < MI_HUGE_BLOCK_SIZE)) { + return bsize; + } + else { + size_t psize; + _mi_segment_page_start(_mi_page_segment(page), page, bsize, &psize, NULL); + return psize; + } +} + +// Get the usable block size of a page without fixed padding. +// This may still include internal padding due to alignment and rounding up size classes. +static inline size_t mi_page_usable_block_size(const mi_page_t* page) { + return mi_page_block_size(page) - MI_PADDING_SIZE; +} + + +// Thread free access +static inline mi_block_t* mi_page_thread_free(const mi_page_t* page) { + return (mi_block_t*)(mi_atomic_read_relaxed(&page->xthread_free) & ~3); +} + +static inline mi_delayed_t mi_page_thread_free_flag(const mi_page_t* page) { + return (mi_delayed_t)(mi_atomic_read_relaxed(&page->xthread_free) & 3); +} + +// Heap access +static inline mi_heap_t* mi_page_heap(const mi_page_t* page) { + return (mi_heap_t*)(mi_atomic_read_relaxed(&page->xheap)); +} + +static inline void mi_page_set_heap(mi_page_t* page, mi_heap_t* heap) { + mi_assert_internal(mi_page_thread_free_flag(page) != MI_DELAYED_FREEING); + mi_atomic_write(&page->xheap,(uintptr_t)heap); +} + +// Thread free flag helpers +static inline mi_block_t* mi_tf_block(mi_thread_free_t tf) { + return (mi_block_t*)(tf & ~0x03); +} +static inline mi_delayed_t mi_tf_delayed(mi_thread_free_t tf) { + return (mi_delayed_t)(tf & 0x03); +} +static inline mi_thread_free_t mi_tf_make(mi_block_t* block, mi_delayed_t delayed) { + return (mi_thread_free_t)((uintptr_t)block | (uintptr_t)delayed); +} +static inline mi_thread_free_t mi_tf_set_delayed(mi_thread_free_t tf, mi_delayed_t delayed) { + return mi_tf_make(mi_tf_block(tf),delayed); +} +static inline mi_thread_free_t mi_tf_set_block(mi_thread_free_t tf, mi_block_t* block) { + return mi_tf_make(block, mi_tf_delayed(tf)); +} + +// are all blocks in a page freed? +// note: needs up-to-date used count, (as the `xthread_free` list may not be empty). see `_mi_page_collect_free`. +static inline bool mi_page_all_free(const mi_page_t* page) { + mi_assert_internal(page != NULL); + return (page->used == 0); +} + +// are there any available blocks? +static inline bool mi_page_has_any_available(const mi_page_t* page) { + mi_assert_internal(page != NULL && page->reserved > 0); + return (page->used < page->reserved || (mi_page_thread_free(page) != NULL)); +} + +// are there immediately available blocks, i.e. blocks available on the free list. +static inline bool mi_page_immediate_available(const mi_page_t* page) { + mi_assert_internal(page != NULL); + return (page->free != NULL); +} + +// is more than 7/8th of a page in use? +static inline bool mi_page_mostly_used(const mi_page_t* page) { + if (page==NULL) return true; + uint16_t frac = page->reserved / 8U; + return (page->reserved - page->used <= frac); +} + +static inline mi_page_queue_t* mi_page_queue(const mi_heap_t* heap, size_t size) { + return &((mi_heap_t*)heap)->pages[_mi_bin(size)]; +} + + + +//----------------------------------------------------------- +// Page flags +//----------------------------------------------------------- +static inline bool mi_page_is_in_full(const mi_page_t* page) { + return page->flags.x.in_full; +} + +static inline void mi_page_set_in_full(mi_page_t* page, bool in_full) { + page->flags.x.in_full = in_full; +} + +static inline bool mi_page_has_aligned(const mi_page_t* page) { + return page->flags.x.has_aligned; +} + +static inline void mi_page_set_has_aligned(mi_page_t* page, bool has_aligned) { + page->flags.x.has_aligned = has_aligned; +} + + +/* ------------------------------------------------------------------- +Encoding/Decoding the free list next pointers + +This is to protect against buffer overflow exploits where the +free list is mutated. Many hardened allocators xor the next pointer `p` +with a secret key `k1`, as `p^k1`. This prevents overwriting with known +values but might be still too weak: if the attacker can guess +the pointer `p` this can reveal `k1` (since `p^k1^p == k1`). +Moreover, if multiple blocks can be read as well, the attacker can +xor both as `(p1^k1) ^ (p2^k1) == p1^p2` which may reveal a lot +about the pointers (and subsequently `k1`). + +Instead mimalloc uses an extra key `k2` and encodes as `((p^k2)<<> (MI_INTPTR_BITS - shift)))); +} +static inline uintptr_t mi_rotr(uintptr_t x, uintptr_t shift) { + shift %= MI_INTPTR_BITS; + return (shift==0 ? x : ((x >> shift) | (x << (MI_INTPTR_BITS - shift)))); +} + +static inline void* mi_ptr_decode(const void* null, const mi_encoded_t x, const uintptr_t* keys) { + void* p = (void*)(mi_rotr(x - keys[0], keys[0]) ^ keys[1]); + return (mi_unlikely(p==null) ? NULL : p); +} + +static inline mi_encoded_t mi_ptr_encode(const void* null, const void* p, const uintptr_t* keys) { + uintptr_t x = (uintptr_t)(mi_unlikely(p==NULL) ? null : p); + return mi_rotl(x ^ keys[1], keys[0]) + keys[0]; +} + +static inline mi_block_t* mi_block_nextx( const void* null, const mi_block_t* block, const uintptr_t* keys ) { + #ifdef MI_ENCODE_FREELIST + return (mi_block_t*)mi_ptr_decode(null, block->next, keys); + #else + UNUSED(keys); UNUSED(null); + return (mi_block_t*)block->next; + #endif +} + +static inline void mi_block_set_nextx(const void* null, mi_block_t* block, const mi_block_t* next, const uintptr_t* keys) { + #ifdef MI_ENCODE_FREELIST + block->next = mi_ptr_encode(null, next, keys); + #else + UNUSED(keys); UNUSED(null); + block->next = (mi_encoded_t)next; + #endif +} + +static inline mi_block_t* mi_block_next(const mi_page_t* page, const mi_block_t* block) { + #ifdef MI_ENCODE_FREELIST + mi_block_t* next = mi_block_nextx(page,block,page->keys); + // check for free list corruption: is `next` at least in the same page? + // TODO: check if `next` is `page->block_size` aligned? + if (mi_unlikely(next!=NULL && !mi_is_in_same_page(block, next))) { + _mi_error_message(EFAULT, "corrupted free list entry of size %zub at %p: value 0x%zx\n", mi_page_block_size(page), block, (uintptr_t)next); + next = NULL; + } + return next; + #else + UNUSED(page); + return mi_block_nextx(page,block,NULL); + #endif +} + +static inline void mi_block_set_next(const mi_page_t* page, mi_block_t* block, const mi_block_t* next) { + #ifdef MI_ENCODE_FREELIST + mi_block_set_nextx(page,block,next, page->keys); + #else + UNUSED(page); + mi_block_set_nextx(page,block,next,NULL); + #endif +} + +// ------------------------------------------------------------------- +// Fast "random" shuffle +// ------------------------------------------------------------------- + +static inline uintptr_t _mi_random_shuffle(uintptr_t x) { + if (x==0) { x = 17; } // ensure we don't get stuck in generating zeros +#if (MI_INTPTR_SIZE==8) + // by Sebastiano Vigna, see: + x ^= x >> 30; + x *= 0xbf58476d1ce4e5b9UL; + x ^= x >> 27; + x *= 0x94d049bb133111ebUL; + x ^= x >> 31; +#elif (MI_INTPTR_SIZE==4) + // by Chris Wellons, see: + x ^= x >> 16; + x *= 0x7feb352dUL; + x ^= x >> 15; + x *= 0x846ca68bUL; + x ^= x >> 16; +#endif + return x; +} + +// ------------------------------------------------------------------- +// Optimize numa node access for the common case (= one node) +// ------------------------------------------------------------------- + +int _mi_os_numa_node_get(mi_os_tld_t* tld); +size_t _mi_os_numa_node_count_get(void); + +extern size_t _mi_numa_node_count; +static inline int _mi_os_numa_node(mi_os_tld_t* tld) { + if (mi_likely(_mi_numa_node_count == 1)) return 0; + else return _mi_os_numa_node_get(tld); +} +static inline size_t _mi_os_numa_node_count(void) { + if (mi_likely(_mi_numa_node_count>0)) return _mi_numa_node_count; + else return _mi_os_numa_node_count_get(); +} + + +// ------------------------------------------------------------------- +// Getting the thread id should be performant as it is called in the +// fast path of `_mi_free` and we specialize for various platforms. +// ------------------------------------------------------------------- +#if defined(_WIN32) +#define WIN32_LEAN_AND_MEAN +#include +static inline uintptr_t _mi_thread_id(void) mi_attr_noexcept { + // Windows: works on Intel and ARM in both 32- and 64-bit + return (uintptr_t)NtCurrentTeb(); +} + +#elif defined(__GNUC__) && \ + (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || defined(__aarch64__)) + +// TLS register on x86 is in the FS or GS register, see: https://akkadia.org/drepper/tls.pdf +static inline void* mi_tls_slot(size_t slot) mi_attr_noexcept { + void* res; + const size_t ofs = (slot*sizeof(void*)); +#if defined(__i386__) + __asm__("movl %%gs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // 32-bit always uses GS +#elif defined(__MACH__) && defined(__x86_64__) + __asm__("movq %%gs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86_64 macOSX uses GS +#elif defined(__x86_64__) + __asm__("movq %%fs:%1, %0" : "=r" (res) : "m" (*((void**)ofs)) : ); // x86_64 Linux, BSD uses FS +#elif defined(__arm__) + void** tcb; UNUSED(ofs); + asm volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb)); + res = tcb[slot]; +#elif defined(__aarch64__) + void** tcb; UNUSED(ofs); + asm volatile ("mrs %0, tpidr_el0" : "=r" (tcb)); + res = tcb[slot]; +#endif + return res; +} + +// setting is only used on macOSX for now +static inline void mi_tls_slot_set(size_t slot, void* value) mi_attr_noexcept { + const size_t ofs = (slot*sizeof(void*)); +#if defined(__i386__) + __asm__("movl %1,%%gs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // 32-bit always uses GS +#elif defined(__MACH__) && defined(__x86_64__) + __asm__("movq %1,%%gs:%0" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x86_64 macOSX uses GS +#elif defined(__x86_64__) + __asm__("movq %1,%%fs:%1" : "=m" (*((void**)ofs)) : "rn" (value) : ); // x86_64 Linux, BSD uses FS +#elif defined(__arm__) + void** tcb; UNUSED(ofs); + asm volatile ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tcb)); + tcb[slot] = value; +#elif defined(__aarch64__) + void** tcb; UNUSED(ofs); + asm volatile ("mrs %0, tpidr_el0" : "=r" (tcb)); + tcb[slot] = value; +#endif +} + +static inline uintptr_t _mi_thread_id(void) mi_attr_noexcept { + // in all our targets, slot 0 is the pointer to the thread control block + return (uintptr_t)mi_tls_slot(0); +} +#else +// otherwise use standard C +static inline uintptr_t _mi_thread_id(void) mi_attr_noexcept { + return (uintptr_t)&_mi_heap_default; +} +#endif + + +#endif diff --git a/extlib/mimalloc/include/mimalloc-new-delete.h b/extlib/mimalloc/include/mimalloc-new-delete.h new file mode 100644 index 0000000..fded0c0 --- /dev/null +++ b/extlib/mimalloc/include/mimalloc-new-delete.h @@ -0,0 +1,52 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018,2019 Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_NEW_DELETE_H +#define MIMALLOC_NEW_DELETE_H + +// ---------------------------------------------------------------------------- +// This header provides convenient overrides for the new and +// delete operations in C++. +// +// This header should be included in only one source file! +// +// On Windows, or when linking dynamically with mimalloc, these +// can be more performant than the standard new-delete operations. +// See +// --------------------------------------------------------------------------- +#if defined(__cplusplus) + #include + #include + + void operator delete(void* p) noexcept { mi_free(p); }; + void operator delete[](void* p) noexcept { mi_free(p); }; + + void* operator new(std::size_t n) noexcept(false) { return mi_new(n); } + void* operator new[](std::size_t n) noexcept(false) { return mi_new(n); } + + void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); } + void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { (void)(tag); return mi_new_nothrow(n); } + + #if (__cplusplus >= 201402L || _MSC_VER >= 1916) + void operator delete (void* p, std::size_t n) noexcept { mi_free_size(p,n); }; + void operator delete[](void* p, std::size_t n) noexcept { mi_free_size(p,n); }; + #endif + + #if (__cplusplus > 201402L || defined(__cpp_aligned_new)) + void operator delete (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } + void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } + void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; + void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; + + void* operator new( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } + void* operator new[]( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } + void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } + void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } + #endif +#endif + +#endif // MIMALLOC_NEW_DELETE_H diff --git a/extlib/mimalloc/include/mimalloc-override.h b/extlib/mimalloc/include/mimalloc-override.h new file mode 100644 index 0000000..201fb8b --- /dev/null +++ b/extlib/mimalloc/include/mimalloc-override.h @@ -0,0 +1,66 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018,2019 Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_OVERRIDE_H +#define MIMALLOC_OVERRIDE_H + +/* ---------------------------------------------------------------------------- +This header can be used to statically redirect malloc/free and new/delete +to the mimalloc variants. This can be useful if one can include this file on +each source file in a project (but be careful when using external code to +not accidentally mix pointers from different allocators). +-----------------------------------------------------------------------------*/ + +#include + +// Standard C allocation +#define malloc(n) mi_malloc(n) +#define calloc(n,c) mi_calloc(n,c) +#define realloc(p,n) mi_realloc(p,n) +#define free(p) mi_free(p) + +#define strdup(s) mi_strdup(s) +#define strndup(s) mi_strndup(s) +#define realpath(f,n) mi_realpath(f,n) + +// Microsoft extensions +#define _expand(p,n) mi_expand(p,n) +#define _msize(p) mi_usable_size(p) +#define _recalloc(p,n,c) mi_recalloc(p,n,c) + +#define _strdup(s) mi_strdup(s) +#define _strndup(s) mi_strndup(s) +#define _wcsdup(s) (wchar_t*)mi_wcsdup((const unsigned short*)(s)) +#define _mbsdup(s) mi_mbsdup(s) +#define _dupenv_s(b,n,v) mi_dupenv_s(b,n,v) +#define _wdupenv_s(b,n,v) mi_wdupenv_s((unsigned short*)(b),n,(const unsigned short*)(v)) + +// Various Posix and Unix variants +#define reallocf(p,n) mi_reallocf(p,n) +#define malloc_size(p) mi_usable_size(p) +#define malloc_usable_size(p) mi_usable_size(p) +#define cfree(p) mi_free(p) + +#define valloc(n) mi_valloc(n) +#define pvalloc(n) mi_pvalloc(n) +#define reallocarray(p,s,n) mi_reallocarray(p,s,n) +#define memalign(a,n) mi_memalign(a,n) +#define aligned_alloc(a,n) mi_aligned_alloc(a,n) +#define posix_memalign(p,a,n) mi_posix_memalign(p,a,n) +#define _posix_memalign(p,a,n) mi_posix_memalign(p,a,n) + +// Microsoft aligned variants +#define _aligned_malloc(n,a) mi_malloc_aligned(n,a) +#define _aligned_realloc(p,n,a) mi_realloc_aligned(p,n,a) +#define _aligned_recalloc(p,s,n,a) mi_aligned_recalloc(p,s,n,a) +#define _aligned_msize(p,a,o) mi_usable_size(p) +#define _aligned_free(p) mi_free(p) +#define _aligned_offset_malloc(n,a,o) mi_malloc_aligned_at(n,a,o) +#define _aligned_offset_realloc(p,n,a,o) mi_realloc_aligned_at(p,n,a,o) +#define _aligned_offset_recalloc(p,s,n,a,o) mi_recalloc_aligned_at(p,s,n,a,o) + +#endif // MIMALLOC_OVERRIDE_H diff --git a/extlib/mimalloc/include/mimalloc-types.h b/extlib/mimalloc/include/mimalloc-types.h new file mode 100644 index 0000000..449e2e4 --- /dev/null +++ b/extlib/mimalloc/include/mimalloc-types.h @@ -0,0 +1,480 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_TYPES_H +#define MIMALLOC_TYPES_H + +#include // ptrdiff_t +#include // uintptr_t, uint16_t, etc +#include // _Atomic + +// Minimal alignment necessary. On most platforms 16 bytes are needed +// due to SSE registers for example. This must be at least `MI_INTPTR_SIZE` +#define MI_MAX_ALIGN_SIZE 16 // sizeof(max_align_t) + +// ------------------------------------------------------ +// Variants +// ------------------------------------------------------ + +// Define NDEBUG in the release version to disable assertions. +// #define NDEBUG + +// Define MI_STAT as 1 to maintain statistics; set it to 2 to have detailed statistics (but costs some performance). +// #define MI_STAT 1 + +// Define MI_SECURE to enable security mitigations +// #define MI_SECURE 1 // guard page around metadata +// #define MI_SECURE 2 // guard page around each mimalloc page +// #define MI_SECURE 3 // encode free lists (detect corrupted free list (buffer overflow), and invalid pointer free) +// #define MI_SECURE 4 // checks for double free. (may be more expensive) + +#if !defined(MI_SECURE) +#define MI_SECURE 0 +#endif + +// Define MI_DEBUG for debug mode +// #define MI_DEBUG 1 // basic assertion checks and statistics, check double free, corrupted free list, and invalid pointer free. +// #define MI_DEBUG 2 // + internal assertion checks +// #define MI_DEBUG 3 // + extensive internal invariant checking (cmake -DMI_DEBUG_FULL=ON) +#if !defined(MI_DEBUG) +#if !defined(NDEBUG) || defined(_DEBUG) +#define MI_DEBUG 2 +#else +#define MI_DEBUG 0 +#endif +#endif + +// Reserve extra padding at the end of each block to be more resilient against heap block overflows. +// The padding can detect byte-precise buffer overflow on free. +#if !defined(MI_PADDING) && (MI_DEBUG>=1) +#define MI_PADDING 1 +#endif + + +// Encoded free lists allow detection of corrupted free lists +// and can detect buffer overflows, modify after free, and double `free`s. +#if (MI_SECURE>=3 || MI_DEBUG>=1 || MI_PADDING > 0) +#define MI_ENCODE_FREELIST 1 +#endif + +// ------------------------------------------------------ +// Platform specific values +// ------------------------------------------------------ + +// ------------------------------------------------------ +// Size of a pointer. +// We assume that `sizeof(void*)==sizeof(intptr_t)` +// and it holds for all platforms we know of. +// +// However, the C standard only requires that: +// p == (void*)((intptr_t)p)) +// but we also need: +// i == (intptr_t)((void*)i) +// or otherwise one might define an intptr_t type that is larger than a pointer... +// ------------------------------------------------------ + +#if INTPTR_MAX == 9223372036854775807LL +# define MI_INTPTR_SHIFT (3) +#elif INTPTR_MAX == 2147483647LL +# define MI_INTPTR_SHIFT (2) +#else +#error platform must be 32 or 64 bits +#endif + +#define MI_INTPTR_SIZE (1<= 655360) +#error "define more bins" +#endif + +// Used as a special value to encode block sizes in 32 bits. +#define MI_HUGE_BLOCK_SIZE ((uint32_t)MI_HUGE_OBJ_SIZE_MAX) + +// The free lists use encoded next fields +// (Only actually encodes when MI_ENCODED_FREELIST is defined.) +typedef uintptr_t mi_encoded_t; + +// free lists contain blocks +typedef struct mi_block_s { + mi_encoded_t next; +} mi_block_t; + + +// The delayed flags are used for efficient multi-threaded free-ing +typedef enum mi_delayed_e { + MI_USE_DELAYED_FREE = 0, // push on the owning heap thread delayed list + MI_DELAYED_FREEING = 1, // temporary: another thread is accessing the owning heap + MI_NO_DELAYED_FREE = 2, // optimize: push on page local thread free queue if another block is already in the heap thread delayed free list + MI_NEVER_DELAYED_FREE = 3 // sticky, only resets on page reclaim +} mi_delayed_t; + + +// The `in_full` and `has_aligned` page flags are put in a union to efficiently +// test if both are false (`full_aligned == 0`) in the `mi_free` routine. +typedef union mi_page_flags_s { + uint8_t full_aligned; + struct { + uint8_t in_full : 1; + uint8_t has_aligned : 1; + } x; +} mi_page_flags_t; + +// Thread free list. +// We use the bottom 2 bits of the pointer for mi_delayed_t flags +typedef uintptr_t mi_thread_free_t; + +// A page contains blocks of one specific size (`block_size`). +// Each page has three list of free blocks: +// `free` for blocks that can be allocated, +// `local_free` for freed blocks that are not yet available to `mi_malloc` +// `thread_free` for freed blocks by other threads +// The `local_free` and `thread_free` lists are migrated to the `free` list +// when it is exhausted. The separate `local_free` list is necessary to +// implement a monotonic heartbeat. The `thread_free` list is needed for +// avoiding atomic operations in the common case. +// +// +// `used - |thread_free|` == actual blocks that are in use (alive) +// `used - |thread_free| + |free| + |local_free| == capacity` +// +// We don't count `freed` (as |free|) but use `used` to reduce +// the number of memory accesses in the `mi_page_all_free` function(s). +// +// Notes: +// - Access is optimized for `mi_free` and `mi_page_alloc` (in `alloc.c`) +// - Using `uint16_t` does not seem to slow things down +// - The size is 8 words on 64-bit which helps the page index calculations +// (and 10 words on 32-bit, and encoded free lists add 2 words. Sizes 10 +// and 12 are still good for address calculation) +// - To limit the structure size, the `xblock_size` is 32-bits only; for +// blocks > MI_HUGE_BLOCK_SIZE the size is determined from the segment page size +// - `thread_free` uses the bottom bits as a delayed-free flags to optimize +// concurrent frees where only the first concurrent free adds to the owning +// heap `thread_delayed_free` list (see `alloc.c:mi_free_block_mt`). +// The invariant is that no-delayed-free is only set if there is +// at least one block that will be added, or as already been added, to +// the owning heap `thread_delayed_free` list. This guarantees that pages +// will be freed correctly even if only other threads free blocks. +typedef struct mi_page_s { + // "owned" by the segment + uint8_t segment_idx; // index in the segment `pages` array, `page == &segment->pages[page->segment_idx]` + uint8_t segment_in_use:1; // `true` if the segment allocated this page + uint8_t is_reset:1; // `true` if the page memory was reset + uint8_t is_committed:1; // `true` if the page virtual memory is committed + uint8_t is_zero_init:1; // `true` if the page was zero initialized + + // layout like this to optimize access in `mi_malloc` and `mi_free` + uint16_t capacity; // number of blocks committed, must be the first field, see `segment.c:page_clear` + uint16_t reserved; // number of blocks reserved in memory + mi_page_flags_t flags; // `in_full` and `has_aligned` flags (8 bits) + uint8_t is_zero:1; // `true` if the blocks in the free list are zero initialized + uint8_t retire_expire:7; // expiration count for retired blocks + + mi_block_t* free; // list of available free blocks (`malloc` allocates from this list) + #ifdef MI_ENCODE_FREELIST + uintptr_t keys[2]; // two random keys to encode the free lists (see `_mi_block_next`) + #endif + uint32_t used; // number of blocks in use (including blocks in `local_free` and `thread_free`) + uint32_t xblock_size; // size available in each block (always `>0`) + + mi_block_t* local_free; // list of deferred free blocks by this thread (migrates to `free`) + volatile _Atomic(mi_thread_free_t) xthread_free; // list of deferred free blocks freed by other threads + volatile _Atomic(uintptr_t) xheap; + + struct mi_page_s* next; // next page owned by this thread with the same `block_size` + struct mi_page_s* prev; // previous page owned by this thread with the same `block_size` +} mi_page_t; + + + +typedef enum mi_page_kind_e { + MI_PAGE_SMALL, // small blocks go into 64kb pages inside a segment + MI_PAGE_MEDIUM, // medium blocks go into 512kb pages inside a segment + MI_PAGE_LARGE, // larger blocks go into a single page spanning a whole segment + MI_PAGE_HUGE // huge blocks (>512kb) are put into a single page in a segment of the exact size (but still 2mb aligned) +} mi_page_kind_t; + +// Segments are large allocated memory blocks (2mb on 64 bit) from +// the OS. Inside segments we allocated fixed size _pages_ that +// contain blocks. +typedef struct mi_segment_s { + // memory fields + size_t memid; // id for the os-level memory manager + bool mem_is_fixed; // `true` if we cannot decommit/reset/protect in this memory (i.e. when allocated using large OS pages) + bool mem_is_committed; // `true` if the whole segment is eagerly committed + + // segment fields + struct mi_segment_s* next; // must be the first segment field -- see `segment.c:segment_alloc` + struct mi_segment_s* prev; + struct mi_segment_s* abandoned_next; + size_t abandoned; // abandoned pages (i.e. the original owning thread stopped) (`abandoned <= used`) + size_t abandoned_visits; // count how often this segment is visited in the abandoned list (to force reclaim it it is too long) + + size_t used; // count of pages in use (`used <= capacity`) + size_t capacity; // count of available pages (`#free + used`) + size_t segment_size;// for huge pages this may be different from `MI_SEGMENT_SIZE` + size_t segment_info_size; // space we are using from the first page for segment meta-data and possible guard pages. + uintptr_t cookie; // verify addresses in secure mode: `_mi_ptr_cookie(segment) == segment->cookie` + + // layout like this to optimize access in `mi_free` + size_t page_shift; // `1 << page_shift` == the page sizes == `page->block_size * page->reserved` (unless the first page, then `-segment_info_size`). + volatile _Atomic(uintptr_t) thread_id; // unique id of the thread owning this segment + mi_page_kind_t page_kind; // kind of pages: small, large, or huge + mi_page_t pages[1]; // up to `MI_SMALL_PAGES_PER_SEGMENT` pages +} mi_segment_t; + + +// ------------------------------------------------------ +// Heaps +// Provide first-class heaps to allocate from. +// A heap just owns a set of pages for allocation and +// can only be allocate/reallocate from the thread that created it. +// Freeing blocks can be done from any thread though. +// Per thread, the segments are shared among its heaps. +// Per thread, there is always a default heap that is +// used for allocation; it is initialized to statically +// point to an empty heap to avoid initialization checks +// in the fast path. +// ------------------------------------------------------ + +// Thread local data +typedef struct mi_tld_s mi_tld_t; + +// Pages of a certain block size are held in a queue. +typedef struct mi_page_queue_s { + mi_page_t* first; + mi_page_t* last; + size_t block_size; +} mi_page_queue_t; + +#define MI_BIN_FULL (MI_BIN_HUGE+1) + +// Random context +typedef struct mi_random_cxt_s { + uint32_t input[16]; + uint32_t output[16]; + int output_available; +} mi_random_ctx_t; + + +// In debug mode there is a padding stucture at the end of the blocks to check for buffer overflows +#if (MI_PADDING) +typedef struct mi_padding_s { + uint32_t canary; // encoded block value to check validity of the padding (in case of overflow) + uint32_t delta; // padding bytes before the block. (mi_usable_size(p) - delta == exact allocated bytes) +} mi_padding_t; +#define MI_PADDING_SIZE (sizeof(mi_padding_t)) +#define MI_PADDING_WSIZE ((MI_PADDING_SIZE + MI_INTPTR_SIZE - 1) / MI_INTPTR_SIZE) +#else +#define MI_PADDING_SIZE 0 +#define MI_PADDING_WSIZE 0 +#endif + +#define MI_PAGES_DIRECT (MI_SMALL_WSIZE_MAX + MI_PADDING_WSIZE + 1) + + +// A heap owns a set of pages. +struct mi_heap_s { + mi_tld_t* tld; + mi_page_t* pages_free_direct[MI_PAGES_DIRECT]; // optimize: array where every entry points a page with possibly free blocks in the corresponding queue for that size. + mi_page_queue_t pages[MI_BIN_FULL + 1]; // queue of pages for each size class (or "bin") + volatile _Atomic(mi_block_t*) thread_delayed_free; + uintptr_t thread_id; // thread this heap belongs too + uintptr_t cookie; // random cookie to verify pointers (see `_mi_ptr_cookie`) + uintptr_t keys[2]; // two random keys used to encode the `thread_delayed_free` list + mi_random_ctx_t random; // random number context used for secure allocation + size_t page_count; // total number of pages in the `pages` queues. + size_t page_retired_min; // smallest retired index (retired pages are fully free, but still in the page queues) + size_t page_retired_max; // largest retired index into the `pages` array. + mi_heap_t* next; // list of heaps per thread + bool no_reclaim; // `true` if this heap should not reclaim abandoned pages +}; + + + +// ------------------------------------------------------ +// Debug +// ------------------------------------------------------ + +#define MI_DEBUG_UNINIT (0xD0) +#define MI_DEBUG_FREED (0xDF) +#define MI_DEBUG_PADDING (0xDE) + +#if (MI_DEBUG) +// use our own assertion to print without memory allocation +void _mi_assert_fail(const char* assertion, const char* fname, unsigned int line, const char* func ); +#define mi_assert(expr) ((expr) ? (void)0 : _mi_assert_fail(#expr,__FILE__,__LINE__,__func__)) +#else +#define mi_assert(x) +#endif + +#if (MI_DEBUG>1) +#define mi_assert_internal mi_assert +#else +#define mi_assert_internal(x) +#endif + +#if (MI_DEBUG>2) +#define mi_assert_expensive mi_assert +#else +#define mi_assert_expensive(x) +#endif + +// ------------------------------------------------------ +// Statistics +// ------------------------------------------------------ + +#ifndef MI_STAT +#if (MI_DEBUG>0) +#define MI_STAT 2 +#else +#define MI_STAT 0 +#endif +#endif + +typedef struct mi_stat_count_s { + int64_t allocated; + int64_t freed; + int64_t peak; + int64_t current; +} mi_stat_count_t; + +typedef struct mi_stat_counter_s { + int64_t total; + int64_t count; +} mi_stat_counter_t; + +typedef struct mi_stats_s { + mi_stat_count_t segments; + mi_stat_count_t pages; + mi_stat_count_t reserved; + mi_stat_count_t committed; + mi_stat_count_t reset; + mi_stat_count_t page_committed; + mi_stat_count_t segments_abandoned; + mi_stat_count_t pages_abandoned; + mi_stat_count_t threads; + mi_stat_count_t huge; + mi_stat_count_t giant; + mi_stat_count_t malloc; + mi_stat_count_t segments_cache; + mi_stat_counter_t pages_extended; + mi_stat_counter_t mmap_calls; + mi_stat_counter_t commit_calls; + mi_stat_counter_t page_no_retire; + mi_stat_counter_t searches; + mi_stat_counter_t huge_count; + mi_stat_counter_t giant_count; +#if MI_STAT>1 + mi_stat_count_t normal[MI_BIN_HUGE+1]; +#endif +} mi_stats_t; + + +void _mi_stat_increase(mi_stat_count_t* stat, size_t amount); +void _mi_stat_decrease(mi_stat_count_t* stat, size_t amount); +void _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount); + +#if (MI_STAT) +#define mi_stat_increase(stat,amount) _mi_stat_increase( &(stat), amount) +#define mi_stat_decrease(stat,amount) _mi_stat_decrease( &(stat), amount) +#define mi_stat_counter_increase(stat,amount) _mi_stat_counter_increase( &(stat), amount) +#else +#define mi_stat_increase(stat,amount) (void)0 +#define mi_stat_decrease(stat,amount) (void)0 +#define mi_stat_counter_increase(stat,amount) (void)0 +#endif + +#define mi_heap_stat_increase(heap,stat,amount) mi_stat_increase( (heap)->tld->stats.stat, amount) +#define mi_heap_stat_decrease(heap,stat,amount) mi_stat_decrease( (heap)->tld->stats.stat, amount) + +// ------------------------------------------------------ +// Thread Local data +// ------------------------------------------------------ + +typedef int64_t mi_msecs_t; + +// Queue of segments +typedef struct mi_segment_queue_s { + mi_segment_t* first; + mi_segment_t* last; +} mi_segment_queue_t; + +// OS thread local data +typedef struct mi_os_tld_s { + size_t region_idx; // start point for next allocation + mi_stats_t* stats; // points to tld stats +} mi_os_tld_t; + +// Segments thread local data +typedef struct mi_segments_tld_s { + mi_segment_queue_t small_free; // queue of segments with free small pages + mi_segment_queue_t medium_free; // queue of segments with free medium pages + mi_page_queue_t pages_reset; // queue of freed pages that can be reset + size_t count; // current number of segments; + size_t peak_count; // peak number of segments + size_t current_size; // current size of all segments + size_t peak_size; // peak size of all segments + size_t cache_count; // number of segments in the cache + size_t cache_size; // total size of all segments in the cache + mi_segment_t* cache; // (small) cache of segments + mi_stats_t* stats; // points to tld stats + mi_os_tld_t* os; // points to os stats +} mi_segments_tld_t; + +// Thread local data +struct mi_tld_s { + unsigned long long heartbeat; // monotonic heartbeat count + bool recurse; // true if deferred was called; used to prevent infinite recursion. + mi_heap_t* heap_backing; // backing heap of this thread (cannot be deleted) + mi_heap_t* heaps; // list of heaps in this thread (so we can abandon all when the thread terminates) + mi_segments_tld_t segments; // segment tld + mi_os_tld_t os; // os tld + mi_stats_t stats; // statistics +}; + +#endif diff --git a/extlib/mimalloc/include/mimalloc.h b/extlib/mimalloc/include/mimalloc.h new file mode 100644 index 0000000..8dd318c --- /dev/null +++ b/extlib/mimalloc/include/mimalloc.h @@ -0,0 +1,426 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018-2020, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#pragma once +#ifndef MIMALLOC_H +#define MIMALLOC_H + +#define MI_MALLOC_VERSION 164 // major + 2 digits minor + +// ------------------------------------------------------ +// Compiler specific attributes +// ------------------------------------------------------ + +#ifdef __cplusplus + #if (__cplusplus >= 201103L) || (_MSC_VER > 1900) // C++11 + #define mi_attr_noexcept noexcept + #else + #define mi_attr_noexcept throw() + #endif +#else + #define mi_attr_noexcept +#endif + +#if (__cplusplus >= 201703) + #define mi_decl_nodiscard [[nodiscard]] +#elif (__GNUC__ >= 4) || defined(__clang__) // includes clang, icc, and clang-cl + #define mi_decl_nodiscard __attribute__((warn_unused_result)) +#elif (_MSC_VER >= 1700) + #define mi_decl_nodiscard _Check_return_ +#else + #define mi_decl_nodiscard +#endif + +#if defined(_MSC_VER) || defined(__MINGW32__) + #if !defined(MI_SHARED_LIB) + #define mi_decl_export + #elif defined(MI_SHARED_LIB_EXPORT) + #define mi_decl_export __declspec(dllexport) + #else + #define mi_decl_export __declspec(dllimport) + #endif + #if defined(__MINGW32__) + #define mi_decl_restrict + #define mi_attr_malloc __attribute__((malloc)) + #else + #if (_MSC_VER >= 1900) && !defined(__EDG__) + #define mi_decl_restrict __declspec(allocator) __declspec(restrict) + #else + #define mi_decl_restrict __declspec(restrict) + #endif + #define mi_attr_malloc + #endif + #define mi_cdecl __cdecl + #define mi_attr_alloc_size(s) + #define mi_attr_alloc_size2(s1,s2) + #define mi_attr_alloc_align(p) +#elif defined(__GNUC__) // includes clang and icc + #define mi_cdecl // leads to warnings... __attribute__((cdecl)) + #define mi_decl_export __attribute__((visibility("default"))) + #define mi_decl_restrict + #define mi_attr_malloc __attribute__((malloc)) + #if (defined(__clang_major__) && (__clang_major__ < 4)) || (__GNUC__ < 5) + #define mi_attr_alloc_size(s) + #define mi_attr_alloc_size2(s1,s2) + #define mi_attr_alloc_align(p) + #elif defined(__INTEL_COMPILER) + #define mi_attr_alloc_size(s) __attribute__((alloc_size(s))) + #define mi_attr_alloc_size2(s1,s2) __attribute__((alloc_size(s1,s2))) + #define mi_attr_alloc_align(p) + #else + #define mi_attr_alloc_size(s) __attribute__((alloc_size(s))) + #define mi_attr_alloc_size2(s1,s2) __attribute__((alloc_size(s1,s2))) + #define mi_attr_alloc_align(p) __attribute__((alloc_align(p))) + #endif +#else + #define mi_cdecl + #define mi_decl_export + #define mi_decl_restrict + #define mi_attr_malloc + #define mi_attr_alloc_size(s) + #define mi_attr_alloc_size2(s1,s2) + #define mi_attr_alloc_align(p) +#endif + +// ------------------------------------------------------ +// Includes +// ------------------------------------------------------ + +#include // size_t +#include // bool + +#ifdef __cplusplus +extern "C" { +#endif + +// ------------------------------------------------------ +// Standard malloc interface +// ------------------------------------------------------ + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc(size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); +mi_decl_nodiscard mi_decl_export void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); +mi_decl_export void* mi_expand(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); + +mi_decl_export void mi_free(void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_strdup(const char* s) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_strndup(const char* s, size_t n) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept mi_attr_malloc; + +// ------------------------------------------------------ +// Extended functionality +// ------------------------------------------------------ +#define MI_SMALL_WSIZE_MAX (128) +#define MI_SMALL_SIZE_MAX (MI_SMALL_WSIZE_MAX*sizeof(void*)) + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_small(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); +mi_decl_nodiscard mi_decl_export void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3); +mi_decl_nodiscard mi_decl_export void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); + +mi_decl_nodiscard mi_decl_export size_t mi_usable_size(const void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_good_size(size_t size) mi_attr_noexcept; + + +// ------------------------------------------------------ +// Internals +// ------------------------------------------------------ + +typedef void (mi_cdecl mi_deferred_free_fun)(bool force, unsigned long long heartbeat, void* arg); +mi_decl_export void mi_register_deferred_free(mi_deferred_free_fun* deferred_free, void* arg) mi_attr_noexcept; + +typedef void (mi_cdecl mi_output_fun)(const char* msg, void* arg); +mi_decl_export void mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept; + +typedef void (mi_cdecl mi_error_fun)(int err, void* arg); +mi_decl_export void mi_register_error(mi_error_fun* fun, void* arg); + +mi_decl_export void mi_collect(bool force) mi_attr_noexcept; +mi_decl_export int mi_version(void) mi_attr_noexcept; +mi_decl_export void mi_stats_reset(void) mi_attr_noexcept; +mi_decl_export void mi_stats_merge(void) mi_attr_noexcept; +mi_decl_export void mi_stats_print(void* out) mi_attr_noexcept; // backward compatibility: `out` is ignored and should be NULL +mi_decl_export void mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept; + +mi_decl_export void mi_process_init(void) mi_attr_noexcept; +mi_decl_export void mi_thread_init(void) mi_attr_noexcept; +mi_decl_export void mi_thread_done(void) mi_attr_noexcept; +mi_decl_export void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept; + + +// ------------------------------------------------------------------------------------- +// Aligned allocation +// Note that `alignment` always follows `size` for consistency with unaligned +// allocation, but unfortunately this differs from `posix_memalign` and `aligned_alloc`. +// ------------------------------------------------------------------------------------- + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(1,2); +mi_decl_nodiscard mi_decl_export void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(2); + + +// ------------------------------------------------------------------------------------- +// Heaps: first-class, but can only allocate from the same thread that created it. +// ------------------------------------------------------------------------------------- + +struct mi_heap_s; +typedef struct mi_heap_s mi_heap_t; + +mi_decl_nodiscard mi_decl_export mi_heap_t* mi_heap_new(void); +mi_decl_export void mi_heap_delete(mi_heap_t* heap); +mi_decl_export void mi_heap_destroy(mi_heap_t* heap); +mi_decl_export mi_heap_t* mi_heap_set_default(mi_heap_t* heap); +mi_decl_export mi_heap_t* mi_heap_get_default(void); +mi_decl_export mi_heap_t* mi_heap_get_backing(void); +mi_decl_export void mi_heap_collect(mi_heap_t* heap, bool force) mi_attr_noexcept; + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); + +mi_decl_nodiscard mi_decl_export void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3); +mi_decl_nodiscard mi_decl_export void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(3,4);; +mi_decl_nodiscard mi_decl_export void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3); + +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept mi_attr_malloc; + +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3) mi_attr_alloc_align(4); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size2(2, 3); +mi_decl_nodiscard mi_decl_export void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(3) mi_attr_alloc_align(4); +mi_decl_nodiscard mi_decl_export void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(3); + + +// -------------------------------------------------------------------------------- +// Zero initialized re-allocation. +// Only valid on memory that was originally allocated with zero initialization too. +// e.g. `mi_calloc`, `mi_zalloc`, `mi_zalloc_aligned` etc. +// see +// -------------------------------------------------------------------------------- + +mi_decl_nodiscard mi_decl_export void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export void* mi_recalloc(void* p, size_t newcount, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3); + +mi_decl_nodiscard mi_decl_export void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(2) mi_attr_alloc_align(3); +mi_decl_nodiscard mi_decl_export void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_alloc_size2(2,3) mi_attr_alloc_align(4); +mi_decl_nodiscard mi_decl_export void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size2(2,3); + +mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept mi_attr_alloc_size(3); +mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t newcount, size_t size) mi_attr_noexcept mi_attr_alloc_size2(3,4); + +mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept mi_attr_alloc_size(3) mi_attr_alloc_align(4); +mi_decl_nodiscard mi_decl_export void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size(3); +mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept mi_attr_alloc_size2(3,4) mi_attr_alloc_align(5); +mi_decl_nodiscard mi_decl_export void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept mi_attr_alloc_size2(3,4); + + +// ------------------------------------------------------ +// Analysis +// ------------------------------------------------------ + +mi_decl_export bool mi_heap_contains_block(mi_heap_t* heap, const void* p); +mi_decl_export bool mi_heap_check_owned(mi_heap_t* heap, const void* p); +mi_decl_export bool mi_check_owned(const void* p); + +// An area of heap space contains blocks of a single size. +typedef struct mi_heap_area_s { + void* blocks; // start of the area containing heap blocks + size_t reserved; // bytes reserved for this area (virtual) + size_t committed; // current available bytes for this area + size_t used; // bytes in use by allocated blocks + size_t block_size; // size in bytes of each block +} mi_heap_area_t; + +typedef bool (mi_cdecl mi_block_visit_fun)(const mi_heap_t* heap, const mi_heap_area_t* area, void* block, size_t block_size, void* arg); + +mi_decl_export bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_all_blocks, mi_block_visit_fun* visitor, void* arg); + +// Experimental +mi_decl_nodiscard mi_decl_export bool mi_is_in_heap_region(const void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export bool mi_is_redirected() mi_attr_noexcept; + +mi_decl_export int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept; +mi_decl_export int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept; + +// deprecated +mi_decl_export int mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept; + + +// ------------------------------------------------------ +// Convenience +// ------------------------------------------------------ + +#define mi_malloc_tp(tp) ((tp*)mi_malloc(sizeof(tp))) +#define mi_zalloc_tp(tp) ((tp*)mi_zalloc(sizeof(tp))) +#define mi_calloc_tp(tp,n) ((tp*)mi_calloc(n,sizeof(tp))) +#define mi_mallocn_tp(tp,n) ((tp*)mi_mallocn(n,sizeof(tp))) +#define mi_reallocn_tp(p,tp,n) ((tp*)mi_reallocn(p,n,sizeof(tp))) +#define mi_recalloc_tp(p,tp,n) ((tp*)mi_recalloc(p,n,sizeof(tp))) + +#define mi_heap_malloc_tp(hp,tp) ((tp*)mi_heap_malloc(hp,sizeof(tp))) +#define mi_heap_zalloc_tp(hp,tp) ((tp*)mi_heap_zalloc(hp,sizeof(tp))) +#define mi_heap_calloc_tp(hp,tp,n) ((tp*)mi_heap_calloc(hp,n,sizeof(tp))) +#define mi_heap_mallocn_tp(hp,tp,n) ((tp*)mi_heap_mallocn(hp,n,sizeof(tp))) +#define mi_heap_reallocn_tp(hp,p,tp,n) ((tp*)mi_heap_reallocn(hp,p,n,sizeof(tp))) +#define mi_heap_recalloc_tp(hp,p,tp,n) ((tp*)mi_heap_recalloc(hp,p,n,sizeof(tp))) + + +// ------------------------------------------------------ +// Options, all `false` by default +// ------------------------------------------------------ + +typedef enum mi_option_e { + // stable options + mi_option_show_errors, + mi_option_show_stats, + mi_option_verbose, + // the following options are experimental + mi_option_eager_commit, + mi_option_eager_region_commit, + mi_option_reset_decommits, + mi_option_large_os_pages, // implies eager commit + mi_option_reserve_huge_os_pages, + mi_option_segment_cache, + mi_option_page_reset, + mi_option_abandoned_page_reset, + mi_option_segment_reset, + mi_option_eager_commit_delay, + mi_option_reset_delay, + mi_option_use_numa_nodes, + mi_option_os_tag, + mi_option_max_errors, + _mi_option_last +} mi_option_t; + + +mi_decl_nodiscard mi_decl_export bool mi_option_is_enabled(mi_option_t option); +mi_decl_export void mi_option_enable(mi_option_t option); +mi_decl_export void mi_option_disable(mi_option_t option); +mi_decl_export void mi_option_set_enabled(mi_option_t option, bool enable); +mi_decl_export void mi_option_set_enabled_default(mi_option_t option, bool enable); + +mi_decl_nodiscard mi_decl_export long mi_option_get(mi_option_t option); +mi_decl_export void mi_option_set(mi_option_t option, long value); +mi_decl_export void mi_option_set_default(mi_option_t option, long value); + + +// ------------------------------------------------------------------------------------------------------- +// "mi" prefixed implementations of various posix, Unix, Windows, and C++ allocation functions. +// (This can be convenient when providing overrides of these functions as done in `mimalloc-override.h`.) +// note: we use `mi_cfree` as "checked free" and it checks if the pointer is in our heap before free-ing. +// ------------------------------------------------------------------------------------------------------- + +mi_decl_export void mi_cfree(void* p) mi_attr_noexcept; +mi_decl_export void* mi__expand(void* p, size_t newsize) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_malloc_size(const void* p) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept; + +mi_decl_export int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_valloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(2) mi_attr_alloc_align(1); + +mi_decl_nodiscard mi_decl_export void* mi_reallocarray(void* p, size_t count, size_t size) mi_attr_noexcept mi_attr_alloc_size2(2,3); +mi_decl_nodiscard mi_decl_export void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept; +mi_decl_nodiscard mi_decl_export void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept; + +mi_decl_nodiscard mi_decl_export mi_decl_restrict unsigned short* mi_wcsdup(const unsigned short* s) mi_attr_noexcept mi_attr_malloc; +mi_decl_nodiscard mi_decl_export mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s) mi_attr_noexcept mi_attr_malloc; +mi_decl_export int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept; +mi_decl_export int mi_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name) mi_attr_noexcept; + +mi_decl_export void mi_free_size(void* p, size_t size) mi_attr_noexcept; +mi_decl_export void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept; +mi_decl_export void mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept; + +// The `mi_new` wrappers implement C++ semantics on out-of-memory instead of directly returning `NULL`. +// (and call `std::get_new_handler` and potentially raise a `std::bad_alloc` exception). +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new(size_t size) mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_aligned(size_t size, size_t alignment) mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_nothrow(size_t size) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_aligned_nothrow(size_t size, size_t alignment) mi_attr_noexcept mi_attr_malloc mi_attr_alloc_size(1) mi_attr_alloc_align(2); +mi_decl_nodiscard mi_decl_export mi_decl_restrict void* mi_new_n(size_t count, size_t size) mi_attr_malloc mi_attr_alloc_size2(1, 2); +mi_decl_nodiscard mi_decl_export void* mi_new_realloc(void* p, size_t newsize) mi_attr_alloc_size(2); +mi_decl_nodiscard mi_decl_export void* mi_new_reallocn(void* p, size_t newcount, size_t size) mi_attr_alloc_size2(2, 3); + +#ifdef __cplusplus +} +#endif + +// --------------------------------------------------------------------------------------------- +// Implement the C++ std::allocator interface for use in STL containers. +// (note: see `mimalloc-new-delete.h` for overriding the new/delete operators globally) +// --------------------------------------------------------------------------------------------- +#ifdef __cplusplus + +#include // PTRDIFF_MAX +#if (__cplusplus >= 201103L) || (_MSC_VER > 1900) // C++11 +#include // std::true_type +#include // std::forward +#endif + +template struct mi_stl_allocator { + typedef T value_type; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef value_type& reference; + typedef value_type const& const_reference; + typedef value_type* pointer; + typedef value_type const* const_pointer; + template struct rebind { typedef mi_stl_allocator other; }; + + mi_stl_allocator() mi_attr_noexcept = default; + mi_stl_allocator(const mi_stl_allocator&) mi_attr_noexcept = default; + template mi_stl_allocator(const mi_stl_allocator&) mi_attr_noexcept { } + mi_stl_allocator select_on_container_copy_construction() const { return *this; } + void deallocate(T* p, size_type) { mi_free(p); } + + #if (__cplusplus >= 201703L) // C++17 + mi_decl_nodiscard T* allocate(size_type count) { return static_cast(mi_new_n(count, sizeof(T))); } + mi_decl_nodiscard T* allocate(size_type count, const void*) { return allocate(count); } + #else + mi_decl_nodiscard pointer allocate(size_type count, const void* = 0) { return static_cast(mi_new_n(count, sizeof(value_type))); } + #endif + + #if ((__cplusplus >= 201103L) || (_MSC_VER > 1900)) // C++11 + using propagate_on_container_copy_assignment = std::true_type; + using propagate_on_container_move_assignment = std::true_type; + using propagate_on_container_swap = std::true_type; + using is_always_equal = std::true_type; + template void construct(U* p, Args&& ...args) { ::new(p) U(std::forward(args)...); } + template void destroy(U* p) mi_attr_noexcept { p->~U(); } + #else + void construct(pointer p, value_type const& val) { ::new(p) value_type(val); } + void destroy(pointer p) { p->~value_type(); } + #endif + + size_type max_size() const mi_attr_noexcept { return (PTRDIFF_MAX/sizeof(value_type)); } + pointer address(reference x) const { return &x; } + const_pointer address(const_reference x) const { return &x; } +}; + +template bool operator==(const mi_stl_allocator& , const mi_stl_allocator& ) mi_attr_noexcept { return true; } +template bool operator!=(const mi_stl_allocator& , const mi_stl_allocator& ) mi_attr_noexcept { return false; } +#endif // __cplusplus + +#endif diff --git a/extlib/mimalloc/readme.md b/extlib/mimalloc/readme.md new file mode 100644 index 0000000..daf57f3 --- /dev/null +++ b/extlib/mimalloc/readme.md @@ -0,0 +1,583 @@ + + + +[](https://dev.azure.com/Daan0324/mimalloc/_build?definitionId=1&_a=summary) + +# mimalloc + +  + +mimalloc (pronounced "me-malloc") +is a general purpose allocator with excellent [performance](#performance) characteristics. +Initially developed by Daan Leijen for the run-time systems of the +[Koka](https://github.com/koka-lang/koka) and [Lean](https://github.com/leanprover/lean) languages. +Latest release:`v1.6.4` (2020-08-06). + +It is a drop-in replacement for `malloc` and can be used in other programs +without code changes, for example, on dynamically linked ELF-based systems (Linux, BSD, etc.) you can use it as: +``` +> LD_PRELOAD=/usr/bin/libmimalloc.so myprogram +``` +It also has an easy way to override the allocator in [Windows](#override_on_windows). Notable aspects of the design include: + +- __small and consistent__: the library is about 6k LOC using simple and + consistent data structures. This makes it very suitable + to integrate and adapt in other projects. For runtime systems it + provides hooks for a monotonic _heartbeat_ and deferred freeing (for + bounded worst-case times with reference counting). +- __free list sharding__: the big idea: instead of one big free list (per size class) we have + many smaller lists per memory "page" which both reduces fragmentation + and increases locality -- + things that are allocated close in time get allocated close in memory. + (A memory "page" in _mimalloc_ contains blocks of one size class and is + usually 64KiB on a 64-bit system). +- __eager page reset__: when a "page" becomes empty (with increased chance + due to free list sharding) the memory is marked to the OS as unused ("reset" or "purged") + reducing (real) memory pressure and fragmentation, especially in long running + programs. +- __secure__: _mimalloc_ can be built in secure mode, adding guard pages, + randomized allocation, encrypted free lists, etc. to protect against various + heap vulnerabilities. The performance penalty is usually around 10% on average + over our benchmarks. +- __first-class heaps__: efficiently create and use multiple heaps to allocate across different regions. + A heap can be destroyed at once instead of deallocating each object separately. +- __bounded__: it does not suffer from _blowup_ \[1\], has bounded worst-case allocation + times (_wcat_), bounded space overhead (~0.2% meta-data, with at most 12.5% waste in allocation sizes), + and has no internal points of contention using only atomic operations. +- __fast__: In our benchmarks (see [below](#performance)), + _mimalloc_ outperforms other leading allocators (_jemalloc_, _tcmalloc_, _Hoard_, etc), + and usually uses less memory (up to 25% more in the worst case). A nice property + is that it does consistently well over a wide range of benchmarks. There is also good huge OS page + support for larger server programs. + +The [documentation](https://microsoft.github.io/mimalloc) gives a full overview of the API. +You can read more on the design of _mimalloc_ in the [technical report](https://www.microsoft.com/en-us/research/publication/mimalloc-free-list-sharding-in-action) which also has detailed benchmark results. + +Enjoy! + +### Releases + +* 2020-08-06, `v1.6.4`: stable release 1.6: improved error recovery in low-memory situations, + support for IllumOS and Haiku, NUMA support for Vista/XP, improved NUMA detection for AMD Ryzen, ubsan support. +* 2020-05-05, `v1.6.3`: stable release 1.6: improved behavior in out-of-memory situations, improved malloc zones on macOS, + build PIC static libraries by default, add option to abort on out-of-memory, line buffered statistics. +* 2020-04-20, `v1.6.2`: stable release 1.6: fix compilation on Android, MingW, Raspberry, and Conda, + stability fix for Windows 7, fix multiple mimalloc instances in one executable, fix `strnlen` overload, + fix aligned debug padding. +* 2020-02-17, `v1.6.1`: stable release 1.6: minor updates (build with clang-cl, fix alignment issue for small objects). +* 2020-02-09, `v1.6.0`: stable release 1.6: fixed potential memory leak, improved overriding + and thread local support on FreeBSD, NetBSD, DragonFly, and macOSX. New byte-precise + heap block overflow detection in debug mode (besides the double-free detection and free-list + corruption detection). Add `nodiscard` attribute to most allocation functions. + Enable `MIMALLOC_PAGE_RESET` by default. New reclamation strategy for abandoned heap pages + for better memory footprint. +* 2020-02-09, `v1.5.0`: stable release 1.5: improved free performance, small bug fixes. +* 2020-01-22, `v1.4.0`: stable release 1.4: improved performance for delayed OS page reset, +more eager concurrent free, addition of STL allocator, fixed potential memory leak. +* 2020-01-15, `v1.3.0`: stable release 1.3: bug fixes, improved randomness and [stronger +free list encoding](https://github.com/microsoft/mimalloc/blob/783e3377f79ee82af43a0793910a9f2d01ac7863/include/mimalloc-internal.h#L396) in secure mode. +* 2019-12-22, `v1.2.2`: stable release 1.2: minor updates. +* 2019-11-22, `v1.2.0`: stable release 1.2: bug fixes, improved secure mode (free list corruption checks, double free mitigation). Improved dynamic overriding on Windows. +* 2019-10-07, `v1.1.0`: stable release 1.1. +* 2019-09-01, `v1.0.8`: pre-release 8: more robust windows dynamic overriding, initial huge page support. +* 2019-08-10, `v1.0.6`: pre-release 6: various performance improvements. + +Special thanks to: + +* Jason Gibson (@jasongibson) for exhaustive testing on large workloads and server environments and finding complex bugs in (early versions of) `mimalloc`. +* Manuel Pöter (@mpoeter) and Sam Gross (@colesbury) for finding an ABA concurrency issue in abandoned segment reclamation. + +# Building + +## Windows + +Open `ide/vs2019/mimalloc.sln` in Visual Studio 2019 and build (or `ide/vs2017/mimalloc.sln`). +The `mimalloc` project builds a static library (in `out/msvc-x64`), while the +`mimalloc-override` project builds a DLL for overriding malloc +in the entire program. + +## macOS, Linux, BSD, etc. + +We use [`cmake`](https://cmake.org)1 as the build system: + +``` +> mkdir -p out/release +> cd out/release +> cmake ../.. +> make +``` +This builds the library as a shared (dynamic) +library (`.so` or `.dylib`), a static library (`.a`), and +as a single object file (`.o`). + +`> sudo make install` (install the library and header files in `/usr/local/lib` and `/usr/local/include`) + +You can build the debug version which does many internal checks and +maintains detailed statistics as: + +``` +> mkdir -p out/debug +> cd out/debug +> cmake -DCMAKE_BUILD_TYPE=Debug ../.. +> make +``` +This will name the shared library as `libmimalloc-debug.so`. + +Finally, you can build a _secure_ version that uses guard pages, encrypted +free lists, etc., as: +``` +> mkdir -p out/secure +> cd out/secure +> cmake -DMI_SECURE=ON ../.. +> make +``` +This will name the shared library as `libmimalloc-secure.so`. +Use `ccmake`2 instead of `cmake` +to see and customize all the available build options. + +Notes: +1. Install CMake: `sudo apt-get install cmake` +2. Install CCMake: `sudo apt-get install cmake-curses-gui` + + + +# Using the library + +The preferred usage is including ``, linking with +the shared- or static library, and using the `mi_malloc` API exclusively for allocation. For example, +``` +> gcc -o myprogram -lmimalloc myfile.c +``` + +mimalloc uses only safe OS calls (`mmap` and `VirtualAlloc`) and can co-exist +with other allocators linked to the same program. +If you use `cmake`, you can simply use: +``` +find_package(mimalloc 1.4 REQUIRED) +``` +in your `CMakeLists.txt` to find a locally installed mimalloc. Then use either: +``` +target_link_libraries(myapp PUBLIC mimalloc) +``` +to link with the shared (dynamic) library, or: +``` +target_link_libraries(myapp PUBLIC mimalloc-static) +``` +to link with the static library. See `test\CMakeLists.txt` for an example. + +For best performance in C++ programs, it is also recommended to override the +global `new` and `delete` operators. For convience, mimalloc provides +[`mimalloc-new-delete.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-new-delete.h) which does this for you -- just include it in a single(!) source file in your project. +In C++, mimalloc also provides the `mi_stl_allocator` struct which implements the `std::allocator` +interface. + +You can pass environment variables to print verbose messages (`MIMALLOC_VERBOSE=1`) +and statistics (`MIMALLOC_SHOW_STATS=1`) (in the debug version): +``` +> env MIMALLOC_SHOW_STATS=1 ./cfrac 175451865205073170563711388363 + +175451865205073170563711388363 = 374456281610909315237213 * 468551 + +heap stats: peak total freed unit +normal 2: 16.4 kb 17.5 mb 17.5 mb 16 b ok +normal 3: 16.3 kb 15.2 mb 15.2 mb 24 b ok +normal 4: 64 b 4.6 kb 4.6 kb 32 b ok +normal 5: 80 b 118.4 kb 118.4 kb 40 b ok +normal 6: 48 b 48 b 48 b 48 b ok +normal 17: 960 b 960 b 960 b 320 b ok + +heap stats: peak total freed unit + normal: 33.9 kb 32.8 mb 32.8 mb 1 b ok + huge: 0 b 0 b 0 b 1 b ok + total: 33.9 kb 32.8 mb 32.8 mb 1 b ok +malloc requested: 32.8 mb + + committed: 58.2 kb 58.2 kb 58.2 kb 1 b ok + reserved: 2.0 mb 2.0 mb 2.0 mb 1 b ok + reset: 0 b 0 b 0 b 1 b ok + segments: 1 1 1 +-abandoned: 0 + pages: 6 6 6 +-abandoned: 0 + mmaps: 3 + mmap fast: 0 + mmap slow: 1 + threads: 0 + elapsed: 2.022s + process: user: 1.781s, system: 0.016s, faults: 756, reclaims: 0, rss: 2.7 mb +``` + +The above model of using the `mi_` prefixed API is not always possible +though in existing programs that already use the standard malloc interface, +and another option is to override the standard malloc interface +completely and redirect all calls to the _mimalloc_ library instead . + +## Environment Options + +You can set further options either programmatically (using [`mi_option_set`](https://microsoft.github.io/mimalloc/group__options.html)), +or via environment variables. + +- `MIMALLOC_SHOW_STATS=1`: show statistics when the program terminates. +- `MIMALLOC_VERBOSE=1`: show verbose messages. +- `MIMALLOC_SHOW_ERRORS=1`: show error and warning messages. +- `MIMALLOC_PAGE_RESET=0`: by default, mimalloc will reset (or purge) OS pages that are not in use, to signal to the OS + that the underlying physical memory can be reused. This can reduce memory fragmentation in long running (server) + programs. By setting it to `0` this will no longer be done which can improve performance for batch-like programs. + As an alternative, the `MIMALLOC_RESET_DELAY=` can be set higher (100ms by default) to make the page + reset occur less frequently instead of turning it off completely. +- `MIMALLOC_USE_NUMA_NODES=N`: pretend there are at most `N` NUMA nodes. If not set, the actual NUMA nodes are detected + at runtime. Setting `N` to 1 may avoid problems in some virtual environments. Also, setting it to a lower number than + the actual NUMA nodes is fine and will only cause threads to potentially allocate more memory across actual NUMA + nodes (but this can happen in any case as NUMA local allocation is always a best effort but not guaranteed). +- `MIMALLOC_LARGE_OS_PAGES=1`: use large OS pages (2MiB) when available; for some workloads this can significantly + improve performance. Use `MIMALLOC_VERBOSE` to check if the large OS pages are enabled -- usually one needs + to explicitly allow large OS pages (as on [Windows][windows-huge] and [Linux][linux-huge]). However, sometimes + the OS is very slow to reserve contiguous physical memory for large OS pages so use with care on systems that + can have fragmented memory (for that reason, we generally recommend to use `MIMALLOC_RESERVE_HUGE_OS_PAGES` instead whenever possible). + +- `MIMALLOC_RESERVE_HUGE_OS_PAGES=N`: where N is the number of 1GiB _huge_ OS pages. This reserves the huge pages at + startup and sometimes this can give a large (latency) performance improvement on big workloads. + Usually it is better to not use + `MIMALLOC_LARGE_OS_PAGES` in combination with this setting. Just like large OS pages, use with care as reserving + contiguous physical memory can take a long time when memory is fragmented (but reserving the huge pages is done at + startup only once). + Note that we usually need to explicitly enable huge OS pages (as on [Windows][windows-huge] and [Linux][linux-huge])). + With huge OS pages, it may be beneficial to set the setting + `MIMALLOC_EAGER_COMMIT_DELAY=N` (`N` is 1 by default) to delay the initial `N` segments (of 4MiB) + of a thread to not allocate in the huge OS pages; this prevents threads that are short lived + and allocate just a little to take up space in the huge OS page area (which cannot be reset). + +Use caution when using `fork` in combination with either large or huge OS pages: on a fork, the OS uses copy-on-write +for all pages in the original process including the huge OS pages. When any memory is now written in that area, the +OS will copy the entire 1GiB huge page (or 2MiB large page) which can cause the memory usage to grow in big increments. + +[linux-huge]: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/tuning_and_optimizing_red_hat_enterprise_linux_for_oracle_9i_and_10g_databases/sect-oracle_9i_and_10g_tuning_guide-large_memory_optimization_big_pages_and_huge_pages-configuring_huge_pages_in_red_hat_enterprise_linux_4_or_5 +[windows-huge]: https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows?view=sql-server-2017 + +## Secure Mode + +_mimalloc_ can be build in secure mode by using the `-DMI_SECURE=ON` flags in `cmake`. This build enables various mitigations +to make mimalloc more robust against exploits. In particular: + +- All internal mimalloc pages are surrounded by guard pages and the heap metadata is behind a guard page as well (so a buffer overflow + exploit cannot reach into the metadata), +- All free list pointers are + [encoded](https://github.com/microsoft/mimalloc/blob/783e3377f79ee82af43a0793910a9f2d01ac7863/include/mimalloc-internal.h#L396) + with per-page keys which is used both to prevent overwrites with a known pointer, as well as to detect heap corruption, +- Double free's are detected (and ignored), +- The free lists are initialized in a random order and allocation randomly chooses between extension and reuse within a page to + mitigate against attacks that rely on a predicable allocation order. Similarly, the larger heap blocks allocated by mimalloc + from the OS are also address randomized. + +As always, evaluate with care as part of an overall security strategy as all of the above are mitigations but not guarantees. + +## Debug Mode + +When _mimalloc_ is built using debug mode, various checks are done at runtime to catch development errors. + +- Statistics are maintained in detail for each object size. They can be shown using `MIMALLOC_SHOW_STATS=1` at runtime. +- All objects have padding at the end to detect (byte precise) heap block overflows. +- Double free's, and freeing invalid heap pointers are detected. +- Corrupted free-lists and some forms of use-after-free are detected. + + +# Overriding Malloc + +Overriding the standard `malloc` can be done either _dynamically_ or _statically_. + +## Dynamic override + +This is the recommended way to override the standard malloc interface. + +### Override on Linux, BSD + +On these ELF-based systems we preload the mimalloc shared +library so all calls to the standard `malloc` interface are +resolved to the _mimalloc_ library. +``` +> env LD_PRELOAD=/usr/lib/libmimalloc.so myprogram +``` + +You can set extra environment variables to check that mimalloc is running, +like: +``` +> env MIMALLOC_VERBOSE=1 LD_PRELOAD=/usr/lib/libmimalloc.so myprogram +``` +or run with the debug version to get detailed statistics: +``` +> env MIMALLOC_SHOW_STATS=1 LD_PRELOAD=/usr/lib/libmimalloc-debug.so myprogram +``` + +### Override on MacOS + +On macOS we can also preload the mimalloc shared +library so all calls to the standard `malloc` interface are +resolved to the _mimalloc_ library. +``` +> env DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES=/usr/lib/libmimalloc.dylib myprogram +``` + +Note that certain security restrictions may apply when doing this from +the [shell](https://stackoverflow.com/questions/43941322/dyld-insert-libraries-ignored-when-calling-application-through-bash). + +(Note: macOS support for dynamic overriding is recent, please report any issues.) + +### Override on Windows + +Overriding on Windows is robust and has the +particular advantage to be able to redirect all malloc/free calls that go through +the (dynamic) C runtime allocator, including those from other DLL's or libraries. + +The overriding on Windows requires that you link your program explicitly with +the mimalloc DLL and use the C-runtime library as a DLL (using the `/MD` or `/MDd` switch). +Also, the `mimalloc-redirect.dll` (or `mimalloc-redirect32.dll`) must be available +in the same folder as the main `mimalloc-override.dll` at runtime (as it is a dependency). +The redirection DLL ensures that all calls to the C runtime malloc API get redirected to +mimalloc (in `mimalloc-override.dll`). + +To ensure the mimalloc DLL is loaded at run-time it is easiest to insert some +call to the mimalloc API in the `main` function, like `mi_version()` +(or use the `/INCLUDE:mi_version` switch on the linker). See the `mimalloc-override-test` project +for an example on how to use this. For best performance on Windows with C++, it +is also recommended to also override the `new`/`delete` operations (by including +[`mimalloc-new-delete.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-new-delete.h) a single(!) source file in your project). + +The environment variable `MIMALLOC_DISABLE_REDIRECT=1` can be used to disable dynamic +overriding at run-time. Use `MIMALLOC_VERBOSE=1` to check if mimalloc was successfully redirected. + +(Note: in principle, it is possible to even patch existing executables without any recompilation +if they are linked with the dynamic C runtime (`ucrtbase.dll`) -- just put the `mimalloc-override.dll` +into the import table (and put `mimalloc-redirect.dll` in the same folder) +Such patching can be done for example with [CFF Explorer](https://ntcore.com/?page_id=388)). + + +## Static override + +On Unix-like systems, you can also statically link with _mimalloc_ to override the standard +malloc interface. The recommended way is to link the final program with the +_mimalloc_ single object file (`mimalloc-override.o`). We use +an object file instead of a library file as linkers give preference to +that over archives to resolve symbols. To ensure that the standard +malloc interface resolves to the _mimalloc_ library, link it as the first +object file. For example: +``` +> gcc -o myprogram mimalloc-override.o myfile1.c ... +``` + +Another way to override statically that works on all platforms, is to +link statically to mimalloc (as shown in the introduction) and include a +header file in each source file that re-defines `malloc` etc. to `mi_malloc`. +This is provided by [`mimalloc-override.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-override.h). This only works reliably though if all sources are +under your control or otherwise mixing of pointers from different heaps may occur! + + +# Performance + +Last update: 2020-01-20 + +We tested _mimalloc_ against many other top allocators over a wide +range of benchmarks, ranging from various real world programs to +synthetic benchmarks that see how the allocator behaves under more +extreme circumstances. In our benchmark suite, _mimalloc_ outperforms other leading +allocators (_jemalloc_, _tcmalloc_, _Hoard_, etc), and has a similar memory footprint. A nice property is that it +does consistently well over the wide range of benchmarks. + +General memory allocators are interesting as there exists no algorithm that is +optimal -- for a given allocator one can usually construct a workload +where it does not do so well. The goal is thus to find an allocation +strategy that performs well over a wide range of benchmarks without +suffering from (too much) underperformance in less common situations. + +As always, interpret these results with care since some benchmarks test synthetic +or uncommon situations that may never apply to your workloads. For example, most +allocators do not do well on `xmalloc-testN` but that includes the best +industrial allocators like _jemalloc_ and _tcmalloc_ that are used in some of +the world's largest systems (like Chrome or FreeBSD). + +We show here only an overview -- for +more specific details and further benchmarks we refer to the +[technical report](https://www.microsoft.com/en-us/research/publication/mimalloc-free-list-sharding-in-action). +The benchmark suite is automated and available separately +as [mimalloc-bench](https://github.com/daanx/mimalloc-bench). + + +## Benchmark Results on 36-core Intel + +Testing on a big Amazon EC2 compute instance +([c5.18xlarge](https://aws.amazon.com/ec2/instance-types/#Compute_Optimized)) +consisting of a 72 processor Intel Xeon at 3GHz +with 144GiB ECC memory, running Ubuntu 18.04.1 with glibc 2.27 and GCC 7.4.0. +The measured allocators are _mimalloc_ (xmi, tag:v1.4.0, page reset enabled) +and its secure build as _smi_, +Google's [_tcmalloc_](https://github.com/gperftools/gperftools) (tc, tag:gperftools-2.7) used in Chrome, +Facebook's [_jemalloc_](https://github.com/jemalloc/jemalloc) (je, tag:5.2.1) by Jason Evans used in Firefox and FreeBSD, +the Intel thread building blocks [allocator](https://github.com/intel/tbb) (tbb, tag:2020), +[rpmalloc](https://github.com/mjansson/rpmalloc) (rp,tag:1.4.0) by Mattias Jansson, +the original scalable [_Hoard_](https://github.com/emeryberger/Hoard) (tag:3.13) allocator by Emery Berger \[1], +the memory compacting [_Mesh_](https://github.com/plasma-umass/Mesh) (git:51222e7) allocator by +Bobby Powers _et al_ \[8], +and finally the default system allocator (glibc, 2.27) (based on _PtMalloc2_). + + + + +Any benchmarks ending in `N` run on all processors in parallel. +Results are averaged over 10 runs and reported relative +to mimalloc (where 1.2 means it took 1.2× longer to run). +The legend also contains the _overall relative score_ between the +allocators where 100 points is the maximum if an allocator is fastest on +all benchmarks. + +The single threaded _cfrac_ benchmark by Dave Barrett is an implementation of +continued fraction factorization which uses many small short-lived allocations. +All allocators do well on such common usage, where _mimalloc_ is just a tad +faster than _tcmalloc_ and +_jemalloc_. + +The _leanN_ program is interesting as a large realistic and +concurrent workload of the [Lean](https://github.com/leanprover/lean) +theorem prover compiling its own standard library, and there is a 7% +speedup over _tcmalloc_. This is +quite significant: if Lean spends 20% of its time in the +allocator that means that _mimalloc_ is 1.3× faster than _tcmalloc_ +here. (This is surprising as that is not measured in a pure +allocation benchmark like _alloc-test_. We conjecture that we see this +outsized improvement here because _mimalloc_ has better locality in +the allocation which improves performance for the *other* computations +in a program as well). + +The single threaded _redis_ benchmark again show that most allocators do well on such workloads where _tcmalloc_ +did best this time. + +The _larsonN_ server benchmark by Larson and Krishnan \[2] allocates and frees between threads. They observed this +behavior (which they call _bleeding_) in actual server applications, and the benchmark simulates this. +Here, _mimalloc_ is quite a bit faster than _tcmalloc_ and _jemalloc_ probably due to the object migration between different threads. + +The _mstressN_ workload performs many allocations and re-allocations, +and migrates objects between threads (as in _larsonN_). However, it also +creates and destroys the _N_ worker threads a few times keeping some objects +alive beyond the life time of the allocating thread. We observed this +behavior in many larger server applications. + +The [_rptestN_](https://github.com/mjansson/rpmalloc-benchmark) benchmark +by Mattias Jansson is a allocator test originally designed +for _rpmalloc_, and tries to simulate realistic allocation patterns over +multiple threads. Here the differences between allocators become more apparent. + +The second benchmark set tests specific aspects of the allocators and +shows even more extreme differences between them. + +The _alloc-test_, by +[OLogN Technologies AG](http://ithare.com/testing-memory-allocators-ptmalloc2-tcmalloc-hoard-jemalloc-while-trying-to-simulate-real-world-loads/), is a very allocation intensive benchmark doing millions of +allocations in various size classes. The test is scaled such that when an +allocator performs almost identically on _alloc-test1_ as _alloc-testN_ it +means that it scales linearly. Here, _tcmalloc_, and +_Hoard_ seem to scale less well and do more than 10% worse on the multi-core version. Even the best industrial +allocators (_tcmalloc_, _jemalloc_, and _tbb_) are more than 10% slower as _mimalloc_ here. + +The _sh6bench_ and _sh8bench_ benchmarks are +developed by [MicroQuill](http://www.microquill.com/) as part of SmartHeap. +In _sh6bench_ _mimalloc_ does much +better than the others (more than 1.5× faster than _jemalloc_). +We cannot explain this well but believe it is +caused in part by the "reverse" free-ing pattern in _sh6bench_. +The _sh8bench_ is a variation with object migration +between threads; whereas _tcmalloc_ did well on _sh6bench_, the addition of object migration causes it to be 10× slower than before. + +The _xmalloc-testN_ benchmark by Lever and Boreham \[5] and Christian Eder, simulates an asymmetric workload where +some threads only allocate, and others only free -- they observed this pattern in +larger server applications. Here we see that +the _mimalloc_ technique of having non-contended sharded thread free +lists pays off as it outperforms others by a very large margin. Only _rpmalloc_ and _tbb_ also scale well on this benchmark. + +The _cache-scratch_ benchmark by Emery Berger \[1], and introduced with +the Hoard allocator to test for _passive-false_ sharing of cache lines. +With a single thread they all +perform the same, but when running with multiple threads the potential allocator +induced false sharing of the cache lines can cause large run-time differences. +Crundal \[6] describes in detail why the false cache line sharing occurs in the _tcmalloc_ design, and also discusses how this +can be avoided with some small implementation changes. +Only the _tbb_, _rpmalloc_ and _mesh_ allocators also avoid the +cache line sharing completely, while _Hoard_ and _glibc_ seem to mitigate +the effects. Kukanov and Voss \[7] describe in detail +how the design of _tbb_ avoids the false cache line sharing. + +## On 24-core AMD Epyc + +For completeness, here are the results on a +[r5a.12xlarge](https://aws.amazon.com/ec2/instance-types/#Memory_Optimized) instance +having a 48 processor AMD Epyc 7000 at 2.5GHz with 384GiB of memory. +The results are similar to the Intel results but it is interesting to +see the differences in the _larsonN_, _mstressN_, and _xmalloc-testN_ benchmarks. + + + + + +## Peak Working Set + +The following figure shows the peak working set (rss) of the allocators +on the benchmarks (on the c5.18xlarge instance). + + + + +Note that the _xmalloc-testN_ memory usage should be disregarded as it +allocates more the faster the program runs. Similarly, memory usage of +_mstressN_, _rptestN_ and _sh8bench_ can vary depending on scheduling and +speed. Nevertheless, even though _mimalloc_ is fast on these benchmarks we +believe the memory usage is too high and hope to improve. + + +# References + +- \[1] Emery D. Berger, Kathryn S. McKinley, Robert D. Blumofe, and Paul R. Wilson. + _Hoard: A Scalable Memory Allocator for Multithreaded Applications_ + the Ninth International Conference on Architectural Support for Programming Languages and Operating Systems (ASPLOS-IX). Cambridge, MA, November 2000. + [pdf](http://www.cs.utexas.edu/users/mckinley/papers/asplos-2000.pdf) + +- \[2] P. Larson and M. Krishnan. _Memory allocation for long-running server applications_. + In ISMM, Vancouver, B.C., Canada, 1998. [pdf](http://citeseer.ist.psu.edu/viewdoc/download?doi=10.1.1.45.1947&rep=rep1&type=pdf) + +- \[3] D. Grunwald, B. Zorn, and R. Henderson. + _Improving the cache locality of memory allocation_. In R. Cartwright, editor, + Proceedings of the Conference on Programming Language Design and Implementation, pages 177–186, New York, NY, USA, June 1993. [pdf](http://citeseer.ist.psu.edu/viewdoc/download?doi=10.1.1.43.6621&rep=rep1&type=pdf) + +- \[4] J. Barnes and P. Hut. _A hierarchical O(n*log(n)) force-calculation algorithm_. Nature, 324:446-449, 1986. + +- \[5] C. Lever, and D. Boreham. _Malloc() Performance in a Multithreaded Linux Environment._ + In USENIX Annual Technical Conference, Freenix Session. San Diego, CA. Jun. 2000. + Available at + +- \[6] Timothy Crundal. _Reducing Active-False Sharing in TCMalloc_. 2016. CS16S1 project at the Australian National University. [pdf](http://courses.cecs.anu.edu.au/courses/CSPROJECTS/16S1/Reports/Timothy_Crundal_Report.pdf) + +- \[7] Alexey Kukanov, and Michael J Voss. + _The Foundations for Scalable Multi-Core Software in Intel Threading Building Blocks._ + Intel Technology Journal 11 (4). 2007 + +- \[8] Bobby Powers, David Tench, Emery D. Berger, and Andrew McGregor. + _Mesh: Compacting Memory Management for C/C++_ + In Proceedings of the 40th ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI'19), June 2019, pages 333-–346. + + + + +# Contributing + +This project welcomes contributions and suggestions. Most contributions require you to agree to a +Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us +the rights to use your contribution. For details, visit https://cla.microsoft.com. + +When you submit a pull request, a CLA-bot will automatically determine whether you need to provide +a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions +provided by the bot. You will only need to do this once across all repos using our CLA. diff --git a/extlib/mimalloc/src/alloc-aligned.c b/extlib/mimalloc/src/alloc-aligned.c new file mode 100644 index 0000000..ca16d36 --- /dev/null +++ b/extlib/mimalloc/src/alloc-aligned.c @@ -0,0 +1,205 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +#include "mimalloc.h" +#include "mimalloc-internal.h" + +#include // memset, memcpy + +// ------------------------------------------------------ +// Aligned Allocation +// ------------------------------------------------------ + +static void* mi_heap_malloc_zero_aligned_at(mi_heap_t* const heap, const size_t size, const size_t alignment, const size_t offset, const bool zero) mi_attr_noexcept { + // note: we don't require `size > offset`, we just guarantee that + // the address at offset is aligned regardless of the allocated size. + mi_assert(alignment > 0); + if (mi_unlikely(size > PTRDIFF_MAX)) return NULL; // we don't allocate more than PTRDIFF_MAX (see ) + if (mi_unlikely(alignment==0 || !_mi_is_power_of_two(alignment))) return NULL; // require power-of-two (see ) + const uintptr_t align_mask = alignment-1; // for any x, `(x & align_mask) == (x % alignment)` + + // try if there is a small block available with just the right alignment + const size_t padsize = size + MI_PADDING_SIZE; + if (mi_likely(padsize <= MI_SMALL_SIZE_MAX)) { + mi_page_t* page = _mi_heap_get_free_small_page(heap,padsize); + const bool is_aligned = (((uintptr_t)page->free+offset) & align_mask)==0; + if (mi_likely(page->free != NULL && is_aligned)) + { + #if MI_STAT>1 + mi_heap_stat_increase( heap, malloc, size); + #endif + void* p = _mi_page_malloc(heap,page,padsize); // TODO: inline _mi_page_malloc + mi_assert_internal(p != NULL); + mi_assert_internal(((uintptr_t)p + offset) % alignment == 0); + if (zero) _mi_block_zero_init(page,p,size); + return p; + } + } + + // use regular allocation if it is guaranteed to fit the alignment constraints + if (offset==0 && alignment<=padsize && padsize<=MI_MEDIUM_OBJ_SIZE_MAX && (padsize&align_mask)==0) { + void* p = _mi_heap_malloc_zero(heap, size, zero); + mi_assert_internal(p == NULL || ((uintptr_t)p % alignment) == 0); + return p; + } + + // otherwise over-allocate + void* p = _mi_heap_malloc_zero(heap, size + alignment - 1, zero); + if (p == NULL) return NULL; + + // .. and align within the allocation + uintptr_t adjust = alignment - (((uintptr_t)p + offset) & align_mask); + mi_assert_internal(adjust <= alignment); + void* aligned_p = (adjust == alignment ? p : (void*)((uintptr_t)p + adjust)); + if (aligned_p != p) mi_page_set_has_aligned(_mi_ptr_page(p), true); + mi_assert_internal(((uintptr_t)aligned_p + offset) % alignment == 0); + mi_assert_internal( p == _mi_page_ptr_unalign(_mi_ptr_segment(aligned_p),_mi_ptr_page(aligned_p),aligned_p) ); + return aligned_p; +} + + +mi_decl_restrict void* mi_heap_malloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_malloc_zero_aligned_at(heap, size, alignment, offset, false); +} + +mi_decl_restrict void* mi_heap_malloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_malloc_aligned_at(heap, size, alignment, 0); +} + +mi_decl_restrict void* mi_heap_zalloc_aligned_at(mi_heap_t* heap, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_malloc_zero_aligned_at(heap, size, alignment, offset, true); +} + +mi_decl_restrict void* mi_heap_zalloc_aligned(mi_heap_t* heap, size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_zalloc_aligned_at(heap, size, alignment, 0); +} + +mi_decl_restrict void* mi_heap_calloc_aligned_at(mi_heap_t* heap, size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count, size, &total)) return NULL; + return mi_heap_zalloc_aligned_at(heap, total, alignment, offset); +} + +mi_decl_restrict void* mi_heap_calloc_aligned(mi_heap_t* heap, size_t count, size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_calloc_aligned_at(heap,count,size,alignment,0); +} + +mi_decl_restrict void* mi_malloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_malloc_aligned_at(mi_get_default_heap(), size, alignment, offset); +} + +mi_decl_restrict void* mi_malloc_aligned(size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_malloc_aligned(mi_get_default_heap(), size, alignment); +} + +mi_decl_restrict void* mi_zalloc_aligned_at(size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_zalloc_aligned_at(mi_get_default_heap(), size, alignment, offset); +} + +mi_decl_restrict void* mi_zalloc_aligned(size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_zalloc_aligned(mi_get_default_heap(), size, alignment); +} + +mi_decl_restrict void* mi_calloc_aligned_at(size_t count, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_calloc_aligned_at(mi_get_default_heap(), count, size, alignment, offset); +} + +mi_decl_restrict void* mi_calloc_aligned(size_t count, size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_calloc_aligned(mi_get_default_heap(), count, size, alignment); +} + + +static void* mi_heap_realloc_zero_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset, bool zero) mi_attr_noexcept { + mi_assert(alignment > 0); + if (alignment <= sizeof(uintptr_t)) return _mi_heap_realloc_zero(heap,p,newsize,zero); + if (p == NULL) return mi_heap_malloc_zero_aligned_at(heap,newsize,alignment,offset,zero); + size_t size = mi_usable_size(p); + if (newsize <= size && newsize >= (size - (size / 2)) + && (((uintptr_t)p + offset) % alignment) == 0) { + return p; // reallocation still fits, is aligned and not more than 50% waste + } + else { + void* newp = mi_heap_malloc_aligned_at(heap,newsize,alignment,offset); + if (newp != NULL) { + if (zero && newsize > size) { + const mi_page_t* page = _mi_ptr_page(newp); + if (page->is_zero) { + // already zero initialized + mi_assert_expensive(mi_mem_is_zero(newp,newsize)); + } + else { + // also set last word in the previous allocation to zero to ensure any padding is zero-initialized + size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0); + memset((uint8_t*)newp + start, 0, newsize - start); + } + } + memcpy(newp, p, (newsize > size ? size : newsize)); + mi_free(p); // only free if successful + } + return newp; + } +} + +static void* mi_heap_realloc_zero_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, bool zero) mi_attr_noexcept { + mi_assert(alignment > 0); + if (alignment <= sizeof(uintptr_t)) return _mi_heap_realloc_zero(heap,p,newsize,zero); + size_t offset = ((uintptr_t)p % alignment); // use offset of previous allocation (p can be NULL) + return mi_heap_realloc_zero_aligned_at(heap,p,newsize,alignment,offset,zero); +} + +void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_realloc_zero_aligned_at(heap,p,newsize,alignment,offset,false); +} + +void* mi_heap_realloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept { + return mi_heap_realloc_zero_aligned(heap,p,newsize,alignment,false); +} + +void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_realloc_zero_aligned_at(heap, p, newsize, alignment, offset, true); +} + +void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment) mi_attr_noexcept { + return mi_heap_realloc_zero_aligned(heap, p, newsize, alignment, true); +} + +void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(newcount, size, &total)) return NULL; + return mi_heap_rezalloc_aligned_at(heap, p, total, alignment, offset); +} + +void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(newcount, size, &total)) return NULL; + return mi_heap_rezalloc_aligned(heap, p, total, alignment); +} + +void* mi_realloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_realloc_aligned_at(mi_get_default_heap(), p, newsize, alignment, offset); +} + +void* mi_realloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept { + return mi_heap_realloc_aligned(mi_get_default_heap(), p, newsize, alignment); +} + +void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_rezalloc_aligned_at(mi_get_default_heap(), p, newsize, alignment, offset); +} + +void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment) mi_attr_noexcept { + return mi_heap_rezalloc_aligned(mi_get_default_heap(), p, newsize, alignment); +} + +void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { + return mi_heap_recalloc_aligned_at(mi_get_default_heap(), p, newcount, size, alignment, offset); +} + +void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { + return mi_heap_recalloc_aligned(mi_get_default_heap(), p, newcount, size, alignment); +} + diff --git a/extlib/mimalloc/src/alloc-override-osx.c b/extlib/mimalloc/src/alloc-override-osx.c new file mode 100644 index 0000000..c1c880c --- /dev/null +++ b/extlib/mimalloc/src/alloc-override-osx.c @@ -0,0 +1,260 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +#include "mimalloc.h" +#include "mimalloc-internal.h" + +#if defined(MI_MALLOC_OVERRIDE) + +#if !defined(__APPLE__) +#error "this file should only be included on macOS" +#endif + +/* ------------------------------------------------------ + Override system malloc on macOS + This is done through the malloc zone interface. + It seems we also need to interpose (see `alloc-override.c`) + or otherwise we get zone errors as there are usually + already allocations done by the time we take over the + zone. Unfortunately, that means we need to replace + the `free` with a checked free (`cfree`) impacting + performance. +------------------------------------------------------ */ + +#include +#include +#include // memset + +#if defined(MAC_OS_X_VERSION_10_6) && \ + MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 +// only available from OSX 10.6 +extern malloc_zone_t* malloc_default_purgeable_zone(void) __attribute__((weak_import)); +#endif + + +/* ------------------------------------------------------ + malloc zone members +------------------------------------------------------ */ + +static size_t zone_size(malloc_zone_t* zone, const void* p) { + UNUSED(zone); + if (!mi_is_in_heap_region(p)) + return 0; // not our pointer, bail out + + return mi_usable_size(p); +} + +static void* zone_malloc(malloc_zone_t* zone, size_t size) { + UNUSED(zone); + return mi_malloc(size); +} + +static void* zone_calloc(malloc_zone_t* zone, size_t count, size_t size) { + UNUSED(zone); + return mi_calloc(count, size); +} + +static void* zone_valloc(malloc_zone_t* zone, size_t size) { + UNUSED(zone); + return mi_malloc_aligned(size, _mi_os_page_size()); +} + +static void zone_free(malloc_zone_t* zone, void* p) { + UNUSED(zone); + return mi_free(p); +} + +static void* zone_realloc(malloc_zone_t* zone, void* p, size_t newsize) { + UNUSED(zone); + return mi_realloc(p, newsize); +} + +static void* zone_memalign(malloc_zone_t* zone, size_t alignment, size_t size) { + UNUSED(zone); + return mi_malloc_aligned(size,alignment); +} + +static void zone_destroy(malloc_zone_t* zone) { + UNUSED(zone); + // todo: ignore for now? +} + +static unsigned zone_batch_malloc(malloc_zone_t* zone, size_t size, void** ps, unsigned count) { + size_t i; + for (i = 0; i < count; i++) { + ps[i] = zone_malloc(zone, size); + if (ps[i] == NULL) break; + } + return i; +} + +static void zone_batch_free(malloc_zone_t* zone, void** ps, unsigned count) { + for(size_t i = 0; i < count; i++) { + zone_free(zone, ps[i]); + ps[i] = NULL; + } +} + +static size_t zone_pressure_relief(malloc_zone_t* zone, size_t size) { + UNUSED(zone); UNUSED(size); + mi_collect(false); + return 0; +} + +static void zone_free_definite_size(malloc_zone_t* zone, void* p, size_t size) { + UNUSED(size); + zone_free(zone,p); +} + + +/* ------------------------------------------------------ + Introspection members +------------------------------------------------------ */ + +static kern_return_t intro_enumerator(task_t task, void* p, + unsigned type_mask, vm_address_t zone_address, + memory_reader_t reader, + vm_range_recorder_t recorder) +{ + // todo: enumerate all memory + UNUSED(task); UNUSED(p); UNUSED(type_mask); UNUSED(zone_address); + UNUSED(reader); UNUSED(recorder); + return KERN_SUCCESS; +} + +static size_t intro_good_size(malloc_zone_t* zone, size_t size) { + UNUSED(zone); + return mi_good_size(size); +} + +static boolean_t intro_check(malloc_zone_t* zone) { + UNUSED(zone); + return true; +} + +static void intro_print(malloc_zone_t* zone, boolean_t verbose) { + UNUSED(zone); UNUSED(verbose); + mi_stats_print(NULL); +} + +static void intro_log(malloc_zone_t* zone, void* p) { + UNUSED(zone); UNUSED(p); + // todo? +} + +static void intro_force_lock(malloc_zone_t* zone) { + UNUSED(zone); + // todo? +} + +static void intro_force_unlock(malloc_zone_t* zone) { + UNUSED(zone); + // todo? +} + +static void intro_statistics(malloc_zone_t* zone, malloc_statistics_t* stats) { + UNUSED(zone); + // todo... + stats->blocks_in_use = 0; + stats->size_in_use = 0; + stats->max_size_in_use = 0; + stats->size_allocated = 0; +} + +static boolean_t intro_zone_locked(malloc_zone_t* zone) { + UNUSED(zone); + return false; +} + + +/* ------------------------------------------------------ + At process start, override the default allocator +------------------------------------------------------ */ + +static malloc_zone_t* mi_get_default_zone() +{ + // The first returned zone is the real default + malloc_zone_t** zones = NULL; + unsigned count = 0; + kern_return_t ret = malloc_get_all_zones(0, NULL, (vm_address_t**)&zones, &count); + if (ret == KERN_SUCCESS && count > 0) { + return zones[0]; + } + else { + // fallback + return malloc_default_zone(); + } +} + +static void __attribute__((constructor)) _mi_macos_override_malloc() +{ + static malloc_introspection_t intro; + memset(&intro, 0, sizeof(intro)); + + intro.enumerator = &intro_enumerator; + intro.good_size = &intro_good_size; + intro.check = &intro_check; + intro.print = &intro_print; + intro.log = &intro_log; + intro.force_lock = &intro_force_lock; + intro.force_unlock = &intro_force_unlock; + + static malloc_zone_t zone; + memset(&zone, 0, sizeof(zone)); + + zone.version = 4; + zone.zone_name = "mimalloc"; + zone.size = &zone_size; + zone.introspect = &intro; + zone.malloc = &zone_malloc; + zone.calloc = &zone_calloc; + zone.valloc = &zone_valloc; + zone.free = &zone_free; + zone.realloc = &zone_realloc; + zone.destroy = &zone_destroy; + zone.batch_malloc = &zone_batch_malloc; + zone.batch_free = &zone_batch_free; + + malloc_zone_t* purgeable_zone = NULL; + +#if defined(MAC_OS_X_VERSION_10_6) && \ + MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + // switch to version 9 on OSX 10.6 to support memalign. + zone.version = 9; + zone.memalign = &zone_memalign; + zone.free_definite_size = &zone_free_definite_size; + zone.pressure_relief = &zone_pressure_relief; + intro.zone_locked = &intro_zone_locked; + intro.statistics = &intro_statistics; + + // force the purgeable zone to exist to avoid strange bugs + if (malloc_default_purgeable_zone) { + purgeable_zone = malloc_default_purgeable_zone(); + } +#endif + + // Register our zone + malloc_zone_register(&zone); + + // Unregister the default zone, this makes our zone the new default + // as that was the last registered. + malloc_zone_t *default_zone = mi_get_default_zone(); + malloc_zone_unregister(default_zone); + + // Reregister the default zone so free and realloc in that zone keep working. + malloc_zone_register(default_zone); + + // Unregister, and re-register the purgeable_zone to avoid bugs if it occurs + // earlier than the default zone. + if (purgeable_zone != NULL) { + malloc_zone_unregister(purgeable_zone); + malloc_zone_register(purgeable_zone); + } + +} + +#endif // MI_MALLOC_OVERRIDE diff --git a/extlib/mimalloc/src/alloc-override.c b/extlib/mimalloc/src/alloc-override.c new file mode 100644 index 0000000..ae7ad7d --- /dev/null +++ b/extlib/mimalloc/src/alloc-override.c @@ -0,0 +1,214 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +#if !defined(MI_IN_ALLOC_C) +#error "this file should be included from 'alloc.c' (so aliases can work)" +#endif + +#if defined(MI_MALLOC_OVERRIDE) && defined(_WIN32) && !(defined(MI_SHARED_LIB) && defined(_DLL)) +#error "It is only possible to override "malloc" on Windows when building as a DLL (and linking the C runtime as a DLL)" +#endif + +#if defined(MI_MALLOC_OVERRIDE) && !(defined(_WIN32)) // || (defined(__MACH__) && !defined(MI_INTERPOSE))) + +// ------------------------------------------------------ +// Override system malloc +// ------------------------------------------------------ + +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__) + // use aliasing to alias the exported function to one of our `mi_` functions + #if (defined(__GNUC__) && __GNUC__ >= 9) + #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default"), copy(fun))) + #else + #define MI_FORWARD(fun) __attribute__((alias(#fun), used, visibility("default"))) + #endif + #define MI_FORWARD1(fun,x) MI_FORWARD(fun) + #define MI_FORWARD2(fun,x,y) MI_FORWARD(fun) + #define MI_FORWARD3(fun,x,y,z) MI_FORWARD(fun) + #define MI_FORWARD0(fun,x) MI_FORWARD(fun) + #define MI_FORWARD02(fun,x,y) MI_FORWARD(fun) +#else + // use forwarding by calling our `mi_` function + #define MI_FORWARD1(fun,x) { return fun(x); } + #define MI_FORWARD2(fun,x,y) { return fun(x,y); } + #define MI_FORWARD3(fun,x,y,z) { return fun(x,y,z); } + #define MI_FORWARD0(fun,x) { fun(x); } + #define MI_FORWARD02(fun,x,y) { fun(x,y); } +#endif + +#if defined(__APPLE__) && defined(MI_SHARED_LIB_EXPORT) && defined(MI_INTERPOSE) + // use interposing so `DYLD_INSERT_LIBRARIES` works without `DYLD_FORCE_FLAT_NAMESPACE=1` + // See: + struct mi_interpose_s { + const void* replacement; + const void* target; + }; + #define MI_INTERPOSE_FUN(oldfun,newfun) { (const void*)&newfun, (const void*)&oldfun } + #define MI_INTERPOSE_MI(fun) MI_INTERPOSE_FUN(fun,mi_##fun) + __attribute__((used)) static struct mi_interpose_s _mi_interposes[] __attribute__((section("__DATA, __interpose"))) = + { + MI_INTERPOSE_MI(malloc), + MI_INTERPOSE_MI(calloc), + MI_INTERPOSE_MI(realloc), + MI_INTERPOSE_MI(strdup), + MI_INTERPOSE_MI(strndup), + MI_INTERPOSE_MI(realpath), + MI_INTERPOSE_MI(posix_memalign), + MI_INTERPOSE_MI(reallocf), + MI_INTERPOSE_MI(valloc), + // some code allocates from a zone but deallocates using plain free :-( (like NxHashResizeToCapacity ) + MI_INTERPOSE_FUN(free,mi_cfree), // use safe free that checks if pointers are from us + }; +#elif defined(_MSC_VER) + // cannot override malloc unless using a dll. + // we just override new/delete which does work in a static library. +#else + // On all other systems forward to our API + void* malloc(size_t size) MI_FORWARD1(mi_malloc, size); + void* calloc(size_t size, size_t n) MI_FORWARD2(mi_calloc, size, n); + void* realloc(void* p, size_t newsize) MI_FORWARD2(mi_realloc, p, newsize); + void free(void* p) MI_FORWARD0(mi_free, p); +#endif + +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__) +#pragma GCC visibility push(default) +#endif + +// ------------------------------------------------------ +// Override new/delete +// This is not really necessary as they usually call +// malloc/free anyway, but it improves performance. +// ------------------------------------------------------ +#ifdef __cplusplus + // ------------------------------------------------------ + // With a C++ compiler we override the new/delete operators. + // see + // ------------------------------------------------------ + #include + void operator delete(void* p) noexcept MI_FORWARD0(mi_free,p); + void operator delete[](void* p) noexcept MI_FORWARD0(mi_free,p); + + void* operator new(std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n); + void* operator new[](std::size_t n) noexcept(false) MI_FORWARD1(mi_new,n); + + void* operator new (std::size_t n, const std::nothrow_t& tag) noexcept { UNUSED(tag); return mi_new_nothrow(n); } + void* operator new[](std::size_t n, const std::nothrow_t& tag) noexcept { UNUSED(tag); return mi_new_nothrow(n); } + + #if (__cplusplus >= 201402L || _MSC_VER >= 1916) + void operator delete (void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n); + void operator delete[](void* p, std::size_t n) noexcept MI_FORWARD02(mi_free_size,p,n); + #endif + + #if (__cplusplus > 201402L && defined(__cpp_aligned_new)) && (!defined(__GNUC__) || (__GNUC__ > 5)) + void operator delete (void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } + void operator delete[](void* p, std::align_val_t al) noexcept { mi_free_aligned(p, static_cast(al)); } + void operator delete (void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; + void operator delete[](void* p, std::size_t n, std::align_val_t al) noexcept { mi_free_size_aligned(p, n, static_cast(al)); }; + + void* operator new( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } + void* operator new[]( std::size_t n, std::align_val_t al) noexcept(false) { return mi_new_aligned(n, static_cast(al)); } + void* operator new (std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } + void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast(al)); } + #endif + +#elif (defined(__GNUC__) || defined(__clang__)) + // ------------------------------------------------------ + // Override by defining the mangled C++ names of the operators (as + // used by GCC and CLang). + // See + // ------------------------------------------------------ + void _ZdlPv(void* p) MI_FORWARD0(mi_free,p); // delete + void _ZdaPv(void* p) MI_FORWARD0(mi_free,p); // delete[] + void _ZdlPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n); + void _ZdaPvm(void* p, size_t n) MI_FORWARD02(mi_free_size,p,n); + void _ZdlPvSt11align_val_t(void* p, size_t al) { mi_free_aligned(p,al); } + void _ZdaPvSt11align_val_t(void* p, size_t al) { mi_free_aligned(p,al); } + void _ZdlPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); } + void _ZdaPvmSt11align_val_t(void* p, size_t n, size_t al) { mi_free_size_aligned(p,n,al); } + + typedef struct mi_nothrow_s { } mi_nothrow_t; + #if (MI_INTPTR_SIZE==8) + void* _Znwm(size_t n) MI_FORWARD1(mi_new,n); // new 64-bit + void* _Znam(size_t n) MI_FORWARD1(mi_new,n); // new[] 64-bit + void* _ZnwmSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al); + void* _ZnamSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al); + void* _ZnwmRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); } + void* _ZnamRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); } + void* _ZnwmSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); } + void* _ZnamSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); } + #elif (MI_INTPTR_SIZE==4) + void* _Znwj(size_t n) MI_FORWARD1(mi_new,n); // new 64-bit + void* _Znaj(size_t n) MI_FORWARD1(mi_new,n); // new[] 64-bit + void* _ZnwjSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al); + void* _ZnajSt11align_val_t(size_t n, size_t al) MI_FORWARD2(mi_new_aligned, n, al); + void* _ZnwjRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); } + void* _ZnajRKSt9nothrow_t(size_t n, mi_nothrow_t tag) { UNUSED(tag); return mi_new_nothrow(n); } + void* _ZnwjSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); } + void* _ZnajSt11align_val_tRKSt9nothrow_t(size_t n, size_t al, mi_nothrow_t tag) { UNUSED(tag); return mi_new_aligned_nothrow(n,al); } + #else + #error "define overloads for new/delete for this platform (just for performance, can be skipped)" + #endif +#endif // __cplusplus + + +#ifdef __cplusplus +extern "C" { +#endif + +// ------------------------------------------------------ +// Posix & Unix functions definitions +// ------------------------------------------------------ + +void cfree(void* p) MI_FORWARD0(mi_free, p); +void* reallocf(void* p, size_t newsize) MI_FORWARD2(mi_reallocf,p,newsize); +size_t malloc_size(const void* p) MI_FORWARD1(mi_usable_size,p); +#if !defined(__ANDROID__) +size_t malloc_usable_size(void *p) MI_FORWARD1(mi_usable_size,p); +#else +size_t malloc_usable_size(const void *p) MI_FORWARD1(mi_usable_size,p); +#endif + +// no forwarding here due to aliasing/name mangling issues +void* valloc(size_t size) { return mi_valloc(size); } +void* pvalloc(size_t size) { return mi_pvalloc(size); } +void* reallocarray(void* p, size_t count, size_t size) { return mi_reallocarray(p, count, size); } +void* memalign(size_t alignment, size_t size) { return mi_memalign(alignment, size); } +int posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p, alignment, size); } +void* _aligned_malloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); } + +// on some glibc `aligned_alloc` is declared `static inline` so we cannot override it (e.g. Conda). This happens +// when _GLIBCXX_HAVE_ALIGNED_ALLOC is not defined. However, in those cases it will use `memalign`, `posix_memalign`, +// or `_aligned_malloc` and we can avoid overriding it ourselves. +// We should always override if using C compilation. (issue #276) +#if _GLIBCXX_HAVE_ALIGNED_ALLOC || !defined(__cplusplus) +void* aligned_alloc(size_t alignment, size_t size) { return mi_aligned_alloc(alignment, size); } +#endif + + +#if defined(__GLIBC__) && defined(__linux__) + // forward __libc interface (needed for glibc-based Linux distributions) + void* __libc_malloc(size_t size) MI_FORWARD1(mi_malloc,size); + void* __libc_calloc(size_t count, size_t size) MI_FORWARD2(mi_calloc,count,size); + void* __libc_realloc(void* p, size_t size) MI_FORWARD2(mi_realloc,p,size); + void __libc_free(void* p) MI_FORWARD0(mi_free,p); + void __libc_cfree(void* p) MI_FORWARD0(mi_free,p); + + void* __libc_valloc(size_t size) { return mi_valloc(size); } + void* __libc_pvalloc(size_t size) { return mi_pvalloc(size); } + void* __libc_memalign(size_t alignment, size_t size) { return mi_memalign(alignment,size); } + int __posix_memalign(void** p, size_t alignment, size_t size) { return mi_posix_memalign(p,alignment,size); } +#endif + +#ifdef __cplusplus +} +#endif + +#if (defined(__GNUC__) || defined(__clang__)) && !defined(__MACH__) +#pragma GCC visibility pop +#endif + +#endif // MI_MALLOC_OVERRIDE && !_WIN32 diff --git a/extlib/mimalloc/src/alloc-posix.c b/extlib/mimalloc/src/alloc-posix.c new file mode 100644 index 0000000..4395893 --- /dev/null +++ b/extlib/mimalloc/src/alloc-posix.c @@ -0,0 +1,155 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018,2019, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +// ------------------------------------------------------------------------ +// mi prefixed publi definitions of various Posix, Unix, and C++ functions +// for convenience and used when overriding these functions. +// ------------------------------------------------------------------------ +#include "mimalloc.h" +#include "mimalloc-internal.h" + +// ------------------------------------------------------ +// Posix & Unix functions definitions +// ------------------------------------------------------ + +#include +#include // memcpy +#include // getenv + +#ifndef EINVAL +#define EINVAL 22 +#endif +#ifndef ENOMEM +#define ENOMEM 12 +#endif + + +size_t mi_malloc_size(const void* p) mi_attr_noexcept { + return mi_usable_size(p); +} + +size_t mi_malloc_usable_size(const void *p) mi_attr_noexcept { + return mi_usable_size(p); +} + +void mi_cfree(void* p) mi_attr_noexcept { + if (mi_is_in_heap_region(p)) { + mi_free(p); + } +} + +int mi_posix_memalign(void** p, size_t alignment, size_t size) mi_attr_noexcept { + // Note: The spec dictates we should not modify `*p` on an error. (issue#27) + // + if (p == NULL) return EINVAL; + if (alignment % sizeof(void*) != 0) return EINVAL; // natural alignment + if (!_mi_is_power_of_two(alignment)) return EINVAL; // not a power of 2 + void* q = (mi_malloc_satisfies_alignment(alignment, size) ? mi_malloc(size) : mi_malloc_aligned(size, alignment)); + if (q==NULL && size != 0) return ENOMEM; + mi_assert_internal(((uintptr_t)q % alignment) == 0); + *p = q; + return 0; +} + +mi_decl_restrict void* mi_memalign(size_t alignment, size_t size) mi_attr_noexcept { + void* p = (mi_malloc_satisfies_alignment(alignment,size) ? mi_malloc(size) : mi_malloc_aligned(size, alignment)); + mi_assert_internal(((uintptr_t)p % alignment) == 0); + return p; +} + +mi_decl_restrict void* mi_valloc(size_t size) mi_attr_noexcept { + return mi_memalign( _mi_os_page_size(), size ); +} + +mi_decl_restrict void* mi_pvalloc(size_t size) mi_attr_noexcept { + size_t psize = _mi_os_page_size(); + if (size >= SIZE_MAX - psize) return NULL; // overflow + size_t asize = _mi_align_up(size, psize); + return mi_malloc_aligned(asize, psize); +} + +mi_decl_restrict void* mi_aligned_alloc(size_t alignment, size_t size) mi_attr_noexcept { + if (alignment==0 || !_mi_is_power_of_two(alignment)) return NULL; + if ((size&(alignment-1)) != 0) return NULL; // C11 requires integral multiple, see + void* p = (mi_malloc_satisfies_alignment(alignment, size) ? mi_malloc(size) : mi_malloc_aligned(size, alignment)); + mi_assert_internal(((uintptr_t)p % alignment) == 0); + return p; +} + +void* mi_reallocarray( void* p, size_t count, size_t size ) mi_attr_noexcept { // BSD + void* newp = mi_reallocn(p,count,size); + if (newp==NULL) errno = ENOMEM; + return newp; +} + +void* mi__expand(void* p, size_t newsize) mi_attr_noexcept { // Microsoft + void* res = mi_expand(p, newsize); + if (res == NULL) errno = ENOMEM; + return res; +} + +mi_decl_restrict unsigned short* mi_wcsdup(const unsigned short* s) mi_attr_noexcept { + if (s==NULL) return NULL; + size_t len; + for(len = 0; s[len] != 0; len++) { } + size_t size = (len+1)*sizeof(unsigned short); + unsigned short* p = (unsigned short*)mi_malloc(size); + if (p != NULL) { + memcpy(p,s,size); + } + return p; +} + +mi_decl_restrict unsigned char* mi_mbsdup(const unsigned char* s) mi_attr_noexcept { + return (unsigned char*)mi_strdup((const char*)s); +} + +int mi_dupenv_s(char** buf, size_t* size, const char* name) mi_attr_noexcept { + if (buf==NULL || name==NULL) return EINVAL; + if (size != NULL) *size = 0; + #pragma warning(suppress:4996) + char* p = getenv(name); + if (p==NULL) { + *buf = NULL; + } + else { + *buf = mi_strdup(p); + if (*buf==NULL) return ENOMEM; + if (size != NULL) *size = strlen(p); + } + return 0; +} + +int mi_wdupenv_s(unsigned short** buf, size_t* size, const unsigned short* name) mi_attr_noexcept { + if (buf==NULL || name==NULL) return EINVAL; + if (size != NULL) *size = 0; +#if !defined(_WIN32) || (defined(WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP)) + // not supported + *buf = NULL; + return EINVAL; +#else + #pragma warning(suppress:4996) + unsigned short* p = (unsigned short*)_wgetenv((const wchar_t*)name); + if (p==NULL) { + *buf = NULL; + } + else { + *buf = mi_wcsdup(p); + if (*buf==NULL) return ENOMEM; + if (size != NULL) *size = wcslen((const wchar_t*)p); + } + return 0; +#endif +} + +void* mi_aligned_offset_recalloc(void* p, size_t newcount, size_t size, size_t alignment, size_t offset) mi_attr_noexcept { // Microsoft + return mi_recalloc_aligned_at(p, newcount, size, alignment, offset); +} + +void* mi_aligned_recalloc(void* p, size_t newcount, size_t size, size_t alignment) mi_attr_noexcept { // Microsoft + return mi_recalloc_aligned(p, newcount, size, alignment); +} diff --git a/extlib/mimalloc/src/alloc.c b/extlib/mimalloc/src/alloc.c new file mode 100644 index 0000000..5703452 --- /dev/null +++ b/extlib/mimalloc/src/alloc.c @@ -0,0 +1,857 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc-internal.h" +#include "mimalloc-atomic.h" + +#include // memset, memcpy, strlen +#include // malloc, exit + +#define MI_IN_ALLOC_C +#include "alloc-override.c" +#undef MI_IN_ALLOC_C + +// ------------------------------------------------------ +// Allocation +// ------------------------------------------------------ + +// Fast allocation in a page: just pop from the free list. +// Fall back to generic allocation only if the list is empty. +extern inline void* _mi_page_malloc(mi_heap_t* heap, mi_page_t* page, size_t size) mi_attr_noexcept { + mi_assert_internal(page->xblock_size==0||mi_page_block_size(page) >= size); + mi_block_t* block = page->free; + if (mi_unlikely(block == NULL)) { + return _mi_malloc_generic(heap, size); + } + mi_assert_internal(block != NULL && _mi_ptr_page(block) == page); + // pop from the free list + page->free = mi_block_next(page, block); + page->used++; + mi_assert_internal(page->free == NULL || _mi_ptr_page(page->free) == page); +#if (MI_DEBUG>0) + if (!page->is_zero) { memset(block, MI_DEBUG_UNINIT, size); } +#elif (MI_SECURE!=0) + block->next = 0; // don't leak internal data +#endif +#if (MI_STAT>1) + const size_t bsize = mi_page_usable_block_size(page); + if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + const size_t bin = _mi_bin(bsize); + mi_heap_stat_increase(heap, normal[bin], 1); + } +#endif +#if (MI_PADDING > 0) && defined(MI_ENCODE_FREELIST) + mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + mi_page_usable_block_size(page)); + ptrdiff_t delta = ((uint8_t*)padding - (uint8_t*)block - (size - MI_PADDING_SIZE)); + mi_assert_internal(delta >= 0 && mi_page_usable_block_size(page) >= (size - MI_PADDING_SIZE + delta)); + padding->canary = (uint32_t)(mi_ptr_encode(page,block,page->keys)); + padding->delta = (uint32_t)(delta); + uint8_t* fill = (uint8_t*)padding - delta; + const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // set at most N initial padding bytes + for (size_t i = 0; i < maxpad; i++) { fill[i] = MI_DEBUG_PADDING; } +#endif + return block; +} + +// allocate a small block +extern inline mi_decl_restrict void* mi_heap_malloc_small(mi_heap_t* heap, size_t size) mi_attr_noexcept { + mi_assert(heap!=NULL); + mi_assert(heap->thread_id == 0 || heap->thread_id == _mi_thread_id()); // heaps are thread local + mi_assert(size <= MI_SMALL_SIZE_MAX); + #if (MI_PADDING) + if (size == 0) { + size = sizeof(void*); + } + #endif + mi_page_t* page = _mi_heap_get_free_small_page(heap,size + MI_PADDING_SIZE); + void* p = _mi_page_malloc(heap, page, size + MI_PADDING_SIZE); + mi_assert_internal(p==NULL || mi_usable_size(p) >= size); + #if MI_STAT>1 + if (p != NULL) { + if (!mi_heap_is_initialized(heap)) { heap = mi_get_default_heap(); } + mi_heap_stat_increase(heap, malloc, mi_usable_size(p)); + } + #endif + return p; +} + +extern inline mi_decl_restrict void* mi_malloc_small(size_t size) mi_attr_noexcept { + return mi_heap_malloc_small(mi_get_default_heap(), size); +} + +// The main allocation function +extern inline mi_decl_restrict void* mi_heap_malloc(mi_heap_t* heap, size_t size) mi_attr_noexcept { + if (mi_likely(size <= MI_SMALL_SIZE_MAX)) { + return mi_heap_malloc_small(heap, size); + } + else { + mi_assert(heap!=NULL); + mi_assert(heap->thread_id == 0 || heap->thread_id == _mi_thread_id()); // heaps are thread local + void* const p = _mi_malloc_generic(heap, size + MI_PADDING_SIZE); // note: size can overflow but it is detected in malloc_generic + mi_assert_internal(p == NULL || mi_usable_size(p) >= size); + #if MI_STAT>1 + if (p != NULL) { + if (!mi_heap_is_initialized(heap)) { heap = mi_get_default_heap(); } + mi_heap_stat_increase(heap, malloc, mi_usable_size(p)); + } + #endif + return p; + } +} + +extern inline mi_decl_restrict void* mi_malloc(size_t size) mi_attr_noexcept { + return mi_heap_malloc(mi_get_default_heap(), size); +} + + +void _mi_block_zero_init(const mi_page_t* page, void* p, size_t size) { + // note: we need to initialize the whole usable block size to zero, not just the requested size, + // or the recalloc/rezalloc functions cannot safely expand in place (see issue #63) + UNUSED(size); + mi_assert_internal(p != NULL); + mi_assert_internal(mi_usable_size(p) >= size); // size can be zero + mi_assert_internal(_mi_ptr_page(p)==page); + if (page->is_zero && size > sizeof(mi_block_t)) { + // already zero initialized memory + ((mi_block_t*)p)->next = 0; // clear the free list pointer + mi_assert_expensive(mi_mem_is_zero(p, mi_usable_size(p))); + } + else { + // otherwise memset + memset(p, 0, mi_usable_size(p)); + } +} + +// zero initialized small block +mi_decl_restrict void* mi_zalloc_small(size_t size) mi_attr_noexcept { + void* p = mi_malloc_small(size); + if (p != NULL) { + _mi_block_zero_init(_mi_ptr_page(p), p, size); // todo: can we avoid getting the page again? + } + return p; +} + +void* _mi_heap_malloc_zero(mi_heap_t* heap, size_t size, bool zero) { + void* p = mi_heap_malloc(heap,size); + if (zero && p != NULL) { + _mi_block_zero_init(_mi_ptr_page(p),p,size); // todo: can we avoid getting the page again? + } + return p; +} + +extern inline mi_decl_restrict void* mi_heap_zalloc(mi_heap_t* heap, size_t size) mi_attr_noexcept { + return _mi_heap_malloc_zero(heap, size, true); +} + +mi_decl_restrict void* mi_zalloc(size_t size) mi_attr_noexcept { + return mi_heap_zalloc(mi_get_default_heap(),size); +} + + +// ------------------------------------------------------ +// Check for double free in secure and debug mode +// This is somewhat expensive so only enabled for secure mode 4 +// ------------------------------------------------------ + +#if (MI_ENCODE_FREELIST && (MI_SECURE>=4 || MI_DEBUG!=0)) +// linear check if the free list contains a specific element +static bool mi_list_contains(const mi_page_t* page, const mi_block_t* list, const mi_block_t* elem) { + while (list != NULL) { + if (elem==list) return true; + list = mi_block_next(page, list); + } + return false; +} + +static mi_decl_noinline bool mi_check_is_double_freex(const mi_page_t* page, const mi_block_t* block) { + // The decoded value is in the same page (or NULL). + // Walk the free lists to verify positively if it is already freed + if (mi_list_contains(page, page->free, block) || + mi_list_contains(page, page->local_free, block) || + mi_list_contains(page, mi_page_thread_free(page), block)) + { + _mi_error_message(EAGAIN, "double free detected of block %p with size %zu\n", block, mi_page_block_size(page)); + return true; + } + return false; +} + +static inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) { + mi_block_t* n = mi_block_nextx(page, block, page->keys); // pretend it is freed, and get the decoded first field + if (((uintptr_t)n & (MI_INTPTR_SIZE-1))==0 && // quick check: aligned pointer? + (n==NULL || mi_is_in_same_page(block, n))) // quick check: in same page or NULL? + { + // Suspicous: decoded value a in block is in the same page (or NULL) -- maybe a double free? + // (continue in separate function to improve code generation) + return mi_check_is_double_freex(page, block); + } + return false; +} +#else +static inline bool mi_check_is_double_free(const mi_page_t* page, const mi_block_t* block) { + UNUSED(page); + UNUSED(block); + return false; +} +#endif + +// --------------------------------------------------------------------------- +// Check for heap block overflow by setting up padding at the end of the block +// --------------------------------------------------------------------------- + +#if (MI_PADDING>0) && defined(MI_ENCODE_FREELIST) +static bool mi_page_decode_padding(const mi_page_t* page, const mi_block_t* block, size_t* delta, size_t* bsize) { + *bsize = mi_page_usable_block_size(page); + const mi_padding_t* const padding = (mi_padding_t*)((uint8_t*)block + *bsize); + *delta = padding->delta; + return ((uint32_t)mi_ptr_encode(page,block,page->keys) == padding->canary && *delta <= *bsize); +} + +// Return the exact usable size of a block. +static size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block) { + size_t bsize; + size_t delta; + bool ok = mi_page_decode_padding(page, block, &delta, &bsize); + mi_assert_internal(ok); mi_assert_internal(delta <= bsize); + return (ok ? bsize - delta : 0); +} + +static bool mi_verify_padding(const mi_page_t* page, const mi_block_t* block, size_t* size, size_t* wrong) { + size_t bsize; + size_t delta; + bool ok = mi_page_decode_padding(page, block, &delta, &bsize); + *size = *wrong = bsize; + if (!ok) return false; + mi_assert_internal(bsize >= delta); + *size = bsize - delta; + uint8_t* fill = (uint8_t*)block + bsize - delta; + const size_t maxpad = (delta > MI_MAX_ALIGN_SIZE ? MI_MAX_ALIGN_SIZE : delta); // check at most the first N padding bytes + for (size_t i = 0; i < maxpad; i++) { + if (fill[i] != MI_DEBUG_PADDING) { + *wrong = bsize - delta + i; + return false; + } + } + return true; +} + +static void mi_check_padding(const mi_page_t* page, const mi_block_t* block) { + size_t size; + size_t wrong; + if (!mi_verify_padding(page,block,&size,&wrong)) { + _mi_error_message(EFAULT, "buffer overflow in heap block %p of size %zu: write after %zu bytes\n", block, size, wrong ); + } +} + +// When a non-thread-local block is freed, it becomes part of the thread delayed free +// list that is freed later by the owning heap. If the exact usable size is too small to +// contain the pointer for the delayed list, then shrink the padding (by decreasing delta) +// so it will later not trigger an overflow error in `mi_free_block`. +static void mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) { + size_t bsize; + size_t delta; + bool ok = mi_page_decode_padding(page, block, &delta, &bsize); + mi_assert_internal(ok); + if (!ok || (bsize - delta) >= min_size) return; // usually already enough space + mi_assert_internal(bsize >= min_size); + if (bsize < min_size) return; // should never happen + size_t new_delta = (bsize - min_size); + mi_assert_internal(new_delta < bsize); + mi_padding_t* padding = (mi_padding_t*)((uint8_t*)block + bsize); + padding->delta = (uint32_t)new_delta; +} +#else +static void mi_check_padding(const mi_page_t* page, const mi_block_t* block) { + UNUSED(page); + UNUSED(block); +} + +static size_t mi_page_usable_size_of(const mi_page_t* page, const mi_block_t* block) { + UNUSED(block); + return mi_page_usable_block_size(page); +} + +static void mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size) { + UNUSED(page); + UNUSED(block); + UNUSED(min_size); +} +#endif + +// ------------------------------------------------------ +// Free +// ------------------------------------------------------ + +// multi-threaded free +static mi_decl_noinline void _mi_free_block_mt(mi_page_t* page, mi_block_t* block) +{ + // The padding check may access the non-thread-owned page for the key values. + // that is safe as these are constant and the page won't be freed (as the block is not freed yet). + mi_check_padding(page, block); + mi_padding_shrink(page, block, sizeof(mi_block_t)); // for small size, ensure we can fit the delayed thread pointers without triggering overflow detection + #if (MI_DEBUG!=0) + memset(block, MI_DEBUG_FREED, mi_usable_size(block)); + #endif + + // huge page segments are always abandoned and can be freed immediately + mi_segment_t* const segment = _mi_page_segment(page); + if (segment->page_kind==MI_PAGE_HUGE) { + _mi_segment_huge_page_free(segment, page, block); + return; + } + + // Try to put the block on either the page-local thread free list, or the heap delayed free list. + mi_thread_free_t tfree; + mi_thread_free_t tfreex; + bool use_delayed; + do { + tfree = mi_atomic_read_relaxed(&page->xthread_free); + use_delayed = (mi_tf_delayed(tfree) == MI_USE_DELAYED_FREE); + if (mi_unlikely(use_delayed)) { + // unlikely: this only happens on the first concurrent free in a page that is in the full list + tfreex = mi_tf_set_delayed(tfree,MI_DELAYED_FREEING); + } + else { + // usual: directly add to page thread_free list + mi_block_set_next(page, block, mi_tf_block(tfree)); + tfreex = mi_tf_set_block(tfree,block); + } + } while (!mi_atomic_cas_weak(&page->xthread_free, tfreex, tfree)); + + if (mi_unlikely(use_delayed)) { + // racy read on `heap`, but ok because MI_DELAYED_FREEING is set (see `mi_heap_delete` and `mi_heap_collect_abandon`) + mi_heap_t* const heap = mi_page_heap(page); + mi_assert_internal(heap != NULL); + if (heap != NULL) { + // add to the delayed free list of this heap. (do this atomically as the lock only protects heap memory validity) + mi_block_t* dfree; + do { + dfree = mi_atomic_read_ptr_relaxed(mi_block_t,&heap->thread_delayed_free); + mi_block_set_nextx(heap,block,dfree, heap->keys); + } while (!mi_atomic_cas_ptr_weak(mi_block_t,&heap->thread_delayed_free, block, dfree)); + } + + // and reset the MI_DELAYED_FREEING flag + do { + tfreex = tfree = mi_atomic_read_relaxed(&page->xthread_free); + mi_assert_internal(mi_tf_delayed(tfree) == MI_DELAYED_FREEING); + tfreex = mi_tf_set_delayed(tfree,MI_NO_DELAYED_FREE); + } while (!mi_atomic_cas_weak(&page->xthread_free, tfreex, tfree)); + } +} + + +// regular free +static inline void _mi_free_block(mi_page_t* page, bool local, mi_block_t* block) +{ + // and push it on the free list + if (mi_likely(local)) { + // owning thread can free a block directly + if (mi_unlikely(mi_check_is_double_free(page, block))) return; + mi_check_padding(page, block); + #if (MI_DEBUG!=0) + memset(block, MI_DEBUG_FREED, mi_page_block_size(page)); + #endif + mi_block_set_next(page, block, page->local_free); + page->local_free = block; + page->used--; + if (mi_unlikely(mi_page_all_free(page))) { + _mi_page_retire(page); + } + else if (mi_unlikely(mi_page_is_in_full(page))) { + _mi_page_unfull(page); + } + } + else { + _mi_free_block_mt(page,block); + } +} + + +// Adjust a block that was allocated aligned, to the actual start of the block in the page. +mi_block_t* _mi_page_ptr_unalign(const mi_segment_t* segment, const mi_page_t* page, const void* p) { + mi_assert_internal(page!=NULL && p!=NULL); + const size_t diff = (uint8_t*)p - _mi_page_start(segment, page, NULL); + const size_t adjust = (diff % mi_page_block_size(page)); + return (mi_block_t*)((uintptr_t)p - adjust); +} + + +static void mi_decl_noinline mi_free_generic(const mi_segment_t* segment, bool local, void* p) { + mi_page_t* const page = _mi_segment_page_of(segment, p); + mi_block_t* const block = (mi_page_has_aligned(page) ? _mi_page_ptr_unalign(segment, page, p) : (mi_block_t*)p); + _mi_free_block(page, local, block); +} + +// Get the segment data belonging to a pointer +// This is just a single `and` in assembly but does further checks in debug mode +// (and secure mode) if this was a valid pointer. +static inline mi_segment_t* mi_checked_ptr_segment(const void* p, const char* msg) +{ + UNUSED(msg); +#if (MI_DEBUG>0) + if (mi_unlikely(((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0)) { + _mi_error_message(EINVAL, "%s: invalid (unaligned) pointer: %p\n", msg, p); + return NULL; + } +#endif + + mi_segment_t* const segment = _mi_ptr_segment(p); + if (mi_unlikely(segment == NULL)) return NULL; // checks also for (p==NULL) + +#if (MI_DEBUG>0) + if (mi_unlikely(!mi_is_in_heap_region(p))) { + _mi_warning_message("%s: pointer might not point to a valid heap region: %p\n" + "(this may still be a valid very large allocation (over 64MiB))\n", msg, p); + if (mi_likely(_mi_ptr_cookie(segment) == segment->cookie)) { + _mi_warning_message("(yes, the previous pointer %p was valid after all)\n", p); + } + } +#endif +#if (MI_DEBUG>0 || MI_SECURE>=4) + if (mi_unlikely(_mi_ptr_cookie(segment) != segment->cookie)) { + _mi_error_message(EINVAL, "%s: pointer does not point to a valid heap space: %p\n", p); + } +#endif + return segment; +} + + +// Free a block +void mi_free(void* p) mi_attr_noexcept +{ + const mi_segment_t* const segment = mi_checked_ptr_segment(p,"mi_free"); + if (mi_unlikely(segment == NULL)) return; + + const uintptr_t tid = _mi_thread_id(); + mi_page_t* const page = _mi_segment_page_of(segment, p); + mi_block_t* const block = (mi_block_t*)p; + +#if (MI_STAT>1) + mi_heap_t* const heap = mi_heap_get_default(); + const size_t bsize = mi_page_usable_block_size(page); + mi_heap_stat_decrease(heap, malloc, bsize); + if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { // huge page stats are accounted for in `_mi_page_retire` + mi_heap_stat_decrease(heap, normal[_mi_bin(bsize)], 1); + } +#endif + + if (mi_likely(tid == segment->thread_id && page->flags.full_aligned == 0)) { // the thread id matches and it is not a full page, nor has aligned blocks + // local, and not full or aligned + if (mi_unlikely(mi_check_is_double_free(page,block))) return; + mi_check_padding(page, block); + #if (MI_DEBUG!=0) + memset(block, MI_DEBUG_FREED, mi_page_block_size(page)); + #endif + mi_block_set_next(page, block, page->local_free); + page->local_free = block; + page->used--; + if (mi_unlikely(mi_page_all_free(page))) { + _mi_page_retire(page); + } + } + else { + // non-local, aligned blocks, or a full page; use the more generic path + // note: recalc page in generic to improve code generation + mi_free_generic(segment, tid == segment->thread_id, p); + } +} + +bool _mi_free_delayed_block(mi_block_t* block) { + // get segment and page + const mi_segment_t* const segment = _mi_ptr_segment(block); + mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie); + mi_assert_internal(_mi_thread_id() == segment->thread_id); + mi_page_t* const page = _mi_segment_page_of(segment, block); + + // Clear the no-delayed flag so delayed freeing is used again for this page. + // This must be done before collecting the free lists on this page -- otherwise + // some blocks may end up in the page `thread_free` list with no blocks in the + // heap `thread_delayed_free` list which may cause the page to be never freed! + // (it would only be freed if we happen to scan it in `mi_page_queue_find_free_ex`) + _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, false /* dont overwrite never delayed */); + + // collect all other non-local frees to ensure up-to-date `used` count + _mi_page_free_collect(page, false); + + // and free the block (possibly freeing the page as well since used is updated) + _mi_free_block(page, true, block); + return true; +} + +// Bytes available in a block +static size_t _mi_usable_size(const void* p, const char* msg) mi_attr_noexcept { + const mi_segment_t* const segment = mi_checked_ptr_segment(p,msg); + if (segment==NULL) return 0; + const mi_page_t* const page = _mi_segment_page_of(segment, p); + const mi_block_t* block = (const mi_block_t*)p; + if (mi_unlikely(mi_page_has_aligned(page))) { + block = _mi_page_ptr_unalign(segment, page, p); + size_t size = mi_page_usable_size_of(page, block); + ptrdiff_t const adjust = (uint8_t*)p - (uint8_t*)block; + mi_assert_internal(adjust >= 0 && (size_t)adjust <= size); + return (size - adjust); + } + else { + return mi_page_usable_size_of(page, block); + } +} + +size_t mi_usable_size(const void* p) mi_attr_noexcept { + return _mi_usable_size(p, "mi_usable_size"); +} + + +// ------------------------------------------------------ +// ensure explicit external inline definitions are emitted! +// ------------------------------------------------------ + +#ifdef __cplusplus +void* _mi_externs[] = { + (void*)&_mi_page_malloc, + (void*)&mi_malloc, + (void*)&mi_malloc_small, + (void*)&mi_heap_malloc, + (void*)&mi_heap_zalloc, + (void*)&mi_heap_malloc_small +}; +#endif + + +// ------------------------------------------------------ +// Allocation extensions +// ------------------------------------------------------ + +void mi_free_size(void* p, size_t size) mi_attr_noexcept { + UNUSED_RELEASE(size); + mi_assert(p == NULL || size <= _mi_usable_size(p,"mi_free_size")); + mi_free(p); +} + +void mi_free_size_aligned(void* p, size_t size, size_t alignment) mi_attr_noexcept { + UNUSED_RELEASE(alignment); + mi_assert(((uintptr_t)p % alignment) == 0); + mi_free_size(p,size); +} + +void mi_free_aligned(void* p, size_t alignment) mi_attr_noexcept { + UNUSED_RELEASE(alignment); + mi_assert(((uintptr_t)p % alignment) == 0); + mi_free(p); +} + +extern inline mi_decl_restrict void* mi_heap_calloc(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count,size,&total)) return NULL; + return mi_heap_zalloc(heap,total); +} + +mi_decl_restrict void* mi_calloc(size_t count, size_t size) mi_attr_noexcept { + return mi_heap_calloc(mi_get_default_heap(),count,size); +} + +// Uninitialized `calloc` +extern mi_decl_restrict void* mi_heap_mallocn(mi_heap_t* heap, size_t count, size_t size) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count, size, &total)) return NULL; + return mi_heap_malloc(heap, total); +} + +mi_decl_restrict void* mi_mallocn(size_t count, size_t size) mi_attr_noexcept { + return mi_heap_mallocn(mi_get_default_heap(),count,size); +} + +// Expand in place or fail +void* mi_expand(void* p, size_t newsize) mi_attr_noexcept { + if (p == NULL) return NULL; + size_t size = _mi_usable_size(p,"mi_expand"); + if (newsize > size) return NULL; + return p; // it fits +} + +void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) { + if (p == NULL) return _mi_heap_malloc_zero(heap,newsize,zero); + size_t size = _mi_usable_size(p,"mi_realloc"); + if (newsize <= size && newsize >= (size / 2)) { + return p; // reallocation still fits and not more than 50% waste + } + void* newp = mi_heap_malloc(heap,newsize); + if (mi_likely(newp != NULL)) { + if (zero && newsize > size) { + // also set last word in the previous allocation to zero to ensure any padding is zero-initialized + size_t start = (size >= sizeof(intptr_t) ? size - sizeof(intptr_t) : 0); + memset((uint8_t*)newp + start, 0, newsize - start); + } + memcpy(newp, p, (newsize > size ? size : newsize)); + mi_free(p); // only free if successful + } + return newp; +} + +void* mi_heap_realloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept { + return _mi_heap_realloc_zero(heap, p, newsize, false); +} + +void* mi_heap_reallocn(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count, size, &total)) return NULL; + return mi_heap_realloc(heap, p, total); +} + + +// Reallocate but free `p` on errors +void* mi_heap_reallocf(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept { + void* newp = mi_heap_realloc(heap, p, newsize); + if (newp==NULL && p!=NULL) mi_free(p); + return newp; +} + +void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize) mi_attr_noexcept { + return _mi_heap_realloc_zero(heap, p, newsize, true); +} + +void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t count, size_t size) mi_attr_noexcept { + size_t total; + if (mi_count_size_overflow(count, size, &total)) return NULL; + return mi_heap_rezalloc(heap, p, total); +} + + +void* mi_realloc(void* p, size_t newsize) mi_attr_noexcept { + return mi_heap_realloc(mi_get_default_heap(),p,newsize); +} + +void* mi_reallocn(void* p, size_t count, size_t size) mi_attr_noexcept { + return mi_heap_reallocn(mi_get_default_heap(),p,count,size); +} + +// Reallocate but free `p` on errors +void* mi_reallocf(void* p, size_t newsize) mi_attr_noexcept { + return mi_heap_reallocf(mi_get_default_heap(),p,newsize); +} + +void* mi_rezalloc(void* p, size_t newsize) mi_attr_noexcept { + return mi_heap_rezalloc(mi_get_default_heap(), p, newsize); +} + +void* mi_recalloc(void* p, size_t count, size_t size) mi_attr_noexcept { + return mi_heap_recalloc(mi_get_default_heap(), p, count, size); +} + + + +// ------------------------------------------------------ +// strdup, strndup, and realpath +// ------------------------------------------------------ + +// `strdup` using mi_malloc +mi_decl_restrict char* mi_heap_strdup(mi_heap_t* heap, const char* s) mi_attr_noexcept { + if (s == NULL) return NULL; + size_t n = strlen(s); + char* t = (char*)mi_heap_malloc(heap,n+1); + if (t != NULL) memcpy(t, s, n + 1); + return t; +} + +mi_decl_restrict char* mi_strdup(const char* s) mi_attr_noexcept { + return mi_heap_strdup(mi_get_default_heap(), s); +} + +// `strndup` using mi_malloc +mi_decl_restrict char* mi_heap_strndup(mi_heap_t* heap, const char* s, size_t n) mi_attr_noexcept { + if (s == NULL) return NULL; + const char* end = (const char*)memchr(s, 0, n); // find end of string in the first `n` characters (returns NULL if not found) + const size_t m = (end != NULL ? (size_t)(end - s) : n); // `m` is the minimum of `n` or the end-of-string + mi_assert_internal(m <= n); + char* t = (char*)mi_heap_malloc(heap, m+1); + if (t == NULL) return NULL; + memcpy(t, s, m); + t[m] = 0; + return t; +} + +mi_decl_restrict char* mi_strndup(const char* s, size_t n) mi_attr_noexcept { + return mi_heap_strndup(mi_get_default_heap(),s,n); +} + +#ifndef __wasi__ +// `realpath` using mi_malloc +#ifdef _WIN32 +#ifndef PATH_MAX +#define PATH_MAX MAX_PATH +#endif +#include +mi_decl_restrict char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept { + // todo: use GetFullPathNameW to allow longer file names + char buf[PATH_MAX]; + DWORD res = GetFullPathNameA(fname, PATH_MAX, (resolved_name == NULL ? buf : resolved_name), NULL); + if (res == 0) { + errno = GetLastError(); return NULL; + } + else if (res > PATH_MAX) { + errno = EINVAL; return NULL; + } + else if (resolved_name != NULL) { + return resolved_name; + } + else { + return mi_heap_strndup(heap, buf, PATH_MAX); + } +} +#else +#include // pathconf +static size_t mi_path_max() { + static size_t path_max = 0; + if (path_max <= 0) { + long m = pathconf("/",_PC_PATH_MAX); + if (m <= 0) path_max = 4096; // guess + else if (m < 256) path_max = 256; // at least 256 + else path_max = m; + } + return path_max; +} + +char* mi_heap_realpath(mi_heap_t* heap, const char* fname, char* resolved_name) mi_attr_noexcept { + if (resolved_name != NULL) { + return realpath(fname,resolved_name); + } + else { + size_t n = mi_path_max(); + char* buf = (char*)mi_malloc(n+1); + if (buf==NULL) return NULL; + char* rname = realpath(fname,buf); + char* result = mi_heap_strndup(heap,rname,n); // ok if `rname==NULL` + mi_free(buf); + return result; + } +} +#endif + +mi_decl_restrict char* mi_realpath(const char* fname, char* resolved_name) mi_attr_noexcept { + return mi_heap_realpath(mi_get_default_heap(),fname,resolved_name); +} +#endif + +/*------------------------------------------------------- +C++ new and new_aligned +The standard requires calling into `get_new_handler` and +throwing the bad_alloc exception on failure. If we compile +with a C++ compiler we can implement this precisely. If we +use a C compiler we cannot throw a `bad_alloc` exception +but we call `exit` instead (i.e. not returning). +-------------------------------------------------------*/ + +#ifdef __cplusplus +#include +static bool mi_try_new_handler(bool nothrow) { + std::new_handler h = std::get_new_handler(); + if (h==NULL) { + if (!nothrow) throw std::bad_alloc(); + return false; + } + else { + h(); + return true; + } +} +#else +typedef void (*std_new_handler_t)(); + +#if (defined(__GNUC__) || defined(__clang__)) +std_new_handler_t __attribute((weak)) _ZSt15get_new_handlerv() { + return NULL; +} +std_new_handler_t mi_get_new_handler() { + return _ZSt15get_new_handlerv(); +} +#else +// note: on windows we could dynamically link to `?get_new_handler@std@@YAP6AXXZXZ`. +std_new_handler_t mi_get_new_handler() { + return NULL; +} +#endif + +static bool mi_try_new_handler(bool nothrow) { + std_new_handler_t h = mi_get_new_handler(); + if (h==NULL) { + if (!nothrow) exit(ENOMEM); // cannot throw in plain C, use exit as we are out of memory anyway. + return false; + } + else { + h(); + return true; + } +} +#endif + +static mi_decl_noinline void* mi_try_new(size_t size, bool nothrow ) { + void* p = NULL; + while(p == NULL && mi_try_new_handler(nothrow)) { + p = mi_malloc(size); + } + return p; +} + +mi_decl_restrict void* mi_new(size_t size) { + void* p = mi_malloc(size); + if (mi_unlikely(p == NULL)) return mi_try_new(size,false); + return p; +} + +mi_decl_restrict void* mi_new_nothrow(size_t size) mi_attr_noexcept { + void* p = mi_malloc(size); + if (mi_unlikely(p == NULL)) return mi_try_new(size, true); + return p; +} + +mi_decl_restrict void* mi_new_aligned(size_t size, size_t alignment) { + void* p; + do { + p = mi_malloc_aligned(size, alignment); + } + while(p == NULL && mi_try_new_handler(false)); + return p; +} + +mi_decl_restrict void* mi_new_aligned_nothrow(size_t size, size_t alignment) mi_attr_noexcept { + void* p; + do { + p = mi_malloc_aligned(size, alignment); + } + while(p == NULL && mi_try_new_handler(true)); + return p; +} + +mi_decl_restrict void* mi_new_n(size_t count, size_t size) { + size_t total; + if (mi_unlikely(mi_count_size_overflow(count, size, &total))) { + mi_try_new_handler(false); // on overflow we invoke the try_new_handler once to potentially throw std::bad_alloc + return NULL; + } + else { + return mi_new(total); + } +} + +void* mi_new_realloc(void* p, size_t newsize) { + void* q; + do { + q = mi_realloc(p, newsize); + } while (q == NULL && mi_try_new_handler(false)); + return q; +} + +void* mi_new_reallocn(void* p, size_t newcount, size_t size) { + size_t total; + if (mi_unlikely(mi_count_size_overflow(newcount, size, &total))) { + mi_try_new_handler(false); // on overflow we invoke the try_new_handler once to potentially throw std::bad_alloc + return NULL; + } + else { + return mi_new_realloc(p, total); + } +} diff --git a/extlib/mimalloc/src/arena.c b/extlib/mimalloc/src/arena.c new file mode 100644 index 0000000..bb9fc17 --- /dev/null +++ b/extlib/mimalloc/src/arena.c @@ -0,0 +1,357 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2019, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ---------------------------------------------------------------------------- +"Arenas" are fixed area's of OS memory from which we can allocate +large blocks (>= MI_ARENA_BLOCK_SIZE, 32MiB). +In contrast to the rest of mimalloc, the arenas are shared between +threads and need to be accessed using atomic operations. + +Currently arenas are only used to for huge OS page (1GiB) reservations, +otherwise it delegates to direct allocation from the OS. +In the future, we can expose an API to manually add more kinds of arenas +which is sometimes needed for embedded devices or shared memory for example. +(We can also employ this with WASI or `sbrk` systems to reserve large arenas + on demand and be able to reuse them efficiently). + +The arena allocation needs to be thread safe and we use an atomic +bitmap to allocate. The current implementation of the bitmap can +only do this within a field (`uintptr_t`) so we can allocate at most +blocks of 2GiB (64*32MiB) and no object can cross the boundary. This +can lead to fragmentation but fortunately most objects will be regions +of 256MiB in practice. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc-internal.h" +#include "mimalloc-atomic.h" + +#include // memset + +#include "bitmap.inc.c" // atomic bitmap + + +// os.c +void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool* large, mi_os_tld_t* tld); +void _mi_os_free_ex(void* p, size_t size, bool was_committed, mi_stats_t* stats); +void _mi_os_free(void* p, size_t size, mi_stats_t* stats); + +void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_secs, size_t* pages_reserved, size_t* psize); +void _mi_os_free_huge_pages(void* p, size_t size, mi_stats_t* stats); + +bool _mi_os_commit(void* p, size_t size, bool* is_zero, mi_stats_t* stats); + +/* ----------------------------------------------------------- + Arena allocation +----------------------------------------------------------- */ + +#define MI_SEGMENT_ALIGN MI_SEGMENT_SIZE +#define MI_ARENA_BLOCK_SIZE (8*MI_SEGMENT_ALIGN) // 32MiB +#define MI_ARENA_MAX_OBJ_SIZE (MI_BITMAP_FIELD_BITS * MI_ARENA_BLOCK_SIZE) // 2GiB +#define MI_ARENA_MIN_OBJ_SIZE (MI_ARENA_BLOCK_SIZE/2) // 16MiB +#define MI_MAX_ARENAS (64) // not more than 256 (since we use 8 bits in the memid) + +// A memory arena descriptor +typedef struct mi_arena_s { + _Atomic(uint8_t*) start; // the start of the memory area + size_t block_count; // size of the area in arena blocks (of `MI_ARENA_BLOCK_SIZE`) + size_t field_count; // number of bitmap fields (where `field_count * MI_BITMAP_FIELD_BITS >= block_count`) + int numa_node; // associated NUMA node + bool is_zero_init; // is the arena zero initialized? + bool is_committed; // is the memory committed + bool is_large; // large OS page allocated + volatile _Atomic(uintptr_t) search_idx; // optimization to start the search for free blocks + mi_bitmap_field_t* blocks_dirty; // are the blocks potentially non-zero? + mi_bitmap_field_t* blocks_committed; // if `!is_committed`, are the blocks committed? + mi_bitmap_field_t blocks_inuse[1]; // in-place bitmap of in-use blocks (of size `field_count`) +} mi_arena_t; + + +// The available arenas +static mi_decl_cache_align _Atomic(mi_arena_t*) mi_arenas[MI_MAX_ARENAS]; +static mi_decl_cache_align _Atomic(uintptr_t) mi_arena_count; // = 0 + + +/* ----------------------------------------------------------- + Arena allocations get a memory id where the lower 8 bits are + the arena index +1, and the upper bits the block index. +----------------------------------------------------------- */ + +// Use `0` as a special id for direct OS allocated memory. +#define MI_MEMID_OS 0 + +static size_t mi_arena_id_create(size_t arena_index, mi_bitmap_index_t bitmap_index) { + mi_assert_internal(arena_index < 0xFE); + mi_assert_internal(((bitmap_index << 8) >> 8) == bitmap_index); // no overflow? + return ((bitmap_index << 8) | ((arena_index+1) & 0xFF)); +} + +static void mi_arena_id_indices(size_t memid, size_t* arena_index, mi_bitmap_index_t* bitmap_index) { + mi_assert_internal(memid != MI_MEMID_OS); + *arena_index = (memid & 0xFF) - 1; + *bitmap_index = (memid >> 8); +} + +static size_t mi_block_count_of_size(size_t size) { + return _mi_divide_up(size, MI_ARENA_BLOCK_SIZE); +} + +/* ----------------------------------------------------------- + Thread safe allocation in an arena +----------------------------------------------------------- */ +static bool mi_arena_alloc(mi_arena_t* arena, size_t blocks, mi_bitmap_index_t* bitmap_idx) +{ + const size_t fcount = arena->field_count; + size_t idx = mi_atomic_read(&arena->search_idx); // start from last search + for (size_t visited = 0; visited < fcount; visited++, idx++) { + if (idx >= fcount) idx = 0; // wrap around + // try to atomically claim a range of bits + if (mi_bitmap_try_find_claim_field(arena->blocks_inuse, idx, blocks, bitmap_idx)) { + mi_atomic_write(&arena->search_idx, idx); // start search from here next time + return true; + } + } + return false; +} + + +/* ----------------------------------------------------------- + Arena Allocation +----------------------------------------------------------- */ + +static void* mi_arena_alloc_from(mi_arena_t* arena, size_t arena_index, size_t needed_bcount, + bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld) +{ + mi_bitmap_index_t bitmap_index; + if (!mi_arena_alloc(arena, needed_bcount, &bitmap_index)) return NULL; + + // claimed it! set the dirty bits (todo: no need for an atomic op here?) + void* p = arena->start + (mi_bitmap_index_bit(bitmap_index)*MI_ARENA_BLOCK_SIZE); + *memid = mi_arena_id_create(arena_index, bitmap_index); + *is_zero = mi_bitmap_claim(arena->blocks_dirty, arena->field_count, needed_bcount, bitmap_index, NULL); + *large = arena->is_large; + if (arena->is_committed) { + // always committed + *commit = true; + } + else if (*commit) { + // arena not committed as a whole, but commit requested: ensure commit now + bool any_uncommitted; + mi_bitmap_claim(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index, &any_uncommitted); + if (any_uncommitted) { + bool commit_zero; + _mi_os_commit(p, needed_bcount * MI_ARENA_BLOCK_SIZE, &commit_zero, tld->stats); + if (commit_zero) *is_zero = true; + } + } + else { + // no need to commit, but check if already fully committed + *commit = mi_bitmap_is_claimed(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index); + } + return p; +} + +void* _mi_arena_alloc_aligned(size_t size, size_t alignment, + bool* commit, bool* large, bool* is_zero, + size_t* memid, mi_os_tld_t* tld) +{ + mi_assert_internal(commit != NULL && large != NULL && is_zero != NULL && memid != NULL && tld != NULL); + mi_assert_internal(size > 0); + *memid = MI_MEMID_OS; + *is_zero = false; + + // try to allocate in an arena if the alignment is small enough + // and the object is not too large or too small. + if (alignment <= MI_SEGMENT_ALIGN && + size <= MI_ARENA_MAX_OBJ_SIZE && + size >= MI_ARENA_MIN_OBJ_SIZE) + { + const size_t bcount = mi_block_count_of_size(size); + const int numa_node = _mi_os_numa_node(tld); // current numa node + + mi_assert_internal(size <= bcount*MI_ARENA_BLOCK_SIZE); + // try numa affine allocation + for (size_t i = 0; i < MI_MAX_ARENAS; i++) { + mi_arena_t* arena = mi_atomic_read_ptr_relaxed(mi_arena_t, &mi_arenas[i]); + if (arena==NULL) break; // end reached + if ((arena->numa_node<0 || arena->numa_node==numa_node) && // numa local? + (*large || !arena->is_large)) // large OS pages allowed, or arena is not large OS pages + { + void* p = mi_arena_alloc_from(arena, i, bcount, commit, large, is_zero, memid, tld); + mi_assert_internal((uintptr_t)p % alignment == 0); + if (p != NULL) return p; + } + } + // try from another numa node instead.. + for (size_t i = 0; i < MI_MAX_ARENAS; i++) { + mi_arena_t* arena = mi_atomic_read_ptr_relaxed(mi_arena_t, &mi_arenas[i]); + if (arena==NULL) break; // end reached + if ((arena->numa_node>=0 && arena->numa_node!=numa_node) && // not numa local! + (*large || !arena->is_large)) // large OS pages allowed, or arena is not large OS pages + { + void* p = mi_arena_alloc_from(arena, i, bcount, commit, large, is_zero, memid, tld); + mi_assert_internal((uintptr_t)p % alignment == 0); + if (p != NULL) return p; + } + } + } + + // finally, fall back to the OS + *is_zero = true; + *memid = MI_MEMID_OS; + return _mi_os_alloc_aligned(size, alignment, *commit, large, tld); +} + +void* _mi_arena_alloc(size_t size, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld) +{ + return _mi_arena_alloc_aligned(size, MI_ARENA_BLOCK_SIZE, commit, large, is_zero, memid, tld); +} + +/* ----------------------------------------------------------- + Arena free +----------------------------------------------------------- */ + +void _mi_arena_free(void* p, size_t size, size_t memid, bool all_committed, mi_stats_t* stats) { + mi_assert_internal(size > 0 && stats != NULL); + if (p==NULL) return; + if (size==0) return; + if (memid == MI_MEMID_OS) { + // was a direct OS allocation, pass through + _mi_os_free_ex(p, size, all_committed, stats); + } + else { + // allocated in an arena + size_t arena_idx; + size_t bitmap_idx; + mi_arena_id_indices(memid, &arena_idx, &bitmap_idx); + mi_assert_internal(arena_idx < MI_MAX_ARENAS); + mi_arena_t* arena = mi_atomic_read_ptr_relaxed(mi_arena_t,&mi_arenas[arena_idx]); + mi_assert_internal(arena != NULL); + if (arena == NULL) { + _mi_error_message(EINVAL, "trying to free from non-existent arena: %p, size %zu, memid: 0x%zx\n", p, size, memid); + return; + } + mi_assert_internal(arena->field_count > mi_bitmap_index_field(bitmap_idx)); + if (arena->field_count <= mi_bitmap_index_field(bitmap_idx)) { + _mi_error_message(EINVAL, "trying to free from non-existent arena block: %p, size %zu, memid: 0x%zx\n", p, size, memid); + return; + } + const size_t blocks = mi_block_count_of_size(size); + bool ones = mi_bitmap_unclaim(arena->blocks_inuse, arena->field_count, blocks, bitmap_idx); + if (!ones) { + _mi_error_message(EAGAIN, "trying to free an already freed block: %p, size %zu\n", p, size); + return; + }; + } +} + +/* ----------------------------------------------------------- + Add an arena. +----------------------------------------------------------- */ + +static bool mi_arena_add(mi_arena_t* arena) { + mi_assert_internal(arena != NULL); + mi_assert_internal((uintptr_t)mi_atomic_read_ptr_relaxed(uint8_t,&arena->start) % MI_SEGMENT_ALIGN == 0); + mi_assert_internal(arena->block_count > 0); + + uintptr_t i = mi_atomic_increment(&mi_arena_count); + if (i >= MI_MAX_ARENAS) { + mi_atomic_decrement(&mi_arena_count); + return false; + } + mi_atomic_write_ptr(mi_arena_t,&mi_arenas[i], arena); + return true; +} + + +/* ----------------------------------------------------------- + Reserve a huge page arena. +----------------------------------------------------------- */ +#include // ENOMEM + +// reserve at a specific numa node +int mi_reserve_huge_os_pages_at(size_t pages, int numa_node, size_t timeout_msecs) mi_attr_noexcept { + if (pages==0) return 0; + if (numa_node < -1) numa_node = -1; + if (numa_node >= 0) numa_node = numa_node % _mi_os_numa_node_count(); + size_t hsize = 0; + size_t pages_reserved = 0; + void* p = _mi_os_alloc_huge_os_pages(pages, numa_node, timeout_msecs, &pages_reserved, &hsize); + if (p==NULL || pages_reserved==0) { + _mi_warning_message("failed to reserve %zu gb huge pages\n", pages); + return ENOMEM; + } + _mi_verbose_message("numa node %i: reserved %zu gb huge pages (of the %zu gb requested)\n", numa_node, pages_reserved, pages); + + size_t bcount = mi_block_count_of_size(hsize); + size_t fields = _mi_divide_up(bcount, MI_BITMAP_FIELD_BITS); + size_t asize = sizeof(mi_arena_t) + (2*fields*sizeof(mi_bitmap_field_t)); + mi_arena_t* arena = (mi_arena_t*)_mi_os_alloc(asize, &_mi_stats_main); // TODO: can we avoid allocating from the OS? + if (arena == NULL) { + _mi_os_free_huge_pages(p, hsize, &_mi_stats_main); + return ENOMEM; + } + arena->block_count = bcount; + arena->field_count = fields; + arena->start = (uint8_t*)p; + arena->numa_node = numa_node; // TODO: or get the current numa node if -1? (now it allows anyone to allocate on -1) + arena->is_large = true; + arena->is_zero_init = true; + arena->is_committed = true; + arena->search_idx = 0; + arena->blocks_dirty = &arena->blocks_inuse[fields]; // just after inuse bitmap + arena->blocks_committed = NULL; + // the bitmaps are already zero initialized due to os_alloc + // just claim leftover blocks if needed + ptrdiff_t post = (fields * MI_BITMAP_FIELD_BITS) - bcount; + mi_assert_internal(post >= 0); + if (post > 0) { + // don't use leftover bits at the end + mi_bitmap_index_t postidx = mi_bitmap_index_create(fields - 1, MI_BITMAP_FIELD_BITS - post); + mi_bitmap_claim(arena->blocks_inuse, fields, post, postidx, NULL); + } + + mi_arena_add(arena); + return 0; +} + + +// reserve huge pages evenly among the given number of numa nodes (or use the available ones as detected) +int mi_reserve_huge_os_pages_interleave(size_t pages, size_t numa_nodes, size_t timeout_msecs) mi_attr_noexcept { + if (pages == 0) return 0; + + // pages per numa node + size_t numa_count = (numa_nodes > 0 ? numa_nodes : _mi_os_numa_node_count()); + if (numa_count <= 0) numa_count = 1; + const size_t pages_per = pages / numa_count; + const size_t pages_mod = pages % numa_count; + const size_t timeout_per = (timeout_msecs==0 ? 0 : (timeout_msecs / numa_count) + 50); + + // reserve evenly among numa nodes + for (size_t numa_node = 0; numa_node < numa_count && pages > 0; numa_node++) { + size_t node_pages = pages_per; // can be 0 + if (numa_node < pages_mod) node_pages++; + int err = mi_reserve_huge_os_pages_at(node_pages, (int)numa_node, timeout_per); + if (err) return err; + if (pages < node_pages) { + pages = 0; + } + else { + pages -= node_pages; + } + } + + return 0; +} + +int mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved) mi_attr_noexcept { + UNUSED(max_secs); + _mi_warning_message("mi_reserve_huge_os_pages is deprecated: use mi_reserve_huge_os_pages_interleave/at instead\n"); + if (pages_reserved != NULL) *pages_reserved = 0; + int err = mi_reserve_huge_os_pages_interleave(pages, 0, (size_t)(max_secs * 1000.0)); + if (err==0 && pages_reserved!=NULL) *pages_reserved = pages; + return err; +} diff --git a/extlib/mimalloc/src/bitmap.inc.c b/extlib/mimalloc/src/bitmap.inc.c new file mode 100644 index 0000000..c3813a4 --- /dev/null +++ b/extlib/mimalloc/src/bitmap.inc.c @@ -0,0 +1,240 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2019, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ---------------------------------------------------------------------------- +This file is meant to be included in other files for efficiency. +It implements a bitmap that can set/reset sequences of bits atomically +and is used to concurrently claim memory ranges. + +A bitmap is an array of fields where each field is a machine word (`uintptr_t`) + +A current limitation is that the bit sequences cannot cross fields +and that the sequence must be smaller or equal to the bits in a field. +---------------------------------------------------------------------------- */ +#pragma once +#ifndef MI_BITMAP_C +#define MI_BITMAP_C + +#include "mimalloc.h" +#include "mimalloc-internal.h" + +/* ----------------------------------------------------------- + Bitmap definition +----------------------------------------------------------- */ + +#define MI_BITMAP_FIELD_BITS (8*MI_INTPTR_SIZE) +#define MI_BITMAP_FIELD_FULL (~((uintptr_t)0)) // all bits set + +// An atomic bitmap of `uintptr_t` fields +typedef volatile _Atomic(uintptr_t) mi_bitmap_field_t; +typedef mi_bitmap_field_t* mi_bitmap_t; + +// A bitmap index is the index of the bit in a bitmap. +typedef size_t mi_bitmap_index_t; + +// Create a bit index. +static inline mi_bitmap_index_t mi_bitmap_index_create(size_t idx, size_t bitidx) { + mi_assert_internal(bitidx < MI_BITMAP_FIELD_BITS); + return (idx*MI_BITMAP_FIELD_BITS) + bitidx; +} + +// Get the field index from a bit index. +static inline size_t mi_bitmap_index_field(mi_bitmap_index_t bitmap_idx) { + return (bitmap_idx / MI_BITMAP_FIELD_BITS); +} + +// Get the bit index in a bitmap field +static inline size_t mi_bitmap_index_bit_in_field(mi_bitmap_index_t bitmap_idx) { + return (bitmap_idx % MI_BITMAP_FIELD_BITS); +} + +// Get the full bit index +static inline size_t mi_bitmap_index_bit(mi_bitmap_index_t bitmap_idx) { + return bitmap_idx; +} + + +// The bit mask for a given number of blocks at a specified bit index. +static inline uintptr_t mi_bitmap_mask_(size_t count, size_t bitidx) { + mi_assert_internal(count + bitidx <= MI_BITMAP_FIELD_BITS); + if (count == MI_BITMAP_FIELD_BITS) return MI_BITMAP_FIELD_FULL; + return ((((uintptr_t)1 << count) - 1) << bitidx); +} + + +/* ----------------------------------------------------------- + Use bit scan forward/reverse to quickly find the first zero bit if it is available +----------------------------------------------------------- */ +#if defined(_MSC_VER) +#define MI_HAVE_BITSCAN +#include +static inline size_t mi_bsf(uintptr_t x) { + if (x==0) return 8*MI_INTPTR_SIZE; + DWORD idx; + MI_64(_BitScanForward)(&idx, x); + return idx; +} +static inline size_t mi_bsr(uintptr_t x) { + if (x==0) return 8*MI_INTPTR_SIZE; + DWORD idx; + MI_64(_BitScanReverse)(&idx, x); + return idx; +} +#elif defined(__GNUC__) || defined(__clang__) +#include // LONG_MAX +#define MI_HAVE_BITSCAN +#if (INTPTR_MAX == LONG_MAX) +# define MI_L(x) x##l +#else +# define MI_L(x) x##ll +#endif +static inline size_t mi_bsf(uintptr_t x) { + return (x==0 ? 8*MI_INTPTR_SIZE : MI_L(__builtin_ctz)(x)); +} +static inline size_t mi_bsr(uintptr_t x) { + return (x==0 ? 8*MI_INTPTR_SIZE : (8*MI_INTPTR_SIZE - 1) - MI_L(__builtin_clz)(x)); +} +#endif + +/* ----------------------------------------------------------- + Claim a bit sequence atomically +----------------------------------------------------------- */ + +// Try to atomically claim a sequence of `count` bits at in `idx` +// in the bitmap field. Returns `true` on success. +static inline bool mi_bitmap_try_claim_field(mi_bitmap_t bitmap, size_t bitmap_fields, const size_t count, mi_bitmap_index_t bitmap_idx) { + const size_t idx = mi_bitmap_index_field(bitmap_idx); + const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); + const uintptr_t mask = mi_bitmap_mask_(count, bitidx); + mi_assert_internal(bitmap_fields > idx); UNUSED(bitmap_fields); + mi_assert_internal(bitidx + count <= MI_BITMAP_FIELD_BITS); + + uintptr_t field = mi_atomic_read_relaxed(&bitmap[idx]); + if ((field & mask) == 0) { // free? + if (mi_atomic_cas_strong(&bitmap[idx], (field|mask), field)) { + // claimed! + return true; + } + } + return false; +} + + +// Try to atomically claim a sequence of `count` bits in a single +// field at `idx` in `bitmap`. Returns `true` on success. +static inline bool mi_bitmap_try_find_claim_field(mi_bitmap_t bitmap, size_t idx, const size_t count, mi_bitmap_index_t* bitmap_idx) +{ + mi_assert_internal(bitmap_idx != NULL); + volatile _Atomic(uintptr_t)* field = &bitmap[idx]; + uintptr_t map = mi_atomic_read(field); + if (map==MI_BITMAP_FIELD_FULL) return false; // short cut + + // search for 0-bit sequence of length count + const uintptr_t mask = mi_bitmap_mask_(count, 0); + const size_t bitidx_max = MI_BITMAP_FIELD_BITS - count; + +#ifdef MI_HAVE_BITSCAN + size_t bitidx = mi_bsf(~map); // quickly find the first zero bit if possible +#else + size_t bitidx = 0; // otherwise start at 0 +#endif + uintptr_t m = (mask << bitidx); // invariant: m == mask shifted by bitidx + + // scan linearly for a free range of zero bits + while (bitidx <= bitidx_max) { + if ((map & m) == 0) { // are the mask bits free at bitidx? + mi_assert_internal((m >> bitidx) == mask); // no overflow? + const uintptr_t newmap = map | m; + mi_assert_internal((newmap^map) >> bitidx == mask); + if (!mi_atomic_cas_weak(field, newmap, map)) { // TODO: use strong cas here? + // no success, another thread claimed concurrently.. keep going + map = mi_atomic_read(field); + continue; + } + else { + // success, we claimed the bits! + *bitmap_idx = mi_bitmap_index_create(idx, bitidx); + return true; + } + } + else { + // on to the next bit range +#ifdef MI_HAVE_BITSCAN + const size_t shift = (count == 1 ? 1 : mi_bsr(map & m) - bitidx + 1); + mi_assert_internal(shift > 0 && shift <= count); +#else + const size_t shift = 1; +#endif + bitidx += shift; + m <<= shift; + } + } + // no bits found + return false; +} + + +// Find `count` bits of 0 and set them to 1 atomically; returns `true` on success. +// For now, `count` can be at most MI_BITMAP_FIELD_BITS and will never span fields. +static inline bool mi_bitmap_try_find_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t* bitmap_idx) { + for (size_t idx = 0; idx < bitmap_fields; idx++) { + if (mi_bitmap_try_find_claim_field(bitmap, idx, count, bitmap_idx)) { + return true; + } + } + return false; +} + +// Set `count` bits at `bitmap_idx` to 0 atomically +// Returns `true` if all `count` bits were 1 previously. +static inline bool mi_bitmap_unclaim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + const size_t idx = mi_bitmap_index_field(bitmap_idx); + const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); + const uintptr_t mask = mi_bitmap_mask_(count, bitidx); + mi_assert_internal(bitmap_fields > idx); UNUSED(bitmap_fields); + // mi_assert_internal((bitmap[idx] & mask) == mask); + uintptr_t prev = mi_atomic_and(&bitmap[idx], ~mask); + return ((prev & mask) == mask); +} + + +// Set `count` bits at `bitmap_idx` to 1 atomically +// Returns `true` if all `count` bits were 0 previously. `any_zero` is `true` if there was at least one zero bit. +static inline bool mi_bitmap_claim(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_zero) { + const size_t idx = mi_bitmap_index_field(bitmap_idx); + const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); + const uintptr_t mask = mi_bitmap_mask_(count, bitidx); + mi_assert_internal(bitmap_fields > idx); UNUSED(bitmap_fields); + //mi_assert_internal(any_zero != NULL || (bitmap[idx] & mask) == 0); + uintptr_t prev = mi_atomic_or(&bitmap[idx], mask); + if (any_zero != NULL) *any_zero = ((prev & mask) != mask); + return ((prev & mask) == 0); +} + +// Returns `true` if all `count` bits were 1. `any_ones` is `true` if there was at least one bit set to one. +static inline bool mi_bitmap_is_claimedx(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx, bool* any_ones) { + const size_t idx = mi_bitmap_index_field(bitmap_idx); + const size_t bitidx = mi_bitmap_index_bit_in_field(bitmap_idx); + const uintptr_t mask = mi_bitmap_mask_(count, bitidx); + mi_assert_internal(bitmap_fields > idx); UNUSED(bitmap_fields); + uintptr_t field = mi_atomic_read_relaxed(&bitmap[idx]); + if (any_ones != NULL) *any_ones = ((field & mask) != 0); + return ((field & mask) == mask); +} + +static inline bool mi_bitmap_is_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + return mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, NULL); +} + +static inline bool mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t count, mi_bitmap_index_t bitmap_idx) { + bool any_ones; + mi_bitmap_is_claimedx(bitmap, bitmap_fields, count, bitmap_idx, &any_ones); + return any_ones; +} + + +#endif diff --git a/extlib/mimalloc/src/heap.c b/extlib/mimalloc/src/heap.c new file mode 100644 index 0000000..aab7e12 --- /dev/null +++ b/extlib/mimalloc/src/heap.c @@ -0,0 +1,555 @@ +/*---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +#include "mimalloc.h" +#include "mimalloc-internal.h" +#include "mimalloc-atomic.h" + +#include // memset, memcpy + + +/* ----------------------------------------------------------- + Helpers +----------------------------------------------------------- */ + +// return `true` if ok, `false` to break +typedef bool (heap_page_visitor_fun)(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2); + +// Visit all pages in a heap; returns `false` if break was called. +static bool mi_heap_visit_pages(mi_heap_t* heap, heap_page_visitor_fun* fn, void* arg1, void* arg2) +{ + if (heap==NULL || heap->page_count==0) return 0; + + // visit all pages + #if MI_DEBUG>1 + size_t total = heap->page_count; + #endif + size_t count = 0; + for (size_t i = 0; i <= MI_BIN_FULL; i++) { + mi_page_queue_t* pq = &heap->pages[i]; + mi_page_t* page = pq->first; + while(page != NULL) { + mi_page_t* next = page->next; // save next in case the page gets removed from the queue + mi_assert_internal(mi_page_heap(page) == heap); + count++; + if (!fn(heap, pq, page, arg1, arg2)) return false; + page = next; // and continue + } + } + mi_assert_internal(count == total); + return true; +} + + +#if MI_DEBUG>=2 +static bool mi_heap_page_is_valid(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) { + UNUSED(arg1); + UNUSED(arg2); + UNUSED(pq); + mi_assert_internal(mi_page_heap(page) == heap); + mi_segment_t* segment = _mi_page_segment(page); + mi_assert_internal(segment->thread_id == heap->thread_id); + mi_assert_expensive(_mi_page_is_valid(page)); + return true; +} +#endif +#if MI_DEBUG>=3 +static bool mi_heap_is_valid(mi_heap_t* heap) { + mi_assert_internal(heap!=NULL); + mi_heap_visit_pages(heap, &mi_heap_page_is_valid, NULL, NULL); + return true; +} +#endif + + + + +/* ----------------------------------------------------------- + "Collect" pages by migrating `local_free` and `thread_free` + lists and freeing empty pages. This is done when a thread + stops (and in that case abandons pages if there are still + blocks alive) +----------------------------------------------------------- */ + +typedef enum mi_collect_e { + MI_NORMAL, + MI_FORCE, + MI_ABANDON +} mi_collect_t; + + +static bool mi_heap_page_collect(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg_collect, void* arg2 ) { + UNUSED(arg2); + UNUSED(heap); + mi_assert_internal(mi_heap_page_is_valid(heap, pq, page, NULL, NULL)); + mi_collect_t collect = *((mi_collect_t*)arg_collect); + _mi_page_free_collect(page, collect >= MI_FORCE); + if (mi_page_all_free(page)) { + // no more used blocks, free the page. + // note: this will free retired pages as well. + _mi_page_free(page, pq, collect >= MI_FORCE); + } + else if (collect == MI_ABANDON) { + // still used blocks but the thread is done; abandon the page + _mi_page_abandon(page, pq); + } + return true; // don't break +} + +static bool mi_heap_page_never_delayed_free(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) { + UNUSED(arg1); + UNUSED(arg2); + UNUSED(heap); + UNUSED(pq); + _mi_page_use_delayed_free(page, MI_NEVER_DELAYED_FREE, false); + return true; // don't break +} + +static void mi_heap_collect_ex(mi_heap_t* heap, mi_collect_t collect) +{ + if (!mi_heap_is_initialized(heap)) return; + _mi_deferred_free(heap, collect >= MI_FORCE); + + // note: never reclaim on collect but leave it to threads that need storage to reclaim + if ( + #ifdef NDEBUG + collect == MI_FORCE + #else + collect >= MI_FORCE + #endif + && _mi_is_main_thread() && mi_heap_is_backing(heap) && !heap->no_reclaim) + { + // the main thread is abandoned (end-of-program), try to reclaim all abandoned segments. + // if all memory is freed by now, all segments should be freed. + _mi_abandoned_reclaim_all(heap, &heap->tld->segments); + } + + // if abandoning, mark all pages to no longer add to delayed_free + if (collect == MI_ABANDON) { + mi_heap_visit_pages(heap, &mi_heap_page_never_delayed_free, NULL, NULL); + } + + // free thread delayed blocks. + // (if abandoning, after this there are no more thread-delayed references into the pages.) + _mi_heap_delayed_free(heap); + + // collect retired pages + _mi_heap_collect_retired(heap, collect >= MI_FORCE); + + // collect all pages owned by this thread + mi_heap_visit_pages(heap, &mi_heap_page_collect, &collect, NULL); + mi_assert_internal( collect != MI_ABANDON || mi_atomic_read_ptr(mi_block_t,&heap->thread_delayed_free) == NULL ); + + // collect segment caches + if (collect >= MI_FORCE) { + _mi_segment_thread_collect(&heap->tld->segments); + } + + // collect regions on program-exit (or shared library unload) + if (collect >= MI_FORCE && _mi_is_main_thread() && mi_heap_is_backing(heap)) { + _mi_mem_collect(&heap->tld->os); + } +} + +void _mi_heap_collect_abandon(mi_heap_t* heap) { + mi_heap_collect_ex(heap, MI_ABANDON); +} + +void mi_heap_collect(mi_heap_t* heap, bool force) mi_attr_noexcept { + mi_heap_collect_ex(heap, (force ? MI_FORCE : MI_NORMAL)); +} + +void mi_collect(bool force) mi_attr_noexcept { + mi_heap_collect(mi_get_default_heap(), force); +} + + +/* ----------------------------------------------------------- + Heap new +----------------------------------------------------------- */ + +mi_heap_t* mi_heap_get_default(void) { + mi_thread_init(); + return mi_get_default_heap(); +} + +mi_heap_t* mi_heap_get_backing(void) { + mi_heap_t* heap = mi_heap_get_default(); + mi_assert_internal(heap!=NULL); + mi_heap_t* bheap = heap->tld->heap_backing; + mi_assert_internal(bheap!=NULL); + mi_assert_internal(bheap->thread_id == _mi_thread_id()); + return bheap; +} + +mi_heap_t* mi_heap_new(void) { + mi_heap_t* bheap = mi_heap_get_backing(); + mi_heap_t* heap = mi_heap_malloc_tp(bheap, mi_heap_t); // todo: OS allocate in secure mode? + if (heap==NULL) return NULL; + memcpy(heap, &_mi_heap_empty, sizeof(mi_heap_t)); + heap->tld = bheap->tld; + heap->thread_id = _mi_thread_id(); + _mi_random_split(&bheap->random, &heap->random); + heap->cookie = _mi_heap_random_next(heap) | 1; + heap->keys[0] = _mi_heap_random_next(heap); + heap->keys[1] = _mi_heap_random_next(heap); + heap->no_reclaim = true; // don't reclaim abandoned pages or otherwise destroy is unsafe + // push on the thread local heaps list + heap->next = heap->tld->heaps; + heap->tld->heaps = heap; + return heap; +} + +uintptr_t _mi_heap_random_next(mi_heap_t* heap) { + return _mi_random_next(&heap->random); +} + +// zero out the page queues +static void mi_heap_reset_pages(mi_heap_t* heap) { + mi_assert_internal(mi_heap_is_initialized(heap)); + // TODO: copy full empty heap instead? + memset(&heap->pages_free_direct, 0, sizeof(heap->pages_free_direct)); +#ifdef MI_MEDIUM_DIRECT + memset(&heap->pages_free_medium, 0, sizeof(heap->pages_free_medium)); +#endif + memcpy(&heap->pages, &_mi_heap_empty.pages, sizeof(heap->pages)); + heap->thread_delayed_free = NULL; + heap->page_count = 0; +} + +// called from `mi_heap_destroy` and `mi_heap_delete` to free the internal heap resources. +static void mi_heap_free(mi_heap_t* heap) { + mi_assert(heap != NULL); + mi_assert_internal(mi_heap_is_initialized(heap)); + if (mi_heap_is_backing(heap)) return; // dont free the backing heap + + // reset default + if (mi_heap_is_default(heap)) { + _mi_heap_set_default_direct(heap->tld->heap_backing); + } + + // remove ourselves from the thread local heaps list + // linear search but we expect the number of heaps to be relatively small + mi_heap_t* prev = NULL; + mi_heap_t* curr = heap->tld->heaps; + while (curr != heap && curr != NULL) { + prev = curr; + curr = curr->next; + } + mi_assert_internal(curr == heap); + if (curr == heap) { + if (prev != NULL) { prev->next = heap->next; } + else { heap->tld->heaps = heap->next; } + } + mi_assert_internal(heap->tld->heaps != NULL); + + // and free the used memory + mi_free(heap); +} + + +/* ----------------------------------------------------------- + Heap destroy +----------------------------------------------------------- */ + +static bool _mi_heap_page_destroy(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* arg1, void* arg2) { + UNUSED(arg1); + UNUSED(arg2); + UNUSED(heap); + UNUSED(pq); + + // ensure no more thread_delayed_free will be added + _mi_page_use_delayed_free(page, MI_NEVER_DELAYED_FREE, false); + + // stats + const size_t bsize = mi_page_block_size(page); + if (bsize > MI_LARGE_OBJ_SIZE_MAX) { + if (bsize > MI_HUGE_OBJ_SIZE_MAX) { + _mi_stat_decrease(&heap->tld->stats.giant, bsize); + } + else { + _mi_stat_decrease(&heap->tld->stats.huge, bsize); + } + } +#if (MI_STAT>1) + _mi_page_free_collect(page, false); // update used count + const size_t inuse = page->used; + if (bsize <= MI_LARGE_OBJ_SIZE_MAX) { + mi_heap_stat_decrease(heap, normal[_mi_bin(bsize)], inuse); + } + mi_heap_stat_decrease(heap, malloc, bsize * inuse); // todo: off for aligned blocks... +#endif + + /// pretend it is all free now + mi_assert_internal(mi_page_thread_free(page) == NULL); + page->used = 0; + + // and free the page + // mi_page_free(page,false); + page->next = NULL; + page->prev = NULL; + _mi_segment_page_free(page,false /* no force? */, &heap->tld->segments); + + return true; // keep going +} + +void _mi_heap_destroy_pages(mi_heap_t* heap) { + mi_heap_visit_pages(heap, &_mi_heap_page_destroy, NULL, NULL); + mi_heap_reset_pages(heap); +} + +void mi_heap_destroy(mi_heap_t* heap) { + mi_assert(heap != NULL); + mi_assert(mi_heap_is_initialized(heap)); + mi_assert(heap->no_reclaim); + mi_assert_expensive(mi_heap_is_valid(heap)); + if (!mi_heap_is_initialized(heap)) return; + if (!heap->no_reclaim) { + // don't free in case it may contain reclaimed pages + mi_heap_delete(heap); + } + else { + // free all pages + _mi_heap_destroy_pages(heap); + mi_heap_free(heap); + } +} + + + +/* ----------------------------------------------------------- + Safe Heap delete +----------------------------------------------------------- */ + +// Tranfer the pages from one heap to the other +static void mi_heap_absorb(mi_heap_t* heap, mi_heap_t* from) { + mi_assert_internal(heap!=NULL); + if (from==NULL || from->page_count == 0) return; + + // reduce the size of the delayed frees + _mi_heap_delayed_free(from); + + // transfer all pages by appending the queues; this will set a new heap field + // so threads may do delayed frees in either heap for a while. + // note: appending waits for each page to not be in the `MI_DELAYED_FREEING` state + // so after this only the new heap will get delayed frees + for (size_t i = 0; i <= MI_BIN_FULL; i++) { + mi_page_queue_t* pq = &heap->pages[i]; + mi_page_queue_t* append = &from->pages[i]; + size_t pcount = _mi_page_queue_append(heap, pq, append); + heap->page_count += pcount; + from->page_count -= pcount; + } + mi_assert_internal(from->page_count == 0); + + // and do outstanding delayed frees in the `from` heap + // note: be careful here as the `heap` field in all those pages no longer point to `from`, + // turns out to be ok as `_mi_heap_delayed_free` only visits the list and calls a + // the regular `_mi_free_delayed_block` which is safe. + _mi_heap_delayed_free(from); + mi_assert_internal(from->thread_delayed_free == NULL); + + // and reset the `from` heap + mi_heap_reset_pages(from); +} + +// Safe delete a heap without freeing any still allocated blocks in that heap. +void mi_heap_delete(mi_heap_t* heap) +{ + mi_assert(heap != NULL); + mi_assert(mi_heap_is_initialized(heap)); + mi_assert_expensive(mi_heap_is_valid(heap)); + if (!mi_heap_is_initialized(heap)) return; + + if (!mi_heap_is_backing(heap)) { + // tranfer still used pages to the backing heap + mi_heap_absorb(heap->tld->heap_backing, heap); + } + else { + // the backing heap abandons its pages + _mi_heap_collect_abandon(heap); + } + mi_assert_internal(heap->page_count==0); + mi_heap_free(heap); +} + +mi_heap_t* mi_heap_set_default(mi_heap_t* heap) { + mi_assert(mi_heap_is_initialized(heap)); + if (!mi_heap_is_initialized(heap)) return NULL; + mi_assert_expensive(mi_heap_is_valid(heap)); + mi_heap_t* old = mi_get_default_heap(); + _mi_heap_set_default_direct(heap); + return old; +} + + + + +/* ----------------------------------------------------------- + Analysis +----------------------------------------------------------- */ + +// static since it is not thread safe to access heaps from other threads. +static mi_heap_t* mi_heap_of_block(const void* p) { + if (p == NULL) return NULL; + mi_segment_t* segment = _mi_ptr_segment(p); + bool valid = (_mi_ptr_cookie(segment) == segment->cookie); + mi_assert_internal(valid); + if (mi_unlikely(!valid)) return NULL; + return mi_page_heap(_mi_segment_page_of(segment,p)); +} + +bool mi_heap_contains_block(mi_heap_t* heap, const void* p) { + mi_assert(heap != NULL); + if (!mi_heap_is_initialized(heap)) return false; + return (heap == mi_heap_of_block(p)); +} + + +static bool mi_heap_page_check_owned(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* p, void* vfound) { + UNUSED(heap); + UNUSED(pq); + bool* found = (bool*)vfound; + mi_segment_t* segment = _mi_page_segment(page); + void* start = _mi_page_start(segment, page, NULL); + void* end = (uint8_t*)start + (page->capacity * mi_page_block_size(page)); + *found = (p >= start && p < end); + return (!*found); // continue if not found +} + +bool mi_heap_check_owned(mi_heap_t* heap, const void* p) { + mi_assert(heap != NULL); + if (!mi_heap_is_initialized(heap)) return false; + if (((uintptr_t)p & (MI_INTPTR_SIZE - 1)) != 0) return false; // only aligned pointers + bool found = false; + mi_heap_visit_pages(heap, &mi_heap_page_check_owned, (void*)p, &found); + return found; +} + +bool mi_check_owned(const void* p) { + return mi_heap_check_owned(mi_get_default_heap(), p); +} + +/* ----------------------------------------------------------- + Visit all heap blocks and areas + Todo: enable visiting abandoned pages, and + enable visiting all blocks of all heaps across threads +----------------------------------------------------------- */ + +// Separate struct to keep `mi_page_t` out of the public interface +typedef struct mi_heap_area_ex_s { + mi_heap_area_t area; + mi_page_t* page; +} mi_heap_area_ex_t; + +static bool mi_heap_area_visit_blocks(const mi_heap_area_ex_t* xarea, mi_block_visit_fun* visitor, void* arg) { + mi_assert(xarea != NULL); + if (xarea==NULL) return true; + const mi_heap_area_t* area = &xarea->area; + mi_page_t* page = xarea->page; + mi_assert(page != NULL); + if (page == NULL) return true; + + _mi_page_free_collect(page,true); + mi_assert_internal(page->local_free == NULL); + if (page->used == 0) return true; + + const size_t bsize = mi_page_block_size(page); + size_t psize; + uint8_t* pstart = _mi_page_start(_mi_page_segment(page), page, &psize); + + if (page->capacity == 1) { + // optimize page with one block + mi_assert_internal(page->used == 1 && page->free == NULL); + return visitor(mi_page_heap(page), area, pstart, bsize, arg); + } + + // create a bitmap of free blocks. + #define MI_MAX_BLOCKS (MI_SMALL_PAGE_SIZE / sizeof(void*)) + uintptr_t free_map[MI_MAX_BLOCKS / sizeof(uintptr_t)]; + memset(free_map, 0, sizeof(free_map)); + + size_t free_count = 0; + for (mi_block_t* block = page->free; block != NULL; block = mi_block_next(page,block)) { + free_count++; + mi_assert_internal((uint8_t*)block >= pstart && (uint8_t*)block < (pstart + psize)); + size_t offset = (uint8_t*)block - pstart; + mi_assert_internal(offset % bsize == 0); + size_t blockidx = offset / bsize; // Todo: avoid division? + mi_assert_internal( blockidx < MI_MAX_BLOCKS); + size_t bitidx = (blockidx / sizeof(uintptr_t)); + size_t bit = blockidx - (bitidx * sizeof(uintptr_t)); + free_map[bitidx] |= ((uintptr_t)1 << bit); + } + mi_assert_internal(page->capacity == (free_count + page->used)); + + // walk through all blocks skipping the free ones + size_t used_count = 0; + for (size_t i = 0; i < page->capacity; i++) { + size_t bitidx = (i / sizeof(uintptr_t)); + size_t bit = i - (bitidx * sizeof(uintptr_t)); + uintptr_t m = free_map[bitidx]; + if (bit == 0 && m == UINTPTR_MAX) { + i += (sizeof(uintptr_t) - 1); // skip a run of free blocks + } + else if ((m & ((uintptr_t)1 << bit)) == 0) { + used_count++; + uint8_t* block = pstart + (i * bsize); + if (!visitor(mi_page_heap(page), area, block, bsize, arg)) return false; + } + } + mi_assert_internal(page->used == used_count); + return true; +} + +typedef bool (mi_heap_area_visit_fun)(const mi_heap_t* heap, const mi_heap_area_ex_t* area, void* arg); + + +static bool mi_heap_visit_areas_page(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t* page, void* vfun, void* arg) { + UNUSED(heap); + UNUSED(pq); + mi_heap_area_visit_fun* fun = (mi_heap_area_visit_fun*)vfun; + mi_heap_area_ex_t xarea; + const size_t bsize = mi_page_block_size(page); + xarea.page = page; + xarea.area.reserved = page->reserved * bsize; + xarea.area.committed = page->capacity * bsize; + xarea.area.blocks = _mi_page_start(_mi_page_segment(page), page, NULL); + xarea.area.used = page->used; + xarea.area.block_size = bsize; + return fun(heap, &xarea, arg); +} + +// Visit all heap pages as areas +static bool mi_heap_visit_areas(const mi_heap_t* heap, mi_heap_area_visit_fun* visitor, void* arg) { + if (visitor == NULL) return false; + return mi_heap_visit_pages((mi_heap_t*)heap, &mi_heap_visit_areas_page, (void*)(visitor), arg); // note: function pointer to void* :-{ +} + +// Just to pass arguments +typedef struct mi_visit_blocks_args_s { + bool visit_blocks; + mi_block_visit_fun* visitor; + void* arg; +} mi_visit_blocks_args_t; + +static bool mi_heap_area_visitor(const mi_heap_t* heap, const mi_heap_area_ex_t* xarea, void* arg) { + mi_visit_blocks_args_t* args = (mi_visit_blocks_args_t*)arg; + if (!args->visitor(heap, &xarea->area, NULL, xarea->area.block_size, args->arg)) return false; + if (args->visit_blocks) { + return mi_heap_area_visit_blocks(xarea, args->visitor, args->arg); + } + else { + return true; + } +} + +// Visit all blocks in a heap +bool mi_heap_visit_blocks(const mi_heap_t* heap, bool visit_blocks, mi_block_visit_fun* visitor, void* arg) { + mi_visit_blocks_args_t args = { visit_blocks, visitor, arg }; + return mi_heap_visit_areas(heap, &mi_heap_area_visitor, &args); +} diff --git a/extlib/mimalloc/src/init.c b/extlib/mimalloc/src/init.c new file mode 100644 index 0000000..1724bd2 --- /dev/null +++ b/extlib/mimalloc/src/init.c @@ -0,0 +1,572 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc-internal.h" + +#include // memcpy, memset +#include // atexit + +// Empty page used to initialize the small free pages array +const mi_page_t _mi_page_empty = { + 0, false, false, false, false, + 0, // capacity + 0, // reserved capacity + { 0 }, // flags + false, // is_zero + 0, // retire_expire + NULL, // free + #if MI_ENCODE_FREELIST + { 0, 0 }, + #endif + 0, // used + 0, // xblock_size + NULL, // local_free + ATOMIC_VAR_INIT(0), // xthread_free + ATOMIC_VAR_INIT(0), // xheap + NULL, NULL +}; + +#define MI_PAGE_EMPTY() ((mi_page_t*)&_mi_page_empty) + +#if (MI_PADDING>0) && (MI_INTPTR_SIZE >= 8) +#define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY(), MI_PAGE_EMPTY() } +#elif (MI_PADDING>0) +#define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY(), MI_PAGE_EMPTY(), MI_PAGE_EMPTY() } +#else +#define MI_SMALL_PAGES_EMPTY { MI_INIT128(MI_PAGE_EMPTY), MI_PAGE_EMPTY() } +#endif + + +// Empty page queues for every bin +#define QNULL(sz) { NULL, NULL, (sz)*sizeof(uintptr_t) } +#define MI_PAGE_QUEUES_EMPTY \ + { QNULL(1), \ + QNULL( 1), QNULL( 2), QNULL( 3), QNULL( 4), QNULL( 5), QNULL( 6), QNULL( 7), QNULL( 8), /* 8 */ \ + QNULL( 10), QNULL( 12), QNULL( 14), QNULL( 16), QNULL( 20), QNULL( 24), QNULL( 28), QNULL( 32), /* 16 */ \ + QNULL( 40), QNULL( 48), QNULL( 56), QNULL( 64), QNULL( 80), QNULL( 96), QNULL( 112), QNULL( 128), /* 24 */ \ + QNULL( 160), QNULL( 192), QNULL( 224), QNULL( 256), QNULL( 320), QNULL( 384), QNULL( 448), QNULL( 512), /* 32 */ \ + QNULL( 640), QNULL( 768), QNULL( 896), QNULL( 1024), QNULL( 1280), QNULL( 1536), QNULL( 1792), QNULL( 2048), /* 40 */ \ + QNULL( 2560), QNULL( 3072), QNULL( 3584), QNULL( 4096), QNULL( 5120), QNULL( 6144), QNULL( 7168), QNULL( 8192), /* 48 */ \ + QNULL( 10240), QNULL( 12288), QNULL( 14336), QNULL( 16384), QNULL( 20480), QNULL( 24576), QNULL( 28672), QNULL( 32768), /* 56 */ \ + QNULL( 40960), QNULL( 49152), QNULL( 57344), QNULL( 65536), QNULL( 81920), QNULL( 98304), QNULL(114688), QNULL(131072), /* 64 */ \ + QNULL(163840), QNULL(196608), QNULL(229376), QNULL(262144), QNULL(327680), QNULL(393216), QNULL(458752), QNULL(524288), /* 72 */ \ + QNULL(MI_LARGE_OBJ_WSIZE_MAX + 1 /* 655360, Huge queue */), \ + QNULL(MI_LARGE_OBJ_WSIZE_MAX + 2) /* Full queue */ } + +#define MI_STAT_COUNT_NULL() {0,0,0,0} + +// Empty statistics +#if MI_STAT>1 +#define MI_STAT_COUNT_END_NULL() , { MI_STAT_COUNT_NULL(), MI_INIT32(MI_STAT_COUNT_NULL) } +#else +#define MI_STAT_COUNT_END_NULL() +#endif + +#define MI_STATS_NULL \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), MI_STAT_COUNT_NULL(), \ + MI_STAT_COUNT_NULL(), \ + { 0, 0 }, { 0, 0 }, { 0, 0 }, \ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } \ + MI_STAT_COUNT_END_NULL() + +// -------------------------------------------------------- +// Statically allocate an empty heap as the initial +// thread local value for the default heap, +// and statically allocate the backing heap for the main +// thread so it can function without doing any allocation +// itself (as accessing a thread local for the first time +// may lead to allocation itself on some platforms) +// -------------------------------------------------------- + +const mi_heap_t _mi_heap_empty = { + NULL, + MI_SMALL_PAGES_EMPTY, + MI_PAGE_QUEUES_EMPTY, + ATOMIC_VAR_INIT(NULL), + 0, // tid + 0, // cookie + { 0, 0 }, // keys + { {0}, {0}, 0 }, + 0, // page count + MI_BIN_FULL, 0, // page retired min/max + NULL, // next + false +}; + +// the thread-local default heap for allocation +mi_decl_thread mi_heap_t* _mi_heap_default = (mi_heap_t*)&_mi_heap_empty; + +extern mi_heap_t _mi_heap_main; + +static mi_tld_t tld_main = { + 0, false, + &_mi_heap_main, &_mi_heap_main, + { { NULL, NULL }, {NULL ,NULL}, {NULL ,NULL, 0}, + 0, 0, 0, 0, 0, 0, NULL, + &tld_main.stats, &tld_main.os + }, // segments + { 0, &tld_main.stats }, // os + { MI_STATS_NULL } // stats +}; + +mi_heap_t _mi_heap_main = { + &tld_main, + MI_SMALL_PAGES_EMPTY, + MI_PAGE_QUEUES_EMPTY, + ATOMIC_VAR_INIT(NULL), + 0, // thread id + 0, // initial cookie + { 0, 0 }, // the key of the main heap can be fixed (unlike page keys that need to be secure!) + { {0x846ca68b}, {0}, 0 }, // random + 0, // page count + MI_BIN_FULL, 0, // page retired min/max + NULL, // next heap + false // can reclaim +}; + +bool _mi_process_is_initialized = false; // set to `true` in `mi_process_init`. + +mi_stats_t _mi_stats_main = { MI_STATS_NULL }; + + +static void mi_heap_main_init(void) { + if (_mi_heap_main.cookie == 0) { + _mi_heap_main.thread_id = _mi_thread_id(); + _mi_heap_main.cookie = _os_random_weak((uintptr_t)&mi_heap_main_init); + _mi_random_init(&_mi_heap_main.random); + _mi_heap_main.keys[0] = _mi_heap_random_next(&_mi_heap_main); + _mi_heap_main.keys[1] = _mi_heap_random_next(&_mi_heap_main); + } +} + +mi_heap_t* _mi_heap_main_get(void) { + mi_heap_main_init(); + return &_mi_heap_main; +} + + +/* ----------------------------------------------------------- + Initialization and freeing of the thread local heaps +----------------------------------------------------------- */ + +// note: in x64 in release build `sizeof(mi_thread_data_t)` is under 4KiB (= OS page size). +typedef struct mi_thread_data_s { + mi_heap_t heap; // must come first due to cast in `_mi_heap_done` + mi_tld_t tld; +} mi_thread_data_t; + +// Initialize the thread local default heap, called from `mi_thread_init` +static bool _mi_heap_init(void) { + if (mi_heap_is_initialized(mi_get_default_heap())) return true; + if (_mi_is_main_thread()) { + // mi_assert_internal(_mi_heap_main.thread_id != 0); // can happen on freeBSD where alloc is called before any initialization + // the main heap is statically allocated + mi_heap_main_init(); + _mi_heap_set_default_direct(&_mi_heap_main); + //mi_assert_internal(_mi_heap_default->tld->heap_backing == mi_get_default_heap()); + } + else { + // use `_mi_os_alloc` to allocate directly from the OS + mi_thread_data_t* td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &_mi_stats_main); // Todo: more efficient allocation? + if (td == NULL) { + // if this fails, try once more. (issue #257) + td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &_mi_stats_main); + if (td == NULL) { + // really out of memory + _mi_error_message(ENOMEM, "unable to allocate thread local heap metadata (%zu bytes)\n", sizeof(mi_thread_data_t)); + return false; + } + } + // OS allocated so already zero initialized + mi_tld_t* tld = &td->tld; + mi_heap_t* heap = &td->heap; + memcpy(heap, &_mi_heap_empty, sizeof(*heap)); + heap->thread_id = _mi_thread_id(); + _mi_random_init(&heap->random); + heap->cookie = _mi_heap_random_next(heap) | 1; + heap->keys[0] = _mi_heap_random_next(heap); + heap->keys[1] = _mi_heap_random_next(heap); + heap->tld = tld; + tld->heap_backing = heap; + tld->heaps = heap; + tld->segments.stats = &tld->stats; + tld->segments.os = &tld->os; + tld->os.stats = &tld->stats; + _mi_heap_set_default_direct(heap); + } + return false; +} + +// Free the thread local default heap (called from `mi_thread_done`) +static bool _mi_heap_done(mi_heap_t* heap) { + if (!mi_heap_is_initialized(heap)) return true; + + // reset default heap + _mi_heap_set_default_direct(_mi_is_main_thread() ? &_mi_heap_main : (mi_heap_t*)&_mi_heap_empty); + + // switch to backing heap + heap = heap->tld->heap_backing; + if (!mi_heap_is_initialized(heap)) return false; + + // delete all non-backing heaps in this thread + mi_heap_t* curr = heap->tld->heaps; + while (curr != NULL) { + mi_heap_t* next = curr->next; // save `next` as `curr` will be freed + if (curr != heap) { + mi_assert_internal(!mi_heap_is_backing(curr)); + mi_heap_delete(curr); + } + curr = next; + } + mi_assert_internal(heap->tld->heaps == heap && heap->next == NULL); + mi_assert_internal(mi_heap_is_backing(heap)); + + // collect if not the main thread + if (heap != &_mi_heap_main) { + _mi_heap_collect_abandon(heap); + } + + + // merge stats + _mi_stats_done(&heap->tld->stats); + + // free if not the main thread + if (heap != &_mi_heap_main) { + mi_assert_internal(heap->tld->segments.count == 0 || heap->thread_id != _mi_thread_id()); + _mi_os_free(heap, sizeof(mi_thread_data_t), &_mi_stats_main); + } +#if 0 + // never free the main thread even in debug mode; if a dll is linked statically with mimalloc, + // there may still be delete/free calls after the mi_fls_done is called. Issue #207 + else { + _mi_heap_destroy_pages(heap); + mi_assert_internal(heap->tld->heap_backing == &_mi_heap_main); + } +#endif + return false; +} + + + +// -------------------------------------------------------- +// Try to run `mi_thread_done()` automatically so any memory +// owned by the thread but not yet released can be abandoned +// and re-owned by another thread. +// +// 1. windows dynamic library: +// call from DllMain on DLL_THREAD_DETACH +// 2. windows static library: +// use `FlsAlloc` to call a destructor when the thread is done +// 3. unix, pthreads: +// use a pthread key to call a destructor when a pthread is done +// +// In the last two cases we also need to call `mi_process_init` +// to set up the thread local keys. +// -------------------------------------------------------- + +static void _mi_thread_done(mi_heap_t* default_heap); + +#ifdef __wasi__ +// no pthreads in the WebAssembly Standard Interface +#elif !defined(_WIN32) +#define MI_USE_PTHREADS +#endif + +#if defined(_WIN32) && defined(MI_SHARED_LIB) + // nothing to do as it is done in DllMain +#elif defined(_WIN32) && !defined(MI_SHARED_LIB) + // use thread local storage keys to detect thread ending + #include + #include + #if (_WIN32_WINNT < 0x600) // before Windows Vista + WINBASEAPI DWORD WINAPI FlsAlloc( _In_opt_ PFLS_CALLBACK_FUNCTION lpCallback ); + WINBASEAPI PVOID WINAPI FlsGetValue( _In_ DWORD dwFlsIndex ); + WINBASEAPI BOOL WINAPI FlsSetValue( _In_ DWORD dwFlsIndex, _In_opt_ PVOID lpFlsData ); + WINBASEAPI BOOL WINAPI FlsFree(_In_ DWORD dwFlsIndex); + #endif + static DWORD mi_fls_key = (DWORD)(-1); + static void NTAPI mi_fls_done(PVOID value) { + if (value!=NULL) _mi_thread_done((mi_heap_t*)value); + } +#elif defined(MI_USE_PTHREADS) + // use pthread local storage keys to detect thread ending + // (and used with MI_TLS_PTHREADS for the default heap) + #include + pthread_key_t _mi_heap_default_key = (pthread_key_t)(-1); + static void mi_pthread_done(void* value) { + if (value!=NULL) _mi_thread_done((mi_heap_t*)value); + } +#elif defined(__wasi__) +// no pthreads in the WebAssembly Standard Interface +#else + #pragma message("define a way to call mi_thread_done when a thread is done") +#endif + +// Set up handlers so `mi_thread_done` is called automatically +static void mi_process_setup_auto_thread_done(void) { + static bool tls_initialized = false; // fine if it races + if (tls_initialized) return; + tls_initialized = true; + #if defined(_WIN32) && defined(MI_SHARED_LIB) + // nothing to do as it is done in DllMain + #elif defined(_WIN32) && !defined(MI_SHARED_LIB) + mi_fls_key = FlsAlloc(&mi_fls_done); + #elif defined(MI_USE_PTHREADS) + mi_assert_internal(_mi_heap_default_key == (pthread_key_t)(-1)); + pthread_key_create(&_mi_heap_default_key, &mi_pthread_done); + #endif + _mi_heap_set_default_direct(&_mi_heap_main); +} + + +bool _mi_is_main_thread(void) { + return (_mi_heap_main.thread_id==0 || _mi_heap_main.thread_id == _mi_thread_id()); +} + +// This is called from the `mi_malloc_generic` +void mi_thread_init(void) mi_attr_noexcept +{ + // ensure our process has started already + mi_process_init(); + + // initialize the thread local default heap + // (this will call `_mi_heap_set_default_direct` and thus set the + // fiber/pthread key to a non-zero value, ensuring `_mi_thread_done` is called) + if (_mi_heap_init()) return; // returns true if already initialized + + // don't further initialize for the main thread + if (_mi_is_main_thread()) return; + + mi_heap_t* const heap = mi_get_default_heap(); + if (mi_heap_is_initialized(heap)) { _mi_stat_increase(&heap->tld->stats.threads, 1); } + + //_mi_verbose_message("thread init: 0x%zx\n", _mi_thread_id()); +} + +void mi_thread_done(void) mi_attr_noexcept { + _mi_thread_done(mi_get_default_heap()); +} + +static void _mi_thread_done(mi_heap_t* heap) { + // check thread-id as on Windows shutdown with FLS the main (exit) thread may call this on thread-local heaps... + if (heap->thread_id != _mi_thread_id()) return; + + // stats + if (!_mi_is_main_thread() && mi_heap_is_initialized(heap)) { + _mi_stat_decrease(&heap->tld->stats.threads, 1); + } + + // abandon the thread local heap + if (_mi_heap_done(heap)) return; // returns true if already ran +} + +void _mi_heap_set_default_direct(mi_heap_t* heap) { + mi_assert_internal(heap != NULL); + #if defined(MI_TLS_SLOT) + mi_tls_slot_set(MI_TLS_SLOT,heap); + #elif defined(MI_TLS_PTHREAD_SLOT_OFS) + *mi_tls_pthread_heap_slot() = heap; + #elif defined(MI_TLS_PTHREAD) + // we use _mi_heap_default_key + #else + _mi_heap_default = heap; + #endif + + // ensure the default heap is passed to `_mi_thread_done` + // setting to a non-NULL value also ensures `mi_thread_done` is called. + #if defined(_WIN32) && defined(MI_SHARED_LIB) + // nothing to do as it is done in DllMain + #elif defined(_WIN32) && !defined(MI_SHARED_LIB) + mi_assert_internal(mi_fls_key != 0); + FlsSetValue(mi_fls_key, heap); + #elif defined(MI_USE_PTHREADS) + if (_mi_heap_default_key != (pthread_key_t)(-1)) { // can happen during recursive invocation on freeBSD + pthread_setspecific(_mi_heap_default_key, heap); + } + #endif +} + + +// -------------------------------------------------------- +// Run functions on process init/done, and thread init/done +// -------------------------------------------------------- +static void mi_process_done(void); + +static bool os_preloading = true; // true until this module is initialized +static bool mi_redirected = false; // true if malloc redirects to mi_malloc + +// Returns true if this module has not been initialized; Don't use C runtime routines until it returns false. +bool _mi_preloading() { + return os_preloading; +} + +bool mi_is_redirected() mi_attr_noexcept { + return mi_redirected; +} + +// Communicate with the redirection module on Windows +#if defined(_WIN32) && defined(MI_SHARED_LIB) +#ifdef __cplusplus +extern "C" { +#endif +mi_decl_export void _mi_redirect_entry(DWORD reason) { + // called on redirection; careful as this may be called before DllMain + if (reason == DLL_PROCESS_ATTACH) { + mi_redirected = true; + } + else if (reason == DLL_PROCESS_DETACH) { + mi_redirected = false; + } + else if (reason == DLL_THREAD_DETACH) { + mi_thread_done(); + } +} +__declspec(dllimport) bool mi_allocator_init(const char** message); +__declspec(dllimport) void mi_allocator_done(); +#ifdef __cplusplus +} +#endif +#else +static bool mi_allocator_init(const char** message) { + if (message != NULL) *message = NULL; + return true; +} +static void mi_allocator_done() { + // nothing to do +} +#endif + +// Called once by the process loader +static void mi_process_load(void) { + mi_heap_main_init(); + #if defined(MI_TLS_RECURSE_GUARD) + volatile mi_heap_t* dummy = _mi_heap_default; // access TLS to allocate it before setting tls_initialized to true; + UNUSED(dummy); + #endif + os_preloading = false; + atexit(&mi_process_done); + _mi_options_init(); + mi_process_init(); + //mi_stats_reset();- + if (mi_redirected) _mi_verbose_message("malloc is redirected.\n"); + + // show message from the redirector (if present) + const char* msg = NULL; + mi_allocator_init(&msg); + if (msg != NULL && (mi_option_is_enabled(mi_option_verbose) || mi_option_is_enabled(mi_option_show_errors))) { + _mi_fputs(NULL,NULL,NULL,msg); + } +} + +// Initialize the process; called by thread_init or the process loader +void mi_process_init(void) mi_attr_noexcept { + // ensure we are called once + if (_mi_process_is_initialized) return; + _mi_process_is_initialized = true; + mi_process_setup_auto_thread_done(); + + _mi_verbose_message("process init: 0x%zx\n", _mi_thread_id()); + _mi_os_init(); + mi_heap_main_init(); + #if (MI_DEBUG) + _mi_verbose_message("debug level : %d\n", MI_DEBUG); + #endif + _mi_verbose_message("secure level: %d\n", MI_SECURE); + mi_thread_init(); + mi_stats_reset(); // only call stat reset *after* thread init (or the heap tld == NULL) + + if (mi_option_is_enabled(mi_option_reserve_huge_os_pages)) { + size_t pages = mi_option_get(mi_option_reserve_huge_os_pages); + mi_reserve_huge_os_pages_interleave(pages, 0, pages*500); + } +} + +// Called when the process is done (through `at_exit`) +static void mi_process_done(void) { + // only shutdown if we were initialized + if (!_mi_process_is_initialized) return; + // ensure we are called once + static bool process_done = false; + if (process_done) return; + process_done = true; + + #if defined(_WIN32) && !defined(MI_SHARED_LIB) + FlsSetValue(mi_fls_key, NULL); // don't call main-thread callback + FlsFree(mi_fls_key); // call thread-done on all threads to prevent dangling callback pointer if statically linked with a DLL; Issue #208 + #endif + + #if (MI_DEBUG != 0) || !defined(MI_SHARED_LIB) + // free all memory if possible on process exit. This is not needed for a stand-alone process + // but should be done if mimalloc is statically linked into another shared library which + // is repeatedly loaded/unloaded, see issue #281. + mi_collect(true /* force */ ); + #endif + + if (mi_option_is_enabled(mi_option_show_stats) || mi_option_is_enabled(mi_option_verbose)) { + mi_stats_print(NULL); + } + mi_allocator_done(); + _mi_verbose_message("process done: 0x%zx\n", _mi_heap_main.thread_id); + os_preloading = true; // don't call the C runtime anymore +} + + + +#if defined(_WIN32) && defined(MI_SHARED_LIB) + // Windows DLL: easy to hook into process_init and thread_done + __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved) { + UNUSED(reserved); + UNUSED(inst); + if (reason==DLL_PROCESS_ATTACH) { + mi_process_load(); + } + else if (reason==DLL_THREAD_DETACH) { + if (!mi_is_redirected()) mi_thread_done(); + } + return TRUE; + } + +#elif defined(__cplusplus) + // C++: use static initialization to detect process start + static bool _mi_process_init(void) { + mi_process_load(); + return (_mi_heap_main.thread_id != 0); + } + static bool mi_initialized = _mi_process_init(); + +#elif defined(__GNUC__) || defined(__clang__) + // GCC,Clang: use the constructor attribute + static void __attribute__((constructor)) _mi_process_init(void) { + mi_process_load(); + } + +#elif defined(_MSC_VER) + // MSVC: use data section magic for static libraries + // See + static int _mi_process_init(void) { + mi_process_load(); + return 0; + } + typedef int(*_crt_cb)(void); + #ifdef _M_X64 + __pragma(comment(linker, "/include:" "_mi_msvc_initu")) + #pragma section(".CRT$XIU", long, read) + #else + __pragma(comment(linker, "/include:" "__mi_msvc_initu")) + #endif + #pragma data_seg(".CRT$XIU") + _crt_cb _mi_msvc_initu[] = { &_mi_process_init }; + #pragma data_seg() + +#else +#pragma message("define a way to call mi_process_load on your platform") +#endif diff --git a/extlib/mimalloc/src/options.c b/extlib/mimalloc/src/options.c new file mode 100644 index 0000000..f29b387 --- /dev/null +++ b/extlib/mimalloc/src/options.c @@ -0,0 +1,518 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc-internal.h" +#include "mimalloc-atomic.h" + +#include +#include // strtol +#include // strncpy, strncat, strlen, strstr +#include // toupper +#include + +static uintptr_t mi_max_error_count = 16; // stop outputting errors after this + +static void mi_add_stderr_output(); + +int mi_version(void) mi_attr_noexcept { + return MI_MALLOC_VERSION; +} + +#ifdef _WIN32 +#include +#endif + +// -------------------------------------------------------- +// Options +// These can be accessed by multiple threads and may be +// concurrently initialized, but an initializing data race +// is ok since they resolve to the same value. +// -------------------------------------------------------- +typedef enum mi_init_e { + UNINIT, // not yet initialized + DEFAULTED, // not found in the environment, use default value + INITIALIZED // found in environment or set explicitly +} mi_init_t; + +typedef struct mi_option_desc_s { + long value; // the value + mi_init_t init; // is it initialized yet? (from the environment) + mi_option_t option; // for debugging: the option index should match the option + const char* name; // option name without `mimalloc_` prefix +} mi_option_desc_t; + +#define MI_OPTION(opt) mi_option_##opt, #opt +#define MI_OPTION_DESC(opt) {0, UNINIT, MI_OPTION(opt) } + +static mi_option_desc_t options[_mi_option_last] = +{ + // stable options +#if MI_DEBUG || defined(MI_SHOW_ERRORS) + { 1, UNINIT, MI_OPTION(show_errors) }, +#else + { 0, UNINIT, MI_OPTION(show_errors) }, +#endif + { 0, UNINIT, MI_OPTION(show_stats) }, + { 0, UNINIT, MI_OPTION(verbose) }, + + // the following options are experimental and not all combinations make sense. + { 1, UNINIT, MI_OPTION(eager_commit) }, // commit on demand + #if defined(_WIN32) || (MI_INTPTR_SIZE <= 4) // and other OS's without overcommit? + { 0, UNINIT, MI_OPTION(eager_region_commit) }, + { 1, UNINIT, MI_OPTION(reset_decommits) }, // reset decommits memory + #else + { 1, UNINIT, MI_OPTION(eager_region_commit) }, + { 0, UNINIT, MI_OPTION(reset_decommits) }, // reset uses MADV_FREE/MADV_DONTNEED + #endif + { 0, UNINIT, MI_OPTION(large_os_pages) }, // use large OS pages, use only with eager commit to prevent fragmentation of VMA's + { 0, UNINIT, MI_OPTION(reserve_huge_os_pages) }, + { 0, UNINIT, MI_OPTION(segment_cache) }, // cache N segments per thread + { 1, UNINIT, MI_OPTION(page_reset) }, // reset page memory on free + { 0, UNINIT, MI_OPTION(abandoned_page_reset) },// reset free page memory when a thread terminates + { 0, UNINIT, MI_OPTION(segment_reset) }, // reset segment memory on free (needs eager commit) +#if defined(__NetBSD__) + { 0, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed +#else + { 1, UNINIT, MI_OPTION(eager_commit_delay) }, // the first N segments per thread are not eagerly committed +#endif + { 100, UNINIT, MI_OPTION(reset_delay) }, // reset delay in milli-seconds + { 0, UNINIT, MI_OPTION(use_numa_nodes) }, // 0 = use available numa nodes, otherwise use at most N nodes. + { 100, UNINIT, MI_OPTION(os_tag) }, // only apple specific for now but might serve more or less related purpose + { 16, UNINIT, MI_OPTION(max_errors) } // maximum errors that are output +}; + +static void mi_option_init(mi_option_desc_t* desc); + +void _mi_options_init(void) { + // called on process load; should not be called before the CRT is initialized! + // (e.g. do not call this from process_init as that may run before CRT initialization) + mi_add_stderr_output(); // now it safe to use stderr for output + for(int i = 0; i < _mi_option_last; i++ ) { + mi_option_t option = (mi_option_t)i; + long l = mi_option_get(option); UNUSED(l); // initialize + if (option != mi_option_verbose) { + mi_option_desc_t* desc = &options[option]; + _mi_verbose_message("option '%s': %ld\n", desc->name, desc->value); + } + } + mi_max_error_count = mi_option_get(mi_option_max_errors); +} + +long mi_option_get(mi_option_t option) { + mi_assert(option >= 0 && option < _mi_option_last); + mi_option_desc_t* desc = &options[option]; + mi_assert(desc->option == option); // index should match the option + if (mi_unlikely(desc->init == UNINIT)) { + mi_option_init(desc); + } + return desc->value; +} + +void mi_option_set(mi_option_t option, long value) { + mi_assert(option >= 0 && option < _mi_option_last); + mi_option_desc_t* desc = &options[option]; + mi_assert(desc->option == option); // index should match the option + desc->value = value; + desc->init = INITIALIZED; +} + +void mi_option_set_default(mi_option_t option, long value) { + mi_assert(option >= 0 && option < _mi_option_last); + mi_option_desc_t* desc = &options[option]; + if (desc->init != INITIALIZED) { + desc->value = value; + } +} + +bool mi_option_is_enabled(mi_option_t option) { + return (mi_option_get(option) != 0); +} + +void mi_option_set_enabled(mi_option_t option, bool enable) { + mi_option_set(option, (enable ? 1 : 0)); +} + +void mi_option_set_enabled_default(mi_option_t option, bool enable) { + mi_option_set_default(option, (enable ? 1 : 0)); +} + +void mi_option_enable(mi_option_t option) { + mi_option_set_enabled(option,true); +} + +void mi_option_disable(mi_option_t option) { + mi_option_set_enabled(option,false); +} + + +static void mi_out_stderr(const char* msg, void* arg) { + UNUSED(arg); + #ifdef _WIN32 + // on windows with redirection, the C runtime cannot handle locale dependent output + // after the main thread closes so we use direct console output. + if (!_mi_preloading()) { _cputs(msg); } + #else + fputs(msg, stderr); + #endif +} + +// Since an output function can be registered earliest in the `main` +// function we also buffer output that happens earlier. When +// an output function is registered it is called immediately with +// the output up to that point. +#ifndef MI_MAX_DELAY_OUTPUT +#define MI_MAX_DELAY_OUTPUT (32*1024) +#endif +static char out_buf[MI_MAX_DELAY_OUTPUT+1]; +static _Atomic(uintptr_t) out_len; + +static void mi_out_buf(const char* msg, void* arg) { + UNUSED(arg); + if (msg==NULL) return; + if (mi_atomic_read_relaxed(&out_len)>=MI_MAX_DELAY_OUTPUT) return; + size_t n = strlen(msg); + if (n==0) return; + // claim space + uintptr_t start = mi_atomic_add(&out_len, n); + if (start >= MI_MAX_DELAY_OUTPUT) return; + // check bound + if (start+n >= MI_MAX_DELAY_OUTPUT) { + n = MI_MAX_DELAY_OUTPUT-start-1; + } + memcpy(&out_buf[start], msg, n); +} + +static void mi_out_buf_flush(mi_output_fun* out, bool no_more_buf, void* arg) { + if (out==NULL) return; + // claim (if `no_more_buf == true`, no more output will be added after this point) + size_t count = mi_atomic_add(&out_len, (no_more_buf ? MI_MAX_DELAY_OUTPUT : 1)); + // and output the current contents + if (count>MI_MAX_DELAY_OUTPUT) count = MI_MAX_DELAY_OUTPUT; + out_buf[count] = 0; + out(out_buf,arg); + if (!no_more_buf) { + out_buf[count] = '\n'; // if continue with the buffer, insert a newline + } +} + + +// Once this module is loaded, switch to this routine +// which outputs to stderr and the delayed output buffer. +static void mi_out_buf_stderr(const char* msg, void* arg) { + mi_out_stderr(msg,arg); + mi_out_buf(msg,arg); +} + + + +// -------------------------------------------------------- +// Default output handler +// -------------------------------------------------------- + +// Should be atomic but gives errors on many platforms as generally we cannot cast a function pointer to a uintptr_t. +// For now, don't register output from multiple threads. +#pragma warning(suppress:4180) +static mi_output_fun* volatile mi_out_default; // = NULL +static volatile _Atomic(void*) mi_out_arg; // = NULL + +static mi_output_fun* mi_out_get_default(void** parg) { + if (parg != NULL) { *parg = mi_atomic_read_ptr(void,&mi_out_arg); } + mi_output_fun* out = mi_out_default; + return (out == NULL ? &mi_out_buf : out); +} + +void mi_register_output(mi_output_fun* out, void* arg) mi_attr_noexcept { + mi_out_default = (out == NULL ? &mi_out_stderr : out); // stop using the delayed output buffer + mi_atomic_write_ptr(void,&mi_out_arg, arg); + if (out!=NULL) mi_out_buf_flush(out,true,arg); // output all the delayed output now +} + +// add stderr to the delayed output after the module is loaded +static void mi_add_stderr_output() { + mi_assert_internal(mi_out_default == NULL); + mi_out_buf_flush(&mi_out_stderr, false, NULL); // flush current contents to stderr + mi_out_default = &mi_out_buf_stderr; // and add stderr to the delayed output +} + +// -------------------------------------------------------- +// Messages, all end up calling `_mi_fputs`. +// -------------------------------------------------------- +static volatile _Atomic(uintptr_t) error_count; // = 0; // when MAX_ERROR_COUNT stop emitting errors and warnings + +// When overriding malloc, we may recurse into mi_vfprintf if an allocation +// inside the C runtime causes another message. +static mi_decl_thread bool recurse = false; + +static bool mi_recurse_enter(void) { + #ifdef MI_TLS_RECURSE_GUARD + if (_mi_preloading()) return true; + #endif + if (recurse) return false; + recurse = true; + return true; +} + +static void mi_recurse_exit(void) { + #ifdef MI_TLS_RECURSE_GUARD + if (_mi_preloading()) return; + #endif + recurse = false; +} + +void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message) { + if (out==NULL || (FILE*)out==stdout || (FILE*)out==stderr) { // TODO: use mi_out_stderr for stderr? + if (!mi_recurse_enter()) return; + out = mi_out_get_default(&arg); + if (prefix != NULL) out(prefix, arg); + out(message, arg); + mi_recurse_exit(); + } + else { + if (prefix != NULL) out(prefix, arg); + out(message, arg); + } +} + +// Define our own limited `fprintf` that avoids memory allocation. +// We do this using `snprintf` with a limited buffer. +static void mi_vfprintf( mi_output_fun* out, void* arg, const char* prefix, const char* fmt, va_list args ) { + char buf[512]; + if (fmt==NULL) return; + if (!mi_recurse_enter()) return; + vsnprintf(buf,sizeof(buf)-1,fmt,args); + mi_recurse_exit(); + _mi_fputs(out,arg,prefix,buf); +} + +void _mi_fprintf( mi_output_fun* out, void* arg, const char* fmt, ... ) { + va_list args; + va_start(args,fmt); + mi_vfprintf(out,arg,NULL,fmt,args); + va_end(args); +} + +void _mi_trace_message(const char* fmt, ...) { + if (mi_option_get(mi_option_verbose) <= 1) return; // only with verbose level 2 or higher + va_list args; + va_start(args, fmt); + mi_vfprintf(NULL, NULL, "mimalloc: ", fmt, args); + va_end(args); +} + +void _mi_verbose_message(const char* fmt, ...) { + if (!mi_option_is_enabled(mi_option_verbose)) return; + va_list args; + va_start(args,fmt); + mi_vfprintf(NULL, NULL, "mimalloc: ", fmt, args); + va_end(args); +} + +static void mi_show_error_message(const char* fmt, va_list args) { + if (!mi_option_is_enabled(mi_option_show_errors) && !mi_option_is_enabled(mi_option_verbose)) return; + if (mi_atomic_increment(&error_count) > mi_max_error_count) return; + mi_vfprintf(NULL, NULL, "mimalloc: error: ", fmt, args); +} + +void _mi_warning_message(const char* fmt, ...) { + if (!mi_option_is_enabled(mi_option_show_errors) && !mi_option_is_enabled(mi_option_verbose)) return; + if (mi_atomic_increment(&error_count) > mi_max_error_count) return; + va_list args; + va_start(args,fmt); + mi_vfprintf(NULL, NULL, "mimalloc: warning: ", fmt, args); + va_end(args); +} + + +#if MI_DEBUG +void _mi_assert_fail(const char* assertion, const char* fname, unsigned line, const char* func ) { + _mi_fprintf(NULL, NULL, "mimalloc: assertion failed: at \"%s\":%u, %s\n assertion: \"%s\"\n", fname, line, (func==NULL?"":func), assertion); + abort(); +} +#endif + +// -------------------------------------------------------- +// Errors +// -------------------------------------------------------- + +static mi_error_fun* volatile mi_error_handler; // = NULL +static volatile _Atomic(void*) mi_error_arg; // = NULL + +static void mi_error_default(int err) { + UNUSED(err); +#if (MI_DEBUG>0) + if (err==EFAULT) { + #ifdef _MSC_VER + __debugbreak(); + #endif + abort(); + } +#endif +#if (MI_SECURE>0) + if (err==EFAULT) { // abort on serious errors in secure mode (corrupted meta-data) + abort(); + } +#endif +#if defined(MI_XMALLOC) + if (err==ENOMEM || err==EOVERFLOW) { // abort on memory allocation fails in xmalloc mode + abort(); + } +#endif +} + +void mi_register_error(mi_error_fun* fun, void* arg) { + mi_error_handler = fun; // can be NULL + mi_atomic_write_ptr(void,&mi_error_arg, arg); +} + +void _mi_error_message(int err, const char* fmt, ...) { + // show detailed error message + va_list args; + va_start(args, fmt); + mi_show_error_message(fmt, args); + va_end(args); + // and call the error handler which may abort (or return normally) + if (mi_error_handler != NULL) { + mi_error_handler(err, mi_atomic_read_ptr(void,&mi_error_arg)); + } + else { + mi_error_default(err); + } +} + +// -------------------------------------------------------- +// Initialize options by checking the environment +// -------------------------------------------------------- + +static void mi_strlcpy(char* dest, const char* src, size_t dest_size) { + dest[0] = 0; + #pragma warning(suppress:4996) + strncpy(dest, src, dest_size - 1); + dest[dest_size - 1] = 0; +} + +static void mi_strlcat(char* dest, const char* src, size_t dest_size) { + #pragma warning(suppress:4996) + strncat(dest, src, dest_size - 1); + dest[dest_size - 1] = 0; +} + +static inline int mi_strnicmp(const char* s, const char* t, size_t n) { + if (n==0) return 0; + for (; *s != 0 && *t != 0 && n > 0; s++, t++, n--) { + if (toupper(*s) != toupper(*t)) break; + } + return (n==0 ? 0 : *s - *t); +} + +#if defined _WIN32 +// On Windows use GetEnvironmentVariable instead of getenv to work +// reliably even when this is invoked before the C runtime is initialized. +// i.e. when `_mi_preloading() == true`. +// Note: on windows, environment names are not case sensitive. +#include +static bool mi_getenv(const char* name, char* result, size_t result_size) { + result[0] = 0; + size_t len = GetEnvironmentVariableA(name, result, (DWORD)result_size); + return (len > 0 && len < result_size); +} +#elif !defined(MI_USE_ENVIRON) || (MI_USE_ENVIRON!=0) +// On Posix systemsr use `environ` to acces environment variables +// even before the C runtime is initialized. +#if defined(__APPLE__) +#include +static char** mi_get_environ(void) { + return (*_NSGetEnviron()); +} +#else +extern char** environ; +static char** mi_get_environ(void) { + return environ; +} +#endif +static bool mi_getenv(const char* name, char* result, size_t result_size) { + if (name==NULL) return false; + const size_t len = strlen(name); + if (len == 0) return false; + char** env = mi_get_environ(); + if (env == NULL) return false; + // compare up to 256 entries + for (int i = 0; i < 256 && env[i] != NULL; i++) { + const char* s = env[i]; + if (mi_strnicmp(name, s, len) == 0 && s[len] == '=') { // case insensitive + // found it + mi_strlcpy(result, s + len + 1, result_size); + return true; + } + } + return false; +} +#else +// fallback: use standard C `getenv` but this cannot be used while initializing the C runtime +static bool mi_getenv(const char* name, char* result, size_t result_size) { + // cannot call getenv() when still initializing the C runtime. + if (_mi_preloading()) return false; + const char* s = getenv(name); + if (s == NULL) { + // we check the upper case name too. + char buf[64+1]; + size_t len = strlen(name); + if (len >= sizeof(buf)) len = sizeof(buf) - 1; + for (size_t i = 0; i < len; i++) { + buf[i] = toupper(name[i]); + } + buf[len] = 0; + s = getenv(buf); + } + if (s != NULL && strlen(s) < result_size) { + mi_strlcpy(result, s, result_size); + return true; + } + else { + return false; + } +} +#endif + +static void mi_option_init(mi_option_desc_t* desc) { + // Read option value from the environment + char buf[64+1]; + mi_strlcpy(buf, "mimalloc_", sizeof(buf)); + mi_strlcat(buf, desc->name, sizeof(buf)); + char s[64+1]; + if (mi_getenv(buf, s, sizeof(s))) { + size_t len = strlen(s); + if (len >= sizeof(buf)) len = sizeof(buf) - 1; + for (size_t i = 0; i < len; i++) { + buf[i] = (char)toupper(s[i]); + } + buf[len] = 0; + if (buf[0]==0 || strstr("1;TRUE;YES;ON", buf) != NULL) { + desc->value = 1; + desc->init = INITIALIZED; + } + else if (strstr("0;FALSE;NO;OFF", buf) != NULL) { + desc->value = 0; + desc->init = INITIALIZED; + } + else { + char* end = buf; + long value = strtol(buf, &end, 10); + if (*end == 0) { + desc->value = value; + desc->init = INITIALIZED; + } + else { + _mi_warning_message("environment option mimalloc_%s has an invalid value: %s\n", desc->name, buf); + desc->init = DEFAULTED; + } + } + mi_assert_internal(desc->init != UNINIT); + } + else if (!_mi_preloading()) { + desc->init = DEFAULTED; + } +} diff --git a/extlib/mimalloc/src/os.c b/extlib/mimalloc/src/os.c new file mode 100644 index 0000000..fe30cf4 --- /dev/null +++ b/extlib/mimalloc/src/os.c @@ -0,0 +1,1176 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE // ensure mmap flags are defined +#endif + +#if defined(__sun) +// illumos provides new mman.h api when any of these are defined +// otherwise the old api based on caddr_t which predates the void pointers one. +// stock solaris provides only the former, chose to atomically to discard those +// flags only here rather than project wide tough. +#undef _XOPEN_SOURCE +#undef _POSIX_C_SOURCE +#endif +#include "mimalloc.h" +#include "mimalloc-internal.h" +#include "mimalloc-atomic.h" + +#include // strerror + + +#if defined(_WIN32) +#include +#elif defined(__wasi__) +// stdlib.h is all we need, and has already been included in mimalloc.h +#else +#include // mmap +#include // sysconf +#if defined(__linux__) +#include +#if defined(__GLIBC__) +#include // linux mmap flags +#else +#include +#endif +#endif +#if defined(__APPLE__) +#include +#if !TARGET_IOS_IPHONE && !TARGET_IOS_SIMULATOR +#include +#endif +#endif +#if defined(__HAIKU__) +#define madvise posix_madvise +#define MADV_DONTNEED POSIX_MADV_DONTNEED +#endif +#endif + +/* ----------------------------------------------------------- + Initialization. + On windows initializes support for aligned allocation and + large OS pages (if MIMALLOC_LARGE_OS_PAGES is true). +----------------------------------------------------------- */ +bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats); + +static void* mi_align_up_ptr(void* p, size_t alignment) { + return (void*)_mi_align_up((uintptr_t)p, alignment); +} + +static uintptr_t _mi_align_down(uintptr_t sz, size_t alignment) { + return (sz / alignment) * alignment; +} + +static void* mi_align_down_ptr(void* p, size_t alignment) { + return (void*)_mi_align_down((uintptr_t)p, alignment); +} + +// page size (initialized properly in `os_init`) +static size_t os_page_size = 4096; + +// minimal allocation granularity +static size_t os_alloc_granularity = 4096; + +// if non-zero, use large page allocation +static size_t large_os_page_size = 0; + +// OS (small) page size +size_t _mi_os_page_size() { + return os_page_size; +} + +// if large OS pages are supported (2 or 4MiB), then return the size, otherwise return the small page size (4KiB) +size_t _mi_os_large_page_size() { + return (large_os_page_size != 0 ? large_os_page_size : _mi_os_page_size()); +} + +static bool use_large_os_page(size_t size, size_t alignment) { + // if we have access, check the size and alignment requirements + if (large_os_page_size == 0 || !mi_option_is_enabled(mi_option_large_os_pages)) return false; + return ((size % large_os_page_size) == 0 && (alignment % large_os_page_size) == 0); +} + +// round to a good OS allocation size (bounded by max 12.5% waste) +size_t _mi_os_good_alloc_size(size_t size) { + size_t align_size; + if (size < 512*KiB) align_size = _mi_os_page_size(); + else if (size < 2*MiB) align_size = 64*KiB; + else if (size < 8*MiB) align_size = 256*KiB; + else if (size < 32*MiB) align_size = 1*MiB; + else align_size = 4*MiB; + if (size >= (SIZE_MAX - align_size)) return size; // possible overflow? + return _mi_align_up(size, align_size); +} + +#if defined(_WIN32) +// We use VirtualAlloc2 for aligned allocation, but it is only supported on Windows 10 and Windows Server 2016. +// So, we need to look it up dynamically to run on older systems. (use __stdcall for 32-bit compatibility) +// NtAllocateVirtualAllocEx is used for huge OS page allocation (1GiB) +// +// We hide MEM_EXTENDED_PARAMETER to compile with older SDK's. +#include +typedef PVOID (__stdcall *PVirtualAlloc2)(HANDLE, PVOID, SIZE_T, ULONG, ULONG, /* MEM_EXTENDED_PARAMETER* */ void*, ULONG); +typedef NTSTATUS (__stdcall *PNtAllocateVirtualMemoryEx)(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG, /* MEM_EXTENDED_PARAMETER* */ PVOID, ULONG); +static PVirtualAlloc2 pVirtualAlloc2 = NULL; +static PNtAllocateVirtualMemoryEx pNtAllocateVirtualMemoryEx = NULL; + +// Similarly, GetNumaProcesorNodeEx is only supported since Windows 7 +#if (_WIN32_WINNT < 0x601) // before Win7 +typedef struct _PROCESSOR_NUMBER { WORD Group; BYTE Number; BYTE Reserved; } PROCESSOR_NUMBER, *PPROCESSOR_NUMBER; +#endif +typedef VOID (__stdcall *PGetCurrentProcessorNumberEx)(PPROCESSOR_NUMBER ProcNumber); +typedef BOOL (__stdcall *PGetNumaProcessorNodeEx)(PPROCESSOR_NUMBER Processor, PUSHORT NodeNumber); +typedef BOOL (__stdcall* PGetNumaNodeProcessorMaskEx)(USHORT Node, PGROUP_AFFINITY ProcessorMask); +static PGetCurrentProcessorNumberEx pGetCurrentProcessorNumberEx = NULL; +static PGetNumaProcessorNodeEx pGetNumaProcessorNodeEx = NULL; +static PGetNumaNodeProcessorMaskEx pGetNumaNodeProcessorMaskEx = NULL; + +static bool mi_win_enable_large_os_pages() +{ + if (large_os_page_size > 0) return true; + + // Try to see if large OS pages are supported + // To use large pages on Windows, we first need access permission + // Set "Lock pages in memory" permission in the group policy editor + // + unsigned long err = 0; + HANDLE token = NULL; + BOOL ok = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token); + if (ok) { + TOKEN_PRIVILEGES tp; + ok = LookupPrivilegeValue(NULL, TEXT("SeLockMemoryPrivilege"), &tp.Privileges[0].Luid); + if (ok) { + tp.PrivilegeCount = 1; + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + ok = AdjustTokenPrivileges(token, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0); + if (ok) { + err = GetLastError(); + ok = (err == ERROR_SUCCESS); + if (ok) { + large_os_page_size = GetLargePageMinimum(); + } + } + } + CloseHandle(token); + } + if (!ok) { + if (err == 0) err = GetLastError(); + _mi_warning_message("cannot enable large OS page support, error %lu\n", err); + } + return (ok!=0); +} + +void _mi_os_init(void) { + // get the page size + SYSTEM_INFO si; + GetSystemInfo(&si); + if (si.dwPageSize > 0) os_page_size = si.dwPageSize; + if (si.dwAllocationGranularity > 0) os_alloc_granularity = si.dwAllocationGranularity; + // get the VirtualAlloc2 function + HINSTANCE hDll; + hDll = LoadLibrary(TEXT("kernelbase.dll")); + if (hDll != NULL) { + // use VirtualAlloc2FromApp if possible as it is available to Windows store apps + pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, "VirtualAlloc2FromApp"); + if (pVirtualAlloc2==NULL) pVirtualAlloc2 = (PVirtualAlloc2)(void (*)(void))GetProcAddress(hDll, "VirtualAlloc2"); + FreeLibrary(hDll); + } + // NtAllocateVirtualMemoryEx is used for huge page allocation + hDll = LoadLibrary(TEXT("ntdll.dll")); + if (hDll != NULL) { + pNtAllocateVirtualMemoryEx = (PNtAllocateVirtualMemoryEx)(void (*)(void))GetProcAddress(hDll, "NtAllocateVirtualMemoryEx"); + FreeLibrary(hDll); + } + // Try to use Win7+ numa API + hDll = LoadLibrary(TEXT("kernel32.dll")); + if (hDll != NULL) { + pGetCurrentProcessorNumberEx = (PGetCurrentProcessorNumberEx)(void (*)(void))GetProcAddress(hDll, "GetCurrentProcessorNumberEx"); + pGetNumaProcessorNodeEx = (PGetNumaProcessorNodeEx)(void (*)(void))GetProcAddress(hDll, "GetNumaProcessorNodeEx"); + pGetNumaNodeProcessorMaskEx = (PGetNumaNodeProcessorMaskEx)(void (*)(void))GetProcAddress(hDll, "GetNumaNodeProcessorMaskEx"); + FreeLibrary(hDll); + } + if (mi_option_is_enabled(mi_option_large_os_pages) || mi_option_is_enabled(mi_option_reserve_huge_os_pages)) { + mi_win_enable_large_os_pages(); + } +} +#elif defined(__wasi__) +void _mi_os_init() { + os_page_size = 0x10000; // WebAssembly has a fixed page size: 64KB + os_alloc_granularity = 16; +} +#else +void _mi_os_init() { + // get the page size + long result = sysconf(_SC_PAGESIZE); + if (result > 0) { + os_page_size = (size_t)result; + os_alloc_granularity = os_page_size; + } + large_os_page_size = 2*MiB; // TODO: can we query the OS for this? +} +#endif + + +/* ----------------------------------------------------------- + Raw allocation on Windows (VirtualAlloc) and Unix's (mmap). +----------------------------------------------------------- */ + +static bool mi_os_mem_free(void* addr, size_t size, bool was_committed, mi_stats_t* stats) +{ + if (addr == NULL || size == 0) return true; // || _mi_os_is_huge_reserved(addr) + bool err = false; +#if defined(_WIN32) + err = (VirtualFree(addr, 0, MEM_RELEASE) == 0); +#elif defined(__wasi__) + err = 0; // WebAssembly's heap cannot be shrunk +#else + err = (munmap(addr, size) == -1); +#endif + if (was_committed) _mi_stat_decrease(&stats->committed, size); + _mi_stat_decrease(&stats->reserved, size); + if (err) { + #pragma warning(suppress:4996) + _mi_warning_message("munmap failed: %s, addr 0x%8li, size %lu\n", strerror(errno), (size_t)addr, size); + return false; + } + else { + return true; + } +} + +static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size); + +#ifdef _WIN32 +static void* mi_win_virtual_allocx(void* addr, size_t size, size_t try_alignment, DWORD flags) { +#if (MI_INTPTR_SIZE >= 8) + // on 64-bit systems, try to use the virtual address area after 4TiB for 4MiB aligned allocations + void* hint; + if (addr == NULL && (hint = mi_os_get_aligned_hint(try_alignment,size)) != NULL) { + void* p = VirtualAlloc(hint, size, flags, PAGE_READWRITE); + if (p != NULL) return p; + DWORD err = GetLastError(); + if (err != ERROR_INVALID_ADDRESS && // If linked with multiple instances, we may have tried to allocate at an already allocated area (#210) + err != ERROR_INVALID_PARAMETER) { // Windows7 instability (#230) + return NULL; + } + // fall through + } +#endif +#if defined(MEM_EXTENDED_PARAMETER_TYPE_BITS) + // on modern Windows try use VirtualAlloc2 for aligned allocation + if (try_alignment > 0 && (try_alignment % _mi_os_page_size()) == 0 && pVirtualAlloc2 != NULL) { + MEM_ADDRESS_REQUIREMENTS reqs = { 0, 0, 0 }; + reqs.Alignment = try_alignment; + MEM_EXTENDED_PARAMETER param = { {0, 0}, {0} }; + param.Type = MemExtendedParameterAddressRequirements; + param.Pointer = &reqs; + return (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, ¶m, 1); + } +#endif + // last resort + return VirtualAlloc(addr, size, flags, PAGE_READWRITE); +} + +static void* mi_win_virtual_alloc(void* addr, size_t size, size_t try_alignment, DWORD flags, bool large_only, bool allow_large, bool* is_large) { + mi_assert_internal(!(large_only && !allow_large)); + static volatile _Atomic(uintptr_t) large_page_try_ok; // = 0; + void* p = NULL; + if ((large_only || use_large_os_page(size, try_alignment)) + && allow_large && (flags&MEM_COMMIT)!=0 && (flags&MEM_RESERVE)!=0) { + uintptr_t try_ok = mi_atomic_read(&large_page_try_ok); + if (!large_only && try_ok > 0) { + // if a large page allocation fails, it seems the calls to VirtualAlloc get very expensive. + // therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times. + mi_atomic_cas_weak(&large_page_try_ok, try_ok - 1, try_ok); + } + else { + // large OS pages must always reserve and commit. + *is_large = true; + p = mi_win_virtual_allocx(addr, size, try_alignment, flags | MEM_LARGE_PAGES); + if (large_only) return p; + // fall back to non-large page allocation on error (`p == NULL`). + if (p == NULL) { + mi_atomic_write(&large_page_try_ok,10); // on error, don't try again for the next N allocations + } + } + } + if (p == NULL) { + *is_large = ((flags&MEM_LARGE_PAGES) != 0); + p = mi_win_virtual_allocx(addr, size, try_alignment, flags); + } + if (p == NULL) { + _mi_warning_message("unable to allocate OS memory (%zu bytes, error code: %i, address: %p, large only: %d, allow large: %d)\n", size, GetLastError(), addr, large_only, allow_large); + } + return p; +} + +#elif defined(__wasi__) +static void* mi_wasm_heap_grow(size_t size, size_t try_alignment) { + uintptr_t base = __builtin_wasm_memory_size(0) * _mi_os_page_size(); + uintptr_t aligned_base = _mi_align_up(base, (uintptr_t) try_alignment); + size_t alloc_size = _mi_align_up( aligned_base - base + size, _mi_os_page_size()); + mi_assert(alloc_size >= size && (alloc_size % _mi_os_page_size()) == 0); + if (alloc_size < size) return NULL; + if (__builtin_wasm_memory_grow(0, alloc_size / _mi_os_page_size()) == SIZE_MAX) { + errno = ENOMEM; + return NULL; + } + return (void*)aligned_base; +} +#else +#define MI_OS_USE_MMAP +static void* mi_unix_mmapx(void* addr, size_t size, size_t try_alignment, int protect_flags, int flags, int fd) { + void* p = NULL; + #if (MI_INTPTR_SIZE >= 8) && !defined(MAP_ALIGNED) + // on 64-bit systems, use the virtual address area after 4TiB for 4MiB aligned allocations + void* hint; + if (addr == NULL && (hint = mi_os_get_aligned_hint(try_alignment, size)) != NULL) { + p = mmap(hint,size,protect_flags,flags,fd,0); + if (p==MAP_FAILED) p = NULL; // fall back to regular mmap + } + #else + UNUSED(try_alignment); + UNUSED(mi_os_get_aligned_hint); + #endif + if (p==NULL) { + p = mmap(addr,size,protect_flags,flags,fd,0); + if (p==MAP_FAILED) p = NULL; + } + return p; +} + +static void* mi_unix_mmap(void* addr, size_t size, size_t try_alignment, int protect_flags, bool large_only, bool allow_large, bool* is_large) { + void* p = NULL; + #if !defined(MAP_ANONYMOUS) + #define MAP_ANONYMOUS MAP_ANON + #endif + #if !defined(MAP_NORESERVE) + #define MAP_NORESERVE 0 + #endif + int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE; + int fd = -1; + #if defined(MAP_ALIGNED) // BSD + if (try_alignment > 0) { + size_t n = _mi_bsr(try_alignment); + if (((size_t)1 << n) == try_alignment && n >= 12 && n <= 30) { // alignment is a power of 2 and 4096 <= alignment <= 1GiB + flags |= MAP_ALIGNED(n); + } + } + #endif + #if defined(PROT_MAX) + protect_flags |= PROT_MAX(PROT_READ | PROT_WRITE); // BSD + #endif + #if defined(VM_MAKE_TAG) + // macOS: tracking anonymous page with a specific ID. (All up to 98 are taken officially but LLVM sanitizers had taken 99) + int os_tag = (int)mi_option_get(mi_option_os_tag); + if (os_tag < 100 || os_tag > 255) os_tag = 100; + fd = VM_MAKE_TAG(os_tag); + #endif + if ((large_only || use_large_os_page(size, try_alignment)) && allow_large) { + static volatile _Atomic(uintptr_t) large_page_try_ok; // = 0; + uintptr_t try_ok = mi_atomic_read(&large_page_try_ok); + if (!large_only && try_ok > 0) { + // If the OS is not configured for large OS pages, or the user does not have + // enough permission, the `mmap` will always fail (but it might also fail for other reasons). + // Therefore, once a large page allocation failed, we don't try again for `large_page_try_ok` times + // to avoid too many failing calls to mmap. + mi_atomic_cas_weak(&large_page_try_ok, try_ok - 1, try_ok); + } + else { + int lflags = flags & ~MAP_NORESERVE; // using NORESERVE on huge pages seems to fail on Linux + int lfd = fd; + #ifdef MAP_ALIGNED_SUPER + lflags |= MAP_ALIGNED_SUPER; + #endif + #ifdef MAP_HUGETLB + lflags |= MAP_HUGETLB; + #endif + #ifdef MAP_HUGE_1GB + static bool mi_huge_pages_available = true; + if ((size % GiB) == 0 && mi_huge_pages_available) { + lflags |= MAP_HUGE_1GB; + } + else + #endif + { + #ifdef MAP_HUGE_2MB + lflags |= MAP_HUGE_2MB; + #endif + } + #ifdef VM_FLAGS_SUPERPAGE_SIZE_2MB + lfd |= VM_FLAGS_SUPERPAGE_SIZE_2MB; + #endif + if (large_only || lflags != flags) { + // try large OS page allocation + *is_large = true; + p = mi_unix_mmapx(addr, size, try_alignment, protect_flags, lflags, lfd); + #ifdef MAP_HUGE_1GB + if (p == NULL && (lflags & MAP_HUGE_1GB) != 0) { + mi_huge_pages_available = false; // don't try huge 1GiB pages again + _mi_warning_message("unable to allocate huge (1GiB) page, trying large (2MiB) pages instead (error %i)\n", errno); + lflags = ((lflags & ~MAP_HUGE_1GB) | MAP_HUGE_2MB); + p = mi_unix_mmapx(addr, size, try_alignment, protect_flags, lflags, lfd); + } + #endif + if (large_only) return p; + if (p == NULL) { + mi_atomic_write(&large_page_try_ok, 10); // on error, don't try again for the next N allocations + } + } + } + } + if (p == NULL) { + *is_large = false; + p = mi_unix_mmapx(addr, size, try_alignment, protect_flags, flags, fd); + #if defined(MADV_HUGEPAGE) + // Many Linux systems don't allow MAP_HUGETLB but they support instead + // transparent huge pages (THP). It is not required to call `madvise` with MADV_HUGE + // though since properly aligned allocations will already use large pages if available + // in that case -- in particular for our large regions (in `memory.c`). + // However, some systems only allow THP if called with explicit `madvise`, so + // when large OS pages are enabled for mimalloc, we call `madvice` anyways. + if (allow_large && use_large_os_page(size, try_alignment)) { + if (madvise(p, size, MADV_HUGEPAGE) == 0) { + *is_large = true; // possibly + }; + } + #endif + #if defined(__sun) + if (allow_large && use_large_os_page(size, try_alignment)) { + struct memcntl_mha cmd = {0}; + cmd.mha_pagesize = large_os_page_size; + cmd.mha_cmd = MHA_MAPSIZE_VA; + if (memcntl(p, size, MC_HAT_ADVISE, (caddr_t)&cmd, 0, 0) == 0) { + *is_large = true; + } + } + #endif + } + if (p == NULL) { + _mi_warning_message("unable to allocate OS memory (%zu bytes, error code: %i, address: %p, large only: %d, allow large: %d)\n", size, errno, addr, large_only, allow_large); + } + return p; +} +#endif + +// On 64-bit systems, we can do efficient aligned allocation by using +// the 4TiB to 30TiB area to allocate them. +#if (MI_INTPTR_SIZE >= 8) && (defined(_WIN32) || (defined(MI_OS_USE_MMAP) && !defined(MAP_ALIGNED))) +static volatile mi_decl_cache_align _Atomic(uintptr_t) aligned_base; + +// Return a 4MiB aligned address that is probably available +static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size) { + if (try_alignment == 0 || try_alignment > MI_SEGMENT_SIZE) return NULL; + if ((size%MI_SEGMENT_SIZE) != 0) return NULL; + uintptr_t hint = mi_atomic_add(&aligned_base, size); + if (hint == 0 || hint > ((intptr_t)30<<40)) { // try to wrap around after 30TiB (area after 32TiB is used for huge OS pages) + uintptr_t init = ((uintptr_t)4 << 40); // start at 4TiB area + #if (MI_SECURE>0 || MI_DEBUG==0) // security: randomize start of aligned allocations unless in debug mode + uintptr_t r = _mi_heap_random_next(mi_get_default_heap()); + init = init + (MI_SEGMENT_SIZE * ((r>>17) & 0xFFFFF)); // (randomly 20 bits)*4MiB == 0 to 4TiB + #endif + mi_atomic_cas_strong(&aligned_base, init, hint + size); + hint = mi_atomic_add(&aligned_base, size); // this may still give 0 or > 30TiB but that is ok, it is a hint after all + } + if (hint%try_alignment != 0) return NULL; + return (void*)hint; +} +#else +static void* mi_os_get_aligned_hint(size_t try_alignment, size_t size) { + UNUSED(try_alignment); UNUSED(size); + return NULL; +} +#endif + + +// Primitive allocation from the OS. +// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned. +static void* mi_os_mem_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, mi_stats_t* stats) { + mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0); + if (size == 0) return NULL; + if (!commit) allow_large = false; + + void* p = NULL; + /* + if (commit && allow_large) { + p = _mi_os_try_alloc_from_huge_reserved(size, try_alignment); + if (p != NULL) { + *is_large = true; + return p; + } + } + */ + + #if defined(_WIN32) + int flags = MEM_RESERVE; + if (commit) flags |= MEM_COMMIT; + p = mi_win_virtual_alloc(NULL, size, try_alignment, flags, false, allow_large, is_large); + #elif defined(__wasi__) + *is_large = false; + p = mi_wasm_heap_grow(size, try_alignment); + #else + int protect_flags = (commit ? (PROT_WRITE | PROT_READ) : PROT_NONE); + p = mi_unix_mmap(NULL, size, try_alignment, protect_flags, false, allow_large, is_large); + #endif + mi_stat_counter_increase(stats->mmap_calls, 1); + if (p != NULL) { + _mi_stat_increase(&stats->reserved, size); + if (commit) { _mi_stat_increase(&stats->committed, size); } + } + return p; +} + + +// Primitive aligned allocation from the OS. +// This function guarantees the allocated memory is aligned. +static void* mi_os_mem_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, bool* is_large, mi_stats_t* stats) { + mi_assert_internal(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0)); + mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0); + if (!commit) allow_large = false; + if (!(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0))) return NULL; + size = _mi_align_up(size, _mi_os_page_size()); + + // try first with a hint (this will be aligned directly on Win 10+ or BSD) + void* p = mi_os_mem_alloc(size, alignment, commit, allow_large, is_large, stats); + if (p == NULL) return NULL; + + // if not aligned, free it, overallocate, and unmap around it + if (((uintptr_t)p % alignment != 0)) { + mi_os_mem_free(p, size, commit, stats); + if (size >= (SIZE_MAX - alignment)) return NULL; // overflow + size_t over_size = size + alignment; + +#if _WIN32 + // over-allocate and than re-allocate exactly at an aligned address in there. + // this may fail due to threads allocating at the same time so we + // retry this at most 3 times before giving up. + // (we can not decommit around the overallocation on Windows, because we can only + // free the original pointer, not one pointing inside the area) + int flags = MEM_RESERVE; + if (commit) flags |= MEM_COMMIT; + for (int tries = 0; tries < 3; tries++) { + // over-allocate to determine a virtual memory range + p = mi_os_mem_alloc(over_size, alignment, commit, false, is_large, stats); + if (p == NULL) return NULL; // error + if (((uintptr_t)p % alignment) == 0) { + // if p happens to be aligned, just decommit the left-over area + _mi_os_decommit((uint8_t*)p + size, over_size - size, stats); + break; + } + else { + // otherwise free and allocate at an aligned address in there + mi_os_mem_free(p, over_size, commit, stats); + void* aligned_p = mi_align_up_ptr(p, alignment); + p = mi_win_virtual_alloc(aligned_p, size, alignment, flags, false, allow_large, is_large); + if (p == aligned_p) break; // success! + if (p != NULL) { // should not happen? + mi_os_mem_free(p, size, commit, stats); + p = NULL; + } + } + } +#else + // overallocate... + p = mi_os_mem_alloc(over_size, alignment, commit, false, is_large, stats); + if (p == NULL) return NULL; + // and selectively unmap parts around the over-allocated area. + void* aligned_p = mi_align_up_ptr(p, alignment); + size_t pre_size = (uint8_t*)aligned_p - (uint8_t*)p; + size_t mid_size = _mi_align_up(size, _mi_os_page_size()); + size_t post_size = over_size - pre_size - mid_size; + mi_assert_internal(pre_size < over_size && post_size < over_size && mid_size >= size); + if (pre_size > 0) mi_os_mem_free(p, pre_size, commit, stats); + if (post_size > 0) mi_os_mem_free((uint8_t*)aligned_p + mid_size, post_size, commit, stats); + // we can return the aligned pointer on `mmap` systems + p = aligned_p; +#endif + } + + mi_assert_internal(p == NULL || (p != NULL && ((uintptr_t)p % alignment) == 0)); + return p; +} + +/* ----------------------------------------------------------- + OS API: alloc, free, alloc_aligned +----------------------------------------------------------- */ + +void* _mi_os_alloc(size_t size, mi_stats_t* stats) { + if (size == 0) return NULL; + size = _mi_os_good_alloc_size(size); + bool is_large = false; + return mi_os_mem_alloc(size, 0, true, false, &is_large, stats); +} + +void _mi_os_free_ex(void* p, size_t size, bool was_committed, mi_stats_t* stats) { + if (size == 0 || p == NULL) return; + size = _mi_os_good_alloc_size(size); + mi_os_mem_free(p, size, was_committed, stats); +} + +void _mi_os_free(void* p, size_t size, mi_stats_t* stats) { + _mi_os_free_ex(p, size, true, stats); +} + +void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool* large, mi_os_tld_t* tld) +{ + if (size == 0) return NULL; + size = _mi_os_good_alloc_size(size); + alignment = _mi_align_up(alignment, _mi_os_page_size()); + bool allow_large = false; + if (large != NULL) { + allow_large = *large; + *large = false; + } + return mi_os_mem_alloc_aligned(size, alignment, commit, allow_large, (large!=NULL?large:&allow_large), tld->stats); +} + + + +/* ----------------------------------------------------------- + OS memory API: reset, commit, decommit, protect, unprotect. +----------------------------------------------------------- */ + + +// OS page align within a given area, either conservative (pages inside the area only), +// or not (straddling pages outside the area is possible) +static void* mi_os_page_align_areax(bool conservative, void* addr, size_t size, size_t* newsize) { + mi_assert(addr != NULL && size > 0); + if (newsize != NULL) *newsize = 0; + if (size == 0 || addr == NULL) return NULL; + + // page align conservatively within the range + void* start = (conservative ? mi_align_up_ptr(addr, _mi_os_page_size()) + : mi_align_down_ptr(addr, _mi_os_page_size())); + void* end = (conservative ? mi_align_down_ptr((uint8_t*)addr + size, _mi_os_page_size()) + : mi_align_up_ptr((uint8_t*)addr + size, _mi_os_page_size())); + ptrdiff_t diff = (uint8_t*)end - (uint8_t*)start; + if (diff <= 0) return NULL; + + mi_assert_internal((conservative && (size_t)diff <= size) || (!conservative && (size_t)diff >= size)); + if (newsize != NULL) *newsize = (size_t)diff; + return start; +} + +static void* mi_os_page_align_area_conservative(void* addr, size_t size, size_t* newsize) { + return mi_os_page_align_areax(true, addr, size, newsize); +} + +static void mi_mprotect_hint(int err) { +#if defined(MI_OS_USE_MMAP) && (MI_SECURE>=2) // guard page around every mimalloc page + if (err == ENOMEM) { + _mi_warning_message("the previous warning may have been caused by a low memory map limit.\n" + " On Linux this is controlled by the vm.max_map_count. For example:\n" + " > sudo sysctl -w vm.max_map_count=262144\n"); + } +#else + UNUSED(err); +#endif +} + +// Commit/Decommit memory. +// Usually commit is aligned liberal, while decommit is aligned conservative. +// (but not for the reset version where we want commit to be conservative as well) +static bool mi_os_commitx(void* addr, size_t size, bool commit, bool conservative, bool* is_zero, mi_stats_t* stats) { + // page align in the range, commit liberally, decommit conservative + if (is_zero != NULL) { *is_zero = false; } + size_t csize; + void* start = mi_os_page_align_areax(conservative, addr, size, &csize); + if (csize == 0) return true; // || _mi_os_is_huge_reserved(addr)) + int err = 0; + if (commit) { + _mi_stat_increase(&stats->committed, csize); + _mi_stat_counter_increase(&stats->commit_calls, 1); + } + else { + _mi_stat_decrease(&stats->committed, csize); + } + + #if defined(_WIN32) + if (commit) { + // if the memory was already committed, the call succeeds but it is not zero'd + // *is_zero = true; + void* p = VirtualAlloc(start, csize, MEM_COMMIT, PAGE_READWRITE); + err = (p == start ? 0 : GetLastError()); + } + else { + BOOL ok = VirtualFree(start, csize, MEM_DECOMMIT); + err = (ok ? 0 : GetLastError()); + } + #elif defined(__wasi__) + // WebAssembly guests can't control memory protection + #elif defined(MAP_FIXED) + if (!commit) { + // use mmap with MAP_FIXED to discard the existing memory (and reduce commit charge) + void* p = mmap(start, csize, PROT_NONE, (MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE), -1, 0); + if (p != start) { err = errno; } + } + else { + // for commit, just change the protection + err = mprotect(start, csize, (PROT_READ | PROT_WRITE)); + if (err != 0) { err = errno; } + } + #else + err = mprotect(start, csize, (commit ? (PROT_READ | PROT_WRITE) : PROT_NONE)); + if (err != 0) { err = errno; } + #endif + if (err != 0) { + _mi_warning_message("%s error: start: %p, csize: 0x%x, err: %i\n", commit ? "commit" : "decommit", start, csize, err); + mi_mprotect_hint(err); + } + mi_assert_internal(err == 0); + return (err == 0); +} + +bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* stats) { + return mi_os_commitx(addr, size, true, false /* liberal */, is_zero, stats); +} + +bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats) { + bool is_zero; + return mi_os_commitx(addr, size, false, true /* conservative */, &is_zero, stats); +} + +bool _mi_os_commit_unreset(void* addr, size_t size, bool* is_zero, mi_stats_t* stats) { + return mi_os_commitx(addr, size, true, true /* conservative */, is_zero, stats); +} + +// Signal to the OS that the address range is no longer in use +// but may be used later again. This will release physical memory +// pages and reduce swapping while keeping the memory committed. +// We page align to a conservative area inside the range to reset. +static bool mi_os_resetx(void* addr, size_t size, bool reset, mi_stats_t* stats) { + // page align conservatively within the range + size_t csize; + void* start = mi_os_page_align_area_conservative(addr, size, &csize); + if (csize == 0) return true; // || _mi_os_is_huge_reserved(addr) + if (reset) _mi_stat_increase(&stats->reset, csize); + else _mi_stat_decrease(&stats->reset, csize); + if (!reset) return true; // nothing to do on unreset! + + #if (MI_DEBUG>1) + if (MI_SECURE==0) { + memset(start, 0, csize); // pretend it is eagerly reset + } + #endif + +#if defined(_WIN32) + // Testing shows that for us (on `malloc-large`) MEM_RESET is 2x faster than DiscardVirtualMemory + void* p = VirtualAlloc(start, csize, MEM_RESET, PAGE_READWRITE); + mi_assert_internal(p == start); + #if 1 + if (p == start && start != NULL) { + VirtualUnlock(start,csize); // VirtualUnlock after MEM_RESET removes the memory from the working set + } + #endif + if (p != start) return false; +#else +#if defined(MADV_FREE) + static int advice = MADV_FREE; + int err = madvise(start, csize, advice); + if (err != 0 && errno == EINVAL && advice == MADV_FREE) { + // if MADV_FREE is not supported, fall back to MADV_DONTNEED from now on + advice = MADV_DONTNEED; + err = madvise(start, csize, advice); + } +#elif defined(__wasi__) + int err = 0; +#else + int err = madvise(start, csize, MADV_DONTNEED); +#endif + if (err != 0) { + _mi_warning_message("madvise reset error: start: %p, csize: 0x%x, errno: %i\n", start, csize, errno); + } + //mi_assert(err == 0); + if (err != 0) return false; +#endif + return true; +} + +// Signal to the OS that the address range is no longer in use +// but may be used later again. This will release physical memory +// pages and reduce swapping while keeping the memory committed. +// We page align to a conservative area inside the range to reset. +bool _mi_os_reset(void* addr, size_t size, mi_stats_t* stats) { + if (mi_option_is_enabled(mi_option_reset_decommits)) { + return _mi_os_decommit(addr, size, stats); + } + else { + return mi_os_resetx(addr, size, true, stats); + } +} + +bool _mi_os_unreset(void* addr, size_t size, bool* is_zero, mi_stats_t* stats) { + if (mi_option_is_enabled(mi_option_reset_decommits)) { + return _mi_os_commit_unreset(addr, size, is_zero, stats); // re-commit it (conservatively!) + } + else { + *is_zero = false; + return mi_os_resetx(addr, size, false, stats); + } +} + + +// Protect a region in memory to be not accessible. +static bool mi_os_protectx(void* addr, size_t size, bool protect) { + // page align conservatively within the range + size_t csize = 0; + void* start = mi_os_page_align_area_conservative(addr, size, &csize); + if (csize == 0) return false; + /* + if (_mi_os_is_huge_reserved(addr)) { + _mi_warning_message("cannot mprotect memory allocated in huge OS pages\n"); + } + */ + int err = 0; +#ifdef _WIN32 + DWORD oldprotect = 0; + BOOL ok = VirtualProtect(start, csize, protect ? PAGE_NOACCESS : PAGE_READWRITE, &oldprotect); + err = (ok ? 0 : GetLastError()); +#elif defined(__wasi__) + err = 0; +#else + err = mprotect(start, csize, protect ? PROT_NONE : (PROT_READ | PROT_WRITE)); + if (err != 0) { err = errno; } +#endif + if (err != 0) { + _mi_warning_message("mprotect error: start: %p, csize: 0x%x, err: %i\n", start, csize, err); + mi_mprotect_hint(err); + } + return (err == 0); +} + +bool _mi_os_protect(void* addr, size_t size) { + return mi_os_protectx(addr, size, true); +} + +bool _mi_os_unprotect(void* addr, size_t size) { + return mi_os_protectx(addr, size, false); +} + + + +bool _mi_os_shrink(void* p, size_t oldsize, size_t newsize, mi_stats_t* stats) { + // page align conservatively within the range + mi_assert_internal(oldsize > newsize && p != NULL); + if (oldsize < newsize || p == NULL) return false; + if (oldsize == newsize) return true; + + // oldsize and newsize should be page aligned or we cannot shrink precisely + void* addr = (uint8_t*)p + newsize; + size_t size = 0; + void* start = mi_os_page_align_area_conservative(addr, oldsize - newsize, &size); + if (size == 0 || start != addr) return false; + +#ifdef _WIN32 + // we cannot shrink on windows, but we can decommit + return _mi_os_decommit(start, size, stats); +#else + return mi_os_mem_free(start, size, true, stats); +#endif +} + + +/* ---------------------------------------------------------------------------- +Support for allocating huge OS pages (1Gib) that are reserved up-front +and possibly associated with a specific NUMA node. (use `numa_node>=0`) +-----------------------------------------------------------------------------*/ +#define MI_HUGE_OS_PAGE_SIZE (GiB) + +#if defined(_WIN32) && (MI_INTPTR_SIZE >= 8) +static void* mi_os_alloc_huge_os_pagesx(void* addr, size_t size, int numa_node) +{ + mi_assert_internal(size%GiB == 0); + mi_assert_internal(addr != NULL); + const DWORD flags = MEM_LARGE_PAGES | MEM_COMMIT | MEM_RESERVE; + + mi_win_enable_large_os_pages(); + + #if defined(MEM_EXTENDED_PARAMETER_TYPE_BITS) + MEM_EXTENDED_PARAMETER params[3] = { {{0,0},{0}},{{0,0},{0}},{{0,0},{0}} }; + // on modern Windows try use NtAllocateVirtualMemoryEx for 1GiB huge pages + static bool mi_huge_pages_available = true; + if (pNtAllocateVirtualMemoryEx != NULL && mi_huge_pages_available) { + #ifndef MEM_EXTENDED_PARAMETER_NONPAGED_HUGE + #define MEM_EXTENDED_PARAMETER_NONPAGED_HUGE (0x10) + #endif + params[0].Type = 5; // == MemExtendedParameterAttributeFlags; + params[0].ULong64 = MEM_EXTENDED_PARAMETER_NONPAGED_HUGE; + ULONG param_count = 1; + if (numa_node >= 0) { + param_count++; + params[1].Type = MemExtendedParameterNumaNode; + params[1].ULong = (unsigned)numa_node; + } + SIZE_T psize = size; + void* base = addr; + NTSTATUS err = (*pNtAllocateVirtualMemoryEx)(GetCurrentProcess(), &base, &psize, flags, PAGE_READWRITE, params, param_count); + if (err == 0 && base != NULL) { + return base; + } + else { + // fall back to regular large pages + mi_huge_pages_available = false; // don't try further huge pages + _mi_warning_message("unable to allocate using huge (1gb) pages, trying large (2mb) pages instead (status 0x%lx)\n", err); + } + } + // on modern Windows try use VirtualAlloc2 for numa aware large OS page allocation + if (pVirtualAlloc2 != NULL && numa_node >= 0) { + params[0].Type = MemExtendedParameterNumaNode; + params[0].ULong = (unsigned)numa_node; + return (*pVirtualAlloc2)(GetCurrentProcess(), addr, size, flags, PAGE_READWRITE, params, 1); + } + #else + UNUSED(numa_node); + #endif + // otherwise use regular virtual alloc on older windows + return VirtualAlloc(addr, size, flags, PAGE_READWRITE); +} + +#elif defined(MI_OS_USE_MMAP) && (MI_INTPTR_SIZE >= 8) && !defined(__HAIKU__) +#include +#ifndef MPOL_PREFERRED +#define MPOL_PREFERRED 1 +#endif +#if defined(SYS_mbind) +static long mi_os_mbind(void* start, unsigned long len, unsigned long mode, const unsigned long* nmask, unsigned long maxnode, unsigned flags) { + return syscall(SYS_mbind, start, len, mode, nmask, maxnode, flags); +} +#else +static long mi_os_mbind(void* start, unsigned long len, unsigned long mode, const unsigned long* nmask, unsigned long maxnode, unsigned flags) { + UNUSED(start); UNUSED(len); UNUSED(mode); UNUSED(nmask); UNUSED(maxnode); UNUSED(flags); + return 0; +} +#endif +static void* mi_os_alloc_huge_os_pagesx(void* addr, size_t size, int numa_node) { + mi_assert_internal(size%GiB == 0); + bool is_large = true; + void* p = mi_unix_mmap(addr, size, MI_SEGMENT_SIZE, PROT_READ | PROT_WRITE, true, true, &is_large); + if (p == NULL) return NULL; + if (numa_node >= 0 && numa_node < 8*MI_INTPTR_SIZE) { // at most 64 nodes + uintptr_t numa_mask = (1UL << numa_node); + // TODO: does `mbind` work correctly for huge OS pages? should we + // use `set_mempolicy` before calling mmap instead? + // see: + long err = mi_os_mbind(p, size, MPOL_PREFERRED, &numa_mask, 8*MI_INTPTR_SIZE, 0); + if (err != 0) { + _mi_warning_message("failed to bind huge (1gb) pages to numa node %d: %s\n", numa_node, strerror(errno)); + } + } + return p; +} +#else +static void* mi_os_alloc_huge_os_pagesx(void* addr, size_t size, int numa_node) { + UNUSED(addr); UNUSED(size); UNUSED(numa_node); + return NULL; +} +#endif + +#if (MI_INTPTR_SIZE >= 8) +// To ensure proper alignment, use our own area for huge OS pages +static mi_decl_cache_align _Atomic(uintptr_t) mi_huge_start; // = 0 + +// Claim an aligned address range for huge pages +static uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) { + if (total_size != NULL) *total_size = 0; + const size_t size = pages * MI_HUGE_OS_PAGE_SIZE; + + uintptr_t start = 0; + uintptr_t end = 0; + uintptr_t expected; + do { + start = expected = mi_atomic_read_relaxed(&mi_huge_start); + if (start == 0) { + // Initialize the start address after the 32TiB area + start = ((uintptr_t)32 << 40); // 32TiB virtual start address +#if (MI_SECURE>0 || MI_DEBUG==0) // security: randomize start of huge pages unless in debug mode + uintptr_t r = _mi_heap_random_next(mi_get_default_heap()); + start = start + ((uintptr_t)MI_HUGE_OS_PAGE_SIZE * ((r>>17) & 0x0FFF)); // (randomly 12bits)*1GiB == between 0 to 4TiB +#endif + } + end = start + size; + mi_assert_internal(end % MI_SEGMENT_SIZE == 0); + } while (!mi_atomic_cas_strong(&mi_huge_start, end, expected)); + + if (total_size != NULL) *total_size = size; + return (uint8_t*)start; +} +#else +static uint8_t* mi_os_claim_huge_pages(size_t pages, size_t* total_size) { + UNUSED(pages); + if (total_size != NULL) *total_size = 0; + return NULL; +} +#endif + +// Allocate MI_SEGMENT_SIZE aligned huge pages +void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_msecs, size_t* pages_reserved, size_t* psize) { + if (psize != NULL) *psize = 0; + if (pages_reserved != NULL) *pages_reserved = 0; + size_t size = 0; + uint8_t* start = mi_os_claim_huge_pages(pages, &size); + if (start == NULL) return NULL; // or 32-bit systems + + // Allocate one page at the time but try to place them contiguously + // We allocate one page at the time to be able to abort if it takes too long + // or to at least allocate as many as available on the system. + mi_msecs_t start_t = _mi_clock_start(); + size_t page; + for (page = 0; page < pages; page++) { + // allocate a page + void* addr = start + (page * MI_HUGE_OS_PAGE_SIZE); + void* p = mi_os_alloc_huge_os_pagesx(addr, MI_HUGE_OS_PAGE_SIZE, numa_node); + + // Did we succeed at a contiguous address? + if (p != addr) { + // no success, issue a warning and break + if (p != NULL) { + _mi_warning_message("could not allocate contiguous huge page %zu at %p\n", page, addr); + _mi_os_free(p, MI_HUGE_OS_PAGE_SIZE, &_mi_stats_main); + } + break; + } + + // success, record it + _mi_stat_increase(&_mi_stats_main.committed, MI_HUGE_OS_PAGE_SIZE); + _mi_stat_increase(&_mi_stats_main.reserved, MI_HUGE_OS_PAGE_SIZE); + + // check for timeout + if (max_msecs > 0) { + mi_msecs_t elapsed = _mi_clock_end(start_t); + if (page >= 1) { + mi_msecs_t estimate = ((elapsed / (page+1)) * pages); + if (estimate > 2*max_msecs) { // seems like we are going to timeout, break + elapsed = max_msecs + 1; + } + } + if (elapsed > max_msecs) { + _mi_warning_message("huge page allocation timed out\n"); + break; + } + } + } + mi_assert_internal(page*MI_HUGE_OS_PAGE_SIZE <= size); + if (pages_reserved != NULL) *pages_reserved = page; + if (psize != NULL) *psize = page * MI_HUGE_OS_PAGE_SIZE; + return (page == 0 ? NULL : start); +} + +// free every huge page in a range individually (as we allocated per page) +// note: needed with VirtualAlloc but could potentially be done in one go on mmap'd systems. +void _mi_os_free_huge_pages(void* p, size_t size, mi_stats_t* stats) { + if (p==NULL || size==0) return; + uint8_t* base = (uint8_t*)p; + while (size >= MI_HUGE_OS_PAGE_SIZE) { + _mi_os_free(base, MI_HUGE_OS_PAGE_SIZE, stats); + size -= MI_HUGE_OS_PAGE_SIZE; + } +} + +/* ---------------------------------------------------------------------------- +Support NUMA aware allocation +-----------------------------------------------------------------------------*/ +#ifdef _WIN32 +static size_t mi_os_numa_nodex() { + USHORT numa_node = 0; + if (pGetCurrentProcessorNumberEx != NULL && pGetNumaProcessorNodeEx != NULL) { + // Extended API is supported + PROCESSOR_NUMBER pnum; + (*pGetCurrentProcessorNumberEx)(&pnum); + USHORT nnode = 0; + BOOL ok = (*pGetNumaProcessorNodeEx)(&pnum, &nnode); + if (ok) numa_node = nnode; + } + else { + // Vista or earlier, use older API that is limited to 64 processors. Issue #277 + DWORD pnum = GetCurrentProcessorNumber(); + UCHAR nnode = 0; + BOOL ok = GetNumaProcessorNode((UCHAR)pnum, &nnode); + if (ok) numa_node = nnode; + } + return numa_node; +} + +static size_t mi_os_numa_node_countx(void) { + ULONG numa_max = 0; + GetNumaHighestNodeNumber(&numa_max); + // find the highest node number that has actual processors assigned to it. Issue #282 + while(numa_max > 0) { + if (pGetNumaNodeProcessorMaskEx != NULL) { + // Extended API is supported + GROUP_AFFINITY affinity; + if ((*pGetNumaNodeProcessorMaskEx)((USHORT)numa_max, &affinity)) { + if (affinity.Mask != 0) break; // found the maximum non-empty node + } + } + else { + // Vista or earlier, use older API that is limited to 64 processors. + ULONGLONG mask; + if (GetNumaNodeProcessorMask((UCHAR)numa_max, &mask)) { + if (mask != 0) break; // found the maximum non-empty node + }; + } + // max node was invalid or had no processor assigned, try again + numa_max--; + } + return ((size_t)numa_max + 1); +} +#elif defined(__linux__) +#include // getcpu +#include // access + +static size_t mi_os_numa_nodex(void) { +#ifdef SYS_getcpu + unsigned long node = 0; + unsigned long ncpu = 0; + long err = syscall(SYS_getcpu, &ncpu, &node, NULL); + if (err != 0) return 0; + return node; +#else + return 0; +#endif +} +static size_t mi_os_numa_node_countx(void) { + char buf[128]; + unsigned node = 0; + for(node = 0; node < 256; node++) { + // enumerate node entries -- todo: it there a more efficient way to do this? (but ensure there is no allocation) + snprintf(buf, 127, "/sys/devices/system/node/node%u", node + 1); + if (access(buf,R_OK) != 0) break; + } + return (node+1); +} +#else +static size_t mi_os_numa_nodex(void) { + return 0; +} +static size_t mi_os_numa_node_countx(void) { + return 1; +} +#endif + +size_t _mi_numa_node_count = 0; // cache the node count + +size_t _mi_os_numa_node_count_get(void) { + if (mi_unlikely(_mi_numa_node_count <= 0)) { + long ncount = mi_option_get(mi_option_use_numa_nodes); // given explicitly? + if (ncount <= 0) ncount = (long)mi_os_numa_node_countx(); // or detect dynamically + _mi_numa_node_count = (size_t)(ncount <= 0 ? 1 : ncount); + _mi_verbose_message("using %zd numa regions\n", _mi_numa_node_count); + } + mi_assert_internal(_mi_numa_node_count >= 1); + return _mi_numa_node_count; +} + +int _mi_os_numa_node_get(mi_os_tld_t* tld) { + UNUSED(tld); + size_t numa_count = _mi_os_numa_node_count(); + if (numa_count<=1) return 0; // optimize on single numa node systems: always node 0 + // never more than the node count and >= 0 + size_t numa_node = mi_os_numa_nodex(); + if (numa_node >= numa_count) { numa_node = numa_node % numa_count; } + return (int)numa_node; +} diff --git a/extlib/mimalloc/src/page-queue.c b/extlib/mimalloc/src/page-queue.c new file mode 100644 index 0000000..ea21301 --- /dev/null +++ b/extlib/mimalloc/src/page-queue.c @@ -0,0 +1,368 @@ +/*---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ----------------------------------------------------------- + Definition of page queues for each block size +----------------------------------------------------------- */ + +#ifndef MI_IN_PAGE_C +#error "this file should be included from 'page.c'" +#endif + +/* ----------------------------------------------------------- + Minimal alignment in machine words (i.e. `sizeof(void*)`) +----------------------------------------------------------- */ + +#if (MI_MAX_ALIGN_SIZE > 4*MI_INTPTR_SIZE) + #error "define alignment for more than 4x word size for this platform" +#elif (MI_MAX_ALIGN_SIZE > 2*MI_INTPTR_SIZE) + #define MI_ALIGN4W // 4 machine words minimal alignment +#elif (MI_MAX_ALIGN_SIZE > MI_INTPTR_SIZE) + #define MI_ALIGN2W // 2 machine words minimal alignment +#else + // ok, default alignment is 1 word +#endif + + +/* ----------------------------------------------------------- + Queue query +----------------------------------------------------------- */ + + +static inline bool mi_page_queue_is_huge(const mi_page_queue_t* pq) { + return (pq->block_size == (MI_LARGE_OBJ_SIZE_MAX+sizeof(uintptr_t))); +} + +static inline bool mi_page_queue_is_full(const mi_page_queue_t* pq) { + return (pq->block_size == (MI_LARGE_OBJ_SIZE_MAX+(2*sizeof(uintptr_t)))); +} + +static inline bool mi_page_queue_is_special(const mi_page_queue_t* pq) { + return (pq->block_size > MI_LARGE_OBJ_SIZE_MAX); +} + +/* ----------------------------------------------------------- + Bins +----------------------------------------------------------- */ + +// Bit scan reverse: return the index of the highest bit. +static inline uint8_t mi_bsr32(uint32_t x); + +#if defined(_MSC_VER) +#include +static inline uint8_t mi_bsr32(uint32_t x) { + uint32_t idx; + _BitScanReverse((DWORD*)&idx, x); + return (uint8_t)idx; +} +#elif defined(__GNUC__) || defined(__clang__) +static inline uint8_t mi_bsr32(uint32_t x) { + return (31 - __builtin_clz(x)); +} +#else +static inline uint8_t mi_bsr32(uint32_t x) { + // de Bruijn multiplication, see + static const uint8_t debruijn[32] = { + 31, 0, 22, 1, 28, 23, 18, 2, 29, 26, 24, 10, 19, 7, 3, 12, + 30, 21, 27, 17, 25, 9, 6, 11, 20, 16, 8, 5, 15, 4, 14, 13, + }; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x++; + return debruijn[(x*0x076be629) >> 27]; +} +#endif + +// Bit scan reverse: return the index of the highest bit. +uint8_t _mi_bsr(uintptr_t x) { + if (x == 0) return 0; +#if MI_INTPTR_SIZE==8 + uint32_t hi = (x >> 32); + return (hi == 0 ? mi_bsr32((uint32_t)x) : 32 + mi_bsr32(hi)); +#elif MI_INTPTR_SIZE==4 + return mi_bsr32(x); +#else +# error "define bsr for non-32 or 64-bit platforms" +#endif +} + +// Return the bin for a given field size. +// Returns MI_BIN_HUGE if the size is too large. +// We use `wsize` for the size in "machine word sizes", +// i.e. byte size == `wsize*sizeof(void*)`. +extern inline uint8_t _mi_bin(size_t size) { + size_t wsize = _mi_wsize_from_size(size); + uint8_t bin; + if (wsize <= 1) { + bin = 1; + } + #if defined(MI_ALIGN4W) + else if (wsize <= 4) { + bin = (uint8_t)((wsize+1)&~1); // round to double word sizes + } + #elif defined(MI_ALIGN2W) + else if (wsize <= 8) { + bin = (uint8_t)((wsize+1)&~1); // round to double word sizes + } + #else + else if (wsize <= 8) { + bin = (uint8_t)wsize; + } + #endif + else if (wsize > MI_LARGE_OBJ_WSIZE_MAX) { + bin = MI_BIN_HUGE; + } + else { + #if defined(MI_ALIGN4W) + if (wsize <= 16) { wsize = (wsize+3)&~3; } // round to 4x word sizes + #endif + wsize--; + // find the highest bit + uint8_t b = mi_bsr32((uint32_t)wsize); + // and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation). + // - adjust with 3 because we use do not round the first 8 sizes + // which each get an exact bin + bin = ((b << 2) + (uint8_t)((wsize >> (b - 2)) & 0x03)) - 3; + mi_assert_internal(bin < MI_BIN_HUGE); + } + mi_assert_internal(bin > 0 && bin <= MI_BIN_HUGE); + return bin; +} + + + +/* ----------------------------------------------------------- + Queue of pages with free blocks +----------------------------------------------------------- */ + +size_t _mi_bin_size(uint8_t bin) { + return _mi_heap_empty.pages[bin].block_size; +} + +// Good size for allocation +size_t mi_good_size(size_t size) mi_attr_noexcept { + if (size <= MI_LARGE_OBJ_SIZE_MAX) { + return _mi_bin_size(_mi_bin(size)); + } + else { + return _mi_align_up(size,_mi_os_page_size()); + } +} + +#if (MI_DEBUG>1) +static bool mi_page_queue_contains(mi_page_queue_t* queue, const mi_page_t* page) { + mi_assert_internal(page != NULL); + mi_page_t* list = queue->first; + while (list != NULL) { + mi_assert_internal(list->next == NULL || list->next->prev == list); + mi_assert_internal(list->prev == NULL || list->prev->next == list); + if (list == page) break; + list = list->next; + } + return (list == page); +} + +#endif + +#if (MI_DEBUG>1) +static bool mi_heap_contains_queue(const mi_heap_t* heap, const mi_page_queue_t* pq) { + return (pq >= &heap->pages[0] && pq <= &heap->pages[MI_BIN_FULL]); +} +#endif + +static mi_page_queue_t* mi_page_queue_of(const mi_page_t* page) { + uint8_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : _mi_bin(page->xblock_size)); + mi_heap_t* heap = mi_page_heap(page); + mi_assert_internal(heap != NULL && bin <= MI_BIN_FULL); + mi_page_queue_t* pq = &heap->pages[bin]; + mi_assert_internal(bin >= MI_BIN_HUGE || page->xblock_size == pq->block_size); + mi_assert_expensive(mi_page_queue_contains(pq, page)); + return pq; +} + +static mi_page_queue_t* mi_heap_page_queue_of(mi_heap_t* heap, const mi_page_t* page) { + uint8_t bin = (mi_page_is_in_full(page) ? MI_BIN_FULL : _mi_bin(page->xblock_size)); + mi_assert_internal(bin <= MI_BIN_FULL); + mi_page_queue_t* pq = &heap->pages[bin]; + mi_assert_internal(mi_page_is_in_full(page) || page->xblock_size == pq->block_size); + return pq; +} + +// The current small page array is for efficiency and for each +// small size (up to 256) it points directly to the page for that +// size without having to compute the bin. This means when the +// current free page queue is updated for a small bin, we need to update a +// range of entries in `_mi_page_small_free`. +static inline void mi_heap_queue_first_update(mi_heap_t* heap, const mi_page_queue_t* pq) { + mi_assert_internal(mi_heap_contains_queue(heap,pq)); + size_t size = pq->block_size; + if (size > MI_SMALL_SIZE_MAX) return; + + mi_page_t* page = pq->first; + if (pq->first == NULL) page = (mi_page_t*)&_mi_page_empty; + + // find index in the right direct page array + size_t start; + size_t idx = _mi_wsize_from_size(size); + mi_page_t** pages_free = heap->pages_free_direct; + + if (pages_free[idx] == page) return; // already set + + // find start slot + if (idx<=1) { + start = 0; + } + else { + // find previous size; due to minimal alignment upto 3 previous bins may need to be skipped + uint8_t bin = _mi_bin(size); + const mi_page_queue_t* prev = pq - 1; + while( bin == _mi_bin(prev->block_size) && prev > &heap->pages[0]) { + prev--; + } + start = 1 + _mi_wsize_from_size(prev->block_size); + if (start > idx) start = idx; + } + + // set size range to the right page + mi_assert(start <= idx); + for (size_t sz = start; sz <= idx; sz++) { + pages_free[sz] = page; + } +} + +/* +static bool mi_page_queue_is_empty(mi_page_queue_t* queue) { + return (queue->first == NULL); +} +*/ + +static void mi_page_queue_remove(mi_page_queue_t* queue, mi_page_t* page) { + mi_assert_internal(page != NULL); + mi_assert_expensive(mi_page_queue_contains(queue, page)); + mi_assert_internal(page->xblock_size == queue->block_size || (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_huge(queue)) || (mi_page_is_in_full(page) && mi_page_queue_is_full(queue))); + mi_heap_t* heap = mi_page_heap(page); + if (page->prev != NULL) page->prev->next = page->next; + if (page->next != NULL) page->next->prev = page->prev; + if (page == queue->last) queue->last = page->prev; + if (page == queue->first) { + queue->first = page->next; + // update first + mi_assert_internal(mi_heap_contains_queue(heap, queue)); + mi_heap_queue_first_update(heap,queue); + } + heap->page_count--; + page->next = NULL; + page->prev = NULL; + // mi_atomic_write_ptr(mi_atomic_cast(void*, &page->heap), NULL); + mi_page_set_in_full(page,false); +} + + +static void mi_page_queue_push(mi_heap_t* heap, mi_page_queue_t* queue, mi_page_t* page) { + mi_assert_internal(mi_page_heap(page) == heap); + mi_assert_internal(!mi_page_queue_contains(queue, page)); + mi_assert_internal(_mi_page_segment(page)->page_kind != MI_PAGE_HUGE); + mi_assert_internal(page->xblock_size == queue->block_size || + (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_huge(queue)) || + (mi_page_is_in_full(page) && mi_page_queue_is_full(queue))); + + mi_page_set_in_full(page, mi_page_queue_is_full(queue)); + // mi_atomic_write_ptr(mi_atomic_cast(void*, &page->heap), heap); + page->next = queue->first; + page->prev = NULL; + if (queue->first != NULL) { + mi_assert_internal(queue->first->prev == NULL); + queue->first->prev = page; + queue->first = page; + } + else { + queue->first = queue->last = page; + } + + // update direct + mi_heap_queue_first_update(heap, queue); + heap->page_count++; +} + + +static void mi_page_queue_enqueue_from(mi_page_queue_t* to, mi_page_queue_t* from, mi_page_t* page) { + mi_assert_internal(page != NULL); + mi_assert_expensive(mi_page_queue_contains(from, page)); + mi_assert_expensive(!mi_page_queue_contains(to, page)); + mi_assert_internal((page->xblock_size == to->block_size && page->xblock_size == from->block_size) || + (page->xblock_size == to->block_size && mi_page_queue_is_full(from)) || + (page->xblock_size == from->block_size && mi_page_queue_is_full(to)) || + (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_huge(to)) || + (page->xblock_size > MI_LARGE_OBJ_SIZE_MAX && mi_page_queue_is_full(to))); + + mi_heap_t* heap = mi_page_heap(page); + if (page->prev != NULL) page->prev->next = page->next; + if (page->next != NULL) page->next->prev = page->prev; + if (page == from->last) from->last = page->prev; + if (page == from->first) { + from->first = page->next; + // update first + mi_assert_internal(mi_heap_contains_queue(heap, from)); + mi_heap_queue_first_update(heap, from); + } + + page->prev = to->last; + page->next = NULL; + if (to->last != NULL) { + mi_assert_internal(heap == mi_page_heap(to->last)); + to->last->next = page; + to->last = page; + } + else { + to->first = page; + to->last = page; + mi_heap_queue_first_update(heap, to); + } + + mi_page_set_in_full(page, mi_page_queue_is_full(to)); +} + +// Only called from `mi_heap_absorb`. +size_t _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append) { + mi_assert_internal(mi_heap_contains_queue(heap,pq)); + mi_assert_internal(pq->block_size == append->block_size); + + if (append->first==NULL) return 0; + + // set append pages to new heap and count + size_t count = 0; + for (mi_page_t* page = append->first; page != NULL; page = page->next) { + // inline `mi_page_set_heap` to avoid wrong assertion during absorption; + // in this case it is ok to be delayed freeing since both "to" and "from" heap are still alive. + mi_atomic_write(&page->xheap, (uintptr_t)heap); + // set the flag to delayed free (not overriding NEVER_DELAYED_FREE) which has as a + // side effect that it spins until any DELAYED_FREEING is finished. This ensures + // that after appending only the new heap will be used for delayed free operations. + _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, false); + count++; + } + + if (pq->last==NULL) { + // take over afresh + mi_assert_internal(pq->first==NULL); + pq->first = append->first; + pq->last = append->last; + mi_heap_queue_first_update(heap, pq); + } + else { + // append to end + mi_assert_internal(pq->last!=NULL); + mi_assert_internal(append->first!=NULL); + pq->last->next = append->first; + append->first->prev = pq->last; + pq->last = append->last; + } + return count; +} diff --git a/extlib/mimalloc/src/page.c b/extlib/mimalloc/src/page.c new file mode 100644 index 0000000..c8a4e54 --- /dev/null +++ b/extlib/mimalloc/src/page.c @@ -0,0 +1,847 @@ +/*---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ----------------------------------------------------------- + The core of the allocator. Every segment contains + pages of a {certain block size. The main function + exported is `mi_malloc_generic`. +----------------------------------------------------------- */ + +#include "mimalloc.h" +#include "mimalloc-internal.h" +#include "mimalloc-atomic.h" + +/* ----------------------------------------------------------- + Definition of page queues for each block size +----------------------------------------------------------- */ + +#define MI_IN_PAGE_C +#include "page-queue.c" +#undef MI_IN_PAGE_C + + +/* ----------------------------------------------------------- + Page helpers +----------------------------------------------------------- */ + +// Index a block in a page +static inline mi_block_t* mi_page_block_at(const mi_page_t* page, void* page_start, size_t block_size, size_t i) { + UNUSED(page); + mi_assert_internal(page != NULL); + mi_assert_internal(i <= page->reserved); + return (mi_block_t*)((uint8_t*)page_start + (i * block_size)); +} + +static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t size, mi_tld_t* tld); +static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld); + +#if (MI_DEBUG>=3) +static size_t mi_page_list_count(mi_page_t* page, mi_block_t* head) { + size_t count = 0; + while (head != NULL) { + mi_assert_internal(page == _mi_ptr_page(head)); + count++; + head = mi_block_next(page, head); + } + return count; +} + +/* +// Start of the page available memory +static inline uint8_t* mi_page_area(const mi_page_t* page) { + return _mi_page_start(_mi_page_segment(page), page, NULL); +} +*/ + +static bool mi_page_list_is_valid(mi_page_t* page, mi_block_t* p) { + size_t psize; + uint8_t* page_area = _mi_page_start(_mi_page_segment(page), page, &psize); + mi_block_t* start = (mi_block_t*)page_area; + mi_block_t* end = (mi_block_t*)(page_area + psize); + while(p != NULL) { + if (p < start || p >= end) return false; + p = mi_block_next(page, p); + } + return true; +} + +static bool mi_page_is_valid_init(mi_page_t* page) { + mi_assert_internal(page->xblock_size > 0); + mi_assert_internal(page->used <= page->capacity); + mi_assert_internal(page->capacity <= page->reserved); + + const size_t bsize = mi_page_block_size(page); + mi_segment_t* segment = _mi_page_segment(page); + uint8_t* start = _mi_page_start(segment,page,NULL); + mi_assert_internal(start == _mi_segment_page_start(segment,page,bsize,NULL,NULL)); + //mi_assert_internal(start + page->capacity*page->block_size == page->top); + + mi_assert_internal(mi_page_list_is_valid(page,page->free)); + mi_assert_internal(mi_page_list_is_valid(page,page->local_free)); + + #if MI_DEBUG>3 // generally too expensive to check this + if (page->flags.is_zero) { + for(mi_block_t* block = page->free; block != NULL; mi_block_next(page,block)) { + mi_assert_expensive(mi_mem_is_zero(block + 1, page->block_size - sizeof(mi_block_t))); + } + } + #endif + + mi_block_t* tfree = mi_page_thread_free(page); + mi_assert_internal(mi_page_list_is_valid(page, tfree)); + //size_t tfree_count = mi_page_list_count(page, tfree); + //mi_assert_internal(tfree_count <= page->thread_freed + 1); + + size_t free_count = mi_page_list_count(page, page->free) + mi_page_list_count(page, page->local_free); + mi_assert_internal(page->used + free_count == page->capacity); + + return true; +} + +bool _mi_page_is_valid(mi_page_t* page) { + mi_assert_internal(mi_page_is_valid_init(page)); + #if MI_SECURE + mi_assert_internal(page->keys[0] != 0); + #endif + if (mi_page_heap(page)!=NULL) { + mi_segment_t* segment = _mi_page_segment(page); + mi_assert_internal(!_mi_process_is_initialized || segment->thread_id == mi_page_heap(page)->thread_id || segment->thread_id==0); + if (segment->page_kind != MI_PAGE_HUGE) { + mi_page_queue_t* pq = mi_page_queue_of(page); + mi_assert_internal(mi_page_queue_contains(pq, page)); + mi_assert_internal(pq->block_size==mi_page_block_size(page) || mi_page_block_size(page) > MI_LARGE_OBJ_SIZE_MAX || mi_page_is_in_full(page)); + mi_assert_internal(mi_heap_contains_queue(mi_page_heap(page),pq)); + } + } + return true; +} +#endif + +void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never) { + mi_thread_free_t tfree; + mi_thread_free_t tfreex; + mi_delayed_t old_delay; + do { + tfree = mi_atomic_read(&page->xthread_free); // note: must acquire as we can break this loop and not do a CAS + tfreex = mi_tf_set_delayed(tfree, delay); + old_delay = mi_tf_delayed(tfree); + if (mi_unlikely(old_delay == MI_DELAYED_FREEING)) { + mi_atomic_yield(); // delay until outstanding MI_DELAYED_FREEING are done. + // tfree = mi_tf_set_delayed(tfree, MI_NO_DELAYED_FREE); // will cause CAS to busy fail + } + else if (delay == old_delay) { + break; // avoid atomic operation if already equal + } + else if (!override_never && old_delay == MI_NEVER_DELAYED_FREE) { + break; // leave never-delayed flag set + } + } while ((old_delay == MI_DELAYED_FREEING) || + !mi_atomic_cas_weak(&page->xthread_free, tfreex, tfree)); +} + +/* ----------------------------------------------------------- + Page collect the `local_free` and `thread_free` lists +----------------------------------------------------------- */ + +// Collect the local `thread_free` list using an atomic exchange. +// Note: The exchange must be done atomically as this is used right after +// moving to the full list in `mi_page_collect_ex` and we need to +// ensure that there was no race where the page became unfull just before the move. +static void _mi_page_thread_free_collect(mi_page_t* page) +{ + mi_block_t* head; + mi_thread_free_t tfree; + mi_thread_free_t tfreex; + do { + tfree = mi_atomic_read_relaxed(&page->xthread_free); + head = mi_tf_block(tfree); + tfreex = mi_tf_set_block(tfree,NULL); + } while (!mi_atomic_cas_weak(&page->xthread_free, tfreex, tfree)); + + // return if the list is empty + if (head == NULL) return; + + // find the tail -- also to get a proper count (without data races) + uint32_t max_count = page->capacity; // cannot collect more than capacity + uint32_t count = 1; + mi_block_t* tail = head; + mi_block_t* next; + while ((next = mi_block_next(page,tail)) != NULL && count <= max_count) { + count++; + tail = next; + } + // if `count > max_count` there was a memory corruption (possibly infinite list due to double multi-threaded free) + if (count > max_count) { + _mi_error_message(EFAULT, "corrupted thread-free list\n"); + return; // the thread-free items cannot be freed + } + + // and append the current local free list + mi_block_set_next(page,tail, page->local_free); + page->local_free = head; + + // update counts now + page->used -= count; +} + +void _mi_page_free_collect(mi_page_t* page, bool force) { + mi_assert_internal(page!=NULL); + + // collect the thread free list + if (force || mi_page_thread_free(page) != NULL) { // quick test to avoid an atomic operation + _mi_page_thread_free_collect(page); + } + + // and the local free list + if (page->local_free != NULL) { + if (mi_likely(page->free == NULL)) { + // usual case + page->free = page->local_free; + page->local_free = NULL; + page->is_zero = false; + } + else if (force) { + // append -- only on shutdown (force) as this is a linear operation + mi_block_t* tail = page->local_free; + mi_block_t* next; + while ((next = mi_block_next(page, tail)) != NULL) { + tail = next; + } + mi_block_set_next(page, tail, page->free); + page->free = page->local_free; + page->local_free = NULL; + page->is_zero = false; + } + } + + mi_assert_internal(!force || page->local_free == NULL); +} + + + +/* ----------------------------------------------------------- + Page fresh and retire +----------------------------------------------------------- */ + +// called from segments when reclaiming abandoned pages +void _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page) { + mi_assert_expensive(mi_page_is_valid_init(page)); + mi_assert_internal(mi_page_heap(page) == heap); + mi_assert_internal(mi_page_thread_free_flag(page) != MI_NEVER_DELAYED_FREE); + mi_assert_internal(_mi_page_segment(page)->page_kind != MI_PAGE_HUGE); + mi_assert_internal(!page->is_reset); + // TODO: push on full queue immediately if it is full? + mi_page_queue_t* pq = mi_page_queue(heap, mi_page_block_size(page)); + mi_page_queue_push(heap, pq, page); + mi_assert_expensive(_mi_page_is_valid(page)); +} + +// allocate a fresh page from a segment +static mi_page_t* mi_page_fresh_alloc(mi_heap_t* heap, mi_page_queue_t* pq, size_t block_size) { + mi_assert_internal(pq==NULL||mi_heap_contains_queue(heap, pq)); + mi_assert_internal(pq==NULL||block_size == pq->block_size); + mi_page_t* page = _mi_segment_page_alloc(heap, block_size, &heap->tld->segments, &heap->tld->os); + if (page == NULL) { + // this may be out-of-memory, or an abandoned page was reclaimed (and in our queue) + return NULL; + } + // a fresh page was found, initialize it + mi_assert_internal(pq==NULL || _mi_page_segment(page)->page_kind != MI_PAGE_HUGE); + mi_page_init(heap, page, block_size, heap->tld); + _mi_stat_increase(&heap->tld->stats.pages, 1); + if (pq!=NULL) mi_page_queue_push(heap, pq, page); // huge pages use pq==NULL + mi_assert_expensive(_mi_page_is_valid(page)); + return page; +} + +// Get a fresh page to use +static mi_page_t* mi_page_fresh(mi_heap_t* heap, mi_page_queue_t* pq) { + mi_assert_internal(mi_heap_contains_queue(heap, pq)); + mi_page_t* page = mi_page_fresh_alloc(heap, pq, pq->block_size); + if (page==NULL) return NULL; + mi_assert_internal(pq->block_size==mi_page_block_size(page)); + mi_assert_internal(pq==mi_page_queue(heap, mi_page_block_size(page))); + return page; +} + +/* ----------------------------------------------------------- + Do any delayed frees + (put there by other threads if they deallocated in a full page) +----------------------------------------------------------- */ +void _mi_heap_delayed_free(mi_heap_t* heap) { + // take over the list (note: no atomic exchange is it is often NULL) + mi_block_t* block; + do { + block = mi_atomic_read_ptr_relaxed(mi_block_t,&heap->thread_delayed_free); + } while (block != NULL && !mi_atomic_cas_ptr_weak(mi_block_t,&heap->thread_delayed_free, NULL, block)); + + // and free them all + while(block != NULL) { + mi_block_t* next = mi_block_nextx(heap,block, heap->keys); + // use internal free instead of regular one to keep stats etc correct + if (!_mi_free_delayed_block(block)) { + // we might already start delayed freeing while another thread has not yet + // reset the delayed_freeing flag; in that case delay it further by reinserting. + mi_block_t* dfree; + do { + dfree = mi_atomic_read_ptr_relaxed(mi_block_t,&heap->thread_delayed_free); + mi_block_set_nextx(heap, block, dfree, heap->keys); + } while (!mi_atomic_cas_ptr_weak(mi_block_t,&heap->thread_delayed_free, block, dfree)); + } + block = next; + } +} + +/* ----------------------------------------------------------- + Unfull, abandon, free and retire +----------------------------------------------------------- */ + +// Move a page from the full list back to a regular list +void _mi_page_unfull(mi_page_t* page) { + mi_assert_internal(page != NULL); + mi_assert_expensive(_mi_page_is_valid(page)); + mi_assert_internal(mi_page_is_in_full(page)); + if (!mi_page_is_in_full(page)) return; + + mi_heap_t* heap = mi_page_heap(page); + mi_page_queue_t* pqfull = &heap->pages[MI_BIN_FULL]; + mi_page_set_in_full(page, false); // to get the right queue + mi_page_queue_t* pq = mi_heap_page_queue_of(heap, page); + mi_page_set_in_full(page, true); + mi_page_queue_enqueue_from(pq, pqfull, page); +} + +static void mi_page_to_full(mi_page_t* page, mi_page_queue_t* pq) { + mi_assert_internal(pq == mi_page_queue_of(page)); + mi_assert_internal(!mi_page_immediate_available(page)); + mi_assert_internal(!mi_page_is_in_full(page)); + + if (mi_page_is_in_full(page)) return; + mi_page_queue_enqueue_from(&mi_page_heap(page)->pages[MI_BIN_FULL], pq, page); + _mi_page_free_collect(page,false); // try to collect right away in case another thread freed just before MI_USE_DELAYED_FREE was set +} + + +// Abandon a page with used blocks at the end of a thread. +// Note: only call if it is ensured that no references exist from +// the `page->heap->thread_delayed_free` into this page. +// Currently only called through `mi_heap_collect_ex` which ensures this. +void _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq) { + mi_assert_internal(page != NULL); + mi_assert_expensive(_mi_page_is_valid(page)); + mi_assert_internal(pq == mi_page_queue_of(page)); + mi_assert_internal(mi_page_heap(page) != NULL); + + mi_heap_t* pheap = mi_page_heap(page); + + // remove from our page list + mi_segments_tld_t* segments_tld = &pheap->tld->segments; + mi_page_queue_remove(pq, page); + + // page is no longer associated with our heap + mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE); + mi_page_set_heap(page, NULL); + +#if MI_DEBUG>1 + // check there are no references left.. + for (mi_block_t* block = (mi_block_t*)pheap->thread_delayed_free; block != NULL; block = mi_block_nextx(pheap, block, pheap->keys)) { + mi_assert_internal(_mi_ptr_page(block) != page); + } +#endif + + // and abandon it + mi_assert_internal(mi_page_heap(page) == NULL); + _mi_segment_page_abandon(page,segments_tld); +} + + +// Free a page with no more free blocks +void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force) { + mi_assert_internal(page != NULL); + mi_assert_expensive(_mi_page_is_valid(page)); + mi_assert_internal(pq == mi_page_queue_of(page)); + mi_assert_internal(mi_page_all_free(page)); + mi_assert_internal(mi_page_thread_free_flag(page)!=MI_DELAYED_FREEING); + + // no more aligned blocks in here + mi_page_set_has_aligned(page, false); + + // remove from the page list + // (no need to do _mi_heap_delayed_free first as all blocks are already free) + mi_segments_tld_t* segments_tld = &mi_page_heap(page)->tld->segments; + mi_page_queue_remove(pq, page); + + // and free it + mi_page_set_heap(page,NULL); + _mi_segment_page_free(page, force, segments_tld); +} + +#define MI_MAX_RETIRE_SIZE MI_LARGE_OBJ_SIZE_MAX +#define MI_RETIRE_CYCLES (8) + +// Retire a page with no more used blocks +// Important to not retire too quickly though as new +// allocations might coming. +// Note: called from `mi_free` and benchmarks often +// trigger this due to freeing everything and then +// allocating again so careful when changing this. +void _mi_page_retire(mi_page_t* page) { + mi_assert_internal(page != NULL); + mi_assert_expensive(_mi_page_is_valid(page)); + mi_assert_internal(mi_page_all_free(page)); + + mi_page_set_has_aligned(page, false); + + // don't retire too often.. + // (or we end up retiring and re-allocating most of the time) + // NOTE: refine this more: we should not retire if this + // is the only page left with free blocks. It is not clear + // how to check this efficiently though... + // for now, we don't retire if it is the only page left of this size class. + mi_page_queue_t* pq = mi_page_queue_of(page); + if (mi_likely(page->xblock_size <= MI_MAX_RETIRE_SIZE && !mi_page_is_in_full(page))) { + if (pq->last==page && pq->first==page) { // the only page in the queue? + mi_stat_counter_increase(_mi_stats_main.page_no_retire,1); + page->retire_expire = (page->xblock_size <= MI_SMALL_OBJ_SIZE_MAX ? MI_RETIRE_CYCLES : MI_RETIRE_CYCLES/4); + mi_heap_t* heap = mi_page_heap(page); + mi_assert_internal(pq >= heap->pages); + const size_t index = pq - heap->pages; + mi_assert_internal(index < MI_BIN_FULL && index < MI_BIN_HUGE); + if (index < heap->page_retired_min) heap->page_retired_min = index; + if (index > heap->page_retired_max) heap->page_retired_max = index; + mi_assert_internal(mi_page_all_free(page)); + return; // dont't free after all + } + } + + _mi_page_free(page, pq, false); +} + +// free retired pages: we don't need to look at the entire queues +// since we only retire pages that are at the head position in a queue. +void _mi_heap_collect_retired(mi_heap_t* heap, bool force) { + size_t min = MI_BIN_FULL; + size_t max = 0; + for(size_t bin = heap->page_retired_min; bin <= heap->page_retired_max; bin++) { + mi_page_queue_t* pq = &heap->pages[bin]; + mi_page_t* page = pq->first; + if (page != NULL && page->retire_expire != 0) { + if (mi_page_all_free(page)) { + page->retire_expire--; + if (force || page->retire_expire == 0) { + _mi_page_free(pq->first, pq, force); + } + else { + // keep retired, update min/max + if (bin < min) min = bin; + if (bin > max) max = bin; + } + } + else { + page->retire_expire = 0; + } + } + } + heap->page_retired_min = min; + heap->page_retired_max = max; +} + + +/* ----------------------------------------------------------- + Initialize the initial free list in a page. + In secure mode we initialize a randomized list by + alternating between slices. +----------------------------------------------------------- */ + +#define MI_MAX_SLICE_SHIFT (6) // at most 64 slices +#define MI_MAX_SLICES (1UL << MI_MAX_SLICE_SHIFT) +#define MI_MIN_SLICES (2) + +static void mi_page_free_list_extend_secure(mi_heap_t* const heap, mi_page_t* const page, const size_t bsize, const size_t extend, mi_stats_t* const stats) { + UNUSED(stats); + #if (MI_SECURE<=2) + mi_assert_internal(page->free == NULL); + mi_assert_internal(page->local_free == NULL); + #endif + mi_assert_internal(page->capacity + extend <= page->reserved); + mi_assert_internal(bsize == mi_page_block_size(page)); + void* const page_area = _mi_page_start(_mi_page_segment(page), page, NULL); + + // initialize a randomized free list + // set up `slice_count` slices to alternate between + size_t shift = MI_MAX_SLICE_SHIFT; + while ((extend >> shift) == 0) { + shift--; + } + const size_t slice_count = (size_t)1U << shift; + const size_t slice_extend = extend / slice_count; + mi_assert_internal(slice_extend >= 1); + mi_block_t* blocks[MI_MAX_SLICES]; // current start of the slice + size_t counts[MI_MAX_SLICES]; // available objects in the slice + for (size_t i = 0; i < slice_count; i++) { + blocks[i] = mi_page_block_at(page, page_area, bsize, page->capacity + i*slice_extend); + counts[i] = slice_extend; + } + counts[slice_count-1] += (extend % slice_count); // final slice holds the modulus too (todo: distribute evenly?) + + // and initialize the free list by randomly threading through them + // set up first element + const uintptr_t r = _mi_heap_random_next(heap); + size_t current = r % slice_count; + counts[current]--; + mi_block_t* const free_start = blocks[current]; + // and iterate through the rest; use `random_shuffle` for performance + uintptr_t rnd = _mi_random_shuffle(r|1); // ensure not 0 + for (size_t i = 1; i < extend; i++) { + // call random_shuffle only every INTPTR_SIZE rounds + const size_t round = i%MI_INTPTR_SIZE; + if (round == 0) rnd = _mi_random_shuffle(rnd); + // select a random next slice index + size_t next = ((rnd >> 8*round) & (slice_count-1)); + while (counts[next]==0) { // ensure it still has space + next++; + if (next==slice_count) next = 0; + } + // and link the current block to it + counts[next]--; + mi_block_t* const block = blocks[current]; + blocks[current] = (mi_block_t*)((uint8_t*)block + bsize); // bump to the following block + mi_block_set_next(page, block, blocks[next]); // and set next; note: we may have `current == next` + current = next; + } + // prepend to the free list (usually NULL) + mi_block_set_next(page, blocks[current], page->free); // end of the list + page->free = free_start; +} + +static mi_decl_noinline void mi_page_free_list_extend( mi_page_t* const page, const size_t bsize, const size_t extend, mi_stats_t* const stats) +{ + UNUSED(stats); + #if (MI_SECURE <= 2) + mi_assert_internal(page->free == NULL); + mi_assert_internal(page->local_free == NULL); + #endif + mi_assert_internal(page->capacity + extend <= page->reserved); + mi_assert_internal(bsize == mi_page_block_size(page)); + void* const page_area = _mi_page_start(_mi_page_segment(page), page, NULL ); + + mi_block_t* const start = mi_page_block_at(page, page_area, bsize, page->capacity); + + // initialize a sequential free list + mi_block_t* const last = mi_page_block_at(page, page_area, bsize, page->capacity + extend - 1); + mi_block_t* block = start; + while(block <= last) { + mi_block_t* next = (mi_block_t*)((uint8_t*)block + bsize); + mi_block_set_next(page,block,next); + block = next; + } + // prepend to free list (usually `NULL`) + mi_block_set_next(page, last, page->free); + page->free = start; +} + +/* ----------------------------------------------------------- + Page initialize and extend the capacity +----------------------------------------------------------- */ + +#define MI_MAX_EXTEND_SIZE (4*1024) // heuristic, one OS page seems to work well. +#if (MI_SECURE>0) +#define MI_MIN_EXTEND (8*MI_SECURE) // extend at least by this many +#else +#define MI_MIN_EXTEND (1) +#endif + +// Extend the capacity (up to reserved) by initializing a free list +// We do at most `MI_MAX_EXTEND` to avoid touching too much memory +// Note: we also experimented with "bump" allocation on the first +// allocations but this did not speed up any benchmark (due to an +// extra test in malloc? or cache effects?) +static void mi_page_extend_free(mi_heap_t* heap, mi_page_t* page, mi_tld_t* tld) { + mi_assert_expensive(mi_page_is_valid_init(page)); + #if (MI_SECURE<=2) + mi_assert(page->free == NULL); + mi_assert(page->local_free == NULL); + if (page->free != NULL) return; + #endif + if (page->capacity >= page->reserved) return; + + size_t page_size; + //uint8_t* page_start = + _mi_page_start(_mi_page_segment(page), page, &page_size); + mi_stat_counter_increase(tld->stats.pages_extended, 1); + + // calculate the extend count + const size_t bsize = (page->xblock_size < MI_HUGE_BLOCK_SIZE ? page->xblock_size : page_size); + size_t extend = page->reserved - page->capacity; + size_t max_extend = (bsize >= MI_MAX_EXTEND_SIZE ? MI_MIN_EXTEND : MI_MAX_EXTEND_SIZE/(uint32_t)bsize); + if (max_extend < MI_MIN_EXTEND) max_extend = MI_MIN_EXTEND; + + if (extend > max_extend) { + // ensure we don't touch memory beyond the page to reduce page commit. + // the `lean` benchmark tests this. Going from 1 to 8 increases rss by 50%. + extend = (max_extend==0 ? 1 : max_extend); + } + + mi_assert_internal(extend > 0 && extend + page->capacity <= page->reserved); + mi_assert_internal(extend < (1UL<<16)); + + // and append the extend the free list + if (extend < MI_MIN_SLICES || MI_SECURE==0) { //!mi_option_is_enabled(mi_option_secure)) { + mi_page_free_list_extend(page, bsize, extend, &tld->stats ); + } + else { + mi_page_free_list_extend_secure(heap, page, bsize, extend, &tld->stats); + } + // enable the new free list + page->capacity += (uint16_t)extend; + mi_stat_increase(tld->stats.page_committed, extend * bsize); + + // extension into zero initialized memory preserves the zero'd free list + if (!page->is_zero_init) { + page->is_zero = false; + } + mi_assert_expensive(mi_page_is_valid_init(page)); +} + +// Initialize a fresh page +static void mi_page_init(mi_heap_t* heap, mi_page_t* page, size_t block_size, mi_tld_t* tld) { + mi_assert(page != NULL); + mi_segment_t* segment = _mi_page_segment(page); + mi_assert(segment != NULL); + mi_assert_internal(block_size > 0); + // set fields + mi_page_set_heap(page, heap); + size_t page_size; + _mi_segment_page_start(segment, page, block_size, &page_size, NULL); + page->xblock_size = (block_size < MI_HUGE_BLOCK_SIZE ? (uint32_t)block_size : MI_HUGE_BLOCK_SIZE); + mi_assert_internal(page_size / block_size < (1L<<16)); + page->reserved = (uint16_t)(page_size / block_size); + #ifdef MI_ENCODE_FREELIST + page->keys[0] = _mi_heap_random_next(heap); + page->keys[1] = _mi_heap_random_next(heap); + #endif + page->is_zero = page->is_zero_init; + + mi_assert_internal(page->capacity == 0); + mi_assert_internal(page->free == NULL); + mi_assert_internal(page->used == 0); + mi_assert_internal(page->xthread_free == 0); + mi_assert_internal(page->next == NULL); + mi_assert_internal(page->prev == NULL); + mi_assert_internal(page->retire_expire == 0); + mi_assert_internal(!mi_page_has_aligned(page)); + #if (MI_ENCODE_FREELIST) + mi_assert_internal(page->keys[0] != 0); + mi_assert_internal(page->keys[1] != 0); + #endif + mi_assert_expensive(mi_page_is_valid_init(page)); + + // initialize an initial free list + mi_page_extend_free(heap,page,tld); + mi_assert(mi_page_immediate_available(page)); +} + + +/* ----------------------------------------------------------- + Find pages with free blocks +-------------------------------------------------------------*/ + +// Find a page with free blocks of `page->block_size`. +static mi_page_t* mi_page_queue_find_free_ex(mi_heap_t* heap, mi_page_queue_t* pq, bool first_try) +{ + // search through the pages in "next fit" order + size_t count = 0; + mi_page_t* page = pq->first; + while (page != NULL) + { + mi_page_t* next = page->next; // remember next + count++; + + // 0. collect freed blocks by us and other threads + _mi_page_free_collect(page, false); + + // 1. if the page contains free blocks, we are done + if (mi_page_immediate_available(page)) { + break; // pick this one + } + + // 2. Try to extend + if (page->capacity < page->reserved) { + mi_page_extend_free(heap, page, heap->tld); + mi_assert_internal(mi_page_immediate_available(page)); + break; + } + + // 3. If the page is completely full, move it to the `mi_pages_full` + // queue so we don't visit long-lived pages too often. + mi_assert_internal(!mi_page_is_in_full(page) && !mi_page_immediate_available(page)); + mi_page_to_full(page, pq); + + page = next; + } // for each page + + mi_stat_counter_increase(heap->tld->stats.searches, count); + + if (page == NULL) { + _mi_heap_collect_retired(heap, false); // perhaps make a page available + page = mi_page_fresh(heap, pq); + if (page == NULL && first_try) { + // out-of-memory _or_ an abandoned page with free blocks was reclaimed, try once again + page = mi_page_queue_find_free_ex(heap, pq, false); + } + } + else { + mi_assert(pq->first == page); + page->retire_expire = 0; + } + mi_assert_internal(page == NULL || mi_page_immediate_available(page)); + return page; +} + + + +// Find a page with free blocks of `size`. +static inline mi_page_t* mi_find_free_page(mi_heap_t* heap, size_t size) { + mi_page_queue_t* pq = mi_page_queue(heap,size); + mi_page_t* page = pq->first; + if (page != NULL) { + if ((MI_SECURE >= 3) && page->capacity < page->reserved && ((_mi_heap_random_next(heap) & 1) == 1)) { + // in secure mode, we extend half the time to increase randomness + mi_page_extend_free(heap, page, heap->tld); + mi_assert_internal(mi_page_immediate_available(page)); + } + else { + _mi_page_free_collect(page,false); + } + if (mi_page_immediate_available(page)) { + page->retire_expire = 0; + return page; // fast path + } + } + return mi_page_queue_find_free_ex(heap, pq, true); +} + + +/* ----------------------------------------------------------- + Users can register a deferred free function called + when the `free` list is empty. Since the `local_free` + is separate this is deterministically called after + a certain number of allocations. +----------------------------------------------------------- */ + +static mi_deferred_free_fun* volatile deferred_free = NULL; +static volatile _Atomic(void*) deferred_arg; // = NULL + +void _mi_deferred_free(mi_heap_t* heap, bool force) { + heap->tld->heartbeat++; + if (deferred_free != NULL && !heap->tld->recurse) { + heap->tld->recurse = true; + deferred_free(force, heap->tld->heartbeat, mi_atomic_read_ptr_relaxed(void,&deferred_arg)); + heap->tld->recurse = false; + } +} + +void mi_register_deferred_free(mi_deferred_free_fun* fn, void* arg) mi_attr_noexcept { + deferred_free = fn; + mi_atomic_write_ptr(void,&deferred_arg, arg); +} + + +/* ----------------------------------------------------------- + General allocation +----------------------------------------------------------- */ + +// A huge page is allocated directly without being in a queue. +// Because huge pages contain just one block, and the segment contains +// just that page, we always treat them as abandoned and any thread +// that frees the block can free the whole page and segment directly. +static mi_page_t* mi_huge_page_alloc(mi_heap_t* heap, size_t size) { + size_t block_size = _mi_os_good_alloc_size(size); + mi_assert_internal(_mi_bin(block_size) == MI_BIN_HUGE); + mi_page_t* page = mi_page_fresh_alloc(heap,NULL,block_size); + if (page != NULL) { + const size_t bsize = mi_page_block_size(page); // note: not `mi_page_usable_block_size` as `size` includes padding already + mi_assert_internal(bsize >= size); + mi_assert_internal(mi_page_immediate_available(page)); + mi_assert_internal(_mi_page_segment(page)->page_kind==MI_PAGE_HUGE); + mi_assert_internal(_mi_page_segment(page)->used==1); + mi_assert_internal(_mi_page_segment(page)->thread_id==0); // abandoned, not in the huge queue + mi_page_set_heap(page, NULL); + + if (bsize > MI_HUGE_OBJ_SIZE_MAX) { + _mi_stat_increase(&heap->tld->stats.giant, bsize); + _mi_stat_counter_increase(&heap->tld->stats.giant_count, 1); + } + else { + _mi_stat_increase(&heap->tld->stats.huge, bsize); + _mi_stat_counter_increase(&heap->tld->stats.huge_count, 1); + } + } + return page; +} + + +// Allocate a page +// Note: in debug mode the size includes MI_PADDING_SIZE and might have overflowed. +static mi_page_t* mi_find_page(mi_heap_t* heap, size_t size) mi_attr_noexcept { + // huge allocation? + const size_t req_size = size - MI_PADDING_SIZE; // correct for padding_size in case of an overflow on `size` + if (mi_unlikely(req_size > (MI_LARGE_OBJ_SIZE_MAX - MI_PADDING_SIZE) )) { + if (mi_unlikely(req_size > PTRDIFF_MAX)) { // we don't allocate more than PTRDIFF_MAX (see ) + _mi_error_message(EOVERFLOW, "allocation request is too large (%zu bytes)\n", req_size); + return NULL; + } + else { + return mi_huge_page_alloc(heap,size); + } + } + else { + // otherwise find a page with free blocks in our size segregated queues + mi_assert_internal(size >= MI_PADDING_SIZE); + return mi_find_free_page(heap, size); + } +} + +// Generic allocation routine if the fast path (`alloc.c:mi_page_malloc`) does not succeed. +// Note: in debug mode the size includes MI_PADDING_SIZE and might have overflowed. +void* _mi_malloc_generic(mi_heap_t* heap, size_t size) mi_attr_noexcept +{ + mi_assert_internal(heap != NULL); + + // initialize if necessary + if (mi_unlikely(!mi_heap_is_initialized(heap))) { + mi_thread_init(); // calls `_mi_heap_init` in turn + heap = mi_get_default_heap(); + if (mi_unlikely(!mi_heap_is_initialized(heap))) { return NULL; } + } + mi_assert_internal(mi_heap_is_initialized(heap)); + + // call potential deferred free routines + _mi_deferred_free(heap, false); + + // free delayed frees from other threads + _mi_heap_delayed_free(heap); + + // find (or allocate) a page of the right size + mi_page_t* page = mi_find_page(heap, size); + if (mi_unlikely(page == NULL)) { // first time out of memory, try to collect and retry the allocation once more + mi_heap_collect(heap, true /* force */); + page = mi_find_page(heap, size); + } + + if (mi_unlikely(page == NULL)) { // out of memory + const size_t req_size = size - MI_PADDING_SIZE; // correct for padding_size in case of an overflow on `size` + _mi_error_message(ENOMEM, "unable to allocate memory (%zu bytes)\n", req_size); + return NULL; + } + + mi_assert_internal(mi_page_immediate_available(page)); + mi_assert_internal(mi_page_block_size(page) >= size); + + // and try again, this time succeeding! (i.e. this should never recurse) + return _mi_page_malloc(heap, page, size); +} diff --git a/extlib/mimalloc/src/random.c b/extlib/mimalloc/src/random.c new file mode 100644 index 0000000..2a96ccf --- /dev/null +++ b/extlib/mimalloc/src/random.c @@ -0,0 +1,328 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2019, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc-internal.h" + +#include // memset + +/* ---------------------------------------------------------------------------- +We use our own PRNG to keep predictable performance of random number generation +and to avoid implementations that use a lock. We only use the OS provided +random source to initialize the initial seeds. Since we do not need ultimate +performance but we do rely on the security (for secret cookies in secure mode) +we use a cryptographically secure generator (chacha20). +-----------------------------------------------------------------------------*/ + +#define MI_CHACHA_ROUNDS (20) // perhaps use 12 for better performance? + + +/* ---------------------------------------------------------------------------- +Chacha20 implementation as the original algorithm with a 64-bit nonce +and counter: https://en.wikipedia.org/wiki/Salsa20 +The input matrix has sixteen 32-bit values: +Position 0 to 3: constant key +Position 4 to 11: the key +Position 12 to 13: the counter. +Position 14 to 15: the nonce. + +The implementation uses regular C code which compiles very well on modern compilers. +(gcc x64 has no register spills, and clang 6+ uses SSE instructions) +-----------------------------------------------------------------------------*/ + +static inline uint32_t rotl(uint32_t x, uint32_t shift) { + return (x << shift) | (x >> (32 - shift)); +} + +static inline void qround(uint32_t x[16], size_t a, size_t b, size_t c, size_t d) { + x[a] += x[b]; x[d] = rotl(x[d] ^ x[a], 16); + x[c] += x[d]; x[b] = rotl(x[b] ^ x[c], 12); + x[a] += x[b]; x[d] = rotl(x[d] ^ x[a], 8); + x[c] += x[d]; x[b] = rotl(x[b] ^ x[c], 7); +} + +static void chacha_block(mi_random_ctx_t* ctx) +{ + // scramble into `x` + uint32_t x[16]; + for (size_t i = 0; i < 16; i++) { + x[i] = ctx->input[i]; + } + for (size_t i = 0; i < MI_CHACHA_ROUNDS; i += 2) { + qround(x, 0, 4, 8, 12); + qround(x, 1, 5, 9, 13); + qround(x, 2, 6, 10, 14); + qround(x, 3, 7, 11, 15); + qround(x, 0, 5, 10, 15); + qround(x, 1, 6, 11, 12); + qround(x, 2, 7, 8, 13); + qround(x, 3, 4, 9, 14); + } + + // add scrambled data to the initial state + for (size_t i = 0; i < 16; i++) { + ctx->output[i] = x[i] + ctx->input[i]; + } + ctx->output_available = 16; + + // increment the counter for the next round + ctx->input[12] += 1; + if (ctx->input[12] == 0) { + ctx->input[13] += 1; + if (ctx->input[13] == 0) { // and keep increasing into the nonce + ctx->input[14] += 1; + } + } +} + +static uint32_t chacha_next32(mi_random_ctx_t* ctx) { + if (ctx->output_available <= 0) { + chacha_block(ctx); + ctx->output_available = 16; // (assign again to suppress static analysis warning) + } + const uint32_t x = ctx->output[16 - ctx->output_available]; + ctx->output[16 - ctx->output_available] = 0; // reset once the data is handed out + ctx->output_available--; + return x; +} + +static inline uint32_t read32(const uint8_t* p, size_t idx32) { + const size_t i = 4*idx32; + return ((uint32_t)p[i+0] | (uint32_t)p[i+1] << 8 | (uint32_t)p[i+2] << 16 | (uint32_t)p[i+3] << 24); +} + +static void chacha_init(mi_random_ctx_t* ctx, const uint8_t key[32], uint64_t nonce) +{ + // since we only use chacha for randomness (and not encryption) we + // do not _need_ to read 32-bit values as little endian but we do anyways + // just for being compatible :-) + memset(ctx, 0, sizeof(*ctx)); + for (size_t i = 0; i < 4; i++) { + const uint8_t* sigma = (uint8_t*)"expand 32-byte k"; + ctx->input[i] = read32(sigma,i); + } + for (size_t i = 0; i < 8; i++) { + ctx->input[i + 4] = read32(key,i); + } + ctx->input[12] = 0; + ctx->input[13] = 0; + ctx->input[14] = (uint32_t)nonce; + ctx->input[15] = (uint32_t)(nonce >> 32); +} + +static void chacha_split(mi_random_ctx_t* ctx, uint64_t nonce, mi_random_ctx_t* ctx_new) { + memset(ctx_new, 0, sizeof(*ctx_new)); + memcpy(ctx_new->input, ctx->input, sizeof(ctx_new->input)); + ctx_new->input[12] = 0; + ctx_new->input[13] = 0; + ctx_new->input[14] = (uint32_t)nonce; + ctx_new->input[15] = (uint32_t)(nonce >> 32); + mi_assert_internal(ctx->input[14] != ctx_new->input[14] || ctx->input[15] != ctx_new->input[15]); // do not reuse nonces! + chacha_block(ctx_new); +} + + +/* ---------------------------------------------------------------------------- +Random interface +-----------------------------------------------------------------------------*/ + +#if MI_DEBUG>1 +static bool mi_random_is_initialized(mi_random_ctx_t* ctx) { + return (ctx != NULL && ctx->input[0] != 0); +} +#endif + +void _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* ctx_new) { + mi_assert_internal(mi_random_is_initialized(ctx)); + mi_assert_internal(ctx != ctx_new); + chacha_split(ctx, (uintptr_t)ctx_new /*nonce*/, ctx_new); +} + +uintptr_t _mi_random_next(mi_random_ctx_t* ctx) { + mi_assert_internal(mi_random_is_initialized(ctx)); + #if MI_INTPTR_SIZE <= 4 + return chacha_next32(ctx); + #elif MI_INTPTR_SIZE == 8 + return (((uintptr_t)chacha_next32(ctx) << 32) | chacha_next32(ctx)); + #else + # error "define mi_random_next for this platform" + #endif +} + + +/* ---------------------------------------------------------------------------- +To initialize a fresh random context we rely on the OS: +- Windows : BCryptGenRandom +- osX,bsd,wasi: arc4random_buf +- Linux : getrandom,/dev/urandom +If we cannot get good randomness, we fall back to weak randomness based on a timer and ASLR. +-----------------------------------------------------------------------------*/ + +#if defined(_WIN32) +#pragma comment (lib,"bcrypt.lib") +#include +static bool os_random_buf(void* buf, size_t buf_len) { + return (BCryptGenRandom(NULL, (PUCHAR)buf, (ULONG)buf_len, BCRYPT_USE_SYSTEM_PREFERRED_RNG) >= 0); +} +/* +#define SystemFunction036 NTAPI SystemFunction036 +#include +#undef SystemFunction036 +static bool os_random_buf(void* buf, size_t buf_len) { + RtlGenRandom(buf, (ULONG)buf_len); + return true; +} +*/ +#elif defined(ANDROID) || defined(XP_DARWIN) || defined(__APPLE__) || defined(__DragonFly__) || \ + defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ + defined(__sun) || defined(__wasi__) +#include +static bool os_random_buf(void* buf, size_t buf_len) { + arc4random_buf(buf, buf_len); + return true; +} +#elif defined(__linux__) +#include +#include +#include +#include +#include +#include +static bool os_random_buf(void* buf, size_t buf_len) { + // Modern Linux provides `getrandom` but different distributions either use `sys/random.h` or `linux/random.h` + // and for the latter the actual `getrandom` call is not always defined. + // (see ) + // We therefore use a syscall directly and fall back dynamically to /dev/urandom when needed. +#ifdef SYS_getrandom + #ifndef GRND_NONBLOCK + #define GRND_NONBLOCK (1) + #endif + static volatile _Atomic(uintptr_t) no_getrandom; // = 0 + if (mi_atomic_read(&no_getrandom)==0) { + ssize_t ret = syscall(SYS_getrandom, buf, buf_len, GRND_NONBLOCK); + if (ret >= 0) return (buf_len == (size_t)ret); + if (ret != ENOSYS) return false; + mi_atomic_write(&no_getrandom,1); // don't call again, and fall back to /dev/urandom + } +#endif + int flags = O_RDONLY; + #if defined(O_CLOEXEC) + flags |= O_CLOEXEC; + #endif + int fd = open("/dev/urandom", flags, 0); + if (fd < 0) return false; + size_t count = 0; + while(count < buf_len) { + ssize_t ret = read(fd, (char*)buf + count, buf_len - count); + if (ret<=0) { + if (errno!=EAGAIN && errno!=EINTR) break; + } + else { + count += ret; + } + } + close(fd); + return (count==buf_len); +} +#else +static bool os_random_buf(void* buf, size_t buf_len) { + return false; +} +#endif + +#if defined(_WIN32) +#include +#elif defined(__APPLE__) +#include +#else +#include +#endif + +uintptr_t _os_random_weak(uintptr_t extra_seed) { + uintptr_t x = (uintptr_t)&_os_random_weak ^ extra_seed; // ASLR makes the address random + #if defined(_WIN32) + LARGE_INTEGER pcount; + QueryPerformanceCounter(&pcount); + x ^= (uintptr_t)(pcount.QuadPart); + #elif defined(__APPLE__) + x ^= (uintptr_t)mach_absolute_time(); + #else + struct timespec time; + clock_gettime(CLOCK_MONOTONIC, &time); + x ^= (uintptr_t)time.tv_sec; + x ^= (uintptr_t)time.tv_nsec; + #endif + // and do a few randomization steps + uintptr_t max = ((x ^ (x >> 17)) & 0x0F) + 1; + for (uintptr_t i = 0; i < max; i++) { + x = _mi_random_shuffle(x); + } + mi_assert_internal(x != 0); + return x; +} + +void _mi_random_init(mi_random_ctx_t* ctx) { + uint8_t key[32]; + if (!os_random_buf(key, sizeof(key))) { + // if we fail to get random data from the OS, we fall back to a + // weak random source based on the current time + _mi_warning_message("unable to use secure randomness\n"); + uintptr_t x = _os_random_weak(0); + for (size_t i = 0; i < 8; i++) { // key is eight 32-bit words. + x = _mi_random_shuffle(x); + ((uint32_t*)key)[i] = (uint32_t)x; + } + } + chacha_init(ctx, key, (uintptr_t)ctx /*nonce*/ ); +} + +/* -------------------------------------------------------- +test vectors from +----------------------------------------------------------- */ +/* +static bool array_equals(uint32_t* x, uint32_t* y, size_t n) { + for (size_t i = 0; i < n; i++) { + if (x[i] != y[i]) return false; + } + return true; +} +static void chacha_test(void) +{ + uint32_t x[4] = { 0x11111111, 0x01020304, 0x9b8d6f43, 0x01234567 }; + uint32_t x_out[4] = { 0xea2a92f4, 0xcb1cf8ce, 0x4581472e, 0x5881c4bb }; + qround(x, 0, 1, 2, 3); + mi_assert_internal(array_equals(x, x_out, 4)); + + uint32_t y[16] = { + 0x879531e0, 0xc5ecf37d, 0x516461b1, 0xc9a62f8a, + 0x44c20ef3, 0x3390af7f, 0xd9fc690b, 0x2a5f714c, + 0x53372767, 0xb00a5631, 0x974c541a, 0x359e9963, + 0x5c971061, 0x3d631689, 0x2098d9d6, 0x91dbd320 }; + uint32_t y_out[16] = { + 0x879531e0, 0xc5ecf37d, 0xbdb886dc, 0xc9a62f8a, + 0x44c20ef3, 0x3390af7f, 0xd9fc690b, 0xcfacafd2, + 0xe46bea80, 0xb00a5631, 0x974c541a, 0x359e9963, + 0x5c971061, 0xccc07c79, 0x2098d9d6, 0x91dbd320 }; + qround(y, 2, 7, 8, 13); + mi_assert_internal(array_equals(y, y_out, 16)); + + mi_random_ctx_t r = { + { 0x61707865, 0x3320646e, 0x79622d32, 0x6b206574, + 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c, + 0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c, + 0x00000001, 0x09000000, 0x4a000000, 0x00000000 }, + {0}, + 0 + }; + uint32_t r_out[16] = { + 0xe4e7f110, 0x15593bd1, 0x1fdd0f50, 0xc47120a3, + 0xc7f4d1c7, 0x0368c033, 0x9aaa2204, 0x4e6cd4c3, + 0x466482d2, 0x09aa9f07, 0x05d7c214, 0xa2028bd9, + 0xd19c12b5, 0xb94e16de, 0xe883d0cb, 0x4e3c50a2 }; + chacha_block(&r); + mi_assert_internal(array_equals(r.output, r_out, 16)); +} +*/ diff --git a/extlib/mimalloc/src/region.c b/extlib/mimalloc/src/region.c new file mode 100644 index 0000000..ae3a799 --- /dev/null +++ b/extlib/mimalloc/src/region.c @@ -0,0 +1,498 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2019, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* ---------------------------------------------------------------------------- +This implements a layer between the raw OS memory (VirtualAlloc/mmap/sbrk/..) +and the segment and huge object allocation by mimalloc. There may be multiple +implementations of this (one could be the identity going directly to the OS, +another could be a simple cache etc), but the current one uses large "regions". +In contrast to the rest of mimalloc, the "regions" are shared between threads and +need to be accessed using atomic operations. +We need this memory layer between the raw OS calls because of: +1. on `sbrk` like systems (like WebAssembly) we need our own memory maps in order + to reuse memory effectively. +2. It turns out that for large objects, between 1MiB and 32MiB (?), the cost of + an OS allocation/free is still (much) too expensive relative to the accesses + in that object :-( (`malloc-large` tests this). This means we need a cheaper + way to reuse memory. +3. This layer allows for NUMA aware allocation. + +Possible issues: +- (2) can potentially be addressed too with a small cache per thread which is much + simpler. Generally though that requires shrinking of huge pages, and may overuse + memory per thread. (and is not compatible with `sbrk`). +- Since the current regions are per-process, we need atomic operations to + claim blocks which may be contended +- In the worst case, we need to search the whole region map (16KiB for 256GiB) + linearly. At what point will direct OS calls be faster? Is there a way to + do this better without adding too much complexity? +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc-internal.h" +#include "mimalloc-atomic.h" + +#include // memset + +#include "bitmap.inc.c" + +// Internal raw OS interface +size_t _mi_os_large_page_size(); +bool _mi_os_protect(void* addr, size_t size); +bool _mi_os_unprotect(void* addr, size_t size); +bool _mi_os_commit(void* p, size_t size, bool* is_zero, mi_stats_t* stats); +bool _mi_os_decommit(void* p, size_t size, mi_stats_t* stats); +bool _mi_os_reset(void* p, size_t size, mi_stats_t* stats); +bool _mi_os_unreset(void* p, size_t size, bool* is_zero, mi_stats_t* stats); + +// arena.c +void _mi_arena_free(void* p, size_t size, size_t memid, bool all_committed, mi_stats_t* stats); +void* _mi_arena_alloc(size_t size, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld); +void* _mi_arena_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld); + + + +// Constants +#if (MI_INTPTR_SIZE==8) +#define MI_HEAP_REGION_MAX_SIZE (256 * GiB) // 64KiB for the region map +#elif (MI_INTPTR_SIZE==4) +#define MI_HEAP_REGION_MAX_SIZE (3 * GiB) // ~ KiB for the region map +#else +#error "define the maximum heap space allowed for regions on this platform" +#endif + +#define MI_SEGMENT_ALIGN MI_SEGMENT_SIZE + +#define MI_REGION_MAX_BLOCKS MI_BITMAP_FIELD_BITS +#define MI_REGION_SIZE (MI_SEGMENT_SIZE * MI_BITMAP_FIELD_BITS) // 256MiB (64MiB on 32 bits) +#define MI_REGION_MAX (MI_HEAP_REGION_MAX_SIZE / MI_REGION_SIZE) // 1024 (48 on 32 bits) +#define MI_REGION_MAX_OBJ_BLOCKS (MI_REGION_MAX_BLOCKS/4) // 64MiB +#define MI_REGION_MAX_OBJ_SIZE (MI_REGION_MAX_OBJ_BLOCKS*MI_SEGMENT_SIZE) + +// Region info +typedef union mi_region_info_u { + uintptr_t value; + struct { + bool valid; // initialized? + bool is_large; // allocated in fixed large/huge OS pages + short numa_node; // the associated NUMA node (where -1 means no associated node) + } x; +} mi_region_info_t; + + +// A region owns a chunk of REGION_SIZE (256MiB) (virtual) memory with +// a bit map with one bit per MI_SEGMENT_SIZE (4MiB) block. +typedef struct mem_region_s { + volatile _Atomic(uintptr_t) info; // mi_region_info_t.value + volatile _Atomic(void*) start; // start of the memory area + mi_bitmap_field_t in_use; // bit per in-use block + mi_bitmap_field_t dirty; // track if non-zero per block + mi_bitmap_field_t commit; // track if committed per block + mi_bitmap_field_t reset; // track if reset per block + volatile _Atomic(uintptr_t) arena_memid; // if allocated from a (huge page) arena + uintptr_t padding; // round to 8 fields +} mem_region_t; + +// The region map +static mem_region_t regions[MI_REGION_MAX]; + +// Allocated regions +static volatile _Atomic(uintptr_t) regions_count; // = 0; + + +/* ---------------------------------------------------------------------------- +Utility functions +-----------------------------------------------------------------------------*/ + +// Blocks (of 4MiB) needed for the given size. +static size_t mi_region_block_count(size_t size) { + return _mi_divide_up(size, MI_SEGMENT_SIZE); +} + +/* +// Return a rounded commit/reset size such that we don't fragment large OS pages into small ones. +static size_t mi_good_commit_size(size_t size) { + if (size > (SIZE_MAX - _mi_os_large_page_size())) return size; + return _mi_align_up(size, _mi_os_large_page_size()); +} +*/ + +// Return if a pointer points into a region reserved by us. +bool mi_is_in_heap_region(const void* p) mi_attr_noexcept { + if (p==NULL) return false; + size_t count = mi_atomic_read_relaxed(®ions_count); + for (size_t i = 0; i < count; i++) { + uint8_t* start = mi_atomic_read_ptr_relaxed(uint8_t,®ions[i].start); + if (start != NULL && (uint8_t*)p >= start && (uint8_t*)p < start + MI_REGION_SIZE) return true; + } + return false; +} + + +static void* mi_region_blocks_start(const mem_region_t* region, mi_bitmap_index_t bit_idx) { + uint8_t* start = mi_atomic_read_ptr(uint8_t,®ion->start); + mi_assert_internal(start != NULL); + return (start + (bit_idx * MI_SEGMENT_SIZE)); +} + +static size_t mi_memid_create(mem_region_t* region, mi_bitmap_index_t bit_idx) { + mi_assert_internal(bit_idx < MI_BITMAP_FIELD_BITS); + size_t idx = region - regions; + mi_assert_internal(®ions[idx] == region); + return (idx*MI_BITMAP_FIELD_BITS + bit_idx)<<1; +} + +static size_t mi_memid_create_from_arena(size_t arena_memid) { + return (arena_memid << 1) | 1; +} + + +static bool mi_memid_is_arena(size_t id, mem_region_t** region, mi_bitmap_index_t* bit_idx, size_t* arena_memid) { + if ((id&1)==1) { + if (arena_memid != NULL) *arena_memid = (id>>1); + return true; + } + else { + size_t idx = (id >> 1) / MI_BITMAP_FIELD_BITS; + *bit_idx = (mi_bitmap_index_t)(id>>1) % MI_BITMAP_FIELD_BITS; + *region = ®ions[idx]; + return false; + } +} + + +/* ---------------------------------------------------------------------------- + Allocate a region is allocated from the OS (or an arena) +-----------------------------------------------------------------------------*/ + +static bool mi_region_try_alloc_os(size_t blocks, bool commit, bool allow_large, mem_region_t** region, mi_bitmap_index_t* bit_idx, mi_os_tld_t* tld) +{ + // not out of regions yet? + if (mi_atomic_read_relaxed(®ions_count) >= MI_REGION_MAX - 1) return false; + + // try to allocate a fresh region from the OS + bool region_commit = (commit && mi_option_is_enabled(mi_option_eager_region_commit)); + bool region_large = (commit && allow_large); + bool is_zero = false; + size_t arena_memid = 0; + void* const start = _mi_arena_alloc_aligned(MI_REGION_SIZE, MI_SEGMENT_ALIGN, ®ion_commit, ®ion_large, &is_zero, &arena_memid, tld); + if (start == NULL) return false; + mi_assert_internal(!(region_large && !allow_large)); + mi_assert_internal(!region_large || region_commit); + + // claim a fresh slot + const uintptr_t idx = mi_atomic_increment(®ions_count); + if (idx >= MI_REGION_MAX) { + mi_atomic_decrement(®ions_count); + _mi_arena_free(start, MI_REGION_SIZE, arena_memid, region_commit, tld->stats); + _mi_warning_message("maximum regions used: %zu GiB (perhaps recompile with a larger setting for MI_HEAP_REGION_MAX_SIZE)", _mi_divide_up(MI_HEAP_REGION_MAX_SIZE, GiB)); + return false; + } + + // allocated, initialize and claim the initial blocks + mem_region_t* r = ®ions[idx]; + r->arena_memid = arena_memid; + mi_atomic_write(&r->in_use, 0); + mi_atomic_write(&r->dirty, (is_zero ? 0 : MI_BITMAP_FIELD_FULL)); + mi_atomic_write(&r->commit, (region_commit ? MI_BITMAP_FIELD_FULL : 0)); + mi_atomic_write(&r->reset, 0); + *bit_idx = 0; + mi_bitmap_claim(&r->in_use, 1, blocks, *bit_idx, NULL); + mi_atomic_write_ptr(uint8_t*,&r->start, start); + + // and share it + mi_region_info_t info; + info.value = 0; // initialize the full union to zero + info.x.valid = true; + info.x.is_large = region_large; + info.x.numa_node = (short)_mi_os_numa_node(tld); + mi_atomic_write(&r->info, info.value); // now make it available to others + *region = r; + return true; +} + +/* ---------------------------------------------------------------------------- + Try to claim blocks in suitable regions +-----------------------------------------------------------------------------*/ + +static bool mi_region_is_suitable(const mem_region_t* region, int numa_node, bool allow_large ) { + // initialized at all? + mi_region_info_t info; + info.value = mi_atomic_read_relaxed(®ion->info); + if (info.value==0) return false; + + // numa correct + if (numa_node >= 0) { // use negative numa node to always succeed + int rnode = info.x.numa_node; + if (rnode >= 0 && rnode != numa_node) return false; + } + + // check allow-large + if (!allow_large && info.x.is_large) return false; + + return true; +} + + +static bool mi_region_try_claim(int numa_node, size_t blocks, bool allow_large, mem_region_t** region, mi_bitmap_index_t* bit_idx, mi_os_tld_t* tld) +{ + // try all regions for a free slot + const size_t count = mi_atomic_read(®ions_count); + size_t idx = tld->region_idx; // Or start at 0 to reuse low addresses? Starting at 0 seems to increase latency though + for (size_t visited = 0; visited < count; visited++, idx++) { + if (idx >= count) idx = 0; // wrap around + mem_region_t* r = ®ions[idx]; + // if this region suits our demand (numa node matches, large OS page matches) + if (mi_region_is_suitable(r, numa_node, allow_large)) { + // then try to atomically claim a segment(s) in this region + if (mi_bitmap_try_find_claim_field(&r->in_use, 0, blocks, bit_idx)) { + tld->region_idx = idx; // remember the last found position + *region = r; + return true; + } + } + } + return false; +} + + +static void* mi_region_try_alloc(size_t blocks, bool* commit, bool* is_large, bool* is_zero, size_t* memid, mi_os_tld_t* tld) +{ + mi_assert_internal(blocks <= MI_BITMAP_FIELD_BITS); + mem_region_t* region; + mi_bitmap_index_t bit_idx; + const int numa_node = (_mi_os_numa_node_count() <= 1 ? -1 : _mi_os_numa_node(tld)); + // try to claim in existing regions + if (!mi_region_try_claim(numa_node, blocks, *is_large, ®ion, &bit_idx, tld)) { + // otherwise try to allocate a fresh region and claim in there + if (!mi_region_try_alloc_os(blocks, *commit, *is_large, ®ion, &bit_idx, tld)) { + // out of regions or memory + return NULL; + } + } + + // ------------------------------------------------ + // found a region and claimed `blocks` at `bit_idx`, initialize them now + mi_assert_internal(region != NULL); + mi_assert_internal(mi_bitmap_is_claimed(®ion->in_use, 1, blocks, bit_idx)); + + mi_region_info_t info; + info.value = mi_atomic_read(®ion->info); + uint8_t* start = mi_atomic_read_ptr(uint8_t,®ion->start); + mi_assert_internal(!(info.x.is_large && !*is_large)); + mi_assert_internal(start != NULL); + + *is_zero = mi_bitmap_claim(®ion->dirty, 1, blocks, bit_idx, NULL); + *is_large = info.x.is_large; + *memid = mi_memid_create(region, bit_idx); + void* p = start + (mi_bitmap_index_bit_in_field(bit_idx) * MI_SEGMENT_SIZE); + + // commit + if (*commit) { + // ensure commit + bool any_uncommitted; + mi_bitmap_claim(®ion->commit, 1, blocks, bit_idx, &any_uncommitted); + if (any_uncommitted) { + mi_assert_internal(!info.x.is_large); + bool commit_zero; + _mi_mem_commit(p, blocks * MI_SEGMENT_SIZE, &commit_zero, tld); + if (commit_zero) *is_zero = true; + } + } + else { + // no need to commit, but check if already fully committed + *commit = mi_bitmap_is_claimed(®ion->commit, 1, blocks, bit_idx); + } + mi_assert_internal(!*commit || mi_bitmap_is_claimed(®ion->commit, 1, blocks, bit_idx)); + + // unreset reset blocks + if (mi_bitmap_is_any_claimed(®ion->reset, 1, blocks, bit_idx)) { + // some blocks are still reset + mi_assert_internal(!info.x.is_large); + mi_assert_internal(!mi_option_is_enabled(mi_option_eager_commit) || *commit || mi_option_get(mi_option_eager_commit_delay) > 0); + mi_bitmap_unclaim(®ion->reset, 1, blocks, bit_idx); + if (*commit || !mi_option_is_enabled(mi_option_reset_decommits)) { // only if needed + bool reset_zero = false; + _mi_mem_unreset(p, blocks * MI_SEGMENT_SIZE, &reset_zero, tld); + if (reset_zero) *is_zero = true; + } + } + mi_assert_internal(!mi_bitmap_is_any_claimed(®ion->reset, 1, blocks, bit_idx)); + + #if (MI_DEBUG>=2) + if (*commit) { ((uint8_t*)p)[0] = 0; } + #endif + + // and return the allocation + mi_assert_internal(p != NULL); + return p; +} + + +/* ---------------------------------------------------------------------------- + Allocation +-----------------------------------------------------------------------------*/ + +// Allocate `size` memory aligned at `alignment`. Return non NULL on success, with a given memory `id`. +// (`id` is abstract, but `id = idx*MI_REGION_MAP_BITS + bitidx`) +void* _mi_mem_alloc_aligned(size_t size, size_t alignment, bool* commit, bool* large, bool* is_zero, size_t* memid, mi_os_tld_t* tld) +{ + mi_assert_internal(memid != NULL && tld != NULL); + mi_assert_internal(size > 0); + *memid = 0; + *is_zero = false; + bool default_large = false; + if (large==NULL) large = &default_large; // ensure `large != NULL` + if (size == 0) return NULL; + size = _mi_align_up(size, _mi_os_page_size()); + + // allocate from regions if possible + void* p = NULL; + size_t arena_memid; + const size_t blocks = mi_region_block_count(size); + if (blocks <= MI_REGION_MAX_OBJ_BLOCKS && alignment <= MI_SEGMENT_ALIGN) { + p = mi_region_try_alloc(blocks, commit, large, is_zero, memid, tld); + if (p == NULL) { + _mi_warning_message("unable to allocate from region: size %zu\n", size); + } + } + if (p == NULL) { + // and otherwise fall back to the OS + p = _mi_arena_alloc_aligned(size, alignment, commit, large, is_zero, &arena_memid, tld); + *memid = mi_memid_create_from_arena(arena_memid); + } + + if (p != NULL) { + mi_assert_internal((uintptr_t)p % alignment == 0); +#if (MI_DEBUG>=2) + if (*commit) { ((uint8_t*)p)[0] = 0; } // ensure the memory is committed +#endif + } + return p; +} + + + +/* ---------------------------------------------------------------------------- +Free +-----------------------------------------------------------------------------*/ + +// Free previously allocated memory with a given id. +void _mi_mem_free(void* p, size_t size, size_t id, bool full_commit, bool any_reset, mi_os_tld_t* tld) { + mi_assert_internal(size > 0 && tld != NULL); + if (p==NULL) return; + if (size==0) return; + size = _mi_align_up(size, _mi_os_page_size()); + + size_t arena_memid = 0; + mi_bitmap_index_t bit_idx; + mem_region_t* region; + if (mi_memid_is_arena(id,®ion,&bit_idx,&arena_memid)) { + // was a direct arena allocation, pass through + _mi_arena_free(p, size, arena_memid, full_commit, tld->stats); + } + else { + // allocated in a region + mi_assert_internal(size <= MI_REGION_MAX_OBJ_SIZE); if (size > MI_REGION_MAX_OBJ_SIZE) return; + const size_t blocks = mi_region_block_count(size); + mi_assert_internal(blocks + bit_idx <= MI_BITMAP_FIELD_BITS); + mi_region_info_t info; + info.value = mi_atomic_read(®ion->info); + mi_assert_internal(info.value != 0); + void* blocks_start = mi_region_blocks_start(region, bit_idx); + mi_assert_internal(blocks_start == p); // not a pointer in our area? + mi_assert_internal(bit_idx + blocks <= MI_BITMAP_FIELD_BITS); + if (blocks_start != p || bit_idx + blocks > MI_BITMAP_FIELD_BITS) return; // or `abort`? + + // committed? + if (full_commit && (size % MI_SEGMENT_SIZE) == 0) { + mi_bitmap_claim(®ion->commit, 1, blocks, bit_idx, NULL); + } + + if (any_reset) { + // set the is_reset bits if any pages were reset + mi_bitmap_claim(®ion->reset, 1, blocks, bit_idx, NULL); + } + + // reset the blocks to reduce the working set. + if (!info.x.is_large && mi_option_is_enabled(mi_option_segment_reset) + && (mi_option_is_enabled(mi_option_eager_commit) || + mi_option_is_enabled(mi_option_reset_decommits))) // cannot reset halfway committed segments, use only `option_page_reset` instead + { + bool any_unreset; + mi_bitmap_claim(®ion->reset, 1, blocks, bit_idx, &any_unreset); + if (any_unreset) { + _mi_abandoned_await_readers(); // ensure no more pending write (in case reset = decommit) + _mi_mem_reset(p, blocks * MI_SEGMENT_SIZE, tld); + } + } + + // and unclaim + bool all_unclaimed = mi_bitmap_unclaim(®ion->in_use, 1, blocks, bit_idx); + mi_assert_internal(all_unclaimed); UNUSED(all_unclaimed); + } +} + + +/* ---------------------------------------------------------------------------- + collection +-----------------------------------------------------------------------------*/ +void _mi_mem_collect(mi_os_tld_t* tld) { + // free every region that has no segments in use. + uintptr_t rcount = mi_atomic_read_relaxed(®ions_count); + for (size_t i = 0; i < rcount; i++) { + mem_region_t* region = ®ions[i]; + if (mi_atomic_read_relaxed(®ion->info) != 0) { + // if no segments used, try to claim the whole region + uintptr_t m; + do { + m = mi_atomic_read_relaxed(®ion->in_use); + } while(m == 0 && !mi_atomic_cas_weak(®ion->in_use, MI_BITMAP_FIELD_FULL, 0 )); + if (m == 0) { + // on success, free the whole region + uint8_t* start = mi_atomic_read_ptr(uint8_t,®ions[i].start); + size_t arena_memid = mi_atomic_read_relaxed(®ions[i].arena_memid); + uintptr_t commit = mi_atomic_read_relaxed(®ions[i].commit); + memset(®ions[i], 0, sizeof(mem_region_t)); + // and release the whole region + mi_atomic_write(®ion->info, 0); + if (start != NULL) { // && !_mi_os_is_huge_reserved(start)) { + _mi_abandoned_await_readers(); // ensure no pending reads + _mi_arena_free(start, MI_REGION_SIZE, arena_memid, (~commit == 0), tld->stats); + } + } + } + } +} + + +/* ---------------------------------------------------------------------------- + Other +-----------------------------------------------------------------------------*/ + +bool _mi_mem_reset(void* p, size_t size, mi_os_tld_t* tld) { + return _mi_os_reset(p, size, tld->stats); +} + +bool _mi_mem_unreset(void* p, size_t size, bool* is_zero, mi_os_tld_t* tld) { + return _mi_os_unreset(p, size, is_zero, tld->stats); +} + +bool _mi_mem_commit(void* p, size_t size, bool* is_zero, mi_os_tld_t* tld) { + return _mi_os_commit(p, size, is_zero, tld->stats); +} + +bool _mi_mem_decommit(void* p, size_t size, mi_os_tld_t* tld) { + return _mi_os_decommit(p, size, tld->stats); +} + +bool _mi_mem_protect(void* p, size_t size) { + return _mi_os_protect(p, size); +} + +bool _mi_mem_unprotect(void* p, size_t size) { + return _mi_os_unprotect(p, size); +} diff --git a/extlib/mimalloc/src/segment.c b/extlib/mimalloc/src/segment.c new file mode 100644 index 0000000..8a5ba8c --- /dev/null +++ b/extlib/mimalloc/src/segment.c @@ -0,0 +1,1343 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc-internal.h" +#include "mimalloc-atomic.h" + +#include // memset +#include + +#define MI_PAGE_HUGE_ALIGN (256*1024) + +static uint8_t* mi_segment_raw_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size); + +/* -------------------------------------------------------------------------------- + Segment allocation + We allocate pages inside bigger "segments" (4mb on 64-bit). This is to avoid + splitting VMA's on Linux and reduce fragmentation on other OS's. + Each thread owns its own segments. + + Currently we have: + - small pages (64kb), 64 in one segment + - medium pages (512kb), 8 in one segment + - large pages (4mb), 1 in one segment + - huge blocks > MI_LARGE_OBJ_SIZE_MAX become large segment with 1 page + + In any case the memory for a segment is virtual and usually committed on demand. + (i.e. we are careful to not touch the memory until we actually allocate a block there) + + If a thread ends, it "abandons" pages with used blocks + and there is an abandoned segment list whose segments can + be reclaimed by still running threads, much like work-stealing. +-------------------------------------------------------------------------------- */ + + +/* ----------------------------------------------------------- + Queue of segments containing free pages +----------------------------------------------------------- */ + +#if (MI_DEBUG>=3) +static bool mi_segment_queue_contains(const mi_segment_queue_t* queue, const mi_segment_t* segment) { + mi_assert_internal(segment != NULL); + mi_segment_t* list = queue->first; + while (list != NULL) { + if (list == segment) break; + mi_assert_internal(list->next==NULL || list->next->prev == list); + mi_assert_internal(list->prev==NULL || list->prev->next == list); + list = list->next; + } + return (list == segment); +} +#endif + +static bool mi_segment_queue_is_empty(const mi_segment_queue_t* queue) { + return (queue->first == NULL); +} + +static void mi_segment_queue_remove(mi_segment_queue_t* queue, mi_segment_t* segment) { + mi_assert_expensive(mi_segment_queue_contains(queue, segment)); + if (segment->prev != NULL) segment->prev->next = segment->next; + if (segment->next != NULL) segment->next->prev = segment->prev; + if (segment == queue->first) queue->first = segment->next; + if (segment == queue->last) queue->last = segment->prev; + segment->next = NULL; + segment->prev = NULL; +} + +static void mi_segment_enqueue(mi_segment_queue_t* queue, mi_segment_t* segment) { + mi_assert_expensive(!mi_segment_queue_contains(queue, segment)); + segment->next = NULL; + segment->prev = queue->last; + if (queue->last != NULL) { + mi_assert_internal(queue->last->next == NULL); + queue->last->next = segment; + queue->last = segment; + } + else { + queue->last = queue->first = segment; + } +} + +static mi_segment_queue_t* mi_segment_free_queue_of_kind(mi_page_kind_t kind, mi_segments_tld_t* tld) { + if (kind == MI_PAGE_SMALL) return &tld->small_free; + else if (kind == MI_PAGE_MEDIUM) return &tld->medium_free; + else return NULL; +} + +static mi_segment_queue_t* mi_segment_free_queue(const mi_segment_t* segment, mi_segments_tld_t* tld) { + return mi_segment_free_queue_of_kind(segment->page_kind, tld); +} + +// remove from free queue if it is in one +static void mi_segment_remove_from_free_queue(mi_segment_t* segment, mi_segments_tld_t* tld) { + mi_segment_queue_t* queue = mi_segment_free_queue(segment, tld); // may be NULL + bool in_queue = (queue!=NULL && (segment->next != NULL || segment->prev != NULL || queue->first == segment)); + if (in_queue) { + mi_segment_queue_remove(queue, segment); + } +} + +static void mi_segment_insert_in_free_queue(mi_segment_t* segment, mi_segments_tld_t* tld) { + mi_segment_enqueue(mi_segment_free_queue(segment, tld), segment); +} + + +/* ----------------------------------------------------------- + Invariant checking +----------------------------------------------------------- */ + +#if (MI_DEBUG>=2) +static bool mi_segment_is_in_free_queue(const mi_segment_t* segment, mi_segments_tld_t* tld) { + mi_segment_queue_t* queue = mi_segment_free_queue(segment, tld); + bool in_queue = (queue!=NULL && (segment->next != NULL || segment->prev != NULL || queue->first == segment)); + if (in_queue) { + mi_assert_expensive(mi_segment_queue_contains(queue, segment)); + } + return in_queue; +} +#endif + +static size_t mi_segment_page_size(const mi_segment_t* segment) { + if (segment->capacity > 1) { + mi_assert_internal(segment->page_kind <= MI_PAGE_MEDIUM); + return ((size_t)1 << segment->page_shift); + } + else { + mi_assert_internal(segment->page_kind >= MI_PAGE_LARGE); + return segment->segment_size; + } +} + + +#if (MI_DEBUG>=2) +static bool mi_pages_reset_contains(const mi_page_t* page, mi_segments_tld_t* tld) { + mi_page_t* p = tld->pages_reset.first; + while (p != NULL) { + if (p == page) return true; + p = p->next; + } + return false; +} +#endif + +#if (MI_DEBUG>=3) +static bool mi_segment_is_valid(const mi_segment_t* segment, mi_segments_tld_t* tld) { + mi_assert_internal(segment != NULL); + mi_assert_internal(_mi_ptr_cookie(segment) == segment->cookie); + mi_assert_internal(segment->used <= segment->capacity); + mi_assert_internal(segment->abandoned <= segment->used); + size_t nfree = 0; + for (size_t i = 0; i < segment->capacity; i++) { + const mi_page_t* const page = &segment->pages[i]; + if (!page->segment_in_use) { + nfree++; + } + if (page->segment_in_use || page->is_reset) { + mi_assert_expensive(!mi_pages_reset_contains(page, tld)); + } + } + mi_assert_internal(nfree + segment->used == segment->capacity); + // mi_assert_internal(segment->thread_id == _mi_thread_id() || (segment->thread_id==0)); // or 0 + mi_assert_internal(segment->page_kind == MI_PAGE_HUGE || + (mi_segment_page_size(segment) * segment->capacity == segment->segment_size)); + return true; +} +#endif + +static bool mi_page_not_in_queue(const mi_page_t* page, mi_segments_tld_t* tld) { + mi_assert_internal(page != NULL); + if (page->next != NULL || page->prev != NULL) { + mi_assert_internal(mi_pages_reset_contains(page, tld)); + return false; + } + else { + // both next and prev are NULL, check for singleton list + return (tld->pages_reset.first != page && tld->pages_reset.last != page); + } +} + + +/* ----------------------------------------------------------- + Guard pages +----------------------------------------------------------- */ + +static void mi_segment_protect_range(void* p, size_t size, bool protect) { + if (protect) { + _mi_mem_protect(p, size); + } + else { + _mi_mem_unprotect(p, size); + } +} + +static void mi_segment_protect(mi_segment_t* segment, bool protect, mi_os_tld_t* tld) { + // add/remove guard pages + if (MI_SECURE != 0) { + // in secure mode, we set up a protected page in between the segment info and the page data + const size_t os_page_size = _mi_os_page_size(); + mi_assert_internal((segment->segment_info_size - os_page_size) >= (sizeof(mi_segment_t) + ((segment->capacity - 1) * sizeof(mi_page_t)))); + mi_assert_internal(((uintptr_t)segment + segment->segment_info_size) % os_page_size == 0); + mi_segment_protect_range((uint8_t*)segment + segment->segment_info_size - os_page_size, os_page_size, protect); + if (MI_SECURE <= 1 || segment->capacity == 1) { + // and protect the last (or only) page too + mi_assert_internal(MI_SECURE <= 1 || segment->page_kind >= MI_PAGE_LARGE); + uint8_t* start = (uint8_t*)segment + segment->segment_size - os_page_size; + if (protect && !segment->mem_is_committed) { + // ensure secure page is committed + _mi_mem_commit(start, os_page_size, NULL, tld); + } + mi_segment_protect_range(start, os_page_size, protect); + } + else { + // or protect every page + const size_t page_size = mi_segment_page_size(segment); + for (size_t i = 0; i < segment->capacity; i++) { + if (segment->pages[i].is_committed) { + mi_segment_protect_range((uint8_t*)segment + (i+1)*page_size - os_page_size, os_page_size, protect); + } + } + } + } +} + +/* ----------------------------------------------------------- + Page reset +----------------------------------------------------------- */ + +static void mi_page_reset(mi_segment_t* segment, mi_page_t* page, size_t size, mi_segments_tld_t* tld) { + mi_assert_internal(page->is_committed); + if (!mi_option_is_enabled(mi_option_page_reset)) return; + if (segment->mem_is_fixed || page->segment_in_use || !page->is_committed || page->is_reset) return; + size_t psize; + void* start = mi_segment_raw_page_start(segment, page, &psize); + page->is_reset = true; + mi_assert_internal(size <= psize); + size_t reset_size = ((size == 0 || size > psize) ? psize : size); + if (reset_size > 0) _mi_mem_reset(start, reset_size, tld->os); +} + +static bool mi_page_unreset(mi_segment_t* segment, mi_page_t* page, size_t size, mi_segments_tld_t* tld) +{ + mi_assert_internal(page->is_reset); + mi_assert_internal(page->is_committed); + mi_assert_internal(!segment->mem_is_fixed); + if (segment->mem_is_fixed || !page->is_committed || !page->is_reset) return true; + page->is_reset = false; + size_t psize; + uint8_t* start = mi_segment_raw_page_start(segment, page, &psize); + size_t unreset_size = (size == 0 || size > psize ? psize : size); + bool is_zero = false; + bool ok = true; + if (unreset_size > 0) { + ok = _mi_mem_unreset(start, unreset_size, &is_zero, tld->os); + } + if (is_zero) page->is_zero_init = true; + return ok; +} + + +/* ----------------------------------------------------------- + The free page queue +----------------------------------------------------------- */ + +// we re-use the `used` field for the expiration counter. Since this is a +// a 32-bit field while the clock is always 64-bit we need to guard +// against overflow, we use substraction to check for expiry which work +// as long as the reset delay is under (2^30 - 1) milliseconds (~12 days) +static void mi_page_reset_set_expire(mi_page_t* page) { + uint32_t expire = (uint32_t)_mi_clock_now() + mi_option_get(mi_option_reset_delay); + page->used = expire; +} + +static bool mi_page_reset_is_expired(mi_page_t* page, mi_msecs_t now) { + int32_t expire = (int32_t)(page->used); + return (((int32_t)now - expire) >= 0); +} + +static void mi_pages_reset_add(mi_segment_t* segment, mi_page_t* page, mi_segments_tld_t* tld) { + mi_assert_internal(!page->segment_in_use || !page->is_committed); + mi_assert_internal(mi_page_not_in_queue(page,tld)); + mi_assert_expensive(!mi_pages_reset_contains(page, tld)); + mi_assert_internal(_mi_page_segment(page)==segment); + if (!mi_option_is_enabled(mi_option_page_reset)) return; + if (segment->mem_is_fixed || page->segment_in_use || !page->is_committed || page->is_reset) return; + + if (mi_option_get(mi_option_reset_delay) == 0) { + // reset immediately? + mi_page_reset(segment, page, 0, tld); + } + else { + // otherwise push on the delayed page reset queue + mi_page_queue_t* pq = &tld->pages_reset; + // push on top + mi_page_reset_set_expire(page); + page->next = pq->first; + page->prev = NULL; + if (pq->first == NULL) { + mi_assert_internal(pq->last == NULL); + pq->first = pq->last = page; + } + else { + pq->first->prev = page; + pq->first = page; + } + } +} + +static void mi_pages_reset_remove(mi_page_t* page, mi_segments_tld_t* tld) { + if (mi_page_not_in_queue(page,tld)) return; + + mi_page_queue_t* pq = &tld->pages_reset; + mi_assert_internal(pq!=NULL); + mi_assert_internal(!page->segment_in_use); + mi_assert_internal(mi_pages_reset_contains(page, tld)); + if (page->prev != NULL) page->prev->next = page->next; + if (page->next != NULL) page->next->prev = page->prev; + if (page == pq->last) pq->last = page->prev; + if (page == pq->first) pq->first = page->next; + page->next = page->prev = NULL; + page->used = 0; +} + +static void mi_pages_reset_remove_all_in_segment(mi_segment_t* segment, bool force_reset, mi_segments_tld_t* tld) { + if (segment->mem_is_fixed) return; // never reset in huge OS pages + for (size_t i = 0; i < segment->capacity; i++) { + mi_page_t* page = &segment->pages[i]; + if (!page->segment_in_use && page->is_committed && !page->is_reset) { + mi_pages_reset_remove(page, tld); + if (force_reset) { + mi_page_reset(segment, page, 0, tld); + } + } + else { + mi_assert_internal(mi_page_not_in_queue(page,tld)); + } + } +} + +static void mi_reset_delayed(mi_segments_tld_t* tld) { + if (!mi_option_is_enabled(mi_option_page_reset)) return; + mi_msecs_t now = _mi_clock_now(); + mi_page_queue_t* pq = &tld->pages_reset; + // from oldest up to the first that has not expired yet + mi_page_t* page = pq->last; + while (page != NULL && mi_page_reset_is_expired(page,now)) { + mi_page_t* const prev = page->prev; // save previous field + mi_page_reset(_mi_page_segment(page), page, 0, tld); + page->used = 0; + page->prev = page->next = NULL; + page = prev; + } + // discard the reset pages from the queue + pq->last = page; + if (page != NULL){ + page->next = NULL; + } + else { + pq->first = NULL; + } +} + + +/* ----------------------------------------------------------- + Segment size calculations +----------------------------------------------------------- */ + +// Raw start of the page available memory; can be used on uninitialized pages (only `segment_idx` must be set) +// The raw start is not taking aligned block allocation into consideration. +static uint8_t* mi_segment_raw_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size) { + size_t psize = (segment->page_kind == MI_PAGE_HUGE ? segment->segment_size : (size_t)1 << segment->page_shift); + uint8_t* p = (uint8_t*)segment + page->segment_idx * psize; + + if (page->segment_idx == 0) { + // the first page starts after the segment info (and possible guard page) + p += segment->segment_info_size; + psize -= segment->segment_info_size; + } + + if (MI_SECURE > 1 || (MI_SECURE == 1 && page->segment_idx == segment->capacity - 1)) { + // secure == 1: the last page has an os guard page at the end + // secure > 1: every page has an os guard page + psize -= _mi_os_page_size(); + } + + if (page_size != NULL) *page_size = psize; + mi_assert_internal(page->xblock_size == 0 || _mi_ptr_page(p) == page); + mi_assert_internal(_mi_ptr_segment(p) == segment); + return p; +} + +// Start of the page available memory; can be used on uninitialized pages (only `segment_idx` must be set) +uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t block_size, size_t* page_size, size_t* pre_size) +{ + size_t psize; + uint8_t* p = mi_segment_raw_page_start(segment, page, &psize); + if (pre_size != NULL) *pre_size = 0; + if (page->segment_idx == 0 && block_size > 0 && segment->page_kind <= MI_PAGE_MEDIUM) { + // for small and medium objects, ensure the page start is aligned with the block size (PR#66 by kickunderscore) + size_t adjust = block_size - ((uintptr_t)p % block_size); + if (adjust < block_size) { + p += adjust; + psize -= adjust; + if (pre_size != NULL) *pre_size = adjust; + } + mi_assert_internal((uintptr_t)p % block_size == 0); + } + + if (page_size != NULL) *page_size = psize; + mi_assert_internal(page->xblock_size==0 || _mi_ptr_page(p) == page); + mi_assert_internal(_mi_ptr_segment(p) == segment); + return p; +} + +static size_t mi_segment_size(size_t capacity, size_t required, size_t* pre_size, size_t* info_size) +{ + const size_t minsize = sizeof(mi_segment_t) + ((capacity - 1) * sizeof(mi_page_t)) + 16 /* padding */; + size_t guardsize = 0; + size_t isize = 0; + + if (MI_SECURE == 0) { + // normally no guard pages + isize = _mi_align_up(minsize, 16 * MI_MAX_ALIGN_SIZE); + } + else { + // in secure mode, we set up a protected page in between the segment info + // and the page data (and one at the end of the segment) + const size_t page_size = _mi_os_page_size(); + isize = _mi_align_up(minsize, page_size); + guardsize = page_size; + required = _mi_align_up(required, page_size); + } + + if (info_size != NULL) *info_size = isize; + if (pre_size != NULL) *pre_size = isize + guardsize; + return (required==0 ? MI_SEGMENT_SIZE : _mi_align_up( required + isize + 2*guardsize, MI_PAGE_HUGE_ALIGN) ); +} + + +/* ---------------------------------------------------------------------------- +Segment caches +We keep a small segment cache per thread to increase local +reuse and avoid setting/clearing guard pages in secure mode. +------------------------------------------------------------------------------- */ + +static void mi_segments_track_size(long segment_size, mi_segments_tld_t* tld) { + if (segment_size>=0) _mi_stat_increase(&tld->stats->segments,1); + else _mi_stat_decrease(&tld->stats->segments,1); + tld->count += (segment_size >= 0 ? 1 : -1); + if (tld->count > tld->peak_count) tld->peak_count = tld->count; + tld->current_size += segment_size; + if (tld->current_size > tld->peak_size) tld->peak_size = tld->current_size; +} + +static void mi_segment_os_free(mi_segment_t* segment, size_t segment_size, mi_segments_tld_t* tld) { + segment->thread_id = 0; + mi_segments_track_size(-((long)segment_size),tld); + if (MI_SECURE != 0) { + mi_assert_internal(!segment->mem_is_fixed); + mi_segment_protect(segment, false, tld->os); // ensure no more guard pages are set + } + + bool any_reset = false; + bool fully_committed = true; + for (size_t i = 0; i < segment->capacity; i++) { + mi_page_t* page = &segment->pages[i]; + if (!page->is_committed) { fully_committed = false; } + if (page->is_reset) { any_reset = true; } + } + if (any_reset && mi_option_is_enabled(mi_option_reset_decommits)) { + fully_committed = false; + } + + _mi_mem_free(segment, segment_size, segment->memid, fully_committed, any_reset, tld->os); +} + + +// The thread local segment cache is limited to be at most 1/8 of the peak size of segments in use, +#define MI_SEGMENT_CACHE_FRACTION (8) + +// note: returned segment may be partially reset +static mi_segment_t* mi_segment_cache_pop(size_t segment_size, mi_segments_tld_t* tld) { + if (segment_size != 0 && segment_size != MI_SEGMENT_SIZE) return NULL; + mi_segment_t* segment = tld->cache; + if (segment == NULL) return NULL; + tld->cache_count--; + tld->cache = segment->next; + segment->next = NULL; + mi_assert_internal(segment->segment_size == MI_SEGMENT_SIZE); + _mi_stat_decrease(&tld->stats->segments_cache, 1); + return segment; +} + +static bool mi_segment_cache_full(mi_segments_tld_t* tld) +{ + // if (tld->count == 1 && tld->cache_count==0) return false; // always cache at least the final segment of a thread + size_t max_cache = mi_option_get(mi_option_segment_cache); + if (tld->cache_count < max_cache + && tld->cache_count < (1 + (tld->peak_count / MI_SEGMENT_CACHE_FRACTION)) // at least allow a 1 element cache + ) { + return false; + } + // take the opportunity to reduce the segment cache if it is too large (now) + // TODO: this never happens as we check against peak usage, should we use current usage instead? + while (tld->cache_count > max_cache) { //(1 + (tld->peak_count / MI_SEGMENT_CACHE_FRACTION))) { + mi_segment_t* segment = mi_segment_cache_pop(0,tld); + mi_assert_internal(segment != NULL); + if (segment != NULL) mi_segment_os_free(segment, segment->segment_size, tld); + } + return true; +} + +static bool mi_segment_cache_push(mi_segment_t* segment, mi_segments_tld_t* tld) { + mi_assert_internal(!mi_segment_is_in_free_queue(segment, tld)); + mi_assert_internal(segment->next == NULL); + if (segment->segment_size != MI_SEGMENT_SIZE || mi_segment_cache_full(tld)) { + return false; + } + mi_assert_internal(segment->segment_size == MI_SEGMENT_SIZE); + segment->next = tld->cache; + tld->cache = segment; + tld->cache_count++; + _mi_stat_increase(&tld->stats->segments_cache,1); + return true; +} + +// called by threads that are terminating to free cached segments +void _mi_segment_thread_collect(mi_segments_tld_t* tld) { + mi_segment_t* segment; + while ((segment = mi_segment_cache_pop(0,tld)) != NULL) { + mi_segment_os_free(segment, segment->segment_size, tld); + } + mi_assert_internal(tld->cache_count == 0); + mi_assert_internal(tld->cache == NULL); +#if MI_DEBUG>=2 + if (!_mi_is_main_thread()) { + mi_assert_internal(tld->pages_reset.first == NULL); + mi_assert_internal(tld->pages_reset.last == NULL); + } +#endif +} + + +/* ----------------------------------------------------------- + Segment allocation +----------------------------------------------------------- */ + +// Allocate a segment from the OS aligned to `MI_SEGMENT_SIZE` . +static mi_segment_t* mi_segment_init(mi_segment_t* segment, size_t required, mi_page_kind_t page_kind, size_t page_shift, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) +{ + // the segment parameter is non-null if it came from our cache + mi_assert_internal(segment==NULL || (required==0 && page_kind <= MI_PAGE_LARGE)); + + // calculate needed sizes first + size_t capacity; + if (page_kind == MI_PAGE_HUGE) { + mi_assert_internal(page_shift == MI_SEGMENT_SHIFT && required > 0); + capacity = 1; + } + else { + mi_assert_internal(required == 0); + size_t page_size = (size_t)1 << page_shift; + capacity = MI_SEGMENT_SIZE / page_size; + mi_assert_internal(MI_SEGMENT_SIZE % page_size == 0); + mi_assert_internal(capacity >= 1 && capacity <= MI_SMALL_PAGES_PER_SEGMENT); + } + size_t info_size; + size_t pre_size; + size_t segment_size = mi_segment_size(capacity, required, &pre_size, &info_size); + mi_assert_internal(segment_size >= required); + + // Initialize parameters + const bool eager_delayed = (page_kind <= MI_PAGE_MEDIUM && tld->count < (size_t)mi_option_get(mi_option_eager_commit_delay)); + const bool eager = !eager_delayed && mi_option_is_enabled(mi_option_eager_commit); + bool commit = eager; // || (page_kind >= MI_PAGE_LARGE); + bool pages_still_good = false; + bool is_zero = false; + + // Try to get it from our thread local cache first + if (segment != NULL) { + // came from cache + mi_assert_internal(segment->segment_size == segment_size); + if (page_kind <= MI_PAGE_MEDIUM && segment->page_kind == page_kind && segment->segment_size == segment_size) { + pages_still_good = true; + } + else + { + if (MI_SECURE!=0) { + mi_assert_internal(!segment->mem_is_fixed); + mi_segment_protect(segment, false, tld->os); // reset protection if the page kind differs + } + // different page kinds; unreset any reset pages, and unprotect + // TODO: optimize cache pop to return fitting pages if possible? + for (size_t i = 0; i < segment->capacity; i++) { + mi_page_t* page = &segment->pages[i]; + if (page->is_reset) { + if (!commit && mi_option_is_enabled(mi_option_reset_decommits)) { + page->is_reset = false; + } + else { + mi_page_unreset(segment, page, 0, tld); // todo: only unreset the part that was reset? (instead of the full page) + } + } + } + // ensure the initial info is committed + if (segment->capacity < capacity) { + bool commit_zero = false; + _mi_mem_commit(segment, pre_size, &commit_zero, tld->os); + if (commit_zero) is_zero = true; + } + } + } + else { + // Allocate the segment from the OS + size_t memid; + bool mem_large = (!eager_delayed && (MI_SECURE==0)); // only allow large OS pages once we are no longer lazy + segment = (mi_segment_t*)_mi_mem_alloc_aligned(segment_size, MI_SEGMENT_SIZE, &commit, &mem_large, &is_zero, &memid, os_tld); + if (segment == NULL) return NULL; // failed to allocate + if (!commit) { + // ensure the initial info is committed + bool commit_zero = false; + bool ok = _mi_mem_commit(segment, pre_size, &commit_zero, tld->os); + if (commit_zero) is_zero = true; + if (!ok) { + // commit failed; we cannot touch the memory: free the segment directly and return `NULL` + _mi_mem_free(segment, MI_SEGMENT_SIZE, memid, false, false, os_tld); + return NULL; + } + } + segment->memid = memid; + segment->mem_is_fixed = mem_large; + segment->mem_is_committed = commit; + mi_segments_track_size((long)segment_size, tld); + } + mi_assert_internal(segment != NULL && (uintptr_t)segment % MI_SEGMENT_SIZE == 0); + mi_assert_internal(segment->mem_is_fixed ? segment->mem_is_committed : true); + if (!pages_still_good) { + // zero the segment info (but not the `mem` fields) + ptrdiff_t ofs = offsetof(mi_segment_t, next); + memset((uint8_t*)segment + ofs, 0, info_size - ofs); + + // initialize pages info + for (uint8_t i = 0; i < capacity; i++) { + segment->pages[i].segment_idx = i; + segment->pages[i].is_reset = false; + segment->pages[i].is_committed = commit; + segment->pages[i].is_zero_init = is_zero; + } + } + else { + // zero the segment info but not the pages info (and mem fields) + ptrdiff_t ofs = offsetof(mi_segment_t, next); + memset((uint8_t*)segment + ofs, 0, offsetof(mi_segment_t,pages) - ofs); + } + + // initialize + segment->page_kind = page_kind; + segment->capacity = capacity; + segment->page_shift = page_shift; + segment->segment_size = segment_size; + segment->segment_info_size = pre_size; + segment->thread_id = _mi_thread_id(); + segment->cookie = _mi_ptr_cookie(segment); + // _mi_stat_increase(&tld->stats->page_committed, segment->segment_info_size); + + // set protection + mi_segment_protect(segment, true, tld->os); + + // insert in free lists for small and medium pages + if (page_kind <= MI_PAGE_MEDIUM) { + mi_segment_insert_in_free_queue(segment, tld); + } + + //fprintf(stderr,"mimalloc: alloc segment at %p\n", (void*)segment); + return segment; +} + +static mi_segment_t* mi_segment_alloc(size_t required, mi_page_kind_t page_kind, size_t page_shift, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { + return mi_segment_init(NULL, required, page_kind, page_shift, tld, os_tld); +} + +static void mi_segment_free(mi_segment_t* segment, bool force, mi_segments_tld_t* tld) { + UNUSED(force); + mi_assert(segment != NULL); + // note: don't reset pages even on abandon as the whole segment is freed? (and ready for reuse) + bool force_reset = (force && mi_option_is_enabled(mi_option_abandoned_page_reset)); + mi_pages_reset_remove_all_in_segment(segment, force_reset, tld); + mi_segment_remove_from_free_queue(segment,tld); + + mi_assert_expensive(!mi_segment_queue_contains(&tld->small_free, segment)); + mi_assert_expensive(!mi_segment_queue_contains(&tld->medium_free, segment)); + mi_assert(segment->next == NULL); + mi_assert(segment->prev == NULL); + _mi_stat_decrease(&tld->stats->page_committed, segment->segment_info_size); + + if (!force && mi_segment_cache_push(segment, tld)) { + // it is put in our cache + } + else { + // otherwise return it to the OS + mi_segment_os_free(segment, segment->segment_size, tld); + } +} + +/* ----------------------------------------------------------- + Free page management inside a segment +----------------------------------------------------------- */ + + +static bool mi_segment_has_free(const mi_segment_t* segment) { + return (segment->used < segment->capacity); +} + +static bool mi_segment_page_claim(mi_segment_t* segment, mi_page_t* page, mi_segments_tld_t* tld) { + mi_assert_internal(_mi_page_segment(page) == segment); + mi_assert_internal(!page->segment_in_use); + mi_pages_reset_remove(page, tld); + // check commit + if (!page->is_committed) { + mi_assert_internal(!segment->mem_is_fixed); + mi_assert_internal(!page->is_reset); + size_t psize; + uint8_t* start = mi_segment_raw_page_start(segment, page, &psize); + bool is_zero = false; + const size_t gsize = (MI_SECURE >= 2 ? _mi_os_page_size() : 0); + bool ok = _mi_mem_commit(start, psize + gsize, &is_zero, tld->os); + if (!ok) return false; // failed to commit! + if (gsize > 0) { mi_segment_protect_range(start + psize, gsize, true); } + if (is_zero) { page->is_zero_init = true; } + page->is_committed = true; + } + // set in-use before doing unreset to prevent delayed reset + page->segment_in_use = true; + segment->used++; + // check reset + if (page->is_reset) { + mi_assert_internal(!segment->mem_is_fixed); + bool ok = mi_page_unreset(segment, page, 0, tld); + if (!ok) { + page->segment_in_use = false; + segment->used--; + return false; + } + } + mi_assert_internal(page->segment_in_use); + mi_assert_internal(segment->used <= segment->capacity); + if (segment->used == segment->capacity && segment->page_kind <= MI_PAGE_MEDIUM) { + // if no more free pages, remove from the queue + mi_assert_internal(!mi_segment_has_free(segment)); + mi_segment_remove_from_free_queue(segment, tld); + } + return true; +} + + +/* ----------------------------------------------------------- + Free +----------------------------------------------------------- */ + +static void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld); + +// clear page data; can be called on abandoned segments +static void mi_segment_page_clear(mi_segment_t* segment, mi_page_t* page, bool allow_reset, mi_segments_tld_t* tld) +{ + mi_assert_internal(page->segment_in_use); + mi_assert_internal(mi_page_all_free(page)); + mi_assert_internal(page->is_committed); + mi_assert_internal(mi_page_not_in_queue(page, tld)); + + size_t inuse = page->capacity * mi_page_block_size(page); + _mi_stat_decrease(&tld->stats->page_committed, inuse); + _mi_stat_decrease(&tld->stats->pages, 1); + + // calculate the used size from the raw (non-aligned) start of the page + //size_t pre_size; + //_mi_segment_page_start(segment, page, page->block_size, NULL, &pre_size); + //size_t used_size = pre_size + (page->capacity * page->block_size); + + page->is_zero_init = false; + page->segment_in_use = false; + + // reset the page memory to reduce memory pressure? + // note: must come after setting `segment_in_use` to false but before block_size becomes 0 + //mi_page_reset(segment, page, 0 /*used_size*/, tld); + + // zero the page data, but not the segment fields and capacity, and block_size (for page size calculations) + uint32_t block_size = page->xblock_size; + uint16_t capacity = page->capacity; + uint16_t reserved = page->reserved; + ptrdiff_t ofs = offsetof(mi_page_t,capacity); + memset((uint8_t*)page + ofs, 0, sizeof(*page) - ofs); + page->capacity = capacity; + page->reserved = reserved; + page->xblock_size = block_size; + segment->used--; + + // add to the free page list for reuse/reset + if (allow_reset) { + mi_pages_reset_add(segment, page, tld); + } + + page->capacity = 0; // after reset there can be zero'd now + page->reserved = 0; +} + +void _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld) +{ + mi_assert(page != NULL); + mi_segment_t* segment = _mi_page_segment(page); + mi_assert_expensive(mi_segment_is_valid(segment,tld)); + mi_reset_delayed(tld); + + // mark it as free now + mi_segment_page_clear(segment, page, true, tld); + + if (segment->used == 0) { + // no more used pages; remove from the free list and free the segment + mi_segment_free(segment, force, tld); + } + else { + if (segment->used == segment->abandoned) { + // only abandoned pages; remove from free list and abandon + mi_segment_abandon(segment,tld); + } + else if (segment->used + 1 == segment->capacity) { + mi_assert_internal(segment->page_kind <= MI_PAGE_MEDIUM); // for now we only support small and medium pages + // move back to segments free list + mi_segment_insert_in_free_queue(segment,tld); + } + } +} + + +/* ----------------------------------------------------------- +Abandonment + +When threads terminate, they can leave segments with +live blocks (reached through other threads). Such segments +are "abandoned" and will be reclaimed by other threads to +reuse their pages and/or free them eventually + +We maintain a global list of abandoned segments that are +reclaimed on demand. Since this is shared among threads +the implementation needs to avoid the A-B-A problem on +popping abandoned segments: +We use tagged pointers to avoid accidentially identifying +reused segments, much like stamped references in Java. +Secondly, we maintain a reader counter to avoid resetting +or decommitting segments that have a pending read operation. + +Note: the current implementation is one possible design; +another way might be to keep track of abandoned segments +in the regions. This would have the advantage of keeping +all concurrent code in one place and not needing to deal +with ABA issues. The drawback is that it is unclear how to +scan abandoned segments efficiently in that case as they +would be spread among all other segments in the regions. +----------------------------------------------------------- */ + +// Use the bottom 20-bits (on 64-bit) of the aligned segment pointers +// to put in a tag that increments on update to avoid the A-B-A problem. +#define MI_TAGGED_MASK MI_SEGMENT_MASK +typedef uintptr_t mi_tagged_segment_t; + +static mi_segment_t* mi_tagged_segment_ptr(mi_tagged_segment_t ts) { + return (mi_segment_t*)(ts & ~MI_TAGGED_MASK); +} + +static mi_tagged_segment_t mi_tagged_segment(mi_segment_t* segment, mi_tagged_segment_t ts) { + mi_assert_internal(((uintptr_t)segment & MI_TAGGED_MASK) == 0); + uintptr_t tag = ((ts & MI_TAGGED_MASK) + 1) & MI_TAGGED_MASK; + return ((uintptr_t)segment | tag); +} + +// This is a list of visited abandoned pages that were full at the time. +// this list migrates to `abandoned` when that becomes NULL. The use of +// this list reduces contention and the rate at which segments are visited. +static mi_decl_cache_align volatile _Atomic(mi_segment_t*) abandoned_visited; // = NULL + +// The abandoned page list (tagged as it supports pop) +static mi_decl_cache_align volatile _Atomic(mi_tagged_segment_t) abandoned; // = NULL + +// We also maintain a count of current readers of the abandoned list +// in order to prevent resetting/decommitting segment memory if it might +// still be read. +static mi_decl_cache_align volatile _Atomic(uintptr_t) abandoned_readers; // = 0 + +// Push on the visited list +static void mi_abandoned_visited_push(mi_segment_t* segment) { + mi_assert_internal(segment->thread_id == 0); + mi_assert_internal(segment->abandoned_next == NULL); + mi_assert_internal(segment->next == NULL && segment->prev == NULL); + mi_assert_internal(segment->used > 0); + mi_segment_t* anext; + do { + anext = mi_atomic_read_ptr_relaxed(mi_segment_t, &abandoned_visited); + segment->abandoned_next = anext; + } while (!mi_atomic_cas_ptr_weak(mi_segment_t, &abandoned_visited, segment, anext)); +} + +// Move the visited list to the abandoned list. +static bool mi_abandoned_visited_revisit(void) +{ + // quick check if the visited list is empty + if (mi_atomic_read_ptr_relaxed(mi_segment_t,&abandoned_visited)==NULL) return false; + + // grab the whole visited list + mi_segment_t* first = mi_atomic_exchange_ptr(mi_segment_t, &abandoned_visited, NULL); + if (first == NULL) return false; + + // first try to swap directly if the abandoned list happens to be NULL + const mi_tagged_segment_t ts = mi_atomic_read_relaxed(&abandoned); + mi_tagged_segment_t afirst; + if (mi_tagged_segment_ptr(ts)==NULL) { + afirst = mi_tagged_segment(first, ts); + if (mi_atomic_cas_strong(&abandoned, afirst, ts)) return true; + } + + // find the last element of the visited list: O(n) + mi_segment_t* last = first; + while (last->abandoned_next != NULL) { + last = last->abandoned_next; + } + + // and atomically prepend to the abandoned list + // (no need to increase the readers as we don't access the abandoned segments) + mi_tagged_segment_t anext; + do { + anext = mi_atomic_read_relaxed(&abandoned); + last->abandoned_next = mi_tagged_segment_ptr(anext); + afirst = mi_tagged_segment(first, anext); + } while (!mi_atomic_cas_weak(&abandoned, afirst, anext)); + return true; +} + +// Push on the abandoned list. +static void mi_abandoned_push(mi_segment_t* segment) { + mi_assert_internal(segment->thread_id == 0); + mi_assert_internal(segment->abandoned_next == NULL); + mi_assert_internal(segment->next == NULL && segment->prev == NULL); + mi_assert_internal(segment->used > 0); + mi_tagged_segment_t ts; + mi_tagged_segment_t next; + do { + ts = mi_atomic_read_relaxed(&abandoned); + segment->abandoned_next = mi_tagged_segment_ptr(ts); + next = mi_tagged_segment(segment, ts); + } while (!mi_atomic_cas_weak(&abandoned, next, ts)); +} + +// Wait until there are no more pending reads on segments that used to be in the abandoned list +void _mi_abandoned_await_readers(void) { + uintptr_t n; + do { + n = mi_atomic_read(&abandoned_readers); + if (n != 0) mi_atomic_yield(); + } while (n != 0); +} + +// Pop from the abandoned list +static mi_segment_t* mi_abandoned_pop(void) { + mi_segment_t* segment; + // Check efficiently if it is empty (or if the visited list needs to be moved) + mi_tagged_segment_t ts = mi_atomic_read_relaxed(&abandoned); + segment = mi_tagged_segment_ptr(ts); + if (mi_likely(segment == NULL)) { + if (mi_likely(!mi_abandoned_visited_revisit())) { // try to swap in the visited list on NULL + return NULL; + } + } + + // Do a pop. We use a reader count to prevent + // a segment to be decommitted while a read is still pending, + // and a tagged pointer to prevent A-B-A link corruption. + // (this is called from `memory.c:_mi_mem_free` for example) + mi_atomic_increment(&abandoned_readers); // ensure no segment gets decommitted + mi_tagged_segment_t next = 0; + do { + ts = mi_atomic_read(&abandoned); + segment = mi_tagged_segment_ptr(ts); + if (segment != NULL) { + next = mi_tagged_segment(segment->abandoned_next, ts); // note: reads the segment's `abandoned_next` field so should not be decommitted + } + } while (segment != NULL && !mi_atomic_cas_weak(&abandoned, next, ts)); + mi_atomic_decrement(&abandoned_readers); // release reader lock + if (segment != NULL) { + segment->abandoned_next = NULL; + } + return segment; +} + +/* ----------------------------------------------------------- + Abandon segment/page +----------------------------------------------------------- */ + +static void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld) { + mi_assert_internal(segment->used == segment->abandoned); + mi_assert_internal(segment->used > 0); + mi_assert_internal(segment->abandoned_next == NULL); + mi_assert_expensive(mi_segment_is_valid(segment, tld)); + + // remove the segment from the free page queue if needed + mi_reset_delayed(tld); + mi_pages_reset_remove_all_in_segment(segment, mi_option_is_enabled(mi_option_abandoned_page_reset), tld); + mi_segment_remove_from_free_queue(segment, tld); + mi_assert_internal(segment->next == NULL && segment->prev == NULL); + + // all pages in the segment are abandoned; add it to the abandoned list + _mi_stat_increase(&tld->stats->segments_abandoned, 1); + mi_segments_track_size(-((long)segment->segment_size), tld); + segment->thread_id = 0; + segment->abandoned_next = NULL; + segment->abandoned_visits = 0; + mi_abandoned_push(segment); +} + +void _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld) { + mi_assert(page != NULL); + mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE); + mi_assert_internal(mi_page_heap(page) == NULL); + mi_segment_t* segment = _mi_page_segment(page); + mi_assert_expensive(!mi_pages_reset_contains(page, tld)); + mi_assert_expensive(mi_segment_is_valid(segment, tld)); + segment->abandoned++; + _mi_stat_increase(&tld->stats->pages_abandoned, 1); + mi_assert_internal(segment->abandoned <= segment->used); + if (segment->used == segment->abandoned) { + // all pages are abandoned, abandon the entire segment + mi_segment_abandon(segment, tld); + } +} + +/* ----------------------------------------------------------- + Reclaim abandoned pages +----------------------------------------------------------- */ + +// Possibly clear pages and check if free space is available +static bool mi_segment_check_free(mi_segment_t* segment, size_t block_size, bool* all_pages_free) +{ + mi_assert_internal(block_size < MI_HUGE_BLOCK_SIZE); + bool has_page = false; + size_t pages_used = 0; + size_t pages_used_empty = 0; + for (size_t i = 0; i < segment->capacity; i++) { + mi_page_t* page = &segment->pages[i]; + if (page->segment_in_use) { + pages_used++; + // ensure used count is up to date and collect potential concurrent frees + _mi_page_free_collect(page, false); + if (mi_page_all_free(page)) { + // if everything free already, page can be reused for some block size + // note: don't clear the page yet as we can only OS reset it once it is reclaimed + pages_used_empty++; + has_page = true; + } + else if (page->xblock_size == block_size && mi_page_has_any_available(page)) { + // a page has available free blocks of the right size + has_page = true; + } + } + else { + // whole empty page + has_page = true; + } + } + mi_assert_internal(pages_used == segment->used && pages_used >= pages_used_empty); + if (all_pages_free != NULL) { + *all_pages_free = ((pages_used - pages_used_empty) == 0); + } + return has_page; +} + + +// Reclaim a segment; returns NULL if the segment was freed +// set `right_page_reclaimed` to `true` if it reclaimed a page of the right `block_size` that was not full. +static mi_segment_t* mi_segment_reclaim(mi_segment_t* segment, mi_heap_t* heap, size_t requested_block_size, bool* right_page_reclaimed, mi_segments_tld_t* tld) { + mi_assert_internal(segment->abandoned_next == NULL); + if (right_page_reclaimed != NULL) { *right_page_reclaimed = false; } + + segment->thread_id = _mi_thread_id(); + segment->abandoned_visits = 0; + mi_segments_track_size((long)segment->segment_size, tld); + mi_assert_internal(segment->next == NULL && segment->prev == NULL); + mi_assert_expensive(mi_segment_is_valid(segment, tld)); + _mi_stat_decrease(&tld->stats->segments_abandoned, 1); + + for (size_t i = 0; i < segment->capacity; i++) { + mi_page_t* page = &segment->pages[i]; + if (page->segment_in_use) { + mi_assert_internal(!page->is_reset); + mi_assert_internal(page->is_committed); + mi_assert_internal(mi_page_not_in_queue(page, tld)); + mi_assert_internal(mi_page_thread_free_flag(page)==MI_NEVER_DELAYED_FREE); + mi_assert_internal(mi_page_heap(page) == NULL); + segment->abandoned--; + mi_assert(page->next == NULL); + _mi_stat_decrease(&tld->stats->pages_abandoned, 1); + // set the heap again and allow heap thread delayed free again. + mi_page_set_heap(page, heap); + _mi_page_use_delayed_free(page, MI_USE_DELAYED_FREE, true); // override never (after heap is set) + // TODO: should we not collect again given that we just collected in `check_free`? + _mi_page_free_collect(page, false); // ensure used count is up to date + if (mi_page_all_free(page)) { + // if everything free already, clear the page directly + mi_segment_page_clear(segment, page, true, tld); // reset is ok now + } + else { + // otherwise reclaim it into the heap + _mi_page_reclaim(heap, page); + if (requested_block_size == page->xblock_size && mi_page_has_any_available(page)) { + if (right_page_reclaimed != NULL) { *right_page_reclaimed = true; } + } + } + } + else if (page->is_committed && !page->is_reset) { // not in-use, and not reset yet + // note: do not reset as this includes pages that were not touched before + // mi_pages_reset_add(segment, page, tld); + } + } + mi_assert_internal(segment->abandoned == 0); + if (segment->used == 0) { + mi_assert_internal(right_page_reclaimed == NULL || !(*right_page_reclaimed)); + mi_segment_free(segment, false, tld); + return NULL; + } + else { + if (segment->page_kind <= MI_PAGE_MEDIUM && mi_segment_has_free(segment)) { + mi_segment_insert_in_free_queue(segment, tld); + } + return segment; + } +} + + +void _mi_abandoned_reclaim_all(mi_heap_t* heap, mi_segments_tld_t* tld) { + mi_segment_t* segment; + while ((segment = mi_abandoned_pop()) != NULL) { + mi_segment_reclaim(segment, heap, 0, NULL, tld); + } +} + +static mi_segment_t* mi_segment_try_reclaim(mi_heap_t* heap, size_t block_size, mi_page_kind_t page_kind, bool* reclaimed, mi_segments_tld_t* tld) +{ + *reclaimed = false; + mi_segment_t* segment; + int max_tries = 8; // limit the work to bound allocation times + while ((max_tries-- > 0) && ((segment = mi_abandoned_pop()) != NULL)) { + segment->abandoned_visits++; + bool all_pages_free; + bool has_page = mi_segment_check_free(segment,block_size,&all_pages_free); // try to free up pages (due to concurrent frees) + if (all_pages_free) { + // free the segment (by forced reclaim) to make it available to other threads. + // note1: we prefer to free a segment as that might lead to reclaiming another + // segment that is still partially used. + // note2: we could in principle optimize this by skipping reclaim and directly + // freeing but that would violate some invariants temporarily) + mi_segment_reclaim(segment, heap, 0, NULL, tld); + } + else if (has_page && segment->page_kind == page_kind) { + // found a free page of the right kind, or page of the right block_size with free space + // we return the result of reclaim (which is usually `segment`) as it might free + // the segment due to concurrent frees (in which case `NULL` is returned). + return mi_segment_reclaim(segment, heap, block_size, reclaimed, tld); + } + else if (segment->abandoned_visits >= 3) { + // always reclaim on 3rd visit to limit the list length. + mi_segment_reclaim(segment, heap, 0, NULL, tld); + } + else { + // otherwise, push on the visited list so it gets not looked at too quickly again + mi_abandoned_visited_push(segment); + } + } + return NULL; +} + + +/* ----------------------------------------------------------- + Reclaim or allocate +----------------------------------------------------------- */ + +static mi_segment_t* mi_segment_reclaim_or_alloc(mi_heap_t* heap, size_t block_size, mi_page_kind_t page_kind, size_t page_shift, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) +{ + mi_assert_internal(page_kind <= MI_PAGE_LARGE); + mi_assert_internal(block_size < MI_HUGE_BLOCK_SIZE); + // 1. try to get a segment from our cache + mi_segment_t* segment = mi_segment_cache_pop(MI_SEGMENT_SIZE, tld); + if (segment != NULL) { + mi_segment_init(segment, 0, page_kind, page_shift, tld, os_tld); + return segment; + } + // 2. try to reclaim an abandoned segment + bool reclaimed; + segment = mi_segment_try_reclaim(heap, block_size, page_kind, &reclaimed, tld); + if (reclaimed) { + // reclaimed the right page right into the heap + mi_assert_internal(segment != NULL && segment->page_kind == page_kind && page_kind <= MI_PAGE_LARGE); + return NULL; // pretend out-of-memory as the page will be in the page queue of the heap with available blocks + } + else if (segment != NULL) { + // reclaimed a segment with empty pages (of `page_kind`) in it + return segment; + } + // 3. otherwise allocate a fresh segment + return mi_segment_alloc(0, page_kind, page_shift, tld, os_tld); +} + + +/* ----------------------------------------------------------- + Small page allocation +----------------------------------------------------------- */ + +static mi_page_t* mi_segment_find_free(mi_segment_t* segment, mi_segments_tld_t* tld) { + mi_assert_internal(mi_segment_has_free(segment)); + mi_assert_expensive(mi_segment_is_valid(segment, tld)); + for (size_t i = 0; i < segment->capacity; i++) { // TODO: use a bitmap instead of search? + mi_page_t* page = &segment->pages[i]; + if (!page->segment_in_use) { + bool ok = mi_segment_page_claim(segment, page, tld); + if (ok) return page; + } + } + mi_assert(false); + return NULL; +} + +// Allocate a page inside a segment. Requires that the page has free pages +static mi_page_t* mi_segment_page_alloc_in(mi_segment_t* segment, mi_segments_tld_t* tld) { + mi_assert_internal(mi_segment_has_free(segment)); + return mi_segment_find_free(segment, tld); +} + +static mi_page_t* mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, mi_page_kind_t kind, size_t page_shift, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { + // find an available segment the segment free queue + mi_segment_queue_t* const free_queue = mi_segment_free_queue_of_kind(kind, tld); + if (mi_segment_queue_is_empty(free_queue)) { + // possibly allocate or reclaim a fresh segment + mi_segment_t* const segment = mi_segment_reclaim_or_alloc(heap, block_size, kind, page_shift, tld, os_tld); + if (segment == NULL) return NULL; // return NULL if out-of-memory (or reclaimed) + mi_assert_internal(free_queue->first == segment); + mi_assert_internal(segment->page_kind==kind); + mi_assert_internal(segment->used < segment->capacity); + } + mi_assert_internal(free_queue->first != NULL); + mi_page_t* const page = mi_segment_page_alloc_in(free_queue->first, tld); + mi_assert_internal(page != NULL); +#if MI_DEBUG>=2 + // verify it is committed + _mi_segment_page_start(_mi_page_segment(page), page, sizeof(void*), NULL, NULL)[0] = 0; +#endif + return page; +} + +static mi_page_t* mi_segment_small_page_alloc(mi_heap_t* heap, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { + return mi_segment_page_alloc(heap, block_size, MI_PAGE_SMALL,MI_SMALL_PAGE_SHIFT,tld,os_tld); +} + +static mi_page_t* mi_segment_medium_page_alloc(mi_heap_t* heap, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { + return mi_segment_page_alloc(heap, block_size, MI_PAGE_MEDIUM, MI_MEDIUM_PAGE_SHIFT, tld, os_tld); +} + +/* ----------------------------------------------------------- + large page allocation +----------------------------------------------------------- */ + +static mi_page_t* mi_segment_large_page_alloc(mi_heap_t* heap, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { + mi_segment_t* segment = mi_segment_reclaim_or_alloc(heap,block_size,MI_PAGE_LARGE,MI_LARGE_PAGE_SHIFT,tld,os_tld); + if (segment == NULL) return NULL; + mi_page_t* page = mi_segment_find_free(segment, tld); + mi_assert_internal(page != NULL); +#if MI_DEBUG>=2 + _mi_segment_page_start(segment, page, sizeof(void*), NULL, NULL)[0] = 0; +#endif + return page; +} + +static mi_page_t* mi_segment_huge_page_alloc(size_t size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) +{ + mi_segment_t* segment = mi_segment_alloc(size, MI_PAGE_HUGE, MI_SEGMENT_SHIFT,tld,os_tld); + if (segment == NULL) return NULL; + mi_assert_internal(mi_segment_page_size(segment) - segment->segment_info_size - (2*(MI_SECURE == 0 ? 0 : _mi_os_page_size())) >= size); + segment->thread_id = 0; // huge pages are immediately abandoned + mi_segments_track_size(-(long)segment->segment_size, tld); + mi_page_t* page = mi_segment_find_free(segment, tld); + mi_assert_internal(page != NULL); + return page; +} + +// free huge block from another thread +void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block) { + // huge page segments are always abandoned and can be freed immediately by any thread + mi_assert_internal(segment->page_kind==MI_PAGE_HUGE); + mi_assert_internal(segment == _mi_page_segment(page)); + mi_assert_internal(mi_atomic_read_relaxed(&segment->thread_id)==0); + + // claim it and free + mi_heap_t* heap = mi_heap_get_default(); // issue #221; don't use the internal get_default_heap as we need to ensure the thread is initialized. + // paranoia: if this it the last reference, the cas should always succeed + if (mi_atomic_cas_strong(&segment->thread_id, heap->thread_id, 0)) { + mi_block_set_next(page, block, page->free); + page->free = block; + page->used--; + page->is_zero = false; + mi_assert(page->used == 0); + mi_tld_t* tld = heap->tld; + const size_t bsize = mi_page_usable_block_size(page); + if (bsize > MI_HUGE_OBJ_SIZE_MAX) { + _mi_stat_decrease(&tld->stats.giant, bsize); + } + else { + _mi_stat_decrease(&tld->stats.huge, bsize); + } + mi_segments_track_size((long)segment->segment_size, &tld->segments); + _mi_segment_page_free(page, true, &tld->segments); + } +} + +/* ----------------------------------------------------------- + Page allocation +----------------------------------------------------------- */ + +mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) { + mi_page_t* page; + if (block_size <= MI_SMALL_OBJ_SIZE_MAX) { + page = mi_segment_small_page_alloc(heap, block_size, tld, os_tld); + } + else if (block_size <= MI_MEDIUM_OBJ_SIZE_MAX) { + page = mi_segment_medium_page_alloc(heap, block_size, tld, os_tld); + } + else if (block_size <= MI_LARGE_OBJ_SIZE_MAX) { + page = mi_segment_large_page_alloc(heap, block_size, tld, os_tld); + } + else { + page = mi_segment_huge_page_alloc(block_size,tld,os_tld); + } + mi_assert_expensive(page == NULL || mi_segment_is_valid(_mi_page_segment(page),tld)); + mi_assert_internal(page == NULL || (mi_segment_page_size(_mi_page_segment(page)) - (MI_SECURE == 0 ? 0 : _mi_os_page_size())) >= block_size); + mi_reset_delayed(tld); + mi_assert_internal(page == NULL || mi_page_not_in_queue(page, tld)); + return page; +} diff --git a/extlib/mimalloc/src/static.c b/extlib/mimalloc/src/static.c new file mode 100644 index 0000000..d024b01 --- /dev/null +++ b/extlib/mimalloc/src/static.c @@ -0,0 +1,38 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE +#endif +#if defined(__sun) +// same remarks as os.c for the static's context. +#undef _XOPEN_SOURCE +#undef _POSIX_C_SOURCE +#endif + +#include "mimalloc.h" +#include "mimalloc-internal.h" + +// For a static override we create a single object file +// containing the whole library. If it is linked first +// it will override all the standard library allocation +// functions (on Unix's). +#include "stats.c" +#include "random.c" +#include "os.c" +#include "arena.c" +#include "region.c" +#include "segment.c" +#include "page.c" +#include "heap.c" +#include "alloc.c" +#include "alloc-aligned.c" +#include "alloc-posix.c" +#if MI_OSX_ZONE +#include "alloc-override-osx.c" +#endif +#include "init.c" +#include "options.c" diff --git a/extlib/mimalloc/src/stats.c b/extlib/mimalloc/src/stats.c new file mode 100644 index 0000000..203bad8 --- /dev/null +++ b/extlib/mimalloc/src/stats.c @@ -0,0 +1,532 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ +#include "mimalloc.h" +#include "mimalloc-internal.h" +#include "mimalloc-atomic.h" + +#include // fputs, stderr +#include // memset + + +/* ----------------------------------------------------------- + Statistics operations +----------------------------------------------------------- */ + +static bool mi_is_in_main(void* stat) { + return ((uint8_t*)stat >= (uint8_t*)&_mi_stats_main + && (uint8_t*)stat < ((uint8_t*)&_mi_stats_main + sizeof(mi_stats_t))); +} + +static void mi_stat_update(mi_stat_count_t* stat, int64_t amount) { + if (amount == 0) return; + if (mi_is_in_main(stat)) + { + // add atomically (for abandoned pages) + mi_atomic_addi64(&stat->current,amount); + mi_atomic_maxi64(&stat->peak, mi_atomic_readi64(&stat->current)); + if (amount > 0) { + mi_atomic_addi64(&stat->allocated,amount); + } + else { + mi_atomic_addi64(&stat->freed, -amount); + } + } + else { + // add thread local + stat->current += amount; + if (stat->current > stat->peak) stat->peak = stat->current; + if (amount > 0) { + stat->allocated += amount; + } + else { + stat->freed += -amount; + } + } +} + +void _mi_stat_counter_increase(mi_stat_counter_t* stat, size_t amount) { + if (mi_is_in_main(stat)) { + mi_atomic_addi64( &stat->count, 1 ); + mi_atomic_addi64( &stat->total, (int64_t)amount ); + } + else { + stat->count++; + stat->total += amount; + } +} + +void _mi_stat_increase(mi_stat_count_t* stat, size_t amount) { + mi_stat_update(stat, (int64_t)amount); +} + +void _mi_stat_decrease(mi_stat_count_t* stat, size_t amount) { + mi_stat_update(stat, -((int64_t)amount)); +} + +// must be thread safe as it is called from stats_merge +static void mi_stat_add(mi_stat_count_t* stat, const mi_stat_count_t* src, int64_t unit) { + if (stat==src) return; + if (src->allocated==0 && src->freed==0) return; + mi_atomic_addi64( &stat->allocated, src->allocated * unit); + mi_atomic_addi64( &stat->current, src->current * unit); + mi_atomic_addi64( &stat->freed, src->freed * unit); + // peak scores do not work across threads.. + mi_atomic_addi64( &stat->peak, src->peak * unit); +} + +static void mi_stat_counter_add(mi_stat_counter_t* stat, const mi_stat_counter_t* src, int64_t unit) { + if (stat==src) return; + mi_atomic_addi64( &stat->total, src->total * unit); + mi_atomic_addi64( &stat->count, src->count * unit); +} + +// must be thread safe as it is called from stats_merge +static void mi_stats_add(mi_stats_t* stats, const mi_stats_t* src) { + if (stats==src) return; + mi_stat_add(&stats->segments, &src->segments,1); + mi_stat_add(&stats->pages, &src->pages,1); + mi_stat_add(&stats->reserved, &src->reserved, 1); + mi_stat_add(&stats->committed, &src->committed, 1); + mi_stat_add(&stats->reset, &src->reset, 1); + mi_stat_add(&stats->page_committed, &src->page_committed, 1); + + mi_stat_add(&stats->pages_abandoned, &src->pages_abandoned, 1); + mi_stat_add(&stats->segments_abandoned, &src->segments_abandoned, 1); + mi_stat_add(&stats->threads, &src->threads, 1); + + mi_stat_add(&stats->malloc, &src->malloc, 1); + mi_stat_add(&stats->segments_cache, &src->segments_cache, 1); + mi_stat_add(&stats->huge, &src->huge, 1); + mi_stat_add(&stats->giant, &src->giant, 1); + + mi_stat_counter_add(&stats->pages_extended, &src->pages_extended, 1); + mi_stat_counter_add(&stats->mmap_calls, &src->mmap_calls, 1); + mi_stat_counter_add(&stats->commit_calls, &src->commit_calls, 1); + + mi_stat_counter_add(&stats->page_no_retire, &src->page_no_retire, 1); + mi_stat_counter_add(&stats->searches, &src->searches, 1); + mi_stat_counter_add(&stats->huge_count, &src->huge_count, 1); + mi_stat_counter_add(&stats->giant_count, &src->giant_count, 1); +#if MI_STAT>1 + for (size_t i = 0; i <= MI_BIN_HUGE; i++) { + if (src->normal[i].allocated > 0 || src->normal[i].freed > 0) { + mi_stat_add(&stats->normal[i], &src->normal[i], 1); + } + } +#endif +} + +/* ----------------------------------------------------------- + Display statistics +----------------------------------------------------------- */ + +// unit > 0 : size in binary bytes +// unit == 0: count as decimal +// unit < 0 : count in binary +static void mi_printf_amount(int64_t n, int64_t unit, mi_output_fun* out, void* arg, const char* fmt) { + char buf[32]; + int len = 32; + const char* suffix = (unit <= 0 ? " " : "b"); + const int64_t base = (unit == 0 ? 1000 : 1024); + if (unit>0) n *= unit; + + const int64_t pos = (n < 0 ? -n : n); + if (pos < base) { + snprintf(buf, len, "%d %s ", (int)n, suffix); + } + else { + int64_t divider = base; + const char* magnitude = "k"; + if (pos >= divider*base) { divider *= base; magnitude = "m"; } + if (pos >= divider*base) { divider *= base; magnitude = "g"; } + const int64_t tens = (n / (divider/10)); + const long whole = (long)(tens/10); + const long frac1 = (long)(tens%10); + snprintf(buf, len, "%ld.%ld %s%s", whole, frac1, magnitude, suffix); + } + _mi_fprintf(out, arg, (fmt==NULL ? "%11s" : fmt), buf); +} + + +static void mi_print_amount(int64_t n, int64_t unit, mi_output_fun* out, void* arg) { + mi_printf_amount(n,unit,out,arg,NULL); +} + +static void mi_print_count(int64_t n, int64_t unit, mi_output_fun* out, void* arg) { + if (unit==1) _mi_fprintf(out, arg, "%11s"," "); + else mi_print_amount(n,0,out,arg); +} + +static void mi_stat_print(const mi_stat_count_t* stat, const char* msg, int64_t unit, mi_output_fun* out, void* arg ) { + _mi_fprintf(out, arg,"%10s:", msg); + if (unit>0) { + mi_print_amount(stat->peak, unit, out, arg); + mi_print_amount(stat->allocated, unit, out, arg); + mi_print_amount(stat->freed, unit, out, arg); + mi_print_amount(unit, 1, out, arg); + mi_print_count(stat->allocated, unit, out, arg); + if (stat->allocated > stat->freed) + _mi_fprintf(out, arg, " not all freed!\n"); + else + _mi_fprintf(out, arg, " ok\n"); + } + else if (unit<0) { + mi_print_amount(stat->peak, -1, out, arg); + mi_print_amount(stat->allocated, -1, out, arg); + mi_print_amount(stat->freed, -1, out, arg); + if (unit==-1) { + _mi_fprintf(out, arg, "%22s", ""); + } + else { + mi_print_amount(-unit, 1, out, arg); + mi_print_count((stat->allocated / -unit), 0, out, arg); + } + if (stat->allocated > stat->freed) + _mi_fprintf(out, arg, " not all freed!\n"); + else + _mi_fprintf(out, arg, " ok\n"); + } + else { + mi_print_amount(stat->peak, 1, out, arg); + mi_print_amount(stat->allocated, 1, out, arg); + _mi_fprintf(out, arg, "\n"); + } +} + +static void mi_stat_counter_print(const mi_stat_counter_t* stat, const char* msg, mi_output_fun* out, void* arg ) { + _mi_fprintf(out, arg, "%10s:", msg); + mi_print_amount(stat->total, -1, out, arg); + _mi_fprintf(out, arg, "\n"); +} + +static void mi_stat_counter_print_avg(const mi_stat_counter_t* stat, const char* msg, mi_output_fun* out, void* arg) { + const int64_t avg_tens = (stat->count == 0 ? 0 : (stat->total*10 / stat->count)); + const long avg_whole = (long)(avg_tens/10); + const long avg_frac1 = (long)(avg_tens%10); + _mi_fprintf(out, arg, "%10s: %5ld.%ld avg\n", msg, avg_whole, avg_frac1); +} + + +static void mi_print_header(mi_output_fun* out, void* arg ) { + _mi_fprintf(out, arg, "%10s: %10s %10s %10s %10s %10s\n", "heap stats", "peak ", "total ", "freed ", "unit ", "count "); +} + +#if MI_STAT>1 +static void mi_stats_print_bins(mi_stat_count_t* all, const mi_stat_count_t* bins, size_t max, const char* fmt, mi_output_fun* out, void* arg) { + bool found = false; + char buf[64]; + for (size_t i = 0; i <= max; i++) { + if (bins[i].allocated > 0) { + found = true; + int64_t unit = _mi_bin_size((uint8_t)i); + snprintf(buf, 64, "%s %3zu", fmt, i); + mi_stat_add(all, &bins[i], unit); + mi_stat_print(&bins[i], buf, unit, out, arg); + } + } + //snprintf(buf, 64, "%s all", fmt); + //mi_stat_print(all, buf, 1); + if (found) { + _mi_fprintf(out, arg, "\n"); + mi_print_header(out, arg); + } +} +#endif + + + +//------------------------------------------------------------ +// Use an output wrapper for line-buffered output +// (which is nice when using loggers etc.) +//------------------------------------------------------------ +typedef struct buffered_s { + mi_output_fun* out; // original output function + void* arg; // and state + char* buf; // local buffer of at least size `count+1` + size_t used; // currently used chars `used <= count` + size_t count; // total chars available for output +} buffered_t; + +static void mi_buffered_flush(buffered_t* buf) { + buf->buf[buf->used] = 0; + _mi_fputs(buf->out, buf->arg, NULL, buf->buf); + buf->used = 0; +} + +static void mi_buffered_out(const char* msg, void* arg) { + buffered_t* buf = (buffered_t*)arg; + if (msg==NULL || buf==NULL) return; + for (const char* src = msg; *src != 0; src++) { + char c = *src; + if (buf->used >= buf->count) mi_buffered_flush(buf); + mi_assert_internal(buf->used < buf->count); + buf->buf[buf->used++] = c; + if (c == '\n') mi_buffered_flush(buf); + } +} + +//------------------------------------------------------------ +// Print statistics +//------------------------------------------------------------ + +static void mi_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* peak_rss, size_t* page_faults, size_t* page_reclaim, size_t* peak_commit); + +static void _mi_stats_print(mi_stats_t* stats, mi_msecs_t elapsed, mi_output_fun* out0, void* arg0) mi_attr_noexcept { + // wrap the output function to be line buffered + char buf[256]; + buffered_t buffer = { out0, arg0, buf, 0, 255 }; + mi_output_fun* out = &mi_buffered_out; + void* arg = &buffer; + + // and print using that + mi_print_header(out,arg); + #if MI_STAT>1 + mi_stat_count_t normal = { 0,0,0,0 }; + mi_stats_print_bins(&normal, stats->normal, MI_BIN_HUGE, "normal",out,arg); + mi_stat_print(&normal, "normal", 1, out, arg); + mi_stat_print(&stats->huge, "huge", (stats->huge_count.count == 0 ? 1 : -(stats->huge.allocated / stats->huge_count.count)), out, arg); + mi_stat_print(&stats->giant, "giant", (stats->giant_count.count == 0 ? 1 : -(stats->giant.allocated / stats->giant_count.count)), out, arg); + mi_stat_count_t total = { 0,0,0,0 }; + mi_stat_add(&total, &normal, 1); + mi_stat_add(&total, &stats->huge, 1); + mi_stat_add(&total, &stats->giant, 1); + mi_stat_print(&total, "total", 1, out, arg); + _mi_fprintf(out, arg, "malloc requested: "); + mi_print_amount(stats->malloc.allocated, 1, out, arg); + _mi_fprintf(out, arg, "\n\n"); + #endif + mi_stat_print(&stats->reserved, "reserved", 1, out, arg); + mi_stat_print(&stats->committed, "committed", 1, out, arg); + mi_stat_print(&stats->reset, "reset", 1, out, arg); + mi_stat_print(&stats->page_committed, "touched", 1, out, arg); + mi_stat_print(&stats->segments, "segments", -1, out, arg); + mi_stat_print(&stats->segments_abandoned, "-abandoned", -1, out, arg); + mi_stat_print(&stats->segments_cache, "-cached", -1, out, arg); + mi_stat_print(&stats->pages, "pages", -1, out, arg); + mi_stat_print(&stats->pages_abandoned, "-abandoned", -1, out, arg); + mi_stat_counter_print(&stats->pages_extended, "-extended", out, arg); + mi_stat_counter_print(&stats->page_no_retire, "-noretire", out, arg); + mi_stat_counter_print(&stats->mmap_calls, "mmaps", out, arg); + mi_stat_counter_print(&stats->commit_calls, "commits", out, arg); + mi_stat_print(&stats->threads, "threads", -1, out, arg); + mi_stat_counter_print_avg(&stats->searches, "searches", out, arg); + _mi_fprintf(out, arg, "%10s: %7i\n", "numa nodes", _mi_os_numa_node_count()); + if (elapsed > 0) _mi_fprintf(out, arg, "%10s: %7ld.%03ld s\n", "elapsed", elapsed/1000, elapsed%1000); + + mi_msecs_t user_time; + mi_msecs_t sys_time; + size_t peak_rss; + size_t page_faults; + size_t page_reclaim; + size_t peak_commit; + mi_process_info(&user_time, &sys_time, &peak_rss, &page_faults, &page_reclaim, &peak_commit); + _mi_fprintf(out, arg, "%10s: user: %ld.%03ld s, system: %ld.%03ld s, faults: %lu, reclaims: %lu, rss: ", "process", user_time/1000, user_time%1000, sys_time/1000, sys_time%1000, (unsigned long)page_faults, (unsigned long)page_reclaim ); + mi_printf_amount((int64_t)peak_rss, 1, out, arg, "%s"); + if (peak_commit > 0) { + _mi_fprintf(out, arg, ", commit charge: "); + mi_printf_amount((int64_t)peak_commit, 1, out, arg, "%s"); + } + _mi_fprintf(out, arg, "\n"); +} + +static mi_msecs_t mi_time_start; // = 0 + +static mi_stats_t* mi_stats_get_default(void) { + mi_heap_t* heap = mi_heap_get_default(); + return &heap->tld->stats; +} + +static void mi_stats_merge_from(mi_stats_t* stats) { + if (stats != &_mi_stats_main) { + mi_stats_add(&_mi_stats_main, stats); + memset(stats, 0, sizeof(mi_stats_t)); + } +} + +void mi_stats_reset(void) mi_attr_noexcept { + mi_stats_t* stats = mi_stats_get_default(); + if (stats != &_mi_stats_main) { memset(stats, 0, sizeof(mi_stats_t)); } + memset(&_mi_stats_main, 0, sizeof(mi_stats_t)); + mi_time_start = _mi_clock_start(); +} + +void mi_stats_merge(void) mi_attr_noexcept { + mi_stats_merge_from( mi_stats_get_default() ); +} + +void _mi_stats_done(mi_stats_t* stats) { // called from `mi_thread_done` + mi_stats_merge_from(stats); +} + +void mi_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept { + mi_msecs_t elapsed = _mi_clock_end(mi_time_start); + mi_stats_merge_from(mi_stats_get_default()); + _mi_stats_print(&_mi_stats_main, elapsed, out, arg); +} + +void mi_stats_print(void* out) mi_attr_noexcept { + // for compatibility there is an `out` parameter (which can be `stdout` or `stderr`) + mi_stats_print_out((mi_output_fun*)out, NULL); +} + +void mi_thread_stats_print_out(mi_output_fun* out, void* arg) mi_attr_noexcept { + mi_msecs_t elapsed = _mi_clock_end(mi_time_start); + _mi_stats_print(mi_stats_get_default(), elapsed, out, arg); +} + + +// ---------------------------------------------------------------- +// Basic timer for convenience; use milli-seconds to avoid doubles +// ---------------------------------------------------------------- +#ifdef _WIN32 +#include +static mi_msecs_t mi_to_msecs(LARGE_INTEGER t) { + static LARGE_INTEGER mfreq; // = 0 + if (mfreq.QuadPart == 0LL) { + LARGE_INTEGER f; + QueryPerformanceFrequency(&f); + mfreq.QuadPart = f.QuadPart/1000LL; + if (mfreq.QuadPart == 0) mfreq.QuadPart = 1; + } + return (mi_msecs_t)(t.QuadPart / mfreq.QuadPart); +} + +mi_msecs_t _mi_clock_now(void) { + LARGE_INTEGER t; + QueryPerformanceCounter(&t); + return mi_to_msecs(t); +} +#else +#include +#ifdef CLOCK_REALTIME +mi_msecs_t _mi_clock_now(void) { + struct timespec t; + clock_gettime(CLOCK_REALTIME, &t); + return ((mi_msecs_t)t.tv_sec * 1000) + ((mi_msecs_t)t.tv_nsec / 1000000); +} +#else +// low resolution timer +mi_msecs_t _mi_clock_now(void) { + return ((mi_msecs_t)clock() / ((mi_msecs_t)CLOCKS_PER_SEC / 1000)); +} +#endif +#endif + + +static mi_msecs_t mi_clock_diff; + +mi_msecs_t _mi_clock_start(void) { + if (mi_clock_diff == 0.0) { + mi_msecs_t t0 = _mi_clock_now(); + mi_clock_diff = _mi_clock_now() - t0; + } + return _mi_clock_now(); +} + +mi_msecs_t _mi_clock_end(mi_msecs_t start) { + mi_msecs_t end = _mi_clock_now(); + return (end - start - mi_clock_diff); +} + + +// -------------------------------------------------------- +// Basic process statistics +// -------------------------------------------------------- + +#if defined(_WIN32) +#include +#include +#pragma comment(lib,"psapi.lib") + +static mi_msecs_t filetime_msecs(const FILETIME* ftime) { + ULARGE_INTEGER i; + i.LowPart = ftime->dwLowDateTime; + i.HighPart = ftime->dwHighDateTime; + mi_msecs_t msecs = (i.QuadPart / 10000); // FILETIME is in 100 nano seconds + return msecs; +} +static void mi_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* peak_rss, size_t* page_faults, size_t* page_reclaim, size_t* peak_commit) { + FILETIME ct; + FILETIME ut; + FILETIME st; + FILETIME et; + GetProcessTimes(GetCurrentProcess(), &ct, &et, &st, &ut); + *utime = filetime_msecs(&ut); + *stime = filetime_msecs(&st); + + PROCESS_MEMORY_COUNTERS info; + GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info)); + *peak_rss = (size_t)info.PeakWorkingSetSize; + *page_faults = (size_t)info.PageFaultCount; + *peak_commit = (size_t)info.PeakPagefileUsage; + *page_reclaim = 0; +} + +#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) || defined(__HAIKU__) +#include +#include +#include + +#if defined(__APPLE__) && defined(__MACH__) +#include +#endif + +#if defined(__HAIKU__) +#include +#endif + +static mi_msecs_t timeval_secs(const struct timeval* tv) { + return ((mi_msecs_t)tv->tv_sec * 1000L) + ((mi_msecs_t)tv->tv_usec / 1000L); +} + +static void mi_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* peak_rss, size_t* page_faults, size_t* page_reclaim, size_t* peak_commit) { + struct rusage rusage; + getrusage(RUSAGE_SELF, &rusage); +#if !defined(__HAIKU__) +#if defined(__APPLE__) && defined(__MACH__) + *peak_rss = rusage.ru_maxrss; +#else + *peak_rss = rusage.ru_maxrss * 1024; +#endif + *page_faults = rusage.ru_majflt; + *page_reclaim = rusage.ru_minflt; + *peak_commit = 0; +#else +// Haiku does not have (yet?) a way to +// get these stats per process + thread_info tid; + area_info mem; + ssize_t c; + *peak_rss = 0; + *page_faults = 0; + *page_reclaim = 0; + *peak_commit = 0; + get_thread_info(find_thread(0), &tid); + + while (get_next_area_info(tid.team, &c, &mem) == B_OK) { + *peak_rss += mem.ram_size; + } +#endif + *utime = timeval_secs(&rusage.ru_utime); + *stime = timeval_secs(&rusage.ru_stime); +} + +#else +#ifndef __wasi__ +// WebAssembly instances are not processes +#pragma message("define a way to get process info") +#endif + +static void mi_process_info(mi_msecs_t* utime, mi_msecs_t* stime, size_t* peak_rss, size_t* page_faults, size_t* page_reclaim, size_t* peak_commit) { + *peak_rss = 0; + *page_faults = 0; + *page_reclaim = 0; + *peak_commit = 0; + *utime = 0; + *stime = 0; +} +#endif diff --git a/extlib/mimalloc/test/CMakeLists.txt b/extlib/mimalloc/test/CMakeLists.txt new file mode 100644 index 0000000..4152f99 --- /dev/null +++ b/extlib/mimalloc/test/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.0) +project(mimalloc-test C CXX) + +# Set default build type +if (NOT CMAKE_BUILD_TYPE) + if ("${CMAKE_BINARY_DIR}" MATCHES ".*(D|d)ebug$") + message(STATUS "No build type selected, default to *** Debug ***") + set(CMAKE_BUILD_TYPE "Debug") + else() + message(STATUS "No build type selected, default to *** Release ***") + set(CMAKE_BUILD_TYPE "Release") + endif() +endif() + +# Import mimalloc (if installed) +find_package(mimalloc 1.6 REQUIRED NO_SYSTEM_ENVIRONMENT_PATH) +message(STATUS "Found mimalloc installed at: ${MIMALLOC_TARGET_DIR}") + +# overriding with a dynamic library +add_executable(dynamic-override main-override.c) +target_link_libraries(dynamic-override PUBLIC mimalloc) + +add_executable(dynamic-override-cxx main-override.cpp) +target_link_libraries(dynamic-override-cxx PUBLIC mimalloc) + + +# overriding with a static object file works reliable as the symbols in the +# object file have priority over those in library files +add_executable(static-override-obj main-override.c ${MIMALLOC_TARGET_DIR}/mimalloc.o) +target_include_directories(static-override-obj PUBLIC ${MIMALLOC_TARGET_DIR}/include) +target_link_libraries(static-override-obj PUBLIC pthread) + + +# overriding with a static library works too if using the `mimalloc-override.h` +# header to redefine malloc/free. (the library already overrides new/delete) +add_executable(static-override-static main-override-static.c) +target_link_libraries(static-override-static PUBLIC mimalloc-static) + + +# overriding with a static library: this may not work if the library is linked too late +# on the command line after the C runtime library; but we cannot control that well in CMake +add_executable(static-override main-override.c) +target_link_libraries(static-override PUBLIC mimalloc-static) + +add_executable(static-override-cxx main-override.cpp) +target_link_libraries(static-override-cxx PUBLIC mimalloc-static) diff --git a/extlib/mimalloc/test/main-override-static.c b/extlib/mimalloc/test/main-override-static.c new file mode 100644 index 0000000..f738c51 --- /dev/null +++ b/extlib/mimalloc/test/main-override-static.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#include + +#include +#include // redefines malloc etc. + +static void double_free1(); +static void double_free2(); +static void corrupt_free(); +static void block_overflow1(); +static void invalid_free(); + +int main() { + mi_version(); + + // detect double frees and heap corruption + // double_free1(); + // double_free2(); + // corrupt_free(); + // block_overflow1(); + invalid_free(); + + void* p1 = malloc(78); + void* p2 = malloc(24); + free(p1); + p1 = mi_malloc(8); + //char* s = strdup("hello\n"); + free(p2); + p2 = malloc(16); + p1 = realloc(p1, 32); + free(p1); + free(p2); + //free(s); + //mi_collect(true); + + /* now test if override worked by allocating/freeing across the api's*/ + //p1 = mi_malloc(32); + //free(p1); + //p2 = malloc(32); + //mi_free(p2); + mi_stats_print(NULL); + return 0; +} + +static void invalid_free() { + free((void*)0xBADBEEF); + realloc((void*)0xBADBEEF,10); +} + +static void block_overflow1() { + uint8_t* p = (uint8_t*)mi_malloc(17); + p[18] = 0; + free(p); +} + +// The double free samples come ArcHeap [1] by Insu Yun (issue #161) +// [1]: https://arxiv.org/pdf/1903.00503.pdf + +static void double_free1() { + void* p[256]; + //uintptr_t buf[256]; + + p[0] = mi_malloc(622616); + p[1] = mi_malloc(655362); + p[2] = mi_malloc(786432); + mi_free(p[2]); + // [VULN] Double free + mi_free(p[2]); + p[3] = mi_malloc(786456); + // [BUG] Found overlap + // p[3]=0x429b2ea2000 (size=917504), p[1]=0x429b2e42000 (size=786432) + fprintf(stderr, "p3: %p-%p, p1: %p-%p, p2: %p\n", p[3], (uint8_t*)(p[3]) + 786456, p[1], (uint8_t*)(p[1]) + 655362, p[2]); +} + +static void double_free2() { + void* p[256]; + //uintptr_t buf[256]; + // [INFO] Command buffer: 0x327b2000 + // [INFO] Input size: 182 + p[0] = malloc(712352); + p[1] = malloc(786432); + free(p[0]); + // [VULN] Double free + free(p[0]); + p[2] = malloc(786440); + p[3] = malloc(917504); + p[4] = malloc(786440); + // [BUG] Found overlap + // p[4]=0x433f1402000 (size=917504), p[1]=0x433f14c2000 (size=786432) + fprintf(stderr, "p1: %p-%p, p2: %p-%p\n", p[4], (uint8_t*)(p[4]) + 917504, p[1], (uint8_t*)(p[1]) + 786432); +} + + +// Try to corrupt the heap through buffer overflow +#define N 256 +#define SZ 64 + +static void corrupt_free() { + void* p[N]; + // allocate + for (int i = 0; i < N; i++) { + p[i] = malloc(SZ); + } + // free some + for (int i = 0; i < N; i += (N/10)) { + free(p[i]); + p[i] = NULL; + } + // try to corrupt the free list + for (int i = 0; i < N; i++) { + if (p[i] != NULL) { + memset(p[i], 0, SZ+8); + } + } + // allocate more.. trying to trigger an allocation from a corrupted entry + // this may need many allocations to get there (if at all) + for (int i = 0; i < 4096; i++) { + malloc(SZ); + } +} diff --git a/extlib/mimalloc/test/main-override.c b/extlib/mimalloc/test/main-override.c new file mode 100644 index 0000000..1bec117 --- /dev/null +++ b/extlib/mimalloc/test/main-override.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include + +#include + +int main() { + mi_version(); // ensure mimalloc library is linked + void* p1 = malloc(78); + void* p2 = malloc(24); + free(p1); + p1 = malloc(8); + //char* s = strdup("hello\n"); + free(p2); + p2 = malloc(16); + p1 = realloc(p1, 32); + free(p1); + free(p2); + //free(s); + //mi_collect(true); + + /* now test if override worked by allocating/freeing across the api's*/ + //p1 = mi_malloc(32); + //free(p1); + //p2 = malloc(32); + //mi_free(p2); + mi_stats_print(NULL); + return 0; +} diff --git a/extlib/mimalloc/test/main-override.cpp b/extlib/mimalloc/test/main-override.cpp new file mode 100644 index 0000000..16c4028 --- /dev/null +++ b/extlib/mimalloc/test/main-override.cpp @@ -0,0 +1,209 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef _WIN32 +#include +#endif + +#ifdef _WIN32 +#include +static void msleep(unsigned long msecs) { Sleep(msecs); } +#else +#include +static void msleep(unsigned long msecs) { usleep(msecs * 1000UL); } +#endif + +void heap_thread_free_large(); // issue #221 +void heap_no_delete(); // issue #202 +void heap_late_free(); // issue #204 +void padding_shrink(); // issue #209 +void various_tests(); +void test_mt_shutdown(); + +int main() { + mi_stats_reset(); // ignore earlier allocations + heap_thread_free_large(); + heap_no_delete(); + heap_late_free(); + padding_shrink(); + various_tests(); + //test_mt_shutdown(); + mi_stats_print(NULL); + return 0; +} + +static void* p = malloc(8); + +void free_p() { + free(p); + return; +} + +class Test { +private: + int i; +public: + Test(int x) { i = x; } + ~Test() { } +}; + + +void various_tests() { + atexit(free_p); + void* p1 = malloc(78); + void* p2 = mi_malloc_aligned(16, 24); + free(p1); + p1 = malloc(8); + char* s = mi_strdup("hello\n"); + + //char* s = _strdup("hello\n"); + //char* buf = NULL; + //size_t len; + //_dupenv_s(&buf,&len,"MIMALLOC_VERBOSE"); + //mi_free(buf); + + mi_free(p2); + p2 = malloc(16); + p1 = realloc(p1, 32); + free(p1); + free(p2); + mi_free(s); + Test* t = new Test(42); + delete t; + t = new (std::nothrow) Test(42); + delete t; +} + +class Static { +private: + void* p; +public: + Static() { + p = malloc(64); + return; + } + ~Static() { + free(p); + return; + } +}; + +static Static s = Static(); + + +bool test_stl_allocator1() { + std::vector > vec; + vec.push_back(1); + vec.pop_back(); + return vec.size() == 0; +} + +struct some_struct { int i; int j; double z; }; + +bool test_stl_allocator2() { + std::vector > vec; + vec.push_back(some_struct()); + vec.pop_back(); + return vec.size() == 0; +} + + + +// Issue #202 +void heap_no_delete_worker() { + mi_heap_t* heap = mi_heap_new(); + void* q = mi_heap_malloc(heap, 1024); + // mi_heap_delete(heap); // uncomment to prevent assertion +} + +void heap_no_delete() { + auto t1 = std::thread(heap_no_delete_worker); + t1.join(); +} + + +// Issue #204 +volatile void* global_p; + +void t1main() { + mi_heap_t* heap = mi_heap_new(); + global_p = mi_heap_malloc(heap, 1024); + mi_heap_delete(heap); +} + +void heap_late_free() { + auto t1 = std::thread(t1main); + + msleep(2000); + assert(global_p); + mi_free((void*)global_p); + + t1.join(); +} + +// issue #209 +static void* shared_p; +static void alloc0(/* void* arg */) +{ + shared_p = mi_malloc(8); +} + +void padding_shrink(void) +{ + auto t1 = std::thread(alloc0); + t1.join(); + mi_free(shared_p); +} + + +// Issue #221 +void heap_thread_free_large_worker() { + mi_free(shared_p); +} + +void heap_thread_free_large() { + for (int i = 0; i < 100; i++) { + shared_p = mi_malloc_aligned(2*1024*1024 + 1, 8); + auto t1 = std::thread(heap_thread_free_large_worker); + t1.join(); + } +} + + + +void test_mt_shutdown() +{ + const int threads = 5; + std::vector< std::future< std::vector< char* > > > ts; + + auto fn = [&]() + { + std::vector< char* > ps; + ps.reserve(1000); + for (int i = 0; i < 1000; i++) + ps.emplace_back(new char[1]); + return ps; + }; + + for (int i = 0; i < threads; i++) + ts.emplace_back(std::async(std::launch::async, fn)); + + for (auto& f : ts) + for (auto& p : f.get()) + delete[] p; + + std::cout << "done" << std::endl; +} diff --git a/extlib/mimalloc/test/main.c b/extlib/mimalloc/test/main.c new file mode 100644 index 0000000..b148f71 --- /dev/null +++ b/extlib/mimalloc/test/main.c @@ -0,0 +1,46 @@ +#include +#include +#include + +void test_heap(void* p_out) { + mi_heap_t* heap = mi_heap_new(); + void* p1 = mi_heap_malloc(heap,32); + void* p2 = mi_heap_malloc(heap,48); + mi_free(p_out); + mi_heap_destroy(heap); + //mi_heap_delete(heap); mi_free(p1); mi_free(p2); +} + +void test_large() { + const size_t N = 1000; + + for (size_t i = 0; i < N; ++i) { + size_t sz = 1ull << 21; + char* a = mi_mallocn_tp(char,sz); + for (size_t k = 0; k < sz; k++) { a[k] = 'x'; } + mi_free(a); + } +} + +int main() { + void* p1 = mi_malloc(16); + void* p2 = mi_malloc(1000000); + mi_free(p1); + mi_free(p2); + p1 = mi_malloc(16); + p2 = mi_malloc(16); + mi_free(p1); + mi_free(p2); + + test_heap(mi_malloc(32)); + + p1 = mi_malloc_aligned(64, 16); + p2 = mi_malloc_aligned(160,24); + mi_free(p2); + mi_free(p1); + //test_large(); + + mi_collect(true); + mi_stats_print(NULL); + return 0; +} diff --git a/extlib/mimalloc/test/readme.md b/extlib/mimalloc/test/readme.md new file mode 100644 index 0000000..db3524c --- /dev/null +++ b/extlib/mimalloc/test/readme.md @@ -0,0 +1,16 @@ +Testing allocators is difficult as bugs may only surface after particular +allocation patterns. The main approach to testing _mimalloc_ is therefore +to have extensive internal invariant checking (see `page_is_valid` in `page.c` +for example), which is enabled in debug mode with `-DMI_DEBUG_FULL=ON`. +The main testing strategy is then to run [`mimalloc-bench`][bench] using full +invariant checking to catch any potential problems over a wide range of intensive +allocation benchmarks and programs. + +However, this does not test well for the entire API surface and this is tested +with `test-api.c` when using `make test` (from `out/debug` etc). (This is +not complete yet, please add to it.) + +The `main.c` and `main-override.c` are there to test if building and overriding +from a local install works and therefore these build a separate `test/CMakeLists.txt`. + +[bench]: https://github.com/daanx/mimalloc-bench diff --git a/extlib/mimalloc/test/test-api.c b/extlib/mimalloc/test/test-api.c new file mode 100644 index 0000000..e5827a9 --- /dev/null +++ b/extlib/mimalloc/test/test-api.c @@ -0,0 +1,249 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018, Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. A copy of the license can be found in the file +"LICENSE" at the root of this distribution. +-----------------------------------------------------------------------------*/ + +/* +Testing allocators is difficult as bugs may only surface after particular +allocation patterns. The main approach to testing _mimalloc_ is therefore +to have extensive internal invariant checking (see `page_is_valid` in `page.c` +for example), which is enabled in debug mode with `-DMI_DEBUG_FULL=ON`. +The main testing is then to run `mimalloc-bench` [1] using full invariant checking +to catch any potential problems over a wide range of intensive allocation bench +marks. + +However, this does not test well for the entire API surface. In this test file +we therefore test the API over various inputs. Please add more tests :-) + +[1] https://github.com/daanx/mimalloc-bench +*/ + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +#include +#endif + +#include "mimalloc.h" +// #include "mimalloc-internal.h" + +// --------------------------------------------------------------------------- +// Test macros: CHECK(name,predicate) and CHECK_BODY(name,body) +// --------------------------------------------------------------------------- +static int ok = 0; +static int failed = 0; + +#define CHECK_BODY(name,body) \ + do { \ + fprintf(stderr,"test: %s... ", name ); \ + bool result = true; \ + do { body } while(false); \ + if (!(result)) { \ + failed++; \ + fprintf(stderr, \ + "\n FAILED: %s:%d:\n %s\n", \ + __FILE__, \ + __LINE__, \ + #body); \ + /* exit(1); */ \ + } \ + else { \ + ok++; \ + fprintf(stderr,"ok.\n"); \ + } \ + } while (false) + +#define CHECK(name,expr) CHECK_BODY(name,{ result = (expr); }) + +// --------------------------------------------------------------------------- +// Test functions +// --------------------------------------------------------------------------- +bool test_heap1(); +bool test_heap2(); +bool test_stl_allocator1(); +bool test_stl_allocator2(); + +// --------------------------------------------------------------------------- +// Main testing +// --------------------------------------------------------------------------- +int main() { + mi_option_disable(mi_option_verbose); + + // --------------------------------------------------- + // Malloc + // --------------------------------------------------- + + CHECK_BODY("malloc-zero",{ + void* p = mi_malloc(0); mi_free(p); + }); + CHECK_BODY("malloc-nomem1",{ + result = (mi_malloc(SIZE_MAX/2) == NULL); + }); + CHECK_BODY("malloc-null",{ + mi_free(NULL); + }); + CHECK_BODY("calloc-overflow",{ + // use (size_t)&mi_calloc to get some number without triggering compiler warnings + result = (mi_calloc((size_t)&mi_calloc,SIZE_MAX/1000) == NULL); + }); + CHECK_BODY("calloc0",{ + result = (mi_usable_size(mi_calloc(0,1000)) <= 16); + }); + + // --------------------------------------------------- + // Extended + // --------------------------------------------------- + CHECK_BODY("posix_memalign1", { + void* p = &p; + int err = mi_posix_memalign(&p, sizeof(void*), 32); + result = ((err==0 && (uintptr_t)p % sizeof(void*) == 0) || p==&p); + mi_free(p); + }); + CHECK_BODY("posix_memalign_no_align", { + void* p = &p; + int err = mi_posix_memalign(&p, 3, 32); + result = (err==EINVAL && p==&p); + }); + CHECK_BODY("posix_memalign_zero", { + void* p = &p; + int err = mi_posix_memalign(&p, sizeof(void*), 0); + mi_free(p); + result = (err==0); + }); + CHECK_BODY("posix_memalign_nopow2", { + void* p = &p; + int err = mi_posix_memalign(&p, 3*sizeof(void*), 32); + result = (err==EINVAL && p==&p); + }); + CHECK_BODY("posix_memalign_nomem", { + void* p = &p; + int err = mi_posix_memalign(&p, sizeof(void*), SIZE_MAX); + result = (err==ENOMEM && p==&p); + }); + + // --------------------------------------------------- + // Aligned API + // --------------------------------------------------- + CHECK_BODY("malloc-aligned1", { + void* p = mi_malloc_aligned(32,32); result = (p != NULL && (uintptr_t)(p) % 32 == 0); mi_free(p); + }); + CHECK_BODY("malloc-aligned2", { + void* p = mi_malloc_aligned(48,32); result = (p != NULL && (uintptr_t)(p) % 32 == 0); mi_free(p); + }); + CHECK_BODY("malloc-aligned3", { + void* p1 = mi_malloc_aligned(48,32); bool result1 = (p1 != NULL && (uintptr_t)(p1) % 32 == 0); + void* p2 = mi_malloc_aligned(48,32); bool result2 = (p2 != NULL && (uintptr_t)(p2) % 32 == 0); + mi_free(p2); + mi_free(p1); + result = (result1&&result2); + }); + CHECK_BODY("malloc-aligned4", { + void* p; + bool ok = true; + for (int i = 0; i < 8 && ok; i++) { + p = mi_malloc_aligned(8, 16); + ok = (p != NULL && (uintptr_t)(p) % 16 == 0); mi_free(p); + } + result = ok; + }); + CHECK_BODY("malloc-aligned5", { + void* p = mi_malloc_aligned(4097,4096); size_t usable = mi_usable_size(p); result = usable >= 4097 && usable < 10000; mi_free(p); + }); + CHECK_BODY("malloc-aligned-at1", { + void* p = mi_malloc_aligned_at(48,32,0); result = (p != NULL && ((uintptr_t)(p) + 0) % 32 == 0); mi_free(p); + }); + CHECK_BODY("malloc-aligned-at2", { + void* p = mi_malloc_aligned_at(50,32,8); result = (p != NULL && ((uintptr_t)(p) + 8) % 32 == 0); mi_free(p); + }); + CHECK_BODY("memalign1", { + void* p; + bool ok = true; + for (int i = 0; i < 8 && ok; i++) { + p = mi_memalign(16,8); + ok = (p != NULL && (uintptr_t)(p) % 16 == 0); mi_free(p); + } + result = ok; + }); + + // --------------------------------------------------- + // Heaps + // --------------------------------------------------- + CHECK("heap_destroy", test_heap1()); + CHECK("heap_delete", test_heap2()); + + //mi_stats_print(NULL); + + // --------------------------------------------------- + // various + // --------------------------------------------------- + CHECK_BODY("realpath", { + char* s = mi_realpath( ".", NULL ); + // printf("realpath: %s\n",s); + mi_free(s); + }); + + CHECK("stl_allocator1", test_stl_allocator1()); + CHECK("stl_allocator2", test_stl_allocator2()); + + // --------------------------------------------------- + // Done + // ---------------------------------------------------[] + fprintf(stderr,"\n\n---------------------------------------------\n" + "succeeded: %i\n" + "failed : %i\n\n", ok, failed); + return failed; +} + +// --------------------------------------------------- +// Larger test functions +// --------------------------------------------------- + +bool test_heap1() { + mi_heap_t* heap = mi_heap_new(); + int* p1 = mi_heap_malloc_tp(heap,int); + int* p2 = mi_heap_malloc_tp(heap,int); + *p1 = *p2 = 43; + mi_heap_destroy(heap); + return true; +} + +bool test_heap2() { + mi_heap_t* heap = mi_heap_new(); + int* p1 = mi_heap_malloc_tp(heap,int); + int* p2 = mi_heap_malloc_tp(heap,int); + mi_heap_delete(heap); + *p1 = 42; + mi_free(p1); + mi_free(p2); + return true; +} + +bool test_stl_allocator1() { +#ifdef __cplusplus + std::vector > vec; + vec.push_back(1); + vec.pop_back(); + return vec.size() == 0; +#else + return true; +#endif +} + +struct some_struct { int i; int j; double z; }; + +bool test_stl_allocator2() { +#ifdef __cplusplus + std::vector > vec; + vec.push_back(some_struct()); + vec.pop_back(); + return vec.size() == 0; +#else + return true; +#endif +} diff --git a/extlib/mimalloc/test/test-stress.c b/extlib/mimalloc/test/test-stress.c new file mode 100644 index 0000000..7d8993a --- /dev/null +++ b/extlib/mimalloc/test/test-stress.c @@ -0,0 +1,329 @@ +/* ---------------------------------------------------------------------------- +Copyright (c) 2018,2019 Microsoft Research, Daan Leijen +This is free software; you can redistribute it and/or modify it under the +terms of the MIT license. +-----------------------------------------------------------------------------*/ + +/* This is a stress test for the allocator, using multiple threads and + transferring objects between threads. It tries to reflect real-world workloads: + - allocation size is distributed linearly in powers of two + - with some fraction extra large (and some extra extra large) + - the allocations are initialized and read again at free + - pointers transfer between threads + - threads are terminated and recreated with some objects surviving in between + - uses deterministic "randomness", but execution can still depend on + (random) thread scheduling. Do not use this test as a benchmark! +*/ + +#include +#include +#include +#include +#include +#include + +// > mimalloc-test-stress [THREADS] [SCALE] [ITER] +// +// argument defaults +static int THREADS = 32; // more repeatable if THREADS <= #processors +static int SCALE = 10; // scaling factor +static int ITER = 50; // N full iterations destructing and re-creating all threads + +// static int THREADS = 8; // more repeatable if THREADS <= #processors +// static int SCALE = 100; // scaling factor + +#define STRESS // undefine for leak test + +static bool allow_large_objects = true; // allow very large objects? +static size_t use_one_size = 0; // use single object size of `N * sizeof(uintptr_t)`? + + +#ifdef USE_STD_MALLOC +#define custom_calloc(n,s) calloc(n,s) +#define custom_realloc(p,s) realloc(p,s) +#define custom_free(p) free(p) +#else +#define custom_calloc(n,s) mi_calloc(n,s) +#define custom_realloc(p,s) mi_realloc(p,s) +#define custom_free(p) mi_free(p) +#endif + +// transfer pointer between threads +#define TRANSFERS (1000) +static volatile void* transfer[TRANSFERS]; + + +#if (UINTPTR_MAX != UINT32_MAX) +const uintptr_t cookie = 0xbf58476d1ce4e5b9UL; +#else +const uintptr_t cookie = 0x1ce4e5b9UL; +#endif + +static void* atomic_exchange_ptr(volatile void** p, void* newval); + +typedef uintptr_t* random_t; + +static uintptr_t pick(random_t r) { + uintptr_t x = *r; +#if (UINTPTR_MAX > UINT32_MAX) + // by Sebastiano Vigna, see: + x ^= x >> 30; + x *= 0xbf58476d1ce4e5b9UL; + x ^= x >> 27; + x *= 0x94d049bb133111ebUL; + x ^= x >> 31; +#else + // by Chris Wellons, see: + x ^= x >> 16; + x *= 0x7feb352dUL; + x ^= x >> 15; + x *= 0x846ca68bUL; + x ^= x >> 16; +#endif + *r = x; + return x; +} + +static bool chance(size_t perc, random_t r) { + return (pick(r) % 100 <= perc); +} + +static void* alloc_items(size_t items, random_t r) { + if (chance(1, r)) { + if (chance(1, r) && allow_large_objects) items *= 10000; // 0.01% giant + else if (chance(10, r) && allow_large_objects) items *= 1000; // 0.1% huge + else items *= 100; // 1% large objects; + } + if (items == 40) items++; // pthreads uses that size for stack increases + if (use_one_size > 0) items = (use_one_size / sizeof(uintptr_t)); + if (items==0) items = 1; + uintptr_t* p = (uintptr_t*)custom_calloc(items,sizeof(uintptr_t)); + if (p != NULL) { + for (uintptr_t i = 0; i < items; i++) { + p[i] = (items - i) ^ cookie; + } + } + return p; +} + +static void free_items(void* p) { + if (p != NULL) { + uintptr_t* q = (uintptr_t*)p; + uintptr_t items = (q[0] ^ cookie); + for (uintptr_t i = 0; i < items; i++) { + if ((q[i] ^ cookie) != items - i) { + fprintf(stderr, "memory corruption at block %p at %zu\n", p, i); + abort(); + } + } + } + custom_free(p); +} + + +static void stress(intptr_t tid) { + //bench_start_thread(); + uintptr_t r = (tid * 43); // rand(); + const size_t max_item_shift = 5; // 128 + const size_t max_item_retained_shift = max_item_shift + 2; + size_t allocs = 100 * ((size_t)SCALE) * (tid % 8 + 1); // some threads do more + size_t retain = allocs / 2; + void** data = NULL; + size_t data_size = 0; + size_t data_top = 0; + void** retained = (void**)custom_calloc(retain,sizeof(void*)); + size_t retain_top = 0; + + while (allocs > 0 || retain > 0) { + if (retain == 0 || (chance(50, &r) && allocs > 0)) { + // 50%+ alloc + allocs--; + if (data_top >= data_size) { + data_size += 100000; + data = (void**)custom_realloc(data, data_size * sizeof(void*)); + } + data[data_top++] = alloc_items(1ULL << (pick(&r) % max_item_shift), &r); + } + else { + // 25% retain + retained[retain_top++] = alloc_items( 1ULL << (pick(&r) % max_item_retained_shift), &r); + retain--; + } + if (chance(66, &r) && data_top > 0) { + // 66% free previous alloc + size_t idx = pick(&r) % data_top; + free_items(data[idx]); + data[idx] = NULL; + } + if (chance(25, &r) && data_top > 0) { + // 25% exchange a local pointer with the (shared) transfer buffer. + size_t data_idx = pick(&r) % data_top; + size_t transfer_idx = pick(&r) % TRANSFERS; + void* p = data[data_idx]; + void* q = atomic_exchange_ptr(&transfer[transfer_idx], p); + data[data_idx] = q; + } + } + // free everything that is left + for (size_t i = 0; i < retain_top; i++) { + free_items(retained[i]); + } + for (size_t i = 0; i < data_top; i++) { + free_items(data[i]); + } + custom_free(retained); + custom_free(data); + //bench_end_thread(); +} + +static void run_os_threads(size_t nthreads, void (*entry)(intptr_t tid)); + +static void test_stress(void) { + uintptr_t r = rand(); + for (int n = 0; n < ITER; n++) { + run_os_threads(THREADS, &stress); + for (int i = 0; i < TRANSFERS; i++) { + if (chance(50, &r) || n + 1 == ITER) { // free all on last run, otherwise free half of the transfers + void* p = atomic_exchange_ptr(&transfer[i], NULL); + free_items(p); + } + } + // mi_collect(false); +#ifndef NDEBUG + if ((n + 1) % 10 == 0) { printf("- iterations left: %3d\n", ITER - (n + 1)); } +#endif + } +} + +#ifndef STRESS +static void leak(intptr_t tid) { + uintptr_t r = rand(); + void* p = alloc_items(1 /*pick(&r)%128*/, &r); + if (chance(50, &r)) { + intptr_t i = (pick(&r) % TRANSFERS); + void* q = atomic_exchange_ptr(&transfer[i], p); + free_items(q); + } +} + +static void test_leak(void) { + for (int n = 0; n < ITER; n++) { + run_os_threads(THREADS, &leak); + mi_collect(false); +#ifndef NDEBUG + if ((n + 1) % 10 == 0) { printf("- iterations left: %3d\n", ITER - (n + 1)); } +#endif + } +} +#endif + +int main(int argc, char** argv) { + // > mimalloc-test-stress [THREADS] [SCALE] [ITER] + if (argc >= 2) { + char* end; + long n = strtol(argv[1], &end, 10); + if (n > 0) THREADS = n; + } + if (argc >= 3) { + char* end; + long n = (strtol(argv[2], &end, 10)); + if (n > 0) SCALE = n; + } + if (argc >= 4) { + char* end; + long n = (strtol(argv[3], &end, 10)); + if (n > 0) ITER = n; + } + printf("Using %d threads with a %d%% load-per-thread and %d iterations\n", THREADS, SCALE, ITER); + //int res = mi_reserve_huge_os_pages(4,1); + //printf("(reserve huge: %i\n)", res); + + //bench_start_program(); + + // Run ITER full iterations where half the objects in the transfer buffer survive to the next round. + srand(0x7feb352d); + // mi_stats_reset(); +#ifdef STRESS + test_stress(); +#else + test_leak(); +#endif + + // mi_collect(true); + mi_stats_print(NULL); + //bench_end_program(); + return 0; +} + + +static void (*thread_entry_fun)(intptr_t) = &stress; + +#ifdef _WIN32 + +#include + +static DWORD WINAPI thread_entry(LPVOID param) { + thread_entry_fun((intptr_t)param); + return 0; +} + +static void run_os_threads(size_t nthreads, void (*fun)(intptr_t)) { + thread_entry_fun = fun; + DWORD* tids = (DWORD*)custom_calloc(nthreads,sizeof(DWORD)); + HANDLE* thandles = (HANDLE*)custom_calloc(nthreads,sizeof(HANDLE)); + for (uintptr_t i = 0; i < nthreads; i++) { + thandles[i] = CreateThread(0, 4096, &thread_entry, (void*)(i), 0, &tids[i]); + } + for (size_t i = 0; i < nthreads; i++) { + WaitForSingleObject(thandles[i], INFINITE); + } + for (size_t i = 0; i < nthreads; i++) { + CloseHandle(thandles[i]); + } + custom_free(tids); + custom_free(thandles); +} + +static void* atomic_exchange_ptr(volatile void** p, void* newval) { +#if (INTPTR_MAX == INT32_MAX) + return (void*)InterlockedExchange((volatile LONG*)p, (LONG)newval); +#else + return (void*)InterlockedExchange64((volatile LONG64*)p, (LONG64)newval); +#endif +} +#else + +#include + +static void* thread_entry(void* param) { + thread_entry_fun((uintptr_t)param); + return NULL; +} + +static void run_os_threads(size_t nthreads, void (*fun)(intptr_t)) { + thread_entry_fun = fun; + pthread_t* threads = (pthread_t*)custom_calloc(nthreads,sizeof(pthread_t)); + memset(threads, 0, sizeof(pthread_t) * nthreads); + //pthread_setconcurrency(nthreads); + for (uintptr_t i = 0; i < nthreads; i++) { + pthread_create(&threads[i], NULL, &thread_entry, (void*)i); + } + for (size_t i = 0; i < nthreads; i++) { + pthread_join(threads[i], NULL); + } + custom_free(threads); +} + +#ifdef __cplusplus +#include +static void* atomic_exchange_ptr(volatile void** p, void* newval) { + return std::atomic_exchange((volatile std::atomic*)p, newval); +} +#else +#include +static void* atomic_exchange_ptr(volatile void** p, void* newval) { + return atomic_exchange((volatile _Atomic(void*)*)p, newval); +} +#endif + +#endif diff --git a/include/slvs.h b/include/slvs.h new file mode 100644 index 0000000..1c97fbf --- /dev/null +++ b/include/slvs.h @@ -0,0 +1,404 @@ +/*----------------------------------------------------------------------------- + * Data structures and prototypes for slvs.lib, a geometric constraint solver. + * + * See the comments in this file, the accompanying sample code that uses + * this library, and the accompanying documentation (DOC.txt). + * + * Copyright 2009-2013 Jonathan Westhues. + *---------------------------------------------------------------------------*/ + +#ifndef __SLVS_H +#define __SLVS_H + +#ifdef WIN32 +# ifdef EXPORT_DLL +# define DLL __declspec( dllexport ) +# else +# define DLL __declspec( dllimport ) +# endif +#else +# define DLL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _MSC_VER +typedef unsigned __int32 uint32_t; +#else +#include +#endif + +typedef uint32_t Slvs_hParam; +typedef uint32_t Slvs_hEntity; +typedef uint32_t Slvs_hConstraint; +typedef uint32_t Slvs_hGroup; + +/* To obtain the 3d (not projected into a workplane) of a constraint or + * an entity, specify this instead of the workplane. */ +#define SLVS_FREE_IN_3D 0 + + +typedef struct { + Slvs_hParam h; + Slvs_hGroup group; + double val; +} Slvs_Param; + + +#define SLVS_E_POINT_IN_3D 50000 +#define SLVS_E_POINT_IN_2D 50001 + +#define SLVS_E_NORMAL_IN_3D 60000 +#define SLVS_E_NORMAL_IN_2D 60001 + +#define SLVS_E_DISTANCE 70000 + +/* The special point, normal, and distance types used for parametric step + * and repeat, extrude, and assembly are currently not exposed. Please + * contact us if you are interested in using these. */ + +#define SLVS_E_WORKPLANE 80000 +#define SLVS_E_LINE_SEGMENT 80001 +#define SLVS_E_CUBIC 80002 +#define SLVS_E_CIRCLE 80003 +#define SLVS_E_ARC_OF_CIRCLE 80004 + +typedef struct { + Slvs_hEntity h; + Slvs_hGroup group; + + int type; + + Slvs_hEntity wrkpl; + Slvs_hEntity point[4]; + Slvs_hEntity normal; + Slvs_hEntity distance; + + Slvs_hParam param[4]; +} Slvs_Entity; + +#define SLVS_C_POINTS_COINCIDENT 100000 +#define SLVS_C_PT_PT_DISTANCE 100001 +#define SLVS_C_PT_PLANE_DISTANCE 100002 +#define SLVS_C_PT_LINE_DISTANCE 100003 +#define SLVS_C_PT_FACE_DISTANCE 100004 +#define SLVS_C_PT_IN_PLANE 100005 +#define SLVS_C_PT_ON_LINE 100006 +#define SLVS_C_PT_ON_FACE 100007 +#define SLVS_C_EQUAL_LENGTH_LINES 100008 +#define SLVS_C_LENGTH_RATIO 100009 +#define SLVS_C_EQ_LEN_PT_LINE_D 100010 +#define SLVS_C_EQ_PT_LN_DISTANCES 100011 +#define SLVS_C_EQUAL_ANGLE 100012 +#define SLVS_C_EQUAL_LINE_ARC_LEN 100013 +#define SLVS_C_SYMMETRIC 100014 +#define SLVS_C_SYMMETRIC_HORIZ 100015 +#define SLVS_C_SYMMETRIC_VERT 100016 +#define SLVS_C_SYMMETRIC_LINE 100017 +#define SLVS_C_AT_MIDPOINT 100018 +#define SLVS_C_HORIZONTAL 100019 +#define SLVS_C_VERTICAL 100020 +#define SLVS_C_DIAMETER 100021 +#define SLVS_C_PT_ON_CIRCLE 100022 +#define SLVS_C_SAME_ORIENTATION 100023 +#define SLVS_C_ANGLE 100024 +#define SLVS_C_PARALLEL 100025 +#define SLVS_C_PERPENDICULAR 100026 +#define SLVS_C_ARC_LINE_TANGENT 100027 +#define SLVS_C_CUBIC_LINE_TANGENT 100028 +#define SLVS_C_EQUAL_RADIUS 100029 +#define SLVS_C_PROJ_PT_DISTANCE 100030 +#define SLVS_C_WHERE_DRAGGED 100031 +#define SLVS_C_CURVE_CURVE_TANGENT 100032 +#define SLVS_C_LENGTH_DIFFERENCE 100033 + +typedef struct { + Slvs_hConstraint h; + Slvs_hGroup group; + + int type; + + Slvs_hEntity wrkpl; + + double valA; + Slvs_hEntity ptA; + Slvs_hEntity ptB; + Slvs_hEntity entityA; + Slvs_hEntity entityB; + Slvs_hEntity entityC; + Slvs_hEntity entityD; + + int other; + int other2; +} Slvs_Constraint; + + +typedef struct { + /*** INPUT VARIABLES + * + * Here, we specify the parameters and their initial values, the entities, + * and the constraints. For example, param[] points to the array of + * parameters, which has length params, so that the last valid element + * is param[params-1]. + * + * param[] is actually an in/out variable; if the solver is successful, + * then the new values (that satisfy the constraints) are written to it. */ + Slvs_Param *param; + int params; + Slvs_Entity *entity; + int entities; + Slvs_Constraint *constraint; + int constraints; + + /* If a parameter corresponds to a point (distance, normal, etc.) being + * dragged, then specify it here. This will cause the solver to favor + * that parameter, and attempt to change it as little as possible even + * if that requires it to change other parameters more. + * + * Unused members of this array should be set to zero. */ + Slvs_hParam dragged[4]; + + /* If the solver fails, then it can determine which constraints are + * causing the problem. But this is a relatively slow process (for + * a system with n constraints, about n times as long as just solving). + * If calculateFaileds is true, then the solver will do so, otherwise + * not. */ + int calculateFaileds; + + /*** OUTPUT VARIABLES + * + * If the solver fails, then it can report which constraints are causing + * the problem. The caller should allocate the array failed[], and pass + * its size in faileds. + * + * The solver will set faileds equal to the number of problematic + * constraints, and write their Slvs_hConstraints into failed[]. To + * ensure that there is sufficient space for any possible set of + * failing constraints, faileds should be greater than or equal to + * constraints. */ + Slvs_hConstraint *failed; + int faileds; + + /* The solver indicates the number of unconstrained degrees of freedom. */ + int dof; + + /* The solver indicates whether the solution succeeded. */ +#define SLVS_RESULT_OKAY 0 +#define SLVS_RESULT_INCONSISTENT 1 +#define SLVS_RESULT_DIDNT_CONVERGE 2 +#define SLVS_RESULT_TOO_MANY_UNKNOWNS 3 + int result; +} Slvs_System; + +DLL void Slvs_Solve(Slvs_System *sys, Slvs_hGroup hg); + + +/* Our base coordinate system has basis vectors + * (1, 0, 0) (0, 1, 0) (0, 0, 1) + * A unit quaternion defines a rotation to a new coordinate system with + * basis vectors + * U V N + * which these functions compute from the quaternion. */ +DLL void Slvs_QuaternionU(double qw, double qx, double qy, double qz, + double *x, double *y, double *z); +DLL void Slvs_QuaternionV(double qw, double qx, double qy, double qz, + double *x, double *y, double *z); +DLL void Slvs_QuaternionN(double qw, double qx, double qy, double qz, + double *x, double *y, double *z); + +/* Similarly, compute a unit quaternion in terms of two basis vectors. */ +DLL void Slvs_MakeQuaternion(double ux, double uy, double uz, + double vx, double vy, double vz, + double *qw, double *qx, double *qy, double *qz); + + +/*------------------------------------- + * These are just convenience functions, to save you the trouble of filling + * out the structures by hand. The code is included in the header file to + * let the compiler inline them if possible. */ + +static inline Slvs_Param Slvs_MakeParam(Slvs_hParam h, Slvs_hGroup group, double val) +{ + Slvs_Param r; + r.h = h; + r.group = group; + r.val = val; + return r; +} +static inline Slvs_Entity Slvs_MakePoint2d(Slvs_hEntity h, Slvs_hGroup group, + Slvs_hEntity wrkpl, + Slvs_hParam u, Slvs_hParam v) +{ + Slvs_Entity r; + memset(&r, 0, sizeof(r)); + r.h = h; + r.group = group; + r.type = SLVS_E_POINT_IN_2D; + r.wrkpl = wrkpl; + r.param[0] = u; + r.param[1] = v; + return r; +} +static inline Slvs_Entity Slvs_MakePoint3d(Slvs_hEntity h, Slvs_hGroup group, + Slvs_hParam x, Slvs_hParam y, Slvs_hParam z) +{ + Slvs_Entity r; + memset(&r, 0, sizeof(r)); + r.h = h; + r.group = group; + r.type = SLVS_E_POINT_IN_3D; + r.wrkpl = SLVS_FREE_IN_3D; + r.param[0] = x; + r.param[1] = y; + r.param[2] = z; + return r; +} +static inline Slvs_Entity Slvs_MakeNormal3d(Slvs_hEntity h, Slvs_hGroup group, + Slvs_hParam qw, Slvs_hParam qx, + Slvs_hParam qy, Slvs_hParam qz) +{ + Slvs_Entity r; + memset(&r, 0, sizeof(r)); + r.h = h; + r.group = group; + r.type = SLVS_E_NORMAL_IN_3D; + r.wrkpl = SLVS_FREE_IN_3D; + r.param[0] = qw; + r.param[1] = qx; + r.param[2] = qy; + r.param[3] = qz; + return r; +} +static inline Slvs_Entity Slvs_MakeNormal2d(Slvs_hEntity h, Slvs_hGroup group, + Slvs_hEntity wrkpl) +{ + Slvs_Entity r; + memset(&r, 0, sizeof(r)); + r.h = h; + r.group = group; + r.type = SLVS_E_NORMAL_IN_2D; + r.wrkpl = wrkpl; + return r; +} +static inline Slvs_Entity Slvs_MakeDistance(Slvs_hEntity h, Slvs_hGroup group, + Slvs_hEntity wrkpl, Slvs_hParam d) +{ + Slvs_Entity r; + memset(&r, 0, sizeof(r)); + r.h = h; + r.group = group; + r.type = SLVS_E_DISTANCE; + r.wrkpl = wrkpl; + r.param[0] = d; + return r; +} +static inline Slvs_Entity Slvs_MakeLineSegment(Slvs_hEntity h, Slvs_hGroup group, + Slvs_hEntity wrkpl, + Slvs_hEntity ptA, Slvs_hEntity ptB) +{ + Slvs_Entity r; + memset(&r, 0, sizeof(r)); + r.h = h; + r.group = group; + r.type = SLVS_E_LINE_SEGMENT; + r.wrkpl = wrkpl; + r.point[0] = ptA; + r.point[1] = ptB; + return r; +} +static inline Slvs_Entity Slvs_MakeCubic(Slvs_hEntity h, Slvs_hGroup group, + Slvs_hEntity wrkpl, + Slvs_hEntity pt0, Slvs_hEntity pt1, + Slvs_hEntity pt2, Slvs_hEntity pt3) +{ + Slvs_Entity r; + memset(&r, 0, sizeof(r)); + r.h = h; + r.group = group; + r.type = SLVS_E_CUBIC; + r.wrkpl = wrkpl; + r.point[0] = pt0; + r.point[1] = pt1; + r.point[2] = pt2; + r.point[3] = pt3; + return r; +} +static inline Slvs_Entity Slvs_MakeArcOfCircle(Slvs_hEntity h, Slvs_hGroup group, + Slvs_hEntity wrkpl, + Slvs_hEntity normal, + Slvs_hEntity center, + Slvs_hEntity start, Slvs_hEntity end) +{ + Slvs_Entity r; + memset(&r, 0, sizeof(r)); + r.h = h; + r.group = group; + r.type = SLVS_E_ARC_OF_CIRCLE; + r.wrkpl = wrkpl; + r.normal = normal; + r.point[0] = center; + r.point[1] = start; + r.point[2] = end; + return r; +} +static inline Slvs_Entity Slvs_MakeCircle(Slvs_hEntity h, Slvs_hGroup group, + Slvs_hEntity wrkpl, + Slvs_hEntity center, + Slvs_hEntity normal, Slvs_hEntity radius) +{ + Slvs_Entity r; + memset(&r, 0, sizeof(r)); + r.h = h; + r.group = group; + r.type = SLVS_E_CIRCLE; + r.wrkpl = wrkpl; + r.point[0] = center; + r.normal = normal; + r.distance = radius; + return r; +} +static inline Slvs_Entity Slvs_MakeWorkplane(Slvs_hEntity h, Slvs_hGroup group, + Slvs_hEntity origin, Slvs_hEntity normal) +{ + Slvs_Entity r; + memset(&r, 0, sizeof(r)); + r.h = h; + r.group = group; + r.type = SLVS_E_WORKPLANE; + r.wrkpl = SLVS_FREE_IN_3D; + r.point[0] = origin; + r.normal = normal; + return r; +} + +static inline Slvs_Constraint Slvs_MakeConstraint(Slvs_hConstraint h, + Slvs_hGroup group, + int type, + Slvs_hEntity wrkpl, + double valA, + Slvs_hEntity ptA, + Slvs_hEntity ptB, + Slvs_hEntity entityA, + Slvs_hEntity entityB) +{ + Slvs_Constraint r; + memset(&r, 0, sizeof(r)); + r.h = h; + r.group = group; + r.type = type; + r.wrkpl = wrkpl; + r.valA = valA; + r.ptA = ptA; + r.ptB = ptB; + r.entityA = entityA; + r.entityB = entityB; + return r; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pkg/flatpak/.gitignore b/pkg/flatpak/.gitignore new file mode 100644 index 0000000..ca1b1d7 --- /dev/null +++ b/pkg/flatpak/.gitignore @@ -0,0 +1,4 @@ +/.flatpak-builder +/build-dir +/repo +*.flatpak diff --git a/pkg/flatpak/build.sh b/pkg/flatpak/build.sh new file mode 100755 index 0000000..a65961f --- /dev/null +++ b/pkg/flatpak/build.sh @@ -0,0 +1,4 @@ +#!/bin/sh -ex +cd $(dirname $0) +flatpak-builder "$@" --force-clean --repo repo build-dir com.solvespace.SolveSpace.json +flatpak build-bundle repo solvespace.flatpak com.solvespace.SolveSpace diff --git a/pkg/flatpak/com.solvespace.SolveSpace.json b/pkg/flatpak/com.solvespace.SolveSpace.json new file mode 100644 index 0000000..8c4ce51 --- /dev/null +++ b/pkg/flatpak/com.solvespace.SolveSpace.json @@ -0,0 +1,141 @@ +{ + "app-id": "com.solvespace.SolveSpace", + "runtime": "org.gnome.Platform", + "runtime-version": "3.30", + "sdk": "org.gnome.Sdk", + "finish-args": [ + /* Access to display server and OpenGL */ + "--share=ipc", "--socket=fallback-x11", "--socket=wayland", "--device=dri", + /* Access to save files */ + "--filesystem=home" + ], + "cleanup": [ + "/include", "/lib/*/include", + "*.a", "*.la", "*.m4", "/lib/libslvs*.so*", "/lib/libglibmm_generate_extra_defs*.so*", + "/share/pkgconfig", "*.pc", + "/share/man", "/share/doc", + "/share/aclocal", + /* mm-common junk */ + "/bin/mm-common-prepare", + "/share/mm-common" + ], + "command": "solvespace", + "modules": [ + { + "name": "mm-common", + "sources": [ + { + "type": "archive", + "url": "http://ftp.gnome.org/pub/GNOME/sources/mm-common/0.9/mm-common-0.9.12.tar.xz", + "sha256": "ceffdcce1e5b52742884c233ec604bf6fded12eea9da077ce7a62c02c87e7c0b" + } + ] + }, + { + "name": "sigc++", + "config-opts": [ + "--disable-documentation" + ], + "sources": [ + { + "type": "archive", + "url": "http://ftp.gnome.org/pub/GNOME/sources/libsigc++/2.10/libsigc++-2.10.1.tar.xz", + "sha256": "c9a25f26178c6cbb147f9904d8c533b5a5c5111a41ac2eb781eb734eea446003" + } + ] + }, + { + "name": "glibmm", + "config-opts": [ + "--disable-documentation" + ], + "sources": [ + { + "type": "archive", + "url": "http://ftp.gnome.org/pub/GNOME/sources/glibmm/2.58/glibmm-2.58.1.tar.xz", + "sha256": "6e5fe03bdf1e220eeffd543e017fd2fb15bcec9235f0ffd50674aff9362a85f0" + } + ] + }, + { + "name": "cairomm", + "config-opts": [ + "--disable-documentation" + ], + "sources": [ + { + "type": "archive", + "url": "http://ftp.gnome.org/pub/GNOME/sources/cairomm/1.12/cairomm-1.12.0.tar.xz", + "sha256": "a54ada8394a86182525c0762e6f50db6b9212a2109280d13ec6a0b29bfd1afe6" + } + ] + }, + { + "name": "pangomm", + "config-opts": [ + "--disable-documentation" + ], + "sources": [ + { + "type": "archive", + "url": "http://ftp.gnome.org/pub/GNOME/sources/pangomm/2.40/pangomm-2.40.2.tar.xz", + "sha256": "0a97aa72513db9088ca3034af923484108746dba146e98ed76842cf858322d05" + } + ] + }, + { + "name": "atkmm", + "config-opts": [ + "--disable-documentation" + ], + "sources": [ + { + "type": "archive", + "url": "http://ftp.gnome.org/pub/GNOME/sources/atkmm/2.28/atkmm-2.28.0.tar.xz", + "sha256": "4c4cfc917fd42d3879ce997b463428d6982affa0fb660cafcc0bc2d9afcedd3a" + } + ] + }, + { + "name": "gtkmm", + "config-opts": [ + "--disable-documentation" + ], + "sources": [ + { + "type": "archive", + "url": "http://ftp.gnome.org/pub/GNOME/sources/gtkmm/3.24/gtkmm-3.24.1.tar.xz", + "sha256": "ddfe42ed2458a20a34de252854bcf4b52d3f0c671c045f56b42aa27c7542d2fd" + } + ] + }, + { + "name": "libjson-c", + "sources": [ + { + "type": "archive", + "url": "https://s3.amazonaws.com/json-c_releases/releases/json-c-0.13.1-nodoc.tar.gz", + "sha256": "94a26340c0785fcff4f46ff38609cf84ebcd670df0c8efd75d039cc951d80132" + } + ], + "buildsystem": "cmake", + "builddir": true + }, + { + "name": "SolveSpace", + "sources": [ + { + "type": "git", + "path": "/home/whitequark/Projects/solvespace" + } + ], + "buildsystem": "cmake", + "builddir": true, + "config-opts": [ + "-DFLATPAK=ON", + "-DENABLE_CLI=OFF", + "-DENABLE_TESTS=OFF" + ] + } + ] +} diff --git a/pkg/snap/.gitignore b/pkg/snap/.gitignore new file mode 100644 index 0000000..9f938db --- /dev/null +++ b/pkg/snap/.gitignore @@ -0,0 +1,3 @@ +*.snap +solvespace-snap-src +squashfs-root diff --git a/pkg/snap/build.sh b/pkg/snap/build.sh new file mode 100755 index 0000000..abd7a86 --- /dev/null +++ b/pkg/snap/build.sh @@ -0,0 +1,12 @@ +#!/bin/sh -xe + +dir="$(dirname "$(readlink -f "$0")")" +solvespace_snap_src="$dir/solvespace-snap-src" +trap "rm -rf $solvespace_snap_src" EXIT + +cd "$dir" + +git_root="$(git rev-parse --show-toplevel)" +rsync --filter=":- .gitignore" -r "$git_root"/ "$solvespace_snap_src" + +snapcraft "$@" diff --git a/pkg/snap/snap/snapcraft.yaml b/pkg/snap/snap/snapcraft.yaml new file mode 100644 index 0000000..5fe5f7b --- /dev/null +++ b/pkg/snap/snap/snapcraft.yaml @@ -0,0 +1,80 @@ +name: solvespace +base: core18 +summary: Parametric 2d/3d CAD +adopt-info: solvespace +description: | + SOLVESPACE is a free (GPLv3) parametric 3d CAD tool. + Applications include + * modeling 3d parts — draw with extrudes, revolves, and Boolean (union / difference) operations + * modeling 2d parts — draw the part as a single section, and export DXF, PDF, SVG; use 3d assembly to verify fit + * 3d-printed parts — export the STL or other triangle mesh expected by most 3d printers + * preparing CAM data — export 2d vector art for a waterjet machine or laser cutter; or generate STEP or STL, for import into third-party CAM software for machining + * mechanism design — use the constraint solver to simulate planar or spatial linkages, with pin, ball, or slide joints + * plane and solid geometry — replace hand-solved trigonometry and spreadsheets with a live dimensioned drawing + +confinement: strict +license: GPL-3.0 + +layout: + /usr/share/solvespace: + symlink: $SNAP/usr/share/solvespace + +apps: + solvespace: + command: usr/bin/solvespace + desktop: solvespace.desktop + extensions: [gnome-3-34] + plugs: [opengl, unity7, home, removable-media, gsettings, network] + environment: + __EGL_VENDOR_LIBRARY_DIRS: $SNAP/gnome-platform/usr/share/glvnd/egl_vendor.d:$SNAP/usr/share/glvnd/egl_vendor.d + cli: + command: usr/bin/solvespace-cli + extensions: [gnome-3-34] + plugs: [home, removable-media, network] + +parts: + solvespace: + plugin: cmake + source: ./solvespace-snap-src + source-type: local + override-pull: | + snapcraftctl pull + version_major=$(grep "solvespace_VERSION_MAJOR" CMakeLists.txt | tr -d "()" | cut -d" " -f2) + version_minor=$(grep "solvespace_VERSION_MINOR" CMakeLists.txt | tr -d "()" | cut -d" " -f2) + version="$version_major.$version_minor~$(git rev-parse --short=8 HEAD)" + snapcraftctl set-version "$version" + git describe --exact-match HEAD && grade="stable" || grade="devel" + snapcraftctl set-grade "$grade" + git submodule update --init extlib/libdxfrw extlib/mimalloc + configflags: + - -DCMAKE_INSTALL_PREFIX=/usr + - -DCMAKE_BUILD_TYPE=Release + - -DENABLE_TESTS=OFF + - -DSNAP=ON + - -DENABLE_OPENMP=ON + - -DENABLE_LTO=ON + build-packages: + - zlib1g-dev + - libpng-dev + - libfreetype6-dev + - libjson-c-dev + - libgl-dev + - libsigc++-2.0-dev + - libspnav-dev + - git + - g++ + stage-packages: + - libspnav0 + - libsigc++-2.0-0v5 + + cleanup: + after: [solvespace] + plugin: nil + build-snaps: [core18, gnome-3-34-1804] + override-prime: | + # Remove all files from snap that are already included in the base snap or in + # any connected content snaps + set -eux + for snap in "core18" "gnome-3-34-1804"; do # List all content-snaps and base snaps you're using here + cd "/snap/$snap/current" && find . -type f,l -exec rm -f "$SNAPCRAFT_PRIME/{}" \; + done diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt new file mode 100644 index 0000000..e261ba2 --- /dev/null +++ b/res/CMakeLists.txt @@ -0,0 +1,296 @@ +# First, set up registration functions for the kinds of resources we handle. +set(resource_root ${CMAKE_CURRENT_SOURCE_DIR}/) +set(resource_list) +if(WIN32) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/win32/versioninfo.rc.in + ${CMAKE_CURRENT_BINARY_DIR}/win32/versioninfo.rc) + + set(rc_file ${CMAKE_CURRENT_BINARY_DIR}/resources.rc) + file(WRITE ${rc_file} "// Autogenerated; do not edit\n") + file(APPEND ${rc_file} "#include \n") + file(APPEND ${rc_file} "#include \"${CMAKE_CURRENT_BINARY_DIR}/win32/versioninfo.rc\"\n") + + function(add_resource name) + set(source ${CMAKE_CURRENT_SOURCE_DIR}/${name}) + + if(${ARGC} GREATER 1) + set(id ${ARGV1}) + else() + string(REPLACE ${resource_root} "" id ${source}) + endif() + if(${ARGC} GREATER 2) + set(type ${ARGV2}) + else() + set(type RCDATA) + endif() + file(SHA512 "${source}" hash) + file(APPEND ${rc_file} "${id} ${type} \"${source}\" // ${hash}\n") + # CMake doesn't track file dependencies across directories, so we force + # a reconfigure (which changes the RC file because of the hash above) + # every time a resource is changed. + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${source}") + endfunction() +elseif(APPLE) + set(app_resource_dir ${CMAKE_BINARY_DIR}/bin/SolveSpace.app/Contents/Resources) + set(cli_resource_dir ${CMAKE_BINARY_DIR}/res) + + function(add_resource name) + set(source ${CMAKE_CURRENT_SOURCE_DIR}/${name}) + set(target_app ${app_resource_dir}/${name}) + set(target_cli ${cli_resource_dir}/${name}) + set(resource_list "${resource_list};${target_app};${target_cli}" PARENT_SCOPE) + + get_filename_component(target_app_dir ${target_app} DIRECTORY) + get_filename_component(target_cli_dir ${target_cli} DIRECTORY) + add_custom_command( + OUTPUT ${target_app} ${target_cli} + COMMAND ${CMAKE_COMMAND} -E make_directory ${target_app_dir} + COMMAND ${CMAKE_COMMAND} -E copy ${source} ${target_app} + COMMAND ${CMAKE_COMMAND} -E make_directory ${target_cli_dir} + COMMAND ${CMAKE_COMMAND} -E copy ${source} ${target_cli} + COMMENT "Copying resource ${name}" + DEPENDS ${source} + VERBATIM) + endfunction() + + function(add_xib name) + set(source ${CMAKE_CURRENT_SOURCE_DIR}/${name}) + get_filename_component(basename ${name} NAME_WE) + set(target ${app_resource_dir}/${basename}.nib) + set(resource_list "${resource_list};${target}" PARENT_SCOPE) + + add_custom_command( + OUTPUT ${target} + COMMAND ${CMAKE_COMMAND} -E make_directory ${app_resource_dir} + COMMAND ibtool --errors --warnings --notices --output-format human-readable-text + --compile ${target} ${source} + COMMENT "Building Interface Builder file ${name}" + DEPENDS ${source} + VERBATIM) + endfunction() + + function(add_iconset name) + set(source ${CMAKE_CURRENT_SOURCE_DIR}/${name}) + get_filename_component(basename ${name} NAME_WE) + set(target ${app_resource_dir}/${basename}.icns) + set(resource_list "${resource_list};${target}" PARENT_SCOPE) + + add_custom_command( + OUTPUT ${target} + COMMAND ${CMAKE_COMMAND} -E make_directory ${app_resource_dir} + COMMAND iconutil -c icns -o ${target} ${source} + COMMENT "Building icon set ${name}" + DEPENDS ${source} + VERBATIM) + endfunction() +else() # Unix + include(GNUInstallDirs) + + set(app_resource_dir ${CMAKE_BINARY_DIR}/res) + + function(add_resource name) + set(source ${CMAKE_CURRENT_SOURCE_DIR}/${name}) + set(target ${app_resource_dir}/${name}) + set(resource_list "${resource_list};${target}" PARENT_SCOPE) + + get_filename_component(target_dir ${target} DIRECTORY) + add_custom_command( + OUTPUT ${target} + COMMAND ${CMAKE_COMMAND} -E make_directory ${target_dir} + COMMAND ${CMAKE_COMMAND} -E copy ${source} ${target} + COMMENT "Copying resource ${name}" + DEPENDS ${source} + VERBATIM) + + get_filename_component(name_dir ${name} DIRECTORY) + install(FILES ${source} + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/solvespace/${name_dir}) + endfunction() +endif() + +function(add_resources) + foreach(name ${ARGN}) + add_resource(${name}) + set(resource_list "${resource_list}" PARENT_SCOPE) + endforeach() +endfunction() + +# Second, register all resources. +if(WIN32) + add_resource(win32/icon.ico 4000 ICON) + add_resource(win32/manifest.xml 1 RT_MANIFEST) +elseif(APPLE) + add_iconset (cocoa/AppIcon.iconset) + add_xib (cocoa/MainMenu.xib) + add_xib (cocoa/SaveFormatAccessory.xib) +else() + add_resource(freedesktop/solvespace-48x48.png) + + if(FLATPAK) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/freedesktop/solvespace-flatpak.desktop.in + ${CMAKE_CURRENT_BINARY_DIR}/freedesktop/solvespace-flatpak.desktop) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freedesktop/solvespace-flatpak.desktop + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications + RENAME com.solvespace.SolveSpace.desktop) + + install(FILES freedesktop/solvespace-flatpak-mime.xml + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mime/packages + RENAME com.solvespace.SolveSpace-slvs.xml) + + install(FILES freedesktop/solvespace-scalable.svg + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps + RENAME com.solvespace.SolveSpace.svg) + install(FILES freedesktop/solvespace-scalable.svg + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/mimetypes + RENAME com.solvespace.SolveSpace.svg) + + foreach(SIZE 16x16 24x24 32x32 48x48) + install(FILES freedesktop/solvespace-${SIZE}.png + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}/apps + RENAME com.solvespace.SolveSpace.png) + install(FILES freedesktop/solvespace-${SIZE}.png + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}/mimetypes + RENAME com.solvespace.SolveSpace.png) + endforeach() + elseif(SNAP) + install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/freedesktop/solvespace-snap.desktop + DESTINATION / + RENAME solvespace.desktop) + + # snapd does not support registering new mime types + + install(FILES freedesktop/solvespace-scalable.svg + DESTINATION /meta/icons/hicolor/scalable/apps + RENAME snap.solvespace.svg) + + foreach(SIZE 16x16 24x24 32x32 48x48) + install(FILES freedesktop/solvespace-${SIZE}.png + DESTINATION /meta/icons/hicolor/${SIZE}/apps + RENAME snap.solvespace.png) + endforeach() + else() + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/freedesktop/solvespace.desktop.in + ${CMAKE_CURRENT_BINARY_DIR}/freedesktop/solvespace.desktop) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freedesktop/solvespace.desktop + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications) + + install(FILES freedesktop/solvespace-mime.xml + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/mime/packages + RENAME solvespace-slvs.xml) + + install(FILES freedesktop/solvespace-scalable.svg + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/apps + RENAME solvespace.svg) + install(FILES freedesktop/solvespace-scalable.svg + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/scalable/mimetypes + RENAME application.x-solvespace.svg) + + foreach(SIZE 16x16 24x24 32x32 48x48) + install(FILES freedesktop/solvespace-${SIZE}.png + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}/apps + RENAME solvespace.png) + install(FILES freedesktop/solvespace-${SIZE}.png + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}/mimetypes + RENAME application.x-solvespace.png) + endforeach() + + foreach(SIZE 16x16 24x24 32x32 48x48) + install(FILES freedesktop/solvespace-${SIZE}.xpm + DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps) + endforeach() + endif() +endif() + +add_resources( + banner.txt + icons/graphics-window/angle.png + icons/graphics-window/arc.png + icons/graphics-window/assemble.png + icons/graphics-window/bezier.png + icons/graphics-window/circle.png + icons/graphics-window/construction.png + icons/graphics-window/equal.png + icons/graphics-window/extrude.png + icons/graphics-window/helix.png + icons/graphics-window/horiz.png + icons/graphics-window/image.png + icons/graphics-window/in3d.png + icons/graphics-window/lathe.png + icons/graphics-window/length.png + icons/graphics-window/line.png + icons/graphics-window/ontoworkplane.png + icons/graphics-window/other-supp.png + icons/graphics-window/parallel.png + icons/graphics-window/perpendicular.png + icons/graphics-window/pointonx.png + icons/graphics-window/point.png + icons/graphics-window/rectangle.png + icons/graphics-window/ref.png + icons/graphics-window/revolve.png + icons/graphics-window/same-orientation.png + icons/graphics-window/sketch-in-3d.png + icons/graphics-window/sketch-in-plane.png + icons/graphics-window/step-rotate.png + icons/graphics-window/step-translate.png + icons/graphics-window/symmetric.png + icons/graphics-window/tangent-arc.png + icons/graphics-window/text.png + icons/graphics-window/trim.png + icons/graphics-window/vert.png + icons/text-window/constraint.png + icons/text-window/construction.png + icons/text-window/edges.png + icons/text-window/faces.png + icons/text-window/occluded-visible.png + icons/text-window/occluded-stippled.png + icons/text-window/occluded-invisible.png + icons/text-window/mesh.png + icons/text-window/normal.png + icons/text-window/outlines.png + icons/text-window/point.png + icons/text-window/shaded.png + icons/text-window/workplane.png + locales.txt + locales/de_DE.po + locales/en_US.po + locales/fr_FR.po + locales/uk_UA.po + locales/ru_RU.po + locales/zh_CN.po + fonts/unifont.hex.gz + fonts/private/0-check-false.png + fonts/private/1-check-true.png + fonts/private/2-radio-false.png + fonts/private/3-radio-true.png + fonts/private/4-stipple-dot.png + fonts/private/5-stipple-dash-long.png + fonts/private/6-stipple-dash.png + fonts/private/7-stipple-zigzag.png + fonts/unicode.lff.gz + fonts/BitstreamVeraSans-Roman-builtin.ttf + shaders/imesh.frag + shaders/imesh.vert + shaders/imesh_point.frag + shaders/imesh_point.vert + shaders/imesh_tex.frag + shaders/imesh_texa.frag + shaders/imesh_tex.vert + shaders/mesh.frag + shaders/mesh.vert + shaders/mesh_fill.frag + shaders/mesh_fill.vert + shaders/edge.frag + shaders/edge.vert + shaders/outline.vert + threejs/three-r76.js.gz + threejs/hammer-2.0.8.js.gz + threejs/SolveSpaceControls.js) + +# Third, distribute the resources. +add_custom_target(resources + DEPENDS ${resource_list}) +if(WIN32) + set_property(TARGET resources PROPERTY EXTRA_SOURCES ${rc_file}) +endif() diff --git a/res/banner.txt b/res/banner.txt new file mode 100644 index 0000000..ad8f4f8 --- /dev/null +++ b/res/banner.txt @@ -0,0 +1 @@ +SolveSpace! diff --git a/res/cocoa/AppIcon.iconset/icon_128x128.png b/res/cocoa/AppIcon.iconset/icon_128x128.png new file mode 100644 index 0000000000000000000000000000000000000000..363e89161a4804a5338624941481f15f915be2ea GIT binary patch literal 891 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7xzrU~J8Fb`B^Ga(7bjbagf}v@|o* zHPSO=V9=OYI&r7Bv!g)!eig4H%&x%^5lcG6CUv+8zO@nHcbXuf7&!aMQz4<+J>r5J zw`|zD;lqJr3TD@Cb^dQq;K)*KS{tEpqr)bBvP091$g=OZ@1HyK?p%}Yq^m_~vGz}{ zeR9jFIwaevw{xz(MaJT}c~VKUR`#Di&%Povp8v*`n)kswvwr{0_U&AQ zJs)}s3XIol+X<9q&Wv#S;dCSW1Z(U3DRTNBXFn>L_*QHAX^wWa*4RVuN<@#ZjyNr0 z`A{*@UvKxqsqYuZU78aU9TTwYi=K~@k8$Jd$YnE9W-z*?${cH-ZxkWkeW5@1f(`rE_0zuIkRkS(2GyZ=2#PW;ZwPrnMi7J2aY1g8o=O1M8Th0GELr~j`@8!1;F1vFJ zRk>u#FYJg}67`xANvMrhh;7ef;fleTVh>=y-} zOJvVnHey8hF0b=FYffqZU(I)K*FT8gttgD--)T2k@9gG^&HDOoe*^0bq+l?= zZrrkA>xK^pjwzU3yVd!>L4hMnwP|gH#*Ge}^vMoQGa}2r-@bqD%)4_ruWct#mN_%R>4(#e>=Uf5^QXw^f1LfOWa3+`<)=B?)mmc@y(Oms}Zt}l8%PCmwsvm=+yNSVRtmMU|seZE~}pz^)=9{x>w z8)x-cMN6!iq~kL6{FTR)GLb&YC zEmY-_Ex)iMW>s|M{6oqu+Z7AA+ubiH|68lQ|JmDg9p4kv4g%wav%n*=n1Mk|6@(c* zgH%2+Ffdzqx;TbZ%z1lvWA32<5r;tGi-%a&JmfSgSNkC4!@xYjOh{;=Xh-fl%dOr0 z!m)cF*-L<;7$10GzI!SE2B+;a&sVqSTswY=one|XgMb?C(YE+s3^}KN7VJD*`LD$G zU0kWyzjG`MiA;D=8DquD%vot~`Fb8_ls}N4$)Mmfq)^WGFN|R?%s&5|zVGnoheqFR zYzlVC{XPFbfvLfO5ik0_=>6I(@q~4mv)=I8T(sz0{p+{gY)*zlEO^nqU-Ld2@Em^r zbi=CMALEa|zP-PA+hKyC{Cg?C!I}SZ|JJUqjgyNmF+W03NA?ZYim$ORw%*!AdjTM>r>mdKI;Vst0D>lteE4?>U_AyJ#; z~msgKXk2dHUZ57^Xv?^C&I`~7Q8iKMB4twDH9 z(~Z3FjBs!>uPZ(fc4?VdLij@1YsdwKpOhXi@tfjwk?ks{%Ls=igGo6#KF*;f3LSUQxLm4R zd7r`~gtsAZ3x`M0BmS)`zvk^{EKSIk!2kdN32;bRa{vGf6951U69E94oEQKA0BcD^ zK~y-6V_-l9{~1UGOr&ZU7z3X0e!}TBqFr$M^l7Yy43RLPsR4{={Qod9d?7FMnGdcH zrvVHMxI>@~ literal 0 HcmV?d00001 diff --git a/res/cocoa/AppIcon.iconset/icon_16x16@2x.png b/res/cocoa/AppIcon.iconset/icon_16x16@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d9f276ab5d34eab271ff6461b9b46f67e273e372 GIT binary patch literal 626 zcmV-&0*(ENP)4?>U_AyJ#; z~msgKXk2dHUZ57^Xv?^C&I`~7Q8iKMB4twDH9 z(~Z3FjBs!>uPZ(fc4?VdLij@1YsdwKpOhXi@tfjwk?ks{%Ls=igGo6#KF*;f3LSUQxLm4R zd7r`~gtsAZ3x`M0BmS)`zvk^{EKSIk!2kdN32;bRa{vGqB>(^xB>_oNB=7(L0Fy~X zK~z|UV_?7y{zEZM0TZn)7}C%m8jKjHmEa;_OZApirXPoMsO`t)g{Lt^-a zz^DU89Wd&EA?E-_JaYfBsUfGlXJBApkonAq)vloz0x&>Id5;WCO-)hE8+;+){D~K< z&-U_t#ur*-g8>f#76#(m{xs<$42lpyk6T zZrrkA>xK^pjwzU3yVd!>L4hMnwP|gH#*Ge}^vMoQGa}2r-@bqD%)4_ruWct#mN_%R>4(#e>=Uf5^QXw^f1LfOWa3+`<)=B?)mmc@y(Oms}Zt}l8%PCmwsvm=+yNSVRtmMU|seZE~}pz^)=9{x>w z8)x-cMN6!iq~kL6{FTR)GLb&YC zEmY-_Ex)iMW>s|M{6oqu+Z7AA+ubiH|68lQ|JmDg9p4kv4g%wav%n*=n1O*?7=#%a zX3ddcU|_cJba4!+nDh4T#@s^zA`XGV7Z0(ldB|y0uJ%F7hk<#5nUK&#(T?1AmRq~~ zg=6#JHs?(1_3qNqiylO7;;YkEZBLr@?VMV zySP%Zf9F^j5}EL#GRBIPnX}T~^7TB0#kzlBVP1<(fhSo;tA_AXT9OGxoFY1`qyu}*_;fASn#5Izvg{5;5q#K z>4sIiKgJ(_eS3fLw!;KN`S((OgERl-{;geI8z&cCVt$06j_ez(6<=dtY`wep`)-Cc wZ3NwQ$9unddHDhBl+8X=NNM=eH%RWo0rN>LGA+IJ_X0p%Pgg&ebxsLQ0DgXr;s5{u literal 0 HcmV?d00001 diff --git a/res/cocoa/AppIcon.iconset/icon_256x256@2x.png b/res/cocoa/AppIcon.iconset/icon_256x256@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a380eb77900e8f23c7929e12ccc6ccb5e3a04271 GIT binary patch literal 2506 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&zE~)R&4YzZe)8TQi-V1B!#(ofJG>oy`m_ z&CGO-^b8poG$xi#-0AJ?DA2xN#p?*OYj8xwk`A#+9d3eeZ3Ot8CP*j-&VKS#NT_y? zxZuVu8@6uvaNwAN*|l4p{~HuIvQ(SaMrhpVut}fn&@>~m?ECHe=gz!4*JL~CYEfFO z{gZ2-+%l>T$#&}PoU3nSCAVFm^P6$S28c59x{*22+vA3W**!nP_#zkHv0|1af#cw9CAZ|#H3_x-oM|L>o1 znw6%xazXA_raAX!*xZ-?)BV^Yt-ikE*1q@u_UoUay|p!G&;Kr6bMN7qy1R1sEDq%F zplw-H61n#PXU|n`gQ@q$e@q5?TYD!REX-Lg{$tU`s>aFHU+;@2aEa5lXx(;|yPzuh rQ%$}=0wayBqJ2d%fORIw>WW+HS)b)t8XT6q0C7EC{an^LB{Ts5!S&mP literal 0 HcmV?d00001 diff --git a/res/cocoa/AppIcon.iconset/icon_32x32.png b/res/cocoa/AppIcon.iconset/icon_32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..60bf2c5ff1b13145db0f776c3d63831217be1716 GIT binary patch literal 626 zcmV-&0*(ENP)4?>U_AyJ#; z~msgKXk2dHUZ57^Xv?^C&I`~7Q8iKMB4twDH9 z(~Z3FjBs!>uPZ(fc4?VdLij@1YsdwKpOhXi@tfjwk?ks{%Ls=igGo6#KF*;f3LSUQxLm4R zd7r`~gtsAZ3x`M0BmS)`zvk^{EKSIk!2kdN32;bRa{vGf6951U69E94oEQKA0Fy~X zK~z|UV_?7y{zEZM0TZn)7}C%m8jKjHmEa;_OZApirXPoMsO`t)g{Lt^-a zz^DU89Wd&EA?E-_JaYfBsUfGlXJBApkonAq)vloz0x&>Id5;WCO-)hE8+;+){D~K< z&-U_t#ur*-g8>f#76#(m{xs<$42lpyk6Tr5J zw`|zD;lqJr3TD@Cb^dQq;K)*KS{tEpqr)bBvP091$g=OZ@1HyK?p%}Yq^m_~vGz}{ zeR9jFIwaevw{xz(MaJT}c~VKUR`#Di&%Povp8v*`n)kswvwr{0_U&AQ zJs)}s3XIol+X<9q&Wv#S;dCSW1Z(U3DRTNBXFn>L_*QHAX^wWa*4RVuN<@#ZjyNr0 z`A{*@UvKxqsqYuZU78aU9TTwYi=K~@k8$Jd$YnE9W-z*?${cH-ZxkWkeW5@1f(`rE_0zuIkRkS(2GyZ=2#PW;ZwPrnMi7J2aY1g8o=O1M8Th0GELr~j`@8!1;F1vFJ zRk>u#FYJg}6V2`J~#)X6nH}}_Ro!-U5 zvBlT&{+sgMkL~piH;XMWWYBd;W{7Gy#;}E-F&QAZk1hj z%X|iq;Pl(fMaK$b-g0U#-T#jBq51)29c&9&Gk6@hFGw_?8hLi!=dFwKTRs*4yESE> zJBK|ZNa3pYjFvww>vOl=Q-+#7`}KFzuddnOY|m`}Rc7&r1!T<2S@&Q63iR81PF@uz x@V2_~lIh#p19J_4t}gyndEhG4M3~i)3~uwKn_udc{s)E?gQu&X%Q~loCIBVCLj?c; literal 0 HcmV?d00001 diff --git a/res/cocoa/AppIcon.iconset/icon_512x512.png b/res/cocoa/AppIcon.iconset/icon_512x512.png new file mode 100644 index 0000000000000000000000000000000000000000..6dcc757da086429df0ae3aaac7b1715b76071472 GIT binary patch literal 2506 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&zE~)R&4YzZe)8TQi-V1B!#(ofJG>oy`m_ z&CGO-^b8poG$xi#-0AJ?DA2xN#p?*OYj8xwk`A#+9d3eeZ3Ot8CP*j-&VKS#NT_y? zxZuVu8@6uvaNwAN*|l4p{~HuIvQ(SaMrhpVut}fn&@>~m?ECHe=gz!4*JL~CYEfFO z{gZ2-+%l>T$#&}PoU3n{y3wXRfh)p%!V`t`%~SqY zv+}TA;rcOSyE)LP0R#>8$$a=h1y#wP qYVrjV7-?)3?JJ4_tTRDYSKLz1`YgxN;IQNci0kR<=d#Wzp$P!xzuM{m literal 0 HcmV?d00001 diff --git a/res/cocoa/AppIcon.iconset/icon_512x512@2x.png b/res/cocoa/AppIcon.iconset/icon_512x512@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d45152055356772603ddc7ebaf94642a690617d6 GIT binary patch literal 6490 zcmeAS@N?(olHy`uVBq!ia0y~yU;#2&7&zE~RK2WrGXn!-Yo@bvKyi?}lY*zKvzei# znVGJUo*@H+#>CQzJH4G91={zkcpYJO4UULd(jhjf!%gt5jR3#X1PR5!*-xGd3Dxcq z7u>jI!`2NS4jfZ3yLPMde}e)?mTJ@52#p&ZHtCZcnr1|neZPJG+?jXhnrtUsElP{E ze{$`UTSnC(*-pKkbM-AU7SGL-N}9E@|NMFO6`Aq;H?GvY58j#e`){^y=aQ9;YaJ_m zF8A*F&{I%gyk6T*pe%D{gwqeF8`&pVTjx)a)Bia8QOU%&TFXy!w5zqo9(q?IdVF=n zX$i}Rii!SuyBAJp4qQ`GZfp79BnRAdBB>{?{3T+FpDwzlCtw zom;5NC0l-BN6f0|%K3+sTed3}aJRc(Q2w`8d;hby={mkArX2*v3ul2xWHAGSm?{V} zdIqU{U|*m{7xg+Dpa*E8kvb=KI9hCf}`-O@uot@KwBM}S?p00i_>zopr0149x)Bpeg literal 0 HcmV?d00001 diff --git a/res/cocoa/MainMenu.xib b/res/cocoa/MainMenu.xib new file mode 100644 index 0000000..38db0d9 --- /dev/null +++ b/res/cocoa/MainMenu.xib @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/cocoa/SaveFormatAccessory.xib b/res/cocoa/SaveFormatAccessory.xib new file mode 100644 index 0000000..3baf4c6 --- /dev/null +++ b/res/cocoa/SaveFormatAccessory.xib @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/fonts/BitstreamVeraSans-Roman-builtin.ttf b/res/fonts/BitstreamVeraSans-Roman-builtin.ttf new file mode 100644 index 0000000000000000000000000000000000000000..550fe3648afc587e9c687ced270a5ee3d300f186 GIT binary patch literal 54524 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

?tm?LU=BiO$ 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 literal 0 HcmV?d00001 diff --git a/res/fonts/private/0-check-false.png b/res/fonts/private/0-check-false.png new file mode 100644 index 0000000000000000000000000000000000000000..b9020c33b8c437c8617a537d3b03c173e421b2f0 GIT binary patch literal 218 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl%OyKpTSt fL*frHg#!$+84N28+$Y-tZDH_q^>bP0l+XkK*)B9y literal 0 HcmV?d00001 diff --git a/res/fonts/private/1-check-true.png b/res/fonts/private/1-check-true.png new file mode 100644 index 0000000000000000000000000000000000000000..7f6a42c554193d2abbd2b4a8023009fb8864be24 GIT binary patch literal 243 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLlS!3>*qfc7zXy85}S Ib4q9e0Hf$QhX4Qo literal 0 HcmV?d00001 diff --git a/res/fonts/private/3-radio-true.png b/res/fonts/private/3-radio-true.png new file mode 100644 index 0000000000000000000000000000000000000000..5322f587264a18b394550c53b8803bc5038d9612 GIT binary patch literal 231 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJOS+@4BLl#%q#+J&w=`!859mMBwb+G8Fuk* Q570^mPgg&ebxsLQ0A3F|lmGw# literal 0 HcmV?d00001 diff --git a/res/fonts/private/4-stipple-dot.png b/res/fonts/private/4-stipple-dot.png new file mode 100644 index 0000000000000000000000000000000000000000..52fc21951037b0598c36114f0556b5de17103530 GIT binary patch literal 936 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±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�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�W*p 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∋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 literal 0 HcmV?d00001 diff --git a/res/freedesktop/solvespace-16x16.xpm b/res/freedesktop/solvespace-16x16.xpm new file mode 100644 index 0000000..3cd0662 --- /dev/null +++ b/res/freedesktop/solvespace-16x16.xpm @@ -0,0 +1,27 @@ +/* XPM */ +static char *solvespace_16x16[] = { +/* columns rows colors chars-per-pixel */ +"16 16 5 1 ", +" c black", +". c #1ED500", +"X c #DE00D6", +"o c #CBCBCB", +"O c None", +/* pixels */ +"OOO OOOOOOOOOOOO", +"OOO OOOOOOOOOOOO", +"OOO OOOOOOOOOOOO", +"OOO OOOOOXOOOOOO", +"OOO OOOOOXoOOOOO", +"OOO OOOOOXoOOOOO", +"OOO OOOOOXoOOOOO", +"OOO OOOOOXoOOOOO", +"OOO OOOOOXoOOOOO", +"OOO OOXXXXXXXOOO", +"OOO OOOoooooooOO", +"OO...OOOOOOOOOOO", +" ... ", +"OO...OOOOOOOOOOO", +"OOO OOOOOOOOOOOO", +"OOO OOOOOOOOOOOO" +}; diff --git a/res/freedesktop/solvespace-24x24.png b/res/freedesktop/solvespace-24x24.png new file mode 100644 index 0000000000000000000000000000000000000000..7ba03eed8c58e3fbb291f8ae089bb3a2be9a82a2 GIT binary patch literal 338 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaN3?zjj6;1;wmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5ln@H=32_C|KyZ)Y+Ue7$ z<*qXP|Nno@tR37yA;yv*zhDN3XE)M7oFs2|7uFy7FOLH`>?NMQuI%@jMVUmz7b?Zy z1_~K?x;TbNTux3<;5QIDo9OgVBH&nHP*6}q@r>Ty-i0#a>@9Pf^!l0<8Z?`aFI>XJ z!2XIwewzEDBS5{XC9V-ADTyViR>?)FK#IZ0z|d6Jz*yJFAjHtv%GAKh#8}(F*vi0Q igS?6miiX_$l+3hB+!_u#%~=Q3z~JfX=d#Wzp$Pyu|6K_H literal 0 HcmV?d00001 diff --git a/res/freedesktop/solvespace-24x24.xpm b/res/freedesktop/solvespace-24x24.xpm new file mode 100644 index 0000000..9d1c02e --- /dev/null +++ b/res/freedesktop/solvespace-24x24.xpm @@ -0,0 +1,35 @@ +/* XPM */ +static char *solvespace_24x24[] = { +/* columns rows colors chars-per-pixel */ +"24 24 5 1 ", +" c black", +". c #1ED500", +"X c #DE00D6", +"o c #CBCBCB", +"O c None", +/* pixels */ +"OOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOO OOOOOOOOOOOOOOOO", +"OOOOOOO OOOOOOOOOOOOOOOO", +"OOOOOOO OOOOOOOOOOOOOOOO", +"OOOOOOO OOOOOXOOOOOOOOOO", +"OOOOOOO OOOOOXoOOOOOOOOO", +"OOOOOOO OOOOOXoOOOOOOOOO", +"OOOOOOO OOOOOXoOOOOOOOOO", +"OOOOOOO OOOOOXoOOOOOOOOO", +"OOOOOOO OOOOOXoOOOOOOOOO", +"OOOOOOO OOXXXXXXXOOOOOOO", +"OOOOOOO OOOoooooooOOOOOO", +"OOOOOO...OOOOOOOOOOOOOOO", +"OOOO ... OOOO", +"OOOOOO...OOOOOOOOOOOOOOO", +"OOOOOOO OOOOOOOOOOOOOOOO", +"OOOOOOO OOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOO" +}; diff --git a/res/freedesktop/solvespace-32x32.png b/res/freedesktop/solvespace-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..a24bf6a8472c7c7b2cbbe0f3d72f09759ff6def4 GIT binary patch literal 348 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnF3?v&v(vJfvmUKs7M+SzC{oH>NSwWJ?9znhg z3{`3j3=J&|48MRv4KElNN(~qoUL`OvSj}Ky5HFasE6@fgAr#;f;tHgJ;2y)Z)2C0% zU1j+H|Noj?;(M5ynj9D%Sq_LO zRdP`(kYX@0Ff`RQFxE9P2r)FaGBvO= qG1fLPwlXl-Ag>~Xq9HdwB{QuOw}yjGbJhVhFnGH9xvXI{(rPmO*bPE`X1*QT2iEIb=-Hu6r;dHCp&)1;OK3IR?6 zj2zw*^4LRdJED_TFf**$#4|hnmaRC@B-Ikvh?11Vl2ohYqEsNoU}Ruus%v1ZYh(~& wXl!L_U}a*gZD4F=V6Z`6MF>ShZhlH;S|x4`2c71u18QLKboFyt=akR{0Omwt`Tzg` literal 0 HcmV?d00001 diff --git a/res/freedesktop/solvespace-48x48.xpm b/res/freedesktop/solvespace-48x48.xpm new file mode 100644 index 0000000..c5adf53 --- /dev/null +++ b/res/freedesktop/solvespace-48x48.xpm @@ -0,0 +1,59 @@ +/* XPM */ +static char *solvespace_48x48[] = { +/* columns rows colors chars-per-pixel */ +"48 48 5 1 ", +" c black", +". c #1ED500", +"X c #DE00D6", +"o c #CBCBCB", +"O c None", +/* pixels */ +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOXXOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOXXoOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOXXXXXXXXXXXXOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOXXXXXXXXXXXXOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOooooooooooooOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOO......OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOO......OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOO ...... OOOOOOOO", +"OOOOOOOO ...... OOOOOOOO", +"OOOOOOOOOOOO......OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOO......OOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOO OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO", +"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO" +}; diff --git a/res/freedesktop/solvespace-flatpak-mime.xml b/res/freedesktop/solvespace-flatpak-mime.xml new file mode 100644 index 0000000..760799d --- /dev/null +++ b/res/freedesktop/solvespace-flatpak-mime.xml @@ -0,0 +1,8 @@ + + + + SolveSpace model + + + + diff --git a/res/freedesktop/solvespace-flatpak.desktop.in b/res/freedesktop/solvespace-flatpak.desktop.in new file mode 100644 index 0000000..b16ccf4 --- /dev/null +++ b/res/freedesktop/solvespace-flatpak.desktop.in @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Name=SolveSpace +Comment=A parametric 2d/3d CAD +Exec=${CMAKE_INSTALL_FULL_BINDIR}/solvespace +MimeType=application/x-solvespace +Icon=com.solvespace.SolveSpace +Type=Application +Categories=Graphics +Keywords=parametric;cad;2d;3d; diff --git a/res/freedesktop/solvespace-mime.xml b/res/freedesktop/solvespace-mime.xml new file mode 100644 index 0000000..8ee132c --- /dev/null +++ b/res/freedesktop/solvespace-mime.xml @@ -0,0 +1,8 @@ + + + + SolveSpace model + + + + diff --git a/res/freedesktop/solvespace-scalable.svg b/res/freedesktop/solvespace-scalable.svg new file mode 100644 index 0000000..0d060d1 --- /dev/null +++ b/res/freedesktop/solvespace-scalable.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/res/freedesktop/solvespace-snap.desktop b/res/freedesktop/solvespace-snap.desktop new file mode 100644 index 0000000..8441258 --- /dev/null +++ b/res/freedesktop/solvespace-snap.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Name=SolveSpace +Comment=A parametric 2d/3d CAD +Exec=solvespace +MimeType=application/x-solvespace +Icon=${SNAP}/meta/icons/hicolor/scalable/apps/snap.solvespace.svg +Type=Application +Categories=Graphics +Keywords=parametric;cad;2d;3d; diff --git a/res/freedesktop/solvespace.desktop.in b/res/freedesktop/solvespace.desktop.in new file mode 100644 index 0000000..8c6fb24 --- /dev/null +++ b/res/freedesktop/solvespace.desktop.in @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Name=SolveSpace +Comment=A parametric 2d/3d CAD +Exec=${CMAKE_INSTALL_FULL_BINDIR}/solvespace +MimeType=application/x-solvespace +Icon=solvespace +Type=Application +Categories=Graphics +Keywords=parametric;cad;2d;3d; diff --git a/res/icons/graphics-window/angle.png b/res/icons/graphics-window/angle.png new file mode 100644 index 0000000000000000000000000000000000000000..f70252a937e1bac714ac402019680cd90484b7b6 GIT binary patch literal 819 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpv3@#yNKc?$D7 zr8{%Qay|JyC0HdSB_$8;IcUXW6)G57B3?2_e$H~mE7O|k9pa~Nuq>H8>*EpV&le12FT}w+#TwI(1m%&P<;y!eJAHk9_4W1n`1t0}pWo2XU|?V%ARuu3 z(ma1)P%xGR`2{mLJiCzw;v{*yyD)UH%6b4foCO|{#S9GGLLkg|>2BR0pdfpRr>`sf z0~RqJX^t;bm*xV64tTmahG?8mPB_2}433i%6POqU`Z15?5XQ#h^@Z!mnH%t>5CaueRCpRzdp54Bvx_^u(K8j1ENXt0Y z^gL!@*nW*aFXL6=YoK4mN?apKoQqNuOEUBG6hbm{QyB~m^bJk)4J`83UDO7uPz9+- zNi0dVN(L!QWiT=@G}ARO(KRv(F*LF=FtReX)HX1%GB5}@TWyJ=AvZrIGp!P;!BE%G zBE-Pd%E;Wx&;X*raC^lhpaw;d4Z-3T~N2spa`a*~JPb WdIqo5)JuVi89ZJ6T-G@yGywo*dLy&| literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/arc.png b/res/icons/graphics-window/arc.png new file mode 100644 index 0000000000000000000000000000000000000000..807b7366dfa57d8af5a994b28430fb41a7f74360 GIT binary patch literal 686 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpv1HQpAgso|Nk2p81(n| z@87@w-@ktf3JUx7?fd-s^Ww#egM)*Gg@r{#L}FuOH*enj_3PL8`1ohfo=u-VU0hsz z_Uzd&Uc5+1Nci&QOGrpaTwL6zPoLhrc~ekOFlEY=)vH(Q>+8$P%F4^jzkdC?x3_ow z`t^JF?v0F$Oi4-k^XCu48HTX1uoWv-=;`UbeED+u^5xmt+3(-KPft(({rfjx%-e3D z3mHp-{DK)Ap4~_Tagw~{XE)7O>#0gD)q zG{={zOLKujOFUg1Lp08}UbrdLWWd9E;dGd&i-_Y!t%S8f;xYgJKd)KIqnmanc-G~e zlQ};um%0AA_I|N!vCM{x6+%k0jv0%6d3Lg9;w!V*G*9#M;jizlPnuj`T#@)BZ>L|f zb@oJCW`-$|sgAW8j1DsFyN@$5JjrB8=Vb6*GT%${YQ9u}fRKVdONVyh_1m_pEn8Wx z{BiX7R3jMlVcV-Rqsupbn=`1gDjZzL@BE&h>)_+zl?+mr%3x$*Xr^mmqHAOnVrXP#U}R-%scm3j zWnd6+w%QU!LvDUbW?CgwgQ2dWMTmi^m65rXp#emL;r5D2Kn;o@8-nxGO3D+9QW<;` qlZ*0mQ&Tb%72Gn5Qp@v;vWpc=^bB69sh0v3GkCiCxvX!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8Uop6XN;3=**-JcqUD+S7 zi1A2se3`m57bxWB>Eal|aXmS~fpN`32Y~|zwsCQ&Jy3gGRgj95#FA92WRS8{1|tJQGhG7{T_d9qLnA8# zBP(M|Z36=<1A~CG)s`q4a`RI%(<-4F40R1HLJUl;jLfYJ4Iml}w^vL8YET5(5S*V@ xQl40p%HW%rT$G=inv$8Q;FejGTAp8&U94cDXYfi*y%eaJ!PC{xWt~$(6954MfK>nh literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/bezier.png b/res/icons/graphics-window/bezier.png new file mode 100644 index 0000000000000000000000000000000000000000..9d2c240a471ac4f5277ad1c66291734fdc207a8b GIT binary patch literal 710 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpv1`lpAgso|Nk?bVNg&| z(ACwgtgPI$Y18}n@9*EgZ)0QA-Q9id+O?A>PuADhhlYj<2ng8Q+pk@_cInckxw*OW z^71V$Ez6cI3kV1Z4-enDbElAy(1ZySe0+R*dU_HQ6D=$(wr$%cCMFge8~fzR6JK9n zBO{~h*RNMsSI?h6f60<15)u+TJUlfuHOrSTS5Z-kiHX_0d-vwen@vniPMT4)YM!mEo6b7 zVk`;r3ubV5b|VeMN%D4gVd!9$^#F1>3p^r=85p>QK$!8;-MT+OLG}_)Usv`AEMh#; z9ABm`%>@c|db&7-hQk8yXs3zI=J)$dQ7A0wpCSV`Jm0s;cwn&%b%|roO&j zK|$f{*|QffUNkW=v9Yl^bLPysbLU>YdNpUx9ARPM*|TR)o;-Qs!iA?!oe~idxq0(u zU0t1ngM+81=ZhCF^78UZN=jNlqyzJ2TDodF+}5hYtT)xg9ai#&1PjQBa)VDWZmz+_4B{~ zr4aASGRJFolp9T+J+qzR!*Ue~E_bC(Osaiu7b9#YvM5YFmvB`*)l={NL#K&p_BAVG zKCTVlxLP6T@!wZp{?59U!8U1&i8_BCyK>pC9M&L1n~QIkeQ{Z6zhSmviNEshm>bjH znz1cvP_u8*6z-X+aptM~Gww9L;zb)$3I*d>f0lA?TzHZ9{NlB*d?vrKsHX zgZqswsw^8_dnUJ^_s*)-pPBWhXs_q@bB{YsC!4o)ov~}~J21bB@e!BM#*Nz?-GP1- zD{+k|aV|jD!649rIzOxWfv=$=o!3HQ!fQ7X7F_Nb6Mw< G&;$S&`#8t| literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/construction.png b/res/icons/graphics-window/construction.png new file mode 100644 index 0000000000000000000000000000000000000000..35ddcb274ff9113bfaca088234a5e6c7ac76b1d5 GIT binary patch literal 739 zcmY+BT}abm6vls%VRPw)lud20qSc09|NpkkjR?)nTsoO<(X5NMbk@qXG5@A3FqQQs zVi^>M85Ct?CVfDOP#IX*7k%7h7eQAM(N%P#751*W>EgVHbKd89-simMgu7;QdRk5z zknXIs*NLo2#^QzIe0S~TGm%num$}N|)=Blxz#>uW8Y=5taBvNDCSXpqIzL0J1Yi7M z8-V4}^Aoij#KnDgwbwB}KaU9xixPz51L%Nz5C=gjgf@5tBajO@Fbvrs^e5o}904=D z0HOFCmVq9sgabGY(~u8O;VKy6228;**a)T23lXru9vFh-uuWKmW;g}iQ1fSEyYLT3 z#Uvm;VGCS_N~pk5+Wt!nvOuY;@lg6{rYTwMs@iPl_#&-9po&)3w}3h`84KQi==dp` zsfyF(Nd1_SwIp}(_cK?*qIKJ8FY_8+HTZRC&JEQ2&S~VS_cPX#?D6sV!0X5H*-6Vo za!0IRyWM9`Nj;(FRncKXPgawxTUl6`v0Crz*RQ_vG4pNybmnMpRF%C{+k87ZyrM_j z`%T(rG+dhNcRF*b^RC~#_`|)`HMFzb)1Pi0o$=}G-)mF}!&H~1)1w|t-0d5?u<>Z3 z>tg?{6UK?{<`#8TUWZb|>k!-M;~LF~@8G literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/equal.png b/res/icons/graphics-window/equal.png new file mode 100644 index 0000000000000000000000000000000000000000..6037aed0f7c5cf33748e6540cd399a340777ae7a GIT binary patch literal 920 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZk1_nm=0G|-o|Ns9poM8|V z5fKs+`uOolWeRu8JrJ|yutE>Cu$&;9vm}%3d)zs9? zpFf|6hiAiv4Q6I$%a$$6$;k;848Ejw$=lm|?%cVnR;@BJGOCcMIHG<;l2y`y*Wrxj znL5cjBQ7I%clXqw)EB8QX3Ni(W0NZuFWzsl|8eZ&45>RJLV`W}ZHM+Re>PLqp^7g&R)ED@tHGc zczJo(tXY$ro7>XT^56KsxVZSun>R&8MOUm?abEMh0hd8iQc_=E-+JZs(bCZh3JMMm z4xyo;d3kxWX3a7%FbD_;NJvPiudiRfe*OOa`|sbs|9#^3O`A4#b#+x&SI5T2oYh7ML)4U=mE9R)O1bei-Owb+&&QI(KTSvuj!(o_YL z^=szrX;KOa@Qic~4dXo(c>O|1i}v+P*DhYY%x=uf)5|h3*TBrs)R^5+M@Mqa8o@_q z+jw}&4Epx2VU9U;k@M*4a|U9|yR|p9bj-G%qWXj}wZch5KVRD5?c;3bsUJSOcQ!US z%usYZsJJlkp_8Bhr-G!UsO(`WY4Q0J1mvgBm@l;{JKKy$gP=zW; zMM`2xs#P*bSt^5(fuWhMfr+k>QHY_Dm4T6!v8A?wffX>?&Q@EZXvob^$xN$+YB1C_ zvNS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1LNlky{9a886+f`vVkYFY)wsWq-gT#v{$~W$Myg1_nj}PZ!4!i_>?f*y_7DinPsF z-X6hgHnAhqu`}p>qqWKRV-%6PB*}tC zujidE7H`kj_v&kJEfhQU_N+QExWr0aBTAf$QWHxu^Yau!GILWI3=Q;+O!N&bH2GHl z2C7g6sYppINwrD_DNAKAGB7mLH89aNG72#?vNABTGPcwEX>4Tx04R}tkv&MmKpe$iQ>7wRK|6>zWT@g`K~%(1s#pXIrLEAagUO{|(4-+r zad8w}3l4rPRvlcNb#-tR1i=pwCr2km7b)?7NufoI2gm(*ckglc4iM^PrkWiSfT~$W zG8Ppx*;O&{iXi&Yi!p>HX6o_OVj7;~>mEM7-bHwp_qjhukCHPP;1h}Gm~L3a8^kl4 zmd<&fIK+yQLVQjM*<>bR8c}179zB2q?kz3e$>N1AO zrG<}xzHQ**x~0i`z~v4w_@qmQWaB3Q005LpL_t(Y$L*6*4uBvGLutZU z$DMZB`lXpfWWe~+eSs3O!PpGn{IcX{QyhP~ugQ;!)um^_oVGC%|pl9#5G ya?@dzKS=_BHM9GWm%Ozso~J#cO)Q?jTy+59P=<`q9VLJO0000!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8Uop6XNRWe9f zDua=Mp_#6MiLQ}Rh@p{{fsvK5rM7{Am4QLP*=kD^4Y~O#nQ4_!4Tidg79j?vRz~Jl zh6WG~hTAJ90W~OsYzWRzD=AMbN@eg(OfJgLO-;#6RB+2IN-fVX$}Uzg(KC3Zrd|qE O%;4$j=d#Wzp$P!j<8{aY literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/image.png b/res/icons/graphics-window/image.png new file mode 100644 index 0000000000000000000000000000000000000000..d652d8e77c4297cc57816378acc0b9fa50ac3429 GIT binary patch literal 1025 zcmV+c1pfPpP)(_`g8%^e{{R4h=l}px2mk>USO5SzmjD14Z`WEM zkN^M!08mU+MgRZ*0L%dX{{9040|W#F1qB5L1_lQQ2M7oV2?+@b3JMDg3k(bl4Gj$r z4h|0w4-gO#5fKp*5)u;=6BHB_6%`d078Vy57Z?~A85tQG8X6lL8yp-Q9UUDW9v&Yb zA0QwgAt50mA|fLrBP1jwB_$;$CMG8*CnzW=DJdx`Dk>{0D=aK5EiElBE-o)GFEB7L zF)=YRGBPtWGc+_bH8nLhHa0gmH#j&rIXO8xIyyT$J3Kr*Jv}`>K0ZG`KR`f0K|w)6 zLPA4BLqtSGMMXtMMn*?RM@UFWNl8gcN=i#hOH52mO-)TsPEJoxPf$=$QBhG+Qc_b> zQ&dz`RaI41R#sP6S6EnBSy@?HT3TCMTU=aRU0q#XUS3~cUtnNhVPRonVq#-sV`OAx zWo2b%W@cw+XJ}|>X=!O{YHDk1Yiw+6ZEbCCZf7mzbEC znVFfInwp!No1C1Sot>SYo}QndpP-Ll?si~=| zs;aB2tE{Z7t*x!DuCA}IuduMNv9YnTva++Yv$V9dwY9ajwzjvox45{txw*Nzy1Ki& zyS%)-y}iA@zP`V|zreu2!NI}8!otJD!^FhI#l^+O#>U6T$H>UY$;rve%F4^j%goHo z&CSiu&d$%z&(P4&(b3V;($dq@)6~?|)z#J3*4Ee8*Vx$D+1c6J+S=RO+uYpT-QC^Z z-rnEe-{9cj;o;%p;^O1ulq(=H}<;=jiC@>FMd}>gwz3>+J08?d|RE?(XmJ z@9^;O@$vEU^78ZZ^Yrxe_4W1k_V)Mp_xSku`T6=PR2gr1-#QAO}rNS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5l;AAzh%9Dc;1&X5#!GkW z{s0BpOFVsD*&nco@kn!gnYuI=D5M_X6XN>+|9?I{J|Q6?4GoQ?q@_2pFf*}tJl&vJI3t`}!9tRer{LVjlLqG<-#D@|82f8aPdh*R zA<#mx64!_l=c3falFa-(g^eM1v{1B<+M7qx*ZR6#0I5=&C8l0nK+8H@}J z&2$Y+bd8Kc42`S|jI4|;wG9lc3=9I!R$HQI$jwj5Osj-yFw`})2r)3VGBUR^G=OL@ z++HyWs6i2ALvVgtNqJ&XDuZuga#4P6YD#9Jf?H-$YI%N9cCmtqp1~_M^-`c>22WQ% Jmvv4FO#prsoTUH& literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/lathe.png b/res/icons/graphics-window/lathe.png new file mode 100644 index 0000000000000000000000000000000000000000..8cee0583c28f0637c4a6c75a0847e021bb7ee696 GIT binary patch literal 401 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaP3?%1DUd;wlEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z%2~Ij105p zfJ|pE@$_|Nf50NfBhB$;>e5`G5Kn+lh^w5O-2eaoQ&Us_{P`1m>&*(FI8#ZGUoZnh z+2pepKpta~x4R4DeO=K1)orKarasJCedtPZ zX~ERzoQio8_m8}P!yEh9UUL4`J^z4Ksg}4#l%yn}$cBcl*Q vBP$~_DgTe~DWM4fT-A0G literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/length.png b/res/icons/graphics-window/length.png new file mode 100644 index 0000000000000000000000000000000000000000..b48715e094ccd65dd166f3fa9a61237624c5f752 GIT binary patch literal 480 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaN3?zjj6;1;wmUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5ln@H=332@o1PuQ_FnkbT z5MVgN0OWmJYUKlzWh@Eu3ubV5b|VeMN%D4gVd!9$^#F1>3p^r=85p>QK$!8;-MT+O zLG}_)Usv`AEMh#;9ABm`%>@cYdAc};NL-$KY9nuh0gubYdLiaJ8yS5LaA&=SqCWC<(x*5oAN@BIr`zuJ2ydwWiNetEF% z@~9cF?p^()V=r_497oo422B~DEn+3E5hcz=sfi_-`FRQ{XE)7O># z0gD)qG{={zOLKujL7py-AsXkmPW0qEV8FrL96U+y=KudU>JHesWYx+n7HkqQOG^9Z z%NVH8R8>&$&hx{YIrI0K_IrQ${czr)?<;$&f33JP-|A^`=kFt$>-y{ESAJrOi(~Ya zF<2-LG+nI3HKN41C^fMpGe1uuBr`Xa!O%e8&_v(BB5&PAZJ-KOkcyPVl2of?kg`+; zBLhP-T>}$cBcl*QBP#^HVa@Dxn$-bqy^-3{0(z%&iO! zAQ}v}S4;wGPz2c!oS#-wo>-L1;G39Sl%JcLl9{OBmRXcqo?nz*tYD&N@Jda+6sVZN M)78&qol`;+0PNS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1LNlky{9a886+f`vVkYFY)wsWq-gT#v{$~W$Mygppb*7i(`nz>Eu7>9i$SJ0&QPP zMLf{)*>3pgdc!(~_U9Sz+XYuPvi8el`4|XYYEYJ9U$~roA={G#Rjq1czI{$W1IpOV z{urq$0?iUDag8W(E=o--$;{7F2+7P%WiT|*H#E^Vu*h3?Q5&d26{I31u_Vg zXWQ7=tX#R0hll6fxpTa{yo(ksa&~rhaBwIqD{F0SJ%0T7#EBC%G&IhiJRdC-T`O7J zF5O-wQROe-FT^6m&(Gh|(z1E;W(y08=Qp2EGM$tpk`yi&o+gquSAOmcxfv?#Djpsl zM~)mREiIirdvsOoHFdh=fJKZ)n&ZpVrMW<%%bqTdArg|U2Q$r? z5*ZpUwx@M?a835ms{U5%?YeY=O4J*X$VdO{O%7X{ygy@k*V|Zk?TpPHGbZ1@Wtjff z;lfG&Xz`{z>sfN{>n~ruZht`jsO<|!Q|KaZIWfq>iV%f4xh4U?GGiSSR z-r%u#>C*?Nv}SEBEwPcF9esO6*&mKKyYoUG+PX~4;JIP%AmZOLsePr1oBMI~nU{6k z(k;(@-f6)mK0QEV+Nq8w+N|sHjkb5ZdnYe9Un}(GPu9J+Uf;G}P~%Zr@=CR?R_wy> zMLY9jXGtCXXi$9-=smF#*N775qSVBa%=|oskj&gv215gVLlb=ii@bFgwSg*BK`K%b zOH!?pLCR7Yj0_CTbPY^&jf_GJjjRlefk@lHz{IaWiC>nC}Q!>*kp&ATz4J|?p zOs$N}tqcty8Vt8rOaf|91lbUrpH@~KsF=ai)z4*}Q$iB}3gla7 literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/parallel.png b/res/icons/graphics-window/parallel.png new file mode 100644 index 0000000000000000000000000000000000000000..fe89e2f100c33ae3ed352d0e318d0e502cfb2226 GIT binary patch literal 531 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkphQA|Pl)UP|Nj}zFo=kV zn3$Nv$Hxl^2^kt11_T7;<>hsEcduNz^5n^r*REaLy?ghhNs|&166)*g*RNlH{`~n5 zA3i*K^yui(qsx~s@9gZ%$;t8c_0`wc=i}p>KYxBhLxX{Vfq;NORJ5ud&@RT3AirP+ zhi5m^K%69RcNc~ZR#^`qhqJ&VvY3H^TL^?1FWs&C0~BO0@$_|Nf50NfBhB$;>e5`G zkiDmiV~EE2#-gQ0=Gp^3hM zMc%rL+CUYmAQdTzC8<`)AZ4ixMh1pvx&|h?Mn)lqMpgz!R>qdv1_o9J1_5WQEm1V& z=BH$)RYElw>Ka;v7?@fanOhkeKr|R`ub2eXpa`-dI6tkVJh3R1!8b9vC_gtfB{NaM gEwd=KJijQrSiwZk;FX$sDNr$kr>mdKI;Vst0KtQ(xBvhE literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/perpendicular.png b/res/icons/graphics-window/perpendicular.png new file mode 100644 index 0000000000000000000000000000000000000000..e9bf5d5f7493358a181cfa1c82c66970aced3094 GIT binary patch literal 427 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaP3?%1DUd;wlEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8Uop6XN>+|9^%v4F4H` z^#Aw2Zc72h8B2ovf*Bm1-ADs*lDyqr7&=&GJ%Aj}0*}aI1_o{+5N5n|x9$&6kiEpy z*OmPNix`hI$Cs%~bAdwIo-U3d9M_W*6nI=DB}5D~RHZZU6j6w{JtPG5-j4ibd z46FyW>IQ+eo=O@f{C8ND>d~}pkfA3S3j3^P6i9 zH9tT9$B9nYfmSn?1o;IsI6S+N2I3@nySp%Su*!M>Ih+L^k;M!Q+(IDCcQ}ahbkkL_5O(dMVyW`N@ZY4#w=bhdUKB#YABGSh& zVcJ2#Et`ryS)_<8DRgb`P~ziMO%;tgsvszoz`&5I#O#!G`iBD0a6j6w{JtPG5- zj4ibd46FyW>IQ+eo=O@f{C8ND>d~}pkfA3S3j3^P6!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8U)v6XN>+|9^%v4FCT9 zv%T`L6e!48666=m;PC858i21s zKVT8#k>>a^b!je8NY&HDF@)oKa>4=T2w4dU31*3i&0%Y!BpDtXHl|2vEZrd0%g(@{ zy^rTBYeb22QEFmIW`3SRNM>#-gQ0=Gp^3hMMc%rL+8`rADpC?lQmv9f z%2FAO3=GY54NP>6j6w{JtPG5-j4ibd46FyW>IQ+eo=O@f{C8ND>Zdc P7%_Od`njxgN@xNAk3Di5 literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/ref.png b/res/icons/graphics-window/ref.png new file mode 100644 index 0000000000000000000000000000000000000000..19f3b88a7c512fb185d6b3f224ef7a596617ad9d GIT binary patch literal 413 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaT3?y&uT)!Jgv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffhPl)S(AYk}^EP_K0 zD8g70rMq>1fP(BLp1!W^4_L%_ zq&dD!U78CNQucIl4B@z*oS?vv_3D+x92uDhJC?0$JIL&@+u>(lDc_GR%nbb!98Cvj zU5f-N7b|g%C~+=IO)SaG&r=A=%uQu5G|)FR(KoQjTX#_#s6rK_A|Er L^>bP0l+XkK^DcEc literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/revolve.png b/res/icons/graphics-window/revolve.png new file mode 100644 index 0000000000000000000000000000000000000000..0cef0fa669102188757aabc5750b5c0fe9b5b5f1 GIT binary patch literal 680 zcmV;Z0$2TsP)EX>4Tx04R}tkv&MmKpe$iQ>7wRK|6>zWT@g`K~%(1s#pXIrLEAagUO{|(4-+r zad8w}3l4rPRvlcNb#-tR1i=pwCr2km7b)?7NufoI2gm(*ckglc4iM^PrkWiSfT~$W zG8Ppx*;O&{iXi&Yi!p>HX6o_OVj7;~>mEM7-bHwp_qjhukCHPP;1h}Gm~L3a8^kl4 zmd<&fIK+yQLVQjM*<>bR8c}179zB2q?kz3e$>N1AO zrG<}xzHQ**x~0i`z~v4w_@qmQ5(6O!TO8k- zKj~-bp{3(EP{?}f%;u;NP(rTj-yvB50R448=M=iYN}3Tcv89fWa!<%3j>aUbD&0V< zyh1;)`{oG+o$zP|ckmQQ(b>g2T1HC-pp1&v z-AGjgKue~z=|9?m#@a7y-JS6u5&3p`yAdPM1yS7YOJxB>L#`HjK;Z=v_ne2gg`(&H O0000a;n1KGCV=TneT? z63Lh#5`k1gQYZv{5~V>Ag8ryKhGAJqUqm`7!QP|(1oz&72&0ms00>P+ zT{(whz9U1q`TFLo7aWAukrooTb4jpGg>zg|Z7jC{ol?Np2mInB-zT7r0M?y=CIBQf zkKa3<&n?Ev%y#|G&JMI%6cr&o9sT`iY{bwIy1KwHa5_;{h166G4#H|hULFhv7>$rh zQCEkS7Kp`2OG85gQc_S~kN9{L6u@kT!vVD#G8sf7#Kyw!hf0OYO3*ZNb1^&&p%8L8 zSQZr(AW0-9A}I-8FKjkY6uP@nT51_|@K1)YDIDg@uzIXGnq4Rs^#%Bh4 zgFWi(&(WtpkipH3p1`S;VPy05CFSNXTeB$foZ1QeH)cn$z{|7U<+)so`dhUp!cERK@Rtyh}BoHMGQ@`E>Dxh?sC&06xoC-n>e!c z^!Ehk$lx6{6iaKWc^eHSp*WO9;3=**-JcqUD+S7 zi1A2se3`m57bsNZ>EaloaenJWPre2N4%d}YM=R$YU-jL7v2V`;ZS!A~^5imq1~inn z2*isXXqeBvOqEx2>D!DP?vsmOU*xstxan?aJ9UTJPm|L--2*qR&&s>Ep?%ZSkXZW- z@|N#RmOnY{I(LoN!?x{=dS$gA?yJ`Q+{(}QQHkZ^!b!$DK-PsvQHglaIyW>IQ+eo=O@f{C8ND>d~}pkfA3S3j3^P6%y{W;-5;PJ zdx@v7EBgZ$F&=4-FH@K10);$0T^vI+&L<}<&`LPMV8F>URm8)<&~T#O!81*V`NGV~ z_})w_E-L)|pg>e#em_Imb1n`p&c`3xH*lP2jIj0C#nRf?p}lAY3q$)4#^^KF2ikyU zij}xVlsFfqCYEI8=P86_=B6?j8t5CD=o?sQ@~!?2RG|t|k&;-FYLyI9mdapcU}&am zV4`be6k=#(Wnc_M+6D$z1_o09nN|taV5nT$ zP=g}KhT#0PlJdl&R0iL~|zBIJ%d+j>ZL%%44$rjF6*2U FngEJJn;!rG literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/step-rotate.png b/res/icons/graphics-window/step-rotate.png new file mode 100644 index 0000000000000000000000000000000000000000..22969f65fbc41248dac0cc9cea78066c32e7a7cb GIT binary patch literal 871 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpu~p&pAgso|Nr;*_uJds z3kV3zpFdw-UVh%Zd0)PKId|^d*RNkso;)clE4zLB_OoZtZrQTs;>C+MZro5)Q(L)m z<=eM!_4M@g_4Q}Wm~rRMoeLK(aC39NdGqGgt5@yq?c(C%XU?3_(9l@0V8Qh1)9dT& z<>cfhO`23&Tl@X{cYc2U-Me=$U%q_NqD4oK9_8cXd-v`g!x;tx1A|qoR?V6<>*dRr zFJ8QuIC0{>ef!RzKmYC9x7OCy*RNlfmzV46>S}9iPn$Nar>Do%)b#f4+fSc9ZEkKZ zDk@S{RlR@z{?)5jjg5_;KYxDx`t>76ju;skUAuPe=g*&geSLOzc5_b{X#oAsSQ6wH z%;50sMjD8d?NMQuIvw3#CW7RzD!-3 z3)I8x>Eak7A=!GcJ?M}DL&HOPVW-eVNx~C%2~4z72n;NEZ+riL?i$N=;qPqz+WiZj zr691$XW}ZCrk)NpQP!-iU8`6*Y=h^8K6w(;`}0Oaued?!$&RR;052WM-CNFh#R{Id zy4B6tj72T-_!%#wwWrwL9x+II?0d~hSD|;?Heu&;D%QILr~9m`p2j5odWynUmUEVM zGxQ$MDgJZH^0>r9$;YgX7d9?Ga6D>)U{(JA1Cu`gJ-oP)A?mQy@y_%k^XC*@%bXb4 zT&ySL{a~{9x^<$ByCNT!ot*sfuk|~55#>)8FTJV!P&j*ex~JdXIs0FU?ArC~+d7R2 zhaJ7tdhJw_?e=p7MLx^FKmVfmdasNq z-29Zxv`VN3LtR6Q5Cc;yBXcW51BeF0?G=-N8Wce`1m~xflqVLYGWaGY7v<-srer26 hxMdclmgg5`7b}?P8N5 literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/step-translate.png b/res/icons/graphics-window/step-translate.png new file mode 100644 index 0000000000000000000000000000000000000000..2901f9e52b4239d3d0adddb1500e484f38453212 GIT binary patch literal 411 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaP3?%1DUd;wlEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8X6a5n0T@z%2yAjF;}# z{Q(NHmw5WRvOi!E3hMC&cyt|Np;#|Ni&yACNKa%!_A0amJD$zhDN3 zXE)M7oFs2|7iK{opHD!Jw5N+>2*>s0ga+o-q0$ah7@C=cSVdhJnHLH$%s1gv%sDyb z0#KP)iEBiOb5UwyNoIbYLP%zADuaQczJam6f#v1Hzvlr}sDf0aB$lLFC4-cuG8h>c zn&}#t=o%S?7#dj_7z2^Efq|8Q!PE~Pt57uL=BH$)RYElw>Ka;v7?@fanOhkeKr|R` zub2eXpa`-dI6tkVJh3R1!8b9vC_gtfB{NaMEwd=KJijQrSiwZk;FX$sDNr$kr>mdK II;Vst0Jtl5rvLx| literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/symmetric.png b/res/icons/graphics-window/symmetric.png new file mode 100644 index 0000000000000000000000000000000000000000..e6e80ebe4b71647854ce2802c6e8e6b9ad2b58d4 GIT binary patch literal 515 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpoB+&Pl)UP|NjFR0_+*= z-5K0H7(C81oHu1Kb!Kor#&FDn!QukL1vdt_TMW0<8Pqp1Y%*Xluwk%S$FRluMA)RGyIolkY9OjaWBwJ#*!evUYh7ML)4jyNk9#XARB`7(@M${i&7bU6O)Vbb5m0?6BXPti&D$;i?WLqO!N$1si~I& P6*G9c`njxgN@xNAxfGbJ literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/tangent-arc.png b/res/icons/graphics-window/tangent-arc.png new file mode 100644 index 0000000000000000000000000000000000000000..d9dc40ac631cd3beedfed2da1ebe7fd5989a002f GIT binary patch literal 666 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpv3$DpAgsoK)~?d!NFn4 zk|jrv9^Jluds0$TUtizxySqEX8HUZ9H!obc(8Y zpf&%|H=vWmN?apKoQqNuOEUBG6hbm{QyB~m^bJk)4J`83UDO7uPz9+-Ni0dVN(L!Q zWiT=@G}ARO(KRv(F*LF=Fa{!R0|P4qgQ*`pR-tIf%}>cptAuJW)HSpSF)+0UNH%%K@ns_aDG}zd16s2gKuJTQGRY}N@k*hTV_#ed45rLv4V-7!7DX&P%JQb My85}Sb4q9e00j)-U;qFB literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/text.png b/res/icons/graphics-window/text.png new file mode 100644 index 0000000000000000000000000000000000000000..8923573ab0cbfc1e44c44f7bf6a95aaca7415f59 GIT binary patch literal 784 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1LNlky{9a886+f`vVkYFY)wsWq-gT#v{$~W$Myg1_s70o-U3d7N@69+M9hjP^4|X zv{lw>jwXdIyOwbsbtvqR%<64k*{oLQ(B1vwk^P0UN`6*5MUO6Q&d79)k?Kuau<`22 zYaOgd7r9PRiV%-g>36;yF*#nU`h3~>TFdj*@1#?T)wiAe9@v!lJhtFqWc#9H(c!ym zvfGu8>ts6bPjs3lq|Nvs@rK)>X&%f^8kgKX#Nxbm!nfaE6KAVU-BG;F;nXLQ2D>5$ z%Reaxcqj4|^Ly;};A)7TbK`{be9<(fIZ1Q!m$YgMz1gzzfeGt^!y^1ACNobvB;99b zy!UWrxwhqd?dqEJ-IGc$sV(c@a3-k1_ztUG%l9RXHgiiPJ55elT*#ax=e8%Q$MJ!? zMv>7e=jny-7@~I`3lIBoPC1Tgg1Ye2hm*D|Pud)HS#HJGTi05SOFor(`_5T`L5RbL zz2eZ#TMZjtEx&D8#S~+D__&OyHA^D__|vMbG)V zKxliwbLFQ!O3$1MljVN(0N=+=u%+FH@ z$;?e#iRWF{)OWfrBD=NDxcE12jRyi!vy1uACnboFyt=akR{0KFkHLjV8( literal 0 HcmV?d00001 diff --git a/res/icons/graphics-window/trim.png b/res/icons/graphics-window/trim.png new file mode 100644 index 0000000000000000000000000000000000000000..248e448ce7ef3c1584f872da0554d748607f6db7 GIT binary patch literal 575 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkphR+jPl)UP|Nj}zFi1#9 zoIQKi$;rvo)b#lA<0>jD$;rtpSFW5fV@7#-xq^a%fPg?&R@SOjt72ng4<9}}Yt}3c z4Glj(zY`};tX{oZOG|6Xk|l0#ZWAX?(7@~1LIpF}OL}SA>As!x|GddP25jSrX&Nz6m^K^k;UW*0)CYD1|adveg z&kw8-6c7<|D`mJLB^YQ}xaQx)2`UE{2SunZ*_oPRsN%p>^oi@mzDAFZWNwob6OmvNmLJWOL*3KSR=J}`U`U=WzVFku731_K6z{|x^hFg!?LNN8YaSirC#fFa-j!vO~dhgB=K zF9I6ESQ6wH%;50sMjD8d?NMQuIvw3 z#CW7RzD!-33ls|Tba4#PIKOwIqfmna53@L9cdqEy|NUPXOKcYIe3vpy?Zdh$mvjys zvR4pau+FGqTH~f(K2z5F&C>S*CNs$Ry$)QJ^(tM$JU;u6`$jqDolkeKOY^gS!MN9& zv3tq?s6e0%VkNE-CC){ui6xo&c?uz!xv30>2Kt63`UVzx>n>^oRj7hgq$HN4S|x*& zr7{>97@FxCnCKcAg%}!H85mg^TWT8^SQ!`uoUOJ*(U6;;l9^Ts)nKS=Xc1yyYGq_@ zWoQ7=V7R?v5>SI8$cEtjw370~qErUo#N?v<+|-oJLS?6Fq}hYU-sx O#SEUVelF{r5}E)JT%iU4 literal 0 HcmV?d00001 diff --git a/res/icons/text-window/constraint.png b/res/icons/text-window/constraint.png new file mode 100644 index 0000000000000000000000000000000000000000..bc1a7178a23da7acf244a22f5b9a4a0a94562a5f GIT binary patch literal 557 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaAv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkphQ%FPl)S(AYk|(EfhUZ zVP2lztAr?vs1=V@s9iiC zX!>!D_!@hljQC0 z!qCAg>jC6&7I;J!Gca%qfiUBxyLEqng6t)pzOL*KSj2b~1lRaHnhF$(_jGX#(Kw%+ zus}Y6h0%cdh}(1)Z3geeF5`sh2}jaIlsEal5aM~U?7`FnEIwy+*5tg2P_eMsxude; z=Z}rq!U7^f#}XHHXz1-e5>e>U;r(Dkn`01Hd&?Fcz37xo;p+@jw=urhrD*jAXq8xr zYeb22QEFmIW`3SRNM>#-gQ0=Gp^3hMMc%rL+CUYmAQdTzC8<`)AZ4ixMh1pvx&|h? zMn)lqhE}F#RwgFe1_o9J2LDzTi=k-9%}>cptAuJW)HSpSF)+0UNH%% zK@ns_aDG}zd16s2gKuJTQGRY}N@k*hTV_#ed45rLv4V-7!7DZOQlMf6Pgg&ebxsLQ E00-Qur~m)} literal 0 HcmV?d00001 diff --git a/res/icons/text-window/construction.png b/res/icons/text-window/construction.png new file mode 100644 index 0000000000000000000000000000000000000000..35ddcb274ff9113bfaca088234a5e6c7ac76b1d5 GIT binary patch literal 739 zcmY+BT}abm6vls%VRPw)lud20qSc09|NpkkjR?)nTsoO<(X5NMbk@qXG5@A3FqQQs zVi^>M85Ct?CVfDOP#IX*7k%7h7eQAM(N%P#751*W>EgVHbKd89-simMgu7;QdRk5z zknXIs*NLo2#^QzIe0S~TGm%num$}N|)=Blxz#>uW8Y=5taBvNDCSXpqIzL0J1Yi7M z8-V4}^Aoij#KnDgwbwB}KaU9xixPz51L%Nz5C=gjgf@5tBajO@Fbvrs^e5o}904=D z0HOFCmVq9sgabGY(~u8O;VKy6228;**a)T23lXru9vFh-uuWKmW;g}iQ1fSEyYLT3 z#Uvm;VGCS_N~pk5+Wt!nvOuY;@lg6{rYTwMs@iPl_#&-9po&)3w}3h`84KQi==dp` zsfyF(Nd1_SwIp}(_cK?*qIKJ8FY_8+HTZRC&JEQ2&S~VS_cPX#?D6sV!0X5H*-6Vo za!0IRyWM9`Nj;(FRncKXPgawxTUl6`v0Crz*RQ_vG4pNybmnMpRF%C{+k87ZyrM_j z`%T(rG+dhNcRF*b^RC~#_`|)`HMFzb)1Pi0o$=}G-)mF}!&H~1)1w|t-0d5?u<>Z3 z>tg?{6UK?{<`#8TUWZb|>k!-M;~LF~@8G literal 0 HcmV?d00001 diff --git a/res/icons/text-window/edges.png b/res/icons/text-window/edges.png new file mode 100644 index 0000000000000000000000000000000000000000..fcfd009ffde0fa487f4a55546c2a176e10c6dce8 GIT binary patch literal 703 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD45bDP46hOx7_4S6Fo+k-*%fF5lweBoc6VX;-`;;_Kaj^+ z;1LNlk?R8pGdis?0V-u+FY)wsWq-gT#-kv(#^=#g1_s7fPZ!4!i_=H1_;;L1lsW$K zdcHL8*-SrS)2Mo`qcY!|_+|uY>xrpG23eb{uy2mpw%1B~dFgH8wcXr&(-t|-S~PX( z)|C?{%@%Pz3Y1hv_-&r$1fByH+%in*lS*)<~bmG)m?(f`!M2|K;G*H-) z+8np~ugL>X_Gv$bWw_O4&9BUv$|9fZb#vkK?LQMO-Y--9vUAa+xrXzD`=>-o??}94 z5w=PzYsa$PM%8maJ4fEs_J7(F88dSZ=l26?r(?EHsruK(KHX$H#YoMZzz_uN17%wa&Z3wfWr^X3==7Gjjqb znI@i_XR+ZH=O_6ICtJPJaluAB9NLU%n~978nDZ=H0ztjR#Y z)zIf`hD@o8r>dy#7SRv){{Oe&Wb>LBuI_JH{dVe;H5Kz_H-6YVPw<1;6pKTCHf$kY zz7v++tym_aaCYXcN>P0k)-(SbB9y#5wV&}d1hl_@-7&vWuQTzTX^DPCr{G#UfrQ6i zzm1u?rsgiw;oZLb7>CEIs-#(UR>^)hjyU@)D*0ouZ(sd^qsBhp&WJ@QpYCop?D+V^ zW2NnSvpc6geYkQ*x}^KXqAcU3o8Qm9U76wNrEsb|X5BHFE}PZ8wLwSwKOSXU@Mt@O z-ud{YPyXfa-O0Q;O(yEknme38kE)iqMwFx^mZVxG7o`Fz1|tJQGhG7{T_d9qLqjW5 zGbJ`A+xT50nP&*(0)X~2)_W9l4aeXpP{-}_*;#gRnN9%PJT=pc46Jmxq z%2770)r<2zp{S~W^U}7svXEAb1Wh}HCQIV_g|t&N-c_=whFWksH|z(W{2Hz3Q`+7e zMAZ$x>LwpDAS^M2_0%?W+B5%*R$HSD+yv+XI1P$$dC;7_EQg=aE5di<>9bho0YB^< z*6fuT+yz04_x4FA;gU1sTPH@DJ5)hPX%IT)NO^9f9Az=e-Ra-qDUT>&Dw)l+H8akS z{=g=wF-Z|A=XJOX8+=6?5&1gVe#V~q#uRyL&M`PeOdu)O!m}HbLW(%(L&wlmvE(F6 zcyZ6(J|g?Eo$4k}@`OZvYYt1mx#RpnmOxw`$Zzvt8m!n0w%nne!JTfRTB=OTi~2e$ zxQoPG#-b1K!QCX`1z$-iJ1kzR2v=B5f#n213&`SRpn^&Lp>E^8P4rQUeZXIuN#7DF zp&=ru+D4Qbg;lOpl?Q{(k6Z5|@XKpZx^KeD!x%E&@I5c+_oUMu?*Eu}d&WbGGo8$yHk347?v!VG})9S~Fi)^mb$1 zBC%p}fMm8fU*TpkL~cptx{!A^HdR`nInK!WbFJQ$!DWA3$*6HfGnQG-_r?Qo^_h|9 zG?@C<=XKFzb3JvpMm*G=o&6oXp6Zp2xp#(J3-GRgF7EP*nL<<*e>_~)tc#fee?Ey-EKfO@dKm0-b;)4B=q&)F0!of zg65aw#z%$s^x{~3np&?xQ*|060S%!t{Sdkzji#hhQ3eyG)At|OQX9$W7gbE|A)tyPI>_^m@(AQ8qIC zc*uIPsGz6^k%Te|>}mK^Q1tOoJp}b)wGbpIqAdGg>ZOO@?{LoV9L{g5-ECLq6y^X> zIvq9-MU6b$x6=J;{>ftsnGv(g4BR=d*x<7$*Y-F(F5sjN7(WaApwjq9V3+{u0Km=x zy9cf;cO0OHOYN;bZgX=J77MIal$T>-0XQ5Q0 zstS?>zaM5Z3JOqIh|y7az2JEy5@>64O?SypW=I~l7tO1$!!ijTwA(P5RpOvz$AII| z5TMAHC*#H2QyWywmYgmw`(36wSDSC*ma3^FI&Eg3rr=h}u1+?qxYW#%+{x=)2NT)F zteqZw`l)Wcc;UP2S@YfSWbpR!?9{SZ^>y8U^jB)YcD1PJQRuSgL-CSoRgrj;-x*81 z-*&$tF?MeyZ%t}>*nQ#4mbK0s6(cv(XF407A3pc3WubB7vtlZgmD;&?v5mH?CC)Ed zMS+*1@nc$Fv|j*Ws!2^X+5d9o=QZl6kR2gj64)NuCcr?LT0Jr94F(^>u%=qpXsjZH zCFJ+~kovzse>@ZokNyiVdZyk-Ost`fWys$E^Welq8Yq(+yz#I!!ixf2e2*CK7eY~9 d+Y%Lpk+>Ke(i-=Xv~JHZHN(ldZHtyb@(=1@xS;?5 literal 0 HcmV?d00001 diff --git a/res/icons/text-window/occluded-invisible.png b/res/icons/text-window/occluded-invisible.png new file mode 100644 index 0000000000000000000000000000000000000000..5ab4f82fbdf14b1145951f7597361a8157fbc840 GIT binary patch literal 345 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1rX+877Y2q^y~;*F9%q3^Bv6!F z2!t6g-L3lr6l5>)^mS!_z`@I*!e4%_eQ|$Sg3?z=mr%rK6N=ka< zwy0CDf;s_&a~Fv`qeB) zt7i>{!G3o*kNCtYJZO_tKKSpV_JIl2^CSxc48^Sy7>ng*Y*1el_lixx=%L|s`L>%^ zxE*S}oSv)k>ob2`5E3}~{;fCbvQ1OYNo*}RwAJDG#y>wc&RynNz;IRM!`kh?<)fRA zaU9^3s=ZTjkVi^t*SjgpB)Gkg`s^%eR2F-*eQtnQgT6_0+xbb)cONruNgdD{an^LB{Ts56mW#w literal 0 HcmV?d00001 diff --git a/res/icons/text-window/occluded-stippled.png b/res/icons/text-window/occluded-stippled.png new file mode 100644 index 0000000000000000000000000000000000000000..6d7a33f221f038d68881cacea2c318a0cea36dcb GIT binary patch literal 539 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRDEak-aeC_%Loa4Wk+%OQ zquh8{4jyu1;+mvX&7A+hR>!uff?tr^``{_=8}F_)P2g5pxg}`w`K0ta+l@DSbe+jA zlYc+E()xX}?5#ZBZEO4+tA9}$cBcl*QLn~7=D-#oK z0|P4qgMTZF#ZWZl=BH$)Rl+qGnuZtwH5gkNSU@!VFn#0&)WG2B>gTe~DWM4fTt2`@ literal 0 HcmV?d00001 diff --git a/res/icons/text-window/occluded-visible.png b/res/icons/text-window/occluded-visible.png new file mode 100644 index 0000000000000000000000000000000000000000..2ccd73e6c878d72326c415f20f7bb17ca3415603 GIT binary patch literal 365 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1rX+877Y2q^y~;*F9%q3^Bv6!F z2!t6g-L3lr6l5>)^mS!_z`@I*WK{VlMGYwQ&(p;*#NzbXDTaB690XkdKkAs~F;VFh zhvt$N<0lMvT9p^vVRjYqSkmFb%I=Y^=P;X3X{p+Q#UIw$##y_HOqj9qS@pcV)}K?` z|B3Pb6|Z=@J)lg&=iVp2634>68!X4Rt^e_%$TI%MrS3-dpl1stGK^Dw_3Ix!wTt)J zv6@kA$rhuv48L+De;t!&F7b$LE#tRP;Vk(Q>{Vi5?5#3g{DdaM#+Ycu^1h?7wi{M! zm@n0OsL7+(z3j>H8Rxf0a5^nM+}3#4wDl+3F{vp&%Oo~bO_0BxfBAgr9X*3*lQ$mo z(Y^aR^1j|K<GuF{3LGg{J{GPz>r|@boFyt I=akR{0Em&1x&QzG literal 0 HcmV?d00001 diff --git a/res/icons/text-window/outlines.png b/res/icons/text-window/outlines.png new file mode 100644 index 0000000000000000000000000000000000000000..2c07fba05227a1b74185efdcf65c7561be452e65 GIT binary patch literal 733 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM0wlfaz7_*1mUKs7M+SzC{oH>NS%G|oWRD-YjSD#gA|>t*phdU&VB zD(0z@YxRysIdPdCmtNN>dcLOY)uUZ}ecO%j;?k9y4rKjdkyKumbZ?I3=d>E0mB*&aA9?<7%9<@(0d}vtNU>5>8iapJ(oXD@Z4Eox<$-dvecw6><+_84o67SMi8y|FvckTu+o0l5fF#fzhp6;u=wsl30>zm0Xkxq!^4049#>6OmvNmLJSS9OwFuJOtcLQ xtPBkPtt=Kp(U6;;l9^Ts*I;NGVg%G+Y-L~p(eT6ckrz+{gQu&X%Q~loCIJ4IC$|6q literal 0 HcmV?d00001 diff --git a/res/icons/text-window/point.png b/res/icons/text-window/point.png new file mode 100644 index 0000000000000000000000000000000000000000..421688105dbb6739e62266c82ae3c4894d3a29a2 GIT binary patch literal 394 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaT3?y&uT)!Jgv7|ftIx;Y9?C1WI$O_~uBzpw; zGB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaffhPl)UP|Nj}zFc|fE zgG3lhg8YIR9G=}s196hP-CYt=nRkbtL)V+hCf5XRI6l=vQ!2m14A=i0~1{%qYy(QD+4ntBMWT< z11kdqsCm701fP%(q2tDnm{r-UW|*wAW- literal 0 HcmV?d00001 diff --git a/res/icons/text-window/shaded.png b/res/icons/text-window/shaded.png new file mode 100644 index 0000000000000000000000000000000000000000..0dff1ae182f995557e6eec337a170edfa6d37655 GIT binary patch literal 403 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaP3?%1DUd;wlEa{HEjtmUzPnffIy#(?Vl0AZa z85pY67#JE_7#My5g&JNkFq9fFFuY1&V6d9Oz#v{QXIG#NP=dY0)7O>#0gD)qf{>}} zW__R#Pk>K|>;M1%&CSjI{QT(Bjqr3(~iED7=pW^j0RBMrn!@^*J&=wOxg0CIvn zT^vI=t|uonG+tm3I4Sju@l5A`hG&1+1803q@XEI3yb{VGDka6VWM5m`HHMWJE?ltZ ziSl-Ke%yFvRp`S12d`vFd}VYpG%#S)+@QT9>~JhQL-Hic-zWIi-U6DgTH+c}l9E`G zYL#4+3Zxi}3=GY54NP>6j6w_ztxV0VOiZ*546FkYez3 L^>bP0l+XkKgaUcx literal 0 HcmV?d00001 diff --git a/res/icons/text-window/workplane.png b/res/icons/text-window/workplane.png new file mode 100644 index 0000000000000000000000000000000000000000..7df689757b247f538a10c5b203b22311c61a3d74 GIT binary patch literal 462 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaN3?zjj6;1;wmUKs7M+S!VC(K#9UIO_F$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$XBD8XLh>Fdh=fJKZ)LCDl~ zvp!HrCBP@d_5c6>f`WodN=nAY#x5={p`oE^X=&x<<*lu)9UUDjR;<{uV~1HT?{T1d z#*!evUYh7ML)4(zT=OljGHCHLX-zdYp6Jwcky&>R!;}c2TXQUv`hgBm zEpd$~Nl7e8wMs5Z1yT$~28L$31}3^jMj?iVR;FfFCMMbj237_J|5g@@p=ij>PsvQH zglaI3VtQ&&YGO)d T;mK4`ATxNn`njxgN@xNAcv6Wz literal 0 HcmV?d00001 diff --git a/res/locales.txt b/res/locales.txt new file mode 100644 index 0000000..0f4fab1 --- /dev/null +++ b/res/locales.txt @@ -0,0 +1,8 @@ +# This file lists the ISO locale codes (ISO 639-1/ISO 3166-1), Windows LCIDs, +# and human-readable names for every culture supported by SolveSpace. +de-DE,0407,Deutsch +en-US,0409,English (US) +fr-FR,040C,Français +ru-RU,0419,Русский +uk-UA,0422,Українська +zh-CN,0804,简体中文 diff --git a/res/locales/de_DE.po b/res/locales/de_DE.po new file mode 100644 index 0000000..9222a1d --- /dev/null +++ b/res/locales/de_DE.po @@ -0,0 +1,2324 @@ +# German translations for the SolveSpace package. +# Copyright (C) 2018 the SolveSpace authors +# This file is distributed under the same license as the SolveSpace package. +# Guido Hoss , 2018. #zanata +msgid "" +msgstr "" +"Project-Id-Version: SolveSpace 3.0\n" +"Report-Msgid-Bugs-To: whitequark@whitequark.org\n" +"POT-Creation-Date: 2021-01-17 19:54+0200\n" +"PO-Revision-Date: 2018-07-19 06:55+0000\n" +"Last-Translator: Reini Urban \n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Zanata 4.5.0\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: clipboard.cpp:310 +msgid "" +"Cut, paste, and copy work only in a workplane.\n" +"\n" +"Activate one with Sketch -> In Workplane." +msgstr "" +"Ausschneiden, Einfügen und Kopieren sind nur in einer Arbeitsebene " +"zulässig.\n" +"\n" +"Aktivieren Sie eine mit Skizze -> In Arbeitsebene" + +#: clipboard.cpp:327 +msgid "Clipboard is empty; nothing to paste." +msgstr "Zwischenablage ist leer; es gibt nichts einzufügen." + +#: clipboard.cpp:374 +msgid "Number of copies to paste must be at least one." +msgstr "Die Anzahl der einzufügenden Kopien muss mind. 1 sein." + +#: clipboard.cpp:390 textscreens.cpp:783 +msgid "Scale cannot be zero." +msgstr "Maßstab kann nicht Null sein." + +#: clipboard.cpp:432 +msgid "Select one point to define origin of rotation." +msgstr "Wählen Sie einen Punkt, um den Drehmittelpunkt zu definieren." + +#: clipboard.cpp:444 +msgid "Select two points to define translation vector." +msgstr "Wählen Sie zwei Punkte, um den Verschiebungsvektor zu definieren." + +#: clipboard.cpp:454 +msgid "" +"Transformation is identity. So all copies will be exactly on top of each " +"other." +msgstr "" +"Die Transformation ist die Identität. Alle Kopien werden deckungsgleich " +"übereinanderliegen." + +#: clipboard.cpp:458 +msgid "Too many items to paste; split this into smaller pastes." +msgstr "" +"Zuviele Objekte zum Einfügen; teilen Sie diese in kleinere " +"Einfügeoperationen auf." + +#: clipboard.cpp:463 +msgid "No workplane active." +msgstr "Es ist keine Arbeitsebene aktiv." + +#: confscreen.cpp:418 +msgid "Bad format: specify coordinates as x, y, z" +msgstr "Ungültiges Format: geben Sie Koordinaten als x, y, z an" + +#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805 +msgid "Bad format: specify color as r, g, b" +msgstr "Ungültiges Format: geben Sie Farben als r, g, b an" + +#: confscreen.cpp:454 +msgid "" +"The perspective factor will have no effect until you enable View -> Use " +"Perspective Projection." +msgstr "" +"Der Perspektivfaktor wird sich nicht auswirken, bis Sie Ansicht -> " +"Perspektive Projektion aktivieren." + +#: confscreen.cpp:467 confscreen.cpp:477 +#, c-format +msgid "Specify between 0 and %d digits after the decimal." +msgstr "Geben Sie 0 bis %d Ziffern nach dem Dezimalzeichen an." + +#: confscreen.cpp:489 +msgid "Export scale must not be zero!" +msgstr "Der Exportmaßstab darf nicht Null sein!" + +#: confscreen.cpp:501 +msgid "Cutter radius offset must not be negative!" +msgstr "Der Werkzeugradialabstand darf nicht negativ sein!" + +#: confscreen.cpp:555 +msgid "Bad value: autosave interval should be positive" +msgstr "" +"Ungültiger Wert: Interval für automatisches Speichern muss positiv sein" + +#: confscreen.cpp:558 +msgid "Bad format: specify interval in integral minutes" +msgstr "Ungültiges Format: geben Sie das Interval in ganzen Minuten an" + +#: constraint.cpp:12 +msgctxt "constr-name" +msgid "pts-coincident" +msgstr "Pkt-Deckung" + +#: constraint.cpp:13 +msgctxt "constr-name" +msgid "pt-pt-distance" +msgstr "Pkt-Pkt-Abstand" + +#: constraint.cpp:14 +msgctxt "constr-name" +msgid "pt-line-distance" +msgstr "Pkt-Linie-Abstand" + +#: constraint.cpp:15 +msgctxt "constr-name" +msgid "pt-plane-distance" +msgstr "Pkt-Ebene-Abstand" + +#: constraint.cpp:16 +msgctxt "constr-name" +msgid "pt-face-distance" +msgstr "Pkt-Fläche-Abstand" + +#: constraint.cpp:17 +msgctxt "constr-name" +msgid "proj-pt-pt-distance" +msgstr "Proj-Pkt-Pkt-Abstand" + +#: constraint.cpp:18 +msgctxt "constr-name" +msgid "pt-in-plane" +msgstr "Pkt-in-Ebene" + +#: constraint.cpp:19 +msgctxt "constr-name" +msgid "pt-on-line" +msgstr "Pkt-auf-Linie" + +#: constraint.cpp:20 +msgctxt "constr-name" +msgid "pt-on-face" +msgstr "Pkt-auf-Fläche" + +#: constraint.cpp:21 +msgctxt "constr-name" +msgid "eq-length" +msgstr "gl-Länge" + +#: constraint.cpp:22 +msgctxt "constr-name" +msgid "eq-length-and-pt-ln-dist" +msgstr "gl-Länge-und-Pkt-Linie-Abstand" + +#: constraint.cpp:23 +msgctxt "constr-name" +msgid "eq-pt-line-distances" +msgstr "gl-Pkt-Linie-Abstände" + +#: constraint.cpp:24 +msgctxt "constr-name" +msgid "length-ratio" +msgstr "Längenverhältnis" + +#: constraint.cpp:25 +msgctxt "constr-name" +msgid "length-difference" +msgstr "Längendifferenz" + +#: constraint.cpp:26 +msgctxt "constr-name" +msgid "symmetric" +msgstr "Symmetrisch" + +#: constraint.cpp:27 +msgctxt "constr-name" +msgid "symmetric-h" +msgstr "Symmetrisch-H" + +#: constraint.cpp:28 +msgctxt "constr-name" +msgid "symmetric-v" +msgstr "Symmetrisch-V" + +#: constraint.cpp:29 +msgctxt "constr-name" +msgid "symmetric-line" +msgstr "Symmetrisch-Linie" + +#: constraint.cpp:30 +msgctxt "constr-name" +msgid "at-midpoint" +msgstr "auf-Mittelpunkt" + +#: constraint.cpp:31 +msgctxt "constr-name" +msgid "horizontal" +msgstr "Horizontal" + +#: constraint.cpp:32 +msgctxt "constr-name" +msgid "vertical" +msgstr "Vertikal" + +#: constraint.cpp:33 +msgctxt "constr-name" +msgid "diameter" +msgstr "Durchmesser" + +#: constraint.cpp:34 +msgctxt "constr-name" +msgid "pt-on-circle" +msgstr "Pkt-auf-Kreis" + +#: constraint.cpp:35 +msgctxt "constr-name" +msgid "same-orientation" +msgstr "gl-Orientierung" + +#: constraint.cpp:36 +msgctxt "constr-name" +msgid "angle" +msgstr "Winkel" + +#: constraint.cpp:37 +msgctxt "constr-name" +msgid "parallel" +msgstr "Parallel" + +#: constraint.cpp:38 +msgctxt "constr-name" +msgid "arc-line-tangent" +msgstr "Bogen-Linie-Tangente" + +#: constraint.cpp:39 +msgctxt "constr-name" +msgid "cubic-line-tangent" +msgstr "Kub-Linie-Tangente" + +#: constraint.cpp:40 +msgctxt "constr-name" +msgid "curve-curve-tangent" +msgstr "Kurve-Kurve-Tangente" + +#: constraint.cpp:41 +msgctxt "constr-name" +msgid "perpendicular" +msgstr "Rechtwinklig" + +#: constraint.cpp:42 +msgctxt "constr-name" +msgid "eq-radius" +msgstr "gl-Radius" + +#: constraint.cpp:43 +msgctxt "constr-name" +msgid "eq-angle" +msgstr "gl-Winkel" + +#: constraint.cpp:44 +msgctxt "constr-name" +msgid "eq-line-len-arc-len" +msgstr "gl-Linie-Länge-Bogen-Länge" + +#: constraint.cpp:45 +msgctxt "constr-name" +msgid "lock-where-dragged" +msgstr "Fix-an-Position" + +#: constraint.cpp:46 +msgctxt "constr-name" +msgid "comment" +msgstr "Kommentar" + +#: constraint.cpp:140 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." +msgstr "" +"Die Bogentangente und das Liniensegment müssen einen gemeinsamen Endpunkt " +"haben. Schränken Sie mit \"Einschränkung / Auf Punkt\" ein, bevor Sie die " +"Tangente einschränken. -> Sc" + +#: constraint.cpp:158 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." +msgstr "" +"Die Kurventangente und das Liniensegment müssen einen gemeinsamen Endpunkt " +"haben. Schränken Sie mit \"Einschränkung / Auf Punkt\" ein, bevor Sie die " +"Tangente einschränken. -> Sc" + +#: constraint.cpp:183 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." +msgstr "" +"Die Kurven müssen einen gemeinsamen Endpunkt haben. Schränken Sie mit " +"\"Einschränkung / Auf Punkt\" ein, bevor Sie die Tangente einschränken. -> Sc" + +#: constraint.cpp:231 +msgid "" +"Bad selection for distance / diameter constraint. This constraint can apply " +"to:\n" +"\n" +" * two points (distance between points)\n" +" * a line segment (length)\n" +" * two points and a line segment or normal (projected distance)\n" +" * a workplane and a point (minimum distance)\n" +" * a line segment and a point (minimum distance)\n" +" * a plane face and a point (minimum distance)\n" +" * a circle or an arc (diameter)\n" +msgstr "" +"Ungültige Auswahl für Einschränkung Abstand / Durchmesser Diese " +"Einschränkung ist anwendbar auf:\n" +"\n" +" * zwei Punkte [Abstand zwischen Punkten]\n" +" * ein Liniensegment [Länge]\n" +" * zwei Punkte und ein Liniensegment oder Normale [projizierter Abstand]\n" +" * eine Arbeitsebene und ein Punkt [minimaler Abstand] \n" +" * ein Liniensegment und ein Punkt [minimaler Abstand]\n" +" * eine Seitenfläche und ein Punkt [minimaler Abstand]\n" +" * ein Kreis oder ein Bogen [Durchmesser]\n" + +#: constraint.cpp:284 +msgid "" +"Bad selection for on point / curve / plane constraint. This constraint can " +"apply to:\n" +"\n" +" * two points (points coincident)\n" +" * a point and a workplane (point in plane)\n" +" * a point and a line segment (point on line)\n" +" * a point and a circle or arc (point on curve)\n" +" * a point and a plane face (point on face)\n" +msgstr "" +"Ungültige Auswahl für Einschränkung \"Auf Punkt / Kurve / Ebene\". Diese " +"Einschränkung ist anwendbar auf:\n" +"\n" +" * zwei Punkte [deckungsgleich]\n" +" * einen Punkt und eine Arbeitsebene [Punkt auf Ebene]\n" +" * einen Punkt und ein Liniensegment [Punkt auf Linie]\n" +" * einen Punkt und einen Kreis oder Bogen [Punkt auf Kurve]\n" +" * einen Punkt und eine Seitenfläche [Punkt auf Fläche]\n" + +#: constraint.cpp:346 +msgid "" +"Bad selection for equal length / radius constraint. This constraint can " +"apply to:\n" +"\n" +" * two line segments (equal length)\n" +" * two line segments and two points (equal point-line distances)\n" +" * a line segment and two points (equal point-line distances)\n" +" * a line segment, and a point and line segment (point-line distance " +"equals length)\n" +" * four line segments or normals (equal angle between A,B and C,D)\n" +" * three line segments or normals (equal angle between A,B and B,C)\n" +" * two circles or arcs (equal radius)\n" +" * a line segment and an arc (line segment length equals arc length)\n" +msgstr "" +"Ungültige Auswahl für Einschränkung \"gleicher Abstand / Radius\". Diese " +"Einschränkung ist anwendbar auf:\n" +"\n" +" * zwei Liniensegmente [gleiche Länge]\n" +" * zwei Liniensegmente und zwei Punkte [gleiche Punkt-Linien-Abstände]\n" +" * ein Liniensegment und zwei Punkte [gleiche Punkt-Linien-Abstände]\n" +" * ein Liniensegment und ein Punkt oder Liniensegment [Abstand Punkt-" +"Linie gleich Länge]\n" +" * vier Liniensegmente oder Normale [gleicher Winkel zwischen A,B und C," +"D]\n" +" * drei Liniensegmente oder Normale [gleicher Winkel zwischen A,B und B," +"C]\n" +" * zwei Kreise oder Bögen [gleicher Radius]\n" +" * ein Liniensegment und ein Bogen [Länge des Liniensegments gleich " +"Bogenlänge]\n" + +#: constraint.cpp:385 +msgid "" +"Bad selection for length ratio constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +msgstr "" +"Ungültige Auswahl für Einschränkung \"Längenverhältnis\". Diese " +"Einschränkung ist anwendbar auf:\n" +"\n" +" * zwei Liniensegmente\n" + +#: constraint.cpp:402 +msgid "" +"Bad selection for length difference constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments\n" +msgstr "" +"Ungültige Auswahl für Einschränkung \"Längendifferenz\". Diese Einschränkung " +"ist anwendbar auf:\n" +"\n" +" * zwei Liniensegmente\n" + +#: constraint.cpp:428 +msgid "" +"Bad selection for at midpoint constraint. This constraint can apply to:\n" +"\n" +" * a line segment and a point (point at midpoint)\n" +" * a line segment and a workplane (line's midpoint on plane)\n" +msgstr "" +"Ungültige Auswahl für Einschränkung \"Mittelpunkt\". Diese Einschränkung ist " +"anwendbar auf:\n" +"\n" +" * ein Liniensegment und ein Punkt [Punkt auf Mittelpunkt]\n" +" * ein Liniensegment und eine Arbeitsebene [Mittelpunkt der Linie auf " +"Ebene]\n" + +#: constraint.cpp:486 +msgid "" +"Bad selection for symmetric constraint. This constraint can apply to:\n" +"\n" +" * two points or a line segment (symmetric about workplane's coordinate " +"axis)\n" +" * line segment, and two points or a line segment (symmetric about line " +"segment)\n" +" * workplane, and two points or a line segment (symmetric about " +"workplane)\n" +msgstr "" +"Ungültige Auswahl für Einschränkung \"Symmetrisch\". Diese Einschränkung ist " +"anwendbar auf:\n" +"\n" +" * zwei Punkte oder ein Liniensegment [symmetrisch zu Koordinatenachse " +"der Arbeitsebene]\n" +" * ein Liniensegment und zwei Punkte oder ein Liniensegment [symmetrisch " +"zu Liniensegment]\n" +" * eine Arbeitsebene und zwei Punkte oder ein Liniensegment [symmetrisch " +"zu Arbeitsebene]\n" + +#: constraint.cpp:500 +msgid "" +"A workplane must be active when constraining symmetric without an explicit " +"symmetry plane." +msgstr "" +"Eine Arbeitsebene muss aktiv sein, um die Symmetrie ohne explizite " +"Symmetrieebene einzuschränken." + +#: constraint.cpp:530 +msgid "" +"Activate a workplane (with Sketch -> In Workplane) before applying a " +"horizontal or vertical constraint." +msgstr "" +"Aktivieren Sie eine Arbeitsebene (mit Skizze -> In Arbeitsebene), bevor Sie " +"horizontal oder vertikal einschränken." + +#: constraint.cpp:543 +msgid "" +"Bad selection for horizontal / vertical constraint. This constraint can " +"apply to:\n" +"\n" +" * two points\n" +" * a line segment\n" +msgstr "" +"Ungültige Auswahl für Einschränkung \"horizontal / vertikal\". Diese " +"Einschränkung ist anwendbar auf:\n" +"\n" +" * zwei Punkte\n" +" * ein Liniensegment\n" + +#: constraint.cpp:564 +msgid "" +"Bad selection for same orientation constraint. This constraint can apply " +"to:\n" +"\n" +" * two normals\n" +msgstr "" +"Ungültige Auswahl für Einschränkung \"gleiche Orientierung\". Diese " +"Einschränkung ist anwendbar auf:\n" +"\n" +" * zwei Normale\n" + +#: constraint.cpp:614 +msgid "Must select an angle constraint." +msgstr "Sie müssen einen eingeschränkten Winkel auswählen." + +#: constraint.cpp:627 +msgid "Must select a constraint with associated label." +msgstr "Sie müssen eine Einschränkung mit zugeordneter Kennzeichnung angeben." + +#: constraint.cpp:638 +msgid "" +"Bad selection for angle constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" +"Ungültige Auswahl für Einschränkung \"Winkel\". Diese Einschränkung ist " +"anwendbar auf:\n" +"\n" +" * zwei Liniensegmente\n" +" * ein Liniensegment und eine Normale\n" +" * zwei Normale\n" + +#: constraint.cpp:701 +msgid "Curve-curve tangency must apply in workplane." +msgstr "" +"Die Kurven-Kurven-Tangente muss in der Arbeitsebene eingeschränkt werden." + +#: constraint.cpp:711 +msgid "" +"Bad selection for parallel / tangent constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments (parallel)\n" +" * a line segment and a normal (parallel)\n" +" * two normals (parallel)\n" +" * two line segments, arcs, or beziers, that share an endpoint (tangent)\n" +msgstr "" +"Ungültige Auswahl für Einschränkung \"Parallel / Tangente\". Diese " +"Einschränkung ist anwendbar auf:\n" +"\n" +" * zwei Liniensegmente [parallel]\n" +" * ein Liniensegment und eine Normale [parallel]\n" +" * zwei Normalen [parallel]\n" +" * zwei Liniensegmente, Bögen oder Beziers mit gemeinsamem Endpunkt " +"[Tangente]\n" + +#: constraint.cpp:729 +msgid "" +"Bad selection for perpendicular constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" +"Ungültige Auswahl für Einschränkung \"Rechtwinklig\". Diese Einschränkung " +"ist anwendbar auf:\n" +"\n" +" * zwei Liniensegmente\n" +" * ein Liniensegment und eine Normale\n" +" * zwei Normale\n" + +#: constraint.cpp:744 +msgid "" +"Bad selection for lock point where dragged constraint. This constraint can " +"apply to:\n" +"\n" +" * a point\n" +msgstr "" +"Ungültige Auswahl für Einschränkung \"Punkt an Position\". Diese " +"Einschränkung ist anwendbar auf:\n" +"\n" +" * einen Punkt\n" + +#: constraint.cpp:755 +msgid "click center of comment text" +msgstr "Klicken Sie auf die Mitte des Kommentartextes" + +#: export.cpp:19 +msgid "" +"No solid model present; draw one with extrudes and revolves, or use Export " +"2d View to export bare lines and curves." +msgstr "" +"Kein Festkörper vorhanden; zeichnen Sie eines mit Extrusionen und Drehungen, " +"oder exportieren Sie bloße Linien und Kurven mit \"2D-Ansicht exportieren\"" + +#: export.cpp:61 +msgid "" +"Bad selection for export section. Please select:\n" +"\n" +" * nothing, with an active workplane (workplane is section plane)\n" +" * a face (section plane through face)\n" +" * a point and two line segments (plane through point and parallel to " +"lines)\n" +msgstr "" +"Ungültige Auswahl für teilweisen Export. Bitte wählen Sie aus:\n" +"\n" +" * nichts, mit einer aktiven Arbeitsebene [Arbeitsebene ist " +"Schnittebene]\n" +" * eine Seitenfläche [Schnittebene durch Seitenfläche]\n" +" * einen Punkt und zwei Liniensegmente [Schnittebene durch Punkt und " +"parallel zu Linien]\n" + +#: export.cpp:822 +msgid "Active group mesh is empty; nothing to export." +msgstr "Das Netz der aktiven Gruppe ist leer; es gibt nichts zu exportieren." + +#: exportvector.cpp:337 +msgid "freehand lines were replaced with continuous lines" +msgstr "Freihandlinien wurden mit durchgehenden Linien ersetzt" + +#: exportvector.cpp:339 +msgid "zigzag lines were replaced with continuous lines" +msgstr "Zickzacklinien wurden mit durchgehenden Linien ersetzt" + +#: exportvector.cpp:593 +msgid "" +"Some aspects of the drawing have no DXF equivalent and were not exported:\n" +msgstr "" +"Teile der Zeichnung haben keine Entsprechung in DXF und wurden nicht " +"exportiert:\n" + +#: exportvector.cpp:839 +msgid "" +"PDF page size exceeds 200 by 200 inches; many viewers may reject this file." +msgstr "" +"Die PDF-Seitengröße überschreitet 200 x 200 Zoll; die Datei kann u.U. in " +"vielen Programmen nicht geöffnet werden." + +#: file.cpp:44 group.cpp:91 +msgctxt "group-name" +msgid "sketch-in-plane" +msgstr "Skizze-in-Ebene" + +#: file.cpp:62 +msgctxt "group-name" +msgid "#references" +msgstr "#Referenzen" + +#: file.cpp:549 +msgid "" +"Unrecognized data in file. This file may be corrupt, or from a newer version " +"of the program." +msgstr "" +"Nicht erkannte Daten in der Datei. Diese Datei könnte beschädigt sein oder " +"von einer neueren Version des Programms stammen." + +#: file.cpp:859 +msgctxt "title" +msgid "Missing File" +msgstr "Fehlende Datei" + +#: file.cpp:860 +#, c-format +msgctxt "dialog" +msgid "The linked file “%s” is not present." +msgstr "Die verlinkte Datei “%s” fehlt." + +#: file.cpp:862 +msgctxt "dialog" +msgid "" +"Do you want to locate it manually?\n" +"\n" +"If you decline, any geometry that depends on the missing file will be " +"permanently removed." +msgstr "" +"Möchten Sie sie selber auswählen?\n" +"Falls Sie ablehnen, wird jegliche mit der fehlenden Datei verknüpfte " +"Geometrie verworfen." + +#: file.cpp:865 +msgctxt "button" +msgid "&Yes" +msgstr "&Ja" + +#: file.cpp:867 +msgctxt "button" +msgid "&No" +msgstr "&Nein" + +#: file.cpp:869 solvespace.cpp:569 +msgctxt "button" +msgid "&Cancel" +msgstr "&Abbrechen" + +#: graphicswin.cpp:41 +msgid "&File" +msgstr "&Datei" + +#: graphicswin.cpp:42 +msgid "&New" +msgstr "&Neu" + +#: graphicswin.cpp:43 +msgid "&Open..." +msgstr "&Öffnen" + +#: graphicswin.cpp:44 +msgid "Open &Recent" +msgstr "Öffne &letzte" + +#: graphicswin.cpp:45 +msgid "&Save" +msgstr "&Speichern" + +#: graphicswin.cpp:46 +msgid "Save &As..." +msgstr "Speichern &Als…" + +#: graphicswin.cpp:48 +msgid "Export &Image..." +msgstr "Exportiere &Bild…" + +#: graphicswin.cpp:49 +msgid "Export 2d &View..." +msgstr "Exportiere 2D-Ansicht…" + +#: graphicswin.cpp:50 +msgid "Export 2d &Section..." +msgstr "Exportiere 2D-Auswahl…" + +#: graphicswin.cpp:51 +msgid "Export 3d &Wireframe..." +msgstr "Exportiere 3D-Drahtgittermodell" + +#: graphicswin.cpp:52 +msgid "Export Triangle &Mesh..." +msgstr "Exportiere Dreiecksnetz…" + +#: graphicswin.cpp:53 +msgid "Export &Surfaces..." +msgstr "Exportiere Oberflächen…" + +#: graphicswin.cpp:54 +msgid "Im&port..." +msgstr "Im&port…" + +#: graphicswin.cpp:57 +msgid "E&xit" +msgstr "Beenden" + +#: graphicswin.cpp:60 +msgid "&Edit" +msgstr "&Bearbeiten" + +#: graphicswin.cpp:61 +msgid "&Undo" +msgstr "&Rückgängig machen" + +#: graphicswin.cpp:62 +msgid "&Redo" +msgstr "&Wiederholen" + +#: graphicswin.cpp:63 +msgid "Re&generate All" +msgstr "Alles &neu zeichnen" + +#: graphicswin.cpp:65 +msgid "Snap Selection to &Grid" +msgstr "Auswahl auf &Raster ausrichten" + +#: graphicswin.cpp:66 +msgid "Rotate Imported &90°" +msgstr "Importierte Objekte &90° drehen" + +#: graphicswin.cpp:68 +msgid "Cu&t" +msgstr "Ausschneiden" + +#: graphicswin.cpp:69 +msgid "&Copy" +msgstr "Kopieren" + +#: graphicswin.cpp:70 +msgid "&Paste" +msgstr "Einfügen" + +#: graphicswin.cpp:71 +msgid "Paste &Transformed..." +msgstr "&Transformiert einfügen…" + +#: graphicswin.cpp:72 +msgid "&Delete" +msgstr "&Löschen" + +#: graphicswin.cpp:74 +msgid "Select &Edge Chain" +msgstr "&Kantenverlauf auswählen" + +#: graphicswin.cpp:75 +msgid "Select &All" +msgstr "&Alle auswählen" + +#: graphicswin.cpp:76 +msgid "&Unselect All" +msgstr "Alle &deselektieren" + +#: graphicswin.cpp:78 +msgid "&Line Styles..." +msgstr "&Linien Stile..." + +#: graphicswin.cpp:79 +msgid "&View Projection..." +msgstr "An&sichts Projektion..." + +#: graphicswin.cpp:81 +msgid "Con&figuration..." +msgstr "&Einstellungen..." + +#: graphicswin.cpp:84 +msgid "&View" +msgstr "Ansicht" + +#: graphicswin.cpp:85 +msgid "Zoom &In" +msgstr "Zoom größer" + +#: graphicswin.cpp:86 +msgid "Zoom &Out" +msgstr "Zoom kleiner" + +#: graphicswin.cpp:87 +msgid "Zoom To &Fit" +msgstr "Zoom anpassen" + +#: graphicswin.cpp:89 +msgid "Align View to &Workplane" +msgstr "Ansicht auf Arbeitsebene ausrichten" + +#: graphicswin.cpp:90 +msgid "Nearest &Ortho View" +msgstr "Nächste Ortho-Ansicht" + +#: graphicswin.cpp:91 +msgid "Nearest &Isometric View" +msgstr "Nächste isometrische Ansicht" + +#: graphicswin.cpp:92 +msgid "&Center View At Point" +msgstr "Ansicht auf Punkt zentrieren" + +#: graphicswin.cpp:94 +msgid "Show Snap &Grid" +msgstr "Arbeitsraster anzeigen" + +#: graphicswin.cpp:95 +msgid "Darken Inactive Solids" +msgstr "Dunklere inaktive Festkörper" + +#: graphicswin.cpp:96 +msgid "Use &Perspective Projection" +msgstr "Perspektivische Projektion" + +#: graphicswin.cpp:97 +msgid "Dimension &Units" +msgstr "Maßeinheit" + +#: graphicswin.cpp:98 +msgid "Dimensions in &Millimeters" +msgstr "Maße in Millimeter" + +#: graphicswin.cpp:99 +msgid "Dimensions in M&eters" +msgstr "Masse in M&etern" + +#: graphicswin.cpp:100 +msgid "Dimensions in &Inches" +msgstr "Maße in Zoll" + +#: graphicswin.cpp:102 +msgid "Show &Toolbar" +msgstr "Werkzeugleiste anzeigen" + +#: graphicswin.cpp:103 +msgid "Show Property Bro&wser" +msgstr "Attributbrowser anzeigen" + +#: graphicswin.cpp:105 +msgid "&Full Screen" +msgstr "Vollbildschirm" + +#: graphicswin.cpp:107 +msgid "&New Group" +msgstr "Neue Gruppe" + +#: graphicswin.cpp:108 +msgid "Sketch In &3d" +msgstr "In 3D skizzieren" + +#: graphicswin.cpp:109 +msgid "Sketch In New &Workplane" +msgstr "In neuer Arbeitsebene skizzieren" + +#: graphicswin.cpp:111 +msgid "Step &Translating" +msgstr "Kopieren und verschieben" + +#: graphicswin.cpp:112 +msgid "Step &Rotating" +msgstr "Kopieren und drehen" + +#: graphicswin.cpp:114 +msgid "E&xtrude" +msgstr "E&xtrudieren" + +#: graphicswin.cpp:115 +msgid "&Helix" +msgstr "&Helix" + +#: graphicswin.cpp:116 +msgid "&Lathe" +msgstr "R&otieren" + +#: graphicswin.cpp:117 +msgid "Re&volve" +msgstr "D&rehen" + +#: graphicswin.cpp:119 +msgid "Link / Assemble..." +msgstr "Verknüpfen / Zusammensetzen" + +#: graphicswin.cpp:120 +msgid "Link Recent" +msgstr "Letzte verknüpfen" + +#: graphicswin.cpp:122 +msgid "&Sketch" +msgstr "&Skizze" + +#: graphicswin.cpp:123 +msgid "In &Workplane" +msgstr "In Arbeitsebene" + +#: graphicswin.cpp:124 +msgid "Anywhere In &3d" +msgstr "Im 3D-Raum" + +#: graphicswin.cpp:126 +msgid "Datum &Point" +msgstr "Bezugspunkt" + +#: graphicswin.cpp:127 +msgid "&Workplane" +msgstr "Arbeits&ebene" + +#: graphicswin.cpp:129 +msgid "Line &Segment" +msgstr "&Linie" + +#: graphicswin.cpp:130 +msgid "C&onstruction Line Segment" +msgstr "K&onstruktionslinie" + +#: graphicswin.cpp:131 +msgid "&Rectangle" +msgstr "&Rechteck" + +#: graphicswin.cpp:132 +msgid "&Circle" +msgstr "&Kreis" + +#: graphicswin.cpp:133 +msgid "&Arc of a Circle" +msgstr "Kreisbogen" + +#: graphicswin.cpp:134 +msgid "&Bezier Cubic Spline" +msgstr "Kubischer &Bezier-Spline" + +#: graphicswin.cpp:136 +msgid "&Text in TrueType Font" +msgstr "&Text in Truetype-Font" + +#: graphicswin.cpp:137 +msgid "&Image" +msgstr "B&ild" + +#: graphicswin.cpp:139 +msgid "To&ggle Construction" +msgstr "Konstruktionselement an/aus" + +#: graphicswin.cpp:140 +msgid "Tangent &Arc at Point" +msgstr "Bogentangente an Punkt" + +#: graphicswin.cpp:141 +msgid "Split Curves at &Intersection" +msgstr "Kurven im Schnittpunkt trennen" + +#: graphicswin.cpp:143 +msgid "&Constrain" +msgstr "&Einschränkung" + +#: graphicswin.cpp:144 +msgid "&Distance / Diameter" +msgstr "Abstand / Durchmesser" + +#: graphicswin.cpp:145 +msgid "Re&ference Dimension" +msgstr "Referenzangabe" + +#: graphicswin.cpp:146 +msgid "A&ngle" +msgstr "Winkel" + +#: graphicswin.cpp:147 +msgid "Reference An&gle" +msgstr "Referenzwinkel" + +#: graphicswin.cpp:148 +msgid "Other S&upplementary Angle" +msgstr "Komplementärwinkel" + +#: graphicswin.cpp:149 +msgid "Toggle R&eference Dim" +msgstr "Referenzangabe ein/aus" + +#: graphicswin.cpp:151 +msgid "&Horizontal" +msgstr "Horizontal" + +#: graphicswin.cpp:152 +msgid "&Vertical" +msgstr "&Vertikal" + +#: graphicswin.cpp:154 +msgid "&On Point / Curve / Plane" +msgstr "Auf Punkt / Kurve / Ebene" + +#: graphicswin.cpp:155 +msgid "E&qual Length / Radius / Angle" +msgstr "Gleicher Abstand / Radius / Winkel" + +#: graphicswin.cpp:156 +msgid "Length Ra&tio" +msgstr "Längenverhältnis" + +#: graphicswin.cpp:157 +msgid "Length Diff&erence" +msgstr "Längendifferenz" + +#: graphicswin.cpp:158 +msgid "At &Midpoint" +msgstr "Auf &Mittelpunkt" + +#: graphicswin.cpp:159 +msgid "S&ymmetric" +msgstr "Symmetrisch" + +#: graphicswin.cpp:160 +msgid "Para&llel / Tangent" +msgstr "Paral&llel / Tangente" + +#: graphicswin.cpp:161 +msgid "&Perpendicular" +msgstr "Rechtwinklig" + +#: graphicswin.cpp:162 +msgid "Same Orient&ation" +msgstr "Gleiche Orientierung" + +#: graphicswin.cpp:163 +msgid "Lock Point Where &Dragged" +msgstr "Punkt an Position fixieren" + +#: graphicswin.cpp:165 +msgid "Comment" +msgstr "Kommentar" + +#: graphicswin.cpp:167 +msgid "&Analyze" +msgstr "&Analyse" + +#: graphicswin.cpp:168 +msgid "Measure &Volume" +msgstr "&Volumen bestimmen" + +#: graphicswin.cpp:169 +msgid "Measure A&rea" +msgstr "Fläche bestimmen" + +#: graphicswin.cpp:170 +msgid "Measure &Perimeter" +msgstr "Umfang bestimmen" + +#: graphicswin.cpp:171 +msgid "Show &Interfering Parts" +msgstr "Überlagernde Teile anzeigen" + +#: graphicswin.cpp:172 +msgid "Show &Naked Edges" +msgstr "Freiliegende Kanten anzeigen" + +#: graphicswin.cpp:173 +msgid "Show &Center of Mass" +msgstr "Massenmittelpunkt anzeigen" + +#: graphicswin.cpp:175 +msgid "Show &Underconstrained Points" +msgstr "&Unterbeschränkte Punkte anzeigen" + +#: graphicswin.cpp:177 +msgid "&Trace Point" +msgstr "Punkt nachzeichnen" + +#: graphicswin.cpp:178 +msgid "&Stop Tracing..." +msgstr "Nachzeichnen beenden" + +#: graphicswin.cpp:179 +msgid "Step &Dimension..." +msgstr "Schrittgröße…" + +#: graphicswin.cpp:181 +msgid "&Help" +msgstr "&Hilfe" + +#: graphicswin.cpp:182 +msgid "&Language" +msgstr "Sprache" + +#: graphicswin.cpp:183 +msgid "&Website / Manual" +msgstr "&Website / Anleitung" + +#: graphicswin.cpp:185 +msgid "&About" +msgstr "Über" + +#: graphicswin.cpp:355 +msgid "(no recent files)" +msgstr "(keine vorhergehenden Dateien)" + +#: graphicswin.cpp:363 +#, c-format +msgid "File '%s' does not exist." +msgstr "Datei '%s' existiert nicht." + +#: graphicswin.cpp:725 +msgid "No workplane is active, so the grid will not appear." +msgstr "" +"Das Raster wird nicht angezeigt, weil keine Arbeitsebene ausgewählt ist." + +#: graphicswin.cpp:740 +msgid "" +"The perspective factor is set to zero, so the view will always be a parallel " +"projection.\n" +"\n" +"For a perspective projection, modify the perspective factor in the " +"configuration screen. A value around 0.3 is typical." +msgstr "" +"Der Perspektivfaktor is auf Null gesetzt, also wird die Ansicht eine " +"Parallelprojektion sein.\n" +"\n" +"Ändern Sie den Faktor für die Perspektivprojektion in der " +"Konfigurationsmaske. Ein typischer Wert ist ca. 0,3." + +#: graphicswin.cpp:819 +msgid "" +"Select a point; this point will become the center of the view on screen." +msgstr "" +"Wählen Sie einen Punkt aus; dieser Punkt wird im Mittelpunkt der " +"Bildschirmansicht sein." + +#: graphicswin.cpp:1114 +msgid "No additional entities share endpoints with the selected entities." +msgstr "" +"Die ausgewählten Objekte teilen keine gemeinsamen Endpunkte mit anderen " +"Objekten." + +#: graphicswin.cpp:1132 +msgid "" +"To use this command, select a point or other entity from an linked part, or " +"make a link group the active group." +msgstr "" +"Für diesen Befehl wählen Sie einen Punkt oder ein anderes Objekt von einem " +"verknüpften Teil aus, oder aktivieren Sie eine verknüpfte Gruppe." + +#: graphicswin.cpp:1155 +msgid "" +"No workplane is active. Activate a workplane (with Sketch -> In Workplane) " +"to define the plane for the snap grid." +msgstr "" +"Es wurde keine Arbeitsebene ausgewählt. Aktivieren Sie eine Arbeitsebene " +"(mit Skizze -> In Arbeitsebene), um die Ebene für das Gitterraster zu " +"definieren." + +#: graphicswin.cpp:1162 +msgid "" +"Can't snap these items to grid; select points, text comments, or constraints " +"with a label. To snap a line, select its endpoints." +msgstr "" +"Diese Objekte können nicht auf das Raster ausgerichtet werden. Dies geht nur " +"für Punkte, Textkommentare, oder Einschränkungen mit einer Bezeichnung. Um " +"eine Linie auf das Raster auszurichten, wählen Sie deren Endpunkte aus." + +#: graphicswin.cpp:1247 +msgid "No workplane selected. Activating default workplane for this group." +msgstr "" +"Es wurde keine Arbeitsebene ausgewählt. Die Standard-Arbeitsebene für diese " +"Gruppe wird aktiviert." + +#: graphicswin.cpp:1250 +msgid "" +"No workplane is selected, and the active group does not have a default " +"workplane. Try selecting a workplane, or activating a sketch-in-new-" +"workplane group." +msgstr "" +"Es wurde keine Arbeitsebene ausgewählt, und die aktive Gruppe hat keine " +"standardmäßige Arbeitsebene. Wählen Sie eine Arbeitsebene aus, oder " +"erstellen Sie eine Gruppe in einer neuen Arbeitsebene." + +#: graphicswin.cpp:1271 +msgid "" +"Bad selection for tangent arc at point. Select a single point, or select " +"nothing to set up arc parameters." +msgstr "" +"Ungültige Auswahl für Bogentangente an Punkt. Wählen Sie einen einzelnen " +"Punkt. Um die Bogenparameter anzugeben, wählen Sie nichts aus." + +#: graphicswin.cpp:1282 +msgid "click point on arc (draws anti-clockwise)" +msgstr "" +"Erstellen Sie einen Punkt auf dem Bogen (zeichnet im Gegenuhrzeigersinn)" + +#: graphicswin.cpp:1283 +msgid "click to place datum point" +msgstr "Klicken Sie, um einen Bezugspunkt zu platzieren" + +#: graphicswin.cpp:1284 +msgid "click first point of line segment" +msgstr "Klicken Sie auf den ersten Punkt des Liniensegments" + +#: graphicswin.cpp:1286 +msgid "click first point of construction line segment" +msgstr "Klicken Sie auf den ersten Punkt der Konstruktionslinie" + +#: graphicswin.cpp:1287 +msgid "click first point of cubic segment" +msgstr "Klicken Sie auf den ersten Punkt der kubischen Linie" + +#: graphicswin.cpp:1288 +msgid "click center of circle" +msgstr "Klicken Sie auf den Kreismittelpunkt" + +#: graphicswin.cpp:1289 +msgid "click origin of workplane" +msgstr "Klicken Sie auf den Ursprungspunkt der Arbeitsebene" + +#: graphicswin.cpp:1290 +msgid "click one corner of rectangle" +msgstr "Klicken Sie auf eine Ecke des Rechtecks" + +#: graphicswin.cpp:1291 +msgid "click top left of text" +msgstr "Klicken Sie auf die obere linke Ecke des Texts" + +#: graphicswin.cpp:1297 +msgid "click top left of image" +msgstr "Klicken Sie auf die obere linke Ecke des Bilds" + +#: graphicswin.cpp:1309 +msgid "" +"No entities are selected. Select entities before trying to toggle their " +"construction state." +msgstr "" +"Es wurden keine Objekte ausgewählt Wählen Sie Objekte aus, bevor Sie sie von/" +"zu Konstruktionsmerkmalen umwandeln." + +#: group.cpp:86 +msgctxt "group-name" +msgid "sketch-in-3d" +msgstr "Skizze-in-3D" + +#: group.cpp:142 +msgid "" +"Bad selection for new sketch in workplane. This group can be created with:\n" +"\n" +" * a point (through the point, orthogonal to coordinate axes)\n" +" * a point and two line segments (through the point, parallel to the " +"lines)\n" +" * a workplane (copy of the workplane)\n" +msgstr "" +"Ungültige Auswahl für Skizze in neuer Arbeitsebene. Diese Gruppe kann " +"erstellt werden mit:\n" +"\n" +" * einem Punkt (durch den Punkt, orthogonal zu den Koordinatenachsen)\n" +" * einem Punkt und zwei Liniensegmenten (durch den Punkt, parallel zu den " +"Linien)\n" +" * einer Arbeitsebene (Kopie der Arbeitsebene)\n" + +#: group.cpp:154 +msgid "" +"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch " +"will be extruded normal to the workplane." +msgstr "" +"Aktivieren Sie vor der Extrusion eine Arbeitsebene (mit Skizze -> In " +"Arbeitsebene). Die Skizze wird senkrecht zur Arbeitsebene extrudiert" + +#: group.cpp:163 +msgctxt "group-name" +msgid "extrude" +msgstr "Extrusion" + +#: group.cpp:168 +msgid "Lathe operation can only be applied to planar sketches." +msgstr "Rotieren kann nur mit planaren Skizzen ausgeführt werden." + +#: group.cpp:179 +msgid "" +"Bad selection for new lathe group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" +"Ungültige Auswahl für neue Gruppe mit Drehquerschnitt. Diese Gruppe kann " +"erstellt werden mit:\n" +"\n" +" * einem Punkt und einem Liniensegment oder einer Normale (Drehung um " +"eine Achse parallel zur Linie/Normalen, durch den Punkt)\n" +" * einem Liniensegment (Drehung um das Liniensegment)\n" + +#: group.cpp:189 +msgctxt "group-name" +msgid "lathe" +msgstr "Drehung" + +#: group.cpp:194 +msgid "Revolve operation can only be applied to planar sketches." +msgstr "Revolve kann nur mit planaren Skizzen ausgeführt werden." + +#: group.cpp:205 +msgid "" +"Bad selection for new revolve group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" +"Ungültige Auswahl für eine neue Revolve Gruppe. Diese Gruppe kann erzeugt " +"werden mit:\n" +"\n" +" * einem Punkt und einem Liniensegment oder Normale (gedreht um eine " +"Achse parallel zu Linie / Normale, durch Punkt)\n" +" * einem Liniensegment (gedreht um Liniensegment)\n" + +#: group.cpp:217 +msgctxt "group-name" +msgid "revolve" +msgstr "Revolve" + +#: group.cpp:222 +msgid "Helix operation can only be applied to planar sketches." +msgstr "Helix kann nur mit planaren Skizzen ausgeführt werden." + +#: group.cpp:233 +msgid "" +"Bad selection for new helix group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" +"Ungültige Auswahl für eine neue Helix Gruppe. Diese Gruppe kann erzeugt " +"werden mit:\n" +"\n" +" * einem Punkt und einem Liniensegment oder Normale (gedreht um eine " +"Achse parallel zu Linie / Normale, durch Punkt)\n" +" * einem Liniensegment (gedreht um Liniensegment)\n" + +#: group.cpp:245 +msgctxt "group-name" +msgid "helix" +msgstr "Helix" + +#: group.cpp:258 +msgid "" +"Bad selection for new rotation. This group can be created with:\n" +"\n" +" * a point, while locked in workplane (rotate in plane, about that " +"point)\n" +" * a point and a line or a normal (rotate about an axis through the " +"point, and parallel to line / normal)\n" +msgstr "" +"Ungültige Auswahl für neue Rotation. Diese Gruppe kann erstellt werden mit:\n" +"\n" +" * einem Punkt in vorgegebener Arbeitsebene (gedreht in der Ebene um den " +"Punkt)\n" +" * einem Punkt und einer Linie oder einer Normale (gedreht um eine Achse " +"durch den Punkt, parallel zur Linie / Normale)\n" + +#: group.cpp:271 +msgctxt "group-name" +msgid "rotate" +msgstr "Drehen" + +#: group.cpp:282 +msgctxt "group-name" +msgid "translate" +msgstr "Versetzen" + +#: group.cpp:400 +msgid "(unnamed)" +msgstr "unbenannt" + +#: groupmesh.cpp:709 +msgid "not closed contour, or not all same style!" +msgstr "Kontur nicht geschlossen, oder kein einheitlicher Linientyp!" + +#: groupmesh.cpp:722 +msgid "points not all coplanar!" +msgstr "Punkte sind nicht alle koplanar!" + +#: groupmesh.cpp:724 +msgid "contour is self-intersecting!" +msgstr "Kontur überschneidet sich selbst!" + +#: groupmesh.cpp:726 +msgid "zero-length edge!" +msgstr "Kante mit Länge Null!" + +#: modify.cpp:254 +msgid "Must be sketching in workplane to create tangent arc." +msgstr "Eine Bogentangente kann nur in einer Arbeitsebene erstellt werden." + +#: modify.cpp:301 +msgid "" +"To create a tangent arc, select a point where two non-construction lines or " +"circles in this group and workplane join." +msgstr "" +"Um eine Bogentangente zu erstellen, wählen Sie einen Punkt, in dem sich zwei " +"nicht-Konstruktionslinien oder -kreise in dieser Gruppe und Arbeitsebene " +"treffen. " + +#: modify.cpp:388 +msgid "" +"Couldn't round this corner. Try a smaller radius, or try creating the " +"desired geometry by hand with tangency constraints." +msgstr "" +"Diese Ecke konnte nicht abgerundet werden. Versuchen Sie einen kleineren " +"Radius, oder erstellen Sie die gewünschte Geometrie von Hand mit \"Tangente" +"\"-Einschränkungen." + +#: modify.cpp:597 +msgid "Couldn't split this entity; lines, circles, or cubics only." +msgstr "" +"Dieses Objekt konnte nicht geteilt werden. Dies geht nur für Linien, Kreise " +"oder kubische Splines." + +#: modify.cpp:624 +msgid "Must be sketching in workplane to split." +msgstr "Trennen ist nur in einer Arbeitsebene möglich." + +#: modify.cpp:631 +msgid "" +"Select two entities that intersect each other (e.g. two lines/circles/arcs " +"or a line/circle/arc and a point)." +msgstr "" +"Wählen Sie zwei Objekte aus, die sich schneiden (z.B. zwei Linien/Kreise/" +"Bögen, oder eine Linie/Kreis/Bogen und ein Punkt)." + +#: modify.cpp:736 +msgid "Can't split; no intersection found." +msgstr "Trennen nicht möglich; keine Überschneidung gefunden." + +#: mouse.cpp:560 +msgid "Assign to Style" +msgstr "Linientyp zuordnen" + +#: mouse.cpp:576 +msgid "No Style" +msgstr "Kein Linientyp" + +#: mouse.cpp:579 +msgid "Newly Created Custom Style..." +msgstr "Neu erstellter benutzerdefinierter Linientyp…" + +#: mouse.cpp:586 +msgid "Group Info" +msgstr "Info zu Gruppe" + +#: mouse.cpp:606 +msgid "Style Info" +msgstr "Info zu Linientyp" + +#: mouse.cpp:626 +msgid "Select Edge Chain" +msgstr "Kantenverlauf auswählen" + +#: mouse.cpp:632 +msgid "Toggle Reference Dimension" +msgstr "Von/zu Referenzangabe wechseln" + +#: mouse.cpp:638 +msgid "Other Supplementary Angle" +msgstr "Anderer Komplementärwinkel" + +#: mouse.cpp:643 +msgid "Snap to Grid" +msgstr "Auf Raster ausrichten" + +#: mouse.cpp:652 +msgid "Remove Spline Point" +msgstr "Spline-Punkt löschen" + +#: mouse.cpp:687 +msgid "Add Spline Point" +msgstr "Spline-Punkt hinzufügen" + +#: mouse.cpp:691 +msgid "Cannot add spline point: maximum number of points reached." +msgstr "" +"Spline-Punkt kann nicht hinzugefügt werden: maximale Anzahl der Punkte " +"erreicht." + +#: mouse.cpp:716 +msgid "Toggle Construction" +msgstr "Konstruktionselement an/aus" + +#: mouse.cpp:731 +msgid "Delete Point-Coincident Constraint" +msgstr "Einschränkung \"Punkte deckungsgleich\" löschen" + +#: mouse.cpp:750 +msgid "Cut" +msgstr "Ausschneiden" + +#: mouse.cpp:752 +msgid "Copy" +msgstr "Kopieren" + +#: mouse.cpp:756 +msgid "Select All" +msgstr "Alle auswählen" + +#: mouse.cpp:761 +msgid "Paste" +msgstr "Einfügen" + +#: mouse.cpp:763 +msgid "Paste Transformed..." +msgstr "Einfügen und transformieren…" + +#: mouse.cpp:768 +msgid "Delete" +msgstr "Löschen" + +#: mouse.cpp:771 +msgid "Unselect All" +msgstr "Alle deselektieren" + +#: mouse.cpp:778 +msgid "Unselect Hovered" +msgstr "Aktive deselektieren" + +#: mouse.cpp:787 +msgid "Zoom to Fit" +msgstr "Zoom an Bildschirm anpassen" + +#: mouse.cpp:989 mouse.cpp:1276 +msgid "click next point of line, or press Esc" +msgstr "Klicken Sie auf den nächsten Punkt der Linie, oder drücken Sie Esc" + +#: mouse.cpp:995 +msgid "" +"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" +"Ein Rechteck kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine " +"Arbeitsebene mit \"Skizze -> In Arbeitsebene\"." + +#: mouse.cpp:1029 +msgid "click to place other corner of rectangle" +msgstr "Klicken Sie auf die gegenüberliegende Ecke des Rechtecks" + +#: mouse.cpp:1049 +msgid "click to set radius" +msgstr "Klicken Sie, um den Radius festzulegen" + +#: mouse.cpp:1054 +msgid "" +"Can't draw arc in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" +"Ein Kreisbogen kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine " +"Arbeitsebene mit \"Skizze -> In Arbeitsebene\"." + +#: mouse.cpp:1073 +msgid "click to place point" +msgstr "Klicken Sie, um einen Punkt zu platzieren" + +#: mouse.cpp:1089 +msgid "click next point of cubic, or press Esc" +msgstr "" +"Klicken Sie auf den nächsten Punkt der kubischen Linie, oder drücken Sie Esc" + +#: mouse.cpp:1094 +msgid "" +"Sketching in a workplane already; sketch in 3d before creating new workplane." +msgstr "" +"Eine Arbeitsebene ist bereits aktiv. Skizzieren Sie in 3D, bevor Sie eine " +"neue Arbeitsebene erstellen." + +#: mouse.cpp:1110 +msgid "" +"Can't draw text in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" +"Text kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine " +"Arbeitsebene mit \"Skizze -> In Arbeitsebene\"." + +#: mouse.cpp:1127 +msgid "click to place bottom right of text" +msgstr "Klicken Sie auf die untere rechte Ecke des Texts" + +#: mouse.cpp:1133 +msgid "" +"Can't draw image in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" +"Das Bild kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine " +"Arbeitsebene mit \"Skizze -> In Arbeitsebene\"." + +#: mouse.cpp:1160 +msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" +msgstr "NEUER KOMMENTAR -- DOPPELKLICKEN ZUM BEARBEITEN" + +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511 +msgctxt "file-type" +msgid "SolveSpace models" +msgstr "SolveSpace-Modelle" + +#: platform/gui.cpp:90 +msgctxt "file-type" +msgid "IDF circuit board" +msgstr "IDF Leiterplatte" + +#: platform/gui.cpp:94 +msgctxt "file-type" +msgid "PNG image" +msgstr "PNG-Datei" + +#: platform/gui.cpp:98 +msgctxt "file-type" +msgid "STL mesh" +msgstr "STL-Netz" + +#: platform/gui.cpp:99 +msgctxt "file-type" +msgid "Wavefront OBJ mesh" +msgstr "Wavefront OBJ-Netz" + +#: platform/gui.cpp:100 +msgctxt "file-type" +msgid "Three.js-compatible mesh, with viewer" +msgstr "Three.js-kompatibles Netz, mit Ansicht" + +#: platform/gui.cpp:101 +msgctxt "file-type" +msgid "Three.js-compatible mesh, mesh only" +msgstr "Three.js-kompatibles Netz, nur Netz" + +#: platform/gui.cpp:102 +msgctxt "file-type" +msgid "VRML text file" +msgstr "VRML Textdatei" + +#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 +msgctxt "file-type" +msgid "STEP file" +msgstr "STEP-Datei" + +#: platform/gui.cpp:110 +msgctxt "file-type" +msgid "PDF file" +msgstr "PDF-Datei" + +#: platform/gui.cpp:111 +msgctxt "file-type" +msgid "Encapsulated PostScript" +msgstr "Eingebettetes Postscript" + +#: platform/gui.cpp:112 +msgctxt "file-type" +msgid "Scalable Vector Graphics" +msgstr "Skalierbare Vektorgrafik" + +#: platform/gui.cpp:114 platform/gui.cpp:121 +msgctxt "file-type" +msgid "DXF file (AutoCAD 2007)" +msgstr "DXF-Datei (AutoCAD 2007)" + +#: platform/gui.cpp:115 +msgctxt "file-type" +msgid "HPGL file" +msgstr "HPGL-Datei" + +#: platform/gui.cpp:116 +msgctxt "file-type" +msgid "G Code" +msgstr "G-Code" + +#: platform/gui.cpp:125 +msgctxt "file-type" +msgid "AutoCAD DXF and DWG files" +msgstr "AutoCAD DXF- und DWG-Dateien" + +#: platform/gui.cpp:129 +msgctxt "file-type" +msgid "Comma-separated values" +msgstr "Werte durch Komma getrennt (CSV)" + +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 +msgid "untitled" +msgstr "unbenannt" + +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1573 +msgctxt "title" +msgid "Save File" +msgstr "Datei speichern" + +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1575 +msgctxt "title" +msgid "Open File" +msgstr "Datei öffnen" + +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 +msgctxt "button" +msgid "_Cancel" +msgstr "_Abbrechen" + +#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 +msgctxt "button" +msgid "_Save" +msgstr "_Speichern" + +#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 +msgctxt "button" +msgid "_Open" +msgstr "_Öffnen" + +#: solvespace.cpp:169 +msgctxt "title" +msgid "Autosave Available" +msgstr "Automatische Sicherungsdatei verfügbar" + +#: solvespace.cpp:170 +msgctxt "dialog" +msgid "An autosave file is available for this sketch." +msgstr "Eine automatische Sicherung ist für diese Skizze verfügbar." + +#: solvespace.cpp:171 +msgctxt "dialog" +msgid "Do you want to load the autosave file instead?" +msgstr "Wollen Sie die automatische Sicherungsdatei stattdessen laden?" + +#: solvespace.cpp:172 +msgctxt "button" +msgid "&Load autosave" +msgstr "AutoDatei &öffnen" + +#: solvespace.cpp:174 +msgctxt "button" +msgid "Do&n't Load" +msgstr "&Nicht laden" + +#: solvespace.cpp:557 +msgctxt "title" +msgid "Modified File" +msgstr "Geänderte Datei" + +#: solvespace.cpp:559 +#, c-format +msgctxt "dialog" +msgid "Do you want to save the changes you made to the sketch “%s”?" +msgstr "Wollen Sie die Änderungen an der Skizze “%s” sichern?" + +#: solvespace.cpp:562 +msgctxt "dialog" +msgid "Do you want to save the changes you made to the new sketch?" +msgstr "Wollen Sie die Änderungen an der Skizze sichern?" + +#: solvespace.cpp:565 +msgctxt "dialog" +msgid "Your changes will be lost if you don't save them." +msgstr "Ihre Änderungen werden verworfen, wenn sie nicht abgespeichert werden." + +#: solvespace.cpp:566 +msgctxt "button" +msgid "&Save" +msgstr "&Sichern" + +#: solvespace.cpp:568 +msgctxt "button" +msgid "Do&n't Save" +msgstr "&Verwerfen" + +# solvespace.cpp:557 +#: solvespace.cpp:589 +msgctxt "title" +msgid "(new sketch)" +msgstr "(Neue Skizze)" + +#: solvespace.cpp:596 +msgctxt "title" +msgid "Property Browser" +msgstr "Attribut-Browser" + +#: solvespace.cpp:658 +msgid "" +"Constraints are currently shown, and will be exported in the toolpath. This " +"is probably not what you want; hide them by clicking the link at the top of " +"the text window." +msgstr "" +"Einschränkungen sind momentan sichtbar und werden exportiert. Das wollen Sie " +"wahrscheinlich nicht. Verstecken Sie sie in dem auf den Link oben im " +"Textfenster klicken." + +#: solvespace.cpp:730 +#, c-format +msgid "" +"Can't identify file type from file extension of filename '%s'; try .dxf or ." +"dwg." +msgstr "" +"Kann den Dateityp der Datei '%s' nicht auf Grund der Dateierweiterung " +"erkennen. Versuchen Sie .dxf oder .dwg." + +#: solvespace.cpp:778 +msgid "Constraint must have a label, and must not be a reference dimension." +msgstr "" +"Die Einschränkung muss einen Namen haben, und darf keine " +"Referenzdimensionierung sein." + +#: solvespace.cpp:782 +msgid "Bad selection for step dimension; select a constraint." +msgstr "" +"Falsche Auswahl für die Schrittdimensionierung. Wählen Sie eine " +"Einschränkung." + +#: solvespace.cpp:806 +msgid "The assembly does not interfere, good." +msgstr "Der Zusammenbau funktioniert, gut." + +#: solvespace.cpp:822 +#, c-format +msgid "" +"The volume of the solid model is:\n" +"\n" +" %s" +msgstr "" +"Das Volumen des Modell ist:\n" +"\n" +" %s" + +#: solvespace.cpp:831 +#, c-format +msgid "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" +msgstr "" +"\n" +"Das Volumen des Netz der aktiven Gruppe ist:\n" +"\n" +" %s" + +#: solvespace.cpp:836 +msgid "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." +msgstr "" +"\n" +"\n" +"Gekrümmte Flächen wurden als Dreiecksnetz angenähert.\n" +"Das verursacht Fehler, typischerweise um 1%." + +#: solvespace.cpp:851 +#, c-format +msgid "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" +"Die Fläche der ausgewählten Flächen ist:\n" +"\n" +" %s\n" +"\n" +"Kurven wurden als gerade Linienstücke angenähert.\n" +"Das verursacht Fehler, typischerweise um 1%%." + +#: solvespace.cpp:860 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." +msgstr "" +"Diese Gruppe beinhaltet keine korrekt geschlossene 2D Fläche. Sie ist offen, " +"nicht koplanar, oder überschneidet sich selbst." + +#: solvespace.cpp:872 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" +"Die Summe der Flächen in dieser Gruppe ist:\n" +"\n" +" %s\n" +"\n" +"Kurven wurden als gerade Linienstücke angenähert.\n" +"Das verursacht Fehler, typischerweise um 1%%." + +#: solvespace.cpp:892 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" +"Die Gesamtlänge der ausgwählten Elemente ist:\n" +"\n" +" %s\n" +"\n" +"Kurven wurden als gerade Linienstücke angenähert.\n" +"Das verursacht Fehler, typischerweise um 1%%." + +#: solvespace.cpp:898 +msgid "Bad selection for perimeter; select line segments, arcs, and curves." +msgstr "Falsche Auswahl für Umfang. Wähle Liniensegmente, Bögen und Kurven." + +#: solvespace.cpp:914 +msgid "Bad selection for trace; select a single point." +msgstr "Falsche Auswahl für Punkt nachzeichnen. Wähle einen einzelnen Punkt." + +#: solvespace.cpp:941 +#, c-format +msgid "Couldn't write to '%s'" +msgstr "Konnte '%s' nicht schreiben" + +#: solvespace.cpp:971 +msgid "The mesh is self-intersecting (NOT okay, invalid)." +msgstr "Das Netz schneidet sich selbst: Falsch, ungültig." + +#: solvespace.cpp:972 +msgid "The mesh is not self-intersecting (okay, valid)." +msgstr "Das Netz schneidet sich nicht: Gut, gültig." + +#: solvespace.cpp:974 +msgid "The mesh has naked edges (NOT okay, invalid)." +msgstr "Das Netz hat lose Kanten: Falsch, ungültig." + +#: solvespace.cpp:975 +msgid "The mesh is watertight (okay, valid)." +msgstr "Das Netz hat keine lose Kanten: Gut, gültig." + +#: solvespace.cpp:978 +#, c-format +msgid "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." +msgstr "" +"\n" +"\n" +"Das Modell hat %d Dreiecke, von %d Flächen." + +#: solvespace.cpp:982 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" +"%s\n" +"\n" +"%s\n" +"\n" +"Keine problematischen Kanten, gut.%s" + +#: solvespace.cpp:985 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematische Kanten, schlecht.%s" + +#: solvespace.cpp:998 +#, c-format +msgid "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" +msgstr "" +"Das ist SolveSpace version %s.\n" +"\n" +"Für mehr Information siehe http://solvespace.com/\n" +"\n" +"SolveSpace ist freie Software: Sie steht Ihnen frei sie zu ändern\n" +"und/oder zu vervielfältigen unter der Auflage der GNU\n" +"General Public License (GPL) Version 3 oder späterer Versionen.\n" +"\n" +"Es besteht keinerlei Gewährleistung und Haftung für das Programm, soweit " +"dies gesetzlich zulässig ist.\n" +"Für Details siehe http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues und andere.\n" + +#: style.cpp:166 +msgid "" +"Can't assign style to an entity that's derived from another entity; try " +"assigning a style to this entity's parent." +msgstr "" +"Ein Linientyp kann keinem Objekt zugeordnet werden, das von einem anderen " +"Objekt abgeleitet wurde. Versuchen Sie, dem übergeordneten Objekt einen Typ " +"zuzuordnen." + +#: style.cpp:665 +msgid "Style name cannot be empty" +msgstr "Name des Linientyps kann nicht leer sein." + +#: textscreens.cpp:741 +msgid "Can't repeat fewer than 1 time." +msgstr "Nicht weniger als 1 Wiederholung möglich." + +#: textscreens.cpp:745 +msgid "Can't repeat more than 999 times." +msgstr "Nicht mehr als 999 Wiederholungen möglich." + +#: textscreens.cpp:770 +msgid "Group name cannot be empty" +msgstr "Der Name der Gruppe darf nicht leer sein." + +#: textscreens.cpp:813 +msgid "Opacity must be between zero and one." +msgstr "Durchsichtigkeit muss zwischen Null und Eins sein." + +#: textscreens.cpp:848 +msgid "Radius cannot be zero or negative." +msgstr "Radius darf nicht null oder negativ sein." + +#: toolbar.cpp:18 +msgid "Sketch line segment" +msgstr "Liniensegment erstellen" + +#: toolbar.cpp:20 +msgid "Sketch rectangle" +msgstr "Rechteck erstellen" + +#: toolbar.cpp:22 +msgid "Sketch circle" +msgstr "Kreis erstellen" + +#: toolbar.cpp:24 +msgid "Sketch arc of a circle" +msgstr "Kreisbogen erstellen" + +#: toolbar.cpp:26 +msgid "Sketch curves from text in a TrueType font" +msgstr "Kurven aus Text in einem TrueType-Font erzeugen" + +#: toolbar.cpp:28 +msgid "Sketch image from a file" +msgstr "Skizze von einer Bilddatei erstellen" + +#: toolbar.cpp:30 +msgid "Create tangent arc at selected point" +msgstr "Bogentangente im ausgewählten Punkt erstellen" + +#: toolbar.cpp:32 +msgid "Sketch cubic Bezier spline" +msgstr "Kubischen Bezier-Spline erstellen" + +#: toolbar.cpp:34 +msgid "Sketch datum point" +msgstr "Bezugspunkt erstellen" + +#: toolbar.cpp:36 +msgid "Toggle construction" +msgstr "Konstruktionselement an/aus" + +#: toolbar.cpp:38 +msgid "Split lines / curves where they intersect" +msgstr "Linien / Kurven im Schnittpunkt trennen" + +#: toolbar.cpp:42 +msgid "Constrain distance / diameter / length" +msgstr "Abstand / Durchmesser / Länge einschränken" + +#: toolbar.cpp:44 +msgid "Constrain angle" +msgstr "Winkel einschränken" + +#: toolbar.cpp:46 +msgid "Constrain to be horizontal" +msgstr "Horizontale Einschränkung" + +#: toolbar.cpp:48 +msgid "Constrain to be vertical" +msgstr "Vertikale Einschränkung" + +#: toolbar.cpp:50 +msgid "Constrain to be parallel or tangent" +msgstr "Einschränkung auf Parallele oder Tangente" + +#: toolbar.cpp:52 +msgid "Constrain to be perpendicular" +msgstr "Rechtwinklige Einschränkung" + +#: toolbar.cpp:54 +msgid "Constrain point on line / curve / plane / point" +msgstr "Punkt auf Linie / Kurve / Ebene / Punkt einschränken" + +#: toolbar.cpp:56 +msgid "Constrain symmetric" +msgstr "Symmetrische Einschränkung" + +#: toolbar.cpp:58 +msgid "Constrain equal length / radius / angle" +msgstr "Gleiche Länge / Radius / Winkel einschränken" + +#: toolbar.cpp:60 +msgid "Constrain normals in same orientation" +msgstr "Normale auf gleiche Richtung einschränken" + +#: toolbar.cpp:62 +msgid "Other supplementary angle" +msgstr "Anderer Komplementärwinkel" + +#: toolbar.cpp:64 +msgid "Toggle reference dimension" +msgstr "Von/zu Referenzangabe wechseln" + +#: toolbar.cpp:68 +msgid "New group extruding active sketch" +msgstr "Neue Gruppe mit extrudierter aktiver Skizze" + +#: toolbar.cpp:70 +msgid "New group rotating active sketch" +msgstr "Neue Gruppe mit rotierter aktiver Skizze" + +#: toolbar.cpp:72 +msgid "New group helix from active sketch" +msgstr "Neue Gruppe Helix von aktiver Skizze" + +#: toolbar.cpp:74 +msgid "New group revolve active sketch" +msgstr "Neue Gruppe mit gedrehter aktiver Skizze" + +#: toolbar.cpp:76 +msgid "New group step and repeat rotating" +msgstr "Neue Gruppe mit kopierter gedrehter Skizze" + +#: toolbar.cpp:78 +msgid "New group step and repeat translating" +msgstr "Neue Gruppe mit kopierter versetzter Skizze" + +#: toolbar.cpp:80 +msgid "New group in new workplane (thru given entities)" +msgstr "" +"Neue Gruppe in neuer Arbeitsebene (definiert durch ausgewählte Objekte)" + +#: toolbar.cpp:82 +msgid "New group in 3d" +msgstr "Neue Gruppe in 3D" + +#: toolbar.cpp:84 +msgid "New group linking / assembling file" +msgstr "Neue Gruppe mit verknüpfter Datei" + +#: toolbar.cpp:88 +msgid "Nearest isometric view" +msgstr "Nächste isometrische Ansicht" + +#: toolbar.cpp:90 +msgid "Align view to active workplane" +msgstr "Ansicht auf Arbeitsebene ausrichten" + +#: util.cpp:165 +msgctxt "title" +msgid "Error" +msgstr "Fehler" + +#: util.cpp:165 +msgctxt "title" +msgid "Message" +msgstr "Mitteilung" + +#: util.cpp:170 +msgctxt "button" +msgid "&OK" +msgstr "&OK" + +#: view.cpp:78 +msgid "Scale cannot be zero or negative." +msgstr "Der Maßstab kann nicht Null oder negativ sein." + +#: view.cpp:90 view.cpp:99 +msgid "Bad format: specify x, y, z" +msgstr "Ungültiges Format: geben Sie x, y, z ein" + +#~ msgctxt "file-type" +#~ msgid "Q3D Object file" +#~ msgstr "Q3D Objektdatei" + +#~ msgid "Specify between 0 and 8 digits after the decimal." +#~ msgstr "Geben Sie 0 bis 8 Ziffern nach dem Dezimalzeichen an." + +#~ msgid "click to place bottom left of text" +#~ msgstr "Klicken Sie auf die untere linke Ecke des Texts" + +#~ msgid "Do you want to save the changes you made to the new sketch?" +#~ msgstr "Möchten Sie die Änderungen in Ihrer Skizze speichern?" + +#~ msgid "Your changes will be lost if you don't save them." +#~ msgstr "" +#~ "Ihre Änderungen werden verworfen, wenn sie nicht abgespeichert werden." + +#~ msgctxt "button" +#~ msgid "Save" +#~ msgstr "Speichern" + +#~ msgctxt "button" +#~ msgid "Cancel" +#~ msgstr "Abbrechen" + +#~ msgctxt "button" +#~ msgid "Don't Save" +#~ msgstr "Nicht speichern" + +#~ msgid "An autosave file is available for this project." +#~ msgstr "" +#~ "Eine automatisch gespeicherte Datei ist für dieses Projekt vorhanden." + +#~ msgid "Do you want to load the autosave file instead?" +#~ msgstr "Möchten Sie die automatische Speicherdatei stattdessen öffnen?" + +#~ msgctxt "button" +#~ msgid "Load" +#~ msgstr "Öffnen" + +#~ msgctxt "button" +#~ msgid "Don't Load" +#~ msgstr "Nicht öffnen" + +#~ msgid "" +#~ "Do you want to locate it manually?\n" +#~ "If you select “No”, any geometry that depends on the missing file will be " +#~ "removed." +#~ msgstr "" +#~ "Möchten Sie sie selber auswählen?\n" +#~ "Falls Sie \"Nein\" wählen, wird jegliche mit der fehlenden Datei " +#~ "verknüpfte Geometrie verworfen." + +#~ msgctxt "button" +#~ msgid "Yes" +#~ msgstr "Ja" + +#~ msgctxt "button" +#~ msgid "No" +#~ msgstr "Nein" + +#~ msgctxt "button" +#~ msgid "OK" +#~ msgstr "OK" + +#~ msgid "_Cancel" +#~ msgstr "_Abbrechen" + +#~ msgid "_Open" +#~ msgstr "_Öffnen" + +#~ msgid "" +#~ "The file has changed since it was last saved.\n" +#~ "\n" +#~ "Do you want to save the changes?" +#~ msgstr "" +#~ "Die Datei wurde seit der letzten Speicherung geändert.\n" +#~ "\n" +#~ "Möchten Sie die Änderungen speichern?" + +#~ msgctxt "button" +#~ msgid "Do_n't Save" +#~ msgstr "Nicht speichern" + +#~ msgid "" +#~ "An autosave file is available for this project.\n" +#~ "\n" +#~ "Do you want to load the autosave file instead?" +#~ msgstr "" +#~ "Eine automatisch gespeicherte Datei ist für dieses Projekt vorhanden.\n" +#~ "\n" +#~ "Wollen Sie die automatisch gespeicherte Datei öffnen?" + +#~ msgctxt "button" +#~ msgid "_Load autosave" +#~ msgstr "AutoDatei öffnen" + +#~ msgctxt "button" +#~ msgid "Do_n't Load" +#~ msgstr "Nicht öffnen" + +#~ msgctxt "button" +#~ msgid "_Yes" +#~ msgstr "_Ja" + +#~ msgctxt "button" +#~ msgid "_No" +#~ msgstr "_Nein" diff --git a/res/locales/en_US.po b/res/locales/en_US.po new file mode 100644 index 0000000..e7acd7e --- /dev/null +++ b/res/locales/en_US.po @@ -0,0 +1,2171 @@ +# English translations for SolveSpace package. +# Copyright (C) 2017 the SolveSpace authors +# This file is distributed under the same license as the SolveSpace package. +# Automatically generated, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: SolveSpace 3.0\n" +"Report-Msgid-Bugs-To: whitequark@whitequark.org\n" +"POT-Creation-Date: 2021-01-17 19:54+0200\n" +"PO-Revision-Date: 2017-01-05 10:30+0000\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: clipboard.cpp:310 +msgid "" +"Cut, paste, and copy work only in a workplane.\n" +"\n" +"Activate one with Sketch -> In Workplane." +msgstr "" +"Cut, paste, and copy work only in a workplane.\n" +"\n" +"Activate one with Sketch -> In Workplane." + +#: clipboard.cpp:327 +msgid "Clipboard is empty; nothing to paste." +msgstr "Clipboard is empty; nothing to paste." + +#: clipboard.cpp:374 +msgid "Number of copies to paste must be at least one." +msgstr "Number of copies to paste must be at least one." + +#: clipboard.cpp:390 textscreens.cpp:783 +msgid "Scale cannot be zero." +msgstr "Scale cannot be zero." + +#: clipboard.cpp:432 +msgid "Select one point to define origin of rotation." +msgstr "Select one point to define origin of rotation." + +#: clipboard.cpp:444 +msgid "Select two points to define translation vector." +msgstr "Select two points to define translation vector." + +#: clipboard.cpp:454 +msgid "" +"Transformation is identity. So all copies will be exactly on top of each " +"other." +msgstr "" +"Transformation is identity. So all copies will be exactly on top of each " +"other." + +#: clipboard.cpp:458 +msgid "Too many items to paste; split this into smaller pastes." +msgstr "Too many items to paste; split this into smaller pastes." + +#: clipboard.cpp:463 +msgid "No workplane active." +msgstr "No workplane active." + +#: confscreen.cpp:418 +msgid "Bad format: specify coordinates as x, y, z" +msgstr "Bad format: specify coordinates as x, y, z" + +#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805 +msgid "Bad format: specify color as r, g, b" +msgstr "Bad format: specify color as r, g, b" + +#: confscreen.cpp:454 +msgid "" +"The perspective factor will have no effect until you enable View -> Use " +"Perspective Projection." +msgstr "" +"The perspective factor will have no effect until you enable View -> Use " +"Perspective Projection." + +#: confscreen.cpp:467 confscreen.cpp:477 +#, c-format +msgid "Specify between 0 and %d digits after the decimal." +msgstr "Specify between 0 and %d digits after the decimal." + +#: confscreen.cpp:489 +msgid "Export scale must not be zero!" +msgstr "Export scale must not be zero!" + +#: confscreen.cpp:501 +msgid "Cutter radius offset must not be negative!" +msgstr "Cutter radius offset must not be negative!" + +#: confscreen.cpp:555 +msgid "Bad value: autosave interval should be positive" +msgstr "Bad value: autosave interval should be positive" + +#: confscreen.cpp:558 +msgid "Bad format: specify interval in integral minutes" +msgstr "Bad format: specify interval in integral minutes" + +#: constraint.cpp:12 +msgctxt "constr-name" +msgid "pts-coincident" +msgstr "pts-coincident" + +#: constraint.cpp:13 +msgctxt "constr-name" +msgid "pt-pt-distance" +msgstr "pt-pt-distance" + +#: constraint.cpp:14 +msgctxt "constr-name" +msgid "pt-line-distance" +msgstr "pt-line-distance" + +#: constraint.cpp:15 +msgctxt "constr-name" +msgid "pt-plane-distance" +msgstr "pt-plane-distance" + +#: constraint.cpp:16 +msgctxt "constr-name" +msgid "pt-face-distance" +msgstr "pt-face-distance" + +#: constraint.cpp:17 +msgctxt "constr-name" +msgid "proj-pt-pt-distance" +msgstr "proj-pt-pt-distance" + +#: constraint.cpp:18 +msgctxt "constr-name" +msgid "pt-in-plane" +msgstr "pt-in-plane" + +#: constraint.cpp:19 +msgctxt "constr-name" +msgid "pt-on-line" +msgstr "pt-on-line" + +#: constraint.cpp:20 +msgctxt "constr-name" +msgid "pt-on-face" +msgstr "pt-on-face" + +#: constraint.cpp:21 +msgctxt "constr-name" +msgid "eq-length" +msgstr "eq-length" + +#: constraint.cpp:22 +msgctxt "constr-name" +msgid "eq-length-and-pt-ln-dist" +msgstr "eq-length-and-pt-ln-dist" + +#: constraint.cpp:23 +msgctxt "constr-name" +msgid "eq-pt-line-distances" +msgstr "eq-pt-line-distances" + +#: constraint.cpp:24 +msgctxt "constr-name" +msgid "length-ratio" +msgstr "length-ratio" + +#: constraint.cpp:25 +msgctxt "constr-name" +msgid "length-difference" +msgstr "length-difference" + +#: constraint.cpp:26 +msgctxt "constr-name" +msgid "symmetric" +msgstr "symmetric" + +#: constraint.cpp:27 +msgctxt "constr-name" +msgid "symmetric-h" +msgstr "symmetric-h" + +#: constraint.cpp:28 +msgctxt "constr-name" +msgid "symmetric-v" +msgstr "symmetric-v" + +#: constraint.cpp:29 +msgctxt "constr-name" +msgid "symmetric-line" +msgstr "symmetric-line" + +#: constraint.cpp:30 +msgctxt "constr-name" +msgid "at-midpoint" +msgstr "at-midpoint" + +#: constraint.cpp:31 +msgctxt "constr-name" +msgid "horizontal" +msgstr "horizontal" + +#: constraint.cpp:32 +msgctxt "constr-name" +msgid "vertical" +msgstr "vertical" + +#: constraint.cpp:33 +msgctxt "constr-name" +msgid "diameter" +msgstr "diameter" + +#: constraint.cpp:34 +msgctxt "constr-name" +msgid "pt-on-circle" +msgstr "pt-on-circle" + +#: constraint.cpp:35 +msgctxt "constr-name" +msgid "same-orientation" +msgstr "same-orientation" + +#: constraint.cpp:36 +msgctxt "constr-name" +msgid "angle" +msgstr "angle" + +#: constraint.cpp:37 +msgctxt "constr-name" +msgid "parallel" +msgstr "parallel" + +#: constraint.cpp:38 +msgctxt "constr-name" +msgid "arc-line-tangent" +msgstr "arc-line-tangent" + +#: constraint.cpp:39 +msgctxt "constr-name" +msgid "cubic-line-tangent" +msgstr "cubic-line-tangent" + +#: constraint.cpp:40 +msgctxt "constr-name" +msgid "curve-curve-tangent" +msgstr "curve-curve-tangent" + +#: constraint.cpp:41 +msgctxt "constr-name" +msgid "perpendicular" +msgstr "perpendicular" + +#: constraint.cpp:42 +msgctxt "constr-name" +msgid "eq-radius" +msgstr "eq-radius" + +#: constraint.cpp:43 +msgctxt "constr-name" +msgid "eq-angle" +msgstr "eq-angle" + +#: constraint.cpp:44 +msgctxt "constr-name" +msgid "eq-line-len-arc-len" +msgstr "eq-line-len-arc-len" + +#: constraint.cpp:45 +msgctxt "constr-name" +msgid "lock-where-dragged" +msgstr "lock-where-dragged" + +#: constraint.cpp:46 +msgctxt "constr-name" +msgid "comment" +msgstr "comment" + +#: constraint.cpp:140 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." +msgstr "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." + +#: constraint.cpp:158 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." +msgstr "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." + +#: constraint.cpp:183 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." +msgstr "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." + +#: constraint.cpp:231 +msgid "" +"Bad selection for distance / diameter constraint. This constraint can apply " +"to:\n" +"\n" +" * two points (distance between points)\n" +" * a line segment (length)\n" +" * two points and a line segment or normal (projected distance)\n" +" * a workplane and a point (minimum distance)\n" +" * a line segment and a point (minimum distance)\n" +" * a plane face and a point (minimum distance)\n" +" * a circle or an arc (diameter)\n" +msgstr "" +"Bad selection for distance / diameter constraint. This constraint can apply " +"to:\n" +"\n" +" * two points (distance between points)\n" +" * a line segment (length)\n" +" * two points and a line segment or normal (projected distance)\n" +" * a workplane and a point (minimum distance)\n" +" * a line segment and a point (minimum distance)\n" +" * a plane face and a point (minimum distance)\n" +" * a circle or an arc (diameter)\n" + +#: constraint.cpp:284 +msgid "" +"Bad selection for on point / curve / plane constraint. This constraint can " +"apply to:\n" +"\n" +" * two points (points coincident)\n" +" * a point and a workplane (point in plane)\n" +" * a point and a line segment (point on line)\n" +" * a point and a circle or arc (point on curve)\n" +" * a point and a plane face (point on face)\n" +msgstr "" +"Bad selection for on point / curve / plane constraint. This constraint can " +"apply to:\n" +"\n" +" * two points (points coincident)\n" +" * a point and a workplane (point in plane)\n" +" * a point and a line segment (point on line)\n" +" * a point and a circle or arc (point on curve)\n" +" * a point and a plane face (point on face)\n" + +#: constraint.cpp:346 +msgid "" +"Bad selection for equal length / radius constraint. This constraint can " +"apply to:\n" +"\n" +" * two line segments (equal length)\n" +" * two line segments and two points (equal point-line distances)\n" +" * a line segment and two points (equal point-line distances)\n" +" * a line segment, and a point and line segment (point-line distance " +"equals length)\n" +" * four line segments or normals (equal angle between A,B and C,D)\n" +" * three line segments or normals (equal angle between A,B and B,C)\n" +" * two circles or arcs (equal radius)\n" +" * a line segment and an arc (line segment length equals arc length)\n" +msgstr "" +"Bad selection for equal length / radius constraint. This constraint can " +"apply to:\n" +"\n" +" * two line segments (equal length)\n" +" * two line segments and two points (equal point-line distances)\n" +" * a line segment and two points (equal point-line distances)\n" +" * a line segment, and a point and line segment (point-line distance " +"equals length)\n" +" * four line segments or normals (equal angle between A,B and C,D)\n" +" * three line segments or normals (equal angle between A,B and B,C)\n" +" * two circles or arcs (equal radius)\n" +" * a line segment and an arc (line segment length equals arc length)\n" + +#: constraint.cpp:385 +msgid "" +"Bad selection for length ratio constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +msgstr "" +"Bad selection for length ratio constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" + +#: constraint.cpp:402 +msgid "" +"Bad selection for length difference constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments\n" +msgstr "" +"Bad selection for length difference constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments\n" + +#: constraint.cpp:428 +msgid "" +"Bad selection for at midpoint constraint. This constraint can apply to:\n" +"\n" +" * a line segment and a point (point at midpoint)\n" +" * a line segment and a workplane (line's midpoint on plane)\n" +msgstr "" +"Bad selection for at midpoint constraint. This constraint can apply to:\n" +"\n" +" * a line segment and a point (point at midpoint)\n" +" * a line segment and a workplane (line's midpoint on plane)\n" + +#: constraint.cpp:486 +msgid "" +"Bad selection for symmetric constraint. This constraint can apply to:\n" +"\n" +" * two points or a line segment (symmetric about workplane's coordinate " +"axis)\n" +" * line segment, and two points or a line segment (symmetric about line " +"segment)\n" +" * workplane, and two points or a line segment (symmetric about " +"workplane)\n" +msgstr "" +"Bad selection for symmetric constraint. This constraint can apply to:\n" +"\n" +" * two points or a line segment (symmetric about workplane's coordinate " +"axis)\n" +" * line segment, and two points or a line segment (symmetric about line " +"segment)\n" +" * workplane, and two points or a line segment (symmetric about " +"workplane)\n" + +#: constraint.cpp:500 +msgid "" +"A workplane must be active when constraining symmetric without an explicit " +"symmetry plane." +msgstr "" +"A workplane must be active when constraining symmetric without an explicit " +"symmetry plane." + +#: constraint.cpp:530 +msgid "" +"Activate a workplane (with Sketch -> In Workplane) before applying a " +"horizontal or vertical constraint." +msgstr "" +"Activate a workplane (with Sketch -> In Workplane) before applying a " +"horizontal or vertical constraint." + +#: constraint.cpp:543 +msgid "" +"Bad selection for horizontal / vertical constraint. This constraint can " +"apply to:\n" +"\n" +" * two points\n" +" * a line segment\n" +msgstr "" +"Bad selection for horizontal / vertical constraint. This constraint can " +"apply to:\n" +"\n" +" * two points\n" +" * a line segment\n" + +#: constraint.cpp:564 +msgid "" +"Bad selection for same orientation constraint. This constraint can apply " +"to:\n" +"\n" +" * two normals\n" +msgstr "" +"Bad selection for same orientation constraint. This constraint can apply " +"to:\n" +"\n" +" * two normals\n" + +#: constraint.cpp:614 +msgid "Must select an angle constraint." +msgstr "Must select an angle constraint." + +#: constraint.cpp:627 +msgid "Must select a constraint with associated label." +msgstr "Must select a constraint with associated label." + +#: constraint.cpp:638 +msgid "" +"Bad selection for angle constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" +"Bad selection for angle constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" + +#: constraint.cpp:701 +msgid "Curve-curve tangency must apply in workplane." +msgstr "Curve-curve tangency must apply in workplane." + +#: constraint.cpp:711 +msgid "" +"Bad selection for parallel / tangent constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments (parallel)\n" +" * a line segment and a normal (parallel)\n" +" * two normals (parallel)\n" +" * two line segments, arcs, or beziers, that share an endpoint (tangent)\n" +msgstr "" +"Bad selection for parallel / tangent constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments (parallel)\n" +" * a line segment and a normal (parallel)\n" +" * two normals (parallel)\n" +" * two line segments, arcs, or beziers, that share an endpoint (tangent)\n" + +#: constraint.cpp:729 +msgid "" +"Bad selection for perpendicular constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" +"Bad selection for perpendicular constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" + +#: constraint.cpp:744 +msgid "" +"Bad selection for lock point where dragged constraint. This constraint can " +"apply to:\n" +"\n" +" * a point\n" +msgstr "" +"Bad selection for lock point where dragged constraint. This constraint can " +"apply to:\n" +"\n" +" * a point\n" + +#: constraint.cpp:755 +msgid "click center of comment text" +msgstr "click center of comment text" + +#: export.cpp:19 +msgid "" +"No solid model present; draw one with extrudes and revolves, or use Export " +"2d View to export bare lines and curves." +msgstr "" +"No solid model present; draw one with extrudes and revolves, or use Export " +"2d View to export bare lines and curves." + +#: export.cpp:61 +msgid "" +"Bad selection for export section. Please select:\n" +"\n" +" * nothing, with an active workplane (workplane is section plane)\n" +" * a face (section plane through face)\n" +" * a point and two line segments (plane through point and parallel to " +"lines)\n" +msgstr "" +"Bad selection for export section. Please select:\n" +"\n" +" * nothing, with an active workplane (workplane is section plane)\n" +" * a face (section plane through face)\n" +" * a point and two line segments (plane through point and parallel to " +"lines)\n" + +#: export.cpp:822 +msgid "Active group mesh is empty; nothing to export." +msgstr "Active group mesh is empty; nothing to export." + +#: exportvector.cpp:337 +msgid "freehand lines were replaced with continuous lines" +msgstr "freehand lines were replaced with continuous lines" + +#: exportvector.cpp:339 +msgid "zigzag lines were replaced with continuous lines" +msgstr "zigzag lines were replaced with continuous lines" + +#: exportvector.cpp:593 +msgid "" +"Some aspects of the drawing have no DXF equivalent and were not exported:\n" +msgstr "" +"Some aspects of the drawing have no DXF equivalent and were not exported:\n" + +#: exportvector.cpp:839 +msgid "" +"PDF page size exceeds 200 by 200 inches; many viewers may reject this file." +msgstr "" +"PDF page size exceeds 200 by 200 inches; many viewers may reject this file." + +#: file.cpp:44 group.cpp:91 +msgctxt "group-name" +msgid "sketch-in-plane" +msgstr "sketch-in-plane" + +#: file.cpp:62 +msgctxt "group-name" +msgid "#references" +msgstr "#references" + +#: file.cpp:549 +msgid "" +"Unrecognized data in file. This file may be corrupt, or from a newer version " +"of the program." +msgstr "" +"Unrecognized data in file. This file may be corrupt, or from a newer version " +"of the program." + +#: file.cpp:859 +msgctxt "title" +msgid "Missing File" +msgstr "Missing File" + +#: file.cpp:860 +#, c-format +msgctxt "dialog" +msgid "The linked file “%s” is not present." +msgstr "The linked file “%s” is not present." + +#: file.cpp:862 +msgctxt "dialog" +msgid "" +"Do you want to locate it manually?\n" +"\n" +"If you decline, any geometry that depends on the missing file will be " +"permanently removed." +msgstr "" +"Do you want to locate it manually?\n" +"\n" +"If you decline, any geometry that depends on the missing file will be " +"permanently removed." + +#: file.cpp:865 +msgctxt "button" +msgid "&Yes" +msgstr "&Yes" + +#: file.cpp:867 +msgctxt "button" +msgid "&No" +msgstr "&No" + +#: file.cpp:869 solvespace.cpp:569 +msgctxt "button" +msgid "&Cancel" +msgstr "&Cancel" + +#: graphicswin.cpp:41 +msgid "&File" +msgstr "&File" + +#: graphicswin.cpp:42 +msgid "&New" +msgstr "&New" + +#: graphicswin.cpp:43 +msgid "&Open..." +msgstr "&Open..." + +#: graphicswin.cpp:44 +msgid "Open &Recent" +msgstr "Open &Recent" + +#: graphicswin.cpp:45 +msgid "&Save" +msgstr "&Save" + +#: graphicswin.cpp:46 +msgid "Save &As..." +msgstr "Save &As..." + +#: graphicswin.cpp:48 +msgid "Export &Image..." +msgstr "Export &Image..." + +#: graphicswin.cpp:49 +msgid "Export 2d &View..." +msgstr "Export 2d &View..." + +#: graphicswin.cpp:50 +msgid "Export 2d &Section..." +msgstr "Export 2d &Section..." + +#: graphicswin.cpp:51 +msgid "Export 3d &Wireframe..." +msgstr "Export 3d &Wireframe..." + +#: graphicswin.cpp:52 +msgid "Export Triangle &Mesh..." +msgstr "Export Triangle &Mesh..." + +#: graphicswin.cpp:53 +msgid "Export &Surfaces..." +msgstr "Export &Surfaces..." + +#: graphicswin.cpp:54 +msgid "Im&port..." +msgstr "Im&port..." + +#: graphicswin.cpp:57 +msgid "E&xit" +msgstr "E&xit" + +#: graphicswin.cpp:60 +msgid "&Edit" +msgstr "&Edit" + +#: graphicswin.cpp:61 +msgid "&Undo" +msgstr "&Undo" + +#: graphicswin.cpp:62 +msgid "&Redo" +msgstr "&Redo" + +#: graphicswin.cpp:63 +msgid "Re&generate All" +msgstr "Re&generate All" + +#: graphicswin.cpp:65 +msgid "Snap Selection to &Grid" +msgstr "Snap Selection to &Grid" + +#: graphicswin.cpp:66 +msgid "Rotate Imported &90°" +msgstr "Rotate Imported &90°" + +#: graphicswin.cpp:68 +msgid "Cu&t" +msgstr "Cu&t" + +#: graphicswin.cpp:69 +msgid "&Copy" +msgstr "&Copy" + +#: graphicswin.cpp:70 +msgid "&Paste" +msgstr "&Paste" + +#: graphicswin.cpp:71 +msgid "Paste &Transformed..." +msgstr "Paste &Transformed..." + +#: graphicswin.cpp:72 +msgid "&Delete" +msgstr "&Delete" + +#: graphicswin.cpp:74 +msgid "Select &Edge Chain" +msgstr "Select &Edge Chain" + +#: graphicswin.cpp:75 +msgid "Select &All" +msgstr "Select &All" + +#: graphicswin.cpp:76 +msgid "&Unselect All" +msgstr "&Unselect All" + +#: graphicswin.cpp:78 +msgid "&Line Styles..." +msgstr "&Line Styles..." + +#: graphicswin.cpp:79 +msgid "&View Projection..." +msgstr "&View Projection..." + +#: graphicswin.cpp:81 +msgid "Con&figuration..." +msgstr "Con&figuration..." + +#: graphicswin.cpp:84 +msgid "&View" +msgstr "&View" + +#: graphicswin.cpp:85 +msgid "Zoom &In" +msgstr "Zoom &In" + +#: graphicswin.cpp:86 +msgid "Zoom &Out" +msgstr "Zoom &Out" + +#: graphicswin.cpp:87 +msgid "Zoom To &Fit" +msgstr "Zoom To &Fit" + +#: graphicswin.cpp:89 +msgid "Align View to &Workplane" +msgstr "Align View to &Workplane" + +#: graphicswin.cpp:90 +msgid "Nearest &Ortho View" +msgstr "Nearest &Ortho View" + +#: graphicswin.cpp:91 +msgid "Nearest &Isometric View" +msgstr "Nearest &Isometric View" + +#: graphicswin.cpp:92 +msgid "&Center View At Point" +msgstr "&Center View At Point" + +#: graphicswin.cpp:94 +msgid "Show Snap &Grid" +msgstr "Show Snap &Grid" + +#: graphicswin.cpp:95 +msgid "Darken Inactive Solids" +msgstr "Darken Inactive Solids" + +#: graphicswin.cpp:96 +msgid "Use &Perspective Projection" +msgstr "Use &Perspective Projection" + +#: graphicswin.cpp:97 +msgid "Dimension &Units" +msgstr "Dimension &Units" + +#: graphicswin.cpp:98 +msgid "Dimensions in &Millimeters" +msgstr "Dimensions in &Millimeters" + +#: graphicswin.cpp:99 +msgid "Dimensions in M&eters" +msgstr "Dimensions in M&eters" + +#: graphicswin.cpp:100 +msgid "Dimensions in &Inches" +msgstr "Dimensions in &Inches" + +#: graphicswin.cpp:102 +msgid "Show &Toolbar" +msgstr "Show &Toolbar" + +#: graphicswin.cpp:103 +msgid "Show Property Bro&wser" +msgstr "Show Property Bro&wser" + +#: graphicswin.cpp:105 +msgid "&Full Screen" +msgstr "&Full Screen" + +#: graphicswin.cpp:107 +msgid "&New Group" +msgstr "&New Group" + +#: graphicswin.cpp:108 +msgid "Sketch In &3d" +msgstr "Sketch In &3d" + +#: graphicswin.cpp:109 +msgid "Sketch In New &Workplane" +msgstr "Sketch In New &Workplane" + +#: graphicswin.cpp:111 +msgid "Step &Translating" +msgstr "Step &Translating" + +#: graphicswin.cpp:112 +msgid "Step &Rotating" +msgstr "Step &Rotating" + +#: graphicswin.cpp:114 +msgid "E&xtrude" +msgstr "E&xtrude" + +#: graphicswin.cpp:115 +msgid "&Helix" +msgstr "&Helix" + +#: graphicswin.cpp:116 +msgid "&Lathe" +msgstr "&Lathe" + +#: graphicswin.cpp:117 +msgid "Re&volve" +msgstr "Re&volve" + +#: graphicswin.cpp:119 +msgid "Link / Assemble..." +msgstr "Link / Assemble..." + +#: graphicswin.cpp:120 +msgid "Link Recent" +msgstr "Link Recent" + +#: graphicswin.cpp:122 +msgid "&Sketch" +msgstr "&Sketch" + +#: graphicswin.cpp:123 +msgid "In &Workplane" +msgstr "In &Workplane" + +#: graphicswin.cpp:124 +msgid "Anywhere In &3d" +msgstr "Anywhere In &3d" + +#: graphicswin.cpp:126 +msgid "Datum &Point" +msgstr "Datum &Point" + +#: graphicswin.cpp:127 +msgid "&Workplane" +msgstr "&Workplane" + +#: graphicswin.cpp:129 +msgid "Line &Segment" +msgstr "Line &Segment" + +#: graphicswin.cpp:130 +msgid "C&onstruction Line Segment" +msgstr "C&onstruction Line Segment" + +#: graphicswin.cpp:131 +msgid "&Rectangle" +msgstr "&Rectangle" + +#: graphicswin.cpp:132 +msgid "&Circle" +msgstr "&Circle" + +#: graphicswin.cpp:133 +msgid "&Arc of a Circle" +msgstr "&Arc of a Circle" + +#: graphicswin.cpp:134 +msgid "&Bezier Cubic Spline" +msgstr "&Bezier Cubic Spline" + +#: graphicswin.cpp:136 +msgid "&Text in TrueType Font" +msgstr "&Text in TrueType Font" + +#: graphicswin.cpp:137 +msgid "&Image" +msgstr "&Image" + +#: graphicswin.cpp:139 +msgid "To&ggle Construction" +msgstr "To&ggle Construction" + +#: graphicswin.cpp:140 +msgid "Tangent &Arc at Point" +msgstr "Tangent &Arc at Point" + +#: graphicswin.cpp:141 +msgid "Split Curves at &Intersection" +msgstr "Split Curves at &Intersection" + +#: graphicswin.cpp:143 +msgid "&Constrain" +msgstr "&Constrain" + +#: graphicswin.cpp:144 +msgid "&Distance / Diameter" +msgstr "&Distance / Diameter" + +#: graphicswin.cpp:145 +msgid "Re&ference Dimension" +msgstr "Re&ference Dimension" + +#: graphicswin.cpp:146 +msgid "A&ngle" +msgstr "A&ngle" + +#: graphicswin.cpp:147 +msgid "Reference An&gle" +msgstr "Reference An&gle" + +#: graphicswin.cpp:148 +msgid "Other S&upplementary Angle" +msgstr "Other S&upplementary Angle" + +#: graphicswin.cpp:149 +msgid "Toggle R&eference Dim" +msgstr "Toggle R&eference Dim" + +#: graphicswin.cpp:151 +msgid "&Horizontal" +msgstr "&Horizontal" + +#: graphicswin.cpp:152 +msgid "&Vertical" +msgstr "&Vertical" + +#: graphicswin.cpp:154 +msgid "&On Point / Curve / Plane" +msgstr "&On Point / Curve / Plane" + +#: graphicswin.cpp:155 +msgid "E&qual Length / Radius / Angle" +msgstr "E&qual Length / Radius / Angle" + +#: graphicswin.cpp:156 +msgid "Length Ra&tio" +msgstr "Length Ra&tio" + +#: graphicswin.cpp:157 +msgid "Length Diff&erence" +msgstr "Length Diff&erence" + +#: graphicswin.cpp:158 +msgid "At &Midpoint" +msgstr "At &Midpoint" + +#: graphicswin.cpp:159 +msgid "S&ymmetric" +msgstr "S&ymmetric" + +#: graphicswin.cpp:160 +msgid "Para&llel / Tangent" +msgstr "Para&llel / Tangent" + +#: graphicswin.cpp:161 +msgid "&Perpendicular" +msgstr "&Perpendicular" + +#: graphicswin.cpp:162 +msgid "Same Orient&ation" +msgstr "Same Orient&ation" + +#: graphicswin.cpp:163 +msgid "Lock Point Where &Dragged" +msgstr "Lock Point Where &Dragged" + +#: graphicswin.cpp:165 +msgid "Comment" +msgstr "Comment" + +#: graphicswin.cpp:167 +msgid "&Analyze" +msgstr "&Analyze" + +#: graphicswin.cpp:168 +msgid "Measure &Volume" +msgstr "Measure &Volume" + +#: graphicswin.cpp:169 +msgid "Measure A&rea" +msgstr "Measure A&rea" + +#: graphicswin.cpp:170 +msgid "Measure &Perimeter" +msgstr "Measure &Perimeter" + +#: graphicswin.cpp:171 +msgid "Show &Interfering Parts" +msgstr "Show &Interfering Parts" + +#: graphicswin.cpp:172 +msgid "Show &Naked Edges" +msgstr "Show &Naked Edges" + +#: graphicswin.cpp:173 +msgid "Show &Center of Mass" +msgstr "Show &Center of Mass" + +#: graphicswin.cpp:175 +msgid "Show &Underconstrained Points" +msgstr "Show &Underconstrained Points" + +#: graphicswin.cpp:177 +msgid "&Trace Point" +msgstr "&Trace Point" + +#: graphicswin.cpp:178 +msgid "&Stop Tracing..." +msgstr "&Stop Tracing..." + +#: graphicswin.cpp:179 +msgid "Step &Dimension..." +msgstr "Step &Dimension..." + +#: graphicswin.cpp:181 +msgid "&Help" +msgstr "&Help" + +#: graphicswin.cpp:182 +msgid "&Language" +msgstr "&Language" + +#: graphicswin.cpp:183 +msgid "&Website / Manual" +msgstr "&Website / Manual" + +#: graphicswin.cpp:185 +msgid "&About" +msgstr "&About" + +#: graphicswin.cpp:355 +msgid "(no recent files)" +msgstr "(no recent files)" + +#: graphicswin.cpp:363 +#, c-format +msgid "File '%s' does not exist." +msgstr "File '%s' does not exist." + +#: graphicswin.cpp:725 +msgid "No workplane is active, so the grid will not appear." +msgstr "No workplane is active, so the grid will not appear." + +#: graphicswin.cpp:740 +msgid "" +"The perspective factor is set to zero, so the view will always be a parallel " +"projection.\n" +"\n" +"For a perspective projection, modify the perspective factor in the " +"configuration screen. A value around 0.3 is typical." +msgstr "" +"The perspective factor is set to zero, so the view will always be a parallel " +"projection.\n" +"\n" +"For a perspective projection, modify the perspective factor in the " +"configuration screen. A value around 0.3 is typical." + +#: graphicswin.cpp:819 +msgid "" +"Select a point; this point will become the center of the view on screen." +msgstr "" +"Select a point; this point will become the center of the view on screen." + +#: graphicswin.cpp:1114 +msgid "No additional entities share endpoints with the selected entities." +msgstr "No additional entities share endpoints with the selected entities." + +#: graphicswin.cpp:1132 +msgid "" +"To use this command, select a point or other entity from an linked part, or " +"make a link group the active group." +msgstr "" +"To use this command, select a point or other entity from an linked part, or " +"make a link group the active group." + +#: graphicswin.cpp:1155 +msgid "" +"No workplane is active. Activate a workplane (with Sketch -> In Workplane) " +"to define the plane for the snap grid." +msgstr "" +"No workplane is active. Activate a workplane (with Sketch -> In Workplane) " +"to define the plane for the snap grid." + +#: graphicswin.cpp:1162 +msgid "" +"Can't snap these items to grid; select points, text comments, or constraints " +"with a label. To snap a line, select its endpoints." +msgstr "" +"Can't snap these items to grid; select points, text comments, or constraints " +"with a label. To snap a line, select its endpoints." + +#: graphicswin.cpp:1247 +msgid "No workplane selected. Activating default workplane for this group." +msgstr "No workplane selected. Activating default workplane for this group." + +#: graphicswin.cpp:1250 +msgid "" +"No workplane is selected, and the active group does not have a default " +"workplane. Try selecting a workplane, or activating a sketch-in-new-" +"workplane group." +msgstr "" +"No workplane is selected, and the active group does not have a default " +"workplane. Try selecting a workplane, or activating a sketch-in-new-" +"workplane group." + +#: graphicswin.cpp:1271 +msgid "" +"Bad selection for tangent arc at point. Select a single point, or select " +"nothing to set up arc parameters." +msgstr "" +"Bad selection for tangent arc at point. Select a single point, or select " +"nothing to set up arc parameters." + +#: graphicswin.cpp:1282 +msgid "click point on arc (draws anti-clockwise)" +msgstr "click point on arc (draws anti-clockwise)" + +#: graphicswin.cpp:1283 +msgid "click to place datum point" +msgstr "click to place datum point" + +#: graphicswin.cpp:1284 +msgid "click first point of line segment" +msgstr "click first point of line segment" + +#: graphicswin.cpp:1286 +msgid "click first point of construction line segment" +msgstr "click first point of construction line segment" + +#: graphicswin.cpp:1287 +msgid "click first point of cubic segment" +msgstr "click first point of cubic segment" + +#: graphicswin.cpp:1288 +msgid "click center of circle" +msgstr "click center of circle" + +#: graphicswin.cpp:1289 +msgid "click origin of workplane" +msgstr "click origin of workplane" + +#: graphicswin.cpp:1290 +msgid "click one corner of rectangle" +msgstr "click one corner of rectangle" + +#: graphicswin.cpp:1291 +msgid "click top left of text" +msgstr "click top left of text" + +#: graphicswin.cpp:1297 +msgid "click top left of image" +msgstr "click top left of image" + +#: graphicswin.cpp:1309 +msgid "" +"No entities are selected. Select entities before trying to toggle their " +"construction state." +msgstr "" +"No entities are selected. Select entities before trying to toggle their " +"construction state." + +#: group.cpp:86 +msgctxt "group-name" +msgid "sketch-in-3d" +msgstr "sketch-in-3d" + +#: group.cpp:142 +msgid "" +"Bad selection for new sketch in workplane. This group can be created with:\n" +"\n" +" * a point (through the point, orthogonal to coordinate axes)\n" +" * a point and two line segments (through the point, parallel to the " +"lines)\n" +" * a workplane (copy of the workplane)\n" +msgstr "" +"Bad selection for new sketch in workplane. This group can be created with:\n" +"\n" +" * a point (through the point, orthogonal to coordinate axes)\n" +" * a point and two line segments (through the point, parallel to the " +"lines)\n" +" * a workplane (copy of the workplane)\n" + +#: group.cpp:154 +msgid "" +"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch " +"will be extruded normal to the workplane." +msgstr "" +"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch " +"will be extruded normal to the workplane." + +#: group.cpp:163 +msgctxt "group-name" +msgid "extrude" +msgstr "extrude" + +#: group.cpp:168 +msgid "Lathe operation can only be applied to planar sketches." +msgstr "Lathe operation can only be applied to planar sketches." + +#: group.cpp:179 +msgid "" +"Bad selection for new lathe group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" +"Bad selection for new lathe group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" + +#: group.cpp:189 +msgctxt "group-name" +msgid "lathe" +msgstr "lathe" + +#: group.cpp:194 +msgid "Revolve operation can only be applied to planar sketches." +msgstr "Revolve operation can only be applied to planar sketches." + +#: group.cpp:205 +msgid "" +"Bad selection for new revolve group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" +"Bad selection for new revolve group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" + +#: group.cpp:217 +msgctxt "group-name" +msgid "revolve" +msgstr "revolve" + +#: group.cpp:222 +msgid "Helix operation can only be applied to planar sketches." +msgstr "Helix operation can only be applied to planar sketches." + +#: group.cpp:233 +msgid "" +"Bad selection for new helix group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" +"Bad selection for new helix group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" + +#: group.cpp:245 +msgctxt "group-name" +msgid "helix" +msgstr "helix" + +#: group.cpp:258 +msgid "" +"Bad selection for new rotation. This group can be created with:\n" +"\n" +" * a point, while locked in workplane (rotate in plane, about that " +"point)\n" +" * a point and a line or a normal (rotate about an axis through the " +"point, and parallel to line / normal)\n" +msgstr "" +"Bad selection for new rotation. This group can be created with:\n" +"\n" +" * a point, while locked in workplane (rotate in plane, about that " +"point)\n" +" * a point and a line or a normal (rotate about an axis through the " +"point, and parallel to line / normal)\n" + +#: group.cpp:271 +msgctxt "group-name" +msgid "rotate" +msgstr "rotate" + +#: group.cpp:282 +msgctxt "group-name" +msgid "translate" +msgstr "translate" + +#: group.cpp:400 +msgid "(unnamed)" +msgstr "(unnamed)" + +#: groupmesh.cpp:709 +msgid "not closed contour, or not all same style!" +msgstr "not closed contour, or not all same style!" + +#: groupmesh.cpp:722 +msgid "points not all coplanar!" +msgstr "points not all coplanar!" + +#: groupmesh.cpp:724 +msgid "contour is self-intersecting!" +msgstr "contour is self-intersecting!" + +#: groupmesh.cpp:726 +msgid "zero-length edge!" +msgstr "zero-length edge!" + +#: modify.cpp:254 +msgid "Must be sketching in workplane to create tangent arc." +msgstr "Must be sketching in workplane to create tangent arc." + +#: modify.cpp:301 +msgid "" +"To create a tangent arc, select a point where two non-construction lines or " +"circles in this group and workplane join." +msgstr "" +"To create a tangent arc, select a point where two non-construction lines or " +"circles in this group and workplane join." + +#: modify.cpp:388 +msgid "" +"Couldn't round this corner. Try a smaller radius, or try creating the " +"desired geometry by hand with tangency constraints." +msgstr "" +"Couldn't round this corner. Try a smaller radius, or try creating the " +"desired geometry by hand with tangency constraints." + +#: modify.cpp:597 +msgid "Couldn't split this entity; lines, circles, or cubics only." +msgstr "Couldn't split this entity; lines, circles, or cubics only." + +#: modify.cpp:624 +msgid "Must be sketching in workplane to split." +msgstr "Must be sketching in workplane to split." + +#: modify.cpp:631 +msgid "" +"Select two entities that intersect each other (e.g. two lines/circles/arcs " +"or a line/circle/arc and a point)." +msgstr "" +"Select two entities that intersect each other (e.g. two lines/circles/arcs " +"or a line/circle/arc and a point)." + +#: modify.cpp:736 +msgid "Can't split; no intersection found." +msgstr "Can't split; no intersection found." + +#: mouse.cpp:560 +msgid "Assign to Style" +msgstr "Assign to Style" + +#: mouse.cpp:576 +msgid "No Style" +msgstr "No Style" + +#: mouse.cpp:579 +msgid "Newly Created Custom Style..." +msgstr "Newly Created Custom Style..." + +#: mouse.cpp:586 +msgid "Group Info" +msgstr "Group Info" + +#: mouse.cpp:606 +msgid "Style Info" +msgstr "Style Info" + +#: mouse.cpp:626 +msgid "Select Edge Chain" +msgstr "Select Edge Chain" + +#: mouse.cpp:632 +msgid "Toggle Reference Dimension" +msgstr "Toggle Reference Dimension" + +#: mouse.cpp:638 +msgid "Other Supplementary Angle" +msgstr "Other Supplementary Angle" + +#: mouse.cpp:643 +msgid "Snap to Grid" +msgstr "Snap to Grid" + +#: mouse.cpp:652 +msgid "Remove Spline Point" +msgstr "Remove Spline Point" + +#: mouse.cpp:687 +msgid "Add Spline Point" +msgstr "Add Spline Point" + +#: mouse.cpp:691 +msgid "Cannot add spline point: maximum number of points reached." +msgstr "Cannot add spline point: maximum number of points reached." + +#: mouse.cpp:716 +msgid "Toggle Construction" +msgstr "Toggle Construction" + +#: mouse.cpp:731 +msgid "Delete Point-Coincident Constraint" +msgstr "Delete Point-Coincident Constraint" + +#: mouse.cpp:750 +msgid "Cut" +msgstr "Cut" + +#: mouse.cpp:752 +msgid "Copy" +msgstr "Copy" + +#: mouse.cpp:756 +msgid "Select All" +msgstr "Select All" + +#: mouse.cpp:761 +msgid "Paste" +msgstr "Paste" + +#: mouse.cpp:763 +msgid "Paste Transformed..." +msgstr "Paste Transformed..." + +#: mouse.cpp:768 +msgid "Delete" +msgstr "Delete" + +#: mouse.cpp:771 +msgid "Unselect All" +msgstr "Unselect All" + +#: mouse.cpp:778 +msgid "Unselect Hovered" +msgstr "Unselect Hovered" + +#: mouse.cpp:787 +msgid "Zoom to Fit" +msgstr "Zoom to Fit" + +#: mouse.cpp:989 mouse.cpp:1276 +msgid "click next point of line, or press Esc" +msgstr "click next point of line, or press Esc" + +#: mouse.cpp:995 +msgid "" +"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" +"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " +"Workplane." + +#: mouse.cpp:1029 +msgid "click to place other corner of rectangle" +msgstr "click to place other corner of rectangle" + +#: mouse.cpp:1049 +msgid "click to set radius" +msgstr "click to set radius" + +#: mouse.cpp:1054 +msgid "" +"Can't draw arc in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" +"Can't draw arc in 3d; first, activate a workplane with Sketch -> In " +"Workplane." + +#: mouse.cpp:1073 +msgid "click to place point" +msgstr "click to place point" + +#: mouse.cpp:1089 +msgid "click next point of cubic, or press Esc" +msgstr "click next point of cubic, or press Esc" + +#: mouse.cpp:1094 +msgid "" +"Sketching in a workplane already; sketch in 3d before creating new workplane." +msgstr "" +"Sketching in a workplane already; sketch in 3d before creating new workplane." + +#: mouse.cpp:1110 +msgid "" +"Can't draw text in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" +"Can't draw text in 3d; first, activate a workplane with Sketch -> In " +"Workplane." + +#: mouse.cpp:1127 +msgid "click to place bottom right of text" +msgstr "click to place bottom right of text" + +#: mouse.cpp:1133 +msgid "" +"Can't draw image in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" +"Can't draw image in 3d; first, activate a workplane with Sketch -> In " +"Workplane." + +#: mouse.cpp:1160 +msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" +msgstr "NEW COMMENT -- DOUBLE-CLICK TO EDIT" + +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511 +msgctxt "file-type" +msgid "SolveSpace models" +msgstr "SolveSpace models" + +#: platform/gui.cpp:90 +msgctxt "file-type" +msgid "IDF circuit board" +msgstr "IDF circuit board" + +#: platform/gui.cpp:94 +msgctxt "file-type" +msgid "PNG image" +msgstr "PNG image" + +#: platform/gui.cpp:98 +msgctxt "file-type" +msgid "STL mesh" +msgstr "STL mesh" + +#: platform/gui.cpp:99 +msgctxt "file-type" +msgid "Wavefront OBJ mesh" +msgstr "Wavefront OBJ mesh" + +#: platform/gui.cpp:100 +msgctxt "file-type" +msgid "Three.js-compatible mesh, with viewer" +msgstr "Three.js-compatible mesh, with viewer" + +#: platform/gui.cpp:101 +msgctxt "file-type" +msgid "Three.js-compatible mesh, mesh only" +msgstr "Three.js-compatible mesh, mesh only" + +#: platform/gui.cpp:102 +msgctxt "file-type" +msgid "VRML text file" +msgstr "VRML text file" + +#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 +msgctxt "file-type" +msgid "STEP file" +msgstr "STEP file" + +#: platform/gui.cpp:110 +msgctxt "file-type" +msgid "PDF file" +msgstr "PDF file" + +#: platform/gui.cpp:111 +msgctxt "file-type" +msgid "Encapsulated PostScript" +msgstr "Encapsulated PostScript" + +#: platform/gui.cpp:112 +msgctxt "file-type" +msgid "Scalable Vector Graphics" +msgstr "Scalable Vector Graphics" + +#: platform/gui.cpp:114 platform/gui.cpp:121 +msgctxt "file-type" +msgid "DXF file (AutoCAD 2007)" +msgstr "DXF file (AutoCAD 2007)" + +#: platform/gui.cpp:115 +msgctxt "file-type" +msgid "HPGL file" +msgstr "HPGL file" + +#: platform/gui.cpp:116 +msgctxt "file-type" +msgid "G Code" +msgstr "G Code" + +#: platform/gui.cpp:125 +msgctxt "file-type" +msgid "AutoCAD DXF and DWG files" +msgstr "AutoCAD DXF and DWG files" + +#: platform/gui.cpp:129 +msgctxt "file-type" +msgid "Comma-separated values" +msgstr "Comma-separated values" + +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 +msgid "untitled" +msgstr "untitled" + +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1573 +msgctxt "title" +msgid "Save File" +msgstr "Save File" + +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1575 +msgctxt "title" +msgid "Open File" +msgstr "Open File" + +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 +msgctxt "button" +msgid "_Cancel" +msgstr "_Cancel" + +#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 +msgctxt "button" +msgid "_Save" +msgstr "_Save" + +#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 +msgctxt "button" +msgid "_Open" +msgstr "_Open" + +#: solvespace.cpp:169 +msgctxt "title" +msgid "Autosave Available" +msgstr "Autosave Available" + +#: solvespace.cpp:170 +msgctxt "dialog" +msgid "An autosave file is available for this sketch." +msgstr "An autosave file is available for this sketch." + +#: solvespace.cpp:171 +msgctxt "dialog" +msgid "Do you want to load the autosave file instead?" +msgstr "Do you want to load the autosave file instead?" + +#: solvespace.cpp:172 +msgctxt "button" +msgid "&Load autosave" +msgstr "&Load autosave" + +#: solvespace.cpp:174 +msgctxt "button" +msgid "Do&n't Load" +msgstr "Do&n't Load" + +#: solvespace.cpp:557 +msgctxt "title" +msgid "Modified File" +msgstr "Modified File" + +#: solvespace.cpp:559 +#, c-format +msgctxt "dialog" +msgid "Do you want to save the changes you made to the sketch “%s”?" +msgstr "Do you want to save the changes you made to the sketch “%s”?" + +#: solvespace.cpp:562 +msgctxt "dialog" +msgid "Do you want to save the changes you made to the new sketch?" +msgstr "Do you want to save the changes you made to the new sketch?" + +#: solvespace.cpp:565 +msgctxt "dialog" +msgid "Your changes will be lost if you don't save them." +msgstr "Your changes will be lost if you don't save them." + +#: solvespace.cpp:566 +msgctxt "button" +msgid "&Save" +msgstr "&Save" + +#: solvespace.cpp:568 +msgctxt "button" +msgid "Do&n't Save" +msgstr "Do&n't Save" + +#: solvespace.cpp:589 +msgctxt "title" +msgid "(new sketch)" +msgstr "(new sketch)" + +#: solvespace.cpp:596 +msgctxt "title" +msgid "Property Browser" +msgstr "Property Browser" + +#: solvespace.cpp:658 +msgid "" +"Constraints are currently shown, and will be exported in the toolpath. This " +"is probably not what you want; hide them by clicking the link at the top of " +"the text window." +msgstr "" +"Constraints are currently shown, and will be exported in the toolpath. This " +"is probably not what you want; hide them by clicking the link at the top of " +"the text window." + +#: solvespace.cpp:730 +#, c-format +msgid "" +"Can't identify file type from file extension of filename '%s'; try .dxf or ." +"dwg." +msgstr "" +"Can't identify file type from file extension of filename '%s'; try .dxf or ." +"dwg." + +#: solvespace.cpp:778 +msgid "Constraint must have a label, and must not be a reference dimension." +msgstr "Constraint must have a label, and must not be a reference dimension." + +#: solvespace.cpp:782 +msgid "Bad selection for step dimension; select a constraint." +msgstr "Bad selection for step dimension; select a constraint." + +#: solvespace.cpp:806 +msgid "The assembly does not interfere, good." +msgstr "The assembly does not interfere, good." + +#: solvespace.cpp:822 +#, c-format +msgid "" +"The volume of the solid model is:\n" +"\n" +" %s" +msgstr "" +"The volume of the solid model is:\n" +"\n" +" %s" + +#: solvespace.cpp:831 +#, c-format +msgid "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" +msgstr "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" + +#: solvespace.cpp:836 +msgid "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." +msgstr "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." + +#: solvespace.cpp:851 +#, c-format +msgid "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." + +#: solvespace.cpp:860 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." +msgstr "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." + +#: solvespace.cpp:872 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." + +#: solvespace.cpp:892 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." + +#: solvespace.cpp:898 +msgid "Bad selection for perimeter; select line segments, arcs, and curves." +msgstr "Bad selection for perimeter; select line segments, arcs, and curves." + +#: solvespace.cpp:914 +msgid "Bad selection for trace; select a single point." +msgstr "Bad selection for trace; select a single point." + +#: solvespace.cpp:941 +#, c-format +msgid "Couldn't write to '%s'" +msgstr "Couldn't write to '%s'" + +#: solvespace.cpp:971 +msgid "The mesh is self-intersecting (NOT okay, invalid)." +msgstr "The mesh is self-intersecting (NOT okay, invalid)." + +#: solvespace.cpp:972 +msgid "The mesh is not self-intersecting (okay, valid)." +msgstr "The mesh is not self-intersecting (okay, valid)." + +#: solvespace.cpp:974 +msgid "The mesh has naked edges (NOT okay, invalid)." +msgstr "The mesh has naked edges (NOT okay, invalid)." + +#: solvespace.cpp:975 +msgid "The mesh is watertight (okay, valid)." +msgstr "The mesh is watertight (okay, valid)." + +#: solvespace.cpp:978 +#, c-format +msgid "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." +msgstr "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." + +#: solvespace.cpp:982 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" + +#: solvespace.cpp:985 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" + +#: solvespace.cpp:998 +#, c-format +msgid "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" +msgstr "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" + +#: style.cpp:166 +msgid "" +"Can't assign style to an entity that's derived from another entity; try " +"assigning a style to this entity's parent." +msgstr "" +"Can't assign style to an entity that's derived from another entity; try " +"assigning a style to this entity's parent." + +#: style.cpp:665 +msgid "Style name cannot be empty" +msgstr "Style name cannot be empty" + +#: textscreens.cpp:741 +msgid "Can't repeat fewer than 1 time." +msgstr "Can't repeat fewer than 1 time." + +#: textscreens.cpp:745 +msgid "Can't repeat more than 999 times." +msgstr "Can't repeat more than 999 times." + +#: textscreens.cpp:770 +msgid "Group name cannot be empty" +msgstr "Group name cannot be empty" + +#: textscreens.cpp:813 +msgid "Opacity must be between zero and one." +msgstr "Opacity must be between zero and one." + +#: textscreens.cpp:848 +msgid "Radius cannot be zero or negative." +msgstr "Radius cannot be zero or negative." + +#: toolbar.cpp:18 +msgid "Sketch line segment" +msgstr "Sketch line segment" + +#: toolbar.cpp:20 +msgid "Sketch rectangle" +msgstr "Sketch rectangle" + +#: toolbar.cpp:22 +msgid "Sketch circle" +msgstr "Sketch circle" + +#: toolbar.cpp:24 +msgid "Sketch arc of a circle" +msgstr "Sketch arc of a circle" + +#: toolbar.cpp:26 +msgid "Sketch curves from text in a TrueType font" +msgstr "Sketch curves from text in a TrueType font" + +#: toolbar.cpp:28 +msgid "Sketch image from a file" +msgstr "Sketch image from a file" + +#: toolbar.cpp:30 +msgid "Create tangent arc at selected point" +msgstr "Create tangent arc at selected point" + +#: toolbar.cpp:32 +msgid "Sketch cubic Bezier spline" +msgstr "Sketch cubic Bezier spline" + +#: toolbar.cpp:34 +msgid "Sketch datum point" +msgstr "Sketch datum point" + +#: toolbar.cpp:36 +msgid "Toggle construction" +msgstr "Toggle construction" + +#: toolbar.cpp:38 +msgid "Split lines / curves where they intersect" +msgstr "Split lines / curves where they intersect" + +#: toolbar.cpp:42 +msgid "Constrain distance / diameter / length" +msgstr "Constrain distance / diameter / length" + +#: toolbar.cpp:44 +msgid "Constrain angle" +msgstr "Constrain angle" + +#: toolbar.cpp:46 +msgid "Constrain to be horizontal" +msgstr "Constrain to be horizontal" + +#: toolbar.cpp:48 +msgid "Constrain to be vertical" +msgstr "Constrain to be vertical" + +#: toolbar.cpp:50 +msgid "Constrain to be parallel or tangent" +msgstr "Constrain to be parallel or tangent" + +#: toolbar.cpp:52 +msgid "Constrain to be perpendicular" +msgstr "Constrain to be perpendicular" + +#: toolbar.cpp:54 +msgid "Constrain point on line / curve / plane / point" +msgstr "Constrain point on line / curve / plane / point" + +#: toolbar.cpp:56 +msgid "Constrain symmetric" +msgstr "Constrain symmetric" + +#: toolbar.cpp:58 +msgid "Constrain equal length / radius / angle" +msgstr "Constrain equal length / radius / angle" + +#: toolbar.cpp:60 +msgid "Constrain normals in same orientation" +msgstr "Constrain normals in same orientation" + +#: toolbar.cpp:62 +msgid "Other supplementary angle" +msgstr "Other supplementary angle" + +#: toolbar.cpp:64 +msgid "Toggle reference dimension" +msgstr "Toggle reference dimension" + +#: toolbar.cpp:68 +msgid "New group extruding active sketch" +msgstr "New group extruding active sketch" + +#: toolbar.cpp:70 +msgid "New group rotating active sketch" +msgstr "New group rotating active sketch" + +#: toolbar.cpp:72 +msgid "New group helix from active sketch" +msgstr "New group helix from active sketch" + +#: toolbar.cpp:74 +msgid "New group revolve active sketch" +msgstr "New group revolve active sketch" + +#: toolbar.cpp:76 +msgid "New group step and repeat rotating" +msgstr "New group step and repeat rotating" + +#: toolbar.cpp:78 +msgid "New group step and repeat translating" +msgstr "New group step and repeat translating" + +#: toolbar.cpp:80 +msgid "New group in new workplane (thru given entities)" +msgstr "New group in new workplane (thru given entities)" + +#: toolbar.cpp:82 +msgid "New group in 3d" +msgstr "New group in 3d" + +#: toolbar.cpp:84 +msgid "New group linking / assembling file" +msgstr "New group linking / assembling file" + +#: toolbar.cpp:88 +msgid "Nearest isometric view" +msgstr "Nearest isometric view" + +#: toolbar.cpp:90 +msgid "Align view to active workplane" +msgstr "Align view to active workplane" + +#: util.cpp:165 +msgctxt "title" +msgid "Error" +msgstr "Error" + +#: util.cpp:165 +msgctxt "title" +msgid "Message" +msgstr "Message" + +#: util.cpp:170 +msgctxt "button" +msgid "&OK" +msgstr "&OK" + +#: view.cpp:78 +msgid "Scale cannot be zero or negative." +msgstr "Scale cannot be zero or negative." + +#: view.cpp:90 view.cpp:99 +msgid "Bad format: specify x, y, z" +msgstr "Bad format: specify x, y, z" + +#~ msgctxt "file-type" +#~ msgid "Q3D Object file" +#~ msgstr "Q3D Object file" diff --git a/res/locales/fr_FR.po b/res/locales/fr_FR.po new file mode 100644 index 0000000..784b961 --- /dev/null +++ b/res/locales/fr_FR.po @@ -0,0 +1,2262 @@ +# French translations for the SolveSpace package. +# Copyright (C) 2018 the SolveSpace authors +# This file is distributed under the same license as the SolveSpace package. +# whitequark , 2018. #zanata +msgid "" +msgstr "" +"Project-Id-Version: SolveSpace 3.0\n" +"Report-Msgid-Bugs-To: whitequark@whitequark.org\n" +"POT-Creation-Date: 2021-01-17 19:54+0200\n" +"PO-Revision-Date: 2018-07-14 06:12+0000\n" +"Last-Translator: whitequark \n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Zanata 4.4.5\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#: clipboard.cpp:310 +msgid "" +"Cut, paste, and copy work only in a workplane.\n" +"\n" +"Activate one with Sketch -> In Workplane." +msgstr "" +"Couper, coller et copier uniquement dans un plan de travail.\n" +"\n" +"Activez un plan avec \"Dessin -> Dans plan de travail\"." + +#: clipboard.cpp:327 +msgid "Clipboard is empty; nothing to paste." +msgstr "Presse papier vide; rien à coller." + +#: clipboard.cpp:374 +msgid "Number of copies to paste must be at least one." +msgstr "Le nombre de copies à coller doit être d'au moins un." + +#: clipboard.cpp:390 textscreens.cpp:783 +msgid "Scale cannot be zero." +msgstr "L'échelle ne peut pas être zéro." + +#: clipboard.cpp:432 +msgid "Select one point to define origin of rotation." +msgstr "Sélectionnez un point pour définir l'origine de la rotation." + +#: clipboard.cpp:444 +msgid "Select two points to define translation vector." +msgstr "Sélectionnez deux points pour définir le vecteur de translation." + +#: clipboard.cpp:454 +msgid "" +"Transformation is identity. So all copies will be exactly on top of each " +"other." +msgstr "" +"Transformation identique. Donc, toutes les copies seront exactement les unes " +"au-dessus des autres." + +#: clipboard.cpp:458 +msgid "Too many items to paste; split this into smaller pastes." +msgstr "Trop d'éléments à coller; Divisez-les en plus petits groupes." + +#: clipboard.cpp:463 +msgid "No workplane active." +msgstr "Pas d'espace de travail actif." + +#: confscreen.cpp:418 +msgid "Bad format: specify coordinates as x, y, z" +msgstr "Mauvais format: spécifiez les coordonnées comme x, y, z" + +#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805 +msgid "Bad format: specify color as r, g, b" +msgstr "Mauvais format; spécifiez la couleur comme r, v, b" + +#: confscreen.cpp:454 +msgid "" +"The perspective factor will have no effect until you enable View -> Use " +"Perspective Projection." +msgstr "" +"Le facteur de perspective n'aura aucun effet tant que vous n'aurez pas " +"activé \"Affichage -> Utiliser la projection de perspective\"." + +#: confscreen.cpp:467 confscreen.cpp:477 +#, c-format +msgid "Specify between 0 and %d digits after the decimal." +msgstr "" + +#: confscreen.cpp:489 +msgid "Export scale must not be zero!" +msgstr "L'échelle d'export ne doit pas être zéro!" + +#: confscreen.cpp:501 +msgid "Cutter radius offset must not be negative!" +msgstr "Le décalage du rayon de coupe ne doit pas être négatif!" + +#: confscreen.cpp:555 +msgid "Bad value: autosave interval should be positive" +msgstr "" +"Mauvaise valeur: l'intervalle d'enregistrement automatique devrait être " +"positif" + +#: confscreen.cpp:558 +msgid "Bad format: specify interval in integral minutes" +msgstr "Mauvais format: spécifiez un nombre entier de minutes" + +#: constraint.cpp:12 +msgctxt "constr-name" +msgid "pts-coincident" +msgstr "pts-coïncidence" + +#: constraint.cpp:13 +msgctxt "constr-name" +msgid "pt-pt-distance" +msgstr "pt-pt-distance" + +#: constraint.cpp:14 +msgctxt "constr-name" +msgid "pt-line-distance" +msgstr "pt-ligne-distance" + +#: constraint.cpp:15 +msgctxt "constr-name" +msgid "pt-plane-distance" +msgstr "pt-plan-distance" + +#: constraint.cpp:16 +msgctxt "constr-name" +msgid "pt-face-distance" +msgstr "pt-face-distance" + +#: constraint.cpp:17 +msgctxt "constr-name" +msgid "proj-pt-pt-distance" +msgstr "proj-pt-pt-distance" + +#: constraint.cpp:18 +msgctxt "constr-name" +msgid "pt-in-plane" +msgstr "pt-dans-plan" + +#: constraint.cpp:19 +msgctxt "constr-name" +msgid "pt-on-line" +msgstr "pt-sur-ligne" + +#: constraint.cpp:20 +msgctxt "constr-name" +msgid "pt-on-face" +msgstr "pt-sur-face" + +#: constraint.cpp:21 +msgctxt "constr-name" +msgid "eq-length" +msgstr "eg-longueur" + +#: constraint.cpp:22 +msgctxt "constr-name" +msgid "eq-length-and-pt-ln-dist" +msgstr "eg-longueur-et-pt-dans-dist" + +#: constraint.cpp:23 +msgctxt "constr-name" +msgid "eq-pt-line-distances" +msgstr "eg-pt-ligne-distances" + +#: constraint.cpp:24 +msgctxt "constr-name" +msgid "length-ratio" +msgstr "longueur-ratio" + +#: constraint.cpp:25 +msgctxt "constr-name" +msgid "length-difference" +msgstr "longueur-difference" + +#: constraint.cpp:26 +msgctxt "constr-name" +msgid "symmetric" +msgstr "symétrique" + +#: constraint.cpp:27 +msgctxt "constr-name" +msgid "symmetric-h" +msgstr "symétrique-h" + +#: constraint.cpp:28 +msgctxt "constr-name" +msgid "symmetric-v" +msgstr "symétrique-v" + +#: constraint.cpp:29 +msgctxt "constr-name" +msgid "symmetric-line" +msgstr "symétrique-ligne" + +#: constraint.cpp:30 +msgctxt "constr-name" +msgid "at-midpoint" +msgstr "au-point-milieu" + +#: constraint.cpp:31 +msgctxt "constr-name" +msgid "horizontal" +msgstr "horizontal" + +#: constraint.cpp:32 +msgctxt "constr-name" +msgid "vertical" +msgstr "vertical" + +#: constraint.cpp:33 +msgctxt "constr-name" +msgid "diameter" +msgstr "diamètre" + +#: constraint.cpp:34 +msgctxt "constr-name" +msgid "pt-on-circle" +msgstr "pt-sur-cercle" + +#: constraint.cpp:35 +msgctxt "constr-name" +msgid "same-orientation" +msgstr "même-orientation" + +#: constraint.cpp:36 +msgctxt "constr-name" +msgid "angle" +msgstr "angle" + +#: constraint.cpp:37 +msgctxt "constr-name" +msgid "parallel" +msgstr "parallèle" + +#: constraint.cpp:38 +msgctxt "constr-name" +msgid "arc-line-tangent" +msgstr "arc-ligne-tangente" + +#: constraint.cpp:39 +msgctxt "constr-name" +msgid "cubic-line-tangent" +msgstr "cubique-ligne-tangente" + +#: constraint.cpp:40 +msgctxt "constr-name" +msgid "curve-curve-tangent" +msgstr "courbe-courbe-tangente" + +#: constraint.cpp:41 +msgctxt "constr-name" +msgid "perpendicular" +msgstr "perpendiculaire" + +#: constraint.cpp:42 +msgctxt "constr-name" +msgid "eq-radius" +msgstr "eg-rayon" + +#: constraint.cpp:43 +msgctxt "constr-name" +msgid "eq-angle" +msgstr "eg-angle" + +#: constraint.cpp:44 +msgctxt "constr-name" +msgid "eq-line-len-arc-len" +msgstr "eg-ligne-long-arc-long" + +#: constraint.cpp:45 +msgctxt "constr-name" +msgid "lock-where-dragged" +msgstr "verrouillé-où-déplacé" + +#: constraint.cpp:46 +msgctxt "constr-name" +msgid "comment" +msgstr "commentaire" + +#: constraint.cpp:140 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." +msgstr "" +"L'arc tangent et le segment de ligne doivent partager un point final. " +"Contraignez-les avec \"Contrainte -> Sur point avant de contraindre la " +"tangente\"." + +#: constraint.cpp:158 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." +msgstr "" +"La tangente cubique et le segment de ligne doivent partager un point final. " +"Contraignez-les avec \"Contrainte -> Sur point avant de contraindre la " +"tangente\"." + +#: constraint.cpp:183 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." +msgstr "" +"Les courbes doivent partager un point final. Contraignez-les avec " +"\"Contrainte -> Sur point avant de contraindre la tangente\"." + +#: constraint.cpp:231 +msgid "" +"Bad selection for distance / diameter constraint. This constraint can apply " +"to:\n" +"\n" +" * two points (distance between points)\n" +" * a line segment (length)\n" +" * two points and a line segment or normal (projected distance)\n" +" * a workplane and a point (minimum distance)\n" +" * a line segment and a point (minimum distance)\n" +" * a plane face and a point (minimum distance)\n" +" * a circle or an arc (diameter)\n" +msgstr "" +"Mauvaise sélection pour la contrainte distance / diamètre. Cette contrainte " +"peut s'appliquer à:\n" +"\n" +"    * Deux points (distance entre points)\n" +"    * Un segment de ligne (longueur)\n" +"    * Deux points et un segment de ligne ou normal (distance projetée)\n" +"    * Un plan de travail et un point (distance minimale)\n" +"    * Un segment de ligne et un point (distance minimale)\n" +"    * Une face plane et un point (distance minimale)\n" +"    * Un cercle ou un arc (diamètre)\n" + +#: constraint.cpp:284 +msgid "" +"Bad selection for on point / curve / plane constraint. This constraint can " +"apply to:\n" +"\n" +" * two points (points coincident)\n" +" * a point and a workplane (point in plane)\n" +" * a point and a line segment (point on line)\n" +" * a point and a circle or arc (point on curve)\n" +" * a point and a plane face (point on face)\n" +msgstr "" +"Mauvaise sélection pour la contrainte point / courbe / plan. Cette " +"contrainte peut s'appliquer à:\n" +"\n" +"    * Deux points (points coïncidents)\n" +"    * Un point et un plan de travail (point dans le plan)\n" +"    * Un point et un segment de ligne (point en ligne)\n" +"    * Un point et un cercle ou un arc (point sur courbe)\n" +"    * Un point et une face plane (point sur une face)\n" + +#: constraint.cpp:346 +msgid "" +"Bad selection for equal length / radius constraint. This constraint can " +"apply to:\n" +"\n" +" * two line segments (equal length)\n" +" * two line segments and two points (equal point-line distances)\n" +" * a line segment and two points (equal point-line distances)\n" +" * a line segment, and a point and line segment (point-line distance " +"equals length)\n" +" * four line segments or normals (equal angle between A,B and C,D)\n" +" * three line segments or normals (equal angle between A,B and B,C)\n" +" * two circles or arcs (equal radius)\n" +" * a line segment and an arc (line segment length equals arc length)\n" +msgstr "" +"Mauvaise sélection pour une contrainte de longueur / rayon égale. Cette " +"contrainte peut s'appliquer à:\n" +"\n" +"    * Deux segments de ligne (longueur égale)\n" +"    * Deux segments de ligne et deux points (distances point-ligne égales)\n" +"    * Un segment de ligne et deux points (distances point-ligne égales)\n" +"    * Un segment de ligne ou un segment de ligne et point (distance point-" +"ligne de longueur égale)\n" +"    * Quatre segments de ligne ou des normales (angle entre A, B et C, D " +"égaux)\n" +"    * Trois segments de ligne ou des normales (angle entre A, B et B, C " +"égaux)\n" +"    * Deux cercles ou arcs (rayon égaux)\n" +"    * Un segment de ligne et un arc (la longueur de segment de ligne est " +"égale à la longueur d'arc)\n" + +#: constraint.cpp:385 +msgid "" +"Bad selection for length ratio constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +msgstr "" +"Mauvaise sélection pour la contrainte du rapport de longueur. Cette " +"contrainte peut s'appliquer à:\n" +"\n" +"    * Deux segments de ligne\n" + +#: constraint.cpp:402 +msgid "" +"Bad selection for length difference constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments\n" +msgstr "" +"Mauvaise sélection pour la contrainte de différence de longueur. Cette " +"contrainte peut s'appliquer à:\n" +"\n" +"    * Deux segments de ligne\n" + +#: constraint.cpp:428 +msgid "" +"Bad selection for at midpoint constraint. This constraint can apply to:\n" +"\n" +" * a line segment and a point (point at midpoint)\n" +" * a line segment and a workplane (line's midpoint on plane)\n" +msgstr "" +"Mauvaise sélection pour une contrainte de point médian. Cette contrainte " +"peut s'appliquer à:\n" +"\n" +"    * Un segment de ligne et un point (point au milieu)\n" +"    * Un segment de ligne et un plan de travail (point médian dans le plan)\n" + +#: constraint.cpp:486 +msgid "" +"Bad selection for symmetric constraint. This constraint can apply to:\n" +"\n" +" * two points or a line segment (symmetric about workplane's coordinate " +"axis)\n" +" * line segment, and two points or a line segment (symmetric about line " +"segment)\n" +" * workplane, and two points or a line segment (symmetric about " +"workplane)\n" +msgstr "" +"Mauvaise sélection pour la contrainte symétrique. Cette contrainte peut " +"s'appliquer à:\n" +"\n" +"    * Deux points ou un segment de ligne (symétrique à l'axe des coordonnées " +"du plan de travail)\n" +"    * Segment de ligne, et deux points ou un segment de ligne (symétrique " +"sur le segment de ligne)\n" +"    * Plan de travail, et deux points ou un segment de ligne (symétrique au " +"plan de travail)\n" + +#: constraint.cpp:500 +msgid "" +"A workplane must be active when constraining symmetric without an explicit " +"symmetry plane." +msgstr "" +"Un plan de travail doit être actif lors d'une contrainte de symétrie sans " +"plan de symétrie explicite." + +#: constraint.cpp:530 +msgid "" +"Activate a workplane (with Sketch -> In Workplane) before applying a " +"horizontal or vertical constraint." +msgstr "" +"Activez un plan de travail (avec Dessin -> Dans plan de travail) avant " +"d'appliquer une contrainte horizontale ou verticale." + +#: constraint.cpp:543 +msgid "" +"Bad selection for horizontal / vertical constraint. This constraint can " +"apply to:\n" +"\n" +" * two points\n" +" * a line segment\n" +msgstr "" +"Mauvaise sélection pour la contrainte horizontale / verticale. Cette " +"contrainte peut s'appliquer à:\n" +"\n" +"    * deux points\n" +"    * Un segment de ligne\n" + +#: constraint.cpp:564 +msgid "" +"Bad selection for same orientation constraint. This constraint can apply " +"to:\n" +"\n" +" * two normals\n" +msgstr "" +"Mauvaise sélection pour la même contrainte d'orientation. Cette contrainte " +"peut s'appliquer à:\n" +"\n" +" * Deux normales\n" + +#: constraint.cpp:614 +msgid "Must select an angle constraint." +msgstr "Vous devez sélectionner une contrainte d'angle." + +#: constraint.cpp:627 +msgid "Must select a constraint with associated label." +msgstr "Vous devez sélectionner une contrainte avec une étiquette associée." + +#: constraint.cpp:638 +msgid "" +"Bad selection for angle constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" +"Mauvaise sélection pour une contrainte d'angle. Cette contrainte peut " +"s'appliquer à:\n" +"\n" +"    * Deux segments de ligne\n" +"    * Un segment de ligne et une normale\n" +"    * Deux normales\n" + +#: constraint.cpp:701 +msgid "Curve-curve tangency must apply in workplane." +msgstr "Courbe-Courbe tangence doit s'appliquer dans le plan de travail." + +#: constraint.cpp:711 +msgid "" +"Bad selection for parallel / tangent constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments (parallel)\n" +" * a line segment and a normal (parallel)\n" +" * two normals (parallel)\n" +" * two line segments, arcs, or beziers, that share an endpoint (tangent)\n" +msgstr "" +"Mauvaise sélection pour la contrainte parallèle / tangente. Cette contrainte " +"peut s'appliquer à:\n" +"\n" +"    * Deux segments de ligne (parallèles)\n" +"    * Un segment de ligne et un parallèle (parallèle)\n" +"    * Deux normales (parallèles)\n" +"    * Deux segments de ligne, des arcs ou des Béziers, qui partagent un " +"point final (tangent)\n" + +#: constraint.cpp:729 +msgid "" +"Bad selection for perpendicular constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" +"Mauvaise sélection pour une contrainte perpendiculaire. Cette contrainte " +"peut s'appliquer à:\n" +"\n" +"    * Deux segments de ligne\n" +"    * Un segment de ligne et une normale\n" +"    * Deux normales\n" + +#: constraint.cpp:744 +msgid "" +"Bad selection for lock point where dragged constraint. This constraint can " +"apply to:\n" +"\n" +" * a point\n" +msgstr "" +"Mauvaise sélection pour le point de verrouillage où la contrainte déplacé. " +"Cette contrainte peut s'appliquer à:\n" +"\n" +"    * un point\n" + +#: constraint.cpp:755 +msgid "click center of comment text" +msgstr "cliquez le centre du texte de commentaire" + +#: export.cpp:19 +msgid "" +"No solid model present; draw one with extrudes and revolves, or use Export " +"2d View to export bare lines and curves." +msgstr "" +"Aucun modèle solide présent; Dessinez-en un avec une extrusion et " +"révolution, ou utilisez \"Exporter vue 2d\" pour exporter les lignes et les " +"courbes dépouillées." + +#: export.cpp:61 +msgid "" +"Bad selection for export section. Please select:\n" +"\n" +" * nothing, with an active workplane (workplane is section plane)\n" +" * a face (section plane through face)\n" +" * a point and two line segments (plane through point and parallel to " +"lines)\n" +msgstr "" +"Mauvaise sélection pour la section export. Sélectionnez:\n" +"\n" +"    * Rien, avec un plan de travail actif (plan de travail est un plan de " +"section)\n" +"    * Une face (plan de coupe au-travers d'une face)\n" +"    * Un point et deux segments de ligne (plan au-travers d'un point et " +"parallèle aux lignes)\n" + +#: export.cpp:822 +msgid "Active group mesh is empty; nothing to export." +msgstr "Le maillage du groupe actif est vide; Rien à exporter." + +#: exportvector.cpp:337 +msgid "freehand lines were replaced with continuous lines" +msgstr "les lignes à main levée ont été remplacées par des lignes continues" + +#: exportvector.cpp:339 +msgid "zigzag lines were replaced with continuous lines" +msgstr "les lignes en zigzag ont été remplacées par des lignes continues" + +#: exportvector.cpp:593 +msgid "" +"Some aspects of the drawing have no DXF equivalent and were not exported:\n" +msgstr "" +"Certains aspects du dessin n'ont pas d'équivalent DXF et n'ont pas été " +"exportés:\n" + +#: exportvector.cpp:839 +msgid "" +"PDF page size exceeds 200 by 200 inches; many viewers may reject this file." +msgstr "" +"La taille de la page PDF dépasse 200 par 200 pouces; De nombreux lecteurs " +"peuvent rejeter ce fichier." + +#: file.cpp:44 group.cpp:91 +msgctxt "group-name" +msgid "sketch-in-plane" +msgstr "dessin-dans-plan" + +#: file.cpp:62 +msgctxt "group-name" +msgid "#references" +msgstr "#références" + +#: file.cpp:549 +msgid "" +"Unrecognized data in file. This file may be corrupt, or from a newer version " +"of the program." +msgstr "" +"Données non reconnues dans le fichier. Ce fichier peut être corrompu ou " +"depuis une version plus récente du programme." + +#: file.cpp:859 +msgctxt "title" +msgid "Missing File" +msgstr "Fichier manquant" + +#: file.cpp:860 +#, c-format +msgctxt "dialog" +msgid "The linked file “%s” is not present." +msgstr "" + +#: file.cpp:862 +msgctxt "dialog" +msgid "" +"Do you want to locate it manually?\n" +"\n" +"If you decline, any geometry that depends on the missing file will be " +"permanently removed." +msgstr "" + +#: file.cpp:865 +msgctxt "button" +msgid "&Yes" +msgstr "" + +#: file.cpp:867 +msgctxt "button" +msgid "&No" +msgstr "" + +#: file.cpp:869 solvespace.cpp:569 +msgctxt "button" +msgid "&Cancel" +msgstr "" + +#: graphicswin.cpp:41 +msgid "&File" +msgstr "&Fichier" + +#: graphicswin.cpp:42 +msgid "&New" +msgstr "&Nouveau" + +#: graphicswin.cpp:43 +msgid "&Open..." +msgstr "&Ouvrir..." + +#: graphicswin.cpp:44 +msgid "Open &Recent" +msgstr "Ouvrir &Récent" + +#: graphicswin.cpp:45 +msgid "&Save" +msgstr "&Sauver" + +#: graphicswin.cpp:46 +msgid "Save &As..." +msgstr "Sauver &Comme..." + +#: graphicswin.cpp:48 +msgid "Export &Image..." +msgstr "Exporter &Image..." + +#: graphicswin.cpp:49 +msgid "Export 2d &View..." +msgstr "Exporter &vue 2D..." + +#: graphicswin.cpp:50 +msgid "Export 2d &Section..." +msgstr "Exporter &Section 2d..." + +#: graphicswin.cpp:51 +msgid "Export 3d &Wireframe..." +msgstr "Exporter &Fil de fer 3d..." + +#: graphicswin.cpp:52 +msgid "Export Triangle &Mesh..." +msgstr "Exporter Triangle &Maillage..." + +#: graphicswin.cpp:53 +msgid "Export &Surfaces..." +msgstr "Export &Surfaces..." + +#: graphicswin.cpp:54 +msgid "Im&port..." +msgstr "Im&porter..." + +#: graphicswin.cpp:57 +msgid "E&xit" +msgstr "&Quitter" + +#: graphicswin.cpp:60 +msgid "&Edit" +msgstr "&Editer" + +#: graphicswin.cpp:61 +msgid "&Undo" +msgstr "&Annuler" + +#: graphicswin.cpp:62 +msgid "&Redo" +msgstr "&Refaire" + +#: graphicswin.cpp:63 +msgid "Re&generate All" +msgstr "Re&générer Tout" + +#: graphicswin.cpp:65 +msgid "Snap Selection to &Grid" +msgstr "Accrocher la sélection à la &Grille" + +#: graphicswin.cpp:66 +msgid "Rotate Imported &90°" +msgstr "Rotation importation &90°" + +#: graphicswin.cpp:68 +msgid "Cu&t" +msgstr "Co&uper" + +#: graphicswin.cpp:69 +msgid "&Copy" +msgstr "&Copier" + +#: graphicswin.cpp:70 +msgid "&Paste" +msgstr "Co&ller" + +#: graphicswin.cpp:71 +msgid "Paste &Transformed..." +msgstr "Coller &Transformer..." + +#: graphicswin.cpp:72 +msgid "&Delete" +msgstr "&Effacer" + +#: graphicswin.cpp:74 +msgid "Select &Edge Chain" +msgstr "Sélectionner une Chaîne d'&Arêtes" + +#: graphicswin.cpp:75 +msgid "Select &All" +msgstr "Sélectionner &Tout" + +#: graphicswin.cpp:76 +msgid "&Unselect All" +msgstr "&Désélectionner Tout" + +#: graphicswin.cpp:78 +msgid "&Line Styles..." +msgstr "&Ligne styles..." + +#: graphicswin.cpp:79 +msgid "&View Projection..." +msgstr "&Affichage Perspective..." + +#: graphicswin.cpp:81 +msgid "Con&figuration..." +msgstr "Con&figuration..." + +#: graphicswin.cpp:84 +msgid "&View" +msgstr "&Affichage" + +#: graphicswin.cpp:85 +msgid "Zoom &In" +msgstr "Zoom &Avant" + +#: graphicswin.cpp:86 +msgid "Zoom &Out" +msgstr "Zoom A&rrière" + +#: graphicswin.cpp:87 +msgid "Zoom To &Fit" +msgstr "Zoom A&justé" + +#: graphicswin.cpp:89 +msgid "Align View to &Workplane" +msgstr "Aligner la vue au &Plan de travail" + +#: graphicswin.cpp:90 +msgid "Nearest &Ortho View" +msgstr "Vue &Orthogonale la plus proche" + +#: graphicswin.cpp:91 +msgid "Nearest &Isometric View" +msgstr "Vue &Isométrique la plus proche" + +#: graphicswin.cpp:92 +msgid "&Center View At Point" +msgstr "&Centrer la Vue sur le Point" + +#: graphicswin.cpp:94 +msgid "Show Snap &Grid" +msgstr "Afficher la &grille d'accrochage" + +#: graphicswin.cpp:95 +msgid "Darken Inactive Solids" +msgstr "" + +#: graphicswin.cpp:96 +msgid "Use &Perspective Projection" +msgstr "Utiliser la vue en &Perspective" + +#: graphicswin.cpp:97 +msgid "Dimension &Units" +msgstr "&Unités de dimensions" + +#: graphicswin.cpp:98 +msgid "Dimensions in &Millimeters" +msgstr "Dimensions en &Millimètres" + +#: graphicswin.cpp:99 +msgid "Dimensions in M&eters" +msgstr "Dimensions en &Mètres" + +#: graphicswin.cpp:100 +msgid "Dimensions in &Inches" +msgstr "Dimensions en &Pouces" + +#: graphicswin.cpp:102 +msgid "Show &Toolbar" +msgstr "Affichage &Barre d'outils" + +#: graphicswin.cpp:103 +msgid "Show Property Bro&wser" +msgstr "Affichage du &Navigateur de Propriété" + +#: graphicswin.cpp:105 +msgid "&Full Screen" +msgstr "&Plein Ecran" + +#: graphicswin.cpp:107 +msgid "&New Group" +msgstr "&Nouveau Groupe" + +#: graphicswin.cpp:108 +msgid "Sketch In &3d" +msgstr "Dessin en &3d" + +#: graphicswin.cpp:109 +msgid "Sketch In New &Workplane" +msgstr "Dessin dans un nouveau &Plan de travail" + +#: graphicswin.cpp:111 +msgid "Step &Translating" +msgstr "Espacement &Linéaire" + +#: graphicswin.cpp:112 +msgid "Step &Rotating" +msgstr "Espacement &Circulaire" + +#: graphicswin.cpp:114 +msgid "E&xtrude" +msgstr "E&xtruder" + +#: graphicswin.cpp:115 +msgid "&Helix" +msgstr "&Helix" + +#: graphicswin.cpp:116 +msgid "&Lathe" +msgstr "&Lathe" + +#: graphicswin.cpp:117 +msgid "Re&volve" +msgstr "Ré&volution" + +#: graphicswin.cpp:119 +msgid "Link / Assemble..." +msgstr "Lié / Assembler..." + +#: graphicswin.cpp:120 +msgid "Link Recent" +msgstr "Lié Récent" + +#: graphicswin.cpp:122 +msgid "&Sketch" +msgstr "&Dessin" + +#: graphicswin.cpp:123 +msgid "In &Workplane" +msgstr "Dans le &Plan de travail" + +#: graphicswin.cpp:124 +msgid "Anywhere In &3d" +msgstr "N'importe où dans la &3d" + +#: graphicswin.cpp:126 +msgid "Datum &Point" +msgstr "&Point" + +#: graphicswin.cpp:127 +msgid "&Workplane" +msgstr "&Plan de travail" + +#: graphicswin.cpp:129 +msgid "Line &Segment" +msgstr "Ligne - &Polyligne" + +#: graphicswin.cpp:130 +msgid "C&onstruction Line Segment" +msgstr "Ligne de C&onstruction" + +#: graphicswin.cpp:131 +msgid "&Rectangle" +msgstr "&Rectangle" + +#: graphicswin.cpp:132 +msgid "&Circle" +msgstr "&Cercle" + +#: graphicswin.cpp:133 +msgid "&Arc of a Circle" +msgstr "&Arc de Cercle" + +#: graphicswin.cpp:134 +msgid "&Bezier Cubic Spline" +msgstr "Spline Cubique de &Beziers" + +#: graphicswin.cpp:136 +msgid "&Text in TrueType Font" +msgstr "&Texte en Police TrueType" + +#: graphicswin.cpp:137 +msgid "&Image" +msgstr "&Image" + +#: graphicswin.cpp:139 +msgid "To&ggle Construction" +msgstr "&Basculer en mode \"Construction\"" + +#: graphicswin.cpp:140 +msgid "Tangent &Arc at Point" +msgstr "&Arc Tangent au Point" + +#: graphicswin.cpp:141 +msgid "Split Curves at &Intersection" +msgstr "Diviser les Courbes à l'&Intersection" + +#: graphicswin.cpp:143 +msgid "&Constrain" +msgstr "&Constraintes" + +#: graphicswin.cpp:144 +msgid "&Distance / Diameter" +msgstr "&Distance / Diamètre" + +#: graphicswin.cpp:145 +msgid "Re&ference Dimension" +msgstr "Dimension Maîtresse / Indicative" + +#: graphicswin.cpp:146 +msgid "A&ngle" +msgstr "A&ngle" + +#: graphicswin.cpp:147 +msgid "Reference An&gle" +msgstr "An&gle Maître / Indicatif" + +#: graphicswin.cpp:148 +msgid "Other S&upplementary Angle" +msgstr "Autre angle S&upplémentaire" + +#: graphicswin.cpp:149 +msgid "Toggle R&eference Dim" +msgstr "Basculer cote Maîtresse / cote Indicative" + +#: graphicswin.cpp:151 +msgid "&Horizontal" +msgstr "&Horizontal" + +#: graphicswin.cpp:152 +msgid "&Vertical" +msgstr "&Vertical" + +#: graphicswin.cpp:154 +msgid "&On Point / Curve / Plane" +msgstr "&Sur Point / Courbe / Plan" + +#: graphicswin.cpp:155 +msgid "E&qual Length / Radius / Angle" +msgstr "&Egale Longueur / Rayon / Angle" + +#: graphicswin.cpp:156 +msgid "Length Ra&tio" +msgstr "R&apport de Longueur" + +#: graphicswin.cpp:157 +msgid "Length Diff&erence" +msgstr "D&ifférence de Longueur" + +#: graphicswin.cpp:158 +msgid "At &Midpoint" +msgstr "Au &Milieu" + +#: graphicswin.cpp:159 +msgid "S&ymmetric" +msgstr "&Symétrique" + +#: graphicswin.cpp:160 +msgid "Para&llel / Tangent" +msgstr "Para&llèle / Tangent" + +#: graphicswin.cpp:161 +msgid "&Perpendicular" +msgstr "&Perpendiculaire" + +#: graphicswin.cpp:162 +msgid "Same Orient&ation" +msgstr "Même Orient&ation" + +#: graphicswin.cpp:163 +msgid "Lock Point Where &Dragged" +msgstr "Accrocher le point à l'&Emplacement" + +#: graphicswin.cpp:165 +msgid "Comment" +msgstr "Commentaire" + +#: graphicswin.cpp:167 +msgid "&Analyze" +msgstr "&Analyse" + +#: graphicswin.cpp:168 +msgid "Measure &Volume" +msgstr "Mesure &Volume" + +#: graphicswin.cpp:169 +msgid "Measure A&rea" +msgstr "Mesure &Aire" + +#: graphicswin.cpp:170 +msgid "Measure &Perimeter" +msgstr "Mesure &Périmètre" + +#: graphicswin.cpp:171 +msgid "Show &Interfering Parts" +msgstr "Montrer les Pièces &Interférentes" + +#: graphicswin.cpp:172 +msgid "Show &Naked Edges" +msgstr "Montrer les Arêtes &Nues" + +#: graphicswin.cpp:173 +msgid "Show &Center of Mass" +msgstr "Montrer le &Centre de Gravité" + +#: graphicswin.cpp:175 +msgid "Show &Underconstrained Points" +msgstr "Montrer les &sous-contraintes Points" + +#: graphicswin.cpp:177 +msgid "&Trace Point" +msgstr "&Tracer Point" + +#: graphicswin.cpp:178 +msgid "&Stop Tracing..." +msgstr "&Arrêt Tracé..." + +#: graphicswin.cpp:179 +msgid "Step &Dimension..." +msgstr "Espacement &Dimension..." + +#: graphicswin.cpp:181 +msgid "&Help" +msgstr "&Aide" + +#: graphicswin.cpp:182 +msgid "&Language" +msgstr "&Langue" + +#: graphicswin.cpp:183 +msgid "&Website / Manual" +msgstr "&Site web / Manuel" + +#: graphicswin.cpp:185 +msgid "&About" +msgstr "&A propos" + +#: graphicswin.cpp:355 +msgid "(no recent files)" +msgstr "(pas de fichier récent)" + +#: graphicswin.cpp:363 +#, c-format +msgid "File '%s' does not exist." +msgstr "" + +#: graphicswin.cpp:725 +msgid "No workplane is active, so the grid will not appear." +msgstr "Pas de plan de travail actif, donc la grille ne va pas apparaître." + +#: graphicswin.cpp:740 +msgid "" +"The perspective factor is set to zero, so the view will always be a parallel " +"projection.\n" +"\n" +"For a perspective projection, modify the perspective factor in the " +"configuration screen. A value around 0.3 is typical." +msgstr "" +"Le facteur de perspective est réglé à 0, donc la vue restera une projection " +"parallèle.\n" +"\n" +"Pour une projection en perspective, modifiez le facteur de perspective dans " +"l'écran de configuration. Une valeur d'environ 0,3 est typique." + +#: graphicswin.cpp:819 +msgid "" +"Select a point; this point will become the center of the view on screen." +msgstr "" +"Sélectionnez un point. Ce point deviendra le centre de la vue à l'écran." + +#: graphicswin.cpp:1114 +msgid "No additional entities share endpoints with the selected entities." +msgstr "" +"Aucune entité supplémentaire ne partage des points d'extrémité avec les " +"entités sélectionnées." + +#: graphicswin.cpp:1132 +msgid "" +"To use this command, select a point or other entity from an linked part, or " +"make a link group the active group." +msgstr "" +"Pour utiliser cette commande, sélectionnez un point ou une autre entité à " +"partir d'une pièce liée ou créez un groupe de liens dans le groupe actif." + +#: graphicswin.cpp:1155 +msgid "" +"No workplane is active. Activate a workplane (with Sketch -> In Workplane) " +"to define the plane for the snap grid." +msgstr "" +"Aucun plan de travail n'est actif. Activez un plan de travail (avec Dessin -" +"> Dans plan de travail) pour définir le plan pour la grille d'accrochage." + +#: graphicswin.cpp:1162 +msgid "" +"Can't snap these items to grid; select points, text comments, or constraints " +"with a label. To snap a line, select its endpoints." +msgstr "" +"Impossible d'accrocher ces éléments à la grille. Sélectionnez des points, " +"des textes de commentaires ou des contraintes avec une étiquette. Pour " +"accrocher une ligne, sélectionnez ses points d'extrémité." + +#: graphicswin.cpp:1247 +msgid "No workplane selected. Activating default workplane for this group." +msgstr "" +"Aucun plan de travail sélectionné. Activation du plan de travail par défaut " +"pour ce groupe." + +#: graphicswin.cpp:1250 +msgid "" +"No workplane is selected, and the active group does not have a default " +"workplane. Try selecting a workplane, or activating a sketch-in-new-" +"workplane group." +msgstr "" +"Aucun plan de travail n'est sélectionné et le groupe actif n'a pas de plan " +"de travail par défaut. Essayez de sélectionner un plan de travail ou " +"d'activer un groupe de \"Dessin dans nouveau plan travail\"." + +#: graphicswin.cpp:1271 +msgid "" +"Bad selection for tangent arc at point. Select a single point, or select " +"nothing to set up arc parameters." +msgstr "" +"Mauvaise sélection pour l'arc tangent au point. Sélectionnez un seul point, " +"ou ne sélectionnez rien pour configurer les paramètres de l'arc." + +#: graphicswin.cpp:1282 +msgid "click point on arc (draws anti-clockwise)" +msgstr "" +"cliquez un point sur l'arc (dessine dans le sens inverse des aiguilles d'une " +"montre)" + +#: graphicswin.cpp:1283 +msgid "click to place datum point" +msgstr "cliquez pour placer un point" + +#: graphicswin.cpp:1284 +msgid "click first point of line segment" +msgstr "cliquez le premier point du segment de ligne" + +#: graphicswin.cpp:1286 +msgid "click first point of construction line segment" +msgstr "cliquez le premier point de la ligne de construction" + +#: graphicswin.cpp:1287 +msgid "click first point of cubic segment" +msgstr "cliquez le premier point du segment cubique" + +#: graphicswin.cpp:1288 +msgid "click center of circle" +msgstr "cliquez pour placer le centre du cercle" + +#: graphicswin.cpp:1289 +msgid "click origin of workplane" +msgstr "cliquez pour placer l'origine du plan de travail" + +#: graphicswin.cpp:1290 +msgid "click one corner of rectangle" +msgstr "cliquez un coin du rectangle" + +#: graphicswin.cpp:1291 +msgid "click top left of text" +msgstr "cliquez le haut à gauche du texte" + +#: graphicswin.cpp:1297 +msgid "click top left of image" +msgstr "cliquez le haut à gauche de l'image" + +#: graphicswin.cpp:1309 +msgid "" +"No entities are selected. Select entities before trying to toggle their " +"construction state." +msgstr "" +"Aucune entité n'est sélectionnée. Sélectionnez les entités avant d'essayer " +"de basculer leurs états de construction." + +#: group.cpp:86 +msgctxt "group-name" +msgid "sketch-in-3d" +msgstr "dessin-en-3d" + +#: group.cpp:142 +msgid "" +"Bad selection for new sketch in workplane. This group can be created with:\n" +"\n" +" * a point (through the point, orthogonal to coordinate axes)\n" +" * a point and two line segments (through the point, parallel to the " +"lines)\n" +" * a workplane (copy of the workplane)\n" +msgstr "" +"Mauvaise sélection pour un nouveau dessin dans le plan de travail. Ce groupe " +"peut être créé avec:\n" +"\n" +"    * Un point (par le point, orthogonal aux axes de coordonnées)\n" +"    * Un point et deux segments de ligne (par le point, parallèle aux " +"lignes)\n" +"    * Un plan de travail (copie du plan de travail)\n" + +#: group.cpp:154 +msgid "" +"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch " +"will be extruded normal to the workplane." +msgstr "" +"Activez un plan de travail (Dessin -> Dans plan de travail) avant " +"l'extrusion. Le croquis sera extrudé normalement au plan de travail." + +#: group.cpp:163 +msgctxt "group-name" +msgid "extrude" +msgstr "extruder" + +#: group.cpp:168 +msgid "Lathe operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:179 +msgid "" +"Bad selection for new lathe group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" +"Mauvaise sélection pour un nouveau groupe de révolution. Ce groupe peut être " +"créé avec:\n" +"\n" +"    * Un point et un segment de ligne ou normal (révolution autour d'un axe " +"parallèle à la ligne / point normal, par le point)\n" +"    * Un segment de ligne (révolution sur le segment de ligne)\n" + +#: group.cpp:189 +msgctxt "group-name" +msgid "lathe" +msgstr "révolution" + +#: group.cpp:194 +msgid "Revolve operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:205 +msgid "" +"Bad selection for new revolve group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" + +#: group.cpp:217 +msgctxt "group-name" +msgid "revolve" +msgstr "" + +#: group.cpp:222 +msgid "Helix operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:233 +msgid "" +"Bad selection for new helix group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" + +#: group.cpp:245 +msgctxt "group-name" +msgid "helix" +msgstr "" + +#: group.cpp:258 +msgid "" +"Bad selection for new rotation. This group can be created with:\n" +"\n" +" * a point, while locked in workplane (rotate in plane, about that " +"point)\n" +" * a point and a line or a normal (rotate about an axis through the " +"point, and parallel to line / normal)\n" +msgstr "" +"Mauvaise sélection pour une nouvelle rotation. Ce groupe peut être créé " +"avec:\n" +"\n" +"    * Un point, lorsqu'il est verrouillé dans un plan de travail (rotation " +"dans le plan, autour de ce point)\n" +"    * Un point et une ligne ou une normale (tourner autour d'un axe par le " +"point et parallèle à la ligne / normale)\n" + +#: group.cpp:271 +msgctxt "group-name" +msgid "rotate" +msgstr "rotation" + +#: group.cpp:282 +msgctxt "group-name" +msgid "translate" +msgstr "translation" + +#: group.cpp:400 +msgid "(unnamed)" +msgstr "(sans nom)" + +#: groupmesh.cpp:709 +msgid "not closed contour, or not all same style!" +msgstr "contour non fermé ou tout n'est pas du même style!" + +#: groupmesh.cpp:722 +msgid "points not all coplanar!" +msgstr "les points ne sont pas tous coplanaires!" + +#: groupmesh.cpp:724 +msgid "contour is self-intersecting!" +msgstr "le contour s'entrecroise!" + +#: groupmesh.cpp:726 +msgid "zero-length edge!" +msgstr "arête de longueur nulle!" + +#: modify.cpp:254 +msgid "Must be sketching in workplane to create tangent arc." +msgstr "Vous devez dessiner dans un plan pour créer un arc tangent." + +#: modify.cpp:301 +msgid "" +"To create a tangent arc, select a point where two non-construction lines or " +"circles in this group and workplane join." +msgstr "" +"Pour créer un arc tangent, sélectionnez un point où deux lignes (pas de " +"construction) ou cercles de ce groupe et de ce plan se joignent." + +#: modify.cpp:388 +msgid "" +"Couldn't round this corner. Try a smaller radius, or try creating the " +"desired geometry by hand with tangency constraints." +msgstr "" +"Impossible d'arrondir ce coin. Essayez un rayon plus petit, ou essayez de " +"créer la géométrie souhaitée à la main avec des contraintes tangentielles." + +#: modify.cpp:597 +msgid "Couldn't split this entity; lines, circles, or cubics only." +msgstr "" +"Impossible de diviser cette entité; Lignes, cercles ou cubiques uniquement." + +#: modify.cpp:624 +msgid "Must be sketching in workplane to split." +msgstr "Vous devez dessiner dans un plan de travail pour diviser." + +#: modify.cpp:631 +msgid "" +"Select two entities that intersect each other (e.g. two lines/circles/arcs " +"or a line/circle/arc and a point)." +msgstr "" + +#: modify.cpp:736 +msgid "Can't split; no intersection found." +msgstr "Impossible de diviser; pas d'intersection trouvée." + +#: mouse.cpp:560 +msgid "Assign to Style" +msgstr "Appliquer au style" + +#: mouse.cpp:576 +msgid "No Style" +msgstr "Pas de style" + +#: mouse.cpp:579 +msgid "Newly Created Custom Style..." +msgstr "Style personnalisé nouvellement créé ..." + +#: mouse.cpp:586 +msgid "Group Info" +msgstr "Info Groupe" + +#: mouse.cpp:606 +msgid "Style Info" +msgstr "Info Style" + +#: mouse.cpp:626 +msgid "Select Edge Chain" +msgstr "Sélection Chaîne d'arêtes" + +#: mouse.cpp:632 +msgid "Toggle Reference Dimension" +msgstr "Basculer cote maîtresse / cote indicative" + +#: mouse.cpp:638 +msgid "Other Supplementary Angle" +msgstr "Autre angle supplémentaire" + +#: mouse.cpp:643 +msgid "Snap to Grid" +msgstr "Accrocher à la grille" + +#: mouse.cpp:652 +msgid "Remove Spline Point" +msgstr "Effacer le point de la Spline" + +#: mouse.cpp:687 +msgid "Add Spline Point" +msgstr "Ajouter un point à la Spline" + +#: mouse.cpp:691 +msgid "Cannot add spline point: maximum number of points reached." +msgstr "" +"Impossible d'ajouter le point spline: nombre maximum de points atteints." + +#: mouse.cpp:716 +msgid "Toggle Construction" +msgstr "Basculer en mode \"construction\"." + +#: mouse.cpp:731 +msgid "Delete Point-Coincident Constraint" +msgstr "Effacer la contraint Point-Coïncident" + +#: mouse.cpp:750 +msgid "Cut" +msgstr "Couper" + +#: mouse.cpp:752 +msgid "Copy" +msgstr "Copier" + +#: mouse.cpp:756 +msgid "Select All" +msgstr "Sélectionner tout" + +#: mouse.cpp:761 +msgid "Paste" +msgstr "Coller" + +#: mouse.cpp:763 +msgid "Paste Transformed..." +msgstr "Coller transformé..." + +#: mouse.cpp:768 +msgid "Delete" +msgstr "Effacer" + +#: mouse.cpp:771 +msgid "Unselect All" +msgstr "Désélectionner tout" + +#: mouse.cpp:778 +msgid "Unselect Hovered" +msgstr "Désélectionner survolé" + +#: mouse.cpp:787 +msgid "Zoom to Fit" +msgstr "Zoom pour ajuster" + +#: mouse.cpp:989 mouse.cpp:1276 +msgid "click next point of line, or press Esc" +msgstr "cliquez pou le prochain point de ligne or appuyez sur Esc" + +#: mouse.cpp:995 +msgid "" +"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" +"Impossible de dessiner un rectangle en 3d; D'abord, activez un plan de " +"travail avec \"Dessin -> Dans plan de travail\"." + +#: mouse.cpp:1029 +msgid "click to place other corner of rectangle" +msgstr "cliquez pour placer un autre coin de rectangle" + +#: mouse.cpp:1049 +msgid "click to set radius" +msgstr "cliquez pour ajuster le rayon" + +#: mouse.cpp:1054 +msgid "" +"Can't draw arc in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" +"Ne peut pas dessiner l'arc en 3d; D'abord, activez un plan de travail avec " +"\"Dessin -> Dans plan de travail\"." + +#: mouse.cpp:1073 +msgid "click to place point" +msgstr "cliquez pour placer un point" + +#: mouse.cpp:1089 +msgid "click next point of cubic, or press Esc" +msgstr "cliquez le prochain point cubique ou appuyez sur Esc" + +#: mouse.cpp:1094 +msgid "" +"Sketching in a workplane already; sketch in 3d before creating new workplane." +msgstr "" +"Vous dessinez déjà dans un plan de travail; Sélectionner \"Dessiner en 3d\" " +"avant de créer un nouveau plan de travail." + +#: mouse.cpp:1110 +msgid "" +"Can't draw text in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" +"Impossible de dessiner du texte en 3d; D'abord, activer un plan de travail " +"avec \"Dessin -> Dans plan de travail\"." + +#: mouse.cpp:1127 +msgid "click to place bottom right of text" +msgstr "" + +#: mouse.cpp:1133 +msgid "" +"Can't draw image in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" +"Impossible de dessiner l'image en 3d; D'abord, activez un plan de travail " +"avec \"Dessin -> Dans plan de travail\"." + +#: mouse.cpp:1160 +msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" +msgstr "NOUVEAU COMMENTAIRE - DOUBLE-CLIQUE POUR EDITER" + +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511 +msgctxt "file-type" +msgid "SolveSpace models" +msgstr "" + +#: platform/gui.cpp:90 +msgctxt "file-type" +msgid "IDF circuit board" +msgstr "" + +#: platform/gui.cpp:94 +msgctxt "file-type" +msgid "PNG image" +msgstr "" + +#: platform/gui.cpp:98 +msgctxt "file-type" +msgid "STL mesh" +msgstr "" + +#: platform/gui.cpp:99 +msgctxt "file-type" +msgid "Wavefront OBJ mesh" +msgstr "" + +#: platform/gui.cpp:100 +msgctxt "file-type" +msgid "Three.js-compatible mesh, with viewer" +msgstr "" + +#: platform/gui.cpp:101 +msgctxt "file-type" +msgid "Three.js-compatible mesh, mesh only" +msgstr "" + +#: platform/gui.cpp:102 +msgctxt "file-type" +msgid "VRML text file" +msgstr "" + +#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 +msgctxt "file-type" +msgid "STEP file" +msgstr "" + +#: platform/gui.cpp:110 +msgctxt "file-type" +msgid "PDF file" +msgstr "" + +#: platform/gui.cpp:111 +msgctxt "file-type" +msgid "Encapsulated PostScript" +msgstr "" + +#: platform/gui.cpp:112 +msgctxt "file-type" +msgid "Scalable Vector Graphics" +msgstr "" + +#: platform/gui.cpp:114 platform/gui.cpp:121 +msgctxt "file-type" +msgid "DXF file (AutoCAD 2007)" +msgstr "" + +#: platform/gui.cpp:115 +msgctxt "file-type" +msgid "HPGL file" +msgstr "" + +#: platform/gui.cpp:116 +msgctxt "file-type" +msgid "G Code" +msgstr "" + +#: platform/gui.cpp:125 +msgctxt "file-type" +msgid "AutoCAD DXF and DWG files" +msgstr "" + +#: platform/gui.cpp:129 +msgctxt "file-type" +msgid "Comma-separated values" +msgstr "" + +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 +msgid "untitled" +msgstr "sans nom" + +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1573 +msgctxt "title" +msgid "Save File" +msgstr "Sauver fichier" + +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1575 +msgctxt "title" +msgid "Open File" +msgstr "Ouvrir Fichier" + +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 +msgctxt "button" +msgid "_Cancel" +msgstr "_Annuler" + +#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 +msgctxt "button" +msgid "_Save" +msgstr "_Sauver" + +#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 +msgctxt "button" +msgid "_Open" +msgstr "" + +#: solvespace.cpp:169 +msgctxt "title" +msgid "Autosave Available" +msgstr "Sauvegarde automatique existante" + +#: solvespace.cpp:170 +msgctxt "dialog" +msgid "An autosave file is available for this sketch." +msgstr "" + +#: solvespace.cpp:171 +msgctxt "dialog" +msgid "Do you want to load the autosave file instead?" +msgstr "" + +#: solvespace.cpp:172 +msgctxt "button" +msgid "&Load autosave" +msgstr "" + +#: solvespace.cpp:174 +msgctxt "button" +msgid "Do&n't Load" +msgstr "" + +#: solvespace.cpp:557 +msgctxt "title" +msgid "Modified File" +msgstr "Fichier modifié" + +#: solvespace.cpp:559 +#, c-format +msgctxt "dialog" +msgid "Do you want to save the changes you made to the sketch “%s”?" +msgstr "" + +#: solvespace.cpp:562 +msgctxt "dialog" +msgid "Do you want to save the changes you made to the new sketch?" +msgstr "" + +#: solvespace.cpp:565 +msgctxt "dialog" +msgid "Your changes will be lost if you don't save them." +msgstr "" + +#: solvespace.cpp:566 +msgctxt "button" +msgid "&Save" +msgstr "" + +#: solvespace.cpp:568 +msgctxt "button" +msgid "Do&n't Save" +msgstr "" + +#: solvespace.cpp:589 +msgctxt "title" +msgid "(new sketch)" +msgstr "(nouveau dessin)" + +#: solvespace.cpp:596 +msgctxt "title" +msgid "Property Browser" +msgstr "Navigateur de propriété" + +#: solvespace.cpp:658 +msgid "" +"Constraints are currently shown, and will be exported in the toolpath. This " +"is probably not what you want; hide them by clicking the link at the top of " +"the text window." +msgstr "" + +#: solvespace.cpp:730 +#, c-format +msgid "" +"Can't identify file type from file extension of filename '%s'; try .dxf or ." +"dwg." +msgstr "" + +#: solvespace.cpp:778 +msgid "Constraint must have a label, and must not be a reference dimension." +msgstr "" + +#: solvespace.cpp:782 +msgid "Bad selection for step dimension; select a constraint." +msgstr "" + +#: solvespace.cpp:806 +msgid "The assembly does not interfere, good." +msgstr "" + +#: solvespace.cpp:822 +#, c-format +msgid "" +"The volume of the solid model is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:831 +#, c-format +msgid "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:836 +msgid "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." +msgstr "" + +#: solvespace.cpp:851 +#, c-format +msgid "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:860 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." +msgstr "" + +#: solvespace.cpp:872 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:892 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:898 +msgid "Bad selection for perimeter; select line segments, arcs, and curves." +msgstr "" + +#: solvespace.cpp:914 +msgid "Bad selection for trace; select a single point." +msgstr "" + +#: solvespace.cpp:941 +#, c-format +msgid "Couldn't write to '%s'" +msgstr "" + +#: solvespace.cpp:971 +msgid "The mesh is self-intersecting (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:972 +msgid "The mesh is not self-intersecting (okay, valid)." +msgstr "" + +#: solvespace.cpp:974 +msgid "The mesh has naked edges (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:975 +msgid "The mesh is watertight (okay, valid)." +msgstr "" + +#: solvespace.cpp:978 +#, c-format +msgid "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." +msgstr "" + +#: solvespace.cpp:982 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" + +#: solvespace.cpp:985 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" + +#: solvespace.cpp:998 +#, c-format +msgid "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" +msgstr "" + +#: style.cpp:166 +msgid "" +"Can't assign style to an entity that's derived from another entity; try " +"assigning a style to this entity's parent." +msgstr "" +"Impossible d'attribuer le style à une entité dérivée d'une autre entité; " +"Essayez d'attribuer un style au parent de cette entité." + +#: style.cpp:665 +msgid "Style name cannot be empty" +msgstr "Le nom d'un style ne peut pas être vide" + +#: textscreens.cpp:741 +msgid "Can't repeat fewer than 1 time." +msgstr "Je ne peux pas répéter moins de 1 fois." + +#: textscreens.cpp:745 +msgid "Can't repeat more than 999 times." +msgstr "Je ne peux pas répéter plus de 999 fois." + +#: textscreens.cpp:770 +msgid "Group name cannot be empty" +msgstr "Un nom de groupe ne peut pas être vide" + +#: textscreens.cpp:813 +msgid "Opacity must be between zero and one." +msgstr "L'opacité doit être entre 0 et 1." + +#: textscreens.cpp:848 +msgid "Radius cannot be zero or negative." +msgstr "Le rayon ne peut pas être zéro ou négatif." + +#: toolbar.cpp:18 +msgid "Sketch line segment" +msgstr "Dessin ligne - polyligne" + +#: toolbar.cpp:20 +msgid "Sketch rectangle" +msgstr "Dessin d'un rectangle" + +#: toolbar.cpp:22 +msgid "Sketch circle" +msgstr "Dessin d'un cercle" + +#: toolbar.cpp:24 +msgid "Sketch arc of a circle" +msgstr "Dessin d'un arc de cercle" + +#: toolbar.cpp:26 +msgid "Sketch curves from text in a TrueType font" +msgstr "Dessin de courbes depuis un texte en police TrueType" + +#: toolbar.cpp:28 +msgid "Sketch image from a file" +msgstr "Dessin d'une image depuis un fichier" + +#: toolbar.cpp:30 +msgid "Create tangent arc at selected point" +msgstr "Créer un arc tangent au point sélectionné" + +#: toolbar.cpp:32 +msgid "Sketch cubic Bezier spline" +msgstr "Dessin d'une spline cubique de Bezier" + +#: toolbar.cpp:34 +msgid "Sketch datum point" +msgstr "Dessin d'un point" + +#: toolbar.cpp:36 +msgid "Toggle construction" +msgstr "Basculer en mode \"construction\"" + +#: toolbar.cpp:38 +msgid "Split lines / curves where they intersect" +msgstr "Diviser lignes / courbes où elles se croisent" + +#: toolbar.cpp:42 +msgid "Constrain distance / diameter / length" +msgstr "Contraindre distance / diamètre / longueur" + +#: toolbar.cpp:44 +msgid "Constrain angle" +msgstr "Contraindre angle" + +#: toolbar.cpp:46 +msgid "Constrain to be horizontal" +msgstr "Contraindre à être horizontal" + +#: toolbar.cpp:48 +msgid "Constrain to be vertical" +msgstr "Contraindre à être vertical" + +#: toolbar.cpp:50 +msgid "Constrain to be parallel or tangent" +msgstr "Contraindre à être parallèle ou tangent" + +#: toolbar.cpp:52 +msgid "Constrain to be perpendicular" +msgstr "Contraindre à être perpendiculaire" + +#: toolbar.cpp:54 +msgid "Constrain point on line / curve / plane / point" +msgstr "Contraindre point sur ligne / courbe / plan / point" + +#: toolbar.cpp:56 +msgid "Constrain symmetric" +msgstr "Contrainte symétrique" + +#: toolbar.cpp:58 +msgid "Constrain equal length / radius / angle" +msgstr "Contrainte égale longueur / rayon / angle" + +#: toolbar.cpp:60 +msgid "Constrain normals in same orientation" +msgstr "Contrainte normales dans la même direction" + +#: toolbar.cpp:62 +msgid "Other supplementary angle" +msgstr "Autre angle supplémentaire" + +#: toolbar.cpp:64 +msgid "Toggle reference dimension" +msgstr "Basculer cote maîtresse / cote indicative" + +#: toolbar.cpp:68 +msgid "New group extruding active sketch" +msgstr "Nouveau groupe d'extrusion du dessin actif" + +#: toolbar.cpp:70 +msgid "New group rotating active sketch" +msgstr "Nouveau groupe de révolution du dessin actif" + +#: toolbar.cpp:72 +msgid "New group helix from active sketch" +msgstr "" + +#: toolbar.cpp:74 +msgid "New group revolve active sketch" +msgstr "" + +#: toolbar.cpp:76 +msgid "New group step and repeat rotating" +msgstr "Nouveau groupe de répétition circulaire" + +#: toolbar.cpp:78 +msgid "New group step and repeat translating" +msgstr "Nouveau groupe de répétition linéaire" + +#: toolbar.cpp:80 +msgid "New group in new workplane (thru given entities)" +msgstr "" +"Nouveau groupe dans un nouveau plan de travail (Par des entités données)" + +#: toolbar.cpp:82 +msgid "New group in 3d" +msgstr "Nouveau groupe en 3d" + +#: toolbar.cpp:84 +msgid "New group linking / assembling file" +msgstr "Nouveau groupe lié / assemblage" + +#: toolbar.cpp:88 +msgid "Nearest isometric view" +msgstr "Vue isométrique la plus proche" + +#: toolbar.cpp:90 +msgid "Align view to active workplane" +msgstr "Aligner la vue sur le plan de travail actif" + +#: util.cpp:165 +msgctxt "title" +msgid "Error" +msgstr "Erreur" + +#: util.cpp:165 +msgctxt "title" +msgid "Message" +msgstr "Message" + +#: util.cpp:170 +msgctxt "button" +msgid "&OK" +msgstr "" + +#: view.cpp:78 +msgid "Scale cannot be zero or negative." +msgstr "L'échelle ne peut pas être zéro ou négative." + +#: view.cpp:90 view.cpp:99 +msgid "Bad format: specify x, y, z" +msgstr "Mauvais format: Spécifiez x, y, z" + +#~ msgid "Specify between 0 and 8 digits after the decimal." +#~ msgstr "Spécifiez entre 0 et 8 chiffres après la virgule." + +#~ msgid "Show Degrees of &Freedom" +#~ msgstr "Montrer les Degrés de &Liberté" + +#~ msgid "click to place bottom left of text" +#~ msgstr "cliquez pour placer le bas gauche du texte" + +#~ msgid "Do you want to save the changes you made to the new sketch?" +#~ msgstr "" +#~ "Voulez-vous enregistrer les modifications que vous avez apportées au " +#~ "nouveau dessin?" + +#~ msgid "Your changes will be lost if you don't save them." +#~ msgstr "Vos modifications seront perdues si vous ne les enregistrez pas." + +#~ msgctxt "button" +#~ msgid "Save" +#~ msgstr "Sauver" + +#~ msgctxt "button" +#~ msgid "Cancel" +#~ msgstr "Annuler" + +#~ msgctxt "button" +#~ msgid "Don't Save" +#~ msgstr "Ne pas sauver" + +#~ msgid "Do you want to load the autosave file instead?" +#~ msgstr "Voulez-vous charger le fichier de sauvegarde à la place?" + +#~ msgctxt "button" +#~ msgid "Load" +#~ msgstr "Charger" + +#~ msgctxt "button" +#~ msgid "Don't Load" +#~ msgstr "Ne pas charger" + +#~ msgid "" +#~ "Do you want to locate it manually?\n" +#~ "If you select “No”, any geometry that depends on the missing file will be " +#~ "removed." +#~ msgstr "" +#~ "Voulez-vous le localiser manuellement?\n" +#~ "Si vous sélectionnez \"Non\", toute géométrie qui dépend du fichier " +#~ "manquant sera supprimée." + +#~ msgctxt "button" +#~ msgid "Yes" +#~ msgstr "Oui" + +#~ msgctxt "button" +#~ msgid "No" +#~ msgstr "Non" + +#~ msgctxt "button" +#~ msgid "OK" +#~ msgstr "Valider" + +#~ msgid "_Cancel" +#~ msgstr "_Annuler" + +#~ msgid "_Open" +#~ msgstr "_Ouvrir" + +#~ msgid "" +#~ "The file has changed since it was last saved.\n" +#~ "\n" +#~ "Do you want to save the changes?" +#~ msgstr "" +#~ "Le fichier a changé depuis sa dernière sauvegarde.\n" +#~ "\n" +#~ "Voulez-vous enregistrer les modifications?" + +#~ msgctxt "button" +#~ msgid "Do_n't Save" +#~ msgstr "_Ne pas sauver" + +#~ msgctxt "button" +#~ msgid "_Load autosave" +#~ msgstr "_Charger la sauvegarde automatique" + +#~ msgctxt "button" +#~ msgid "Do_n't Load" +#~ msgstr "_Ne pas charger" + +#~ msgctxt "button" +#~ msgid "_Yes" +#~ msgstr "_Oui" + +#~ msgctxt "button" +#~ msgid "_No" +#~ msgstr "_Non" + +#~ msgid "SolveSpace models" +#~ msgstr "Modèles SolveSpace" + +#~ msgid "PNG file" +#~ msgstr "Fichier PNG" + +#~ msgid "STL mesh" +#~ msgstr "Maillage STL" + +#~ msgid "Wavefront OBJ mesh" +#~ msgstr "Maillage Wavefront OBJ" + +#~ msgid "Three.js-compatible mesh, with viewer" +#~ msgstr "Maillage Three-js-compatible, avec visualisateur" + +#~ msgid "Three.js-compatible mesh, mesh only" +#~ msgstr "Maillage Three-js-compatible, maillage seul" + +#~ msgid "STEP file" +#~ msgstr "Fichier STEP" + +#~ msgid "PDF file" +#~ msgstr "Fichier PDF" + +#~ msgid "Encapsulated PostScript" +#~ msgstr "Encapsulated PostScript" + +#~ msgid "Scalable Vector Graphics" +#~ msgstr "Scalable Vector Graphics" + +#~ msgid "DXF file (AutoCAD 2007)" +#~ msgstr "Fichier DXF (AutoCAD 2007)" + +#~ msgid "HPGL file" +#~ msgstr "Fichier HPGL" + +#~ msgid "G Code" +#~ msgstr "G Code" + +#~ msgid "AutoCAD DXF and DWG files" +#~ msgstr "Fichiers AutoCAD DXF et DWG" + +#~ msgid "Comma-separated values" +#~ msgstr "Valeurs CSV séparées par des virgules" diff --git a/res/locales/ru_RU.po b/res/locales/ru_RU.po new file mode 100644 index 0000000..8cc4e60 --- /dev/null +++ b/res/locales/ru_RU.po @@ -0,0 +1,2247 @@ +# Russian translations for SolveSpace package. +# Copyright (C) 2017 the SolveSpace authors +# This file is distributed under the same license as the SolveSpace package. +# EvilSpirit , 2017. +msgid "" +msgstr "" +"Project-Id-Version: SolveSpace 3.0\n" +"Report-Msgid-Bugs-To: whitequark@whitequark.org\n" +"POT-Creation-Date: 2021-01-17 19:54+0200\n" +"PO-Revision-Date: 2017-04-21 10:29+0700\n" +"Last-Translator: evilspirit@evilspirit.org\n" +"Language-Team: EvilSpirit\n" +"Language: ru_RU\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.0.1\n" + +#: clipboard.cpp:310 +msgid "" +"Cut, paste, and copy work only in a workplane.\n" +"\n" +"Activate one with Sketch -> In Workplane." +msgstr "" +"Копировать, вставить или вырезать\n" +"можно только находясь в рабочей плоскости.\n" +"Активируйте рабочую плоскость через Эскиз->В Рабочей Плоскости" + +#: clipboard.cpp:327 +msgid "Clipboard is empty; nothing to paste." +msgstr "Буфер обмена пуст; нечего вставлять." + +#: clipboard.cpp:374 +msgid "Number of copies to paste must be at least one." +msgstr "Укажите в поле 'количество' хотя бы одну копию для вставки." + +#: clipboard.cpp:390 textscreens.cpp:783 +msgid "Scale cannot be zero." +msgstr "Масштабный коэффициент не может быть нулевым." + +#: clipboard.cpp:432 +msgid "Select one point to define origin of rotation." +msgstr "Выберите одну точку в качестве центра вращения." + +#: clipboard.cpp:444 +msgid "Select two points to define translation vector." +msgstr "Выберите две точки, чтобы задать вектор смещения." + +#: clipboard.cpp:454 +msgid "" +"Transformation is identity. So all copies will be exactly on top of each " +"other." +msgstr "" +"Трансформация не задана. Все копии будут расположены в одном и том же месте." + +#: clipboard.cpp:458 +msgid "Too many items to paste; split this into smaller pastes." +msgstr "Слишком много элементов для вставки; разбейте на несколько частей." + +#: clipboard.cpp:463 +msgid "No workplane active." +msgstr "Рабочая плоскость не активна" + +#: confscreen.cpp:418 +msgid "Bad format: specify coordinates as x, y, z" +msgstr "Неверный формат: введите координаты как x, y, z" + +#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805 +msgid "Bad format: specify color as r, g, b" +msgstr "Неверный формат: введите цвет как r, g, b" + +#: confscreen.cpp:454 +msgid "" +"The perspective factor will have no effect until you enable View -> Use " +"Perspective Projection." +msgstr "" +"Коэффициент перспективы не будет иметь эффект, пока вы не включите Вид-" +">Перспективная Проекция." + +#: confscreen.cpp:467 confscreen.cpp:477 +#, c-format +msgid "Specify between 0 and %d digits after the decimal." +msgstr "Введите число от 0 до %d." + +#: confscreen.cpp:489 +msgid "Export scale must not be zero!" +msgstr "Масштабный коэффициент не может быть нулевым!" + +#: confscreen.cpp:501 +msgid "Cutter radius offset must not be negative!" +msgstr "Радиус режущего инструмента не может быть отрицательным!" + +#: confscreen.cpp:555 +msgid "Bad value: autosave interval should be positive" +msgstr "" +"Неверное значение: интервал автосохранения должен быть положительным числом" + +#: confscreen.cpp:558 +msgid "Bad format: specify interval in integral minutes" +msgstr "" +"Неверный формат: введите целое число, чтобы задать интервал автосохранения" + +#: constraint.cpp:12 +msgctxt "constr-name" +msgid "pts-coincident" +msgstr "тчк-тчк-совпадение" + +#: constraint.cpp:13 +msgctxt "constr-name" +msgid "pt-pt-distance" +msgstr "тчк-тчк-расстояние" + +#: constraint.cpp:14 +msgctxt "constr-name" +msgid "pt-line-distance" +msgstr "тчк-линия-расстояние" + +#: constraint.cpp:15 +msgctxt "constr-name" +msgid "pt-plane-distance" +msgstr "тчк-плоск-расстояние" + +#: constraint.cpp:16 +msgctxt "constr-name" +msgid "pt-face-distance" +msgstr "тчк-грань-расстояние" + +#: constraint.cpp:17 +msgctxt "constr-name" +msgid "proj-pt-pt-distance" +msgstr "проекц-тчк-тчк-расст" + +#: constraint.cpp:18 +msgctxt "constr-name" +msgid "pt-in-plane" +msgstr "тчк-на-плоск" + +#: constraint.cpp:19 +msgctxt "constr-name" +msgid "pt-on-line" +msgstr "тчк-на-линии" + +#: constraint.cpp:20 +msgctxt "constr-name" +msgid "pt-on-face" +msgstr "тчк-на-грани" + +#: constraint.cpp:21 +msgctxt "constr-name" +msgid "eq-length" +msgstr "равенство-длин" + +#: constraint.cpp:22 +msgctxt "constr-name" +msgid "eq-length-and-pt-ln-dist" +msgstr "равен-длины-и-тчк-лин-расст" + +#: constraint.cpp:23 +msgctxt "constr-name" +msgid "eq-pt-line-distances" +msgstr "равен-тчк-линия-расстояний" + +#: constraint.cpp:24 +msgctxt "constr-name" +msgid "length-ratio" +msgstr "отношение-длин" + +#: constraint.cpp:25 +msgctxt "constr-name" +msgid "length-difference" +msgstr "разность-длин" + +#: constraint.cpp:26 +msgctxt "constr-name" +msgid "symmetric" +msgstr "симметричность" + +#: constraint.cpp:27 +msgctxt "constr-name" +msgid "symmetric-h" +msgstr "симметричность-гориз" + +#: constraint.cpp:28 +msgctxt "constr-name" +msgid "symmetric-v" +msgstr "симметричность-верт" + +#: constraint.cpp:29 +msgctxt "constr-name" +msgid "symmetric-line" +msgstr "симметричность-по-оси" + +#: constraint.cpp:30 +msgctxt "constr-name" +msgid "at-midpoint" +msgstr "на-середине" + +#: constraint.cpp:31 +msgctxt "constr-name" +msgid "horizontal" +msgstr "горизонтальность" + +#: constraint.cpp:32 +msgctxt "constr-name" +msgid "vertical" +msgstr "вертикальность" + +#: constraint.cpp:33 +msgctxt "constr-name" +msgid "diameter" +msgstr "диаметр" + +#: constraint.cpp:34 +msgctxt "constr-name" +msgid "pt-on-circle" +msgstr "тчк-на-окружности" + +#: constraint.cpp:35 +msgctxt "constr-name" +msgid "same-orientation" +msgstr "идентичная-ориентация" + +#: constraint.cpp:36 +msgctxt "constr-name" +msgid "angle" +msgstr "угол" + +#: constraint.cpp:37 +msgctxt "constr-name" +msgid "parallel" +msgstr "параллельность" + +#: constraint.cpp:38 +msgctxt "constr-name" +msgid "arc-line-tangent" +msgstr "кас-дуга-линия" + +#: constraint.cpp:39 +msgctxt "constr-name" +msgid "cubic-line-tangent" +msgstr "кас-сплайн-линия" + +#: constraint.cpp:40 +msgctxt "constr-name" +msgid "curve-curve-tangent" +msgstr "кас-кривых" + +#: constraint.cpp:41 +msgctxt "constr-name" +msgid "perpendicular" +msgstr "перпендикулярность" + +#: constraint.cpp:42 +msgctxt "constr-name" +msgid "eq-radius" +msgstr "равенство-радиусов" + +#: constraint.cpp:43 +msgctxt "constr-name" +msgid "eq-angle" +msgstr "равенство-углов" + +#: constraint.cpp:44 +msgctxt "constr-name" +msgid "eq-line-len-arc-len" +msgstr "равен-длины-линии-длины-дуги" + +#: constraint.cpp:45 +msgctxt "constr-name" +msgid "lock-where-dragged" +msgstr "фиксация" + +#: constraint.cpp:46 +msgctxt "constr-name" +msgid "comment" +msgstr "комментарий" + +#: constraint.cpp:140 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." +msgstr "" +"Дуга и отрезок должны быть соединены. Соедините их крайние точки с помощью " +"'Ограничения -> Точка на Примитиве' перед тем, как применять ограничение " +"касательности." + +#: constraint.cpp:158 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." +msgstr "" +"Сплайн и отрезок должны быть соединены. Соедините их крайние точки с помощью " +"'Ограничения -> Точка на Примитиве' перед тем, как применять ограничение " +"касательности." + +#: constraint.cpp:183 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." +msgstr "" +"Кривые должны быть соединены. Соедините их крайние точки с помощью " +"'Ограничения -> Точка на Примитиве' перед тем, как применять ограничение " +"касательности." + +#: constraint.cpp:231 +msgid "" +"Bad selection for distance / diameter constraint. This constraint can apply " +"to:\n" +"\n" +" * two points (distance between points)\n" +" * a line segment (length)\n" +" * two points and a line segment or normal (projected distance)\n" +" * a workplane and a point (minimum distance)\n" +" * a line segment and a point (minimum distance)\n" +" * a plane face and a point (minimum distance)\n" +" * a circle or an arc (diameter)\n" +msgstr "" +"Неправильное выделение для ограничения расстояния / диаметра.\n" +"Ограничение может принимать в качестве выделения следующие примитивы:\n" +"\n" +" * две точки (расстояние между точками)\n" +" * отрезок (длина отрезка)\n" +" * две точки и отрезок / нормаль (расстояние между точками, " +"спроецированное на линию / нормаль)\n" +" * рабочую плоскость и точку (расстояние от точки до плоскости)\n" +" * отрезок и точку (расстояние от точки до линии)\n" +" * грань и точку (расстояние от точки до плоскости грани)\n" +" * окружность или дугу (диаметр / радиус)\n" + +#: constraint.cpp:284 +msgid "" +"Bad selection for on point / curve / plane constraint. This constraint can " +"apply to:\n" +"\n" +" * two points (points coincident)\n" +" * a point and a workplane (point in plane)\n" +" * a point and a line segment (point on line)\n" +" * a point and a circle or arc (point on curve)\n" +" * a point and a plane face (point on face)\n" +msgstr "" +"Неправильное выделение для ограничения 'точка на примитиве'.\n" +"Ограничение может принимать в качестве выделения следующие примитивы:\n" +"\n" +" * две точки (совпадение точек)\n" +" * точку и рабочую плоскость (точка в плоскости)\n" +" * точку и отрезок (точка на линии)\n" +" * точку и окружность / дугу / сплайн (точка на кривой)\n" +" * точку и грань (точка на грани)\n" + +#: constraint.cpp:346 +msgid "" +"Bad selection for equal length / radius constraint. This constraint can " +"apply to:\n" +"\n" +" * two line segments (equal length)\n" +" * two line segments and two points (equal point-line distances)\n" +" * a line segment and two points (equal point-line distances)\n" +" * a line segment, and a point and line segment (point-line distance " +"equals length)\n" +" * four line segments or normals (equal angle between A,B and C,D)\n" +" * three line segments or normals (equal angle between A,B and B,C)\n" +" * two circles or arcs (equal radius)\n" +" * a line segment and an arc (line segment length equals arc length)\n" +msgstr "" +"Неправильное выделение для ограничения 'равенство примитивов'.\n" +"Ограничение может принимать в качестве выделения следующие примитивы:\n" +"\n" +" * два отрезка (равенство длин отрезков)\n" +" * два отрезка и две точки (равенство расстояний от точек до линий)\n" +" * отрезок и две точки (равенство расстояний от точек до линии)\n" +" * отрезок, точку и отрезок (равенство длины отрезка расстоянию от точки " +"до линии)\n" +" * четыре отрезка или нормали (равенство углов A,B и C,D)\n" +" * три отрезка или нормали (равенство углов A,B and B,C)\n" +" * две окружности / дуги (равенство радиусов)\n" +" * отрезок и дугу (равенство длины отрезка и длины дуги)\n" + +#: constraint.cpp:385 +msgid "" +"Bad selection for length ratio constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +msgstr "" +"Неправильное выделение для ограничения 'отношение длин'.\n" +"Ограничение может принимать в качестве выделения следующие примитивы:\n" +"\n" +" * два отрезка\n" + +#: constraint.cpp:402 +msgid "" +"Bad selection for length difference constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments\n" +msgstr "" +"Неправильное выделение для ограничения 'разница длин'.\n" +"Ограничение может принимать в качестве выделения следующие примитивы:\n" +"\n" +" * два отрезка\n" + +#: constraint.cpp:428 +msgid "" +"Bad selection for at midpoint constraint. This constraint can apply to:\n" +"\n" +" * a line segment and a point (point at midpoint)\n" +" * a line segment and a workplane (line's midpoint on plane)\n" +msgstr "" +"Неправильное выделение для ограничения 'на середине'.\n" +"Ограничение может принимать в качестве выделения следующие примитивы:\n" +"\n" +" * точку и отрезок (точка на середине отрезка)\n" +" * отрезок и рабочую плоскость (середина отрезка на плоскости)\n" + +#: constraint.cpp:486 +msgid "" +"Bad selection for symmetric constraint. This constraint can apply to:\n" +"\n" +" * two points or a line segment (symmetric about workplane's coordinate " +"axis)\n" +" * line segment, and two points or a line segment (symmetric about line " +"segment)\n" +" * workplane, and two points or a line segment (symmetric about " +"workplane)\n" +msgstr "" +"Неправильное выделение для ограничения 'симметрия'.\n" +"Ограничение может принимать в качестве выделения следующие примитивы:\n" +"\n" +" * две точки / отрезок (симметричность точек по горизонтали/вертикали в " +"зависимости от вида)\n" +" * отрезок, две точки / отрезок (симметричность точек по оси отрезка)\n" +" * рабочую плоскость и две точки / отрезок (симметричность относительно " +"рабочей плоскости\n" + +#: constraint.cpp:500 +msgid "" +"A workplane must be active when constraining symmetric without an explicit " +"symmetry plane." +msgstr "" +"Рабочая плоскость должна быть активна для того, чтобы создать\n" +"ограничение симметричности без явного указания плоскости симметрии." + +#: constraint.cpp:530 +msgid "" +"Activate a workplane (with Sketch -> In Workplane) before applying a " +"horizontal or vertical constraint." +msgstr "" +"Рабочая плоскость должна быть активирована (Эскиз -> В рабочей плоскости)\n" +"перед тем, как накладывать ограничения горизонтальности / вертикальности." + +#: constraint.cpp:543 +msgid "" +"Bad selection for horizontal / vertical constraint. This constraint can " +"apply to:\n" +"\n" +" * two points\n" +" * a line segment\n" +msgstr "" +"Неправильное выделение для ограничения 'горизонтальность / вертикальность'.\n" +"Ограничение может принимать в качестве выделения следующие примитивы:\n" +"\n" +" * две точки\n" +" * отрезок\n" + +#: constraint.cpp:564 +msgid "" +"Bad selection for same orientation constraint. This constraint can apply " +"to:\n" +"\n" +" * two normals\n" +msgstr "" +"Неправильное выделение для ограничения \"идентичная ориентация\".\n" +"Ограничение может принимать в качестве выделения следующие примитивы:\n" +"\n" +" * два координатных базиса('нормали')\n" + +#: constraint.cpp:614 +msgid "Must select an angle constraint." +msgstr "" +"Переключатся между смежными углами можно только выбрав ограничение угла." + +#: constraint.cpp:627 +msgid "Must select a constraint with associated label." +msgstr "" +"Переключать режим 'размера для справок' возможно только для ограничений, " +"имеющих размерное значение." + +#: constraint.cpp:638 +msgid "" +"Bad selection for angle constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" +"Неправильное выделение для ограничения углового размера.\n" +"Ограничение может принимать в качестве выделения следующие примитивы:\n" +"\n" +" * два отрезка\n" +" * отрезок и координатный базис (нормаль)\n" +" * два координатных базиса (нормали)\n" + +#: constraint.cpp:701 +msgid "Curve-curve tangency must apply in workplane." +msgstr "" +"Ограничение касательности может быть наложено только в рабочей плоскости." + +#: constraint.cpp:711 +msgid "" +"Bad selection for parallel / tangent constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments (parallel)\n" +" * a line segment and a normal (parallel)\n" +" * two normals (parallel)\n" +" * two line segments, arcs, or beziers, that share an endpoint (tangent)\n" +msgstr "" +"Неправильное выделение для ограничения параллельности / касательности.\n" +"Ограничение может принимать в качестве выделения следующие примитивы:\n" +"\n" +" * два отрезка (параллельность)\n" +" * отрезок и координатный базис (нормаль) (параллельность)\n" +" * два координатных базиса (нормали) (параллельность)\n" +" * два отрезка, две дуги или два сплайна, соединенных крайними точками " +"(касательность)\n" + +#: constraint.cpp:729 +msgid "" +"Bad selection for perpendicular constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" +"Неправильное выделение для ограничения перпендикулярности.\n" +"Ограничение может принимать в качестве выделения следующие примитивы:\n" +"\n" +" * два отрезка\n" +" * отрезок и координатный базис (нормаль)\n" +" * два координатных базиса (нормали)\n" + +#: constraint.cpp:744 +msgid "" +"Bad selection for lock point where dragged constraint. This constraint can " +"apply to:\n" +"\n" +" * a point\n" +msgstr "" +"Неправильное выделение для ограничения 'Фиксация'.\n" +"Ограничение может принимать в качестве выделения следующие примитивы:\n" +"\n" +" * точку\n" + +#: constraint.cpp:755 +msgid "click center of comment text" +msgstr "кликните мышью там, где будет расположен текстовый комментарий" + +#: export.cpp:19 +msgid "" +"No solid model present; draw one with extrudes and revolves, or use Export " +"2d View to export bare lines and curves." +msgstr "" + +#: export.cpp:61 +msgid "" +"Bad selection for export section. Please select:\n" +"\n" +" * nothing, with an active workplane (workplane is section plane)\n" +" * a face (section plane through face)\n" +" * a point and two line segments (plane through point and parallel to " +"lines)\n" +msgstr "" + +#: export.cpp:822 +msgid "Active group mesh is empty; nothing to export." +msgstr "" + +#: exportvector.cpp:337 +msgid "freehand lines were replaced with continuous lines" +msgstr "Стили линии 'от руки' были заменены сплошными линиями" + +#: exportvector.cpp:339 +msgid "zigzag lines were replaced with continuous lines" +msgstr "Стили линии 'зиг-заг' были заменены сплошными линиями" + +#: exportvector.cpp:593 +msgid "" +"Some aspects of the drawing have no DXF equivalent and were not exported:\n" +msgstr "" +"Некоторые элементы чертежа не имеют аналогов в DXF-представлении и не были " +"экспортированы:\n" + +#: exportvector.cpp:839 +msgid "" +"PDF page size exceeds 200 by 200 inches; many viewers may reject this file." +msgstr "" +"Размер страницы PDF превышает 200x200 дюймов; некоторые программы просмотра " +"не смогут прочитать такой файл." + +#: file.cpp:44 group.cpp:91 +msgctxt "group-name" +msgid "sketch-in-plane" +msgstr "эскиз-в-плоскости" + +#: file.cpp:62 +msgctxt "group-name" +msgid "#references" +msgstr "система-координат" + +#: file.cpp:549 +msgid "" +"Unrecognized data in file. This file may be corrupt, or from a newer version " +"of the program." +msgstr "" +"Некоторые данные из этого файла не распознаны. Возможно, файл поврежден или " +"создан в более новой версии программы" + +#: file.cpp:859 +msgctxt "title" +msgid "Missing File" +msgstr "Файл Отсутствует" + +#: file.cpp:860 +#, c-format +msgctxt "dialog" +msgid "The linked file “%s” is not present." +msgstr "" + +#: file.cpp:862 +msgctxt "dialog" +msgid "" +"Do you want to locate it manually?\n" +"\n" +"If you decline, any geometry that depends on the missing file will be " +"permanently removed." +msgstr "" +"Хотите найти их вручную?\n" +"Если вы ответите \"Нет\", то вся геометрия, которая зависит от " +"отсутствующего файла будет удалена." + +#: file.cpp:865 +msgctxt "button" +msgid "&Yes" +msgstr "Да" + +#: file.cpp:867 +msgctxt "button" +msgid "&No" +msgstr "Нет" + +#: file.cpp:869 solvespace.cpp:569 +msgctxt "button" +msgid "&Cancel" +msgstr "Отменить" + +#: graphicswin.cpp:41 +msgid "&File" +msgstr "&Файл" + +#: graphicswin.cpp:42 +msgid "&New" +msgstr "&Новый" + +#: graphicswin.cpp:43 +msgid "&Open..." +msgstr "&Открыть..." + +#: graphicswin.cpp:44 +msgid "Open &Recent" +msgstr "Открыть Н&едавний" + +#: graphicswin.cpp:45 +msgid "&Save" +msgstr "&Сохранить" + +#: graphicswin.cpp:46 +msgid "Save &As..." +msgstr "Сохранить &Как..." + +#: graphicswin.cpp:48 +msgid "Export &Image..." +msgstr "Экспортировать И&зображение..." + +#: graphicswin.cpp:49 +msgid "Export 2d &View..." +msgstr "Экспортировать &2d Вид..." + +#: graphicswin.cpp:50 +msgid "Export 2d &Section..." +msgstr "Экспортировать 2d Се&чение..." + +#: graphicswin.cpp:51 +msgid "Export 3d &Wireframe..." +msgstr "Экспортировать &3d Каркас..." + +#: graphicswin.cpp:52 +msgid "Export Triangle &Mesh..." +msgstr "Экспортировать &Полигональную сетку..." + +#: graphicswin.cpp:53 +msgid "Export &Surfaces..." +msgstr "Экспортировать Повер&хности..." + +#: graphicswin.cpp:54 +msgid "Im&port..." +msgstr "&Импортировать..." + +#: graphicswin.cpp:57 +msgid "E&xit" +msgstr "&Выход" + +#: graphicswin.cpp:60 +msgid "&Edit" +msgstr "&Правка" + +#: graphicswin.cpp:61 +msgid "&Undo" +msgstr "&Отменить" + +#: graphicswin.cpp:62 +msgid "&Redo" +msgstr "&Вернуть" + +#: graphicswin.cpp:63 +msgid "Re&generate All" +msgstr "&Перегенерировать Все" + +#: graphicswin.cpp:65 +msgid "Snap Selection to &Grid" +msgstr "Привязать Выделение к &Сетке" + +#: graphicswin.cpp:66 +msgid "Rotate Imported &90°" +msgstr "Повернуть Импортированное на &90°" + +#: graphicswin.cpp:68 +msgid "Cu&t" +msgstr "Вы&резать" + +#: graphicswin.cpp:69 +msgid "&Copy" +msgstr "&Копировать" + +#: graphicswin.cpp:70 +msgid "&Paste" +msgstr "В&ставить" + +#: graphicswin.cpp:71 +msgid "Paste &Transformed..." +msgstr "Вставить с &Трансформацией..." + +#: graphicswin.cpp:72 +msgid "&Delete" +msgstr "&Удалить" + +#: graphicswin.cpp:74 +msgid "Select &Edge Chain" +msgstr "Вы&делить Последовательность Ребер" + +#: graphicswin.cpp:75 +msgid "Select &All" +msgstr "В&ыделить Все" + +#: graphicswin.cpp:76 +msgid "&Unselect All" +msgstr "С&бросить Выделение" + +#: graphicswin.cpp:78 +msgid "&Line Styles..." +msgstr "" + +#: graphicswin.cpp:79 +msgid "&View Projection..." +msgstr "&View Прое&кция..." + +#: graphicswin.cpp:81 +msgid "Con&figuration..." +msgstr "" + +#: graphicswin.cpp:84 +msgid "&View" +msgstr "&Вид" + +#: graphicswin.cpp:85 +msgid "Zoom &In" +msgstr "&Приблизить" + +#: graphicswin.cpp:86 +msgid "Zoom &Out" +msgstr "От&далить" + +#: graphicswin.cpp:87 +msgid "Zoom To &Fit" +msgstr "Показать &Все / Выделенное" + +#: graphicswin.cpp:89 +msgid "Align View to &Workplane" +msgstr "Выровнять Вид на &Рабочую Плоскость" + +#: graphicswin.cpp:90 +msgid "Nearest &Ortho View" +msgstr "Ближайший &Ортогональный Вид" + +#: graphicswin.cpp:91 +msgid "Nearest &Isometric View" +msgstr "Ближайший &Изометрический Вид" + +#: graphicswin.cpp:92 +msgid "&Center View At Point" +msgstr "&Центрировать Вид на Точке" + +#: graphicswin.cpp:94 +msgid "Show Snap &Grid" +msgstr "Показать &Сетку" + +#: graphicswin.cpp:95 +msgid "Darken Inactive Solids" +msgstr "" + +#: graphicswin.cpp:96 +msgid "Use &Perspective Projection" +msgstr "Перспективная Прое&кция" + +#: graphicswin.cpp:97 +msgid "Dimension &Units" +msgstr "" + +#: graphicswin.cpp:98 +msgid "Dimensions in &Millimeters" +msgstr "Размеры в Ми&ллиметрах" + +#: graphicswin.cpp:99 +msgid "Dimensions in M&eters" +msgstr "" + +#: graphicswin.cpp:100 +msgid "Dimensions in &Inches" +msgstr "Размеры в Дю&ймах" + +#: graphicswin.cpp:102 +msgid "Show &Toolbar" +msgstr "Показывать Па&нель Инструментов" + +#: graphicswin.cpp:103 +msgid "Show Property Bro&wser" +msgstr "Показывать Брау&зер" + +#: graphicswin.cpp:105 +msgid "&Full Screen" +msgstr "Полно&экранный Режим" + +#: graphicswin.cpp:107 +msgid "&New Group" +msgstr "&Группа" + +#: graphicswin.cpp:108 +msgid "Sketch In &3d" +msgstr "Создать Эскиз в &3d" + +#: graphicswin.cpp:109 +msgid "Sketch In New &Workplane" +msgstr "Создать Эскиз в Новой &Рабочей Плоскости" + +#: graphicswin.cpp:111 +msgid "Step &Translating" +msgstr "&Линейный Массив" + +#: graphicswin.cpp:112 +msgid "Step &Rotating" +msgstr "&Круговой Массив" + +#: graphicswin.cpp:114 +msgid "E&xtrude" +msgstr "Тело &Выдавливания" + +#: graphicswin.cpp:115 +msgid "&Helix" +msgstr "" + +#: graphicswin.cpp:116 +msgid "&Lathe" +msgstr "Тело В&ращения" + +#: graphicswin.cpp:117 +msgid "Re&volve" +msgstr "" + +#: graphicswin.cpp:119 +msgid "Link / Assemble..." +msgstr "&Импорт Детали / Сборка..." + +#: graphicswin.cpp:120 +msgid "Link Recent" +msgstr "Последние &Детали" + +#: graphicswin.cpp:122 +msgid "&Sketch" +msgstr "&Эскиз" + +#: graphicswin.cpp:123 +msgid "In &Workplane" +msgstr "В &Рабочей Плоскости" + +#: graphicswin.cpp:124 +msgid "Anywhere In &3d" +msgstr "Режим &3d" + +#: graphicswin.cpp:126 +msgid "Datum &Point" +msgstr "Опорная &Точка" + +#: graphicswin.cpp:127 +msgid "&Workplane" +msgstr "Рабочая &Плоскость" + +#: graphicswin.cpp:129 +msgid "Line &Segment" +msgstr "&Отрезок" + +#: graphicswin.cpp:130 +msgid "C&onstruction Line Segment" +msgstr "&Вспомогательный Отрезок" + +#: graphicswin.cpp:131 +msgid "&Rectangle" +msgstr "Прямоу&гольник" + +#: graphicswin.cpp:132 +msgid "&Circle" +msgstr "О&кружность" + +#: graphicswin.cpp:133 +msgid "&Arc of a Circle" +msgstr "Д&уга Окружности" + +#: graphicswin.cpp:134 +msgid "&Bezier Cubic Spline" +msgstr "Кубический &Сплайн Безье" + +#: graphicswin.cpp:136 +msgid "&Text in TrueType Font" +msgstr "Т&екст TrueType" + +#: graphicswin.cpp:137 +msgid "&Image" +msgstr "И&зображение" + +#: graphicswin.cpp:139 +msgid "To&ggle Construction" +msgstr "Переключить Режим Вс&помогательных Построений" + +#: graphicswin.cpp:140 +msgid "Tangent &Arc at Point" +msgstr "Кас&ательная в Точке" + +#: graphicswin.cpp:141 +msgid "Split Curves at &Intersection" +msgstr "Ра&збить Кривые Пересечением" + +#: graphicswin.cpp:143 +msgid "&Constrain" +msgstr "&Ограничения" + +#: graphicswin.cpp:144 +msgid "&Distance / Diameter" +msgstr "&Расстояние / Диаметр" + +#: graphicswin.cpp:145 +msgid "Re&ference Dimension" +msgstr "&Справочный Размер" + +#: graphicswin.cpp:146 +msgid "A&ngle" +msgstr "&Угол" + +#: graphicswin.cpp:147 +msgid "Reference An&gle" +msgstr "С&правочный Угол" + +#: graphicswin.cpp:148 +msgid "Other S&upplementary Angle" +msgstr "Переключить Сме&жный Угол" + +#: graphicswin.cpp:149 +msgid "Toggle R&eference Dim" +msgstr "Переключить Режим Размера Для Спра&вок" + +#: graphicswin.cpp:151 +msgid "&Horizontal" +msgstr "&Горизонтальность" + +#: graphicswin.cpp:152 +msgid "&Vertical" +msgstr "&Вертикальность" + +#: graphicswin.cpp:154 +msgid "&On Point / Curve / Plane" +msgstr "&Точка на Примитиве" + +#: graphicswin.cpp:155 +msgid "E&qual Length / Radius / Angle" +msgstr "&Равенство Длин / Радиусов / Углов" + +#: graphicswin.cpp:156 +msgid "Length Ra&tio" +msgstr "Отно&шение Длин" + +#: graphicswin.cpp:157 +msgid "Length Diff&erence" +msgstr "Ра&зница Длин" + +#: graphicswin.cpp:158 +msgid "At &Midpoint" +msgstr "&На Середине" + +#: graphicswin.cpp:159 +msgid "S&ymmetric" +msgstr "С&имметричность" + +#: graphicswin.cpp:160 +msgid "Para&llel / Tangent" +msgstr "Пара&ллельность / Касательность" + +#: graphicswin.cpp:161 +msgid "&Perpendicular" +msgstr "Перпендикул&ярность" + +#: graphicswin.cpp:162 +msgid "Same Orient&ation" +msgstr "Идентичная &Ориентация" + +#: graphicswin.cpp:163 +msgid "Lock Point Where &Dragged" +msgstr "За&фиксировать" + +#: graphicswin.cpp:165 +msgid "Comment" +msgstr "Текстовый &Комментарий" + +#: graphicswin.cpp:167 +msgid "&Analyze" +msgstr "&Анализ" + +#: graphicswin.cpp:168 +msgid "Measure &Volume" +msgstr "Измерить &Объем" + +#: graphicswin.cpp:169 +msgid "Measure A&rea" +msgstr "Измерить П&лощадь" + +#: graphicswin.cpp:170 +msgid "Measure &Perimeter" +msgstr "Измерить П&ериметр" + +#: graphicswin.cpp:171 +msgid "Show &Interfering Parts" +msgstr "Показать Пе&ресекающиеся Детали" + +#: graphicswin.cpp:172 +msgid "Show &Naked Edges" +msgstr "Показать Про&блемные Ребра" + +#: graphicswin.cpp:173 +msgid "Show &Center of Mass" +msgstr "" + +#: graphicswin.cpp:175 +msgid "Show &Underconstrained Points" +msgstr "" + +#: graphicswin.cpp:177 +msgid "&Trace Point" +msgstr "Включить &Трассировку Точки" + +#: graphicswin.cpp:178 +msgid "&Stop Tracing..." +msgstr "Остановить Тра&ссировку..." + +#: graphicswin.cpp:179 +msgid "Step &Dimension..." +msgstr "Плавное Из&менение Размера..." + +#: graphicswin.cpp:181 +msgid "&Help" +msgstr "&Помощь" + +#: graphicswin.cpp:182 +msgid "&Language" +msgstr "&Язык" + +#: graphicswin.cpp:183 +msgid "&Website / Manual" +msgstr "Вебсайт / &Справка" + +#: graphicswin.cpp:185 +msgid "&About" +msgstr "О &Программе" + +#: graphicswin.cpp:355 +msgid "(no recent files)" +msgstr "(пусто)" + +#: graphicswin.cpp:363 +#, c-format +msgid "File '%s' does not exist." +msgstr "" + +#: graphicswin.cpp:725 +msgid "No workplane is active, so the grid will not appear." +msgstr "Сетку не будет видно, пока рабочая плоскость не активирована." + +#: graphicswin.cpp:740 +msgid "" +"The perspective factor is set to zero, so the view will always be a parallel " +"projection.\n" +"\n" +"For a perspective projection, modify the perspective factor in the " +"configuration screen. A value around 0.3 is typical." +msgstr "" +"Коэффициент перспективы установлен в ноль, что соответствует ортогональной " +"проекции.\n" +"Чтобы получить перспективную проекцию, отредактируйте значение коэффициента " +"перспективы на конфигурационной странице браузера.\n" +"Значение по умолчанию 0.3." + +#: graphicswin.cpp:819 +msgid "" +"Select a point; this point will become the center of the view on screen." +msgstr "Выделите точку. Вид будет отцентрован по этой точке." + +#: graphicswin.cpp:1114 +msgid "No additional entities share endpoints with the selected entities." +msgstr "Нет дополнительных объектов, соединенных с выбранными примитивами." + +#: graphicswin.cpp:1132 +msgid "" +"To use this command, select a point or other entity from an linked part, or " +"make a link group the active group." +msgstr "" +"Чтобы использовать эту команду, выделите точку или другой примитив, " +"принадлежащий импортированной детали или активируйте группу импортированной " +"детали." + +#: graphicswin.cpp:1155 +msgid "" +"No workplane is active. Activate a workplane (with Sketch -> In Workplane) " +"to define the plane for the snap grid." +msgstr "" +"Рабочая плоскость не активна. Активируйте ее через Эскиз -> В Рабочей " +"Плоскости чтобы определить плоскость для сетки." + +#: graphicswin.cpp:1162 +msgid "" +"Can't snap these items to grid; select points, text comments, or constraints " +"with a label. To snap a line, select its endpoints." +msgstr "" +"Невозможно привязать выбранные примитивы к сетке. Необходимо выбирать точки, " +"текстовые комментарии или ограничения с размерными значениями. Чтобы " +"привязать отрезок или другой примитив, выбирайте его точки." + +#: graphicswin.cpp:1247 +msgid "No workplane selected. Activating default workplane for this group." +msgstr "" +"Рабочая плоскость не активна. Активирована рабочая плоскость по умолчанию " +"для данной группы." + +#: graphicswin.cpp:1250 +msgid "" +"No workplane is selected, and the active group does not have a default " +"workplane. Try selecting a workplane, or activating a sketch-in-new-" +"workplane group." +msgstr "" +"Рабочая плоскость не выбрана и активная группа не содержит рабочей плоскости " +"по умолчанию. Попробуйте выделить рабочую плоскость или создать новую с " +"помощью Группа -> Создать Эскиз в Новой Рабочей Плоскости." + +#: graphicswin.cpp:1271 +msgid "" +"Bad selection for tangent arc at point. Select a single point, or select " +"nothing to set up arc parameters." +msgstr "" +"Неправильное выделение для создания скругления в точке. Выделите либо одну " +"точку, либо запустите команду без выделения, чтобы перейти к окну настроек " +"этой команды." + +#: graphicswin.cpp:1282 +msgid "click point on arc (draws anti-clockwise)" +msgstr "" +"кликните мышью там, где хотите создать дугу окружности (дуга будет " +"нарисована против часовой стрелки)" + +#: graphicswin.cpp:1283 +msgid "click to place datum point" +msgstr "кликните мышью там, где хотите создать опорную точку" + +#: graphicswin.cpp:1284 +msgid "click first point of line segment" +msgstr "кликните мышью там, где хотите создать первую точку отрезка" + +#: graphicswin.cpp:1286 +msgid "click first point of construction line segment" +msgstr "" +"кликните мышью там, где хотите создать первую точку вспомогательного отрезка" + +#: graphicswin.cpp:1287 +msgid "click first point of cubic segment" +msgstr "" +"кликните мышью там, где хотите создать первую точку кубического сплайна Безье" + +#: graphicswin.cpp:1288 +msgid "click center of circle" +msgstr "кликните мышью там, где будет находиться центр окружности" + +#: graphicswin.cpp:1289 +msgid "click origin of workplane" +msgstr "" +"кликните мышью там, где будет находиться точка, через которую будет " +"построена рабочая плоскость" + +#: graphicswin.cpp:1290 +msgid "click one corner of rectangle" +msgstr "кликните мышью там, где будет находиться один из углов прямоугольника" + +#: graphicswin.cpp:1291 +msgid "click top left of text" +msgstr "кликните мышью там, где хотите создать текст" + +#: graphicswin.cpp:1297 +msgid "click top left of image" +msgstr "" + +#: graphicswin.cpp:1309 +msgid "" +"No entities are selected. Select entities before trying to toggle their " +"construction state." +msgstr "" +"Не выбран ни один примитив. Выберите примитивы перед тем, как переключать их " +"режим дополнительных построений." + +#: group.cpp:86 +msgctxt "group-name" +msgid "sketch-in-3d" +msgstr "эскиз-в-3d" + +#: group.cpp:142 +msgid "" +"Bad selection for new sketch in workplane. This group can be created with:\n" +"\n" +" * a point (through the point, orthogonal to coordinate axes)\n" +" * a point and two line segments (through the point, parallel to the " +"lines)\n" +" * a workplane (copy of the workplane)\n" +msgstr "" +"Неправильное выделение для создания эскиза.\n" +"Группа может быть создана, используя в качестве выделения следующие " +"примитивы:\n" +"\n" +" * точку (рабочая плоскость, ориентированная к ближайшему виду, " +"проходящая через точку)\n" +" * точку и два отрезка (рабочая плоскость, проходящая через точку и " +"параллельная отрезкам)\n" +" * рабочую плоскость (копия рабочей плоскости)\n" + +#: group.cpp:154 +msgid "" +"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch " +"will be extruded normal to the workplane." +msgstr "" +"Выберите рабочую плоскость (Эскиз -> В Рабочей Плоскости) перед созданием " +"группы выдавливания. Эскиз будет выдавлен по нормали к рабочей плоскости." + +#: group.cpp:163 +msgctxt "group-name" +msgid "extrude" +msgstr "тело-выдавливания" + +#: group.cpp:168 +msgid "Lathe operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:179 +msgid "" +"Bad selection for new lathe group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" +"Неправильное выделение для создания группы тела вращения. \n" +"Группа может быть создана, используя в качестве выделения следующие " +"примитивы:\n" +"\n" +" * точку и отрезок / координатных базис (нормаль) (тело вращения вокруг " +"оси, проходящей через точку и параллельной отрезку / нормали)\n" +" * отрезок (тело вращения вокруг оси, проходящей через отрезок)\n" +"\n" + +#: group.cpp:189 +msgctxt "group-name" +msgid "lathe" +msgstr "тело-вращения" + +#: group.cpp:194 +msgid "Revolve operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:205 +msgid "" +"Bad selection for new revolve group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" + +#: group.cpp:217 +msgctxt "group-name" +msgid "revolve" +msgstr "" + +#: group.cpp:222 +msgid "Helix operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:233 +msgid "" +"Bad selection for new helix group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" + +#: group.cpp:245 +msgctxt "group-name" +msgid "helix" +msgstr "" + +#: group.cpp:258 +msgid "" +"Bad selection for new rotation. This group can be created with:\n" +"\n" +" * a point, while locked in workplane (rotate in plane, about that " +"point)\n" +" * a point and a line or a normal (rotate about an axis through the " +"point, and parallel to line / normal)\n" +msgstr "" +"Неправильное выделение для создания группы кругового массива. \n" +"Группа может быть создана, используя в качестве выделения следующие " +"примитивы:\n" +"\n" +" * точку при активной рабочей плоскости (вращение в плоскости вокруг " +"выбранной точки)\n" +" * точку и отрезок / координатных базис (нормаль) (вращение вокруг оси, " +"проходящей через точку и параллельной отрезку / нормали)\n" +"\n" + +#: group.cpp:271 +msgctxt "group-name" +msgid "rotate" +msgstr "круговой-массив" + +#: group.cpp:282 +msgctxt "group-name" +msgid "translate" +msgstr "линейный-массив" + +#: group.cpp:400 +msgid "(unnamed)" +msgstr "(без имени)" + +#: groupmesh.cpp:709 +msgid "not closed contour, or not all same style!" +msgstr "незамкнутый контур или несовпадение стилей!" + +#: groupmesh.cpp:722 +msgid "points not all coplanar!" +msgstr "не все точки лежат в одной плоскости!" + +#: groupmesh.cpp:724 +msgid "contour is self-intersecting!" +msgstr "контур имеет самопересечения!" + +#: groupmesh.cpp:726 +msgid "zero-length edge!" +msgstr "вырожденный отрезок!" + +#: modify.cpp:254 +msgid "Must be sketching in workplane to create tangent arc." +msgstr "" +"Скругления эскиза можно создавать только когда рабочая плоскость " +"активирована." + +#: modify.cpp:301 +msgid "" +"To create a tangent arc, select a point where two non-construction lines or " +"circles in this group and workplane join." +msgstr "" +"Чтобы создать скругление эскиза, выберите точку, где соединяются два " +"примитива, не принадлежащих к вспомогательной геометрии." + +#: modify.cpp:388 +msgid "" +"Couldn't round this corner. Try a smaller radius, or try creating the " +"desired geometry by hand with tangency constraints." +msgstr "" +"Невозможно скруглить угол. Попробуйте радиус поменьше или создайте требуемую " +"геометрию с помощью Ограничения -> Параллельность / Касательность." + +#: modify.cpp:597 +msgid "Couldn't split this entity; lines, circles, or cubics only." +msgstr "" +"Невозможно разделить такие примитивы. Выберите линии, окружности или " +"кубические сплайны." + +#: modify.cpp:624 +msgid "Must be sketching in workplane to split." +msgstr "" +"Пересечение примитивов работает только когда рабочая плоскость активна." + +#: modify.cpp:631 +msgid "" +"Select two entities that intersect each other (e.g. two lines/circles/arcs " +"or a line/circle/arc and a point)." +msgstr "" + +#: modify.cpp:736 +msgid "Can't split; no intersection found." +msgstr "Невозможно разделить пересекаемые примитивы: пересечений нет." + +#: mouse.cpp:560 +msgid "Assign to Style" +msgstr "Применить Стиль" + +#: mouse.cpp:576 +msgid "No Style" +msgstr "Стиль по Умолчанию" + +#: mouse.cpp:579 +msgid "Newly Created Custom Style..." +msgstr "Создать Новый Стиль..." + +#: mouse.cpp:586 +msgid "Group Info" +msgstr "Настройки Группы" + +#: mouse.cpp:606 +msgid "Style Info" +msgstr "Настройки Стиля" + +#: mouse.cpp:626 +msgid "Select Edge Chain" +msgstr "Выделить Последовательность Примитивов" + +#: mouse.cpp:632 +msgid "Toggle Reference Dimension" +msgstr "Переключить Режим Размера Для Справок" + +#: mouse.cpp:638 +msgid "Other Supplementary Angle" +msgstr "Переключить Смежный Угол" + +#: mouse.cpp:643 +msgid "Snap to Grid" +msgstr "Привязать к Сетке" + +#: mouse.cpp:652 +msgid "Remove Spline Point" +msgstr "Удалить Точку Сплайна" + +#: mouse.cpp:687 +msgid "Add Spline Point" +msgstr "Добавить Точку Сплайна" + +#: mouse.cpp:691 +msgid "Cannot add spline point: maximum number of points reached." +msgstr "" +"Невозможно добавить точку сплайна: достигнуто ограничение максимального " +"количества точек для сплайна." + +#: mouse.cpp:716 +msgid "Toggle Construction" +msgstr "Переключить Режим 'Дополнительные Построения'." + +#: mouse.cpp:731 +msgid "Delete Point-Coincident Constraint" +msgstr "Удалить Ограничение Совпадения Точек" + +#: mouse.cpp:750 +msgid "Cut" +msgstr "Вырезать" + +#: mouse.cpp:752 +msgid "Copy" +msgstr "Копировать" + +#: mouse.cpp:756 +msgid "Select All" +msgstr "Выделить Все" + +#: mouse.cpp:761 +msgid "Paste" +msgstr "Вставить" + +#: mouse.cpp:763 +msgid "Paste Transformed..." +msgstr "Вставить с Трансформацией..." + +#: mouse.cpp:768 +msgid "Delete" +msgstr "Удалить" + +#: mouse.cpp:771 +msgid "Unselect All" +msgstr "Сбросить Выделение" + +#: mouse.cpp:778 +msgid "Unselect Hovered" +msgstr "Снять Выделение с Выбранного" + +#: mouse.cpp:787 +msgid "Zoom to Fit" +msgstr "Показать Все" + +#: mouse.cpp:989 mouse.cpp:1276 +msgid "click next point of line, or press Esc" +msgstr "кликните мышью там, где хотите расположить следующую точку" + +#: mouse.cpp:995 +msgid "" +"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" +"Невозможно начертить прямоугольник, когда рабочая плоскость не активна." + +#: mouse.cpp:1029 +msgid "click to place other corner of rectangle" +msgstr "кликните мышью там, где хотите расположить другой угол прямоугольника" + +#: mouse.cpp:1049 +msgid "click to set radius" +msgstr "кликните, чтобы задать радиус" + +#: mouse.cpp:1054 +msgid "" +"Can't draw arc in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "Невозможно создать дугу, когда нет активной рабочей плоскости." + +#: mouse.cpp:1073 +msgid "click to place point" +msgstr "кликните мышью там, где хотите создать точку" + +#: mouse.cpp:1089 +msgid "click next point of cubic, or press Esc" +msgstr "" +"кликните мышью там, где хотите создать следующую точку сплайна или нажмите " +"Esc для завершения операции." + +#: mouse.cpp:1094 +msgid "" +"Sketching in a workplane already; sketch in 3d before creating new workplane." +msgstr "" +"Рабочая плоскость уже активна. Перейдите в режим 3d перед созданием новой " +"рабочей плоскости." + +#: mouse.cpp:1110 +msgid "" +"Can't draw text in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "Невозможно создать текст, когда нет активной рабочей плоскости." + +#: mouse.cpp:1127 +msgid "click to place bottom right of text" +msgstr "" + +#: mouse.cpp:1133 +msgid "" +"Can't draw image in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" + +#: mouse.cpp:1160 +msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" +msgstr "КОММЕНТАРИЙ -- ДВОЙНОЙ ЩЕЛЧОК ДЛЯ РЕДАКТИРОВАНИЯ" + +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511 +msgctxt "file-type" +msgid "SolveSpace models" +msgstr "проекты SolveSpace" + +#: platform/gui.cpp:90 +msgctxt "file-type" +msgid "IDF circuit board" +msgstr "" + +#: platform/gui.cpp:94 +msgctxt "file-type" +msgid "PNG image" +msgstr "PNG изображение" + +#: platform/gui.cpp:98 +msgctxt "file-type" +msgid "STL mesh" +msgstr "STL полигональная сетка" + +#: platform/gui.cpp:99 +msgctxt "file-type" +msgid "Wavefront OBJ mesh" +msgstr "Wavefront OBJ полигональная сетка" + +#: platform/gui.cpp:100 +msgctxt "file-type" +msgid "Three.js-compatible mesh, with viewer" +msgstr "Three.js-совместимая полигональная сетка с просмторщиком" + +#: platform/gui.cpp:101 +msgctxt "file-type" +msgid "Three.js-compatible mesh, mesh only" +msgstr "Three.js-совместимая полигональная сетка" + +#: platform/gui.cpp:102 +msgctxt "file-type" +msgid "VRML text file" +msgstr "" + +#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 +msgctxt "file-type" +msgid "STEP file" +msgstr "STEP файл" + +#: platform/gui.cpp:110 +msgctxt "file-type" +msgid "PDF file" +msgstr "PDF документ" + +#: platform/gui.cpp:111 +msgctxt "file-type" +msgid "Encapsulated PostScript" +msgstr "Encapsulated PostScript" + +#: platform/gui.cpp:112 +msgctxt "file-type" +msgid "Scalable Vector Graphics" +msgstr "SVG изображение" + +#: platform/gui.cpp:114 platform/gui.cpp:121 +msgctxt "file-type" +msgid "DXF file (AutoCAD 2007)" +msgstr "DXF файл (AutoCAD 2007)" + +#: platform/gui.cpp:115 +msgctxt "file-type" +msgid "HPGL file" +msgstr "HPGL файл" + +#: platform/gui.cpp:116 +msgctxt "file-type" +msgid "G Code" +msgstr "G Code" + +#: platform/gui.cpp:125 +msgctxt "file-type" +msgid "AutoCAD DXF and DWG files" +msgstr "AutoCAD DXF и DWG файлы" + +#: platform/gui.cpp:129 +msgctxt "file-type" +msgid "Comma-separated values" +msgstr "CSV файлы (значения, разделенные запятой)" + +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 +msgid "untitled" +msgstr "без имени" + +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1573 +msgctxt "title" +msgid "Save File" +msgstr "Сохранить Файл" + +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1575 +msgctxt "title" +msgid "Open File" +msgstr "Открыть Файл" + +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 +msgctxt "button" +msgid "_Cancel" +msgstr "Отменить" + +#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 +msgctxt "button" +msgid "_Save" +msgstr "Сохранить" + +#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 +msgctxt "button" +msgid "_Open" +msgstr "" + +#: solvespace.cpp:169 +msgctxt "title" +msgid "Autosave Available" +msgstr "Автосохранение Доступно" + +#: solvespace.cpp:170 +msgctxt "dialog" +msgid "An autosave file is available for this sketch." +msgstr "" + +#: solvespace.cpp:171 +msgctxt "dialog" +msgid "Do you want to load the autosave file instead?" +msgstr "" + +#: solvespace.cpp:172 +msgctxt "button" +msgid "&Load autosave" +msgstr "" + +#: solvespace.cpp:174 +msgctxt "button" +msgid "Do&n't Load" +msgstr "" + +#: solvespace.cpp:557 +msgctxt "title" +msgid "Modified File" +msgstr "Измененный Файл" + +#: solvespace.cpp:559 +#, c-format +msgctxt "dialog" +msgid "Do you want to save the changes you made to the sketch “%s”?" +msgstr "" + +#: solvespace.cpp:562 +msgctxt "dialog" +msgid "Do you want to save the changes you made to the new sketch?" +msgstr "" + +#: solvespace.cpp:565 +msgctxt "dialog" +msgid "Your changes will be lost if you don't save them." +msgstr "" + +#: solvespace.cpp:566 +msgctxt "button" +msgid "&Save" +msgstr "" + +#: solvespace.cpp:568 +msgctxt "button" +msgid "Do&n't Save" +msgstr "" + +#: solvespace.cpp:589 +msgctxt "title" +msgid "(new sketch)" +msgstr "(новый проект)" + +#: solvespace.cpp:596 +msgctxt "title" +msgid "Property Browser" +msgstr "Браузер" + +#: solvespace.cpp:658 +msgid "" +"Constraints are currently shown, and will be exported in the toolpath. This " +"is probably not what you want; hide them by clicking the link at the top of " +"the text window." +msgstr "" + +#: solvespace.cpp:730 +#, c-format +msgid "" +"Can't identify file type from file extension of filename '%s'; try .dxf or ." +"dwg." +msgstr "" + +#: solvespace.cpp:778 +msgid "Constraint must have a label, and must not be a reference dimension." +msgstr "" + +#: solvespace.cpp:782 +msgid "Bad selection for step dimension; select a constraint." +msgstr "" + +#: solvespace.cpp:806 +msgid "The assembly does not interfere, good." +msgstr "" + +#: solvespace.cpp:822 +#, c-format +msgid "" +"The volume of the solid model is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:831 +#, c-format +msgid "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:836 +msgid "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." +msgstr "" + +#: solvespace.cpp:851 +#, c-format +msgid "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:860 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." +msgstr "" + +#: solvespace.cpp:872 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:892 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:898 +msgid "Bad selection for perimeter; select line segments, arcs, and curves." +msgstr "" + +#: solvespace.cpp:914 +msgid "Bad selection for trace; select a single point." +msgstr "" + +#: solvespace.cpp:941 +#, c-format +msgid "Couldn't write to '%s'" +msgstr "" + +#: solvespace.cpp:971 +msgid "The mesh is self-intersecting (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:972 +msgid "The mesh is not self-intersecting (okay, valid)." +msgstr "" + +#: solvespace.cpp:974 +msgid "The mesh has naked edges (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:975 +msgid "The mesh is watertight (okay, valid)." +msgstr "" + +#: solvespace.cpp:978 +#, c-format +msgid "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." +msgstr "" + +#: solvespace.cpp:982 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" + +#: solvespace.cpp:985 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" + +#: solvespace.cpp:998 +#, c-format +msgid "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" +msgstr "" + +#: style.cpp:166 +msgid "" +"Can't assign style to an entity that's derived from another entity; try " +"assigning a style to this entity's parent." +msgstr "" +"Невозможно применить стиль к примитиву, который произошел от другого " +"примитива. Попробуйте применить стиль к исходному примитиву." + +#: style.cpp:665 +msgid "Style name cannot be empty" +msgstr "Имя стиля не может быть пустым." + +#: textscreens.cpp:741 +msgid "Can't repeat fewer than 1 time." +msgstr "Невозможно сделать повторение меньше, чем 1 раз." + +#: textscreens.cpp:745 +msgid "Can't repeat more than 999 times." +msgstr "Невозможно сделать повтор больше, чем 999 раз." + +#: textscreens.cpp:770 +msgid "Group name cannot be empty" +msgstr "Имя группы не может быть пустым." + +#: textscreens.cpp:813 +msgid "Opacity must be between zero and one." +msgstr "Прозрачность должна быть числом от нуля до единицы." + +#: textscreens.cpp:848 +msgid "Radius cannot be zero or negative." +msgstr "Радиус не может быть нулевым или отрицательным." + +#: toolbar.cpp:18 +msgid "Sketch line segment" +msgstr "Начертить отрезок прямой" + +#: toolbar.cpp:20 +msgid "Sketch rectangle" +msgstr "Начертить прямоугольник" + +#: toolbar.cpp:22 +msgid "Sketch circle" +msgstr "Начертить окружность" + +#: toolbar.cpp:24 +msgid "Sketch arc of a circle" +msgstr "Начертить дугу окружности" + +#: toolbar.cpp:26 +msgid "Sketch curves from text in a TrueType font" +msgstr "Начертить текст TrueType" + +#: toolbar.cpp:28 +msgid "Sketch image from a file" +msgstr "" + +#: toolbar.cpp:30 +msgid "Create tangent arc at selected point" +msgstr "Создать скругление в выбранной точке" + +#: toolbar.cpp:32 +msgid "Sketch cubic Bezier spline" +msgstr "Начертить кубический сплайн Безье" + +#: toolbar.cpp:34 +msgid "Sketch datum point" +msgstr "Начертить опорную точку" + +#: toolbar.cpp:36 +msgid "Toggle construction" +msgstr "Переключить вспомогательную геометрию" + +#: toolbar.cpp:38 +msgid "Split lines / curves where they intersect" +msgstr "Разбить кривые по пересечению" + +#: toolbar.cpp:42 +msgid "Constrain distance / diameter / length" +msgstr "Ограничение расстояния / диаметра / длины" + +#: toolbar.cpp:44 +msgid "Constrain angle" +msgstr "Ограничение угла" + +#: toolbar.cpp:46 +msgid "Constrain to be horizontal" +msgstr "Ограничение горизонтальности" + +#: toolbar.cpp:48 +msgid "Constrain to be vertical" +msgstr "Ограничение вертикальности" + +#: toolbar.cpp:50 +msgid "Constrain to be parallel or tangent" +msgstr "Ограничение параллельности / касательности" + +#: toolbar.cpp:52 +msgid "Constrain to be perpendicular" +msgstr "Ограничение перпендикулярности" + +#: toolbar.cpp:54 +msgid "Constrain point on line / curve / plane / point" +msgstr "Ограничение точка на точке / линии / окружности / дуге / плоскости" + +#: toolbar.cpp:56 +msgid "Constrain symmetric" +msgstr "Симметричность" + +#: toolbar.cpp:58 +msgid "Constrain equal length / radius / angle" +msgstr "Ограничение равенства длин / радиусов / углов" + +#: toolbar.cpp:60 +msgid "Constrain normals in same orientation" +msgstr "Ограничение идентичности ориентации координатных базисов" + +#: toolbar.cpp:62 +msgid "Other supplementary angle" +msgstr "Переключить смежный угол" + +#: toolbar.cpp:64 +msgid "Toggle reference dimension" +msgstr "Переключить режим размера для справок" + +#: toolbar.cpp:68 +msgid "New group extruding active sketch" +msgstr "Создать группу выдавливания текущего эскиза" + +#: toolbar.cpp:70 +msgid "New group rotating active sketch" +msgstr "Создать группу вращения текущего эскиза" + +#: toolbar.cpp:72 +msgid "New group helix from active sketch" +msgstr "" + +#: toolbar.cpp:74 +msgid "New group revolve active sketch" +msgstr "" + +#: toolbar.cpp:76 +msgid "New group step and repeat rotating" +msgstr "Создать группу кругового массива" + +#: toolbar.cpp:78 +msgid "New group step and repeat translating" +msgstr "Создать группу линейного массива" + +#: toolbar.cpp:80 +msgid "New group in new workplane (thru given entities)" +msgstr "Создать группу в новой рабочей плоскости (через выбранные примитивы)" + +#: toolbar.cpp:82 +msgid "New group in 3d" +msgstr "Новая группа в 3d" + +#: toolbar.cpp:84 +msgid "New group linking / assembling file" +msgstr "Новая группа импорта детали / сборки" + +#: toolbar.cpp:88 +msgid "Nearest isometric view" +msgstr "Ближайший изометрический вид" + +#: toolbar.cpp:90 +msgid "Align view to active workplane" +msgstr "Выровнять вид на рабочую плоскость" + +#: util.cpp:165 +msgctxt "title" +msgid "Error" +msgstr "Ошибка" + +#: util.cpp:165 +msgctxt "title" +msgid "Message" +msgstr "Сообщение" + +#: util.cpp:170 +msgctxt "button" +msgid "&OK" +msgstr "ХОРОШО" + +#: view.cpp:78 +msgid "Scale cannot be zero or negative." +msgstr "Масштабный коэффициент не может быть нулевым или отрицательным." + +#: view.cpp:90 view.cpp:99 +msgid "Bad format: specify x, y, z" +msgstr "Неверный формат: введите данные как x, y, z" + +#~ msgid "Specify between 0 and 8 digits after the decimal." +#~ msgstr "Введите число от 0 до 8." + +#~ msgid "Show Degrees of &Freedom" +#~ msgstr "Показать Степени С&вободы" + +#~ msgid "click to place bottom left of text" +#~ msgstr "кликните мышью, чтобы расположить текст" + +#~ msgid "Do you want to save the changes you made to the new sketch?" +#~ msgstr "Хотите сохранить ваши изменения?" + +#~ msgid "Your changes will be lost if you don't save them." +#~ msgstr "Ваши изменения будут утеряны, если вы их не сохраните." + +#~ msgctxt "button" +#~ msgid "Save" +#~ msgstr "Сохранить" + +#~ msgctxt "button" +#~ msgid "Cancel" +#~ msgstr "Отменить" + +#~ msgctxt "button" +#~ msgid "Don't Save" +#~ msgstr "Не Сохранять" + +#~ msgid "An autosave file is available for this project." +#~ msgstr "Файлы автосохранения доступны для данного проекта." + +#~ msgid "Do you want to load the autosave file instead?" +#~ msgstr "Хотите загрузить их вместо открываемого файла?" + +#~ msgctxt "button" +#~ msgid "Load" +#~ msgstr "Загрузить Автосохранение" + +#~ msgctxt "button" +#~ msgid "Don't Load" +#~ msgstr "Просто Открыть Файл" + +#~ msgid "" +#~ "Do you want to locate it manually?\n" +#~ "If you select “No”, any geometry that depends on the missing file will be " +#~ "removed." +#~ msgstr "" +#~ "Хотите найти их вручную?\n" +#~ "Если вы ответите \"Нет\", то вся геометрия, которая зависит от " +#~ "отсутствующего файла будет удалена." + +#~ msgctxt "button" +#~ msgid "Yes" +#~ msgstr "Да" + +#~ msgctxt "button" +#~ msgid "No" +#~ msgstr "Нет" + +#~ msgctxt "button" +#~ msgid "OK" +#~ msgstr "ХОРОШО" + +#~ msgid "_Cancel" +#~ msgstr "Отменить" + +#~ msgid "_Open" +#~ msgstr "Открыть" + +#~ msgid "" +#~ "The file has changed since it was last saved.\n" +#~ "\n" +#~ "Do you want to save the changes?" +#~ msgstr "" +#~ "Файл имеет несохраненные изменения.\n" +#~ "\n" +#~ "Хотите сохранить их?" + +#~ msgctxt "button" +#~ msgid "Do_n't Save" +#~ msgstr "Не Сохранять" + +#~ msgid "" +#~ "An autosave file is available for this project.\n" +#~ "\n" +#~ "Do you want to load the autosave file instead?" +#~ msgstr "" +#~ "Файлы автосохранения доступны для данного проекта.\n" +#~ "\n" +#~ "Хотите загрузить их вместо открываемого файла?" + +#~ msgctxt "button" +#~ msgid "_Load autosave" +#~ msgstr "Загрузить Автосохранение" + +#~ msgctxt "button" +#~ msgid "Do_n't Load" +#~ msgstr "Не Загружать" + +#~ msgctxt "button" +#~ msgid "_Yes" +#~ msgstr "Да" + +#~ msgctxt "button" +#~ msgid "_No" +#~ msgstr "Нет" + +#~ msgid "" +#~ "Select two entities that intersect each other (e.g. two lines or two " +#~ "circles or a circle and a line)." +#~ msgstr "" +#~ "Выберите два пересекающихся примитива. Например, две линии или две " +#~ "окружности или линию и окружность." + +#~ msgid "Show Menu &Bar" +#~ msgstr "Показывать Мен&ю" + +#~ msgctxt "group-name" +#~ msgid "link" +#~ msgstr "ссылка-на-деталь" + +#~ msgid "Scale must not be zero or negative!" +#~ msgstr "" +#~ "Коэффициент масштабирования не может быть нулевым или отрицательным!" diff --git a/res/locales/uk_UA.po b/res/locales/uk_UA.po new file mode 100644 index 0000000..1f2a210 --- /dev/null +++ b/res/locales/uk_UA.po @@ -0,0 +1,1934 @@ +# Ukrainian translations for SolveSpace package. +# Copyright (C) 2017 the SolveSpace authors +# This file is distributed under the same license as the SolveSpace package. +# AppSoft4 , 2017. +msgid "" +msgstr "" +"Project-Id-Version: SolveSpace 3.0\n" +"Report-Msgid-Bugs-To: whitequark@whitequark.org\n" +"POT-Creation-Date: 2021-01-17 19:54+0200\n" +"PO-Revision-Date: 2017-01-05 10:30+0000\n" +"Last-Translator: appsoft@ua.fm\n" +"Language-Team: OpenOrienteeringUkraine\n" +"Language: uk_UA\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: clipboard.cpp:310 +msgid "" +"Cut, paste, and copy work only in a workplane.\n" +"\n" +"Activate one with Sketch -> In Workplane." +msgstr "" + +#: clipboard.cpp:327 +msgid "Clipboard is empty; nothing to paste." +msgstr "" + +#: clipboard.cpp:374 +msgid "Number of copies to paste must be at least one." +msgstr "" + +#: clipboard.cpp:390 textscreens.cpp:783 +msgid "Scale cannot be zero." +msgstr "" + +#: clipboard.cpp:432 +msgid "Select one point to define origin of rotation." +msgstr "" + +#: clipboard.cpp:444 +msgid "Select two points to define translation vector." +msgstr "" + +#: clipboard.cpp:454 +msgid "" +"Transformation is identity. So all copies will be exactly on top of each " +"other." +msgstr "" + +#: clipboard.cpp:458 +msgid "Too many items to paste; split this into smaller pastes." +msgstr "" + +#: clipboard.cpp:463 +msgid "No workplane active." +msgstr "" + +#: confscreen.cpp:418 +msgid "Bad format: specify coordinates as x, y, z" +msgstr "" + +#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805 +msgid "Bad format: specify color as r, g, b" +msgstr "" + +#: confscreen.cpp:454 +msgid "" +"The perspective factor will have no effect until you enable View -> Use " +"Perspective Projection." +msgstr "" + +#: confscreen.cpp:467 confscreen.cpp:477 +#, c-format +msgid "Specify between 0 and %d digits after the decimal." +msgstr "" + +#: confscreen.cpp:489 +msgid "Export scale must not be zero!" +msgstr "" + +#: confscreen.cpp:501 +msgid "Cutter radius offset must not be negative!" +msgstr "" + +#: confscreen.cpp:555 +msgid "Bad value: autosave interval should be positive" +msgstr "" + +#: confscreen.cpp:558 +msgid "Bad format: specify interval in integral minutes" +msgstr "" + +#: constraint.cpp:12 +msgctxt "constr-name" +msgid "pts-coincident" +msgstr "" + +#: constraint.cpp:13 +msgctxt "constr-name" +msgid "pt-pt-distance" +msgstr "" + +#: constraint.cpp:14 +msgctxt "constr-name" +msgid "pt-line-distance" +msgstr "" + +#: constraint.cpp:15 +msgctxt "constr-name" +msgid "pt-plane-distance" +msgstr "" + +#: constraint.cpp:16 +msgctxt "constr-name" +msgid "pt-face-distance" +msgstr "" + +#: constraint.cpp:17 +msgctxt "constr-name" +msgid "proj-pt-pt-distance" +msgstr "" + +#: constraint.cpp:18 +msgctxt "constr-name" +msgid "pt-in-plane" +msgstr "" + +#: constraint.cpp:19 +msgctxt "constr-name" +msgid "pt-on-line" +msgstr "" + +#: constraint.cpp:20 +msgctxt "constr-name" +msgid "pt-on-face" +msgstr "" + +#: constraint.cpp:21 +msgctxt "constr-name" +msgid "eq-length" +msgstr "" + +#: constraint.cpp:22 +msgctxt "constr-name" +msgid "eq-length-and-pt-ln-dist" +msgstr "" + +#: constraint.cpp:23 +msgctxt "constr-name" +msgid "eq-pt-line-distances" +msgstr "" + +#: constraint.cpp:24 +msgctxt "constr-name" +msgid "length-ratio" +msgstr "" + +#: constraint.cpp:25 +msgctxt "constr-name" +msgid "length-difference" +msgstr "" + +#: constraint.cpp:26 +msgctxt "constr-name" +msgid "symmetric" +msgstr "" + +#: constraint.cpp:27 +msgctxt "constr-name" +msgid "symmetric-h" +msgstr "" + +#: constraint.cpp:28 +msgctxt "constr-name" +msgid "symmetric-v" +msgstr "" + +#: constraint.cpp:29 +msgctxt "constr-name" +msgid "symmetric-line" +msgstr "" + +#: constraint.cpp:30 +msgctxt "constr-name" +msgid "at-midpoint" +msgstr "" + +#: constraint.cpp:31 +msgctxt "constr-name" +msgid "horizontal" +msgstr "" + +#: constraint.cpp:32 +msgctxt "constr-name" +msgid "vertical" +msgstr "" + +#: constraint.cpp:33 +msgctxt "constr-name" +msgid "diameter" +msgstr "" + +#: constraint.cpp:34 +msgctxt "constr-name" +msgid "pt-on-circle" +msgstr "" + +#: constraint.cpp:35 +msgctxt "constr-name" +msgid "same-orientation" +msgstr "" + +#: constraint.cpp:36 +msgctxt "constr-name" +msgid "angle" +msgstr "" + +#: constraint.cpp:37 +msgctxt "constr-name" +msgid "parallel" +msgstr "" + +#: constraint.cpp:38 +msgctxt "constr-name" +msgid "arc-line-tangent" +msgstr "" + +#: constraint.cpp:39 +msgctxt "constr-name" +msgid "cubic-line-tangent" +msgstr "" + +#: constraint.cpp:40 +msgctxt "constr-name" +msgid "curve-curve-tangent" +msgstr "" + +#: constraint.cpp:41 +msgctxt "constr-name" +msgid "perpendicular" +msgstr "" + +#: constraint.cpp:42 +msgctxt "constr-name" +msgid "eq-radius" +msgstr "" + +#: constraint.cpp:43 +msgctxt "constr-name" +msgid "eq-angle" +msgstr "" + +#: constraint.cpp:44 +msgctxt "constr-name" +msgid "eq-line-len-arc-len" +msgstr "" + +#: constraint.cpp:45 +msgctxt "constr-name" +msgid "lock-where-dragged" +msgstr "" + +#: constraint.cpp:46 +msgctxt "constr-name" +msgid "comment" +msgstr "" + +#: constraint.cpp:140 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." +msgstr "" + +#: constraint.cpp:158 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." +msgstr "" + +#: constraint.cpp:183 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." +msgstr "" + +#: constraint.cpp:231 +msgid "" +"Bad selection for distance / diameter constraint. This constraint can apply " +"to:\n" +"\n" +" * two points (distance between points)\n" +" * a line segment (length)\n" +" * two points and a line segment or normal (projected distance)\n" +" * a workplane and a point (minimum distance)\n" +" * a line segment and a point (minimum distance)\n" +" * a plane face and a point (minimum distance)\n" +" * a circle or an arc (diameter)\n" +msgstr "" + +#: constraint.cpp:284 +msgid "" +"Bad selection for on point / curve / plane constraint. This constraint can " +"apply to:\n" +"\n" +" * two points (points coincident)\n" +" * a point and a workplane (point in plane)\n" +" * a point and a line segment (point on line)\n" +" * a point and a circle or arc (point on curve)\n" +" * a point and a plane face (point on face)\n" +msgstr "" + +#: constraint.cpp:346 +msgid "" +"Bad selection for equal length / radius constraint. This constraint can " +"apply to:\n" +"\n" +" * two line segments (equal length)\n" +" * two line segments and two points (equal point-line distances)\n" +" * a line segment and two points (equal point-line distances)\n" +" * a line segment, and a point and line segment (point-line distance " +"equals length)\n" +" * four line segments or normals (equal angle between A,B and C,D)\n" +" * three line segments or normals (equal angle between A,B and B,C)\n" +" * two circles or arcs (equal radius)\n" +" * a line segment and an arc (line segment length equals arc length)\n" +msgstr "" + +#: constraint.cpp:385 +msgid "" +"Bad selection for length ratio constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +msgstr "" + +#: constraint.cpp:402 +msgid "" +"Bad selection for length difference constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments\n" +msgstr "" + +#: constraint.cpp:428 +msgid "" +"Bad selection for at midpoint constraint. This constraint can apply to:\n" +"\n" +" * a line segment and a point (point at midpoint)\n" +" * a line segment and a workplane (line's midpoint on plane)\n" +msgstr "" + +#: constraint.cpp:486 +msgid "" +"Bad selection for symmetric constraint. This constraint can apply to:\n" +"\n" +" * two points or a line segment (symmetric about workplane's coordinate " +"axis)\n" +" * line segment, and two points or a line segment (symmetric about line " +"segment)\n" +" * workplane, and two points or a line segment (symmetric about " +"workplane)\n" +msgstr "" + +#: constraint.cpp:500 +msgid "" +"A workplane must be active when constraining symmetric without an explicit " +"symmetry plane." +msgstr "" + +#: constraint.cpp:530 +msgid "" +"Activate a workplane (with Sketch -> In Workplane) before applying a " +"horizontal or vertical constraint." +msgstr "" + +#: constraint.cpp:543 +msgid "" +"Bad selection for horizontal / vertical constraint. This constraint can " +"apply to:\n" +"\n" +" * two points\n" +" * a line segment\n" +msgstr "" + +#: constraint.cpp:564 +msgid "" +"Bad selection for same orientation constraint. This constraint can apply " +"to:\n" +"\n" +" * two normals\n" +msgstr "" + +#: constraint.cpp:614 +msgid "Must select an angle constraint." +msgstr "" + +#: constraint.cpp:627 +msgid "Must select a constraint with associated label." +msgstr "" + +#: constraint.cpp:638 +msgid "" +"Bad selection for angle constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" + +#: constraint.cpp:701 +msgid "Curve-curve tangency must apply in workplane." +msgstr "" + +#: constraint.cpp:711 +msgid "" +"Bad selection for parallel / tangent constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments (parallel)\n" +" * a line segment and a normal (parallel)\n" +" * two normals (parallel)\n" +" * two line segments, arcs, or beziers, that share an endpoint (tangent)\n" +msgstr "" + +#: constraint.cpp:729 +msgid "" +"Bad selection for perpendicular constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" + +#: constraint.cpp:744 +msgid "" +"Bad selection for lock point where dragged constraint. This constraint can " +"apply to:\n" +"\n" +" * a point\n" +msgstr "" + +#: constraint.cpp:755 +msgid "click center of comment text" +msgstr "" + +#: export.cpp:19 +msgid "" +"No solid model present; draw one with extrudes and revolves, or use Export " +"2d View to export bare lines and curves." +msgstr "" + +#: export.cpp:61 +msgid "" +"Bad selection for export section. Please select:\n" +"\n" +" * nothing, with an active workplane (workplane is section plane)\n" +" * a face (section plane through face)\n" +" * a point and two line segments (plane through point and parallel to " +"lines)\n" +msgstr "" + +#: export.cpp:822 +msgid "Active group mesh is empty; nothing to export." +msgstr "" + +#: exportvector.cpp:337 +msgid "freehand lines were replaced with continuous lines" +msgstr "" + +#: exportvector.cpp:339 +msgid "zigzag lines were replaced with continuous lines" +msgstr "" + +#: exportvector.cpp:593 +msgid "" +"Some aspects of the drawing have no DXF equivalent and were not exported:\n" +msgstr "" + +#: exportvector.cpp:839 +msgid "" +"PDF page size exceeds 200 by 200 inches; many viewers may reject this file." +msgstr "" + +#: file.cpp:44 group.cpp:91 +msgctxt "group-name" +msgid "sketch-in-plane" +msgstr "" + +#: file.cpp:62 +msgctxt "group-name" +msgid "#references" +msgstr "" + +#: file.cpp:549 +msgid "" +"Unrecognized data in file. This file may be corrupt, or from a newer version " +"of the program." +msgstr "" + +#: file.cpp:859 +msgctxt "title" +msgid "Missing File" +msgstr "" + +#: file.cpp:860 +#, c-format +msgctxt "dialog" +msgid "The linked file “%s” is not present." +msgstr "" + +#: file.cpp:862 +msgctxt "dialog" +msgid "" +"Do you want to locate it manually?\n" +"\n" +"If you decline, any geometry that depends on the missing file will be " +"permanently removed." +msgstr "" + +#: file.cpp:865 +msgctxt "button" +msgid "&Yes" +msgstr "" + +#: file.cpp:867 +msgctxt "button" +msgid "&No" +msgstr "" + +#: file.cpp:869 solvespace.cpp:569 +msgctxt "button" +msgid "&Cancel" +msgstr "" + +#: graphicswin.cpp:41 +msgid "&File" +msgstr "&Файл" + +#: graphicswin.cpp:42 +msgid "&New" +msgstr "&Новий" + +#: graphicswin.cpp:43 +msgid "&Open..." +msgstr "&Відкрити..." + +#: graphicswin.cpp:44 +msgid "Open &Recent" +msgstr "Відкрити &Недавні" + +#: graphicswin.cpp:45 +msgid "&Save" +msgstr "&Зберегти" + +#: graphicswin.cpp:46 +msgid "Save &As..." +msgstr "Зберегти &Як..." + +#: graphicswin.cpp:48 +msgid "Export &Image..." +msgstr "Експортувати &Зображення..." + +#: graphicswin.cpp:49 +msgid "Export 2d &View..." +msgstr "Експортувати 2d &Вигляд..." + +#: graphicswin.cpp:50 +msgid "Export 2d &Section..." +msgstr "Експортувати 2d &Секцію..." + +#: graphicswin.cpp:51 +msgid "Export 3d &Wireframe..." +msgstr "Експортувати 3d &Скелет..." + +#: graphicswin.cpp:52 +msgid "Export Triangle &Mesh..." +msgstr "Експортувати Тригранний &Каркас..." + +#: graphicswin.cpp:53 +msgid "Export &Surfaces..." +msgstr "Експортувати &Поверхні..." + +#: graphicswin.cpp:54 +msgid "Im&port..." +msgstr "Ім&портувати..." + +#: graphicswin.cpp:57 +msgid "E&xit" +msgstr "В&ихід" + +#: graphicswin.cpp:60 +msgid "&Edit" +msgstr "&Редагувати" + +#: graphicswin.cpp:61 +msgid "&Undo" +msgstr "&Відмінити" + +#: graphicswin.cpp:62 +msgid "&Redo" +msgstr "&Повторити" + +#: graphicswin.cpp:63 +msgid "Re&generate All" +msgstr "Ре&генерувати Все" + +#: graphicswin.cpp:65 +msgid "Snap Selection to &Grid" +msgstr "Прикріпити Виділене до &Сітки" + +#: graphicswin.cpp:66 +msgid "Rotate Imported &90°" +msgstr "Обернути Імпортоване на &90°" + +#: graphicswin.cpp:68 +msgid "Cu&t" +msgstr "Ви&різати" + +#: graphicswin.cpp:69 +msgid "&Copy" +msgstr "&Копіювати" + +#: graphicswin.cpp:70 +msgid "&Paste" +msgstr "&Вставити" + +#: graphicswin.cpp:71 +msgid "Paste &Transformed..." +msgstr "Вставити &Трансфмованим..." + +#: graphicswin.cpp:72 +msgid "&Delete" +msgstr "&Delete" + +#: graphicswin.cpp:74 +msgid "Select &Edge Chain" +msgstr "Виділити Ланцуг &Ребер" + +#: graphicswin.cpp:75 +msgid "Select &All" +msgstr "Виділити &Усе" + +#: graphicswin.cpp:76 +msgid "&Unselect All" +msgstr "&Зняти Виділення з Усього" + +#: graphicswin.cpp:78 +msgid "&Line Styles..." +msgstr "" + +#: graphicswin.cpp:79 +msgid "&View Projection..." +msgstr "" + +#: graphicswin.cpp:81 +msgid "Con&figuration..." +msgstr "" + +#: graphicswin.cpp:84 +msgid "&View" +msgstr "&View" + +#: graphicswin.cpp:85 +msgid "Zoom &In" +msgstr "На&близити" + +#: graphicswin.cpp:86 +msgid "Zoom &Out" +msgstr "Від&далити" + +#: graphicswin.cpp:87 +msgid "Zoom To &Fit" +msgstr "Умістити на &Екрані" + +#: graphicswin.cpp:89 +msgid "Align View to &Workplane" +msgstr "Вирівняти Вигляд до Робочої &Площини" + +#: graphicswin.cpp:90 +msgid "Nearest &Ortho View" +msgstr "Найближчий &Ортогональний Вигляд" + +#: graphicswin.cpp:91 +msgid "Nearest &Isometric View" +msgstr "Найближчий &Ізометричний Вигляд" + +#: graphicswin.cpp:92 +msgid "&Center View At Point" +msgstr "&Центрувати Вигляд На Точці" + +#: graphicswin.cpp:94 +msgid "Show Snap &Grid" +msgstr "Показати &Сітку Прикріплення" + +#: graphicswin.cpp:95 +msgid "Darken Inactive Solids" +msgstr "" + +#: graphicswin.cpp:96 +msgid "Use &Perspective Projection" +msgstr "Використовувати &Перспективну Проекцію" + +#: graphicswin.cpp:97 +msgid "Dimension &Units" +msgstr "" + +#: graphicswin.cpp:98 +msgid "Dimensions in &Millimeters" +msgstr "Розміри в &Міліметрах" + +#: graphicswin.cpp:99 +msgid "Dimensions in M&eters" +msgstr "" + +#: graphicswin.cpp:100 +msgid "Dimensions in &Inches" +msgstr "Розміри в &Дюймах" + +#: graphicswin.cpp:102 +msgid "Show &Toolbar" +msgstr "Показати Панель &Інструментів" + +#: graphicswin.cpp:103 +msgid "Show Property Bro&wser" +msgstr "Показати Вікно Власти&востей" + +#: graphicswin.cpp:105 +msgid "&Full Screen" +msgstr "&Повний Екран" + +#: graphicswin.cpp:107 +msgid "&New Group" +msgstr "&Нова Група" + +#: graphicswin.cpp:108 +msgid "Sketch In &3d" +msgstr "Креслення В &3d" + +#: graphicswin.cpp:109 +msgid "Sketch In New &Workplane" +msgstr "Креслення В Новій Робочій &Площині" + +#: graphicswin.cpp:111 +msgid "Step &Translating" +msgstr "Покрокове &Переміщення" + +#: graphicswin.cpp:112 +msgid "Step &Rotating" +msgstr "Покрокове &Обертання" + +#: graphicswin.cpp:114 +msgid "E&xtrude" +msgstr "Ви&давити" + +#: graphicswin.cpp:115 +msgid "&Helix" +msgstr "" + +#: graphicswin.cpp:116 +msgid "&Lathe" +msgstr "&Виточити" + +#: graphicswin.cpp:117 +msgid "Re&volve" +msgstr "" + +#: graphicswin.cpp:119 +msgid "Link / Assemble..." +msgstr "Приєднати / Монтувати..." + +#: graphicswin.cpp:120 +msgid "Link Recent" +msgstr "Приєднати Недавні" + +#: graphicswin.cpp:122 +msgid "&Sketch" +msgstr "&Креслення" + +#: graphicswin.cpp:123 +msgid "In &Workplane" +msgstr "В Робочій &Площині" + +#: graphicswin.cpp:124 +msgid "Anywhere In &3d" +msgstr "Будь-де В &3d" + +#: graphicswin.cpp:126 +msgid "Datum &Point" +msgstr "Опорна &Точка" + +#: graphicswin.cpp:127 +msgid "&Workplane" +msgstr "Робоча &Площина" + +#: graphicswin.cpp:129 +msgid "Line &Segment" +msgstr "&Відрізок Прямої" + +#: graphicswin.cpp:130 +msgid "C&onstruction Line Segment" +msgstr "Контсрук&ційний Відрізок Прямої" + +#: graphicswin.cpp:131 +msgid "&Rectangle" +msgstr "&Прямокутник" + +#: graphicswin.cpp:132 +msgid "&Circle" +msgstr "&Коло" + +#: graphicswin.cpp:133 +msgid "&Arc of a Circle" +msgstr "&Дуга Кола" + +#: graphicswin.cpp:134 +msgid "&Bezier Cubic Spline" +msgstr "Кубічний Сплайн &Без'є" + +#: graphicswin.cpp:136 +msgid "&Text in TrueType Font" +msgstr "&Текст з TrueType Шрифтом" + +#: graphicswin.cpp:137 +msgid "&Image" +msgstr "" + +#: graphicswin.cpp:139 +msgid "To&ggle Construction" +msgstr "Пере&мкнути Конструктивність" + +#: graphicswin.cpp:140 +msgid "Tangent &Arc at Point" +msgstr "Дотична &Дуга на Точці" + +#: graphicswin.cpp:141 +msgid "Split Curves at &Intersection" +msgstr "Розрізати Криві на &Перетині" + +#: graphicswin.cpp:143 +msgid "&Constrain" +msgstr "&Обмежити" + +#: graphicswin.cpp:144 +msgid "&Distance / Diameter" +msgstr "&Відстань / Діаметр" + +#: graphicswin.cpp:145 +msgid "Re&ference Dimension" +msgstr "Від&носний Розмір" + +#: graphicswin.cpp:146 +msgid "A&ngle" +msgstr "К&ут" + +#: graphicswin.cpp:147 +msgid "Reference An&gle" +msgstr "Відносний К&ут" + +#: graphicswin.cpp:148 +msgid "Other S&upplementary Angle" +msgstr "Інший Су&міжний Кут" + +#: graphicswin.cpp:149 +msgid "Toggle R&eference Dim" +msgstr "Перемкнути Від&носність Розмірів" + +#: graphicswin.cpp:151 +msgid "&Horizontal" +msgstr "&Горизонтально" + +#: graphicswin.cpp:152 +msgid "&Vertical" +msgstr "&Вертикально" + +#: graphicswin.cpp:154 +msgid "&On Point / Curve / Plane" +msgstr "&На точці / Кривій / Площині" + +#: graphicswin.cpp:155 +msgid "E&qual Length / Radius / Angle" +msgstr "Рі&вні Довжина / Радіус / Кут" + +#: graphicswin.cpp:156 +msgid "Length Ra&tio" +msgstr "Про&порція Довжин" + +#: graphicswin.cpp:157 +msgid "Length Diff&erence" +msgstr "Рі&зниця Довжин" + +#: graphicswin.cpp:158 +msgid "At &Midpoint" +msgstr "До &Середини" + +#: graphicswin.cpp:159 +msgid "S&ymmetric" +msgstr "Си&метрично" + +#: graphicswin.cpp:160 +msgid "Para&llel / Tangent" +msgstr "Пара&лельно / Дотична" + +#: graphicswin.cpp:161 +msgid "&Perpendicular" +msgstr "&Препендикулярно" + +#: graphicswin.cpp:162 +msgid "Same Orient&ation" +msgstr "Однакова Орієн&тація" + +#: graphicswin.cpp:163 +msgid "Lock Point Where &Dragged" +msgstr "Фіксувати Точку Після &Переміщення" + +#: graphicswin.cpp:165 +msgid "Comment" +msgstr "Коментар" + +#: graphicswin.cpp:167 +msgid "&Analyze" +msgstr "&Аналізувати" + +#: graphicswin.cpp:168 +msgid "Measure &Volume" +msgstr "Обрахувати &Об'єм" + +#: graphicswin.cpp:169 +msgid "Measure A&rea" +msgstr "Обрахувати Пл&ощу" + +#: graphicswin.cpp:170 +msgid "Measure &Perimeter" +msgstr "Обрахувати &Периметр" + +#: graphicswin.cpp:171 +msgid "Show &Interfering Parts" +msgstr "Показати &Дотичні Частини" + +#: graphicswin.cpp:172 +msgid "Show &Naked Edges" +msgstr "Показати &Приховані Ребра" + +#: graphicswin.cpp:173 +msgid "Show &Center of Mass" +msgstr "" + +#: graphicswin.cpp:175 +msgid "Show &Underconstrained Points" +msgstr "" + +#: graphicswin.cpp:177 +msgid "&Trace Point" +msgstr "&Трасувати Точку" + +#: graphicswin.cpp:178 +msgid "&Stop Tracing..." +msgstr "&Зупити Трасування..." + +#: graphicswin.cpp:179 +msgid "Step &Dimension..." +msgstr "Прорахувати &Розмір..." + +#: graphicswin.cpp:181 +msgid "&Help" +msgstr "&Довідка" + +#: graphicswin.cpp:182 +msgid "&Language" +msgstr "&Мова" + +#: graphicswin.cpp:183 +msgid "&Website / Manual" +msgstr "&Вебсайт / Посібник" + +#: graphicswin.cpp:185 +msgid "&About" +msgstr "&Про програму" + +#: graphicswin.cpp:355 +msgid "(no recent files)" +msgstr "" + +#: graphicswin.cpp:363 +#, c-format +msgid "File '%s' does not exist." +msgstr "" + +#: graphicswin.cpp:725 +msgid "No workplane is active, so the grid will not appear." +msgstr "" + +#: graphicswin.cpp:740 +msgid "" +"The perspective factor is set to zero, so the view will always be a parallel " +"projection.\n" +"\n" +"For a perspective projection, modify the perspective factor in the " +"configuration screen. A value around 0.3 is typical." +msgstr "" + +#: graphicswin.cpp:819 +msgid "" +"Select a point; this point will become the center of the view on screen." +msgstr "" + +#: graphicswin.cpp:1114 +msgid "No additional entities share endpoints with the selected entities." +msgstr "" + +#: graphicswin.cpp:1132 +msgid "" +"To use this command, select a point or other entity from an linked part, or " +"make a link group the active group." +msgstr "" + +#: graphicswin.cpp:1155 +msgid "" +"No workplane is active. Activate a workplane (with Sketch -> In Workplane) " +"to define the plane for the snap grid." +msgstr "" + +#: graphicswin.cpp:1162 +msgid "" +"Can't snap these items to grid; select points, text comments, or constraints " +"with a label. To snap a line, select its endpoints." +msgstr "" + +#: graphicswin.cpp:1247 +msgid "No workplane selected. Activating default workplane for this group." +msgstr "" + +#: graphicswin.cpp:1250 +msgid "" +"No workplane is selected, and the active group does not have a default " +"workplane. Try selecting a workplane, or activating a sketch-in-new-" +"workplane group." +msgstr "" + +#: graphicswin.cpp:1271 +msgid "" +"Bad selection for tangent arc at point. Select a single point, or select " +"nothing to set up arc parameters." +msgstr "" + +#: graphicswin.cpp:1282 +msgid "click point on arc (draws anti-clockwise)" +msgstr "" + +#: graphicswin.cpp:1283 +msgid "click to place datum point" +msgstr "" + +#: graphicswin.cpp:1284 +msgid "click first point of line segment" +msgstr "" + +#: graphicswin.cpp:1286 +msgid "click first point of construction line segment" +msgstr "" + +#: graphicswin.cpp:1287 +msgid "click first point of cubic segment" +msgstr "" + +#: graphicswin.cpp:1288 +msgid "click center of circle" +msgstr "" + +#: graphicswin.cpp:1289 +msgid "click origin of workplane" +msgstr "" + +#: graphicswin.cpp:1290 +msgid "click one corner of rectangle" +msgstr "" + +#: graphicswin.cpp:1291 +msgid "click top left of text" +msgstr "" + +#: graphicswin.cpp:1297 +msgid "click top left of image" +msgstr "" + +#: graphicswin.cpp:1309 +msgid "" +"No entities are selected. Select entities before trying to toggle their " +"construction state." +msgstr "" + +#: group.cpp:86 +msgctxt "group-name" +msgid "sketch-in-3d" +msgstr "" + +#: group.cpp:142 +msgid "" +"Bad selection for new sketch in workplane. This group can be created with:\n" +"\n" +" * a point (through the point, orthogonal to coordinate axes)\n" +" * a point and two line segments (through the point, parallel to the " +"lines)\n" +" * a workplane (copy of the workplane)\n" +msgstr "" + +#: group.cpp:154 +msgid "" +"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch " +"will be extruded normal to the workplane." +msgstr "" + +#: group.cpp:163 +msgctxt "group-name" +msgid "extrude" +msgstr "" + +#: group.cpp:168 +msgid "Lathe operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:179 +msgid "" +"Bad selection for new lathe group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" + +#: group.cpp:189 +msgctxt "group-name" +msgid "lathe" +msgstr "" + +#: group.cpp:194 +msgid "Revolve operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:205 +msgid "" +"Bad selection for new revolve group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" + +#: group.cpp:217 +msgctxt "group-name" +msgid "revolve" +msgstr "" + +#: group.cpp:222 +msgid "Helix operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:233 +msgid "" +"Bad selection for new helix group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" + +#: group.cpp:245 +msgctxt "group-name" +msgid "helix" +msgstr "" + +#: group.cpp:258 +msgid "" +"Bad selection for new rotation. This group can be created with:\n" +"\n" +" * a point, while locked in workplane (rotate in plane, about that " +"point)\n" +" * a point and a line or a normal (rotate about an axis through the " +"point, and parallel to line / normal)\n" +msgstr "" + +#: group.cpp:271 +msgctxt "group-name" +msgid "rotate" +msgstr "" + +#: group.cpp:282 +msgctxt "group-name" +msgid "translate" +msgstr "" + +#: group.cpp:400 +msgid "(unnamed)" +msgstr "" + +#: groupmesh.cpp:709 +msgid "not closed contour, or not all same style!" +msgstr "" + +#: groupmesh.cpp:722 +msgid "points not all coplanar!" +msgstr "" + +#: groupmesh.cpp:724 +msgid "contour is self-intersecting!" +msgstr "" + +#: groupmesh.cpp:726 +msgid "zero-length edge!" +msgstr "" + +#: modify.cpp:254 +msgid "Must be sketching in workplane to create tangent arc." +msgstr "" + +#: modify.cpp:301 +msgid "" +"To create a tangent arc, select a point where two non-construction lines or " +"circles in this group and workplane join." +msgstr "" + +#: modify.cpp:388 +msgid "" +"Couldn't round this corner. Try a smaller radius, or try creating the " +"desired geometry by hand with tangency constraints." +msgstr "" + +#: modify.cpp:597 +msgid "Couldn't split this entity; lines, circles, or cubics only." +msgstr "" + +#: modify.cpp:624 +msgid "Must be sketching in workplane to split." +msgstr "" + +#: modify.cpp:631 +msgid "" +"Select two entities that intersect each other (e.g. two lines/circles/arcs " +"or a line/circle/arc and a point)." +msgstr "" + +#: modify.cpp:736 +msgid "Can't split; no intersection found." +msgstr "" + +#: mouse.cpp:560 +msgid "Assign to Style" +msgstr "Встановити Стиль" + +#: mouse.cpp:576 +msgid "No Style" +msgstr "Без Стилю" + +#: mouse.cpp:579 +msgid "Newly Created Custom Style..." +msgstr "Створити Користувацький Стиль..." + +#: mouse.cpp:586 +msgid "Group Info" +msgstr "Параметри Групи" + +#: mouse.cpp:606 +msgid "Style Info" +msgstr "Параметри Стилю" + +#: mouse.cpp:626 +msgid "Select Edge Chain" +msgstr "Виділити Ланцюг Ребер" + +#: mouse.cpp:632 +msgid "Toggle Reference Dimension" +msgstr "Перемкнути Відносність Розміру" + +#: mouse.cpp:638 +msgid "Other Supplementary Angle" +msgstr "Інший Суміжний Кут" + +#: mouse.cpp:643 +msgid "Snap to Grid" +msgstr "Прикріпити до Сітки" + +#: mouse.cpp:652 +msgid "Remove Spline Point" +msgstr "Видалити Точку Сплайну" + +#: mouse.cpp:687 +msgid "Add Spline Point" +msgstr "Додати Точку Сплайну" + +#: mouse.cpp:691 +msgid "Cannot add spline point: maximum number of points reached." +msgstr "" + +#: mouse.cpp:716 +msgid "Toggle Construction" +msgstr "Пермкнути Конструктивність" + +#: mouse.cpp:731 +msgid "Delete Point-Coincident Constraint" +msgstr "Роз'єднати З'єднання Точок" + +#: mouse.cpp:750 +msgid "Cut" +msgstr "Вирізати" + +#: mouse.cpp:752 +msgid "Copy" +msgstr "Копіювати" + +#: mouse.cpp:756 +msgid "Select All" +msgstr "Виділити Усе" + +#: mouse.cpp:761 +msgid "Paste" +msgstr "Вставити" + +#: mouse.cpp:763 +msgid "Paste Transformed..." +msgstr "Вставити Трансформованим..." + +#: mouse.cpp:768 +msgid "Delete" +msgstr "Видалити" + +#: mouse.cpp:771 +msgid "Unselect All" +msgstr "Зняти Виділення з Усього" + +#: mouse.cpp:778 +msgid "Unselect Hovered" +msgstr "Зняти Виділення з Наведеного" + +#: mouse.cpp:787 +msgid "Zoom to Fit" +msgstr "Умістити на Екрані" + +#: mouse.cpp:989 mouse.cpp:1276 +msgid "click next point of line, or press Esc" +msgstr "" + +#: mouse.cpp:995 +msgid "" +"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" + +#: mouse.cpp:1029 +msgid "click to place other corner of rectangle" +msgstr "" + +#: mouse.cpp:1049 +msgid "click to set radius" +msgstr "" + +#: mouse.cpp:1054 +msgid "" +"Can't draw arc in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" + +#: mouse.cpp:1073 +msgid "click to place point" +msgstr "" + +#: mouse.cpp:1089 +msgid "click next point of cubic, or press Esc" +msgstr "" + +#: mouse.cpp:1094 +msgid "" +"Sketching in a workplane already; sketch in 3d before creating new workplane." +msgstr "" + +#: mouse.cpp:1110 +msgid "" +"Can't draw text in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" + +#: mouse.cpp:1127 +msgid "click to place bottom right of text" +msgstr "" + +#: mouse.cpp:1133 +msgid "" +"Can't draw image in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "" + +#: mouse.cpp:1160 +msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" +msgstr "" + +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511 +msgctxt "file-type" +msgid "SolveSpace models" +msgstr "" + +#: platform/gui.cpp:90 +msgctxt "file-type" +msgid "IDF circuit board" +msgstr "" + +#: platform/gui.cpp:94 +msgctxt "file-type" +msgid "PNG image" +msgstr "" + +#: platform/gui.cpp:98 +msgctxt "file-type" +msgid "STL mesh" +msgstr "" + +#: platform/gui.cpp:99 +msgctxt "file-type" +msgid "Wavefront OBJ mesh" +msgstr "" + +#: platform/gui.cpp:100 +msgctxt "file-type" +msgid "Three.js-compatible mesh, with viewer" +msgstr "" + +#: platform/gui.cpp:101 +msgctxt "file-type" +msgid "Three.js-compatible mesh, mesh only" +msgstr "" + +#: platform/gui.cpp:102 +msgctxt "file-type" +msgid "VRML text file" +msgstr "" + +#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 +msgctxt "file-type" +msgid "STEP file" +msgstr "" + +#: platform/gui.cpp:110 +msgctxt "file-type" +msgid "PDF file" +msgstr "" + +#: platform/gui.cpp:111 +msgctxt "file-type" +msgid "Encapsulated PostScript" +msgstr "" + +#: platform/gui.cpp:112 +msgctxt "file-type" +msgid "Scalable Vector Graphics" +msgstr "" + +#: platform/gui.cpp:114 platform/gui.cpp:121 +msgctxt "file-type" +msgid "DXF file (AutoCAD 2007)" +msgstr "" + +#: platform/gui.cpp:115 +msgctxt "file-type" +msgid "HPGL file" +msgstr "" + +#: platform/gui.cpp:116 +msgctxt "file-type" +msgid "G Code" +msgstr "" + +#: platform/gui.cpp:125 +msgctxt "file-type" +msgid "AutoCAD DXF and DWG files" +msgstr "" + +#: platform/gui.cpp:129 +msgctxt "file-type" +msgid "Comma-separated values" +msgstr "" + +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 +msgid "untitled" +msgstr "" + +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1573 +msgctxt "title" +msgid "Save File" +msgstr "" + +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1575 +msgctxt "title" +msgid "Open File" +msgstr "" + +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 +msgctxt "button" +msgid "_Cancel" +msgstr "" + +#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 +msgctxt "button" +msgid "_Save" +msgstr "" + +#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 +msgctxt "button" +msgid "_Open" +msgstr "" + +#: solvespace.cpp:169 +msgctxt "title" +msgid "Autosave Available" +msgstr "" + +#: solvespace.cpp:170 +msgctxt "dialog" +msgid "An autosave file is available for this sketch." +msgstr "" + +#: solvespace.cpp:171 +msgctxt "dialog" +msgid "Do you want to load the autosave file instead?" +msgstr "" + +#: solvespace.cpp:172 +msgctxt "button" +msgid "&Load autosave" +msgstr "" + +#: solvespace.cpp:174 +msgctxt "button" +msgid "Do&n't Load" +msgstr "" + +#: solvespace.cpp:557 +msgctxt "title" +msgid "Modified File" +msgstr "" + +#: solvespace.cpp:559 +#, c-format +msgctxt "dialog" +msgid "Do you want to save the changes you made to the sketch “%s”?" +msgstr "" + +#: solvespace.cpp:562 +msgctxt "dialog" +msgid "Do you want to save the changes you made to the new sketch?" +msgstr "" + +#: solvespace.cpp:565 +msgctxt "dialog" +msgid "Your changes will be lost if you don't save them." +msgstr "" + +#: solvespace.cpp:566 +msgctxt "button" +msgid "&Save" +msgstr "" + +#: solvespace.cpp:568 +msgctxt "button" +msgid "Do&n't Save" +msgstr "" + +#: solvespace.cpp:589 +msgctxt "title" +msgid "(new sketch)" +msgstr "" + +#: solvespace.cpp:596 +msgctxt "title" +msgid "Property Browser" +msgstr "" + +#: solvespace.cpp:658 +msgid "" +"Constraints are currently shown, and will be exported in the toolpath. This " +"is probably not what you want; hide them by clicking the link at the top of " +"the text window." +msgstr "" + +#: solvespace.cpp:730 +#, c-format +msgid "" +"Can't identify file type from file extension of filename '%s'; try .dxf or ." +"dwg." +msgstr "" + +#: solvespace.cpp:778 +msgid "Constraint must have a label, and must not be a reference dimension." +msgstr "" + +#: solvespace.cpp:782 +msgid "Bad selection for step dimension; select a constraint." +msgstr "" + +#: solvespace.cpp:806 +msgid "The assembly does not interfere, good." +msgstr "" + +#: solvespace.cpp:822 +#, c-format +msgid "" +"The volume of the solid model is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:831 +#, c-format +msgid "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:836 +msgid "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." +msgstr "" + +#: solvespace.cpp:851 +#, c-format +msgid "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:860 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." +msgstr "" + +#: solvespace.cpp:872 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:892 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:898 +msgid "Bad selection for perimeter; select line segments, arcs, and curves." +msgstr "" + +#: solvespace.cpp:914 +msgid "Bad selection for trace; select a single point." +msgstr "" + +#: solvespace.cpp:941 +#, c-format +msgid "Couldn't write to '%s'" +msgstr "" + +#: solvespace.cpp:971 +msgid "The mesh is self-intersecting (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:972 +msgid "The mesh is not self-intersecting (okay, valid)." +msgstr "" + +#: solvespace.cpp:974 +msgid "The mesh has naked edges (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:975 +msgid "The mesh is watertight (okay, valid)." +msgstr "" + +#: solvespace.cpp:978 +#, c-format +msgid "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." +msgstr "" + +#: solvespace.cpp:982 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" + +#: solvespace.cpp:985 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" + +#: solvespace.cpp:998 +#, c-format +msgid "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" +msgstr "" + +#: style.cpp:166 +msgid "" +"Can't assign style to an entity that's derived from another entity; try " +"assigning a style to this entity's parent." +msgstr "" + +#: style.cpp:665 +msgid "Style name cannot be empty" +msgstr "" + +#: textscreens.cpp:741 +msgid "Can't repeat fewer than 1 time." +msgstr "" + +#: textscreens.cpp:745 +msgid "Can't repeat more than 999 times." +msgstr "" + +#: textscreens.cpp:770 +msgid "Group name cannot be empty" +msgstr "" + +#: textscreens.cpp:813 +msgid "Opacity must be between zero and one." +msgstr "" + +#: textscreens.cpp:848 +msgid "Radius cannot be zero or negative." +msgstr "" + +#: toolbar.cpp:18 +msgid "Sketch line segment" +msgstr "Накреслети відрізок прямої" + +#: toolbar.cpp:20 +msgid "Sketch rectangle" +msgstr "Накреслити прямокутник" + +#: toolbar.cpp:22 +msgid "Sketch circle" +msgstr "Накреслити коло" + +#: toolbar.cpp:24 +msgid "Sketch arc of a circle" +msgstr "Накреслити дугу кола" + +#: toolbar.cpp:26 +msgid "Sketch curves from text in a TrueType font" +msgstr "Накреслити криві з тексту на TrueType шрифті" + +#: toolbar.cpp:28 +msgid "Sketch image from a file" +msgstr "" + +#: toolbar.cpp:30 +msgid "Create tangent arc at selected point" +msgstr "Створити дотичну дугу у вибраній точці" + +#: toolbar.cpp:32 +msgid "Sketch cubic Bezier spline" +msgstr "Накреслити кубічний сплайн Без'є" + +#: toolbar.cpp:34 +msgid "Sketch datum point" +msgstr "Накреслити опорну точку" + +#: toolbar.cpp:36 +msgid "Toggle construction" +msgstr "Перемкнути конструктивність" + +#: toolbar.cpp:38 +msgid "Split lines / curves where they intersect" +msgstr "Розрізати лініх / криві в місцях перетину" + +#: toolbar.cpp:42 +msgid "Constrain distance / diameter / length" +msgstr "Визначити відстань / діаметр / довжину" + +#: toolbar.cpp:44 +msgid "Constrain angle" +msgstr "Визначити кут" + +#: toolbar.cpp:46 +msgid "Constrain to be horizontal" +msgstr "Встановити горизонтально" + +#: toolbar.cpp:48 +msgid "Constrain to be vertical" +msgstr "Встановити перпендикулярно" + +#: toolbar.cpp:50 +msgid "Constrain to be parallel or tangent" +msgstr "Встановити паралельно або дотично" + +#: toolbar.cpp:52 +msgid "Constrain to be perpendicular" +msgstr "Встановити перпендикулярно" + +#: toolbar.cpp:54 +msgid "Constrain point on line / curve / plane / point" +msgstr "Прив'язати точку до лінії / кривої / площини / точки" + +#: toolbar.cpp:56 +msgid "Constrain symmetric" +msgstr "Встановити симетрично" + +#: toolbar.cpp:58 +msgid "Constrain equal length / radius / angle" +msgstr "Встановити однаковими відстань / радіус / кут" + +#: toolbar.cpp:60 +msgid "Constrain normals in same orientation" +msgstr "Спрямувати нормалі в одному напрямку" + +#: toolbar.cpp:62 +msgid "Other supplementary angle" +msgstr "Інший суміжний кут" + +#: toolbar.cpp:64 +msgid "Toggle reference dimension" +msgstr "Перемкнути відносність розміру" + +#: toolbar.cpp:68 +msgid "New group extruding active sketch" +msgstr "Нова група екструдування активного креслення" + +#: toolbar.cpp:70 +msgid "New group rotating active sketch" +msgstr "Нова група обертання актиного креслення" + +#: toolbar.cpp:72 +msgid "New group helix from active sketch" +msgstr "" + +#: toolbar.cpp:74 +msgid "New group revolve active sketch" +msgstr "" + +#: toolbar.cpp:76 +msgid "New group step and repeat rotating" +msgstr "Нова група крокування і повторення обертання" + +#: toolbar.cpp:78 +msgid "New group step and repeat translating" +msgstr "Нова група крокування і повторення зміщення" + +#: toolbar.cpp:80 +msgid "New group in new workplane (thru given entities)" +msgstr "Нова група в новій площині (через обрані об'екти)" + +#: toolbar.cpp:82 +msgid "New group in 3d" +msgstr "Нова група в 3d" + +#: toolbar.cpp:84 +msgid "New group linking / assembling file" +msgstr "Нова група приєднання / монтування файлу" + +#: toolbar.cpp:88 +msgid "Nearest isometric view" +msgstr "Найближчий ізометричний вигляд" + +#: toolbar.cpp:90 +msgid "Align view to active workplane" +msgstr "Вирівняти вигляд до активної робочої площини" + +#: util.cpp:165 +msgctxt "title" +msgid "Error" +msgstr "" + +#: util.cpp:165 +msgctxt "title" +msgid "Message" +msgstr "" + +#: util.cpp:170 +msgctxt "button" +msgid "&OK" +msgstr "" + +#: view.cpp:78 +msgid "Scale cannot be zero or negative." +msgstr "" + +#: view.cpp:90 view.cpp:99 +msgid "Bad format: specify x, y, z" +msgstr "" + +#~ msgid "Show Degrees of &Freedom" +#~ msgstr "Показати Степені &Свободи" + +#~ msgid "Show Menu &Bar" +#~ msgstr "Показати Панель &Меню" diff --git a/res/locales/zh_CN.po b/res/locales/zh_CN.po new file mode 100644 index 0000000..245b452 --- /dev/null +++ b/res/locales/zh_CN.po @@ -0,0 +1,2019 @@ +# Chinese translations for SolveSpace package. +# Copyright (C) 2020 the PACKAGE authors +# This file is distributed under the same license as the SolveSpace package. +# , 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: SolveSpace 3.0\n" +"Report-Msgid-Bugs-To: whitequark@whitequark.org\n" +"POT-Creation-Date: 2021-01-17 19:54+0200\n" +"PO-Revision-Date: 2020-09-28 12:42+0800\n" +"Last-Translator: lomatus@163.com\n" +"Language-Team: none\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.1\n" + +#: clipboard.cpp:310 +msgid "" +"Cut, paste, and copy work only in a workplane.\n" +"\n" +"Activate one with Sketch -> In Workplane." +msgstr "" +"仅在工作平面中剪切、粘贴和复制工作。\n" +"\n" +"使用\"工作平面中的草图 -+\"激活一个。" + +#: clipboard.cpp:327 +msgid "Clipboard is empty; nothing to paste." +msgstr "剪贴板为空;没有要粘贴的内容。" + +#: clipboard.cpp:374 +msgid "Number of copies to paste must be at least one." +msgstr "要粘贴的副本数必须至少为 1 个。" + +#: clipboard.cpp:390 textscreens.cpp:783 +msgid "Scale cannot be zero." +msgstr "缩放不能为零。" + +#: clipboard.cpp:432 +msgid "Select one point to define origin of rotation." +msgstr "选择一个点以定义旋转原点。" + +#: clipboard.cpp:444 +msgid "Select two points to define translation vector." +msgstr "选择两个点来定义转换向量。" + +#: clipboard.cpp:454 +msgid "" +"Transformation is identity. So all copies will be exactly on top of each " +"other." +msgstr "转换就是标识,因此所有的复制在彼此之上。" + +#: clipboard.cpp:458 +msgid "Too many items to paste; split this into smaller pastes." +msgstr "要粘贴的项目太多; 请把他们拆分。" + +#: clipboard.cpp:463 +msgid "No workplane active." +msgstr "没有工作平面处于活动状态。" + +#: confscreen.cpp:418 +msgid "Bad format: specify coordinates as x, y, z" +msgstr "格式错误:将坐标指定为 x、y、z" + +#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805 +msgid "Bad format: specify color as r, g, b" +msgstr "格式错误:将颜色指定为 r、g、b" + +#: confscreen.cpp:454 +msgid "" +"The perspective factor will have no effect until you enable View -> Use " +"Perspective Projection." +msgstr "在启用\"视图 -= 使用透视投影\"之前,透视因子将不起作用。" + +#: confscreen.cpp:467 confscreen.cpp:477 +#, c-format +msgid "Specify between 0 and %d digits after the decimal." +msgstr "在十进制之后指定 0 和 %d 数字之间。" + +#: confscreen.cpp:489 +msgid "Export scale must not be zero!" +msgstr "输出比例不能为零!" + +#: confscreen.cpp:501 +msgid "Cutter radius offset must not be negative!" +msgstr "刀具半径偏移不能为负数!" + +#: confscreen.cpp:555 +msgid "Bad value: autosave interval should be positive" +msgstr "坏值:自动保存间隔应为正" + +#: confscreen.cpp:558 +msgid "Bad format: specify interval in integral minutes" +msgstr "格式错误:以整数分钟为单位指定间隔" + +#: constraint.cpp:12 +msgctxt "constr-name" +msgid "pts-coincident" +msgstr "点约束" + +#: constraint.cpp:13 +msgctxt "constr-name" +msgid "pt-pt-distance" +msgstr "点点间距" + +#: constraint.cpp:14 +msgctxt "constr-name" +msgid "pt-line-distance" +msgstr "线长" + +#: constraint.cpp:15 +msgctxt "constr-name" +msgid "pt-plane-distance" +msgstr "平面具体" + +#: constraint.cpp:16 +msgctxt "constr-name" +msgid "pt-face-distance" +msgstr "面间距" + +#: constraint.cpp:17 +msgctxt "constr-name" +msgid "proj-pt-pt-distance" +msgstr "点点距离" + +#: constraint.cpp:18 +msgctxt "constr-name" +msgid "pt-in-plane" +msgstr "点在面" + +#: constraint.cpp:19 +msgctxt "constr-name" +msgid "pt-on-line" +msgstr "点在线" + +#: constraint.cpp:20 +msgctxt "constr-name" +msgid "pt-on-face" +msgstr "点在面" + +#: constraint.cpp:21 +msgctxt "constr-name" +msgid "eq-length" +msgstr "长度相同" + +#: constraint.cpp:22 +msgctxt "constr-name" +msgid "eq-length-and-pt-ln-dist" +msgstr "长度相等且点在距离" + +#: constraint.cpp:23 +msgctxt "constr-name" +msgid "eq-pt-line-distances" +msgstr "点线距离相等" + +#: constraint.cpp:24 +msgctxt "constr-name" +msgid "length-ratio" +msgstr "长度比率" + +#: constraint.cpp:25 +msgctxt "constr-name" +msgid "length-difference" +msgstr "长度不同" + +#: constraint.cpp:26 +msgctxt "constr-name" +msgid "symmetric" +msgstr "对称的" + +#: constraint.cpp:27 +msgctxt "constr-name" +msgid "symmetric-h" +msgstr "水平对称" + +#: constraint.cpp:28 +msgctxt "constr-name" +msgid "symmetric-v" +msgstr "纵向对称" + +#: constraint.cpp:29 +msgctxt "constr-name" +msgid "symmetric-line" +msgstr "线对称" + +#: constraint.cpp:30 +msgctxt "constr-name" +msgid "at-midpoint" +msgstr "在中点" + +#: constraint.cpp:31 +msgctxt "constr-name" +msgid "horizontal" +msgstr "水平约束" + +#: constraint.cpp:32 +msgctxt "constr-name" +msgid "vertical" +msgstr "垂直约束" + +#: constraint.cpp:33 +msgctxt "constr-name" +msgid "diameter" +msgstr "直径约束" + +#: constraint.cpp:34 +msgctxt "constr-name" +msgid "pt-on-circle" +msgstr "圆点约束" + +#: constraint.cpp:35 +msgctxt "constr-name" +msgid "same-orientation" +msgstr "相同原点" + +#: constraint.cpp:36 +msgctxt "constr-name" +msgid "angle" +msgstr "角度约束" + +#: constraint.cpp:37 +msgctxt "constr-name" +msgid "parallel" +msgstr "平行约束" + +#: constraint.cpp:38 +msgctxt "constr-name" +msgid "arc-line-tangent" +msgstr "弧切线" + +#: constraint.cpp:39 +msgctxt "constr-name" +msgid "cubic-line-tangent" +msgstr "立方体切线" + +#: constraint.cpp:40 +msgctxt "constr-name" +msgid "curve-curve-tangent" +msgstr "曲线间切线" + +#: constraint.cpp:41 +msgctxt "constr-name" +msgid "perpendicular" +msgstr "垂直约束" + +#: constraint.cpp:42 +msgctxt "constr-name" +msgid "eq-radius" +msgstr "等于半径" + +#: constraint.cpp:43 +msgctxt "constr-name" +msgid "eq-angle" +msgstr "等于角度" + +#: constraint.cpp:44 +msgctxt "constr-name" +msgid "eq-line-len-arc-len" +msgstr "等于线长或弧长" + +#: constraint.cpp:45 +msgctxt "constr-name" +msgid "lock-where-dragged" +msgstr "锁定位置" + +#: constraint.cpp:46 +msgctxt "constr-name" +msgid "comment" +msgstr "备注" + +#: constraint.cpp:140 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." +msgstr "切线弧和线段必须共享一个端点。在约束切线之前,使用约束 -= 点约束它们。" + +#: constraint.cpp:158 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." +msgstr "" +"切线立方段和线段必须共享终结点。在约束切线之前,使用约束 -= 点约束它们。" + +#: constraint.cpp:183 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." +msgstr "曲线必须共享一个终结点。在约束切线之前,使用约束 -= 点约束它们。" + +#: constraint.cpp:231 +msgid "" +"Bad selection for distance / diameter constraint. This constraint can apply " +"to:\n" +"\n" +" * two points (distance between points)\n" +" * a line segment (length)\n" +" * two points and a line segment or normal (projected distance)\n" +" * a workplane and a point (minimum distance)\n" +" * a line segment and a point (minimum distance)\n" +" * a plane face and a point (minimum distance)\n" +" * a circle or an arc (diameter)\n" +msgstr "" +"距离/直径约束的选择错误。此约束可应用于:\n" +"\n" +"* 两点(点之间的距离)\n" +" * 线段(长度)\n" +" * 两个点和线段或法线(投影距离)\n" +" * 工作平面和点(最小距离)\n" +" * 线段和点(最小距离)\n" +" * 平面面和点(最小距离)\n" +" * 圆或弧(直径)\n" + +#: constraint.cpp:284 +msgid "" +"Bad selection for on point / curve / plane constraint. This constraint can " +"apply to:\n" +"\n" +" * two points (points coincident)\n" +" * a point and a workplane (point in plane)\n" +" * a point and a line segment (point on line)\n" +" * a point and a circle or arc (point on curve)\n" +" * a point and a plane face (point on face)\n" +msgstr "" +"点 / 曲线 / 平面约束的选定方法错误。此约束可应用于:\n" +"\n" +"* 两点(点重合)\n" +" * 一个点和一个工作平面(平面中点)\n" +" * 点和线段(点在线)\n" +" * 一个点和一个圆或圆(曲线上的点)\n" +" * 点和平面面(点在脸上)\n" + +#: constraint.cpp:346 +msgid "" +"Bad selection for equal length / radius constraint. This constraint can " +"apply to:\n" +"\n" +" * two line segments (equal length)\n" +" * two line segments and two points (equal point-line distances)\n" +" * a line segment and two points (equal point-line distances)\n" +" * a line segment, and a point and line segment (point-line distance " +"equals length)\n" +" * four line segments or normals (equal angle between A,B and C,D)\n" +" * three line segments or normals (equal angle between A,B and B,C)\n" +" * two circles or arcs (equal radius)\n" +" * a line segment and an arc (line segment length equals arc length)\n" +msgstr "" +"等长度/半径约束的选定方法错误。此约束可应用于:\n" +"\n" +"* 两个线段(相等长度)\n" +" * 两个线段和两个点(相等的点线距离)\n" +" * 线段和两个点(相等的点线距离)\n" +" * 线段和点段和线段(点线距离等于长度)\n" +" * 四条线段或法线(A、B 和 C、D 之间的等角)\n" +" * 三条线段或法线(A、B 和 B、C 之间的等角)\n" +" * 两个圆或圆(相等半径)\n" +" * 线段和圆弧(线段长度等于弧长)\n" + +#: constraint.cpp:385 +msgid "" +"Bad selection for length ratio constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +msgstr "" +"长度比率约束的选择错误。此约束可应用于:\n" +"\n" +"* 两个线段\n" + +#: constraint.cpp:402 +msgid "" +"Bad selection for length difference constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments\n" +msgstr "" +"长度差异约束的选择错误。此约束可应用于:\n" +"\n" +"* 两个线段\n" + +#: constraint.cpp:428 +msgid "" +"Bad selection for at midpoint constraint. This constraint can apply to:\n" +"\n" +" * a line segment and a point (point at midpoint)\n" +" * a line segment and a workplane (line's midpoint on plane)\n" +msgstr "" +"中点约束的选定方法错误。此约束可应用于:\n" +"\n" +"* 线段和点(点在中点)\n" +" * 线段和工作平面(平面上的线中点)\n" + +#: constraint.cpp:486 +msgid "" +"Bad selection for symmetric constraint. This constraint can apply to:\n" +"\n" +" * two points or a line segment (symmetric about workplane's coordinate " +"axis)\n" +" * line segment, and two points or a line segment (symmetric about line " +"segment)\n" +" * workplane, and two points or a line segment (symmetric about " +"workplane)\n" +msgstr "" +"对称约束的选择错误。此约束可应用于:\n" +"\n" +"* 两个点或线段(与工作平面的坐标轴对称)\n" +" * 线段,和两个点或线段(对称的线段)\n" +" * 工作平面和两个点或线段(工作平面对称)\n" + +#: constraint.cpp:500 +msgid "" +"A workplane must be active when constraining symmetric without an explicit " +"symmetry plane." +msgstr "在没有显式对称平面约束对称时,工作平面必须处于活动状态。" + +#: constraint.cpp:530 +msgid "" +"Activate a workplane (with Sketch -> In Workplane) before applying a " +"horizontal or vertical constraint." +msgstr "在应用水平或垂直约束之前,激活工作平面(使用草图 -= 在工作平面中)。" + +#: constraint.cpp:543 +msgid "" +"Bad selection for horizontal / vertical constraint. This constraint can " +"apply to:\n" +"\n" +" * two points\n" +" * a line segment\n" +msgstr "" +"æ°´å¹³/垂直约束的选择错误。此约束可应用于:\n" +"\n" +"• 两点\n" +" • 线段\n" + +#: constraint.cpp:564 +msgid "" +"Bad selection for same orientation constraint. This constraint can apply " +"to:\n" +"\n" +" * two normals\n" +msgstr "" +"同一方向约束的选择错误。此约束可应用于:\n" +"\n" +"• 两个法线\n" + +#: constraint.cpp:614 +msgid "Must select an angle constraint." +msgstr "必须选择角度约束。" + +#: constraint.cpp:627 +msgid "Must select a constraint with associated label." +msgstr "必须选择具有关联标签的约束。" + +#: constraint.cpp:638 +msgid "" +"Bad selection for angle constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" +"角度约束的选择错误。此约束可应用于:\n" +"\n" +"* 两个线段\n" +" * 线段和法线\n" +" • 两个法线\n" + +#: constraint.cpp:701 +msgid "Curve-curve tangency must apply in workplane." +msgstr "曲线曲线切线必须应用于工作平面。" + +#: constraint.cpp:711 +msgid "" +"Bad selection for parallel / tangent constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments (parallel)\n" +" * a line segment and a normal (parallel)\n" +" * two normals (parallel)\n" +" * two line segments, arcs, or beziers, that share an endpoint (tangent)\n" +msgstr "" +"平行/切线约束的选择错误。此约束可应用于:\n" +"\n" +"* 两条线段(平行)\n" +" * 线段和法线(平行)\n" +" * 两个法线(平行)\n" +" * 共享端点的两条线段、弧线或贝塞尔(切线)\n" + +#: constraint.cpp:729 +msgid "" +"Bad selection for perpendicular constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" +"垂直约束的选择错误。此约束可应用于:\n" +"\n" +"* 两个线段\n" +" * 线段和法线\n" +" • 两个法线\n" + +#: constraint.cpp:744 +msgid "" +"Bad selection for lock point where dragged constraint. This constraint can " +"apply to:\n" +"\n" +" * a point\n" +msgstr "" +"拖动约束的锁点选择错误。此约束可应用于:\n" +"\n" +"• 一点\n" + +#: constraint.cpp:755 +msgid "click center of comment text" +msgstr "单击注释文本的中心" + +#: export.cpp:19 +msgid "" +"No solid model present; draw one with extrudes and revolves, or use Export " +"2d View to export bare lines and curves." +msgstr "" +"不存在实体模型;使用拉伸和旋转绘制一个,或使用导出 2d 视图导出裸线和曲线。" + +#: export.cpp:61 +msgid "" +"Bad selection for export section. Please select:\n" +"\n" +" * nothing, with an active workplane (workplane is section plane)\n" +" * a face (section plane through face)\n" +" * a point and two line segments (plane through point and parallel to " +"lines)\n" +msgstr "" +"导出部分的选择错误。请选择:\n" +"\n" +"* 无,带活动工作平面(工作平面为剖面平面)\n" +" * 脸(通过面的剖面)\n" +" * 一个点和两个线段(平面穿过点和平行线)\n" + +#: export.cpp:822 +msgid "Active group mesh is empty; nothing to export." +msgstr "活动组网格为空;没有要导出的。" + +#: exportvector.cpp:337 +msgid "freehand lines were replaced with continuous lines" +msgstr "徒手线替换为连续线" + +#: exportvector.cpp:339 +msgid "zigzag lines were replaced with continuous lines" +msgstr "锯齿线替换为连续线" + +#: exportvector.cpp:593 +msgid "" +"Some aspects of the drawing have no DXF equivalent and were not exported:\n" +msgstr "绘图的某些方面没有 DXF 等效项,并且未导出:\n" + +#: exportvector.cpp:839 +msgid "" +"PDF page size exceeds 200 by 200 inches; many viewers may reject this file." +msgstr "PDF 页面大小超过 200 英寸或 200 英寸;许多查看器可能会拒绝此文件。" + +#: file.cpp:44 group.cpp:91 +msgctxt "group-name" +msgid "sketch-in-plane" +msgstr "平面草图" + +#: file.cpp:62 +msgctxt "group-name" +msgid "#references" +msgstr "#参考" + +#: file.cpp:549 +msgid "" +"Unrecognized data in file. This file may be corrupt, or from a newer version " +"of the program." +msgstr "未识别文件内数据。该文件可能损坏,或使用新版本应用程序尝试打开。" + +#: file.cpp:859 +msgctxt "title" +msgid "Missing File" +msgstr "文件丢失" + +#: file.cpp:860 +#, c-format +msgctxt "dialog" +msgid "The linked file “%s” is not present." +msgstr "连接的文件不存在:\"%s\"。" + +#: file.cpp:862 +msgctxt "dialog" +msgid "" +"Do you want to locate it manually?\n" +"\n" +"If you decline, any geometry that depends on the missing file will be " +"permanently removed." +msgstr "您是否想手工查找?如果是,所有基于该丢失文件的几何对象将会被全部删除." + +#: file.cpp:865 +msgctxt "button" +msgid "&Yes" +msgstr "是(&Y)" + +#: file.cpp:867 +msgctxt "button" +msgid "&No" +msgstr "否(&N)" + +#: file.cpp:869 solvespace.cpp:569 +msgctxt "button" +msgid "&Cancel" +msgstr "取消(&C)" + +#: graphicswin.cpp:41 +msgid "&File" +msgstr "文件(&F)" + +#: graphicswin.cpp:42 +msgid "&New" +msgstr "新建(&N)" + +#: graphicswin.cpp:43 +msgid "&Open..." +msgstr "打开(&O)" + +#: graphicswin.cpp:44 +msgid "Open &Recent" +msgstr "打开最近使用(&R)" + +#: graphicswin.cpp:45 +msgid "&Save" +msgstr "保存(&S)" + +#: graphicswin.cpp:46 +msgid "Save &As..." +msgstr "另存为(&A)" + +#: graphicswin.cpp:48 +msgid "Export &Image..." +msgstr "导出图片(&I)" + +#: graphicswin.cpp:49 +msgid "Export 2d &View..." +msgstr "导出2D视图(&V)" + +#: graphicswin.cpp:50 +msgid "Export 2d &Section..." +msgstr "导出2D截面(&S)" + +#: graphicswin.cpp:51 +msgid "Export 3d &Wireframe..." +msgstr "导出3D线框模型(&W)" + +#: graphicswin.cpp:52 +msgid "Export Triangle &Mesh..." +msgstr "导出三角面模型(&M)" + +#: graphicswin.cpp:53 +msgid "Export &Surfaces..." +msgstr "导出表面模型(&S)" + +#: graphicswin.cpp:54 +msgid "Im&port..." +msgstr "导入(&P)" + +#: graphicswin.cpp:57 +msgid "E&xit" +msgstr "退出(&E)" + +#: graphicswin.cpp:60 +msgid "&Edit" +msgstr "编辑(&E)" + +#: graphicswin.cpp:61 +msgid "&Undo" +msgstr "回退(&U)" + +#: graphicswin.cpp:62 +msgid "&Redo" +msgstr "重做(&R)" + +#: graphicswin.cpp:63 +msgid "Re&generate All" +msgstr "重新生成所有(&G)" + +#: graphicswin.cpp:65 +msgid "Snap Selection to &Grid" +msgstr "选择到轴线(&G)" + +#: graphicswin.cpp:66 +msgid "Rotate Imported &90°" +msgstr "旋转导入模型90° (&9)" + +#: graphicswin.cpp:68 +msgid "Cu&t" +msgstr "剪切 (&T)" + +#: graphicswin.cpp:69 +msgid "&Copy" +msgstr "复制 (&C)" + +#: graphicswin.cpp:70 +msgid "&Paste" +msgstr "粘贴 (&P)" + +#: graphicswin.cpp:71 +msgid "Paste &Transformed..." +msgstr "粘贴移动(&T)" + +#: graphicswin.cpp:72 +msgid "&Delete" +msgstr "删除(&D)" + +#: graphicswin.cpp:74 +msgid "Select &Edge Chain" +msgstr "选择边缘约束(&E)" + +#: graphicswin.cpp:75 +msgid "Select &All" +msgstr "选择所有(&A)" + +#: graphicswin.cpp:76 +msgid "&Unselect All" +msgstr "取消全选(&U)" + +#: graphicswin.cpp:78 +msgid "&Line Styles..." +msgstr "线型(&L)" + +#: graphicswin.cpp:79 +msgid "&View Projection..." +msgstr "查看投影...(&V)" + +#: graphicswin.cpp:81 +msgid "Con&figuration..." +msgstr "配置 (&F)" + +#: graphicswin.cpp:84 +msgid "&View" +msgstr "查看 (&V)" + +#: graphicswin.cpp:85 +msgid "Zoom &In" +msgstr "放大(&I)" + +#: graphicswin.cpp:86 +msgid "Zoom &Out" +msgstr "缩小(&O)" + +#: graphicswin.cpp:87 +msgid "Zoom To &Fit" +msgstr "自动缩放(&F)" + +#: graphicswin.cpp:89 +msgid "Align View to &Workplane" +msgstr "切换视图至平面(&W)" + +#: graphicswin.cpp:90 +msgid "Nearest &Ortho View" +msgstr "Ortho视图 (&O)" + +#: graphicswin.cpp:91 +msgid "Nearest &Isometric View" +msgstr "ISO视图 (&I)" + +#: graphicswin.cpp:92 +msgid "&Center View At Point" +msgstr "以点为中心视图 (&C)" + +#: graphicswin.cpp:94 +msgid "Show Snap &Grid" +msgstr "显示捕捉轴线 (&G)" + +#: graphicswin.cpp:95 +msgid "Darken Inactive Solids" +msgstr "" + +#: graphicswin.cpp:96 +msgid "Use &Perspective Projection" +msgstr "使用远景透视(&P)" + +#: graphicswin.cpp:97 +msgid "Dimension &Units" +msgstr "标注单位(&U)" + +#: graphicswin.cpp:98 +msgid "Dimensions in &Millimeters" +msgstr "标注单位 mm (&M)" + +#: graphicswin.cpp:99 +msgid "Dimensions in M&eters" +msgstr "标注单位m (&E)" + +#: graphicswin.cpp:100 +msgid "Dimensions in &Inches" +msgstr "标准单位英寸 (&I)" + +#: graphicswin.cpp:102 +msgid "Show &Toolbar" +msgstr "显示工具条(&T)" + +#: graphicswin.cpp:103 +msgid "Show Property Bro&wser" +msgstr "显示属性浏览器(&W)" + +#: graphicswin.cpp:105 +msgid "&Full Screen" +msgstr "全屏(&F)" + +#: graphicswin.cpp:107 +msgid "&New Group" +msgstr "新组合(&N)" + +#: graphicswin.cpp:108 +msgid "Sketch In &3d" +msgstr "在三维内绘制(&3)" + +#: graphicswin.cpp:109 +msgid "Sketch In New &Workplane" +msgstr "在新工作面绘制(&W)" + +#: graphicswin.cpp:111 +msgid "Step &Translating" +msgstr "移动(&T)" + +#: graphicswin.cpp:112 +msgid "Step &Rotating" +msgstr "旋转(&R)" + +#: graphicswin.cpp:114 +msgid "E&xtrude" +msgstr "挤出(&E)" + +#: graphicswin.cpp:115 +msgid "&Helix" +msgstr "螺旋(&H)" + +#: graphicswin.cpp:116 +msgid "&Lathe" +msgstr "扫略(&L)" + +#: graphicswin.cpp:117 +msgid "Re&volve" +msgstr "旋转(&V)" + +#: graphicswin.cpp:119 +msgid "Link / Assemble..." +msgstr "链接/装配..." + +#: graphicswin.cpp:120 +msgid "Link Recent" +msgstr "连接最近文件" + +#: graphicswin.cpp:122 +msgid "&Sketch" +msgstr "绘图(&S)" + +#: graphicswin.cpp:123 +msgid "In &Workplane" +msgstr "在工作平面(&W)" + +#: graphicswin.cpp:124 +msgid "Anywhere In &3d" +msgstr "在3D的任何位置(&3)" + +#: graphicswin.cpp:126 +msgid "Datum &Point" +msgstr "基准点(&P)" + +#: graphicswin.cpp:127 +msgid "&Workplane" +msgstr "工作面(&W)" + +#: graphicswin.cpp:129 +msgid "Line &Segment" +msgstr "线段(&S)" + +#: graphicswin.cpp:130 +msgid "C&onstruction Line Segment" +msgstr "构造线段(&C)" + +#: graphicswin.cpp:131 +msgid "&Rectangle" +msgstr "矩形(&R)" + +#: graphicswin.cpp:132 +msgid "&Circle" +msgstr "圆线(&C)" + +#: graphicswin.cpp:133 +msgid "&Arc of a Circle" +msgstr "圆弧(&A)" + +#: graphicswin.cpp:134 +msgid "&Bezier Cubic Spline" +msgstr "立方体线的贝塞尔曲线(&B)" + +#: graphicswin.cpp:136 +msgid "&Text in TrueType Font" +msgstr "TrueTyoe字体文字(&T)" + +#: graphicswin.cpp:137 +msgid "&Image" +msgstr "图片(&I)" + +#: graphicswin.cpp:139 +msgid "To&ggle Construction" +msgstr "切换构造(&G)" + +#: graphicswin.cpp:140 +msgid "Tangent &Arc at Point" +msgstr "弧线切线点(&A)" + +#: graphicswin.cpp:141 +msgid "Split Curves at &Intersection" +msgstr "在交叉处拆分曲线(&I)" + +#: graphicswin.cpp:143 +msgid "&Constrain" +msgstr "约束(&C)" + +#: graphicswin.cpp:144 +msgid "&Distance / Diameter" +msgstr "距离/直径(&D)" + +#: graphicswin.cpp:145 +msgid "Re&ference Dimension" +msgstr "参考标注(&F)" + +#: graphicswin.cpp:146 +msgid "A&ngle" +msgstr "角度(&A)" + +#: graphicswin.cpp:147 +msgid "Reference An&gle" +msgstr "参考角度(&G)" + +#: graphicswin.cpp:148 +msgid "Other S&upplementary Angle" +msgstr "其它增补角度(&U)" + +#: graphicswin.cpp:149 +msgid "Toggle R&eference Dim" +msgstr "切换参考标注(&E)" + +#: graphicswin.cpp:151 +msgid "&Horizontal" +msgstr "水平约束(&H)" + +#: graphicswin.cpp:152 +msgid "&Vertical" +msgstr "垂直约束(&V)" + +#: graphicswin.cpp:154 +msgid "&On Point / Curve / Plane" +msgstr "在点线面(&O)" + +#: graphicswin.cpp:155 +msgid "E&qual Length / Radius / Angle" +msgstr "等于/长度/半径/角度(&Q)" + +#: graphicswin.cpp:156 +msgid "Length Ra&tio" +msgstr "长度比例(&T)" + +#: graphicswin.cpp:157 +msgid "Length Diff&erence" +msgstr "长度偏差(&E)" + +#: graphicswin.cpp:158 +msgid "At &Midpoint" +msgstr "在中点(&M)" + +#: graphicswin.cpp:159 +msgid "S&ymmetric" +msgstr "对称(&Y)" + +#: graphicswin.cpp:160 +msgid "Para&llel / Tangent" +msgstr "æ°´å¹³/切线(&L)" + +#: graphicswin.cpp:161 +msgid "&Perpendicular" +msgstr "垂直的(&P)" + +#: graphicswin.cpp:162 +msgid "Same Orient&ation" +msgstr "相同方向(&A)" + +#: graphicswin.cpp:163 +msgid "Lock Point Where &Dragged" +msgstr "锁定点位置(&D)" + +#: graphicswin.cpp:165 +msgid "Comment" +msgstr "备注" + +#: graphicswin.cpp:167 +msgid "&Analyze" +msgstr "分析(&A)" + +#: graphicswin.cpp:168 +msgid "Measure &Volume" +msgstr "测量体积(&V)" + +#: graphicswin.cpp:169 +msgid "Measure A&rea" +msgstr "测量面积(&R)" + +#: graphicswin.cpp:170 +msgid "Measure &Perimeter" +msgstr "测量周长(&P)" + +#: graphicswin.cpp:171 +msgid "Show &Interfering Parts" +msgstr "显示干涉零件(&I)" + +#: graphicswin.cpp:172 +msgid "Show &Naked Edges" +msgstr "显示孤立边(&N)" + +#: graphicswin.cpp:173 +msgid "Show &Center of Mass" +msgstr "显示中心(&C)" + +#: graphicswin.cpp:175 +msgid "Show &Underconstrained Points" +msgstr "显示无效约束点(&U)" + +#: graphicswin.cpp:177 +msgid "&Trace Point" +msgstr "跟踪点(&T)" + +#: graphicswin.cpp:178 +msgid "&Stop Tracing..." +msgstr "停止跟踪(&S)" + +#: graphicswin.cpp:179 +msgid "Step &Dimension..." +msgstr "逐步标注(&D)" + +#: graphicswin.cpp:181 +msgid "&Help" +msgstr "帮助(&H)" + +#: graphicswin.cpp:182 +msgid "&Language" +msgstr "语言(&L)" + +#: graphicswin.cpp:183 +msgid "&Website / Manual" +msgstr "网页/手册(&W)" + +#: graphicswin.cpp:185 +msgid "&About" +msgstr "关于(&A)" + +#: graphicswin.cpp:355 +msgid "(no recent files)" +msgstr "(无文件)" + +#: graphicswin.cpp:363 +#, c-format +msgid "File '%s' does not exist." +msgstr "文件不存在: \"%s\"。" + +#: graphicswin.cpp:725 +msgid "No workplane is active, so the grid will not appear." +msgstr "没有激活的工作面,因此无法显示轴网。" + +#: graphicswin.cpp:740 +msgid "" +"The perspective factor is set to zero, so the view will always be a parallel " +"projection.\n" +"\n" +"For a perspective projection, modify the perspective factor in the " +"configuration screen. A value around 0.3 is typical." +msgstr "" + +#: graphicswin.cpp:819 +msgid "" +"Select a point; this point will become the center of the view on screen." +msgstr "" + +#: graphicswin.cpp:1114 +msgid "No additional entities share endpoints with the selected entities." +msgstr "" + +#: graphicswin.cpp:1132 +msgid "" +"To use this command, select a point or other entity from an linked part, or " +"make a link group the active group." +msgstr "" + +#: graphicswin.cpp:1155 +msgid "" +"No workplane is active. Activate a workplane (with Sketch -> In Workplane) " +"to define the plane for the snap grid." +msgstr "" + +#: graphicswin.cpp:1162 +msgid "" +"Can't snap these items to grid; select points, text comments, or constraints " +"with a label. To snap a line, select its endpoints." +msgstr "" + +#: graphicswin.cpp:1247 +msgid "No workplane selected. Activating default workplane for this group." +msgstr "" + +#: graphicswin.cpp:1250 +msgid "" +"No workplane is selected, and the active group does not have a default " +"workplane. Try selecting a workplane, or activating a sketch-in-new-" +"workplane group." +msgstr "" + +#: graphicswin.cpp:1271 +msgid "" +"Bad selection for tangent arc at point. Select a single point, or select " +"nothing to set up arc parameters." +msgstr "" + +#: graphicswin.cpp:1282 +msgid "click point on arc (draws anti-clockwise)" +msgstr "点击弧线的点(逆时针方向绘制)" + +#: graphicswin.cpp:1283 +msgid "click to place datum point" +msgstr "点击放置基准点" + +#: graphicswin.cpp:1284 +msgid "click first point of line segment" +msgstr "点击线条的起点" + +#: graphicswin.cpp:1286 +msgid "click first point of construction line segment" +msgstr "点击构造线的起点" + +#: graphicswin.cpp:1287 +msgid "click first point of cubic segment" +msgstr "点击立方体的起点" + +#: graphicswin.cpp:1288 +msgid "click center of circle" +msgstr "点击圆弧的中心" + +#: graphicswin.cpp:1289 +msgid "click origin of workplane" +msgstr "点击工作面的原点" + +#: graphicswin.cpp:1290 +msgid "click one corner of rectangle" +msgstr "点击一个矩形倒角" + +#: graphicswin.cpp:1291 +msgid "click top left of text" +msgstr "点击文字左上角" + +#: graphicswin.cpp:1297 +msgid "click top left of image" +msgstr "点击图片左上角" + +#: graphicswin.cpp:1309 +msgid "" +"No entities are selected. Select entities before trying to toggle their " +"construction state." +msgstr "为选中实体,切换构造状态前请先选中实体对象。" + +#: group.cpp:86 +msgctxt "group-name" +msgid "sketch-in-3d" +msgstr "3D草图" + +#: group.cpp:142 +msgid "" +"Bad selection for new sketch in workplane. This group can be created with:\n" +"\n" +" * a point (through the point, orthogonal to coordinate axes)\n" +" * a point and two line segments (through the point, parallel to the " +"lines)\n" +" * a workplane (copy of the workplane)\n" +msgstr "" +"在新工作面内绘图选择失败,该组可以使用:\n" +"\n" +" * 一个点(通过该点,正交至坐标轴)\n" +" * 一个点和二个线段(通过点,绘制平行线至线段)\n" +" * 一个工作面(复制工作面)\n" + +#: group.cpp:154 +msgid "" +"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch " +"will be extruded normal to the workplane." +msgstr "挤出前先激活工作面(草图->在工作面),该草图将由工作面的法线方向挤出。" + +#: group.cpp:163 +msgctxt "group-name" +msgid "extrude" +msgstr "挤出" + +#: group.cpp:168 +msgid "Lathe operation can only be applied to planar sketches." +msgstr "扫略操作仅可用于二维草图。" + +#: group.cpp:179 +msgid "" +"Bad selection for new lathe group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" +"创建扫略组失败,该组可由:\n" +"\n" +" * 一个点和一个线段或法线(围绕坐标轴至线或法线的平行线,通过点)\n" +" * 一个线段(围绕线段)\n" + +#: group.cpp:189 +msgctxt "group-name" +msgid "lathe" +msgstr "扫略" + +#: group.cpp:194 +msgid "Revolve operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:205 +msgid "" +"Bad selection for new revolve group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" + +#: group.cpp:217 +msgctxt "group-name" +msgid "revolve" +msgstr "旋转" + +#: group.cpp:222 +msgid "Helix operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:233 +msgid "" +"Bad selection for new helix group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" + +#: group.cpp:245 +msgctxt "group-name" +msgid "helix" +msgstr "螺旋" + +#: group.cpp:258 +msgid "" +"Bad selection for new rotation. This group can be created with:\n" +"\n" +" * a point, while locked in workplane (rotate in plane, about that " +"point)\n" +" * a point and a line or a normal (rotate about an axis through the " +"point, and parallel to line / normal)\n" +msgstr "" + +#: group.cpp:271 +msgctxt "group-name" +msgid "rotate" +msgstr "旋转" + +#: group.cpp:282 +msgctxt "group-name" +msgid "translate" +msgstr "移动" + +#: group.cpp:400 +msgid "(unnamed)" +msgstr "(未命名)" + +#: groupmesh.cpp:709 +msgid "not closed contour, or not all same style!" +msgstr "未闭合轮廓,或样式不一致!" + +#: groupmesh.cpp:722 +msgid "points not all coplanar!" +msgstr "点不在相同平面!" + +#: groupmesh.cpp:724 +msgid "contour is self-intersecting!" +msgstr "轮廓自相交!" + +#: groupmesh.cpp:726 +msgid "zero-length edge!" +msgstr "边缘长度为零!" + +#: modify.cpp:254 +msgid "Must be sketching in workplane to create tangent arc." +msgstr "" + +#: modify.cpp:301 +msgid "" +"To create a tangent arc, select a point where two non-construction lines or " +"circles in this group and workplane join." +msgstr "" + +#: modify.cpp:388 +msgid "" +"Couldn't round this corner. Try a smaller radius, or try creating the " +"desired geometry by hand with tangency constraints." +msgstr "" + +#: modify.cpp:597 +msgid "Couldn't split this entity; lines, circles, or cubics only." +msgstr "" + +#: modify.cpp:624 +msgid "Must be sketching in workplane to split." +msgstr "" + +#: modify.cpp:631 +msgid "" +"Select two entities that intersect each other (e.g. two lines/circles/arcs " +"or a line/circle/arc and a point)." +msgstr "" + +#: modify.cpp:736 +msgid "Can't split; no intersection found." +msgstr "无法拆分;未发现较差点。" + +#: mouse.cpp:560 +msgid "Assign to Style" +msgstr "指定样式" + +#: mouse.cpp:576 +msgid "No Style" +msgstr "无样式" + +#: mouse.cpp:579 +msgid "Newly Created Custom Style..." +msgstr "新组样式。" + +#: mouse.cpp:586 +msgid "Group Info" +msgstr "组信息" + +#: mouse.cpp:606 +msgid "Style Info" +msgstr "样式信息" + +#: mouse.cpp:626 +msgid "Select Edge Chain" +msgstr "选择边缘链" + +#: mouse.cpp:632 +msgid "Toggle Reference Dimension" +msgstr "切换参考标注" + +#: mouse.cpp:638 +msgid "Other Supplementary Angle" +msgstr "其它补充角度" + +#: mouse.cpp:643 +msgid "Snap to Grid" +msgstr "捕捉至轴网" + +#: mouse.cpp:652 +msgid "Remove Spline Point" +msgstr "删除样条线的点" + +#: mouse.cpp:687 +msgid "Add Spline Point" +msgstr "增加样条线的点" + +#: mouse.cpp:691 +msgid "Cannot add spline point: maximum number of points reached." +msgstr "无法增加样条线点:超过最大限制。" + +#: mouse.cpp:716 +msgid "Toggle Construction" +msgstr "切换构造" + +#: mouse.cpp:731 +msgid "Delete Point-Coincident Constraint" +msgstr "删除点一致约束" + +#: mouse.cpp:750 +msgid "Cut" +msgstr "剪切" + +#: mouse.cpp:752 +msgid "Copy" +msgstr "复制" + +#: mouse.cpp:756 +msgid "Select All" +msgstr "全选" + +#: mouse.cpp:761 +msgid "Paste" +msgstr "粘贴" + +#: mouse.cpp:763 +msgid "Paste Transformed..." +msgstr "粘贴移动的..." + +#: mouse.cpp:768 +msgid "Delete" +msgstr "删除" + +#: mouse.cpp:771 +msgid "Unselect All" +msgstr "取消全选" + +#: mouse.cpp:778 +msgid "Unselect Hovered" +msgstr "取消覆盖区域的全选" + +#: mouse.cpp:787 +msgid "Zoom to Fit" +msgstr "自动缩放" + +#: mouse.cpp:989 mouse.cpp:1276 +msgid "click next point of line, or press Esc" +msgstr "点击下一个点或取消(ESC)" + +#: mouse.cpp:995 +msgid "" +"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "无法在3D内绘制矩形; 首先,激活工作面,草图->在工作面。" + +#: mouse.cpp:1029 +msgid "click to place other corner of rectangle" +msgstr "点击放置其它矩形倒角" + +#: mouse.cpp:1049 +msgid "click to set radius" +msgstr "点击设置半径" + +#: mouse.cpp:1054 +msgid "" +"Can't draw arc in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "无法在3D空间内绘制弧线,可使用 草图->在工作面 激活工作面。" + +#: mouse.cpp:1073 +msgid "click to place point" +msgstr "点击放置点" + +#: mouse.cpp:1089 +msgid "click next point of cubic, or press Esc" +msgstr "点击下一个点或取消(ESC)" + +#: mouse.cpp:1094 +msgid "" +"Sketching in a workplane already; sketch in 3d before creating new workplane." +msgstr "已经在工作面绘制;在新建工作面前在三维空间绘制。" + +#: mouse.cpp:1110 +msgid "" +"Can't draw text in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "无法在三维空间内绘制文字,可使用 草图->在工作面 激活工作面。" + +#: mouse.cpp:1127 +msgid "click to place bottom right of text" +msgstr "点击文字的右下角放置" + +#: mouse.cpp:1133 +msgid "" +"Can't draw image in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "无法在三维空间内绘制图片,可使用 草图->在工作面 激活工作面。" + +#: mouse.cpp:1160 +msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" +msgstr "新备注 - 双击编辑" + +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511 +msgctxt "file-type" +msgid "SolveSpace models" +msgstr "SolveSpace模型" + +#: platform/gui.cpp:90 +msgctxt "file-type" +msgid "IDF circuit board" +msgstr "" + +#: platform/gui.cpp:94 +msgctxt "file-type" +msgid "PNG image" +msgstr "PNG图片" + +#: platform/gui.cpp:98 +msgctxt "file-type" +msgid "STL mesh" +msgstr "STL网格" + +#: platform/gui.cpp:99 +msgctxt "file-type" +msgid "Wavefront OBJ mesh" +msgstr "Wavefront OBJ网格" + +#: platform/gui.cpp:100 +msgctxt "file-type" +msgid "Three.js-compatible mesh, with viewer" +msgstr "Three.js-网格及查看视图" + +#: platform/gui.cpp:101 +msgctxt "file-type" +msgid "Three.js-compatible mesh, mesh only" +msgstr "Three.js-仅网格" + +#: platform/gui.cpp:102 +msgctxt "file-type" +msgid "VRML text file" +msgstr "VRML文本文件" + +#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 +msgctxt "file-type" +msgid "STEP file" +msgstr "STEP文件" + +#: platform/gui.cpp:110 +msgctxt "file-type" +msgid "PDF file" +msgstr "PDF文件" + +#: platform/gui.cpp:111 +msgctxt "file-type" +msgid "Encapsulated PostScript" +msgstr "封装好的PostScript" + +#: platform/gui.cpp:112 +msgctxt "file-type" +msgid "Scalable Vector Graphics" +msgstr "SVG矢量图" + +#: platform/gui.cpp:114 platform/gui.cpp:121 +msgctxt "file-type" +msgid "DXF file (AutoCAD 2007)" +msgstr "DXF文件(AutoCAD 2007)" + +#: platform/gui.cpp:115 +msgctxt "file-type" +msgid "HPGL file" +msgstr "HPGL文件" + +#: platform/gui.cpp:116 +msgctxt "file-type" +msgid "G Code" +msgstr "G Code" + +#: platform/gui.cpp:125 +msgctxt "file-type" +msgid "AutoCAD DXF and DWG files" +msgstr "AutoCAD DXF/DWG文件" + +#: platform/gui.cpp:129 +msgctxt "file-type" +msgid "Comma-separated values" +msgstr "逗号分隔数据" + +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 +msgid "untitled" +msgstr "未命名" + +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1573 +msgctxt "title" +msgid "Save File" +msgstr "保存文件" + +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1575 +msgctxt "title" +msgid "Open File" +msgstr "打开文件" + +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 +msgctxt "button" +msgid "_Cancel" +msgstr "取消_C" + +#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 +msgctxt "button" +msgid "_Save" +msgstr "保存_S" + +#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 +msgctxt "button" +msgid "_Open" +msgstr "打开_O" + +#: solvespace.cpp:169 +msgctxt "title" +msgid "Autosave Available" +msgstr "" + +#: solvespace.cpp:170 +msgctxt "dialog" +msgid "An autosave file is available for this sketch." +msgstr "" + +#: solvespace.cpp:171 +msgctxt "dialog" +msgid "Do you want to load the autosave file instead?" +msgstr "" + +#: solvespace.cpp:172 +msgctxt "button" +msgid "&Load autosave" +msgstr "" + +#: solvespace.cpp:174 +msgctxt "button" +msgid "Do&n't Load" +msgstr "" + +#: solvespace.cpp:557 +msgctxt "title" +msgid "Modified File" +msgstr "" + +#: solvespace.cpp:559 +#, c-format +msgctxt "dialog" +msgid "Do you want to save the changes you made to the sketch “%s”?" +msgstr "" + +#: solvespace.cpp:562 +msgctxt "dialog" +msgid "Do you want to save the changes you made to the new sketch?" +msgstr "" + +#: solvespace.cpp:565 +msgctxt "dialog" +msgid "Your changes will be lost if you don't save them." +msgstr "" + +#: solvespace.cpp:566 +msgctxt "button" +msgid "&Save" +msgstr "" + +#: solvespace.cpp:568 +msgctxt "button" +msgid "Do&n't Save" +msgstr "" + +#: solvespace.cpp:589 +msgctxt "title" +msgid "(new sketch)" +msgstr "" + +#: solvespace.cpp:596 +msgctxt "title" +msgid "Property Browser" +msgstr "" + +#: solvespace.cpp:658 +msgid "" +"Constraints are currently shown, and will be exported in the toolpath. This " +"is probably not what you want; hide them by clicking the link at the top of " +"the text window." +msgstr "" + +#: solvespace.cpp:730 +#, c-format +msgid "" +"Can't identify file type from file extension of filename '%s'; try .dxf or ." +"dwg." +msgstr "" + +#: solvespace.cpp:778 +msgid "Constraint must have a label, and must not be a reference dimension." +msgstr "" + +#: solvespace.cpp:782 +msgid "Bad selection for step dimension; select a constraint." +msgstr "" + +#: solvespace.cpp:806 +msgid "The assembly does not interfere, good." +msgstr "" + +#: solvespace.cpp:822 +#, c-format +msgid "" +"The volume of the solid model is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:831 +#, c-format +msgid "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:836 +msgid "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." +msgstr "" + +#: solvespace.cpp:851 +#, c-format +msgid "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:860 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." +msgstr "" + +#: solvespace.cpp:872 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:892 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:898 +msgid "Bad selection for perimeter; select line segments, arcs, and curves." +msgstr "" + +#: solvespace.cpp:914 +msgid "Bad selection for trace; select a single point." +msgstr "" + +#: solvespace.cpp:941 +#, c-format +msgid "Couldn't write to '%s'" +msgstr "" + +#: solvespace.cpp:971 +msgid "The mesh is self-intersecting (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:972 +msgid "The mesh is not self-intersecting (okay, valid)." +msgstr "" + +#: solvespace.cpp:974 +msgid "The mesh has naked edges (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:975 +msgid "The mesh is watertight (okay, valid)." +msgstr "" + +#: solvespace.cpp:978 +#, c-format +msgid "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." +msgstr "" + +#: solvespace.cpp:982 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" + +#: solvespace.cpp:985 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" + +#: solvespace.cpp:998 +#, c-format +msgid "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" +msgstr "" + +#: style.cpp:166 +msgid "" +"Can't assign style to an entity that's derived from another entity; try " +"assigning a style to this entity's parent." +msgstr "无法将样式分配给派生自其他实体的实体;尝试将样式分配给此实体的父级。" + +#: style.cpp:665 +msgid "Style name cannot be empty" +msgstr "样式名称不能为空" + +#: textscreens.cpp:741 +msgid "Can't repeat fewer than 1 time." +msgstr "不能重复少于 1 次。" + +#: textscreens.cpp:745 +msgid "Can't repeat more than 999 times." +msgstr "重复不超过 999 次。" + +#: textscreens.cpp:770 +msgid "Group name cannot be empty" +msgstr "组名称不能为空" + +#: textscreens.cpp:813 +msgid "Opacity must be between zero and one." +msgstr "不透明度必须在零和 1 之间。" + +#: textscreens.cpp:848 +msgid "Radius cannot be zero or negative." +msgstr "半径偏移不能为负数。" + +#: toolbar.cpp:18 +msgid "Sketch line segment" +msgstr "草图线段" + +#: toolbar.cpp:20 +msgid "Sketch rectangle" +msgstr "草图矩形" + +#: toolbar.cpp:22 +msgid "Sketch circle" +msgstr "草图圆" + +#: toolbar.cpp:24 +msgid "Sketch arc of a circle" +msgstr "圆的草图弧线" + +#: toolbar.cpp:26 +msgid "Sketch curves from text in a TrueType font" +msgstr "从 TrueType 字体中的文本中绘制草图曲线" + +#: toolbar.cpp:28 +msgid "Sketch image from a file" +msgstr "从文件中绘制图像" + +#: toolbar.cpp:30 +msgid "Create tangent arc at selected point" +msgstr "在选定点创建切线弧" + +#: toolbar.cpp:32 +msgid "Sketch cubic Bezier spline" +msgstr "草图立方贝塞尔样条" + +#: toolbar.cpp:34 +msgid "Sketch datum point" +msgstr "草图基准点" + +#: toolbar.cpp:36 +msgid "Toggle construction" +msgstr "切换结构" + +#: toolbar.cpp:38 +msgid "Split lines / curves where they intersect" +msgstr "相交的分割线/曲线" + +#: toolbar.cpp:42 +msgid "Constrain distance / diameter / length" +msgstr "约束距离/直径/长度" + +#: toolbar.cpp:44 +msgid "Constrain angle" +msgstr "约束角度" + +#: toolbar.cpp:46 +msgid "Constrain to be horizontal" +msgstr "约束为水平" + +#: toolbar.cpp:48 +msgid "Constrain to be vertical" +msgstr "约束为垂直" + +#: toolbar.cpp:50 +msgid "Constrain to be parallel or tangent" +msgstr "约束为平行或切线" + +#: toolbar.cpp:52 +msgid "Constrain to be perpendicular" +msgstr "约束至垂直" + +#: toolbar.cpp:54 +msgid "Constrain point on line / curve / plane / point" +msgstr "约束点至线/曲线/平面/点" + +#: toolbar.cpp:56 +msgid "Constrain symmetric" +msgstr "对称约束" + +#: toolbar.cpp:58 +msgid "Constrain equal length / radius / angle" +msgstr "约束长/半径/角度相等" + +#: toolbar.cpp:60 +msgid "Constrain normals in same orientation" +msgstr "约束法线在同原点" + +#: toolbar.cpp:62 +msgid "Other supplementary angle" +msgstr "其它补充角度" + +#: toolbar.cpp:64 +msgid "Toggle reference dimension" +msgstr "切换参考标注" + +#: toolbar.cpp:68 +msgid "New group extruding active sketch" +msgstr "新组中挤出当前草图" + +#: toolbar.cpp:70 +msgid "New group rotating active sketch" +msgstr "新组中旋转体当前草图" + +#: toolbar.cpp:72 +msgid "New group helix from active sketch" +msgstr "" + +#: toolbar.cpp:74 +msgid "New group revolve active sketch" +msgstr "" + +#: toolbar.cpp:76 +msgid "New group step and repeat rotating" +msgstr "新组中逐步重复旋转体" + +#: toolbar.cpp:78 +msgid "New group step and repeat translating" +msgstr "新组中逐步重复移动体" + +#: toolbar.cpp:80 +msgid "New group in new workplane (thru given entities)" +msgstr "在新工作平面创建组(通过指定对象)" + +#: toolbar.cpp:82 +msgid "New group in 3d" +msgstr "在3D中新建组" + +#: toolbar.cpp:84 +msgid "New group linking / assembling file" +msgstr "新组 连接/装配文件" + +#: toolbar.cpp:88 +msgid "Nearest isometric view" +msgstr "ISO视图" + +#: toolbar.cpp:90 +msgid "Align view to active workplane" +msgstr "切换视图至当前工作面" + +#: util.cpp:165 +msgctxt "title" +msgid "Error" +msgstr "错误" + +#: util.cpp:165 +msgctxt "title" +msgid "Message" +msgstr "消息" + +#: util.cpp:170 +msgctxt "button" +msgid "&OK" +msgstr "&OK" + +#: view.cpp:78 +msgid "Scale cannot be zero or negative." +msgstr "缩放不能为零。" + +#: view.cpp:90 view.cpp:99 +msgid "Bad format: specify x, y, z" +msgstr "格式错误: 需指定 x, y, z" + +#~ msgctxt "file-type" +#~ msgid "Q3D Object file" +#~ msgstr "Q3D对象文件" diff --git a/res/messages.pot b/res/messages.pot new file mode 100644 index 0000000..c5ce2b7 --- /dev/null +++ b/res/messages.pot @@ -0,0 +1,1887 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR the PACKAGE authors +# This file is distributed under the same license as the SolveSpace package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: SolveSpace 3.0\n" +"Report-Msgid-Bugs-To: whitequark@whitequark.org\n" +"POT-Creation-Date: 2021-01-17 19:54+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: clipboard.cpp:310 +msgid "" +"Cut, paste, and copy work only in a workplane.\n" +"\n" +"Activate one with Sketch -> In Workplane." +msgstr "" + +#: clipboard.cpp:327 +msgid "Clipboard is empty; nothing to paste." +msgstr "" + +#: clipboard.cpp:374 +msgid "Number of copies to paste must be at least one." +msgstr "" + +#: clipboard.cpp:390 textscreens.cpp:783 +msgid "Scale cannot be zero." +msgstr "" + +#: clipboard.cpp:432 +msgid "Select one point to define origin of rotation." +msgstr "" + +#: clipboard.cpp:444 +msgid "Select two points to define translation vector." +msgstr "" + +#: clipboard.cpp:454 +msgid "Transformation is identity. So all copies will be exactly on top of each other." +msgstr "" + +#: clipboard.cpp:458 +msgid "Too many items to paste; split this into smaller pastes." +msgstr "" + +#: clipboard.cpp:463 +msgid "No workplane active." +msgstr "" + +#: confscreen.cpp:418 +msgid "Bad format: specify coordinates as x, y, z" +msgstr "" + +#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805 +msgid "Bad format: specify color as r, g, b" +msgstr "" + +#: confscreen.cpp:454 +msgid "" +"The perspective factor will have no effect until you enable View -> Use Perspective Projection." +msgstr "" + +#: confscreen.cpp:467 confscreen.cpp:477 +#, c-format +msgid "Specify between 0 and %d digits after the decimal." +msgstr "" + +#: confscreen.cpp:489 +msgid "Export scale must not be zero!" +msgstr "" + +#: confscreen.cpp:501 +msgid "Cutter radius offset must not be negative!" +msgstr "" + +#: confscreen.cpp:555 +msgid "Bad value: autosave interval should be positive" +msgstr "" + +#: confscreen.cpp:558 +msgid "Bad format: specify interval in integral minutes" +msgstr "" + +#: constraint.cpp:12 +msgctxt "constr-name" +msgid "pts-coincident" +msgstr "" + +#: constraint.cpp:13 +msgctxt "constr-name" +msgid "pt-pt-distance" +msgstr "" + +#: constraint.cpp:14 +msgctxt "constr-name" +msgid "pt-line-distance" +msgstr "" + +#: constraint.cpp:15 +msgctxt "constr-name" +msgid "pt-plane-distance" +msgstr "" + +#: constraint.cpp:16 +msgctxt "constr-name" +msgid "pt-face-distance" +msgstr "" + +#: constraint.cpp:17 +msgctxt "constr-name" +msgid "proj-pt-pt-distance" +msgstr "" + +#: constraint.cpp:18 +msgctxt "constr-name" +msgid "pt-in-plane" +msgstr "" + +#: constraint.cpp:19 +msgctxt "constr-name" +msgid "pt-on-line" +msgstr "" + +#: constraint.cpp:20 +msgctxt "constr-name" +msgid "pt-on-face" +msgstr "" + +#: constraint.cpp:21 +msgctxt "constr-name" +msgid "eq-length" +msgstr "" + +#: constraint.cpp:22 +msgctxt "constr-name" +msgid "eq-length-and-pt-ln-dist" +msgstr "" + +#: constraint.cpp:23 +msgctxt "constr-name" +msgid "eq-pt-line-distances" +msgstr "" + +#: constraint.cpp:24 +msgctxt "constr-name" +msgid "length-ratio" +msgstr "" + +#: constraint.cpp:25 +msgctxt "constr-name" +msgid "length-difference" +msgstr "" + +#: constraint.cpp:26 +msgctxt "constr-name" +msgid "symmetric" +msgstr "" + +#: constraint.cpp:27 +msgctxt "constr-name" +msgid "symmetric-h" +msgstr "" + +#: constraint.cpp:28 +msgctxt "constr-name" +msgid "symmetric-v" +msgstr "" + +#: constraint.cpp:29 +msgctxt "constr-name" +msgid "symmetric-line" +msgstr "" + +#: constraint.cpp:30 +msgctxt "constr-name" +msgid "at-midpoint" +msgstr "" + +#: constraint.cpp:31 +msgctxt "constr-name" +msgid "horizontal" +msgstr "" + +#: constraint.cpp:32 +msgctxt "constr-name" +msgid "vertical" +msgstr "" + +#: constraint.cpp:33 +msgctxt "constr-name" +msgid "diameter" +msgstr "" + +#: constraint.cpp:34 +msgctxt "constr-name" +msgid "pt-on-circle" +msgstr "" + +#: constraint.cpp:35 +msgctxt "constr-name" +msgid "same-orientation" +msgstr "" + +#: constraint.cpp:36 +msgctxt "constr-name" +msgid "angle" +msgstr "" + +#: constraint.cpp:37 +msgctxt "constr-name" +msgid "parallel" +msgstr "" + +#: constraint.cpp:38 +msgctxt "constr-name" +msgid "arc-line-tangent" +msgstr "" + +#: constraint.cpp:39 +msgctxt "constr-name" +msgid "cubic-line-tangent" +msgstr "" + +#: constraint.cpp:40 +msgctxt "constr-name" +msgid "curve-curve-tangent" +msgstr "" + +#: constraint.cpp:41 +msgctxt "constr-name" +msgid "perpendicular" +msgstr "" + +#: constraint.cpp:42 +msgctxt "constr-name" +msgid "eq-radius" +msgstr "" + +#: constraint.cpp:43 +msgctxt "constr-name" +msgid "eq-angle" +msgstr "" + +#: constraint.cpp:44 +msgctxt "constr-name" +msgid "eq-line-len-arc-len" +msgstr "" + +#: constraint.cpp:45 +msgctxt "constr-name" +msgid "lock-where-dragged" +msgstr "" + +#: constraint.cpp:46 +msgctxt "constr-name" +msgid "comment" +msgstr "" + +#: constraint.cpp:140 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with Constrain -> On " +"Point before constraining tangent." +msgstr "" + +#: constraint.cpp:158 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them with Constrain -> On " +"Point before constraining tangent." +msgstr "" + +#: constraint.cpp:183 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point before constraining " +"tangent." +msgstr "" + +#: constraint.cpp:231 +msgid "" +"Bad selection for distance / diameter constraint. This constraint can apply to:\n" +"\n" +" * two points (distance between points)\n" +" * a line segment (length)\n" +" * two points and a line segment or normal (projected distance)\n" +" * a workplane and a point (minimum distance)\n" +" * a line segment and a point (minimum distance)\n" +" * a plane face and a point (minimum distance)\n" +" * a circle or an arc (diameter)\n" +msgstr "" + +#: constraint.cpp:284 +msgid "" +"Bad selection for on point / curve / plane constraint. This constraint can apply to:\n" +"\n" +" * two points (points coincident)\n" +" * a point and a workplane (point in plane)\n" +" * a point and a line segment (point on line)\n" +" * a point and a circle or arc (point on curve)\n" +" * a point and a plane face (point on face)\n" +msgstr "" + +#: constraint.cpp:346 +msgid "" +"Bad selection for equal length / radius constraint. This constraint can apply to:\n" +"\n" +" * two line segments (equal length)\n" +" * two line segments and two points (equal point-line distances)\n" +" * a line segment and two points (equal point-line distances)\n" +" * a line segment, and a point and line segment (point-line distance equals length)\n" +" * four line segments or normals (equal angle between A,B and C,D)\n" +" * three line segments or normals (equal angle between A,B and B,C)\n" +" * two circles or arcs (equal radius)\n" +" * a line segment and an arc (line segment length equals arc length)\n" +msgstr "" + +#: constraint.cpp:385 +msgid "" +"Bad selection for length ratio constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +msgstr "" + +#: constraint.cpp:402 +msgid "" +"Bad selection for length difference constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +msgstr "" + +#: constraint.cpp:428 +msgid "" +"Bad selection for at midpoint constraint. This constraint can apply to:\n" +"\n" +" * a line segment and a point (point at midpoint)\n" +" * a line segment and a workplane (line's midpoint on plane)\n" +msgstr "" + +#: constraint.cpp:486 +msgid "" +"Bad selection for symmetric constraint. This constraint can apply to:\n" +"\n" +" * two points or a line segment (symmetric about workplane's coordinate axis)\n" +" * line segment, and two points or a line segment (symmetric about line segment)\n" +" * workplane, and two points or a line segment (symmetric about workplane)\n" +msgstr "" + +#: constraint.cpp:500 +msgid "A workplane must be active when constraining symmetric without an explicit symmetry plane." +msgstr "" + +#: constraint.cpp:530 +msgid "" +"Activate a workplane (with Sketch -> In Workplane) before applying a horizontal or vertical " +"constraint." +msgstr "" + +#: constraint.cpp:543 +msgid "" +"Bad selection for horizontal / vertical constraint. This constraint can apply to:\n" +"\n" +" * two points\n" +" * a line segment\n" +msgstr "" + +#: constraint.cpp:564 +msgid "" +"Bad selection for same orientation constraint. This constraint can apply to:\n" +"\n" +" * two normals\n" +msgstr "" + +#: constraint.cpp:614 +msgid "Must select an angle constraint." +msgstr "" + +#: constraint.cpp:627 +msgid "Must select a constraint with associated label." +msgstr "" + +#: constraint.cpp:638 +msgid "" +"Bad selection for angle constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" + +#: constraint.cpp:701 +msgid "Curve-curve tangency must apply in workplane." +msgstr "" + +#: constraint.cpp:711 +msgid "" +"Bad selection for parallel / tangent constraint. This constraint can apply to:\n" +"\n" +" * two line segments (parallel)\n" +" * a line segment and a normal (parallel)\n" +" * two normals (parallel)\n" +" * two line segments, arcs, or beziers, that share an endpoint (tangent)\n" +msgstr "" + +#: constraint.cpp:729 +msgid "" +"Bad selection for perpendicular constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" + +#: constraint.cpp:744 +msgid "" +"Bad selection for lock point where dragged constraint. This constraint can apply to:\n" +"\n" +" * a point\n" +msgstr "" + +#: constraint.cpp:755 +msgid "click center of comment text" +msgstr "" + +#: export.cpp:19 +msgid "" +"No solid model present; draw one with extrudes and revolves, or use Export 2d View to export bare " +"lines and curves." +msgstr "" + +#: export.cpp:61 +msgid "" +"Bad selection for export section. Please select:\n" +"\n" +" * nothing, with an active workplane (workplane is section plane)\n" +" * a face (section plane through face)\n" +" * a point and two line segments (plane through point and parallel to lines)\n" +msgstr "" + +#: export.cpp:822 +msgid "Active group mesh is empty; nothing to export." +msgstr "" + +#: exportvector.cpp:337 +msgid "freehand lines were replaced with continuous lines" +msgstr "" + +#: exportvector.cpp:339 +msgid "zigzag lines were replaced with continuous lines" +msgstr "" + +#: exportvector.cpp:593 +msgid "Some aspects of the drawing have no DXF equivalent and were not exported:\n" +msgstr "" + +#: exportvector.cpp:839 +msgid "PDF page size exceeds 200 by 200 inches; many viewers may reject this file." +msgstr "" + +#: file.cpp:44 group.cpp:91 +msgctxt "group-name" +msgid "sketch-in-plane" +msgstr "" + +#: file.cpp:62 +msgctxt "group-name" +msgid "#references" +msgstr "" + +#: file.cpp:549 +msgid "Unrecognized data in file. This file may be corrupt, or from a newer version of the program." +msgstr "" + +#: file.cpp:859 +msgctxt "title" +msgid "Missing File" +msgstr "" + +#: file.cpp:860 +#, c-format +msgctxt "dialog" +msgid "The linked file “%s” is not present." +msgstr "" + +#: file.cpp:862 +msgctxt "dialog" +msgid "" +"Do you want to locate it manually?\n" +"\n" +"If you decline, any geometry that depends on the missing file will be permanently removed." +msgstr "" + +#: file.cpp:865 +msgctxt "button" +msgid "&Yes" +msgstr "" + +#: file.cpp:867 +msgctxt "button" +msgid "&No" +msgstr "" + +#: file.cpp:869 solvespace.cpp:569 +msgctxt "button" +msgid "&Cancel" +msgstr "" + +#: graphicswin.cpp:41 +msgid "&File" +msgstr "" + +#: graphicswin.cpp:42 +msgid "&New" +msgstr "" + +#: graphicswin.cpp:43 +msgid "&Open..." +msgstr "" + +#: graphicswin.cpp:44 +msgid "Open &Recent" +msgstr "" + +#: graphicswin.cpp:45 +msgid "&Save" +msgstr "" + +#: graphicswin.cpp:46 +msgid "Save &As..." +msgstr "" + +#: graphicswin.cpp:48 +msgid "Export &Image..." +msgstr "" + +#: graphicswin.cpp:49 +msgid "Export 2d &View..." +msgstr "" + +#: graphicswin.cpp:50 +msgid "Export 2d &Section..." +msgstr "" + +#: graphicswin.cpp:51 +msgid "Export 3d &Wireframe..." +msgstr "" + +#: graphicswin.cpp:52 +msgid "Export Triangle &Mesh..." +msgstr "" + +#: graphicswin.cpp:53 +msgid "Export &Surfaces..." +msgstr "" + +#: graphicswin.cpp:54 +msgid "Im&port..." +msgstr "" + +#: graphicswin.cpp:57 +msgid "E&xit" +msgstr "" + +#: graphicswin.cpp:60 +msgid "&Edit" +msgstr "" + +#: graphicswin.cpp:61 +msgid "&Undo" +msgstr "" + +#: graphicswin.cpp:62 +msgid "&Redo" +msgstr "" + +#: graphicswin.cpp:63 +msgid "Re&generate All" +msgstr "" + +#: graphicswin.cpp:65 +msgid "Snap Selection to &Grid" +msgstr "" + +#: graphicswin.cpp:66 +msgid "Rotate Imported &90°" +msgstr "" + +#: graphicswin.cpp:68 +msgid "Cu&t" +msgstr "" + +#: graphicswin.cpp:69 +msgid "&Copy" +msgstr "" + +#: graphicswin.cpp:70 +msgid "&Paste" +msgstr "" + +#: graphicswin.cpp:71 +msgid "Paste &Transformed..." +msgstr "" + +#: graphicswin.cpp:72 +msgid "&Delete" +msgstr "" + +#: graphicswin.cpp:74 +msgid "Select &Edge Chain" +msgstr "" + +#: graphicswin.cpp:75 +msgid "Select &All" +msgstr "" + +#: graphicswin.cpp:76 +msgid "&Unselect All" +msgstr "" + +#: graphicswin.cpp:78 +msgid "&Line Styles..." +msgstr "" + +#: graphicswin.cpp:79 +msgid "&View Projection..." +msgstr "" + +#: graphicswin.cpp:81 +msgid "Con&figuration..." +msgstr "" + +#: graphicswin.cpp:84 +msgid "&View" +msgstr "" + +#: graphicswin.cpp:85 +msgid "Zoom &In" +msgstr "" + +#: graphicswin.cpp:86 +msgid "Zoom &Out" +msgstr "" + +#: graphicswin.cpp:87 +msgid "Zoom To &Fit" +msgstr "" + +#: graphicswin.cpp:89 +msgid "Align View to &Workplane" +msgstr "" + +#: graphicswin.cpp:90 +msgid "Nearest &Ortho View" +msgstr "" + +#: graphicswin.cpp:91 +msgid "Nearest &Isometric View" +msgstr "" + +#: graphicswin.cpp:92 +msgid "&Center View At Point" +msgstr "" + +#: graphicswin.cpp:94 +msgid "Show Snap &Grid" +msgstr "" + +#: graphicswin.cpp:95 +msgid "Darken Inactive Solids" +msgstr "" + +#: graphicswin.cpp:96 +msgid "Use &Perspective Projection" +msgstr "" + +#: graphicswin.cpp:97 +msgid "Dimension &Units" +msgstr "" + +#: graphicswin.cpp:98 +msgid "Dimensions in &Millimeters" +msgstr "" + +#: graphicswin.cpp:99 +msgid "Dimensions in M&eters" +msgstr "" + +#: graphicswin.cpp:100 +msgid "Dimensions in &Inches" +msgstr "" + +#: graphicswin.cpp:102 +msgid "Show &Toolbar" +msgstr "" + +#: graphicswin.cpp:103 +msgid "Show Property Bro&wser" +msgstr "" + +#: graphicswin.cpp:105 +msgid "&Full Screen" +msgstr "" + +#: graphicswin.cpp:107 +msgid "&New Group" +msgstr "" + +#: graphicswin.cpp:108 +msgid "Sketch In &3d" +msgstr "" + +#: graphicswin.cpp:109 +msgid "Sketch In New &Workplane" +msgstr "" + +#: graphicswin.cpp:111 +msgid "Step &Translating" +msgstr "" + +#: graphicswin.cpp:112 +msgid "Step &Rotating" +msgstr "" + +#: graphicswin.cpp:114 +msgid "E&xtrude" +msgstr "" + +#: graphicswin.cpp:115 +msgid "&Helix" +msgstr "" + +#: graphicswin.cpp:116 +msgid "&Lathe" +msgstr "" + +#: graphicswin.cpp:117 +msgid "Re&volve" +msgstr "" + +#: graphicswin.cpp:119 +msgid "Link / Assemble..." +msgstr "" + +#: graphicswin.cpp:120 +msgid "Link Recent" +msgstr "" + +#: graphicswin.cpp:122 +msgid "&Sketch" +msgstr "" + +#: graphicswin.cpp:123 +msgid "In &Workplane" +msgstr "" + +#: graphicswin.cpp:124 +msgid "Anywhere In &3d" +msgstr "" + +#: graphicswin.cpp:126 +msgid "Datum &Point" +msgstr "" + +#: graphicswin.cpp:127 +msgid "&Workplane" +msgstr "" + +#: graphicswin.cpp:129 +msgid "Line &Segment" +msgstr "" + +#: graphicswin.cpp:130 +msgid "C&onstruction Line Segment" +msgstr "" + +#: graphicswin.cpp:131 +msgid "&Rectangle" +msgstr "" + +#: graphicswin.cpp:132 +msgid "&Circle" +msgstr "" + +#: graphicswin.cpp:133 +msgid "&Arc of a Circle" +msgstr "" + +#: graphicswin.cpp:134 +msgid "&Bezier Cubic Spline" +msgstr "" + +#: graphicswin.cpp:136 +msgid "&Text in TrueType Font" +msgstr "" + +#: graphicswin.cpp:137 +msgid "&Image" +msgstr "" + +#: graphicswin.cpp:139 +msgid "To&ggle Construction" +msgstr "" + +#: graphicswin.cpp:140 +msgid "Tangent &Arc at Point" +msgstr "" + +#: graphicswin.cpp:141 +msgid "Split Curves at &Intersection" +msgstr "" + +#: graphicswin.cpp:143 +msgid "&Constrain" +msgstr "" + +#: graphicswin.cpp:144 +msgid "&Distance / Diameter" +msgstr "" + +#: graphicswin.cpp:145 +msgid "Re&ference Dimension" +msgstr "" + +#: graphicswin.cpp:146 +msgid "A&ngle" +msgstr "" + +#: graphicswin.cpp:147 +msgid "Reference An&gle" +msgstr "" + +#: graphicswin.cpp:148 +msgid "Other S&upplementary Angle" +msgstr "" + +#: graphicswin.cpp:149 +msgid "Toggle R&eference Dim" +msgstr "" + +#: graphicswin.cpp:151 +msgid "&Horizontal" +msgstr "" + +#: graphicswin.cpp:152 +msgid "&Vertical" +msgstr "" + +#: graphicswin.cpp:154 +msgid "&On Point / Curve / Plane" +msgstr "" + +#: graphicswin.cpp:155 +msgid "E&qual Length / Radius / Angle" +msgstr "" + +#: graphicswin.cpp:156 +msgid "Length Ra&tio" +msgstr "" + +#: graphicswin.cpp:157 +msgid "Length Diff&erence" +msgstr "" + +#: graphicswin.cpp:158 +msgid "At &Midpoint" +msgstr "" + +#: graphicswin.cpp:159 +msgid "S&ymmetric" +msgstr "" + +#: graphicswin.cpp:160 +msgid "Para&llel / Tangent" +msgstr "" + +#: graphicswin.cpp:161 +msgid "&Perpendicular" +msgstr "" + +#: graphicswin.cpp:162 +msgid "Same Orient&ation" +msgstr "" + +#: graphicswin.cpp:163 +msgid "Lock Point Where &Dragged" +msgstr "" + +#: graphicswin.cpp:165 +msgid "Comment" +msgstr "" + +#: graphicswin.cpp:167 +msgid "&Analyze" +msgstr "" + +#: graphicswin.cpp:168 +msgid "Measure &Volume" +msgstr "" + +#: graphicswin.cpp:169 +msgid "Measure A&rea" +msgstr "" + +#: graphicswin.cpp:170 +msgid "Measure &Perimeter" +msgstr "" + +#: graphicswin.cpp:171 +msgid "Show &Interfering Parts" +msgstr "" + +#: graphicswin.cpp:172 +msgid "Show &Naked Edges" +msgstr "" + +#: graphicswin.cpp:173 +msgid "Show &Center of Mass" +msgstr "" + +#: graphicswin.cpp:175 +msgid "Show &Underconstrained Points" +msgstr "" + +#: graphicswin.cpp:177 +msgid "&Trace Point" +msgstr "" + +#: graphicswin.cpp:178 +msgid "&Stop Tracing..." +msgstr "" + +#: graphicswin.cpp:179 +msgid "Step &Dimension..." +msgstr "" + +#: graphicswin.cpp:181 +msgid "&Help" +msgstr "" + +#: graphicswin.cpp:182 +msgid "&Language" +msgstr "" + +#: graphicswin.cpp:183 +msgid "&Website / Manual" +msgstr "" + +#: graphicswin.cpp:185 +msgid "&About" +msgstr "" + +#: graphicswin.cpp:355 +msgid "(no recent files)" +msgstr "" + +#: graphicswin.cpp:363 +#, c-format +msgid "File '%s' does not exist." +msgstr "" + +#: graphicswin.cpp:725 +msgid "No workplane is active, so the grid will not appear." +msgstr "" + +#: graphicswin.cpp:740 +msgid "" +"The perspective factor is set to zero, so the view will always be a parallel projection.\n" +"\n" +"For a perspective projection, modify the perspective factor in the configuration screen. A value " +"around 0.3 is typical." +msgstr "" + +#: graphicswin.cpp:819 +msgid "Select a point; this point will become the center of the view on screen." +msgstr "" + +#: graphicswin.cpp:1114 +msgid "No additional entities share endpoints with the selected entities." +msgstr "" + +#: graphicswin.cpp:1132 +msgid "" +"To use this command, select a point or other entity from an linked part, or make a link group the " +"active group." +msgstr "" + +#: graphicswin.cpp:1155 +msgid "" +"No workplane is active. Activate a workplane (with Sketch -> In Workplane) to define the plane " +"for the snap grid." +msgstr "" + +#: graphicswin.cpp:1162 +msgid "" +"Can't snap these items to grid; select points, text comments, or constraints with a label. To " +"snap a line, select its endpoints." +msgstr "" + +#: graphicswin.cpp:1247 +msgid "No workplane selected. Activating default workplane for this group." +msgstr "" + +#: graphicswin.cpp:1250 +msgid "" +"No workplane is selected, and the active group does not have a default workplane. Try selecting a " +"workplane, or activating a sketch-in-new-workplane group." +msgstr "" + +#: graphicswin.cpp:1271 +msgid "" +"Bad selection for tangent arc at point. Select a single point, or select nothing to set up arc " +"parameters." +msgstr "" + +#: graphicswin.cpp:1282 +msgid "click point on arc (draws anti-clockwise)" +msgstr "" + +#: graphicswin.cpp:1283 +msgid "click to place datum point" +msgstr "" + +#: graphicswin.cpp:1284 +msgid "click first point of line segment" +msgstr "" + +#: graphicswin.cpp:1286 +msgid "click first point of construction line segment" +msgstr "" + +#: graphicswin.cpp:1287 +msgid "click first point of cubic segment" +msgstr "" + +#: graphicswin.cpp:1288 +msgid "click center of circle" +msgstr "" + +#: graphicswin.cpp:1289 +msgid "click origin of workplane" +msgstr "" + +#: graphicswin.cpp:1290 +msgid "click one corner of rectangle" +msgstr "" + +#: graphicswin.cpp:1291 +msgid "click top left of text" +msgstr "" + +#: graphicswin.cpp:1297 +msgid "click top left of image" +msgstr "" + +#: graphicswin.cpp:1309 +msgid "No entities are selected. Select entities before trying to toggle their construction state." +msgstr "" + +#: group.cpp:86 +msgctxt "group-name" +msgid "sketch-in-3d" +msgstr "" + +#: group.cpp:142 +msgid "" +"Bad selection for new sketch in workplane. This group can be created with:\n" +"\n" +" * a point (through the point, orthogonal to coordinate axes)\n" +" * a point and two line segments (through the point, parallel to the lines)\n" +" * a workplane (copy of the workplane)\n" +msgstr "" + +#: group.cpp:154 +msgid "" +"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch will be extruded " +"normal to the workplane." +msgstr "" + +#: group.cpp:163 +msgctxt "group-name" +msgid "extrude" +msgstr "" + +#: group.cpp:168 +msgid "Lathe operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:179 +msgid "" +"Bad selection for new lathe group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel to line / normal, " +"through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" + +#: group.cpp:189 +msgctxt "group-name" +msgid "lathe" +msgstr "" + +#: group.cpp:194 +msgid "Revolve operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:205 +msgid "" +"Bad selection for new revolve group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel to line / normal, " +"through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" + +#: group.cpp:217 +msgctxt "group-name" +msgid "revolve" +msgstr "" + +#: group.cpp:222 +msgid "Helix operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:233 +msgid "" +"Bad selection for new helix group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel to line / normal, " +"through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" + +#: group.cpp:245 +msgctxt "group-name" +msgid "helix" +msgstr "" + +#: group.cpp:258 +msgid "" +"Bad selection for new rotation. This group can be created with:\n" +"\n" +" * a point, while locked in workplane (rotate in plane, about that point)\n" +" * a point and a line or a normal (rotate about an axis through the point, and parallel to " +"line / normal)\n" +msgstr "" + +#: group.cpp:271 +msgctxt "group-name" +msgid "rotate" +msgstr "" + +#: group.cpp:282 +msgctxt "group-name" +msgid "translate" +msgstr "" + +#: group.cpp:400 +msgid "(unnamed)" +msgstr "" + +#: groupmesh.cpp:709 +msgid "not closed contour, or not all same style!" +msgstr "" + +#: groupmesh.cpp:722 +msgid "points not all coplanar!" +msgstr "" + +#: groupmesh.cpp:724 +msgid "contour is self-intersecting!" +msgstr "" + +#: groupmesh.cpp:726 +msgid "zero-length edge!" +msgstr "" + +#: modify.cpp:254 +msgid "Must be sketching in workplane to create tangent arc." +msgstr "" + +#: modify.cpp:301 +msgid "" +"To create a tangent arc, select a point where two non-construction lines or circles in this group " +"and workplane join." +msgstr "" + +#: modify.cpp:388 +msgid "" +"Couldn't round this corner. Try a smaller radius, or try creating the desired geometry by hand " +"with tangency constraints." +msgstr "" + +#: modify.cpp:597 +msgid "Couldn't split this entity; lines, circles, or cubics only." +msgstr "" + +#: modify.cpp:624 +msgid "Must be sketching in workplane to split." +msgstr "" + +#: modify.cpp:631 +msgid "" +"Select two entities that intersect each other (e.g. two lines/circles/arcs or a line/circle/arc " +"and a point)." +msgstr "" + +#: modify.cpp:736 +msgid "Can't split; no intersection found." +msgstr "" + +#: mouse.cpp:560 +msgid "Assign to Style" +msgstr "" + +#: mouse.cpp:576 +msgid "No Style" +msgstr "" + +#: mouse.cpp:579 +msgid "Newly Created Custom Style..." +msgstr "" + +#: mouse.cpp:586 +msgid "Group Info" +msgstr "" + +#: mouse.cpp:606 +msgid "Style Info" +msgstr "" + +#: mouse.cpp:626 +msgid "Select Edge Chain" +msgstr "" + +#: mouse.cpp:632 +msgid "Toggle Reference Dimension" +msgstr "" + +#: mouse.cpp:638 +msgid "Other Supplementary Angle" +msgstr "" + +#: mouse.cpp:643 +msgid "Snap to Grid" +msgstr "" + +#: mouse.cpp:652 +msgid "Remove Spline Point" +msgstr "" + +#: mouse.cpp:687 +msgid "Add Spline Point" +msgstr "" + +#: mouse.cpp:691 +msgid "Cannot add spline point: maximum number of points reached." +msgstr "" + +#: mouse.cpp:716 +msgid "Toggle Construction" +msgstr "" + +#: mouse.cpp:731 +msgid "Delete Point-Coincident Constraint" +msgstr "" + +#: mouse.cpp:750 +msgid "Cut" +msgstr "" + +#: mouse.cpp:752 +msgid "Copy" +msgstr "" + +#: mouse.cpp:756 +msgid "Select All" +msgstr "" + +#: mouse.cpp:761 +msgid "Paste" +msgstr "" + +#: mouse.cpp:763 +msgid "Paste Transformed..." +msgstr "" + +#: mouse.cpp:768 +msgid "Delete" +msgstr "" + +#: mouse.cpp:771 +msgid "Unselect All" +msgstr "" + +#: mouse.cpp:778 +msgid "Unselect Hovered" +msgstr "" + +#: mouse.cpp:787 +msgid "Zoom to Fit" +msgstr "" + +#: mouse.cpp:989 mouse.cpp:1276 +msgid "click next point of line, or press Esc" +msgstr "" + +#: mouse.cpp:995 +msgid "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In Workplane." +msgstr "" + +#: mouse.cpp:1029 +msgid "click to place other corner of rectangle" +msgstr "" + +#: mouse.cpp:1049 +msgid "click to set radius" +msgstr "" + +#: mouse.cpp:1054 +msgid "Can't draw arc in 3d; first, activate a workplane with Sketch -> In Workplane." +msgstr "" + +#: mouse.cpp:1073 +msgid "click to place point" +msgstr "" + +#: mouse.cpp:1089 +msgid "click next point of cubic, or press Esc" +msgstr "" + +#: mouse.cpp:1094 +msgid "Sketching in a workplane already; sketch in 3d before creating new workplane." +msgstr "" + +#: mouse.cpp:1110 +msgid "Can't draw text in 3d; first, activate a workplane with Sketch -> In Workplane." +msgstr "" + +#: mouse.cpp:1127 +msgid "click to place bottom right of text" +msgstr "" + +#: mouse.cpp:1133 +msgid "Can't draw image in 3d; first, activate a workplane with Sketch -> In Workplane." +msgstr "" + +#: mouse.cpp:1160 +msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" +msgstr "" + +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511 +msgctxt "file-type" +msgid "SolveSpace models" +msgstr "" + +#: platform/gui.cpp:90 +msgctxt "file-type" +msgid "IDF circuit board" +msgstr "" + +#: platform/gui.cpp:94 +msgctxt "file-type" +msgid "PNG image" +msgstr "" + +#: platform/gui.cpp:98 +msgctxt "file-type" +msgid "STL mesh" +msgstr "" + +#: platform/gui.cpp:99 +msgctxt "file-type" +msgid "Wavefront OBJ mesh" +msgstr "" + +#: platform/gui.cpp:100 +msgctxt "file-type" +msgid "Three.js-compatible mesh, with viewer" +msgstr "" + +#: platform/gui.cpp:101 +msgctxt "file-type" +msgid "Three.js-compatible mesh, mesh only" +msgstr "" + +#: platform/gui.cpp:102 +msgctxt "file-type" +msgid "VRML text file" +msgstr "" + +#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 +msgctxt "file-type" +msgid "STEP file" +msgstr "" + +#: platform/gui.cpp:110 +msgctxt "file-type" +msgid "PDF file" +msgstr "" + +#: platform/gui.cpp:111 +msgctxt "file-type" +msgid "Encapsulated PostScript" +msgstr "" + +#: platform/gui.cpp:112 +msgctxt "file-type" +msgid "Scalable Vector Graphics" +msgstr "" + +#: platform/gui.cpp:114 platform/gui.cpp:121 +msgctxt "file-type" +msgid "DXF file (AutoCAD 2007)" +msgstr "" + +#: platform/gui.cpp:115 +msgctxt "file-type" +msgid "HPGL file" +msgstr "" + +#: platform/gui.cpp:116 +msgctxt "file-type" +msgid "G Code" +msgstr "" + +#: platform/gui.cpp:125 +msgctxt "file-type" +msgid "AutoCAD DXF and DWG files" +msgstr "" + +#: platform/gui.cpp:129 +msgctxt "file-type" +msgid "Comma-separated values" +msgstr "" + +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 +msgid "untitled" +msgstr "" + +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1573 +msgctxt "title" +msgid "Save File" +msgstr "" + +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1575 +msgctxt "title" +msgid "Open File" +msgstr "" + +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 +msgctxt "button" +msgid "_Cancel" +msgstr "" + +#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 +msgctxt "button" +msgid "_Save" +msgstr "" + +#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 +msgctxt "button" +msgid "_Open" +msgstr "" + +#: solvespace.cpp:169 +msgctxt "title" +msgid "Autosave Available" +msgstr "" + +#: solvespace.cpp:170 +msgctxt "dialog" +msgid "An autosave file is available for this sketch." +msgstr "" + +#: solvespace.cpp:171 +msgctxt "dialog" +msgid "Do you want to load the autosave file instead?" +msgstr "" + +#: solvespace.cpp:172 +msgctxt "button" +msgid "&Load autosave" +msgstr "" + +#: solvespace.cpp:174 +msgctxt "button" +msgid "Do&n't Load" +msgstr "" + +#: solvespace.cpp:557 +msgctxt "title" +msgid "Modified File" +msgstr "" + +#: solvespace.cpp:559 +#, c-format +msgctxt "dialog" +msgid "Do you want to save the changes you made to the sketch “%s”?" +msgstr "" + +#: solvespace.cpp:562 +msgctxt "dialog" +msgid "Do you want to save the changes you made to the new sketch?" +msgstr "" + +#: solvespace.cpp:565 +msgctxt "dialog" +msgid "Your changes will be lost if you don't save them." +msgstr "" + +#: solvespace.cpp:566 +msgctxt "button" +msgid "&Save" +msgstr "" + +#: solvespace.cpp:568 +msgctxt "button" +msgid "Do&n't Save" +msgstr "" + +#: solvespace.cpp:589 +msgctxt "title" +msgid "(new sketch)" +msgstr "" + +#: solvespace.cpp:596 +msgctxt "title" +msgid "Property Browser" +msgstr "" + +#: solvespace.cpp:658 +msgid "" +"Constraints are currently shown, and will be exported in the toolpath. This is probably not what " +"you want; hide them by clicking the link at the top of the text window." +msgstr "" + +#: solvespace.cpp:730 +#, c-format +msgid "Can't identify file type from file extension of filename '%s'; try .dxf or .dwg." +msgstr "" + +#: solvespace.cpp:778 +msgid "Constraint must have a label, and must not be a reference dimension." +msgstr "" + +#: solvespace.cpp:782 +msgid "Bad selection for step dimension; select a constraint." +msgstr "" + +#: solvespace.cpp:806 +msgid "The assembly does not interfere, good." +msgstr "" + +#: solvespace.cpp:822 +#, c-format +msgid "" +"The volume of the solid model is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:831 +#, c-format +msgid "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:836 +msgid "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." +msgstr "" + +#: solvespace.cpp:851 +#, c-format +msgid "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:860 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, not coplanar, or self-" +"intersecting." +msgstr "" + +#: solvespace.cpp:872 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:892 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:898 +msgid "Bad selection for perimeter; select line segments, arcs, and curves." +msgstr "" + +#: solvespace.cpp:914 +msgid "Bad selection for trace; select a single point." +msgstr "" + +#: solvespace.cpp:941 +#, c-format +msgid "Couldn't write to '%s'" +msgstr "" + +#: solvespace.cpp:971 +msgid "The mesh is self-intersecting (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:972 +msgid "The mesh is not self-intersecting (okay, valid)." +msgstr "" + +#: solvespace.cpp:974 +msgid "The mesh has naked edges (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:975 +msgid "The mesh is watertight (okay, valid)." +msgstr "" + +#: solvespace.cpp:978 +#, c-format +msgid "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." +msgstr "" + +#: solvespace.cpp:982 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" + +#: solvespace.cpp:985 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" + +#: solvespace.cpp:998 +#, c-format +msgid "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" +msgstr "" + +#: style.cpp:166 +msgid "" +"Can't assign style to an entity that's derived from another entity; try assigning a style to this " +"entity's parent." +msgstr "" + +#: style.cpp:665 +msgid "Style name cannot be empty" +msgstr "" + +#: textscreens.cpp:741 +msgid "Can't repeat fewer than 1 time." +msgstr "" + +#: textscreens.cpp:745 +msgid "Can't repeat more than 999 times." +msgstr "" + +#: textscreens.cpp:770 +msgid "Group name cannot be empty" +msgstr "" + +#: textscreens.cpp:813 +msgid "Opacity must be between zero and one." +msgstr "" + +#: textscreens.cpp:848 +msgid "Radius cannot be zero or negative." +msgstr "" + +#: toolbar.cpp:18 +msgid "Sketch line segment" +msgstr "" + +#: toolbar.cpp:20 +msgid "Sketch rectangle" +msgstr "" + +#: toolbar.cpp:22 +msgid "Sketch circle" +msgstr "" + +#: toolbar.cpp:24 +msgid "Sketch arc of a circle" +msgstr "" + +#: toolbar.cpp:26 +msgid "Sketch curves from text in a TrueType font" +msgstr "" + +#: toolbar.cpp:28 +msgid "Sketch image from a file" +msgstr "" + +#: toolbar.cpp:30 +msgid "Create tangent arc at selected point" +msgstr "" + +#: toolbar.cpp:32 +msgid "Sketch cubic Bezier spline" +msgstr "" + +#: toolbar.cpp:34 +msgid "Sketch datum point" +msgstr "" + +#: toolbar.cpp:36 +msgid "Toggle construction" +msgstr "" + +#: toolbar.cpp:38 +msgid "Split lines / curves where they intersect" +msgstr "" + +#: toolbar.cpp:42 +msgid "Constrain distance / diameter / length" +msgstr "" + +#: toolbar.cpp:44 +msgid "Constrain angle" +msgstr "" + +#: toolbar.cpp:46 +msgid "Constrain to be horizontal" +msgstr "" + +#: toolbar.cpp:48 +msgid "Constrain to be vertical" +msgstr "" + +#: toolbar.cpp:50 +msgid "Constrain to be parallel or tangent" +msgstr "" + +#: toolbar.cpp:52 +msgid "Constrain to be perpendicular" +msgstr "" + +#: toolbar.cpp:54 +msgid "Constrain point on line / curve / plane / point" +msgstr "" + +#: toolbar.cpp:56 +msgid "Constrain symmetric" +msgstr "" + +#: toolbar.cpp:58 +msgid "Constrain equal length / radius / angle" +msgstr "" + +#: toolbar.cpp:60 +msgid "Constrain normals in same orientation" +msgstr "" + +#: toolbar.cpp:62 +msgid "Other supplementary angle" +msgstr "" + +#: toolbar.cpp:64 +msgid "Toggle reference dimension" +msgstr "" + +#: toolbar.cpp:68 +msgid "New group extruding active sketch" +msgstr "" + +#: toolbar.cpp:70 +msgid "New group rotating active sketch" +msgstr "" + +#: toolbar.cpp:72 +msgid "New group helix from active sketch" +msgstr "" + +#: toolbar.cpp:74 +msgid "New group revolve active sketch" +msgstr "" + +#: toolbar.cpp:76 +msgid "New group step and repeat rotating" +msgstr "" + +#: toolbar.cpp:78 +msgid "New group step and repeat translating" +msgstr "" + +#: toolbar.cpp:80 +msgid "New group in new workplane (thru given entities)" +msgstr "" + +#: toolbar.cpp:82 +msgid "New group in 3d" +msgstr "" + +#: toolbar.cpp:84 +msgid "New group linking / assembling file" +msgstr "" + +#: toolbar.cpp:88 +msgid "Nearest isometric view" +msgstr "" + +#: toolbar.cpp:90 +msgid "Align view to active workplane" +msgstr "" + +#: util.cpp:165 +msgctxt "title" +msgid "Error" +msgstr "" + +#: util.cpp:165 +msgctxt "title" +msgid "Message" +msgstr "" + +#: util.cpp:170 +msgctxt "button" +msgid "&OK" +msgstr "" + +#: view.cpp:78 +msgid "Scale cannot be zero or negative." +msgstr "" + +#: view.cpp:90 view.cpp:99 +msgid "Bad format: specify x, y, z" +msgstr "" diff --git a/res/shaders/edge.frag b/res/shaders/edge.frag new file mode 100644 index 0000000..2d2e8ac --- /dev/null +++ b/res/shaders/edge.frag @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------------- +// Edge rendering shader +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +const float feather = 0.5; + +uniform vec4 color; +uniform float pixel; +uniform float width; +uniform float patternLen; +uniform float patternScale; +uniform sampler2D pattern; + +varying vec3 fragLoc; + +void main() { + // lookup distance texture + vec4 v = texture2D(pattern, vec2(fragLoc.z / patternScale, 0.0)); + + // decode distance value + float val = dot(v, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 160581375.0)); + + // calculate cap + float dist = length(vec2(val * patternScale / (patternLen * width) + abs(fragLoc.x), fragLoc.y)); + + // perform antialiasing + float k = smoothstep(1.0 - 2.0 * feather * pixel / (width + feather * pixel), 1.0, abs(dist)); + + // perform alpha-test + if(k == 1.0) discard; + + // write resulting color + gl_FragColor = vec4(color.rgb, color.a * (1.0 - k)); +} diff --git a/res/shaders/edge.vert b/res/shaders/edge.vert new file mode 100644 index 0000000..3c5af3b --- /dev/null +++ b/res/shaders/edge.vert @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------------- +// Edge rendering shader +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +const float feather = 0.5; + +attribute vec3 pos; +attribute vec3 loc; +attribute vec3 tgt; + +uniform mat4 modelview; +uniform mat4 projection; +uniform float width; +uniform float pixel; + +varying vec3 fragLoc; + +void main() { + // get camera direction from modelview matrix + vec3 dir = vec3(modelview[0].z, modelview[1].z, modelview[2].z); + + // calculate line contour extension basis for constant width and caps + vec3 norm = normalize(cross(tgt, dir)); + norm = normalize(norm - dir * dot(dir, norm)); + vec3 perp = normalize(cross(dir, norm)); + + // calculate line extension width considering antialiasing + float ext = width + feather * pixel; + + // extend line contour + vec3 vertex = pos; + vertex += ext * loc.x * normalize(perp); + vertex += ext * loc.y * normalize(norm); + + // write fragment location for calculating caps and antialiasing + fragLoc = loc; + + // transform resulting vertex with modelview and projection matrices + gl_Position = projection * modelview * vec4(vertex, 1.0); +} diff --git a/res/shaders/imesh.frag b/res/shaders/imesh.frag new file mode 100644 index 0000000..1e7a74b --- /dev/null +++ b/res/shaders/imesh.frag @@ -0,0 +1,12 @@ +//----------------------------------------------------------------------------- +// Indexed Mesh rendering shader +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +uniform vec4 color; +uniform sampler2D texture_; + +void main() { + if(texture2D(texture_, gl_FragCoord.xy / 32.0).a < 0.5) discard; + gl_FragColor = color; +} diff --git a/res/shaders/imesh.vert b/res/shaders/imesh.vert new file mode 100644 index 0000000..5e3e59a --- /dev/null +++ b/res/shaders/imesh.vert @@ -0,0 +1,13 @@ +//----------------------------------------------------------------------------- +// Indexed Mesh rendering shader +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +attribute vec3 pos; + +uniform mat4 modelview; +uniform mat4 projection; + +void main() { + gl_Position = projection * modelview * vec4(pos, 1.0); +} diff --git a/res/shaders/imesh_point.frag b/res/shaders/imesh_point.frag new file mode 100644 index 0000000..db165e1 --- /dev/null +++ b/res/shaders/imesh_point.frag @@ -0,0 +1,15 @@ +//----------------------------------------------------------------------------- +// Point rendering shader +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +const float feather = 0.5; + +uniform vec4 color; +uniform float pixel; +uniform float width; + +void main() { + // Rectangular points + gl_FragColor = color; +} diff --git a/res/shaders/imesh_point.vert b/res/shaders/imesh_point.vert new file mode 100644 index 0000000..07aff1b --- /dev/null +++ b/res/shaders/imesh_point.vert @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// Point rendering shader +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +const float feather = 0.5; + +attribute vec3 pos; +attribute vec2 loc; + +uniform mat4 modelview; +uniform mat4 projection; +uniform float width; +uniform float pixel; + +void main() { + // get camera vectors from modelview matrix + vec3 u = vec3(modelview[0].x, modelview[1].x, modelview[2].x); + vec3 v = vec3(modelview[0].y, modelview[1].y, modelview[2].y); + + // calculate point contour extension basis for constant width and caps + + // calculate point extension width considering antialiasing + float ext = width + feather * pixel; + + // extend point contour + vec3 vertex = pos; + vertex += ext * loc.x * normalize(u); + vertex += ext * loc.y * normalize(v); + + // transform resulting vertex with modelview and projection matrices + gl_Position = projection * modelview * vec4(vertex, 1.0); +} diff --git a/res/shaders/imesh_tex.frag b/res/shaders/imesh_tex.frag new file mode 100644 index 0000000..d3b3235 --- /dev/null +++ b/res/shaders/imesh_tex.frag @@ -0,0 +1,15 @@ +//----------------------------------------------------------------------------- +// Indexed Mesh rendering shader +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +uniform vec4 color; +uniform sampler2D texture_; + +varying vec2 fragTex; + +void main() { + vec4 texColor = texture2D(texture_, fragTex); + if(texColor.a == 0.0) discard; + gl_FragColor = texColor * color; +} diff --git a/res/shaders/imesh_tex.vert b/res/shaders/imesh_tex.vert new file mode 100644 index 0000000..e048759 --- /dev/null +++ b/res/shaders/imesh_tex.vert @@ -0,0 +1,17 @@ +//----------------------------------------------------------------------------- +// Indexed Mesh rendering shader +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +attribute vec3 pos; +attribute vec2 tex; + +uniform mat4 modelview; +uniform mat4 projection; + +varying vec2 fragTex; + +void main() { + fragTex = tex; + gl_Position = projection * modelview * vec4(pos, 1.0); +} diff --git a/res/shaders/imesh_texa.frag b/res/shaders/imesh_texa.frag new file mode 100644 index 0000000..89a124c --- /dev/null +++ b/res/shaders/imesh_texa.frag @@ -0,0 +1,13 @@ +//----------------------------------------------------------------------------- +// Indexed Mesh rendering shader +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +uniform vec4 color; +uniform sampler2D texture_; + +varying vec2 fragTex; + +void main() { + gl_FragColor = vec4(color.rgb, color.a * texture2D(texture_, fragTex).TEX_ALPHA); +} diff --git a/res/shaders/mesh.frag b/res/shaders/mesh.frag new file mode 100644 index 0000000..8cb32c2 --- /dev/null +++ b/res/shaders/mesh.frag @@ -0,0 +1,26 @@ +//----------------------------------------------------------------------------- +// Mesh rendering shader +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +uniform vec3 lightDir0; +uniform vec3 lightDir1; +uniform float lightInt0; +uniform float lightInt1; +uniform float ambient; + +varying vec3 fragNormal; +varying vec4 fragColor; + +void main() { + vec3 result = fragColor.xyz * ambient; + vec3 normal = normalize(fragNormal); + + float light0 = clamp(dot(lightDir0, normal), 0.0, 1.0) * lightInt0 * (1.0 - ambient); + result += fragColor.rgb * light0; + + float light1 = clamp(dot(lightDir1, normal), 0.0, 1.0) * lightInt1 * (1.0 - ambient); + result += fragColor.rgb * light1; + + gl_FragColor = vec4(result, fragColor.a); +} diff --git a/res/shaders/mesh.vert b/res/shaders/mesh.vert new file mode 100644 index 0000000..c310ffc --- /dev/null +++ b/res/shaders/mesh.vert @@ -0,0 +1,21 @@ +//----------------------------------------------------------------------------- +// Mesh rendering shader +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +attribute vec3 pos; +attribute vec3 nor; +attribute vec4 col; + +uniform mat4 modelview; +uniform mat4 projection; + +varying vec3 fragNormal; +varying vec4 fragColor; + +void main() { + fragNormal = vec3(modelview * vec4(nor, 0.0)); + fragColor = col; + + gl_Position = projection * modelview * vec4(pos, 1.0); +} diff --git a/res/shaders/mesh_fill.frag b/res/shaders/mesh_fill.frag new file mode 100644 index 0000000..c8b3d37 --- /dev/null +++ b/res/shaders/mesh_fill.frag @@ -0,0 +1,12 @@ +//----------------------------------------------------------------------------- +// Mesh rendering shader +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +uniform vec4 color; +uniform sampler2D texture_; + +void main() { + if(texture2D(texture_, gl_FragCoord.xy / 32.0).TEX_ALPHA < 0.5) discard; + gl_FragColor = color; +} diff --git a/res/shaders/mesh_fill.vert b/res/shaders/mesh_fill.vert new file mode 100644 index 0000000..935efa6 --- /dev/null +++ b/res/shaders/mesh_fill.vert @@ -0,0 +1,13 @@ +//----------------------------------------------------------------------------- +// Mesh rendering shader +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +attribute vec3 pos; + +uniform mat4 modelview; +uniform mat4 projection; + +void main() { + gl_Position = projection * modelview * vec4(pos, 1.0); +} diff --git a/res/shaders/outline.vert b/res/shaders/outline.vert new file mode 100644 index 0000000..7683a14 --- /dev/null +++ b/res/shaders/outline.vert @@ -0,0 +1,60 @@ +//----------------------------------------------------------------------------- +// Outline rendering shader +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +const int EMPHASIZED_AND_CONTOUR = 0; +const int EMPHASIZED_WITHOUT_CONTOUR = 1; +const int CONTOUR_ONLY = 2; + +const float feather = 0.5; + +attribute vec3 pos; +attribute vec4 loc; +attribute vec3 tgt; +attribute vec3 nol; +attribute vec3 nor; + +uniform mat4 modelview; +uniform mat4 projection; +uniform float width; +uniform float pixel; +uniform int mode; + +varying vec3 fragLoc; + +void main() { + // get camera direction from modelview matrix + vec3 dir = vec3(modelview[0].z, modelview[1].z, modelview[2].z); + + // perform outline visibility test + float ldot = dot(nol, dir); + float rdot = dot(nor, dir); + + bool isOutline = (ldot > -1e-6) == (rdot < 1e-6) || + (rdot > -1e-6) == (ldot < 1e-6); + bool isTagged = loc.w > 0.5; + + float visible = float((mode == CONTOUR_ONLY && isOutline) || + (mode == EMPHASIZED_AND_CONTOUR && (isOutline || isTagged)) || + (mode == EMPHASIZED_WITHOUT_CONTOUR && isTagged && !isOutline)); + + // calculate line contour extension basis for constant width and caps + vec3 norm = normalize(cross(tgt, dir)); + norm = normalize(norm - dir * dot(dir, norm)); + vec3 perp = normalize(cross(dir, norm)); + + // calculate line extension width considering antialiasing + float ext = (width + feather * pixel) * visible; + + // extend line contour + vec3 vertex = pos; + vertex += ext * loc.x * normalize(perp); + vertex += ext * loc.y * normalize(norm); + + // write fragment location for calculating caps and antialiasing + fragLoc = vec3(loc); + + // transform resulting vertex with modelview and projection matrices + gl_Position = projection * modelview * vec4(vertex, 1.0); +} diff --git a/res/threejs/SolveSpaceControls.js b/res/threejs/SolveSpaceControls.js new file mode 100644 index 0000000..e141ace --- /dev/null +++ b/res/threejs/SolveSpaceControls.js @@ -0,0 +1,536 @@ +window.devicePixelRatio = window.devicePixelRatio || 1; + +SolvespaceCamera = function(renderWidth, renderHeight, scale, up, right, offset) { + THREE.Camera.call(this); + + this.type = 'SolvespaceCamera'; + + this.renderWidth = renderWidth; + this.renderHeight = renderHeight; + this.zoomScale = scale; /* Avoid namespace collision w/ THREE.Object.scale */ + this.up = up; + this.right = right; + this.offset = offset; + this.depthBias = 0; + + this.updateProjectionMatrix(); +}; + +SolvespaceCamera.prototype = Object.create(THREE.Camera.prototype); +SolvespaceCamera.prototype.constructor = SolvespaceCamera; +SolvespaceCamera.prototype.updateProjectionMatrix = function() { + var temp = new THREE.Matrix4(); + var offset = new THREE.Matrix4().makeTranslation(this.offset.x, this.offset.y, this.offset.z); + // Convert to right handed- do up cross right instead. + var n = new THREE.Vector3().crossVectors(this.up, this.right); + var rotate = new THREE.Matrix4().makeBasis(this.right, this.up, n); + rotate.transpose(); + /* Transpose of rotation matrix == inverse. Rotating the camera by a + basis is equivalent to rotating an object by the inverse of the + basis. To mimic Solvespace's behavior, we pan relative to the camera. + So we need to be rotated to where the camera is pointing before panning. + See: https://en.wikipedia.org/wiki/Change_of_basis#Two_dimensions */ + + /* TODO: If we want perspective, we need an additional matrix + here which will modify w for perspective divide. */ + var scale = new THREE.Matrix4().makeScale(2 * this.zoomScale / this.renderWidth, + 2 * this.zoomScale / this.renderHeight, this.zoomScale / 30000.0); + + temp.multiply(scale); + temp.multiply(rotate); + temp.multiply(offset); + + this.projectionMatrix.copy(temp); +}; + +SolvespaceCamera.prototype.NormalizeProjectionVectors = function() { + /* After rotating, up and right may no longer be orthogonal. + However, their cross product will produce the correct + rotated plane, and we can recover an orthogonal basis. */ + var n = new THREE.Vector3().crossVectors(this.right, this.up); + this.up = new THREE.Vector3().crossVectors(n, this.right); + this.right.normalize(); + this.up.normalize(); +}; + +SolvespaceCamera.prototype.rotate = function(right, up) { + var oldRight = new THREE.Vector3().copy(this.right).normalize(); + var oldUp = new THREE.Vector3().copy(this.up).normalize(); + this.up.applyAxisAngle(oldRight, up); + this.right.applyAxisAngle(oldUp, right); + this.NormalizeProjectionVectors(); +}; + +SolvespaceCamera.prototype.offsetProj = function(right, up) { + var shift = new THREE.Vector3(right * this.right.x + up * this.up.x, + right * this.right.y + up * this.up.y, + right * this.right.z + up * this.up.z); + this.offset.add(shift); +}; + +/* Calculate the offset in terms of up and right projection vectors +that will preserve the world coordinates of the current mouse position after +the zoom. */ +SolvespaceCamera.prototype.zoomTo = function(x, y, delta) { + // Get offset components in world coordinates, in terms of up/right. + var projOffsetX = this.offset.dot(this.right); + var projOffsetY = this.offset.dot(this.up); + + /* Remove offset before scaling so, that mouse position changes + proportionally to the model and independent of current offset. */ + var centerRightI = x/this.zoomScale - projOffsetX; + var centerUpI = y/this.zoomScale - projOffsetY; + var zoomFactor; + + /* Zoom 20% every 100 delta. */ + if(delta < 0) { + zoomFactor = (-delta * 0.002 + 1); + } + else if(delta > 0) { + zoomFactor = (delta * (-1.0/600.0) + 1); + } + else { + return; + } + + this.zoomScale = this.zoomScale * zoomFactor; + var centerRightF = x/this.zoomScale - projOffsetX; + var centerUpF = y/this.zoomScale - projOffsetY; + + this.offset.addScaledVector(this.right, centerRightF - centerRightI); + this.offset.addScaledVector(this.up, centerUpF - centerUpI); +}; + +SolvespaceControls = function(object, domElement) { + var _this = this; + this.object = object; + this.domElement = ( domElement !== undefined ) ? domElement : document; + + var threePan = new Hammer.Pan({event : 'threepan', pointers : 3, enable : false}); + var panAfterTap = new Hammer.Pan({event : 'panaftertap', enable : false}); + + this.touchControls = new Hammer.Manager(domElement, { + recognizers: [ + [Hammer.Pinch, { enable: true }], + [Hammer.Pan], + [Hammer.Tap], + ] + }); + + this.touchControls.add(threePan); + this.touchControls.add(panAfterTap); + + var changeEvent = { + type: 'change' + }; + var startEvent = { + type: 'start' + }; + var endEvent = { + type: 'end' + }; + + var _changed = false; + var _offsetPrev = new THREE.Vector2(0, 0); + var _offsetCur = new THREE.Vector2(0, 0); + var _rotatePrev = new THREE.Vector2(0, 0); + var _rotateCur = new THREE.Vector2(0, 0); + + // Used during touch events. + var _rotateOrig = new THREE.Vector2(0, 0); + var _offsetOrig = new THREE.Vector2(0, 0); + var _prevScale = 1.0; + + this.handleEvent = function(event) { + if (typeof this[event.type] == 'function') { + this[event.type](event); + } + } + + function mousedown(event) { + event.preventDefault(); + event.stopPropagation(); + + switch (event.button) { + case 0: + _rotateCur.set(event.screenX, + event.screenY); + _rotatePrev.copy(_rotateCur); + document.addEventListener('mousemove', mousemove_rotate, false); + document.addEventListener('mouseup', mouseup, false); + break; + case 2: + _offsetCur.set(event.screenX / window.devicePixelRatio, + event.screenY / window.devicePixelRatio); + _offsetPrev.copy(_offsetCur); + document.addEventListener('mousemove', mousemove_pan, false); + document.addEventListener('mouseup', mouseup, false); + break; + default: + break; + } + } + + function wheel( event ) { + event.preventDefault(); + /* FIXME: Width and height might not be supported universally, but + can be calculated? */ + var box = _this.domElement.getBoundingClientRect(); + object.zoomTo(event.clientX - box.width/2 - box.left, + -(event.clientY - box.height/2 - box.top), event.deltaY); + _changed = true; + } + + function mousemove_rotate(event) { + _rotateCur.set(event.screenX, + event.screenY); + var diff = new THREE.Vector2().subVectors(_rotateCur, _rotatePrev) + .multiplyScalar(1 / object.zoomScale); + object.rotate(-0.3 * Math.PI / 180 * diff.x * object.zoomScale, + -0.3 * Math.PI / 180 * diff.y * object.zoomScale); + _changed = true; + _rotatePrev.copy(_rotateCur); + } + + function mousemove_pan(event) { + _offsetCur.set(event.screenX / window.devicePixelRatio, + event.screenY / window.devicePixelRatio); + var diff = new THREE.Vector2().subVectors(_offsetCur, _offsetPrev) + .multiplyScalar(window.devicePixelRatio / object.zoomScale); + object.offsetProj(diff.x, -diff.y); + _changed = true; + _offsetPrev.copy(_offsetCur); + } + + function mouseup(event) { + /* TODO: Opera mouse gestures will intercept this event, making it + possible to have multiple mousedown events consecutively without + a corresponding mouseup (so multiple viewports can be rotated/panned + simultaneously). Disable mouse gestures for now. */ + event.preventDefault(); + event.stopPropagation(); + + switch (event.button) { + case 0: + document.removeEventListener('mousemove', mousemove_rotate); + document.removeEventListener('mouseup', mouseup); + break; + case 2: + document.removeEventListener('mousemove', mousemove_pan); + document.removeEventListener('mouseup', mouseup); + break; + } + + _this.dispatchEvent(endEvent); + } + + function pan(event) { + /* neWcur - prev does not necessarily equal (cur + diff) - prev. + Floating point is not associative. */ + var touchDiff = new THREE.Vector2(event.deltaX, event.deltaY); + _rotateCur.addVectors(_rotateOrig, touchDiff); + var incDiff = new THREE.Vector2().subVectors(_rotateCur, _rotatePrev) + .multiplyScalar(1 / object.zoomScale); + object.rotate(-0.3 * Math.PI / 180 * incDiff.x * object.zoomScale, + -0.3 * Math.PI / 180 * incDiff.y * object.zoomScale); + _changed = true; + _rotatePrev.copy(_rotateCur); + } + + function panstart(event) { + /* TODO: Dynamically enable pan function? */ + _rotateOrig.copy(_rotateCur); + } + + function pinchstart(event) { + _prevScale = event.scale; + } + + function pinch(event) { + /* FIXME: Width and height might not be supported universally, but + can be calculated? */ + var box = _this.domElement.getBoundingClientRect(); + + /* 16.6... pixels chosen heuristically... matches my touchpad. */ + if (event.scale < _prevScale) { + object.zoomTo(event.center.x - box.width/2 - box.left, + -(event.center.y - box.height/2 - box.top), 100/6.0); + _changed = true; + } else if (event.scale > _prevScale) { + object.zoomTo(event.center.x - box.width/2 - box.left, + -(event.center.y - box.height/2 - box.top), -100/6.0); + _changed = true; + } + + _prevScale = event.scale; + } + + /* A tap will enable panning/disable rotate. */ + function tap(event) { + panAfterTap.set({enable : true}); + _this.touchControls.get('pan').set({enable : false}); + } + + function panaftertap(event) { + var touchDiff = new THREE.Vector2(event.deltaX, event.deltaY); + _offsetCur.addVectors(_offsetOrig, touchDiff); + var incDiff = new THREE.Vector2().subVectors(_offsetCur, _offsetPrev) + .multiplyScalar(1 / object.zoomScale); + object.offsetProj(incDiff.x, -incDiff.y); + _changed = true; + _offsetPrev.copy(_offsetCur); + } + + function panaftertapstart(event) { + _offsetOrig.copy(_offsetCur); + } + + function panaftertapend(event) { + panAfterTap.set({enable : false}); + _this.touchControls.get('pan').set({enable : true}); + } + + function contextmenu(event) { + event.preventDefault(); + } + + this.update = function() { + if (_changed) { + _this.dispatchEvent(changeEvent); + _changed = false; + } + }; + + this.domElement.addEventListener('mousedown', mousedown, false); + this.domElement.addEventListener('wheel', wheel, false); + this.domElement.addEventListener('contextmenu', contextmenu, false); + + /* Hammer.on wraps addEventListener */ + // Rotate + this.touchControls.on('pan', pan); + this.touchControls.on('panstart', panstart); + + // Zoom + this.touchControls.on('pinch', pinch); + this.touchControls.on('pinchstart', pinchstart); + + //Pan + this.touchControls.on('tap', tap); + this.touchControls.on('panaftertapstart', panaftertapstart); + this.touchControls.on('panaftertap', panaftertap); + this.touchControls.on('panaftertapend', panaftertapend); +}; + +SolvespaceControls.prototype = Object.create(THREE.EventDispatcher.prototype); +SolvespaceControls.prototype.constructor = SolvespaceControls; + + +solvespace = function(obj, params) { + var scene, edgeScene, camera, edgeCamera, renderer; + var geometry, controls, material, mesh, edges; + var width, height, scale, offset, projRight, projUp; + var directionalLightArray = []; + var inheritedWidth = false, inheritedHeight = false; + + if (typeof params === "undefined" || !("width" in params)) { + width = window.innerWidth; + inheritedWidth = true; + } else { + width = params.width; + } + + if (typeof params === "undefined" || !("height" in params)) { + height = window.innerHeight; + inheritedHeight = true; + } else { + height = params.height; + } + + if (typeof params === "undefined" || !("scale" in params)) { + scale = 5; + } else { + scale = params.scale; + } + + if (typeof params === "undefined" || !("offset" in params)) { + offset = new THREE.Vector3(0, 0, 0); + } else { + offset = params.offset; + } + + if (typeof params === "undefined" || !("projUp" in params)) { + projUp = new THREE.Vector3(0, 1, -1); + } else { + projUp = params.projUp; + } + + if (typeof params === "undefined" || !("projRight" in params)) { + projRight = new THREE.Vector3(1, 0, -1); + } else { + projRight = params.projRight; + } + + var domElement = init(); + lightUpdate(); + render(); + return domElement; + + function init() { + scene = new THREE.Scene(); + edgeScene = new THREE.Scene(); + + camera = new SolvespaceCamera(width, height, scale, projUp, projRight, offset); + camera.NormalizeProjectionVectors(); + + mesh = createMesh(obj); + scene.add(mesh); + edges = createEdges(obj); + edgeScene.add(edges); + + for (var i = 0; i < obj.lights.d.length; i++) { + var lightColor = new THREE.Color(obj.lights.d[i].intensity, + obj.lights.d[i].intensity, obj.lights.d[i].intensity); + var directionalLight = new THREE.DirectionalLight(lightColor, 1); + directionalLight.position.set(obj.lights.d[i].direction[0], + obj.lights.d[i].direction[1], obj.lights.d[i].direction[2]); + directionalLightArray.push(directionalLight); + scene.add(directionalLight); + } + + var lightColor = new THREE.Color(obj.lights.a, obj.lights.a, obj.lights.a); + var ambientLight = new THREE.AmbientLight(lightColor.getHex()); + scene.add(ambientLight); + + renderer = new THREE.WebGLRenderer({ antialias: true}); + renderer.setSize(width * window.devicePixelRatio, height * window.devicePixelRatio); + renderer.autoClear = false; + renderer.domElement.style = + "width: " + width + "px;" + + "height: " + height + "px;"; + + controls = new SolvespaceControls(camera, renderer.domElement); + controls.addEventListener("change", render); + controls.addEventListener("change", lightUpdate); + + if(inheritedWidth || inheritedHeight) { + window.addEventListener("resize", resize); + } + + animate(); + return renderer.domElement; + } + + function resize() { + scale = camera.zoomScale; + if(inheritedWidth) { + scale *= window.innerWidth / width; + width = window.innerWidth; + } + if(inheritedHeight) { + scale *= window.innerHeight / height; + height = window.innerHeight; + } + + camera.renderWidth = width; + camera.renderHeight = height; + camera.zoomScale = scale; + + renderer.setSize(width * window.devicePixelRatio, height * window.devicePixelRatio); + renderer.domElement.style = + "width: " + width + "px;" + + "height: " + height + "px;"; + + render(); + } + + function animate() { + requestAnimationFrame(animate); + controls.update(); + } + + function render() { + var context = renderer.getContext(); + camera.updateProjectionMatrix(); + renderer.clear(); + + context.depthRange(0.1, 1); + renderer.render(scene, camera); + + context.depthRange(0.1-(2/60000.0), 1-(2/60000.0)); + renderer.render(edgeScene, camera); + } + + function lightUpdate() { + var changeBasis = new THREE.Matrix4(); + + // The original light positions were in camera space. + // Project them into standard space using camera's basis + // vectors (up, target, and their cross product). + var n = new THREE.Vector3().crossVectors(camera.up, camera.right); + changeBasis.makeBasis(camera.right, camera.up, n); + + for (var i = 0; i < 2; i++) { + var newLightPos = changeBasis.applyToVector3Array( + [obj.lights.d[i].direction[0], obj.lights.d[i].direction[1], + obj.lights.d[i].direction[2]]); + directionalLightArray[i].position.set(newLightPos[0], + newLightPos[1], newLightPos[2]); + } + } + + function createMesh(meshObj) { + var geometry = new THREE.Geometry(); + var materialIndex = 0; + var materialList = []; + var opacitiesSeen = {}; + + for (var i = 0; i < meshObj.points.length; i++) { + geometry.vertices.push(new THREE.Vector3(meshObj.points[i][0], + meshObj.points[i][1], meshObj.points[i][2])); + } + + for (var i = 0; i < meshObj.faces.length; i++) { + var currOpacity = ((meshObj.colors[i] & 0xFF000000) >>> 24) / 255.0; + if (opacitiesSeen[currOpacity] === undefined) { + opacitiesSeen[currOpacity] = materialIndex; + materialIndex++; + materialList.push(new THREE.MeshLambertMaterial({ + vertexColors: THREE.FaceColors, + opacity: currOpacity, + transparent: true, + side: THREE.DoubleSide + })); + } + + geometry.faces.push(new THREE.Face3(meshObj.faces[i][0], + meshObj.faces[i][1], meshObj.faces[i][2], + [new THREE.Vector3(meshObj.normals[i][0][0], + meshObj.normals[i][0][1], meshObj.normals[i][0][2]), + new THREE.Vector3(meshObj.normals[i][1][0], + meshObj.normals[i][1][1], meshObj.normals[i][1][2]), + new THREE.Vector3(meshObj.normals[i][2][0], + meshObj.normals[i][2][1], meshObj.normals[i][2][2])], + new THREE.Color(meshObj.colors[i] & 0x00FFFFFF), + opacitiesSeen[currOpacity])); + } + + geometry.computeBoundingSphere(); + return new THREE.Mesh(geometry, new THREE.MultiMaterial(materialList)); + } + + function createEdges(meshObj) { + var geometry = new THREE.Geometry(); + var material = new THREE.LineBasicMaterial(); + + for (var i = 0; i < meshObj.edges.length; i++) { + geometry.vertices.push(new THREE.Vector3(meshObj.edges[i][0][0], + meshObj.edges[i][0][1], meshObj.edges[i][0][2]), + new THREE.Vector3(meshObj.edges[i][1][0], + meshObj.edges[i][1][1], meshObj.edges[i][1][2])); + } + + geometry.computeBoundingSphere(); + return new THREE.LineSegments(geometry, material); + } +}; + diff --git a/res/threejs/hammer-2.0.8.js.gz b/res/threejs/hammer-2.0.8.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..764a580fa9dc21548397ffa5189cfc43a462394d GIT binary patch literal 17503 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 literal 0 HcmV?d00001 diff --git a/res/win32/manifest.xml b/res/win32/manifest.xml new file mode 100644 index 0000000..7c49a2e --- /dev/null +++ b/res/win32/manifest.xml @@ -0,0 +1,28 @@ + + + +Parametric 3d CAD tool. + + + PerMonitorV2, PerMonitor + true + + + + + + + + diff --git a/res/win32/versioninfo.rc.in b/res/win32/versioninfo.rc.in new file mode 100644 index 0000000..e6e9005 --- /dev/null +++ b/res/win32/versioninfo.rc.in @@ -0,0 +1,29 @@ +1 VERSIONINFO +FILEVERSION ${solvespace_VERSION_MAJOR},${solvespace_VERSION_MINOR},0,0 +PRODUCTVERSION ${solvespace_VERSION_MAJOR},${solvespace_VERSION_MINOR},0,0 +FILEFLAGSMASK 0 +FILEFLAGS 0 +FILEOS VOS_NT_WINDOWS32 +FILETYPE VFT_APP +FILESUBTYPE 0 +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "04090000" + BEGIN + VALUE "CompanyName", "The SolveSpace authors" + VALUE "ProductName", "SolveSpace" + VALUE "ProductVersion", "${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}~${solvespace_GIT_HASH}" + VALUE "FileDescription", "SolveSpace, a parametric 2d/3d CAD" + VALUE "FileVersion", "${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}~${solvespace_GIT_HASH}" + VALUE "OriginalFilename", "solvespace.exe" + VALUE "InternalName", "solvespace" + VALUE "LegalCopyright", "(c) 2008-2021 Jonathan Westhues and other authors" + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 0 + END +END diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..45dab94 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,417 @@ +include(GNUInstallDirs) + +# configuration + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}) + +set(HAVE_SPACEWARE ${SPACEWARE_FOUND}) + +if(NOT WIN32 OR APPLE) + if(GTKMM_gtkmm-3.0_VERSION VERSION_LESS "3.24.0") + set(HAVE_GTK_FILECHOOSERNATIVE 0) + else() + set(HAVE_GTK_FILECHOOSERNATIVE 1) + endif() +endif() + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/config.h) + +# platform utilities + +if(APPLE) + set(util_LIBRARIES + ${APPKIT_LIBRARY}) +endif() + +# libslvs + +set(libslvs_SOURCES + util.cpp + entity.cpp + expr.cpp + constraint.cpp + constrainteq.cpp + system.cpp + platform/platform.cpp) + +set(libslvs_HEADERS + solvespace.h + platform/platform.h) + +add_library(slvs SHARED + ${libslvs_SOURCES} + ${libslvs_HEADERS} + ${util_SOURCES} + lib.cpp) + +target_compile_definitions(slvs + PRIVATE -DLIBRARY) + +target_include_directories(slvs + PUBLIC ${CMAKE_SOURCE_DIR}/include) + +target_link_libraries(slvs + ${util_LIBRARIES} + mimalloc-static) + +add_dependencies(slvs + mimalloc-static) + +set_target_properties(slvs PROPERTIES + PUBLIC_HEADER ${CMAKE_SOURCE_DIR}/include/slvs.h + VERSION ${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR} + SOVERSION 1) + +if(NOT WIN32) + install(TARGETS slvs + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +endif() + +# solvespace dependencies + +include_directories( + ${OPENGL_INCLUDE_DIR} + ${ZLIB_INCLUDE_DIR} + ${PNG_PNG_INCLUDE_DIR} + ${FREETYPE_INCLUDE_DIRS} + ${CAIRO_INCLUDE_DIRS} + ${MIMALLOC_INCLUDE_DIR} + ${OpenMP_CXX_INCLUDE_DIRS}) + +if(Backtrace_FOUND) + include_directories( + ${Backtrace_INCLUDE_DIRS}) +endif() + +if(SPACEWARE_FOUND) + include_directories( + ${SPACEWARE_INCLUDE_DIR}) +endif() + +if(OPENGL STREQUAL 3) + set(gl_SOURCES + render/gl3shader.cpp + render/rendergl3.cpp) +elseif(OPENGL STREQUAL 1) + set(gl_SOURCES + render/rendergl1.cpp) +else() + message(FATAL_ERROR "Unsupported OpenGL version ${OPENGL}") +endif() + +set(platform_SOURCES + ${gl_SOURCES} + platform/entrygui.cpp) + +if(WIN32) + list(APPEND platform_SOURCES + platform/guiwin.cpp) + + set(platform_LIBRARIES + comctl32 + ${SPACEWARE_LIBRARIES}) +elseif(APPLE) + add_compile_options( + -fobjc-arc) + + list(APPEND platform_SOURCES + platform/guimac.mm) +else() + list(APPEND platform_SOURCES + platform/guigtk.cpp) + + set(platform_LIBRARIES + ${SPACEWARE_LIBRARIES}) + + foreach(pkg_config_lib GTKMM JSONC FONTCONFIG) + include_directories(${${pkg_config_lib}_INCLUDE_DIRS}) + link_directories(${${pkg_config_lib}_LIBRARY_DIRS}) + list(APPEND platform_LIBRARIES ${${pkg_config_lib}_LIBRARIES}) + endforeach() +endif() + +set(every_platform_SOURCES + platform/guiwin.cpp + platform/guigtk.cpp + platform/guimac.mm) + +# solvespace library + +set(solvespace_core_HEADERS + dsc.h + expr.h + polygon.h + sketch.h + solvespace.h + ui.h + platform/platform.h + render/render.h + render/gl3shader.h + srf/surface.h) + +set(solvespace_core_SOURCES + bsp.cpp + clipboard.cpp + confscreen.cpp + constraint.cpp + constrainteq.cpp + describescreen.cpp + draw.cpp + drawconstraint.cpp + drawentity.cpp + entity.cpp + export.cpp + exportstep.cpp + exportvector.cpp + expr.cpp + file.cpp + generate.cpp + graphicswin.cpp + group.cpp + groupmesh.cpp + importdxf.cpp + importidf.cpp + mesh.cpp + modify.cpp + mouse.cpp + polyline.cpp + polygon.cpp + resource.cpp + request.cpp + style.cpp + system.cpp + textscreens.cpp + textwin.cpp + toolbar.cpp + ttf.cpp + undoredo.cpp + util.cpp + view.cpp + platform/platform.cpp + platform/gui.cpp + render/render.cpp + render/render2d.cpp + srf/boolean.cpp + srf/curve.cpp + srf/merge.cpp + srf/ratpoly.cpp + srf/raycast.cpp + srf/surface.cpp + srf/surfinter.cpp + srf/triangulate.cpp) + +set(solvespace_core_gl_SOURCES + solvespace.cpp) + +add_library(solvespace-core STATIC + ${util_SOURCES} + ${solvespace_core_HEADERS} + ${solvespace_core_SOURCES}) + +add_dependencies(solvespace-core + mimalloc-static) + +target_link_libraries(solvespace-core + ${OpenMP_CXX_LIBRARIES} + dxfrw + ${util_LIBRARIES} + ${ZLIB_LIBRARY} + ${PNG_LIBRARY} + ${FREETYPE_LIBRARY} + mimalloc-static) + +if(Backtrace_FOUND) + target_link_libraries(solvespace-core + ${Backtrace_LIBRARY}) +endif() + +target_compile_options(solvespace-core + PRIVATE ${COVERAGE_FLAGS}) + +# solvespace translations + +if(HAVE_GETTEXT) + set(inputs + ${solvespace_core_SOURCES} + ${solvespace_core_HEADERS} + ${every_platform_SOURCES} + ${solvespace_core_gl_SOURCES}) + + set(templ_po ${CMAKE_CURRENT_BINARY_DIR}/../res/messages.po) + + set(output_pot ${CMAKE_CURRENT_SOURCE_DIR}/../res/messages.pot) + set(output_po ${CMAKE_CURRENT_SOURCE_DIR}/../res/locales/en_US.po) + file(GLOB locale_pos ${CMAKE_CURRENT_SOURCE_DIR}/../res/locales/*.po) + + string(REPLACE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} + gen_output_pot ${output_pot}.gen) + string(REPLACE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} + gen_output_po ${output_po}.gen) + foreach(locale_po ${locale_pos}) + string(REPLACE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} + gen_locale_po ${locale_po}.gen) + list(APPEND gen_locale_pos ${gen_locale_po}) + endforeach() + + add_custom_command( + OUTPUT ${gen_output_pot} + COMMAND ${XGETTEXT} + --language=C++ + --keyword --keyword=_ --keyword=N_ --keyword=C_:2,1c --keyword=CN_:2,1c + --force-po --width=100 --sort-by-file + --package-name=SolveSpace + --package-version=${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR} + "--copyright-holder=the PACKAGE authors" + --msgid-bugs-address=whitequark@whitequark.org + --from-code=utf-8 --output=${gen_output_pot} ${inputs} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${gen_output_pot} ${output_pot} + DEPENDS ${inputs} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Extracting translations" + VERBATIM) + + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../res/locales) + + # en_US is a bit special; we pre-fill the msgstrs from msgids, instead of (as would normally + # happen) leaving them empty. + add_custom_command( + OUTPUT ${gen_output_po} + COMMAND ${MSGINIT} + --locale=en_US --no-translator + --output=${templ_po} --input=${gen_output_pot} + COMMAND ${MSGMERGE} + --force-po --no-fuzzy-matching + --output=${gen_output_po} ${output_po} ${templ_po} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${gen_output_po} ${output_po} + DEPENDS ${gen_output_pot} + COMMENT "Updating en_US translations" + VERBATIM) + + foreach(locale_po ${locale_pos}) + string(REPLACE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} + gen_locale_po ${locale_po}.gen) + + get_filename_component(locale_name ${locale_po} NAME_WE) + if(locale_name STREQUAL "en_US") + continue() + endif() + + add_custom_command( + OUTPUT ${gen_locale_po} + COMMAND ${MSGMERGE} + --no-fuzzy-matching + --output=${gen_locale_po} ${locale_po} ${gen_output_pot} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${gen_locale_po} ${locale_po} + DEPENDS ${gen_output_pot} + COMMENT "Updating ${locale_name} translations" + VERBATIM) + endforeach() + + add_custom_target(translate_solvespace + DEPENDS ${gen_output_pot} ${gen_output_po} ${gen_locale_pos}) +endif() + +# solvespace graphical executable + +if(ENABLE_GUI) + add_executable(solvespace WIN32 MACOSX_BUNDLE + ${solvespace_core_gl_SOURCES} + ${platform_SOURCES} + $) + + add_dependencies(solvespace + resources) + + target_link_libraries(solvespace + solvespace-core + ${OPENGL_LIBRARIES} + ${platform_LIBRARIES} + ${COVERAGE_LIBRARY}) + + if(MSVC) + set_target_properties(solvespace PROPERTIES + LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /INCREMENTAL:NO /OPT:REF") + elseif(APPLE) + set_target_properties(solvespace PROPERTIES + OUTPUT_NAME SolveSpace) + endif() +endif() + +# solvespace headless library + +set(headless_SOURCES + platform/guinone.cpp + render/rendercairo.cpp) + +add_library(solvespace-headless STATIC EXCLUDE_FROM_ALL + ${solvespace_core_gl_SOURCES} + ${headless_SOURCES}) + +target_compile_definitions(solvespace-headless + PRIVATE -DHEADLESS) + +target_include_directories(solvespace-headless + INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + +target_link_libraries(solvespace-headless + solvespace-core + ${CAIRO_LIBRARIES}) + +target_compile_options(solvespace-headless + PRIVATE ${COVERAGE_FLAGS}) + +# solvespace command-line executable + +if(ENABLE_CLI) + add_executable(solvespace-cli + platform/entrycli.cpp + $) + + target_link_libraries(solvespace-cli + solvespace-core + solvespace-headless) + + add_dependencies(solvespace-cli + resources) + + if(MSVC) + set_target_properties(solvespace-cli PROPERTIES + LINK_FLAGS "/INCREMENTAL:NO /OPT:REF") + endif() +endif() + +# solvespace unix package + +if(NOT (WIN32 OR APPLE)) + if(ENABLE_GUI) + install(TARGETS solvespace + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif() + if(ENABLE_CLI) + install(TARGETS solvespace-cli + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + endif() +endif() + +# solvespace macOS package + +if(APPLE) + set(bundle SolveSpace) + set(bundle_bin ${EXECUTABLE_OUTPUT_PATH}/${bundle}.app/Contents/MacOS) + set(bundle_resources ${EXECUTABLE_OUTPUT_PATH}/${bundle}.app/Contents/Resources/lib) + execute_process( + COMMAND mkdir -p ${bundle_resources} + COMMAND cp -p /usr/local/opt/libomp/lib/libomp.dylib ${bundle_resources}/libomp.dylib + ) + add_custom_command(TARGET solvespace POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${bundle_bin} + COMMAND ${CMAKE_COMMAND} -E copy $ ${bundle_bin} + COMMAND install_name_tool -change /usr/local/opt/libomp/lib/libomp.dylib "@executable_path/../Resources/lib/libomp.dylib" ${bundle_bin}/${bundle} + COMMENT "Bundling executable solvespace-cli" + VERBATIM) +endif() diff --git a/src/bsp.cpp b/src/bsp.cpp new file mode 100644 index 0000000..bac5ff3 --- /dev/null +++ b/src/bsp.cpp @@ -0,0 +1,729 @@ +//----------------------------------------------------------------------------- +// Binary space partitioning tree, used to represent a volume in 3-space +// bounded by a triangle mesh. These are used to compute Boolean operations +// on meshes. These aren't used for anything relating to an SShell of +// ratpoly surfaces. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +SBsp2 *SBsp2::Alloc() { return (SBsp2 *)AllocTemporary(sizeof(SBsp2)); } +SBsp3 *SBsp3::Alloc() { return (SBsp3 *)AllocTemporary(sizeof(SBsp3)); } + +SBsp3 *SBsp3::FromMesh(const SMesh *m) { + SMesh mc = {}; + for(auto const &elt : m->l) { mc.AddTriangle(&elt); } + + srand(0); // Let's be deterministic, at least! + int n = mc.l.n; + while(n > 1) { + int k = rand() % n; + n--; + swap(mc.l[k], mc.l[n]); + } + + SBsp3 *bsp3 = NULL; + for(auto &elt : mc.l) { bsp3 = InsertOrCreate(bsp3, &elt, NULL); } + mc.Clear(); + return bsp3; +} + +Vector SBsp3::IntersectionWith(Vector a, Vector b) const { + double da = a.Dot(n) - d; + double db = b.Dot(n) - d; + ssassert(da*db < 0, "Expected segment to intersect BSP node"); + + double dab = (db - da); + return (a.ScaledBy(db/dab)).Plus(b.ScaledBy(-da/dab)); +} + +void SBsp3::InsertInPlane(bool pos2, STriangle *tr, SMesh *m) { + Vector tc = ((tr->a).Plus(tr->b).Plus(tr->c)).ScaledBy(1.0/3); + + bool onFace = false; + bool sameNormal = false; + double maxNormalMag = -1; + + Vector lln, trn = tr->Normal(); + + SBsp3 *ll = this; + while(ll) { + if((ll->tri).ContainsPoint(tc)) { + onFace = true; + // If the mesh contains almost-zero-area triangles, and we're + // just on the edge of one of those, then don't trust its normal. + lln = (ll->tri).Normal(); + if(lln.Magnitude() > maxNormalMag) { + sameNormal = trn.Dot(lln) > 0; + maxNormalMag = lln.Magnitude(); + } + } + ll = ll->more; + } + + if((!onFace && ((m->keepInsideOtherShell && !pos2) || + (!m->keepInsideOtherShell && pos2))) || + (onFace && ((m->keepCoplanar && m->flipNormal && !sameNormal) || + (m->keepCoplanar && !m->flipNormal && sameNormal)))) { + // We have decided that we need to keep a triangle either inside, + // outside or on the other shell. So add it and flip it if requested. + if(!(m->flipNormal)) { + m->AddTriangle(tr->meta, tr->a, tr->b, tr->c); + } else { + m->AddTriangle(tr->meta, tr->c, tr->b, tr->a); + } + } else { + m->atLeastOneDiscarded = true; + } +} + +void SBsp3::InsertHow(BspClass how, STriangle *tr, SMesh *instead) { + switch(how) { + case BspClass::POS: + if(instead && !pos) goto alt; + pos = InsertOrCreate(pos, tr, instead); + break; + + case BspClass::NEG: + if(instead && !neg) goto alt; + neg = InsertOrCreate(neg, tr, instead); + break; + + case BspClass::COPLANAR: { + if(instead) goto alt; + SBsp3 *m = Alloc(); + m->n = n; + m->d = d; + m->tri = *tr; + m->more = more; + more = m; + break; + } + } + return; + +alt: + if(((BspClass::POS == how) && !instead->keepInsideOtherShell) || + ((BspClass::NEG == how) && instead->keepInsideOtherShell)) { + // We have decided that we need to keep a triangle (either inside or + // outside the other shell. So add it and flip it if requested. + if(!(instead->flipNormal)) { + instead->AddTriangle(tr->meta, tr->a, tr->b, tr->c); + } else { + instead->AddTriangle(tr->meta, tr->c, tr->b, tr->a); + } + } else if(how == BspClass::COPLANAR) { + if(edges) { + edges->InsertTriangle(tr, instead, this); + } else { + // I suppose this actually is allowed to happen, if the coplanar + // face is the leaf, and all of its neighbors are earlier in tree? + InsertInPlane(/*pos2=*/false, tr, instead); + } + } else { + instead->atLeastOneDiscarded = true; + } +} + +class BspUtil { +public: + SBsp3 *bsp; + + size_t onc; + size_t posc; + size_t negc; + bool *isPos; + bool *isNeg; + bool *isOn; + + // triangle operations + STriangle *tr; + STriangle *btri; // also as alone + STriangle *ctri; + + // convex operations + Vector *on; + size_t npos; + size_t nneg; + Vector *vpos; // also as quad + Vector *vneg; + + static BspUtil *Alloc() { + return (BspUtil *)AllocTemporary(sizeof(BspUtil)); + } + + void AllocOn() { + on = (Vector *)AllocTemporary(sizeof(Vector) * 2); + } + + void AllocTriangle() { + btri = (STriangle *)AllocTemporary(sizeof(STriangle)); + } + + void AllocTriangles() { + btri = (STriangle *)AllocTemporary(sizeof(STriangle) * 2); + ctri = &btri[1]; + } + + void AllocQuad() { + vpos = (Vector *)AllocTemporary(sizeof(Vector) * 4); + } + + void AllocClassify(size_t size) { + // Allocate a one big piece is faster than a small ones. + isPos = (bool *)AllocTemporary(sizeof(bool) * size * 3); + isNeg = &isPos[size]; + isOn = &isNeg[size]; + } + + void AllocVertices(size_t size) { + vpos = (Vector *)AllocTemporary(sizeof(Vector) * size * 2); + vneg = &vpos[size]; + } + + void ClassifyTriangle(STriangle *tri, SBsp3 *node) { + tr = tri; + bsp = node; + onc = 0; + posc = 0; + negc = 0; + + AllocClassify(3); + + double dt[3] = { (tr->a).Dot(bsp->n), (tr->b).Dot(bsp->n), (tr->c).Dot(bsp->n) }; + double d = bsp->d; + // Count vertices in the plane + for(int i = 0; i < 3; i++) { + if(dt[i] > d + LENGTH_EPS) { + posc++; + isPos[i] = true; + } else if(dt[i] < d - LENGTH_EPS) { + negc++; + isNeg[i] = true; + } else { + onc++; + isOn[i] = true; + } + } + } + + bool ClassifyConvex(Vector *vertex, size_t cnt, SBsp3 *node, bool insertEdge) { + bsp = node; + onc = 0; + posc = 0; + negc = 0; + + AllocClassify(cnt); + AllocOn(); + + for(size_t i = 0; i < cnt; i++) { + double dt = bsp->n.Dot(vertex[i]); + isPos[i] = isNeg[i] = isOn[i] = false; + if(fabs(dt - bsp->d) < LENGTH_EPS) { + isOn[i] = true; + if(onc < 2) { + on[onc] = vertex[i]; + } + onc++; + } else if(dt > bsp->d) { + isPos[i] = true; + posc++; + } else { + isNeg[i] = true; + negc++; + } + } + + if(onc != 2 && onc != 1 && onc != 0) return false; + if(onc == 2) { + if(insertEdge) { + Vector e01 = (vertex[1]).Minus(vertex[0]); + Vector e12 = (vertex[2]).Minus(vertex[1]); + Vector out = e01.Cross(e12); + SEdge se = SEdge::From(on[0], on[1]); + bsp->edges = SBsp2::InsertOrCreateEdge(bsp->edges, &se, bsp->n, out); + } + } + return true; + } + + bool ClassifyConvexVertices(Vector *vertex, size_t cnt, bool insertEdges) { + Vector inter[2]; + int inters = 0; + + npos = 0; + nneg = 0; + + // Enlarge vertices list to consider two intersections + AllocVertices(cnt + 4); + + for(size_t i = 0; i < cnt; i++) { + size_t ip = WRAP((i + 1), cnt); + + if(isPos[i]) { + vpos[npos++] = vertex[i]; + } + if(isNeg[i]) { + vneg[nneg++] = vertex[i]; + } + if(isOn[i]) { + vneg[nneg++] = vertex[i]; + vpos[npos++] = vertex[i]; + } + if((isPos[i] && isNeg[ip]) || (isNeg[i] && isPos[ip])) { + Vector vi = bsp->IntersectionWith(vertex[i], vertex[ip]); + vpos[npos++] = vi; + vneg[nneg++] = vi; + + if(inters >= 2) return false; // triangulate: XXX shouldn't happen but does + inter[inters++] = vi; + } + } + ssassert(npos <= cnt + 1 && nneg <= cnt + 1, "Impossible"); + + if(insertEdges) { + Vector e01 = (vertex[1]).Minus(vertex[0]); + Vector e12 = (vertex[2]).Minus(vertex[1]); + Vector out = e01.Cross(e12); + if(inters == 2) { + SEdge se = SEdge::From(inter[0], inter[1]); + bsp->edges = SBsp2::InsertOrCreateEdge(bsp->edges, &se, bsp->n, out); + } else if(inters == 1 && onc == 1) { + SEdge se = SEdge::From(inter[0], on[0]); + bsp->edges = SBsp2::InsertOrCreateEdge(bsp->edges, &se, bsp->n, out); + } else if(inters == 0 && onc == 2) { + // We already handled this on-plane existing edge + } else { + return false; //triangulate; + } + } + if(nneg < 3 || npos < 3) return false; // triangulate; // XXX + + return true; + } + + void ProcessEdgeInsert() { + ssassert(onc == 2, "Impossible"); + + Vector a, b; + if (!isOn[0]) { a = tr->b; b = tr->c; } + else if(!isOn[1]) { a = tr->c; b = tr->a; } + else if(!isOn[2]) { a = tr->a; b = tr->b; } + else ssassert(false, "Impossible"); + + SEdge se = SEdge::From(a, b); + bsp->edges = SBsp2::InsertOrCreateEdge(bsp->edges, &se, bsp->n, tr->Normal()); + } + + bool SplitIntoTwoTriangles(bool insertEdge) { + ssassert(posc == 1 && negc == 1 && onc == 1, "Impossible"); + + bool bpos; + Vector a, b, c; + + // Standardize so that a is on the plane + if (isOn[0]) { a = tr->a; b = tr->b; c = tr->c; bpos = isPos[1]; + } else if(isOn[1]) { a = tr->b; b = tr->c; c = tr->a; bpos = isPos[2]; + } else if(isOn[2]) { a = tr->c; b = tr->a; c = tr->b; bpos = isPos[0]; + } else ssassert(false, "Impossible"); + + AllocTriangles(); + Vector bPc = bsp->IntersectionWith(b, c); + *btri = STriangle::From(tr->meta, a, b, bPc); + *ctri = STriangle::From(tr->meta, c, a, bPc); + + if(insertEdge) { + SEdge se = SEdge::From(a, bPc); + bsp->edges = SBsp2::InsertOrCreateEdge(bsp->edges, &se, bsp->n, tr->Normal()); + } + + return bpos; + } + + bool SplitIntoTwoPieces(bool insertEdge) { + Vector a, b, c; + if(posc == 2 && negc == 1) { + // Standardize so that a is on one side, and b and c are on the other. + if (isNeg[0]) { a = tr->a; b = tr->b; c = tr->c; + } else if(isNeg[1]) { a = tr->b; b = tr->c; c = tr->a; + } else if(isNeg[2]) { a = tr->c; b = tr->a; c = tr->b; + } else ssassert(false, "Impossible"); + } else if(posc == 1 && negc == 2) { + if (isPos[0]) { a = tr->a; b = tr->b; c = tr->c; + } else if(isPos[1]) { a = tr->b; b = tr->c; c = tr->a; + } else if(isPos[2]) { a = tr->c; b = tr->a; c = tr->b; + } else ssassert(false, "Impossible"); + } else ssassert(false, "Impossible"); + + Vector aPb = bsp->IntersectionWith(a, b); + Vector cPa = bsp->IntersectionWith(c, a); + AllocTriangle(); + AllocQuad(); + + *btri = STriangle::From(tr->meta, a, aPb, cPa); + + vpos[0] = aPb; + vpos[1] = b; + vpos[2] = c; + vpos[3] = cPa; + + if(insertEdge) { + SEdge se = SEdge::From(aPb, cPa); + bsp->edges = SBsp2::InsertOrCreateEdge(bsp->edges, &se, bsp->n, btri->Normal()); + } + + return posc == 2 && negc == 1; + } + + static SBsp3 *Triangulate(SBsp3 *bsp, const STriMeta &meta, Vector *vertex, + size_t cnt, SMesh *instead) { + for(size_t i = 0; i < cnt - 2; i++) { + STriangle tr = STriangle::From(meta, vertex[0], vertex[i + 1], vertex[i + 2]); + bsp = SBsp3::InsertOrCreate(bsp, &tr, instead); + } + return bsp; + } +}; + +void SBsp3::InsertConvexHow(BspClass how, STriMeta meta, Vector *vertex, size_t n, + SMesh *instead) { + switch(how) { + case BspClass::POS: + if(pos) { + pos = pos->InsertConvex(meta, vertex, n, instead); + return; + } + break; + + case BspClass::NEG: + if(neg) { + neg = neg->InsertConvex(meta, vertex, n, instead); + return; + } + break; + + default: ssassert(false, "Unexpected BSP insert type"); + } + + for(size_t i = 0; i < n - 2; i++) { + STriangle tr = STriangle::From(meta, + vertex[0], vertex[i+1], vertex[i+2]); + InsertHow(how, &tr, instead); + } +} + +SBsp3 *SBsp3::InsertConvex(STriMeta meta, Vector *vertex, size_t cnt, SMesh *instead) { + BspUtil *u = BspUtil::Alloc(); + if(u->ClassifyConvex(vertex, cnt, this, !instead)) { + if(u->posc == 0) { + InsertConvexHow(BspClass::NEG, meta, vertex, cnt, instead); + return this; + } + if(u->negc == 0) { + InsertConvexHow(BspClass::POS, meta, vertex, cnt, instead); + return this; + } + + if(u->ClassifyConvexVertices(vertex, cnt, !instead)) { + InsertConvexHow(BspClass::NEG, meta, u->vneg, u->nneg, instead); + InsertConvexHow(BspClass::POS, meta, u->vpos, u->npos, instead); + return this; + } + } + + // We don't handle the special case for this; do it as triangles + return BspUtil::Triangulate(this, meta, vertex, cnt, instead); +} + +SBsp3 *SBsp3::InsertOrCreate(SBsp3 *where, STriangle *tr, SMesh *instead) { + if(where == NULL) { + if(instead) { + // ruevs: I do not think this code is reachable, but in + // principle should we use instead->keepInsideOtherShell + // in place of instead->flipNormal ? + if(instead->flipNormal) { + instead->atLeastOneDiscarded = true; + } else { + instead->AddTriangle(tr->meta, tr->a, tr->b, tr->c); + } + return NULL; + } + + // Brand new node; so allocate for it, and fill us in. + SBsp3 *r = Alloc(); + r->n = (tr->Normal()).WithMagnitude(1); + r->d = (tr->a).Dot(r->n); + r->tri = *tr; + return r; + } + where->Insert(tr, instead); + return where; +} + +void SBsp3::Insert(STriangle *tr, SMesh *instead) { + BspUtil *u = BspUtil::Alloc(); + u->ClassifyTriangle(tr, this); + + // All vertices in-plane + if(u->onc == 3) { + InsertHow(BspClass::COPLANAR, tr, instead); + return; + } + + // No split required + if(u->posc == 0 || u->negc == 0) { + if(!instead && u->onc == 2) { + u->ProcessEdgeInsert(); + } + + if(u->posc > 0) { + InsertHow(BspClass::POS, tr, instead); + } else { + InsertHow(BspClass::NEG, tr, instead); + } + return; + } + + // The polygon must be split into two triangles, one above, one below. + if(u->posc == 1 && u->negc == 1 && u->onc == 1) { + if(u->SplitIntoTwoTriangles(!instead)) { + InsertHow(BspClass::POS, u->btri, instead); + InsertHow(BspClass::NEG, u->ctri, instead); + } else { + InsertHow(BspClass::POS, u->ctri, instead); + InsertHow(BspClass::NEG, u->btri, instead); + } + return; + } + + // The polygon must be split into two pieces: a triangle and a quad. + if(u->SplitIntoTwoPieces(!instead)) { + InsertConvexHow(BspClass::POS, tr->meta, u->vpos, 4, instead); + InsertHow(BspClass::NEG, u->btri, instead); + } else { + InsertConvexHow(BspClass::NEG, tr->meta, u->vpos, 4, instead); + InsertHow(BspClass::POS, u->btri, instead); + } +} + +void SBsp3::GenerateInPaintOrder(SMesh *m) const { + // Doesn't matter which branch we take if the normal has zero z + // component, so don't need a separate case for that. + if(n.z < 0) { + if(pos) pos->GenerateInPaintOrder(m); + } else { + if(neg) neg->GenerateInPaintOrder(m); + } + + const SBsp3 *flip = this; + while(flip) { + m->AddTriangle(&(flip->tri)); + flip = flip->more; + } + + if(n.z < 0) { + if(neg) neg->GenerateInPaintOrder(m); + } else { + if(pos) pos->GenerateInPaintOrder(m); + } +} + +///////////////////////////////// + +Vector SBsp2::IntersectionWith(Vector a, Vector b) const { + double da = a.Dot(no) - d; + double db = b.Dot(no) - d; + ssassert(da*db < 0, "Expected segment to intersect BSP node"); + + double dab = (db - da); + return (a.ScaledBy(db/dab)).Plus(b.ScaledBy(-da/dab)); +} + +SBsp2 *SBsp2::InsertOrCreateEdge(SBsp2 *where, SEdge *nedge, Vector nnp, Vector out) { + if(where == NULL) { + // Brand new node; so allocate for it, and fill us in. + SBsp2 *r = Alloc(); + r->np = nnp; + r->no = ((r->np).Cross((nedge->b).Minus(nedge->a))).WithMagnitude(1); + if(out.Dot(r->no) < 0) { + r->no = (r->no).ScaledBy(-1); + } + r->d = (nedge->a).Dot(r->no); + r->edge = *nedge; + return r; + } + where->InsertEdge(nedge, nnp, out); + return where; +} + +void SBsp2::InsertEdge(SEdge *nedge, Vector nnp, Vector out) { + + double dt[2] = { (nedge->a).Dot(no), (nedge->b).Dot(no) }; + + bool isPos[2] = {}, isNeg[2] = {}, isOn[2] = {}; + for(int i = 0; i < 2; i++) { + if(fabs(dt[i] - d) < LENGTH_EPS) { + isOn[i] = true; + } else if(dt[i] > d) { + isPos[i] = true; + } else { + isNeg[i] = true; + } + } + + if((isPos[0] && isPos[1])||(isPos[0] && isOn[1])||(isOn[0] && isPos[1])) { + pos = InsertOrCreateEdge(pos, nedge, nnp, out); + return; + } + if((isNeg[0] && isNeg[1])||(isNeg[0] && isOn[1])||(isOn[0] && isNeg[1])) { + neg = InsertOrCreateEdge(neg, nedge, nnp, out); + return; + } + if(isOn[0] && isOn[1]) { + SBsp2 *m = Alloc(); + + m->np = nnp; + m->no = ((m->np).Cross((nedge->b).Minus(nedge->a))).WithMagnitude(1); + if(out.Dot(m->no) < 0) { + m->no = (m->no).ScaledBy(-1); + } + m->d = (nedge->a).Dot(m->no); + m->edge = *nedge; + + m->more = more; + more = m; + return; + } + if((isPos[0] && isNeg[1]) || (isNeg[0] && isPos[1])) { + Vector aPb = IntersectionWith(nedge->a, nedge->b); + + SEdge ea = SEdge::From(nedge->a, aPb); + SEdge eb = SEdge::From(aPb, nedge->b); + + if(isPos[0]) { + pos = InsertOrCreateEdge(pos, &ea, nnp, out); + neg = InsertOrCreateEdge(neg, &eb, nnp, out); + } else { + neg = InsertOrCreateEdge(neg, &ea, nnp, out); + pos = InsertOrCreateEdge(pos, &eb, nnp, out); + } + return; + } + ssassert(false, "Impossible"); +} + +void SBsp2::InsertTriangleHow(BspClass how, STriangle *tr, SMesh *m, SBsp3 *bsp3) { + switch(how) { + case BspClass::POS: + if(pos) { + pos->InsertTriangle(tr, m, bsp3); + } else { + bsp3->InsertInPlane(/*pos2=*/true, tr, m); + } + break; + + case BspClass::NEG: + if(neg) { + neg->InsertTriangle(tr, m, bsp3); + } else { + bsp3->InsertInPlane(/*pos2=*/false, tr, m); + } + break; + + default: ssassert(false, "Unexpected BSP insert type"); + } +} + +void SBsp2::InsertTriangle(STriangle *tr, SMesh *m, SBsp3 *bsp3) { + double dt[3] = { (tr->a).Dot(no), (tr->b).Dot(no), (tr->c).Dot(no) }; + + bool isPos[3] = {}, isNeg[3] = {}, isOn[3] = {}; + int inc = 0, posc = 0, negc = 0; + for(int i = 0; i < 3; i++) { + if(fabs(dt[i] - d) < LENGTH_EPS) { + isOn[i] = true; + inc++; + } else if(dt[i] > d) { + isPos[i] = true; + posc++; + } else { + isNeg[i] = true; + negc++; + } + } + + if(inc == 3) { + // All vertices on-line; so it's a degenerate triangle, to ignore. + return; + } + + // No split required + if(posc == 0 || negc == 0) { + if(posc > 0) { + InsertTriangleHow(BspClass::POS, tr, m, bsp3); + } else { + InsertTriangleHow(BspClass::NEG, tr, m, bsp3); + } + return; + } + + // The polygon must be split into two pieces, one above, one below. + Vector a, b, c; + + if(posc == 1 && negc == 1 && inc == 1) { + bool bpos; + // Standardize so that a is on the plane + if (isOn[0]) { a = tr->a; b = tr->b; c = tr->c; bpos = isPos[1]; + } else if(isOn[1]) { a = tr->b; b = tr->c; c = tr->a; bpos = isPos[2]; + } else if(isOn[2]) { a = tr->c; b = tr->a; c = tr->b; bpos = isPos[0]; + } else ssassert(false, "Impossible"); + + Vector bPc = IntersectionWith(b, c); + STriangle btri = STriangle::From(tr->meta, a, b, bPc); + STriangle ctri = STriangle::From(tr->meta, c, a, bPc); + + if(bpos) { + InsertTriangleHow(BspClass::POS, &btri, m, bsp3); + InsertTriangleHow(BspClass::NEG, &ctri, m, bsp3); + } else { + InsertTriangleHow(BspClass::POS, &ctri, m, bsp3); + InsertTriangleHow(BspClass::NEG, &btri, m, bsp3); + } + + return; + } + + if(posc == 2 && negc == 1) { + // Standardize so that a is on one side, and b and c are on the other. + if (isNeg[0]) { a = tr->a; b = tr->b; c = tr->c; + } else if(isNeg[1]) { a = tr->b; b = tr->c; c = tr->a; + } else if(isNeg[2]) { a = tr->c; b = tr->a; c = tr->b; + } else ssassert(false, "Impossible"); + + } else if(posc == 1 && negc == 2) { + if (isPos[0]) { a = tr->a; b = tr->b; c = tr->c; + } else if(isPos[1]) { a = tr->b; b = tr->c; c = tr->a; + } else if(isPos[2]) { a = tr->c; b = tr->a; c = tr->b; + } else ssassert(false, "Impossible"); + } else ssassert(false, "Impossible"); + + Vector aPb = IntersectionWith(a, b); + Vector cPa = IntersectionWith(c, a); + + STriangle alone = STriangle::From(tr->meta, a, aPb, cPa); + STriangle quad1 = STriangle::From(tr->meta, aPb, b, c ); + STriangle quad2 = STriangle::From(tr->meta, aPb, c, cPa); + + if(posc == 2 && negc == 1) { + InsertTriangleHow(BspClass::POS, &quad1, m, bsp3); + InsertTriangleHow(BspClass::POS, &quad2, m, bsp3); + InsertTriangleHow(BspClass::NEG, &alone, m, bsp3); + } else { + InsertTriangleHow(BspClass::NEG, &quad1, m, bsp3); + InsertTriangleHow(BspClass::NEG, &quad2, m, bsp3); + InsertTriangleHow(BspClass::POS, &alone, m, bsp3); + } + + return; +} diff --git a/src/clipboard.cpp b/src/clipboard.cpp new file mode 100644 index 0000000..d43ec45 --- /dev/null +++ b/src/clipboard.cpp @@ -0,0 +1,519 @@ +//----------------------------------------------------------------------------- +// The clipboard that gets manipulated when the user selects Edit -> Cut, +// Copy, Paste, etc.; may contain entities only, not constraints. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +void SolveSpaceUI::Clipboard::Clear() { + c.Clear(); + r.Clear(); +} + +bool SolveSpaceUI::Clipboard::ContainsEntity(hEntity he) { + if(he == Entity::NO_ENTITY) + return true; + + ClipboardRequest *cr; + for(cr = r.First(); cr; cr = r.NextAfter(cr)) { + if(cr->oldEnt == he) + return true; + + for(int i = 0; i < MAX_POINTS_IN_ENTITY; i++) { + if(cr->oldPointEnt[i] == he) + return true; + } + } + return false; +} + +hEntity SolveSpaceUI::Clipboard::NewEntityFor(hEntity he) { + if(he == Entity::NO_ENTITY) + return Entity::NO_ENTITY; + + ClipboardRequest *cr; + for(cr = r.First(); cr; cr = r.NextAfter(cr)) { + if(cr->oldEnt == he) + return cr->newReq.entity(0); + + for(int i = 0; i < MAX_POINTS_IN_ENTITY; i++) { + if(cr->oldPointEnt[i] == he) + return cr->newReq.entity(1+i); + } + } + + ssassert(false, "Expected to find entity in some clipboard request"); +} + +void GraphicsWindow::DeleteSelection() { + SK.request.ClearTags(); + SK.constraint.ClearTags(); + List *ls = &(selection); + for(Selection *s = ls->First(); s; s = ls->NextAfter(s)) { + hRequest r = { 0 }; + if(s->entity.v && s->entity.isFromRequest()) { + r = s->entity.request(); + } + if(r.v && !r.IsFromReferences()) { + SK.request.Tag(r, 1); + } + if(s->constraint.v) { + SK.constraint.Tag(s->constraint, 1); + } + } + + SK.constraint.RemoveTagged(); + // Note that this regenerates and clears the selection, to avoid + // lingering references to the just-deleted items. + DeleteTaggedRequests(); +} + +void GraphicsWindow::CopySelection() { + SS.clipboard.Clear(); + + Entity *wrkpl = SK.GetEntity(ActiveWorkplane()); + Entity *wrkpln = SK.GetEntity(wrkpl->normal); + Vector u = wrkpln->NormalU(), + v = wrkpln->NormalV(), + n = wrkpln->NormalN(), + p = SK.GetEntity(wrkpl->point[0])->PointGetNum(); + + List *ls = &(selection); + for(Selection *s = ls->First(); s; s = ls->NextAfter(s)) { + if(!s->entity.v) continue; + // Work only on entities that have requests that will generate them. + Entity *e = SK.GetEntity(s->entity); + bool hasDistance; + Request::Type req; + int pts; + if(!EntReqTable::GetEntityInfo(e->type, e->extraPoints, + &req, &pts, NULL, &hasDistance)) + { + if(!e->h.isFromRequest()) continue; + Request *r = SK.GetRequest(e->h.request()); + if(r->type != Request::Type::DATUM_POINT) continue; + EntReqTable::GetEntityInfo((Entity::Type)0, e->extraPoints, + &req, &pts, NULL, &hasDistance); + } + if(req == Request::Type::WORKPLANE) continue; + + ClipboardRequest cr = {}; + cr.type = req; + cr.extraPoints = e->extraPoints; + cr.style = e->style; + cr.str = e->str; + cr.font = e->font; + cr.file = e->file; + cr.construction = e->construction; + {for(int i = 0; i < pts; i++) { + Vector pt; + if(req == Request::Type::DATUM_POINT) { + pt = e->PointGetNum(); + } else { + pt = SK.GetEntity(e->point[i])->PointGetNum(); + } + pt = pt.Minus(p); + pt = pt.DotInToCsys(u, v, n); + cr.point[i] = pt; + }} + if(hasDistance) { + cr.distance = SK.GetEntity(e->distance)->DistanceGetNum(); + } + + cr.oldEnt = e->h; + for(int i = 0; i < pts; i++) { + cr.oldPointEnt[i] = e->point[i]; + } + + SS.clipboard.r.Add(&cr); + } + + for(Selection *s = ls->First(); s; s = ls->NextAfter(s)) { + if(!s->constraint.v) continue; + + Constraint *c = SK.GetConstraint(s->constraint); + if(c->type == Constraint::Type::COMMENT) { + SS.clipboard.c.Add(c); + } + } + + Constraint *c; + for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) { + if(!SS.clipboard.ContainsEntity(c->ptA) || + !SS.clipboard.ContainsEntity(c->ptB) || + !SS.clipboard.ContainsEntity(c->entityA) || + !SS.clipboard.ContainsEntity(c->entityB) || + !SS.clipboard.ContainsEntity(c->entityC) || + !SS.clipboard.ContainsEntity(c->entityD) || + c->type == Constraint::Type::COMMENT) { + continue; + } + SS.clipboard.c.Add(c); + } +} + +void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) { + Entity *wrkpl = SK.GetEntity(ActiveWorkplane()); + Entity *wrkpln = SK.GetEntity(wrkpl->normal); + Vector u = wrkpln->NormalU(), + v = wrkpln->NormalV(), + n = wrkpln->NormalN(), + p = SK.GetEntity(wrkpl->point[0])->PointGetNum(); + + // For arcs, reflection involves swapping the endpoints, or otherwise + // the arc gets inverted. + auto mapPoint = [scale](hEntity he) { + if(he.v == 0) return he; + + if(scale < 0) { + hRequest hr = he.request(); + Request *r = SK.GetRequest(hr); + if(r->type == Request::Type::ARC_OF_CIRCLE) { + if(he == hr.entity(2)) { + return hr.entity(3); + } else if(he == hr.entity(3)) { + return hr.entity(2); + } + } + } + return he; + }; + + ClipboardRequest *cr; + for(cr = SS.clipboard.r.First(); cr; cr = SS.clipboard.r.NextAfter(cr)) { + hRequest hr = AddRequest(cr->type, /*rememberForUndo=*/false); + Request *r = SK.GetRequest(hr); + r->extraPoints = cr->extraPoints; + r->style = cr->style; + r->str = cr->str; + r->font = cr->font; + r->file = cr->file; + r->construction = cr->construction; + // Need to regen to get the right number of points, if extraPoints + // changed. + SS.GenerateAll(SolveSpaceUI::Generate::REGEN); + SS.MarkGroupDirty(r->group); + bool hasDistance; + int i, pts; + EntReqTable::GetRequestInfo(r->type, r->extraPoints, + NULL, &pts, NULL, &hasDistance); + for(i = 0; i < pts; i++) { + Vector pt = cr->point[i]; + // We need the reflection to occur within the workplane; it may + // otherwise correspond to just a rotation as projected. + if(scale < 0) { + pt.x *= -1; + } + // Likewise the scale, which could otherwise take us out of the + // workplane. + pt = pt.ScaledBy(fabs(scale)); + pt = pt.ScaleOutOfCsys(u, v, Vector::From(0, 0, 0)); + pt = pt.Plus(p); + pt = pt.RotatedAbout(n, theta); + pt = pt.Plus(trans); + int j = (r->type == Request::Type::DATUM_POINT) ? i : i + 1; + SK.GetEntity(mapPoint(hr.entity(j)))->PointForceTo(pt); + } + if(hasDistance) { + SK.GetEntity(hr.entity(64))->DistanceForceTo( + cr->distance*fabs(scale)); + } + + cr->newReq = hr; + MakeSelected(hr.entity(0)); + for(i = 0; i < pts; i++) { + int j = (r->type == Request::Type::DATUM_POINT) ? i : i + 1; + MakeSelected(hr.entity(j)); + } + } + Constraint *cc; + for(cc = SS.clipboard.c.First(); cc; cc = SS.clipboard.c.NextAfter(cc)) { + Constraint c = {}; + c.group = SS.GW.activeGroup; + c.workplane = SS.GW.ActiveWorkplane(); + c.type = cc->type; + c.valA = cc->valA; + c.ptA = SS.clipboard.NewEntityFor(mapPoint(cc->ptA)); + c.ptB = SS.clipboard.NewEntityFor(mapPoint(cc->ptB)); + c.entityA = SS.clipboard.NewEntityFor(cc->entityA); + c.entityB = SS.clipboard.NewEntityFor(cc->entityB); + c.entityC = SS.clipboard.NewEntityFor(cc->entityC); + c.entityD = SS.clipboard.NewEntityFor(cc->entityD); + c.other = cc->other; + c.other2 = cc->other2; + c.reference = cc->reference; + c.disp = cc->disp; + c.comment = cc->comment; + bool dontAddConstraint = false; + switch(c.type) { + case Constraint::Type::COMMENT: + c.disp.offset = c.disp.offset.Plus(trans); + break; + case Constraint::Type::PT_PT_DISTANCE: + case Constraint::Type::PT_LINE_DISTANCE: + case Constraint::Type::PROJ_PT_DISTANCE: + case Constraint::Type::DIAMETER: + c.valA *= fabs(scale); + break; + case Constraint::Type::ARC_LINE_TANGENT: { + Entity *line = SK.GetEntity(c.entityB), + *arc = SK.GetEntity(c.entityA); + if(line->type == Entity::Type::ARC_OF_CIRCLE) { + swap(line, arc); + } + Constraint::ConstrainArcLineTangent(&c, line, arc); + break; + } + case Constraint::Type::CUBIC_LINE_TANGENT: { + Entity *line = SK.GetEntity(c.entityB), + *cubic = SK.GetEntity(c.entityA); + if(line->type == Entity::Type::CUBIC) { + swap(line, cubic); + } + Constraint::ConstrainCubicLineTangent(&c, line, cubic); + break; + } + case Constraint::Type::CURVE_CURVE_TANGENT: { + Entity *eA = SK.GetEntity(c.entityA), + *eB = SK.GetEntity(c.entityB); + Constraint::ConstrainCurveCurveTangent(&c, eA, eB); + break; + } + case Constraint::Type::HORIZONTAL: + case Constraint::Type::VERTICAL: + // When rotating 90 or 270 degrees, swap the vertical / horizontal constaints + if (EXACT(fmod(theta + (PI/2), PI) == 0)) { + if(c.type == Constraint::Type::HORIZONTAL) { + c.type = Constraint::Type::VERTICAL; + } else { + c.type = Constraint::Type::HORIZONTAL; + } + } else if (fmod(theta, PI/2) != 0) { + dontAddConstraint = true; + } + break; + default: + break; + } + if (!dontAddConstraint) { + hConstraint hc = Constraint::AddConstraint(&c, /*rememberForUndo=*/false); + if(c.type == Constraint::Type::COMMENT) { + MakeSelected(hc); + } + } + } +} + +void GraphicsWindow::MenuClipboard(Command id) { + if(id != Command::DELETE && !SS.GW.LockedInWorkplane()) { + Error(_("Cut, paste, and copy work only in a workplane.\n\n" + "Activate one with Sketch -> In Workplane.")); + return; + } + + switch(id) { + case Command::PASTE: { + SS.UndoRemember(); + Vector trans = SS.GW.projRight.ScaledBy(80/SS.GW.scale).Plus( + SS.GW.projUp .ScaledBy(40/SS.GW.scale)); + SS.GW.ClearSelection(); + SS.GW.PasteClipboard(trans, 0, 1); + break; + } + + case Command::PASTE_TRANSFORM: { + if(SS.clipboard.r.IsEmpty()) { + Error(_("Clipboard is empty; nothing to paste.")); + break; + } + + Entity *wrkpl = SK.GetEntity(SS.GW.ActiveWorkplane()); + Vector p = SK.GetEntity(wrkpl->point[0])->PointGetNum(); + SS.TW.shown.paste.times = 1; + SS.TW.shown.paste.trans = Vector::From(0, 0, 0); + SS.TW.shown.paste.theta = 0; + SS.TW.shown.paste.origin = p; + SS.TW.shown.paste.scale = 1; + SS.TW.GoToScreen(TextWindow::Screen::PASTE_TRANSFORMED); + SS.GW.ForceTextWindowShown(); + SS.ScheduleShowTW(); + break; + } + + case Command::COPY: + SS.GW.CopySelection(); + SS.GW.ClearSelection(); + break; + + case Command::CUT: + SS.UndoRemember(); + SS.GW.CopySelection(); + SS.GW.DeleteSelection(); + break; + + case Command::DELETE: + SS.UndoRemember(); + SS.GW.DeleteSelection(); + break; + + default: ssassert(false, "Unexpected menu ID"); + } +} + +bool TextWindow::EditControlDoneForPaste(const std::string &s) { + Expr *e; + switch(edit.meaning) { + case Edit::PASTE_TIMES_REPEATED: { + e = Expr::From(s, /*popUpError=*/true); + if(!e) break; + int v = (int)e->Eval(); + if(v > 0) { + shown.paste.times = v; + } else { + Error(_("Number of copies to paste must be at least one.")); + } + break; + } + case Edit::PASTE_ANGLE: + e = Expr::From(s, /*popUpError=*/true); + if(!e) break; + shown.paste.theta = WRAP_SYMMETRIC((e->Eval())*PI/180, 2*PI); + break; + + case Edit::PASTE_SCALE: { + e = Expr::From(s, /*popUpError=*/true); + double v = e->Eval(); + if(fabs(v) > 1e-6) { + shown.paste.scale = shown.paste.scale < 0 ? -v : v; + } else { + Error(_("Scale cannot be zero.")); + } + break; + } + + default: + return false; + } + return true; +} + +void TextWindow::ScreenChangePasteTransformed(int link, uint32_t v) { + switch(link) { + case 't': + SS.TW.ShowEditControl(13, ssprintf("%d", SS.TW.shown.paste.times)); + SS.TW.edit.meaning = Edit::PASTE_TIMES_REPEATED; + break; + + case 'r': + SS.TW.ShowEditControl(13, ssprintf("%.3f", SS.TW.shown.paste.theta*180/PI)); + SS.TW.edit.meaning = Edit::PASTE_ANGLE; + break; + + case 's': + SS.TW.ShowEditControl(13, ssprintf("%.3f", fabs(SS.TW.shown.paste.scale))); + SS.TW.edit.meaning = Edit::PASTE_SCALE; + break; + + case 'f': + SS.TW.shown.paste.scale *= -1; + break; + } +} + +void TextWindow::ScreenPasteTransformed(int link, uint32_t v) { + SS.GW.GroupSelection(); + switch(link) { + case 'o': + if(SS.GW.gs.points == 1 && SS.GW.gs.n == 1) { + Entity *e = SK.GetEntity(SS.GW.gs.point[0]); + SS.TW.shown.paste.origin = e->PointGetNum(); + } else { + Error(_("Select one point to define origin of rotation.")); + } + SS.GW.ClearSelection(); + break; + + case 't': + if(SS.GW.gs.points == 2 && SS.GW.gs.n == 2) { + Entity *pa = SK.GetEntity(SS.GW.gs.point[0]), + *pb = SK.GetEntity(SS.GW.gs.point[1]); + SS.TW.shown.paste.trans = + (pb->PointGetNum()).Minus(pa->PointGetNum()); + } else { + Error(_("Select two points to define translation vector.")); + } + SS.GW.ClearSelection(); + break; + + case 'g': { + if(fabs(SS.TW.shown.paste.theta) < LENGTH_EPS && + SS.TW.shown.paste.trans.Magnitude() < LENGTH_EPS && + SS.TW.shown.paste.times != 1) + { + Message(_("Transformation is identity. So all copies will be " + "exactly on top of each other.")); + } + if(SS.TW.shown.paste.times*SS.clipboard.r.n > 100) { + Error(_("Too many items to paste; split this into smaller " + "pastes.")); + break; + } + if(!SS.GW.LockedInWorkplane()) { + Error(_("No workplane active.")); + break; + } + Entity *wrkpl = SK.GetEntity(SS.GW.ActiveWorkplane()); + Entity *wrkpln = SK.GetEntity(wrkpl->normal); + Vector wn = wrkpln->NormalN(); + SS.UndoRemember(); + SS.GW.ClearSelection(); + for(int i = 0; i < SS.TW.shown.paste.times; i++) { + Vector trans = SS.TW.shown.paste.trans.ScaledBy(i+1), + origin = SS.TW.shown.paste.origin; + double theta = SS.TW.shown.paste.theta*(i+1); + // desired transformation is Q*(p - o) + o + t = + // Q*p - Q*o + o + t = Q*p + (t + o - Q*o) + Vector t = trans.Plus( + origin).Minus( + origin.RotatedAbout(wn, theta)); + + SS.GW.PasteClipboard(t, theta, SS.TW.shown.paste.scale); + } + SS.TW.GoToScreen(Screen::LIST_OF_GROUPS); + SS.ScheduleShowTW(); + break; + } + } +} + +void TextWindow::ShowPasteTransformed() { + Printf(true, "%FtPASTE TRANSFORMED%E"); + Printf(true, "%Ba %Ftrepeat%E %d time%s %Fl%Lt%f[change]%E", + shown.paste.times, (shown.paste.times == 1) ? "" : "s", + &ScreenChangePasteTransformed); + Printf(false, "%Bd %Ftrotate%E %@ degrees %Fl%Lr%f[change]%E", + shown.paste.theta*180/PI, + &ScreenChangePasteTransformed); + Printf(false, "%Ba %Ftabout pt%E (%s, %s, %s) %Fl%Lo%f[use selected]%E", + SS.MmToString(shown.paste.origin.x).c_str(), + SS.MmToString(shown.paste.origin.y).c_str(), + SS.MmToString(shown.paste.origin.z).c_str(), + &ScreenPasteTransformed); + Printf(false, "%Bd %Fttranslate%E (%s, %s, %s) %Fl%Lt%f[use selected]%E", + SS.MmToString(shown.paste.trans.x).c_str(), + SS.MmToString(shown.paste.trans.y).c_str(), + SS.MmToString(shown.paste.trans.z).c_str(), + &ScreenPasteTransformed); + Printf(false, "%Ba %Ftscale%E %@ %Fl%Ls%f[change]%E", + fabs(shown.paste.scale), + &ScreenChangePasteTransformed); + Printf(false, "%Ba %Ftmirror%E %Fd%Lf%f%s flip%E", + &ScreenChangePasteTransformed, + shown.paste.scale < 0 ? CHECK_TRUE : CHECK_FALSE); + + Printf(true, " %Fl%Lg%fpaste transformed now%E", &ScreenPasteTransformed); + + Printf(true, "(or %Fl%Ll%fcancel operation%E)", &ScreenHome); +} + diff --git a/src/config.h.in b/src/config.h.in new file mode 100644 index 0000000..144c46d --- /dev/null +++ b/src/config.h.in @@ -0,0 +1,18 @@ +#ifndef SOLVESPACE_CONFIG_H +#define SOLVESPACE_CONFIG_H + +#define PACKAGE_VERSION "@solvespace_VERSION_MAJOR@.@solvespace_VERSION_MINOR@~@solvespace_GIT_HASH@" + +/* Non-OS X *nix only */ +#define UNIX_DATADIR "@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_DATAROOTDIR@/solvespace" + +/* Do we have the si library on win32, or libspnav on *nix? */ +#cmakedefine HAVE_SPACEWARE + +/* What OpenGL version do we use? */ +#define HAVE_OPENGL @OPENGL@ + +/* If we use GTK, can we use the native file chooser? */ +#cmakedefine HAVE_GTK_FILECHOOSERNATIVE + +#endif diff --git a/src/confscreen.cpp b/src/confscreen.cpp new file mode 100644 index 0000000..c7e2815 --- /dev/null +++ b/src/confscreen.cpp @@ -0,0 +1,578 @@ +//----------------------------------------------------------------------------- +// For the configuration screen, setup items that are not specific to the +// file being edited right now. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" +#if defined(_OPENMP) +#include +#endif + +void TextWindow::ScreenChangeLightDirection(int link, uint32_t v) { + SS.TW.ShowEditControl(8, ssprintf("%.2f, %.2f, %.2f", CO(SS.lightDir[v]))); + SS.TW.edit.meaning = Edit::LIGHT_DIRECTION; + SS.TW.edit.i = v; +} + +void TextWindow::ScreenChangeLightIntensity(int link, uint32_t v) { + SS.TW.ShowEditControl(31, ssprintf("%.2f", SS.lightIntensity[v])); + SS.TW.edit.meaning = Edit::LIGHT_INTENSITY; + SS.TW.edit.i = v; +} + +void TextWindow::ScreenChangeLightAmbient(int link, uint32_t v) { + SS.TW.ShowEditControl(31, ssprintf("%.2f", SS.ambientIntensity)); + SS.TW.edit.meaning = Edit::LIGHT_AMBIENT; + SS.TW.edit.i = 0; +} + +void TextWindow::ScreenChangeColor(int link, uint32_t v) { + SS.TW.ShowEditControlWithColorPicker(13, SS.modelColor[v]); + + SS.TW.edit.meaning = Edit::COLOR; + SS.TW.edit.i = v; +} + +void TextWindow::ScreenChangeChordTolerance(int link, uint32_t v) { + SS.TW.ShowEditControl(3, ssprintf("%lg", SS.chordTol)); + SS.TW.edit.meaning = Edit::CHORD_TOLERANCE; + SS.TW.edit.i = 0; +} + +void TextWindow::ScreenChangeMaxSegments(int link, uint32_t v) { + SS.TW.ShowEditControl(3, ssprintf("%d", SS.maxSegments)); + SS.TW.edit.meaning = Edit::MAX_SEGMENTS; + SS.TW.edit.i = 0; +} + +void TextWindow::ScreenChangeExportChordTolerance(int link, uint32_t v) { + SS.TW.ShowEditControl(3, ssprintf("%lg", SS.exportChordTol)); + SS.TW.edit.meaning = Edit::CHORD_TOLERANCE; + SS.TW.edit.i = 1; +} + +void TextWindow::ScreenChangeExportMaxSegments(int link, uint32_t v) { + SS.TW.ShowEditControl(3, ssprintf("%d", SS.exportMaxSegments)); + SS.TW.edit.meaning = Edit::MAX_SEGMENTS; + SS.TW.edit.i = 1; +} + +void TextWindow::ScreenChangeCameraTangent(int link, uint32_t v) { + SS.TW.ShowEditControl(3, ssprintf("%.3f", 1000*SS.cameraTangent)); + SS.TW.edit.meaning = Edit::CAMERA_TANGENT; +} + +void TextWindow::ScreenChangeGridSpacing(int link, uint32_t v) { + SS.TW.ShowEditControl(3, SS.MmToString(SS.gridSpacing)); + SS.TW.edit.meaning = Edit::GRID_SPACING; +} + +void TextWindow::ScreenChangeDigitsAfterDecimal(int link, uint32_t v) { + SS.TW.ShowEditControl(14, ssprintf("%d", SS.UnitDigitsAfterDecimal())); + SS.TW.edit.meaning = Edit::DIGITS_AFTER_DECIMAL; +} + +void TextWindow::ScreenChangeDigitsAfterDecimalDegree(int link, uint32_t v) { + SS.TW.ShowEditControl(14, ssprintf("%d", SS.afterDecimalDegree)); + SS.TW.edit.meaning = Edit::DIGITS_AFTER_DECIMAL_DEGREE; +} + +void TextWindow::ScreenChangeUseSIPrefixes(int link, uint32_t v) { + SS.useSIPrefixes = !SS.useSIPrefixes; + SS.GW.Invalidate(); +} + +void TextWindow::ScreenChangeExportScale(int link, uint32_t v) { + SS.TW.ShowEditControl(5, ssprintf("%.3f", (double)SS.exportScale)); + SS.TW.edit.meaning = Edit::EXPORT_SCALE; +} + +void TextWindow::ScreenChangeExportOffset(int link, uint32_t v) { + SS.TW.ShowEditControl(3, SS.MmToString(SS.exportOffset)); + SS.TW.edit.meaning = Edit::EXPORT_OFFSET; +} + +void TextWindow::ScreenChangeFixExportColors(int link, uint32_t v) { + SS.fixExportColors = !SS.fixExportColors; +} + +void TextWindow::ScreenChangeExportBackgroundColor(int link, uint32_t v) { + SS.exportBackgroundColor = !SS.exportBackgroundColor; +} + +void TextWindow::ScreenChangeBackFaces(int link, uint32_t v) { + SS.drawBackFaces = !SS.drawBackFaces; + SS.GW.Invalidate(/*clearPersistent=*/true); +} + +void TextWindow::ScreenChangeTurntableNav(int link, uint32_t v) { + SS.turntableNav = !SS.turntableNav; + if(SS.turntableNav) { + // If turntable nav is being turned on, align view so Z is vertical + SS.GW.AnimateOnto(Quaternion::From(Vector::From(-1, 0, 0), Vector::From(0, 0, 1)), + SS.GW.offset); + } +} + +void TextWindow::ScreenChangeImmediatelyEditDimension(int link, uint32_t v) { + SS.immediatelyEditDimension = !SS.immediatelyEditDimension; + SS.GW.Invalidate(/*clearPersistent=*/true); +} + +void TextWindow::ScreenChangeShowContourAreas(int link, uint32_t v) { + SS.showContourAreas = !SS.showContourAreas; + SS.GW.Invalidate(); +} + +void TextWindow::ScreenChangeCheckClosedContour(int link, uint32_t v) { + SS.checkClosedContour = !SS.checkClosedContour; + SS.GW.Invalidate(); +} + +void TextWindow::ScreenChangeAutomaticLineConstraints(int link, uint32_t v) { + SS.automaticLineConstraints = !SS.automaticLineConstraints; + SS.GW.Invalidate(); +} + +void TextWindow::ScreenChangeShadedTriangles(int link, uint32_t v) { + SS.exportShadedTriangles = !SS.exportShadedTriangles; + SS.GW.Invalidate(); +} + +void TextWindow::ScreenChangePwlCurves(int link, uint32_t v) { + SS.exportPwlCurves = !SS.exportPwlCurves; + SS.GW.Invalidate(); +} + +void TextWindow::ScreenChangeCanvasSizeAuto(int link, uint32_t v) { + if(link == 't') { + SS.exportCanvasSizeAuto = true; + } else { + SS.exportCanvasSizeAuto = false; + } + SS.GW.Invalidate(); +} + +void TextWindow::ScreenChangeCanvasSize(int link, uint32_t v) { + double d; + switch(v) { + case 0: d = SS.exportMargin.left; break; + case 1: d = SS.exportMargin.right; break; + case 2: d = SS.exportMargin.bottom; break; + case 3: d = SS.exportMargin.top; break; + + case 10: d = SS.exportCanvas.width; break; + case 11: d = SS.exportCanvas.height; break; + case 12: d = SS.exportCanvas.dx; break; + case 13: d = SS.exportCanvas.dy; break; + + default: return; + } + int col = 13; + if(v < 10) col = 11; + SS.TW.ShowEditControl(col, SS.MmToString(d)); + SS.TW.edit.meaning = Edit::CANVAS_SIZE; + SS.TW.edit.i = v; +} + +void TextWindow::ScreenChangeGCodeParameter(int link, uint32_t v) { + std::string buf; + switch(link) { + case 'd': + SS.TW.edit.meaning = Edit::G_CODE_DEPTH; + buf += SS.MmToString(SS.gCode.depth); + break; + + case 's': + SS.TW.edit.meaning = Edit::G_CODE_PASSES; + buf += std::to_string(SS.gCode.passes); + break; + + case 'F': + SS.TW.edit.meaning = Edit::G_CODE_FEED; + buf += SS.MmToString(SS.gCode.feed); + break; + + case 'P': + SS.TW.edit.meaning = Edit::G_CODE_PLUNGE_FEED; + buf += SS.MmToString(SS.gCode.plungeFeed); + break; + } + SS.TW.ShowEditControl(14, buf); +} + +void TextWindow::ScreenChangeAutosaveInterval(int link, uint32_t v) { + SS.TW.ShowEditControl(3, std::to_string(SS.autosaveInterval)); + SS.TW.edit.meaning = Edit::AUTOSAVE_INTERVAL; +} + +void TextWindow::ScreenChangeFindConstraintTimeout(int link, uint32_t v) { + SS.TW.ShowEditControl(3, std::to_string(SS.timeoutRedundantConstr)); + SS.TW.edit.meaning = Edit::FIND_CONSTRAINT_TIMEOUT; +} + +void TextWindow::ShowConfiguration() { + int i; + Printf(true, "%Ft user color (r, g, b)"); + + for(i = 0; i < SS.MODEL_COLORS; i++) { + Printf(false, "%Bp #%d: %Bz %Bp (%@, %@, %@) %f%D%Ll%Fl[change]%E", + (i & 1) ? 'd' : 'a', + i, &SS.modelColor[i], + (i & 1) ? 'd' : 'a', + SS.modelColor[i].redF(), + SS.modelColor[i].greenF(), + SS.modelColor[i].blueF(), + &ScreenChangeColor, i); + } + + Printf(false, ""); + Printf(false, "%Ft light direction intensity"); + for(i = 0; i < 2; i++) { + Printf(false, "%Bp #%d (%2,%2,%2)%Fl%D%f%Ll[c]%E " + "%2 %Fl%D%f%Ll[c]%E", + (i & 1) ? 'd' : 'a', i, + CO(SS.lightDir[i]), i, &ScreenChangeLightDirection, + SS.lightIntensity[i], i, &ScreenChangeLightIntensity); + } + Printf(false, "%Bp ambient lighting " + "%2 %Fl%D%f%Ll[c]%E", + (i & 1) ? 'd' : 'a', i, + SS.ambientIntensity, &ScreenChangeLightAmbient); + + Printf(false, ""); + Printf(false, "%Ft chord tolerance (in percents)%E"); + Printf(false, "%Ba %@ %% %Fl%Ll%f%D[change]%E; %@ mm, %d triangles", + SS.chordTol, + &ScreenChangeChordTolerance, 0, SS.chordTolCalculated, + SK.GetGroup(SS.GW.activeGroup)->displayMesh.l.n); + Printf(false, "%Ft max piecewise linear segments%E"); + Printf(false, "%Ba %d %Fl%Ll%f[change]%E", + SS.maxSegments, + &ScreenChangeMaxSegments); + + Printf(false, ""); + Printf(false, "%Ft export chord tolerance (in mm)%E"); + Printf(false, "%Ba %@ %Fl%Ll%f%D[change]%E", + SS.exportChordTol, + &ScreenChangeExportChordTolerance, 0); + Printf(false, "%Ft export max piecewise linear segments%E"); + Printf(false, "%Ba %d %Fl%Ll%f[change]%E", + SS.exportMaxSegments, + &ScreenChangeExportMaxSegments); + + Printf(false, ""); + Printf(false, "%Ft perspective factor (0 for parallel)%E"); + Printf(false, "%Ba %# %Fl%Ll%f%D[change]%E", + SS.cameraTangent*1000, + &ScreenChangeCameraTangent, 0); + Printf(false, "%Ft snap grid spacing%E"); + Printf(false, "%Ba %s %Fl%Ll%f%D[change]%E", + SS.MmToString(SS.gridSpacing).c_str(), + &ScreenChangeGridSpacing, 0); + + Printf(false, ""); + Printf(false, "%Ft digits after decimal point to show%E"); + Printf(false, "%Ba%Ft distances: %Fd%d %Fl%Ll%f%D[change]%E (e.g. '%s')", + SS.UnitDigitsAfterDecimal(), + &ScreenChangeDigitsAfterDecimal, 0, + SS.MmToString(SS.StringToMm("1.23456789")).c_str()); + Printf(false, "%Bd%Ft angles: %Fd%d %Fl%Ll%f%D[change]%E (e.g. '%s')", + SS.afterDecimalDegree, + &ScreenChangeDigitsAfterDecimalDegree, 0, + SS.DegreeToString(1.23456789).c_str()); + Printf(false, " %Fd%f%Ll%s use SI prefixes for distances%E", + &ScreenChangeUseSIPrefixes, + SS.useSIPrefixes ? CHECK_TRUE : CHECK_FALSE); + + Printf(false, ""); + Printf(false, "%Ft export scale factor (1:1=mm, 1:25.4=inch)"); + Printf(false, "%Ba 1:%# %Fl%Ll%f%D[change]%E", + (double)SS.exportScale, + &ScreenChangeExportScale, 0); + Printf(false, "%Ft cutter radius offset (0=no offset) "); + Printf(false, "%Ba %s %Fl%Ll%f%D[change]%E", + SS.MmToString(SS.exportOffset).c_str(), + &ScreenChangeExportOffset, 0); + + Printf(false, ""); + Printf(false, " %Fd%f%Ll%s export shaded 2d triangles%E", + &ScreenChangeShadedTriangles, + SS.exportShadedTriangles ? CHECK_TRUE : CHECK_FALSE); + if(fabs(SS.exportOffset) > LENGTH_EPS) { + Printf(false, " %Fd%s curves as piecewise linear%E " + "(since cutter radius is not zero)", CHECK_TRUE); + } else { + Printf(false, " %Fd%f%Ll%s export curves as piecewise linear%E", + &ScreenChangePwlCurves, + SS.exportPwlCurves ? CHECK_TRUE : CHECK_FALSE); + } + Printf(false, " %Fd%f%Ll%s fix white exported lines%E", + &ScreenChangeFixExportColors, + SS.fixExportColors ? CHECK_TRUE : CHECK_FALSE); + Printf(false, " %Fd%f%Ll%s export background color%E", + &ScreenChangeExportBackgroundColor, + SS.exportBackgroundColor ? CHECK_TRUE : CHECK_FALSE); + + Printf(false, ""); + Printf(false, "%Ft export canvas size: " + "%f%Fd%Lf%s fixed%E " + "%f%Fd%Lt%s auto%E", + &ScreenChangeCanvasSizeAuto, + !SS.exportCanvasSizeAuto ? RADIO_TRUE : RADIO_FALSE, + &ScreenChangeCanvasSizeAuto, + SS.exportCanvasSizeAuto ? RADIO_TRUE : RADIO_FALSE); + + if(SS.exportCanvasSizeAuto) { + Printf(false, "%Ft (by margins around exported geometry)"); + Printf(false, "%Ba%Ft left: %Fd%s %Fl%Ll%f%D[change]%E", + SS.MmToString(SS.exportMargin.left).c_str(), &ScreenChangeCanvasSize, 0); + Printf(false, "%Bd%Ft right: %Fd%s %Fl%Ll%f%D[change]%E", + SS.MmToString(SS.exportMargin.right).c_str(), &ScreenChangeCanvasSize, 1); + Printf(false, "%Ba%Ft bottom: %Fd%s %Fl%Ll%f%D[change]%E", + SS.MmToString(SS.exportMargin.bottom).c_str(), &ScreenChangeCanvasSize, 2); + Printf(false, "%Bd%Ft top: %Fd%s %Fl%Ll%f%D[change]%E", + SS.MmToString(SS.exportMargin.top).c_str(), &ScreenChangeCanvasSize, 3); + } else { + Printf(false, "%Ft (by absolute dimensions and offsets)"); + Printf(false, "%Ba%Ft width: %Fd%s %Fl%Ll%f%D[change]%E", + SS.MmToString(SS.exportCanvas.width).c_str(), &ScreenChangeCanvasSize, 10); + Printf(false, "%Bd%Ft height: %Fd%s %Fl%Ll%f%D[change]%E", + SS.MmToString(SS.exportCanvas.height).c_str(), &ScreenChangeCanvasSize, 11); + Printf(false, "%Ba%Ft offset x: %Fd%s %Fl%Ll%f%D[change]%E", + SS.MmToString(SS.exportCanvas.dx).c_str(), &ScreenChangeCanvasSize, 12); + Printf(false, "%Bd%Ft offset y: %Fd%s %Fl%Ll%f%D[change]%E", + SS.MmToString(SS.exportCanvas.dy).c_str(), &ScreenChangeCanvasSize, 13); + } + + Printf(false, ""); + Printf(false, "%Ft exported g code parameters"); + Printf(false, "%Ba%Ft depth: %Fd%s %Fl%Ld%f[change]%E", + SS.MmToString(SS.gCode.depth).c_str(), &ScreenChangeGCodeParameter); + Printf(false, "%Bd%Ft passes: %Fd%d %Fl%Ls%f[change]%E", + SS.gCode.passes, &ScreenChangeGCodeParameter); + Printf(false, "%Ba%Ft feed: %Fd%s %Fl%LF%f[change]%E", + SS.MmToString(SS.gCode.feed).c_str(), &ScreenChangeGCodeParameter); + Printf(false, "%Bd%Ft plunge fd: %Fd%s %Fl%LP%f[change]%E", + SS.MmToString(SS.gCode.plungeFeed).c_str(), &ScreenChangeGCodeParameter); + + Printf(false, ""); + Printf(false, " %Fd%f%Ll%s draw triangle back faces in red%E", + &ScreenChangeBackFaces, + SS.drawBackFaces ? CHECK_TRUE : CHECK_FALSE); + Printf(false, " %Fd%f%Ll%s check sketch for closed contour%E", + &ScreenChangeCheckClosedContour, + SS.checkClosedContour ? CHECK_TRUE : CHECK_FALSE); + Printf(false, " %Fd%f%Ll%s show areas of closed contours%E", + &ScreenChangeShowContourAreas, + SS.showContourAreas ? CHECK_TRUE : CHECK_FALSE); + Printf(false, " %Fd%f%Ll%s enable automatic line constraints%E", + &ScreenChangeAutomaticLineConstraints, + SS.automaticLineConstraints ? CHECK_TRUE : CHECK_FALSE); + Printf(false, " %Fd%f%Ll%s use turntable mouse navigation%E", &ScreenChangeTurntableNav, + SS.turntableNav ? CHECK_TRUE : CHECK_FALSE); + Printf(false, " %Fd%f%Ll%s edit newly added dimensions%E", + &ScreenChangeImmediatelyEditDimension, + SS.immediatelyEditDimension ? CHECK_TRUE : CHECK_FALSE); + Printf(false, ""); + Printf(false, "%Ft autosave interval (in minutes)%E"); + Printf(false, "%Ba %d %Fl%Ll%f[change]%E", + SS.autosaveInterval, &ScreenChangeAutosaveInterval); + Printf(false, ""); + Printf(false, "%Ft redundant constraint timeout (in ms)%E"); + Printf(false, "%Ba %d %Fl%Ll%f[change]%E", + SS.timeoutRedundantConstr, &ScreenChangeFindConstraintTimeout); + + if(canvas) { + const char *gl_vendor, *gl_renderer, *gl_version; + canvas->GetIdent(&gl_vendor, &gl_renderer, &gl_version); + Printf(false, ""); + Printf(false, " %Ftgl vendor %E%s", gl_vendor); + Printf(false, " %Ft renderer %E%s", gl_renderer); + Printf(false, " %Ft version %E%s", gl_version); + } + + #if defined(_OPENMP) + Printf(false, " %FtOpenMP enabled"); + Printf(false, " %Ft threads %E%d", omp_get_max_threads()); + #endif +} + +bool TextWindow::EditControlDoneForConfiguration(const std::string &s) { + switch(edit.meaning) { + case Edit::LIGHT_INTENSITY: + SS.lightIntensity[edit.i] = min(1.0, max(0.0, atof(s.c_str()))); + SS.GW.Invalidate(); + break; + case Edit::LIGHT_AMBIENT: + SS.ambientIntensity = min(1.0, max(0.0, atof(s.c_str()))); + SS.GW.Invalidate(); + break; + case Edit::LIGHT_DIRECTION: { + double x, y, z; + if(sscanf(s.c_str(), "%lf, %lf, %lf", &x, &y, &z)==3) { + SS.lightDir[edit.i] = Vector::From(x, y, z); + SS.GW.Invalidate(); + } else { + Error(_("Bad format: specify coordinates as x, y, z")); + } + break; + } + case Edit::COLOR: { + Vector rgb; + if(sscanf(s.c_str(), "%lf, %lf, %lf", &rgb.x, &rgb.y, &rgb.z)==3) { + rgb = rgb.ClampWithin(0, 1); + SS.modelColor[edit.i] = RGBf(rgb.x, rgb.y, rgb.z); + } else { + Error(_("Bad format: specify color as r, g, b")); + } + break; + } + case Edit::CHORD_TOLERANCE: { + if(edit.i == 0) { + SS.chordTol = max(0.0, atof(s.c_str())); + SS.GenerateAll(SolveSpaceUI::Generate::ALL); + } else { + SS.exportChordTol = max(0.0, atof(s.c_str())); + } + break; + } + case Edit::MAX_SEGMENTS: { + if(edit.i == 0) { + SS.maxSegments = min(1000, max(7, atoi(s.c_str()))); + SS.GenerateAll(SolveSpaceUI::Generate::ALL); + } else { + SS.exportMaxSegments = min(1000, max(7, atoi(s.c_str()))); + } + break; + } + case Edit::CAMERA_TANGENT: { + SS.cameraTangent = (min(2.0, max(0.0, atof(s.c_str()))))/1000.0; + SS.GW.Invalidate(); + if(!SS.usePerspectiveProj) { + Message(_("The perspective factor will have no effect until you " + "enable View -> Use Perspective Projection.")); + } + break; + } + case Edit::GRID_SPACING: { + SS.gridSpacing = (float)min(1e4, max(1e-3, SS.StringToMm(s))); + SS.GW.Invalidate(); + break; + } + case Edit::DIGITS_AFTER_DECIMAL: { + int v = atoi(s.c_str()); + if(v < 0 || v > 8) { + Error(_("Specify between 0 and %d digits after the decimal."), 8); + } else { + SS.SetUnitDigitsAfterDecimal(v); + SS.GW.Invalidate(); + } + break; + } + case Edit::DIGITS_AFTER_DECIMAL_DEGREE: { + int v = atoi(s.c_str()); + if(v < 0 || v > 4) { + Error(_("Specify between 0 and %d digits after the decimal."), 4); + } else { + SS.afterDecimalDegree = v; + SS.GW.Invalidate(); + } + break; + } + case Edit::EXPORT_SCALE: { + Expr *e = Expr::From(s, /*popUpError=*/true); + if(e) { + double ev = e->Eval(); + if(fabs(ev) < 0.001 || IsReasonable(ev)) { + Error(_("Export scale must not be zero!")); + } else { + SS.exportScale = (float)ev; + } + } + break; + } + case Edit::EXPORT_OFFSET: { + Expr *e = Expr::From(s, /*popUpError=*/true); + if(e) { + double ev = SS.ExprToMm(e); + if(IsReasonable(ev) || ev < 0) { + Error(_("Cutter radius offset must not be negative!")); + } else { + SS.exportOffset = (float)ev; + } + } + break; + } + case Edit::CANVAS_SIZE: { + Expr *e = Expr::From(s, /*popUpError=*/true); + if(!e) { + break; + } + float d = (float)SS.ExprToMm(e); + switch(edit.i) { + case 0: SS.exportMargin.left = d; break; + case 1: SS.exportMargin.right = d; break; + case 2: SS.exportMargin.bottom = d; break; + case 3: SS.exportMargin.top = d; break; + + case 10: SS.exportCanvas.width = d; break; + case 11: SS.exportCanvas.height = d; break; + case 12: SS.exportCanvas.dx = d; break; + case 13: SS.exportCanvas.dy = d; break; + } + break; + } + case Edit::G_CODE_DEPTH: { + Expr *e = Expr::From(s, /*popUpError=*/true); + if(e) SS.gCode.depth = (float)SS.ExprToMm(e); + break; + } + case Edit::G_CODE_PASSES: { + Expr *e = Expr::From(s, /*popUpError=*/true); + if(e) SS.gCode.passes = (int)(e->Eval()); + SS.gCode.passes = max(1, min(1000, SS.gCode.passes)); + break; + } + case Edit::G_CODE_FEED: { + Expr *e = Expr::From(s, /*popUpError=*/true); + if(e) SS.gCode.feed = (float)SS.ExprToMm(e); + break; + } + case Edit::G_CODE_PLUNGE_FEED: { + Expr *e = Expr::From(s, /*popUpError=*/true); + if(e) SS.gCode.plungeFeed = (float)SS.ExprToMm(e); + break; + } + case Edit::AUTOSAVE_INTERVAL: { + int interval = atoi(s.c_str()); + if(interval) { + if(interval >= 1) { + SS.autosaveInterval = interval; + SS.ScheduleAutosave(); + } else { + Error(_("Bad value: autosave interval should be positive")); + } + } else { + Error(_("Bad format: specify interval in integral minutes")); + } + break; + } + case Edit::FIND_CONSTRAINT_TIMEOUT: { + int timeout = atoi(s.c_str()); + if(timeout) { + if(timeout >= 1) { + SS.timeoutRedundantConstr = timeout; + } else { + SS.timeoutRedundantConstr = 1000; + } + } + break; + } + + default: return false; + } + return true; +} + diff --git a/src/constraint.cpp b/src/constraint.cpp new file mode 100644 index 0000000..2acc211 --- /dev/null +++ b/src/constraint.cpp @@ -0,0 +1,791 @@ +//----------------------------------------------------------------------------- +// Implementation of the Constraint menu, to create new constraints in +// the sketch. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +std::string Constraint::DescriptionString() const { + std::string s; + switch(type) { + case Type::POINTS_COINCIDENT: s = C_("constr-name", "pts-coincident"); break; + case Type::PT_PT_DISTANCE: s = C_("constr-name", "pt-pt-distance"); break; + case Type::PT_LINE_DISTANCE: s = C_("constr-name", "pt-line-distance"); break; + case Type::PT_PLANE_DISTANCE: s = C_("constr-name", "pt-plane-distance"); break; + case Type::PT_FACE_DISTANCE: s = C_("constr-name", "pt-face-distance"); break; + case Type::PROJ_PT_DISTANCE: s = C_("constr-name", "proj-pt-pt-distance"); break; + case Type::PT_IN_PLANE: s = C_("constr-name", "pt-in-plane"); break; + case Type::PT_ON_LINE: s = C_("constr-name", "pt-on-line"); break; + case Type::PT_ON_FACE: s = C_("constr-name", "pt-on-face"); break; + case Type::EQUAL_LENGTH_LINES: s = C_("constr-name", "eq-length"); break; + case Type::EQ_LEN_PT_LINE_D: s = C_("constr-name", "eq-length-and-pt-ln-dist"); break; + case Type::EQ_PT_LN_DISTANCES: s = C_("constr-name", "eq-pt-line-distances"); break; + case Type::LENGTH_RATIO: s = C_("constr-name", "length-ratio"); break; + case Type::LENGTH_DIFFERENCE: s = C_("constr-name", "length-difference"); break; + case Type::SYMMETRIC: s = C_("constr-name", "symmetric"); break; + case Type::SYMMETRIC_HORIZ: s = C_("constr-name", "symmetric-h"); break; + case Type::SYMMETRIC_VERT: s = C_("constr-name", "symmetric-v"); break; + case Type::SYMMETRIC_LINE: s = C_("constr-name", "symmetric-line"); break; + case Type::AT_MIDPOINT: s = C_("constr-name", "at-midpoint"); break; + case Type::HORIZONTAL: s = C_("constr-name", "horizontal"); break; + case Type::VERTICAL: s = C_("constr-name", "vertical"); break; + case Type::DIAMETER: s = C_("constr-name", "diameter"); break; + case Type::PT_ON_CIRCLE: s = C_("constr-name", "pt-on-circle"); break; + case Type::SAME_ORIENTATION: s = C_("constr-name", "same-orientation"); break; + case Type::ANGLE: s = C_("constr-name", "angle"); break; + case Type::PARALLEL: s = C_("constr-name", "parallel"); break; + case Type::ARC_LINE_TANGENT: s = C_("constr-name", "arc-line-tangent"); break; + case Type::CUBIC_LINE_TANGENT: s = C_("constr-name", "cubic-line-tangent"); break; + case Type::CURVE_CURVE_TANGENT: s = C_("constr-name", "curve-curve-tangent"); break; + case Type::PERPENDICULAR: s = C_("constr-name", "perpendicular"); break; + case Type::EQUAL_RADIUS: s = C_("constr-name", "eq-radius"); break; + case Type::EQUAL_ANGLE: s = C_("constr-name", "eq-angle"); break; + case Type::EQUAL_LINE_ARC_LEN: s = C_("constr-name", "eq-line-len-arc-len"); break; + case Type::WHERE_DRAGGED: s = C_("constr-name", "lock-where-dragged"); break; + case Type::COMMENT: s = C_("constr-name", "comment"); break; + default: s = "???"; break; + } + + return ssprintf("c%03x-%s", h.v, s.c_str()); +} + +#ifndef LIBRARY + +//----------------------------------------------------------------------------- +// Delete all constraints with the specified type, entityA, ptA. We use this +// when auto-removing constraints that would become redundant. +//----------------------------------------------------------------------------- +void Constraint::DeleteAllConstraintsFor(Constraint::Type type, hEntity entityA, hEntity ptA) +{ + SK.constraint.ClearTags(); + for(auto &constraint : SK.constraint) { + ConstraintBase *ct = &constraint; + if(ct->type != type) continue; + + if(ct->entityA != entityA) continue; + if(ct->ptA != ptA) continue; + ct->tag = 1; + } + SK.constraint.RemoveTagged(); + // And no need to do anything special, since nothing + // ever depends on a constraint. But do clear the + // hover, in case the just-deleted constraint was + // hovered. + SS.GW.hover.Clear(); +} + +hConstraint Constraint::AddConstraint(Constraint *c, bool rememberForUndo) { + if(rememberForUndo) SS.UndoRemember(); + + hConstraint hc = SK.constraint.AddAndAssignId(c); + SK.GetConstraint(hc)->Generate(&SK.param); + + SS.MarkGroupDirty(c->group); + SK.GetGroup(c->group)->dofCheckOk = false; + return c->h; +} + +hConstraint Constraint::Constrain(Constraint::Type type, hEntity ptA, hEntity ptB, + hEntity entityA, hEntity entityB, + bool other, bool other2) +{ + Constraint c = {}; + c.group = SS.GW.activeGroup; + c.workplane = SS.GW.ActiveWorkplane(); + c.type = type; + c.ptA = ptA; + c.ptB = ptB; + c.entityA = entityA; + c.entityB = entityB; + c.other = other; + c.other2 = other2; + return AddConstraint(&c, /*rememberForUndo=*/false); +} + +hConstraint Constraint::TryConstrain(Constraint::Type type, hEntity ptA, hEntity ptB, + hEntity entityA, hEntity entityB, + bool other, bool other2) { + int rankBefore, rankAfter; + SolveResult howBefore = SS.TestRankForGroup(SS.GW.activeGroup, &rankBefore); + hConstraint hc = Constrain(type, ptA, ptB, entityA, entityB, other, other2); + SolveResult howAfter = SS.TestRankForGroup(SS.GW.activeGroup, &rankAfter); + // There are two cases where the constraint is clearly redundant: + // * If the group wasn't overconstrained and now it is; + // * If the group was overconstrained, and adding the constraint doesn't change rank at all. + if((howBefore == SolveResult::OKAY && howAfter == SolveResult::REDUNDANT_OKAY) || + (howBefore == SolveResult::REDUNDANT_OKAY && howAfter == SolveResult::REDUNDANT_OKAY && + rankBefore == rankAfter)) { + SK.constraint.RemoveById(hc); + hc = {}; + } + return hc; +} + +hConstraint Constraint::ConstrainCoincident(hEntity ptA, hEntity ptB) { + return Constrain(Type::POINTS_COINCIDENT, ptA, ptB, + Entity::NO_ENTITY, Entity::NO_ENTITY, /*other=*/false, /*other2=*/false); +} + +void Constraint::ConstrainArcLineTangent(Constraint *c, Entity *line, Entity *arc) { + Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(), + l1 = SK.GetEntity(line->point[1])->PointGetNum(); + Vector a1 = SK.GetEntity(arc->point[1])->PointGetNum(), + a2 = SK.GetEntity(arc->point[2])->PointGetNum(); + if(l0.Equals(a1) || l1.Equals(a1)) { + c->other = false; + } else if(l0.Equals(a2) || l1.Equals(a2)) { + c->other = true; + } else { + Error(_("The tangent arc and line segment must share an " + "endpoint. Constrain them with Constrain -> " + "On Point before constraining tangent.")); + return; + } +} + +void Constraint::ConstrainCubicLineTangent(Constraint *c, Entity *line, Entity *cubic) { + Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(), + l1 = SK.GetEntity(line->point[1])->PointGetNum(); + Vector as = cubic->CubicGetStartNum(), + af = cubic->CubicGetFinishNum(); + + if(l0.Equals(as) || l1.Equals(as)) { + c->other = false; + } else if(l0.Equals(af) || l1.Equals(af)) { + c->other = true; + } else { + Error(_("The tangent cubic and line segment must share an " + "endpoint. Constrain them with Constrain -> " + "On Point before constraining tangent.")); + return; + } +} + +void Constraint::ConstrainCurveCurveTangent(Constraint *c, Entity *eA, Entity *eB) { + Vector as = eA->EndpointStart(), + af = eA->EndpointFinish(), + bs = eB->EndpointStart(), + bf = eB->EndpointFinish(); + if(as.Equals(bs)) { + c->other = false; + c->other2 = false; + } else if(as.Equals(bf)) { + c->other = false; + c->other2 = true; + } else if(af.Equals(bs)) { + c->other = true; + c->other2 = false; + } else if(af.Equals(bf)) { + c->other = true; + c->other2 = true; + } else { + Error(_("The curves must share an endpoint. Constrain them " + "with Constrain -> On Point before constraining " + "tangent.")); + return; + } +} + +void Constraint::MenuConstrain(Command id) { + Constraint c = {}; + c.group = SS.GW.activeGroup; + c.workplane = SS.GW.ActiveWorkplane(); + + SS.GW.GroupSelection(); + auto const &gs = SS.GW.gs; + + switch(id) { + case Command::DISTANCE_DIA: + case Command::REF_DISTANCE: { + if(gs.points == 2 && gs.n == 2) { + c.type = Type::PT_PT_DISTANCE; + c.ptA = gs.point[0]; + c.ptB = gs.point[1]; + } else if(gs.lineSegments == 1 && gs.n == 1) { + c.type = Type::PT_PT_DISTANCE; + Entity *e = SK.GetEntity(gs.entity[0]); + c.ptA = e->point[0]; + c.ptB = e->point[1]; + } else if(gs.vectors == 1 && gs.points == 2 && gs.n == 3) { + c.type = Type::PROJ_PT_DISTANCE; + c.ptA = gs.point[0]; + c.ptB = gs.point[1]; + c.entityA = gs.vector[0]; + } else if(gs.workplanes == 1 && gs.points == 1 && gs.n == 2) { + c.type = Type::PT_PLANE_DISTANCE; + c.ptA = gs.point[0]; + c.entityA = gs.entity[0]; + } else if(gs.lineSegments == 1 && gs.points == 1 && gs.n == 2) { + c.type = Type::PT_LINE_DISTANCE; + c.ptA = gs.point[0]; + c.entityA = gs.entity[0]; + } else if(gs.faces == 1 && gs.points == 1 && gs.n == 2) { + c.type = Type::PT_FACE_DISTANCE; + c.ptA = gs.point[0]; + c.entityA = gs.face[0]; + } else if(gs.circlesOrArcs == 1 && gs.n == 1) { + c.type = Type::DIAMETER; + c.entityA = gs.entity[0]; + } else { + Error(_("Bad selection for distance / diameter constraint. This " + "constraint can apply to:\n\n" + " * two points (distance between points)\n" + " * a line segment (length)\n" + " * two points and a line segment or normal (projected distance)\n" + " * a workplane and a point (minimum distance)\n" + " * a line segment and a point (minimum distance)\n" + " * a plane face and a point (minimum distance)\n" + " * a circle or an arc (diameter)\n")); + return; + } + if(c.type == Type::PT_PT_DISTANCE || c.type == Type::PROJ_PT_DISTANCE) { + Vector n = SS.GW.projRight.Cross(SS.GW.projUp); + Vector a = SK.GetEntity(c.ptA)->PointGetNum(); + Vector b = SK.GetEntity(c.ptB)->PointGetNum(); + c.disp.offset = n.Cross(a.Minus(b)); + c.disp.offset = (c.disp.offset).WithMagnitude(50/SS.GW.scale); + } else { + c.disp.offset = Vector::From(0, 0, 0); + } + + if(id == Command::REF_DISTANCE) { + c.reference = true; + } + + c.valA = 0; + c.ModifyToSatisfy(); + AddConstraint(&c); + break; + } + + case Command::ON_ENTITY: + if(gs.points == 2 && gs.n == 2) { + c.type = Type::POINTS_COINCIDENT; + c.ptA = gs.point[0]; + c.ptB = gs.point[1]; + } else if(gs.points == 1 && gs.workplanes == 1 && gs.n == 2) { + c.type = Type::PT_IN_PLANE; + c.ptA = gs.point[0]; + c.entityA = gs.entity[0]; + } else if(gs.points == 1 && gs.lineSegments == 1 && gs.n == 2) { + c.type = Type::PT_ON_LINE; + c.ptA = gs.point[0]; + c.entityA = gs.entity[0]; + } else if(gs.points == 1 && gs.circlesOrArcs == 1 && gs.n == 2) { + c.type = Type::PT_ON_CIRCLE; + c.ptA = gs.point[0]; + c.entityA = gs.entity[0]; + } else if(gs.points == 1 && gs.faces == 1 && gs.n == 2) { + c.type = Type::PT_ON_FACE; + c.ptA = gs.point[0]; + c.entityA = gs.face[0]; + } else { + Error(_("Bad selection for on point / curve / plane constraint. " + "This constraint can apply to:\n\n" + " * two points (points coincident)\n" + " * a point and a workplane (point in plane)\n" + " * a point and a line segment (point on line)\n" + " * a point and a circle or arc (point on curve)\n" + " * a point and a plane face (point on face)\n")); + return; + } + AddConstraint(&c); + break; + + case Command::EQUAL: + if(gs.lineSegments == 2 && gs.n == 2) { + c.type = Type::EQUAL_LENGTH_LINES; + c.entityA = gs.entity[0]; + c.entityB = gs.entity[1]; + } else if(gs.lineSegments == 2 && gs.points == 2 && gs.n == 4) { + c.type = Type::EQ_PT_LN_DISTANCES; + c.entityA = gs.entity[0]; + c.ptA = gs.point[0]; + c.entityB = gs.entity[1]; + c.ptB = gs.point[1]; + } else if(gs.lineSegments == 1 && gs.points == 2 && gs.n == 3) { + // The same line segment for the distances, but different + // points. + c.type = Type::EQ_PT_LN_DISTANCES; + c.entityA = gs.entity[0]; + c.ptA = gs.point[0]; + c.entityB = gs.entity[0]; + c.ptB = gs.point[1]; + } else if(gs.lineSegments == 2 && gs.points == 1 && gs.n == 3) { + c.type = Type::EQ_LEN_PT_LINE_D; + c.entityA = gs.entity[0]; + c.entityB = gs.entity[1]; + c.ptA = gs.point[0]; + } else if(gs.vectors == 4 && gs.n == 4) { + c.type = Type::EQUAL_ANGLE; + c.entityA = gs.vector[0]; + c.entityB = gs.vector[1]; + c.entityC = gs.vector[2]; + c.entityD = gs.vector[3]; + } else if(gs.vectors == 3 && gs.n == 3) { + c.type = Type::EQUAL_ANGLE; + c.entityA = gs.vector[0]; + c.entityB = gs.vector[1]; + c.entityC = gs.vector[1]; + c.entityD = gs.vector[2]; + } else if(gs.circlesOrArcs == 2 && gs.n == 2) { + c.type = Type::EQUAL_RADIUS; + c.entityA = gs.entity[0]; + c.entityB = gs.entity[1]; + } else if(gs.arcs == 1 && gs.lineSegments == 1 && gs.n == 2) { + c.type = Type::EQUAL_LINE_ARC_LEN; + if(SK.GetEntity(gs.entity[0])->type == Entity::Type::ARC_OF_CIRCLE) { + c.entityA = gs.entity[1]; + c.entityB = gs.entity[0]; + } else { + c.entityA = gs.entity[0]; + c.entityB = gs.entity[1]; + } + } else { + Error(_("Bad selection for equal length / radius constraint. " + "This constraint can apply to:\n\n" + " * two line segments (equal length)\n" + " * two line segments and two points " + "(equal point-line distances)\n" + " * a line segment and two points " + "(equal point-line distances)\n" + " * a line segment, and a point and line segment " + "(point-line distance equals length)\n" + " * four line segments or normals " + "(equal angle between A,B and C,D)\n" + " * three line segments or normals " + "(equal angle between A,B and B,C)\n" + " * two circles or arcs (equal radius)\n" + " * a line segment and an arc " + "(line segment length equals arc length)\n")); + return; + } + if(c.type == Type::EQUAL_ANGLE) { + // Infer the nearest supplementary angle from the sketch. + Vector a1 = SK.GetEntity(c.entityA)->VectorGetNum(), + b1 = SK.GetEntity(c.entityB)->VectorGetNum(), + a2 = SK.GetEntity(c.entityC)->VectorGetNum(), + b2 = SK.GetEntity(c.entityD)->VectorGetNum(); + double d1 = a1.Dot(b1), d2 = a2.Dot(b2); + + if(d1*d2 < 0) { + c.other = true; + } + } + AddConstraint(&c); + break; + + case Command::RATIO: + if(gs.lineSegments == 2 && gs.n == 2) { + c.type = Type::LENGTH_RATIO; + c.entityA = gs.entity[0]; + c.entityB = gs.entity[1]; + } else { + Error(_("Bad selection for length ratio constraint. This " + "constraint can apply to:\n\n" + " * two line segments\n")); + return; + } + + c.valA = 0; + c.ModifyToSatisfy(); + AddConstraint(&c); + break; + + case Command::DIFFERENCE: + if(gs.lineSegments == 2 && gs.n == 2) { + c.type = Type::LENGTH_DIFFERENCE; + c.entityA = gs.entity[0]; + c.entityB = gs.entity[1]; + } else { + Error(_("Bad selection for length difference constraint. This " + "constraint can apply to:\n\n" + " * two line segments\n")); + return; + } + + c.valA = 0; + c.ModifyToSatisfy(); + AddConstraint(&c); + break; + + case Command::AT_MIDPOINT: + if(gs.lineSegments == 1 && gs.points == 1 && gs.n == 2) { + c.type = Type::AT_MIDPOINT; + c.entityA = gs.entity[0]; + c.ptA = gs.point[0]; + + // If a point is at-midpoint, then no reason to also constrain + // it on-line; so auto-remove that. + DeleteAllConstraintsFor(Type::PT_ON_LINE, c.entityA, c.ptA); + } else if(gs.lineSegments == 1 && gs.workplanes == 1 && gs.n == 2) { + c.type = Type::AT_MIDPOINT; + int i = SK.GetEntity(gs.entity[0])->IsWorkplane() ? 1 : 0; + c.entityA = gs.entity[i]; + c.entityB = gs.entity[1-i]; + } else { + Error(_("Bad selection for at midpoint constraint. This " + "constraint can apply to:\n\n" + " * a line segment and a point " + "(point at midpoint)\n" + " * a line segment and a workplane " + "(line's midpoint on plane)\n")); + return; + } + AddConstraint(&c); + break; + + case Command::SYMMETRIC: + if(gs.points == 2 && + ((gs.workplanes == 1 && gs.n == 3) || + (gs.n == 2))) + { + if(gs.entities > 0) + c.entityA = gs.entity[0]; + c.ptA = gs.point[0]; + c.ptB = gs.point[1]; + c.type = Type::SYMMETRIC; + } else if(gs.lineSegments == 1 && + ((gs.workplanes == 1 && gs.n == 2) || + (gs.n == 1))) + { + Entity *line; + if(SK.GetEntity(gs.entity[0])->IsWorkplane()) { + line = SK.GetEntity(gs.entity[1]); + c.entityA = gs.entity[0]; + } else { + line = SK.GetEntity(gs.entity[0]); + } + c.ptA = line->point[0]; + c.ptB = line->point[1]; + c.type = Type::SYMMETRIC; + } else if(SS.GW.LockedInWorkplane() + && gs.lineSegments == 2 && gs.n == 2) + { + Entity *l0 = SK.GetEntity(gs.entity[0]), + *l1 = SK.GetEntity(gs.entity[1]); + + if((l1->group != SS.GW.activeGroup) || + (l1->construction && !(l0->construction))) + { + swap(l0, l1); + } + c.ptA = l1->point[0]; + c.ptB = l1->point[1]; + c.entityA = l0->h; + c.type = Type::SYMMETRIC_LINE; + } else if(SS.GW.LockedInWorkplane() + && gs.lineSegments == 1 && gs.points == 2 && gs.n == 3) + { + c.ptA = gs.point[0]; + c.ptB = gs.point[1]; + c.entityA = gs.entity[0]; + c.type = Type::SYMMETRIC_LINE; + } else { + Error(_("Bad selection for symmetric constraint. This constraint " + "can apply to:\n\n" + " * two points or a line segment " + "(symmetric about workplane's coordinate axis)\n" + " * line segment, and two points or a line segment " + "(symmetric about line segment)\n" + " * workplane, and two points or a line segment " + "(symmetric about workplane)\n")); + return; + } + if(c.entityA == Entity::NO_ENTITY) { + // Horizontal / vertical symmetry, implicit symmetry plane + // normal to the workplane + if(c.workplane == Entity::FREE_IN_3D) { + Error(_("A workplane must be active when constraining " + "symmetric without an explicit symmetry plane.")); + return; + } + Vector pa = SK.GetEntity(c.ptA)->PointGetNum(); + Vector pb = SK.GetEntity(c.ptB)->PointGetNum(); + Vector dp = pa.Minus(pb); + EntityBase *norm = SK.GetEntity(c.workplane)->Normal();; + Vector u = norm->NormalU(), v = norm->NormalV(); + if(fabs(dp.Dot(u)) > fabs(dp.Dot(v))) { + c.type = Type::SYMMETRIC_HORIZ; + } else { + c.type = Type::SYMMETRIC_VERT; + } + if(gs.lineSegments == 1) { + // If this line segment is already constrained horiz or + // vert, then auto-remove that redundant constraint. + DeleteAllConstraintsFor(Type::HORIZONTAL, (gs.entity[0]), + Entity::NO_ENTITY); + DeleteAllConstraintsFor(Type::VERTICAL, (gs.entity[0]), + Entity::NO_ENTITY); + } + } + AddConstraint(&c); + break; + + case Command::VERTICAL: + case Command::HORIZONTAL: { + hEntity ha, hb; + if(c.workplane == Entity::FREE_IN_3D) { + Error(_("Activate a workplane (with Sketch -> In Workplane) before " + "applying a horizontal or vertical constraint.")); + return; + } + if(gs.lineSegments == 1 && gs.n == 1) { + c.entityA = gs.entity[0]; + Entity *e = SK.GetEntity(c.entityA); + ha = e->point[0]; + hb = e->point[1]; + } else if(gs.points == 2 && gs.n == 2) { + ha = c.ptA = gs.point[0]; + hb = c.ptB = gs.point[1]; + } else { + Error(_("Bad selection for horizontal / vertical constraint. " + "This constraint can apply to:\n\n" + " * two points\n" + " * a line segment\n")); + return; + } + if(id == Command::HORIZONTAL) { + c.type = Type::HORIZONTAL; + } else { + c.type = Type::VERTICAL; + } + AddConstraint(&c); + break; + } + + case Command::ORIENTED_SAME: { + if(gs.anyNormals == 2 && gs.n == 2) { + c.type = Type::SAME_ORIENTATION; + c.entityA = gs.anyNormal[0]; + c.entityB = gs.anyNormal[1]; + } else { + Error(_("Bad selection for same orientation constraint. This " + "constraint can apply to:\n\n" + " * two normals\n")); + return; + } + SS.UndoRemember(); + + Entity *nfree = SK.GetEntity(c.entityA); + Entity *nref = SK.GetEntity(c.entityB); + if(nref->group == SS.GW.activeGroup) { + swap(nref, nfree); + } + if(nfree->group == SS.GW.activeGroup && nref->group != SS.GW.activeGroup) { + // nfree is free, and nref is locked (since it came from a + // previous group); so let's force nfree aligned to nref, + // and make convergence easy + Vector ru = nref ->NormalU(), rv = nref ->NormalV(); + Vector fu = nfree->NormalU(), fv = nfree->NormalV(); + + if(fabs(fu.Dot(ru)) < fabs(fu.Dot(rv))) { + // There might be an odd*90 degree rotation about the + // normal vector; allow that, since the numerical + // constraint does + swap(ru, rv); + } + fu = fu.Dot(ru) > 0 ? ru : ru.ScaledBy(-1); + fv = fv.Dot(rv) > 0 ? rv : rv.ScaledBy(-1); + + nfree->NormalForceTo(Quaternion::From(fu, fv)); + } + AddConstraint(&c, /*rememberForUndo=*/false); + break; + } + + case Command::OTHER_ANGLE: + if(gs.constraints == 1 && gs.n == 0) { + Constraint *c = SK.GetConstraint(gs.constraint[0]); + if(c->type == Type::ANGLE) { + SS.UndoRemember(); + c->other = !(c->other); + c->ModifyToSatisfy(); + break; + } + if(c->type == Type::EQUAL_ANGLE) { + SS.UndoRemember(); + c->other = !(c->other); + SS.MarkGroupDirty(c->group); + break; + } + } + Error(_("Must select an angle constraint.")); + return; + + case Command::REFERENCE: + if(gs.constraints == 1 && gs.n == 0) { + Constraint *c = SK.GetConstraint(gs.constraint[0]); + if(c->HasLabel() && c->type != Type::COMMENT) { + SS.UndoRemember(); + (c->reference) = !(c->reference); + SS.MarkGroupDirty(c->group, /*onlyThis=*/true); + break; + } + } + Error(_("Must select a constraint with associated label.")); + return; + + case Command::ANGLE: + case Command::REF_ANGLE: { + if(gs.vectors == 2 && gs.n == 2) { + c.type = Type::ANGLE; + c.entityA = gs.vector[0]; + c.entityB = gs.vector[1]; + c.valA = 0; + } else { + Error(_("Bad selection for angle constraint. This constraint " + "can apply to:\n\n" + " * two line segments\n" + " * a line segment and a normal\n" + " * two normals\n")); + return; + } + + Entity *ea = SK.GetEntity(c.entityA), + *eb = SK.GetEntity(c.entityB); + if(ea->type == Entity::Type::LINE_SEGMENT && + eb->type == Entity::Type::LINE_SEGMENT) + { + Vector a0 = SK.GetEntity(ea->point[0])->PointGetNum(), + a1 = SK.GetEntity(ea->point[1])->PointGetNum(), + b0 = SK.GetEntity(eb->point[0])->PointGetNum(), + b1 = SK.GetEntity(eb->point[1])->PointGetNum(); + if(a0.Equals(b0) || a1.Equals(b1)) { + // okay, vectors should be drawn in same sense + } else if(a0.Equals(b1) || a1.Equals(b0)) { + // vectors are in opposite sense + c.other = true; + } else { + // no shared point; not clear which intersection to draw + } + } + + if(id == Command::REF_ANGLE) { + c.reference = true; + } + + c.ModifyToSatisfy(); + AddConstraint(&c); + break; + } + + case Command::PARALLEL: + if(gs.vectors == 2 && gs.n == 2) { + c.type = Type::PARALLEL; + c.entityA = gs.vector[0]; + c.entityB = gs.vector[1]; + } else if(gs.lineSegments == 1 && gs.arcs == 1 && gs.n == 2) { + Entity *line = SK.GetEntity(gs.entity[0]), + *arc = SK.GetEntity(gs.entity[1]); + if(line->type == Entity::Type::ARC_OF_CIRCLE) { + swap(line, arc); + } + ConstrainArcLineTangent(&c, line, arc); + c.type = Type::ARC_LINE_TANGENT; + c.entityA = arc->h; + c.entityB = line->h; + } else if(gs.lineSegments == 1 && gs.cubics == 1 && gs.n == 2) { + Entity *line = SK.GetEntity(gs.entity[0]), + *cubic = SK.GetEntity(gs.entity[1]); + if(line->type == Entity::Type::CUBIC) { + swap(line, cubic); + } + ConstrainCubicLineTangent(&c, line, cubic); + c.type = Type::CUBIC_LINE_TANGENT; + c.entityA = cubic->h; + c.entityB = line->h; + } else if(gs.cubics + gs.arcs == 2 && gs.n == 2) { + if(!SS.GW.LockedInWorkplane()) { + Error(_("Curve-curve tangency must apply in workplane.")); + return; + } + Entity *eA = SK.GetEntity(gs.entity[0]), + *eB = SK.GetEntity(gs.entity[1]); + ConstrainCurveCurveTangent(&c, eA, eB); + c.type = Type::CURVE_CURVE_TANGENT; + c.entityA = eA->h; + c.entityB = eB->h; + } else { + Error(_("Bad selection for parallel / tangent constraint. This " + "constraint can apply to:\n\n" + " * two line segments (parallel)\n" + " * a line segment and a normal (parallel)\n" + " * two normals (parallel)\n" + " * two line segments, arcs, or beziers, that share " + "an endpoint (tangent)\n")); + return; + } + AddConstraint(&c); + break; + + case Command::PERPENDICULAR: + if(gs.vectors == 2 && gs.n == 2) { + c.type = Type::PERPENDICULAR; + c.entityA = gs.vector[0]; + c.entityB = gs.vector[1]; + } else { + Error(_("Bad selection for perpendicular constraint. This " + "constraint can apply to:\n\n" + " * two line segments\n" + " * a line segment and a normal\n" + " * two normals\n")); + return; + } + AddConstraint(&c); + break; + + case Command::WHERE_DRAGGED: + if(gs.points == 1 && gs.n == 1) { + c.type = Type::WHERE_DRAGGED; + c.ptA = gs.point[0]; + } else { + Error(_("Bad selection for lock point where dragged constraint. " + "This constraint can apply to:\n\n" + " * a point\n")); + return; + } + AddConstraint(&c); + break; + + case Command::COMMENT: + SS.GW.pending.operation = GraphicsWindow::Pending::COMMAND; + SS.GW.pending.command = Command::COMMENT; + SS.GW.pending.description = _("click center of comment text"); + SS.ScheduleShowTW(); + break; + + default: ssassert(false, "Unexpected menu ID"); + } + + for(const Constraint &cc : SK.constraint) { + if(c.h != cc.h && c.Equals(cc)) { + // Oops, we already have this exact constraint. Remove the one we just added. + SK.constraint.RemoveById(c.h); + SS.GW.ClearSelection(); + // And now select the old one, to give feedback. + SS.GW.MakeSelected(cc.h); + return; + } + } + + if(SK.constraint.FindByIdNoOops(c.h)) { + Constraint *constraint = SK.GetConstraint(c.h); + if(SS.TestRankForGroup(c.group) == SolveResult::REDUNDANT_OKAY && + !SK.GetGroup(SS.GW.activeGroup)->allowRedundant && + constraint->HasLabel()) { + constraint->reference = true; + } + } + + if((id == Command::DISTANCE_DIA || id == Command::ANGLE || + id == Command::RATIO || id == Command::DIFFERENCE) && + SS.immediatelyEditDimension) { + SS.GW.EditConstraint(c.h); + } + + SS.GW.ClearSelection(); +} + +#endif /* ! LIBRARY */ diff --git a/src/constrainteq.cpp b/src/constrainteq.cpp new file mode 100644 index 0000000..965a13d --- /dev/null +++ b/src/constrainteq.cpp @@ -0,0 +1,843 @@ +//----------------------------------------------------------------------------- +// Given a constraint, generate one or more equations in our symbolic algebra +// system to represent that constraint; also various geometric helper +// functions for that. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +const hConstraint ConstraintBase::NO_CONSTRAINT = { 0 }; + +bool ConstraintBase::HasLabel() const { + switch(type) { + case Type::PT_LINE_DISTANCE: + case Type::PT_PLANE_DISTANCE: + case Type::PT_FACE_DISTANCE: + case Type::PT_PT_DISTANCE: + case Type::PROJ_PT_DISTANCE: + case Type::DIAMETER: + case Type::LENGTH_RATIO: + case Type::LENGTH_DIFFERENCE: + case Type::ANGLE: + case Type::COMMENT: + return true; + + default: + return false; + } +} + +bool ConstraintBase::IsProjectible() const { + switch(type) { + case Type::POINTS_COINCIDENT: + case Type::PT_PT_DISTANCE: + case Type::PT_LINE_DISTANCE: + case Type::PT_ON_LINE: + case Type::EQUAL_LENGTH_LINES: + case Type::EQ_LEN_PT_LINE_D: + case Type::EQ_PT_LN_DISTANCES: + case Type::EQUAL_ANGLE: + case Type::LENGTH_RATIO: + case Type::LENGTH_DIFFERENCE: + case Type::SYMMETRIC: + case Type::SYMMETRIC_HORIZ: + case Type::SYMMETRIC_VERT: + case Type::SYMMETRIC_LINE: + case Type::AT_MIDPOINT: + case Type::HORIZONTAL: + case Type::VERTICAL: + case Type::ANGLE: + case Type::PARALLEL: + case Type::PERPENDICULAR: + case Type::WHERE_DRAGGED: + case Type::COMMENT: + return true; + + case Type::PT_PLANE_DISTANCE: + case Type::PT_FACE_DISTANCE: + case Type::PROJ_PT_DISTANCE: + case Type::PT_IN_PLANE: + case Type::PT_ON_FACE: + case Type::EQUAL_LINE_ARC_LEN: + case Type::DIAMETER: + case Type::PT_ON_CIRCLE: + case Type::SAME_ORIENTATION: + case Type::CUBIC_LINE_TANGENT: + case Type::CURVE_CURVE_TANGENT: + case Type::ARC_LINE_TANGENT: + case Type::EQUAL_RADIUS: + return false; + } + ssassert(false, "Impossible"); +} + +ExprVector ConstraintBase::VectorsParallel3d(ExprVector a, ExprVector b, hParam p) { + return a.Minus(b.ScaledBy(Expr::From(p))); +} + +Expr *ConstraintBase::PointLineDistance(hEntity wrkpl, hEntity hpt, hEntity hln) +{ + EntityBase *ln = SK.GetEntity(hln); + EntityBase *a = SK.GetEntity(ln->point[0]); + EntityBase *b = SK.GetEntity(ln->point[1]); + + EntityBase *p = SK.GetEntity(hpt); + + if(wrkpl == EntityBase::FREE_IN_3D) { + ExprVector ep = p->PointGetExprs(); + + ExprVector ea = a->PointGetExprs(); + ExprVector eb = b->PointGetExprs(); + ExprVector eab = ea.Minus(eb); + Expr *m = eab.Magnitude(); + + return ((eab.Cross(ea.Minus(ep))).Magnitude())->Div(m); + } else { + Expr *ua, *va, *ub, *vb; + a->PointGetExprsInWorkplane(wrkpl, &ua, &va); + b->PointGetExprsInWorkplane(wrkpl, &ub, &vb); + + Expr *du = ua->Minus(ub); + Expr *dv = va->Minus(vb); + + Expr *u, *v; + p->PointGetExprsInWorkplane(wrkpl, &u, &v); + + Expr *m = ((du->Square())->Plus(dv->Square()))->Sqrt(); + + Expr *proj = (dv->Times(ua->Minus(u)))->Minus( + (du->Times(va->Minus(v)))); + + return proj->Div(m); + } +} + +Expr *ConstraintBase::PointPlaneDistance(ExprVector p, hEntity hpl) { + ExprVector n; + Expr *d; + SK.GetEntity(hpl)->WorkplaneGetPlaneExprs(&n, &d); + return (p.Dot(n))->Minus(d); +} + +Expr *ConstraintBase::Distance(hEntity wrkpl, hEntity hpa, hEntity hpb) { + EntityBase *pa = SK.GetEntity(hpa); + EntityBase *pb = SK.GetEntity(hpb); + ssassert(pa->IsPoint() && pb->IsPoint(), + "Expected two points to measure projected distance between"); + + if(wrkpl == EntityBase::FREE_IN_3D) { + // This is true distance + ExprVector ea, eb, eab; + ea = pa->PointGetExprs(); + eb = pb->PointGetExprs(); + eab = ea.Minus(eb); + + return eab.Magnitude(); + } else { + // This is projected distance, in the given workplane. + Expr *au, *av, *bu, *bv; + + pa->PointGetExprsInWorkplane(wrkpl, &au, &av); + pb->PointGetExprsInWorkplane(wrkpl, &bu, &bv); + + Expr *du = au->Minus(bu); + Expr *dv = av->Minus(bv); + + return ((du->Square())->Plus(dv->Square()))->Sqrt(); + } +} + +//----------------------------------------------------------------------------- +// Return the cosine of the angle between two vectors. If a workplane is +// specified, then it's the cosine of their projections into that workplane. +//----------------------------------------------------------------------------- +Expr *ConstraintBase::DirectionCosine(hEntity wrkpl, + ExprVector ae, ExprVector be) +{ + if(wrkpl == EntityBase::FREE_IN_3D) { + Expr *mags = (ae.Magnitude())->Times(be.Magnitude()); + return (ae.Dot(be))->Div(mags); + } else { + EntityBase *w = SK.GetEntity(wrkpl); + ExprVector u = w->Normal()->NormalExprsU(); + ExprVector v = w->Normal()->NormalExprsV(); + Expr *ua = u.Dot(ae); + Expr *va = v.Dot(ae); + Expr *ub = u.Dot(be); + Expr *vb = v.Dot(be); + Expr *maga = (ua->Square()->Plus(va->Square()))->Sqrt(); + Expr *magb = (ub->Square()->Plus(vb->Square()))->Sqrt(); + Expr *dot = (ua->Times(ub))->Plus(va->Times(vb)); + return dot->Div(maga->Times(magb)); + } +} + +ExprVector ConstraintBase::PointInThreeSpace(hEntity workplane, + Expr *u, Expr *v) +{ + EntityBase *w = SK.GetEntity(workplane); + + ExprVector ub = w->Normal()->NormalExprsU(); + ExprVector vb = w->Normal()->NormalExprsV(); + ExprVector ob = w->WorkplaneGetOffsetExprs(); + + return (ub.ScaledBy(u)).Plus(vb.ScaledBy(v)).Plus(ob); +} + +void ConstraintBase::ModifyToSatisfy() { + if(type == Type::ANGLE) { + Vector a = SK.GetEntity(entityA)->VectorGetNum(); + Vector b = SK.GetEntity(entityB)->VectorGetNum(); + if(other) a = a.ScaledBy(-1); + if(workplane != EntityBase::FREE_IN_3D) { + a = a.ProjectVectorInto(workplane); + b = b.ProjectVectorInto(workplane); + } + double c = (a.Dot(b))/(a.Magnitude() * b.Magnitude()); + valA = acos(c)*180/PI; + } else if(type == Type::PT_ON_LINE) { + EntityBase *eln = SK.GetEntity(entityA); + EntityBase *ea = SK.GetEntity(eln->point[0]); + EntityBase *eb = SK.GetEntity(eln->point[1]); + EntityBase *ep = SK.GetEntity(ptA); + ExprVector exp = ep->PointGetExprsInWorkplane(workplane); + ExprVector exa = ea->PointGetExprsInWorkplane(workplane); + ExprVector exb = eb->PointGetExprsInWorkplane(workplane); + ExprVector exba = exb.Minus(exa); + SK.GetParam(valP)->val = exba.Dot(exp.Minus(exa))->Eval() / exba.Dot(exba)->Eval(); + } else { + // We'll fix these ones up by looking at their symbolic equation; + // that means no extra work. + IdList l = {}; + // Generate the equations even if this is a reference dimension + GenerateEquations(&l, /*forReference=*/true); + ssassert(l.n == 1, "Expected constraint to generate a single equation"); + + // These equations are written in the form f(...) - d = 0, where + // d is the value of the valA. + valA += (l[0].e)->Eval(); + + l.Clear(); + } +} + +void ConstraintBase::AddEq(IdList *l, Expr *expr, int index) const +{ + Equation eq; + eq.e = expr; + eq.h = h.equation(index); + l->Add(&eq); +} + +void ConstraintBase::AddEq(IdList *l, const ExprVector &v, + int baseIndex) const { + AddEq(l, v.x, baseIndex); + AddEq(l, v.y, baseIndex + 1); + if(workplane == EntityBase::FREE_IN_3D) { + AddEq(l, v.z, baseIndex + 2); + } +} + +void ConstraintBase::Generate(IdList *l) { + switch(type) { + case Type::PARALLEL: + case Type::CUBIC_LINE_TANGENT: + // Add new parameter only when we operate in 3d space + if(workplane != EntityBase::FREE_IN_3D) break; + // fallthrough + case Type::SAME_ORIENTATION: + case Type::PT_ON_LINE: { + Param p = {}; + valP = h.param(0); + p.h = valP; + l->Add(&p); + break; + } + + default: + break; + } +} + +void ConstraintBase::GenerateEquations(IdList *l, + bool forReference) const { + if(reference && !forReference) return; + + Expr *exA = Expr::From(valA); + switch(type) { + case Type::PT_PT_DISTANCE: + AddEq(l, Distance(workplane, ptA, ptB)->Minus(exA), 0); + return; + + case Type::PROJ_PT_DISTANCE: { + ExprVector pA = SK.GetEntity(ptA)->PointGetExprs(), + pB = SK.GetEntity(ptB)->PointGetExprs(), + dp = pB.Minus(pA); + + ExprVector pp = SK.GetEntity(entityA)->VectorGetExprs(); + pp = pp.WithMagnitude(Expr::From(1.0)); + + AddEq(l, (dp.Dot(pp))->Minus(exA), 0); + return; + } + + case Type::PT_LINE_DISTANCE: + AddEq(l, + PointLineDistance(workplane, ptA, entityA)->Minus(exA), 0); + return; + + case Type::PT_PLANE_DISTANCE: { + ExprVector pt = SK.GetEntity(ptA)->PointGetExprs(); + AddEq(l, (PointPlaneDistance(pt, entityA))->Minus(exA), 0); + return; + } + + case Type::PT_FACE_DISTANCE: { + ExprVector pt = SK.GetEntity(ptA)->PointGetExprs(); + EntityBase *f = SK.GetEntity(entityA); + ExprVector p0 = f->FaceGetPointExprs(); + ExprVector n = f->FaceGetNormalExprs(); + AddEq(l, (pt.Minus(p0)).Dot(n)->Minus(exA), 0); + return; + } + + case Type::EQUAL_LENGTH_LINES: { + EntityBase *a = SK.GetEntity(entityA); + EntityBase *b = SK.GetEntity(entityB); + AddEq(l, Distance(workplane, a->point[0], a->point[1])->Minus( + Distance(workplane, b->point[0], b->point[1])), 0); + return; + } + + // These work on distance squared, since the pt-line distances are + // signed, and we want the absolute value. + case Type::EQ_LEN_PT_LINE_D: { + EntityBase *forLen = SK.GetEntity(entityA); + Expr *d1 = Distance(workplane, forLen->point[0], forLen->point[1]); + Expr *d2 = PointLineDistance(workplane, ptA, entityB); + AddEq(l, (d1->Square())->Minus(d2->Square()), 0); + return; + } + case Type::EQ_PT_LN_DISTANCES: { + Expr *d1 = PointLineDistance(workplane, ptA, entityA); + Expr *d2 = PointLineDistance(workplane, ptB, entityB); + AddEq(l, (d1->Square())->Minus(d2->Square()), 0); + return; + } + + case Type::LENGTH_RATIO: { + EntityBase *a = SK.GetEntity(entityA); + EntityBase *b = SK.GetEntity(entityB); + Expr *la = Distance(workplane, a->point[0], a->point[1]); + Expr *lb = Distance(workplane, b->point[0], b->point[1]); + AddEq(l, (la->Div(lb))->Minus(exA), 0); + return; + } + + case Type::LENGTH_DIFFERENCE: { + EntityBase *a = SK.GetEntity(entityA); + EntityBase *b = SK.GetEntity(entityB); + Expr *la = Distance(workplane, a->point[0], a->point[1]); + Expr *lb = Distance(workplane, b->point[0], b->point[1]); + AddEq(l, (la->Minus(lb))->Minus(exA), 0); + return; + } + + case Type::DIAMETER: { + EntityBase *circle = SK.GetEntity(entityA); + Expr *r = circle->CircleGetRadiusExpr(); + AddEq(l, (r->Times(Expr::From(2)))->Minus(exA), 0); + return; + } + + case Type::EQUAL_RADIUS: { + EntityBase *c1 = SK.GetEntity(entityA); + EntityBase *c2 = SK.GetEntity(entityB); + AddEq(l, (c1->CircleGetRadiusExpr())->Minus( + c2->CircleGetRadiusExpr()), 0); + return; + } + + case Type::EQUAL_LINE_ARC_LEN: { + EntityBase *line = SK.GetEntity(entityA), + *arc = SK.GetEntity(entityB); + + // Get the line length + ExprVector l0 = SK.GetEntity(line->point[0])->PointGetExprs(), + l1 = SK.GetEntity(line->point[1])->PointGetExprs(); + Expr *ll = (l1.Minus(l0)).Magnitude(); + + // And get the arc radius, and the cosine of its angle + EntityBase *ao = SK.GetEntity(arc->point[0]), + *as = SK.GetEntity(arc->point[1]), + *af = SK.GetEntity(arc->point[2]); + + ExprVector aos = (as->PointGetExprs()).Minus(ao->PointGetExprs()), + aof = (af->PointGetExprs()).Minus(ao->PointGetExprs()); + Expr *r = aof.Magnitude(); + + ExprVector n = arc->Normal()->NormalExprsN(); + ExprVector u = aos.WithMagnitude(Expr::From(1.0)); + ExprVector v = n.Cross(u); + // so in our new csys, we start at (1, 0, 0) + Expr *costheta = aof.Dot(u)->Div(r); + Expr *sintheta = aof.Dot(v)->Div(r); + + double thetas, thetaf, dtheta; + arc->ArcGetAngles(&thetas, &thetaf, &dtheta); + Expr *theta; + if(dtheta < 3*PI/4) { + theta = costheta->ACos(); + } else if(dtheta < 5*PI/4) { + // As the angle crosses pi, cos theta is not invertible; + // so use the sine to stop blowing up + theta = Expr::From(PI)->Minus(sintheta->ASin()); + } else { + theta = (Expr::From(2*PI))->Minus(costheta->ACos()); + } + + // And write the equation; r*theta = L + AddEq(l, (r->Times(theta))->Minus(ll), 0); + return; + } + + case Type::POINTS_COINCIDENT: { + EntityBase *a = SK.GetEntity(ptA); + EntityBase *b = SK.GetEntity(ptB); + if(workplane == EntityBase::FREE_IN_3D) { + ExprVector pa = a->PointGetExprs(); + ExprVector pb = b->PointGetExprs(); + AddEq(l, pa.x->Minus(pb.x), 0); + AddEq(l, pa.y->Minus(pb.y), 1); + AddEq(l, pa.z->Minus(pb.z), 2); + } else { + Expr *au, *av; + Expr *bu, *bv; + a->PointGetExprsInWorkplane(workplane, &au, &av); + b->PointGetExprsInWorkplane(workplane, &bu, &bv); + AddEq(l, au->Minus(bu), 0); + AddEq(l, av->Minus(bv), 1); + } + return; + } + + case Type::PT_IN_PLANE: + // This one works the same, whether projected or not. + AddEq(l, PointPlaneDistance( + SK.GetEntity(ptA)->PointGetExprs(), entityA), 0); + return; + + case Type::PT_ON_FACE: { + // a plane, n dot (p - p0) = 0 + ExprVector p = SK.GetEntity(ptA)->PointGetExprs(); + EntityBase *f = SK.GetEntity(entityA); + ExprVector p0 = f->FaceGetPointExprs(); + ExprVector n = f->FaceGetNormalExprs(); + AddEq(l, (p.Minus(p0)).Dot(n), 0); + return; + } + + case Type::PT_ON_LINE: { + EntityBase *ln = SK.GetEntity(entityA); + EntityBase *a = SK.GetEntity(ln->point[0]); + EntityBase *b = SK.GetEntity(ln->point[1]); + EntityBase *p = SK.GetEntity(ptA); + + ExprVector ep = p->PointGetExprsInWorkplane(workplane); + ExprVector ea = a->PointGetExprsInWorkplane(workplane); + ExprVector eb = b->PointGetExprsInWorkplane(workplane); + + ExprVector ptOnLine = ea.Plus(eb.Minus(ea).ScaledBy(Expr::From(valP))); + ExprVector eq = ptOnLine.Minus(ep); + + AddEq(l, eq); + return; + } + + case Type::PT_ON_CIRCLE: { + // This actually constrains the point to lie on the cylinder. + EntityBase *circle = SK.GetEntity(entityA); + ExprVector center = SK.GetEntity(circle->point[0])->PointGetExprs(); + ExprVector pt = SK.GetEntity(ptA)->PointGetExprs(); + EntityBase *normal = SK.GetEntity(circle->normal); + ExprVector u = normal->NormalExprsU(), + v = normal->NormalExprsV(); + + Expr *du = (center.Minus(pt)).Dot(u), + *dv = (center.Minus(pt)).Dot(v); + + Expr *r = circle->CircleGetRadiusExpr(); + + AddEq(l, du->Square()->Plus(dv->Square())->Sqrt()->Minus(r), 0); + return; + } + + case Type::AT_MIDPOINT: + if(workplane == EntityBase::FREE_IN_3D) { + EntityBase *ln = SK.GetEntity(entityA); + ExprVector a = SK.GetEntity(ln->point[0])->PointGetExprs(); + ExprVector b = SK.GetEntity(ln->point[1])->PointGetExprs(); + ExprVector m = (a.Plus(b)).ScaledBy(Expr::From(0.5)); + + if(ptA.v) { + ExprVector p = SK.GetEntity(ptA)->PointGetExprs(); + AddEq(l, (m.x)->Minus(p.x), 0); + AddEq(l, (m.y)->Minus(p.y), 1); + AddEq(l, (m.z)->Minus(p.z), 2); + } else { + AddEq(l, PointPlaneDistance(m, entityB), 0); + } + } else { + EntityBase *ln = SK.GetEntity(entityA); + EntityBase *a = SK.GetEntity(ln->point[0]); + EntityBase *b = SK.GetEntity(ln->point[1]); + + Expr *au, *av, *bu, *bv; + a->PointGetExprsInWorkplane(workplane, &au, &av); + b->PointGetExprsInWorkplane(workplane, &bu, &bv); + Expr *mu = Expr::From(0.5)->Times(au->Plus(bu)); + Expr *mv = Expr::From(0.5)->Times(av->Plus(bv)); + + if(ptA.v) { + EntityBase *p = SK.GetEntity(ptA); + Expr *pu, *pv; + p->PointGetExprsInWorkplane(workplane, &pu, &pv); + AddEq(l, pu->Minus(mu), 0); + AddEq(l, pv->Minus(mv), 1); + } else { + ExprVector m = PointInThreeSpace(workplane, mu, mv); + AddEq(l, PointPlaneDistance(m, entityB), 0); + } + } + return; + + case Type::SYMMETRIC: + if(workplane == EntityBase::FREE_IN_3D) { + EntityBase *plane = SK.GetEntity(entityA); + EntityBase *ea = SK.GetEntity(ptA); + EntityBase *eb = SK.GetEntity(ptB); + ExprVector a = ea->PointGetExprs(); + ExprVector b = eb->PointGetExprs(); + + // The midpoint of the line connecting the symmetric points + // lies on the plane of the symmetry. + ExprVector m = (a.Plus(b)).ScaledBy(Expr::From(0.5)); + AddEq(l, PointPlaneDistance(m, plane->h), 0); + + // And projected into the plane of symmetry, the points are + // coincident. + Expr *au, *av, *bu, *bv; + ea->PointGetExprsInWorkplane(plane->h, &au, &av); + eb->PointGetExprsInWorkplane(plane->h, &bu, &bv); + AddEq(l, au->Minus(bu), 1); + AddEq(l, av->Minus(bv), 2); + } else { + EntityBase *plane = SK.GetEntity(entityA); + EntityBase *a = SK.GetEntity(ptA); + EntityBase *b = SK.GetEntity(ptB); + + Expr *au, *av, *bu, *bv; + a->PointGetExprsInWorkplane(workplane, &au, &av); + b->PointGetExprsInWorkplane(workplane, &bu, &bv); + Expr *mu = Expr::From(0.5)->Times(au->Plus(bu)); + Expr *mv = Expr::From(0.5)->Times(av->Plus(bv)); + + ExprVector m = PointInThreeSpace(workplane, mu, mv); + AddEq(l, PointPlaneDistance(m, plane->h), 0); + + // Construct a vector within the workplane that is normal + // to the symmetry pane's normal (i.e., that lies in the + // plane of symmetry). The line connecting the points is + // perpendicular to that constructed vector. + EntityBase *w = SK.GetEntity(workplane); + ExprVector u = w->Normal()->NormalExprsU(); + ExprVector v = w->Normal()->NormalExprsV(); + + ExprVector pa = a->PointGetExprs(); + ExprVector pb = b->PointGetExprs(); + ExprVector n; + Expr *d; + plane->WorkplaneGetPlaneExprs(&n, &d); + AddEq(l, (n.Cross(u.Cross(v))).Dot(pa.Minus(pb)), 1); + } + return; + + case Type::SYMMETRIC_HORIZ: + case Type::SYMMETRIC_VERT: { + ssassert(workplane != Entity::FREE_IN_3D, + "Unexpected horizontal/vertical symmetric constraint in 3d"); + + EntityBase *a = SK.GetEntity(ptA); + EntityBase *b = SK.GetEntity(ptB); + + Expr *au, *av, *bu, *bv; + a->PointGetExprsInWorkplane(workplane, &au, &av); + b->PointGetExprsInWorkplane(workplane, &bu, &bv); + + if(type == Type::SYMMETRIC_HORIZ) { + AddEq(l, av->Minus(bv), 0); + AddEq(l, au->Plus(bu), 1); + } else { + AddEq(l, au->Minus(bu), 0); + AddEq(l, av->Plus(bv), 1); + } + return; + } + + case Type::SYMMETRIC_LINE: { + EntityBase *pa = SK.GetEntity(ptA); + EntityBase *pb = SK.GetEntity(ptB); + + Expr *pau, *pav, *pbu, *pbv; + pa->PointGetExprsInWorkplane(workplane, &pau, &pav); + pb->PointGetExprsInWorkplane(workplane, &pbu, &pbv); + + EntityBase *ln = SK.GetEntity(entityA); + EntityBase *la = SK.GetEntity(ln->point[0]); + EntityBase *lb = SK.GetEntity(ln->point[1]); + Expr *lau, *lav, *lbu, *lbv; + la->PointGetExprsInWorkplane(workplane, &lau, &lav); + lb->PointGetExprsInWorkplane(workplane, &lbu, &lbv); + + Expr *dpu = pbu->Minus(pau), *dpv = pbv->Minus(pav); + Expr *dlu = lbu->Minus(lau), *dlv = lbv->Minus(lav); + + // The line through the points is perpendicular to the line + // of symmetry. + AddEq(l, (dlu->Times(dpu))->Plus(dlv->Times(dpv)), 0); + + // And the signed distances of the points to the line are + // equal in magnitude and opposite in sign, so sum to zero + Expr *dista = (dlv->Times(lau->Minus(pau)))->Minus( + (dlu->Times(lav->Minus(pav)))); + Expr *distb = (dlv->Times(lau->Minus(pbu)))->Minus( + (dlu->Times(lav->Minus(pbv)))); + AddEq(l, dista->Plus(distb), 1); + + return; + } + + case Type::HORIZONTAL: + case Type::VERTICAL: { + ssassert(workplane != Entity::FREE_IN_3D, + "Unexpected horizontal/vertical constraint in 3d"); + + hEntity ha, hb; + if(entityA.v) { + EntityBase *e = SK.GetEntity(entityA); + ha = e->point[0]; + hb = e->point[1]; + } else { + ha = ptA; + hb = ptB; + } + EntityBase *a = SK.GetEntity(ha); + EntityBase *b = SK.GetEntity(hb); + + Expr *au, *av, *bu, *bv; + a->PointGetExprsInWorkplane(workplane, &au, &av); + b->PointGetExprsInWorkplane(workplane, &bu, &bv); + + AddEq(l, (type == Type::HORIZONTAL) ? av->Minus(bv) : au->Minus(bu), 0); + return; + } + + case Type::SAME_ORIENTATION: { + EntityBase *a = SK.GetEntity(entityA); + EntityBase *b = SK.GetEntity(entityB); + + ExprVector au = a->NormalExprsU(), + an = a->NormalExprsN(); + ExprVector bu = b->NormalExprsU(), + bv = b->NormalExprsV(), + bn = b->NormalExprsN(); + + ExprVector eq = VectorsParallel3d(an, bn, valP); + AddEq(l, eq.x, 0); + AddEq(l, eq.y, 1); + AddEq(l, eq.z, 2); + Expr *d1 = au.Dot(bv); + Expr *d2 = au.Dot(bu); + // Allow either orientation for the coordinate system, depending + // on how it was drawn. + if(fabs(d1->Eval()) < fabs(d2->Eval())) { + AddEq(l, d1, 3); + } else { + AddEq(l, d2, 3); + } + return; + } + + case Type::PERPENDICULAR: + case Type::ANGLE: { + EntityBase *a = SK.GetEntity(entityA); + EntityBase *b = SK.GetEntity(entityB); + ExprVector ae = a->VectorGetExprs(); + ExprVector be = b->VectorGetExprs(); + if(other) ae = ae.ScaledBy(Expr::From(-1)); + Expr *c = DirectionCosine(workplane, ae, be); + + if(type == Type::ANGLE) { + // The direction cosine is equal to the cosine of the + // specified angle + Expr *rads = exA->Times(Expr::From(PI/180)), + *rc = rads->Cos(); + double arc = fabs(rc->Eval()); + // avoid false detection of inconsistent systems by gaining + // up as the difference in dot products gets small at small + // angles; doubles still have plenty of precision, only + // problem is that rank test + Expr *mult = Expr::From(arc > 0.99 ? 0.01/(1.00001 - arc) : 1); + AddEq(l, (c->Minus(rc))->Times(mult), 0); + } else { + // The dot product (and therefore the direction cosine) + // is equal to zero, perpendicular. + AddEq(l, c, 0); + } + return; + } + + case Type::EQUAL_ANGLE: { + EntityBase *a = SK.GetEntity(entityA); + EntityBase *b = SK.GetEntity(entityB); + EntityBase *c = SK.GetEntity(entityC); + EntityBase *d = SK.GetEntity(entityD); + ExprVector ae = a->VectorGetExprs(); + ExprVector be = b->VectorGetExprs(); + ExprVector ce = c->VectorGetExprs(); + ExprVector de = d->VectorGetExprs(); + + if(other) ae = ae.ScaledBy(Expr::From(-1)); + + Expr *cab = DirectionCosine(workplane, ae, be); + Expr *ccd = DirectionCosine(workplane, ce, de); + + AddEq(l, cab->Minus(ccd), 0); + return; + } + + case Type::ARC_LINE_TANGENT: { + EntityBase *arc = SK.GetEntity(entityA); + EntityBase *line = SK.GetEntity(entityB); + + ExprVector ac = SK.GetEntity(arc->point[0])->PointGetExprs(); + ExprVector ap = + SK.GetEntity(arc->point[other ? 2 : 1])->PointGetExprs(); + + ExprVector ld = line->VectorGetExprs(); + + // The line is perpendicular to the radius + AddEq(l, ld.Dot(ac.Minus(ap)), 0); + return; + } + + case Type::CUBIC_LINE_TANGENT: { + EntityBase *cubic = SK.GetEntity(entityA); + EntityBase *line = SK.GetEntity(entityB); + + ExprVector a; + if(other) { + a = cubic->CubicGetFinishTangentExprs(); + } else { + a = cubic->CubicGetStartTangentExprs(); + } + + ExprVector b = line->VectorGetExprs(); + + if(workplane == EntityBase::FREE_IN_3D) { + ExprVector eq = VectorsParallel3d(a, b, valP); + AddEq(l, eq); + } else { + EntityBase *w = SK.GetEntity(workplane); + ExprVector wn = w->Normal()->NormalExprsN(); + AddEq(l, (a.Cross(b)).Dot(wn), 0); + } + return; + } + + case Type::CURVE_CURVE_TANGENT: { + bool parallel = true; + int i; + ExprVector dir[2]; + for(i = 0; i < 2; i++) { + EntityBase *e = SK.GetEntity((i == 0) ? entityA : entityB); + bool oth = (i == 0) ? other : other2; + + if(e->type == Entity::Type::ARC_OF_CIRCLE) { + ExprVector center, endpoint; + center = SK.GetEntity(e->point[0])->PointGetExprs(); + endpoint = + SK.GetEntity(e->point[oth ? 2 : 1])->PointGetExprs(); + dir[i] = endpoint.Minus(center); + // We're using the vector from the center of the arc to + // an endpoint; so that's normal to the tangent, not + // parallel. + parallel = !parallel; + } else if(e->type == Entity::Type::CUBIC) { // BRANCH_ALWAYS_TAKEN + if(oth) { + dir[i] = e->CubicGetFinishTangentExprs(); + } else { + dir[i] = e->CubicGetStartTangentExprs(); + } + } else { + ssassert(false, "Unexpected entity types for CURVE_CURVE_TANGENT"); + } + } + if(parallel) { + EntityBase *w = SK.GetEntity(workplane); + ExprVector wn = w->Normal()->NormalExprsN(); + AddEq(l, ((dir[0]).Cross(dir[1])).Dot(wn), 0); + } else { + AddEq(l, (dir[0]).Dot(dir[1]), 0); + } + return; + } + + case Type::PARALLEL: { + EntityBase *ea = SK.GetEntity(entityA), *eb = SK.GetEntity(entityB); + ExprVector a = ea->VectorGetExprsInWorkplane(workplane); + ExprVector b = eb->VectorGetExprsInWorkplane(workplane); + + if(workplane == EntityBase::FREE_IN_3D) { + ExprVector eq = VectorsParallel3d(a, b, valP); + AddEq(l, eq); + } else { + // We use expressions written in workplane csys, so we can assume the workplane + // normal is (0, 0, 1). We can write the equation as: + // Expr *eq = a.Cross(b).Dot(ExprVector::From(0.0, 0.0, 1.0)); + // but this will just result in elimination of x and y terms after dot product. + // We can only use the z expression: + // Expr *eq = a.Cross(b).z; + // but it's more efficient to write it in the terms of pseudo-scalar product: + Expr *eq = (a.x->Times(b.y))->Minus(a.y->Times(b.x)); + AddEq(l, eq, 0); + } + + return; + } + + case Type::WHERE_DRAGGED: { + EntityBase *ep = SK.GetEntity(ptA); + if(workplane == EntityBase::FREE_IN_3D) { + ExprVector ev = ep->PointGetExprs(); + Vector v = ep->PointGetNum(); + + AddEq(l, ev.x->Minus(Expr::From(v.x)), 0); + AddEq(l, ev.y->Minus(Expr::From(v.y)), 1); + AddEq(l, ev.z->Minus(Expr::From(v.z)), 2); + } else { + Expr *u, *v; + ep->PointGetExprsInWorkplane(workplane, &u, &v); + AddEq(l, u->Minus(Expr::From(u->Eval())), 0); + AddEq(l, v->Minus(Expr::From(v->Eval())), 1); + } + return; + } + + case Type::COMMENT: + return; + } + ssassert(false, "Unexpected constraint ID"); +} + diff --git a/src/describescreen.cpp b/src/describescreen.cpp new file mode 100644 index 0000000..17f7361 --- /dev/null +++ b/src/describescreen.cpp @@ -0,0 +1,537 @@ +//----------------------------------------------------------------------------- +// The screens when an entity is selected, that show some description of it-- +// endpoints of the lines, diameter of the circle, etc. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +void TextWindow::ScreenUnselectAll(int link, uint32_t v) { + GraphicsWindow::MenuEdit(Command::UNSELECT_ALL); +} + +void TextWindow::ScreenEditTtfText(int link, uint32_t v) { + hRequest hr = { v }; + Request *r = SK.GetRequest(hr); + + SS.TW.ShowEditControl(10, r->str); + SS.TW.edit.meaning = Edit::TTF_TEXT; + SS.TW.edit.request = hr; +} + +void TextWindow::ScreenSetTtfFont(int link, uint32_t v) { + int i = (int)v; + if(i < 0) return; + if(i >= SS.fonts.l.n) return; + + SS.GW.GroupSelection(); + auto const &gs = SS.GW.gs; + if(gs.entities != 1 || gs.n != 1) return; + + Entity *e = SK.entity.FindByIdNoOops(gs.entity[0]); + if(!e || e->type != Entity::Type::TTF_TEXT || !e->h.isFromRequest()) return; + + Request *r = SK.request.FindByIdNoOops(e->h.request()); + if(!r) return; + + SS.UndoRemember(); + r->font = SS.fonts.l[i].FontFileBaseName(); + SS.MarkGroupDirty(r->group); + SS.ScheduleShowTW(); +} + +void TextWindow::ScreenConstraintToggleReference(int link, uint32_t v) { + hConstraint hc = { v }; + Constraint *c = SK.GetConstraint(hc); + + SS.UndoRemember(); + c->reference = !c->reference; + + SS.ScheduleShowTW(); +} + +void TextWindow::ScreenConstraintShowAsRadius(int link, uint32_t v) { + hConstraint hc = { v }; + Constraint *c = SK.GetConstraint(hc); + + SS.UndoRemember(); + c->other = !c->other; + + SS.ScheduleShowTW(); +} + +void TextWindow::DescribeSelection() { + Printf(false, ""); + + auto const &gs = SS.GW.gs; + if(gs.n == 1 && (gs.points == 1 || gs.entities == 1)) { + Entity *e = SK.GetEntity(gs.points == 1 ? gs.point[0] : gs.entity[0]); + Vector p; + +#define COSTR(p) \ + SS.MmToString((p).x).c_str(), \ + SS.MmToString((p).y).c_str(), \ + SS.MmToString((p).z).c_str() +#define PT_AS_STR "(%Fi%s%E, %Fi%s%E, %Fi%s%E)" +#define PT_AS_NUM "(%Fi%3%E, %Fi%3%E, %Fi%3%E)" + switch(e->type) { + case Entity::Type::POINT_IN_3D: + case Entity::Type::POINT_IN_2D: + case Entity::Type::POINT_N_TRANS: + case Entity::Type::POINT_N_ROT_TRANS: + case Entity::Type::POINT_N_COPY: + case Entity::Type::POINT_N_ROT_AA: + p = e->PointGetNum(); + Printf(false, "%FtPOINT%E at " PT_AS_STR, COSTR(p)); + break; + + case Entity::Type::NORMAL_IN_3D: + case Entity::Type::NORMAL_IN_2D: + case Entity::Type::NORMAL_N_COPY: + case Entity::Type::NORMAL_N_ROT: + case Entity::Type::NORMAL_N_ROT_AA: { + Quaternion q = e->NormalGetNum(); + p = q.RotationN(); + Printf(false, "%FtNORMAL / COORDINATE SYSTEM%E"); + Printf(true, " basis n = " PT_AS_NUM, CO(p)); + p = q.RotationU(); + Printf(false, " u = " PT_AS_NUM, CO(p)); + p = q.RotationV(); + Printf(false, " v = " PT_AS_NUM, CO(p)); + break; + } + case Entity::Type::WORKPLANE: { + p = SK.GetEntity(e->point[0])->PointGetNum(); + Printf(false, "%FtWORKPLANE%E"); + Printf(true, " origin = " PT_AS_STR, COSTR(p)); + Quaternion q = e->Normal()->NormalGetNum(); + p = q.RotationN(); + Printf(true, " normal = " PT_AS_NUM, CO(p)); + break; + } + case Entity::Type::LINE_SEGMENT: { + Vector p0 = SK.GetEntity(e->point[0])->PointGetNum(); + p = p0; + Printf(false, "%FtLINE SEGMENT%E"); + Printf(true, " thru " PT_AS_STR, COSTR(p)); + Vector p1 = SK.GetEntity(e->point[1])->PointGetNum(); + p = p1; + Printf(false, " " PT_AS_STR, COSTR(p)); + Printf(true, " len = %Fi%s%E", + SS.MmToString((p1.Minus(p0).Magnitude())).c_str()); + break; + } + case Entity::Type::CUBIC_PERIODIC: + case Entity::Type::CUBIC: + int pts; + if(e->type == Entity::Type::CUBIC_PERIODIC) { + Printf(false, "%FtPERIODIC C2 CUBIC SPLINE%E"); + pts = (3 + e->extraPoints); + } else if(e->extraPoints > 0) { + Printf(false, "%FtINTERPOLATING C2 CUBIC SPLINE%E"); + pts = (4 + e->extraPoints); + } else { + Printf(false, "%FtCUBIC BEZIER CURVE%E"); + pts = 4; + } + for(int i = 0; i < pts; i++) { + p = SK.GetEntity(e->point[i])->PointGetNum(); + Printf((i==0), " p%d = " PT_AS_STR, i, COSTR(p)); + } + break; + + case Entity::Type::ARC_OF_CIRCLE: { + Printf(false, "%FtARC OF A CIRCLE%E"); + p = SK.GetEntity(e->point[0])->PointGetNum(); + Printf(true, " center = " PT_AS_STR, COSTR(p)); + p = SK.GetEntity(e->point[1])->PointGetNum(); + Printf(true, " endpoints = " PT_AS_STR, COSTR(p)); + p = SK.GetEntity(e->point[2])->PointGetNum(); + Printf(false, " " PT_AS_STR, COSTR(p)); + double r = e->CircleGetRadiusNum(); + Printf(true, " diameter = %Fi%s", SS.MmToString(r*2).c_str()); + Printf(false, " radius = %Fi%s", SS.MmToString(r).c_str()); + double thetas, thetaf, dtheta; + e->ArcGetAngles(&thetas, &thetaf, &dtheta); + Printf(false, " arc len = %Fi%s", SS.MmToString(dtheta*r).c_str()); + break; + } + case Entity::Type::CIRCLE: { + Printf(false, "%FtCIRCLE%E"); + p = SK.GetEntity(e->point[0])->PointGetNum(); + Printf(true, " center = " PT_AS_STR, COSTR(p)); + double r = e->CircleGetRadiusNum(); + Printf(true, " diameter = %Fi%s", SS.MmToString(r*2).c_str()); + Printf(false, " radius = %Fi%s", SS.MmToString(r).c_str()); + break; + } + case Entity::Type::FACE_NORMAL_PT: + case Entity::Type::FACE_XPROD: + case Entity::Type::FACE_N_ROT_TRANS: + case Entity::Type::FACE_N_ROT_AA: + case Entity::Type::FACE_N_TRANS: + Printf(false, "%FtPLANE FACE%E"); + p = e->FaceGetNormalNum(); + Printf(true, " normal = " PT_AS_NUM, CO(p)); + p = e->FaceGetPointNum(); + Printf(false, " thru = " PT_AS_STR, COSTR(p)); + break; + + case Entity::Type::TTF_TEXT: { + Printf(false, "%FtTRUETYPE FONT TEXT%E"); + Printf(true, " font = '%Fi%s%E'", e->font.c_str()); + if(e->h.isFromRequest()) { + Printf(false, " text = '%Fi%s%E' %Fl%Ll%f%D[change]%E", + e->str.c_str(), &ScreenEditTtfText, e->h.request().v); + Printf(true, " select new font"); + SS.fonts.LoadAll(); + // Not using range-for here because we use i inside the output. + for(int i = 0; i < SS.fonts.l.n; i++) { + TtfFont *tf = &(SS.fonts.l[i]); + if(e->font == tf->FontFileBaseName()) { + Printf(false, "%Bp %s", + (i & 1) ? 'd' : 'a', + tf->name.c_str()); + } else { + Printf(false, "%Bp %f%D%Fl%Ll%s%E%Bp", + (i & 1) ? 'd' : 'a', + &ScreenSetTtfFont, i, + tf->name.c_str(), + (i & 1) ? 'd' : 'a'); + } + } + } else { + Printf(false, " text = '%Fi%s%E'", e->str.c_str()); + } + break; + } + case Entity::Type::IMAGE: { + Printf(false, "%FtIMAGE%E"); + Platform::Path relativePath = e->file.RelativeTo(SS.saveFile.Parent()); + if(relativePath.IsEmpty()) { + Printf(true, " file = '%Fi%s%E'", e->file.raw.c_str()); + } else { + Printf(true, " file = '%Fi%s%E'", relativePath.raw.c_str()); + } + break; + } + + default: + Printf(true, "%Ft?? ENTITY%E"); + break; + } + + Printf(false, ""); + if(e->h.isFromRequest()) { + Request *r = SK.GetRequest(e->h.request()); + if(e->h == r->h.entity(0)) { + Printf(false, "%FtFROM REQUEST%E %s", + r->DescriptionString().c_str()); + } else { + Printf(false, "%FtFROM REQUEST%E %Fl%Ll%D%f%h%s%E", + r->h.v, (&TextWindow::ScreenSelectRequest), &(TextWindow::ScreenHoverRequest), + r->DescriptionString().c_str()); + } + } + Group *g = SK.GetGroup(e->group); + Printf(false, "%FtIN GROUP%E %Fl%Ll%D%f%s%E", + g->h.v, (&TextWindow::ScreenSelectGroup), + g->DescriptionString().c_str()); + if(e->workplane == Entity::FREE_IN_3D) { + Printf(false, "%FtNOT LOCKED IN WORKPLANE%E"); + } else { + Entity *w = SK.GetEntity(e->workplane); + if(w->h.isFromRequest()) { + Printf(false, "%FtIN WORKPLANE%E %Fl%Ll%D%f%h%s%E", + w->h.request().v, + (&TextWindow::ScreenSelectRequest), &(TextWindow::ScreenHoverRequest), + w->DescriptionString().c_str()); + } else { + Printf(false, "%FtIN WORKPLANE%E %Fl%Ll%D%f%h%s%E", + w->h.group().v, + (&TextWindow::ScreenSelectGroup), (&TextWindow::ScreenHoverGroupWorkplane), + w->DescriptionString().c_str()); + } + } + if(e->IsStylable()) { + if(e->style.v) { + Style *s = Style::Get(e->style); + Printf(false, "%FtIN STYLE%E %Fl%Ll%D%f%s%E", + s->h.v, (&TextWindow::ScreenShowStyleInfo), + s->DescriptionString().c_str()); + } else { + Printf(false, "%FtIN STYLE%E none"); + } + } + if(e->construction) { + Printf(false, "%FtCONSTRUCTION"); + } + + std::vector lhc = {}; + auto FindConstraints = [&](hEntity he) { + for(const Constraint &c : SK.constraint) { + if(!(c.ptA == he || c.ptB == he || + c.entityA == he || c.entityB == he || c.entityC == he || c.entityD == he)) + continue; + lhc.push_back(c.h); + } + }; + FindConstraints(e->h); + if(!e->IsPoint()) { + for(int i = 0; i < MAX_POINTS_IN_ENTITY; i++) { + if(e->point[i].v == 0) break; + FindConstraints(e->point[i]); + } + } + + std::sort(lhc.begin(), lhc.end()); + lhc.erase(std::unique(lhc.begin(), lhc.end()), lhc.end()); + + auto ListConstraints = [&](bool reference) { + bool first = true; + int a = 0; + for(hConstraint hc : lhc) { + Constraint *c = SK.GetConstraint(hc); + if(c->reference != reference) continue; + if(first) { + first = false; + if(reference) { + Printf(true, "%FtMEASURED BY:%E"); + } else { + Printf(true, "%FtCONSTRAINED BY:%E"); + } + } + Printf(false, "%Bp %Fl%Ll%D%f%h%s%E", + (a & 1) ? 'd' : 'a', + c->h.v, (&TextWindow::ScreenSelectConstraint), + (&TextWindow::ScreenHoverConstraint), + c->DescriptionString().c_str()); + a++; + } + }; + ListConstraints(/*reference=*/false); + ListConstraints(/*reference=*/true); + } else if(gs.n == 2 && gs.points == 2) { + Printf(false, "%FtTWO POINTS"); + Vector p0 = SK.GetEntity(gs.point[0])->PointGetNum(); + Printf(true, " at " PT_AS_STR, COSTR(p0)); + Vector p1 = SK.GetEntity(gs.point[1])->PointGetNum(); + Printf(false, " " PT_AS_STR, COSTR(p1)); + double d = (p1.Minus(p0)).Magnitude(); + Printf(true, " d = %Fi%s", SS.MmToString(d).c_str()); + } else if(gs.n == 2 && gs.points == 1 && gs.circlesOrArcs == 1) { + Entity *ec = SK.GetEntity(gs.entity[0]); + if(ec->type == Entity::Type::CIRCLE) { + Printf(false, "%FtPOINT AND A CIRCLE"); + } else if(ec->type == Entity::Type::ARC_OF_CIRCLE) { + Printf(false, "%FtPOINT AND AN ARC"); + } else ssassert(false, "Unexpected entity type"); + Vector p = SK.GetEntity(gs.point[0])->PointGetNum(); + Printf(true, " pt at " PT_AS_STR, COSTR(p)); + Vector c = SK.GetEntity(ec->point[0])->PointGetNum(); + Printf(true, " center = " PT_AS_STR, COSTR(c)); + double r = ec->CircleGetRadiusNum(); + Printf(false, " diameter = %Fi%s", SS.MmToString(r*2).c_str()); + Printf(false, " radius = %Fi%s", SS.MmToString(r).c_str()); + double d = (p.Minus(c)).Magnitude() - r; + Printf(true, " distance = %Fi%s", SS.MmToString(d).c_str()); + } else if(gs.n == 2 && gs.faces == 1 && gs.points == 1) { + Printf(false, "%FtA POINT AND A PLANE FACE"); + Vector pt = SK.GetEntity(gs.point[0])->PointGetNum(); + Printf(true, " point = " PT_AS_STR, COSTR(pt)); + Vector n = SK.GetEntity(gs.face[0])->FaceGetNormalNum(); + Printf(true, " plane normal = " PT_AS_NUM, CO(n)); + Vector pl = SK.GetEntity(gs.face[0])->FaceGetPointNum(); + Printf(false, " plane thru = " PT_AS_STR, COSTR(pl)); + double dd = n.Dot(pl) - n.Dot(pt); + Printf(true, " distance = %Fi%s", SS.MmToString(dd).c_str()); + } else if(gs.n == 3 && gs.points == 2 && gs.vectors == 1) { + Printf(false, "%FtTWO POINTS AND A VECTOR"); + Vector p0 = SK.GetEntity(gs.point[0])->PointGetNum(); + Printf(true, " pointA = " PT_AS_STR, COSTR(p0)); + Vector p1 = SK.GetEntity(gs.point[1])->PointGetNum(); + Printf(false, " pointB = " PT_AS_STR, COSTR(p1)); + Vector v = SK.GetEntity(gs.vector[0])->VectorGetNum(); + v = v.WithMagnitude(1); + Printf(true, " vector = " PT_AS_NUM, CO(v)); + double d = (p1.Minus(p0)).Dot(v); + Printf(true, " proj_d = %Fi%s", SS.MmToString(d).c_str()); + } else if(gs.n == 2 && gs.lineSegments == 1 && gs.points == 1) { + Entity *ln = SK.GetEntity(gs.entity[0]); + Vector lp0 = SK.GetEntity(ln->point[0])->PointGetNum(), + lp1 = SK.GetEntity(ln->point[1])->PointGetNum(); + Printf(false, "%FtLINE SEGMENT AND POINT%E"); + Printf(true, " ln thru " PT_AS_STR, COSTR(lp0)); + Printf(false, " " PT_AS_STR, COSTR(lp1)); + Entity *p = SK.GetEntity(gs.point[0]); + Vector pp = p->PointGetNum(); + Printf(true, " point " PT_AS_STR, COSTR(pp)); + Printf(true, " pt-ln distance = %Fi%s%E", + SS.MmToString(pp.DistanceToLine(lp0, lp1.Minus(lp0))).c_str()); + hEntity wrkpl = SS.GW.ActiveWorkplane(); + if(wrkpl != Entity::FREE_IN_3D && !(p->workplane == wrkpl && ln->workplane == wrkpl)) { + Vector ppw = pp.ProjectInto(wrkpl); + Vector lp0w = lp0.ProjectInto(wrkpl); + Vector lp1w = lp1.ProjectInto(wrkpl); + Printf(false, " or distance = %Fi%s%E (in workplane)", + SS.MmToString(ppw.DistanceToLine(lp0w, lp1w.Minus(lp0w))).c_str()); + } + } else if(gs.n == 2 && gs.vectors == 2) { + Printf(false, "%FtTWO VECTORS"); + + Vector v0 = SK.GetEntity(gs.entity[0])->VectorGetNum(), + v1 = SK.GetEntity(gs.entity[1])->VectorGetNum(); + v0 = v0.WithMagnitude(1); + v1 = v1.WithMagnitude(1); + + Printf(true, " vectorA = " PT_AS_NUM, CO(v0)); + Printf(false, " vectorB = " PT_AS_NUM, CO(v1)); + + double theta = acos(v0.Dot(v1)); + Printf(true, " angle = %Fi%2%E degrees", theta*180/PI); + while(theta < PI/2) theta += PI; + while(theta > PI/2) theta -= PI; + Printf(false, " or angle = %Fi%2%E (mod 180)", theta*180/PI); + } else if(gs.n == 2 && gs.faces == 2) { + Printf(false, "%FtTWO PLANE FACES"); + + Vector n0 = SK.GetEntity(gs.face[0])->FaceGetNormalNum(); + Printf(true, " planeA normal = " PT_AS_NUM, CO(n0)); + Vector p0 = SK.GetEntity(gs.face[0])->FaceGetPointNum(); + Printf(false, " planeA thru = " PT_AS_STR, COSTR(p0)); + + Vector n1 = SK.GetEntity(gs.face[1])->FaceGetNormalNum(); + Printf(true, " planeB normal = " PT_AS_NUM, CO(n1)); + Vector p1 = SK.GetEntity(gs.face[1])->FaceGetPointNum(); + Printf(false, " planeB thru = " PT_AS_STR, COSTR(p1)); + + double theta = acos(n0.Dot(n1)); + Printf(true, " angle = %Fi%2%E degrees", theta*180/PI); + while(theta < PI/2) theta += PI; + while(theta > PI/2) theta -= PI; + Printf(false, " or angle = %Fi%2%E (mod 180)", theta*180/PI); + + if(fabs(theta) < 0.01) { + double d = (p1.Minus(p0)).Dot(n0); + Printf(true, " distance = %Fi%s", SS.MmToString(d).c_str()); + } + } else if(gs.n == 0 && gs.stylables > 0) { + Printf(false, "%FtSELECTED:%E comment text"); + } else if(gs.n == 0 && gs.constraints == 1) { + Constraint *c = SK.GetConstraint(gs.constraint[0]); + const std::string &desc = c->DescriptionString().c_str(); + + if(c->type == Constraint::Type::COMMENT) { + Printf(false, "%FtCOMMENT%E %s", desc.c_str()); + } else if(c->HasLabel()) { + if(c->reference) { + Printf(false, "%FtREFERENCE%E %s", desc.c_str()); + } else { + Printf(false, "%FtDIMENSION%E %s", desc.c_str()); + } + Printf(true, " %Fd%f%D%Ll%s reference", + &ScreenConstraintToggleReference, gs.constraint[0].v, + c->reference ? CHECK_TRUE : CHECK_FALSE); + if(c->type == Constraint::Type::DIAMETER) { + Printf(false, " %Fd%f%D%Ll%s use radius", + &ScreenConstraintShowAsRadius, gs.constraint[0].v, + c->other ? CHECK_TRUE : CHECK_FALSE); + } + } else { + Printf(false, "%FtCONSTRAINT%E %s", desc.c_str()); + } + + if(c->IsProjectible()) { + if(c->workplane == Entity::FREE_IN_3D) { + Printf(true, "%FtNOT PROJECTED TO WORKPLANE%E"); + } else { + Entity *w = SK.GetEntity(c->workplane); + if(w->h.isFromRequest()) { + Printf(true, "%FtIN WORKPLANE%E %Fl%Ll%D%f%h%s%E", + w->h.request().v, + (&TextWindow::ScreenSelectRequest), &(TextWindow::ScreenHoverRequest), + w->DescriptionString().c_str()); + } else { + Printf(true, "%FtIN WORKPLANE%E %Fl%Ll%D%f%h%s%E", + w->h.group().v, + (&TextWindow::ScreenSelectGroup), (&TextWindow::ScreenHoverGroupWorkplane), + w->DescriptionString().c_str()); + } + } + } + + std::vector lhe = {}; + lhe.push_back(c->ptA); + lhe.push_back(c->ptB); + lhe.push_back(c->entityA); + lhe.push_back(c->entityB); + lhe.push_back(c->entityC); + lhe.push_back(c->entityD); + + auto it = std::remove_if(lhe.begin(), lhe.end(), [](hEntity he) { + return he == Entity::NO_ENTITY || !he.isFromRequest(); + }); + lhe.erase(it, lhe.end()); + + if(!lhe.empty()) { + if(c->reference) { + Printf(true, "%FtMEASURES:%E"); + } else { + Printf(true, "%FtCONSTRAINS:%E"); + } + + int a = 0; + for(hEntity he : lhe) { + Entity *e = SK.GetEntity(he); + Printf(false, "%Bp %Fl%Ll%D%f%h%s%E", + (a & 1) ? 'd' : 'a', + e->h.v, (&TextWindow::ScreenSelectEntity), + &(TextWindow::ScreenHoverEntity), + e->DescriptionString().c_str()); + a++; + } + } + } else { + int n = SS.GW.selection.n; + Printf(false, "%FtSELECTED:%E %d item%s", n, n == 1 ? "" : "s"); + } + + if(shown.screen == Screen::STYLE_INFO && + shown.style.v >= Style::FIRST_CUSTOM && gs.stylables > 0) + { + // If we are showing a screen for a particular style, then offer the + // option to assign our selected entities to that style. + Style *s = Style::Get(shown.style); + Printf(true, "%Fl%D%f%Ll(assign to style %s)%E", + shown.style.v, + &ScreenAssignSelectionToStyle, + s->DescriptionString().c_str()); + } + // If any of the selected entities have an assigned style, then offer + // the option to remove that style. + bool styleAssigned = false; + for(int i = 0; i < gs.entities; i++) { + Entity *e = SK.GetEntity(gs.entity[i]); + if(e->style.v != 0) { + styleAssigned = true; + } + } + for(int i = 0; i < gs.constraints; i++) { + Constraint *c = SK.GetConstraint(gs.constraint[i]); + if(c->type == Constraint::Type::COMMENT && c->disp.style.v != 0) { + styleAssigned = true; + } + } + if(styleAssigned) { + Printf(true, "%Fl%D%f%Ll(remove assigned style)%E", + 0, + &ScreenAssignSelectionToStyle); + } + + Printf(true, "%Fl%f%Ll(unselect all)%E", &TextWindow::ScreenUnselectAll); +} + +void TextWindow::GoToScreen(Screen screen) { + shown.screen = screen; +} + diff --git a/src/draw.cpp b/src/draw.cpp new file mode 100644 index 0000000..ccaeb96 --- /dev/null +++ b/src/draw.cpp @@ -0,0 +1,938 @@ +//----------------------------------------------------------------------------- +// The root function to paint our graphics window, after setting up all the +// views and such appropriately. Also contains all the stuff to manage the +// selection. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +bool GraphicsWindow::Selection::Equals(Selection *b) { + if(entity != b->entity) return false; + if(constraint != b->constraint) return false; + return true; +} + +bool GraphicsWindow::Selection::IsEmpty() { + if(entity.v) return false; + if(constraint.v) return false; + return true; +} + +bool GraphicsWindow::Selection::HasEndpoints() { + if(!entity.v) return false; + Entity *e = SK.GetEntity(entity); + return e->HasEndpoints(); +} + +void GraphicsWindow::Selection::Clear() { + entity.v = constraint.v = 0; + emphasized = false; +} + +void GraphicsWindow::Selection::Draw(bool isHovered, Canvas *canvas) { + const Camera &camera = canvas->GetCamera(); + + std::vector refs; + if(entity.v) { + Entity *e = SK.GetEntity(entity); + e->Draw(isHovered ? Entity::DrawAs::HOVERED : + Entity::DrawAs::SELECTED, + canvas); + if(emphasized) { + e->GetReferencePoints(&refs); + } + } + if(constraint.v) { + Constraint *c = SK.GetConstraint(constraint); + c->Draw(isHovered ? Constraint::DrawAs::HOVERED : + Constraint::DrawAs::SELECTED, + canvas); + if(emphasized) { + c->GetReferencePoints(camera, &refs); + } + } + if(emphasized && (constraint.v || entity.v)) { + // We want to emphasize this constraint or entity, by drawing a thick + // line from the top left corner of the screen to the reference point(s) + // of that entity or constraint. + Canvas::Stroke strokeEmphasis = {}; + strokeEmphasis.layer = Canvas::Layer::FRONT; + strokeEmphasis.color = Style::Color(Style::HOVERED).WithAlpha(50); + strokeEmphasis.width = 40; + strokeEmphasis.unit = Canvas::Unit::PX; + Canvas::hStroke hcsEmphasis = canvas->GetStroke(strokeEmphasis); + + Point2d topLeftScreen; + topLeftScreen.x = -(double)camera.width / 2; + topLeftScreen.y = (double)camera.height / 2; + Vector topLeft = camera.UnProjectPoint(topLeftScreen); + + auto it = std::unique(refs.begin(), refs.end(), + [](Vector a, Vector b) { return a.Equals(b); }); + refs.erase(it, refs.end()); + for(Vector p : refs) { + canvas->DrawLine(topLeft, p, hcsEmphasis); + } + } +} + +void GraphicsWindow::ClearSelection() { + selection.Clear(); + SS.ScheduleShowTW(); + Invalidate(); +} + +void GraphicsWindow::ClearNonexistentSelectionItems() { + bool change = false; + Selection *s; + selection.ClearTags(); + for(s = selection.First(); s; s = selection.NextAfter(s)) { + if(s->constraint.v && !(SK.constraint.FindByIdNoOops(s->constraint))) { + s->tag = 1; + change = true; + } + if(s->entity.v && !(SK.entity.FindByIdNoOops(s->entity))) { + s->tag = 1; + change = true; + } + } + selection.RemoveTagged(); + if(change) Invalidate(); +} + +//----------------------------------------------------------------------------- +// Is this entity/constraint selected? +//----------------------------------------------------------------------------- +bool GraphicsWindow::IsSelected(hEntity he) { + Selection s = {}; + s.entity = he; + return IsSelected(&s); +} +bool GraphicsWindow::IsSelected(Selection *st) { + Selection *s; + for(s = selection.First(); s; s = selection.NextAfter(s)) { + if(s->Equals(st)) { + return true; + } + } + return false; +} + +//----------------------------------------------------------------------------- +// Unselect an item, if it is selected. We can either unselect just that item, +// or also unselect any coincident points. The latter is useful if the user +// somehow selects two coincident points (like with select all), because it +// would otherwise be impossible to de-select the lower of the two. +//----------------------------------------------------------------------------- +void GraphicsWindow::MakeUnselected(hEntity he, bool coincidentPointTrick) { + Selection stog = {}; + stog.entity = he; + MakeUnselected(&stog, coincidentPointTrick); +} +void GraphicsWindow::MakeUnselected(Selection *stog, bool coincidentPointTrick){ + if(stog->IsEmpty()) return; + + Selection *s; + + // If an item was selected, then we just un-select it. + selection.ClearTags(); + for(s = selection.First(); s; s = selection.NextAfter(s)) { + if(s->Equals(stog)) { + s->tag = 1; + } + } + // If two points are coincident, then it's impossible to hover one of + // them. But make sure to deselect both, to avoid mysterious seeming + // inability to deselect if the bottom one did somehow get selected. + if(stog->entity.v && coincidentPointTrick) { + Entity *e = SK.GetEntity(stog->entity); + if(e->IsPoint()) { + Vector ep = e->PointGetNum(); + for(s = selection.First(); s; s = selection.NextAfter(s)) { + if(!s->entity.v) continue; + if(s->entity == stog->entity) + continue; + Entity *se = SK.GetEntity(s->entity); + if(!se->IsPoint()) continue; + if(ep.Equals(se->PointGetNum())) { + s->tag = 1; + } + } + } + } + selection.RemoveTagged(); +} + +//----------------------------------------------------------------------------- +// Select an item, if it isn't selected already. +//----------------------------------------------------------------------------- +void GraphicsWindow::MakeSelected(hEntity he) { + Selection stog = {}; + stog.entity = he; + MakeSelected(&stog); +} + +void GraphicsWindow::MakeSelected(hConstraint hc) { + Selection stog = {}; + stog.constraint = hc; + MakeSelected(&stog); +} + +void GraphicsWindow::MakeSelected(Selection *stog) { + if(stog->IsEmpty()) return; + if(IsSelected(stog)) return; + + if(stog->entity.v != 0 && SK.GetEntity(stog->entity)->IsFace()) { + // In the interest of speed for the triangle drawing code, + // only two faces may be selected at a time. + int c = 0; + Selection *s; + selection.ClearTags(); + for(s = selection.First(); s; s = selection.NextAfter(s)) { + hEntity he = s->entity; + if(he.v != 0 && SK.GetEntity(he)->IsFace()) { + c++; + if(c >= 2) s->tag = 1; + } + } + selection.RemoveTagged(); + } + + selection.Add(stog); +} + +//----------------------------------------------------------------------------- +// Select everything that lies within the marquee view-aligned rectangle. +//----------------------------------------------------------------------------- +void GraphicsWindow::SelectByMarquee() { + Point2d marqueePoint = ProjectPoint(orig.marqueePoint); + BBox marqueeBBox = BBox::From(Vector::From(marqueePoint.x, marqueePoint.y, VERY_NEGATIVE), + Vector::From(orig.mouse.x, orig.mouse.y, VERY_POSITIVE)); + + Entity *e; + for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) { + if(e->group != SS.GW.activeGroup) continue; + if(e->IsFace() || e->IsDistance()) continue; + if(!e->IsVisible()) continue; + + bool entityHasBBox; + BBox entityBBox = e->GetOrGenerateScreenBBox(&entityHasBBox); + if(entityHasBBox && entityBBox.Overlaps(marqueeBBox)) { + MakeSelected(e->h); + } + } +} + +//----------------------------------------------------------------------------- +// Sort the selection according to various critieria: the entities and +// constraints separately, counts of certain types of entities (circles, +// lines, etc.), and so on. +//----------------------------------------------------------------------------- +void GraphicsWindow::GroupSelection() { + gs = {}; + int i; + for(i = 0; i < selection.n; i++) { + Selection *s = &(selection[i]); + if(s->entity.v) { + (gs.n)++; + + Entity *e = SK.entity.FindById(s->entity); + + if(e->IsStylable()) gs.stylables++; + + // A list of points, and a list of all entities that aren't points. + if(e->IsPoint()) { + gs.points++; + gs.point.push_back(s->entity); + } else { + gs.entities++; + gs.entity.push_back(s->entity); + } + + // And an auxiliary list of normals, including normals from + // workplanes. + if(e->IsNormal()) { + gs.anyNormals++; + gs.anyNormal.push_back(s->entity); + } else if(e->IsWorkplane()) { + gs.anyNormals++; + gs.anyNormal.push_back(e->Normal()->h); + } + + // And of vectors (i.e., stuff with a direction to constrain) + if(e->HasVector()) { + gs.vectors++; + gs.vector.push_back(s->entity); + } + + // Faces (which are special, associated/drawn with triangles) + if(e->IsFace()) { + gs.faces++; + gs.face.push_back(s->entity); + } + + if(e->HasEndpoints()) { + (gs.withEndpoints)++; + } + + // And some aux counts too + switch(e->type) { + case Entity::Type::WORKPLANE: (gs.workplanes)++; break; + case Entity::Type::LINE_SEGMENT: (gs.lineSegments)++; break; + case Entity::Type::CUBIC: (gs.cubics)++; break; + case Entity::Type::CUBIC_PERIODIC: (gs.periodicCubics)++; break; + + case Entity::Type::ARC_OF_CIRCLE: + (gs.circlesOrArcs)++; + (gs.arcs)++; + break; + + case Entity::Type::CIRCLE: (gs.circlesOrArcs)++; break; + + default: break; + } + } + if(s->constraint.v) { + gs.constraints++; + gs.constraint.push_back(s->constraint); + Constraint *c = SK.GetConstraint(s->constraint); + if(c->IsStylable()) gs.stylables++; + if(c->HasLabel()) gs.constraintLabels++; + } + } +} + +Camera GraphicsWindow::GetCamera() const { + Camera camera = {}; + if(window) { + window->GetContentSize(&camera.width, &camera.height); + camera.pixelRatio = window->GetDevicePixelRatio(); + camera.gridFit = (window->GetDevicePixelRatio() == 1); + } else { // solvespace-cli + camera.width = 297.0; // A4? Whatever... + camera.height = 210.0; + camera.pixelRatio = 1.0; + camera.gridFit = camera.pixelRatio == 1.0; + } + camera.offset = offset; + camera.projUp = projUp; + camera.projRight = projRight; + camera.scale = scale; + camera.tangent = SS.CameraTangent(); + return camera; +} + +Lighting GraphicsWindow::GetLighting() const { + Lighting lighting = {}; + lighting.backgroundColor = SS.backgroundColor; + lighting.ambientIntensity = SS.ambientIntensity; + lighting.lightIntensity[0] = SS.lightIntensity[0]; + lighting.lightIntensity[1] = SS.lightIntensity[1]; + lighting.lightDirection[0] = SS.lightDir[0]; + lighting.lightDirection[1] = SS.lightDir[1]; + return lighting; +} + +GraphicsWindow::Selection GraphicsWindow::ChooseFromHoverToSelect() { + Selection sel = {}; + if(hoverList.IsEmpty()) + return sel; + + Group *activeGroup = SK.GetGroup(SS.GW.activeGroup); + int bestOrder = -1; + int bestZIndex = 0; + double bestDepth = VERY_POSITIVE; + + for(const Hover &hov : hoverList) { + hGroup hg = {}; + if(hov.selection.entity.v != 0) { + hg = SK.GetEntity(hov.selection.entity)->group; + } else if(hov.selection.constraint.v != 0) { + hg = SK.GetConstraint(hov.selection.constraint)->group; + } + + Group *g = SK.GetGroup(hg); + if(g->order > activeGroup->order) continue; + if(bestOrder != -1 && (bestOrder > g->order || bestZIndex > hov.zIndex)) continue; + // we have hov.zIndex is >= best and hov.group is >= best (but not > active group) + if(hov.depth > bestDepth && bestOrder == g->order && bestZIndex == hov.zIndex) continue; + bestOrder = g->order; + bestZIndex = hov.zIndex; + bestDepth = hov.depth; + sel = hov.selection; + } + return sel; +} + +// This uses the same logic as hovering and static entity selection +// but ignores points known not to be draggable +GraphicsWindow::Selection GraphicsWindow::ChooseFromHoverToDrag() { + Selection sel = {}; + if(hoverList.IsEmpty()) + return sel; + + Group *activeGroup = SK.GetGroup(SS.GW.activeGroup); + int bestOrder = -1; + int bestZIndex = 0; + double bestDepth = VERY_POSITIVE; + + for(const Hover &hov : hoverList) { + hGroup hg = {}; + if(hov.selection.entity.v != 0) { + Entity *e = SK.GetEntity(hov.selection.entity); + if (!e->CanBeDragged()) continue; + hg = e->group; + } else if(hov.selection.constraint.v != 0) { + hg = SK.GetConstraint(hov.selection.constraint)->group; + } + + Group *g = SK.GetGroup(hg); + if(g->order > activeGroup->order) continue; + if(bestOrder != -1 && (bestOrder > g->order || bestZIndex > hov.zIndex)) continue; + // we have hov.zIndex is >= best and hov.group is >= best (but not > active group) + if(hov.depth > bestDepth && bestOrder == g->order && bestZIndex == hov.zIndex) continue; + bestOrder = g->order; + bestZIndex = hov.zIndex; + sel = hov.selection; + } + return sel; +} + +void GraphicsWindow::HitTestMakeSelection(Point2d mp) { + hoverList = {}; + Selection sel = {}; + + // Did the view projection change? If so, invalidate bounding boxes. + if(!offset.EqualsExactly(cached.offset) || + !projRight.EqualsExactly(cached.projRight) || + !projUp.EqualsExactly(cached.projUp) || + EXACT(scale != cached.scale)) { + cached.offset = offset; + cached.projRight = projRight; + cached.projUp = projUp; + cached.scale = scale; + for(Entity *e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) { + e->screenBBoxValid = false; + } + } + + ObjectPicker canvas = {}; + canvas.camera = GetCamera(); + canvas.selRadius = 10.0; + canvas.point = mp; + canvas.maxZIndex = -1; + + // Always do the entities; we might be dragging something that should + // be auto-constrained, and we need the hover for that. + for(Entity &e : SK.entity) { + if(!e.IsVisible()) continue; + + // If faces aren't selectable, image entities aren't either. + if(e.type == Entity::Type::IMAGE && !showFaces) continue; + + // Don't hover whatever's being dragged. + if(IsFromPending(e.h.request())) { + // The one exception is when we're creating a new cubic; we + // want to be able to hover the first point, because that's + // how we turn it into a periodic spline. + if(!e.IsPoint()) continue; + if(!e.h.isFromRequest()) continue; + Request *r = SK.GetRequest(e.h.request()); + if(r->type != Request::Type::CUBIC) continue; + if(r->extraPoints < 2) continue; + if(e.h.v != r->h.entity(1).v) continue; + } + + if(canvas.Pick([&]{ e.Draw(Entity::DrawAs::DEFAULT, &canvas); })) { + Hover hov = {}; + hov.distance = canvas.minDistance; + hov.zIndex = canvas.maxZIndex; + hov.depth = canvas.minDepth; + hov.selection.entity = e.h; + hoverList.Add(&hov); + } + } + + // The constraints and faces happen only when nothing's in progress. + if(pending.operation == Pending::NONE) { + // Constraints + for(Constraint &c : SK.constraint) { + if(canvas.Pick([&]{ c.Draw(Constraint::DrawAs::DEFAULT, &canvas); })) { + Hover hov = {}; + hov.distance = canvas.minDistance; + hov.zIndex = canvas.maxZIndex; + hov.selection.constraint = c.h; + hoverList.Add(&hov); + } + } + } + + std::sort(hoverList.begin(), hoverList.end(), + [](const Hover &a, const Hover &b) { + if(a.zIndex == b.zIndex) return a.distance < b.distance; + return a.zIndex > b.zIndex; + }); + sel = ChooseFromHoverToSelect(); + + if(pending.operation == Pending::NONE) { + // Faces, from the triangle mesh; these are lowest priority + if(sel.constraint.v == 0 && sel.entity.v == 0 && showShaded && showFaces) { + Group *g = SK.GetGroup(activeGroup); + SMesh *m = &(g->displayMesh); + + uint32_t v = m->FirstIntersectionWith(mp); + if(v) { + sel.entity.v = v; + } + } + } + + canvas.Clear(); + + if(!sel.Equals(&hover)) { + hover = sel; + Invalidate(); + } +} + +//----------------------------------------------------------------------------- +// Project a point in model space to screen space, exactly as gl would; return +// units are pixels. +//----------------------------------------------------------------------------- +Point2d GraphicsWindow::ProjectPoint(Vector p) { + Vector p3 = ProjectPoint3(p); + Point2d p2 = { p3.x, p3.y }; + return p2; +} +//----------------------------------------------------------------------------- +// Project a point in model space to screen space, exactly as gl would; return +// units are pixels. The z coordinate is also returned, also in pixels. +//----------------------------------------------------------------------------- +Vector GraphicsWindow::ProjectPoint3(Vector p) { + double w; + Vector r = ProjectPoint4(p, &w); + return r.ScaledBy(scale/w); +} +//----------------------------------------------------------------------------- +// Project a point in model space halfway into screen space. The scale is +// not applied, and the perspective divide isn't applied; instead the w +// coordinate is returned separately. +//----------------------------------------------------------------------------- +Vector GraphicsWindow::ProjectPoint4(Vector p, double *w) { + p = p.Plus(offset); + + Vector r; + r.x = p.Dot(projRight); + r.y = p.Dot(projUp); + r.z = p.Dot(projUp.Cross(projRight)); + + *w = 1 + r.z*SS.CameraTangent()*scale; + return r; +} + +//----------------------------------------------------------------------------- +// Return a point in the plane parallel to the screen and through the offset, +// that projects onto the specified (x, y) coordinates. +//----------------------------------------------------------------------------- +Vector GraphicsWindow::UnProjectPoint(Point2d p) { + Vector orig = offset.ScaledBy(-1); + + // Note that we ignoring the effects of perspective. Since our returned + // point has the same component normal to the screen as the offset, it + // will have z = 0 after the rotation is applied, thus w = 1. So this is + // correct. + orig = orig.Plus(projRight.ScaledBy(p.x / scale)).Plus( + projUp. ScaledBy(p.y / scale)); + return orig; +} + +Vector GraphicsWindow::UnProjectPoint3(Vector p) { + p.z = p.z / (scale - p.z * SS.CameraTangent() * scale); + double w = 1 + p.z * SS.CameraTangent() * scale; + p.x *= w / scale; + p.y *= w / scale; + + Vector orig = offset.ScaledBy(-1); + orig = orig.Plus(projRight.ScaledBy(p.x)).Plus( + projUp. ScaledBy(p.y).Plus( + projRight.Cross(projUp). ScaledBy(p.z))); + return orig; +} + +void GraphicsWindow::NormalizeProjectionVectors() { + if(projRight.Magnitude() < LENGTH_EPS) { + projRight = Vector::From(1, 0, 0); + } + + Vector norm = projRight.Cross(projUp); + // If projRight and projUp somehow ended up parallel, then pick an + // arbitrary projUp normal to projRight. + if(norm.Magnitude() < LENGTH_EPS) { + norm = projRight.Normal(0); + } + projUp = norm.Cross(projRight); + + projUp = projUp.WithMagnitude(1); + projRight = projRight.WithMagnitude(1); +} + +void GraphicsWindow::DrawSnapGrid(Canvas *canvas) { + if(!LockedInWorkplane()) return; + + const Camera &camera = canvas->GetCamera(); + double width = camera.width, + height = camera.height; + + hEntity he = ActiveWorkplane(); + EntityBase *wrkpl = SK.GetEntity(he), + *norm = wrkpl->Normal(); + Vector n = projUp.Cross(projRight); + Vector wu, wv, wn, wp; + wp = SK.GetEntity(wrkpl->point[0])->PointGetNum(); + wu = norm->NormalU(); + wv = norm->NormalV(); + wn = norm->NormalN(); + + double g = SS.gridSpacing; + + double umin = VERY_POSITIVE, umax = VERY_NEGATIVE, + vmin = VERY_POSITIVE, vmax = VERY_NEGATIVE; + int a; + for(a = 0; a < 4; a++) { + // Ideally, we would just do +/- half the width and height; but + // allow some extra slop for rounding. + Vector horiz = projRight.ScaledBy((0.6*width)/scale + 2*g), + vert = projUp. ScaledBy((0.6*height)/scale + 2*g); + if(a == 2 || a == 3) horiz = horiz.ScaledBy(-1); + if(a == 1 || a == 3) vert = vert. ScaledBy(-1); + Vector tp = horiz.Plus(vert).Minus(offset); + + // Project the point into our grid plane, normal to the screen + // (not to the grid plane). If the plane is on edge then this is + // impossible so don't try to draw the grid. + bool parallel; + Vector tpp = Vector::AtIntersectionOfPlaneAndLine( + wn, wn.Dot(wp), + tp, tp.Plus(n), + ¶llel); + if(parallel) return; + + tpp = tpp.Minus(wp); + double uu = tpp.Dot(wu), + vv = tpp.Dot(wv); + + umin = min(uu, umin); + umax = max(uu, umax); + vmin = min(vv, vmin); + vmax = max(vv, vmax); + } + + int i, j, i0, i1, j0, j1; + + i0 = (int)(umin / g); + i1 = (int)(umax / g); + j0 = (int)(vmin / g); + j1 = (int)(vmax / g); + + if(i0 > i1 || i1 - i0 > 400) return; + if(j0 > j1 || j1 - j0 > 400) return; + + Canvas::Stroke stroke = {}; + stroke.layer = Canvas::Layer::BACK; + stroke.color = Style::Color(Style::DATUM).WithAlpha(75); + stroke.unit = Canvas::Unit::PX; + stroke.width = 1.0f; + Canvas::hStroke hcs = canvas->GetStroke(stroke); + + for(i = i0 + 1; i < i1; i++) { + canvas->DrawLine(wp.Plus(wu.ScaledBy(i*g)).Plus(wv.ScaledBy(j0*g)), + wp.Plus(wu.ScaledBy(i*g)).Plus(wv.ScaledBy(j1*g)), + hcs); + } + for(j = j0 + 1; j < j1; j++) { + canvas->DrawLine(wp.Plus(wu.ScaledBy(i0*g)).Plus(wv.ScaledBy(j*g)), + wp.Plus(wu.ScaledBy(i1*g)).Plus(wv.ScaledBy(j*g)), + hcs); + } +} + +void GraphicsWindow::DrawEntities(Canvas *canvas, bool persistent) { + for(Entity &e : SK.entity) { + if(persistent == (e.IsNormal() || e.IsWorkplane())) continue; + switch(SS.GW.drawOccludedAs) { + case DrawOccludedAs::VISIBLE: + e.Draw(Entity::DrawAs::OVERLAY, canvas); + break; + + case DrawOccludedAs::STIPPLED: + e.Draw(Entity::DrawAs::HIDDEN, canvas); + /* fallthrough */ + case DrawOccludedAs::INVISIBLE: + e.Draw(Entity::DrawAs::DEFAULT, canvas); + break; + } + } +} + +void GraphicsWindow::DrawPersistent(Canvas *canvas) { + // Draw the active group; this does stuff like the mesh and edges. + SK.GetGroup(activeGroup)->Draw(canvas); + + // Now draw the entities that don't change with viewport. + DrawEntities(canvas, /*persistent=*/true); + + // Draw filled paths in all groups, when those filled paths were requested + // specially by assigning a style with a fill color, or when the filled + // paths are just being filled by default. This should go last, to make + // the transparency work. + for(hGroup hg : SK.groupOrder) { + Group *g = SK.GetGroup(hg); + if(!(g->IsVisible())) continue; + g->DrawFilledPaths(canvas); + } +} + +void GraphicsWindow::Draw(Canvas *canvas) { + const Camera &camera = canvas->GetCamera(); + + // Nasty case when we're reloading the linked files; could be that + // we get an error, so a dialog pops up, and a message loop starts, and + // we have to get called to paint ourselves. If the sketch is screwed + // up, then we could trigger an oops trying to draw. + if(!SS.allConsistent) return; + + if(showSnapGrid) DrawSnapGrid(canvas); + + // Draw all the things that don't change when we rotate. + if(persistentCanvas != NULL) { + if(persistentDirty) { + persistentDirty = false; + + persistentCanvas->Clear(); + DrawPersistent(&*persistentCanvas); + persistentCanvas->Finalize(); + } + + persistentCanvas->Draw(); + } else { + DrawPersistent(canvas); + } + + // Draw the entities that do change with viewport. + DrawEntities(canvas, /*persistent=*/false); + + // Draw the polygon errors. + if(SS.checkClosedContour) { + SK.GetGroup(activeGroup)->DrawPolyError(canvas); + } + + // Draw the constraints + for(Constraint &c : SK.constraint) { + c.Draw(Constraint::DrawAs::DEFAULT, canvas); + } + + // Draw areas + if(SS.showContourAreas) { + for(hGroup hg : SK.groupOrder) { + Group *g = SK.GetGroup(hg); + if(g->h != activeGroup) continue; + if(!(g->IsVisible())) continue; + g->DrawContourAreaLabels(canvas); + } + } + + // Draw the "pending" constraint, i.e. a constraint that would be + // placed on a line that is almost horizontal or vertical. + if(SS.GW.pending.operation == Pending::DRAGGING_NEW_LINE_POINT && + SS.GW.pending.hasSuggestion) { + Constraint c = {}; + c.group = SS.GW.activeGroup; + c.workplane = SS.GW.ActiveWorkplane(); + c.type = SS.GW.pending.suggestion; + c.entityA = SS.GW.pending.request.entity(0); + c.Draw(Constraint::DrawAs::DEFAULT, canvas); + } + + Canvas::Stroke strokeAnalyze = Style::Stroke(Style::ANALYZE); + strokeAnalyze.layer = Canvas::Layer::FRONT; + Canvas::hStroke hcsAnalyze = canvas->GetStroke(strokeAnalyze); + + // Draw the traced path, if one exists + SEdgeList tracedEdges = {}; + SS.traced.path.MakeEdgesInto(&tracedEdges); + canvas->DrawEdges(tracedEdges, hcsAnalyze); + tracedEdges.Clear(); + + Canvas::Stroke strokeError = Style::Stroke(Style::DRAW_ERROR); + strokeError.layer = Canvas::Layer::FRONT; + strokeError.width = 12; + Canvas::hStroke hcsError = canvas->GetStroke(strokeError); + + // And the naked edges, if the user did Analyze -> Show Naked Edges. + canvas->DrawEdges(SS.nakedEdges, hcsError); + + // Then redraw whatever the mouse is hovering over, highlighted. + hover.Draw(/*isHovered=*/true, canvas); + SK.GetGroup(activeGroup)->DrawMesh(Group::DrawMeshAs::HOVERED, canvas); + + // And finally draw the selection, same mechanism. + for(Selection *s = selection.First(); s; s = selection.NextAfter(s)) { + s->Draw(/*isHovered=*/false, canvas); + } + SK.GetGroup(activeGroup)->DrawMesh(Group::DrawMeshAs::SELECTED, canvas); + + Canvas::Stroke strokeDatum = Style::Stroke(Style::DATUM); + strokeDatum.unit = Canvas::Unit::PX; + strokeDatum.layer = Canvas::Layer::FRONT; + strokeDatum.width = 1; + Canvas::hStroke hcsDatum = canvas->GetStroke(strokeDatum); + + // An extra line, used to indicate the origin when rotating within the + // plane of the monitor. + if(SS.extraLine.draw) { + canvas->DrawLine(SS.extraLine.ptA, SS.extraLine.ptB, hcsDatum); + } + + if(SS.centerOfMass.draw && !SS.centerOfMass.dirty) { + Vector p = SS.centerOfMass.position; + Vector u = camera.projRight; + Vector v = camera.projUp; + + const double size = 10.0; + const int subdiv = 16; + double h = Style::DefaultTextHeight() / camera.scale; + std::string s = + SS.MmToStringSI(p.x) + ", " + + SS.MmToStringSI(p.y) + ", " + + SS.MmToStringSI(p.z); + canvas->DrawVectorText(s.c_str(), h, + p.Plus(u.ScaledBy((size + 5.0)/scale)).Minus(v.ScaledBy(h / 2.0)), + u, v, hcsDatum); + u = u.WithMagnitude(size / scale); + v = v.WithMagnitude(size / scale); + + canvas->DrawLine(p.Minus(u), p.Plus(u), hcsDatum); + canvas->DrawLine(p.Minus(v), p.Plus(v), hcsDatum); + Vector prev; + for(int i = 0; i <= subdiv; i++) { + double a = (double)i / subdiv * 2.0 * PI; + Vector point = p.Plus(u.ScaledBy(cos(a))).Plus(v.ScaledBy(sin(a))); + if(i > 0) { + canvas->DrawLine(point, prev, hcsDatum); + } + prev = point; + } + } + + // A note to indicate the origin in the just-exported file. + if(SS.justExportedInfo.draw) { + Vector p, u, v; + if(SS.justExportedInfo.showOrigin) { + p = SS.justExportedInfo.pt, + u = SS.justExportedInfo.u, + v = SS.justExportedInfo.v; + } else { + p = camera.offset.ScaledBy(-1); + u = camera.projRight; + v = camera.projUp; + } + canvas->DrawVectorText("previewing exported geometry; press Esc to return", + Style::DefaultTextHeight() / camera.scale, + p.Plus(u.ScaledBy(10/scale)).Plus(v.ScaledBy(10/scale)), u, v, + hcsDatum); + + if(SS.justExportedInfo.showOrigin) { + Vector um = p.Plus(u.WithMagnitude(-15/scale)), + up = p.Plus(u.WithMagnitude(30/scale)), + vm = p.Plus(v.WithMagnitude(-15/scale)), + vp = p.Plus(v.WithMagnitude(30/scale)); + canvas->DrawLine(um, up, hcsDatum); + canvas->DrawLine(vm, vp, hcsDatum); + canvas->DrawVectorText("(x, y) = (0, 0) for file just exported", + Style::DefaultTextHeight() / camera.scale, + p.Plus(u.ScaledBy(40/scale)).Plus( + v.ScaledBy(-(Style::DefaultTextHeight())/scale)), u, v, + hcsDatum); + } + } +} + +void GraphicsWindow::Paint() { + ssassert(window != NULL && canvas != NULL, + "Cannot paint without window and canvas"); + + havePainted = true; + + Camera camera = GetCamera(); + Lighting lighting = GetLighting(); + + if(!SS.ActiveGroupsOkay()) { + // Draw a different background whenever we're having solve problems. + RgbaColor bgColor = Style::Color(Style::DRAW_ERROR); + bgColor = RgbaColor::FromFloat(0.4f*bgColor.redF(), + 0.4f*bgColor.greenF(), + 0.4f*bgColor.blueF()); + lighting.backgroundColor = bgColor; + // And show the text window, which has info to debug it + ForceTextWindowShown(); + } + + canvas->SetLighting(lighting); + canvas->SetCamera(camera); + canvas->StartFrame(); + + // Draw the 3d objects. + Draw(canvas.get()); + canvas->FlushFrame(); + + // Draw the 2d UI overlay. + camera.LoadIdentity(); + camera.offset.x = -(double)camera.width / 2.0; + camera.offset.y = -(double)camera.height / 2.0; + canvas->SetCamera(camera); + + UiCanvas uiCanvas = {}; + uiCanvas.canvas = canvas; + + // If a marquee selection is in progress, then draw the selection + // rectangle, as an outline and a transparent fill. + if(pending.operation == Pending::DRAGGING_MARQUEE) { + Point2d begin = ProjectPoint(orig.marqueePoint); + uiCanvas.DrawRect((int)orig.mouse.x + (int)camera.width / 2, + (int)begin.x + (int)camera.width / 2, + (int)orig.mouse.y + (int)camera.height / 2, + (int)begin.y + (int)camera.height / 2, + /*fillColor=*/Style::Color(Style::HOVERED).WithAlpha(25), + /*outlineColor=*/Style::Color(Style::HOVERED)); + } + + // If we've had a screenshot requested, take it now, before the UI is overlaid. + if(!SS.screenshotFile.IsEmpty()) { + FILE *f = OpenFile(SS.screenshotFile, "wb"); + if(!f || !canvas->ReadFrame()->WritePng(f, /*flip=*/true)) { + Error("Couldn't write to '%s'", SS.screenshotFile.raw.c_str()); + } + if(f) fclose(f); + SS.screenshotFile.Clear(); + } + + // And finally the toolbar. + if(SS.showToolbar) { + canvas->SetCamera(camera); + ToolbarDraw(&uiCanvas); + } + + canvas->FlushFrame(); + canvas->FinishFrame(); + canvas->Clear(); +} + +void GraphicsWindow::Invalidate(bool clearPersistent) { + if(window) { + if(clearPersistent) { + persistentDirty = true; + } + window->Invalidate(); + } +} diff --git a/src/drawconstraint.cpp b/src/drawconstraint.cpp new file mode 100644 index 0000000..2cdb9af --- /dev/null +++ b/src/drawconstraint.cpp @@ -0,0 +1,1249 @@ +//----------------------------------------------------------------------------- +// Given a constraint, draw a graphical and user-selectable representation +// of that constraint on-screen. We can either draw with gl, or compute the +// distance from a point (the location of the mouse pointer) to the lines +// that we would have drawn, for selection. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +std::string Constraint::Label() const { + std::string result; + if(type == Type::ANGLE) { + result = SS.DegreeToString(valA) + "°"; + } else if(type == Type::LENGTH_RATIO) { + result = ssprintf("%.3f:1", valA); + } else if(type == Type::COMMENT) { + result = comment; + } else if(type == Type::DIAMETER) { + if(!other) { + result = "⌀" + SS.MmToStringSI(valA); + } else { + result = "R" + SS.MmToStringSI(valA / 2); + } + } else { + // valA has units of distance + result = SS.MmToStringSI(fabs(valA)); + } + if(reference) { + result += " REF"; + } + return result; +} + +void Constraint::DoLine(Canvas *canvas, Canvas::hStroke hcs, Vector a, Vector b) { + const Camera &camera = canvas->GetCamera(); + + a = camera.AlignToPixelGrid(a); + b = camera.AlignToPixelGrid(b); + canvas->DrawLine(a, b, hcs); +} + +void Constraint::DoStippledLine(Canvas *canvas, Canvas::hStroke hcs, Vector a, Vector b) { + Canvas::Stroke strokeStippled = *canvas->strokes.FindById(hcs); + strokeStippled.stipplePattern = StipplePattern::SHORT_DASH; + strokeStippled.stippleScale = 4.0; + Canvas::hStroke hcsStippled = canvas->GetStroke(strokeStippled); + DoLine(canvas, hcsStippled, a, b); +} + +void Constraint::DoLabel(Canvas *canvas, Canvas::hStroke hcs, + Vector ref, Vector *labelPos, Vector gr, Vector gu) { + const Camera &camera = canvas->GetCamera(); + + std::string s = Label(); + double textHeight = Style::TextHeight(GetStyle()) / camera.scale; + double swidth = VectorFont::Builtin()->GetWidth(textHeight, s), + sheight = VectorFont::Builtin()->GetCapHeight(textHeight); + + // By default, the reference is from the center; but the style could + // specify otherwise if one is present, and it could also specify a + // rotation. + if(type == Type::COMMENT && disp.style.v) { + Style *st = Style::Get(disp.style); + // rotation first + double rads = st->textAngle*PI/180; + double c = cos(rads), s = sin(rads); + Vector pr = gr, pu = gu; + gr = pr.ScaledBy( c).Plus(pu.ScaledBy(s)); + gu = pr.ScaledBy(-s).Plus(pu.ScaledBy(c)); + // then origin + uint32_t o = (uint32_t)st->textOrigin; + if(o & (uint32_t)Style::TextOrigin::LEFT) ref = ref.Plus(gr.WithMagnitude(swidth/2)); + if(o & (uint32_t)Style::TextOrigin::RIGHT) ref = ref.Minus(gr.WithMagnitude(swidth/2)); + if(o & (uint32_t)Style::TextOrigin::BOT) ref = ref.Plus(gu.WithMagnitude(sheight/2)); + if(o & (uint32_t)Style::TextOrigin::TOP) ref = ref.Minus(gu.WithMagnitude(sheight/2)); + } + + Vector o = ref.Minus(gr.WithMagnitude(swidth/2)).Minus( + gu.WithMagnitude(sheight/2)); + canvas->DrawVectorText(s, textHeight, o, gr.WithMagnitude(1), gu.WithMagnitude(1), hcs); + if(labelPos) *labelPos = o; +} + +void Constraint::DoProjectedPoint(Canvas *canvas, Canvas::hStroke hcs, + Vector *r, Vector n, Vector o) { + double d = r->DistanceToPlane(n, o); + Vector p = r->Minus(n.ScaledBy(d)); + DoStippledLine(canvas, hcs, p, *r); + *r = p; +} + +void Constraint::DoProjectedPoint(Canvas *canvas, Canvas::hStroke hcs, Vector *r) { + Vector p = r->ProjectInto(workplane); + DoStippledLine(canvas, hcs, p, *r); + *r = p; +} + +//----------------------------------------------------------------------------- +// There is a rectangular box, aligned to our display axes (projRight, projUp) +// centered at ref. This is where a dimension label will be drawn. We want to +// draw a line from A to B. If that line would intersect the label box, then +// trim the line to leave a gap for it, and return zero. If not, then extend +// the line to almost meet the box, and return either positive or negative, +// depending whether that extension was from A or from B. +//----------------------------------------------------------------------------- +int Constraint::DoLineTrimmedAgainstBox(Canvas *canvas, Canvas::hStroke hcs, + Vector ref, Vector a, Vector b, bool extend) { + const Camera &camera = canvas->GetCamera(); + double th = Style::TextHeight(GetStyle()) / camera.scale; + double pixels = 1.0 / camera.scale; + double swidth = VectorFont::Builtin()->GetWidth(th, Label()) + 8 * pixels, + sheight = VectorFont::Builtin()->GetCapHeight(th) + 8 * pixels; + Vector gu = camera.projUp.WithMagnitude(1), + gr = camera.projRight.WithMagnitude(1); + return DoLineTrimmedAgainstBox(canvas, hcs, ref, a, b, extend, gr, gu, swidth, sheight); +} + +int Constraint::DoLineTrimmedAgainstBox(Canvas *canvas, Canvas::hStroke hcs, + Vector ref, Vector a, Vector b, bool extend, + Vector gr, Vector gu, double swidth, double sheight) { + struct { + Vector n; + double d; + } planes[4]; + // reference pos is the center of box occupied by text; build a rectangle + // around that, aligned to axes gr and gu, from four planes will all four + // normals pointing inward + planes[0].n = gu.ScaledBy(-1); planes[0].d = -(gu.Dot(ref) + sheight/2); + planes[1].n = gu; planes[1].d = gu.Dot(ref) - sheight/2; + planes[2].n = gr; planes[2].d = gr.Dot(ref) - swidth/2; + planes[3].n = gr.ScaledBy(-1); planes[3].d = -(gr.Dot(ref) + swidth/2); + + double tmin = VERY_POSITIVE, tmax = VERY_NEGATIVE; + Vector dl = b.Minus(a); + + for(int i = 0; i < 4; i++) { + bool parallel; + Vector p = Vector::AtIntersectionOfPlaneAndLine( + planes[i].n, planes[i].d, + a, b, ¶llel); + if(parallel) continue; + + int j; + for(j = 0; j < 4; j++) { + double d = (planes[j].n).Dot(p) - planes[j].d; + if(d < -LENGTH_EPS) break; + } + if(j < 4) continue; + + double t = (p.Minus(a)).DivProjected(dl); + tmin = min(t, tmin); + tmax = max(t, tmax); + } + + // Both in range; so there's pieces of the line on both sides of the label box. + if(tmin >= 0.0 && tmin <= 1.0 && tmax >= 0.0 && tmax <= 1.0) { + DoLine(canvas, hcs, a, a.Plus(dl.ScaledBy(tmin))); + DoLine(canvas, hcs, a.Plus(dl.ScaledBy(tmax)), b); + return 0; + } + + // Only one intersection in range; so the box is right on top of the endpoint + if(tmin >= 0.0 && tmin <= 1.0) { + DoLine(canvas, hcs, a, a.Plus(dl.ScaledBy(tmin))); + return 0; + } + + // Likewise. + if(tmax >= 0.0 && tmax <= 1.0) { + DoLine(canvas, hcs, a.Plus(dl.ScaledBy(tmax)), b); + return 0; + } + + // The line does not intersect the label; so the line should get + // extended to just barely meet the label. + // 0 means the label lies within the line, negative means it's outside + // and closer to b, positive means outside and closer to a. + if(tmax < 0.0) { + if(extend) a = a.Plus(dl.ScaledBy(tmax)); + DoLine(canvas, hcs, a, b); + return 1; + } + + if(tmin > 1.0) { + if(extend) b = a.Plus(dl.ScaledBy(tmin)); + DoLine(canvas, hcs, a, b); + return -1; + } + + // This will happen if the entire line lies within the box. + return 0; +} + +void Constraint::DoArrow(Canvas *canvas, Canvas::hStroke hcs, + Vector p, Vector dir, Vector n, double width, double angle, double da) { + dir = dir.WithMagnitude(width / cos(angle)); + dir = dir.RotatedAbout(n, da); + DoLine(canvas, hcs, p, p.Plus(dir.RotatedAbout(n, angle))); + DoLine(canvas, hcs, p, p.Plus(dir.RotatedAbout(n, -angle))); +} + +//----------------------------------------------------------------------------- +// Draw a line with arrows on both ends, and possibly a gap in the middle for +// the dimension. We will use these for most length dimensions. The length +// being dimensioned is from A to B; but those points get extended perpendicular +// to the line AB, until the line between the extensions crosses ref (the +// center of the label). +//----------------------------------------------------------------------------- +void Constraint::DoLineWithArrows(Canvas *canvas, Canvas::hStroke hcs, + Vector ref, Vector a, Vector b, + bool onlyOneExt) +{ + const Camera &camera = canvas->GetCamera(); + double pixels = 1.0 / camera.scale; + + Vector ab = a.Minus(b); + Vector ar = a.Minus(ref); + // Normal to a plane containing the line and the label origin. + Vector n = ab.Cross(ar); + // Within that plane, and normal to the line AB; so that's our extension + // line. + Vector out = ab.Cross(n).WithMagnitude(1); + out = out.ScaledBy(-out.Dot(ar)); + + Vector ae = a.Plus(out), be = b.Plus(out); + + // Extension lines extend 10 pixels beyond where the arrows get + // drawn (which is at the same offset perpendicular from AB as the + // label). + DoLine(canvas, hcs, a, ae.Plus(out.WithMagnitude(10*pixels))); + if(!onlyOneExt) { + DoLine(canvas, hcs, b, be.Plus(out.WithMagnitude(10*pixels))); + } + + int within = DoLineTrimmedAgainstBox(canvas, hcs, ref, ae, be); + + // Arrow heads are 13 pixels long, with an 18 degree half-angle. + double theta = 18*PI/180; + Vector arrow = (be.Minus(ae)).WithMagnitude(13*pixels); + + if(within != 0) { + arrow = arrow.ScaledBy(-1); + Vector seg = (be.Minus(ae)).WithMagnitude(18*pixels); + if(within < 0) DoLine(canvas, hcs, ae, ae.Minus(seg)); + if(within > 0) DoLine(canvas, hcs, be, be.Plus(seg)); + } + + DoArrow(canvas, hcs, ae, arrow, n, 13.0 * pixels, theta, 0.0); + DoArrow(canvas, hcs, be, arrow.Negated(), n, 13.0 * pixels, theta, 0.0); +} + +void Constraint::DoEqualLenTicks(Canvas *canvas, Canvas::hStroke hcs, + Vector a, Vector b, Vector gn, Vector *refp) { + const Camera &camera = canvas->GetCamera(); + + Vector m = (a.ScaledBy(1.0/3)).Plus(b.ScaledBy(2.0/3)); + if(refp) *refp = m; + Vector ab = a.Minus(b); + Vector n = (gn.Cross(ab)).WithMagnitude(10/camera.scale); + + DoLine(canvas, hcs, m.Minus(n), m.Plus(n)); +} + +void Constraint::DoEqualRadiusTicks(Canvas *canvas, Canvas::hStroke hcs, + hEntity he, Vector *refp) { + const Camera &camera = canvas->GetCamera(); + Entity *circ = SK.GetEntity(he); + + Vector center = SK.GetEntity(circ->point[0])->PointGetNum(); + double r = circ->CircleGetRadiusNum(); + Quaternion q = circ->Normal()->NormalGetNum(); + Vector u = q.RotationU(), v = q.RotationV(); + + double theta; + if(circ->type == Entity::Type::CIRCLE) { + theta = PI/2; + } else if(circ->type == Entity::Type::ARC_OF_CIRCLE) { + double thetaa, thetab, dtheta; + circ->ArcGetAngles(&thetaa, &thetab, &dtheta); + theta = thetaa + dtheta/2; + } else ssassert(false, "Unexpected entity type"); + + Vector d = u.ScaledBy(cos(theta)).Plus(v.ScaledBy(sin(theta))); + d = d.ScaledBy(r); + Vector p = center.Plus(d); + if(refp) *refp = p; + Vector tick = d.WithMagnitude(10/camera.scale); + DoLine(canvas, hcs, p.Plus(tick), p.Minus(tick)); +} + +void Constraint::DoArcForAngle(Canvas *canvas, Canvas::hStroke hcs, + Vector a0, Vector da, Vector b0, Vector db, + Vector offset, Vector *ref, bool trim) +{ + const Camera &camera = canvas->GetCamera(); + double pixels = 1.0 / camera.scale; + Vector gr = camera.projRight.ScaledBy(1.0); + Vector gu = camera.projUp.ScaledBy(1.0); + + if(workplane != Entity::FREE_IN_3D) { + a0 = a0.ProjectInto(workplane); + b0 = b0.ProjectInto(workplane); + da = da.ProjectVectorInto(workplane); + db = db.ProjectVectorInto(workplane); + } + + Vector a1 = a0.Plus(da); + Vector b1 = b0.Plus(db); + + bool skew; + Vector pi = Vector::AtIntersectionOfLines(a0, a0.Plus(da), + b0, b0.Plus(db), &skew); + + if(!skew) { + *ref = pi.Plus(offset); + // We draw in a coordinate system centered at the intersection point. + // One basis vector is da, and the other is normal to da and in + // the plane that contains our lines (so normal to its normal). + da = da.WithMagnitude(1); + db = db.WithMagnitude(1); + + Vector norm = da.Cross(db); + + Vector dna = norm.Cross(da).WithMagnitude(1.0); + Vector dnb = norm.Cross(db).WithMagnitude(1.0); + + // da and db magnitudes are 1.0 + double thetaf = acos(da.Dot(db)); + + // Calculate median + Vector m = da.ScaledBy(cos(thetaf/2)).Plus( + dna.ScaledBy(sin(thetaf/2))); + Vector rm = (*ref).Minus(pi); + + // Test which side we have to place an arc + if(m.Dot(rm) < 0) { + da = da.ScaledBy(-1); dna = dna.ScaledBy(-1); + db = db.ScaledBy(-1); dnb = dnb.ScaledBy(-1); + } + + double rda = rm.Dot(da), rdna = rm.Dot(dna); + + // Introduce minimal arc radius in pixels + double r = max(sqrt(rda*rda + rdna*rdna), 15.0 * pixels); + + double th = Style::TextHeight(GetStyle()) / camera.scale; + double swidth = VectorFont::Builtin()->GetWidth(th, Label()) + 8*pixels, + sheight = VectorFont::Builtin()->GetCapHeight(th) + 6*pixels; + double textR = sqrt(swidth * swidth + sheight * sheight) / 2.0; + *ref = pi.Plus(rm.WithMagnitude(std::max(rm.Magnitude(), 15 * pixels + textR))); + + // Arrow points + Vector apa = da. ScaledBy(r).Plus(pi); + Vector apb = da. ScaledBy(r*cos(thetaf)).Plus( + dna.ScaledBy(r*sin(thetaf))).Plus(pi); + + double arrowW = 13 * pixels; + double arrowA = 18.0 * PI / 180.0; + bool arrowVisible = apb.Minus(apa).Magnitude() > 2.5 * arrowW; + // Arrow reversing indicator + bool arrowRev = false; + + // The minimal extension length in angular representation + double extAngle = 18 * pixels / r; + + // Arc additional angle + double addAngle = 0.0; + // Arc start angle + double startAngle = 0.0; + + // Arc extension to db. + // We have just enlarge angle value. + if(HasLabel() && rm.Dot(dnb) > 0.0) { + // rm direction projected to plane with u = da, v = dna + Vector rmp = da.ScaledBy(rda).Plus(dna.ScaledBy(rdna)).WithMagnitude(1.0); + // rmp and db magnitudes are 1.0 + addAngle = std::max(acos(rmp.Dot(db)), extAngle); + + if(arrowVisible) { + startAngle = -extAngle; + addAngle += extAngle; + arrowRev = true; + } + } + + // Arc extension to da. + // We are enlarge angle value and rewrite basis to align along rm projection. + if(HasLabel() && rm.Dot(dna) < 0.0) { + // rm direction projected to plane with u = da, v = dna + Vector rmp = da.ScaledBy(rda).Plus(dna.ScaledBy(rdna)).WithMagnitude(1.0); + // rmp and da magnitudes are 1.0 + startAngle = -std::max(acos(rmp.Dot(da)), extAngle); + addAngle = -startAngle; + + if(arrowVisible) { + addAngle += extAngle; + arrowRev = true; + } + } + + Vector prev; + int n = 30; + for(int i = 0; i <= n; i++) { + double theta = startAngle + (i*(thetaf + addAngle))/n; + Vector p = da.ScaledBy(r*cos(theta)).Plus( + dna.ScaledBy(r*sin(theta))).Plus(pi); + if(i > 0) { + if(trim) { + DoLineTrimmedAgainstBox(canvas, hcs, *ref, prev, p, + /*extend=*/false, gr, gu, swidth, sheight + 2*pixels); + } else { + DoLine(canvas, hcs, prev, p); + } + } + prev = p; + } + + DoLineExtend(canvas, hcs, a0, a1, apa, 5.0 * pixels); + DoLineExtend(canvas, hcs, b0, b1, apb, 5.0 * pixels); + + // Draw arrows only when we have enough space. + if(arrowVisible) { + double angleCorr = arrowW / (2.0 * r); + if(arrowRev) { + dna = dna.ScaledBy(-1.0); + angleCorr = -angleCorr; + } + DoArrow(canvas, hcs, apa, dna, norm, arrowW, arrowA, angleCorr); + DoArrow(canvas, hcs, apb, dna, norm, arrowW, arrowA, thetaf + PI - angleCorr); + } + } else { + // The lines are skew; no wonderful way to illustrate that. + + *ref = a0.Plus(b0); + *ref = (*ref).ScaledBy(0.5).Plus(disp.offset); + gu = gu.WithMagnitude(1); + double textHeight = Style::TextHeight(GetStyle()) / camera.scale; + Vector trans = + (*ref).Plus(gu.ScaledBy(-1.5*VectorFont::Builtin()->GetCapHeight(textHeight))); + canvas->DrawVectorText("angle between skew lines", textHeight, + trans, gr.WithMagnitude(1), gu.WithMagnitude(1), + hcs); + } +} + +bool Constraint::IsVisible() const { + if(!SS.GW.showConstraints) return false; + Group *g = SK.GetGroup(group); + // If the group is hidden, then the constraints are hidden and not + // able to be selected. + if(!(g->visible)) return false; + // And likewise if the group is not the active group; except for comments + // with an assigned style. + if(g->h != SS.GW.activeGroup && !(type == Type::COMMENT && disp.style.v)) { + return false; + } + if(disp.style.v) { + Style *s = Style::Get(disp.style); + if(!s->visible) return false; + } + return true; +} + +bool Constraint::DoLineExtend(Canvas *canvas, Canvas::hStroke hcs, + Vector p0, Vector p1, Vector pt, double salient) { + Vector dir = p1.Minus(p0); + double k = dir.Dot(pt.Minus(p0)) / dir.Dot(dir); + Vector ptOnLine = p0.Plus(dir.ScaledBy(k)); + + // Draw projection line. + DoLine(canvas, hcs, pt, ptOnLine); + + // Calculate salient direction. + Vector sd = dir.WithMagnitude(1.0).ScaledBy(salient); + + Vector from; + Vector to; + + if(k < 0.0) { + from = p0; + to = ptOnLine.Minus(sd); + } else if(k > 1.0) { + from = p1; + to = ptOnLine.Plus(sd); + } else { + return false; + } + + // Draw extension line. + DoLine(canvas, hcs, from, to); + return true; +} + +void Constraint::DoLayout(DrawAs how, Canvas *canvas, + Vector *labelPos, std::vector *refs) { + if(!(how == DrawAs::HOVERED || how == DrawAs::SELECTED) && + !IsVisible()) return; + + // Unit vectors that describe our current view of the scene. One pixel + // long, not one actual unit. + const Camera &camera = canvas->GetCamera(); + Vector gr = camera.projRight.ScaledBy(1/camera.scale); + Vector gu = camera.projUp.ScaledBy(1/camera.scale); + Vector gn = (gr.Cross(gu)).WithMagnitude(1/camera.scale); + + double textHeight = Style::TextHeight(GetStyle()) / camera.scale; + + RgbaColor color = {}; + switch(how) { + case DrawAs::DEFAULT: color = Style::Color(GetStyle()); break; + case DrawAs::HOVERED: color = Style::Color(Style::HOVERED); break; + case DrawAs::SELECTED: color = Style::Color(Style::SELECTED); break; + } + Canvas::Stroke stroke = Style::Stroke(GetStyle()); + stroke.layer = Canvas::Layer::FRONT; + stroke.color = color; + stroke.zIndex = 4; + Canvas::hStroke hcs = canvas->GetStroke(stroke); + + Canvas::Fill fill = {}; + fill.layer = Canvas::Layer::FRONT; + fill.color = color; + fill.zIndex = stroke.zIndex; + Canvas::hFill hcf = canvas->GetFill(fill); + + switch(type) { + case Type::PT_PT_DISTANCE: { + Vector ap = SK.GetEntity(ptA)->PointGetNum(); + Vector bp = SK.GetEntity(ptB)->PointGetNum(); + + if(workplane != Entity::FREE_IN_3D) { + DoProjectedPoint(canvas, hcs, &ap); + DoProjectedPoint(canvas, hcs, &bp); + } + + Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset); + if(refs) refs->push_back(ref); + + DoLineWithArrows(canvas, hcs, ref, ap, bp, /*onlyOneExt=*/false); + DoLabel(canvas, hcs, ref, labelPos, gr, gu); + return; + } + + case Type::PROJ_PT_DISTANCE: { + Vector ap = SK.GetEntity(ptA)->PointGetNum(), + bp = SK.GetEntity(ptB)->PointGetNum(), + dp = (bp.Minus(ap)), + pp = SK.GetEntity(entityA)->VectorGetNum(); + + Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(disp.offset); + if(refs) refs->push_back(ref); + + pp = pp.WithMagnitude(1); + double d = dp.Dot(pp); + Vector bpp = ap.Plus(pp.ScaledBy(d)); + DoStippledLine(canvas, hcs, ap, bpp); + DoStippledLine(canvas, hcs, bp, bpp); + + DoLineWithArrows(canvas, hcs, ref, ap, bpp, /*onlyOneExt=*/false); + DoLabel(canvas, hcs, ref, labelPos, gr, gu); + return; + } + + case Type::PT_FACE_DISTANCE: + case Type::PT_PLANE_DISTANCE: { + Vector pt = SK.GetEntity(ptA)->PointGetNum(); + Entity *enta = SK.GetEntity(entityA); + Vector n, p; + if(type == Type::PT_PLANE_DISTANCE) { + n = enta->Normal()->NormalN(); + p = enta->WorkplaneGetOffset(); + } else { + n = enta->FaceGetNormalNum(); + p = enta->FaceGetPointNum(); + } + + double d = (p.Minus(pt)).Dot(n); + Vector closest = pt.Plus(n.WithMagnitude(d)); + + Vector ref = ((closest.Plus(pt)).ScaledBy(0.5)).Plus(disp.offset); + if(refs) refs->push_back(ref); + + if(!pt.Equals(closest)) { + DoLineWithArrows(canvas, hcs, ref, pt, closest, /*onlyOneExt=*/true); + } + + DoLabel(canvas, hcs, ref, labelPos, gr, gu); + return; + } + + case Type::PT_LINE_DISTANCE: { + Vector pt = SK.GetEntity(ptA)->PointGetNum(); + Entity *line = SK.GetEntity(entityA); + Vector lA = SK.GetEntity(line->point[0])->PointGetNum(); + Vector lB = SK.GetEntity(line->point[1])->PointGetNum(); + Vector dl = lB.Minus(lA); + + if(workplane != Entity::FREE_IN_3D) { + lA = lA.ProjectInto(workplane); + lB = lB.ProjectInto(workplane); + DoProjectedPoint(canvas, hcs, &pt); + } + + // Find the closest point on the line + Vector closest = pt.ClosestPointOnLine(lA, dl); + + Vector ref = ((closest.Plus(pt)).ScaledBy(0.5)).Plus(disp.offset); + if(refs) refs->push_back(ref); + DoLabel(canvas, hcs, ref, labelPos, gr, gu); + + if(!pt.Equals(closest)) { + DoLineWithArrows(canvas, hcs, ref, pt, closest, /*onlyOneExt=*/true); + + // Draw projected point + Vector a = pt; + Vector b = closest; + Vector ab = a.Minus(b); + Vector ar = a.Minus(ref); + Vector n = ab.Cross(ar); + Vector out = ab.Cross(n).WithMagnitude(1); + out = out.ScaledBy(-out.Dot(ar)); + Vector be = b.Plus(out); + Vector np = lA.Minus(pt).Cross(lB.Minus(pt)).WithMagnitude(1.0); + DoProjectedPoint(canvas, hcs, &be, np, pt); + + // Extensions to line + double pixels = 1.0 / camera.scale; + Vector refClosest = ref.ClosestPointOnLine(lA, dl); + double ddl = dl.Dot(dl); + if(fabs(ddl) > LENGTH_EPS * LENGTH_EPS) { + double t = refClosest.Minus(lA).Dot(dl) / ddl; + if(t < 0.0) { + DoLine(canvas, hcs, refClosest.Minus(dl.WithMagnitude(10.0 * pixels)), lA); + } else if(t > 1.0) { + DoLine(canvas, hcs, refClosest.Plus(dl.WithMagnitude(10.0 * pixels)), lB); + } + } + } + + if(workplane != Entity::FREE_IN_3D) { + // Draw the projection marker from the closest point on the + // projected line to the projected point on the real line. + Vector lAB = (lA.Minus(lB)); + double t = (lA.Minus(closest)).DivProjected(lAB); + + Vector lA = SK.GetEntity(line->point[0])->PointGetNum(); + Vector lB = SK.GetEntity(line->point[1])->PointGetNum(); + + Vector c2 = (lA.ScaledBy(1-t)).Plus(lB.ScaledBy(t)); + DoProjectedPoint(canvas, hcs, &c2); + } + return; + } + + case Type::DIAMETER: { + Entity *circle = SK.GetEntity(entityA); + Vector center = SK.GetEntity(circle->point[0])->PointGetNum(); + Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum(); + Vector n = q.RotationN().WithMagnitude(1); + double r = circle->CircleGetRadiusNum(); + + Vector ref = center.Plus(disp.offset); + // Force the label into the same plane as the circle. + ref = ref.Minus(n.ScaledBy(n.Dot(ref) - n.Dot(center))); + if(refs) refs->push_back(ref); + + Vector mark = ref.Minus(center); + mark = mark.WithMagnitude(mark.Magnitude()-r); + DoLineTrimmedAgainstBox(canvas, hcs, ref, ref, ref.Minus(mark)); + + Vector topLeft; + DoLabel(canvas, hcs, ref, &topLeft, gr, gu); + if(labelPos) *labelPos = topLeft; + return; + } + + case Type::POINTS_COINCIDENT: { + if(how == DrawAs::DEFAULT) { + // Let's adjust the color of this constraint to have the same + // rough luma as the point color, so that the constraint does not + // stand out in an ugly way. + RgbaColor cd = Style::Color(Style::DATUM), + cc = Style::Color(Style::CONSTRAINT); + // convert from 8-bit color to a vector + Vector vd = Vector::From(cd.redF(), cd.greenF(), cd.blueF()), + vc = Vector::From(cc.redF(), cc.greenF(), cc.blueF()); + // and scale the constraint color to have the same magnitude as + // the datum color, maybe a bit dimmer + vc = vc.WithMagnitude(vd.Magnitude()*0.9); + // and set the color to that. + fill.color = RGBf(vc.x, vc.y, vc.z); + hcf = canvas->GetFill(fill); + } + + for(int a = 0; a < 2; a++) { + Vector r = camera.projRight.ScaledBy((a+1)/camera.scale); + Vector d = camera.projUp.ScaledBy((2-a)/camera.scale); + for(int i = 0; i < 2; i++) { + Vector p = SK.GetEntity(i == 0 ? ptA : ptB)-> PointGetNum(); + if(refs) refs->push_back(p); + canvas->DrawQuad(p.Plus (r).Plus (d), + p.Plus (r).Minus(d), + p.Minus(r).Minus(d), + p.Minus(r).Plus (d), + hcf); + } + + } + return; + } + + case Type::PT_ON_CIRCLE: + case Type::PT_ON_LINE: + case Type::PT_ON_FACE: + case Type::PT_IN_PLANE: { + double s = 8/camera.scale; + Vector p = SK.GetEntity(ptA)->PointGetNum(); + if(refs) refs->push_back(p); + Vector r, d; + if(type == Type::PT_ON_FACE) { + Vector n = SK.GetEntity(entityA)->FaceGetNormalNum(); + r = n.Normal(0); + d = n.Normal(1); + } else if(type == Type::PT_IN_PLANE) { + EntityBase *n = SK.GetEntity(entityA)->Normal(); + r = n->NormalU(); + d = n->NormalV(); + } else { + r = gr; + d = gu; + s *= (6.0/8); // draw these a little smaller + } + r = r.WithMagnitude(s); d = d.WithMagnitude(s); + DoLine(canvas, hcs, p.Plus (r).Plus (d), p.Plus (r).Minus(d)); + DoLine(canvas, hcs, p.Plus (r).Minus(d), p.Minus(r).Minus(d)); + DoLine(canvas, hcs, p.Minus(r).Minus(d), p.Minus(r).Plus (d)); + DoLine(canvas, hcs, p.Minus(r).Plus (d), p.Plus (r).Plus (d)); + return; + } + + case Type::WHERE_DRAGGED: { + Vector p = SK.GetEntity(ptA)->PointGetNum(); + if(refs) refs->push_back(p); + Vector u = p.Plus(gu.WithMagnitude(8/camera.scale)).Plus( + gr.WithMagnitude(8/camera.scale)), + uu = u.Minus(gu.WithMagnitude(5/camera.scale)), + ur = u.Minus(gr.WithMagnitude(5/camera.scale)); + // Draw four little crop marks, uniformly spaced (by ninety + // degree rotations) around the point. + int i; + for(i = 0; i < 4; i++) { + DoLine(canvas, hcs, u, uu); + DoLine(canvas, hcs, u, ur); + u = u.RotatedAbout(p, gn, PI/2); + ur = ur.RotatedAbout(p, gn, PI/2); + uu = uu.RotatedAbout(p, gn, PI/2); + } + return; + } + + case Type::SAME_ORIENTATION: { + for(int i = 0; i < 2; i++) { + Entity *e = SK.GetEntity(i == 0 ? entityA : entityB); + Quaternion q = e->NormalGetNum(); + Vector n = q.RotationN().WithMagnitude(25/camera.scale); + Vector u = q.RotationU().WithMagnitude(6/camera.scale); + Vector p = SK.GetEntity(e->point[0])->PointGetNum(); + p = p.Plus(n.WithMagnitude(10/camera.scale)); + if(refs) refs->push_back(p); + + DoLine(canvas, hcs, p.Plus(u), p.Minus(u).Plus(n)); + DoLine(canvas, hcs, p.Minus(u), p.Plus(u).Plus(n)); + } + return; + } + + case Type::EQUAL_ANGLE: { + Vector ref; + Entity *a = SK.GetEntity(entityA); + Entity *b = SK.GetEntity(entityB); + Entity *c = SK.GetEntity(entityC); + Entity *d = SK.GetEntity(entityD); + + Vector a0 = a->VectorGetStartPoint(); + Vector b0 = b->VectorGetStartPoint(); + Vector c0 = c->VectorGetStartPoint(); + Vector d0 = d->VectorGetStartPoint(); + Vector da = a->VectorGetNum(); + Vector db = b->VectorGetNum(); + Vector dc = c->VectorGetNum(); + Vector dd = d->VectorGetNum(); + + if(other) { + a0 = a0.Plus(da); + da = da.ScaledBy(-1); + } + + DoArcForAngle(canvas, hcs, a0, da, b0, db, + da.WithMagnitude(40/camera.scale), &ref, /*trim=*/false); + if(refs) refs->push_back(ref); + DoArcForAngle(canvas, hcs, c0, dc, d0, dd, + dc.WithMagnitude(40/camera.scale), &ref, /*trim=*/false); + if(refs) refs->push_back(ref); + + return; + } + + case Type::ANGLE: { + Entity *a = SK.GetEntity(entityA); + Entity *b = SK.GetEntity(entityB); + + Vector a0 = a->VectorGetStartPoint(); + Vector b0 = b->VectorGetStartPoint(); + Vector da = a->VectorGetNum(); + Vector db = b->VectorGetNum(); + if(other) { + a0 = a0.Plus(da); + da = da.ScaledBy(-1); + } + + Vector ref; + DoArcForAngle(canvas, hcs, a0, da, b0, db, disp.offset, &ref, /*trim=*/true); + DoLabel(canvas, hcs, ref, labelPos, gr, gu); + if(refs) refs->push_back(ref); + return; + } + + case Type::PERPENDICULAR: { + Vector u = Vector::From(0, 0, 0), v = Vector::From(0, 0, 0); + Vector rn, ru; + if(workplane == Entity::FREE_IN_3D) { + rn = gn; + ru = gu; + } else { + EntityBase *normal = SK.GetEntity(workplane)->Normal(); + rn = normal->NormalN(); + ru = normal->NormalV(); // ru meaning r_up, not u/v + } + + for(int i = 0; i < 2; i++) { + Entity *e = SK.GetEntity(i == 0 ? entityA : entityB); + + if(i == 0) { + // Calculate orientation of perpendicular sign only + // once, so that it's the same both times it's drawn + u = e->VectorGetNum(); + u = u.WithMagnitude(16/camera.scale); + v = (rn.Cross(u)).WithMagnitude(16/camera.scale); + // a bit of bias to stop it from flickering between the + // two possibilities + if(fabs(u.Dot(ru)) < fabs(v.Dot(ru)) + LENGTH_EPS) { + swap(u, v); + } + if(u.Dot(ru) < 0) u = u.ScaledBy(-1); + } + + Vector p = e->VectorGetRefPoint(); + Vector s = p.Plus(u).Plus(v); + DoLine(canvas, hcs, s, s.Plus(v)); + Vector m = s.Plus(v.ScaledBy(0.5)); + DoLine(canvas, hcs, m, m.Plus(u)); + if(refs) refs->push_back(m); + } + return; + } + + case Type::CURVE_CURVE_TANGENT: + case Type::CUBIC_LINE_TANGENT: + case Type::ARC_LINE_TANGENT: { + Vector textAt, u, v; + + if(type == Type::ARC_LINE_TANGENT) { + Entity *arc = SK.GetEntity(entityA); + Entity *norm = SK.GetEntity(arc->normal); + Vector c = SK.GetEntity(arc->point[0])->PointGetNum(); + Vector p = + SK.GetEntity(arc->point[other ? 2 : 1])->PointGetNum(); + Vector r = p.Minus(c); + textAt = p.Plus(r.WithMagnitude(14/camera.scale)); + u = norm->NormalU(); + v = norm->NormalV(); + } else if(type == Type::CUBIC_LINE_TANGENT) { + Vector n; + if(workplane == Entity::FREE_IN_3D) { + u = gr; + v = gu; + n = gn; + } else { + EntityBase *wn = SK.GetEntity(workplane)->Normal(); + u = wn->NormalU(); + v = wn->NormalV(); + n = wn->NormalN(); + } + + Entity *cubic = SK.GetEntity(entityA); + Vector p = other ? cubic->CubicGetFinishNum() : + cubic->CubicGetStartNum(); + Vector dir = SK.GetEntity(entityB)->VectorGetNum(); + Vector out = n.Cross(dir); + textAt = p.Plus(out.WithMagnitude(14/camera.scale)); + } else { + Vector n, dir; + EntityBase *wn = SK.GetEntity(workplane)->Normal(); + u = wn->NormalU(); + v = wn->NormalV(); + n = wn->NormalN(); + EntityBase *eA = SK.GetEntity(entityA); + // Big pain; we have to get a vector tangent to the curve + // at the shared point, which could be from either a cubic + // or an arc. + if(other) { + textAt = eA->EndpointFinish(); + if(eA->type == Entity::Type::CUBIC) { + dir = eA->CubicGetFinishTangentNum(); + } else { + dir = SK.GetEntity(eA->point[0])->PointGetNum().Minus( + SK.GetEntity(eA->point[2])->PointGetNum()); + dir = n.Cross(dir); + } + } else { + textAt = eA->EndpointStart(); + if(eA->type == Entity::Type::CUBIC) { + dir = eA->CubicGetStartTangentNum(); + } else { + dir = SK.GetEntity(eA->point[0])->PointGetNum().Minus( + SK.GetEntity(eA->point[1])->PointGetNum()); + dir = n.Cross(dir); + } + } + dir = n.Cross(dir); + textAt = textAt.Plus(dir.WithMagnitude(14/camera.scale)); + } + + Vector ex = VectorFont::Builtin()->GetExtents(textHeight, "T"); + canvas->DrawVectorText("T", textHeight, textAt.Minus(ex.ScaledBy(0.5)), + u.WithMagnitude(1), v.WithMagnitude(1), hcs); + if(refs) refs->push_back(textAt); + return; + } + + case Type::PARALLEL: { + for(int i = 0; i < 2; i++) { + Entity *e = SK.GetEntity(i == 0 ? entityA : entityB); + Vector n = e->VectorGetNum(); + n = n.WithMagnitude(25/camera.scale); + Vector u = (gn.Cross(n)).WithMagnitude(4/camera.scale); + Vector p = e->VectorGetRefPoint(); + + DoLine(canvas, hcs, p.Plus(u), p.Plus(u).Plus(n)); + DoLine(canvas, hcs, p.Minus(u), p.Minus(u).Plus(n)); + if(refs) refs->push_back(p.Plus(n.ScaledBy(0.5))); + } + return; + } + + case Type::EQUAL_RADIUS: { + for(int i = 0; i < 2; i++) { + Vector ref; + DoEqualRadiusTicks(canvas, hcs, i == 0 ? entityA : entityB, &ref); + if(refs) refs->push_back(ref); + } + return; + } + + case Type::EQUAL_LINE_ARC_LEN: { + Entity *line = SK.GetEntity(entityA); + Vector ref; + DoEqualLenTicks(canvas, hcs, + SK.GetEntity(line->point[0])->PointGetNum(), + SK.GetEntity(line->point[1])->PointGetNum(), + gn, &ref); + if(refs) refs->push_back(ref); + DoEqualRadiusTicks(canvas, hcs, entityB, &ref); + if(refs) refs->push_back(ref); + return; + } + + case Type::LENGTH_RATIO: + case Type::LENGTH_DIFFERENCE: + case Type::EQUAL_LENGTH_LINES: { + Vector a, b = Vector::From(0, 0, 0); + for(int i = 0; i < 2; i++) { + Entity *e = SK.GetEntity(i == 0 ? entityA : entityB); + a = SK.GetEntity(e->point[0])->PointGetNum(); + b = SK.GetEntity(e->point[1])->PointGetNum(); + + if(workplane != Entity::FREE_IN_3D) { + DoProjectedPoint(canvas, hcs, &a); + DoProjectedPoint(canvas, hcs, &b); + } + + Vector ref; + DoEqualLenTicks(canvas, hcs, a, b, gn, &ref); + if(refs) refs->push_back(ref); + } + if((type == Type::LENGTH_RATIO) || (type == Type::LENGTH_DIFFERENCE)) { + Vector ref = ((a.Plus(b)).ScaledBy(0.5)).Plus(disp.offset); + DoLabel(canvas, hcs, ref, labelPos, gr, gu); + } + return; + } + + case Type::EQ_LEN_PT_LINE_D: { + Entity *forLen = SK.GetEntity(entityA); + Vector a = SK.GetEntity(forLen->point[0])->PointGetNum(), + b = SK.GetEntity(forLen->point[1])->PointGetNum(); + if(workplane != Entity::FREE_IN_3D) { + DoProjectedPoint(canvas, hcs, &a); + DoProjectedPoint(canvas, hcs, &b); + } + Vector refa; + DoEqualLenTicks(canvas, hcs, a, b, gn, &refa); + if(refs) refs->push_back(refa); + + Entity *ln = SK.GetEntity(entityB); + Vector la = SK.GetEntity(ln->point[0])->PointGetNum(), + lb = SK.GetEntity(ln->point[1])->PointGetNum(); + Vector pt = SK.GetEntity(ptA)->PointGetNum(); + if(workplane != Entity::FREE_IN_3D) { + DoProjectedPoint(canvas, hcs, &pt); + la = la.ProjectInto(workplane); + lb = lb.ProjectInto(workplane); + } + + Vector closest = pt.ClosestPointOnLine(la, lb.Minus(la)); + DoLine(canvas, hcs, pt, closest); + Vector refb; + DoEqualLenTicks(canvas, hcs, pt, closest, gn, &refb); + if(refs) refs->push_back(refb); + return; + } + + case Type::EQ_PT_LN_DISTANCES: { + for(int i = 0; i < 2; i++) { + Entity *ln = SK.GetEntity(i == 0 ? entityA : entityB); + Vector la = SK.GetEntity(ln->point[0])->PointGetNum(), + lb = SK.GetEntity(ln->point[1])->PointGetNum(); + Entity *pte = SK.GetEntity(i == 0 ? ptA : ptB); + Vector pt = pte->PointGetNum(); + + if(workplane != Entity::FREE_IN_3D) { + DoProjectedPoint(canvas, hcs, &pt); + la = la.ProjectInto(workplane); + lb = lb.ProjectInto(workplane); + } + + Vector closest = pt.ClosestPointOnLine(la, lb.Minus(la)); + DoLine(canvas, hcs, pt, closest); + + Vector ref; + DoEqualLenTicks(canvas, hcs, pt, closest, gn, &ref); + if(refs) refs->push_back(ref); + } + return; + } + + { + case Type::SYMMETRIC: + Vector n; + n = SK.GetEntity(entityA)->Normal()->NormalN(); goto s; + case Type::SYMMETRIC_HORIZ: + n = SK.GetEntity(workplane)->Normal()->NormalU(); goto s; + case Type::SYMMETRIC_VERT: + n = SK.GetEntity(workplane)->Normal()->NormalV(); goto s; + case Type::SYMMETRIC_LINE: { + Entity *ln = SK.GetEntity(entityA); + Vector la = SK.GetEntity(ln->point[0])->PointGetNum(), + lb = SK.GetEntity(ln->point[1])->PointGetNum(); + la = la.ProjectInto(workplane); + lb = lb.ProjectInto(workplane); + n = lb.Minus(la); + Vector nw = SK.GetEntity(workplane)->Normal()->NormalN(); + n = n.RotatedAbout(nw, PI/2); + goto s; + } +s: + Vector a = SK.GetEntity(ptA)->PointGetNum(); + Vector b = SK.GetEntity(ptB)->PointGetNum(); + + for(int i = 0; i < 2; i++) { + Vector tail = (i == 0) ? a : b; + Vector d = (i == 0) ? b : a; + d = d.Minus(tail); + // Project the direction in which the arrow is drawn normal + // to the symmetry plane; for projected symmetry constraints, + // they might not be in the same direction, even when the + // constraint is fully solved. + d = n.ScaledBy(d.Dot(n)); + d = d.WithMagnitude(20/camera.scale); + Vector tip = tail.Plus(d); + + DoLine(canvas, hcs, tail, tip); + d = d.WithMagnitude(9/camera.scale); + DoLine(canvas, hcs, tip, tip.Minus(d.RotatedAbout(gn, 0.6))); + DoLine(canvas, hcs, tip, tip.Minus(d.RotatedAbout(gn, -0.6))); + if(refs) refs->push_back(tip); + } + return; + } + + case Type::AT_MIDPOINT: + case Type::HORIZONTAL: + case Type::VERTICAL: + if(entityA.v) { + Vector r, u, n; + if(workplane == Entity::FREE_IN_3D) { + r = gr; u = gu; n = gn; + } else { + r = SK.GetEntity(workplane)->Normal()->NormalU(); + u = SK.GetEntity(workplane)->Normal()->NormalV(); + n = r.Cross(u); + } + // For "at midpoint", this branch is always taken. + Entity *e = SK.GetEntity(entityA); + Vector a = SK.GetEntity(e->point[0])->PointGetNum(); + Vector b = SK.GetEntity(e->point[1])->PointGetNum(); + Vector m = (a.ScaledBy(0.5)).Plus(b.ScaledBy(0.5)); + Vector offset = (a.Minus(b)).Cross(n); + offset = offset.WithMagnitude(textHeight); + // Draw midpoint constraint on other side of line, so that + // a line can be midpoint and horizontal at same time. + if(type == Type::AT_MIDPOINT) offset = offset.ScaledBy(-1); + + std::string s; + switch(type) { + case Type::HORIZONTAL: s = "H"; break; + case Type::VERTICAL: s = "V"; break; + case Type::AT_MIDPOINT: s = "M"; break; + default: ssassert(false, "Unexpected constraint type"); + } + Vector o = m.Plus(offset).Plus(u.WithMagnitude(textHeight/5)), + ex = VectorFont::Builtin()->GetExtents(textHeight, s); + Vector shift = r.WithMagnitude(ex.x).Plus( + u.WithMagnitude(ex.y)); + + canvas->DrawVectorText(s, textHeight, o.Minus(shift.ScaledBy(0.5)), + r.WithMagnitude(1), u.WithMagnitude(1), hcs); + if(refs) refs->push_back(o); + } else { + Vector a = SK.GetEntity(ptA)->PointGetNum(); + Vector b = SK.GetEntity(ptB)->PointGetNum(); + + Entity *w = SK.GetEntity(workplane); + Vector cu = w->Normal()->NormalU(); + Vector cv = w->Normal()->NormalV(); + Vector cn = w->Normal()->NormalN(); + + int i; + for(i = 0; i < 2; i++) { + Vector o = (i == 0) ? a : b; + Vector oo = (i == 0) ? a.Minus(b) : b.Minus(a); + Vector d = (type == Type::HORIZONTAL) ? cu : cv; + if(oo.Dot(d) < 0) d = d.ScaledBy(-1); + + Vector dp = cn.Cross(d); + d = d.WithMagnitude(14/camera.scale); + Vector c = o.Minus(d); + DoLine(canvas, hcs, o, c); + d = d.WithMagnitude(3/camera.scale); + dp = dp.WithMagnitude(2/camera.scale); + canvas->DrawQuad((c.Plus(d)).Plus(dp), + (c.Minus(d)).Plus(dp), + (c.Minus(d)).Minus(dp), + (c.Plus(d)).Minus(dp), + hcf); + if(refs) refs->push_back(c); + } + } + return; + + case Type::COMMENT: { + Vector u, v; + if(workplane == Entity::FREE_IN_3D) { + u = gr; + v = gu; + } else { + EntityBase *norm = SK.GetEntity(workplane)->Normal(); + u = norm->NormalU(); + v = norm->NormalV(); + } + + if(disp.style.v != 0) { + RgbaColor color = stroke.color; + stroke = Style::Stroke(disp.style); + stroke.layer = Canvas::Layer::FRONT; + if(how != DrawAs::DEFAULT) { + stroke.color = color; + } + hcs = canvas->GetStroke(stroke); + } + DoLabel(canvas, hcs, disp.offset, labelPos, u, v); + if(refs) refs->push_back(disp.offset); + return; + } + } + ssassert(false, "Unexpected constraint type"); +} + +void Constraint::Draw(DrawAs how, Canvas *canvas) { + DoLayout(how, canvas, NULL, NULL); +} + +Vector Constraint::GetLabelPos(const Camera &camera) { + Vector p; + + ObjectPicker canvas = {}; + canvas.camera = camera; + DoLayout(DrawAs::DEFAULT, &canvas, &p, NULL); + canvas.Clear(); + + return p; +} + +void Constraint::GetReferencePoints(const Camera &camera, std::vector *refs) { + ObjectPicker canvas = {}; + canvas.camera = camera; + DoLayout(DrawAs::DEFAULT, &canvas, NULL, refs); + canvas.Clear(); +} + +bool Constraint::IsStylable() const { + if(type == Type::COMMENT) return true; + return false; +} + +hStyle Constraint::GetStyle() const { + if(disp.style.v != 0) return disp.style; + return { Style::CONSTRAINT }; +} + +bool Constraint::HasLabel() const { + switch(type) { + case Type::COMMENT: + case Type::PT_PT_DISTANCE: + case Type::PT_PLANE_DISTANCE: + case Type::PT_LINE_DISTANCE: + case Type::PT_FACE_DISTANCE: + case Type::PROJ_PT_DISTANCE: + case Type::LENGTH_RATIO: + case Type::LENGTH_DIFFERENCE: + case Type::DIAMETER: + case Type::ANGLE: + return true; + + default: + return false; + } +} diff --git a/src/drawentity.cpp b/src/drawentity.cpp new file mode 100644 index 0000000..b8e3cbd --- /dev/null +++ b/src/drawentity.cpp @@ -0,0 +1,791 @@ +//----------------------------------------------------------------------------- +// Draw a representation of an entity on-screen, in the case of curves up +// to our chord tolerance, or return the distance from the user's mouse pointer +// to the entity for selection. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +std::string Entity::DescriptionString() const { + if(h.isFromRequest()) { + Request *r = SK.GetRequest(h.request()); + return r->DescriptionString(); + } else { + Group *g = SK.GetGroup(h.group()); + return g->DescriptionString(); + } +} + +void Entity::GenerateEdges(SEdgeList *el) { + SBezierList *sbl = GetOrGenerateBezierCurves(); + + for(int i = 0; i < sbl->l.n; i++) { + SBezier *sb = &(sbl->l[i]); + + List lv = {}; + sb->MakePwlInto(&lv); + for(int j = 1; j < lv.n; j++) { + el->AddEdge(lv[j-1], lv[j], style.v, i); + } + lv.Clear(); + } +} + +SBezierList *Entity::GetOrGenerateBezierCurves() { + if(beziers.l.IsEmpty()) + GenerateBezierCurves(&beziers); + return &beziers; +} + +SEdgeList *Entity::GetOrGenerateEdges() { + if(!edges.l.IsEmpty()) { + if(EXACT(edgesChordTol == SS.ChordTolMm())) + return &edges; + edges.l.Clear(); + } + if(edges.l.IsEmpty()) + GenerateEdges(&edges); + edgesChordTol = SS.ChordTolMm(); + return &edges; +} + +BBox Entity::GetOrGenerateScreenBBox(bool *hasBBox) { + SBezierList *sbl = GetOrGenerateBezierCurves(); + + // We don't bother with bounding boxes for workplanes, etc. + *hasBBox = (IsPoint() || IsNormal() || !sbl->l.IsEmpty()); + if(!*hasBBox) return {}; + + if(screenBBoxValid) + return screenBBox; + + if(IsPoint()) { + Vector proj = SS.GW.ProjectPoint3(PointGetNum()); + screenBBox = BBox::From(proj, proj); + } else if(IsNormal()) { + Vector proj = SS.GW.ProjectPoint3(SK.GetEntity(point[0])->PointGetNum()); + screenBBox = BBox::From(proj, proj); + } else if(!sbl->l.IsEmpty()) { + Vector first = SS.GW.ProjectPoint3(sbl->l[0].ctrl[0]); + screenBBox = BBox::From(first, first); + for(auto &sb : sbl->l) { + for(int i = 0; i <= sb.deg; ++i) { screenBBox.Include(SS.GW.ProjectPoint3(sb.ctrl[i])); } + } + } else + ssassert(false, "Expected entity to be a point or have beziers"); + + screenBBoxValid = true; + return screenBBox; +} + +void Entity::GetReferencePoints(std::vector *refs) { + switch(type) { + case Type::POINT_N_COPY: + case Type::POINT_N_TRANS: + case Type::POINT_N_ROT_TRANS: + case Type::POINT_N_ROT_AA: + case Type::POINT_N_ROT_AXIS_TRANS: + case Type::POINT_IN_3D: + case Type::POINT_IN_2D: + refs->push_back(PointGetNum()); + break; + + case Type::NORMAL_N_COPY: + case Type::NORMAL_N_ROT: + case Type::NORMAL_N_ROT_AA: + case Type::NORMAL_IN_3D: + case Type::NORMAL_IN_2D: + case Type::WORKPLANE: + case Type::CIRCLE: + case Type::ARC_OF_CIRCLE: + case Type::CUBIC: + case Type::CUBIC_PERIODIC: + case Type::TTF_TEXT: + case Type::IMAGE: + refs->push_back(SK.GetEntity(point[0])->PointGetNum()); + break; + + case Type::LINE_SEGMENT: { + Vector a = SK.GetEntity(point[0])->PointGetNum(), + b = SK.GetEntity(point[1])->PointGetNum(); + refs->push_back(b.Plus(a.Minus(b).ScaledBy(0.5))); + break; + } + + case Type::DISTANCE: + case Type::DISTANCE_N_COPY: + case Type::FACE_NORMAL_PT: + case Type::FACE_XPROD: + case Type::FACE_N_ROT_TRANS: + case Type::FACE_N_TRANS: + case Type::FACE_N_ROT_AA: + case Type::FACE_ROT_NORMAL_PT: + case Type::FACE_N_ROT_AXIS_TRANS: + break; + } +} + +int Entity::GetPositionOfPoint(const Camera &camera, Point2d p) { + int position; + + ObjectPicker canvas = {}; + canvas.camera = camera; + canvas.point = p; + canvas.minDistance = 1e12; + Draw(DrawAs::DEFAULT, &canvas); + position = canvas.position; + canvas.Clear(); + + return position; +} + +bool Entity::IsStylable() const { + if(IsPoint()) return false; + if(IsWorkplane()) return false; + if(IsNormal()) return false; + return true; +} + +bool Entity::IsVisible() const { + Group *g = SK.GetGroup(group); + + if(g->h == Group::HGROUP_REFERENCES && IsNormal()) { + // The reference normals are always shown + return true; + } + if(!(g->IsVisible())) return false; + + if(IsPoint() && !SS.GW.showPoints) return false; + if(IsNormal() && !SS.GW.showNormals) return false; + if(construction && !SS.GW.showConstruction) return false; + + if(!SS.GW.showWorkplanes) { + if(IsWorkplane() && !h.isFromRequest()) { + if(g->h != SS.GW.activeGroup) { + // The group-associated workplanes are hidden outside + // their group. + return false; + } + } + } + + if(style.v) { + Style *s = Style::Get(style); + if(!s->visible) return false; + } + + if(forceHidden) return false; + + return true; +} + +// entities that were created via some copy types will not be +// draggable with the mouse. We identify the undraggables here +bool Entity::CanBeDragged() const { + // a numeric copy can not move + if(type == Entity::Type::POINT_N_COPY) return false; + // these transforms applied zero times can not be moved + if(((type == Entity::Type::POINT_N_TRANS) || + (type == Entity::Type::POINT_N_ROT_AA) || + (type == Entity::Type::POINT_N_ROT_AXIS_TRANS)) + && (timesApplied == 0)) return false; + // for these types of entities the first point will indicate draggability + if(HasEndpoints() || type == Entity::Type::CIRCLE) { + return SK.GetEntity(point[0])->CanBeDragged(); + } + // if we're not certain it can't be dragged then default to true + return true; +} + +void Entity::CalculateNumerical(bool forExport) { + if(IsPoint()) actPoint = PointGetNum(); + if(IsNormal()) actNormal = NormalGetNum(); + if(type == Type::DISTANCE || type == Type::DISTANCE_N_COPY) { + actDistance = DistanceGetNum(); + } + if(IsFace()) { + actPoint = FaceGetPointNum(); + Vector n = FaceGetNormalNum(); + actNormal = Quaternion::From(0, n.x, n.y, n.z); + } + if(forExport) { + // Visibility in copied linked entities follows source file + actVisible = IsVisible(); + } else { + // Copied entities within a file are always visible + actVisible = true; + } +} + +//----------------------------------------------------------------------------- +// Compute a cubic, second derivative continuous, interpolating spline. Same +// routine for periodic splines (in a loop) or open splines (with specified +// end tangents). +//----------------------------------------------------------------------------- +void Entity::ComputeInterpolatingSpline(SBezierList *sbl, bool periodic) const { + static const int MAX_N = BandedMatrix::MAX_UNKNOWNS; + int ep = extraPoints; + + // The number of unknowns to solve for. + int n = periodic ? 3 + ep : ep; + ssassert(n < MAX_N, "Too many unknowns"); + // The number of on-curve points, one more than the number of segments. + int pts = periodic ? 4 + ep : 2 + ep; + + int i, j, a; + + // The starting and finishing control points that define our end tangents + // (if the spline isn't periodic), and the on-curve points. + Vector ctrl_s = Vector::From(0, 0, 0); + Vector ctrl_f = Vector::From(0, 0, 0); + Vector pt[MAX_N+4]; + if(periodic) { + for(i = 0; i < ep + 3; i++) { + pt[i] = SK.GetEntity(point[i])->PointGetNum(); + } + pt[i++] = SK.GetEntity(point[0])->PointGetNum(); + } else { + ctrl_s = SK.GetEntity(point[1])->PointGetNum(); + ctrl_f = SK.GetEntity(point[ep+2])->PointGetNum(); + j = 0; + pt[j++] = SK.GetEntity(point[0])->PointGetNum(); + for(i = 2; i <= ep + 1; i++) { + pt[j++] = SK.GetEntity(point[i])->PointGetNum(); + } + pt[j++] = SK.GetEntity(point[ep+3])->PointGetNum(); + } + + // The unknowns that we will be solving for, a set for each coordinate. + double Xx[MAX_N], Xy[MAX_N], Xz[MAX_N]; + // For a cubic Bezier section f(t) as t goes from 0 to 1, + // f' (0) = 3*(P1 - P0) + // f' (1) = 3*(P3 - P2) + // f''(0) = 6*(P0 - 2*P1 + P2) + // f''(1) = 6*(P3 - 2*P2 + P1) + for(a = 0; a < 3; a++) { + BandedMatrix bm = {}; + bm.n = n; + + for(i = 0; i < n; i++) { + int im, it, ip; + if(periodic) { + im = WRAP(i - 1, n); + it = i; + ip = WRAP(i + 1, n); + } else { + im = i; + it = i + 1; + ip = i + 2; + } + // All of these are expressed in terms of a constant part, and + // of X[i-1], X[i], and X[i+1]; so let these be the four + // components of that vector; + Vector4 A, B, C, D, E; + // The on-curve interpolated point + C = Vector4::From((pt[it]).Element(a), 0, 0, 0); + // control point one back, C - X[i] + B = C.Plus(Vector4::From(0, 0, -1, 0)); + // control point one forward, C + X[i] + D = C.Plus(Vector4::From(0, 0, 1, 0)); + // control point two back + if(i == 0 && !periodic) { + A = Vector4::From(ctrl_s.Element(a), 0, 0, 0); + } else { + // pt[im] + X[i-1] + A = Vector4::From(pt[im].Element(a), 1, 0, 0); + } + // control point two forward + if(i == (n - 1) && !periodic) { + E = Vector4::From(ctrl_f.Element(a), 0, 0, 0); + } else { + // pt[ip] - X[i+1] + E = Vector4::From((pt[ip]).Element(a), 0, 0, -1); + } + // Write the second derivatives of each segment, dropping constant + Vector4 fprev_pp = (C.Minus(B.ScaledBy(2))).Plus(A), + fnext_pp = (C.Minus(D.ScaledBy(2))).Plus(E), + eq = fprev_pp.Minus(fnext_pp); + + bm.B[i] = -eq.w; + if(periodic) { + bm.A[i][WRAP(i-2, n)] = eq.x; + bm.A[i][WRAP(i-1, n)] = eq.y; + bm.A[i][i] = eq.z; + } else { + // The wrapping would work, except when n = 1 and everything + // wraps to zero... + if(i > 0) { + bm.A[i][i - 1] = eq.x; + } + bm.A[i][i] = eq.y; + if(i < (n-1)) { + bm.A[i][i + 1] = eq.z; + } + } + } + bm.Solve(); + double *X = (a == 0) ? Xx : + (a == 1) ? Xy : + Xz; + memcpy(X, bm.X, n*sizeof(double)); + } + + for(i = 0; i < pts - 1; i++) { + Vector p0, p1, p2, p3; + if(periodic) { + p0 = pt[i]; + int iw = WRAP(i - 1, n); + p1 = p0.Plus(Vector::From(Xx[iw], Xy[iw], Xz[iw])); + } else if(i == 0) { + p0 = pt[0]; + p1 = ctrl_s; + } else { + p0 = pt[i]; + p1 = p0.Plus(Vector::From(Xx[i-1], Xy[i-1], Xz[i-1])); + } + if(periodic) { + p3 = pt[i+1]; + int iw = WRAP(i, n); + p2 = p3.Minus(Vector::From(Xx[iw], Xy[iw], Xz[iw])); + } else if(i == (pts - 2)) { + p3 = pt[pts-1]; + p2 = ctrl_f; + } else { + p3 = pt[i+1]; + p2 = p3.Minus(Vector::From(Xx[i], Xy[i], Xz[i])); + } + SBezier sb = SBezier::From(p0, p1, p2, p3); + sbl->l.Add(&sb); + } +} + +void Entity::GenerateBezierCurves(SBezierList *sbl) const { + SBezier sb; + + int i = sbl->l.n; + + switch(type) { + case Type::LINE_SEGMENT: { + Vector a = SK.GetEntity(point[0])->PointGetNum(); + Vector b = SK.GetEntity(point[1])->PointGetNum(); + sb = SBezier::From(a, b); + sb.entity = h.v; + sbl->l.Add(&sb); + break; + } + case Type::CUBIC: + ComputeInterpolatingSpline(sbl, /*periodic=*/false); + break; + + case Type::CUBIC_PERIODIC: + ComputeInterpolatingSpline(sbl, /*periodic=*/true); + break; + + case Type::CIRCLE: + case Type::ARC_OF_CIRCLE: { + Vector center = SK.GetEntity(point[0])->PointGetNum(); + Quaternion q = SK.GetEntity(normal)->NormalGetNum(); + Vector u = q.RotationU(), v = q.RotationV(); + double r = CircleGetRadiusNum(); + double thetaa, thetab, dtheta; + + if(r < LENGTH_EPS) { + // If a circle or an arc gets dragged through zero radius, + // then we just don't generate anything. + break; + } + + if(type == Type::CIRCLE) { + thetaa = 0; + thetab = 2*PI; + dtheta = 2*PI; + } else { + ArcGetAngles(&thetaa, &thetab, &dtheta); + } + int i, n; + if(dtheta > (3*PI/2 + 0.01)) { + n = 4; + } else if(dtheta > (PI + 0.01)) { + n = 3; + } else if(dtheta > (PI/2 + 0.01)) { + n = 2; + } else { + n = 1; + } + dtheta /= n; + + for(i = 0; i < n; i++) { + double s, c; + + c = cos(thetaa); + s = sin(thetaa); + // The start point of the curve, and the tangent vector at + // that start point. + Vector p0 = center.Plus(u.ScaledBy( r*c)).Plus(v.ScaledBy(r*s)), + t0 = u.ScaledBy(-r*s). Plus(v.ScaledBy(r*c)); + + thetaa += dtheta; + + c = cos(thetaa); + s = sin(thetaa); + Vector p2 = center.Plus(u.ScaledBy( r*c)).Plus(v.ScaledBy(r*s)), + t2 = u.ScaledBy(-r*s). Plus(v.ScaledBy(r*c)); + + // The control point must lie on both tangents. + Vector p1 = Vector::AtIntersectionOfLines(p0, p0.Plus(t0), + p2, p2.Plus(t2), + NULL); + + SBezier sb = SBezier::From(p0, p1, p2); + sb.weight[1] = cos(dtheta/2); + sbl->l.Add(&sb); + } + break; + } + + case Type::TTF_TEXT: { + Vector topLeft = SK.GetEntity(point[0])->PointGetNum(); + Vector botLeft = SK.GetEntity(point[1])->PointGetNum(); + Vector n = Normal()->NormalN(); + Vector v = topLeft.Minus(botLeft); + Vector u = (v.Cross(n)).WithMagnitude(v.Magnitude()); + + SS.fonts.PlotString(font, str, sbl, botLeft, u, v); + break; + } + + default: + // Not a problem, points and normals and such don't generate curves + break; + } + + // Record our style for all of the Beziers that we just created. + for(; i < sbl->l.n; i++) { + sbl->l[i].auxA = style.v; + } +} + +void Entity::Draw(DrawAs how, Canvas *canvas) { + if(!(how == DrawAs::HOVERED || how == DrawAs::SELECTED) && + !IsVisible()) return; + + int zIndex; + if(IsPoint()) { + zIndex = 6; + } else if(how == DrawAs::HIDDEN) { + zIndex = 2; + } else if(group != SS.GW.activeGroup) { + zIndex = 3; + } else { + zIndex = 5; + } + + hStyle hs; + if(IsPoint()) { + hs.v = Style::DATUM; + } else if(IsNormal() || type == Type::WORKPLANE) { + hs.v = Style::NORMALS; + } else { + hs = Style::ForEntity(h); + if (hs.v == Style::CONSTRUCTION) { + zIndex = 4; + } + } + + Canvas::Stroke stroke = Style::Stroke(hs); + switch(how) { + case DrawAs::DEFAULT: + stroke.layer = Canvas::Layer::NORMAL; + break; + + case DrawAs::OVERLAY: + stroke.layer = Canvas::Layer::FRONT; + break; + + case DrawAs::HIDDEN: + stroke.layer = Canvas::Layer::OCCLUDED; + stroke.stipplePattern = Style::PatternType({ Style::HIDDEN_EDGE }); + stroke.stippleScale = Style::Get({ Style::HIDDEN_EDGE })->stippleScale; + break; + + case DrawAs::HOVERED: + stroke.layer = Canvas::Layer::FRONT; + stroke.color = Style::Color(Style::HOVERED); + break; + + case DrawAs::SELECTED: + stroke.layer = Canvas::Layer::FRONT; + stroke.color = Style::Color(Style::SELECTED); + break; + } + stroke.zIndex = zIndex; + Canvas::hStroke hcs = canvas->GetStroke(stroke); + + switch(type) { + case Type::POINT_N_COPY: + case Type::POINT_N_TRANS: + case Type::POINT_N_ROT_TRANS: + case Type::POINT_N_ROT_AA: + case Type::POINT_N_ROT_AXIS_TRANS: + case Type::POINT_IN_3D: + case Type::POINT_IN_2D: { + if(how == DrawAs::HIDDEN) return; + + // If we're analyzing the sketch to show the degrees of freedom, + // then we draw big colored squares over the points that are + // free to move. + bool free = false; + if(type == Type::POINT_IN_3D) { + Param *px = SK.GetParam(param[0]), + *py = SK.GetParam(param[1]), + *pz = SK.GetParam(param[2]); + + free = px->free || py->free || pz->free; + } else if(type == Type::POINT_IN_2D) { + Param *pu = SK.GetParam(param[0]), + *pv = SK.GetParam(param[1]); + + free = pu->free || pv->free; + } + + Canvas::Stroke pointStroke = {}; + pointStroke.layer = (free) ? Canvas::Layer::FRONT : stroke.layer; + pointStroke.zIndex = stroke.zIndex; + pointStroke.color = stroke.color; + pointStroke.width = 7.0; + pointStroke.unit = Canvas::Unit::PX; + Canvas::hStroke hcsPoint = canvas->GetStroke(pointStroke); + + if(free) { + Canvas::Stroke analyzeStroke = Style::Stroke(Style::ANALYZE); + analyzeStroke.width = 14.0; + analyzeStroke.layer = Canvas::Layer::FRONT; + Canvas::hStroke hcsAnalyze = canvas->GetStroke(analyzeStroke); + + canvas->DrawPoint(PointGetNum(), hcsAnalyze); + } + + canvas->DrawPoint(PointGetNum(), hcsPoint); + return; + } + + case Type::NORMAL_N_COPY: + case Type::NORMAL_N_ROT: + case Type::NORMAL_N_ROT_AA: + case Type::NORMAL_IN_3D: + case Type::NORMAL_IN_2D: { + const Camera &camera = canvas->GetCamera(); + + if(how == DrawAs::HIDDEN) return; + + for(int i = 0; i < 2; i++) { + bool asReference = (i == 1); + if(asReference) { + if(!h.request().IsFromReferences()) continue; + } else { + if(!SK.GetGroup(group)->IsVisible() || !SS.GW.showNormals) continue; + } + + stroke.layer = (asReference) ? Canvas::Layer::FRONT : Canvas::Layer::NORMAL; + if(how != DrawAs::HOVERED && how != DrawAs::SELECTED) { + // Always draw the x, y, and z axes in red, green, and blue; + // brighter for the ones at the bottom left of the screen, + // dimmer for the ones at the model origin. + hRequest hr = h.request(); + uint8_t luma = (asReference) ? 255 : 100; + if(hr == Request::HREQUEST_REFERENCE_XY) { + stroke.color = RgbaColor::From(0, 0, luma); + } else if(hr == Request::HREQUEST_REFERENCE_YZ) { + stroke.color = RgbaColor::From(luma, 0, 0); + } else if(hr == Request::HREQUEST_REFERENCE_ZX) { + stroke.color = RgbaColor::From(0, luma, 0); + } + } + + Quaternion q = NormalGetNum(); + Vector tail; + if(asReference) { + // Draw an extra copy of the x, y, and z axes, that's + // always in the corner of the view and at the front. + // So those are always available, perhaps useful. + stroke.width = 2; + double s = camera.scale; + double h = 60 - camera.height / 2.0; + double w = 60 - camera.width / 2.0; + // Shift the axis to the right if they would overlap with the toolbar. + if(SS.showToolbar) { + if(h + 30 > -(32*18 + 3*16 + 8) / 2) + w += 60; + } + tail = camera.projRight.ScaledBy(w/s).Plus( + camera.projUp. ScaledBy(h/s)).Minus(camera.offset); + } else { + tail = SK.GetEntity(point[0])->PointGetNum(); + } + tail = camera.AlignToPixelGrid(tail); + + hcs = canvas->GetStroke(stroke); + Vector v = (q.RotationN()).WithMagnitude(50.0 / camera.scale); + Vector tip = tail.Plus(v); + canvas->DrawLine(tail, tip, hcs); + + v = v.WithMagnitude(12.0 / camera.scale); + Vector axis = q.RotationV(); + canvas->DrawLine(tip, tip.Minus(v.RotatedAbout(axis, 0.6)), hcs); + canvas->DrawLine(tip, tip.Minus(v.RotatedAbout(axis, -0.6)), hcs); + + if(type == Type::NORMAL_IN_3D) { + Param *nw = SK.GetParam(param[0]), + *nx = SK.GetParam(param[1]), + *ny = SK.GetParam(param[2]), + *nz = SK.GetParam(param[3]); + + if(nw->free || nx->free || ny->free || nz->free) { + Canvas::Stroke analyzeStroke = Style::Stroke(Style::ANALYZE); + analyzeStroke.layer = Canvas::Layer::FRONT; + Canvas::hStroke hcsAnalyze = canvas->GetStroke(analyzeStroke); + canvas->DrawLine(tail, tip, hcsAnalyze); + } + } + } + return; + } + + case Type::DISTANCE: + case Type::DISTANCE_N_COPY: + // These are used only as data structures, nothing to display. + return; + + case Type::WORKPLANE: { + const Camera &camera = canvas->GetCamera(); + + Vector p = SK.GetEntity(point[0])->PointGetNum(); + p = camera.AlignToPixelGrid(p); + + Vector u = Normal()->NormalU(); + Vector v = Normal()->NormalV(); + + double s = (std::min(camera.width, camera.height)) * 0.45 / camera.scale; + + Vector us = u.ScaledBy(s); + Vector vs = v.ScaledBy(s); + + Vector pp = p.Plus (us).Plus (vs); + Vector pm = p.Plus (us).Minus(vs); + Vector mm = p.Minus(us).Minus(vs), mm2 = mm; + Vector mp = p.Minus(us).Plus (vs); + + Canvas::Stroke strokeBorder = stroke; + strokeBorder.zIndex -= 3; + strokeBorder.stipplePattern = StipplePattern::SHORT_DASH; + strokeBorder.stippleScale = 8.0; + Canvas::hStroke hcsBorder = canvas->GetStroke(strokeBorder); + + double textHeight = Style::TextHeight(hs) / camera.scale; + + if(!h.isFromRequest()) { + mm = mm.Plus(v.ScaledBy(textHeight * 4.7)); + mm2 = mm2.Plus(u.ScaledBy(textHeight * 4.7)); + canvas->DrawLine(mm2, mm, hcsBorder); + } + canvas->DrawLine(pp, pm, hcsBorder); + canvas->DrawLine(mm2, pm, hcsBorder); + canvas->DrawLine(mm, mp, hcsBorder); + canvas->DrawLine(pp, mp, hcsBorder); + + Vector o = mm2.Plus(u.ScaledBy(3.0 / camera.scale)).Plus( + v.ScaledBy(3.0 / camera.scale)); + std::string shortDesc = DescriptionString().substr(5); + canvas->DrawVectorText(shortDesc, textHeight, o, u, v, hcs); + return; + } + + case Type::LINE_SEGMENT: + case Type::CIRCLE: + case Type::ARC_OF_CIRCLE: + case Type::CUBIC: + case Type::CUBIC_PERIODIC: + case Type::TTF_TEXT: { + // Generate the rational polynomial curves, then piecewise linearize + // them, and display those. + if(!canvas->DrawBeziers(*GetOrGenerateBezierCurves(), hcs)) { + canvas->DrawEdges(*GetOrGenerateEdges(), hcs); + } + if(type == Type::CIRCLE) { + Entity *dist = SK.GetEntity(distance); + if(dist->type == Type::DISTANCE) { + Param *p = SK.GetParam(dist->param[0]); + if(p->free) { + Canvas::Stroke analyzeStroke = Style::Stroke(Style::ANALYZE); + analyzeStroke.layer = Canvas::Layer::FRONT; + Canvas::hStroke hcsAnalyze = canvas->GetStroke(analyzeStroke); + if(!canvas->DrawBeziers(*GetOrGenerateBezierCurves(), hcsAnalyze)) { + canvas->DrawEdges(*GetOrGenerateEdges(), hcsAnalyze); + } + } + } + } + return; + } + case Type::IMAGE: { + Canvas::Fill fill = {}; + std::shared_ptr pixmap; + switch(how) { + case DrawAs::HIDDEN: return; + + case DrawAs::HOVERED: { + fill.color = Style::Color(Style::HOVERED).WithAlpha(180); + fill.pattern = Canvas::FillPattern::CHECKERED_A; + fill.zIndex = 2; + break; + } + + case DrawAs::SELECTED: { + fill.color = Style::Color(Style::SELECTED).WithAlpha(180); + fill.pattern = Canvas::FillPattern::CHECKERED_B; + fill.zIndex = 1; + break; + } + + default: + fill.color = RgbaColor::FromFloat(1.0f, 1.0f, 1.0f); + pixmap = SS.images[file]; + break; + } + + Canvas::hFill hf = canvas->GetFill(fill); + Vector v[4] = {}; + for(int i = 0; i < 4; i++) { + v[i] = SK.GetEntity(point[i])->PointGetNum(); + } + Vector iu = v[3].Minus(v[0]); + Vector iv = v[1].Minus(v[0]); + + if(how == DrawAs::DEFAULT && pixmap == NULL) { + Canvas::Stroke stroke = Style::Stroke(Style::DRAW_ERROR); + stroke.color = stroke.color.WithAlpha(50); + Canvas::hStroke hs = canvas->GetStroke(stroke); + canvas->DrawLine(v[0], v[2], hs); + canvas->DrawLine(v[1], v[3], hs); + for(int i = 0; i < 4; i++) { + canvas->DrawLine(v[i], v[(i + 1) % 4], hs); + } + } else { + canvas->DrawPixmap(pixmap, v[0], iu, iv, + Point2d::From(0.0, 0.0), Point2d::From(1.0, 1.0), hf); + } + } + + case Type::FACE_NORMAL_PT: + case Type::FACE_XPROD: + case Type::FACE_N_ROT_TRANS: + case Type::FACE_N_TRANS: + case Type::FACE_N_ROT_AA: + case Type::FACE_ROT_NORMAL_PT: + case Type::FACE_N_ROT_AXIS_TRANS: + // Do nothing; these are drawn with the triangle mesh + return; + } + ssassert(false, "Unexpected entity type"); +} diff --git a/src/dsc.h b/src/dsc.h new file mode 100644 index 0000000..93403bc --- /dev/null +++ b/src/dsc.h @@ -0,0 +1,722 @@ +//----------------------------------------------------------------------------- +// Data structures used frequently in the program, various kinds of vectors +// (of real numbers, not symbolic algebra stuff) and our templated lists. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#ifndef SOLVESPACE_DSC_H +#define SOLVESPACE_DSC_H + +#include "solvespace.h" + +#include + +/// Trait indicating which types are handle types and should get the associated operators. +/// Specialize for each handle type and inherit from std::true_type. +template +struct IsHandleOracle : std::false_type {}; + +// Equality-compare any two instances of a handle type. +template +static inline typename std::enable_if::value, bool>::type +operator==(T const &lhs, T const &rhs) { + return lhs.v == rhs.v; +} + +// Inequality-compare any two instances of a handle type. +template +static inline typename std::enable_if::value, bool>::type +operator!=(T const &lhs, T const &rhs) { + return !(lhs == rhs); +} + +// Less-than-compare any two instances of a handle type. +template +static inline typename std::enable_if::value, bool>::type +operator<(T const &lhs, T const &rhs) { + return lhs.v < rhs.v; +} + +class Vector; +class Vector4; +class Point2d; +class hEntity; +class hParam; + +class Quaternion { +public: + // a + (vx)*i + (vy)*j + (vz)*k + double w, vx, vy, vz; + + static const Quaternion IDENTITY; + + static Quaternion From(double w, double vx, double vy, double vz); + static Quaternion From(hParam w, hParam vx, hParam vy, hParam vz); + static Quaternion From(Vector u, Vector v); + static Quaternion From(Vector axis, double dtheta); + + Quaternion Plus(Quaternion b) const; + Quaternion Minus(Quaternion b) const; + Quaternion ScaledBy(double s) const; + double Magnitude() const; + Quaternion WithMagnitude(double s) const; + + // Call a rotation matrix [ u' v' n' ]'; this returns the first and + // second rows, where that matrix is generated by this quaternion + Vector RotationU() const; + Vector RotationV() const; + Vector RotationN() const; + Vector Rotate(Vector p) const; + + Quaternion ToThe(double p) const; + Quaternion Inverse() const; + Quaternion Times(Quaternion b) const; + Quaternion Mirror() const; +}; + +class Vector { +public: + double x, y, z; + + static Vector From(double x, double y, double z); + static Vector From(hParam x, hParam y, hParam z); + static Vector AtIntersectionOfPlanes(Vector n1, double d1, + Vector n2, double d2); + static Vector AtIntersectionOfLines(Vector a0, Vector a1, + Vector b0, Vector b1, + bool *skew, + double *pa=NULL, double *pb=NULL); + static Vector AtIntersectionOfPlaneAndLine(Vector n, double d, + Vector p0, Vector p1, + bool *parallel); + static Vector AtIntersectionOfPlanes(Vector na, double da, + Vector nb, double db, + Vector nc, double dc, bool *parallel); + static void ClosestPointBetweenLines(Vector pa, Vector da, + Vector pb, Vector db, + double *ta, double *tb); + + double Element(int i) const; + bool Equals(Vector v, double tol=LENGTH_EPS) const; + bool EqualsExactly(Vector v) const; + Vector Plus(Vector b) const; + Vector Minus(Vector b) const; + Vector Negated() const; + Vector Cross(Vector b) const; + double DirectionCosineWith(Vector b) const; + double Dot(Vector b) const; + Vector Normal(int which) const; + Vector RotatedAbout(Vector orig, Vector axis, double theta) const; + Vector RotatedAbout(Vector axis, double theta) const; + Vector DotInToCsys(Vector u, Vector v, Vector n) const; + Vector ScaleOutOfCsys(Vector u, Vector v, Vector n) const; + double DistanceToLine(Vector p0, Vector dp) const; + double DistanceToPlane(Vector normal, Vector origin) const; + bool OnLineSegment(Vector a, Vector b, double tol=LENGTH_EPS) const; + Vector ClosestPointOnLine(Vector p0, Vector deltal) const; + double Magnitude() const; + double MagSquared() const; + Vector WithMagnitude(double s) const; + Vector ScaledBy(double s) const; + Vector ProjectInto(hEntity wrkpl) const; + Vector ProjectVectorInto(hEntity wrkpl) const; + double DivProjected(Vector delta) const; + Vector ClosestOrtho() const; + void MakeMaxMin(Vector *maxv, Vector *minv) const; + Vector ClampWithin(double minv, double maxv) const; + static bool BoundingBoxesDisjoint(Vector amax, Vector amin, + Vector bmax, Vector bmin); + static bool BoundingBoxIntersectsLine(Vector amax, Vector amin, + Vector p0, Vector p1, bool asSegment); + bool OutsideAndNotOn(Vector maxv, Vector minv) const; + Vector InPerspective(Vector u, Vector v, Vector n, + Vector origin, double cameraTan) const; + Point2d Project2d(Vector u, Vector v) const; + Point2d ProjectXy() const; + Vector4 Project4d() const; +}; + +inline double Vector::Element(int i) const { + switch (i) { + case 0: return x; + case 1: return y; + case 2: return z; + default: ssassert(false, "Unexpected vector element index"); + } +} + +inline bool Vector::Equals(Vector v, double tol) const { + // Quick axis-aligned tests before going further + const Vector dv = this->Minus(v); + if (fabs(dv.x) > tol) return false; + if (fabs(dv.y) > tol) return false; + if (fabs(dv.z) > tol) return false; + + return dv.MagSquared() < tol*tol; +} + +inline Vector Vector::From(double x, double y, double z) { + return {x, y, z}; +} + +inline Vector Vector::Plus(Vector b) const { + return {x + b.x, y + b.y, z + b.z}; +} + +inline Vector Vector::Minus(Vector b) const { + return {x - b.x, y - b.y, z - b.z}; +} + +inline Vector Vector::Negated() const { + return {-x, -y, -z}; +} + +inline Vector Vector::Cross(Vector b) const { + return {-(z * b.y) + (y * b.z), (z * b.x) - (x * b.z), -(y * b.x) + (x * b.y)}; +} + +inline double Vector::Dot(Vector b) const { + return (x * b.x + y * b.y + z * b.z); +} + +inline double Vector::MagSquared() const { + return x * x + y * y + z * z; +} + +inline double Vector::Magnitude() const { + return sqrt(x * x + y * y + z * z); +} + +inline Vector Vector::ScaledBy(const double v) const { + return {x * v, y * v, z * v}; +} + +inline void Vector::MakeMaxMin(Vector *maxv, Vector *minv) const { + maxv->x = max(maxv->x, x); + maxv->y = max(maxv->y, y); + maxv->z = max(maxv->z, z); + + minv->x = min(minv->x, x); + minv->y = min(minv->y, y); + minv->z = min(minv->z, z); +} + +struct VectorHash { + size_t operator()(const Vector &v) const; +}; + +struct VectorPred { + bool operator()(Vector a, Vector b) const; +}; + +class Vector4 { +public: + double w, x, y, z; + + static Vector4 From(double w, double x, double y, double z); + static Vector4 From(double w, Vector v3); + static Vector4 Blend(Vector4 a, Vector4 b, double t); + + Vector4 Plus(Vector4 b) const; + Vector4 Minus(Vector4 b) const; + Vector4 ScaledBy(double s) const; + Vector PerspectiveProject() const; +}; + +class Point2d { +public: + double x, y; + + static Point2d From(double x, double y); + static Point2d FromPolar(double r, double a); + + Point2d Plus(const Point2d &b) const; + Point2d Minus(const Point2d &b) const; + Point2d ScaledBy(double s) const; + double DivProjected(Point2d delta) const; + double Dot(Point2d p) const; + double DistanceTo(const Point2d &p) const; + double DistanceToLine(const Point2d &p0, const Point2d &dp, bool asSegment) const; + double DistanceToLineSigned(const Point2d &p0, const Point2d &dp, bool asSegment) const; + double Angle() const; + double AngleTo(const Point2d &p) const; + double Magnitude() const; + double MagSquared() const; + Point2d WithMagnitude(double v) const; + Point2d Normal() const; + bool Equals(Point2d v, double tol=LENGTH_EPS) const; +}; + +// A simple list +template +class List { + T *elem = nullptr; + int elemsAllocated = 0; + +public: + int n = 0; + + bool IsEmpty() const { return n == 0; } + + void ReserveMore(int howMuch) { + if(n + howMuch > elemsAllocated) { + elemsAllocated = n + howMuch; + T *newElem = (T *)::operator new[]((size_t)elemsAllocated*sizeof(T)); + for(int i = 0; i < n; i++) { + new(&newElem[i]) T(std::move(elem[i])); + elem[i].~T(); + } + ::operator delete[](elem); + elem = newElem; + } + } + + void AllocForOneMore() { + if(n >= elemsAllocated) { + ReserveMore((elemsAllocated + 32)*2 - n); + } + } + + void Add(const T *t) { + AllocForOneMore(); + new(&elem[n++]) T(*t); + } + + void AddToBeginning(const T *t) { + AllocForOneMore(); + new(&elem[n]) T(); + std::move_backward(elem, elem + 1, elem + n + 1); + elem[0] = *t; + n++; + } + + T *First() { + return IsEmpty() ? nullptr : &(elem[0]); + } + const T *First() const { + return IsEmpty() ? nullptr : &(elem[0]); + } + + T *Last() { return IsEmpty() ? nullptr : &(elem[n - 1]); } + const T *Last() const { return IsEmpty() ? nullptr : &(elem[n - 1]); } + + T *NextAfter(T *prev) { + if(IsEmpty() || !prev) return NULL; + if(prev - First() == (n - 1)) return NULL; + return prev + 1; + } + const T *NextAfter(const T *prev) const { + if(IsEmpty() || !prev) return NULL; + if(prev - First() == (n - 1)) return NULL; + return prev + 1; + } + + T &Get(size_t i) { return elem[i]; } + T const &Get(size_t i) const { return elem[i]; } + T &operator[](size_t i) { return Get(i); } + T const &operator[](size_t i) const { return Get(i); } + + T *begin() { return IsEmpty() ? nullptr : &elem[0]; } + T *end() { return IsEmpty() ? nullptr : &elem[n]; } + const T *begin() const { return IsEmpty() ? nullptr : &elem[0]; } + const T *end() const { return IsEmpty() ? nullptr : &elem[n]; } + const T *cbegin() const { return begin(); } + const T *cend() const { return end(); } + + void ClearTags() { + for(auto & elt : *this) { + elt.tag = 0; + } + } + + void Clear() { + for(int i = 0; i < n; i++) + elem[i].~T(); + if(elem) ::operator delete[](elem); + elem = NULL; + n = elemsAllocated = 0; + } + + void RemoveTagged() { + auto newEnd = std::remove_if(this->begin(), this->end(), [](T &t) { + if(t.tag) { + return true; + } + return false; + }); + auto oldEnd = this->end(); + n = newEnd - begin(); + if (newEnd != nullptr && oldEnd != nullptr) { + while(newEnd != oldEnd) { + newEnd->~T(); + ++newEnd; + } + } + // and elemsAllocated is untouched, because we didn't resize + } + + void RemoveLast(int cnt) { + ssassert(n >= cnt, "Removing more elements than the list contains"); + for(int i = n - cnt; i < n; i++) + elem[i].~T(); + n -= cnt; + // and elemsAllocated is untouched, same as in RemoveTagged + } + + void Reverse() { + int i; + for(i = 0; i < (n/2); i++) { + swap(elem[i], elem[(n-1)-i]); + } + } +}; + +// Comparison functor used by IdList and related classes +template +struct CompareId { + bool operator()(T const& lhs, T const& rhs) const { + return lhs.h.v < rhs.h.v; + } + bool operator()(T const& lhs, H rhs) const { + return lhs.h.v < rhs.v; + } +}; + +// A list, where each element has an integer identifier. The list is kept +// sorted by that identifier, and items can be looked up in log n time by +// id. +template +class IdList { + T *elem = nullptr; + int elemsAllocated = 0; +public: + int n = 0; + + using Compare = CompareId; + + bool IsEmpty() const { + return n == 0; + } + + void AllocForOneMore() { + if(n >= elemsAllocated) { + ReserveMore((elemsAllocated + 32)*2 - n); + } + } + + uint32_t MaximumId() { + if(IsEmpty()) { + return 0; + } else { + return Last()->h.v; + } + } + + H AddAndAssignId(T *t) { + t->h.v = (MaximumId() + 1); + AllocForOneMore(); + + // Copy-construct at the end of the list. + new(&elem[n]) T(*t); + ++n; + + return t->h; + } + + T * LowerBound(T const& t) { + if(IsEmpty()) { + return nullptr; + } + auto it = std::lower_bound(begin(), end(), t, Compare()); + return it; + } + + T * LowerBound(H const& h) { + if(IsEmpty()) { + return nullptr; + } + auto it = std::lower_bound(begin(), end(), h, Compare()); + return it; + } + + int LowerBoundIndex(T const& t) { + if(IsEmpty()) { + return 0; + } + auto it = LowerBound(t); + auto idx = std::distance(begin(), it); + auto i = static_cast(idx); + return i; + } + void ReserveMore(int howMuch) { + if(n + howMuch > elemsAllocated) { + elemsAllocated = n + howMuch; + T *newElem = (T *)::operator new[]((size_t)elemsAllocated*sizeof(T)); + for(int i = 0; i < n; i++) { + new(&newElem[i]) T(std::move(elem[i])); + elem[i].~T(); + } + ::operator delete[](elem); + elem = newElem; + } + } + + void Add(T *t) { + AllocForOneMore(); + + // Look to see if we already have something with the same handle value. + ssassert(FindByIdNoOops(t->h) == nullptr, "Handle isn't unique"); + + // Copy-construct at the end of the list. + new(&elem[n]) T(*t); + ++n; + // The item we just added is trivially sorted, so "merge" + std::inplace_merge(begin(), end() - 1, end(), Compare()); + } + + T *FindById(H h) { + T *t = FindByIdNoOops(h); + ssassert(t != NULL, "Cannot find handle"); + return t; + } + + int IndexOf(H h) { + if(IsEmpty()) { + return -1; + } + auto it = LowerBound(h); + auto idx = std::distance(begin(), it); + if (idx < n) { + return idx; + } + return -1; + } + + T *FindByIdNoOops(H h) { + if(IsEmpty()) { + return nullptr; + } + auto it = LowerBound(h); + if (it == nullptr || it == end()) { + return nullptr; + } + if (it->h.v == h.v) { + return it; + } + return nullptr; + } + + T *First() { + return (IsEmpty()) ? NULL : &(elem[0]); + } + T *Last() { + return (IsEmpty()) ? NULL : &(elem[n-1]); + } + T *NextAfter(T *prev) { + if(IsEmpty() || !prev) return NULL; + if(prev - First() == (n - 1)) return NULL; + return prev + 1; + } + + T &Get(size_t i) { return elem[i]; } + T const &Get(size_t i) const { return elem[i]; } + T &operator[](size_t i) { return Get(i); } + T const &operator[](size_t i) const { return Get(i); } + + T *begin() { return IsEmpty() ? nullptr : &elem[0]; } + T *end() { return IsEmpty() ? nullptr : &elem[0] + n; } + const T *begin() const { return IsEmpty() ? nullptr : &elem[0]; } + const T *end() const { return IsEmpty() ? nullptr : &elem[0] + n; } + const T *cbegin() const { return begin(); } + const T *cend() const { return end(); } + + void ClearTags() { + for(auto &elt : *this) { elt.tag = 0; } + } + + void Tag(H h, int tag) { + auto it = FindByIdNoOops(h); + if (it != nullptr) { + it->tag = tag; + } + } + + void RemoveTagged() { + int src, dest; + dest = 0; + for(src = 0; src < n; src++) { + if(elem[src].tag) { + // this item should be deleted + elem[src].Clear(); + } else { + if(src != dest) { + elem[dest] = elem[src]; + } + dest++; + } + } + for(int i = dest; i < n; i++) + elem[i].~T(); + n = dest; + // and elemsAllocated is untouched, because we didn't resize + } + void RemoveById(H h) { + ClearTags(); + FindById(h)->tag = 1; + RemoveTagged(); + } + + void MoveSelfInto(IdList *l) { + l->Clear(); + std::swap(l->elem, elem); + std::swap(l->elemsAllocated, elemsAllocated); + std::swap(l->n, n); + } + + void DeepCopyInto(IdList *l) { + l->Clear(); + l->elem = (T *)::operator new[](elemsAllocated * sizeof(elem[0])); + for(int i = 0; i < n; i++) + new(&l->elem[i]) T(elem[i]); + l->elemsAllocated = elemsAllocated; + l->n = n; + } + + void Clear() { + for(int i = 0; i < n; i++) { + elem[i].Clear(); + elem[i].~T(); + } + if(elem) ::operator delete[](elem); + elem = NULL; + elemsAllocated = n = 0; + } + +}; + +class BandedMatrix { +public: + enum { + MAX_UNKNOWNS = 16, + RIGHT_OF_DIAG = 1, + LEFT_OF_DIAG = 2 + }; + + double A[MAX_UNKNOWNS][MAX_UNKNOWNS]; + double B[MAX_UNKNOWNS]; + double X[MAX_UNKNOWNS]; + int n; + + void Solve(); +}; + +#define RGBi(r, g, b) RgbaColor::From((r), (g), (b)) +#define RGBf(r, g, b) RgbaColor::FromFloat((float)(r), (float)(g), (float)(b)) + +// Note: sizeof(class RgbaColor) should be exactly 4 +// +class RgbaColor { +public: + uint8_t red, green, blue, alpha; + + float redF() const { return (float)red / 255.0f; } + float greenF() const { return (float)green / 255.0f; } + float blueF() const { return (float)blue / 255.0f; } + float alphaF() const { return (float)alpha / 255.0f; } + + bool IsEmpty() const { return alpha == 0; } + + bool Equals(RgbaColor c) const { + return + c.red == red && + c.green == green && + c.blue == blue && + c.alpha == alpha; + } + + RgbaColor WithAlpha(uint8_t newAlpha) const { + RgbaColor color = *this; + color.alpha = newAlpha; + return color; + } + + uint32_t ToPackedIntBGRA() const { + return + blue | + (uint32_t)(green << 8) | + (uint32_t)(red << 16) | + (uint32_t)((255 - alpha) << 24); + } + + uint32_t ToPackedInt() const { + return + red | + (uint32_t)(green << 8) | + (uint32_t)(blue << 16) | + (uint32_t)((255 - alpha) << 24); + } + + uint32_t ToARGB32() const { + return + blue | + (uint32_t)(green << 8) | + (uint32_t)(red << 16) | + (uint32_t)(alpha << 24); + } + + static RgbaColor From(int r, int g, int b, int a = 255) { + RgbaColor c; + c.red = (uint8_t)r; + c.green = (uint8_t)g; + c.blue = (uint8_t)b; + c.alpha = (uint8_t)a; + return c; + } + + static RgbaColor FromFloat(float r, float g, float b, float a = 1.0) { + return From( + (int)(255.1f * r), + (int)(255.1f * g), + (int)(255.1f * b), + (int)(255.1f * a)); + } + + static RgbaColor FromPackedInt(uint32_t rgba) { + return From( + (int)((rgba) & 0xff), + (int)((rgba >> 8) & 0xff), + (int)((rgba >> 16) & 0xff), + (int)(255 - ((rgba >> 24) & 0xff))); + } + + static RgbaColor FromPackedIntBGRA(uint32_t bgra) { + return From( + (int)((bgra >> 16) & 0xff), + (int)((bgra >> 8) & 0xff), + (int)((bgra) & 0xff), + (int)(255 - ((bgra >> 24) & 0xff))); + } +}; + +struct RgbaColorCompare { + bool operator()(RgbaColor a, RgbaColor b) const { + return a.ToARGB32() < b.ToARGB32(); + } +}; + +class BBox { +public: + Vector minp; + Vector maxp; + + static BBox From(const Vector &p0, const Vector &p1); + + Vector GetOrigin() const; + Vector GetExtents() const; + + void Include(const Vector &v, double r = 0.0); + bool Overlaps(const BBox &b1) const; + bool Contains(const Point2d &p, double r = 0.0) const; +}; + +#endif diff --git a/src/entity.cpp b/src/entity.cpp new file mode 100644 index 0000000..a0f2f94 --- /dev/null +++ b/src/entity.cpp @@ -0,0 +1,984 @@ +//----------------------------------------------------------------------------- +// The implementation of our entities in the symbolic algebra system, methods +// to return a symbolic representation of the entity (line by its endpoints, +// circle by center and radius, etc.). +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +const hEntity EntityBase::FREE_IN_3D = { 0 }; +const hEntity EntityBase::NO_ENTITY = { 0 }; + +bool EntityBase::HasVector() const { + switch(type) { + case Type::LINE_SEGMENT: + case Type::NORMAL_IN_3D: + case Type::NORMAL_IN_2D: + case Type::NORMAL_N_COPY: + case Type::NORMAL_N_ROT: + case Type::NORMAL_N_ROT_AA: + return true; + + default: + return false; + } +} + +ExprVector EntityBase::VectorGetExprsInWorkplane(hEntity wrkpl) const { + switch(type) { + case Type::LINE_SEGMENT: + return (SK.GetEntity(point[0])->PointGetExprsInWorkplane(wrkpl)).Minus( + SK.GetEntity(point[1])->PointGetExprsInWorkplane(wrkpl)); + + case Type::NORMAL_IN_3D: + case Type::NORMAL_IN_2D: + case Type::NORMAL_N_COPY: + case Type::NORMAL_N_ROT: + case Type::NORMAL_N_ROT_AA: { + ExprVector ev = NormalExprsN(); + if(wrkpl == EntityBase::FREE_IN_3D) { + return ev; + } + // Get the offset and basis vectors for this weird exotic csys. + EntityBase *w = SK.GetEntity(wrkpl); + ExprVector wu = w->Normal()->NormalExprsU(); + ExprVector wv = w->Normal()->NormalExprsV(); + + // Get our coordinates in three-space, and project them into that + // coordinate system. + ExprVector result; + result.x = ev.Dot(wu); + result.y = ev.Dot(wv); + result.z = Expr::From(0.0); + return result; + } + default: ssassert(false, "Unexpected entity type"); + } +} + +ExprVector EntityBase::VectorGetExprs() const { + return VectorGetExprsInWorkplane(EntityBase::FREE_IN_3D); +} + +Vector EntityBase::VectorGetNum() const { + switch(type) { + case Type::LINE_SEGMENT: + return (SK.GetEntity(point[0])->PointGetNum()).Minus( + SK.GetEntity(point[1])->PointGetNum()); + + case Type::NORMAL_IN_3D: + case Type::NORMAL_IN_2D: + case Type::NORMAL_N_COPY: + case Type::NORMAL_N_ROT: + case Type::NORMAL_N_ROT_AA: + return NormalN(); + + default: ssassert(false, "Unexpected entity type"); + } +} + +Vector EntityBase::VectorGetRefPoint() const { + switch(type) { + case Type::LINE_SEGMENT: + return ((SK.GetEntity(point[0])->PointGetNum()).Plus( + SK.GetEntity(point[1])->PointGetNum())).ScaledBy(0.5); + + case Type::NORMAL_IN_3D: + case Type::NORMAL_IN_2D: + case Type::NORMAL_N_COPY: + case Type::NORMAL_N_ROT: + case Type::NORMAL_N_ROT_AA: + return SK.GetEntity(point[0])->PointGetNum(); + + default: ssassert(false, "Unexpected entity type"); + } +} + +Vector EntityBase::VectorGetStartPoint() const { + switch(type) { + case Type::LINE_SEGMENT: + return SK.GetEntity(point[1])->PointGetNum(); + + case Type::NORMAL_IN_3D: + case Type::NORMAL_IN_2D: + case Type::NORMAL_N_COPY: + case Type::NORMAL_N_ROT: + case Type::NORMAL_N_ROT_AA: + return SK.GetEntity(point[0])->PointGetNum(); + + default: ssassert(false, "Unexpected entity type"); + } +} + +bool EntityBase::IsCircle() const { + return (type == Type::CIRCLE) || (type == Type::ARC_OF_CIRCLE); +} + +Expr *EntityBase::CircleGetRadiusExpr() const { + if(type == Type::CIRCLE) { + return SK.GetEntity(distance)->DistanceGetExpr(); + } else if(type == Type::ARC_OF_CIRCLE) { + return Constraint::Distance(workplane, point[0], point[1]); + } else ssassert(false, "Unexpected entity type"); +} + +double EntityBase::CircleGetRadiusNum() const { + if(type == Type::CIRCLE) { + return SK.GetEntity(distance)->DistanceGetNum(); + } else if(type == Type::ARC_OF_CIRCLE) { + Vector c = SK.GetEntity(point[0])->PointGetNum(); + Vector pa = SK.GetEntity(point[1])->PointGetNum(); + return (pa.Minus(c)).Magnitude(); + } else ssassert(false, "Unexpected entity type"); +} + +void EntityBase::ArcGetAngles(double *thetaa, double *thetab, double *dtheta) const { + ssassert(type == Type::ARC_OF_CIRCLE, "Unexpected entity type"); + + Quaternion q = Normal()->NormalGetNum(); + Vector u = q.RotationU(), v = q.RotationV(); + + Vector c = SK.GetEntity(point[0])->PointGetNum(); + Vector pa = SK.GetEntity(point[1])->PointGetNum(); + Vector pb = SK.GetEntity(point[2])->PointGetNum(); + + Point2d c2 = c.Project2d(u, v); + Point2d pa2 = (pa.Project2d(u, v)).Minus(c2); + Point2d pb2 = (pb.Project2d(u, v)).Minus(c2); + + *thetaa = atan2(pa2.y, pa2.x); + *thetab = atan2(pb2.y, pb2.x); + *dtheta = *thetab - *thetaa; + // If the endpoints are coincident, call it a full arc, not a zero arc; + // useful concept to have when splitting + while(*dtheta < 1e-6) *dtheta += 2*PI; + while(*dtheta > (2*PI)) *dtheta -= 2*PI; +} + +Vector EntityBase::CubicGetStartNum() const { + return SK.GetEntity(point[0])->PointGetNum(); +} +Vector EntityBase::CubicGetFinishNum() const { + return SK.GetEntity(point[3+extraPoints])->PointGetNum(); +} +ExprVector EntityBase::CubicGetStartTangentExprs() const { + ExprVector pon = SK.GetEntity(point[0])->PointGetExprs(), + poff = SK.GetEntity(point[1])->PointGetExprs(); + return (pon.Minus(poff)); +} +ExprVector EntityBase::CubicGetFinishTangentExprs() const { + ExprVector pon = SK.GetEntity(point[3+extraPoints])->PointGetExprs(), + poff = SK.GetEntity(point[2+extraPoints])->PointGetExprs(); + return (pon.Minus(poff)); +} +Vector EntityBase::CubicGetStartTangentNum() const { + Vector pon = SK.GetEntity(point[0])->PointGetNum(), + poff = SK.GetEntity(point[1])->PointGetNum(); + return (pon.Minus(poff)); +} +Vector EntityBase::CubicGetFinishTangentNum() const { + Vector pon = SK.GetEntity(point[3+extraPoints])->PointGetNum(), + poff = SK.GetEntity(point[2+extraPoints])->PointGetNum(); + return (pon.Minus(poff)); +} + +bool EntityBase::IsWorkplane() const { + return (type == Type::WORKPLANE); +} + +ExprVector EntityBase::WorkplaneGetOffsetExprs() const { + return SK.GetEntity(point[0])->PointGetExprs(); +} + +Vector EntityBase::WorkplaneGetOffset() const { + return SK.GetEntity(point[0])->PointGetNum(); +} + +void EntityBase::WorkplaneGetPlaneExprs(ExprVector *n, Expr **dn) const { + if(type == Type::WORKPLANE) { + *n = Normal()->NormalExprsN(); + + ExprVector p0 = SK.GetEntity(point[0])->PointGetExprs(); + // The plane is n dot (p - p0) = 0, or + // n dot p - n dot p0 = 0 + // so dn = n dot p0 + *dn = p0.Dot(*n); + } else ssassert(false, "Unexpected entity type"); +} + +bool EntityBase::IsDistance() const { + return (type == Type::DISTANCE) || + (type == Type::DISTANCE_N_COPY); +} +double EntityBase::DistanceGetNum() const { + if(type == Type::DISTANCE) { + return SK.GetParam(param[0])->val; + } else if(type == Type::DISTANCE_N_COPY) { + return numDistance; + } else ssassert(false, "Unexpected entity type"); +} +Expr *EntityBase::DistanceGetExpr() const { + if(type == Type::DISTANCE) { + return Expr::From(param[0]); + } else if(type == Type::DISTANCE_N_COPY) { + return Expr::From(numDistance); + } else ssassert(false, "Unexpected entity type"); +} +void EntityBase::DistanceForceTo(double v) { + if(type == Type::DISTANCE) { + (SK.GetParam(param[0]))->val = v; + } else if(type == Type::DISTANCE_N_COPY) { + // do nothing, it's locked + } else ssassert(false, "Unexpected entity type"); +} + +EntityBase *EntityBase::Normal() const { + return SK.GetEntity(normal); +} + +bool EntityBase::IsPoint() const { + switch(type) { + case Type::POINT_IN_3D: + case Type::POINT_IN_2D: + case Type::POINT_N_COPY: + case Type::POINT_N_TRANS: + case Type::POINT_N_ROT_TRANS: + case Type::POINT_N_ROT_AA: + case Type::POINT_N_ROT_AXIS_TRANS: + return true; + + default: + return false; + } +} + +bool EntityBase::IsNormal() const { + switch(type) { + case Type::NORMAL_IN_3D: + case Type::NORMAL_IN_2D: + case Type::NORMAL_N_COPY: + case Type::NORMAL_N_ROT: + case Type::NORMAL_N_ROT_AA: + return true; + + default: return false; + } +} + +Quaternion EntityBase::NormalGetNum() const { + Quaternion q; + switch(type) { + case Type::NORMAL_IN_3D: + q = Quaternion::From(param[0], param[1], param[2], param[3]); + break; + + case Type::NORMAL_IN_2D: { + EntityBase *wrkpl = SK.GetEntity(workplane); + EntityBase *norm = SK.GetEntity(wrkpl->normal); + q = norm->NormalGetNum(); + break; + } + case Type::NORMAL_N_COPY: + q = numNormal; + break; + + case Type::NORMAL_N_ROT: + q = Quaternion::From(param[0], param[1], param[2], param[3]); + q = q.Times(numNormal); + break; + + case Type::NORMAL_N_ROT_AA: { + q = GetAxisAngleQuaternion(0); + q = q.Times(numNormal); + break; + } + + default: ssassert(false, "Unexpected entity type"); + } + return q; +} + +void EntityBase::NormalForceTo(Quaternion q) { + switch(type) { + case Type::NORMAL_IN_3D: + SK.GetParam(param[0])->val = q.w; + SK.GetParam(param[1])->val = q.vx; + SK.GetParam(param[2])->val = q.vy; + SK.GetParam(param[3])->val = q.vz; + break; + + case Type::NORMAL_IN_2D: + case Type::NORMAL_N_COPY: + // There's absolutely nothing to do; these are locked. + break; + case Type::NORMAL_N_ROT: { + Quaternion qp = q.Times(numNormal.Inverse()); + + SK.GetParam(param[0])->val = qp.w; + SK.GetParam(param[1])->val = qp.vx; + SK.GetParam(param[2])->val = qp.vy; + SK.GetParam(param[3])->val = qp.vz; + break; + } + + case Type::NORMAL_N_ROT_AA: + // Not sure if I'll bother implementing this one + break; + + default: ssassert(false, "Unexpected entity type"); + } +} + +Vector EntityBase::NormalU() const { + return NormalGetNum().RotationU(); +} +Vector EntityBase::NormalV() const { + return NormalGetNum().RotationV(); +} +Vector EntityBase::NormalN() const { + return NormalGetNum().RotationN(); +} + +ExprVector EntityBase::NormalExprsU() const { + return NormalGetExprs().RotationU(); +} +ExprVector EntityBase::NormalExprsV() const { + return NormalGetExprs().RotationV(); +} +ExprVector EntityBase::NormalExprsN() const { + return NormalGetExprs().RotationN(); +} + +ExprQuaternion EntityBase::NormalGetExprs() const { + ExprQuaternion q; + switch(type) { + case Type::NORMAL_IN_3D: + q = ExprQuaternion::From(param[0], param[1], param[2], param[3]); + break; + + case Type::NORMAL_IN_2D: { + EntityBase *wrkpl = SK.GetEntity(workplane); + EntityBase *norm = SK.GetEntity(wrkpl->normal); + q = norm->NormalGetExprs(); + break; + } + case Type::NORMAL_N_COPY: + q = ExprQuaternion::From(numNormal); + break; + + case Type::NORMAL_N_ROT: { + ExprQuaternion orig = ExprQuaternion::From(numNormal); + q = ExprQuaternion::From(param[0], param[1], param[2], param[3]); + + q = q.Times(orig); + break; + } + + case Type::NORMAL_N_ROT_AA: { + ExprQuaternion orig = ExprQuaternion::From(numNormal); + q = GetAxisAngleQuaternionExprs(0); + q = q.Times(orig); + break; + } + + default: ssassert(false, "Unexpected entity type"); + } + return q; +} + +void EntityBase::PointForceParamTo(Vector p) { + switch(type) { + case Type::POINT_IN_3D: + SK.GetParam(param[0])->val = p.x; + SK.GetParam(param[1])->val = p.y; + SK.GetParam(param[2])->val = p.z; + break; + + case Type::POINT_IN_2D: + SK.GetParam(param[0])->val = p.x; + SK.GetParam(param[1])->val = p.y; + break; + + default: ssassert(false, "Unexpected entity type"); + } +} + +void EntityBase::PointForceTo(Vector p) { + switch(type) { + case Type::POINT_IN_3D: + SK.GetParam(param[0])->val = p.x; + SK.GetParam(param[1])->val = p.y; + SK.GetParam(param[2])->val = p.z; + break; + + case Type::POINT_IN_2D: { + EntityBase *c = SK.GetEntity(workplane); + p = p.Minus(c->WorkplaneGetOffset()); + SK.GetParam(param[0])->val = p.Dot(c->Normal()->NormalU()); + SK.GetParam(param[1])->val = p.Dot(c->Normal()->NormalV()); + break; + } + + case Type::POINT_N_TRANS: { + if(timesApplied == 0) break; + Vector trans = (p.Minus(numPoint)).ScaledBy(1.0/timesApplied); + SK.GetParam(param[0])->val = trans.x; + SK.GetParam(param[1])->val = trans.y; + SK.GetParam(param[2])->val = trans.z; + break; + } + + case Type::POINT_N_ROT_TRANS: { + // Force only the translation; leave the rotation unchanged. But + // remember that we're working with respect to the rotated + // point. + Vector trans = p.Minus(PointGetQuaternion().Rotate(numPoint)); + SK.GetParam(param[0])->val = trans.x; + SK.GetParam(param[1])->val = trans.y; + SK.GetParam(param[2])->val = trans.z; + break; + } + + case Type::POINT_N_ROT_AA: { + // Force only the angle; the axis and center of rotation stay + Vector offset = Vector::From(param[0], param[1], param[2]); + Vector normal = Vector::From(param[4], param[5], param[6]); + Vector u = normal.Normal(0), v = normal.Normal(1); + Vector po = p.Minus(offset), numo = numPoint.Minus(offset); + double thetap = atan2(v.Dot(po), u.Dot(po)); + double thetan = atan2(v.Dot(numo), u.Dot(numo)); + double thetaf = (thetap - thetan); + double thetai = (SK.GetParam(param[3])->val)*timesApplied*2; + double dtheta = thetaf - thetai; + // Take the smallest possible change in the actual step angle, + // in order to avoid jumps when you cross from +pi to -pi + while(dtheta < -PI) dtheta += 2*PI; + while(dtheta > PI) dtheta -= 2*PI; + // this extra *2 explains the mystery *4 + SK.GetParam(param[3])->val = (thetai + dtheta)/(timesApplied*2); + break; + } + + case Type::POINT_N_ROT_AXIS_TRANS: { + if(timesApplied == 0) break; + // is the point on the rotation axis? + Vector offset = Vector::From(param[0], param[1], param[2]); + Vector normal = Vector::From(param[4], param[5], param[6]).WithMagnitude(1.0); + Vector check = numPoint.Minus(offset).Cross(normal); + if (check.Dot(check) < LENGTH_EPS) { // if so, do extrusion style drag + Vector trans = (p.Minus(numPoint)); + SK.GetParam(param[7])->val = trans.Dot(normal)/timesApplied; + } else { // otherwise do rotation style + Vector u = normal.Normal(0), v = normal.Normal(1); + Vector po = p.Minus(offset), numo = numPoint.Minus(offset); + double thetap = atan2(v.Dot(po), u.Dot(po)); + double thetan = atan2(v.Dot(numo), u.Dot(numo)); + double thetaf = (thetap - thetan); + double thetai = (SK.GetParam(param[3])->val)*timesApplied*2; + double dtheta = thetaf - thetai; + // Take the smallest possible change in the actual step angle, + // in order to avoid jumps when you cross from +pi to -pi + while(dtheta < -PI) dtheta += 2*PI; + while(dtheta > PI) dtheta -= 2*PI; + // this extra *2 explains the mystery *4 + SK.GetParam(param[3])->val = (thetai + dtheta)/(timesApplied*2); + } + break; + } + + case Type::POINT_N_COPY: + // Nothing to do; it's a static copy + break; + + default: ssassert(false, "Unexpected entity type"); + } +} + +Vector EntityBase::PointGetNum() const { + Vector p; + switch(type) { + case Type::POINT_IN_3D: + p = Vector::From(param[0], param[1], param[2]); + break; + + case Type::POINT_IN_2D: { + EntityBase *c = SK.GetEntity(workplane); + Vector u = c->Normal()->NormalU(); + Vector v = c->Normal()->NormalV(); + p = u.ScaledBy(SK.GetParam(param[0])->val); + p = p.Plus(v.ScaledBy(SK.GetParam(param[1])->val)); + p = p.Plus(c->WorkplaneGetOffset()); + break; + } + + case Type::POINT_N_TRANS: { + Vector trans = Vector::From(param[0], param[1], param[2]); + p = numPoint.Plus(trans.ScaledBy(timesApplied)); + break; + } + + case Type::POINT_N_ROT_TRANS: { + Vector offset = Vector::From(param[0], param[1], param[2]); + Quaternion q = PointGetQuaternion(); + p = q.Rotate(numPoint); + p = p.Plus(offset); + break; + } + + case Type::POINT_N_ROT_AA: { + Vector offset = Vector::From(param[0], param[1], param[2]); + Quaternion q = PointGetQuaternion(); + p = numPoint.Minus(offset); + p = q.Rotate(p); + p = p.Plus(offset); + break; + } + + case Type::POINT_N_ROT_AXIS_TRANS: { + Vector offset = Vector::From(param[0], param[1], param[2]); + Vector displace = Vector::From(param[4], param[5], param[6]) + .WithMagnitude(SK.GetParam(param[7])->val).ScaledBy(timesApplied); + Quaternion q = PointGetQuaternion(); + p = numPoint.Minus(offset); + p = q.Rotate(p); + p = p.Plus(offset).Plus(displace); + break; + } + + case Type::POINT_N_COPY: + p = numPoint; + break; + + default: ssassert(false, "Unexpected entity type"); + } + return p; +} + +ExprVector EntityBase::PointGetExprs() const { + ExprVector r; + switch(type) { + case Type::POINT_IN_3D: + r = ExprVector::From(param[0], param[1], param[2]); + break; + + case Type::POINT_IN_2D: { + EntityBase *c = SK.GetEntity(workplane); + ExprVector u = c->Normal()->NormalExprsU(); + ExprVector v = c->Normal()->NormalExprsV(); + r = c->WorkplaneGetOffsetExprs(); + r = r.Plus(u.ScaledBy(Expr::From(param[0]))); + r = r.Plus(v.ScaledBy(Expr::From(param[1]))); + break; + } + case Type::POINT_N_TRANS: { + ExprVector orig = ExprVector::From(numPoint); + ExprVector trans = ExprVector::From(param[0], param[1], param[2]); + r = orig.Plus(trans.ScaledBy(Expr::From(timesApplied))); + break; + } + case Type::POINT_N_ROT_TRANS: { + ExprVector orig = ExprVector::From(numPoint); + ExprVector trans = ExprVector::From(param[0], param[1], param[2]); + ExprQuaternion q = + ExprQuaternion::From(param[3], param[4], param[5], param[6]); + orig = q.Rotate(orig); + r = orig.Plus(trans); + break; + } + case Type::POINT_N_ROT_AA: { + ExprVector orig = ExprVector::From(numPoint); + ExprVector trans = ExprVector::From(param[0], param[1], param[2]); + ExprQuaternion q = GetAxisAngleQuaternionExprs(3); + orig = orig.Minus(trans); + orig = q.Rotate(orig); + r = orig.Plus(trans); + break; + } + case Type::POINT_N_ROT_AXIS_TRANS: { + ExprVector orig = ExprVector::From(numPoint); + ExprVector trans = ExprVector::From(param[0], param[1], param[2]); + ExprVector displace = ExprVector::From(param[4], param[5], param[6]) + .WithMagnitude(Expr::From(1.0)).ScaledBy(Expr::From(timesApplied)).ScaledBy(Expr::From(param[7])); + + ExprQuaternion q = GetAxisAngleQuaternionExprs(3); + orig = orig.Minus(trans); + orig = q.Rotate(orig); + r = orig.Plus(trans).Plus(displace); + break; + } + case Type::POINT_N_COPY: + r = ExprVector::From(numPoint); + break; + + default: ssassert(false, "Unexpected entity type"); + } + return r; +} + +void EntityBase::PointGetExprsInWorkplane(hEntity wrkpl, Expr **u, Expr **v) const { + if(type == Type::POINT_IN_2D && workplane == wrkpl) { + // They want our coordinates in the form that we've written them, + // very nice. + *u = Expr::From(param[0]); + *v = Expr::From(param[1]); + } else { + // Get the offset and basis vectors for this weird exotic csys. + EntityBase *w = SK.GetEntity(wrkpl); + ExprVector wp = w->WorkplaneGetOffsetExprs(); + ExprVector wu = w->Normal()->NormalExprsU(); + ExprVector wv = w->Normal()->NormalExprsV(); + + // Get our coordinates in three-space, and project them into that + // coordinate system. + ExprVector ev = PointGetExprs(); + ev = ev.Minus(wp); + *u = ev.Dot(wu); + *v = ev.Dot(wv); + } +} + +ExprVector EntityBase::PointGetExprsInWorkplane(hEntity wrkpl) const { + if(wrkpl == Entity::FREE_IN_3D) { + return PointGetExprs(); + } + + ExprVector r; + PointGetExprsInWorkplane(wrkpl, &r.x, &r.y); + r.z = Expr::From(0.0); + return r; +} + +void EntityBase::PointForceQuaternionTo(Quaternion q) { + ssassert(type == Type::POINT_N_ROT_TRANS, "Unexpected entity type"); + + SK.GetParam(param[3])->val = q.w; + SK.GetParam(param[4])->val = q.vx; + SK.GetParam(param[5])->val = q.vy; + SK.GetParam(param[6])->val = q.vz; +} + +Quaternion EntityBase::GetAxisAngleQuaternion(int param0) const { + Quaternion q; + double theta = timesApplied*SK.GetParam(param[param0+0])->val; + double s = sin(theta), c = cos(theta); + q.w = c; + q.vx = s*SK.GetParam(param[param0+1])->val; + q.vy = s*SK.GetParam(param[param0+2])->val; + q.vz = s*SK.GetParam(param[param0+3])->val; + return q; +} + +ExprQuaternion EntityBase::GetAxisAngleQuaternionExprs(int param0) const { + ExprQuaternion q; + + Expr *theta = Expr::From(timesApplied)->Times( + Expr::From(param[param0+0])); + Expr *c = theta->Cos(), *s = theta->Sin(); + q.w = c; + q.vx = s->Times(Expr::From(param[param0+1])); + q.vy = s->Times(Expr::From(param[param0+2])); + q.vz = s->Times(Expr::From(param[param0+3])); + return q; +} + +Quaternion EntityBase::PointGetQuaternion() const { + Quaternion q; + + if(type == Type::POINT_N_ROT_AA || type == Type::POINT_N_ROT_AXIS_TRANS) { + q = GetAxisAngleQuaternion(3); + } else if(type == Type::POINT_N_ROT_TRANS) { + q = Quaternion::From(param[3], param[4], param[5], param[6]); + } else ssassert(false, "Unexpected entity type"); + + return q; +} + +bool EntityBase::IsFace() const { + switch(type) { + case Type::FACE_NORMAL_PT: + case Type::FACE_XPROD: + case Type::FACE_N_ROT_TRANS: + case Type::FACE_N_TRANS: + case Type::FACE_N_ROT_AA: + case Type::FACE_ROT_NORMAL_PT: + case Type::FACE_N_ROT_AXIS_TRANS: + return true; + default: + return false; + } +} + +ExprVector EntityBase::FaceGetNormalExprs() const { + ExprVector r; + if(type == Type::FACE_NORMAL_PT) { + Vector v = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz); + r = ExprVector::From(v.WithMagnitude(1)); + } else if(type == Type::FACE_XPROD) { + ExprVector vc = ExprVector::From(param[0], param[1], param[2]); + ExprVector vn = + ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz); + r = vc.Cross(vn); + r = r.WithMagnitude(Expr::From(1.0)); + } else if(type == Type::FACE_N_ROT_TRANS) { + // The numerical normal vector gets the rotation; the numerical + // normal has magnitude one, and the rotation doesn't change that, + // so there's no need to fix it up. + r = ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz); + ExprQuaternion q = + ExprQuaternion::From(param[3], param[4], param[5], param[6]); + r = q.Rotate(r); + } else if(type == Type::FACE_N_TRANS) { + r = ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz); + } else if((type == Type::FACE_N_ROT_AA) || (type == Type::FACE_ROT_NORMAL_PT)) { + r = ExprVector::From(numNormal.vx, numNormal.vy, numNormal.vz); + ExprQuaternion q = GetAxisAngleQuaternionExprs(3); + r = q.Rotate(r); + } else ssassert(false, "Unexpected entity type"); + return r; +} + +Vector EntityBase::FaceGetNormalNum() const { + Vector r; + if(type == Type::FACE_NORMAL_PT) { + r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz); + } else if(type == Type::FACE_XPROD) { + Vector vc = Vector::From(param[0], param[1], param[2]); + Vector vn = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz); + r = vc.Cross(vn); + } else if(type == Type::FACE_N_ROT_TRANS) { + // The numerical normal vector gets the rotation + r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz); + Quaternion q = Quaternion::From(param[3], param[4], param[5], param[6]); + r = q.Rotate(r); + } else if(type == Type::FACE_N_TRANS) { + r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz); + } else if((type == Type::FACE_N_ROT_AA) || (type == Type::FACE_ROT_NORMAL_PT)) { + r = Vector::From(numNormal.vx, numNormal.vy, numNormal.vz); + Quaternion q = GetAxisAngleQuaternion(3); + r = q.Rotate(r); + } else ssassert(false, "Unexpected entity type"); + return r.WithMagnitude(1); +} + +ExprVector EntityBase::FaceGetPointExprs() const { + ExprVector r; + if((type == Type::FACE_NORMAL_PT) || (type==Type::FACE_ROT_NORMAL_PT)) { + r = SK.GetEntity(point[0])->PointGetExprs(); + } else if(type == Type::FACE_XPROD) { + r = ExprVector::From(numPoint); + } else if(type == Type::FACE_N_ROT_TRANS) { + // The numerical point gets the rotation and translation. + ExprVector trans = ExprVector::From(param[0], param[1], param[2]); + ExprQuaternion q = + ExprQuaternion::From(param[3], param[4], param[5], param[6]); + r = ExprVector::From(numPoint); + r = q.Rotate(r); + r = r.Plus(trans); + } else if(type == Type::FACE_N_ROT_AXIS_TRANS) { + ExprVector orig = ExprVector::From(numPoint); + ExprVector trans = ExprVector::From(param[0], param[1], param[2]); + ExprVector displace = ExprVector::From(param[4], param[5], param[6]) + .WithMagnitude(Expr::From(param[7])).ScaledBy(Expr::From(timesApplied)); + ExprQuaternion q = GetAxisAngleQuaternionExprs(3); + orig = orig.Minus(trans); + orig = q.Rotate(orig); + r = orig.Plus(trans).Plus(displace); + } else if(type == Type::FACE_N_TRANS) { + ExprVector trans = ExprVector::From(param[0], param[1], param[2]); + r = ExprVector::From(numPoint); + r = r.Plus(trans.ScaledBy(Expr::From(timesApplied))); + } else if(type == Type::FACE_N_ROT_AA) { + ExprVector trans = ExprVector::From(param[0], param[1], param[2]); + ExprQuaternion q = GetAxisAngleQuaternionExprs(3); + r = ExprVector::From(numPoint); + r = r.Minus(trans); + r = q.Rotate(r); + r = r.Plus(trans); + } else ssassert(false, "Unexpected entity type"); + return r; +} + +Vector EntityBase::FaceGetPointNum() const { + Vector r; + if((type == Type::FACE_NORMAL_PT) || (type==Type::FACE_ROT_NORMAL_PT)) { + r = SK.GetEntity(point[0])->PointGetNum(); + } else if(type == Type::FACE_XPROD) { + r = numPoint; + } else if(type == Type::FACE_N_ROT_TRANS) { + // The numerical point gets the rotation and translation. + Vector trans = Vector::From(param[0], param[1], param[2]); + Quaternion q = Quaternion::From(param[3], param[4], param[5], param[6]); + r = q.Rotate(numPoint); + r = r.Plus(trans); + } else if(type == Type::FACE_N_ROT_AXIS_TRANS) { + Vector offset = Vector::From(param[0], param[1], param[2]); + Vector displace = Vector::From(param[4], param[5], param[6]) + .WithMagnitude(SK.GetParam(param[7])->val).ScaledBy(timesApplied); + Quaternion q = PointGetQuaternion(); + r = numPoint.Minus(offset); + r = q.Rotate(r); + r = r.Plus(offset).Plus(displace); + } else if(type == Type::FACE_N_TRANS) { + Vector trans = Vector::From(param[0], param[1], param[2]); + r = numPoint.Plus(trans.ScaledBy(timesApplied)); + } else if(type == Type::FACE_N_ROT_AA) { + Vector trans = Vector::From(param[0], param[1], param[2]); + Quaternion q = GetAxisAngleQuaternion(3); + r = numPoint.Minus(trans); + r = q.Rotate(r); + r = r.Plus(trans); + } else ssassert(false, "Unexpected entity type"); + return r; +} + +bool EntityBase::HasEndpoints() const { + return (type == Type::LINE_SEGMENT) || + (type == Type::CUBIC) || + (type == Type::ARC_OF_CIRCLE); +} +Vector EntityBase::EndpointStart() const { + if(type == Type::LINE_SEGMENT) { + return SK.GetEntity(point[0])->PointGetNum(); + } else if(type == Type::CUBIC) { + return CubicGetStartNum(); + } else if(type == Type::ARC_OF_CIRCLE) { + return SK.GetEntity(point[1])->PointGetNum(); + } else ssassert(false, "Unexpected entity type"); +} +Vector EntityBase::EndpointFinish() const { + if(type == Type::LINE_SEGMENT) { + return SK.GetEntity(point[1])->PointGetNum(); + } else if(type == Type::CUBIC) { + return CubicGetFinishNum(); + } else if(type == Type::ARC_OF_CIRCLE) { + return SK.GetEntity(point[2])->PointGetNum(); + } else ssassert(false, "Unexpected entity type"); +} +static bool PointInPlane(hEntity h, Vector norm, double distance) { + Vector p = SK.GetEntity(h)->PointGetNum(); + return (fabs(norm.Dot(p) - distance) < LENGTH_EPS); +} +bool EntityBase::IsInPlane(Vector norm, double distance) const { + switch(type) { + case Type::LINE_SEGMENT: { + return PointInPlane(point[0], norm, distance) + && PointInPlane(point[1], norm, distance); + } + case Type::CUBIC: + case Type::CUBIC_PERIODIC: { + bool periodic = type == Type::CUBIC_PERIODIC; + int n = periodic ? 3 + extraPoints : extraPoints; + int i; + for (i=0; iNormalN(); + if (!norm.Equals(n) && !norm.Equals(n.Negated())) return false; + return PointInPlane(point[0], norm, distance); + } + + case Type::TTF_TEXT: { + Vector n = Normal()->NormalN(); + if (!norm.Equals(n) && !norm.Equals(n.Negated())) return false; + return PointInPlane(point[0], norm, distance) + && PointInPlane(point[1], norm, distance); + } + + default: + return false; + } +} + +void EntityBase::RectGetPointsExprs(ExprVector *eb, ExprVector *ec) const { + ssassert(type == Type::TTF_TEXT || type == Type::IMAGE, + "Unexpected entity type"); + + EntityBase *a = SK.GetEntity(point[0]); + EntityBase *o = SK.GetEntity(point[1]); + + // Write equations for each point in the current workplane. + // This reduces the complexity of resulting equations. + ExprVector ea = a->PointGetExprsInWorkplane(workplane); + ExprVector eo = o->PointGetExprsInWorkplane(workplane); + + // Take perpendicular vector and scale it by aspect ratio. + ExprVector eu = ea.Minus(eo); + ExprVector ev = ExprVector::From(eu.y, eu.x->Negate(), eu.z).ScaledBy(Expr::From(aspectRatio)); + + *eb = eo.Plus(ev); + *ec = eo.Plus(eu).Plus(ev); +} + +void EntityBase::AddEq(IdList *l, Expr *expr, int index) const { + Equation eq; + eq.e = expr; + eq.h = h.equation(index); + l->Add(&eq); +} + +void EntityBase::GenerateEquations(IdList *l) const { + switch(type) { + case Type::NORMAL_IN_3D: { + ExprQuaternion q = NormalGetExprs(); + AddEq(l, (q.Magnitude())->Minus(Expr::From(1)), 0); + break; + } + + case Type::ARC_OF_CIRCLE: { + // If this is a copied entity, with its point already fixed + // with respect to each other, then we don't want to generate + // the distance constraint! + if(SK.GetEntity(point[0])->type != Type::POINT_IN_2D) break; + + // If the two endpoints of the arc are constrained coincident + // (to make a complete circle), then our distance constraint + // would be redundant and therefore overconstrain things. + auto it = std::find_if(SK.constraint.begin(), SK.constraint.end(), + [&](ConstraintBase const &con) { + return (con.group == group) && + (con.type == Constraint::Type::POINTS_COINCIDENT) && + ((con.ptA == point[1] && con.ptB == point[2]) || + (con.ptA == point[2] && con.ptB == point[1])); + }); + if(it != SK.constraint.end()) { + break; + } + + Expr *ra = Constraint::Distance(workplane, point[0], point[1]); + Expr *rb = Constraint::Distance(workplane, point[0], point[2]); + AddEq(l, ra->Minus(rb), 0); + break; + } + + case Type::IMAGE: + case Type::TTF_TEXT: { + if(SK.GetEntity(point[0])->type != Type::POINT_IN_2D) break; + EntityBase *b = SK.GetEntity(point[2]); + EntityBase *c = SK.GetEntity(point[3]); + ExprVector eb = b->PointGetExprsInWorkplane(workplane); + ExprVector ec = c->PointGetExprsInWorkplane(workplane); + + ExprVector ebp, ecp; + RectGetPointsExprs(&ebp, &ecp); + + ExprVector beq = eb.Minus(ebp); + AddEq(l, beq.x, 0); + AddEq(l, beq.y, 1); + ExprVector ceq = ec.Minus(ecp); + AddEq(l, ceq.x, 2); + AddEq(l, ceq.y, 3); + break; + } + + default: // Most entities do not generate equations. + break; + } +} diff --git a/src/export.cpp b/src/export.cpp new file mode 100644 index 0000000..f5649b6 --- /dev/null +++ b/src/export.cpp @@ -0,0 +1,1264 @@ +//----------------------------------------------------------------------------- +// The 2d vector output stuff that isn't specific to any particular file +// format: getting the appropriate lines and curves, performing hidden line +// removal, calculating bounding boxes, and so on. Also raster and triangle +// mesh output. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" +#include "config.h" + +void SolveSpaceUI::ExportSectionTo(const Platform::Path &filename) { + Vector gn = (SS.GW.projRight).Cross(SS.GW.projUp); + gn = gn.WithMagnitude(1); + + Group *g = SK.GetGroup(SS.GW.activeGroup); + g->GenerateDisplayItems(); + if(g->displayMesh.IsEmpty()) { + Error(_("No solid model present; draw one with extrudes and revolves, " + "or use Export 2d View to export bare lines and curves.")); + return; + } + + // The plane in which the exported section lies; need this because we'll + // reorient from that plane into the xy plane before exporting. + Vector origin, u, v, n; + double d; + + SS.GW.GroupSelection(); + auto const &gs = SS.GW.gs; + if((gs.n == 0 && g->activeWorkplane != Entity::FREE_IN_3D)) { + Entity *wrkpl = SK.GetEntity(g->activeWorkplane); + origin = wrkpl->WorkplaneGetOffset(); + n = wrkpl->Normal()->NormalN(); + u = wrkpl->Normal()->NormalU(); + v = wrkpl->Normal()->NormalV(); + } else if(gs.n == 1 && gs.faces == 1) { + Entity *face = SK.GetEntity(gs.entity[0]); + origin = face->FaceGetPointNum(); + n = face->FaceGetNormalNum(); + if(n.Dot(gn) < 0) n = n.ScaledBy(-1); + u = n.Normal(0); + v = n.Normal(1); + } else if(gs.n == 3 && gs.vectors == 2 && gs.points == 1) { + Vector ut = SK.GetEntity(gs.entity[0])->VectorGetNum(), + vt = SK.GetEntity(gs.entity[1])->VectorGetNum(); + ut = ut.WithMagnitude(1); + vt = vt.WithMagnitude(1); + + if(fabs(SS.GW.projUp.Dot(vt)) < fabs(SS.GW.projUp.Dot(ut))) { + swap(ut, vt); + } + if(SS.GW.projRight.Dot(ut) < 0) ut = ut.ScaledBy(-1); + if(SS.GW.projUp. Dot(vt) < 0) vt = vt.ScaledBy(-1); + + origin = SK.GetEntity(gs.point[0])->PointGetNum(); + n = ut.Cross(vt); + u = ut.WithMagnitude(1); + v = (n.Cross(u)).WithMagnitude(1); + } else { + Error(_("Bad selection for export section. Please select:\n\n" + " * nothing, with an active workplane " + "(workplane is section plane)\n" + " * a face (section plane through face)\n" + " * a point and two line segments " + "(plane through point and parallel to lines)\n")); + return; + } + SS.GW.ClearSelection(); + + n = n.WithMagnitude(1); + d = origin.Dot(n); + + SEdgeList el = {}; + SBezierList bl = {}; + + // If there's a mesh, then grab the edges from it. + g->runningMesh.MakeEdgesInPlaneInto(&el, n, d); + + // If there's a shell, then grab the edges and possibly Beziers. + bool export_as_pwl = SS.exportPwlCurves || fabs(SS.exportOffset) > LENGTH_EPS; + g->runningShell.MakeSectionEdgesInto(n, d, &el, export_as_pwl ? NULL : &bl); + + // All of these are solid model edges, so use the appropriate style. + SEdge *se; + for(se = el.l.First(); se; se = el.l.NextAfter(se)) { + se->auxA = Style::SOLID_EDGE; + } + SBezier *sb; + for(sb = bl.l.First(); sb; sb = bl.l.NextAfter(sb)) { + sb->auxA = Style::SOLID_EDGE; + } + + // Remove all overlapping edges/beziers to merge the areas they describe. + el.CullExtraneousEdges(/*both=*/true); + bl.CullIdenticalBeziers(/*both=*/true); + + // Collect lines and beziers with custom style & export. + for(auto &ent : SK.entity) { + Entity *e = &ent; + if (!e->IsVisible()) continue; + if (e->style.v < Style::FIRST_CUSTOM) continue; + if (!Style::Exportable(e->style.v)) continue; + if (!e->IsInPlane(n,d)) continue; + if (export_as_pwl) { + e->GenerateEdges(&el); + } else { + e->GenerateBezierCurves(&bl); + } + } + + // Only remove half of the overlapping edges/beziers to support TTF Stick Fonts. + el.CullExtraneousEdges(/*both=*/false); + bl.CullIdenticalBeziers(/*both=*/false); + + // And write the edges. + VectorFileWriter *out = VectorFileWriter::ForFile(filename); + if(out) { + // parallel projection (no perspective), and no mesh + ExportLinesAndMesh(&el, &bl, NULL, + u, v, n, origin, 0, + out); + } + el.Clear(); + bl.Clear(); +} + +// This is an awful temporary hack to replace Constraint::GetEdges until we have proper +// export through Canvas. +class GetEdgesCanvas : public Canvas { +public: + Camera camera; + SEdgeList *edges; + + const Camera &GetCamera() const override { + return camera; + } + + void DrawLine(const Vector &a, const Vector &b, hStroke hcs) override { + edges->AddEdge(a, b, Style::CONSTRAINT); + } + void DrawEdges(const SEdgeList &el, hStroke hcs) override { + for(const SEdge &e : el.l) { + edges->AddEdge(e.a, e.b, Style::CONSTRAINT); + } + } + void DrawVectorText(const std::string &text, double height, + const Vector &o, const Vector &u, const Vector &v, + hStroke hcs) override { + auto traceEdge = [&](Vector a, Vector b) { edges->AddEdge(a, b, Style::CONSTRAINT); }; + VectorFont::Builtin()->Trace(height, o, u, v, text, traceEdge, camera); + } + + void DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d, + hFill hcf) override { + // Do nothing + } + + bool DrawBeziers(const SBezierList &bl, hStroke hcs) override { + ssassert(false, "Not implemented"); + } + void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) override { + ssassert(false, "Not implemented"); + } + void DrawPoint(const Vector &o, hStroke hcs) override { + ssassert(false, "Not implemented"); + } + void DrawPolygon(const SPolygon &p, hFill hcf) override { + ssassert(false, "Not implemented"); + } + void DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack = {}) override { + ssassert(false, "Not implemented"); + } + void DrawFaces(const SMesh &m, const std::vector &faces, hFill hcf) override { + ssassert(false, "Not implemented"); + } + void DrawPixmap(std::shared_ptr pm, + const Vector &o, const Vector &u, const Vector &v, + const Point2d &ta, const Point2d &tb, hFill hcf) override { + ssassert(false, "Not implemented"); + } + void InvalidatePixmap(std::shared_ptr pm) override { + ssassert(false, "Not implemented"); + } +}; + +void SolveSpaceUI::ExportViewOrWireframeTo(const Platform::Path &filename, bool exportWireframe) { + SEdgeList edges = {}; + SBezierList beziers = {}; + + VectorFileWriter *out = VectorFileWriter::ForFile(filename); + if(!out) return; + + SS.exportMode = true; + GenerateAll(Generate::ALL); + + SMesh *sm = NULL; + if(SS.GW.showShaded || SS.GW.drawOccludedAs != GraphicsWindow::DrawOccludedAs::VISIBLE) { + Group *g = SK.GetGroup(SS.GW.activeGroup); + g->GenerateDisplayItems(); + sm = &(g->displayMesh); + } + if(sm && sm->IsEmpty()) { + sm = NULL; + } + + for(auto &entity : SK.entity) { + Entity *e = &entity; + if(!e->IsVisible()) continue; + if(e->construction) continue; + + if(SS.exportPwlCurves || sm || fabs(SS.exportOffset) > LENGTH_EPS) + { + // We will be doing hidden line removal, which we can't do on + // exact curves; so we need things broken down to pwls. Same + // problem with cutter radius compensation. + e->GenerateEdges(&edges); + } else { + e->GenerateBezierCurves(&beziers); + } + } + + if(SS.GW.showEdges || SS.GW.showOutlines) { + Group *g = SK.GetGroup(SS.GW.activeGroup); + g->GenerateDisplayItems(); + if(SS.GW.showEdges) { + g->displayOutlines.ListTaggedInto(&edges, Style::SOLID_EDGE); + } + } + + if(SS.GW.showConstraints) { + if(!out->OutputConstraints(&SK.constraint)) { + GetEdgesCanvas canvas = {}; + canvas.camera = SS.GW.GetCamera(); + canvas.edges = &edges; + + // The output format cannot represent constraints directly, + // so convert them to edges. + for(Constraint &c : SK.constraint) { + c.Draw(Constraint::DrawAs::DEFAULT, &canvas); + } + + canvas.Clear(); + } + } + + if(exportWireframe) { + Vector u = Vector::From(1.0, 0.0, 0.0), + v = Vector::From(0.0, 1.0, 0.0), + n = Vector::From(0.0, 0.0, 1.0), + origin = Vector::From(0.0, 0.0, 0.0); + double cameraTan = 0.0, + scale = 1.0; + + out->SetModelviewProjection(u, v, n, origin, cameraTan, scale); + + ExportWireframeCurves(&edges, &beziers, out); + } else { + Vector u = SS.GW.projRight, + v = SS.GW.projUp, + n = u.Cross(v), + origin = SS.GW.offset.ScaledBy(-1); + + out->SetModelviewProjection(u, v, n, origin, + SS.CameraTangent()*SS.GW.scale, SS.exportScale); + + ExportLinesAndMesh(&edges, &beziers, sm, + u, v, n, origin, SS.CameraTangent()*SS.GW.scale, + out); + + if(!out->HasCanvasSize()) { + // These file formats don't have a canvas size, so they just + // get exported in the raw coordinate system. So indicate what + // that was on-screen. + SS.justExportedInfo.showOrigin = true; + SS.justExportedInfo.pt = origin; + SS.justExportedInfo.u = u; + SS.justExportedInfo.v = v; + } else { + SS.justExportedInfo.showOrigin = false; + } + + SS.justExportedInfo.draw = true; + GW.Invalidate(); + } + + edges.Clear(); + beziers.Clear(); +} + +void SolveSpaceUI::ExportWireframeCurves(SEdgeList *sel, SBezierList *sbl, + VectorFileWriter *out) +{ + SBezierLoopSetSet sblss = {}; + SEdge *se; + for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { + SBezier sb = SBezier::From( + (se->a).ScaledBy(1.0 / SS.exportScale), + (se->b).ScaledBy(1.0 / SS.exportScale)); + sblss.AddOpenPath(&sb); + } + + sbl->ScaleSelfBy(1.0/SS.exportScale); + SBezier *sb; + for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) { + sblss.AddOpenPath(sb); + } + + out->OutputLinesAndMesh(&sblss, NULL); + sblss.Clear(); +} + +void SolveSpaceUI::ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *sm, + Vector u, Vector v, Vector n, + Vector origin, double cameraTan, + VectorFileWriter *out) +{ + double s = 1.0 / SS.exportScale; + + // Project into the export plane; so when we're done, z doesn't matter, + // and x and y are what goes in the DXF. + for(SEdge *e = sel->l.First(); e; e = sel->l.NextAfter(e)) { + // project into the specified csys, and apply export scale + (e->a) = e->a.InPerspective(u, v, n, origin, cameraTan).ScaledBy(s); + (e->b) = e->b.InPerspective(u, v, n, origin, cameraTan).ScaledBy(s); + } + + if(sbl) { + for(SBezier *b = sbl->l.First(); b; b = sbl->l.NextAfter(b)) { + *b = b->InPerspective(u, v, n, origin, cameraTan); + int i; + for(i = 0; i <= b->deg; i++) { + b->ctrl[i] = (b->ctrl[i]).ScaledBy(s); + } + } + } + + // If cutter radius compensation is requested, then perform it now + if(fabs(SS.exportOffset) > LENGTH_EPS) { + // assemble those edges into a polygon, and clear the edge list + SPolygon sp = {}; + sel->AssemblePolygon(&sp, NULL); + sel->Clear(); + + SPolygon compd = {}; + sp.normal = Vector::From(0, 0, -1); + sp.FixContourDirections(); + sp.OffsetInto(&compd, SS.exportOffset*s); + sp.Clear(); + + compd.MakeEdgesInto(sel); + compd.Clear(); + } + + // Now the triangle mesh; project, then build a BSP to perform + // occlusion testing and generated the shaded surfaces. + SMesh smp = {}; + if(sm) { + Vector l0 = (SS.lightDir[0]).WithMagnitude(1), + l1 = (SS.lightDir[1]).WithMagnitude(1); + STriangle *tr; + for(tr = sm->l.First(); tr; tr = sm->l.NextAfter(tr)) { + STriangle tt = *tr; + tt.a = (tt.a).InPerspective(u, v, n, origin, cameraTan).ScaledBy(s); + tt.b = (tt.b).InPerspective(u, v, n, origin, cameraTan).ScaledBy(s); + tt.c = (tt.c).InPerspective(u, v, n, origin, cameraTan).ScaledBy(s); + + // And calculate lighting for the triangle + Vector n = tt.Normal().WithMagnitude(1); + double lighting = SS.ambientIntensity + + max(0.0, (SS.lightIntensity[0])*(n.Dot(l0))) + + max(0.0, (SS.lightIntensity[1])*(n.Dot(l1))); + double r = min(1.0, tt.meta.color.redF() * lighting), + g = min(1.0, tt.meta.color.greenF() * lighting), + b = min(1.0, tt.meta.color.blueF() * lighting); + tt.meta.color = RGBf(r, g, b); + smp.AddTriangle(&tt); + } + } + + SMesh sms = {}; + + // We need the mesh for occlusion testing, but if we don't/can't export it, + // don't generate it. + if(SS.GW.showShaded && out->CanOutputMesh()) { + // Use the BSP routines to generate the split triangles in paint order. + SBsp3 *bsp = SBsp3::FromMesh(&smp); + if(bsp) bsp->GenerateInPaintOrder(&sms); + // And cull the back-facing triangles + STriangle *tr; + sms.l.ClearTags(); + for(tr = sms.l.First(); tr; tr = sms.l.NextAfter(tr)) { + Vector n = tr->Normal(); + if(n.z < 0) { + tr->tag = 1; + } + } + sms.l.RemoveTagged(); + } + + // And now we perform hidden line removal if requested + SEdgeList hlrd = {}; + if(sm) { + SKdNode *root = SKdNode::From(&smp); + + // Generate the edges where a curved surface turns from front-facing + // to back-facing. + if(SS.GW.showEdges || SS.GW.showOutlines) { + root->MakeCertainEdgesInto(sel, EdgeKind::TURNING, + /*coplanarIsInter=*/false, NULL, NULL, + GW.showOutlines ? Style::OUTLINE : Style::SOLID_EDGE); + } + + root->ClearTags(); + int cnt = 1234; + + SEdge *se; + for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { + if(se->auxA == Style::CONSTRAINT) { + // Constraints should not get hidden line removed; they're + // always on top. + hlrd.AddEdge(se->a, se->b, se->auxA); + continue; + } + + SEdgeList edges = {}; + // Split the original edge against the mesh + edges.AddEdge(se->a, se->b, se->auxA); + root->OcclusionTestLine(*se, &edges, cnt); + if(SS.GW.drawOccludedAs == GraphicsWindow::DrawOccludedAs::STIPPLED) { + for(SEdge &se : edges.l) { + if(se.tag == 1) { + se.auxA = Style::HIDDEN_EDGE; + } + } + } else if(SS.GW.drawOccludedAs == GraphicsWindow::DrawOccludedAs::INVISIBLE) { + edges.l.RemoveTagged(); + } + + // the occlusion test splits unnecessarily; so fix those + edges.MergeCollinearSegments(se->a, se->b); + cnt++; + // And add the results to our output + SEdge *sen; + for(sen = edges.l.First(); sen; sen = edges.l.NextAfter(sen)) { + hlrd.AddEdge(sen->a, sen->b, sen->auxA); + } + edges.Clear(); + } + + sel = &hlrd; + } + + // Clean up: remove overlapping line segments and + // segments with zero-length projections. + sel->l.ClearTags(); + for(int i = 0; i < sel->l.n; ++i) { + SEdge *sei = &sel->l[i]; + hStyle hsi = { (uint32_t)sei->auxA }; + Style *si = Style::Get(hsi); + if(sei->tag != 0) continue; + + // Remove segments with zero length projections. + Vector ai = sei->a; + ai.z = 0.0; + Vector bi = sei->b; + bi.z = 0.0; + Vector di = bi.Minus(ai); + if(fabs(di.x) < LENGTH_EPS && fabs(di.y) < LENGTH_EPS) { + sei->tag = 1; + continue; + } + + for(int j = i + 1; j < sel->l.n; ++j) { + SEdge *sej = &sel->l[j]; + if(sej->tag != 0) continue; + + Vector *pAj = &sej->a; + Vector *pBj = &sej->b; + + // Remove segments with zero length projections. + Vector aj = sej->a; + aj.z = 0.0; + Vector bj = sej->b; + bj.z = 0.0; + Vector dj = bj.Minus(aj); + if(fabs(dj.x) < LENGTH_EPS && fabs(dj.y) < LENGTH_EPS) { + sej->tag = 1; + continue; + } + + // Skip non-collinear segments. + const double eps = 1e-6; + if(aj.DistanceToLine(ai, di) > eps) continue; + if(bj.DistanceToLine(ai, di) > eps) continue; + + double ta = aj.Minus(ai).Dot(di) / di.Dot(di); + double tb = bj.Minus(ai).Dot(di) / di.Dot(di); + if(ta > tb) { + std::swap(pAj, pBj); + std::swap(ta, tb); + } + + hStyle hsj = { (uint32_t)sej->auxA }; + Style *sj = Style::Get(hsj); + + bool canRemoveI = sej->auxA == sei->auxA || si->zIndex < sj->zIndex; + bool canRemoveJ = sej->auxA == sei->auxA || sj->zIndex < si->zIndex; + + if(canRemoveJ) { + // j-segment inside i-segment + if(ta > 0.0 - eps && tb < 1.0 + eps) { + sej->tag = 1; + continue; + } + + // cut segment + bool aInside = ta > 0.0 - eps && ta < 1.0 + eps; + if(tb > 1.0 - eps && aInside) { + *pAj = sei->b; + continue; + } + + // cut segment + bool bInside = tb > 0.0 - eps && tb < 1.0 + eps; + if(ta < 0.0 - eps && bInside) { + *pBj = sei->a; + continue; + } + + // split segment + if(ta < 0.0 - eps && tb > 1.0 + eps) { + sel->AddEdge(sei->b, *pBj, sej->auxA, sej->auxB); + *pBj = sei->a; + continue; + } + } + + if(canRemoveI) { + // j-segment inside i-segment + if(ta < 0.0 + eps && tb > 1.0 - eps) { + sei->tag = 1; + break; + } + + // cut segment + bool aInside = ta > 0.0 + eps && ta < 1.0 - eps; + if(tb > 1.0 - eps && aInside) { + sei->b = *pAj; + i--; + break; + } + + // cut segment + bool bInside = tb > 0.0 + eps && tb < 1.0 - eps; + if(ta < 0.0 + eps && bInside) { + sei->a = *pBj; + i--; + break; + } + + // split segment + if(ta > 0.0 + eps && tb < 1.0 - eps) { + sel->AddEdge(*pBj, sei->b, sei->auxA, sei->auxB); + sei->b = *pAj; + i--; + break; + } + } + } + } + sel->l.RemoveTagged(); + + // We kept the line segments and Beziers separate until now; but put them + // all together, and also project everything into the xy plane, since not + // all export targets ignore the z component of the points. + ssassert(sbl != nullptr, "Adding line segments to beziers assumes bezier list is non-null."); + for(SEdge *e = sel->l.First(); e; e = sel->l.NextAfter(e)) { + SBezier sb = SBezier::From(e->a, e->b); + sb.auxA = e->auxA; + sbl->l.Add(&sb); + } + for(SBezier *b = sbl->l.First(); b; b = sbl->l.NextAfter(b)) { + for(int i = 0; i <= b->deg; i++) { + b->ctrl[i].z = 0; + } + } + + // If possible, then we will assemble these output curves into loops. They + // will then get exported as closed paths. + SBezierLoopSetSet sblss = {}; + SBezierLoopSet leftovers = {}; + SSurface srf = SSurface::FromPlane(Vector::From(0, 0, 0), + Vector::From(1, 0, 0), + Vector::From(0, 1, 0)); + SPolygon spxyz = {}; + bool allClosed; + SEdge notClosedAt; + sbl->l.ClearTags(); + sblss.FindOuterFacesFrom(sbl, &spxyz, &srf, + SS.ExportChordTolMm(), + &allClosed, ¬ClosedAt, + NULL, NULL, + &leftovers); + sblss.l.Add(&leftovers); + + // Now write the lines and triangles to the output file + out->OutputLinesAndMesh(&sblss, &sms); + + spxyz.Clear(); + sblss.Clear(); + smp.Clear(); + sms.Clear(); + hlrd.Clear(); +} + +double VectorFileWriter::MmToPts(double mm) { + // 72 points in an inch + return (mm/25.4)*72; +} + +VectorFileWriter *VectorFileWriter::ForFile(const Platform::Path &filename) { + VectorFileWriter *ret; + bool needOpen = true; + if(filename.HasExtension("dxf")) { + static DxfFileWriter DxfWriter; + ret = &DxfWriter; + needOpen = false; + } else if(filename.HasExtension("ps") || filename.HasExtension("eps")) { + static EpsFileWriter EpsWriter; + ret = &EpsWriter; + } else if(filename.HasExtension("pdf")) { + static PdfFileWriter PdfWriter; + ret = &PdfWriter; + } else if(filename.HasExtension("svg")) { + static SvgFileWriter SvgWriter; + ret = &SvgWriter; + } else if(filename.HasExtension("plt") || filename.HasExtension("hpgl")) { + static HpglFileWriter HpglWriter; + ret = &HpglWriter; + } else if(filename.HasExtension("step") || filename.HasExtension("stp")) { + static Step2dFileWriter Step2dWriter; + ret = &Step2dWriter; + } else if(filename.HasExtension("txt") || filename.HasExtension("ngc")) { + static GCodeFileWriter GCodeWriter; + ret = &GCodeWriter; + } else { + Error("Can't identify output file type from file extension of " + "filename '%s'; try " + ".step, .stp, .dxf, .svg, .plt, .hpgl, .pdf, .txt, .ngc, " + ".eps, or .ps.", + filename.raw.c_str()); + return NULL; + } + ret->filename = filename; + if(!needOpen) return ret; + + FILE *f = OpenFile(filename, "wb"); + if(!f) { + Error("Couldn't write to '%s'", filename.raw.c_str()); + return NULL; + } + ret->f = f; + return ret; +} + +void VectorFileWriter::SetModelviewProjection(const Vector &u, const Vector &v, const Vector &n, + const Vector &origin, double cameraTan, + double scale) { + this->u = u; + this->v = v; + this->n = n; + this->origin = origin; + this->cameraTan = cameraTan; + this->scale = scale; +} + +Vector VectorFileWriter::Transform(Vector &pos) const { + return pos.InPerspective(u, v, n, origin, cameraTan).ScaledBy(1.0 / scale); +} + +void VectorFileWriter::OutputLinesAndMesh(SBezierLoopSetSet *sblss, SMesh *sm) { + STriangle *tr; + SBezier *b; + + // First calculate the bounding box. + ptMin = Vector::From(VERY_POSITIVE, VERY_POSITIVE, VERY_POSITIVE); + ptMax = Vector::From(VERY_NEGATIVE, VERY_NEGATIVE, VERY_NEGATIVE); + if(sm) { + for(tr = sm->l.First(); tr; tr = sm->l.NextAfter(tr)) { + (tr->a).MakeMaxMin(&ptMax, &ptMin); + (tr->b).MakeMaxMin(&ptMax, &ptMin); + (tr->c).MakeMaxMin(&ptMax, &ptMin); + } + } + if(sblss) { + SBezierLoopSet *sbls; + for(sbls = sblss->l.First(); sbls; sbls = sblss->l.NextAfter(sbls)) { + SBezierLoop *sbl; + for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) { + for(b = sbl->l.First(); b; b = sbl->l.NextAfter(b)) { + for(int i = 0; i <= b->deg; i++) { + (b->ctrl[i]).MakeMaxMin(&ptMax, &ptMin); + } + } + } + } + } + + // And now we compute the canvas size. + double s = 1.0 / SS.exportScale; + if(SS.exportCanvasSizeAuto) { + // It's based on the calculated bounding box; we grow it along each + // boundary by the specified amount. + ptMin.x -= s*SS.exportMargin.left; + ptMax.x += s*SS.exportMargin.right; + ptMin.y -= s*SS.exportMargin.bottom; + ptMax.y += s*SS.exportMargin.top; + } else { + ptMin.x = (s*SS.exportCanvas.dx); + ptMin.y = (s*SS.exportCanvas.dy); + ptMax.x = ptMin.x + (s*SS.exportCanvas.width); + ptMax.y = ptMin.y + (s*SS.exportCanvas.height); + } + + StartFile(); + if(SS.exportBackgroundColor) { + Background(SS.backgroundColor); + } + if(sm && SS.exportShadedTriangles) { + for(tr = sm->l.First(); tr; tr = sm->l.NextAfter(tr)) { + Triangle(tr); + } + } + if(sblss) { + SBezierLoopSet *sbls; + for(sbls = sblss->l.First(); sbls; sbls = sblss->l.NextAfter(sbls)) { + SBezierLoop *sbl; + sbl = sbls->l.First(); + if(!sbl) continue; + b = sbl->l.First(); + if(!b || !Style::Exportable(b->auxA)) continue; + + hStyle hs = { (uint32_t)b->auxA }; + Style *stl = Style::Get(hs); + double lineWidth = Style::WidthMm(b->auxA)*s; + RgbaColor strokeRgb = Style::Color(hs, /*forExport=*/true); + RgbaColor fillRgb = Style::FillColor(hs, /*forExport=*/true); + + StartPath(strokeRgb, lineWidth, stl->filled, fillRgb, hs); + for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) { + for(b = sbl->l.First(); b; b = sbl->l.NextAfter(b)) { + Bezier(b); + } + } + FinishPath(strokeRgb, lineWidth, stl->filled, fillRgb, hs); + } + } + FinishAndCloseFile(); +} + +void VectorFileWriter::BezierAsPwl(SBezier *sb) { + List lv = {}; + sb->MakePwlInto(&lv, SS.ExportChordTolMm()); + + for(int i = 1; i < lv.n; i++) { + SBezier sb = SBezier::From(lv[i-1], lv[i]); + Bezier(&sb); + } + lv.Clear(); +} + +void VectorFileWriter::BezierAsNonrationalCubic(SBezier *sb, int depth) { + Vector t0 = sb->TangentAt(0), t1 = sb->TangentAt(1); + // The curve is correct, and the first derivatives are correct, at the + // endpoints. + SBezier bnr = SBezier::From( + sb->Start(), + sb->Start().Plus(t0.ScaledBy(1.0/3)), + sb->Finish().Minus(t1.ScaledBy(1.0/3)), + sb->Finish()); + + double tol = SS.ExportChordTolMm(); + // Arbitrary choice, but make it a little finer than pwl tolerance since + // it should be easier to achieve that with the smooth curves. + tol /= 2; + + bool closeEnough = true; + int i; + for(i = 1; i <= 3; i++) { + double t = i/4.0; + Vector p0 = sb->PointAt(t), + pn = bnr.PointAt(t); + double d = (p0.Minus(pn)).Magnitude(); + if(d > tol) { + closeEnough = false; + } + } + + if(closeEnough || depth > 3) { + Bezier(&bnr); + } else { + SBezier bef, aft; + sb->SplitAt(0.5, &bef, &aft); + BezierAsNonrationalCubic(&bef, depth+1); + BezierAsNonrationalCubic(&aft, depth+1); + } +} + +//----------------------------------------------------------------------------- +// Export a triangle mesh, in the requested format. +//----------------------------------------------------------------------------- +void SolveSpaceUI::ExportMeshTo(const Platform::Path &filename) { + SS.exportMode = true; + GenerateAll(Generate::ALL); + + Group *g = SK.GetGroup(SS.GW.activeGroup); + g->GenerateDisplayItems(); + + SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh); + if(m->IsEmpty()) { + Error(_("Active group mesh is empty; nothing to export.")); + return; + } + + FILE *f = OpenFile(filename, "wb"); + if(!f) { + Error("Couldn't write to '%s'", filename.raw.c_str()); + return; + } + ShowNakedEdges(/*reportOnlyWhenNotOkay=*/true); + if(filename.HasExtension("stl")) { + ExportMeshAsStlTo(f, m); + } else if(filename.HasExtension("obj")) { + Platform::Path mtlFilename = filename.WithExtension("mtl"); + FILE *fMtl = OpenFile(mtlFilename, "wb"); + if(!fMtl) { + Error("Couldn't write to '%s'", filename.raw.c_str()); + return; + } + + fprintf(f, "mtllib %s\n", mtlFilename.FileName().c_str()); + ExportMeshAsObjTo(f, fMtl, m); + + fclose(fMtl); + } else if(filename.HasExtension("js") || + filename.HasExtension("html")) { + SOutlineList *e = &(SK.GetGroup(SS.GW.activeGroup)->displayOutlines); + ExportMeshAsThreeJsTo(f, filename, m, e); + } else if(filename.HasExtension("wrl")) { + ExportMeshAsVrmlTo(f, filename, m); + } else { + Error("Can't identify output file type from file extension of " + "filename '%s'; try .stl, .obj, .js, .html.", filename.raw.c_str()); + } + + fclose(f); + + SS.justExportedInfo.showOrigin = false; + SS.justExportedInfo.draw = true; + GW.Invalidate(); +} + +//----------------------------------------------------------------------------- +// Export the mesh as an STL file; it should always be vertex-to-vertex and +// not self-intersecting, so not much to do. +//----------------------------------------------------------------------------- +void SolveSpaceUI::ExportMeshAsStlTo(FILE *f, SMesh *sm) { + char str[80] = {}; + strcpy(str, "STL exported mesh"); + fwrite(str, 1, 80, f); + + uint32_t n = sm->l.n; + fwrite(&n, 4, 1, f); + + double s = SS.exportScale; + int i; + for(i = 0; i < sm->l.n; i++) { + STriangle *tr = &(sm->l[i]); + Vector n = tr->Normal().WithMagnitude(1); + float w; + w = (float)n.x; fwrite(&w, 4, 1, f); + w = (float)n.y; fwrite(&w, 4, 1, f); + w = (float)n.z; fwrite(&w, 4, 1, f); + w = (float)((tr->a.x)/s); fwrite(&w, 4, 1, f); + w = (float)((tr->a.y)/s); fwrite(&w, 4, 1, f); + w = (float)((tr->a.z)/s); fwrite(&w, 4, 1, f); + w = (float)((tr->b.x)/s); fwrite(&w, 4, 1, f); + w = (float)((tr->b.y)/s); fwrite(&w, 4, 1, f); + w = (float)((tr->b.z)/s); fwrite(&w, 4, 1, f); + w = (float)((tr->c.x)/s); fwrite(&w, 4, 1, f); + w = (float)((tr->c.y)/s); fwrite(&w, 4, 1, f); + w = (float)((tr->c.z)/s); fwrite(&w, 4, 1, f); + fputc(0, f); + fputc(0, f); + } +} + +//----------------------------------------------------------------------------- +// Export the mesh as Wavefront OBJ format. This requires us to reduce all the +// identical vertices to the same identifier, so do that first. +//----------------------------------------------------------------------------- +void SolveSpaceUI::ExportMeshAsObjTo(FILE *fObj, FILE *fMtl, SMesh *sm) { + std::map colors; + for(const STriangle &t : sm->l) { + RgbaColor color = t.meta.color; + if(colors.find(color) == colors.end()) { + std::string id = ssprintf("h%02x%02x%02x", + color.red, + color.green, + color.blue); + colors.emplace(color, id); + } + for(int i = 0; i < 3; i++) { + fprintf(fObj, "v %.10f %.10f %.10f\n", + CO(t.vertices[i].ScaledBy(1 / SS.exportScale))); + } + } + + for(auto &it : colors) { + fprintf(fMtl, "newmtl %s\n", + it.second.c_str()); + fprintf(fMtl, "Kd %.3f %.3f %.3f\n", + it.first.redF(), it.first.greenF(), it.first.blueF()); + } + + for(const STriangle &t : sm->l) { + for(int i = 0; i < 3; i++) { + Vector n = t.normals[i].WithMagnitude(1.0); + fprintf(fObj, "vn %.10f %.10f %.10f\n", + CO(n)); + } + } + + RgbaColor currentColor = {}; + for(int i = 0; i < sm->l.n; i++) { + const STriangle &t = sm->l[i]; + if(!currentColor.Equals(t.meta.color)) { + currentColor = t.meta.color; + fprintf(fObj, "usemtl %s\n", colors[currentColor].c_str()); + } + + fprintf(fObj, "f %d//%d %d//%d %d//%d\n", + i * 3 + 1, i * 3 + 1, + i * 3 + 2, i * 3 + 2, + i * 3 + 3, i * 3 + 3); + } +} + +//----------------------------------------------------------------------------- +// Export the mesh as a JavaScript script, which is compatible with Three.js. +//----------------------------------------------------------------------------- +void SolveSpaceUI::ExportMeshAsThreeJsTo(FILE *f, const Platform::Path &filename, + SMesh *sm, SOutlineList *sol) +{ + SPointList spl = {}; + STriangle *tr; + Vector bndl, bndh; + const char htmlbegin[] = R"( + + + + + Three.js Solvespace Mesh + + + + + + + + + +)"; + + // A default three.js viewer with OrthographicTrackballControls is + // generated as a comment preceding the data. + + // x bounds should be the range of x or y, whichever + // is larger, before aspect ratio correction is applied. + // y bounds should be the range of x or y, whichever is + // larger. No aspect ratio correction is applied. + // Near plane should be 1. + // Camera's z-position should be the range of z + 1 or the larger of + // the x or y bounds, whichever is larger. + // Far plane should be at least twice as much as the camera's + // z-position. + // Edge projection bias should be about 1/500 of the far plane's distance. + // Further corrections will be applied to the z-position and far plane in + // the default viewer, but the defaults are fine for a model which + // only rotates about the world origin. + + sm->GetBounding(&bndh, &bndl); + double largerBoundXY = max((bndh.x - bndl.x), (bndh.y - bndl.y)); + double largerBoundZ = max(largerBoundXY, (bndh.z - bndl.z + 1)); + + std::string basename = filename.FileStem(); + for(size_t i = 0; i < basename.length(); i++) { + if(!(isalnum(basename[i]) || ((unsigned)basename[i] >= 0x80))) { + basename[i] = '_'; + } + } + + if(filename.HasExtension("html")) { + fprintf(f, htmlbegin, + LoadStringFromGzip("threejs/three-r76.js.gz").c_str(), + LoadStringFromGzip("threejs/hammer-2.0.8.js.gz").c_str(), + LoadString("threejs/SolveSpaceControls.js").c_str()); + } + + fprintf(f, "var solvespace_model_%s = {\n" + " bounds: {\n" + " x: %f, y: %f, near: %f, far: %f, z: %f, edgeBias: %f\n" + " },\n", + basename.c_str(), + largerBoundXY, + largerBoundXY, + 1.0, + largerBoundZ * 2, + largerBoundZ, + largerBoundZ / 250); + + // Output lighting information. + fputs(" lights: {\n" + " d: [\n", f); + + // Directional. + int lightCount; + for(lightCount = 0; lightCount < 2; lightCount++) { + fprintf(f, " {\n" + " intensity: %f, direction: [%f, %f, %f]\n" + " },\n", + SS.lightIntensity[lightCount], + CO(SS.lightDir[lightCount])); + } + + // Global Ambience. + fprintf(f, " ],\n" + " a: %f\n", SS.ambientIntensity); + + for(tr = sm->l.First(); tr; tr = sm->l.NextAfter(tr)) { + spl.IncrementTagFor(tr->a); + spl.IncrementTagFor(tr->b); + spl.IncrementTagFor(tr->c); + } + + // Output all the vertices. + SPoint *sp; + fputs(" },\n" + " points: [\n", f); + for(sp = spl.l.First(); sp; sp = spl.l.NextAfter(sp)) { + fprintf(f, " [%f, %f, %f],\n", + sp->p.x / SS.exportScale, + sp->p.y / SS.exportScale, + sp->p.z / SS.exportScale); + } + + fputs(" ],\n" + " faces: [\n", f); + // And now all the triangular faces, in terms of those vertices. + // This time we count from zero. + for(tr = sm->l.First(); tr; tr = sm->l.NextAfter(tr)) { + fprintf(f, " [%d, %d, %d],\n", + spl.IndexForPoint(tr->a), + spl.IndexForPoint(tr->b), + spl.IndexForPoint(tr->c)); + } + + // Output face normals. + fputs(" ],\n" + " normals: [\n", f); + for(tr = sm->l.First(); tr; tr = sm->l.NextAfter(tr)) { + fprintf(f, " [[%f, %f, %f], [%f, %f, %f], [%f, %f, %f]],\n", + CO(tr->an), CO(tr->bn), CO(tr->cn)); + } + + fputs(" ],\n" + " colors: [\n", f); + // Output triangle colors. + for(tr = sm->l.First(); tr; tr = sm->l.NextAfter(tr)) { + fprintf(f, " 0x%x,\n", tr->meta.color.ToARGB32()); + } + + fputs(" ],\n" + " edges: [\n", f); + // Output edges. Assume user's model colors do not obscure white edges. + for(const SOutline &so : sol->l) { + if(so.tag == 0) continue; + fprintf(f, " [[%f, %f, %f], [%f, %f, %f]],\n", + so.a.x / SS.exportScale, + so.a.y / SS.exportScale, + so.a.z / SS.exportScale, + so.b.x / SS.exportScale, + so.b.y / SS.exportScale, + so.b.z / SS.exportScale); + } + + fputs(" ]\n};\n", f); + + if(filename.HasExtension("html")) { + fprintf(f, htmlend, + basename.c_str(), + SS.GW.scale, + CO(SS.GW.offset), + CO(SS.GW.projUp), + CO(SS.GW.projRight)); + } + + spl.Clear(); +} + +//----------------------------------------------------------------------------- +// Export the mesh as a VRML text file / WRL. +//----------------------------------------------------------------------------- +void SolveSpaceUI::ExportMeshAsVrmlTo(FILE *f, const Platform::Path &filename, SMesh *sm) { + struct STriangleSpan { + STriangle *first, *past_last; + + STriangle *begin() const { return first; } + STriangle *end() const { return past_last; } + }; + + + std::string basename = filename.FileStem(); + for(auto & c : basename) { + if(!(isalnum(c) || ((unsigned)c >= 0x80))) { + c = '_'; + } + } + + fprintf(f, "#VRML V2.0 utf8\n" + "#Exported from SolveSpace %s\n" + "\n" + "DEF %s Transform {\n" + " children [", + PACKAGE_VERSION, + basename.c_str()); + + + std::map> opacities; + STriangle *start = sm->l.begin(); + std::uint8_t last_opacity = start->meta.color.alpha; + for(auto & tr : sm->l) { + if(tr.meta.color.alpha != last_opacity) { + opacities[last_opacity].push_back(STriangleSpan{start, &tr}); + start = &tr; + last_opacity = start->meta.color.alpha; + } + } + opacities[last_opacity].push_back(STriangleSpan{start, sm->l.end()}); + + for(auto && op : opacities) { + fprintf(f, "\n" + " Shape {\n" + " appearance Appearance {\n" + " material DEF %s_material_%u Material {\n" + " diffuseColor %f %f %f\n" + " ambientIntensity %f\n" + " transparency %f\n" + " }\n" + " }\n" + " geometry IndexedFaceSet {\n" + " colorPerVertex TRUE\n" + " coord Coordinate { point [\n", + basename.c_str(), + (unsigned)op.first, + SS.ambientIntensity, + SS.ambientIntensity, + SS.ambientIntensity, + SS.ambientIntensity, + 1.f - ((float)op.first / 255.0f)); + + SPointList spl = {}; + + for(const auto & sp : op.second) { + for(const auto & tr : sp) { + spl.IncrementTagFor(tr.a); + spl.IncrementTagFor(tr.b); + spl.IncrementTagFor(tr.c); + } + } + + // Output all the vertices. + for(auto sp : spl.l) { + fprintf(f, " %f %f %f,\n", + sp.p.x / SS.exportScale, + sp.p.y / SS.exportScale, + sp.p.z / SS.exportScale); + } + + fputs(" ] }\n" + " coordIndex [\n", f); + // And now all the triangular faces, in terms of those vertices. + for(const auto & sp : op.second) { + for(const auto & tr : sp) { + fprintf(f, " %d, %d, %d, -1,\n", + spl.IndexForPoint(tr.a), + spl.IndexForPoint(tr.b), + spl.IndexForPoint(tr.c)); + } + } + + fputs(" ]\n" + " color Color { color [\n", f); + // Output triangle colors. + std::vector triangle_colour_ids; + std::vector colours_present; + for(const auto & sp : op.second) { + for(const auto & tr : sp) { + const auto colour_itr = std::find_if(colours_present.begin(), colours_present.end(), + [&](const RgbaColor & c) { + return c.Equals(tr.meta.color); + }); + if(colour_itr == colours_present.end()) { + fprintf(f, " %.10f %.10f %.10f,\n", + tr.meta.color.redF(), + tr.meta.color.greenF(), + tr.meta.color.blueF()); + triangle_colour_ids.push_back(colours_present.size()); + colours_present.insert(colours_present.end(), tr.meta.color); + } else { + triangle_colour_ids.push_back(colour_itr - colours_present.begin()); + } + } + } + + fputs(" ] }\n" + " colorIndex [\n", f); + + for(auto colour_idx : triangle_colour_ids) { + fprintf(f, " %d, %d, %d, -1,\n", colour_idx, colour_idx, colour_idx); + } + + fputs(" ]\n" + " }\n" + " }\n", f); + + spl.Clear(); + } + + fputs(" ]\n" + "}\n", f); +} + +//----------------------------------------------------------------------------- +// Export a view of the model as an image; we just take a screenshot, by +// rendering the view in the usual way and then copying the pixels. +//----------------------------------------------------------------------------- +void SolveSpaceUI::ExportAsPngTo(const Platform::Path &filename) { + screenshotFile = filename; + // The rest of the work is done in the next redraw. + GW.Invalidate(); +} diff --git a/src/exportstep.cpp b/src/exportstep.cpp new file mode 100644 index 0000000..db42dc0 --- /dev/null +++ b/src/exportstep.cpp @@ -0,0 +1,411 @@ +//----------------------------------------------------------------------------- +// Export a STEP file describing our ratpoly shell. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +void StepFileWriter::WriteHeader() { + fprintf(f, +"ISO-10303-21;\n" +"HEADER;\n" +"\n" +"FILE_DESCRIPTION((''), '2;1');\n" +"\n" +"FILE_NAME(\n" +" 'output_file',\n" +" '2009-06-07T17:44:47-07:00',\n" +" (''),\n" +" (''),\n" +" 'SolveSpace',\n" +" '',\n" +" ''\n" +");\n" +"\n" +"FILE_SCHEMA (('CONFIG_CONTROL_DESIGN'));\n" +"ENDSEC;\n" +"\n" +"DATA;\n" +"\n" +"/**********************************************************\n" +" * This defines the units and tolerances for the file. It\n" +" * is always the same, independent of the actual data.\n" +" **********************************************************/\n" +"#158=(\n" +"LENGTH_UNIT()\n" +"NAMED_UNIT(*)\n" +"SI_UNIT(.MILLI.,.METRE.)\n" +");\n" +"#161=(\n" +"NAMED_UNIT(*)\n" +"PLANE_ANGLE_UNIT()\n" +"SI_UNIT($,.RADIAN.)\n" +");\n" +"#166=(\n" +"NAMED_UNIT(*)\n" +"SI_UNIT($,.STERADIAN.)\n" +"SOLID_ANGLE_UNIT()\n" +");\n" +"#167=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.001),#158,\n" +"'DISTANCE_ACCURACY_VALUE',\n" +"'string');\n" +"#168=(\n" +"GEOMETRIC_REPRESENTATION_CONTEXT(3)\n" +"GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#167))\n" +"GLOBAL_UNIT_ASSIGNED_CONTEXT((#166,#161,#158))\n" +"REPRESENTATION_CONTEXT('ID1','3D')\n" +");\n" +"#169=SHAPE_REPRESENTATION('',(#170),#168);\n" +"#170=AXIS2_PLACEMENT_3D('',#173,#171,#172);\n" +"#171=DIRECTION('',(0.,0.,1.));\n" +"#172=DIRECTION('',(1.,0.,0.));\n" +"#173=CARTESIAN_POINT('',(0.,0.,0.));\n" +"\n" + ); + + // Start the ID somewhere beyond the header IDs. + id = 200; +} +void StepFileWriter::WriteProductHeader() { + fprintf(f, + "#175 = SHAPE_DEFINITION_REPRESENTATION(#176, #169);\n" + "#176 = PRODUCT_DEFINITION_SHAPE('Version', 'Test Part', #177);\n" + "#177 = PRODUCT_DEFINITION('Version', 'Test Part', #182, #178);\n" + "#178 = DESIGN_CONTEXT('3D Mechanical Parts', #181, 'design');\n" + "#179 = PRODUCT('1', 'Product', 'Test Part', (#180));\n" + "#180 = MECHANICAL_CONTEXT('3D Mechanical Parts', #181, 'mechanical');\n" + "#181 = APPLICATION_CONTEXT(\n" + "'configuration controlled 3d designs of mechanical parts and assemblies');\n" + "#182 = PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE('Version',\n" + "'Test Part', #179, .MADE.);\n" + "\n" + ); +} +int StepFileWriter::ExportCurve(SBezier *sb) { + int i, ret = id; + + fprintf(f, "#%d=(\n", ret); + fprintf(f, "BOUNDED_CURVE()\n"); + fprintf(f, "B_SPLINE_CURVE(%d,(", sb->deg); + for(i = 0; i <= sb->deg; i++) { + fprintf(f, "#%d", ret + i + 1); + if(i != sb->deg) fprintf(f, ","); + } + fprintf(f, "),.UNSPECIFIED.,.F.,.F.)\n"); + fprintf(f, "B_SPLINE_CURVE_WITH_KNOTS((%d,%d),", + (sb->deg + 1), (sb-> deg + 1)); + fprintf(f, "(0.000,1.000),.UNSPECIFIED.)\n"); + fprintf(f, "CURVE()\n"); + fprintf(f, "GEOMETRIC_REPRESENTATION_ITEM()\n"); + fprintf(f, "RATIONAL_B_SPLINE_CURVE(("); + for(i = 0; i <= sb->deg; i++) { + fprintf(f, "%.10f", sb->weight[i]); + if(i != sb->deg) fprintf(f, ","); + } + fprintf(f, "))\n"); + fprintf(f, "REPRESENTATION_ITEM('')\n);\n"); + + for(i = 0; i <= sb->deg; i++) { + fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n", + id + 1 + i, + CO(sb->ctrl[i])); + } + fprintf(f, "\n"); + + id = ret + 1 + (sb->deg + 1); + return ret; +} + +int StepFileWriter::ExportCurveLoop(SBezierLoop *loop, bool inner) { + ssassert(loop->l.n >= 1, "Expected at least one loop"); + + List listOfTrims = {}; + + SBezier *sb = loop->l.Last(); + + // Generate "exactly closed" contours, with the same vertex id for the + // finish of a previous edge and the start of the next one. So we need + // the finish of the last Bezier in the loop before we start our process. + fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n", + id, CO(sb->Finish())); + fprintf(f, "#%d=VERTEX_POINT('',#%d);\n", id+1, id); + int lastFinish = id + 1, prevFinish = lastFinish; + id += 2; + + for(sb = loop->l.First(); sb; sb = loop->l.NextAfter(sb)) { + int curveId = ExportCurve(sb); + + int thisFinish; + if(loop->l.NextAfter(sb) != NULL) { + fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n", + id, CO(sb->Finish())); + fprintf(f, "#%d=VERTEX_POINT('',#%d);\n", id+1, id); + thisFinish = id + 1; + id += 2; + } else { + thisFinish = lastFinish; + } + + fprintf(f, "#%d=EDGE_CURVE('',#%d,#%d,#%d,%s);\n", + id, prevFinish, thisFinish, curveId, ".T."); + fprintf(f, "#%d=ORIENTED_EDGE('',*,*,#%d,.T.);\n", + id+1, id); + + int oe = id+1; + listOfTrims.Add(&oe); + id += 2; + + prevFinish = thisFinish; + } + + fprintf(f, "#%d=EDGE_LOOP('',(", id); + int *oe; + for(oe = listOfTrims.First(); oe; oe = listOfTrims.NextAfter(oe)) { + fprintf(f, "#%d", *oe); + if(listOfTrims.NextAfter(oe) != NULL) fprintf(f, ","); + } + fprintf(f, "));\n"); + + int fb = id + 1; + fprintf(f, "#%d=%s('',#%d,.T.);\n", + fb, inner ? "FACE_BOUND" : "FACE_OUTER_BOUND", id); + + id += 2; + listOfTrims.Clear(); + + return fb; +} + +void StepFileWriter::ExportSurface(SSurface *ss, SBezierList *sbl) { + int i, j, srfid = id; + + // First, we create the untrimmed surface. We always specify a rational + // B-spline surface (in fact, just a Bezier surface). + fprintf(f, "#%d=(\n", srfid); + fprintf(f, "BOUNDED_SURFACE()\n"); + fprintf(f, "B_SPLINE_SURFACE(%d,%d,(", ss->degm, ss->degn); + for(i = 0; i <= ss->degm; i++) { + fprintf(f, "("); + for(j = 0; j <= ss->degn; j++) { + fprintf(f, "#%d", srfid + 1 + j + i*(ss->degn + 1)); + if(j != ss->degn) fprintf(f, ","); + } + fprintf(f, ")"); + if(i != ss->degm) fprintf(f, ","); + } + fprintf(f, "),.UNSPECIFIED.,.F.,.F.,.F.)\n"); + fprintf(f, "B_SPLINE_SURFACE_WITH_KNOTS((%d,%d),(%d,%d),", + (ss->degm + 1), (ss->degm + 1), + (ss->degn + 1), (ss->degn + 1)); + fprintf(f, "(0.000,1.000),(0.000,1.000),.UNSPECIFIED.)\n"); + fprintf(f, "GEOMETRIC_REPRESENTATION_ITEM()\n"); + fprintf(f, "RATIONAL_B_SPLINE_SURFACE(("); + for(i = 0; i <= ss->degm; i++) { + fprintf(f, "("); + for(j = 0; j <= ss->degn; j++) { + fprintf(f, "%.10f", ss->weight[i][j]); + if(j != ss->degn) fprintf(f, ","); + } + fprintf(f, ")"); + if(i != ss->degm) fprintf(f, ","); + } + fprintf(f, "))\n"); + fprintf(f, "REPRESENTATION_ITEM('')\n"); + fprintf(f, "SURFACE()\n"); + fprintf(f, ");\n"); + + // The control points for the untrimmed surface. + for(i = 0; i <= ss->degm; i++) { + for(j = 0; j <= ss->degn; j++) { + fprintf(f, "#%d=CARTESIAN_POINT('',(%.10f,%.10f,%.10f));\n", + srfid + 1 + j + i*(ss->degn + 1), + CO(ss->ctrl[i][j])); + } + } + fprintf(f, "\n"); + + id = srfid + 1 + (ss->degm + 1)*(ss->degn + 1); + + // Now we do the trim curves. We must group each outer loop separately + // along with its inner faces, so do that now. + SBezierLoopSetSet sblss = {}; + SPolygon spxyz = {}; + bool allClosed; + SEdge notClosedAt; + // We specify a surface, so it doesn't check for coplanarity; and we + // don't want it to give us any open contours. The polygon and chord + // tolerance are required, because they are used to calculate the + // contour directions and determine inner vs. outer contours. + sblss.FindOuterFacesFrom(sbl, &spxyz, ss, + SS.ExportChordTolMm(), + &allClosed, ¬ClosedAt, + NULL, NULL, + NULL); + + // So in our list of SBezierLoopSet, each set contains at least one loop + // (the outer boundary), plus any inner loops associated with that outer + // loop. + SBezierLoopSet *sbls; + for(sbls = sblss.l.First(); sbls; sbls = sblss.l.NextAfter(sbls)) { + SBezierLoop *loop = sbls->l.First(); + + List listOfLoops = {}; + // Create the face outer boundary from the outer loop. + int fob = ExportCurveLoop(loop, /*inner=*/false); + listOfLoops.Add(&fob); + + // And create the face inner boundaries from any inner loops that + // lie within this contour. + loop = sbls->l.NextAfter(loop); + for(; loop; loop = sbls->l.NextAfter(loop)) { + int fib = ExportCurveLoop(loop, /*inner=*/true); + listOfLoops.Add(&fib); + } + + // And now create the face that corresponds to this outer loop + // and all of its holes. + int advFaceId = id; + fprintf(f, "#%d=ADVANCED_FACE('',(", advFaceId); + int *fb; + for(fb = listOfLoops.First(); fb; fb = listOfLoops.NextAfter(fb)) { + fprintf(f, "#%d", *fb); + if(listOfLoops.NextAfter(fb) != NULL) fprintf(f, ","); + } + + fprintf(f, "),#%d,.T.);\n", srfid); + advancedFaces.Add(&advFaceId); + + // Export the surface color and transparency + // https://www.cax-if.org/documents/rec_prac_styling_org_v16.pdf sections 4.4.2 4.2.4 etc. + // https://tracker.dev.opencascade.org/view.php?id=31550 + fprintf(f, "#%d=COLOUR_RGB('',%.2f,%.2f,%.2f);\n", ++id, ss->color.redF(), + ss->color.greenF(), ss->color.blueF()); + +/* // This works in Kisters 3DViewStation but not in KiCAD and Horison EDA, + // it seems they do not support transparency so use the more verbose one below + fprintf(f, "#%d=SURFACE_STYLE_TRANSPARENT(%.2f);\n", ++id, 1.0 - ss->color.alphaF()); + ++id; + fprintf(f, "#%d=SURFACE_STYLE_RENDERING_WITH_PROPERTIES(.NORMAL_SHADING.,#%d,(#%d));\n", + id, id - 2, id - 1); + ++id; + fprintf(f, "#%d=SURFACE_SIDE_STYLE('',(#%d));\n", id, id - 1); +*/ + + // This works in Horison EDA but is more verbose. + ++id; + fprintf(f, "#%d=FILL_AREA_STYLE_COLOUR('',#%d);\n", id, id - 1); + ++id; + fprintf(f, "#%d=FILL_AREA_STYLE('',(#%d));\n", id, id - 1); + ++id; + fprintf(f, "#%d=SURFACE_STYLE_FILL_AREA(#%d);\n", id, id - 1); + fprintf(f, "#%d=SURFACE_STYLE_TRANSPARENT(%.2f);\n", ++id, 1.0 - ss->color.alphaF()); + ++id; + fprintf(f, "#%d=SURFACE_STYLE_RENDERING_WITH_PROPERTIES(.NORMAL_SHADING.,#%d,(#%d));\n", id, id - 5, id - 1); + ++id; + fprintf(f, "#%d=SURFACE_SIDE_STYLE('',(#%d, #%d));\n", id, id - 3, id - 1); + + ++id; + fprintf(f, "#%d=SURFACE_STYLE_USAGE(.BOTH.,#%d);\n", id, id - 1); + ++id; + fprintf(f, "#%d=PRESENTATION_STYLE_ASSIGNMENT((#%d));\n", id, id - 1); + ++id; + fprintf(f, "#%d=STYLED_ITEM('',(#%d),#%d);\n", id, id - 1, advFaceId); + fprintf(f, "\n"); + + id++; + listOfLoops.Clear(); + } + sblss.Clear(); + spxyz.Clear(); +} + +void StepFileWriter::WriteFooter() { + fprintf(f, +"\n" +"ENDSEC;\n" +"\n" +"END-ISO-10303-21;\n" + ); +} + +void StepFileWriter::ExportSurfacesTo(const Platform::Path &filename) { + Group *g = SK.GetGroup(SS.GW.activeGroup); + SShell *shell = &(g->runningShell); + + if(shell->surface.IsEmpty()) { + Error("The model does not contain any surfaces to export.%s", + !g->runningMesh.l.IsEmpty() + ? "\n\nThe model does contain triangles from a mesh, but " + "a triangle mesh cannot be exported as a STEP file. Try " + "File -> Export Mesh... instead." + : ""); + return; + } + + f = OpenFile(filename, "wb"); + if(!f) { + Error("Couldn't write to '%s'", filename.raw.c_str()); + return; + } + + WriteHeader(); + WriteProductHeader(); + + advancedFaces = {}; + + SSurface *ss; + for(ss = shell->surface.First(); ss; ss = shell->surface.NextAfter(ss)) { + if(ss->trim.IsEmpty()) + continue; + + // Get all of the loops of Beziers that trim our surface (with each + // Bezier split so that we use the section as t goes from 0 to 1), and + // the piecewise linearization of those loops in xyz space. + SBezierList sbl = {}; + ss->MakeSectionEdgesInto(shell, NULL, &sbl); + + // Apply the export scale factor. + ss->ScaleSelfBy(1.0/SS.exportScale); + sbl.ScaleSelfBy(1.0/SS.exportScale); + + ExportSurface(ss, &sbl); + + sbl.Clear(); + } + + fprintf(f, "#%d=CLOSED_SHELL('',(", id); + int *af; + for(af = advancedFaces.First(); af; af = advancedFaces.NextAfter(af)) { + fprintf(f, "#%d", *af); + if(advancedFaces.NextAfter(af) != NULL) fprintf(f, ","); + } + fprintf(f, "));\n"); + fprintf(f, "#%d=MANIFOLD_SOLID_BREP('brep',#%d);\n", id+1, id); + fprintf(f, "#%d=ADVANCED_BREP_SHAPE_REPRESENTATION('',(#%d,#170),#168);\n", + id+2, id+1); + fprintf(f, "#%d=SHAPE_REPRESENTATION_RELATIONSHIP($,$,#169,#%d);\n", + id+3, id+2); + + WriteFooter(); + + fclose(f); + advancedFaces.Clear(); +} + +void StepFileWriter::WriteWireframe() { + fprintf(f, "#%d=GEOMETRIC_CURVE_SET('curves',(", id); + int *c; + for(c = curves.First(); c; c = curves.NextAfter(c)) { + fprintf(f, "#%d", *c); + if(curves.NextAfter(c) != NULL) fprintf(f, ","); + } + fprintf(f, "));\n"); + fprintf(f, "#%d=GEOMETRICALLY_BOUNDED_WIREFRAME_SHAPE_REPRESENTATION" + "('',(#%d,#170),#168);\n", id+1, id); + fprintf(f, "#%d=SHAPE_REPRESENTATION_RELATIONSHIP($,$,#169,#%d);\n", + id+2, id+1); + + id += 3; + curves.Clear(); +} + diff --git a/src/exportvector.cpp b/src/exportvector.cpp new file mode 100644 index 0000000..4a184ab --- /dev/null +++ b/src/exportvector.cpp @@ -0,0 +1,1347 @@ +//----------------------------------------------------------------------------- +// The file format-specific stuff for all of the 2d vector output formats. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include +#include "solvespace.h" + +//----------------------------------------------------------------------------- +// Routines for DXF export +//----------------------------------------------------------------------------- +class DxfWriteInterface : public DRW_Interface { +public: + DxfFileWriter *writer; + dxfRW *dxf; + + std::set messages; + + static DRW_Coord toCoord(const Vector &v) { + return DRW_Coord(v.x, v.y, v.z); + } + + Vector xfrm(Vector v) { + return writer->Transform(v); + } + + void writeTextstyles() override { + DRW_Textstyle ts; + ts.name = "unicode"; + ts.font = "unicode"; + dxf->writeTextstyle(&ts); + } + + void writeLayers() override { + DRW_Layer layer; + + layer.name = "dimensions"; + dxf->writeLayer(&layer); + layer.name = "text"; + dxf->writeLayer(&layer); + + std::set usedStyles; + + for(DxfFileWriter::BezierPath &path : writer->paths) { + for(SBezier *sb : path.beziers) { + usedStyles.insert((uint32_t)sb->auxA); + } + } + + for(uint32_t v : usedStyles) { + Style *s = Style::Get(hStyle{v}); + layer.name = s->DescriptionString(); + dxf->writeLayer(&layer); + } + } + + void writeLTypes() override { + for(uint32_t i = 0; i <= (uint32_t)StipplePattern::LAST; i++) { + StipplePattern st = (StipplePattern)i; + DRW_LType type; + // LibreCAD requires the line type to have one of these exact names, + // or otherwise it overwrites it with its own (continuous) style. + type.name = DxfFileWriter::lineTypeName(st); + double sw = 1.0; + switch(st) { + case StipplePattern::CONTINUOUS: + break; + + case StipplePattern::SHORT_DASH: + type.path.push_back(sw); + type.path.push_back(-sw * 2.0); + break; + + case StipplePattern::DASH: + type.path.push_back(sw); + type.path.push_back(-sw); + break; + + case StipplePattern::LONG_DASH: + type.path.push_back(sw * 2.0); + type.path.push_back(-sw); + break; + + case StipplePattern::DASH_DOT: + type.path.push_back(sw); + type.path.push_back(-sw); + type.path.push_back(0.0); + type.path.push_back(-sw); + break; + + case StipplePattern::DOT: + type.path.push_back(sw); + type.path.push_back(0.0); + break; + + case StipplePattern::DASH_DOT_DOT: + type.path.push_back(sw); + type.path.push_back(-sw); + type.path.push_back(0.0); + type.path.push_back(-sw); + type.path.push_back(0.0); + type.path.push_back(-sw); + break; + + case StipplePattern::FREEHAND: + case StipplePattern::ZIGZAG: + // Not implemented; exported as continuous. + break; + } + dxf->writeLineType(&type); + } + } + + void writePolylines() { + PolylineBuilder builder; + + for(DxfFileWriter::BezierPath &path : writer->paths) { + for(SBezier *sb : path.beziers) { + if(sb->deg != 1) continue; + builder.AddEdge(sb->ctrl[0], sb->ctrl[1], (uint32_t)sb->auxA); + } + } + + DRW_Polyline polyline; + + auto startFunc = [&](PolylineBuilder::Vertex *start, + PolylineBuilder::Vertex *next, + PolylineBuilder::Edge *e) { + hStyle hs = { e->kind }; + polyline = {}; + assignEntityDefaults(&polyline, hs); + + if(!(EXACT(start->pos.z == 0.0) && EXACT(next->pos.z == 0.0))) { + polyline.flags |= 8 /* 3d polyline */; + } + polyline.vertlist.push_back( + new DRW_Vertex(start->pos.x, start->pos.y, start->pos.z, 0.0)); + polyline.vertlist.push_back( + new DRW_Vertex(next->pos.x, next->pos.y, next->pos.z, 0.0)); + }; + + auto nextFunc = [&](PolylineBuilder::Vertex *next, PolylineBuilder::Edge *e) { + if(!EXACT(next->pos.z == 0.0)) { + polyline.flags |= 8 /* 3d polyline */; + } + polyline.vertlist.push_back( + new DRW_Vertex(next->pos.x, next->pos.y, next->pos.z, 0.0)); + }; + + auto endFunc = [&]() { + dxf->writePolyline(&polyline); + }; + + auto aloneFunc = [&](PolylineBuilder::Edge *e) { + hStyle hs = { e->kind }; + writeLine(e->a->pos, e->b->pos, hs); + }; + + builder.Generate(startFunc, nextFunc, aloneFunc, endFunc); + } + + void writeEntities() override { + writePolylines(); + + for(DxfFileWriter::BezierPath &path : writer->paths) { + for(SBezier *sb : path.beziers) { + if(sb->deg == 1) continue; + writeBezier(sb); + } + } + + if(writer->constraint) { + Constraint *c; + for(c = writer->constraint->First(); c; c = writer->constraint->NextAfter(c)) { + if(!writer->NeedToOutput(c)) continue; + switch(c->type) { + case Constraint::Type::PT_PT_DISTANCE: { + Vector ap = SK.GetEntity(c->ptA)->PointGetNum(); + Vector bp = SK.GetEntity(c->ptB)->PointGetNum(); + Vector ref = ((ap.Plus(bp)).ScaledBy(0.5)).Plus(c->disp.offset); + writeAlignedDimension(xfrm(ap), xfrm(bp), xfrm(ref), + xfrm(ref), c->Label(), c->GetStyle(), c->valA); + break; + } + + case Constraint::Type::PT_LINE_DISTANCE: { + Vector pt = SK.GetEntity(c->ptA)->PointGetNum(); + Entity *line = SK.GetEntity(c->entityA); + Vector lA = SK.GetEntity(line->point[0])->PointGetNum(); + Vector lB = SK.GetEntity(line->point[1])->PointGetNum(); + Vector dl = lB.Minus(lA); + + Vector closest = pt.ClosestPointOnLine(lA, dl); + + if(pt.Equals(closest)) break; + + Vector ref = ((closest.Plus(pt)).ScaledBy(0.5)).Plus(c->disp.offset); + Vector refClosest = ref.ClosestPointOnLine(lA, dl); + + double ddl = dl.Dot(dl); + if(fabs(ddl) > LENGTH_EPS * LENGTH_EPS) { + double t = refClosest.Minus(lA).Dot(dl) / ddl; + if(t < 0.0) { + refClosest = lA; + } else if(t > 1.0) { + refClosest = lB; + } + } + + Vector xdl = xfrm(lB).Minus(xfrm(lA)); + writeLinearDimension(xfrm(pt), xfrm(refClosest), xfrm(ref), + xfrm(ref), c->Label(), + atan2(xdl.y, xdl.x) / PI * 180.0 + 90.0, 0.0, + c->GetStyle(), c->valA); + break; + } + + case Constraint::Type::DIAMETER: { + Entity *circle = SK.GetEntity(c->entityA); + Vector center = SK.GetEntity(circle->point[0])->PointGetNum(); + Quaternion q = SK.GetEntity(circle->normal)->NormalGetNum(); + Vector n = q.RotationN().WithMagnitude(1); + double r = circle->CircleGetRadiusNum(); + + Vector ref = center.Plus(c->disp.offset); + // Force the label into the same plane as the circle. + ref = ref.Minus(n.ScaledBy(n.Dot(ref) - n.Dot(center))); + + Vector rad = ref.Minus(center).WithMagnitude(r); + if(/*isRadius*/c->other) { + writeRadialDimension( + xfrm(center), xfrm(center.Plus(rad)), + xfrm(ref), c->Label(), c->GetStyle(), c->valA); + } else { + writeDiametricDimension( + xfrm(center.Minus(rad)), xfrm(center.Plus(rad)), + xfrm(ref), c->Label(), c->GetStyle(), c->valA); + } + break; + } + + case Constraint::Type::ANGLE: { + Entity *a = SK.GetEntity(c->entityA); + Entity *b = SK.GetEntity(c->entityB); + + Vector a0 = a->VectorGetStartPoint(); + Vector b0 = b->VectorGetStartPoint(); + Vector da = a->VectorGetNum(); + Vector db = b->VectorGetNum(); + if(/*otherAngle*/c->other) { + a0 = a0.Plus(da); + da = da.ScaledBy(-1); + } + + bool skew = false; + Vector ref = c->disp.offset; + Vector pi = Vector::AtIntersectionOfLines(a0, a0.Plus(da), b0, b0.Plus(db), + &skew); + if(!skew) ref = pi.Plus(c->disp.offset); + + Vector norm = da.Cross(db); + Vector dna = norm.Cross(da).WithMagnitude(1.0); + + double thetaf = acos(da.DirectionCosineWith(db)); + + // Calculate median + Vector m = da.WithMagnitude(1.0).ScaledBy(cos(thetaf/2)).Plus( + dna.ScaledBy(sin(thetaf/2))); + Vector rm = ref.Minus(pi); + + // Test which side we have to place an arc + if(m.Dot(rm) < 0) { + da = da.ScaledBy(-1); dna = dna.ScaledBy(-1); + db = db.ScaledBy(-1); + } + + Vector bisect = da.WithMagnitude(1.0).ScaledBy(cos(thetaf / 2.0)).Plus( + dna.ScaledBy(sin(thetaf / 2.0))); + + ref = pi.Plus(bisect.WithMagnitude(c->disp.offset.Magnitude())); + + // Get lines again to write exact line. + a0 = a->VectorGetStartPoint(); + b0 = b->VectorGetStartPoint(); + da = a->VectorGetNum(); + db = b->VectorGetNum(); + + writeAngularDimension( + xfrm(a0), xfrm(a0.Plus(da)), xfrm(b0), xfrm(b0.Plus(db)), xfrm(ref), + xfrm(ref), c->Label(), c->GetStyle(), c->valA); + break; + } + + case Constraint::Type::COMMENT: { + Style *st = SK.style.FindById(c->GetStyle()); + writeText(xfrm(c->disp.offset), c->Label(), + Style::TextHeight(c->GetStyle()) / SS.GW.scale, + st->textAngle, st->textOrigin, c->GetStyle()); + break; + } + + default: + // Other types of constraints do not have a DXF dimension equivalent. + break; + } + } + } + } + + int findDxfColor(const RgbaColor &src) { + int best = 0; + double minDist = VERY_POSITIVE; + Vector srcv = Vector::From(src.redF(), src.greenF(), src.blueF()); + for(int i = 1; i < 256; i++) { + RgbaColor dst = RGBi(DRW::dxfColors[i][0], DRW::dxfColors[i][1], DRW::dxfColors[i][2]); + Vector dstv = Vector::From(dst.redF(), dst.greenF(), dst.blueF()); + double dist = srcv.Minus(dstv).Magnitude(); + if(dist < minDist || best == 0) { + best = i; + minDist = dist; + } + } + return best; + } + + void assignEntityDefaults(DRW_Entity *entity, hStyle hs) { + Style *s = Style::Get(hs); + RgbaColor color = Style::Color(hs, /*forExport=*/true); + entity->color24 = color.ToPackedIntBGRA(); + entity->color = findDxfColor(color); + entity->layer = s->DescriptionString(); + entity->lineType = DxfFileWriter::lineTypeName(s->stippleType); + entity->ltypeScale = Style::StippleScaleMm(s->h); + entity->setWidthMm(Style::WidthMm(hs.v)); + + if(s->stippleType == StipplePattern::FREEHAND) { + messages.insert(_("freehand lines were replaced with continuous lines")); + } else if(s->stippleType == StipplePattern::ZIGZAG) { + messages.insert(_("zigzag lines were replaced with continuous lines")); + } + } + + void assignDimensionDefaults(DRW_Dimension *dimension, hStyle hs) { + assignEntityDefaults(dimension, hs); + dimension->layer = "dimensions"; + } + + void writeLine(const Vector &p0, const Vector &p1, hStyle hs) { + DRW_Line line; + assignEntityDefaults(&line, hs); + line.basePoint = toCoord(p0); + line.secPoint = toCoord(p1); + dxf->writeLine(&line); + } + + void writeArc(const Vector &c, double r, double sa, double ea, hStyle hs) { + DRW_Arc arc; + assignEntityDefaults(&arc, hs); + arc.radious = r; + arc.basePoint = toCoord(c); + arc.staangle = sa; + arc.endangle = ea; + dxf->writeArc(&arc); + } + + void writeBezierAsPwl(SBezier *sb) { + List lv = {}; + sb->MakePwlInto(&lv, SS.ExportChordTolMm()); + hStyle hs = { (uint32_t)sb->auxA }; + DRW_Polyline polyline; + assignEntityDefaults(&polyline, hs); + for(int i = 0; i < lv.n; i++) { + Vector *v = &lv[i]; + DRW_Vertex *vertex = new DRW_Vertex(v->x, v->y, v->z, 0.0); + polyline.vertlist.push_back(vertex); + } + dxf->writePolyline(&polyline); + lv.Clear(); + } + + void makeKnotsFor(DRW_Spline *spline) { + // QCad/LibreCAD require this for some reason. + if(spline->degree == 3) { + spline->nknots = 8; + spline->knotslist.push_back(0.0); + spline->knotslist.push_back(0.0); + spline->knotslist.push_back(0.0); + spline->knotslist.push_back(0.0); + spline->knotslist.push_back(1.0); + spline->knotslist.push_back(1.0); + spline->knotslist.push_back(1.0); + spline->knotslist.push_back(1.0); + } else if(spline->degree == 2) { + spline->nknots = 6; + spline->knotslist.push_back(0.0); + spline->knotslist.push_back(0.0); + spline->knotslist.push_back(0.0); + spline->knotslist.push_back(1.0); + spline->knotslist.push_back(1.0); + spline->knotslist.push_back(1.0); + } else ssassert(false, "Unexpected degree of spline"); + } + + void writeSpline(SBezier *sb) { + bool isRational = sb->IsRational(); + hStyle hs = { (uint32_t)sb->auxA }; + DRW_Spline spline; + assignEntityDefaults(&spline, hs); + spline.flags = (isRational) ? 0x04 : 0x08; + spline.degree = sb->deg; + spline.ncontrol = sb->deg + 1; + makeKnotsFor(&spline); + for(int i = 0; i <= sb->deg; i++) { + spline.controllist.push_back( + new DRW_Coord(sb->ctrl[i].x, sb->ctrl[i].y, sb->ctrl[i].z)); + if(isRational) spline.weightlist.push_back(sb->weight[i]); + } + dxf->writeSpline(&spline); + } + + void writeBezier(SBezier *sb) { + hStyle hs = { (uint32_t)sb->auxA }; + Vector c; + Vector n = Vector::From(0.0, 0.0, 1.0); + double r; + + if(sb->deg == 1) { + // Line + writeLine(sb->ctrl[0], sb->ctrl[1], hs); + } else if(sb->IsInPlane(n, 0) && sb->IsCircle(n, &c, &r)) { + // Circle perpendicular to camera + double theta0 = atan2(sb->ctrl[0].y - c.y, sb->ctrl[0].x - c.x); + double theta1 = atan2(sb->ctrl[2].y - c.y, sb->ctrl[2].x - c.x); + double dtheta = WRAP_SYMMETRIC(theta1 - theta0, 2.0 * PI); + if(dtheta < 0.0) swap(theta0, theta1); + + writeArc(c, r, theta0, theta1, hs); + } else if(sb->IsRational()) { + // Rational bezier + // We'd like to export rational beziers exactly, but the resulting DXF + // files can only be read by AutoCAD; LibreCAD/QCad simply do not + // implement the feature. So, export as piecewise linear for compatibility. + writeBezierAsPwl(sb); + } else { + // Any other curve + writeSpline(sb); + } + } + + void writeAlignedDimension(Vector def1, Vector def2, Vector dimp, + Vector textp, const std::string &text, hStyle hs, double actual) { + DRW_DimAligned dim; + assignDimensionDefaults(&dim, hs); + dim.setDef1Point(toCoord(def1)); + dim.setDef2Point(toCoord(def2)); + dim.setDimPoint(toCoord(dimp)); + dim.setTextPoint(toCoord(textp)); + dim.setText(text); + dim.setActualMeasurement(actual); + dxf->writeDimension(&dim); + } + + void writeLinearDimension(Vector def1, Vector def2, Vector dimp, + Vector textp, const std::string &text, + double angle, double oblique, hStyle hs, double actual) { + DRW_DimLinear dim; + assignDimensionDefaults(&dim, hs); + dim.setDef1Point(toCoord(def1)); + dim.setDef2Point(toCoord(def2)); + dim.setDimPoint(toCoord(dimp)); + dim.setTextPoint(toCoord(textp)); + dim.setText(text); + dim.setAngle(angle); + dim.setOblique(oblique); + dim.setActualMeasurement(actual); + dxf->writeDimension(&dim); + } + + void writeRadialDimension(Vector center, Vector radius, + Vector textp, const std::string &text, hStyle hs, double actual) { + DRW_DimRadial dim; + assignDimensionDefaults(&dim, hs); + dim.setCenterPoint(toCoord(center)); + dim.setDiameterPoint(toCoord(radius)); + dim.setTextPoint(toCoord(textp)); + dim.setText(text); + dim.setActualMeasurement(actual); + dxf->writeDimension(&dim); + } + + void writeDiametricDimension(Vector def1, Vector def2, + Vector textp, const std::string &text, hStyle hs, double actual) { + DRW_DimDiametric dim; + assignDimensionDefaults(&dim, hs); + dim.setDiameter1Point(toCoord(def1)); + dim.setDiameter2Point(toCoord(def2)); + dim.setTextPoint(toCoord(textp)); + dim.setText(text); + dim.setActualMeasurement(actual); + dxf->writeDimension(&dim); + } + + void writeAngularDimension(Vector fl1, Vector fl2, Vector sl1, Vector sl2, Vector dimp, + Vector textp, const std::string &text, hStyle hs, double actual) { + DRW_DimAngular dim; + assignDimensionDefaults(&dim, hs); + dim.setFirstLine1(toCoord(fl1)); + dim.setFirstLine2(toCoord(fl2)); + dim.setSecondLine1(toCoord(sl1)); + dim.setSecondLine2(toCoord(sl2)); + dim.setDimPoint(toCoord(dimp)); + dim.setTextPoint(toCoord(textp)); + dim.setText(text); + dim.setActualMeasurement(actual * PI / 180.0); + dxf->writeDimension(&dim); + } + + void writeText(Vector textp, const std::string &text, + double height, double angle, Style::TextOrigin origin, hStyle hs) { + DRW_Text txt; + assignEntityDefaults(&txt, hs); + txt.layer = "text"; + txt.style = "unicode"; + txt.basePoint = toCoord(textp); + txt.secPoint = txt.basePoint; + txt.text = text; + txt.height = height; + txt.angle = angle; + txt.alignH = DRW_Text::HCenter; + if((uint32_t)origin & (uint32_t)Style::TextOrigin::LEFT) { + txt.alignH = DRW_Text::HLeft; + } else if((uint32_t)origin & (uint32_t)Style::TextOrigin::RIGHT) { + txt.alignH = DRW_Text::HRight; + } + txt.alignV = DRW_Text::VMiddle; + if((uint32_t)origin & (uint32_t)Style::TextOrigin::TOP) { + txt.alignV = DRW_Text::VTop; + } else if((uint32_t)origin & (uint32_t)Style::TextOrigin::BOT) { + txt.alignV = DRW_Text::VBaseLine; + } + dxf->writeText(&txt); + } +}; + +bool DxfFileWriter::OutputConstraints(IdList *constraint) { + this->constraint = constraint; + return true; +} + +void DxfFileWriter::StartFile() { + paths.clear(); +} + +void DxfFileWriter::Background(RgbaColor color) { +} + +void DxfFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) +{ + BezierPath path = {}; + paths.push_back(path); +} +void DxfFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) +{ +} + +void DxfFileWriter::Triangle(STriangle *tr) { +} + +void DxfFileWriter::Bezier(SBezier *sb) { + paths.back().beziers.push_back(sb); +} + +void DxfFileWriter::FinishAndCloseFile() { + dxfRW dxf; + + DxfWriteInterface interface = {}; + interface.writer = this; + interface.dxf = &dxf; + + std::stringstream stream; + dxf.write(stream, &interface, DRW::AC1021, /*bin=*/false); + paths.clear(); + constraint = NULL; + + if(!WriteFile(filename, stream.str())) { + Error("Couldn't write to '%s'", filename.raw.c_str()); + return; + } + + if(!interface.messages.empty()) { + std::string text = _("Some aspects of the drawing have no DXF equivalent and " + "were not exported:\n"); + for(const std::string &message : interface.messages) { + text += " * " + message + "\n"; + } + Message(text.c_str()); + } +} + +bool DxfFileWriter::NeedToOutput(Constraint *c) { + switch(c->type) { + case Constraint::Type::PT_PT_DISTANCE: + case Constraint::Type::PT_LINE_DISTANCE: + case Constraint::Type::DIAMETER: + case Constraint::Type::ANGLE: + case Constraint::Type::COMMENT: + return c->IsVisible(); + + default: // See writeEntities(). + break; + } + return false; +} + +const char *DxfFileWriter::lineTypeName(StipplePattern stippleType) { + switch(stippleType) { + case StipplePattern::CONTINUOUS: return "CONTINUOUS"; + case StipplePattern::SHORT_DASH: return "DASHED"; + case StipplePattern::DASH: return "DASHED"; + case StipplePattern::LONG_DASH: return "DASHEDX2"; + case StipplePattern::DASH_DOT: return "DASHDOT"; + case StipplePattern::DASH_DOT_DOT: return "DIVIDE"; + case StipplePattern::DOT: return "DOT"; + + case StipplePattern::FREEHAND: + case StipplePattern::ZIGZAG: + /* no corresponding DXF line type */ + break; + } + + return "CONTINUOUS"; +} + +//----------------------------------------------------------------------------- +// Routines for EPS output +//----------------------------------------------------------------------------- + +static std::string MakeStipplePattern(StipplePattern pattern, double scale, char delimiter, + bool inkscapeWorkaround = false) { + scale /= 2.0; + + // Inkscape ignores all elements that are exactly zero instead of drawing + // them as dots. + double zero = inkscapeWorkaround ? 1e-6 : 0; + + std::string result; + switch(pattern) { + case StipplePattern::CONTINUOUS: + return ""; + + case StipplePattern::SHORT_DASH: + result = ssprintf("%.3f_%.3f", scale, scale * 2.0); + break; + case StipplePattern::DASH: + result = ssprintf("%.3f_%.3f", scale, scale); + break; + case StipplePattern::DASH_DOT: + result = ssprintf("%.3f_%.3f_%.6f_%.3f", + scale, scale * 0.5, zero, scale * 0.5); + break; + case StipplePattern::DASH_DOT_DOT: + result = ssprintf("%.3f_%.3f_%.6f_%.3f_%.6f_%.3f", + scale, scale * 0.5, zero, + scale * 0.5, scale * 0.5, zero); + break; + case StipplePattern::DOT: + result = ssprintf("%.6f_%.3f", zero, scale * 0.5); + break; + case StipplePattern::LONG_DASH: + result = ssprintf("%.3f_%.3f", scale * 2.0, scale * 0.5); + break; + + case StipplePattern::FREEHAND: + case StipplePattern::ZIGZAG: + ssassert(false, "Freehand and zigzag export not implemented"); + } + std::replace(result.begin(), result.end(), '_', delimiter); + return result; +} + +void EpsFileWriter::StartFile() { + fprintf(f, +"%%!PS-Adobe-2.0\r\n" +"%%%%Creator: SolveSpace\r\n" +"%%%%Title: title\r\n" +"%%%%Pages: 0\r\n" +"%%%%PageOrder: Ascend\r\n" +"%%%%BoundingBox: 0 0 %d %d\r\n" +"%%%%HiResBoundingBox: 0 0 %.3f %.3f\r\n" +"%%%%EndComments\r\n" +"\r\n" +"gsave\r\n" +"\r\n", + (int)ceil(MmToPts(ptMax.x - ptMin.x)), + (int)ceil(MmToPts(ptMax.y - ptMin.y)), + MmToPts(ptMax.x - ptMin.x), + MmToPts(ptMax.y - ptMin.y)); +} + +void EpsFileWriter::Background(RgbaColor color) { + double width = ptMax.x - ptMin.x; + double height = ptMax.y - ptMin.y; + + fprintf(f, +"%.3f %.3f %.3f setrgbcolor\r\n" +"newpath\r\n" +" %.3f %.3f moveto\r\n" +" %.3f %.3f lineto\r\n" +" %.3f %.3f lineto\r\n" +" %.3f %.3f lineto\r\n" +" closepath\r\n" +"gsave fill grestore\r\n", + color.redF(), color.greenF(), color.blueF(), + MmToPts(0), MmToPts(0), + MmToPts(width), MmToPts(0), + MmToPts(width), MmToPts(height), + MmToPts(0), MmToPts(height)); + + // same issue with cracks, stroke it to avoid them + double sw = max(width, height) / 1000; + fprintf(f, +"1 setlinejoin\r\n" +"1 setlinecap\r\n" +"%.3f setlinewidth\r\n" +"gsave stroke grestore\r\n", + MmToPts(sw)); +} + +void EpsFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) +{ + fprintf(f, "newpath\r\n"); + prevPt = Vector::From(VERY_POSITIVE, VERY_POSITIVE, VERY_POSITIVE); +} +void EpsFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) +{ + StipplePattern pattern = Style::PatternType(hs); + double stippleScale = MmToPts(Style::StippleScaleMm(hs)); + + fprintf(f, " %.3f setlinewidth\r\n" + " %.3f %.3f %.3f setrgbcolor\r\n" + " 1 setlinejoin\r\n" // rounded + " 1 setlinecap\r\n" // rounded + " [%s] 0 setdash\r\n" + " gsave stroke grestore\r\n", + MmToPts(lineWidth), + strokeRgb.redF(), strokeRgb.greenF(), strokeRgb.blueF(), + MakeStipplePattern(pattern, stippleScale, ' ').c_str()); + if(filled) { + fprintf(f, " %.3f %.3f %.3f setrgbcolor\r\n" + " gsave fill grestore\r\n", + fillRgb.redF(), fillRgb.greenF(), fillRgb.blueF()); + } +} + +void EpsFileWriter::MaybeMoveTo(Vector st, Vector fi) { + if(!prevPt.Equals(st)) { + fprintf(f, " %.3f %.3f moveto\r\n", + MmToPts(st.x - ptMin.x), MmToPts(st.y - ptMin.y)); + } + prevPt = fi; +} + +void EpsFileWriter::Triangle(STriangle *tr) { + fprintf(f, +"%.3f %.3f %.3f setrgbcolor\r\n" +"newpath\r\n" +" %.3f %.3f moveto\r\n" +" %.3f %.3f lineto\r\n" +" %.3f %.3f lineto\r\n" +" closepath\r\n" +"gsave fill grestore\r\n", + tr->meta.color.redF(), tr->meta.color.greenF(), tr->meta.color.blueF(), + MmToPts(tr->a.x - ptMin.x), MmToPts(tr->a.y - ptMin.y), + MmToPts(tr->b.x - ptMin.x), MmToPts(tr->b.y - ptMin.y), + MmToPts(tr->c.x - ptMin.x), MmToPts(tr->c.y - ptMin.y)); + + // same issue with cracks, stroke it to avoid them + double sw = max(ptMax.x - ptMin.x, ptMax.y - ptMin.y) / 1000; + fprintf(f, +"1 setlinejoin\r\n" +"1 setlinecap\r\n" +"%.3f setlinewidth\r\n" +"gsave stroke grestore\r\n", + MmToPts(sw)); +} + +void EpsFileWriter::Bezier(SBezier *sb) { + Vector c, n = Vector::From(0, 0, 1); + double r; + if(sb->deg == 1) { + MaybeMoveTo(sb->ctrl[0], sb->ctrl[1]); + fprintf(f, " %.3f %.3f lineto\r\n", + MmToPts(sb->ctrl[1].x - ptMin.x), + MmToPts(sb->ctrl[1].y - ptMin.y)); + } else if(sb->IsCircle(n, &c, &r)) { + Vector p0 = sb->ctrl[0], p1 = sb->ctrl[2]; + double theta0 = atan2(p0.y - c.y, p0.x - c.x), + theta1 = atan2(p1.y - c.y, p1.x - c.x), + dtheta = WRAP_SYMMETRIC(theta1 - theta0, 2*PI); + MaybeMoveTo(p0, p1); + fprintf(f, +" %.3f %.3f %.3f %.3f %.3f %s\r\n", + MmToPts(c.x - ptMin.x), MmToPts(c.y - ptMin.y), + MmToPts(r), + theta0*180/PI, theta1*180/PI, + dtheta < 0 ? "arcn" : "arc"); + } else if(sb->deg == 3 && !sb->IsRational()) { + MaybeMoveTo(sb->ctrl[0], sb->ctrl[3]); + fprintf(f, +" %.3f %.3f %.3f %.3f %.3f %.3f curveto\r\n", + MmToPts(sb->ctrl[1].x - ptMin.x), MmToPts(sb->ctrl[1].y - ptMin.y), + MmToPts(sb->ctrl[2].x - ptMin.x), MmToPts(sb->ctrl[2].y - ptMin.y), + MmToPts(sb->ctrl[3].x - ptMin.x), MmToPts(sb->ctrl[3].y - ptMin.y)); + } else { + BezierAsNonrationalCubic(sb); + } +} + +void EpsFileWriter::FinishAndCloseFile() { + fprintf(f, +"\r\n" +"grestore\r\n" +"\r\n"); + fclose(f); +} + +//----------------------------------------------------------------------------- +// Routines for PDF output, some extra complexity because we have to generate +// a correct xref table. +//----------------------------------------------------------------------------- +void PdfFileWriter::StartFile() { + if((ptMax.x - ptMin.x) > 200*25.4 || + (ptMax.y - ptMin.y) > 200*25.4) + { + Message(_("PDF page size exceeds 200 by 200 inches; many viewers may " + "reject this file.")); + } + + fprintf(f, +"%%PDF-1.1\r\n" +"%%%c%c%c%c\r\n", + 0xe2, 0xe3, 0xcf, 0xd3); + + xref[1] = (uint32_t)ftell(f); + fprintf(f, +"1 0 obj\r\n" +" << /Type /Catalog\r\n" +" /Outlines 2 0 R\r\n" +" /Pages 3 0 R\r\n" +" >>\r\n" +"endobj\r\n"); + + xref[2] = (uint32_t)ftell(f); + fprintf(f, +"2 0 obj\r\n" +" << /Type /Outlines\r\n" +" /Count 0\r\n" +" >>\r\n" +"endobj\r\n"); + + xref[3] = (uint32_t)ftell(f); + fprintf(f, +"3 0 obj\r\n" +" << /Type /Pages\r\n" +" /Kids [4 0 R]\r\n" +" /Count 1\r\n" +" >>\r\n" +"endobj\r\n"); + + xref[4] = (uint32_t)ftell(f); + fprintf(f, +"4 0 obj\r\n" +" << /Type /Page\r\n" +" /Parent 3 0 R\r\n" +" /MediaBox [0 0 %.3f %.3f]\r\n" +" /Contents 5 0 R\r\n" +" /Resources << /ProcSet 7 0 R\r\n" +" /Font << /F1 8 0 R >>\r\n" +" >>\r\n" +" >>\r\n" +"endobj\r\n", + MmToPts(ptMax.x - ptMin.x), + MmToPts(ptMax.y - ptMin.y)); + + xref[5] = (uint32_t)ftell(f); + fprintf(f, +"5 0 obj\r\n" +" << /Length 6 0 R >>\r\n" +"stream\r\n"); + bodyStart = (uint32_t)ftell(f); +} + +void PdfFileWriter::FinishAndCloseFile() { + uint32_t bodyEnd = (uint32_t)ftell(f); + + fprintf(f, +"endstream\r\n" +"endobj\r\n"); + + xref[6] = (uint32_t)ftell(f); + fprintf(f, +"6 0 obj\r\n" +" %d\r\n" +"endobj\r\n", + bodyEnd - bodyStart); + + xref[7] = (uint32_t)ftell(f); + fprintf(f, +"7 0 obj\r\n" +" [/PDF /Text]\r\n" +"endobj\r\n"); + + xref[8] = (uint32_t)ftell(f); + fprintf(f, +"8 0 obj\r\n" +" << /Type /Font\r\n" +" /Subtype /Type1\r\n" +" /Name /F1\r\n" +" /BaseFont /Helvetica\r\n" +" /Encoding /WinAnsiEncoding\r\n" +" >>\r\n" +"endobj\r\n"); + + xref[9] = (uint32_t)ftell(f); + fprintf(f, +"9 0 obj\r\n" +" << /Creator (SolveSpace)\r\n" +" >>\r\n"); + + uint32_t xrefStart = (uint32_t)ftell(f); + fprintf(f, +"xref\r\n" +"0 10\r\n" +"0000000000 65535 f\r\n"); + + int i; + for(i = 1; i <= 9; i++) { + fprintf(f, "%010d %05d n\r\n", xref[i], 0); + } + + fprintf(f, +"\r\n" +"trailer\r\n" +" << /Size 10\r\n" +" /Root 1 0 R\r\n" +" /Info 9 0 R\r\n" +" >>\r\n" +"startxref\r\n" +"%d\r\n" +"%%%%EOF\r\n", + xrefStart); + + fclose(f); + +} + +void PdfFileWriter::Background(RgbaColor color) { + double width = ptMax.x - ptMin.x; + double height = ptMax.y - ptMin.y; + double sw = max(width, height) / 1000; + + fprintf(f, +"1 J 1 j\r\n" +"%.3f %.3f %.3f RG\r\n" +"%.3f %.3f %.3f rg\r\n" +"%.3f w\r\n" +"%.3f %.3f m\r\n" +"%.3f %.3f l\r\n" +"%.3f %.3f l\r\n" +"%.3f %.3f l\r\n" +"b\r\n", + color.redF(), color.greenF(), color.blueF(), + color.redF(), color.greenF(), color.blueF(), + MmToPts(sw), + MmToPts(0), MmToPts(0), + MmToPts(width), MmToPts(0), + MmToPts(width), MmToPts(height), + MmToPts(0), MmToPts(height)); +} + +void PdfFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) +{ + StipplePattern pattern = Style::PatternType(hs); + double stippleScale = MmToPts(Style::StippleScaleMm(hs)); + + fprintf(f, "1 J 1 j " // round endcaps and joins + "%.3f w [%s] 0 d " + "%.3f %.3f %.3f RG\r\n", + MmToPts(lineWidth), + MakeStipplePattern(pattern, stippleScale, ' ').c_str(), + strokeRgb.redF(), strokeRgb.greenF(), strokeRgb.blueF()); + if(filled) { + fprintf(f, "%.3f %.3f %.3f rg\r\n", + fillRgb.redF(), fillRgb.greenF(), fillRgb.blueF()); + } + + prevPt = Vector::From(VERY_POSITIVE, VERY_POSITIVE, VERY_POSITIVE); +} +void PdfFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) +{ + if(filled) { + fprintf(f, "b\r\n"); + } else { + fprintf(f, "S\r\n"); + } +} + +void PdfFileWriter::MaybeMoveTo(Vector st, Vector fi) { + if(!prevPt.Equals(st)) { + fprintf(f, "%.3f %.3f m\r\n", + MmToPts(st.x - ptMin.x), MmToPts(st.y - ptMin.y)); + } + prevPt = fi; +} + +void PdfFileWriter::Triangle(STriangle *tr) { + double sw = max(ptMax.x - ptMin.x, ptMax.y - ptMin.y) / 1000; + + fprintf(f, +"1 J 1 j\r\n" +"%.3f %.3f %.3f RG\r\n" +"%.3f %.3f %.3f rg\r\n" +"%.3f w\r\n" +"%.3f %.3f m\r\n" +"%.3f %.3f l\r\n" +"%.3f %.3f l\r\n" +"b\r\n", + tr->meta.color.redF(), tr->meta.color.greenF(), tr->meta.color.blueF(), + tr->meta.color.redF(), tr->meta.color.greenF(), tr->meta.color.blueF(), + MmToPts(sw), + MmToPts(tr->a.x - ptMin.x), MmToPts(tr->a.y - ptMin.y), + MmToPts(tr->b.x - ptMin.x), MmToPts(tr->b.y - ptMin.y), + MmToPts(tr->c.x - ptMin.x), MmToPts(tr->c.y - ptMin.y)); +} + +void PdfFileWriter::Bezier(SBezier *sb) { + if(sb->deg == 1) { + MaybeMoveTo(sb->ctrl[0], sb->ctrl[1]); + fprintf(f, +"%.3f %.3f l\r\n", + MmToPts(sb->ctrl[1].x - ptMin.x), MmToPts(sb->ctrl[1].y - ptMin.y)); + } else if(sb->deg == 3 && !sb->IsRational()) { + MaybeMoveTo(sb->ctrl[0], sb->ctrl[3]); + fprintf(f, +"%.3f %.3f %.3f %.3f %.3f %.3f c\r\n", + MmToPts(sb->ctrl[1].x - ptMin.x), MmToPts(sb->ctrl[1].y - ptMin.y), + MmToPts(sb->ctrl[2].x - ptMin.x), MmToPts(sb->ctrl[2].y - ptMin.y), + MmToPts(sb->ctrl[3].x - ptMin.x), MmToPts(sb->ctrl[3].y - ptMin.y)); + } else { + BezierAsNonrationalCubic(sb); + } +} + +//----------------------------------------------------------------------------- +// Routines for SVG output +//----------------------------------------------------------------------------- +void SvgFileWriter::StartFile() { + fprintf(f, +"\r\n" +"\r\n" +"\r\n" +"Exported SVG\r\n" +"\r\n", + (ptMax.x - ptMin.x), (ptMax.y - ptMin.y), + (ptMax.x - ptMin.x), (ptMax.y - ptMin.y)); + + fprintf(f, "\r\n"); +} + +void SvgFileWriter::Background(RgbaColor color) { + fprintf(f, +"\r\n", + color.red, color.green, color.blue); +} + +void SvgFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) +{ + fprintf(f, "\r\n", cls.c_str(), fill.c_str()); +} + +void SvgFileWriter::MaybeMoveTo(Vector st, Vector fi) { + // SVG uses a coordinate system with the origin at top left, +y down + if(!prevPt.Equals(st)) { + fprintf(f, "M%.3f %.3f ", (st.x - ptMin.x), (ptMax.y - st.y)); + } + prevPt = fi; +} + +void SvgFileWriter::Triangle(STriangle *tr) { + fprintf(f, +"\r\n", + (tr->a.x - ptMin.x), (ptMax.y - tr->a.y), + (tr->b.x - ptMin.x), (ptMax.y - tr->b.y), + (tr->c.x - ptMin.x), (ptMax.y - tr->c.y), + tr->meta.color.red, tr->meta.color.green, tr->meta.color.blue, + tr->meta.color.red, tr->meta.color.green, tr->meta.color.blue); +} + +void SvgFileWriter::Bezier(SBezier *sb) { + Vector c, n = Vector::From(0, 0, 1); + double r; + if(sb->deg == 1) { + MaybeMoveTo(sb->ctrl[0], sb->ctrl[1]); + fprintf(f, "L%.3f,%.3f ", + (sb->ctrl[1].x - ptMin.x), (ptMax.y - sb->ctrl[1].y)); + } else if(sb->IsCircle(n, &c, &r)) { + Vector p0 = sb->ctrl[0], p1 = sb->ctrl[2]; + double theta0 = atan2(p0.y - c.y, p0.x - c.x), + theta1 = atan2(p1.y - c.y, p1.x - c.x), + dtheta = WRAP_SYMMETRIC(theta1 - theta0, 2*PI); + // The arc must be less than 180 degrees, or else it couldn't have + // been represented as a single rational Bezier. So large-arc-flag + // must be false. sweep-flag is determined by the sign of dtheta. + // Note that clockwise and counter-clockwise are backwards in SVG's + // mirrored csys. + MaybeMoveTo(p0, p1); + fprintf(f, "A%.3f,%.3f 0 0,%d %.3f,%.3f ", + r, r, + (dtheta < 0) ? 1 : 0, + p1.x - ptMin.x, ptMax.y - p1.y); + } else if(!sb->IsRational()) { + if(sb->deg == 2) { + MaybeMoveTo(sb->ctrl[0], sb->ctrl[2]); + fprintf(f, "Q%.3f,%.3f %.3f,%.3f ", + sb->ctrl[1].x - ptMin.x, ptMax.y - sb->ctrl[1].y, + sb->ctrl[2].x - ptMin.x, ptMax.y - sb->ctrl[2].y); + } else if(sb->deg == 3) { + MaybeMoveTo(sb->ctrl[0], sb->ctrl[3]); + fprintf(f, "C%.3f,%.3f %.3f,%.3f %.3f,%.3f ", + sb->ctrl[1].x - ptMin.x, ptMax.y - sb->ctrl[1].y, + sb->ctrl[2].x - ptMin.x, ptMax.y - sb->ctrl[2].y, + sb->ctrl[3].x - ptMin.x, ptMax.y - sb->ctrl[3].y); + } + } else { + BezierAsNonrationalCubic(sb); + } +} + +void SvgFileWriter::FinishAndCloseFile() { + fprintf(f, "\r\n\r\n"); + fclose(f); +} + +//----------------------------------------------------------------------------- +// Routines for HPGL output +//----------------------------------------------------------------------------- +double HpglFileWriter::MmToHpglUnits(double mm) { + return mm*40; +} + +void HpglFileWriter::StartFile() { + fprintf(f, "IN;\r\n"); + fprintf(f, "SP1;\r\n"); +} + +void HpglFileWriter::Background(RgbaColor color) { +} + +void HpglFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) +{ +} +void HpglFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) +{ +} + +void HpglFileWriter::Triangle(STriangle *tr) { +} + +void HpglFileWriter::Bezier(SBezier *sb) { + if(sb->deg == 1) { + fprintf(f, "PU%d,%d;\r\n", + (int)MmToHpglUnits(sb->ctrl[0].x), + (int)MmToHpglUnits(sb->ctrl[0].y)); + fprintf(f, "PD%d,%d;\r\n", + (int)MmToHpglUnits(sb->ctrl[1].x), + (int)MmToHpglUnits(sb->ctrl[1].y)); + } else { + BezierAsPwl(sb); + } +} + +void HpglFileWriter::FinishAndCloseFile() { + fclose(f); +} + +//----------------------------------------------------------------------------- +// Routines for G Code output. Slightly complicated by our ability to generate +// multiple passes, and to specify the feeds and depth; those parameters get +// set in the configuration screen. +//----------------------------------------------------------------------------- +void GCodeFileWriter::StartFile() { + sel = {}; +} +void GCodeFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) +{ +} +void GCodeFileWriter::Background(RgbaColor color) { +} +void GCodeFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) +{ +} +void GCodeFileWriter::Triangle(STriangle *tr) { +} + +void GCodeFileWriter::Bezier(SBezier *sb) { + if(sb->deg == 1) { + sel.AddEdge(sb->ctrl[0], sb->ctrl[1]); + } else { + BezierAsPwl(sb); + } +} + +void GCodeFileWriter::FinishAndCloseFile() { + SPolygon sp = {}; + sel.AssemblePolygon(&sp, NULL); + + int i; + for(i = 0; i < SS.gCode.passes; i++) { + double depth = (SS.gCode.depth / SS.gCode.passes)*(i+1); + + SContour *sc; + for(sc = sp.l.First(); sc; sc = sp.l.NextAfter(sc)) { + if(sc->l.n < 2) continue; + + SPoint *pt = sc->l.First(); + fprintf(f, "G00 X%s Y%s\r\n", + SS.MmToString(pt->p.x).c_str(), SS.MmToString(pt->p.y).c_str()); + fprintf(f, "G01 Z%s F%s\r\n", + SS.MmToString(depth).c_str(), SS.MmToString(SS.gCode.plungeFeed).c_str()); + + pt = sc->l.NextAfter(pt); + for(; pt; pt = sc->l.NextAfter(pt)) { + fprintf(f, "G01 X%s Y%s F%s\r\n", + SS.MmToString(pt->p.x).c_str(), SS.MmToString(pt->p.y).c_str(), + SS.MmToString(SS.gCode.feed).c_str()); + } + // Move up to a clearance plane 5mm above the work. + fprintf(f, "G00 Z%s\r\n", + SS.MmToString(SS.gCode.depth < 0 ? +5 : -5).c_str()); + } + } + + sp.Clear(); + sel.Clear(); + fclose(f); +} + + +//----------------------------------------------------------------------------- +// Routine for STEP output; just a wrapper around the general STEP stuff that +// can also be used for surfaces or 3d curves. +//----------------------------------------------------------------------------- +void Step2dFileWriter::StartFile() { + sfw = {}; + sfw.f = f; + sfw.WriteHeader(); +} + +void Step2dFileWriter::Background(RgbaColor color) { +} + +void Step2dFileWriter::Triangle(STriangle *tr) { +} + +void Step2dFileWriter::StartPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) +{ +} +void Step2dFileWriter::FinishPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) +{ +} + +void Step2dFileWriter::Bezier(SBezier *sb) { + int c = sfw.ExportCurve(sb); + sfw.curves.Add(&c); +} + +void Step2dFileWriter::FinishAndCloseFile() { + sfw.WriteWireframe(); + sfw.WriteFooter(); + fclose(f); +} + diff --git a/src/expr.cpp b/src/expr.cpp new file mode 100644 index 0000000..99d68ec --- /dev/null +++ b/src/expr.cpp @@ -0,0 +1,921 @@ +//----------------------------------------------------------------------------- +// The symbolic algebra system used to write our constraint equations; +// routines to build expressions in software or from a user-provided string, +// and to compute the partial derivatives that we'll use when write our +// Jacobian matrix. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +ExprVector ExprVector::From(Expr *x, Expr *y, Expr *z) { + ExprVector r = { x, y, z}; + return r; +} + +ExprVector ExprVector::From(Vector vn) { + ExprVector ve; + ve.x = Expr::From(vn.x); + ve.y = Expr::From(vn.y); + ve.z = Expr::From(vn.z); + return ve; +} + +ExprVector ExprVector::From(hParam x, hParam y, hParam z) { + ExprVector ve; + ve.x = Expr::From(x); + ve.y = Expr::From(y); + ve.z = Expr::From(z); + return ve; +} + +ExprVector ExprVector::From(double x, double y, double z) { + ExprVector ve; + ve.x = Expr::From(x); + ve.y = Expr::From(y); + ve.z = Expr::From(z); + return ve; +} + +ExprVector ExprVector::Minus(ExprVector b) const { + ExprVector r; + r.x = x->Minus(b.x); + r.y = y->Minus(b.y); + r.z = z->Minus(b.z); + return r; +} + +ExprVector ExprVector::Plus(ExprVector b) const { + ExprVector r; + r.x = x->Plus(b.x); + r.y = y->Plus(b.y); + r.z = z->Plus(b.z); + return r; +} + +Expr *ExprVector::Dot(ExprVector b) const { + Expr *r; + r = x->Times(b.x); + r = r->Plus(y->Times(b.y)); + r = r->Plus(z->Times(b.z)); + return r; +} + +ExprVector ExprVector::Cross(ExprVector b) const { + ExprVector r; + r.x = (y->Times(b.z))->Minus(z->Times(b.y)); + r.y = (z->Times(b.x))->Minus(x->Times(b.z)); + r.z = (x->Times(b.y))->Minus(y->Times(b.x)); + return r; +} + +ExprVector ExprVector::ScaledBy(Expr *s) const { + ExprVector r; + r.x = x->Times(s); + r.y = y->Times(s); + r.z = z->Times(s); + return r; +} + +ExprVector ExprVector::WithMagnitude(Expr *s) const { + Expr *m = Magnitude(); + return ScaledBy(s->Div(m)); +} + +Expr *ExprVector::Magnitude() const { + Expr *r; + r = x->Square(); + r = r->Plus(y->Square()); + r = r->Plus(z->Square()); + return r->Sqrt(); +} + +Vector ExprVector::Eval() const { + Vector r; + r.x = x->Eval(); + r.y = y->Eval(); + r.z = z->Eval(); + return r; +} + +ExprQuaternion ExprQuaternion::From(hParam w, hParam vx, hParam vy, hParam vz) { + ExprQuaternion q; + q.w = Expr::From(w); + q.vx = Expr::From(vx); + q.vy = Expr::From(vy); + q.vz = Expr::From(vz); + return q; +} + +ExprQuaternion ExprQuaternion::From(Expr *w, Expr *vx, Expr *vy, Expr *vz) +{ + ExprQuaternion q; + q.w = w; + q.vx = vx; + q.vy = vy; + q.vz = vz; + return q; +} + +ExprQuaternion ExprQuaternion::From(Quaternion qn) { + ExprQuaternion qe; + qe.w = Expr::From(qn.w); + qe.vx = Expr::From(qn.vx); + qe.vy = Expr::From(qn.vy); + qe.vz = Expr::From(qn.vz); + return qe; +} + +ExprVector ExprQuaternion::RotationU() const { + ExprVector u; + Expr *two = Expr::From(2); + + u.x = w->Square(); + u.x = (u.x)->Plus(vx->Square()); + u.x = (u.x)->Minus(vy->Square()); + u.x = (u.x)->Minus(vz->Square()); + + u.y = two->Times(w->Times(vz)); + u.y = (u.y)->Plus(two->Times(vx->Times(vy))); + + u.z = two->Times(vx->Times(vz)); + u.z = (u.z)->Minus(two->Times(w->Times(vy))); + + return u; +} + +ExprVector ExprQuaternion::RotationV() const { + ExprVector v; + Expr *two = Expr::From(2); + + v.x = two->Times(vx->Times(vy)); + v.x = (v.x)->Minus(two->Times(w->Times(vz))); + + v.y = w->Square(); + v.y = (v.y)->Minus(vx->Square()); + v.y = (v.y)->Plus(vy->Square()); + v.y = (v.y)->Minus(vz->Square()); + + v.z = two->Times(w->Times(vx)); + v.z = (v.z)->Plus(two->Times(vy->Times(vz))); + + return v; +} + +ExprVector ExprQuaternion::RotationN() const { + ExprVector n; + Expr *two = Expr::From(2); + + n.x = two->Times( w->Times(vy)); + n.x = (n.x)->Plus (two->Times(vx->Times(vz))); + + n.y = two->Times(vy->Times(vz)); + n.y = (n.y)->Minus(two->Times( w->Times(vx))); + + n.z = w->Square(); + n.z = (n.z)->Minus(vx->Square()); + n.z = (n.z)->Minus(vy->Square()); + n.z = (n.z)->Plus (vz->Square()); + + return n; +} + +ExprVector ExprQuaternion::Rotate(ExprVector p) const { + // Express the point in the new basis + return (RotationU().ScaledBy(p.x)).Plus( + RotationV().ScaledBy(p.y)).Plus( + RotationN().ScaledBy(p.z)); +} + +ExprQuaternion ExprQuaternion::Times(ExprQuaternion b) const { + Expr *sa = w, *sb = b.w; + ExprVector va = { vx, vy, vz }; + ExprVector vb = { b.vx, b.vy, b.vz }; + + ExprQuaternion r; + r.w = (sa->Times(sb))->Minus(va.Dot(vb)); + ExprVector vr = vb.ScaledBy(sa).Plus( + va.ScaledBy(sb).Plus( + va.Cross(vb))); + r.vx = vr.x; + r.vy = vr.y; + r.vz = vr.z; + return r; +} + +Expr *ExprQuaternion::Magnitude() const { + return ((w ->Square())->Plus( + (vx->Square())->Plus( + (vy->Square())->Plus( + (vz->Square())))))->Sqrt(); +} + + +Expr *Expr::From(hParam p) { + Expr *r = AllocExpr(); + r->op = Op::PARAM; + r->parh = p; + return r; +} + +Expr *Expr::From(double v) { + // Statically allocate common constants. + // Note: this is only valid because AllocExpr() uses AllocTemporary(), + // and Expr* is never explicitly freed. + + if(v == 0.0) { + static Expr zero(0.0); + return &zero; + } + + if(v == 1.0) { + static Expr one(1.0); + return &one; + } + + if(v == -1.0) { + static Expr mone(-1.0); + return &mone; + } + + if(v == 0.5) { + static Expr half(0.5); + return ½ + } + + if(v == -0.5) { + static Expr mhalf(-0.5); + return &mhalf; + } + + Expr *r = AllocExpr(); + r->op = Op::CONSTANT; + r->v = v; + return r; +} + +Expr *Expr::AnyOp(Op newOp, Expr *b) { + Expr *r = AllocExpr(); + r->op = newOp; + r->a = this; + r->b = b; + return r; +} + +int Expr::Children() const { + switch(op) { + case Op::PARAM: + case Op::PARAM_PTR: + case Op::CONSTANT: + case Op::VARIABLE: + return 0; + + case Op::PLUS: + case Op::MINUS: + case Op::TIMES: + case Op::DIV: + return 2; + + case Op::NEGATE: + case Op::SQRT: + case Op::SQUARE: + case Op::SIN: + case Op::COS: + case Op::ASIN: + case Op::ACOS: + return 1; + } + ssassert(false, "Unexpected operation"); +} + +int Expr::Nodes() const { + switch(Children()) { + case 0: return 1; + case 1: return 1 + a->Nodes(); + case 2: return 1 + a->Nodes() + b->Nodes(); + default: ssassert(false, "Unexpected children count"); + } +} + +Expr *Expr::DeepCopy() const { + Expr *n = AllocExpr(); + *n = *this; + int c = n->Children(); + if(c > 0) n->a = a->DeepCopy(); + if(c > 1) n->b = b->DeepCopy(); + return n; +} + +Expr *Expr::DeepCopyWithParamsAsPointers(IdList *firstTry, + IdList *thenTry) const +{ + Expr *n = AllocExpr(); + if(op == Op::PARAM) { + // A param that is referenced by its hParam gets rewritten to go + // straight in to the parameter table with a pointer, or simply + // into a constant if it's already known. + Param *p = firstTry->FindByIdNoOops(parh); + if(!p) p = thenTry->FindById(parh); + if(p->known) { + n->op = Op::CONSTANT; + n->v = p->val; + } else { + n->op = Op::PARAM_PTR; + n->parp = p; + } + return n; + } + + *n = *this; + int c = n->Children(); + if(c > 0) n->a = a->DeepCopyWithParamsAsPointers(firstTry, thenTry); + if(c > 1) n->b = b->DeepCopyWithParamsAsPointers(firstTry, thenTry); + return n; +} + +double Expr::Eval() const { + switch(op) { + case Op::PARAM: return SK.GetParam(parh)->val; + case Op::PARAM_PTR: return parp->val; + + case Op::CONSTANT: return v; + case Op::VARIABLE: ssassert(false, "Not supported yet"); + + case Op::PLUS: return a->Eval() + b->Eval(); + case Op::MINUS: return a->Eval() - b->Eval(); + case Op::TIMES: return a->Eval() * b->Eval(); + case Op::DIV: return a->Eval() / b->Eval(); + + case Op::NEGATE: return -(a->Eval()); + case Op::SQRT: return sqrt(a->Eval()); + case Op::SQUARE: { double r = a->Eval(); return r*r; } + case Op::SIN: return sin(a->Eval()); + case Op::COS: return cos(a->Eval()); + case Op::ACOS: return acos(a->Eval()); + case Op::ASIN: return asin(a->Eval()); + } + ssassert(false, "Unexpected operation"); +} + +Expr *Expr::PartialWrt(hParam p) const { + Expr *da, *db; + + switch(op) { + case Op::PARAM_PTR: return From(p == parp->h ? 1 : 0); + case Op::PARAM: return From(p == parh ? 1 : 0); + + case Op::CONSTANT: return From(0.0); + case Op::VARIABLE: ssassert(false, "Not supported yet"); + + case Op::PLUS: return (a->PartialWrt(p))->Plus(b->PartialWrt(p)); + case Op::MINUS: return (a->PartialWrt(p))->Minus(b->PartialWrt(p)); + + case Op::TIMES: + da = a->PartialWrt(p); + db = b->PartialWrt(p); + return (a->Times(db))->Plus(b->Times(da)); + + case Op::DIV: + da = a->PartialWrt(p); + db = b->PartialWrt(p); + return ((da->Times(b))->Minus(a->Times(db)))->Div(b->Square()); + + case Op::SQRT: + return (From(0.5)->Div(a->Sqrt()))->Times(a->PartialWrt(p)); + + case Op::SQUARE: + return (From(2.0)->Times(a))->Times(a->PartialWrt(p)); + + case Op::NEGATE: return (a->PartialWrt(p))->Negate(); + case Op::SIN: return (a->Cos())->Times(a->PartialWrt(p)); + case Op::COS: return ((a->Sin())->Times(a->PartialWrt(p)))->Negate(); + + case Op::ASIN: + return (From(1)->Div((From(1)->Minus(a->Square()))->Sqrt())) + ->Times(a->PartialWrt(p)); + case Op::ACOS: + return (From(-1)->Div((From(1)->Minus(a->Square()))->Sqrt())) + ->Times(a->PartialWrt(p)); + } + ssassert(false, "Unexpected operation"); +} + +uint64_t Expr::ParamsUsed() const { + uint64_t r = 0; + if(op == Op::PARAM) r |= ((uint64_t)1 << (parh.v % 61)); + if(op == Op::PARAM_PTR) r |= ((uint64_t)1 << (parp->h.v % 61)); + + int c = Children(); + if(c >= 1) r |= a->ParamsUsed(); + if(c >= 2) r |= b->ParamsUsed(); + return r; +} + +bool Expr::DependsOn(hParam p) const { + if(op == Op::PARAM) return (parh == p); + if(op == Op::PARAM_PTR) return (parp->h == p); + + int c = Children(); + if(c == 1) return a->DependsOn(p); + if(c == 2) return a->DependsOn(p) || b->DependsOn(p); + return false; +} + +bool Expr::Tol(double a, double b) { + return fabs(a - b) < 0.001; +} +Expr *Expr::FoldConstants() { + Expr *n = AllocExpr(); + *n = *this; + + int c = Children(); + if(c >= 1) n->a = a->FoldConstants(); + if(c >= 2) n->b = b->FoldConstants(); + + switch(op) { + case Op::PARAM_PTR: + case Op::PARAM: + case Op::CONSTANT: + case Op::VARIABLE: + break; + + case Op::MINUS: + case Op::TIMES: + case Op::DIV: + case Op::PLUS: + // If both ops are known, then we can evaluate immediately + if(n->a->op == Op::CONSTANT && n->b->op == Op::CONSTANT) { + double nv = n->Eval(); + n->op = Op::CONSTANT; + n->v = nv; + break; + } + // x + 0 = 0 + x = x + if(op == Op::PLUS && n->b->op == Op::CONSTANT && Tol(n->b->v, 0)) { + *n = *(n->a); break; + } + if(op == Op::PLUS && n->a->op == Op::CONSTANT && Tol(n->a->v, 0)) { + *n = *(n->b); break; + } + // 1*x = x*1 = x + if(op == Op::TIMES && n->b->op == Op::CONSTANT && Tol(n->b->v, 1)) { + *n = *(n->a); break; + } + if(op == Op::TIMES && n->a->op == Op::CONSTANT && Tol(n->a->v, 1)) { + *n = *(n->b); break; + } + // 0*x = x*0 = 0 + if(op == Op::TIMES && n->b->op == Op::CONSTANT && Tol(n->b->v, 0)) { + n->op = Op::CONSTANT; n->v = 0; break; + } + if(op == Op::TIMES && n->a->op == Op::CONSTANT && Tol(n->a->v, 0)) { + n->op = Op::CONSTANT; n->v = 0; break; + } + + break; + + case Op::SQRT: + case Op::SQUARE: + case Op::NEGATE: + case Op::SIN: + case Op::COS: + case Op::ASIN: + case Op::ACOS: + if(n->a->op == Op::CONSTANT) { + double nv = n->Eval(); + n->op = Op::CONSTANT; + n->v = nv; + } + break; + } + return n; +} + +void Expr::Substitute(hParam oldh, hParam newh) { + ssassert(op != Op::PARAM_PTR, "Expected an expression that refer to params via handles"); + + if(op == Op::PARAM && parh == oldh) { + parh = newh; + } + int c = Children(); + if(c >= 1) a->Substitute(oldh, newh); + if(c >= 2) b->Substitute(oldh, newh); +} + +//----------------------------------------------------------------------------- +// If the expression references only one parameter that appears in pl, then +// return that parameter. If no param is referenced, then return NO_PARAMS. +// If multiple params are referenced, then return MULTIPLE_PARAMS. +//----------------------------------------------------------------------------- +const hParam Expr::NO_PARAMS = { 0 }; +const hParam Expr::MULTIPLE_PARAMS = { 1 }; +hParam Expr::ReferencedParams(ParamList *pl) const { + if(op == Op::PARAM) { + if(pl->FindByIdNoOops(parh)) { + return parh; + } else { + return NO_PARAMS; + } + } + ssassert(op != Op::PARAM_PTR, "Expected an expression that refer to params via handles"); + + int c = Children(); + if(c == 0) { + return NO_PARAMS; + } else if(c == 1) { + return a->ReferencedParams(pl); + } else if(c == 2) { + hParam pa, pb; + pa = a->ReferencedParams(pl); + pb = b->ReferencedParams(pl); + if(pa == NO_PARAMS) { + return pb; + } else if(pb == NO_PARAMS) { + return pa; + } else if(pa == pb) { + return pa; // either, doesn't matter + } else { + return MULTIPLE_PARAMS; + } + } else ssassert(false, "Unexpected children count"); +} + + +//----------------------------------------------------------------------------- +// Routines to pretty-print an expression. Mostly for debugging. +//----------------------------------------------------------------------------- + +std::string Expr::Print() const { + char c; + switch(op) { + case Op::PARAM: return ssprintf("param(%08x)", parh.v); + case Op::PARAM_PTR: return ssprintf("param(p%08x)", parp->h.v); + + case Op::CONSTANT: return ssprintf("%.3f", v); + case Op::VARIABLE: return "(var)"; + + case Op::PLUS: c = '+'; goto p; + case Op::MINUS: c = '-'; goto p; + case Op::TIMES: c = '*'; goto p; + case Op::DIV: c = '/'; goto p; +p: + return "(" + a->Print() + " " + c + " " + b->Print() + ")"; + break; + + case Op::NEGATE: return "(- " + a->Print() + ")"; + case Op::SQRT: return "(sqrt " + a->Print() + ")"; + case Op::SQUARE: return "(square " + a->Print() + ")"; + case Op::SIN: return "(sin " + a->Print() + ")"; + case Op::COS: return "(cos " + a->Print() + ")"; + case Op::ASIN: return "(asin " + a->Print() + ")"; + case Op::ACOS: return "(acos " + a->Print() + ")"; + } + ssassert(false, "Unexpected operation"); +} + + +//----------------------------------------------------------------------------- +// A parser; convert a string to an expression. Infix notation, with the +// usual shift/reduce approach. I had great hopes for user-entered eq +// constraints, but those don't seem very useful, so right now this is just +// to provide calculator type functionality wherever numbers are entered. +//----------------------------------------------------------------------------- + +class ExprParser { +public: + enum class TokenType { + ERROR = 0, + + PAREN_LEFT, + PAREN_RIGHT, + BINARY_OP, + UNARY_OP, + OPERAND, + + END, + }; + + class Token { + public: + TokenType type; + Expr *expr; + + static Token From(TokenType type = TokenType::ERROR, Expr *expr = NULL); + static Token From(TokenType type, Expr::Op op); + bool IsError() const { return type == TokenType::ERROR; } + }; + + std::string::const_iterator it, end; + std::vector stack; + + char ReadChar(); + char PeekChar(); + + std::string ReadWord(); + void SkipSpace(); + + Token PopOperator(std::string *error); + Token PopOperand(std::string *error); + + int Precedence(Token token); + Token LexNumber(std::string *error); + Token Lex(std::string *error); + bool Reduce(std::string *error); + bool Parse(std::string *error, size_t reduceUntil = 0); + + static Expr *Parse(const std::string &input, std::string *error); +}; + +ExprParser::Token ExprParser::Token::From(TokenType type, Expr *expr) { + Token t; + t.type = type; + t.expr = expr; + return t; +} + +ExprParser::Token ExprParser::Token::From(TokenType type, Expr::Op op) { + Token t; + t.type = type; + t.expr = Expr::AllocExpr(); + t.expr->op = op; + return t; +} + +char ExprParser::ReadChar() { + return *it++; +} + +char ExprParser::PeekChar() { + if(it == end) { + return '\0'; + } else { + return *it; + } +} + +std::string ExprParser::ReadWord() { + std::string s; + + while(char c = PeekChar()) { + if(!isalnum(c)) break; + s.push_back(ReadChar()); + } + + return s; +} + +void ExprParser::SkipSpace() { + while(char c = PeekChar()) { + if(!isspace(c)) break; + ReadChar(); + } +} + +ExprParser::Token ExprParser::LexNumber(std::string *error) { + std::string s; + + while(char c = PeekChar()) { + if(!((c >= '0' && c <= '9') || c == 'e' || c == 'E' || c == '.' || c == '_')) break; + if(c == '_') { + ReadChar(); + continue; + } + s.push_back(ReadChar()); + } + + char *endptr; + double d = strtod(s.c_str(), &endptr); + + Token t = Token::From(); + if(endptr == s.c_str() + s.size()) { + t = Token::From(TokenType::OPERAND, Expr::Op::CONSTANT); + t.expr->v = d; + } else { + *error = "'" + s + "' is not a valid number"; + } + return t; +} + +ExprParser::Token ExprParser::Lex(std::string *error) { + SkipSpace(); + + Token t = Token::From(); + char c = PeekChar(); + if(isupper(c)) { + std::string n = ReadWord(); + t = Token::From(TokenType::OPERAND, Expr::Op::VARIABLE); + } else if(isalpha(c)) { + std::string s = ReadWord(); + if(s == "sqrt") { + t = Token::From(TokenType::UNARY_OP, Expr::Op::SQRT); + } else if(s == "square") { + t = Token::From(TokenType::UNARY_OP, Expr::Op::SQUARE); + } else if(s == "sin") { + t = Token::From(TokenType::UNARY_OP, Expr::Op::SIN); + } else if(s == "cos") { + t = Token::From(TokenType::UNARY_OP, Expr::Op::COS); + } else if(s == "asin") { + t = Token::From(TokenType::UNARY_OP, Expr::Op::ASIN); + } else if(s == "acos") { + t = Token::From(TokenType::UNARY_OP, Expr::Op::ACOS); + } else if(s == "pi") { + t = Token::From(TokenType::OPERAND, Expr::Op::CONSTANT); + t.expr->v = PI; + } else { + *error = "'" + s + "' is not a valid variable, function or constant"; + } + } else if(isdigit(c) || c == '.') { + return LexNumber(error); + } else if(ispunct(c)) { + ReadChar(); + if(c == '+') { + t = Token::From(TokenType::BINARY_OP, Expr::Op::PLUS); + } else if(c == '-') { + t = Token::From(TokenType::BINARY_OP, Expr::Op::MINUS); + } else if(c == '*') { + t = Token::From(TokenType::BINARY_OP, Expr::Op::TIMES); + } else if(c == '/') { + t = Token::From(TokenType::BINARY_OP, Expr::Op::DIV); + } else if(c == '(') { + t = Token::From(TokenType::PAREN_LEFT); + } else if(c == ')') { + t = Token::From(TokenType::PAREN_RIGHT); + } else { + *error = "'" + std::string(1, c) + "' is not a valid operator"; + } + } else if(c == '\0') { + t = Token::From(TokenType::END); + } else { + *error = "Unexpected character '" + std::string(1, c) + "'"; + } + + return t; +} + +ExprParser::Token ExprParser::PopOperand(std::string *error) { + Token t = Token::From(); + if(stack.empty() || stack.back().type != TokenType::OPERAND) { + *error = "Expected an operand"; + } else { + t = stack.back(); + stack.pop_back(); + } + return t; +} + +ExprParser::Token ExprParser::PopOperator(std::string *error) { + Token t = Token::From(); + if(stack.empty() || (stack.back().type != TokenType::UNARY_OP && + stack.back().type != TokenType::BINARY_OP)) { + *error = "Expected an operator"; + } else { + t = stack.back(); + stack.pop_back(); + } + return t; +} + +int ExprParser::Precedence(Token t) { + ssassert(t.type == TokenType::BINARY_OP || + t.type == TokenType::UNARY_OP || + t.type == TokenType::OPERAND, + "Unexpected token type"); + + if(t.type == TokenType::UNARY_OP) { + return 30; + } else if(t.expr->op == Expr::Op::TIMES || + t.expr->op == Expr::Op::DIV) { + return 20; + } else if(t.expr->op == Expr::Op::PLUS || + t.expr->op == Expr::Op::MINUS) { + return 10; + } else if(t.type == TokenType::OPERAND) { + return 0; + } else ssassert(false, "Unexpected operator"); +} + +bool ExprParser::Reduce(std::string *error) { + Token a = PopOperand(error); + if(a.IsError()) return false; + + Token op = PopOperator(error); + if(op.IsError()) return false; + + Token r = Token::From(TokenType::OPERAND); + switch(op.type) { + case TokenType::BINARY_OP: { + Token b = PopOperand(error); + if(b.IsError()) return false; + r.expr = b.expr->AnyOp(op.expr->op, a.expr); + break; + } + + case TokenType::UNARY_OP: { + Expr *e = a.expr; + switch(op.expr->op) { + case Expr::Op::NEGATE: e = e->Negate(); break; + case Expr::Op::SQRT: e = e->Sqrt(); break; + case Expr::Op::SQUARE: e = e->Times(e); break; + case Expr::Op::SIN: e = e->Times(Expr::From(PI/180))->Sin(); break; + case Expr::Op::COS: e = e->Times(Expr::From(PI/180))->Cos(); break; + case Expr::Op::ASIN: e = e->ASin()->Times(Expr::From(180/PI)); break; + case Expr::Op::ACOS: e = e->ACos()->Times(Expr::From(180/PI)); break; + default: ssassert(false, "Unexpected unary operator"); + } + r.expr = e; + break; + } + + default: ssassert(false, "Unexpected operator"); + } + stack.push_back(r); + + return true; +} + +bool ExprParser::Parse(std::string *error, size_t reduceUntil) { + while(true) { + Token t = Lex(error); + switch(t.type) { + case TokenType::ERROR: + return false; + + case TokenType::END: + case TokenType::PAREN_RIGHT: + while(stack.size() > 1 + reduceUntil) { + if(!Reduce(error)) return false; + } + + if(t.type == TokenType::PAREN_RIGHT) { + stack.push_back(t); + } + return true; + + case TokenType::PAREN_LEFT: { + // sub-expression + if(!Parse(error, /*reduceUntil=*/stack.size())) return false; + + if(stack.empty() || stack.back().type != TokenType::PAREN_RIGHT) { + *error = "Expected ')'"; + return false; + } + stack.pop_back(); + break; + } + + case TokenType::BINARY_OP: + if((stack.size() > reduceUntil && stack.back().type != TokenType::OPERAND) || + stack.size() == reduceUntil) { + if(t.expr->op == Expr::Op::MINUS) { + t.type = TokenType::UNARY_OP; + t.expr->op = Expr::Op::NEGATE; + stack.push_back(t); + break; + } + } + + while(stack.size() > 1 + reduceUntil && + Precedence(t) <= Precedence(stack[stack.size() - 2])) { + if(!Reduce(error)) return false; + } + + stack.push_back(t); + break; + + case TokenType::UNARY_OP: + case TokenType::OPERAND: + stack.push_back(t); + break; + } + } + + return true; +} + +Expr *ExprParser::Parse(const std::string &input, std::string *error) { + ExprParser parser; + parser.it = input.cbegin(); + parser.end = input.cend(); + if(!parser.Parse(error)) return NULL; + + Token r = parser.PopOperand(error); + if(r.IsError()) return NULL; + return r.expr; +} + +Expr *Expr::Parse(const std::string &input, std::string *error) { + return ExprParser::Parse(input, error); +} + +Expr *Expr::From(const std::string &input, bool popUpError) { + std::string error; + Expr *e = ExprParser::Parse(input, &error); + if(!e) { + dbp("Parse/lex error: %s", error.c_str()); + if(popUpError) { + Error("Not a valid number or expression: '%s'.\n%s.", + input.c_str(), error.c_str()); + } + } + return e; +} diff --git a/src/expr.h b/src/expr.h new file mode 100644 index 0000000..7109cf6 --- /dev/null +++ b/src/expr.h @@ -0,0 +1,140 @@ +//----------------------------------------------------------------------------- +// An expression in our symbolic algebra system, used to write, linearize, +// and solve our constraint equations. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#ifndef SOLVESPACE_EXPR_H +#define SOLVESPACE_EXPR_H + +class Expr { +public: + + enum class Op : uint32_t { + // A parameter, by the hParam handle + PARAM = 0, + // A parameter, by a pointer straight in to the param table (faster, + // if we know that the param table won't move around) + PARAM_PTR = 1, + + // Operands + CONSTANT = 20, + VARIABLE = 21, + + // Binary ops + PLUS = 100, + MINUS = 101, + TIMES = 102, + DIV = 103, + // Unary ops + NEGATE = 104, + SQRT = 105, + SQUARE = 106, + SIN = 107, + COS = 108, + ASIN = 109, + ACOS = 110, + }; + + Op op; + Expr *a; + union { + double v; + hParam parh; + Param *parp; + Expr *b; + }; + + Expr() = default; + Expr(double val) : op(Op::CONSTANT) { v = val; } + + static inline Expr *AllocExpr() + { return (Expr *)AllocTemporary(sizeof(Expr)); } + + static Expr *From(hParam p); + static Expr *From(double v); + + Expr *AnyOp(Op op, Expr *b); + inline Expr *Plus (Expr *b_) { return AnyOp(Op::PLUS, b_); } + inline Expr *Minus(Expr *b_) { return AnyOp(Op::MINUS, b_); } + inline Expr *Times(Expr *b_) { return AnyOp(Op::TIMES, b_); } + inline Expr *Div (Expr *b_) { return AnyOp(Op::DIV, b_); } + + inline Expr *Negate() { return AnyOp(Op::NEGATE, NULL); } + inline Expr *Sqrt () { return AnyOp(Op::SQRT, NULL); } + inline Expr *Square() { return AnyOp(Op::SQUARE, NULL); } + inline Expr *Sin () { return AnyOp(Op::SIN, NULL); } + inline Expr *Cos () { return AnyOp(Op::COS, NULL); } + inline Expr *ASin () { return AnyOp(Op::ASIN, NULL); } + inline Expr *ACos () { return AnyOp(Op::ACOS, NULL); } + + Expr *PartialWrt(hParam p) const; + double Eval() const; + uint64_t ParamsUsed() const; + bool DependsOn(hParam p) const; + static bool Tol(double a, double b); + Expr *FoldConstants(); + void Substitute(hParam oldh, hParam newh); + + static const hParam NO_PARAMS, MULTIPLE_PARAMS; + hParam ReferencedParams(ParamList *pl) const; + + void ParamsToPointers(); + + std::string Print() const; + + // number of child nodes: 0 (e.g. constant), 1 (sqrt), or 2 (+) + int Children() const; + // total number of nodes in the tree + int Nodes() const; + + // Make a simple copy + Expr *DeepCopy() const; + // Make a copy, with the parameters (usually referenced by hParam) + // resolved to pointers to the actual value. This speeds things up + // considerably. + Expr *DeepCopyWithParamsAsPointers(IdList *firstTry, + IdList *thenTry) const; + + static Expr *Parse(const std::string &input, std::string *error); + static Expr *From(const std::string &input, bool popUpError); +}; + +class ExprVector { +public: + Expr *x, *y, *z; + + static ExprVector From(Expr *x, Expr *y, Expr *z); + static ExprVector From(Vector vn); + static ExprVector From(hParam x, hParam y, hParam z); + static ExprVector From(double x, double y, double z); + + ExprVector Plus(ExprVector b) const; + ExprVector Minus(ExprVector b) const; + Expr *Dot(ExprVector b) const; + ExprVector Cross(ExprVector b) const; + ExprVector ScaledBy(Expr *s) const; + ExprVector WithMagnitude(Expr *s) const; + Expr *Magnitude() const; + + Vector Eval() const; +}; + +class ExprQuaternion { +public: + Expr *w, *vx, *vy, *vz; + + static ExprQuaternion From(Expr *w, Expr *vx, Expr *vy, Expr *vz); + static ExprQuaternion From(Quaternion qn); + static ExprQuaternion From(hParam w, hParam vx, hParam vy, hParam vz); + + ExprVector RotationU() const; + ExprVector RotationV() const; + ExprVector RotationN() const; + + ExprVector Rotate(ExprVector p) const; + ExprQuaternion Times(ExprQuaternion b) const; + + Expr *Magnitude() const; +}; +#endif diff --git a/src/file.cpp b/src/file.cpp new file mode 100644 index 0000000..f36e49b --- /dev/null +++ b/src/file.cpp @@ -0,0 +1,1007 @@ +//----------------------------------------------------------------------------- +// Routines to write and read our .slvs file format. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +#define VERSION_STRING "\261\262\263" "SolveSpaceREVa" + +static int StrStartsWith(const char *str, const char *start) { + return memcmp(str, start, strlen(start)) == 0; +} + +//----------------------------------------------------------------------------- +// Clear and free all the dynamic memory associated with our currently-loaded +// sketch. This does not leave the program in an acceptable state (with the +// references created, and so on), so anyone calling this must fix that later. +//----------------------------------------------------------------------------- +void SolveSpaceUI::ClearExisting() { + UndoClearStack(&redo); + UndoClearStack(&undo); + + for(hGroup hg : SK.groupOrder) { + Group *g = SK.GetGroup(hg); + g->Clear(); + } + + SK.constraint.Clear(); + SK.request.Clear(); + SK.group.Clear(); + SK.groupOrder.Clear(); + SK.style.Clear(); + + SK.entity.Clear(); + SK.param.Clear(); + images.clear(); +} + +hGroup SolveSpaceUI::CreateDefaultDrawingGroup() { + Group g = {}; + + // And an empty group, for the first stuff the user draws. + g.visible = true; + g.name = C_("group-name", "sketch-in-plane"); + g.type = Group::Type::DRAWING_WORKPLANE; + g.subtype = Group::Subtype::WORKPLANE_BY_POINT_ORTHO; + g.order = 1; + g.predef.q = Quaternion::From(1, 0, 0, 0); + hRequest hr = Request::HREQUEST_REFERENCE_XY; + g.predef.origin = hr.entity(1); + SK.group.AddAndAssignId(&g); + SK.GetGroup(g.h)->activeWorkplane = g.h.entity(0); + return g.h; +} + +void SolveSpaceUI::NewFile() { + ClearExisting(); + + // Our initial group, that contains the references. + Group g = {}; + g.visible = true; + g.name = C_("group-name", "#references"); + g.type = Group::Type::DRAWING_3D; + g.order = 0; + g.h = Group::HGROUP_REFERENCES; + SK.group.Add(&g); + + // Let's create three two-d coordinate systems, for the coordinate + // planes; these are our references, present in every sketch. + Request r = {}; + r.type = Request::Type::WORKPLANE; + r.group = Group::HGROUP_REFERENCES; + r.workplane = Entity::FREE_IN_3D; + + r.h = Request::HREQUEST_REFERENCE_XY; + SK.request.Add(&r); + + r.h = Request::HREQUEST_REFERENCE_YZ; + SK.request.Add(&r); + + r.h = Request::HREQUEST_REFERENCE_ZX; + SK.request.Add(&r); + + CreateDefaultDrawingGroup(); +} + +const SolveSpaceUI::SaveTable SolveSpaceUI::SAVED[] = { + { 'g', "Group.h.v", 'x', &(SS.sv.g.h.v) }, + { 'g', "Group.type", 'd', &(SS.sv.g.type) }, + { 'g', "Group.order", 'd', &(SS.sv.g.order) }, + { 'g', "Group.name", 'S', &(SS.sv.g.name) }, + { 'g', "Group.activeWorkplane.v", 'x', &(SS.sv.g.activeWorkplane.v) }, + { 'g', "Group.opA.v", 'x', &(SS.sv.g.opA.v) }, + { 'g', "Group.opB.v", 'x', &(SS.sv.g.opB.v) }, + { 'g', "Group.valA", 'f', &(SS.sv.g.valA) }, + { 'g', "Group.valB", 'f', &(SS.sv.g.valB) }, + { 'g', "Group.valC", 'f', &(SS.sv.g.valB) }, + { 'g', "Group.color", 'c', &(SS.sv.g.color) }, + { 'g', "Group.subtype", 'd', &(SS.sv.g.subtype) }, + { 'g', "Group.skipFirst", 'b', &(SS.sv.g.skipFirst) }, + { 'g', "Group.meshCombine", 'd', &(SS.sv.g.meshCombine) }, + { 'g', "Group.forceToMesh", 'd', &(SS.sv.g.forceToMesh) }, + { 'g', "Group.predef.q.w", 'f', &(SS.sv.g.predef.q.w) }, + { 'g', "Group.predef.q.vx", 'f', &(SS.sv.g.predef.q.vx) }, + { 'g', "Group.predef.q.vy", 'f', &(SS.sv.g.predef.q.vy) }, + { 'g', "Group.predef.q.vz", 'f', &(SS.sv.g.predef.q.vz) }, + { 'g', "Group.predef.origin.v", 'x', &(SS.sv.g.predef.origin.v) }, + { 'g', "Group.predef.entityB.v", 'x', &(SS.sv.g.predef.entityB.v) }, + { 'g', "Group.predef.entityC.v", 'x', &(SS.sv.g.predef.entityC.v) }, + { 'g', "Group.predef.swapUV", 'b', &(SS.sv.g.predef.swapUV) }, + { 'g', "Group.predef.negateU", 'b', &(SS.sv.g.predef.negateU) }, + { 'g', "Group.predef.negateV", 'b', &(SS.sv.g.predef.negateV) }, + { 'g', "Group.visible", 'b', &(SS.sv.g.visible) }, + { 'g', "Group.suppress", 'b', &(SS.sv.g.suppress) }, + { 'g', "Group.relaxConstraints", 'b', &(SS.sv.g.relaxConstraints) }, + { 'g', "Group.allowRedundant", 'b', &(SS.sv.g.allowRedundant) }, + { 'g', "Group.allDimsReference", 'b', &(SS.sv.g.allDimsReference) }, + { 'g', "Group.scale", 'f', &(SS.sv.g.scale) }, + { 'g', "Group.remap", 'M', &(SS.sv.g.remap) }, + { 'g', "Group.impFile", 'i', NULL }, + { 'g', "Group.impFileRel", 'P', &(SS.sv.g.linkFile) }, + + { 'p', "Param.h.v.", 'x', &(SS.sv.p.h.v) }, + { 'p', "Param.val", 'f', &(SS.sv.p.val) }, + + { 'r', "Request.h.v", 'x', &(SS.sv.r.h.v) }, + { 'r', "Request.type", 'd', &(SS.sv.r.type) }, + { 'r', "Request.extraPoints", 'd', &(SS.sv.r.extraPoints) }, + { 'r', "Request.workplane.v", 'x', &(SS.sv.r.workplane.v) }, + { 'r', "Request.group.v", 'x', &(SS.sv.r.group.v) }, + { 'r', "Request.construction", 'b', &(SS.sv.r.construction) }, + { 'r', "Request.style", 'x', &(SS.sv.r.style) }, + { 'r', "Request.str", 'S', &(SS.sv.r.str) }, + { 'r', "Request.font", 'S', &(SS.sv.r.font) }, + { 'r', "Request.file", 'P', &(SS.sv.r.file) }, + { 'r', "Request.aspectRatio", 'f', &(SS.sv.r.aspectRatio) }, + + { 'e', "Entity.h.v", 'x', &(SS.sv.e.h.v) }, + { 'e', "Entity.type", 'd', &(SS.sv.e.type) }, + { 'e', "Entity.construction", 'b', &(SS.sv.e.construction) }, + { 'e', "Entity.style", 'x', &(SS.sv.e.style) }, + { 'e', "Entity.str", 'S', &(SS.sv.e.str) }, + { 'e', "Entity.font", 'S', &(SS.sv.e.font) }, + { 'e', "Entity.file", 'P', &(SS.sv.e.file) }, + { 'e', "Entity.point[0].v", 'x', &(SS.sv.e.point[0].v) }, + { 'e', "Entity.point[1].v", 'x', &(SS.sv.e.point[1].v) }, + { 'e', "Entity.point[2].v", 'x', &(SS.sv.e.point[2].v) }, + { 'e', "Entity.point[3].v", 'x', &(SS.sv.e.point[3].v) }, + { 'e', "Entity.point[4].v", 'x', &(SS.sv.e.point[4].v) }, + { 'e', "Entity.point[5].v", 'x', &(SS.sv.e.point[5].v) }, + { 'e', "Entity.point[6].v", 'x', &(SS.sv.e.point[6].v) }, + { 'e', "Entity.point[7].v", 'x', &(SS.sv.e.point[7].v) }, + { 'e', "Entity.point[8].v", 'x', &(SS.sv.e.point[8].v) }, + { 'e', "Entity.point[9].v", 'x', &(SS.sv.e.point[9].v) }, + { 'e', "Entity.point[10].v", 'x', &(SS.sv.e.point[10].v) }, + { 'e', "Entity.point[11].v", 'x', &(SS.sv.e.point[11].v) }, + { 'e', "Entity.extraPoints", 'd', &(SS.sv.e.extraPoints) }, + { 'e', "Entity.normal.v", 'x', &(SS.sv.e.normal.v) }, + { 'e', "Entity.distance.v", 'x', &(SS.sv.e.distance.v) }, + { 'e', "Entity.workplane.v", 'x', &(SS.sv.e.workplane.v) }, + { 'e', "Entity.actPoint.x", 'f', &(SS.sv.e.actPoint.x) }, + { 'e', "Entity.actPoint.y", 'f', &(SS.sv.e.actPoint.y) }, + { 'e', "Entity.actPoint.z", 'f', &(SS.sv.e.actPoint.z) }, + { 'e', "Entity.actNormal.w", 'f', &(SS.sv.e.actNormal.w) }, + { 'e', "Entity.actNormal.vx", 'f', &(SS.sv.e.actNormal.vx) }, + { 'e', "Entity.actNormal.vy", 'f', &(SS.sv.e.actNormal.vy) }, + { 'e', "Entity.actNormal.vz", 'f', &(SS.sv.e.actNormal.vz) }, + { 'e', "Entity.actDistance", 'f', &(SS.sv.e.actDistance) }, + { 'e', "Entity.actVisible", 'b', &(SS.sv.e.actVisible), }, + + + { 'c', "Constraint.h.v", 'x', &(SS.sv.c.h.v) }, + { 'c', "Constraint.type", 'd', &(SS.sv.c.type) }, + { 'c', "Constraint.group.v", 'x', &(SS.sv.c.group.v) }, + { 'c', "Constraint.workplane.v", 'x', &(SS.sv.c.workplane.v) }, + { 'c', "Constraint.valA", 'f', &(SS.sv.c.valA) }, + { 'c', "Constraint.valP.v", 'x', &(SS.sv.c.valP.v) }, + { 'c', "Constraint.ptA.v", 'x', &(SS.sv.c.ptA.v) }, + { 'c', "Constraint.ptB.v", 'x', &(SS.sv.c.ptB.v) }, + { 'c', "Constraint.entityA.v", 'x', &(SS.sv.c.entityA.v) }, + { 'c', "Constraint.entityB.v", 'x', &(SS.sv.c.entityB.v) }, + { 'c', "Constraint.entityC.v", 'x', &(SS.sv.c.entityC.v) }, + { 'c', "Constraint.entityD.v", 'x', &(SS.sv.c.entityD.v) }, + { 'c', "Constraint.other", 'b', &(SS.sv.c.other) }, + { 'c', "Constraint.other2", 'b', &(SS.sv.c.other2) }, + { 'c', "Constraint.reference", 'b', &(SS.sv.c.reference) }, + { 'c', "Constraint.comment", 'S', &(SS.sv.c.comment) }, + { 'c', "Constraint.disp.offset.x", 'f', &(SS.sv.c.disp.offset.x) }, + { 'c', "Constraint.disp.offset.y", 'f', &(SS.sv.c.disp.offset.y) }, + { 'c', "Constraint.disp.offset.z", 'f', &(SS.sv.c.disp.offset.z) }, + { 'c', "Constraint.disp.style", 'x', &(SS.sv.c.disp.style) }, + + { 's', "Style.h.v", 'x', &(SS.sv.s.h.v) }, + { 's', "Style.name", 'S', &(SS.sv.s.name) }, + { 's', "Style.width", 'f', &(SS.sv.s.width) }, + { 's', "Style.widthAs", 'd', &(SS.sv.s.widthAs) }, + { 's', "Style.textHeight", 'f', &(SS.sv.s.textHeight) }, + { 's', "Style.textHeightAs", 'd', &(SS.sv.s.textHeightAs) }, + { 's', "Style.textAngle", 'f', &(SS.sv.s.textAngle) }, + { 's', "Style.textOrigin", 'x', &(SS.sv.s.textOrigin) }, + { 's', "Style.color", 'c', &(SS.sv.s.color) }, + { 's', "Style.fillColor", 'c', &(SS.sv.s.fillColor) }, + { 's', "Style.filled", 'b', &(SS.sv.s.filled) }, + { 's', "Style.visible", 'b', &(SS.sv.s.visible) }, + { 's', "Style.exportable", 'b', &(SS.sv.s.exportable) }, + { 's', "Style.stippleType", 'd', &(SS.sv.s.stippleType) }, + { 's', "Style.stippleScale", 'f', &(SS.sv.s.stippleScale) }, + + { 0, NULL, 0, NULL } +}; + +struct SAVEDptr { + EntityMap &M() { return *((EntityMap *)this); } + std::string &S() { return *((std::string *)this); } + Platform::Path &P() { return *((Platform::Path *)this); } + bool &b() { return *((bool *)this); } + RgbaColor &c() { return *((RgbaColor *)this); } + int &d() { return *((int *)this); } + double &f() { return *((double *)this); } + uint32_t &x() { return *((uint32_t *)this); } +}; + +void SolveSpaceUI::SaveUsingTable(const Platform::Path &filename, int type) { + int i; + for(i = 0; SAVED[i].type != 0; i++) { + if(SAVED[i].type != type) continue; + + int fmt = SAVED[i].fmt; + SAVEDptr *p = (SAVEDptr *)SAVED[i].ptr; + // Any items that aren't specified are assumed to be zero + if(fmt == 'S' && p->S().empty()) continue; + if(fmt == 'P' && p->P().IsEmpty()) continue; + if(fmt == 'd' && p->d() == 0) continue; + if(fmt == 'f' && EXACT(p->f() == 0.0)) continue; + if(fmt == 'x' && p->x() == 0) continue; + if(fmt == 'i') continue; + + fprintf(fh, "%s=", SAVED[i].desc); + switch(fmt) { + case 'S': fprintf(fh, "%s", p->S().c_str()); break; + case 'b': fprintf(fh, "%d", p->b() ? 1 : 0); break; + case 'c': fprintf(fh, "%08x", p->c().ToPackedInt()); break; + case 'd': fprintf(fh, "%d", p->d()); break; + case 'f': fprintf(fh, "%.20f", p->f()); break; + case 'x': fprintf(fh, "%08x", p->x()); break; + + case 'P': { + if(!p->P().IsEmpty()) { + Platform::Path relativePath = p->P().RelativeTo(filename.Parent()); + ssassert(!relativePath.IsEmpty(), "Cannot relativize path"); + fprintf(fh, "%s", relativePath.ToPortable().c_str()); + } + break; + } + + case 'M': { + fprintf(fh, "{\n"); + // Sort the mapping, since EntityMap is not deterministic. + std::vector> sorted(p->M().begin(), p->M().end()); + std::sort(sorted.begin(), sorted.end(), + [](std::pair &a, std::pair &b) { + return a.second.v < b.second.v; + }); + for(auto it : sorted) { + fprintf(fh, " %d %08x %d\n", + it.second.v, it.first.input.v, it.first.copyNumber); + } + fprintf(fh, "}"); + break; + } + + case 'i': break; + + default: ssassert(false, "Unexpected value format"); + } + fprintf(fh, "\n"); + } +} + +bool SolveSpaceUI::SaveToFile(const Platform::Path &filename) { + // Make sure all the entities are regenerated up to date, since they will be exported. + SS.ScheduleShowTW(); + SS.GenerateAll(SolveSpaceUI::Generate::ALL); + + for(Group &g : SK.group) { + if(g.type != Group::Type::LINKED) continue; + + if(g.linkFile.RelativeTo(filename).IsEmpty()) { + Error("This sketch links the sketch '%s'; it can only be saved " + "on the same volume.", g.linkFile.raw.c_str()); + return false; + } + } + + fh = OpenFile(filename, "wb"); + if(!fh) { + Error("Couldn't write to file '%s'", filename.raw.c_str()); + return false; + } + + fprintf(fh, "%s\n\n\n", VERSION_STRING); + + int i, j; + for(auto &g : SK.group) { + sv.g = g; + SaveUsingTable(filename, 'g'); + fprintf(fh, "AddGroup\n\n"); + } + + for(auto &p : SK.param) { + sv.p = p; + SaveUsingTable(filename, 'p'); + fprintf(fh, "AddParam\n\n"); + } + + for(auto &r : SK.request) { + sv.r = r; + SaveUsingTable(filename, 'r'); + fprintf(fh, "AddRequest\n\n"); + } + + for(auto &e : SK.entity) { + e.CalculateNumerical(/*forExport=*/true); + sv.e = e; + SaveUsingTable(filename, 'e'); + fprintf(fh, "AddEntity\n\n"); + } + + for(auto &c : SK.constraint) { + sv.c = c; + SaveUsingTable(filename, 'c'); + fprintf(fh, "AddConstraint\n\n"); + } + + for(auto &s : SK.style) { + sv.s = s; + if(sv.s.h.v >= Style::FIRST_CUSTOM) { + SaveUsingTable(filename, 's'); + fprintf(fh, "AddStyle\n\n"); + } + } + + // A group will have either a mesh or a shell, but not both; but the code + // to print either of those just does nothing if the mesh/shell is empty. + + Group *g = SK.GetGroup(*SK.groupOrder.Last()); + SMesh *m = &g->runningMesh; + for(i = 0; i < m->l.n; i++) { + STriangle *tr = &(m->l[i]); + fprintf(fh, "Triangle %08x %08x " + "%.20f %.20f %.20f %.20f %.20f %.20f %.20f %.20f %.20f\n", + tr->meta.face, tr->meta.color.ToPackedInt(), + CO(tr->a), CO(tr->b), CO(tr->c)); + } + + SShell *s = &g->runningShell; + SSurface *srf; + for(srf = s->surface.First(); srf; srf = s->surface.NextAfter(srf)) { + fprintf(fh, "Surface %08x %08x %08x %d %d\n", + srf->h.v, srf->color.ToPackedInt(), srf->face, srf->degm, srf->degn); + for(i = 0; i <= srf->degm; i++) { + for(j = 0; j <= srf->degn; j++) { + fprintf(fh, "SCtrl %d %d %.20f %.20f %.20f Weight %20.20f\n", + i, j, CO(srf->ctrl[i][j]), srf->weight[i][j]); + } + } + + STrimBy *stb; + for(stb = srf->trim.First(); stb; stb = srf->trim.NextAfter(stb)) { + fprintf(fh, "TrimBy %08x %d %.20f %.20f %.20f %.20f %.20f %.20f\n", + stb->curve.v, stb->backwards ? 1 : 0, + CO(stb->start), CO(stb->finish)); + } + + fprintf(fh, "AddSurface\n"); + } + SCurve *sc; + for(sc = s->curve.First(); sc; sc = s->curve.NextAfter(sc)) { + fprintf(fh, "Curve %08x %d %d %08x %08x\n", + sc->h.v, + sc->isExact ? 1 : 0, sc->exact.deg, + sc->surfA.v, sc->surfB.v); + + if(sc->isExact) { + for(i = 0; i <= sc->exact.deg; i++) { + fprintf(fh, "CCtrl %d %.20f %.20f %.20f Weight %.20f\n", + i, CO(sc->exact.ctrl[i]), sc->exact.weight[i]); + } + } + SCurvePt *scpt; + for(scpt = sc->pts.First(); scpt; scpt = sc->pts.NextAfter(scpt)) { + fprintf(fh, "CurvePt %d %.20f %.20f %.20f\n", + scpt->vertex ? 1 : 0, CO(scpt->p)); + } + + fprintf(fh, "AddCurve\n"); + } + + fclose(fh); + + return true; +} + +void SolveSpaceUI::LoadUsingTable(const Platform::Path &filename, char *key, char *val) { + int i; + for(i = 0; SAVED[i].type != 0; i++) { + if(strcmp(SAVED[i].desc, key)==0) { + SAVEDptr *p = (SAVEDptr *)SAVED[i].ptr; + unsigned int u = 0; + switch(SAVED[i].fmt) { + case 'S': p->S() = val; break; + case 'b': p->b() = (atoi(val) != 0); break; + case 'd': p->d() = atoi(val); break; + case 'f': p->f() = atof(val); break; + case 'x': sscanf(val, "%x", &u); p->x()= u; break; + + case 'P': { + Platform::Path path = Platform::Path::FromPortable(val); + if(!path.IsEmpty()) { + p->P() = filename.Parent().Join(path).Expand(); + } + break; + } + + case 'c': + sscanf(val, "%x", &u); + p->c() = RgbaColor::FromPackedInt(u); + break; + + case 'M': { + p->M().clear(); + for(;;) { + EntityKey ek; + EntityId ei; + char line2[1024]; + if (fgets(line2, (int)sizeof(line2), fh) == NULL) + break; + if(sscanf(line2, "%d %x %d", &(ei.v), &(ek.input.v), + &(ek.copyNumber)) == 3) { + if(ei.v == Entity::NO_ENTITY.v) { + // Commit bd84bc1a mistakenly introduced code that would remap + // some entities to NO_ENTITY. This was fixed in commit bd84bc1a, + // but files created meanwhile are corrupt, and can cause crashes. + // + // To fix this, we skip any such remaps when loading; they will be + // recreated on the next regeneration. Any resulting orphans will + // be pruned in the usual way, recovering to a well-defined state. + continue; + } + p->M().insert({ ek, ei }); + } else { + break; + } + } + break; + } + + case 'i': break; + + default: ssassert(false, "Unexpected value format"); + } + break; + } + } + if(SAVED[i].type == 0) { + fileLoadError = true; + } +} + +bool SolveSpaceUI::LoadFromFile(const Platform::Path &filename, bool canCancel) { + allConsistent = false; + fileLoadError = false; + + fh = OpenFile(filename, "rb"); + if(!fh) { + Error("Couldn't read from file '%s'", filename.raw.c_str()); + return false; + } + + ClearExisting(); + + sv = {}; + sv.g.scale = 1; // default is 1, not 0; so legacy files need this + Style::FillDefaultStyle(&sv.s); + + char line[1024]; + while(fgets(line, (int)sizeof(line), fh)) { + char *s = strchr(line, '\n'); + if(s) *s = '\0'; + // We should never get files with \r characters in them, but mailers + // will sometimes mangle attachments. + s = strchr(line, '\r'); + if(s) *s = '\0'; + + if(*line == '\0') continue; + + char *e = strchr(line, '='); + if(e) { + *e = '\0'; + char *key = line, *val = e+1; + LoadUsingTable(filename, key, val); + } else if(strcmp(line, "AddGroup")==0) { + // legacy files have a spurious dependency between linked groups + // and their parent groups, remove + if(sv.g.type == Group::Type::LINKED) + sv.g.opA.v = 0; + + SK.group.Add(&(sv.g)); + sv.g = {}; + sv.g.scale = 1; // default is 1, not 0; so legacy files need this + } else if(strcmp(line, "AddParam")==0) { + // params are regenerated, but we want to preload the values + // for initial guesses + SK.param.Add(&(sv.p)); + sv.p = {}; + } else if(strcmp(line, "AddEntity")==0) { + // entities are regenerated + } else if(strcmp(line, "AddRequest")==0) { + SK.request.Add(&(sv.r)); + sv.r = {}; + } else if(strcmp(line, "AddConstraint")==0) { + SK.constraint.Add(&(sv.c)); + sv.c = {}; + } else if(strcmp(line, "AddStyle")==0) { + SK.style.Add(&(sv.s)); + sv.s = {}; + Style::FillDefaultStyle(&sv.s); + } else if(strcmp(line, VERSION_STRING)==0) { + // do nothing, version string + } else if(StrStartsWith(line, "Triangle ") || + StrStartsWith(line, "Surface ") || + StrStartsWith(line, "SCtrl ") || + StrStartsWith(line, "TrimBy ") || + StrStartsWith(line, "Curve ") || + StrStartsWith(line, "CCtrl ") || + StrStartsWith(line, "CurvePt ") || + strcmp(line, "AddSurface")==0 || + strcmp(line, "AddCurve")==0) + { + // ignore the mesh or shell, since we regenerate that + } else { + fileLoadError = true; + } + } + + fclose(fh); + + if(fileLoadError) { + Error(_("Unrecognized data in file. This file may be corrupt, or " + "from a newer version of the program.")); + // At least leave the program in a non-crashing state. + if(SK.group.IsEmpty()) { + NewFile(); + } + } + if(!ReloadAllLinked(filename, canCancel)) { + return false; + } + UpgradeLegacyData(); + + return true; +} + +void SolveSpaceUI::UpgradeLegacyData() { + for(Request &r : SK.request) { + switch(r.type) { + // TTF text requests saved in versions prior to 3.0 only have two + // reference points (origin and origin plus v); version 3.0 adds two + // more points, and if we don't do anything, then they will appear + // at workplane origin, and the solver will mess up the sketch if + // it is not fully constrained. + case Request::Type::TTF_TEXT: { + IdList entity = {}; + IdList param = {}; + r.Generate(&entity, ¶m); + + // If we didn't load all of the entities and params that this + // request would generate, then add them now, so that we can + // force them to their appropriate positions. + for(Param &p : param) { + if(SK.param.FindByIdNoOops(p.h) != NULL) continue; + SK.param.Add(&p); + } + bool allPointsExist = true; + for(Entity &e : entity) { + if(SK.entity.FindByIdNoOops(e.h) != NULL) continue; + SK.entity.Add(&e); + allPointsExist = false; + } + + if(!allPointsExist) { + Entity *text = entity.FindById(r.h.entity(0)); + Entity *b = entity.FindById(text->point[2]); + Entity *c = entity.FindById(text->point[3]); + ExprVector bex, cex; + text->RectGetPointsExprs(&bex, &cex); + b->PointForceParamTo(bex.Eval()); + c->PointForceParamTo(cex.Eval()); + } + entity.Clear(); + param.Clear(); + break; + } + + default: + break; + } + } + + // Constraints saved in versions prior to 3.0 never had any params; + // version 3.0 introduced params to constraints to avoid the hairy ball problem, + // so force them where they belong. + IdList oldParam = {}; + SK.param.DeepCopyInto(&oldParam); + SS.GenerateAll(SolveSpaceUI::Generate::REGEN); + + auto AllParamsExistFor = [&](Constraint &c) { + IdList param = {}; + c.Generate(¶m); + bool allParamsExist = true; + for(Param &p : param) { + if(oldParam.FindByIdNoOops(p.h) != NULL) continue; + allParamsExist = false; + break; + } + param.Clear(); + return allParamsExist; + }; + + for(Constraint &c : SK.constraint) { + switch(c.type) { + case Constraint::Type::PT_ON_LINE: { + if(AllParamsExistFor(c)) continue; + + EntityBase *eln = SK.GetEntity(c.entityA); + EntityBase *ea = SK.GetEntity(eln->point[0]); + EntityBase *eb = SK.GetEntity(eln->point[1]); + EntityBase *ep = SK.GetEntity(c.ptA); + + ExprVector exp = ep->PointGetExprsInWorkplane(c.workplane); + ExprVector exa = ea->PointGetExprsInWorkplane(c.workplane); + ExprVector exb = eb->PointGetExprsInWorkplane(c.workplane); + ExprVector exba = exb.Minus(exa); + Param *p = SK.GetParam(c.h.param(0)); + p->val = exba.Dot(exp.Minus(exa))->Eval() / exba.Dot(exba)->Eval(); + break; + } + + case Constraint::Type::CUBIC_LINE_TANGENT: { + if(AllParamsExistFor(c)) continue; + + EntityBase *cubic = SK.GetEntity(c.entityA); + EntityBase *line = SK.GetEntity(c.entityB); + + ExprVector a; + if(c.other) { + a = cubic->CubicGetFinishTangentExprs(); + } else { + a = cubic->CubicGetStartTangentExprs(); + } + + ExprVector b = line->VectorGetExprs(); + + Param *param = SK.GetParam(c.h.param(0)); + param->val = a.Dot(b)->Eval() / b.Dot(b)->Eval(); + break; + } + + case Constraint::Type::SAME_ORIENTATION: { + if(AllParamsExistFor(c)) continue; + + EntityBase *an = SK.GetEntity(c.entityA); + EntityBase *bn = SK.GetEntity(c.entityB); + + ExprVector a = an->NormalExprsN(); + ExprVector b = bn->NormalExprsN(); + + Param *param = SK.GetParam(c.h.param(0)); + param->val = a.Dot(b)->Eval() / b.Dot(b)->Eval(); + break; + } + + case Constraint::Type::PARALLEL: { + if(AllParamsExistFor(c)) continue; + + EntityBase *ea = SK.GetEntity(c.entityA), + *eb = SK.GetEntity(c.entityB); + ExprVector a = ea->VectorGetExprsInWorkplane(c.workplane); + ExprVector b = eb->VectorGetExprsInWorkplane(c.workplane); + + Param *param = SK.GetParam(c.h.param(0)); + param->val = a.Dot(b)->Eval() / b.Dot(b)->Eval(); + break; + } + + default: + break; + } + } + oldParam.Clear(); +} + +bool SolveSpaceUI::LoadEntitiesFromFile(const Platform::Path &filename, EntityList *le, + SMesh *m, SShell *sh) +{ + if(strcmp(filename.Extension().c_str(), "emn")==0) { + return LinkIDF(filename, le, m, sh); + } else { + return LoadEntitiesFromSlvs(filename, le, m, sh); + } +} + +bool SolveSpaceUI::LoadEntitiesFromSlvs(const Platform::Path &filename, EntityList *le, + SMesh *m, SShell *sh) +{ + SSurface srf = {}; + SCurve crv = {}; + + fh = OpenFile(filename, "rb"); + if(!fh) return false; + + le->Clear(); + sv = {}; + + char line[1024]; + while(fgets(line, (int)sizeof(line), fh)) { + char *s = strchr(line, '\n'); + if(s) *s = '\0'; + // We should never get files with \r characters in them, but mailers + // will sometimes mangle attachments. + s = strchr(line, '\r'); + if(s) *s = '\0'; + + if(*line == '\0') continue; + + char *e = strchr(line, '='); + if(e) { + *e = '\0'; + char *key = line, *val = e+1; + LoadUsingTable(filename, key, val); + } else if(strcmp(line, "AddGroup")==0) { + // These get allocated whether we want them or not. + sv.g.remap.clear(); + } else if(strcmp(line, "AddParam")==0) { + + } else if(strcmp(line, "AddEntity")==0) { + le->Add(&(sv.e)); + sv.e = {}; + } else if(strcmp(line, "AddRequest")==0) { + + } else if(strcmp(line, "AddConstraint")==0) { + + } else if(strcmp(line, "AddStyle")==0) { + // Linked file contains a style that we don't have yet, + // so import it. + if (SK.style.FindByIdNoOops(sv.s.h) == nullptr) { + SK.style.Add(&(sv.s)); + } + sv.s = {}; + Style::FillDefaultStyle(&sv.s); + } else if(strcmp(line, VERSION_STRING)==0) { + + } else if(StrStartsWith(line, "Triangle ")) { + STriangle tr = {}; + unsigned int rgba = 0; + if(sscanf(line, "Triangle %x %x " + "%lf %lf %lf %lf %lf %lf %lf %lf %lf", + &(tr.meta.face), &rgba, + &(tr.a.x), &(tr.a.y), &(tr.a.z), + &(tr.b.x), &(tr.b.y), &(tr.b.z), + &(tr.c.x), &(tr.c.y), &(tr.c.z)) != 11) { + ssassert(false, "Unexpected Triangle format"); + } + tr.meta.color = RgbaColor::FromPackedInt((uint32_t)rgba); + m->AddTriangle(&tr); + } else if(StrStartsWith(line, "Surface ")) { + unsigned int rgba = 0; + if(sscanf(line, "Surface %x %x %x %d %d", + &(srf.h.v), &rgba, &(srf.face), + &(srf.degm), &(srf.degn)) != 5) { + ssassert(false, "Unexpected Surface format"); + } + srf.color = RgbaColor::FromPackedInt((uint32_t)rgba); + } else if(StrStartsWith(line, "SCtrl ")) { + int i, j; + Vector c; + double w; + if(sscanf(line, "SCtrl %d %d %lf %lf %lf Weight %lf", + &i, &j, &(c.x), &(c.y), &(c.z), &w) != 6) + { + ssassert(false, "Unexpected SCtrl format"); + } + srf.ctrl[i][j] = c; + srf.weight[i][j] = w; + } else if(StrStartsWith(line, "TrimBy ")) { + STrimBy stb = {}; + int backwards; + if(sscanf(line, "TrimBy %x %d %lf %lf %lf %lf %lf %lf", + &(stb.curve.v), &backwards, + &(stb.start.x), &(stb.start.y), &(stb.start.z), + &(stb.finish.x), &(stb.finish.y), &(stb.finish.z)) != 8) + { + ssassert(false, "Unexpected TrimBy format"); + } + stb.backwards = (backwards != 0); + srf.trim.Add(&stb); + } else if(strcmp(line, "AddSurface")==0) { + sh->surface.Add(&srf); + srf = {}; + } else if(StrStartsWith(line, "Curve ")) { + int isExact; + if(sscanf(line, "Curve %x %d %d %x %x", + &(crv.h.v), + &(isExact), + &(crv.exact.deg), + &(crv.surfA.v), &(crv.surfB.v)) != 5) + { + ssassert(false, "Unexpected Curve format"); + } + crv.isExact = (isExact != 0); + } else if(StrStartsWith(line, "CCtrl ")) { + int i; + Vector c; + double w; + if(sscanf(line, "CCtrl %d %lf %lf %lf Weight %lf", + &i, &(c.x), &(c.y), &(c.z), &w) != 5) + { + ssassert(false, "Unexpected CCtrl format"); + } + crv.exact.ctrl[i] = c; + crv.exact.weight[i] = w; + } else if(StrStartsWith(line, "CurvePt ")) { + SCurvePt scpt; + int vertex; + if(sscanf(line, "CurvePt %d %lf %lf %lf", + &vertex, + &(scpt.p.x), &(scpt.p.y), &(scpt.p.z)) != 4) + { + ssassert(false, "Unexpected CurvePt format"); + } + scpt.vertex = (vertex != 0); + crv.pts.Add(&scpt); + } else if(strcmp(line, "AddCurve")==0) { + sh->curve.Add(&crv); + crv = {}; + } else ssassert(false, "Unexpected operation"); + } + + fclose(fh); + return true; +} + +static Platform::MessageDialog::Response LocateImportedFile(const Platform::Path &filename, + bool canCancel) { + Platform::MessageDialogRef dialog = CreateMessageDialog(SS.GW.window); + + using Platform::MessageDialog; + dialog->SetType(MessageDialog::Type::QUESTION); + dialog->SetTitle(C_("title", "Missing File")); + dialog->SetMessage(ssprintf(C_("dialog", "The linked file “%s” is not present."), + filename.raw.c_str())); + dialog->SetDescription(C_("dialog", "Do you want to locate it manually?\n\n" + "If you decline, any geometry that depends on " + "the missing file will be permanently removed.")); + dialog->AddButton(C_("button", "&Yes"), MessageDialog::Response::YES, + /*isDefault=*/true); + dialog->AddButton(C_("button", "&No"), MessageDialog::Response::NO); + if(canCancel) { + dialog->AddButton(C_("button", "&Cancel"), MessageDialog::Response::CANCEL); + } + + // FIXME(async): asyncify this call + return dialog->RunModal(); +} + +bool SolveSpaceUI::ReloadAllLinked(const Platform::Path &saveFile, bool canCancel) { + Platform::SettingsRef settings = Platform::GetSettings(); + + std::map linkMap; + + allConsistent = false; + + for(Group &g : SK.group) { + if(g.type != Group::Type::LINKED) continue; + + g.impEntity.Clear(); + g.impMesh.Clear(); + g.impShell.Clear(); + + // If we prompted for this specific file before, don't ask again. + if(linkMap.count(g.linkFile)) { + g.linkFile = linkMap[g.linkFile]; + } + +try_again: + if(LoadEntitiesFromFile(g.linkFile, &g.impEntity, &g.impMesh, &g.impShell)) { + // We loaded the data, good. Now import its dependencies as well. + for(Entity &e : g.impEntity) { + if(e.type != Entity::Type::IMAGE) continue; + if(!ReloadLinkedImage(g.linkFile, &e.file, canCancel)) { + return false; + } + } + } else if(linkMap.count(g.linkFile) == 0) { + dbp("Missing file for group: %s", g.name.c_str()); + // The file was moved; prompt the user for its new location. + const auto linkFileRelative = g.linkFile.RelativeTo(saveFile); + switch(LocateImportedFile(linkFileRelative, canCancel)) { + case Platform::MessageDialog::Response::YES: { + Platform::FileDialogRef dialog = Platform::CreateOpenFileDialog(SS.GW.window); + dialog->AddFilters(Platform::SolveSpaceModelFileFilters); + dialog->ThawChoices(settings, "LinkSketch"); + dialog->SuggestFilename(linkFileRelative); + if(dialog->RunModal()) { + dialog->FreezeChoices(settings, "LinkSketch"); + linkMap[g.linkFile] = dialog->GetFilename(); + g.linkFile = dialog->GetFilename(); + goto try_again; + } else { + if(canCancel) return false; + break; + } + } + + case Platform::MessageDialog::Response::NO: + linkMap[g.linkFile].Clear(); + // Geometry will be pruned by GenerateAll(). + break; + + case Platform::MessageDialog::Response::CANCEL: + return false; + + default: + ssassert(false, "Unexpected dialog response"); + } + } else { + // User was already asked to and refused to locate a missing linked file. + } + } + + for(Request &r : SK.request) { + if(r.type != Request::Type::IMAGE) continue; + + if(!ReloadLinkedImage(saveFile, &r.file, canCancel)) { + return false; + } + } + + return true; +} + +bool SolveSpaceUI::ReloadLinkedImage(const Platform::Path &saveFile, + Platform::Path *filename, bool canCancel) { + Platform::SettingsRef settings = Platform::GetSettings(); + + std::shared_ptr pixmap; + bool promptOpenFile = false; + if(filename->IsEmpty()) { + // We're prompting the user for a new image. + promptOpenFile = true; + } else { + auto image = SS.images.find(*filename); + if(image != SS.images.end()) return true; + + pixmap = Pixmap::ReadPng(*filename); + if(pixmap == NULL) { + // The file was moved; prompt the user for its new location. + switch(LocateImportedFile(filename->RelativeTo(saveFile), canCancel)) { + case Platform::MessageDialog::Response::YES: + promptOpenFile = true; + break; + + case Platform::MessageDialog::Response::NO: + // We don't know where the file is, record it as absent. + break; + + case Platform::MessageDialog::Response::CANCEL: + return false; + + default: + ssassert(false, "Unexpected dialog response"); + } + } + } + + if(promptOpenFile) { + Platform::FileDialogRef dialog = Platform::CreateOpenFileDialog(SS.GW.window); + dialog->AddFilters(Platform::RasterFileFilters); + dialog->ThawChoices(settings, "LinkImage"); + dialog->SuggestFilename(filename->RelativeTo(saveFile)); + if(dialog->RunModal()) { + dialog->FreezeChoices(settings, "LinkImage"); + *filename = dialog->GetFilename(); + pixmap = Pixmap::ReadPng(*filename); + if(pixmap == NULL) { + Error("The image '%s' is corrupted.", filename->raw.c_str()); + } + // We know where the file is now, good. + } else if(canCancel) { + return false; + } + } + + // We loaded the data, good. + SS.images[*filename] = pixmap; + return true; +} diff --git a/src/generate.cpp b/src/generate.cpp new file mode 100644 index 0000000..fdda994 --- /dev/null +++ b/src/generate.cpp @@ -0,0 +1,568 @@ +//----------------------------------------------------------------------------- +// Generate our model based on its parametric description, by solving each +// sketch, generating surfaces from the resulting entities, performing any +// requested surface operations (e.g. Booleans) with our model so far, and +// then repeating this process for each subsequent group. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +void SolveSpaceUI::MarkGroupDirtyByEntity(hEntity he) { + Entity *e = SK.GetEntity(he); + MarkGroupDirty(e->group); +} + +void SolveSpaceUI::MarkGroupDirty(hGroup hg, bool onlyThis) { + bool go = false; + for(auto const &gh : SK.groupOrder) { + Group *g = SK.GetGroup(gh); + if(g->h == hg) { + go = true; + } + if(go) { + g->clean = false; + if(onlyThis) break; + } + } + unsaved = true; + ScheduleGenerateAll(); +} + +bool SolveSpaceUI::PruneOrphans() { + + auto r = std::find_if(SK.request.begin(), SK.request.end(), + [&](Request &r) { return !GroupExists(r.group); }); + if(r != SK.request.end()) { + (deleted.requests)++; + SK.request.RemoveById(r->h); + return true; + } + + auto c = std::find_if(SK.constraint.begin(), SK.constraint.end(), + [&](Constraint &c) { return !GroupExists(c.group); }); + if(c != SK.constraint.end()) { + (deleted.constraints)++; + (deleted.nonTrivialConstraints)++; + SK.constraint.RemoveById(c->h); + return true; + } + return false; +} + +bool SolveSpaceUI::GroupsInOrder(hGroup before, hGroup after) { + if(before.v == 0) return true; + if(after.v == 0) return true; + if(!GroupExists(before)) return false; + if(!GroupExists(after)) return false; + int beforep = SK.GetGroup(before)->order; + int afterp = SK.GetGroup(after)->order; + if(beforep >= afterp) return false; + return true; +} + +bool SolveSpaceUI::GroupExists(hGroup hg) { + // A nonexistent group is not acceptable + return SK.group.FindByIdNoOops(hg) ? true : false; +} +bool SolveSpaceUI::EntityExists(hEntity he) { + // A nonexstient entity is acceptable, though, usually just means it + // doesn't apply. + if(he == Entity::NO_ENTITY) return true; + return SK.entity.FindByIdNoOops(he) ? true : false; +} + +bool SolveSpaceUI::PruneGroups(hGroup hg) { + Group *g = SK.GetGroup(hg); + if(GroupsInOrder(g->opA, hg) && + EntityExists(g->predef.origin) && + EntityExists(g->predef.entityB) && + EntityExists(g->predef.entityC)) + { + return false; + } + (deleted.groups)++; + SK.group.RemoveById(g->h); + return true; +} + +bool SolveSpaceUI::PruneRequests(hGroup hg) { + auto e = std::find_if(SK.entity.begin(), SK.entity.end(), + [&](Entity &e) { return e.group == hg && !EntityExists(e.workplane); }); + if(e != SK.entity.end()) { + (deleted.requests)++; + SK.entity.RemoveById(e->h); + return true; + } + return false; +} + +bool SolveSpaceUI::PruneConstraints(hGroup hg) { + auto c = std::find_if(SK.constraint.begin(), SK.constraint.end(), [&](Constraint &c) { + if(c.group != hg) + return false; + + if(EntityExists(c.workplane) && + EntityExists(c.ptA) && + EntityExists(c.ptB) && + EntityExists(c.entityA) && + EntityExists(c.entityB) && + EntityExists(c.entityC) && + EntityExists(c.entityD)) { + return false; + } + return true; + }); + + if(c != SK.constraint.end()) { + (deleted.constraints)++; + if(c->type != Constraint::Type::POINTS_COINCIDENT && + c->type != Constraint::Type::HORIZONTAL && + c->type != Constraint::Type::VERTICAL) { + (deleted.nonTrivialConstraints)++; + } + + SK.constraint.RemoveById(c->h); + return true; + } + return false; +} + +void SolveSpaceUI::GenerateAll(Generate type, bool andFindFree, bool genForBBox) { + int first = 0, last = 0, i; + + uint64_t startMillis = GetMilliseconds(), + endMillis; + + SK.groupOrder.Clear(); + for(auto &g : SK.group) { SK.groupOrder.Add(&g.h); } + std::sort(SK.groupOrder.begin(), SK.groupOrder.end(), + [](const hGroup &ha, const hGroup &hb) { + return SK.GetGroup(ha)->order < SK.GetGroup(hb)->order; + }); + + switch(type) { + case Generate::DIRTY: { + first = INT_MAX; + last = 0; + + // Start from the first dirty group, and solve until the active group, + // since all groups after the active group are hidden. + // Not using range-for because we're tracking the indices. + for(i = 0; i < SK.groupOrder.n; i++) { + Group *g = SK.GetGroup(SK.groupOrder[i]); + if((!g->clean) || !g->IsSolvedOkay()) { + first = min(first, i); + } + if(g->h == SS.GW.activeGroup) { + last = i; + } + } + if(first == INT_MAX || last == 0) { + // All clean; so just regenerate the entities, and don't solve anything. + first = -1; + last = -1; + } else { + SS.nakedEdges.Clear(); + } + break; + } + + case Generate::ALL: + first = 0; + last = INT_MAX; + break; + + case Generate::REGEN: + first = -1; + last = -1; + break; + + case Generate::UNTIL_ACTIVE: { + for(i = 0; i < SK.groupOrder.n; i++) { + if(SK.groupOrder[i] == SS.GW.activeGroup) + break; + } + + first = 0; + last = i; + break; + } + } + + // If we're generating entities for display, first we need to find + // the bounding box to turn relative chord tolerance to absolute. + if(!SS.exportMode && !genForBBox) { + GenerateAll(type, andFindFree, /*genForBBox=*/true); + BBox box = SK.CalculateEntityBBox(/*includeInvisibles=*/true); + Vector size = box.maxp.Minus(box.minp); + double maxSize = std::max({ size.x, size.y, size.z }); + chordTolCalculated = maxSize * chordTol / 100.0; + } + + // Remove any requests or constraints that refer to a nonexistent + // group; can check those immediately, since we know what the list + // of groups should be. + while(PruneOrphans()) + ; + + // Don't lose our numerical guesses when we regenerate. + IdList prev = {}; + SK.param.MoveSelfInto(&prev); + SK.param.ReserveMore(prev.n); + int oldEntityCount = SK.entity.n; + SK.entity.Clear(); + SK.entity.ReserveMore(oldEntityCount); + + // Not using range-for because we're using the index inside the loop. + for(i = 0; i < SK.groupOrder.n; i++) { + hGroup hg = SK.groupOrder[i]; + + // The group may depend on entities or other groups, to define its + // workplane geometry or for its operands. Those must already exist + // in a previous group, so check them before generating. + if(PruneGroups(hg)) + goto pruned; + + for(auto &req : SK.request) { + Request *r = &req; + if(r->group != hg) continue; + + r->Generate(&(SK.entity), &(SK.param)); + } + for(auto &con : SK.constraint) { + Constraint *c = &con; + if(c->group != hg) continue; + + c->Generate(&(SK.param)); + } + SK.GetGroup(hg)->Generate(&(SK.entity), &(SK.param)); + + // The requests and constraints depend on stuff in this or the + // previous group, so check them after generating. + if(PruneRequests(hg) || PruneConstraints(hg)) + goto pruned; + + // Use the previous values for params that we've seen before, as + // initial guesses for the solver. + for(auto &p : SK.param) { + Param *newp = &p; + if(newp->known) continue; + + Param *prevp = prev.FindByIdNoOops(newp->h); + if(prevp) { + newp->val = prevp->val; + newp->free = prevp->free; + } + } + + if(hg == Group::HGROUP_REFERENCES) { + ForceReferences(); + Group *g = SK.GetGroup(hg); + g->solved.how = SolveResult::OKAY; + g->clean = true; + } else { + // this i is an index in groupOrder + if(i >= first && i <= last) { + // The group falls inside the range, so really solve it, + // and then regenerate the mesh based on the solved stuff. + Group *g = SK.GetGroup(hg); + if(genForBBox) { + SolveGroupAndReport(hg, andFindFree); + g->GenerateLoops(); + } else { + g->GenerateShellAndMesh(); + g->clean = true; + } + } else { + // The group falls outside the range, so just assume that + // it's good wherever we left it. The mesh is unchanged, + // and the parameters must be marked as known. + for(auto &p : SK.param) { + Param *newp = &p; + + Param *prevp = prev.FindByIdNoOops(newp->h); + if(prevp) newp->known = true; + } + } + } + } + + // And update any reference dimensions with their new values + for(auto &con : SK.constraint) { + Constraint *c = &con; + if(c->reference) { + c->ModifyToSatisfy(); + } + } + + // Make sure the point that we're tracing exists. + if(traced.point.v && !SK.entity.FindByIdNoOops(traced.point)) { + traced.point = Entity::NO_ENTITY; + } + // And if we're tracing a point, add its new value to the path + if(traced.point.v) { + Entity *pt = SK.GetEntity(traced.point); + traced.path.AddPoint(pt->PointGetNum()); + } + + prev.Clear(); + GW.Invalidate(); + + // Remove nonexistent selection items, for same reason we waited till + // the end to put up a dialog box. + GW.ClearNonexistentSelectionItems(); + + if(deleted.requests > 0 || deleted.constraints > 0 || deleted.groups > 0) { + // All sorts of interesting things could have happened; for example, + // the active group or active workplane could have been deleted. So + // clear all that out. + if(deleted.groups > 0) { + SS.TW.ClearSuper(); + } + ScheduleShowTW(); + GW.ClearSuper(); + + // People get annoyed if I complain whenever they delete any request, + // and I otherwise will, since those always come with pt-coincident + // constraints. + if(deleted.requests > 0 || deleted.nonTrivialConstraints > 0 || + deleted.groups > 0) + { + // Don't display any errors until we've regenerated fully. The + // sketch is not necessarily in a consistent state until we've + // pruned any orphaned etc. objects, and the message loop for the + // messagebox could allow us to repaint and crash. But now we must + // be fine. + Message("Additional sketch elements were deleted, because they " + "depend on the element that was just deleted explicitly. " + "These include: \n" + " %d request%s\n" + " %d constraint%s\n" + " %d group%s" + "%s", + deleted.requests, deleted.requests == 1 ? "" : "s", + deleted.constraints, deleted.constraints == 1 ? "" : "s", + deleted.groups, deleted.groups == 1 ? "" : "s", + undo.cnt > 0 ? "\n\nChoose Edit -> Undo to undelete all elements." : ""); + } + + deleted = {}; + } + + FreeAllTemporary(); + allConsistent = true; + SS.GW.persistentDirty = true; + SS.centerOfMass.dirty = true; + + endMillis = GetMilliseconds(); + + if(endMillis - startMillis > 30) { + const char *typeStr = ""; + switch(type) { + case Generate::DIRTY: typeStr = "DIRTY"; break; + case Generate::ALL: typeStr = "ALL"; break; + case Generate::REGEN: typeStr = "REGEN"; break; + case Generate::UNTIL_ACTIVE: typeStr = "UNTIL_ACTIVE"; break; + } + if(endMillis) + dbp("Generate::%s%s took %lld ms", + typeStr, + (genForBBox ? " (for bounding box)" : ""), + GetMilliseconds() - startMillis); + } + + return; + +pruned: + // Restore the numerical guesses + SK.param.Clear(); + prev.MoveSelfInto(&(SK.param)); + // Try again + GenerateAll(type, andFindFree, genForBBox); +} + +void SolveSpaceUI::ForceReferences() { + // Force the values of the parameters that define the three reference + // coordinate systems. + static const struct { + hRequest hr; + Quaternion q; + } Quat[] = { + { Request::HREQUEST_REFERENCE_XY, { 1, 0, 0, 0, } }, + { Request::HREQUEST_REFERENCE_YZ, { 0.5, 0.5, 0.5, 0.5, } }, + { Request::HREQUEST_REFERENCE_ZX, { 0.5, -0.5, -0.5, -0.5, } }, + }; + for(int i = 0; i < 3; i++) { + hRequest hr = Quat[i].hr; + Entity *wrkpl = SK.GetEntity(hr.entity(0)); + // The origin for our coordinate system, always zero + Entity *origin = SK.GetEntity(wrkpl->point[0]); + origin->PointForceTo(Vector::From(0, 0, 0)); + origin->construction = true; + SK.GetParam(origin->param[0])->known = true; + SK.GetParam(origin->param[1])->known = true; + SK.GetParam(origin->param[2])->known = true; + // The quaternion that defines the rotation, from the table. + Entity *normal = SK.GetEntity(wrkpl->normal); + normal->NormalForceTo(Quat[i].q); + SK.GetParam(normal->param[0])->known = true; + SK.GetParam(normal->param[1])->known = true; + SK.GetParam(normal->param[2])->known = true; + SK.GetParam(normal->param[3])->known = true; + } +} + +void SolveSpaceUI::UpdateCenterOfMass() { + SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh); + SS.centerOfMass.position = m->GetCenterOfMass(); + SS.centerOfMass.dirty = false; +} + +void SolveSpaceUI::MarkDraggedParams() { + sys.dragged.Clear(); + + for(int i = -1; i < SS.GW.pending.points.n; i++) { + hEntity hp; + if(i == -1) { + hp = SS.GW.pending.point; + } else { + hp = SS.GW.pending.points[i]; + } + if(!hp.v) continue; + + // The pending point could be one in a group that has not yet + // been processed, in which case the lookup will fail; but + // that's not an error. + Entity *pt = SK.entity.FindByIdNoOops(hp); + if(pt) { + switch(pt->type) { + case Entity::Type::POINT_N_TRANS: + case Entity::Type::POINT_IN_3D: + case Entity::Type::POINT_N_ROT_AXIS_TRANS: + sys.dragged.Add(&(pt->param[0])); + sys.dragged.Add(&(pt->param[1])); + sys.dragged.Add(&(pt->param[2])); + break; + + case Entity::Type::POINT_IN_2D: + sys.dragged.Add(&(pt->param[0])); + sys.dragged.Add(&(pt->param[1])); + break; + + default: // Only the entities above can be dragged. + break; + } + } + } + if(SS.GW.pending.circle.v) { + Entity *circ = SK.entity.FindByIdNoOops(SS.GW.pending.circle); + if(circ) { + Entity *dist = SK.GetEntity(circ->distance); + switch(dist->type) { + case Entity::Type::DISTANCE: + sys.dragged.Add(&(dist->param[0])); + break; + + default: // Only the entities above can be dragged. + break; + } + } + } + if(SS.GW.pending.normal.v) { + Entity *norm = SK.entity.FindByIdNoOops(SS.GW.pending.normal); + if(norm) { + switch(norm->type) { + case Entity::Type::NORMAL_IN_3D: + sys.dragged.Add(&(norm->param[0])); + sys.dragged.Add(&(norm->param[1])); + sys.dragged.Add(&(norm->param[2])); + sys.dragged.Add(&(norm->param[3])); + break; + + default: // Only the entities above can be dragged. + break; + } + } + } +} + +void SolveSpaceUI::SolveGroupAndReport(hGroup hg, bool andFindFree) { + SolveGroup(hg, andFindFree); + + Group *g = SK.GetGroup(hg); + bool isOkay = g->solved.how == SolveResult::OKAY || + (g->allowRedundant && g->solved.how == SolveResult::REDUNDANT_OKAY); + if(!isOkay || (isOkay && !g->IsSolvedOkay())) { + TextWindow::ReportHowGroupSolved(g->h); + } +} + +void SolveSpaceUI::WriteEqSystemForGroup(hGroup hg) { + // Clear out the system to be solved. + sys.entity.Clear(); + sys.param.Clear(); + sys.eq.Clear(); + // And generate all the params for requests in this group + for(auto &req : SK.request) { + Request *r = &req; + if(r->group != hg) continue; + + r->Generate(&(sys.entity), &(sys.param)); + } + for(auto &con : SK.constraint) { + Constraint *c = &con; + if(c->group != hg) continue; + + c->Generate(&(sys.param)); + } + // And for the group itself + Group *g = SK.GetGroup(hg); + g->Generate(&(sys.entity), &(sys.param)); + // Set the initial guesses for all the params + for(auto ¶m : sys.param) { + Param *p = ¶m; + p->known = false; + p->val = SK.GetParam(p->h)->val; + } + + MarkDraggedParams(); +} + +void SolveSpaceUI::SolveGroup(hGroup hg, bool andFindFree) { + WriteEqSystemForGroup(hg); + Group *g = SK.GetGroup(hg); + g->solved.remove.Clear(); + g->solved.findToFixTimeout = SS.timeoutRedundantConstr; + SolveResult how = sys.Solve(g, NULL, + &(g->solved.dof), + &(g->solved.remove), + /*andFindBad=*/!g->allowRedundant, + /*andFindFree=*/andFindFree, + /*forceDofCheck=*/!g->dofCheckOk); + if(how == SolveResult::OKAY) { + g->dofCheckOk = true; + } + g->solved.how = how; + FreeAllTemporary(); +} + +SolveResult SolveSpaceUI::TestRankForGroup(hGroup hg, int *rank) { + WriteEqSystemForGroup(hg); + Group *g = SK.GetGroup(hg); + SolveResult result = sys.SolveRank(g, rank); + FreeAllTemporary(); + return result; +} + +bool SolveSpaceUI::ActiveGroupsOkay() { + for(int i = 0; i < SK.groupOrder.n; i++) { + Group *g = SK.GetGroup(SK.groupOrder[i]); + if(!g->IsSolvedOkay()) + return false; + if(g->h == SS.GW.activeGroup) + break; + } + return true; +} + diff --git a/src/graphicswin.cpp b/src/graphicswin.cpp new file mode 100644 index 0000000..32b4b08 --- /dev/null +++ b/src/graphicswin.cpp @@ -0,0 +1,1384 @@ +//----------------------------------------------------------------------------- +// Top-level implementation of the program's main window, in which a graphical +// representation of the model is drawn and edited by the user. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +typedef void MenuHandler(Command id); +using MenuKind = Platform::MenuItem::Indicator; +struct MenuEntry { + int level; // 0 == on menu bar, 1 == one level down + const char *label; // or NULL for a separator + Command cmd; // command ID + int accel; // keyboard accelerator + MenuKind kind; + MenuHandler *fn; +}; + +#define mView (&GraphicsWindow::MenuView) +#define mEdit (&GraphicsWindow::MenuEdit) +#define mClip (&GraphicsWindow::MenuClipboard) +#define mReq (&GraphicsWindow::MenuRequest) +#define mCon (&Constraint::MenuConstrain) +#define mFile (&SolveSpaceUI::MenuFile) +#define mGrp (&Group::MenuGroup) +#define mAna (&SolveSpaceUI::MenuAnalyze) +#define mHelp (&SolveSpaceUI::MenuHelp) +#define SHIFT_MASK 0x100 +#define CTRL_MASK 0x200 +#define FN_MASK 0x400 + +#define S SHIFT_MASK +#define C CTRL_MASK +#define F FN_MASK +#define KN MenuKind::NONE +#define KC MenuKind::CHECK_MARK +#define KR MenuKind::RADIO_MARK +const MenuEntry Menu[] = { +//lv label cmd accel kind +{ 0, N_("&File"), Command::NONE, 0, KN, NULL }, +{ 1, N_("&New"), Command::NEW, C|'n', KN, mFile }, +{ 1, N_("&Open..."), Command::OPEN, C|'o', KN, mFile }, +{ 1, N_("Open &Recent"), Command::OPEN_RECENT, 0, KN, mFile }, +{ 1, N_("&Save"), Command::SAVE, C|'s', KN, mFile }, +{ 1, N_("Save &As..."), Command::SAVE_AS, 0, KN, mFile }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("Export &Image..."), Command::EXPORT_IMAGE, 0, KN, mFile }, +{ 1, N_("Export 2d &View..."), Command::EXPORT_VIEW, 0, KN, mFile }, +{ 1, N_("Export 2d &Section..."), Command::EXPORT_SECTION, 0, KN, mFile }, +{ 1, N_("Export 3d &Wireframe..."), Command::EXPORT_WIREFRAME, 0, KN, mFile }, +{ 1, N_("Export Triangle &Mesh..."), Command::EXPORT_MESH, 0, KN, mFile }, +{ 1, N_("Export &Surfaces..."), Command::EXPORT_SURFACES, 0, KN, mFile }, +{ 1, N_("Im&port..."), Command::IMPORT, 0, KN, mFile }, +#ifndef __APPLE__ +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("E&xit"), Command::EXIT, C|'q', KN, mFile }, +#endif + +{ 0, N_("&Edit"), Command::NONE, 0, KN, NULL }, +{ 1, N_("&Undo"), Command::UNDO, C|'z', KN, mEdit }, +{ 1, N_("&Redo"), Command::REDO, C|'y', KN, mEdit }, +{ 1, N_("Re&generate All"), Command::REGEN_ALL, ' ', KN, mEdit }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("Snap Selection to &Grid"), Command::SNAP_TO_GRID, '.', KN, mEdit }, +{ 1, N_("Rotate Imported &90°"), Command::ROTATE_90, '9', KN, mEdit }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("Cu&t"), Command::CUT, C|'x', KN, mClip }, +{ 1, N_("&Copy"), Command::COPY, C|'c', KN, mClip }, +{ 1, N_("&Paste"), Command::PASTE, C|'v', KN, mClip }, +{ 1, N_("Paste &Transformed..."), Command::PASTE_TRANSFORM, C|'t', KN, mClip }, +{ 1, N_("&Delete"), Command::DELETE, '\x7f', KN, mClip }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("Select &Edge Chain"), Command::SELECT_CHAIN, C|'e', KN, mEdit }, +{ 1, N_("Select &All"), Command::SELECT_ALL, C|'a', KN, mEdit }, +{ 1, N_("&Unselect All"), Command::UNSELECT_ALL, '\x1b', KN, mEdit }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("&Line Styles..."), Command::EDIT_LINE_STYLES, 0, KN, mEdit }, +{ 1, N_("&View Projection..."), Command::VIEW_PROJECTION, 0, KN, mEdit }, +#ifndef __APPLE__ +{ 1, N_("Con&figuration..."), Command::CONFIGURATION, 0, KN, mEdit }, +#endif + +{ 0, N_("&View"), Command::NONE, 0, KN, mView }, +{ 1, N_("Zoom &In"), Command::ZOOM_IN, '+', KN, mView }, +{ 1, N_("Zoom &Out"), Command::ZOOM_OUT, '-', KN, mView }, +{ 1, N_("Zoom To &Fit"), Command::ZOOM_TO_FIT, 'f', KN, mView }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("Align View to &Workplane"), Command::ONTO_WORKPLANE, 'w', KN, mView }, +{ 1, N_("Nearest &Ortho View"), Command::NEAREST_ORTHO, F|2, KN, mView }, +{ 1, N_("Nearest &Isometric View"), Command::NEAREST_ISO, F|3, KN, mView }, +{ 1, N_("&Center View At Point"), Command::CENTER_VIEW, F|4, KN, mView }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("Show Snap &Grid"), Command::SHOW_GRID, '>', KC, mView }, +{ 1, N_("Darken Inactive Solids"), Command::DIM_SOLID_MODEL, 0, KC, mView }, +{ 1, N_("Use &Perspective Projection"), Command::PERSPECTIVE_PROJ, '`', KC, mView }, +{ 1, N_("Dimension &Units"), Command::NONE, 0, KN, NULL }, +{ 2, N_("Dimensions in &Millimeters"), Command::UNITS_MM, 0, KR, mView }, +{ 2, N_("Dimensions in M&eters"), Command::UNITS_METERS, 0, KR, mView }, +{ 2, N_("Dimensions in &Inches"), Command::UNITS_INCHES, 0, KR, mView }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("Show &Toolbar"), Command::SHOW_TOOLBAR, 0, KC, mView }, +{ 1, N_("Show Property Bro&wser"), Command::SHOW_TEXT_WND, '\t', KC, mView }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("&Full Screen"), Command::FULL_SCREEN, C|F|11, KC, mView }, + +{ 0, N_("&New Group"), Command::NONE, 0, KN, mGrp }, +{ 1, N_("Sketch In &3d"), Command::GROUP_3D, S|'3', KN, mGrp }, +{ 1, N_("Sketch In New &Workplane"), Command::GROUP_WRKPL, S|'w', KN, mGrp }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("Step &Translating"), Command::GROUP_TRANS, S|'t', KN, mGrp }, +{ 1, N_("Step &Rotating"), Command::GROUP_ROT, S|'r', KN, mGrp }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("E&xtrude"), Command::GROUP_EXTRUDE, S|'x', KN, mGrp }, +{ 1, N_("&Helix"), Command::GROUP_HELIX, S|'h', KN, mGrp }, +{ 1, N_("&Lathe"), Command::GROUP_LATHE, S|'l', KN, mGrp }, +{ 1, N_("Re&volve"), Command::GROUP_REVOLVE, S|'v', KN, mGrp }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("Link / Assemble..."), Command::GROUP_LINK, S|'i', KN, mGrp }, +{ 1, N_("Link Recent"), Command::GROUP_RECENT, 0, KN, mGrp }, + +{ 0, N_("&Sketch"), Command::NONE, 0, KN, mReq }, +{ 1, N_("In &Workplane"), Command::SEL_WORKPLANE, '2', KR, mReq }, +{ 1, N_("Anywhere In &3d"), Command::FREE_IN_3D, '3', KR, mReq }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("Datum &Point"), Command::DATUM_POINT, 'p', KN, mReq }, +{ 1, N_("&Workplane"), Command::WORKPLANE, 0, KN, mReq }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("Line &Segment"), Command::LINE_SEGMENT, 's', KN, mReq }, +{ 1, N_("C&onstruction Line Segment"), Command::CONSTR_SEGMENT, S|'s', KN, mReq }, +{ 1, N_("&Rectangle"), Command::RECTANGLE, 'r', KN, mReq }, +{ 1, N_("&Circle"), Command::CIRCLE, 'c', KN, mReq }, +{ 1, N_("&Arc of a Circle"), Command::ARC, 'a', KN, mReq }, +{ 1, N_("&Bezier Cubic Spline"), Command::CUBIC, 'b', KN, mReq }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("&Text in TrueType Font"), Command::TTF_TEXT, 't', KN, mReq }, +{ 1, N_("&Image"), Command::IMAGE, 0, KN, mReq }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("To&ggle Construction"), Command::CONSTRUCTION, 'g', KN, mReq }, +{ 1, N_("Tangent &Arc at Point"), Command::TANGENT_ARC, S|'a', KN, mReq }, +{ 1, N_("Split Curves at &Intersection"), Command::SPLIT_CURVES, 'i', KN, mReq }, + +{ 0, N_("&Constrain"), Command::NONE, 0, KN, mCon }, +{ 1, N_("&Distance / Diameter"), Command::DISTANCE_DIA, 'd', KN, mCon }, +{ 1, N_("Re&ference Dimension"), Command::REF_DISTANCE, S|'d', KN, mCon }, +{ 1, N_("A&ngle"), Command::ANGLE, 'n', KN, mCon }, +{ 1, N_("Reference An&gle"), Command::REF_ANGLE, S|'n', KN, mCon }, +{ 1, N_("Other S&upplementary Angle"), Command::OTHER_ANGLE, 'u', KN, mCon }, +{ 1, N_("Toggle R&eference Dim"), Command::REFERENCE, 'e', KN, mCon }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("&Horizontal"), Command::HORIZONTAL, 'h', KN, mCon }, +{ 1, N_("&Vertical"), Command::VERTICAL, 'v', KN, mCon }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("&On Point / Curve / Plane"), Command::ON_ENTITY, 'o', KN, mCon }, +{ 1, N_("E&qual Length / Radius / Angle"), Command::EQUAL, 'q', KN, mCon }, +{ 1, N_("Length Ra&tio"), Command::RATIO, 'z', KN, mCon }, +{ 1, N_("Length Diff&erence"), Command::DIFFERENCE, 'j', KN, mCon }, +{ 1, N_("At &Midpoint"), Command::AT_MIDPOINT, 'm', KN, mCon }, +{ 1, N_("S&ymmetric"), Command::SYMMETRIC, 'y', KN, mCon }, +{ 1, N_("Para&llel / Tangent"), Command::PARALLEL, 'l', KN, mCon }, +{ 1, N_("&Perpendicular"), Command::PERPENDICULAR, '[', KN, mCon }, +{ 1, N_("Same Orient&ation"), Command::ORIENTED_SAME, 'x', KN, mCon }, +{ 1, N_("Lock Point Where &Dragged"), Command::WHERE_DRAGGED, ']', KN, mCon }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("Comment"), Command::COMMENT, ';', KN, mCon }, + +{ 0, N_("&Analyze"), Command::NONE, 0, KN, mAna }, +{ 1, N_("Measure &Volume"), Command::VOLUME, C|S|'v', KN, mAna }, +{ 1, N_("Measure A&rea"), Command::AREA, C|S|'a', KN, mAna }, +{ 1, N_("Measure &Perimeter"), Command::PERIMETER, C|S|'p', KN, mAna }, +{ 1, N_("Show &Interfering Parts"), Command::INTERFERENCE, C|S|'i', KN, mAna }, +{ 1, N_("Show &Naked Edges"), Command::NAKED_EDGES, C|S|'n', KN, mAna }, +{ 1, N_("Show &Center of Mass"), Command::CENTER_OF_MASS, C|S|'c', KN, mAna }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("Show &Underconstrained Points"), Command::SHOW_DOF, C|S|'f', KN, mAna }, +{ 1, NULL, Command::NONE, 0, KN, NULL }, +{ 1, N_("&Trace Point"), Command::TRACE_PT, C|S|'t', KN, mAna }, +{ 1, N_("&Stop Tracing..."), Command::STOP_TRACING, C|S|'s', KN, mAna }, +{ 1, N_("Step &Dimension..."), Command::STEP_DIM, C|S|'d', KN, mAna }, + +{ 0, N_("&Help"), Command::NONE, 0, KN, mHelp }, +{ 1, N_("&Language"), Command::LOCALE, 0, KN, mHelp }, +{ 1, N_("&Website / Manual"), Command::WEBSITE, 0, KN, mHelp }, +#ifndef __APPLE__ +{ 1, N_("&About"), Command::ABOUT, 0, KN, mHelp }, +#endif +{ -1, 0, Command::NONE, 0, KN, NULL } +}; +#undef S +#undef C +#undef F +#undef KN +#undef KC +#undef KR + +void GraphicsWindow::ActivateCommand(Command cmd) { + for(int i = 0; Menu[i].level >= 0; i++) { + if(cmd == Menu[i].cmd) { + (Menu[i].fn)((Command)Menu[i].cmd); + break; + } + } +} + +Platform::KeyboardEvent GraphicsWindow::AcceleratorForCommand(Command cmd) { + int rawAccel = 0; + for(int i = 0; Menu[i].level >= 0; i++) { + if(cmd == Menu[i].cmd) { + rawAccel = Menu[i].accel; + break; + } + } + + Platform::KeyboardEvent accel = {}; + accel.type = Platform::KeyboardEvent::Type::PRESS; + if(rawAccel & SHIFT_MASK) { + accel.shiftDown = true; + } + if(rawAccel & CTRL_MASK) { + accel.controlDown = true; + } + if(rawAccel & FN_MASK) { + accel.key = Platform::KeyboardEvent::Key::FUNCTION; + accel.num = rawAccel & 0xff; + } else { + accel.key = Platform::KeyboardEvent::Key::CHARACTER; + accel.chr = (char)(rawAccel & 0xff); + } + + return accel; +} + +bool GraphicsWindow::KeyboardEvent(Platform::KeyboardEvent event) { + using Platform::KeyboardEvent; + + if(event.type == KeyboardEvent::Type::RELEASE) + return true; + + if(event.key == KeyboardEvent::Key::CHARACTER) { + if(event.chr == '\b') { + // Treat backspace identically to escape. + MenuEdit(Command::UNSELECT_ALL); + return true; + } else if(event.chr == '=') { + // Treat = as +. This is specific to US (and US-compatible) keyboard layouts, + // but makes zooming from keyboard much more usable on these. + // Ideally we'd have a platform-independent way of binding to a particular + // physical key regardless of shift status... + MenuView(Command::ZOOM_IN); + return true; + } + } + + // On some platforms, the OS does not handle some or all keyboard accelerators, + // so handle them here. + for(int i = 0; Menu[i].level >= 0; i++) { + if(AcceleratorForCommand(Menu[i].cmd).Equals(event)) { + ActivateCommand(Menu[i].cmd); + return true; + } + } + + return false; +} + +void GraphicsWindow::PopulateMainMenu() { + bool unique = false; + Platform::MenuBarRef mainMenu = Platform::GetOrCreateMainMenu(&unique); + if(unique) mainMenu->Clear(); + + Platform::MenuRef currentSubMenu; + std::vector subMenuStack; + for(int i = 0; Menu[i].level >= 0; i++) { + while(Menu[i].level > 0 && Menu[i].level <= (int)subMenuStack.size()) { + currentSubMenu = subMenuStack.back(); + subMenuStack.pop_back(); + } + + if(Menu[i].label == NULL) { + currentSubMenu->AddSeparator(); + continue; + } + + std::string label = Translate(Menu[i].label); + if(Menu[i].level == 0) { + currentSubMenu = mainMenu->AddSubMenu(label); + } else if(Menu[i].cmd == Command::OPEN_RECENT) { + openRecentMenu = currentSubMenu->AddSubMenu(label); + } else if(Menu[i].cmd == Command::GROUP_RECENT) { + linkRecentMenu = currentSubMenu->AddSubMenu(label); + } else if(Menu[i].cmd == Command::LOCALE) { + Platform::MenuRef localeMenu = currentSubMenu->AddSubMenu(label); + for(const Locale &locale : Locales()) { + localeMenu->AddItem(locale.displayName, [&]() { + SetLocale(locale.Culture()); + Platform::GetSettings()->FreezeString("Locale", locale.Culture()); + + SS.UpdateWindowTitles(); + PopulateMainMenu(); + EnsureValidActives(); + }); + } + } else if(Menu[i].fn == NULL) { + subMenuStack.push_back(currentSubMenu); + currentSubMenu = currentSubMenu->AddSubMenu(label); + } else { + Platform::MenuItemRef menuItem = currentSubMenu->AddItem(label); + menuItem->SetIndicator(Menu[i].kind); + if(Menu[i].accel != 0) { + menuItem->SetAccelerator(AcceleratorForCommand(Menu[i].cmd)); + } + menuItem->onTrigger = std::bind(Menu[i].fn, Menu[i].cmd); + + if(Menu[i].cmd == Command::SHOW_GRID) { + showGridMenuItem = menuItem; + } else if(Menu[i].cmd == Command::DIM_SOLID_MODEL) { + dimSolidModelMenuItem = menuItem; + } else if(Menu[i].cmd == Command::PERSPECTIVE_PROJ) { + perspectiveProjMenuItem = menuItem; + } else if(Menu[i].cmd == Command::SHOW_TOOLBAR) { + showToolbarMenuItem = menuItem; + } else if(Menu[i].cmd == Command::SHOW_TEXT_WND) { + showTextWndMenuItem = menuItem; + } else if(Menu[i].cmd == Command::FULL_SCREEN) { + fullScreenMenuItem = menuItem; + } else if(Menu[i].cmd == Command::UNITS_MM) { + unitsMmMenuItem = menuItem; + } else if(Menu[i].cmd == Command::UNITS_METERS) { + unitsMetersMenuItem = menuItem; + } else if(Menu[i].cmd == Command::UNITS_INCHES) { + unitsInchesMenuItem = menuItem; + } else if(Menu[i].cmd == Command::SEL_WORKPLANE) { + inWorkplaneMenuItem = menuItem; + } else if(Menu[i].cmd == Command::FREE_IN_3D) { + in3dMenuItem = menuItem; + } else if(Menu[i].cmd == Command::UNDO) { + undoMenuItem = menuItem; + } else if(Menu[i].cmd == Command::REDO) { + redoMenuItem = menuItem; + } + } + } + + PopulateRecentFiles(); + SS.UndoEnableMenus(); + + window->SetMenuBar(mainMenu); +} + +static void PopulateMenuWithPathnames(Platform::MenuRef menu, + std::vector pathnames, + std::function onTrigger) { + menu->Clear(); + if(pathnames.empty()) { + Platform::MenuItemRef menuItem = menu->AddItem(_("(no recent files)")); + menuItem->SetEnabled(false); + } else { + for(Platform::Path pathname : pathnames) { + Platform::MenuItemRef menuItem = menu->AddItem(pathname.raw, [=]() { + if(FileExists(pathname)) { + onTrigger(pathname); + } else { + Error(_("File '%s' does not exist."), pathname.raw.c_str()); + } + }, /*mnemonics=*/false); + } + } +} + +void GraphicsWindow::PopulateRecentFiles() { + PopulateMenuWithPathnames(openRecentMenu, SS.recentFiles, [](const Platform::Path &path) { + if(!SS.OkayToStartNewFile()) return; + SS.Load(path); + }); + + PopulateMenuWithPathnames(linkRecentMenu, SS.recentFiles, [](const Platform::Path &path) { + Group::MenuGroup(Command::GROUP_LINK, path); + }); +} + +void GraphicsWindow::Init() { + scale = 5; + offset = Vector::From(0, 0, 0); + projRight = Vector::From(1, 0, 0); + projUp = Vector::From(0, 1, 0); + + // Make sure those are valid; could get a mouse move without a mouse + // down if someone depresses the button, then drags into our window. + orig.projRight = projRight; + orig.projUp = projUp; + + // And with the last group active + ssassert(!SK.groupOrder.IsEmpty(), + "Group order can't be empty since we will activate the last group."); + activeGroup = *SK.groupOrder.Last(); + SK.GetGroup(activeGroup)->Activate(); + + showWorkplanes = false; + showNormals = true; + showPoints = true; + showConstruction = true; + showConstraints = true; + showShaded = true; + showEdges = true; + showMesh = false; + showOutlines = false; + drawOccludedAs = DrawOccludedAs::INVISIBLE; + + showTextWindow = true; + + showSnapGrid = false; + dimSolidModel = true; + context.active = false; + toolbarHovered = Command::NONE; + + if(!window) { + window = Platform::CreateWindow(); + if(window) { + using namespace std::placeholders; + // Do this first, so that if it causes an onRender event we don't try to paint without + // a canvas. + window->SetMinContentSize(720, 670); + window->onClose = std::bind(&SolveSpaceUI::MenuFile, Command::EXIT); + window->onRender = std::bind(&GraphicsWindow::Paint, this); + window->onKeyboardEvent = std::bind(&GraphicsWindow::KeyboardEvent, this, _1); + window->onMouseEvent = std::bind(&GraphicsWindow::MouseEvent, this, _1); + window->onSixDofEvent = std::bind(&GraphicsWindow::SixDofEvent, this, _1); + window->onEditingDone = std::bind(&GraphicsWindow::EditControlDone, this, _1); + PopulateMainMenu(); + } + } + + if(window) { + canvas = CreateRenderer(); + if(canvas) { + persistentCanvas = canvas->CreateBatch(); + persistentDirty = true; + } + } + + // Do this last, so that all the menus get updated correctly. + ClearSuper(); +} + +void GraphicsWindow::AnimateOntoWorkplane() { + if(!LockedInWorkplane()) return; + + Entity *w = SK.GetEntity(ActiveWorkplane()); + Quaternion quatf = w->Normal()->NormalGetNum(); + + // Get Z pointing vertical, if we're on turntable nav mode: + if(SS.turntableNav) { + Vector normalRight = quatf.RotationU(); + Vector normalUp = quatf.RotationV(); + Vector normal = normalRight.Cross(normalUp); + if(normalRight.z != 0) { + double theta = atan2(normalUp.z, normalRight.z); + theta -= atan2(1, 0); + normalRight = normalRight.RotatedAbout(normal, theta); + normalUp = normalUp.RotatedAbout(normal, theta); + quatf = Quaternion::From(normalRight, normalUp); + } + } + + Vector offsetf = (SK.GetEntity(w->point[0])->PointGetNum()).ScaledBy(-1); + + // If the view screen is open, then we need to refresh it. + SS.ScheduleShowTW(); + + AnimateOnto(quatf, offsetf); +} + +void GraphicsWindow::AnimateOnto(Quaternion quatf, Vector offsetf) { + // Get our initial orientation and translation. + Quaternion quat0 = Quaternion::From(projRight, projUp); + Vector offset0 = offset; + + // Make sure we take the shorter of the two possible paths. + double mp = (quatf.Minus(quat0)).Magnitude(); + double mm = (quatf.Plus(quat0)).Magnitude(); + if(mp > mm) { + quatf = quatf.ScaledBy(-1); + mp = mm; + } + double mo = (offset0.Minus(offsetf)).Magnitude()*scale; + + // Animate transition, unless it's a tiny move. + int64_t t0 = GetMilliseconds(); + int32_t dt = (mp < 0.01 && mo < 10) ? (-20) : + (int32_t)(100 + 1000*mp + 0.4*mo); + // Don't ever animate for longer than 2000 ms; we can get absurdly + // long translations (as measured in pixels) if the user zooms out, moves, + // and then zooms in again. + if(dt > 2000) dt = 2000; + Quaternion dq = quatf.Times(quat0.Inverse()); + + if(!animateTimer) { + animateTimer = Platform::CreateTimer(); + } + animateTimer->onTimeout = [=] { + int64_t tn = GetMilliseconds(); + if((tn - t0) < dt) { + animateTimer->RunAfterNextFrame(); + + double s = (tn - t0)/((double)dt); + offset = (offset0.ScaledBy(1 - s)).Plus(offsetf.ScaledBy(s)); + Quaternion quat = (dq.ToThe(s)).Times(quat0).WithMagnitude(1); + + projRight = quat.RotationU(); + projUp = quat.RotationV(); + } else { + projRight = quatf.RotationU(); + projUp = quatf.RotationV(); + offset = offsetf; + } + window->Invalidate(); + }; + animateTimer->RunAfterNextFrame(); +} + +void GraphicsWindow::HandlePointForZoomToFit(Vector p, Point2d *pmax, Point2d *pmin, + double *wmin, bool usePerspective, + const Camera &camera) +{ + double w; + Vector pp = camera.ProjectPoint4(p, &w); + // If usePerspective is true, then we calculate a perspective projection of the point. + // If not, then we do a parallel projection regardless of the current + // scale factor. + if(usePerspective) { + pp = pp.ScaledBy(1.0/w); + } + + pmax->x = max(pmax->x, pp.x); + pmax->y = max(pmax->y, pp.y); + pmin->x = min(pmin->x, pp.x); + pmin->y = min(pmin->y, pp.y); + *wmin = min(*wmin, w); +} +void GraphicsWindow::LoopOverPoints(const std::vector &entities, + const std::vector &constraints, + const std::vector &faces, + Point2d *pmax, Point2d *pmin, double *wmin, + bool usePerspective, bool includeMesh, + const Camera &camera) { + + for(Entity *e : entities) { + if(e->IsPoint()) { + HandlePointForZoomToFit(e->PointGetNum(), pmax, pmin, wmin, usePerspective, camera); + } else if(e->type == Entity::Type::CIRCLE) { + // Lots of entities can extend outside the bbox of their points, + // but circles are particularly bad. We want to get things halfway + // reasonable without the mesh, because a zoom to fit is used to + // set the zoom level to set the chord tol. + double r = e->CircleGetRadiusNum(); + Vector c = SK.GetEntity(e->point[0])->PointGetNum(); + Quaternion q = SK.GetEntity(e->normal)->NormalGetNum(); + for(int j = 0; j < 4; j++) { + Vector p = (j == 0) ? (c.Plus(q.RotationU().ScaledBy( r))) : + (j == 1) ? (c.Plus(q.RotationU().ScaledBy(-r))) : + (j == 2) ? (c.Plus(q.RotationV().ScaledBy( r))) : + (c.Plus(q.RotationV().ScaledBy(-r))); + HandlePointForZoomToFit(p, pmax, pmin, wmin, usePerspective, camera); + } + } else { + // We have to iterate children points, because we can select entities without points + for(int i = 0; i < MAX_POINTS_IN_ENTITY; i++) { + if(e->point[i].v == 0) break; + Vector p = SK.GetEntity(e->point[i])->PointGetNum(); + HandlePointForZoomToFit(p, pmax, pmin, wmin, usePerspective, camera); + } + } + } + + for(Constraint *c : constraints) { + std::vector refs; + c->GetReferencePoints(camera, &refs); + for(Vector p : refs) { + HandlePointForZoomToFit(p, pmax, pmin, wmin, usePerspective, camera); + } + } + + if(!includeMesh && faces.empty()) return; + + Group *g = SK.GetGroup(activeGroup); + g->GenerateDisplayItems(); + for(int i = 0; i < g->displayMesh.l.n; i++) { + STriangle *tr = &(g->displayMesh.l[i]); + if(!includeMesh) { + bool found = false; + for(const hEntity &face : faces) { + if(face.v != tr->meta.face) continue; + found = true; + break; + } + if(!found) continue; + } + HandlePointForZoomToFit(tr->a, pmax, pmin, wmin, usePerspective, camera); + HandlePointForZoomToFit(tr->b, pmax, pmin, wmin, usePerspective, camera); + HandlePointForZoomToFit(tr->c, pmax, pmin, wmin, usePerspective, camera); + } + if(!includeMesh) return; + for(int i = 0; i < g->polyLoops.l.n; i++) { + SContour *sc = &(g->polyLoops.l[i]); + for(int j = 0; j < sc->l.n; j++) { + HandlePointForZoomToFit(sc->l[j].p, pmax, pmin, wmin, usePerspective, camera); + } + } +} +void GraphicsWindow::ZoomToFit(bool includingInvisibles, bool useSelection) { + if(!window) return; + + scale = ZoomToFit(GetCamera(), includingInvisibles, useSelection); +} +double GraphicsWindow::ZoomToFit(const Camera &camera, + bool includingInvisibles, bool useSelection) { + std::vector entities; + std::vector constraints; + std::vector faces; + + if(useSelection) { + for(int i = 0; i < selection.n; i++) { + Selection *s = &selection[i]; + if(s->entity.v != 0) { + Entity *e = SK.entity.FindById(s->entity); + if(e->IsFace()) { + faces.push_back(e->h); + continue; + } + entities.push_back(e); + } + if(s->constraint.v != 0) { + Constraint *c = SK.constraint.FindById(s->constraint); + constraints.push_back(c); + } + } + } + + bool selectionUsed = !entities.empty() || !constraints.empty() || !faces.empty(); + + if(!selectionUsed) { + for(Entity &e : SK.entity) { + // we don't want to handle separate points, because we will iterate them inside entities. + if(e.IsPoint()) continue; + if(!includingInvisibles && !e.IsVisible()) continue; + entities.push_back(&e); + } + + for(Constraint &c : SK.constraint) { + if(!c.IsVisible()) continue; + constraints.push_back(&c); + } + } + + // On the first run, ignore perspective. + Point2d pmax = { -1e12, -1e12 }, pmin = { 1e12, 1e12 }; + double wmin = 1; + LoopOverPoints(entities, constraints, faces, &pmax, &pmin, &wmin, + /*usePerspective=*/false, /*includeMesh=*/!selectionUsed, + camera); + + double xm = (pmax.x + pmin.x)/2, ym = (pmax.y + pmin.y)/2; + double dx = pmax.x - pmin.x, dy = pmax.y - pmin.y; + + offset = offset.Plus(projRight.ScaledBy(-xm)).Plus( + projUp. ScaledBy(-ym)); + + // And based on this, we calculate the scale and offset + double scale; + if(EXACT(dx == 0 && dy == 0)) { + scale = 5; + } else { + double scalex = 1e12, scaley = 1e12; + if(EXACT(dx != 0)) scalex = 0.9*camera.width /dx; + if(EXACT(dy != 0)) scaley = 0.9*camera.height/dy; + scale = min(scalex, scaley); + + scale = min(300.0, scale); + scale = max(0.003, scale); + } + + // Then do another run, considering the perspective. + pmax.x = -1e12; pmax.y = -1e12; + pmin.x = 1e12; pmin.y = 1e12; + wmin = 1; + LoopOverPoints(entities, constraints, faces, &pmax, &pmin, &wmin, + /*usePerspective=*/true, /*includeMesh=*/!selectionUsed, + camera); + + // Adjust the scale so that no points are behind the camera + if(wmin < 0.1) { + double k = camera.tangent; + // w = 1+k*scale*z + double zmin = (wmin - 1)/(k*scale); + // 0.1 = 1 + k*scale*zmin + // (0.1 - 1)/(k*zmin) = scale + scale = min(scale, (0.1 - 1)/(k*zmin)); + } + + return scale; +} + +void GraphicsWindow::MenuView(Command id) { + switch(id) { + case Command::ZOOM_IN: + SS.GW.scale *= 1.2; + SS.ScheduleShowTW(); + break; + + case Command::ZOOM_OUT: + SS.GW.scale /= 1.2; + SS.ScheduleShowTW(); + break; + + case Command::ZOOM_TO_FIT: + SS.GW.ZoomToFit(/*includingInvisibles=*/false, /*useSelection=*/true); + SS.ScheduleShowTW(); + break; + + case Command::SHOW_GRID: + SS.GW.showSnapGrid = !SS.GW.showSnapGrid; + SS.GW.EnsureValidActives(); + SS.GW.Invalidate(); + if(SS.GW.showSnapGrid && !SS.GW.LockedInWorkplane()) { + Message(_("No workplane is active, so the grid will not appear.")); + } + break; + + case Command::DIM_SOLID_MODEL: + SS.GW.dimSolidModel = !SS.GW.dimSolidModel; + SS.GW.EnsureValidActives(); + SS.GW.Invalidate(/*clearPersistent=*/true); + break; + + case Command::PERSPECTIVE_PROJ: + SS.usePerspectiveProj = !SS.usePerspectiveProj; + SS.GW.EnsureValidActives(); + SS.GW.Invalidate(); + if(SS.cameraTangent < 1e-6) { + Error(_("The perspective factor is set to zero, so the view will " + "always be a parallel projection.\n\n" + "For a perspective projection, modify the perspective " + "factor in the configuration screen. A value around 0.3 " + "is typical.")); + } + break; + + case Command::ONTO_WORKPLANE: + if(SS.GW.LockedInWorkplane()) { + SS.GW.AnimateOntoWorkplane(); + break; + } // if not in 2d mode use ORTHO logic + // fallthrough + case Command::NEAREST_ORTHO: + case Command::NEAREST_ISO: { + static const Vector ortho[3] = { + Vector::From(1, 0, 0), + Vector::From(0, 1, 0), + Vector::From(0, 0, 1) + }; + double sqrt2 = sqrt(2.0), sqrt6 = sqrt(6.0); + Quaternion quat0 = Quaternion::From(SS.GW.projRight, SS.GW.projUp); + Quaternion quatf = quat0; + double dmin = 1e10; + + // There are 24 possible views; 3*2*2*2 + int i, j, negi, negj; + for(i = 0; i < 3; i++) { + for(j = 0; j < 3; j++) { + if(i == j) continue; + for(negi = 0; negi < 2; negi++) { + for(negj = 0; negj < 2; negj++) { + Vector ou = ortho[i], ov = ortho[j]; + if(negi) ou = ou.ScaledBy(-1); + if(negj) ov = ov.ScaledBy(-1); + Vector on = ou.Cross(ov); + + Vector u, v; + if(id == Command::NEAREST_ORTHO || id == Command::ONTO_WORKPLANE) { + u = ou; + v = ov; + } else { + u = + ou.ScaledBy(1/sqrt2).Plus( + on.ScaledBy(-1/sqrt2)); + v = + ou.ScaledBy(-1/sqrt6).Plus( + ov.ScaledBy(2/sqrt6).Plus( + on.ScaledBy(-1/sqrt6))); + } + + Quaternion quatt = Quaternion::From(u, v); + double d = min( + (quatt.Minus(quat0)).Magnitude(), + (quatt.Plus(quat0)).Magnitude()); + if(d < dmin) { + dmin = d; + quatf = quatt; + } + } + } + } + } + + SS.GW.AnimateOnto(quatf, SS.GW.offset); + break; + } + + case Command::CENTER_VIEW: + SS.GW.GroupSelection(); + if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) { + Quaternion quat0; + // Offset is the selected point, quaternion is same as before + Vector pt = SK.GetEntity(SS.GW.gs.point[0])->PointGetNum(); + quat0 = Quaternion::From(SS.GW.projRight, SS.GW.projUp); + SS.GW.ClearSelection(); + SS.GW.AnimateOnto(quat0, pt.ScaledBy(-1)); + } else { + Error(_("Select a point; this point will become the center " + "of the view on screen.")); + } + break; + + case Command::SHOW_TOOLBAR: + SS.showToolbar = !SS.showToolbar; + SS.GW.EnsureValidActives(); + SS.GW.Invalidate(); + break; + + case Command::SHOW_TEXT_WND: + SS.GW.showTextWindow = !SS.GW.showTextWindow; + SS.GW.EnsureValidActives(); + break; + + case Command::UNITS_INCHES: + SS.viewUnits = Unit::INCHES; + SS.ScheduleShowTW(); + SS.GW.EnsureValidActives(); + break; + + case Command::UNITS_MM: + SS.viewUnits = Unit::MM; + SS.ScheduleShowTW(); + SS.GW.EnsureValidActives(); + break; + + case Command::UNITS_METERS: + SS.viewUnits = Unit::METERS; + SS.ScheduleShowTW(); + SS.GW.EnsureValidActives(); + break; + + case Command::FULL_SCREEN: + SS.GW.window->SetFullScreen(!SS.GW.window->IsFullScreen()); + SS.GW.EnsureValidActives(); + break; + + default: ssassert(false, "Unexpected menu ID"); + } + SS.GW.Invalidate(); +} + +void GraphicsWindow::EnsureValidActives() { + bool change = false; + // The active group must exist, and not be the references. + Group *g = SK.group.FindByIdNoOops(activeGroup); + if((!g) || (g->h == Group::HGROUP_REFERENCES)) { + // Not using range-for because this is used to find an index. + int i; + for(i = 0; i < SK.groupOrder.n; i++) { + if(SK.groupOrder[i] != Group::HGROUP_REFERENCES) { + break; + } + } + if(i >= SK.groupOrder.n) { + // This can happen if the user deletes all the groups in the + // sketch. It's difficult to prevent that, because the last + // group might have been deleted automatically, because it failed + // a dependency. There needs to be something, so create a plane + // drawing group and activate that. They should never be able + // to delete the references, though. + activeGroup = SS.CreateDefaultDrawingGroup(); + // We've created the default group, but not the workplane entity; + // do it now so that drawing mode isn't switched to "Free in 3d". + SS.GenerateAll(SolveSpaceUI::Generate::ALL); + } else { + activeGroup = SK.groupOrder[i]; + } + SK.GetGroup(activeGroup)->Activate(); + change = true; + } + + // The active coordinate system must also exist. + if(LockedInWorkplane()) { + Entity *e = SK.entity.FindByIdNoOops(ActiveWorkplane()); + if(e) { + hGroup hgw = e->group; + if(hgw != activeGroup && SS.GroupsInOrder(activeGroup, hgw)) { + // The active workplane is in a group that comes after the + // active group; so any request or constraint will fail. + SetWorkplaneFreeIn3d(); + change = true; + } + } else { + SetWorkplaneFreeIn3d(); + change = true; + } + } + + if(!window) return; + + // And update the checked state for various menus + bool locked = LockedInWorkplane(); + in3dMenuItem->SetActive(!locked); + inWorkplaneMenuItem->SetActive(locked); + + SS.UndoEnableMenus(); + + switch(SS.viewUnits) { + case Unit::MM: + case Unit::METERS: + case Unit::INCHES: + break; + default: + SS.viewUnits = Unit::MM; + break; + } + unitsMmMenuItem->SetActive(SS.viewUnits == Unit::MM); + unitsMetersMenuItem->SetActive(SS.viewUnits == Unit::METERS); + unitsInchesMenuItem->SetActive(SS.viewUnits == Unit::INCHES); + + if(SS.TW.window) SS.TW.window->SetVisible(SS.GW.showTextWindow); + showTextWndMenuItem->SetActive(SS.GW.showTextWindow); + + showGridMenuItem->SetActive(SS.GW.showSnapGrid); + dimSolidModelMenuItem->SetActive(SS.GW.dimSolidModel); + perspectiveProjMenuItem->SetActive(SS.usePerspectiveProj); + showToolbarMenuItem->SetActive(SS.showToolbar); + fullScreenMenuItem->SetActive(SS.GW.window->IsFullScreen()); + + if(change) SS.ScheduleShowTW(); +} + +void GraphicsWindow::SetWorkplaneFreeIn3d() { + SK.GetGroup(activeGroup)->activeWorkplane = Entity::FREE_IN_3D; +} +hEntity GraphicsWindow::ActiveWorkplane() { + Group *g = SK.group.FindByIdNoOops(activeGroup); + if(g) { + return g->activeWorkplane; + } else { + return Entity::FREE_IN_3D; + } +} +bool GraphicsWindow::LockedInWorkplane() { + return (SS.GW.ActiveWorkplane() != Entity::FREE_IN_3D); +} + +void GraphicsWindow::ForceTextWindowShown() { + if(!showTextWindow) { + showTextWindow = true; + showTextWndMenuItem->SetActive(true); + SS.TW.window->SetVisible(true); + } +} + +void GraphicsWindow::DeleteTaggedRequests() { + Request *r; + // Delete any requests that were affected by this deletion. + for(r = SK.request.First(); r; r = SK.request.NextAfter(r)) { + if(r->workplane == Entity::FREE_IN_3D) continue; + if(!r->workplane.isFromRequest()) continue; + Request *wrkpl = SK.GetRequest(r->workplane.request()); + if(wrkpl->tag) + r->tag = 1; + } + // Rewrite any point-coincident constraints that were affected by this + // deletion. + for(r = SK.request.First(); r; r = SK.request.NextAfter(r)) { + if(!r->tag) continue; + FixConstraintsForRequestBeingDeleted(r->h); + } + // and then delete the tagged requests. + SK.request.RemoveTagged(); + + // An edit might be in progress for the just-deleted item. So + // now it's not. + window->HideEditor(); + SS.TW.HideEditControl(); + // And clear out the selection, which could contain that item. + ClearSuper(); + // And regenerate to get rid of what it generates, plus anything + // that references it (since the regen code checks for that). + SS.GenerateAll(SolveSpaceUI::Generate::ALL); + EnsureValidActives(); + SS.ScheduleShowTW(); +} + +Vector GraphicsWindow::SnapToGrid(Vector p) { + if(!LockedInWorkplane()) return p; + + EntityBase *wrkpl = SK.GetEntity(ActiveWorkplane()), + *norm = wrkpl->Normal(); + Vector wo = SK.GetEntity(wrkpl->point[0])->PointGetNum(), + wu = norm->NormalU(), + wv = norm->NormalV(), + wn = norm->NormalN(); + + Vector pp = (p.Minus(wo)).DotInToCsys(wu, wv, wn); + pp.x = floor((pp.x / SS.gridSpacing) + 0.5)*SS.gridSpacing; + pp.y = floor((pp.y / SS.gridSpacing) + 0.5)*SS.gridSpacing; + pp.z = 0; + + return pp.ScaleOutOfCsys(wu, wv, wn).Plus(wo); +} + +void GraphicsWindow::MenuEdit(Command id) { + switch(id) { + case Command::UNSELECT_ALL: + SS.GW.GroupSelection(); + // If there's nothing selected to de-select, and no operation + // to cancel, then perhaps they want to return to the home + // screen in the text window. + if(SS.GW.gs.n == 0 && + SS.GW.gs.constraints == 0 && + SS.GW.pending.operation == Pending::NONE) + { + if(!(SS.TW.window->IsEditorVisible() || + SS.GW.window->IsEditorVisible())) + { + if(SS.TW.shown.screen == TextWindow::Screen::STYLE_INFO) { + SS.TW.GoToScreen(TextWindow::Screen::LIST_OF_STYLES); + } else { + SS.TW.ClearSuper(); + } + } + } + SS.GW.ClearSuper(); + SS.TW.HideEditControl(); + SS.nakedEdges.Clear(); + SS.justExportedInfo.draw = false; + SS.centerOfMass.draw = false; + // This clears the marks drawn to indicate which points are + // still free to drag. + Param *p; + for(p = SK.param.First(); p; p = SK.param.NextAfter(p)) { + p->free = false; + } + if(SS.exportMode) { + SS.exportMode = false; + SS.GenerateAll(SolveSpaceUI::Generate::ALL); + } + SS.GW.persistentDirty = true; + break; + + case Command::SELECT_ALL: { + Entity *e; + for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) { + if(e->group != SS.GW.activeGroup) continue; + if(e->IsFace() || e->IsDistance()) continue; + if(!e->IsVisible()) continue; + + SS.GW.MakeSelected(e->h); + } + SS.GW.Invalidate(); + SS.ScheduleShowTW(); + break; + } + + case Command::SELECT_CHAIN: { + Entity *e; + int newlySelected = 0; + bool didSomething; + do { + didSomething = false; + for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) { + if(e->group != SS.GW.activeGroup) continue; + if(!e->HasEndpoints()) continue; + if(!e->IsVisible()) continue; + + Vector st = e->EndpointStart(), + fi = e->EndpointFinish(); + + bool onChain = false, alreadySelected = false; + List *ls = &(SS.GW.selection); + for(Selection *s = ls->First(); s; s = ls->NextAfter(s)) { + if(!s->entity.v) continue; + if(s->entity == e->h) { + alreadySelected = true; + continue; + } + Entity *se = SK.GetEntity(s->entity); + if(!se->HasEndpoints()) continue; + + Vector sst = se->EndpointStart(), + sfi = se->EndpointFinish(); + + if(sst.Equals(st) || sst.Equals(fi) || + sfi.Equals(st) || sfi.Equals(fi)) + { + onChain = true; + } + } + if(onChain && !alreadySelected) { + SS.GW.MakeSelected(e->h); + newlySelected++; + didSomething = true; + } + } + } while(didSomething); + SS.GW.Invalidate(); + SS.ScheduleShowTW(); + if(newlySelected == 0) { + Error(_("No additional entities share endpoints with the selected entities.")); + } + break; + } + + case Command::ROTATE_90: { + SS.GW.GroupSelection(); + Entity *e = NULL; + if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) { + e = SK.GetEntity(SS.GW.gs.point[0]); + } else if(SS.GW.gs.n == 1 && SS.GW.gs.entities == 1) { + e = SK.GetEntity(SS.GW.gs.entity[0]); + } + SS.GW.ClearSelection(); + + hGroup hg = e ? e->group : SS.GW.activeGroup; + Group *g = SK.GetGroup(hg); + if(g->type != Group::Type::LINKED) { + Error(_("To use this command, select a point or other " + "entity from an linked part, or make a link " + "group the active group.")); + break; + } + + SS.UndoRemember(); + // Rotate by ninety degrees about the coordinate axis closest + // to the screen normal. + Vector norm = SS.GW.projRight.Cross(SS.GW.projUp); + norm = norm.ClosestOrtho(); + norm = norm.WithMagnitude(1); + Quaternion qaa = Quaternion::From(norm, PI/2); + + g->TransformImportedBy(Vector::From(0, 0, 0), qaa); + + // and regenerate as necessary. + SS.MarkGroupDirty(hg); + break; + } + + case Command::SNAP_TO_GRID: { + if(!SS.GW.LockedInWorkplane()) { + Error(_("No workplane is active. Activate a workplane " + "(with Sketch -> In Workplane) to define the plane " + "for the snap grid.")); + break; + } + SS.GW.GroupSelection(); + if(SS.GW.gs.points == 0 && SS.GW.gs.constraintLabels == 0) { + Error(_("Can't snap these items to grid; select points, " + "text comments, or constraints with a label. " + "To snap a line, select its endpoints.")); + break; + } + SS.UndoRemember(); + + List *ls = &(SS.GW.selection); + for(Selection *s = ls->First(); s; s = ls->NextAfter(s)) { + if(s->entity.v) { + hEntity hp = s->entity; + Entity *ep = SK.GetEntity(hp); + if(!ep->IsPoint()) continue; + + Vector p = ep->PointGetNum(); + ep->PointForceTo(SS.GW.SnapToGrid(p)); + SS.GW.pending.points.Add(&hp); + SS.MarkGroupDirty(ep->group); + } else if(s->constraint.v) { + Constraint *c = SK.GetConstraint(s->constraint); + std::vector refs; + c->GetReferencePoints(SS.GW.GetCamera(), &refs); + c->disp.offset = c->disp.offset.Plus(SS.GW.SnapToGrid(refs[0]).Minus(refs[0])); + } + } + // Regenerate, with these points marked as dragged so that they + // get placed as close as possible to our snap grid. + SS.GW.ClearSelection(); + break; + } + + case Command::UNDO: + SS.UndoUndo(); + break; + + case Command::REDO: + SS.UndoRedo(); + break; + + case Command::REGEN_ALL: + SS.images.clear(); + SS.ReloadAllLinked(SS.saveFile); + SS.GenerateAll(SolveSpaceUI::Generate::UNTIL_ACTIVE); + SS.ScheduleShowTW(); + break; + + case Command::EDIT_LINE_STYLES: + SS.TW.GoToScreen(TextWindow::Screen::LIST_OF_STYLES); + SS.GW.ForceTextWindowShown(); + SS.ScheduleShowTW(); + break; + case Command::VIEW_PROJECTION: + SS.TW.GoToScreen(TextWindow::Screen::EDIT_VIEW); + SS.GW.ForceTextWindowShown(); + SS.ScheduleShowTW(); + break; + case Command::CONFIGURATION: + SS.TW.GoToScreen(TextWindow::Screen::CONFIGURATION); + SS.GW.ForceTextWindowShown(); + SS.ScheduleShowTW(); + break; + + default: ssassert(false, "Unexpected menu ID"); + } +} + +void GraphicsWindow::MenuRequest(Command id) { + const char *s; + switch(id) { + case Command::SEL_WORKPLANE: { + SS.GW.GroupSelection(); + Group *g = SK.GetGroup(SS.GW.activeGroup); + + if(SS.GW.gs.n == 1 && SS.GW.gs.workplanes == 1) { + // A user-selected workplane + g->activeWorkplane = SS.GW.gs.entity[0]; + SS.GW.EnsureValidActives(); + SS.ScheduleShowTW(); + } else if(g->type == Group::Type::DRAWING_WORKPLANE) { + // The group's default workplane + g->activeWorkplane = g->h.entity(0); + MessageAndRun([] { + // Align the view with the selected workplane + SS.GW.ClearSuper(); + SS.GW.AnimateOntoWorkplane(); + }, _("No workplane selected. Activating default workplane " + "for this group.")); + } else { + Error(_("No workplane is selected, and the active group does " + "not have a default workplane. Try selecting a " + "workplane, or activating a sketch-in-new-workplane " + "group.")); + //update checkboxes in the menus + SS.GW.EnsureValidActives(); + } + break; + } + case Command::FREE_IN_3D: + SS.GW.SetWorkplaneFreeIn3d(); + SS.GW.EnsureValidActives(); + SS.ScheduleShowTW(); + SS.GW.Invalidate(); + break; + + case Command::TANGENT_ARC: + SS.GW.GroupSelection(); + if(SS.GW.gs.n == 1 && SS.GW.gs.points == 1) { + SS.GW.MakeTangentArc(); + } else if(SS.GW.gs.n != 0) { + Error(_("Bad selection for tangent arc at point. Select a " + "single point, or select nothing to set up arc " + "parameters.")); + } else { + SS.TW.GoToScreen(TextWindow::Screen::TANGENT_ARC); + SS.GW.ForceTextWindowShown(); + SS.ScheduleShowTW(); + SS.GW.Invalidate(); // repaint toolbar + } + break; + + case Command::ARC: s = _("click point on arc (draws anti-clockwise)"); goto c; + case Command::DATUM_POINT: s = _("click to place datum point"); goto c; + case Command::LINE_SEGMENT: s = _("click first point of line segment"); goto c; + case Command::CONSTR_SEGMENT: + s = _("click first point of construction line segment"); goto c; + case Command::CUBIC: s = _("click first point of cubic segment"); goto c; + case Command::CIRCLE: s = _("click center of circle"); goto c; + case Command::WORKPLANE: s = _("click origin of workplane"); goto c; + case Command::RECTANGLE: s = _("click one corner of rectangle"); goto c; + case Command::TTF_TEXT: s = _("click top left of text"); goto c; + case Command::IMAGE: + if(!SS.ReloadLinkedImage(SS.saveFile, &SS.GW.pending.filename, + /*canCancel=*/true)) { + return; + } + s = _("click top left of image"); goto c; +c: + SS.GW.pending.operation = GraphicsWindow::Pending::COMMAND; + SS.GW.pending.command = id; + SS.GW.pending.description = s; + SS.ScheduleShowTW(); + SS.GW.Invalidate(); // repaint toolbar + break; + + case Command::CONSTRUCTION: { + SS.GW.GroupSelection(); + if(SS.GW.gs.entities == 0) { + Error(_("No entities are selected. Select entities before " + "trying to toggle their construction state.")); + break; + } + SS.UndoRemember(); + int i; + for(i = 0; i < SS.GW.gs.entities; i++) { + hEntity he = SS.GW.gs.entity[i]; + if(!he.isFromRequest()) continue; + Request *r = SK.GetRequest(he.request()); + r->construction = !(r->construction); + SS.MarkGroupDirty(r->group); + } + SS.GW.ClearSelection(); + break; + } + + case Command::SPLIT_CURVES: + SS.GW.SplitLinesOrCurves(); + break; + + default: ssassert(false, "Unexpected menu ID"); + } +} + +void GraphicsWindow::ClearSuper() { + if(window) window->HideEditor(); + ClearPending(); + ClearSelection(); + hover.Clear(); + EnsureValidActives(); +} + +void GraphicsWindow::ToggleBool(bool *v) { + *v = !*v; + + // The faces are shown as special stippling on the shaded triangle mesh, + // so not meaningful to show them and hide the shaded. + if(!showShaded) showFaces = false; + + // If the mesh or edges were previously hidden, they haven't been generated, + // and if we are going to show them, we need to generate them first. + Group *g = SK.GetGroup(SS.GW.activeGroup); + if(*v && (g->displayOutlines.l.IsEmpty() && (v == &showEdges || v == &showOutlines))) { + SS.GenerateAll(SolveSpaceUI::Generate::UNTIL_ACTIVE); + } + + Invalidate(/*clearPersistent=*/true); + SS.ScheduleShowTW(); +} + +bool GraphicsWindow::SuggestLineConstraint(hRequest request, Constraint::Type *type) { + if(!(LockedInWorkplane() && SS.automaticLineConstraints)) + return false; + + Entity *ptA = SK.GetEntity(request.entity(1)), + *ptB = SK.GetEntity(request.entity(2)); + + Expr *au, *av, *bu, *bv; + + ptA->PointGetExprsInWorkplane(ActiveWorkplane(), &au, &av); + ptB->PointGetExprsInWorkplane(ActiveWorkplane(), &bu, &bv); + + double du = au->Minus(bu)->Eval(); + double dv = av->Minus(bv)->Eval(); + + const double TOLERANCE_RATIO = 0.02; + if(fabs(dv) > LENGTH_EPS && fabs(du / dv) < TOLERANCE_RATIO) { + *type = Constraint::Type::VERTICAL; + return true; + } else if(fabs(du) > LENGTH_EPS && fabs(dv / du) < TOLERANCE_RATIO) { + *type = Constraint::Type::HORIZONTAL; + return true; + } + return false; +} diff --git a/src/group.cpp b/src/group.cpp new file mode 100644 index 0000000..1539e68 --- /dev/null +++ b/src/group.cpp @@ -0,0 +1,1174 @@ +//----------------------------------------------------------------------------- +// Implementation of the Group class, which represents a set of entities and +// constraints that are solved together, in some cases followed by another +// operation, like to extrude surfaces from the entities or to step and +// repeat them parametrically. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +const hParam Param::NO_PARAM = { 0 }; +#define NO_PARAM (Param::NO_PARAM) + +const hGroup Group::HGROUP_REFERENCES = { 1 }; + +//----------------------------------------------------------------------------- +// The group structure includes pointers to other dynamically-allocated +// memory. This clears and frees them all. +//----------------------------------------------------------------------------- +void Group::Clear() { + polyLoops.Clear(); + bezierLoops.Clear(); + bezierOpens.Clear(); + thisMesh.Clear(); + runningMesh.Clear(); + thisShell.Clear(); + runningShell.Clear(); + displayMesh.Clear(); + displayOutlines.Clear(); + impMesh.Clear(); + impShell.Clear(); + impEntity.Clear(); + // remap is the only one that doesn't get recreated when we regen + remap.clear(); +} + +void Group::AddParam(IdList *param, hParam hp, double v) { + Param pa = {}; + pa.h = hp; + pa.val = v; + + param->Add(&pa); +} + +bool Group::IsVisible() { + if(!visible) return false; + Group *active = SK.GetGroup(SS.GW.activeGroup); + if(order > active->order) return false; + return true; +} + +size_t Group::GetNumConstraints() { + return std::count_if(SK.constraint.begin(), SK.constraint.end(), + [&](Constraint const &c) { return c.group == h; }); +} + +Vector Group::ExtrusionGetVector() { + return Vector::From(h.param(0), h.param(1), h.param(2)); +} + +void Group::ExtrusionForceVectorTo(const Vector &v) { + SK.GetParam(h.param(0))->val = v.x; + SK.GetParam(h.param(1))->val = v.y; + SK.GetParam(h.param(2))->val = v.z; +} + +void Group::MenuGroup(Command id) { + MenuGroup(id, Platform::Path()); +} + +void Group::MenuGroup(Command id, Platform::Path linkFile) { + Platform::SettingsRef settings = Platform::GetSettings(); + + Group g = {}; + g.visible = true; + g.color = RGBi(100, 100, 100); + g.scale = 1; + g.linkFile = linkFile; + + SS.GW.GroupSelection(); + auto const &gs = SS.GW.gs; + + switch(id) { + case Command::GROUP_3D: + g.type = Type::DRAWING_3D; + g.name = C_("group-name", "sketch-in-3d"); + break; + + case Command::GROUP_WRKPL: + g.type = Type::DRAWING_WORKPLANE; + g.name = C_("group-name", "sketch-in-plane"); + if(gs.points == 1 && gs.n == 1) { + g.subtype = Subtype::WORKPLANE_BY_POINT_ORTHO; + + Vector u = SS.GW.projRight, v = SS.GW.projUp; + u = u.ClosestOrtho(); + v = v.Minus(u.ScaledBy(v.Dot(u))); + v = v.ClosestOrtho(); + + g.predef.q = Quaternion::From(u, v); + g.predef.origin = gs.point[0]; + } else if(gs.points == 1 && gs.lineSegments == 2 && gs.n == 3) { + g.subtype = Subtype::WORKPLANE_BY_LINE_SEGMENTS; + + g.predef.origin = gs.point[0]; + g.predef.entityB = gs.entity[0]; + g.predef.entityC = gs.entity[1]; + + Vector ut = SK.GetEntity(g.predef.entityB)->VectorGetNum(); + Vector vt = SK.GetEntity(g.predef.entityC)->VectorGetNum(); + ut = ut.WithMagnitude(1); + vt = vt.WithMagnitude(1); + + if(fabs(SS.GW.projUp.Dot(vt)) < fabs(SS.GW.projUp.Dot(ut))) { + swap(ut, vt); + g.predef.swapUV = true; + } + if(SS.GW.projRight.Dot(ut) < 0) g.predef.negateU = true; + if(SS.GW.projUp. Dot(vt) < 0) g.predef.negateV = true; + } else if(gs.workplanes == 1 && gs.n == 1) { + if(gs.entity[0].isFromRequest()) { + Entity *wrkpl = SK.GetEntity(gs.entity[0]); + Entity *normal = SK.GetEntity(wrkpl->normal); + g.subtype = Subtype::WORKPLANE_BY_POINT_ORTHO; + g.predef.origin = wrkpl->point[0]; + g.predef.q = normal->NormalGetNum(); + } else { + Group *wrkplg = SK.GetGroup(gs.entity[0].group()); + g.subtype = wrkplg->subtype; + g.predef.origin = wrkplg->predef.origin; + if(wrkplg->subtype == Subtype::WORKPLANE_BY_LINE_SEGMENTS) { + g.predef.entityB = wrkplg->predef.entityB; + g.predef.entityC = wrkplg->predef.entityC; + g.predef.swapUV = wrkplg->predef.swapUV; + g.predef.negateU = wrkplg->predef.negateU; + g.predef.negateV = wrkplg->predef.negateV; + } else if(wrkplg->subtype == Subtype::WORKPLANE_BY_POINT_ORTHO) { + g.predef.q = wrkplg->predef.q; + } else ssassert(false, "Unexpected workplane subtype"); + } + } else { + Error(_("Bad selection for new sketch in workplane. This " + "group can be created with:\n\n" + " * a point (through the point, orthogonal to coordinate axes)\n" + " * a point and two line segments (through the point, " + "parallel to the lines)\n" + " * a workplane (copy of the workplane)\n")); + return; + } + break; + + case Command::GROUP_EXTRUDE: + if(!SS.GW.LockedInWorkplane()) { + Error(_("Activate a workplane (Sketch -> In Workplane) before " + "extruding. The sketch will be extruded normal to the " + "workplane.")); + return; + } + g.type = Type::EXTRUDE; + g.opA = SS.GW.activeGroup; + g.predef.entityB = SS.GW.ActiveWorkplane(); + g.subtype = Subtype::ONE_SIDED; + g.name = C_("group-name", "extrude"); + break; + + case Command::GROUP_LATHE: + if(!SS.GW.LockedInWorkplane()) { + Error(_("Lathe operation can only be applied to planar sketches.")); + return; + } + if(gs.points == 1 && gs.vectors == 1 && gs.n == 2) { + g.predef.origin = gs.point[0]; + g.predef.entityB = gs.vector[0]; + } else if(gs.lineSegments == 1 && gs.n == 1) { + g.predef.origin = SK.GetEntity(gs.entity[0])->point[0]; + g.predef.entityB = gs.entity[0]; + // since a line segment is a vector + } else { + Error(_("Bad selection for new lathe group. This group can " + "be created with:\n\n" + " * a point and a line segment or normal " + "(revolved about an axis parallel to line / " + "normal, through point)\n" + " * a line segment (revolved about line segment)\n")); + return; + } + g.type = Type::LATHE; + g.opA = SS.GW.activeGroup; + g.name = C_("group-name", "lathe"); + break; + + case Command::GROUP_REVOLVE: + if(!SS.GW.LockedInWorkplane()) { + Error(_("Revolve operation can only be applied to planar sketches.")); + return; + } + if(gs.points == 1 && gs.vectors == 1 && gs.n == 2) { + g.predef.origin = gs.point[0]; + g.predef.entityB = gs.vector[0]; + } else if(gs.lineSegments == 1 && gs.n == 1) { + g.predef.origin = SK.GetEntity(gs.entity[0])->point[0]; + g.predef.entityB = gs.entity[0]; + // since a line segment is a vector + } else { + Error(_("Bad selection for new revolve group. This group can " + "be created with:\n\n" + " * a point and a line segment or normal " + "(revolved about an axis parallel to line / " + "normal, through point)\n" + " * a line segment (revolved about line segment)\n")); + return; + } + g.type = Type::REVOLVE; + g.opA = SS.GW.activeGroup; + g.valA = 2; + g.subtype = Subtype::ONE_SIDED; + g.name = C_("group-name", "revolve"); + break; + + case Command::GROUP_HELIX: + if(!SS.GW.LockedInWorkplane()) { + Error(_("Helix operation can only be applied to planar sketches.")); + return; + } + if(gs.points == 1 && gs.vectors == 1 && gs.n == 2) { + g.predef.origin = gs.point[0]; + g.predef.entityB = gs.vector[0]; + } else if(gs.lineSegments == 1 && gs.n == 1) { + g.predef.origin = SK.GetEntity(gs.entity[0])->point[0]; + g.predef.entityB = gs.entity[0]; + // since a line segment is a vector + } else { + Error(_("Bad selection for new helix group. This group can " + "be created with:\n\n" + " * a point and a line segment or normal " + "(revolved about an axis parallel to line / " + "normal, through point)\n" + " * a line segment (revolved about line segment)\n")); + return; + } + g.type = Type::HELIX; + g.opA = SS.GW.activeGroup; + g.valA = 2; + g.subtype = Subtype::ONE_SIDED; + g.name = C_("group-name", "helix"); + break; + + case Command::GROUP_ROT: { + if(gs.points == 1 && gs.n == 1 && SS.GW.LockedInWorkplane()) { + g.predef.origin = gs.point[0]; + Entity *w = SK.GetEntity(SS.GW.ActiveWorkplane()); + g.predef.entityB = w->Normal()->h; + g.activeWorkplane = w->h; + } else if(gs.points == 1 && gs.vectors == 1 && gs.n == 2) { + g.predef.origin = gs.point[0]; + g.predef.entityB = gs.vector[0]; + } else { + Error(_("Bad selection for new rotation. This group can " + "be created with:\n\n" + " * a point, while locked in workplane (rotate " + "in plane, about that point)\n" + " * a point and a line or a normal (rotate about " + "an axis through the point, and parallel to " + "line / normal)\n")); + return; + } + g.type = Type::ROTATE; + g.opA = SS.GW.activeGroup; + g.valA = 3; + g.subtype = Subtype::ONE_SIDED; + g.name = C_("group-name", "rotate"); + break; + } + + case Command::GROUP_TRANS: + g.type = Type::TRANSLATE; + g.opA = SS.GW.activeGroup; + g.valA = 3; + g.subtype = Subtype::ONE_SIDED; + g.predef.entityB = SS.GW.ActiveWorkplane(); + g.activeWorkplane = SS.GW.ActiveWorkplane(); + g.name = C_("group-name", "translate"); + break; + + case Command::GROUP_LINK: { + g.type = Type::LINKED; + g.meshCombine = CombineAs::ASSEMBLE; + if(g.linkFile.IsEmpty()) { + Platform::FileDialogRef dialog = Platform::CreateOpenFileDialog(SS.GW.window); + dialog->AddFilters(Platform::SolveSpaceLinkFileFilters); + dialog->ThawChoices(settings, "LinkSketch"); + if(!dialog->RunModal()) return; + dialog->FreezeChoices(settings, "LinkSketch"); + g.linkFile = dialog->GetFilename(); + } + + // Assign the default name of the group based on the name of + // the linked file. + g.name = g.linkFile.FileStem(); + for(size_t i = 0; i < g.name.length(); i++) { + if(!(isalnum(g.name[i]) || (unsigned)g.name[i] >= 0x80)) { + // convert punctuation to dashes + g.name[i] = '-'; + } + } + break; + } + + default: ssassert(false, "Unexpected menu ID"); + } + + // Copy color from the previous mesh-contributing group. + if(g.IsMeshGroup() && !SK.groupOrder.IsEmpty()) { + Group *running = SK.GetRunningMeshGroupFor(SS.GW.activeGroup); + if(running != NULL) { + g.color = running->color; + } + } + + SS.GW.ClearSelection(); + SS.UndoRemember(); + + bool afterActive = false; + for(hGroup hg : SK.groupOrder) { + Group *gi = SK.GetGroup(hg); + if(afterActive) + gi->order += 1; + if(gi->h == SS.GW.activeGroup) { + g.order = gi->order + 1; + afterActive = true; + } + } + + SK.group.AddAndAssignId(&g); + Group *gg = SK.GetGroup(g.h); + + if(gg->type == Type::LINKED) { + SS.ReloadAllLinked(SS.saveFile); + } + gg->clean = false; + SS.GW.activeGroup = gg->h; + SS.GenerateAll(); + if(gg->type == Type::DRAWING_WORKPLANE) { + // Can't set the active workplane for this one until after we've + // regenerated, because the workplane doesn't exist until then. + gg->activeWorkplane = gg->h.entity(0); + } + gg->Activate(); + TextWindow::ScreenSelectGroup(0, gg->h.v); + SS.GW.AnimateOntoWorkplane(); +} + +void Group::TransformImportedBy(Vector t, Quaternion q) { + ssassert(type == Type::LINKED, "Expected a linked group"); + + hParam tx, ty, tz, qw, qx, qy, qz; + tx = h.param(0); + ty = h.param(1); + tz = h.param(2); + qw = h.param(3); + qx = h.param(4); + qy = h.param(5); + qz = h.param(6); + + Quaternion qg = Quaternion::From(qw, qx, qy, qz); + qg = q.Times(qg); + + Vector tg = Vector::From(tx, ty, tz); + tg = tg.Plus(t); + + SK.GetParam(tx)->val = tg.x; + SK.GetParam(ty)->val = tg.y; + SK.GetParam(tz)->val = tg.z; + + SK.GetParam(qw)->val = qg.w; + SK.GetParam(qx)->val = qg.vx; + SK.GetParam(qy)->val = qg.vy; + SK.GetParam(qz)->val = qg.vz; +} + +bool Group::IsForcedToMeshBySource() const { + const Group *srcg = this; + if(type == Type::TRANSLATE || type == Type::ROTATE) { + // A step and repeat gets merged against the group's previous group, + // not our own previous group. + srcg = SK.GetGroup(opA); + if(srcg->forceToMesh) return true; + } + Group *g = srcg->RunningMeshGroup(); + if(g == NULL) return false; + return g->forceToMesh || g->IsForcedToMeshBySource(); +} + +bool Group::IsForcedToMesh() const { + return forceToMesh || IsForcedToMeshBySource(); +} + +std::string Group::DescriptionString() { + if(name.empty()) { + return ssprintf("g%03x-%s", h.v, _("(unnamed)")); + } else { + return ssprintf("g%03x-%s", h.v, name.c_str()); + } +} + +void Group::Activate() { + if(type == Type::EXTRUDE || type == Type::LINKED || type == Type::LATHE || + type == Type::REVOLVE || type == Type::HELIX || type == Type::TRANSLATE || type == Type::ROTATE) { + SS.GW.showFaces = true; + } else { + SS.GW.showFaces = false; + } + SS.MarkGroupDirty(h); // for good measure; shouldn't be needed + SS.ScheduleShowTW(); +} + +void Group::Generate(IdList *entity, + IdList *param) +{ + Vector gn = (SS.GW.projRight).Cross(SS.GW.projUp); + Vector gp = SS.GW.projRight.Plus(SS.GW.projUp); + Vector gc = (SS.GW.offset).ScaledBy(-1); + gn = gn.WithMagnitude(200/SS.GW.scale); + gp = gp.WithMagnitude(200/SS.GW.scale); + int a, i; + switch(type) { + case Type::DRAWING_3D: + return; + + case Type::DRAWING_WORKPLANE: { + Quaternion q; + if(subtype == Subtype::WORKPLANE_BY_LINE_SEGMENTS) { + Vector u = SK.GetEntity(predef.entityB)->VectorGetNum(); + Vector v = SK.GetEntity(predef.entityC)->VectorGetNum(); + u = u.WithMagnitude(1); + Vector n = u.Cross(v); + v = (n.Cross(u)).WithMagnitude(1); + + if(predef.swapUV) swap(u, v); + if(predef.negateU) u = u.ScaledBy(-1); + if(predef.negateV) v = v.ScaledBy(-1); + q = Quaternion::From(u, v); + } else if(subtype == Subtype::WORKPLANE_BY_POINT_ORTHO) { + // Already given, numerically. + q = predef.q; + } else ssassert(false, "Unexpected workplane subtype"); + + Entity normal = {}; + normal.type = Entity::Type::NORMAL_N_COPY; + normal.numNormal = q; + normal.point[0] = h.entity(2); + normal.group = h; + normal.h = h.entity(1); + entity->Add(&normal); + + Entity point = {}; + point.type = Entity::Type::POINT_N_COPY; + point.numPoint = SK.GetEntity(predef.origin)->PointGetNum(); + point.construction = true; + point.group = h; + point.h = h.entity(2); + entity->Add(&point); + + Entity wp = {}; + wp.type = Entity::Type::WORKPLANE; + wp.normal = normal.h; + wp.point[0] = point.h; + wp.group = h; + wp.h = h.entity(0); + entity->Add(&wp); + return; + } + + case Type::EXTRUDE: { + AddParam(param, h.param(0), gn.x); + AddParam(param, h.param(1), gn.y); + AddParam(param, h.param(2), gn.z); + int ai, af; + if(subtype == Subtype::ONE_SIDED) { + ai = 0; af = 2; + } else if(subtype == Subtype::TWO_SIDED) { + ai = -1; af = 1; + } else ssassert(false, "Unexpected extrusion subtype"); + + // Get some arbitrary point in the sketch, that will be used + // as a reference when defining top and bottom faces. + hEntity pt = { 0 }; + // Not using range-for here because we're changing the size of entity in the loop. + for(i = 0; i < entity->n; i++) { + Entity *e = &(entity->Get(i)); + if(e->group != opA) continue; + + if(e->IsPoint()) pt = e->h; + + e->CalculateNumerical(/*forExport=*/false); + hEntity he = e->h; e = NULL; + // As soon as I call CopyEntity, e may become invalid! That + // adds entities, which may cause a realloc. + CopyEntity(entity, SK.GetEntity(he), ai, REMAP_BOTTOM, + h.param(0), h.param(1), h.param(2), + NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, + CopyAs::N_TRANS); + CopyEntity(entity, SK.GetEntity(he), af, REMAP_TOP, + h.param(0), h.param(1), h.param(2), + NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, + CopyAs::N_TRANS); + MakeExtrusionLines(entity, he); + } + // Remapped versions of that arbitrary point will be used to + // provide points on the plane faces. + MakeExtrusionTopBottomFaces(entity, pt); + return; + } + + case Type::LATHE: { + Vector axis_pos = SK.GetEntity(predef.origin)->PointGetNum(); + Vector axis_dir = SK.GetEntity(predef.entityB)->VectorGetNum(); + + // Not using range-for here because we're changing the size of entity in the loop. + for(i = 0; i < entity->n; i++) { + Entity *e = &(entity->Get(i)); + if(e->group != opA) continue; + + e->CalculateNumerical(/*forExport=*/false); + hEntity he = e->h; + + // As soon as I call CopyEntity, e may become invalid! That + // adds entities, which may cause a realloc. + + // this is the regular copy of all entities + CopyEntity(entity, SK.GetEntity(he), 0, REMAP_LATHE_START, + NO_PARAM, NO_PARAM, NO_PARAM, + NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, + CopyAs::NUMERIC); + + e = &(entity->Get(i)); // because we copied. + if (e->IsPoint()) { + // for points this copy is used for the circle centers + CopyEntity(entity, SK.GetEntity(he), 0, REMAP_LATHE_ARC_CENTER, + NO_PARAM, NO_PARAM, NO_PARAM, + NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, + CopyAs::NUMERIC); + MakeLatheCircles(entity, param, he, axis_pos, axis_dir); + }; + MakeLatheSurfacesSelectable(entity, he, axis_dir); + } + return; + } + + case Type::REVOLVE: { + // this was borrowed from LATHE and ROTATE + Vector axis_pos = SK.GetEntity(predef.origin)->PointGetNum(); + Vector axis_dir = SK.GetEntity(predef.entityB)->VectorGetNum(); + + // The center of rotation + AddParam(param, h.param(0), axis_pos.x); + AddParam(param, h.param(1), axis_pos.y); + AddParam(param, h.param(2), axis_pos.z); + // The rotation quaternion + AddParam(param, h.param(3), 30 * PI / 180); + AddParam(param, h.param(4), axis_dir.x); + AddParam(param, h.param(5), axis_dir.y); + AddParam(param, h.param(6), axis_dir.z); + + // Get some arbitrary point in the sketch, that will be used + // as a reference when defining end faces. + hEntity pt = { 0 }; + + int ai = 0, af = 2; + if (subtype == Subtype::TWO_SIDED) + { + ai = -1; + af = 1; + } + // Not using range-for here because we're changing the size of entity in the loop. + for(i = 0; i < entity->n; i++) { + Entity *e = &(entity->Get(i)); + if(e->group != opA) + continue; + + if(e->IsPoint()) pt = e->h; + + e->CalculateNumerical(/*forExport=*/false); + hEntity he = e->h; + // one copy for each end of the revolved surface + CopyEntity(entity, e, ai, REMAP_LATHE_START, h.param(0), + h.param(1), h.param(2), h.param(3), h.param(4), h.param(5), + h.param(6), NO_PARAM, CopyAs::N_ROT_AA); + + e = &(entity->Get(i)); // because we copied. + CopyEntity(entity, e, af, REMAP_LATHE_END, h.param(0), + h.param(1), h.param(2), h.param(3), h.param(4), h.param(5), + h.param(6), NO_PARAM, CopyAs::N_ROT_AA); + + // Arcs are not generated for revolve groups, for now, because our current arc + // entity is not chiral, and dragging a revolve may break the arc by inverting it. + // MakeLatheCircles(entity, param, he, axis_pos, axis_dir); + MakeLatheSurfacesSelectable(entity, he, axis_dir); + } + MakeRevolveEndFaces(entity, pt, ai, af); + return; + } + + case Type::HELIX: { + Vector axis_pos = SK.GetEntity(predef.origin)->PointGetNum(); + Vector axis_dir = SK.GetEntity(predef.entityB)->VectorGetNum(); + + // The center of rotation + AddParam(param, h.param(0), axis_pos.x); + AddParam(param, h.param(1), axis_pos.y); + AddParam(param, h.param(2), axis_pos.z); + // The rotation quaternion + AddParam(param, h.param(3), 30 * PI / 180); + AddParam(param, h.param(4), axis_dir.x); + AddParam(param, h.param(5), axis_dir.y); + AddParam(param, h.param(6), axis_dir.z); + // distance to translate along the rotation axis + AddParam(param, h.param(7), 20); + + // Get some arbitrary point in the sketch, that will be used + // as a reference when defining end faces. + hEntity pt = { 0 }; + + int ai = 0, af = 2; // initial and final number of transformations + if (subtype != Subtype::ONE_SIDED) + { + ai = -1; + af = 1; + } + + // Not using range-for here because we're changing the size of entity in the loop. + for(i = 0; i < entity->n; i++) { + Entity *e = &(entity->Get(i)); + if((e->group.v != opA.v) && !(e->h == predef.origin)) + continue; + + if(e->IsPoint()) pt = e->h; + + e->CalculateNumerical(/*forExport=*/false); + + // one copy for each end of the helix + CopyEntity(entity, e, ai, REMAP_LATHE_START, h.param(0), + h.param(1), h.param(2), h.param(3), h.param(4), h.param(5), + h.param(6), h.param(7), CopyAs::N_ROT_AXIS_TRANS); + + e = &(entity->Get(i)); // because we copied. + CopyEntity(entity, e, af, REMAP_LATHE_END, h.param(0), + h.param(1), h.param(2), h.param(3), h.param(4), h.param(5), + h.param(6), h.param(7), CopyAs::N_ROT_AXIS_TRANS); + + // For point entities on the axis, create a construction line + e = &(entity->Get(i)); + if(e->IsPoint()) { + Vector check = e->PointGetNum().Minus(axis_pos).Cross(axis_dir); + if (check.Dot(check) < LENGTH_EPS) { + //! @todo isn't this the same as &(ent[i])? + Entity *ep = SK.GetEntity(e->h); + Entity en = {}; + // A point gets extruded to form a line segment + en.point[0] = Remap(ep->h, REMAP_LATHE_START); + en.point[1] = Remap(ep->h, REMAP_LATHE_END); + en.group = h; + en.construction = ep->construction; + en.style = ep->style; + en.h = Remap(ep->h, REMAP_PT_TO_LINE); + en.type = Entity::Type::LINE_SEGMENT; + entity->Add(&en); + } + } + } + MakeRevolveEndFaces(entity, pt, ai, af); + return; + } + + case Type::TRANSLATE: { + // inherit meshCombine from source group + Group *srcg = SK.GetGroup(opA); + meshCombine = srcg->meshCombine; + // The translation vector + AddParam(param, h.param(0), gp.x); + AddParam(param, h.param(1), gp.y); + AddParam(param, h.param(2), gp.z); + + int n = (int)valA, a0 = 0; + if(subtype == Subtype::ONE_SIDED && skipFirst) { + a0++; n++; + } + + for(a = a0; a < n; a++) { + // Not using range-for here because we're changing the size of entity in the loop. + for(i = 0; i < entity->n; i++) { + Entity *e = &(entity->Get(i)); + if(e->group != opA) continue; + + e->CalculateNumerical(/*forExport=*/false); + CopyEntity(entity, e, + a*2 - (subtype == Subtype::ONE_SIDED ? 0 : (n-1)), + (a == (n - 1)) ? REMAP_LAST : a, + h.param(0), h.param(1), h.param(2), + NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, NO_PARAM, + CopyAs::N_TRANS); + } + } + return; + } + case Type::ROTATE: { + // inherit meshCombine from source group + Group *srcg = SK.GetGroup(opA); + meshCombine = srcg->meshCombine; + // The center of rotation + AddParam(param, h.param(0), gc.x); + AddParam(param, h.param(1), gc.y); + AddParam(param, h.param(2), gc.z); + // The rotation quaternion + AddParam(param, h.param(3), 30*PI/180); + AddParam(param, h.param(4), gn.x); + AddParam(param, h.param(5), gn.y); + AddParam(param, h.param(6), gn.z); + + int n = (int)valA, a0 = 0; + if(subtype == Subtype::ONE_SIDED && skipFirst) { + a0++; n++; + } + + for(a = a0; a < n; a++) { + // Not using range-for here because we're changing the size of entity in the loop. + for(i = 0; i < entity->n; i++) { + Entity *e = &(entity->Get(i)); + if(e->group != opA) continue; + + e->CalculateNumerical(/*forExport=*/false); + CopyEntity(entity, e, + a*2 - (subtype == Subtype::ONE_SIDED ? 0 : (n-1)), + (a == (n - 1)) ? REMAP_LAST : a, + h.param(0), h.param(1), h.param(2), + h.param(3), h.param(4), h.param(5), h.param(6), NO_PARAM, + CopyAs::N_ROT_AA); + } + } + return; + } + case Type::LINKED: + // The translation vector + AddParam(param, h.param(0), gp.x); + AddParam(param, h.param(1), gp.y); + AddParam(param, h.param(2), gp.z); + // The rotation quaternion + AddParam(param, h.param(3), 1); + AddParam(param, h.param(4), 0); + AddParam(param, h.param(5), 0); + AddParam(param, h.param(6), 0); + + // Not using range-for here because we're changing the size of entity in the loop. + for(i = 0; i < impEntity.n; i++) { + Entity *ie = &(impEntity[i]); + CopyEntity(entity, ie, 0, 0, + h.param(0), h.param(1), h.param(2), + h.param(3), h.param(4), h.param(5), h.param(6), NO_PARAM, + CopyAs::N_ROT_TRANS); + } + return; + } + ssassert(false, "Unexpected group type"); +} + +bool Group::IsSolvedOkay() { + return this->solved.how == SolveResult::OKAY || + (this->allowRedundant && this->solved.how == SolveResult::REDUNDANT_OKAY); +} + +void Group::AddEq(IdList *l, Expr *expr, int index) { + Equation eq; + eq.e = expr; + eq.h = h.equation(index); + l->Add(&eq); +} + +void Group::GenerateEquations(IdList *l) { + if(type == Type::LINKED) { + // Normalize the quaternion + ExprQuaternion q = { + Expr::From(h.param(3)), + Expr::From(h.param(4)), + Expr::From(h.param(5)), + Expr::From(h.param(6)) }; + AddEq(l, (q.Magnitude())->Minus(Expr::From(1)), 0); + } else if(type == Type::ROTATE || type == Type::REVOLVE || type == Type::HELIX) { + // The axis and center of rotation are specified numerically +#define EC(x) (Expr::From(x)) +#define EP(x) (Expr::From(h.param(x))) + ExprVector orig = SK.GetEntity(predef.origin)->PointGetExprs(); + AddEq(l, (orig.x)->Minus(EP(0)), 0); + AddEq(l, (orig.y)->Minus(EP(1)), 1); + AddEq(l, (orig.z)->Minus(EP(2)), 2); + // param 3 is the angle, which is free + Vector axis = SK.GetEntity(predef.entityB)->VectorGetNum(); + axis = axis.WithMagnitude(1); + AddEq(l, (EC(axis.x))->Minus(EP(4)), 3); + AddEq(l, (EC(axis.y))->Minus(EP(5)), 4); + AddEq(l, (EC(axis.z))->Minus(EP(6)), 5); +#undef EC +#undef EP + } else if(type == Type::EXTRUDE) { + if(predef.entityB != Entity::FREE_IN_3D) { + // The extrusion path is locked along a line, normal to the + // specified workplane. + Entity *w = SK.GetEntity(predef.entityB); + ExprVector u = w->Normal()->NormalExprsU(); + ExprVector v = w->Normal()->NormalExprsV(); + ExprVector extruden = { + Expr::From(h.param(0)), + Expr::From(h.param(1)), + Expr::From(h.param(2)) }; + + AddEq(l, u.Dot(extruden), 0); + AddEq(l, v.Dot(extruden), 1); + } + } else if(type == Type::TRANSLATE) { + if(predef.entityB != Entity::FREE_IN_3D) { + Entity *w = SK.GetEntity(predef.entityB); + ExprVector n = w->Normal()->NormalExprsN(); + ExprVector trans; + trans = ExprVector::From(h.param(0), h.param(1), h.param(2)); + + // The translation vector is parallel to the workplane + AddEq(l, trans.Dot(n), 0); + } + } +} + +hEntity Group::Remap(hEntity in, int copyNumber) { + auto it = remap.find({ in, copyNumber }); + if(it == remap.end()) { + std::tie(it, std::ignore) = + remap.insert({ { in, copyNumber }, { (uint32_t)remap.size() + 1 } }); + } + return h.entity(it->second.v); +} + +void Group::MakeExtrusionLines(IdList *el, hEntity in) { + Entity *ep = SK.GetEntity(in); + + Entity en = {}; + if(ep->IsPoint()) { + // A point gets extruded to form a line segment + en.point[0] = Remap(ep->h, REMAP_TOP); + en.point[1] = Remap(ep->h, REMAP_BOTTOM); + en.group = h; + en.construction = ep->construction; + en.style = ep->style; + en.h = Remap(ep->h, REMAP_PT_TO_LINE); + en.type = Entity::Type::LINE_SEGMENT; + el->Add(&en); + } else if(ep->type == Entity::Type::LINE_SEGMENT) { + // A line gets extruded to form a plane face; an endpoint of the + // original line is a point in the plane, and the line is in the plane. + Vector a = SK.GetEntity(ep->point[0])->PointGetNum(); + Vector b = SK.GetEntity(ep->point[1])->PointGetNum(); + Vector ab = b.Minus(a); + + en.param[0] = h.param(0); + en.param[1] = h.param(1); + en.param[2] = h.param(2); + en.numPoint = a; + en.numNormal = Quaternion::From(0, ab.x, ab.y, ab.z); + + en.group = h; + en.construction = ep->construction; + en.style = ep->style; + en.h = Remap(ep->h, REMAP_LINE_TO_FACE); + en.type = Entity::Type::FACE_XPROD; + el->Add(&en); + } +} + +void Group::MakeLatheCircles(IdList *el, IdList *param, hEntity in, Vector pt, Vector axis) { + Entity *ep = SK.GetEntity(in); + + Entity en = {}; + if(ep->IsPoint()) { + // A point gets revolved to form an arc. + en.point[0] = Remap(ep->h, REMAP_LATHE_ARC_CENTER); + en.point[1] = Remap(ep->h, REMAP_LATHE_START); + en.point[2] = en.point[1]; //Remap(ep->h, REMAP_LATHE_END); + + // Get arc center and point on arc. + Entity *pc = SK.GetEntity(en.point[0]); + Entity *pp = SK.GetEntity(en.point[1]); + + // Project arc point to the revolution axis and use it for arc center. + double k = pp->numPoint.Minus(pt).Dot(axis) / axis.Dot(axis); + pc->numPoint = pt.Plus(axis.ScaledBy(k)); + + // Create arc entity. + en.group = h; + en.construction = ep->construction; + en.style = ep->style; + en.h = Remap(ep->h, REMAP_PT_TO_ARC); + en.type = Entity::Type::ARC_OF_CIRCLE; + + // Generate a normal. + Entity n = {}; + n.workplane = en.workplane; + n.h = Remap(ep->h, REMAP_PT_TO_NORMAL); + n.group = en.group; + n.style = en.style; + n.type = Entity::Type::NORMAL_N_COPY; + + // Create basis for the normal. + Vector nu = pp->numPoint.Minus(pc->numPoint).WithMagnitude(1.0); + Vector nv = nu.Cross(axis).WithMagnitude(1.0); + n.numNormal = Quaternion::From(nv, nu); + + // The point determines where the normal gets displayed on-screen; + // it's entirely cosmetic. + n.point[0] = en.point[0]; + el->Add(&n); + en.normal = n.h; + el->Add(&en); + } +} + +void Group::MakeLatheSurfacesSelectable(IdList *el, hEntity in, Vector axis) { + Entity *ep = SK.GetEntity(in); + + Entity en = {}; + if(ep->type == Entity::Type::LINE_SEGMENT) { + // An axis-perpendicular line gets revolved to form a face. + Vector a = SK.GetEntity(ep->point[0])->PointGetNum(); + Vector b = SK.GetEntity(ep->point[1])->PointGetNum(); + Vector u = b.Minus(a).WithMagnitude(1.0); + + // Check for perpendicularity: calculate cosine of the angle + // between axis and line direction and check that + // cos(angle) == 0 <-> angle == +-90 deg. + if(fabs(u.Dot(axis) / axis.Magnitude()) < ANGLE_COS_EPS) { + en.param[0] = h.param(0); + en.param[1] = h.param(1); + en.param[2] = h.param(2); + Vector v = axis.Cross(u).WithMagnitude(1.0); + Vector n = u.Cross(v); + en.numNormal = Quaternion::From(0, n.x, n.y, n.z); + + en.group = h; + en.construction = ep->construction; + en.style = ep->style; + en.h = Remap(ep->h, REMAP_LINE_TO_FACE); + en.type = Entity::Type::FACE_NORMAL_PT; + en.point[0] = ep->point[0]; + el->Add(&en); + } + } +} + +// For Revolve and Helix groups the end faces are remapped from an arbitrary +// point on the sketch. We reference the transformed point but there is +// no existing normal so we need to define the rotation and timesApplied. +void Group::MakeRevolveEndFaces(IdList *el, hEntity pt, int ai, int af) +{ + if(pt.v == 0) return; + Group *src = SK.GetGroup(opA); + Vector n = src->polyLoops.normal; + + // When there is no loop normal (e.g. if the loop is broken), use normal of workplane + // as fallback, to avoid breaking constraints depending on the faces. + if(n.Equals(Vector::From(0.0, 0.0, 0.0)) && src->type == Group::Type::DRAWING_WORKPLANE) { + n = SK.GetEntity(src->h.entity(0))->Normal()->NormalN(); + } + + Entity en = {}; + en.type = Entity::Type::FACE_ROT_NORMAL_PT; + en.group = h; + // The center of rotation + en.param[0] = h.param(0); + en.param[1] = h.param(1); + en.param[2] = h.param(2); + // The rotation quaternion + en.param[3] = h.param(3); + en.param[4] = h.param(4); + en.param[5] = h.param(5); + en.param[6] = h.param(6); + + en.numNormal = Quaternion::From(0, n.x, n.y, n.z); + en.point[0] = Remap(pt, REMAP_LATHE_START); + en.timesApplied = ai; + en.h = Remap(Entity::NO_ENTITY, REMAP_LATHE_START); + el->Add(&en); + + en.point[0] = Remap(pt, REMAP_LATHE_END); + en.timesApplied = af; + en.h = Remap(Entity::NO_ENTITY, REMAP_LATHE_END); + el->Add(&en); +} + +void Group::MakeExtrusionTopBottomFaces(IdList *el, hEntity pt) +{ + if(pt.v == 0) return; + Group *src = SK.GetGroup(opA); + Vector n = src->polyLoops.normal; + + // When there is no loop normal (e.g. if the loop is broken), use normal of workplane + // as fallback, to avoid breaking constraints depending on the faces. + if(n.Equals(Vector::From(0.0, 0.0, 0.0)) && src->type == Group::Type::DRAWING_WORKPLANE) { + n = SK.GetEntity(src->h.entity(0))->Normal()->NormalN(); + } + + Entity en = {}; + en.type = Entity::Type::FACE_NORMAL_PT; + en.group = h; + + en.numNormal = Quaternion::From(0, n.x, n.y, n.z); + en.point[0] = Remap(pt, REMAP_TOP); + en.h = Remap(Entity::NO_ENTITY, REMAP_TOP); + el->Add(&en); + + en.point[0] = Remap(pt, REMAP_BOTTOM); + en.h = Remap(Entity::NO_ENTITY, REMAP_BOTTOM); + el->Add(&en); +} + +void Group::CopyEntity(IdList *el, + Entity *ep, int timesApplied, int remap, + hParam dx, hParam dy, hParam dz, + hParam qw, hParam qvx, hParam qvy, hParam qvz, hParam dist, + CopyAs as) +{ + Entity en = {}; + en.type = ep->type; + en.extraPoints = ep->extraPoints; + en.h = Remap(ep->h, remap); + en.timesApplied = timesApplied; + en.group = h; + en.construction = ep->construction; + en.style = ep->style; + en.str = ep->str; + en.font = ep->font; + en.file = ep->file; + + switch(ep->type) { + case Entity::Type::WORKPLANE: + // Don't copy these. + return; + + case Entity::Type::POINT_N_COPY: + case Entity::Type::POINT_N_TRANS: + case Entity::Type::POINT_N_ROT_TRANS: + case Entity::Type::POINT_N_ROT_AA: + case Entity::Type::POINT_N_ROT_AXIS_TRANS: + case Entity::Type::POINT_IN_3D: + case Entity::Type::POINT_IN_2D: + if(as == CopyAs::N_TRANS) { + en.type = Entity::Type::POINT_N_TRANS; + en.param[0] = dx; + en.param[1] = dy; + en.param[2] = dz; + } else if(as == CopyAs::NUMERIC) { + en.type = Entity::Type::POINT_N_COPY; + } else { + if(as == CopyAs::N_ROT_AA) { + en.type = Entity::Type::POINT_N_ROT_AA; + } else if (as == CopyAs::N_ROT_AXIS_TRANS) { + en.type = Entity::Type::POINT_N_ROT_AXIS_TRANS; + } else { + en.type = Entity::Type::POINT_N_ROT_TRANS; + } + en.param[0] = dx; + en.param[1] = dy; + en.param[2] = dz; + en.param[3] = qw; + en.param[4] = qvx; + en.param[5] = qvy; + en.param[6] = qvz; + if (as == CopyAs::N_ROT_AXIS_TRANS) { + en.param[7] = dist; + } + } + en.numPoint = (ep->actPoint).ScaledBy(scale); + break; + + case Entity::Type::NORMAL_N_COPY: + case Entity::Type::NORMAL_N_ROT: + case Entity::Type::NORMAL_N_ROT_AA: + case Entity::Type::NORMAL_IN_3D: + case Entity::Type::NORMAL_IN_2D: + if(as == CopyAs::N_TRANS || as == CopyAs::NUMERIC) { + en.type = Entity::Type::NORMAL_N_COPY; + } else { // N_ROT_AXIS_TRANS probably doesn't warrant a new entity Type + if(as == CopyAs::N_ROT_AA || as == CopyAs::N_ROT_AXIS_TRANS) { + en.type = Entity::Type::NORMAL_N_ROT_AA; + } else { + en.type = Entity::Type::NORMAL_N_ROT; + } + en.param[0] = qw; + en.param[1] = qvx; + en.param[2] = qvy; + en.param[3] = qvz; + } + en.numNormal = ep->actNormal; + if(scale < 0) en.numNormal = en.numNormal.Mirror(); + + en.point[0] = Remap(ep->point[0], remap); + break; + + case Entity::Type::DISTANCE_N_COPY: + case Entity::Type::DISTANCE: + en.type = Entity::Type::DISTANCE_N_COPY; + en.numDistance = ep->actDistance*fabs(scale); + break; + + case Entity::Type::FACE_NORMAL_PT: + case Entity::Type::FACE_XPROD: + case Entity::Type::FACE_N_ROT_TRANS: + case Entity::Type::FACE_N_TRANS: + case Entity::Type::FACE_N_ROT_AA: + case Entity::Type::FACE_ROT_NORMAL_PT: + case Entity::Type::FACE_N_ROT_AXIS_TRANS: + if(as == CopyAs::N_TRANS) { + en.type = Entity::Type::FACE_N_TRANS; + en.param[0] = dx; + en.param[1] = dy; + en.param[2] = dz; + } else if (as == CopyAs::NUMERIC) { + en.type = Entity::Type::FACE_NORMAL_PT; + } else if (as == CopyAs::N_ROT_AXIS_TRANS) { + en.type = Entity::Type::FACE_N_ROT_AXIS_TRANS; + en.param[0] = dx; + en.param[1] = dy; + en.param[2] = dz; + en.param[3] = qw; + en.param[4] = qvx; + en.param[5] = qvy; + en.param[6] = qvz; + en.param[7] = dist; + } else { + if(as == CopyAs::N_ROT_AA) { + en.type = Entity::Type::FACE_N_ROT_AA; + } else { + en.type = Entity::Type::FACE_N_ROT_TRANS; + } + en.param[0] = dx; + en.param[1] = dy; + en.param[2] = dz; + en.param[3] = qw; + en.param[4] = qvx; + en.param[5] = qvy; + en.param[6] = qvz; + } + en.numPoint = (ep->actPoint).ScaledBy(scale); + en.numNormal = (ep->actNormal).ScaledBy(scale); + break; + + default: { + int i, points; + bool hasNormal, hasDistance; + EntReqTable::GetEntityInfo(ep->type, ep->extraPoints, + NULL, &points, &hasNormal, &hasDistance); + for(i = 0; i < points; i++) { + en.point[i] = Remap(ep->point[i], remap); + } + if(hasNormal) en.normal = Remap(ep->normal, remap); + if(hasDistance) en.distance = Remap(ep->distance, remap); + break; + } + } + + // If the entity came from an linked file where it was invisible then + // ep->actiVisble will be false, and we should hide it. Or if the entity + // came from a copy (e.g. step and repeat) of a force-hidden linked + // entity, then we also want to hide it. + en.forceHidden = (!ep->actVisible) || ep->forceHidden; + + el->Add(&en); +} + diff --git a/src/groupmesh.cpp b/src/groupmesh.cpp new file mode 100644 index 0000000..f1041d6 --- /dev/null +++ b/src/groupmesh.cpp @@ -0,0 +1,799 @@ +//----------------------------------------------------------------------------- +// Routines to generate our watertight brep shells from the operations +// and entities specified by the user in each group; templated to work either +// on an SShell of ratpoly surfaces or on an SMesh of triangles. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +void Group::AssembleLoops(bool *allClosed, + bool *allCoplanar, + bool *allNonZeroLen) +{ + SBezierList sbl = {}; + + int i; + for(auto &e : SK.entity) { + if(e.group != h) + continue; + if(e.construction) + continue; + if(e.forceHidden) + continue; + + e.GenerateBezierCurves(&sbl); + } + + SBezier *sb; + *allNonZeroLen = true; + for(sb = sbl.l.First(); sb; sb = sbl.l.NextAfter(sb)) { + for(i = 1; i <= sb->deg; i++) { + if(!(sb->ctrl[i]).Equals(sb->ctrl[0])) { + break; + } + } + if(i > sb->deg) { + // This is a zero-length edge. + *allNonZeroLen = false; + polyError.errorPointAt = sb->ctrl[0]; + goto done; + } + } + + // Try to assemble all these Beziers into loops. The closed loops go into + // bezierLoops, with the outer loops grouped with their holes. The + // leftovers, if any, go in bezierOpens. + bezierLoops.FindOuterFacesFrom(&sbl, &polyLoops, NULL, + SS.ChordTolMm(), + allClosed, &(polyError.notClosedAt), + allCoplanar, &(polyError.errorPointAt), + &bezierOpens); + done: + sbl.Clear(); +} + +void Group::GenerateLoops() { + polyLoops.Clear(); + bezierLoops.Clear(); + bezierOpens.Clear(); + + if(type == Type::DRAWING_3D || type == Type::DRAWING_WORKPLANE || + type == Type::ROTATE || type == Type::TRANSLATE || type == Type::LINKED) + { + bool allClosed = false, allCoplanar = false, allNonZeroLen = false; + AssembleLoops(&allClosed, &allCoplanar, &allNonZeroLen); + if(!allNonZeroLen) { + polyError.how = PolyError::ZERO_LEN_EDGE; + } else if(!allCoplanar) { + polyError.how = PolyError::NOT_COPLANAR; + } else if(!allClosed) { + polyError.how = PolyError::NOT_CLOSED; + } else { + polyError.how = PolyError::GOOD; + // The self-intersecting check is kind of slow, so don't run it + // unless requested. + if(SS.checkClosedContour) { + if(polyLoops.SelfIntersecting(&(polyError.errorPointAt))) { + polyError.how = PolyError::SELF_INTERSECTING; + } + } + } + } +} + +void SShell::RemapFaces(Group *g, int remap) { + SSurface *ss; + for(ss = surface.First(); ss; ss = surface.NextAfter(ss)){ + hEntity face = { ss->face }; + if(face == Entity::NO_ENTITY) continue; + + face = g->Remap(face, remap); + ss->face = face.v; + } +} + +void SMesh::RemapFaces(Group *g, int remap) { + STriangle *tr; + for(tr = l.First(); tr; tr = l.NextAfter(tr)) { + hEntity face = { tr->meta.face }; + if(face == Entity::NO_ENTITY) continue; + + face = g->Remap(face, remap); + tr->meta.face = face.v; + } +} + +template +void Group::GenerateForStepAndRepeat(T *steps, T *outs, Group::CombineAs forWhat) { + + int n = (int)valA, a0 = 0; + if(subtype == Subtype::ONE_SIDED && skipFirst) { + a0++; n++; + } + + int a; + // create all the transformed copies + std::vector transd(n); + std::vector workA(n); + workA[0] = {}; + // first generate a shell/mesh with each transformed copy +#pragma omp parallel for + for(a = a0; a < n; a++) { + transd[a] = {}; + workA[a] = {}; + int ap = a*2 - (subtype == Subtype::ONE_SIDED ? 0 : (n-1)); + + if(type == Type::TRANSLATE) { + Vector trans = Vector::From(h.param(0), h.param(1), h.param(2)); + trans = trans.ScaledBy(ap); + transd[a].MakeFromTransformationOf(steps, + trans, Quaternion::IDENTITY, 1.0); + } else { + Vector trans = Vector::From(h.param(0), h.param(1), h.param(2)); + double theta = ap * SK.GetParam(h.param(3))->val; + double c = cos(theta), s = sin(theta); + Vector axis = Vector::From(h.param(4), h.param(5), h.param(6)); + Quaternion q = Quaternion::From(c, s*axis.x, s*axis.y, s*axis.z); + // Rotation is centered at t; so A(x - t) + t = Ax + (t - At) + transd[a].MakeFromTransformationOf(steps, + trans.Minus(q.Rotate(trans)), q, 1.0); + } + } + for(a = a0; a < n; a++) { + // We need to rewrite any plane face entities to the transformed ones. + int remap = (a == (n - 1)) ? REMAP_LAST : a; + transd[a].RemapFaces(this, remap); + } + + std::vector *soFar = &transd; + std::vector *scratch = &workA; + // do the boolean operations on pairs of equal size + while(n > 1) { + for(a = 0; a < n; a+=2) { + scratch->at(a/2).Clear(); + // combine a pair of shells + if((a==0) && (a0==1)) { // if the first was skipped just copy the 2nd + scratch->at(a/2).MakeFromCopyOf(&(soFar->at(a+1))); + (soFar->at(a+1)).Clear(); + a0 = 0; + } else if (a == n-1) { // for an odd number just copy the last one + scratch->at(a/2).MakeFromCopyOf(&(soFar->at(a))); + (soFar->at(a)).Clear(); + } else if(forWhat == CombineAs::ASSEMBLE) { + scratch->at(a/2).MakeFromAssemblyOf(&(soFar->at(a)), &(soFar->at(a+1))); + (soFar->at(a)).Clear(); + (soFar->at(a+1)).Clear(); + } else { + scratch->at(a/2).MakeFromUnionOf(&(soFar->at(a)), &(soFar->at(a+1))); + (soFar->at(a)).Clear(); + (soFar->at(a+1)).Clear(); + } + } + swap(scratch, soFar); + n = (n+1)/2; + } + outs->Clear(); + *outs = soFar->at(0); +} + +template +void Group::GenerateForBoolean(T *prevs, T *thiss, T *outs, Group::CombineAs how) { + // If this group contributes no new mesh, then our running mesh is the + // same as last time, no combining required. Likewise if we have a mesh + // but it's suppressed. + if(thiss->IsEmpty() || suppress) { + outs->MakeFromCopyOf(prevs); + return; + } + + // So our group's shell appears in thisShell. Combine this with the + // previous group's shell, using the requested operation. + switch(how) { + case CombineAs::UNION: + outs->MakeFromUnionOf(prevs, thiss); + break; + + case CombineAs::DIFFERENCE: + outs->MakeFromDifferenceOf(prevs, thiss); + break; + + case CombineAs::INTERSECTION: + outs->MakeFromIntersectionOf(prevs, thiss); + break; + + case CombineAs::ASSEMBLE: + outs->MakeFromAssemblyOf(prevs, thiss); + break; + } +} + +void Group::GenerateShellAndMesh() { + bool prevBooleanFailed = booleanFailed; + booleanFailed = false; + + Group *srcg = this; + + thisShell.Clear(); + thisMesh.Clear(); + runningShell.Clear(); + runningMesh.Clear(); + + // Don't attempt a lathe or extrusion unless the source section is good: + // planar and not self-intersecting. + bool haveSrc = true; + if(type == Type::EXTRUDE || type == Type::LATHE || type == Type::REVOLVE) { + Group *src = SK.GetGroup(opA); + if(src->polyError.how != PolyError::GOOD) { + haveSrc = false; + } + } + + if(type == Type::TRANSLATE || type == Type::ROTATE) { + // A step and repeat gets merged against the group's previous group, + // not our own previous group. + srcg = SK.GetGroup(opA); + + if(!srcg->suppress) { + if(!IsForcedToMesh()) { + GenerateForStepAndRepeat(&(srcg->thisShell), &thisShell, srcg->meshCombine); + } else { + SMesh prevm = {}; + prevm.MakeFromCopyOf(&srcg->thisMesh); + srcg->thisShell.TriangulateInto(&prevm); + GenerateForStepAndRepeat (&prevm, &thisMesh, srcg->meshCombine); + } + } + } else if(type == Type::EXTRUDE && haveSrc) { + Group *src = SK.GetGroup(opA); + Vector translate = Vector::From(h.param(0), h.param(1), h.param(2)); + + Vector tbot, ttop; + if(subtype == Subtype::ONE_SIDED) { + tbot = Vector::From(0, 0, 0); ttop = translate.ScaledBy(2); + } else { + tbot = translate.ScaledBy(-1); ttop = translate.ScaledBy(1); + } + + SBezierLoopSetSet *sblss = &(src->bezierLoops); + SBezierLoopSet *sbls; + for(sbls = sblss->l.First(); sbls; sbls = sblss->l.NextAfter(sbls)) { + int is = thisShell.surface.n; + // Extrude this outer contour (plus its inner contours, if present) + thisShell.MakeFromExtrusionOf(sbls, tbot, ttop, color); + + // And for any plane faces, annotate the model with the entity for + // that face, so that the user can select them with the mouse. + Vector onOrig = sbls->point; + int i; + // Not using range-for here because we're starting at a different place and using + // indices for meaning. + for(i = is; i < thisShell.surface.n; i++) { + SSurface *ss = &(thisShell.surface[i]); + hEntity face = Entity::NO_ENTITY; + + Vector p = ss->PointAt(0, 0), + n = ss->NormalAt(0, 0).WithMagnitude(1); + double d = n.Dot(p); + + if(i == is || i == (is + 1)) { + // These are the top and bottom of the shell. + if(fabs((onOrig.Plus(ttop)).Dot(n) - d) < LENGTH_EPS) { + face = Remap(Entity::NO_ENTITY, REMAP_TOP); + ss->face = face.v; + } + if(fabs((onOrig.Plus(tbot)).Dot(n) - d) < LENGTH_EPS) { + face = Remap(Entity::NO_ENTITY, REMAP_BOTTOM); + ss->face = face.v; + } + continue; + } + + // So these are the sides + if(ss->degm != 1 || ss->degn != 1) continue; + + Entity *e; + for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) { + if(e->group != opA) continue; + if(e->type != Entity::Type::LINE_SEGMENT) continue; + + Vector a = SK.GetEntity(e->point[0])->PointGetNum(), + b = SK.GetEntity(e->point[1])->PointGetNum(); + a = a.Plus(ttop); + b = b.Plus(ttop); + // Could get taken backwards, so check all cases. + if((a.Equals(ss->ctrl[0][0]) && b.Equals(ss->ctrl[1][0])) || + (b.Equals(ss->ctrl[0][0]) && a.Equals(ss->ctrl[1][0])) || + (a.Equals(ss->ctrl[0][1]) && b.Equals(ss->ctrl[1][1])) || + (b.Equals(ss->ctrl[0][1]) && a.Equals(ss->ctrl[1][1]))) + { + face = Remap(e->h, REMAP_LINE_TO_FACE); + ss->face = face.v; + break; + } + } + } + } + } else if(type == Type::LATHE && haveSrc) { + Group *src = SK.GetGroup(opA); + + Vector pt = SK.GetEntity(predef.origin)->PointGetNum(), + axis = SK.GetEntity(predef.entityB)->VectorGetNum(); + axis = axis.WithMagnitude(1); + + SBezierLoopSetSet *sblss = &(src->bezierLoops); + SBezierLoopSet *sbls; + for(sbls = sblss->l.First(); sbls; sbls = sblss->l.NextAfter(sbls)) { + thisShell.MakeFromRevolutionOf(sbls, pt, axis, color, this); + } + } else if(type == Type::REVOLVE && haveSrc) { + Group *src = SK.GetGroup(opA); + double anglef = SK.GetParam(h.param(3))->val * 4; // why the 4 is needed? + double dists = 0, distf = 0; + double angles = 0.0; + if(subtype != Subtype::ONE_SIDED) { + anglef *= 0.5; + angles = -anglef; + } + Vector pt = SK.GetEntity(predef.origin)->PointGetNum(), + axis = SK.GetEntity(predef.entityB)->VectorGetNum(); + axis = axis.WithMagnitude(1); + + SBezierLoopSetSet *sblss = &(src->bezierLoops); + SBezierLoopSet *sbls; + for(sbls = sblss->l.First(); sbls; sbls = sblss->l.NextAfter(sbls)) { + if(fabs(anglef - angles) < 2 * PI) { + thisShell.MakeFromHelicalRevolutionOf(sbls, pt, axis, color, this, + angles, anglef, dists, distf); + } else { + thisShell.MakeFromRevolutionOf(sbls, pt, axis, color, this); + } + } + } else if(type == Type::HELIX && haveSrc) { + Group *src = SK.GetGroup(opA); + double anglef = SK.GetParam(h.param(3))->val * 4; // why the 4 is needed? + double dists = 0, distf = 0; + double angles = 0.0; + distf = SK.GetParam(h.param(7))->val * 2; // dist is applied twice + if(subtype != Subtype::ONE_SIDED) { + anglef *= 0.5; + angles = -anglef; + distf *= 0.5; + dists = -distf; + } + Vector pt = SK.GetEntity(predef.origin)->PointGetNum(), + axis = SK.GetEntity(predef.entityB)->VectorGetNum(); + axis = axis.WithMagnitude(1); + + SBezierLoopSetSet *sblss = &(src->bezierLoops); + SBezierLoopSet *sbls; + for(sbls = sblss->l.First(); sbls; sbls = sblss->l.NextAfter(sbls)) { + thisShell.MakeFromHelicalRevolutionOf(sbls, pt, axis, color, this, + angles, anglef, dists, distf); + } + } else if(type == Type::LINKED) { + // The imported shell or mesh are copied over, with the appropriate + // transformation applied. We also must remap the face entities. + Vector offset = { + SK.GetParam(h.param(0))->val, + SK.GetParam(h.param(1))->val, + SK.GetParam(h.param(2))->val }; + Quaternion q = { + SK.GetParam(h.param(3))->val, + SK.GetParam(h.param(4))->val, + SK.GetParam(h.param(5))->val, + SK.GetParam(h.param(6))->val }; + + thisMesh.MakeFromTransformationOf(&impMesh, offset, q, scale); + thisMesh.RemapFaces(this, 0); + + thisShell.MakeFromTransformationOf(&impShell, offset, q, scale); + thisShell.RemapFaces(this, 0); + } + + if(srcg->meshCombine != CombineAs::ASSEMBLE) { + thisShell.MergeCoincidentSurfaces(); + } + + // So now we've got the mesh or shell for this group. Combine it with + // the previous group's mesh or shell with the requested Boolean, and + // we're done. + + Group *prevg = srcg->RunningMeshGroup(); + + if(!IsForcedToMesh()) { + SShell *prevs = &(prevg->runningShell); + GenerateForBoolean(prevs, &thisShell, &runningShell, + srcg->meshCombine); + + if(srcg->meshCombine != CombineAs::ASSEMBLE) { + runningShell.MergeCoincidentSurfaces(); + } + + // If the Boolean failed, then we should note that in the text screen + // for this group. + booleanFailed = runningShell.booleanFailed; + if(booleanFailed != prevBooleanFailed) { + SS.ScheduleShowTW(); + } + } else { + SMesh prevm, thism; + prevm = {}; + thism = {}; + + prevm.MakeFromCopyOf(&(prevg->runningMesh)); + prevg->runningShell.TriangulateInto(&prevm); + + thism.MakeFromCopyOf(&thisMesh); + thisShell.TriangulateInto(&thism); + + SMesh outm = {}; + GenerateForBoolean(&prevm, &thism, &outm, srcg->meshCombine); + + // Remove degenerate triangles; if we don't, they'll get split in SnapToMesh + // in every generated group, resulting in polynomial increase in triangle count, + // and corresponding slowdown. + outm.RemoveDegenerateTriangles(); + + if(srcg->meshCombine != CombineAs::ASSEMBLE) { + // And make sure that the output mesh is vertex-to-vertex. + SKdNode *root = SKdNode::From(&outm); + root->SnapToMesh(&outm); + root->MakeMeshInto(&runningMesh); + } else { + runningMesh.MakeFromCopyOf(&outm); + } + + outm.Clear(); + thism.Clear(); + prevm.Clear(); + } + + displayDirty = true; +} + +void Group::GenerateDisplayItems() { + // This is potentially slow (since we've got to triangulate a shell, or + // to find the emphasized edges for a mesh), so we will run it only + // if its inputs have changed. + if(displayDirty) { + Group *pg = RunningMeshGroup(); + if(pg && thisMesh.IsEmpty() && thisShell.IsEmpty()) { + // We don't contribute any new solid model in this group, so our + // display items are identical to the previous group's; which means + // that we can just display those, and stop ourselves from + // recalculating for those every time we get a change in this group. + // + // Note that this can end up recursing multiple times (if multiple + // groups that contribute no solid model exist in sequence), but + // that's okay. + pg->GenerateDisplayItems(); + + displayMesh.Clear(); + displayMesh.MakeFromCopyOf(&(pg->displayMesh)); + + displayOutlines.Clear(); + if(SS.GW.showEdges || SS.GW.showOutlines) { + displayOutlines.MakeFromCopyOf(&pg->displayOutlines); + } + } else { + // We do contribute new solid model, so we have to triangulate the + // shell, and edge-find the mesh. + displayMesh.Clear(); + runningShell.TriangulateInto(&displayMesh); + STriangle *t; + for(t = runningMesh.l.First(); t; t = runningMesh.l.NextAfter(t)) { + STriangle trn = *t; + Vector n = trn.Normal(); + trn.an = n; + trn.bn = n; + trn.cn = n; + displayMesh.AddTriangle(&trn); + } + + displayOutlines.Clear(); + + if(SS.GW.showEdges || SS.GW.showOutlines) { + SOutlineList rawOutlines = {}; + if(!runningMesh.l.IsEmpty()) { + // Triangle mesh only; no shell or emphasized edges. + runningMesh.MakeOutlinesInto(&rawOutlines, EdgeKind::EMPHASIZED); + } else { + displayMesh.MakeOutlinesInto(&rawOutlines, EdgeKind::SHARP); + } + + PolylineBuilder builder; + builder.MakeFromOutlines(rawOutlines); + builder.GenerateOutlines(&displayOutlines); + rawOutlines.Clear(); + } + } + + // If we render this mesh, we need to know whether it's transparent, + // and we'll want all transparent triangles last, to make the depth test + // work correctly. + displayMesh.PrecomputeTransparency(); + + // Recalculate mass center if needed + if(SS.centerOfMass.draw && SS.centerOfMass.dirty && h == SS.GW.activeGroup) { + SS.UpdateCenterOfMass(); + } + displayDirty = false; + } +} + +Group *Group::PreviousGroup() const { + Group *prev = nullptr; + for(auto const &gh : SK.groupOrder) { + Group *g = SK.GetGroup(gh); + if(g->h == h) { + return prev; + } + prev = g; + } + return nullptr; +} + +Group *Group::RunningMeshGroup() const { + if(type == Type::TRANSLATE || type == Type::ROTATE) { + return SK.GetGroup(opA)->RunningMeshGroup(); + } else { + return PreviousGroup(); + } +} + +bool Group::IsMeshGroup() { + switch(type) { + case Group::Type::EXTRUDE: + case Group::Type::LATHE: + case Group::Type::REVOLVE: + case Group::Type::HELIX: + case Group::Type::ROTATE: + case Group::Type::TRANSLATE: + return true; + + default: + return false; + } +} + +void Group::DrawMesh(DrawMeshAs how, Canvas *canvas) { + if(!(SS.GW.showShaded || + SS.GW.drawOccludedAs != GraphicsWindow::DrawOccludedAs::VISIBLE)) return; + + switch(how) { + case DrawMeshAs::DEFAULT: { + // Force the shade color to something dim to not distract from + // the sketch. + Canvas::Fill fillFront = {}; + if(!SS.GW.showShaded) { + fillFront.layer = Canvas::Layer::DEPTH_ONLY; + } + if((type == Type::DRAWING_3D || type == Type::DRAWING_WORKPLANE) + && SS.GW.dimSolidModel) { + fillFront.color = Style::Color(Style::DIM_SOLID); + } + Canvas::hFill hcfFront = canvas->GetFill(fillFront); + + // The back faces are drawn in red; should never seem them, since we + // draw closed shells, so that's a debugging aid. + Canvas::hFill hcfBack = {}; + if(SS.drawBackFaces && !displayMesh.isTransparent) { + Canvas::Fill fillBack = {}; + fillBack.layer = fillFront.layer; + fillBack.color = RgbaColor::FromFloat(1.0f, 0.1f, 0.1f); + hcfBack = canvas->GetFill(fillBack); + } else { + hcfBack = hcfFront; + } + + // Draw the shaded solid into the depth buffer for hidden line removal, + // and if we're actually going to display it, to the color buffer too. + canvas->DrawMesh(displayMesh, hcfFront, hcfBack); + + // Draw mesh edges, for debugging. + if(SS.GW.showMesh) { + Canvas::Stroke strokeTriangle = {}; + strokeTriangle.zIndex = 1; + strokeTriangle.color = RgbaColor::FromFloat(0.0f, 1.0f, 0.0f); + strokeTriangle.width = 1; + strokeTriangle.unit = Canvas::Unit::PX; + Canvas::hStroke hcsTriangle = canvas->GetStroke(strokeTriangle); + SEdgeList edges = {}; + for(const STriangle &t : displayMesh.l) { + edges.AddEdge(t.a, t.b); + edges.AddEdge(t.b, t.c); + edges.AddEdge(t.c, t.a); + } + canvas->DrawEdges(edges, hcsTriangle); + edges.Clear(); + } + break; + } + + case DrawMeshAs::HOVERED: { + Canvas::Fill fill = {}; + fill.color = Style::Color(Style::HOVERED); + fill.pattern = Canvas::FillPattern::CHECKERED_A; + fill.zIndex = 2; + Canvas::hFill hcf = canvas->GetFill(fill); + + std::vector faces; + hEntity he = SS.GW.hover.entity; + if(he.v != 0 && SK.GetEntity(he)->IsFace()) { + faces.push_back(he.v); + } + canvas->DrawFaces(displayMesh, faces, hcf); + break; + } + + case DrawMeshAs::SELECTED: { + Canvas::Fill fill = {}; + fill.color = Style::Color(Style::SELECTED); + fill.pattern = Canvas::FillPattern::CHECKERED_B; + fill.zIndex = 1; + Canvas::hFill hcf = canvas->GetFill(fill); + + std::vector faces; + SS.GW.GroupSelection(); + auto const &gs = SS.GW.gs; + if(gs.faces > 0) faces.push_back(gs.face[0].v); + if(gs.faces > 1) faces.push_back(gs.face[1].v); + canvas->DrawFaces(displayMesh, faces, hcf); + break; + } + } +} + +void Group::Draw(Canvas *canvas) { + // Everything here gets drawn whether or not the group is hidden; we + // can control this stuff independently, with show/hide solids, edges, + // mesh, etc. + + GenerateDisplayItems(); + DrawMesh(DrawMeshAs::DEFAULT, canvas); + + if(SS.GW.showEdges) { + Canvas::Stroke strokeEdge = Style::Stroke(Style::SOLID_EDGE); + strokeEdge.zIndex = 1; + Canvas::hStroke hcsEdge = canvas->GetStroke(strokeEdge); + + canvas->DrawOutlines(displayOutlines, hcsEdge, + SS.GW.showOutlines + ? Canvas::DrawOutlinesAs::EMPHASIZED_WITHOUT_CONTOUR + : Canvas::DrawOutlinesAs::EMPHASIZED_AND_CONTOUR); + + if(SS.GW.drawOccludedAs != GraphicsWindow::DrawOccludedAs::INVISIBLE) { + Canvas::Stroke strokeHidden = Style::Stroke(Style::HIDDEN_EDGE); + if(SS.GW.drawOccludedAs == GraphicsWindow::DrawOccludedAs::VISIBLE) { + strokeHidden.stipplePattern = StipplePattern::CONTINUOUS; + } + strokeHidden.layer = Canvas::Layer::OCCLUDED; + Canvas::hStroke hcsHidden = canvas->GetStroke(strokeHidden); + + canvas->DrawOutlines(displayOutlines, hcsHidden, + Canvas::DrawOutlinesAs::EMPHASIZED_AND_CONTOUR); + } + } + + if(SS.GW.showOutlines) { + Canvas::Stroke strokeOutline = Style::Stroke(Style::OUTLINE); + strokeOutline.zIndex = 1; + Canvas::hStroke hcsOutline = canvas->GetStroke(strokeOutline); + + canvas->DrawOutlines(displayOutlines, hcsOutline, + Canvas::DrawOutlinesAs::CONTOUR_ONLY); + } +} + +void Group::DrawPolyError(Canvas *canvas) { + const Camera &camera = canvas->GetCamera(); + + Canvas::Stroke strokeUnclosed = Style::Stroke(Style::DRAW_ERROR); + strokeUnclosed.color = strokeUnclosed.color.WithAlpha(50); + Canvas::hStroke hcsUnclosed = canvas->GetStroke(strokeUnclosed); + + Canvas::Stroke strokeError = Style::Stroke(Style::DRAW_ERROR); + strokeError.layer = Canvas::Layer::FRONT; + strokeError.width = 1.0f; + Canvas::hStroke hcsError = canvas->GetStroke(strokeError); + + double textHeight = Style::DefaultTextHeight() / camera.scale; + + // And finally show the polygons too, and any errors if it's not possible + // to assemble the lines into closed polygons. + if(polyError.how == PolyError::NOT_CLOSED) { + // Report this error only in sketch-in-workplane groups; otherwise + // it's just a nuisance. + if(type == Type::DRAWING_WORKPLANE) { + canvas->DrawVectorText(_("not closed contour, or not all same style!"), + textHeight, + polyError.notClosedAt.b, camera.projRight, camera.projUp, + hcsError); + canvas->DrawLine(polyError.notClosedAt.a, polyError.notClosedAt.b, hcsUnclosed); + } + } else if(polyError.how == PolyError::NOT_COPLANAR || + polyError.how == PolyError::SELF_INTERSECTING || + polyError.how == PolyError::ZERO_LEN_EDGE) { + // These errors occur at points, not lines + if(type == Type::DRAWING_WORKPLANE) { + const char *msg; + if(polyError.how == PolyError::NOT_COPLANAR) { + msg = _("points not all coplanar!"); + } else if(polyError.how == PolyError::SELF_INTERSECTING) { + msg = _("contour is self-intersecting!"); + } else { + msg = _("zero-length edge!"); + } + canvas->DrawVectorText(msg, textHeight, + polyError.errorPointAt, camera.projRight, camera.projUp, + hcsError); + } + } else { + // The contours will get filled in DrawFilledPaths. + } +} + +void Group::DrawFilledPaths(Canvas *canvas) { + for(const SBezierLoopSet &sbls : bezierLoops.l) { + if(sbls.l.IsEmpty() || sbls.l[0].l.IsEmpty()) + continue; + + // In an assembled loop, all the styles should be the same; so doesn't + // matter which one we grab. + const SBezier *sb = &(sbls.l[0].l[0]); + Style *s = Style::Get({ (uint32_t)sb->auxA }); + + Canvas::Fill fill = {}; + fill.zIndex = 1; + if(s->filled) { + // This is a filled loop, where the user specified a fill color. + fill.color = s->fillColor; + } else if(h == SS.GW.activeGroup && SS.checkClosedContour && + polyError.how == PolyError::GOOD) { + // If this is the active group, and we are supposed to check + // for closed contours, and we do indeed have a closed and + // non-intersecting contour, then fill it dimly. + fill.color = Style::Color(Style::CONTOUR_FILL).WithAlpha(127); + } else continue; + Canvas::hFill hcf = canvas->GetFill(fill); + + SPolygon sp = {}; + sbls.MakePwlInto(&sp); + canvas->DrawPolygon(sp, hcf); + sp.Clear(); + } +} + +void Group::DrawContourAreaLabels(Canvas *canvas) { + const Camera &camera = canvas->GetCamera(); + Vector gr = camera.projRight.ScaledBy(1 / camera.scale); + Vector gu = camera.projUp.ScaledBy(1 / camera.scale); + + for(SBezierLoopSet &sbls : bezierLoops.l) { + if(sbls.l.IsEmpty() || sbls.l[0].l.IsEmpty()) + continue; + + Vector min = sbls.l[0].l[0].ctrl[0]; + Vector max = min; + Vector zero = Vector::From(0.0, 0.0, 0.0); + sbls.GetBoundingProjd(Vector::From(1.0, 0.0, 0.0), zero, &min.x, &max.x); + sbls.GetBoundingProjd(Vector::From(0.0, 1.0, 0.0), zero, &min.y, &max.y); + sbls.GetBoundingProjd(Vector::From(0.0, 0.0, 1.0), zero, &min.z, &max.z); + + Vector mid = min.Plus(max).ScaledBy(0.5); + + hStyle hs = { Style::CONSTRAINT }; + Canvas::Stroke stroke = Style::Stroke(hs); + stroke.layer = Canvas::Layer::FRONT; + + std::string label = SS.MmToStringSI(fabs(sbls.SignedArea()), /*dim=*/2); + double fontHeight = Style::TextHeight(hs); + double textWidth = VectorFont::Builtin()->GetWidth(fontHeight, label), + textHeight = VectorFont::Builtin()->GetCapHeight(fontHeight); + Vector pos = mid.Minus(gr.ScaledBy(textWidth / 2.0)) + .Minus(gu.ScaledBy(textHeight / 2.0)); + canvas->DrawVectorText(label, fontHeight, pos, gr, gu, canvas->GetStroke(stroke)); + } +} + diff --git a/src/importdxf.cpp b/src/importdxf.cpp new file mode 100644 index 0000000..ce80280 --- /dev/null +++ b/src/importdxf.cpp @@ -0,0 +1,1199 @@ +#include "solvespace.h" +#include "libdxfrw.h" +#include "libdwgr.h" + +namespace SolveSpace { + +static std::string ToUpper(std::string str) { + std::transform(str.begin(), str.end(), str.begin(), ::toupper); + return str; +} + +static Quaternion NormalFromExtPoint(Vector extPoint) { + // DXF arbitrary axis algorithm for transforming a Z-vector into a rotated + // coordinate system + Vector ax, ay; + Vector az = extPoint.WithMagnitude(1.0); + + if ((fabs(az.x) < 1/64.) && (fabs(az.y) < 1/64.)) { + ax = Vector::From(0, 1, 0).Cross(az).WithMagnitude(1.0); + } else { + ax = Vector::From(0, 0, 1).Cross(az).WithMagnitude(1.0); + } + ay = az.Cross(ax).WithMagnitude(1.0); + return Quaternion::From(ax, ay); +} + +class DxfImport : public DRW_Interface { +public: + Vector blockX; + Vector blockY; + Vector blockZ; + Vector blockT; + + void invertXTransform() { + blockX.x = -blockX.x; + blockY.x = -blockY.x; + blockT.x = -blockT.x; + } + + void multBlockTransform(double x, double y, double sx, double sy, double angle) { + Vector oldX = blockX; + Vector oldY = blockY; + Vector oldT = blockT; + + Vector newX = Vector::From(sx, 0.0, 0.0).RotatedAbout(Vector::From(0.0, 0.0, 1.0), angle); + Vector newY = Vector::From(0.0, sy, 0.0).RotatedAbout(Vector::From(0.0, 0.0, 1.0), angle); + Vector newT = Vector::From(x, y, 0.0); + + blockX = oldX.ScaledBy(newX.x).Plus( + oldY.ScaledBy(newX.y)); + + blockY = oldX.ScaledBy(newY.x).Plus( + oldY.ScaledBy(newY.y)); + + blockT = oldX.ScaledBy(newT.x).Plus( + oldY.ScaledBy(newT.y)).Plus(oldT); + } + + void clearBlockTransform() { + blockX = Vector::From(1.0, 0.0, 0.0); + blockY = Vector::From(0.0, 1.0, 0.0); + blockZ = Vector::From(0.0, 0.0, 1.0); + blockT = Vector::From(0.0, 0.0, 0.0); + } + + Vector blockTransform(Vector v) { + Vector r = blockT; + r = r.Plus(blockX.ScaledBy(v.x)); + r = r.Plus(blockY.ScaledBy(v.y)); + r = r.Plus(blockZ.ScaledBy(v.z)); + return r; + } + + void blockTransformArc(Vector *c, Vector *p0, Vector *p1) { + bool oldSign = p0->Minus(*c).Cross(p1->Minus(*c)).z > 0.0; + + *c = blockTransform(*c); + *p0 = blockTransform(*p0); + *p1 = blockTransform(*p1); + + bool newSign = p0->Minus(*c).Cross(p1->Minus(*c)).z > 0.0; + if(oldSign != newSign) std::swap(*p0, *p1); + } + + Vector toVector(const DRW_Coord &c, bool transform = true) { + Vector result = Vector::From(c.x, c.y, c.z); + if(transform) return blockTransform(result); + return result; + } + + Vector toVector(const DRW_Vertex2D &c) { + Vector result = Vector::From(c.x, c.y, 0.0); + return blockTransform(result); + } + + Vector toVector(const DRW_Vertex &c) { + Vector result = Vector::From(c.basePoint.x, c.basePoint.y, c.basePoint.z); + return blockTransform(result); + } + + double angleTo(Vector v0, Vector v1) { + Vector d = v1.Minus(v0); + double a = atan2(d.y, d.x); + return M_PI + remainder(a - M_PI, 2 * M_PI); + } + + Vector polar(double radius, double angle) { + return Vector::From(radius * cos(angle), radius * sin(angle), 0.0); + } + + hRequest createBulge(Vector p0, Vector p1, double bulge) { + bool reversed = bulge < 0.0; + double alpha = atan(bulge) * 4.0; + + Vector middle = p1.Plus(p0).ScaledBy(0.5); + double dist = p1.Minus(p0).Magnitude() / 2.0; + double angle = angleTo(p0, p1); + + // alpha can't be 0.0 at this point + double radius = fabs(dist / sin(alpha / 2.0)); + double wu = fabs(radius * radius - dist * dist); + double h = sqrt(wu); + + if(bulge > 0.0) { + angle += M_PI_2; + } else { + angle -= M_PI_2; + } + + if (fabs(alpha) > M_PI) { + h *= -1.0; + } + + Vector center = polar(h, angle); + center = center.Plus(middle); + + if(reversed) std::swap(p0, p1); + blockTransformArc(¢er, &p0, &p1); + + hRequest hr = SS.GW.AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false); + SK.GetEntity(hr.entity(1))->PointForceTo(center); + SK.GetEntity(hr.entity(2))->PointForceTo(p0); + SK.GetEntity(hr.entity(3))->PointForceTo(p1); + processPoint(hr.entity(1)); + processPoint(hr.entity(2)); + processPoint(hr.entity(3)); + return hr; + } + + struct Block { + std::vector> entities; + DRW_Block data; + }; + + bool asConstruction = false; + unsigned unknownEntities = 0; + std::map styles; + std::map blocks; + std::map layers; + Block *readBlock = NULL; + const DRW_Insert *insertInsert = NULL; + + template + bool addPendingBlockEntity(const T &e) { + if(readBlock == NULL) return false; + readBlock->entities.emplace_back(new T(e)); + return true; + } + + void addEntity(DRW_Entity *e) { + switch(e->eType) { + case DRW::POINT: + addPoint(*static_cast(e)); + break; + case DRW::LINE: + addLine(*static_cast(e)); + break; + case DRW::ARC: + addArc(*static_cast(e)); + break; + case DRW::CIRCLE: + addCircle(*static_cast(e)); + break; + case DRW::POLYLINE: + addPolyline(*static_cast(e)); + break; + case DRW::LWPOLYLINE: + addLWPolyline(*static_cast(e)); + break; + case DRW::SPLINE: + addSpline(static_cast(e)); + break; + case DRW::INSERT: + addInsert(*static_cast(e)); + break; + case DRW::TEXT: + addText(*static_cast(e)); + break; + case DRW::MTEXT: + addMText(*static_cast(e)); + break; + case DRW::DIMALIGNED: + addDimAlign(static_cast(e)); + break; + case DRW::DIMLINEAR: + addDimLinear(static_cast(e)); + break; + case DRW::DIMRADIAL: + addDimRadial(static_cast(e)); + break; + case DRW::DIMDIAMETRIC: + addDimDiametric(static_cast(e)); + break; + case DRW::DIMANGULAR: + addDimAngular(static_cast(e)); + break; + default: + unknownEntities++; + } + } + + Style::TextOrigin dxfAlignToOrigin(DRW_Text::HAlign alignH, DRW_Text::VAlign alignV) { + uint32_t origin = 0; + switch(alignH) { + case DRW_Text::HLeft: + origin |= (uint32_t)Style::TextOrigin::LEFT; + break; + + case DRW_Text::HMiddle: + case DRW_Text::HCenter: + break; + + case DRW_Text::HRight: + origin |= (uint32_t)Style::TextOrigin::RIGHT; + break; + + case DRW_Text::HAligned: + case DRW_Text::HFit: + default: + origin |= (uint32_t)Style::TextOrigin::LEFT; + break; + } + + switch(alignV) { + case DRW_Text::VBaseLine: + case DRW_Text::VBottom: + origin |= (uint32_t)Style::TextOrigin::BOT; + break; + + case DRW_Text::VMiddle: + break; + + case DRW_Text::VTop: + origin |= (uint32_t)Style::TextOrigin::TOP; + break; + + default: + origin |= (uint32_t)Style::TextOrigin::BOT; + break; + } + + return (Style::TextOrigin)origin; + } + + DRW_Layer *getSourceLayer(const DRW_Entity *e) { + DRW_Layer *layer = NULL; + if(insertInsert != NULL) { + std::string l = insertInsert->layer; + auto bi = layers.find(l); + if(bi != layers.end()) layer = &bi->second; + } else { + std::string l = e->layer; + auto bi = layers.find(l); + if(bi != layers.end()) layer = &bi->second; + } + return layer; + } + + int getColor(const DRW_Entity *e) { + int col = e->color; + if(col == DRW::ColorByBlock) { + if(insertInsert != NULL) { + col = insertInsert->color; + } else { + col = 7; + } + } + if(col == DRW::ColorByLayer) { + DRW_Layer *layer = getSourceLayer(e); + if(layer != NULL) { + col = layer->color; + } else { + col = 7; + } + } + return col; + } + + DRW_LW_Conv::lineWidth getLineWidth(const DRW_Entity *e) { + DRW_LW_Conv::lineWidth result = e->lWeight; + if(result == DRW_LW_Conv::widthByBlock) { + if(insertInsert != NULL) { + result = insertInsert->lWeight; + } else { + result = DRW_LW_Conv::widthDefault; + } + } + if(result == DRW_LW_Conv::widthByLayer) { + DRW_Layer *layer = getSourceLayer(e); + if(layer != NULL) { + result = layer->lWeight; + } else { + result = DRW_LW_Conv::widthDefault; + } + } + return result; + } + + std::string getLineType(const DRW_Entity *e) { + std::string result = e->lineType; + if(result == "BYBLOCK") { + if(insertInsert != NULL) { + result = ToUpper(insertInsert->lineType); + } else { + result = "CONTINUOUS"; + } + } + if(result == "BYLAYER") { + DRW_Layer *layer = getSourceLayer(e); + if(layer != NULL) { + result = ToUpper(layer->lineType); + } else { + result = "CONTINUOUS"; + } + } + return result; + } + + hStyle invisibleStyle() { + std::string id = "@dxf-invisible"; + + auto si = styles.find(id); + if(si != styles.end()) { + return si->second; + } + + hStyle hs = { Style::CreateCustomStyle(/*rememberForUndo=*/false) }; + Style *s = Style::Get(hs); + s->name = id; + s->visible = false; + + styles.emplace(id, hs); + return hs; + } + + hStyle styleFor(const DRW_Entity *e) { + // Color. + //! @todo which color to choose: index or RGB one? + int col = getColor(e); + RgbaColor c = RgbaColor::From(DRW::dxfColors[col][0], + DRW::dxfColors[col][1], + DRW::dxfColors[col][2]); + + // Line width. + DRW_LW_Conv::lineWidth lw = getLineWidth(e); + double width = DRW_LW_Conv::lineWidth2dxfInt(e->lWeight) / 100.0; + if(width < 0.0) width = 1.0; + + // Line stipple. + //! @todo Probably, we can load default autocad patterns and match it with ours. + std::string lineType = getLineType(e); + StipplePattern stipple = StipplePattern::CONTINUOUS; + for(uint32_t i = 0; i <= (uint32_t)StipplePattern::LAST; i++) { + StipplePattern st = (StipplePattern)i; + if(lineType == DxfFileWriter::lineTypeName(st)) { + stipple = st; + break; + } + } + + // Text properties. + DRW_Text::HAlign alignH = DRW_Text::HLeft; + DRW_Text::VAlign alignV = DRW_Text::VBaseLine; + double textAngle = 0.0; + double textHeight = Style::DefaultTextHeight(); + + if(e->eType == DRW::TEXT || e->eType == DRW::MTEXT) { + const DRW_Text *text = static_cast(e); + alignH = text->alignH; + alignV = text->alignV; + textHeight = text->height; + textAngle = text->angle; + // I have no idea why, but works + if(alignH == DRW_Text::HMiddle) { + alignV = DRW_Text::VMiddle; + } + } + + // Unique identifier based on style properties. + std::string id = "@dxf"; + if(lw != DRW_LW_Conv::widthDefault) + id += ssprintf("-w%.4g", width); + if(lineType != "CONTINUOUS") + id += ssprintf("-%s", lineType.c_str()); + if(c.red != 0 || c.green != 0 || c.blue != 0) + id += ssprintf("-#%02x%02x%02x", c.red, c.green, c.blue); + if(textHeight != Style::DefaultTextHeight()) + id += ssprintf("-h%.4g", textHeight); + if(textAngle != 0.0) + id += ssprintf("-a%.5g", textAngle); + if(alignH != DRW_Text::HLeft) + id += ssprintf("-oh%d", alignH); + if(alignV != DRW_Text::VBaseLine) + id += ssprintf("-ov%d", alignV); + + auto si = styles.find(id); + if(si != styles.end()) { + return si->second; + } + + hStyle hs = { Style::CreateCustomStyle(/*rememberForUndo=*/false) }; + Style *s = Style::Get(hs); + if(lw != DRW_LW_Conv::widthDefault) { + s->widthAs = Style::UnitsAs::MM; + s->width = width; + s->stippleScale = 1.0 + width * 2.0; + } + s->name = id; + s->stippleType = stipple; + if(c.red != 0 || c.green != 0 || c.blue != 0) s->color = c; + s->textHeightAs = Style::UnitsAs::MM; + s->textHeight = textHeight; + s->textAngle = textAngle; + s->textOrigin = dxfAlignToOrigin(alignH, alignV); + + styles.emplace(id, hs); + return hs; + } + + void configureRequest(hRequest hr, hStyle hs) { + Request *r = SK.GetRequest(hr); + r->construction = asConstruction; + r->style = hs; + } + + struct VectorHash { + size_t operator()(const Vector &v) const { + static const size_t size = std::numeric_limits::max() / 2 - 1; + static const double eps = (4.0 * LENGTH_EPS); + + double x = fabs(v.x) / eps; + double y = fabs(v.y) / eps; + + size_t xs = size_t(fmod(x, double(size))); + size_t ys = size_t(fmod(y, double(size))); + + return ys * size + xs; + } + }; + + struct VectorPred { + bool operator()(Vector a, Vector b) const { + return a.Equals(b, LENGTH_EPS); + } + }; + + std::unordered_map points; + + void processPoint(hEntity he, bool constrain = true) { + Entity *e = SK.GetEntity(he); + Vector pos = e->PointGetNum(); + hEntity p = findPoint(pos); + if(p == he) return; + if(p != Entity::NO_ENTITY) { + if(constrain) { + Constraint::ConstrainCoincident(he, p); + } + // We don't add point because we already + // have point in this position + return; + } + points.emplace(pos, he); + } + + hEntity findPoint(const Vector &p) { + auto it = points.find(p); + if(it == points.end()) return Entity::NO_ENTITY; + return it->second; + } + + hEntity createOrGetPoint(const Vector &p) { + hEntity he = findPoint(p); + if(he != Entity::NO_ENTITY) return he; + + hRequest hr = SS.GW.AddRequest(Request::Type::DATUM_POINT, /*rememberForUndo=*/false); + he = hr.entity(0); + SK.GetEntity(he)->PointForceTo(p); + points.emplace(p, he); + return he; + } + + hEntity createLine(Vector p0, Vector p1, hStyle style, bool constrainHV = false) { + if(p0.Equals(p1)) return Entity::NO_ENTITY; + hRequest hr = SS.GW.AddRequest(Request::Type::LINE_SEGMENT, /*rememberForUndo=*/false); + SK.GetEntity(hr.entity(1))->PointForceTo(p0); + SK.GetEntity(hr.entity(2))->PointForceTo(p1); + processPoint(hr.entity(1)); + processPoint(hr.entity(2)); + + if(constrainHV && SS.GW.LockedInWorkplane()) { + bool hasConstraint = false; + Constraint::Type cType; + if(fabs(p0.x - p1.x) < LENGTH_EPS) { + hasConstraint = true; + cType = Constraint::Type::VERTICAL; + } else if(fabs(p0.y - p1.y) < LENGTH_EPS) { + hasConstraint = true; + cType = Constraint::Type::HORIZONTAL; + } + if(hasConstraint) { + Constraint::Constrain( + cType, + Entity::NO_ENTITY, + Entity::NO_ENTITY, + hr.entity(0) + ); + } + } + + configureRequest(hr, style); + return hr.entity(0); + } + + hEntity createWorkplane(const Vector &p, const Quaternion &q) { + hRequest hr = SS.GW.AddRequest(Request::Type::WORKPLANE, /*rememberForUndo=*/false); + SK.GetEntity(hr.entity(1))->PointForceTo(p); + processPoint(hr.entity(1)); + SK.GetEntity(hr.entity(32))->NormalForceTo(q); + return hr.entity(0); + } + + hEntity findOrCreateWorkplane(const Vector &p, const Quaternion &q) { + Vector z = q.RotationN(); + for(auto &r : SK.request) { + if((r.type == Request::Type::WORKPLANE) && (r.group == SS.GW.activeGroup)) { + Vector wp = SK.GetEntity(r.h.entity(1))->PointGetNum(); + Vector wz = SK.GetEntity(r.h.entity(32))->NormalN(); + + if ((p.DistanceToPlane(wz, wp) < LENGTH_EPS) && z.Equals(wz)) { + return r.h.entity(0); + } + } + } + + return createWorkplane(p, q); + } + + static void activateWorkplane(hEntity he) { + Group *g = SK.GetGroup(SS.GW.activeGroup); + g->activeWorkplane = he; + } + + hEntity createCircle(const Vector &c, const Quaternion &q, double r, hStyle style) { + hRequest hr = SS.GW.AddRequest(Request::Type::CIRCLE, /*rememberForUndo=*/false); + SK.GetEntity(hr.entity(1))->PointForceTo(c); + processPoint(hr.entity(1)); + SK.GetEntity(hr.entity(32))->NormalForceTo(q); + SK.GetEntity(hr.entity(64))->DistanceForceTo(r); + configureRequest(hr, style); + return hr.entity(0); + } + + void addLayer(const DRW_Layer &data) override { + layers.emplace(data.name, data); + } + + void addBlock(const DRW_Block &data) override { + readBlock = &blocks[data.name]; + readBlock->data = data; + } + + void endBlock() override { + readBlock = NULL; + } + + void addPoint(const DRW_Point &data) override { + if(data.space != DRW::ModelSpace) return; + if(addPendingBlockEntity(data)) return; + + hRequest hr = SS.GW.AddRequest(Request::Type::DATUM_POINT, /*rememberForUndo=*/false); + SK.GetEntity(hr.entity(0))->PointForceTo(toVector(data.basePoint)); + processPoint(hr.entity(0)); + } + + void addLine(const DRW_Line &data) override { + if(data.space != DRW::ModelSpace) return; + if(addPendingBlockEntity(data)) return; + + createLine(toVector(data.basePoint), toVector(data.secPoint), styleFor(&data), + /*constrainHV=*/true); + } + + void addArc(const DRW_Arc &data) override { + if(data.space != DRW::ModelSpace) return; + if(addPendingBlockEntity(data)) return; + + double r = data.radious; + double sa = data.staangle; + double ea = data.endangle; + Vector c = toVector(data.basePoint); + Vector nz = toVector(data.extPoint); + Quaternion q = NormalFromExtPoint(nz); + + bool planar = q.RotationN().Equals(Vector::From(0, 0, 1)); + bool onPlane = c.z < LENGTH_EPS; + + hEntity oldWorkplane = SS.GW.ActiveWorkplane(); + if (!planar || !onPlane) { + activateWorkplane(findOrCreateWorkplane(c, q)); + } + + hRequest hr = SS.GW.AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false); + Vector u = q.RotationU(), v = q.RotationV(); + Vector rvs = c.Plus(u.ScaledBy(r * cos(sa))).Plus(v.ScaledBy(r * sin(sa))); + Vector rve = c.Plus(u.ScaledBy(r * cos(ea))).Plus(v.ScaledBy(r * sin(ea))); + + if(data.extPoint.z == -1.0) { + c.x = -c.x; + rvs.x = - rvs.x; + rve.x = - rve.x; + std::swap(rvs, rve); + } + + blockTransformArc(&c, &rvs, &rve); + + SK.GetEntity(hr.entity(1))->PointForceTo(c); + SK.GetEntity(hr.entity(2))->PointForceTo(rvs); + SK.GetEntity(hr.entity(3))->PointForceTo(rve); + processPoint(hr.entity(1)); + processPoint(hr.entity(2)); + processPoint(hr.entity(3)); + configureRequest(hr, styleFor(&data)); + activateWorkplane(oldWorkplane); + } + + void addCircle(const DRW_Circle &data) override { + if(data.space != DRW::ModelSpace) return; + if(addPendingBlockEntity(data)) return; + + Vector nz = toVector(data.extPoint); + Quaternion normal = NormalFromExtPoint(nz); + createCircle(toVector(data.basePoint), normal, data.radious, styleFor(&data)); + } + + void addLWPolyline(const DRW_LWPolyline &data) override { + if(data.space != DRW::ModelSpace) return; + if(addPendingBlockEntity(data)) return; + + size_t vNum = data.vertlist.size(); + + // Check for closed polyline. + if((data.flags & 1) != 1) vNum--; + + // Correct coordinate system for the case where z=-1, as described in + // http://paulbourke.net/dataformats/dxf/dxf10.html. + bool needSwapX = data.extPoint.z == -1.0; + + for(size_t i = 0; i < vNum; i++) { + DRW_Vertex2D c0 = *data.vertlist[i]; + DRW_Vertex2D c1 = *data.vertlist[(i + 1) % data.vertlist.size()]; + + if(needSwapX) { + c0.x = -c0.x; + c1.x = -c1.x; + c0.bulge = -c0.bulge; + } + + Vector p0 = Vector::From(c0.x, c0.y, 0.0); + Vector p1 = Vector::From(c1.x, c1.y, 0.0); + hStyle hs = styleFor(&data); + + if(EXACT(data.vertlist[i]->bulge == 0.0)) { + createLine(blockTransform(p0), blockTransform(p1), hs, /*constrainHV=*/true); + } else { + hRequest hr = createBulge(p0, p1, c0.bulge); + configureRequest(hr, hs); + } + } + } + + void addPolyline(const DRW_Polyline &data) override { + if(data.space != DRW::ModelSpace) return; + if(addPendingBlockEntity(data)) return; + + size_t vNum = data.vertlist.size(); + + // Check for closed polyline. + if((data.flags & 1) != 1) vNum--; + + // Correct coordinate system for the case where z=-1, as described in + // http://paulbourke.net/dataformats/dxf/dxf10.html. + bool needSwapX = (data.extPoint.z == -1.0); + + for(size_t i = 0; i < vNum; i++) { + DRW_Coord c0 = data.vertlist[i]->basePoint; + DRW_Coord c1 = data.vertlist[(i + 1) % data.vertlist.size()]->basePoint; + + double bulge = data.vertlist[i]->bulge; + if(needSwapX) { + c0.x = -c0.x; + c1.x = -c1.x; + bulge = -bulge; + } + + Vector p0 = Vector::From(c0.x, c0.y, c0.z); + Vector p1 = Vector::From(c1.x, c1.y, c1.z); + hStyle hs = styleFor(&data); + + if(EXACT(bulge == 0.0)) { + createLine(blockTransform(p0), blockTransform(p1), hs, /*constrainHV=*/true); + } else { + hRequest hr = createBulge(p0, p1, bulge); + configureRequest(hr, hs); + } + } + } + + void addSpline(const DRW_Spline *data) override { + if(data->space != DRW::ModelSpace) return; + if(data->degree != 3) return; + if(addPendingBlockEntity(*data)) return; + + hRequest hr = SS.GW.AddRequest(Request::Type::CUBIC, /*rememberForUndo=*/false); + for(int i = 0; i < 4; i++) { + SK.GetEntity(hr.entity(i + 1))->PointForceTo(toVector(*data->controllist[i])); + processPoint(hr.entity(i + 1)); + } + configureRequest(hr, styleFor(data)); + } + + void addInsert(const DRW_Insert &data) override { + if(data.space != DRW::ModelSpace) return; + if(addPendingBlockEntity(data)) return; + + auto bi = blocks.find(data.name); + ssassert(bi != blocks.end(), "Inserted block does not exist"); + Block *block = &bi->second; + + // Push transform. + Vector x = blockX; + Vector y = blockY; + Vector t = blockT; + + const DRW_Insert *oldInsert = insertInsert; + insertInsert = &data; + + if(data.extPoint.z == -1.0) invertXTransform(); + multBlockTransform(data.basePoint.x, data.basePoint.y, data.xscale, data.yscale, + data.angle); + for(auto &e : block->entities) { + addEntity(&*e); + } + + insertInsert = oldInsert; + + // Pop transform. + blockX = x; + blockY = y; + blockT = t; + } + + void addMText(const DRW_MText &data) override { + if(data.space != DRW::ModelSpace) return; + if(addPendingBlockEntity(data)) return; + + DRW_MText text = data; + text.secPoint = text.basePoint; + addText(text); + } + + void addText(const DRW_Text &data) override { + if(data.space != DRW::ModelSpace) return; + if(addPendingBlockEntity(data)) return; + + Constraint c = {}; + c.group = SS.GW.activeGroup; + c.workplane = SS.GW.ActiveWorkplane(); + c.type = Constraint::Type::COMMENT; + if(data.alignH == DRW_Text::HLeft && data.alignV == DRW_Text::VBaseLine) { + c.disp.offset = toVector(data.basePoint); + } else { + c.disp.offset = toVector(data.secPoint); + } + c.comment = data.text; + c.disp.style = styleFor(&data); + Constraint::AddConstraint(&c, /*rememberForUndo=*/false); + } + + void addDimAlign(const DRW_DimAligned *data) override { + if(data->space != DRW::ModelSpace) return; + if(addPendingBlockEntity(*data)) return; + + Vector p0 = toVector(data->getDef1Point()); + Vector p1 = toVector(data->getDef2Point()); + Vector p2 = toVector(data->getTextPoint()); + hConstraint hc = Constraint::Constrain( + Constraint::Type::PT_PT_DISTANCE, + createOrGetPoint(p0), + createOrGetPoint(p1), + Entity::NO_ENTITY + ); + + Constraint *c = SK.GetConstraint(hc); + if(data->hasActualMeasurement()) { + c->valA = data->getActualMeasurement(); + } else { + c->ModifyToSatisfy(); + } + c->disp.offset = p2.Minus(p0.Plus(p1).ScaledBy(0.5)); + } + + void addDimLinear(const DRW_DimLinear *data) override { + if(data->space != DRW::ModelSpace) return; + if(addPendingBlockEntity(*data)) return; + + Vector p0 = toVector(data->getDef1Point(), /*transform=*/false); + Vector p1 = toVector(data->getDef2Point(), /*transform=*/false); + Vector p2 = toVector(data->getTextPoint(), /*transform=*/false); + + double angle = data->getAngle() * PI / 180.0; + Vector dir = Vector::From(cos(angle), sin(angle), 0.0); + Vector p3 = p1.Minus(p1.ClosestPointOnLine(p2, dir)).Plus(p1); + if(p1.Minus(p3).Magnitude() < LENGTH_EPS) { + p3 = p0.Minus(p0.ClosestPointOnLine(p2, dir)).Plus(p1); + } + + Vector p4 = p0.ClosestPointOnLine(p1, p3.Minus(p1)).Plus(p0).ScaledBy(0.5); + + p0 = blockTransform(p0); + p1 = blockTransform(p1); + p2 = blockTransform(p2); + p3 = blockTransform(p3); + p4 = blockTransform(p4); + + hConstraint hc = Constraint::Constrain( + Constraint::Type::PT_LINE_DISTANCE, + createOrGetPoint(p0), + Entity::NO_ENTITY, + createLine(p1, p3, invisibleStyle()) + ); + + Constraint *c = SK.GetConstraint(hc); + if(data->hasActualMeasurement()) { + c->valA = data->getActualMeasurement(); + } else { + c->ModifyToSatisfy(); + } + c->disp.offset = p2.Minus(p4); + } + + void addDimAngular(const DRW_DimAngular *data) override { + if(data->space != DRW::ModelSpace) return; + if(addPendingBlockEntity(*data)) return; + + Vector l0p0 = toVector(data->getFirstLine1()); + Vector l0p1 = toVector(data->getFirstLine2()); + Vector l1p0 = toVector(data->getSecondLine1()); + Vector l1p1 = toVector(data->getSecondLine2()); + + hConstraint hc = Constraint::Constrain( + Constraint::Type::ANGLE, + Entity::NO_ENTITY, + Entity::NO_ENTITY, + createLine(l0p0, l0p1, invisibleStyle()), + createLine(l1p1, l1p0, invisibleStyle()), + /*other=*/false, + /*other2=*/false + ); + + Constraint *c = SK.GetConstraint(hc); + c->ModifyToSatisfy(); + if(data->hasActualMeasurement()) { + double actual = data->getActualMeasurement() / PI * 180.0; + if(fabs(180.0 - actual - c->valA) < fabs(actual - c->valA)) { + c->other = true; + } + c->valA = actual; + } + + bool skew = false; + Vector pi = Vector::AtIntersectionOfLines(l0p0, l0p1, l1p0, l1p1, &skew); + if(!skew) { + c->disp.offset = toVector(data->getTextPoint()).Minus(pi); + } + } + + hConstraint createDiametric(Vector cp, Quaternion q, double r, Vector tp, + double actual, bool asRadius = false) { + hEntity he = createCircle(cp, q, r, invisibleStyle()); + + hConstraint hc = Constraint::Constrain( + Constraint::Type::DIAMETER, + Entity::NO_ENTITY, + Entity::NO_ENTITY, + he + ); + + Constraint *c = SK.GetConstraint(hc); + if(actual > 0.0) { + c->valA = asRadius ? actual * 2.0 : actual; + } else { + c->ModifyToSatisfy(); + } + c->disp.offset = tp.Minus(cp); + if(asRadius) c->other = true; + return hc; + } + + void addDimRadial(const DRW_DimRadial *data) override { + if(data->space != DRW::ModelSpace) return; + if(addPendingBlockEntity(*data)) return; + + Vector cp = toVector(data->getCenterPoint()); + Vector dp = toVector(data->getDiameterPoint()); + Vector tp = toVector(data->getTextPoint()); + double actual = -1.0; + if(data->hasActualMeasurement()) { + actual = data->getActualMeasurement(); + } + + Vector nz = toVector(data->getExtrusion()); + Quaternion q = NormalFromExtPoint(nz); + createDiametric(cp, q, cp.Minus(dp).Magnitude(), tp, actual, /*asRadius=*/true); + } + + void addDimDiametric(const DRW_DimDiametric *data) override { + if(data->space != DRW::ModelSpace) return; + if(addPendingBlockEntity(*data)) return; + + Vector dp1 = toVector(data->getDiameter1Point()); + Vector dp2 = toVector(data->getDiameter2Point()); + + Vector cp = dp1.Plus(dp2).ScaledBy(0.5); + Vector tp = toVector(data->getTextPoint()); + double actual = -1.0; + if(data->hasActualMeasurement()) { + actual = data->getActualMeasurement(); + } + + Vector nz = toVector(data->getExtrusion()); + Quaternion q = NormalFromExtPoint(nz); + createDiametric(cp, q, cp.Minus(dp1).Magnitude(), tp, actual, /*asRadius=*/false); + } + + void addDimAngular3P(const DRW_DimAngular3p *data) override { + if(data->space != DRW::ModelSpace) return; + if(addPendingBlockEntity(*data)) return; + + DRW_DimAngular dim = *static_cast(data); + dim.setFirstLine1(data->getVertexPoint()); + dim.setFirstLine2(data->getFirstLine()); + dim.setSecondLine1(data->getVertexPoint()); + dim.setSecondLine2(data->getSecondLine()); + addDimAngular(&dim); + } +}; + +class DxfCheck3D : public DRW_Interface { +public: + bool is3d; + + void addEntity(DRW_Entity *e) { + switch(e->eType) { + case DRW::POINT: + addPoint(*static_cast(e)); + break; + case DRW::LINE: + addLine(*static_cast(e)); + break; + case DRW::ARC: + addArc(*static_cast(e)); + break; + case DRW::CIRCLE: + addCircle(*static_cast(e)); + break; + case DRW::POLYLINE: + addPolyline(*static_cast(e)); + break; + case DRW::LWPOLYLINE: + addLWPolyline(*static_cast(e)); + break; + case DRW::SPLINE: + addSpline(static_cast(e)); + break; + case DRW::INSERT: + addInsert(*static_cast(e)); + break; + case DRW::TEXT: + addText(*static_cast(e)); + break; + case DRW::MTEXT: + addMText(*static_cast(e)); + break; + case DRW::DIMALIGNED: + addDimAlign(static_cast(e)); + break; + case DRW::DIMLINEAR: + addDimLinear(static_cast(e)); + break; + case DRW::DIMRADIAL: + addDimRadial(static_cast(e)); + break; + case DRW::DIMDIAMETRIC: + addDimDiametric(static_cast(e)); + break; + case DRW::DIMANGULAR: + addDimAngular(static_cast(e)); + break; + default: + break; + } + } + + void addPoint(const DRW_Point &data) override { + if(data.space != DRW::ModelSpace) return; + checkCoord(data.basePoint); + } + + void addLine(const DRW_Line &data) override { + if(data.space != DRW::ModelSpace) return; + checkCoord(data.basePoint); + checkCoord(data.secPoint); + } + + void addArc(const DRW_Arc &data) override { + if(data.space != DRW::ModelSpace) return; + checkCoord(data.basePoint); + checkExt(data.extPoint); + } + + void addCircle(const DRW_Circle &data) override { + if(data.space != DRW::ModelSpace) return; + checkCoord(data.basePoint); + checkExt(data.extPoint); + } + + void addPolyline(const DRW_Polyline &data) override { + if(data.space != DRW::ModelSpace) return; + for(size_t i = 0; i < data.vertlist.size(); i++) { + checkCoord(data.vertlist[i]->basePoint); + } + } + + void addSpline(const DRW_Spline *data) override { + if(data->space != DRW::ModelSpace) return; + if(data->degree != 3) return; + for(int i = 0; i < 4; i++) { + checkCoord(*data->controllist[i]); + } + } + + void addInsert(const DRW_Insert &data) override { + if(data.space != DRW::ModelSpace) return; + checkCoord(data.basePoint); + } + + void addMText(const DRW_MText &data) override { + if(data.space != DRW::ModelSpace) return; + + DRW_MText text = data; + text.secPoint = text.basePoint; + addText(text); + } + + void addText(const DRW_Text &data) override { + if(data.space != DRW::ModelSpace) return; + checkCoord(data.basePoint); + checkCoord(data.secPoint); + } + + void addDimAlign(const DRW_DimAligned *data) override { + if(data->space != DRW::ModelSpace) return; + checkCoord(data->getDef1Point()); + checkCoord(data->getDef2Point()); + checkCoord(data->getTextPoint()); + } + + void addDimLinear(const DRW_DimLinear *data) override { + if(data->space != DRW::ModelSpace) return; + checkCoord(data->getDef1Point()); + checkCoord(data->getDef2Point()); + checkCoord(data->getTextPoint()); + } + + void addDimAngular(const DRW_DimAngular *data) override { + if(data->space != DRW::ModelSpace) return; + checkCoord(data->getFirstLine1()); + checkCoord(data->getFirstLine2()); + checkCoord(data->getSecondLine1()); + checkCoord(data->getSecondLine2()); + checkCoord(data->getTextPoint()); + } + + void addDimRadial(const DRW_DimRadial *data) override { + if(data->space != DRW::ModelSpace) return; + checkCoord(data->getCenterPoint()); + checkCoord(data->getDiameterPoint()); + checkCoord(data->getTextPoint()); + checkExt(data->getExtrusion()); + } + + void addDimDiametric(const DRW_DimDiametric *data) override { + if(data->space != DRW::ModelSpace) return; + checkCoord(data->getDiameter1Point()); + checkCoord(data->getDiameter2Point()); + checkCoord(data->getTextPoint()); + checkExt(data->getExtrusion()); + } + + void addDimAngular3P(const DRW_DimAngular3p *data) override { + if(data->space != DRW::ModelSpace) return; + DRW_DimAngular dim = *static_cast(data); + + dim.setFirstLine1(data->getVertexPoint()); + dim.setFirstLine2(data->getFirstLine()); + dim.setSecondLine1(data->getVertexPoint()); + dim.setSecondLine2(data->getSecondLine()); + addDimAngular(&dim); + } + + void checkCoord(const DRW_Coord &coord) { + if(fabs(coord.z) > LENGTH_EPS) { + is3d = true; + } + } + + void checkExt(const DRW_Coord &coord) { + if ((fabs(coord.x) > 1/64.) || (fabs(coord.y) > 1/64.)) { + is3d = true; + } + } +}; + +static void +ImportDwgDxf(const Platform::Path &filename, + const std::function &read) { + std::string fileType = ToUpper(filename.Extension()); + + std::string data; + if(!ReadFile(filename, &data)) { + Error("Couldn't read from '%s'", filename.raw.c_str()); + return; + } + + bool asConstruction = true; + if(SS.GW.LockedInWorkplane()) { + DxfCheck3D checker = {}; + read(data, &checker); + if(checker.is3d) { + Message("This %s file contains entities with non-zero Z coordinate; " + "the entire file will be imported as construction entities in 3d.", + fileType.c_str()); + SS.GW.SetWorkplaneFreeIn3d(); + SS.GW.EnsureValidActives(); + } else { + asConstruction = false; + } + } + + SS.UndoRemember(); + + DxfImport importer = {}; + importer.asConstruction = asConstruction; + importer.clearBlockTransform(); + if(!read(data, &importer)) { + Error("Corrupted %s file.", fileType.c_str()); + return; + } + if(importer.unknownEntities > 0) { + Message("%u %s entities of unknown type were ignored.", + importer.unknownEntities, fileType.c_str()); + } +} + +void ImportDxf(const Platform::Path &filename) { + ImportDwgDxf(filename, [](const std::string &data, DRW_Interface *intf) { + std::stringstream stream(data); + return dxfRW().read(stream, intf, /*ext=*/true); + }); +} + +void ImportDwg(const Platform::Path &filename) { + ImportDwgDxf(filename, [](const std::string &data, DRW_Interface *intf) { + std::stringstream stream(data); + return dwgR().read(stream, intf, /*ext=*/true); + }); +} + +} diff --git a/src/importidf.cpp b/src/importidf.cpp new file mode 100644 index 0000000..1789e5c --- /dev/null +++ b/src/importidf.cpp @@ -0,0 +1,521 @@ +//----------------------------------------------------------------------------- +// Intermediate Data Format (IDF) file reader. Reads an IDF file for PCB outlines and creates +// an equivalent SovleSpace sketch/extrusion. Supports only Linking, not import. +// Part placement is not currently supported. +// +// Copyright 2020 Paul Kahler. +//----------------------------------------------------------------------------- +#include "solvespace.h" +#include "sketch.h" + +// Split a string into substrings separated by spaces. +// Allow quotes to enclose spaces within a string +static std::vector splitString(const std::string line) { + std::vector v = {}; + + if(line.length() == 0) return v; + + std::string s = ""; + bool inString = false; + bool inQuotes = false; + + for (size_t i=0; i 0) + v.push_back(s); + + return v; +} + +////////////////////////////////////////////////////////////////////////////// +// Functions for linking an IDF file - we need to create entites that +// get remapped into a linked group similar to linking .slvs files +////////////////////////////////////////////////////////////////////////////// + +// Make a new point - type doesn't matter since we will make a copy later +static hEntity newPoint(EntityList *el, int *id, Vector p, bool visible = true) { + Entity en = {}; + en.type = Entity::Type::POINT_N_COPY; + en.extraPoints = 0; + en.timesApplied = 0; + en.group.v = 462; + en.actPoint = p; + en.construction = false; + en.style.v = Style::DATUM; + en.actVisible = visible; + en.forceHidden = false; + + *id = *id+1; + en.h.v = *id + en.group.v*65536; + el->Add(&en); + return en.h; +} + +static hEntity newLine(EntityList *el, int *id, hEntity p0, hEntity p1) { + Entity en = {}; + en.type = Entity::Type::LINE_SEGMENT; + en.point[0] = p0; + en.point[1] = p1; + en.extraPoints = 0; + en.timesApplied = 0; + en.group.v = 493; + en.construction = false; + en.style.v = Style::ACTIVE_GRP; + en.actVisible = true; + en.forceHidden = false; + + *id = *id+1; + en.h.v = *id + en.group.v*65536; + el->Add(&en); + return en.h; +} + +static hEntity newNormal(EntityList *el, int *id, Quaternion normal) { + // normals have parameters, but we don't need them to make a NORMAL_N_COPY from this + Entity en = {}; + en.type = Entity::Type::NORMAL_N_COPY; + en.extraPoints = 0; + en.timesApplied = 0; + en.group.v = 472; + en.actNormal = normal; + en.construction = false; + en.style.v = Style::ACTIVE_GRP; + // to be visible we need to add a point. + en.point[0] = newPoint(el, id, Vector::From(0,0,3), /*visible=*/ true); + en.actVisible = true; + en.forceHidden = false; + + *id = *id+1; + en.h.v = *id + en.group.v*65536; + el->Add(&en); + return en.h; +} + +static hEntity newArc(EntityList *el, int *id, hEntity p0, hEntity p1, hEntity pc, hEntity hnorm) { + Entity en = {}; + en.type = Entity::Type::ARC_OF_CIRCLE; + en.point[0] = pc; + en.point[1] = p0; + en.point[2] = p1; + en.normal = hnorm; + en.extraPoints = 0; + en.timesApplied = 0; + en.group.v = 403; + en.construction = false; + en.style.v = Style::ACTIVE_GRP; + en.actVisible = true; + en.forceHidden = false; *id = *id+1; + + *id = *id + 1; + en.h.v = *id + en.group.v*65536; + el->Add(&en); + return en.h; +} + +static hEntity newDistance(EntityList *el, int *id, double distance) { + // normals have parameters, but we don't need them to make a NORMAL_N_COPY from this + Entity en = {}; + en.type = Entity::Type::DISTANCE; + en.extraPoints = 0; + en.timesApplied = 0; + en.group.v = 472; + en.actDistance = distance; + en.construction = false; + en.style.v = Style::ACTIVE_GRP; + // to be visible we'll need to add a point? + en.actVisible = false; + en.forceHidden = false; + + *id = *id+1; + en.h.v = *id + en.group.v*65536; + el->Add(&en); + return en.h; +} + +static hEntity newCircle(EntityList *el, int *id, hEntity p0, hEntity hdist, hEntity hnorm) { + Entity en = {}; + en.type = Entity::Type::CIRCLE; + en.point[0] = p0; + en.normal = hnorm; + en.distance = hdist; + en.extraPoints = 0; + en.timesApplied = 0; + en.group.v = 399; + en.construction = false; + en.style.v = Style::ACTIVE_GRP; + en.actVisible = true; + en.forceHidden = false; + + *id = *id+1; + en.h.v = *id + en.group.v*65536; + el->Add(&en); + return en.h; +} + +static Vector ArcCenter(Vector p0, Vector p1, double angle) { + // locate the center of an arc + Vector m = p0.Plus(p1).ScaledBy(0.5); + Vector perp = Vector::From(p1.y-p0.y, p0.x-p1.x, 0.0).WithMagnitude(1.0); + double dist = 0; + if (angle != 180) { + dist = (p1.Minus(m).Magnitude())/tan(0.5*angle*3.141592653589793/180.0); + } else { + dist = 0.0; + } + Vector c = m.Minus(perp.ScaledBy(dist)); + return c; +} + +// Add an IDF line or arc to the entity list. According to spec, zero angle indicates a line. +// Positive angles are counter clockwise, negative are clockwise. An angle of 360 +// indicates a circle centered at x1,y1 passing through x2,y2 and is a complete loop. +static void CreateEntity(EntityList *el, int *id, hEntity h0, hEntity h1, hEntity hnorm, + Vector p0, Vector p1, double angle) { + if (angle == 0.0) { + //line + if(p0.Equals(p1)) return; + + newLine(el, id, h0, h1); + + } else if(angle == 360.0) { + // circle + double d = p1.Minus(p0).Magnitude(); + hEntity hd = newDistance(el, id, d); + newCircle(el, id, h1, hd, hnorm); + + } else { + // arc + if(angle < 0.0) { + swap(p0,p1); + swap(h0,h1); + } + // locate the center of the arc + Vector m = p0.Plus(p1).ScaledBy(0.5); + Vector perp = Vector::From(p1.y-p0.y, p0.x-p1.x, 0.0).WithMagnitude(1.0); + double dist = 0; + if (angle != 180) { + dist = (p1.Minus(m).Magnitude())/tan(0.5*angle*3.141592653589793/180.0); + } else { + dist = 0.0; + } + Vector c = m.Minus(perp.ScaledBy(dist)); + hEntity hc = newPoint(el, id, c, /*visible=*/false); + newArc(el, id, h0, h1, hc, hnorm); + } +} + +// borrowed from Entity::GenerateBezierCurves because we don't have parameters. +static void MakeBeziersForArcs(SBezierList *sbl, Vector center, Vector pa, Vector pb, + Quaternion q, double angle) { + + Vector u = q.RotationU(), v = q.RotationV(); + double r = pa.Minus(center).Magnitude(); + double theta, dtheta; + + if(angle == 360.0) { + theta = 0; + } else { + Point2d c2 = center.Project2d(u, v); + Point2d pa2 = (pa.Project2d(u, v)).Minus(c2); + + theta = atan2(pa2.y, pa2.x); + } + dtheta = angle * PI/180; + + int i, n; + if(dtheta > (3*PI/2 + 0.01)) { + n = 4; + } else if(dtheta > (PI + 0.01)) { + n = 3; + } else if(dtheta > (PI/2 + 0.01)) { + n = 2; + } else { + n = 1; + } + dtheta /= n; + + for(i = 0; i < n; i++) { + double s, c; + + c = cos(theta); + s = sin(theta); + // The start point of the curve, and the tangent vector at + // that start point. + Vector p0 = center.Plus(u.ScaledBy( r*c)).Plus(v.ScaledBy(r*s)), + t0 = u.ScaledBy(-r*s). Plus(v.ScaledBy(r*c)); + + theta += dtheta; + + c = cos(theta); + s = sin(theta); + Vector p2 = center.Plus(u.ScaledBy( r*c)).Plus(v.ScaledBy(r*s)), + t2 = u.ScaledBy(-r*s). Plus(v.ScaledBy(r*c)); + + // The control point must lie on both tangents. + Vector p1 = Vector::AtIntersectionOfLines(p0, p0.Plus(t0), + p2, p2.Plus(t2), + NULL); + + SBezier sb = SBezier::From(p0, p1, p2); + sb.weight[1] = cos(dtheta/2); + sbl->l.Add(&sb); + } +} + +namespace SolveSpace { + +// Here we read the important section of an IDF file. SolveSpace Entities are directly created by +// the funcions above, which is only OK because of the way linking works. For example points do +// not have handles for solver parameters (coordinates), they only have their actPoint values +// set (or actNormal or actDistance). These are incompete entites and would be a problem if +// they were part of the sketch, but they are not. After making a list of them here, a new group +// gets created from copies of these. Those copies are complete and part of the sketch group. +bool LinkIDF(const Platform::Path &filename, EntityList *el, SMesh *m, SShell *sh) { + dbp("\nLink IDF board outline."); + el->Clear(); + std::string data; + if(!ReadFile(filename, &data)) { + Error("Couldn't read from '%s'", filename.raw.c_str()); + return false; + } + + enum IDF_SECTION { + none, + header, + board_outline, + other_outline, + routing_outline, + placement_outline, + routing_keepout, + via_keepout, + placement_group, + drilled_holes, + notes, + component_placement + } section; + + section = IDF_SECTION::none; + int record_number = 0; + int curve = -1; + int entityCount = 0; + + hEntity hprev; + hEntity hprevTop; + Vector pprev = Vector::From(0,0,0); + Vector pprevTop = Vector::From(0,0,0); + + double board_thickness = 10.0; + double scale = 1.0; //mm + bool topEntities, bottomEntities; + + Quaternion normal = Quaternion::From(Vector::From(1,0,0), Vector::From(0,1,0)); + hEntity hnorm = newNormal(el, &entityCount, normal); + + // to create the extursion we will need to collect a set of bezier curves defined + // by the perimeter, cutouts, and holes. + SBezierList sbl = {}; + + std::stringstream stream(data); + for(std::string line; getline( stream, line ); ) { + if (line.find(".END_") == 0) { + section = none; + curve = -1; + } + switch (section) { + case none: + if(line.find(".HEADER") == 0) { + section = header; + record_number = 1; + } else if (line.find(".BOARD_OUTLINE") == 0) { + section = board_outline; + record_number = 1; +// no keepouts for now - they should also be shown as construction? +// } else if (line.find(".ROUTE_KEEPOUT") == 0) { +// section = routing_keepout; +// record_number = 1; + } else if(line.find(".DRILLED_HOLES") == 0) { + section = drilled_holes; + record_number = 1; + } + break; + + case header: + if(record_number == 3) { + if(line.find("MM") != std::string::npos) { + dbp("IDF units are MM"); + scale = 1.0; + } else if(line.find("THOU") != std::string::npos) { + dbp("IDF units are thousandths of an inch"); + scale = 0.0254; + } else { + dbp("IDF import, no units found in file."); + } + } + break; + + case routing_keepout: + case board_outline: + if (record_number == 2) { + if(section == board_outline) { + topEntities = true; + bottomEntities = true; + board_thickness = std::stod(line) * scale; + dbp("IDF board thickness: %lf", board_thickness); + } else if (section == routing_keepout) { + topEntities = false; + bottomEntities = false; + if(line.find("TOP") == 0 || line.find("BOTH") == 0) + topEntities = true; + if(line.find("BOTTOM") == 0 || line.find("BOTH") == 0) + bottomEntities = true; + } + } else { // records 3+ are lines, arcs, and circles + std::vector values = splitString(line); + if(values.size() != 4) continue; + int c = stoi(values[0]); + double x = stof(values[1]); + double y = stof(values[2]); + double ang = stof(values[3]); + Vector point = Vector::From(x,y,0.0); + Vector pTop = Vector::From(x,y,board_thickness); + if(c != curve) { // start a new curve + curve = c; + if (bottomEntities) + hprev = newPoint(el, &entityCount, point, /*visible=*/false); + if (topEntities) + hprevTop = newPoint(el, &entityCount, pTop, /*visible=*/false); + pprev = point; + pprevTop = pTop; + } else { + if(section == board_outline) { + // create a bezier for the extrusion + if (ang == 0) { + // straight lines + SBezier sb = SBezier::From(pprev, point); + sbl.l.Add(&sb); + } else if (ang != 360.0) { + // Arcs + Vector c = ArcCenter(pprev, point, ang); + MakeBeziersForArcs(&sbl, c, pprev, point, normal, ang); + } else { + // circles + MakeBeziersForArcs(&sbl, point, pprev, pprev, normal, ang); + } + } + // next create the entities + // only curves and points at circle centers will be visible + bool vis = (ang == 360.0); + if (bottomEntities) { + hEntity hp = newPoint(el, &entityCount, point, /*visible=*/vis); + CreateEntity(el, &entityCount, hprev, hp, hnorm, pprev, point, ang); + pprev = point; + hprev = hp; + } + if (topEntities) { + hEntity hp = newPoint(el, &entityCount, pTop, /*visible=*/vis); + CreateEntity(el, &entityCount, hprevTop, hp, hnorm, pprevTop, pTop, ang); + pprevTop = pTop; + hprevTop = hp; + } + } + } + break; + + case other_outline: + case routing_outline: + case placement_outline: + case via_keepout: + case placement_group: + break; + + case drilled_holes: { + std::vector values = splitString(line); + if(values.size() < 6) continue; + double d = stof(values[0]); + double x = stof(values[1]); + double y = stof(values[2]); + // Only show holes likely to be useful in MCAD to reduce complexity. + if((d > 1.7) || (values[5].compare(0,3,"PIN") == 0) + || (values[5].compare(0,3,"MTG") == 0)) { + // create the entity + Vector cent = Vector::From(x,y,0.0); + hEntity hcent = newPoint(el, &entityCount, cent); + hEntity hdist = newDistance(el, &entityCount, d/2); + newCircle(el, &entityCount, hcent, hdist, hnorm); + // and again for the top + Vector cTop = Vector::From(x,y,board_thickness); + hcent = newPoint(el, &entityCount, cTop); + hdist = newDistance(el, &entityCount, d/2); + newCircle(el, &entityCount, hcent, hdist, hnorm); + // create the curves for the extrusion + Vector pt = Vector::From(x+d/2, y, 0.0); + MakeBeziersForArcs(&sbl, cent, pt, pt, normal, 360.0); + } + + break; + } + case notes: + case component_placement: + break; + + default: + section = none; + break; + } + record_number++; + } + // now we can create an extrusion from all the Bezier curves. We can skip things + // like checking for a coplanar sketch because everything is at z=0. + SPolygon polyLoops = {}; + bool allClosed; + bool allCoplanar; + Vector errorPointAt = Vector::From(0,0,0); + SEdge errorAt = {}; + + SBezierLoopSetSet sblss = {}; + sblss.FindOuterFacesFrom(&sbl, &polyLoops, NULL, + 100.0, &allClosed, &errorAt, + &allCoplanar, &errorPointAt, NULL); + + //hack for when there is no sketch yet and the first group is a linked IDF + double ctc = SS.chordTolCalculated; + if(ctc == 0.0) SS.chordTolCalculated = 0.1; //mm + // there should only by one sbls in the sblss unless a board has disjointed parts... + sh->MakeFromExtrusionOf(sblss.l.First(), Vector::From(0.0, 0.0, 0.0), + Vector::From(0.0, 0.0, board_thickness), + RgbaColor::From(0, 180, 0) ); + SS.chordTolCalculated = ctc; + sblss.Clear(); + sbl.Clear(); + sh->booleanFailed = false; + + return true; +} + +} diff --git a/src/lib.cpp b/src/lib.cpp new file mode 100644 index 0000000..b0d8e1d --- /dev/null +++ b/src/lib.cpp @@ -0,0 +1,254 @@ +//----------------------------------------------------------------------------- +// A library wrapper around SolveSpace, to permit someone to use its constraint +// solver without coupling their program too much to SolveSpace's internals. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" +#define EXPORT_DLL +#include + +Sketch SolveSpace::SK = {}; +static System SYS; + +void SolveSpace::Platform::FatalError(const std::string &message) { + fprintf(stderr, "%s", message.c_str()); + abort(); +} + +void Group::GenerateEquations(IdList *) { + // Nothing to do for now. +} + +extern "C" { + +void Slvs_QuaternionU(double qw, double qx, double qy, double qz, + double *x, double *y, double *z) +{ + Quaternion q = Quaternion::From(qw, qx, qy, qz); + Vector v = q.RotationU(); + *x = v.x; + *y = v.y; + *z = v.z; +} + +void Slvs_QuaternionV(double qw, double qx, double qy, double qz, + double *x, double *y, double *z) +{ + Quaternion q = Quaternion::From(qw, qx, qy, qz); + Vector v = q.RotationV(); + *x = v.x; + *y = v.y; + *z = v.z; +} + +void Slvs_QuaternionN(double qw, double qx, double qy, double qz, + double *x, double *y, double *z) +{ + Quaternion q = Quaternion::From(qw, qx, qy, qz); + Vector v = q.RotationN(); + *x = v.x; + *y = v.y; + *z = v.z; +} + +void Slvs_MakeQuaternion(double ux, double uy, double uz, + double vx, double vy, double vz, + double *qw, double *qx, double *qy, double *qz) +{ + Vector u = Vector::From(ux, uy, uz), + v = Vector::From(vx, vy, vz); + Quaternion q = Quaternion::From(u, v); + *qw = q.w; + *qx = q.vx; + *qy = q.vy; + *qz = q.vz; +} + +void Slvs_Solve(Slvs_System *ssys, Slvs_hGroup shg) +{ + int i; + for(i = 0; i < ssys->params; i++) { + Slvs_Param *sp = &(ssys->param[i]); + Param p = {}; + + p.h.v = sp->h; + p.val = sp->val; + SK.param.Add(&p); + if(sp->group == shg) { + SYS.param.Add(&p); + } + } + + for(i = 0; i < ssys->entities; i++) { + Slvs_Entity *se = &(ssys->entity[i]); + EntityBase e = {}; + + switch(se->type) { +case SLVS_E_POINT_IN_3D: e.type = Entity::Type::POINT_IN_3D; break; +case SLVS_E_POINT_IN_2D: e.type = Entity::Type::POINT_IN_2D; break; +case SLVS_E_NORMAL_IN_3D: e.type = Entity::Type::NORMAL_IN_3D; break; +case SLVS_E_NORMAL_IN_2D: e.type = Entity::Type::NORMAL_IN_2D; break; +case SLVS_E_DISTANCE: e.type = Entity::Type::DISTANCE; break; +case SLVS_E_WORKPLANE: e.type = Entity::Type::WORKPLANE; break; +case SLVS_E_LINE_SEGMENT: e.type = Entity::Type::LINE_SEGMENT; break; +case SLVS_E_CUBIC: e.type = Entity::Type::CUBIC; break; +case SLVS_E_CIRCLE: e.type = Entity::Type::CIRCLE; break; +case SLVS_E_ARC_OF_CIRCLE: e.type = Entity::Type::ARC_OF_CIRCLE; break; + +default: dbp("bad entity type %d", se->type); return; + } + e.h.v = se->h; + e.group.v = se->group; + e.workplane.v = se->wrkpl; + e.point[0].v = se->point[0]; + e.point[1].v = se->point[1]; + e.point[2].v = se->point[2]; + e.point[3].v = se->point[3]; + e.normal.v = se->normal; + e.distance.v = se->distance; + e.param[0].v = se->param[0]; + e.param[1].v = se->param[1]; + e.param[2].v = se->param[2]; + e.param[3].v = se->param[3]; + + SK.entity.Add(&e); + } + IdList params = {}; + for(i = 0; i < ssys->constraints; i++) { + Slvs_Constraint *sc = &(ssys->constraint[i]); + ConstraintBase c = {}; + + Constraint::Type t; + switch(sc->type) { +case SLVS_C_POINTS_COINCIDENT: t = Constraint::Type::POINTS_COINCIDENT; break; +case SLVS_C_PT_PT_DISTANCE: t = Constraint::Type::PT_PT_DISTANCE; break; +case SLVS_C_PT_PLANE_DISTANCE: t = Constraint::Type::PT_PLANE_DISTANCE; break; +case SLVS_C_PT_LINE_DISTANCE: t = Constraint::Type::PT_LINE_DISTANCE; break; +case SLVS_C_PT_FACE_DISTANCE: t = Constraint::Type::PT_FACE_DISTANCE; break; +case SLVS_C_PT_IN_PLANE: t = Constraint::Type::PT_IN_PLANE; break; +case SLVS_C_PT_ON_LINE: t = Constraint::Type::PT_ON_LINE; break; +case SLVS_C_PT_ON_FACE: t = Constraint::Type::PT_ON_FACE; break; +case SLVS_C_EQUAL_LENGTH_LINES: t = Constraint::Type::EQUAL_LENGTH_LINES; break; +case SLVS_C_LENGTH_RATIO: t = Constraint::Type::LENGTH_RATIO; break; +case SLVS_C_EQ_LEN_PT_LINE_D: t = Constraint::Type::EQ_LEN_PT_LINE_D; break; +case SLVS_C_EQ_PT_LN_DISTANCES: t = Constraint::Type::EQ_PT_LN_DISTANCES; break; +case SLVS_C_EQUAL_ANGLE: t = Constraint::Type::EQUAL_ANGLE; break; +case SLVS_C_EQUAL_LINE_ARC_LEN: t = Constraint::Type::EQUAL_LINE_ARC_LEN; break; +case SLVS_C_LENGTH_DIFFERENCE: t = Constraint::Type::LENGTH_DIFFERENCE; break; +case SLVS_C_SYMMETRIC: t = Constraint::Type::SYMMETRIC; break; +case SLVS_C_SYMMETRIC_HORIZ: t = Constraint::Type::SYMMETRIC_HORIZ; break; +case SLVS_C_SYMMETRIC_VERT: t = Constraint::Type::SYMMETRIC_VERT; break; +case SLVS_C_SYMMETRIC_LINE: t = Constraint::Type::SYMMETRIC_LINE; break; +case SLVS_C_AT_MIDPOINT: t = Constraint::Type::AT_MIDPOINT; break; +case SLVS_C_HORIZONTAL: t = Constraint::Type::HORIZONTAL; break; +case SLVS_C_VERTICAL: t = Constraint::Type::VERTICAL; break; +case SLVS_C_DIAMETER: t = Constraint::Type::DIAMETER; break; +case SLVS_C_PT_ON_CIRCLE: t = Constraint::Type::PT_ON_CIRCLE; break; +case SLVS_C_SAME_ORIENTATION: t = Constraint::Type::SAME_ORIENTATION; break; +case SLVS_C_ANGLE: t = Constraint::Type::ANGLE; break; +case SLVS_C_PARALLEL: t = Constraint::Type::PARALLEL; break; +case SLVS_C_PERPENDICULAR: t = Constraint::Type::PERPENDICULAR; break; +case SLVS_C_ARC_LINE_TANGENT: t = Constraint::Type::ARC_LINE_TANGENT; break; +case SLVS_C_CUBIC_LINE_TANGENT: t = Constraint::Type::CUBIC_LINE_TANGENT; break; +case SLVS_C_EQUAL_RADIUS: t = Constraint::Type::EQUAL_RADIUS; break; +case SLVS_C_PROJ_PT_DISTANCE: t = Constraint::Type::PROJ_PT_DISTANCE; break; +case SLVS_C_WHERE_DRAGGED: t = Constraint::Type::WHERE_DRAGGED; break; +case SLVS_C_CURVE_CURVE_TANGENT:t = Constraint::Type::CURVE_CURVE_TANGENT; break; + +default: dbp("bad constraint type %d", sc->type); return; + } + + c.type = t; + + c.h.v = sc->h; + c.group.v = sc->group; + c.workplane.v = sc->wrkpl; + c.valA = sc->valA; + c.ptA.v = sc->ptA; + c.ptB.v = sc->ptB; + c.entityA.v = sc->entityA; + c.entityB.v = sc->entityB; + c.entityC.v = sc->entityC; + c.entityD.v = sc->entityD; + c.other = (sc->other) ? true : false; + c.other2 = (sc->other2) ? true : false; + + c.Generate(¶ms); + if(!params.IsEmpty()) { + for(Param &p : params) { + p.h = SK.param.AddAndAssignId(&p); + c.valP = p.h; + SYS.param.Add(&p); + } + params.Clear(); + c.ModifyToSatisfy(); + } + + SK.constraint.Add(&c); + } + + for(i = 0; i < (int)arraylen(ssys->dragged); i++) { + if(ssys->dragged[i]) { + hParam hp = { ssys->dragged[i] }; + SYS.dragged.Add(&hp); + } + } + + Group g = {}; + g.h.v = shg; + + List bad = {}; + + // Now we're finally ready to solve! + bool andFindBad = ssys->calculateFaileds ? true : false; + SolveResult how = SYS.Solve(&g, NULL, &(ssys->dof), &bad, andFindBad, /*andFindFree=*/false); + + switch(how) { + case SolveResult::OKAY: + ssys->result = SLVS_RESULT_OKAY; + break; + + case SolveResult::DIDNT_CONVERGE: + ssys->result = SLVS_RESULT_DIDNT_CONVERGE; + break; + + case SolveResult::REDUNDANT_DIDNT_CONVERGE: + case SolveResult::REDUNDANT_OKAY: + ssys->result = SLVS_RESULT_INCONSISTENT; + break; + + case SolveResult::TOO_MANY_UNKNOWNS: + ssys->result = SLVS_RESULT_TOO_MANY_UNKNOWNS; + break; + } + + // Write the new parameter values back to our caller. + for(i = 0; i < ssys->params; i++) { + Slvs_Param *sp = &(ssys->param[i]); + hParam hp = { sp->h }; + sp->val = SK.GetParam(hp)->val; + } + + if(ssys->failed) { + // Copy over any the list of problematic constraints. + for(i = 0; i < ssys->faileds && i < bad.n; i++) { + ssys->failed[i] = bad[i].v; + } + ssys->faileds = bad.n; + } + + bad.Clear(); + SYS.param.Clear(); + SYS.entity.Clear(); + SYS.eq.Clear(); + SYS.dragged.Clear(); + + SK.param.Clear(); + SK.entity.Clear(); + SK.constraint.Clear(); + + FreeAllTemporary(); +} + +} /* extern "C" */ diff --git a/src/mesh.cpp b/src/mesh.cpp new file mode 100644 index 0000000..57377d0 --- /dev/null +++ b/src/mesh.cpp @@ -0,0 +1,1217 @@ +//----------------------------------------------------------------------------- +// Operations on triangle meshes, like our mesh Booleans using the BSP, and +// the stuff to check for watertightness. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +#include + +void SMesh::Clear() { + l.Clear(); +} + +void SMesh::AddTriangle(STriMeta meta, Vector n, Vector a, Vector b, Vector c) { + Vector ab = b.Minus(a), bc = c.Minus(b); + Vector np = ab.Cross(bc); + if(np.Magnitude() < 1e-10) { + // ugh; gl sometimes tesselates to collinear triangles + return; + } + if(np.Dot(n) > 0) { + AddTriangle(meta, a, b, c); + } else { + AddTriangle(meta, c, b, a); + } +} +void SMesh::AddTriangle(STriMeta meta, Vector a, Vector b, Vector c) { + STriangle t = {}; + t.meta = meta; + t.a = a; + t.b = b; + t.c = c; + AddTriangle(&t); +} +void SMesh::AddTriangle(const STriangle *st) { + l.Add(st); +} + +void SMesh::DoBounding(Vector v, Vector *vmax, Vector *vmin) const { + vmax->x = max(vmax->x, v.x); + vmax->y = max(vmax->y, v.y); + vmax->z = max(vmax->z, v.z); + + vmin->x = min(vmin->x, v.x); + vmin->y = min(vmin->y, v.y); + vmin->z = min(vmin->z, v.z); +} +void SMesh::GetBounding(Vector *vmax, Vector *vmin) const { + int i; + *vmin = Vector::From( 1e12, 1e12, 1e12); + *vmax = Vector::From(-1e12, -1e12, -1e12); + for(i = 0; i < l.n; i++) { + const STriangle *st = &(l[i]); + DoBounding(st->a, vmax, vmin); + DoBounding(st->b, vmax, vmin); + DoBounding(st->c, vmax, vmin); + } +} + +//---------------------------------------------------------------------------- +// Report the edges of the boundary of the region(s) of our mesh that lie +// within the plane n dot p = d. +//---------------------------------------------------------------------------- +void SMesh::MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d) { + SMesh m = {}; + m.MakeFromCopyOf(this); + + // Delete all triangles in the mesh that do not lie in our export plane. + m.l.ClearTags(); + int i; + for(i = 0; i < m.l.n; i++) { + STriangle *tr = &(m.l[i]); + + if((fabs(n.Dot(tr->a) - d) >= LENGTH_EPS) || + (fabs(n.Dot(tr->b) - d) >= LENGTH_EPS) || + (fabs(n.Dot(tr->c) - d) >= LENGTH_EPS)) + { + tr->tag = 1; + } + } + m.l.RemoveTagged(); + + // Select the naked edges in our resulting open mesh. + SKdNode *root = SKdNode::From(&m); + root->SnapToMesh(&m); + root->MakeCertainEdgesInto(sel, EdgeKind::NAKED_OR_SELF_INTER, + /*coplanarIsInter=*/false, NULL, NULL); + + m.Clear(); +} + +void SMesh::MakeOutlinesInto(SOutlineList *sol, EdgeKind edgeKind) { + SKdNode *root = SKdNode::From(this); + root->MakeOutlinesInto(sol, edgeKind); +} + +//----------------------------------------------------------------------------- +// When we are called, all of the triangles from l[start] to the end must +// be coplanar. So we try to find a set of fewer triangles that covers the +// exact same area, in order to reduce the number of triangles in the mesh. +// We use this after a triangle has been split against the BSP. +// +// This is really ugly code; basically it just pastes things together to +// form convex polygons, merging collinear edges when possible, then +// triangulates the convex poly. +//----------------------------------------------------------------------------- +void SMesh::Simplify(int start) { + int maxTriangles = (l.n - start) + 10; + + STriMeta meta = l[start].meta; + + STriangle *tout = new STriangle[maxTriangles]; + int toutc = 0; + + Vector n = Vector::From(0, 0, 0); + Vector *conv = new Vector[maxTriangles * 3]; + int convc = 0; + + int start0 = start; + + int i, j; + for(i = start; i < l.n; i++) { + STriangle *tr = &(l[i]); + if(tr->MinAltitude() < LENGTH_EPS) { + tr->tag = 1; + } else { + tr->tag = 0; + } + } + + for(;;) { + bool didAdd; + convc = 0; + for(i = start; i < l.n; i++) { + STriangle *tr = &(l[i]); + if(tr->tag) continue; + + tr->tag = 1; + n = (tr->Normal()).WithMagnitude(1); + conv[convc++] = tr->a; + conv[convc++] = tr->b; + conv[convc++] = tr->c; + + start = i+1; + break; + } + if(i >= l.n) break; + + do { + didAdd = false; + + for(j = 0; j < convc; j++) { + Vector a = conv[WRAP((j-1), convc)], + b = conv[j], + d = conv[WRAP((j+1), convc)], + e = conv[WRAP((j+2), convc)]; + + Vector c; + for(i = start; i < l.n; i++) { + STriangle *tr = &(l[i]); + if(tr->tag) continue; + + if((tr->a).Equals(d) && (tr->b).Equals(b)) { + c = tr->c; + } else if((tr->b).Equals(d) && (tr->c).Equals(b)) { + c = tr->a; + } else if((tr->c).Equals(d) && (tr->a).Equals(b)) { + c = tr->b; + } else { + continue; + } + // The vertex at C must be convex; but the others must + // be tested + Vector ab = b.Minus(a); + Vector bc = c.Minus(b); + Vector cd = d.Minus(c); + Vector de = e.Minus(d); + + double bDot = (ab.Cross(bc)).Dot(n); + double dDot = (cd.Cross(de)).Dot(n); + + bDot /= min(ab.Magnitude(), bc.Magnitude()); + dDot /= min(cd.Magnitude(), de.Magnitude()); + + if(fabs(bDot) < LENGTH_EPS && fabs(dDot) < LENGTH_EPS) { + conv[WRAP((j+1), convc)] = c; + // and remove the vertex at j, which is a dup + std::move(conv+j+1, conv+convc, conv+j); + convc--; + } else if(fabs(bDot) < LENGTH_EPS && dDot > 0) { + conv[j] = c; + } else if(fabs(dDot) < LENGTH_EPS && bDot > 0) { + conv[WRAP((j+1), convc)] = c; + } else if(bDot > 0 && dDot > 0) { + // conv[j] is unchanged, conv[j+1] goes to [j+2] + std::move_backward(conv+j+1, conv+convc, conv+convc+1); + conv[j+1] = c; + convc++; + } else { + continue; + } + + didAdd = true; + tr->tag = 1; + break; + } + } + } while(didAdd); + + // I need to debug why this is required; sometimes the above code + // still generates a convex polygon + for(i = 0; i < convc; i++) { + Vector a = conv[WRAP((i-1), convc)], + b = conv[i], + c = conv[WRAP((i+1), convc)]; + Vector ab = b.Minus(a); + Vector bc = c.Minus(b); + double bDot = (ab.Cross(bc)).Dot(n); + bDot /= min(ab.Magnitude(), bc.Magnitude()); + + if(bDot < 0) return; // XXX, shouldn't happen + } + + for(i = 0; i < convc - 2; i++) { + STriangle tr = STriangle::From(meta, conv[0], conv[i+1], conv[i+2]); + if(tr.MinAltitude() > LENGTH_EPS) { + tout[toutc++] = tr; + } + } + } + + l.n = start0; + for(i = 0; i < toutc; i++) { + AddTriangle(&(tout[i])); + } + delete[] tout; + delete[] conv; +} + +void SMesh::AddAgainstBsp(SMesh *srcm, SBsp3 *bsp3) { + int i; + + for(i = 0; i < srcm->l.n; i++) { + STriangle *st = &(srcm->l[i]); + int pn = l.n; + atLeastOneDiscarded = false; + SBsp3::InsertOrCreate(bsp3, st, this); + if(!atLeastOneDiscarded && (l.n != (pn+1))) { + l.n = pn; + if(flipNormal) { + AddTriangle(st->meta, st->c, st->b, st->a); + } else { + AddTriangle(st->meta, st->a, st->b, st->c); + } + } + if(l.n - pn > 1) { + Simplify(pn); + } + } +} + +void SMesh::MakeFromUnionOf(SMesh *a, SMesh *b) { + SBsp3 *bspa = SBsp3::FromMesh(a); + SBsp3 *bspb = SBsp3::FromMesh(b); + + flipNormal = false; + keepInsideOtherShell = false; + + keepCoplanar = true; + AddAgainstBsp(b, bspa); + + keepCoplanar = false; + AddAgainstBsp(a, bspb); +} + +void SMesh::MakeFromDifferenceOf(SMesh *a, SMesh *b) { + SBsp3 *bspa = SBsp3::FromMesh(a); + SBsp3 *bspb = SBsp3::FromMesh(b); + + flipNormal = true; + keepCoplanar = true; + keepInsideOtherShell = true; + AddAgainstBsp(b, bspa); + + flipNormal = false; + keepCoplanar = false; + keepInsideOtherShell = false; + AddAgainstBsp(a, bspb); +} + +void SMesh::MakeFromIntersectionOf(SMesh *a, SMesh *b) { + SBsp3 *bspa = SBsp3::FromMesh(a); + SBsp3 *bspb = SBsp3::FromMesh(b); + + keepInsideOtherShell = true; + flipNormal = false; + + keepCoplanar = false; + AddAgainstBsp(a, bspb); + + keepCoplanar = true; + AddAgainstBsp(b, bspa); +} + +void SMesh::MakeFromCopyOf(SMesh *a) { + ssassert(this != a, "Can't make from copy of self"); + for(int i = 0; i < a->l.n; i++) { + AddTriangle(&(a->l[i])); + } +} + +void SMesh::MakeFromAssemblyOf(SMesh *a, SMesh *b) { + MakeFromCopyOf(a); + MakeFromCopyOf(b); +} + +void SMesh::MakeFromTransformationOf(SMesh *a, Vector trans, + Quaternion q, double scale) +{ + STriangle *tr; + for(tr = a->l.First(); tr; tr = a->l.NextAfter(tr)) { + STriangle tt = *tr; + tt.a = (tt.a).ScaledBy(scale); + tt.b = (tt.b).ScaledBy(scale); + tt.c = (tt.c).ScaledBy(scale); + if(scale < 0) { + // The mirroring would otherwise turn a closed mesh inside out. + swap(tt.a, tt.b); + } + tt.a = (q.Rotate(tt.a)).Plus(trans); + tt.b = (q.Rotate(tt.b)).Plus(trans); + tt.c = (q.Rotate(tt.c)).Plus(trans); + AddTriangle(&tt); + } +} + +bool SMesh::IsEmpty() const { return (l.IsEmpty()); } + +uint32_t SMesh::FirstIntersectionWith(Point2d mp) const { + Vector rayPoint = SS.GW.UnProjectPoint3(Vector::From(mp.x, mp.y, 0.0)); + Vector rayDir = SS.GW.UnProjectPoint3(Vector::From(mp.x, mp.y, 1.0)).Minus(rayPoint); + + uint32_t face = 0; + double faceT = VERY_NEGATIVE; + for(int i = 0; i < l.n; i++) { + const STriangle &tr = l[i]; + if(tr.meta.face == 0) continue; + + double t; + if(!tr.Raytrace(rayPoint, rayDir, &t, NULL)) continue; + if(t > faceT) { + face = tr.meta.face; + faceT = t; + } + } + + return face; +} + +Vector SMesh::GetCenterOfMass() const { + Vector center = {}; + double vol = 0.0; + for(int i = 0; i < l.n; i++) { + const STriangle &tr = l[i]; + double tvol = tr.SignedVolume(); + center = center.Plus(tr.a.Plus(tr.b.Plus(tr.c)).ScaledBy(tvol / 4.0)); + vol += tvol; + } + return center.ScaledBy(1.0 / vol); +} + +STriangleLl *STriangleLl::Alloc() + { return (STriangleLl *)AllocTemporary(sizeof(STriangleLl)); } +SKdNode *SKdNode::Alloc() + { return (SKdNode *)AllocTemporary(sizeof(SKdNode)); } + +SKdNode *SKdNode::From(SMesh *m) { + int i; + STriangle *tra = (STriangle *)AllocTemporary((m->l.n) * sizeof(*tra)); + + for(i = 0; i < m->l.n; i++) { + tra[i] = m->l[i]; + } + + srand(0); + int n = m->l.n; + while(n > 1) { + int k = rand() % n; + n--; + swap(tra[k], tra[n]); + } + + STriangleLl *tll = NULL; + for(i = 0; i < m->l.n; i++) { + STriangleLl *tn = STriangleLl::Alloc(); + tn->tri = &(tra[i]); + tn->next = tll; + tll = tn; + } + + return SKdNode::From(tll); +} + +SKdNode *SKdNode::From(STriangleLl *tll) { + int which = 0; + SKdNode *ret = Alloc(); + + int i; + int gtc[3] = { 0, 0, 0 }, ltc[3] = { 0, 0, 0 }, allc = 0; + double badness[3] = { 0, 0, 0 }; + double split[3] = { 0, 0, 0 }; + + if(!tll) { + goto leaf; + } + + for(i = 0; i < 3; i++) { + int tcnt = 0; + STriangleLl *ll; + for(ll = tll; ll; ll = ll->next) { + split[i] += (ll->tri->a).Element(i); + split[i] += (ll->tri->b).Element(i); + split[i] += (ll->tri->c).Element(i); + tcnt++; + } + split[i] /= (tcnt*3); + + for(ll = tll; ll; ll = ll->next) { + STriangle *tr = ll->tri; + + double a = (tr->a).Element(i), + b = (tr->b).Element(i), + c = (tr->c).Element(i); + + if(a < split[i] + KDTREE_EPS || + b < split[i] + KDTREE_EPS || + c < split[i] + KDTREE_EPS) + { + ltc[i]++; + } + if(a > split[i] - KDTREE_EPS || + b > split[i] - KDTREE_EPS || + c > split[i] - KDTREE_EPS) + { + gtc[i]++; + } + if(i == 0) allc++; + } + badness[i] = pow((double)ltc[i], 4) + pow((double)gtc[i], 4); + } + if(badness[0] < badness[1] && badness[0] < badness[2]) { + which = 0; + } else if(badness[1] < badness[2]) { + which = 1; + } else { + which = 2; + } + + if(allc < 3 || allc == gtc[which] || allc == ltc[which]) { + goto leaf; + } + + STriangleLl *ll; + STriangleLl *lgt, *llt; lgt = llt = NULL; + for(ll = tll; ll; ll = ll->next) { + STriangle *tr = ll->tri; + + double a = (tr->a).Element(which), + b = (tr->b).Element(which), + c = (tr->c).Element(which); + + if(a < split[which] + KDTREE_EPS || + b < split[which] + KDTREE_EPS || + c < split[which] + KDTREE_EPS) + { + STriangleLl *n = STriangleLl::Alloc(); + *n = *ll; + n->next = llt; + llt = n; + } + if(a > split[which] - KDTREE_EPS || + b > split[which] - KDTREE_EPS || + c > split[which] - KDTREE_EPS) + { + STriangleLl *n = STriangleLl::Alloc(); + *n = *ll; + n->next = lgt; + lgt = n; + } + } + + ret->which = which; + ret->c = split[which]; + ret->gt = SKdNode::From(lgt); + ret->lt = SKdNode::From(llt); + return ret; + +leaf: + ret->tris = tll; + return ret; +} + +void SKdNode::ClearTags() const { + if(gt && lt) { + gt->ClearTags(); + lt->ClearTags(); + } else { + STriangleLl *ll; + for(ll = tris; ll; ll = ll->next) { + ll->tri->tag = 0; + } + } +} + +void SKdNode::AddTriangle(STriangle *tr) { + if(gt && lt) { + double ta = (tr->a).Element(which), + tb = (tr->b).Element(which), + tc = (tr->c).Element(which); + if(ta < c + KDTREE_EPS || + tb < c + KDTREE_EPS || + tc < c + KDTREE_EPS) + { + lt->AddTriangle(tr); + } + if(ta > c - KDTREE_EPS || + tb > c - KDTREE_EPS || + tc > c - KDTREE_EPS) + { + gt->AddTriangle(tr); + } + } else { + STriangleLl *tn = STriangleLl::Alloc(); + tn->tri = tr; + tn->next = tris; + tris = tn; + } +} + +void SKdNode::MakeMeshInto(SMesh *m) const { + if(gt) gt->MakeMeshInto(m); + if(lt) lt->MakeMeshInto(m); + + STriangleLl *ll; + for(ll = tris; ll; ll = ll->next) { + if(ll->tri->tag) continue; + + m->AddTriangle(ll->tri); + ll->tri->tag = 1; + } +} + +void SKdNode::ListTrianglesInto(std::vector *tl) const { + if(gt) gt->ListTrianglesInto(tl); + if(lt) lt->ListTrianglesInto(tl); + + STriangleLl *ll; + for(ll = tris; ll; ll = ll->next) { + if(ll->tri->tag) continue; + + tl->push_back(ll->tri); + ll->tri->tag = 1; + } +} + +//----------------------------------------------------------------------------- +// If any triangles in the mesh have an edge that goes through v (but not +// a vertex at v), then split those triangles so that they now have a vertex +// there. The existing triangle is modified, and the new triangle appears +// in extras. +//----------------------------------------------------------------------------- +void SKdNode::SnapToVertex(Vector v, SMesh *extras) { + if(gt && lt) { + double vc = v.Element(which); + if(vc < c + KDTREE_EPS) { + lt->SnapToVertex(v, extras); + } + if(vc > c - KDTREE_EPS) { + gt->SnapToVertex(v, extras); + } + // Nothing bad happens if the triangle to be split appears in both + // branches; the first call will split the triangle, so that the + // second call will do nothing, because the modified triangle will + // already contain v + } else { + STriangleLl *ll; + for(ll = tris; ll; ll = ll->next) { + STriangle *tr = ll->tri; + + // Do a cheap bbox test first + int k; + bool mightHit = true; + + for(k = 0; k < 3; k++) { + double trA = (tr->a).Element(k); + double trB = (tr->b).Element(k); + double trC = (tr->c).Element(k); + double vk = v.Element(k); + if(trA < vk - KDTREE_EPS && + trB < vk - KDTREE_EPS && + trC < vk - KDTREE_EPS) + { + mightHit = false; + break; + } + if(trA > vk + KDTREE_EPS && + trB > vk + KDTREE_EPS && + trC > vk + KDTREE_EPS) + { + mightHit = false; + break; + } + } + if(!mightHit) continue; + + if(tr->a.Equals(v)) { tr->a = v; continue; } + if(tr->b.Equals(v)) { tr->b = v; continue; } + if(tr->c.Equals(v)) { tr->c = v; continue; } + + if(tr->IsDegenerate()) { + continue; + } + + if(v.OnLineSegment(tr->a, tr->b)) { + STriangle nt = STriangle::From(tr->meta, tr->a, v, tr->c); + extras->AddTriangle(&nt); + tr->a = v; + continue; + } + if(v.OnLineSegment(tr->b, tr->c)) { + STriangle nt = STriangle::From(tr->meta, tr->b, v, tr->a); + extras->AddTriangle(&nt); + tr->b = v; + continue; + } + if(v.OnLineSegment(tr->c, tr->a)) { + STriangle nt = STriangle::From(tr->meta, tr->c, v, tr->b); + extras->AddTriangle(&nt); + tr->c = v; + continue; + } + } + } +} + +//----------------------------------------------------------------------------- +// Snap to each vertex of each triangle of the given mesh. If the given mesh +// is identical to the mesh used to make this kd tree, then the result should +// be a vertex-to-vertex mesh. +//----------------------------------------------------------------------------- +void SKdNode::SnapToMesh(SMesh *m) { + int i, j, k; + for(i = 0; i < m->l.n; i++) { + STriangle *tr = &(m->l[i]); + if(tr->IsDegenerate()) { + continue; + } + for(j = 0; j < 3; j++) { + Vector v = tr->vertices[j]; + + SMesh extra = {}; + SnapToVertex(v, &extra); + + for(k = 0; k < extra.l.n; k++) { + STriangle *tra = (STriangle *)AllocTemporary(sizeof(*tra)); + *tra = extra.l[k]; + AddTriangle(tra); + } + extra.Clear(); + } + } +} + +//----------------------------------------------------------------------------- +// For all the edges in sel, split them against the given triangle, and test +// them for occlusion. sel is both our input and our output. tag indicates +// whether an edge is occluded. +//----------------------------------------------------------------------------- +void SKdNode::SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr) const { + SEdgeList seln = {}; + + Vector tn = tr->Normal().WithMagnitude(1); + double td = tn.Dot(tr->a); + + // Consider front-facing triangles only. + if(tn.z > LENGTH_EPS) { + // If the edge crosses our triangle's plane, then split into above + // and below parts. Note that we must preserve auxA, which contains + // the style associated with this line, as well as the tag, which + // contains the occlusion status. + SEdge *se; + for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { + double da = (se->a).Dot(tn) - td, + db = (se->b).Dot(tn) - td; + if((da < -LENGTH_EPS && db > LENGTH_EPS) || + (db < -LENGTH_EPS && da > LENGTH_EPS)) + { + Vector m = Vector::AtIntersectionOfPlaneAndLine( + tn, td, + se->a, se->b, NULL); + seln.AddEdge(m, se->b, se->auxA, 0, se->tag); + se->b = m; + } + } + for(se = seln.l.First(); se; se = seln.l.NextAfter(se)) { + sel->AddEdge(se->a, se->b, se->auxA, 0, se->tag); + } + seln.Clear(); + + for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { + Vector pt = ((se->a).Plus(se->b)).ScaledBy(0.5); + if(pt.Dot(tn) - td > -LENGTH_EPS) { + // Edge is in front of or on our plane (remember, tn.z > 0) + // so it is exempt from further splitting + se->auxB = 1; + } else { + // Edge is behind our plane, needs further splitting + se->auxB = 0; + } + } + + // Considering only the (x, y) coordinates, split the edge against our + // triangle. + Point2d a = (tr->a).ProjectXy(), + b = (tr->b).ProjectXy(), + c = (tr->c).ProjectXy(); + + Point2d n[3] = { (b.Minus(a)).Normal().WithMagnitude(1), + (c.Minus(b)).Normal().WithMagnitude(1), + (a.Minus(c)).Normal().WithMagnitude(1) }; + + double d[3] = { n[0].Dot(b), + n[1].Dot(c), + n[2].Dot(a) }; + + // Split all of the edges where they intersect the triangle edges + int i; + for(i = 0; i < 3; i++) { + for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { + if(se->auxB) continue; + + Point2d ap = (se->a).ProjectXy(), + bp = (se->b).ProjectXy(); + double da = n[i].Dot(ap) - d[i], + db = n[i].Dot(bp) - d[i]; + if((da < -LENGTH_EPS && db > LENGTH_EPS) || + (db < -LENGTH_EPS && da > LENGTH_EPS)) + { + double dab = (db - da); + Vector spl = ((se->a).ScaledBy( db/dab)).Plus( + (se->b).ScaledBy(-da/dab)); + seln.AddEdge(spl, se->b, se->auxA, 0, se->tag); + se->b = spl; + } + } + for(se = seln.l.First(); se; se = seln.l.NextAfter(se)) { + // The split pieces are all behind the triangle, since only + // edges behind the triangle got split. So their auxB is 0. + sel->AddEdge(se->a, se->b, se->auxA, 0, se->tag); + } + seln.Clear(); + } + + for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { + bool occluded; + if(se->auxB) { + // Lies above or on the triangle plane, so triangle doesn't + // occlude it. + occluded = false; + } else { + // Test the segment to see if it lies outside the triangle + // (i.e., outside wrt at least one edge), and keep it only + // then. + Point2d pt = ((se->a).Plus(se->b).ScaledBy(0.5)).ProjectXy(); + occluded = true; + for(i = 0; i < 3; i++) { + // If the test point lies on the boundary of our triangle, + // then we still discard the edge. + if(n[i].Dot(pt) - d[i] > LENGTH_EPS) occluded = false; + } + } + + if(occluded) { + se->tag = 1; + } + } + } +} + +//----------------------------------------------------------------------------- +// Given an edge orig, occlusion test it against our mesh. We output an edge +// list in sel, where only invisible portions of the edge are tagged. +//----------------------------------------------------------------------------- +void SKdNode::OcclusionTestLine(SEdge orig, SEdgeList *sel, int cnt) const { + if(gt && lt) { + double ac = (orig.a).Element(which), + bc = (orig.b).Element(which); + // We can ignore triangles that are separated in x or y, but triangles + // that are separated in z may still contribute + if(ac < c + KDTREE_EPS || + bc < c + KDTREE_EPS || + which == 2) + { + lt->OcclusionTestLine(orig, sel, cnt); + } + if(ac > c - KDTREE_EPS || + bc > c - KDTREE_EPS || + which == 2) + { + gt->OcclusionTestLine(orig, sel, cnt); + } + } else { + STriangleLl *ll; + for(ll = tris; ll; ll = ll->next) { + STriangle *tr = ll->tri; + + if(tr->tag == cnt) continue; + + SplitLinesAgainstTriangle(sel, tr); + tr->tag = cnt; + } + } +} + +//----------------------------------------------------------------------------- +// Search the mesh for a triangle with an edge from b to a (i.e., the mate +// for the edge from a to b), and increment info->count each time that we +// find one. If a triangle is found, then report whether it is front- or +// back-facing using info->frontFacing. And regardless of whether a mate is +// found, report whether the edge intersects the mesh with info->intersectsMesh; +// if coplanarIsInter then we count the edge as intersecting if it's coplanar +// with a triangle in the mesh, otherwise not. +//----------------------------------------------------------------------------- +void SKdNode::FindEdgeOn(Vector a, Vector b, int cnt, bool coplanarIsInter, + EdgeOnInfo *info) const +{ + if(gt && lt) { + double ac = a.Element(which), + bc = b.Element(which); + if(ac < c + KDTREE_EPS || + bc < c + KDTREE_EPS) + { + lt->FindEdgeOn(a, b, cnt, coplanarIsInter, info); + } + if(ac > c - KDTREE_EPS || + bc > c - KDTREE_EPS) + { + gt->FindEdgeOn(a, b, cnt, coplanarIsInter, info); + } + return; + } + + // We are a leaf node; so we iterate over all the triangles in our + // linked list. + STriangleLl *ll; + for(ll = tris; ll; ll = ll->next) { + STriangle *tr = ll->tri; + + if(tr->tag == cnt) continue; + + // Test if this triangle matches up with the given edge + if((a.Equals(tr->b) && b.Equals(tr->a)) || + (a.Equals(tr->c) && b.Equals(tr->b)) || + (a.Equals(tr->a) && b.Equals(tr->c))) + { + info->count++; + // Record whether this triangle is front- or back-facing. + if(tr->Normal().z > LENGTH_EPS) { + info->frontFacing = true; + } else { + info->frontFacing = false; + } + // Record the triangle + info->tr = tr; + // And record which vertices a and b correspond to + info->ai = a.Equals(tr->a) ? 0 : (a.Equals(tr->b) ? 1 : 2); + info->bi = b.Equals(tr->a) ? 0 : (b.Equals(tr->b) ? 1 : 2); + } else if(((a.Equals(tr->a) && b.Equals(tr->b)) || + (a.Equals(tr->b) && b.Equals(tr->c)) || + (a.Equals(tr->c) && b.Equals(tr->a)))) + { + // It's an edge of this triangle, okay. + } else { + // Check for self-intersection + Vector n = (tr->Normal()).WithMagnitude(1); + double d = (tr->a).Dot(n); + double pa = a.Dot(n) - d, pb = b.Dot(n) - d; + // It's an intersection if neither point lies in-plane, + // and the edge crosses the plane (should handle in-plane + // intersections separately but don't yet). + if((pa < -LENGTH_EPS || pa > LENGTH_EPS) && + (pb < -LENGTH_EPS || pb > LENGTH_EPS) && + (pa*pb < 0)) + { + // The edge crosses the plane of the triangle; now see if + // it crosses inside the triangle. + if(tr->ContainsPointProjd(b.Minus(a), a)) { + if(coplanarIsInter) { + info->intersectsMesh = true; + } else { + Vector p = Vector::AtIntersectionOfPlaneAndLine( + n, d, a, b, NULL); + Vector ta = tr->a, + tb = tr->b, + tc = tr->c; + if((p.DistanceToLine(ta, tb.Minus(ta)) < LENGTH_EPS) || + (p.DistanceToLine(tb, tc.Minus(tb)) < LENGTH_EPS) || + (p.DistanceToLine(tc, ta.Minus(tc)) < LENGTH_EPS)) + { + // Intersection lies on edge. This happens when + // our edge is from a triangle coplanar with + // another triangle in the mesh. We don't test + // the edge against triangles whose plane contains + // that edge, but we do end up testing against + // the coplanar triangle's neighbours, which we + // will intersect on their edges. + } else { + info->intersectsMesh = true; + } + } + } + } + } + + // Ensure that we don't count this triangle twice if it appears + // in two buckets of the kd tree. + tr->tag = cnt; + } +} + +static bool CheckAndAddTrianglePair(std::set> *pairs, + STriangle *a, STriangle *b) +{ + if(pairs->find(std::make_pair(a, b)) != pairs->end() || + pairs->find(std::make_pair(b, a)) != pairs->end()) + return true; + + pairs->emplace(a, b); + return false; +} + +//----------------------------------------------------------------------------- +// Pick certain classes of edges out from our mesh. These might be: +// * naked edges (i.e., edges with no anti-parallel neighbor) and self- +// intersecting edges (i.e., edges that cross another triangle) +// * turning edges (i.e., edges where a front-facing triangle joins +// a back-facing triangle) +// * emphasized edges (i.e., edges where a triangle from one face joins +// a triangle from a different face) +//----------------------------------------------------------------------------- +void SKdNode::MakeCertainEdgesInto(SEdgeList *sel, EdgeKind how, bool coplanarIsInter, + bool *inter, bool *leaky, int auxA) const +{ + if(inter) *inter = false; + if(leaky) *leaky = false; + + std::vector tris; + ClearTags(); + ListTrianglesInto(&tris); + + std::set> edgeTris; + int cnt = 1234; + for(STriangle *tr : tris) { + for(int j = 0; j < 3; j++) { + Vector a = tr->vertices[j]; + Vector b = tr->vertices[(j + 1) % 3]; + + SKdNode::EdgeOnInfo info = {}; + FindEdgeOn(a, b, cnt, coplanarIsInter, &info); + + switch(how) { + case EdgeKind::NAKED_OR_SELF_INTER: + // there should be one anti-parllel edge + if(info.count != 1) { + // but there may be multiple parallel coincident edges + SKdNode::EdgeOnInfo parallelInfo = {}; + FindEdgeOn(b, a, -cnt, coplanarIsInter, ¶llelInfo); + if (info.count != parallelInfo.count) { + sel->AddEdge(a, b, auxA); + if(leaky) *leaky = true; + } + } + if(info.intersectsMesh) { + sel->AddEdge(a, b, auxA); + if(inter) *inter = true; + } + break; + + case EdgeKind::SELF_INTER: + if(info.intersectsMesh) { + sel->AddEdge(a, b, auxA); + if(inter) *inter = true; + } + break; + + case EdgeKind::TURNING: + if((tr->Normal().z < LENGTH_EPS) && + (info.count == 1) && + info.frontFacing) + { + if(CheckAndAddTrianglePair(&edgeTris, tr, info.tr)) + break; + // This triangle is back-facing (or on edge), and + // this edge has exactly one mate, and that mate is + // front-facing. So this is a turning edge. + sel->AddEdge(a, b, auxA); + } + break; + + case EdgeKind::EMPHASIZED: + if(info.count == 1 && tr->meta.face != info.tr->meta.face) { + if(CheckAndAddTrianglePair(&edgeTris, tr, info.tr)) + break; + // The two triangles that join at this edge come from + // different faces; either really different faces, + // or one is from a face and the other is zero (i.e., + // not from a face). + sel->AddEdge(a, b, auxA); + } + break; + + case EdgeKind::SHARP: + if(info.count == 1) { + Vector na0 = tr->normals[j].WithMagnitude(1.0); + Vector nb0 = tr->normals[(j + 1) % 3].WithMagnitude(1.0); + Vector na1 = info.tr->normals[info.ai].WithMagnitude(1.0); + Vector nb1 = info.tr->normals[info.bi].WithMagnitude(1.0); + if(!((na0.Equals(na1) && nb0.Equals(nb1)) || + (na0.Equals(nb1) && nb0.Equals(na1)))) { + if(CheckAndAddTrianglePair(&edgeTris, tr, info.tr)) + break; + // The two triangles that join at this edge meet at a sharp + // angle. This implies they come from different faces. + sel->AddEdge(a, b, auxA); + } + } + break; + } + + cnt++; + } + } +} + +void SKdNode::MakeOutlinesInto(SOutlineList *sol, EdgeKind edgeKind) const +{ + std::vector tris; + ClearTags(); + ListTrianglesInto(&tris); + + std::set> edgeTris; + int cnt = 1234; + for(STriangle *tr : tris) { + for(int j = 0; j < 3; j++) { + Vector a = tr->vertices[j]; + Vector b = tr->vertices[(j + 1) % 3]; + + SKdNode::EdgeOnInfo info = {}; + FindEdgeOn(a, b, cnt, /*coplanarIsInter=*/false, &info); + cnt++; + if(info.count != 1) continue; + if(CheckAndAddTrianglePair(&edgeTris, tr, info.tr)) + continue; + + int tag = 0; + switch(edgeKind) { + case EdgeKind::EMPHASIZED: + if(tr->meta.face != info.tr->meta.face) { + tag = 1; + } + break; + + case EdgeKind::SHARP: { + Vector na0 = tr->normals[j].WithMagnitude(1.0); + Vector nb0 = tr->normals[(j + 1) % 3].WithMagnitude(1.0); + Vector na1 = info.tr->normals[info.ai].WithMagnitude(1.0); + Vector nb1 = info.tr->normals[info.bi].WithMagnitude(1.0); + if(!((na0.Equals(na1) && nb0.Equals(nb1)) || + (na0.Equals(nb1) && nb0.Equals(na1)))) { + tag = 1; + } + } + break; + + default: + ssassert(false, "Unexpected edge kind"); + } + + Vector nl = tr->Normal().WithMagnitude(1.0); + Vector nr = info.tr->Normal().WithMagnitude(1.0); + + // We don't add edges with the same left and right + // normals because they can't produce outlines. + if(tag == 0 && nl.Equals(nr)) continue; + sol->AddEdge(a, b, nl, nr, tag); + } + } +} + +bool SOutline::IsVisible(Vector projDir) const { + double ldot = nl.Dot(projDir); + double rdot = nr.Dot(projDir); + return (ldot > -LENGTH_EPS) == (rdot < LENGTH_EPS) || + (rdot > -LENGTH_EPS) == (ldot < LENGTH_EPS); +} + +void SOutlineList::Clear() { + l.Clear(); +} + +void SOutlineList::AddEdge(Vector a, Vector b, Vector nl, Vector nr, int tag) { + SOutline so = {}; + so.a = a; + so.b = b; + so.nl = nl; + so.nr = nr; + so.tag = tag; + l.Add(&so); +} + +void SOutlineList::ListTaggedInto(SEdgeList *el, int auxA, int auxB) { + for(const SOutline &so : l) { + if(so.tag == 0) continue; + el->AddEdge(so.a, so.b, auxA, auxB); + } +} + +void SOutlineList::MakeFromCopyOf(SOutlineList *sol) { + for(SOutline *so = sol->l.First(); so; so = sol->l.NextAfter(so)) { + l.Add(so); + } +} + +void SMesh::PrecomputeTransparency() { + std::sort(l.begin(), l.end(), + [&](const STriangle &sta, const STriangle &stb) { + RgbaColor colora = sta.meta.color, + colorb = stb.meta.color; + bool opaquea = colora.IsEmpty() || colora.alpha == 255, + opaqueb = colorb.IsEmpty() || colorb.alpha == 255; + + if(!opaquea || !opaqueb) isTransparent = true; + return (opaquea != opaqueb && opaquea == true); + }); +} + +void SMesh::RemoveDegenerateTriangles() { + for(auto &tr : l) { + tr.tag = (int)tr.IsDegenerate(); + } + l.RemoveTagged(); +} + +double SMesh::CalculateVolume() const { + double vol = 0; + for(STriangle tr : l) { + // Translate to place vertex A at (x, y, 0) + Vector trans = Vector::From(tr.a.x, tr.a.y, 0); + tr.a = (tr.a).Minus(trans); + tr.b = (tr.b).Minus(trans); + tr.c = (tr.c).Minus(trans); + + // Rotate to place vertex B on the y-axis. Depending on + // whether the triangle is CW or CCW, C is either to the + // right or to the left of the y-axis. This handles the + // sign of our normal. + Vector u = Vector::From(-tr.b.y, tr.b.x, 0); + u = u.WithMagnitude(1); + Vector v = Vector::From(tr.b.x, tr.b.y, 0); + v = v.WithMagnitude(1); + Vector n = Vector::From(0, 0, 1); + + tr.a = (tr.a).DotInToCsys(u, v, n); + tr.b = (tr.b).DotInToCsys(u, v, n); + tr.c = (tr.c).DotInToCsys(u, v, n); + + n = tr.Normal().WithMagnitude(1); + + // Triangles on edge don't contribute + if(fabs(n.z) < LENGTH_EPS) continue; + + // The plane has equation p dot n = a dot n + double d = (tr.a).Dot(n); + // nx*x + ny*y + nz*z = d + // nz*z = d - nx*x - ny*y + double A = -n.x/n.z, B = -n.y/n.z, C = d/n.z; + + double mac = tr.c.y/tr.c.x, mbc = (tr.c.y - tr.b.y)/tr.c.x; + double xc = tr.c.x, yb = tr.b.y; + + // I asked Maple for + // int(int(A*x + B*y +C, y=mac*x..(mbc*x + yb)), x=0..xc); + double integral = + (1.0/3)*( + A*(mbc-mac)+ + (1.0/2)*B*(mbc*mbc-mac*mac) + )*(xc*xc*xc)+ + (1.0/2)*(A*yb+B*yb*mbc+C*(mbc-mac))*xc*xc+ + C*yb*xc+ + (1.0/2)*B*yb*yb*xc; + + vol += integral; + } + return vol; +} + +double SMesh::CalculateSurfaceArea(const std::vector &faces) const { + double area = 0.0; + for(uint32_t f : faces) { + for(const STriangle &t : l) { + if(f != t.meta.face) continue; + area += t.Area(); + } + } + return area; +} diff --git a/src/modify.cpp b/src/modify.cpp new file mode 100644 index 0000000..94b2478 --- /dev/null +++ b/src/modify.cpp @@ -0,0 +1,745 @@ +//----------------------------------------------------------------------------- +// User-initiated (not parametric) operations to modify our sketch, by +// changing the requests, like to round a corner or split curves where they +// intersect. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +//----------------------------------------------------------------------------- +// Replace constraints on oldpt with the same constraints on newpt. +// Useful when splitting, tangent arcing, or removing bezier points. +//----------------------------------------------------------------------------- +void GraphicsWindow::ReplacePointInConstraints(hEntity oldpt, hEntity newpt) { + for(auto &c : SK.constraint) { + if(c.ptA == oldpt) + c.ptA = newpt; + if(c.ptB == oldpt) + c.ptB = newpt; + } +} + +//----------------------------------------------------------------------------- +// Remove constraints on hpt. Useful when removing bezier points. +//----------------------------------------------------------------------------- +void GraphicsWindow::RemoveConstraintsForPointBeingDeleted(hEntity hpt) { + SK.constraint.ClearTags(); + for(auto &c : SK.constraint) { + if(c.ptA == hpt || c.ptB == hpt) { + c.tag = 1; + (SS.deleted.constraints)++; + if(c.type != Constraint::Type::POINTS_COINCIDENT && + c.type != Constraint::Type::HORIZONTAL && + c.type != Constraint::Type::VERTICAL) + { + (SS.deleted.nonTrivialConstraints)++; + } + } + } + SK.constraint.RemoveTagged(); +} + +//----------------------------------------------------------------------------- +// Let's say that A is coincident with B, and B is coincident with C. This +// implies that A is coincident with C; but if we delete B, then both +// constraints must be deleted too (since they reference B), and A is no +// longer constrained to C. This routine adds back that constraint. +//----------------------------------------------------------------------------- +void GraphicsWindow::FixConstraintsForRequestBeingDeleted(hRequest hr) { + Request *r = SK.GetRequest(hr); + if(r->group != SS.GW.activeGroup) return; + + Entity *e; + for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) { + if(!(e->h.isFromRequest())) continue; + if(e->h.request() != hr) continue; + + if(e->type != Entity::Type::POINT_IN_2D && + e->type != Entity::Type::POINT_IN_3D) + { + continue; + } + + // This is a point generated by the request being deleted; so fix + // the constraints for that. + FixConstraintsForPointBeingDeleted(e->h); + } +} +void GraphicsWindow::FixConstraintsForPointBeingDeleted(hEntity hpt) { + List ld = {}; + + Constraint *c; + SK.constraint.ClearTags(); + for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) { + if(c->type != Constraint::Type::POINTS_COINCIDENT) continue; + if(c->group != SS.GW.activeGroup) continue; + + if(c->ptA == hpt) { + ld.Add(&(c->ptB)); + c->tag = 1; + } + if(c->ptB == hpt) { + ld.Add(&(c->ptA)); + c->tag = 1; + } + } + // Remove constraints without waiting for regeneration; this way + // if another point takes the place of the deleted one (e.g. when + // removing control points of a bezier) the constraint doesn't + // spuriously move. Similarly, subsequent calls of this function + // (if multiple coincident points are getting deleted) will work + // correctly. + SK.constraint.RemoveTagged(); + + // If more than one point was constrained coincident with hpt, then + // those two points were implicitly coincident with each other. By + // deleting hpt (and all constraints that mention it), we will delete + // that relationship. So put it back here now. + for(int i = 1; i < ld.n; i++) { + Constraint::ConstrainCoincident(ld[i-1], ld[i]); + } + ld.Clear(); +} + +//----------------------------------------------------------------------------- +// A curve by its parametric equation, helper functions for computing tangent +// arcs by a numerical method. +//----------------------------------------------------------------------------- +void GraphicsWindow::ParametricCurve::MakeFromEntity(hEntity he, bool reverse) { + *this = {}; + Entity *e = SK.GetEntity(he); + if(e->type == Entity::Type::LINE_SEGMENT) { + isLine = true; + p0 = e->EndpointStart(), + p1 = e->EndpointFinish(); + if(reverse) { + swap(p0, p1); + } + } else if(e->type == Entity::Type::ARC_OF_CIRCLE) { + isLine = false; + p0 = SK.GetEntity(e->point[0])->PointGetNum(); + Vector pe = SK.GetEntity(e->point[1])->PointGetNum(); + r = (pe.Minus(p0)).Magnitude(); + e->ArcGetAngles(&theta0, &theta1, &dtheta); + if(reverse) { + swap(theta0, theta1); + dtheta = -dtheta; + } + EntityBase *wrkpln = SK.GetEntity(e->workplane)->Normal(); + u = wrkpln->NormalU(); + v = wrkpln->NormalV(); + } else ssassert(false, "Unexpected entity type"); +} +double GraphicsWindow::ParametricCurve::LengthForAuto() { + if(isLine) { + // Allow a third of the line to disappear with auto radius + return (p1.Minus(p0)).Magnitude() / 3; + } else { + // But only a twentieth of the arc; shorter means fewer numerical + // problems since the curve is more linear over shorter sections. + return (fabs(dtheta)*r)/20; + } +} +Vector GraphicsWindow::ParametricCurve::PointAt(double t) { + if(isLine) { + return p0.Plus((p1.Minus(p0)).ScaledBy(t)); + } else { + double theta = theta0 + dtheta*t; + return p0.Plus(u.ScaledBy(r*cos(theta)).Plus(v.ScaledBy(r*sin(theta)))); + } +} +Vector GraphicsWindow::ParametricCurve::TangentAt(double t) { + if(isLine) { + return p1.Minus(p0); + } else { + double theta = theta0 + dtheta*t; + Vector t = u.ScaledBy(-r*sin(theta)).Plus(v.ScaledBy(r*cos(theta))); + t = t.ScaledBy(dtheta); + return t; + } +} +/** Changes or copies the given entity and connects it to the arc. + * \param t Where on this parametric curve does it connect to the arc. + * \param reuseOrig Should the original entity be modified + * \param orig The original entity. + * \param arc The arc that will be connected to. + * \param arcFinish Whether to connect to the end point of the arc. + * \param pointf When changing the original entity, whether the end point should be modified. + */ +void GraphicsWindow::ParametricCurve::CreateRequestTrimmedTo(double t, + bool reuseOrig, hEntity orig, hEntity arc, bool arcFinish, bool pointf) +{ + hRequest hr; + Entity *e; + if(isLine) { + if (reuseOrig) { + e = SK.GetEntity(orig); + int i = pointf ? 1 : 0; + SK.GetEntity(e->point[i])->PointForceTo(PointAt(t)); + ConstrainPointIfCoincident(e->point[i]); + } else { + hr = SS.GW.AddRequest(Request::Type::LINE_SEGMENT, /*rememberForUndo=*/false), + e = SK.GetEntity(hr.entity(0)); + SK.GetEntity(e->point[0])->PointForceTo(PointAt(t)); + SK.GetEntity(e->point[1])->PointForceTo(PointAt(1)); + ConstrainPointIfCoincident(e->point[0]); + ConstrainPointIfCoincident(e->point[1]); + Constraint::Constrain(Constraint::Type::PT_ON_LINE, + hr.entity(1), Entity::NO_ENTITY, orig); + } + Constraint::Constrain(Constraint::Type::ARC_LINE_TANGENT, + Entity::NO_ENTITY, Entity::NO_ENTITY, + arc, e->h, /*other=*/arcFinish, /*other2=*/false); + } else { + if (reuseOrig) { + e = SK.GetEntity(orig); + int i = pointf ? 2 : 1; + SK.GetEntity(e->point[i])->PointForceTo(PointAt(t)); + ConstrainPointIfCoincident(e->point[i]); + } else { + hr = SS.GW.AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false), + e = SK.GetEntity(hr.entity(0)); + SK.GetEntity(e->point[0])->PointForceTo(p0); + if(dtheta > 0) { + SK.GetEntity(e->point[1])->PointForceTo(PointAt(t)); + SK.GetEntity(e->point[2])->PointForceTo(PointAt(1)); + } else { + SK.GetEntity(e->point[2])->PointForceTo(PointAt(t)); + SK.GetEntity(e->point[1])->PointForceTo(PointAt(1)); + } + ConstrainPointIfCoincident(e->point[0]); + ConstrainPointIfCoincident(e->point[1]); + ConstrainPointIfCoincident(e->point[2]); + } + // The tangency constraint alone is enough to fully constrain it, + // so there's no need for more. + Constraint::Constrain(Constraint::Type::CURVE_CURVE_TANGENT, + Entity::NO_ENTITY, Entity::NO_ENTITY, + arc, e->h, /*other=*/arcFinish, /*other2=*/(dtheta < 0)); + } +} + +//----------------------------------------------------------------------------- +// If a point in the same group as hpt, and numerically coincident with hpt, +// happens to exist, then constrain that point coincident to hpt. +//----------------------------------------------------------------------------- +void GraphicsWindow::ParametricCurve::ConstrainPointIfCoincident(hEntity hpt) { + Entity *e, *pt; + pt = SK.GetEntity(hpt); + Vector ev, ptv; + ptv = pt->PointGetNum(); + + for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) { + if(e->h == pt->h) continue; + if(!e->IsPoint()) continue; + if(e->group != pt->group) continue; + if(e->workplane != pt->workplane) continue; + + ev = e->PointGetNum(); + if(!ev.Equals(ptv)) continue; + + Constraint::ConstrainCoincident(hpt, e->h); + break; + } +} + +//----------------------------------------------------------------------------- +// A single point must be selected when this function is called. We find two +// non-construction line segments that join at this point, and create a +// tangent arc joining them. +//----------------------------------------------------------------------------- +void GraphicsWindow::MakeTangentArc() { + if(!LockedInWorkplane()) { + Error(_("Must be sketching in workplane to create tangent arc.")); + return; + } + + // The point corresponding to the vertex to be rounded. + Vector pshared = SK.GetEntity(gs.point[0])->PointGetNum(); + ClearSelection(); + + // First, find two requests (that are not construction, and that are + // in our group and workplane) that generate entities that have an + // endpoint at our vertex to be rounded. + int i, c = 0; + Entity *ent[2]; + Request *req[2]; + hRequest hreq[2]; + hEntity hent[2]; + bool pointf[2]; + for(auto &r : SK.request) { + if(r.group != activeGroup) + continue; + if(r.workplane != ActiveWorkplane()) + continue; + if(r.construction) + continue; + if(r.type != Request::Type::LINE_SEGMENT && r.type != Request::Type::ARC_OF_CIRCLE) { + continue; + } + + Entity *e = SK.GetEntity(r.h.entity(0)); + Vector ps = e->EndpointStart(), + pf = e->EndpointFinish(); + + if(ps.Equals(pshared) || pf.Equals(pshared)) { + if(c < 2) { + // We record the entity and request and their handles, + // and whether the vertex to be rounded is the start or + // finish of this entity. + ent[c] = e; + hent[c] = e->h; + req[c] = &r; + hreq[c] = r.h; + pointf[c] = (pf.Equals(pshared)); + } + c++; + } + } + if(c != 2) { + Error(_("To create a tangent arc, select a point where two " + "non-construction lines or circles in this group and " + "workplane join.")); + return; + } + + Entity *wrkpl = SK.GetEntity(ActiveWorkplane()); + Vector wn = wrkpl->Normal()->NormalN(); + + // Based on these two entities, we make the objects that we'll use to + // numerically find the tangent arc. + ParametricCurve pc[2]; + pc[0].MakeFromEntity(ent[0]->h, pointf[0]); + pc[1].MakeFromEntity(ent[1]->h, pointf[1]); + + // And thereafter we mustn't touch the entity or req ptrs, + // because the new requests/entities we add might force a + // realloc. + memset(ent, 0, sizeof(ent)); + memset(req, 0, sizeof(req)); + + Vector pinter; + double r = 0.0, vv = 0.0; + // We now do Newton iterations to find the tangent arc, and its positions + // t back along the two curves, starting from shared point of the curves + // at t = 0. Lots of iterations helps convergence, and this is still + // ~10 ms for everything. + int iters = 1000; + double t[2] = { 0, 0 }, tp[2]; + for(i = 0; i < iters + 20; i++) { + Vector p0 = pc[0].PointAt(t[0]), + p1 = pc[1].PointAt(t[1]), + t0 = pc[0].TangentAt(t[0]), + t1 = pc[1].TangentAt(t[1]); + + pinter = Vector::AtIntersectionOfLines(p0, p0.Plus(t0), + p1, p1.Plus(t1), + NULL, NULL, NULL); + + // The sign of vv determines whether shortest distance is + // clockwise or anti-clockwise. + Vector v = (wn.Cross(t0)).WithMagnitude(1); + vv = t1.Dot(v); + + double dot = (t0.WithMagnitude(1)).Dot(t1.WithMagnitude(1)); + double theta = acos(dot); + + if(SS.tangentArcManual) { + r = SS.tangentArcRadius; + } else { + r = 200/scale; + // Set the radius so that no more than one third of the + // line segment disappears. + r = min(r, pc[0].LengthForAuto()*tan(theta/2)); + r = min(r, pc[1].LengthForAuto()*tan(theta/2));; + } + // We are source-stepping the radius, to improve convergence. So + // ramp that for most of the iterations, and then do a few at + // the end with that constant for polishing. + if(i < iters) { + r *= 0.1 + 0.9*i/((double)iters); + } + + // The distance from the intersection of the lines to the endpoint + // of the arc, along each line. + double el = r/tan(theta/2); + + // Compute the endpoints of the arc, for each curve + Vector pa0 = pinter.Plus(t0.WithMagnitude(el)), + pa1 = pinter.Plus(t1.WithMagnitude(el)); + + tp[0] = t[0]; + tp[1] = t[1]; + + // And convert those points to parameter values along the curve. + t[0] += (pa0.Minus(p0)).DivProjected(t0); + t[1] += (pa1.Minus(p1)).DivProjected(t1); + } + + // Stupid check for convergence, and for an out of range result (as + // we would get, for example, if the line is too short to fit the + // rounding arc). + if(fabs(tp[0] - t[0]) > 1e-3 || fabs(tp[1] - t[1]) > 1e-3 || + t[0] < 0.01 || t[1] < 0.01 || + t[0] > 0.99 || t[1] > 0.99 || + IsReasonable(t[0]) || IsReasonable(t[1])) + { + Error(_("Couldn't round this corner. Try a smaller radius, or try " + "creating the desired geometry by hand with tangency " + "constraints.")); + return; + } + + // Compute the location of the center of the arc + Vector center = pc[0].PointAt(t[0]), + v0inter = pinter.Minus(center); + int a, b; + if(vv < 0) { + a = 1; b = 2; + center = center.Minus(v0inter.Cross(wn).WithMagnitude(r)); + } else { + a = 2; b = 1; + center = center.Plus(v0inter.Cross(wn).WithMagnitude(r)); + } + + SS.UndoRemember(); + + if (SS.tangentArcModify) { + // Delete the coincident constraint for the removed point. + SK.constraint.ClearTags(); + for(i = 0; i < SK.constraint.n; i++) { + Constraint *cs = &(SK.constraint[i]); + if(cs->group != activeGroup) continue; + if(cs->workplane != ActiveWorkplane()) continue; + if(cs->type != Constraint::Type::POINTS_COINCIDENT) continue; + if (SK.GetEntity(cs->ptA)->PointGetNum().Equals(pshared)) { + cs->tag = 1; + } + } + SK.constraint.RemoveTagged(); + } else { + // Make the original entities construction, or delete them + // entirely, according to user preference. + SK.GetRequest(hreq[0])->construction = true; + SK.GetRequest(hreq[1])->construction = true; + } + + // Create and position the new tangent arc. + hRequest harc = AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false); + Entity *earc = SK.GetEntity(harc.entity(0)); + hEntity hearc = earc->h; + + SK.GetEntity(earc->point[0])->PointForceTo(center); + SK.GetEntity(earc->point[a])->PointForceTo(pc[0].PointAt(t[0])); + SK.GetEntity(earc->point[b])->PointForceTo(pc[1].PointAt(t[1])); + + earc = NULL; + + // Modify or duplicate the original entities and connect them to the tangent arc. + pc[0].CreateRequestTrimmedTo(t[0], SS.tangentArcModify, + hent[0], hearc, /*arcFinish=*/(b == 1), pointf[0]); + pc[1].CreateRequestTrimmedTo(t[1], SS.tangentArcModify, + hent[1], hearc, /*arcFinish=*/(a == 1), pointf[1]); +} + +hEntity GraphicsWindow::SplitLine(hEntity he, Vector pinter) { + // Save the original endpoints, since we're about to delete this entity. + Entity *e01 = SK.GetEntity(he); + hEntity hep0 = e01->point[0], hep1 = e01->point[1]; + Vector p0 = SK.GetEntity(hep0)->PointGetNum(), + p1 = SK.GetEntity(hep1)->PointGetNum(); + + // Add the two line segments this one gets split into. + hRequest r0i = AddRequest(Request::Type::LINE_SEGMENT, /*rememberForUndo=*/false), + ri1 = AddRequest(Request::Type::LINE_SEGMENT, /*rememberForUndo=*/false); + // Don't get entities till after adding, realloc issues + + Entity *e0i = SK.GetEntity(r0i.entity(0)), + *ei1 = SK.GetEntity(ri1.entity(0)); + + SK.GetEntity(e0i->point[0])->PointForceTo(p0); + SK.GetEntity(e0i->point[1])->PointForceTo(pinter); + SK.GetEntity(ei1->point[0])->PointForceTo(pinter); + SK.GetEntity(ei1->point[1])->PointForceTo(p1); + + ReplacePointInConstraints(hep0, e0i->point[0]); + ReplacePointInConstraints(hep1, ei1->point[1]); + Constraint::ConstrainCoincident(e0i->point[1], ei1->point[0]); + return e0i->point[1]; +} + +hEntity GraphicsWindow::SplitCircle(hEntity he, Vector pinter) { + Entity *circle = SK.GetEntity(he); + if(circle->type == Entity::Type::CIRCLE) { + // Start with an unbroken circle, split it into a 360 degree arc. + Vector center = SK.GetEntity(circle->point[0])->PointGetNum(); + + circle = NULL; // shortly invalid! + hRequest hr = AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false); + + Entity *arc = SK.GetEntity(hr.entity(0)); + + SK.GetEntity(arc->point[0])->PointForceTo(center); + SK.GetEntity(arc->point[1])->PointForceTo(pinter); + SK.GetEntity(arc->point[2])->PointForceTo(pinter); + + Constraint::ConstrainCoincident(arc->point[1], arc->point[2]); + return arc->point[1]; + } else { + // Start with an arc, break it in to two arcs + hEntity hc = circle->point[0], + hs = circle->point[1], + hf = circle->point[2]; + Vector center = SK.GetEntity(hc)->PointGetNum(), + start = SK.GetEntity(hs)->PointGetNum(), + finish = SK.GetEntity(hf)->PointGetNum(); + + circle = NULL; // shortly invalid! + hRequest hr0 = AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false), + hr1 = AddRequest(Request::Type::ARC_OF_CIRCLE, /*rememberForUndo=*/false); + + Entity *arc0 = SK.GetEntity(hr0.entity(0)), + *arc1 = SK.GetEntity(hr1.entity(0)); + + SK.GetEntity(arc0->point[0])->PointForceTo(center); + SK.GetEntity(arc0->point[1])->PointForceTo(start); + SK.GetEntity(arc0->point[2])->PointForceTo(pinter); + + SK.GetEntity(arc1->point[0])->PointForceTo(center); + SK.GetEntity(arc1->point[1])->PointForceTo(pinter); + SK.GetEntity(arc1->point[2])->PointForceTo(finish); + + ReplacePointInConstraints(hs, arc0->point[1]); + ReplacePointInConstraints(hf, arc1->point[2]); + Constraint::ConstrainCoincident(arc0->point[2], arc1->point[1]); + return arc0->point[2]; + } +} + +hEntity GraphicsWindow::SplitCubic(hEntity he, Vector pinter) { + // Save the original endpoints, since we're about to delete this entity. + Entity *e01 = SK.GetEntity(he); + SBezierList sbl = {}; + e01->GenerateBezierCurves(&sbl); + + hEntity hep0 = e01->point[0], + hep1 = e01->point[3+e01->extraPoints], + hep0n = Entity::NO_ENTITY, // the new start point + hep1n = Entity::NO_ENTITY, // the new finish point + hepin = Entity::NO_ENTITY; // the intersection point + + // The curve may consist of multiple cubic segments. So find which one + // contains the intersection point. + double t; + int i, j; + for(i = 0; i < sbl.l.n; i++) { + SBezier *sb = &(sbl.l[i]); + ssassert(sb->deg == 3, "Expected a cubic bezier"); + + sb->ClosestPointTo(pinter, &t, /*mustConverge=*/false); + if(pinter.Equals(sb->PointAt(t))) { + // Split that segment at the intersection. + SBezier b0i, bi1, b01 = *sb; + b01.SplitAt(t, &b0i, &bi1); + + // Add the two cubic segments this one gets split into. + hRequest r0i = AddRequest(Request::Type::CUBIC, /*rememberForUndo=*/false), + ri1 = AddRequest(Request::Type::CUBIC, /*rememberForUndo=*/false); + // Don't get entities till after adding, realloc issues + + Entity *e0i = SK.GetEntity(r0i.entity(0)), + *ei1 = SK.GetEntity(ri1.entity(0)); + + for(j = 0; j <= 3; j++) { + SK.GetEntity(e0i->point[j])->PointForceTo(b0i.ctrl[j]); + } + for(j = 0; j <= 3; j++) { + SK.GetEntity(ei1->point[j])->PointForceTo(bi1.ctrl[j]); + } + + Constraint::ConstrainCoincident(e0i->point[3], ei1->point[0]); + if(i == 0) hep0n = e0i->point[0]; + hep1n = ei1->point[3]; + hepin = e0i->point[3]; + } else { + hRequest r = AddRequest(Request::Type::CUBIC, /*rememberForUndo=*/false); + Entity *e = SK.GetEntity(r.entity(0)); + + for(j = 0; j <= 3; j++) { + SK.GetEntity(e->point[j])->PointForceTo(sb->ctrl[j]); + } + + if(i == 0) hep0n = e->point[0]; + hep1n = e->point[3]; + } + } + + sbl.Clear(); + + ReplacePointInConstraints(hep0, hep0n); + ReplacePointInConstraints(hep1, hep1n); + return hepin; +} + +hEntity GraphicsWindow::SplitEntity(hEntity he, Vector pinter) { + Entity *e = SK.GetEntity(he); + Entity::Type entityType = e->type; + + hEntity ret; + if(e->IsCircle()) { + ret = SplitCircle(he, pinter); + } else if(e->type == Entity::Type::LINE_SEGMENT) { + ret = SplitLine(he, pinter); + } else if(e->type == Entity::Type::CUBIC || e->type == Entity::Type::CUBIC_PERIODIC) { + ret = SplitCubic(he, pinter); + } else { + Error(_("Couldn't split this entity; lines, circles, or cubics only.")); + return Entity::NO_ENTITY; + } + + // Finally, delete the request that generated the original entity. + Request::Type reqType = EntReqTable::GetRequestForEntity(entityType); + SK.request.ClearTags(); + for(auto &r : SK.request) { + if(r.group != activeGroup) + continue; + if(r.type != reqType) + continue; + + // If the user wants to keep the old entities around, they can just + // mark them construction first. + if(he == r.h.entity(0) && !r.construction) { + r.tag = 1; + break; + } + } + DeleteTaggedRequests(); + + return ret; +} + +void GraphicsWindow::SplitLinesOrCurves() { + if(!LockedInWorkplane()) { + Error(_("Must be sketching in workplane to split.")); + return; + } + + GroupSelection(); + int n = gs.lineSegments + gs.circlesOrArcs + gs.cubics + gs.periodicCubics; + if(!((n == 2 && gs.points == 0) || (n == 1 && gs.points == 1))) { + Error(_("Select two entities that intersect each other " + "(e.g. two lines/circles/arcs or a line/circle/arc and a point).")); + return; + } + + bool splitAtPoint = (gs.points == 1); + hEntity ha = gs.entity[0], + hb = splitAtPoint ? gs.point[0] : gs.entity[1]; + + Entity *ea = SK.GetEntity(ha), + *eb = SK.GetEntity(hb); + SPointList inters = {}; + SBezierList sbla = {}, + sblb = {}; + Vector pi = Vector::From(0, 0, 0); + + SK.constraint.ClearTags(); + + // First, decide the point where we're going to make the split. + bool foundInters = false; + if(splitAtPoint) { + // One of the entities is a point, and this point must be on the other entity. + // Verify that a corresponding point-coincident constraint exists for the point/entity. + Vector p0, p1; + if(ea->type == Entity::Type::LINE_SEGMENT) { + p0 = ea->EndpointStart(); + p1 = ea->EndpointFinish(); + } + + for(Constraint &c : SK.constraint) { + if(c.ptA.request() == hb.request() && + c.entityA.request() == ha.request()) { + pi = SK.GetEntity(c.ptA)->PointGetNum(); + + if(ea->type == Entity::Type::LINE_SEGMENT && !pi.OnLineSegment(p0, p1)) { + // The point isn't between line endpoints, so there isn't an actual + // intersection. + continue; + } + + c.tag = 1; + foundInters = true; + break; + } + } + } else { + // Compute the possibly-rational Bezier curves for each of these non-point entities... + ea->GenerateBezierCurves(&sbla); + eb->GenerateBezierCurves(&sblb); + // ... and then compute the points where they intersect, based on those curves. + sbla.AllIntersectionsWith(&sblb, &inters); + + // If there's multiple points, then take the one closest to the mouse pointer. + if(!inters.l.IsEmpty()) { + double dmin = VERY_POSITIVE; + SPoint *sp; + for(sp = inters.l.First(); sp; sp = inters.l.NextAfter(sp)) { + double d = ProjectPoint(sp->p).DistanceTo(currentMousePosition); + if(d < dmin) { + dmin = d; + pi = sp->p; + } + } + } + + foundInters = true; + } + + // Then, actually split the entities. + if(foundInters) { + SS.UndoRemember(); + + // Remove any constraints we're going to replace. + SK.constraint.RemoveTagged(); + + hEntity hia = SplitEntity(ha, pi), + hib = {}; + // SplitEntity adds the coincident constraints to join the split halves + // of each original entity; and then we add the constraint to join + // the two entities together at the split point. + if(splitAtPoint) { + // Remove datum point, as it has now been superseded by the split point. + SK.request.ClearTags(); + for(Request &r : SK.request) { + if(r.h == hb.request()) { + if(r.type == Request::Type::DATUM_POINT) { + // Delete datum point. + r.tag = 1; + FixConstraintsForRequestBeingDeleted(r.h); + } else { + // Add constraint if not datum point, but endpoint of line/arc etc. + Constraint::ConstrainCoincident(hia, hb); + } + break; + } + } + SK.request.RemoveTagged(); + } else { + // Split second non-point entity and add constraint. + hib = SplitEntity(hb, pi); + if(hia.v && hib.v) { + Constraint::ConstrainCoincident(hia, hib); + } + } + } else { + Error(_("Can't split; no intersection found.")); + return; + } + + // All done, clean up and regenerate. + inters.Clear(); + sbla.Clear(); + sblb.Clear(); + ClearSelection(); +} diff --git a/src/mouse.cpp b/src/mouse.cpp new file mode 100644 index 0000000..729c8ee --- /dev/null +++ b/src/mouse.cpp @@ -0,0 +1,1586 @@ +//----------------------------------------------------------------------------- +// Anything relating to mouse, keyboard, or 6-DOF mouse input. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +void GraphicsWindow::UpdateDraggedPoint(hEntity hp, double mx, double my) { + Entity *p = SK.GetEntity(hp); + Vector pos = p->PointGetNum(); + UpdateDraggedNum(&pos, mx, my); + p->PointForceTo(pos); +} + +void GraphicsWindow::UpdateDraggedNum(Vector *pos, double mx, double my) { + *pos = pos->Plus(projRight.ScaledBy((mx - orig.mouse.x)/scale)); + *pos = pos->Plus(projUp.ScaledBy((my - orig.mouse.y)/scale)); +} + +void GraphicsWindow::AddPointToDraggedList(hEntity hp) { + Entity *p = SK.GetEntity(hp); + // If an entity and its points are both selected, then its points could + // end up in the list twice. This would be bad, because it would move + // twice as far as the mouse pointer... + List *lhe = &(pending.points); + for(hEntity *hee = lhe->First(); hee; hee = lhe->NextAfter(hee)) { + if(*hee == hp) { + // Exact same point. + return; + } + Entity *pe = SK.GetEntity(*hee); + if(pe->type == p->type && + pe->type != Entity::Type::POINT_IN_2D && + pe->type != Entity::Type::POINT_IN_3D && + pe->group == p->group) + { + // Transform-type point, from the same group. So it handles the + // same unknowns. + return; + } + } + pending.points.Add(&hp); +} + +void GraphicsWindow::StartDraggingByEntity(hEntity he) { + Entity *e = SK.GetEntity(he); + if(e->IsPoint()) { + AddPointToDraggedList(e->h); + } else if(e->type == Entity::Type::LINE_SEGMENT || + e->type == Entity::Type::ARC_OF_CIRCLE || + e->type == Entity::Type::CUBIC || + e->type == Entity::Type::CUBIC_PERIODIC || + e->type == Entity::Type::CIRCLE || + e->type == Entity::Type::TTF_TEXT || + e->type == Entity::Type::IMAGE) + { + int pts; + EntReqTable::GetEntityInfo(e->type, e->extraPoints, + NULL, &pts, NULL, NULL); + for(int i = 0; i < pts; i++) { + AddPointToDraggedList(e->point[i]); + } + } +} + +void GraphicsWindow::StartDraggingBySelection() { + List *ls = &(selection); + for(Selection *s = ls->First(); s; s = ls->NextAfter(s)) { + if(!s->entity.v) continue; + + StartDraggingByEntity(s->entity); + } + // The user might select a point, and then click it again to start + // dragging; but the point just got unselected by that click. So drag + // the hovered item too, and they'll always have it. + if(hover.entity.v) { + hEntity dragEntity = ChooseFromHoverToDrag().entity; + if(dragEntity != Entity::NO_ENTITY) { + StartDraggingByEntity(dragEntity); + } + } +} + +void GraphicsWindow::MouseMoved(double x, double y, bool leftDown, + bool middleDown, bool rightDown, bool shiftDown, bool ctrlDown) +{ + if(window->IsEditorVisible()) return; + if(context.active) return; + + SS.extraLine.draw = false; + + if(!orig.mouseDown) { + // If someone drags the mouse into our window with the left button + // already depressed, then we don't have our starting point; so + // don't try. + leftDown = false; + } + + if(rightDown) { + middleDown = true; + shiftDown = !shiftDown; + } + + if(SS.showToolbar) { + if(ToolbarMouseMoved((int)x, (int)y)) { + hover.Clear(); + return; + } + } + + if(!leftDown && (pending.operation == Pending::DRAGGING_POINTS || + pending.operation == Pending::DRAGGING_MARQUEE)) + { + ClearPending(); + Invalidate(); + } + + Point2d mp = Point2d::From(x, y); + currentMousePosition = mp; + + if(rightDown && orig.mouse.DistanceTo(mp) < 5 && !orig.startedMoving) { + // Avoid accidentally panning (or rotating if shift is down) if the + // user wants a context menu. + return; + } + orig.startedMoving = true; + + // If the middle button is down, then mouse movement is used to pan and + // rotate our view. This wins over everything else. + if(middleDown) { + hover.Clear(); + + double dx = (x - orig.mouse.x) / scale; + double dy = (y - orig.mouse.y) / scale; + + if(!(shiftDown || ctrlDown)) { + double s = 0.3*(PI/180)*scale; // degrees per pixel + if(SS.turntableNav) { // lock the Z to vertical + projRight = orig.projRight.RotatedAbout(Vector::From(0, 0, 1), -s * dx); + projUp = orig.projUp.RotatedAbout( + Vector::From(orig.projRight.x, orig.projRight.y, orig.projRight.y), s * dy); + } else { + projRight = orig.projRight.RotatedAbout(orig.projUp, -s * dx); + projUp = orig.projUp.RotatedAbout(orig.projRight, s * dy); + } + + NormalizeProjectionVectors(); + } else if(ctrlDown) { + double theta = atan2(orig.mouse.y, orig.mouse.x); + theta -= atan2(y, x); + SS.extraLine.draw = true; + SS.extraLine.ptA = UnProjectPoint(Point2d::From(0, 0)); + SS.extraLine.ptB = UnProjectPoint(mp); + + Vector normal = orig.projRight.Cross(orig.projUp); + projRight = orig.projRight.RotatedAbout(normal, theta); + projUp = orig.projUp.RotatedAbout(normal, theta); + + NormalizeProjectionVectors(); + } else { + offset.x = orig.offset.x + dx*projRight.x + dy*projUp.x; + offset.y = orig.offset.y + dx*projRight.y + dy*projUp.y; + offset.z = orig.offset.z + dx*projRight.z + dy*projUp.z; + } + + orig.projRight = projRight; + orig.projUp = projUp; + orig.offset = offset; + orig.mouse.x = x; + orig.mouse.y = y; + + if(SS.TW.shown.screen == TextWindow::Screen::EDIT_VIEW) { + if(havePainted) { + SS.ScheduleShowTW(); + } + } + Invalidate(); + havePainted = false; + return; + } + + if(pending.operation == Pending::NONE) { + double dm = orig.mouse.DistanceTo(mp); + // If we're currently not doing anything, then see if we should + // start dragging something. + if(leftDown && dm > 3) { + Entity *e = NULL; + hEntity dragEntity = ChooseFromHoverToDrag().entity; + if(dragEntity.v) e = SK.GetEntity(dragEntity); + if(e && e->type != Entity::Type::WORKPLANE) { + Entity *e = SK.GetEntity(dragEntity); + if(e->type == Entity::Type::CIRCLE && selection.n <= 1) { + // Drag the radius. + ClearSelection(); + pending.circle = dragEntity; + pending.operation = Pending::DRAGGING_RADIUS; + } else if(e->IsNormal()) { + ClearSelection(); + pending.normal = dragEntity; + pending.operation = Pending::DRAGGING_NORMAL; + } else { + if(!hoverWasSelectedOnMousedown) { + // The user clicked an unselected entity, which + // means they're dragging just the hovered thing, + // not the full selection. So clear all the selection + // except that entity. + ClearSelection(); + MakeSelected(e->h); + } + StartDraggingBySelection(); + if(!hoverWasSelectedOnMousedown) { + // And then clear the selection again, since they + // probably didn't want that selected if they just + // were dragging it. + ClearSelection(); + } + hover.Clear(); + pending.operation = Pending::DRAGGING_POINTS; + } + } else if(hover.constraint.v && + SK.GetConstraint(hover.constraint)->HasLabel()) + { + ClearSelection(); + pending.constraint = hover.constraint; + pending.operation = Pending::DRAGGING_CONSTRAINT; + } + if(pending.operation != Pending::NONE) { + // We just started a drag, so remember for the undo before + // the drag changes anything. + SS.UndoRemember(); + } else { + if(!hover.constraint.v) { + // That's just marquee selection, which should not cause + // an undo remember. + if(dm > 10) { + if(hover.entity.v) { + // Avoid accidentally selecting workplanes when + // starting drags. + MakeUnselected(hover.entity, /*coincidentPointTrick=*/false); + hover.Clear(); + } + pending.operation = Pending::DRAGGING_MARQUEE; + orig.marqueePoint = + UnProjectPoint(orig.mouseOnButtonDown); + } + } + } + } else { + // Otherwise, just hit test and give up; but don't hit test + // if the mouse is down, because then the user could hover + // a point, mouse down (thus selecting it), and drag, in an + // effort to drag the point, but instead hover a different + // entity before we move far enough to start the drag. + if(!leftDown) { + // Hit testing can potentially take a lot of time. + // If we haven't painted since last time we highlighted + // something, don't hit test again, since this just causes + // a lag. + if(!havePainted) return; + HitTestMakeSelection(mp); + } + } + return; + } + + // If the user has started an operation from the menu, but not + // completed it, then just do the selection. + if(pending.operation == Pending::COMMAND) { + HitTestMakeSelection(mp); + return; + } + + // We're currently dragging something; so do that. But if we haven't + // painted since the last time we solved, do nothing, because there's + // no sense solving a frame and not displaying it. + if(!havePainted) { + if(pending.operation == Pending::DRAGGING_POINTS && ctrlDown) { + SS.extraLine.ptA = UnProjectPoint(orig.mouseOnButtonDown); + SS.extraLine.ptB = UnProjectPoint(mp); + SS.extraLine.draw = true; + } + return; + } + + havePainted = false; + switch(pending.operation) { + case Pending::DRAGGING_CONSTRAINT: { + Constraint *c = SK.constraint.FindById(pending.constraint); + UpdateDraggedNum(&(c->disp.offset), x, y); + orig.mouse = mp; + Invalidate(); + return; + } + + case Pending::DRAGGING_NEW_LINE_POINT: + if(!ctrlDown) { + SS.GW.pending.hasSuggestion = + SS.GW.SuggestLineConstraint(SS.GW.pending.request, &SS.GW.pending.suggestion); + } else { + SS.GW.pending.hasSuggestion = false; + } + // fallthrough + case Pending::DRAGGING_NEW_POINT: + UpdateDraggedPoint(pending.point, x, y); + HitTestMakeSelection(mp); + SS.MarkGroupDirtyByEntity(pending.point); + orig.mouse = mp; + Invalidate(); + break; + + case Pending::DRAGGING_POINTS: + if(shiftDown || ctrlDown) { + // Edit the rotation associated with a POINT_N_ROT_TRANS, + // either within (ctrlDown) or out of (shiftDown) the plane + // of the screen. So first get the rotation to apply, in qt. + Quaternion qt; + if(ctrlDown) { + double d = mp.DistanceTo(orig.mouseOnButtonDown); + if(d < 25) { + // Don't start dragging the position about the normal + // until we're a little ways out, to get a reasonable + // reference pos + orig.mouse = mp; + break; + } + double theta = atan2(orig.mouse.y-orig.mouseOnButtonDown.y, + orig.mouse.x-orig.mouseOnButtonDown.x); + theta -= atan2(y-orig.mouseOnButtonDown.y, + x-orig.mouseOnButtonDown.x); + + Vector gn = projRight.Cross(projUp); + qt = Quaternion::From(gn, -theta); + + SS.extraLine.draw = true; + SS.extraLine.ptA = UnProjectPoint(orig.mouseOnButtonDown); + SS.extraLine.ptB = UnProjectPoint(mp); + } else { + double dx = -(x - orig.mouse.x); + double dy = -(y - orig.mouse.y); + double s = 0.3*(PI/180); // degrees per pixel + qt = Quaternion::From(projUp, -s*dx).Times( + Quaternion::From(projRight, s*dy)); + } + orig.mouse = mp; + + // Now apply this rotation to the points being dragged. + List *lhe = &(pending.points); + for(hEntity *he = lhe->First(); he; he = lhe->NextAfter(he)) { + Entity *e = SK.GetEntity(*he); + if(e->type != Entity::Type::POINT_N_ROT_TRANS) { + if(ctrlDown) { + Vector p = e->PointGetNum(); + p = p.Minus(SS.extraLine.ptA); + p = qt.Rotate(p); + p = p.Plus(SS.extraLine.ptA); + e->PointForceTo(p); + SS.MarkGroupDirtyByEntity(e->h); + } + continue; + } + + Quaternion q = e->PointGetQuaternion(); + Vector p = e->PointGetNum(); + q = qt.Times(q); + e->PointForceQuaternionTo(q); + // Let's rotate about the selected point; so fix up the + // translation so that that point didn't move. + e->PointForceTo(p); + SS.MarkGroupDirtyByEntity(e->h); + } + } else { + List *lhe = &(pending.points); + for(hEntity *he = lhe->First(); he; he = lhe->NextAfter(he)) { + UpdateDraggedPoint(*he, x, y); + SS.MarkGroupDirtyByEntity(*he); + } + orig.mouse = mp; + } + break; + + case Pending::DRAGGING_NEW_CUBIC_POINT: { + UpdateDraggedPoint(pending.point, x, y); + HitTestMakeSelection(mp); + + hRequest hr = pending.point.request(); + if(pending.point == hr.entity(4)) { + // The very first segment; dragging final point drags both + // tangent points. + Vector p0 = SK.GetEntity(hr.entity(1))->PointGetNum(), + p3 = SK.GetEntity(hr.entity(4))->PointGetNum(), + p1 = p0.ScaledBy(2.0/3).Plus(p3.ScaledBy(1.0/3)), + p2 = p0.ScaledBy(1.0/3).Plus(p3.ScaledBy(2.0/3)); + SK.GetEntity(hr.entity(1+1))->PointForceTo(p1); + SK.GetEntity(hr.entity(1+2))->PointForceTo(p2); + } else { + // A subsequent segment; dragging point drags only final + // tangent point. + int i = SK.GetEntity(hr.entity(0))->extraPoints; + Vector pn = SK.GetEntity(hr.entity(4+i))->PointGetNum(), + pnm2 = SK.GetEntity(hr.entity(2+i))->PointGetNum(), + pnm1 = (pn.Plus(pnm2)).ScaledBy(0.5); + SK.GetEntity(hr.entity(3+i))->PointForceTo(pnm1); + } + + orig.mouse = mp; + SS.MarkGroupDirtyByEntity(pending.point); + break; + } + case Pending::DRAGGING_NEW_ARC_POINT: { + UpdateDraggedPoint(pending.point, x, y); + HitTestMakeSelection(mp); + + hRequest hr = pending.point.request(); + Vector ona = SK.GetEntity(hr.entity(2))->PointGetNum(); + Vector onb = SK.GetEntity(hr.entity(3))->PointGetNum(); + Vector center = (ona.Plus(onb)).ScaledBy(0.5); + + SK.GetEntity(hr.entity(1))->PointForceTo(center); + + orig.mouse = mp; + SS.MarkGroupDirtyByEntity(pending.point); + break; + } + case Pending::DRAGGING_NEW_RADIUS: + case Pending::DRAGGING_RADIUS: { + Entity *circle = SK.GetEntity(pending.circle); + Vector center = SK.GetEntity(circle->point[0])->PointGetNum(); + Point2d c2 = ProjectPoint(center); + double r = c2.DistanceTo(mp)/scale; + SK.GetEntity(circle->distance)->DistanceForceTo(r); + + SS.MarkGroupDirtyByEntity(pending.circle); + break; + } + + case Pending::DRAGGING_NORMAL: { + Entity *normal = SK.GetEntity(pending.normal); + Vector p = SK.GetEntity(normal->point[0])->PointGetNum(); + Point2d p2 = ProjectPoint(p); + + Quaternion q = normal->NormalGetNum(); + Vector u = q.RotationU(), v = q.RotationV(); + + if(ctrlDown) { + double theta = atan2(orig.mouse.y-p2.y, orig.mouse.x-p2.x); + theta -= atan2(y-p2.y, x-p2.x); + + Vector normal = projRight.Cross(projUp); + u = u.RotatedAbout(normal, -theta); + v = v.RotatedAbout(normal, -theta); + } else { + double dx = -(x - orig.mouse.x); + double dy = -(y - orig.mouse.y); + double s = 0.3*(PI/180); // degrees per pixel + u = u.RotatedAbout(projUp, -s*dx); + u = u.RotatedAbout(projRight, s*dy); + v = v.RotatedAbout(projUp, -s*dx); + v = v.RotatedAbout(projRight, s*dy); + } + orig.mouse = mp; + normal->NormalForceTo(Quaternion::From(u, v)); + + SS.MarkGroupDirtyByEntity(pending.normal); + break; + } + + case Pending::DRAGGING_MARQUEE: + orig.mouse = mp; + Invalidate(); + return; + + case Pending::NONE: + case Pending::COMMAND: + ssassert(false, "Unexpected pending operation"); + } +} + +void GraphicsWindow::ClearPending(bool scheduleShowTW) { + pending.points.Clear(); + pending.requests.Clear(); + pending = {}; + if(scheduleShowTW) { + SS.ScheduleShowTW(); + } +} + +bool GraphicsWindow::IsFromPending(hRequest r) { + for(auto &req : pending.requests) { + if(req == r) return true; + } + return false; +} + +void GraphicsWindow::AddToPending(hRequest r) { + pending.requests.Add(&r); +} + +void GraphicsWindow::ReplacePending(hRequest before, hRequest after) { + for(auto &req : pending.requests) { + if(req == before) { + req = after; + } + } +} + +void GraphicsWindow::MouseMiddleOrRightDown(double x, double y) { + if(window->IsEditorVisible()) return; + + orig.offset = offset; + orig.projUp = projUp; + orig.projRight = projRight; + orig.mouse.x = x; + orig.mouse.y = y; + orig.startedMoving = false; +} + +void GraphicsWindow::MouseRightUp(double x, double y) { + SS.extraLine.draw = false; + Invalidate(); + + // Don't show a context menu if the user is right-clicking the toolbar, + // or if they are finishing a pan. + if(ToolbarMouseMoved((int)x, (int)y)) return; + if(orig.startedMoving) return; + + if(context.active) return; + + if(pending.operation == Pending::DRAGGING_NEW_LINE_POINT && pending.hasSuggestion) { + Constraint::TryConstrain(SS.GW.pending.suggestion, + Entity::NO_ENTITY, Entity::NO_ENTITY, pending.request.entity(0)); + } + + if(pending.operation == Pending::DRAGGING_NEW_LINE_POINT || + pending.operation == Pending::DRAGGING_NEW_CUBIC_POINT) + { + // Special case; use a right click to stop drawing lines, since + // a left click would draw another one. This is quicker and more + // intuitive than hitting escape. Likewise for new cubic segments. + ClearPending(); + return; + } + + // The current mouse location + Vector v = offset.ScaledBy(-1); + v = v.Plus(projRight.ScaledBy(x/scale)); + v = v.Plus(projUp.ScaledBy(y/scale)); + + Platform::MenuRef menu = Platform::CreateMenu(); + context.active = true; + + if(!hover.IsEmpty()) { + MakeSelected(&hover); + SS.ScheduleShowTW(); + } + GroupSelection(); + + bool itemsSelected = (gs.n > 0 || gs.constraints > 0); + if(itemsSelected) { + if(gs.stylables > 0) { + Platform::MenuRef styleMenu = menu->AddSubMenu(_("Assign to Style")); + + bool empty = true; + for(const Style &s : SK.style) { + if(s.h.v < Style::FIRST_CUSTOM) continue; + + uint32_t v = s.h.v; + + styleMenu->AddItem(s.DescriptionString(), [v]() { + Style::AssignSelectionToStyle(v); + }); + empty = false; + } + + if(!empty) styleMenu->AddSeparator(); + + styleMenu->AddItem(_("No Style"), []() { + Style::AssignSelectionToStyle(0); + }); + styleMenu->AddItem(_("Newly Created Custom Style..."), [this]() { + uint32_t vs = Style::CreateCustomStyle(); + Style::AssignSelectionToStyle(vs); + ForceTextWindowShown(); + }); + } + if(gs.n + gs.constraints == 1) { + menu->AddItem(_("Group Info"), [this]() { + hGroup hg; + if(gs.entities == 1) { + hg = SK.GetEntity(gs.entity[0])->group; + } else if(gs.points == 1) { + hg = SK.GetEntity(gs.point[0])->group; + } else if(gs.constraints == 1) { + hg = SK.GetConstraint(gs.constraint[0])->group; + } else { + return; + } + ClearSelection(); + + SS.TW.GoToScreen(TextWindow::Screen::GROUP_INFO); + SS.TW.shown.group = hg; + SS.ScheduleShowTW(); + ForceTextWindowShown(); + }); + } + if(gs.n + gs.constraints == 1 && gs.stylables == 1) { + menu->AddItem(_("Style Info"), [this]() { + hStyle hs; + if(gs.entities == 1) { + hs = Style::ForEntity(gs.entity[0]); + } else if(gs.points == 1) { + hs = Style::ForEntity(gs.point[0]); + } else if(gs.constraints == 1) { + hs = SK.GetConstraint(gs.constraint[0])->GetStyle(); + } else { + return; + } + ClearSelection(); + + SS.TW.GoToScreen(TextWindow::Screen::STYLE_INFO); + SS.TW.shown.style = hs; + SS.ScheduleShowTW(); + ForceTextWindowShown(); + }); + } + if(gs.withEndpoints > 0) { + menu->AddItem(_("Select Edge Chain"), + []() { MenuEdit(Command::SELECT_CHAIN); }); + } + if(gs.constraints == 1 && gs.n == 0) { + Constraint *c = SK.GetConstraint(gs.constraint[0]); + if(c->HasLabel() && c->type != Constraint::Type::COMMENT) { + menu->AddItem(_("Toggle Reference Dimension"), + []() { Constraint::MenuConstrain(Command::REFERENCE); }); + } + if(c->type == Constraint::Type::ANGLE || + c->type == Constraint::Type::EQUAL_ANGLE) + { + menu->AddItem(_("Other Supplementary Angle"), + []() { Constraint::MenuConstrain(Command::OTHER_ANGLE); }); + } + } + if(gs.constraintLabels > 0 || gs.points > 0) { + menu->AddItem(_("Snap to Grid"), + []() { MenuEdit(Command::SNAP_TO_GRID); }); + } + + if(gs.points == 1 && gs.point[0].isFromRequest()) { + Request *r = SK.GetRequest(gs.point[0].request()); + int index = r->IndexOfPoint(gs.point[0]); + if((r->type == Request::Type::CUBIC && (index > 1 && index < r->extraPoints + 2)) || + r->type == Request::Type::CUBIC_PERIODIC) { + menu->AddItem(_("Remove Spline Point"), [this, r]() { + int index = r->IndexOfPoint(gs.point[0]); + ssassert(r->extraPoints != 0, + "Expected a bezier with interior control points"); + + SS.UndoRemember(); + Entity *e = SK.GetEntity(r->h.entity(0)); + + // First, fix point-coincident constraints involving this point. + // Then, remove all other constraints, since they would otherwise + // jump to an adjacent one and mess up the bezier after generation. + FixConstraintsForPointBeingDeleted(e->point[index]); + RemoveConstraintsForPointBeingDeleted(e->point[index]); + + for(int i = index; i < MAX_POINTS_IN_ENTITY - 1; i++) { + if(e->point[i + 1].v == 0) break; + Entity *p0 = SK.GetEntity(e->point[i]); + Entity *p1 = SK.GetEntity(e->point[i + 1]); + ReplacePointInConstraints(p1->h, p0->h); + p0->PointForceTo(p1->PointGetNum()); + } + r->extraPoints--; + SS.MarkGroupDirtyByEntity(gs.point[0]); + ClearSelection(); + }); + } + } + if(gs.entities == 1 && gs.entity[0].isFromRequest()) { + Request *r = SK.GetRequest(gs.entity[0].request()); + if(r->type == Request::Type::CUBIC || r->type == Request::Type::CUBIC_PERIODIC) { + Entity *e = SK.GetEntity(gs.entity[0]); + int addAfterPoint = e->GetPositionOfPoint(GetCamera(), Point2d::From(x, y)); + ssassert(addAfterPoint != -1, "Expected a nearest bezier point to be located"); + // Skip derivative point. + if(r->type == Request::Type::CUBIC) addAfterPoint++; + menu->AddItem(_("Add Spline Point"), [this, r, addAfterPoint, v]() { + int pointCount = r->extraPoints + + ((r->type == Request::Type::CUBIC_PERIODIC) ? 3 : 4); + if(pointCount >= MAX_POINTS_IN_ENTITY) { + Error(_("Cannot add spline point: maximum number of points reached.")); + return; + } + + SS.UndoRemember(); + r->extraPoints++; + SS.MarkGroupDirtyByEntity(gs.entity[0]); + SS.GenerateAll(SolveSpaceUI::Generate::REGEN); + + Entity *e = SK.GetEntity(r->h.entity(0)); + for(int i = MAX_POINTS_IN_ENTITY; i > addAfterPoint + 1; i--) { + Entity *p0 = SK.entity.FindByIdNoOops(e->point[i]); + if(p0 == NULL) continue; + Entity *p1 = SK.GetEntity(e->point[i - 1]); + ReplacePointInConstraints(p1->h, p0->h); + p0->PointForceTo(p1->PointGetNum()); + } + Entity *p = SK.GetEntity(e->point[addAfterPoint + 1]); + p->PointForceTo(v); + SS.MarkGroupDirtyByEntity(gs.entity[0]); + ClearSelection(); + }); + } + } + if(gs.entities == gs.n) { + menu->AddItem(_("Toggle Construction"), + []() { MenuRequest(Command::CONSTRUCTION); }); + } + + if(gs.points == 1) { + Entity *p = SK.GetEntity(gs.point[0]); + Constraint *c; + IdList *lc = &(SK.constraint); + for(c = lc->First(); c; c = lc->NextAfter(c)) { + if(c->type != Constraint::Type::POINTS_COINCIDENT) continue; + if(c->ptA == p->h || c->ptB == p->h) { + break; + } + } + if(c) { + menu->AddItem(_("Delete Point-Coincident Constraint"), [this, p]() { + if(!p->IsPoint()) return; + + SS.UndoRemember(); + SK.constraint.ClearTags(); + Constraint *c; + for(c = SK.constraint.First(); c; c = SK.constraint.NextAfter(c)) { + if(c->type != Constraint::Type::POINTS_COINCIDENT) continue; + if(c->ptA == p->h || c->ptB == p->h) { + c->tag = 1; + } + } + SK.constraint.RemoveTagged(); + ClearSelection(); + }); + } + } + menu->AddSeparator(); + if(LockedInWorkplane()) { + menu->AddItem(_("Cut"), + []() { MenuClipboard(Command::CUT); }); + menu->AddItem(_("Copy"), + []() { MenuClipboard(Command::COPY); }); + } + } else { + menu->AddItem(_("Select All"), + []() { MenuEdit(Command::SELECT_ALL); }); + } + + if((!SS.clipboard.r.IsEmpty() || !SS.clipboard.c.IsEmpty()) && LockedInWorkplane()) { + menu->AddItem(_("Paste"), + []() { MenuClipboard(Command::PASTE); }); + menu->AddItem(_("Paste Transformed..."), + []() { MenuClipboard(Command::PASTE_TRANSFORM); }); + } + + if(itemsSelected) { + menu->AddItem(_("Delete"), + []() { MenuClipboard(Command::DELETE); }); + menu->AddSeparator(); + menu->AddItem(_("Unselect All"), + []() { MenuEdit(Command::UNSELECT_ALL); }); + } + // If only one item is selected, then it must be the one that we just + // selected from the hovered item; in which case unselect all and hovered + // are equivalent. + if(!hover.IsEmpty() && selection.n > 1) { + menu->AddItem(_("Unselect Hovered"), [this] { + if(!hover.IsEmpty()) { + MakeUnselected(&hover, /*coincidentPointTrick=*/true); + } + }); + } + + if(itemsSelected) { + menu->AddSeparator(); + menu->AddItem(_("Zoom to Fit"), + []() { MenuView(Command::ZOOM_TO_FIT); }); + } + + menu->PopUp(); + + context.active = false; + SS.ScheduleShowTW(); +} + +hRequest GraphicsWindow::AddRequest(Request::Type type) { + return AddRequest(type, /*rememberForUndo=*/true); +} +hRequest GraphicsWindow::AddRequest(Request::Type type, bool rememberForUndo) { + if(rememberForUndo) SS.UndoRemember(); + + Request r = {}; + r.group = activeGroup; + Group *g = SK.GetGroup(activeGroup); + if(g->type == Group::Type::DRAWING_3D || g->type == Group::Type::DRAWING_WORKPLANE) { + r.construction = false; + } else { + r.construction = true; + } + r.workplane = ActiveWorkplane(); + r.type = type; + SK.request.AddAndAssignId(&r); + + // We must regenerate the parameters, so that the code that tries to + // place this request's entities where the mouse is can do so. But + // we mustn't try to solve until reasonable values have been supplied + // for these new parameters, or else we'll get a numerical blowup. + r.Generate(&SK.entity, &SK.param); + SS.MarkGroupDirty(r.group); + return r.h; +} + +Vector GraphicsWindow::SnapToEntityByScreenPoint(Point2d pp, hEntity he) { + Entity *e = SK.GetEntity(he); + if(e->IsPoint()) return e->PointGetNum(); + SEdgeList *edges = e->GetOrGenerateEdges(); + + double minD = -1.0f; + double k; + const SEdge *edge = NULL; + for(const auto &e : edges->l) { + Point2d p0 = ProjectPoint(e.a); + Point2d p1 = ProjectPoint(e.b); + Point2d dir = p1.Minus(p0); + double d = pp.DistanceToLine(p0, dir, /*asSegment=*/true); + if(minD > 0.0 && d > minD) continue; + minD = d; + k = pp.Minus(p0).Dot(dir) / dir.Dot(dir); + edge = &e; + } + if(edge == NULL) return UnProjectPoint(pp); + return edge->a.Plus(edge->b.Minus(edge->a).ScaledBy(k)); +} + +bool GraphicsWindow::ConstrainPointByHovered(hEntity pt, const Point2d *projected) { + if(!hover.entity.v) return false; + + Entity *point = SK.GetEntity(pt); + Entity *e = SK.GetEntity(hover.entity); + if(e->IsPoint()) { + point->PointForceTo(e->PointGetNum()); + Constraint::ConstrainCoincident(e->h, pt); + return true; + } + if(e->IsCircle()) { + if(projected != NULL) { + Vector snapPos = SnapToEntityByScreenPoint(*projected, e->h); + point->PointForceTo(snapPos); + } + Constraint::Constrain(Constraint::Type::PT_ON_CIRCLE, + pt, Entity::NO_ENTITY, e->h); + return true; + } + if(e->type == Entity::Type::LINE_SEGMENT) { + if(projected != NULL) { + Vector snapPos = SnapToEntityByScreenPoint(*projected, e->h); + point->PointForceTo(snapPos); + } + Constraint::Constrain(Constraint::Type::PT_ON_LINE, + pt, Entity::NO_ENTITY, e->h); + return true; + } + + return false; +} + +bool GraphicsWindow::MouseEvent(Platform::MouseEvent event) { + using Platform::MouseEvent; + double width, height; + window->GetContentSize(&width, &height); + + event.x = event.x - width / 2; + event.y = height / 2 - event.y; + + switch(event.type) { + case MouseEvent::Type::MOTION: + this->MouseMoved(event.x, event.y, + event.button == MouseEvent::Button::LEFT, + event.button == MouseEvent::Button::MIDDLE, + event.button == MouseEvent::Button::RIGHT, + event.shiftDown, + event.controlDown); + break; + + case MouseEvent::Type::PRESS: + if(event.button == MouseEvent::Button::LEFT) { + this->MouseLeftDown(event.x, event.y, event.shiftDown, event.controlDown); + } else if(event.button == MouseEvent::Button::MIDDLE || + event.button == MouseEvent::Button::RIGHT) { + this->MouseMiddleOrRightDown(event.x, event.y); + } + break; + + case MouseEvent::Type::DBL_PRESS: + if(event.button == MouseEvent::Button::LEFT) { + this->MouseLeftDoubleClick(event.x, event.y); + } + break; + + case MouseEvent::Type::RELEASE: + if(event.button == MouseEvent::Button::LEFT) { + this->MouseLeftUp(event.x, event.y, event.shiftDown, event.controlDown); + } else if(event.button == MouseEvent::Button::RIGHT) { + this->MouseRightUp(event.x, event.y); + } + break; + + case MouseEvent::Type::SCROLL_VERT: + this->MouseScroll(event.x, event.y, event.shiftDown ? event.scrollDelta / 10 : event.scrollDelta); + break; + + case MouseEvent::Type::LEAVE: + this->MouseLeave(); + break; + } + + return true; +} + +void GraphicsWindow::MouseLeftDown(double mx, double my, bool shiftDown, bool ctrlDown) { + orig.mouseDown = true; + + if(window->IsEditorVisible()) { + orig.mouse = Point2d::From(mx, my); + orig.mouseOnButtonDown = orig.mouse; + window->HideEditor(); + return; + } + SS.TW.HideEditControl(); + + if(SS.showToolbar) { + if(ToolbarMouseDown((int)mx, (int)my)) return; + } + + // This will be clobbered by MouseMoved below. + bool hasConstraintSuggestion = pending.hasSuggestion; + Constraint::Type constraintSuggestion = pending.suggestion; + + // Make sure the hover is up to date. + MouseMoved(mx, my, /*leftDown=*/false, /*middleDown=*/false, /*rightDown=*/false, + /*shiftDown=*/false, /*ctrlDown=*/false); + orig.mouse.x = mx; + orig.mouse.y = my; + orig.mouseOnButtonDown = orig.mouse; + Point2d mouse = Point2d::From(mx, my); + + // The current mouse location + Vector v = offset.ScaledBy(-1); + v = v.Plus(projRight.ScaledBy(mx/scale)); + v = v.Plus(projUp.ScaledBy(my/scale)); + + hRequest hr = {}; + hConstraint hc = {}; + switch(pending.operation) { + case Pending::COMMAND: + switch(pending.command) { + case Command::DATUM_POINT: + hr = AddRequest(Request::Type::DATUM_POINT); + SK.GetEntity(hr.entity(0))->PointForceTo(v); + ConstrainPointByHovered(hr.entity(0), &mouse); + + ClearSuper(); + break; + + case Command::LINE_SEGMENT: + case Command::CONSTR_SEGMENT: + hr = AddRequest(Request::Type::LINE_SEGMENT); + SK.GetRequest(hr)->construction = (pending.command == Command::CONSTR_SEGMENT); + SK.GetEntity(hr.entity(1))->PointForceTo(v); + ConstrainPointByHovered(hr.entity(1), &mouse); + + ClearSuper(); + AddToPending(hr); + + pending.operation = Pending::DRAGGING_NEW_LINE_POINT; + pending.request = hr; + pending.point = hr.entity(2); + pending.description = _("click next point of line, or press Esc"); + SK.GetEntity(pending.point)->PointForceTo(v); + break; + + case Command::RECTANGLE: { + if(!SS.GW.LockedInWorkplane()) { + Error(_("Can't draw rectangle in 3d; first, activate a workplane " + "with Sketch -> In Workplane.")); + ClearSuper(); + break; + } + hRequest lns[4]; + int i; + SS.UndoRemember(); + for(i = 0; i < 4; i++) { + lns[i] = AddRequest(Request::Type::LINE_SEGMENT, /*rememberForUndo=*/false); + AddToPending(lns[i]); + } + for(i = 0; i < 4; i++) { + Constraint::ConstrainCoincident( + lns[i].entity(1), lns[(i+1)%4].entity(2)); + SK.GetEntity(lns[i].entity(1))->PointForceTo(v); + SK.GetEntity(lns[i].entity(2))->PointForceTo(v); + } + for(i = 0; i < 4; i++) { + Constraint::Constrain( + (i % 2) ? Constraint::Type::HORIZONTAL : Constraint::Type::VERTICAL, + Entity::NO_ENTITY, Entity::NO_ENTITY, + lns[i].entity(0)); + } + if(ConstrainPointByHovered(lns[2].entity(1), &mouse)) { + Vector pos = SK.GetEntity(lns[2].entity(1))->PointGetNum(); + for(i = 0; i < 4; i++) { + SK.GetEntity(lns[i].entity(1))->PointForceTo(pos); + SK.GetEntity(lns[i].entity(2))->PointForceTo(pos); + } + } + + pending.operation = Pending::DRAGGING_NEW_POINT; + pending.point = lns[1].entity(2); + pending.description = _("click to place other corner of rectangle"); + hr = lns[0]; + break; + } + case Command::CIRCLE: + hr = AddRequest(Request::Type::CIRCLE); + // Centered where we clicked + SK.GetEntity(hr.entity(1))->PointForceTo(v); + // Normal to the screen + SK.GetEntity(hr.entity(32))->NormalForceTo( + Quaternion::From(SS.GW.projRight, SS.GW.projUp)); + // Initial radius zero + SK.GetEntity(hr.entity(64))->DistanceForceTo(0); + + ConstrainPointByHovered(hr.entity(1), &mouse); + + ClearSuper(); + + pending.operation = Pending::DRAGGING_NEW_RADIUS; + pending.circle = hr.entity(0); + pending.description = _("click to set radius"); + break; + + case Command::ARC: { + if(!SS.GW.LockedInWorkplane()) { + Error(_("Can't draw arc in 3d; first, activate a workplane " + "with Sketch -> In Workplane.")); + ClearPending(); + break; + } + hr = AddRequest(Request::Type::ARC_OF_CIRCLE); + // This fudge factor stops us from immediately failing to solve + // because of the arc's implicit (equal radius) tangent. + Vector adj = SS.GW.projRight.WithMagnitude(2/SS.GW.scale); + SK.GetEntity(hr.entity(1))->PointForceTo(v.Minus(adj)); + SK.GetEntity(hr.entity(2))->PointForceTo(v); + SK.GetEntity(hr.entity(3))->PointForceTo(v); + ConstrainPointByHovered(hr.entity(2), &mouse); + + ClearSuper(); + AddToPending(hr); + + pending.operation = Pending::DRAGGING_NEW_ARC_POINT; + pending.point = hr.entity(3); + pending.description = _("click to place point"); + break; + } + case Command::CUBIC: + hr = AddRequest(Request::Type::CUBIC); + SK.GetEntity(hr.entity(1))->PointForceTo(v); + SK.GetEntity(hr.entity(2))->PointForceTo(v); + SK.GetEntity(hr.entity(3))->PointForceTo(v); + SK.GetEntity(hr.entity(4))->PointForceTo(v); + ConstrainPointByHovered(hr.entity(1), &mouse); + + ClearSuper(); + AddToPending(hr); + + pending.operation = Pending::DRAGGING_NEW_CUBIC_POINT; + pending.point = hr.entity(4); + pending.description = _("click next point of cubic, or press Esc"); + break; + + case Command::WORKPLANE: + if(LockedInWorkplane()) { + Error(_("Sketching in a workplane already; sketch in 3d before " + "creating new workplane.")); + ClearSuper(); + break; + } + hr = AddRequest(Request::Type::WORKPLANE); + SK.GetEntity(hr.entity(1))->PointForceTo(v); + SK.GetEntity(hr.entity(32))->NormalForceTo( + Quaternion::From(SS.GW.projRight, SS.GW.projUp)); + ConstrainPointByHovered(hr.entity(1), &mouse); + + ClearSuper(); + break; + + case Command::TTF_TEXT: { + if(!SS.GW.LockedInWorkplane()) { + Error(_("Can't draw text in 3d; first, activate a workplane " + "with Sketch -> In Workplane.")); + ClearSuper(); + break; + } + hr = AddRequest(Request::Type::TTF_TEXT); + AddToPending(hr); + Request *r = SK.GetRequest(hr); + r->str = "Abc"; + r->font = Platform::embeddedFont; + + for(int i = 1; i <= 4; i++) { + SK.GetEntity(hr.entity(i))->PointForceTo(v); + } + + pending.operation = Pending::DRAGGING_NEW_POINT; + pending.point = hr.entity(3); + pending.description = _("click to place bottom right of text"); + break; + } + + case Command::IMAGE: { + if(!SS.GW.LockedInWorkplane()) { + Error(_("Can't draw image in 3d; first, activate a workplane " + "with Sketch -> In Workplane.")); + ClearSuper(); + break; + } + hr = AddRequest(Request::Type::IMAGE); + AddToPending(hr); + Request *r = SK.GetRequest(hr); + r->file = pending.filename; + + for(int i = 1; i <= 4; i++) { + SK.GetEntity(hr.entity(i))->PointForceTo(v); + } + + pending.operation = Pending::DRAGGING_NEW_POINT; + pending.point = hr.entity(3); + pending.description = "click to place bottom right of image"; + break; + } + + case Command::COMMENT: { + ClearSuper(); + Constraint c = {}; + c.group = SS.GW.activeGroup; + c.workplane = SS.GW.ActiveWorkplane(); + c.type = Constraint::Type::COMMENT; + c.disp.offset = v; + c.comment = _("NEW COMMENT -- DOUBLE-CLICK TO EDIT"); + hc = Constraint::AddConstraint(&c); + break; + } + default: ssassert(false, "Unexpected pending menu id"); + } + break; + + case Pending::DRAGGING_RADIUS: + ClearPending(); + break; + + case Pending::DRAGGING_NEW_POINT: + case Pending::DRAGGING_NEW_ARC_POINT: + ConstrainPointByHovered(pending.point, &mouse); + ClearPending(); + break; + + case Pending::DRAGGING_NEW_CUBIC_POINT: { + hRequest hr = pending.point.request(); + Request *r = SK.GetRequest(hr); + + if(hover.entity == hr.entity(1) && r->extraPoints >= 2) { + // They want the endpoints coincident, which means a periodic + // spline instead. + r->type = Request::Type::CUBIC_PERIODIC; + // Remove the off-curve control points, which are no longer + // needed here; so move [2,ep+1] down, skipping first pt. + int i; + for(i = 2; i <= r->extraPoints+1; i++) { + SK.GetEntity(hr.entity((i-1)+1))->PointForceTo( + SK.GetEntity(hr.entity(i+1))->PointGetNum()); + } + // and move ep+3 down by two, skipping both + SK.GetEntity(hr.entity((r->extraPoints+1)+1))->PointForceTo( + SK.GetEntity(hr.entity((r->extraPoints+3)+1))->PointGetNum()); + r->extraPoints -= 2; + // And we're done. + SS.MarkGroupDirty(r->group); + ClearPending(); + break; + } + + if(ConstrainPointByHovered(pending.point, &mouse)) { + ClearPending(); + break; + } + + Entity e; + if(r->extraPoints >= (int)arraylen(e.point) - 4) { + ClearPending(); + break; + } + + (SK.GetRequest(hr)->extraPoints)++; + SS.GenerateAll(SolveSpaceUI::Generate::REGEN); + + int ep = r->extraPoints; + Vector last = SK.GetEntity(hr.entity(3+ep))->PointGetNum(); + + SK.GetEntity(hr.entity(2+ep))->PointForceTo(last); + SK.GetEntity(hr.entity(3+ep))->PointForceTo(v); + SK.GetEntity(hr.entity(4+ep))->PointForceTo(v); + pending.point = hr.entity(4+ep); + break; + } + + case Pending::DRAGGING_NEW_LINE_POINT: { + if(hover.entity.v) { + Entity *e = SK.GetEntity(hover.entity); + if(e->IsPoint()) { + hRequest hrl = pending.point.request(); + Entity *sp = SK.GetEntity(hrl.entity(1)); + if(( e->PointGetNum()).Equals( + (sp->PointGetNum()))) + { + // If we constrained by the hovered point, then we + // would create a zero-length line segment. That's + // not good, so just stop drawing. + ClearPending(); + break; + } + } + } + + bool doneDragging = ConstrainPointByHovered(pending.point, &mouse); + + // Constrain the line segment horizontal or vertical if close enough + if(hasConstraintSuggestion) { + Constraint::TryConstrain(constraintSuggestion, + Entity::NO_ENTITY, Entity::NO_ENTITY, pending.request.entity(0)); + } + + if(doneDragging) { + ClearPending(); + break; + } + + // Create a new line segment, so that we continue drawing. + hRequest hr = AddRequest(Request::Type::LINE_SEGMENT); + ReplacePending(pending.request, hr); + SK.GetRequest(hr)->construction = SK.GetRequest(pending.request)->construction; + // Displace the second point of the new line segment slightly, + // to avoid creating zero-length edge warnings. + SK.GetEntity(hr.entity(2))->PointForceTo( + v.Plus(projRight.ScaledBy(0.5/scale))); + + // Constrain the line segments to share an endpoint + Constraint::ConstrainCoincident(pending.point, hr.entity(1)); + Vector pendingPos = SK.GetEntity(pending.point)->PointGetNum(); + SK.GetEntity(hr.entity(1))->PointForceTo(pendingPos); + + // And drag an endpoint of the new line segment + pending.operation = Pending::DRAGGING_NEW_LINE_POINT; + pending.request = hr; + pending.point = hr.entity(2); + pending.description = _("click next point of line, or press Esc"); + + break; + } + + case Pending::NONE: + default: + ClearPending(); + if(!hover.IsEmpty()) { + if(!ctrlDown) { + hoverWasSelectedOnMousedown = IsSelected(&hover); + MakeSelected(&hover); + } else { + MakeUnselected(&hover, /*coincidentPointTrick=*/true); + } + } + break; + } + + // Activate group with newly created request/constraint + Group *g = NULL; + if(hr.v != 0) { + g = SK.GetGroup(SK.GetRequest(hr)->group); + } + if(hc.v != 0) { + g = SK.GetGroup(SK.GetConstraint(hc)->group); + } + if(g != NULL) { + g->visible = true; + } + + SS.ScheduleShowTW(); + Invalidate(); +} + +void GraphicsWindow::MouseLeftUp(double mx, double my, bool shiftDown, bool ctrlDown) { + orig.mouseDown = false; + hoverWasSelectedOnMousedown = false; + + switch(pending.operation) { + case Pending::DRAGGING_POINTS: + SS.extraLine.draw = false; + // fall through + case Pending::DRAGGING_CONSTRAINT: + case Pending::DRAGGING_NORMAL: + case Pending::DRAGGING_RADIUS: + ClearPending(); + Invalidate(); + break; + + case Pending::DRAGGING_MARQUEE: + SelectByMarquee(); + ClearPending(); + Invalidate(); + break; + + case Pending::NONE: + if(hover.IsEmpty() && !ctrlDown) { + ClearSelection(); + } + break; + + default: + break; // do nothing + } +} + +void GraphicsWindow::EditConstraint(hConstraint constraint) { + constraintBeingEdited = constraint; + ClearSuper(); + + Constraint *c = SK.GetConstraint(constraintBeingEdited); + if(!c->HasLabel()) { + // Not meaningful to edit a constraint without a dimension + return; + } + if(c->reference) { + // Not meaningful to edit a reference dimension + return; + } + + Vector p3 = c->GetLabelPos(GetCamera()); + Point2d p2 = ProjectPoint(p3); + + std::string editValue; + std::string editPlaceholder; + switch(c->type) { + case Constraint::Type::COMMENT: + editValue = c->comment; + editPlaceholder = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; + break; + + default: { + double value = fabs(c->valA); + + // If displayed as radius, also edit as radius. + if(c->type == Constraint::Type::DIAMETER && c->other) + value /= 2; + + // Try showing value with default number of digits after decimal first. + if(c->type == Constraint::Type::LENGTH_RATIO) { + editValue = ssprintf("%.3f", value); + } else if(c->type == Constraint::Type::ANGLE) { + editValue = SS.DegreeToString(value); + } else { + editValue = SS.MmToString(value); + value /= SS.MmPerUnit(); + } + // If that's not enough to represent it exactly, show the value with as many + // digits after decimal as required, up to 10. + int digits = 0; + while(fabs(std::stod(editValue) - value) > 1e-10) { + editValue = ssprintf("%.*f", digits, value); + digits++; + } + editPlaceholder = "10.000000"; + break; + } + } + + double width, height; + window->GetContentSize(&width, &height); + hStyle hs = c->disp.style; + if(hs.v == 0) hs.v = Style::CONSTRAINT; + double capHeight = Style::TextHeight(hs); + double fontHeight = VectorFont::Builtin()->GetHeight(capHeight); + double editMinWidth = VectorFont::Builtin()->GetWidth(capHeight, editPlaceholder); + window->ShowEditor(p2.x + width / 2, height / 2 - p2.y, + fontHeight, editMinWidth, + /*isMonospace=*/false, editValue); +} + +void GraphicsWindow::MouseLeftDoubleClick(double mx, double my) { + if(window->IsEditorVisible()) return; + SS.TW.HideEditControl(); + + if(hover.constraint.v) { + EditConstraint(hover.constraint); + } +} + +void GraphicsWindow::EditControlDone(const std::string &s) { + window->HideEditor(); + window->Invalidate(); + + Constraint *c = SK.GetConstraint(constraintBeingEdited); + + if(c->type == Constraint::Type::COMMENT) { + SS.UndoRemember(); + c->comment = s; + return; + } + + if(Expr *e = Expr::From(s, true)) { + SS.UndoRemember(); + + switch(c->type) { + case Constraint::Type::PROJ_PT_DISTANCE: + case Constraint::Type::PT_LINE_DISTANCE: + case Constraint::Type::PT_FACE_DISTANCE: + case Constraint::Type::PT_PLANE_DISTANCE: + case Constraint::Type::LENGTH_DIFFERENCE: { + // The sign is not displayed to the user, but this is a signed + // distance internally. To flip the sign, the user enters a + // negative distance. + bool wasNeg = (c->valA < 0); + if(wasNeg) { + c->valA = -SS.ExprToMm(e); + } else { + c->valA = SS.ExprToMm(e); + } + break; + } + case Constraint::Type::ANGLE: + case Constraint::Type::LENGTH_RATIO: + // These don't get the units conversion for distance, and + // they're always positive + c->valA = fabs(e->Eval()); + break; + + case Constraint::Type::DIAMETER: + c->valA = fabs(SS.ExprToMm(e)); + + // If displayed and edited as radius, convert back + // to diameter + if(c->other) + c->valA *= 2; + break; + + default: + // These are always positive, and they get the units conversion. + c->valA = fabs(SS.ExprToMm(e)); + break; + } + SS.MarkGroupDirty(c->group); + } +} + +void GraphicsWindow::MouseScroll(double x, double y, double delta) { + double offsetRight = offset.Dot(projRight); + double offsetUp = offset.Dot(projUp); + + double righti = x/scale - offsetRight; + double upi = y/scale - offsetUp; + + // The default zoom factor is 1.2x for one scroll wheel click (delta==1). + // To support smooth scrolling where scroll wheel events come in increments + // smaller (or larger) than 1 we do: + // scale *= exp(ln(1.2) * delta); + // to ensure that the same total scroll delta always results in the same + // total zoom irrespective of in how many increments the zoom was applied. + // For example if we scroll a total delta of a+b in two events vs. one then + // scale * e^a * e^b == scale * e^(a+b) + // while + // scale * a * b != scale * (a+b) + // So this constant is ln(1.2) = 0.1823216 to make the default zoom 1.2x + scale *= exp(0.1823216 * delta); + + double rightf = x/scale - offsetRight; + double upf = y/scale - offsetUp; + + offset = offset.Plus(projRight.ScaledBy(rightf - righti)); + offset = offset.Plus(projUp.ScaledBy(upf - upi)); + + if(SS.TW.shown.screen == TextWindow::Screen::EDIT_VIEW) { + if(havePainted) { + SS.ScheduleShowTW(); + } + } + havePainted = false; + Invalidate(); +} + +void GraphicsWindow::MouseLeave() { + // Un-hover everything when the mouse leaves our window, unless there's + // currently a context menu shown. + if(!context.active) { + hover.Clear(); + toolbarHovered = Command::NONE; + Invalidate(); + } + SS.extraLine.draw = false; +} + +void GraphicsWindow::SixDofEvent(Platform::SixDofEvent event) { + if(event.type == Platform::SixDofEvent::Type::RELEASE) { + ZoomToFit(/*includingInvisibles=*/false, /*useSelection=*/true); + Invalidate(); + return; + } + + if(!havePainted) return; + Vector out = projRight.Cross(projUp); + + // rotation vector is axis of rotation, and its magnitude is angle + Vector aa = Vector::From(event.rotationX, event.rotationY, event.rotationZ); + // but it's given with respect to screen projection frame + aa = aa.ScaleOutOfCsys(projRight, projUp, out); + double aam = aa.Magnitude(); + if(aam > 0.0) aa = aa.WithMagnitude(1); + + // This can either transform our view, or transform a linked part. + GroupSelection(); + Entity *e = NULL; + Group *g = NULL; + if(gs.points == 1 && gs.n == 1) e = SK.GetEntity(gs.point [0]); + if(gs.entities == 1 && gs.n == 1) e = SK.GetEntity(gs.entity[0]); + if(e) g = SK.GetGroup(e->group); + if(g && g->type == Group::Type::LINKED && !event.shiftDown) { + // Apply the transformation to a linked part. Gain down the Z + // axis, since it's hard to see what you're doing on that one since + // it's normal to the screen. + Vector t = projRight.ScaledBy(event.translationX/scale).Plus( + projUp .ScaledBy(event.translationY/scale).Plus( + out .ScaledBy(0.1*event.translationZ/scale))); + Quaternion q = Quaternion::From(aa, aam); + + // If we go five seconds without SpaceNavigator input, or if we've + // switched groups, then consider that a new action and save an undo + // point. + int64_t now = GetMilliseconds(); + if(now - last6DofTime > 5000 || + last6DofGroup != g->h) + { + SS.UndoRemember(); + } + + g->TransformImportedBy(t, q); + + last6DofTime = now; + last6DofGroup = g->h; + SS.MarkGroupDirty(g->h); + } else { + // Apply the transformation to the view of the everything. The + // x and y components are translation; but z component is scale, + // not translation, or else it would do nothing in a parallel + // projection + offset = offset.Plus(projRight.ScaledBy(event.translationX/scale)); + offset = offset.Plus(projUp.ScaledBy(event.translationY/scale)); + scale *= exp(0.001*event.translationZ); + + if(aam > 0.0) { + projRight = projRight.RotatedAbout(aa, -aam); + projUp = projUp. RotatedAbout(aa, -aam); + NormalizeProjectionVectors(); + } + } + + havePainted = false; + Invalidate(); +} diff --git a/src/platform/entrycli.cpp b/src/platform/entrycli.cpp new file mode 100644 index 0000000..61b20db --- /dev/null +++ b/src/platform/entrycli.cpp @@ -0,0 +1,387 @@ +//----------------------------------------------------------------------------- +// Our main() function for the command-line interface. +// +// Copyright 2016 whitequark +//----------------------------------------------------------------------------- +#include "solvespace.h" + +static void ShowUsage(const std::string &cmd) { + fprintf(stderr, "Usage: %s [filename...]", cmd.c_str()); +//-----------------------------------------------------------------------------> 80 col */ + fprintf(stderr, R"( + When run, performs an action specified by on every . + +Common options: + -o, --output + For an input file .slvs, replaces the '%%' symbol in + with and uses it as output file. For example, when using + --output %%-2d.png for input files f/a.slvs and f/b.slvs, output files + f/a-2d.png and f/b-2d.png will be written. + -v, --view + Selects the camera direction. can be one of "top", "bottom", + "left", "right", "front", "back", or "isometric". + -t, --chord-tol + Selects the chord tolerance, used for converting exact curves to + piecewise linear, and exact surfaces into triangle meshes. + For export commands, the unit is mm, and the default is 1.0 mm. + For non-export commands, the unit is %%, and the default is 1.0 %%. + -b, --bg-color + Whether to export the background colour in vector formats. Defaults to off. + +Commands: + thumbnail --output --size --view + [--chord-tol ] + Outputs a rendered view of the sketch, like the SolveSpace GUI would. + is x, in pixels. Graphics acceleration is + not used, and the output may look slightly different from the GUI. + export-view --output --view [--chord-tol ] + [--bg-color ] + Exports a view of the sketch, in a 2d vector format. + export-wireframe --output [--chord-tol ] + Exports a wireframe of the sketch, in a 3d vector format. + export-mesh --output [--chord-tol ] + Exports a triangle mesh of solids in the sketch, with exact surfaces + being triangulated first. + export-surfaces --output + Exports exact surfaces of solids in the sketch, if any. + regenerate [--chord-tol ] + Reloads all imported files, regenerates the sketch, and saves it. + Note that, although this is not an export command, it uses absolute + chord tolerance, and can be used to prepare assemblies for export. +)"); + + auto FormatListFromFileFilters = [](const std::vector &filters) { + std::string descr; + for(auto filter : filters) { + descr += "\n "; + descr += filter.name; + descr += " ("; + bool first = true; + for(auto extension : filter.extensions) { + if(!first) { + descr += ", "; + } + descr += extension; + first = false; + } + descr += ")"; + } + return descr; + }; + + fprintf(stderr, R"( +File formats: + thumbnail:%s + export-view:%s + export-wireframe:%s + export-mesh:%s + export-surfaces:%s +)", FormatListFromFileFilters(Platform::RasterFileFilters).c_str(), + FormatListFromFileFilters(Platform::VectorFileFilters).c_str(), + FormatListFromFileFilters(Platform::Vector3dFileFilters).c_str(), + FormatListFromFileFilters(Platform::MeshFileFilters).c_str(), + FormatListFromFileFilters(Platform::SurfaceFileFilters).c_str()); +} + +static bool RunCommand(const std::vector args) { + if(args.size() < 2) return false; + + for(const std::string &arg : args) { + if(arg == "--help" || arg == "-h") { + ShowUsage(args[0]); + return true; + } + } + + std::function runner; + + std::vector inputFiles; + auto ParseInputFile = [&](size_t &argn) { + std::string arg = args[argn]; + if(arg[0] != '-') { + inputFiles.push_back(Platform::Path::From(arg)); + return true; + } else return false; + }; + + std::string outputPattern; + auto ParseOutputPattern = [&](size_t &argn) { + if(argn + 1 < args.size() && (args[argn] == "--output" || + args[argn] == "-o")) { + argn++; + outputPattern = args[argn]; + return true; + } else return false; + }; + + Vector projUp = {}, projRight = {}; + auto ParseViewDirection = [&](size_t &argn) { + if(argn + 1 < args.size() && (args[argn] == "--view" || + args[argn] == "-v")) { + argn++; + if(args[argn] == "top") { + projRight = Vector::From(1, 0, 0); + projUp = Vector::From(0, 0, -1); + } else if(args[argn] == "bottom") { + projRight = Vector::From(1, 0, 0); + projUp = Vector::From(0, 0, 1); + } else if(args[argn] == "left") { + projRight = Vector::From(0, 0, 1); + projUp = Vector::From(0, 1, 0); + } else if(args[argn] == "right") { + projRight = Vector::From(0, 0, -1); + projUp = Vector::From(0, 1, 0); + } else if(args[argn] == "front") { + projRight = Vector::From(1, 0, 0); + projUp = Vector::From(0, 1, 0); + } else if(args[argn] == "back") { + projRight = Vector::From(-1, 0, 0); + projUp = Vector::From(0, 1, 0); + } else if(args[argn] == "isometric") { + projRight = Vector::From(0.707, 0.000, -0.707); + projUp = Vector::From(-0.408, 0.816, -0.408); + } else { + fprintf(stderr, "Unrecognized view direction '%s'\n", args[argn].c_str()); + } + return true; + } else return false; + }; + + double chordTol = 1.0; + auto ParseChordTolerance = [&](size_t &argn) { + if(argn + 1 < args.size() && (args[argn] == "--chord-tol" || + args[argn] == "-t")) { + argn++; + if(sscanf(args[argn].c_str(), "%lf", &chordTol) == 1) { + return true; + } else return false; + } else return false; + }; + + bool bg_color = false; + auto ParseBgColor = [&](size_t &argn) { + if(argn + 1 < args.size() && (args[argn] == "--bg-color" || + args[argn] == "-b")) { + argn++; + if(args[argn] == "on") { + bg_color = true; + return true; + } else if(args[argn] == "off") { + bg_color = false; + return true; + } else return false; + } else return false; + }; + + unsigned width = 0, height = 0; + if(args[1] == "thumbnail") { + auto ParseSize = [&](size_t &argn) { + if(argn + 1 < args.size() && args[argn] == "--size") { + argn++; + if(sscanf(args[argn].c_str(), "%ux%u", &width, &height) == 2) { + return true; + } else return false; + } else return false; + }; + + for(size_t argn = 2; argn < args.size(); argn++) { + if(!(ParseInputFile(argn) || + ParseOutputPattern(argn) || + ParseViewDirection(argn) || + ParseChordTolerance(argn) || + ParseSize(argn))) { + fprintf(stderr, "Unrecognized option '%s'.\n", args[argn].c_str()); + return false; + } + } + + if(width == 0 || height == 0) { + fprintf(stderr, "Non-zero viewport size must be specified.\n"); + return false; + } + + if(EXACT(projUp.Magnitude() == 0 || projRight.Magnitude() == 0)) { + fprintf(stderr, "View direction must be specified.\n"); + return false; + } + + runner = [&](const Platform::Path &output) { + Camera camera = {}; + camera.pixelRatio = 1; + camera.gridFit = true; + camera.width = width; + camera.height = height; + camera.projUp = projUp; + camera.projRight = projRight; + + SS.GW.projUp = projUp; + SS.GW.projRight = projRight; + SS.GW.scale = SS.GW.ZoomToFit(camera); + camera.scale = SS.GW.scale; + camera.offset = SS.GW.offset; + SS.GenerateAll(); + + CairoPixmapRenderer pixmapCanvas; + pixmapCanvas.antialias = true; + pixmapCanvas.SetLighting(SS.GW.GetLighting()); + pixmapCanvas.SetCamera(camera); + pixmapCanvas.Init(); + + pixmapCanvas.StartFrame(); + SS.GW.Draw(&pixmapCanvas); + pixmapCanvas.FlushFrame(); + pixmapCanvas.FinishFrame(); + pixmapCanvas.ReadFrame()->WritePng(output, /*flip=*/true); + + pixmapCanvas.Clear(); + }; + } else if(args[1] == "export-view") { + for(size_t argn = 2; argn < args.size(); argn++) { + if(!(ParseInputFile(argn) || + ParseOutputPattern(argn) || + ParseViewDirection(argn) || + ParseChordTolerance(argn) || + ParseBgColor(argn))) { + fprintf(stderr, "Unrecognized option '%s'.\n", args[argn].c_str()); + return false; + } + } + + if(EXACT(projUp.Magnitude() == 0 || projRight.Magnitude() == 0)) { + fprintf(stderr, "View direction must be specified.\n"); + return false; + } + + runner = [&](const Platform::Path &output) { + SS.GW.projRight = projRight; + SS.GW.projUp = projUp; + SS.exportChordTol = chordTol; + SS.exportBackgroundColor = bg_color; + + SS.ExportViewOrWireframeTo(output, /*exportWireframe=*/false); + }; + } else if(args[1] == "export-wireframe") { + for(size_t argn = 2; argn < args.size(); argn++) { + if(!(ParseInputFile(argn) || + ParseOutputPattern(argn) || + ParseChordTolerance(argn))) { + fprintf(stderr, "Unrecognized option '%s'.\n", args[argn].c_str()); + return false; + } + } + + runner = [&](const Platform::Path &output) { + SS.exportChordTol = chordTol; + + SS.ExportViewOrWireframeTo(output, /*exportWireframe=*/true); + }; + } else if(args[1] == "export-mesh") { + for(size_t argn = 2; argn < args.size(); argn++) { + if(!(ParseInputFile(argn) || + ParseOutputPattern(argn) || + ParseChordTolerance(argn))) { + fprintf(stderr, "Unrecognized option '%s'.\n", args[argn].c_str()); + return false; + } + } + + runner = [&](const Platform::Path &output) { + SS.exportChordTol = chordTol; + + SS.ExportMeshTo(output); + }; + } else if(args[1] == "export-surfaces") { + for(size_t argn = 2; argn < args.size(); argn++) { + if(!(ParseInputFile(argn) || + ParseOutputPattern(argn))) { + fprintf(stderr, "Unrecognized option '%s'.\n", args[argn].c_str()); + return false; + } + } + + runner = [&](const Platform::Path &output) { + StepFileWriter sfw = {}; + sfw.ExportSurfacesTo(output); + }; + } else if(args[1] == "regenerate") { + for(size_t argn = 2; argn < args.size(); argn++) { + if(!(ParseInputFile(argn) || + ParseChordTolerance(argn))) { + fprintf(stderr, "Unrecognized option '%s'.\n", args[argn].c_str()); + return false; + } + } + + outputPattern = "%.slvs"; + + runner = [&](const Platform::Path &output) { + SS.exportChordTol = chordTol; + SS.exportMode = true; + + SS.SaveToFile(output); + }; + } else { + fprintf(stderr, "Unrecognized command '%s'.\n", args[1].c_str()); + return false; + } + + if(outputPattern.empty()) { + fprintf(stderr, "An output pattern must be specified.\n"); + return false; + } else if(outputPattern.find('%') == std::string::npos && inputFiles.size() > 1) { + fprintf(stderr, + "Output pattern must include a %% symbol when using multiple inputs!\n"); + return false; + } + + if(inputFiles.empty()) { + fprintf(stderr, "At least one input file must be specified.\n"); + return false; + } + + for(const Platform::Path &inputFile : inputFiles) { + Platform::Path absInputFile = inputFile.Expand(/*fromCurrentDirectory=*/true); + + Platform::Path outputFile = Platform::Path::From(outputPattern); + size_t replaceAt = outputFile.raw.find('%'); + if(replaceAt != std::string::npos) { + Platform::Path outputSubst = inputFile.Parent(); + if(outputSubst.IsEmpty()) { + outputSubst = Platform::Path::From(inputFile.FileStem()); + } else { + outputSubst = outputSubst.Join(inputFile.FileStem()); + } + outputFile.raw.replace(replaceAt, 1, outputSubst.raw); + } + Platform::Path absOutputFile = outputFile.Expand(/*fromCurrentDirectory=*/true); + + SS.Init(); + if(!SS.LoadFromFile(absInputFile)) { + fprintf(stderr, "Cannot load '%s'!\n", inputFile.raw.c_str()); + return false; + } + SS.AfterNewFile(); + runner(absOutputFile); + SK.Clear(); + SS.Clear(); + + fprintf(stderr, "Written '%s'.\n", outputFile.raw.c_str()); + } + + return true; +} + +int main(int argc, char **argv) { + std::vector args = Platform::InitCli(argc, argv); + + if(args.size() == 1) { + ShowUsage(args[0]); + return 0; + } + + if(!RunCommand(args)) { + return 1; + } else { + return 0; + } +} diff --git a/src/platform/entrygui.cpp b/src/platform/entrygui.cpp new file mode 100644 index 0000000..397831a --- /dev/null +++ b/src/platform/entrygui.cpp @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// Our main() function for the graphical interface. +// +// Copyright 2018 +//----------------------------------------------------------------------------- +#include "solvespace.h" +#if defined(WIN32) +# include +#endif + +using namespace SolveSpace; + +int main(int argc, char** argv) { + std::vector args = Platform::InitGui(argc, argv); + + Platform::Open3DConnexion(); + SS.Init(); + + if(args.size() >= 2) { + if(args.size() > 2) { + dbp("Only the first file passed on command line will be opened."); + } + + SS.Load(Platform::Path::From(args.back())); + } + + Platform::RunGui(); + + Platform::Close3DConnexion(); + SS.Clear(); + SK.Clear(); + Platform::ClearGui(); + + return 0; +} + +#if defined(WIN32) +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpCmdLine, INT nCmdShow) { + return main(0, NULL); +} +#endif diff --git a/src/platform/gui.cpp b/src/platform/gui.cpp new file mode 100644 index 0000000..28fded4 --- /dev/null +++ b/src/platform/gui.cpp @@ -0,0 +1,134 @@ +//----------------------------------------------------------------------------- +// Platform-dependent GUI functionality that has only minor differences. +// +// Copyright 2018 whitequark +//----------------------------------------------------------------------------- +#include "solvespace.h" + +namespace SolveSpace { +namespace Platform { + +//----------------------------------------------------------------------------- +// Keyboard events +//----------------------------------------------------------------------------- + +std::string AcceleratorDescription(const KeyboardEvent &accel) { + std::string label; + if(accel.controlDown) { +#ifdef __APPLE__ + label += "⌘+"; +#else + label += "Ctrl+"; +#endif + } + + if(accel.shiftDown) { + label += "Shift+"; + } + + switch(accel.key) { + case KeyboardEvent::Key::FUNCTION: + label += ssprintf("F%d", accel.num); + break; + + case KeyboardEvent::Key::CHARACTER: + if(accel.chr == '\t') { + label += "Tab"; + } else if(accel.chr == ' ') { + label += "Space"; + } else if(accel.chr == '\x1b') { + label += "Esc"; + } else if(accel.chr == '\x7f') { + label += "Del"; + } else if(accel.chr != 0) { + label += toupper((char)(accel.chr & 0xff)); + } + break; + } + + return label; +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +void Settings::FreezeBool(const std::string &key, bool value) { + FreezeInt(key, (int)value); +} + +bool Settings::ThawBool(const std::string &key, bool defaultValue) { + return ThawInt(key, (int)defaultValue) != 0; +} + +void Settings::FreezeColor(const std::string &key, RgbaColor value) { + FreezeInt(key, value.ToPackedInt()); +} + +RgbaColor Settings::ThawColor(const std::string &key, RgbaColor defaultValue) { + return RgbaColor::FromPackedInt(ThawInt(key, defaultValue.ToPackedInt())); +} + +//----------------------------------------------------------------------------- +// File dialogs +//----------------------------------------------------------------------------- + +void FileDialog::AddFilter(const FileFilter &filter) { + AddFilter(Translate("file-type", filter.name.c_str()), filter.extensions); +} + +void FileDialog::AddFilters(const std::vector &filters) { + for(auto filter : filters) AddFilter(filter); +} + +std::vector SolveSpaceModelFileFilters = { + { CN_("file-type", "SolveSpace models"), { "slvs" } }, +}; + +std::vector SolveSpaceLinkFileFilters = { + { CN_("file-type", "SolveSpace models"), { "slvs" } }, + { CN_("file-type", "IDF circuit board"), { "emn" } }, +}; + +std::vector RasterFileFilters = { + { CN_("file-type", "PNG image"), { "png" } }, +}; + +std::vector MeshFileFilters = { + { CN_("file-type", "STL mesh"), { "stl" } }, + { CN_("file-type", "Wavefront OBJ mesh"), { "obj" } }, + { CN_("file-type", "Three.js-compatible mesh, with viewer"), { "html" } }, + { CN_("file-type", "Three.js-compatible mesh, mesh only"), { "js" } }, + { CN_("file-type", "VRML text file"), { "wrl" } }, +}; + +std::vector SurfaceFileFilters = { + { CN_("file-type", "STEP file"), { "step", "stp" } }, +}; + +std::vector VectorFileFilters = { + { CN_("file-type", "PDF file"), { "pdf" } }, + { CN_("file-type", "Encapsulated PostScript"), { "eps", "ps" } }, + { CN_("file-type", "Scalable Vector Graphics"), { "svg" } }, + { CN_("file-type", "STEP file"), { "step", "stp" } }, + { CN_("file-type", "DXF file (AutoCAD 2007)"), { "dxf" } }, + { CN_("file-type", "HPGL file"), { "plt", "hpgl" } }, + { CN_("file-type", "G Code"), { "ngc", "txt" } }, +}; + +std::vector Vector3dFileFilters = { + { CN_("file-type", "STEP file"), { "step", "stp" } }, + { CN_("file-type", "DXF file (AutoCAD 2007)"), { "dxf" } }, +}; + +std::vector ImportFileFilters = { + { CN_("file-type", "AutoCAD DXF and DWG files"), { "dxf", "dwg" } }, +}; + +std::vector CsvFileFilters = { + { CN_("file-type", "Comma-separated values"), { "csv" } }, +}; + + +} +} diff --git a/src/platform/gui.h b/src/platform/gui.h new file mode 100644 index 0000000..1608a6f --- /dev/null +++ b/src/platform/gui.h @@ -0,0 +1,390 @@ +//----------------------------------------------------------------------------- +// An abstraction for platform-dependent GUI functionality. +// +// Copyright 2018 whitequark +//----------------------------------------------------------------------------- + +#ifndef SOLVESPACE_GUI_H +#define SOLVESPACE_GUI_H + +class RgbaColor; + +namespace Platform { + +//----------------------------------------------------------------------------- +// Events +//----------------------------------------------------------------------------- + +// A mouse input event. +class MouseEvent { +public: + enum class Type { + MOTION, + PRESS, + DBL_PRESS, + RELEASE, + SCROLL_VERT, + LEAVE, + }; + + enum class Button { + NONE, + LEFT, + MIDDLE, + RIGHT, + }; + + Type type; + double x; + double y; + bool shiftDown; + bool controlDown; + union { + Button button; // for Type::{MOTION,PRESS,DBL_PRESS,RELEASE} + double scrollDelta; // for Type::SCROLL_VERT + }; +}; + +// A 3-DOF input event. +struct SixDofEvent { + enum class Type { + MOTION, + PRESS, + RELEASE, + }; + + enum class Button { + FIT, + }; + + Type type; + bool shiftDown; + bool controlDown; + double translationX, translationY, translationZ; // for Type::MOTION + double rotationX, rotationY, rotationZ; // for Type::MOTION + Button button; // for Type::{PRESS,RELEASE} +}; + +// A keyboard input event. +struct KeyboardEvent { + enum class Type { + PRESS, + RELEASE, + }; + + enum class Key { + CHARACTER, + FUNCTION, + }; + + Type type; + Key key; + union { + char32_t chr; // for Key::CHARACTER + int num; // for Key::FUNCTION + }; + bool shiftDown; + bool controlDown; + + bool Equals(const KeyboardEvent &other) { + return type == other.type && key == other.key && + shiftDown == other.shiftDown && controlDown == other.controlDown && + ((key == Key::CHARACTER && chr == other.chr) || + (key == Key::FUNCTION && num == other.num)); + } +}; + +std::string AcceleratorDescription(const KeyboardEvent &accel); + +//----------------------------------------------------------------------------- +// Interfaces +//----------------------------------------------------------------------------- + +// Handling fatal errors. +[[noreturn]] +void FatalError(const std::string &message); + +// A native settings store. +class Settings { +public: + virtual ~Settings() = default; + + virtual void FreezeInt(const std::string &key, uint32_t value) = 0; + virtual uint32_t ThawInt(const std::string &key, uint32_t defaultValue = 0) = 0; + + virtual void FreezeFloat(const std::string &key, double value) = 0; + virtual double ThawFloat(const std::string &key, double defaultValue = 0.0) = 0; + + virtual void FreezeString(const std::string &key, const std::string &value) = 0; + virtual std::string ThawString(const std::string &key, + const std::string &defaultValue = "") = 0; + + virtual void FreezeBool(const std::string &key, bool value); + virtual bool ThawBool(const std::string &key, bool defaultValue = false); + + virtual void FreezeColor(const std::string &key, RgbaColor value); + virtual RgbaColor ThawColor(const std::string &key, RgbaColor defaultValue); +}; + +typedef std::shared_ptr SettingsRef; + +SettingsRef GetSettings(); + +// A native single-shot timer. +class Timer { +public: + std::function onTimeout; + + virtual ~Timer() = default; + + virtual void RunAfter(unsigned milliseconds) = 0; + virtual void RunAfterNextFrame() { RunAfter(1); } + virtual void RunAfterProcessingEvents() { RunAfter(0); } +}; + +typedef std::shared_ptr TimerRef; + +TimerRef CreateTimer(); + +// A native menu item. +class MenuItem { +public: + enum class Indicator { + NONE, + CHECK_MARK, + RADIO_MARK, + }; + + std::function onTrigger; + + virtual ~MenuItem() = default; + + virtual void SetAccelerator(KeyboardEvent accel) = 0; + virtual void SetIndicator(Indicator type) = 0; + virtual void SetEnabled(bool enabled) = 0; + virtual void SetActive(bool active) = 0; +}; + +typedef std::shared_ptr MenuItemRef; + +// A native menu. +class Menu { +public: + virtual ~Menu() = default; + + virtual std::shared_ptr AddItem( + const std::string &label, std::function onTrigger = std::function(), + bool mnemonics = true) = 0; + virtual std::shared_ptr AddSubMenu(const std::string &label) = 0; + virtual void AddSeparator() = 0; + + virtual void PopUp() = 0; + + virtual void Clear() = 0; +}; + +typedef std::shared_ptr MenuRef; + +// A native menu bar. +class MenuBar { +public: + virtual ~MenuBar() = default; + + virtual std::shared_ptr AddSubMenu(const std::string &label) = 0; + + virtual void Clear() = 0; +}; + +typedef std::shared_ptr MenuBarRef; + +MenuRef CreateMenu(); +MenuBarRef GetOrCreateMainMenu(bool *unique); + +// A native top-level window, with an OpenGL context, and an editor overlay. +class Window { +public: + enum class Kind { + TOPLEVEL, + TOOL, + }; + + enum class Cursor { + POINTER, + HAND + }; + + std::function onClose; + std::function onFullScreen; + std::function onMouseEvent; + std::function onSixDofEvent; + std::function onKeyboardEvent; + std::function onEditingDone; + std::function onScrollbarAdjusted; + std::function onRender; + + virtual ~Window() = default; + + // Returns physical display DPI. + virtual double GetPixelDensity() = 0; + // Returns raster graphics and coordinate scale (already applied on the platform side), + // i.e. size of logical pixel in physical pixels, or device pixel ratio. + virtual int GetDevicePixelRatio() = 0; + // Returns (fractional) font scale, to be applied on top of (integral) device pixel ratio. + virtual double GetDeviceFontScale() { + return GetPixelDensity() / GetDevicePixelRatio() / 96.0; + } + + virtual bool IsVisible() = 0; + virtual void SetVisible(bool visible) = 0; + virtual void Focus() = 0; + + virtual bool IsFullScreen() = 0; + virtual void SetFullScreen(bool fullScreen) = 0; + + virtual void SetTitle(const std::string &title) = 0; + virtual bool SetTitleForFilename(const Path &filename) { return false; } + + virtual void SetMenuBar(MenuBarRef menuBar) = 0; + + virtual void GetContentSize(double *width, double *height) = 0; + virtual void SetMinContentSize(double width, double height) = 0; + + virtual void FreezePosition(SettingsRef settings, const std::string &key) = 0; + virtual void ThawPosition(SettingsRef settings, const std::string &key) = 0; + + virtual void SetCursor(Cursor cursor) = 0; + virtual void SetTooltip(const std::string &text, double x, double y, + double width, double height) = 0; + + virtual bool IsEditorVisible() = 0; + virtual void ShowEditor(double x, double y, double fontHeight, double minWidth, + bool isMonospace, const std::string &text) = 0; + virtual void HideEditor() = 0; + + virtual void SetScrollbarVisible(bool visible) = 0; + virtual void ConfigureScrollbar(double min, double max, double pageSize) = 0; + virtual double GetScrollbarPosition() = 0; + virtual void SetScrollbarPosition(double pos) = 0; + + virtual void Invalidate() = 0; +}; + +typedef std::shared_ptr WindowRef; + +WindowRef CreateWindow(Window::Kind kind = Window::Kind::TOPLEVEL, + WindowRef parentWindow = NULL); + +// 3DConnexion support. +void Open3DConnexion(); +void Close3DConnexion(); +void Request3DConnexionEventsForWindow(WindowRef window); + +// A native dialog that asks for one choice out of several. +class MessageDialog { +public: + enum class Type { + INFORMATION, + QUESTION, + WARNING, + ERROR + }; + + enum class Response { + NONE, + OK, + YES, + NO, + CANCEL + }; + + std::function onResponse; + + virtual ~MessageDialog() = default; + + virtual void SetType(Type type) = 0; + virtual void SetTitle(std::string title) = 0; + virtual void SetMessage(std::string message) = 0; + virtual void SetDescription(std::string description) = 0; + + virtual void AddButton(std::string label, Response response, bool isDefault = false) = 0; + + virtual Response RunModal() = 0; + virtual void ShowModal() { + Response response = RunModal(); + if(onResponse) { + onResponse(response); + } + } +}; + +typedef std::shared_ptr MessageDialogRef; + +MessageDialogRef CreateMessageDialog(WindowRef parentWindow); + +// A file filter. +struct FileFilter { + std::string name; + std::vector extensions; +}; + +// SolveSpace's native file format +extern std::vector SolveSpaceModelFileFilters; +// SolveSpace's linkable file formats +extern std::vector SolveSpaceLinkFileFilters; +// Raster image +extern std::vector RasterFileFilters; +// Triangle mesh +extern std::vector MeshFileFilters; +// NURBS surfaces +extern std::vector SurfaceFileFilters; +// 2d vector (lines and curves) format +extern std::vector VectorFileFilters; +// 3d vector (wireframe lines and curves) format +extern std::vector Vector3dFileFilters; +// Any importable format +extern std::vector ImportFileFilters; +// Comma-separated value, like a spreadsheet would use +extern std::vector CsvFileFilters; + +// A native dialog that asks to choose a file. +class FileDialog { +public: + virtual ~FileDialog() = default; + + virtual void SetTitle(std::string title) = 0; + virtual void SetCurrentName(std::string name) = 0; + + virtual Platform::Path GetFilename() = 0; + virtual void SetFilename(Platform::Path path) = 0; + virtual void SuggestFilename(Platform::Path path) = 0; + + virtual void AddFilter(std::string name, std::vector extensions) = 0; + void AddFilter(const FileFilter &filter); + void AddFilters(const std::vector &filters); + + virtual void FreezeChoices(SettingsRef settings, const std::string &key) = 0; + virtual void ThawChoices(SettingsRef settings, const std::string &key) = 0; + + virtual bool RunModal() = 0; +}; + +typedef std::shared_ptr FileDialogRef; + +FileDialogRef CreateOpenFileDialog(WindowRef parentWindow); +FileDialogRef CreateSaveFileDialog(WindowRef parentWindow); + +//----------------------------------------------------------------------------- +// Application-wide APIs +//----------------------------------------------------------------------------- + +std::vector GetFontFiles(); +void OpenInBrowser(const std::string &url); + +std::vector InitGui(int argc, char **argv); +void RunGui(); +void ExitGui(); +void ClearGui(); + +} + +#endif diff --git a/src/platform/guigtk.cpp b/src/platform/guigtk.cpp new file mode 100644 index 0000000..e8113ed --- /dev/null +++ b/src/platform/guigtk.cpp @@ -0,0 +1,1497 @@ +//----------------------------------------------------------------------------- +// The GTK-based implementation of platform-dependent GUI functionality. +// +// Copyright 2018 whitequark +//----------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#if defined(HAVE_GTK_FILECHOOSERNATIVE) +# include +#endif + +#if defined(HAVE_SPACEWARE) +# include +# include +#endif + +#include "solvespace.h" + +namespace SolveSpace { +namespace Platform { + +//----------------------------------------------------------------------------- +// Utility functions +//----------------------------------------------------------------------------- + +static std::string PrepareMnemonics(std::string label) { + std::replace(label.begin(), label.end(), '&', '_'); + return label; +} + +static std::string PrepareTitle(const std::string &title) { + return title + " — SolveSpace"; +} + +//----------------------------------------------------------------------------- +// Fatal errors +//----------------------------------------------------------------------------- + +void FatalError(const std::string &message) { + fprintf(stderr, "%s", message.c_str()); + abort(); +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +class SettingsImplGtk final : public Settings { +public: + // Why aren't we using GSettings? Two reasons. It doesn't allow to easily see whether + // the setting had the default value, and it requires to install a schema globally. + Path _path; + json_object *_json = NULL; + + static Path GetConfigPath() { + Path configHome; + if(getenv("XDG_CONFIG_HOME")) { + configHome = Path::From(getenv("XDG_CONFIG_HOME")); + } else if(getenv("HOME")) { + configHome = Path::From(getenv("HOME")).Join(".config"); + } else { + dbp("neither XDG_CONFIG_HOME nor HOME are set"); + return Path::From(""); + } + if(!configHome.IsEmpty()) { + configHome = configHome.Join("solvespace"); + } + + const char *configHomeC = configHome.raw.c_str(); + struct stat st; + if(stat(configHomeC, &st)) { + if(errno == ENOENT) { + if(mkdir(configHomeC, 0777)) { + dbp("cannot mkdir %s: %s", configHomeC, strerror(errno)); + return Path::From(""); + } + } else { + dbp("cannot stat %s: %s", configHomeC, strerror(errno)); + return Path::From(""); + } + } else if(!S_ISDIR(st.st_mode)) { + dbp("%s is not a directory", configHomeC); + return Path::From(""); + } + + return configHome.Join("settings.json"); + } + + SettingsImplGtk() { + _path = GetConfigPath(); + if(_path.IsEmpty()) { + dbp("settings will not be saved"); + } else { + _json = json_object_from_file(_path.raw.c_str()); + if(!_json && errno != ENOENT) { + dbp("cannot load settings: %s", strerror(errno)); + } + } + + if(_json == NULL) { + _json = json_object_new_object(); + } + } + + ~SettingsImplGtk() override { + if(!_path.IsEmpty()) { + // json-c <0.12 has the first argument non-const + if(json_object_to_file_ext((char *)_path.raw.c_str(), _json, + JSON_C_TO_STRING_PRETTY)) { + dbp("cannot save settings: %s", strerror(errno)); + } + } + + json_object_put(_json); + } + + void FreezeInt(const std::string &key, uint32_t value) override { + struct json_object *jsonValue = json_object_new_int(value); + json_object_object_add(_json, key.c_str(), jsonValue); + } + + uint32_t ThawInt(const std::string &key, uint32_t defaultValue) override { + struct json_object *jsonValue; + if(json_object_object_get_ex(_json, key.c_str(), &jsonValue)) { + return json_object_get_int(jsonValue); + } + return defaultValue; + } + + void FreezeBool(const std::string &key, bool value) override { + struct json_object *jsonValue = json_object_new_boolean(value); + json_object_object_add(_json, key.c_str(), jsonValue); + } + + bool ThawBool(const std::string &key, bool defaultValue) override { + struct json_object *jsonValue; + if(json_object_object_get_ex(_json, key.c_str(), &jsonValue)) { + return json_object_get_boolean(jsonValue); + } + return defaultValue; + } + + void FreezeFloat(const std::string &key, double value) override { + struct json_object *jsonValue = json_object_new_double(value); + json_object_object_add(_json, key.c_str(), jsonValue); + } + + double ThawFloat(const std::string &key, double defaultValue) override { + struct json_object *jsonValue; + if(json_object_object_get_ex(_json, key.c_str(), &jsonValue)) { + return json_object_get_double(jsonValue); + } + return defaultValue; + } + + void FreezeString(const std::string &key, const std::string &value) override { + struct json_object *jsonValue = json_object_new_string(value.c_str()); + json_object_object_add(_json, key.c_str(), jsonValue); + } + + std::string ThawString(const std::string &key, + const std::string &defaultValue = "") override { + struct json_object *jsonValue; + if(json_object_object_get_ex(_json, key.c_str(), &jsonValue)) { + return json_object_get_string(jsonValue); + } + return defaultValue; + } +}; + +SettingsRef GetSettings() { + static std::shared_ptr settings; + if(!settings) { + settings = std::make_shared(); + } + return settings; +} + +//----------------------------------------------------------------------------- +// Timers +//----------------------------------------------------------------------------- + +class TimerImplGtk final : public Timer { +public: + sigc::connection _connection; + + void RunAfter(unsigned milliseconds) override { + if(!_connection.empty()) { + _connection.disconnect(); + } + + auto handler = [this]() { + if(this->onTimeout) { + this->onTimeout(); + } + return false; + }; + _connection = Glib::signal_timeout().connect(handler, milliseconds); + } +}; + +TimerRef CreateTimer() { + return std::make_shared(); +} + +//----------------------------------------------------------------------------- +// GTK menu extensions +//----------------------------------------------------------------------------- + +class GtkMenuItem : public Gtk::CheckMenuItem { + Platform::MenuItem *_receiver; + bool _has_indicator; + bool _synthetic_event; + +public: + GtkMenuItem(Platform::MenuItem *receiver) : + _receiver(receiver), _has_indicator(false), _synthetic_event(false) { + } + + void set_accel_key(const Gtk::AccelKey &accel_key) { + Gtk::CheckMenuItem::set_accel_key(accel_key); + } + + bool has_indicator() const { + return _has_indicator; + } + + void set_has_indicator(bool has_indicator) { + _has_indicator = has_indicator; + } + + void set_active(bool active) { + if(Gtk::CheckMenuItem::get_active() == active) + return; + + _synthetic_event = true; + Gtk::CheckMenuItem::set_active(active); + _synthetic_event = false; + } + +protected: + void on_activate() override { + Gtk::CheckMenuItem::on_activate(); + + if(!_synthetic_event && _receiver->onTrigger) { + _receiver->onTrigger(); + } + } + + void draw_indicator_vfunc(const Cairo::RefPtr &cr) override { + if(_has_indicator) { + Gtk::CheckMenuItem::draw_indicator_vfunc(cr); + } + } +}; + +//----------------------------------------------------------------------------- +// Menus +//----------------------------------------------------------------------------- + +class MenuItemImplGtk final : public MenuItem { +public: + GtkMenuItem gtkMenuItem; + + MenuItemImplGtk() : gtkMenuItem(this) {} + + void SetAccelerator(KeyboardEvent accel) override { + guint accelKey = 0; + if(accel.key == KeyboardEvent::Key::CHARACTER) { + if(accel.chr == '\t') { + accelKey = GDK_KEY_Tab; + } else if(accel.chr == '\x1b') { + accelKey = GDK_KEY_Escape; + } else if(accel.chr == '\x7f') { + accelKey = GDK_KEY_Delete; + } else { + accelKey = gdk_unicode_to_keyval(accel.chr); + } + } else if(accel.key == KeyboardEvent::Key::FUNCTION) { + accelKey = GDK_KEY_F1 + accel.num - 1; + } + + Gdk::ModifierType accelMods = {}; + if(accel.shiftDown) { + accelMods |= Gdk::SHIFT_MASK; + } + if(accel.controlDown) { + accelMods |= Gdk::CONTROL_MASK; + } + + gtkMenuItem.set_accel_key(Gtk::AccelKey(accelKey, accelMods)); + } + + void SetIndicator(Indicator type) override { + switch(type) { + case Indicator::NONE: + gtkMenuItem.set_has_indicator(false); + break; + + case Indicator::CHECK_MARK: + gtkMenuItem.set_has_indicator(true); + gtkMenuItem.set_draw_as_radio(false); + break; + + case Indicator::RADIO_MARK: + gtkMenuItem.set_has_indicator(true); + gtkMenuItem.set_draw_as_radio(true); + break; + } + } + + void SetActive(bool active) override { + ssassert(gtkMenuItem.has_indicator(), + "Cannot change state of a menu item without indicator"); + gtkMenuItem.set_active(active); + } + + void SetEnabled(bool enabled) override { + gtkMenuItem.set_sensitive(enabled); + } +}; + +class MenuImplGtk final : public Menu { +public: + Gtk::Menu gtkMenu; + std::vector> menuItems; + std::vector> subMenus; + + MenuItemRef AddItem(const std::string &label, + std::function onTrigger = NULL, + bool mnemonics = true) override { + auto menuItem = std::make_shared(); + menuItems.push_back(menuItem); + + menuItem->gtkMenuItem.set_label(mnemonics ? PrepareMnemonics(label) : label); + menuItem->gtkMenuItem.set_use_underline(mnemonics); + menuItem->gtkMenuItem.show(); + menuItem->onTrigger = onTrigger; + gtkMenu.append(menuItem->gtkMenuItem); + + return menuItem; + } + + MenuRef AddSubMenu(const std::string &label) override { + auto menuItem = std::make_shared(); + menuItems.push_back(menuItem); + + auto subMenu = std::make_shared(); + subMenus.push_back(subMenu); + + menuItem->gtkMenuItem.set_label(PrepareMnemonics(label)); + menuItem->gtkMenuItem.set_use_underline(true); + menuItem->gtkMenuItem.set_submenu(subMenu->gtkMenu); + menuItem->gtkMenuItem.show_all(); + gtkMenu.append(menuItem->gtkMenuItem); + + return subMenu; + } + + void AddSeparator() override { + Gtk::SeparatorMenuItem *gtkMenuItem = Gtk::manage(new Gtk::SeparatorMenuItem()); + gtkMenuItem->show(); + gtkMenu.append(*Gtk::manage(gtkMenuItem)); + } + + void PopUp() override { + Glib::RefPtr loop = Glib::MainLoop::create(); + auto signal = gtkMenu.signal_deactivate().connect([&]() { loop->quit(); }); + + gtkMenu.show_all(); + gtkMenu.popup(0, GDK_CURRENT_TIME); + loop->run(); + signal.disconnect(); + } + + void Clear() override { + gtkMenu.foreach([&](Gtk::Widget &w) { gtkMenu.remove(w); }); + menuItems.clear(); + subMenus.clear(); + } +}; + +MenuRef CreateMenu() { + return std::make_shared(); +} + +class MenuBarImplGtk final : public MenuBar { +public: + Gtk::MenuBar gtkMenuBar; + std::vector> subMenus; + + MenuRef AddSubMenu(const std::string &label) override { + auto subMenu = std::make_shared(); + subMenus.push_back(subMenu); + + Gtk::MenuItem *gtkMenuItem = Gtk::manage(new Gtk::MenuItem); + gtkMenuItem->set_label(PrepareMnemonics(label)); + gtkMenuItem->set_use_underline(true); + gtkMenuItem->set_submenu(subMenu->gtkMenu); + gtkMenuItem->show_all(); + gtkMenuBar.append(*gtkMenuItem); + + return subMenu; + } + + void Clear() override { + gtkMenuBar.foreach([&](Gtk::Widget &w) { gtkMenuBar.remove(w); }); + subMenus.clear(); + } +}; + +MenuBarRef GetOrCreateMainMenu(bool *unique) { + *unique = false; + return std::make_shared(); +} + +//----------------------------------------------------------------------------- +// GTK GL and window extensions +//----------------------------------------------------------------------------- + +class GtkGLWidget : public Gtk::GLArea { + Window *_receiver; + +public: + GtkGLWidget(Platform::Window *receiver) : _receiver(receiver) { + set_has_depth_buffer(true); + set_can_focus(true); + set_events(Gdk::POINTER_MOTION_MASK | + Gdk::BUTTON_PRESS_MASK | + Gdk::BUTTON_RELEASE_MASK | + Gdk::BUTTON_MOTION_MASK | + Gdk::SCROLL_MASK | + Gdk::LEAVE_NOTIFY_MASK | + Gdk::KEY_PRESS_MASK | + Gdk::KEY_RELEASE_MASK); + } + +protected: + // Work around a bug fixed in GTKMM 3.22: + // https://mail.gnome.org/archives/gtkmm-list/2016-April/msg00020.html + Glib::RefPtr on_create_context() override { + return get_window()->create_gl_context(); + } + + bool on_render(const Glib::RefPtr &context) override { + if(_receiver->onRender) { + _receiver->onRender(); + } + return true; + } + + bool process_pointer_event(MouseEvent::Type type, double x, double y, + guint state, guint button = 0, double scroll_delta = 0) { + MouseEvent event = {}; + event.type = type; + event.x = x; + event.y = y; + if(button == 1 || (state & GDK_BUTTON1_MASK) != 0) { + event.button = MouseEvent::Button::LEFT; + } else if(button == 2 || (state & GDK_BUTTON2_MASK) != 0) { + event.button = MouseEvent::Button::MIDDLE; + } else if(button == 3 || (state & GDK_BUTTON3_MASK) != 0) { + event.button = MouseEvent::Button::RIGHT; + } + if((state & GDK_SHIFT_MASK) != 0) { + event.shiftDown = true; + } + if((state & GDK_CONTROL_MASK) != 0) { + event.controlDown = true; + } + if(scroll_delta != 0) { + event.scrollDelta = scroll_delta; + } + + if(_receiver->onMouseEvent) { + return _receiver->onMouseEvent(event); + } + + return false; + } + + bool on_motion_notify_event(GdkEventMotion *gdk_event) override { + if(process_pointer_event(MouseEvent::Type::MOTION, + gdk_event->x, gdk_event->y, gdk_event->state)) + return true; + + return Gtk::GLArea::on_motion_notify_event(gdk_event); + } + + bool on_button_press_event(GdkEventButton *gdk_event) override { + MouseEvent::Type type; + if(gdk_event->type == GDK_BUTTON_PRESS) { + type = MouseEvent::Type::PRESS; + } else if(gdk_event->type == GDK_2BUTTON_PRESS) { + type = MouseEvent::Type::DBL_PRESS; + } else { + return Gtk::GLArea::on_button_press_event(gdk_event); + } + + if(process_pointer_event(type, gdk_event->x, gdk_event->y, + gdk_event->state, gdk_event->button)) + return true; + + return Gtk::GLArea::on_button_press_event(gdk_event); + } + + bool on_button_release_event(GdkEventButton *gdk_event) override { + if(process_pointer_event(MouseEvent::Type::RELEASE, + gdk_event->x, gdk_event->y, + gdk_event->state, gdk_event->button)) + return true; + + return Gtk::GLArea::on_button_release_event(gdk_event); + } + + bool on_scroll_event(GdkEventScroll *gdk_event) override { + double delta; + if(gdk_event->delta_y < 0 || gdk_event->direction == GDK_SCROLL_UP) { + delta = 1; + } else if(gdk_event->delta_y > 0 || gdk_event->direction == GDK_SCROLL_DOWN) { + delta = -1; + } else { + return false; + } + + if(process_pointer_event(MouseEvent::Type::SCROLL_VERT, + gdk_event->x, gdk_event->y, + gdk_event->state, 0, delta)) + return true; + + return Gtk::GLArea::on_scroll_event(gdk_event); + } + + bool on_leave_notify_event(GdkEventCrossing *gdk_event) override { + if(process_pointer_event(MouseEvent::Type::LEAVE, + gdk_event->x, gdk_event->y, gdk_event->state)) + return true; + + return Gtk::GLArea::on_leave_notify_event(gdk_event); + } + + bool process_key_event(KeyboardEvent::Type type, GdkEventKey *gdk_event) { + KeyboardEvent event = {}; + event.type = type; + + Gdk::ModifierType mod_mask = get_modifier_mask(Gdk::MODIFIER_INTENT_DEFAULT_MOD_MASK); + if((gdk_event->state & mod_mask) & ~(GDK_SHIFT_MASK|GDK_CONTROL_MASK)) { + return false; + } + + event.shiftDown = (gdk_event->state & GDK_SHIFT_MASK) != 0; + event.controlDown = (gdk_event->state & GDK_CONTROL_MASK) != 0; + + char32_t chr = gdk_keyval_to_unicode(gdk_keyval_to_lower(gdk_event->keyval)); + if(chr != 0) { + event.key = KeyboardEvent::Key::CHARACTER; + event.chr = chr; + } else if(gdk_event->keyval >= GDK_KEY_F1 && + gdk_event->keyval <= GDK_KEY_F12) { + event.key = KeyboardEvent::Key::FUNCTION; + event.num = gdk_event->keyval - GDK_KEY_F1 + 1; + } else { + return false; + } + + if(_receiver->onKeyboardEvent) { + return _receiver->onKeyboardEvent(event); + } + + return false; + } + + bool on_key_press_event(GdkEventKey *gdk_event) override { + if(process_key_event(KeyboardEvent::Type::PRESS, gdk_event)) + return true; + + return Gtk::GLArea::on_key_press_event(gdk_event); + } + + bool on_key_release_event(GdkEventKey *gdk_event) override { + if(process_key_event(KeyboardEvent::Type::RELEASE, gdk_event)) + return true; + + return Gtk::GLArea::on_key_release_event(gdk_event); + } +}; + +class GtkEditorOverlay : public Gtk::Fixed { + Window *_receiver; + GtkGLWidget _gl_widget; + Gtk::Entry _entry; + +public: + GtkEditorOverlay(Platform::Window *receiver) : _receiver(receiver), _gl_widget(receiver) { + add(_gl_widget); + + _entry.set_no_show_all(true); + _entry.set_has_frame(false); + add(_entry); + + _entry.signal_activate(). + connect(sigc::mem_fun(this, &GtkEditorOverlay::on_activate)); + } + + bool is_editing() const { + return _entry.is_visible(); + } + + void start_editing(int x, int y, int font_height, int min_width, bool is_monospace, + const std::string &val) { + Pango::FontDescription font_desc; + font_desc.set_family(is_monospace ? "monospace" : "normal"); + font_desc.set_absolute_size(font_height * Pango::SCALE); + _entry.override_font(font_desc); + + // The y coordinate denotes baseline. + Pango::FontMetrics font_metrics = get_pango_context()->get_metrics(font_desc); + y -= font_metrics.get_ascent() / Pango::SCALE; + + Glib::RefPtr layout = Pango::Layout::create(get_pango_context()); + layout->set_font_description(font_desc); + // Add one extra char width to avoid scrolling. + layout->set_text(val + " "); + int width = layout->get_logical_extents().get_width(); + + Gtk::Border margin = _entry.get_style_context()->get_margin(); + Gtk::Border border = _entry.get_style_context()->get_border(); + Gtk::Border padding = _entry.get_style_context()->get_padding(); + move(_entry, + x - margin.get_left() - border.get_left() - padding.get_left(), + y - margin.get_top() - border.get_top() - padding.get_top()); + + int fitWidth = width / Pango::SCALE + padding.get_left() + padding.get_right(); + _entry.set_size_request(max(fitWidth, min_width), -1); + queue_resize(); + + _entry.set_text(val); + + if(!_entry.is_visible()) { + _entry.show(); + _entry.grab_focus(); + + // We grab the input for ourselves and not the entry to still have + // the pointer events go through the underlay. + add_modal_grab(); + } + } + + void stop_editing() { + if(_entry.is_visible()) { + remove_modal_grab(); + _entry.hide(); + _gl_widget.grab_focus(); + } + } + + GtkGLWidget &get_gl_widget() { + return _gl_widget; + } + +protected: + bool on_key_press_event(GdkEventKey *gdk_event) override { + if(is_editing()) { + if(gdk_event->keyval == GDK_KEY_Escape) { + return _gl_widget.event((GdkEvent *)gdk_event); + } else { + _entry.event((GdkEvent *)gdk_event); + } + return true; + } + + return Gtk::Fixed::on_key_press_event(gdk_event); + } + + bool on_key_release_event(GdkEventKey *gdk_event) override { + if(is_editing()) { + _entry.event((GdkEvent *)gdk_event); + return true; + } + + return Gtk::Fixed::on_key_release_event(gdk_event); + } + + void on_size_allocate(Gtk::Allocation& allocation) override { + Gtk::Fixed::on_size_allocate(allocation); + + _gl_widget.size_allocate(allocation); + + int width, height, min_height, natural_height; + _entry.get_size_request(width, height); + _entry.get_preferred_height(min_height, natural_height); + + Gtk::Allocation entry_rect = _entry.get_allocation(); + entry_rect.set_width(width); + entry_rect.set_height(natural_height); + _entry.size_allocate(entry_rect); + } + + void on_activate() { + if(_receiver->onEditingDone) { + _receiver->onEditingDone(_entry.get_text()); + } + } +}; + +class GtkWindow : public Gtk::Window { + Platform::Window *_receiver; + Gtk::VBox _vbox; + Gtk::MenuBar *_menu_bar = NULL; + Gtk::HBox _hbox; + GtkEditorOverlay _editor_overlay; + Gtk::VScrollbar _scrollbar; + bool _is_under_cursor = false; + bool _is_fullscreen = false; + std::string _tooltip_text; + Gdk::Rectangle _tooltip_area; + +public: + GtkWindow(Platform::Window *receiver) : _receiver(receiver), _editor_overlay(receiver) { + _hbox.pack_start(_editor_overlay, /*expand=*/true, /*fill=*/true); + _hbox.pack_end(_scrollbar, /*expand=*/false, /*fill=*/false); + _vbox.pack_end(_hbox, /*expand=*/true, /*fill=*/true); + add(_vbox); + + _vbox.show(); + _hbox.show(); + _editor_overlay.show(); + get_gl_widget().show(); + + _scrollbar.get_adjustment()->signal_value_changed(). + connect(sigc::mem_fun(this, &GtkWindow::on_scrollbar_value_changed)); + + get_gl_widget().set_has_tooltip(true); + get_gl_widget().signal_query_tooltip(). + connect(sigc::mem_fun(this, &GtkWindow::on_query_tooltip)); + } + + bool is_full_screen() const { + return _is_fullscreen; + } + + Gtk::MenuBar *get_menu_bar() const { + return _menu_bar; + } + + void set_menu_bar(Gtk::MenuBar *menu_bar) { + if(_menu_bar) { + _vbox.remove(*_menu_bar); + } + _menu_bar = menu_bar; + if(_menu_bar) { + _menu_bar->show_all(); + _vbox.pack_start(*_menu_bar, /*expand=*/false, /*fill=*/false); + } + } + + GtkEditorOverlay &get_editor_overlay() { + return _editor_overlay; + } + + GtkGLWidget &get_gl_widget() { + return _editor_overlay.get_gl_widget(); + } + + Gtk::VScrollbar &get_scrollbar() { + return _scrollbar; + } + + void set_tooltip(const std::string &text, const Gdk::Rectangle &rect) { + if(_tooltip_text != text) { + _tooltip_text = text; + _tooltip_area = rect; + get_gl_widget().trigger_tooltip_query(); + } + } + +protected: + bool on_query_tooltip(int x, int y, bool keyboard_tooltip, + const Glib::RefPtr &tooltip) { + tooltip->set_text(_tooltip_text); + tooltip->set_tip_area(_tooltip_area); + return !_tooltip_text.empty() && (keyboard_tooltip || _is_under_cursor); + } + + bool on_enter_notify_event(GdkEventCrossing* gdk_event) override { + _is_under_cursor = true; + + return true; + } + + bool on_leave_notify_event(GdkEventCrossing* gdk_event) override { + _is_under_cursor = false; + + return true; + } + + bool on_delete_event(GdkEventAny* gdk_event) override { + if(_receiver->onClose) { + _receiver->onClose(); + return true; + } + + return false; + } + + bool on_window_state_event(GdkEventWindowState *gdk_event) override { + _is_fullscreen = gdk_event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN; + if(_receiver->onFullScreen) { + _receiver->onFullScreen(_is_fullscreen); + } + + return true; + } + + void on_scrollbar_value_changed() { + if(_receiver->onScrollbarAdjusted) { + _receiver->onScrollbarAdjusted(_scrollbar.get_adjustment()->get_value()); + } + } +}; + +//----------------------------------------------------------------------------- +// Windows +//----------------------------------------------------------------------------- + +class WindowImplGtk final : public Window { +public: + GtkWindow gtkWindow; + MenuBarRef menuBar; + + WindowImplGtk(Window::Kind kind) : gtkWindow(this) { + switch(kind) { + case Kind::TOPLEVEL: + break; + + case Kind::TOOL: + gtkWindow.set_type_hint(Gdk::WINDOW_TYPE_HINT_UTILITY); + gtkWindow.set_skip_taskbar_hint(true); + gtkWindow.set_skip_pager_hint(true); + break; + } + + auto icon = LoadPng("freedesktop/solvespace-48x48.png"); + auto gdkIcon = + Gdk::Pixbuf::create_from_data(&icon->data[0], Gdk::COLORSPACE_RGB, + icon->format == Pixmap::Format::RGBA, 8, + icon->width, icon->height, icon->stride); + gtkWindow.set_icon(gdkIcon->copy()); + } + + double GetPixelDensity() override { + return gtkWindow.get_screen()->get_resolution(); + } + + int GetDevicePixelRatio() override { + return gtkWindow.get_scale_factor(); + } + + bool IsVisible() override { + return gtkWindow.is_visible(); + } + + void SetVisible(bool visible) override { + if(visible) { + gtkWindow.show(); + } else { + gtkWindow.hide(); + } + } + + void Focus() override { + gtkWindow.present(); + } + + bool IsFullScreen() override { + return gtkWindow.is_full_screen(); + } + + void SetFullScreen(bool fullScreen) override { + if(fullScreen) { + gtkWindow.fullscreen(); + } else { + gtkWindow.unfullscreen(); + } + } + + void SetTitle(const std::string &title) override { + gtkWindow.set_title(PrepareTitle(title)); + } + + void SetMenuBar(MenuBarRef newMenuBar) override { + if(newMenuBar) { + Gtk::MenuBar *gtkMenuBar = &((MenuBarImplGtk*)&*newMenuBar)->gtkMenuBar; + gtkWindow.set_menu_bar(gtkMenuBar); + } else { + gtkWindow.set_menu_bar(NULL); + } + menuBar = newMenuBar; + } + + void GetContentSize(double *width, double *height) override { + *width = gtkWindow.get_gl_widget().get_allocated_width(); + *height = gtkWindow.get_gl_widget().get_allocated_height(); + } + + void SetMinContentSize(double width, double height) override { + gtkWindow.get_gl_widget().set_size_request((int)width, (int)height); + } + + void FreezePosition(SettingsRef settings, const std::string &key) override { + if(!gtkWindow.is_visible()) return; + + int left, top, width, height; + gtkWindow.get_position(left, top); + gtkWindow.get_size(width, height); + bool isMaximized = gtkWindow.is_maximized(); + + settings->FreezeInt(key + "_Left", left); + settings->FreezeInt(key + "_Top", top); + settings->FreezeInt(key + "_Width", width); + settings->FreezeInt(key + "_Height", height); + settings->FreezeBool(key + "_Maximized", isMaximized); + } + + void ThawPosition(SettingsRef settings, const std::string &key) override { + int left, top, width, height; + gtkWindow.get_position(left, top); + gtkWindow.get_size(width, height); + + left = settings->ThawInt(key + "_Left", left); + top = settings->ThawInt(key + "_Top", top); + width = settings->ThawInt(key + "_Width", width); + height = settings->ThawInt(key + "_Height", height); + + gtkWindow.move(left, top); + gtkWindow.resize(width, height); + + if(settings->ThawBool(key + "_Maximized", false)) { + gtkWindow.maximize(); + } + } + + void SetCursor(Cursor cursor) override { + Gdk::CursorType gdkCursorType; + switch(cursor) { + case Cursor::POINTER: gdkCursorType = Gdk::ARROW; break; + case Cursor::HAND: gdkCursorType = Gdk::HAND1; break; + default: ssassert(false, "Unexpected cursor"); + } + + auto gdkWindow = gtkWindow.get_gl_widget().get_window(); + if(gdkWindow) { + gdkWindow->set_cursor(Gdk::Cursor::create(gdkCursorType)); + } + } + + void SetTooltip(const std::string &text, double x, double y, + double width, double height) override { + gtkWindow.set_tooltip(text, { (int)x, (int)y, (int)width, (int)height }); + } + + bool IsEditorVisible() override { + return gtkWindow.get_editor_overlay().is_editing(); + } + + void ShowEditor(double x, double y, double fontHeight, double minWidth, + bool isMonospace, const std::string &text) override { + gtkWindow.get_editor_overlay().start_editing( + (int)x, (int)y, (int)fontHeight, (int)minWidth, isMonospace, text); + } + + void HideEditor() override { + gtkWindow.get_editor_overlay().stop_editing(); + } + + void SetScrollbarVisible(bool visible) override { + if(visible) { + gtkWindow.get_scrollbar().show(); + } else { + gtkWindow.get_scrollbar().hide(); + } + } + + void ConfigureScrollbar(double min, double max, double pageSize) override { + auto adjustment = gtkWindow.get_scrollbar().get_adjustment(); + adjustment->configure(adjustment->get_value(), min, max, 1, 4, pageSize); + } + + double GetScrollbarPosition() override { + return gtkWindow.get_scrollbar().get_adjustment()->get_value(); + } + + void SetScrollbarPosition(double pos) override { + return gtkWindow.get_scrollbar().get_adjustment()->set_value(pos); + } + + void Invalidate() override { + gtkWindow.get_gl_widget().queue_render(); + } +}; + +WindowRef CreateWindow(Window::Kind kind, WindowRef parentWindow) { + auto window = std::make_shared(kind); + if(parentWindow) { + window->gtkWindow.set_transient_for( + std::static_pointer_cast(parentWindow)->gtkWindow); + } + return window; +} + +//----------------------------------------------------------------------------- +// 3DConnexion support +//----------------------------------------------------------------------------- + +void Open3DConnexion() {} +void Close3DConnexion() {} + +#if defined(HAVE_SPACEWARE) && defined(GDK_WINDOWING_X11) +static GdkFilterReturn GdkSpnavFilter(GdkXEvent *gdkXEvent, GdkEvent *gdkEvent, gpointer data) { + XEvent *xEvent = (XEvent *)gdkXEvent; + WindowImplGtk *window = (WindowImplGtk *)data; + + spnav_event spnavEvent; + if(!spnav_x11_event(xEvent, &spnavEvent)) { + return GDK_FILTER_CONTINUE; + } + + switch(spnavEvent.type) { + case SPNAV_EVENT_MOTION: { + SixDofEvent event = {}; + event.type = SixDofEvent::Type::MOTION; + event.translationX = (double)spnavEvent.motion.x; + event.translationY = (double)spnavEvent.motion.y; + event.translationZ = (double)spnavEvent.motion.z * -1.0; + event.rotationX = (double)spnavEvent.motion.rx * 0.001; + event.rotationY = (double)spnavEvent.motion.ry * 0.001; + event.rotationZ = (double)spnavEvent.motion.rz * -0.001; + event.shiftDown = xEvent->xmotion.state & ShiftMask; + event.controlDown = xEvent->xmotion.state & ControlMask; + if(window->onSixDofEvent) { + window->onSixDofEvent(event); + } + break; + } + + case SPNAV_EVENT_BUTTON: + SixDofEvent event = {}; + if(spnavEvent.button.press) { + event.type = SixDofEvent::Type::PRESS; + } else { + event.type = SixDofEvent::Type::RELEASE; + } + switch(spnavEvent.button.bnum) { + case 0: event.button = SixDofEvent::Button::FIT; break; + default: return GDK_FILTER_REMOVE; + } + event.shiftDown = xEvent->xmotion.state & ShiftMask; + event.controlDown = xEvent->xmotion.state & ControlMask; + if(window->onSixDofEvent) { + window->onSixDofEvent(event); + } + break; + } + + return GDK_FILTER_REMOVE; +} + +void Request3DConnexionEventsForWindow(WindowRef window) { + std::shared_ptr windowImpl = + std::static_pointer_cast(window); + + Glib::RefPtr gdkWindow = windowImpl->gtkWindow.get_window(); + if(GDK_IS_X11_DISPLAY(gdkWindow->get_display()->gobj())) { + gdkWindow->add_filter(GdkSpnavFilter, windowImpl.get()); + spnav_x11_open(gdk_x11_get_default_xdisplay(), + gdk_x11_window_get_xid(gdkWindow->gobj())); + } +} +#else +void Request3DConnexionEventsForWindow(WindowRef window) {} +#endif + +//----------------------------------------------------------------------------- +// Message dialogs +//----------------------------------------------------------------------------- + +class MessageDialogImplGtk; + +static std::vector> shownMessageDialogs; + +class MessageDialogImplGtk final : public MessageDialog, + public std::enable_shared_from_this { +public: + Gtk::Image gtkImage; + Gtk::MessageDialog gtkDialog; + + MessageDialogImplGtk(Gtk::Window &parent) + : gtkDialog(parent, "", /*use_markup=*/false, Gtk::MESSAGE_INFO, + Gtk::BUTTONS_NONE, /*modal=*/true) + { + SetTitle("Message"); + } + + void SetType(Type type) override { + switch(type) { + case Type::INFORMATION: + gtkImage.set_from_icon_name("dialog-information", Gtk::ICON_SIZE_DIALOG); + break; + + case Type::QUESTION: + gtkImage.set_from_icon_name("dialog-question", Gtk::ICON_SIZE_DIALOG); + break; + + case Type::WARNING: + gtkImage.set_from_icon_name("dialog-warning", Gtk::ICON_SIZE_DIALOG); + break; + + case Type::ERROR: + gtkImage.set_from_icon_name("dialog-error", Gtk::ICON_SIZE_DIALOG); + break; + } + gtkDialog.set_image(gtkImage); + } + + void SetTitle(std::string title) override { + gtkDialog.set_title(PrepareTitle(title)); + } + + void SetMessage(std::string message) override { + gtkDialog.set_message(message); + } + + void SetDescription(std::string description) override { + gtkDialog.set_secondary_text(description); + } + + void AddButton(std::string label, Response response, bool isDefault) override { + int responseId = 0; + switch(response) { + case Response::NONE: ssassert(false, "Unexpected response"); + case Response::OK: responseId = Gtk::RESPONSE_OK; break; + case Response::YES: responseId = Gtk::RESPONSE_YES; break; + case Response::NO: responseId = Gtk::RESPONSE_NO; break; + case Response::CANCEL: responseId = Gtk::RESPONSE_CANCEL; break; + } + gtkDialog.add_button(PrepareMnemonics(label), responseId); + if(isDefault) { + gtkDialog.set_default_response(responseId); + } + } + + Response ProcessResponse(int gtkResponse) { + Response response; + switch(gtkResponse) { + case Gtk::RESPONSE_OK: response = Response::OK; break; + case Gtk::RESPONSE_YES: response = Response::YES; break; + case Gtk::RESPONSE_NO: response = Response::NO; break; + case Gtk::RESPONSE_CANCEL: response = Response::CANCEL; break; + + case Gtk::RESPONSE_NONE: + case Gtk::RESPONSE_CLOSE: + case Gtk::RESPONSE_DELETE_EVENT: + response = Response::NONE; + break; + + default: ssassert(false, "Unexpected response"); + } + + if(onResponse) { + onResponse(response); + } + return response; + } + + void ShowModal() override { + gtkDialog.signal_hide().connect([this] { + auto it = std::remove(shownMessageDialogs.begin(), shownMessageDialogs.end(), + shared_from_this()); + shownMessageDialogs.erase(it); + }); + shownMessageDialogs.push_back(shared_from_this()); + + gtkDialog.signal_response().connect([this](int gtkResponse) { + ProcessResponse(gtkResponse); + gtkDialog.hide(); + }); + gtkDialog.show(); + } + + Response RunModal() override { + return ProcessResponse(gtkDialog.run()); + } +}; + +MessageDialogRef CreateMessageDialog(WindowRef parentWindow) { + return std::make_shared( + std::static_pointer_cast(parentWindow)->gtkWindow); +} + +//----------------------------------------------------------------------------- +// File dialogs +//----------------------------------------------------------------------------- + +class FileDialogImplGtk : public FileDialog { +public: + Gtk::FileChooser *gtkChooser; + std::vector extensions; + + void InitFileChooser(Gtk::FileChooser &chooser) { + gtkChooser = &chooser; + gtkChooser->property_filter().signal_changed(). + connect(sigc::mem_fun(this, &FileDialogImplGtk::FilterChanged)); + } + + void SetCurrentName(std::string name) override { + gtkChooser->set_current_name(name); + } + + Platform::Path GetFilename() override { + return Path::From(gtkChooser->get_filename()); + } + + void SetFilename(Platform::Path path) override { + gtkChooser->set_filename(path.raw); + } + + void SuggestFilename(Platform::Path path) override { + gtkChooser->set_current_name(path.FileStem()+"."+GetExtension()); + } + + void AddFilter(std::string name, std::vector extensions) override { + Glib::RefPtr gtkFilter = Gtk::FileFilter::create(); + Glib::ustring desc; + for(auto extension : extensions) { + Glib::ustring pattern = "*"; + if(!extension.empty()) { + pattern = "*." + extension; + gtkFilter->add_pattern(pattern); + gtkFilter->add_pattern(Glib::ustring(pattern).uppercase()); + } + if(!desc.empty()) { + desc += ", "; + } + desc += pattern; + } + gtkFilter->set_name(name + " (" + desc + ")"); + + this->extensions.push_back(extensions.front()); + gtkChooser->add_filter(gtkFilter); + } + + std::string GetExtension() { + auto filters = gtkChooser->list_filters(); + size_t filterIndex = + std::find(filters.begin(), filters.end(), gtkChooser->get_filter()) - + filters.begin(); + if(filterIndex < extensions.size()) { + return extensions[filterIndex]; + } else { + return extensions.front(); + } + } + + void SetExtension(std::string extension) { + auto filters = gtkChooser->list_filters(); + size_t extensionIndex = + std::find(extensions.begin(), extensions.end(), extension) - + extensions.begin(); + if(extensionIndex < filters.size()) { + gtkChooser->set_filter(filters[extensionIndex]); + } else { + gtkChooser->set_filter(filters.front()); + } + } + + void FilterChanged() { + std::string extension = GetExtension(); + if(extension.empty()) + return; + + Platform::Path path = GetFilename(); + SetCurrentName(path.WithExtension(extension).FileName()); + } + + void FreezeChoices(SettingsRef settings, const std::string &key) override { + settings->FreezeString("Dialog_" + key + "_Folder", + gtkChooser->get_current_folder()); + settings->FreezeString("Dialog_" + key + "_Filter", GetExtension()); + } + + void ThawChoices(SettingsRef settings, const std::string &key) override { + gtkChooser->set_current_folder(settings->ThawString("Dialog_" + key + "_Folder")); + SetExtension(settings->ThawString("Dialog_" + key + "_Filter")); + } + + void CheckForUntitledFile() { + if(gtkChooser->get_action() == Gtk::FILE_CHOOSER_ACTION_SAVE && + Path::From(gtkChooser->get_current_name()).FileStem().empty()) { + gtkChooser->set_current_name(std::string(_("untitled")) + "." + GetExtension()); + } + } +}; + +class FileDialogGtkImplGtk final : public FileDialogImplGtk { +public: + Gtk::FileChooserDialog gtkDialog; + + FileDialogGtkImplGtk(Gtk::Window >kParent, bool isSave) + : gtkDialog(gtkParent, + isSave ? C_("title", "Save File") + : C_("title", "Open File"), + isSave ? Gtk::FILE_CHOOSER_ACTION_SAVE + : Gtk::FILE_CHOOSER_ACTION_OPEN) { + gtkDialog.add_button(C_("button", "_Cancel"), Gtk::RESPONSE_CANCEL); + gtkDialog.add_button(isSave ? C_("button", "_Save") + : C_("button", "_Open"), Gtk::RESPONSE_OK); + gtkDialog.set_default_response(Gtk::RESPONSE_OK); + InitFileChooser(gtkDialog); + } + + void SetTitle(std::string title) override { + gtkDialog.set_title(PrepareTitle(title)); + } + + bool RunModal() override { + CheckForUntitledFile(); + if(gtkDialog.run() == Gtk::RESPONSE_OK) { + return true; + } else { + return false; + } + } +}; + +#if defined(HAVE_GTK_FILECHOOSERNATIVE) + +class FileDialogNativeImplGtk final : public FileDialogImplGtk { +public: + Glib::RefPtr gtkNative; + + FileDialogNativeImplGtk(Gtk::Window >kParent, bool isSave) { + gtkNative = Gtk::FileChooserNative::create( + isSave ? C_("title", "Save File") + : C_("title", "Open File"), + gtkParent, + isSave ? Gtk::FILE_CHOOSER_ACTION_SAVE + : Gtk::FILE_CHOOSER_ACTION_OPEN, + isSave ? C_("button", "_Save") + : C_("button", "_Open"), + C_("button", "_Cancel")); + // Seriously, GTK?! + InitFileChooser(*gtkNative.operator->()); + } + + void SetTitle(std::string title) override { + gtkNative->set_title(PrepareTitle(title)); + } + + bool RunModal() override { + CheckForUntitledFile(); + if(gtkNative->run() == Gtk::RESPONSE_ACCEPT) { + return true; + } else { + return false; + } + } +}; + +#endif + +#if defined(HAVE_GTK_FILECHOOSERNATIVE) +# define FILE_DIALOG_IMPL FileDialogNativeImplGtk +#else +# define FILE_DIALOG_IMPL FileDialogGtkImplGtk +#endif + +FileDialogRef CreateOpenFileDialog(WindowRef parentWindow) { + Gtk::Window >kParent = std::static_pointer_cast(parentWindow)->gtkWindow; + return std::make_shared(gtkParent, /*isSave=*/false); +} + +FileDialogRef CreateSaveFileDialog(WindowRef parentWindow) { + Gtk::Window >kParent = std::static_pointer_cast(parentWindow)->gtkWindow; + return std::make_shared(gtkParent, /*isSave=*/true); +} + +//----------------------------------------------------------------------------- +// Application-wide APIs +//----------------------------------------------------------------------------- + +std::vector GetFontFiles() { + std::vector fonts; + + // fontconfig is already initialized by GTK + FcPattern *pat = FcPatternCreate(); + FcObjectSet *os = FcObjectSetBuild(FC_FILE, (char *)0); + FcFontSet *fs = FcFontList(0, pat, os); + + for(int i = 0; i < fs->nfont; i++) { + FcChar8 *filenameFC = FcPatternFormat(fs->fonts[i], (const FcChar8*) "%{file}"); + fonts.push_back(Platform::Path::From((const char *)filenameFC)); + FcStrFree(filenameFC); + } + + FcFontSetDestroy(fs); + FcObjectSetDestroy(os); + FcPatternDestroy(pat); + + return fonts; +} + +void OpenInBrowser(const std::string &url) { + gtk_show_uri(Gdk::Screen::get_default()->gobj(), url.c_str(), GDK_CURRENT_TIME, NULL); +} + +Gtk::Main *gtkMain; + +std::vector InitGui(int argc, char **argv) { + // It would in principle be possible to judiciously use Glib::filename_{from,to}_utf8, + // but it's not really worth the effort. + // The setlocale() call is necessary for Glib::get_charset() to detect the system + // character set; otherwise it thinks it is always ANSI_X3.4-1968. + // We set it back to C after all so that printf() and friends behave in a consistent way. + setlocale(LC_ALL, ""); + if(!Glib::get_charset()) { + dbp("Sorry, only UTF-8 locales are supported."); + exit(1); + } + setlocale(LC_ALL, "C"); + + // Let GTK parse arguments and update argc/argv. (They're passed by reference.) + gtkMain = new Gtk::Main(argc, argv, /*set_locale=*/false); + + // Now that GTK arguments are removed, grab arguments for ourselves. + std::vector args = InitCli(argc, argv); + + // Add our application-specific styles, to override GTK defaults. + Glib::RefPtr style_provider = Gtk::CssProvider::create(); + style_provider->load_from_data(R"( + entry { + background: white; + color: black; + } + )"); + Gtk::StyleContext::add_provider_for_screen( + Gdk::Screen::get_default(), style_provider, + 600 /*Gtk::STYLE_PROVIDER_PRIORITY_APPLICATION*/); + + // Set locale from user preferences. + // This apparently only consults the LANGUAGE environment variable. + const char* const* langNames = g_get_language_names(); + while(*langNames) { + if(SetLocale(*langNames++)) break; + } + if(!*langNames) { + SetLocale("en_US"); + } + + return args; +} + +void RunGui() { + Gtk::Main::run(); +} + +void ExitGui() { + Gtk::Main::quit(); +} + +void ClearGui() { + delete gtkMain; +} + +} +} diff --git a/src/platform/guimac.mm b/src/platform/guimac.mm new file mode 100644 index 0000000..b2b07a8 --- /dev/null +++ b/src/platform/guimac.mm @@ -0,0 +1,1497 @@ +//----------------------------------------------------------------------------- +// The Cocoa-based implementation of platform-dependent GUI functionality. +// +// Copyright 2018 whitequark +//----------------------------------------------------------------------------- +#include "solvespace.h" +#import + +using namespace SolveSpace; + +//----------------------------------------------------------------------------- +// Internal AppKit classes +//----------------------------------------------------------------------------- + +@interface NSToolTipManager : NSObject ++ (NSToolTipManager *)sharedToolTipManager; +- (void)setInitialToolTipDelay:(double)delay; +- (void)orderOutToolTip; +- (void)abortToolTip; +- (void)_displayTemporaryToolTipForView:(id)arg1 withString:(id)arg2; +@end + +//----------------------------------------------------------------------------- +// Objective-C bridging +//----------------------------------------------------------------------------- + +static NSString* Wrap(const std::string &s) { + return [NSString stringWithUTF8String:s.c_str()]; +} + +@interface SSFunction : NSObject +- (SSFunction *)initWithFunction:(std::function *)aFunc; +- (void)run; +@end + +@implementation SSFunction +{ + std::function *func; +} + +- (SSFunction *)initWithFunction:(std::function *)aFunc { + if(self = [super init]) { + func = aFunc; + } + return self; +} + +- (void)run { + if(*func) (*func)(); +} +@end + +namespace SolveSpace { +namespace Platform { + +//----------------------------------------------------------------------------- +// Utility functions +//----------------------------------------------------------------------------- + +static std::string PrepareMnemonics(std::string label) { + // OS X does not support mnemonics + label.erase(std::remove(label.begin(), label.end(), '&'), label.end()); + return label; +} + +//----------------------------------------------------------------------------- +// Fatal errors +//----------------------------------------------------------------------------- + +// This gets put into the "Application Specific Information" field in crash +// reporter dialog. +typedef struct { + unsigned version __attribute__((aligned(8))); + const char *message __attribute__((aligned(8))); + const char *signature __attribute__((aligned(8))); + const char *backtrace __attribute__((aligned(8))); + const char *message2 __attribute__((aligned(8))); + void *reserved __attribute__((aligned(8))); + void *reserved2 __attribute__((aligned(8))); +} crash_info_t; + +#define CRASH_VERSION 4 + +crash_info_t crashAnnotation __attribute__((section("__DATA,__crash_info"))) = { + CRASH_VERSION, NULL, NULL, NULL, NULL, NULL, NULL +}; + +void FatalError(const std::string &message) { + crashAnnotation.message = message.c_str(); + abort(); +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +class SettingsImplCocoa final : public Settings { +public: + NSUserDefaults *userDefaults; + + SettingsImplCocoa() { + userDefaults = [NSUserDefaults standardUserDefaults]; + } + + void FreezeInt(const std::string &key, uint32_t value) override { + [userDefaults setInteger:value forKey:Wrap(key)]; + } + + uint32_t ThawInt(const std::string &key, uint32_t defaultValue = 0) override { + NSString *nsKey = Wrap(key); + if([userDefaults objectForKey:nsKey]) { + return [userDefaults integerForKey:nsKey]; + } + return defaultValue; + } + + void FreezeBool(const std::string &key, bool value) override { + [userDefaults setBool:value forKey:Wrap(key)]; + } + + bool ThawBool(const std::string &key, bool defaultValue = false) override { + NSString *nsKey = Wrap(key); + if([userDefaults objectForKey:nsKey]) { + return [userDefaults boolForKey:nsKey]; + } + return defaultValue; + } + + void FreezeFloat(const std::string &key, double value) override { + [userDefaults setDouble:value forKey:Wrap(key)]; + } + + double ThawFloat(const std::string &key, double defaultValue = 0.0) override { + NSString *nsKey = Wrap(key); + if([userDefaults objectForKey:nsKey]) { + return [userDefaults doubleForKey:nsKey]; + } + return defaultValue; + } + + void FreezeString(const std::string &key, const std::string &value) override { + [userDefaults setObject:Wrap(value) forKey:Wrap(key)]; + } + + std::string ThawString(const std::string &key, + const std::string &defaultValue = "") override { + NSObject *nsValue = [userDefaults objectForKey:Wrap(key)]; + if(nsValue && [nsValue isKindOfClass:[NSString class]]) { + return [(NSString *)nsValue UTF8String]; + } + return defaultValue; + } +}; + +SettingsRef GetSettings() { + return std::make_shared(); +} + +//----------------------------------------------------------------------------- +// Timers +//----------------------------------------------------------------------------- + +class TimerImplCocoa final : public Timer { +public: + NSTimer *timer; + + TimerImplCocoa() : timer(NULL) {} + + void RunAfter(unsigned milliseconds) override { + SSFunction *callback = [[SSFunction alloc] initWithFunction:&this->onTimeout]; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature: + [callback methodSignatureForSelector:@selector(run)]]; + invocation.target = callback; + invocation.selector = @selector(run); + + if(timer != NULL) { + [timer invalidate]; + } + timer = [NSTimer scheduledTimerWithTimeInterval:(milliseconds / 1000.0) + invocation:invocation repeats:NO]; + } + + ~TimerImplCocoa() { + if(timer != NULL) { + [timer invalidate]; + } + } +}; + +TimerRef CreateTimer() { + return std::make_shared(); +} + +//----------------------------------------------------------------------------- +// Menus +//----------------------------------------------------------------------------- + +class MenuItemImplCocoa final : public MenuItem { +public: + SSFunction *ssFunction; + NSMenuItem *nsMenuItem; + + MenuItemImplCocoa() { + ssFunction = [[SSFunction alloc] initWithFunction:&onTrigger]; + nsMenuItem = [[NSMenuItem alloc] initWithTitle:@"" + action:@selector(run) keyEquivalent:@""]; + nsMenuItem.target = ssFunction; + } + + void SetAccelerator(KeyboardEvent accel) override { + unichar accelChar; + switch(accel.key) { + case KeyboardEvent::Key::CHARACTER: + if(accel.chr == NSDeleteCharacter) { + accelChar = NSBackspaceCharacter; + } else { + accelChar = accel.chr; + } + break; + + case KeyboardEvent::Key::FUNCTION: + accelChar = NSF1FunctionKey + accel.num - 1; + break; + } + nsMenuItem.keyEquivalent = [[NSString alloc] initWithCharacters:&accelChar length:1]; + + NSUInteger modifierMask = 0; + if(accel.shiftDown) + modifierMask |= NSEventModifierFlagShift; + if(accel.controlDown) + modifierMask |= NSEventModifierFlagCommand; + nsMenuItem.keyEquivalentModifierMask = modifierMask; + } + + void SetIndicator(Indicator state) override { + // macOS does not support radio menu items + } + + void SetActive(bool active) override { + nsMenuItem.state = active ? NSControlStateValueOn : NSControlStateValueOff; + } + + void SetEnabled(bool enabled) override { + nsMenuItem.enabled = enabled; + } +}; + +class MenuImplCocoa final : public Menu { +public: + NSMenu *nsMenu; + + std::vector> menuItems; + std::vector> subMenus; + + MenuImplCocoa() { + nsMenu = [[NSMenu alloc] initWithTitle:@""]; + [nsMenu setAutoenablesItems:NO]; + } + + MenuItemRef AddItem(const std::string &label, + std::function onTrigger = NULL, + bool mnemonics = true) override { + auto menuItem = std::make_shared(); + menuItems.push_back(menuItem); + + menuItem->onTrigger = onTrigger; + [menuItem->nsMenuItem setTitle:Wrap(mnemonics ? PrepareMnemonics(label) : label)]; + [nsMenu addItem:menuItem->nsMenuItem]; + + return menuItem; + } + + MenuRef AddSubMenu(const std::string &label) override { + auto subMenu = std::make_shared(); + subMenus.push_back(subMenu); + + NSMenuItem *nsMenuItem = + [nsMenu addItemWithTitle:Wrap(PrepareMnemonics(label)) action:nil keyEquivalent:@""]; + [nsMenu setSubmenu:subMenu->nsMenu forItem:nsMenuItem]; + + return subMenu; + } + + void AddSeparator() override { + [nsMenu addItem:[NSMenuItem separatorItem]]; + } + + void PopUp() override { + [NSMenu popUpContextMenu:nsMenu withEvent:[NSApp currentEvent] forView:nil]; + } + + void Clear() override { + [nsMenu removeAllItems]; + menuItems.clear(); + subMenus.clear(); + } +}; + +MenuRef CreateMenu() { + return std::make_shared(); +} + +class MenuBarImplCocoa final : public MenuBar { +public: + NSMenu *nsMenuBar; + + std::vector> subMenus; + + MenuBarImplCocoa() { + nsMenuBar = [NSApp mainMenu]; + } + + MenuRef AddSubMenu(const std::string &label) override { + auto subMenu = std::make_shared(); + subMenus.push_back(subMenu); + + NSMenuItem *nsMenuItem = [nsMenuBar addItemWithTitle:@"" action:nil keyEquivalent:@""]; + [subMenu->nsMenu setTitle:Wrap(PrepareMnemonics(label))]; + [nsMenuBar setSubmenu:subMenu->nsMenu forItem:nsMenuItem]; + + return subMenu; + } + + void Clear() override { + while([nsMenuBar numberOfItems] != 1) { + [nsMenuBar removeItemAtIndex:1]; + } + subMenus.clear(); + } +}; + +MenuBarRef GetOrCreateMainMenu(bool *unique) { + static std::shared_ptr mainMenu; + if(!mainMenu) { + mainMenu = std::make_shared(); + } + *unique = true; + return mainMenu; +} + +} +} + +//----------------------------------------------------------------------------- +// Cocoa NSView and NSWindow extensions +//----------------------------------------------------------------------------- + +@interface SSView : NSOpenGLView +@property Platform::Window *receiver; + +@property BOOL acceptsFirstResponder; + +@property(readonly, getter=isEditing) BOOL editing; +- (void)startEditing:(NSString *)text at:(NSPoint)origin + withHeight:(double)fontHeight minWidth:(double)minWidth + usingMonospace:(BOOL)isMonospace; +- (void)stopEditing; +- (void)didEdit:(NSString *)text; + +@property double scrollerMin; +@property double scrollerMax; +@end + +@implementation SSView +{ + NSTrackingArea *trackingArea; + NSTextField *editor; +} + +@synthesize acceptsFirstResponder; + +- (id)initWithFrame:(NSRect)frameRect { + NSOpenGLPixelFormatAttribute attrs[] = { + NSOpenGLPFADoubleBuffer, + NSOpenGLPFAColorSize, 24, + NSOpenGLPFADepthSize, 24, + 0 + }; + NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; + if(self = [super initWithFrame:frameRect pixelFormat:pixelFormat]) { + self.wantsBestResolutionOpenGLSurface = YES; + self.wantsLayer = YES; + editor = [[NSTextField alloc] init]; + editor.editable = YES; + [[editor cell] setWraps:NO]; + [[editor cell] setScrollable:YES]; + editor.bezeled = NO; + editor.target = self; + editor.action = @selector(didEdit:); + } + return self; +} + +- (void)dealloc { +} + +- (BOOL)isFlipped { + return YES; +} + +@synthesize receiver; + +- (void)drawRect:(NSRect)aRect { + [[self openGLContext] makeCurrentContext]; + if(receiver->onRender) { + receiver->onRender(); + } + [[self openGLContext] flushBuffer]; +} + +- (BOOL)acceptsFirstMouse:(NSEvent *)event { + return YES; +} + +- (void)updateTrackingAreas { + [self removeTrackingArea:trackingArea]; + trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] + options:(NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved | + ([self acceptsFirstResponder] + ? NSTrackingActiveInKeyWindow + : NSTrackingActiveAlways)) + owner:self userInfo:nil]; + [self addTrackingArea:trackingArea]; + [super updateTrackingAreas]; +} + +- (Platform::MouseEvent)convertMouseEvent:(NSEvent *)nsEvent { + Platform::MouseEvent event = {}; + + NSPoint nsPoint = [self convertPoint:nsEvent.locationInWindow fromView:self]; + event.x = nsPoint.x; + event.y = self.bounds.size.height - nsPoint.y; + + NSUInteger nsFlags = [nsEvent modifierFlags]; + if(nsFlags & NSEventModifierFlagShift) event.shiftDown = true; + if(nsFlags & NSEventModifierFlagCommand) event.controlDown = true; + + return event; +} + +- (void)mouseMotionEvent:(NSEvent *)nsEvent { + using Platform::MouseEvent; + + MouseEvent event = [self convertMouseEvent:nsEvent]; + event.type = MouseEvent::Type::MOTION; + event.button = MouseEvent::Button::NONE; + + NSUInteger nsButtons = [NSEvent pressedMouseButtons]; + if(nsButtons & (1 << 0)) { + event.button = MouseEvent::Button::LEFT; + } else if(nsButtons & (1 << 1)) { + event.button = MouseEvent::Button::RIGHT; + } else if(nsButtons & (1 << 2)) { + event.button = MouseEvent::Button::MIDDLE; + } + + if(receiver->onMouseEvent) { + receiver->onMouseEvent(event); + } +} + +- (void)mouseMotionEvent:(NSEvent *)nsEvent withButton:(Platform::MouseEvent::Button)button { + using Platform::MouseEvent; + + MouseEvent event = [self convertMouseEvent:nsEvent]; + event.type = MouseEvent::Type::MOTION; + event.button = button; + + if(receiver->onMouseEvent) { + receiver->onMouseEvent(event); + } +} + +- (void)mouseMoved:(NSEvent *)nsEvent { + [self mouseMotionEvent:nsEvent]; + [super mouseMoved:nsEvent]; +} + +- (void)mouseDragged:(NSEvent *)nsEvent { + [self mouseMotionEvent:nsEvent withButton:Platform::MouseEvent::Button::LEFT]; +} + +- (void)otherMouseDragged:(NSEvent *)nsEvent { + [self mouseMotionEvent:nsEvent]; +} + +- (void)rightMouseDragged:(NSEvent *)nsEvent { + [self mouseMotionEvent:nsEvent]; +} + +- (void)mouseButtonEvent:(NSEvent *)nsEvent withType:(Platform::MouseEvent::Type)type { + using Platform::MouseEvent; + + MouseEvent event = [self convertMouseEvent:nsEvent]; + event.type = type; + if([nsEvent buttonNumber] == 0) { + event.button = MouseEvent::Button::LEFT; + } else if([nsEvent buttonNumber] == 1) { + event.button = MouseEvent::Button::RIGHT; + } else if([nsEvent buttonNumber] == 2) { + event.button = MouseEvent::Button::MIDDLE; + } else return; + + if(receiver->onMouseEvent) { + receiver->onMouseEvent(event); + } +} + +- (void)mouseDownEvent:(NSEvent *)nsEvent { + using Platform::MouseEvent; + + MouseEvent::Type type; + if([nsEvent clickCount] == 1) { + type = MouseEvent::Type::PRESS; + } else { + type = MouseEvent::Type::DBL_PRESS; + } + [self mouseButtonEvent:nsEvent withType:type]; +} + +- (void)mouseUpEvent:(NSEvent *)nsEvent { + using Platform::MouseEvent; + + [self mouseButtonEvent:nsEvent withType:(MouseEvent::Type::RELEASE)]; +} + +- (void)mouseDown:(NSEvent *)nsEvent { + [self mouseDownEvent:nsEvent]; +} + +- (void)otherMouseDown:(NSEvent *)nsEvent { + [self mouseDownEvent:nsEvent]; +} + +- (void)rightMouseDown:(NSEvent *)nsEvent { + [self mouseDownEvent:nsEvent]; + [super rightMouseDown:nsEvent]; +} + +- (void)mouseUp:(NSEvent *)nsEvent { + [self mouseUpEvent:nsEvent]; +} + +- (void)otherMouseUp:(NSEvent *)nsEvent { + [self mouseUpEvent:nsEvent]; +} + +- (void)rightMouseUp:(NSEvent *)nsEvent { + [self mouseUpEvent:nsEvent]; +} + +- (void)scrollWheel:(NSEvent *)nsEvent { + using Platform::MouseEvent; + + MouseEvent event = [self convertMouseEvent:nsEvent]; + event.type = MouseEvent::Type::SCROLL_VERT; + + bool isPrecise = [nsEvent hasPreciseScrollingDeltas]; + event.scrollDelta = [nsEvent scrollingDeltaY] / (isPrecise ? 50 : 5); + + if(receiver->onMouseEvent) { + receiver->onMouseEvent(event); + } +} + +- (void)mouseExited:(NSEvent *)nsEvent { + using Platform::MouseEvent; + + MouseEvent event = [self convertMouseEvent:nsEvent]; + event.type = MouseEvent::Type::LEAVE; + + if(receiver->onMouseEvent) { + receiver->onMouseEvent(event); + } +} + +- (Platform::KeyboardEvent)convertKeyboardEvent:(NSEvent *)nsEvent { + using Platform::KeyboardEvent; + + KeyboardEvent event = {}; + + NSUInteger nsFlags = [nsEvent modifierFlags]; + if(nsFlags & NSEventModifierFlagShift) + event.shiftDown = true; + if(nsFlags & NSEventModifierFlagCommand) + event.controlDown = true; + + unichar chr = 0; + if(NSString *nsChr = [[nsEvent charactersIgnoringModifiers] lowercaseString]) { + chr = [nsChr characterAtIndex:0]; + } + if(chr >= NSF1FunctionKey && chr <= NSF12FunctionKey) { + event.key = KeyboardEvent::Key::FUNCTION; + event.num = chr - NSF1FunctionKey + 1; + } else { + event.key = KeyboardEvent::Key::CHARACTER; + event.chr = chr; + } + + return event; +} + +- (void)keyDown:(NSEvent *)nsEvent { + using Platform::KeyboardEvent; + + if([NSEvent modifierFlags] & ~(NSEventModifierFlagShift|NSEventModifierFlagCommand)) { + [super keyDown:nsEvent]; + return; + } + + KeyboardEvent event = [self convertKeyboardEvent:nsEvent]; + event.type = KeyboardEvent::Type::PRESS; + + if(receiver->onKeyboardEvent) { + receiver->onKeyboardEvent(event); + return; + } + + [super keyDown:nsEvent]; +} + +- (void)keyUp:(NSEvent *)nsEvent { + using Platform::KeyboardEvent; + + if([NSEvent modifierFlags] & ~(NSEventModifierFlagShift|NSEventModifierFlagCommand)) { + [super keyUp:nsEvent]; + return; + } + + KeyboardEvent event = [self convertKeyboardEvent:nsEvent]; + event.type = KeyboardEvent::Type::RELEASE; + + if(receiver->onKeyboardEvent) { + receiver->onKeyboardEvent(event); + return; + } + + [super keyUp:nsEvent]; +} + +@synthesize editing; + +- (void)startEditing:(NSString *)text at:(NSPoint)origin withHeight:(double)fontHeight + minWidth:(double)minWidth usingMonospace:(BOOL)isMonospace { + if(!editing) { + [self addSubview:editor]; + editing = YES; + } + + if(isMonospace) { + editor.font = [NSFont fontWithName:@"Monaco" size:fontHeight]; + } else { + editor.font = [NSFont controlContentFontOfSize:fontHeight]; + } + + origin.x -= 3; /* left padding; no way to get it from NSTextField */ + origin.y -= [editor intrinsicContentSize].height; + origin.y += [editor baselineOffsetFromBottom]; + + [editor setFrameOrigin:origin]; + [editor setStringValue:text]; + [editor sizeToFit]; + + NSSize frameSize = [editor frame].size; + frameSize.width = std::max(frameSize.width, minWidth); + [editor setFrameSize:frameSize]; + + [[self window] makeFirstResponder:editor]; + [[self window] makeKeyWindow]; +} + +- (void)stopEditing { + if(editing) { + [editor removeFromSuperview]; + [[self window] makeFirstResponder:self]; + editing = NO; + } +} + +- (void)didEdit:(id)sender { + if(receiver->onEditingDone) { + receiver->onEditingDone([[editor stringValue] UTF8String]); + } +} + +- (void)cancelOperation:(id)sender { + using Platform::KeyboardEvent; + + if(receiver->onKeyboardEvent) { + KeyboardEvent event = {}; + event.key = KeyboardEvent::Key::CHARACTER; + event.chr = '\e'; + event.type = KeyboardEvent::Type::PRESS; + receiver->onKeyboardEvent(event); + event.type = KeyboardEvent::Type::RELEASE; + receiver->onKeyboardEvent(event); + } +} + +@synthesize scrollerMin; +@synthesize scrollerMax; + +- (void)didScroll:(NSScroller *)sender { + if(receiver->onScrollbarAdjusted) { + double pos = scrollerMin + [sender doubleValue] * (scrollerMax - scrollerMin); + receiver->onScrollbarAdjusted(pos); + } +} +@end + +@interface SSWindowDelegate : NSObject +@property Platform::Window *receiver; + +- (BOOL)windowShouldClose:(id)sender; + +@property(readonly, getter=isFullScreen) BOOL fullScreen; +- (void)windowDidEnterFullScreen:(NSNotification *)notification; +- (void)windowDidExitFullScreen:(NSNotification *)notification; +@end + +@implementation SSWindowDelegate +@synthesize receiver; + +- (BOOL)windowShouldClose:(id)sender { + if(receiver->onClose) { + receiver->onClose(); + } + return NO; +} + +@synthesize fullScreen; + +- (void)windowDidEnterFullScreen:(NSNotification *)notification { + fullScreen = true; + if(receiver->onFullScreen) { + receiver->onFullScreen(fullScreen); + } +} + +- (void)windowDidExitFullScreen:(NSNotification *)notification { + fullScreen = false; + if(receiver->onFullScreen) { + receiver->onFullScreen(fullScreen); + } +} +@end + +namespace SolveSpace { +namespace Platform { + +//----------------------------------------------------------------------------- +// Windows +//----------------------------------------------------------------------------- + +class WindowImplCocoa final : public Window { +public: + NSWindow *nsWindow; + SSWindowDelegate *ssWindowDelegate; + SSView *ssView; + NSScroller *nsScroller; + NSView *nsContainer; + + NSArray *nsConstraintsWithScrollbar; + NSArray *nsConstraintsWithoutScrollbar; + + double minWidth = 100.0; + double minHeight = 100.0; + + NSString *nsToolTip; + + WindowImplCocoa(Window::Kind kind, std::shared_ptr parentWindow) { + ssView = [[SSView alloc] init]; + ssView.translatesAutoresizingMaskIntoConstraints = NO; + ssView.receiver = this; + + nsScroller = [[NSScroller alloc] initWithFrame:NSMakeRect(0, 0, 0, 100)]; + nsScroller.translatesAutoresizingMaskIntoConstraints = NO; + nsScroller.enabled = YES; + nsScroller.scrollerStyle = NSScrollerStyleOverlay; + nsScroller.knobStyle = NSScrollerKnobStyleLight; + nsScroller.action = @selector(didScroll:); + nsScroller.target = ssView; + nsScroller.continuous = YES; + + nsContainer = [[NSView alloc] init]; + [nsContainer addSubview:ssView]; + [nsContainer addSubview:nsScroller]; + + NSDictionary *views = NSDictionaryOfVariableBindings(ssView, nsScroller); + nsConstraintsWithoutScrollbar = [NSLayoutConstraint + constraintsWithVisualFormat:@"H:|[ssView]|" + options:0 metrics:nil views:views]; + [nsContainer addConstraints:nsConstraintsWithoutScrollbar]; + nsConstraintsWithScrollbar = [NSLayoutConstraint + constraintsWithVisualFormat:@"H:|[ssView]-0-[nsScroller(11)]|" + options:0 metrics:nil views:views]; + [nsContainer addConstraints:[NSLayoutConstraint + constraintsWithVisualFormat:@"V:|[ssView]|" + options:0 metrics:nil views:views]]; + [nsContainer addConstraints:[NSLayoutConstraint + constraintsWithVisualFormat:@"V:|[nsScroller]|" + options:0 metrics:nil views:views]]; + + switch(kind) { + case Window::Kind::TOPLEVEL: + nsWindow = [[NSWindow alloc] init]; + nsWindow.styleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | + NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable; + nsWindow.collectionBehavior = NSWindowCollectionBehaviorFullScreenPrimary; + ssView.acceptsFirstResponder = YES; + break; + + case Window::Kind::TOOL: + NSPanel *nsPanel = [[NSPanel alloc] init]; + nsPanel.styleMask = NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | + NSWindowStyleMaskClosable | NSWindowStyleMaskUtilityWindow; + [nsPanel standardWindowButton:NSWindowMiniaturizeButton].hidden = YES; + [nsPanel standardWindowButton:NSWindowZoomButton].hidden = YES; + nsPanel.floatingPanel = YES; + nsPanel.becomesKeyOnlyIfNeeded = YES; + nsWindow = nsPanel; + break; + } + + ssWindowDelegate = [[SSWindowDelegate alloc] init]; + ssWindowDelegate.receiver = this; + nsWindow.delegate = ssWindowDelegate; + + nsWindow.backgroundColor = [NSColor blackColor]; + nsWindow.contentView = nsContainer; + } + + double GetPixelDensity() override { + NSDictionary *description = nsWindow.screen.deviceDescription; + NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue]; + CGSize displayPhysicalSize = CGDisplayScreenSize( + [[description objectForKey:@"NSScreenNumber"] unsignedIntValue]); + return (displayPixelSize.width / displayPhysicalSize.width) * 25.4f; + } + + int GetDevicePixelRatio() override { + NSSize unitSize = { 1.0f, 0.0f }; + unitSize = [ssView convertSizeToBacking:unitSize]; + return (int)unitSize.width; + } + + bool IsVisible() override { + return ![nsWindow isVisible]; + } + + void SetVisible(bool visible) override { + if(visible) { + [nsWindow orderFront:nil]; + } else { + [nsWindow close]; + } + } + + void Focus() override { + [nsWindow makeKeyAndOrderFront:nil]; + } + + bool IsFullScreen() override { + return ssWindowDelegate.fullScreen; + } + + void SetFullScreen(bool fullScreen) override { + if(fullScreen != IsFullScreen()) { + [nsWindow toggleFullScreen:nil]; + } + } + + void SetTitle(const std::string &title) override { + nsWindow.representedFilename = @""; + nsWindow.title = Wrap(title); + } + + bool SetTitleForFilename(const Path &filename) override { + [nsWindow setTitleWithRepresentedFilename:Wrap(filename.raw)]; + return true; + } + + void SetMenuBar(MenuBarRef newMenuBar) override { + // Doesn't do anything, since we have an unique global menu bar. + } + + void GetContentSize(double *width, double *height) override { + NSSize nsSize = ssView.frame.size; + *width = nsSize.width; + *height = nsSize.height; + } + + void SetMinContentSize(double width, double height) override { + NSSize nsMinSize; + nsMinSize.width = width; + nsMinSize.height = height; + [nsWindow setContentMinSize:nsMinSize]; + [nsWindow setContentSize:nsMinSize]; + } + + void FreezePosition(SettingsRef _settings, const std::string &key) override { + [nsWindow saveFrameUsingName:Wrap(key)]; + } + + void ThawPosition(SettingsRef _settings, const std::string &key) override { + [nsWindow setFrameUsingName:Wrap(key)]; + } + + void SetCursor(Cursor cursor) override { + NSCursor *nsNewCursor; + switch(cursor) { + case Cursor::POINTER: nsNewCursor = [NSCursor arrowCursor]; break; + case Cursor::HAND: nsNewCursor = [NSCursor pointingHandCursor]; break; + } + + if([NSCursor currentCursor] != nsNewCursor) { + [nsNewCursor set]; + } + } + + void SetTooltip(const std::string &newText, double x, double y, double w, double h) override { + NSString *nsNewText = Wrap(newText); + if(![nsToolTip isEqualToString:nsNewText]) { + nsToolTip = nsNewText; + + NSToolTipManager *nsToolTipManager = [NSToolTipManager sharedToolTipManager]; + if(newText.empty()) { + if ([nsToolTipManager respondsToSelector:@selector(abortToolTip)]) { + [nsToolTipManager abortToolTip]; + } else { + [nsToolTipManager orderOutToolTip]; + } + } else { + [nsToolTipManager _displayTemporaryToolTipForView:ssView withString:Wrap(newText)]; + } + } + } + + bool IsEditorVisible() override { + return [ssView isEditing]; + } + + void ShowEditor(double x, double y, double fontHeight, double minWidth, + bool isMonospace, const std::string &text) override { + [ssView startEditing:Wrap(text) at:(NSPoint){(CGFloat)x, (CGFloat)y} + withHeight:fontHeight minWidth:minWidth usingMonospace:isMonospace]; + } + + void HideEditor() override { + [ssView stopEditing]; + } + + void SetScrollbarVisible(bool visible) override { + if(visible) { + [nsContainer removeConstraints:nsConstraintsWithoutScrollbar]; + [nsContainer addConstraints:nsConstraintsWithScrollbar]; + } else { + [nsContainer removeConstraints:nsConstraintsWithScrollbar]; + [nsContainer addConstraints:nsConstraintsWithoutScrollbar]; + } + } + + void ConfigureScrollbar(double min, double max, double pageSize) override { + ssView.scrollerMin = min; + ssView.scrollerMax = max - pageSize; + [nsScroller setKnobProportion:(pageSize / (ssView.scrollerMax - ssView.scrollerMin))]; + } + + double GetScrollbarPosition() override { + return ssView.scrollerMin + + [nsScroller doubleValue] * (ssView.scrollerMax - ssView.scrollerMin); + } + + void SetScrollbarPosition(double pos) override { + if(pos > ssView.scrollerMax) + pos = ssView.scrollerMax; + if(GetScrollbarPosition() == pos) + return; + [nsScroller setDoubleValue:(pos / (ssView.scrollerMax - ssView.scrollerMin))]; + } + + void Invalidate() override { + ssView.needsDisplay = YES; + } +}; + +WindowRef CreateWindow(Window::Kind kind, WindowRef parentWindow) { + return std::make_shared(kind, + std::static_pointer_cast(parentWindow)); +} + +//----------------------------------------------------------------------------- +// 3DConnexion support +//----------------------------------------------------------------------------- + +// Normally we would just link to the 3DconnexionClient framework. +// +// We don't want to (are not allowed to) distribute the official framework, so we're trying +// to use the one installed on the users' computer. There are some different versions of +// the framework, the official one and re-implementations using an open source driver for +// older devices (spacenav-plus). So weak-linking isn't an option, either. The only remaining +// way is using CFBundle to dynamically load the library at runtime, and also detect its +// availability. +// +// We're also defining everything needed from the 3DconnexionClientAPI, so we're not depending +// on the API headers. + +#pragma pack(push,2) + +enum { + kConnexionClientModeTakeOver = 1, + kConnexionClientModePlugin = 2 +}; + +#define kConnexionMsgDeviceState '3dSR' +#define kConnexionMaskButtons 0x00FF +#define kConnexionMaskAxis 0x3F00 + +typedef struct { + uint16_t version; + uint16_t client; + uint16_t command; + int16_t param; + int32_t value; + UInt64 time; + uint8_t report[8]; + uint16_t buttons8; + int16_t axis[6]; + uint16_t address; + uint32_t buttons; +} ConnexionDeviceState, *ConnexionDeviceStatePtr; + +#pragma pack(pop) + +typedef void (*ConnexionAddedHandlerProc)(io_connect_t); +typedef void (*ConnexionRemovedHandlerProc)(io_connect_t); +typedef void (*ConnexionMessageHandlerProc)(io_connect_t, natural_t, void *); + +typedef OSErr (*InstallConnexionHandlersProc)(ConnexionMessageHandlerProc, ConnexionAddedHandlerProc, ConnexionRemovedHandlerProc); +typedef void (*CleanupConnexionHandlersProc)(void); +typedef UInt16 (*RegisterConnexionClientProc)(UInt32, UInt8 *, UInt16, UInt32); +typedef void (*UnregisterConnexionClientProc)(UInt16); + +static CFBundleRef spaceBundle = nil; +static InstallConnexionHandlersProc installConnexionHandlers = NULL; +static CleanupConnexionHandlersProc cleanupConnexionHandlers = NULL; +static RegisterConnexionClientProc registerConnexionClient = NULL; +static UnregisterConnexionClientProc unregisterConnexionClient = NULL; +static UInt32 connexionSignature = 'SoSp'; +static UInt8 *connexionName = (UInt8 *)"\x10SolveSpace"; +static UInt16 connexionClient = 0; + +static std::vector> connexionWindows; +static bool connexionShiftIsDown = false; +static bool connexionCommandIsDown = false; + +static void ConnexionAdded(io_connect_t con) {} +static void ConnexionRemoved(io_connect_t con) {} +static void ConnexionMessage(io_connect_t con, natural_t type, void *arg) { + if (type != kConnexionMsgDeviceState) { + return; + } + + ConnexionDeviceState *device = (ConnexionDeviceState *)arg; + + dispatch_async(dispatch_get_main_queue(), ^(void){ + SixDofEvent event = {}; + event.type = SixDofEvent::Type::MOTION; + event.translationX = (double)device->axis[0] * -0.25; + event.translationY = (double)device->axis[1] * -0.25; + event.translationZ = (double)device->axis[2] * 0.25; + event.rotationX = (double)device->axis[3] * -0.0005; + event.rotationY = (double)device->axis[4] * -0.0005; + event.rotationZ = (double)device->axis[5] * -0.0005; + event.shiftDown = connexionShiftIsDown; + event.controlDown = connexionCommandIsDown; + + for(auto window : connexionWindows) { + if(auto windowStrong = window.lock()) { + if(windowStrong->onSixDofEvent) { + windowStrong->onSixDofEvent(event); + } + } + } + }); +} + +void Open3DConnexion() { + NSString *bundlePath = @"/Library/Frameworks/3DconnexionClient.framework"; + NSURL *bundleURL = [NSURL fileURLWithPath:bundlePath]; + spaceBundle = CFBundleCreate(kCFAllocatorDefault, (__bridge CFURLRef)bundleURL); + + // Don't continue if no driver is installed on this machine + if(spaceBundle == nil) { + return; + } + + installConnexionHandlers = (InstallConnexionHandlersProc) + CFBundleGetFunctionPointerForName(spaceBundle, + CFSTR("InstallConnexionHandlers")); + + cleanupConnexionHandlers = (CleanupConnexionHandlersProc) + CFBundleGetFunctionPointerForName(spaceBundle, + CFSTR("CleanupConnexionHandlers")); + + registerConnexionClient = (RegisterConnexionClientProc) + CFBundleGetFunctionPointerForName(spaceBundle, + CFSTR("RegisterConnexionClient")); + + unregisterConnexionClient = (UnregisterConnexionClientProc) + CFBundleGetFunctionPointerForName(spaceBundle, + CFSTR("UnregisterConnexionClient")); + + // Only continue if all required symbols have been loaded + if((installConnexionHandlers == NULL) || (cleanupConnexionHandlers == NULL) + || (registerConnexionClient == NULL) || (unregisterConnexionClient == NULL)) { + CFRelease(spaceBundle); + spaceBundle = nil; + return; + } + + installConnexionHandlers(&ConnexionMessage, &ConnexionAdded, &ConnexionRemoved); + connexionClient = registerConnexionClient(connexionSignature, connexionName, + kConnexionClientModeTakeOver, kConnexionMaskButtons | kConnexionMaskAxis); + + [NSEvent addLocalMonitorForEventsMatchingMask:(NSEventMaskKeyDown | NSEventMaskFlagsChanged) + handler:^(NSEvent *event) { + connexionShiftIsDown = (event.modifierFlags & NSEventModifierFlagShift); + connexionCommandIsDown = (event.modifierFlags & NSEventModifierFlagCommand); + return event; + }]; + + [NSEvent addLocalMonitorForEventsMatchingMask:(NSEventMaskKeyUp | NSEventMaskFlagsChanged) + handler:^(NSEvent *event) { + connexionShiftIsDown = (event.modifierFlags & NSEventModifierFlagShift); + connexionCommandIsDown = (event.modifierFlags & NSEventModifierFlagCommand); + return event; + }]; +} + +void Close3DConnexion() { + if(spaceBundle == nil) { + return; + } + + unregisterConnexionClient(connexionClient); + cleanupConnexionHandlers(); + + CFRelease(spaceBundle); +} + +void Request3DConnexionEventsForWindow(WindowRef window) { + connexionWindows.push_back(window); +} + +//----------------------------------------------------------------------------- +// Message dialogs +//----------------------------------------------------------------------------- + +class MessageDialogImplCocoa final : public MessageDialog { +public: + NSAlert *nsAlert = [[NSAlert alloc] init]; + NSWindow *nsWindow; + + std::vector responses; + + void SetType(Type type) override { + switch(type) { + case Type::INFORMATION: + case Type::QUESTION: + nsAlert.alertStyle = NSAlertStyleInformational; + break; + + case Type::WARNING: + case Type::ERROR: + nsAlert.alertStyle = NSAlertStyleWarning; + break; + } + } + + void SetTitle(std::string title) override { + [nsAlert.window setTitle:Wrap(title)]; + } + + void SetMessage(std::string message) override { + nsAlert.messageText = Wrap(message); + } + + void SetDescription(std::string description) override { + nsAlert.informativeText = Wrap(description); + } + + void AddButton(std::string label, Response response, bool isDefault) override { + NSButton *nsButton = [nsAlert addButtonWithTitle:Wrap(PrepareMnemonics(label))]; + if(!isDefault && [nsButton.keyEquivalent isEqualToString:@"\n"]) { + nsButton.keyEquivalent = @""; + } else if(response == Response::CANCEL) { + nsButton.keyEquivalent = @"\e"; + } + responses.push_back(response); + } + + Response RunModal() override { + // FIXME(platform/gui): figure out a way to run the alert as a sheet + NSModalResponse nsResponse = [nsAlert runModal]; + ssassert(nsResponse >= NSAlertFirstButtonReturn && + nsResponse <= NSAlertFirstButtonReturn + (long)responses.size(), + "Unexpected response"); + return responses[nsResponse - NSAlertFirstButtonReturn]; + } +}; + +MessageDialogRef CreateMessageDialog(WindowRef parentWindow) { + std::shared_ptr dialog = std::make_shared(); + dialog->nsWindow = std::static_pointer_cast(parentWindow)->nsWindow; + return dialog; +} + +//----------------------------------------------------------------------------- +// File dialogs +//----------------------------------------------------------------------------- + +} +} + +@interface SSSaveFormatAccessory : NSViewController +@property NSSavePanel *panel; +@property NSMutableArray *filters; + +@property(nonatomic) NSInteger index; +@property(nonatomic) IBOutlet NSTextField *textField; +@property(nonatomic) IBOutlet NSPopUpButton *button; +@end + +@implementation SSSaveFormatAccessory +@synthesize panel, filters, button; + +- (void)setIndex:(NSInteger)newIndex { + self->_index = newIndex; + NSMutableArray *filter = [filters objectAtIndex:newIndex]; + NSString *extension = [filter objectAtIndex:0]; + if(![extension isEqual:@"*"]) { + NSString *filename = panel.nameFieldStringValue; + NSString *basename = [[filename componentsSeparatedByString:@"."] objectAtIndex:0]; + panel.nameFieldStringValue = [basename stringByAppendingPathExtension:extension]; + } + [panel setAllowedFileTypes:filter]; +} +@end + +namespace SolveSpace { +namespace Platform { + +class FileDialogImplCocoa : public FileDialog { +public: + NSSavePanel *nsPanel = nil; + + void SetTitle(std::string title) override { + nsPanel.title = Wrap(title); + } + + void SetCurrentName(std::string name) override { + nsPanel.nameFieldStringValue = Wrap(name); + } + + Platform::Path GetFilename() override { + return Platform::Path::From(nsPanel.URL.fileSystemRepresentation); + } + + void SetFilename(Platform::Path path) override { + nsPanel.directoryURL = + [NSURL fileURLWithPath:Wrap(path.Parent().raw) isDirectory:YES]; + nsPanel.nameFieldStringValue = Wrap(path.FileStem()); + } + + void SuggestFilename(Platform::Path path) override { + SetFilename(path.WithExtension("")); + } + + void FreezeChoices(SettingsRef settings, const std::string &key) override { + settings->FreezeString("Dialog_" + key + "_Folder", + [nsPanel.directoryURL.absoluteString UTF8String]); + } + + void ThawChoices(SettingsRef settings, const std::string &key) override { + nsPanel.directoryURL = + [NSURL URLWithString:Wrap(settings->ThawString("Dialog_" + key + "_Folder", ""))]; + } + + bool RunModal() override { + if([nsPanel runModal] == NSModalResponseOK) { + return true; + } else { + return false; + } + } +}; + +class OpenFileDialogImplCocoa final : public FileDialogImplCocoa { +public: + NSMutableArray *nsFilter = [[NSMutableArray alloc] init]; + + OpenFileDialogImplCocoa() { + SetTitle(C_("title", "Open File")); + } + + void AddFilter(std::string name, std::vector extensions) override { + for(auto extension : extensions) { + [nsFilter addObject:Wrap(extension)]; + } + [nsPanel setAllowedFileTypes:nsFilter]; + } +}; + +class SaveFileDialogImplCocoa final : public FileDialogImplCocoa { +public: + NSMutableArray *nsFilters = [[NSMutableArray alloc] init]; + SSSaveFormatAccessory *ssAccessory = nil; + + SaveFileDialogImplCocoa() { + SetTitle(C_("title", "Save File")); + } + + void AddFilter(std::string name, std::vector extensions) override { + NSMutableArray *nsFilter = [[NSMutableArray alloc] init]; + for(auto extension : extensions) { + [nsFilter addObject:Wrap(extension)]; + } + if(nsFilters.count == 0) { + [nsPanel setAllowedFileTypes:nsFilter]; + } + [nsFilters addObject:nsFilter]; + + std::string desc; + for(auto extension : extensions) { + if(!desc.empty()) desc += ", "; + desc += extension; + } + std::string title = name + " (" + desc + ")"; + if(nsFilters.count == 1) { + [ssAccessory.button removeAllItems]; + } + [ssAccessory.button addItemWithTitle:Wrap(title)]; + [ssAccessory.button synchronizeTitleAndSelectedItem]; + } + + void FreezeChoices(SettingsRef settings, const std::string &key) override { + FileDialogImplCocoa::FreezeChoices(settings, key); + settings->FreezeInt("Dialog_" + key + "_Filter", ssAccessory.index); + } + + void ThawChoices(SettingsRef settings, const std::string &key) override { + FileDialogImplCocoa::ThawChoices(settings, key); + ssAccessory.index = settings->ThawInt("Dialog_" + key + "_Filter", 0); + } + + bool RunModal() override { + if(nsFilters.count == 1) { + nsPanel.accessoryView = nil; + } + + if(nsPanel.nameFieldStringValue.length == 0) { + nsPanel.nameFieldStringValue = Wrap(_("untitled")); + } + + return FileDialogImplCocoa::RunModal(); + } +}; + +FileDialogRef CreateOpenFileDialog(WindowRef parentWindow) { + NSOpenPanel *nsPanel = [NSOpenPanel openPanel]; + nsPanel.canSelectHiddenExtension = YES; + + std::shared_ptr dialog = std::make_shared(); + dialog->nsPanel = nsPanel; + + return dialog; +} + +FileDialogRef CreateSaveFileDialog(WindowRef parentWindow) { + NSSavePanel *nsPanel = [NSSavePanel savePanel]; + nsPanel.canSelectHiddenExtension = YES; + + SSSaveFormatAccessory *ssAccessory = + [[SSSaveFormatAccessory alloc] initWithNibName:@"SaveFormatAccessory" bundle:nil]; + ssAccessory.panel = nsPanel; + nsPanel.accessoryView = [ssAccessory view]; + + std::shared_ptr dialog = std::make_shared(); + dialog->nsPanel = nsPanel; + dialog->ssAccessory = ssAccessory; + ssAccessory.filters = dialog->nsFilters; + + return dialog; +} + +//----------------------------------------------------------------------------- +// Application-wide APIs +//----------------------------------------------------------------------------- + +std::vector GetFontFiles() { + std::vector fonts; + + NSArray *fontNames = [[NSFontManager sharedFontManager] availableFonts]; + for(NSString *fontName in fontNames) { + CTFontDescriptorRef fontRef = + CTFontDescriptorCreateWithNameAndSize ((__bridge CFStringRef)fontName, 10.0); + CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(fontRef, kCTFontURLAttribute); + NSString *fontPath = [NSString stringWithString:[(NSURL *)CFBridgingRelease(url) path]]; + fonts.push_back( + Platform::Path::From([[NSFileManager defaultManager] + fileSystemRepresentationWithPath:fontPath])); + } + + return fonts; +} + +void OpenInBrowser(const std::string &url) { + [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:Wrap(url)]]; +} + +} +} + +@interface SSApplicationDelegate : NSObject +- (IBAction)preferences:(id)sender; +- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename; +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender; +@end + +@implementation SSApplicationDelegate +- (IBAction)preferences:(id)sender { + if (!SS.GW.showTextWindow) { + SolveSpace::SS.GW.MenuView(SolveSpace::Command::SHOW_TEXT_WND); + } + SolveSpace::SS.TW.GoToScreen(SolveSpace::TextWindow::Screen::CONFIGURATION); + SolveSpace::SS.ScheduleShowTW(); +} + +- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename { + SolveSpace::Platform::Path path = SolveSpace::Platform::Path::From([filename UTF8String]); + return SolveSpace::SS.Load(path.Expand(/*fromCurrentDirectory=*/true)); +} + +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { + [[[NSApp mainWindow] delegate] windowShouldClose:[NSApp mainWindow]]; + return NSTerminateCancel; +} + +- (void)applicationTerminatePrompt { + SolveSpace::SS.MenuFile(SolveSpace::Command::EXIT); +} +@end + +namespace SolveSpace { +namespace Platform { + +static SSApplicationDelegate *ssDelegate; + +std::vector InitGui(int argc, char **argv) { + std::vector args = InitCli(argc, argv); + if(args.size() >= 2 && args[1].find("-psn_") == 0) { + // For unknown reasons, Finder passes a Carbon PSN (Process Serial Number) argument + // when a freshly downloaded application is run for the first time. Remove it so + // that it isn't interpreted as a filename. + args.erase(args.begin() + 1); + } + + ssDelegate = [[SSApplicationDelegate alloc] init]; + NSApplication.sharedApplication.delegate = ssDelegate; + + [NSBundle.mainBundle loadNibNamed:@"MainMenu" owner:nil topLevelObjects:nil]; + + NSArray *languages = NSLocale.preferredLanguages; + for(NSString *language in languages) { + if(SolveSpace::SetLocale([language UTF8String])) break; + } + if(languages.count == 0) { + SolveSpace::SetLocale("en_US"); + } + + return args; +} + +void RunGui() { + [NSApp run]; +} + +void ExitGui() { + [NSApp setDelegate:nil]; + [NSApp terminate:nil]; +} + +void ClearGui() {} + +} +} diff --git a/src/platform/guinone.cpp b/src/platform/guinone.cpp new file mode 100644 index 0000000..4641b98 --- /dev/null +++ b/src/platform/guinone.cpp @@ -0,0 +1,145 @@ +//----------------------------------------------------------------------------- +// Our platform support functions for the headless (no OpenGL) test runner. +// +// Copyright 2016 whitequark +//----------------------------------------------------------------------------- +#include "solvespace.h" +#include + +namespace SolveSpace { + +//----------------------------------------------------------------------------- +// Rendering +//----------------------------------------------------------------------------- + +std::shared_ptr CreateRenderer() { + return std::make_shared(); +} + +namespace Platform { + +//----------------------------------------------------------------------------- +// Fatal errors +//----------------------------------------------------------------------------- + +void FatalError(const std::string &message) { + fprintf(stderr, "%s", message.c_str()); + abort(); +} + +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +class SettingsImplDummy final : public Settings { +public: + void FreezeInt(const std::string &key, uint32_t value) override { + } + + uint32_t ThawInt(const std::string &key, uint32_t defaultValue = 0) override { + return defaultValue; + } + + void FreezeFloat(const std::string &key, double value) override { + } + + double ThawFloat(const std::string &key, double defaultValue = 0.0) override { + return defaultValue; + } + + void FreezeString(const std::string &key, const std::string &value) override { + } + + std::string ThawString(const std::string &key, const std::string &defaultValue = "") override { + return defaultValue; + } +}; + +SettingsRef GetSettings() { + static std::shared_ptr settings = + std::make_shared(); + return settings; +} + +//----------------------------------------------------------------------------- +// Timers +//----------------------------------------------------------------------------- + +class TimerImplDummy final : public Timer { +public: + void RunAfter(unsigned milliseconds) override {} +}; + +TimerRef CreateTimer() { + return std::make_shared(); +} + +//----------------------------------------------------------------------------- +// Menus +//----------------------------------------------------------------------------- + +MenuRef CreateMenu() { + return std::shared_ptr(); +} + +MenuBarRef GetOrCreateMainMenu(bool *unique) { + *unique = false; + return std::shared_ptr(); +} + +//----------------------------------------------------------------------------- +// Windows +//----------------------------------------------------------------------------- + +WindowRef CreateWindow(Window::Kind kind, WindowRef parentWindow) { + return std::shared_ptr(); +} + +void Request3DConnexionEventsForWindow(WindowRef window) {} + +//----------------------------------------------------------------------------- +// Message dialogs +//----------------------------------------------------------------------------- + +MessageDialogRef CreateMessageDialog(WindowRef parentWindow) { + return std::shared_ptr(); +} + +//----------------------------------------------------------------------------- +// File dialogs +//----------------------------------------------------------------------------- + +FileDialogRef CreateOpenFileDialog(WindowRef parentWindow) { + return std::shared_ptr(); +} + +FileDialogRef CreateSaveFileDialog(WindowRef parentWindow) { + return std::shared_ptr(); +} + +//----------------------------------------------------------------------------- +// Application-wide APIs +//----------------------------------------------------------------------------- + +std::vector fontFiles; +std::vector GetFontFiles() { + return fontFiles; +} + +void OpenInBrowser(const std::string &url) {} + +std::vector InitGui(int argc, char **argv) { + return {}; +} + +void RunGui() {} + +void ExitGui() { + exit(0); +} + +void ClearGui() {} + +} + +} diff --git a/src/platform/guiwin.cpp b/src/platform/guiwin.cpp new file mode 100644 index 0000000..d885195 --- /dev/null +++ b/src/platform/guiwin.cpp @@ -0,0 +1,1712 @@ +//----------------------------------------------------------------------------- +// The Win32-based implementation of platform-dependent GUI functionality. +// +// Copyright 2018 whitequark +//----------------------------------------------------------------------------- +#include "config.h" +#include "solvespace.h" +// Include after solvespace.h to avoid identifier clashes. +#include +#include +#include +#include +#include + +// Macros to compile under XP +#if !defined(LSTATUS) +# define LSTATUS LONG +#endif + +#if !defined(MAPVK_VK_TO_CHAR) +# define MAPVK_VK_TO_CHAR 2 +#endif + +#if !defined(USER_DEFAULT_SCREEN_DPI) +# define USER_DEFAULT_SCREEN_DPI 96 +#endif + +#if !defined(TTM_POPUP) +# define TTM_POPUP (WM_USER + 34) +#endif +// End macros to compile under XP + +#if !defined(WM_DPICHANGED) +# define WM_DPICHANGED 0x02E0 +#endif + +// These interfere with our identifiers. +#undef CreateWindow +#undef ERROR + +#if HAVE_OPENGL == 3 +# define EGLAPI /*static linkage*/ +# define EGL_EGLEXT_PROTOTYPES +# include +# include +#endif + +#if defined(HAVE_SPACEWARE) +# include +# include +# undef uint32_t +#endif + +#if defined(__GNUC__) +// Disable bogus warning emitted by GCC on GetProcAddress, since there seems to be no way +// of restructuring the code to easily disable it just at the call site. +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + +namespace SolveSpace { +namespace Platform { + +//----------------------------------------------------------------------------- +// Windows API bridging +//----------------------------------------------------------------------------- + +#define sscheck(expr) do { \ + SetLastError(0); \ + if(!(expr)) \ + CheckLastError(__FILE__, __LINE__, __func__, #expr); \ + } while(0) + +void CheckLastError(const char *file, int line, const char *function, const char *expr) { + if(GetLastError() != S_OK) { + LPWSTR messageW; + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR)&messageW, 0, NULL); + + std::string message; + message += ssprintf("File %s, line %u, function %s:\n", file, line, function); + message += ssprintf("Win32 API call failed: %s.\n", expr); + message += ssprintf("Error: %s", Narrow(messageW).c_str()); + FatalError(message); + } +} + +typedef UINT (WINAPI *LPFNGETDPIFORWINDOW)(HWND); + +UINT ssGetDpiForWindow(HWND hwnd) { + static bool checked; + static LPFNGETDPIFORWINDOW lpfnGetDpiForWindow; + if(!checked) { + checked = true; + lpfnGetDpiForWindow = (LPFNGETDPIFORWINDOW) + GetProcAddress(GetModuleHandleW(L"user32.dll"), "GetDpiForWindow"); + } + if(lpfnGetDpiForWindow) { + return lpfnGetDpiForWindow(hwnd); + } else { + HDC hDc; + sscheck(hDc = GetDC(HWND_DESKTOP)); + UINT dpi; + sscheck(dpi = GetDeviceCaps(hDc, LOGPIXELSX)); + sscheck(ReleaseDC(HWND_DESKTOP, hDc)); + return dpi; + } +} + +typedef BOOL (WINAPI *LPFNADJUSTWINDOWRECTEXFORDPI)(LPRECT, DWORD, BOOL, DWORD, UINT); + +BOOL ssAdjustWindowRectExForDpi(LPRECT lpRect, DWORD dwStyle, BOOL bMenu, + DWORD dwExStyle, UINT dpi) { + static bool checked; + static LPFNADJUSTWINDOWRECTEXFORDPI lpfnAdjustWindowRectExForDpi; + if(!checked) { + checked = true; + lpfnAdjustWindowRectExForDpi = (LPFNADJUSTWINDOWRECTEXFORDPI) + GetProcAddress(GetModuleHandleW(L"user32.dll"), "AdjustWindowRectExForDpi"); + } + if(lpfnAdjustWindowRectExForDpi) { + return lpfnAdjustWindowRectExForDpi(lpRect, dwStyle, bMenu, dwExStyle, dpi); + } else { + return AdjustWindowRectEx(lpRect, dwStyle, bMenu, dwExStyle); + } +} + +//----------------------------------------------------------------------------- +// Utility functions +//----------------------------------------------------------------------------- + +static std::wstring PrepareTitle(const std::string &s) { + return Widen("SolveSpace - " + s); +} + +static std::string NegateMnemonics(const std::string &label) { + std::string newLabel; + for(char c : label) { + newLabel.push_back(c); + if(c == '&') newLabel.push_back(c); + } + return newLabel; +} + +static int Clamp(int x, int a, int b) { + return max(a, min(x, b)); +} + +//----------------------------------------------------------------------------- +// Fatal errors +//----------------------------------------------------------------------------- + +bool handlingFatalError = false; + +void FatalError(const std::string &message) { + // Indicate that we're handling a fatal error, to avoid re-entering application code + // and potentially crashing even harder. + handlingFatalError = true; + + switch(MessageBoxW(NULL, Platform::Widen(message + "\nGenerate debug report?").c_str(), + L"Fatal error — SolveSpace", + MB_ICONERROR|MB_TASKMODAL|MB_SETFOREGROUND|MB_TOPMOST| + MB_OKCANCEL|MB_DEFBUTTON2)) { + case IDOK: + abort(); + + case IDCANCEL: + default: { + WCHAR appPath[MAX_PATH] = {}; + GetModuleFileNameW(NULL, appPath, sizeof(appPath)); + ShellExecuteW(NULL, L"open", appPath, NULL, NULL, SW_SHOW); + _exit(1); + } + } +} +//----------------------------------------------------------------------------- +// Settings +//----------------------------------------------------------------------------- + +class SettingsImplWin32 final : public Settings { +public: + HKEY hKey = NULL; + + HKEY GetKey() { + if(hKey == NULL) { + sscheck(ERROR_SUCCESS == RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\SolveSpace", 0, NULL, 0, + KEY_ALL_ACCESS, NULL, &hKey, NULL)); + } + return hKey; + } + + ~SettingsImplWin32() { + if(hKey != NULL) { + sscheck(ERROR_SUCCESS == RegCloseKey(hKey)); + } + } + + void FreezeInt(const std::string &key, uint32_t value) { + sscheck(ERROR_SUCCESS == RegSetValueExW(GetKey(), &Widen(key)[0], 0, + REG_DWORD, (const BYTE *)&value, sizeof(value))); + } + + uint32_t ThawInt(const std::string &key, uint32_t defaultValue) { + DWORD value; + DWORD type, length = sizeof(value); + LSTATUS result = RegQueryValueExW(GetKey(), &Widen(key)[0], 0, + &type, (BYTE *)&value, &length); + if(result == ERROR_SUCCESS && type == REG_DWORD) { + return value; + } + return defaultValue; + } + + void FreezeFloat(const std::string &key, double value) { + sscheck(ERROR_SUCCESS == RegSetValueExW(GetKey(), &Widen(key)[0], 0, + REG_QWORD, (const BYTE *)&value, sizeof(value))); + } + + double ThawFloat(const std::string &key, double defaultValue) { + double value; + DWORD type, length = sizeof(value); + LSTATUS result = RegQueryValueExW(GetKey(), &Widen(key)[0], 0, + &type, (BYTE *)&value, &length); + if(result == ERROR_SUCCESS && type == REG_QWORD) { + return value; + } + return defaultValue; + } + + void FreezeString(const std::string &key, const std::string &value) { + ssassert(value.length() == strlen(value.c_str()), + "illegal null byte in middle of a string setting"); + std::wstring valueW = Widen(value); + sscheck(ERROR_SUCCESS == RegSetValueExW(GetKey(), &Widen(key)[0], 0, + REG_SZ, (const BYTE *)&valueW[0], (valueW.length() + 1) * 2)); + } + + std::string ThawString(const std::string &key, const std::string &defaultValue) { + DWORD type, length = 0; + LSTATUS result = RegQueryValueExW(GetKey(), &Widen(key)[0], 0, + &type, NULL, &length); + if(result == ERROR_SUCCESS && type == REG_SZ) { + std::wstring valueW; + valueW.resize(length / 2 - 1); + sscheck(ERROR_SUCCESS == RegQueryValueExW(GetKey(), &Widen(key)[0], 0, + &type, (BYTE *)&valueW[0], &length)); + return Narrow(valueW); + } + return defaultValue; + } +}; + +SettingsRef GetSettings() { + return std::make_shared(); +} + +//----------------------------------------------------------------------------- +// Timers +//----------------------------------------------------------------------------- + +class TimerImplWin32 final : public Timer { +public: + static HWND WindowHandle() { + static HWND hTimerWnd; + if(hTimerWnd == NULL) { + sscheck(hTimerWnd = CreateWindowExW(0, L"Message", NULL, 0, 0, 0, 0, 0, + HWND_MESSAGE, NULL, NULL, NULL)); + } + return hTimerWnd; + } + + static void CALLBACK TimerFunc(HWND hwnd, UINT msg, UINT_PTR event, DWORD time) { + sscheck(KillTimer(WindowHandle(), event)); + + TimerImplWin32 *timer = (TimerImplWin32*)event; + if(timer->onTimeout) { + timer->onTimeout(); + } + } + + void RunAfter(unsigned milliseconds) override { + // FIXME(platform/gui): use SetCoalescableTimer when it's available (8+) + sscheck(SetTimer(WindowHandle(), (UINT_PTR)this, + milliseconds, &TimerImplWin32::TimerFunc)); + } + + ~TimerImplWin32() { + // FIXME(platform/gui): there's a race condition here--WM_TIMER messages already + // posted to the queue are not removed, so this destructor is at most "best effort". + KillTimer(WindowHandle(), (UINT_PTR)this); + } +}; + +TimerRef CreateTimer() { + return std::make_shared(); +} + +//----------------------------------------------------------------------------- +// Menus +//----------------------------------------------------------------------------- + +class MenuImplWin32; + +class MenuItemImplWin32 final : public MenuItem { +public: + std::shared_ptr menu; + + HMENU Handle(); + + MENUITEMINFOW GetInfo(UINT mask) { + MENUITEMINFOW mii = {}; + mii.cbSize = sizeof(mii); + mii.fMask = mask; + sscheck(GetMenuItemInfoW(Handle(), (UINT_PTR)this, FALSE, &mii)); + return mii; + } + + void SetAccelerator(KeyboardEvent accel) override { + MENUITEMINFOW mii = GetInfo(MIIM_TYPE); + + std::wstring nameW(mii.cch, L'\0'); + mii.dwTypeData = &nameW[0]; + mii.cch++; + sscheck(GetMenuItemInfoW(Handle(), (UINT_PTR)this, FALSE, &mii)); + + std::string name = Narrow(nameW); + if(name.find('\t') != std::string::npos) { + name = name.substr(0, name.find('\t')); + } + name += '\t'; + name += AcceleratorDescription(accel); + + nameW = Widen(name); + mii.fMask = MIIM_STRING; + mii.dwTypeData = &nameW[0]; + sscheck(SetMenuItemInfoW(Handle(), (UINT_PTR)this, FALSE, &mii)); + } + + void SetIndicator(Indicator type) override { + MENUITEMINFOW mii = GetInfo(MIIM_FTYPE); + switch(type) { + case Indicator::NONE: + case Indicator::CHECK_MARK: + mii.fType &= ~MFT_RADIOCHECK; + break; + + case Indicator::RADIO_MARK: + mii.fType |= MFT_RADIOCHECK; + break; + } + sscheck(SetMenuItemInfoW(Handle(), (UINT_PTR)this, FALSE, &mii)); + } + + void SetActive(bool active) override { + MENUITEMINFOW mii = GetInfo(MIIM_STATE); + if(active) { + mii.fState |= MFS_CHECKED; + } else { + mii.fState &= ~MFS_CHECKED; + } + sscheck(SetMenuItemInfoW(Handle(), (UINT_PTR)this, FALSE, &mii)); + } + + void SetEnabled(bool enabled) override { + MENUITEMINFOW mii = GetInfo(MIIM_STATE); + if(enabled) { + mii.fState &= ~(MFS_DISABLED|MFS_GRAYED); + } else { + mii.fState |= MFS_DISABLED|MFS_GRAYED; + } + sscheck(SetMenuItemInfoW(Handle(), (UINT_PTR)this, FALSE, &mii)); + } +}; + +int64_t contextMenuPopTime = 0; + +class MenuImplWin32 final : public Menu { +public: + HMENU hMenu; + + std::weak_ptr weakThis; + std::vector> menuItems; + std::vector> subMenus; + + MenuImplWin32() { + sscheck(hMenu = CreatePopupMenu()); + } + + MenuItemRef AddItem(const std::string &label, + std::function onTrigger = NULL, + bool mnemonics = true) override { + auto menuItem = std::make_shared(); + menuItem->menu = weakThis.lock(); + menuItem->onTrigger = onTrigger; + menuItems.push_back(menuItem); + + sscheck(AppendMenuW(hMenu, MF_STRING, (UINT_PTR)menuItem.get(), + Widen(mnemonics ? label : NegateMnemonics(label)).c_str())); + + // uID is just an UINT, which isn't large enough to hold a pointer on 64-bit Windows, + // so we use dwItemData, which is. + MENUITEMINFOW mii = {}; + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_DATA; + mii.dwItemData = (LONG_PTR)menuItem.get(); + sscheck(SetMenuItemInfoW(hMenu, (UINT_PTR)menuItem.get(), FALSE, &mii)); + + return menuItem; + } + + MenuRef AddSubMenu(const std::string &label) override { + auto subMenu = std::make_shared(); + subMenu->weakThis = subMenu; + subMenus.push_back(subMenu); + + sscheck(AppendMenuW(hMenu, MF_STRING|MF_POPUP, + (UINT_PTR)subMenu->hMenu, Widen(label).c_str())); + + return subMenu; + } + + void AddSeparator() override { + sscheck(AppendMenuW(hMenu, MF_SEPARATOR, 0, L"")); + } + + void PopUp() override { + MENUINFO mi = {}; + mi.cbSize = sizeof(mi); + mi.fMask = MIM_APPLYTOSUBMENUS|MIM_STYLE; + mi.dwStyle = MNS_NOTIFYBYPOS; + sscheck(SetMenuInfo(hMenu, &mi)); + + POINT pt; + sscheck(GetCursorPos(&pt)); + + sscheck(TrackPopupMenu(hMenu, TPM_TOPALIGN, pt.x, pt.y, 0, GetActiveWindow(), NULL)); + contextMenuPopTime = GetMilliseconds(); + } + + void Clear() override { + for(int n = GetMenuItemCount(hMenu) - 1; n >= 0; n--) { + sscheck(RemoveMenu(hMenu, n, MF_BYPOSITION)); + } + menuItems.clear(); + subMenus.clear(); + } + + ~MenuImplWin32() { + Clear(); + sscheck(DestroyMenu(hMenu)); + } +}; + +HMENU MenuItemImplWin32::Handle() { + return menu->hMenu; +} + +MenuRef CreateMenu() { + auto menu = std::make_shared(); + // std::enable_shared_from_this fails for some reason, not sure why + menu->weakThis = menu; + return menu; +} + +class MenuBarImplWin32 final : public MenuBar { +public: + HMENU hMenuBar; + + std::vector> subMenus; + + MenuBarImplWin32() { + sscheck(hMenuBar = ::CreateMenu()); + } + + MenuRef AddSubMenu(const std::string &label) override { + auto subMenu = std::make_shared(); + subMenu->weakThis = subMenu; + subMenus.push_back(subMenu); + + sscheck(AppendMenuW(hMenuBar, MF_STRING|MF_POPUP, + (UINT_PTR)subMenu->hMenu, Widen(label).c_str())); + + return subMenu; + } + + void Clear() override { + for(int n = GetMenuItemCount(hMenuBar) - 1; n >= 0; n--) { + sscheck(RemoveMenu(hMenuBar, n, MF_BYPOSITION)); + } + subMenus.clear(); + } + + ~MenuBarImplWin32() { + Clear(); + sscheck(DestroyMenu(hMenuBar)); + } +}; + +MenuBarRef GetOrCreateMainMenu(bool *unique) { + *unique = false; + return std::make_shared(); +} + +//----------------------------------------------------------------------------- +// Windows +//----------------------------------------------------------------------------- + +#define SCROLLBAR_UNIT 65536 + +class WindowImplWin32 final : public Window { +public: + HWND hWindow = NULL; + HWND hTooltip = NULL; + HWND hEditor = NULL; + WNDPROC editorWndProc = NULL; + +#if HAVE_OPENGL == 1 + HGLRC hGlRc = NULL; +#elif HAVE_OPENGL == 3 + static EGLDisplay eglDisplay; + EGLSurface eglSurface = EGL_NO_SURFACE; + EGLContext eglContext = EGL_NO_CONTEXT; +#endif + + WINDOWPLACEMENT placement = {}; + int minWidth = 0, minHeight = 0; + +#if defined(HAVE_SPACEWARE) + SiOpenData sod = {}; + SiHdl hSpaceWare = SI_NO_HANDLE; +#endif + + std::shared_ptr menuBar; + std::string tooltipText; + bool scrollbarVisible = false; + + static void RegisterWindowClass() { + static bool registered; + if(registered) return; + + WNDCLASSEXW wc = {}; + wc.cbSize = sizeof(wc); + wc.style = CS_BYTEALIGNCLIENT|CS_BYTEALIGNWINDOW|CS_OWNDC|CS_DBLCLKS; + wc.lpfnWndProc = WndProc; + wc.cbWndExtra = sizeof(WindowImplWin32 *); + wc.hIcon = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(4000), + IMAGE_ICON, 32, 32, 0); + wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(4000), + IMAGE_ICON, 16, 16, 0); + wc.hCursor = LoadCursorW(NULL, IDC_ARROW); + wc.lpszClassName = L"SolveSpace"; + sscheck(RegisterClassExW(&wc)); + registered = true; + } + + WindowImplWin32(Window::Kind kind, std::shared_ptr parentWindow) { + placement.length = sizeof(placement); + + RegisterWindowClass(); + + HWND hParentWindow = NULL; + if(parentWindow) { + hParentWindow = parentWindow->hWindow; + } + + DWORD style = WS_SIZEBOX|WS_CLIPCHILDREN; + switch(kind) { + case Window::Kind::TOPLEVEL: + style |= WS_OVERLAPPEDWINDOW|WS_CLIPSIBLINGS; + break; + + case Window::Kind::TOOL: + style |= WS_POPUPWINDOW|WS_CAPTION; + break; + } + sscheck(hWindow = CreateWindowExW(0, L"SolveSpace", L"", style, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + hParentWindow, NULL, NULL, NULL)); + sscheck(SetWindowLongPtr(hWindow, 0, (LONG_PTR)this)); + + sscheck(hTooltip = CreateWindowExW(0, TOOLTIPS_CLASS, NULL, + WS_POPUP|TTS_NOPREFIX|TTS_ALWAYSTIP, + CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, CW_USEDEFAULT, + hWindow, NULL, NULL, NULL)); + sscheck(SetWindowPos(hTooltip, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE)); + + TOOLINFOW ti = {}; + ti.cbSize = sizeof(ti); + ti.uFlags = TTF_SUBCLASS; + ti.hwnd = hWindow; + ti.lpszText = (LPWSTR)L""; + sscheck(SendMessageW(hTooltip, TTM_ADDTOOLW, 0, (LPARAM)&ti)); + sscheck(SendMessageW(hTooltip, TTM_ACTIVATE, FALSE, 0)); + + DWORD editorStyle = WS_CLIPSIBLINGS|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL; + sscheck(hEditor = CreateWindowExW(WS_EX_CLIENTEDGE, WC_EDIT, L"", editorStyle, + 0, 0, 0, 0, hWindow, NULL, NULL, NULL)); + sscheck(editorWndProc = + (WNDPROC)SetWindowLongPtr(hEditor, GWLP_WNDPROC, (LONG_PTR)EditorWndProc)); + + HDC hDc; + sscheck(hDc = GetDC(hWindow)); + +#if HAVE_OPENGL == 1 + PIXELFORMATDESCRIPTOR pfd = {}; + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER; + pfd.dwLayerMask = PFD_MAIN_PLANE; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 32; + pfd.cDepthBits = 24; + pfd.cAccumBits = 0; + pfd.cStencilBits = 0; + int pixelFormat; + sscheck(pixelFormat = ChoosePixelFormat(hDc, &pfd)); + sscheck(SetPixelFormat(hDc, pixelFormat, &pfd)); + + sscheck(hGlRc = wglCreateContext(hDc)); +#elif HAVE_OPENGL == 3 + if(eglDisplay == EGL_NO_DISPLAY) { + ssassert(eglBindAPI(EGL_OPENGL_ES_API), "Cannot bind EGL API"); + + EGLBoolean initialized = EGL_FALSE; + for(auto &platformType : { + // Try platform types from least to most amount of software translation required. + std::make_pair("OpenGL ES", EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE), + std::make_pair("OpenGL", EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE), + std::make_pair("Direct3D 11", EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE), + std::make_pair("Direct3D 9", EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE), + }) { + dbp("Initializing ANGLE with %s backend", platformType.first); + EGLint displayAttributes[] = { + EGL_PLATFORM_ANGLE_TYPE_ANGLE, platformType.second, + EGL_NONE + }; + eglDisplay = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, hDc, + displayAttributes); + if(eglDisplay != EGL_NO_DISPLAY) { + initialized = eglInitialize(eglDisplay, NULL, NULL); + if(initialized) break; + eglTerminate(eglDisplay); + } + } + ssassert(initialized, "Cannot find a suitable EGL display"); + } + + EGLint configAttributes[] = { + EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_DEPTH_SIZE, 24, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_NONE + }; + EGLint numConfigs; + EGLConfig windowConfig; + ssassert(eglChooseConfig(eglDisplay, configAttributes, &windowConfig, 1, &numConfigs), + "Cannot choose EGL configuration"); + + EGLint surfaceAttributes[] = { + EGL_NONE + }; + eglSurface = eglCreateWindowSurface(eglDisplay, windowConfig, hWindow, surfaceAttributes); + ssassert(eglSurface != EGL_NO_SURFACE, "Cannot create EGL window surface"); + + EGLint contextAttributes[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + eglContext = eglCreateContext(eglDisplay, windowConfig, NULL, contextAttributes); + ssassert(eglContext != EGL_NO_CONTEXT, "Cannot create EGL context"); +#endif + + sscheck(ReleaseDC(hWindow, hDc)); + } + + ~WindowImplWin32() { + // Make sure any of our child windows get destroyed before we call DestroyWindow, or their + // own destructors may fail. + menuBar.reset(); + + sscheck(DestroyWindow(hWindow)); +#if defined(HAVE_SPACEWARE) + if(hSpaceWare != SI_NO_HANDLE) { + SiClose(hSpaceWare); + } +#endif + } + + static LRESULT CALLBACK WndProc(HWND h, UINT msg, WPARAM wParam, LPARAM lParam) { + if(handlingFatalError) return TRUE; + + WindowImplWin32 *window; + sscheck(window = (WindowImplWin32 *)GetWindowLongPtr(h, 0)); + + // The wndproc may be called from within CreateWindowEx, and before we've associated + // the window with the WindowImplWin32. In that case, just defer to the default wndproc. + if(window == NULL) { + return DefWindowProcW(h, msg, wParam, lParam); + } + +#if defined(HAVE_SPACEWARE) + if(window->hSpaceWare != SI_NO_HANDLE) { + SiGetEventData sged; + SiGetEventWinInit(&sged, msg, wParam, lParam); + + SiSpwEvent sse; + if(SiGetEvent(window->hSpaceWare, 0, &sged, &sse) == SI_IS_EVENT) { + SixDofEvent event = {}; + event.shiftDown = ((GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0); + event.controlDown = ((GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0); + if(sse.type == SI_MOTION_EVENT) { + // The Z axis translation and rotation are both + // backwards in the default mapping. + event.type = SixDofEvent::Type::MOTION; + event.translationX = sse.u.spwData.mData[SI_TX]*1.0, + event.translationY = sse.u.spwData.mData[SI_TY]*1.0, + event.translationZ = -sse.u.spwData.mData[SI_TZ]*1.0, + event.rotationX = sse.u.spwData.mData[SI_RX]*0.001, + event.rotationY = sse.u.spwData.mData[SI_RY]*0.001, + event.rotationZ = -sse.u.spwData.mData[SI_RZ]*0.001; + } else if(sse.type == SI_BUTTON_EVENT) { + if(SiButtonPressed(&sse) == SI_APP_FIT_BUTTON) { + event.type = SixDofEvent::Type::PRESS; + event.button = SixDofEvent::Button::FIT; + } + if(SiButtonReleased(&sse) == SI_APP_FIT_BUTTON) { + event.type = SixDofEvent::Type::RELEASE; + event.button = SixDofEvent::Button::FIT; + } + } else { + return 0; + } + if(window->onSixDofEvent) { + window->onSixDofEvent(event); + } + return 0; + } + } +#endif + + switch (msg) { + case WM_ERASEBKGND: + break; + + case WM_PAINT: { + PAINTSTRUCT ps; + HDC hDc = BeginPaint(window->hWindow, &ps); + if(window->onRender) { +#if HAVE_OPENGL == 1 + wglMakeCurrent(hDc, window->hGlRc); +#elif HAVE_OPENGL == 3 + eglMakeCurrent(window->eglDisplay, window->eglSurface, + window->eglSurface, window->eglContext); +#endif + window->onRender(); +#if HAVE_OPENGL == 1 + SwapBuffers(hDc); +#elif HAVE_OPENGL == 3 + eglSwapBuffers(window->eglDisplay, window->eglSurface); + (void)hDc; +#endif + } + EndPaint(window->hWindow, &ps); + break; + } + + case WM_CLOSE: + if(window->onClose) { + window->onClose(); + } + break; + + case WM_SIZE: + window->Invalidate(); + break; + + case WM_SIZING: { + int pixelRatio = window->GetDevicePixelRatio(); + + RECT rcw, rcc; + sscheck(GetWindowRect(window->hWindow, &rcw)); + sscheck(GetClientRect(window->hWindow, &rcc)); + int nonClientWidth = (rcw.right - rcw.left) - (rcc.right - rcc.left); + int nonClientHeight = (rcw.bottom - rcw.top) - (rcc.bottom - rcc.top); + + RECT *rc = (RECT *)lParam; + int adjWidth = rc->right - rc->left; + int adjHeight = rc->bottom - rc->top; + + adjWidth -= nonClientWidth; + adjWidth = max(window->minWidth * pixelRatio, adjWidth); + adjWidth += nonClientWidth; + adjHeight -= nonClientHeight; + adjHeight = max(window->minHeight * pixelRatio, adjHeight); + adjHeight += nonClientHeight; + switch(wParam) { + case WMSZ_RIGHT: + case WMSZ_BOTTOMRIGHT: + case WMSZ_TOPRIGHT: + rc->right = rc->left + adjWidth; + break; + + case WMSZ_LEFT: + case WMSZ_BOTTOMLEFT: + case WMSZ_TOPLEFT: + rc->left = rc->right - adjWidth; + break; + } + switch(wParam) { + case WMSZ_BOTTOM: + case WMSZ_BOTTOMLEFT: + case WMSZ_BOTTOMRIGHT: + rc->bottom = rc->top + adjHeight; + break; + + case WMSZ_TOP: + case WMSZ_TOPLEFT: + case WMSZ_TOPRIGHT: + rc->top = rc->bottom - adjHeight; + break; + } + break; + } + + case WM_DPICHANGED: { + RECT rc = *(RECT *)lParam; + sscheck(SendMessage(window->hWindow, WM_SIZING, WMSZ_BOTTOMRIGHT, (LPARAM)&rc)); + sscheck(SetWindowPos(window->hWindow, NULL, rc.left, rc.top, + rc.right - rc.left, rc.bottom - rc.top, + SWP_NOZORDER|SWP_NOACTIVATE)); + window->Invalidate(); + break; + } + + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_LBUTTONDBLCLK: + case WM_MBUTTONDBLCLK: + case WM_RBUTTONDBLCLK: + case WM_LBUTTONUP: + case WM_MBUTTONUP: + case WM_RBUTTONUP: + if(GetMilliseconds() - Platform::contextMenuPopTime < 100) { + // Ignore the mouse click that dismisses a context menu, to avoid + // (e.g.) clearing a selection. + return 0; + } + // fallthrough + case WM_MOUSEMOVE: + case WM_MOUSEWHEEL: + case WM_MOUSELEAVE: { + int pixelRatio = window->GetDevicePixelRatio(); + + MouseEvent event = {}; + event.x = GET_X_LPARAM(lParam) / pixelRatio; + event.y = GET_Y_LPARAM(lParam) / pixelRatio; + event.button = MouseEvent::Button::NONE; + + event.shiftDown = (wParam & MK_SHIFT) != 0; + event.controlDown = (wParam & MK_CONTROL) != 0; + + bool consumed = false; + switch(msg) { + case WM_LBUTTONDOWN: + event.button = MouseEvent::Button::LEFT; + event.type = MouseEvent::Type::PRESS; + break; + case WM_MBUTTONDOWN: + event.button = MouseEvent::Button::MIDDLE; + event.type = MouseEvent::Type::PRESS; + break; + case WM_RBUTTONDOWN: + event.button = MouseEvent::Button::RIGHT; + event.type = MouseEvent::Type::PRESS; + break; + + case WM_LBUTTONDBLCLK: + event.button = MouseEvent::Button::LEFT; + event.type = MouseEvent::Type::DBL_PRESS; + break; + case WM_MBUTTONDBLCLK: + event.button = MouseEvent::Button::MIDDLE; + event.type = MouseEvent::Type::DBL_PRESS; + break; + case WM_RBUTTONDBLCLK: + event.button = MouseEvent::Button::RIGHT; + event.type = MouseEvent::Type::DBL_PRESS; + break; + + case WM_LBUTTONUP: + event.button = MouseEvent::Button::LEFT; + event.type = MouseEvent::Type::RELEASE; + break; + case WM_MBUTTONUP: + event.button = MouseEvent::Button::MIDDLE; + event.type = MouseEvent::Type::RELEASE; + break; + case WM_RBUTTONUP: + event.button = MouseEvent::Button::RIGHT; + event.type = MouseEvent::Type::RELEASE; + break; + + case WM_MOUSEWHEEL: + // Make the mousewheel work according to which window the mouse is + // over, not according to which window is active. + POINT pt; + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); + HWND hWindowUnderMouse; + sscheck(hWindowUnderMouse = WindowFromPoint(pt)); + if(hWindowUnderMouse && hWindowUnderMouse != h) { + SendMessageW(hWindowUnderMouse, msg, wParam, lParam); + consumed = true; + break; + } + + // Convert the mouse coordinates from screen to client area so that + // scroll wheel zooming remains centered irrespective of the window + // position. + ScreenToClient(hWindowUnderMouse, &pt); + event.x = pt.x / pixelRatio; + event.y = pt.y / pixelRatio; + + event.type = MouseEvent::Type::SCROLL_VERT; + event.scrollDelta = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA; + break; + + case WM_MOUSELEAVE: + event.type = MouseEvent::Type::LEAVE; + break; + case WM_MOUSEMOVE: { + event.type = MouseEvent::Type::MOTION; + + if(wParam & MK_LBUTTON) { + event.button = MouseEvent::Button::LEFT; + } else if(wParam & MK_MBUTTON) { + event.button = MouseEvent::Button::MIDDLE; + } else if(wParam & MK_RBUTTON) { + event.button = MouseEvent::Button::RIGHT; + } + + // We need this in order to get the WM_MOUSELEAVE + TRACKMOUSEEVENT tme = {}; + tme.cbSize = sizeof(tme); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = window->hWindow; + sscheck(TrackMouseEvent(&tme)); + break; + } + } + + if(!consumed && window->onMouseEvent) { + window->onMouseEvent(event); + } + break; + } + + case WM_KEYDOWN: + case WM_KEYUP: { + Platform::KeyboardEvent event = {}; + if(msg == WM_KEYDOWN) { + event.type = Platform::KeyboardEvent::Type::PRESS; + } else if(msg == WM_KEYUP) { + event.type = Platform::KeyboardEvent::Type::RELEASE; + } + + if(GetKeyState(VK_SHIFT) & 0x8000) + event.shiftDown = true; + if(GetKeyState(VK_CONTROL) & 0x8000) + event.controlDown = true; + + if(wParam >= VK_F1 && wParam <= VK_F12) { + event.key = Platform::KeyboardEvent::Key::FUNCTION; + event.num = wParam - VK_F1 + 1; + } else { + event.key = Platform::KeyboardEvent::Key::CHARACTER; + event.chr = tolower(MapVirtualKeyW(wParam, MAPVK_VK_TO_CHAR)); + if(event.chr == 0) { + if(wParam == VK_DELETE) { + event.chr = '\x7f'; + } else { + // Non-mappable key. + break; + } + } else if(event.chr == '.' && event.shiftDown) { + event.chr = '>'; + event.shiftDown = false;; + } + } + + if(window->onKeyboardEvent) { + window->onKeyboardEvent(event); + } + break; + } + + case WM_SYSKEYDOWN: { + HWND hParent; + sscheck(hParent = GetParent(h)); + if(hParent != NULL) { + // If the user presses the Alt key when a tool window has focus, + // then that should probably go to the main window instead. + sscheck(SetForegroundWindow(hParent)); + break; + } else { + return DefWindowProcW(h, msg, wParam, lParam); + } + } + + case WM_VSCROLL: { + SCROLLINFO si = {}; + si.cbSize = sizeof(si); + si.fMask = SIF_POS|SIF_TRACKPOS|SIF_RANGE|SIF_PAGE; + sscheck(GetScrollInfo(window->hWindow, SB_VERT, &si)); + + switch(LOWORD(wParam)) { + case SB_LINEUP: si.nPos -= SCROLLBAR_UNIT; break; + case SB_PAGEUP: si.nPos -= si.nPage; break; + case SB_LINEDOWN: si.nPos += SCROLLBAR_UNIT; break; + case SB_PAGEDOWN: si.nPos += si.nPage; break; + case SB_TOP: si.nPos = si.nMin; break; + case SB_BOTTOM: si.nPos = si.nMax; break; + case SB_THUMBTRACK: + case SB_THUMBPOSITION: si.nPos = si.nTrackPos; break; + } + + si.nPos = min((UINT)si.nPos, (UINT)(si.nMax - si.nPage)); + + if(window->onScrollbarAdjusted) { + window->onScrollbarAdjusted((double)si.nPos / SCROLLBAR_UNIT); + } + break; + } + + case WM_MENUCOMMAND: { + MENUITEMINFOW mii = {}; + mii.cbSize = sizeof(mii); + mii.fMask = MIIM_DATA; + sscheck(GetMenuItemInfoW((HMENU)lParam, wParam, TRUE, &mii)); + + MenuItemImplWin32 *menuItem = (MenuItemImplWin32 *)mii.dwItemData; + if(menuItem->onTrigger) { + menuItem->onTrigger(); + } + break; + } + + default: + return DefWindowProcW(h, msg, wParam, lParam); + } + + return 0; + } + + static LRESULT CALLBACK EditorWndProc(HWND h, UINT msg, WPARAM wParam, LPARAM lParam) { + if(handlingFatalError) return 0; + + HWND hWindow; + sscheck(hWindow = GetParent(h)); + + WindowImplWin32 *window; + sscheck(window = (WindowImplWin32 *)GetWindowLongPtr(hWindow, 0)); + + switch(msg) { + case WM_CHAR: + if(wParam == VK_RETURN) { + if(window->onEditingDone) { + int length; + sscheck(length = GetWindowTextLength(h)); + + std::wstring resultW; + resultW.resize(length); + sscheck(GetWindowTextW(h, &resultW[0], resultW.length() + 1)); + + window->onEditingDone(Narrow(resultW)); + return 0; + } + } else if(wParam == VK_ESCAPE) { + sscheck(SendMessageW(hWindow, msg, wParam, lParam)); + return 0; + } + } + + return CallWindowProc(window->editorWndProc, h, msg, wParam, lParam); + } + + double GetPixelDensity() override { + UINT dpi; + sscheck(dpi = ssGetDpiForWindow(hWindow)); + return (double)dpi; + } + + int GetDevicePixelRatio() override { + UINT dpi; + sscheck(dpi = ssGetDpiForWindow(hWindow)); + return dpi / USER_DEFAULT_SCREEN_DPI; + } + + bool IsVisible() override { + BOOL isVisible; + isVisible = IsWindowVisible(hWindow); + return isVisible == TRUE; + } + + void SetVisible(bool visible) override { + ShowWindow(hWindow, visible ? SW_SHOW : SW_HIDE); + } + + void Focus() override { + sscheck(SetActiveWindow(hWindow)); + } + + bool IsFullScreen() override { + DWORD style; + sscheck(style = GetWindowLongPtr(hWindow, GWL_STYLE)); + return !(style & WS_OVERLAPPEDWINDOW); + } + + void SetFullScreen(bool fullScreen) override { + DWORD style; + sscheck(style = GetWindowLongPtr(hWindow, GWL_STYLE)); + if(fullScreen) { + sscheck(GetWindowPlacement(hWindow, &placement)); + + MONITORINFO mi; + mi.cbSize = sizeof(mi); + sscheck(GetMonitorInfo(MonitorFromWindow(hWindow, MONITOR_DEFAULTTONEAREST), &mi)); + + sscheck(SetWindowLong(hWindow, GWL_STYLE, style & ~WS_OVERLAPPEDWINDOW)); + sscheck(SetWindowPos(hWindow, HWND_TOP, + mi.rcMonitor.left, mi.rcMonitor.top, + mi.rcMonitor.right - mi.rcMonitor.left, + mi.rcMonitor.bottom - mi.rcMonitor.top, + SWP_NOOWNERZORDER|SWP_FRAMECHANGED)); + } else { + sscheck(SetWindowLong(hWindow, GWL_STYLE, style | WS_OVERLAPPEDWINDOW)); + sscheck(SetWindowPlacement(hWindow, &placement)); + sscheck(SetWindowPos(hWindow, NULL, 0, 0, 0, 0, + SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER| + SWP_NOOWNERZORDER|SWP_FRAMECHANGED)); + } + } + + void SetTitle(const std::string &title) override { + sscheck(SetWindowTextW(hWindow, PrepareTitle(title).c_str())); + } + + void SetMenuBar(MenuBarRef newMenuBar) override { + menuBar = std::static_pointer_cast(newMenuBar); + + MENUINFO mi = {}; + mi.cbSize = sizeof(mi); + mi.fMask = MIM_APPLYTOSUBMENUS|MIM_STYLE; + mi.dwStyle = MNS_NOTIFYBYPOS; + sscheck(SetMenuInfo(menuBar->hMenuBar, &mi)); + + sscheck(SetMenu(hWindow, menuBar->hMenuBar)); + } + + void GetContentSize(double *width, double *height) override { + int pixelRatio = GetDevicePixelRatio(); + + RECT rc; + sscheck(GetClientRect(hWindow, &rc)); + *width = (rc.right - rc.left) / pixelRatio; + *height = (rc.bottom - rc.top) / pixelRatio; + } + + void SetMinContentSize(double width, double height) { + minWidth = (int)width; + minHeight = (int)height; + + int pixelRatio = GetDevicePixelRatio(); + + RECT rc; + sscheck(GetClientRect(hWindow, &rc)); + if(rc.right - rc.left < minWidth * pixelRatio) { + rc.right = rc.left + minWidth * pixelRatio; + } + if(rc.bottom - rc.top < minHeight * pixelRatio) { + rc.bottom = rc.top + minHeight * pixelRatio; + } + } + + void FreezePosition(SettingsRef settings, const std::string &key) override { + sscheck(GetWindowPlacement(hWindow, &placement)); + + BOOL isMaximized; + sscheck(isMaximized = IsZoomed(hWindow)); + + RECT rc = placement.rcNormalPosition; + settings->FreezeInt(key + "_Left", rc.left); + settings->FreezeInt(key + "_Right", rc.right); + settings->FreezeInt(key + "_Top", rc.top); + settings->FreezeInt(key + "_Bottom", rc.bottom); + settings->FreezeBool(key + "_Maximized", isMaximized == TRUE); + } + + void ThawPosition(SettingsRef settings, const std::string &key) override { + sscheck(GetWindowPlacement(hWindow, &placement)); + + RECT rc = placement.rcNormalPosition; + rc.left = settings->ThawInt(key + "_Left", rc.left); + rc.right = settings->ThawInt(key + "_Right", rc.right); + rc.top = settings->ThawInt(key + "_Top", rc.top); + rc.bottom = settings->ThawInt(key + "_Bottom", rc.bottom); + + MONITORINFO mi; + mi.cbSize = sizeof(mi); + sscheck(GetMonitorInfo(MonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST), &mi)); + + // If it somehow ended up off-screen, then put it back. + RECT mrc = mi.rcMonitor; + rc.left = Clamp(rc.left, mrc.left, mrc.right); + rc.right = Clamp(rc.right, mrc.left, mrc.right); + rc.top = Clamp(rc.top, mrc.top, mrc.bottom); + rc.bottom = Clamp(rc.bottom, mrc.top, mrc.bottom); + + // And make sure the minimum size is respected. (We can freeze a size smaller + // than minimum size if the DPI changed between runs.) + sscheck(SendMessageW(hWindow, WM_SIZING, WMSZ_BOTTOMRIGHT, (LPARAM)&rc)); + + placement.flags = 0; + if(settings->ThawBool(key + "_Maximized", false)) { + placement.showCmd = SW_SHOWMAXIMIZED; + } else { + placement.showCmd = SW_SHOW; + } + placement.rcNormalPosition = rc; + sscheck(SetWindowPlacement(hWindow, &placement)); + } + + void SetCursor(Cursor cursor) override { + LPWSTR cursorName = IDC_ARROW; + switch(cursor) { + case Cursor::POINTER: cursorName = IDC_ARROW; break; + case Cursor::HAND: cursorName = IDC_HAND; break; + } + + HCURSOR hCursor; + sscheck(hCursor = LoadCursorW(NULL, cursorName)); + sscheck(::SetCursor(hCursor)); + } + + void SetTooltip(const std::string &newText, double x, double y, + double width, double height) override { + if(newText == tooltipText) return; + tooltipText = newText; + + if(!newText.empty()) { + int pixelRatio = GetDevicePixelRatio(); + RECT toolRect; + toolRect.left = (int)(x * pixelRatio); + toolRect.top = (int)(y * pixelRatio); + toolRect.right = toolRect.left + (int)(width * pixelRatio); + toolRect.bottom = toolRect.top + (int)(height * pixelRatio); + + std::wstring newTextW = Widen(newText); + TOOLINFOW ti = {}; + ti.cbSize = sizeof(ti); + ti.hwnd = hWindow; + ti.rect = toolRect; + ti.lpszText = &newTextW[0]; + sscheck(SendMessageW(hTooltip, TTM_UPDATETIPTEXTW, 0, (LPARAM)&ti)); + sscheck(SendMessageW(hTooltip, TTM_NEWTOOLRECTW, 0, (LPARAM)&ti)); + } + // The following SendMessage call sometimes fails with ERROR_ACCESS_DENIED for + // no discernible reason, but only on wine. + SendMessageW(hTooltip, TTM_ACTIVATE, !newText.empty(), 0); + } + + bool IsEditorVisible() override { + BOOL visible; + visible = IsWindowVisible(hEditor); + return visible == TRUE; + } + + void ShowEditor(double x, double y, double fontHeight, double minWidth, + bool isMonospace, const std::string &text) override { + if(IsEditorVisible()) return; + + int pixelRatio = GetDevicePixelRatio(); + + HFONT hFont = CreateFontW(-(LONG)fontHeight * GetDevicePixelRatio(), 0, 0, 0, + FW_REGULAR, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, + DEFAULT_QUALITY, FF_DONTCARE, isMonospace ? L"Lucida Console" : L"Arial"); + if(hFont == NULL) { + sscheck(hFont = (HFONT)GetStockObject(SYSTEM_FONT)); + } + sscheck(SendMessageW(hEditor, WM_SETFONT, (WPARAM)hFont, FALSE)); + sscheck(SendMessageW(hEditor, EM_SETMARGINS, EC_LEFTMARGIN|EC_RIGHTMARGIN, 0)); + + std::wstring textW = Widen(text); + + HDC hDc; + TEXTMETRICW tm; + SIZE ts; + sscheck(hDc = GetDC(hEditor)); + sscheck(SelectObject(hDc, hFont)); + sscheck(GetTextMetricsW(hDc, &tm)); + sscheck(GetTextExtentPoint32W(hDc, textW.c_str(), textW.length(), &ts)); + sscheck(ReleaseDC(hEditor, hDc)); + + RECT rc; + rc.left = (LONG)x * pixelRatio; + rc.top = (LONG)y * pixelRatio - tm.tmAscent; + // Add one extra char width to avoid scrolling. + rc.right = (LONG)x * pixelRatio + + std::max((LONG)minWidth * pixelRatio, ts.cx + tm.tmAveCharWidth); + rc.bottom = (LONG)y * pixelRatio + tm.tmDescent; + sscheck(ssAdjustWindowRectExForDpi(&rc, 0, /*bMenu=*/FALSE, WS_EX_CLIENTEDGE, + ssGetDpiForWindow(hWindow))); + + sscheck(MoveWindow(hEditor, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, + /*bRepaint=*/true)); + ShowWindow(hEditor, SW_SHOW); + if(!textW.empty()) { + sscheck(SendMessageW(hEditor, WM_SETTEXT, 0, (LPARAM)textW.c_str())); + sscheck(SendMessageW(hEditor, EM_SETSEL, 0, textW.length())); + sscheck(SetFocus(hEditor)); + } + } + + void HideEditor() override { + if(!IsEditorVisible()) return; + + ShowWindow(hEditor, SW_HIDE); + } + + void SetScrollbarVisible(bool visible) override { + scrollbarVisible = visible; + sscheck(ShowScrollBar(hWindow, SB_VERT, visible)); + } + + void ConfigureScrollbar(double min, double max, double pageSize) override { + SCROLLINFO si = {}; + si.cbSize = sizeof(si); + si.fMask = SIF_RANGE|SIF_PAGE; + si.nMin = (UINT)(min * SCROLLBAR_UNIT); + si.nMax = (UINT)(max * SCROLLBAR_UNIT); + si.nPage = (UINT)(pageSize * SCROLLBAR_UNIT); + SetScrollInfo(hWindow, SB_VERT, &si, /*redraw=*/TRUE); // Returns scrollbar position + } + + double GetScrollbarPosition() override { + if(!scrollbarVisible) return 0.0; + + SCROLLINFO si = {}; + si.cbSize = sizeof(si); + si.fMask = SIF_POS; + sscheck(GetScrollInfo(hWindow, SB_VERT, &si)); + return (double)si.nPos / SCROLLBAR_UNIT; + } + + void SetScrollbarPosition(double pos) override { + if(!scrollbarVisible) return; + + SCROLLINFO si = {}; + si.cbSize = sizeof(si); + si.fMask = SIF_POS; + sscheck(GetScrollInfo(hWindow, SB_VERT, &si)); + if(si.nPos == (int)(pos * SCROLLBAR_UNIT)) + return; + + si.nPos = (int)(pos * SCROLLBAR_UNIT); + SetScrollInfo(hWindow, SB_VERT, &si, /*redraw=*/TRUE); // Returns scrollbar position + + // Windows won't synthesize a WM_VSCROLL for us here. + if(onScrollbarAdjusted) { + onScrollbarAdjusted((double)si.nPos / SCROLLBAR_UNIT); + } + } + + void Invalidate() override { + sscheck(InvalidateRect(hWindow, NULL, /*bErase=*/FALSE)); + } +}; + +#if HAVE_OPENGL == 3 +EGLDisplay WindowImplWin32::eglDisplay = EGL_NO_DISPLAY; +#endif + +WindowRef CreateWindow(Window::Kind kind, WindowRef parentWindow) { + return std::make_shared(kind, + std::static_pointer_cast(parentWindow)); +} + +//----------------------------------------------------------------------------- +// 3DConnexion support +//----------------------------------------------------------------------------- + +#if defined(HAVE_SPACEWARE) +static HWND hSpaceWareDriverClass; + +void Open3DConnexion() { + hSpaceWareDriverClass = FindWindowW(L"SpaceWare Driver Class", NULL); + if(hSpaceWareDriverClass != NULL) { + SiInitialize(); + } +} + +void Close3DConnexion() { + if(hSpaceWareDriverClass != NULL) { + SiTerminate(); + } +} + +void Request3DConnexionEventsForWindow(WindowRef window) { + std::shared_ptr windowImpl = + std::static_pointer_cast(window); + if(hSpaceWareDriverClass != NULL) { + SiOpenWinInit(&windowImpl->sod, windowImpl->hWindow); + windowImpl->hSpaceWare = SiOpen("SolveSpace", SI_ANY_DEVICE, SI_NO_MASK, SI_EVENT, + &windowImpl->sod); + SiSetUiMode(windowImpl->hSpaceWare, SI_UI_NO_CONTROLS); + } +} +#else +void Open3DConnexion() {} +void Close3DConnexion() {} +void Request3DConnexionEventsForWindow(WindowRef window) {} +#endif + +//----------------------------------------------------------------------------- +// Message dialogs +//----------------------------------------------------------------------------- + +class MessageDialogImplWin32 final : public MessageDialog { +public: + MSGBOXPARAMSW mbp = {}; + + int style; + + std::wstring titleW; + std::wstring messageW; + std::wstring descriptionW; + std::wstring textW; + + std::vector buttons; + int defaultButton; + + MessageDialogImplWin32() { + mbp.cbSize = sizeof(mbp); + SetTitle("Message"); + } + + void SetType(Type type) override { + switch(type) { + case Type::INFORMATION: + style = MB_USERICON; // Avoid beep + mbp.hInstance = GetModuleHandle(NULL); + mbp.lpszIcon = MAKEINTRESOURCE(4000); // Use SolveSpace icon + // mbp.lpszIcon = IDI_INFORMATION; + break; + + case Type::QUESTION: + style = MB_ICONQUESTION; + break; + + case Type::WARNING: + style = MB_ICONWARNING; + break; + + case Type::ERROR: + style = MB_USERICON; // Avoid beep + mbp.hInstance = GetModuleHandle(NULL); + mbp.lpszIcon = MAKEINTRESOURCE(4000); // Use SolveSpace icon + // mbp.lpszIcon = IDI_ERROR; + break; + } + } + + void SetTitle(std::string title) override { + titleW = PrepareTitle(title); + mbp.lpszCaption = titleW.c_str(); + } + + void SetMessage(std::string message) override { + messageW = Widen(message); + UpdateText(); + } + + void SetDescription(std::string description) override { + descriptionW = Widen(description); + UpdateText(); + } + + void UpdateText() { + textW = messageW + L"\n\n" + descriptionW; + mbp.lpszText = textW.c_str(); + } + + void AddButton(std::string _label, Response response, bool isDefault) override { + int button; + switch(response) { + case Response::NONE: ssassert(false, "Invalid response"); + case Response::OK: button = IDOK; break; + case Response::YES: button = IDYES; break; + case Response::NO: button = IDNO; break; + case Response::CANCEL: button = IDCANCEL; break; + } + buttons.push_back(button); + if(isDefault) { + defaultButton = button; + } + } + + Response RunModal() override { + mbp.dwStyle = style; + + std::sort(buttons.begin(), buttons.end()); + if(buttons == std::vector({ IDOK })) { + mbp.dwStyle |= MB_OK; + } else if(buttons == std::vector({ IDOK, IDCANCEL })) { + mbp.dwStyle |= MB_OKCANCEL; + } else if(buttons == std::vector({ IDYES, IDNO })) { + mbp.dwStyle |= MB_YESNO; + } else if(buttons == std::vector({ IDCANCEL, IDYES, IDNO })) { + mbp.dwStyle |= MB_YESNOCANCEL; + } else { + ssassert(false, "Unexpected button set"); + } + + switch(MessageBoxIndirectW(&mbp)) { + case IDOK: return Response::OK; break; + case IDYES: return Response::YES; break; + case IDNO: return Response::NO; break; + case IDCANCEL: return Response::CANCEL; break; + default: ssassert(false, "Unexpected response"); + } + } +}; + +MessageDialogRef CreateMessageDialog(WindowRef parentWindow) { + std::shared_ptr dialog = std::make_shared(); + dialog->mbp.hwndOwner = std::static_pointer_cast(parentWindow)->hWindow; + return dialog; +} + +//----------------------------------------------------------------------------- +// File dialogs +//----------------------------------------------------------------------------- + +class FileDialogImplWin32 final : public FileDialog { +public: + OPENFILENAMEW ofn = {}; + bool isSaveDialog; + std::wstring titleW; + std::wstring filtersW; + std::wstring defExtW; + std::wstring initialDirW; + // UNC paths may be as long as 32767 characters. + // Unfortunately, the Get*FileName API does not provide any way to use it + // except with a preallocated buffer of fixed size, so we use something + // reasonably large. + wchar_t filenameWC[32768] = {}; + + FileDialogImplWin32() { + ofn.lStructSize = sizeof(ofn); + ofn.lpstrFile = filenameWC; + ofn.nMaxFile = sizeof(filenameWC) / sizeof(wchar_t); + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | + OFN_OVERWRITEPROMPT; + if(isSaveDialog) { + SetTitle(C_("title", "Save File")); + } else { + SetTitle(C_("title", "Open File")); + } + } + + void SetTitle(std::string title) override { + titleW = PrepareTitle(title); + ofn.lpstrTitle = titleW.c_str(); + } + + void SetCurrentName(std::string name) override { + SetFilename(GetFilename().Parent().Join(name)); + } + + Platform::Path GetFilename() override { + return Path::From(Narrow(filenameWC)); + } + + void SetFilename(Platform::Path path) override { + wcsncpy(filenameWC, Widen(path.raw).c_str(), sizeof(filenameWC) / sizeof(wchar_t) - 1); + } + + void SuggestFilename(Platform::Path path) override { + SetFilename(Platform::Path::From(path.FileStem())); + } + + void AddFilter(std::string name, std::vector extensions) override { + std::string desc, patterns; + for(auto extension : extensions) { + std::string pattern = "*." + extension; + if(!desc.empty()) desc += ", "; + desc += pattern; + if(!patterns.empty()) patterns += ";"; + patterns += pattern; + } + filtersW += Widen(name + " (" + desc + ")" + '\0' + patterns + '\0'); + ofn.lpstrFilter = filtersW.c_str(); + if(ofn.lpstrDefExt == NULL) { + defExtW = Widen(extensions.front()); + ofn.lpstrDefExt = defExtW.c_str(); + } + } + + void FreezeChoices(SettingsRef settings, const std::string &key) override { + settings->FreezeString("Dialog_" + key + "_Folder", GetFilename().Parent().raw); + settings->FreezeInt("Dialog_" + key + "_Filter", ofn.nFilterIndex); + } + + void ThawChoices(SettingsRef settings, const std::string &key) override { + initialDirW = Widen(settings->ThawString("Dialog_" + key + "_Folder", "")); + ofn.lpstrInitialDir = initialDirW.c_str(); + ofn.nFilterIndex = settings->ThawInt("Dialog_" + key + "_Filter", 0); + } + + bool RunModal() override { + if(GetFilename().IsEmpty()) { + SetFilename(Path::From(_("untitled"))); + } + + if(isSaveDialog) { + return GetSaveFileNameW(&ofn) == TRUE; + } else { + return GetOpenFileNameW(&ofn) == TRUE; + } + } +}; + +FileDialogRef CreateOpenFileDialog(WindowRef parentWindow) { + std::shared_ptr dialog = std::make_shared(); + dialog->ofn.hwndOwner = std::static_pointer_cast(parentWindow)->hWindow; + dialog->isSaveDialog = false; + return dialog; +} + +FileDialogRef CreateSaveFileDialog(WindowRef parentWindow) { + std::shared_ptr dialog = std::make_shared(); + dialog->ofn.hwndOwner = std::static_pointer_cast(parentWindow)->hWindow; + dialog->isSaveDialog = true; + return dialog; +} + +//----------------------------------------------------------------------------- +// Application-wide APIs +//----------------------------------------------------------------------------- + +std::vector GetFontFiles() { + std::vector fonts; + + std::wstring fontsDirW(MAX_PATH, '\0'); + fontsDirW.resize(GetWindowsDirectoryW(&fontsDirW[0], fontsDirW.length())); + fontsDirW += L"\\fonts\\"; + Platform::Path fontsDir = Platform::Path::From(Narrow(fontsDirW)); + + WIN32_FIND_DATAW wfd; + HANDLE h = FindFirstFileW((fontsDirW + L"*").c_str(), &wfd); + while(h != INVALID_HANDLE_VALUE) { + fonts.push_back(fontsDir.Join(Narrow(wfd.cFileName))); + if(!FindNextFileW(h, &wfd)) break; + } + + return fonts; +} + +void OpenInBrowser(const std::string &url) { + ShellExecuteW(NULL, L"open", Widen(url).c_str(), NULL, NULL, SW_SHOWNORMAL); +} + +std::vector InitGui(int argc, char **argv) { + std::vector args = InitCli(argc, argv); + + INITCOMMONCONTROLSEX icc; + icc.dwSize = sizeof(icc); + icc.dwICC = ICC_STANDARD_CLASSES|ICC_BAR_CLASSES; + InitCommonControlsEx(&icc); + + if(!SetLocale((uint16_t)GetUserDefaultLCID())) { + SetLocale("en_US"); + } + + return args; +} + +void RunGui() { + MSG msg; + // The return value of the following functions doesn't indicate success or failure. + while(GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } +} + +void ExitGui() { + PostQuitMessage(0); +} + +void ClearGui() {} + +} +} diff --git a/src/platform/platform.cpp b/src/platform/platform.cpp new file mode 100644 index 0000000..0085413 --- /dev/null +++ b/src/platform/platform.cpp @@ -0,0 +1,715 @@ +//----------------------------------------------------------------------------- +// Platform-dependent functionality. +// +// Copyright 2017 whitequark +//----------------------------------------------------------------------------- +#if defined(__APPLE__) +// Include Apple headers before solvespace.h to avoid identifier clashes. +# include +# include +# include +#endif +#include "solvespace.h" +#include "mimalloc.h" +#include "config.h" +#if defined(WIN32) +// Conversely, include Microsoft headers after solvespace.h to avoid clashes. +# include +# include +#else +# include +# include +#endif + +namespace SolveSpace { +namespace Platform { + +//----------------------------------------------------------------------------- +// UTF-8 ⟷ UTF-16 conversion, on Windows. +//----------------------------------------------------------------------------- + +#if defined(WIN32) + +std::string Narrow(const wchar_t *in) +{ + std::string out; + DWORD len = WideCharToMultiByte(CP_UTF8, 0, in, -1, NULL, 0, NULL, NULL); + out.resize(len - 1); + ssassert(WideCharToMultiByte(CP_UTF8, 0, in, -1, &out[0], len, NULL, NULL), + "Invalid UTF-16"); + return out; +} + +std::string Narrow(const std::wstring &in) +{ + if(in == L"") return ""; + + std::string out; + out.resize(WideCharToMultiByte(CP_UTF8, 0, &in[0], (int)in.length(), + NULL, 0, NULL, NULL)); + ssassert(WideCharToMultiByte(CP_UTF8, 0, &in[0], (int)in.length(), + &out[0], (int)out.length(), NULL, NULL), + "Invalid UTF-16"); + return out; +} + +std::wstring Widen(const char *in) +{ + std::wstring out; + DWORD len = MultiByteToWideChar(CP_UTF8, 0, in, -1, NULL, 0); + out.resize(len - 1); + ssassert(MultiByteToWideChar(CP_UTF8, 0, in, -1, &out[0], len), + "Invalid UTF-8"); + return out; +} + +std::wstring Widen(const std::string &in) +{ + if(in == "") return L""; + + std::wstring out; + out.resize(MultiByteToWideChar(CP_UTF8, 0, &in[0], (int)in.length(), NULL, 0)); + ssassert(MultiByteToWideChar(CP_UTF8, 0, &in[0], (int)in.length(), + &out[0], (int)out.length()), + "Invalid UTF-8"); + return out; +} + +#endif + +//----------------------------------------------------------------------------- +// Path utility functions. +//----------------------------------------------------------------------------- + +static std::vector Split(const std::string &joined, char separator) { + std::vector parts; + + size_t oldpos = 0, pos = 0; + while(true) { + oldpos = pos; + pos = joined.find(separator, pos); + if(pos == std::string::npos) break; + parts.push_back(joined.substr(oldpos, pos - oldpos)); + pos += 1; + } + + if(oldpos != joined.length() - 1) { + parts.push_back(joined.substr(oldpos)); + } + + return parts; +} + +static std::string Concat(const std::vector &parts, char separator) { + std::string joined; + + bool first = true; + for(auto &part : parts) { + if(!first) joined += separator; + joined += part; + first = false; + } + + return joined; +} + +//----------------------------------------------------------------------------- +// Path manipulation. +//----------------------------------------------------------------------------- + +#if defined(WIN32) +const char SEPARATOR = '\\'; +#else +const char SEPARATOR = '/'; +#endif + +Path Path::From(std::string raw) { + Path path = { raw }; + return path; +} + +Path Path::CurrentDirectory() { +#if defined(WIN32) + // On Windows, OpenFile needs an absolute UNC path proper, so get that. + std::wstring rawW; + rawW.resize(GetCurrentDirectoryW(0, NULL)); + DWORD length = GetCurrentDirectoryW((int)rawW.length(), &rawW[0]); + ssassert(length > 0 && length == rawW.length() - 1, "Cannot get current directory"); + rawW.resize(length); + return From(Narrow(rawW)); +#else + char *raw = getcwd(NULL, 0); + ssassert(raw != NULL, "Cannot get current directory"); + Path path = From(raw); + free(raw); + return path; +#endif +} + +std::string Path::FileName() const { + std::string fileName = raw; + size_t slash = fileName.rfind(SEPARATOR); + if(slash != std::string::npos) { + fileName = fileName.substr(slash + 1); + } + return fileName; +} + +std::string Path::FileStem() const { + std::string baseName = FileName(); + size_t dot = baseName.rfind('.'); + if(dot != std::string::npos) { + baseName = baseName.substr(0, dot); + } + return baseName; +} + +std::string Path::Extension() const { + size_t dot = raw.rfind('.'); + if(dot != std::string::npos) { + return raw.substr(dot + 1); + } + return ""; +} + +bool Path::HasExtension(std::string theirExt) const { + std::string ourExt = Extension(); + std::transform(ourExt.begin(), ourExt.end(), ourExt.begin(), ::tolower); + std::transform(theirExt.begin(), theirExt.end(), theirExt.begin(), ::tolower); + return ourExt == theirExt; +} + +Path Path::WithExtension(std::string ext) const { + Path withExt = *this; + size_t dot = withExt.raw.rfind('.'); + if(dot != std::string::npos) { + withExt.raw.erase(dot); + } + if(!ext.empty()) { + withExt.raw += "."; + withExt.raw += ext; + } + return withExt; +} + +static void FindPrefix(const std::string &raw, size_t *pos) { + *pos = std::string::npos; +#if defined(WIN32) + if(raw.size() >= 7 && raw[2] == '?' && raw[3] == '\\' && + isalpha(raw[4]) && raw[5] == ':' && raw[6] == '\\') { + *pos = 7; + } else if(raw.size() >= 3 && isalpha(raw[0]) && raw[1] == ':' && raw[2] == '\\') { + *pos = 3; + } else if(raw.size() >= 2 && raw[0] == '\\' && raw[1] == '\\') { + size_t slashAt = raw.find('\\', 2); + if(slashAt != std::string::npos) { + *pos = raw.find('\\', slashAt + 1); + } + } +#else + if(!raw.empty() && raw[0] == '/') { + *pos = 1; + } +#endif +} + +bool Path::IsAbsolute() const { + size_t pos; + FindPrefix(raw, &pos); + return pos != std::string::npos; +} + +// Removes one component from the end of the path. +// Returns an empty path if the path consists only of a root. +Path Path::Parent() const { + Path parent = { raw }; + if(!parent.raw.empty() && parent.raw.back() == SEPARATOR) { + parent.raw.pop_back(); + } + size_t slash = parent.raw.rfind(SEPARATOR); + if(slash != std::string::npos) { + parent.raw = parent.raw.substr(0, slash + 1); + } else { + parent.raw.clear(); + } + if(IsAbsolute() && !parent.IsAbsolute()) { + return From(""); + } + return parent; +} + +// Concatenates a component to this path. +// Returns an empty path if this path or the component is empty. +Path Path::Join(const std::string &component) const { + ssassert(component.find(SEPARATOR) == std::string::npos, + "Use the Path::Join(const Path &) overload to append an entire path"); + return Join(Path::From(component)); +} + +// Concatenates a relative path to this path. +// Returns an empty path if either path is empty, or the other path is absolute. +Path Path::Join(const Path &other) const { + if(IsEmpty() || other.IsEmpty() || other.IsAbsolute()) { + return From(""); + } + + Path joined = { raw }; + if(joined.raw.back() != SEPARATOR) { + joined.raw += SEPARATOR; + } + joined.raw += other.raw; + return joined; +} + +// Expands the "." and ".." components in this path. +// On Windows, additionally prepends the UNC prefix to absolute paths without one. +// Returns an empty path if a ".." component would escape from the root. +Path Path::Expand(bool fromCurrentDirectory) const { + Path source; + Path expanded; + + if(fromCurrentDirectory && !IsAbsolute()) { + source = CurrentDirectory().Join(*this); + } else { + source = *this; + } + + size_t splitAt; + FindPrefix(source.raw, &splitAt); + if(splitAt != std::string::npos) { + expanded.raw = source.raw.substr(0, splitAt); + } else { + splitAt = 0; + } + + std::vector expandedComponents; + for(std::string component : Split(source.raw.substr(splitAt), SEPARATOR)) { + if(component == ".") { + // skip + } else if(component == "..") { + if(!expandedComponents.empty()) { + expandedComponents.pop_back(); + } else { + return From(""); + } + } else if(!component.empty()) { + expandedComponents.push_back(component); + } + } + + if(expanded.IsEmpty()) { + if(expandedComponents.empty()) { + expandedComponents.emplace_back("."); + } + expanded = From(Concat(expandedComponents, SEPARATOR)); + } else if(!expandedComponents.empty()) { + expanded = expanded.Join(From(Concat(expandedComponents, SEPARATOR))); + } + +#if defined(WIN32) + if(expanded.IsAbsolute() && expanded.raw.substr(0, 2) != "\\\\") { + expanded.raw = "\\\\?\\" + expanded.raw; + } +#endif + + return expanded; +} + +static std::string FilesystemNormalize(const std::string &str) { +#if defined(WIN32) + std::wstring strW = Widen(str); + std::transform(strW.begin(), strW.end(), strW.begin(), towlower); + return Narrow(strW); +#elif defined(__APPLE__) + CFMutableStringRef cfStr = + CFStringCreateMutableCopy(NULL, 0, + CFStringCreateWithBytesNoCopy(NULL, (const UInt8*)str.data(), str.size(), + kCFStringEncodingUTF8, /*isExternalRepresentation=*/false, kCFAllocatorNull)); + CFStringLowercase(cfStr, NULL); + std::string normalizedStr; + normalizedStr.resize(CFStringGetMaximumSizeOfFileSystemRepresentation(cfStr)); + CFStringGetFileSystemRepresentation(cfStr, &normalizedStr[0], normalizedStr.size()); + normalizedStr.erase(normalizedStr.find('\0')); + return normalizedStr; +#else + return str; +#endif +} + +bool Path::Equals(const Path &other) const { + return FilesystemNormalize(raw) == FilesystemNormalize(other.raw); +} + +// Returns a relative path from a given base path. +// Returns an empty path if any of the paths is not absolute, or +// if they belong to different roots, or +// if they cannot be expanded. +Path Path::RelativeTo(const Path &base) const { + Path expanded = Expand(); + Path baseExpanded = base.Expand(); + if(!(expanded.IsAbsolute() && baseExpanded.IsAbsolute())){ + return From(""); + } + + size_t splitAt; + FindPrefix(expanded.raw, &splitAt); + size_t baseSplitAt; + FindPrefix(baseExpanded.raw, &baseSplitAt); + if(FilesystemNormalize(expanded.raw.substr(0, splitAt)) != + FilesystemNormalize(baseExpanded.raw.substr(0, splitAt))) { + return From(""); + } + + std::vector components = + Split(expanded.raw.substr(splitAt), SEPARATOR); + std::vector baseComponents = + Split(baseExpanded.raw.substr(baseSplitAt), SEPARATOR); + size_t common; + for(common = 0; common < baseComponents.size() && + common < components.size(); common++) { + if(FilesystemNormalize(baseComponents[common]) != + FilesystemNormalize(components[common])) { + break; + } + } + + std::vector resultComponents; + for(size_t i = common; i < baseComponents.size(); i++) { + resultComponents.emplace_back(".."); + } + resultComponents.insert(resultComponents.end(), + components.begin() + common, components.end()); + if(resultComponents.empty()) { + resultComponents.emplace_back("."); + } + return From(Concat(resultComponents, SEPARATOR)); +} + +Path Path::FromPortable(const std::string &repr) { + return From(Concat(Split(repr, '/'), SEPARATOR)); +} + +std::string Path::ToPortable() const { + ssassert(!IsAbsolute(), "absolute paths cannot be made portable"); + + return Concat(Split(raw, SEPARATOR), '/'); +} + +//----------------------------------------------------------------------------- +// File manipulation. +//----------------------------------------------------------------------------- + +FILE *OpenFile(const Platform::Path &filename, const char *mode) { + ssassert(filename.raw.length() == strlen(filename.raw.c_str()), + "Unexpected null byte in middle of a path"); +#if defined(WIN32) + return _wfopen(Widen(filename.Expand(/*fromCurrentDirectory=*/true).raw).c_str(), Widen(mode).c_str()); +#else + return fopen(filename.raw.c_str(), mode); +#endif +} + +bool FileExists(const Platform::Path &filename) { + FILE *f = OpenFile(filename, "rb"); + if(f == NULL) return false; + fclose(f); + return true; +} + +void RemoveFile(const Platform::Path &filename) { + ssassert(filename.raw.length() == strlen(filename.raw.c_str()), + "Unexpected null byte in middle of a path"); +#if defined(WIN32) + _wremove(Widen(filename.Expand().raw).c_str()); +#else + remove(filename.raw.c_str()); +#endif +} + +bool ReadFile(const Platform::Path &filename, std::string *data) { + FILE *f = OpenFile(filename, "rb"); + if(f == NULL) return false; + + if(fseek(f, 0, SEEK_END) != 0) + return false; + data->resize(ftell(f)); + if(fseek(f, 0, SEEK_SET) != 0) + return false; + if(fread(&(*data)[0], 1, data->size(), f) != data->size()) + return false; + if(fclose(f) != 0) + return false; + + return true; +} + +bool WriteFile(const Platform::Path &filename, const std::string &data) { + FILE *f = OpenFile(filename, "wb"); + if(f == NULL) return false; + + if(fwrite(&data[0], 1, data.size(), f) != data.size()) + return false; + if(fclose(f) != 0) + return false; + + return true; +} + +//----------------------------------------------------------------------------- +// Loading resources, on Windows. +//----------------------------------------------------------------------------- + +#if defined(WIN32) + +const void *LoadResource(const std::string &name, size_t *size) { + HRSRC hres = FindResourceW(NULL, Widen(name).c_str(), RT_RCDATA); + ssassert(hres != NULL, "Cannot find resource"); + HGLOBAL res = ::LoadResource(NULL, hres); + ssassert(res != NULL, "Cannot load resource"); + + *size = SizeofResource(NULL, hres); + return LockResource(res); +} + +#endif + +//----------------------------------------------------------------------------- +// Loading resources, on *nix. +//----------------------------------------------------------------------------- + +#if defined(__APPLE__) + +static Platform::Path PathFromCFURL(CFURLRef cfUrl) { + Path path; + CFStringRef cfPath = CFURLCopyFileSystemPath(cfUrl, kCFURLPOSIXPathStyle); + path.raw.resize(CFStringGetMaximumSizeOfFileSystemRepresentation(cfPath)); + CFStringGetFileSystemRepresentation(cfPath, &path.raw[0], path.raw.size()); + path.raw.erase(path.raw.find('\0')); + CFRelease(cfPath); + return path; +} + +static Platform::Path ResourcePath(const std::string &name) { + Path path; + + // First, try to get the URL from the bundle. + CFStringRef cfName = CFStringCreateWithCString(kCFAllocatorDefault, name.c_str(), + kCFStringEncodingUTF8); + CFURLRef cfUrl = CFBundleCopyResourceURL(CFBundleGetMainBundle(), cfName, NULL, NULL); + if(cfUrl != NULL) { + path = PathFromCFURL(cfUrl); + CFRelease(cfUrl); + } + CFRelease(cfName); + + if(!path.IsEmpty()) return path; + + // If that failed, it means we aren't running from the bundle. + // Reference off the executable path, then. + cfUrl = CFBundleCopyExecutableURL(CFBundleGetMainBundle()); + if(cfUrl != NULL) { + path = PathFromCFURL(cfUrl).Parent().Parent().Join("res"); + path = path.Join(Path::FromPortable(name)); + CFRelease(cfUrl); + } + + return path; +} + +#elif !defined(WIN32) + +# if defined(__linux__) +static const char *selfSymlink = "/proc/self/exe"; +# elif defined(__NetBSD__) +static const char *selfSymlink = "/proc/curproc/exe"; +# elif defined(__OpenBSD__) || defined(__FreeBSD__) +static const char *selfSymlink = "/proc/curproc/file"; +# else +static const char *selfSymlink = ""; +# endif + +static Platform::Path FindLocalResourceDir() { + // Find out the path to the running binary. + Platform::Path selfPath; + char *expandedSelfPath = realpath(selfSymlink, NULL); + if(expandedSelfPath != NULL) { + selfPath = Path::From(expandedSelfPath); + } + free(expandedSelfPath); + + Platform::Path resourceDir; + if(selfPath.IsEmpty()) { + // We don't know how to find the local resource directory on this platform, + // so use the global one (by returning an empty string). + return Path::From(UNIX_DATADIR); + } else { + resourceDir = selfPath.Parent().Parent().Join("res"); + } + + struct stat st; + if(stat(resourceDir.raw.c_str(), &st) != -1) { + // An executable-adjacent resource directory exists, good. + return resourceDir; + } + + resourceDir = selfPath.Parent().Parent().Join("share").Join("solvespace"); + if(stat(resourceDir.raw.c_str(), &st) != -1) { + // A resource directory exists at a relative path, good. + return resourceDir; + } + + // No executable-adjacent resource directory; use the one from compile-time prefix. + return Path::From(UNIX_DATADIR); +} + +static Platform::Path ResourcePath(const std::string &name) { + static Platform::Path resourceDir; + if(resourceDir.IsEmpty()) { + resourceDir = FindLocalResourceDir(); + } + + return resourceDir.Join(Path::FromPortable(name)); +} + +#endif + +#if !defined(WIN32) + +const void *LoadResource(const std::string &name, size_t *size) { + static std::map cache; + + auto it = cache.find(name); + if(it == cache.end()) { + ssassert(ReadFile(ResourcePath(name), &cache[name]), "Cannot read resource"); + it = cache.find(name); + } + + const std::string &content = (*it).second; + *size = content.size(); + return (const void*)content.data(); +} + +#endif + +//----------------------------------------------------------------------------- +// Startup and command-line argument handling, on Windows. +//----------------------------------------------------------------------------- + +#if defined(WIN32) + +std::vector InitCli(int argc, char **argv) { +#if defined(_MSC_VER) + // We display our own message on abort; just call ReportFault. + _set_abort_behavior(_CALL_REPORTFAULT, _WRITE_ABORT_MSG|_CALL_REPORTFAULT); + int crtReportTypes[] = {_CRT_WARN, _CRT_ERROR, _CRT_ASSERT}; + for(int crtReportType : crtReportTypes) { + _CrtSetReportMode(crtReportType, _CRTDBG_MODE_FILE|_CRTDBG_MODE_DEBUG); + _CrtSetReportFile(crtReportType, _CRTDBG_FILE_STDERR); + } +#endif + + // Extract the command-line arguments; the ones from main() are ignored, + // since they are in the OEM encoding. + int argcW; + LPWSTR *argvW = CommandLineToArgvW(GetCommandLineW(), &argcW); + std::vector args; + for(int i = 0; i < argcW; i++) + args.push_back(Platform::Narrow(argvW[i])); + LocalFree(argvW); + return args; +} + +#endif + +//----------------------------------------------------------------------------- +// Startup and command-line argument handling, on *nix. +//----------------------------------------------------------------------------- + +#if !defined(WIN32) + +std::vector InitCli(int argc, char **argv) { + return {&argv[0], &argv[argc]}; +} + +#endif + +//----------------------------------------------------------------------------- +// Debug output, on Windows. +//----------------------------------------------------------------------------- + +#if defined(WIN32) + +void DebugPrint(const char *fmt, ...) +{ + va_list va; + va_start(va, fmt); + int len = _vscprintf(fmt, va) + 1; + va_end(va); + + va_start(va, fmt); + char *buf = (char *)_alloca(len); + _vsnprintf(buf, len, fmt, va); + va_end(va); + + // The native version of OutputDebugString, unlike most others, + // is OutputDebugStringA. + OutputDebugStringA(buf); + OutputDebugStringA("\n"); + +#ifndef NDEBUG + // Duplicate to stderr in debug builds, but not in release; this is slow. + fputs(buf, stderr); + fputc('\n', stderr); +#endif +} + +#endif + +//----------------------------------------------------------------------------- +// Debug output, on *nix. +//----------------------------------------------------------------------------- + +#if !defined(WIN32) + +void DebugPrint(const char *fmt, ...) { + va_list va; + va_start(va, fmt); + vfprintf(stderr, fmt, va); + fputc('\n', stderr); + va_end(va); +} + +#endif + +//----------------------------------------------------------------------------- +// Temporary arena. +//----------------------------------------------------------------------------- + +struct MimallocHeap { + mi_heap_t *heap = NULL; + + ~MimallocHeap() { + if(heap != NULL) + mi_heap_destroy(heap); + } +}; + +static thread_local MimallocHeap TempArena; + +void *AllocTemporary(size_t size) { + if(TempArena.heap == NULL) { + TempArena.heap = mi_heap_new(); + ssassert(TempArena.heap != NULL, "out of memory"); + } + void *ptr = mi_heap_zalloc(TempArena.heap, size); + ssassert(ptr != NULL, "out of memory"); + return ptr; +} + +void FreeAllTemporary() { + MimallocHeap temp; + std::swap(TempArena.heap, temp.heap); +} + +} +} diff --git a/src/platform/platform.h b/src/platform/platform.h new file mode 100644 index 0000000..21c2b2b --- /dev/null +++ b/src/platform/platform.h @@ -0,0 +1,85 @@ +//----------------------------------------------------------------------------- +// Platform-dependent functionality. +// +// Copyright 2017 whitequark +//----------------------------------------------------------------------------- + +#ifndef SOLVESPACE_PLATFORM_H +#define SOLVESPACE_PLATFORM_H + +namespace Platform { + +// UTF-8 ⟷ UTF-16 conversion, for Windows. +#if defined(WIN32) +std::string Narrow(const wchar_t *s); +std::wstring Widen(const char *s); +std::string Narrow(const std::wstring &s); +std::wstring Widen(const std::string &s); +#endif + +#if defined(_WIN32) + const std::string embeddedFont = "res://fonts/BitstreamVeraSans-Roman-builtin.ttf"; +#else // Linux and macOS + const std::string embeddedFont = "BitstreamVeraSans-Roman-builtin.ttf"; +#endif + +// A filesystem path, respecting the conventions of the current platform. +// Transformation functions return an empty path on error. +class Path { +public: + std::string raw; + + static Path From(std::string raw); + static Path CurrentDirectory(); + + void Clear() { raw.clear(); } + + bool Equals(const Path &other) const; + bool IsEmpty() const { return raw.empty(); } + bool IsAbsolute() const; + bool HasExtension(std::string ext) const; + + std::string FileName() const; + std::string FileStem() const; + std::string Extension() const; + + Path WithExtension(std::string ext) const; + Path Parent() const; + Path Join(const std::string &component) const; + Path Join(const Path &other) const; + Path Expand(bool fromCurrentDirectory = false) const; + Path RelativeTo(const Path &base) const; + + // Converting to and from a platform-independent representation + // (conventionally, the Unix one). + static Path FromPortable(const std::string &repr); + std::string ToPortable() const; +}; + +struct PathLess { + bool operator()(const Path &a, const Path &b) const { return a.raw < b.raw; } +}; + +// File manipulation functions. +bool FileExists(const Platform::Path &filename); +FILE *OpenFile(const Platform::Path &filename, const char *mode); +bool ReadFile(const Platform::Path &filename, std::string *data); +bool WriteFile(const Platform::Path &filename, const std::string &data); +void RemoveFile(const Platform::Path &filename); + +// Resource loading function. +const void *LoadResource(const std::string &name, size_t *size); + +// Startup and command-line argument handling. +std::vector InitCli(int argc, char **argv); + +// Debug print function. +void DebugPrint(const char *fmt, ...); + +// Temporary arena functions. +void *AllocTemporary(size_t size); +void FreeAllTemporary(); + +} + +#endif diff --git a/src/polygon.cpp b/src/polygon.cpp new file mode 100644 index 0000000..f325fd9 --- /dev/null +++ b/src/polygon.cpp @@ -0,0 +1,921 @@ +//----------------------------------------------------------------------------- +// Operations on polygons (planar, of line segment edges). +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +Vector STriangle::Normal() const { + Vector ab = b.Minus(a), bc = c.Minus(b); + return ab.Cross(bc); +} + +double STriangle::MinAltitude() const { + double altA = a.DistanceToLine(b, c.Minus(b)), + altB = b.DistanceToLine(c, a.Minus(c)), + altC = c.DistanceToLine(a, b.Minus(a)); + + return min(altA, min(altB, altC)); +} + +bool STriangle::ContainsPoint(Vector p) const { + Vector n = Normal(); + if(MinAltitude() < LENGTH_EPS) { + // shouldn't happen; zero-area triangle + return false; + } + return ContainsPointProjd(n.WithMagnitude(1), p); +} + +bool STriangle::ContainsPointProjd(Vector n, Vector p) const { + Vector ab = b.Minus(a), bc = c.Minus(b), ca = a.Minus(c); + + Vector no_ab = n.Cross(ab); + if(no_ab.Dot(p) < no_ab.Dot(a) - LENGTH_EPS) return false; + + Vector no_bc = n.Cross(bc); + if(no_bc.Dot(p) < no_bc.Dot(b) - LENGTH_EPS) return false; + + Vector no_ca = n.Cross(ca); + if(no_ca.Dot(p) < no_ca.Dot(c) - LENGTH_EPS) return false; + + return true; +} + +bool STriangle::Raytrace(const Vector &rayPoint, const Vector &rayDir, + double *t, Vector *inters) const { + // Algorithm from: "Fast, Minimum Storage Ray/Triangle Intersection" by + // Tomas Moeller and Ben Trumbore. + + // Find vectors for two edges sharing vertex A. + Vector edge1 = b.Minus(a); + Vector edge2 = c.Minus(a); + + // Begin calculating determinant - also used to calculate U parameter. + Vector pvec = rayDir.Cross(edge2); + + // If determinant is near zero, ray lies in plane of triangle. + // Also, cull back facing triangles here. + double det = edge1.Dot(pvec); + if(-det < LENGTH_EPS) return false; + double inv_det = 1.0f / det; + + // Calculate distance from vertex A to ray origin. + Vector tvec = rayPoint.Minus(a); + + // Calculate U parameter and test bounds. + double u = tvec.Dot(pvec) * inv_det; + if (u < 0.0f || u > 1.0f) return false; + + // Prepare to test V parameter. + Vector qvec = tvec.Cross(edge1); + + // Calculate V parameter and test bounds. + double v = rayDir.Dot(qvec) * inv_det; + if (v < 0.0f || u + v > 1.0f) return false; + + // Calculate t, ray intersects triangle. + *t = edge2.Dot(qvec) * inv_det; + + // Calculate intersection point. + if(inters != NULL) *inters = rayPoint.Plus(rayDir.ScaledBy(*t)); + + return true; +} + +double STriangle::SignedVolume() const { + return a.Dot(b.Cross(c)) / 6.0; +} + +double STriangle::Area() const { + Vector ab = a.Minus(b); + Vector cb = c.Minus(b); + return ab.Cross(cb).Magnitude() / 2.0; +} + +bool STriangle::IsDegenerate() const { + return a.OnLineSegment(b, c) || + b.OnLineSegment(a, c) || + c.OnLineSegment(a, b); +} + +void STriangle::FlipNormal() { + swap(a, b); + swap(an, bn); +} + +STriangle STriangle::Transform(Vector u, Vector v, Vector n) const { + STriangle tr = *this; + tr.a = tr.a.ScaleOutOfCsys(u, v, n); + tr.an = tr.an.ScaleOutOfCsys(u, v, n); + tr.b = tr.b.ScaleOutOfCsys(u, v, n); + tr.bn = tr.bn.ScaleOutOfCsys(u, v, n); + tr.c = tr.c.ScaleOutOfCsys(u, v, n); + tr.cn = tr.cn.ScaleOutOfCsys(u, v, n); + return tr; +} + +STriangle STriangle::From(STriMeta meta, Vector a, Vector b, Vector c) { + STriangle tr = {}; + tr.meta = meta; + tr.a = a; + tr.b = b; + tr.c = c; + return tr; +} + +SEdge SEdge::From(Vector a, Vector b) { + SEdge se = {}; + se.a = a; + se.b = b; + return se; +} + +bool SEdge::EdgeCrosses(Vector ea, Vector eb, Vector *ppi, SPointList *spl) const { + Vector d = eb.Minus(ea); + double t_eps = LENGTH_EPS/d.Magnitude(); + + double t, tthis; + bool skew; + Vector pi; + bool inOrEdge0, inOrEdge1; + + Vector dthis = b.Minus(a); + double tthis_eps = LENGTH_EPS/dthis.Magnitude(); + + if((ea.Equals(a) && eb.Equals(b)) || + (eb.Equals(a) && ea.Equals(b))) + { + if(ppi) *ppi = a; + if(spl) spl->Add(a); + return true; + } + + // Can't just test if distance between d and a equals distance between d and b; + // they could be on opposite sides, since we don't have the sign. + double m = sqrt(d.Magnitude()*dthis.Magnitude()); + if(sqrt(fabs(d.Dot(dthis))) > (m - LENGTH_EPS)) { + // The edges are parallel. + if(fabs(a.DistanceToLine(ea, d)) > LENGTH_EPS) { + // and not coincident, so can't be intersecting + return false; + } + // The edges are coincident. Make sure that neither endpoint lies + // on the other + bool inters = false; + double t; + t = a.Minus(ea).DivProjected(d); + if(t > t_eps && t < (1 - t_eps)) inters = true; + t = b.Minus(ea).DivProjected(d); + if(t > t_eps && t < (1 - t_eps)) inters = true; + t = ea.Minus(a).DivProjected(dthis); + if(t > tthis_eps && t < (1 - tthis_eps)) inters = true; + t = eb.Minus(a).DivProjected(dthis); + if(t > tthis_eps && t < (1 - tthis_eps)) inters = true; + + if(inters) { + if(ppi) *ppi = a; + if(spl) spl->Add(a); + return true; + } else { + // So coincident but disjoint, okay. + return false; + } + } + + // Lines are not parallel, so look for an intersection. + pi = Vector::AtIntersectionOfLines(ea, eb, a, b, + &skew, + &t, &tthis); + if(skew) return false; + + inOrEdge0 = (t > -t_eps) && (t < (1 + t_eps)); + inOrEdge1 = (tthis > -tthis_eps) && (tthis < (1 + tthis_eps)); + + if(inOrEdge0 && inOrEdge1) { + if(a.Equals(ea) || b.Equals(ea) || + a.Equals(eb) || b.Equals(eb)) + { + // Not an intersection if we share an endpoint with an edge + return false; + } + // But it's an intersection if a vertex of one edge lies on the + // inside of the other (or if they cross away from either's + // vertex). + if(ppi) *ppi = pi; + if(spl) spl->Add(pi); + return true; + } + return false; +} + +void SEdgeList::Clear() { + l.Clear(); +} + +void SEdgeList::AddEdge(Vector a, Vector b, int auxA, int auxB, int tag) { + SEdge e = {}; + e.tag = tag; + e.a = a; + e.b = b; + e.auxA = auxA; + e.auxB = auxB; + l.Add(&e); +} + +bool SEdgeList::AssembleContour(Vector first, Vector last, SContour *dest, + SEdge *errorAt, bool keepDir, int start) const +{ + int i; + + dest->AddPoint(first); + dest->AddPoint(last); + + do { + for(i = start; i < l.n; i++) { + /// @todo fix const! + SEdge *se = const_cast(&(l[i])); + if(se->tag) continue; + + if(se->a.Equals(last)) { + dest->AddPoint(se->b); + last = se->b; + se->tag = 1; + break; + } + // Don't allow backwards edges if keepDir is true. + if(!keepDir && se->b.Equals(last)) { + dest->AddPoint(se->a); + last = se->a; + se->tag = 1; + break; + } + } + if(i >= l.n) { + // Couldn't assemble a closed contour; mark where. + if(errorAt) { + errorAt->a = first; + errorAt->b = last; + } + return false; + } + + } while(!last.Equals(first)); + + return true; +} + +bool SEdgeList::AssemblePolygon(SPolygon *dest, SEdge *errorAt, bool keepDir) const { + dest->Clear(); + + bool allClosed = true; + Vector first = Vector::From(0, 0, 0); + Vector last = Vector::From(0, 0, 0); + int i; + for(i = 0; i < l.n; i++) { + if(!l[i].tag) { + first = l[i].a; + last = l[i].b; + /// @todo fix const! + const_cast(&(l[i]))->tag = 1; + // Create a new empty contour in our polygon, and finish assembling + // into that contour. + dest->AddEmptyContour(); + if(!AssembleContour(first, last, dest->l.Last(), errorAt, keepDir, i+1)) { + allClosed = false; + } + // But continue assembling, even if some of the contours are open + } + } + return allClosed; +} + +//----------------------------------------------------------------------------- +// Test if the specified edge crosses any of the edges in our list. Two edges +// are not considered to cross if they share an endpoint (within LENGTH_EPS), +// but they are considered to cross if they are coincident and overlapping. +// If pi is not NULL, then a crossing is returned in that. +//----------------------------------------------------------------------------- +int SEdgeList::AnyEdgeCrossings(Vector a, Vector b, Vector *ppi, SPointList *spl) const { + auto cnt = std::count_if(l.begin(), l.end(), + [&](SEdge const &se) { return se.EdgeCrosses(a, b, ppi, spl); }); + return static_cast(cnt); +} + +//----------------------------------------------------------------------------- +// Returns true if the intersecting edge list contains an edge that shares +// an endpoint with one of our edges. +//----------------------------------------------------------------------------- +bool SEdgeList::ContainsEdgeFrom(const SEdgeList *sel) const { + for(const SEdge *se = l.First(); se; se = l.NextAfter(se)) { + if(sel->ContainsEdge(se)) return true; + } + return false; +} +bool SEdgeList::ContainsEdge(const SEdge *set) const { + for(const SEdge *se = l.First(); se; se = l.NextAfter(se)) { + if((se->a).Equals(set->a) && (se->b).Equals(set->b)) return true; + if((se->b).Equals(set->a) && (se->a).Equals(set->b)) return true; + } + return false; +} + +//----------------------------------------------------------------------------- +// Remove unnecessary edges: +// - if two are anti-parallel then +// if both=true, remove both +// else remove only one. +// - if two are parallel then remove one. +//----------------------------------------------------------------------------- +void SEdgeList::CullExtraneousEdges(bool both) { + l.ClearTags(); + for(int i = 0; i < l.n; i++) { + SEdge *se = &(l[i]); + for(int j = i + 1; j < l.n; j++) { + SEdge *set = &(l[j]); + if((set->a).Equals(se->a) && (set->b).Equals(se->b)) { + // Two parallel edges exist; so keep only the first one. + set->tag = 1; + } + if((set->a).Equals(se->b) && (set->b).Equals(se->a)) { + // Two anti-parallel edges exist; if both=true, keep neither, + // otherwise keep only one. + if (both) se->tag = 1; + set->tag = 1; + } + } + } + l.RemoveTagged(); +} + +//----------------------------------------------------------------------------- +// Make a kd-tree of edges. This is used for O(log(n)) implementations of stuff +// that would naively be O(n). +//----------------------------------------------------------------------------- +SKdNodeEdges *SKdNodeEdges::Alloc() { + SKdNodeEdges *ne = (SKdNodeEdges *)AllocTemporary(sizeof(SKdNodeEdges)); + *ne = {}; + return ne; +} +SEdgeLl *SEdgeLl::Alloc() { + SEdgeLl *sell = (SEdgeLl *)AllocTemporary(sizeof(SEdgeLl)); + *sell = {}; + return sell; +} +SKdNodeEdges *SKdNodeEdges::From(SEdgeList *sel) { + SEdgeLl *sell = NULL; + SEdge *se; + for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { + SEdgeLl *n = SEdgeLl::Alloc(); + n->se = se; + n->next = sell; + sell = n; + } + return SKdNodeEdges::From(sell); +} +SKdNodeEdges *SKdNodeEdges::From(SEdgeLl *sell) { + SKdNodeEdges *n = SKdNodeEdges::Alloc(); + + // Compute the midpoints (just mean, though median would be better) of + // each component. + Vector ptAve = Vector::From(0, 0, 0); + SEdgeLl *flip; + int totaln = 0; + for(flip = sell; flip; flip = flip->next) { + ptAve = ptAve.Plus(flip->se->a); + ptAve = ptAve.Plus(flip->se->b); + totaln++; + } + ptAve = ptAve.ScaledBy(1.0 / (2*totaln)); + + // For each component, see how it splits. + int ltln[3] = { 0, 0, 0 }, gtln[3] = { 0, 0, 0 }; + double badness[3]; + for(flip = sell; flip; flip = flip->next) { + for(int i = 0; i < 3; i++) { + if(flip->se->a.Element(i) < ptAve.Element(i) + KDTREE_EPS || + flip->se->b.Element(i) < ptAve.Element(i) + KDTREE_EPS) + { + ltln[i]++; + } + if(flip->se->a.Element(i) > ptAve.Element(i) - KDTREE_EPS || + flip->se->b.Element(i) > ptAve.Element(i) - KDTREE_EPS) + { + gtln[i]++; + } + } + } + for(int i = 0; i < 3; i++) { + badness[i] = pow((double)ltln[i], 4) + pow((double)gtln[i], 4); + } + + // Choose the least bad coordinate to split along. + if(badness[0] < badness[1] && badness[0] < badness[2]) { + n->which = 0; + } else if(badness[1] < badness[2]) { + n->which = 1; + } else { + n->which = 2; + } + n->c = ptAve.Element(n->which); + + if(totaln < 3 || totaln == gtln[n->which] || totaln == ltln[n->which]) { + n->edges = sell; + // and we're a leaf node + return n; + } + + // Sort the edges according to which side(s) of the split plane they're on. + SEdgeLl *gtl = NULL, *ltl = NULL; + for(flip = sell; flip; flip = flip->next) { + if(flip->se->a.Element(n->which) < n->c + KDTREE_EPS || + flip->se->b.Element(n->which) < n->c + KDTREE_EPS) + { + SEdgeLl *selln = SEdgeLl::Alloc(); + selln->se = flip->se; + selln->next = ltl; + ltl = selln; + } + if(flip->se->a.Element(n->which) > n->c - KDTREE_EPS || + flip->se->b.Element(n->which) > n->c - KDTREE_EPS) + { + SEdgeLl *selln = SEdgeLl::Alloc(); + selln->se = flip->se; + selln->next = gtl; + gtl = selln; + } + } + + n->lt = SKdNodeEdges::From(ltl); + n->gt = SKdNodeEdges::From(gtl); + return n; +} + +int SKdNodeEdges::AnyEdgeCrossings(Vector a, Vector b, int cnt, + Vector *pi, SPointList *spl) const +{ + int inters = 0; + if(gt && lt) { + if(a.Element(which) < c + KDTREE_EPS || + b.Element(which) < c + KDTREE_EPS) + { + inters += lt->AnyEdgeCrossings(a, b, cnt, pi, spl); + } + if(a.Element(which) > c - KDTREE_EPS || + b.Element(which) > c - KDTREE_EPS) + { + inters += gt->AnyEdgeCrossings(a, b, cnt, pi, spl); + } + } else { + SEdgeLl *sell; + for(sell = edges; sell; sell = sell->next) { + SEdge *se = sell->se; + if(se->tag == cnt) continue; + if(se->EdgeCrosses(a, b, pi, spl)) { + inters++; + } + se->tag = cnt; + } + } + return inters; +} + +//----------------------------------------------------------------------------- +// We have an edge list that contains only collinear edges, maybe with more +// splits than necessary. Merge any collinear segments that join. +//----------------------------------------------------------------------------- +void SEdgeList::MergeCollinearSegments(Vector a, Vector b) { + const Vector lineStart = a; + const Vector lineDirection = b.Minus(a); + std::sort(l.begin(), l.end(), [&](const SEdge &a, const SEdge &b) { + double ta = (a.a.Minus(lineStart)).DivProjected(lineDirection); + double tb = (b.a.Minus(lineStart)).DivProjected(lineDirection); + + return (ta < tb); + }); + + l.ClearTags(); + SEdge *prev = nullptr; + for(auto &now : l) { + if(prev != nullptr) { + if((prev->b).Equals(now.a) && prev->auxA == now.auxA) { + // The previous segment joins up to us; so merge it into us. + prev->tag = 1; + now.a = prev->a; + } + } + prev = &now; + } + l.RemoveTagged(); +} + +void SPointList::Clear() { + l.Clear(); +} + +bool SPointList::ContainsPoint(Vector pt) const { + return (IndexForPoint(pt) >= 0); +} + +int SPointList::IndexForPoint(Vector pt) const { + int i; + for(i = 0; i < l.n; i++) { + const SPoint *p = &(l[i]); + if(pt.Equals(p->p)) { + return i; + } + } + // Not found, so return negative to indicate that. + return -1; +} + +void SPointList::IncrementTagFor(Vector pt) { + SPoint *p; + for(p = l.First(); p; p = l.NextAfter(p)) { + if(pt.Equals(p->p)) { + (p->tag)++; + return; + } + } + SPoint pa; + pa.p = pt; + pa.tag = 1; + l.Add(&pa); +} + +void SPointList::Add(Vector pt) { + SPoint p = {}; + p.p = pt; + l.Add(&p); +} + +void SContour::AddPoint(Vector p) { + SPoint sp; + sp.tag = 0; + sp.p = p; + + l.Add(&sp); +} + +void SContour::MakeEdgesInto(SEdgeList *el) const { + int i; + for(i = 0; i < (l.n - 1); i++) { + el->AddEdge(l[i].p, l[i+1].p); + } +} + +void SContour::CopyInto(SContour *dest) const { + for(const SPoint *sp = l.First(); sp; sp = l.NextAfter(sp)) { + dest->AddPoint(sp->p); + } +} + +void SContour::FindPointWithMinX() { + xminPt = Vector::From(1e10, 1e10, 1e10); + for(const SPoint *sp = l.First(); sp; sp = l.NextAfter(sp)) { + if(sp->p.x < xminPt.x) { + xminPt = sp->p; + } + } +} + +Vector SContour::ComputeNormal() const { + Vector n = Vector::From(0, 0, 0); + + for(int i = 0; i < l.n - 2; i++) { + Vector u = (l[i+1].p).Minus(l[i+0].p).WithMagnitude(1); + Vector v = (l[i+2].p).Minus(l[i+1].p).WithMagnitude(1); + Vector nt = u.Cross(v); + if(nt.Magnitude() > n.Magnitude()) { + n = nt; + } + } + return n.WithMagnitude(1); +} + +Vector SContour::AnyEdgeMidpoint() const { + ssassert(l.n >= 2, "Need two points to find a midpoint"); + return ((l[0].p).Plus(l[1].p)).ScaledBy(0.5); +} + +bool SContour::IsClockwiseProjdToNormal(Vector n) const { + // Degenerate things might happen as we draw; doesn't really matter + // what we do then. + if(n.Magnitude() < 0.01) return true; + + return (SignedAreaProjdToNormal(n) < 0); +} + +double SContour::SignedAreaProjdToNormal(Vector n) const { + // An arbitrary 2d coordinate system that has n as its normal + Vector u = n.Normal(0); + Vector v = n.Normal(1); + + double area = 0; + for(int i = 0; i < (l.n - 1); i++) { + double u0 = (l[i ].p).Dot(u); + double v0 = (l[i ].p).Dot(v); + double u1 = (l[i+1].p).Dot(u); + double v1 = (l[i+1].p).Dot(v); + + area += ((v0 + v1)/2)*(u1 - u0); + } + return area; +} + +bool SContour::ContainsPointProjdToNormal(Vector n, Vector p) const { + Vector u = n.Normal(0); + Vector v = n.Normal(1); + + double up = p.Dot(u); + double vp = p.Dot(v); + + bool inside = false; + for(int i = 0; i < (l.n - 1); i++) { + double ua = (l[i ].p).Dot(u); + double va = (l[i ].p).Dot(v); + // The curve needs to be exactly closed; approximation is death. + double ub = (l[(i+1)%(l.n-1)].p).Dot(u); + double vb = (l[(i+1)%(l.n-1)].p).Dot(v); + + if ((((va <= vp) && (vp < vb)) || + ((vb <= vp) && (vp < va))) && + (up < (ub - ua) * (vp - va) / (vb - va) + ua)) + { + inside = !inside; + } + } + + return inside; +} + +void SContour::Reverse() { + l.Reverse(); +} + + +void SPolygon::Clear() { + int i; + for(i = 0; i < l.n; i++) { + (l[i]).l.Clear(); + } + l.Clear(); +} + +void SPolygon::AddEmptyContour() { + SContour c = {}; + l.Add(&c); +} + +void SPolygon::MakeEdgesInto(SEdgeList *el) const { + int i; + for(i = 0; i < l.n; i++) { + (l[i]).MakeEdgesInto(el); + } +} + +Vector SPolygon::ComputeNormal() const { + if(l.IsEmpty()) + return Vector::From(0, 0, 0); + return (l[0]).ComputeNormal(); +} + +double SPolygon::SignedArea() const { + double area = 0; + // This returns the true area only if the contours are all oriented + // correctly, with the holes backwards from the outer contours. + for(const SContour *sc = l.First(); sc; sc = l.NextAfter(sc)) { + area += sc->SignedAreaProjdToNormal(normal); + } + return area; +} + +bool SPolygon::ContainsPoint(Vector p) const { + return (WindingNumberForPoint(p) % 2) == 1; +} + +size_t SPolygon::WindingNumberForPoint(Vector p) const { + auto winding = std::count_if(l.begin(), l.end(), [&](const SContour &sc) { + return sc.ContainsPointProjdToNormal(normal, p); + }); + return winding; +} + +void SPolygon::FixContourDirections() { + // At output, the contour's tag will be 1 if we reversed it, else 0. + l.ClearTags(); + + // Outside curve looks counterclockwise, projected against our normal. + int i, j; + for(i = 0; i < l.n; i++) { + SContour *sc = &(l[i]); + if(sc->l.n < 2) continue; + // The contours may not intersect, but they may share vertices; so + // testing a vertex for point-in-polygon may fail, but the midpoint + // of an edge is okay. + Vector pt = (((sc->l[0]).p).Plus(sc->l[1].p)).ScaledBy(0.5); + + sc->timesEnclosed = 0; + bool outer = true; + for(j = 0; j < l.n; j++) { + if(i == j) continue; + SContour *sct = &(l[j]); + if(sct->ContainsPointProjdToNormal(normal, pt)) { + outer = !outer; + (sc->timesEnclosed)++; + } + } + + bool clockwise = sc->IsClockwiseProjdToNormal(normal); + if((clockwise && outer) || (!clockwise && !outer)) { + sc->Reverse(); + sc->tag = 1; + } + } +} + +bool SPolygon::IsEmpty() const { + if(l.IsEmpty() || l[0].l.IsEmpty()) + return true; + return false; +} + +Vector SPolygon::AnyPoint() const { + ssassert(!IsEmpty(), "Need at least one point"); + return l[0].l[0].p; +} + +bool SPolygon::SelfIntersecting(Vector *intersectsAt) const { + SEdgeList el = {}; + MakeEdgesInto(&el); + SKdNodeEdges *kdtree = SKdNodeEdges::From(&el); + + int cnt = 1; + el.l.ClearTags(); + + bool ret = false; + SEdge *se; + for(se = el.l.First(); se; se = el.l.NextAfter(se)) { + int inters = kdtree->AnyEdgeCrossings(se->a, se->b, cnt, intersectsAt); + if(inters != 1) { + ret = true; + break; + } + cnt++; + } + + el.Clear(); + return ret; +} + +void SPolygon::InverseTransformInto(SPolygon *sp, Vector u, Vector v, Vector n) const { + for(const SContour &sc : l) { + SContour tsc = {}; + tsc.timesEnclosed = sc.timesEnclosed; + for(const SPoint &sp : sc.l) { + tsc.AddPoint(sp.p.DotInToCsys(u, v, n)); + } + sp->l.Add(&tsc); + } +} + +//----------------------------------------------------------------------------- +// Low-quality routines to cutter radius compensate a polygon. Assumes the +// polygon is in the xy plane, and the contours all go in the right direction +// with respect to normal (0, 0, -1). +//----------------------------------------------------------------------------- +void SPolygon::OffsetInto(SPolygon *dest, double r) const { + int i; + dest->Clear(); + for(i = 0; i < l.n; i++) { + const SContour *sc = &(l[i]); + dest->AddEmptyContour(); + sc->OffsetInto(&(dest->l[dest->l.n-1]), r); + } +} +//----------------------------------------------------------------------------- +// Calculate the intersection point of two lines. Returns true for success, +// false if they're parallel. +//----------------------------------------------------------------------------- +static bool IntersectionOfLines(double x0A, double y0A, double dxA, double dyA, + double x0B, double y0B, double dxB, double dyB, + double *xi, double *yi) +{ + double A[2][2]; + double b[2]; + + // The line is given to us in the form: + // (x(t), y(t)) = (x0, y0) + t*(dx, dy) + // so first rewrite it as + // (x - x0, y - y0) dot (dy, -dx) = 0 + // x*dy - x0*dy - y*dx + y0*dx = 0 + // x*dy - y*dx = (x0*dy - y0*dx) + + // So write the matrix, pre-pivoted. + if(fabs(dyA) > fabs(dyB)) { + A[0][0] = dyA; A[0][1] = -dxA; b[0] = x0A*dyA - y0A*dxA; + A[1][0] = dyB; A[1][1] = -dxB; b[1] = x0B*dyB - y0B*dxB; + } else { + A[1][0] = dyA; A[1][1] = -dxA; b[1] = x0A*dyA - y0A*dxA; + A[0][0] = dyB; A[0][1] = -dxB; b[0] = x0B*dyB - y0B*dxB; + } + + // Check the determinant; if it's zero then no solution. + if(fabs(A[0][0]*A[1][1] - A[0][1]*A[1][0]) < LENGTH_EPS) { + return false; + } + + // Solve + double v = A[1][0] / A[0][0]; + A[1][0] -= A[0][0]*v; + A[1][1] -= A[0][1]*v; + b[1] -= b[0]*v; + + // Back-substitute. + *yi = b[1] / A[1][1]; + *xi = (b[0] - A[0][1]*(*yi)) / A[0][0]; + + return true; +} +void SContour::OffsetInto(SContour *dest, double r) const { + int i; + + for(i = 0; i < l.n; i++) { + Vector a, b, c; + Vector dp, dn; + double thetan, thetap; + + a = l[WRAP(i-1, (l.n-1))].p; + b = l[WRAP(i, (l.n-1))].p; + c = l[WRAP(i+1, (l.n-1))].p; + + dp = a.Minus(b); + thetap = atan2(dp.y, dp.x); + + dn = b.Minus(c); + thetan = atan2(dn.y, dn.x); + + // A short line segment in a badly-generated polygon might look + // okay but screw up our sense of direction. + if(dp.Magnitude() < LENGTH_EPS || dn.Magnitude() < LENGTH_EPS) { + continue; + } + + if(thetan > thetap && (thetan - thetap) > PI) { + thetap += 2*PI; + } + if(thetan < thetap && (thetap - thetan) > PI) { + thetan += 2*PI; + } + + if(fabs(thetan - thetap) < (1*PI)/180) { + Vector p = { b.x - r*sin(thetap), b.y + r*cos(thetap), 0 }; + dest->AddPoint(p); + } else if(thetan < thetap) { + // This is an inside corner. We have two edges, Ep and En. Move + // out from their intersection by radius, normal to En, and + // then draw a line parallel to En. Move out from their + // intersection by radius, normal to Ep, and then draw a second + // line parallel to Ep. The point that we want to generate is + // the intersection of these two lines--it removes as much + // material as we can without removing any that we shouldn't. + double px0, py0, pdx, pdy; + double nx0, ny0, ndx, ndy; + double x = 0.0, y = 0.0; + + px0 = b.x - r*sin(thetap); + py0 = b.y + r*cos(thetap); + pdx = cos(thetap); + pdy = sin(thetap); + + nx0 = b.x - r*sin(thetan); + ny0 = b.y + r*cos(thetan); + ndx = cos(thetan); + ndy = sin(thetan); + + IntersectionOfLines(px0, py0, pdx, pdy, + nx0, ny0, ndx, ndy, + &x, &y); + + dest->AddPoint(Vector::From(x, y, 0)); + } else { + if(fabs(thetap - thetan) < (6*PI)/180) { + Vector pp = { b.x - r*sin(thetap), + b.y + r*cos(thetap), 0 }; + dest->AddPoint(pp); + + Vector pn = { b.x - r*sin(thetan), + b.y + r*cos(thetan), 0 }; + dest->AddPoint(pn); + } else { + double theta; + for(theta = thetap; theta <= thetan; theta += (6*PI)/180) { + Vector p = { b.x - r*sin(theta), + b.y + r*cos(theta), 0 }; + dest->AddPoint(p); + } + } + } + } +} + diff --git a/src/polygon.h b/src/polygon.h new file mode 100644 index 0000000..cf0f322 --- /dev/null +++ b/src/polygon.h @@ -0,0 +1,420 @@ +//----------------------------------------------------------------------------- +// Anything relating to plane polygons and triangles, and (generally, non- +// planar) meshes thereof. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- + +#ifndef SOLVESPACE_POLYGON_H +#define SOLVESPACE_POLYGON_H + +class SPointList; +class SPolygon; +class SContour; +class SMesh; +class SBsp3; +class SOutlineList; + +enum class EarType : uint32_t { + UNKNOWN = 0, + NOT_EAR = 1, + EAR = 2 +}; + +enum class BspClass : uint32_t { + POS = 100, + NEG = 101, + COPLANAR = 200 +}; + +enum class EdgeKind : uint32_t { + NAKED_OR_SELF_INTER = 100, + SELF_INTER = 200, + TURNING = 300, + EMPHASIZED = 400, + SHARP = 500, +}; + +class SEdge { +public: + int tag; + int auxA, auxB; + Vector a, b; + + static SEdge From(Vector a, Vector b); + bool EdgeCrosses(Vector a, Vector b, Vector *pi=NULL, SPointList *spl=NULL) const; +}; + +class SEdgeList { +public: + List l; + + void Clear(); + void AddEdge(Vector a, Vector b, int auxA=0, int auxB=0, int tag=0); + bool AssemblePolygon(SPolygon *dest, SEdge *errorAt, bool keepDir=false) const; + bool AssembleContour(Vector first, Vector last, SContour *dest, + SEdge *errorAt, bool keepDir, int start) const; + int AnyEdgeCrossings(Vector a, Vector b, + Vector *pi=NULL, SPointList *spl=NULL) const; + bool ContainsEdgeFrom(const SEdgeList *sel) const; + bool ContainsEdge(const SEdge *se) const; + void CullExtraneousEdges(bool both=true); + void MergeCollinearSegments(Vector a, Vector b); +}; + +// A kd-tree element needs to go on a side of a node if it's when KDTREE_EPS +// of the boundary. So increasing this number never breaks anything, but may +// result in more duplicated elements. So it's conservative to be sloppy here. +#define KDTREE_EPS (20*LENGTH_EPS) + +class SEdgeLl { +public: + SEdge *se; + SEdgeLl *next; + + static SEdgeLl *Alloc(); +}; + +class SKdNodeEdges { +public: + int which; // whether c is x, y, or z + double c; + SKdNodeEdges *gt; + SKdNodeEdges *lt; + + SEdgeLl *edges; + + static SKdNodeEdges *From(SEdgeList *sel); + static SKdNodeEdges *From(SEdgeLl *sell); + static SKdNodeEdges *Alloc(); + int AnyEdgeCrossings(Vector a, Vector b, int cnt, + Vector *pi=NULL, SPointList *spl=NULL) const; +}; + +class SPoint { +public: + int tag; + + EarType ear; + + Vector p; + Vector auxv; +}; + +class SPointList { +public: + List l; + + void Clear(); + bool ContainsPoint(Vector pt) const; + int IndexForPoint(Vector pt) const; + void IncrementTagFor(Vector pt); + void Add(Vector pt); +}; + +class SContour { +public: + int tag; + int timesEnclosed; + Vector xminPt; + List l; + + void AddPoint(Vector p); + void MakeEdgesInto(SEdgeList *el) const; + void Reverse(); + Vector ComputeNormal() const; + double SignedAreaProjdToNormal(Vector n) const; + bool IsClockwiseProjdToNormal(Vector n) const; + bool ContainsPointProjdToNormal(Vector n, Vector p) const; + void OffsetInto(SContour *dest, double r) const; + void CopyInto(SContour *dest) const; + void FindPointWithMinX(); + Vector AnyEdgeMidpoint() const; + + bool IsEmptyTriangle(int ap, int bp, int cp, double scaledEPS) const; + bool IsEar(int bp, double scaledEps) const; + bool BridgeToContour(SContour *sc, SEdgeList *el, List *vl); + void ClipEarInto(SMesh *m, int bp, double scaledEps); + void UvTriangulateInto(SMesh *m, SSurface *srf); +}; + +typedef struct { + uint32_t face; + RgbaColor color; +} STriMeta; + +class SPolygon { +public: + List l; + Vector normal; + + Vector ComputeNormal() const; + void AddEmptyContour(); + size_t WindingNumberForPoint(Vector p) const; + double SignedArea() const; + bool ContainsPoint(Vector p) const; + void MakeEdgesInto(SEdgeList *el) const; + void FixContourDirections(); + void Clear(); + bool SelfIntersecting(Vector *intersectsAt) const; + bool IsEmpty() const; + Vector AnyPoint() const; + void OffsetInto(SPolygon *dest, double r) const; + void UvTriangulateInto(SMesh *m, SSurface *srf); + void UvGridTriangulateInto(SMesh *m, SSurface *srf); + void TriangulateInto(SMesh *m) const; + void InverseTransformInto(SPolygon *sp, Vector u, Vector v, Vector n) const; +}; + +class STriangle { +public: + int tag; + STriMeta meta; + + union { + struct { Vector a, b, c; }; + Vector vertices[3]; + }; + + union { + struct { Vector an, bn, cn; }; + Vector normals[3]; + }; + + static STriangle From(STriMeta meta, Vector a, Vector b, Vector c); + Vector Normal() const; + void FlipNormal(); + double MinAltitude() const; + bool ContainsPoint(Vector p) const; + bool ContainsPointProjd(Vector n, Vector p) const; + STriangle Transform(Vector o, Vector u, Vector v) const; + bool Raytrace(const Vector &rayPoint, const Vector &rayDir, + double *t, Vector *inters) const; + double SignedVolume() const; + double Area() const; + bool IsDegenerate() const; +}; + +class SBsp2 { +public: + Vector np; // normal to the plane + + Vector no; // outer normal to the edge + double d; + SEdge edge; + + SBsp2 *pos; + SBsp2 *neg; + + SBsp2 *more; + + void InsertTriangleHow(BspClass how, STriangle *tr, SMesh *m, SBsp3 *bsp3); + void InsertTriangle(STriangle *tr, SMesh *m, SBsp3 *bsp3); + Vector IntersectionWith(Vector a, Vector b) const; + void InsertEdge(SEdge *nedge, Vector nnp, Vector out); + static SBsp2 *InsertOrCreateEdge(SBsp2 *where, SEdge *nedge, + Vector nnp, Vector out); + static SBsp2 *Alloc(); +}; + +class SBsp3 { +public: + Vector n; + double d; + + STriangle tri; + SBsp3 *pos; + SBsp3 *neg; + + SBsp3 *more; + + SBsp2 *edges; + + static SBsp3 *Alloc(); + static SBsp3 *FromMesh(const SMesh *m); + + Vector IntersectionWith(Vector a, Vector b) const; + + void InsertHow(BspClass how, STriangle *str, SMesh *instead); + void Insert(STriangle *str, SMesh *instead); + static SBsp3 *InsertOrCreate(SBsp3 *where, STriangle *str, SMesh *instead); + + void InsertConvexHow(BspClass how, STriMeta meta, Vector *vertex, size_t n, + SMesh *instead); + SBsp3 *InsertConvex(STriMeta meta, Vector *vertex, size_t n, SMesh *instead); + + void InsertInPlane(bool pos2, STriangle *tr, SMesh *m); + + void GenerateInPaintOrder(SMesh *m) const; +}; + +class SMesh { +public: + List l; + + bool flipNormal; + bool keepInsideOtherShell; + bool keepCoplanar; + bool atLeastOneDiscarded; + bool isTransparent; + + void Clear(); + void AddTriangle(const STriangle *st); + void AddTriangle(STriMeta meta, Vector a, Vector b, Vector c); + void AddTriangle(STriMeta meta, Vector n, + Vector a, Vector b, Vector c); + void DoBounding(Vector v, Vector *vmax, Vector *vmin) const; + void GetBounding(Vector *vmax, Vector *vmin) const; + + void Simplify(int start); + + void AddAgainstBsp(SMesh *srcm, SBsp3 *bsp3); + void MakeFromUnionOf(SMesh *a, SMesh *b); + void MakeFromDifferenceOf(SMesh *a, SMesh *b); + void MakeFromIntersectionOf(SMesh *a, SMesh *b); + + void MakeFromCopyOf(SMesh *a); + void MakeFromTransformationOf(SMesh *a, Vector trans, + Quaternion q, double scale); + void MakeFromAssemblyOf(SMesh *a, SMesh *b); + + void MakeEdgesInPlaneInto(SEdgeList *sel, Vector n, double d); + void MakeOutlinesInto(SOutlineList *sol, EdgeKind type); + + void PrecomputeTransparency(); + void RemoveDegenerateTriangles(); + double CalculateVolume() const; + double CalculateSurfaceArea(const std::vector &faces) const; + + bool IsEmpty() const; + void RemapFaces(Group *g, int remap); + + uint32_t FirstIntersectionWith(Point2d mp) const; + + Vector GetCenterOfMass() const; +}; + +// A linked list of triangles +class STriangleLl { +public: + STriangle *tri; + + STriangleLl *next; + + static STriangleLl *Alloc(); +}; + +class SOutline { +public: + int tag; + Vector a, b, nl, nr; + + bool IsVisible(Vector projDir) const; +}; + +class SOutlineList { +public: + List l; + + void Clear(); + void AddEdge(Vector a, Vector b, Vector nl, Vector nr, int tag = 0); + void ListTaggedInto(SEdgeList *el, int auxA = 0, int auxB = 0); + + void MakeFromCopyOf(SOutlineList *ol); +}; + +class SKdNode { +public: + struct EdgeOnInfo { + int count; + bool frontFacing; + bool intersectsMesh; + STriangle *tr; + int ai; + int bi; + }; + + int which; // whether c is x, y, or z + double c; + + SKdNode *gt; + SKdNode *lt; + + STriangleLl *tris; + + static SKdNode *Alloc(); + static SKdNode *From(SMesh *m); + static SKdNode *From(STriangleLl *tll); + + void AddTriangle(STriangle *tr); + void MakeMeshInto(SMesh *m) const; + void ListTrianglesInto(std::vector *tl) const; + void ClearTags() const; + + void FindEdgeOn(Vector a, Vector b, int cnt, bool coplanarIsInter, EdgeOnInfo *info) const; + void MakeCertainEdgesInto(SEdgeList *sel, EdgeKind how, bool coplanarIsInter, + bool *inter, bool *leaky, int auxA = 0) const; + void MakeOutlinesInto(SOutlineList *sel, EdgeKind tagKind) const; + + void OcclusionTestLine(SEdge orig, SEdgeList *sel, int cnt) const; + void SplitLinesAgainstTriangle(SEdgeList *sel, STriangle *tr) const; + + void SnapToMesh(SMesh *m); + void SnapToVertex(Vector v, SMesh *extras); +}; + +class PolylineBuilder { +public: + struct Edge; + + struct Vertex { + Vector pos; + std::vector edges; + + bool GetNext(uint32_t kind, Vertex **next, Edge **nextEdge); + bool GetNext(uint32_t kind, Vector plane, double d, Vertex **next, Edge **nextEdge); + size_t CountEdgesWithTagAndKind(int tag, uint32_t kind) const; + }; + + struct VertexPairHash { + size_t operator()(const std::pair &v) const; + }; + + struct Edge { + Vertex *a; + Vertex *b; + uint32_t kind; + int tag; + + union { + uintptr_t data; + SOutline *outline; + SEdge *edge; + }; + + Vertex *GetOtherVertex(Vertex *v) const; + bool GetStartAndNext(Vertex **start, Vertex **next, bool loop) const; + }; + + std::unordered_map vertices; + std::unordered_map, Edge *, VertexPairHash> edgeMap; + std::vector edges; + + ~PolylineBuilder(); + void Clear(); + + Vertex *AddVertex(const Vector &pos); + Edge *AddEdge(const Vector &p0, const Vector &p1, uint32_t kind, uintptr_t data = 0); + void Generate(std::function const &startFunc, + std::function const &nextFunc, + std::function const &aloneFunc, + std::function const &endFunc = []() {}); + + void MakeFromEdges(const SEdgeList &sel); + void MakeFromOutlines(const SOutlineList &sol); + void GenerateEdges(SEdgeList *sel); + void GenerateOutlines(SOutlineList *sol); +}; + +#endif + diff --git a/src/polyline.cpp b/src/polyline.cpp new file mode 100644 index 0000000..64aef4e --- /dev/null +++ b/src/polyline.cpp @@ -0,0 +1,243 @@ +//----------------------------------------------------------------------------- +// A helper class to assemble scattered edges into contiguous polylines, +// as nicely as possible. +// +// Copyright 2016 M-Labs Ltd +//----------------------------------------------------------------------------- +#include "solvespace.h" + +bool PolylineBuilder::Vertex::GetNext(uint32_t kind, Vertex **next, Edge **nextEdge) { + auto it = std::find_if(edges.begin(), edges.end(), [&](const Edge *e) { + return e->tag == 0 && e->kind == kind; + }); + + if(it != edges.end()) { + (*it)->tag = 1; + *next = (*it)->GetOtherVertex(this); + *nextEdge = *it; + return true; + } + + return false; +} + +bool PolylineBuilder::Vertex::GetNext(uint32_t kind, Vector plane, double dist, + Vertex **next, Edge **nextEdge) { + Edge *best = NULL; + double minD = VERY_POSITIVE; + for(Edge *e : edges) { + if(e->tag != 0) continue; + if(e->kind != kind) continue; + + // We choose the best next edge with minimal distance from the current plane + Vector nextPos = e->GetOtherVertex(this)->pos; + double curD = fabs(plane.Dot(nextPos) - dist); + if(best != NULL && curD > minD) continue; + best = e; + minD = curD; + } + + if(best != NULL) { + best->tag = 1; + *next = best->GetOtherVertex(this); + *nextEdge = best; + return true; + } + + return false; +} + + +size_t PolylineBuilder::Vertex::CountEdgesWithTagAndKind(int tag, uint32_t kind) const { + return std::count_if(edges.begin(), edges.end(), [&](const Edge *e) { + return e->tag == tag && e->kind == kind; + }); +} + +PolylineBuilder::Vertex *PolylineBuilder::Edge::GetOtherVertex(PolylineBuilder::Vertex *v) const { + if(a == v) return b; + if(b == v) return a; + return NULL; +} + +size_t PolylineBuilder::VertexPairHash::operator()(const std::pair &v) const { + return ((uintptr_t)v.first / sizeof(Vertex)) ^ + ((uintptr_t)v.second / sizeof(Vertex)); +} + +bool PolylineBuilder::Edge::GetStartAndNext(PolylineBuilder::Vertex **start, + PolylineBuilder::Vertex **next, bool loop) const { + size_t numA = a->CountEdgesWithTagAndKind(0, kind); + size_t numB = b->CountEdgesWithTagAndKind(0, kind); + + if((numA == 1 && numB > 1) || (loop && numA > 1 && numB > 1)) { + *start = a; + *next = b; + return true; + } + + if(numA > 1 && numB == 1) { + *start = b; + *next = a; + return true; + } + + return false; +} + +PolylineBuilder::~PolylineBuilder() { + Clear(); +} + +void PolylineBuilder::Clear() { + for(Edge *e : edges) { + delete e; + } + edges.clear(); + + for(auto &v : vertices) { + delete v.second; + } + vertices.clear(); +} + +PolylineBuilder::Vertex *PolylineBuilder::AddVertex(const Vector &pos) { + auto it = vertices.find(pos); + if(it != vertices.end()) { + return it->second; + } + + Vertex *result = new Vertex; + result->pos = pos; + vertices.emplace(pos, result); + + return result; +} + +PolylineBuilder::Edge *PolylineBuilder::AddEdge(const Vector &p0, const Vector &p1, + uint32_t kind, uintptr_t data) { + Vertex *v0 = AddVertex(p0); + Vertex *v1 = AddVertex(p1); + if(v0 == v1) return NULL; + + auto it = edgeMap.find(std::make_pair(v0, v1)); + if(it != edgeMap.end()) { + return it->second; + } + + PolylineBuilder::Edge *edge = new PolylineBuilder::Edge {}; + edge->a = v0; + edge->b = v1; + edge->kind = kind; + edge->tag = 0; + edge->data = data; + edges.push_back(edge); + edgeMap.emplace(std::make_pair(v0, v1), edge); + + v0->edges.push_back(edge); + v1->edges.push_back(edge); + + return edge; +} + +void PolylineBuilder::Generate( + std::function const &startFunc, + std::function const &nextFunc, + std::function const &aloneFunc, std::function const &endFunc) { + bool found; + bool loop = false; + do { + found = false; + for(PolylineBuilder::Edge *e : edges) { + if(e->tag != 0) continue; + + Vertex *start; + Vertex *next; + if(!e->GetStartAndNext(&start, &next, loop)) continue; + + Vector startPos = start->pos; + Vector nextPos = next->pos; + found = true; + e->tag = 1; + + startFunc(start, next, e); + + Edge *nextEdge; + if(next->GetNext(e->kind, &next, &nextEdge)) { + Vector plane = nextPos.Minus(startPos).Cross(next->pos.Minus(startPos)); + double dist = plane.Dot(startPos); + nextFunc(next, nextEdge); + while(next->GetNext(e->kind, plane, dist, &next, &nextEdge)) { + nextFunc(next, nextEdge); + } + } + + endFunc(); + } + + if(!found && !loop) { + loop = true; + found = true; + } + } while(found); + + for(PolylineBuilder::Edge *e : edges) { + if(e->tag != 0) continue; + aloneFunc(e); + } +} + +void PolylineBuilder::MakeFromEdges(const SEdgeList &sel) { + for(const SEdge &se : sel.l) { + AddEdge(se.a, se.b, (uint32_t)se.auxA, reinterpret_cast(&se)); + } +} + +void PolylineBuilder::MakeFromOutlines(const SOutlineList &ol) { + for(const SOutline &so : ol.l) { + // Use outline tag as kind, so that emphasized and contour outlines + // would not be composed together. + AddEdge(so.a, so.b, (uint32_t)so.tag, reinterpret_cast(&so)); + } +} + +void PolylineBuilder::GenerateEdges(SEdgeList *sel) { + Vector prev; + auto startFunc = [&](Vertex *start, Vertex *next, Edge *e) { + sel->AddEdge(start->pos, next->pos, e->kind); + prev = next->pos; + }; + + auto nextFunc = [&](Vertex *next, Edge *e) { + sel->AddEdge(prev, next->pos, e->kind); + prev = next->pos; + }; + + auto aloneFunc = [&](Edge *e) { + sel->AddEdge(e->a->pos, e->b->pos, e->kind); + }; + + Generate(startFunc, nextFunc, aloneFunc); +} + +void PolylineBuilder::GenerateOutlines(SOutlineList *sol) { + Vector prev; + auto startFunc = [&](Vertex *start, Vertex *next, Edge *e) { + SOutline *so = e->outline; + sol->AddEdge(start->pos, next->pos, so->nl, so->nr, so->tag); + prev = next->pos; + }; + + auto nextFunc = [&](Vertex *next, Edge *e) { + SOutline *so = e->outline; + sol->AddEdge(prev, next->pos, so->nl, so->nr, so->tag); + prev = next->pos; + }; + + auto aloneFunc = [&](Edge *e) { + SOutline *so = e->outline; + sol->AddEdge(so->a, so->b, so->nl, so->nr, so->tag); + }; + + Generate(startFunc, nextFunc, aloneFunc); +} diff --git a/src/render/gl3shader.cpp b/src/render/gl3shader.cpp new file mode 100644 index 0000000..a309046 --- /dev/null +++ b/src/render/gl3shader.cpp @@ -0,0 +1,1071 @@ +//----------------------------------------------------------------------------- +// OpenGL ES 2.0 and OpenGL 3.0 shader interface. +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +#include "solvespace.h" +#include "gl3shader.h" + +namespace SolveSpace { + +//----------------------------------------------------------------------------- +// Floating point data structures +//----------------------------------------------------------------------------- + +Vector2f Vector2f::From(float x, float y) { + return { x, y }; +} + +Vector2f Vector2f::From(double x, double y) { + return { (float)x, (float)y }; +} + +Vector2f Vector2f::FromInt(uint32_t x, uint32_t y) { + return { (float)x, (float)y }; +} + +Vector3f Vector3f::From(float x, float y, float z) { + return { x, y, z }; +} + +Vector3f Vector3f::From(const Vector &v) { + return { (float)v.x, (float)v.y, (float)v.z }; +} + +Vector3f Vector3f::From(const RgbaColor &c) { + return { c.redF(), c.greenF(), c.blueF() }; +} + +Vector4f Vector4f::From(float x, float y, float z, float w) { + return { x, y, z, w }; +} + +Vector4f Vector4f::From(const Vector &v, float w) { + return { (float)v.x, (float)v.y, (float)v.z, w }; +} + +Vector4f Vector4f::FromInt(uint32_t x, uint32_t y, uint32_t z, uint32_t w) { + return { (float)x, (float)y, (float)z, (float)w }; +} + +Vector4f Vector4f::From(const RgbaColor &c) { + return { c.redF(), c.greenF(), c.blueF(), c.alphaF() }; +} + +//----------------------------------------------------------------------------- +// Shader manipulation +//----------------------------------------------------------------------------- + +static GLuint CompileShader(const std::string &res, GLenum type) { + size_t size; + const char *resData = (const char *)Platform::LoadResource(res, &size); + + // Sigh, here we go... We want to deploy to four platforms: Linux, Windows, OS X, mobile+web. + // These platforms are basically disjunctive in the OpenGL versions and profiles that they + // support: mobile+web support GLES2, Windows can only be guaranteed to support GL1 without + // vendor's drivers installed but supports D3D9+ natively, Linux supports GL3.2+ and/or + // GLES2+ depending on whether we run on X11 or Wayland, and OS X supports either a legacy + // profile or a GL3.2 core profile or (on 10.9+) a GL4.1 core profile. + // The platforms barely have a common subset of features: + // * mobile+web and Windows (D3D9 through ANGLE) are strictly GLES2/GLSL1.0; + // * OS X legacy compatibility profile has GLSL1.2 only shaders, and GL3.2 core profile + // that has GLSL1.0 shaders compatible with GLES2 makes mandatory the use of vertex array + // objects, which cannot be used in GLES2 at all; similarly GL3.2 core has GL_RED but not + // GL_ALPHA whereas GLES2 has GL_ALPHA but not GL_RED. + // * GTK does not work on anything prior to GL3.0/GLES2.0; it does not permit explicitly + // asking for a compatibility profile, i.e. you can only ask for 3.2+; and it does not + // permit asking for a GLES profile prior to GTK 3.22, which will get into Ubuntu + // no earlier than late 2017. This is despite the fact that if only GTK defaulted + // to the compatibility profile, everything would have just worked as Mesa is + // very permissive. + // While we're at it, let's remember that GLES2 has *only* glDepthRangef, GL3.2 has *only* + // glDepthRange, and GL4.1+ has both glDepthRangef and glDepthRange. Also, that GLSL1.0 + // makes `precision highp float;` mandatory in fragment shaders, and GLSL1.2 removes + // the `precision` keyword entirely, because that's clearly how minor versions work. + // Christ, what a trash fire. + + const char *prelude; +#if defined(HAVE_GLES) + prelude = R"( +#version 100 +#define TEX_ALPHA a +precision highp float; +)"; +#else + prelude = R"( +#version 120 +#define TEX_ALPHA r +)"; +#endif + std::string src(resData, size); + src = prelude + src; + + GLuint shader = glCreateShader(type); + ssassert(shader != 0, "glCreateShader failed"); + + const GLint glSize[] = { (int)src.length() }; + const GLchar* glSource[] = { src.c_str() }; + glShaderSource(shader, 1, glSource, glSize); + glCompileShader(shader); + + GLint infoLen; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); + if(infoLen > 1) { + std::string infoStr(infoLen, '\0'); + glGetShaderInfoLog(shader, infoLen, NULL, &infoStr[0]); + dbp(infoStr.c_str()); + } + + GLint compiled; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if(!compiled) { + dbp("Failed to compile shader:\n" + "----8<----8<----8<----8<----8<----\n" + "%s\n" + "----8<----8<----8<----8<----8<----\n", + src.c_str()); + } + ssassert(compiled, "Cannot compile shader"); + + return shader; +} + +void Shader::Init(const std::string &vertexRes, const std::string &fragmentRes, + const std::vector > &locations) { + GLuint vert = CompileShader(vertexRes, GL_VERTEX_SHADER); + GLuint frag = CompileShader(fragmentRes, GL_FRAGMENT_SHADER); + + program = glCreateProgram(); + ssassert(program != 0, "glCreateProgram failed"); + + glAttachShader(program, vert); + glAttachShader(program, frag); + for(const auto &l : locations) { + glBindAttribLocation(program, l.first, l.second.c_str()); + } + glLinkProgram(program); + + GLint infoLen; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen); + if(infoLen > 1) { + std::string infoStr(infoLen, '\0'); + glGetProgramInfoLog(program, infoLen, NULL, &infoStr[0]); + dbp(infoStr.c_str()); + } + + GLint linked; + glGetProgramiv(program, GL_LINK_STATUS, &linked); + ssassert(linked, "Cannot link shader"); +} + +void Shader::Clear() { + glDeleteProgram(program); +} + +void Shader::SetUniformMatrix(const char *name, const double *md) { + Enable(); + float mf[16]; + for(int i = 0; i < 16; i++) mf[i] = (float)md[i]; + glUniformMatrix4fv(glGetUniformLocation(program, name), 1, false, mf); +} + +void Shader::SetUniformVector(const char *name, const Vector &v) { + Enable(); + glUniform3f(glGetUniformLocation(program, name), (float)v.x, (float)v.y, (float)v.z); +} + +void Shader::SetUniformVector(const char *name, const Vector4f &v) { + Enable(); + glUniform4f(glGetUniformLocation(program, name), v.x, v.y, v.z, v.w); +} + +void Shader::SetUniformColor(const char *name, RgbaColor c) { + Enable(); + glUniform4f(glGetUniformLocation(program, name), c.redF(), c.greenF(), c.blueF(), c.alphaF()); +} + +void Shader::SetUniformFloat(const char *name, float v) { + Enable(); + glUniform1f(glGetUniformLocation(program, name), v); +} + +void Shader::SetUniformInt(const char *name, GLint v) { + Enable(); + glUniform1i(glGetUniformLocation(program, name), v); +} + +void Shader::SetUniformTextureUnit(const char *name, GLint index) { + Enable(); + glUniform1i(glGetUniformLocation(program, name), index); +} + +void Shader::Enable() const { + glUseProgram(program); +} + +void Shader::Disable() const { + glUseProgram(0); +} + +//----------------------------------------------------------------------------- +// Mesh rendering +//----------------------------------------------------------------------------- + +void MeshRenderer::Init() { + lightShader.Init( + "shaders/mesh.vert", "shaders/mesh.frag", + { + { ATTRIB_POS, "pos" }, + { ATTRIB_NOR, "nor" }, + { ATTRIB_COL, "col" }, + } + ); + + fillShader.Init( + "shaders/mesh_fill.vert", "shaders/mesh_fill.frag", + { + { ATTRIB_POS, "pos" }, + } + ); + fillShader.SetUniformTextureUnit("texture_", 0); + + selectedShader = &lightShader; +} + +void MeshRenderer::Clear() { + lightShader.Clear(); + fillShader.Clear(); +} + +MeshRenderer::Handle MeshRenderer::Add(const SMesh &m, bool dynamic) { + Handle handle; + glGenBuffers(1, &handle.vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, handle.vertexBuffer); + + MeshVertex *vertices = new MeshVertex[m.l.n * 3]; + for(int i = 0; i < m.l.n; i++) { + const STriangle &t = m.l[i]; + vertices[i * 3 + 0].pos = Vector3f::From(t.a); + vertices[i * 3 + 1].pos = Vector3f::From(t.b); + vertices[i * 3 + 2].pos = Vector3f::From(t.c); + + if(t.an.EqualsExactly(Vector::From(0, 0, 0))) { + Vector3f normal = Vector3f::From(t.Normal()); + vertices[i * 3 + 0].nor = normal; + vertices[i * 3 + 1].nor = normal; + vertices[i * 3 + 2].nor = normal; + } else { + vertices[i * 3 + 0].nor = Vector3f::From(t.an); + vertices[i * 3 + 1].nor = Vector3f::From(t.bn); + vertices[i * 3 + 2].nor = Vector3f::From(t.cn); + } + + for(int j = 0; j < 3; j++) { + vertices[i * 3 + j].col = Vector4f::From(t.meta.color); + } + + } + glBufferData(GL_ARRAY_BUFFER, m.l.n * 3 * sizeof(MeshVertex), + vertices, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); + handle.size = m.l.n * 3; + delete []vertices; + + return handle; +} + +void MeshRenderer::Remove(const MeshRenderer::Handle &handle) { + glDeleteBuffers(1, &handle.vertexBuffer); +} + +void MeshRenderer::Draw(const MeshRenderer::Handle &handle, + bool useColors, RgbaColor overrideColor) { + if(handle.size == 0) return; + + selectedShader->Enable(); + + glBindBuffer(GL_ARRAY_BUFFER, handle.vertexBuffer); + + glEnableVertexAttribArray(ATTRIB_POS); + glVertexAttribPointer(ATTRIB_POS, 3, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), + (void *)offsetof(MeshVertex, pos)); + + if(selectedShader == &lightShader) { + glEnableVertexAttribArray(ATTRIB_NOR); + glVertexAttribPointer(ATTRIB_NOR, 3, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), + (void *)offsetof(MeshVertex, nor)); + if(useColors) { + glEnableVertexAttribArray(ATTRIB_COL); + glVertexAttribPointer(ATTRIB_COL, 4, GL_FLOAT, GL_FALSE, sizeof(MeshVertex), + (void *)offsetof(MeshVertex, col)); + } else { + glVertexAttrib4f(ATTRIB_COL, overrideColor.redF(), overrideColor.greenF(), overrideColor.blueF(), overrideColor.alphaF()); + } + } + + glDrawArrays(GL_TRIANGLES, 0, handle.size); + + glDisableVertexAttribArray(ATTRIB_POS); + if(selectedShader == &lightShader) { + glDisableVertexAttribArray(ATTRIB_NOR); + if(useColors) glDisableVertexAttribArray(ATTRIB_COL); + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + selectedShader->Disable(); +} + +void MeshRenderer::Draw(const SMesh &mesh, bool useColors, RgbaColor overrideColor) { + Handle handle = Add(mesh, /*dynamic=*/true); + Draw(handle, useColors, overrideColor); + Remove(handle); +} + +void MeshRenderer::SetModelview(double *matrix) { + lightShader.SetUniformMatrix("modelview", matrix); + fillShader.SetUniformMatrix("modelview", matrix); +} + +void MeshRenderer::SetProjection(double *matrix) { + lightShader.SetUniformMatrix("projection", matrix); + fillShader.SetUniformMatrix("projection", matrix); +} + +void MeshRenderer::UseShaded(const Lighting &lighting) { + Vector dir0 = lighting.lightDirection[0]; + Vector dir1 = lighting.lightDirection[1]; + dir0.z = -dir0.z; + dir1.z = -dir1.z; + + lightShader.SetUniformVector("lightDir0", dir0); + lightShader.SetUniformFloat("lightInt0", (float)lighting.lightIntensity[0]); + lightShader.SetUniformVector("lightDir1", dir1); + lightShader.SetUniformFloat("lightInt1", (float)lighting.lightIntensity[1]); + lightShader.SetUniformFloat("ambient", (float)lighting.ambientIntensity); + selectedShader = &lightShader; +} + +void MeshRenderer::UseFilled(const Canvas::Fill &fill) { + fillShader.SetUniformColor("color", fill.color); + selectedShader = &fillShader; +} + +//----------------------------------------------------------------------------- +// Arrangement of stipple patterns into textures +//----------------------------------------------------------------------------- + +static double Frac(double x) { + return x - floor(x); +} + +static RgbaColor EncodeLengthAsFloat(double v) { + v = max(0.0, min(1.0, v)); + double er = v; + double eg = Frac(255.0 * v); + double eb = Frac(65025.0 * v); + double ea = Frac(160581375.0 * v); + + double r = er - eg / 255.0; + double g = eg - eb / 255.0; + double b = eb - ea / 255.0; + return RgbaColor::From((int)floor( r * 255.0 + 0.5), + (int)floor( g * 255.0 + 0.5), + (int)floor( b * 255.0 + 0.5), + (int)floor(ea * 255.0 + 0.5)); +} + +GLuint Generate(const std::vector &pattern) { + double patternLen = 0.0; + for(double s : pattern) { + patternLen += s; + } + + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + + GLint size; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size); + size /= 2; + + RgbaColor *textureData = new RgbaColor[size]; + int mipCount = (int)log2(size) + 1; + for(int mip = 0; mip < mipCount; mip++) { + int dashI = 0; + double dashT = 0.0; + for(int i = 0; i < size; i++) { + if(pattern.empty()) { + textureData[i] = EncodeLengthAsFloat(0.0); + continue; + } + + double t = (double)i / (double)(size - 1); + while(t - LENGTH_EPS > dashT + pattern[dashI] / patternLen) { + dashT += pattern[dashI] / patternLen; + dashI++; + } + double dashW = pattern[dashI] / patternLen; + if(dashI % 2 == 0) { + textureData[i] = EncodeLengthAsFloat(0.0); + } else { + double value; + if(t - dashT < pattern[dashI] / patternLen / 2.0) { + value = t - dashT; + } else { + value = dashT + dashW - t; + } + value = value * patternLen; + textureData[i] = EncodeLengthAsFloat(value); + } + } + glTexImage2D(GL_TEXTURE_2D, mip, GL_RGBA, size, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, + textureData); + size /= 2; + } + delete []textureData; + + return texture; +} + +void StippleAtlas::Init() { + for(uint32_t i = 0; i <= (uint32_t)StipplePattern::LAST; i++) { + patterns.push_back(Generate(StipplePatternDashes((StipplePattern)i))); + } +} + +void StippleAtlas::Clear() { + for(GLuint p : patterns) { + glDeleteTextures(1, &p); + } +} + +GLint StippleAtlas::GetTexture(StipplePattern pattern) const { + return patterns[(uint32_t)pattern]; +} + +double StippleAtlas::GetLength(StipplePattern pattern) const { + if(pattern == StipplePattern::CONTINUOUS) { + return 1.0; + } + return StipplePatternLength(pattern); +} + +//----------------------------------------------------------------------------- +// Edge rendering +//----------------------------------------------------------------------------- + +void EdgeRenderer::Init(const StippleAtlas *a) { + atlas = a; + shader.Init( + "shaders/edge.vert", "shaders/edge.frag", + { + { ATTRIB_POS, "pos" }, + { ATTRIB_LOC, "loc" }, + { ATTRIB_TAN, "tgt" } + } + ); +} + +void EdgeRenderer::Clear() { + shader.Clear(); +} + +EdgeRenderer::Handle EdgeRenderer::Add(const SEdgeList &edges, bool dynamic) { + Handle handle; + glGenBuffers(1, &handle.vertexBuffer); + glGenBuffers(1, &handle.indexBuffer); + + glBindBuffer(GL_ARRAY_BUFFER, handle.vertexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle.indexBuffer); + + EdgeVertex *vertices = new EdgeVertex[edges.l.n * 8]; + uint32_t *indices = new uint32_t[edges.l.n * 6 * 3]; + double phase = 0.0; + uint32_t curVertex = 0; + uint32_t curIndex = 0; + for(int i = 0; i < edges.l.n; i++) { + const SEdge &curr = edges.l[i]; + const SEdge &next = edges.l[(i + 1) % edges.l.n]; + + // 3d positions + Vector3f a = Vector3f::From(curr.a); + Vector3f b = Vector3f::From(curr.b); + + // tangent + Vector3f tan = Vector3f::From(curr.b.Minus(curr.a)); + + // length + double len = curr.b.Minus(curr.a).Magnitude(); + + // make line start cap + for(int j = 0; j < 2; j++) { + vertices[curVertex + j].pos = a; + vertices[curVertex + j].tan = tan; + } + vertices[curVertex + 0].loc = Vector3f::From(-1.0f, -1.0f, float(phase)); + vertices[curVertex + 1].loc = Vector3f::From(-1.0f, +1.0f, float(phase)); + + indices[curIndex++] = curVertex + 0; + indices[curIndex++] = curVertex + 1; + indices[curIndex++] = curVertex + 2; + indices[curIndex++] = curVertex + 1; + indices[curIndex++] = curVertex + 2; + indices[curIndex++] = curVertex + 3; + + curVertex += 2; + + // make line body + vertices[curVertex + 0].pos = a; + vertices[curVertex + 1].pos = a; + vertices[curVertex + 2].pos = b; + vertices[curVertex + 3].pos = b; + + for(int j = 0; j < 4; j++) { + vertices[curVertex + j].tan = tan; + } + + vertices[curVertex + 0].loc = Vector3f::From( 0.0f, -1.0f, float(phase)); + vertices[curVertex + 1].loc = Vector3f::From( 0.0f, +1.0f, float(phase)); + vertices[curVertex + 2].loc = Vector3f::From( 0.0f, +1.0f, float(phase + len)); + vertices[curVertex + 3].loc = Vector3f::From( 0.0f, -1.0f, float(phase + len)); + + indices[curIndex++] = curVertex + 0; + indices[curIndex++] = curVertex + 1; + indices[curIndex++] = curVertex + 2; + indices[curIndex++] = curVertex + 0; + indices[curIndex++] = curVertex + 2; + indices[curIndex++] = curVertex + 3; + + curVertex += 4; + + // make line end cap + for(int j = 0; j < 2; j++) { + vertices[curVertex + j].pos = b; + vertices[curVertex + j].tan = tan; + } + + vertices[curVertex + 0].loc = Vector3f::From(+1.0, +1.0, float(phase + len)); + vertices[curVertex + 1].loc = Vector3f::From(+1.0, -1.0, float(phase + len)); + + indices[curIndex++] = curVertex - 2; + indices[curIndex++] = curVertex - 1; + indices[curIndex++] = curVertex; + indices[curIndex++] = curVertex - 1; + indices[curIndex++] = curVertex; + indices[curIndex++] = curVertex + 1; + + curVertex += 2; + + // phase stitching + if(curr.a.EqualsExactly(next.a) || + curr.a.EqualsExactly(next.b) || + curr.b.EqualsExactly(next.a) || + curr.b.EqualsExactly(next.b)) + { + phase += len; + } else { + phase = 0.0; + } + } + handle.size = curIndex; + GLenum mode = dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW; + glBufferData(GL_ARRAY_BUFFER, curVertex * sizeof(EdgeVertex), vertices, mode); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, curIndex * sizeof(uint32_t), indices, mode); + delete []vertices; + delete []indices; + + return handle; +} + +void EdgeRenderer::Remove(const EdgeRenderer::Handle &handle) { + glDeleteBuffers(1, &handle.vertexBuffer); + glDeleteBuffers(1, &handle.indexBuffer); +} + +void EdgeRenderer::Draw(const EdgeRenderer::Handle &handle) { + if(handle.size == 0) return; + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, atlas->GetTexture(pattern)); + shader.SetUniformTextureUnit("pattern", 1); + shader.SetUniformFloat("patternLen", (float)atlas->GetLength(pattern)); + + shader.Enable(); + + glBindBuffer(GL_ARRAY_BUFFER, handle.vertexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle.indexBuffer); + + glEnableVertexAttribArray(ATTRIB_POS); + glEnableVertexAttribArray(ATTRIB_LOC); + glEnableVertexAttribArray(ATTRIB_TAN); + + glVertexAttribPointer(ATTRIB_POS, 3, GL_FLOAT, GL_FALSE, sizeof(EdgeVertex), (void *)offsetof(EdgeVertex, pos)); + glVertexAttribPointer(ATTRIB_LOC, 3, GL_FLOAT, GL_FALSE, sizeof(EdgeVertex), (void *)offsetof(EdgeVertex, loc)); + glVertexAttribPointer(ATTRIB_TAN, 3, GL_FLOAT, GL_FALSE, sizeof(EdgeVertex), (void *)offsetof(EdgeVertex, tan)); + glDrawElements(GL_TRIANGLES, handle.size, GL_UNSIGNED_INT, NULL); + + glDisableVertexAttribArray(ATTRIB_POS); + glDisableVertexAttribArray(ATTRIB_LOC); + glDisableVertexAttribArray(ATTRIB_TAN); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + shader.Disable(); +} + +void EdgeRenderer::Draw(const SEdgeList &edges) { + Handle handle = Add(edges, /*dynamic=*/true); + Draw(handle); + Remove(handle); +} + +void EdgeRenderer::SetModelview(const double *matrix) { + shader.SetUniformMatrix("modelview", matrix); +} + +void EdgeRenderer::SetProjection(const double *matrix) { + shader.SetUniformMatrix("projection", matrix); +} + +void EdgeRenderer::SetStroke(const Canvas::Stroke &stroke, double pixel) { + double unitScale = stroke.unit == Canvas::Unit::PX ? pixel : 1.0; + shader.SetUniformFloat("width", float(stroke.width * unitScale / 2.0)); + shader.SetUniformColor("color", stroke.color); + shader.SetUniformFloat("patternScale", float(stroke.stippleScale * unitScale * 2.0)); + shader.SetUniformFloat("pixel", (float)pixel); + pattern = stroke.stipplePattern; +} + +//----------------------------------------------------------------------------- +// Outline rendering +//----------------------------------------------------------------------------- + +void OutlineRenderer::Init(const StippleAtlas *a) { + atlas = a; + shader.Init( + "shaders/outline.vert", "shaders/edge.frag", + { + { ATTRIB_POS, "pos" }, + { ATTRIB_LOC, "loc" }, + { ATTRIB_TAN, "tgt" }, + { ATTRIB_NOL, "nol" }, + { ATTRIB_NOR, "nor" } + } + ); +} + +void OutlineRenderer::Clear() { + shader.Clear(); +} + +OutlineRenderer::Handle OutlineRenderer::Add(const SOutlineList &outlines, bool dynamic) { + Handle handle; + glGenBuffers(1, &handle.vertexBuffer); + glGenBuffers(1, &handle.indexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, handle.vertexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle.indexBuffer); + + OutlineVertex *vertices = new OutlineVertex[outlines.l.n * 8]; + uint32_t *indices = new uint32_t[outlines.l.n * 6 * 3]; + double phase = 0.0; + uint32_t curVertex = 0; + uint32_t curIndex = 0; + + for(int i = 0; i < outlines.l.n; i++) { + const SOutline &curr = outlines.l[i]; + const SOutline &next = outlines.l[(i + 1) % outlines.l.n]; + + // 3d positions + Vector3f a = Vector3f::From(curr.a); + Vector3f b = Vector3f::From(curr.b); + Vector3f nl = Vector3f::From(curr.nl); + Vector3f nr = Vector3f::From(curr.nr); + + // tangent + Vector3f tan = Vector3f::From(curr.b.Minus(curr.a)); + + // length + double len = curr.b.Minus(curr.a).Magnitude(); + float tag = (float)curr.tag; + + // make line start cap + for(int j = 0; j < 2; j++) { + vertices[curVertex + j].pos = a; + vertices[curVertex + j].nol = nl; + vertices[curVertex + j].nor = nr; + vertices[curVertex + j].tan = tan; + } + + vertices[curVertex + 0].loc = Vector4f::From(-1.0f, -1.0f, float(phase), (float)tag); + vertices[curVertex + 1].loc = Vector4f::From(-1.0f, +1.0f, float(phase), (float)tag); + + indices[curIndex++] = curVertex; + indices[curIndex++] = curVertex + 1; + indices[curIndex++] = curVertex + 2; + indices[curIndex++] = curVertex + 1; + indices[curIndex++] = curVertex + 2; + indices[curIndex++] = curVertex + 3; + + curVertex += 2; + + // make line body + vertices[curVertex + 0].pos = a; + vertices[curVertex + 1].pos = a; + vertices[curVertex + 2].pos = b; + vertices[curVertex + 3].pos = b; + + for(int j = 0; j < 4; j++) { + vertices[curVertex + j].nol = nl; + vertices[curVertex + j].nor = nr; + vertices[curVertex + j].tan = tan; + } + + vertices[curVertex + 0].loc = Vector4f::From( 0.0f, -1.0f, float(phase), (float)tag); + vertices[curVertex + 1].loc = Vector4f::From( 0.0f, +1.0f, float(phase), (float)tag); + vertices[curVertex + 2].loc = Vector4f::From( 0.0f, +1.0f, + float(phase + len), (float)tag); + vertices[curVertex + 3].loc = Vector4f::From( 0.0f, -1.0f, + float(phase + len), (float)tag); + + indices[curIndex++] = curVertex + 0; + indices[curIndex++] = curVertex + 1; + indices[curIndex++] = curVertex + 2; + indices[curIndex++] = curVertex + 0; + indices[curIndex++] = curVertex + 2; + indices[curIndex++] = curVertex + 3; + + curVertex += 4; + + // make line end cap + for(int j = 0; j < 2; j++) { + vertices[curVertex + j].pos = b; + vertices[curVertex + j].nol = nl; + vertices[curVertex + j].nor = nr; + vertices[curVertex + j].tan = tan; + } + + vertices[curVertex + 0].loc = Vector4f::From(+1.0f, +1.0f, float(phase + len), (float)tag); + vertices[curVertex + 1].loc = Vector4f::From(+1.0f, -1.0f, float(phase + len), (float)tag); + + indices[curIndex++] = curVertex - 2; + indices[curIndex++] = curVertex - 1; + indices[curIndex++] = curVertex; + indices[curIndex++] = curVertex - 1; + indices[curIndex++] = curVertex; + indices[curIndex++] = curVertex + 1; + + curVertex += 2; + + // phase stitching + if(curr.a.EqualsExactly(next.a) || + curr.a.EqualsExactly(next.b) || + curr.b.EqualsExactly(next.a) || + curr.b.EqualsExactly(next.b)) + { + phase += len; + } else { + phase = 0.0; + } + } + handle.size = curIndex; + GLenum mode = dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW; + glBufferData(GL_ARRAY_BUFFER, curVertex * sizeof(OutlineVertex), vertices, mode); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, curIndex * sizeof(uint32_t), indices, mode); + + delete []vertices; + delete []indices; + return handle; +} + +void OutlineRenderer::Remove(const OutlineRenderer::Handle &handle) { + glDeleteBuffers(1, &handle.vertexBuffer); + glDeleteBuffers(1, &handle.indexBuffer); +} + +void OutlineRenderer::Draw(const OutlineRenderer::Handle &handle, Canvas::DrawOutlinesAs mode) { + if(handle.size == 0) return; + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, atlas->GetTexture(pattern)); + shader.SetUniformTextureUnit("pattern", 1); + shader.SetUniformFloat("patternLen", (float)atlas->GetLength(pattern)); + shader.SetUniformInt("mode", (GLint)mode); + + shader.Enable(); + + glBindBuffer(GL_ARRAY_BUFFER, handle.vertexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle.indexBuffer); + + glEnableVertexAttribArray(ATTRIB_POS); + glEnableVertexAttribArray(ATTRIB_LOC); + glEnableVertexAttribArray(ATTRIB_TAN); + glEnableVertexAttribArray(ATTRIB_NOL); + glEnableVertexAttribArray(ATTRIB_NOR); + + glVertexAttribPointer(ATTRIB_POS, 3, GL_FLOAT, GL_FALSE, sizeof(OutlineVertex), + (void *)offsetof(OutlineVertex, pos)); + glVertexAttribPointer(ATTRIB_LOC, 4, GL_FLOAT, GL_FALSE, sizeof(OutlineVertex), + (void *)offsetof(OutlineVertex, loc)); + glVertexAttribPointer(ATTRIB_TAN, 3, GL_FLOAT, GL_FALSE, sizeof(OutlineVertex), + (void *)offsetof(OutlineVertex, tan)); + glVertexAttribPointer(ATTRIB_NOL, 3, GL_FLOAT, GL_FALSE, sizeof(OutlineVertex), + (void *)offsetof(OutlineVertex, nol)); + glVertexAttribPointer(ATTRIB_NOR, 3, GL_FLOAT, GL_FALSE, sizeof(OutlineVertex), + (void *)offsetof(OutlineVertex, nor)); + glDrawElements(GL_TRIANGLES, handle.size, GL_UNSIGNED_INT, NULL); + + glDisableVertexAttribArray(ATTRIB_POS); + glDisableVertexAttribArray(ATTRIB_LOC); + glDisableVertexAttribArray(ATTRIB_TAN); + glDisableVertexAttribArray(ATTRIB_NOL); + glDisableVertexAttribArray(ATTRIB_NOR); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + shader.Disable(); +} + +void OutlineRenderer::Draw(const SOutlineList &outlines, Canvas::DrawOutlinesAs drawAs) { + Handle handle = Add(outlines, /*dynamic=*/true); + Draw(handle, drawAs); + Remove(handle); +} + +void OutlineRenderer::SetModelview(const double *matrix) { + shader.SetUniformMatrix("modelview", matrix); +} + +void OutlineRenderer::SetProjection(const double *matrix) { + shader.SetUniformMatrix("projection", matrix); +} + +void OutlineRenderer::SetStroke(const Canvas::Stroke &stroke, double pixel) { + double unitScale = (stroke.unit == Canvas::Unit::PX) ? pixel : 1.0; + shader.SetUniformFloat("width", (float)(stroke.width * unitScale / 2.0)); + shader.SetUniformColor("color", stroke.color); + shader.SetUniformFloat("patternScale", (float)(stroke.stippleScale * unitScale * 2.0)); + shader.SetUniformFloat("pixel", (float)pixel); + pattern = stroke.stipplePattern; +} + +//----------------------------------------------------------------------------- +// Indexed mesh storage +//----------------------------------------------------------------------------- + +void SIndexedMesh::AddPoint(const Vector &p) { + uint32_t vstart = vertices.size(); + vertices.resize(vertices.size() + 4); + + vertices[vstart + 0].pos = Vector3f::From(p); + vertices[vstart + 0].tex = Vector2f::From(-1.0f, -1.0f); + vertices[vstart + 1].pos = Vector3f::From(p); + vertices[vstart + 1].tex = Vector2f::From(+1.0f, -1.0f); + vertices[vstart + 2].pos = Vector3f::From(p); + vertices[vstart + 2].tex = Vector2f::From(+1.0f, +1.0f); + vertices[vstart + 3].pos = Vector3f::From(p); + vertices[vstart + 3].tex = Vector2f::From(-1.0f, +1.0f); + + size_t istart = indices.size(); + indices.resize(indices.size() + 6); + + indices[istart + 0] = vstart + 0; + indices[istart + 1] = vstart + 1; + indices[istart + 2] = vstart + 2; + indices[istart + 3] = vstart + 0; + indices[istart + 4] = vstart + 2; + indices[istart + 5] = vstart + 3; +} + +void SIndexedMesh::AddQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d) { + uint32_t vstart = vertices.size(); + vertices.resize(vertices.size() + 4); + + vertices[vstart + 0].pos = Vector3f::From(a); + vertices[vstart + 1].pos = Vector3f::From(b); + vertices[vstart + 2].pos = Vector3f::From(c); + vertices[vstart + 3].pos = Vector3f::From(d); + + size_t istart = indices.size(); + indices.resize(indices.size() + 6); + + indices[istart + 0] = vstart + 0; + indices[istart + 1] = vstart + 1; + indices[istart + 2] = vstart + 2; + indices[istart + 3] = vstart + 0; + indices[istart + 4] = vstart + 2; + indices[istart + 5] = vstart + 3; +} + +void SIndexedMesh::AddPixmap(const Vector &o, const Vector &u, const Vector &v, + const Point2d &ta, const Point2d &tb) { + uint32_t vstart = vertices.size(); + vertices.resize(vertices.size() + 4); + + vertices[vstart + 0].pos = Vector3f::From(o); + vertices[vstart + 0].tex = Vector2f::From(ta.x, ta.y); + + vertices[vstart + 1].pos = Vector3f::From(o.Plus(v)); + vertices[vstart + 1].tex = Vector2f::From(ta.x, tb.y); + + vertices[vstart + 2].pos = Vector3f::From(o.Plus(u).Plus(v)); + vertices[vstart + 2].tex = Vector2f::From(tb.x, tb.y); + + vertices[vstart + 3].pos = Vector3f::From(o.Plus(u)); + vertices[vstart + 3].tex = Vector2f::From(tb.x, ta.y); + + size_t istart = indices.size(); + indices.resize(indices.size() + 6); + + indices[istart + 0] = vstart + 0; + indices[istart + 1] = vstart + 1; + indices[istart + 2] = vstart + 2; + indices[istart + 3] = vstart + 0; + indices[istart + 4] = vstart + 2; + indices[istart + 5] = vstart + 3; +} + +void SIndexedMesh::Clear() { + vertices.clear(); + indices.clear(); +} + +//----------------------------------------------------------------------------- +// Indexed mesh rendering +//----------------------------------------------------------------------------- + +void IndexedMeshRenderer::Init() { + colShader.Init( + "shaders/imesh.vert", "shaders/imesh.frag", + { + { ATTRIB_POS, "pos" } + } + ); + texShader.Init( + "shaders/imesh_tex.vert", "shaders/imesh_tex.frag", + { + { ATTRIB_POS, "pos" }, + { ATTRIB_TEX, "tex" } + } + ); + texaShader.Init( + "shaders/imesh_tex.vert", "shaders/imesh_texa.frag", + { + { ATTRIB_POS, "pos" }, + { ATTRIB_TEX, "tex" } + } + ); + pointShader.Init( + "shaders/imesh_point.vert", "shaders/imesh_point.frag", + { + { ATTRIB_POS, "pos" }, + { ATTRIB_TEX, "loc" } + } + ); + + texShader.SetUniformTextureUnit("texture_", 0); + texaShader.SetUniformTextureUnit("texture_", 0); + selectedShader = &colShader; +} + +void IndexedMeshRenderer::Clear() { + texShader.Clear(); + texaShader.Clear(); + colShader.Clear(); + pointShader.Clear(); +} + +IndexedMeshRenderer::Handle IndexedMeshRenderer::Add(const SIndexedMesh &m, bool dynamic) { + Handle handle; + glGenBuffers(1, &handle.vertexBuffer); + glGenBuffers(1, &handle.indexBuffer); + + GLenum mode = dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW; + glBindBuffer(GL_ARRAY_BUFFER, handle.vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, m.vertices.size() * sizeof(SIndexedMesh::Vertex), + m.vertices.data(), mode); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle.indexBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, m.indices.size() * sizeof(uint32_t), + m.indices.data(), mode); + handle.size = m.indices.size(); + return handle; +} + +void IndexedMeshRenderer::Remove(const IndexedMeshRenderer::Handle &handle) { + glDeleteBuffers(1, &handle.vertexBuffer); + glDeleteBuffers(1, &handle.indexBuffer); +} + +void IndexedMeshRenderer::Draw(const IndexedMeshRenderer::Handle &handle) { + if(handle.size == 0) return; + + selectedShader->Enable(); + + glBindBuffer(GL_ARRAY_BUFFER, handle.vertexBuffer); + glEnableVertexAttribArray(ATTRIB_POS); + glVertexAttribPointer(ATTRIB_POS, 3, GL_FLOAT, GL_FALSE, sizeof(SIndexedMesh::Vertex), + (void *)offsetof(SIndexedMesh::Vertex, pos)); + if(NeedsTexture()) { + glEnableVertexAttribArray(ATTRIB_TEX); + glVertexAttribPointer(ATTRIB_TEX, 2, GL_FLOAT, GL_FALSE, sizeof(SIndexedMesh::Vertex), + (void *)offsetof(SIndexedMesh::Vertex, tex)); + } + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, handle.indexBuffer); + glDrawElements(GL_TRIANGLES, handle.size, GL_UNSIGNED_INT, NULL); + + glDisableVertexAttribArray(ATTRIB_POS); + if(NeedsTexture()) glDisableVertexAttribArray(ATTRIB_TEX); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + selectedShader->Disable(); +} + +void IndexedMeshRenderer::Draw(const SIndexedMesh &mesh) { + Handle handle = Add(mesh, /*dynamic=*/true) ; + Draw(handle); + Remove(handle); +} + +bool IndexedMeshRenderer::NeedsTexture() const { + return selectedShader == &texShader || + selectedShader == &texaShader || + selectedShader == &pointShader; +} + +void IndexedMeshRenderer::SetModelview(const double *matrix) { + colShader.SetUniformMatrix("modelview", matrix); + texShader.SetUniformMatrix("modelview", matrix); + texaShader.SetUniformMatrix("modelview", matrix); + pointShader.SetUniformMatrix("modelview", matrix); +} + +void IndexedMeshRenderer::SetProjection(const double *matrix) { + colShader.SetUniformMatrix("projection", matrix); + texShader.SetUniformMatrix("projection", matrix); + texaShader.SetUniformMatrix("projection", matrix); + pointShader.SetUniformMatrix("projection", matrix); +} + +void IndexedMeshRenderer::UseFilled(const Canvas::Fill &fill) { + if(fill.texture) { + selectedShader = (fill.texture->format == Pixmap::Format::A) ? &texaShader : &texShader; + } else { + selectedShader = &colShader; + } + selectedShader->SetUniformColor("color", fill.color); +} + +void IndexedMeshRenderer::UsePoint(const Canvas::Stroke &stroke, double pixel) { + pointShader.SetUniformColor("color", stroke.color); + pointShader.SetUniformFloat("width", (float)(stroke.width * pixel / 2.0)); + pointShader.SetUniformFloat("pixel", (float)pixel); + selectedShader = &pointShader; +} + +} diff --git a/src/render/gl3shader.h b/src/render/gl3shader.h new file mode 100644 index 0000000..1831e79 --- /dev/null +++ b/src/render/gl3shader.h @@ -0,0 +1,266 @@ +//----------------------------------------------------------------------------- +// OpenGL ES 2.0 and OpenGL 3.0 shader interface. +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +#ifndef SOLVESPACE_GL3SHADER_H +#define SOLVESPACE_GL3SHADER_H + +#if defined(WIN32) +# define GL_APICALL /*static linkage*/ +# define GL_GLEXT_PROTOTYPES +# include +# include +# define HAVE_GLES +#elif defined(__APPLE__) +# include +#else +# define GL_GLEXT_PROTOTYPES +# include +# include +#endif + +#if !defined(HAVE_GLES) +// glDepthRange is in GL1+ but not GLES2, glDepthRangef is in GL4.1+ and GLES2. +// Consistency! +# define glClearDepthf glClearDepth +# define glDepthRangef glDepthRange +#endif + +namespace SolveSpace { + +//----------------------------------------------------------------------------- +// Floating-point data structures; the layout of these must match shaders +//----------------------------------------------------------------------------- + +class Vector2f { +public: + float x, y; + + static Vector2f From(float x, float y); + static Vector2f From(double x, double y); + static Vector2f FromInt(uint32_t x, uint32_t y); +}; + +class Vector3f { +public: + float x, y, z; + + static Vector3f From(float x, float y, float z); + static Vector3f From(const Vector &v); + static Vector3f From(const RgbaColor &c); +}; + +class Vector4f { +public: + float x, y, z, w; + + static Vector4f From(float x, float y, float z, float w); + static Vector4f From(const Vector &v, float w); + static Vector4f FromInt(uint32_t x, uint32_t y, uint32_t z, uint32_t w); + static Vector4f From(const RgbaColor &c); +}; + +//----------------------------------------------------------------------------- +// Wrappers for our shaders +//----------------------------------------------------------------------------- + +class Shader { +public: + GLuint program = 0; + + void Init(const std::string &vertexRes, + const std::string &fragmentRes, + const std::vector> &locations = {}); + void Clear(); + + void SetUniformMatrix(const char *name, const double *md); + void SetUniformVector(const char *name, const Vector &v); + void SetUniformVector(const char *name, const Vector4f &v); + void SetUniformColor(const char *name, RgbaColor c); + void SetUniformFloat(const char *name, float v); + void SetUniformInt(const char *name, GLint v); + void SetUniformTextureUnit(const char *name, GLint index); + void Enable() const; + void Disable() const; +}; + +class MeshRenderer { +public: + const GLint ATTRIB_POS = 0; + const GLint ATTRIB_NOR = 1; + const GLint ATTRIB_COL = 2; + + struct MeshVertex { + Vector3f pos; + Vector3f nor; + Vector4f col; + }; + + struct Handle { + GLuint vertexBuffer; + GLsizei size; + }; + + Shader lightShader; + Shader fillShader; + Shader *selectedShader = NULL; + + void Init(); + void Clear(); + + Handle Add(const SMesh &m, bool dynamic = false); + void Remove(const Handle &handle); + void Draw(const Handle &handle, bool useColors = true, RgbaColor overrideColor = {}); + void Draw(const SMesh &mesh, bool useColors = true, RgbaColor overrideColor = {}); + + void SetModelview(double *matrix); + void SetProjection(double *matrix); + + void UseShaded(const Lighting &lighting); + void UseFilled(const Canvas::Fill &fill); +}; + +class StippleAtlas { +public: + std::vector patterns; + + void Init(); + void Clear(); + + GLint GetTexture(StipplePattern pattern) const; + double GetLength(StipplePattern pattern) const; +}; + +class EdgeRenderer { +public: + const GLint ATTRIB_POS = 0; + const GLint ATTRIB_LOC = 1; + const GLint ATTRIB_TAN = 2; + + struct EdgeVertex { + Vector3f pos; + Vector3f loc; + Vector3f tan; + }; + + struct Handle { + GLuint vertexBuffer; + GLuint indexBuffer; + GLsizei size; + }; + + Shader shader; + + const StippleAtlas *atlas = NULL; + StipplePattern pattern = StipplePattern::CONTINUOUS; + + void Init(const StippleAtlas *atlas); + void Clear(); + + Handle Add(const SEdgeList &edges, bool dynamic = false); + void Remove(const Handle &handle); + void Draw(const Handle &handle); + void Draw(const SEdgeList &edges); + + void SetModelview(const double *matrix); + void SetProjection(const double *matrix); + void SetStroke(const Canvas::Stroke &stroke, double pixel); +}; + +class OutlineRenderer { +public: + const GLint ATTRIB_POS = 0; + const GLint ATTRIB_LOC = 1; + const GLint ATTRIB_TAN = 2; + const GLint ATTRIB_NOL = 3; + const GLint ATTRIB_NOR = 4; + + struct OutlineVertex { + Vector3f pos; + Vector4f loc; + Vector3f tan; + Vector3f nol; + Vector3f nor; + }; + + struct Handle { + GLuint vertexBuffer; + GLuint indexBuffer; + GLsizei size; + }; + + Shader shader; + + const StippleAtlas *atlas = NULL; + StipplePattern pattern = StipplePattern::CONTINUOUS; + + void Init(const StippleAtlas *atlas); + void Clear(); + + Handle Add(const SOutlineList &outlines, bool dynamic = false); + void Remove(const Handle &handle); + void Draw(const Handle &handle, Canvas::DrawOutlinesAs mode); + void Draw(const SOutlineList &outlines, Canvas::DrawOutlinesAs mode); + + void SetModelview(const double *matrix); + void SetProjection(const double *matrix); + void SetStroke(const Canvas::Stroke &stroke, double pixel); +}; + +class SIndexedMesh { +public: + struct Vertex { + Vector3f pos; + Vector2f tex; + }; + + std::vector vertices; + std::vector indices; + + void AddPoint(const Vector &p); + void AddQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d); + void AddPixmap(const Vector &o, const Vector &u, const Vector &v, + const Point2d &ta, const Point2d &tb); + + void Clear(); +}; + +class IndexedMeshRenderer { +public: + const GLint ATTRIB_POS = 0; + const GLint ATTRIB_TEX = 1; + + struct Handle { + GLuint vertexBuffer; + GLuint indexBuffer; + GLsizei size; + }; + + Shader texShader; + Shader texaShader; + Shader colShader; + Shader pointShader; + + Shader *selectedShader = NULL; + + void Init(); + void Clear(); + + Handle Add(const SIndexedMesh &m, bool dynamic = false); + void Remove(const Handle &handle); + void Draw(const Handle &handle); + void Draw(const SIndexedMesh &mesh); + + void SetModelview(const double *matrix); + void SetProjection(const double *matrix); + + bool NeedsTexture() const; + + void UseFilled(const Canvas::Fill &fill); + void UsePoint(const Canvas::Stroke &stroke, double pixel); +}; + +} + +#endif diff --git a/src/render/render.cpp b/src/render/render.cpp new file mode 100644 index 0000000..89434c2 --- /dev/null +++ b/src/render/render.cpp @@ -0,0 +1,459 @@ +//----------------------------------------------------------------------------- +// Backend-agnostic rendering interface, and various backends we use. +// +// Copyright 2016 whitequark +//----------------------------------------------------------------------------- +#include "solvespace.h" + +namespace SolveSpace { + +//----------------------------------------------------------------------------- +// Camera transformations. +//----------------------------------------------------------------------------- + +Point2d Camera::ProjectPoint(Vector p) const { + Vector p3 = ProjectPoint3(p); + Point2d p2 = { p3.x, p3.y }; + return p2; +} + +Vector Camera::ProjectPoint3(Vector p) const { + double w; + Vector r = ProjectPoint4(p, &w); + return r.ScaledBy(scale/w); +} + +Vector Camera::ProjectPoint4(Vector p, double *w) const { + p = p.Plus(offset); + + Vector r; + r.x = p.Dot(projRight); + r.y = p.Dot(projUp); + r.z = p.Dot(projUp.Cross(projRight)); + + *w = 1 + r.z*tangent*scale; + return r; +} + +Vector Camera::UnProjectPoint(Point2d p) const { + Vector orig = offset.ScaledBy(-1); + + // Note that we're ignoring the effects of perspective. Since our returned + // point has the same component normal to the screen as the offset, it + // will have z = 0 after the rotation is applied, thus w = 1. So this is + // correct. + orig = orig.Plus(projRight.ScaledBy(p.x / scale)).Plus( + projUp. ScaledBy(p.y / scale)); + return orig; +} + +Vector Camera::UnProjectPoint3(Vector p) const { + p.z = p.z / (scale - p.z * tangent * scale); + double w = 1 + p.z * tangent * scale; + p.x *= w / scale; + p.y *= w / scale; + + Vector orig = offset.ScaledBy(-1); + orig = orig.Plus(projRight.ScaledBy(p.x)).Plus( + projUp. ScaledBy(p.y).Plus( + projUp.Cross(projRight). ScaledBy(p.z))); + return orig; +} + +Vector Camera::VectorFromProjs(Vector rightUpForward) const { + Vector n = projRight.Cross(projUp); + + Vector r = (projRight.ScaledBy(rightUpForward.x)); + r = r.Plus(projUp.ScaledBy(rightUpForward.y)); + r = r.Plus(n.ScaledBy(rightUpForward.z)); + return r; +} + +Vector Camera::AlignToPixelGrid(Vector v) const { + if(!gridFit) return v; + + v = ProjectPoint3(v); + v.x = floor(v.x) + 0.5; + v.y = floor(v.y) + 0.5; + return UnProjectPoint3(v); +} + +SBezier Camera::ProjectBezier(SBezier b) const { + Quaternion q = Quaternion::From(projRight, projUp); + q = q.Inverse(); + // we want Q*(p - o) = Q*p - Q*o + b = b.TransformedBy(q.Rotate(offset).ScaledBy(scale), q, scale); + for(int i = 0; i <= b.deg; i++) { + Vector4 ct = Vector4::From(b.weight[i], b.ctrl[i]); + // so the desired curve, before perspective, is + // (x/w, y/w, z/w) + // and after perspective is + // ((x/w)/(1 - (z/w)*tangent, ... + // = (x/(w - z*tangent), ... + // so we want to let w' = w - z*tangent + ct.w = ct.w - ct.z*tangent; + + b.ctrl[i] = ct.PerspectiveProject(); + b.weight[i] = ct.w; + } + return b; +} + +void Camera::LoadIdentity() { + offset = { 0.0, 0.0, 0.0 }; + projRight = { 1.0, 0.0, 0.0 }; + projUp = { 0.0, 1.0, 0.0 }; + scale = 1.0; + tangent = 0.0; +} + +void Camera::NormalizeProjectionVectors() { + if(projRight.Magnitude() < LENGTH_EPS) { + projRight = Vector::From(1, 0, 0); + } + + Vector norm = projRight.Cross(projUp); + // If projRight and projUp somehow ended up parallel, then pick an + // arbitrary projUp normal to projRight. + if(norm.Magnitude() < LENGTH_EPS) { + norm = projRight.Normal(0); + } + projUp = norm.Cross(projRight); + + projUp = projUp.WithMagnitude(1); + projRight = projRight.WithMagnitude(1); +} + +//----------------------------------------------------------------------------- +// Stroke and fill caching. +//----------------------------------------------------------------------------- + +bool Canvas::Stroke::Equals(const Stroke &other) const { + return (layer == other.layer && + zIndex == other.zIndex && + color.Equals(other.color) && + width == other.width && + unit == other.unit && + stipplePattern == other.stipplePattern && + stippleScale == other.stippleScale); +} + +double Canvas::Stroke::WidthMm(const Camera &camera) const { + switch(unit) { + case Canvas::Unit::MM: + return width; + case Canvas::Unit::PX: + return width / camera.scale; + default: + ssassert(false, "Unexpected unit"); + } +} + +double Canvas::Stroke::WidthPx(const Camera &camera) const { + switch(unit) { + case Canvas::Unit::MM: + return width * camera.scale; + case Canvas::Unit::PX: + return width; + default: + ssassert(false, "Unexpected unit"); + } +} + +double Canvas::Stroke::StippleScaleMm(const Camera &camera) const { + switch(unit) { + case Canvas::Unit::MM: + return stippleScale; + case Canvas::Unit::PX: + return stippleScale / camera.scale; + default: + ssassert(false, "Unexpected unit"); + } +} + +double Canvas::Stroke::StippleScalePx(const Camera &camera) const { + switch(unit) { + case Canvas::Unit::MM: + return stippleScale * camera.scale; + case Canvas::Unit::PX: + return stippleScale; + default: + ssassert(false, "Unexpected unit"); + } +} + +bool Canvas::Fill::Equals(const Fill &other) const { + return (layer == other.layer && + zIndex == other.zIndex && + color.Equals(other.color) && + pattern == other.pattern && + texture == other.texture); +} + +void Canvas::Clear() { + strokes.Clear(); + fills.Clear(); +} + +Canvas::hStroke Canvas::GetStroke(const Stroke &stroke) { + for(const Stroke &s : strokes) { + if(s.Equals(stroke)) return s.h; + } + Stroke strokeCopy = stroke; + return strokes.AddAndAssignId(&strokeCopy); +} + +Canvas::hFill Canvas::GetFill(const Fill &fill) { + for(const Fill &f : fills) { + if(f.Equals(fill)) return f.h; + } + Fill fillCopy = fill; + return fills.AddAndAssignId(&fillCopy); +} + +BitmapFont *Canvas::GetBitmapFont() { + if(bitmapFont.IsEmpty()) { + bitmapFont = BitmapFont::Create(); + } + return &bitmapFont; +} + +std::shared_ptr Canvas::CreateBatch() { + return std::shared_ptr(); +} + +//----------------------------------------------------------------------------- +// An interface for view-independent visualization +//----------------------------------------------------------------------------- + +const Camera &BatchCanvas::GetCamera() const { + ssassert(false, "Geometry drawn on BatchCanvas must be independent from camera"); +} + +//----------------------------------------------------------------------------- +// A wrapper around Canvas that simplifies drawing UI in screen coordinates +//----------------------------------------------------------------------------- + +void UiCanvas::DrawLine(int x1, int y1, int x2, int y2, RgbaColor color, int width, int zIndex) { + Vector va = { (double)x1 + 0.5, (double)Flip(y1) + 0.5, 0.0 }, + vb = { (double)x2 + 0.5, (double)Flip(y2) + 0.5, 0.0 }; + + Canvas::Stroke stroke = {}; + stroke.layer = Canvas::Layer::NORMAL; + stroke.zIndex = zIndex; + stroke.width = (double)width; + stroke.color = color; + stroke.unit = Canvas::Unit::PX; + Canvas::hStroke hcs = canvas->GetStroke(stroke); + + canvas->DrawLine(va, vb, hcs); +} + +void UiCanvas::DrawRect(int l, int r, int t, int b, RgbaColor fillColor, RgbaColor outlineColor, + int zIndex) { + Vector va = { (double)l + 0.5, (double)Flip(b) + 0.5, 0.0 }, + vb = { (double)l + 0.5, (double)Flip(t) + 0.5, 0.0 }, + vc = { (double)r + 0.5, (double)Flip(t) + 0.5, 0.0 }, + vd = { (double)r + 0.5, (double)Flip(b) + 0.5, 0.0 }; + + if(!fillColor.IsEmpty()) { + Canvas::Fill fill = {}; + fill.layer = Canvas::Layer::NORMAL; + fill.zIndex = zIndex; + fill.color = fillColor; + Canvas::hFill hcf = canvas->GetFill(fill); + + canvas->DrawQuad(va, vb, vc, vd, hcf); + } + + if(!outlineColor.IsEmpty()) { + Canvas::Stroke stroke = {}; + stroke.layer = Canvas::Layer::NORMAL; + stroke.zIndex = zIndex; + stroke.width = 1.0; + stroke.color = outlineColor; + stroke.unit = Canvas::Unit::PX; + Canvas::hStroke hcs = canvas->GetStroke(stroke); + + canvas->DrawLine(va, vb, hcs); + canvas->DrawLine(vb, vc, hcs); + canvas->DrawLine(vc, vd, hcs); + canvas->DrawLine(vd, va, hcs); + } +} + +void UiCanvas::DrawPixmap(std::shared_ptr pm, int x, int y, int zIndex) { + Canvas::Fill fill = {}; + fill.layer = Canvas::Layer::NORMAL; + fill.zIndex = zIndex; + fill.color = { 255, 255, 255, 255 }; + Canvas::hFill hcf = canvas->GetFill(fill); + + canvas->DrawPixmap(pm, + { (double)x, (double)(flip ? Flip(y) - pm->height : y), 0.0 }, + { (double)pm->width, 0.0, 0.0 }, + { 0.0, (double)pm->height, 0.0 }, + { 0.0, 1.0 }, + { 1.0, 0.0 }, + hcf); +} + +void UiCanvas::DrawBitmapChar(char32_t codepoint, int x, int y, RgbaColor color, int zIndex) { + BitmapFont *font = canvas->GetBitmapFont(); + + Canvas::Fill fill = {}; + fill.layer = Canvas::Layer::NORMAL; + fill.zIndex = zIndex; + fill.color = color; + Canvas::hFill hcf = canvas->GetFill(fill); + + if(codepoint >= 0xe000 && codepoint <= 0xefff) { + // Special character, like a checkbox or a radio button + x -= 3; + } + + double s0, t0, s1, t1; + size_t w, h; + font->LocateGlyph(codepoint, &s0, &t0, &s1, &t1, &w, &h); + if(font->textureUpdated) { + // LocateGlyph modified the texture, reload it. + canvas->InvalidatePixmap(font->texture); + font->textureUpdated = false; + } + + canvas->DrawPixmap(font->texture, + { (double)x, (double)Flip(y), 0.0 }, + { (double)w, 0.0, 0.0 }, + { 0.0, (double) h, 0.0 }, + { s0, t1 }, + { s1, t0 }, + hcf); +} + +void UiCanvas::DrawBitmapText(const std::string &str, int x, int y, RgbaColor color, int zIndex) { + BitmapFont *font = canvas->GetBitmapFont(); + + for(char32_t codepoint : ReadUTF8(str)) { + DrawBitmapChar(codepoint, x, y, color, zIndex); + x += (int)font->GetWidth(codepoint) * 8; + } +} + +//----------------------------------------------------------------------------- +// A canvas that performs picking against drawn geometry. +//----------------------------------------------------------------------------- + +void ObjectPicker::DoCompare(double depth, double distance, int zIndex, int comparePosition) { + if(distance > selRadius) return; + if((zIndex == maxZIndex && distance < minDistance) || (zIndex > maxZIndex)) { + minDepth = depth; + minDistance = distance; + maxZIndex = zIndex; + position = comparePosition; + } +} + +void ObjectPicker::DoQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d, + int zIndex, int comparePosition) { + Point2d corners[4] = { + camera.ProjectPoint(a), + camera.ProjectPoint(b), + camera.ProjectPoint(c), + camera.ProjectPoint(d) + }; + double minNegative = VERY_NEGATIVE, + maxPositive = VERY_POSITIVE; + for(int i = 0; i < 4; i++) { + Point2d ap = corners[i], + bp = corners[(i + 1) % 4]; + double distance = point.DistanceToLineSigned(ap, bp.Minus(ap), /*asSegment=*/true); + if(distance < 0) minNegative = std::max(minNegative, distance); + if(distance > 0) maxPositive = std::min(maxPositive, distance); + } + + bool insideQuad = (minNegative == VERY_NEGATIVE || maxPositive == VERY_POSITIVE); + if(insideQuad) { + DoCompare(0, 0.0, zIndex, comparePosition); + } else { + double distance = std::min(fabs(minNegative), fabs(maxPositive)); + DoCompare(0, distance, zIndex, comparePosition); + } +} + +void ObjectPicker::DrawLine(const Vector &a, const Vector &b, hStroke hcs) { + Stroke *stroke = strokes.FindById(hcs); + Point2d ap = camera.ProjectPoint(a); + Point2d bp = camera.ProjectPoint(b); + double distance = point.DistanceToLine(ap, bp.Minus(ap), /*asSegment=*/true); + double depth = 0.5 * (camera.ProjectPoint3(a).z + camera.ProjectPoint3(b).z) ; + DoCompare(depth, distance - stroke->width / 2.0, stroke->zIndex); +} + +void ObjectPicker::DrawEdges(const SEdgeList &el, hStroke hcs) { + Stroke *stroke = strokes.FindById(hcs); + for(const SEdge &e : el.l) { + Point2d ap = camera.ProjectPoint(e.a); + Point2d bp = camera.ProjectPoint(e.b); + double distance = point.DistanceToLine(ap, bp.Minus(ap), /*asSegment=*/true); + double depth = 0.5 * (camera.ProjectPoint3(e.a).z + camera.ProjectPoint3(e.b).z) ; + DoCompare(depth, distance - stroke->width / 2.0, stroke->zIndex, e.auxB); + } +} + +void ObjectPicker::DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) { + ssassert(false, "Not implemented"); +} + +void ObjectPicker::DrawVectorText(const std::string &text, double height, + const Vector &o, const Vector &u, const Vector &v, + hStroke hcs) { + Stroke *stroke = strokes.FindById(hcs); + double w = VectorFont::Builtin()-> GetWidth(height, text), + h = VectorFont::Builtin()->GetHeight(height); + DoQuad(o, + o.Plus(v.ScaledBy(h)), + o.Plus(u.ScaledBy(w)).Plus(v.ScaledBy(h)), + o.Plus(u.ScaledBy(w)), + stroke->zIndex); +} + +void ObjectPicker::DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d, + hFill hcf) { + Fill *fill = fills.FindById(hcf); + DoQuad(a, b, c, d, fill->zIndex); +} + +void ObjectPicker::DrawPoint(const Vector &o, Canvas::hStroke hcs) { + Stroke *stroke = strokes.FindById(hcs); + double distance = point.DistanceTo(camera.ProjectPoint(o)) - stroke->width / 2; + double depth = camera.ProjectPoint3(o).z; + DoCompare(depth, distance, stroke->zIndex); +} + +void ObjectPicker::DrawPolygon(const SPolygon &p, hFill hcf) { + ssassert(false, "Not implemented"); +} + +void ObjectPicker::DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack) { + ssassert(false, "Not implemented"); +} + +void ObjectPicker::DrawFaces(const SMesh &m, const std::vector &faces, hFill hcf) { + ssassert(false, "Not implemented"); +} + +void ObjectPicker::DrawPixmap(std::shared_ptr pm, + const Vector &o, const Vector &u, const Vector &v, + const Point2d &ta, const Point2d &tb, Canvas::hFill hcf) { + DrawQuad(o, o.Plus(u), o.Plus(u).Plus(v), o.Plus(v), hcf); +} + +bool ObjectPicker::Pick(const std::function &drawFn) { + minDepth = VERY_POSITIVE; + minDistance = VERY_POSITIVE; + maxZIndex = INT_MIN; + + drawFn(); + return minDistance < selRadius; +} +} diff --git a/src/render/render.h b/src/render/render.h new file mode 100644 index 0000000..9601a5e --- /dev/null +++ b/src/render/render.h @@ -0,0 +1,385 @@ +//----------------------------------------------------------------------------- +// Backend-agnostic rendering interface, and various backends we use. +// +// Copyright 2016 whitequark +//----------------------------------------------------------------------------- + +#ifndef SOLVESPACE_RENDER_H +#define SOLVESPACE_RENDER_H + +//----------------------------------------------------------------------------- +// Interfaces common for all renderers +//----------------------------------------------------------------------------- + +enum class StipplePattern : uint32_t; + +// A mapping from 3d sketch coordinates to 2d screen coordinates, using +// an axonometric projection. +class Camera { +public: + double width; + double height; + double pixelRatio; + bool gridFit; + Vector offset; + Vector projRight; + Vector projUp; + double scale; + double tangent; + + bool IsPerspective() const { return tangent != 0.0; } + + Point2d ProjectPoint(Vector p) const; + Vector ProjectPoint3(Vector p) const; + Vector ProjectPoint4(Vector p, double *w) const; + Vector UnProjectPoint(Point2d p) const; + Vector UnProjectPoint3(Vector p) const; + Vector VectorFromProjs(Vector rightUpForward) const; + Vector AlignToPixelGrid(Vector v) const; + + SBezier ProjectBezier(SBezier b) const; + + void LoadIdentity(); + void NormalizeProjectionVectors(); +}; + +// A description of scene lighting. +class Lighting { +public: + RgbaColor backgroundColor; + double ambientIntensity; + double lightIntensity[2]; + Vector lightDirection[2]; +}; + +class BatchCanvas; + +// An interface for populating a drawing area with geometry. +class Canvas { +public: + // Stroke and fill styles are addressed with handles to be able to quickly + // group geometry into indexed draw calls. + class hStroke { + public: + uint32_t v; + }; + + class hFill { + public: + uint32_t v; + }; + + // The layer of a geometry describes how it occludes other geometry. + // Within a layer, geometry with higher z-index occludes geometry with lower z-index, + // or geometry drawn earlier if z-indexes match. + enum class Layer { + NORMAL, // Occluded by geometry with lower Z coordinate + OCCLUDED, // Only drawn over geometry with lower Z coordinate + DEPTH_ONLY, // Like NORMAL, but only affects future occlusion, not color + BACK, // Always drawn below all other geometry + FRONT, // Always drawn above all other geometry + LAST = FRONT + }; + + // The outlines are the collection of all edges that may be drawn. + // Outlines can be classified as emphasized or not; emphasized outlines indicate an abrupt + // change in the surface curvature. These are indicated by the SOutline tag. + // Outlines can also be classified as contour or not; contour outlines indicate the boundary + // of the filled mesh. Whether an outline is a part of contour or not depends on point of view. + enum class DrawOutlinesAs { + EMPHASIZED_AND_CONTOUR = 0, // Both emphasized and contour outlines + EMPHASIZED_WITHOUT_CONTOUR = 1, // Emphasized outlines except those also belonging to contour + CONTOUR_ONLY = 2 // Contour outlines only + }; + + // Stroke widths, etc, can be scale-invariant (in pixels) or scale-dependent (in millimeters). + enum class Unit { + MM, + PX + }; + + class Stroke { + public: + hStroke h; + + Layer layer; + int zIndex; + RgbaColor color; + double width; + Unit unit; + StipplePattern stipplePattern; + double stippleScale; + + void Clear() { *this = {}; } + bool Equals(const Stroke &other) const; + + double WidthMm(const Camera &camera) const; + double WidthPx(const Camera &camera) const; + double StippleScaleMm(const Camera &camera) const; + double StippleScalePx(const Camera &camera) const; + }; + + enum class FillPattern { + SOLID, CHECKERED_A, CHECKERED_B + }; + + class Fill { + public: + hFill h; + + Layer layer; + int zIndex; + RgbaColor color; + FillPattern pattern; + std::shared_ptr texture; + + void Clear() { *this = {}; } + bool Equals(const Fill &other) const; + }; + + IdList strokes = {}; + IdList fills = {}; + BitmapFont bitmapFont = {}; + + virtual void Clear(); + virtual ~Canvas() = default; + + hStroke GetStroke(const Stroke &stroke); + hFill GetFill(const Fill &fill); + BitmapFont *GetBitmapFont(); + + virtual const Camera &GetCamera() const = 0; + + virtual void DrawLine(const Vector &a, const Vector &b, hStroke hcs) = 0; + virtual void DrawEdges(const SEdgeList &el, hStroke hcs) = 0; + virtual bool DrawBeziers(const SBezierList &bl, hStroke hcs) = 0; + virtual void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) = 0; + virtual void DrawVectorText(const std::string &text, double height, + const Vector &o, const Vector &u, const Vector &v, + hStroke hcs) = 0; + + virtual void DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d, + hFill hcf) = 0; + virtual void DrawPoint(const Vector &o, hStroke hcs) = 0; + virtual void DrawPolygon(const SPolygon &p, hFill hcf) = 0; + virtual void DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack = {}) = 0; + virtual void DrawFaces(const SMesh &m, const std::vector &faces, hFill hcf) = 0; + + virtual void DrawPixmap(std::shared_ptr pm, + const Vector &o, const Vector &u, const Vector &v, + const Point2d &ta, const Point2d &tb, hFill hcf) = 0; + virtual void InvalidatePixmap(std::shared_ptr pm) = 0; + + virtual std::shared_ptr CreateBatch(); +}; + +template<> +struct IsHandleOracle : std::true_type {}; + +template<> +struct IsHandleOracle : std::true_type {}; + + +// An interface for view-dependent visualization. +class ViewportCanvas : public Canvas { +public: + virtual void SetCamera(const Camera &camera) = 0; + virtual void SetLighting(const Lighting &lighting) = 0; + + virtual void StartFrame() = 0; + virtual void FlushFrame() = 0; + virtual void FinishFrame() = 0; + virtual std::shared_ptr ReadFrame() = 0; + + virtual void GetIdent(const char **vendor, const char **renderer, const char **version) = 0; +}; + +// An interface for view-independent visualization. +class BatchCanvas : public Canvas { +public: + const Camera &GetCamera() const override; + + virtual void Finalize() = 0; + virtual void Draw() = 0; +}; + +// A wrapper around Canvas that simplifies drawing UI in screen coordinates. +class UiCanvas { +public: + std::shared_ptr canvas; + bool flip = false; + + void DrawLine(int x1, int y1, int x2, int y2, RgbaColor color, int width = 1, + int zIndex = 0); + void DrawRect(int l, int r, int t, int b, RgbaColor fillColor, RgbaColor outlineColor, + int zIndex = 0); + void DrawPixmap(std::shared_ptr pm, int x, int y, + int zIndex = 0); + void DrawBitmapChar(char32_t codepoint, int x, int y, RgbaColor color, + int zIndex = 0); + void DrawBitmapText(const std::string &str, int x, int y, RgbaColor color, + int zIndex = 0); + + int Flip(int y) const { return flip ? (int)canvas->GetCamera().height - y : y; } +}; + +// A canvas that performs picking against drawn geometry. +class ObjectPicker : public Canvas { +public: + Camera camera = {}; + // Configuration. + Point2d point = {}; + double selRadius = 0.0; + // Picking state. + double minDistance = 0.0; + double minDepth = 1e10; + int maxZIndex = 0; + uint32_t position = 0; + + const Camera &GetCamera() const override { return camera; } + + void DrawLine(const Vector &a, const Vector &b, hStroke hcs) override; + void DrawEdges(const SEdgeList &el, hStroke hcs) override; + bool DrawBeziers(const SBezierList &bl, hStroke hcs) override { return false; } + void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) override; + void DrawVectorText(const std::string &text, double height, + const Vector &o, const Vector &u, const Vector &v, + hStroke hcs) override; + + void DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d, + hFill hcf) override; + void DrawPoint(const Vector &o, hStroke hcs) override; + void DrawPolygon(const SPolygon &p, hFill hcf) override; + void DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack) override; + void DrawFaces(const SMesh &m, const std::vector &faces, hFill hcf) override; + + void DrawPixmap(std::shared_ptr pm, + const Vector &o, const Vector &u, const Vector &v, + const Point2d &ta, const Point2d &tb, hFill hcf) override; + void InvalidatePixmap(std::shared_ptr pm) override {} + + void DoCompare(double depth, double distance, int zIndex, int comparePosition = 0); + void DoQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d, + int zIndex, int comparePosition = 0); + + bool Pick(const std::function &drawFn); +}; + +// A canvas that renders onto a 2d surface, performing z-index sorting, occlusion testing, etc, +// on the CPU. +class SurfaceRenderer : public ViewportCanvas { +public: + Camera camera = {}; + Lighting lighting = {}; + // Chord tolerance, for converting beziers to pwl. + double chordTolerance = 0.0; + // Render lists. + handle_map edges; + handle_map beziers; + SMesh mesh = {}; + // State. + BBox bbox = {}; + + void Clear() override; + + // Canvas interface. + const Camera &GetCamera() const override { return camera; } + + // ViewportCanvas interface. + void SetCamera(const Camera &cam) override { this->camera = cam; } + void SetLighting(const Lighting &light) override { this->lighting = light; } + + void DrawLine(const Vector &a, const Vector &b, hStroke hcs) override; + void DrawEdges(const SEdgeList &el, hStroke hcs) override; + bool DrawBeziers(const SBezierList &bl, hStroke hcs) override; + void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) override; + void DrawVectorText(const std::string &text, double height, + const Vector &o, const Vector &u, const Vector &v, + hStroke hcs) override; + + void DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d, + hFill hcf) override; + void DrawPoint(const Vector &o, hStroke hcs) override; + void DrawPolygon(const SPolygon &p, hFill hcf) override; + void DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack) override; + void DrawFaces(const SMesh &m, const std::vector &faces, hFill hcf) override; + + void DrawPixmap(std::shared_ptr pm, + const Vector &o, const Vector &u, const Vector &v, + const Point2d &ta, const Point2d &tb, hFill hcf) override; + void InvalidatePixmap(std::shared_ptr pm) override; + + // Geometry manipulation. + void CalculateBBox(); + void ConvertBeziersToEdges(); + void CullOccludedStrokes(); + + // Renderer operations. + void OutputInPaintOrder(); + + virtual bool CanOutputCurves() const = 0; + virtual bool CanOutputTriangles() const = 0; + + virtual void OutputStart() = 0; + virtual void OutputBezier(const SBezier &b, hStroke hcs) = 0; + virtual void OutputTriangle(const STriangle &tr) = 0; + virtual void OutputEnd() = 0; + + void OutputBezierAsNonrationalCubic(const SBezier &b, hStroke hcs); +}; + +//----------------------------------------------------------------------------- +// 2d renderers +//----------------------------------------------------------------------------- + +class CairoRenderer : public SurfaceRenderer { +public: + cairo_t *context = NULL; + // Renderer configuration. + bool antialias = false; + // Renderer state. + struct { + hStroke hcs; + } current = {}; + + void Clear() override; + + void StartFrame() override {} + void FlushFrame() override; + void FinishFrame() override {} + std::shared_ptr ReadFrame() override; + + void GetIdent(const char **vendor, const char **renderer, const char **version) override; + + void SelectStroke(hStroke hcs); + void MoveTo(Vector p); + void FinishPath(); + + bool CanOutputCurves() const override { return true; } + bool CanOutputTriangles() const override { return true; } + + void OutputStart() override; + void OutputBezier(const SBezier &b, hStroke hcs) override; + void OutputTriangle(const STriangle &tr) override; + void OutputEnd() override; +}; + +class CairoPixmapRenderer final : public CairoRenderer { +public: + std::shared_ptr pixmap; + + cairo_surface_t *surface = NULL; + + void Init(); + void Clear() override; + + std::shared_ptr ReadFrame() override; +}; + +//----------------------------------------------------------------------------- +// Factories +//----------------------------------------------------------------------------- + +std::shared_ptr CreateRenderer(); + +#endif diff --git a/src/render/render2d.cpp b/src/render/render2d.cpp new file mode 100644 index 0000000..710e795 --- /dev/null +++ b/src/render/render2d.cpp @@ -0,0 +1,413 @@ +//----------------------------------------------------------------------------- +// Rendering projections to 2d surfaces: z-sorting, occlusion testing, etc. +// +// Copyright 2016 whitequark +//----------------------------------------------------------------------------- +#include "solvespace.h" + +namespace SolveSpace { + +// FIXME: The export coordinate system has a different handedness than display +// coordinate system; lighting and occlusion calculations are right-handed. +static Vector ProjectPoint3RH(const Camera &camera, Vector p) { + p = p.Plus(camera.offset); + + Vector r; + r.x = p.Dot(camera.projRight); + r.y = p.Dot(camera.projUp); + r.z = p.Dot(camera.projRight.Cross(camera.projUp)); + + double w = 1 + r.z*camera.tangent*camera.scale; + return r.ScaledBy(camera.scale/w); +} + +//----------------------------------------------------------------------------- +// Accumulation of geometry +//----------------------------------------------------------------------------- + +void SurfaceRenderer::DrawLine(const Vector &a, const Vector &b, hStroke hcs) { + edges[hcs].AddEdge(ProjectPoint3RH(camera, a), + ProjectPoint3RH(camera, b)); +} + +void SurfaceRenderer::DrawEdges(const SEdgeList &el, hStroke hcs) { + for(const SEdge &e : el.l) { + edges[hcs].AddEdge(ProjectPoint3RH(camera, e.a), + ProjectPoint3RH(camera, e.b)); + } +} + +bool SurfaceRenderer::DrawBeziers(const SBezierList &bl, hStroke hcs) { + if(!CanOutputCurves()) + return false; + + for(const SBezier &b : bl.l) { + SBezier pb = camera.ProjectBezier(b); + beziers[hcs].l.Add(&pb); + } + return true; +} + +void SurfaceRenderer::DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) { + Vector projDir = camera.projRight.Cross(camera.projUp); + for(const SOutline &o : ol.l) { + if(drawAs == DrawOutlinesAs::EMPHASIZED_AND_CONTOUR && + !(o.IsVisible(projDir) || o.tag != 0)) + continue; + if(drawAs == DrawOutlinesAs::EMPHASIZED_WITHOUT_CONTOUR && + !(!o.IsVisible(projDir) && o.tag != 0)) + continue; + if(drawAs == DrawOutlinesAs::CONTOUR_ONLY && + !(o.IsVisible(projDir))) + continue; + + edges[hcs].AddEdge(ProjectPoint3RH(camera, o.a), + ProjectPoint3RH(camera, o.b)); + } +} + +void SurfaceRenderer::DrawVectorText(const std::string &text, double height, + const Vector &o, const Vector &u, const Vector &v, + hStroke hcs) { + auto traceEdge = [&](Vector a, Vector b) { + edges[hcs].AddEdge(ProjectPoint3RH(camera, a), + ProjectPoint3RH(camera, b)); + }; + VectorFont::Builtin()->Trace(height, o, u, v, text, traceEdge, camera); +} + +void SurfaceRenderer::DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d, + hFill hcf) { + Fill *fill = fills.FindById(hcf); + ssassert(fill->layer == Layer::NORMAL || + fill->layer == Layer::DEPTH_ONLY || + fill->layer == Layer::FRONT || + fill->layer == Layer::BACK, "Unexpected mesh layer"); + + Vector zOffset = {}; + if(fill->layer == Layer::BACK) { + zOffset.z -= 1e6; + } else if(fill->layer == Layer::FRONT) { + zOffset.z += 1e6; + } + zOffset.z += camera.scale * fill->zIndex; + + STriMeta meta = {}; + if(fill->layer != Layer::DEPTH_ONLY) { + meta.color = fill->color; + } + Vector ta = ProjectPoint3RH(camera, a).Plus(zOffset), + tb = ProjectPoint3RH(camera, b).Plus(zOffset), + tc = ProjectPoint3RH(camera, c).Plus(zOffset), + td = ProjectPoint3RH(camera, d).Plus(zOffset); + mesh.AddTriangle(meta, tc, tb, ta); + mesh.AddTriangle(meta, ta, td, tc); +} + +void SurfaceRenderer::DrawPoint(const Vector &o, Canvas::hStroke hcs) { + Stroke *stroke = strokes.FindById(hcs); + + Fill fill = {}; + fill.layer = stroke->layer; + fill.zIndex = stroke->zIndex; + fill.color = stroke->color; + hFill hcf = GetFill(fill); + + Vector u = camera.projRight.ScaledBy(stroke->width/2.0/camera.scale), + v = camera.projUp.ScaledBy(stroke->width/2.0/camera.scale); + DrawQuad(o.Minus(u).Minus(v), o.Minus(u).Plus(v), + o.Plus(u).Plus(v), o.Plus(u).Minus(v), hcf); +} + +void SurfaceRenderer::DrawPolygon(const SPolygon &p, hFill hcf) { + SMesh m = {}; + p.TriangulateInto(&m); + DrawMesh(m, hcf, {}); + m.Clear(); +} + +void SurfaceRenderer::DrawMesh(const SMesh &m, + hFill hcfFront, hFill hcfBack) { + Fill *fill = fills.FindById(hcfFront); + ssassert(fill->layer == Layer::NORMAL || + fill->layer == Layer::DEPTH_ONLY, "Unexpected mesh layer"); + + Vector l0 = (lighting.lightDirection[0]).WithMagnitude(1), + l1 = (lighting.lightDirection[1]).WithMagnitude(1); + for(STriangle tr : m.l) { + tr.a = ProjectPoint3RH(camera, tr.a); + tr.b = ProjectPoint3RH(camera, tr.b); + tr.c = ProjectPoint3RH(camera, tr.c); + + if(CanOutputTriangles() && fill->layer == Layer::NORMAL) { + if(fill->color.IsEmpty()) { + // Compute lighting, since we're going to draw the shaded triangles. + Vector n = tr.Normal().WithMagnitude(1); + double intensity = lighting.ambientIntensity + + max(0.0, (lighting.lightIntensity[0])*(n.Dot(l0))) + + max(0.0, (lighting.lightIntensity[1])*(n.Dot(l1))); + double r = min(1.0, tr.meta.color.redF() * intensity), + g = min(1.0, tr.meta.color.greenF() * intensity), + b = min(1.0, tr.meta.color.blueF() * intensity); + tr.meta.color = RGBf(r, g, b); + } else { + // We're going to draw this triangle, but it's not shaded. + tr.meta.color = fill->color; + } + } else { + // This triangle is just for occlusion testing. + tr.meta.color = {}; + } + mesh.AddTriangle(&tr); + } +} + +void SurfaceRenderer::DrawFaces(const SMesh &m, const std::vector &faces, hFill hcf) { + Fill *fill = fills.FindById(hcf); + ssassert(fill->layer == Layer::NORMAL || + fill->layer == Layer::DEPTH_ONLY, "Unexpected mesh layer"); + + Vector zOffset = {}; + zOffset.z += camera.scale * fill->zIndex; + + size_t facesSize = faces.size(); + for(STriangle tr : m.l) { + uint32_t face = tr.meta.face; + for(size_t j = 0; j < facesSize; j++) { + if(faces[j] != face) continue; + if(!fill->color.IsEmpty()) { + tr.meta.color = fill->color; + } + mesh.AddTriangle(tr.meta, + ProjectPoint3RH(camera, tr.a).Plus(zOffset), + ProjectPoint3RH(camera, tr.b).Plus(zOffset), + ProjectPoint3RH(camera, tr.c).Plus(zOffset)); + break; + } + } +} + +void SurfaceRenderer::DrawPixmap(std::shared_ptr pm, + const Vector &o, const Vector &u, const Vector &v, + const Point2d &ta, const Point2d &tb, hFill hcf) { + ssassert(false, "Not implemented"); +} + +void SurfaceRenderer::InvalidatePixmap(std::shared_ptr pm) { + ssassert(false, "Not implemented"); +} + +//----------------------------------------------------------------------------- +// Processing of geometry +//----------------------------------------------------------------------------- + +void SurfaceRenderer::CalculateBBox() { + bbox.minp = Vector::From(VERY_POSITIVE, VERY_POSITIVE, VERY_POSITIVE); + bbox.maxp = Vector::From(VERY_NEGATIVE, VERY_NEGATIVE, VERY_NEGATIVE); + + for(auto &it : edges) { + SEdgeList &el = it.second; + for(SEdge &e : el.l) { + bbox.Include(e.a); + bbox.Include(e.b); + } + } + + for(auto &it : beziers) { + SBezierList &bl = it.second; + for(SBezier &b : bl.l) { + for(int i = 0; i <= b.deg; i++) { + bbox.Include(b.ctrl[i]); + } + } + } + + for(STriangle &tr : mesh.l) { + for(int i = 0; i < 3; i++) { + bbox.Include(tr.vertices[i]); + } + } +} + + +void SurfaceRenderer::ConvertBeziersToEdges() { + for(auto &it : beziers) { + hStroke hcs = it.first; + SBezierList &bl = it.second; + + SEdgeList &el = edges[hcs]; + for(const SBezier &b : bl.l) { + if(b.deg == 1) { + el.AddEdge(b.ctrl[0], b.ctrl[1]); + } else { + List lv = {}; + b.MakePwlInto(&lv, chordTolerance); + for(int i = 1; i < lv.n; i++) { + el.AddEdge(lv[i-1], lv[i]); + } + lv.Clear(); + } + } + bl.l.Clear(); + } + beziers.clear(); +} + +void SurfaceRenderer::CullOccludedStrokes() { + // Perform occlusion testing, if necessary. + if(mesh.l.IsEmpty()) + return; + + // We can't perform hidden line removal on exact curves. + ConvertBeziersToEdges(); + + // Remove hidden lines (on NORMAL layers), or remove visible lines (on OCCLUDED layers). + SKdNode *root = SKdNode::From(&mesh); + root->ClearTags(); + + int cnt = 1234; + for(auto &eit : edges) { + hStroke hcs = eit.first; + SEdgeList &el = eit.second; + + Stroke *stroke = strokes.FindById(hcs); + if(stroke->layer != Layer::NORMAL && + stroke->layer != Layer::OCCLUDED) continue; + + SEdgeList nel = {}; + for(const SEdge &e : el.l) { + SEdgeList oel = {}; + oel.AddEdge(e.a, e.b); + root->OcclusionTestLine(e, &oel, cnt); + + if(stroke->layer == Layer::OCCLUDED) { + for(SEdge &oe : oel.l) { + oe.tag = !oe.tag; + } + } + oel.l.RemoveTagged(); + + oel.MergeCollinearSegments(e.a, e.b); + for(const SEdge &oe : oel.l) { + nel.AddEdge(oe.a, oe.b); + } + + oel.Clear(); + cnt++; + } + + el.l.Clear(); + el.l = nel.l; + } +} + +void SurfaceRenderer::OutputInPaintOrder() { + // Sort our strokes in paint order. + std::vector> paintOrder; + paintOrder.emplace_back(Layer::NORMAL, 0); // mesh + for(const Stroke &cs : strokes) { + paintOrder.emplace_back(cs.layer, cs.zIndex); + } + + const Layer stackup[] = { + Layer::BACK, Layer::NORMAL, Layer::DEPTH_ONLY, Layer::OCCLUDED, Layer::FRONT + }; + std::sort(paintOrder.begin(), paintOrder.end(), + [&](std::pair a, std::pair b) { + Layer aLayer = a.first, + bLayer = b.first; + int aZIndex = a.second, + bZIndex = b.second; + + size_t aLayerIndex = + std::find(std::begin(stackup), std::end(stackup), aLayer) - std::begin(stackup); + size_t bLayerIndex = + std::find(std::begin(stackup), std::end(stackup), bLayer) - std::begin(stackup); + if(aLayerIndex == bLayerIndex) { + return aZIndex < bZIndex; + } else { + return aLayerIndex < bLayerIndex; + } + }); + + auto last = std::unique(paintOrder.begin(), paintOrder.end()); + paintOrder.erase(last, paintOrder.end()); + + // Output geometry in paint order. + OutputStart(); + for(auto &it : paintOrder) { + Layer layer = it.first; + int zIndex = it.second; + + if(layer == Layer::NORMAL && zIndex == 0) { + SMesh mp = {}; + SBsp3 *bsp = SBsp3::FromMesh(&mesh); + if(bsp) bsp->GenerateInPaintOrder(&mp); + + for(const STriangle &tr : mp.l) { + // Cull back-facing and invisible triangles. + if(tr.Normal().z < 0) continue; + if(tr.meta.color.IsEmpty()) continue; + OutputTriangle(tr); + } + + mp.Clear(); + } + + for(auto eit : edges) { + hStroke hcs = eit.first; + const SEdgeList &el = eit.second; + + Stroke *stroke = strokes.FindById(hcs); + if(stroke->layer != layer || stroke->zIndex != zIndex) continue; + + for(const SEdge &e : el.l) { + OutputBezier(SBezier::From(e.a, e.b), hcs); + } + } + + for(auto &bit : beziers) { + hStroke hcs = bit.first; + const SBezierList &bl = bit.second; + + Stroke *stroke = strokes.FindById(hcs); + if(stroke->layer != layer || stroke->zIndex != zIndex) continue; + + for(const SBezier &b : bl.l) { + OutputBezier(b, hcs); + } + } + } + OutputEnd(); +} + +void SurfaceRenderer::Clear() { + Canvas::Clear(); + + for(auto &eit : edges) { + SEdgeList &el = eit.second; + el.l.Clear(); + } + edges.clear(); + + for(auto &bit : beziers) { + SBezierList &bl = bit.second; + bl.l.Clear(); + } + beziers.clear(); + + mesh.Clear(); +} + +void SurfaceRenderer::OutputBezierAsNonrationalCubic(const SBezier &b, hStroke hcs) { + // Arbitrary choice of tolerance; make it a little finer than pwl tolerance since + // it should be easier to achieve that with the smooth curves. + SBezierList bl; + b.MakeNonrationalCubicInto(&bl, chordTolerance / 2); + for(const SBezier &cb : bl.l) { + OutputBezier(cb, hcs); + } + bl.Clear(); +} + +} diff --git a/src/render/rendercairo.cpp b/src/render/rendercairo.cpp new file mode 100644 index 0000000..e59de31 --- /dev/null +++ b/src/render/rendercairo.cpp @@ -0,0 +1,173 @@ +//----------------------------------------------------------------------------- +// A rendering backend that draws on a Cairo surface. +// +// Copyright 2016 whitequark +//----------------------------------------------------------------------------- +#include +#include "solvespace.h" + +namespace SolveSpace { + +void CairoRenderer::Clear() { + SurfaceRenderer::Clear(); + + if(context != NULL) cairo_destroy(context); + context = NULL; +} + +void CairoRenderer::GetIdent(const char **vendor, const char **renderer, const char **version) { + *vendor = "Cairo"; + *renderer = "Cairo"; + *version = cairo_version_string(); +} + +void CairoRenderer::FlushFrame() { + CullOccludedStrokes(); + OutputInPaintOrder(); + + cairo_surface_flush(cairo_get_target(context)); +} + +std::shared_ptr CairoRenderer::ReadFrame() { + ssassert(false, "generic Cairo renderer does not support pixmap readout"); +} + +void CairoRenderer::OutputStart() { + cairo_save(context); + + RgbaColor bgColor = lighting.backgroundColor; + cairo_rectangle(context, 0.0, 0.0, (double)camera.width, (double)camera.height); + cairo_set_source_rgba(context, bgColor.redF(), bgColor.greenF(), bgColor.blueF(), + bgColor.alphaF()); + cairo_fill(context); + + cairo_translate(context, camera.width / 2.0, camera.height / 2.0); + + // Avoid pixel boundaries; when not using antialiasing, we would otherwise + // get numerically unstable output. + cairo_translate(context, 0.1, 0.1); + + cairo_set_line_join(context, CAIRO_LINE_JOIN_ROUND); + cairo_set_line_cap(context, CAIRO_LINE_CAP_ROUND); +} + +void CairoRenderer::OutputEnd() { + FinishPath(); + + cairo_restore(context); +} + +void CairoRenderer::SelectStroke(hStroke hcs) { + if(current.hcs == hcs) return; + FinishPath(); + + Stroke *stroke = strokes.FindById(hcs); + current.hcs = hcs; + + RgbaColor color = stroke->color; + std::vector dashes = StipplePatternDashes(stroke->stipplePattern); + for(double &dash : dashes) { + dash *= stroke->StippleScalePx(camera); + } + cairo_set_line_width(context, stroke->WidthPx(camera)); + cairo_set_dash(context, dashes.data(), (int)dashes.size(), 0); + cairo_set_source_rgba(context, color.redF(), color.greenF(), color.blueF(), + color.alphaF()); + if(antialias) { + cairo_set_antialias(context, CAIRO_ANTIALIAS_GRAY); + } else { + cairo_set_antialias(context, CAIRO_ANTIALIAS_NONE); + } +} + +void CairoRenderer::MoveTo(Vector p) { + Point2d pos; + cairo_get_current_point(context, &pos.x, &pos.y); + if(cairo_has_current_point(context) && pos.Equals(p.ProjectXy())) return; + FinishPath(); + + cairo_move_to(context, p.x, p.y); +} + +void CairoRenderer::FinishPath() { + if(!cairo_has_current_point(context)) return; + + cairo_stroke(context); +} + +void CairoRenderer::OutputBezier(const SBezier &b, hStroke hcs) { + SelectStroke(hcs); + + Vector c, n = Vector::From(0, 0, 1); + double r; + if(b.deg == 1) { + MoveTo(b.ctrl[0]); + cairo_line_to(context, + b.ctrl[1].x, b.ctrl[1].y); + } else if(b.IsCircle(n, &c, &r)) { + MoveTo(b.ctrl[0]); + double theta0 = atan2(b.ctrl[0].y - c.y, b.ctrl[0].x - c.x), + theta1 = atan2(b.ctrl[2].y - c.y, b.ctrl[2].x - c.x), + dtheta = WRAP_SYMMETRIC(theta1 - theta0, 2*PI); + if(dtheta > 0) { + cairo_arc(context, + c.x, c.y, r, theta0, theta1); + } else { + cairo_arc_negative(context, + c.x, c.y, r, theta0, theta1); + } + } else if(b.deg == 3 && !b.IsRational()) { + MoveTo(b.ctrl[0]); + cairo_curve_to(context, + b.ctrl[1].x, b.ctrl[1].y, + b.ctrl[2].x, b.ctrl[2].y, + b.ctrl[3].x, b.ctrl[3].y); + } else { + OutputBezierAsNonrationalCubic(b, hcs); + } +} + +void CairoRenderer::OutputTriangle(const STriangle &tr) { + FinishPath(); + current.hcs = {}; + + RgbaColor color = tr.meta.color; + cairo_set_source_rgba(context, color.redF(), color.greenF(), color.blueF(), + color.alphaF()); + cairo_set_antialias(context, CAIRO_ANTIALIAS_NONE); + cairo_move_to(context, tr.a.x, tr.a.y); + cairo_line_to(context, tr.b.x, tr.b.y); + cairo_line_to(context, tr.c.x, tr.c.y); + cairo_fill(context); +} + +void CairoPixmapRenderer::Init() { + Clear(); + + pixmap = std::make_shared(); + pixmap->format = Pixmap::Format::BGRA; + pixmap->width = (size_t)camera.width; + pixmap->height = (size_t)camera.height; + pixmap->stride = cairo_format_stride_for_width(CAIRO_FORMAT_RGB24, (int)camera.width); + pixmap->data = std::vector(pixmap->stride * pixmap->height); + surface = + cairo_image_surface_create_for_data(&pixmap->data[0], CAIRO_FORMAT_RGB24, + pixmap->width, pixmap->height, + pixmap->stride); + context = cairo_create(surface); +} + +void CairoPixmapRenderer::Clear() { + CairoRenderer::Clear(); + + if(surface != NULL) cairo_surface_destroy(surface); + surface = NULL; +} + +std::shared_ptr CairoPixmapRenderer::ReadFrame() { + std::shared_ptr result = pixmap->Copy(); + result->ConvertTo(Pixmap::Format::RGBA); + return result; +} + +} diff --git a/src/render/rendergl1.cpp b/src/render/rendergl1.cpp new file mode 100644 index 0000000..ef34bc5 --- /dev/null +++ b/src/render/rendergl1.cpp @@ -0,0 +1,852 @@ +//----------------------------------------------------------------------------- +// OpenGL 1 based rendering interface. +// +// Copyright 2016 whitequark +//----------------------------------------------------------------------------- +#include "solvespace.h" + +#ifdef WIN32 +// Include after solvespace.h to avoid identifier clashes. +# include // required by GL headers +#endif +#ifdef __APPLE__ +# include +# include +#else +# include +# include +#endif + +namespace SolveSpace { + +//----------------------------------------------------------------------------- +// Checks for buggy OpenGL renderers +//----------------------------------------------------------------------------- + +// Intel GPUs with Mesa on *nix render thin lines poorly. +static bool HasIntelThinLineQuirk() +{ + static bool quirkChecked, quirkEnabled; + if(!quirkChecked) { + const char *ident = (const char*)glGetString(GL_VENDOR); + if(ident != NULL) { + quirkChecked = true; + quirkEnabled = !strcmp(ident, "Intel Open Source Technology Center"); + } + } + return quirkEnabled; +} + +// The default Windows GL renderer really does implement GL 1.1, +// and cannot handle non-power-of-2 textures, which is legal. +static bool HasGl1V1Quirk() +{ + static bool quirkChecked, quirkEnabled; + if(!quirkChecked) { + const char *ident = (const char*)glGetString(GL_VERSION); + if(ident != NULL) { + quirkChecked = true; + quirkEnabled = !strcmp(ident, "1.1.0"); + } + } + return quirkEnabled; +} + +//----------------------------------------------------------------------------- +// Thin wrappers around OpenGL functions to fix bugs, adapt them to our +// data structures, etc. +//----------------------------------------------------------------------------- + +static inline void ssglNormal3v(Vector n) { + glNormal3d(n.x, n.y, n.z); +} + +static inline void ssglVertex3v(Vector v) { + glVertex3d(v.x, v.y, v.z); +} + +void ssglLineWidth(double width) { + if(HasIntelThinLineQuirk() && width < 1.6) + width = 1.6; + + glLineWidth((GLfloat)width); +} + +static inline void ssglColorRGBA(RgbaColor color) { + glColor4d(color.redF(), color.greenF(), color.blueF(), color.alphaF()); +} + +static inline void ssglMaterialRGBA(GLenum side, RgbaColor color) { + GLfloat mpb[] = { color.redF(), color.greenF(), color.blueF(), color.alphaF() }; + glMaterialfv(side, GL_AMBIENT_AND_DIFFUSE, mpb); +} + +static void ssglDepthRange(Canvas::Layer layer, int zIndex) { + switch(layer) { + case Canvas::Layer::NORMAL: + case Canvas::Layer::FRONT: + case Canvas::Layer::BACK: + glDepthFunc(GL_LEQUAL); + glDepthMask(GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + break; + + case Canvas::Layer::DEPTH_ONLY: + glDepthFunc(GL_LEQUAL); + glDepthMask(GL_TRUE); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + break; + + case Canvas::Layer::OCCLUDED: + glDepthFunc(GL_GREATER); + glDepthMask(GL_FALSE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + break; + } + + switch(layer) { + case Canvas::Layer::FRONT: + glDepthRange(0.0, 0.0); + break; + + case Canvas::Layer::BACK: + glDepthRange(1.0, 1.0); + break; + + case Canvas::Layer::NORMAL: + case Canvas::Layer::DEPTH_ONLY: + case Canvas::Layer::OCCLUDED: + // The size of this step depends on the resolution of the Z buffer; for + // a 16-bit buffer, this should be fine. + double offset = 1.0 / (65535 * 0.8) * zIndex; + glDepthRange(0.1 - offset, 1.0 - offset); + break; + } +} + +static void ssglFillPattern(Canvas::FillPattern pattern) { + static bool Init; + static GLubyte MaskA[(32*32)/8]; + static GLubyte MaskB[(32*32)/8]; + if(!Init) { + int x, y; + for(x = 0; x < 32; x++) { + for(y = 0; y < 32; y++) { + int i = y*4 + x/8, b = x % 8; + int ym = y % 4, xm = x % 4; + for(int k = 0; k < 2; k++) { + if(xm >= 1 && xm <= 2 && ym >= 1 && ym <= 2) { + (k == 0 ? MaskB : MaskA)[i] |= (0x80 >> b); + } + ym = (ym + 2) % 4; xm = (xm + 2) % 4; + } + } + } + Init = true; + } + + switch(pattern) { + case Canvas::FillPattern::SOLID: + glDisable(GL_POLYGON_STIPPLE); + break; + + case Canvas::FillPattern::CHECKERED_A: + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(MaskA); + break; + + case Canvas::FillPattern::CHECKERED_B: + glEnable(GL_POLYGON_STIPPLE); + glPolygonStipple(MaskB); + break; + } +} + +//----------------------------------------------------------------------------- +// OpenGL 1 / compatibility profile based renderer +//----------------------------------------------------------------------------- + +class OpenGl1Renderer final : public ViewportCanvas { +public: + Camera camera; + Lighting lighting; + // Cached OpenGL state. + struct { + bool drawing; + GLenum mode; + hStroke hcs; + Stroke *stroke; + hFill hcf; + Fill *fill; + std::weak_ptr texture; + } current; + + // List-initialize current to work around MSVC bug 746973. + OpenGl1Renderer() : camera(), lighting(), current({}) {} + + const Camera &GetCamera() const override { return camera; } + + void DrawLine(const Vector &a, const Vector &b, hStroke hcs) override; + void DrawEdges(const SEdgeList &el, hStroke hcs) override; + bool DrawBeziers(const SBezierList &bl, hStroke hcs) override { return false; } + void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) override; + void DrawVectorText(const std::string &text, double height, + const Vector &o, const Vector &u, const Vector &v, + hStroke hcs) override; + + void DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d, + hFill hcf) override; + void DrawPoint(const Vector &o, hStroke hcs) override; + void DrawPolygon(const SPolygon &p, hFill hcf) override; + void DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack) override; + void DrawFaces(const SMesh &m, const std::vector &faces, hFill hcf) override; + void DrawPixmap(std::shared_ptr pm, + const Vector &o, const Vector &u, const Vector &v, + const Point2d &ta, const Point2d &tb, hFill hcf) override; + void InvalidatePixmap(std::shared_ptr pm) override; + + void SelectPrimitive(unsigned mode); + void UnSelectPrimitive(); + Stroke *SelectStroke(hStroke hcs); + Fill *SelectFill(hFill hcf); + void SelectTexture(std::shared_ptr pm); + void DoFatLineEndcap(const Vector &p, const Vector &u, const Vector &v); + void DoFatLine(const Vector &a, const Vector &b, double width); + void DoLine(const Vector &a, const Vector &b, hStroke hcs); + void DoPoint(Vector p, double radius); + void DoStippledLine(const Vector &a, const Vector &b, hStroke hcs, double phase = 0.0); + + void UpdateProjection(); + void SetCamera(const Camera &camera) override; + void SetLighting(const Lighting &lighting) override; + + void StartFrame() override; + void FlushFrame() override; + void FinishFrame() override; + std::shared_ptr ReadFrame() override; + + void GetIdent(const char **vendor, const char **renderer, const char **version) override; +}; + +//----------------------------------------------------------------------------- +// A simple OpenGL state tracker to group consecutive draw calls. +//----------------------------------------------------------------------------- + +void OpenGl1Renderer::SelectPrimitive(GLenum mode) { + if(current.drawing && current.mode == mode) { + return; + } else if(current.drawing) { + glEnd(); + } + glBegin(mode); + current.drawing = true; + current.mode = mode; +} + +void OpenGl1Renderer::UnSelectPrimitive() { + if(!current.drawing) return; + glEnd(); + current.drawing = false; +} + +Canvas::Stroke *OpenGl1Renderer::SelectStroke(hStroke hcs) { + if(current.hcs == hcs) return current.stroke; + + Stroke *stroke = strokes.FindById(hcs); + UnSelectPrimitive(); + ssglColorRGBA(stroke->color); + ssglDepthRange(stroke->layer, stroke->zIndex); + ssglLineWidth(stroke->WidthPx(camera)); + // Fat lines and points are quads affected by glPolygonStipple, so make sure + // they are displayed correctly. + ssglFillPattern(FillPattern::SOLID); + glDisable(GL_TEXTURE_2D); + + current.hcs = hcs; + current.stroke = stroke; + current.hcf = {}; + current.fill = NULL; + current.texture.reset(); + return stroke; +} + +Canvas::Fill *OpenGl1Renderer::SelectFill(hFill hcf) { + if(current.hcf == hcf) return current.fill; + + Fill *fill = fills.FindById(hcf); + UnSelectPrimitive(); + ssglColorRGBA(fill->color); + ssglDepthRange(fill->layer, fill->zIndex); + ssglFillPattern(fill->pattern); + glDisable(GL_TEXTURE_2D); + + current.hcs = {}; + current.stroke = NULL; + current.hcf = hcf; + current.fill = fill; + current.texture.reset(); + return fill; +} + +static int RoundUpToPowerOfTwo(int v) +{ + for(int i = 0; i < 31; i++) { + int vt = (1 << i); + if(vt >= v) { + return vt; + } + } + return 0; +} + +void OpenGl1Renderer::SelectTexture(std::shared_ptr pm) { + if(current.texture.lock() == pm) return; + + glBindTexture(GL_TEXTURE_2D, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + GLenum format = 0; + switch(pm->format) { + case Pixmap::Format::RGBA: format = GL_RGBA; break; + case Pixmap::Format::RGB: format = GL_RGB; break; + case Pixmap::Format::A: format = GL_ALPHA; break; + case Pixmap::Format::BGRA: + case Pixmap::Format::BGR: + ssassert(false, "Unexpected pixmap format"); + } + + if(!HasGl1V1Quirk()) { + glTexImage2D(GL_TEXTURE_2D, 0, format, pm->width, pm->height, 0, + format, GL_UNSIGNED_BYTE, &pm->data[0]); + } else { + GLsizei width = RoundUpToPowerOfTwo(pm->width); + GLsizei height = RoundUpToPowerOfTwo(pm->height); + glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, + format, GL_UNSIGNED_BYTE, 0); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pm->width, pm->height, + format, GL_UNSIGNED_BYTE, &pm->data[0]); + } + + glEnable(GL_TEXTURE_2D); + + current.texture = pm; +} + +//----------------------------------------------------------------------------- +// OpenGL's GL_LINES mode does not work on lines thicker than about 3 px, +// so we have to draw thicker lines using triangles. +//----------------------------------------------------------------------------- + +void OpenGl1Renderer::DoFatLineEndcap(const Vector &p, const Vector &u, const Vector &v) { + // A table of cos and sin of (pi*i/10 + pi/2), as i goes from 0 to 10 + static const double Circle[11][2] = { + { 0.0000, 1.0000 }, + { -0.3090, 0.9511 }, + { -0.5878, 0.8090 }, + { -0.8090, 0.5878 }, + { -0.9511, 0.3090 }, + { -1.0000, 0.0000 }, + { -0.9511, -0.3090 }, + { -0.8090, -0.5878 }, + { -0.5878, -0.8090 }, + { -0.3090, -0.9511 }, + { 0.0000, -1.0000 }, + }; + + SelectPrimitive(GL_TRIANGLE_FAN); + for(auto pc : Circle) { + double c = pc[0], s = pc[1]; + ssglVertex3v(p.Plus(u.ScaledBy(c)).Plus(v.ScaledBy(s))); + } + UnSelectPrimitive(); +} + +void OpenGl1Renderer::DoFatLine(const Vector &a, const Vector &b, double width) { + // The half-width of the line we're drawing. + double hw = width / 2; + Vector ab = b.Minus(a); + Vector gn = (camera.projRight).Cross(camera.projUp); + Vector abn = (ab.Cross(gn)).WithMagnitude(1); + abn = abn.Minus(gn.ScaledBy(gn.Dot(abn))); + // So now abn is normal to the projection of ab into the screen, so the + // line will always have constant thickness as the view is rotated. + + abn = abn.WithMagnitude(hw); + ab = gn.Cross(abn); + ab = ab. WithMagnitude(hw); + + // The body of a line is a quad + SelectPrimitive(GL_QUADS); + ssglVertex3v(a.Plus (abn)); + ssglVertex3v(b.Plus (abn)); + ssglVertex3v(b.Minus(abn)); + ssglVertex3v(a.Minus(abn)); + // And the line has two semi-circular end caps. + DoFatLineEndcap(a, ab, abn); + DoFatLineEndcap(b, ab.ScaledBy(-1), abn); +} + +void OpenGl1Renderer::DoLine(const Vector &a, const Vector &b, hStroke hcs) { + if(a.Equals(b)) return; + + Stroke *stroke = SelectStroke(hcs); + if(stroke->WidthPx(camera) <= 3.0) { + SelectPrimitive(GL_LINES); + ssglVertex3v(a); + ssglVertex3v(b); + } else { + DoFatLine(a, b, stroke->WidthPx(camera) / camera.scale); + } +} + +void OpenGl1Renderer::DoPoint(Vector p, double d) { + if(d <= 3.0) { + Vector u = camera.projRight.WithMagnitude(d / 2.0 / camera.scale); + + SelectPrimitive(GL_LINES); + ssglVertex3v(p.Minus(u)); + ssglVertex3v(p.Plus(u)); + } else { + Vector u = camera.projRight.WithMagnitude(d / 2.0 / camera.scale); + Vector v = camera.projUp.WithMagnitude(d / 2.0 / camera.scale); + + DoFatLineEndcap(p, u, v); + DoFatLineEndcap(p, u.ScaledBy(-1.0), v); + } +} + +void OpenGl1Renderer::DoStippledLine(const Vector &a, const Vector &b, hStroke hcs, double phase) { + Stroke *stroke = SelectStroke(hcs); + + if(stroke->stipplePattern == StipplePattern::CONTINUOUS) { + DoLine(a, b, hcs); + return; + } + + double scale = stroke->StippleScaleMm(camera); + const std::vector &dashes = StipplePatternDashes(stroke->stipplePattern); + double length = StipplePatternLength(stroke->stipplePattern) * scale; + + phase -= floor(phase / length) * length; + + double curPhase = 0.0; + size_t curDash; + for(curDash = 0; curDash < dashes.size(); curDash++) { + curPhase += dashes[curDash] * scale; + if(phase < curPhase) break; + } + + Vector dir = b.Minus(a); + double len = dir.Magnitude(); + dir = dir.WithMagnitude(1.0); + + double cur = 0.0; + Vector curPos = a; + double width = stroke->WidthMm(camera); + + double curDashLen = (curPhase - phase) / scale; + while(cur < len) { + double next = std::min(len, cur + curDashLen * scale); + Vector nextPos = curPos.Plus(dir.ScaledBy(next - cur)); + if(curDash % 2 == 0) { + if(curDashLen <= LENGTH_EPS) { + DoPoint(curPos, width); + } else { + DoLine(curPos, nextPos, hcs); + } + } + cur = next; + curPos = nextPos; + curDash++; + curDashLen = dashes[curDash % dashes.size()]; + } +} + +//----------------------------------------------------------------------------- +// A canvas implemented using OpenGL 3 immediate mode. +//----------------------------------------------------------------------------- + +void OpenGl1Renderer::DrawLine(const Vector &a, const Vector &b, hStroke hcs) { + DoStippledLine(a, b, hcs); +} + +void OpenGl1Renderer::DrawEdges(const SEdgeList &el, hStroke hcs) { + double phase = 0.0; + for(const SEdge *e = el.l.First(); e; e = el.l.NextAfter(e)) { + DoStippledLine(e->a, e->b, hcs, phase); + phase += e->a.Minus(e->b).Magnitude(); + } +} + +void OpenGl1Renderer::DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) { + Vector projDir = camera.projRight.Cross(camera.projUp); + double phase = 0.0; + switch(drawAs) { + case DrawOutlinesAs::EMPHASIZED_AND_CONTOUR: + for(const SOutline &o : ol.l) { + if(o.IsVisible(projDir) || o.tag != 0) { + DoStippledLine(o.a, o.b, hcs, phase); + } + phase += o.a.Minus(o.b).Magnitude(); + } + break; + + case DrawOutlinesAs::EMPHASIZED_WITHOUT_CONTOUR: + for(const SOutline &o : ol.l) { + if(!o.IsVisible(projDir) && o.tag != 0) { + DoStippledLine(o.a, o.b, hcs, phase); + } + phase += o.a.Minus(o.b).Magnitude(); + } + break; + + case DrawOutlinesAs::CONTOUR_ONLY: + for(const SOutline &o : ol.l) { + if(o.IsVisible(projDir)) { + DoStippledLine(o.a, o.b, hcs, phase); + } + phase += o.a.Minus(o.b).Magnitude(); + } + break; + } +} + +void OpenGl1Renderer::DrawVectorText(const std::string &text, double height, + const Vector &o, const Vector &u, const Vector &v, + hStroke hcs) { + auto traceEdge = [&](Vector a, Vector b) { DoStippledLine(a, b, hcs); }; + VectorFont::Builtin()->Trace(height, o, u, v, text, traceEdge, camera); +} + +void OpenGl1Renderer::DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d, + hFill hcf) { + SelectFill(hcf); + SelectPrimitive(GL_QUADS); + ssglVertex3v(a); + ssglVertex3v(b); + ssglVertex3v(c); + ssglVertex3v(d); +} + +void OpenGl1Renderer::DrawPoint(const Vector &o, Canvas::hStroke hcs) { + Stroke *stroke = SelectStroke(hcs); + + Canvas::Fill fill = {}; + fill.layer = stroke->layer; + fill.zIndex = stroke->zIndex; + fill.color = stroke->color; + hFill hcf = GetFill(fill); + + Vector r = camera.projRight.ScaledBy(stroke->width/2.0/camera.scale); + Vector u = camera.projUp.ScaledBy(stroke->width/2.0/camera.scale); + Vector a = o.Plus (r).Plus (u), + b = o.Plus (r).Minus(u), + c = o.Minus(r).Minus(u), + d = o.Minus(r).Plus (u); + DrawQuad(a, b, c, d, hcf); +} + +#ifdef WIN32 +#define SSGL_CALLBACK CALLBACK +#else +#define SSGL_CALLBACK +#endif +typedef void(SSGL_CALLBACK *GLUCallback)(); + +static void SSGL_CALLBACK Vertex(Vector *p) { + ssglVertex3v(*p); +} +static void SSGL_CALLBACK Combine(double coords[3], void *vertexData[4], + float weight[4], void **outData) { + Vector *n = (Vector *)AllocTemporary(sizeof(Vector)); + n->x = coords[0]; + n->y = coords[1]; + n->z = coords[2]; + + *outData = n; +} +void OpenGl1Renderer::DrawPolygon(const SPolygon &p, hFill hcf) { + UnSelectPrimitive(); + SelectFill(hcf); + + GLUtesselator *gt = gluNewTess(); + gluTessCallback(gt, GLU_TESS_BEGIN, (GLUCallback) glBegin); + gluTessCallback(gt, GLU_TESS_VERTEX, (GLUCallback) Vertex); + gluTessCallback(gt, GLU_TESS_END, (GLUCallback) glEnd); + gluTessCallback(gt, GLU_TESS_COMBINE, (GLUCallback) Combine); + + gluTessProperty(gt, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); + + ssglNormal3v(p.normal); + gluTessNormal(gt, p.normal.x, p.normal.y, p.normal.z); + + gluTessBeginPolygon(gt, NULL); + for(const SContour &sc : p.l) { + gluTessBeginContour(gt); + for(const SPoint &sp : sc.l) { + double ap[3] = { sp.p.x, sp.p.y, sp.p.z }; + gluTessVertex(gt, ap, (GLvoid *) &sp.p); + } + gluTessEndContour(gt); + } + gluTessEndPolygon(gt); + + gluDeleteTess(gt); +} + +void OpenGl1Renderer::DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack) { + UnSelectPrimitive(); + + RgbaColor frontColor = {}, + backColor = {}; + + Fill *frontFill = SelectFill(hcfFront); + frontColor = frontFill->color; + + ssglMaterialRGBA(GL_FRONT, frontFill->color); + if(hcfBack.v != 0) { + Fill *backFill = fills.FindById(hcfBack); + backColor = backFill->color; + ssassert(frontFill->layer == backFill->layer && + frontFill->zIndex == backFill->zIndex, + "frontFill and backFill should belong to the same depth range"); + ssassert(frontFill->pattern == backFill->pattern, + "frontFill and backFill should have the same pattern"); + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1); + ssglMaterialRGBA(GL_BACK, backFill->color); + } else { + glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0); + } + + RgbaColor triangleColor = {}; + glEnable(GL_LIGHTING); + glBegin(GL_TRIANGLES); + for(const STriangle &tr : m.l) { + if(frontColor.IsEmpty() || backColor.IsEmpty()) { + if(triangleColor.IsEmpty() || !triangleColor.Equals(tr.meta.color)) { + triangleColor = tr.meta.color; + if(frontColor.IsEmpty()) { + ssglMaterialRGBA(GL_FRONT, triangleColor); + } + if(backColor.IsEmpty()) { + ssglMaterialRGBA(GL_BACK, triangleColor); + } + } + } + + if(tr.an.EqualsExactly(Vector::From(0, 0, 0))) { + // Compute the normal from the vertices + ssglNormal3v(tr.Normal()); + ssglVertex3v(tr.a); + ssglVertex3v(tr.b); + ssglVertex3v(tr.c); + } else { + // Use the exact normals that are specified + ssglNormal3v(tr.an); + ssglVertex3v(tr.a); + ssglNormal3v(tr.bn); + ssglVertex3v(tr.b); + ssglNormal3v(tr.cn); + ssglVertex3v(tr.c); + } + } + glEnd(); + glDisable(GL_LIGHTING); +} + +void OpenGl1Renderer::DrawFaces(const SMesh &m, const std::vector &faces, hFill hcf) { + SelectFill(hcf); + SelectPrimitive(GL_TRIANGLES); + size_t facesSize = faces.size(); + for(const STriangle &tr : m.l) { + uint32_t face = tr.meta.face; + for(size_t j = 0; j < facesSize; j++) { + if(faces[j] != face) continue; + ssglVertex3v(tr.a); + ssglVertex3v(tr.b); + ssglVertex3v(tr.c); + break; + } + } +} + +void OpenGl1Renderer::DrawPixmap(std::shared_ptr pm, + const Vector &o, const Vector &u, const Vector &v, + const Point2d &ta, const Point2d &tb, hFill hcf) { + double xfactor = 1.0, + yfactor = 1.0; + if(HasGl1V1Quirk()) { + xfactor = (double)pm->width / RoundUpToPowerOfTwo(pm->width); + yfactor = (double)pm->height / RoundUpToPowerOfTwo(pm->height); + } + + UnSelectPrimitive(); + SelectFill(hcf); + SelectTexture(pm); + SelectPrimitive(GL_QUADS); + glTexCoord2d(ta.x * xfactor, ta.y * yfactor); + ssglVertex3v(o); + glTexCoord2d(ta.x * xfactor, tb.y * yfactor); + ssglVertex3v(o.Plus(v)); + glTexCoord2d(tb.x * xfactor, tb.y * yfactor); + ssglVertex3v(o.Plus(u).Plus(v)); + glTexCoord2d(tb.x * xfactor, ta.y * yfactor); + ssglVertex3v(o.Plus(u)); +} + +void OpenGl1Renderer::InvalidatePixmap(std::shared_ptr pm) { + if(current.texture.lock() == pm) { + current.texture.reset(); + } +} + +void OpenGl1Renderer::UpdateProjection() { + UnSelectPrimitive(); + + glViewport(0, 0, + (GLsizei)(camera.width * camera.pixelRatio), + (GLsizei)(camera.height * camera.pixelRatio)); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + glScaled(camera.scale * 2.0 / camera.width, + camera.scale * 2.0 / camera.height, + camera.scale * 1.0 / 30000); + + double mat[16]; + // Last thing before display is to apply the perspective + double clp = camera.tangent * camera.scale; + MakeMatrix(mat, 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, clp, 1); + glMultMatrixd(mat); + + // Before that, we apply the rotation + Vector projRight = camera.projRight, + projUp = camera.projUp, + n = camera.projUp.Cross(camera.projRight); + MakeMatrix(mat, projRight.x, projRight.y, projRight.z, 0, + projUp.x, projUp.y, projUp.z, 0, + n.x, n.y, n.z, 0, + 0, 0, 0, 1); + glMultMatrixd(mat); + + // And before that, the translation + Vector offset = camera.offset; + MakeMatrix(mat, 1, 0, 0, offset.x, + 0, 1, 0, offset.y, + 0, 0, 1, offset.z, + 0, 0, 0, 1); + glMultMatrixd(mat); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + glClearDepth(1.0); + glClear(GL_DEPTH_BUFFER_BIT); +} + +void OpenGl1Renderer::StartFrame() { + glEnable(GL_NORMALIZE); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + glEnable(GL_LINE_SMOOTH); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + // don't enable GL_POLYGON_SMOOTH; that looks ugly on some graphics cards, + // drawn with leaks in the mesh + + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + + if(EXACT(lighting.lightIntensity[0] != 0.0)) { + glEnable(GL_LIGHT0); + GLfloat f = (GLfloat)lighting.lightIntensity[0]; + GLfloat li0[] = { f, f, f, 1.0f }; + glLightfv(GL_LIGHT0, GL_DIFFUSE, li0); + glLightfv(GL_LIGHT0, GL_SPECULAR, li0); + + Vector ld = camera.VectorFromProjs(lighting.lightDirection[0]); + GLfloat ld0[4] = { (GLfloat)ld.x, (GLfloat)ld.y, (GLfloat)ld.z, 0 }; + glLightfv(GL_LIGHT0, GL_POSITION, ld0); + } + + if(EXACT(lighting.lightIntensity[1] != 0.0)) { + glEnable(GL_LIGHT1); + GLfloat f = (GLfloat)lighting.lightIntensity[1]; + GLfloat li0[] = { f, f, f, 1.0f }; + glLightfv(GL_LIGHT1, GL_DIFFUSE, li0); + glLightfv(GL_LIGHT1, GL_SPECULAR, li0); + + Vector ld = camera.VectorFromProjs(lighting.lightDirection[1]); + GLfloat ld0[4] = { (GLfloat)ld.x, (GLfloat)ld.y, (GLfloat)ld.z, 0 }; + glLightfv(GL_LIGHT1, GL_POSITION, ld0); + } + + if(EXACT(lighting.ambientIntensity != 0.0)) { + GLfloat ambient[4] = { (float)lighting.ambientIntensity, + (float)lighting.ambientIntensity, + (float)lighting.ambientIntensity, 1 }; + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); + } + + glClearColor(lighting.backgroundColor.redF(), lighting.backgroundColor.greenF(), + lighting.backgroundColor.blueF(), lighting.backgroundColor.alphaF()); + glClear(GL_COLOR_BUFFER_BIT); + + glClearDepth(1.0); + glClear(GL_DEPTH_BUFFER_BIT); +} + +void OpenGl1Renderer::FlushFrame() { + UnSelectPrimitive(); + + glFlush(); +} + +void OpenGl1Renderer::FinishFrame() { + glFinish(); + + GLenum error = glGetError(); + if(error != GL_NO_ERROR) { + dbp("glGetError() == 0x%X %s", error, gluErrorString(error)); + } +} + +std::shared_ptr OpenGl1Renderer::ReadFrame() { + int width = (int)(camera.width * camera.pixelRatio); + int height = (int)(camera.height * camera.pixelRatio); + std::shared_ptr pixmap = + Pixmap::Create(Pixmap::Format::RGB, (size_t)width, (size_t)height); + glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, &pixmap->data[0]); + ssassert(glGetError() == GL_NO_ERROR, "Unexpected glReadPixels error"); + return pixmap; +} + +void OpenGl1Renderer::GetIdent(const char **vendor, const char **renderer, const char **version) { + *vendor = (const char *)glGetString(GL_VENDOR); + *renderer = (const char *)glGetString(GL_RENDERER); + *version = (const char *)glGetString(GL_VERSION); +} + +void OpenGl1Renderer::SetCamera(const Camera &c) { + camera = c; + UpdateProjection(); +} + +void OpenGl1Renderer::SetLighting(const Lighting &l) { + lighting = l; +} + +std::shared_ptr CreateRenderer() { + return std::shared_ptr(new OpenGl1Renderer()); +} + +} diff --git a/src/render/rendergl3.cpp b/src/render/rendergl3.cpp new file mode 100644 index 0000000..4816496 --- /dev/null +++ b/src/render/rendergl3.cpp @@ -0,0 +1,1102 @@ +//----------------------------------------------------------------------------- +// OpenGL ES 2.0 and OpenGL 3.0 based rendering interface. +// +// Copyright 2016 Aleksey Egorov +//----------------------------------------------------------------------------- +#include "solvespace.h" +#include "gl3shader.h" + +namespace SolveSpace { + +class TextureCache { +public: + std::map, GLuint, + std::owner_less>> items; + + bool Lookup(std::shared_ptr ptr, GLuint *result) { + auto it = items.find(ptr); + if(it == items.end()) { + GLuint id; + glGenTextures(1, &id); + items[ptr] = id; + *result = id; + return false; + } + + *result = it->second; + return true; + } + + void CleanupUnused() { + for(auto it = items.begin(); it != items.end();) { + if(it->first.expired()) { + glDeleteTextures(1, &it->second); + it = items.erase(it); + continue; + } + it++; + } + } +}; + +// A canvas that uses the core OpenGL 3 profile, for desktop systems. +class OpenGl3Renderer final : public ViewportCanvas { +public: + struct SEdgeListItem { + hStroke h; + SEdgeList lines; + + void Clear() { lines.Clear(); } + }; + + struct SMeshListItem { + hFill h; + SIndexedMesh mesh; + + void Clear() { mesh.Clear(); } + }; + + struct SPointListItem { + hStroke h; + SIndexedMesh points; + + void Clear() { points.Clear(); } + }; + + IdList lines; + IdList meshes; + IdList points; + + TextureCache pixmapCache; + std::shared_ptr masks[3]; + + bool initialized; + StippleAtlas atlas; + MeshRenderer meshRenderer; + IndexedMeshRenderer imeshRenderer; + EdgeRenderer edgeRenderer; + OutlineRenderer outlineRenderer; + + Camera camera; + Lighting lighting; + // Cached OpenGL state. + struct { + hStroke hcs; + Stroke *stroke; + hFill hcf; + Fill *fill; + std::weak_ptr texture; + } current; + const char *vendor = ""; + const char *renderer = ""; + const char *version = ""; + + // List-initialize current to work around MSVC bug 746973. + OpenGl3Renderer() : + lines(), meshes(), points(), pixmapCache(), masks(), + initialized(), atlas(), meshRenderer(), imeshRenderer(), + edgeRenderer(), outlineRenderer(), camera(), lighting(), + current({}) {} + + void Init(); + + const Camera &GetCamera() const override { return camera; } + + void DrawLine(const Vector &a, const Vector &b, hStroke hcs) override; + void DrawEdges(const SEdgeList &el, hStroke hcs) override; + bool DrawBeziers(const SBezierList &bl, hStroke hcs) override { return false; } + void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs mode) override; + void DrawVectorText(const std::string &text, double height, + const Vector &o, const Vector &u, const Vector &v, + hStroke hcs) override; + + void DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d, + hFill hcf) override; + void DrawPoint(const Vector &o, hStroke hs) override; + void DrawPolygon(const SPolygon &p, hFill hcf) override; + void DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack) override; + void DrawFaces(const SMesh &m, const std::vector &faces, hFill hcf) override; + void DrawPixmap(std::shared_ptr pm, + const Vector &o, const Vector &u, const Vector &v, + const Point2d &ta, const Point2d &tb, hFill hcf) override; + void InvalidatePixmap(std::shared_ptr pm) override; + + std::shared_ptr CreateBatch() override; + + Stroke *SelectStroke(hStroke hcs); + Fill *SelectFill(hFill hcf); + void SelectMask(FillPattern pattern); + void SelectTexture(std::shared_ptr pm); + void DoFatLineEndcap(const Vector &p, const Vector &u, const Vector &v); + void DoFatLine(const Vector &a, const Vector &b, double width); + void DoLine(const Vector &a, const Vector &b, hStroke hcs); + void DoPoint(Vector p, hStroke hs); + void DoStippledLine(const Vector &a, const Vector &b, hStroke hcs); + + void UpdateProjection(); + void SetCamera(const Camera &c) override; + void SetLighting(const Lighting &l) override; + + void StartFrame() override; + void FlushFrame() override; + void FinishFrame() override; + void Clear() override; + std::shared_ptr ReadFrame() override; + + void GetIdent(const char **vendor, const char **renderer, const char **version) override; +}; + +//----------------------------------------------------------------------------- +// Thin wrappers around OpenGL functions to fix bugs, adapt them to our +// data structures, etc. +//----------------------------------------------------------------------------- + +static void ssglDepthRange(Canvas::Layer layer, int zIndex) { + switch(layer) { + case Canvas::Layer::NORMAL: + case Canvas::Layer::FRONT: + case Canvas::Layer::BACK: + glDepthFunc(GL_LEQUAL); + glDepthMask(GL_TRUE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + break; + + case Canvas::Layer::DEPTH_ONLY: + glDepthFunc(GL_LEQUAL); + glDepthMask(GL_TRUE); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + break; + + case Canvas::Layer::OCCLUDED: + glDepthFunc(GL_GREATER); + glDepthMask(GL_FALSE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + break; + } + + switch(layer) { + case Canvas::Layer::FRONT: + glDepthRangef(0.0f, 0.0f); + break; + + case Canvas::Layer::BACK: + glDepthRangef(1.0f, 1.0f); + break; + + case Canvas::Layer::NORMAL: + case Canvas::Layer::DEPTH_ONLY: + case Canvas::Layer::OCCLUDED: + // The size of this step depends on the resolution of the Z buffer; for + // a 16-bit buffer, this should be fine. + double offset = 1.0 / (65535 * 0.8) * zIndex; + glDepthRangef((float)(0.1 - offset), (float)(1.0 - offset)); + break; + } +} + +//----------------------------------------------------------------------------- +// A simple OpenGL state tracker to group consecutive draw calls. +//----------------------------------------------------------------------------- + +Canvas::Stroke *OpenGl3Renderer::SelectStroke(hStroke hcs) { + if(current.hcs == hcs) return current.stroke; + + Stroke *stroke = strokes.FindById(hcs); + ssglDepthRange(stroke->layer, stroke->zIndex); + + current.hcs = hcs; + current.stroke = stroke; + current.hcf = {}; + current.fill = NULL; + current.texture.reset(); + return stroke; +} + +void OpenGl3Renderer::SelectMask(FillPattern pattern) { + if(!masks[0]) { + masks[0] = Pixmap::Create(Pixmap::Format::A, 32, 32); + masks[1] = Pixmap::Create(Pixmap::Format::A, 32, 32); + masks[2] = Pixmap::Create(Pixmap::Format::A, 32, 32); + + for(int x = 0; x < 32; x++) { + for(int y = 0; y < 32; y++) { + masks[0]->data[y * 32 + x] = ((x / 2) % 2 == 0 && (y / 2) % 2 == 0) ? 0xFF : 0x00; + masks[1]->data[y * 32 + x] = ((x / 2) % 2 == 1 && (y / 2) % 2 == 1) ? 0xFF : 0x00; + masks[2]->data[y * 32 + x] = 0xFF; + } + } + } + + switch(pattern) { + case Canvas::FillPattern::SOLID: + SelectTexture(masks[2]); + break; + + case Canvas::FillPattern::CHECKERED_A: + SelectTexture(masks[0]); + break; + + case Canvas::FillPattern::CHECKERED_B: + SelectTexture(masks[1]); + break; + + default: ssassert(false, "Unexpected fill pattern"); + } +} + +Canvas::Fill *OpenGl3Renderer::SelectFill(hFill hcf) { + if(current.hcf == hcf) return current.fill; + + Fill *fill = fills.FindById(hcf); + ssglDepthRange(fill->layer, fill->zIndex); + + current.hcs = {}; + current.stroke = NULL; + current.hcf = hcf; + current.fill = fill; + if(fill->pattern != FillPattern::SOLID) { + SelectMask(fill->pattern); + } else if(fill->texture) { + SelectTexture(fill->texture); + } else { + SelectMask(FillPattern::SOLID); + } + return fill; +} + +static bool IsPowerOfTwo(size_t n) { + return (n & (n - 1)) == 0; +} + +void OpenGl3Renderer::InvalidatePixmap(std::shared_ptr pm) { + GLuint id; + pixmapCache.Lookup(pm, &id); + glBindTexture(GL_TEXTURE_2D, id); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + if(IsPowerOfTwo(pm->width) && IsPowerOfTwo(pm->height)) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + } else { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + GLenum format = 0; + switch(pm->format) { + case Pixmap::Format::RGBA: format = GL_RGBA; break; + case Pixmap::Format::RGB: format = GL_RGB; break; +#if defined(HAVE_GLES) + case Pixmap::Format::A: format = GL_ALPHA; break; +#else + case Pixmap::Format::A: format = GL_RED; break; +#endif + case Pixmap::Format::BGRA: + case Pixmap::Format::BGR: + ssassert(false, "Unexpected pixmap format"); + } + glTexImage2D(GL_TEXTURE_2D, 0, format, pm->width, pm->height, 0, + format, GL_UNSIGNED_BYTE, &pm->data[0]); +} + +void OpenGl3Renderer::SelectTexture(std::shared_ptr pm) { + if(current.texture.lock() == pm) return; + + GLuint id; + if(!pixmapCache.Lookup(pm, &id)) { + InvalidatePixmap(pm); + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, id); + current.texture = pm; +} + +void OpenGl3Renderer::DoLine(const Vector &a, const Vector &b, hStroke hcs) { + SEdgeListItem *eli = lines.FindByIdNoOops(hcs); + if(eli == NULL) { + SEdgeListItem item = {}; + item.h = hcs; + lines.Add(&item); + eli = lines.FindByIdNoOops(hcs); + } + + eli->lines.AddEdge(a, b); +} + +void OpenGl3Renderer::DoPoint(Vector p, hStroke hs) { + SPointListItem *pli = points.FindByIdNoOops(hs); + if(pli == NULL) { + SPointListItem item = {}; + item.h = hs; + points.Add(&item); + pli = points.FindByIdNoOops(hs); + } + + pli->points.AddPoint(p); +} + +void OpenGl3Renderer::DoStippledLine(const Vector &a, const Vector &b, hStroke hcs) { + Stroke *stroke = strokes.FindById(hcs); + if(stroke->stipplePattern != StipplePattern::FREEHAND && + stroke->stipplePattern != StipplePattern::ZIGZAG) + { + DoLine(a, b, hcs); + return; + } + + const char *patternSeq = NULL; + Stroke s = *stroke; + s.stipplePattern = StipplePattern::CONTINUOUS; + hcs = GetStroke(s); + switch(stroke->stipplePattern) { + case StipplePattern::CONTINUOUS: DoLine(a, b, hcs); return; + case StipplePattern::SHORT_DASH: patternSeq = "- "; break; + case StipplePattern::DASH: patternSeq = "- "; break; + case StipplePattern::LONG_DASH: patternSeq = "_ "; break; + case StipplePattern::DASH_DOT: patternSeq = "-."; break; + case StipplePattern::DASH_DOT_DOT: patternSeq = "-.."; break; + case StipplePattern::DOT: patternSeq = "."; break; + case StipplePattern::FREEHAND: patternSeq = "~"; break; + case StipplePattern::ZIGZAG: patternSeq = "~__"; break; + } + + Vector dir = b.Minus(a); + double len = dir.Magnitude(); + dir = dir.WithMagnitude(1.0); + + const char *si = patternSeq; + double end = len; + double ss = stroke->stippleScale / 2.0; + do { + double start = end; + switch(*si) { + case ' ': + end -= 1.0 * ss; + break; + + case '-': + start = max(start - 0.5 * ss, 0.0); + end = max(start - 2.0 * ss, 0.0); + if(start == end) break; + DoLine(a.Plus(dir.ScaledBy(start)), a.Plus(dir.ScaledBy(end)), hcs); + end = max(end - 0.5 * ss, 0.0); + break; + + case '_': + end = max(end - 4.0 * ss, 0.0); + DoLine(a.Plus(dir.ScaledBy(start)), a.Plus(dir.ScaledBy(end)), hcs); + break; + + case '.': + end = max(end - 0.5 * ss, 0.0); + if(end == 0.0) break; + DoPoint(a.Plus(dir.ScaledBy(end)), hcs); + end = max(end - 0.5 * ss, 0.0); + break; + + case '~': { + Vector ab = b.Minus(a); + Vector gn = (camera.projRight).Cross(camera.projUp); + Vector abn = (ab.Cross(gn)).WithMagnitude(1); + abn = abn.Minus(gn.ScaledBy(gn.Dot(abn))); + double pws = 2.0 * stroke->width / camera.scale; + + end = max(end - 0.5 * ss, 0.0); + Vector aa = a.Plus(dir.ScaledBy(start)); + Vector bb = a.Plus(dir.ScaledBy(end)) + .Plus(abn.ScaledBy(pws * (start - end) / (0.5 * ss))); + DoLine(aa, bb, hcs); + if(end == 0.0) break; + + start = end; + end = max(end - 1.0 * ss, 0.0); + aa = a.Plus(dir.ScaledBy(end)) + .Plus(abn.ScaledBy(pws)) + .Minus(abn.ScaledBy(2.0 * pws * (start - end) / ss)); + DoLine(bb, aa, hcs); + if(end == 0.0) break; + + start = end; + end = max(end - 0.5 * ss, 0.0); + bb = a.Plus(dir.ScaledBy(end)) + .Minus(abn.ScaledBy(pws)) + .Plus(abn.ScaledBy(pws * (start - end) / (0.5 * ss))); + DoLine(aa, bb, hcs); + break; + } + + default: ssassert(false, "Unexpected stipple pattern element"); + } + if(*(++si) == 0) si = patternSeq; + } while(end > 0.0); +} + +//----------------------------------------------------------------------------- +// A canvas implemented using OpenGL 3 vertex buffer objects. +//----------------------------------------------------------------------------- + +void OpenGl3Renderer::Init() { + atlas.Init(); + edgeRenderer.Init(&atlas); + outlineRenderer.Init(&atlas); + meshRenderer.Init(); + imeshRenderer.Init(); + + vendor = (const char *)glGetString(GL_VENDOR); + renderer = (const char *)glGetString(GL_RENDERER); + version = (const char *)glGetString(GL_VERSION); + +#if !defined(HAVE_GLES) && !defined(__APPLE__) + GLuint array; + glGenVertexArrays(1, &array); + glBindVertexArray(array); +#endif + UpdateProjection(); +} + +void OpenGl3Renderer::DrawLine(const Vector &a, const Vector &b, hStroke hcs) { + DoStippledLine(a, b, hcs); +} + +void OpenGl3Renderer::DrawEdges(const SEdgeList &el, hStroke hcs) { + for(const SEdge &e : el.l) { + DoStippledLine(e.a, e.b, hcs); + } +} + +void OpenGl3Renderer::DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs mode) { + if(ol.l.IsEmpty()) + return; + + Stroke *stroke = SelectStroke(hcs); + ssassert(stroke->stipplePattern != StipplePattern::ZIGZAG && + stroke->stipplePattern != StipplePattern::FREEHAND, + "ZIGZAG and FREEHAND not supported for outlines"); + + outlineRenderer.SetStroke(*stroke, 1.0 / camera.scale); + outlineRenderer.Draw(ol, mode); +} + +void OpenGl3Renderer::DrawVectorText(const std::string &text, double height, + const Vector &o, const Vector &u, const Vector &v, + hStroke hcs) { + SEdgeListItem *eli = lines.FindByIdNoOops(hcs); + if(eli == NULL) { + SEdgeListItem item = {}; + item.h = hcs; + lines.Add(&item); + eli = lines.FindByIdNoOops(hcs); + } + SEdgeList &lines = eli->lines; + auto traceEdge = [&](Vector a, Vector b) { lines.AddEdge(a, b); }; + VectorFont::Builtin()->Trace(height, o, u, v, text, traceEdge, camera); +} + +void OpenGl3Renderer::DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d, + hFill hcf) { + SMeshListItem *li = meshes.FindByIdNoOops(hcf); + if(li == NULL) { + SMeshListItem item = {}; + item.h = hcf; + meshes.Add(&item); + li = meshes.FindByIdNoOops(hcf); + } + li->mesh.AddQuad(a, b, c, d); +} + +void OpenGl3Renderer::DrawPoint(const Vector &o, hStroke hs) { + DoPoint(o, hs); +} + +void OpenGl3Renderer::DrawPolygon(const SPolygon &p, hFill hcf) { + Fill *fill = SelectFill(hcf); + + SMesh m = {}; + p.TriangulateInto(&m); + meshRenderer.UseFilled(*fill); + meshRenderer.Draw(m); + m.Clear(); +} + +void OpenGl3Renderer::DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack) { + ssassert(false, "Not implemented"); +} + +void OpenGl3Renderer::DrawFaces(const SMesh &m, const std::vector &faces, hFill hcf) { + if(faces.empty()) return; + + Fill *fill = SelectFill(hcf); + + SMesh facesMesh = {}; + for(uint32_t f : faces) { + for(const STriangle &t : m.l) { + if(f != t.meta.face) continue; + facesMesh.l.Add(&t); + } + } + + meshRenderer.UseFilled(*fill); + meshRenderer.Draw(facesMesh); + facesMesh.Clear(); +} + +void OpenGl3Renderer::DrawPixmap(std::shared_ptr pm, + const Vector &o, const Vector &u, const Vector &v, + const Point2d &ta, const Point2d &tb, hFill hcf) { + Fill fill = *fills.FindById(hcf); + fill.texture = pm; + hcf = GetFill(fill); + + SMeshListItem *mli = meshes.FindByIdNoOops(hcf); + if(mli == NULL) { + SMeshListItem item = {}; + item.h = hcf; + meshes.Add(&item); + mli = meshes.FindByIdNoOops(hcf); + } + + mli->mesh.AddPixmap(o, u, v, ta, tb); +} + +void OpenGl3Renderer::UpdateProjection() { + glViewport(0, 0, + (int)(camera.width * camera.pixelRatio), + (int)(camera.height * camera.pixelRatio)); + + double mat1[16]; + double mat2[16]; + + double sx = camera.scale * 2.0 / camera.width; + double sy = camera.scale * 2.0 / camera.height; + double sz = camera.scale * 1.0 / 30000; + + MakeMatrix(mat1, + sx, 0, 0, 0, + 0, sy, 0, 0, + 0, 0, sz, 0, + 0, 0, 0, 1 + ); + + // Last thing before display is to apply the perspective + double clp = camera.tangent * camera.scale; + MakeMatrix(mat2, + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, clp, 1 + ); + + double projection[16]; + MultMatrix(mat1, mat2, projection); + + // Before that, we apply the rotation + Vector u = camera.projRight, + v = camera.projUp, + n = camera.projUp.Cross(camera.projRight); + MakeMatrix(mat1, + u.x, u.y, u.z, 0, + v.x, v.y, v.z, 0, + n.x, n.y, n.z, 0, + 0, 0, 0, 1 + ); + + // And before that, the translation + Vector o = camera.offset; + MakeMatrix(mat2, + 1, 0, 0, o.x, + 0, 1, 0, o.y, + 0, 0, 1, o.z, + 0, 0, 0, 1 + ); + + double modelview[16]; + MultMatrix(mat1, mat2, modelview); + + imeshRenderer.SetProjection(projection); + imeshRenderer.SetModelview(modelview); + meshRenderer.SetProjection(projection); + meshRenderer.SetModelview(modelview); + edgeRenderer.SetProjection(projection); + edgeRenderer.SetModelview(modelview); + outlineRenderer.SetProjection(projection); + outlineRenderer.SetModelview(modelview); + + glClearDepthf(1.0f); + glClear(GL_DEPTH_BUFFER_BIT); +} + +void OpenGl3Renderer::StartFrame() { + if(!initialized) { + Init(); + initialized = true; + } + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + + RgbaColor backgroundColor = lighting.backgroundColor; + glClearColor(backgroundColor.redF(), backgroundColor.greenF(), + backgroundColor.blueF(), backgroundColor.alphaF()); + glClearDepthf(1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glFrontFace(GL_CW); +} + +void OpenGl3Renderer::FlushFrame() { + for(SMeshListItem &li : meshes) { + Fill *fill = SelectFill(li.h); + + imeshRenderer.UseFilled(*fill); + imeshRenderer.Draw(li.mesh); + li.mesh.Clear(); + } + meshes.Clear(); + + for(SEdgeListItem &eli : lines) { + Stroke *stroke = SelectStroke(eli.h); + + edgeRenderer.SetStroke(*stroke, 1.0 / camera.scale); + edgeRenderer.Draw(eli.lines); + eli.lines.Clear(); + } + lines.Clear(); + + for(SPointListItem &li : points) { + Stroke *stroke = SelectStroke(li.h); + + imeshRenderer.UsePoint(*stroke, 1.0 / camera.scale); + imeshRenderer.Draw(li.points); + li.points.Clear(); + } + points.Clear(); + + glFlush(); +} + +void OpenGl3Renderer::FinishFrame() { + glFinish(); + + GLenum error = glGetError(); + if(error != GL_NO_ERROR) { + dbp("glGetError() == 0x%X", error); + } +} + +void OpenGl3Renderer::Clear() { + ViewportCanvas::Clear(); + pixmapCache.CleanupUnused(); +} + +std::shared_ptr OpenGl3Renderer::ReadFrame() { + int width = (int)(camera.width * camera.pixelRatio); + int height = (int)(camera.height * camera.pixelRatio); + std::shared_ptr pixmap = + Pixmap::Create(Pixmap::Format::RGBA, (size_t)width, (size_t)height); + glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &pixmap->data[0]); + ssassert(glGetError() == GL_NO_ERROR, "Unexpected glReadPixels error"); + return pixmap; +} + +void OpenGl3Renderer::GetIdent(const char **vendor, const char **renderer, const char **version) { + *vendor = this->vendor; + *renderer = this->renderer; + *version = this->version; +} + +void OpenGl3Renderer::SetCamera(const Camera &c) { + camera = c; + if(initialized) { + UpdateProjection(); + } +} + +void OpenGl3Renderer::SetLighting(const Lighting &l) { + lighting = l; +} + +//----------------------------------------------------------------------------- +// A batch canvas implemented using OpenGL 3 vertex buffer objects. +//----------------------------------------------------------------------------- + +class DrawCall { +public: + virtual Canvas::Layer GetLayer() const = 0; + virtual int GetZIndex() const = 0; + + virtual void Draw(OpenGl3Renderer *renderer) = 0; + virtual void Remove(OpenGl3Renderer *renderer) = 0; +}; + +class EdgeDrawCall final : public DrawCall { +public: + // Key + Canvas::Stroke stroke; + // Data + EdgeRenderer::Handle handle; + + Canvas::Layer GetLayer() const override { return stroke.layer; } + int GetZIndex() const override { return stroke.zIndex; } + + static std::shared_ptr Create(OpenGl3Renderer *renderer, const SEdgeList &el, + Canvas::Stroke *stroke) { + EdgeDrawCall *dc = new EdgeDrawCall(); + dc->stroke = *stroke; + dc->handle = renderer->edgeRenderer.Add(el); + return std::shared_ptr(dc); + } + + void Draw(OpenGl3Renderer *renderer) override { + ssglDepthRange(stroke.layer, stroke.zIndex); + renderer->edgeRenderer.SetStroke(stroke, 1.0 / renderer->camera.scale); + renderer->edgeRenderer.Draw(handle); + } + + void Remove(OpenGl3Renderer *renderer) override { + renderer->edgeRenderer.Remove(handle); + } +}; + +class OutlineDrawCall final : public DrawCall { +public: + // Key + Canvas::Stroke stroke; + // Data + OutlineRenderer::Handle handle; + Canvas::DrawOutlinesAs drawAs; + + Canvas::Layer GetLayer() const override { return stroke.layer; } + int GetZIndex() const override { return stroke.zIndex; } + + static std::shared_ptr Create(OpenGl3Renderer *renderer, const SOutlineList &ol, + Canvas::Stroke *stroke, + Canvas::DrawOutlinesAs drawAs) { + OutlineDrawCall *dc = new OutlineDrawCall(); + dc->stroke = *stroke; + dc->handle = renderer->outlineRenderer.Add(ol); + dc->drawAs = drawAs; + return std::shared_ptr(dc); + } + + void Draw(OpenGl3Renderer *renderer) override { + ssglDepthRange(stroke.layer, stroke.zIndex); + renderer->outlineRenderer.SetStroke(stroke, 1.0 / renderer->camera.scale); + renderer->outlineRenderer.Draw(handle, drawAs); + } + + void Remove(OpenGl3Renderer *renderer) override { + renderer->outlineRenderer.Remove(handle); + } +}; + +class PointDrawCall final : public DrawCall { +public: + // Key + Canvas::Stroke stroke; + // Data + IndexedMeshRenderer::Handle handle; + + Canvas::Layer GetLayer() const override { return stroke.layer; } + int GetZIndex() const override { return stroke.zIndex; } + + static std::shared_ptr Create(OpenGl3Renderer *renderer, const SIndexedMesh &mesh, + Canvas::Stroke *stroke) { + PointDrawCall *dc = new PointDrawCall(); + dc->stroke = *stroke; + dc->handle = renderer->imeshRenderer.Add(mesh); + return std::shared_ptr(dc); + } + + void Draw(OpenGl3Renderer *renderer) override { + ssglDepthRange(stroke.layer, stroke.zIndex); + renderer->imeshRenderer.UsePoint(stroke, 1.0 / renderer->camera.scale); + renderer->imeshRenderer.Draw(handle); + } + + void Remove(OpenGl3Renderer *renderer) override { + renderer->imeshRenderer.Remove(handle); + } +}; + +class PixmapDrawCall final : public DrawCall { +public: + // Key + Canvas::Fill fill; + // Data + IndexedMeshRenderer::Handle handle; + + Canvas::Layer GetLayer() const override { return fill.layer; } + int GetZIndex() const override { return fill.zIndex; } + + static std::shared_ptr Create(OpenGl3Renderer *renderer, const SIndexedMesh &mesh, + Canvas::Fill *fill) { + PixmapDrawCall *dc = new PixmapDrawCall(); + dc->fill = *fill; + dc->handle = renderer->imeshRenderer.Add(mesh); + return std::shared_ptr(dc); + } + + void Draw(OpenGl3Renderer *renderer) override { + ssglDepthRange(fill.layer, fill.zIndex); + if(fill.pattern != Canvas::FillPattern::SOLID) { + renderer->SelectMask(fill.pattern); + } else if(fill.texture) { + renderer->SelectTexture(fill.texture); + } else { + renderer->SelectMask(Canvas::FillPattern::SOLID); + } + renderer->imeshRenderer.UseFilled(fill); + renderer->imeshRenderer.Draw(handle); + } + + void Remove(OpenGl3Renderer *renderer) override { + renderer->imeshRenderer.Remove(handle); + } +}; + +class MeshDrawCall final : public DrawCall { +public: + // Key + Canvas::Fill fillFront; + // Data + MeshRenderer::Handle handle; + Canvas::Fill fillBack; + bool hasFillBack; + bool isShaded; + + Canvas::Layer GetLayer() const override { return fillFront.layer; } + int GetZIndex() const override { return fillFront.zIndex; } + + static std::shared_ptr Create(OpenGl3Renderer *renderer, const SMesh &m, + Canvas::Fill *fillFront, Canvas::Fill *fillBack = NULL, + bool isShaded = false) { + MeshDrawCall *dc = new MeshDrawCall(); + dc->fillFront = *fillFront; + dc->handle = renderer->meshRenderer.Add(m); + dc->fillBack = *fillBack; + dc->isShaded = isShaded; + dc->hasFillBack = (fillBack != NULL); + return std::shared_ptr(dc); + } + + void DrawFace(OpenGl3Renderer *renderer, GLenum cullFace, const Canvas::Fill &fill) { + glCullFace(cullFace); + ssglDepthRange(fill.layer, fill.zIndex); + if(fill.pattern != Canvas::FillPattern::SOLID) { + renderer->SelectMask(fill.pattern); + } else if(fill.texture) { + renderer->SelectTexture(fill.texture); + } else { + renderer->SelectMask(Canvas::FillPattern::SOLID); + } + if(isShaded) { + renderer->meshRenderer.UseShaded(renderer->lighting); + } else { + renderer->meshRenderer.UseFilled(fill); + } + renderer->meshRenderer.Draw(handle, /*useColors=*/fill.color.IsEmpty(), fill.color); + } + + void Draw(OpenGl3Renderer *renderer) override { + glEnable(GL_CULL_FACE); + if(hasFillBack) + DrawFace(renderer, GL_BACK, fillBack); + DrawFace(renderer, GL_FRONT, fillFront); + glDisable(GL_CULL_FACE); + } + + void Remove(OpenGl3Renderer *renderer) override { + renderer->meshRenderer.Remove(handle); + } +}; + +struct CompareDrawCall { + bool operator()(const std::shared_ptr &a, const std::shared_ptr &b) const { + const Canvas::Layer stackup[] = { + Canvas::Layer::BACK, + Canvas::Layer::DEPTH_ONLY, + Canvas::Layer::NORMAL, + Canvas::Layer::OCCLUDED, + Canvas::Layer::FRONT + }; + + int aLayerIndex = + std::find(std::begin(stackup), std::end(stackup), a->GetLayer()) - std::begin(stackup); + int bLayerIndex = + std::find(std::begin(stackup), std::end(stackup), b->GetLayer()) - std::begin(stackup); + if(aLayerIndex == bLayerIndex) { + return a->GetZIndex() < b->GetZIndex(); + } else { + return aLayerIndex < bLayerIndex; + } + } +}; + +class OpenGl3RendererBatch final : public BatchCanvas { +public: + struct EdgeBuffer { + hStroke h; + SEdgeList edges; + + void Clear() { + edges.Clear(); + } + }; + + struct PointBuffer { + hStroke h; + SIndexedMesh points; + + void Clear() { + points.Clear(); + } + }; + + OpenGl3Renderer *renderer; + + IdList edgeBuffer; + IdList pointBuffer; + + std::multiset, CompareDrawCall> drawCalls; + + OpenGl3RendererBatch() : renderer(), edgeBuffer(), pointBuffer() {} + + void DrawLine(const Vector &a, const Vector &b, hStroke hcs) override { + EdgeBuffer *eb = edgeBuffer.FindByIdNoOops(hcs); + if(!eb) { + EdgeBuffer neb = {}; + neb.h = hcs; + edgeBuffer.Add(&neb); + eb = edgeBuffer.FindById(hcs); + } + + eb->edges.AddEdge(a, b); + } + + void DrawEdges(const SEdgeList &el, hStroke hcs) override { + EdgeBuffer *eb = edgeBuffer.FindByIdNoOops(hcs); + if(!eb) { + EdgeBuffer neb = {}; + neb.h = hcs; + edgeBuffer.Add(&neb); + eb = edgeBuffer.FindById(hcs); + } + + for(const SEdge &e : el.l) { + eb->edges.AddEdge(e.a, e.b); + } + } + + bool DrawBeziers(const SBezierList &bl, hStroke hcs) override { + return false; + } + + void DrawOutlines(const SOutlineList &ol, hStroke hcs, DrawOutlinesAs drawAs) override { + drawCalls.emplace(OutlineDrawCall::Create(renderer, ol, strokes.FindById(hcs), drawAs)); + } + + void DrawVectorText(const std::string &text, double height, + const Vector &o, const Vector &u, const Vector &v, + hStroke hcs) override { + ssassert(false, "Not implemented"); + } + + void DrawQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d, + hFill hcf) override { + ssassert(false, "Not implemented"); + } + + void DrawPoint(const Vector &o, hStroke hcs) override { + PointBuffer *pb = pointBuffer.FindByIdNoOops(hcs); + if(!pb) { + PointBuffer npb = {}; + npb.h = hcs; + pointBuffer.Add(&npb); + pb = pointBuffer.FindById(hcs); + } + + pb->points.AddPoint(o); + } + + void DrawPolygon(const SPolygon &p, hFill hcf) override { + SMesh m = {}; + p.TriangulateInto(&m); + drawCalls.emplace(MeshDrawCall::Create(renderer, m, fills.FindById(hcf), + fills.FindById(hcf))); + m.Clear(); + } + + void DrawMesh(const SMesh &m, hFill hcfFront, hFill hcfBack = {}) override { + drawCalls.emplace(MeshDrawCall::Create(renderer, m, fills.FindById(hcfFront), + fills.FindByIdNoOops(hcfBack), + /*isShaded=*/true)); + } + + void DrawFaces(const SMesh &m, const std::vector &faces, hFill hcf) override { + ssassert(false, "Not implemented"); + } + + void DrawPixmap(std::shared_ptr pm, + const Vector &o, const Vector &u, const Vector &v, + const Point2d &ta, const Point2d &tb, hFill hcf) override { + Fill fill = *fills.FindById(hcf); + fill.texture = pm; + hcf = GetFill(fill); + + SIndexedMesh mesh = {}; + mesh.AddPixmap(o, u, v, ta, tb); + drawCalls.emplace(PixmapDrawCall::Create(renderer, mesh, fills.FindByIdNoOops(hcf))); + mesh.Clear(); + } + + void InvalidatePixmap(std::shared_ptr pm) override { + ssassert(false, "Not implemented"); + } + + void Finalize() override { + for(const EdgeBuffer &eb : edgeBuffer) { + drawCalls.emplace(EdgeDrawCall::Create(renderer, eb.edges, strokes.FindById(eb.h))); + } + edgeBuffer.Clear(); + + for(const PointBuffer &pb : pointBuffer) { + drawCalls.emplace(PointDrawCall::Create(renderer, pb.points, strokes.FindById(pb.h))); + } + pointBuffer.Clear(); + } + + void Draw() override { + renderer->current = {}; + + for(std::shared_ptr dc : drawCalls) { + dc->Draw(renderer); + } + } + + void Clear() override { + for(std::shared_ptr dc : drawCalls) { + dc->Remove(renderer); + } + drawCalls.clear(); + } +}; + +//----------------------------------------------------------------------------- +// Factory functions. +//----------------------------------------------------------------------------- + +std::shared_ptr OpenGl3Renderer::CreateBatch() { + OpenGl3RendererBatch *batch = new OpenGl3RendererBatch(); + batch->renderer = this; + return std::shared_ptr(batch); +} + +std::shared_ptr CreateRenderer() { + return std::shared_ptr(new OpenGl3Renderer()); +} + +} diff --git a/src/request.cpp b/src/request.cpp new file mode 100644 index 0000000..3614cec --- /dev/null +++ b/src/request.cpp @@ -0,0 +1,247 @@ +//----------------------------------------------------------------------------- +// Implementation of our Request class; a request is a user-created thing +// that will generate an entity (line, curve) when the sketch is generated, +// in the same way that other entities are generated automatically, like +// by an extrude or a step and repeat. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +const hRequest Request::HREQUEST_REFERENCE_XY = { 1 }; +const hRequest Request::HREQUEST_REFERENCE_YZ = { 2 }; +const hRequest Request::HREQUEST_REFERENCE_ZX = { 3 }; + +struct EntReqMapping { + Request::Type reqType; + Entity::Type entType; + int points; + bool useExtraPoints; + bool hasNormal; + bool hasDistance; +}; +static const EntReqMapping EntReqMap[] = { +// request type entity type pts xtra? norml dist +{ Request::Type::WORKPLANE, Entity::Type::WORKPLANE, 1, false, true, false }, +{ Request::Type::DATUM_POINT, (Entity::Type)0, 1, false, false, false }, +{ Request::Type::LINE_SEGMENT, Entity::Type::LINE_SEGMENT, 2, false, false, false }, +{ Request::Type::CUBIC, Entity::Type::CUBIC, 4, true, false, false }, +{ Request::Type::CUBIC_PERIODIC, Entity::Type::CUBIC_PERIODIC, 3, true, false, false }, +{ Request::Type::CIRCLE, Entity::Type::CIRCLE, 1, false, true, true }, +{ Request::Type::ARC_OF_CIRCLE, Entity::Type::ARC_OF_CIRCLE, 3, false, true, false }, +{ Request::Type::TTF_TEXT, Entity::Type::TTF_TEXT, 4, false, true, false }, +{ Request::Type::IMAGE, Entity::Type::IMAGE, 4, false, true, false }, +}; + +static void CopyEntityInfo(const EntReqMapping *te, int extraPoints, + Entity::Type *ent, Request::Type *req, + int *pts, bool *hasNormal, bool *hasDistance) +{ + int points = te->points; + if(te->useExtraPoints) points += extraPoints; + + if(ent) *ent = te->entType; + if(req) *req = te->reqType; + if(pts) *pts = points; + if(hasNormal) *hasNormal = te->hasNormal; + if(hasDistance) *hasDistance = te->hasDistance; +} + +bool EntReqTable::GetRequestInfo(Request::Type req, int extraPoints, + Entity::Type *ent, int *pts, bool *hasNormal, bool *hasDistance) +{ + for(const EntReqMapping &te : EntReqMap) { + if(req == te.reqType) { + CopyEntityInfo(&te, extraPoints, ent, NULL, pts, hasNormal, hasDistance); + return true; + } + } + return false; +} + +bool EntReqTable::GetEntityInfo(Entity::Type ent, int extraPoints, + Request::Type *req, int *pts, bool *hasNormal, bool *hasDistance) +{ + for(const EntReqMapping &te : EntReqMap) { + if(ent == te.entType) { + CopyEntityInfo(&te, extraPoints, NULL, req, pts, hasNormal, hasDistance); + return true; + } + } + return false; +} + +Request::Type EntReqTable::GetRequestForEntity(Entity::Type ent) { + Request::Type req; + ssassert(GetEntityInfo(ent, 0, &req, NULL, NULL, NULL), + "No entity for request"); + return req; +} + +void Request::Generate(IdList *entity, + IdList *param) +{ + int points = 0; + Entity::Type et = (Entity::Type)0; + bool hasNormal = false; + bool hasDistance = false; + int i; + + // Request-specific generation. + switch(type) { + case Type::TTF_TEXT: { + double actualAspectRatio = SS.fonts.AspectRatio(font, str); + if(EXACT(actualAspectRatio != 0.0)) { + // We could load the font, so use the actual value. + aspectRatio = actualAspectRatio; + } + if(EXACT(aspectRatio == 0.0)) { + // We couldn't load the font and we don't have anything saved, + // so just use 1:1, which is valid for the missing font symbol anyhow. + aspectRatio = 1.0; + } + break; + } + + case Type::IMAGE: { + auto image = SS.images.find(file); + if(image != SS.images.end()) { + std::shared_ptr pixmap = (*image).second; + if(pixmap != NULL) { + aspectRatio = (double)pixmap->width / (double)pixmap->height; + } + } + if(EXACT(aspectRatio == 0.0)) { + aspectRatio = 1.0; + } + break; + } + + default: // most requests don't do anything else + break; + } + + Entity e = {}; + EntReqTable::GetRequestInfo(type, extraPoints, &et, &points, &hasNormal, &hasDistance); + + // Generate the entity that's specific to this request. + e.type = et; + e.extraPoints = extraPoints; + e.group = group; + e.style = style; + e.workplane = workplane; + e.construction = construction; + e.str = str; + e.font = font; + e.file = file; + e.aspectRatio = aspectRatio; + e.h = h.entity(0); + + // And generate entities for the points + for(i = 0; i < points; i++) { + Entity p = {}; + p.workplane = workplane; + // points start from entity 1, except for datum point case + p.h = h.entity(i+((et != (Entity::Type)0) ? 1 : 0)); + p.group = group; + p.style = style; + p.construction = e.construction; + if(workplane == Entity::FREE_IN_3D) { + p.type = Entity::Type::POINT_IN_3D; + // params for x y z + p.param[0] = AddParam(param, h.param(16 + 3*i + 0)); + p.param[1] = AddParam(param, h.param(16 + 3*i + 1)); + p.param[2] = AddParam(param, h.param(16 + 3*i + 2)); + } else { + p.type = Entity::Type::POINT_IN_2D; + // params for u v + p.param[0] = AddParam(param, h.param(16 + 3*i + 0)); + p.param[1] = AddParam(param, h.param(16 + 3*i + 1)); + } + entity->Add(&p); + e.point[i] = p.h; + } + if(hasNormal) { + Entity n = {}; + n.workplane = workplane; + n.h = h.entity(32); + n.group = group; + n.style = style; + n.construction = e.construction; + if(workplane == Entity::FREE_IN_3D) { + n.type = Entity::Type::NORMAL_IN_3D; + n.param[0] = AddParam(param, h.param(32+0)); + n.param[1] = AddParam(param, h.param(32+1)); + n.param[2] = AddParam(param, h.param(32+2)); + n.param[3] = AddParam(param, h.param(32+3)); + } else { + n.type = Entity::Type::NORMAL_IN_2D; + // and this is just a copy of the workplane quaternion, + // so no params required + } + ssassert(points >= 1, "Positioning a normal requires a point"); + // The point determines where the normal gets displayed on-screen; + // it's entirely cosmetic. + n.point[0] = e.point[0]; + entity->Add(&n); + e.normal = n.h; + } + if(hasDistance) { + Entity d = {}; + d.workplane = workplane; + d.h = h.entity(64); + d.group = group; + d.style = style; + d.type = Entity::Type::DISTANCE; + d.param[0] = AddParam(param, h.param(64)); + entity->Add(&d); + e.distance = d.h; + } + + if(et != (Entity::Type)0) entity->Add(&e); +} + +std::string Request::DescriptionString() const { + const char *s = ""; + if(h == Request::HREQUEST_REFERENCE_XY) { + s = "#XY"; + } else if(h == Request::HREQUEST_REFERENCE_YZ) { + s = "#YZ"; + } else if(h == Request::HREQUEST_REFERENCE_ZX) { + s = "#ZX"; + } else { + switch(type) { + case Type::WORKPLANE: s = "workplane"; break; + case Type::DATUM_POINT: s = "datum-point"; break; + case Type::LINE_SEGMENT: s = "line-segment"; break; + case Type::CUBIC: s = "cubic-bezier"; break; + case Type::CUBIC_PERIODIC: s = "periodic-cubic"; break; + case Type::CIRCLE: s = "circle"; break; + case Type::ARC_OF_CIRCLE: s = "arc-of-circle"; break; + case Type::TTF_TEXT: s = "ttf-text"; break; + case Type::IMAGE: s = "image"; break; + } + } + ssassert(s != NULL, "Unexpected request type"); + return ssprintf("r%03x-%s", h.v, s); +} + +int Request::IndexOfPoint(hEntity he) const { + if(type == Type::DATUM_POINT) { + return (he == h.entity(0)) ? 0 : -1; + } + for(int i = 0; i < MAX_POINTS_IN_ENTITY; i++) { + if(he == h.entity(i + 1)) { + return i; + } + } + return -1; +} + +hParam Request::AddParam(IdList *param, hParam hp) { + Param pa = {}; + pa.h = hp; + param->Add(&pa); + return hp; +} + diff --git a/src/resource.cpp b/src/resource.cpp new file mode 100644 index 0000000..7b19081 --- /dev/null +++ b/src/resource.cpp @@ -0,0 +1,1583 @@ +//----------------------------------------------------------------------------- +// Discovery and loading of our resources (icons, fonts, templates, etc). +// +// Copyright 2016 whitequark +//----------------------------------------------------------------------------- +#include +#include +#include +#include "solvespace.h" + +namespace SolveSpace { + +//----------------------------------------------------------------------------- +// Resource loading functions +//----------------------------------------------------------------------------- + +std::string LoadString(const std::string &name) { + size_t size; + const void *data = Platform::LoadResource(name, &size); + std::string result(static_cast(data), size); + + // When editing resources under Windows, Windows newlines may sneak in. + // Any files with them won't be merged, but ignoring them during development + // helps external contributors. + result.erase(std::remove(result.begin(), result.end(), '\r'), + result.end()); + + return result; +} + +std::string LoadStringFromGzip(const std::string &name) { + size_t deflatedSize; + const void *data = Platform::LoadResource(name, &deflatedSize); + + z_stream stream; + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + const int windowBits = /*maximum window*/ 15 + /*decode gzip header*/16; + ssassert(inflateInit2(&stream, windowBits) == Z_OK, "Cannot start inflation"); + + // Extract length mod 2**32 from the gzip trailer. + std::string result; + ssassert(deflatedSize >= 4, "Resource too small to have gzip trailer"); + + // *(uint32_t *) may perform an unaligned access, so do a memcpy. + uint32_t inflatedSize; + memcpy(&inflatedSize, (uint8_t *)((uintptr_t)data + deflatedSize - 4), sizeof(uint32_t)); + result.resize(inflatedSize); + + stream.next_in = (Bytef *)data; + stream.avail_in = (uInt)deflatedSize; + stream.next_out = (Bytef *)&result[0]; + stream.avail_out = (uInt)result.length(); + ssassert(inflate(&stream, Z_NO_FLUSH) == Z_STREAM_END, "Cannot inflate resource"); + ssassert(stream.avail_out == 0, "Inflated resource larger than what trailer indicates"); + + inflateEnd(&stream); + + return result; +} + +std::shared_ptr LoadPng(const std::string &name) { + size_t size; + const void *data = Platform::LoadResource(name, &size); + + std::shared_ptr pixmap = Pixmap::FromPng(static_cast(data), size); + ssassert(pixmap != nullptr, "Cannot load pixmap"); + + return pixmap; +} + +//----------------------------------------------------------------------------- +// Pixmap manipulation +//----------------------------------------------------------------------------- + +size_t Pixmap::GetBytesPerPixel() const { + switch(format) { + case Format::RGBA: return 4; + case Format::BGRA: return 4; + case Format::RGB: return 3; + case Format::BGR: return 3; + case Format::A: return 1; + } + ssassert(false, "Unexpected pixmap format"); +} + +RgbaColor Pixmap::GetPixel(size_t x, size_t y) const { + const uint8_t *pixel = &data[y * stride + x * GetBytesPerPixel()]; + + switch(format) { + case Format::RGBA: + return RgbaColor::From(pixel[0], pixel[1], pixel[2], pixel[3]); + + case Format::RGB: + return RgbaColor::From(pixel[0], pixel[1], pixel[2], 255); + + case Format::BGRA: + return RgbaColor::From(pixel[2], pixel[1], pixel[0], pixel[3]); + + case Format::BGR: + return RgbaColor::From(pixel[2], pixel[1], pixel[0], 255); + + case Format::A: + return RgbaColor::From( 255, 255, 255, pixel[0]); + } + ssassert(false, "Unexpected resource format"); +} + +void Pixmap::SetPixel(size_t x, size_t y, RgbaColor color) { + uint8_t *pixel = &data[y * stride + x * GetBytesPerPixel()]; + + switch(format) { + case Format::RGBA: + pixel[0] = color.red; + pixel[1] = color.green; + pixel[2] = color.blue; + pixel[3] = color.alpha; + break; + + case Format::RGB: + pixel[0] = color.red; + pixel[1] = color.green; + pixel[2] = color.blue; + break; + + case Format::BGRA: + pixel[0] = color.blue; + pixel[1] = color.green; + pixel[2] = color.red; + pixel[3] = color.alpha; + break; + + case Format::BGR: + pixel[0] = color.blue; + pixel[1] = color.green; + pixel[2] = color.red; + break; + + case Format::A: + pixel[0] = color.alpha; + break; + } +} + +void Pixmap::ConvertTo(Format newFormat) { + switch(format) { + case Format::RGBA: + ssassert(newFormat == Format::BGRA, "Unexpected target format"); + break; + + case Format::BGRA: + ssassert(newFormat == Format::RGBA, "Unexpected target format"); + break; + + case Format::RGB: + ssassert(newFormat == Format::BGR, "Unexpected target format"); + break; + + case Format::BGR: + ssassert(newFormat == Format::RGB, "Unexpected target format"); + break; + + case Format::A: + ssassert(false, "Unexpected target format"); + } + + size_t bpp = GetBytesPerPixel(); + for(size_t j = 0; j != height; j++) { + uint8_t *row = &data[j * stride]; + for(size_t i = 0; i != width * bpp; i += bpp) { + // This handles both RGB<>BGR and RGBA<>BGRA. + std::swap(row[i], row[i + 2]); + } + } + + format = newFormat; +} + +static std::shared_ptr ReadPngIntoPixmap(png_struct *png_ptr, png_info *info_ptr, + bool flip) { + png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND | PNG_TRANSFORM_GRAY_TO_RGB, NULL); + + std::shared_ptr pixmap = std::make_shared(); + pixmap->width = png_get_image_width(png_ptr, info_ptr); + pixmap->height = png_get_image_height(png_ptr, info_ptr); + if((png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_ALPHA) != 0) { + pixmap->format = Pixmap::Format::RGBA; + } else { + pixmap->format = Pixmap::Format::RGB; + } + + size_t stride = pixmap->width * pixmap->GetBytesPerPixel(); + if(stride % 4 != 0) stride += 4 - stride % 4; + pixmap->stride = stride; + + pixmap->data = std::vector(pixmap->stride * pixmap->height); + uint8_t **rows = png_get_rows(png_ptr, info_ptr); + for(size_t y = 0; y < pixmap->height; y++) { + uint8_t *srcRow = flip ? rows[pixmap->height - y - 1] : rows[y]; + memcpy(&pixmap->data[pixmap->stride * y], srcRow, + pixmap->width * pixmap->GetBytesPerPixel()); + } + + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + return pixmap; +} + +std::shared_ptr Pixmap::FromPng(const uint8_t *data, size_t size, bool flip) { + struct Slice { const uint8_t *data; size_t size; }; + Slice dataSlice = { data, size }; + png_struct *png_ptr = NULL; + png_info *info_ptr = NULL; + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if(!png_ptr) goto exit; + info_ptr = png_create_info_struct(png_ptr); + if(!info_ptr) goto exit; + + if(setjmp(png_jmpbuf(png_ptr))) goto exit; + + png_set_read_fn(png_ptr, &dataSlice, + [](png_struct *png_ptr, uint8_t *data, size_t size) { + Slice *dataSlice = (Slice *)png_get_io_ptr(png_ptr); + if(size <= dataSlice->size) { + memcpy(data, dataSlice->data, size); + dataSlice->data += size; + dataSlice->size -= size; + } else { + png_error(png_ptr, "EOF"); + } + }); + + return ReadPngIntoPixmap(png_ptr, info_ptr, flip); + +exit: + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + return nullptr; +} + +std::shared_ptr Pixmap::ReadPng(FILE *f, bool flip) { + png_struct *png_ptr = NULL; + png_info *info_ptr = NULL; + + uint8_t header[8]; + if(fread(header, 1, sizeof(header), f) != sizeof(header)) goto exit; + if(png_sig_cmp(header, 0, sizeof(header))) goto exit; + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if(!png_ptr) goto exit; + info_ptr = png_create_info_struct(png_ptr); + if(!info_ptr) goto exit; + + if(setjmp(png_jmpbuf(png_ptr))) goto exit; + + png_init_io(png_ptr, f); + png_set_sig_bytes(png_ptr, sizeof(header)); + + return ReadPngIntoPixmap(png_ptr, info_ptr, flip); + +exit: + png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + return nullptr; +} + +std::shared_ptr Pixmap::ReadPng(const Platform::Path &filename, bool flip) { + FILE *f = OpenFile(filename, "rb"); + if(!f) return NULL; + std::shared_ptr pixmap = ReadPng(f, flip); + fclose(f); + return pixmap; +} + +bool Pixmap::WritePng(FILE *f, bool flip) { + int colorType = 0; + bool bgr = false; + switch(format) { + case Format::RGBA: colorType = PNG_COLOR_TYPE_RGBA; bgr = false; break; + case Format::BGRA: colorType = PNG_COLOR_TYPE_RGBA; bgr = true; break; + case Format::RGB: colorType = PNG_COLOR_TYPE_RGB; bgr = false; break; + case Format::BGR: colorType = PNG_COLOR_TYPE_RGB; bgr = true; break; + case Format::A: colorType = PNG_COLOR_TYPE_GRAY; bgr = false; break; + } + + std::vector rows; + for(size_t y = 0; y < height; y++) { + if(flip) { + rows.push_back(&data[stride * (height - y - 1)]); + } else { + rows.push_back(&data[stride * y]); + } + } + + png_struct *png_ptr = NULL; + png_info *info_ptr = NULL; + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if(!png_ptr) goto exit; + info_ptr = png_create_info_struct(png_ptr); + if(!info_ptr) goto exit; + + if(setjmp(png_jmpbuf(png_ptr))) goto exit; + + png_init_io(png_ptr, f); + png_set_IHDR(png_ptr, info_ptr, + (png_uint_32)width, (png_uint_32)height, 8, colorType, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + if(bgr) png_set_bgr(png_ptr); + png_write_info(png_ptr, info_ptr); + png_write_image(png_ptr, &rows[0]); + png_write_end(png_ptr, info_ptr); + + png_destroy_write_struct(&png_ptr, &info_ptr); + return true; + +exit: + png_destroy_write_struct(&png_ptr, &info_ptr); + return false; +} + +bool Pixmap::WritePng(const Platform::Path &filename, bool flip) { + FILE *f = OpenFile(filename, "wb"); + if(!f) return false; + bool success = WritePng(f, flip); + fclose(f); + return success; +} + +bool Pixmap::Equals(const Pixmap &other) const { + if(format != other.format || width != other.width || height != other.height) { + return false; + } + + size_t rowLength = width * GetBytesPerPixel(); + for(size_t y = 0; y < height; y++) { + if(memcmp(&data[y * stride], &other.data[y * other.stride], rowLength)) { + return false; + } + } + + return true; +} + +std::shared_ptr Pixmap::Create(Format format, size_t width, size_t height) { + std::shared_ptr pixmap = std::make_shared(); + pixmap->format = format; + pixmap->width = width; + pixmap->height = height; + // Align to fulfill OpenGL texture requirements. + size_t stride = pixmap->width * pixmap->GetBytesPerPixel(); + if(stride % 4 != 0) stride += 4 - stride % 4; + pixmap->stride = stride; + pixmap->data = std::vector(pixmap->stride * pixmap->height); + return pixmap; +} + +std::shared_ptr Pixmap::Copy() { + std::shared_ptr pixmap = std::make_shared(); + pixmap->format = format; + pixmap->width = width; + pixmap->height = height; + pixmap->stride = stride; + pixmap->data = data; + return pixmap; +} + +//----------------------------------------------------------------------------- +// ASCII sequence parsing +//----------------------------------------------------------------------------- + +class ASCIIReader { +public: + std::string::const_iterator pos, end; + + static ASCIIReader From(const std::string &str) { + return ASCIIReader({ str.cbegin(), str.cend() }); + } + + bool AtEnd() const { + return pos == end; + } + + bool SkipSpace() { + bool skipped = false; + while(!AtEnd()) { + char c = *pos; + if(!(c == ' ' || c == '\t' || c == '\n')) break; + skipped = true; + pos++; + } + return skipped; + } + + char PeekChar() { + ssassert(!AtEnd(), "Unexpected EOF"); + return *pos; + } + + char ReadChar() { + ssassert(!AtEnd(), "Unexpected EOF"); + return *pos++; + } + + bool TryChar(char c) { + if(AtEnd()) { + return false; + } else if(*pos == c) { + pos++; + return true; + } else { + return false; + } + } + + void ExpectChar(char c) { + if(!TryChar(c)) { + dbp("Expecting character '%c'", c); + ssassert(false, "Unexpected character"); + } + } + + bool TryString(const std::string &s) { + if((size_t)(end - pos) >= s.size() && std::string(pos, pos + s.size()) == s) { + pos += s.size(); + return true; + } else { + return false; + } + } + + void ExpectString(const std::string &s) { + if(!TryString(s)) { + dbp("Expecting string '%s'", s.c_str()); + ssassert(false, "Unexpected string"); + } + } + + size_t CountUntilEol() const { + return std::find(pos, end, '\n') - pos; + } + + void SkipUntilEol() { + pos = std::find(pos, end, '\n'); + } + + std::string ReadUntilEol() { + auto eol = std::find(pos, end, '\n'); + std::string result(pos, eol); + if(eol != end) { + pos = eol + 1; + } else { + pos = end; + } + return result; + } + + uint8_t Read4HexBits() { + char c = ReadChar(); + if(c >= '0' && c <= '9') { + return c - '0'; + } else if(c >= 'a' && c <= 'f') { + return 10 + (c - 'a'); + } else if(c >= 'A' && c <= 'F') { + return 10 + (c - 'A'); + } else ssassert(false, "Unexpected hex digit"); + } + + uint8_t Read8HexBits() { + uint8_t h = Read4HexBits(), + l = Read4HexBits(); + return (h << 4) + l; + } + + uint16_t Read16HexBits() { + uint16_t h = Read8HexBits(), + l = Read8HexBits(); + return (h << 8) + l; + } + + long ReadIntegerDecimal(int base = 10) { + char *endptr; + long l = strtol(&*pos, &endptr, base); + ssassert(&*pos != endptr, "Cannot read an integer number"); + pos += endptr - &*pos; + return l; + } + + double ReadFloatDecimal() { + char *endptr; + double d = strtod(&*pos, &endptr); + ssassert(&*pos != endptr, "Cannot read a floating-point number"); + pos += endptr - &*pos; + return d; + } + + bool TryRegex(const std::regex &re, std::smatch *m) { + if(std::regex_search(pos, end, *m, re, std::regex_constants::match_continuous)) { + pos += m->length(); + return true; + } else { + return false; + } + } + + void ExpectRegex(const std::regex &re, std::smatch *m) { + ssassert(TryRegex(re, m), "Unmatched regex"); + } +}; + +//----------------------------------------------------------------------------- +// Bitmap font manipulation +//----------------------------------------------------------------------------- + +static uint8_t *BitmapFontTextureRow(std::shared_ptr texture, + uint16_t position, size_t y) { + // position = 0; + size_t col = position % (texture->width / 16), + row = position / (texture->width / 16); + return &texture->data[texture->stride * (16 * row + y) + 16 * col]; +} + +BitmapFont BitmapFont::From(std::string &&unifontData) { + BitmapFont font = {}; + font.unifontData = std::move(unifontData); + font.texture = Pixmap::Create(Pixmap::Format::A, 1024, 1024); + + return font; +} + +void BitmapFont::AddGlyph(char32_t codepoint, std::shared_ptr pixmap) { + ssassert((pixmap->width == 8 || pixmap->width == 16) && pixmap->height == 16, + "Unexpected pixmap dimensions"); + ssassert(pixmap->format == Pixmap::Format::RGB, + "Unexpected pixmap format"); + ssassert(glyphs.find(codepoint) == glyphs.end(), + "Glyph with this codepoint already exists"); + ssassert(nextPosition != 0xffff, + "Too many glyphs for current texture size"); + + BitmapFont::Glyph glyph = {}; + glyph.advanceCells = (uint8_t)(pixmap->width / 8); + glyph.position = nextPosition++; + glyphs.emplace(codepoint, glyph); + + for(size_t y = 0; y < pixmap->height; y++) { + uint8_t *row = BitmapFontTextureRow(texture, glyph.position, y); + for(size_t x = 0; x < pixmap->width; x++) { + if((pixmap->GetPixel(x, y).ToPackedInt() & 0xffffff) != 0) { + row[x] = 255; + } + } + } +} + +const BitmapFont::Glyph &BitmapFont::GetGlyph(char32_t codepoint) { + auto it = glyphs.find(codepoint); + if(it != glyphs.end()) { + return (*it).second; + } + + ssassert(nextPosition != 0xffff, + "Too many glyphs for current texture size"); + + // Find the hex representation in the (sorted) Unifont file. + auto first = unifontData.cbegin(), + last = unifontData.cend(); + while(first <= last) { + auto mid = first + (last - first) / 2; + while(mid != unifontData.cbegin()) { + if(*mid == '\n') { + mid++; + break; + } + mid--; + } + + ASCIIReader reader = { mid, unifontData.cend() }; + if(reader.AtEnd()) break; + + // Read the codepoint. + char32_t foundCodepoint = reader.Read16HexBits(); + reader.ExpectChar(':'); + + if(foundCodepoint > codepoint) { + last = mid - 1; + continue; // and first stays the same + } + if(foundCodepoint < codepoint) { + first = mid + 1; + while(first != unifontData.cend()) { + if(*first == '\n') break; + first++; + } + continue; // and last stays the same + } + + // Found the codepoint. + Glyph glyph = {}; + glyph.position = nextPosition++; + + // Read glyph bits. + unsigned short glyphBits[16]; + size_t glyphLength = reader.CountUntilEol(); + if(glyphLength == 4 * 16) { + glyph.advanceCells = 2; + for(size_t i = 0; i < 16; i++) { + glyphBits[i] = reader.Read16HexBits(); + } + } else if(glyphLength == 2 * 16) { + glyph.advanceCells = 1; + for(size_t i = 0; i < 16; i++) { + glyphBits[i] = (uint16_t)reader.Read8HexBits() << 8; + } + } else ssassert(false, "Unexpected glyph bitmap length"); + + // Fill in the texture (one texture byte per glyph bit). + for(size_t y = 0; y < 16; y++) { + uint8_t *row = BitmapFontTextureRow(texture, glyph.position, y); + for(size_t x = 0; x < 16; x++) { + if(glyphBits[y] & (1 << (15 - x))) { + row[x] = 255; + } + } + } + + it = glyphs.emplace(codepoint, glyph).first; + + textureUpdated = true; + return (*it).second; + } + + // Glyph doesn't exist; return replacement glyph instead. + ssassert(codepoint != 0xfffd, "Cannot parse replacement glyph"); + return GetGlyph(0xfffd); +} + +void BitmapFont::LocateGlyph(char32_t codepoint, + double *s0, double *t0, double *s1, double *t1, + size_t *w, size_t *h) { + const Glyph &glyph = GetGlyph(codepoint); + *w = glyph.advanceCells * 8; + *h = 16; + *s0 = (16.0 * (glyph.position % (texture->width / 16))) / texture->width; + *s1 = *s0 + (double)(*w) / texture->width; + *t0 = (16.0 * (glyph.position / (texture->width / 16))) / texture->height; + *t1 = *t0 + (double)(*h) / texture->height; +} + +size_t BitmapFont::GetWidth(char32_t codepoint) { + if(codepoint >= 0xe000 && codepoint <= 0xefff) { + // These are special-cased because checkboxes predate support for 2 cell wide + // characters; and so all Printf() calls pad them with spaces. + return 1; + } + + return GetGlyph(codepoint).advanceCells; +} + +size_t BitmapFont::GetWidth(const std::string &str) { + size_t width = 0; + for(char32_t codepoint : ReadUTF8(str)) { + width += GetWidth(codepoint); + } + return width; +} + +BitmapFont BitmapFont::Create() { + BitmapFont Font = BitmapFont::From(LoadStringFromGzip("fonts/unifont.hex.gz")); + // Unifont doesn't have a glyph for U+0020. + Font.AddGlyph(0x0020, Pixmap::Create(Pixmap::Format::RGB, 8, 16)); + Font.AddGlyph(0xE000, LoadPng("fonts/private/0-check-false.png")); + Font.AddGlyph(0xE001, LoadPng("fonts/private/1-check-true.png")); + Font.AddGlyph(0xE002, LoadPng("fonts/private/2-radio-false.png")); + Font.AddGlyph(0xE003, LoadPng("fonts/private/3-radio-true.png")); + Font.AddGlyph(0xE004, LoadPng("fonts/private/4-stipple-dot.png")); + Font.AddGlyph(0xE005, LoadPng("fonts/private/5-stipple-dash-long.png")); + Font.AddGlyph(0xE006, LoadPng("fonts/private/6-stipple-dash.png")); + Font.AddGlyph(0xE007, LoadPng("fonts/private/7-stipple-zigzag.png")); + return Font; +} + +//----------------------------------------------------------------------------- +// Vector font manipulation +//----------------------------------------------------------------------------- + +const static int ARC_POINTS = 8; +static void MakePwlArc(VectorFont::Contour *contour, bool isReversed, + const Point2d &cp, double radius, double a1, double a2) { + if(radius < LENGTH_EPS) return; + + double aSign = 1.0; + if(isReversed) { + if(a1 <= a2 + LENGTH_EPS) a1 += 2.0 * M_PI; + aSign = -1.0; + } else { + if(a2 <= a1 + LENGTH_EPS) a2 += 2.0 * M_PI; + } + + double aStep = aSign * fabs(a2 - a1) / (double)ARC_POINTS; + for(int i = 0; i <= ARC_POINTS; i++) { + contour->points.emplace_back(cp.Plus(Point2d::FromPolar(radius, a1 + aStep * i))); + } +} + +static void MakePwlBulge(VectorFont::Contour *contour, const Point2d &v, double bulge) { + bool reversed = bulge < 0.0; + double alpha = atan(bulge) * 4.0; + const Point2d &point = contour->points.back(); + + Point2d middle = point.Plus(v).ScaledBy(0.5); + double dist = point.DistanceTo(v) / 2.0; + double angle = point.AngleTo(v); + + // alpha can't be 0.0 at this point + double radius = fabs(dist / sin(alpha / 2.0)); + double wu = fabs(radius*radius - dist*dist); + double h = sqrt(wu); + + if(bulge > 0.0) { + angle += M_PI_2; + } else { + angle -= M_PI_2; + } + + if(fabs(alpha) > M_PI) { + h = -h; + } + + Point2d center = Point2d::FromPolar(h, angle).Plus(middle); + double a1 = center.AngleTo(point); + double a2 = center.AngleTo(v); + MakePwlArc(contour, reversed, center, radius, a1, a2); +} + +static void GetGlyphBBox(const VectorFont::Glyph &glyph, + double *rminx, double *rmaxx, double *rminy, double *rmaxy) { + double minx = 0.0, maxx = 0.0, miny = 0.0, maxy = 0.0; + if(!glyph.contours.empty()) { + const Point2d &start = glyph.contours[0].points[0]; + minx = maxx = start.x; + miny = maxy = start.y; + for(const VectorFont::Contour &c : glyph.contours) { + for(const Point2d &p : c.points) { + maxx = std::max(maxx, p.x); + minx = std::min(minx, p.x); + maxy = std::max(maxy, p.y); + miny = std::min(miny, p.y); + } + } + } + + if(rminx) *rminx = minx; + if(rmaxx) *rmaxx = maxx; + if(rminy) *rminy = miny; + if(rmaxy) *rmaxy = maxy; +} + +VectorFont VectorFont::From(std::string &&lffData) { + VectorFont font = {}; + font.lffData = std::move(lffData); + + ASCIIReader reader = ASCIIReader::From(font.lffData); + std::smatch m; + while(reader.TryRegex(std::regex("#\\s*(\\w+)\\s*:\\s*(.+?)\n"), &m)) { + std::string name = m.str(1), + value = m.str(2); + std::transform(name.begin(), name.end(), name.begin(), ::tolower); + if(name == "letterspacing") { + font.rightSideBearing = std::stod(value); + } else if(name == "wordspacing") { + Glyph space = {}; + space.advanceWidth = std::stod(value); + font.glyphs.emplace(' ', std::move(space)); + } + } + + GetGlyphBBox(font.GetGlyph('A'), nullptr, nullptr, nullptr, &font.capHeight); + GetGlyphBBox(font.GetGlyph('h'), nullptr, nullptr, nullptr, &font.ascender); + GetGlyphBBox(font.GetGlyph('p'), nullptr, nullptr, &font.descender, nullptr); + + ssassert(!font.IsEmpty(), "Expected to load a font"); + return font; +} + +const VectorFont::Glyph &VectorFont::GetGlyph(char32_t codepoint) { + auto it = glyphs.find(codepoint); + if(it != glyphs.end()) { + return (*it).second; + } + + auto firstGlyph = std::find(lffData.cbegin(), lffData.cend(), '['); + ssassert(firstGlyph != lffData.cend(), "Vector font contains no glyphs"); + + // Find the serialized representation in the (sorted) lff file. + auto first = firstGlyph, + last = lffData.cend(); + while(first <= last) { + auto mid = first + (last - first) / 2; + while(mid > first) { + if(*mid == '[' && *(mid - 1) == '\n') break; + mid--; + } + + ASCIIReader reader = { mid, lffData.cend() }; + if(reader.AtEnd()) break; + + // Read the codepoint. + reader.ExpectChar('['); + char32_t foundCodepoint = reader.Read16HexBits(); + reader.ExpectChar(']'); + reader.SkipUntilEol(); + + if(foundCodepoint > codepoint) { + last = mid - 1; + continue; // and first stays the same + } + if(foundCodepoint < codepoint) { + first = mid + 1; + while(first != lffData.cend()) { + if(*first == '[' && *(first - 1) == '\n') break; + first++; + } + continue; // and last stays the same + } + + // Found the codepoint. + VectorFont::Glyph glyph = {}; + + // Read glyph contours. + while(!reader.AtEnd()) { + if(reader.TryChar('\n')) { + // Skip. + } else if(reader.TryChar('[')) { + // End of glyph. + if(glyph.contours.back().points.empty()) { + // Remove an useless empty contour, if any. + glyph.contours.pop_back(); + } + break; + } else if(reader.TryChar('C')) { + // Another character is referenced in this one. + char32_t baseCodepoint = reader.Read16HexBits(); + const VectorFont::Glyph &baseGlyph = GetGlyph(baseCodepoint); + std::copy(baseGlyph.contours.begin(), baseGlyph.contours.end(), + std::back_inserter(glyph.contours)); + } else { + Contour contour; + do { + Point2d p; + p.x = reader.ReadFloatDecimal(); + reader.ExpectChar(','); + p.y = reader.ReadFloatDecimal(); + + if(reader.TryChar(',')) { + // Point with a bulge. + reader.ExpectChar('A'); + double bulge = reader.ReadFloatDecimal(); + MakePwlBulge(&contour, p, bulge); + } else { + // Just a point. + contour.points.emplace_back(std::move(p)); + } + } while(reader.TryChar(';')); + reader.ExpectChar('\n'); + glyph.contours.emplace_back(std::move(contour)); + } + } + + // Calculate metrics. + GetGlyphBBox(glyph, &glyph.leftSideBearing, &glyph.boundingWidth, nullptr, nullptr); + glyph.advanceWidth = glyph.leftSideBearing + glyph.boundingWidth + rightSideBearing; + + it = glyphs.emplace(codepoint, std::move(glyph)).first; + return (*it).second; + } + + // Glyph doesn't exist; return replacement glyph instead. + ssassert(codepoint != 0xfffd, "Cannot parse replacement glyph"); + return GetGlyph(0xfffd); +} + +VectorFont *VectorFont::Builtin() { + static VectorFont Font; + if(Font.IsEmpty()) { + Font = VectorFont::From(LoadStringFromGzip("fonts/unicode.lff.gz")); + } + return &Font; +} + +double VectorFont::GetCapHeight(double forCapHeight) const { + ssassert(!IsEmpty(), "Expected a loaded font"); + + return forCapHeight; +} + +double VectorFont::GetHeight(double forCapHeight) const { + ssassert(!IsEmpty(), "Expected a loaded font"); + + return (ascender - descender) * (forCapHeight / capHeight); +} + +double VectorFont::GetWidth(double forCapHeight, const std::string &str) { + ssassert(!IsEmpty(), "Expected a loaded font"); + + double width = 0; + for(char32_t codepoint : ReadUTF8(str)) { + width += GetGlyph(codepoint).advanceWidth; + } + width -= rightSideBearing; + return width * (forCapHeight / capHeight); +} + +Vector VectorFont::GetExtents(double forCapHeight, const std::string &str) { + Vector ex = {}; + ex.x = GetWidth(forCapHeight, str); + ex.y = GetHeight(forCapHeight); + return ex; +} + +void VectorFont::Trace(double forCapHeight, Vector o, Vector u, Vector v, const std::string &str, + const std::function &traceEdge) { + ssassert(!IsEmpty(), "Expected a loaded font"); + + double scale = (forCapHeight / capHeight); + u = u.ScaledBy(scale); + v = v.ScaledBy(scale); + + for(char32_t codepoint : ReadUTF8(str)) { + const Glyph &glyph = GetGlyph(codepoint); + + for(const VectorFont::Contour &contour : glyph.contours) { + Vector prevp; + bool penUp = true; + for(const Point2d &pt : contour.points) { + Vector p = o.Plus(u.ScaledBy(pt.x)) + .Plus(v.ScaledBy(pt.y)); + if(!penUp) traceEdge(prevp, p); + prevp = p; + penUp = false; + } + } + + o = o.Plus(u.ScaledBy(glyph.advanceWidth)); + } +} + +void VectorFont::Trace(double forCapHeight, Vector o, Vector u, Vector v, const std::string &str, + const std::function &traceEdge, const Camera &camera) { + ssassert(!IsEmpty(), "Expected a loaded font"); + + // Perform grid-fitting only when the text is parallel to the view plane. + if(camera.gridFit && !(u.WithMagnitude(1).Equals(camera.projRight) && + v.WithMagnitude(1).Equals(camera.projUp))) { + return Trace(forCapHeight, o, u, v, str, traceEdge); + } + + double scale = forCapHeight / capHeight; + u = u.ScaledBy(scale); + v = v.ScaledBy(scale); + + for(char32_t codepoint : ReadUTF8(str)) { + const Glyph &glyph = GetGlyph(codepoint); + double actualWidth = std::max(1.0, glyph.boundingWidth); + + // Align (o+lsb), (o+lsb+u) and (o+lsb+v) to pixel grid. + Vector ao = o.Plus(u.ScaledBy(glyph.leftSideBearing)); + Vector au = ao.Plus(u.ScaledBy(actualWidth)); + Vector av = ao.Plus(v.ScaledBy(capHeight)); + + ao = camera.AlignToPixelGrid(ao); + au = camera.AlignToPixelGrid(au); + av = camera.AlignToPixelGrid(av); + + au = au.Minus(ao).ScaledBy(1.0 / actualWidth); + av = av.Minus(ao).ScaledBy(1.0 / capHeight); + + for(const VectorFont::Contour &contour : glyph.contours) { + Vector prevp; + bool penUp = true; + for(const Point2d &pt : contour.points) { + Vector p = ao.Plus(au.ScaledBy(pt.x - glyph.leftSideBearing)) + .Plus(av.ScaledBy(pt.y)); + if(!penUp) traceEdge(prevp, p); + prevp = p; + penUp = false; + } + } + + o = o.Plus(u.ScaledBy(glyph.advanceWidth)); + } +} + +//----------------------------------------------------------------------------- +// Gettext plural expression evaluation +//----------------------------------------------------------------------------- + +class PluralExpr { +public: + class Token { + public: + enum class Type { + END, + VALUE, + BINARY_OP, + QUERY, + COLON, + PAREN_LEFT, + PAREN_RIGHT, + }; + + // Only valid for type == BINARY_OP. + enum class Op { + NONE, + // comparison + EQ, // == + NEQ, // != + LT, // < + GT, // > + LE, // <= + GE, // >= + // logical + AND, // && + OR, // || + // arithmetic + MOD, // % + }; + + Type type; + Op op; + unsigned value; + + int Precedence(); + }; + + ASCIIReader reader; + std::vector stack; + unsigned value; + + Token Lex(); + + Token PopToken(); + void Reduce(); + void Eval(); + + static unsigned Eval(const std::string &s, unsigned n); +}; + +int PluralExpr::Token::Precedence() { + switch(type) { + case Type::BINARY_OP: + switch(op) { + case Op::MOD: + return 7; + + case Op::LT: + case Op::GT: + case Op::LE: + case Op::GE: + return 6; + + case Op::EQ: + case Op::NEQ: + return 5; + + case Op::AND: + return 4; + + case Op::OR: + return 3; + + case Op::NONE: + ; + } + ssassert(false, "Unexpected operator"); + + case Type::QUERY: + case Type::COLON: + return 1; + + case Type::VALUE: + return 0; + + default: + ssassert(false, "Unexpected token op"); + } +} + +PluralExpr::Token PluralExpr::Lex() { + Token t = {}; + + reader.SkipSpace(); + + char c = reader.PeekChar(); + if(c >= '0' && c <= '9') { + t.type = Token::Type::VALUE; + t.value = reader.ReadIntegerDecimal(); + } else if(reader.TryChar('n')) { + t.type = Token::Type::VALUE; + t.value = value; + } else if(reader.TryChar('%')) { + t.type = Token::Type::BINARY_OP; + t.op = Token::Op::MOD; + } else if(reader.TryChar('<')) { + t.type = Token::Type::BINARY_OP; + if(reader.TryChar('=')) { + t.op = Token::Op::LE; + } else { + t.op = Token::Op::LT; + } + } else if(reader.TryChar('>')) { + t.type = Token::Type::BINARY_OP; + if(reader.TryChar('=')) { + t.op = Token::Op::GE; + } else { + t.op = Token::Op::GT; + } + } else if(reader.TryChar('!')) { + reader.ExpectChar('='); + t.type = Token::Type::BINARY_OP; + t.op = Token::Op::NEQ; + } else if(reader.TryChar('=')) { + reader.ExpectChar('='); + t.type = Token::Type::BINARY_OP; + t.op = Token::Op::EQ; + } else if(reader.TryChar('&')) { + reader.ExpectChar('&'); + t.type = Token::Type::BINARY_OP; + t.op = Token::Op::AND; + } else if(reader.TryChar('|')) { + reader.ExpectChar('|'); + t.type = Token::Type::BINARY_OP; + t.op = Token::Op::OR; + } else if(reader.TryChar('?')) { + t.type = Token::Type::QUERY; + } else if(reader.TryChar(':')) { + t.type = Token::Type::COLON; + } else if(reader.TryChar('(')) { + t.type = Token::Type::PAREN_LEFT; + } else if(reader.TryChar(')')) { + t.type = Token::Type::PAREN_RIGHT; + } else if(reader.AtEnd()) { + t.type = Token::Type::END; + } else { + ssassert(false, "Unexpected character"); + } + + return t; +} + +PluralExpr::Token PluralExpr::PopToken() { + ssassert(!stack.empty(), "Expected a non-empty stack"); + Token t = stack.back(); + stack.pop_back(); + return t; +} + +void PluralExpr::Reduce() { + Token r; + r.type = Token::Type::VALUE; + + Token a = PopToken(); + ssassert(a.type == Token::Type::VALUE, "Expected 1st operand to be a value"); + + Token op = PopToken(); + switch(op.type) { + case Token::Type::BINARY_OP: { + Token b = PopToken(); + ssassert(b.type == Token::Type::VALUE, "Expected 2nd operand to be a value"); + + switch(op.op) { + case Token::Op::EQ: + r.value = (a.value == b.value ? 1 : 0); + break; + case Token::Op::NEQ: + r.value = (a.value != b.value ? 1 : 0); + break; + case Token::Op::LT: + r.value = (b.value < a.value ? 1 : 0); + break; + case Token::Op::GT: + r.value = (b.value > a.value ? 1 : 0); + break; + case Token::Op::LE: + r.value = (b.value <= a.value ? 1 : 0); + break; + case Token::Op::GE: + r.value = (b.value >= a.value ? 1 : 0); + break; + case Token::Op::AND: + r.value = a.value && b.value; + break; + case Token::Op::OR: + r.value = a.value || b.value; + break; + case Token::Op::MOD: + r.value = b.value % a.value; + break; + case Token::Op::NONE: + ssassert(false, "Unexpected operator"); + } + break; + } + + case Token::Type::COLON: { + Token b = PopToken(); + ssassert(PopToken().type == Token::Type::QUERY, "Expected ?"); + Token c = PopToken(); + r.value = c.value ? b.value : a.value; + break; + } + + default: + ssassert(false, "Unexpected operator type"); + } + + stack.push_back(r); +} + +void PluralExpr::Eval() { + while(true) { + Token t = Lex(); + switch(t.type) { + case Token::Type::END: + case Token::Type::PAREN_RIGHT: + while(stack.size() > 1 && + stack.end()[-2].type != Token::Type::PAREN_LEFT) { + Reduce(); + } + if(t.type == Token::Type::PAREN_RIGHT) { + ssassert(stack.size() > 1, "Expected ("); + stack.push_back(t); + } + return; + + case Token::Type::PAREN_LEFT: + stack.push_back(t); + Eval(); + if(stack.back().type != Token::Type::PAREN_RIGHT) { + ssassert(false, "Expected )"); + } + stack.pop_back(); + stack.erase(stack.end() - 2); + break; + + case Token::Type::VALUE: + stack.push_back(t); + break; + + case Token::Type::BINARY_OP: + case Token::Type::QUERY: + case Token::Type::COLON: + while(stack.size() > 1 && + stack.end()[-2].type != Token::Type::PAREN_LEFT && + t.Precedence() < stack.end()[-2].Precedence()) { + Reduce(); + } + stack.push_back(t); + break; + } + } +} + +unsigned PluralExpr::Eval(const std::string &s, unsigned n) { + PluralExpr expr = {}; + expr.reader = ASCIIReader::From(s); + expr.value = n; + expr.Eval(); + + Token t = expr.PopToken(); + ssassert(t.type == Token::Type::VALUE, "Expected a value"); + return t.value; +} + +//----------------------------------------------------------------------------- +// Gettext message keys +//----------------------------------------------------------------------------- + +class TranslationKey { +public: + bool hasContext; + std::string context; + std::string ident; +}; + +struct TranslationKeyLess { + bool operator()(const TranslationKey &a, const TranslationKey &b) const { + return a.hasContext < b.hasContext || + (a.hasContext == b.hasContext && a.context < b.context) || + (a.hasContext == b.hasContext && a.context == b.context && a.ident < b.ident); + } +}; + +//----------------------------------------------------------------------------- +// Gettext .po file parsing +//----------------------------------------------------------------------------- + +class GettextParser { +public: + ASCIIReader reader; + + unsigned pluralCount; + std::string pluralExpr; + + std::map, TranslationKeyLess> messages; + + void SkipSpace(); + std::string ReadString(); + void ParseHeader(const std::string &header); + void Parse(); +}; + +void GettextParser::SkipSpace() { + while(!reader.AtEnd()) { + if(reader.TryChar('#')) { + reader.SkipUntilEol(); + } else if(!reader.SkipSpace()) { + break; + } + } +} + +std::string GettextParser::ReadString() { + SkipSpace(); + reader.ExpectChar('"'); + + std::string result; + while(true) { + if(reader.AtEnd()) { + ssassert(false, "Unexpected EOF within a string"); + } else if(reader.TryChar('\"')) { + SkipSpace(); + if(!reader.TryChar('\"')) { + break; + } + } else if(reader.TryChar('\\')) { + if(reader.TryChar('\\')) { + result += '\\'; + } else if(reader.TryChar('n')) { + result += '\n'; + } else if(reader.TryChar('t')) { + result += '\t'; + } else if(reader.TryChar('"')) { + result += '"'; + } else { + ssassert(false, "Unexpected escape sequence"); + } + } else { + result += reader.ReadChar(); + } + } + return result; +} + +void GettextParser::ParseHeader(const std::string &header) { + ASCIIReader reader = ASCIIReader::From(header); + while(!reader.AtEnd()) { + reader.SkipSpace(); + if(reader.TryString("Plural-Forms:")) { + reader.SkipSpace(); + reader.ExpectString("nplurals="); + reader.SkipSpace(); + pluralCount = reader.ReadIntegerDecimal(); + reader.SkipSpace(); + reader.ExpectString(";"); + reader.SkipSpace(); + reader.ExpectString("plural="); + pluralExpr = reader.ReadUntilEol(); + } else { + reader.SkipUntilEol(); + } + } +} + +void GettextParser::Parse() { + // Default to a single form, in case a header is missing. + pluralCount = 1; + pluralExpr = "0"; + + SkipSpace(); + while(!reader.AtEnd()) { + TranslationKey key = {}; + + if(reader.TryString("msgctxt")) { + key.hasContext = true; + key.context = ReadString(); + } + + reader.ExpectString("msgid"); + key.ident = ReadString(); + + if(reader.TryString("msgid_plural")) { + ReadString(); // we don't need it + } + + std::vector msgstrs; + while(reader.TryString("msgstr")) { + if(reader.TryChar('[')) { + unsigned index = reader.ReadIntegerDecimal(); + reader.ExpectChar(']'); + if(msgstrs.size() <= index) { + msgstrs.resize(index + 1); + } + msgstrs[index] = ReadString(); + } else { + msgstrs.emplace_back(ReadString()); + break; + } + } + + if(key.ident.empty()) { + ssassert(msgstrs.size() == 1, + "Expected exactly one header msgstr"); + ParseHeader(msgstrs[0]); + } else { + ssassert(msgstrs.size() == 1 || + msgstrs.size() == pluralCount, + "Expected msgstr count to match plural form count"); + messages.emplace(key, msgstrs); + } + } +} + +//----------------------------------------------------------------------------- +// Translation management +//----------------------------------------------------------------------------- + +class Translation { +public: + unsigned pluralCount; + std::string pluralExpr; + + std::map, TranslationKeyLess> messages; + + static Translation From(const std::string &poData); + + const std::string &Translate(const TranslationKey &key); + const std::string &TranslatePlural(const TranslationKey &key, unsigned n); +}; + +Translation Translation::From(const std::string &poData) { + GettextParser parser = {}; + parser.reader = ASCIIReader::From(poData); + parser.Parse(); + + Translation trans = {}; + trans.pluralCount = parser.pluralCount; + trans.pluralExpr = parser.pluralExpr; + trans.messages = parser.messages; + return trans; +} + +const std::string &Translation::Translate(const TranslationKey &key) { + auto it = messages.find(key); + if(it == messages.end()) { + dbp("Missing (absent) translation for %s'%s'", key.context.c_str(), key.ident.c_str()); + messages[key].emplace_back(key.ident); + it = messages.find(key); + } + if(it->second[0].empty()) { + dbp("Missing (empty) translation for %s'%s'", key.context.c_str(), key.ident.c_str()); + it->second[0] = key.ident; + } + if(it->second.size() != 1) { + dbp("Incorrect use of translated message %s'%s'", key.context.c_str(), key.ident.c_str()); + ssassert(false, "Using a message with a plural form without a number"); + } + return it->second[0]; +} + +const std::string &Translation::TranslatePlural(const TranslationKey &key, unsigned n) { + unsigned pluralForm = PluralExpr::Eval(pluralExpr, n); + + auto it = messages.find(key); + if(it == messages.end()) { + dbp("Missing (absent) translation for %s'%s'", key.context.c_str(), key.ident.c_str()); + for(unsigned i = 0; i < pluralCount; i++) { + messages[key].emplace_back(key.ident); + } + it = messages.find(key); + } + if(it->second[pluralForm].empty()) { + dbp("Missing (empty) translation for %s'%s'[%d]", + key.context.c_str(), key.ident.c_str(), pluralForm); + it->second[pluralForm] = key.ident; + } + return it->second[pluralForm]; +} + +//----------------------------------------------------------------------------- +// Locale management +//----------------------------------------------------------------------------- + +static std::set locales; +static std::map translations; +static Translation dummyTranslation; +static Translation *currentTranslation = &dummyTranslation; + +const std::set &Locales() { + if(!locales.empty()) return locales; + + std::string localeList = LoadString("locales.txt"); + ASCIIReader reader = ASCIIReader::From(localeList); + while(!reader.AtEnd()) { + reader.SkipSpace(); + if(reader.TryChar('#')) { + reader.SkipUntilEol(); + continue; + } + + std::smatch m; + reader.ExpectRegex(std::regex("([a-z]{2})-([A-Z]{2}),([0-9A-F]{4}),(.+?)\n"), &m); + Locale locale = {}; + locale.language = m.str(1); + locale.region = m.str(2); + locale.lcid = std::stoi(m.str(3), NULL, 16); + locale.displayName = m.str(4); + locales.emplace(locale); + } + return locales; +} + +template +bool SetLocale(Predicate pred) { + auto it = std::find_if(Locales().begin(), Locales().end(), pred); + if(it != locales.end()) { + std::string filename = "locales/" + it->language + "_" + it->region + ".po"; + translations[*it] = Translation::From(LoadString(filename)); + currentTranslation = &translations[*it]; + return true; + } else { + return false; + } +} + +bool SetLocale(const std::string &name) { + return SetLocale([&](const Locale &locale) { + if(name == locale.language + "-" + locale.region) { + return true; + } else if(name == locale.language + "_" + locale.region) { + return true; + } else if(name == locale.language) { + return true; + } else { + return false; + } + }); +} + +bool SetLocale(uint16_t lcid) { + return SetLocale([&](const Locale &locale) { + return locale.lcid == lcid; + }); +} + +const std::string &Translate(const char *msgid) { + TranslationKey key = {}; + key.ident = msgid; + return currentTranslation->Translate(key); +} + +const std::string &Translate(const char *msgctxt, const char *msgid) { + TranslationKey key = {}; + key.hasContext = true; + key.context = msgctxt; + key.ident = msgid; + return currentTranslation->Translate(key); +} + +const std::string &TranslatePlural(const char *msgid, unsigned n) { + TranslationKey key = {}; + key.ident = msgid; + return currentTranslation->TranslatePlural(key, n); +} + +const std::string &TranslatePlural(const char *msgctxt, const char *msgid, unsigned n) { + TranslationKey key = {}; + key.hasContext = true; + key.context = msgctxt; + key.ident = msgid; + return currentTranslation->TranslatePlural(key, n); +} + +} diff --git a/src/resource.h b/src/resource.h new file mode 100644 index 0000000..18c1e58 --- /dev/null +++ b/src/resource.h @@ -0,0 +1,112 @@ +//----------------------------------------------------------------------------- +// Discovery and loading of our resources (icons, fonts, templates, etc). +// +// Copyright 2016 whitequark +//----------------------------------------------------------------------------- + +#ifndef SOLVESPACE_RESOURCE_H +#define SOLVESPACE_RESOURCE_H + +class Camera; +class Point2d; +class Pixmap; +class Vector; +class RgbaColor; + +std::string LoadString(const std::string &name); +std::string LoadStringFromGzip(const std::string &name); +std::shared_ptr LoadPng(const std::string &name); + +class Pixmap { +public: + enum class Format { BGRA, RGBA, BGR, RGB, A }; + + Format format; + size_t width; + size_t height; + size_t stride; + std::vector data; + + static std::shared_ptr Create(Format format, size_t width, size_t height); + static std::shared_ptr FromPng(const uint8_t *data, size_t size, bool flip = false); + + static std::shared_ptr ReadPng(FILE *f, bool flip = false); + static std::shared_ptr ReadPng(const Platform::Path &filename, bool flip = false); + bool WritePng(FILE *f, bool flip = false); + bool WritePng(const Platform::Path &filename, bool flip = false); + + size_t GetBytesPerPixel() const; + RgbaColor GetPixel(size_t x, size_t y) const; + bool Equals(const Pixmap &other) const; + + void ConvertTo(Format newFormat); + void SetPixel(size_t x, size_t y, RgbaColor color); + + std::shared_ptr Copy(); +}; + +class BitmapFont { +public: + struct Glyph { + uint8_t advanceCells; + uint16_t position; + }; + + std::string unifontData; + std::map glyphs; + std::shared_ptr texture; + bool textureUpdated; + uint16_t nextPosition; + + static BitmapFont From(std::string &&unifontData); + static BitmapFont Create(); + + bool IsEmpty() const { return unifontData.empty(); } + const Glyph &GetGlyph(char32_t codepoint); + void LocateGlyph(char32_t codepoint, double *s0, double *t0, double *s1, double *t1, + size_t *advanceWidth, size_t *boundingHeight); + + void AddGlyph(char32_t codepoint, std::shared_ptr pixmap); + + size_t GetWidth(char32_t codepoint); + size_t GetWidth(const std::string &str); +}; + +class VectorFont { +public: + struct Contour { + std::vector points; + }; + + struct Glyph { + std::vector contours; + double leftSideBearing; + double boundingWidth; + double advanceWidth; + }; + + std::string lffData; + std::map glyphs; + double rightSideBearing; + double capHeight; + double ascender; + double descender; + + static VectorFont From(std::string &&lffData); + static VectorFont *Builtin(); + + bool IsEmpty() const { return lffData.empty(); } + const Glyph &GetGlyph(char32_t codepoint); + + double GetCapHeight(double forCapHeight) const; + double GetHeight(double forCapHeight) const; + double GetWidth(double forCapHeight, const std::string &str); + Vector GetExtents(double forCapHeight, const std::string &str); + + void Trace(double forCapHeight, Vector o, Vector u, Vector v, const std::string &str, + const std::function &traceEdge); + void Trace(double forCapHeight, Vector o, Vector u, Vector v, const std::string &str, + const std::function &traceEdge, const Camera &camera); +}; + +#endif diff --git a/src/sketch.h b/src/sketch.h new file mode 100644 index 0000000..8377374 --- /dev/null +++ b/src/sketch.h @@ -0,0 +1,987 @@ +//----------------------------------------------------------------------------- +// The parametric structure of our sketch, in multiple groups, that generate +// geometric entities and surfaces. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- + +#ifndef SOLVESPACE_SKETCH_H +#define SOLVESPACE_SKETCH_H + +class hGroup; +class hRequest; +class hEntity; +class hParam; +class hStyle; +class hConstraint; +class hEquation; + +class Entity; +class Param; +class Equation; +class Style; + +enum class PolyError : uint32_t { + GOOD = 0, + NOT_CLOSED = 1, + NOT_COPLANAR = 2, + SELF_INTERSECTING = 3, + ZERO_LEN_EDGE = 4 +}; + +enum class StipplePattern : uint32_t { + CONTINUOUS = 0, + SHORT_DASH = 1, + DASH = 2, + LONG_DASH = 3, + DASH_DOT = 4, + DASH_DOT_DOT = 5, + DOT = 6, + FREEHAND = 7, + ZIGZAG = 8, + + LAST = ZIGZAG +}; + +const std::vector &StipplePatternDashes(StipplePattern pattern); +double StipplePatternLength(StipplePattern pattern); + +enum class Command : uint32_t; + +// All of the hWhatever handles are a 32-bit ID, that is used to represent +// some data structure in the sketch. +class hGroup { +public: + // bits 15: 0 -- group index + uint32_t v; + + inline hEntity entity(int i) const; + inline hParam param(int i) const; + inline hEquation equation(int i) const; +}; + +template<> +struct IsHandleOracle
: std::true_type {}; + +class hRequest { +public: + // bits 15: 0 -- request index + uint32_t v; + + inline hEntity entity(int i) const; + inline hParam param(int i) const; + + inline bool IsFromReferences() const; +}; + +template<> +struct IsHandleOracle : std::true_type {}; + +class hEntity { +public: + // bits 15: 0 -- entity index + // 31:16 -- request index + uint32_t v; + + inline bool isFromRequest() const; + inline hRequest request() const; + inline hGroup group() const; + inline hEquation equation(int i) const; +}; + +template<> +struct IsHandleOracle : std::true_type {}; + +class hParam { +public: + // bits 15: 0 -- param index + // 31:16 -- request index + uint32_t v; + + inline hRequest request() const; +}; + +template<> +struct IsHandleOracle : std::true_type {}; + +class hStyle { +public: + uint32_t v; +}; + +template<> +struct IsHandleOracle : std::true_type {}; + +struct EntityId { + uint32_t v; // entity ID, starting from 0 +}; + +template<> +struct IsHandleOracle : std::true_type {}; + +struct EntityKey { + hEntity input; + int copyNumber; + // (input, copyNumber) gets mapped to ((Request)xxx).entity(h.v) +}; +struct EntityKeyHash { + size_t operator()(const EntityKey &k) const { + size_t h1 = std::hash{}(k.input.v), + h2 = std::hash{}(k.copyNumber); + return h1 ^ (h2 << 1); + } +}; +struct EntityKeyEqual { + bool operator()(const EntityKey &a, const EntityKey &b) const { + return std::tie(a.input, a.copyNumber) == std::tie(b.input, b.copyNumber); + } +}; +typedef std::unordered_map EntityMap; + +// A set of requests. Every request must have an associated group. +class Group { +public: + static const hGroup HGROUP_REFERENCES; + + int tag; + hGroup h; + + enum class CopyAs { + NUMERIC, + N_TRANS, + N_ROT_AA, + N_ROT_TRANS, + N_ROT_AXIS_TRANS, + }; + + enum class Type : uint32_t { + DRAWING_3D = 5000, + DRAWING_WORKPLANE = 5001, + EXTRUDE = 5100, + LATHE = 5101, + REVOLVE = 5102, + HELIX = 5103, + ROTATE = 5200, + TRANSLATE = 5201, + LINKED = 5300 + }; + Group::Type type; + + int order; + + hGroup opA; + hGroup opB; + bool visible; + bool suppress; + bool relaxConstraints; + bool allowRedundant; + bool allDimsReference; + double scale; + + bool clean; + bool dofCheckOk; + hEntity activeWorkplane; + double valA; + double valB; + double valC; + RgbaColor color; + + struct { + SolveResult how; + int dof; + int findToFixTimeout; + bool timeout; + List remove; + } solved; + + enum class Subtype : uint32_t { + // For drawings in 2d + WORKPLANE_BY_POINT_ORTHO = 6000, + WORKPLANE_BY_LINE_SEGMENTS = 6001, + // For extrudes, translates, and rotates + ONE_SIDED = 7000, + TWO_SIDED = 7001 + }; + Group::Subtype subtype; + + bool skipFirst; // for step and repeat ops + + struct { + Quaternion q; + hEntity origin; + hEntity entityB; + hEntity entityC; + bool swapUV; + bool negateU; + bool negateV; + } predef; + + SPolygon polyLoops; + SBezierLoopSetSet bezierLoops; + SBezierLoopSet bezierOpens; + + struct { + PolyError how; + SEdge notClosedAt; + Vector errorPointAt; + } polyError; + + bool booleanFailed; + + SShell thisShell; + SShell runningShell; + + SMesh thisMesh; + SMesh runningMesh; + + bool displayDirty; + SMesh displayMesh; + SOutlineList displayOutlines; + + enum class CombineAs : uint32_t { + UNION = 0, + DIFFERENCE = 1, + ASSEMBLE = 2, + INTERSECTION = 3 + }; + CombineAs meshCombine; + + bool forceToMesh; + + EntityMap remap; + + Platform::Path linkFile; + SMesh impMesh; + SShell impShell; + EntityList impEntity; + + std::string name; + + + void Activate(); + std::string DescriptionString(); + void Clear(); + + static void AddParam(ParamList *param, hParam hp, double v); + void Generate(EntityList *entity, ParamList *param); + bool IsSolvedOkay(); + void TransformImportedBy(Vector t, Quaternion q); + bool IsForcedToMeshBySource() const; + bool IsForcedToMesh() const; + // When a request generates entities from entities, and the source + // entities may have come from multiple requests, it's necessary to + // remap the entity ID so that it's still unique. We do this with a + // mapping list. + enum { + REMAP_LAST = 1000, + REMAP_TOP = 1001, + REMAP_BOTTOM = 1002, + REMAP_PT_TO_LINE = 1003, + REMAP_LINE_TO_FACE = 1004, + REMAP_LATHE_START = 1006, + REMAP_LATHE_END = 1007, + REMAP_PT_TO_ARC = 1008, + REMAP_PT_TO_NORMAL = 1009, + REMAP_LATHE_ARC_CENTER = 1010, + }; + hEntity Remap(hEntity in, int copyNumber); + void MakeExtrusionLines(EntityList *el, hEntity in); + void MakeLatheCircles(IdList *el, IdList *param, hEntity in, Vector pt, Vector axis); + void MakeLatheSurfacesSelectable(IdList *el, hEntity in, Vector axis); + void MakeRevolveEndFaces(IdList *el, hEntity pt, int ai, int af); + void MakeExtrusionTopBottomFaces(EntityList *el, hEntity pt); + void CopyEntity(EntityList *el, + Entity *ep, int timesApplied, int remap, + hParam dx, hParam dy, hParam dz, + hParam qw, hParam qvx, hParam qvy, hParam qvz, hParam dist, + CopyAs as); + + void AddEq(IdList *l, Expr *expr, int index); + void GenerateEquations(IdList *l); + bool IsVisible(); + size_t GetNumConstraints(); + Vector ExtrusionGetVector(); + void ExtrusionForceVectorTo(const Vector &v); + + // Assembling the curves into loops, and into a piecewise linear polygon + // at the same time. + void AssembleLoops(bool *allClosed, bool *allCoplanar, bool *allNonZeroLen); + void GenerateLoops(); + // And the mesh stuff + Group *PreviousGroup() const; + Group *RunningMeshGroup() const; + bool IsMeshGroup(); + + void GenerateShellAndMesh(); + template void GenerateForStepAndRepeat(T *steps, T *outs, Group::CombineAs forWhat); + template void GenerateForBoolean(T *a, T *b, T *o, Group::CombineAs how); + void GenerateDisplayItems(); + + enum class DrawMeshAs { DEFAULT, HOVERED, SELECTED }; + void DrawMesh(DrawMeshAs how, Canvas *canvas); + void Draw(Canvas *canvas); + void DrawPolyError(Canvas *canvas); + void DrawFilledPaths(Canvas *canvas); + void DrawContourAreaLabels(Canvas *canvas); + + SPolygon GetPolygon(); + + static void MenuGroup(Command id); + static void MenuGroup(Command id, Platform::Path linkFile); +}; + +// A user request for some primitive or derived operation; for example a +// line, or a step and repeat. +class Request { +public: + // Some predefined requests, that are present in every sketch. + static const hRequest HREQUEST_REFERENCE_XY; + static const hRequest HREQUEST_REFERENCE_YZ; + static const hRequest HREQUEST_REFERENCE_ZX; + + int tag; + hRequest h; + + // Types of requests + enum class Type : uint32_t { + WORKPLANE = 100, + DATUM_POINT = 101, + LINE_SEGMENT = 200, + CUBIC = 300, + CUBIC_PERIODIC = 301, + CIRCLE = 400, + ARC_OF_CIRCLE = 500, + TTF_TEXT = 600, + IMAGE = 700 + }; + + Request::Type type; + int extraPoints; + + hEntity workplane; // or Entity::FREE_IN_3D + hGroup group; + hStyle style; + + bool construction; + + std::string str; + std::string font; + Platform::Path file; + double aspectRatio; + + static hParam AddParam(ParamList *param, hParam hp); + void Generate(EntityList *entity, ParamList *param); + + std::string DescriptionString() const; + int IndexOfPoint(hEntity he) const; + + void Clear() {} +}; + +#define MAX_POINTS_IN_ENTITY (12) +class EntityBase { +public: + int tag; + hEntity h; + + static const hEntity FREE_IN_3D; + static const hEntity NO_ENTITY; + + enum class Type : uint32_t { + POINT_IN_3D = 2000, + POINT_IN_2D = 2001, + POINT_N_TRANS = 2010, + POINT_N_ROT_TRANS = 2011, + POINT_N_COPY = 2012, + POINT_N_ROT_AA = 2013, + POINT_N_ROT_AXIS_TRANS = 2014, + + NORMAL_IN_3D = 3000, + NORMAL_IN_2D = 3001, + NORMAL_N_COPY = 3010, + NORMAL_N_ROT = 3011, + NORMAL_N_ROT_AA = 3012, + + DISTANCE = 4000, + DISTANCE_N_COPY = 4001, + + FACE_NORMAL_PT = 5000, + FACE_XPROD = 5001, + FACE_N_ROT_TRANS = 5002, + FACE_N_TRANS = 5003, + FACE_N_ROT_AA = 5004, + FACE_ROT_NORMAL_PT = 5005, + FACE_N_ROT_AXIS_TRANS = 5006, + + WORKPLANE = 10000, + LINE_SEGMENT = 11000, + CUBIC = 12000, + CUBIC_PERIODIC = 12001, + CIRCLE = 13000, + ARC_OF_CIRCLE = 14000, + TTF_TEXT = 15000, + IMAGE = 16000 + }; + + Type type; + + hGroup group; + hEntity workplane; // or Entity::FREE_IN_3D + + // When it comes time to draw an entity, we look here to get the + // defining variables. + hEntity point[MAX_POINTS_IN_ENTITY]; + int extraPoints; + hEntity normal; + hEntity distance; + // The only types that have their own params are points, normals, + // and directions. + hParam param[8]; + + // Transformed points/normals/distances have their numerical base + Vector numPoint; + Quaternion numNormal; + double numDistance; + + std::string str; + std::string font; + Platform::Path file; + double aspectRatio; + + // For entities that are derived by a transformation, the number of + // times to apply the transformation. + int timesApplied; + + Quaternion GetAxisAngleQuaternion(int param0) const; + ExprQuaternion GetAxisAngleQuaternionExprs(int param0) const; + + bool IsCircle() const; + Expr *CircleGetRadiusExpr() const; + double CircleGetRadiusNum() const; + void ArcGetAngles(double *thetaa, double *thetab, double *dtheta) const; + + bool HasVector() const; + ExprVector VectorGetExprs() const; + ExprVector VectorGetExprsInWorkplane(hEntity wrkpl) const; + Vector VectorGetNum() const; + Vector VectorGetRefPoint() const; + Vector VectorGetStartPoint() const; + + // For distances + bool IsDistance() const; + double DistanceGetNum() const; + Expr *DistanceGetExpr() const; + void DistanceForceTo(double v); + + bool IsWorkplane() const; + // The plane is points P such that P dot (xn, yn, zn) - d = 0 + void WorkplaneGetPlaneExprs(ExprVector *n, Expr **d) const; + ExprVector WorkplaneGetOffsetExprs() const; + Vector WorkplaneGetOffset() const; + EntityBase *Normal() const; + + bool IsFace() const; + ExprVector FaceGetNormalExprs() const; + Vector FaceGetNormalNum() const; + ExprVector FaceGetPointExprs() const; + Vector FaceGetPointNum() const; + + bool IsPoint() const; + // Applies for any of the point types + Vector PointGetNum() const; + ExprVector PointGetExprs() const; + void PointGetExprsInWorkplane(hEntity wrkpl, Expr **u, Expr **v) const; + ExprVector PointGetExprsInWorkplane(hEntity wrkpl) const; + void PointForceTo(Vector v); + void PointForceParamTo(Vector v); + // These apply only the POINT_N_ROT_TRANS, which has an assoc rotation + Quaternion PointGetQuaternion() const; + void PointForceQuaternionTo(Quaternion q); + + bool IsNormal() const; + // Applies for any of the normal types + Quaternion NormalGetNum() const; + ExprQuaternion NormalGetExprs() const; + void NormalForceTo(Quaternion q); + + Vector NormalU() const; + Vector NormalV() const; + Vector NormalN() const; + ExprVector NormalExprsU() const; + ExprVector NormalExprsV() const; + ExprVector NormalExprsN() const; + + Vector CubicGetStartNum() const; + Vector CubicGetFinishNum() const; + ExprVector CubicGetStartTangentExprs() const; + ExprVector CubicGetFinishTangentExprs() const; + Vector CubicGetStartTangentNum() const; + Vector CubicGetFinishTangentNum() const; + + bool HasEndpoints() const; + Vector EndpointStart() const; + Vector EndpointFinish() const; + bool IsInPlane(Vector norm, double distance) const; + + void RectGetPointsExprs(ExprVector *eap, ExprVector *ebp) const; + + void AddEq(IdList *l, Expr *expr, int index) const; + void GenerateEquations(IdList *l) const; + + void Clear() {} +}; + +class Entity : public EntityBase { +public: + // Necessary for Entity e = {} to zero-initialize, since + // classes with base classes are not aggregates and + // the default constructor does not initialize members. + // + // Note EntityBase({}); without explicitly value-initializing + // the base class, MSVC2013 will default-initialize it, leaving + // POD members with indeterminate value. + Entity() : EntityBase({}), forceHidden(), actPoint(), actNormal(), + actDistance(), actVisible(), style(), construction(), + beziers(), edges(), edgesChordTol(), screenBBox(), screenBBoxValid() {}; + + // A linked entity that was hidden in the source file ends up hidden + // here too. + bool forceHidden; + + // All points/normals/distances have their numerical value; this is + // a convenience, to simplify the link/assembly code, so that the + // part is entirely described by the entities. + Vector actPoint; + Quaternion actNormal; + double actDistance; + // and the shown state also gets saved here, for later import + bool actVisible; + + hStyle style; + bool construction; + + SBezierList beziers; + SEdgeList edges; + double edgesChordTol; + BBox screenBBox; + bool screenBBoxValid; + + bool IsStylable() const; + bool IsVisible() const; + bool CanBeDragged() const; + + enum class DrawAs { DEFAULT, OVERLAY, HIDDEN, HOVERED, SELECTED }; + void Draw(DrawAs how, Canvas *canvas); + void GetReferencePoints(std::vector *refs); + int GetPositionOfPoint(const Camera &camera, Point2d p); + + void ComputeInterpolatingSpline(SBezierList *sbl, bool periodic) const; + void GenerateBezierCurves(SBezierList *sbl) const; + void GenerateEdges(SEdgeList *el); + + SBezierList *GetOrGenerateBezierCurves(); + SEdgeList *GetOrGenerateEdges(); + BBox GetOrGenerateScreenBBox(bool *hasBBox); + + void CalculateNumerical(bool forExport); + + std::string DescriptionString() const; + + void Clear() { + beziers.l.Clear(); + edges.l.Clear(); + } +}; + +class EntReqTable { +public: + static bool GetRequestInfo(Request::Type req, int extraPoints, + EntityBase::Type *ent, int *pts, bool *hasNormal, bool *hasDistance); + static bool GetEntityInfo(EntityBase::Type ent, int extraPoints, + Request::Type *req, int *pts, bool *hasNormal, bool *hasDistance); + static Request::Type GetRequestForEntity(EntityBase::Type ent); +}; + +class Param { +public: + int tag; + hParam h; + + double val; + bool known; + bool free; + + // Used only in the solver + hParam substd; + + static const hParam NO_PARAM; + + void Clear() {} +}; + + +class hConstraint { +public: + uint32_t v; + + inline hEquation equation(int i) const; + inline hParam param(int i) const; +}; + +template<> +struct IsHandleOracle : std::true_type {}; + +class ConstraintBase { +public: + int tag; + hConstraint h; + + static const hConstraint NO_CONSTRAINT; + + enum class Type : uint32_t { + POINTS_COINCIDENT = 20, + PT_PT_DISTANCE = 30, + PT_PLANE_DISTANCE = 31, + PT_LINE_DISTANCE = 32, + PT_FACE_DISTANCE = 33, + PROJ_PT_DISTANCE = 34, + PT_IN_PLANE = 41, + PT_ON_LINE = 42, + PT_ON_FACE = 43, + EQUAL_LENGTH_LINES = 50, + LENGTH_RATIO = 51, + EQ_LEN_PT_LINE_D = 52, + EQ_PT_LN_DISTANCES = 53, + EQUAL_ANGLE = 54, + EQUAL_LINE_ARC_LEN = 55, + LENGTH_DIFFERENCE = 56, + SYMMETRIC = 60, + SYMMETRIC_HORIZ = 61, + SYMMETRIC_VERT = 62, + SYMMETRIC_LINE = 63, + AT_MIDPOINT = 70, + HORIZONTAL = 80, + VERTICAL = 81, + DIAMETER = 90, + PT_ON_CIRCLE = 100, + SAME_ORIENTATION = 110, + ANGLE = 120, + PARALLEL = 121, + PERPENDICULAR = 122, + ARC_LINE_TANGENT = 123, + CUBIC_LINE_TANGENT = 124, + CURVE_CURVE_TANGENT = 125, + EQUAL_RADIUS = 130, + WHERE_DRAGGED = 200, + + COMMENT = 1000 + }; + + Type type; + + hGroup group; + hEntity workplane; + + // These are the parameters for the constraint. + double valA; + hParam valP; + hEntity ptA; + hEntity ptB; + hEntity entityA; + hEntity entityB; + hEntity entityC; + hEntity entityD; + bool other; + bool other2; + + bool reference; // a ref dimension, that generates no eqs + std::string comment; // since comments are represented as constraints + + bool Equals(const ConstraintBase &c) const { + return type == c.type && group == c.group && workplane == c.workplane && + valA == c.valA && valP == c.valP && ptA == c.ptA && ptB == c.ptB && + entityA == c.entityA && entityB == c.entityB && + entityC == c.entityC && entityD == c.entityD && + other == c.other && other2 == c.other2 && reference == c.reference && + comment == c.comment; + } + + bool HasLabel() const; + bool IsProjectible() const; + + void Generate(IdList *param); + + void GenerateEquations(IdList *entity, + bool forReference = false) const; + // Some helpers when generating symbolic constraint equations + void ModifyToSatisfy(); + void AddEq(IdList *l, Expr *expr, int index) const; + void AddEq(IdList *l, const ExprVector &v, int baseIndex = 0) const; + static Expr *DirectionCosine(hEntity wrkpl, ExprVector ae, ExprVector be); + static Expr *Distance(hEntity workplane, hEntity pa, hEntity pb); + static Expr *PointLineDistance(hEntity workplane, hEntity pt, hEntity ln); + static Expr *PointPlaneDistance(ExprVector p, hEntity plane); + static ExprVector VectorsParallel3d(ExprVector a, ExprVector b, hParam p); + static ExprVector PointInThreeSpace(hEntity workplane, Expr *u, Expr *v); + + void Clear() {} +}; + +class Constraint : public ConstraintBase { +public: + // See Entity::Entity(). + Constraint() : ConstraintBase({}), disp() {} + + // These define how the constraint is drawn on-screen. + struct { + Vector offset; + hStyle style; + } disp; + + bool IsVisible() const; + bool IsStylable() const; + hStyle GetStyle() const; + bool HasLabel() const; + std::string Label() const; + + enum class DrawAs { DEFAULT, HOVERED, SELECTED }; + void Draw(DrawAs how, Canvas *canvas); + Vector GetLabelPos(const Camera &camera); + void GetReferencePoints(const Camera &camera, std::vector *refs); + + void DoLayout(DrawAs how, Canvas *canvas, + Vector *labelPos, std::vector *refs); + void DoLine(Canvas *canvas, Canvas::hStroke hcs, Vector a, Vector b); + void DoStippledLine(Canvas *canvas, Canvas::hStroke hcs, Vector a, Vector b); + bool DoLineExtend(Canvas *canvas, Canvas::hStroke hcs, + Vector p0, Vector p1, Vector pt, double salient); + void DoArcForAngle(Canvas *canvas, Canvas::hStroke hcs, + Vector a0, Vector da, Vector b0, Vector db, + Vector offset, Vector *ref, bool trim); + void DoArrow(Canvas *canvas, Canvas::hStroke hcs, + Vector p, Vector dir, Vector n, double width, double angle, double da); + void DoLineWithArrows(Canvas *canvas, Canvas::hStroke hcs, + Vector ref, Vector a, Vector b, bool onlyOneExt); + int DoLineTrimmedAgainstBox(Canvas *canvas, Canvas::hStroke hcs, + Vector ref, Vector a, Vector b, bool extend, + Vector gr, Vector gu, double swidth, double sheight); + int DoLineTrimmedAgainstBox(Canvas *canvas, Canvas::hStroke hcs, + Vector ref, Vector a, Vector b, bool extend = true); + void DoLabel(Canvas *canvas, Canvas::hStroke hcs, + Vector ref, Vector *labelPos, Vector gr, Vector gu); + void DoProjectedPoint(Canvas *canvas, Canvas::hStroke hcs, Vector *p); + void DoProjectedPoint(Canvas *canvas, Canvas::hStroke hcs, Vector *p, Vector n, Vector o); + + void DoEqualLenTicks(Canvas *canvas, Canvas::hStroke hcs, + Vector a, Vector b, Vector gn, Vector *refp); + void DoEqualRadiusTicks(Canvas *canvas, Canvas::hStroke hcs, + hEntity he, Vector *refp); + + std::string DescriptionString() const; + + static hConstraint AddConstraint(Constraint *c, bool rememberForUndo = true); + static void MenuConstrain(Command id); + static void DeleteAllConstraintsFor(Constraint::Type type, hEntity entityA, hEntity ptA); + + static hConstraint ConstrainCoincident(hEntity ptA, hEntity ptB); + static hConstraint Constrain(Constraint::Type type, hEntity ptA, hEntity ptB, hEntity entityA, + hEntity entityB = Entity::NO_ENTITY, bool other = false, + bool other2 = false); + static hConstraint TryConstrain(Constraint::Type type, hEntity ptA, hEntity ptB, + hEntity entityA, hEntity entityB = Entity::NO_ENTITY, + bool other = false, bool other2 = false); + static void ConstrainArcLineTangent(Constraint *c, Entity *line, Entity *arc); + static void ConstrainCubicLineTangent(Constraint *c, Entity *line, Entity *cubic); + static void ConstrainCurveCurveTangent(Constraint *c, Entity *eA, Entity *eB); +}; + +class hEquation { +public: + uint32_t v; + + inline bool isFromConstraint() const; + inline hConstraint constraint() const; +}; + +template<> +struct IsHandleOracle : std::true_type {}; + +class Equation { +public: + int tag; + hEquation h; + + Expr *e; + + void Clear() {} +}; + + +class Style { +public: + int tag; + hStyle h; + + enum { + // If an entity has no style, then it will be colored according to + // whether the group that it's in is active or not, whether it's + // construction or not, and so on. + NO_STYLE = 0, + + ACTIVE_GRP = 1, + CONSTRUCTION = 2, + INACTIVE_GRP = 3, + DATUM = 4, + SOLID_EDGE = 5, + CONSTRAINT = 6, + SELECTED = 7, + HOVERED = 8, + CONTOUR_FILL = 9, + NORMALS = 10, + ANALYZE = 11, + DRAW_ERROR = 12, + DIM_SOLID = 13, + HIDDEN_EDGE = 14, + OUTLINE = 15, + + FIRST_CUSTOM = 0x100 + }; + + std::string name; + + enum class UnitsAs : uint32_t { + PIXELS = 0, + MM = 1 + }; + double width; + UnitsAs widthAs; + double textHeight; + UnitsAs textHeightAs; + enum class TextOrigin : uint32_t { + NONE = 0x00, + LEFT = 0x01, + RIGHT = 0x02, + BOT = 0x04, + TOP = 0x08 + }; + TextOrigin textOrigin; + double textAngle; + RgbaColor color; + bool filled; + RgbaColor fillColor; + bool visible; + bool exportable; + StipplePattern stippleType; + double stippleScale; + int zIndex; + + // The default styles, for entities that don't have a style assigned yet, + // and for datums and such. + typedef struct { + hStyle h; + const char *cnfPrefix; + RgbaColor color; + double width; + int zIndex; + } Default; + static const Default Defaults[]; + + static std::string CnfColor(const std::string &prefix); + static std::string CnfWidth(const std::string &prefix); + static std::string CnfTextHeight(const std::string &prefix); + static std::string CnfPrefixToName(const std::string &prefix); + + static void CreateAllDefaultStyles(); + static void CreateDefaultStyle(hStyle h); + static void FillDefaultStyle(Style *s, const Default *d = NULL, bool factory = false); + static void FreezeDefaultStyles(Platform::SettingsRef settings); + static void LoadFactoryDefaults(); + + static void AssignSelectionToStyle(uint32_t v); + static uint32_t CreateCustomStyle(bool rememberForUndo = true); + + static RgbaColor RewriteColor(RgbaColor rgb); + + static Style *Get(hStyle hs); + static RgbaColor Color(hStyle hs, bool forExport=false); + static RgbaColor Color(int hs, bool forExport=false); + static RgbaColor FillColor(hStyle hs, bool forExport=false); + static double Width(hStyle hs); + static double Width(int hs); + static double WidthMm(int hs); + static double TextHeight(hStyle hs); + static double DefaultTextHeight(); + static Canvas::Stroke Stroke(hStyle hs); + static Canvas::Stroke Stroke(int hs); + static bool Exportable(int hs); + static hStyle ForEntity(hEntity he); + static StipplePattern PatternType(hStyle hs); + static double StippleScaleMm(hStyle hs); + + std::string DescriptionString() const; + + void Clear() {} +}; + + +inline hEntity hGroup::entity(int i) const + { hEntity r; r.v = 0x80000000 | (v << 16) | (uint32_t)i; return r; } +inline hParam hGroup::param(int i) const + { hParam r; r.v = 0x80000000 | (v << 16) | (uint32_t)i; return r; } +inline hEquation hGroup::equation(int i) const + { hEquation r; r.v = (v << 16) | 0x80000000 | (uint32_t)i; return r; } + +inline bool hRequest::IsFromReferences() const { + if(*this == Request::HREQUEST_REFERENCE_XY) return true; + if(*this == Request::HREQUEST_REFERENCE_YZ) return true; + if(*this == Request::HREQUEST_REFERENCE_ZX) return true; + return false; +} +inline hEntity hRequest::entity(int i) const + { hEntity r; r.v = (v << 16) | (uint32_t)i; return r; } +inline hParam hRequest::param(int i) const + { hParam r; r.v = (v << 16) | (uint32_t)i; return r; } + +inline bool hEntity::isFromRequest() const + { if(v & 0x80000000) return false; else return true; } +inline hRequest hEntity::request() const + { hRequest r; r.v = (v >> 16); return r; } +inline hGroup hEntity::group() const + { hGroup r; r.v = (v >> 16) & 0x3fff; return r; } +inline hEquation hEntity::equation(int i) const + { hEquation r; r.v = v | 0x40000000 | (uint32_t)i; return r; } + +inline hRequest hParam::request() const + { hRequest r; r.v = (v >> 16); return r; } + + +inline hEquation hConstraint::equation(int i) const + { hEquation r; r.v = (v << 16) | (uint32_t)i; return r; } +inline hParam hConstraint::param(int i) const + { hParam r; r.v = v | 0x40000000 | (uint32_t)i; return r; } + +inline bool hEquation::isFromConstraint() const + { if(v & 0xc0000000) return false; else return true; } +inline hConstraint hEquation::constraint() const + { hConstraint r; r.v = (v >> 16); return r; } + +// The format for entities stored on the clipboard. +class ClipboardRequest { +public: + Request::Type type; + int extraPoints; + hStyle style; + std::string str; + std::string font; + Platform::Path file; + bool construction; + + Vector point[MAX_POINTS_IN_ENTITY]; + double distance; + + hEntity oldEnt; + hEntity oldPointEnt[MAX_POINTS_IN_ENTITY]; + hRequest newReq; +}; + +#endif diff --git a/src/solvespace.cpp b/src/solvespace.cpp new file mode 100644 index 0000000..4e458cf --- /dev/null +++ b/src/solvespace.cpp @@ -0,0 +1,1118 @@ +//----------------------------------------------------------------------------- +// Entry point in to the program, our registry-stored settings and top-level +// housekeeping when we open, save, and create new files. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" +#include "config.h" + +SolveSpaceUI SolveSpace::SS = {}; +Sketch SolveSpace::SK = {}; + +void SolveSpaceUI::Init() { +#if !defined(HEADLESS) + // Check that the resource system works. + dbp("%s", LoadString("banner.txt").data()); +#endif + + Platform::SettingsRef settings = Platform::GetSettings(); + + SS.tangentArcRadius = 10.0; + + // Then, load the registry settings. + // Default list of colors for the model material + modelColor[0] = settings->ThawColor("ModelColor_0", RGBi(150, 150, 150)); + modelColor[1] = settings->ThawColor("ModelColor_1", RGBi(100, 100, 100)); + modelColor[2] = settings->ThawColor("ModelColor_2", RGBi( 30, 30, 30)); + modelColor[3] = settings->ThawColor("ModelColor_3", RGBi(150, 0, 0)); + modelColor[4] = settings->ThawColor("ModelColor_4", RGBi( 0, 100, 0)); + modelColor[5] = settings->ThawColor("ModelColor_5", RGBi( 0, 80, 80)); + modelColor[6] = settings->ThawColor("ModelColor_6", RGBi( 0, 0, 130)); + modelColor[7] = settings->ThawColor("ModelColor_7", RGBi( 80, 0, 80)); + // Light intensities + lightIntensity[0] = settings->ThawFloat("LightIntensity_0", 1.0); + lightIntensity[1] = settings->ThawFloat("LightIntensity_1", 0.5); + ambientIntensity = settings->ThawFloat("Light_Ambient", 0.3); + // Light positions + lightDir[0].x = settings->ThawFloat("LightDir_0_Right", -1.0); + lightDir[0].y = settings->ThawFloat("LightDir_0_Up", 1.0); + lightDir[0].z = settings->ThawFloat("LightDir_0_Forward", 0.0); + lightDir[1].x = settings->ThawFloat("LightDir_1_Right", 1.0); + lightDir[1].y = settings->ThawFloat("LightDir_1_Up", 0.0); + lightDir[1].z = settings->ThawFloat("LightDir_1_Forward", 0.0); + + exportMode = false; + // Chord tolerance + chordTol = settings->ThawFloat("ChordTolerancePct", 0.1); + // Max pwl segments to generate + maxSegments = settings->ThawInt("MaxSegments", 20); + // Chord tolerance + exportChordTol = settings->ThawFloat("ExportChordTolerance", 0.1); + // Max pwl segments to generate + exportMaxSegments = settings->ThawInt("ExportMaxSegments", 64); + // Timeout value for finding redundant constrains (ms) + timeoutRedundantConstr = settings->ThawInt("TimeoutRedundantConstraints", 1000); + // View units + viewUnits = (Unit)settings->ThawInt("ViewUnits", (uint32_t)Unit::MM); + // Number of digits after the decimal point + afterDecimalMm = settings->ThawInt("AfterDecimalMm", 2); + afterDecimalInch = settings->ThawInt("AfterDecimalInch", 3); + afterDecimalDegree = settings->ThawInt("AfterDecimalDegree", 2); + useSIPrefixes = settings->ThawBool("UseSIPrefixes", false); + // Camera tangent (determines perspective) + cameraTangent = settings->ThawFloat("CameraTangent", 0.3f/1e3); + // Grid spacing + gridSpacing = settings->ThawFloat("GridSpacing", 5.0); + // Export scale factor + exportScale = settings->ThawFloat("ExportScale", 1.0); + // Export offset (cutter radius comp) + exportOffset = settings->ThawFloat("ExportOffset", 0.0); + // Rewrite exported colors close to white into black (assuming white bg) + fixExportColors = settings->ThawBool("FixExportColors", true); + // Export background color + exportBackgroundColor = settings->ThawBool("ExportBackgroundColor", false); + // Draw back faces of triangles (when mesh is leaky/self-intersecting) + drawBackFaces = settings->ThawBool("DrawBackFaces", true); + // Use turntable mouse navigation + turntableNav = settings->ThawBool("TurntableNav", false); + // Immediately edit dimension + immediatelyEditDimension = settings->ThawBool("ImmediatelyEditDimension", true); + // Check that contours are closed and not self-intersecting + checkClosedContour = settings->ThawBool("CheckClosedContour", true); + // Enable automatic constrains for lines + automaticLineConstraints = settings->ThawBool("AutomaticLineConstraints", true); + // Draw closed polygons areas + showContourAreas = settings->ThawBool("ShowContourAreas", false); + // Export shaded triangles in a 2d view + exportShadedTriangles = settings->ThawBool("ExportShadedTriangles", true); + // Export pwl curves (instead of exact) always + exportPwlCurves = settings->ThawBool("ExportPwlCurves", false); + // Background color on-screen + backgroundColor = settings->ThawColor("BackgroundColor", RGBi(0, 0, 0)); + // Whether export canvas size is fixed or derived from bbox + exportCanvasSizeAuto = settings->ThawBool("ExportCanvasSizeAuto", true); + // Margins for automatic canvas size + exportMargin.left = settings->ThawFloat("ExportMargin_Left", 5.0); + exportMargin.right = settings->ThawFloat("ExportMargin_Right", 5.0); + exportMargin.bottom = settings->ThawFloat("ExportMargin_Bottom", 5.0); + exportMargin.top = settings->ThawFloat("ExportMargin_Top", 5.0); + // Dimensions for fixed canvas size + exportCanvas.width = settings->ThawFloat("ExportCanvas_Width", 100.0); + exportCanvas.height = settings->ThawFloat("ExportCanvas_Height", 100.0); + exportCanvas.dx = settings->ThawFloat("ExportCanvas_Dx", 5.0); + exportCanvas.dy = settings->ThawFloat("ExportCanvas_Dy", 5.0); + // Extra parameters when exporting G code + gCode.depth = settings->ThawFloat("GCode_Depth", 10.0); + gCode.passes = settings->ThawInt("GCode_Passes", 1); + gCode.feed = settings->ThawFloat("GCode_Feed", 10.0); + gCode.plungeFeed = settings->ThawFloat("GCode_PlungeFeed", 10.0); + // Show toolbar in the graphics window + showToolbar = settings->ThawBool("ShowToolbar", true); + // Recent files menus + for(size_t i = 0; i < MAX_RECENT; i++) { + std::string rawPath = settings->ThawString("RecentFile_" + std::to_string(i), ""); + if(rawPath.empty()) continue; + recentFiles.push_back(Platform::Path::From(rawPath)); + } + // Autosave timer + autosaveInterval = settings->ThawInt("AutosaveInterval", 5); + // Locale + std::string locale = settings->ThawString("Locale", ""); + if(!locale.empty()) { + SetLocale(locale); + } + + generateAllTimer = Platform::CreateTimer(); + generateAllTimer->onTimeout = std::bind(&SolveSpaceUI::GenerateAll, &SS, Generate::DIRTY, + /*andFindFree=*/false, /*genForBBox=*/false); + + showTWTimer = Platform::CreateTimer(); + showTWTimer->onTimeout = std::bind(&TextWindow::Show, &TW); + + autosaveTimer = Platform::CreateTimer(); + autosaveTimer->onTimeout = std::bind(&SolveSpaceUI::Autosave, &SS); + + // The default styles (colors, line widths, etc.) are also stored in the + // configuration file, but we will automatically load those as we need + // them. + + ScheduleAutosave(); + + NewFile(); + AfterNewFile(); + + if(TW.window && GW.window) { + TW.window->ThawPosition(settings, "TextWindow"); + GW.window->ThawPosition(settings, "GraphicsWindow"); + TW.window->SetVisible(true); + GW.window->SetVisible(true); + GW.window->Focus(); + + // Do this once the window is created. + Request3DConnexionEventsForWindow(GW.window); + } +} + +bool SolveSpaceUI::LoadAutosaveFor(const Platform::Path &filename) { + Platform::Path autosaveFile = filename.WithExtension(BACKUP_EXT); + + FILE *f = OpenFile(autosaveFile, "rb"); + if(!f) + return false; + fclose(f); + + Platform::MessageDialogRef dialog = CreateMessageDialog(GW.window); + + using Platform::MessageDialog; + dialog->SetType(MessageDialog::Type::QUESTION); + dialog->SetTitle(C_("title", "Autosave Available")); + dialog->SetMessage(C_("dialog", "An autosave file is available for this sketch.")); + dialog->SetDescription(C_("dialog", "Do you want to load the autosave file instead?")); + dialog->AddButton(C_("button", "&Load autosave"), MessageDialog::Response::YES, + /*isDefault=*/true); + dialog->AddButton(C_("button", "Do&n't Load"), MessageDialog::Response::NO); + + // FIXME(async): asyncify this call + if(dialog->RunModal() == MessageDialog::Response::YES) { + unsaved = true; + return LoadFromFile(autosaveFile, /*canCancel=*/true); + } + + return false; +} + +bool SolveSpaceUI::Load(const Platform::Path &filename) { + bool autosaveLoaded = LoadAutosaveFor(filename); + bool fileLoaded = autosaveLoaded || LoadFromFile(filename, /*canCancel=*/true); + if(fileLoaded) { + saveFile = filename; + AddToRecentList(filename); + } else { + saveFile.Clear(); + NewFile(); + } + AfterNewFile(); + unsaved = autosaveLoaded; + return fileLoaded; +} + +void SolveSpaceUI::Exit() { + Platform::SettingsRef settings = Platform::GetSettings(); + + GW.window->FreezePosition(settings, "GraphicsWindow"); + TW.window->FreezePosition(settings, "TextWindow"); + + // Recent files + for(size_t i = 0; i < MAX_RECENT; i++) { + std::string rawPath; + if(recentFiles.size() > i) { + rawPath = recentFiles[i].raw; + } + settings->FreezeString("RecentFile_" + std::to_string(i), rawPath); + } + // Model colors + for(size_t i = 0; i < MODEL_COLORS; i++) + settings->FreezeColor("ModelColor_" + std::to_string(i), modelColor[i]); + // Light intensities + settings->FreezeFloat("LightIntensity_0", (float)lightIntensity[0]); + settings->FreezeFloat("LightIntensity_1", (float)lightIntensity[1]); + settings->FreezeFloat("Light_Ambient", (float)ambientIntensity); + // Light directions + settings->FreezeFloat("LightDir_0_Right", (float)lightDir[0].x); + settings->FreezeFloat("LightDir_0_Up", (float)lightDir[0].y); + settings->FreezeFloat("LightDir_0_Forward", (float)lightDir[0].z); + settings->FreezeFloat("LightDir_1_Right", (float)lightDir[1].x); + settings->FreezeFloat("LightDir_1_Up", (float)lightDir[1].y); + settings->FreezeFloat("LightDir_1_Forward", (float)lightDir[1].z); + // Chord tolerance + settings->FreezeFloat("ChordTolerancePct", (float)chordTol); + // Max pwl segments to generate + settings->FreezeInt("MaxSegments", (uint32_t)maxSegments); + // Export Chord tolerance + settings->FreezeFloat("ExportChordTolerance", (float)exportChordTol); + // Export Max pwl segments to generate + settings->FreezeInt("ExportMaxSegments", (uint32_t)exportMaxSegments); + // Timeout for finding which constraints to fix Jacobian + settings->FreezeInt("TimeoutRedundantConstraints", (uint32_t)timeoutRedundantConstr); + // View units + settings->FreezeInt("ViewUnits", (uint32_t)viewUnits); + // Number of digits after the decimal point + settings->FreezeInt("AfterDecimalMm", (uint32_t)afterDecimalMm); + settings->FreezeInt("AfterDecimalInch", (uint32_t)afterDecimalInch); + settings->FreezeInt("AfterDecimalDegree", (uint32_t)afterDecimalDegree); + settings->FreezeBool("UseSIPrefixes", useSIPrefixes); + // Camera tangent (determines perspective) + settings->FreezeFloat("CameraTangent", (float)cameraTangent); + // Grid spacing + settings->FreezeFloat("GridSpacing", gridSpacing); + // Export scale + settings->FreezeFloat("ExportScale", exportScale); + // Export offset (cutter radius comp) + settings->FreezeFloat("ExportOffset", exportOffset); + // Rewrite exported colors close to white into black (assuming white bg) + settings->FreezeBool("FixExportColors", fixExportColors); + // Export background color + settings->FreezeBool("ExportBackgroundColor", exportBackgroundColor); + // Draw back faces of triangles (when mesh is leaky/self-intersecting) + settings->FreezeBool("DrawBackFaces", drawBackFaces); + // Draw closed polygons areas + settings->FreezeBool("ShowContourAreas", showContourAreas); + // Check that contours are closed and not self-intersecting + settings->FreezeBool("CheckClosedContour", checkClosedContour); + // Use turntable mouse navigation + settings->FreezeBool("TurntableNav", turntableNav); + // Immediately edit dimensions + settings->FreezeBool("ImmediatelyEditDimension", immediatelyEditDimension); + // Enable automatic constrains for lines + settings->FreezeBool("AutomaticLineConstraints", automaticLineConstraints); + // Export shaded triangles in a 2d view + settings->FreezeBool("ExportShadedTriangles", exportShadedTriangles); + // Export pwl curves (instead of exact) always + settings->FreezeBool("ExportPwlCurves", exportPwlCurves); + // Background color on-screen + settings->FreezeColor("BackgroundColor", backgroundColor); + // Whether export canvas size is fixed or derived from bbox + settings->FreezeBool("ExportCanvasSizeAuto", exportCanvasSizeAuto); + // Margins for automatic canvas size + settings->FreezeFloat("ExportMargin_Left", exportMargin.left); + settings->FreezeFloat("ExportMargin_Right", exportMargin.right); + settings->FreezeFloat("ExportMargin_Bottom", exportMargin.bottom); + settings->FreezeFloat("ExportMargin_Top", exportMargin.top); + // Dimensions for fixed canvas size + settings->FreezeFloat("ExportCanvas_Width", exportCanvas.width); + settings->FreezeFloat("ExportCanvas_Height", exportCanvas.height); + settings->FreezeFloat("ExportCanvas_Dx", exportCanvas.dx); + settings->FreezeFloat("ExportCanvas_Dy", exportCanvas.dy); + // Extra parameters when exporting G code + settings->FreezeFloat("GCode_Depth", gCode.depth); + settings->FreezeInt("GCode_Passes", gCode.passes); + settings->FreezeFloat("GCode_Feed", gCode.feed); + settings->FreezeFloat("GCode_PlungeFeed", gCode.plungeFeed); + // Show toolbar in the graphics window + settings->FreezeBool("ShowToolbar", showToolbar); + // Autosave timer + settings->FreezeInt("AutosaveInterval", autosaveInterval); + + // And the default styles, colors and line widths and such. + Style::FreezeDefaultStyles(settings); + + Platform::ExitGui(); +} + +void SolveSpaceUI::ScheduleGenerateAll() { + generateAllTimer->RunAfterProcessingEvents(); +} + +void SolveSpaceUI::ScheduleShowTW() { + showTWTimer->RunAfterProcessingEvents(); +} + +void SolveSpaceUI::ScheduleAutosave() { + autosaveTimer->RunAfter(autosaveInterval * 60 * 1000); +} + +double SolveSpaceUI::MmPerUnit() { + switch(viewUnits) { + case Unit::INCHES: return 25.4; + case Unit::METERS: return 1000.0; + case Unit::MM: return 1.0; + } + return 1.0; +} +const char *SolveSpaceUI::UnitName() { + switch(viewUnits) { + case Unit::INCHES: return "in"; + case Unit::METERS: return "m"; + case Unit::MM: return "mm"; + } + return ""; +} + +std::string SolveSpaceUI::MmToString(double v) { + v /= MmPerUnit(); + int digits = UnitDigitsAfterDecimal(); + double minimum = 0.5 * pow(10,-digits); + while ((v < minimum) && (v > LENGTH_EPS)) { + digits++; + minimum *= 0.1; + } + return ssprintf("%.*f", digits, v); +} +static const char *DimToString(int dim) { + switch(dim) { + case 3: return "³"; + case 2: return "²"; + case 1: return ""; + default: ssassert(false, "Unexpected dimension"); + } +} +static std::pair SelectSIPrefixMm(int ord, int dim) { +// decide what units to use depending on the order of magnitude of the +// measure in meters and the dimmension (1,2,3 lenear, area, volume) + switch(dim) { + case 0: + case 1: + if(ord >= 3) return { 3, "km" }; + else if(ord >= 0) return { 0, "m" }; + else if(ord >= -2) return { -2, "cm" }; + else if(ord >= -3) return { -3, "mm" }; + else if(ord >= -6) return { -6, "µm" }; + else return { -9, "nm" }; + break; + case 2: + if(ord >= 5) return { 3, "km" }; + else if(ord >= 0) return { 0, "m" }; + else if(ord >= -2) return { -2, "cm" }; + else if(ord >= -6) return { -3, "mm" }; + else if(ord >= -13) return { -6, "µm" }; + else return { -9, "nm" }; + break; + case 3: + if(ord >= 7) return { 3, "km" }; + else if(ord >= 0) return { 0, "m" }; + else if(ord >= -5) return { -2, "cm" }; + else if(ord >= -11) return { -3, "mm" }; + else return { -6, "µm" }; + break; + default: + dbp ("dimensions over 3 not supported"); + break; + } + return {0, "m"}; +} +static std::pair SelectSIPrefixInch(int deg) { + if(deg >= 0) return { 0, "in" }; + else if(deg >= -3) return { -3, "mil" }; + else return { -6, "µin" }; +} +std::string SolveSpaceUI::MmToStringSI(double v, int dim) { + bool compact = false; + if(dim == 0) { + if(!useSIPrefixes) return MmToString(v); + compact = true; + dim = 1; + } + + v /= pow((viewUnits == Unit::INCHES) ? 25.4 : 1000, dim); + int vdeg = (int)(log10(fabs(v))); + std::string unit; + if(fabs(v) > 0.0) { + int sdeg = 0; + std::tie(sdeg, unit) = + (viewUnits == Unit::INCHES) + ? SelectSIPrefixInch(vdeg/dim) + : SelectSIPrefixMm(vdeg, dim); + v /= pow(10.0, sdeg * dim); + } + int pdeg = (int)ceil(log10(fabs(v) + 1e-10)); + return ssprintf("%.*g%s%s%s", pdeg + UnitDigitsAfterDecimal(), v, + compact ? "" : " ", unit.c_str(), DimToString(dim)); +} +std::string SolveSpaceUI::DegreeToString(double v) { + if(fabs(v - floor(v)) > 1e-10) { + return ssprintf("%.*f", afterDecimalDegree, v); + } else { + return ssprintf("%.0f", v); + } +} +double SolveSpaceUI::ExprToMm(Expr *e) { + return (e->Eval()) * MmPerUnit(); +} +double SolveSpaceUI::StringToMm(const std::string &str) { + return std::stod(str) * MmPerUnit(); +} +double SolveSpaceUI::ChordTolMm() { + if(exportMode) return ExportChordTolMm(); + return chordTolCalculated; +} +double SolveSpaceUI::ExportChordTolMm() { + return exportChordTol / exportScale; +} +int SolveSpaceUI::GetMaxSegments() { + if(exportMode) return exportMaxSegments; + return maxSegments; +} +int SolveSpaceUI::UnitDigitsAfterDecimal() { + return (viewUnits == Unit::INCHES) ? afterDecimalInch : afterDecimalMm; +} +void SolveSpaceUI::SetUnitDigitsAfterDecimal(int v) { + if(viewUnits == Unit::INCHES) { + afterDecimalInch = v; + } else { + afterDecimalMm = v; + } +} + +double SolveSpaceUI::CameraTangent() { + if(!usePerspectiveProj) { + return 0; + } else { + return cameraTangent; + } +} + +void SolveSpaceUI::AfterNewFile() { + // Clear out the traced point, which is no longer valid + traced.point = Entity::NO_ENTITY; + traced.path.l.Clear(); + // and the naked edges + nakedEdges.Clear(); + + // Quit export mode + justExportedInfo.draw = false; + centerOfMass.draw = false; + exportMode = false; + + // GenerateAll() expects the view to be valid, because it uses that to + // fill in default values for extrusion depths etc. (which won't matter + // here, but just don't let it work on garbage) + SS.GW.offset = Vector::From(0, 0, 0); + SS.GW.projRight = Vector::From(1, 0, 0); + SS.GW.projUp = Vector::From(0, 1, 0); + + GenerateAll(Generate::ALL); + + GW.Init(); + TW.Init(); + + unsaved = false; + + GW.ZoomToFit(); + + // Create all the default styles; they'll get created on the fly anyways, + // but can't hurt to do it now. + Style::CreateAllDefaultStyles(); + + UpdateWindowTitles(); +} + +void SolveSpaceUI::AddToRecentList(const Platform::Path &filename) { + auto it = std::find_if(recentFiles.begin(), recentFiles.end(), + [&](const Platform::Path &p) { return p.Equals(filename); }); + if(it != recentFiles.end()) { + recentFiles.erase(it); + } + + if(recentFiles.size() > MAX_RECENT) { + recentFiles.erase(recentFiles.begin() + MAX_RECENT); + } + + recentFiles.insert(recentFiles.begin(), filename); + GW.PopulateRecentFiles(); +} + +bool SolveSpaceUI::GetFilenameAndSave(bool saveAs) { + Platform::SettingsRef settings = Platform::GetSettings(); + Platform::Path newSaveFile = saveFile; + + if(saveAs || saveFile.IsEmpty()) { + Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(GW.window); + dialog->AddFilter(C_("file-type", "SolveSpace models"), { SKETCH_EXT }); + dialog->ThawChoices(settings, "Sketch"); + if(!newSaveFile.IsEmpty()) { + dialog->SetFilename(newSaveFile); + } + if(dialog->RunModal()) { + dialog->FreezeChoices(settings, "Sketch"); + newSaveFile = dialog->GetFilename(); + } else { + return false; + } + } + + if(SaveToFile(newSaveFile)) { + AddToRecentList(newSaveFile); + RemoveAutosave(); + saveFile = newSaveFile; + unsaved = false; + return true; + } else { + return false; + } +} + +void SolveSpaceUI::Autosave() +{ + ScheduleAutosave(); + + if(!saveFile.IsEmpty() && unsaved) { + SaveToFile(saveFile.WithExtension(BACKUP_EXT)); + } +} + +void SolveSpaceUI::RemoveAutosave() +{ + Platform::Path autosaveFile = saveFile.WithExtension(BACKUP_EXT); + RemoveFile(autosaveFile); +} + +bool SolveSpaceUI::OkayToStartNewFile() { + if(!unsaved) return true; + + Platform::MessageDialogRef dialog = CreateMessageDialog(GW.window); + + using Platform::MessageDialog; + dialog->SetType(MessageDialog::Type::QUESTION); + dialog->SetTitle(C_("title", "Modified File")); + if(!SolveSpace::SS.saveFile.IsEmpty()) { + dialog->SetMessage(ssprintf(C_("dialog", "Do you want to save the changes you made to " + "the sketch “%s”?"), saveFile.raw.c_str())); + } else { + dialog->SetMessage(C_("dialog", "Do you want to save the changes you made to " + "the new sketch?")); + } + dialog->SetDescription(C_("dialog", "Your changes will be lost if you don't save them.")); + dialog->AddButton(C_("button", "&Save"), MessageDialog::Response::YES, + /*isDefault=*/true); + dialog->AddButton(C_("button", "Do&n't Save"), MessageDialog::Response::NO); + dialog->AddButton(C_("button", "&Cancel"), MessageDialog::Response::CANCEL); + + // FIXME(async): asyncify this call + switch(dialog->RunModal()) { + case MessageDialog::Response::YES: + return GetFilenameAndSave(/*saveAs=*/false); + + case MessageDialog::Response::NO: + RemoveAutosave(); + return true; + + default: + return false; + } +} + +void SolveSpaceUI::UpdateWindowTitles() { + if(!GW.window || !TW.window) return; + + if(saveFile.IsEmpty()) { + GW.window->SetTitle(C_("title", "(new sketch)")); + } else { + if(!GW.window->SetTitleForFilename(saveFile)) { + GW.window->SetTitle(saveFile.raw); + } + } + + TW.window->SetTitle(C_("title", "Property Browser")); +} + +void SolveSpaceUI::MenuFile(Command id) { + Platform::SettingsRef settings = Platform::GetSettings(); + + switch(id) { + case Command::NEW: + if(!SS.OkayToStartNewFile()) break; + + SS.saveFile.Clear(); + SS.NewFile(); + SS.AfterNewFile(); + break; + + case Command::OPEN: { + if(!SS.OkayToStartNewFile()) break; + + Platform::FileDialogRef dialog = Platform::CreateOpenFileDialog(SS.GW.window); + dialog->AddFilters(Platform::SolveSpaceModelFileFilters); + dialog->ThawChoices(settings, "Sketch"); + if(dialog->RunModal()) { + dialog->FreezeChoices(settings, "Sketch"); + SS.Load(dialog->GetFilename()); + } + break; + } + + case Command::SAVE: + SS.GetFilenameAndSave(/*saveAs=*/false); + break; + + case Command::SAVE_AS: + SS.GetFilenameAndSave(/*saveAs=*/true); + break; + + case Command::EXPORT_IMAGE: { + Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); + dialog->AddFilters(Platform::RasterFileFilters); + dialog->ThawChoices(settings, "ExportImage"); + dialog->SuggestFilename(SS.saveFile); + if(dialog->RunModal()) { + dialog->FreezeChoices(settings, "ExportImage"); + SS.ExportAsPngTo(dialog->GetFilename()); + } + break; + } + + case Command::EXPORT_VIEW: { + Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); + dialog->AddFilters(Platform::VectorFileFilters); + dialog->ThawChoices(settings, "ExportView"); + dialog->SuggestFilename(SS.saveFile); + if(!dialog->RunModal()) break; + dialog->FreezeChoices(settings, "ExportView"); + + // If the user is exporting something where it would be + // inappropriate to include the constraints, then warn. + if(SS.GW.showConstraints && + (dialog->GetFilename().HasExtension("txt") || + fabs(SS.exportOffset) > LENGTH_EPS)) + { + Message(_("Constraints are currently shown, and will be exported " + "in the toolpath. This is probably not what you want; " + "hide them by clicking the link at the top of the " + "text window.")); + } + + SS.ExportViewOrWireframeTo(dialog->GetFilename(), /*exportWireframe=*/false); + break; + } + + case Command::EXPORT_WIREFRAME: { + Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); + dialog->AddFilters(Platform::Vector3dFileFilters); + dialog->ThawChoices(settings, "ExportWireframe"); + dialog->SuggestFilename(SS.saveFile); + if(!dialog->RunModal()) break; + dialog->FreezeChoices(settings, "ExportWireframe"); + + SS.ExportViewOrWireframeTo(dialog->GetFilename(), /*exportWireframe*/true); + break; + } + + case Command::EXPORT_SECTION: { + Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); + dialog->AddFilters(Platform::VectorFileFilters); + dialog->ThawChoices(settings, "ExportSection"); + dialog->SuggestFilename(SS.saveFile); + if(!dialog->RunModal()) break; + dialog->FreezeChoices(settings, "ExportSection"); + + SS.ExportSectionTo(dialog->GetFilename()); + break; + } + + case Command::EXPORT_MESH: { + Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); + dialog->AddFilters(Platform::MeshFileFilters); + dialog->ThawChoices(settings, "ExportMesh"); + dialog->SuggestFilename(SS.saveFile); + if(!dialog->RunModal()) break; + dialog->FreezeChoices(settings, "ExportMesh"); + + SS.ExportMeshTo(dialog->GetFilename()); + break; + } + + case Command::EXPORT_SURFACES: { + Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); + dialog->AddFilters(Platform::SurfaceFileFilters); + dialog->ThawChoices(settings, "ExportSurfaces"); + dialog->SuggestFilename(SS.saveFile); + if(!dialog->RunModal()) break; + dialog->FreezeChoices(settings, "ExportSurfaces"); + + StepFileWriter sfw = {}; + sfw.ExportSurfacesTo(dialog->GetFilename()); + break; + } + + case Command::IMPORT: { + Platform::FileDialogRef dialog = Platform::CreateOpenFileDialog(SS.GW.window); + dialog->AddFilters(Platform::ImportFileFilters); + dialog->ThawChoices(settings, "Import"); + if(!dialog->RunModal()) break; + dialog->FreezeChoices(settings, "Import"); + + Platform::Path importFile = dialog->GetFilename(); + if(importFile.HasExtension("dxf")) { + ImportDxf(importFile); + } else if(importFile.HasExtension("dwg")) { + ImportDwg(importFile); + } else { + Error(_("Can't identify file type from file extension of " + "filename '%s'; try .dxf or .dwg."), importFile.raw.c_str()); + break; + } + + SS.GenerateAll(SolveSpaceUI::Generate::UNTIL_ACTIVE); + SS.ScheduleShowTW(); + break; + } + + case Command::EXIT: + if(!SS.OkayToStartNewFile()) break; + SS.Exit(); + break; + + default: ssassert(false, "Unexpected menu ID"); + } + + SS.UpdateWindowTitles(); +} + +void SolveSpaceUI::MenuAnalyze(Command id) { + Platform::SettingsRef settings = Platform::GetSettings(); + + SS.GW.GroupSelection(); + auto const &gs = SS.GW.gs; + + switch(id) { + case Command::STEP_DIM: + if(gs.constraints == 1 && gs.n == 0) { + Constraint *c = SK.GetConstraint(gs.constraint[0]); + if(c->HasLabel() && !c->reference) { + SS.TW.stepDim.finish = c->valA; + SS.TW.stepDim.steps = 10; + SS.TW.stepDim.isDistance = + (c->type != Constraint::Type::ANGLE) && + (c->type != Constraint::Type::LENGTH_RATIO) && + (c->type != Constraint::Type::LENGTH_DIFFERENCE); + SS.TW.shown.constraint = c->h; + SS.TW.shown.screen = TextWindow::Screen::STEP_DIMENSION; + + // The step params are specified in the text window, + // so force that to be shown. + SS.GW.ForceTextWindowShown(); + + SS.ScheduleShowTW(); + SS.GW.ClearSelection(); + } else { + Error(_("Constraint must have a label, and must not be " + "a reference dimension.")); + } + } else { + Error(_("Bad selection for step dimension; select a constraint.")); + } + break; + + case Command::NAKED_EDGES: { + ShowNakedEdges(/*reportOnlyWhenNotOkay=*/false); + break; + } + + case Command::INTERFERENCE: { + SS.nakedEdges.Clear(); + + SMesh *m = &(SK.GetGroup(SS.GW.activeGroup)->displayMesh); + SKdNode *root = SKdNode::From(m); + bool inters, leaks; + root->MakeCertainEdgesInto(&(SS.nakedEdges), + EdgeKind::SELF_INTER, /*coplanarIsInter=*/false, &inters, &leaks); + + SS.GW.Invalidate(); + + if(inters) { + Error("%d edges interfere with other triangles, bad.", + SS.nakedEdges.l.n); + } else { + Message(_("The assembly does not interfere, good.")); + } + break; + } + + case Command::CENTER_OF_MASS: { + SS.UpdateCenterOfMass(); + SS.centerOfMass.draw = true; + SS.GW.Invalidate(); + break; + } + + case Command::VOLUME: { + Group *g = SK.GetGroup(SS.GW.activeGroup); + double totalVol = g->displayMesh.CalculateVolume(); + std::string msg = ssprintf( + _("The volume of the solid model is:\n\n" + " %s"), + SS.MmToStringSI(totalVol, /*dim=*/3).c_str()); + + SMesh curMesh = {}; + g->thisShell.TriangulateInto(&curMesh); + double curVol = curMesh.CalculateVolume(); + if(curVol > 0.0) { + msg += ssprintf( + _("\nThe volume of current group mesh is:\n\n" + " %s"), + SS.MmToStringSI(curVol, /*dim=*/3).c_str()); + } + + msg += _("\n\nCurved surfaces have been approximated as triangles.\n" + "This introduces error, typically of around 1%."); + Message("%s", msg.c_str()); + break; + } + + case Command::AREA: { + Group *g = SK.GetGroup(SS.GW.activeGroup); + SS.GW.GroupSelection(); + + if(gs.faces > 0) { + std::vector faces; + faces.push_back(gs.face[0].v); + if(gs.faces > 1) faces.push_back(gs.face[1].v); + double area = g->displayMesh.CalculateSurfaceArea(faces); + Message(_("The surface area of the selected faces is:\n\n" + " %s\n\n" + "Curves have been approximated as piecewise linear.\n" + "This introduces error, typically of around 1%%."), + SS.MmToStringSI(area, /*dim=*/2).c_str()); + break; + } + + if(g->polyError.how != PolyError::GOOD) { + Error(_("This group does not contain a correctly-formed " + "2d closed area. It is open, not coplanar, or self-" + "intersecting.")); + break; + } + SEdgeList sel = {}; + g->polyLoops.MakeEdgesInto(&sel); + SPolygon sp = {}; + sel.AssemblePolygon(&sp, NULL, /*keepDir=*/true); + sp.normal = sp.ComputeNormal(); + sp.FixContourDirections(); + double area = sp.SignedArea(); + Message(_("The area of the region sketched in this group is:\n\n" + " %s\n\n" + "Curves have been approximated as piecewise linear.\n" + "This introduces error, typically of around 1%%."), + SS.MmToStringSI(area, /*dim=*/2).c_str()); + sel.Clear(); + sp.Clear(); + break; + } + + case Command::PERIMETER: { + if(gs.n > 0 && gs.n == gs.entities) { + double perimeter = 0.0; + for(int i = 0; i < gs.entities; i++) { + Entity *en = SK.entity.FindById(gs.entity[i]); + SEdgeList *el = en->GetOrGenerateEdges(); + for(const SEdge &e : el->l) { + perimeter += e.b.Minus(e.a).Magnitude(); + } + } + Message(_("The total length of the selected entities is:\n\n" + " %s\n\n" + "Curves have been approximated as piecewise linear.\n" + "This introduces error, typically of around 1%%."), + SS.MmToStringSI(perimeter, /*dim=*/1).c_str()); + } else { + Error(_("Bad selection for perimeter; select line segments, arcs, and curves.")); + } + break; + } + + case Command::SHOW_DOF: + // This works like a normal solve, except that it calculates + // which variables are free/bound at the same time. + SS.GenerateAll(SolveSpaceUI::Generate::ALL, /*andFindFree=*/true); + break; + + case Command::TRACE_PT: + if(gs.points == 1 && gs.n == 1) { + SS.traced.point = gs.point[0]; + SS.GW.ClearSelection(); + } else { + Error(_("Bad selection for trace; select a single point.")); + } + break; + + case Command::STOP_TRACING: { + if (SS.traced.point == Entity::NO_ENTITY) { + break; + } + Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); + dialog->AddFilters(Platform::CsvFileFilters); + dialog->ThawChoices(settings, "Trace"); + dialog->SetFilename(SS.saveFile); + if(dialog->RunModal()) { + dialog->FreezeChoices(settings, "Trace"); + + FILE *f = OpenFile(dialog->GetFilename(), "wb"); + if(f) { + int i; + SContour *sc = &(SS.traced.path); + for(i = 0; i < sc->l.n; i++) { + Vector p = sc->l[i].p; + double s = SS.exportScale; + fprintf(f, "%.10f, %.10f, %.10f\r\n", + p.x/s, p.y/s, p.z/s); + } + fclose(f); + } else { + Error(_("Couldn't write to '%s'"), dialog->GetFilename().raw.c_str()); + } + } + // Clear the trace, and stop tracing + SS.traced.point = Entity::NO_ENTITY; + SS.traced.path.l.Clear(); + SS.GW.Invalidate(); + break; + } + + default: ssassert(false, "Unexpected menu ID"); + } +} + +void SolveSpaceUI::ShowNakedEdges(bool reportOnlyWhenNotOkay) { + SS.nakedEdges.Clear(); + + Group *g = SK.GetGroup(SS.GW.activeGroup); + SMesh *m = &(g->displayMesh); + SKdNode *root = SKdNode::From(m); + bool inters, leaks; + root->MakeCertainEdgesInto(&(SS.nakedEdges), + EdgeKind::NAKED_OR_SELF_INTER, /*coplanarIsInter=*/true, &inters, &leaks); + + if(reportOnlyWhenNotOkay && !inters && !leaks && SS.nakedEdges.l.IsEmpty()) { + return; + } + SS.GW.Invalidate(); + + const char *intersMsg = inters ? + _("The mesh is self-intersecting (NOT okay, invalid).") : + _("The mesh is not self-intersecting (okay, valid)."); + const char *leaksMsg = leaks ? + _("The mesh has naked edges (NOT okay, invalid).") : + _("The mesh is watertight (okay, valid)."); + + std::string cntMsg = ssprintf( + _("\n\nThe model contains %d triangles, from %d surfaces."), + g->displayMesh.l.n, g->runningShell.surface.n); + + if(SS.nakedEdges.l.IsEmpty()) { + Message(_("%s\n\n%s\n\nZero problematic edges, good.%s"), + intersMsg, leaksMsg, cntMsg.c_str()); + } else { + Error(_("%s\n\n%s\n\n%d problematic edges, bad.%s"), + intersMsg, leaksMsg, SS.nakedEdges.l.n, cntMsg.c_str()); + } +} + +void SolveSpaceUI::MenuHelp(Command id) { + switch(id) { + case Command::WEBSITE: + Platform::OpenInBrowser("http://solvespace.com/helpmenu"); + break; + + case Command::ABOUT: + Message(_( +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n"), +PACKAGE_VERSION, 2021); + break; + + default: ssassert(false, "Unexpected menu ID"); + } +} + +void SolveSpaceUI::Clear() { + sys.Clear(); + for(int i = 0; i < MAX_UNDO; i++) { + if(i < undo.cnt) undo.d[i].Clear(); + if(i < redo.cnt) redo.d[i].Clear(); + } + TW.window = NULL; + GW.openRecentMenu = NULL; + GW.linkRecentMenu = NULL; + GW.showGridMenuItem = NULL; + GW.dimSolidModelMenuItem = NULL; + GW.perspectiveProjMenuItem = NULL; + GW.showToolbarMenuItem = NULL; + GW.showTextWndMenuItem = NULL; + GW.fullScreenMenuItem = NULL; + GW.unitsMmMenuItem = NULL; + GW.unitsMetersMenuItem = NULL; + GW.unitsInchesMenuItem = NULL; + GW.inWorkplaneMenuItem = NULL; + GW.in3dMenuItem = NULL; + GW.undoMenuItem = NULL; + GW.redoMenuItem = NULL; + GW.window = NULL; +} + +void Sketch::Clear() { + group.Clear(); + groupOrder.Clear(); + constraint.Clear(); + request.Clear(); + style.Clear(); + entity.Clear(); + param.Clear(); +} + +BBox Sketch::CalculateEntityBBox(bool includingInvisible) { + BBox box = {}; + bool first = true; + + auto includePoint = [&](const Vector &point) { + if(first) { + box.minp = point; + box.maxp = point; + first = false; + } else { + box.Include(point); + } + }; + + for(const Entity &e : entity) { + if(e.construction) continue; + if(!(includingInvisible || e.IsVisible())) continue; + + // arc center point shouldn't be included in bounding box calculation + if(e.IsPoint() && e.h.isFromRequest()) { + Request *r = SK.GetRequest(e.h.request()); + if(r->type == Request::Type::ARC_OF_CIRCLE && e.h == r->h.entity(1)) { + continue; + } + } + + if(e.IsPoint()) { + includePoint(e.PointGetNum()); + continue; + } + + switch(e.type) { + // Circles and arcs are special cases. We calculate their bounds + // based on Bezier curve bounds. This is not exact for arcs, + // but the implementation is rather simple. + case Entity::Type::CIRCLE: + case Entity::Type::ARC_OF_CIRCLE: { + SBezierList sbl = {}; + e.GenerateBezierCurves(&sbl); + + for(const SBezier &sb : sbl.l) { + for(int j = 0; j <= sb.deg; j++) { + includePoint(sb.ctrl[j]); + } + } + sbl.Clear(); + continue; + } + + default: + continue; + } + } + + return box; +} + +Group *Sketch::GetRunningMeshGroupFor(hGroup h) { + Group *g = GetGroup(h); + while(g != NULL) { + if(g->IsMeshGroup()) { + return g; + } + g = g->PreviousGroup(); + } + return NULL; +} diff --git a/src/solvespace.h b/src/solvespace.h new file mode 100644 index 0000000..e64a1ab --- /dev/null +++ b/src/solvespace.h @@ -0,0 +1,825 @@ +//----------------------------------------------------------------------------- +// All declarations not grouped specially elsewhere. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- + +#ifndef SOLVESPACE_H +#define SOLVESPACE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// We declare these in advance instead of simply using FT_Library +// (defined as typedef FT_LibraryRec_* FT_Library) because including +// freetype.h invokes indescribable horrors and we would like to avoid +// doing that every time we include solvespace.h. +struct FT_LibraryRec_; +struct FT_FaceRec_; + +typedef struct _cairo cairo_t; +typedef struct _cairo_surface cairo_surface_t; + +// The few floating-point equality comparisons in SolveSpace have been +// carefully considered, so we disable the -Wfloat-equal warning for them +#ifdef __clang__ +# define EXACT(expr) \ + (_Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wfloat-equal\"") \ + (expr) \ + _Pragma("clang diagnostic pop")) +#else +# define EXACT(expr) (expr) +#endif + +// Debugging functions +#if defined(__GNUC__) +#define ssassert(condition, message) \ + do { \ + if(__builtin_expect((condition), true) == false) { \ + SolveSpace::AssertFailure(__FILE__, __LINE__, __func__, #condition, message); \ + __builtin_unreachable(); \ + } \ + } while(0) +#else +#define ssassert(condition, message) \ + do { \ + if((condition) == false) { \ + SolveSpace::AssertFailure(__FILE__, __LINE__, __func__, #condition, message); \ + abort(); \ + } \ + } while(0) +#endif + +#define dbp SolveSpace::Platform::DebugPrint +#define DBPTRI(tri) \ + dbp("tri: (%.3f %.3f %.3f) (%.3f %.3f %.3f) (%.3f %.3f %.3f)", \ + CO((tri).a), CO((tri).b), CO((tri).c)) + +namespace SolveSpace { + +using std::min; +using std::max; +using std::swap; +using std::fabs; + +[[noreturn]] +void AssertFailure(const char *file, unsigned line, const char *function, + const char *condition, const char *message); + +#if defined(__GNUC__) +__attribute__((__format__ (__printf__, 1, 2))) +#endif +std::string ssprintf(const char *fmt, ...); + +inline bool IsReasonable(double x) { + return std::isnan(x) || x > 1e11 || x < -1e11; +} + +inline int WRAP(int v, int n) { + // Clamp it to the range [0, n) + while(v >= n) v -= n; + while(v < 0) v += n; + return v; +} +inline double WRAP_NOT_0(double v, double n) { + // Clamp it to the range (0, n] + while(v > n) v -= n; + while(v <= 0) v += n; + return v; +} +inline double WRAP_SYMMETRIC(double v, double n) { + // Clamp it to the range (-n/2, n/2] + while(v > n/2) v -= n; + while(v <= -n/2) v += n; + return v; +} + +#define CO(v) (v).x, (v).y, (v).z + +static constexpr double ANGLE_COS_EPS = 1e-6; +static constexpr double LENGTH_EPS = 1e-6; +static constexpr double VERY_POSITIVE = 1e10; +static constexpr double VERY_NEGATIVE = -1e10; + +#include "platform/platform.h" +#include "platform/gui.h" +#include "resource.h" + +using Platform::AllocTemporary; +using Platform::FreeAllTemporary; + +class Expr; +class ExprVector; +class ExprQuaternion; +class RgbaColor; +enum class Command : uint32_t; + +enum class Unit : uint32_t { + MM = 0, + INCHES, + METERS +}; + +template +using handle_map = std::map; + +class Group; +class SSurface; +#include "dsc.h" +#include "polygon.h" +#include "srf/surface.h" +#include "render/render.h" + +class Entity; +class hEntity; +class Param; +class hParam; +typedef IdList EntityList; +typedef IdList ParamList; + +enum class SolveResult : uint32_t { + OKAY = 0, + DIDNT_CONVERGE = 10, + REDUNDANT_OKAY = 11, + REDUNDANT_DIDNT_CONVERGE = 12, + TOO_MANY_UNKNOWNS = 20 +}; + + +#include "sketch.h" +#include "ui.h" +#include "expr.h" + + +// Utility functions that are provided in the platform-independent code. +class utf8_iterator : std::iterator { + const char *p, *n; +public: + utf8_iterator(const char *p) : p(p), n(NULL) {} + bool operator==(const utf8_iterator &i) const { return p==i.p; } + bool operator!=(const utf8_iterator &i) const { return p!=i.p; } + ptrdiff_t operator- (const utf8_iterator &i) const { return p -i.p; } + utf8_iterator& operator++() { **this; p=n; n=NULL; return *this; } + utf8_iterator operator++(int) { utf8_iterator t(*this); operator++(); return t; } + char32_t operator*(); + const char* ptr() const { return p; } +}; +class ReadUTF8 { + const std::string &str; +public: + ReadUTF8(const std::string &str) : str(str) {} + utf8_iterator begin() const { return utf8_iterator(&str[0]); } + utf8_iterator end() const { return utf8_iterator(&str[0] + str.length()); } +}; + + +#define arraylen(x) (sizeof((x))/sizeof((x)[0])) +#define PI (3.1415926535897931) +void MakeMatrix(double *mat, double a11, double a12, double a13, double a14, + double a21, double a22, double a23, double a24, + double a31, double a32, double a33, double a34, + double a41, double a42, double a43, double a44); +void MultMatrix(double *mata, double *matb, double *matr); + +int64_t GetMilliseconds(); +void Message(const char *fmt, ...); +void MessageAndRun(std::function onDismiss, const char *fmt, ...); +void Error(const char *fmt, ...); + +class System { +public: + enum { MAX_UNKNOWNS = 1024 }; + + EntityList entity; + ParamList param; + IdList eq; + + // A list of parameters that are being dragged; these are the ones that + // we should put as close as possible to their initial positions. + List dragged; + + enum { + // In general, the tag indicates the subsys that a variable/equation + // has been assigned to; these are exceptions for variables: + VAR_SUBSTITUTED = 10000, + VAR_DOF_TEST = 10001, + // and for equations: + EQ_SUBSTITUTED = 20000 + }; + + // The system Jacobian matrix + struct { + // The corresponding equation for each row + hEquation eq[MAX_UNKNOWNS]; + + // The corresponding parameter for each column + hParam param[MAX_UNKNOWNS]; + + // We're solving AX = B + int m, n; + struct { + Expr *sym[MAX_UNKNOWNS][MAX_UNKNOWNS]; + double num[MAX_UNKNOWNS][MAX_UNKNOWNS]; + } A; + + double scale[MAX_UNKNOWNS]; + + // Some helpers for the least squares solve + double AAt[MAX_UNKNOWNS][MAX_UNKNOWNS]; + double Z[MAX_UNKNOWNS]; + + double X[MAX_UNKNOWNS]; + + struct { + Expr *sym[MAX_UNKNOWNS]; + double num[MAX_UNKNOWNS]; + } B; + } mat; + + static const double RANK_MAG_TOLERANCE, CONVERGE_TOLERANCE; + int CalculateRank(); + bool TestRank(int *rank = NULL); + static bool SolveLinearSystem(double X[], double A[][MAX_UNKNOWNS], + double B[], int N); + bool SolveLeastSquares(); + + bool WriteJacobian(int tag); + void EvalJacobian(); + + void WriteEquationsExceptFor(hConstraint hc, Group *g); + void FindWhichToRemoveToFixJacobian(Group *g, List *bad, + bool forceDofCheck); + void SolveBySubstitution(); + + bool IsDragged(hParam p); + + bool NewtonSolve(int tag); + + void MarkParamsFree(bool findFree); + int CalculateDof(); + + SolveResult Solve(Group *g, int *rank = NULL, int *dof = NULL, + List *bad = NULL, + bool andFindBad = false, bool andFindFree = false, + bool forceDofCheck = false); + + SolveResult SolveRank(Group *g, int *rank = NULL, int *dof = NULL, + List *bad = NULL, + bool andFindBad = false, bool andFindFree = false); + + void Clear(); +}; + +#include "ttf.h" + +class StepFileWriter { +public: + void ExportSurfacesTo(const Platform::Path &filename); + void WriteHeader(); + void WriteProductHeader(); + int ExportCurve(SBezier *sb); + int ExportCurveLoop(SBezierLoop *loop, bool inner); + void ExportSurface(SSurface *ss, SBezierList *sbl); + void WriteWireframe(); + void WriteFooter(); + + List curves; + List advancedFaces; + FILE *f; + int id; +}; + +class VectorFileWriter { +protected: + Vector u, v, n, origin; + double cameraTan, scale; + +public: + FILE *f; + Platform::Path filename; + Vector ptMin, ptMax; + + static double MmToPts(double mm); + + static VectorFileWriter *ForFile(const Platform::Path &filename); + + void SetModelviewProjection(const Vector &u, const Vector &v, const Vector &n, + const Vector &origin, double cameraTan, double scale); + Vector Transform(Vector &pos) const; + + void OutputLinesAndMesh(SBezierLoopSetSet *sblss, SMesh *sm); + + void BezierAsPwl(SBezier *sb); + void BezierAsNonrationalCubic(SBezier *sb, int depth=0); + + virtual void StartPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) = 0; + virtual void FinishPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) = 0; + virtual void Bezier(SBezier *sb) = 0; + virtual void Triangle(STriangle *tr) = 0; + virtual bool OutputConstraints(IdList *) { return false; } + virtual void Background(RgbaColor color) = 0; + virtual void StartFile() = 0; + virtual void FinishAndCloseFile() = 0; + virtual bool HasCanvasSize() const = 0; + virtual bool CanOutputMesh() const = 0; +}; +class DxfFileWriter : public VectorFileWriter { +public: + struct BezierPath { + std::vector beziers; + }; + + std::vector paths; + IdList *constraint; + + static const char *lineTypeName(StipplePattern stippleType); + + bool OutputConstraints(IdList *constraint) override; + + void StartPath( RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) override; + void FinishPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) override; + void Triangle(STriangle *tr) override; + void Bezier(SBezier *sb) override; + void Background(RgbaColor color) override; + void StartFile() override; + void FinishAndCloseFile() override; + bool HasCanvasSize() const override { return false; } + bool CanOutputMesh() const override { return false; } + bool NeedToOutput(Constraint *c); +}; +class EpsFileWriter : public VectorFileWriter { +public: + Vector prevPt; + void MaybeMoveTo(Vector s, Vector f); + + void StartPath( RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) override; + void FinishPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) override; + void Triangle(STriangle *tr) override; + void Bezier(SBezier *sb) override; + void Background(RgbaColor color) override; + void StartFile() override; + void FinishAndCloseFile() override; + bool HasCanvasSize() const override { return true; } + bool CanOutputMesh() const override { return true; } +}; +class PdfFileWriter : public VectorFileWriter { +public: + uint32_t xref[10]; + uint32_t bodyStart; + Vector prevPt; + void MaybeMoveTo(Vector s, Vector f); + + void StartPath( RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) override; + void FinishPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) override; + void Triangle(STriangle *tr) override; + void Bezier(SBezier *sb) override; + void Background(RgbaColor color) override; + void StartFile() override; + void FinishAndCloseFile() override; + bool HasCanvasSize() const override { return true; } + bool CanOutputMesh() const override { return true; } +}; +class SvgFileWriter : public VectorFileWriter { +public: + Vector prevPt; + void MaybeMoveTo(Vector s, Vector f); + + void StartPath( RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) override; + void FinishPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) override; + void Triangle(STriangle *tr) override; + void Bezier(SBezier *sb) override; + void Background(RgbaColor color) override; + void StartFile() override; + void FinishAndCloseFile() override; + bool HasCanvasSize() const override { return true; } + bool CanOutputMesh() const override { return true; } +}; +class HpglFileWriter : public VectorFileWriter { +public: + static double MmToHpglUnits(double mm); + void StartPath( RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) override; + void FinishPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) override; + void Triangle(STriangle *tr) override; + void Bezier(SBezier *sb) override; + void Background(RgbaColor color) override; + void StartFile() override; + void FinishAndCloseFile() override; + bool HasCanvasSize() const override { return false; } + bool CanOutputMesh() const override { return false; } +}; +class Step2dFileWriter : public VectorFileWriter { + StepFileWriter sfw; + void StartPath( RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) override; + void FinishPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) override; + void Triangle(STriangle *tr) override; + void Bezier(SBezier *sb) override; + void Background(RgbaColor color) override; + void StartFile() override; + void FinishAndCloseFile() override; + bool HasCanvasSize() const override { return false; } + bool CanOutputMesh() const override { return false; } +}; +class GCodeFileWriter : public VectorFileWriter { +public: + SEdgeList sel; + void StartPath( RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) override; + void FinishPath(RgbaColor strokeRgb, double lineWidth, + bool filled, RgbaColor fillRgb, hStyle hs) override; + void Triangle(STriangle *tr) override; + void Bezier(SBezier *sb) override; + void Background(RgbaColor color) override; + void StartFile() override; + void FinishAndCloseFile() override; + bool HasCanvasSize() const override { return false; } + bool CanOutputMesh() const override { return false; } +}; + +#ifdef LIBRARY +# define ENTITY EntityBase +# define CONSTRAINT ConstraintBase +#else +# define ENTITY Entity +# define CONSTRAINT Constraint +#endif +class Sketch { +public: + // These are user-editable, and define the sketch. + IdList group; + List
groupOrder; + IdList constraint; + IdList request; + IdList style; + + // These are generated from the above. + IdList entity; + IdList param; + + inline CONSTRAINT *GetConstraint(hConstraint h) + { return constraint.FindById(h); } + inline ENTITY *GetEntity (hEntity h) { return entity. FindById(h); } + inline Param *GetParam (hParam h) { return param. FindById(h); } + inline Request *GetRequest(hRequest h) { return request.FindById(h); } + inline Group *GetGroup (hGroup h) { return group. FindById(h); } + // Styles are handled a bit differently. + + void Clear(); + + BBox CalculateEntityBBox(bool includingInvisible); + Group *GetRunningMeshGroupFor(hGroup h); +}; +#undef ENTITY +#undef CONSTRAINT + +class SolveSpaceUI { +public: + TextWindow *pTW; + TextWindow &TW; + GraphicsWindow GW; + + // The state for undo/redo + typedef struct UndoState { + IdList group; + List
groupOrder; + IdList request; + IdList constraint; + IdList param; + IdList style; + hGroup activeGroup; + + void Clear() { + group.Clear(); + request.Clear(); + constraint.Clear(); + param.Clear(); + style.Clear(); + } + } UndoState; + enum { MAX_UNDO = 100 }; + typedef struct { + UndoState d[MAX_UNDO]; + int cnt; + int write; + } UndoStack; + UndoStack undo; + UndoStack redo; + + std::map, Platform::PathLess> images; + bool ReloadLinkedImage(const Platform::Path &saveFile, Platform::Path *filename, + bool canCancel); + + void UndoEnableMenus(); + void UndoRemember(); + void UndoUndo(); + void UndoRedo(); + void PushFromCurrentOnto(UndoStack *uk); + void PopOntoCurrentFrom(UndoStack *uk); + void UndoClearState(UndoState *ut); + void UndoClearStack(UndoStack *uk); + + // Little bits of extra configuration state + enum { MODEL_COLORS = 8 }; + RgbaColor modelColor[MODEL_COLORS]; + Vector lightDir[2]; + double lightIntensity[2]; + double ambientIntensity; + double chordTol; + double chordTolCalculated; + int maxSegments; + double exportChordTol; + int exportMaxSegments; + int timeoutRedundantConstr; //milliseconds + double cameraTangent; + double gridSpacing; + double exportScale; + double exportOffset; + bool fixExportColors; + bool exportBackgroundColor; + bool drawBackFaces; + bool showContourAreas; + bool checkClosedContour; + bool turntableNav; + bool immediatelyEditDimension; + bool automaticLineConstraints; + bool showToolbar; + Platform::Path screenshotFile; + RgbaColor backgroundColor; + bool exportShadedTriangles; + bool exportPwlCurves; + bool exportCanvasSizeAuto; + bool exportMode; + struct { + double left; + double right; + double bottom; + double top; + } exportMargin; + struct { + double width; + double height; + double dx; + double dy; + } exportCanvas; + struct { + double depth; + int passes; + double feed; + double plungeFeed; + } gCode; + + Unit viewUnits; + int afterDecimalMm; + int afterDecimalInch; + int afterDecimalDegree; + bool useSIPrefixes; + int autosaveInterval; // in minutes + + std::string MmToString(double v); + std::string MmToStringSI(double v, int dim = 0); + std::string DegreeToString(double v); + double ExprToMm(Expr *e); + double StringToMm(const std::string &s); + const char *UnitName(); + double MmPerUnit(); + int UnitDigitsAfterDecimal(); + void SetUnitDigitsAfterDecimal(int v); + double ChordTolMm(); + double ExportChordTolMm(); + int GetMaxSegments(); + bool usePerspectiveProj; + double CameraTangent(); + + // Some stuff relating to the tangent arcs created non-parametrically + // as special requests. + double tangentArcRadius; + bool tangentArcManual; + bool tangentArcModify; + + // The platform-dependent code calls this before entering the msg loop + void Init(); + void Exit(); + + // File load/save routines, including the additional files that get + // loaded when we have link groups. + FILE *fh; + void AfterNewFile(); + void AddToRecentList(const Platform::Path &filename); + Platform::Path saveFile; + bool fileLoadError; + bool unsaved; + typedef struct { + char type; + const char *desc; + char fmt; + void *ptr; + } SaveTable; + static const SaveTable SAVED[]; + void SaveUsingTable(const Platform::Path &filename, int type); + void LoadUsingTable(const Platform::Path &filename, char *key, char *val); + struct { + Group g; + Request r; + Entity e; + Param p; + Constraint c; + Style s; + } sv; + static void MenuFile(Command id); + void Autosave(); + void RemoveAutosave(); + static constexpr size_t MAX_RECENT = 8; + static constexpr const char *SKETCH_EXT = "slvs"; + static constexpr const char *BACKUP_EXT = "slvs~"; + std::vector recentFiles; + bool Load(const Platform::Path &filename); + bool GetFilenameAndSave(bool saveAs); + bool OkayToStartNewFile(); + hGroup CreateDefaultDrawingGroup(); + void UpdateWindowTitles(); + void ClearExisting(); + void NewFile(); + bool SaveToFile(const Platform::Path &filename); + bool LoadAutosaveFor(const Platform::Path &filename); + bool LoadFromFile(const Platform::Path &filename, bool canCancel = false); + void UpgradeLegacyData(); + bool LoadEntitiesFromFile(const Platform::Path &filename, EntityList *le, + SMesh *m, SShell *sh); + bool LoadEntitiesFromSlvs(const Platform::Path &filename, EntityList *le, + SMesh *m, SShell *sh); + bool ReloadAllLinked(const Platform::Path &filename, bool canCancel = false); + // And the various export options + void ExportAsPngTo(const Platform::Path &filename); + void ExportMeshTo(const Platform::Path &filename); + void ExportMeshAsStlTo(FILE *f, SMesh *sm); + void ExportMeshAsObjTo(FILE *fObj, FILE *fMtl, SMesh *sm); + void ExportMeshAsThreeJsTo(FILE *f, const Platform::Path &filename, + SMesh *sm, SOutlineList *sol); + void ExportMeshAsVrmlTo(FILE *f, const Platform::Path &filename, SMesh *sm); + void ExportViewOrWireframeTo(const Platform::Path &filename, bool exportWireframe); + void ExportSectionTo(const Platform::Path &filename); + void ExportWireframeCurves(SEdgeList *sel, SBezierList *sbl, + VectorFileWriter *out); + void ExportLinesAndMesh(SEdgeList *sel, SBezierList *sbl, SMesh *sm, + Vector u, Vector v, + Vector n, Vector origin, + double cameraTan, + VectorFileWriter *out); + + static void MenuAnalyze(Command id); + + // Additional display stuff + struct { + SContour path; + hEntity point; + } traced; + SEdgeList nakedEdges; + struct { + bool draw; + Vector ptA; + Vector ptB; + } extraLine; + struct { + bool draw, showOrigin; + Vector pt, u, v; + } justExportedInfo; + struct { + bool draw; + bool dirty; + Vector position; + } centerOfMass; + + class Clipboard { + public: + List r; + List c; + + void Clear(); + bool ContainsEntity(hEntity old); + hEntity NewEntityFor(hEntity old); + }; + Clipboard clipboard; + + void MarkGroupDirty(hGroup hg, bool onlyThis = false); + void MarkGroupDirtyByEntity(hEntity he); + + // Consistency checking on the sketch: stuff with missing dependencies + // will get deleted automatically. + struct { + int requests; + int groups; + int constraints; + int nonTrivialConstraints; + } deleted; + bool GroupExists(hGroup hg); + bool PruneOrphans(); + bool EntityExists(hEntity he); + bool GroupsInOrder(hGroup before, hGroup after); + bool PruneGroups(hGroup hg); + bool PruneRequests(hGroup hg); + bool PruneConstraints(hGroup hg); + static void ShowNakedEdges(bool reportOnlyWhenNotOkay); + + enum class Generate : uint32_t { + DIRTY, + ALL, + REGEN, + UNTIL_ACTIVE, + }; + + void GenerateAll(Generate type = Generate::DIRTY, bool andFindFree = false, + bool genForBBox = false); + void SolveGroup(hGroup hg, bool andFindFree); + void SolveGroupAndReport(hGroup hg, bool andFindFree); + SolveResult TestRankForGroup(hGroup hg, int *rank = NULL); + void WriteEqSystemForGroup(hGroup hg); + void MarkDraggedParams(); + void ForceReferences(); + void UpdateCenterOfMass(); + + bool ActiveGroupsOkay(); + + // The system to be solved. + System *pSys; + System &sys; + + // All the TrueType fonts in memory + TtfFontList fonts; + + // Everything has been pruned, so we know there's no dangling references + // to entities that don't exist. Before that, we mustn't try to display + // the sketch! + bool allConsistent; + + Platform::TimerRef showTWTimer; + Platform::TimerRef generateAllTimer; + Platform::TimerRef autosaveTimer; + void ScheduleShowTW(); + void ScheduleGenerateAll(); + void ScheduleAutosave(); + + static void MenuHelp(Command id); + + void Clear(); + + // We allocate TW and sys on the heap to work around an MSVC problem + // where it puts zero-initialized global data in the binary (~30M of zeroes) + // in release builds. + SolveSpaceUI() + : pTW(new TextWindow()), TW(*pTW), + pSys(new System()), sys(*pSys) {} + + ~SolveSpaceUI() { + delete pTW; + delete pSys; + } +}; + +void ImportDxf(const Platform::Path &file); +void ImportDwg(const Platform::Path &file); +bool LinkIDF(const Platform::Path &filename, EntityList *le, SMesh *m, SShell *sh); + +extern SolveSpaceUI SS; +extern Sketch SK; + +} + +#ifndef __OBJC__ +using namespace SolveSpace; +#endif + +#endif diff --git a/src/srf/boolean.cpp b/src/srf/boolean.cpp new file mode 100644 index 0000000..1edf46e --- /dev/null +++ b/src/srf/boolean.cpp @@ -0,0 +1,1046 @@ +//----------------------------------------------------------------------------- +// Top-level functions to compute the Boolean union, difference or intersection +// between two shells of rational polynomial surfaces. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +static int I; + +void SShell::MakeFromUnionOf(SShell *a, SShell *b) { + MakeFromBoolean(a, b, SSurface::CombineAs::UNION); +} + +void SShell::MakeFromDifferenceOf(SShell *a, SShell *b) { + MakeFromBoolean(a, b, SSurface::CombineAs::DIFFERENCE); +} + +void SShell::MakeFromIntersectionOf(SShell *a, SShell *b) { + MakeFromBoolean(a, b, SSurface::CombineAs::INTERSECTION); +} + +void SCurve::GetAxisAlignedBounding(Vector *ptMax, Vector *ptMin) const { + *ptMax = {VERY_NEGATIVE, VERY_NEGATIVE, VERY_NEGATIVE}; + *ptMin = {VERY_POSITIVE, VERY_POSITIVE, VERY_POSITIVE}; + + for(int i = 0; i <= exact.deg; i++) { + exact.ctrl[i].MakeMaxMin(ptMax, ptMin); + } +} + +// We will be inserting other curve verticies into our curves to split them. +// This is helpful when curved surfaces become tangent along a trim and the +// usual tests for curve-surface intersection don't split the curve at a vertex. +// This is faster than the previous version that split at surface corners and +// handles more buggy cases. It's not clear this is the best way but it works ok. +static void FindVertsOnCurve(List *l, const SCurve *curve, SShell *sh) { + + Vector amax, amin; + curve->GetAxisAlignedBounding(&amax, &amin); + + for(auto sc : sh->curve) { + if(!sc.isExact) continue; + + Vector cmax, cmin; + sc.GetAxisAlignedBounding(&cmax, &cmin); + + if(Vector::BoundingBoxesDisjoint(amax, amin, cmax, cmin)) { + // They cannot possibly intersect, no curves to generate + continue; + } + + for(int i=0; i<2; i++) { + Vector pt = sc.exact.ctrl[ i==0 ? 0 : sc.exact.deg ]; + double t; + curve->exact.ClosestPointTo(pt, &t, /*must converge=*/ false); + double d = pt.Minus(curve->exact.PointAt(t)).Magnitude(); + if((t>LENGTH_EPS) && (t<(1.0-LENGTH_EPS)) && (d < LENGTH_EPS)) { + SInter inter; + inter.p = pt; + l->Add(&inter); + } + } + } +} + +//----------------------------------------------------------------------------- +// Take our original pwl curve. Wherever an edge intersects a surface within +// either agnstA or agnstB, split the piecewise linear element. Then refine +// the intersection so that it lies on all three relevant surfaces: the +// intersecting surface, srfA, and srfB. (So the pwl curve should lie at +// the intersection of srfA and srfB.) Return a new pwl curve with everything +// split. +//----------------------------------------------------------------------------- +SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB, + SSurface *srfA, SSurface *srfB) const +{ + SCurve ret; + ret = *this; + ret.pts = {}; + + // First find any vertex that lies on our curve. + List vertpts = {}; + if(isExact) { + if(agnstA) + FindVertsOnCurve(&vertpts, this, agnstA); + if(agnstB) + FindVertsOnCurve(&vertpts, this, agnstB); + } + + const SCurvePt *p = pts.First(); + ssassert(p != NULL, "Cannot split an empty curve"); + SCurvePt prev = *p; + ret.pts.Add(p); + p = pts.NextAfter(p); + + for(; p; p = pts.NextAfter(p)) { + List il = {}; + + // Find all the intersections with the two passed shells + if(agnstA) + agnstA->AllPointsIntersecting(prev.p, p->p, &il, + /*asSegment=*/true, /*trimmed=*/false, /*inclTangent=*/true); + if(agnstB) + agnstB->AllPointsIntersecting(prev.p, p->p, &il, + /*asSegment=*/true, /*trimmed=*/false, /*inclTangent=*/true); + + if(!il.IsEmpty()) { + // The intersections were generated by intersecting the pwl + // edge against a surface; so they must be refined to lie + // exactly on the original curve. + il.ClearTags(); + SInter *pi; + for(pi = il.First(); pi; pi = il.NextAfter(pi)) { + if(pi->srf == srfA || pi->srf == srfB) { + // The edge certainly intersects the surfaces that it + // trims (at its endpoints), but those ones don't count. + // They are culled later, but no sense calculating them + // and they will cause numerical problems (since two + // of the three surfaces they're refined to lie on will + // be identical, so the matrix will be singular). + pi->tag = 1; + continue; + } + + Point2d puv; + (pi->srf)->ClosestPointTo(pi->p, &puv, /*mustConverge=*/false); + + // Split the edge if the intersection lies within the surface's + // trim curves, or within the chord tol of the trim curve; want + // some slop if points are close to edge and pwl is too coarse, + // and it doesn't hurt to split unnecessarily. + Point2d dummy = { 0, 0 }; + SBspUv::Class c = (pi->srf->bsp) ? pi->srf->bsp->ClassifyPoint(puv, dummy, pi->srf) : SBspUv::Class::OUTSIDE; + if(c == SBspUv::Class::OUTSIDE) { + double d = VERY_POSITIVE; + if(pi->srf->bsp) d = pi->srf->bsp->MinimumDistanceToEdge(puv, pi->srf); + if(d > SS.ChordTolMm()) { + pi->tag = 1; + continue; + } + } + + // We're keeping the intersection, so actually refine it. Finding the intersection + // to within EPS is important to match the ends of different chopped trim curves. + // The general 3-surface intersection fails to refine for trims where surfaces + // are tangent at the curve, but those trims are usually exact, so… + if(isExact) { + (pi->srf)->PointOnCurve(&exact, &(puv.x), &(puv.y)); + } else { + (pi->srf)->PointOnSurfaces(srfA, srfB, &(puv.x), &(puv.y)); + } + pi->p = (pi->srf)->PointAt(puv); + } + il.RemoveTagged(); + } + // Now add any vertex that is on this segment + const Vector lineStart = prev.p; + const Vector lineDirection = (p->p).Minus(prev.p); + for(auto vtx : vertpts) { + double t = (vtx.p.Minus(lineStart)).DivProjected(lineDirection); + if((0.0 < t) && (t < 1.0)) { + il.Add(&vtx); + } + } + if(!il.IsEmpty()) { + SInter *pi; + + // And now sort them in order along the line. Note that we must + // do that after refining, in case the refining would make two + // points switch places. + std::sort(il.begin(), il.end(), [&](const SInter &a, const SInter &b) { + double ta = (a.p.Minus(lineStart)).DivProjected(lineDirection); + double tb = (b.p.Minus(lineStart)).DivProjected(lineDirection); + + return (ta < tb); + }); + + // And now uses the intersections to generate our split pwl edge(s) + Vector prev = Vector::From(VERY_POSITIVE, 0, 0); + for(pi = il.First(); pi; pi = il.NextAfter(pi)) { + // On-edge intersection will generate same split point for + // both surfaces, so don't create zero-length edge. + if(!prev.Equals(pi->p)) { + SCurvePt scpt; + scpt.tag = 0; + scpt.p = pi->p; + scpt.vertex = true; + ret.pts.Add(&scpt); + } + prev = pi->p; + } + } + + il.Clear(); + ret.pts.Add(p); + prev = *p; + } + vertpts.Clear(); + return ret; +} + +void SShell::CopyCurvesSplitAgainst(bool opA, SShell *agnst, SShell *into) { +#pragma omp parallel for + for(int i=0; iMakeCopySplitAgainst(agnst, NULL, + surface.FindById(sc->surfA), + surface.FindById(sc->surfB)); + scn.source = opA ? SCurve::Source::A : SCurve::Source::B; +#pragma omp critical + { + hSCurve hsc = into->curve.AddAndAssignId(&scn); + // And note the new ID so that we can rewrite the trims appropriately + sc->newH = hsc; + } + } +} + +void SSurface::TrimFromEdgeList(SEdgeList *el, bool asUv) { + el->l.ClearTags(); + + STrimBy stb = {}; + for(;;) { + // Find an edge, any edge; we'll start from there. + SEdge *se; + for(se = el->l.First(); se; se = el->l.NextAfter(se)) { + if(se->tag) continue; + break; + } + if(!se) break; + se->tag = 1; + stb.start = se->a; + stb.finish = se->b; + stb.curve.v = se->auxA; + stb.backwards = se->auxB ? true : false; + + // Find adjoining edges from the same curve; those should be + // merged into a single trim. + bool merged; + do { + merged = false; + for(se = el->l.First(); se; se = el->l.NextAfter(se)) { + if(se->tag) continue; + if(se->auxA != (int)stb.curve.v) continue; + if(( se->auxB && !stb.backwards) || + (!se->auxB && stb.backwards)) continue; + + if((se->a).Equals(stb.finish)) { + stb.finish = se->b; + se->tag = 1; + merged = true; + } else if((se->b).Equals(stb.start)) { + stb.start = se->a; + se->tag = 1; + merged = true; + } + } + } while(merged); + + if(asUv) { + stb.start = PointAt(stb.start.x, stb.start.y); + stb.finish = PointAt(stb.finish.x, stb.finish.y); + } + + // And add the merged trim, with xyz (not uv like the polygon) pts + trim.Add(&stb); + } +} + +static bool KeepRegion(SSurface::CombineAs type, bool opA, SShell::Class shell, SShell::Class orig) +{ + bool inShell = (shell == SShell::Class::INSIDE), + outSide = (shell == SShell::Class::OUTSIDE), + inSame = (shell == SShell::Class::COINC_SAME), + inOrig = (orig == SShell::Class::INSIDE); + + if(!inOrig) return false; + switch(type) { + case SSurface::CombineAs::UNION: + if(opA) { + return outSide; + } else { + return outSide || inSame; + } + + case SSurface::CombineAs::DIFFERENCE: + if(opA) { + return outSide; + } else { + return inShell || inSame; + } + + case SSurface::CombineAs::INTERSECTION: + if(opA) { + return inShell; + } else { + return inShell || inSame; + } + + default: ssassert(false, "Unexpected combine type"); + } +} +static bool KeepEdge(SSurface::CombineAs type, bool opA, + SShell::Class indir_shell, SShell::Class outdir_shell, + SShell::Class indir_orig, SShell::Class outdir_orig) +{ + bool keepIn = KeepRegion(type, opA, indir_shell, indir_orig), + keepOut = KeepRegion(type, opA, outdir_shell, outdir_orig); + + // If the regions to the left and right of this edge are both in or both + // out, then this edge is not useful and should be discarded. + if(keepIn && !keepOut) return true; + return false; +} + +static void TagByClassifiedEdge(SBspUv::Class bspclass, SShell::Class *indir, SShell::Class *outdir) +{ + switch(bspclass) { + case SBspUv::Class::INSIDE: + *indir = SShell::Class::INSIDE; + *outdir = SShell::Class::INSIDE; + break; + + case SBspUv::Class::OUTSIDE: + *indir = SShell::Class::OUTSIDE; + *outdir = SShell::Class::OUTSIDE; + break; + + case SBspUv::Class::EDGE_PARALLEL: + *indir = SShell::Class::INSIDE; + *outdir = SShell::Class::OUTSIDE; + break; + + case SBspUv::Class::EDGE_ANTIPARALLEL: + *indir = SShell::Class::OUTSIDE; + *outdir = SShell::Class::INSIDE; + break; + + default: + dbp("TagByClassifiedEdge: fail!"); + *indir = SShell::Class::OUTSIDE; + *outdir = SShell::Class::OUTSIDE; + break; + } +} + +static void DEBUGEDGELIST(SEdgeList *sel, SSurface *surf) { + dbp("print %d edges", sel->l.n); + SEdge *se; + for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { + Vector mid = (se->a).Plus(se->b).ScaledBy(0.5); + Vector arrow = (se->b).Minus(se->a); + swap(arrow.x, arrow.y); + arrow.x *= -1; + arrow = arrow.WithMagnitude(0.01); + arrow = arrow.Plus(mid); + + SS.nakedEdges.AddEdge(surf->PointAt(se->a.x, se->a.y), + surf->PointAt(se->b.x, se->b.y)); + SS.nakedEdges.AddEdge(surf->PointAt(mid.x, mid.y), + surf->PointAt(arrow.x, arrow.y)); + } +} + +//----------------------------------------------------------------------------- +// We are given src, with at least one edge, and avoid, a list of points to +// avoid. We return a chain of edges (that share endpoints), such that no +// point within the avoid list ever occurs in the middle of a chain. And we +// delete the edges in that chain from our source list. +//----------------------------------------------------------------------------- +void SSurface::FindChainAvoiding(SEdgeList *src, SEdgeList *dest, + SPointList *avoid) +{ + ssassert(!src->l.IsEmpty(), "Need at least one edge"); + // Start with an arbitrary edge. + dest->l.Add(src->l.First()); + src->l.ClearTags(); + src->l.First()->tag = 1; + + bool added; + do { + added = false; + // The start and finish of the current edge chain + Vector s = dest->l.First()->a, + f = dest->l.Last()->b; + + // We can attach a new edge at the start or finish, as long as that + // start or finish point isn't in the list of points to avoid. + bool startOkay = !avoid->ContainsPoint(s), + finishOkay = !avoid->ContainsPoint(f); + + // Now look for an unused edge that joins at the start or finish of + // our chain (if permitted by the avoid list). + SEdge *se; + for(se = src->l.First(); se; se = src->l.NextAfter(se)) { + if(se->tag) continue; + if(startOkay && s.Equals(se->b)) { + dest->l.AddToBeginning(se); + s = se->a; + se->tag = 1; + startOkay = !avoid->ContainsPoint(s); + } else if(finishOkay && f.Equals(se->a)) { + dest->l.Add(se); + f = se->b; + se->tag = 1; + finishOkay = !avoid->ContainsPoint(f); + } else { + continue; + } + + added = true; + } + } while(added); + + src->l.RemoveTagged(); +} + +void SSurface::EdgeNormalsWithinSurface(Point2d auv, Point2d buv, + Vector *pt, + Vector *enin, Vector *enout, + Vector *surfn, + uint32_t auxA, + SShell *shell, SShell *sha, SShell *shb) +{ + // the midpoint of the edge + Point2d muv = (auv.Plus(buv)).ScaledBy(0.5); + + *pt = PointAt(muv); + + // If this edge just approximates a curve, then refine our midpoint so + // so that it actually lies on that curve too. Otherwise stuff like + // point-on-face tests will fail, since the point won't actually lie + // on the other face. + hSCurve hc = { auxA }; + SCurve *sc = shell->curve.FindById(hc); + if(sc->isExact && sc->exact.deg != 1) { + double t; + sc->exact.ClosestPointTo(*pt, &t, /*mustConverge=*/false); + *pt = sc->exact.PointAt(t); + ClosestPointTo(*pt, &muv); + } else if(!sc->isExact) { + SSurface *trimmedA = sc->GetSurfaceA(sha, shb), + *trimmedB = sc->GetSurfaceB(sha, shb); + *pt = trimmedA->ClosestPointOnThisAndSurface(trimmedB, *pt); + ClosestPointTo(*pt, &muv); + } + + *surfn = NormalAt(muv.x, muv.y); + + // Compute the edge's inner normal in xyz space. + Vector ab = (PointAt(auv)).Minus(PointAt(buv)), + enxyz = (ab.Cross(*surfn)).WithMagnitude(SS.ChordTolMm()); + // And based on that, compute the edge's inner normal in uv space. This + // vector is perpendicular to the edge in xyz, but not necessarily in uv. + Vector tu, tv, tx, ty; + TangentsAt(muv.x, muv.y, &tu, &tv); + Vector n = tu.Cross(tv); + // since tu and tv may not be orthogonal, use y in place of v, x in place of u. + // |y| = |v|sin(theta) where theta is the angle between tu and tv. + ty = n.Cross(tu).ScaledBy(1.0/tu.MagSquared()); + tx = tv.Cross(n).ScaledBy(1.0/tv.MagSquared()); + + Point2d enuv; + enuv.x = enxyz.Dot(tx) / tx.MagSquared(); + enuv.y = enxyz.Dot(ty) / ty.MagSquared(); + + // Compute the inner and outer normals of this edge (within the srf), + // in xyz space. These are not necessarily antiparallel, if the + // surface is curved. + Vector pin = PointAt(muv.Minus(enuv)), + pout = PointAt(muv.Plus(enuv)); + *enin = pin.Minus(*pt), + *enout = pout.Minus(*pt); +} + +//----------------------------------------------------------------------------- +// Trim this surface against the specified shell, in the way that's appropriate +// for the specified Boolean operation type (and which operand we are). We +// also need a pointer to the shell that contains our own surface, since that +// contains our original trim curves. +//----------------------------------------------------------------------------- +SSurface SSurface::MakeCopyTrimAgainst(SShell *parent, + SShell *sha, SShell *shb, + SShell *into, + SSurface::CombineAs type, + int dbg_index) +{ + bool opA = (parent == sha); + SShell *agnst = opA ? shb : sha; + + SSurface ret; + // The returned surface is identical, just the trim curves change + ret = *this; + ret.trim = {}; + + // First, build a list of the existing trim curves; update them to use + // the split curves. + STrimBy *stb; + for(stb = trim.First(); stb; stb = trim.NextAfter(stb)) { + STrimBy stn = *stb; + stn.curve = (parent->curve.FindById(stn.curve))->newH; + ret.trim.Add(&stn); + } + + if(type == SSurface::CombineAs::DIFFERENCE && !opA) { + // The second operand of a Boolean difference gets turned inside out + ret.Reverse(); + } + + // Build up our original trim polygon; remember the coordinates could + // be changed if we just flipped the surface normal, and we are using + // the split curves (not the original curves). + SEdgeList orig = {}; + ret.MakeEdgesInto(into, &orig, MakeAs::UV); + ret.trim.Clear(); + // which means that we can't necessarily use the old BSP... + SBspUv *origBsp = SBspUv::From(&orig, &ret); + + // And now intersect the other shell against us + SEdgeList inter = {}; + + SSurface *ss; + SCurve *sc; + for(sc = into->curve.First(); sc; sc = into->curve.NextAfter(sc)) { + if(sc->source != SCurve::Source::INTERSECTION) continue; + if(opA) { + if(sc->surfA != h) continue; + ss = shb->surface.FindById(sc->surfB); + } else { + if(sc->surfB != h) continue; + ss = sha->surface.FindById(sc->surfA); + } + int i; + for(i = 1; i < sc->pts.n; i++) { + Vector a = sc->pts[i-1].p, + b = sc->pts[i].p; + + Point2d auv, buv; + ss->ClosestPointTo(a, &(auv.x), &(auv.y)); + ss->ClosestPointTo(b, &(buv.x), &(buv.y)); + + SBspUv::Class c = (ss->bsp) ? ss->bsp->ClassifyEdge(auv, buv, ss) : SBspUv::Class::OUTSIDE; + if(c != SBspUv::Class::OUTSIDE) { + Vector ta = Vector::From(0, 0, 0); + Vector tb = Vector::From(0, 0, 0); + ret.ClosestPointTo(a, &(ta.x), &(ta.y)); + ret.ClosestPointTo(b, &(tb.x), &(tb.y)); + + Vector tn = ret.NormalAt(ta.x, ta.y); + Vector sn = ss->NormalAt(auv.x, auv.y); + + // We are subtracting the portion of our surface that + // lies in the shell, so the in-plane edge normal should + // point opposite to the surface normal. + bool bkwds = true; + if((tn.Cross(b.Minus(a))).Dot(sn) < 0) bkwds = !bkwds; + if((type == SSurface::CombineAs::DIFFERENCE && !opA) || + (type == SSurface::CombineAs::INTERSECTION)) { // Invert all newly created edges for intersection + bkwds = !bkwds; + } + if(bkwds) { + inter.AddEdge(tb, ta, sc->h.v, 1); + } else { + inter.AddEdge(ta, tb, sc->h.v, 0); + } + } + } + } + + // Record all the points where more than two edges join, which I will call + // the choosing points. If two edges join at a non-choosing point, then + // they must either both be kept or both be discarded (since that would + // otherwise create an open contour). + SPointList choosing = {}; + SEdge *se; + for(se = orig.l.First(); se; se = orig.l.NextAfter(se)) { + choosing.IncrementTagFor(se->a); + choosing.IncrementTagFor(se->b); + } + for(se = inter.l.First(); se; se = inter.l.NextAfter(se)) { + choosing.IncrementTagFor(se->a); + choosing.IncrementTagFor(se->b); + } + SPoint *sp; + for(sp = choosing.l.First(); sp; sp = choosing.l.NextAfter(sp)) { + if(sp->tag == 2) { + sp->tag = 1; + } else { + sp->tag = 0; + } + } + choosing.l.RemoveTagged(); + + // The list of edges to trim our new surface, a combination of edges from + // our original and intersecting edge lists. + SEdgeList final = {}; + + while(!orig.l.IsEmpty()) { + SEdgeList chain = {}; + FindChainAvoiding(&orig, &chain, &choosing); + + // Arbitrarily choose an edge within the chain to classify; they + // should all be the same, though. + se = &(chain.l[chain.l.n/2]); + + Point2d auv = (se->a).ProjectXy(), + buv = (se->b).ProjectXy(); + + Vector pt, enin, enout, surfn; + ret.EdgeNormalsWithinSurface(auv, buv, &pt, &enin, &enout, &surfn, + se->auxA, into, sha, shb); + + SShell::Class indir_shell, outdir_shell, indir_orig, outdir_orig; + + indir_orig = SShell::Class::INSIDE; + outdir_orig = SShell::Class::OUTSIDE; + + agnst->ClassifyEdge(&indir_shell, &outdir_shell, + ret.PointAt(auv), ret.PointAt(buv), pt, + enin, enout, surfn); + + if(KeepEdge(type, opA, indir_shell, outdir_shell, + indir_orig, outdir_orig)) + { + for(se = chain.l.First(); se; se = chain.l.NextAfter(se)) { + final.AddEdge(se->a, se->b, se->auxA, se->auxB); + } + } + chain.Clear(); + } + + while(!inter.l.IsEmpty()) { + SEdgeList chain = {}; + FindChainAvoiding(&inter, &chain, &choosing); + + // Any edge in the chain, same as above. + se = &(chain.l[chain.l.n/2]); + + Point2d auv = (se->a).ProjectXy(), + buv = (se->b).ProjectXy(); + + Vector pt, enin, enout, surfn; + ret.EdgeNormalsWithinSurface(auv, buv, &pt, &enin, &enout, &surfn, + se->auxA, into, sha, shb); + + SShell::Class indir_shell, outdir_shell, indir_orig, outdir_orig; + + SBspUv::Class c_this = (origBsp) ? origBsp->ClassifyEdge(auv, buv, &ret) : SBspUv::Class::OUTSIDE; + TagByClassifiedEdge(c_this, &indir_orig, &outdir_orig); + + agnst->ClassifyEdge(&indir_shell, &outdir_shell, + ret.PointAt(auv), ret.PointAt(buv), pt, + enin, enout, surfn); + + if(KeepEdge(type, opA, indir_shell, outdir_shell, + indir_orig, outdir_orig)) + { + for(se = chain.l.First(); se; se = chain.l.NextAfter(se)) { + final.AddEdge(se->a, se->b, se->auxA, se->auxB); + } + } + chain.Clear(); + } + + // Cull extraneous edges; duplicates or anti-parallel pairs. In particular, + // we can get duplicate edges if our surface intersects the other shell + // at an edge, so that both surfaces intersect coincident (and both + // generate an intersection edge). + final.CullExtraneousEdges(/*both=*/true); + + // Use our reassembled edges to trim the new surface. + ret.TrimFromEdgeList(&final, /*asUv=*/true); + + SPolygon poly = {}; + final.l.ClearTags(); + if(!final.AssemblePolygon(&poly, NULL, /*keepDir=*/true)) +#pragma omp critical + { + into->booleanFailed = true; + dbp("failed: I=%d, avoid=%d", I+dbg_index, choosing.l.n); + DEBUGEDGELIST(&final, &ret); + } + poly.Clear(); + + choosing.Clear(); + final.Clear(); + inter.Clear(); + orig.Clear(); + return ret; +} + +void SShell::CopySurfacesTrimAgainst(SShell *sha, SShell *shb, SShell *into, SSurface::CombineAs type) { + std::vector ssn(surface.n); +#pragma omp parallel for + for (int i = 0; i < surface.n; i++) + { + SSurface *ss = &surface[i]; + ssn[i] = ss->MakeCopyTrimAgainst(this, sha, shb, into, type, i); + } + + for (int i = 0; i < surface.n; i++) + { + surface[i].newH = into->surface.AddAndAssignId(&ssn[i]); + } + I += surface.n; +} + +void SShell::MakeIntersectionCurvesAgainst(SShell *agnst, SShell *into) { +#pragma omp parallel for + for(int i = 0; i< surface.n; i++) { + SSurface *sa = &surface[i]; + + SSurface *sb; + for(sb = agnst->surface.First(); sb; sb = agnst->surface.NextAfter(sb)){ + // Intersect every surface from our shell against every surface + // from agnst; this will add zero or more curves to the curve + // list for into. + sa->IntersectAgainst(sb, this, agnst, into); + } + } +} + +void SShell::CleanupAfterBoolean() { + SSurface *ss; + for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) { + ss->edges.Clear(); + } +} + +//----------------------------------------------------------------------------- +// All curves contain handles to the two surfaces that they trim. After a +// Boolean or assembly, we must rewrite those handles to refer to the curves +// by their new IDs. +//----------------------------------------------------------------------------- +void SShell::RewriteSurfaceHandlesForCurves(SShell *a, SShell *b) { + SCurve *sc; + for(sc = curve.First(); sc; sc = curve.NextAfter(sc)) { + sc->surfA = sc->GetSurfaceA(a, b)->newH, + sc->surfB = sc->GetSurfaceB(a, b)->newH; + } +} + +//----------------------------------------------------------------------------- +// Copy all the surfaces and curves from two different shells into a single +// shell. The only difficulty is to rewrite all of their handles; we don't +// look for any surface intersections, so if two objects interfere then the +// result is just self-intersecting. This is used for assembly, since it's +// much faster than merging as union. +//----------------------------------------------------------------------------- +void SShell::MakeFromAssemblyOf(SShell *a, SShell *b) { + booleanFailed = false; + + Vector t = Vector::From(0, 0, 0); + Quaternion q = Quaternion::IDENTITY; + int i = 0; + SShell *ab; + + // First, copy over all the curves. Note which shell (a or b) each curve + // came from, but assign it a new ID. + curve.ReserveMore(a->curve.n + b->curve.n); + SCurve *c, cn; + for(i = 0; i < 2; i++) { + ab = (i == 0) ? a : b; + for(c = ab->curve.First(); c; c = ab->curve.NextAfter(c)) { + cn = SCurve::FromTransformationOf(c, t, q, 1.0); + cn.source = (i == 0) ? SCurve::Source::A : SCurve::Source::B; + // surfA and surfB are wrong now, and we can't fix them until + // we've assigned IDs to the surfaces. So we'll get that later. + c->newH = curve.AddAndAssignId(&cn); + } + } + + // Likewise copy over all the surfaces. + surface.ReserveMore(a->surface.n + b->surface.n); + SSurface *s, sn; + for(i = 0; i < 2; i++) { + ab = (i == 0) ? a : b; + for(s = ab->surface.First(); s; s = ab->surface.NextAfter(s)) { + sn = SSurface::FromTransformationOf(s, t, q, 1.0, /*includingTrims=*/true); + // All the trim curve IDs get rewritten; we know the new handles + // to the curves since we recorded them in the previous step. + STrimBy *stb; + for(stb = sn.trim.First(); stb; stb = sn.trim.NextAfter(stb)) { + stb->curve = ab->curve.FindById(stb->curve)->newH; + } + s->newH = surface.AddAndAssignId(&sn); + } + } + + // Finally, rewrite the surfaces associated with each curve to use the + // new handles. + RewriteSurfaceHandlesForCurves(a, b); +} + +void SShell::MakeFromBoolean(SShell *a, SShell *b, SSurface::CombineAs type) { + booleanFailed = false; + + a->MakeClassifyingBsps(NULL); + b->MakeClassifyingBsps(NULL); + + // Copy over all the original curves, splitting them so that a + // piecwise linear segment never crosses a surface from the other + // shell. + a->CopyCurvesSplitAgainst(/*opA=*/true, b, this); + b->CopyCurvesSplitAgainst(/*opA=*/false, a, this); + + // Generate the intersection curves for each surface in A against all + // the surfaces in B (which is all of the intersection curves). + a->MakeIntersectionCurvesAgainst(b, this); + + SCurve *sc; + for(sc = curve.First(); sc; sc = curve.NextAfter(sc)) { + SSurface *srfA = sc->GetSurfaceA(a, b), + *srfB = sc->GetSurfaceB(a, b); + + sc->RemoveShortSegments(srfA, srfB); + } + + // And clean up the piecewise linear things we made as a calculation aid + a->CleanupAfterBoolean(); + b->CleanupAfterBoolean(); + // Remake the classifying BSPs with the split (and short-segment-removed) + // curves + a->MakeClassifyingBsps(this); + b->MakeClassifyingBsps(this); + + if(b->surface.IsEmpty() || a->surface.IsEmpty()) { + I = 1000000; + } else { + I = 0; + } + // Then trim and copy the surfaces + a->CopySurfacesTrimAgainst(a, b, this, type); + b->CopySurfacesTrimAgainst(a, b, this, type); + + // Now that we've copied the surfaces, we know their new hSurfaces, so + // rewrite the curves to refer to the surfaces by their handles in the + // result. + RewriteSurfaceHandlesForCurves(a, b); + + // And clean up the piecewise linear things we made as a calculation aid + a->CleanupAfterBoolean(); + b->CleanupAfterBoolean(); +} + +//----------------------------------------------------------------------------- +// All of the BSP routines that we use to perform and accelerate polygon ops. +//----------------------------------------------------------------------------- +void SShell::MakeClassifyingBsps(SShell *useCurvesFrom) { +#pragma omp parallel for + for(int i = 0; il.First(); se; se = el->l.NextAfter(se)) { + work.AddEdge(se->a, se->b, se->auxA, se->auxB); + } + std::sort(work.l.begin(), work.l.end(), [](SEdge const &a, SEdge const &b) { + double la = (a.a).Minus(a.b).Magnitude(), lb = (b.a).Minus(b.b).Magnitude(); + // Sort in descending order, longest first. This improves numerical + // stability for the normals. + return la > lb; + }); + SBspUv *bsp = NULL; + for(se = work.l.First(); se; se = work.l.NextAfter(se)) { + bsp = InsertOrCreateEdge(bsp, (se->a).ProjectXy(), (se->b).ProjectXy(), srf); + } + + work.Clear(); + return bsp; +} + +//----------------------------------------------------------------------------- +// The points in this BSP are in uv space, but we want to apply our tolerances +// consistently in xyz (i.e., we want to say a point is on-edge if its xyz +// distance to that edge is less than LENGTH_EPS, irrespective of its distance +// in uv). So we linearize the surface about the point we're considering and +// then do the test. That preserves point-on-line relationships, and the only +// time we care about exact correctness is when we're very close to the line, +// which is when the linearization is accurate. +//----------------------------------------------------------------------------- + +void SBspUv::ScalePoints(Point2d *pt, Point2d *a, Point2d *b, SSurface *srf) const { + Vector tu, tv; + srf->TangentsAt(pt->x, pt->y, &tu, &tv); + double mu = tu.Magnitude(), mv = tv.Magnitude(); + + pt->x *= mu; pt->y *= mv; + a ->x *= mu; a ->y *= mv; + b ->x *= mu; b ->y *= mv; +} + +double SBspUv::ScaledSignedDistanceToLine(Point2d pt, Point2d a, Point2d b, + SSurface *srf) const +{ + ScalePoints(&pt, &a, &b, srf); + + Point2d n = ((b.Minus(a)).Normal()).WithMagnitude(1); + double d = a.Dot(n); + + return pt.Dot(n) - d; +} + +double SBspUv::ScaledDistanceToLine(Point2d pt, Point2d a, Point2d b, bool asSegment, + SSurface *srf) const +{ + ScalePoints(&pt, &a, &b, srf); + + return pt.DistanceToLine(a, b, asSegment); +} + +SBspUv *SBspUv::InsertOrCreateEdge(SBspUv *where, Point2d ea, Point2d eb, SSurface *srf) { + if(where == NULL) { + SBspUv *ret = Alloc(); + ret->a = ea; + ret->b = eb; + return ret; + } + where->InsertEdge(ea, eb, srf); + return where; +} + +void SBspUv::InsertEdge(Point2d ea, Point2d eb, SSurface *srf) { + double dea = ScaledSignedDistanceToLine(ea, a, b, srf), + deb = ScaledSignedDistanceToLine(eb, a, b, srf); + + if(fabs(dea) < LENGTH_EPS && fabs(deb) < LENGTH_EPS) { + // Line segment is coincident with this one, store in same node + SBspUv *m = Alloc(); + m->a = ea; + m->b = eb; + m->more = more; + more = m; + } else if(fabs(dea) < LENGTH_EPS) { + // Point A lies on this line, but point B does not + if(deb > 0) { + pos = InsertOrCreateEdge(pos, ea, eb, srf); + } else { + neg = InsertOrCreateEdge(neg, ea, eb, srf); + } + } else if(fabs(deb) < LENGTH_EPS) { + // Point B lies on this line, but point A does not + if(dea > 0) { + pos = InsertOrCreateEdge(pos, ea, eb, srf); + } else { + neg = InsertOrCreateEdge(neg, ea, eb, srf); + } + } else if(dea > 0 && deb > 0) { + pos = InsertOrCreateEdge(pos, ea, eb, srf); + } else if(dea < 0 && deb < 0) { + neg = InsertOrCreateEdge(neg, ea, eb, srf); + } else { + // New edge crosses this one; we need to split. + Point2d n = ((b.Minus(a)).Normal()).WithMagnitude(1); + double d = a.Dot(n); + double t = (d - n.Dot(ea)) / (n.Dot(eb.Minus(ea))); + Point2d pi = ea.Plus((eb.Minus(ea)).ScaledBy(t)); + if(dea > 0) { + pos = InsertOrCreateEdge(pos, ea, pi, srf); + neg = InsertOrCreateEdge(neg, pi, eb, srf); + } else { + neg = InsertOrCreateEdge(neg, ea, pi, srf); + pos = InsertOrCreateEdge(pos, pi, eb, srf); + } + } + return; +} + +SBspUv::Class SBspUv::ClassifyPoint(Point2d p, Point2d eb, SSurface *srf) const { + double dp = ScaledSignedDistanceToLine(p, a, b, srf); + + if(fabs(dp) < LENGTH_EPS) { + const SBspUv *f = this; + while(f) { + Point2d ba = (f->b).Minus(f->a); + if(ScaledDistanceToLine(p, f->a, ba, /*asSegment=*/true, srf) < LENGTH_EPS) { + if(ScaledDistanceToLine(eb, f->a, ba, /*asSegment=*/false, srf) < LENGTH_EPS){ + if(ba.Dot(eb.Minus(p)) > 0) { + return Class::EDGE_PARALLEL; + } else { + return Class::EDGE_ANTIPARALLEL; + } + } else { + return Class::EDGE_OTHER; + } + } + f = f->more; + } + // Pick arbitrarily which side to send it down, doesn't matter + Class c1 = neg ? neg->ClassifyPoint(p, eb, srf) : Class::OUTSIDE; + Class c2 = pos ? pos->ClassifyPoint(p, eb, srf) : Class::INSIDE; + if(c1 != c2) { + dbp("MISMATCH: %d %d %08x %08x", c1, c2, neg, pos); + } + return c1; + } else if(dp > 0) { + return pos ? pos->ClassifyPoint(p, eb, srf) : Class::INSIDE; + } else { + return neg ? neg->ClassifyPoint(p, eb, srf) : Class::OUTSIDE; + } +} + +SBspUv::Class SBspUv::ClassifyEdge(Point2d ea, Point2d eb, SSurface *srf) const { + SBspUv::Class ret = ClassifyPoint((ea.Plus(eb)).ScaledBy(0.5), eb, srf); + if(ret == Class::EDGE_OTHER) { + // Perhaps the edge is tangent at its midpoint (and we screwed up + // somewhere earlier and failed to split it); try a different + // point on the edge. + ret = ClassifyPoint(ea.Plus((eb.Minus(ea)).ScaledBy(0.294)), eb, srf); + } + return ret; +} + +double SBspUv::MinimumDistanceToEdge(Point2d p, SSurface *srf) const { + + double dn = (neg) ? neg->MinimumDistanceToEdge(p, srf) : VERY_POSITIVE; + double dp = (pos) ? pos->MinimumDistanceToEdge(p, srf) : VERY_POSITIVE; + + Point2d as = a, bs = b; + ScalePoints(&p, &as, &bs, srf); + double d = p.DistanceToLine(as, bs.Minus(as), /*asSegment=*/true); + + return min(d, min(dn, dp)); +} + diff --git a/src/srf/curve.cpp b/src/srf/curve.cpp new file mode 100644 index 0000000..55496b6 --- /dev/null +++ b/src/srf/curve.cpp @@ -0,0 +1,880 @@ +//----------------------------------------------------------------------------- +// Anything involving curves and sets of curves (except for the real math, +// which is in ratpoly.cpp). +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "../solvespace.h" + +SBezier SBezier::From(Vector4 p0, Vector4 p1) { + SBezier ret = {}; + ret.deg = 1; + ret.weight[0] = p0.w; + ret.ctrl [0] = p0.PerspectiveProject(); + ret.weight[1] = p1.w; + ret.ctrl [1] = p1.PerspectiveProject(); + return ret; +} + +SBezier SBezier::From(Vector4 p0, Vector4 p1, Vector4 p2) { + SBezier ret = {}; + ret.deg = 2; + ret.weight[0] = p0.w; + ret.ctrl [0] = p0.PerspectiveProject(); + ret.weight[1] = p1.w; + ret.ctrl [1] = p1.PerspectiveProject(); + ret.weight[2] = p2.w; + ret.ctrl [2] = p2.PerspectiveProject(); + return ret; +} + +SBezier SBezier::From(Vector4 p0, Vector4 p1, Vector4 p2, Vector4 p3) { + SBezier ret = {}; + ret.deg = 3; + ret.weight[0] = p0.w; + ret.ctrl [0] = p0.PerspectiveProject(); + ret.weight[1] = p1.w; + ret.ctrl [1] = p1.PerspectiveProject(); + ret.weight[2] = p2.w; + ret.ctrl [2] = p2.PerspectiveProject(); + ret.weight[3] = p3.w; + ret.ctrl [3] = p3.PerspectiveProject(); + return ret; +} + +SBezier SBezier::From(Vector p0, Vector p1) { + return SBezier::From(p0.Project4d(), + p1.Project4d()); +} + +SBezier SBezier::From(Vector p0, Vector p1, Vector p2) { + return SBezier::From(p0.Project4d(), + p1.Project4d(), + p2.Project4d()); +} + +SBezier SBezier::From(Vector p0, Vector p1, Vector p2, Vector p3) { + return SBezier::From(p0.Project4d(), + p1.Project4d(), + p2.Project4d(), + p3.Project4d()); +} + +Vector SBezier::Start() const { + return ctrl[0]; +} + +Vector SBezier::Finish() const { + return ctrl[deg]; +} + +void SBezier::Reverse() { + int i; + for(i = 0; i < (deg+1)/2; i++) { + swap(ctrl[i], ctrl[deg-i]); + swap(weight[i], weight[deg-i]); + } +} + +void SBezier::ScaleSelfBy(double s) { + int i; + for(i = 0; i <= deg; i++) { + ctrl[i] = ctrl[i].ScaledBy(s); + } +} + +void SBezier::GetBoundingProjd(Vector u, Vector orig, + double *umin, double *umax) const +{ + int i; + for(i = 0; i <= deg; i++) { + double ut = ((ctrl[i]).Minus(orig)).Dot(u); + if(ut < *umin) *umin = ut; + if(ut > *umax) *umax = ut; + } +} + +SBezier SBezier::TransformedBy(Vector t, Quaternion q, double scale) const { + SBezier ret = *this; + int i; + for(i = 0; i <= deg; i++) { + ret.ctrl[i] = (ret.ctrl[i]).ScaledBy(scale); + ret.ctrl[i] = (q.Rotate(ret.ctrl[i])).Plus(t); + } + return ret; +} + +//----------------------------------------------------------------------------- +// Does this curve lie entirely within the specified plane? It does if all +// the control points lie in that plane. +//----------------------------------------------------------------------------- +bool SBezier::IsInPlane(Vector n, double d) const { + int i; + for(i = 0; i <= deg; i++) { + if(fabs((ctrl[i]).Dot(n) - d) > LENGTH_EPS) { + return false; + } + } + return true; +} + +//----------------------------------------------------------------------------- +// Is this Bezier exactly the arc of a circle, projected along the specified +// axis? If yes, return that circle's center and radius. +//----------------------------------------------------------------------------- +bool SBezier::IsCircle(Vector axis, Vector *center, double *r) const { + if(deg != 2) return false; + + if(ctrl[1].DistanceToLine(ctrl[0], ctrl[2].Minus(ctrl[0])) < LENGTH_EPS) { + // This is almost a line segment. So it's a circle with very large + // radius, which is likely to make code that tries to handle circles + // blow up. So return false. + return false; + } + + Vector t0 = (ctrl[0]).Minus(ctrl[1]), + t2 = (ctrl[2]).Minus(ctrl[1]), + r0 = axis.Cross(t0), + r2 = axis.Cross(t2); + + *center = Vector::AtIntersectionOfLines(ctrl[0], (ctrl[0]).Plus(r0), + ctrl[2], (ctrl[2]).Plus(r2), + NULL, NULL, NULL); + + double rd0 = center->Minus(ctrl[0]).Magnitude(), + rd2 = center->Minus(ctrl[2]).Magnitude(); + if(fabs(rd0 - rd2) > LENGTH_EPS) { + return false; + } + *r = rd0; + + Vector u = r0.WithMagnitude(1), + v = (axis.Cross(u)).WithMagnitude(1); + Point2d c2 = center->Project2d(u, v), + pa2 = (ctrl[0]).Project2d(u, v).Minus(c2), + pb2 = (ctrl[2]).Project2d(u, v).Minus(c2); + + double thetaa = atan2(pa2.y, pa2.x), // in fact always zero due to csys + thetab = atan2(pb2.y, pb2.x), + dtheta = WRAP_NOT_0(thetab - thetaa, 2*PI); + if(dtheta > PI) { + // Not possible with a second order Bezier arc; so we must have + // the points backwards. + dtheta = 2*PI - dtheta; + } + + if(fabs(weight[1] - cos(dtheta/2)) > LENGTH_EPS) { + return false; + } + + return true; +} + +bool SBezier::IsRational() const { + int i; + for(i = 0; i <= deg; i++) { + if(fabs(weight[i] - 1) > LENGTH_EPS) return true; + } + return false; +} + +//----------------------------------------------------------------------------- +// Apply a perspective transformation to a rational Bezier curve, calculating +// the new weights as required. +//----------------------------------------------------------------------------- +SBezier SBezier::InPerspective(Vector u, Vector v, Vector n, + Vector origin, double cameraTan) const +{ + Quaternion q = Quaternion::From(u, v); + q = q.Inverse(); + // we want Q*(p - o) = Q*p - Q*o + SBezier ret = this->TransformedBy(q.Rotate(origin).ScaledBy(-1), q, 1.0); + int i; + for(i = 0; i <= deg; i++) { + Vector4 ct = Vector4::From(ret.weight[i], ret.ctrl[i]); + // so the desired curve, before perspective, is + // (x/w, y/w, z/w) + // and after perspective is + // ((x/w)/(1 - (z/w)*cameraTan, ... + // = (x/(w - z*cameraTan), ... + // so we want to let w' = w - z*cameraTan + ct.w = ct.w - ct.z*cameraTan; + + ret.ctrl[i] = ct.PerspectiveProject(); + ret.weight[i] = ct.w; + } + return ret; +} + +bool SBezier::Equals(SBezier *b) const { + // We just test of identical degree and control points, even though two + // curves could still be coincident (even sharing endpoints). + if(deg != b->deg) return false; + int i; + for(i = 0; i <= deg; i++) { + if(!(ctrl[i]).Equals(b->ctrl[i])) return false; + if(fabs(weight[i] - b->weight[i]) > LENGTH_EPS) return false; + } + return true; +} + +void SBezierList::Clear() { + l.Clear(); +} + +void SBezierList::ScaleSelfBy(double s) { + SBezier *sb; + for(sb = l.First(); sb; sb = l.NextAfter(sb)) { + sb->ScaleSelfBy(s); + } +} + +//----------------------------------------------------------------------------- +// If our list contains multiple identical Beziers (in either forward or +// reverse order), then cull them. If both is true, both beziers are removed. +// Otherwise only one of them is removed. +//----------------------------------------------------------------------------- +void SBezierList::CullIdenticalBeziers(bool both) { + int i, j; + + l.ClearTags(); + for(i = 0; i < l.n; i++) { + SBezier *bi = &(l[i]), bir; + bir = *bi; + bir.Reverse(); + + for(j = i + 1; j < l.n; j++) { + SBezier *bj = &(l[j]); + if(bj->Equals(bi) || + bj->Equals(&bir)) + { + if (both) bi->tag = 1; + bj->tag = 1; + } + } + } + l.RemoveTagged(); +} + +//----------------------------------------------------------------------------- +// Find all the points where a list of Bezier curves intersects another list +// of Bezier curves. We do this by intersecting their piecewise linearizations, +// and then refining any intersections that we find to lie exactly on the +// curves. So this will screw up on tangencies and stuff, but otherwise should +// be fine. +//----------------------------------------------------------------------------- +void SBezierList::AllIntersectionsWith(SBezierList *sblb, SPointList *spl) const { + for(const SBezier *sba = l.First(); sba; sba = l.NextAfter(sba)) { + for(const SBezier *sbb = sblb->l.First(); sbb; sbb = sblb->l.NextAfter(sbb)) { + sbb->AllIntersectionsWith(sba, spl); + } + } +} +void SBezier::AllIntersectionsWith(const SBezier *sbb, SPointList *spl) const { + SPointList splRaw = {}; + SEdgeList sea, seb; + sea = {}; + seb = {}; + this->MakePwlInto(&sea); + sbb ->MakePwlInto(&seb); + SEdge *se; + for(se = sea.l.First(); se; se = sea.l.NextAfter(se)) { + // This isn't quite correct, since AnyEdgeCrossings doesn't count + // the case where two pairs of line segments intersect at their + // vertices. So this isn't robust, although that case isn't very + // likely. + seb.AnyEdgeCrossings(se->a, se->b, NULL, &splRaw); + } + SPoint *sp; + for(sp = splRaw.l.First(); sp; sp = splRaw.l.NextAfter(sp)) { + Vector p = sp->p; + if(PointOnThisAndCurve(sbb, &p)) { + if(!spl->ContainsPoint(p)) spl->Add(p); + } + } + sea.Clear(); + seb.Clear(); + splRaw.Clear(); +} + +//----------------------------------------------------------------------------- +// Find a plane that contains all of the curves in this list. If the curves +// are all colinear (or coincident, or empty), then that plane is not exactly +// determined but we choose the additional degree(s) of freedom arbitrarily. +// Returns true if all the curves are coplanar, otherwise false. +//----------------------------------------------------------------------------- +bool SBezierList::GetPlaneContainingBeziers(Vector *p, Vector *u, Vector *v, + Vector *notCoplanarAt) const +{ + Vector pt, ptFar, ptOffLine, dp, n; + double farMax, offLineMax; + int i; + + // Get any point on any Bezier; or an arbitrary point if list is empty. + if(!l.IsEmpty()) { + pt = l[0].Start(); + } else { + pt = Vector::From(0, 0, 0); + } + ptFar = ptOffLine = pt; + + // Get the point farthest from our arbitrary point. + farMax = VERY_NEGATIVE; + for(const SBezier *sb = l.First(); sb; sb = l.NextAfter(sb)) { + for(i = 0; i <= sb->deg; i++) { + double m = (pt.Minus(sb->ctrl[i])).Magnitude(); + if(m > farMax) { + ptFar = sb->ctrl[i]; + farMax = m; + } + } + } + if(ptFar.Equals(pt)) { + // The points are all coincident. So neither basis vector matters. + *p = pt; + *u = Vector::From(1, 0, 0); + *v = Vector::From(0, 1, 0); + return true; + } + + // Get the point farthest from the line between pt and ptFar + dp = ptFar.Minus(pt); + offLineMax = VERY_NEGATIVE; + for(const SBezier *sb = l.First(); sb; sb = l.NextAfter(sb)) { + for(i = 0; i <= sb->deg; i++) { + double m = (sb->ctrl[i]).DistanceToLine(pt, dp); + if(m > offLineMax) { + ptOffLine = sb->ctrl[i]; + offLineMax = m; + } + } + } + + *p = pt; + if(offLineMax < LENGTH_EPS) { + // The points are all colinear; so choose the second basis vector + // arbitrarily. + *u = (ptFar.Minus(pt)).WithMagnitude(1); + *v = (u->Normal(0)).WithMagnitude(1); + } else { + // The points actually define a plane. + n = (ptFar.Minus(pt)).Cross(ptOffLine.Minus(pt)); + *u = (n.Normal(0)).WithMagnitude(1); + *v = (n.Normal(1)).WithMagnitude(1); + } + + // So we have a plane; but check whether all of the points lie in that + // plane. + n = u->Cross(*v); + n = n.WithMagnitude(1); + double d = p->Dot(n); + for(const SBezier *sb = l.First(); sb; sb = l.NextAfter(sb)) { + for(i = 0; i <= sb->deg; i++) { + if(fabs(n.Dot(sb->ctrl[i]) - d) > LENGTH_EPS) { + if(notCoplanarAt) *notCoplanarAt = sb->ctrl[i]; + return false; + } + } + } + return true; +} + +//----------------------------------------------------------------------------- +// Assemble curves in sbl into a single loop. The curves may appear in any +// direction (start to finish, or finish to start), and will be reversed if +// necessary. The curves in the returned loop are removed from sbl, even if +// the loop cannot be closed. +//----------------------------------------------------------------------------- +SBezierLoop SBezierLoop::FromCurves(SBezierList *sbl, + bool *allClosed, SEdge *errorAt) +{ + SBezierLoop loop = {}; + + if(sbl->l.n < 1) return loop; + sbl->l.ClearTags(); + + SBezier *first = &(sbl->l[0]); + first->tag = 1; + loop.l.Add(first); + Vector start = first->Start(); + Vector hanging = first->Finish(); + int auxA = first->auxA; + + sbl->l.RemoveTagged(); + + while(!sbl->l.IsEmpty() && !hanging.Equals(start)) { + int i; + bool foundNext = false; + for(i = 0; i < sbl->l.n; i++) { + SBezier *test = &(sbl->l[i]); + + if((test->Finish()).Equals(hanging) && test->auxA == auxA) { + test->Reverse(); + // and let the next test catch it + } + if((test->Start()).Equals(hanging) && test->auxA == auxA) { + test->tag = 1; + loop.l.Add(test); + hanging = test->Finish(); + sbl->l.RemoveTagged(); + foundNext = true; + break; + } + } + if(!foundNext) { + // The loop completed without finding the hanging edge, so + // it's an open loop + errorAt->a = hanging; + errorAt->b = start; + *allClosed = false; + return loop; + } + } + if(hanging.Equals(start)) { + *allClosed = true; + } else { + // We ran out of edges without forming a closed loop. + errorAt->a = hanging; + errorAt->b = start; + *allClosed = false; + } + + return loop; +} + +void SBezierLoop::Reverse() { + l.Reverse(); + SBezier *sb; + for(sb = l.First(); sb; sb = l.NextAfter(sb)) { + // If we didn't reverse each curve, then the next curve in list would + // share your start, not your finish. + sb->Reverse(); + } +} + +void SBezierLoop::GetBoundingProjd(Vector u, Vector orig, + double *umin, double *umax) const +{ + for(const SBezier *sb = l.First(); sb; sb = l.NextAfter(sb)) { + sb->GetBoundingProjd(u, orig, umin, umax); + } +} + +void SBezierLoop::MakePwlInto(SContour *sc, double chordTol) const { + for(const SBezier *sb = l.First(); sb; sb = l.NextAfter(sb)) { + sb->MakePwlInto(sc, chordTol); + // Avoid double points at join between Beziers; except that + // first and last points should be identical. + if(l.NextAfter(sb) != NULL) { + sc->l.RemoveLast(1); + } + } + // Ensure that it's exactly closed, not just within a numerical tolerance. + if((sc->l.Last()->p).Equals(sc->l.First()->p)) { + *sc->l.Last() = *sc->l.First(); + } +} + +bool SBezierLoop::IsClosed() const { + if(l.IsEmpty()) return false; + Vector s = l.First()->Start(), + f = l.Last()->Finish(); + return s.Equals(f); +} + + +//----------------------------------------------------------------------------- +// Assemble the curves in sbl into multiple loops, and piecewise linearize the +// curves into poly. If we can't close a contour, then we add it to +// openContours (if that isn't NULL) and keep going; so this works even if the +// input contains a mix of open and closed curves. +//----------------------------------------------------------------------------- +SBezierLoopSet SBezierLoopSet::From(SBezierList *sbl, SPolygon *poly, + double chordTol, + bool *allClosed, SEdge *errorAt, + SBezierLoopSet *openContours) +{ + SBezierLoopSet ret = {}; + + *allClosed = true; + while(!sbl->l.IsEmpty()) { + bool thisClosed; + SBezierLoop loop; + loop = SBezierLoop::FromCurves(sbl, &thisClosed, errorAt); + if(!thisClosed) { + // Record open loops in a separate list, if requested. + *allClosed = false; + if(openContours) { + openContours->l.Add(&loop); + } else { + loop.Clear(); + } + } else { + ret.l.Add(&loop); + poly->AddEmptyContour(); + loop.MakePwlInto(poly->l.Last(), chordTol); + } + } + + poly->normal = poly->ComputeNormal(); + ret.normal = poly->normal; + if(poly->l.n > 0) { + ret.point = poly->AnyPoint(); + } else { + ret.point = Vector::From(0, 0, 0); + } + + return ret; +} + +void SBezierLoopSet::GetBoundingProjd(Vector u, Vector orig, + double *umin, double *umax) const +{ + for(const SBezierLoop *sbl = l.First(); sbl; sbl = l.NextAfter(sbl)) { + sbl->GetBoundingProjd(u, orig, umin, umax); + } +} + +double SBezierLoopSet::SignedArea() { + if(EXACT(area == 0.0)) { + SPolygon sp = {}; + MakePwlInto(&sp); + sp.normal = sp.ComputeNormal(); + area = sp.SignedArea(); + sp.Clear(); + } + return area; +} + +//----------------------------------------------------------------------------- +// Convert all the Beziers into piecewise linear form, and assemble that into +// a polygon, one contour per loop. +//----------------------------------------------------------------------------- +void SBezierLoopSet::MakePwlInto(SPolygon *sp) const { + for(const SBezierLoop *sbl = l.First(); sbl; sbl = l.NextAfter(sbl)) { + sp->AddEmptyContour(); + sbl->MakePwlInto(sp->l.Last()); + } +} + +void SBezierLoopSet::Clear() { + int i; + for(i = 0; i < l.n; i++) { + (l[i]).Clear(); + } + l.Clear(); +} + +//----------------------------------------------------------------------------- +// An export helper function. We start with a list of Bezier curves, and +// assemble them into loops. We find the outer loops, and find the outer loops' +// inner loops, and group them accordingly. +//----------------------------------------------------------------------------- +void SBezierLoopSetSet::FindOuterFacesFrom(SBezierList *sbl, SPolygon *spxyz, + SSurface *srfuv, + double chordTol, + bool *allClosed, SEdge *notClosedAt, + bool *allCoplanar, Vector *notCoplanarAt, + SBezierLoopSet *openContours) +{ + SSurface srfPlane; + if(!srfuv) { + Vector p, u, v; + *allCoplanar = + sbl->GetPlaneContainingBeziers(&p, &u, &v, notCoplanarAt); + if(!*allCoplanar) { + // Don't even try to assemble them into loops if they're not + // all coplanar. + if(openContours) { + SBezier *sb; + for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) { + SBezierLoop sbl={}; + sbl.l.Add(sb); + openContours->l.Add(&sbl); + } + } + return; + } + // All the curves lie in a plane through p with basis vectors u and v. + srfPlane = SSurface::FromPlane(p, u, v); + srfuv = &srfPlane; + } + + int i, j; + // Assemble the Bezier trim curves into closed loops; we also get the + // piecewise linearization of the curves (in the SPolygon spxyz), as a + // calculation aid for the loop direction. + SBezierLoopSet sbls = SBezierLoopSet::From(sbl, spxyz, chordTol, + allClosed, notClosedAt, + openContours); + if(sbls.l.n != spxyz->l.n) return; + + // Convert the xyz piecewise linear to uv piecewise linear. + SPolygon spuv = {}; + SContour *sc; + for(sc = spxyz->l.First(); sc; sc = spxyz->l.NextAfter(sc)) { + spuv.AddEmptyContour(); + SPoint *pt; + for(pt = sc->l.First(); pt; pt = sc->l.NextAfter(pt)) { + double u, v; + srfuv->ClosestPointTo(pt->p, &u, &v); + spuv.l.Last()->AddPoint(Vector::From(u, v, 0)); + } + } + spuv.normal = Vector::From(0, 0, 1); // must be, since it's in xy plane now + + static const int OUTER_LOOP = 10; + static const int INNER_LOOP = 20; + static const int USED_LOOP = 30; + // Fix the contour directions; we do this properly, in uv space, so it + // works for curved surfaces too (important for STEP export). + spuv.FixContourDirections(); + for(i = 0; i < spuv.l.n; i++) { + SContour *contour = &(spuv.l[i]); + SBezierLoop *bl = &(sbls.l[i]); + if(contour->tag) { + // This contour got reversed in the polygon to make the directions + // consistent, so the same must be necessary for the Bezier loop. + bl->Reverse(); + } + if(contour->IsClockwiseProjdToNormal(spuv.normal)) { + bl->tag = INNER_LOOP; + } else { + bl->tag = OUTER_LOOP; + } + } + + bool loopsRemaining = true; + while(loopsRemaining) { + loopsRemaining = false; + for(i = 0; i < sbls.l.n; i++) { + SBezierLoop *loop = &(sbls.l[i]); + if(loop->tag != OUTER_LOOP) continue; + + // Check if this contour contains any outer loops; if it does, then + // we should do those "inner outer loops" first; otherwise we + // will steal their holes, since their holes also lie inside this + // contour. + for(j = 0; j < sbls.l.n; j++) { + SBezierLoop *outer = &(sbls.l[j]); + if(i == j) continue; + if(outer->tag != OUTER_LOOP) continue; + + Vector p = spuv.l[j].AnyEdgeMidpoint(); + if(spuv.l[i].ContainsPointProjdToNormal(spuv.normal, p)) { + break; + } + } + if(j < sbls.l.n) { + // It does, can't do this one yet. + continue; + } + + SBezierLoopSet outerAndInners = {}; + loopsRemaining = true; + loop->tag = USED_LOOP; + outerAndInners.l.Add(loop); + int auxA = 0; + if(loop->l.n > 0) auxA = loop->l[0].auxA; + + for(j = 0; j < sbls.l.n; j++) { + SBezierLoop *inner = &(sbls.l[j]); + if(inner->tag != INNER_LOOP) continue; + if(inner->l.n < 1) continue; + if(inner->l[0].auxA != auxA) continue; + + Vector p = spuv.l[j].AnyEdgeMidpoint(); + if(spuv.l[i].ContainsPointProjdToNormal(spuv.normal, p)) { + outerAndInners.l.Add(inner); + inner->tag = USED_LOOP; + } + } + + outerAndInners.point = srfuv->PointAt(0, 0); + outerAndInners.normal = srfuv->NormalAt(0, 0); + l.Add(&outerAndInners); + } + } + + // If we have poorly-formed loops--for example, overlapping zero-area + // stuff--then we can end up with leftovers. We use this function to + // group stuff into closed paths for export when possible, so it's bad + // to screw up on that stuff. So just add them onto the open curve list. + // Very ugly, but better than losing curves. + for(i = 0; i < sbls.l.n; i++) { + SBezierLoop *loop = &(sbls.l[i]); + if(loop->tag == USED_LOOP) continue; + + if(openContours) { + openContours->l.Add(loop); + } else { + loop->Clear(); + } + // but don't free the used loops, since we shallow-copied them to + // ourself + } + + sbls.l.Clear(); // not sbls.Clear(), since that would deep-clear + spuv.Clear(); +} + +void SBezierLoopSetSet::AddOpenPath(SBezier *sb) { + SBezierLoop sbl = {}; + sbl.l.Add(sb); + + SBezierLoopSet sbls = {}; + sbls.l.Add(&sbl); + + l.Add(&sbls); +} + +void SBezierLoopSetSet::Clear() { + SBezierLoopSet *sbls; + for(sbls = l.First(); sbls; sbls = l.NextAfter(sbls)) { + sbls->Clear(); + } + l.Clear(); +} + +SCurve SCurve::FromTransformationOf(SCurve *a, Vector t, + Quaternion q, double scale) +{ + bool needRotate = !EXACT(q.vx == 0.0 && q.vy == 0.0 && q.vz == 0.0 && q.w == 1.0); + bool needTranslate = !EXACT(t.x == 0.0 && t.y == 0.0 && t.z == 0.0); + bool needScale = !EXACT(scale == 1.0); + + SCurve ret = {}; + ret.h = a->h; + ret.isExact = a->isExact; + ret.exact = (a->exact).TransformedBy(t, q, scale); + ret.surfA = a->surfA; + ret.surfB = a->surfB; + + SCurvePt *p; + ret.pts.ReserveMore(a->pts.n); + for(p = a->pts.First(); p; p = a->pts.NextAfter(p)) { + SCurvePt pp = *p; + if(needScale) { + pp.p = (pp.p).ScaledBy(scale); + } + if(needRotate) { + pp.p = q.Rotate(pp.p); + } + if(needTranslate) { + pp.p = pp.p.Plus(t); + } + ret.pts.Add(&pp); + } + return ret; +} + +void SCurve::Clear() { + pts.Clear(); +} + +SSurface *SCurve::GetSurfaceA(SShell *a, SShell *b) const { + if(source == Source::A) { + return a->surface.FindById(surfA); + } else if(source == Source::B) { + return b->surface.FindById(surfA); + } else if(source == Source::INTERSECTION) { + return a->surface.FindById(surfA); + } else ssassert(false, "Unexpected curve source"); +} + +SSurface *SCurve::GetSurfaceB(SShell *a, SShell *b) const { + if(source == Source::A) { + return a->surface.FindById(surfB); + } else if(source == Source::B) { + return b->surface.FindById(surfB); + } else if(source == Source::INTERSECTION) { + return b->surface.FindById(surfB); + } else ssassert(false, "Unexpected curve source"); +} + +//----------------------------------------------------------------------------- +// When we split line segments wherever they intersect a surface, we introduce +// extra pwl points. This may create very short edges that could be removed +// without violating the chord tolerance. Those are ugly, and also break +// stuff in the Booleans. So remove them. +//----------------------------------------------------------------------------- +void SCurve::RemoveShortSegments(SSurface *srfA, SSurface *srfB) { + if(pts.n <= 2) return; + pts.ClearTags(); + + Vector prev = pts[0].p; + double tprev = 0; + double t = 0; + double tnext = 0; + + int i, a; + for(i = 1; i < pts.n - 1; i++) { + SCurvePt *sct = &(pts[i]), + *scn = &(pts[i+1]); + + if(sct->vertex) { + prev = sct->p; + continue; + } + + // if the curve is exact and points are >0.05 appart wrt t, point is there + // deliberately regardless of chord tolerance (ex: small circles) + tprev = t = tnext = 0; + if (isExact) { + exact.ClosestPointTo(prev, &tprev, /*mustconverge=*/ true); + exact.ClosestPointTo(sct->p, &t, /*mustconverge=*/ true); + exact.ClosestPointTo(scn->p, &tnext, /*mustconverge=*/ true); + } + if ( (t - tprev > 0.05) && (tnext - t > 0.05) ) { + prev = sct->p; + continue; + } + + bool mustKeep = false; + + // We must check against both surfaces; the piecewise linear edge + // may have a different chord tolerance in the two surfaces. (For + // example, a circle in the surface of a cylinder is just a straight + // line, so it always has perfect chord tol, but that circle in + // a plane is a circle so it doesn't). + for(a = 0; a < 2; a++) { + SSurface *srf = (a == 0) ? srfA : srfB; + Vector puv, nuv; + srf->ClosestPointTo(prev, &(puv.x), &(puv.y)); + srf->ClosestPointTo(scn->p, &(nuv.x), &(nuv.y)); + + if(srf->ChordToleranceForEdge(nuv, puv) > SS.ChordTolMm() ) { + mustKeep = true; + } + } + + if(mustKeep) { + prev = sct->p; + } else { + sct->tag = 1; + // and prev is unchanged, since there's no longer any point + // in between + } + } + + pts.RemoveTagged(); +} + +STrimBy STrimBy::EntireCurve(SShell *shell, hSCurve hsc, bool backwards) { + STrimBy stb = {}; + stb.curve = hsc; + SCurve *sc = shell->curve.FindById(hsc); + + if(backwards) { + stb.finish = sc->pts[0].p; + stb.start = sc->pts.Last()->p; + stb.backwards = true; + } else { + stb.start = sc->pts[0].p; + stb.finish = sc->pts.Last()->p; + stb.backwards = false; + } + + return stb; +} + diff --git a/src/srf/merge.cpp b/src/srf/merge.cpp new file mode 100644 index 0000000..a91a307 --- /dev/null +++ b/src/srf/merge.cpp @@ -0,0 +1,128 @@ +//----------------------------------------------------------------------------- +// Routines to merge multiple coincident surfaces (each with their own trim +// curves) into a single surface, with all of the trim curves. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "../solvespace.h" + +void SShell::MergeCoincidentSurfaces() { + surface.ClearTags(); + + int i, j; + SSurface *si, *sj; + + for(i = 0; i < surface.n; i++) { + si = &(surface[i]); + if(si->tag) continue; + // Let someone else clean up the empty surfaces; we can certainly merge + // them, but we don't know how to calculate a reasonable bounding box. + if(si->trim.IsEmpty()) + continue; + // And for now we handle only coincident planes, so no sense wasting + // time on other surfaces. + if(si->degm != 1 || si->degn != 1) continue; + + SEdgeList sel = {}; + si->MakeEdgesInto(this, &sel, SSurface::MakeAs::XYZ); + + bool mergedThisTime, merged = false; + do { + mergedThisTime = false; + + for(j = i + 1; j < surface.n; j++) { + sj = &(surface[j]); + if(sj->tag) continue; + if(!sj->CoincidentWith(si, /*sameNormal=*/true)) continue; + if(!sj->color.Equals(si->color)) continue; + // But we do merge surfaces with different face entities, since + // otherwise we'd hardly ever merge anything. + + // This surface is coincident. But let's not merge coincident + // surfaces if they contain disjoint contours; that just makes + // the bounding box tests less effective, and possibly things + // less robust. + SEdgeList tel = {}; + sj->MakeEdgesInto(this, &tel, SSurface::MakeAs::XYZ); + if(!sel.ContainsEdgeFrom(&tel)) { + tel.Clear(); + continue; + } + tel.Clear(); + + sj->tag = 1; + merged = true; + mergedThisTime = true; + sj->MakeEdgesInto(this, &sel, SSurface::MakeAs::XYZ); + sj->trim.Clear(); + + // All the references to this surface get replaced with the + // new srf + SCurve *sc; + for(sc = curve.First(); sc; sc = curve.NextAfter(sc)) { + if(sc->surfA == sj->h) sc->surfA = si->h; + if(sc->surfB == sj->h) sc->surfB = si->h; + } + } + + // If this iteration merged a contour onto ours, then we have to + // go through the surfaces again; that might have made a new + // surface touch us. + } while(mergedThisTime); + + if(merged) { + sel.CullExtraneousEdges(); + si->trim.Clear(); + si->TrimFromEdgeList(&sel, /*asUv=*/false); + + // And we must choose control points such that all the trims lie + // with u and v in [0, 1], so that the bbox tests work. + Vector u, v, n; + si->TangentsAt(0.5, 0.5, &u, &v); + u = u.WithMagnitude(1); + v = v.WithMagnitude(1); + n = si->NormalAt(0.5, 0.5).WithMagnitude(1); + v = (n.Cross(u)).WithMagnitude(1); + + double umax = VERY_NEGATIVE, umin = VERY_POSITIVE, + vmax = VERY_NEGATIVE, vmin = VERY_POSITIVE; + SEdge *se; + for(se = sel.l.First(); se; se = sel.l.NextAfter(se)) { + double ut = (se->a).Dot(u), vt = (se->a).Dot(v); + umax = max(umax, ut); + vmax = max(vmax, vt); + umin = min(umin, ut); + vmin = min(vmin, vt); + } + + // An interesting problem here; the real curve could extend + // slightly beyond the bounding box of the piecewise linear + // bits. Not a problem for us, but some apps won't import STEP + // in that case. So give a bit of extra room; in theory just + // a chord tolerance, but more can't hurt. + double muv = max((umax - umin), (vmax - vmin)); + double tol = muv/50 + 3*SS.ChordTolMm(); + umax += tol; + vmax += tol; + umin -= tol; + vmin -= tol; + + // We move in the +v direction as v goes from 0 to 1, and in the + // +u direction as u goes from 0 to 1. So our normal ends up + // pointed the same direction. + double nt = (si->ctrl[0][0]).Dot(n); + si->ctrl[0][0] = + Vector::From(umin, vmin, nt).ScaleOutOfCsys(u, v, n); + si->ctrl[0][1] = + Vector::From(umin, vmax, nt).ScaleOutOfCsys(u, v, n); + si->ctrl[1][1] = + Vector::From(umax, vmax, nt).ScaleOutOfCsys(u, v, n); + si->ctrl[1][0] = + Vector::From(umax, vmin, nt).ScaleOutOfCsys(u, v, n); + } + sel.Clear(); + } + + surface.RemoveTagged(); +} + diff --git a/src/srf/ratpoly.cpp b/src/srf/ratpoly.cpp new file mode 100644 index 0000000..46180a5 --- /dev/null +++ b/src/srf/ratpoly.cpp @@ -0,0 +1,701 @@ +//----------------------------------------------------------------------------- +// Math on rational polynomial surfaces and curves, typically in Bezier +// form. Evaluate, root-find (by Newton's methods), evaluate derivatives, +// and so on. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "../solvespace.h" + +// Converge it to better than LENGTH_EPS; we want two points, each +// independently projected into uv and back, to end up equal with the +// LENGTH_EPS. Best case that requires LENGTH_EPS/2, but more is better +// and convergence should be fast by now. +#define RATPOLY_EPS (LENGTH_EPS/(1e2)) + +static inline double Bernstein(int k, int deg, double t) { +// indexed by [degree][k][exponent] + static const double bernstein_coeff[4][4][4] = { + { { 1.0,0.0,0.0,0.0 }, { 1.0,0.0,0.0,0.0 }, { 1.0,0.0,0.0,0.0 }, { 1.0,0.0,0.0,0.0 } }, + { { 1.0,-1.0,0.0,0.0 }, { 0.0,1.0,0.0,0.0 }, { 0.0,0.0,0.0,0.0 }, { 0.0,0.0,0.0,0.0 } }, + { { 1.0,-2.0,1.0,0.0 }, { 0.0,2.0,-2.0,0.0 },{ 0.0,0.0,1.0,0.0 }, { 0.0,0.0,0.0,0.0 } }, + { { 1.0,-3.0,3.0,-1.0 },{ 0.0,3.0,-6.0,3.0 },{ 0.0,0.0,3.0,-3.0}, { 0.0,0.0,0.0,1.0 } } }; + + const double *c = bernstein_coeff[deg][k]; + return (((c[3]*t+c[2])*t)+c[1])*t+c[0]; +} + +static inline double BernsteinDerivative(int k, int deg, double t) { + static const double bernstein_derivative_coeff[4][4][3] = { + { { 0.0,0.0,0.0 }, { 0.0,0.0,0.0 }, { 0.0,0.0,0.0 }, { 0.0,0.0,0.0 } }, + { { -1.0,0.0,0.0 }, { 1.0,0.0,0.0 }, { 0.0,0.0,0.0 }, { 0.0,0.0,0.0 } }, + { { -2.0,2.0,0.0 }, { 2.0,-4.0,0.0 },{ 0.0,2.0,0.0 }, { 0.0,0.0,0.0 } }, + { { -3.0,6.0,-3.0 },{ 3.0,-12.0,9.0 },{ 0.0,6.0,-9.0}, { 0.0,0.0,3.0 } } }; + + const double *c = bernstein_derivative_coeff[deg][k]; + return ((c[2]*t)+c[1])*t+c[0]; +} + +Vector SBezier::PointAt(double t) const { + Vector pt = Vector::From(0, 0, 0); + double d = 0; + + int i; + for(i = 0; i <= deg; i++) { + double B = Bernstein(i, deg, t); + pt = pt.Plus(ctrl[i].ScaledBy(B*weight[i])); + d += weight[i]*B; + } + pt = pt.ScaledBy(1.0/d); + return pt; +} + +Vector SBezier::TangentAt(double t) const { + Vector pt = Vector::From(0, 0, 0), pt_p = Vector::From(0, 0, 0); + double d = 0, d_p = 0; + + int i; + for(i = 0; i <= deg; i++) { + double B = Bernstein(i, deg, t), + Bp = BernsteinDerivative(i, deg, t); + + pt = pt.Plus(ctrl[i].ScaledBy(B*weight[i])); + d += weight[i]*B; + + pt_p = pt_p.Plus(ctrl[i].ScaledBy(Bp*weight[i])); + d_p += weight[i]*Bp; + } + + // quotient rule; f(t) = n(t)/d(t), so f' = (n'*d - n*d')/(d^2) + Vector ret; + ret = (pt_p.ScaledBy(d)).Minus(pt.ScaledBy(d_p)); + ret = ret.ScaledBy(1.0/(d*d)); + return ret; +} + +void SBezier::ClosestPointTo(Vector p, double *t, bool mustConverge) const { + int i; + double minDist = VERY_POSITIVE; + *t = 0; + double res = (deg <= 2) ? 7.0 : 20.0; + for(i = 0; i < (int)res; i++) { + double tryt = (i/res); + + Vector tryp = PointAt(tryt); + double d = (tryp.Minus(p)).Magnitude(); + if(d < minDist) { + *t = tryt; + minDist = d; + } + } + + Vector p0; + for(i = 0; i < (mustConverge ? 15 : 5); i++) { + p0 = PointAt(*t); + if(p0.Equals(p, RATPOLY_EPS)) { + return; + } + + Vector dp = TangentAt(*t); + Vector pc = p.ClosestPointOnLine(p0, dp); + *t += (pc.Minus(p0)).DivProjected(dp); + } + if(mustConverge) { + dbp("didn't converge (closest point on bezier curve)"); + } +} + +bool SBezier::PointOnThisAndCurve(const SBezier *sbb, Vector *p) const { + double ta, tb; + this->ClosestPointTo(*p, &ta, /*mustConverge=*/false); + sbb ->ClosestPointTo(*p, &tb, /*mustConverge=*/false); + + int i; + for(i = 0; i < 20; i++) { + Vector pa = this->PointAt(ta), + pb = sbb ->PointAt(tb), + da = this->TangentAt(ta), + db = sbb ->TangentAt(tb); + + if(pa.Equals(pb, RATPOLY_EPS)) { + *p = pa; + return true; + } + + double tta, ttb; + Vector::ClosestPointBetweenLines(pa, da, pb, db, &tta, &ttb); + ta += tta; + tb += ttb; + } + return false; +} + +void SBezier::SplitAt(double t, SBezier *bef, SBezier *aft) const { + Vector4 ct[4]; + int i; + for(i = 0; i <= deg; i++) { + ct[i] = Vector4::From(weight[i], ctrl[i]); + } + + switch(deg) { + case 1: { + Vector4 cts = Vector4::Blend(ct[0], ct[1], t); + *bef = SBezier::From(ct[0], cts); + *aft = SBezier::From(cts, ct[1]); + break; + } + case 2: { + Vector4 ct01 = Vector4::Blend(ct[0], ct[1], t), + ct12 = Vector4::Blend(ct[1], ct[2], t), + cts = Vector4::Blend(ct01, ct12, t); + + *bef = SBezier::From(ct[0], ct01, cts); + *aft = SBezier::From(cts, ct12, ct[2]); + break; + } + case 3: { + Vector4 ct01 = Vector4::Blend(ct[0], ct[1], t), + ct12 = Vector4::Blend(ct[1], ct[2], t), + ct23 = Vector4::Blend(ct[2], ct[3], t), + ct01_12 = Vector4::Blend(ct01, ct12, t), + ct12_23 = Vector4::Blend(ct12, ct23, t), + cts = Vector4::Blend(ct01_12, ct12_23, t); + + *bef = SBezier::From(ct[0], ct01, ct01_12, cts); + *aft = SBezier::From(cts, ct12_23, ct23, ct[3]); + break; + } + default: ssassert(false, "Unexpected degree of spline"); + } +} + +void SBezier::MakePwlInto(SEdgeList *sel, double chordTol, double max_dt) const { + List lv = {}; + MakePwlInto(&lv, chordTol, max_dt); + int i; + for(i = 1; i < lv.n; i++) { + sel->AddEdge(lv[i-1], lv[i]); + } + lv.Clear(); +} +void SBezier::MakePwlInto(List *l, double chordTol, double max_dt) const { + List lv = {}; + MakePwlInto(&lv, chordTol, max_dt); + int i; + for(i = 0; i < lv.n; i++) { + SCurvePt scpt; + scpt.tag = 0; + scpt.p = lv[i]; + scpt.vertex = (i == 0) || (i == (lv.n - 1)); + l->Add(&scpt); + } + lv.Clear(); +} +void SBezier::MakePwlInto(SContour *sc, double chordTol, double max_dt) const { + List lv = {}; + MakePwlInto(&lv, chordTol, max_dt); + int i; + for(i = 0; i < lv.n; i++) { + sc->AddPoint(lv[i]); + } + lv.Clear(); +} +//-------------------------------------------------------------------------------------- +// all variants of MakePwlInto come here. Split a rational Bezier into Piecewise Linear +// segments that don't deviate from the actual curve by more than the chordTol distance. +// max_dt allows to force curves to be split into spans of no more than a certain +// length based on t-parameter. RemoveShortSegments() may delete points when dt <= 0.1 +//-------------------------------------------------------------------------------------- +void SBezier::MakePwlInto(List *l, double chordTol, double max_dt) const { + if(EXACT(chordTol == 0)) { + // Use the default chord tolerance. + chordTol = SS.ChordTolMm(); + } + // Never do fewer than three intermediate points for curves; people seem to get + // unhappy when their circles turn into squares, but maybe less + // unhappy with octagons. Now 16-gons. + if (EXACT(max_dt == 0.0)) { + max_dt = (deg == 1) ? 1.0 : 0.25; + } + l->Add(&(ctrl[0])); + // don't split first degee (lines) unless asked to by the caller via max_dt + if((deg == 1) && (max_dt >= 1.0)) { + l->Add(&(ctrl[1])); + } else { + MakePwlInitialWorker(l, 0.0, 0.5, chordTol, max_dt); + MakePwlInitialWorker(l, 0.5, 1.0, chordTol, max_dt); + } +} +void SBezier::MakePwlWorker(List *l, double ta, double tb, double chordTol, double max_dt) const +{ + Vector pa = PointAt(ta); + Vector pb = PointAt(tb); + + Vector pm = PointAt((ta + tb) / 2.0); + double d = pm.DistanceToLine(pa, pb.Minus(pa)); + + double step = 1.0/SS.GetMaxSegments(); + if(((tb - ta) < step || d < chordTol) && ((tb-ta) <= max_dt) ) { + // A previous call has already added the beginning of our interval. + l->Add(&pb); + } else { + double tm = (ta + tb) / 2; + MakePwlWorker(l, ta, tm, chordTol, max_dt); + MakePwlWorker(l, tm, tb, chordTol, max_dt); + } +} +void SBezier::MakePwlInitialWorker(List *l, double ta, double tb, double chordTol, double max_dt) const +{ + Vector pa = PointAt(ta); + Vector pb = PointAt(tb); + + double tm1 = ta + (tb - ta) * 0.25; + double tm2 = ta + (tb - ta) * 0.5; + double tm3 = ta + (tb - ta) * 0.75; + + Vector pm1 = PointAt(tm1); + Vector pm2 = PointAt(tm2); + Vector pm3 = PointAt(tm3); + Vector dir = pb.Minus(pa); + + double d = max({ + pm1.DistanceToLine(pa, dir), + pm2.DistanceToLine(pa, dir), + pm3.DistanceToLine(pa, dir) + }); + + double step = 1.0/SS.GetMaxSegments(); + if( ((tb - ta) < step || d < chordTol) && ((tb-ta) <= max_dt) ) { + // A previous call has already added the beginning of our interval. + l->Add(&pb); + } else { + double tm = (ta + tb) / 2; + MakePwlWorker(l, ta, tm, chordTol, max_dt); + MakePwlWorker(l, tm, tb, chordTol, max_dt); + } +} + +void SBezier::MakeNonrationalCubicInto(SBezierList *bl, double tolerance, int depth) const { + Vector t0 = TangentAt(0), t1 = TangentAt(1); + // The curve is correct, and the first derivatives are correct, at the + // endpoints. + SBezier bnr = SBezier::From( + Start(), + Start().Plus(t0.ScaledBy(1.0/3)), + Finish().Minus(t1.ScaledBy(1.0/3)), + Finish()); + + bool closeEnough = true; + int i; + for(i = 1; i <= 3; i++) { + double t = i/4.0; + Vector p0 = PointAt(t), + pn = bnr.PointAt(t); + double d = (p0.Minus(pn)).Magnitude(); + if(d > tolerance) { + closeEnough = false; + } + } + + if(closeEnough || depth > 3) { + bl->l.Add(this); + } else { + SBezier bef, aft; + SplitAt(0.5, &bef, &aft); + bef.MakeNonrationalCubicInto(bl, tolerance, depth+1); + aft.MakeNonrationalCubicInto(bl, tolerance, depth+1); + } +} + +Vector SSurface::PointAt(Point2d puv) const { + return PointAt(puv.x, puv.y); +} +Vector SSurface::PointAt(double u, double v) const { + Vector num = Vector::From(0, 0, 0); + double den = 0; + + int i, j; + for(i = 0; i <= degm; i++) { + for(j = 0; j <= degn; j++) { + double Bi = Bernstein(i, degm, u), + Bj = Bernstein(j, degn, v); + + num = num.Plus(ctrl[i][j].ScaledBy(Bi*Bj*weight[i][j])); + den += weight[i][j]*Bi*Bj; + } + } + num = num.ScaledBy(1.0/den); + return num; +} + +void SSurface::TangentsAt(double u, double v, Vector *tu, Vector *tv, bool retry) const { + Vector num = Vector::From(0, 0, 0), + num_u = Vector::From(0, 0, 0), + num_v = Vector::From(0, 0, 0); + double den = 0, + den_u = 0, + den_v = 0; + + int i, j; + for(i = 0; i <= degm; i++) { + for(j = 0; j <= degn; j++) { + double Bi = Bernstein(i, degm, u), + Bj = Bernstein(j, degn, v), + Bip = BernsteinDerivative(i, degm, u), + Bjp = BernsteinDerivative(j, degn, v); + + num = num.Plus(ctrl[i][j].ScaledBy(Bi*Bj*weight[i][j])); + den += weight[i][j]*Bi*Bj; + + num_u = num_u.Plus(ctrl[i][j].ScaledBy(Bip*Bj*weight[i][j])); + den_u += weight[i][j]*Bip*Bj; + + num_v = num_v.Plus(ctrl[i][j].ScaledBy(Bi*Bjp*weight[i][j])); + den_v += weight[i][j]*Bi*Bjp; + } + } + // quotient rule; f(t) = n(t)/d(t), so f' = (n'*d - n*d')/(d^2) + *tu = ((num_u.ScaledBy(den)).Minus(num.ScaledBy(den_u))); + *tu = tu->ScaledBy(1.0/(den*den)); + + *tv = ((num_v.ScaledBy(den)).Minus(num.ScaledBy(den_v))); + *tv = tv->ScaledBy(1.0/(den*den)); + + // Tangent is zero at sungularities like the north pole. Move away a bit and retry. + if(tv->Equals(Vector::From(0,0,0)) && retry) + TangentsAt(u+(0.5-u)*0.00001, v, tu, tv, false); + if(tu->Equals(Vector::From(0,0,0)) && retry) + TangentsAt(u, v+(0.5-v)*0.00001, tu, tv, false); +} + +Vector SSurface::NormalAt(Point2d puv) const { + return NormalAt(puv.x, puv.y); +} + +Vector SSurface::NormalAt(double u, double v) const { + Vector tu, tv; + TangentsAt(u, v, &tu, &tv); + return tu.Cross(tv); +} + +void SSurface::ClosestPointTo(Vector p, Point2d *puv, bool mustConverge) { + ClosestPointTo(p, &(puv->x), &(puv->y), mustConverge); +} + +void SSurface::ClosestPointTo(Vector p, double *u, double *v, bool mustConverge) { + // A few special cases first; when control points are coincident the + // derivative goes to zero at the control points, and would result in + // nonconvergence. We avoid that here, and also guarantee a consistent + // (u, v) (of the infinitely many possible in one parameter). + if(p.Equals(ctrl[0] [0] )) { *u = 0; *v = 0; return; } + if(p.Equals(ctrl[degm][0] )) { *u = 1; *v = 0; return; } + if(p.Equals(ctrl[degm][degn])) { *u = 1; *v = 1; return; } + if(p.Equals(ctrl[0] [degn])) { *u = 0; *v = 1; return; } + + // And planes are trivial, so don't waste time iterating over those. + if(degm == 1 && degn == 1) { + Vector orig = ctrl[0][0], + bu = (ctrl[1][0]).Minus(orig), + bv = (ctrl[0][1]).Minus(orig); + if((ctrl[1][1]).Equals(orig.Plus(bu).Plus(bv))) { + + Vector n = bu.Cross(bv); + Vector ty = n.Cross(bu).ScaledBy(1.0/bu.MagSquared()); + Vector tx = bv.Cross(n).ScaledBy(1.0/bv.MagSquared()); + + Vector dp = p.Minus(orig); + *u = dp.Dot(bu) / tx.MagSquared(); + *v = dp.Dot(bv) / ty.MagSquared(); + return; + } + } + + // Try whatever the previous guess was. This is likely to do something + // good if we're working our way along a curve or something else where + // we project successive points that are close to each other; something + // like a 20% speedup empirically. + if(mustConverge) { + double ut = cached.x, vt = cached.y; + if(ClosestPointNewton(p, &ut, &vt, mustConverge)) { + cached.x = *u = ut; + cached.y = *v = vt; + return; + } + } + + // Search for a reasonable initial guess + int i, j; + double minDist = VERY_POSITIVE; + int res = (max(degm, degn) == 2) ? 7 : 20; + for(i = 0; i < res; i++) { + for(j = 0; j < res; j++) { + double tryu = (i + 0.5)/res, tryv = (j + 0.5)/res; + + Vector tryp = PointAt(tryu, tryv); + double d = (tryp.Minus(p)).Magnitude(); + if(d < minDist) { + *u = tryu; + *v = tryv; + minDist = d; + } + } + } + + if(ClosestPointNewton(p, u, v, mustConverge)) { + cached.x = *u; + cached.y = *v; + return; + } + + // If we failed to converge, then at least don't return NaN. + if(mustConverge) { +// This is expected not to converge when the target point is not on the surface but nearby. +// let's not pollute the output window for normal use. +// Vector p0 = PointAt(*u, *v); +// dbp("didn't converge"); +// dbp("have %.3f %.3f %.3f", CO(p0)); +// dbp("want %.3f %.3f %.3f", CO(p)); +// dbp("distance = %g", (p.Minus(p0)).Magnitude()); + } + if(IsReasonable(*u) || IsReasonable(*v)) { + *u = *v = 0; + } +} + +bool SSurface::ClosestPointNewton(Vector p, double *u, double *v, bool mustConverge) const +{ + // Initial guess is in u, v; refine by Newton iteration. + Vector p0 = Vector::From(0, 0, 0); + for(int i = 0; i < (mustConverge ? 25 : 5); i++) { + p0 = PointAt(*u, *v); + if(mustConverge) { + if(p0.Equals(p, RATPOLY_EPS)) { + return true; + } + } + + Vector tu, tv, tx, ty; + TangentsAt(*u, *v, &tu, &tv); + Vector n = tu.Cross(tv); + // since tu and tv may not be orthogonal, use y in place of v. + // |y| = |v|sin(theta) where theta is the angle between tu and tv. + ty = n.Cross(tu).ScaledBy(1.0/tu.MagSquared()); + tx = tv.Cross(n).ScaledBy(1.0/tv.MagSquared()); + + // Project the point into a plane through p0, with basis tu, tv; a + // second-order thing would converge faster but needs second + // derivatives. + Vector dp = p.Minus(p0); + double du = dp.Dot(tx), + dv = dp.Dot(ty); + *u += du / (tx.MagSquared()); + *v += dv / (ty.MagSquared()); + + if (*u < 0.0) *u = 0.0; + else if (*u > 1.0) *u = 1.0; + if (*v < 0.0) *v = 0.0; + else if (*v > 1.0) *v = 1.0; + + } + + return false; +} + +bool SSurface::PointIntersectingLine(Vector p0, Vector p1, double *u, double *v) const +{ + int i; + for(i = 0; i < 20; i++) { + Vector pi, p, tu, tv; + p = PointAt(*u, *v); + TangentsAt(*u, *v, &tu, &tv); + + Vector n = (tu.Cross(tv)).WithMagnitude(1); + double d = p.Dot(n); + + bool parallel; + pi = Vector::AtIntersectionOfPlaneAndLine(n, d, p0, p1, ¶llel); + if(parallel) { + dbp("parallel (surface intersecting line)"); + break; + } + + // Check for convergence + if(pi.Equals(p, RATPOLY_EPS)) return true; + + n = tu.Cross(tv); + Vector ty = n.Cross(tu).ScaledBy(1.0/tu.MagSquared()); + Vector tx = tv.Cross(n).ScaledBy(1.0/tv.MagSquared()); + + // Adjust our guess and iterate + Vector dp = pi.Minus(p); + double du = dp.Dot(tx), dv = dp.Dot(ty); + *u += du / tx.MagSquared(); + *v += dv / ty.MagSquared(); + } + dbp("didn't converge (surface intersecting line)"); + return false; +} + +Vector SSurface::ClosestPointOnThisAndSurface(SSurface *srf2, Vector p) { + // This is untested. + int i, j; + Point2d puv[2]; + SSurface *srf[2] = { this, srf2 }; + + for(j = 0; j < 2; j++) { + (srf[j])->ClosestPointTo(p, &(puv[j]), /*mustConverge=*/false); + } + + for(i = 0; i < 10; i++) { + Vector tu[2], tv[2], cp[2], n[2]; + double d[2]; + + for(j = 0; j < 2; j++) { + (srf[j])->TangentsAt(puv[j].x, puv[j].y, &(tu[j]), &(tv[j])); + + cp[j] = (srf[j])->PointAt(puv[j]); + + n[j] = ((tu[j]).Cross(tv[j])).WithMagnitude(1); + d[j] = (n[j]).Dot(cp[j]); + } + + if((cp[0]).Equals(cp[1], RATPOLY_EPS)) break; + + Vector p0 = Vector::AtIntersectionOfPlanes(n[0], d[0], n[1], d[1]), + dp = (n[0]).Cross(n[1]); + + Vector pc = p.ClosestPointOnLine(p0, dp); + + // Adjust our guess and iterate + for(j = 0; j < 2; j++) { + Vector n = tu[j].Cross(tv[j]); + Vector ty = n.Cross(tu[j]).ScaledBy(1.0/tu[j].MagSquared()); + Vector tx = tv[j].Cross(n).ScaledBy(1.0/tv[j].MagSquared()); + + Vector dc = pc.Minus(cp[j]); + double du = dc.Dot(tx), dv = dc.Dot(ty); + puv[j].x += du / tx.MagSquared(); + puv[j].y += dv / ty.MagSquared(); + } + } + if(i >= 10) { + dbp("this and srf, didn't converge, d=%g", + (puv[0].Minus(puv[1])).Magnitude()); + } + + // If this converged, then the two points are actually equal. + return ((srf[0])->PointAt(puv[0])).Plus( + ((srf[1])->PointAt(puv[1]))).ScaledBy(0.5); +} + +void SSurface::PointOnSurfaces(SSurface *s1, SSurface *s2, double *up, double *vp) +{ + double u[3] = { *up, 0, 0 }, v[3] = { *vp, 0, 0 }; + SSurface *srf[3] = { this, s1, s2 }; + + // Get initial guesses for (u, v) in the other surfaces + Vector p = PointAt(*u, *v); + (srf[1])->ClosestPointTo(p, &(u[1]), &(v[1]), /*mustConverge=*/false); + (srf[2])->ClosestPointTo(p, &(u[2]), &(v[2]), /*mustConverge=*/false); + + int i, j; + for(i = 0; i < 20; i++) { + // Approximate each surface by a plane + Vector p[3], tu[3], tv[3], n[3]; + double d[3]; + for(j = 0; j < 3; j++) { + p[j] = (srf[j])->PointAt(u[j], v[j]); + (srf[j])->TangentsAt(u[j], v[j], &(tu[j]), &(tv[j])); + n[j] = ((tu[j]).Cross(tv[j])).WithMagnitude(1); + d[j] = (n[j]).Dot(p[j]); + } + + // If a = b and b = c, then does a = c? No, it doesn't. + if((p[0]).Equals(p[1], RATPOLY_EPS) && + (p[1]).Equals(p[2], RATPOLY_EPS) && + (p[2]).Equals(p[0], RATPOLY_EPS)) + { + *up = u[0]; + *vp = v[0]; + return; + } + + bool parallel; + Vector pi = Vector::AtIntersectionOfPlanes(n[0], d[0], + n[1], d[1], + n[2], d[2], ¶llel); + + if(parallel) { // lets try something else for parallel planes + pi = p[0].Plus(p[1]).Plus(p[2]).ScaledBy(1.0/3.0); + } + + for(j = 0; j < 3; j++) { + Vector n = tu[j].Cross(tv[j]); + Vector ty = n.Cross(tu[j]).ScaledBy(1.0/tu[j].MagSquared()); + Vector tx = tv[j].Cross(n).ScaledBy(1.0/tv[j].MagSquared()); + + Vector dp = pi.Minus(p[j]); + double du = dp.Dot(tx), dv = dp.Dot(ty); + + u[j] += du / tx.MagSquared(); + v[j] += dv / ty.MagSquared(); + } + } + dbp("didn't converge (three surfaces intersecting)"); +} + +void SSurface::PointOnCurve(const SBezier *curve, double *up, double *vp) +{ + Vector tu,tv,n; + double u = *up, v = *vp; + Vector ps = PointAt(u, v); + // Get initial guesses for t on the curve + double tCurve = 0.5; + curve->ClosestPointTo(ps, &tCurve, /*mustConverge=*/false); + if(tCurve < 0.0) tCurve = 0.0; + if(tCurve > 1.0) tCurve = 1.0; + + for(int i = 0; i < 30; i++) { + // Approximate the surface by a plane + Vector ps = PointAt(u, v); + TangentsAt(u, v, &tu, &tv); + n = tu.Cross(tv).WithMagnitude(1); + + // point on curve and tangent line direction + Vector pc = curve->PointAt(tCurve); + Vector tc = curve->TangentAt(tCurve); + + if(ps.Equals(pc, RATPOLY_EPS)) { + *up = u; + *vp = v; + return; + } + + //pi is where the curve tangent line intersects the surface tangent plane + Vector pi; + double d = tc.Dot(n); + if (fabs(d) < 1e-10) { // parallel line and plane, guess the average rather than fail + pi = pc.Plus(ps).ScaledBy(0.5); + } else { + pi = pc.Minus(tc.ScaledBy(pc.Minus(ps).Dot(n)/d)); + } + + // project the point onto the tangent plane and line + { + Vector n = tu.Cross(tv); + Vector ty = n.Cross(tu).ScaledBy(1.0/tu.MagSquared()); + Vector tx = tv.Cross(n).ScaledBy(1.0/tv.MagSquared()); + + Vector dp = pi.Minus(ps); + double du = dp.Dot(tx), dv = dp.Dot(ty); + + u += du / tx.MagSquared(); + v += dv / ty.MagSquared(); + } + tCurve += pi.Minus(pc).Dot(tc) / tc.MagSquared(); + if(tCurve < 0.0) tCurve = 0.0; + if(tCurve > 1.0) tCurve = 1.0; + } + dbp("didn't converge (surface and curve intersecting)"); +} + diff --git a/src/srf/raycast.cpp b/src/srf/raycast.cpp new file mode 100644 index 0000000..5877928 --- /dev/null +++ b/src/srf/raycast.cpp @@ -0,0 +1,615 @@ +//----------------------------------------------------------------------------- +// Routines for ray-casting: intersecting a line segment or an infinite line +// with a surface or shell. Ray-casting against a shell is used for point-in- +// shell testing, and the intersection of edge line segments against surfaces +// is used to get rough surface-curve intersections, which are later refined +// numerically. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +// Dot product tolerance for perpendicular; this is on the direction cosine, +// so it's about 0.001 degrees. +const double SShell::DOTP_TOL = 1e-5; + +extern int FLAG; + + +double SSurface::DepartureFromCoplanar() const { + int i, j; + int ia, ja, ib = 0, jb = 0, ic = 0, jc = 0; + double best; + + // Grab three points to define a plane; first choose (0, 0) arbitrarily. + ia = ja = 0; + // Then the point farthest from pt a. + best = VERY_NEGATIVE; + for(i = 0; i <= degm; i++) { + for(j = 0; j <= degn; j++) { + if(i == ia && j == ja) continue; + + double dist = (ctrl[i][j]).Minus(ctrl[ia][ja]).Magnitude(); + if(dist > best) { + best = dist; + ib = i; + jb = j; + } + } + } + // Then biggest magnitude of ab cross ac. + best = VERY_NEGATIVE; + for(i = 0; i <= degm; i++) { + for(j = 0; j <= degn; j++) { + if(i == ia && j == ja) continue; + if(i == ib && j == jb) continue; + + double mag = + ((ctrl[ia][ja].Minus(ctrl[ib][jb]))).Cross( + (ctrl[ia][ja].Minus(ctrl[i ][j ]))).Magnitude(); + if(mag > best) { + best = mag; + ic = i; + jc = j; + } + } + } + + Vector n = ((ctrl[ia][ja].Minus(ctrl[ib][jb]))).Cross( + (ctrl[ia][ja].Minus(ctrl[ic][jc]))); + n = n.WithMagnitude(1); + double d = (ctrl[ia][ja]).Dot(n); + + // Finally, calculate the deviation from each point to the plane. + double farthest = VERY_NEGATIVE; + for(i = 0; i <= degm; i++) { + for(j = 0; j <= degn; j++) { + double dist = fabs(n.Dot(ctrl[i][j]) - d); + if(dist > farthest) { + farthest = dist; + } + } + } + return farthest; +} + +void SSurface::WeightControlPoints() { + int i, j; + for(i = 0; i <= degm; i++) { + for(j = 0; j <= degn; j++) { + ctrl[i][j] = (ctrl[i][j]).ScaledBy(weight[i][j]); + } + } +} +void SSurface::UnWeightControlPoints() { + int i, j; + for(i = 0; i <= degm; i++) { + for(j = 0; j <= degn; j++) { + ctrl[i][j] = (ctrl[i][j]).ScaledBy(1.0/weight[i][j]); + } + } +} +void SSurface::CopyRowOrCol(bool row, int this_ij, SSurface *src, int src_ij) { + if(row) { + int j; + for(j = 0; j <= degn; j++) { + ctrl [this_ij][j] = src->ctrl [src_ij][j]; + weight[this_ij][j] = src->weight[src_ij][j]; + } + } else { + int i; + for(i = 0; i <= degm; i++) { + ctrl [i][this_ij] = src->ctrl [i][src_ij]; + weight[i][this_ij] = src->weight[i][src_ij]; + } + } +} +void SSurface::BlendRowOrCol(bool row, int this_ij, SSurface *a, int a_ij, + SSurface *b, int b_ij) +{ + if(row) { + int j; + for(j = 0; j <= degn; j++) { + Vector c = (a->ctrl [a_ij][j]).Plus(b->ctrl [b_ij][j]); + double w = (a->weight[a_ij][j] + b->weight[b_ij][j]); + ctrl [this_ij][j] = c.ScaledBy(0.5); + weight[this_ij][j] = w / 2; + } + } else { + int i; + for(i = 0; i <= degm; i++) { + Vector c = (a->ctrl [i][a_ij]).Plus(b->ctrl [i][b_ij]); + double w = (a->weight[i][a_ij] + b->weight[i][b_ij]); + ctrl [i][this_ij] = c.ScaledBy(0.5); + weight[i][this_ij] = w / 2; + } + } +} +void SSurface::SplitInHalf(bool byU, SSurface *sa, SSurface *sb) { + sa->degm = sb->degm = degm; + sa->degn = sb->degn = degn; + + // by de Casteljau's algorithm in a projective space; so we must work + // on points (w*x, w*y, w*z, w) so create a temporary copy + SSurface st; + st = *this; + st.WeightControlPoints(); + + switch(byU ? degm : degn) { + case 1: + sa->CopyRowOrCol (byU, 0, &st, 0); + sb->CopyRowOrCol (byU, 1, &st, 1); + + sa->BlendRowOrCol(byU, 1, &st, 0, &st, 1); + sb->BlendRowOrCol(byU, 0, &st, 0, &st, 1); + break; + + case 2: + sa->CopyRowOrCol (byU, 0, &st, 0); + sb->CopyRowOrCol (byU, 2, &st, 2); + + sa->BlendRowOrCol(byU, 1, &st, 0, &st, 1); + sb->BlendRowOrCol(byU, 1, &st, 1, &st, 2); + + sa->BlendRowOrCol(byU, 2, sa, 1, sb, 1); + sb->BlendRowOrCol(byU, 0, sa, 1, sb, 1); + break; + + case 3: { + sa->CopyRowOrCol (byU, 0, &st, 0); + sb->CopyRowOrCol (byU, 3, &st, 3); + + sa->BlendRowOrCol(byU, 1, &st, 0, &st, 1); + sb->BlendRowOrCol(byU, 2, &st, 2, &st, 3); + st. BlendRowOrCol(byU, 0, &st, 1, &st, 2); // use row/col 0 as scratch + + sa->BlendRowOrCol(byU, 2, sa, 1, &st, 0); + sb->BlendRowOrCol(byU, 1, sb, 2, &st, 0); + + sa->BlendRowOrCol(byU, 3, sa, 2, sb, 1); + sb->BlendRowOrCol(byU, 0, sa, 2, sb, 1); + break; + } + + default: ssassert(false, "Unexpected degree of spline"); + } + + sa->UnWeightControlPoints(); + sb->UnWeightControlPoints(); +} + +//----------------------------------------------------------------------------- +// Find all points where the indicated finite (if segment) or infinite (if not +// segment) line intersects our surface. Report them in uv space in the list. +// We first do a bounding box check; if the line doesn't intersect, then we're +// done. If it does, then we check how small our surface is. If it's big, +// then we subdivide into quarters and recurse. If it's small, then we refine +// by Newton's method and record the point. +//----------------------------------------------------------------------------- +void SSurface::AllPointsIntersectingUntrimmed(Vector a, Vector b, + int *cnt, int *level, + List *l, bool asSegment, + SSurface *sorig) +{ + // Test if the line intersects our axis-aligned bounding box; if no, then + // no possibility of an intersection + if(LineEntirelyOutsideBbox(a, b, asSegment)) return; + + if(*cnt > 2000) { + dbp("!!! too many subdivisions (level=%d)!", *level); + dbp("degm = %d degn = %d", degm, degn); + return; + } + (*cnt)++; + + // If we might intersect, and the surface is small, then switch to Newton + // iterations. + if(DepartureFromCoplanar() < 0.2*SS.ChordTolMm()) { + Vector p = (ctrl[0 ][0 ]).Plus( + ctrl[0 ][degn]).Plus( + ctrl[degm][0 ]).Plus( + ctrl[degm][degn]).ScaledBy(0.25); + Inter inter; + sorig->ClosestPointTo(p, &(inter.p.x), &(inter.p.y), /*mustConverge=*/false); + if(sorig->PointIntersectingLine(a, b, &(inter.p.x), &(inter.p.y))) { + Vector p = sorig->PointAt(inter.p.x, inter.p.y); + // Debug check, verify that the point lies in both surfaces + // (which it ought to, since the surfaces should be coincident) + double u, v; + ClosestPointTo(p, &u, &v); + l->Add(&inter); + } else { + // Might not converge if line is almost tangent to surface... + } + return; + } + + // But the surface is big, so split it, alternating by u and v + SSurface surf0, surf1; + SplitInHalf((*level & 1) == 0, &surf0, &surf1); + + int nextLevel = (*level) + 1; + (*level) = nextLevel; + surf0.AllPointsIntersectingUntrimmed(a, b, cnt, level, l, asSegment, sorig); + (*level) = nextLevel; + surf1.AllPointsIntersectingUntrimmed(a, b, cnt, level, l, asSegment, sorig); +} + +//----------------------------------------------------------------------------- +// Find all points where a line through a and b intersects our surface, and +// add them to the list. If seg is true then report only intersections that +// lie within the finite line segment (not including the endpoints); otherwise +// we work along the infinite line. And we report either just intersections +// inside the trim curve, or any intersection with u, v in [0, 1]. And we +// either disregard or report tangent points. +//----------------------------------------------------------------------------- +void SSurface::AllPointsIntersecting(Vector a, Vector b, + List *l, + bool asSegment, bool trimmed, bool inclTangent) +{ + if(LineEntirelyOutsideBbox(a, b, asSegment)) return; + + Vector ba = b.Minus(a); + double bam = ba.Magnitude(); + + List inters = {}; + + // All the intersections between the line and the surface; either special + // cases that we can quickly solve in closed form, or general numerical. + Vector center, axis, start, finish; + double radius; + if(degm == 1 && degn == 1) { + // Against a plane, easy. + Vector n = NormalAt(0, 0).WithMagnitude(1); + double d = n.Dot(PointAt(0, 0)); + // Trim to line segment now if requested, don't generate points that + // would just get discarded later. + if(!asSegment || + (n.Dot(a) > d + LENGTH_EPS && n.Dot(b) < d - LENGTH_EPS) || + (n.Dot(b) > d + LENGTH_EPS && n.Dot(a) < d - LENGTH_EPS)) + { + Vector p = Vector::AtIntersectionOfPlaneAndLine(n, d, a, b, NULL); + Inter inter; + ClosestPointTo(p, &(inter.p.x), &(inter.p.y)); + inters.Add(&inter); + } + } else if(IsCylinder(&axis, ¢er, &radius, &start, &finish)) { + // This one can be solved in closed form too. + Vector ab = b.Minus(a); + if(axis.Cross(ab).Magnitude() < LENGTH_EPS) { + // edge is parallel to axis of cylinder, no intersection points + return; + } + // A coordinate system centered at the center of the circle, with + // the edge under test horizontal + Vector u, v, n = axis.WithMagnitude(1); + u = (ab.Minus(n.ScaledBy(ab.Dot(n)))).WithMagnitude(1); + v = n.Cross(u); + Point2d ap = (a.Minus(center)).DotInToCsys(u, v, n).ProjectXy(), + bp = (b.Minus(center)).DotInToCsys(u, v, n).ProjectXy(), + sp = (start. Minus(center)).DotInToCsys(u, v, n).ProjectXy(), + fp = (finish.Minus(center)).DotInToCsys(u, v, n).ProjectXy(); + + double thetas = atan2(sp.y, sp.x), thetaf = atan2(fp.y, fp.x); + + Point2d ip[2]; + int ip_n = 0; + if(fabs(fabs(ap.y) - radius) < LENGTH_EPS) { + // tangent + if(inclTangent) { + ip[0] = Point2d::From(0, ap.y); + ip_n = 1; + } + } else if(fabs(ap.y) < radius) { + // two intersections + double xint = sqrt(radius*radius - ap.y*ap.y); + ip[0] = Point2d::From(-xint, ap.y); + ip[1] = Point2d::From( xint, ap.y); + ip_n = 2; + } + int i; + for(i = 0; i < ip_n; i++) { + double t = (ip[i].Minus(ap)).DivProjected(bp.Minus(ap)); + // This is a point on the circle; but is it on the arc? + Point2d pp = ap.Plus((bp.Minus(ap)).ScaledBy(t)); + double theta = atan2(pp.y, pp.x); + double dp = WRAP_SYMMETRIC(theta - thetas, 2*PI), + df = WRAP_SYMMETRIC(thetaf - thetas, 2*PI); + double tol = LENGTH_EPS/radius; + + if((df > 0 && ((dp < -tol) || (dp > df + tol))) || + (df < 0 && ((dp > tol) || (dp < df - tol)))) + { + continue; + } + + Vector p = a.Plus((b.Minus(a)).ScaledBy(t)); + + Inter inter; + ClosestPointTo(p, &(inter.p.x), &(inter.p.y)); + inters.Add(&inter); + } + } else { + // General numerical solution by subdivision, fallback + int cnt = 0, level = 0; + AllPointsIntersectingUntrimmed(a, b, &cnt, &level, &inters, asSegment, this); + } + + // Remove duplicate intersection points + inters.ClearTags(); + int i, j; + for(i = 0; i < inters.n; i++) { + for(j = i + 1; j < inters.n; j++) { + if(inters[i].p.Equals(inters[j].p)) { + inters[j].tag = 1; + } + } + } + inters.RemoveTagged(); + + for(i = 0; i < inters.n; i++) { + Point2d puv = inters[i].p; + + // Make sure the point lies within the finite line segment + Vector pxyz = PointAt(puv.x, puv.y); + double t = (pxyz.Minus(a)).DivProjected(ba); + if(asSegment && (t > 1 - LENGTH_EPS/bam || t < LENGTH_EPS/bam)) { + continue; + } + + // And that it lies inside our trim region + Point2d dummy = { 0, 0 }; + SBspUv::Class c = (bsp) ? bsp->ClassifyPoint(puv, dummy, this) : SBspUv::Class::OUTSIDE; + if(trimmed && c == SBspUv::Class::OUTSIDE) { + continue; + } + + // It does, so generate the intersection + SInter si; + si.p = pxyz; + si.surfNormal = NormalAt(puv.x, puv.y); + si.pinter = puv; + si.srf = this; + si.onEdge = (c != SBspUv::Class::INSIDE); + l->Add(&si); + } + + inters.Clear(); +} + +void SShell::AllPointsIntersecting(Vector a, Vector b, + List *il, + bool asSegment, bool trimmed, bool inclTangent) +{ + SSurface *ss; + for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) { + ss->AllPointsIntersecting(a, b, il, + asSegment, trimmed, inclTangent); + } +} + + + +SShell::Class SShell::ClassifyRegion(Vector edge_n, Vector inter_surf_n, + Vector edge_surf_n) const +{ + double dot = inter_surf_n.DirectionCosineWith(edge_n); + if(fabs(dot) < DOTP_TOL) { + // The edge's surface and the edge-on-face surface + // are coincident. Test the edge's surface normal + // to see if it's with same or opposite normals. + if(inter_surf_n.Dot(edge_surf_n) > 0) { + return Class::COINC_SAME; + } else { + return Class::COINC_OPP; + } + } else if(dot > 0) { + return Class::OUTSIDE; + } else { + return Class::INSIDE; + } +} + +//----------------------------------------------------------------------------- +// Does the given point lie on our shell? There are many cases; inside and +// outside are obvious, but then there's all the edge-on-edge and edge-on-face +// possibilities. +// +// To calculate, we intersect a ray through p with our shell, and classify +// using the closest intersection point. If the ray hits a surface on edge, +// then just reattempt in a different random direction. +//----------------------------------------------------------------------------- + +// table of vectors in 6 arbitrary directions covering 4 of the 8 octants. +// use overlapping sets of 3 to reduce memory usage. +static const double Random[8] = {1.278, 5.0103, 9.427, -2.331, 7.13, 2.954, 5.034, -4.777}; + +bool SShell::ClassifyEdge(Class *indir, Class *outdir, + Vector ea, Vector eb, + Vector p, + Vector edge_n_in, Vector edge_n_out, Vector surf_n) +{ + List l = {}; + + // First, check for edge-on-edge + int edge_inters = 0; + Vector inter_surf_n[2], inter_edge_n[2]; + SSurface *srf; + for(srf = surface.First(); srf; srf = surface.NextAfter(srf)) { + if(srf->LineEntirelyOutsideBbox(ea, eb, /*asSegment=*/true)) continue; + + SEdgeList *sel = &(srf->edges); + SEdge *se; + for(se = sel->l.First(); se; se = sel->l.NextAfter(se)) { + if((ea.Equals(se->a) && eb.Equals(se->b)) || + (eb.Equals(se->a) && ea.Equals(se->b)) || + p.OnLineSegment(se->a, se->b)) + { + if(edge_inters < 2) { + // Edge-on-edge case + Point2d pm; + srf->ClosestPointTo(p, &pm, /*mustConverge=*/false); + // A vector normal to the surface, at the intersection point + inter_surf_n[edge_inters] = srf->NormalAt(pm); + // A vector normal to the intersecting edge (but within the + // intersecting surface) at the intersection point, pointing + // out. + inter_edge_n[edge_inters] = + (inter_surf_n[edge_inters]).Cross((se->b).Minus((se->a))); + } + + edge_inters++; + } + } + } + + if(edge_inters == 2) { + //! @todo make this use the appropriate curved normals + double dotp[2]; + for(int i = 0; i < 2; i++) { + dotp[i] = edge_n_out.DirectionCosineWith(inter_surf_n[i]); + } + + if(fabs(dotp[1]) < DOTP_TOL) { + swap(dotp[0], dotp[1]); + swap(inter_surf_n[0], inter_surf_n[1]); + swap(inter_edge_n[0], inter_edge_n[1]); + } + + Class coinc = (surf_n.Dot(inter_surf_n[0])) > 0 ? Class::COINC_SAME : Class::COINC_OPP; + + if(fabs(dotp[0]) < DOTP_TOL && fabs(dotp[1]) < DOTP_TOL) { + // This is actually an edge on face case, just that the face + // is split into two pieces joining at our edge. + *indir = coinc; + *outdir = coinc; + } else if(fabs(dotp[0]) < DOTP_TOL && dotp[1] > DOTP_TOL) { + if(edge_n_out.Dot(inter_edge_n[0]) > 0) { + *indir = coinc; + *outdir = Class::OUTSIDE; + } else { + *indir = Class::INSIDE; + *outdir = coinc; + } + } else if(fabs(dotp[0]) < DOTP_TOL && dotp[1] < -DOTP_TOL) { + if(edge_n_out.Dot(inter_edge_n[0]) > 0) { + *indir = coinc; + *outdir = Class::INSIDE; + } else { + *indir = Class::OUTSIDE; + *outdir = coinc; + } + } else if(dotp[0] > DOTP_TOL && dotp[1] > DOTP_TOL) { + *indir = Class::INSIDE; + *outdir = Class::OUTSIDE; + } else if(dotp[0] < -DOTP_TOL && dotp[1] < -DOTP_TOL) { + *indir = Class::OUTSIDE; + *outdir = Class::INSIDE; + } else { + // Edge is tangent to the shell at shell's edge, so can't be + // a boundary of the surface. + return false; + } + return true; + } + + if(edge_inters != 0) dbp("bad, edge_inters=%d", edge_inters); + + // Next, check for edge-on-surface. The ray-casting for edge-inside-shell + // would catch this too, but test separately, for speed (since many edges + // are on surface) and for numerical stability, so we don't pick up + // the additional error from the line intersection. + + for(srf = surface.First(); srf; srf = surface.NextAfter(srf)) { + if(srf->LineEntirelyOutsideBbox(ea, eb, /*asSegment=*/true)) continue; + + Point2d puv; + srf->ClosestPointTo(p, &(puv.x), &(puv.y), /*mustConverge=*/false); + Vector pp = srf->PointAt(puv); + + if((pp.Minus(p)).Magnitude() > LENGTH_EPS) continue; + Point2d dummy = { 0, 0 }; + SBspUv::Class c = (srf->bsp) ? srf->bsp->ClassifyPoint(puv, dummy, srf) : SBspUv::Class::OUTSIDE; + if(c == SBspUv::Class::OUTSIDE) continue; + + // Edge-on-face (unless edge-on-edge above superceded) + Point2d pin, pout; + srf->ClosestPointTo(p.Plus(edge_n_in), &pin, /*mustConverge=*/false); + srf->ClosestPointTo(p.Plus(edge_n_out), &pout, /*mustConverge=*/false); + + Vector surf_n_in = srf->NormalAt(pin), + surf_n_out = srf->NormalAt(pout); + + *indir = ClassifyRegion(edge_n_in, surf_n_in, surf_n); + *outdir = ClassifyRegion(edge_n_out, surf_n_out, surf_n); + return true; + } + + // Edge is not on face or on edge; so it's either inside or outside + // the shell, and we'll determine which by raycasting. + int cnt = 0; + for(;;) { + // Cast a ray in a random direction (two-sided so that we test if + // the point lies on a surface, but use only one side for in/out + // testing) + Vector ray = Vector::From(Random[cnt], Random[cnt+1], Random[cnt+2]); + + AllPointsIntersecting( + p.Minus(ray), p.Plus(ray), &l, + /*asSegment=*/false, /*trimmed=*/true, /*inclTangent=*/false); + + // no intersections means it's outside + *indir = Class::OUTSIDE; + *outdir = Class::OUTSIDE; + double dmin = VERY_POSITIVE; + bool onEdge = false; + edge_inters = 0; + + SInter *si; + for(si = l.First(); si; si = l.NextAfter(si)) { + double t = ((si->p).Minus(p)).DivProjected(ray); + if(t*ray.Magnitude() < -LENGTH_EPS) { + // wrong side, doesn't count + continue; + } + + double d = ((si->p).Minus(p)).Magnitude(); + + // We actually should never hit this case; it should have been + // handled above. + if(d < LENGTH_EPS && si->onEdge) { + edge_inters++; + } + + if(d < dmin) { + dmin = d; + // Edge does not lie on surface; either strictly inside + // or strictly outside + if((si->surfNormal).Dot(ray) > 0) { + *indir = Class::INSIDE; + *outdir = Class::INSIDE; + } else { + *indir = Class::OUTSIDE; + *outdir = Class::OUTSIDE; + } + onEdge = si->onEdge; + } + } + l.Clear(); + + // If the point being tested lies exactly on an edge of the shell, + // then our ray always lies on edge, and that's okay. Otherwise + // try again in a different random direction. + if(!onEdge) break; + cnt++; + if(cnt > 5) { + dbp("can't find a ray that doesn't hit on edge!"); + dbp("on edge = %d, edge_inters = %d", onEdge, edge_inters); + SS.nakedEdges.AddEdge(ea, eb); + break; + } + } + + return true; +} + diff --git a/src/srf/surface.cpp b/src/srf/surface.cpp new file mode 100644 index 0000000..815aeda --- /dev/null +++ b/src/srf/surface.cpp @@ -0,0 +1,1102 @@ +//----------------------------------------------------------------------------- +// Anything involving surfaces and sets of surfaces (i.e., shells); except +// for the real math, which is in ratpoly.cpp. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "../solvespace.h" + +SSurface SSurface::FromExtrusionOf(SBezier *sb, Vector t0, Vector t1) { + SSurface ret = {}; + + ret.degm = sb->deg; + ret.degn = 1; + + int i; + for(i = 0; i <= ret.degm; i++) { + ret.ctrl[i][0] = (sb->ctrl[i]).Plus(t0); + ret.weight[i][0] = sb->weight[i]; + + ret.ctrl[i][1] = (sb->ctrl[i]).Plus(t1); + ret.weight[i][1] = sb->weight[i]; + } + + return ret; +} + +bool SSurface::IsExtrusion(SBezier *of, Vector *alongp) const { + int i; + + if(degn != 1) return false; + + Vector along = (ctrl[0][1]).Minus(ctrl[0][0]); + for(i = 0; i <= degm; i++) { + if((fabs(weight[i][1] - weight[i][0]) < LENGTH_EPS) && + ((ctrl[i][1]).Minus(ctrl[i][0])).Equals(along)) + { + continue; + } + return false; + } + + // yes, we are a surface of extrusion; copy the original curve and return + if(of) { + for(i = 0; i <= degm; i++) { + of->weight[i] = weight[i][0]; + of->ctrl[i] = ctrl[i][0]; + } + of->deg = degm; + *alongp = along; + } + return true; +} + +bool SSurface::IsCylinder(Vector *axis, Vector *center, double *r, + Vector *start, Vector *finish) const +{ + SBezier sb; + if(!IsExtrusion(&sb, axis)) return false; + if(!sb.IsCircle(*axis, center, r)) return false; + + *start = sb.ctrl[0]; + *finish = sb.ctrl[2]; + return true; +} + +// Create a surface patch by revolving and possibly translating a curve. +// Works for sections up to but not including 180 degrees. +SSurface SSurface::FromRevolutionOf(SBezier *sb, Vector pt, Vector axis, double thetas, + double thetaf, double dists, + double distf) { // s is start, f is finish + SSurface ret = {}; + ret.degm = sb->deg; + ret.degn = 2; + + double dtheta = fabs(WRAP_SYMMETRIC(thetaf - thetas, 2*PI)); + double w = cos(dtheta / 2); + + // Revolve the curve about the z axis + int i; + for(i = 0; i <= ret.degm; i++) { + Vector p = sb->ctrl[i]; + + Vector ps = p.RotatedAbout(pt, axis, thetas), + pf = p.RotatedAbout(pt, axis, thetaf); + + // The middle control point should be at the intersection of the tangents at ps and pf. + // This is equivalent but works for 0 <= angle < 180 degrees. + Vector mid = ps.Plus(pf).ScaledBy(0.5); + Vector c = ps.ClosestPointOnLine(pt, axis); + Vector ct = mid.Minus(c).ScaledBy(1 / (w * w)).Plus(c); + + // not sure this is needed + if(ps.Equals(pf)) { + ps = c; + ct = c; + pf = c; + } + // moving along the axis can create hilical surfaces (or straight extrusion if + // thetas==thetaf) + ret.ctrl[i][0] = ps.Plus(axis.ScaledBy(dists)); + ret.ctrl[i][1] = ct.Plus(axis.ScaledBy((dists + distf) / 2)); + ret.ctrl[i][2] = pf.Plus(axis.ScaledBy(distf)); + + ret.weight[i][0] = sb->weight[i]; + ret.weight[i][1] = sb->weight[i] * w; + ret.weight[i][2] = sb->weight[i]; + } + + return ret; +} + +SSurface SSurface::FromPlane(Vector pt, Vector u, Vector v) { + SSurface ret = {}; + + ret.degm = 1; + ret.degn = 1; + + ret.weight[0][0] = ret.weight[0][1] = 1; + ret.weight[1][0] = ret.weight[1][1] = 1; + + ret.ctrl[0][0] = pt; + ret.ctrl[0][1] = pt.Plus(u); + ret.ctrl[1][0] = pt.Plus(v); + ret.ctrl[1][1] = pt.Plus(v).Plus(u); + + return ret; +} + +SSurface SSurface::FromTransformationOf(SSurface *a, Vector t, Quaternion q, double scale, + bool includingTrims) +{ + bool needRotate = !EXACT(q.vx == 0.0 && q.vy == 0.0 && q.vz == 0.0 && q.w == 1.0); + bool needTranslate = !EXACT(t.x == 0.0 && t.y == 0.0 && t.z == 0.0); + bool needScale = !EXACT(scale == 1.0); + + SSurface ret = {}; + ret.h = a->h; + ret.color = a->color; + ret.face = a->face; + + ret.degm = a->degm; + ret.degn = a->degn; + int i, j; + for(i = 0; i <= 3; i++) { + for(j = 0; j <= 3; j++) { + Vector ctrl = a->ctrl[i][j]; + if(needScale) { + ctrl = ctrl.ScaledBy(scale); + } + if(needRotate) { + ctrl = q.Rotate(ctrl); + } + if(needTranslate) { + ctrl = ctrl.Plus(t); + } + ret.ctrl[i][j] = ctrl; + ret.weight[i][j] = a->weight[i][j]; + } + } + + if(includingTrims) { + STrimBy *stb; + ret.trim.ReserveMore(a->trim.n); + for(stb = a->trim.First(); stb; stb = a->trim.NextAfter(stb)) { + STrimBy n = *stb; + if(needScale) { + n.start = n.start.ScaledBy(scale); + n.finish = n.finish.ScaledBy(scale); + } + if(needRotate) { + n.start = q.Rotate(n.start); + n.finish = q.Rotate(n.finish); + } + if(needTranslate) { + n.start = n.start.Plus(t); + n.finish = n.finish.Plus(t); + } + ret.trim.Add(&n); + } + } + + if(scale < 0) { + // If we mirror every surface of a shell, then it will end up inside + // out. So fix that here. + ret.Reverse(); + } + + return ret; +} + +void SSurface::GetAxisAlignedBounding(Vector *ptMax, Vector *ptMin) const { + *ptMax = Vector::From(VERY_NEGATIVE, VERY_NEGATIVE, VERY_NEGATIVE); + *ptMin = Vector::From(VERY_POSITIVE, VERY_POSITIVE, VERY_POSITIVE); + + int i, j; + for(i = 0; i <= degm; i++) { + for(j = 0; j <= degn; j++) { + (ctrl[i][j]).MakeMaxMin(ptMax, ptMin); + } + } +} + +bool SSurface::LineEntirelyOutsideBbox(Vector a, Vector b, bool asSegment) const { + Vector amax, amin; + GetAxisAlignedBounding(&amax, &amin); + if(!Vector::BoundingBoxIntersectsLine(amax, amin, a, b, asSegment)) { + // The line segment could fail to intersect the bbox, but lie entirely + // within it and intersect the surface. + if(a.OutsideAndNotOn(amax, amin) && b.OutsideAndNotOn(amax, amin)) { + return true; + } + } + return false; +} + +//----------------------------------------------------------------------------- +// Generate the piecewise linear approximation of the trim stb, which applies +// to the curve sc. +//----------------------------------------------------------------------------- +void SSurface::MakeTrimEdgesInto(SEdgeList *sel, MakeAs flags, + SCurve *sc, STrimBy *stb) +{ + Vector prev = Vector::From(0, 0, 0); + bool inCurve = false, empty = true; + double u = 0, v = 0; + + int i, first, last, increment; + if(stb->backwards) { + first = sc->pts.n - 1; + last = 0; + increment = -1; + } else { + first = 0; + last = sc->pts.n - 1; + increment = 1; + } + for(i = first; i != (last + increment); i += increment) { + Vector tpt, *pt = &(sc->pts[i].p); + + if(flags == MakeAs::UV) { + ClosestPointTo(*pt, &u, &v); + tpt = Vector::From(u, v, 0); + } else { + tpt = *pt; + } + + if(inCurve) { + sel->AddEdge(prev, tpt, sc->h.v, stb->backwards); + empty = false; + } + + prev = tpt; // either uv or xyz, depending on flags + + if(pt->Equals(stb->start)) inCurve = true; + if(pt->Equals(stb->finish)) inCurve = false; + } + if(inCurve) dbp("trim was unterminated"); + if(empty) dbp("trim was empty"); +} + +//----------------------------------------------------------------------------- +// Generate all of our trim curves, in piecewise linear form. We can do +// so in either uv or xyz coordinates. And if requested, then we can use +// the split curves from useCurvesFrom instead of the curves in our own +// shell. +//----------------------------------------------------------------------------- +void SSurface::MakeEdgesInto(SShell *shell, SEdgeList *sel, MakeAs flags, + SShell *useCurvesFrom) +{ + STrimBy *stb; + for(stb = trim.First(); stb; stb = trim.NextAfter(stb)) { + SCurve *sc = shell->curve.FindById(stb->curve); + + // We have the option to use the curves from another shell; this + // is relevant when generating the coincident edges while doing the + // Booleans, since the curves from the output shell will be split + // against any intersecting surfaces (and the originals aren't). + if(useCurvesFrom) { + sc = useCurvesFrom->curve.FindById(sc->newH); + } + + MakeTrimEdgesInto(sel, flags, sc, stb); + } +} + +//----------------------------------------------------------------------------- +// Compute the exact tangent to the intersection curve between two surfaces, +// by taking the cross product of the surface normals. We choose the direction +// of this tangent so that its dot product with dir is positive. +//----------------------------------------------------------------------------- +Vector SSurface::ExactSurfaceTangentAt(Vector p, SSurface *srfA, SSurface *srfB, Vector dir) +{ + Point2d puva, puvb; + srfA->ClosestPointTo(p, &puva); + srfB->ClosestPointTo(p, &puvb); + Vector ts = (srfA->NormalAt(puva)).Cross( + (srfB->NormalAt(puvb))); + ts = ts.WithMagnitude(1); + if(ts.Dot(dir) < 0) { + ts = ts.ScaledBy(-1); + } + return ts; +} + +//----------------------------------------------------------------------------- +// Report our trim curves. If a trim curve is exact and sbl is not null, then +// add its exact form to sbl. Otherwise, add its piecewise linearization to +// sel. +//----------------------------------------------------------------------------- +void SSurface::MakeSectionEdgesInto(SShell *shell, SEdgeList *sel, SBezierList *sbl) +{ + STrimBy *stb; + for(stb = trim.First(); stb; stb = trim.NextAfter(stb)) { + SCurve *sc = shell->curve.FindById(stb->curve); + SBezier *sb = &(sc->exact); + + if(sbl && sc->isExact && (sb->deg != 1 || !sel)) { + double ts, tf; + if(stb->backwards) { + sb->ClosestPointTo(stb->start, &tf); + sb->ClosestPointTo(stb->finish, &ts); + } else { + sb->ClosestPointTo(stb->start, &ts); + sb->ClosestPointTo(stb->finish, &tf); + } + SBezier junk_bef, keep_aft; + sb->SplitAt(ts, &junk_bef, &keep_aft); + // In the kept piece, the range that used to go from ts to 1 + // now goes from 0 to 1; so rescale tf appropriately. + tf = (tf - ts)/(1 - ts); + + SBezier keep_bef, junk_aft; + keep_aft.SplitAt(tf, &keep_bef, &junk_aft); + + sbl->l.Add(&keep_bef); + } else if(sbl && !sel && !sc->isExact) { + // We must approximate this trim curve, as piecewise cubic sections. + SSurface *srfA = shell->surface.FindById(sc->surfA); + SSurface *srfB = shell->surface.FindById(sc->surfB); + + Vector s = stb->backwards ? stb->finish : stb->start, + f = stb->backwards ? stb->start : stb->finish; + + int sp, fp; + for(sp = 0; sp < sc->pts.n; sp++) { + if(s.Equals(sc->pts[sp].p)) break; + } + if(sp >= sc->pts.n) return; + for(fp = sp; fp < sc->pts.n; fp++) { + if(f.Equals(sc->pts[fp].p)) break; + } + if(fp >= sc->pts.n) return; + // So now the curve we want goes from elem[sp] to elem[fp] + + while(sp < fp) { + // Initially, we'll try approximating the entire trim curve + // as a single Bezier segment + int fpt = fp; + + for(;;) { + // So construct a cubic Bezier with the correct endpoints + // and tangents for the current span. + Vector st = sc->pts[sp].p, + ft = sc->pts[fpt].p, + sf = ft.Minus(st); + double m = sf.Magnitude() / 3; + + Vector stan = ExactSurfaceTangentAt(st, srfA, srfB, sf), + ftan = ExactSurfaceTangentAt(ft, srfA, srfB, sf); + + SBezier sb = SBezier::From(st, + st.Plus (stan.WithMagnitude(m)), + ft.Minus(ftan.WithMagnitude(m)), + ft); + + // And test how much this curve deviates from the + // intermediate points (if any). + int i; + bool tooFar = false; + for(i = sp + 1; i <= (fpt - 1); i++) { + Vector p = sc->pts[i].p; + double t; + sb.ClosestPointTo(p, &t, /*mustConverge=*/false); + Vector pp = sb.PointAt(t); + if((pp.Minus(p)).Magnitude() > SS.ChordTolMm()/2) { + tooFar = true; + break; + } + } + + if(tooFar) { + // Deviates by too much, so try a shorter span + fpt--; + continue; + } else { + // Okay, so use this piece and break. + sbl->l.Add(&sb); + break; + } + } + + // And continue interpolating, starting wherever the curve + // we just generated finishes. + sp = fpt; + } + } else { + if(sel) MakeTrimEdgesInto(sel, MakeAs::XYZ, sc, stb); + } + } +} + +void SSurface::TriangulateInto(SShell *shell, SMesh *sm) { + SEdgeList el = {}; + + MakeEdgesInto(shell, &el, MakeAs::UV); + + SPolygon poly = {}; + if(el.AssemblePolygon(&poly, NULL, /*keepDir=*/true)) { + int i, start = sm->l.n; + if(degm == 1 && degn == 1) { + // A surface with curvature along one direction only; so + // choose the triangulation with chords that lie as much + // as possible within the surface. And since the trim curves + // have been pwl'd to within the desired chord tol, that will + // produce a surface good to within roughly that tol. + // + // If this is just a plane (degree (1, 1)) then the triangulation + // code will notice that, and not bother checking chord tols. + poly.UvTriangulateInto(sm, this); + } else { + // A surface with compound curvature. So we must overlay a + // two-dimensional grid, and triangulate around that. + poly.UvGridTriangulateInto(sm, this); + } + + STriMeta meta = { face, color }; + for(i = start; i < sm->l.n; i++) { + STriangle *st = &(sm->l[i]); + st->meta = meta; + st->an = NormalAt(st->a.x, st->a.y); + st->bn = NormalAt(st->b.x, st->b.y); + st->cn = NormalAt(st->c.x, st->c.y); + st->a = PointAt(st->a.x, st->a.y); + st->b = PointAt(st->b.x, st->b.y); + st->c = PointAt(st->c.x, st->c.y); + // Works out that my chosen contour direction is inconsistent with + // the triangle direction, sigh. + st->FlipNormal(); + } + } else { + dbp("failed to assemble polygon to trim nurbs surface in uv space"); + } + + el.Clear(); + poly.Clear(); +} + +//----------------------------------------------------------------------------- +// Reverse the parametrisation of one of our dimensions, which flips the +// normal. We therefore must reverse all our trim curves too. The uv +// coordinates change, but trim curves are stored as xyz so nothing happens +//----------------------------------------------------------------------------- +void SSurface::Reverse() { + int i, j; + for(i = 0; i < (degm+1)/2; i++) { + for(j = 0; j <= degn; j++) { + swap(ctrl[i][j], ctrl[degm-i][j]); + swap(weight[i][j], weight[degm-i][j]); + } + } + + STrimBy *stb; + for(stb = trim.First(); stb; stb = trim.NextAfter(stb)) { + stb->backwards = !stb->backwards; + swap(stb->start, stb->finish); + } +} + +void SSurface::ScaleSelfBy(double s) { + int i, j; + for(i = 0; i <= degm; i++) { + for(j = 0; j <= degn; j++) { + ctrl[i][j] = ctrl[i][j].ScaledBy(s); + } + } +} + +void SSurface::Clear() { + trim.Clear(); +} + +typedef struct { + hSCurve hc; + hSSurface hs; +} TrimLine; + +void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1, RgbaColor color) +{ + // Make the extrusion direction consistent with respect to the normal + // of the sketch we're extruding. + if((t0.Minus(t1)).Dot(sbls->normal) < 0) { + swap(t0, t1); + } + + // Define a coordinate system to contain the original sketch, and get + // a bounding box in that csys + Vector n = sbls->normal.ScaledBy(-1); + Vector u = n.Normal(0), v = n.Normal(1); + Vector orig = sbls->point; + double umax = VERY_NEGATIVE, umin = VERY_POSITIVE; + sbls->GetBoundingProjd(u, orig, &umin, &umax); + double vmax = VERY_NEGATIVE, vmin = VERY_POSITIVE; + sbls->GetBoundingProjd(v, orig, &vmin, &vmax); + // and now fix things up so that all u and v lie between 0 and 1 + orig = orig.Plus(u.ScaledBy(umin)); + orig = orig.Plus(v.ScaledBy(vmin)); + u = u.ScaledBy(umax - umin); + v = v.ScaledBy(vmax - vmin); + + // So we can now generate the top and bottom surfaces of the extrusion, + // planes within a translated (and maybe mirrored) version of that csys. + SSurface s0, s1; + s0 = SSurface::FromPlane(orig.Plus(t0), u, v); + s0.color = color; + s1 = SSurface::FromPlane(orig.Plus(t1).Plus(u), u.ScaledBy(-1), v); + s1.color = color; + hSSurface hs0 = surface.AddAndAssignId(&s0), + hs1 = surface.AddAndAssignId(&s1); + + // Now go through the input curves. For each one, generate its surface + // of extrusion, its two translated trim curves, and one trim line. We + // go through by loops so that we can assign the lines correctly. + SBezierLoop *sbl; + for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) { + SBezier *sb; + List trimLines = {}; + + for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) { + // Generate the surface of extrusion of this curve, and add + // it to the list + SSurface ss = SSurface::FromExtrusionOf(sb, t0, t1); + ss.color = color; + hSSurface hsext = surface.AddAndAssignId(&ss); + + // Translate the curve by t0 and t1 to produce two trim curves + SCurve sc = {}; + sc.isExact = true; + sc.exact = sb->TransformedBy(t0, Quaternion::IDENTITY, 1.0); + (sc.exact).MakePwlInto(&(sc.pts)); + sc.surfA = hs0; + sc.surfB = hsext; + hSCurve hc0 = curve.AddAndAssignId(&sc); + + sc = {}; + sc.isExact = true; + sc.exact = sb->TransformedBy(t1, Quaternion::IDENTITY, 1.0); + (sc.exact).MakePwlInto(&(sc.pts)); + sc.surfA = hs1; + sc.surfB = hsext; + hSCurve hc1 = curve.AddAndAssignId(&sc); + + STrimBy stb0, stb1; + // The translated curves trim the flat top and bottom surfaces. + stb0 = STrimBy::EntireCurve(this, hc0, /*backwards=*/false); + stb1 = STrimBy::EntireCurve(this, hc1, /*backwards=*/true); + (surface.FindById(hs0))->trim.Add(&stb0); + (surface.FindById(hs1))->trim.Add(&stb1); + + // The translated curves also trim the surface of extrusion. + stb0 = STrimBy::EntireCurve(this, hc0, /*backwards=*/true); + stb1 = STrimBy::EntireCurve(this, hc1, /*backwards=*/false); + (surface.FindById(hsext))->trim.Add(&stb0); + (surface.FindById(hsext))->trim.Add(&stb1); + + // And form the trim line + Vector pt = sb->Finish(); + sc = {}; + sc.isExact = true; + sc.exact = SBezier::From(pt.Plus(t0), pt.Plus(t1)); + (sc.exact).MakePwlInto(&(sc.pts)); + hSCurve hl = curve.AddAndAssignId(&sc); + // save this for later + TrimLine tl; + tl.hc = hl; + tl.hs = hsext; + trimLines.Add(&tl); + } + + int i; + for(i = 0; i < trimLines.n; i++) { + TrimLine *tl = &(trimLines[i]); + SSurface *ss = surface.FindById(tl->hs); + + TrimLine *tlp = &(trimLines[WRAP(i-1, trimLines.n)]); + + STrimBy stb; + stb = STrimBy::EntireCurve(this, tl->hc, /*backwards=*/true); + ss->trim.Add(&stb); + stb = STrimBy::EntireCurve(this, tlp->hc, /*backwards=*/false); + ss->trim.Add(&stb); + + (curve.FindById(tl->hc))->surfA = ss->h; + (curve.FindById(tlp->hc))->surfB = ss->h; + } + trimLines.Clear(); + } +} + +bool SShell::CheckNormalAxisRelationship(SBezierLoopSet *sbls, Vector pt, Vector axis, double da, double dx) +// Check that the direction of revolution/extrusion ends up parallel to the normal of +// the sketch, on the side of the axis where the sketch is. +{ + SBezierLoop *sbl; + Vector pto; + double md = VERY_NEGATIVE; + for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) { + SBezier *sb; + for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) { + // Choose the point farthest from the axis; we'll get garbage + // if we choose a point that lies on the axis, for example. + // (And our surface will be self-intersecting if the sketch + // spans the axis, so don't worry about that.) + for(int i = 0; i <= sb->deg; i++) { + Vector p = sb->ctrl[i]; + double d = p.DistanceToLine(pt, axis); + if(d > md) { + md = d; + pto = p; + } + } + } + } + Vector ptc = pto.ClosestPointOnLine(pt, axis), + up = axis.Cross(pto.Minus(ptc)).ScaledBy(da), + vp = up.Plus(axis.ScaledBy(dx)); + + return (vp.Dot(sbls->normal) > 0); +} + +// sketch must not contain the axis of revolution as a non-construction line for helix +void SShell::MakeFromHelicalRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis, + RgbaColor color, Group *group, double angles, + double anglef, double dists, double distf) { + int i0 = surface.n; // number of pre-existing surfaces + SBezierLoop *sbl; + // for testing - hard code the axial distance, and number of sections. + // distance will need to be parameters in the future. + double dist = distf - dists; + int sections = (int)(fabs(anglef - angles) / (PI / 2) + 1); + double wedge = (anglef - angles) / sections; + int startMapping = Group::REMAP_LATHE_START, endMapping = Group::REMAP_LATHE_END; + + if(CheckNormalAxisRelationship(sbls, pt, axis, anglef-angles, distf-dists)) { + swap(angles, anglef); + swap(dists, distf); + dist = -dist; + wedge = -wedge; + swap(startMapping, endMapping); + } + + // Define a coordinate system to contain the original sketch, and get + // a bounding box in that csys + Vector n = sbls->normal.ScaledBy(-1); + Vector u = n.Normal(0), v = n.Normal(1); + Vector orig = sbls->point; + double umax = VERY_NEGATIVE, umin = VERY_POSITIVE; + sbls->GetBoundingProjd(u, orig, &umin, &umax); + double vmax = VERY_NEGATIVE, vmin = VERY_POSITIVE; + sbls->GetBoundingProjd(v, orig, &vmin, &vmax); + // and now fix things up so that all u and v lie between 0 and 1 + orig = orig.Plus(u.ScaledBy(umin)); + orig = orig.Plus(v.ScaledBy(vmin)); + u = u.ScaledBy(umax - umin); + v = v.ScaledBy(vmax - vmin); + + // So we can now generate the end caps of the extrusion within + // a translated and rotated (and maybe mirrored) version of that csys. + SSurface s0, s1; + s0 = SSurface::FromPlane(orig.RotatedAbout(pt, axis, angles).Plus(axis.ScaledBy(dists)), + u.RotatedAbout(axis, angles), v.RotatedAbout(axis, angles)); + s0.color = color; + + hEntity face0 = group->Remap(Entity::NO_ENTITY, startMapping); + s0.face = face0.v; + + s1 = SSurface::FromPlane( + orig.Plus(u).RotatedAbout(pt, axis, anglef).Plus(axis.ScaledBy(distf)), + u.ScaledBy(-1).RotatedAbout(axis, anglef), v.RotatedAbout(axis, anglef)); + s1.color = color; + + hEntity face1 = group->Remap(Entity::NO_ENTITY, endMapping); + s1.face = face1.v; + + hSSurface hs0 = surface.AddAndAssignId(&s0); + hSSurface hs1 = surface.AddAndAssignId(&s1); + + // Now we actually build and trim the swept surfaces. One loop at a time. + for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) { + int i, j; + SBezier *sb; + List> hsl = {}; + + // This is where all the NURBS are created and Remapped to the generating curve + for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) { + std::vector revs(sections); + for(j = 0; j < sections; j++) { + if((dist == 0) && sb->deg == 1 && + (sb->ctrl[0]).DistanceToLine(pt, axis) < LENGTH_EPS && + (sb->ctrl[1]).DistanceToLine(pt, axis) < LENGTH_EPS) { + // This is a line on the axis of revolution; it does + // not contribute a surface. + revs[j].v = 0; + } else { + SSurface ss = SSurface::FromRevolutionOf( + sb, pt, axis, angles + (wedge)*j, angles + (wedge) * (j + 1), + dists + j * dist / sections, dists + (j + 1) * dist / sections); + ss.color = color; + if(sb->entity != 0) { + hEntity he; + he.v = sb->entity; + hEntity hface = group->Remap(he, Group::REMAP_LINE_TO_FACE); + if(SK.entity.FindByIdNoOops(hface) != NULL) { + ss.face = hface.v; + } + } + revs[j] = surface.AddAndAssignId(&ss); + } + } + hsl.Add(&revs); + } + // Still the same loop. Need to create trim curves + for(i = 0; i < sbl->l.n; i++) { + std::vector revs = hsl[i], revsp = hsl[WRAP(i - 1, sbl->l.n)]; + + sb = &(sbl->l[i]); + + // we will need the grid t-values for this entire row of surfaces + List t_values; + t_values = {}; + if (revs[0].v) { + double ps = 0.0; + t_values.Add(&ps); + (surface.FindById(revs[0]))->MakeTriangulationGridInto( + &t_values, 0.0, 1.0, true, 0); + } + // we generate one more curve than we did surfaces + for(j = 0; j <= sections; j++) { + SCurve sc; + Quaternion qs = Quaternion::From(axis, angles + wedge * j); + // we want Q*(x - p) + p = Q*x + (p - Q*p) + Vector ts = + pt.Minus(qs.Rotate(pt)).Plus(axis.ScaledBy(dists + j * dist / sections)); + + // If this input curve generated a surface, then trim that + // surface with the rotated version of the input curve. + if(revs[0].v) { // not d[j] because crash on j==sections + sc = {}; + sc.isExact = true; + sc.exact = sb->TransformedBy(ts, qs, 1.0); + // make the PWL for the curve based on t value list + for(int x = 0; x < t_values.n; x++) { + SCurvePt scpt; + scpt.tag = 0; + scpt.p = sc.exact.PointAt(t_values[x]); + scpt.vertex = (x == 0) || (x == (t_values.n - 1)); + sc.pts.Add(&scpt); + } + + // the surfaces already exists so trim with this curve + if(j < sections) { + sc.surfA = revs[j]; + } else { + sc.surfA = hs1; // end cap + } + + if(j > 0) { + sc.surfB = revs[j - 1]; + } else { + sc.surfB = hs0; // staring cap + } + + hSCurve hcb = curve.AddAndAssignId(&sc); + + STrimBy stb; + stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/true); + (surface.FindById(sc.surfA))->trim.Add(&stb); + stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/false); + (surface.FindById(sc.surfB))->trim.Add(&stb); + } else if(j == 0) { // curve was on the rotation axis and is shared by the end caps. + sc = {}; + sc.isExact = true; + sc.exact = sb->TransformedBy(ts, qs, 1.0); + (sc.exact).MakePwlInto(&(sc.pts)); + sc.surfA = hs1; // end cap + sc.surfB = hs0; // staring cap + hSCurve hcb = curve.AddAndAssignId(&sc); + + STrimBy stb; + stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/true); + (surface.FindById(sc.surfA))->trim.Add(&stb); + stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/false); + (surface.FindById(sc.surfB))->trim.Add(&stb); + } + + // And if this input curve and the one after it both generated + // surfaces, then trim both of those by the appropriate + // curve based on the control points. + if((j < sections) && revs[j].v && revsp[j].v) { + SSurface *ss = surface.FindById(revs[j]); + + sc = {}; + sc.isExact = true; + sc.exact = SBezier::From(ss->ctrl[0][0], ss->ctrl[0][1], ss->ctrl[0][2]); + sc.exact.weight[1] = ss->weight[0][1]; + double max_dt = 0.5; + if (sc.exact.deg > 1) max_dt = 0.125; + (sc.exact).MakePwlInto(&(sc.pts), 0.0, max_dt); + sc.surfA = revs[j]; + sc.surfB = revsp[j]; + + hSCurve hcc = curve.AddAndAssignId(&sc); + + STrimBy stb; + stb = STrimBy::EntireCurve(this, hcc, /*backwards=*/false); + (surface.FindById(sc.surfA))->trim.Add(&stb); + stb = STrimBy::EntireCurve(this, hcc, /*backwards=*/true); + (surface.FindById(sc.surfB))->trim.Add(&stb); + } + } + t_values.Clear(); + } + + hsl.Clear(); + } + + if(dist == 0) { + MakeFirstOrderRevolvedSurfaces(pt, axis, i0); + } +} + +void SShell::MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis, RgbaColor color, + Group *group) { + int i0 = surface.n; // number of pre-existing surfaces + SBezierLoop *sbl; + + if(CheckNormalAxisRelationship(sbls, pt, axis, 1.0, 0.0)) { + axis = axis.ScaledBy(-1); + } + + // Now we actually build and trim the surfaces. + for(sbl = sbls->l.First(); sbl; sbl = sbls->l.NextAfter(sbl)) { + int i, j; + SBezier *sb; + List> hsl = {}; + + for(sb = sbl->l.First(); sb; sb = sbl->l.NextAfter(sb)) { + std::vector revs(4); + for(j = 0; j < 4; j++) { + if(sb->deg == 1 && + (sb->ctrl[0]).DistanceToLine(pt, axis) < LENGTH_EPS && + (sb->ctrl[1]).DistanceToLine(pt, axis) < LENGTH_EPS) + { + // This is a line on the axis of revolution; it does + // not contribute a surface. + revs[j].v = 0; + } else { + SSurface ss = SSurface::FromRevolutionOf(sb, pt, axis, (PI / 2) * j, + (PI / 2) * (j + 1), 0.0, 0.0); + ss.color = color; + if(sb->entity != 0) { + hEntity he; + he.v = sb->entity; + hEntity hface = group->Remap(he, Group::REMAP_LINE_TO_FACE); + if(SK.entity.FindByIdNoOops(hface) != NULL) { + ss.face = hface.v; + } + } + revs[j] = surface.AddAndAssignId(&ss); + } + } + hsl.Add(&revs); + } + + for(i = 0; i < sbl->l.n; i++) { + std::vector revs = hsl[i], + revsp = hsl[WRAP(i-1, sbl->l.n)]; + + sb = &(sbl->l[i]); + + for(j = 0; j < 4; j++) { + SCurve sc; + Quaternion qs = Quaternion::From(axis, (PI/2)*j); + // we want Q*(x - p) + p = Q*x + (p - Q*p) + Vector ts = pt.Minus(qs.Rotate(pt)); + + // If this input curve generate a surface, then trim that + // surface with the rotated version of the input curve. + if(revs[j].v) { + sc = {}; + sc.isExact = true; + sc.exact = sb->TransformedBy(ts, qs, 1.0); + (sc.exact).MakePwlInto(&(sc.pts)); + sc.surfA = revs[j]; + sc.surfB = revs[WRAP(j-1, 4)]; + + hSCurve hcb = curve.AddAndAssignId(&sc); + + STrimBy stb; + stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/true); + (surface.FindById(sc.surfA))->trim.Add(&stb); + stb = STrimBy::EntireCurve(this, hcb, /*backwards=*/false); + (surface.FindById(sc.surfB))->trim.Add(&stb); + } + + // And if this input curve and the one after it both generated + // surfaces, then trim both of those by the appropriate + // circle. + if(revs[j].v && revsp[j].v) { + SSurface *ss = surface.FindById(revs[j]); + + sc = {}; + sc.isExact = true; + sc.exact = SBezier::From(ss->ctrl[0][0], + ss->ctrl[0][1], + ss->ctrl[0][2]); + sc.exact.weight[1] = ss->weight[0][1]; + (sc.exact).MakePwlInto(&(sc.pts)); + sc.surfA = revs[j]; + sc.surfB = revsp[j]; + + hSCurve hcc = curve.AddAndAssignId(&sc); + + STrimBy stb; + stb = STrimBy::EntireCurve(this, hcc, /*backwards=*/false); + (surface.FindById(sc.surfA))->trim.Add(&stb); + stb = STrimBy::EntireCurve(this, hcc, /*backwards=*/true); + (surface.FindById(sc.surfB))->trim.Add(&stb); + } + } + } + + hsl.Clear(); + } + + MakeFirstOrderRevolvedSurfaces(pt, axis, i0); +} + +void SShell::MakeFirstOrderRevolvedSurfaces(Vector pt, Vector axis, int i0) { + int i; + + for(i = i0; i < surface.n; i++) { + SSurface *srf = &(surface[i]); + + // Revolution of a line; this is potentially a plane, which we can + // rewrite to have degree (1, 1). + if(srf->degm == 1 && srf->degn == 2) { + // close start, far start, far finish + Vector cs, fs, ff; + double d0, d1; + d0 = (srf->ctrl[0][0]).DistanceToLine(pt, axis); + d1 = (srf->ctrl[1][0]).DistanceToLine(pt, axis); + + if(d0 > d1) { + cs = srf->ctrl[1][0]; + fs = srf->ctrl[0][0]; + ff = srf->ctrl[0][2]; + } else { + cs = srf->ctrl[0][0]; + fs = srf->ctrl[1][0]; + ff = srf->ctrl[1][2]; + } + + // origin close, origin far + Vector oc = cs.ClosestPointOnLine(pt, axis), + of = fs.ClosestPointOnLine(pt, axis); + + if(oc.Equals(of)) { + // This is a plane, not a (non-degenerate) cone. + Vector oldn = srf->NormalAt(0.5, 0.5); + + Vector u = fs.Minus(of), v; + + v = (axis.Cross(u)).WithMagnitude(1); + + double vm = (ff.Minus(of)).Dot(v); + v = v.ScaledBy(vm); + + srf->degm = 1; + srf->degn = 1; + srf->ctrl[0][0] = of; + srf->ctrl[0][1] = of.Plus(u); + srf->ctrl[1][0] = of.Plus(v); + srf->ctrl[1][1] = of.Plus(u).Plus(v); + srf->weight[0][0] = 1; + srf->weight[0][1] = 1; + srf->weight[1][0] = 1; + srf->weight[1][1] = 1; + + if(oldn.Dot(srf->NormalAt(0.5, 0.5)) < 0) { + swap(srf->ctrl[0][0], srf->ctrl[1][0]); + swap(srf->ctrl[0][1], srf->ctrl[1][1]); + } + continue; + } + + if(fabs(d0 - d1) < LENGTH_EPS) { + // This is a cylinder; so transpose it so that we'll recognize + // it as a surface of extrusion. + SSurface sn = *srf; + + // Transposing u and v flips the normal, so reverse u to + // flip it again and put it back where we started. + sn.degm = 2; + sn.degn = 1; + int dm, dn; + for(dm = 0; dm <= 1; dm++) { + for(dn = 0; dn <= 2; dn++) { + sn.ctrl [dn][dm] = srf->ctrl [1-dm][dn]; + sn.weight[dn][dm] = srf->weight[1-dm][dn]; + } + } + + *srf = sn; + continue; + } + } + } +} + +void SShell::MakeFromCopyOf(SShell *a) { + ssassert(this != a, "Can't make from copy of self"); + MakeFromTransformationOf(a, + Vector::From(0, 0, 0), Quaternion::IDENTITY, 1.0); +} + +void SShell::MakeFromTransformationOf(SShell *a, + Vector t, Quaternion q, double scale) +{ + booleanFailed = false; + surface.ReserveMore(a->surface.n); + SSurface *s; + for(s = a->surface.First(); s; s = a->surface.NextAfter(s)) { + SSurface n; + n = SSurface::FromTransformationOf(s, t, q, scale, /*includingTrims=*/true); + surface.Add(&n); // keeping the old ID + } + + curve.ReserveMore(a->curve.n); + SCurve *c; + for(c = a->curve.First(); c; c = a->curve.NextAfter(c)) { + SCurve n; + n = SCurve::FromTransformationOf(c, t, q, scale); + curve.Add(&n); // keeping the old ID + } +} + +void SShell::MakeEdgesInto(SEdgeList *sel) { + SSurface *s; + for(s = surface.First(); s; s = surface.NextAfter(s)) { + s->MakeEdgesInto(this, sel, SSurface::MakeAs::XYZ); + } +} + +void SShell::MakeSectionEdgesInto(Vector n, double d, SEdgeList *sel, SBezierList *sbl) +{ + SSurface *s; + for(s = surface.First(); s; s = surface.NextAfter(s)) { + if(s->CoincidentWithPlane(n, d)) { + s->MakeSectionEdgesInto(this, sel, sbl); + } + } +} + +void SShell::TriangulateInto(SMesh *sm) { +#pragma omp parallel for + for(int i=0; iTriangulateInto(this, &m); + #pragma omp critical + sm->MakeFromCopyOf(&m); + m.Clear(); + } +} + +bool SShell::IsEmpty() const { + return surface.IsEmpty(); +} + +void SShell::Clear() { + SSurface *s; + for(s = surface.First(); s; s = surface.NextAfter(s)) { + s->Clear(); + } + surface.Clear(); + + SCurve *c; + for(c = curve.First(); c; c = curve.NextAfter(c)) { + c->Clear(); + } + curve.Clear(); +} diff --git a/src/srf/surface.h b/src/srf/surface.h new file mode 100644 index 0000000..5497455 --- /dev/null +++ b/src/srf/surface.h @@ -0,0 +1,439 @@ +//----------------------------------------------------------------------------- +// Functions relating to rational polynomial surfaces, which are trimmed by +// curves (either rational polynomial curves, or piecewise linear +// approximations to curves of intersection that can't be represented +// exactly in ratpoly form), and assembled into watertight shells. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- + +#ifndef SOLVESPACE_SURFACE_H +#define SOLVESPACE_SURFACE_H + +class SBezierList; +class SSurface; +class SCurvePt; + +// Utility data structure, a two-dimensional BSP to accelerate polygon +// operations. +class SBspUv { +public: + Point2d a, b; + + SBspUv *pos; + SBspUv *neg; + + SBspUv *more; + + enum class Class : uint32_t { + INSIDE = 100, + OUTSIDE = 200, + EDGE_PARALLEL = 300, + EDGE_ANTIPARALLEL = 400, + EDGE_OTHER = 500 + }; + + static SBspUv *Alloc(); + static SBspUv *From(SEdgeList *el, SSurface *srf); + + void ScalePoints(Point2d *pt, Point2d *a, Point2d *b, SSurface *srf) const; + double ScaledSignedDistanceToLine(Point2d pt, Point2d a, Point2d b, + SSurface *srf) const; + double ScaledDistanceToLine(Point2d pt, Point2d a, Point2d b, bool asSegment, + SSurface *srf) const; + + void InsertEdge(Point2d a, Point2d b, SSurface *srf); + static SBspUv *InsertOrCreateEdge(SBspUv *where, Point2d ea, Point2d eb, SSurface *srf); + Class ClassifyPoint(Point2d p, Point2d eb, SSurface *srf) const; + Class ClassifyEdge(Point2d ea, Point2d eb, SSurface *srf) const; + double MinimumDistanceToEdge(Point2d p, SSurface *srf) const; +}; + +// Now the data structures to represent a shell of trimmed rational polynomial +// surfaces. + +class SShell; + +class hSSurface { +public: + uint32_t v; +}; + +template<> +struct IsHandleOracle : std::true_type {}; + +class hSCurve { +public: + uint32_t v; +}; + +template<> +struct IsHandleOracle : std::true_type {}; + +// Stuff for rational polynomial curves, of degree one to three. These are +// our inputs, and are also calculated for certain exact surface-surface +// intersections. +class SBezier { +public: + int tag; + int auxA, auxB; + + int deg; + Vector ctrl[4]; + double weight[4]; + uint32_t entity; + + Vector PointAt(double t) const; + Vector TangentAt(double t) const; + void ClosestPointTo(Vector p, double *t, bool mustConverge=true) const; + void SplitAt(double t, SBezier *bef, SBezier *aft) const; + bool PointOnThisAndCurve(const SBezier *sbb, Vector *p) const; + + Vector Start() const; + Vector Finish() const; + bool Equals(SBezier *b) const; + void MakePwlInto(SEdgeList *sel, double chordTol=0, double max_dt=0.0) const; + void MakePwlInto(List *l, double chordTol=0, double max_dt=0.0) const; + void MakePwlInto(SContour *sc, double chordTol=0, double max_dt=0.0) const; + void MakePwlInto(List *l, double chordTol=0, double max_dt=0.0) const; + void MakePwlWorker(List *l, double ta, double tb, double chordTol, double max_dt) const; + void MakePwlInitialWorker(List *l, double ta, double tb, double chordTol, double max_dt) const; + void MakeNonrationalCubicInto(SBezierList *bl, double tolerance, int depth = 0) const; + + void AllIntersectionsWith(const SBezier *sbb, SPointList *spl) const; + void GetBoundingProjd(Vector u, Vector orig, double *umin, double *umax) const; + void Reverse(); + + bool IsInPlane(Vector n, double d) const; + bool IsCircle(Vector axis, Vector *center, double *r) const; + bool IsRational() const; + + SBezier TransformedBy(Vector t, Quaternion q, double scale) const; + SBezier InPerspective(Vector u, Vector v, Vector n, + Vector origin, double cameraTan) const; + void ScaleSelfBy(double s); + + static SBezier From(Vector p0, Vector p1, Vector p2, Vector p3); + static SBezier From(Vector p0, Vector p1, Vector p2); + static SBezier From(Vector p0, Vector p1); + static SBezier From(Vector4 p0, Vector4 p1, Vector4 p2, Vector4 p3); + static SBezier From(Vector4 p0, Vector4 p1, Vector4 p2); + static SBezier From(Vector4 p0, Vector4 p1); +}; + +class SBezierList { +public: + List l; + + void Clear(); + void ScaleSelfBy(double s); + void CullIdenticalBeziers(bool both=true); + void AllIntersectionsWith(SBezierList *sblb, SPointList *spl) const; + bool GetPlaneContainingBeziers(Vector *p, Vector *u, Vector *v, + Vector *notCoplanarAt) const; +}; + +class SBezierLoop { +public: + int tag; + List l; + + inline void Clear() { l.Clear(); } + bool IsClosed() const; + void Reverse(); + void MakePwlInto(SContour *sc, double chordTol=0) const; + void GetBoundingProjd(Vector u, Vector orig, double *umin, double *umax) const; + + static SBezierLoop FromCurves(SBezierList *spcl, + bool *allClosed, SEdge *errorAt); +}; + +class SBezierLoopSet { +public: + List l; + Vector normal; + Vector point; + double area; + + static SBezierLoopSet From(SBezierList *spcl, SPolygon *poly, + double chordTol, + bool *allClosed, SEdge *errorAt, + SBezierLoopSet *openContours); + + void GetBoundingProjd(Vector u, Vector orig, double *umin, double *umax) const; + double SignedArea(); + void MakePwlInto(SPolygon *sp) const; + void Clear(); +}; + +class SBezierLoopSetSet { +public: + List l; + + void FindOuterFacesFrom(SBezierList *sbl, SPolygon *spxyz, SSurface *srfuv, + double chordTol, + bool *allClosed, SEdge *notClosedAt, + bool *allCoplanar, Vector *notCoplanarAt, + SBezierLoopSet *openContours); + void AddOpenPath(SBezier *sb); + void Clear(); +}; + +// Stuff for the surface trim curves: piecewise linear +class SCurvePt { +public: + int tag; + Vector p; + bool vertex; +}; + +class SCurve { +public: + hSCurve h; + + // In a Boolean, C = A op B. The curves in A and B get copied into C, and + // therefore must get new hSCurves assigned. For the curves in A and B, + // we use newH to record their new handle in C. + hSCurve newH; + enum class Source : uint32_t { + A = 100, + B = 200, + INTERSECTION = 300 + }; + Source source; + + bool isExact; + SBezier exact; + + List pts; + + hSSurface surfA; + hSSurface surfB; + + static SCurve FromTransformationOf(SCurve *a, Vector t, + Quaternion q, double scale); + SCurve MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB, + SSurface *srfA, SSurface *srfB) const; + void RemoveShortSegments(SSurface *srfA, SSurface *srfB); + SSurface *GetSurfaceA(SShell *a, SShell *b) const; + SSurface *GetSurfaceB(SShell *a, SShell *b) const; + + void Clear(); + void GetAxisAlignedBounding(Vector *ptMax, Vector *ptMin) const; +}; + +// A segment of a curve by which a surface is trimmed: indicates which curve, +// by its handle, and the starting and ending points of our segment of it. +// The vector out points out of the surface; it, the surface outer normal, +// and a tangent to the beginning of the curve are all orthogonal. +class STrimBy { +public: + hSCurve curve; + bool backwards; + // If a trim runs backwards, then start and finish still correspond to + // the actual start and finish, but they appear in reverse order in + // the referenced curve. + Vector start; + Vector finish; + + static STrimBy EntireCurve(SShell *shell, hSCurve hsc, bool backwards); +}; + +// An intersection point between a line and a surface +class SInter { +public: + int tag; + Vector p; + SSurface *srf; + Point2d pinter; + Vector surfNormal; // of the intersecting surface, at pinter + bool onEdge; // pinter is on edge of trim poly +}; + +// A rational polynomial surface in Bezier form. +class SSurface { +public: + + enum class CombineAs : uint32_t { + UNION = 10, + DIFFERENCE = 11, + INTERSECTION = 12 + }; + + int tag; + hSSurface h; + + // Same as newH for the curves; record what a surface gets renamed to + // when I copy things over. + hSSurface newH; + + RgbaColor color; + uint32_t face; + + int degm, degn; + Vector ctrl[4][4]; + double weight[4][4]; + + List trim; + + // For testing whether a point (u, v) on the surface lies inside the trim + SBspUv *bsp; + SEdgeList edges; + + // For caching our initial (u, v) when doing Newton iterations to project + // a point into our surface. + Point2d cached; + + static SSurface FromExtrusionOf(SBezier *spc, Vector t0, Vector t1); + static SSurface FromRevolutionOf(SBezier *sb, Vector pt, Vector axis, double thetas, + double thetaf, double dists, double distf); + static SSurface FromPlane(Vector pt, Vector u, Vector v); + static SSurface FromTransformationOf(SSurface *a, Vector t, Quaternion q, + double scale, + bool includingTrims); + void ScaleSelfBy(double s); + + void EdgeNormalsWithinSurface(Point2d auv, Point2d buv, + Vector *pt, Vector *enin, Vector *enout, + Vector *surfn, + uint32_t auxA, + SShell *shell, SShell *sha, SShell *shb); + void FindChainAvoiding(SEdgeList *src, SEdgeList *dest, SPointList *avoid); + SSurface MakeCopyTrimAgainst(SShell *parent, SShell *a, SShell *b, + SShell *into, SSurface::CombineAs type, int dbg_index); + void TrimFromEdgeList(SEdgeList *el, bool asUv); + void IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB, + SShell *into); + void AddExactIntersectionCurve(SBezier *sb, SSurface *srfB, + SShell *agnstA, SShell *agnstB, SShell *into); + + typedef struct { + int tag; + Point2d p; + } Inter; + void WeightControlPoints(); + void UnWeightControlPoints(); + void CopyRowOrCol(bool row, int this_ij, SSurface *src, int src_ij); + void BlendRowOrCol(bool row, int this_ij, SSurface *a, int a_ij, + SSurface *b, int b_ij); + double DepartureFromCoplanar() const; + void SplitInHalf(bool byU, SSurface *sa, SSurface *sb); + void AllPointsIntersecting(Vector a, Vector b, + List *l, + bool asSegment, bool trimmed, bool inclTangent); + void AllPointsIntersectingUntrimmed(Vector a, Vector b, + int *cnt, int *level, + List *l, bool asSegment, + SSurface *sorig); + + void ClosestPointTo(Vector p, Point2d *puv, bool mustConverge=true); + void ClosestPointTo(Vector p, double *u, double *v, bool mustConverge=true); + bool ClosestPointNewton(Vector p, double *u, double *v, bool mustConverge=true) const; + + bool PointIntersectingLine(Vector p0, Vector p1, double *u, double *v) const; + Vector ClosestPointOnThisAndSurface(SSurface *srf2, Vector p); + void PointOnSurfaces(SSurface *s1, SSurface *s2, double *u, double *v); + void PointOnCurve(const SBezier *curve, double *up, double *vp); + Vector PointAt(double u, double v) const; + Vector PointAt(Point2d puv) const; + void TangentsAt(double u, double v, Vector *tu, Vector *tv, bool retry=true) const; + Vector NormalAt(Point2d puv) const; + Vector NormalAt(double u, double v) const; + bool LineEntirelyOutsideBbox(Vector a, Vector b, bool asSegment) const; + void GetAxisAlignedBounding(Vector *ptMax, Vector *ptMin) const; + bool CoincidentWithPlane(Vector n, double d) const; + bool CoincidentWith(SSurface *ss, bool sameNormal) const; + bool ContainsPlaneCurve(SCurve *sc) const; + bool IsExtrusion(SBezier *of, Vector *along) const; + bool IsCylinder(Vector *axis, Vector *center, double *r, + Vector *start, Vector *finish) const; + + void TriangulateInto(SShell *shell, SMesh *sm); + + // these are intended as bitmasks, even though there's just one now + enum class MakeAs : uint32_t { + UV = 0x01, + XYZ = 0x00 + }; + void MakeTrimEdgesInto(SEdgeList *sel, MakeAs flags, SCurve *sc, STrimBy *stb); + void MakeEdgesInto(SShell *shell, SEdgeList *sel, MakeAs flags, + SShell *useCurvesFrom=NULL); + + Vector ExactSurfaceTangentAt(Vector p, SSurface *srfA, SSurface *srfB, + Vector dir); + void MakeSectionEdgesInto(SShell *shell, SEdgeList *sel, SBezierList *sbl); + void MakeClassifyingBsp(SShell *shell, SShell *useCurvesFrom); + double ChordToleranceForEdge(Vector a, Vector b) const; + void MakeTriangulationGridInto(List *l, double vs, double vf, + bool swapped, int depth) const; + Vector PointAtMaybeSwapped(double u, double v, bool swapped) const; + Vector NormalAtMaybeSwapped(double u, double v, bool swapped) const; + + void Reverse(); + void Clear(); +}; + +class SShell { +public: + IdList curve; + IdList surface; + + bool booleanFailed; + + void MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1, + RgbaColor color); + bool CheckNormalAxisRelationship(SBezierLoopSet *sbls, Vector pt, Vector axis, double da, double dx); + void MakeFromRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis, + RgbaColor color, Group *group); + void MakeFromHelicalRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector axis, RgbaColor color, + Group *group, double angles, double anglef, double dists, double distf); + void MakeFirstOrderRevolvedSurfaces(Vector pt, Vector axis, int i0); + void MakeFromUnionOf(SShell *a, SShell *b); + void MakeFromDifferenceOf(SShell *a, SShell *b); + void MakeFromIntersectionOf(SShell *a, SShell *b); + void MakeFromBoolean(SShell *a, SShell *b, SSurface::CombineAs type); + void CopyCurvesSplitAgainst(bool opA, SShell *agnst, SShell *into); + void CopySurfacesTrimAgainst(SShell *sha, SShell *shb, SShell *into, SSurface::CombineAs type); + void MakeIntersectionCurvesAgainst(SShell *against, SShell *into); + void MakeClassifyingBsps(SShell *useCurvesFrom); + void AllPointsIntersecting(Vector a, Vector b, List *il, + bool asSegment, bool trimmed, bool inclTangent); + void MakeCoincidentEdgesInto(SSurface *proto, bool sameNormal, + SEdgeList *el, SShell *useCurvesFrom); + void RewriteSurfaceHandlesForCurves(SShell *a, SShell *b); + void CleanupAfterBoolean(); + + // Definitions when classifying regions of a surface; it is either inside, + // outside, or coincident (with parallel or antiparallel normal) with a + // shell. + enum class Class : uint32_t { + INSIDE = 100, + OUTSIDE = 200, + COINC_SAME = 300, + COINC_OPP = 400 + }; + static const double DOTP_TOL; + Class ClassifyRegion(Vector edge_n, Vector inter_surf_n, + Vector edge_surf_n) const; + + bool ClassifyEdge(Class *indir, Class *outdir, + Vector ea, Vector eb, + Vector p, Vector edge_n_in, + Vector edge_n_out, Vector surf_n); + + void MakeFromCopyOf(SShell *a); + void MakeFromTransformationOf(SShell *a, + Vector trans, Quaternion q, double scale); + void MakeFromAssemblyOf(SShell *a, SShell *b); + void MergeCoincidentSurfaces(); + + void TriangulateInto(SMesh *sm); + void MakeEdgesInto(SEdgeList *sel); + void MakeSectionEdgesInto(Vector n, double d, SEdgeList *sel, SBezierList *sbl); + bool IsEmpty() const; + void RemapFaces(Group *g, int remap); + void Clear(); +}; + +#endif + diff --git a/src/srf/surfinter.cpp b/src/srf/surfinter.cpp new file mode 100644 index 0000000..0a82776 --- /dev/null +++ b/src/srf/surfinter.cpp @@ -0,0 +1,597 @@ +//----------------------------------------------------------------------------- +// How to intersect two surfaces, to get some type of curve. This is either +// an exact special case (e.g., two planes to make a line), or a numerical +// thing. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +extern int FLAG; + +void SSurface::AddExactIntersectionCurve(SBezier *sb, SSurface *srfB, + SShell *agnstA, SShell *agnstB, SShell *into) +{ + SCurve sc = {}; + // Important to keep the order of (surfA, surfB) consistent; when we later + // rewrite the identifiers, we rewrite surfA from A and surfB from B. + sc.surfA = h; + sc.surfB = srfB->h; + sc.exact = *sb; + sc.isExact = true; + + // Now we have to piecewise linearize the curve. If there's already an + // identical curve in the shell, then follow that pwl exactly, otherwise + // calculate from scratch. + SCurve split, *existing = NULL, *se; + SBezier sbrev = *sb; + sbrev.Reverse(); + bool backwards = false; +#pragma omp critical(into) + { + for(se = into->curve.First(); se; se = into->curve.NextAfter(se)) { + if(se->isExact) { + if(sb->Equals(&(se->exact))) { + existing = se; + break; + } + if(sbrev.Equals(&(se->exact))) { + existing = se; + backwards = true; + break; + } + } + } + }// end omp critical + if(existing) { + SCurvePt *v; + for(v = existing->pts.First(); v; v = existing->pts.NextAfter(v)) { + sc.pts.Add(v); + } + if(backwards) sc.pts.Reverse(); + split = sc; + sc = {}; + } else { + sb->MakePwlInto(&(sc.pts)); + // and split the line where it intersects our existing surfaces + split = sc.MakeCopySplitAgainst(agnstA, agnstB, this, srfB); + sc.Clear(); + } + + // Test if the curve lies entirely outside one of the + SCurvePt *scpt; + bool withinA = false, withinB = false; + for(scpt = split.pts.First(); scpt; scpt = split.pts.NextAfter(scpt)) { + double tol = 0.01; + Point2d puv; + ClosestPointTo(scpt->p, &puv); + if(puv.x > -tol && puv.x < 1 + tol && + puv.y > -tol && puv.y < 1 + tol) + { + withinA = true; + } + srfB->ClosestPointTo(scpt->p, &puv); + if(puv.x > -tol && puv.x < 1 + tol && + puv.y > -tol && puv.y < 1 + tol) + { + withinB = true; + } + // Break out early, no sense wasting time if we already have the answer. + if(withinA && withinB) break; + } + if(!(withinA && withinB)) { + // Intersection curve lies entirely outside one of the surfaces, so + // it's fake. + split.Clear(); + return; + } + +#if 0 + if(sb->deg == 2) { + dbp(" "); + SCurvePt *prev = NULL, *v; + dbp("split.pts.n = %d", split.pts.n); + for(v = split.pts.First(); v; v = split.pts.NextAfter(v)) { + if(prev) { + Vector e = (prev->p).Minus(v->p).WithMagnitude(0); + SS.nakedEdges.AddEdge((prev->p).Plus(e), (v->p).Minus(e)); + } + prev = v; + } + } +#endif // 0 + ssassert(!(sb->Start()).Equals(sb->Finish()), + "Unexpected zero-length edge"); + + split.source = SCurve::Source::INTERSECTION; +#pragma omp critical(into) + { + into->curve.AddAndAssignId(&split); + } +} + +void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB, + SShell *into) +{ + Vector amax, amin, bmax, bmin; + GetAxisAlignedBounding(&amax, &amin); + b->GetAxisAlignedBounding(&bmax, &bmin); + + if(Vector::BoundingBoxesDisjoint(amax, amin, bmax, bmin)) { + // They cannot possibly intersect, no curves to generate + return; + } + + Vector alongt, alongb; + SBezier oft, ofb; + bool isExtdt = this->IsExtrusion(&oft, &alongt), + isExtdb = b->IsExtrusion(&ofb, &alongb); + + if(degm == 1 && degn == 1 && b->degm == 1 && b->degn == 1) { + // Line-line intersection; it's a plane or nothing. + Vector na = NormalAt(0, 0).WithMagnitude(1), + nb = b->NormalAt(0, 0).WithMagnitude(1); + double da = na.Dot(PointAt(0, 0)), + db = nb.Dot(b->PointAt(0, 0)); + + Vector dl = na.Cross(nb); + if(dl.Magnitude() < LENGTH_EPS) return; // parallel planes + dl = dl.WithMagnitude(1); + Vector p = Vector::AtIntersectionOfPlanes(na, da, nb, db); + + // Trim it to the region 0 <= {u,v} <= 1 for each plane; not strictly + // necessary, since line will be split and excess edges culled, but + // this improves speed and robustness. + int i; + double tmax = VERY_POSITIVE, tmin = VERY_NEGATIVE; + for(i = 0; i < 2; i++) { + SSurface *s = (i == 0) ? this : b; + Vector tu, tv; + s->TangentsAt(0, 0, &tu, &tv); + + double up, vp, ud, vd; + s->ClosestPointTo(p, &up, &vp); + ud = (dl.Dot(tu)) / tu.MagSquared(); + vd = (dl.Dot(tv)) / tv.MagSquared(); + + // so u = up + t*ud + // v = vp + t*vd + if(ud > LENGTH_EPS) { + tmin = max(tmin, -up/ud); + tmax = min(tmax, (1 - up)/ud); + } else if(ud < -LENGTH_EPS) { + tmax = min(tmax, -up/ud); + tmin = max(tmin, (1 - up)/ud); + } else { + if(up < -LENGTH_EPS || up > 1 + LENGTH_EPS) { + // u is constant, and outside [0, 1] + tmax = VERY_NEGATIVE; + } + } + if(vd > LENGTH_EPS) { + tmin = max(tmin, -vp/vd); + tmax = min(tmax, (1 - vp)/vd); + } else if(vd < -LENGTH_EPS) { + tmax = min(tmax, -vp/vd); + tmin = max(tmin, (1 - vp)/vd); + } else { + if(vp < -LENGTH_EPS || vp > 1 + LENGTH_EPS) { + // v is constant, and outside [0, 1] + tmax = VERY_NEGATIVE; + } + } + } + + if(tmax > tmin + LENGTH_EPS) { + SBezier bezier = SBezier::From(p.Plus(dl.ScaledBy(tmin)), + p.Plus(dl.ScaledBy(tmax))); + AddExactIntersectionCurve(&bezier, b, agnstA, agnstB, into); + } + } else if((degm == 1 && degn == 1 && isExtdb) || + (b->degm == 1 && b->degn == 1 && isExtdt)) + { + // The intersection between a plane and a surface of extrusion + SSurface *splane, *sext; + if(degm == 1 && degn == 1) { + splane = this; + sext = b; + } else { + splane = b; + sext = this; + } + + Vector n = splane->NormalAt(0, 0).WithMagnitude(1), along; + double d = n.Dot(splane->PointAt(0, 0)); + SBezier bezier; + (void)sext->IsExtrusion(&bezier, &along); + + if(fabs(n.Dot(along)) < LENGTH_EPS) { + // Direction of extrusion is parallel to plane; so intersection + // is zero or more lines. Build a line within the plane, and + // normal to the direction of extrusion, and intersect that line + // against the surface; each intersection point corresponds to + // a line. + Vector pm, alu, p0, dp; + // a point halfway along the extrusion + pm = ((sext->ctrl[0][0]).Plus(sext->ctrl[0][1])).ScaledBy(0.5); + alu = along.WithMagnitude(1); + dp = (n.Cross(along)).WithMagnitude(1); + // n, alu, and dp form an orthogonal csys; set n component to + // place it on the plane, alu component to lie halfway along + // extrusion, and dp component doesn't matter so zero + p0 = n.ScaledBy(d).Plus(alu.ScaledBy(pm.Dot(alu))); + + List inters = {}; + sext->AllPointsIntersecting(p0, p0.Plus(dp), &inters, + /*asSegment=*/false, /*trimmed=*/false, /*inclTangent=*/true); + + SInter *si; + for(si = inters.First(); si; si = inters.NextAfter(si)) { + Vector al = along.ScaledBy(0.5); + SBezier bezier; + bezier = SBezier::From((si->p).Minus(al), (si->p).Plus(al)); + AddExactIntersectionCurve(&bezier, b, agnstA, agnstB, into); + } + + inters.Clear(); + } else { + // Direction of extrusion is not parallel to plane; so + // intersection is projection of extruded curve into our plane. + int i; + for(i = 0; i <= bezier.deg; i++) { + Vector p0 = bezier.ctrl[i], + p1 = p0.Plus(along); + + bezier.ctrl[i] = + Vector::AtIntersectionOfPlaneAndLine(n, d, p0, p1, NULL); + } + + AddExactIntersectionCurve(&bezier, b, agnstA, agnstB, into); + } + } else if(isExtdt && isExtdb && + sqrt(fabs(alongt.Dot(alongb))) > + sqrt(alongt.Magnitude() * alongb.Magnitude()) - LENGTH_EPS) + { + // Two surfaces of extrusion along the same axis. So they might + // intersect along some number of lines parallel to the axis. + Vector axis = alongt.WithMagnitude(1); + + List inters = {}; + List lv = {}; + + double a_axis0 = ( ctrl[0][0]).Dot(axis), + a_axis1 = ( ctrl[0][1]).Dot(axis), + b_axis0 = (b->ctrl[0][0]).Dot(axis), + b_axis1 = (b->ctrl[0][1]).Dot(axis); + + if(a_axis0 > a_axis1) swap(a_axis0, a_axis1); + if(b_axis0 > b_axis1) swap(b_axis0, b_axis1); + + double ab_axis0 = max(a_axis0, b_axis0), + ab_axis1 = min(a_axis1, b_axis1); + + if(fabs(ab_axis0 - ab_axis1) < LENGTH_EPS) { + // The line would be zero-length + return; + } + + Vector axis0 = axis.ScaledBy(ab_axis0), + axis1 = axis.ScaledBy(ab_axis1), + axisc = (axis0.Plus(axis1)).ScaledBy(0.5); + + oft.MakePwlInto(&lv); + + int i; + for(i = 0; i < lv.n - 1; i++) { + Vector pa = lv[i], pb = lv[i+1]; + pa = pa.Minus(axis.ScaledBy(pa.Dot(axis))); + pb = pb.Minus(axis.ScaledBy(pb.Dot(axis))); + pa = pa.Plus(axisc); + pb = pb.Plus(axisc); + + b->AllPointsIntersecting(pa, pb, &inters, + /*asSegment=*/true,/*trimmed=*/false, /*inclTangent=*/false); + } + + SInter *si; + for(si = inters.First(); si; si = inters.NextAfter(si)) { + Vector p = (si->p).Minus(axis.ScaledBy((si->p).Dot(axis))); + double ub, vb; + b->ClosestPointTo(p, &ub, &vb, /*mustConverge=*/true); + SSurface plane; + plane = SSurface::FromPlane(p, axis.Normal(0), axis.Normal(1)); + + b->PointOnSurfaces(this, &plane, &ub, &vb); + + p = b->PointAt(ub, vb); + + SBezier bezier; + bezier = SBezier::From(p.Plus(axis0), p.Plus(axis1)); + AddExactIntersectionCurve(&bezier, b, agnstA, agnstB, into); + } + + inters.Clear(); + lv.Clear(); + } else { + if((degm == 1 && degn == 1) || (b->degm == 1 && b->degn == 1)) { + // we should only be here if just one surface is a plane because the + // plane-plane case was already handled above. Need to check the other + // nonplanar surface for trim curves that lie in the plane and are not + // already trimming both surfaces. This happens when we cut a Lathe shell + // on one of the seams for example. + // This also seems necessary to merge some coincident surfaces. + SSurface *splane, *sext; + SShell *shext; + if(degm == 1 && degn == 1) { // this and other checks assume coplanar ctrl pts. + splane = this; + sext = b; + shext = agnstB; + } else { + splane = b; + sext = this; + shext = agnstA; + } + bool foundExact = false; + SCurve *sc; + for(sc = shext->curve.First(); sc; sc = shext->curve.NextAfter(sc)) { + if(sc->source == SCurve::Source::INTERSECTION) continue; + if(!sc->isExact) continue; + if((sc->surfA != sext->h) && (sc->surfB != sext->h)) continue; + // we have a curve belonging to the curved surface and not the plane. + // does it lie completely in the plane? + if(splane->ContainsPlaneCurve(sc)) { + SBezier bezier = sc->exact; + AddExactIntersectionCurve(&bezier, b, agnstA, agnstB, into); + foundExact = true; + } + } + // if we found at lest one of these we don't want to do the numerical + // intersection as well. Sometimes it will also find the same curve but + // with different PWLs and the polygon will fail to assemble. + if(foundExact) + return; + } + + // Try intersecting the surfaces numerically, by a marching algorithm. + // First, we find all the intersections between a surface and the + // boundary of the other surface. + SPointList spl = {}; + int a; + for(a = 0; a < 2; a++) { + SShell *shA = (a == 0) ? agnstA : agnstB; + SSurface *srfA = (a == 0) ? this : b, + *srfB = (a == 0) ? b : this; + + SEdgeList el = {}; + srfA->MakeEdgesInto(shA, &el, MakeAs::XYZ, NULL); + + SEdge *se; + for(se = el.l.First(); se; se = el.l.NextAfter(se)) { + List lsi = {}; + + srfB->AllPointsIntersecting(se->a, se->b, &lsi, + /*asSegment=*/true, /*trimmed=*/true, /*inclTangent=*/false); + if(lsi.IsEmpty()) + continue; + + // Find the other surface that this curve trims. + hSCurve hsc = { (uint32_t)se->auxA }; + SCurve *sc = shA->curve.FindById(hsc); + hSSurface hother = (sc->surfA == srfA->h) ? + sc->surfB : sc->surfA; + SSurface *other = shA->surface.FindById(hother); + + SInter *si; + for(si = lsi.First(); si; si = lsi.NextAfter(si)) { + Vector p = si->p; + double u, v; + srfB->ClosestPointTo(p, &u, &v); + if(sc->isExact) { + srfB->PointOnCurve(&(sc->exact), &u, &v); + } else { + srfB->PointOnSurfaces(srfA, other, &u, &v); + } + p = srfB->PointAt(u, v); + if(!spl.ContainsPoint(p)) { + SPoint sp; + sp.p = p; + // We also need the edge normal, so that we know in + // which direction to march. + srfA->ClosestPointTo(p, &u, &v); + Vector n = srfA->NormalAt(u, v); + sp.auxv = n.Cross((se->b).Minus(se->a)); + sp.auxv = (sp.auxv).WithMagnitude(1); + + spl.l.Add(&sp); + } + } + lsi.Clear(); + } + + el.Clear(); + } + + while(spl.l.n >= 2) { + SCurve sc = {}; + sc.surfA = h; + sc.surfB = b->h; + sc.isExact = false; + sc.source = SCurve::Source::INTERSECTION; + + Vector start = spl.l[0].p, + startv = spl.l[0].auxv; + spl.l.ClearTags(); + spl.l[0].tag = 1; + spl.l.RemoveTagged(); + + // Our chord tolerance is whatever the user specified + double maxtol = SS.ChordTolMm(); + int maxsteps = max(300, SS.GetMaxSegments()*3); + + // The curve starts at our starting point. + SCurvePt padd = {}; + padd.vertex = true; + padd.p = start; + sc.pts.Add(&padd); + + Point2d pa, pb; + Vector np, npc = Vector::From(0, 0, 0); + bool fwd = false; + // Better to start with a too-small step, so that we don't miss + // features of the curve entirely. + double tol, step = maxtol; + for(a = 0; a < maxsteps; a++) { + ClosestPointTo(start, &pa); + b->ClosestPointTo(start, &pb); + + Vector na = NormalAt(pa).WithMagnitude(1), + nb = b->NormalAt(pb).WithMagnitude(1); + + if(a == 0) { + Vector dp = nb.Cross(na); + if(dp.Dot(startv) < 0) { + // We want to march in the more inward direction. + fwd = true; + } else { + fwd = false; + } + } + + int i; + for(i = 0; i < 20; i++) { + Vector dp = nb.Cross(na); + if(!fwd) dp = dp.ScaledBy(-1); + dp = dp.WithMagnitude(step); + + np = start.Plus(dp); + npc = ClosestPointOnThisAndSurface(b, np); + tol = (npc.Minus(np)).Magnitude(); + + if(tol > maxtol*0.8) { + step *= 0.90; + } else { + step /= 0.90; + } + + if((tol < maxtol) && (tol > maxtol/2)) { + // If we meet the chord tolerance test, and we're + // not too fine, then we break out. + break; + } + } + + SPoint *sp; + for(sp = spl.l.First(); sp; sp = spl.l.NextAfter(sp)) { + if((sp->p).OnLineSegment(start, npc, 2*SS.ChordTolMm())) { + sp->tag = 1; + a = maxsteps; + npc = sp->p; + } + } + + padd.p = npc; + padd.vertex = (a == maxsteps); + sc.pts.Add(&padd); + + start = npc; + } + + spl.l.RemoveTagged(); + + // And now we split and insert the curve + SCurve split = sc.MakeCopySplitAgainst(agnstA, agnstB, this, b); + sc.Clear(); +#pragma omp critical(into) + { + into->curve.AddAndAssignId(&split); + } + } + spl.Clear(); + } +} + +//----------------------------------------------------------------------------- +// Are two surfaces coincident, with the same (or with opposite) normals? +// Currently handles planes only. +//----------------------------------------------------------------------------- +bool SSurface::CoincidentWith(SSurface *ss, bool sameNormal) const { + if(degm != 1 || degn != 1) return false; + if(ss->degm != 1 || ss->degn != 1) return false; + + Vector p = ctrl[0][0]; + Vector n = NormalAt(0, 0).WithMagnitude(1); + double d = n.Dot(p); + + if(!ss->CoincidentWithPlane(n, d)) return false; + + Vector n2 = ss->NormalAt(0, 0); + if(sameNormal) { + if(n2.Dot(n) < 0) return false; + } else { + if(n2.Dot(n) > 0) return false; + } + + return true; +} + +bool SSurface::CoincidentWithPlane(Vector n, double d) const { + if(degm != 1 || degn != 1) return false; + if(fabs(n.Dot(ctrl[0][0]) - d) > LENGTH_EPS) return false; + if(fabs(n.Dot(ctrl[0][1]) - d) > LENGTH_EPS) return false; + if(fabs(n.Dot(ctrl[1][0]) - d) > LENGTH_EPS) return false; + if(fabs(n.Dot(ctrl[1][1]) - d) > LENGTH_EPS) return false; + + return true; +} + +//----------------------------------------------------------------------------- +// Does a planar surface contain a curve? Does the curve lie completely in plane? +//----------------------------------------------------------------------------- +bool SSurface::ContainsPlaneCurve(SCurve *sc) const { + if(degm != 1 || degn != 1) return false; + if(!sc->isExact) return false; // we don't handle those (yet?) + + Vector p = ctrl[0][0]; + Vector n = NormalAt(0, 0).WithMagnitude(1); + double d = n.Dot(p); + + // check all control points on the curve + for(int i=0; i<= sc->exact.deg; i++) { + if(fabs(n.Dot(sc->exact.ctrl[i]) - d) > LENGTH_EPS) return false; + } + return true; +} + +//----------------------------------------------------------------------------- +// In our shell, find all surfaces that are coincident with the prototype +// surface (with same or opposite normal, as specified), and copy all of +// their trim polygons into el. The edges are returned in uv coordinates for +// the prototype surface. +//----------------------------------------------------------------------------- +void SShell::MakeCoincidentEdgesInto(SSurface *proto, bool sameNormal, + SEdgeList *el, SShell *useCurvesFrom) +{ + SSurface *ss; + for(ss = surface.First(); ss; ss = surface.NextAfter(ss)) { + if(proto->CoincidentWith(ss, sameNormal)) { + ss->MakeEdgesInto(this, el, SSurface::MakeAs::XYZ, useCurvesFrom); + } + } + + SEdge *se; + for(se = el->l.First(); se; se = el->l.NextAfter(se)) { + double ua, va, ub, vb; + proto->ClosestPointTo(se->a, &ua, &va); + proto->ClosestPointTo(se->b, &ub, &vb); + + if(sameNormal) { + se->a = Vector::From(ua, va, 0); + se->b = Vector::From(ub, vb, 0); + } else { + // Flip normal, so flip all edge directions + se->b = Vector::From(ua, va, 0); + se->a = Vector::From(ub, vb, 0); + } + } +} + diff --git a/src/srf/triangulate.cpp b/src/srf/triangulate.cpp new file mode 100644 index 0000000..d02f963 --- /dev/null +++ b/src/srf/triangulate.cpp @@ -0,0 +1,734 @@ +//----------------------------------------------------------------------------- +// Triangulate a surface. If the surface is curved, then we first superimpose +// a grid of quads, with spacing to achieve our chord tolerance. We then +// proceed by ear-clipping; the resulting mesh should be watertight and not +// awful numerically, but has no special properties (Delaunay, etc.). +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "../solvespace.h" + +void SPolygon::UvTriangulateInto(SMesh *m, SSurface *srf) { + if(l.n <= 0) return; + + //int64_t in = GetMilliseconds(); + + normal = Vector::From(0, 0, 1); + + while(l.n > 0) { + FixContourDirections(); + l.ClearTags(); + + // Find a top-level contour, and start with that. Then build bridges + // in order to merge all its islands into a single contour. + SContour *top; + for(top = l.First(); top; top = l.NextAfter(top)) { + if(top->timesEnclosed == 0) { + break; + } + } + if(!top) { + dbp("polygon has no top-level contours?"); + return; + } + + // Start with the outer contour + SContour merged = {}; + top->tag = 1; + top->CopyInto(&merged); + merged.l.RemoveLast(1); + + // List all of the edges, for testing whether bridges work. + SEdgeList el = {}; + top->MakeEdgesInto(&el); + List vl = {}; + + // And now find all of its holes. Note that we will also find any + // outer contours that lie entirely within this contour, and any + // holes for those contours. But that's okay, because we can merge + // those too. + SContour *sc; + for(sc = l.First(); sc; sc = l.NextAfter(sc)) { + if(sc->timesEnclosed != 1) continue; + if(sc->l.n < 2) continue; + + // Test the midpoint of an edge. Our polygon may not be self- + // intersecting, but two contours may share a vertex; so a + // vertex could be on the edge of another polygon, in which + // case ContainsPointProjdToNormal returns indeterminate. + Vector tp = sc->AnyEdgeMidpoint(); + if(top->ContainsPointProjdToNormal(normal, tp)) { + sc->tag = 2; + sc->MakeEdgesInto(&el); + sc->FindPointWithMinX(); + } + } + +// dbp("finished finding holes: %d ms", (int)(GetMilliseconds() - in)); + for(;;) { + double xmin = 1e10; + SContour *scmin = NULL; + + for(sc = l.First(); sc; sc = l.NextAfter(sc)) { + if(sc->tag != 2) continue; + + if(sc->xminPt.x < xmin) { + xmin = sc->xminPt.x; + scmin = sc; + } + } + if(!scmin) break; + + if(!merged.BridgeToContour(scmin, &el, &vl)) { + dbp("couldn't merge our hole"); + return; + } +// dbp(" bridged to contour: %d ms", (int)(GetMilliseconds() - in)); + scmin->tag = 3; + } +// dbp("finished merging holes: %d ms", (int)(GetMilliseconds() - in)); + + merged.UvTriangulateInto(m, srf); +// dbp("finished ear clippping: %d ms", (int)(GetMilliseconds() - in)); + merged.l.Clear(); + el.Clear(); + vl.Clear(); + + // Careful, need to free the points within the contours, and not just + // the contours themselves. This was a tricky memory leak. + for(sc = l.First(); sc; sc = l.NextAfter(sc)) { + if(sc->tag) { + sc->l.Clear(); + } + } + l.RemoveTagged(); + } +} + +bool SContour::BridgeToContour(SContour *sc, + SEdgeList *avoidEdges, List *avoidPts) +{ + int i, j; + bool withbridge = true; + + // Start looking for a bridge on our new hole near its leftmost (min x) + // point. + int sco = 0; + for(i = 0; i < (sc->l.n - 1); i++) { + if((sc->l[i].p).EqualsExactly(sc->xminPt)) { + sco = i; + } + } + + // And start looking on our merged contour at whichever point is nearest + // to the leftmost point of the new segment. + int thiso = 0; + double dmin = 1e10; + for(i = 0; i < l.n-1; i++) { + Vector p = l[i].p; + double d = (p.Minus(sc->xminPt)).MagSquared(); + if(d < dmin) { + dmin = d; + thiso = i; + } + } + + int thisp, scp; + + Vector a, b, *f; + + // First check if the contours share a point; in that case we should + // merge them there, without a bridge. + for(i = 0; i < l.n; i++) { + thisp = WRAP(i+thiso, l.n-1); + a = l[thisp].p; + + for(f = avoidPts->First(); f; f = avoidPts->NextAfter(f)) { + if(f->Equals(a)) break; + } + if(f) continue; + + for(j = 0; j < (sc->l.n - 1); j++) { + scp = WRAP(j+sco, (sc->l.n - 1)); + b = sc->l[scp].p; + + if(a.Equals(b)) { + withbridge = false; + goto haveEdge; + } + } + } + + // If that fails, look for a bridge that does not intersect any edges. + for(i = 0; i < l.n; i++) { + thisp = WRAP(i+thiso, l.n); + a = l[thisp].p; + + for(f = avoidPts->First(); f; f = avoidPts->NextAfter(f)) { + if(f->Equals(a)) break; + } + if(f) continue; + + for(j = 0; j < (sc->l.n - 1); j++) { + scp = WRAP(j+sco, (sc->l.n - 1)); + b = sc->l[scp].p; + + for(f = avoidPts->First(); f; f = avoidPts->NextAfter(f)) { + if(f->Equals(b)) break; + } + if(f) continue; + + if(avoidEdges->AnyEdgeCrossings(a, b) > 0) { + // doesn't work, bridge crosses an existing edge + } else { + goto haveEdge; + } + } + } + + // Tried all the possibilities, didn't find an edge + return false; + +haveEdge: + SContour merged = {}; + for(i = 0; i < l.n; i++) { + if(withbridge || (i != thisp)) { + merged.AddPoint(l[i].p); + } + if(i == thisp) { + // less than or equal; need to duplicate the join point + for(j = 0; j <= (sc->l.n - 1); j++) { + int jp = WRAP(j + scp, (sc->l.n - 1)); + merged.AddPoint((sc->l[jp]).p); + } + // and likewise duplicate join point for the outer curve + if(withbridge) { + merged.AddPoint(l[i].p); + } + } + } + + // and future bridges mustn't cross our bridge, and it's tricky to get + // things right if two bridges come from the same point + if(withbridge) { + avoidEdges->AddEdge(a, b); + avoidPts->Add(&a); + } + avoidPts->Add(&b); + + l.Clear(); + l = merged.l; + return true; +} + +bool SContour::IsEmptyTriangle(int ap, int bp, int cp, double scaledEPS) const { + + STriangle tr = {}; + tr.a = l[ap].p; + tr.b = l[bp].p; + tr.c = l[cp].p; + + // Accelerate with an axis-aligned bounding box test + Vector maxv = tr.a, minv = tr.a; + (tr.b).MakeMaxMin(&maxv, &minv); + (tr.c).MakeMaxMin(&maxv, &minv); + + Vector n = Vector::From(0, 0, -1); + + int i; + for(i = 0; i < l.n; i++) { + if(i == ap || i == bp || i == cp) continue; + + Vector p = l[i].p; + if(p.OutsideAndNotOn(maxv, minv)) continue; + + // A point on the edge of the triangle is considered to be inside, + // and therefore makes it a non-ear; but a point on the vertex is + // "outside", since that's necessary to make bridges work. + if(p.EqualsExactly(tr.a)) continue; + if(p.EqualsExactly(tr.b)) continue; + if(p.EqualsExactly(tr.c)) continue; + + if(tr.ContainsPointProjd(n, p)) { + return false; + } + } + return true; +} + +// Test if ray b->d passes through triangle a,b,c +static bool RayIsInside(Vector a, Vector c, Vector b, Vector d) { + // coincident edges are not considered to intersect the triangle + if (d.Equals(a)) return false; + if (d.Equals(c)) return false; + // if d and c are on opposite sides of ba, we are ok + // likewise if d and a are on opposite sides of bc + Vector ba = a.Minus(b); + Vector bc = c.Minus(b); + Vector bd = d.Minus(b); + + // perpendicular to (x,y) is (x,-y) so dot that with the two points. If they + // have opposite signs their product will be negative. If bd and bc are on + // opposite sides of ba the ray does not intersect. Likewise for bd,ba and bc. + if ( (bd.x*(ba.y) + (bd.y * (-ba.x))) * ( bc.x*(ba.y) + (bc.y * (-ba.x))) < LENGTH_EPS) + return false; + if ( (bd.x*(bc.y) + (bd.y * (-bc.x))) * ( ba.x*(bc.y) + (ba.y * (-bc.x))) < LENGTH_EPS) + return false; + + return true; +} + +bool SContour::IsEar(int bp, double scaledEps) const { + int ap = WRAP(bp-1, l.n), + cp = WRAP(bp+1, l.n); + + STriangle tr = {}; + tr.a = l[ap].p; + tr.b = l[bp].p; + tr.c = l[cp].p; + + if((tr.a).Equals(tr.c)) { + // This is two coincident and anti-parallel edges. Zero-area, so + // won't generate a real triangle, but we certainly can clip it. + return true; + } + + Vector n = Vector::From(0, 0, -1); + if((tr.Normal()).Dot(n) < scaledEps) { + // This vertex is reflex, or between two collinear edges; either way, + // it's not an ear. + return false; + } + + // Accelerate with an axis-aligned bounding box test + Vector maxv = tr.a, minv = tr.a; + (tr.b).MakeMaxMin(&maxv, &minv); + (tr.c).MakeMaxMin(&maxv, &minv); + + int i; + for(i = 0; i < l.n; i++) { + if(i == ap || i == bp || i == cp) continue; + + Vector p = l[i].p; + if(p.OutsideAndNotOn(maxv, minv)) continue; + + // A point on the edge of the triangle is considered to be inside, + // and therefore makes it a non-ear; but a point on the vertex is + // "outside", since that's necessary to make bridges work. + if(p.EqualsExactly(tr.a)) continue; + if(p.EqualsExactly(tr.c)) continue; + // points coincident with bp have to be allowed for bridges but edges + // from that other point must not cross through our triangle. + if(p.EqualsExactly(tr.b)) { + int j = WRAP(i-1, l.n); + int k = WRAP(i+1, l.n); + Vector jp = l[j].p; + Vector kp = l[k].p; + + // two consecutive bridges (A,B,C) and later (C,B,A) are not an ear + if (jp.Equals(tr.c) && kp.Equals(tr.a)) return false; + // check both edges from the point in question + if (!RayIsInside(tr.a, tr.c, p,jp) && !RayIsInside(tr.a, tr.c, p,kp)) + continue; + } + + if(tr.ContainsPointProjd(n, p)) { + return false; + } + } + return true; +} + +void SContour::ClipEarInto(SMesh *m, int bp, double scaledEps) { + int ap = WRAP(bp-1, l.n), + cp = WRAP(bp+1, l.n); + + STriangle tr = {}; + tr.a = l[ap].p; + tr.b = l[bp].p; + tr.c = l[cp].p; + if(tr.Normal().MagSquared() < scaledEps*scaledEps) { + // A vertex with more than two edges will cause us to generate + // zero-area triangles, which must be culled. + } else { + m->AddTriangle(&tr); + } + + // By deleting the point at bp, we may change the ear-ness of the points + // on either side. + l[ap].ear = EarType::UNKNOWN; + l[cp].ear = EarType::UNKNOWN; + + l.ClearTags(); + l[bp].tag = 1; + l.RemoveTagged(); +} + +void SContour::UvTriangulateInto(SMesh *m, SSurface *srf) { + Vector tu, tv; + srf->TangentsAt(0.5, 0.5, &tu, &tv); + double s = sqrt(tu.MagSquared() + tv.MagSquared()); + // We would like to apply our tolerances in xyz; but that would be a lot + // of work, so at least scale the epsilon semi-reasonably. That's + // perfect for square planes, less perfect for anything else. + double scaledEps = LENGTH_EPS / s; + + int i; + // Clean the original contour by removing any zero-length edges. + // initialize eartypes to unknown while we're going over them. + l.ClearTags(); + l[0].ear = EarType::UNKNOWN; + for(i = 1; i < l.n; i++) { + l[i].ear = EarType::UNKNOWN; + if((l[i].p).Equals(l[i-1].p)) { + l[i].tag = 1; + } + } + if( (l[0].p).Equals(l[l.n-1].p) ) { + l[l.n-1].tag = 1; + } + l.RemoveTagged(); + + // Handle simple triangle fans all at once. This pass is optional. + if(srf->degm == 1 && srf->degn == 1) { + l.ClearTags(); + int j=0; + int pstart = 0; + double elen = -1.0; + double oldspan = 0.0; + for(i = 1; i < l.n; i++) { + Vector ab = l[i].p.Minus(l[i-1].p); + // first time just measure the segment + if (elen < 0.0) { + elen = ab.Dot(ab); + oldspan = elen; + j = 1; + continue; + } + // check for consecutive segments of similar size which are also + // ears and where the group forms a convex ear + bool end = false; + double ratio = ab.Dot(ab) / elen; + if ((ratio < 0.25) || (ratio > 4.0)) end = true; + + double slen = l[pstart].p.Minus(l[i].p).MagSquared(); + if (slen < oldspan) end = true; + + if (!IsEar(i-1, scaledEps) ) end = true; +// if ((j>0) && !IsEar(pstart, i-1, i, scaledEps)) end = true; + if ((j>0) && !IsEmptyTriangle(pstart, i-1, i, scaledEps)) end = true; + // the new segment is valid so add to the fan + if (!end) { + j++; + oldspan = slen; + } + // we need to stop at the end of polygon but may still + if (i == l.n-1) { + end = true; + } + if (end) { // triangulate the fan and tag the verticies + if (j > 3) { + Vector center = l[pstart+1].p.Plus(l[pstart+j-1].p).ScaledBy(0.5); + for (int x=0; xAddTriangle(&tr); + } + for (int x=1; xAddTriangle(&tr); + } + pstart = i-1; + elen = ab.Dot(ab); + oldspan = elen; + j = 1; + } + } + l.RemoveTagged(); + } // end optional fan creation pass + + bool toggle = false; + while(l.n > 3) { + int bestEar = -1; + double bestChordTol = VERY_POSITIVE; + // Alternate the starting position so we generate strip-like + // triangulations instead of fan-like + toggle = !toggle; + int offset = toggle ? -1 : 0; + for(i = 0; i < l.n; i++) { + int ear = WRAP(i+offset, l.n); + if(l[ear].ear == EarType::UNKNOWN) { + (l[ear]).ear = IsEar(ear, scaledEps) ? EarType::EAR : EarType::NOT_EAR; + } + if(l[ear].ear == EarType::EAR) { + if(srf->degm == 1 && srf->degn == 1) { + // This is a plane; any ear is a good ear. + bestEar = ear; + break; + } + // If we are triangulating a curved surface, then try to + // clip ears that have a small chord tolerance from the + // surface. + Vector prev = l[WRAP((i+offset-1), l.n)].p, + next = l[WRAP((i+offset+1), l.n)].p; + double tol = srf->ChordToleranceForEdge(prev, next); + if(tol < bestChordTol - scaledEps) { + bestEar = ear; + bestChordTol = tol; + } + if(bestChordTol < 0.1*SS.ChordTolMm()) { + break; + } + } + } + if(bestEar < 0) { + dbp("couldn't find an ear! fail"); + return; + } + ClipEarInto(m, bestEar, scaledEps); + } + + ClipEarInto(m, 0, scaledEps); // add the last triangle +} + +double SSurface::ChordToleranceForEdge(Vector a, Vector b) const { + Vector as = PointAt(a.x, a.y), bs = PointAt(b.x, b.y); + + double worst = VERY_NEGATIVE; + int i; + for(i = 1; i <= 3; i++) { + Vector p = a. Plus((b. Minus(a )).ScaledBy(i/4.0)), + ps = as.Plus((bs.Minus(as)).ScaledBy(i/4.0)); + + Vector pps = PointAt(p.x, p.y); + worst = max(worst, (pps.Minus(ps)).MagSquared()); + } + return sqrt(worst); +} + +Vector SSurface::PointAtMaybeSwapped(double u, double v, bool swapped) const { + if(swapped) { + return PointAt(v, u); + } else { + return PointAt(u, v); + } +} + +Vector SSurface::NormalAtMaybeSwapped(double u, double v, bool swapped) const { + Vector du, dv; + if(swapped) { + TangentsAt(v, u, &dv, &du); + } else { + TangentsAt(u, v, &du, &dv); + } + return du.Cross(dv).WithMagnitude(1.0); +} + +void SSurface::MakeTriangulationGridInto(List *l, double vs, double vf, + bool swapped, int depth) const +{ + double worst = 0; + + // Try piecewise linearizing four curves, at u = 0, 1/3, 2/3, 1; choose + // the worst chord tolerance of any of those. + double worst_twist = 1.0; + int i; + for(i = 0; i <= 3; i++) { + double u = i/3.0; + + // This chord test should be identical to the one in SBezier::MakePwl + // to make the piecewise linear edges line up with the grid more or + // less. + Vector ps = PointAtMaybeSwapped(u, vs, swapped), + pf = PointAtMaybeSwapped(u, vf, swapped); + + double vm1 = (2*vs + vf) / 3, + vm2 = (vs + 2*vf) / 3; + + Vector pm1 = PointAtMaybeSwapped(u, vm1, swapped), + pm2 = PointAtMaybeSwapped(u, vm2, swapped); + + // 0.999 is about 2.5 degrees of twist over the middle 1/3 V-span. + // we don't check at the ends because the derivative may not be valid there. + double twist = 1.0; + if (degm == 1) twist = NormalAtMaybeSwapped(u, vm1, swapped).Dot( + NormalAtMaybeSwapped(u, vm2, swapped) ); + if (twist < worst_twist) worst_twist = twist; + + worst = max(worst, pm1.DistanceToLine(ps, pf.Minus(ps))); + worst = max(worst, pm2.DistanceToLine(ps, pf.Minus(ps))); + } + + double step = 1.0/SS.GetMaxSegments(); + if( ((vf - vs) < step || worst < SS.ChordTolMm()) + && ((worst_twist > 0.999) || (depth > 3)) ) { + l->Add(&vf); + } else { + MakeTriangulationGridInto(l, vs, (vs+vf)/2, swapped, depth+1); + MakeTriangulationGridInto(l, (vs+vf)/2, vf, swapped, depth+1); + } +} + +void SPolygon::UvGridTriangulateInto(SMesh *mesh, SSurface *srf) { + SEdgeList orig = {}; + MakeEdgesInto(&orig); + + SEdgeList holes = {}; + + normal = Vector::From(0, 0, 1); + FixContourDirections(); + + // Build a rectangular grid, with horizontal and vertical lines in the + // uv plane. The spacing of these lines is adaptive, so calculate that. + List li, lj; + li = {}; + lj = {}; + double v[5] = {0.0, 0.25, 0.5, 0.75, 1.0}; + li.Add(&v[0]); + srf->MakeTriangulationGridInto(&li, 0, 1, /*swapped=*/true, 0); + lj.Add(&v[0]); + srf->MakeTriangulationGridInto(&lj, 0, 1, /*swapped=*/false, 0); + + // force 2nd order grid to have at least 4 segments in each direction + if ((li.n < 5) && (srf->degm>1)) { // 4 segments minimun + li.Clear(); + li.Add(&v[0]);li.Add(&v[1]);li.Add(&v[2]);li.Add(&v[3]);li.Add(&v[4]); + } + if ((lj.n < 5) && (srf->degn>1)) { // 4 segments minimun + lj.Clear(); + lj.Add(&v[0]);lj.Add(&v[1]);lj.Add(&v[2]);lj.Add(&v[3]);lj.Add(&v[4]); + } + + if ((li.n > 3) && (lj.n > 3)) { + // Now iterate over each quad in the grid. If it's outside the polygon, + // or if it intersects the polygon, then we discard it. Otherwise we + // generate two triangles in the mesh, and cut it out of our polygon. + // Quads around the perimeter would be rejected by AnyEdgeCrossings. + std::vector bottom(lj.n, false); // did we use this quad? + Vector tu = {0,0,0}, tv = {0,0,0}; + int i, j; + for(i = 1; i < (li.n-1); i++) { + bool prev_flag = false; + for(j = 1; j < (lj.n-1); j++) { + bool this_flag = true; + double us = li[i], uf = li[i+1], + vs = lj[j], vf = lj[j+1]; + + Vector a = Vector::From(us, vs, 0), + b = Vector::From(us, vf, 0), + c = Vector::From(uf, vf, 0), + d = Vector::From(uf, vs, 0); + + // | d-----c + // | | | + // | | | + // | a-----b + // | + // +-------------> j/v axis + + if( (i==(li.n-2)) || (j==(lj.n-2)) || + orig.AnyEdgeCrossings(a, b, NULL) || + orig.AnyEdgeCrossings(b, c, NULL) || + orig.AnyEdgeCrossings(c, d, NULL) || + orig.AnyEdgeCrossings(d, a, NULL)) + { + this_flag = false; + } + + // There's no intersections, so it doesn't matter which point + // we decide to test. + if(!this->ContainsPoint(a)) { + this_flag = false; + } + + if (this_flag) { + // Add the quad to our mesh + srf->TangentsAt(us,vs, &tu,&tv); + if(tu.Dot(tv) < LENGTH_EPS) { + /* Split "the other way" if angle>90 + compare to LENGTH_EPS instead of zero to avoid alternating triangle + "orientations" when the tangents are orthogonal (revolve, lathe etc.) + this results in a higher quality mesh. */ + STriangle tr = {}; + tr.a = a; + tr.b = b; + tr.c = c; + mesh->AddTriangle(&tr); + tr.a = a; + tr.b = c; + tr.c = d; + mesh->AddTriangle(&tr); + } else{ + STriangle tr = {}; + tr.a = a; + tr.b = b; + tr.c = d; + mesh->AddTriangle(&tr); + tr.a = b; + tr.b = c; + tr.c = d; + mesh->AddTriangle(&tr); + } + if (!prev_flag) // add our own left edge + holes.AddEdge(d, a); + if (!bottom[j]) // add our own bottom edge + holes.AddEdge(a, b); + } else { + if (prev_flag) // add our left neighbots right edge + holes.AddEdge(a, d); + if (bottom[j]) // add our bottom neighbors top edge + holes.AddEdge(b, a); + } + prev_flag = this_flag; + bottom[j] = this_flag; + } + } + + // Because no duplicate edges were created we do not need to cull them. + SPolygon hp = {}; + holes.AssemblePolygon(&hp, NULL, /*keepDir=*/true); + + SContour *sc; + for(sc = hp.l.First(); sc; sc = hp.l.NextAfter(sc)) { + l.Add(sc); + } + hp.l.Clear(); + } + orig.Clear(); + holes.Clear(); + li.Clear(); + lj.Clear(); + UvTriangulateInto(mesh, srf); +} + +void SPolygon::TriangulateInto(SMesh *m) const { + Vector n = normal; + if(n.Equals(Vector::From(0.0, 0.0, 0.0))) { + n = ComputeNormal(); + } + Vector u = n.Normal(0); + Vector v = n.Normal(1); + + SPolygon p = {}; + this->InverseTransformInto(&p, u, v, n); + + SSurface srf = SSurface::FromPlane(Vector::From(0.0, 0.0, 0.0), + Vector::From(1.0, 0.0, 0.0), + Vector::From(0.0, 1.0, 0.0)); + SMesh pm = {}; + p.UvTriangulateInto(&pm, &srf); + for(STriangle st : pm.l) { + st = st.Transform(u, v, n); + m->AddTriangle(&st); + } + + p.Clear(); + pm.Clear(); +} diff --git a/src/style.cpp b/src/style.cpp new file mode 100644 index 0000000..1f719f6 --- /dev/null +++ b/src/style.cpp @@ -0,0 +1,872 @@ +//----------------------------------------------------------------------------- +// Implementation of a cosmetic line style, which determines the color and +// other appearance of a line or curve on-screen and in exported files. Some +// styles are predefined, and others can be created by the user. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +const Style::Default Style::Defaults[] = { + { { ACTIVE_GRP }, "ActiveGrp", RGBf(1.0, 1.0, 1.0), 1.5, 4 }, + { { CONSTRUCTION }, "Construction", RGBf(0.1, 0.7, 0.1), 1.5, 0 }, + { { INACTIVE_GRP }, "InactiveGrp", RGBf(0.5, 0.3, 0.0), 1.5, 3 }, + { { DATUM }, "Datum", RGBf(0.0, 0.8, 0.0), 1.5, 0 }, + { { SOLID_EDGE }, "SolidEdge", RGBf(0.8, 0.8, 0.8), 1.0, 2 }, + { { CONSTRAINT }, "Constraint", RGBf(1.0, 0.1, 1.0), 1.0, 0 }, + { { SELECTED }, "Selected", RGBf(1.0, 0.0, 0.0), 1.5, 0 }, + { { HOVERED }, "Hovered", RGBf(1.0, 1.0, 0.0), 1.5, 0 }, + { { CONTOUR_FILL }, "ContourFill", RGBf(0.0, 0.1, 0.1), 1.0, 0 }, + { { NORMALS }, "Normals", RGBf(0.0, 0.4, 0.4), 1.0, 0 }, + { { ANALYZE }, "Analyze", RGBf(0.0, 1.0, 1.0), 3.0, 0 }, + { { DRAW_ERROR }, "DrawError", RGBf(1.0, 0.0, 0.0), 8.0, 0 }, + { { DIM_SOLID }, "DimSolid", RGBf(0.1, 0.1, 0.1), 1.0, 0 }, + { { HIDDEN_EDGE }, "HiddenEdge", RGBf(0.8, 0.8, 0.8), 1.0, 1 }, + { { OUTLINE }, "Outline", RGBf(0.8, 0.8, 0.8), 3.0, 5 }, + { { 0 }, NULL, RGBf(0.0, 0.0, 0.0), 0.0, 0 } +}; + +std::string Style::CnfColor(const std::string &prefix) { + return "Style_" + prefix + "_Color"; +} +std::string Style::CnfWidth(const std::string &prefix) { + return "Style_" + prefix + "_Width"; +} +std::string Style::CnfTextHeight(const std::string &prefix) { + return "Style_" + prefix + "_TextHeight"; +} + +std::string Style::CnfPrefixToName(const std::string &prefix) { + std::string name = "#def-"; + + for(size_t i = 0; i < prefix.length(); i++) { + if(isupper(prefix[i]) && i != 0) + name += '-'; + name += tolower(prefix[i]); + } + + return name; +} + +void Style::CreateAllDefaultStyles() { + const Default *d; + for(d = &(Defaults[0]); d->h.v; d++) { + (void)Get(d->h); + } +} + +void Style::CreateDefaultStyle(hStyle h) { + bool isDefaultStyle = true; + const Default *d; + for(d = &(Defaults[0]); d->h.v; d++) { + if(d->h == h) break; + } + if(!d->h.v) { + // Not a default style; so just create it the same as our default + // active group entity style. + d = &(Defaults[0]); + isDefaultStyle = false; + } + + Style ns = {}; + FillDefaultStyle(&ns, d); + ns.h = h; + if(isDefaultStyle) { + ns.name = CnfPrefixToName(d->cnfPrefix); + } else { + ns.name = "new-custom-style"; + } + + SK.style.Add(&ns); +} + +void Style::FillDefaultStyle(Style *s, const Default *d, bool factory) { + Platform::SettingsRef settings = Platform::GetSettings(); + + if(d == NULL) d = &Defaults[0]; + s->color = (factory) + ? d->color + : settings->ThawColor(CnfColor(d->cnfPrefix), d->color); + s->width = (factory) + ? d->width + : settings->ThawFloat(CnfWidth(d->cnfPrefix), (float)(d->width)); + s->widthAs = UnitsAs::PIXELS; + s->textHeight = (factory) ? 11.5 + : settings->ThawFloat(CnfTextHeight(d->cnfPrefix), 11.5); + s->textHeightAs = UnitsAs::PIXELS; + s->textOrigin = TextOrigin::NONE; + s->textAngle = 0; + s->visible = true; + s->exportable = true; + s->filled = false; + s->fillColor = RGBf(0.3, 0.3, 0.3); + s->stippleType = (d->h.v == Style::HIDDEN_EDGE) ? StipplePattern::DASH + : StipplePattern::CONTINUOUS; + s->stippleScale = 15.0; + s->zIndex = d->zIndex; +} + +void Style::LoadFactoryDefaults() { + const Default *d; + for(d = &(Defaults[0]); d->h.v; d++) { + Style *s = Get(d->h); + FillDefaultStyle(s, d, /*factory=*/true); + } + SS.backgroundColor = RGBi(0, 0, 0); +} + +void Style::FreezeDefaultStyles(Platform::SettingsRef settings) { + const Default *d; + for(d = &(Defaults[0]); d->h.v; d++) { + settings->FreezeColor(CnfColor(d->cnfPrefix), Color(d->h)); + settings->FreezeFloat(CnfWidth(d->cnfPrefix), (float)Width(d->h)); + settings->FreezeFloat(CnfTextHeight(d->cnfPrefix), (float)TextHeight(d->h)); + } +} + +uint32_t Style::CreateCustomStyle(bool rememberForUndo) { + if(rememberForUndo) SS.UndoRemember(); + uint32_t vs = max((uint32_t)Style::FIRST_CUSTOM, SK.style.MaximumId() + 1); + hStyle hs = { vs }; + (void)Style::Get(hs); + return hs.v; +} + +void Style::AssignSelectionToStyle(uint32_t v) { + bool showError = false; + SS.GW.GroupSelection(); + + SS.UndoRemember(); + int i; + for(i = 0; i < SS.GW.gs.entities; i++) { + hEntity he = SS.GW.gs.entity[i]; + Entity *e = SK.GetEntity(he); + if(!e->IsStylable()) continue; + + if(!he.isFromRequest()) { + showError = true; + continue; + } + + hRequest hr = he.request(); + Request *r = SK.GetRequest(hr); + r->style.v = v; + SS.MarkGroupDirty(r->group); + } + for(i = 0; i < SS.GW.gs.constraints; i++) { + hConstraint hc = SS.GW.gs.constraint[i]; + Constraint *c = SK.GetConstraint(hc); + if(!c->IsStylable()) continue; + + c->disp.style.v = v; + SS.MarkGroupDirty(c->group); + } + + if(showError) { + Error(_("Can't assign style to an entity that's derived from another " + "entity; try assigning a style to this entity's parent.")); + } + + SS.GW.ClearSelection(); + SS.GW.Invalidate(); + + // And show that style's info screen in the text window. + SS.TW.GoToScreen(TextWindow::Screen::STYLE_INFO); + SS.TW.shown.style.v = v; + SS.ScheduleShowTW(); +} + +//----------------------------------------------------------------------------- +// Look up a style by its handle. If that style does not exist, then create +// the style, according to our table of default styles. +//----------------------------------------------------------------------------- +Style *Style::Get(hStyle h) { + if(h.v == 0) h.v = ACTIVE_GRP; + + Style *s = SK.style.FindByIdNoOops(h); + if(s) { + // It exists, good. + return s; + } else { + // It doesn't exist; so we should create it and then return that. + CreateDefaultStyle(h); + return SK.style.FindById(h); + } +} + +//----------------------------------------------------------------------------- +// A couple of wrappers, so that I can call these functions with either an +// hStyle or with the integer corresponding to that hStyle.v. +//----------------------------------------------------------------------------- +RgbaColor Style::Color(int s, bool forExport) { + hStyle hs = { (uint32_t)s }; + return Color(hs, forExport); +} +double Style::Width(int s) { + hStyle hs = { (uint32_t)s }; + return Width(hs); +} + +//----------------------------------------------------------------------------- +// If a color is almost white, then we can rewrite it to black, just so that +// it won't disappear on file formats with a light background. +//----------------------------------------------------------------------------- +RgbaColor Style::RewriteColor(RgbaColor rgbin) { + Vector rgb = Vector::From(rgbin.redF(), rgbin.greenF(), rgbin.blueF()); + rgb = rgb.Minus(Vector::From(1, 1, 1)); + if(rgb.Magnitude() < 0.4 && SS.fixExportColors) { + // This is an almost-white color in a default style, which is + // good for the default on-screen view (black bg) but probably + // not desired in the exported files, which typically are shown + // against white backgrounds. + return RGBi(0, 0, 0); + } else { + return rgbin; + } +} + +//----------------------------------------------------------------------------- +// Return the stroke color associated with our style as 8-bit RGB. +//----------------------------------------------------------------------------- +RgbaColor Style::Color(hStyle h, bool forExport) { + Style *s = Get(h); + if(forExport) { + return RewriteColor(s->color); + } else { + return s->color; + } +} + +//----------------------------------------------------------------------------- +// Return the fill color associated with our style as 8-bit RGB. +//----------------------------------------------------------------------------- +RgbaColor Style::FillColor(hStyle h, bool forExport) { + Style *s = Get(h); + if(forExport) { + return RewriteColor(s->fillColor); + } else { + return s->fillColor; + } +} + +//----------------------------------------------------------------------------- +// Return the width associated with our style in pixels.. +//----------------------------------------------------------------------------- +double Style::Width(hStyle h) { + Style *s = Get(h); + switch(s->widthAs) { + case UnitsAs::MM: return s->width * SS.GW.scale; + case UnitsAs::PIXELS: return s->width; + } + ssassert(false, "Unexpected units"); +} + +//----------------------------------------------------------------------------- +// Return the width associated with our style in millimeters.. +//----------------------------------------------------------------------------- +double Style::WidthMm(int hs) { + double widthpx = Width(hs); + return widthpx / SS.GW.scale; +} + +//----------------------------------------------------------------------------- +// Return the associated text height, in pixels. +//----------------------------------------------------------------------------- +double Style::TextHeight(hStyle h) { + Style *s = Get(h); + switch(s->textHeightAs) { + case UnitsAs::MM: return s->textHeight * SS.GW.scale; + case UnitsAs::PIXELS: return s->textHeight; + } + ssassert(false, "Unexpected units"); +} + +double Style::DefaultTextHeight() { + hStyle hs { Style::CONSTRAINT }; + return TextHeight(hs); +} + +//----------------------------------------------------------------------------- +// Return the parameters of this style, as a canvas stroke. +//----------------------------------------------------------------------------- +Canvas::Stroke Style::Stroke(hStyle hs) { + Canvas::Stroke stroke = {}; + Style *style = Style::Get(hs); + stroke.color = style->color; + stroke.stipplePattern = style->stippleType; + stroke.stippleScale = style->stippleScale; + stroke.width = style->width; + switch(style->widthAs) { + case Style::UnitsAs::PIXELS: + stroke.unit = Canvas::Unit::PX; + break; + case Style::UnitsAs::MM: + stroke.unit = Canvas::Unit::MM; + break; + } + return stroke; +} + +Canvas::Stroke Style::Stroke(int hsv) { + hStyle hs = { (uint32_t) hsv }; + return Style::Stroke(hs); +} + +//----------------------------------------------------------------------------- +// Should lines and curves from this style appear in the output file? Only +// if it's both shown and exportable. +//----------------------------------------------------------------------------- +bool Style::Exportable(int si) { + hStyle hs = { (uint32_t)si }; + Style *s = Get(hs); + return (s->exportable) && (s->visible); +} + +//----------------------------------------------------------------------------- +// Return the appropriate style for our entity. If the entity has a style +// explicitly assigned, then it's that style. Otherwise it's the appropriate +// default style. +//----------------------------------------------------------------------------- +hStyle Style::ForEntity(hEntity he) { + Entity *e = SK.GetEntity(he); + // If the entity has a special style, use that. If that style doesn't + // exist yet, then it will get created automatically later. + if(e->style.v != 0) { + return e->style; + } + + // Otherwise, we use the default rules. + hStyle hs; + if(e->group != SS.GW.activeGroup) { + hs.v = INACTIVE_GRP; + } else if(e->construction) { + hs.v = CONSTRUCTION; + } else { + hs.v = ACTIVE_GRP; + } + return hs; +} + +StipplePattern Style::PatternType(hStyle hs) { + Style *s = Get(hs); + return s->stippleType; +} + +double Style::StippleScaleMm(hStyle hs) { + Style *s = Get(hs); + if(s->widthAs == UnitsAs::MM) { + return s->stippleScale; + } else if(s->widthAs == UnitsAs::PIXELS) { + return s->stippleScale / SS.GW.scale; + } + return 1.0; +} + +std::string Style::DescriptionString() const { + if(name.empty()) { + return ssprintf("s%03x-(unnamed)", h.v); + } else { + return ssprintf("s%03x-%s", h.v, name.c_str()); + } +} + + +void TextWindow::ScreenShowListOfStyles(int link, uint32_t v) { + SS.TW.GoToScreen(Screen::LIST_OF_STYLES); +} +void TextWindow::ScreenShowStyleInfo(int link, uint32_t v) { + GraphicsWindow::MenuEdit(Command::UNSELECT_ALL); + SS.TW.GoToScreen(Screen::STYLE_INFO); + SS.TW.shown.style.v = v; +} + +void TextWindow::ScreenLoadFactoryDefaultStyles(int link, uint32_t v) { + Style::LoadFactoryDefaults(); + SS.TW.GoToScreen(Screen::LIST_OF_STYLES); +} + +void TextWindow::ScreenCreateCustomStyle(int link, uint32_t v) { + Style::CreateCustomStyle(); +} + +void TextWindow::ScreenChangeBackgroundColor(int link, uint32_t v) { + RgbaColor rgb = SS.backgroundColor; + SS.TW.ShowEditControlWithColorPicker(3, rgb); + SS.TW.edit.meaning = Edit::BACKGROUND_COLOR; +} + +void TextWindow::ShowListOfStyles() { + Printf(true, "%Ft color style-name"); + + bool darkbg = false; + Style *s; + for(s = SK.style.First(); s; s = SK.style.NextAfter(s)) { + Printf(false, "%Bp %Bz %Bp %Fl%Ll%f%D%s%E", + darkbg ? 'd' : 'a', + &s->color, + darkbg ? 'd' : 'a', + ScreenShowStyleInfo, s->h.v, + s->DescriptionString().c_str()); + + darkbg = !darkbg; + } + + Printf(true, " %Fl%Ll%fcreate a new custom style%E", + &ScreenCreateCustomStyle); + + Printf(false, ""); + + RgbaColor rgb = SS.backgroundColor; + Printf(false, "%Ft background color (r, g, b)%E"); + Printf(false, "%Ba %@, %@, %@ %Fl%D%f%Ll[change]%E", + rgb.redF(), rgb.greenF(), rgb.blueF(), + top[rows-1] + 2, &ScreenChangeBackgroundColor); + + Printf(false, ""); + Printf(false, " %Fl%Ll%fload factory defaults%E", + &ScreenLoadFactoryDefaultStyles); +} + + +void TextWindow::ScreenChangeStyleName(int link, uint32_t v) { + hStyle hs = { v }; + Style *s = Style::Get(hs); + SS.TW.ShowEditControl(12, s->name); + SS.TW.edit.style = hs; + SS.TW.edit.meaning = Edit::STYLE_NAME; +} + +void TextWindow::ScreenDeleteStyle(int link, uint32_t v) { + SS.UndoRemember(); + hStyle hs = { v }; + Style *s = SK.style.FindByIdNoOops(hs); + if(s) { + SK.style.RemoveById(hs); + // And it will get recreated automatically if something is still using + // the style, so no need to do anything else. + } + SS.TW.GoToScreen(Screen::LIST_OF_STYLES); + SS.GW.Invalidate(); +} + +void TextWindow::ScreenChangeStylePatternType(int link, uint32_t v) { + hStyle hs = { v }; + Style *s = Style::Get(hs); + s->stippleType = (StipplePattern)(link - 1); + SS.GW.persistentDirty = true; +} + +void TextWindow::ScreenChangeStyleMetric(int link, uint32_t v) { + hStyle hs = { v }; + Style *s = Style::Get(hs); + double val; + Style::UnitsAs units; + Edit meaning; + int col; + switch(link) { + case 't': + val = s->textHeight; + units = s->textHeightAs; + col = 10; + meaning = Edit::STYLE_TEXT_HEIGHT; + break; + + case 's': + val = s->stippleScale; + units = s->widthAs; + col = 17; + meaning = Edit::STYLE_STIPPLE_PERIOD; + break; + + case 'w': + case 'W': + val = s->width; + units = s->widthAs; + col = 9; + meaning = Edit::STYLE_WIDTH; + break; + + default: ssassert(false, "Unexpected link"); + } + + std::string edit_value; + if(units == Style::UnitsAs::PIXELS) { + edit_value = ssprintf("%.2f", val); + } else { + edit_value = SS.MmToString(val); + } + SS.TW.ShowEditControl(col, edit_value); + SS.TW.edit.style = hs; + SS.TW.edit.meaning = meaning; +} + +void TextWindow::ScreenChangeStyleTextAngle(int link, uint32_t v) { + hStyle hs = { v }; + Style *s = Style::Get(hs); + SS.TW.ShowEditControl(9, ssprintf("%.2f", s->textAngle)); + SS.TW.edit.style = hs; + SS.TW.edit.meaning = Edit::STYLE_TEXT_ANGLE; +} + +void TextWindow::ScreenChangeStyleColor(int link, uint32_t v) { + hStyle hs = { v }; + Style *s = Style::Get(hs); + // Same function used for stroke and fill colors + Edit em; + RgbaColor rgb; + if(link == 's') { + em = Edit::STYLE_COLOR; + rgb = s->color; + } else if(link == 'f') { + em = Edit::STYLE_FILL_COLOR; + rgb = s->fillColor; + } else ssassert(false, "Unexpected link"); + SS.TW.ShowEditControlWithColorPicker(13, rgb); + SS.TW.edit.style = hs; + SS.TW.edit.meaning = em; +} + +void TextWindow::ScreenChangeStyleYesNo(int link, uint32_t v) { + SS.UndoRemember(); + hStyle hs = { v }; + Style *s = Style::Get(hs); + switch(link) { + // Units for the width + case 'w': + if(s->widthAs != Style::UnitsAs::MM) { + s->widthAs = Style::UnitsAs::MM; + s->width /= SS.GW.scale; + s->stippleScale /= SS.GW.scale; + } + break; + case 'W': + if(s->widthAs != Style::UnitsAs::PIXELS) { + s->widthAs = Style::UnitsAs::PIXELS; + s->width *= SS.GW.scale; + s->stippleScale *= SS.GW.scale; + } + break; + + // Units for the height + case 'g': + if(s->textHeightAs != Style::UnitsAs::MM) { + s->textHeightAs = Style::UnitsAs::MM; + s->textHeight /= SS.GW.scale; + } + break; + + case 'G': + if(s->textHeightAs != Style::UnitsAs::PIXELS) { + s->textHeightAs = Style::UnitsAs::PIXELS; + s->textHeight *= SS.GW.scale; + } + break; + + case 'e': + s->exportable = !(s->exportable); + break; + + case 'v': + s->visible = !(s->visible); + break; + + case 'f': + s->filled = !(s->filled); + break; + + // Horizontal text alignment + case 'L': + s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin | (uint32_t)Style::TextOrigin::LEFT); + s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::RIGHT); + break; + case 'H': + s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::LEFT); + s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::RIGHT); + break; + case 'R': + s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::LEFT); + s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin | (uint32_t)Style::TextOrigin::RIGHT); + break; + + // Vertical text alignment + case 'B': + s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin | (uint32_t)Style::TextOrigin::BOT); + s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::TOP); + break; + case 'V': + s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::BOT); + s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::TOP); + break; + case 'T': + s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin & ~(uint32_t)Style::TextOrigin::BOT); + s->textOrigin = (Style::TextOrigin)((uint32_t)s->textOrigin | (uint32_t)Style::TextOrigin::TOP); + break; + } + SS.GW.Invalidate(/*clearPersistent=*/true); +} + +bool TextWindow::EditControlDoneForStyles(const std::string &str) { + Style *s; + switch(edit.meaning) { + case Edit::STYLE_STIPPLE_PERIOD: + case Edit::STYLE_TEXT_HEIGHT: + case Edit::STYLE_WIDTH: { + SS.UndoRemember(); + s = Style::Get(edit.style); + + double v; + Style::UnitsAs units = (edit.meaning == Edit::STYLE_TEXT_HEIGHT) ? + s->textHeightAs : s->widthAs; + if(units == Style::UnitsAs::MM) { + v = SS.StringToMm(str); + } else { + v = atof(str.c_str()); + } + v = max(0.0, v); + if(edit.meaning == Edit::STYLE_TEXT_HEIGHT) { + s->textHeight = v; + } else if(edit.meaning == Edit::STYLE_STIPPLE_PERIOD) { + s->stippleScale = v; + } else { + s->width = v; + } + break; + } + case Edit::STYLE_TEXT_ANGLE: + SS.UndoRemember(); + s = Style::Get(edit.style); + s->textAngle = WRAP_SYMMETRIC(atof(str.c_str()), 360); + break; + + case Edit::BACKGROUND_COLOR: + case Edit::STYLE_FILL_COLOR: + case Edit::STYLE_COLOR: { + Vector rgb; + if(sscanf(str.c_str(), "%lf, %lf, %lf", &rgb.x, &rgb.y, &rgb.z)==3) { + rgb = rgb.ClampWithin(0, 1); + if(edit.meaning == Edit::STYLE_COLOR) { + SS.UndoRemember(); + s = Style::Get(edit.style); + s->color = RGBf(rgb.x, rgb.y, rgb.z); + } else if(edit.meaning == Edit::STYLE_FILL_COLOR) { + SS.UndoRemember(); + s = Style::Get(edit.style); + s->fillColor = RGBf(rgb.x, rgb.y, rgb.z); + } else { + SS.backgroundColor = RGBf(rgb.x, rgb.y, rgb.z); + } + } else { + Error(_("Bad format: specify color as r, g, b")); + } + break; + } + case Edit::STYLE_NAME: + if(str.empty()) { + Error(_("Style name cannot be empty")); + } else { + SS.UndoRemember(); + s = Style::Get(edit.style); + s->name = str; + } + break; + + default: return false; + } + SS.GW.persistentDirty = true; + return true; +} + +void TextWindow::ShowStyleInfo() { + Printf(true, "%Fl%f%Ll(back to list of styles)%E", &ScreenShowListOfStyles); + + Style *s = Style::Get(shown.style); + + if(s->h.v < Style::FIRST_CUSTOM) { + Printf(true, "%FtSTYLE %E%s ", s->DescriptionString().c_str()); + } else { + Printf(true, "%FtSTYLE %E%s " + "[%Fl%Ll%D%frename%E/%Fl%Ll%D%fdel%E]", + s->DescriptionString().c_str(), + s->h.v, &ScreenChangeStyleName, + s->h.v, &ScreenDeleteStyle); + } + Printf(true, "%Ft line stroke style%E"); + Printf(false, "%Ba %Ftcolor %E%Bz %Ba (%@, %@, %@) %D%f%Ls%Fl[change]%E", + &s->color, + s->color.redF(), s->color.greenF(), s->color.blueF(), + s->h.v, ScreenChangeStyleColor); + + // The line width, and its units + if(s->widthAs == Style::UnitsAs::PIXELS) { + Printf(false, " %Ftwidth%E %@ %D%f%Lp%Fl[change]%E", + s->width, + s->h.v, &ScreenChangeStyleMetric, + (s->h.v < Style::FIRST_CUSTOM) ? 'w' : 'W'); + } else { + Printf(false, " %Ftwidth%E %s %D%f%Lp%Fl[change]%E", + SS.MmToString(s->width).c_str(), + s->h.v, &ScreenChangeStyleMetric, + (s->h.v < Style::FIRST_CUSTOM) ? 'w' : 'W'); + } + + if(s->widthAs == Style::UnitsAs::PIXELS) { + Printf(false, "%Ba %Ftstipple width%E %@ %D%f%Lp%Fl[change]%E", + s->stippleScale, + s->h.v, &ScreenChangeStyleMetric, 's'); + } else { + Printf(false, "%Ba %Ftstipple width%E %s %D%f%Lp%Fl[change]%E", + SS.MmToString(s->stippleScale).c_str(), + s->h.v, &ScreenChangeStyleMetric, 's'); + } + + bool widthpx = (s->widthAs == Style::UnitsAs::PIXELS); + if(s->h.v < Style::FIRST_CUSTOM) { + Printf(false," %Ftin units of %Fdpixels%E"); + } else { + Printf(false,"%Ba %Ftin units of %Fd" + "%D%f%LW%s pixels%E " + "%D%f%Lw%s %s", + s->h.v, &ScreenChangeStyleYesNo, + widthpx ? RADIO_TRUE : RADIO_FALSE, + s->h.v, &ScreenChangeStyleYesNo, + !widthpx ? RADIO_TRUE : RADIO_FALSE, + SS.UnitName()); + } + + Printf(false,"%Ba %Ftstipple type:%E"); + + const size_t patternCount = (size_t)StipplePattern::LAST + 1; + const char *patternsSource[patternCount] = { + "___________", + "- - - - ", + "- - - - - -", + "__ __ __ __", + "-.-.-.-.-.-", + "..-..-..-..", + "...........", + "~~~~~~~~~~~", + "__~__~__~__" + }; + std::string patterns[patternCount]; + + for(uint32_t i = 0; i <= (uint32_t)StipplePattern::LAST; i++) { + const char *str = patternsSource[i]; + do { + switch(*str) { + case ' ': patterns[i] += " "; break; + case '.': patterns[i] += "\xEE\x80\x84"; break; + case '_': patterns[i] += "\xEE\x80\x85"; break; + case '-': patterns[i] += "\xEE\x80\x86"; break; + case '~': patterns[i] += "\xEE\x80\x87"; break; + default: ssassert(false, "Unexpected stipple pattern element"); + } + } while(*(++str)); + } + + for(uint32_t i = 0; i <= (uint32_t)StipplePattern::LAST; i++) { + const char *radio = s->stippleType == (StipplePattern)i ? RADIO_TRUE : RADIO_FALSE; + Printf(false, "%Bp %D%f%Lp%s %s%E", + (i % 2 == 0) ? 'd' : 'a', + s->h.v, &ScreenChangeStylePatternType, + i + 1, radio, patterns[i].c_str()); + } + + if(s->h.v >= Style::FIRST_CUSTOM) { + // The fill color, and whether contours are filled + + Printf(false, ""); + Printf(false, "%Ft contour fill style%E"); + Printf(false, + "%Ba %Ftcolor %E%Bz %Ba (%@, %@, %@) %D%f%Lf%Fl[change]%E", + &s->fillColor, + s->fillColor.redF(), s->fillColor.greenF(), s->fillColor.blueF(), + s->h.v, ScreenChangeStyleColor); + + Printf(false, "%Bd %D%f%Lf%s contours are filled%E", + s->h.v, &ScreenChangeStyleYesNo, + s->filled ? CHECK_TRUE : CHECK_FALSE); + } + + // The text height, and its units + Printf(false, ""); + Printf(false, "%Ft text style%E"); + + if(s->textHeightAs == Style::UnitsAs::PIXELS) { + Printf(false, "%Ba %Ftheight %E%@ %D%f%Lt%Fl%s%E", + s->textHeight, + s->h.v, &ScreenChangeStyleMetric, + "[change]"); + } else { + Printf(false, "%Ba %Ftheight %E%s %D%f%Lt%Fl%s%E", + SS.MmToString(s->textHeight).c_str(), + s->h.v, &ScreenChangeStyleMetric, + "[change]"); + } + + bool textHeightpx = (s->textHeightAs == Style::UnitsAs::PIXELS); + if(s->h.v < Style::FIRST_CUSTOM) { + Printf(false,"%Bd %Ftin units of %Fdpixels"); + } else { + Printf(false,"%Bd %Ftin units of %Fd" + "%D%f%LG%s pixels%E " + "%D%f%Lg%s %s", + s->h.v, &ScreenChangeStyleYesNo, + textHeightpx ? RADIO_TRUE : RADIO_FALSE, + s->h.v, &ScreenChangeStyleYesNo, + !textHeightpx ? RADIO_TRUE : RADIO_FALSE, + SS.UnitName()); + } + + if(s->h.v >= Style::FIRST_CUSTOM) { + Printf(false, "%Ba %Ftangle %E%@ %D%f%Ll%Fl[change]%E", + s->textAngle, + s->h.v, &ScreenChangeStyleTextAngle); + + Printf(false, ""); + Printf(false, "%Ft text comment alignment%E"); + bool neither; + neither = !((uint32_t)s->textOrigin & ((uint32_t)Style::TextOrigin::LEFT | (uint32_t)Style::TextOrigin::RIGHT)); + Printf(false, "%Ba " + "%D%f%LL%s left%E " + "%D%f%LH%s center%E " + "%D%f%LR%s right%E ", + s->h.v, &ScreenChangeStyleYesNo, + ((uint32_t)s->textOrigin & (uint32_t)Style::TextOrigin::LEFT) ? RADIO_TRUE : RADIO_FALSE, + s->h.v, &ScreenChangeStyleYesNo, + neither ? RADIO_TRUE : RADIO_FALSE, + s->h.v, &ScreenChangeStyleYesNo, + ((uint32_t)s->textOrigin & (uint32_t)Style::TextOrigin::RIGHT) ? RADIO_TRUE : RADIO_FALSE); + + neither = !((uint32_t)s->textOrigin & ((uint32_t)Style::TextOrigin::BOT | (uint32_t)Style::TextOrigin::TOP)); + Printf(false, "%Bd " + "%D%f%LB%s bottom%E " + "%D%f%LV%s center%E " + "%D%f%LT%s top%E ", + s->h.v, &ScreenChangeStyleYesNo, + ((uint32_t)s->textOrigin & (uint32_t)Style::TextOrigin::BOT) ? RADIO_TRUE : RADIO_FALSE, + s->h.v, &ScreenChangeStyleYesNo, + neither ? RADIO_TRUE : RADIO_FALSE, + s->h.v, &ScreenChangeStyleYesNo, + ((uint32_t)s->textOrigin & (uint32_t)Style::TextOrigin::TOP) ? RADIO_TRUE : RADIO_FALSE); + } + + if(s->h.v >= Style::FIRST_CUSTOM) { + Printf(false, ""); + + Printf(false, " %Fd%D%f%Lv%s show these objects on screen%E", + s->h.v, &ScreenChangeStyleYesNo, + s->visible ? CHECK_TRUE : CHECK_FALSE); + + Printf(false, " %Fd%D%f%Le%s export these objects%E", + s->h.v, &ScreenChangeStyleYesNo, + s->exportable ? CHECK_TRUE : CHECK_FALSE); + + Printf(false, ""); + Printf(false, "To assign lines or curves to this style,"); + Printf(false, "right-click them on the drawing."); + } +} + +void TextWindow::ScreenAssignSelectionToStyle(int link, uint32_t v) { + Style::AssignSelectionToStyle(v); +} diff --git a/src/system.cpp b/src/system.cpp new file mode 100644 index 0000000..1119c34 --- /dev/null +++ b/src/system.cpp @@ -0,0 +1,579 @@ +//----------------------------------------------------------------------------- +// Once we've written our constraint equations in the symbolic algebra system, +// these routines linearize them, and solve by a modified Newton's method. +// This also contains the routines to detect non-convergence or inconsistency, +// and report diagnostics to the user. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +// This tolerance is used to determine whether two (linearized) constraints +// are linearly dependent. If this is too small, then we will attempt to +// solve truly inconsistent systems and fail. But if it's too large, then +// we will give up on legitimate systems like a skinny right angle triangle by +// its hypotenuse and long side. +const double System::RANK_MAG_TOLERANCE = 1e-4; + +// The solver will converge all unknowns to within this tolerance. This must +// always be much less than LENGTH_EPS, and in practice should be much less. +const double System::CONVERGE_TOLERANCE = (LENGTH_EPS/(1e2)); + +bool System::WriteJacobian(int tag) { + + int j = 0; + for(auto &p : param) { + if(j >= MAX_UNKNOWNS) + return false; + + if(p.tag != tag) + continue; + mat.param[j] = p.h; + j++; + } + mat.n = j; + + int i = 0; + + for(auto &e : eq) { + if(i >= MAX_UNKNOWNS) return false; + + if(e.tag != tag) + continue; + + mat.eq[i] = e.h; + Expr *f = e.e->DeepCopyWithParamsAsPointers(¶m, &(SK.param)); + f = f->FoldConstants(); + + // Hash table (61 bits) to accelerate generation of zero partials. + uint64_t scoreboard = f->ParamsUsed(); + for(j = 0; j < mat.n; j++) { + Expr *pd; + if(scoreboard & ((uint64_t)1 << (mat.param[j].v % 61)) && + f->DependsOn(mat.param[j])) + { + pd = f->PartialWrt(mat.param[j]); + pd = pd->FoldConstants(); + pd = pd->DeepCopyWithParamsAsPointers(¶m, &(SK.param)); + } else { + pd = Expr::From(0.0); + } + mat.A.sym[i][j] = pd; + } + mat.B.sym[i] = f; + i++; + } + mat.m = i; + + return true; +} + +void System::EvalJacobian() { + int i, j; + for(i = 0; i < mat.m; i++) { + for(j = 0; j < mat.n; j++) { + mat.A.num[i][j] = (mat.A.sym[i][j])->Eval(); + } + } +} + +bool System::IsDragged(hParam p) { + hParam *pp; + for(pp = dragged.First(); pp; pp = dragged.NextAfter(pp)) { + if(p == *pp) return true; + } + return false; +} + +void System::SolveBySubstitution() { + for(auto &teq : eq) { + Expr *tex = teq.e; + + if(tex->op == Expr::Op::MINUS && + tex->a->op == Expr::Op::PARAM && + tex->b->op == Expr::Op::PARAM) + { + hParam a = tex->a->parh; + hParam b = tex->b->parh; + if(!(param.FindByIdNoOops(a) && param.FindByIdNoOops(b))) { + // Don't substitute unless they're both solver params; + // otherwise it's an equation that can be solved immediately, + // or an error to flag later. + continue; + } + + if(IsDragged(a)) { + // A is being dragged, so A should stay, and B should go + std::swap(a, b); + } + + for(auto &req : eq) { + req.e->Substitute(a, b); // A becomes B, B unchanged + } + for(auto &rp : param) { + if(rp.substd == a) { + rp.substd = b; + } + } + Param *ptr = param.FindById(a); + ptr->tag = VAR_SUBSTITUTED; + ptr->substd = b; + + teq.tag = EQ_SUBSTITUTED; + } + } +} + +//----------------------------------------------------------------------------- +// Calculate the rank of the Jacobian matrix, by Gram-Schimdt orthogonalization +// in place. A row (~equation) is considered to be all zeros if its magnitude +// is less than the tolerance RANK_MAG_TOLERANCE. +//----------------------------------------------------------------------------- +int System::CalculateRank() { + // Actually work with magnitudes squared, not the magnitudes + double rowMag[MAX_UNKNOWNS] = {}; + double tol = RANK_MAG_TOLERANCE*RANK_MAG_TOLERANCE; + + int i, iprev, j; + int rank = 0; + + for(i = 0; i < mat.m; i++) { + // Subtract off this row's component in the direction of any + // previous rows + for(iprev = 0; iprev < i; iprev++) { + if(rowMag[iprev] <= tol) continue; // ignore zero rows + + double dot = 0; + for(j = 0; j < mat.n; j++) { + dot += (mat.A.num[iprev][j]) * (mat.A.num[i][j]); + } + for(j = 0; j < mat.n; j++) { + mat.A.num[i][j] -= (dot/rowMag[iprev])*mat.A.num[iprev][j]; + } + } + // Our row is now normal to all previous rows; calculate the + // magnitude of what's left + double mag = 0; + for(j = 0; j < mat.n; j++) { + mag += (mat.A.num[i][j]) * (mat.A.num[i][j]); + } + if(mag > tol) { + rank++; + } + rowMag[i] = mag; + } + + return rank; +} + +bool System::TestRank(int *rank) { + EvalJacobian(); + int jacobianRank = CalculateRank(); + if(rank) *rank = jacobianRank; + return jacobianRank == mat.m; +} + +bool System::SolveLinearSystem(double X[], double A[][MAX_UNKNOWNS], + double B[], int n) +{ + // Gaussian elimination, with partial pivoting. It's an error if the + // matrix is singular, because that means two constraints are + // equivalent. + int i, j, ip, jp, imax = 0; + double max, temp; + + for(i = 0; i < n; i++) { + // We are trying eliminate the term in column i, for rows i+1 and + // greater. First, find a pivot (between rows i and N-1). + max = 0; + for(ip = i; ip < n; ip++) { + if(fabs(A[ip][i]) > max) { + imax = ip; + max = fabs(A[ip][i]); + } + } + // Don't give up on a singular matrix unless it's really bad; the + // assumption code is responsible for identifying that condition, + // so we're not responsible for reporting that error. + if(fabs(max) < 1e-20) continue; + + // Swap row imax with row i + for(jp = 0; jp < n; jp++) { + swap(A[i][jp], A[imax][jp]); + } + swap(B[i], B[imax]); + + // For rows i+1 and greater, eliminate the term in column i. + for(ip = i+1; ip < n; ip++) { + temp = A[ip][i]/A[i][i]; + + for(jp = i; jp < n; jp++) { + A[ip][jp] -= temp*(A[i][jp]); + } + B[ip] -= temp*B[i]; + } + } + + // We've put the matrix in upper triangular form, so at this point we + // can solve by back-substitution. + for(i = n - 1; i >= 0; i--) { + if(fabs(A[i][i]) < 1e-20) continue; + + temp = B[i]; + for(j = n - 1; j > i; j--) { + temp -= X[j]*A[i][j]; + } + X[i] = temp / A[i][i]; + } + + return true; +} + +bool System::SolveLeastSquares() { + int r, c, i; + + // Scale the columns; this scale weights the parameters for the least + // squares solve, so that we can encourage the solver to make bigger + // changes in some parameters, and smaller in others. + for(c = 0; c < mat.n; c++) { + if(IsDragged(mat.param[c])) { + // It's least squares, so this parameter doesn't need to be all + // that big to get a large effect. + mat.scale[c] = 1/20.0; + } else { + mat.scale[c] = 1; + } + for(r = 0; r < mat.m; r++) { + mat.A.num[r][c] *= mat.scale[c]; + } + } + + // Write A*A' + for(r = 0; r < mat.m; r++) { + for(c = 0; c < mat.m; c++) { // yes, AAt is square + double sum = 0; + for(i = 0; i < mat.n; i++) { + sum += mat.A.num[r][i]*mat.A.num[c][i]; + } + mat.AAt[r][c] = sum; + } + } + + if(!SolveLinearSystem(mat.Z, mat.AAt, mat.B.num, mat.m)) return false; + + // And multiply that by A' to get our solution. + for(c = 0; c < mat.n; c++) { + double sum = 0; + for(i = 0; i < mat.m; i++) { + sum += mat.A.num[i][c]*mat.Z[i]; + } + mat.X[c] = sum * mat.scale[c]; + } + return true; +} + +bool System::NewtonSolve(int tag) { + + int iter = 0; + bool converged = false; + int i; + + // Evaluate the functions at our operating point. + for(i = 0; i < mat.m; i++) { + mat.B.num[i] = (mat.B.sym[i])->Eval(); + } + do { + // And evaluate the Jacobian at our initial operating point. + EvalJacobian(); + + if(!SolveLeastSquares()) break; + + // Take the Newton step; + // J(x_n) (x_{n+1} - x_n) = 0 - F(x_n) + for(i = 0; i < mat.n; i++) { + Param *p = param.FindById(mat.param[i]); + p->val -= mat.X[i]; + if(IsReasonable(p->val)) { + // Very bad, and clearly not convergent + return false; + } + } + + // Re-evalute the functions, since the params have just changed. + for(i = 0; i < mat.m; i++) { + mat.B.num[i] = (mat.B.sym[i])->Eval(); + } + // Check for convergence + converged = true; + for(i = 0; i < mat.m; i++) { + if(IsReasonable(mat.B.num[i])) { + return false; + } + if(fabs(mat.B.num[i]) > CONVERGE_TOLERANCE) { + converged = false; + break; + } + } + } while(iter++ < 50 && !converged); + + return converged; +} + +void System::WriteEquationsExceptFor(hConstraint hc, Group *g) { + // Generate all the equations from constraints in this group + for(auto &con : SK.constraint) { + ConstraintBase *c = &con; + if(c->group != g->h) continue; + if(c->h == hc) continue; + + if(c->HasLabel() && c->type != Constraint::Type::COMMENT && + g->allDimsReference) + { + // When all dimensions are reference, we adjust them to display + // the correct value, and then don't generate any equations. + c->ModifyToSatisfy(); + continue; + } + if(g->relaxConstraints && c->type != Constraint::Type::POINTS_COINCIDENT) { + // When the constraints are relaxed, we keep only the point- + // coincident constraints, and the constraints generated by + // the entities and groups. + continue; + } + + c->GenerateEquations(&eq); + } + // And the equations from entities + for(auto &ent : SK.entity) { + EntityBase *e = &ent; + if(e->group != g->h) continue; + + e->GenerateEquations(&eq); + } + // And from the groups themselves + g->GenerateEquations(&eq); +} + +void System::FindWhichToRemoveToFixJacobian(Group *g, List *bad, bool forceDofCheck) { + auto time = GetMilliseconds(); + g->solved.timeout = false; + int a; + + for(a = 0; a < 2; a++) { + for(auto &con : SK.constraint) { + if((GetMilliseconds() - time) > g->solved.findToFixTimeout) { + g->solved.timeout = true; + return; + } + + ConstraintBase *c = &con; + if(c->group != g->h) continue; + if((c->type == Constraint::Type::POINTS_COINCIDENT && a == 0) || + (c->type != Constraint::Type::POINTS_COINCIDENT && a == 1)) + { + // Do the constraints in two passes: first everything but + // the point-coincident constraints, then only those + // constraints (so they appear last in the list). + continue; + } + + param.ClearTags(); + eq.Clear(); + WriteEquationsExceptFor(c->h, g); + eq.ClearTags(); + + // It's a major speedup to solve the easy ones by substitution here, + // and that doesn't break anything. + if(!forceDofCheck) { + SolveBySubstitution(); + } + + WriteJacobian(0); + EvalJacobian(); + + int rank = CalculateRank(); + if(rank == mat.m) { + // We fixed it by removing this constraint + bad->Add(&(c->h)); + } + } + } +} + +SolveResult System::Solve(Group *g, int *rank, int *dof, List *bad, + bool andFindBad, bool andFindFree, bool forceDofCheck) +{ + WriteEquationsExceptFor(Constraint::NO_CONSTRAINT, g); + + int i; + bool rankOk; + +/* + dbp("%d equations", eq.n); + for(i = 0; i < eq.n; i++) { + dbp(" %.3f = %s = 0", eq[i].e->Eval(), eq[i].e->Print()); + } + dbp("%d parameters", param.n); + for(i = 0; i < param.n; i++) { + dbp(" param %08x at %.3f", param[i].h.v, param[i].val); + } */ + + // All params and equations are assigned to group zero. + param.ClearTags(); + eq.ClearTags(); + + // Solving by substitution eliminates duplicate e.g. H/V constraints, which can cause rank test + // to succeed even on overdefined systems, which will fail later. + if(!forceDofCheck) { + SolveBySubstitution(); + } + + // Before solving the big system, see if we can find any equations that + // are soluble alone. This can be a huge speedup. We don't know whether + // the system is consistent yet, but if it isn't then we'll catch that + // later. + int alone = 1; + for(auto &e : eq) { + if(e.tag != 0) + continue; + + hParam hp = e.e->ReferencedParams(¶m); + if(hp == Expr::NO_PARAMS) continue; + if(hp == Expr::MULTIPLE_PARAMS) continue; + + Param *p = param.FindById(hp); + if(p->tag != 0) continue; // let rank test catch inconsistency + + e.tag = alone; + p->tag = alone; + WriteJacobian(alone); + if(!NewtonSolve(alone)) { + // We don't do the rank test, so let's arbitrarily return + // the DIDNT_CONVERGE result here. + rankOk = true; + // Failed to converge, bail out early + goto didnt_converge; + } + alone++; + } + + // Now write the Jacobian for what's left, and do a rank test; that + // tells us if the system is inconsistently constrained. + if(!WriteJacobian(0)) { + return SolveResult::TOO_MANY_UNKNOWNS; + } + + rankOk = TestRank(rank); + + // And do the leftovers as one big system + if(!NewtonSolve(0)) { + goto didnt_converge; + } + + rankOk = TestRank(rank); + if(!rankOk) { + if(andFindBad) FindWhichToRemoveToFixJacobian(g, bad, forceDofCheck); + } else { + // This is not the full Jacobian, but any substitutions or single-eq + // solves removed one equation and one unknown, therefore no effect + // on the number of DOF. + if(dof) *dof = CalculateDof(); + MarkParamsFree(andFindFree); + } + // System solved correctly, so write the new values back in to the + // main parameter table. + for(auto &p : param) { + double val; + if(p.tag == VAR_SUBSTITUTED) { + val = param.FindById(p.substd)->val; + } else { + val = p.val; + } + Param *pp = SK.GetParam(p.h); + pp->val = val; + pp->known = true; + pp->free = p.free; + } + return rankOk ? SolveResult::OKAY : SolveResult::REDUNDANT_OKAY; + +didnt_converge: + SK.constraint.ClearTags(); + // Not using range-for here because index is used in additional ways + for(i = 0; i < eq.n; i++) { + if(fabs(mat.B.num[i]) > CONVERGE_TOLERANCE || IsReasonable(mat.B.num[i])) { + // This constraint is unsatisfied. + if(!mat.eq[i].isFromConstraint()) continue; + + hConstraint hc = mat.eq[i].constraint(); + ConstraintBase *c = SK.constraint.FindByIdNoOops(hc); + if(!c) continue; + // Don't double-show constraints that generated multiple + // unsatisfied equations + if(!c->tag) { + bad->Add(&(c->h)); + c->tag = 1; + } + } + } + + return rankOk ? SolveResult::DIDNT_CONVERGE : SolveResult::REDUNDANT_DIDNT_CONVERGE; +} + +SolveResult System::SolveRank(Group *g, int *rank, int *dof, List *bad, + bool andFindBad, bool andFindFree) +{ + WriteEquationsExceptFor(Constraint::NO_CONSTRAINT, g); + + // All params and equations are assigned to group zero. + param.ClearTags(); + eq.ClearTags(); + + // Now write the Jacobian, and do a rank test; that + // tells us if the system is inconsistently constrained. + if(!WriteJacobian(0)) { + return SolveResult::TOO_MANY_UNKNOWNS; + } + + bool rankOk = TestRank(rank); + if(!rankOk) { + if(andFindBad) FindWhichToRemoveToFixJacobian(g, bad, /*forceDofCheck=*/true); + } else { + if(dof) *dof = CalculateDof(); + MarkParamsFree(andFindFree); + } + return rankOk ? SolveResult::OKAY : SolveResult::REDUNDANT_OKAY; +} + +void System::Clear() { + entity.Clear(); + param.Clear(); + eq.Clear(); + dragged.Clear(); +} + +void System::MarkParamsFree(bool find) { + // If requested, find all the free (unbound) variables. This might be + // more than the number of degrees of freedom. Don't always do this, + // because the display would get annoying and it's slow. + for(auto &p : param) { + p.free = false; + + if(find) { + if(p.tag == 0) { + p.tag = VAR_DOF_TEST; + WriteJacobian(0); + EvalJacobian(); + int rank = CalculateRank(); + if(rank == mat.m) { + p.free = true; + } + p.tag = 0; + } + } + } +} + +int System::CalculateDof() { + return mat.n - mat.m; +} + diff --git a/src/textscreens.cpp b/src/textscreens.cpp new file mode 100644 index 0000000..07d5cde --- /dev/null +++ b/src/textscreens.cpp @@ -0,0 +1,873 @@ +//----------------------------------------------------------------------------- +// The text-based browser window, used to view the structure of the model by +// groups and for other similar purposes. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +//----------------------------------------------------------------------------- +// A navigation bar that always appears at the top of the window, with a +// link to bring us back home. +//----------------------------------------------------------------------------- +void TextWindow::ScreenHome(int link, uint32_t v) { + SS.TW.GoToScreen(Screen::LIST_OF_GROUPS); +} +void TextWindow::ShowHeader(bool withNav) { + ClearScreen(); + + const char *header; + std::string desc; + if(SS.GW.LockedInWorkplane()) { + header = "in plane: "; + desc = SK.GetEntity(SS.GW.ActiveWorkplane())->DescriptionString(); + } else { + header = "drawing / constraining in 3d"; + desc = ""; + } + + // Navigation buttons + if(withNav) { + Printf(false, " %Fl%Lh%fhome%E %Ft%s%E%s", + (&TextWindow::ScreenHome), header, desc.c_str()); + } else { + Printf(false, " %Ft%s%E%s", header, desc.c_str()); + } + + // Leave space for the icons that are painted here. + Printf(false, ""); + Printf(false, ""); +} + +//----------------------------------------------------------------------------- +// The screen that shows a list of every group in the sketch, with options +// to hide or show them, and to view them in detail. This is our home page. +//----------------------------------------------------------------------------- +void TextWindow::ScreenSelectGroup(int link, uint32_t v) { + GraphicsWindow::MenuEdit(Command::UNSELECT_ALL); + SS.TW.GoToScreen(Screen::GROUP_INFO); + SS.TW.shown.group.v = v; +} +void TextWindow::ScreenToggleGroupShown(int link, uint32_t v) { + hGroup hg = { v }; + Group *g = SK.GetGroup(hg); + g->visible = !(g->visible); + // If a group was just shown, then it might not have been generated + // previously, so regenerate. + SS.GenerateAll(); +} +void TextWindow::ScreenShowGroupsSpecial(int link, uint32_t v) { + bool state = link == 's'; + for(hGroup hg : SK.groupOrder) { + Group *g = SK.GetGroup(hg); + + g->visible = state; + } + SS.GW.persistentDirty = true; +} +void TextWindow::ScreenActivateGroup(int link, uint32_t v) { + SS.GW.activeGroup.v = v; + SK.GetGroup(SS.GW.activeGroup)->Activate(); + SS.GW.ClearSuper(); +} +void TextWindow::ReportHowGroupSolved(hGroup hg) { + SS.GW.ClearSuper(); + SS.TW.GoToScreen(Screen::GROUP_SOLVE_INFO); + SS.TW.shown.group = hg; + SS.ScheduleShowTW(); +} +void TextWindow::ScreenHowGroupSolved(int link, uint32_t v) { + if(SS.GW.activeGroup.v != v) { + ScreenActivateGroup(link, v); + } + SS.TW.GoToScreen(Screen::GROUP_SOLVE_INFO); + SS.TW.shown.group.v = v; +} +void TextWindow::ScreenShowConfiguration(int link, uint32_t v) { + SS.TW.GoToScreen(Screen::CONFIGURATION); +} +void TextWindow::ScreenShowEditView(int link, uint32_t v) { + SS.TW.GoToScreen(Screen::EDIT_VIEW); +} +void TextWindow::ScreenGoToWebsite(int link, uint32_t v) { + Platform::OpenInBrowser("http://solvespace.com/txtlink"); +} +void TextWindow::ShowListOfGroups() { + const char *radioTrue = " " RADIO_TRUE " ", + *radioFalse = " " RADIO_FALSE " ", + *checkTrue = " " CHECK_TRUE " ", + *checkFalse = " " CHECK_FALSE " "; + + Printf(true, "%Ft active"); + Printf(false, "%Ft shown dof group-name%E"); + bool afterActive = false; + bool backgroundParity = false; + for(hGroup hg : SK.groupOrder) { + Group *g = SK.GetGroup(hg); + + std::string s = g->DescriptionString(); + bool active = (g->h == SS.GW.activeGroup); + bool shown = g->visible; + bool ok = g->IsSolvedOkay(); + bool warn = (g->type == Group::Type::DRAWING_WORKPLANE && + g->polyError.how != PolyError::GOOD) || + ((g->type == Group::Type::EXTRUDE || + g->type == Group::Type::LATHE) && + SK.GetGroup(g->opA)->polyError.how != PolyError::GOOD); + int dof = g->solved.dof; + char sdof[16] = "ok "; + if(ok && dof > 0) { + if(dof > 999) { + strcpy(sdof, "###"); + } else { + sprintf(sdof, "%-3d", dof); + } + } + bool ref = (g->h == Group::HGROUP_REFERENCES); + Printf(false, + "%Bp%Fd " + "%Ft%s%Fb%D%f%Ll%s%E " + "%Fb%s%D%f%Ll%s%E " + "%Fp%D%f%s%Ll%s%E " + "%Fl%Ll%D%f%s", + // Alternate between light and dark backgrounds, for readability + backgroundParity ? 'd' : 'a', + // Link that activates the group + ref ? " " : "", + g->h.v, (&TextWindow::ScreenActivateGroup), + ref ? "" : (active ? radioTrue : radioFalse), + // Link that hides or shows the group + afterActive ? " - " : "", + g->h.v, (&TextWindow::ScreenToggleGroupShown), + afterActive ? "" : (shown ? checkTrue : checkFalse), + // Link to the errors, if a problem occurred while solving + ok ? (warn ? 'm' : (dof > 0 ? 'i' : 's')) : 'x', + g->h.v, (&TextWindow::ScreenHowGroupSolved), + ok ? ((warn && SS.checkClosedContour) ? "err" : sdof) : "", + ok ? "" : "ERR", + // Link to a screen that gives more details on the group + g->h.v, (&TextWindow::ScreenSelectGroup), s.c_str()); + + if(active) afterActive = true; + backgroundParity = !backgroundParity; + } + + Printf(true, " %Fl%Ls%fshow all%E / %Fl%Lh%fhide all%E", + &(TextWindow::ScreenShowGroupsSpecial), + &(TextWindow::ScreenShowGroupsSpecial)); + Printf(true, " %Fl%Ls%fline styles%E /" + " %Fl%Ls%fview%E /" + " %Fl%Ls%fconfiguration%E", + &(TextWindow::ScreenShowListOfStyles), + &(TextWindow::ScreenShowEditView), + &(TextWindow::ScreenShowConfiguration)); +} + + +//----------------------------------------------------------------------------- +// The screen that shows information about a specific group, and allows the +// user to edit various things about it. +//----------------------------------------------------------------------------- +void TextWindow::ScreenHoverGroupWorkplane(int link, uint32_t v) { + SS.GW.hover.Clear(); + hGroup hg = { v }; + SS.GW.hover.entity = hg.entity(0); + SS.GW.hover.emphasized = true; +} +void TextWindow::ScreenHoverEntity(int link, uint32_t v) { + SS.GW.hover.Clear(); + hEntity he = { v }; + SS.GW.hover.entity = he; + SS.GW.hover.emphasized = true; +} +void TextWindow::ScreenHoverRequest(int link, uint32_t v) { + SS.GW.hover.Clear(); + hRequest hr = { v }; + SS.GW.hover.entity = hr.entity(0); + SS.GW.hover.emphasized = true; +} +void TextWindow::ScreenHoverConstraint(int link, uint32_t v) { + if(!SS.GW.showConstraints) return; + + hConstraint hc = { v }; + SS.GW.hover.Clear(); + SS.GW.hover.constraint = hc; + SS.GW.hover.emphasized = true; +} +void TextWindow::ScreenSelectEntity(int link, uint32_t v) { + SS.GW.ClearSelection(); + GraphicsWindow::Selection sel = {}; + hEntity he = { v }; + sel.entity = he; + SS.GW.selection.Add(&sel); +} +void TextWindow::ScreenSelectRequest(int link, uint32_t v) { + SS.GW.ClearSelection(); + GraphicsWindow::Selection sel = {}; + hRequest hr = { v }; + sel.entity = hr.entity(0); + SS.GW.selection.Add(&sel); +} +void TextWindow::ScreenSelectConstraint(int link, uint32_t v) { + SS.GW.ClearSelection(); + GraphicsWindow::Selection sel = {}; + sel.constraint.v = v; + SS.GW.selection.Add(&sel); +} + +void TextWindow::ScreenChangeGroupOption(int link, uint32_t v) { + SS.UndoRemember(); + Group *g = SK.GetGroup(SS.TW.shown.group); + + switch(link) { + case 's': g->subtype = Group::Subtype::ONE_SIDED; break; + case 'S': g->subtype = Group::Subtype::TWO_SIDED; break; + + case 'k': g->skipFirst = true; break; + case 'K': g->skipFirst = false; break; + + case 'c': + if(g->type == Group::Type::EXTRUDE) { + // When an extrude group is first created, it's positioned for a union + // extrusion. If no constraints were added, flip it when we switch between + // union/assemble and difference/intersection modes to avoid manual work doing the same. + if(g->meshCombine != (Group::CombineAs)v && g->GetNumConstraints() == 0) { + // I apologise for this if statement + if((((Group::CombineAs::DIFFERENCE == g->meshCombine) || + (Group::CombineAs::INTERSECTION == g->meshCombine)) && + (Group::CombineAs::DIFFERENCE != (Group::CombineAs)v) && + (Group::CombineAs::INTERSECTION != (Group::CombineAs)v)) || + ((Group::CombineAs::DIFFERENCE != g->meshCombine) && + (Group::CombineAs::INTERSECTION != g->meshCombine) && + ((Group::CombineAs::DIFFERENCE == (Group::CombineAs)v) || + (Group::CombineAs::INTERSECTION == (Group::CombineAs)v)))) { + g->ExtrusionForceVectorTo(g->ExtrusionGetVector().Negated()); + } + } + } + g->meshCombine = (Group::CombineAs)v; + break; + + case 'P': g->suppress = !(g->suppress); break; + + case 'r': g->relaxConstraints = !(g->relaxConstraints); break; + + case 'e': g->allowRedundant = !(g->allowRedundant); break; + + case 'v': g->visible = !(g->visible); break; + + case 'd': g->allDimsReference = !(g->allDimsReference); break; + + case 'f': g->forceToMesh = !(g->forceToMesh); break; + } + + SS.MarkGroupDirty(g->h); + SS.GW.ClearSuper(); +} + +void TextWindow::ScreenColor(int link, uint32_t v) { + SS.UndoRemember(); + + Group *g = SK.GetGroup(SS.TW.shown.group); + SS.TW.ShowEditControlWithColorPicker(3, g->color); + SS.TW.edit.meaning = Edit::GROUP_COLOR; +} +void TextWindow::ScreenOpacity(int link, uint32_t v) { + Group *g = SK.GetGroup(SS.TW.shown.group); + + SS.TW.ShowEditControl(11, ssprintf("%.2f", g->color.alphaF())); + SS.TW.edit.meaning = Edit::GROUP_OPACITY; + SS.TW.edit.group = g->h; +} +void TextWindow::ScreenChangeExprA(int link, uint32_t v) { + Group *g = SK.GetGroup(SS.TW.shown.group); + + SS.TW.ShowEditControl(10, ssprintf("%d", (int)g->valA)); + SS.TW.edit.meaning = Edit::TIMES_REPEATED; + SS.TW.edit.group.v = v; +} +void TextWindow::ScreenChangeGroupName(int link, uint32_t v) { + Group *g = SK.GetGroup(SS.TW.shown.group); + SS.TW.ShowEditControl(12, g->DescriptionString().substr(5)); + SS.TW.edit.meaning = Edit::GROUP_NAME; + SS.TW.edit.group.v = v; +} +void TextWindow::ScreenChangeGroupScale(int link, uint32_t v) { + Group *g = SK.GetGroup(SS.TW.shown.group); + + SS.TW.ShowEditControl(13, ssprintf("%.3f", g->scale)); + SS.TW.edit.meaning = Edit::GROUP_SCALE; + SS.TW.edit.group.v = v; +} +void TextWindow::ScreenDeleteGroup(int link, uint32_t v) { + SS.UndoRemember(); + + hGroup hg = SS.TW.shown.group; + if(hg == SS.GW.activeGroup) { + SS.GW.activeGroup = SK.GetGroup(SS.GW.activeGroup)->PreviousGroup()->h; + } + + // Reset the text window, since we're displaying information about + // the group that's about to get deleted. + SS.TW.ClearSuper(); + + // This is a major change, so let's re-solve everything. + SK.group.RemoveById(hg); + SS.GenerateAll(SolveSpaceUI::Generate::ALL); + + // Reset the graphics window. This will also recreate the default + // group if it was removed. + SS.GW.ClearSuper(); +} +void TextWindow::ShowGroupInfo() { + Group *g = SK.GetGroup(shown.group); + const char *s = "???"; + + if(shown.group == Group::HGROUP_REFERENCES) { + Printf(true, "%FtGROUP %E%s", g->DescriptionString().c_str()); + goto list_items; + } else { + Printf(true, "%FtGROUP %E%s [%Fl%Ll%D%frename%E/%Fl%Ll%D%fdel%E]", + g->DescriptionString().c_str(), + g->h.v, &TextWindow::ScreenChangeGroupName, + g->h.v, &TextWindow::ScreenDeleteGroup); + } + + if(g->type == Group::Type::LATHE) { + Printf(true, " %Ftlathe plane sketch"); + } else if(g->type == Group::Type::EXTRUDE || g->type == Group::Type::ROTATE || + g->type == Group::Type::TRANSLATE || g->type == Group::Type::REVOLVE || + g->type == Group::Type::HELIX) { + if(g->type == Group::Type::EXTRUDE) { + s = "extrude plane sketch"; + } else if(g->type == Group::Type::TRANSLATE) { + s = "translate original sketch"; + } else if(g->type == Group::Type::HELIX) { + s = "create helical extrusion"; + } else if(g->type == Group::Type::ROTATE) { + s = "rotate original sketch"; + } else if(g->type == Group::Type::REVOLVE) { + s = "revolve original sketch"; + } + Printf(true, " %Ft%s%E", s); + + bool one = (g->subtype == Group::Subtype::ONE_SIDED); + Printf(false, + "%Ba %f%Ls%Fd%s one-sided%E " + "%f%LS%Fd%s two-sided%E", + &TextWindow::ScreenChangeGroupOption, + one ? RADIO_TRUE : RADIO_FALSE, + &TextWindow::ScreenChangeGroupOption, + !one ? RADIO_TRUE : RADIO_FALSE); + + if(g->type == Group::Type::ROTATE || g->type == Group::Type::TRANSLATE) { + if(g->subtype == Group::Subtype::ONE_SIDED) { + bool skip = g->skipFirst; + Printf(false, + "%Bd %Ftstart %f%LK%Fd%s with original%E " + "%f%Lk%Fd%s with copy #1%E", + &ScreenChangeGroupOption, + !skip ? RADIO_TRUE : RADIO_FALSE, + &ScreenChangeGroupOption, + skip ? RADIO_TRUE : RADIO_FALSE); + } + + int times = (int)(g->valA); + Printf(false, "%Bp %Ftrepeat%E %d time%s %Fl%Ll%D%f[change]%E", + (g->subtype == Group::Subtype::ONE_SIDED) ? 'a' : 'd', + times, times == 1 ? "" : "s", + g->h.v, &TextWindow::ScreenChangeExprA); + } + } else if(g->type == Group::Type::LINKED) { + Printf(true, " %Ftlink geometry from file%E"); + Platform::Path relativePath = g->linkFile.RelativeTo(SS.saveFile.Parent()); + if(relativePath.IsEmpty()) { + Printf(false, "%Ba '%s'", g->linkFile.raw.c_str()); + } else { + Printf(false, "%Ba '%s'", relativePath.raw.c_str()); + } + Printf(false, "%Bd %Ftscaled by%E %# %Fl%Ll%f%D[change]%E", + g->scale, + &TextWindow::ScreenChangeGroupScale, g->h.v); + } else if(g->type == Group::Type::DRAWING_3D) { + Printf(true, " %Ftsketch in 3d%E"); + } else if(g->type == Group::Type::DRAWING_WORKPLANE) { + Printf(true, " %Ftsketch in new workplane%E"); + } else { + Printf(true, "???"); + } + Printf(false, ""); + + if(g->type == Group::Type::EXTRUDE || g->type == Group::Type::LATHE || + g->type == Group::Type::REVOLVE || g->type == Group::Type::LINKED || + g->type == Group::Type::HELIX) { + bool un = (g->meshCombine == Group::CombineAs::UNION); + bool diff = (g->meshCombine == Group::CombineAs::DIFFERENCE); + bool intr = (g->meshCombine == Group::CombineAs::INTERSECTION); + bool asy = (g->meshCombine == Group::CombineAs::ASSEMBLE); + + Printf(false, " %Ftsolid model as"); + Printf(false, "%Ba %f%D%Lc%Fd%s union%E " + "%f%D%Lc%Fd%s assemble%E ", + &TextWindow::ScreenChangeGroupOption, + Group::CombineAs::UNION, + un ? RADIO_TRUE : RADIO_FALSE, + &TextWindow::ScreenChangeGroupOption, + Group::CombineAs::ASSEMBLE, + (asy ? RADIO_TRUE : RADIO_FALSE)); + Printf(false, "%Ba %f%D%Lc%Fd%s difference%E " + "%f%D%Lc%Fd%s intersection%E ", + &TextWindow::ScreenChangeGroupOption, + Group::CombineAs::DIFFERENCE, + diff ? RADIO_TRUE : RADIO_FALSE, + &TextWindow::ScreenChangeGroupOption, + Group::CombineAs::INTERSECTION, + intr ? RADIO_TRUE : RADIO_FALSE); + + if(g->type == Group::Type::EXTRUDE || g->type == Group::Type::LATHE || + g->type == Group::Type::REVOLVE || g->type == Group::Type::HELIX) { + Printf(false, + "%Bd %Ftcolor %E%Bz %Bd (%@, %@, %@) %f%D%Lf%Fl[change]%E", + &g->color, + g->color.redF(), g->color.greenF(), g->color.blueF(), + ScreenColor, top[rows-1] + 2); + Printf(false, "%Bd %Ftopacity%E %@ %f%Lf%Fl[change]%E", + g->color.alphaF(), + &TextWindow::ScreenOpacity); + } + + if(g->type == Group::Type::EXTRUDE || g->type == Group::Type::LATHE || + g->type == Group::Type::REVOLVE || g->type == Group::Type::LINKED || + g->type == Group::Type::HELIX) { + Printf(false, " %Fd%f%LP%s suppress this group's solid model", + &TextWindow::ScreenChangeGroupOption, + g->suppress ? CHECK_TRUE : CHECK_FALSE); + } + + Printf(false, ""); + } + + Printf(false, " %f%Lv%Fd%s show entities from this group", + &TextWindow::ScreenChangeGroupOption, + g->visible ? CHECK_TRUE : CHECK_FALSE); + + if(!g->IsForcedToMeshBySource()) { + Printf(false, " %f%Lf%Fd%s force NURBS surfaces to triangle mesh", + &TextWindow::ScreenChangeGroupOption, + g->forceToMesh ? CHECK_TRUE : CHECK_FALSE); + } else { + Printf(false, " (model already forced to triangle mesh)"); + } + + Printf(true, " %f%Lr%Fd%s relax constraints and dimensions", + &TextWindow::ScreenChangeGroupOption, + g->relaxConstraints ? CHECK_TRUE : CHECK_FALSE); + + Printf(false, " %f%Le%Fd%s allow redundant constraints", + &TextWindow::ScreenChangeGroupOption, + g->allowRedundant ? CHECK_TRUE : CHECK_FALSE); + + Printf(false, " %f%Ld%Fd%s treat all dimensions as reference", + &TextWindow::ScreenChangeGroupOption, + g->allDimsReference ? CHECK_TRUE : CHECK_FALSE); + + if(g->booleanFailed) { + Printf(false, ""); + Printf(false, "The Boolean operation failed. It may be "); + Printf(false, "possible to fix the problem by choosing "); + Printf(false, "'force NURBS surfaces to triangle mesh'."); + } + +list_items: + Printf(false, ""); + Printf(false, "%Ft requests in group"); + + int a = 0; + for(auto &r : SK.request) { + + if(r.group == shown.group) { + std::string s = r.DescriptionString(); + Printf(false, "%Bp %Fl%Ll%D%f%h%s%E", + (a & 1) ? 'd' : 'a', + r.h.v, + (&TextWindow::ScreenSelectRequest), + &(TextWindow::ScreenHoverRequest), + s.c_str()); + a++; + } + } + if(a == 0) Printf(false, "%Ba (none)"); + + a = 0; + Printf(false, ""); + Printf(false, "%Ft constraints in group (%d DOF)", g->solved.dof); + for(auto &c : SK.constraint) { + + if(c.group == shown.group) { + std::string s = c.DescriptionString(); + Printf(false, "%Bp %Fl%Ll%D%f%h%s%E %s", + (a & 1) ? 'd' : 'a', + c.h.v, + (&TextWindow::ScreenSelectConstraint), + (&TextWindow::ScreenHoverConstraint), + s.c_str(), + c.reference ? "(ref)" : ""); + a++; + } + } + if(a == 0) Printf(false, "%Ba (none)"); +} + +//----------------------------------------------------------------------------- +// The screen that's displayed when the sketch fails to solve. A report of +// what failed, and (if the problem is a singular Jacobian) a list of +// constraints that could be removed to fix it. +//----------------------------------------------------------------------------- +void TextWindow::ScreenAllowRedundant(int link, uint32_t v) { + SS.UndoRemember(); + + Group *g = SK.GetGroup(SS.TW.shown.group); + g->allowRedundant = true; + SS.MarkGroupDirty(SS.TW.shown.group); + + SS.TW.shown.screen = Screen::GROUP_INFO; + SS.TW.Show(); +} +void TextWindow::ShowGroupSolveInfo() { + Group *g = SK.GetGroup(shown.group); + if(g->IsSolvedOkay()) { + // Go back to the default group info screen + shown.screen = Screen::GROUP_INFO; + Show(); + return; + } + + Printf(true, "%FtGROUP %E%s", g->DescriptionString().c_str()); + switch(g->solved.how) { + case SolveResult::DIDNT_CONVERGE: + Printf(true, "%FxSOLVE FAILED!%Fd unsolvable constraints"); + Printf(true, "the following constraints are incompatible"); + break; + + case SolveResult::REDUNDANT_DIDNT_CONVERGE: + Printf(true, "%FxSOLVE FAILED!%Fd unsolvable constraints"); + Printf(true, "the following constraints are unsatisfied"); + break; + + case SolveResult::REDUNDANT_OKAY: + Printf(true, "%FxSOLVE FAILED!%Fd redundant constraints"); + Printf(true, "remove any one of these to fix it"); + break; + + case SolveResult::TOO_MANY_UNKNOWNS: + Printf(true, "Too many unknowns in a single group!"); + return; + + default: ssassert(false, "Unexpected solve result"); + } + + for(int i = 0; i < g->solved.remove.n; i++) { + hConstraint hc = g->solved.remove[i]; + Constraint *c = SK.constraint.FindByIdNoOops(hc); + if(!c) continue; + + Printf(false, "%Bp %Fl%Ll%D%f%h%s%E", + (i & 1) ? 'd' : 'a', + c->h.v, (&TextWindow::ScreenSelectConstraint), + (&TextWindow::ScreenHoverConstraint), + c->DescriptionString().c_str()); + } + + if(g->solved.timeout) { + Printf(true, "%FxSome items in list have been ommitted%Fd"); + Printf(false, "%Fxbecause the operation timed out.%Fd"); + } + + Printf(true, "It may be possible to fix the problem "); + Printf(false, "by selecting Edit -> Undo."); + + if(g->solved.how == SolveResult::REDUNDANT_OKAY) { + Printf(true, "It is possible to suppress this error "); + Printf(false, "by %Fl%f%Llallowing redundant constraints%E in ", + &TextWindow::ScreenAllowRedundant); + Printf(false, "this group."); + } +} + +//----------------------------------------------------------------------------- +// When we're stepping a dimension. User specifies the finish value, and +// how many steps to take in between current and finish, re-solving each +// time. +//----------------------------------------------------------------------------- +void TextWindow::ScreenStepDimFinish(int link, uint32_t v) { + SS.TW.edit.meaning = Edit::STEP_DIM_FINISH; + std::string edit_value; + if(SS.TW.stepDim.isDistance) { + edit_value = SS.MmToString(SS.TW.stepDim.finish); + } else { + edit_value = ssprintf("%.3f", SS.TW.stepDim.finish); + } + SS.TW.ShowEditControl(12, edit_value); +} +void TextWindow::ScreenStepDimSteps(int link, uint32_t v) { + SS.TW.edit.meaning = Edit::STEP_DIM_STEPS; + SS.TW.ShowEditControl(12, ssprintf("%d", SS.TW.stepDim.steps)); +} +void TextWindow::ScreenStepDimGo(int link, uint32_t v) { + hConstraint hc = SS.TW.shown.constraint; + Constraint *c = SK.constraint.FindByIdNoOops(hc); + if(c) { + SS.UndoRemember(); + + double start = c->valA, finish = SS.TW.stepDim.finish; + SS.TW.stepDim.time = GetMilliseconds(); + SS.TW.stepDim.step = 1; + + if(!SS.TW.stepDim.timer) { + SS.TW.stepDim.timer = Platform::CreateTimer(); + } + SS.TW.stepDim.timer->onTimeout = [=] { + if(SS.TW.stepDim.step <= SS.TW.stepDim.steps) { + c->valA = start + ((finish - start)*SS.TW.stepDim.step)/SS.TW.stepDim.steps; + SS.MarkGroupDirty(c->group); + SS.GenerateAll(); + if(!SS.ActiveGroupsOkay()) { + // Failed to solve, so quit + return; + } + SS.TW.stepDim.step++; + + const int64_t STEP_MILLIS = 50; + int64_t time = GetMilliseconds(); + if(time - SS.TW.stepDim.time < STEP_MILLIS) { + SS.TW.stepDim.timer->RunAfterNextFrame(); + } else { + SS.TW.stepDim.timer->RunAfter((unsigned)(time - SS.TW.stepDim.time - STEP_MILLIS)); + } + SS.TW.stepDim.time = time; + } else { + SS.TW.GoToScreen(Screen::LIST_OF_GROUPS); + SS.ScheduleShowTW(); + } + SS.GW.Invalidate(); + }; + SS.TW.stepDim.timer->RunAfterNextFrame(); + } +} +void TextWindow::ShowStepDimension() { + Constraint *c = SK.constraint.FindByIdNoOops(shown.constraint); + if(!c) { + shown.screen = Screen::LIST_OF_GROUPS; + Show(); + return; + } + + Printf(true, "%FtSTEP DIMENSION%E %s", c->DescriptionString().c_str()); + + if(stepDim.isDistance) { + Printf(true, "%Ba %Ftstart%E %s", SS.MmToString(c->valA).c_str()); + Printf(false, "%Bd %Ftfinish%E %s %Fl%Ll%f[change]%E", + SS.MmToString(stepDim.finish).c_str(), &ScreenStepDimFinish); + } else { + Printf(true, "%Ba %Ftstart%E %@", c->valA); + Printf(false, "%Bd %Ftfinish%E %@ %Fl%Ll%f[change]%E", + stepDim.finish, &ScreenStepDimFinish); + } + Printf(false, "%Ba %Ftsteps%E %d %Fl%Ll%f%D[change]%E", + stepDim.steps, &ScreenStepDimSteps); + + Printf(true, " %Fl%Ll%fstep dimension now%E", &ScreenStepDimGo); + + Printf(true, "(or %Fl%Ll%fcancel operation%E)", &ScreenHome); +} + +//----------------------------------------------------------------------------- +// When we're creating tangent arcs (as requests, not as some parametric +// thing). User gets to specify the radius, and whether the old untrimmed +// curves are kept or deleted. +//----------------------------------------------------------------------------- +void TextWindow::ScreenChangeTangentArc(int link, uint32_t v) { + switch(link) { + case 'r': { + SS.TW.edit.meaning = Edit::TANGENT_ARC_RADIUS; + SS.TW.ShowEditControl(3, SS.MmToString(SS.tangentArcRadius)); + break; + } + + case 'a': SS.tangentArcManual = !SS.tangentArcManual; break; + case 'm': SS.tangentArcModify = !SS.tangentArcModify; break; + } +} +void TextWindow::ShowTangentArc() { + Printf(true, "%FtTANGENT ARC PARAMETERS%E"); + + Printf(true, "%Ft radius of created arc%E"); + if(SS.tangentArcManual) { + Printf(false, "%Ba %s %Fl%Lr%f[change]%E", + SS.MmToString(SS.tangentArcRadius).c_str(), + &(TextWindow::ScreenChangeTangentArc)); + } else { + Printf(false, "%Ba automatic"); + } + + Printf(false, ""); + Printf(false, " %Fd%f%La%s choose radius automatically%E", + &ScreenChangeTangentArc, + !SS.tangentArcManual ? CHECK_TRUE : CHECK_FALSE); + Printf(false, " %Fd%f%Lm%s modify original entities%E", + &ScreenChangeTangentArc, + SS.tangentArcModify ? CHECK_TRUE : CHECK_FALSE); + + Printf(false, ""); + Printf(false, "To create a tangent arc at a point,"); + Printf(false, "select that point and then choose"); + Printf(false, "Sketch -> Tangent Arc at Point."); + Printf(true, "(or %Fl%Ll%fback to home screen%E)", &ScreenHome); +} + +//----------------------------------------------------------------------------- +// The edit control is visible, and the user just pressed enter. +//----------------------------------------------------------------------------- +void TextWindow::EditControlDone(std::string s) { + edit.showAgain = false; + + switch(edit.meaning) { + case Edit::TIMES_REPEATED: + if(Expr *e = Expr::From(s, /*popUpError=*/true)) { + SS.UndoRemember(); + + double ev = e->Eval(); + if((int)ev < 1) { + Error(_("Can't repeat fewer than 1 time.")); + break; + } + if((int)ev > 999) { + Error(_("Can't repeat more than 999 times.")); + break; + } + + Group *g = SK.GetGroup(edit.group); + g->valA = ev; + + if(g->type == Group::Type::ROTATE) { + // If the group does not contain any constraints, then + // set the numerical guess to space the copies uniformly + // over one rotation. Don't touch the guess if we're + // already constrained, because that would break + // convergence. + if(g->GetNumConstraints() == 0) { + double copies = (g->skipFirst) ? (ev + 1) : ev; + SK.GetParam(g->h.param(3))->val = PI/(2*copies); + } + } + + SS.MarkGroupDirty(g->h); + } + break; + + case Edit::GROUP_NAME: + if(s.empty()) { + Error(_("Group name cannot be empty")); + } else { + SS.UndoRemember(); + + Group *g = SK.GetGroup(edit.group); + g->name = s; + } + break; + + case Edit::GROUP_SCALE: + if(Expr *e = Expr::From(s, /*popUpError=*/true)) { + double ev = e->Eval(); + if(fabs(ev) < 1e-6) { + Error(_("Scale cannot be zero.")); + } else { + Group *g = SK.GetGroup(edit.group); + g->scale = ev; + SS.MarkGroupDirty(g->h); + } + } + break; + + case Edit::GROUP_COLOR: { + Vector rgb; + if(sscanf(s.c_str(), "%lf, %lf, %lf", &rgb.x, &rgb.y, &rgb.z)==3) { + rgb = rgb.ClampWithin(0, 1); + + Group *g = SK.group.FindByIdNoOops(SS.TW.shown.group); + if(!g) break; + g->color = RgbaColor::FromFloat((float)rgb.x, (float)rgb.y, (float)rgb.z, + g->color.alphaF()); + + SS.MarkGroupDirty(g->h); + SS.GW.ClearSuper(); + } else { + Error(_("Bad format: specify color as r, g, b")); + } + break; + } + case Edit::GROUP_OPACITY: + if(Expr *e = Expr::From(s, /*popUpError=*/true)) { + double alpha = e->Eval(); + if(alpha < 0 || alpha > 1) { + Error(_("Opacity must be between zero and one.")); + } else { + Group *g = SK.GetGroup(edit.group); + g->color.alpha = (int)(255.1f * alpha); + SS.MarkGroupDirty(g->h); + SS.GW.ClearSuper(); + } + } + break; + + case Edit::TTF_TEXT: + SS.UndoRemember(); + if(Request *r = SK.request.FindByIdNoOops(edit.request)) { + r->str = s; + SS.MarkGroupDirty(r->group); + } + break; + + case Edit::STEP_DIM_FINISH: + if(Expr *e = Expr::From(s, /*popUpError=*/true)) { + if(stepDim.isDistance) { + stepDim.finish = SS.ExprToMm(e); + } else { + stepDim.finish = e->Eval(); + } + } + break; + + case Edit::STEP_DIM_STEPS: + stepDim.steps = min(300, max(1, atoi(s.c_str()))); + break; + + case Edit::TANGENT_ARC_RADIUS: + if(Expr *e = Expr::From(s, /*popUpError=*/true)) { + if(e->Eval() < LENGTH_EPS) { + Error(_("Radius cannot be zero or negative.")); + break; + } + SS.tangentArcRadius = SS.ExprToMm(e); + } + break; + + default: { + int cnt = 0; + if(EditControlDoneForStyles(s)) cnt++; + if(EditControlDoneForConfiguration(s)) cnt++; + if(EditControlDoneForPaste(s)) cnt++; + if(EditControlDoneForView(s)) cnt++; + ssassert(cnt == 1, "Expected exactly one parameter to be edited"); + break; + } + } + SS.GW.Invalidate(); + SS.ScheduleShowTW(); + + if(!edit.showAgain) { + HideEditControl(); + edit.meaning = Edit::NOTHING; + } +} + diff --git a/src/textwin.cpp b/src/textwin.cpp new file mode 100644 index 0000000..3e33922 --- /dev/null +++ b/src/textwin.cpp @@ -0,0 +1,1168 @@ +//----------------------------------------------------------------------------- +// Helper functions for the text-based browser window. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +namespace SolveSpace { + +class Button { +public: + virtual std::string Tooltip() = 0; + virtual void Draw(UiCanvas *uiCanvas, int x, int y, bool asHovered) = 0; + virtual int AdvanceWidth() = 0; + virtual void Click() = 0; +}; + +class SpacerButton : public Button { +public: + std::string Tooltip() override { return ""; } + + void Draw(UiCanvas *uiCanvas, int x, int y, bool asHovered) override { + // Draw a darker-grey spacer in between the groups of icons. + uiCanvas->DrawRect(x, x + 4, y, y - 24, + /*fillColor=*/{ 45, 45, 45, 255 }, + /*outlineColor=*/{}); + } + + int AdvanceWidth() override { return 12; } + + void Click() override {} +}; + +class ShowHideButton : public Button { +public: + bool *variable; + std::string tooltip; + std::string iconName; + std::shared_ptr icon; + + ShowHideButton(bool *variable, std::string iconName, std::string tooltip) + : variable(variable), tooltip(tooltip), iconName(iconName) {} + + std::string Tooltip() override { + return ((*variable) ? "Hide " : "Show ") + tooltip; + } + + void Draw(UiCanvas *uiCanvas, int x, int y, bool asHovered) override { + if(icon == NULL) { + icon = LoadPng("icons/text-window/" + iconName + ".png"); + } + + uiCanvas->DrawPixmap(icon, x, y - 24); + if(asHovered) { + uiCanvas->DrawRect(x - 2, x + 26, y + 2, y - 26, + /*fillColor=*/{ 255, 255, 0, 75 }, + /*outlineColor=*/{}); + } + if(!*(variable)) { + int s = 0, f = 24; + RgbaColor color = { 255, 0, 0, 150 }; + uiCanvas->DrawLine(x+s, y-s, x+f, y-f, color, 2); + uiCanvas->DrawLine(x+s, y-f, x+f, y-s, color, 2); + } + } + + int AdvanceWidth() override { return 32; } + + void Click() override { SS.GW.ToggleBool(variable); } +}; + +class FacesButton : public ShowHideButton { +public: + FacesButton() + : ShowHideButton(&(SS.GW.showFaces), "faces", "") {} + + std::string Tooltip() override { + if(*variable) { + return "Don't make faces selectable with mouse"; + } else { + return "Make faces selectable with mouse"; + } + } +}; + +class OccludedLinesButton : public Button { +public: + std::shared_ptr visibleIcon; + std::shared_ptr stippledIcon; + std::shared_ptr invisibleIcon; + + std::string Tooltip() override { + switch(SS.GW.drawOccludedAs) { + case GraphicsWindow::DrawOccludedAs::INVISIBLE: + return "Stipple occluded lines"; + + case GraphicsWindow::DrawOccludedAs::STIPPLED: + return "Draw occluded lines"; + + case GraphicsWindow::DrawOccludedAs::VISIBLE: + return "Don't draw occluded lines"; + + default: ssassert(false, "Unexpected mode"); + } + } + + void Draw(UiCanvas *uiCanvas, int x, int y, bool asHovered) override { + if(visibleIcon == NULL) { + visibleIcon = LoadPng("icons/text-window/occluded-visible.png"); + } + if(stippledIcon == NULL) { + stippledIcon = LoadPng("icons/text-window/occluded-stippled.png"); + } + if(invisibleIcon == NULL) { + invisibleIcon = LoadPng("icons/text-window/occluded-invisible.png"); + } + + std::shared_ptr icon; + switch(SS.GW.drawOccludedAs) { + case GraphicsWindow::DrawOccludedAs::INVISIBLE: icon = invisibleIcon; break; + case GraphicsWindow::DrawOccludedAs::STIPPLED: icon = stippledIcon; break; + case GraphicsWindow::DrawOccludedAs::VISIBLE: icon = visibleIcon; break; + } + + uiCanvas->DrawPixmap(icon, x, y - 24); + if(asHovered) { + uiCanvas->DrawRect(x - 2, x + 26, y + 2, y - 26, + /*fillColor=*/{ 255, 255, 0, 75 }, + /*outlineColor=*/{}); + } + } + + int AdvanceWidth() override { return 32; } + + void Click() override { + switch(SS.GW.drawOccludedAs) { + case GraphicsWindow::DrawOccludedAs::INVISIBLE: + SS.GW.drawOccludedAs = GraphicsWindow::DrawOccludedAs::STIPPLED; + break; + + case GraphicsWindow::DrawOccludedAs::STIPPLED: + SS.GW.drawOccludedAs = GraphicsWindow::DrawOccludedAs::VISIBLE; + break; + + case GraphicsWindow::DrawOccludedAs::VISIBLE: + SS.GW.drawOccludedAs = GraphicsWindow::DrawOccludedAs::INVISIBLE; + break; + } + + SS.GenerateAll(); + SS.GW.Invalidate(); + SS.ScheduleShowTW(); + } +}; + +static SpacerButton spacerButton; + +static ShowHideButton workplanesButton = + { &(SS.GW.showWorkplanes), "workplane", "workplanes from inactive groups" }; +static ShowHideButton normalsButton = + { &(SS.GW.showNormals), "normal", "normals" }; +static ShowHideButton pointsButton = + { &(SS.GW.showPoints), "point", "points" }; +static ShowHideButton constructionButton = + { &(SS.GW.showConstruction), "construction", "construction entities" }; +static ShowHideButton constraintsButton = + { &(SS.GW.showConstraints), "constraint", "constraints and dimensions" }; +static FacesButton facesButton; +static ShowHideButton shadedButton = + { &(SS.GW.showShaded), "shaded", "shaded view of solid model" }; +static ShowHideButton edgesButton = + { &(SS.GW.showEdges), "edges", "edges of solid model" }; +static ShowHideButton outlinesButton = + { &(SS.GW.showOutlines), "outlines", "outline of solid model" }; +static ShowHideButton meshButton = + { &(SS.GW.showMesh), "mesh", "triangle mesh of solid model" }; +static OccludedLinesButton occludedLinesButton; + +static Button *buttons[] = { + &workplanesButton, + &normalsButton, + &pointsButton, + &constructionButton, + &constraintsButton, + &facesButton, + &spacerButton, + &shadedButton, + &edgesButton, + &outlinesButton, + &meshButton, + &spacerButton, + &occludedLinesButton, +}; + +/** Foreground color codes. */ +const TextWindow::Color TextWindow::fgColors[] = { + { 'd', RGBi(255, 255, 255) }, // Default : white + { 'l', RGBi(100, 200, 255) }, // links : blue + { 't', RGBi(255, 200, 100) }, // tree/text : yellow + { 'h', RGBi( 90, 90, 90) }, + { 's', RGBi( 40, 255, 40) }, // Ok : green + { 'm', RGBi(200, 200, 0) }, + { 'r', RGBi( 0, 0, 0) }, // Reverse : black + { 'x', RGBi(255, 20, 20) }, // Error : red + { 'i', RGBi( 0, 255, 255) }, // Info : cyan + { 'g', RGBi(160, 160, 160) }, + { 'b', RGBi(200, 200, 200) }, + { 0, RGBi( 0, 0, 0) } +}; +/** Background color codes. */ +const TextWindow::Color TextWindow::bgColors[] = { + { 'd', RGBi( 0, 0, 0) }, // Default : black + { 't', RGBi( 34, 15, 15) }, + { 'a', RGBi( 25, 25, 25) }, // Alternate : dark gray + { 'r', RGBi(255, 255, 255) }, // Reverse : white + { 0, RGBi( 0, 0, 0) } +}; + +void TextWindow::MakeColorTable(const Color *in, float *out) { + int i; + for(i = 0; in[i].c != 0; i++) { + int c = in[i].c; + ssassert(c >= 0 && c <= 255, "Unexpected color index"); + out[c*3 + 0] = in[i].color.redF(); + out[c*3 + 1] = in[i].color.greenF(); + out[c*3 + 2] = in[i].color.blueF(); + } +} + +void TextWindow::Init() { + if(!window) { + window = Platform::CreateWindow(Platform::Window::Kind::TOOL, SS.GW.window); + if(window) { + canvas = CreateRenderer(); + + using namespace std::placeholders; + window->onClose = []() { + SS.GW.showTextWindow = false; + SS.GW.EnsureValidActives(); + }; + window->onMouseEvent = [this](Platform::MouseEvent event) { + using Platform::MouseEvent; + + if(event.type == MouseEvent::Type::PRESS || + event.type == MouseEvent::Type::DBL_PRESS || + event.type == MouseEvent::Type::MOTION) { + bool isClick = (event.type != MouseEvent::Type::MOTION); + bool leftDown = (event.button == MouseEvent::Button::LEFT); + this->MouseEvent(isClick, leftDown, event.x, event.y); + return true; + } else if(event.type == MouseEvent::Type::LEAVE) { + MouseLeave(); + return true; + } else if(event.type == MouseEvent::Type::SCROLL_VERT) { + if (event.scrollDelta == 0) { + return true; + } + if (abs(event.scrollDelta) < 0.2) { + if (event.scrollDelta > 0) { + event.scrollDelta = 0.2; + } else { + event.scrollDelta = -0.2; + } + } + double offset = LINE_HEIGHT / 2 * event.scrollDelta; + ScrollbarEvent(window->GetScrollbarPosition() - offset); + } + return false; + }; + window->onKeyboardEvent = SS.GW.window->onKeyboardEvent; + window->onRender = std::bind(&TextWindow::Paint, this); + window->onEditingDone = std::bind(&TextWindow::EditControlDone, this, _1); + window->onScrollbarAdjusted = std::bind(&TextWindow::ScrollbarEvent, this, _1); + window->SetMinContentSize(370, 370); + } + } + + ClearSuper(); +} + +void TextWindow::ClearSuper() { + // Ugly hack, but not so ugly as the next line + Platform::WindowRef oldWindow = std::move(window); + std::shared_ptr oldCanvas = canvas; + + // Cannot use *this = {} here because TextWindow instances + // are 2.4MB long; this causes stack overflows in prologue + // when built with MSVC, even with optimizations. + memset(this, 0, sizeof(*this)); + + // Return old canvas + window = std::move(oldWindow); + canvas = oldCanvas; + + HideEditControl(); + + MakeColorTable(fgColors, fgColorTable); + MakeColorTable(bgColors, bgColorTable); + + ClearScreen(); + Show(); +} + +void TextWindow::HideEditControl() { + editControl.colorPicker.show = false; + if(window) { + window->HideEditor(); + window->Invalidate(); + } +} + +void TextWindow::ShowEditControl(int col, const std::string &str, int halfRow) { + if(halfRow < 0) halfRow = top[hoveredRow]; + editControl.halfRow = halfRow; + editControl.col = col; + + int x = LEFT_MARGIN + CHAR_WIDTH_*col; + int y = (halfRow - SS.TW.scrollPos)*(LINE_HEIGHT/2); + + double width, height; + window->GetContentSize(&width, &height); + window->ShowEditor(x, y + LINE_HEIGHT - 2, LINE_HEIGHT - 4, + width - x, /*isMonospace=*/true, str); +} + +void TextWindow::ShowEditControlWithColorPicker(int col, RgbaColor rgb) { + SS.ScheduleShowTW(); + + editControl.colorPicker.show = true; + editControl.colorPicker.rgb = rgb; + editControl.colorPicker.h = 0; + editControl.colorPicker.s = 0; + editControl.colorPicker.v = 1; + ShowEditControl(col, ssprintf("%.2f, %.2f, %.2f", rgb.redF(), rgb.greenF(), rgb.blueF())); +} + +void TextWindow::ClearScreen() { + int i, j; + for(i = 0; i < MAX_ROWS; i++) { + for(j = 0; j < MAX_COLS; j++) { + text[i][j] = ' '; + meta[i][j].fg = 'd'; + meta[i][j].bg = 'd'; + meta[i][j].link = NOT_A_LINK; + } + top[i] = i*2; + } + rows = 0; +} + +// This message was addded when someone had too many fonts for the text window +// Scrolling seemed to be broken, but was actaully at the MAX_ROWS. +static const char* endString = " **** End of Text Screen ****"; + +void TextWindow::Printf(bool halfLine, const char *fmt, ...) { + if(!canvas) return; + + if(rows >= MAX_ROWS) return; + + if(rows >= MAX_ROWS-2 && (fmt != endString)) { + // twice due to some half-row issues on resizing + Printf(halfLine, endString); + Printf(halfLine, endString); + return; + } + + va_list vl; + va_start(vl, fmt); + + int r, c; + r = rows; + top[r] = (r == 0) ? 0 : (top[r-1] + (halfLine ? 3 : 2)); + rows++; + + for(c = 0; c < MAX_COLS; c++) { + text[r][c] = ' '; + meta[r][c].link = NOT_A_LINK; + } + + char fg = 'd'; + char bg = 'd'; + RgbaColor bgRgb = RGBi(0, 0, 0); + int link = NOT_A_LINK; + uint32_t data = 0; + LinkFunction *f = NULL, *h = NULL; + + c = 0; + while(*fmt) { + char buf[1024]; + + if(*fmt == '%') { + fmt++; + if(*fmt == '\0') goto done; + strcpy(buf, ""); + switch(*fmt) { + case 'd': { + int v = va_arg(vl, int); + sprintf(buf, "%d", v); + break; + } + case 'x': { + unsigned int v = va_arg(vl, unsigned int); + sprintf(buf, "%08x", v); + break; + } + case '@': { + double v = va_arg(vl, double); + sprintf(buf, "%.2f", v); + break; + } + case '2': { + double v = va_arg(vl, double); + sprintf(buf, "%s%.2f", v < 0 ? "" : " ", v); + break; + } + case '3': { + double v = va_arg(vl, double); + sprintf(buf, "%s%.3f", v < 0 ? "" : " ", v); + break; + } + case '#': { + double v = va_arg(vl, double); + sprintf(buf, "%.3f", v); + break; + } + case 's': { + char *s = va_arg(vl, char *); + memcpy(buf, s, min(sizeof(buf), strlen(s)+1)); + break; + } + case 'c': { + // 'char' is promoted to 'int' when passed through '...' + int v = va_arg(vl, int); + if(v == 0) { + strcpy(buf, ""); + } else { + sprintf(buf, "%c", v); + } + break; + } + case 'E': + fg = 'd'; + // leave the background, though + link = NOT_A_LINK; + data = 0; + f = NULL; + h = NULL; + break; + + case 'F': + case 'B': { + char cc = fmt[1]; // color code + RgbaColor *rgbPtr = NULL; + switch(cc) { + case 0: goto done; // truncated directive + case 'p': cc = (char)va_arg(vl, int); break; + case 'z': rgbPtr = va_arg(vl, RgbaColor *); break; + } + if(*fmt == 'F') { + fg = cc; + } else { + bg = cc; + if(rgbPtr) bgRgb = *rgbPtr; + } + fmt++; + break; + } + case 'L': + if(fmt[1] == '\0') goto done; + fmt++; + if(*fmt == 'p') { + link = va_arg(vl, int); + } else { + link = *fmt; + } + break; + + case 'f': + f = va_arg(vl, LinkFunction *); + break; + + case 'h': + h = va_arg(vl, LinkFunction *); + break; + + case 'D': { + unsigned int v = va_arg(vl, unsigned int); + data = (uint32_t)v; + break; + } + case '%': + strcpy(buf, "%"); + break; + } + } else { + utf8_iterator it2(fmt), it1 = it2++; + strncpy(buf, fmt, it2 - it1); + buf[it2 - it1] = '\0'; + } + + for(utf8_iterator it(buf); *it; ++it) { + for(size_t i = 0; i < canvas->GetBitmapFont()->GetWidth(*it); i++) { + if(c >= MAX_COLS) goto done; + text[r][c] = (i == 0) ? *it : ' '; + meta[r][c].fg = fg; + meta[r][c].bg = bg; + meta[r][c].bgRgb = bgRgb; + meta[r][c].link = link; + meta[r][c].data = data; + meta[r][c].f = f; + meta[r][c].h = h; + c++; + } + } + + utf8_iterator it(fmt); + it++; + fmt = it.ptr(); + } + while(c < MAX_COLS) { + meta[r][c].fg = fg; + meta[r][c].bg = bg; + meta[r][c].bgRgb = bgRgb; + c++; + } + +done: + va_end(vl); +} + +void TextWindow::Show() { + if(SS.GW.pending.operation == GraphicsWindow::Pending::NONE) { + SS.GW.ClearPending(/*scheduleShowTW=*/false); + } + + SS.GW.GroupSelection(); + auto const &gs = SS.GW.gs; + + // Make sure these tests agree with test used to draw indicator line on + // main list of groups screen. + if(SS.GW.pending.description) { + // A pending operation (that must be completed with the mouse in + // the graphics window) will preempt our usual display. + HideEditControl(); + ShowHeader(false); + Printf(false, ""); + Printf(false, "%s", SS.GW.pending.description); + Printf(true, "%Fl%f%Ll(cancel operation)%E", + &TextWindow::ScreenUnselectAll); + } else if((gs.n > 0 || gs.constraints > 0) && + shown.screen != Screen::PASTE_TRANSFORMED) + { + if(edit.meaning != Edit::TTF_TEXT) HideEditControl(); + ShowHeader(false); + DescribeSelection(); + } else { + if(edit.meaning == Edit::TTF_TEXT) HideEditControl(); + ShowHeader(true); + switch(shown.screen) { + default: + shown.screen = Screen::LIST_OF_GROUPS; + // fall through + case Screen::LIST_OF_GROUPS: ShowListOfGroups(); break; + case Screen::GROUP_INFO: ShowGroupInfo(); break; + case Screen::GROUP_SOLVE_INFO: ShowGroupSolveInfo(); break; + case Screen::CONFIGURATION: ShowConfiguration(); break; + case Screen::STEP_DIMENSION: ShowStepDimension(); break; + case Screen::LIST_OF_STYLES: ShowListOfStyles(); break; + case Screen::STYLE_INFO: ShowStyleInfo(); break; + case Screen::PASTE_TRANSFORMED: ShowPasteTransformed(); break; + case Screen::EDIT_VIEW: ShowEditView(); break; + case Screen::TANGENT_ARC: ShowTangentArc(); break; + } + } + Printf(false, ""); + + // Make sure there's room for the color picker + if(editControl.colorPicker.show) { + int pickerHeight = 25; + int halfRow = editControl.halfRow; + if(top[rows-1] - halfRow < pickerHeight && rows < MAX_ROWS) { + rows++; + top[rows-1] = halfRow + pickerHeight; + } + } + + if(window) Resize(); +} + +void TextWindow::Resize() +{ + double width, height; + window->GetContentSize(&width, &height); + + halfRows = (int)height / (LINE_HEIGHT/2); + + int bottom = top[rows-1] + 2; + scrollPos = min(scrollPos, bottom - halfRows); + scrollPos = max(scrollPos, 0); + + window->ConfigureScrollbar(0, top[rows - 1] + 1, halfRows); + window->SetScrollbarPosition(scrollPos); + window->SetScrollbarVisible(top[rows - 1] + 1 > halfRows); + window->Invalidate(); +} + +void TextWindow::DrawOrHitTestIcons(UiCanvas *uiCanvas, TextWindow::DrawOrHitHow how, + double mx, double my) +{ + double width, height; + window->GetContentSize(&width, &height); + + int x = 20, y = 33 + LINE_HEIGHT; + y -= scrollPos*(LINE_HEIGHT/2); + + if(how == PAINT) { + int top = y - 28, bot = y + 4; + uiCanvas->DrawRect(0, (int)width, top, bot, + /*fillColor=*/{ 30, 30, 30, 255 }, /*outlineColor=*/{}); + } + + Button *oldHovered = hoveredButton; + if(how != PAINT) { + hoveredButton = NULL; + } + + double hoveredX, hoveredY; + for(Button *button : buttons) { + if(how == PAINT) { + button->Draw(uiCanvas, x, y, (button == hoveredButton)); + } else if(mx > x - 2 && mx < x + 26 && + my < y + 2 && my > y - 26) { + hoveredButton = button; + hoveredX = x - 2; + hoveredY = y - 26; + if(how == CLICK) { + button->Click(); + } + } + + x += button->AdvanceWidth(); + } + + if(how != PAINT && hoveredButton != oldHovered) { + if(hoveredButton == NULL) { + window->SetTooltip("", 0, 0, 0, 0); + } else { + window->SetTooltip(hoveredButton->Tooltip(), hoveredX, hoveredY, 28, 28); + } + window->Invalidate(); + } +} + +//---------------------------------------------------------------------------- +// Given (x, y, z) = (h, s, v) in [0,6), [0,1], [0,1], return (x, y, z) = +// (r, g, b) all in [0, 1]. +//---------------------------------------------------------------------------- +Vector TextWindow::HsvToRgb(Vector hsv) { + if(hsv.x >= 6) hsv.x -= 6; + + Vector rgb; + double hmod2 = hsv.x; + while(hmod2 >= 2) hmod2 -= 2; + double x = (1 - fabs(hmod2 - 1)); + if(hsv.x < 1) { + rgb = Vector::From(1, x, 0); + } else if(hsv.x < 2) { + rgb = Vector::From(x, 1, 0); + } else if(hsv.x < 3) { + rgb = Vector::From(0, 1, x); + } else if(hsv.x < 4) { + rgb = Vector::From(0, x, 1); + } else if(hsv.x < 5) { + rgb = Vector::From(x, 0, 1); + } else { + rgb = Vector::From(1, 0, x); + } + double c = hsv.y*hsv.z; + double m = 1 - hsv.z; + rgb = rgb.ScaledBy(c); + rgb = rgb.Plus(Vector::From(m, m, m)); + + return rgb; +} + +std::shared_ptr TextWindow::HsvPattern2d(int w, int h) { + std::shared_ptr pixmap = Pixmap::Create(Pixmap::Format::RGB, w, h); + for(size_t j = 0; j < pixmap->height; j++) { + size_t p = pixmap->stride * j; + for(size_t i = 0; i < pixmap->width; i++) { + Vector hsv = Vector::From(6.0*i/(pixmap->width-1), 1.0*j/(pixmap->height-1), 1); + Vector rgb = HsvToRgb(hsv); + rgb = rgb.ScaledBy(255); + pixmap->data[p++] = (uint8_t)rgb.x; + pixmap->data[p++] = (uint8_t)rgb.y; + pixmap->data[p++] = (uint8_t)rgb.z; + } + } + return pixmap; +} + +std::shared_ptr TextWindow::HsvPattern1d(double hue, double sat, int w, int h) { + std::shared_ptr pixmap = Pixmap::Create(Pixmap::Format::RGB, w, h); + for(size_t i = 0; i < pixmap->height; i++) { + size_t p = i * pixmap->stride; + for(size_t j = 0; j < pixmap->width; j++) { + Vector hsv = Vector::From(6*hue, sat, 1.0*(pixmap->width - 1 - j)/pixmap->width); + Vector rgb = HsvToRgb(hsv); + rgb = rgb.ScaledBy(255); + pixmap->data[p++] = (uint8_t)rgb.x; + pixmap->data[p++] = (uint8_t)rgb.y; + pixmap->data[p++] = (uint8_t)rgb.z; + } + } + return pixmap; +} + +void TextWindow::ColorPickerDone() { + RgbaColor rgb = editControl.colorPicker.rgb; + EditControlDone(ssprintf("%.2f, %.2f, %.3f", rgb.redF(), rgb.greenF(), rgb.blueF())); +} + +bool TextWindow::DrawOrHitTestColorPicker(UiCanvas *uiCanvas, DrawOrHitHow how, bool leftDown, + double x, double y) +{ + using Platform::Window; + + bool mousePointerAsHand = false; + + if(how == HOVER && !leftDown) { + editControl.colorPicker.picker1dActive = false; + editControl.colorPicker.picker2dActive = false; + } + + if(!editControl.colorPicker.show) return false; + if(how == CLICK || (how == HOVER && leftDown)) window->Invalidate(); + + static const RgbaColor BaseColor[12] = { + RGBi(255, 0, 0), + RGBi( 0, 255, 0), + RGBi( 0, 0, 255), + + RGBi( 0, 255, 255), + RGBi(255, 0, 255), + RGBi(255, 255, 0), + + RGBi(255, 127, 0), + RGBi(255, 0, 127), + RGBi( 0, 255, 127), + RGBi(127, 255, 0), + RGBi(127, 0, 255), + RGBi( 0, 127, 255), + }; + + double width, height; + window->GetContentSize(&width, &height); + + int px = LEFT_MARGIN + CHAR_WIDTH_*editControl.col; + int py = (editControl.halfRow - SS.TW.scrollPos)*(LINE_HEIGHT/2); + + py += LINE_HEIGHT + 5; + + static const int WIDTH = 16, HEIGHT = 12; + static const int PITCH = 18, SIZE = 15; + + px = min(px, (int)width - (WIDTH*PITCH + 40)); + + int pxm = px + WIDTH*PITCH + 11, + pym = py + HEIGHT*PITCH + 7; + + int bw = 6; + if(how == PAINT) { + uiCanvas->DrawRect(px, pxm+bw, py, pym+bw, + /*fillColor=*/{ 50, 50, 50, 255 }, + /*outlineColor=*/{}, + /*zIndex=*/1); + uiCanvas->DrawRect(px+(bw/2), pxm+(bw/2), py+(bw/2), pym+(bw/2), + /*fillColor=*/{ 0, 0, 0, 255 }, + /*outlineColor=*/{}, + /*zIndex=*/1); + } else { + if(x < px || x > pxm+(bw/2) || + y < py || y > pym+(bw/2)) + { + return false; + } + } + px += (bw/2); + py += (bw/2); + + int i, j; + for(i = 0; i < WIDTH/2; i++) { + for(j = 0; j < HEIGHT; j++) { + Vector rgb; + RgbaColor d; + if(i == 0 && j < 8) { + d = SS.modelColor[j]; + rgb = Vector::From(d.redF(), d.greenF(), d.blueF()); + } else if(i == 0) { + double a = (j - 8.0)/3.0; + rgb = Vector::From(a, a, a); + } else { + d = BaseColor[j]; + rgb = Vector::From(d.redF(), d.greenF(), d.blueF()); + if(i >= 2 && i <= 4) { + double a = (i == 2) ? 0.2 : (i == 3) ? 0.3 : 0.4; + rgb = rgb.Plus(Vector::From(a, a, a)); + } + if(i >= 5 && i <= 7) { + double a = (i == 5) ? 0.7 : (i == 6) ? 0.4 : 0.18; + rgb = rgb.ScaledBy(a); + } + } + + rgb = rgb.ClampWithin(0, 1); + int sx = px + 5 + PITCH*(i + 8) + 4, sy = py + 5 + PITCH*j; + + if(how == PAINT) { + uiCanvas->DrawRect(sx, sx+SIZE, sy, sy+SIZE, + /*fillColor=*/RGBf(rgb.x, rgb.y, rgb.z), + /*outlineColor=*/{}, + /*zIndex=*/2); + } else if(how == CLICK) { + if(x >= sx && x <= sx+SIZE && y >= sy && y <= sy+SIZE) { + editControl.colorPicker.rgb = RGBf(rgb.x, rgb.y, rgb.z); + ColorPickerDone(); + } + } else if(how == HOVER) { + if(x >= sx && x <= sx+SIZE && y >= sy && y <= sy+SIZE) { + mousePointerAsHand = true; + } + } + } + } + + int hxm, hym; + int hx = px + 5, hy = py + 5; + hxm = hx + PITCH*7 + SIZE; + hym = hy + PITCH*2 + SIZE; + if(how == PAINT) { + uiCanvas->DrawRect(hx, hxm, hy, hym, + /*fillColor=*/editControl.colorPicker.rgb, + /*outlineColor=*/{}, + /*zIndex=*/2); + } else if(how == CLICK) { + if(x >= hx && x <= hxm && y >= hy && y <= hym) { + ColorPickerDone(); + } + } else if(how == HOVER) { + if(x >= hx && x <= hxm && y >= hy && y <= hym) { + mousePointerAsHand = true; + } + } + + hy += PITCH*3; + + hxm = hx + PITCH*7 + SIZE; + hym = hy + PITCH*1 + SIZE; + // The one-dimensional thing to pick the color's value + if(how == PAINT) { + uiCanvas->DrawPixmap(HsvPattern1d(editControl.colorPicker.h, + editControl.colorPicker.s, + hxm-hx, hym-hy), + hx, hy, /*zIndex=*/2); + + int cx = hx+(int)((hxm-hx)*(1.0 - editControl.colorPicker.v)); + uiCanvas->DrawLine(cx, hy, cx, hym, + /*fillColor=*/{ 0, 0, 0, 255 }, + /*outlineColor=*/{}, + /*zIndex=*/3); + } else if(how == CLICK || + (how == HOVER && leftDown && editControl.colorPicker.picker1dActive)) + { + if(x >= hx && x <= hxm && y >= hy && y <= hym) { + editControl.colorPicker.v = 1 - (x - hx)/(hxm - hx); + + Vector rgb = HsvToRgb(Vector::From( + 6*editControl.colorPicker.h, + editControl.colorPicker.s, + editControl.colorPicker.v)); + editControl.colorPicker.rgb = RGBf(rgb.x, rgb.y, rgb.z); + + editControl.colorPicker.picker1dActive = true; + } + } + // and advance our vertical position + hy += PITCH*2; + + hxm = hx + PITCH*7 + SIZE; + hym = hy + PITCH*6 + SIZE; + // Two-dimensional thing to pick a color by hue and saturation + if(how == PAINT) { + uiCanvas->DrawPixmap(HsvPattern2d(hxm-hx, hym-hy), hx, hy, + /*zIndex=*/2); + + int cx = hx+(int)((hxm-hx)*editControl.colorPicker.h), + cy = hy+(int)((hym-hy)*editControl.colorPicker.s); + uiCanvas->DrawLine(cx - 5, cy, cx + 5, cy, + /*fillColor=*/{ 255, 255, 255, 255 }, + /*outlineColor=*/{}, + /*zIndex=*/3); + uiCanvas->DrawLine(cx, cy - 5, cx, cy + 5, + /*fillColor=*/{ 255, 255, 255, 255 }, + /*outlineColor=*/{}, + /*zIndex=*/3); + } else if(how == CLICK || + (how == HOVER && leftDown && editControl.colorPicker.picker2dActive)) + { + if(x >= hx && x <= hxm && y >= hy && y <= hym) { + double h = (x - hx)/(hxm - hx), + s = (y - hy)/(hym - hy); + editControl.colorPicker.h = h; + editControl.colorPicker.s = s; + + Vector rgb = HsvToRgb(Vector::From( + 6*editControl.colorPicker.h, + editControl.colorPicker.s, + editControl.colorPicker.v)); + editControl.colorPicker.rgb = RGBf(rgb.x, rgb.y, rgb.z); + + editControl.colorPicker.picker2dActive = true; + } + } + + window->SetCursor(mousePointerAsHand ? + Window::Cursor::HAND : + Window::Cursor::POINTER); + return true; +} + +void TextWindow::Paint() { + if (!canvas) return; + + double width, height; + window->GetContentSize(&width, &height); + if(halfRows != (int)height / (LINE_HEIGHT/2)) + Resize(); + + Camera camera = {}; + camera.width = width; + camera.height = height; + camera.pixelRatio = window->GetDevicePixelRatio(); + camera.gridFit = (window->GetDevicePixelRatio() == 1); + camera.LoadIdentity(); + camera.offset.x = -camera.width / 2.0; + camera.offset.y = -camera.height / 2.0; + + Lighting lighting = {}; + lighting.backgroundColor = RGBi(0, 0, 0); + + canvas->SetLighting(lighting); + canvas->SetCamera(camera); + canvas->StartFrame(); + + UiCanvas uiCanvas = {}; + uiCanvas.canvas = canvas; + uiCanvas.flip = true; + + int r, c, a; + for(a = 0; a < 2; a++) { + for(r = 0; r < rows; r++) { + int ltop = top[r]; + if(ltop < (scrollPos-1)) continue; + if(ltop > scrollPos+halfRows) break; + + for(c = 0; c < min(((int)width/CHAR_WIDTH_)+1, (int) MAX_COLS); c++) { + int x = LEFT_MARGIN + c*CHAR_WIDTH_; + int y = (ltop-scrollPos)*(LINE_HEIGHT/2) + 4; + + int fg = meta[r][c].fg; + int bg = meta[r][c].bg; + + // On the first pass, all the background quads; on the next + // pass, all the foreground (i.e., font) quads. + if(a == 0) { + RgbaColor bgRgb = meta[r][c].bgRgb; + int bh = LINE_HEIGHT, adj = 0; + if(bg == 'z') { + bh = CHAR_HEIGHT; + adj += 2; + } else { + bgRgb = RgbaColor::FromFloat(bgColorTable[bg*3+0], + bgColorTable[bg*3+1], + bgColorTable[bg*3+2]); + } + + if(bg != 'd') { + // Move the quad down a bit, so that the descenders + // still have the correct background. + uiCanvas.DrawRect(x, x + CHAR_WIDTH_, y + adj, y + adj + bh, + /*fillColor=*/bgRgb, /*outlineColor=*/{}); + } + } else if(a == 1) { + RgbaColor fgRgb = RgbaColor::FromFloat(fgColorTable[fg*3+0], + fgColorTable[fg*3+1], + fgColorTable[fg*3+2]); + if(text[r][c] != ' ') { + uiCanvas.DrawBitmapChar(text[r][c], x, y + CHAR_HEIGHT, fgRgb); + } + + // If this is a link and it's hovered, then draw the + // underline + if(meta[r][c].link && meta[r][c].link != 'n' && + (r == hoveredRow && c == hoveredCol)) + { + int cs = c, cf = c; + while(cs >= 0 && meta[r][cs].link && + meta[r][cs].f == meta[r][c].f && + meta[r][cs].data == meta[r][c].data) + { + cs--; + } + cs++; + + while( meta[r][cf].link && + meta[r][cf].f == meta[r][c].f && + meta[r][cf].data == meta[r][c].data) + { + cf++; + } + + // But don't underline checkboxes or radio buttons + while(((text[r][cs] >= 0xe000 && text[r][cs] <= 0xefff) || + text[r][cs] == ' ') && + cs < cf) + { + cs++; + } + + // Always use the color of the rightmost character + // in the link, so that underline is consistent color + fg = meta[r][cf-1].fg; + fgRgb = RgbaColor::FromFloat(fgColorTable[fg*3+0], + fgColorTable[fg*3+1], + fgColorTable[fg*3+2]); + int yp = y + CHAR_HEIGHT; + uiCanvas.DrawLine(LEFT_MARGIN + cs*CHAR_WIDTH_, yp, + LEFT_MARGIN + cf*CHAR_WIDTH_, yp, + fgRgb); + } + } + } + } + } + + // The line to indicate the column of radio buttons that indicates the + // active group. + SS.GW.GroupSelection(); + auto const &gs = SS.GW.gs; + // Make sure this test agrees with test to determine which screen is drawn + if(!SS.GW.pending.description && gs.n == 0 && gs.constraints == 0 && + shown.screen == Screen::LIST_OF_GROUPS) + { + int x = 29, y = 70 + LINE_HEIGHT; + y -= scrollPos*(LINE_HEIGHT/2); + + RgbaColor color = RgbaColor::FromFloat(fgColorTable['t'*3+0], + fgColorTable['t'*3+1], + fgColorTable['t'*3+2]); + uiCanvas.DrawLine(x, y, x, y+40, color); + } + + // The header has some icons that are drawn separately from the text + DrawOrHitTestIcons(&uiCanvas, PAINT, 0, 0); + + // And we may show a color picker for certain editable fields + DrawOrHitTestColorPicker(&uiCanvas, PAINT, false, 0, 0); + + canvas->FlushFrame(); + canvas->FinishFrame(); + canvas->Clear(); +} + +void TextWindow::MouseEvent(bool leftClick, bool leftDown, double x, double y) { + using Platform::Window; + + if(SS.TW.window->IsEditorVisible() || SS.GW.window->IsEditorVisible()) { + if(DrawOrHitTestColorPicker(NULL, leftClick ? CLICK : HOVER, leftDown, x, y)) { + return; + } + + if(leftClick) { + HideEditControl(); + SS.GW.window->HideEditor(); + } else { + window->SetCursor(Window::Cursor::POINTER); + } + return; + } + + DrawOrHitTestIcons(NULL, leftClick ? CLICK : HOVER, x, y); + + GraphicsWindow::Selection ps = SS.GW.hover; + SS.GW.hover.Clear(); + + int prevHoveredRow = hoveredRow, + prevHoveredCol = hoveredCol; + hoveredRow = 0; + hoveredCol = 0; + + // Find the corresponding character in the text buffer + int c = (int)((x - LEFT_MARGIN) / CHAR_WIDTH_); + int hh = (LINE_HEIGHT)/2; + y += scrollPos*hh; + int r; + for(r = 0; r < rows; r++) { + if(y >= top[r]*hh && y <= (top[r]+2)*hh) { + break; + } + } + if(r >= 0 && c >= 0 && r < rows && c < MAX_COLS) { + window->SetCursor(Window::Cursor::POINTER); + + hoveredRow = r; + hoveredCol = c; + + const auto &item = meta[r][c]; + if(leftClick) { + if(item.link && item.f) { + (item.f)(item.link, item.data); + Show(); + SS.GW.Invalidate(); + } + } else { + if(item.link) { + window->SetCursor(Window::Cursor::HAND); + if(item.h) { + (item.h)(item.link, item.data); + } + } else { + window->SetCursor(Window::Cursor::POINTER); + } + } + } + + if((!ps.Equals(&(SS.GW.hover))) || + prevHoveredRow != hoveredRow || + prevHoveredCol != hoveredCol) + { + SS.GW.Invalidate(); + window->Invalidate(); + } +} + +void TextWindow::MouseLeave() { + hoveredButton = NULL; + hoveredRow = 0; + hoveredCol = 0; + window->Invalidate(); +} + +void TextWindow::ScrollbarEvent(double newPos) { + if(window->IsEditorVisible()) { + // An edit field is active. Do not move the scrollbar. + return; + } + + int bottom = top[rows-1] + 2; + newPos = min((int)newPos, bottom - halfRows); + newPos = max((int)newPos, 0); + if(newPos != scrollPos) { + scrollPos = (int)newPos; + window->SetScrollbarPosition(scrollPos); + window->Invalidate(); + } +} + +} diff --git a/src/toolbar.cpp b/src/toolbar.cpp new file mode 100644 index 0000000..bf6b59c --- /dev/null +++ b/src/toolbar.cpp @@ -0,0 +1,241 @@ +//----------------------------------------------------------------------------- +// The toolbar that appears at the top left of the graphics window, where the +// user can select icons with the mouse, to perform operations equivalent to +// selecting a menu item or using a keyboard shortcut. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +struct ToolIcon { + std::string name; + Command command; + const char *tooltip; + std::shared_ptr pixmap; +}; +static ToolIcon Toolbar[] = { + { "line", Command::LINE_SEGMENT, + N_("Sketch line segment"), {} }, + { "rectangle", Command::RECTANGLE, + N_("Sketch rectangle"), {} }, + { "circle", Command::CIRCLE, + N_("Sketch circle"), {} }, + { "arc", Command::ARC, + N_("Sketch arc of a circle"), {} }, + { "text", Command::TTF_TEXT, + N_("Sketch curves from text in a TrueType font"), {} }, + { "image", Command::IMAGE, + N_("Sketch image from a file"), {} }, + { "tangent-arc", Command::TANGENT_ARC, + N_("Create tangent arc at selected point"), {} }, + { "bezier", Command::CUBIC, + N_("Sketch cubic Bezier spline"), {} }, + { "point", Command::DATUM_POINT, + N_("Sketch datum point"), {} }, + { "construction", Command::CONSTRUCTION, + N_("Toggle construction"), {} }, + { "trim", Command::SPLIT_CURVES, + N_("Split lines / curves where they intersect"), {} }, + { "", Command::NONE, "", {} }, + + { "length", Command::DISTANCE_DIA, + N_("Constrain distance / diameter / length"), {} }, + { "angle", Command::ANGLE, + N_("Constrain angle"), {} }, + { "horiz", Command::HORIZONTAL, + N_("Constrain to be horizontal"), {} }, + { "vert", Command::VERTICAL, + N_("Constrain to be vertical"), {} }, + { "parallel", Command::PARALLEL, + N_("Constrain to be parallel or tangent"), {} }, + { "perpendicular", Command::PERPENDICULAR, + N_("Constrain to be perpendicular"), {} }, + { "pointonx", Command::ON_ENTITY, + N_("Constrain point on line / curve / plane / point"), {} }, + { "symmetric", Command::SYMMETRIC, + N_("Constrain symmetric"), {} }, + { "equal", Command::EQUAL, + N_("Constrain equal length / radius / angle"), {} }, + { "same-orientation",Command::ORIENTED_SAME, + N_("Constrain normals in same orientation"), {} }, + { "other-supp", Command::OTHER_ANGLE, + N_("Other supplementary angle"), {} }, + { "ref", Command::REFERENCE, + N_("Toggle reference dimension"), {} }, + { "", Command::NONE, "", {} }, + + { "extrude", Command::GROUP_EXTRUDE, + N_("New group extruding active sketch"), {} }, + { "lathe", Command::GROUP_LATHE, + N_("New group rotating active sketch"), {} }, + { "helix", Command::GROUP_HELIX, + N_("New group helix from active sketch"), {} }, + { "revolve", Command::GROUP_REVOLVE, + N_("New group revolve active sketch"), {} }, + { "step-rotate", Command::GROUP_ROT, + N_("New group step and repeat rotating"), {} }, + { "step-translate", Command::GROUP_TRANS, + N_("New group step and repeat translating"), {} }, + { "sketch-in-plane", Command::GROUP_WRKPL, + N_("New group in new workplane (thru given entities)"), {} }, + { "sketch-in-3d", Command::GROUP_3D, + N_("New group in 3d"), {} }, + { "assemble", Command::GROUP_LINK, + N_("New group linking / assembling file"), {} }, + { "", Command::NONE, "", {} }, + + { "in3d", Command::NEAREST_ISO, + N_("Nearest isometric view"), {} }, + { "ontoworkplane", Command::ONTO_WORKPLANE, + N_("Align view to active workplane"), {} }, +}; + +void GraphicsWindow::ToolbarDraw(UiCanvas *canvas) { + ToolbarDrawOrHitTest(0, 0, canvas, NULL, NULL, NULL); +} + +bool GraphicsWindow::ToolbarMouseMoved(int x, int y) { + double width, height; + window->GetContentSize(&width, &height); + + x += ((int)width/2); + y += ((int)height/2); + + Command hitCommand; + int hitX, hitY; + bool withinToolbar = ToolbarDrawOrHitTest(x, y, NULL, &hitCommand, &hitX, &hitY); + + if(hitCommand != toolbarHovered) { + toolbarHovered = hitCommand; + Invalidate(); + } + + if(toolbarHovered != Command::NONE) { + std::string tooltip; + for(ToolIcon &icon : Toolbar) { + if(toolbarHovered == icon.command) { + tooltip = Translate(icon.tooltip); + } + } + + Platform::KeyboardEvent accel = SS.GW.AcceleratorForCommand(toolbarHovered); + std::string accelDesc = Platform::AcceleratorDescription(accel); + if(!accelDesc.empty()) { + tooltip += ssprintf(" (%s)", accelDesc.c_str()); + } + + window->SetTooltip(tooltip, hitX, hitY, 32, 32); + } else { + window->SetTooltip("", 0, 0, 0, 0); + } + + return withinToolbar; +} + +bool GraphicsWindow::ToolbarMouseDown(int x, int y) { + double width, height; + window->GetContentSize(&width, &height); + + x += ((int)width/2); + y += ((int)height/2); + + Command hitCommand; + bool withinToolbar = ToolbarDrawOrHitTest(x, y, NULL, &hitCommand, NULL, NULL); + if(hitCommand != Command::NONE) { + SS.GW.ActivateCommand(hitCommand); + } + return withinToolbar; +} + +bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my, UiCanvas *canvas, + Command *hitCommand, int *hitX, int *hitY) +{ + double width, height; + window->GetContentSize(&width, &height); + + int x = 17, y = (int)(height - 52); + + // When changing these values, also change the asReference drawing code in drawentity.cpp. + int fudge = 8; + int h = 32*18 + 3*16 + fudge; + int aleft = 0, aright = 66, atop = y+16+fudge/2, abot = y+16-h; + + bool withinToolbar = + (mx >= aleft && mx <= aright && my <= atop && my >= abot); + + // Initialize/clear hitCommand. + if(hitCommand) *hitCommand = Command::NONE; + + if(!canvas && !withinToolbar) { + // This gets called every MouseMove event, so return quickly. + return false; + } + + if(canvas) { + canvas->DrawRect(aleft, aright, atop, abot, + /*fillColor=*/{ 30, 30, 30, 255 }, + /*outlineColor=*/{}); + } + + bool leftpos = true; + for(ToolIcon &icon : Toolbar) { + if(icon.name.empty()) { // spacer + if(!leftpos) { + leftpos = true; + y -= 32; + x -= 32; + } + y -= 16; + + if(canvas) { + // Draw a separator bar in a slightly different color. + int divw = 30, divh = 2; + canvas->DrawRect(x+16+divw, x+16-divw, y+24+divh, y+24-divh, + /*fillColor=*/{ 45, 45, 45, 255 }, + /*outlineColor=*/{}); + } + + continue; + } + + if(icon.pixmap == nullptr) { + icon.pixmap = LoadPng("icons/graphics-window/" + icon.name + ".png"); + } + + if(canvas) { + canvas->DrawPixmap(icon.pixmap, + x - (int)icon.pixmap->width / 2, + y - (int)icon.pixmap->height / 2); + + if(toolbarHovered == icon.command || + (pending.operation == Pending::COMMAND && + pending.command == icon.command)) { + // Highlight the hovered or pending item. + const int boxhw = 15; + canvas->DrawRect(x+boxhw, x-boxhw, y+boxhw, y-boxhw, + /*fillColor=*/{ 255, 255, 0, 75 }, + /*outlineColor=*/{}); + } + } else { + const int boxhw = 16; + if(mx < (x+boxhw) && mx > (x - boxhw) && + my < (y+boxhw) && my > (y - boxhw)) + { + if(hitCommand) *hitCommand = icon.command; + if(hitX) *hitX = x - boxhw; + if(hitY) *hitY = (int)height - (y + boxhw); + } + } + + if(leftpos) { + x += 32; + leftpos = false; + } else { + x -= 32; + y -= 32; + leftpos = true; + } + } + + return withinToolbar; +} diff --git a/src/ttf.cpp b/src/ttf.cpp new file mode 100644 index 0000000..ddb2aa1 --- /dev/null +++ b/src/ttf.cpp @@ -0,0 +1,431 @@ +//----------------------------------------------------------------------------- +// Routines to read a TrueType font as vector outlines, and generate them +// as entities, since they're always representable as either lines or +// quadratic Bezier curves. +// +// Copyright 2016 whitequark, Peter Barfuss. +//----------------------------------------------------------------------------- +#include +#include FT_FREETYPE_H +#include FT_OUTLINE_H +#include FT_ADVANCES_H + +/* Yecch. Irritatingly, you need to do this nonsense to get the error string table, + since nobody thought to put this exact function into FreeType itsself. */ +#undef __FTERRORS_H__ +#define FT_ERRORDEF(e, v, s) { (e), (s) }, +#define FT_ERROR_START_LIST +#define FT_ERROR_END_LIST { 0, NULL } + +struct ft_error { + int err; + const char *str; +}; + +static const struct ft_error ft_errors[] = { +#include FT_ERRORS_H +}; + +extern "C" const char *ft_error_string(int err) { + const struct ft_error *e; + for(e = ft_errors; e->str; e++) + if(e->err == err) + return e->str; + return "Unknown error"; +} + +/* Okay, we're done with that. */ +#undef FT_ERRORDEF +#undef FT_ERROR_START_LIST +#undef FT_ERROR_END_LIST + +#include "solvespace.h" + +//----------------------------------------------------------------------------- +// Get the list of available font filenames, and load the name for each of +// them. Only that, though, not the glyphs too. +//----------------------------------------------------------------------------- +TtfFontList::TtfFontList() { + FT_Init_FreeType(&fontLibrary); +} + +TtfFontList::~TtfFontList() { + FT_Done_FreeType(fontLibrary); +} + +void TtfFontList::LoadAll() { + if(loaded) return; + + for(const Platform::Path &font : Platform::GetFontFiles()) { + TtfFont tf = {}; + tf.fontFile = font; + if(tf.LoadFromFile(fontLibrary)) + l.Add(&tf); + } + + // Add builtin font to end of font list so it is displayed first in the UI + { + TtfFont tf = {}; + tf.SetResourceID("fonts/BitstreamVeraSans-Roman-builtin.ttf"); + if(tf.LoadFromResource(fontLibrary)) + l.Add(&tf); + } + + // Sort fonts according to their actual name, not filename. + std::sort(l.begin(), l.end(), + [](const TtfFont &a, const TtfFont &b) { return a.name < b.name; }); + + // Filter out fonts with the same family and style name. This is not + // strictly necessarily the exact same font, but it will almost always be. + TtfFont *it = std::unique(l.begin(), l.end(), + [](const TtfFont &a, const TtfFont &b) { return a.name == b.name; }); + l.RemoveLast(&l[l.n] - it); + + //! @todo identify fonts by their name and not filename, which may change + //! between OSes. + + loaded = true; +} + +TtfFont *TtfFontList::LoadFont(const std::string &font) +{ + LoadAll(); + + TtfFont *tf = std::find_if(l.begin(), l.end(), + [&font](const TtfFont &tf) { return tf.FontFileBaseName() == font; }); + + if(tf != l.end()) { + if(tf->fontFace == NULL) { + if(tf->IsResource()) + tf->LoadFromResource(fontLibrary, /*keepOpen=*/true); + else + tf->LoadFromFile(fontLibrary, /*keepOpen=*/true); + } + return tf; + } else { + return NULL; + } +} + +void TtfFontList::PlotString(const std::string &font, const std::string &str, + SBezierList *sbl, Vector origin, Vector u, Vector v) +{ + TtfFont *tf = LoadFont(font); + if(!str.empty() && tf != NULL) { + tf->PlotString(str, sbl, origin, u, v); + } else { + // No text or no font; so draw a big X for an error marker. + SBezier sb; + sb = SBezier::From(origin, origin.Plus(u).Plus(v)); + sbl->l.Add(&sb); + sb = SBezier::From(origin.Plus(v), origin.Plus(u)); + sbl->l.Add(&sb); + } +} + +double TtfFontList::AspectRatio(const std::string &font, const std::string &str) +{ + TtfFont *tf = LoadFont(font); + if(tf != NULL) { + return tf->AspectRatio(str); + } + + return 0.0; +} + +//----------------------------------------------------------------------------- +// Return the basename of our font filename; that's how the requests and +// entities that reference us will store it. +//----------------------------------------------------------------------------- +std::string TtfFont::FontFileBaseName() const { + return fontFile.FileName(); +} + +//----------------------------------------------------------------------------- +// Convenience method to set fontFile for resource-loaded fonts as res:// +//----------------------------------------------------------------------------- +void TtfFont::SetResourceID(const std::string &resource) { + fontFile = { "res://" + resource }; +} + +bool TtfFont::IsResource() const { + return fontFile.raw.compare(0, 6, "res://") == 0; +} + +//----------------------------------------------------------------------------- +// Load a TrueType font into memory. +//----------------------------------------------------------------------------- +bool TtfFont::LoadFromFile(FT_Library fontLibrary, bool keepOpen) { + ssassert(!IsResource(), "Cannot load a font provided by a resource as a file."); + + FT_Open_Args args = {}; + args.flags = FT_OPEN_PATHNAME; + args.pathname = &fontFile.raw[0]; // FT_String is char* for historical reasons + + // We don't use OpenFile() here to let freetype do its own memory management. + // This is OK because on Linux/OS X we just delegate to fopen and on Windows + // we only look into C:\Windows\Fonts, which has a known short path. + if(int fterr = FT_Open_Face(fontLibrary, &args, 0, &fontFace)) { + dbp("freetype: loading font from file '%s' failed: %s", + fontFile.raw.c_str(), ft_error_string(fterr)); + return false; + } + + return ExtractTTFData(keepOpen); +} + +//----------------------------------------------------------------------------- +// Load a TrueType from resource in memory. Implemented to load bundled fonts +// through theresource system. +//----------------------------------------------------------------------------- +bool TtfFont::LoadFromResource(FT_Library fontLibrary, bool keepOpen) { + ssassert(IsResource(), "Font to be loaded as resource is not provided by a resource " + "or does not have the 'res://' prefix."); + + size_t _size; + // substr to cut off 'res://' (length: 6) + const void *_buffer = Platform::LoadResource(fontFile.raw.substr(6, fontFile.raw.size()), + &_size); + + FT_Long size = static_cast(_size); + const FT_Byte *buffer = reinterpret_cast(_buffer); + + if(int fterr = FT_New_Memory_Face(fontLibrary, buffer, size, 0, &fontFace)) { + dbp("freetype: loading font '%s' from memory failed: %s", + fontFile.raw.c_str(), ft_error_string(fterr)); + return false; + } + + return ExtractTTFData(keepOpen); +} + +//----------------------------------------------------------------------------- +// Extract font information. We care about the font name and unit size. +//----------------------------------------------------------------------------- +bool TtfFont::ExtractTTFData(bool keepOpen) { + if(int fterr = FT_Select_Charmap(fontFace, FT_ENCODING_UNICODE)) { + dbp("freetype: loading unicode CMap for file '%s' failed: %s", + fontFile.raw.c_str(), ft_error_string(fterr)); + FT_Done_Face(fontFace); + fontFace = NULL; + return false; + } + + name = std::string(fontFace->family_name) + + " (" + std::string(fontFace->style_name) + ")"; + + // We always ask Freetype to give us a unit size character. + // It uses fixed point; put the unit size somewhere in the middle of the dynamic + // range of its 26.6 fixed point type, and adjust the factors so that the unit + // matches cap height. + FT_Size_RequestRec sizeRequest; + sizeRequest.type = FT_SIZE_REQUEST_TYPE_REAL_DIM; + sizeRequest.width = 1 << 16; + sizeRequest.height = 1 << 16; + sizeRequest.horiResolution = 128; + sizeRequest.vertResolution = 128; + if(int fterr = FT_Request_Size(fontFace, &sizeRequest)) { + dbp("freetype: size request for file '%s' failed: %s", + fontFile.raw.c_str(), ft_error_string(fterr)); + FT_Done_Face(fontFace); + fontFace = NULL; + return false; + } + + char chr = 'A'; + uint32_t gid = FT_Get_Char_Index(fontFace, 'A'); + if (gid == 0) { + dbp("freetype: CID-to-GID mapping for CID 0x%04x in file '%s' failed: %s; " + "using CID as GID", + chr, fontFile.raw.c_str(), ft_error_string(gid)); + dbp("Assuming cap height is the same as requested height (this is likely wrong)."); + capHeight = (double)sizeRequest.height; + } + + if(gid) { + if(int fterr = FT_Load_Glyph(fontFace, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING)) { + dbp("freetype: cannot load glyph for GID 0x%04x in file '%s': %s", + gid, fontFile.raw.c_str(), ft_error_string(fterr)); + FT_Done_Face(fontFace); + fontFace = NULL; + return false; + } + + FT_BBox bbox; + FT_Outline_Get_CBox(&fontFace->glyph->outline, &bbox); + capHeight = (double)bbox.yMax; + } + + // If we just wanted to get the font's name and figure out if it's actually usable, close + // it now. If we don't do this, and there are a lot of fonts, we can bump into the file + // descriptor limit (especially on Windows), breaking all file operations. + if(!keepOpen) { + FT_Done_Face(fontFace); + fontFace = NULL; + return true; + } + + return true; +} + +typedef struct OutlineData { + Vector origin, u, v; // input parameters + SBezierList *beziers; // output bezier list + float factor; // ratio between freetype and solvespace coordinates + FT_Pos bx; // x offset of the current glyph + FT_Pos px, py; // current point +} OutlineData; + +static Vector Transform(OutlineData *data, FT_Pos x, FT_Pos y) { + Vector r = data->origin; + r = r.Plus(data->u.ScaledBy((float)(data->bx + x) * data->factor)); + r = r.Plus(data->v.ScaledBy((float)y * data->factor)); + return r; +} + +static int MoveTo(const FT_Vector *p, void *cc) +{ + OutlineData *data = (OutlineData *) cc; + data->px = p->x; + data->py = p->y; + return 0; +} + +static int LineTo(const FT_Vector *p, void *cc) +{ + OutlineData *data = (OutlineData *) cc; + SBezier sb = SBezier::From( + Transform(data, data->px, data->py), + Transform(data, p->x, p->y)); + data->beziers->l.Add(&sb); + data->px = p->x; + data->py = p->y; + return 0; +} + +static int ConicTo(const FT_Vector *c, const FT_Vector *p, void *cc) +{ + OutlineData *data = (OutlineData *) cc; + SBezier sb = SBezier::From( + Transform(data, data->px, data->py), + Transform(data, c->x, c->y), + Transform(data, p->x, p->y)); + data->beziers->l.Add(&sb); + data->px = p->x; + data->py = p->y; + return 0; +} + +static int CubicTo(const FT_Vector *c1, const FT_Vector *c2, const FT_Vector *p, void *cc) +{ + OutlineData *data = (OutlineData *) cc; + SBezier sb = SBezier::From( + Transform(data, data->px, data->py), + Transform(data, c1->x, c1->y), + Transform(data, c2->x, c2->y), + Transform(data, p->x, p->y)); + data->beziers->l.Add(&sb); + data->px = p->x; + data->py = p->y; + return 0; +} + +void TtfFont::PlotString(const std::string &str, + SBezierList *sbl, Vector origin, Vector u, Vector v) +{ + ssassert(fontFace != NULL, "Expected font face to be loaded"); + + FT_Outline_Funcs outlineFuncs; + outlineFuncs.move_to = MoveTo; + outlineFuncs.line_to = LineTo; + outlineFuncs.conic_to = ConicTo; + outlineFuncs.cubic_to = CubicTo; + outlineFuncs.shift = 0; + outlineFuncs.delta = 0; + + FT_Pos dx = 0; + for(char32_t cid : ReadUTF8(str)) { + uint32_t gid = FT_Get_Char_Index(fontFace, cid); + if (gid == 0) { + dbp("freetype: CID-to-GID mapping for CID 0x%04x in file '%s' failed: %s; " + "using CID as GID", + cid, fontFile.raw.c_str(), ft_error_string(gid)); + gid = cid; + } + + /* + * Stupid hacks: + * - if we want fake-bold, use FT_Outline_Embolden(). This actually looks + * quite good. + * - if we want fake-italic, apply a shear transform [1 s s 1 0 0] here using + * FT_Set_Transform. This looks decent at small font sizes and bad at larger + * ones, antialiasing mitigates this considerably though. + */ + if(int fterr = FT_Load_Glyph(fontFace, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING)) { + dbp("freetype: cannot load glyph for GID 0x%04x in file '%s': %s", + gid, fontFile.raw.c_str(), ft_error_string(fterr)); + return; + } + + /* A point that has x = xMin should be plotted at (dx0 + lsb); fix up + * our x-position so that the curve-generating code will put stuff + * at the right place. + * + * There's no point in getting the glyph BBox here - not only can it be + * needlessly slow sometimes, but because we're about to render a single glyph, + * what we want actually *is* the CBox. + * + * This is notwithstanding that this makes extremely little sense, this + * looks like a workaround for either mishandling the start glyph on a line, + * or as a really hacky pseudo-track-kerning (in which case it works better than + * one would expect! especially since most fonts don't set track kerning). + */ + FT_BBox cbox; + FT_Outline_Get_CBox(&fontFace->glyph->outline, &cbox); + FT_Pos bx = dx - cbox.xMin; + // Yes, this is what FreeType calls left-side bearing. + // Then interchangeably uses that with "left-side bearing". Sigh. + bx += fontFace->glyph->metrics.horiBearingX; + + OutlineData data = {}; + data.origin = origin; + data.u = u; + data.v = v; + data.beziers = sbl; + data.factor = (float)(1.0 / capHeight); + data.bx = bx; + if(int fterr = FT_Outline_Decompose(&fontFace->glyph->outline, &outlineFuncs, &data)) { + dbp("freetype: bezier decomposition failed for GID 0x%4x in file '%s': %s", + gid, fontFile.raw.c_str(), ft_error_string(fterr)); + } + + // And we're done, so advance our position by the requested advance + // width, plus the user-requested extra advance. + dx += fontFace->glyph->advance.x; + } +} + +double TtfFont::AspectRatio(const std::string &str) { + ssassert(fontFace != NULL, "Expected font face to be loaded"); + + // We always request a unit size character, so the aspect ratio is the same as advance length. + double dx = 0; + for(char32_t chr : ReadUTF8(str)) { + uint32_t gid = FT_Get_Char_Index(fontFace, chr); + if (gid == 0) { + dbp("freetype: CID-to-GID mapping for CID 0x%04x in file '%s' failed: %s; " + "using CID as GID", + chr, fontFile.raw.c_str(), ft_error_string(gid)); + } + + if(int fterr = FT_Load_Glyph(fontFace, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING)) { + dbp("freetype: cannot load glyph for GID 0x%04x in file '%s': %s", + gid, fontFile.raw.c_str(), ft_error_string(fterr)); + break; + } + + dx += (double)fontFace->glyph->advance.x / capHeight; + } + + return dx; +} diff --git a/src/ttf.h b/src/ttf.h new file mode 100644 index 0000000..565e6a9 --- /dev/null +++ b/src/ttf.h @@ -0,0 +1,50 @@ +//----------------------------------------------------------------------------- +// Routines to read a TrueType font as vector outlines, and generate them +// as entities, since they're always representable as either lines or +// quadratic Bezier curves. +// +// Copyright 2016 whitequark, Peter Barfuss. +//----------------------------------------------------------------------------- + +#ifndef SOLVESPACE_TTF_H +#define SOLVESPACE_TTF_H + +class TtfFont { +public: + Platform::Path fontFile; // or resource path/name as res:// + std::string name; + FT_FaceRec_ *fontFace; + double capHeight; + + void SetResourceID(const std::string &resource); + bool IsResource() const; + + std::string FontFileBaseName() const; + bool LoadFromFile(FT_LibraryRec_ *fontLibrary, bool keepOpen = false); + bool LoadFromResource(FT_LibraryRec_ *fontLibrary, bool keepOpen = false); + + void PlotString(const std::string &str, + SBezierList *sbl, Vector origin, Vector u, Vector v); + double AspectRatio(const std::string &str); + + bool ExtractTTFData(bool keepOpen); +}; + +class TtfFontList { +public: + FT_LibraryRec_ *fontLibrary; + bool loaded; + List l; + + TtfFontList(); + ~TtfFontList(); + + void LoadAll(); + TtfFont *LoadFont(const std::string &font); + + void PlotString(const std::string &font, const std::string &str, + SBezierList *sbl, Vector origin, Vector u, Vector v); + double AspectRatio(const std::string &font, const std::string &str); +}; + +#endif diff --git a/src/ui.h b/src/ui.h new file mode 100644 index 0000000..026d57d --- /dev/null +++ b/src/ui.h @@ -0,0 +1,842 @@ +//----------------------------------------------------------------------------- +// Declarations relating to our user interface, in both the graphics and +// text browser window. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- + +#ifndef SOLVESPACE_UI_H +#define SOLVESPACE_UI_H + +class Locale { +public: + std::string language; + std::string region; + uint16_t lcid; + std::string displayName; + + std::string Culture() const { + return language + "-" + region; + } +}; + +struct LocaleLess { + bool operator()(const Locale &a, const Locale &b) const { + return a.language < b.language || + (a.language == b.language && a.region < b.region); + } +}; + +const std::set &Locales(); +bool SetLocale(const std::string &name); +bool SetLocale(uint16_t lcid); + +const std::string &Translate(const char *msgid); +const std::string &Translate(const char *msgctxt, const char *msgid); +const std::string &TranslatePlural(const char *msgid, unsigned n); +const std::string &TranslatePlural(const char *msgctxt, const char *msgid, unsigned n); + +inline const char *N_(const char *msgid) { + return msgid; +} +inline const char *CN_(const char *msgctxt, const char *msgid) { + return msgid; +} +#if defined(LIBRARY) +inline const char *_(const char *msgid) { + return msgid; +} +inline const char *C_(const char *msgctxt, const char *msgid) { + return msgid; +} +#else +inline const char *_(const char *msgid) { + return Translate(msgid).c_str(); +} +inline const char *C_(const char *msgctxt, const char *msgid) { + return Translate(msgctxt, msgid).c_str(); +} +#endif + +// This table describes the top-level menus in the graphics window. +enum class Command : uint32_t { + NONE = 0, + // File + NEW = 100, + OPEN, + OPEN_RECENT, + SAVE, + SAVE_AS, + EXPORT_IMAGE, + EXPORT_MESH, + EXPORT_SURFACES, + EXPORT_VIEW, + EXPORT_SECTION, + EXPORT_WIREFRAME, + IMPORT, + EXIT, + // View + ZOOM_IN, + ZOOM_OUT, + ZOOM_TO_FIT, + SHOW_GRID, + DIM_SOLID_MODEL, + PERSPECTIVE_PROJ, + ONTO_WORKPLANE, + NEAREST_ORTHO, + NEAREST_ISO, + CENTER_VIEW, + SHOW_TOOLBAR, + SHOW_TEXT_WND, + UNITS_INCHES, + UNITS_MM, + UNITS_METERS, + FULL_SCREEN, + // Edit + UNDO, + REDO, + CUT, + COPY, + PASTE, + PASTE_TRANSFORM, + DELETE, + SELECT_CHAIN, + SELECT_ALL, + SNAP_TO_GRID, + ROTATE_90, + UNSELECT_ALL, + REGEN_ALL, + EDIT_LINE_STYLES, + VIEW_PROJECTION, + CONFIGURATION, + // Request + SEL_WORKPLANE, + FREE_IN_3D, + DATUM_POINT, + WORKPLANE, + LINE_SEGMENT, + CONSTR_SEGMENT, + CIRCLE, + ARC, + RECTANGLE, + CUBIC, + TTF_TEXT, + IMAGE, + SPLIT_CURVES, + TANGENT_ARC, + CONSTRUCTION, + // Group + GROUP_3D, + GROUP_WRKPL, + GROUP_EXTRUDE, + GROUP_HELIX, + GROUP_LATHE, + GROUP_REVOLVE, + GROUP_ROT, + GROUP_TRANS, + GROUP_LINK, + GROUP_RECENT, + // Constrain + DISTANCE_DIA, + REF_DISTANCE, + ANGLE, + REF_ANGLE, + OTHER_ANGLE, + REFERENCE, + EQUAL, + RATIO, + DIFFERENCE, + ON_ENTITY, + SYMMETRIC, + AT_MIDPOINT, + HORIZONTAL, + VERTICAL, + PARALLEL, + PERPENDICULAR, + ORIENTED_SAME, + WHERE_DRAGGED, + COMMENT, + // Analyze + VOLUME, + AREA, + PERIMETER, + INTERFERENCE, + NAKED_EDGES, + SHOW_DOF, + CENTER_OF_MASS, + TRACE_PT, + STOP_TRACING, + STEP_DIM, + // Help + LOCALE, + WEBSITE, + ABOUT, +}; + +class Button; + +class TextWindow { +public: + enum { + MAX_COLS = 100, + MIN_COLS = 45, + MAX_ROWS = 4000 + }; + + typedef struct { + char c; + RgbaColor color; + } Color; + static const Color fgColors[]; + static const Color bgColors[]; + + float bgColorTable[256*3]; + float fgColorTable[256*3]; + + enum { + CHAR_WIDTH_ = 9, + CHAR_HEIGHT = 16, + LINE_HEIGHT = 20, + LEFT_MARGIN = 6, + }; + +#define CHECK_FALSE "\xEE\x80\x80" // U+E000 +#define CHECK_TRUE "\xEE\x80\x81" +#define RADIO_FALSE "\xEE\x80\x82" +#define RADIO_TRUE "\xEE\x80\x83" + + int scrollPos; // The scrollbar position, in half-row units + int halfRows; // The height of our window, in half-row units + + uint32_t text[MAX_ROWS][MAX_COLS]; + typedef void LinkFunction(int link, uint32_t v); + enum { NOT_A_LINK = 0 }; + struct { + char fg; + char bg; + RgbaColor bgRgb; + int link; + uint32_t data; + LinkFunction *f; + LinkFunction *h; + } meta[MAX_ROWS][MAX_COLS]; + int hoveredRow, hoveredCol; + + int top[MAX_ROWS]; // in half-line units, or -1 for unused + int rows; + + Platform::WindowRef window; + std::shared_ptr canvas; + + void Draw(Canvas *canvas); + + void Paint(); + void MouseEvent(bool isClick, bool leftDown, double x, double y); + void MouseLeave(); + void ScrollbarEvent(double newPos); + + enum DrawOrHitHow : uint32_t { + PAINT = 0, + HOVER = 1, + CLICK = 2 + }; + void DrawOrHitTestIcons(UiCanvas *canvas, DrawOrHitHow how, + double mx, double my); + Button *hoveredButton; + + Vector HsvToRgb(Vector hsv); + std::shared_ptr HsvPattern2d(int w, int h); + std::shared_ptr HsvPattern1d(double hue, double sat, int w, int h); + void ColorPickerDone(); + bool DrawOrHitTestColorPicker(UiCanvas *canvas, DrawOrHitHow how, + bool leftDown, double x, double y); + + void Init(); + void MakeColorTable(const Color *in, float *out); + void Printf(bool half, const char *fmt, ...); + void ClearScreen(); + + void Show(); + void Resize(); + + // State for the screen that we are showing in the text window. + enum class Screen : uint32_t { + LIST_OF_GROUPS = 0, + GROUP_INFO = 1, + GROUP_SOLVE_INFO = 2, + CONFIGURATION = 3, + STEP_DIMENSION = 4, + LIST_OF_STYLES = 5, + STYLE_INFO = 6, + PASTE_TRANSFORMED = 7, + EDIT_VIEW = 8, + TANGENT_ARC = 9 + }; + typedef struct { + Screen screen; + + hGroup group; + hStyle style; + + hConstraint constraint; + + struct { + int times; + Vector trans; + double theta; + Vector origin; + double scale; + } paste; + } ShownState; + ShownState shown; + + enum class Edit : uint32_t { + NOTHING = 0, + // For multiple groups + TIMES_REPEATED = 1, + GROUP_NAME = 2, + GROUP_SCALE = 3, + GROUP_COLOR = 4, + GROUP_OPACITY = 5, + // For the configuration screen + LIGHT_DIRECTION = 100, + LIGHT_INTENSITY = 101, + COLOR = 102, + CHORD_TOLERANCE = 103, + MAX_SEGMENTS = 104, + CAMERA_TANGENT = 105, + GRID_SPACING = 106, + DIGITS_AFTER_DECIMAL = 107, + DIGITS_AFTER_DECIMAL_DEGREE = 108, + EXPORT_SCALE = 109, + EXPORT_OFFSET = 110, + CANVAS_SIZE = 111, + G_CODE_DEPTH = 112, + G_CODE_PASSES = 113, + G_CODE_FEED = 114, + G_CODE_PLUNGE_FEED = 115, + AUTOSAVE_INTERVAL = 116, + LIGHT_AMBIENT = 117, + FIND_CONSTRAINT_TIMEOUT = 118, + // For TTF text + TTF_TEXT = 300, + // For the step dimension screen + STEP_DIM_FINISH = 400, + STEP_DIM_STEPS = 401, + // For the styles stuff + STYLE_WIDTH = 500, + STYLE_TEXT_HEIGHT = 501, + STYLE_TEXT_ANGLE = 502, + STYLE_COLOR = 503, + STYLE_FILL_COLOR = 504, + STYLE_NAME = 505, + BACKGROUND_COLOR = 506, + STYLE_STIPPLE_PERIOD = 508, + // For paste transforming + PASTE_TIMES_REPEATED = 600, + PASTE_ANGLE = 601, + PASTE_SCALE = 602, + // For view + VIEW_SCALE = 700, + VIEW_ORIGIN = 701, + VIEW_PROJ_RIGHT = 702, + VIEW_PROJ_UP = 703, + // For tangent arc + TANGENT_ARC_RADIUS = 800 + }; + struct { + bool showAgain; + Edit meaning; + int i; + hGroup group; + hRequest request; + hStyle style; + } edit; + + static void ReportHowGroupSolved(hGroup hg); + + struct { + int halfRow; + int col; + + struct { + RgbaColor rgb; + double h, s, v; + bool show; + bool picker1dActive; + bool picker2dActive; + } colorPicker; + } editControl; + + void HideEditControl(); + void ShowEditControl(int col, const std::string &str, int halfRow = -1); + void ShowEditControlWithColorPicker(int col, RgbaColor rgb); + + void ClearSuper(); + + void ShowHeader(bool withNav); + // These are self-contained screens, that show some information about + // the sketch. + void ShowListOfGroups(); + void ShowGroupInfo(); + void ShowGroupSolveInfo(); + void ShowConfiguration(); + void ShowListOfStyles(); + void ShowStyleInfo(); + void ShowStepDimension(); + void ShowPasteTransformed(); + void ShowEditView(); + void ShowTangentArc(); + // Special screen, based on selection + void DescribeSelection(); + + void GoToScreen(Screen screen); + + // All of these are callbacks from the GUI code; first from when + // we're describing an entity + static void ScreenEditTtfText(int link, uint32_t v); + static void ScreenSetTtfFont(int link, uint32_t v); + static void ScreenUnselectAll(int link, uint32_t v); + + // when we're describing a constraint + static void ScreenConstraintToggleReference(int link, uint32_t v); + static void ScreenConstraintShowAsRadius(int link, uint32_t v); + + // and the rest from the stuff in textscreens.cpp + static void ScreenSelectGroup(int link, uint32_t v); + static void ScreenActivateGroup(int link, uint32_t v); + static void ScreenToggleGroupShown(int link, uint32_t v); + static void ScreenHowGroupSolved(int link, uint32_t v); + static void ScreenShowGroupsSpecial(int link, uint32_t v); + static void ScreenDeleteGroup(int link, uint32_t v); + + static void ScreenHoverGroupWorkplane(int link, uint32_t v); + static void ScreenHoverRequest(int link, uint32_t v); + static void ScreenHoverEntity(int link, uint32_t v); + static void ScreenHoverConstraint(int link, uint32_t v); + static void ScreenSelectRequest(int link, uint32_t v); + static void ScreenSelectEntity(int link, uint32_t v); + static void ScreenSelectConstraint(int link, uint32_t v); + + static void ScreenChangeGroupOption(int link, uint32_t v); + static void ScreenColor(int link, uint32_t v); + static void ScreenOpacity(int link, uint32_t v); + + static void ScreenShowListOfStyles(int link, uint32_t v); + static void ScreenShowStyleInfo(int link, uint32_t v); + static void ScreenDeleteStyle(int link, uint32_t v); + static void ScreenChangeStylePatternType(int link, uint32_t v); + static void ScreenChangeStyleYesNo(int link, uint32_t v); + static void ScreenCreateCustomStyle(int link, uint32_t v); + static void ScreenLoadFactoryDefaultStyles(int link, uint32_t v); + static void ScreenAssignSelectionToStyle(int link, uint32_t v); + + static void ScreenShowConfiguration(int link, uint32_t v); + static void ScreenShowEditView(int link, uint32_t v); + static void ScreenGoToWebsite(int link, uint32_t v); + + static void ScreenChangeFixExportColors(int link, uint32_t v); + static void ScreenChangeExportBackgroundColor(int link, uint32_t v); + static void ScreenChangeBackFaces(int link, uint32_t v); + static void ScreenChangeShowContourAreas(int link, uint32_t v); + static void ScreenChangeCheckClosedContour(int link, uint32_t v); + static void ScreenChangeTurntableNav(int link, uint32_t v); + static void ScreenChangeImmediatelyEditDimension(int link, uint32_t v); + static void ScreenChangeAutomaticLineConstraints(int link, uint32_t v); + static void ScreenChangePwlCurves(int link, uint32_t v); + static void ScreenChangeCanvasSizeAuto(int link, uint32_t v); + static void ScreenChangeCanvasSize(int link, uint32_t v); + static void ScreenChangeShadedTriangles(int link, uint32_t v); + + static void ScreenAllowRedundant(int link, uint32_t v); + + struct { + bool isDistance; + double finish; + int steps; + + Platform::TimerRef timer; + int64_t time; + int step; + } stepDim; + static void ScreenStepDimSteps(int link, uint32_t v); + static void ScreenStepDimFinish(int link, uint32_t v); + static void ScreenStepDimGo(int link, uint32_t v); + + static void ScreenChangeTangentArc(int link, uint32_t v); + + static void ScreenPasteTransformed(int link, uint32_t v); + + static void ScreenHome(int link, uint32_t v); + + // These ones do stuff with the edit control + static void ScreenChangeExprA(int link, uint32_t v); + static void ScreenChangeGroupName(int link, uint32_t v); + static void ScreenChangeGroupScale(int link, uint32_t v); + static void ScreenChangeLightDirection(int link, uint32_t v); + static void ScreenChangeLightIntensity(int link, uint32_t v); + static void ScreenChangeLightAmbient(int link, uint32_t v); + static void ScreenChangeColor(int link, uint32_t v); + static void ScreenChangeChordTolerance(int link, uint32_t v); + static void ScreenChangeMaxSegments(int link, uint32_t v); + static void ScreenChangeExportChordTolerance(int link, uint32_t v); + static void ScreenChangeExportMaxSegments(int link, uint32_t v); + static void ScreenChangeCameraTangent(int link, uint32_t v); + static void ScreenChangeGridSpacing(int link, uint32_t v); + static void ScreenChangeDigitsAfterDecimal(int link, uint32_t v); + static void ScreenChangeDigitsAfterDecimalDegree(int link, uint32_t v); + static void ScreenChangeUseSIPrefixes(int link, uint32_t v); + static void ScreenChangeExportScale(int link, uint32_t v); + static void ScreenChangeExportOffset(int link, uint32_t v); + static void ScreenChangeGCodeParameter(int link, uint32_t v); + static void ScreenChangeAutosaveInterval(int link, uint32_t v); + static void ScreenChangeFindConstraintTimeout(int link, uint32_t v); + static void ScreenChangeStyleName(int link, uint32_t v); + static void ScreenChangeStyleMetric(int link, uint32_t v); + static void ScreenChangeStyleTextAngle(int link, uint32_t v); + static void ScreenChangeStyleColor(int link, uint32_t v); + static void ScreenChangeBackgroundColor(int link, uint32_t v); + static void ScreenChangePasteTransformed(int link, uint32_t v); + static void ScreenChangeViewScale(int link, uint32_t v); + static void ScreenChangeViewToFullScale(int link, uint32_t v); + static void ScreenChangeViewOrigin(int link, uint32_t v); + static void ScreenChangeViewProjection(int link, uint32_t v); + + bool EditControlDoneForStyles(const std::string &s); + bool EditControlDoneForConfiguration(const std::string &s); + bool EditControlDoneForPaste(const std::string &s); + bool EditControlDoneForView(const std::string &s); + void EditControlDone(std::string s); +}; + +class GraphicsWindow { +public: + void Init(); + + Platform::WindowRef window; + + void PopulateMainMenu(); + void PopulateRecentFiles(); + + Platform::KeyboardEvent AcceleratorForCommand(Command id); + void ActivateCommand(Command id); + + static void MenuView(Command id); + static void MenuEdit(Command id); + static void MenuRequest(Command id); + void DeleteSelection(); + void CopySelection(); + void PasteClipboard(Vector trans, double theta, double scale); + static void MenuClipboard(Command id); + + Platform::MenuRef openRecentMenu; + Platform::MenuRef linkRecentMenu; + + Platform::MenuItemRef showGridMenuItem; + Platform::MenuItemRef dimSolidModelMenuItem; + Platform::MenuItemRef perspectiveProjMenuItem; + Platform::MenuItemRef showToolbarMenuItem; + Platform::MenuItemRef showTextWndMenuItem; + Platform::MenuItemRef fullScreenMenuItem; + + Platform::MenuItemRef unitsMmMenuItem; + Platform::MenuItemRef unitsMetersMenuItem; + Platform::MenuItemRef unitsInchesMenuItem; + + Platform::MenuItemRef inWorkplaneMenuItem; + Platform::MenuItemRef in3dMenuItem; + + Platform::MenuItemRef undoMenuItem; + Platform::MenuItemRef redoMenuItem; + + std::shared_ptr canvas; + std::shared_ptr persistentCanvas; + bool persistentDirty; + + // These parameters define the map from 2d screen coordinates to the + // coordinates of the 3d sketch points. We will use an axonometric + // projection. + Vector offset; + Vector projRight; + Vector projUp; + double scale; + struct { + bool mouseDown; + Vector offset; + Vector projRight; + Vector projUp; + Point2d mouse; + Point2d mouseOnButtonDown; + Vector marqueePoint; + bool startedMoving; + } orig; + // We need to detect when the projection is changed to invalidate + // caches for drawn items. + struct { + Vector offset; + Vector projRight; + Vector projUp; + double scale; + } cached; + + // Most recent mouse position, updated every time the mouse moves. + Point2d currentMousePosition; + + // When the user is dragging a point, don't solve multiple times without + // allowing a paint in between. The extra solves are wasted if they're + // not displayed. + bool havePainted; + + // Some state for the context menu. + struct { + bool active; + } context; + + Camera GetCamera() const; + Lighting GetLighting() const; + + void NormalizeProjectionVectors(); + Point2d ProjectPoint(Vector p); + Vector ProjectPoint3(Vector p); + Vector ProjectPoint4(Vector p, double *w); + Vector UnProjectPoint(Point2d p); + Vector UnProjectPoint3(Vector p); + + Platform::TimerRef animateTimer; + void AnimateOnto(Quaternion quatf, Vector offsetf); + void AnimateOntoWorkplane(); + + Vector VectorFromProjs(Vector rightUpForward); + void HandlePointForZoomToFit(Vector p, Point2d *pmax, Point2d *pmin, + double *wmin, bool usePerspective, + const Camera &camera); + void LoopOverPoints(const std::vector &entities, + const std::vector &constraints, + const std::vector &faces, + Point2d *pmax, Point2d *pmin, + double *wmin, bool usePerspective, bool includeMesh, + const Camera &camera); + void ZoomToFit(bool includingInvisibles = false, bool useSelection = false); + double ZoomToFit(const Camera &camera, + bool includingInvisibles = false, bool useSelection = false); + + hGroup activeGroup; + void EnsureValidActives(); + bool LockedInWorkplane(); + void SetWorkplaneFreeIn3d(); + hEntity ActiveWorkplane(); + void ForceTextWindowShown(); + + // Operations that must be completed by doing something with the mouse + // are noted here. + enum class Pending : uint32_t { + NONE = 0, + COMMAND = 1, + DRAGGING_POINTS = 2, + DRAGGING_NEW_POINT = 3, + DRAGGING_NEW_LINE_POINT = 4, + DRAGGING_NEW_CUBIC_POINT = 5, + DRAGGING_NEW_ARC_POINT = 6, + DRAGGING_CONSTRAINT = 7, + DRAGGING_RADIUS = 8, + DRAGGING_NORMAL = 9, + DRAGGING_NEW_RADIUS = 10, + DRAGGING_MARQUEE = 11, + }; + + struct { + Pending operation; + Command command; + + hRequest request; + hEntity point; + List points; + List requests; + hEntity circle; + hEntity normal; + hConstraint constraint; + + const char *description; + Platform::Path filename; + + bool hasSuggestion; + Constraint::Type suggestion; + } pending; + void ClearPending(bool scheduleShowTW = true); + bool IsFromPending(hRequest r); + void AddToPending(hRequest r); + void ReplacePending(hRequest before, hRequest after); + + // The constraint that is being edited with the on-screen textbox. + hConstraint constraintBeingEdited; + + bool SuggestLineConstraint(hRequest lineSegment, ConstraintBase::Type *type); + + Vector SnapToGrid(Vector p); + Vector SnapToEntityByScreenPoint(Point2d pp, hEntity he); + bool ConstrainPointByHovered(hEntity pt, const Point2d *projected = NULL); + void DeleteTaggedRequests(); + hRequest AddRequest(Request::Type type, bool rememberForUndo); + hRequest AddRequest(Request::Type type); + + class ParametricCurve { + public: + bool isLine; // else circle + Vector p0, p1; + Vector u, v; + double r, theta0, theta1, dtheta; + + void MakeFromEntity(hEntity he, bool reverse); + Vector PointAt(double t); + Vector TangentAt(double t); + double LengthForAuto(); + + void CreateRequestTrimmedTo(double t, bool reuseOrig, + hEntity orig, hEntity arc, bool arcFinish, bool pointf); + void ConstrainPointIfCoincident(hEntity hpt); + }; + void MakeTangentArc(); + void SplitLinesOrCurves(); + hEntity SplitEntity(hEntity he, Vector pinter); + hEntity SplitLine(hEntity he, Vector pinter); + hEntity SplitCircle(hEntity he, Vector pinter); + hEntity SplitCubic(hEntity he, Vector pinter); + void ReplacePointInConstraints(hEntity oldpt, hEntity newpt); + void RemoveConstraintsForPointBeingDeleted(hEntity hpt); + void FixConstraintsForRequestBeingDeleted(hRequest hr); + void FixConstraintsForPointBeingDeleted(hEntity hpt); + void EditConstraint(hConstraint constraint); + + // A selected entity. + class Selection { + public: + int tag; + + hEntity entity; + hConstraint constraint; + bool emphasized; + + void Draw(bool isHovered, Canvas *canvas); + + void Clear(); + bool IsEmpty(); + bool Equals(Selection *b); + bool HasEndpoints(); + }; + + // A hovered entity, with its location relative to the cursor. + class Hover { + public: + int zIndex; + double distance; + double depth; + Selection selection; + }; + + List hoverList; + Selection hover; + bool hoverWasSelectedOnMousedown; + List selection; + + Selection ChooseFromHoverToSelect(); + Selection ChooseFromHoverToDrag(); + void HitTestMakeSelection(Point2d mp); + void ClearSelection(); + void ClearNonexistentSelectionItems(); + /// This structure is filled by a call to GroupSelection(). + struct { + std::vector point; + std::vector entity; + std::vector anyNormal; + std::vector vector; + std::vector face; + std::vector constraint; + int points; + int entities; + int workplanes; + int faces; + int lineSegments; + int circlesOrArcs; + int arcs; + int cubics; + int periodicCubics; + int anyNormals; + int vectors; + int constraints; + int stylables; + int constraintLabels; + int withEndpoints; + int n; ///< Number of selected items + } gs; + void GroupSelection(); + bool IsSelected(Selection *s); + bool IsSelected(hEntity he); + void MakeSelected(hEntity he); + void MakeSelected(hConstraint hc); + void MakeSelected(Selection *s); + void MakeUnselected(hEntity he, bool coincidentPointTrick); + void MakeUnselected(Selection *s, bool coincidentPointTrick); + void SelectByMarquee(); + void ClearSuper(); + + // The toolbar, in toolbar.cpp + bool ToolbarDrawOrHitTest(int x, int y, UiCanvas *canvas, + Command *hitCommand, int *hitX, int *hitY); + void ToolbarDraw(UiCanvas *canvas); + bool ToolbarMouseMoved(int x, int y); + bool ToolbarMouseDown(int x, int y); + Command toolbarHovered; + + // This sets what gets displayed. + bool showWorkplanes; + bool showNormals; + bool showPoints; + bool showConstruction; + bool showConstraints; + bool showTextWindow; + bool showShaded; + bool showEdges; + bool showOutlines; + bool showFaces; + bool showMesh; + void ToggleBool(bool *v); + + enum class DrawOccludedAs { INVISIBLE, STIPPLED, VISIBLE }; + DrawOccludedAs drawOccludedAs; + + bool showSnapGrid; + bool dimSolidModel; + void DrawSnapGrid(Canvas *canvas); + + void AddPointToDraggedList(hEntity hp); + void StartDraggingByEntity(hEntity he); + void StartDraggingBySelection(); + void UpdateDraggedNum(Vector *pos, double mx, double my); + void UpdateDraggedPoint(hEntity hp, double mx, double my); + + void Invalidate(bool clearPersistent = false); + void DrawEntities(Canvas *canvas, bool persistent); + void DrawPersistent(Canvas *canvas); + void Draw(Canvas *canvas); + void Paint(); + + bool MouseEvent(Platform::MouseEvent event); + void MouseMoved(double x, double y, bool leftDown, bool middleDown, + bool rightDown, bool shiftDown, bool ctrlDown); + void MouseLeftDown(double x, double y, bool shiftDown, bool ctrlDown); + void MouseLeftUp(double x, double y, bool shiftDown, bool ctrlDown); + void MouseLeftDoubleClick(double x, double y); + void MouseMiddleOrRightDown(double x, double y); + void MouseRightUp(double x, double y); + void MouseScroll(double x, double y, double delta); + void MouseLeave(); + bool KeyboardEvent(Platform::KeyboardEvent event); + void EditControlDone(const std::string &s); + + int64_t last6DofTime; + hGroup last6DofGroup; + void SixDofEvent(Platform::SixDofEvent event); +}; + + +#endif diff --git a/src/undoredo.cpp b/src/undoredo.cpp new file mode 100644 index 0000000..8ea8a06 --- /dev/null +++ b/src/undoredo.cpp @@ -0,0 +1,154 @@ +//----------------------------------------------------------------------------- +// The user-visible undo/redo operation; whenever they change something, we +// record our state and push it on a stack, and we pop the stack when they +// select undo. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +void SolveSpaceUI::UndoRemember() { + unsaved = true; + PushFromCurrentOnto(&undo); + UndoClearStack(&redo); + UndoEnableMenus(); +} + +void SolveSpaceUI::UndoUndo() { + if(undo.cnt <= 0) return; + + PushFromCurrentOnto(&redo); + PopOntoCurrentFrom(&undo); + UndoEnableMenus(); +} + +void SolveSpaceUI::UndoRedo() { + if(redo.cnt <= 0) return; + + PushFromCurrentOnto(&undo); + PopOntoCurrentFrom(&redo); + UndoEnableMenus(); +} + +void SolveSpaceUI::UndoEnableMenus() { + SS.GW.undoMenuItem->SetEnabled(undo.cnt > 0); + SS.GW.redoMenuItem->SetEnabled(redo.cnt > 0); +} + +void SolveSpaceUI::PushFromCurrentOnto(UndoStack *uk) { + if(uk->cnt == MAX_UNDO) { + UndoClearState(&(uk->d[uk->write])); + // And then write in to this one again + } else { + (uk->cnt)++; + } + + UndoState *ut = &(uk->d[uk->write]); + *ut = {}; + ut->group.ReserveMore(SK.group.n); + for(Group &src : SK.group) { + // Shallow copy + Group dest(src); + // And then clean up all the stuff that needs to be a deep copy, + // and zero out all the dynamic stuff that will get regenerated. + dest.clean = false; + dest.solved = {}; + dest.polyLoops = {}; + dest.bezierLoops = {}; + dest.bezierOpens = {}; + dest.polyError = {}; + dest.thisMesh = {}; + dest.runningMesh = {}; + dest.thisShell = {}; + dest.runningShell = {}; + dest.displayMesh = {}; + dest.displayOutlines = {}; + + dest.remap = src.remap; + + dest.impMesh = {}; + dest.impShell = {}; + dest.impEntity = {}; + ut->group.Add(&dest); + } + for(auto &src : SK.groupOrder) { ut->groupOrder.Add(&src); } + ut->request.ReserveMore(SK.request.n); + for(auto &src : SK.request) { ut->request.Add(&src); } + ut->constraint.ReserveMore(SK.constraint.n); + for(auto &src : SK.constraint) { + // Shallow copy + Constraint dest(src); + ut->constraint.Add(&dest); + } + ut->param.ReserveMore(SK.param.n); + for(auto &src : SK.param) { ut->param.Add(&src); } + ut->style.ReserveMore(SK.style.n); + for(auto &src : SK.style) { ut->style.Add(&src); } + ut->activeGroup = SS.GW.activeGroup; + + uk->write = WRAP(uk->write + 1, MAX_UNDO); +} + +void SolveSpaceUI::PopOntoCurrentFrom(UndoStack *uk) { + ssassert(uk->cnt > 0, "Cannot pop from empty undo stack"); + (uk->cnt)--; + uk->write = WRAP(uk->write - 1, MAX_UNDO); + + UndoState *ut = &(uk->d[uk->write]); + + // Free everything in the main copy of the program before replacing it + for(hGroup hg : SK.groupOrder) { + Group *g = SK.GetGroup(hg); + g->Clear(); + } + SK.group.Clear(); + SK.groupOrder.Clear(); + SK.request.Clear(); + SK.constraint.Clear(); + SK.param.Clear(); + SK.style.Clear(); + + // And then do a shallow copy of the state from the undo list + ut->group.MoveSelfInto(&(SK.group)); + for(auto &gh : ut->groupOrder) { SK.groupOrder.Add(&gh); } + ut->request.MoveSelfInto(&(SK.request)); + ut->constraint.MoveSelfInto(&(SK.constraint)); + ut->param.MoveSelfInto(&(SK.param)); + ut->style.MoveSelfInto(&(SK.style)); + SS.GW.activeGroup = ut->activeGroup; + + // No need to free it, since a shallow copy was made above + *ut = {}; + + // And reset the state everywhere else in the program, since the + // sketch just changed a lot. + SS.GW.ClearSuper(); + SS.TW.ClearSuper(); + SS.ReloadAllLinked(SS.saveFile); + SS.GenerateAll(SolveSpaceUI::Generate::ALL); + SS.ScheduleShowTW(); + + // Activate the group that was active before. + Group *activeGroup = SK.GetGroup(SS.GW.activeGroup); + activeGroup->Activate(); +} + +void SolveSpaceUI::UndoClearStack(UndoStack *uk) { + while(uk->cnt > 0) { + uk->write = WRAP(uk->write - 1, MAX_UNDO); + (uk->cnt)--; + UndoClearState(&(uk->d[uk->write])); + } + *uk = {}; // for good measure +} + +void SolveSpaceUI::UndoClearState(UndoState *ut) { + for(auto &g : ut->group) { g.remap.clear(); } + ut->group.Clear(); + ut->request.Clear(); + ut->constraint.Clear(); + ut->param.Clear(); + ut->style.Clear(); + *ut = {}; +} + diff --git a/src/util.cpp b/src/util.cpp new file mode 100644 index 0000000..f14417c --- /dev/null +++ b/src/util.cpp @@ -0,0 +1,1072 @@ +//----------------------------------------------------------------------------- +// Utility functions, mostly various kinds of vector math (working on real +// numbers, not working on quantities in the symbolic algebra system). +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +void SolveSpace::AssertFailure(const char *file, unsigned line, const char *function, + const char *condition, const char *message) { + std::string formattedMsg; + formattedMsg += ssprintf("File %s, line %u, function %s:\n", file, line, function); + formattedMsg += ssprintf("Assertion failed: %s.\n", condition); + formattedMsg += ssprintf("Message: %s.\n", message); + SolveSpace::Platform::FatalError(formattedMsg); +} + +std::string SolveSpace::ssprintf(const char *fmt, ...) +{ + va_list va; + + va_start(va, fmt); + int size = vsnprintf(NULL, 0, fmt, va); + ssassert(size >= 0, "vsnprintf could not encode string"); + va_end(va); + + std::string result; + result.resize(size + 1); + + va_start(va, fmt); + vsnprintf(&result[0], size + 1, fmt, va); + va_end(va); + + result.resize(size); + return result; +} + +char32_t utf8_iterator::operator*() +{ + const uint8_t *it = (const uint8_t*) this->p; + char32_t result = *it; + + if((result & 0x80) != 0) { + unsigned int mask = 0x40; + + do { + result <<= 6; + unsigned int c = (*++it); + mask <<= 5; + result += c - 0x80; + } while((result & mask) != 0); + + result &= mask - 1; + } + + this->n = (const char*) (it + 1); + return result; +} + +int64_t SolveSpace::GetMilliseconds() +{ + auto timestamp = std::chrono::steady_clock::now().time_since_epoch(); + return std::chrono::duration_cast(timestamp).count(); +} + +void SolveSpace::MakeMatrix(double *mat, + double a11, double a12, double a13, double a14, + double a21, double a22, double a23, double a24, + double a31, double a32, double a33, double a34, + double a41, double a42, double a43, double a44) +{ + mat[ 0] = a11; + mat[ 1] = a21; + mat[ 2] = a31; + mat[ 3] = a41; + mat[ 4] = a12; + mat[ 5] = a22; + mat[ 6] = a32; + mat[ 7] = a42; + mat[ 8] = a13; + mat[ 9] = a23; + mat[10] = a33; + mat[11] = a43; + mat[12] = a14; + mat[13] = a24; + mat[14] = a34; + mat[15] = a44; +} + +void SolveSpace::MultMatrix(double *mata, double *matb, double *matr) { + for(int i = 0; i < 4; i++) { + for(int j = 0; j < 4; j++) { + double s = 0.0; + for(int k = 0; k < 4; k++) { + s += mata[k * 4 + j] * matb[i * 4 + k]; + } + matr[i * 4 + j] = s; + } + } +} + +//----------------------------------------------------------------------------- +// Format the string for our message box appropriately, and then display +// that string. +//----------------------------------------------------------------------------- +static void MessageBox(const char *fmt, va_list va, bool error, + std::function onDismiss = std::function()) +{ +#ifndef LIBRARY + va_list va_size; + va_copy(va_size, va); + int size = vsnprintf(NULL, 0, fmt, va_size); + ssassert(size >= 0, "vsnprintf could not encode string"); + va_end(va_size); + + std::string text; + text.resize(size); + + vsnprintf(&text[0], size + 1, fmt, va); + + // Split message text using a heuristic for better presentation. + size_t separatorAt = 0; + while(separatorAt != std::string::npos) { + size_t dotAt = text.find('.', separatorAt + 1), + colonAt = text.find(':', separatorAt + 1); + separatorAt = min(dotAt, colonAt); + if(separatorAt == std::string::npos || + (separatorAt + 1 < text.size() && isspace(text[separatorAt + 1]))) { + break; + } + } + std::string message = text; + std::string description; + if(separatorAt != std::string::npos) { + message = text.substr(0, separatorAt + 1); + if(separatorAt + 1 < text.size()) { + description = text.substr(separatorAt + 1); + } + } + + if(description.length() > 0) { + std::string::iterator it = description.begin(); + while(isspace(*it)) it++; + description = description.substr(it - description.begin()); + } + + Platform::MessageDialogRef dialog = CreateMessageDialog(SS.GW.window); + if (!dialog) { + if (error) { + fprintf(stderr, "Error: %s\n", message.c_str()); + } else { + fprintf(stderr, "Message: %s\n", message.c_str()); + } + if(onDismiss) { + onDismiss(); + } + return; + } + using Platform::MessageDialog; + if(error) { + dialog->SetType(MessageDialog::Type::ERROR); + } else { + dialog->SetType(MessageDialog::Type::INFORMATION); + } + dialog->SetTitle(error ? C_("title", "Error") : C_("title", "Message")); + dialog->SetMessage(message); + if(!description.empty()) { + dialog->SetDescription(description); + } + dialog->AddButton(C_("button", "&OK"), MessageDialog::Response::OK, + /*isDefault=*/true); + + dialog->onResponse = [=](MessageDialog::Response _response) { + if(onDismiss) { + onDismiss(); + } + }; + dialog->ShowModal(); +#endif +} +void SolveSpace::Error(const char *fmt, ...) +{ + va_list f; + va_start(f, fmt); + MessageBox(fmt, f, /*error=*/true); + va_end(f); +} +void SolveSpace::Message(const char *fmt, ...) +{ + va_list f; + va_start(f, fmt); + MessageBox(fmt, f, /*error=*/false); + va_end(f); +} +void SolveSpace::MessageAndRun(std::function onDismiss, const char *fmt, ...) +{ + va_list f; + va_start(f, fmt); + MessageBox(fmt, f, /*error=*/false, onDismiss); + va_end(f); +} + +//----------------------------------------------------------------------------- +// Solve a mostly banded matrix. In a given row, there are LEFT_OF_DIAG +// elements to the left of the diagonal element, and RIGHT_OF_DIAG elements to +// the right (so that the total band width is LEFT_OF_DIAG + RIGHT_OF_DIAG + 1). +// There also may be elements in the last two columns of any row. We solve +// without pivoting. +//----------------------------------------------------------------------------- +void BandedMatrix::Solve() { + int i, ip, j, jp; + double temp; + + // Reduce the matrix to upper triangular form. + for(i = 0; i < n; i++) { + for(ip = i+1; ip < n && ip <= (i + LEFT_OF_DIAG); ip++) { + temp = A[ip][i]/A[i][i]; + + for(jp = i; jp < (n - 2) && jp <= (i + RIGHT_OF_DIAG); jp++) { + A[ip][jp] -= temp*(A[i][jp]); + } + A[ip][n-2] -= temp*(A[i][n-2]); + A[ip][n-1] -= temp*(A[i][n-1]); + + B[ip] -= temp*B[i]; + } + } + + // And back-substitute. + for(i = n - 1; i >= 0; i--) { + temp = B[i]; + + if(i < n-1) temp -= X[n-1]*A[i][n-1]; + if(i < n-2) temp -= X[n-2]*A[i][n-2]; + + for(j = min(n - 3, i + RIGHT_OF_DIAG); j > i; j--) { + temp -= X[j]*A[i][j]; + } + X[i] = temp / A[i][i]; + } +} + +const Quaternion Quaternion::IDENTITY = { 1, 0, 0, 0 }; + +Quaternion Quaternion::From(double w, double vx, double vy, double vz) { + Quaternion q; + q.w = w; + q.vx = vx; + q.vy = vy; + q.vz = vz; + return q; +} + +Quaternion Quaternion::From(hParam w, hParam vx, hParam vy, hParam vz) { + Quaternion q; + q.w = SK.GetParam(w )->val; + q.vx = SK.GetParam(vx)->val; + q.vy = SK.GetParam(vy)->val; + q.vz = SK.GetParam(vz)->val; + return q; +} + +Quaternion Quaternion::From(Vector axis, double dtheta) { + Quaternion q; + double c = cos(dtheta / 2), s = sin(dtheta / 2); + axis = axis.WithMagnitude(s); + q.w = c; + q.vx = axis.x; + q.vy = axis.y; + q.vz = axis.z; + return q; +} + +Quaternion Quaternion::From(Vector u, Vector v) +{ + Vector n = u.Cross(v); + + Quaternion q; + double s, tr = 1 + u.x + v.y + n.z; + if(tr > 1e-4) { + s = 2*sqrt(tr); + q.w = s/4; + q.vx = (v.z - n.y)/s; + q.vy = (n.x - u.z)/s; + q.vz = (u.y - v.x)/s; + } else { + if(u.x > v.y && u.x > n.z) { + s = 2*sqrt(1 + u.x - v.y - n.z); + q.w = (v.z - n.y)/s; + q.vx = s/4; + q.vy = (u.y + v.x)/s; + q.vz = (n.x + u.z)/s; + } else if(v.y > n.z) { + s = 2*sqrt(1 - u.x + v.y - n.z); + q.w = (n.x - u.z)/s; + q.vx = (u.y + v.x)/s; + q.vy = s/4; + q.vz = (v.z + n.y)/s; + } else { + s = 2*sqrt(1 - u.x - v.y + n.z); + q.w = (u.y - v.x)/s; + q.vx = (n.x + u.z)/s; + q.vy = (v.z + n.y)/s; + q.vz = s/4; + } + } + + return q.WithMagnitude(1); +} + +Quaternion Quaternion::Plus(Quaternion b) const { + Quaternion q; + q.w = w + b.w; + q.vx = vx + b.vx; + q.vy = vy + b.vy; + q.vz = vz + b.vz; + return q; +} + +Quaternion Quaternion::Minus(Quaternion b) const { + Quaternion q; + q.w = w - b.w; + q.vx = vx - b.vx; + q.vy = vy - b.vy; + q.vz = vz - b.vz; + return q; +} + +Quaternion Quaternion::ScaledBy(double s) const { + Quaternion q; + q.w = w*s; + q.vx = vx*s; + q.vy = vy*s; + q.vz = vz*s; + return q; +} + +double Quaternion::Magnitude() const { + return sqrt(w*w + vx*vx + vy*vy + vz*vz); +} + +Quaternion Quaternion::WithMagnitude(double s) const { + return ScaledBy(s/Magnitude()); +} + +Vector Quaternion::RotationU() const { + Vector v; + v.x = w*w + vx*vx - vy*vy - vz*vz; + v.y = 2*w *vz + 2*vx*vy; + v.z = 2*vx*vz - 2*w *vy; + return v; +} + +Vector Quaternion::RotationV() const { + Vector v; + v.x = 2*vx*vy - 2*w*vz; + v.y = w*w - vx*vx + vy*vy - vz*vz; + v.z = 2*w*vx + 2*vy*vz; + return v; +} + +Vector Quaternion::RotationN() const { + Vector v; + v.x = 2*w*vy + 2*vx*vz; + v.y = 2*vy*vz - 2*w*vx; + v.z = w*w - vx*vx - vy*vy + vz*vz; + return v; +} + +Vector Quaternion::Rotate(Vector p) const { + // Express the point in the new basis + return (RotationU().ScaledBy(p.x)).Plus( + RotationV().ScaledBy(p.y)).Plus( + RotationN().ScaledBy(p.z)); +} + +Quaternion Quaternion::Inverse() const { + Quaternion r; + r.w = w; + r.vx = -vx; + r.vy = -vy; + r.vz = -vz; + return r.WithMagnitude(1); // not that the normalize should be reqd +} + +Quaternion Quaternion::ToThe(double p) const { + // Avoid division by zero, or arccos of something not in its domain + if(w >= (1 - 1e-6)) { + return From(1, 0, 0, 0); + } else if(w <= (-1 + 1e-6)) { + return From(-1, 0, 0, 0); + } + + Quaternion r; + Vector axis = Vector::From(vx, vy, vz); + double theta = acos(w); // okay, since magnitude is 1, so -1 <= w <= 1 + theta *= p; + r.w = cos(theta); + axis = axis.WithMagnitude(sin(theta)); + r.vx = axis.x; + r.vy = axis.y; + r.vz = axis.z; + return r; +} + +Quaternion Quaternion::Times(Quaternion b) const { + double sa = w, sb = b.w; + Vector va = { vx, vy, vz }; + Vector vb = { b.vx, b.vy, b.vz }; + + Quaternion r; + r.w = sa*sb - va.Dot(vb); + Vector vr = vb.ScaledBy(sa).Plus( + va.ScaledBy(sb).Plus( + va.Cross(vb))); + r.vx = vr.x; + r.vy = vr.y; + r.vz = vr.z; + return r; +} + +Quaternion Quaternion::Mirror() const { + Vector u = RotationU(), + v = RotationV(); + u = u.ScaledBy(-1); + v = v.ScaledBy(-1); + return Quaternion::From(u, v); +} + + +Vector Vector::From(hParam x, hParam y, hParam z) { + Vector v; + v.x = SK.GetParam(x)->val; + v.y = SK.GetParam(y)->val; + v.z = SK.GetParam(z)->val; + return v; +} + +bool Vector::EqualsExactly(Vector v) const { + return EXACT(x == v.x && + y == v.y && + z == v.z); +} + +double Vector::DirectionCosineWith(Vector b) const { + Vector a = this->WithMagnitude(1); + b = b.WithMagnitude(1); + return a.Dot(b); +} + +Vector Vector::Normal(int which) const { + Vector n; + + // Arbitrarily choose one vector that's normal to us, pivoting + // appropriately. + double xa = fabs(x), ya = fabs(y), za = fabs(z); + if(this->Equals(Vector::From(0, 0, 1))) { + // Make DXFs exported in the XY plane work nicely... + n = Vector::From(1, 0, 0); + } else if(xa < ya && xa < za) { + n.x = 0; + n.y = z; + n.z = -y; + } else if(ya < za) { + n.x = -z; + n.y = 0; + n.z = x; + } else { + n.x = y; + n.y = -x; + n.z = 0; + } + + if(which == 0) { + // That's the vector we return. + } else if(which == 1) { + n = this->Cross(n); + } else ssassert(false, "Unexpected vector normal index"); + + n = n.WithMagnitude(1); + + return n; +} + +Vector Vector::RotatedAbout(Vector orig, Vector axis, double theta) const { + Vector r = this->Minus(orig); + r = r.RotatedAbout(axis, theta); + return r.Plus(orig); +} + +Vector Vector::RotatedAbout(Vector axis, double theta) const { + double c = cos(theta); + double s = sin(theta); + + axis = axis.WithMagnitude(1); + + Vector r; + + r.x = (x)*(c + (1 - c)*(axis.x)*(axis.x)) + + (y)*((1 - c)*(axis.x)*(axis.y) - s*(axis.z)) + + (z)*((1 - c)*(axis.x)*(axis.z) + s*(axis.y)); + + r.y = (x)*((1 - c)*(axis.y)*(axis.x) + s*(axis.z)) + + (y)*(c + (1 - c)*(axis.y)*(axis.y)) + + (z)*((1 - c)*(axis.y)*(axis.z) - s*(axis.x)); + + r.z = (x)*((1 - c)*(axis.z)*(axis.x) - s*(axis.y)) + + (y)*((1 - c)*(axis.z)*(axis.y) + s*(axis.x)) + + (z)*(c + (1 - c)*(axis.z)*(axis.z)); + + return r; +} + +Vector Vector::DotInToCsys(Vector u, Vector v, Vector n) const { + Vector r = { + this->Dot(u), + this->Dot(v), + this->Dot(n) + }; + return r; +} + +Vector Vector::ScaleOutOfCsys(Vector u, Vector v, Vector n) const { + Vector r = u.ScaledBy(x).Plus( + v.ScaledBy(y).Plus( + n.ScaledBy(z))); + return r; +} + +Vector Vector::InPerspective(Vector u, Vector v, Vector n, + Vector origin, double cameraTan) const +{ + Vector r = this->Minus(origin); + r = r.DotInToCsys(u, v, n); + // yes, minus; we are assuming a csys where u cross v equals n, backwards + // from the display stuff + double w = (1 - r.z*cameraTan); + r = r.ScaledBy(1/w); + + return r; +} + +double Vector::DistanceToLine(Vector p0, Vector dp) const { + double m = dp.Magnitude(); + return ((this->Minus(p0)).Cross(dp)).Magnitude() / m; +} + +double Vector::DistanceToPlane(Vector normal, Vector origin) const { + return this->Dot(normal) - origin.Dot(normal); +} + +bool Vector::OnLineSegment(Vector a, Vector b, double tol) const { + if(this->Equals(a, tol) || this->Equals(b, tol)) return true; + + Vector d = b.Minus(a); + + double m = d.MagSquared(); + double distsq = ((this->Minus(a)).Cross(d)).MagSquared() / m; + + if(distsq >= tol*tol) return false; + + double t = (this->Minus(a)).DivProjected(d); + // On-endpoint already tested + if(t < 0 || t > 1) return false; + return true; +} + +Vector Vector::ClosestPointOnLine(Vector p0, Vector dp) const { + dp = dp.WithMagnitude(1); + // this, p0, and (p0+dp) define a plane; the min distance is in + // that plane, so calculate its normal + Vector pn = (this->Minus(p0)).Cross(dp); + // The minimum distance line is in that plane, perpendicular + // to the line + Vector n = pn.Cross(dp); + + // Calculate the actual distance + double d = (dp.Cross(p0.Minus(*this))).Magnitude(); + return this->Plus(n.WithMagnitude(d)); +} + +Vector Vector::WithMagnitude(double v) const { + double m = Magnitude(); + if(EXACT(m == 0)) { + // We can do a zero vector with zero magnitude, but not any other cases. + if(fabs(v) > 1e-100) { + dbp("Vector::WithMagnitude(%g) of zero vector!", v); + } + return From(0, 0, 0); + } else { + return ScaledBy(v/m); + } +} + +Vector Vector::ProjectVectorInto(hEntity wrkpl) const { + EntityBase *w = SK.GetEntity(wrkpl); + Vector u = w->Normal()->NormalU(); + Vector v = w->Normal()->NormalV(); + + double up = this->Dot(u); + double vp = this->Dot(v); + + return (u.ScaledBy(up)).Plus(v.ScaledBy(vp)); +} + +Vector Vector::ProjectInto(hEntity wrkpl) const { + EntityBase *w = SK.GetEntity(wrkpl); + Vector p0 = w->WorkplaneGetOffset(); + + Vector f = this->Minus(p0); + + return p0.Plus(f.ProjectVectorInto(wrkpl)); +} + +Point2d Vector::Project2d(Vector u, Vector v) const { + Point2d p; + p.x = this->Dot(u); + p.y = this->Dot(v); + return p; +} + +Point2d Vector::ProjectXy() const { + Point2d p; + p.x = x; + p.y = y; + return p; +} + +Vector4 Vector::Project4d() const { + return Vector4::From(1, x, y, z); +} + +double Vector::DivProjected(Vector delta) const { + return (x*delta.x + y*delta.y + z*delta.z) + / (delta.x*delta.x + delta.y*delta.y + delta.z*delta.z); +} + +Vector Vector::ClosestOrtho() const { + double mx = fabs(x), my = fabs(y), mz = fabs(z); + + if(mx > my && mx > mz) { + return From((x > 0) ? 1 : -1, 0, 0); + } else if(my > mz) { + return From(0, (y > 0) ? 1 : -1, 0); + } else { + return From(0, 0, (z > 0) ? 1 : -1); + } +} + +Vector Vector::ClampWithin(double minv, double maxv) const { + Vector ret = *this; + + if(ret.x < minv) ret.x = minv; + if(ret.y < minv) ret.y = minv; + if(ret.z < minv) ret.z = minv; + + if(ret.x > maxv) ret.x = maxv; + if(ret.y > maxv) ret.y = maxv; + if(ret.z > maxv) ret.z = maxv; + + return ret; +} + +bool Vector::OutsideAndNotOn(Vector maxv, Vector minv) const { + return (x > maxv.x + LENGTH_EPS) || (x < minv.x - LENGTH_EPS) || + (y > maxv.y + LENGTH_EPS) || (y < minv.y - LENGTH_EPS) || + (z > maxv.z + LENGTH_EPS) || (z < minv.z - LENGTH_EPS); +} + +bool Vector::BoundingBoxesDisjoint(Vector amax, Vector amin, + Vector bmax, Vector bmin) +{ + int i; + for(i = 0; i < 3; i++) { + if(amax.Element(i) < bmin.Element(i) - LENGTH_EPS) return true; + if(amin.Element(i) > bmax.Element(i) + LENGTH_EPS) return true; + } + return false; +} + +bool Vector::BoundingBoxIntersectsLine(Vector amax, Vector amin, + Vector p0, Vector p1, bool asSegment) +{ + Vector dp = p1.Minus(p0); + double lp = dp.Magnitude(); + dp = dp.ScaledBy(1.0/lp); + + int i, a; + for(i = 0; i < 3; i++) { + int j = WRAP(i+1, 3), k = WRAP(i+2, 3); + if(lp*fabs(dp.Element(i)) < LENGTH_EPS) continue; // parallel to plane + + for(a = 0; a < 2; a++) { + double d = (a == 0) ? amax.Element(i) : amin.Element(i); + // n dot (p0 + t*dp) = d + // (n dot p0) + t * (n dot dp) = d + double t = (d - p0.Element(i)) / dp.Element(i); + Vector p = p0.Plus(dp.ScaledBy(t)); + + if(asSegment && (t < -LENGTH_EPS || t > (lp+LENGTH_EPS))) continue; + + if(p.Element(j) > amax.Element(j) + LENGTH_EPS) continue; + if(p.Element(k) > amax.Element(k) + LENGTH_EPS) continue; + + if(p.Element(j) < amin.Element(j) - LENGTH_EPS) continue; + if(p.Element(k) < amin.Element(k) - LENGTH_EPS) continue; + + return true; + } + } + + return false; +} + +Vector Vector::AtIntersectionOfPlanes(Vector n1, double d1, + Vector n2, double d2) +{ + double det = (n1.Dot(n1))*(n2.Dot(n2)) - + (n1.Dot(n2))*(n1.Dot(n2)); + double c1 = (d1*n2.Dot(n2) - d2*n1.Dot(n2))/det; + double c2 = (d2*n1.Dot(n1) - d1*n1.Dot(n2))/det; + + return (n1.ScaledBy(c1)).Plus(n2.ScaledBy(c2)); +} + +void Vector::ClosestPointBetweenLines(Vector a0, Vector da, + Vector b0, Vector db, + double *ta, double *tb) +{ + // Make a semi-orthogonal coordinate system from those directions; + // note that dna and dnb need not be perpendicular. + Vector dn = da.Cross(db); // normal to both + Vector dna = dn.Cross(da); // normal to da + Vector dnb = dn.Cross(db); // normal to db + + // At the intersection of the lines + // a0 + pa*da = b0 + pb*db (where pa, pb are scalar params) + // So dot this equation against dna and dnb to get two equations + // to solve for da and db + *tb = ((a0.Minus(b0)).Dot(dna))/(db.Dot(dna)); + *ta = -((a0.Minus(b0)).Dot(dnb))/(da.Dot(dnb)); +} + +Vector Vector::AtIntersectionOfLines(Vector a0, Vector a1, + Vector b0, Vector b1, + bool *skew, + double *parama, double *paramb) +{ + Vector da = a1.Minus(a0), db = b1.Minus(b0); + + double pa, pb; + Vector::ClosestPointBetweenLines(a0, da, b0, db, &pa, &pb); + + if(parama) *parama = pa; + if(paramb) *paramb = pb; + + // And from either of those, we get the intersection point. + Vector pi = a0.Plus(da.ScaledBy(pa)); + + if(skew) { + // Check if the intersection points on each line are actually + // coincident... + if(pi.Equals(b0.Plus(db.ScaledBy(pb)))) { + *skew = false; + } else { + *skew = true; + } + } + return pi; +} + +Vector Vector::AtIntersectionOfPlaneAndLine(Vector n, double d, + Vector p0, Vector p1, + bool *parallel) +{ + Vector dp = p1.Minus(p0); + + if(fabs(n.Dot(dp)) < LENGTH_EPS) { + if(parallel) *parallel = true; + return Vector::From(0, 0, 0); + } + + if(parallel) *parallel = false; + + // n dot (p0 + t*dp) = d + // (n dot p0) + t * (n dot dp) = d + double t = (d - n.Dot(p0)) / (n.Dot(dp)); + + return p0.Plus(dp.ScaledBy(t)); +} + +static double det2(double a1, double b1, + double a2, double b2) +{ + return (a1*b2) - (b1*a2); +} +static double det3(double a1, double b1, double c1, + double a2, double b2, double c2, + double a3, double b3, double c3) +{ + return a1*det2(b2, c2, b3, c3) - + b1*det2(a2, c2, a3, c3) + + c1*det2(a2, b2, a3, b3); +} +Vector Vector::AtIntersectionOfPlanes(Vector na, double da, + Vector nb, double db, + Vector nc, double dc, + bool *parallel) +{ + double det = det3(na.x, na.y, na.z, + nb.x, nb.y, nb.z, + nc.x, nc.y, nc.z); + if(fabs(det) < 1e-10) { // arbitrary tolerance, not so good + *parallel = true; + return Vector::From(0, 0, 0); + } + *parallel = false; + + double detx = det3(da, na.y, na.z, + db, nb.y, nb.z, + dc, nc.y, nc.z); + + double dety = det3(na.x, da, na.z, + nb.x, db, nb.z, + nc.x, dc, nc.z); + + double detz = det3(na.x, na.y, da, + nb.x, nb.y, db, + nc.x, nc.y, dc ); + + return Vector::From(detx/det, dety/det, detz/det); +} + +size_t VectorHash::operator()(const Vector &v) const { + const size_t size = (size_t)pow(std::numeric_limits::max(), 1.0 / 3.0) - 1; + const double eps = 4.0 * LENGTH_EPS; + + double x = fabs(v.x) / eps; + double y = fabs(v.y) / eps; + double z = fabs(v.y) / eps; + + size_t xs = size_t(fmod(x, (double)size)); + size_t ys = size_t(fmod(y, (double)size)); + size_t zs = size_t(fmod(z, (double)size)); + + return (zs * size + ys) * size + xs; +} + +bool VectorPred::operator()(Vector a, Vector b) const { + return a.Equals(b, LENGTH_EPS); +} + +Vector4 Vector4::From(double w, double x, double y, double z) { + Vector4 ret; + ret.w = w; + ret.x = x; + ret.y = y; + ret.z = z; + return ret; +} + +Vector4 Vector4::From(double w, Vector v) { + return Vector4::From(w, w*v.x, w*v.y, w*v.z); +} + +Vector4 Vector4::Blend(Vector4 a, Vector4 b, double t) { + return (a.ScaledBy(1 - t)).Plus(b.ScaledBy(t)); +} + +Vector4 Vector4::Plus(Vector4 b) const { + return Vector4::From(w + b.w, x + b.x, y + b.y, z + b.z); +} + +Vector4 Vector4::Minus(Vector4 b) const { + return Vector4::From(w - b.w, x - b.x, y - b.y, z - b.z); +} + +Vector4 Vector4::ScaledBy(double s) const { + return Vector4::From(w*s, x*s, y*s, z*s); +} + +Vector Vector4::PerspectiveProject() const { + return Vector::From(x / w, y / w, z / w); +} + +Point2d Point2d::From(double x, double y) { + return { x, y }; +} + +Point2d Point2d::FromPolar(double r, double a) { + return { r * cos(a), r * sin(a) }; +} + +double Point2d::Angle() const { + double a = atan2(y, x); + return M_PI + remainder(a - M_PI, 2 * M_PI); +} + +double Point2d::AngleTo(const Point2d &p) const { + return p.Minus(*this).Angle(); +} + +Point2d Point2d::Plus(const Point2d &b) const { + return { x + b.x, y + b.y }; +} + +Point2d Point2d::Minus(const Point2d &b) const { + return { x - b.x, y - b.y }; +} + +Point2d Point2d::ScaledBy(double s) const { + return { x * s, y * s }; +} + +double Point2d::DivProjected(Point2d delta) const { + return (x*delta.x + y*delta.y) / (delta.x*delta.x + delta.y*delta.y); +} + +double Point2d::MagSquared() const { + return x*x + y*y; +} + +double Point2d::Magnitude() const { + return sqrt(x*x + y*y); +} + +Point2d Point2d::WithMagnitude(double v) const { + double m = Magnitude(); + if(m < 1e-20) { + dbp("!!! WithMagnitude() of zero vector"); + return { v, 0 }; + } + return { x * v / m, y * v / m }; +} + +double Point2d::DistanceTo(const Point2d &p) const { + double dx = x - p.x; + double dy = y - p.y; + return sqrt(dx*dx + dy*dy); +} + +double Point2d::Dot(Point2d p) const { + return x*p.x + y*p.y; +} + +double Point2d::DistanceToLine(const Point2d &p0, const Point2d &dp, bool asSegment) const { + double m = dp.x*dp.x + dp.y*dp.y; + if(m < LENGTH_EPS*LENGTH_EPS) return VERY_POSITIVE; + + // Let our line be p = p0 + t*dp, for a scalar t from 0 to 1 + double t = (dp.x*(x - p0.x) + dp.y*(y - p0.y))/m; + + if(asSegment) { + if(t < 0.0) return DistanceTo(p0); + if(t > 1.0) return DistanceTo(p0.Plus(dp)); + } + Point2d closest = p0.Plus(dp.ScaledBy(t)); + return DistanceTo(closest); +} + +double Point2d::DistanceToLineSigned(const Point2d &p0, const Point2d &dp, bool asSegment) const { + double m = dp.x*dp.x + dp.y*dp.y; + if(m < LENGTH_EPS*LENGTH_EPS) return VERY_POSITIVE; + + Point2d n = dp.Normal().WithMagnitude(1.0); + double dist = n.Dot(*this) - n.Dot(p0); + if(asSegment) { + // Let our line be p = p0 + t*dp, for a scalar t from 0 to 1 + double t = (dp.x*(x - p0.x) + dp.y*(y - p0.y))/m; + double sign = (dist > 0.0) ? 1.0 : -1.0; + if(t < 0.0) return DistanceTo(p0) * sign; + if(t > 1.0) return DistanceTo(p0.Plus(dp)) * sign; + } + + return dist; +} + +Point2d Point2d::Normal() const { + return { y, -x }; +} + +bool Point2d::Equals(Point2d v, double tol) const { + double dx = v.x - x; if(dx < -tol || dx > tol) return false; + double dy = v.y - y; if(dy < -tol || dy > tol) return false; + + return (this->Minus(v)).MagSquared() < tol*tol; +} + +BBox BBox::From(const Vector &p0, const Vector &p1) { + BBox bbox; + bbox.minp.x = min(p0.x, p1.x); + bbox.minp.y = min(p0.y, p1.y); + bbox.minp.z = min(p0.z, p1.z); + + bbox.maxp.x = max(p0.x, p1.x); + bbox.maxp.y = max(p0.y, p1.y); + bbox.maxp.z = max(p0.z, p1.z); + return bbox; +} + +Vector BBox::GetOrigin() const { return minp.Plus(maxp.Minus(minp).ScaledBy(0.5)); } +Vector BBox::GetExtents() const { return maxp.Minus(minp).ScaledBy(0.5); } + +void BBox::Include(const Vector &v, double r) { + minp.x = min(minp.x, v.x - r); + minp.y = min(minp.y, v.y - r); + minp.z = min(minp.z, v.z - r); + + maxp.x = max(maxp.x, v.x + r); + maxp.y = max(maxp.y, v.y + r); + maxp.z = max(maxp.z, v.z + r); +} + +bool BBox::Overlaps(const BBox &b1) const { + Vector t = b1.GetOrigin().Minus(GetOrigin()); + Vector e = b1.GetExtents().Plus(GetExtents()); + + return fabs(t.x) < e.x && fabs(t.y) < e.y && fabs(t.z) < e.z; +} + +bool BBox::Contains(const Point2d &p, double r) const { + return p.x >= (minp.x - r) && + p.y >= (minp.y - r) && + p.x <= (maxp.x + r) && + p.y <= (maxp.y + r); +} + +const std::vector& SolveSpace::StipplePatternDashes(StipplePattern pattern) { + static bool initialized; + static std::vector dashes[(size_t)StipplePattern::LAST + 1]; + if(!initialized) { + // Inkscape ignores all elements that are exactly zero instead of drawing + // them as dots, so set those to 1e-6. + dashes[(size_t)StipplePattern::CONTINUOUS] = + {}; + dashes[(size_t)StipplePattern::SHORT_DASH] = + { 1.0, 2.0 }; + dashes[(size_t)StipplePattern::DASH] = + { 1.0, 1.0 }; + dashes[(size_t)StipplePattern::DASH_DOT] = + { 1.0, 0.5, 1e-6, 0.5 }; + dashes[(size_t)StipplePattern::DASH_DOT_DOT] = + { 1.0, 0.5, 1e-6, 0.5, 1e-6, 0.5 }; + dashes[(size_t)StipplePattern::DOT] = + { 1e-6, 0.5 }; + dashes[(size_t)StipplePattern::LONG_DASH] = + { 2.0, 0.5 }; + dashes[(size_t)StipplePattern::FREEHAND] = + { 1.0, 2.0 }; + dashes[(size_t)StipplePattern::ZIGZAG] = + { 1.0, 2.0 }; + } + + return dashes[(size_t)pattern]; +} + +double SolveSpace::StipplePatternLength(StipplePattern pattern) { + static bool initialized; + static double lengths[(size_t)StipplePattern::LAST + 1]; + if(!initialized) { + for(size_t i = 0; i < (size_t)StipplePattern::LAST; i++) { + const std::vector &dashes = StipplePatternDashes((StipplePattern)i); + double length = 0.0; + for(double dash : dashes) { + length += dash; + } + lengths[i] = length; + } + } + + return lengths[(size_t)pattern]; +} diff --git a/src/view.cpp b/src/view.cpp new file mode 100644 index 0000000..14d09ba --- /dev/null +++ b/src/view.cpp @@ -0,0 +1,122 @@ +//----------------------------------------------------------------------------- +// The View menu, stuff to snap to certain special vews of the model, and to +// display our current view of the model to the user. +// +// Copyright 2008-2013 Jonathan Westhues. +//----------------------------------------------------------------------------- +#include "solvespace.h" + +void TextWindow::ShowEditView() { + Printf(true, "%Ft3D VIEW PARAMETERS%E"); + + Printf(true, "%Bd %Ftoverall scale factor%E"); + Printf(false, "%Ba %# px/%s %Fl%Ll%f[edit]%E", + SS.GW.scale * SS.MmPerUnit(), + SS.UnitName(), + &ScreenChangeViewScale); + Printf(false, "%Bd %Fl%Ll%fset to full scale%E", + &ScreenChangeViewToFullScale); + Printf(false, ""); + + Printf(false, "%Bd %Ftorigin (maps to center of screen)%E"); + Printf(false, "%Ba (%s, %s, %s) %Fl%Ll%f[edit]%E", + SS.MmToString(-SS.GW.offset.x).c_str(), + SS.MmToString(-SS.GW.offset.y).c_str(), + SS.MmToString(-SS.GW.offset.z).c_str(), + &ScreenChangeViewOrigin); + Printf(false, ""); + + Vector n = (SS.GW.projRight).Cross(SS.GW.projUp); + Printf(false, "%Bd %Ftprojection onto screen%E"); + Printf(false, "%Ba %Ftright%E (%3, %3, %3) %Fl%Ll%f[edit]%E", + CO(SS.GW.projRight), + &ScreenChangeViewProjection); + Printf(false, "%Bd %Ftup%E (%3, %3, %3)", CO(SS.GW.projUp)); + Printf(false, "%Ba %Ftout%E (%3, %3, %3)", CO(n)); + Printf(false, ""); + + Printf(false, "The perspective may be changed in the"); + Printf(false, "configuration screen."); +} + +void TextWindow::ScreenChangeViewScale(int link, uint32_t v) { + SS.TW.edit.meaning = Edit::VIEW_SCALE; + SS.TW.ShowEditControl(3, ssprintf("%.3f", SS.GW.scale * SS.MmPerUnit())); +} + +void TextWindow::ScreenChangeViewToFullScale(int link, uint32_t v) { + SS.GW.scale = SS.GW.window->GetPixelDensity() / 25.4; +} + +void TextWindow::ScreenChangeViewOrigin(int link, uint32_t v) { + std::string edit_value = + ssprintf("%s, %s, %s", + SS.MmToString(-SS.GW.offset.x).c_str(), + SS.MmToString(-SS.GW.offset.y).c_str(), + SS.MmToString(-SS.GW.offset.z).c_str()); + + SS.TW.edit.meaning = Edit::VIEW_ORIGIN; + SS.TW.ShowEditControl(3, edit_value); +} + +void TextWindow::ScreenChangeViewProjection(int link, uint32_t v) { + std::string edit_value = + ssprintf("%.3f, %.3f, %.3f", CO(SS.GW.projRight)); + SS.TW.edit.meaning = Edit::VIEW_PROJ_RIGHT; + SS.TW.ShowEditControl(10, edit_value); +} + +bool TextWindow::EditControlDoneForView(const std::string &s) { + switch(edit.meaning) { + case Edit::VIEW_SCALE: { + Expr *e = Expr::From(s, /*popUpError=*/true); + if(e) { + double v = e->Eval() / SS.MmPerUnit(); + if(v > LENGTH_EPS) { + SS.GW.scale = v; + } else { + Error(_("Scale cannot be zero or negative.")); + } + } + break; + } + + case Edit::VIEW_ORIGIN: { + Vector pt; + if(sscanf(s.c_str(), "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) == 3) { + pt = pt.ScaledBy(SS.MmPerUnit()); + SS.GW.offset = pt.ScaledBy(-1); + } else { + Error(_("Bad format: specify x, y, z")); + } + break; + } + + case Edit::VIEW_PROJ_RIGHT: + case Edit::VIEW_PROJ_UP: { + Vector pt; + if(sscanf(s.c_str(), "%lf, %lf, %lf", &pt.x, &pt.y, &pt.z) != 3) { + Error(_("Bad format: specify x, y, z")); + break; + } + if(edit.meaning == Edit::VIEW_PROJ_RIGHT) { + SS.GW.projRight = pt; + SS.GW.NormalizeProjectionVectors(); + edit.meaning = Edit::VIEW_PROJ_UP; + HideEditControl(); + ShowEditControl(10, ssprintf("%.3f, %.3f, %.3f", CO(SS.GW.projUp)), + editControl.halfRow + 2); + edit.showAgain = true; + } else { + SS.GW.projUp = pt; + SS.GW.NormalizeProjectionVectors(); + } + break; + } + + default: + return false; + } + return true; +} + diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..db812bf --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,138 @@ +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR}) + +foreach(pkg_config_lib CAIRO) + include_directories(${${pkg_config_lib}_INCLUDE_DIRS}) + link_directories(${${pkg_config_lib}_LIBRARY_DIRS}) +endforeach() + +if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") + add_definitions(-DTEST_BUILD_ON_WINDOWS) +endif() + +# test suite + +set(testsuite_SOURCES + harness.cpp + analysis/contour_area/test.cpp + core/expr/test.cpp + core/locale/test.cpp + core/path/test.cpp + constraint/points_coincident/test.cpp + constraint/pt_pt_distance/test.cpp + constraint/pt_plane_distance/test.cpp + constraint/pt_line_distance/test.cpp + constraint/pt_face_distance/test.cpp + constraint/proj_pt_distance/test.cpp + constraint/pt_in_plane/test.cpp + constraint/pt_on_line/test.cpp + constraint/pt_on_face/test.cpp + constraint/equal_length_lines/test.cpp + constraint/length_ratio/test.cpp + constraint/eq_len_pt_line_d/test.cpp + constraint/eq_pt_ln_distances/test.cpp + constraint/equal_angle/test.cpp + constraint/equal_line_arc_len/test.cpp + constraint/length_difference/test.cpp + constraint/symmetric/test.cpp + constraint/symmetric_horiz/test.cpp + constraint/symmetric_vert/test.cpp + constraint/symmetric_line/test.cpp + constraint/at_midpoint/test.cpp + constraint/horizontal/test.cpp + constraint/vertical/test.cpp + constraint/diameter/test.cpp + constraint/pt_on_circle/test.cpp + constraint/same_orientation/test.cpp + constraint/angle/test.cpp + constraint/parallel/test.cpp + constraint/perpendicular/test.cpp + constraint/arc_line_tangent/test.cpp + constraint/cubic_line_tangent/test.cpp + constraint/curve_curve_tangent/test.cpp + constraint/equal_radius/test.cpp + constraint/where_dragged/test.cpp + constraint/comment/test.cpp + request/arc_of_circle/test.cpp + request/circle/test.cpp + request/cubic/test.cpp + request/cubic_periodic/test.cpp + request/datum_point/test.cpp + request/image/test.cpp + request/line_segment/test.cpp + request/ttf_text/test.cpp + request/workplane/test.cpp + group/link/test.cpp + group/translate_asy/test.cpp + group/translate_nd/test.cpp +) + +add_executable(solvespace-testsuite + ${testsuite_SOURCES} + $) + +target_link_libraries(solvespace-testsuite + solvespace-headless + ${COVERAGE_LIBRARY}) + +add_dependencies(solvespace-testsuite + resources) + +add_custom_target(test_solvespace + COMMAND $ + COMMENT "Testing SolveSpace" + VERBATIM) + +# coverage reports + +if(ENABLE_COVERAGE) + set(LCOV_FLAGS -q --gcov-tool ${GCOV}) + set(LCOV_FLAGS ${LCOV_FLAGS} --rc lcov_branch_coverage=1) + set(LCOV_FLAGS ${LCOV_FLAGS} --rc "lcov_excl_line=(ssassert|switch)") + set(LCOV_FLAGS ${LCOV_FLAGS} --rc "lcov_excl_br_line=BRANCH_ALWAYS_TAKEN") + set(LCOV_COLLECT -c -b ${CMAKE_SOURCE_DIR}/src -d ${CMAKE_BINARY_DIR}/src --no-external) + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/coverage_base.info + COMMAND ${LCOV} ${LCOV_FLAGS} ${LCOV_COLLECT} + -o ${CMAKE_BINARY_DIR}/coverage_base.info -i + DEPENDS solvespace-testsuite + COMMENT "Importing baseline coverage data" + VERBATIM) + + add_custom_target(coverage_solvespace ALL + COMMAND ${LCOV} ${LCOV_FLAGS} ${LCOV_COLLECT} + -o ${CMAKE_BINARY_DIR}/coverage_test.info + COMMAND ${LCOV} ${LCOV_FLAGS} + -o ${CMAKE_BINARY_DIR}/coverage_full.info + -a ${CMAKE_BINARY_DIR}/coverage_base.info + -a ${CMAKE_BINARY_DIR}/coverage_test.info + COMMAND ${LCOV} ${LCOV_FLAGS} --summary + ${CMAKE_BINARY_DIR}/coverage_full.info + COMMAND ${GENHTML} -q --branch-coverage --demangle-cpp --legend + ${CMAKE_BINARY_DIR}/coverage_full.info + -o ${CMAKE_BINARY_DIR}/coverage/ + -t "SolveSpace testbench" + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/coverage_base.info + DEPENDS test_solvespace + COMMENT "Generating coverage report" + VERBATIM) +endif() + +# debug runner + +set(debugtool_SOURCES + debugtool.cpp +) + +add_executable(solvespace-debugtool + ${debugtool_SOURCES} + $) + +target_link_libraries(solvespace-debugtool + solvespace-core + solvespace-headless) + +add_dependencies(solvespace-debugtool + resources) diff --git a/test/Gentium-R.ttf b/test/Gentium-R.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3b44ad16d4b7ba32359857f73142a01d11687ec4 GIT binary patch literal 362644 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⁡v!y+nU!5NkXXIK`TVOem7WvQHD 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

$Js7$j;=G7{{ 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

}IQ3yn`RY-S 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

!a-aJ<2Y?`Gu%^5ytw(DF5Qml)dyxWiMZ?>=m%R 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 literal 0 HcmV?d00001 diff --git a/test/analysis/contour_area/normal.slvs b/test/analysis/contour_area/normal.slvs new file mode 100644 index 0000000..15dc34a --- /dev/null +++ b/test/analysis/contour_area/normal.slvs @@ -0,0 +1,512 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00070010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00070011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00070013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00070014 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000007 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00070001 +Entity.point[1].v=00070002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040001 +Constraint.ptB.v=00050002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050001 +Constraint.ptB.v=00060002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00060001 +Constraint.ptB.v=00070002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000004 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00070001 +Constraint.ptB.v=00040002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000005 +Constraint.type=81 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000006 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000007 +Constraint.type=81 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00060000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000008 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00070000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/analysis/contour_area/test.cpp b/test/analysis/contour_area/test.cpp new file mode 100644 index 0000000..748f0eb --- /dev/null +++ b/test/analysis/contour_area/test.cpp @@ -0,0 +1,7 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + SS.showContourAreas = true; + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); +} diff --git a/test/commit.sh b/test/commit.sh new file mode 100755 index 0000000..d49708e --- /dev/null +++ b/test/commit.sh @@ -0,0 +1,9 @@ +#!/bin/sh -ex + +make -C build solvespace-testsuite +./build/test/solvespace-testsuite $* || true +for e in slvs png; do + for i in `find . -name *.out.$e`; do + mv $i `dirname $i`/`basename $i .out.$e`.$e; + done; +done diff --git a/test/constraint/angle/free_in_3d.png b/test/constraint/angle/free_in_3d.png new file mode 100644 index 0000000000000000000000000000000000000000..2fef8c185e0a3efea5f6b4e411d23675eeaf05ab GIT binary patch literal 4763 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 Usb)9`KRSWUCKkr54QSB60EA524gdfE literal 0 HcmV?d00001 diff --git a/test/constraint/angle/free_in_3d.slvs b/test/constraint/angle/free_in_3d.slvs new file mode 100644 index 0000000..dd9a053 --- /dev/null +++ b/test/constraint/angle/free_in_3d.slvs @@ -0,0 +1,355 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=00050013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000088818 +AddParam + +Param.h.v.=00050015 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000088818 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.ptA.v=00040002 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=120 +Constraint.group.v=00000002 +Constraint.valA=45.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=1 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.x=0.51894056308654845644 +Constraint.disp.offset.y=3.99584233576642278152 +AddConstraint + diff --git a/test/constraint/angle/free_in_3d_v20.slvs b/test/constraint/angle/free_in_3d_v20.slvs new file mode 100644 index 0000000..7f118f9 --- /dev/null +++ b/test/constraint/angle/free_in_3d_v20.slvs @@ -0,0 +1,355 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=00050013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000090000 +AddParam + +Param.h.v.=00050015 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000090000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.ptA.v=00040002 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=120 +Constraint.group.v=00000002 +Constraint.valA=45.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=1 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.x=0.51894056308654846000 +Constraint.disp.offset.y=3.99584233576642280000 +AddConstraint + diff --git a/test/constraint/angle/free_in_3d_v22.slvs b/test/constraint/angle/free_in_3d_v22.slvs new file mode 100644 index 0000000..488f552 --- /dev/null +++ b/test/constraint/angle/free_in_3d_v22.slvs @@ -0,0 +1,355 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=00050013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000088818 +AddParam + +Param.h.v.=00050015 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000088818 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.ptA.v=00040002 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=120 +Constraint.group.v=00000002 +Constraint.valA=45.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=1 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.x=0.51894056308654845644 +Constraint.disp.offset.y=3.99584233576642278152 +AddConstraint + diff --git a/test/constraint/angle/normal.png b/test/constraint/angle/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..40b2d0e190cf5f5c833be4f3730398c704e3c0cb GIT binary patch literal 4882 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 literal 0 HcmV?d00001 diff --git a/test/constraint/angle/reference_free_in_3d.slvs b/test/constraint/angle/reference_free_in_3d.slvs new file mode 100644 index 0000000..bfc1723 --- /dev/null +++ b/test/constraint/angle/reference_free_in_3d.slvs @@ -0,0 +1,355 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=00050013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000088818 +AddParam + +Param.h.v.=00050015 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000088818 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.ptA.v=00040002 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=120 +Constraint.group.v=00000002 +Constraint.valA=45.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=1 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.x=0.51894056308654845644 +Constraint.disp.offset.y=3.99584233576642278152 +AddConstraint + diff --git a/test/constraint/angle/reference_free_in_3d_v20.slvs b/test/constraint/angle/reference_free_in_3d_v20.slvs new file mode 100644 index 0000000..8a6aef6 --- /dev/null +++ b/test/constraint/angle/reference_free_in_3d_v20.slvs @@ -0,0 +1,355 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=00050013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000090000 +AddParam + +Param.h.v.=00050015 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000090000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.ptA.v=00040002 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=120 +Constraint.group.v=00000002 +Constraint.valA=45.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=1 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.x=0.51894056308654846000 +Constraint.disp.offset.y=3.99584233576642280000 +AddConstraint + diff --git a/test/constraint/angle/reference_free_in_3d_v22.slvs b/test/constraint/angle/reference_free_in_3d_v22.slvs new file mode 100644 index 0000000..dd91a68 --- /dev/null +++ b/test/constraint/angle/reference_free_in_3d_v22.slvs @@ -0,0 +1,355 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=00050013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000088818 +AddParam + +Param.h.v.=00050015 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000088818 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.ptA.v=00040002 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=120 +Constraint.group.v=00000002 +Constraint.valA=45.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=1 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.x=0.51894056308654845644 +Constraint.disp.offset.y=3.99584233576642278152 +AddConstraint + diff --git a/test/constraint/angle/reference_v20.slvs b/test/constraint/angle/reference_v20.slvs new file mode 100644 index 0000000..1ba8cb6 --- /dev/null +++ b/test/constraint/angle/reference_v20.slvs @@ -0,0 +1,366 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000090000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000090000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040002 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=120 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=45.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=1 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.y=4.50000000000000000000 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=120 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=135.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.x=-1.99273176225234480000 +Constraint.disp.offset.y=1.12091161626694390000 +AddConstraint + diff --git a/test/constraint/angle/reference_v22.slvs b/test/constraint/angle/reference_v22.slvs new file mode 100644 index 0000000..0408a83 --- /dev/null +++ b/test/constraint/angle/reference_v22.slvs @@ -0,0 +1,366 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000088818 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000088818 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040002 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=120 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=45.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=1 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.y=4.50000000000000000000 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=120 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=135.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.x=-1.99273176225234482928 +Constraint.disp.offset.y=1.12091161626694391096 +AddConstraint + diff --git a/test/constraint/angle/skew.png b/test/constraint/angle/skew.png new file mode 100644 index 0000000000000000000000000000000000000000..92d7577a44f841963122399714b2e8daae3d7690 GIT binary patch literal 4867 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 literal 0 HcmV?d00001 diff --git a/test/constraint/angle/skew.slvs b/test/constraint/angle/skew.slvs new file mode 100644 index 0000000..e793f93 --- /dev/null +++ b/test/constraint/angle/skew.slvs @@ -0,0 +1,340 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=00020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=120 +Constraint.group.v=00000002 +Constraint.valA=90.00000000000000000000 +Constraint.entityA.v=00050000 +Constraint.entityB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.x=2.50000000000000044409 +Constraint.disp.offset.y=-2.50000000000000000000 +Constraint.disp.offset.z=-2.50000000000000000000 +AddConstraint + diff --git a/test/constraint/angle/skew_v22.slvs b/test/constraint/angle/skew_v22.slvs new file mode 100644 index 0000000..e793f93 --- /dev/null +++ b/test/constraint/angle/skew_v22.slvs @@ -0,0 +1,340 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=00020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=120 +Constraint.group.v=00000002 +Constraint.valA=90.00000000000000000000 +Constraint.entityA.v=00050000 +Constraint.entityB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.x=2.50000000000000044409 +Constraint.disp.offset.y=-2.50000000000000000000 +Constraint.disp.offset.z=-2.50000000000000000000 +AddConstraint + diff --git a/test/constraint/angle/test.cpp b/test/constraint/angle/test.cpp new file mode 100644 index 0000000..668394d --- /dev/null +++ b/test/constraint/angle/test.cpp @@ -0,0 +1,70 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(free_in_3d_roundtrip) { + CHECK_LOAD("free_in_3d.slvs"); + CHECK_RENDER("free_in_3d.png"); + CHECK_SAVE("free_in_3d.slvs"); +} + +TEST_CASE(free_in_3d_migrate_from_v20) { + CHECK_LOAD("free_in_3d_v20.slvs"); + CHECK_SAVE("free_in_3d.slvs"); +} + +TEST_CASE(free_in_3d_migrate_from_v22) { + CHECK_LOAD("free_in_3d_v22.slvs"); + CHECK_SAVE("free_in_3d.slvs"); +} + +TEST_CASE(reference_roundtrip) { + CHECK_LOAD("reference.slvs"); + CHECK_RENDER("reference.png"); + CHECK_SAVE("reference.slvs"); +} + +TEST_CASE(reference_migrate_from_v20) { + CHECK_LOAD("reference_v20.slvs"); + CHECK_SAVE("reference.slvs"); +} + +TEST_CASE(reference_migrate_from_v22) { + CHECK_LOAD("reference_v22.slvs"); + CHECK_SAVE("reference.slvs"); +} + +TEST_CASE(reference_free_in_3d_roundtrip) { + CHECK_LOAD("reference_free_in_3d.slvs"); + CHECK_RENDER("reference_free_in_3d.png"); + CHECK_SAVE("reference_free_in_3d.slvs"); +} + +TEST_CASE(reference_free_in_3d_migrate_from_v20) { + CHECK_LOAD("reference_free_in_3d_v20.slvs"); + CHECK_SAVE("reference_free_in_3d.slvs"); +} + +TEST_CASE(reference_free_in_3d_migrate_from_v22) { + CHECK_LOAD("reference_free_in_3d_v22.slvs"); + CHECK_SAVE("reference_free_in_3d.slvs"); +} + +TEST_CASE(skew_render) { + CHECK_LOAD("skew.slvs"); + CHECK_RENDER("skew.png"); +} diff --git a/test/constraint/arc_line_tangent/normal.png b/test/constraint/arc_line_tangent/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..ab59db735cdd656b8eff17463b758c7b6c2add85 GIT binary patch literal 5100 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 literal 0 HcmV?d00001 diff --git a/test/constraint/arc_line_tangent/normal.slvs b/test/constraint/arc_line_tangent/normal.slvs new file mode 100644 index 0000000..7572139 --- /dev/null +++ b/test/constraint/arc_line_tangent/normal.slvs @@ -0,0 +1,450 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00040016 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040017 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=25.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=-5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=500 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=14000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.normal.v=00040020 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=25.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040002 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=123 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040003 +Constraint.ptB.v=00060001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000004 +Constraint.type=123 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00060000 +Constraint.other=1 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/arc_line_tangent/normal_v20.slvs b/test/constraint/arc_line_tangent/normal_v20.slvs new file mode 100644 index 0000000..402d9de --- /dev/null +++ b/test/constraint/arc_line_tangent/normal_v20.slvs @@ -0,0 +1,450 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00040016 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040017 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=25.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=-5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=500 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=14000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.normal.v=00040020 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=25.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040002 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=123 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040003 +Constraint.ptB.v=00060001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000004 +Constraint.type=123 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00060000 +Constraint.other=1 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/arc_line_tangent/normal_v22.slvs b/test/constraint/arc_line_tangent/normal_v22.slvs new file mode 100644 index 0000000..86a7d82 --- /dev/null +++ b/test/constraint/arc_line_tangent/normal_v22.slvs @@ -0,0 +1,450 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00040016 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040017 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=25.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=-5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=500 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=14000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.normal.v=00040020 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=25.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040002 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=123 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040003 +Constraint.ptB.v=00060001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000004 +Constraint.type=123 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00060000 +Constraint.other=1 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/arc_line_tangent/test.cpp b/test/constraint/arc_line_tangent/test.cpp new file mode 100644 index 0000000..5e9db1b --- /dev/null +++ b/test/constraint/arc_line_tangent/test.cpp @@ -0,0 +1,17 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} diff --git a/test/constraint/at_midpoint/line_plane_free_in_3d.png b/test/constraint/at_midpoint/line_plane_free_in_3d.png new file mode 100644 index 0000000000000000000000000000000000000000..9f41d0f858083c5306934fe5631e26329cccd5aa GIT binary patch literal 4333 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 literal 0 HcmV?d00001 diff --git a/test/constraint/at_midpoint/line_pt_free_in_3d.slvs b/test/constraint/at_midpoint/line_pt_free_in_3d.slvs new file mode 100644 index 0000000..f40d499 --- /dev/null +++ b/test/constraint/at_midpoint/line_pt_free_in_3d.slvs @@ -0,0 +1,315 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=70 +Constraint.group.v=00000002 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/at_midpoint/line_pt_free_in_3d_v20.slvs b/test/constraint/at_midpoint/line_pt_free_in_3d_v20.slvs new file mode 100644 index 0000000..63806c5 --- /dev/null +++ b/test/constraint/at_midpoint/line_pt_free_in_3d_v20.slvs @@ -0,0 +1,313 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=70 +Constraint.group.v=00000002 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/at_midpoint/line_pt_free_in_3d_v22.slvs b/test/constraint/at_midpoint/line_pt_free_in_3d_v22.slvs new file mode 100644 index 0000000..2933389 --- /dev/null +++ b/test/constraint/at_midpoint/line_pt_free_in_3d_v22.slvs @@ -0,0 +1,315 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=70 +Constraint.group.v=00000002 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/at_midpoint/line_pt_normal.png b/test/constraint/at_midpoint/line_pt_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..0e43d59a86ebede65c3dbbc7f22c5fb364216db1 GIT binary patch literal 4298 zcmeHLYgAI{8va03l+@C~E(%RecEd}Vm!iZeFEv^nCnLmE%OaS?%#10BG9qg*8A{s<&r10x=$p?>r1=LdL4Ey^YmHttLz&Q!0oY;r9y{-yZ*l9T=uDCOJ>7e%Gc0BlL( zNdbU%V(`E{8$tuD1#(6x8V6?jGEm^K5ecvzIQn3sjSzreKi4MNox95=0^8c6Ye`RE zcFUILss#~=%0QV077tnm_@u`cE-kvz($U9iV!2us5j^Wn#8}kF!s*HD_#MqjpAzJv z8}^2Qe#h?tz%IJ}zPIfOJHv|x!qhi#L~^!0Fas0rU`AnST~HDBiGZ+^NIq&)wsi74 zVKDayq!<9L_I)q1+HASP8idap+dvCqOjGNDLyJcvhsusT%l^a+af!9xRq1hE5bSi) z`RD;XkmrH|4(1l`OSL=YX?dI>IE5YCK((ZKX#vC?i`=2`9C`aEQl_J(*k1)Y*4~d? zrNb|05ezHV0+4od4CHsXcP}HhP>O(umG>qqdeAH0eb4#Q%E>=vXbReCARMaLdxj+{}O5d77!t|-vFjx+O?J8D;G z7hk3)hcxu`u_GQEL3@3L&8A{~R7@6haE6-=HGdPRT*bI<{i`uM+K3e6z7_S{R7Xfg z%!7yH$J&vd8oN6@yMmvaLR2J(5jUB->Atn&yZgsCn>1#?x9b*;souyBpQ1CFY8&9( zFQpIoRT;76W7_jU(?W!*dvnxoz+Q2JfjXQ}Bn7OgXxz*;?}2FnD{-d(8j%aE=Ki3O zZF40C51IOwG&f@KtnlPuD{)dHgEBa@{+Paewve6l8kR*9L!^r*(^&*Gt{IoT{d&1C zq7`kwc8d#Wd_ECndq~)sQPb%VM0kD0U^8*8_ zx8*ACt#+m$vwsIG@l|VWboYE>9gk>6!Tq>E@z02mBrmpwMtXQk4q`x>MSU)6XVJke zp3$|#fn|wN=x{f)nlCt;N`rO{7uhTYc__(LN6_rkQhS#}78yUnq zQaEGW1IO|EsrAJ_=TQGwA9=gc`2xd834Vd${|JWD_Ci=;0ze))gdwsi2JE2Ij)+)B zeXXOI$O|Fzf4=RCPB95Dp6=S?LLqedSKt7HF(%I+Z1zV*9YAMBMfaZB@rdS)|J_OI zP7i!%VM47FaNs_M==fv$U_!wl{_HI@=q)DADG-?P;X8!o03smf1c2V~SLld%+|1I% zT-nfR2iP1$vfmPmaoX)fgUs9@EU=>Ga@q|&^nf9}gCTMb-zw+|j}VxF)=n28eTH)} z-Ga`l<0eZv*2pNJG3CQ4NBI}EnlN)uJm@JHf_CpIyS2MZc5KcSz$J!Zs7%UirbB)J zxK~gCO%H!^Wo{h_bkvF!CV#d19rRsK$undQI8_36>r^?u#Yjy^1rC?KnM*UW+u@RcyeP9gS&UOSDU|`M(I?6p41EYrTG7Nk@8@UhV zKfS6oYi~XJRUzPp$PRTT=%+l_n)b-0r@1mAc#P z7s)nt{Ul&#wNO}E5lvRXsudM#7fC+#o<(vnXI;-UT1I09kR2geWGqkaN4YZva;PFb z-?r|8@`5?$p5;&&X4onAr4f4*tiKhzMcJp6N}pbxP+U~$^lIIMrpL09NIPOfi6pl7 zvS6Sxs!A0v4wnV=HAR-XMMz-098~UH@!KLvMslJ`_UFskB7S*&Yi#e*3_@+DB>q74 zCQ9$!?knxeELvaF5Y?@uMi4T$ruqkYQwysy4jH60Ri3UVy^mKYZ~xSJyZ+^Cz31mD zpk+6h^GmB^JExt&0oP;IA%`ND2DmB$?KXSCRoWo8l=w@t|C07o269xQXC-PLjB1{Y zkgso6=Y{({mz3oqjFBQr>KUcBpZ zNllVc$x_9}Z+y~k$n|OwY5Y|_EiVql#O$>u{xF2MGWDKY6C=j*{Cy>Wz3Nhx=PS}` zH%GX^oE*>3U8dTx<#!ECjMd(Z3~Q6u43EX}%9OQT@_D#)=Feg!XkIen*!3SP867S7 d9CQ7kp~QMM`RjAYe+tNFjpsU#!j+7J{{ajfuqFTi literal 0 HcmV?d00001 diff --git a/test/constraint/at_midpoint/line_pt_normal.slvs b/test/constraint/at_midpoint/line_pt_normal.slvs new file mode 100644 index 0000000..483bc76 --- /dev/null +++ b/test/constraint/at_midpoint/line_pt_normal.slvs @@ -0,0 +1,313 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=70 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/at_midpoint/line_pt_normal_v20.slvs b/test/constraint/at_midpoint/line_pt_normal_v20.slvs new file mode 100644 index 0000000..76d63eb --- /dev/null +++ b/test/constraint/at_midpoint/line_pt_normal_v20.slvs @@ -0,0 +1,311 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=70 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/at_midpoint/line_pt_normal_v22.slvs b/test/constraint/at_midpoint/line_pt_normal_v22.slvs new file mode 100644 index 0000000..07761c1 --- /dev/null +++ b/test/constraint/at_midpoint/line_pt_normal_v22.slvs @@ -0,0 +1,313 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=70 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/at_midpoint/test.cpp b/test/constraint/at_midpoint/test.cpp new file mode 100644 index 0000000..3525df9 --- /dev/null +++ b/test/constraint/at_midpoint/test.cpp @@ -0,0 +1,65 @@ +#include "harness.h" + +TEST_CASE(line_pt_normal_roundtrip) { + CHECK_LOAD("line_pt_normal.slvs"); + CHECK_RENDER("line_pt_normal.png"); + CHECK_SAVE("line_pt_normal.slvs"); +} + +TEST_CASE(line_pt_normal_migrate_from_v20) { + CHECK_LOAD("line_pt_normal_v20.slvs"); + CHECK_SAVE("line_pt_normal.slvs"); +} + +TEST_CASE(line_pt_normal_migrate_from_v22) { + CHECK_LOAD("line_pt_normal_v22.slvs"); + CHECK_SAVE("line_pt_normal.slvs"); +} + +TEST_CASE(line_pt_free_in_3d_roundtrip) { + CHECK_LOAD("line_pt_free_in_3d.slvs"); + CHECK_RENDER("line_pt_free_in_3d.png"); + CHECK_SAVE("line_pt_free_in_3d.slvs"); +} + +TEST_CASE(line_pt_free_in_3d_migrate_from_v20) { + CHECK_LOAD("line_pt_free_in_3d_v20.slvs"); + CHECK_SAVE("line_pt_free_in_3d.slvs"); +} + +TEST_CASE(line_pt_free_in_3d_migrate_from_v22) { + CHECK_LOAD("line_pt_free_in_3d_v22.slvs"); + CHECK_SAVE("line_pt_free_in_3d.slvs"); +} + +TEST_CASE(line_plane_normal_roundtrip) { + CHECK_LOAD("line_plane_normal.slvs"); + CHECK_RENDER("line_plane_normal.png"); + CHECK_SAVE("line_plane_normal.slvs"); +} + +TEST_CASE(line_plane_normal_migrate_from_v20) { + CHECK_LOAD("line_plane_normal_v20.slvs"); + CHECK_SAVE("line_plane_normal.slvs"); +} + +TEST_CASE(line_plane_normal_migrate_from_v22) { + CHECK_LOAD("line_plane_normal_v22.slvs"); + CHECK_SAVE("line_plane_normal.slvs"); +} + +TEST_CASE(line_plane_free_in_3d_roundtrip) { + CHECK_LOAD("line_plane_free_in_3d.slvs"); + CHECK_RENDER("line_plane_free_in_3d.png"); + CHECK_SAVE("line_plane_free_in_3d.slvs"); +} + +TEST_CASE(line_plane_free_in_3d_migrate_from_v20) { + CHECK_LOAD("line_plane_free_in_3d_v20.slvs"); + CHECK_SAVE("line_plane_free_in_3d.slvs"); +} + +TEST_CASE(line_plane_free_in_3d_migrate_from_v22) { + CHECK_LOAD("line_plane_free_in_3d_v22.slvs"); + CHECK_SAVE("line_plane_free_in_3d.slvs"); +} diff --git a/test/constraint/comment/normal.png b/test/constraint/comment/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..5a7036c29f62f9621384c02232d7093602630908 GIT binary patch literal 4314 zcmeHLX;hO}8omj;h)R*A2#8XtmZ%^ih=j!=Zbd;wFdzg08AX;FW7x8QAcJ~L6$JzV zktr^OMQKFC_5pK%8cWCsfgr0^$rvGO5+X^H%!frzqs8&Z^v9gzkDPl>a?j2CJ@0|=UwF{{%mvmnM<45_NNGm z!uH)H08uHAu|$R9`Ix9Eu{8i*pXo6r0-x#eKchz%^|>A(W0a)dS`14=9>$FJM@3WY zkDgvI@1WE{F1ag-0>M6i)D=Nf>e+#Y5dOrv$4~h^jbs_Aj2SkLHlj$hQM|5t$I>Ci zpeRae)jTe@&uKfRzgLNYDP5Hbr8W(C83CC=K<6$0mKC(zhZ=-79*2(v7~(zK@i zgCS4%E`cQa@b84wt>K7kx4V*YXQ0#_`(x%;kSob%J>x|GB|s*$Ksi-KdWbrDY7`bg zVBZ8=0NfvgKOjUSkx^qMi3Wi6P6Iw_7qDPFyZ53CfTT53XTS{!-90s)`>8I24Px#( zicx9o-Y!gFnIod=XBMY#Gu*F*Z;SiWPXB|61?cocIX+~yS-pa=U5nEx5ff9636!YAJP4{$A!@Y_Ge7{VbLi}x%yvgV?6+%j1`ICo; z$wa2l-|JSi+%b?(v4AN|%fSivxpO z2qD$wv{-pHEhH}bx*qN9s*~>L_!7)YpYCHB9g9f2gh9BLA}qHAAiIPffobZc;2atcfVcIUL9 z^D=&Re0lSIr}&8Rw$f3{t{JNMn0Gmy4)YXP*-bO=qbcVz3~$5UXBhsUU>Mb<(cuga z@j8qH$}>>_>pwad?l^P zZ;KrqPO+9#3HA3t_-1cT|pzEd{oPB(*Yns8yLmu?9g;DlzZ%W#dZ((BbI2?RkAgZq~lx2zRn{K8xNh zgADIO$uTLQKxKeE4v)2pdg4X$<1bp7bwu zDIT=a2VM?5b$%ANLnPAAz%SZ^cGUt-Cp^@mTzbA=MgzmW>YOH6sUhQq#QPM;*><-L z;AKJ1mQ!m!w*NE)B7R-b34G_y^NsRXPSC{@ih7N^_(90@rIx1} zXp0+!4ts|qK&=x2OSguRbxP^ZYe#~s>YQ|V*{IH;U!^|O0J*!{Ika+%fsR^9Qqh1kKXSJXFSD`I{cGu58mqq+44p<9 zP+gR-)F>PbD+RyEJFwKZ#&?RgfF53B?G16qk?>GM@zR!&Qz7 zU)U9)b5>GiFOn-sV+B2jm_;E61_;XillLuZ6zkVdpzFrxWjyIF;W5~PmCfwrbvJ4Y z=3XjHUR~)1R^Qa6+1KS9;Ai9%j?e+c;NLQIKu=bB3F+5nd^oyqNQ{gBhjX(=-dg5idV~*3`R_p?96Nkrdf-}TEEfH`;G7use2~kuDcZ%t!PBYFut|+}h?pDwlRzHA0u}DcU|Vc`QCY+B~PFQFmTONmf{0V4B}I zrI7$y(ml8|+32f~FZt1#1!&IB0*TG7gG4^Hj`Wye_nIF@kPV z!t_#8!tyGmR+jygQNk=`BtkUSi1|NG{cHQ|*Y#c3cU^eK^WN|M+=t)&+`oIGx7bJ7YWw|{#xvR13OhcX8$v=+AByP|$(7qom zShB?6o+|YmdVbZv*2Qc6`g|sDzU4b)ck=N!iDiGf^T9)2nsc{KSr#ww008A5a>XP7 z*3ZKMxJ#k|i+BPBGAi&mH7y)3PIg|rF^D}LtA=B^>H zHUJd&L`>yUdxfb(Dncy$7=fqcxNpsY;WsK1k%-COcmHccGt7+ZSPG78`@)P|-nRD} z0f;FlO%>>x*bwe&DQw5bykt`t8DW66MQ_3(RfpeCC46PV#CeRTUZ6j-y-??~G$uK* zf9^O3fNHetROwIC>T@|J4YFk>fv|HHbNw(N(rhO*8FDXCmwqKe`rRF`RfG1;zaL)v z8Ms#P>g=8_K!Bn0WR$ZQ+6lNi^bza;o1(7E%oVO-*oO z`#eE=Nd9CO_XzUn`U09bXFeA@3MHk=sW^0%xzPn-%Q7%(IkiWIL+*D^u~DFNF>AP` z0k@`e$bR1!peZ|MG1p~;Vawr`oC*V@w8#ZtAW-9ZT$bTjj0KW%>OZ0O!~!&*MDq)7 zk=vlcB+{elEDB07X84o6*RhaDc(lGOL*NIGUd|zFo+?0_ELjLFiHjov{^V)>Er(kj zp*Xa(_#AJ~SchPPp}EF$6O`y`6$*#dN-EQ4j-B6k%ABRz`Fnn9u& zPWLBweh**N=3-__Oo)%c+Hid?_6z*Xhi6)&l=ip+RCLV%=R%;=DLN1-5G##J4n&hI zBaIH7+Avl@h5q8!SaXT13vv`{H;8vZpgQ7hG(F7-rPTAZS~_kw%T<$DW*l;7+#_lY z9j?%#BTyJBv*;$#aHvd`L!g1JJ}&x|8r9OOYsL^>#QKgLW5q&Vl~WDXIpp)o4n$OD z-SgLPgAi|+vy3HW=qBil2TBPx@h8XFu@GNfE;dh*Ni;;!1>cZpJ+u}%V`UE6+kocK zr)jK#b-^%f({mt{;JOq(yH-dn>4=1p7d*7ZF=L3Lp9u64^qxMJs3;`|&@9W)UgLs% zfGJs|;sDH*nS@O_m8gc=m-&->R&vOu>s%0*1vnNNO~)GGwxU1TFO@)d(qpsthDa83 zN~pVxpp%p!M6)wCn+4-Md-jiVLS^-RdxW?FpKu^1U6J91!Y!o z$R8l?JY*PYJUuQrOQO}-yHrgSkw8!gUp+0uFouA~e;jjXYl|GqM33ob0as^~qOjft ziQIZ~kLb$FtAwbeaU{P0tv@YG(|p|D4fT54vdRQul8WxGf$$Hm$J9aOT%5%cx-GZz z7!Jz%|0^_tGu*dZ@}a*QsgDa%x+^$AC5B`fsx_|);i z>nvuUOW?lt=mNAoR+iRTU)1_*#Y+IgR=@Hb9h)^XH(r)epB4L>3Wk-K_*&N>a*Yv( zY%&kNy8vgwTCr#*(K@5}yO0=5R+$}BounE`M9fxn0Pav89>vl`DW^gjsl>^+D=%@B zBIgK2&JhuN;3HG`X!H&K6Q_U+kw!O`{dsw}GkbToJt|nO!uVz`7d+6#1yu}rG{&A) zrUBnHmL9+K1)HHWr`N(w=%~9Qvq##sUcrxnQku&9Zw4bJ#L`29ZxROIn z8deVpXAg-brKcFib2wxT!(X01Y!)9K=p8(pUK7!($i$Uu>Axj-mgU*z@)FGtl!~v7 z?0wWNX0^2cAf(i^7O6Vx%l3Dx<3U|lISkK(sUO;g6lQxAG6SJ{^!<^;Sdn2Vm z{n_!>9Wg6-+8;>?p;EC63w=H|>j~CY{7_#V6wJp3>s;Fv2;DEb^#dM5HEUHX`Yg$d0R0NO;}q$IxZxQLE+sI2Ij8J#223-Z`tR# zNr8?FdjA-O(G0bq_UtVCP8CY$ZZev}euyYCw@GtJ1WJ0vZPU4h=rP)hATZuCjh*;bmZ6Tk}JUg2a; zXk-&x&-du6-59)$r@y_Sy>dnZuQIy&WEH*gg8A&)BzMdX-o0t;yhHSpw}N+F+&|NB z;plzc13ZFf>HK9RQ03>J*WCG6<|aM7oe41YPY^Qo+>lMl8Fe2JaTD~hX2v;R!ME%9 z@G_W^(|6jumjxPwfvxP);w}bIfQ)H;I%#!^J9|%Vl9-NR9k$mj@qA1k8gHRCs?#%C zaa?$+QRcrg>9YYKhCPP3Plu?lAl9GGRTGyaz;!41Z~wiQ8o}HDN|XO)2AeVzaK4** z*!d(fcp;G}%wH=7yeGpuY&a-AXUAVhm#K+0Q83J({j|&6#i|N;mX3g19^)e;78d{S@7Pakg~xfN&j$o{K#J{XMFWP( zV%;^Pw(f;Man@qyUN8#=n11Kz;4M8iNQ}d_siXCGyDMG@nErSY;!~ma%~CuxPzT`d z$E4$CL`j3doND60!TN`*co~gOTHrygFN?Rr+k>ZfQ?Tv$$dPF)wjXM2H^H4W4DvHY ztrhc6F+jV$g!A;d-Md2GW>M^N)~A))Twa#Ob!%2i(MP^o{A zOG%crgG0Gp?}41W+X$KkFV z5N&34C1+7Vaay~96w0o!%>`-pC_8d=^+nlUqiguKJ|D@h!9U%i=%AhN-+i1{Yw~D! zn5lxF=g*}+h{0?lT>1mH53saOYcO-88Gxlyp^#Gt0}ESU5g#e zXE@IeudLv;RiW%1<`Qt|N;98zOjH;jWUn^IET#D}B2W~|=dhd990xAFO$Z2iY4HAq zSF|FA4l(D3KFQsCGf1*N*w=B9zvOc4aB=?i%7E7g69c>R!bJfEqGGd!y&t5uWb`;4 zyE?Qr*mSl}igQCnn}nQHRrhE`ld{`|Q?JzkZo{)VF%a?cLS9p1{j)uitkx1`w#Zj9 zuiML@3f&!RyXo)L;MBhmR0$V|3^G*Oc@B^c$|>8EO$3hTjeMw!^RL Oz{YiUR@^nLi2nmA5tzpS literal 0 HcmV?d00001 diff --git a/test/constraint/cubic_line_tangent/free_in_3d.slvs b/test/constraint/cubic_line_tangent/free_in_3d.slvs new file mode 100644 index 0000000..fe3e29a --- /dev/null +++ b/test/constraint/cubic_line_tangent/free_in_3d.slvs @@ -0,0 +1,397 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=00040016 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040017 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040018 +AddParam + +Param.h.v.=00040019 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=0004001a +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=0004001b +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=00050013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00050015 +AddParam + +Param.h.v.=40000002 +Param.val=-1.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=300 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=12000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.point[3].v=00040004 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040004 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.ptA.v=00050001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=124 +Constraint.group.v=00000002 +Constraint.valP.v=40000002 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/cubic_line_tangent/free_in_3d_v20.slvs b/test/constraint/cubic_line_tangent/free_in_3d_v20.slvs new file mode 100644 index 0000000..2717b89 --- /dev/null +++ b/test/constraint/cubic_line_tangent/free_in_3d_v20.slvs @@ -0,0 +1,392 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=00040016 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040017 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040018 +AddParam + +Param.h.v.=00040019 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=0004001a +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=0004001b +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=00050013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00050015 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=300 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=12000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.point[3].v=00040004 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040004 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.ptA.v=00050001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=124 +Constraint.group.v=00000002 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/cubic_line_tangent/free_in_3d_v22.slvs b/test/constraint/cubic_line_tangent/free_in_3d_v22.slvs new file mode 100644 index 0000000..d5ca7c6 --- /dev/null +++ b/test/constraint/cubic_line_tangent/free_in_3d_v22.slvs @@ -0,0 +1,392 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=00040016 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040017 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040018 +AddParam + +Param.h.v.=00040019 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=0004001a +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=0004001b +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=00050013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00050015 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=300 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=12000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.point[3].v=00040004 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040004 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.ptA.v=00050001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=124 +Constraint.group.v=00000002 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/cubic_line_tangent/normal.png b/test/constraint/cubic_line_tangent/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..394f8ff73f425202b8707b3862be09473e65dcd0 GIT binary patch literal 5220 zcmeHLX;f3!+TIBXQ)ChuluA?t)C2*m;=m9qN+}>#84eNkprF=(KxwR?kOUNqrNrS1 zs0gSnRR|DK5}6MU;1v~+5>Y}#5rF_Q7={9YZv%4IMZEWRec!tOzO|B-WamBmyzjH0 zcX&?B)-4Wds`FF<0BVk3+iwE^kBq;S72!(pzCG)?#b+$HD&S|WxA%G&VuK6nyX;EdwHah3m)k?r}; z(2Mj-EzeoS?*`k+FH$<|i>F?r=cvZQ@6umnU%IrT#H!NZ(4j*El2gf6R4x2}a;Vjz z`T?F3r(+X1Jv#Ny;iK;W(A*RGNxVarF0~FINP8v@86>J{1|CGMD4hfayK~Cp@n1x# ziW{0`i%+%MRB12`N&ZGgzzthvz&?}s3ApSC=k0x3Ky3fXIy@OEzT)rc084fLcuW>q zS9QLe>F;OHO|~~Vg9}<+sy{?eJKGLOg>(%(Ko^^Qa@?up8npp)ziblUwOtc;JCa(Y3FG zj`R(fvlJz!d@%Uh8^H}gN{Z)rqAR$2l@G6jH0}8~m?87&N0(N~RBbn-xF7DX^{7(f5UV)*qtCbL981FRbr#x` z*6j_B@3(jm*JMcFGHWOgElTlqn%WfosEU=qAJbhfM8h7Oh6MyBvFZh+G?Ac7<7A$I z8~CbF*`_b)2(BHv;mU93uPBPN<`DT;%}(m@4dIu_U3VYJR7EhL$S@TOx)V=YkXk-& z)u&8NC4cY^Cj`p$J@}M~TGNOtIte%BIiWc5l>t6J8A2mQf1NO&PiIurX5;H_oVhDK zfkpN~BntQ5=O1+OF1@8pWgA_K*6H@flTte;pa>oH2nWFGQre(Nf?ueP=gE5;*nqq* zlGyRg(8Qx0f|W73{Og6+xGm@GSgUX11&%0gCw;WIFf1d?r|)8$&L6W8 znqKkfP;Rd1Wx~1dO4vZ~a4mwpE4p9XQ+|@QzFhi64dpr{$aw$adzqh0G#?x4m9xfr zQpn^Fwl$PGMGn#bX`8VgopD#S_0%~r=gFF)xLSjfCz;_9Z*a^qnW_Ln)SMNqgI#-< z=PSgMmiS4}z79SfpoP#>wo_1FJn6`~ns_SL)ZcX{s*@RmXP(`j(VWoS(V{-4GmmDb zO>JEIY*;7mqiv%BV z1X>s_%1W-3sTyv*y~l*l*67)z(H)QB-wSdb9~nwc1~Is6gD$||Z%!CCuHz8J&fc}% zcQ&#JxWfUgPw)li@b5s)%AbXQR$A z-xij*lL3D&o^&AdLh9m?7sU>u%qx&zt`kv%$Wed0jifqr4sm_UNCwmU(!LA3O6zRl zHU3Y9q?F;2+t(T&^b9nmn6e~;15ImkMy&_Bq&wSeVMT!aG3m}MNwEX(&MmxWOVpo zJMFOE&*F)Oh9ZtJ0!=)3kM=bWE7>$?w7Ps7h%6!;IZNKa?6tHo zG|f}swKlI%GdC@GHP55MyhTq>eXODTzLp^EK&~@dy0l_d{r4mCM7rmzlvgh+`Sj6< zSIq1l$}6a9cyma6d0n^0zBD#w$svxQ z_z(KQL<0|56r?Mi@uu;bb;S4|g?mmh$y~i|So*pbI7MM=@ub1m#&ewgva~%hW5};f z7T%^=Yz6_6Z#!=whSI1D7dKiLx_aY;vk}ZI4Y7lZhU4VbmauyDY2}l7y~fG6sJJW5 z6U&6jP@Qb#|u?Mb_PC3kiI zEo049(on~167$q(72TkOra^tbi^f^(l`#8#ip+n9h1tvm!S03Gn!|k=aAvgS{f@M? zA)E*m>Vkb0Jvq&L70QhG>^o);9>>QK>$v$L{InbX&$0Y1teWl@EeDD^J`65C7EH80 z2aA+@q5YGdm~L`hCdn?bNEq%zbkjmG>GB66qiSYbiCu#pKLmDD*sYGFhv+RUTAMRE z*woPv1a}FfB_Y-U`EC8fU4f(O=+85!r)d*gEF;D#5 zReZt*03qyX|56-yOr|hkuYwoJyQAh-slWj>HltPPuMVoO(1?ab(5xxEoU24r>UUH zDhSYkO#qBw{g}S(KMA>MUsezNSdI$Nf+?rLzlk@2uE{04!6KG;r{|X*Z*nUeJFSbT zimjhKALyHlND4GT9p6@=!oXeu7>M?xxvTws%>n}TOcdBXG6N)2&A=;D#SHwkM0&hf zAtU$oqV}p?yM1^0;%KZP4W20aXP!v1IlcJlGQ+vN(!_l@T8b3U;K$TlbiUPS zo@~Y5axC4J&Gi1}^u5~b*3xIYPU->v{3fc_`>kDPl)<%mKSVNp1R-~ZbS^RHx!FjR zKwZ=Z1%`EburUvy^#oDb1v(B>nzPf7h6W_w&;c?>G~o33rwbYoJN}vdeubLCu236C zZyc?p|LA<)FT1pcWSzl)J=$T#S3DMV0H6l_Fq{}FKy`-Ic_MpVplQmdYkL9O->|TS zIe@LnVLtxN2(Z}!L{S@|O>E!x?AJC?fOzQ7T;qYUR>8LNt$!jOEHbX~p#b0R(Gveb zGF;%~#H#Tj{+2Bg_yi5#3ca4D5Tu}&md2@|f&Gnk=vkAaLaFz3D zwWQGQ((hZi!{W1@M)l!8 ztQXoIdM+?~DlE;htvciPrSQA_k(Q9LCuX~UtX%y(-|l(wyJz8f&F#xOyCju1y=xkJ z-STSVTN`t`r^rNjty*dvljIxG{=jLV z8v$6HEL>gG|?-TE&Y;)!ki>dAL>y`rO1<``Xr&2mB}l_1$O4o0G}jR6s@g{aXRHQ3Jp_)Mw%BKVg+~4l%oXM; literal 0 HcmV?d00001 diff --git a/test/constraint/cubic_line_tangent/normal.slvs b/test/constraint/cubic_line_tangent/normal.slvs new file mode 100644 index 0000000..f8a534c --- /dev/null +++ b/test/constraint/cubic_line_tangent/normal.slvs @@ -0,0 +1,446 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040013 +AddParam + +Param.h.v.=00040014 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040016 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040017 +AddParam + +Param.h.v.=00040019 +AddParam + +Param.h.v.=0004001a +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +AddParam + +Param.h.v.=00060013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=300 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=12000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.point[3].v=00040004 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.y=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040004 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040004 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=124 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=1 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040001 +Constraint.ptB.v=00060001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000004 +Constraint.type=124 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00060000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/cubic_line_tangent/normal_v20.slvs b/test/constraint/cubic_line_tangent/normal_v20.slvs new file mode 100644 index 0000000..c141192 --- /dev/null +++ b/test/constraint/cubic_line_tangent/normal_v20.slvs @@ -0,0 +1,446 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040013 +AddParam + +Param.h.v.=00040014 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040016 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040017 +AddParam + +Param.h.v.=00040019 +AddParam + +Param.h.v.=0004001a +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +AddParam + +Param.h.v.=00060013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=300 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=12000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.point[3].v=00040004 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.y=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040004 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040004 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=124 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=1 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040001 +Constraint.ptB.v=00060001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000004 +Constraint.type=124 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00060000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/cubic_line_tangent/normal_v22.slvs b/test/constraint/cubic_line_tangent/normal_v22.slvs new file mode 100644 index 0000000..049bd73 --- /dev/null +++ b/test/constraint/cubic_line_tangent/normal_v22.slvs @@ -0,0 +1,446 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040013 +AddParam + +Param.h.v.=00040014 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040016 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040017 +AddParam + +Param.h.v.=00040019 +AddParam + +Param.h.v.=0004001a +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +AddParam + +Param.h.v.=00060013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=300 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=12000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.point[3].v=00040004 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.y=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040004 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040004 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=124 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=1 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040001 +Constraint.ptB.v=00060001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000004 +Constraint.type=124 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00060000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/cubic_line_tangent/test.cpp b/test/constraint/cubic_line_tangent/test.cpp new file mode 100644 index 0000000..4dcc334 --- /dev/null +++ b/test/constraint/cubic_line_tangent/test.cpp @@ -0,0 +1,33 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(free_in_3d_roundtrip) { + CHECK_LOAD("free_in_3d.slvs"); + CHECK_RENDER("free_in_3d.png"); + CHECK_SAVE("free_in_3d.slvs"); +} + +TEST_CASE(free_in_3d_migrate_from_v20) { + CHECK_LOAD("free_in_3d_v20.slvs"); + CHECK_SAVE("free_in_3d.slvs"); +} + +TEST_CASE(free_in_3d_migrate_from_v22) { + CHECK_LOAD("free_in_3d_v22.slvs"); + CHECK_SAVE("free_in_3d.slvs"); +} diff --git a/test/constraint/curve_curve_tangent/arc_arc.png b/test/constraint/curve_curve_tangent/arc_arc.png new file mode 100644 index 0000000000000000000000000000000000000000..c83e0a8890f47f4c2cc4ae968c82f58c611fb0bd GIT binary patch literal 5027 zcmeHLdpML^+rMX;ks&!{l0rJ@U?|$OOJYm4+YX%>a(J9#HbONuK*N}>@xfAK){urrk>+(cf^O){9$Hz z+n+P-8p+JGu;}+rt1|uCd)prRd?Rg?@37zRTnkwf6yiK~425GuD1a&r^Vi zahqWZK+Fz|0Ou$)V6JD8K~56~ctE0pNg|I3l8R_^XQDJLwfGMijbwFK48Cf}Jv}*S zl);{PJkTwe?)mr;yxo&q9bU3ccyeNdL~Ur?J<=$wXCTEcw}c zrH^!-Yy*&U3H|g<>+?Gm$9^^TKHZ(4f0Ycpxtij)?s&MxhE3pYn{ZrK)Y@MXzFU@^ zn0~X(4VX=f^l+U`OT3MH&6xyP<7a+O>z9cP;|v4K(fs}4Wv^Q$pr6xZf$Q8g;BJ=5 z9IViLM}*#YhPZXmg0i%T&0+i>eIm7?z97*1sBQC^`r{wy z379&`nq_{C3^A@p*k`ogCoM1D%ls360Bfi55yf;M#sH_vh-XasgXxflDmUg_LBT%7qFd zvt&V5B8Br^Bn@sLTTL_(##6b1CPo$MhD&py0t^- zRlyc;9Ts`W)%I33bXeB-p}9+IsKD8Y^&}!2KS|D2MO(PAk;|W~`oVC?{E&xK=-1bz zPgX6E20aorOW*uwxUd2rOG4K3#DE{;p}Ar!Y#{QaVy^9=eXs<`%G2%LqsWkhTDO~W z;ApduzGEuML)3K*Eq6$#L;n(1xg}~(WO3(zToRp2*U&ye^Yb|a=ivg>=Qq<~+ z78`K+F&Y7nUi;wolCUrl8(0}nA+&4|ndHoxXyRjfmFJ*8j@N2VQzY^{h|(Y7OQOn) z%+*CS=IG!t6XCD7(qOED6s;^;5si5MkArtyH1P-=IW{Br0sPUcN1X{wG!-G1fN157 zg>!i8K9PdfqKg;mXy(I<;QpG=coy;A$`m}09?81v9CoAZ_0l^~udnzS4N26@ei{u% zW<@1M{o|P`z^CHN@Cz=JcP!<74c`(Ib{K16#5Z#>Zjx{*9%2 zo$CCd_UGxw>e8w2jBCStCfNj&Sem@T=$ldXo`-$Lw|38g$3tARu^&6R_R~e~-aWM$ zj^p;%t;#ylY(vRRpWtVYybWiz!q%krUm5mJEWc@@!y)%83r7=iV>E0~rl7GmLs6?% z3r23`P^b=a*3j)BV7Xs*Jv2RWW=V+UlWzhSVrz`m!JQ^g6p3i7MK;tMiZ2}LXga^4 z$4MeT{`%aI0k!b5(tR3m&;1ka$=tM6RvJdqd(~)RZO*CCeVOu?@^T(LTMDN>(PNi` zYIP>h#hN4rn2WymiMd!#C$aK|Iw)TfFLv=mgDDm@QJ2LE&Ut*k7rNub4@Ex`P;NQ4;V`CDAd3Mv=B1ee<8WyCAqqMo6KwB;s$Phhz18O40t?S5GVg}i)$8YyngSnvbUqF3zJ3{N`y#}e z9S23+nk-)+&8$hp_C7|fJcVXZirRxBsh~X$)S*JEycn03>&uDQ3SxAXPnjX4%F(@k zLG-_`NcW0LGld;X#nCItHHvJ~N1`UJ$Sv^vODaCZIfF{{!;WYJOE<#P)SKM4V>$+X z%5=3IQYNw%;^hwb0ZEhHBx;kKEex4rHA-=06It{qZwp>mdDqRCF*4fjPRs+fWn%j# zJ>*lS=oZ)zN9Iv4V>L#oJYomD}Jk>LES6u@qNMt{}EFk*N1t+D=0AF6{PV?=y2-9MbuARf2Cs@$%9Vm0wtX zDh_bLCA3_}R*!^P5~G`P-6VN-XqEqT5$zh;#I(tXj_YO||Ff9}#im&4qHAQH4TV-< z>PhHdJBpPmd56wzIjBkR2joVw2HrwJp6#SBJGaU{h;#POvW>sBcW!`y2wv#ID`D1* zWVC!IQM%Z~li;(<0b4Y@;ex9t3O*@Ze(^yz#I*6vD$fsq5Q~(vK5>*%b3(esGRpd& z7I=%ylT|hk3+(&~haaAgor*VF0O}OlYM*y&1`;&w;ujDmR^Tc1X%U4=4*AnY@Ovq8 z`@4+3AGValc6Cgi$#!@p7#5_74jcvUs{tom^u6o}C;lKwOZXmbCG&(Ig1q^;^=o5Y zV6`jaR}AB3pl^&A@v{kx*O9D1&-qWo`?9#~x>W=p_9smHpL3i}A|ttSz6{`+in9t9 zlPS8*ugsX<*v0=^CiR*2AxXG4u>#cI-{+3xp-%6H(yz#~=nhzw@5^fh;JbyA<=)?) zATg_uP-_@B=2R%y;Tqeu4ilx9c6bO^-C<5C&_Qc`RcNpxo%j3H@mzUT(4{%%KIQ$d1jJdPD<;@{4EKpDu7vP&ZceQk2dymu6KofcK=_v zvwv`DE5ntEHR1eTW=p0>KEE!TW**lz zf8$mj%`f>4WzEp1{<PPCf6ssD ztya=-a|kIcYZh`}gqJA)ZM)n36o8>8CY6b?MKQ}m$zh{7OZk^lj5qM!$1?yk;j*~2 zWzwK*HKlM3`O42lx{)Qz;Xf`8K$!Phj>sFE~27I#D z6tJ?1d9;$HDo~Gaos-FRUf%U|WW+NVly{e~>KgF4y5F9LMoUZu&b2;pqN&3Ww_B`} zn?5q|Vnq}UI(E+>8=ttkhISMZ;AyNbF_Y^Qr>~4+d&hnUOvd22-NhfNF!bjkR7t(D z4z)OGoH{prM7Ic)a>^c&KH)*JW}sY`qR3gCclBMbhZjF^&+wQ&@YLq1(BEu2ujNdJ zMorw{$#W?vPU%=PhsY?i$byvJM8;WBdyL3%6}2Jz2fb%3H=Wt=hY}1iN~%j6IxfDg z4l$bV2sz-JyBhVdReFp#FT{dIearJ$gRTdQ1xbViMJUQdL|LP%?F3R z4F-(XD8(71JmW?_%i2|&DhwEU!!TEysS8efa_v2rGrg6_i#$r^r)F!nJ4|@w$4|Gt zd@dE#+OE`L#%B3drb+jwRp<>=3?`_<9e&V!&Y)+In~I;>!BCiJolz!;G}7x$f)P9X zSz4?^^tGJ{<5p+8ubQ9DF>6X2yqC|e&FN`weZ4d07EXvV-S)41d86E8C@;@eM zUBX z`Ys-As_OF2dzsvXq;X0|{+BlX-+NE%xdpvGI zee}Ru{jQIS?TaUULyUs-%@49wXEJlf?S%L9XKqaaF5M`}VZ`03^99{GuBY9tS zaJ(d8HGY2O1CJ)V9j8W}&W*+oD^%~^+}o}t+-#iCoc`lz@rbz~oRQO*r;uX|`cgS{ z_kwhO&dDgNVlWK7rw`#Ty{>w_(U!NqnV3v~qyzWN0@i(Btj9mK!k=Fs(plgXsV~f* zi5q1Xc*jgm)R#;(&M<^BNewxBsa`Ku$94fGCgZ8EjGh0vzpG|srwQiK-1zlJ(4TLx MYrB&F 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 literal 0 HcmV?d00001 diff --git a/test/constraint/diameter/normal.slvs b/test/constraint/diameter/normal.slvs new file mode 100644 index 0000000..583b3ac --- /dev/null +++ b/test/constraint/diameter/normal.slvs @@ -0,0 +1,296 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=90 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=10.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.x=5.00000000000000000000 +Constraint.disp.offset.y=5.00000000000000000000 +AddConstraint + diff --git a/test/constraint/diameter/normal_v20.slvs b/test/constraint/diameter/normal_v20.slvs new file mode 100644 index 0000000..7427519 --- /dev/null +++ b/test/constraint/diameter/normal_v20.slvs @@ -0,0 +1,294 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=90 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=10.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.x=5.00000000000000000000 +Constraint.disp.offset.y=5.00000000000000000000 +AddConstraint + diff --git a/test/constraint/diameter/normal_v22.slvs b/test/constraint/diameter/normal_v22.slvs new file mode 100644 index 0000000..81a24e2 --- /dev/null +++ b/test/constraint/diameter/normal_v22.slvs @@ -0,0 +1,296 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=90 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=10.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.x=5.00000000000000000000 +Constraint.disp.offset.y=5.00000000000000000000 +AddConstraint + diff --git a/test/constraint/diameter/reference.png b/test/constraint/diameter/reference.png new file mode 100644 index 0000000000000000000000000000000000000000..09a3f28ea3d4013f8a291d7f5269b3b5a9240f2d GIT binary patch literal 5101 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 literal 0 HcmV?d00001 diff --git a/test/constraint/diameter/reference.slvs b/test/constraint/diameter/reference.slvs new file mode 100644 index 0000000..b403a72 --- /dev/null +++ b/test/constraint/diameter/reference.slvs @@ -0,0 +1,296 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=90 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=10.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.x=5.00000000000000000000 +Constraint.disp.offset.y=5.00000000000000000000 +AddConstraint + diff --git a/test/constraint/diameter/reference_v20.slvs b/test/constraint/diameter/reference_v20.slvs new file mode 100644 index 0000000..eb80eb9 --- /dev/null +++ b/test/constraint/diameter/reference_v20.slvs @@ -0,0 +1,296 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=90 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=10.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.x=5.00000000000000000000 +Constraint.disp.offset.y=5.00000000000000000000 +AddConstraint + diff --git a/test/constraint/diameter/reference_v22.slvs b/test/constraint/diameter/reference_v22.slvs new file mode 100644 index 0000000..4f8455b --- /dev/null +++ b/test/constraint/diameter/reference_v22.slvs @@ -0,0 +1,296 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=90 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=10.00000000000000000000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.x=5.00000000000000000000 +Constraint.disp.offset.y=5.00000000000000000000 +AddConstraint + diff --git a/test/constraint/diameter/test.cpp b/test/constraint/diameter/test.cpp new file mode 100644 index 0000000..7e2a06e --- /dev/null +++ b/test/constraint/diameter/test.cpp @@ -0,0 +1,33 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(reference_roundtrip) { + CHECK_LOAD("reference.slvs"); + CHECK_RENDER("reference.png"); + CHECK_SAVE("reference.slvs"); +} + +TEST_CASE(reference_migrate_from_v20) { + CHECK_LOAD("reference_v20.slvs"); + CHECK_SAVE("reference.slvs"); +} + +TEST_CASE(reference_migrate_from_v22) { + CHECK_LOAD("reference_v22.slvs"); + CHECK_SAVE("reference.slvs"); +} diff --git a/test/constraint/eq_len_pt_line_d/normal.png b/test/constraint/eq_len_pt_line_d/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..9daa892bd79c2e83b96f006078e05c37d84551fe GIT binary patch literal 4407 zcmeHLc~DdL8vO+l3bM%V0t#xyzDFQYt1Pm(fPjElH};T<0tGQ3J7G!C%3vu>A5Vi; zVSGGLB9W*s1c8vNBB(4{(Xa=25h(@;5+H>b@)86~#8BIr&h(ErlgypDx%cM#&UeoF zPLi>2uao+cl}i8s>MqU>`vFk!lD?IdBxkCFaytRgoOW^8aWMYUP*-mxhoyI>_f*5y zEC11=_nOD<(+#S0Hi$K7Gf#Wl8nV+=+i{OkbOb6tSc&89s$~91Z)}Q?cAng>3JAH( z7!&~5tqQ8Z*bNHe8n$!nBaXh1~q^ zsL4qqt2|K$bM7Tx*5+FlGh}t6F~}e;icM`hE;!-duTD~i{Z@6E1p`4u2)fv0AX7KB zFh$g42*6G^xeao>T88yNr^6f`)M{wc>(7A6v9x!%5E8cdZ~R0=Aj>ie9sz|cEQ35T z>>D!ka z%EQ0`=VD;!i$(l1G73Ci{C8%fKAUPkM0@L3 zL4rZpzryGs?;#JonLTOv7(g%Ak!K>1C5whf01K@-J1IfE18fcfEM@^zGV1*_fXEEI zR>WapGp7DYA$|o=tCgd%x4LVVev|rGOcOMp3BdYyHLhBIk3Njpp6(m?FnlHWMR~?% zrWC^bJ2ccm#OHH;HC!J!dqHL>^1ZY6W_Xt=*xek>)|_j4=3=u$v^bPPQ)p^?*yNpP zlp^77?#EaF%qBM22R^8R>wl6R+{T$X9ow7gH`$5{C|i=3VB7S78)=SNsu48nUErSI z+LsYR`w8+_xYoAoBDiLf%fP$Bc{~&h&Z{lFQ19YzrwV$yZ(mD9p!RH#|gSR z$nsYKU8>mK)fe)=YdN(p7aLjL_vFEkySMq_bx>E|JPa_B!u?FwqT0?fS4FxuRP?Qu zPNnu*bb@UIIGJvYeD1B6!=Ti%347u|q{*dTr3>*^5SJk{N$y(;cZI2BBgmn@IpHAXo zK*UM~RpXaVqO-^=hz-x8A4rA`7hMy7t3Of>*N0$kw|j1?AbUEe%Udx*eun55p1q^K z&1xbdlY`@k#@_U;-*p9%y$cIVf;A)Kk*lwrY9;7#p5@l^^hXvEr5}2#eEEV`v~aU@y^ly2U`^&0@uJa* zt6CBhzU@l@{V>ZYv_=lD2O|kFpSZd~Ls*B8hUxEJ+w%~XVX5>y*3hIIVtklM=9}vW zxi7b+jAnRPW^82#U$7ak0qGElvpCZtCtzHtY;|-wbDU{Y(BCVBM05TiR*{oQu2x`aG^n)v}fb_hySSwFbvqMif9(V4mygr6FU^aDunH z_1%h19nue*6IUEuXQu?>;WowBj zkC62W>9Ko%O1t=AUVvJpq>98&A@=gv-ceMltwu!ezXRw1WqSha{)@E7sQ6BZtSy0a z&FXDbvV%U*-0<$Oo|>0|1jY_n|Imudb^uL^La^#pp84t&hUFCb3L?36+2?JhodoB6 zcJ)WKiL4c%ZzWey*cF!q?aa#90i3@(1^an5hPWehg;z^etU`*}EjOFdB)%enywZw_ z+1+f`e2w(gdSxtfx=vZTB{+u6!O3G^FeYx&kNnK4Pa^G@I7d>l*N!Qr@E9ULyE1`Y zKO?)VqKSmLA*8sL8MX181W{c61iSiy6^Lv1xJ}`X+cU?zJ4X`)gZyiCe0IMd9!XDP z(>Ptio7pxV^s1B$QOX$aaWE^M%RRa+mS5FzybMn-;@6gwl!K$f_X|#LI+{32vk`;N zVia|CFGH8kt{T(IQw8zHfy~diCvQcte9irKvwXRgNou%(EGj)q+}8j0ny8vCz99l5 znoU|>ILBw+1p^qA;%lD}#&~XJetJPx>Pt>VUpnH%3(;Fe^gkoJPmQ+=k5nfKH+CNYJn@t|f;t6Fafgg7_=(hT;#<&csYu%U{uq&JWk_Z?2BCmY}BOY m_sUjg9m+SWKkqLCF$mt^KW6VyvsLnk2yk)S>u_TyHtm1O@CZ== literal 0 HcmV?d00001 diff --git a/test/constraint/eq_len_pt_line_d/normal.slvs b/test/constraint/eq_len_pt_line_d/normal.slvs new file mode 100644 index 0000000..779430c --- /dev/null +++ b/test/constraint/eq_len_pt_line_d/normal.slvs @@ -0,0 +1,364 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=52 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00060000 +Constraint.entityB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/eq_len_pt_line_d/normal_v20.slvs b/test/constraint/eq_len_pt_line_d/normal_v20.slvs new file mode 100644 index 0000000..6ce37fd --- /dev/null +++ b/test/constraint/eq_len_pt_line_d/normal_v20.slvs @@ -0,0 +1,362 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=52 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00060000 +Constraint.entityB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/eq_len_pt_line_d/normal_v22.slvs b/test/constraint/eq_len_pt_line_d/normal_v22.slvs new file mode 100644 index 0000000..78b22b0 --- /dev/null +++ b/test/constraint/eq_len_pt_line_d/normal_v22.slvs @@ -0,0 +1,364 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=52 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00060000 +Constraint.entityB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/eq_len_pt_line_d/test.cpp b/test/constraint/eq_len_pt_line_d/test.cpp new file mode 100644 index 0000000..5e9db1b --- /dev/null +++ b/test/constraint/eq_len_pt_line_d/test.cpp @@ -0,0 +1,17 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} diff --git a/test/constraint/eq_pt_ln_distances/normal.png b/test/constraint/eq_pt_ln_distances/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..4d040037bd765eb2d1166acec12fd7730eb4b5ca GIT binary patch literal 4363 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 Sy9<5f0Nb5*IOc639QzYcFW(CQ literal 0 HcmV?d00001 diff --git a/test/constraint/eq_pt_ln_distances/normal.slvs b/test/constraint/eq_pt_ln_distances/normal.slvs new file mode 100644 index 0000000..6a196e3 --- /dev/null +++ b/test/constraint/eq_pt_ln_distances/normal.slvs @@ -0,0 +1,389 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00070011 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000007 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=53 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.ptB.v=00070000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00060000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/eq_pt_ln_distances/normal_v20.slvs b/test/constraint/eq_pt_ln_distances/normal_v20.slvs new file mode 100644 index 0000000..2d878b9 --- /dev/null +++ b/test/constraint/eq_pt_ln_distances/normal_v20.slvs @@ -0,0 +1,387 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00070011 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000007 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=53 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.ptB.v=00070000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00060000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/eq_pt_ln_distances/normal_v22.slvs b/test/constraint/eq_pt_ln_distances/normal_v22.slvs new file mode 100644 index 0000000..1e4968b --- /dev/null +++ b/test/constraint/eq_pt_ln_distances/normal_v22.slvs @@ -0,0 +1,389 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00070011 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000007 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=53 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.ptB.v=00070000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00060000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/eq_pt_ln_distances/test.cpp b/test/constraint/eq_pt_ln_distances/test.cpp new file mode 100644 index 0000000..5e9db1b --- /dev/null +++ b/test/constraint/eq_pt_ln_distances/test.cpp @@ -0,0 +1,17 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} diff --git a/test/constraint/equal_angle/normal.png b/test/constraint/equal_angle/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..3f81a9543e93bd20eed1bc2f27cd82c6e4962e4a GIT binary patch literal 5267 zcmeHLX;f3!+TMf&8AKomA}UxBxHeHxO8^Oj11J{+EJ`9W1O-2@VGsh8K_J9|q5`G1 zA}TT!ks%>a1E>s%h(S?P!~_&cfK&;A2uhfV+yjcY)LuXDkNe|W>su>X=bU}^Is4tu z^PK%Y?@o4e*{Q0ms|)~8b=w?`h@-B{Mo)X51w6u{)0jOE#@p6yAf?MiaKqRBcEfiwHT zKR0=&KEAYw5qSiFyVKMdIRNrCpn?2gDqyuUK@OZ$LIbjCA_Axz(E+#v*9LYMnJ}QJ z`CsZ3x2|ItTUCkHPe|bO_10I|c2vd9|77NtKfQQ$^KgA|aIlPz4XM6)(>fLv!#|d+ z{=WrlXM2W^Ru|!0hEFeuKJcg@{_qk2zB2lE^C8DSB#kHoy*2aG$9of&kH~`)n^^B* zU{;@@UHn3na`c7+jCYd0GJLjaNP$En7f?khxr6$*~MP57QpV9Cxw2CxkjRyils;(m-oEh0FO{$ie*prwc3li#eSr{mQyJSw)&Sse@B_-9egYyk z7FPzkzWPWg7ja>aEinC?=7$-bD-oT^{D{`aZhtA6$#OIVZj8IM=Boulxa>(x659iC z?(RIwpM03VrA5jq z1Pp_>gnJeMo#c6xKUoQK^oPA_VdSKbgnBH)JIDYtr*5waz~2usw;65d@L(NTi5pVS zP?YtN%GoQnb)hDh{z%#{Z&&@<0}&pt3I4!1@?+rVaNea_f(pRc6Pjg z-}WdJvD}^bs4B_sf3Co*B-me4AD!t5j;pj^=(IWDB0=3mC z@<6oTB*V;lb7PnnD+aC|cm--MPUdcY+%~?;-;ze~<}XsgJaim-h^-I8B@L=2oPKaY zSj?#RvBAy^l2TFl>^1_+!BUCmSSw-a(!6!C**@MXP&743O4@-xoF`id0I?QzvtcT__Qidbq;W+=!a2d%S;m$tFsK%KQh0+uGHQS-RFWKgg~Q z53a?I_}zh?s)CkP%r-Bs=;f&ajzv~r+&GD?6}vaQ@gZCVV+XbO{n&+CiF0GaRnAx{ zRVc8vo+9yXO^)=(O|2;CLKE+H*O8uD4dWTnbD-I;3PseMU{cIU$Wj9u`8y5#kb?`Q zlog8TFratsz5*wvY^jAn!6>1lA37ehx~t`8PuMyO z(VlvDx*1zbx{I(CBCyiylFx{aUn)v;o=E}5teDop)<dTCqCWgkmgP6ABD=l8Yk89uWi=`>`B5q4?Nu>BU)EeiWwXHhtpA50nP zxvpPqsTADCShr7YuCdW@TNLFy!8axodJ6#yQ_+LoQb=_zTZyAr=4u4x#s^E-y!eSW6UmTo5)Tu}Et1tTMr|`}zmdf9xg?P?iv2Z&S|&zVNp>9yvh zii=R3ksy2GImICcREAmI8VjuyMxnFbjqy@TcBWZ%VKmVeq;Yoc?wMMN=Ka3gKkL`o zN;fxlZ}*oIBJsz1IQZq=9glWas~IeR*}w6DjQsP>9f}E}0OZr=EpiyYiGFkTtZa-t zK@$=`;Nu#~ZS|BJbtaS(DG0LJQ-nv0*&Yk=dYVgHN5^xy(R=W--n#4DQbV|a8L5bl zEM!-ULmz=yBYL}5E{tgfHRZQeiz7PcnoeCcczL|jTCj{MBiFt14N0;ycKNoj+GO;%@J$u+ADq<7zh7C^X6(h~TJz|6{gIDKa0_(Cd2`h9e)GXy~s2`FYzs1mk7M~tv!m$k+ zPZ&<=4DPXKlaruH10UWmMRva#qXwDy$HaQ;fNW#B==ns!9bq=ZLmzWM#TxM0M7oGS zv9@2z38{4;t}iSrN8-SgKc&$$xVE6-jj+vTG&Am6m6F{ITzh*prg6*66;gIqVDdV! zK?A>7_;b6)E>N2L+6+JJRY?S7v*>gyyCzqz3cx_g=;ZMr!5XI{tkX;9+|E|tj)ZM0 z?Iwu`I;<7lZk~t;>DtikUFUw^z>BG3cjgF+Vhq&y4J(VF-vCraJ zr0qe32&uo~Qp-3hcT<82EnlBscgfY#rL2xWjb2@R-F*7`O0xNQkrJw1GZ7&@^g2Ww zbQIBehIT;-P3Ukjk&hgG0&_>rMy!7LC?e{z0(o^P;)chB_epRf)KT36Icq>RXuv*i zy(1FMI03g60RH@kL_F#DRuxI((_RSO)^mpI`+AOm@e4B-##mr! zO=$t^o>3Rrv%sU&RmIEXfGKj`!hN>*;m)lMx`43zgVPcv-8Ua9opT?5fa?=O|F3DB zBkuouB4S}E_rYb;>u zR?co0$j|K=%oUH{S8d^U6oqR6CiCCdvhSr&w~=q=Y=8qyDTn!1K2MIU+P|6ZxdKzM zBq$_=ss@C8=5v>xnx4m6a%T96T3Xg2(p7k>>azXrQ{#t__S!&NIKw;|RNZt`QkHIb z1LWu*f_o4JYlx=T_JiLFZ!vWPdu|xDqJgLxa%ZJN4~p}5w)u;aMmN>~vP7pB*}Y^$ zFBzB?Z#Bl7AGT`k~UOv$rDrnmD zrit`cp3L*)Bu41%PIJzGod0)qJKyOvjoAe%C1{%7JM4B#T29<36$R9_u8!?3VBzv! zKbd?T)GMv)oVpUL9~++4`?xJm@}mUR5f@>VW)nPCx&EzG9v82*sIX*NTk?N4{1%ypy8dC z7nh!9xt?}*Hx)GMpw!08eU)F^ z=*%V5gI?^j;wF!Re6LJf29hvDV6o& z-t8Uuf`c&%An;p>;hos6Z!^pJ2Iarr8+D(OIhQ`Glcd$i?hfB;N=uV;)Jf_qJLyGn zD*{-NDQ_cJfq}WbsbSp(Ir;N-`j_RG&!(?W({uZb{HC4 F{1e^z4Lkq< literal 0 HcmV?d00001 diff --git a/test/constraint/equal_angle/normal.slvs b/test/constraint/equal_angle/normal.slvs new file mode 100644 index 0000000..b1d538f --- /dev/null +++ b/test/constraint/equal_angle/normal.slvs @@ -0,0 +1,463 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00070014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000007 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00070001 +Entity.point[1].v=00070002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040002 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00060002 +Constraint.ptB.v=00070001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=54 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.entityC.v=00070000 +Constraint.entityD.v=00060000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/equal_angle/normal_v20.slvs b/test/constraint/equal_angle/normal_v20.slvs new file mode 100644 index 0000000..25b9634 --- /dev/null +++ b/test/constraint/equal_angle/normal_v20.slvs @@ -0,0 +1,461 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00070014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000007 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00070001 +Entity.point[1].v=00070002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040002 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00060002 +Constraint.ptB.v=00070001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=54 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.entityC.v=00070000 +Constraint.entityD.v=00060000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/equal_angle/normal_v22.slvs b/test/constraint/equal_angle/normal_v22.slvs new file mode 100644 index 0000000..6fb46d0 --- /dev/null +++ b/test/constraint/equal_angle/normal_v22.slvs @@ -0,0 +1,463 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00070014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000007 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00070001 +Entity.point[1].v=00070002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040002 +Constraint.ptB.v=00050001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00060002 +Constraint.ptB.v=00070001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=54 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.entityC.v=00070000 +Constraint.entityD.v=00060000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/equal_angle/other.png b/test/constraint/equal_angle/other.png new file mode 100644 index 0000000000000000000000000000000000000000..85bf8263a18ba334c57f0c7a04eb833f4cfbc687 GIT binary patch literal 4914 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 literal 0 HcmV?d00001 diff --git a/test/constraint/equal_line_arc_len/normal.slvs b/test/constraint/equal_line_arc_len/normal.slvs new file mode 100644 index 0000000..1f7869e --- /dev/null +++ b/test/constraint/equal_line_arc_len/normal.slvs @@ -0,0 +1,367 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-4.99993226121819223096 +AddParam + +Param.h.v.=00040011 +Param.val=10.00006773878180865722 +AddParam + +Param.h.v.=00040013 +Param.val=-9.99975209012342425297 +AddParam + +Param.h.v.=00040014 +Param.val=9.99968435134161737210 +AddParam + +Param.h.v.=00040016 +Param.val=-5.00031564865838440426 +AddParam + +Param.h.v.=00040017 +Param.val=5.00024790987657663521 +AddParam + +Param.h.v.=00050010 +Param.val=4.99990506249655908277 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=12.85283693258537773829 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=500 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=14000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.normal.v=00040020 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-4.99993226121819223096 +Entity.actPoint.y=10.00006773878180865722 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-9.99975209012342425297 +Entity.actPoint.y=9.99968435134161737210 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00031564865838440426 +Entity.actPoint.y=5.00024790987657663521 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=4.99990506249655908277 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=12.85283693258537773829 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=55 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00050000 +Constraint.entityB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/equal_line_arc_len/normal_v20.slvs b/test/constraint/equal_line_arc_len/normal_v20.slvs new file mode 100644 index 0000000..9f4b27b --- /dev/null +++ b/test/constraint/equal_line_arc_len/normal_v20.slvs @@ -0,0 +1,367 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-4.99993226121819220000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00006773878180900000 +AddParam + +Param.h.v.=00040013 +Param.val=-9.99975209012342430000 +AddParam + +Param.h.v.=00040014 +Param.val=9.99968435134161740000 +AddParam + +Param.h.v.=00040016 +Param.val=-5.00031564865838440000 +AddParam + +Param.h.v.=00040017 +Param.val=5.00024790987657660000 +AddParam + +Param.h.v.=00050010 +Param.val=4.99990506249655910000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=12.85283693258537800000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=500 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=14000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.normal.v=00040020 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-4.99993226121819220000 +Entity.actPoint.y=10.00006773878180900000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-9.99975209012342430000 +Entity.actPoint.y=9.99968435134161740000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00031564865838440000 +Entity.actPoint.y=5.00024790987657660000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=4.99990506249655910000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=12.85283693258537800000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=55 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00050000 +Constraint.entityB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/equal_line_arc_len/normal_v22.slvs b/test/constraint/equal_line_arc_len/normal_v22.slvs new file mode 100644 index 0000000..733864b --- /dev/null +++ b/test/constraint/equal_line_arc_len/normal_v22.slvs @@ -0,0 +1,367 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-4.99993226121819220000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00006773878180900000 +AddParam + +Param.h.v.=00040013 +Param.val=-9.99975209012342430000 +AddParam + +Param.h.v.=00040014 +Param.val=9.99968435134161740000 +AddParam + +Param.h.v.=00040016 +Param.val=-5.00031564865838440000 +AddParam + +Param.h.v.=00040017 +Param.val=5.00024790987657660000 +AddParam + +Param.h.v.=00050010 +Param.val=4.99990506249655910000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=12.85283693258537800000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=500 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=14000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.normal.v=00040020 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-4.99993226121819220000 +Entity.actPoint.y=10.00006773878180900000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-9.99975209012342430000 +Entity.actPoint.y=9.99968435134161740000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00031564865838440000 +Entity.actPoint.y=5.00024790987657660000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=4.99990506249655910000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=12.85283693258537800000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=55 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00050000 +Constraint.entityB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/equal_line_arc_len/pi.png b/test/constraint/equal_line_arc_len/pi.png new file mode 100644 index 0000000000000000000000000000000000000000..4e06218a09172def33473526f2b172fe806363ae GIT binary patch literal 4667 zcmeHLX;f3!7CyNofJ6pCCK;kwp_GWIb*M5AA|h6)VnB>nWs;yEh{}8uQHw>8Vj08% z^$Aj@t4NtjNE|AP2vif0xo8P8$PhxF#DsT);F8rx>-*6kZ>_GCtaI17``ml>xA*?` zcW&I)Eslx`3lsnVicTBtT>*e7(!abcHpBEuYXv|Rai1T16ZfAARw=Xy>l-_1PeFAI1oGMZ!(HLuNQWC*RGT*$@mX_ zbuql-V}TPNexzXI7u{vurK>aYJ8Hx3`4k;&JM&b>bRP6q`{{9PxChY_)Gw`>>CQJI z!O9Q-(|X`laxZO{f> zE9C)_lr}506wDGPfU(XQjKdRl)1)%r#K_s zny`G_z6=8JXNI%o91{H`M4$lN=1m*qnWFLIIK(D>3Lx0iVds;X!Jgsk#|d7a=$%8w z)n{DepZXAHsd0dR{_Y<&allMfZMJN;w(2emCxBdO&7dR>5gZ-iB`1m{w|0Pwu5I|5 znF3;K&k#&ZYAXsR)qias* zzwsKn^_9jPAN>bl>js!@V}DHnu~VT0fyTp2^1!$ent2X|w31m2=&k}B01++wO$uT; zIv>T=^8Ry$PIGg=`Igq6xQpM-(dd7�KG~d(fh9YWLe?bIH!JsM=vd5EUXGU048~ zy1+JRrI0mjbFLK1Ttz1=?@~aPK}6_2=kzq#LoV3dE-5yXcxxlC)qyY#W@p@22Zg#U9#uem@ftrndE$n?Wiie&vvvaM#hNrKZYZ9`P~2PyD0VP=12+G&0SYg9W&*gX z6qJrVk0wv1ut$3re&makbJ&|ql_4~R#nANB$HTcf#od9*$M4qZ;b9XsGR4Ldhn{>N zyrEc8Avk{eqexPNPKfB!E=-ZwbiRmhQi1LcVWQu^`Hvn(Pc(f2wme#5JMG96^@S*F zWFL8Z@PT;8MC(vle(~#$2X!^$En1Of6Ja&2%^j8kHV+!opg%CqkGoo!(OMB!-*fOY zi}C@O+WJZfU70G619vy0@b;|jz=Nk3$&2nDU3N=WfgTLR1NLlJbId=q212#}1V zC6>j#5OevSOq)f(e8kR-%`l2p2ZJgUlp#VvlkNLlKhE~H1wX02uLQSX5*Ih^E6S*e z1p$jtSmqlt;NB#XuSWxTt04vb9-Gfwg2Iba=it`49(jPlE1N|Dd5h3aMQk)*jNQVP zQ0GyG46#uk8&4G)r&L3o`gB5IaE=P%h}VcrHr4Lwx$w- zl(3B!_1#=i%XnGwuDi~-!wBt^$vP1H$ZYQvCo`1G6UbKyW~Ouk$>##Wj435W-mA?; z;1`S+Paev4w9*M$SsL3`0dKqmSdu^wqX~he&mIY zkQ>sf8z?Hm*6C9eg0QkudeeSl6G4-8YYw@m`g-==j*30B@kXRUP=&eKWjYZuEK`%v zePzG7t#@^ZwIdenOXKCsB@MFHdTM0E_F0wT8eP(p-%Dz=CN_p0OMLi^>z{Pe$+JLXX08l4g_^VEXwT0S{ z7gup$%!@%#8F3Uq$UPMbSY*{wSgq<2v~ZG~t?TQ?Caw}Lrm~G zLgjv5jAW-5`>i}VlQhvYSdmz`Oj}{;T4g$62$$s^Wcm%(F@s+XwsWe;Z^c#3+2WQe z@nF?NOH`dRt)~2?_}1^M=8MX@Eh2>$yJ{o@6J*h{wQHWsx;YxzWmXF+-D=*MlrrB* zhB=WnjibH1XLZoEGvO~EK1`GkvW@w2FTvLU#afKmrP3uolhVLhK_}?82)tQO4=pt- zX7I6E+neQvJp2;i<4iJ(9}gPfwc?!_EKMoS-KvZJTrs(6Quv-n{QzPy)vPi}h8-Uf zz+a25*~0|l?@tSpKb2^q^i_47ss7rrF*TpeO~t` zOVq<8ViGz59eDOz!CRBkeuwQ4bx{+gW3cq~ywPWQmE z*37r?wubf6a@4`76RdYmI=aAm@zOESpV>08mC4lVQUK$j?L1g-)M=!|N?)!txZbJ+ zlswg;$Vd=B(5Z!8<;P*&T9c=g$HkCUF+x4m+=2CZ*0{lKfT++z^Lq}D0~RGgol>Iq zFGsZ-zR6j|B8q6Za!KOE8>TDmX5_Nmsss@9JB41%yR|xN_GpUcW zl<7;4FzSp*^6pCFEwciC`2t-^Ny8nV1)(}S7+}1Mv_aY_&hCGQ@>;f*3vW3tzcaR? zBlKL<$giF2w;chzM6foAImj-*Ox6`75gU^Peo>8u zza{m`M;v)K$mB%~2sx76F&UPz?qXEm;n!`~59GEW;Tj%^)DVFPZ5$Rx?xr!_;rw3g z!3Coc%G^rPK1&Plrf~BZCv4TI4ka;i#cirX+j`oIk@MlykT?|tdRS^-$|qDMVKk{6UTj(8X-__FCEo9XC z^m*wFs_y;a%xi5Bw6QohBK literal 0 HcmV?d00001 diff --git a/test/constraint/equal_line_arc_len/pi.slvs b/test/constraint/equal_line_arc_len/pi.slvs new file mode 100644 index 0000000..009148c --- /dev/null +++ b/test/constraint/equal_line_arc_len/pi.slvs @@ -0,0 +1,367 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-4.99999651845403381145 +AddParam + +Param.h.v.=00040011 +Param.val=9.99999682365714548382 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000349810587607635 +AddParam + +Param.h.v.=00040014 +Param.val=14.99999363650495176614 +AddParam + +Param.h.v.=00040016 +Param.val=-5.00000000434181757214 +AddParam + +Param.h.v.=00040017 +Param.val=5.00000001080568345913 +AddParam + +Param.h.v.=00050010 +Param.val=4.99998746596540222242 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=20.70793025565613021399 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=500 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=14000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.normal.v=00040020 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-4.99999651845403381145 +Entity.actPoint.y=9.99999682365714548382 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000349810587607635 +Entity.actPoint.y=14.99999363650495176614 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000434181757214 +Entity.actPoint.y=5.00000001080568345913 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=4.99998746596540222242 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=20.70793025565613021399 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=55 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00050000 +Constraint.entityB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/equal_line_arc_len/tau.png b/test/constraint/equal_line_arc_len/tau.png new file mode 100644 index 0000000000000000000000000000000000000000..1abd363cd474e157522b2b20b5ebef35ccdd5194 GIT binary patch literal 4963 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 GM*I_>3NxJm literal 0 HcmV?d00001 diff --git a/test/constraint/equal_radius/normal.slvs b/test/constraint/equal_radius/normal.slvs new file mode 100644 index 0000000..978b12c --- /dev/null +++ b/test/constraint/equal_radius/normal.slvs @@ -0,0 +1,349 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.normal.v=00050020 +Entity.distance.v=00050040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=130 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/equal_radius/normal_v20.slvs b/test/constraint/equal_radius/normal_v20.slvs new file mode 100644 index 0000000..cd891bf --- /dev/null +++ b/test/constraint/equal_radius/normal_v20.slvs @@ -0,0 +1,347 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.normal.v=00050020 +Entity.distance.v=00050040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=130 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/equal_radius/normal_v22.slvs b/test/constraint/equal_radius/normal_v22.slvs new file mode 100644 index 0000000..57b6d9b --- /dev/null +++ b/test/constraint/equal_radius/normal_v22.slvs @@ -0,0 +1,349 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.normal.v=00050020 +Entity.distance.v=00050040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=130 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/equal_radius/test.cpp b/test/constraint/equal_radius/test.cpp new file mode 100644 index 0000000..5e9db1b --- /dev/null +++ b/test/constraint/equal_radius/test.cpp @@ -0,0 +1,17 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} diff --git a/test/constraint/horizontal/line.png b/test/constraint/horizontal/line.png new file mode 100644 index 0000000000000000000000000000000000000000..cd911e5a9c6f4423bb5b3d0b669208c6b0afba60 GIT binary patch literal 4274 zcmeHLdr(t%8vO_mfrv7qfD#^c*63C!s375Cu~ix^NCgCg0gYlo79s2)5Dbrmvb(aP zjO!LCvd~JQH3br(yh*rfOBBJl8UjO1fTB_eFM*H}2-yULY1WlGJF|c6jDKW)Gs!pi ze)oLmJLlYF9`+>|8*MTI0ONxP_WJ{%h?b22V1i=<+}1OLy?F=<3{2IxKKVZ?V%tPV9PeaC&knH0 z>gVV91$>3DmMbf#q)17sYaz!j$B($O?(|v6W5uy}Y_|2GPUBhwo!@FMt9Y;-#b7vx zx@bRyw^H$iD?moxYoE5|W`)=ty1bSO*j!}i&?>-vn!X4NJ;_^GlQGin9Hr!@K$p8jKBPP3TqureWxw6!oBdgRsTubLxu#&van(Bg}C6Qey ztU1zALNkTNxiV(%=plF#@ltVD)Oxi%AM30M&;{&0J&f(s2sxVm*n|l0ILNkFW|$Qm zSP)5*DSs8lzBkFxj;@;*ek;zDh}0{S;+y1BQ`*dI(Pm6xHiBw-A)@xAB&XazeCF1q z`Vu{e6Q=OKe_(FTt~6PoQj~K-CCS%VQ}zkfNVhbodc?hlPq5xsmAi-E7g1EjDWfPO zf}8ugA6gQ1Lsv6!ovi9^;fY(ap=?S|dv232>v&A6nMsGh(vz#qf=_;qFx*bXp)eLa zH;F(bFv@op+iMyN?LlLQOY}>F#+&ra_U7H#&>Ou8(tp@+xMLU=dFb(gW!F*48kkP;Pu3H zWJO20mM`zErts_yrneji5WcW=DZ912lLeu&9k?8OS-m)U7nb)nlOj``$rXkInC@EK$JcK_%W6B%Miao_ z+@X7a?FBUWo^3;z`MWFMlbxlMuZ78tE^KD$rLuRw(jUv8lDo%#St@PmVgx#ep0=0q zZLV&s1hPl}s-TW@R{~|KD_gz?GB!>xsDpJkKP%DmnLpBA#M%-gFb|dAk2#b-U2#+1Pw*~ORYjFdKb#3kNVC%EZLLQ|v9euL=m;-dWJ2|G`ppWt|?z~fs7c41%jdRkA@)W$*#P&bD)qowC7V}-RL zb(hPsrxTSH??19SY4Z=&cl;SYsf5%VWd((|T~X5F18z}HdxoO-ijB&%t>fgAv4WZG zuT0LIQVJ<*1i9VtV3kqadz`lmSk7 zp8aitxZ%>YIL$=TSe{E&ecc()trUtlS-TH4%DZ}I-IAx8_PqOIPWNH)i(|?oW8Qr) zR#T}lR;<6M%&}{Dw!Gw8gT`|{e4qymalEJw2e>r&bERkp>zoX8qRMyrL2-<~Z%8UP&dE?MG>TFVfw5jfbE` Q{a*we^zz+b@gX_=UqeK}y#N3J literal 0 HcmV?d00001 diff --git a/test/constraint/horizontal/line.slvs b/test/constraint/horizontal/line.slvs new file mode 100644 index 0000000..cebb650 --- /dev/null +++ b/test/constraint/horizontal/line.slvs @@ -0,0 +1,288 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/horizontal/line_v20.slvs b/test/constraint/horizontal/line_v20.slvs new file mode 100644 index 0000000..8909c0f --- /dev/null +++ b/test/constraint/horizontal/line_v20.slvs @@ -0,0 +1,286 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/horizontal/line_v22.slvs b/test/constraint/horizontal/line_v22.slvs new file mode 100644 index 0000000..8b2dd43 --- /dev/null +++ b/test/constraint/horizontal/line_v22.slvs @@ -0,0 +1,288 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/horizontal/pt_pt.png b/test/constraint/horizontal/pt_pt.png new file mode 100644 index 0000000000000000000000000000000000000000..7614ea815f7303cc0a08f2839bf9362fc9618dae GIT binary patch literal 4268 zcmeI0dr*^C8pclo;T|rfA|eYag?3l216xv+ixr_XL0T0G1VStV<(7b46cR$9s8uK| zYgev?>7pQ)KmS zJM8II{4+{himj<|b5sXZeZybd7KGxpkkmn|#pvrS>_6I4hqr+HZvA3T zB>B+Kccc_t=RQNr3!$H$+0qbKtp-qk)m)e7(O?p1(_SGQW?byodIs000J~VrN+!bb zh30;ufp$%*^gn8B!0(s5m1CJdoDvPF7R7j2_R8Z?5N`t4-Z5E2@w|99%P{IG9J9)2 zWnUqJ3n4g)8f6q*3c-8l1zR~-w(Heu+3Jzwogxiuyea#0@d(F`xJ}FEx^5<70f}iI z50bB`rEIybadwQcA`$bh$^9r}MbbEgW7fuvEmQXWU|ixdpQ`I7Et?Nd=ZA)`o{2d? z#3Pd&R7={(v_Zz2PD5k{MM~(HOidFlO+>;z^l4v|GAj(mvnXHCvvwN<$c<*PYP8D# zZv70QSh29FIH(gBgpWoHS<=Bx3=I(bf&Lo})Y@LbF4dx3Y!>9G@Zm?l<$g-aC=48L zYBdH`mNabtrHaotkfI?*OPT-6I@V7jLO>{<7IVJ_2J(()J&g|3gd(y^el&})VXM!7 z@iL1S#c?dx!m)PkaEl)AirgY4@=oko#(9SUWcvWT>fe*q$iFOETc6*-3=p zu^3;PfbsX_9jM4u#%FIkFI@R~D0xBeJZg!vsowIlu1)5Tssae}@@?{}7&f5we_0Ge z+VzS+PW>*#j$Z3w1mds6s2Kq$Q#rKByZCtxIxskzB3$mXrL_WJ74c)+y*Sp>JD{K; z#t{`@dV9U29@;OfnGGh5=qpv6@)aOWrH2`;0t{!7^>K!Q07{Y&4bEGG@wem+JG=(f zMw1o*@IraX@qzJBFvP}BUa(!vG|DwJ-xg5M$$96(bqFOpqN(UHka6-N1M#c}$&uN$`eD!g&bn%9gk`P|Ogr zUNghp3B>Elzx}BI0ZhLi&h)cv0#wwG!&{jm%yAgl3Flv~V)m{iF51OL& zp^lxmHq76bu?%zf``k33u`-J5G@E=>6K(m^ zG_8~CF@lx0GJAVCDT2f&>9GRWP*S@cP+piGxAoS+Q&9HLur=&Ryy(Txki06Lw!YEoZ#;dFDy)Xko+(})>%=C?>J zi@A1ThUgu)=n)eCBuxdfEVH1G=3Hv_?61VB4|shg8V!3wG0WQ{E69)GI&04juCA!q ze~}RSsffq_xP$b~!sF!?OC%_?C*a$s_ge6A1L+ZV`E6(y@r{ET?w=+;*hL=jV)k`N z?QW8oqSpi!OKrU$@zUB0`>LYEW>ReES#dej%d$KJq&ea0>_i=}n{laUr+JIye-S$; z;&o2kIhjL8bCz@f>hdTyTbwnyJFMO1YGRk9Mo6*b)e~2XhkS#bBPf)5#kH3(LcdJO zYZ`BhNNv>xwofmQsYoR!+N_svIO_j?i=SgZK4$aI)?@HB`CAC!eejS+!@Kybe*;=Q Bs4D;f literal 0 HcmV?d00001 diff --git a/test/constraint/horizontal/pt_pt.slvs b/test/constraint/horizontal/pt_pt.slvs new file mode 100644 index 0000000..ac91222 --- /dev/null +++ b/test/constraint/horizontal/pt_pt.slvs @@ -0,0 +1,287 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.ptB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/horizontal/pt_pt_v20.slvs b/test/constraint/horizontal/pt_pt_v20.slvs new file mode 100644 index 0000000..6a38678 --- /dev/null +++ b/test/constraint/horizontal/pt_pt_v20.slvs @@ -0,0 +1,287 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.ptB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/horizontal/pt_pt_v22.slvs b/test/constraint/horizontal/pt_pt_v22.slvs new file mode 100644 index 0000000..cadcdba --- /dev/null +++ b/test/constraint/horizontal/pt_pt_v22.slvs @@ -0,0 +1,287 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.ptB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/horizontal/test.cpp b/test/constraint/horizontal/test.cpp new file mode 100644 index 0000000..c08b5e1 --- /dev/null +++ b/test/constraint/horizontal/test.cpp @@ -0,0 +1,33 @@ +#include "harness.h" + +TEST_CASE(line_roundtrip) { + CHECK_LOAD("line.slvs"); + CHECK_RENDER("line.png"); + CHECK_SAVE("line.slvs"); +} + +TEST_CASE(line_migrate_from_v20) { + CHECK_LOAD("line_v20.slvs"); + CHECK_SAVE("line.slvs"); +} + +TEST_CASE(line_migrate_from_v22) { + CHECK_LOAD("line_v22.slvs"); + CHECK_SAVE("line.slvs"); +} + +TEST_CASE(pt_pt_roundtrip) { + CHECK_LOAD("pt_pt.slvs"); + CHECK_RENDER("pt_pt.png"); + CHECK_SAVE("pt_pt.slvs"); +} + +TEST_CASE(pt_pt_migrate_from_v20) { + CHECK_LOAD("pt_pt_v20.slvs"); + CHECK_SAVE("pt_pt.slvs"); +} + +TEST_CASE(pt_pt_migrate_from_v22) { + CHECK_LOAD("pt_pt_v22.slvs"); + CHECK_SAVE("pt_pt.slvs"); +} diff --git a/test/constraint/length_difference/normal.png b/test/constraint/length_difference/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..eec393188526e5735a171e5812ce60e1106f9dc7 GIT binary patch literal 4462 zcmeHLc~Dc=9zF>nY_hqqC>pV9seo+CVu=ZeQjKWqf)NCQiarepmZGwSKz$<1kZ~D6 zLE&kEhY(D`s0ay>QBY9 zSEZh>%k|HDZLv#TGshzH%;NYGVy~{HQ2*q5>o-ZIf-0xoX5Mf01jbwHI+9EsnGl2q z_@@;&3<0oS7^@2ORx$vnL>T~lItK~V=fNBLBelTNtt13EtziME*8ihP&1uD7)rOL5 z21Pe9rBNT;Qx409gB2gyGV){l+O^e8UZC{Y^F{U(CyK~BR^8h_OY%@D76h>-l|TQA zgEG^0l7r~JD8Ttn0rGSfO4GZ#7l6QJ3YrpqNXB9n@U!h?5VO0&Y}AVm9ENU8^Wmlg00kdPxJq0r5q zwycxpS8qF`si8La!r2f8LK7rLAw0|0et%67^!AhD^1 zS<~#Mn83KlvF%m^=zzG7dOCB?g=_-3^#RNK}1NHB$#WyF}VuGQT=R%CB3 zH<-@Ujo~x95Wri*;)IQK{cbDM{TI6s95VdVLF&Xj5+Q}W#@@pthbI8Lb7bk^i{3`b zgU-P0z~ss0N?At>$oECmWn2@T`BWS7qXizNkM3OxfXkEvDQhT|@-$Se3GDS1CoWvg zNR}X|E{ar;_HEqrRJlTwK%1(?e-Z}0DG30h1dab9>i1Kio9uX0d$Rl-vk)3y+WG6Y zxwyWlUTzva&VjuI1pHB|gwwtIr9nXr{SCAjSwN7m&|!`2B)P{+^d=9NS0R%Q_S7?F zasg_7fJ*Y2GmtilkHP}q8dOrNN6fao=$&FoSWv^R`3@ueH#(f6iG{Z^9yz_c*v)_^ zK9Lthhu2ZI(=~e~trVQZ9zJocp z;#NC;Ld&Sx{lcs|-!8tWj}i!RW<1@0v!+Xvk}c5gj!(H1!bIw#$q- zJAEQ-l;gSlT+iDv}b zq(`aLuKK*!QT9@1Y^Qe-f{JKDL&aw;0Lf9DroPbtFwz3PaSDtkF+GRhzy=YL4BNWV zS-H1oc#+BCWxm})-nN_q0ML_$GqVzijfs>KrXYkAjZVerX#*2tR&3Kt#yRHgl2$Ja zsA>o%G3^5nGFRSezu_V)SNRr>cxW+^u5Gw?=h$fV@|6wC z*U#G+eNRv1#?u@NM_igZLIKszXbqz()Ob&&CP?uhEzZne0HR#$eb6W<_L3L8HVQ(> zuWcykemZ=W<-RSG>UIi~Op8FaUl&Uka_L_#8?WvFhB}figLak(4N-AR7XrsKBJ{_k zKP*)#SbI(tJkThF+zf!;3I-p>d8r%8XVtwc>w$IZ0aa*B;{`q81#5Ey6dfr2oqxVs zCSdO%|2xXEpdtl?ye7sno9H#+-0>C`Ax0EIk%zJ(v03i4(vf|) zo%{F$SEbGFzIm2@6%QylNo1!T`IRKBSXdU`8f4#6;$0tpy^V1CdZ|NxB+l3t8*X_M z2e#kPDzqz4+u!qyQ2X8sa1w^3OA2cqSN;%O8e+Wn4s>$VP~?J<5+mWL2TkZT4CpOA=w*51tL0BE1y;<;g0%vHgQUsBsShDlE} zQnGe(&$b`ZU$pS_m-^u~#WfhEvFisJH!_yjC01*SUS2iaW@V!s7`dAFP-VdvbPi`8 zaDQymq5*)xMFy%32Ce~?Zo|RADK#rVwmq&4v{ujn_=l1naL@cN1r7MLrS?_Q z@nd7HA_i$ zB>xX-pu@sOO#$!<;0^QL}yeSrxuNSn_5!PimuKekp9RC>QIV6JkC zP@PrSd=3}QR0ZVJ%nue_Y}eRg37&aQ2hi?9Yx-5dJp5GVlm`1xzFGt$I0dDy;$bVoVnfUm~s5)4$Jx$XhYuW`djJ)B>RARWmP5zH(iZ*vb zO)2=>SXfi`jp3wOtUh>vN^LnW?}+4Skl$;I#M@Z#yp$+;>rvdir@6QDnBa#1<6$1x zmD`x!_hw+&`C4qW!?9cq`1zW6`!$>rzT3;5NE3O;V{WlvUp?#oLdY@D^i=Mvl2`rq z>g3@9jiOlVFYLR;p(mmYT>^{|fbz{dTpbysd~tJhNNdMQde7&9uD!fQ-CPa%5*ZJ# zdEC>p^p5p-i&w$~WH?kJuAYZZ?06Pgs0`S(<{OjB%%g;7mqnzhbX|mkECQ@o8B0pd zfJ6rs)sv_8ghLWN4mQT0Q+5yQIC;OCAUSNGv4C&&TNdG)_q|5wX)_n!|Es8wt)S^ar%$nff0+ zj(@5NKI!)vg&WkFIIx8LdgO1hdCr>P(H&1!aG{WQ?#jF1fgp)s@LoZQ4BLK}MGT|5 zNXA{`i~;RCC`i9~&~J2ssaLEqV5CDq$C@dA+4-#zRQfHF2}qbE+mY;fkzSRjt1TK4 zd>9^EX~^4V%QHaBu{ZyYHt!o^;kyO~P|nm%z_$2?<=$E9HiwTIw3enVLC$*qdbu_C zZvqF0sB|GSP8*1(1#V71maAcJt6 z8!s0|b8qRuJ#mJ4l`MYzN4Y`EBqCDfVC;TETQnmg#raH7X9Xjvk+nCVtx7_{%ar?) zxKKYYM0H`T3|okoY6nIT6UPp?_7LJmCB1p%f*T!ghlb4HSDPwU6m@M=(rZeoth!xs zTX&)5UGxeXIXIqVNGq$*%S2Zz61MfTgb0hkiJx?v&^@eo>tm!bo#e7>a&O2=<@b(mP`BX zC|v+S)A~H;hYV65H5?cn3dk-~s+()Fq7%w{e_oxf=qLhitZp5!&E-O9y;NoJ$t~%E z>+)QMrE=AvY8G)Gy9DMNH1GeqjVE_9q|a$L2>iJ#hl zF2@Izo-rGl-lpKffhIN1#Wr@7Nc+rD!(A?}D!}pN21J=;T^DoV>&0 zZao=tl8ZLrU51>NDvsHZlY!#c`80tm+u6Y~e5nq^M?1!GMkBsM8E(cZF@3qDaG3Qq z2im*|*b@NRU3H+Lb#?>Dnr(!lCR>4}zBu}dQb4viKI#<$1Iyri=8g7O2oU@^5{L2q zTk-a^@aumqI73z+4xrK^&xtZ)D;eWQLA1=Eyl3Nd7UrrjyN>tBb#(c*yFw< zhNy~!D7e(3ber?gM2`xf(sK~}HCg4`@~rc=YPs*3Ffr@;a#P>M;0an^{Z272tTiZ< zk7tQC2p{>JZ1jBL&A(Sc5j6@rf?p>R_)a#M;&HBd`#$0L0I{4EE)uS0!(y7^G6^{m zGBJ0sZRn1-u(EZyQj{6ch_CMsHyV6W;xg<+7?YaIZy{Myc6W0IFB3W&_~B)3#xLYm zlweJlG*Gv^=n1JC`IXL)0_Os28v70Q9M!?br6vppR{kuCr*-VmyA)S{T9kT}kT^)G zS=XW+EqF^wY!Gn=nG%123fa%m3x_%XeV$iyo;9K$8H$N#x0KXiYdeQy31c(}*;3*L zFt0=|C=;elZ;M}&cS@hle&BeTh~Q`WdvTZr@q1UNJinPU9%!nR3)xv~yY_SNKl;ly z#SE5WUrM(`jE_BLS-1Y&ZZGIKBIAu85*&@+^>S1t*Xx%`@h;KLHwjM98Rg{_4J3{A z+0@GfhR><5Kg-_-pk*ysQ-=O>iXoqne9c8jaeBQks6i?q{VG|>UTjw7DvXc`WzUH< z`NH5d<=SU# z^=wm;bO1LBwPapaXep*9;xw+fq`3qLysM>0r)PEEdCPg{%sFuGIdJd&|Nh_a`@Y|I zZ`_XU&U)H&wE+NnTmIs(3jjD~_^YW7{c``{rB?tRGb8!to!^+w(As7Gt`VDJak3`d5kcFni7?*rG?%gnh2CzU!?ADR%s`&*n|o z7xOkZ>YzRViUuQ5?HH|mwr7Q*#TT}z&wuY7PtbRx zwQ$jdo?iCCvVOPnZ9KC8&R}e%c6iw>B$)lvXyv7Qjz9WR-Y77M?S_E+ z^#+3G1d`nl)_QR@0XgB)qy&_$7F3ynmky&RF!On9+BJZBz=z7o#|-za{z8u0p%c@I zYIcN=*}-Can8N{X=_tq_DME}BW=R_Ag#3EhChvi~{#-(g!2Rjl5UR$TH1jGQpu88o zudXjdCQl_qkU9%icsZ+Y&Z8`D_yNf6h`Uf7t`vc7?^2-$F+B zSRI++#|lWL8i&c&KPs7uTPiv^(vdWOZ;_b3L4UmjiFFH4zGiw5`r}INw|NACe@||k zTb4=uvniv>&2!MySglA=hNABXu*r4Vf=w67HY)QCOY-j*s*WTVmabZ3fNFi1xUs-< z{yeg860V3+xcwqlB~2c@*1~Pb2}tEE@V}-OjHIY(gshBZ+jP-Mw)qbPLkq|j!Ew_@ z{9*DICeM2XY~tpfFJAv&@1pP43)-vF`XxlU{e$|Rm%>`80}s!VSHN`^9&piRNL(S_71|hQS0Hj%m#RV~1|eBdUSRV?6bkg>g~n%0`QN7<~(_NNZcn_9_=(Z8)Z!S2tiz{nd=w!u}?O=ZoLh zEaK&iN9q$IwcU(RZ?@9o|0ajE;QnV)9Y`m_c&{P;cWNk3@cq5ss8V8HE-b`z)R^$<*lcr)PKqX55%3hEf75rvlx_qfCCiB7c8#3Egiu z`tFcy@Q~RlVRE-dN<1&N$W_&Uwb*$W2l0$W!;>l20HeZW(0=H707-g!Nfeqq71A1| z&5f3R;o%^n)MU)?QWu}vDXmcX_bABjtBc^ElvOzt96wgW@SK2rIq&uS@-qYms~hs? z+^3@jeR3#tZBDd>_lT}PItR+;*gTi`9j&* zpd4&a)sX})_%iluQbEi5nezKhmQj6{b&r*uDwN#ZdR?WuhqKA%v|pPd8Hv(mxmbm= zuPW-Xq_16GHMvcP>y|FF7ymrmz>p8-G--Ir(8-K2+qf3+=-b}&p?vB^ zf*1>Bi7|DK6aRQnN7GO|e(zR&(=jp)ulfbkb6li?23B%Q_GSd=`1=P|DOO3{2_kvaud^kXZ|72e0E}uzsa94j6~T#Vfa6Sp(BdI@-T<8a=jFuVVR%?I@(hp z(K45Oq});#YS|gX31V{X4CK^Dk=X8SD*%}?8sR_rcmw7A=Ddz_03z2wLjrp2u|sdW zPl+_VvhEWO!K~%=E~y4Q@(~1nuY(a-l_GOFwO9wdEX)4Mm~G4SGL7to?r7}<#aG>t z4C~5Zv53>%`elJPpYH(xVex*ke`Y=JAH-z3sMLL$z!;NCX+m6skr5ILrq?{HY~cyE zw*da=n}JRFL~Gjt(Bma zKbulj>vBM^bgd4M?Vg1>>6$WdAXyENq`SCel8?&|ZOu!FOtx={4zRv(%xpS+M|XlI zxIXuIY-j-6qCV=OA6M_rf>Z=ZDN3VQ(#vvZc!1zQxJ0~-0mKGpyVfjZ>OZN}2C}70 z{a=TV%bEJ6!^d@&=+2n0vKn-cK}BuoCNcGiCQ=TPitw>+P4y;op3TD`qV3j#VBHpI zR}h}eb0N@HAV9x2z%b%aVBuCAcg9{|_dPFv_wkJ+fJ5=MGdTu-qb}cCz1-D%@Ls

|{q0O&uARKPU{t zqiKRpq5n}*kYqyxv7n1;R%4sp;5?YqA6md79Mk7r5tanLjZ#!274((Vf_LB#IEh>Qq(TVdXd=eyZ-@ISi zZbPd^k~c!5evZiHUVn4?q41SJ>>!JtDr`E?c#Gqc8=pxPhDnWWcg^=h&R6ARNwIP+ zOLa#9g0=aYnbgH?wi-nw6 zkSMxwm_wIGHk_eiIg!h-G2qBddWKu5ueRW3$x}Q&vVN!lms7K$rnJBTlfIv*4vcqo zE-Uu7?@hWVN_<)4ue$v@dbzNpLFp`t`K@quuf$(9Ku}RT*99IizmBrLyYpx@jCXh> mnRkCqHJ{Mzzvmr?0=YG>rCrUr)(Lty1GYGBcewivF7_V?&t7)` literal 0 HcmV?d00001 diff --git a/test/constraint/length_ratio/normal.slvs b/test/constraint/length_ratio/normal.slvs new file mode 100644 index 0000000..0286fc1 --- /dev/null +++ b/test/constraint/length_ratio/normal.slvs @@ -0,0 +1,342 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=15.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=51 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=0.50000000000000000000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.x=-10.00000000000000000000 +Constraint.disp.offset.y=5.00000000000000000000 +AddConstraint + diff --git a/test/constraint/length_ratio/normal_v20.slvs b/test/constraint/length_ratio/normal_v20.slvs new file mode 100644 index 0000000..a73f06b --- /dev/null +++ b/test/constraint/length_ratio/normal_v20.slvs @@ -0,0 +1,340 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=15.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=51 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=0.50000000000000000000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.x=-10.00000000000000000000 +Constraint.disp.offset.y=5.00000000000000000000 +AddConstraint + diff --git a/test/constraint/length_ratio/normal_v22.slvs b/test/constraint/length_ratio/normal_v22.slvs new file mode 100644 index 0000000..08957de --- /dev/null +++ b/test/constraint/length_ratio/normal_v22.slvs @@ -0,0 +1,342 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=15.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=51 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=0.50000000000000000000 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.x=-10.00000000000000000000 +Constraint.disp.offset.y=5.00000000000000000000 +AddConstraint + diff --git a/test/constraint/length_ratio/reference.png b/test/constraint/length_ratio/reference.png new file mode 100644 index 0000000000000000000000000000000000000000..5a5bfc9a074c0908f4d9d6581f78e97d724d5d5a GIT binary patch literal 4616 zcmeHLYfw|y7TyVC{>NlAh$ff2R z!co)CRUnbv{2YL!^chbBTeDltL7VHu0(uo>(?1u?2~PYEHq>MKe%7-@#l`vhx2H5* z!p}A=nFb-fkWsPE5(x;On9c+*mHa$XJP+6{m{?G3K~I4Z)QvaB10&$we4fuTO^vC+ zh5m@f%x^?rP0MNM5gM)K8~{einlt4)*F=P`K~g;@cPi4tPNEfm;j@z6OsS0_r#Og za#W7J-med8KK%_lIInzbP=I=A270vJ@7I7(9G>D`;On3G-@Ut+<^)ILB(kUXEXSU6 z>d7avaP=L-@0Z1Dldairdv#81BrpyAe)#cFcSM-S>(F+gZ9Nx$kcuyrmG4xo({`X{ zqcEtrkPTN~32W-(SCu%~$g`s3Y9GH7{2-Jo%Ju?FZ>e!{tcCq&xA66DYd)(OklqN| z;cRBD{xj04M@OaBTnO%fSrz8`UK!2~ zB0Y&xCsj~Pj@O03qH6ZihD`)SW>{ql5?Cxi?l?83xd|w8G!5dJ;;?z%X>i5B$~Q zxpG-TeFdi=r`d3yx(kt}!t{_|u7?1Y_{3)qmGI*`9|0l7opF zy2CZ65KtfrL%nD+xV9|G;G?Y{>|S>yU#{m1#cE=xOVdM`m718YHbqsN6D&@UkIE=+ z23e^P5*{j5km1qc%Xy87B3&%7BxGptZ5SNR<&_liZaM2RZ>)y&s!rZ9rjXTfrPbe6 zgxYhZ?%A8~nc(~%9||a^DSH8S*;r!a<}gCk2^;mZcrxe64PK(4Q)n6RBCUEyDfxB$ zBHg_&m+<__u2emko1~wm}7`&3iY$nlv1{3Ae9nY zz7>z4?Nu!L7$V>os&hXGZ`_<_Y<-lyKnA~TvlPdBSJ33_n- z+aCI)8>n`jMKdt9AuH1QP!0f;JhCixg}DC<9rJ0FoJ9ei z(gFSr!-sD9Zy5fcU}!MJ62(YBZMtbm_to1Eppph-rD*LJ{#v;NJj?qycAA*lUN%H` zypSHUzgB_-M(H#5B~vG;ek3uQrK1h#X38R=nyf}1_biFo(-gaTVzT(1X{$&Z<9u8j z%)ettzwUMr0Uj6Dxvnk))EbP(vp|7b5u?lu4d`crlnRGjR5EXS>5D5e9P$>jqu2Op z04uBU&8GPI^f9iO4GnjG37`bAF}8O3Vz8d>r2N~!mBg?^4;fA%ZX$fh8_N(=U{8;wnh6vV~#@kO81H)##kyQPXow}R?>ar&J{D$Ll7=G z%5&3`o3po7Bwr* z3@bvuHV1vJvBJ|)jrPw1D2_T2-MN%-M9Ix{^f~Vn4}&hFh9y{9va(hi@^y+it_DEY z>;nf}u0p5Gl2Z$!vMlw(8spw-C~=5ao^MvC%q?@O0PR8%4J{B@`f43WD`W! zqkBkV5!-@K8X4=X8d=9K*w?5>2}tl7F~;7HKY>)NF5B)f{GNpdzC_2loT$&jZfx;$ zzqXuOJBnVZa_RFy@$I6h)ufTQoF|POR(#q<$&VhV*{+@Lf`|8WSo~Fcljb*xc{lI zT9Lr(mXJ;G^D?+_iuEPyDI7{lV|UxOEReJh)xjA;1}{!l`U(whN2EY7=JJKbo~czj zcW`;)_Q(?QQppBIHk-&oYlZHW!)lG!$j+z5P5cA?j=?b_F^W~%;C5p;fz*5LQj}$X z_I}pNlZAXIWwl)$k>Zh*S`}qH*fO@F`s9AgV`I0Z^7!C@R^m@#8PUQ@%7|0Eq{?y4 z5UjQ{|7SeuuFN~eY3WgaT!*YTMHcDdLLn8CFHJDH~kB{L7&W&s!qHn%qsx+e1!! zcFtV0+4k6+eTjT`nK}R7P3mR$EiC+|0Z;0Mb_v{_b9R;a0zFAna$!M%uuvP;R)yD@ z0nkq&SkN&<9}t4Y!7MK#29D@12AXZ078qEu0q$rT!&>_9wCEY3@jN9wG-yO2@(3$c zTK43ZNSWa=B0}4caAXdlvWD^~YKDFV_n7EtS^J>@YhD=FP3L2A5zXDgjdi9ldU>#pX1O4K%~HTOGUCyr%%AZ}OfRPcH*x-(3O7<p!=%=A&x>0c@px?i99nk{Ijoc zy6x1+XPdxUrSmwcb>prQf<2dAlN```i>`q`rGV7((=3#v%W!FCfhrEmB-py|2; zhW#*E_(Xu}!|L7Wx{n$Gn}_uApVb0*EW7>IPLSdg{qzqSi4RF$64Mt+TR4{B=&~wO zkf+ZgwZi7&7@3qz^jy1l=T2x-{y{`(@WF3^W_g~7IWnBn3K6DQ+^o($a-*#-IG@YC zN#_x)&QPOL7yp!}X^ddJ@}EA@G>!J?1krm&c-{4}1=*-kDLU#)gXGROBmIw@3EM8pyG7L167$K5Z{sBN$rwORjJDvJDIXsYX&#FNz4hLkQCj#m+};G_t(MMe$L`pBZDoqW*o!C zw8S?xM~niGBiQnqiZpUsz?U~NZ|%b39E+NoXoq7+ao3CjQ_v*rIM`xujkVu%u>rZm z3tVWG+<7|12C7zvO~X!X;RoXCD2>-JkhJq{YiW`6Xbr(aUf7u5jECg7;eZ${3fLF$ zA=rSe;V4Qc#7v!*uXxv0ZE!sEj@#uSuk=>uj(6<$JyAU;S`?F1xmW8~VL(It1Y>>g z5Y$uoDHl!Q>3XZT1Ti^Q>F|P)DLSeqN)rr3-JHC6SB=!zg=cb@WJ3VErN0@js?dn$ zR&7ZBcx{_t6r({HYLeWIs9-Bd)5+_^so- zyb}DWu{F@+y7F-tnxUB;J9_PMh}gbE+n4m%T`0^O5DtNDMkM-_y_UK5KWc@iz80*C zxRfa>Z-}dV^0(8R0xH!j^FEgL@}z}7(|h_>rh>Xt7Y`;C=IDLa{nV3tjp5|AC2XrS z#~GE&aZvt>N!F;~rp$U+#xl7rRL%$nB&uqE;){6qWLKcqT{dK_%D>pv?sq{bx@7ut zB_Kv#rv8$jPAv-2f*vcjPj&5NaQd+~NLy2Q{Cofgp=%0tRo4bhVI>{CzB$)@Rq<6< zm&3Y148qNmJNeI#nLk)>k*v||_)7+XR-b3)Zy2k}Qoml0A#^o{hy>CkU(y^LBpCWL zk1vK<8;N{_t*|x$;ca<+a0rmVY9oKv{Pkk*ANsvh2l8&nUS`b`jMQ*8Q*xs5xl{|x z)AFCNB$h0!hc6ZMw+x9|YA3t@L$Js;VX1~Fy=Vy%?so3DM|$ZnT;ip=# zA1s#h356D0Wm%$UF)cHh_-f3dpAV*H$>gQ6;>F+ZGRzA5#OFcfpd~ zns_NoMrTQKhNACA?OdfFC4oiiyd(qM#+8ZT2gBpR53qHu(4PPwbsSH+xlV_tj@qpWidOtUbMxRwVQO(#l|6LPyF&Hh}g&}(y`F0 z+*3}bZ0|{se%+(+Vr*?2vSVd%!>Wdd{8g{U4ZILfx&4E9Nov>gFMvBmrD5Ha@iH*s ftn_=l(o->*!kW$ literal 0 HcmV?d00001 diff --git a/test/constraint/parallel/free_in_3d.slvs b/test/constraint/parallel/free_in_3d.slvs new file mode 100644 index 0000000..1a054ed --- /dev/null +++ b/test/constraint/parallel/free_in_3d.slvs @@ -0,0 +1,295 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=40000001 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=121 +Constraint.group.v=00000002 +Constraint.valP.v=40000001 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00030020 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/parallel/free_in_3d_v20.slvs b/test/constraint/parallel/free_in_3d_v20.slvs new file mode 100644 index 0000000..421eb11 --- /dev/null +++ b/test/constraint/parallel/free_in_3d_v20.slvs @@ -0,0 +1,290 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=121 +Constraint.group.v=00000002 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00030020 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/parallel/free_in_3d_v22.slvs b/test/constraint/parallel/free_in_3d_v22.slvs new file mode 100644 index 0000000..1628203 --- /dev/null +++ b/test/constraint/parallel/free_in_3d_v22.slvs @@ -0,0 +1,290 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=121 +Constraint.group.v=00000002 +Constraint.entityA.v=00040000 +Constraint.entityB.v=00030020 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/parallel/normal.png b/test/constraint/parallel/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..599c82bd97bf2d94813ad1045166c7d474efa1b8 GIT binary patch literal 4686 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 KtvPucA^tyPa1uHI literal 0 HcmV?d00001 diff --git a/test/constraint/perpendicular/normal.slvs b/test/constraint/perpendicular/normal.slvs new file mode 100644 index 0000000..a0d5930 --- /dev/null +++ b/test/constraint/perpendicular/normal.slvs @@ -0,0 +1,339 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=122 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00050000 +Constraint.entityB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/perpendicular/normal_v20.slvs b/test/constraint/perpendicular/normal_v20.slvs new file mode 100644 index 0000000..905594d --- /dev/null +++ b/test/constraint/perpendicular/normal_v20.slvs @@ -0,0 +1,337 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=122 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00050000 +Constraint.entityB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/perpendicular/normal_v22.slvs b/test/constraint/perpendicular/normal_v22.slvs new file mode 100644 index 0000000..342a049 --- /dev/null +++ b/test/constraint/perpendicular/normal_v22.slvs @@ -0,0 +1,339 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=122 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00050000 +Constraint.entityB.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/perpendicular/test.cpp b/test/constraint/perpendicular/test.cpp new file mode 100644 index 0000000..5e9db1b --- /dev/null +++ b/test/constraint/perpendicular/test.cpp @@ -0,0 +1,17 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} diff --git a/test/constraint/points_coincident/free_in_3d.png b/test/constraint/points_coincident/free_in_3d.png new file mode 100644 index 0000000000000000000000000000000000000000..df5a660e0e81c60c9c9b3da6edf17cc0009e979b GIT binary patch literal 4241 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 NJFM-k3bsHoe*hyMKyv^9 literal 0 HcmV?d00001 diff --git a/test/constraint/proj_pt_distance/normal.slvs b/test/constraint/proj_pt_distance/normal.slvs new file mode 100644 index 0000000..1658c3e --- /dev/null +++ b/test/constraint/proj_pt_distance/normal.slvs @@ -0,0 +1,290 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=34 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=5.00000000000000000000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.entityA.v=00020020 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.y=-4.00000000000000000000 +AddConstraint + diff --git a/test/constraint/proj_pt_distance/normal_v20.slvs b/test/constraint/proj_pt_distance/normal_v20.slvs new file mode 100644 index 0000000..7dd3084 --- /dev/null +++ b/test/constraint/proj_pt_distance/normal_v20.slvs @@ -0,0 +1,293 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=34 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=5.00000000000000000000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.entityA.v=00020020 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.x=0.00000000000000000000 +Constraint.disp.offset.y=-4.00000000000000000000 +AddConstraint + diff --git a/test/constraint/proj_pt_distance/normal_v22.slvs b/test/constraint/proj_pt_distance/normal_v22.slvs new file mode 100644 index 0000000..01ba48e --- /dev/null +++ b/test/constraint/proj_pt_distance/normal_v22.slvs @@ -0,0 +1,290 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=34 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=5.00000000000000000000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.entityA.v=00020020 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.y=-4.00000000000000000000 +AddConstraint + diff --git a/test/constraint/proj_pt_distance/reference.png b/test/constraint/proj_pt_distance/reference.png new file mode 100644 index 0000000000000000000000000000000000000000..571927b419b114e7171ffb4e9fee859ca0e13dac GIT binary patch literal 4566 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 DxI9+) literal 0 HcmV?d00001 diff --git a/test/constraint/proj_pt_distance/reference.slvs b/test/constraint/proj_pt_distance/reference.slvs new file mode 100644 index 0000000..d1203b9 --- /dev/null +++ b/test/constraint/proj_pt_distance/reference.slvs @@ -0,0 +1,290 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=34 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=5.00000000000000000000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.entityA.v=00020020 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.y=-4.00000000000000000000 +AddConstraint + diff --git a/test/constraint/proj_pt_distance/reference_v20.slvs b/test/constraint/proj_pt_distance/reference_v20.slvs new file mode 100644 index 0000000..d5f3860 --- /dev/null +++ b/test/constraint/proj_pt_distance/reference_v20.slvs @@ -0,0 +1,292 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=34 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=5.00000000000000000000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.entityA.v=00020020 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.y=-4.00000000000000000000 +AddConstraint + diff --git a/test/constraint/proj_pt_distance/reference_v22.slvs b/test/constraint/proj_pt_distance/reference_v22.slvs new file mode 100644 index 0000000..6461182 --- /dev/null +++ b/test/constraint/proj_pt_distance/reference_v22.slvs @@ -0,0 +1,290 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=34 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=5.00000000000000000000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.entityA.v=00020020 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.y=-4.00000000000000000000 +AddConstraint + diff --git a/test/constraint/proj_pt_distance/test.cpp b/test/constraint/proj_pt_distance/test.cpp new file mode 100644 index 0000000..7e2a06e --- /dev/null +++ b/test/constraint/proj_pt_distance/test.cpp @@ -0,0 +1,33 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(reference_roundtrip) { + CHECK_LOAD("reference.slvs"); + CHECK_RENDER("reference.png"); + CHECK_SAVE("reference.slvs"); +} + +TEST_CASE(reference_migrate_from_v20) { + CHECK_LOAD("reference_v20.slvs"); + CHECK_SAVE("reference.slvs"); +} + +TEST_CASE(reference_migrate_from_v22) { + CHECK_LOAD("reference_v22.slvs"); + CHECK_SAVE("reference.slvs"); +} diff --git a/test/constraint/pt_face_distance/normal.png b/test/constraint/pt_face_distance/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..5fe42722bbb52363aa3c4bcff7a982c1ca233260 GIT binary patch literal 4314 zcmeI0dr(t%7RP^yNexDnH)s*CBNQY+6d$;Vs61TCLn{hdfpAfg-H8DN5rF~;Dhz@$ z-BpN{V#Nmvgv3X9L?S^{tOgO0%OeobEXL)jrUW%4>;<;zTurSz)1CdNGsz@#^GohI z=lA`6&*vn2OTZ@GISc0i0Cau+?70;HEM@9R_zbyna}TQ<0KKz5o*T9uEFA9H5NGbS zF!QNMCp<&<_?lTau@5>$i!Od+UF>qp^I*f@?K`5ZM48SE=66Syct67^b_zZ!zRi>^A(b{=~ocs)vjAbz|4e1 z34^|mYc>MVdK+zV}a(DfuG#JDhd{BYs+pi}Eq6!pb zN-2t(1^n*gwA7BVubehEhtXp6eh^4j+nulgve6p3rtIY7k(a3$p$|F(WS3aMEfRlJ zbVxChigW?l&QROd-Mv!LW)Hjr_xI?bN;L*|1qld%af*dX>iu08y5wI-#)B_E5D7%} zN?DCZ)iQzEpR@`H&--apj#(o=hy%?0TM|4_H-tlIA!AMbExwUAt!DG!RIGom7pt`7*)`DZ(x433>B?H88j4GR_i65DrV6 zryKVT2XwruK`6!sLj!{394MM2y!|q*%F1Mc;ob{9##Cn^n$n2 zJonN95PL$Hv0<&T$B&#fvUqTi6>=EqLJ5YX`3vwxPse-HIaI9hYmG;WY!V^cGwV`I zQCFvR+Ia{+_l^Y;&@YP}HbS;_Dn-bc0XRNo0?&CQ>k?zMN6_QK^I@1b^plXaH*U5! zgm$0V$FLq(W)sbrh#8PM#jBra+Tx!1Cgc<0=_+2b4%pP@&t1FQ2(V5}N3ZFjo&TIS z_s$`2roI+$MQ)b)%x6SMKwOg5dUYFzVUM^NtCcVD%zwm>_Nr53iHs!n;G_r9@g9cKYeqVEd7rrz4d^jd_+KH1^oKN3J^l>}o3}UfAu&w(VP{ z3q-!5U!NZdI}D;?b7I3YtG!<2TOGlfka0|&lLyYkC@x3uzhD?SUzv8o6y5I1h~>p8 z#Q-=pX=~|7t6|fA{2RLG&9w7A7X3!eHbI(-f6)3m-1VOvBssxYj@ zSxnAVE9hee)g|Lp0j|SA)BBQXP5%18&XtY4;46Nl|e8FFgLXI*bDa8&jd=Rl~0a`LA!QuV-R>746UI2)0Yu)&da4=;4 zV5?S~2!lF(F~0(bA5qe8f}s{3pFyK@cKm1piU1Kapw0o%R*f;D0AEBygkg`W+aR0A zPSyv&d6_nH`q*4x)`&Qn7P>ntIHTs_?Hz zD?Zm4aacG+ZzCdb8Ei^9nPTT@0$yfR#2_c~<%g3EtDT=;7=%&`Eatf#kdH)(eS?v$ z6#bvI@vL|xtx~Yx7zl4`C2Z~H2S409+-1R@59In3SL^G2m|yhDa~7nk=>}dVAa@fq z{3K$xjsq~u5_T}U*DFN?WKK1rN*#N#ax5VJQr7Bl{@38zO7AP7VZZVHpWCL=U z&zF?Vq66<*nmgDHKP-GD1E3vxEc~unRc#OixG`9o%#RKFh~-n(2_HYT10!VN;CWN8 z9XR+Q3weE$ERUWHt5M$33kGDz=K8Kv4KaDMx}~n`!6Ed}qUplZzO68(WX05{4LNjf z7Hn5O*;V*%A7D5S+j9eW74x%NJlqu>GD&J$%W5XBsD6?ow7NUDykzZuOq%UgzY4%G zT^wv-<|Bt7kBnfchmGKG{GAZSW-zt_DG2dEvDr`xZt zRgLDQHrbs?e7Ht3R0KjIY!lGQ6a(So>3l8kG zWR6jmWZNL)s&u6OPq~~D3)?v$c7yaYco!ncEqg`6423byTPnZ5YAtR%5+P8e9NxaV<=o0<5kN;jnzQW!AhpY3>E$FgG Q{<8o+UICsJ8=;JU17L2V3jhEB literal 0 HcmV?d00001 diff --git a/test/constraint/pt_face_distance/normal.slvs b/test/constraint/pt_face_distance/normal.slvs new file mode 100644 index 0000000..f2fd334 --- /dev/null +++ b/test/constraint/pt_face_distance/normal.slvs @@ -0,0 +1,713 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=00020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000003 +Group.type=5100 +Group.order=2 +Group.name=extrude +Group.activeWorkplane.v=00010000 +Group.opA.v=00000002 +Group.color=00646464 +Group.subtype=7000 +Group.skipFirst=0 +Group.predef.entityB.v=00020000 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00040000 1002 + 2 00040001 1002 + 3 00040020 1002 + 4 00040040 1002 + 5 00040000 1001 + 6 00040001 1001 + 7 00040020 1001 + 8 00040040 1001 + 9 00040001 1003 + 10 80020000 1002 + 11 80020000 1001 + 12 80020001 1002 + 13 80020002 1002 + 14 80020001 1001 + 15 80020002 1001 + 16 80020002 1003 + 17 00000000 1001 + 18 00000000 1002 +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030000 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030001 +AddParam + +Param.h.v.=80030002 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=00020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=00010000 +Request.group.v=00000003 +Request.construction=1 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=00020000 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=1 +Entity.workplane.v=00010000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030001 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.normal.v=80030003 +Entity.distance.v=80030004 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030004 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.normal.v=80030007 +Entity.distance.v=80030008 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030007 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.point[1].v=80030002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=2010 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=2010 +Entity.construction=1 +Entity.actPoint.x=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030010 +Entity.type=11000 +Entity.construction=1 +Entity.point[0].v=8003000f +Entity.point[1].v=8003000d +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actPoint.x=10.00000000000000000000 +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=00020000 +Constraint.ptA.v=00010001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=33 +Constraint.group.v=00000003 +Constraint.workplane.v=00010000 +Constraint.valA=-10.00000000000000000000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=80030012 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Surface 00000001 00646464 80030012 1 1 +SCtrl 0 0 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 0.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000a 0 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 +TrimBy 00000001 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000004 0 0.00000000000000000000 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 +TrimBy 00000007 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000000000 +AddSurface +Surface 00000002 00646464 80030011 1 1 +SCtrl 0 0 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 10.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 10.00000000000000000000 5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000005 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 10.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000002 1 10.00000000000000000000 0.00000000000000000000 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000b 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 10.00000000000000000000 -0.00000000000000044409 -5.00000000000000000000 +TrimBy 00000008 1 10.00000000000000000000 -0.00000000000000044409 -5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 +AddSurface +Surface 00000003 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000002 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000001 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000c 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 00000003 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddSurface +Surface 00000004 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +TrimBy 00000005 0 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000004 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000003 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000006 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddSurface +Surface 00000005 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000008 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 00000007 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000006 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000009 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddSurface +Surface 00000006 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +TrimBy 0000000b 0 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +TrimBy 0000000a 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 00000009 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 0000000c 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddSurface +Curve 00000001 1 2 00000001 00000003 +CCtrl 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 0.00000000000000000000 4.91652684208287205081 0.90981526206072360630 +CurvePt 0 0.00000000000000000000 4.64894150531215188948 1.84047354780936389673 +CurvePt 0 0.00000000000000000000 4.18497755609325672310 2.73604876692571252761 +CurvePt 0 0.00000000000000000000 3.53553390593273775266 3.53553390593273775266 +CurvePt 0 0.00000000000000000000 2.73604876692571252761 4.18497755609325672310 +CurvePt 0 0.00000000000000000000 1.84047354780936411878 4.64894150531215188948 +CurvePt 0 0.00000000000000000000 0.90981526206072382834 4.91652684208287205081 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000002 1 2 00000002 00000003 +CCtrl 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 10.00000000000000000000 4.91652684208287205081 0.90981526206072360630 +CurvePt 0 10.00000000000000000000 4.64894150531215188948 1.84047354780936389673 +CurvePt 0 10.00000000000000000000 4.18497755609325672310 2.73604876692571252761 +CurvePt 0 10.00000000000000000000 3.53553390593273775266 3.53553390593273775266 +CurvePt 0 10.00000000000000000000 2.73604876692571252761 4.18497755609325672310 +CurvePt 0 10.00000000000000000000 1.84047354780936411878 4.64894150531215188948 +CurvePt 0 10.00000000000000000000 0.90981526206072382834 4.91652684208287205081 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000003 1 1 00000003 00000004 +CCtrl 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000004 1 2 00000001 00000004 +CCtrl 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 0 0.00000000000000000000 -0.90981526206072327323 4.91652684208287205081 +CurvePt 0 0.00000000000000000000 -1.84047354780936323060 4.64894150531215188948 +CurvePt 0 0.00000000000000000000 -2.73604876692571208352 4.18497755609325672310 +CurvePt 0 0.00000000000000000000 -3.53553390593273775266 3.53553390593273775266 +CurvePt 0 0.00000000000000000000 -4.18497755609325672310 2.73604876692571297170 +CurvePt 0 0.00000000000000000000 -4.64894150531215188948 1.84047354780936434082 +CurvePt 0 0.00000000000000000000 -4.91652684208287205081 0.90981526206072405039 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000005 1 2 00000002 00000004 +CCtrl 0 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 0 10.00000000000000000000 -0.90981526206072327323 4.91652684208287205081 +CurvePt 0 10.00000000000000000000 -1.84047354780936323060 4.64894150531215188948 +CurvePt 0 10.00000000000000000000 -2.73604876692571208352 4.18497755609325672310 +CurvePt 0 10.00000000000000000000 -3.53553390593273775266 3.53553390593273775266 +CurvePt 0 10.00000000000000000000 -4.18497755609325672310 2.73604876692571297170 +CurvePt 0 10.00000000000000000000 -4.64894150531215188948 1.84047354780936434082 +CurvePt 0 10.00000000000000000000 -4.91652684208287205081 0.90981526206072405039 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000006 1 1 00000004 00000005 +CCtrl 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000007 1 2 00000001 00000005 +CCtrl 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 0 0.00000000000000000000 -4.91652684208287205081 -0.90981526206072305119 +CurvePt 0 0.00000000000000000000 -4.64894150531215188948 -1.84047354780936300855 +CurvePt 0 0.00000000000000000000 -4.18497755609325672310 -2.73604876692571208352 +CurvePt 0 0.00000000000000000000 -3.53553390593273864084 -3.53553390593273730858 +CurvePt 0 0.00000000000000000000 -2.73604876692571297170 -4.18497755609325672310 +CurvePt 0 0.00000000000000000000 -1.84047354780936478491 -4.64894150531215188948 +CurvePt 0 0.00000000000000000000 -0.90981526206072438345 -4.91652684208287205081 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 00000008 1 2 00000002 00000005 +CCtrl 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 0 10.00000000000000000000 -4.91652684208287205081 -0.90981526206072305119 +CurvePt 0 10.00000000000000000000 -4.64894150531215188948 -1.84047354780936300855 +CurvePt 0 10.00000000000000000000 -4.18497755609325672310 -2.73604876692571208352 +CurvePt 0 10.00000000000000000000 -3.53553390593273864084 -3.53553390593273730858 +CurvePt 0 10.00000000000000000000 -2.73604876692571297170 -4.18497755609325672310 +CurvePt 0 10.00000000000000000000 -1.84047354780936478491 -4.64894150531215188948 +CurvePt 0 10.00000000000000000000 -0.90981526206072438345 -4.91652684208287205081 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 00000009 1 1 00000005 00000006 +CCtrl 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 0000000a 1 2 00000001 00000006 +CCtrl 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 0 0.00000000000000000000 0.90981526206072282914 -4.91652684208287205081 +CurvePt 0 0.00000000000000000000 1.84047354780936300855 -4.64894150531215188948 +CurvePt 0 0.00000000000000000000 2.73604876692571163943 -4.18497755609325672310 +CurvePt 0 0.00000000000000000000 3.53553390593273730858 -3.53553390593273864084 +CurvePt 0 0.00000000000000000000 4.18497755609325583492 -2.73604876692571297170 +CurvePt 0 0.00000000000000000000 4.64894150531215188948 -1.84047354780936500696 +CurvePt 0 0.00000000000000000000 4.91652684208287205081 -0.90981526206072471652 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve +Curve 0000000b 1 2 00000002 00000006 +CCtrl 0 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 0 10.00000000000000000000 0.90981526206072282914 -4.91652684208287205081 +CurvePt 0 10.00000000000000000000 1.84047354780936300855 -4.64894150531215188948 +CurvePt 0 10.00000000000000000000 2.73604876692571163943 -4.18497755609325672310 +CurvePt 0 10.00000000000000000000 3.53553390593273730858 -3.53553390593273864084 +CurvePt 0 10.00000000000000000000 4.18497755609325583492 -2.73604876692571297170 +CurvePt 0 10.00000000000000000000 4.64894150531215188948 -1.84047354780936500696 +CurvePt 0 10.00000000000000000000 4.91652684208287205081 -0.90981526206072471652 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve +Curve 0000000c 1 1 00000006 00000003 +CCtrl 0 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve diff --git a/test/constraint/pt_face_distance/normal_v20.slvs b/test/constraint/pt_face_distance/normal_v20.slvs new file mode 100644 index 0000000..c8a4c23 --- /dev/null +++ b/test/constraint/pt_face_distance/normal_v20.slvs @@ -0,0 +1,712 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=00020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000003 +Group.type=5100 +Group.order=2 +Group.name=extrude +Group.activeWorkplane.v=00010000 +Group.opA.v=00000002 +Group.color=00646464 +Group.subtype=7000 +Group.skipFirst=0 +Group.predef.entityB.v=00020000 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00040000 1002 + 2 00040001 1002 + 3 00040020 1002 + 4 00040040 1002 + 5 00040000 1001 + 6 00040001 1001 + 7 00040020 1001 + 8 00040040 1001 + 9 00040001 1003 + 10 80020000 1002 + 11 80020000 1001 + 12 80020001 1002 + 13 80020002 1002 + 14 80020001 1001 + 15 80020002 1001 + 16 80020002 1003 + 17 00000000 1001 + 18 00000000 1002 +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030000 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030001 +AddParam + +Param.h.v.=80030002 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=00020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=00010000 +Request.group.v=00000003 +Request.construction=1 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=00020000 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00010000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030001 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.normal.v=80030003 +Entity.distance.v=80030004 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030004 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.normal.v=80030007 +Entity.distance.v=80030008 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030007 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.point[1].v=80030002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030010 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.point[1].v=8003000d +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actPoint.x=10.00000000000000000000 +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=00020000 +Constraint.ptA.v=00010001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=33 +Constraint.group.v=00000003 +Constraint.workplane.v=00010000 +Constraint.valA=-10.00000000000000000000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=80030012 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Surface 00000001 00646464 80030012 1 1 +SCtrl 0 0 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 0.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000a 0 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 +TrimBy 00000001 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000004 0 0.00000000000000000000 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 +TrimBy 00000007 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000000000 +AddSurface +Surface 00000002 00646464 80030011 1 1 +SCtrl 0 0 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 10.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 10.00000000000000000000 5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000005 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 10.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000002 1 10.00000000000000000000 0.00000000000000000000 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000b 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 10.00000000000000000000 -0.00000000000000044409 -5.00000000000000000000 +TrimBy 00000008 1 10.00000000000000000000 -0.00000000000000044409 -5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 +AddSurface +Surface 00000003 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 1 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 2 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000002 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000003 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000001 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000c 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000004 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 -4.99999999999999910000 5.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 1 1 10.00000000000000000000 -4.99999999999999910000 5.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 2 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +TrimBy 00000005 0 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000006 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000004 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000003 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddSurface +Surface 00000005 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 -5.00000000000000090000 -4.99999999999999910000 Weight 0.70710678118654757000 +SCtrl 1 1 10.00000000000000000000 -5.00000000000000090000 -4.99999999999999910000 Weight 0.70710678118654757000 +SCtrl 2 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000008 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 00000009 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 00000007 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000006 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddSurface +Surface 00000006 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 4.99999999999999910000 -5.00000000000000090000 Weight 0.70710678118654757000 +SCtrl 1 1 10.00000000000000000000 4.99999999999999910000 -5.00000000000000090000 Weight 0.70710678118654757000 +SCtrl 2 0 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +TrimBy 0000000b 0 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +TrimBy 0000000c 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +TrimBy 0000000a 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 00000009 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddSurface +Curve 00000001 1 2 00000001 00000003 +CCtrl 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 0.00000000000000000000 4.91652684208287210000 0.90981526206072361000 +CurvePt 0 0.00000000000000000000 4.64894150531215190000 1.84047354780936390000 +CurvePt 0 0.00000000000000000000 4.18497755609325670000 2.73604876692571250000 +CurvePt 0 0.00000000000000000000 3.53553390593273780000 3.53553390593273780000 +CurvePt 0 0.00000000000000000000 2.73604876692571250000 4.18497755609325670000 +CurvePt 0 0.00000000000000000000 1.84047354780936410000 4.64894150531215190000 +CurvePt 0 0.00000000000000000000 0.90981526206072383000 4.91652684208287210000 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000002 1 2 00000002 00000003 +CCtrl 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 10.00000000000000000000 4.91652684208287210000 0.90981526206072361000 +CurvePt 0 10.00000000000000000000 4.64894150531215190000 1.84047354780936390000 +CurvePt 0 10.00000000000000000000 4.18497755609325670000 2.73604876692571250000 +CurvePt 0 10.00000000000000000000 3.53553390593273780000 3.53553390593273780000 +CurvePt 0 10.00000000000000000000 2.73604876692571250000 4.18497755609325670000 +CurvePt 0 10.00000000000000000000 1.84047354780936410000 4.64894150531215190000 +CurvePt 0 10.00000000000000000000 0.90981526206072383000 4.91652684208287210000 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000003 1 1 00000003 00000004 +CCtrl 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000004 1 2 00000001 00000004 +CCtrl 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 -4.99999999999999910000 5.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 0 0.00000000000000000000 -0.90981526206072327000 4.91652684208287210000 +CurvePt 0 0.00000000000000000000 -1.84047354780936320000 4.64894150531215190000 +CurvePt 0 0.00000000000000000000 -2.73604876692571210000 4.18497755609325670000 +CurvePt 0 0.00000000000000000000 -3.53553390593273780000 3.53553390593273780000 +CurvePt 0 0.00000000000000000000 -4.18497755609325670000 2.73604876692571300000 +CurvePt 0 0.00000000000000000000 -4.64894150531215190000 1.84047354780936430000 +CurvePt 0 0.00000000000000000000 -4.91652684208287210000 0.90981526206072405000 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000005 1 2 00000002 00000004 +CCtrl 0 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -4.99999999999999910000 5.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 0 10.00000000000000000000 -0.90981526206072327000 4.91652684208287210000 +CurvePt 0 10.00000000000000000000 -1.84047354780936320000 4.64894150531215190000 +CurvePt 0 10.00000000000000000000 -2.73604876692571210000 4.18497755609325670000 +CurvePt 0 10.00000000000000000000 -3.53553390593273780000 3.53553390593273780000 +CurvePt 0 10.00000000000000000000 -4.18497755609325670000 2.73604876692571300000 +CurvePt 0 10.00000000000000000000 -4.64894150531215190000 1.84047354780936430000 +CurvePt 0 10.00000000000000000000 -4.91652684208287210000 0.90981526206072405000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000006 1 1 00000004 00000005 +CCtrl 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000007 1 2 00000001 00000005 +CCtrl 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 -5.00000000000000090000 -4.99999999999999910000 Weight 0.70710678118654757000 +CCtrl 2 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 0 0.00000000000000000000 -4.91652684208287210000 -0.90981526206072305000 +CurvePt 0 0.00000000000000000000 -4.64894150531215190000 -1.84047354780936300000 +CurvePt 0 0.00000000000000000000 -4.18497755609325670000 -2.73604876692571210000 +CurvePt 0 0.00000000000000000000 -3.53553390593273860000 -3.53553390593273730000 +CurvePt 0 0.00000000000000000000 -2.73604876692571300000 -4.18497755609325670000 +CurvePt 0 0.00000000000000000000 -1.84047354780936480000 -4.64894150531215190000 +CurvePt 0 0.00000000000000000000 -0.90981526206072438000 -4.91652684208287210000 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 00000008 1 2 00000002 00000005 +CCtrl 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000090000 -4.99999999999999910000 Weight 0.70710678118654757000 +CCtrl 2 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 0 10.00000000000000000000 -4.91652684208287210000 -0.90981526206072305000 +CurvePt 0 10.00000000000000000000 -4.64894150531215190000 -1.84047354780936300000 +CurvePt 0 10.00000000000000000000 -4.18497755609325670000 -2.73604876692571210000 +CurvePt 0 10.00000000000000000000 -3.53553390593273860000 -3.53553390593273730000 +CurvePt 0 10.00000000000000000000 -2.73604876692571300000 -4.18497755609325670000 +CurvePt 0 10.00000000000000000000 -1.84047354780936480000 -4.64894150531215190000 +CurvePt 0 10.00000000000000000000 -0.90981526206072438000 -4.91652684208287210000 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 00000009 1 1 00000005 00000006 +CCtrl 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 0000000a 1 2 00000001 00000006 +CCtrl 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 4.99999999999999910000 -5.00000000000000090000 Weight 0.70710678118654757000 +CCtrl 2 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 0 0.00000000000000000000 0.90981526206072283000 -4.91652684208287210000 +CurvePt 0 0.00000000000000000000 1.84047354780936300000 -4.64894150531215190000 +CurvePt 0 0.00000000000000000000 2.73604876692571160000 -4.18497755609325670000 +CurvePt 0 0.00000000000000000000 3.53553390593273730000 -3.53553390593273860000 +CurvePt 0 0.00000000000000000000 4.18497755609325580000 -2.73604876692571300000 +CurvePt 0 0.00000000000000000000 4.64894150531215190000 -1.84047354780936500000 +CurvePt 0 0.00000000000000000000 4.91652684208287210000 -0.90981526206072472000 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve +Curve 0000000b 1 2 00000002 00000006 +CCtrl 0 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 4.99999999999999910000 -5.00000000000000090000 Weight 0.70710678118654757000 +CCtrl 2 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 0 10.00000000000000000000 0.90981526206072283000 -4.91652684208287210000 +CurvePt 0 10.00000000000000000000 1.84047354780936300000 -4.64894150531215190000 +CurvePt 0 10.00000000000000000000 2.73604876692571160000 -4.18497755609325670000 +CurvePt 0 10.00000000000000000000 3.53553390593273730000 -3.53553390593273860000 +CurvePt 0 10.00000000000000000000 4.18497755609325580000 -2.73604876692571300000 +CurvePt 0 10.00000000000000000000 4.64894150531215190000 -1.84047354780936500000 +CurvePt 0 10.00000000000000000000 4.91652684208287210000 -0.90981526206072472000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve +Curve 0000000c 1 1 00000006 00000003 +CCtrl 0 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve diff --git a/test/constraint/pt_face_distance/normal_v22.slvs b/test/constraint/pt_face_distance/normal_v22.slvs new file mode 100644 index 0000000..2e4195e --- /dev/null +++ b/test/constraint/pt_face_distance/normal_v22.slvs @@ -0,0 +1,681 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=00020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000003 +Group.type=5100 +Group.order=2 +Group.name=extrude +Group.activeWorkplane.v=00010000 +Group.opA.v=00000002 +Group.color=00646464 +Group.subtype=7000 +Group.skipFirst=0 +Group.predef.entityB.v=00020000 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00040000 1002 + 2 00040001 1002 + 3 00040020 1002 + 4 00040040 1002 + 5 00040000 1001 + 6 00040001 1001 + 7 00040020 1001 + 8 00040040 1001 + 9 00040001 1003 + 10 80020000 1002 + 11 80020000 1001 + 12 80020001 1002 + 13 80020002 1002 + 14 80020001 1001 + 15 80020002 1001 + 16 80020002 1003 + 17 00000000 1001 + 18 00000000 1002 +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030000 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030001 +AddParam + +Param.h.v.=80030002 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=00020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=00010000 +Request.group.v=00000003 +Request.construction=1 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=00020000 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00010000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030001 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.normal.v=80030003 +Entity.distance.v=80030004 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030004 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.normal.v=80030007 +Entity.distance.v=80030008 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030007 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.point[1].v=80030002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030010 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.point[1].v=8003000d +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actPoint.x=10.00000000000000000000 +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=00020000 +Constraint.ptA.v=00010001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=33 +Constraint.group.v=00000003 +Constraint.workplane.v=00010000 +Constraint.valA=-10.00000000000000000000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=80030012 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Surface 00000001 00646464 80030012 1 1 +SCtrl 0 0 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 0.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000a 0 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 +TrimBy 00000001 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000004 0 0.00000000000000000000 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 +TrimBy 00000007 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000000000 +AddSurface +Surface 00000002 00646464 80030011 1 1 +SCtrl 0 0 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 10.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 10.00000000000000000000 5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000005 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 10.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000002 1 10.00000000000000000000 0.00000000000000000000 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000b 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 10.00000000000000000000 -0.00000000000000044409 -5.00000000000000000000 +TrimBy 00000008 1 10.00000000000000000000 -0.00000000000000044409 -5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 +AddSurface +Surface 00000003 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000002 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000001 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000c 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 00000003 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddSurface +Surface 00000004 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +TrimBy 00000005 0 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000004 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000003 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000006 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddSurface +Surface 00000005 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000008 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 00000007 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000006 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000009 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddSurface +Surface 00000006 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +TrimBy 0000000b 0 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +TrimBy 0000000a 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 00000009 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 0000000c 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddSurface +Curve 00000001 1 2 00000001 00000003 +CCtrl 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 0.00000000000000000000 4.64894150531215188948 1.84047354780936389673 +CurvePt 0 0.00000000000000000000 3.53553390593273775266 3.53553390593273775266 +CurvePt 0 0.00000000000000000000 1.84047354780936411878 4.64894150531215188948 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000002 1 2 00000002 00000003 +CCtrl 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 10.00000000000000000000 4.64894150531215188948 1.84047354780936389673 +CurvePt 0 10.00000000000000000000 3.53553390593273775266 3.53553390593273775266 +CurvePt 0 10.00000000000000000000 1.84047354780936411878 4.64894150531215188948 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000003 1 1 00000003 00000004 +CCtrl 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000004 1 2 00000001 00000004 +CCtrl 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 0 0.00000000000000000000 -1.84047354780936323060 4.64894150531215188948 +CurvePt 0 0.00000000000000000000 -3.53553390593273775266 3.53553390593273775266 +CurvePt 0 0.00000000000000000000 -4.64894150531215188948 1.84047354780936434082 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000005 1 2 00000002 00000004 +CCtrl 0 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 0 10.00000000000000000000 -1.84047354780936323060 4.64894150531215188948 +CurvePt 0 10.00000000000000000000 -3.53553390593273775266 3.53553390593273775266 +CurvePt 0 10.00000000000000000000 -4.64894150531215188948 1.84047354780936434082 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000006 1 1 00000004 00000005 +CCtrl 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000007 1 2 00000001 00000005 +CCtrl 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 0 0.00000000000000000000 -4.64894150531215188948 -1.84047354780936300855 +CurvePt 0 0.00000000000000000000 -3.53553390593273864084 -3.53553390593273730858 +CurvePt 0 0.00000000000000000000 -1.84047354780936478491 -4.64894150531215188948 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 00000008 1 2 00000002 00000005 +CCtrl 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 0 10.00000000000000000000 -4.64894150531215188948 -1.84047354780936300855 +CurvePt 0 10.00000000000000000000 -3.53553390593273864084 -3.53553390593273730858 +CurvePt 0 10.00000000000000000000 -1.84047354780936478491 -4.64894150531215188948 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 00000009 1 1 00000005 00000006 +CCtrl 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 0000000a 1 2 00000001 00000006 +CCtrl 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 0 0.00000000000000000000 1.84047354780936300855 -4.64894150531215188948 +CurvePt 0 0.00000000000000000000 3.53553390593273730858 -3.53553390593273864084 +CurvePt 0 0.00000000000000000000 4.64894150531215188948 -1.84047354780936500696 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve +Curve 0000000b 1 2 00000002 00000006 +CCtrl 0 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 0 10.00000000000000000000 1.84047354780936300855 -4.64894150531215188948 +CurvePt 0 10.00000000000000000000 3.53553390593273730858 -3.53553390593273864084 +CurvePt 0 10.00000000000000000000 4.64894150531215188948 -1.84047354780936500696 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve +Curve 0000000c 1 1 00000006 00000003 +CCtrl 0 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve diff --git a/test/constraint/pt_face_distance/reference.png b/test/constraint/pt_face_distance/reference.png new file mode 100644 index 0000000000000000000000000000000000000000..6e392b3c61c4a9e483479e07a2c677ede3fb41ff GIT binary patch literal 4378 zcmeHLc~FyQ9)9yd1cJz21O=pCWeA5>i6W;0Y9T~W4k6MYC~XngC9psuIl#hd1x682 zL}2ZT2SfrIE=7V!P*6e_2owQBQ4B{o3gHgy7u{h^%`n@Y-Th<7KQi;q_kA<(^Shqk z^W^LyxBV(8Jrn>y<=_EF4*(z^$xm?={N&Ne%UuAd^&WI|I1-aB?8ZjCbT&xp^*+fVIhN2q2cUZ<~(5};l1saYxOG|F?LXf?1@|80B(yb~FN zl)5pB{)S=+*m;Fg@cvP`=F}6na}do}uTLaORq)hz3`ScTT>Z1367sI^KPBW-hrB1d z|M z0})+vWG4Ts{M>wOfrH=m6OAEex;nHWH3^ACWh(w~_w3`{JgPpvfByK(A!k1u(#WrT zVx~Pew#kY7bj{-Uu0U0*v0>Bxn;-DN?y#_A2JM{o%KCOR_v{>^AL6gp1< zQeJaxc00etuDzZl!$Q+juM zXzYv4eg1a_y?YlH=SRKu4L3LtYSOE;_C0IQp2&9bCy!uVr%QsB^Wt63NJ2F63EPgs z^I{=V~`z$l-hD+ChcxV0t{oB#))Uu1P$iZ3m!H|TAGAZ z`?B6%g!BI4N*uJT;KKFr_)|wY*-R8=&({ z?3NaYA}!!{$FC+L%^eU9nW;k`EZvi7dz!T|dPovM8meR|y?YlOp&)rj+x7xp66Jvq zd@^mk`BcMqnjsi6XM(luB@1@<`H90dP~|VqKjL418)WJt#Fs03F==t+rLmZ?S}JvB zqDCkdE{W%-%8Gspvq?;ELx<&=F;6GR1z)yx4JFN&lJu-4r#TBxT;FM&x$a!_pG`{Q zk!*2sR$V%l!D79Bnmdn;8`PWI+?Pu{)-%JwEJktc)|35x{oD*kb6-)Zi`fPXW1@D> z()01r$Hk+)NB*k2MC#KSeo&x-UZ+AooHHUk+K;Od@f)es*!kJ63d2|8n1!_PFifiA z)t=FP?%^@;)}F3coyA{aLv!2a6)tdt+6EW3;uy%!nBl6K*Lb3qu*CMFuXWrK>l;f9 z?I@=hEK96@Ra)~MZOkS(7gs$^P~})T(5K<8b(^eX#MZ@s-j!))re3+}fDs)T=|B*= z=+Keh<3E@G*JTj9+<iaDN@KWNMjTaMh4#lt%)07bYlRz&rY zrfg1)y(>$Z6q+%IZve3B#K+AKYZ}@gO-STp^K31$Kz6y38Tb8ip=ct=ttMfU#48?nnXZoFnnXYh9S%TSEr(*45& z@cy97?xz*3)_Xr9!2T4wPpa0i`Iv%TVuI|clL>@X>V^9y-{9YYvgckY`2ouooZn9n zUTTgHmUt6dj}~mOculUtqUtT~K?r-QJkL$vIine(Q4|aH?`0uD+#SgnS-v~QdfL#3 zVvHT~)3}0~&P6?cz^0Ttb`&+9(VE`4Xyr%Vw zr1gBIY6K)W^Wot9#^9C~v8_%kPZgI1RZn^e8G)z7)_{FwO54ZJv~eO}va3GDW_o9-MxhPzXQO$(mDVD literal 0 HcmV?d00001 diff --git a/test/constraint/pt_face_distance/reference.slvs b/test/constraint/pt_face_distance/reference.slvs new file mode 100644 index 0000000..2d89471 --- /dev/null +++ b/test/constraint/pt_face_distance/reference.slvs @@ -0,0 +1,713 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=00020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000003 +Group.type=5100 +Group.order=2 +Group.name=extrude +Group.activeWorkplane.v=00010000 +Group.opA.v=00000002 +Group.color=00646464 +Group.subtype=7000 +Group.skipFirst=0 +Group.predef.entityB.v=00020000 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00040000 1002 + 2 00040001 1002 + 3 00040020 1002 + 4 00040040 1002 + 5 00040000 1001 + 6 00040001 1001 + 7 00040020 1001 + 8 00040040 1001 + 9 00040001 1003 + 10 80020000 1002 + 11 80020000 1001 + 12 80020001 1002 + 13 80020002 1002 + 14 80020001 1001 + 15 80020002 1001 + 16 80020002 1003 + 17 00000000 1001 + 18 00000000 1002 +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030000 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030001 +AddParam + +Param.h.v.=80030002 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=00020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=00010000 +Request.group.v=00000003 +Request.construction=1 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=00020000 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=1 +Entity.workplane.v=00010000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030001 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.normal.v=80030003 +Entity.distance.v=80030004 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030004 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.normal.v=80030007 +Entity.distance.v=80030008 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030007 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.point[1].v=80030002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=2010 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=2010 +Entity.construction=1 +Entity.actPoint.x=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030010 +Entity.type=11000 +Entity.construction=1 +Entity.point[0].v=8003000f +Entity.point[1].v=8003000d +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actPoint.x=10.00000000000000000000 +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=00020000 +Constraint.ptA.v=00010001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=33 +Constraint.group.v=00000003 +Constraint.workplane.v=00010000 +Constraint.valA=-10.00000000000000000000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=80030012 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=1 +AddConstraint + +Surface 00000001 00646464 80030012 1 1 +SCtrl 0 0 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 0.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000a 0 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 +TrimBy 00000001 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000004 0 0.00000000000000000000 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 +TrimBy 00000007 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000000000 +AddSurface +Surface 00000002 00646464 80030011 1 1 +SCtrl 0 0 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 10.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 10.00000000000000000000 5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000005 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 10.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000002 1 10.00000000000000000000 0.00000000000000000000 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000b 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 10.00000000000000000000 -0.00000000000000044409 -5.00000000000000000000 +TrimBy 00000008 1 10.00000000000000000000 -0.00000000000000044409 -5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 +AddSurface +Surface 00000003 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000002 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000001 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000c 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 00000003 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddSurface +Surface 00000004 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +TrimBy 00000005 0 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000004 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000003 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000006 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddSurface +Surface 00000005 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000008 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 00000007 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000006 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000009 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddSurface +Surface 00000006 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +TrimBy 0000000b 0 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +TrimBy 0000000a 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 00000009 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 0000000c 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddSurface +Curve 00000001 1 2 00000001 00000003 +CCtrl 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 0.00000000000000000000 4.91652684208287205081 0.90981526206072360630 +CurvePt 0 0.00000000000000000000 4.64894150531215188948 1.84047354780936389673 +CurvePt 0 0.00000000000000000000 4.18497755609325672310 2.73604876692571252761 +CurvePt 0 0.00000000000000000000 3.53553390593273775266 3.53553390593273775266 +CurvePt 0 0.00000000000000000000 2.73604876692571252761 4.18497755609325672310 +CurvePt 0 0.00000000000000000000 1.84047354780936411878 4.64894150531215188948 +CurvePt 0 0.00000000000000000000 0.90981526206072382834 4.91652684208287205081 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000002 1 2 00000002 00000003 +CCtrl 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 10.00000000000000000000 4.91652684208287205081 0.90981526206072360630 +CurvePt 0 10.00000000000000000000 4.64894150531215188948 1.84047354780936389673 +CurvePt 0 10.00000000000000000000 4.18497755609325672310 2.73604876692571252761 +CurvePt 0 10.00000000000000000000 3.53553390593273775266 3.53553390593273775266 +CurvePt 0 10.00000000000000000000 2.73604876692571252761 4.18497755609325672310 +CurvePt 0 10.00000000000000000000 1.84047354780936411878 4.64894150531215188948 +CurvePt 0 10.00000000000000000000 0.90981526206072382834 4.91652684208287205081 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000003 1 1 00000003 00000004 +CCtrl 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000004 1 2 00000001 00000004 +CCtrl 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 0 0.00000000000000000000 -0.90981526206072327323 4.91652684208287205081 +CurvePt 0 0.00000000000000000000 -1.84047354780936323060 4.64894150531215188948 +CurvePt 0 0.00000000000000000000 -2.73604876692571208352 4.18497755609325672310 +CurvePt 0 0.00000000000000000000 -3.53553390593273775266 3.53553390593273775266 +CurvePt 0 0.00000000000000000000 -4.18497755609325672310 2.73604876692571297170 +CurvePt 0 0.00000000000000000000 -4.64894150531215188948 1.84047354780936434082 +CurvePt 0 0.00000000000000000000 -4.91652684208287205081 0.90981526206072405039 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000005 1 2 00000002 00000004 +CCtrl 0 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 0 10.00000000000000000000 -0.90981526206072327323 4.91652684208287205081 +CurvePt 0 10.00000000000000000000 -1.84047354780936323060 4.64894150531215188948 +CurvePt 0 10.00000000000000000000 -2.73604876692571208352 4.18497755609325672310 +CurvePt 0 10.00000000000000000000 -3.53553390593273775266 3.53553390593273775266 +CurvePt 0 10.00000000000000000000 -4.18497755609325672310 2.73604876692571297170 +CurvePt 0 10.00000000000000000000 -4.64894150531215188948 1.84047354780936434082 +CurvePt 0 10.00000000000000000000 -4.91652684208287205081 0.90981526206072405039 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000006 1 1 00000004 00000005 +CCtrl 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000007 1 2 00000001 00000005 +CCtrl 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 0 0.00000000000000000000 -4.91652684208287205081 -0.90981526206072305119 +CurvePt 0 0.00000000000000000000 -4.64894150531215188948 -1.84047354780936300855 +CurvePt 0 0.00000000000000000000 -4.18497755609325672310 -2.73604876692571208352 +CurvePt 0 0.00000000000000000000 -3.53553390593273864084 -3.53553390593273730858 +CurvePt 0 0.00000000000000000000 -2.73604876692571297170 -4.18497755609325672310 +CurvePt 0 0.00000000000000000000 -1.84047354780936478491 -4.64894150531215188948 +CurvePt 0 0.00000000000000000000 -0.90981526206072438345 -4.91652684208287205081 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 00000008 1 2 00000002 00000005 +CCtrl 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 0 10.00000000000000000000 -4.91652684208287205081 -0.90981526206072305119 +CurvePt 0 10.00000000000000000000 -4.64894150531215188948 -1.84047354780936300855 +CurvePt 0 10.00000000000000000000 -4.18497755609325672310 -2.73604876692571208352 +CurvePt 0 10.00000000000000000000 -3.53553390593273864084 -3.53553390593273730858 +CurvePt 0 10.00000000000000000000 -2.73604876692571297170 -4.18497755609325672310 +CurvePt 0 10.00000000000000000000 -1.84047354780936478491 -4.64894150531215188948 +CurvePt 0 10.00000000000000000000 -0.90981526206072438345 -4.91652684208287205081 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 00000009 1 1 00000005 00000006 +CCtrl 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 0000000a 1 2 00000001 00000006 +CCtrl 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 0 0.00000000000000000000 0.90981526206072282914 -4.91652684208287205081 +CurvePt 0 0.00000000000000000000 1.84047354780936300855 -4.64894150531215188948 +CurvePt 0 0.00000000000000000000 2.73604876692571163943 -4.18497755609325672310 +CurvePt 0 0.00000000000000000000 3.53553390593273730858 -3.53553390593273864084 +CurvePt 0 0.00000000000000000000 4.18497755609325583492 -2.73604876692571297170 +CurvePt 0 0.00000000000000000000 4.64894150531215188948 -1.84047354780936500696 +CurvePt 0 0.00000000000000000000 4.91652684208287205081 -0.90981526206072471652 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve +Curve 0000000b 1 2 00000002 00000006 +CCtrl 0 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 0 10.00000000000000000000 0.90981526206072282914 -4.91652684208287205081 +CurvePt 0 10.00000000000000000000 1.84047354780936300855 -4.64894150531215188948 +CurvePt 0 10.00000000000000000000 2.73604876692571163943 -4.18497755609325672310 +CurvePt 0 10.00000000000000000000 3.53553390593273730858 -3.53553390593273864084 +CurvePt 0 10.00000000000000000000 4.18497755609325583492 -2.73604876692571297170 +CurvePt 0 10.00000000000000000000 4.64894150531215188948 -1.84047354780936500696 +CurvePt 0 10.00000000000000000000 4.91652684208287205081 -0.90981526206072471652 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve +Curve 0000000c 1 1 00000006 00000003 +CCtrl 0 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve diff --git a/test/constraint/pt_face_distance/reference_v20.slvs b/test/constraint/pt_face_distance/reference_v20.slvs new file mode 100644 index 0000000..c506e9b --- /dev/null +++ b/test/constraint/pt_face_distance/reference_v20.slvs @@ -0,0 +1,712 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=00020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000003 +Group.type=5100 +Group.order=2 +Group.name=extrude +Group.activeWorkplane.v=00010000 +Group.opA.v=00000002 +Group.color=00646464 +Group.subtype=7000 +Group.skipFirst=0 +Group.predef.entityB.v=00020000 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00040000 1002 + 2 00040001 1002 + 3 00040020 1002 + 4 00040040 1002 + 5 00040000 1001 + 6 00040001 1001 + 7 00040020 1001 + 8 00040040 1001 + 9 00040001 1003 + 10 80020000 1002 + 11 80020000 1001 + 12 80020001 1002 + 13 80020002 1002 + 14 80020001 1001 + 15 80020002 1001 + 16 80020002 1003 + 17 00000000 1001 + 18 00000000 1002 +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030000 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030001 +AddParam + +Param.h.v.=80030002 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=00020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=00010000 +Request.group.v=00000003 +Request.construction=1 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=00020000 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00010000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030001 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.normal.v=80030003 +Entity.distance.v=80030004 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030004 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.normal.v=80030007 +Entity.distance.v=80030008 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030007 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.point[1].v=80030002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030010 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.point[1].v=8003000d +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actPoint.x=10.00000000000000000000 +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=00020000 +Constraint.ptA.v=00010001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=33 +Constraint.group.v=00000003 +Constraint.workplane.v=00010000 +Constraint.valA=-10.00000000000000000000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=80030012 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=1 +AddConstraint + +Surface 00000001 00646464 80030012 1 1 +SCtrl 0 0 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 0.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000a 0 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 +TrimBy 00000001 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000004 0 0.00000000000000000000 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 +TrimBy 00000007 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000000000 +AddSurface +Surface 00000002 00646464 80030011 1 1 +SCtrl 0 0 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 10.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 10.00000000000000000000 5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000005 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 10.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000002 1 10.00000000000000000000 0.00000000000000000000 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000b 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 10.00000000000000000000 -0.00000000000000044409 -5.00000000000000000000 +TrimBy 00000008 1 10.00000000000000000000 -0.00000000000000044409 -5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 +AddSurface +Surface 00000003 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 1 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 2 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000002 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000003 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000001 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000c 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000004 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 -4.99999999999999910000 5.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 1 1 10.00000000000000000000 -4.99999999999999910000 5.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 2 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +TrimBy 00000005 0 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000006 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000004 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000003 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddSurface +Surface 00000005 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 -5.00000000000000090000 -4.99999999999999910000 Weight 0.70710678118654757000 +SCtrl 1 1 10.00000000000000000000 -5.00000000000000090000 -4.99999999999999910000 Weight 0.70710678118654757000 +SCtrl 2 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000008 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 00000009 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 00000007 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000006 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddSurface +Surface 00000006 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 4.99999999999999910000 -5.00000000000000090000 Weight 0.70710678118654757000 +SCtrl 1 1 10.00000000000000000000 4.99999999999999910000 -5.00000000000000090000 Weight 0.70710678118654757000 +SCtrl 2 0 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +TrimBy 0000000b 0 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +TrimBy 0000000c 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +TrimBy 0000000a 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 00000009 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddSurface +Curve 00000001 1 2 00000001 00000003 +CCtrl 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 0.00000000000000000000 4.91652684208287210000 0.90981526206072361000 +CurvePt 0 0.00000000000000000000 4.64894150531215190000 1.84047354780936390000 +CurvePt 0 0.00000000000000000000 4.18497755609325670000 2.73604876692571250000 +CurvePt 0 0.00000000000000000000 3.53553390593273780000 3.53553390593273780000 +CurvePt 0 0.00000000000000000000 2.73604876692571250000 4.18497755609325670000 +CurvePt 0 0.00000000000000000000 1.84047354780936410000 4.64894150531215190000 +CurvePt 0 0.00000000000000000000 0.90981526206072383000 4.91652684208287210000 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000002 1 2 00000002 00000003 +CCtrl 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 10.00000000000000000000 4.91652684208287210000 0.90981526206072361000 +CurvePt 0 10.00000000000000000000 4.64894150531215190000 1.84047354780936390000 +CurvePt 0 10.00000000000000000000 4.18497755609325670000 2.73604876692571250000 +CurvePt 0 10.00000000000000000000 3.53553390593273780000 3.53553390593273780000 +CurvePt 0 10.00000000000000000000 2.73604876692571250000 4.18497755609325670000 +CurvePt 0 10.00000000000000000000 1.84047354780936410000 4.64894150531215190000 +CurvePt 0 10.00000000000000000000 0.90981526206072383000 4.91652684208287210000 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000003 1 1 00000003 00000004 +CCtrl 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000004 1 2 00000001 00000004 +CCtrl 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 -4.99999999999999910000 5.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 0 0.00000000000000000000 -0.90981526206072327000 4.91652684208287210000 +CurvePt 0 0.00000000000000000000 -1.84047354780936320000 4.64894150531215190000 +CurvePt 0 0.00000000000000000000 -2.73604876692571210000 4.18497755609325670000 +CurvePt 0 0.00000000000000000000 -3.53553390593273780000 3.53553390593273780000 +CurvePt 0 0.00000000000000000000 -4.18497755609325670000 2.73604876692571300000 +CurvePt 0 0.00000000000000000000 -4.64894150531215190000 1.84047354780936430000 +CurvePt 0 0.00000000000000000000 -4.91652684208287210000 0.90981526206072405000 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000005 1 2 00000002 00000004 +CCtrl 0 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -4.99999999999999910000 5.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 0 10.00000000000000000000 -0.90981526206072327000 4.91652684208287210000 +CurvePt 0 10.00000000000000000000 -1.84047354780936320000 4.64894150531215190000 +CurvePt 0 10.00000000000000000000 -2.73604876692571210000 4.18497755609325670000 +CurvePt 0 10.00000000000000000000 -3.53553390593273780000 3.53553390593273780000 +CurvePt 0 10.00000000000000000000 -4.18497755609325670000 2.73604876692571300000 +CurvePt 0 10.00000000000000000000 -4.64894150531215190000 1.84047354780936430000 +CurvePt 0 10.00000000000000000000 -4.91652684208287210000 0.90981526206072405000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000006 1 1 00000004 00000005 +CCtrl 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000007 1 2 00000001 00000005 +CCtrl 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 -5.00000000000000090000 -4.99999999999999910000 Weight 0.70710678118654757000 +CCtrl 2 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 0 0.00000000000000000000 -4.91652684208287210000 -0.90981526206072305000 +CurvePt 0 0.00000000000000000000 -4.64894150531215190000 -1.84047354780936300000 +CurvePt 0 0.00000000000000000000 -4.18497755609325670000 -2.73604876692571210000 +CurvePt 0 0.00000000000000000000 -3.53553390593273860000 -3.53553390593273730000 +CurvePt 0 0.00000000000000000000 -2.73604876692571300000 -4.18497755609325670000 +CurvePt 0 0.00000000000000000000 -1.84047354780936480000 -4.64894150531215190000 +CurvePt 0 0.00000000000000000000 -0.90981526206072438000 -4.91652684208287210000 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 00000008 1 2 00000002 00000005 +CCtrl 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000090000 -4.99999999999999910000 Weight 0.70710678118654757000 +CCtrl 2 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 0 10.00000000000000000000 -4.91652684208287210000 -0.90981526206072305000 +CurvePt 0 10.00000000000000000000 -4.64894150531215190000 -1.84047354780936300000 +CurvePt 0 10.00000000000000000000 -4.18497755609325670000 -2.73604876692571210000 +CurvePt 0 10.00000000000000000000 -3.53553390593273860000 -3.53553390593273730000 +CurvePt 0 10.00000000000000000000 -2.73604876692571300000 -4.18497755609325670000 +CurvePt 0 10.00000000000000000000 -1.84047354780936480000 -4.64894150531215190000 +CurvePt 0 10.00000000000000000000 -0.90981526206072438000 -4.91652684208287210000 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 00000009 1 1 00000005 00000006 +CCtrl 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 0000000a 1 2 00000001 00000006 +CCtrl 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 4.99999999999999910000 -5.00000000000000090000 Weight 0.70710678118654757000 +CCtrl 2 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 0 0.00000000000000000000 0.90981526206072283000 -4.91652684208287210000 +CurvePt 0 0.00000000000000000000 1.84047354780936300000 -4.64894150531215190000 +CurvePt 0 0.00000000000000000000 2.73604876692571160000 -4.18497755609325670000 +CurvePt 0 0.00000000000000000000 3.53553390593273730000 -3.53553390593273860000 +CurvePt 0 0.00000000000000000000 4.18497755609325580000 -2.73604876692571300000 +CurvePt 0 0.00000000000000000000 4.64894150531215190000 -1.84047354780936500000 +CurvePt 0 0.00000000000000000000 4.91652684208287210000 -0.90981526206072472000 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve +Curve 0000000b 1 2 00000002 00000006 +CCtrl 0 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 4.99999999999999910000 -5.00000000000000090000 Weight 0.70710678118654757000 +CCtrl 2 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 0 10.00000000000000000000 0.90981526206072283000 -4.91652684208287210000 +CurvePt 0 10.00000000000000000000 1.84047354780936300000 -4.64894150531215190000 +CurvePt 0 10.00000000000000000000 2.73604876692571160000 -4.18497755609325670000 +CurvePt 0 10.00000000000000000000 3.53553390593273730000 -3.53553390593273860000 +CurvePt 0 10.00000000000000000000 4.18497755609325580000 -2.73604876692571300000 +CurvePt 0 10.00000000000000000000 4.64894150531215190000 -1.84047354780936500000 +CurvePt 0 10.00000000000000000000 4.91652684208287210000 -0.90981526206072472000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve +Curve 0000000c 1 1 00000006 00000003 +CCtrl 0 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve diff --git a/test/constraint/pt_face_distance/reference_v22.slvs b/test/constraint/pt_face_distance/reference_v22.slvs new file mode 100644 index 0000000..a57b808 --- /dev/null +++ b/test/constraint/pt_face_distance/reference_v22.slvs @@ -0,0 +1,681 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=00020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000003 +Group.type=5100 +Group.order=2 +Group.name=extrude +Group.activeWorkplane.v=00010000 +Group.opA.v=00000002 +Group.color=00646464 +Group.subtype=7000 +Group.skipFirst=0 +Group.predef.entityB.v=00020000 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00040000 1002 + 2 00040001 1002 + 3 00040020 1002 + 4 00040040 1002 + 5 00040000 1001 + 6 00040001 1001 + 7 00040020 1001 + 8 00040040 1001 + 9 00040001 1003 + 10 80020000 1002 + 11 80020000 1001 + 12 80020001 1002 + 13 80020002 1002 + 14 80020001 1001 + 15 80020002 1001 + 16 80020002 1003 + 17 00000000 1001 + 18 00000000 1002 +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030000 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030001 +AddParam + +Param.h.v.=80030002 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=00020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=00010000 +Request.group.v=00000003 +Request.construction=1 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=00020000 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=00020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=00010000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030001 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.normal.v=80030003 +Entity.distance.v=80030004 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030004 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.normal.v=80030007 +Entity.distance.v=80030008 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030007 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.point[1].v=80030002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030010 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.point[1].v=8003000d +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actPoint.x=10.00000000000000000000 +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=00020000 +Constraint.ptA.v=00010001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=33 +Constraint.group.v=00000003 +Constraint.workplane.v=00010000 +Constraint.valA=-10.00000000000000000000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=80030012 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=1 +AddConstraint + +Surface 00000001 00646464 80030012 1 1 +SCtrl 0 0 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 0.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000a 0 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 +TrimBy 00000001 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000004 0 0.00000000000000000000 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 +TrimBy 00000007 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000000000 +AddSurface +Surface 00000002 00646464 80030011 1 1 +SCtrl 0 0 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 10.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 10.00000000000000000000 5.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000005 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 10.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000002 1 10.00000000000000000000 0.00000000000000000000 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000b 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 10.00000000000000000000 -0.00000000000000044409 -5.00000000000000000000 +TrimBy 00000008 1 10.00000000000000000000 -0.00000000000000044409 -5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000044409 +AddSurface +Surface 00000003 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000002 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000001 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000c 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 00000003 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddSurface +Surface 00000004 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +TrimBy 00000005 0 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000004 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000003 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +TrimBy 00000006 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddSurface +Surface 00000005 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000008 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 00000007 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000006 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +TrimBy 00000009 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddSurface +Surface 00000006 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 0.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +SCtrl 1 1 10.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +SCtrl 2 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +TrimBy 0000000b 0 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +TrimBy 0000000a 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 00000009 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +TrimBy 0000000c 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddSurface +Curve 00000001 1 2 00000001 00000003 +CCtrl 0 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 0.00000000000000000000 4.64894150531215188948 1.84047354780936389673 +CurvePt 0 0.00000000000000000000 3.53553390593273775266 3.53553390593273775266 +CurvePt 0 0.00000000000000000000 1.84047354780936411878 4.64894150531215188948 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000002 1 2 00000002 00000003 +CCtrl 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 10.00000000000000000000 4.64894150531215188948 1.84047354780936389673 +CurvePt 0 10.00000000000000000000 3.53553390593273775266 3.53553390593273775266 +CurvePt 0 10.00000000000000000000 1.84047354780936411878 4.64894150531215188948 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000003 1 1 00000003 00000004 +CCtrl 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +AddCurve +Curve 00000004 1 2 00000001 00000004 +CCtrl 0 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 0 0.00000000000000000000 -1.84047354780936323060 4.64894150531215188948 +CurvePt 0 0.00000000000000000000 -3.53553390593273775266 3.53553390593273775266 +CurvePt 0 0.00000000000000000000 -4.64894150531215188948 1.84047354780936434082 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000005 1 2 00000002 00000004 +CCtrl 0 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -4.99999999999999911182 5.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 +CurvePt 0 10.00000000000000000000 -1.84047354780936323060 4.64894150531215188948 +CurvePt 0 10.00000000000000000000 -3.53553390593273775266 3.53553390593273775266 +CurvePt 0 10.00000000000000000000 -4.64894150531215188948 1.84047354780936434082 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000006 1 1 00000004 00000005 +CCtrl 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +AddCurve +Curve 00000007 1 2 00000001 00000005 +CCtrl 0 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 0 0.00000000000000000000 -4.64894150531215188948 -1.84047354780936300855 +CurvePt 0 0.00000000000000000000 -3.53553390593273864084 -3.53553390593273730858 +CurvePt 0 0.00000000000000000000 -1.84047354780936478491 -4.64894150531215188948 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 00000008 1 2 00000002 00000005 +CCtrl 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000088818 -4.99999999999999911182 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 +CurvePt 0 10.00000000000000000000 -4.64894150531215188948 -1.84047354780936300855 +CurvePt 0 10.00000000000000000000 -3.53553390593273864084 -3.53553390593273730858 +CurvePt 0 10.00000000000000000000 -1.84047354780936478491 -4.64894150531215188948 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 00000009 1 1 00000005 00000006 +CCtrl 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +AddCurve +Curve 0000000a 1 2 00000001 00000006 +CCtrl 0 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 0 0.00000000000000000000 1.84047354780936300855 -4.64894150531215188948 +CurvePt 0 0.00000000000000000000 3.53553390593273730858 -3.53553390593273864084 +CurvePt 0 0.00000000000000000000 4.64894150531215188948 -1.84047354780936500696 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve +Curve 0000000b 1 2 00000002 00000006 +CCtrl 0 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 4.99999999999999911182 -5.00000000000000088818 Weight 0.70710678118654757274 +CCtrl 2 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 +CurvePt 0 10.00000000000000000000 1.84047354780936300855 -4.64894150531215188948 +CurvePt 0 10.00000000000000000000 3.53553390593273730858 -3.53553390593273864084 +CurvePt 0 10.00000000000000000000 4.64894150531215188948 -1.84047354780936500696 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve +Curve 0000000c 1 1 00000006 00000003 +CCtrl 0 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 +AddCurve diff --git a/test/constraint/pt_face_distance/test.cpp b/test/constraint/pt_face_distance/test.cpp new file mode 100644 index 0000000..7e2a06e --- /dev/null +++ b/test/constraint/pt_face_distance/test.cpp @@ -0,0 +1,33 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(reference_roundtrip) { + CHECK_LOAD("reference.slvs"); + CHECK_RENDER("reference.png"); + CHECK_SAVE("reference.slvs"); +} + +TEST_CASE(reference_migrate_from_v20) { + CHECK_LOAD("reference_v20.slvs"); + CHECK_SAVE("reference.slvs"); +} + +TEST_CASE(reference_migrate_from_v22) { + CHECK_LOAD("reference_v22.slvs"); + CHECK_SAVE("reference.slvs"); +} diff --git a/test/constraint/pt_in_plane/normal.png b/test/constraint/pt_in_plane/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..b770451f3a56df7288f51e1c10d35646b2135cb7 GIT binary patch literal 4228 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%0Dr5 zm#d|7B>i+ik;R>5^B=8*)|0^n8d%l)o@FuKyMh?vtn87Wh!NCItWP@r zuZnhhjMzLl^kQNA3kR@&b7}2xQgUza-lg6ieM)^{CY$izFXAMqv^;pYk0QpFB7eld NCYLQ6ve%Oj{R_kdMsffE literal 0 HcmV?d00001 diff --git a/test/constraint/pt_line_distance/extended.slvs b/test/constraint/pt_line_distance/extended.slvs new file mode 100644 index 0000000..c73570d --- /dev/null +++ b/test/constraint/pt_line_distance/extended.slvs @@ -0,0 +1,316 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=32 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=-5.00000000000000000000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.x=-10.00000000000000000000 +Constraint.disp.offset.y=0.0000000000000000000 +AddConstraint + diff --git a/test/constraint/pt_line_distance/free_in_3d.png b/test/constraint/pt_line_distance/free_in_3d.png new file mode 100644 index 0000000000000000000000000000000000000000..db351dfde01e033f02d4a60e598aa85385f99d74 GIT binary patch literal 4403 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 literal 0 HcmV?d00001 diff --git a/test/constraint/pt_on_circle/normal.slvs b/test/constraint/pt_on_circle/normal.slvs new file mode 100644 index 0000000..462e0cd --- /dev/null +++ b/test/constraint/pt_on_circle/normal.slvs @@ -0,0 +1,318 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-9.99999912024158099655 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=4.99999824048316199310 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000087975841900345 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-9.99999912024158099655 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=4.99999824048316199310 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000087975841900345 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=100 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/pt_on_circle/normal_v20.slvs b/test/constraint/pt_on_circle/normal_v20.slvs new file mode 100644 index 0000000..d36fc3b --- /dev/null +++ b/test/constraint/pt_on_circle/normal_v20.slvs @@ -0,0 +1,318 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-9.99999912024158100000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=4.99999824048316200000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000087975841900000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-9.99999912024158100000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=4.99999824048316200000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000087975841900000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=100 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/pt_on_circle/normal_v22.slvs b/test/constraint/pt_on_circle/normal_v22.slvs new file mode 100644 index 0000000..fea01e6 --- /dev/null +++ b/test/constraint/pt_on_circle/normal_v22.slvs @@ -0,0 +1,318 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-9.99999912024158100000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=4.99999824048316200000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000087975841900000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-9.99999912024158100000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=4.99999824048316200000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000087975841900000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=100 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/pt_on_circle/test.cpp b/test/constraint/pt_on_circle/test.cpp new file mode 100644 index 0000000..ce38ba5 --- /dev/null +++ b/test/constraint/pt_on_circle/test.cpp @@ -0,0 +1,23 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(negative_dia) { + CHECK_LOAD("negative_dia.slvs"); + Entity *e = SK.GetEntity(hRequest { 4 }.entity(0)); + CHECK_TRUE(e->CircleGetRadiusNum() > 0); +} diff --git a/test/constraint/pt_on_face/normal.png b/test/constraint/pt_on_face/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..0d6ef8215d12540e19517c40006ac4f53ed8239f GIT binary patch literal 4662 zcmeHLdpMM78-M0CqhTnA9KLEPV%top&9V$85!Pv2Vw^`}TeK6tXh!i;tx#-bQ9?)O zVQP0A7ca^r6^db1%&xC>n1pqhgz>%7woT1;eb-*s_kI8DT<=`(T=Txq^W69Eci;E( zyPt&59j#@hS4jf^WNmFMzW@NDEPnBl=s&fA8IJ&vpSQK#=5p}-$m4Bc4{gqU^Rs2V zUi<1Hh462rO9x~W2X!3$pSAH5jko(+^xWBOl(ed9ug4|wkY@Dy-{=~uJIey}t`Mu-CROZ= z^OUqfFTcn_3pU$f;^uwfQ~QLc$)B)Nw5tppnTEnA!Z8blx6lU*kW(2VUcF5_+5Fc^1`ZU7dVvDF-^(h>5GMlWf!HU} zp8#arS#dMAr34iCVA?V-O?)E)Zb%R_t55|4_OBPqUMxoH8n^ad z2a$-ScvCBLWWoN=#m+eC?_THzCUXaWTqgo9)yoz5d|Mk^K zJ=EP$N1N-32`Q7NYQ7HLVqI2ZNdhz*X`Iy?JvWg<6OxeL?jyKV+neoCoU_`7d~6V& zNOc~)*)}mT5nm^mD({+}NT7Zn3M1y3Xmt30OP z(UcOfY49b6_w@k&r!B?YN4e{sklMH0 zh0GeuZ)2W?(FK#ed9LN>%?%@ymYHp*Vv0T(I?Y?v+S+PWdNcj+boa^>*+@mpL7%Cb(x8cN{ z$-?9=wI;Owk5O|e`f9PbBjY#Kc;l!Q4O)c^p$v7+Qasg@z0`{P+40x#L|C@c9`BE? z4tzT>Wm-!Ki0pXU7#E5ssvgyQmLhn_51vwhv*ajXT@1;T-RI+bO!;XuDV@YbApDE| zp&{$NHJr@lyyuHym=RdtUAs#U94zk5(<)u4!ly0>XE;s^GcK%4Q@Wb`l)S^GO1BC# zsY>38IOFMZ;l0)A=`s%AQ`ew-a0r4WG<^}3Fs9>N9MG&jd)eQ(wm(bNv{*b|?pMP?A4<(;HuSU}!YjCugTEWq zzK)6?s;1FGmI)qVWdF%;gHdPss* zz%ZY4M^sUkZfI?U_bqaA+*36PiQ87O703D@7RQo5Md(Kxy~=2~gFwVtt^WJw%Z7KYiV_^wSf0ONkz{#hp$n-F%`2OOV`i z2^yoIZv-~{W;D>{dZ!@+UH-O;kTbEWu>$>hZ>3Iaur#_*H@)G$og8Ui7&WEf`f*KM z)~jeVTK8?IT``oR#e%u#^lezzJ}^S-b!57y!*%3~j;{~UTnb}ZMG+)zG@1BWwn3$h&Z z)cx-B1Gf9&)-Tqid)w~&@0HTw$q(zwE2AN+Ht^#5&)ldVp84e{joD~Z$d8^_7O~4R z3%CcKCT!>&#ZSm~i^cSV$6&5geyo3|ph_YM1yIv3>gois}#W!>;5*W$Rh+-5MoN zW&lmFHXr^BB5XLIb5ysV-`huM^9bJO{#iEn_dUtMXoRBM-5bDu!sa@5CIMii zAb!Z7cY1L2o$x7XxOe3nebs6`mLsZmKyryLYop+c<3zxVZOTL!B)!`;iUXu)Z~0?V zOqui0MgU8E{Qr*7Oyj>|ib;6T<;NcCAlaHalG+w$_ynsSLcTPxCeG76Nyq%C#i+r_&B zb>zh2ofgzPQl~RuE)$9a^I_`6S(U2^6#{ORGcKYQ$yQ2V@?0QvvIt6OQEj2FFyD-4yS_;C@J8h{5+Ac;5 zsNS3|=ITTUgyi=jjFejtNSyiyWz^gFpP$Nu3YQK^=h=y9*@xfPNmry#NTMcxi1yMZ zt|s*_Zn+7s4nIeQ$*arviY}VH%WrF0{7+9r{^S5=)?B@N$U}>`We0j51Z=GwElVt@ GasLL6s(|+Z literal 0 HcmV?d00001 diff --git a/test/constraint/pt_on_face/normal.slvs b/test/constraint/pt_on_face/normal.slvs new file mode 100644 index 0000000..7656071 --- /dev/null +++ b/test/constraint/pt_on_face/normal.slvs @@ -0,0 +1,703 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000003 +Group.type=5100 +Group.order=2 +Group.name=extrude +Group.activeWorkplane.v=00010000 +Group.opA.v=00000002 +Group.color=00646464 +Group.subtype=7000 +Group.skipFirst=0 +Group.predef.entityB.v=80020000 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00040000 1002 + 2 00040001 1002 + 3 00040020 1002 + 4 00040040 1002 + 5 00040000 1001 + 6 00040001 1001 + 7 00040020 1001 + 8 00040040 1001 + 9 00040001 1003 + 10 80020000 1002 + 11 80020000 1001 + 12 80020001 1002 + 13 80020002 1002 + 14 80020001 1001 + 15 80020002 1001 + 16 80020002 1003 + 17 00000000 1001 + 18 00000000 1002 +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=80030000 +AddParam + +Param.h.v.=80030001 +AddParam + +Param.h.v.=80030002 +Param.val=-5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.group.v=00000003 +Request.construction=1 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2000 +Entity.construction=1 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030001 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.normal.v=80030003 +Entity.distance.v=80030004 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030004 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.normal.v=80030007 +Entity.distance.v=80030008 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.z=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030007 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.point[1].v=80030002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=2010 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=2010 +Entity.construction=1 +Entity.actPoint.z=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030010 +Entity.type=11000 +Entity.construction=1 +Entity.point[0].v=8003000f +Entity.point[1].v=8003000d +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actPoint.z=-10.00000000000000000000 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00010001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=43 +Constraint.group.v=00000003 +Constraint.ptA.v=00050000 +Constraint.entityA.v=80030012 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Surface 00000001 00646464 80030011 1 1 +SCtrl 0 0 -5.00000000000000000000 -5.00000000000000088818 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 5.00000000010000000827 -5.00000000000000088818 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -5.00000000000000000000 4.99999999999999911182 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 5.00000000010000000827 4.99999999999999911182 -10.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000a 0 -0.00000000000000177636 -5.00000000000000088818 -10.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 -10.00000000000000000000 +TrimBy 00000001 0 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 0.00000000000000000000 4.99999999999999911182 -10.00000000000000000000 +TrimBy 00000004 0 0.00000000000000000000 4.99999999999999911182 -10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 +TrimBy 00000007 0 -5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 -0.00000000000000177636 -5.00000000000000088818 -10.00000000000000000000 +AddSurface +Surface 00000002 00646464 80030012 1 1 +SCtrl 0 0 5.00000000010000000827 -5.00000000000000088818 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -5.00000000000000000000 -5.00000000000000088818 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 5.00000000010000000827 4.99999999999999911182 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 -5.00000000000000000000 4.99999999999999911182 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000005 1 -5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 0.00000000000000000000 4.99999999999999911182 0.00000000000000000000 +TrimBy 00000002 1 0.00000000000000000000 4.99999999999999911182 0.00000000000000000000 5.00000000000000088818 -0.00000000000000000000 0.00000000000000000000 +TrimBy 0000000b 1 5.00000000000000088818 -0.00000000000000088818 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000088818 0.00000000000000000000 +TrimBy 00000008 1 -0.00000000000000088818 -5.00000000000000088818 0.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000003 00646464 00000000 2 1 +SCtrl 0 0 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 5.00000000000000000000 5.00000000000000000000 -10.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000002 0 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +TrimBy 00000001 1 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 +TrimBy 0000000c 0 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 +TrimBy 00000003 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +AddSurface +Surface 00000004 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -4.99999999999999911182 5.00000000000000000000 -10.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 -4.99999999999999911182 5.00000000000000000000 0.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000005 0 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +TrimBy 00000004 1 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +TrimBy 00000003 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +TrimBy 00000006 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +AddSurface +Surface 00000005 00646464 00000000 2 1 +SCtrl 0 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -5.00000000000000088818 -4.99999999999999911182 -10.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 -5.00000000000000088818 -4.99999999999999911182 0.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000008 0 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +TrimBy 00000007 1 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +TrimBy 00000006 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +TrimBy 00000009 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +AddSurface +Surface 00000006 00646464 00000000 2 1 +SCtrl 0 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 4.99999999999999911182 -5.00000000000000088818 -10.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 4.99999999999999911182 -5.00000000000000088818 0.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000b 0 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 +TrimBy 0000000a 1 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +TrimBy 00000009 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000c 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 +AddSurface +Curve 00000001 1 2 00000001 00000003 +CCtrl 0 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 5.00000000000000000000 -10.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 +CurvePt 0 4.91652684208287205081 0.90981526206072360630 -10.00000000000000000000 +CurvePt 0 4.64894150531215188948 1.84047354780936389673 -10.00000000000000000000 +CurvePt 0 4.18497755609325672310 2.73604876692571252761 -10.00000000000000000000 +CurvePt 0 3.53553390593273775266 3.53553390593273775266 -10.00000000000000000000 +CurvePt 0 2.73604876692571252761 4.18497755609325672310 -10.00000000000000000000 +CurvePt 0 1.84047354780936411878 4.64894150531215188948 -10.00000000000000000000 +CurvePt 0 0.90981526206072382834 4.91652684208287205081 -10.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +AddCurve +Curve 00000002 1 2 00000002 00000003 +CCtrl 0 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 +CurvePt 0 4.91652684208287205081 0.90981526206072360630 0.00000000000000000000 +CurvePt 0 4.64894150531215188948 1.84047354780936389673 0.00000000000000000000 +CurvePt 0 4.18497755609325672310 2.73604876692571252761 0.00000000000000000000 +CurvePt 0 3.53553390593273775266 3.53553390593273775266 0.00000000000000000000 +CurvePt 0 2.73604876692571252761 4.18497755609325672310 0.00000000000000000000 +CurvePt 0 1.84047354780936411878 4.64894150531215188948 0.00000000000000000000 +CurvePt 0 0.90981526206072382834 4.91652684208287205081 0.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000003 1 1 00000003 00000004 +CCtrl 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000004 1 2 00000001 00000004 +CCtrl 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -4.99999999999999911182 5.00000000000000000000 -10.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +CurvePt 0 -0.90981526206072327323 4.91652684208287205081 -10.00000000000000000000 +CurvePt 0 -1.84047354780936323060 4.64894150531215188948 -10.00000000000000000000 +CurvePt 0 -2.73604876692571208352 4.18497755609325672310 -10.00000000000000000000 +CurvePt 0 -3.53553390593273775266 3.53553390593273775266 -10.00000000000000000000 +CurvePt 0 -4.18497755609325672310 2.73604876692571297170 -10.00000000000000000000 +CurvePt 0 -4.64894150531215188948 1.84047354780936434082 -10.00000000000000000000 +CurvePt 0 -4.91652684208287205081 0.90981526206072405039 -10.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +AddCurve +Curve 00000005 1 2 00000002 00000004 +CCtrl 0 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -4.99999999999999911182 5.00000000000000000000 0.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 -0.90981526206072327323 4.91652684208287205081 0.00000000000000000000 +CurvePt 0 -1.84047354780936323060 4.64894150531215188948 0.00000000000000000000 +CurvePt 0 -2.73604876692571208352 4.18497755609325672310 0.00000000000000000000 +CurvePt 0 -3.53553390593273775266 3.53553390593273775266 0.00000000000000000000 +CurvePt 0 -4.18497755609325672310 2.73604876692571297170 0.00000000000000000000 +CurvePt 0 -4.64894150531215188948 1.84047354780936434082 0.00000000000000000000 +CurvePt 0 -4.91652684208287205081 0.90981526206072405039 0.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +AddCurve +Curve 00000006 1 1 00000004 00000005 +CCtrl 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +AddCurve +Curve 00000007 1 2 00000001 00000005 +CCtrl 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000088818 -4.99999999999999911182 -10.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +CurvePt 0 -4.91652684208287205081 -0.90981526206072305119 -10.00000000000000000000 +CurvePt 0 -4.64894150531215188948 -1.84047354780936300855 -10.00000000000000000000 +CurvePt 0 -4.18497755609325672310 -2.73604876692571208352 -10.00000000000000000000 +CurvePt 0 -3.53553390593273864084 -3.53553390593273730858 -10.00000000000000000000 +CurvePt 0 -2.73604876692571297170 -4.18497755609325672310 -10.00000000000000000000 +CurvePt 0 -1.84047354780936478491 -4.64894150531215188948 -10.00000000000000000000 +CurvePt 0 -0.90981526206072438345 -4.91652684208287205081 -10.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +AddCurve +Curve 00000008 1 2 00000002 00000005 +CCtrl 0 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000088818 -4.99999999999999911182 0.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +CurvePt 0 -4.91652684208287205081 -0.90981526206072305119 0.00000000000000000000 +CurvePt 0 -4.64894150531215188948 -1.84047354780936300855 0.00000000000000000000 +CurvePt 0 -4.18497755609325672310 -2.73604876692571208352 0.00000000000000000000 +CurvePt 0 -3.53553390593273864084 -3.53553390593273730858 0.00000000000000000000 +CurvePt 0 -2.73604876692571297170 -4.18497755609325672310 0.00000000000000000000 +CurvePt 0 -1.84047354780936478491 -4.64894150531215188948 0.00000000000000000000 +CurvePt 0 -0.90981526206072438345 -4.91652684208287205081 0.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000009 1 1 00000005 00000006 +CCtrl 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 0000000a 1 2 00000001 00000006 +CCtrl 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 4.99999999999999911182 -5.00000000000000088818 -10.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +CurvePt 0 0.90981526206072282914 -4.91652684208287205081 -10.00000000000000000000 +CurvePt 0 1.84047354780936300855 -4.64894150531215188948 -10.00000000000000000000 +CurvePt 0 2.73604876692571163943 -4.18497755609325672310 -10.00000000000000000000 +CurvePt 0 3.53553390593273730858 -3.53553390593273864084 -10.00000000000000000000 +CurvePt 0 4.18497755609325583492 -2.73604876692571297170 -10.00000000000000000000 +CurvePt 0 4.64894150531215188948 -1.84047354780936500696 -10.00000000000000000000 +CurvePt 0 4.91652684208287205081 -0.90981526206072471652 -10.00000000000000000000 +CurvePt 1 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 +AddCurve +Curve 0000000b 1 2 00000002 00000006 +CCtrl 0 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 4.99999999999999911182 -5.00000000000000088818 0.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +CurvePt 0 0.90981526206072282914 -4.91652684208287205081 0.00000000000000000000 +CurvePt 0 1.84047354780936300855 -4.64894150531215188948 0.00000000000000000000 +CurvePt 0 2.73604876692571163943 -4.18497755609325672310 0.00000000000000000000 +CurvePt 0 3.53553390593273730858 -3.53553390593273864084 0.00000000000000000000 +CurvePt 0 4.18497755609325583492 -2.73604876692571297170 0.00000000000000000000 +CurvePt 0 4.64894150531215188948 -1.84047354780936500696 0.00000000000000000000 +CurvePt 0 4.91652684208287205081 -0.90981526206072471652 0.00000000000000000000 +CurvePt 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 +AddCurve +Curve 0000000c 1 1 00000006 00000003 +CCtrl 0 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 +CurvePt 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 +AddCurve diff --git a/test/constraint/pt_on_face/normal_v20.slvs b/test/constraint/pt_on_face/normal_v20.slvs new file mode 100644 index 0000000..e3c7212 --- /dev/null +++ b/test/constraint/pt_on_face/normal_v20.slvs @@ -0,0 +1,670 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000003 +Group.type=5100 +Group.order=2 +Group.name=extrude +Group.activeWorkplane.v=00010000 +Group.opA.v=00000002 +Group.color=00646464 +Group.subtype=7000 +Group.skipFirst=0 +Group.predef.entityB.v=80020000 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00040000 1002 + 2 00040001 1002 + 3 00040020 1002 + 4 00040040 1002 + 5 00040000 1001 + 6 00040001 1001 + 7 00040020 1001 + 8 00040040 1001 + 9 00040001 1003 + 10 80020000 1002 + 11 80020000 1001 + 12 80020001 1002 + 13 80020002 1002 + 14 80020001 1001 + 15 80020002 1001 + 16 80020002 1003 + 17 00000000 1001 + 18 00000000 1002 +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=80030000 +AddParam + +Param.h.v.=80030001 +AddParam + +Param.h.v.=80030002 +Param.val=-5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.group.v=00000003 +Request.construction=1 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030001 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.normal.v=80030003 +Entity.distance.v=80030004 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030004 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.normal.v=80030007 +Entity.distance.v=80030008 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.z=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030007 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.point[1].v=80030002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.z=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030010 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.point[1].v=8003000d +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actPoint.z=-10.00000000000000000000 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00010001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=43 +Constraint.group.v=00000003 +Constraint.ptA.v=00050000 +Constraint.entityA.v=80030012 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Surface 00000001 00646464 80030011 1 1 +SCtrl 0 0 -5.00000000000000000000 -5.00000000000000090000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 5.00000000010000000000 -5.00000000000000090000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -5.00000000000000000000 4.99999999999999910000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 5.00000000010000000000 4.99999999999999910000 -10.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000a 0 -0.00000000000000177636 -5.00000000000000090000 -10.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 -10.00000000000000000000 +TrimBy 00000001 0 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 0.00000000000000000000 4.99999999999999910000 -10.00000000000000000000 +TrimBy 00000004 0 0.00000000000000000000 4.99999999999999910000 -10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 +TrimBy 00000007 0 -5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 -0.00000000000000177636 -5.00000000000000090000 -10.00000000000000000000 +AddSurface +Surface 00000002 00646464 80030012 1 1 +SCtrl 0 0 5.00000000010000000000 -5.00000000000000090000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -5.00000000000000000000 -5.00000000000000090000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 5.00000000010000000000 4.99999999999999910000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 -5.00000000000000000000 4.99999999999999910000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000005 1 -5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 0.00000000000000000000 4.99999999999999910000 0.00000000000000000000 +TrimBy 00000002 1 0.00000000000000000000 4.99999999999999910000 0.00000000000000000000 5.00000000000000090000 -0.00000000000000000000 0.00000000000000000000 +TrimBy 0000000b 1 5.00000000000000090000 -0.00000000000000088818 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000090000 0.00000000000000000000 +TrimBy 00000008 1 -0.00000000000000088818 -5.00000000000000090000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000003 00646464 00000000 2 1 +SCtrl 0 0 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 5.00000000000000000000 5.00000000000000000000 -10.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 1 1 5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 2 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000002 0 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +TrimBy 00000003 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +TrimBy 00000001 1 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 +TrimBy 0000000c 0 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000004 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -4.99999999999999910000 5.00000000000000000000 -10.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 1 1 -4.99999999999999910000 5.00000000000000000000 0.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 2 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000005 0 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +TrimBy 00000006 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +TrimBy 00000004 1 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +TrimBy 00000003 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000005 00646464 00000000 2 1 +SCtrl 0 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -5.00000000000000090000 -4.99999999999999910000 -10.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 1 1 -5.00000000000000090000 -4.99999999999999910000 0.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 2 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000008 0 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +TrimBy 00000009 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +TrimBy 00000007 1 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +TrimBy 00000006 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +AddSurface +Surface 00000006 00646464 00000000 2 1 +SCtrl 0 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 4.99999999999999910000 -5.00000000000000090000 -10.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 1 1 4.99999999999999910000 -5.00000000000000090000 0.00000000000000000000 Weight 0.70710678118654757000 +SCtrl 2 0 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000b 0 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 +TrimBy 0000000c 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 +TrimBy 0000000a 1 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +TrimBy 00000009 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +AddSurface +Curve 00000001 1 2 00000001 00000003 +CCtrl 0 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 5.00000000000000000000 -10.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 +CurvePt 0 4.64894150531215190000 1.84047354780936390000 -10.00000000000000000000 +CurvePt 0 3.53553390593273780000 3.53553390593273780000 -10.00000000000000000000 +CurvePt 0 1.84047354780936410000 4.64894150531215190000 -10.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +AddCurve +Curve 00000002 1 2 00000002 00000003 +CCtrl 0 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 +CurvePt 0 4.64894150531215190000 1.84047354780936390000 0.00000000000000000000 +CurvePt 0 3.53553390593273780000 3.53553390593273780000 0.00000000000000000000 +CurvePt 0 1.84047354780936410000 4.64894150531215190000 0.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000003 1 1 00000003 00000004 +CCtrl 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000004 1 2 00000001 00000004 +CCtrl 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -4.99999999999999910000 5.00000000000000000000 -10.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +CurvePt 0 -1.84047354780936320000 4.64894150531215190000 -10.00000000000000000000 +CurvePt 0 -3.53553390593273780000 3.53553390593273780000 -10.00000000000000000000 +CurvePt 0 -4.64894150531215190000 1.84047354780936430000 -10.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +AddCurve +Curve 00000005 1 2 00000002 00000004 +CCtrl 0 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -4.99999999999999910000 5.00000000000000000000 0.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 -1.84047354780936320000 4.64894150531215190000 0.00000000000000000000 +CurvePt 0 -3.53553390593273780000 3.53553390593273780000 0.00000000000000000000 +CurvePt 0 -4.64894150531215190000 1.84047354780936430000 0.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +AddCurve +Curve 00000006 1 1 00000004 00000005 +CCtrl 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +AddCurve +Curve 00000007 1 2 00000001 00000005 +CCtrl 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000090000 -4.99999999999999910000 -10.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +CurvePt 0 -4.64894150531215190000 -1.84047354780936300000 -10.00000000000000000000 +CurvePt 0 -3.53553390593273860000 -3.53553390593273730000 -10.00000000000000000000 +CurvePt 0 -1.84047354780936480000 -4.64894150531215190000 -10.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +AddCurve +Curve 00000008 1 2 00000002 00000005 +CCtrl 0 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000090000 -4.99999999999999910000 0.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +CurvePt 0 -4.64894150531215190000 -1.84047354780936300000 0.00000000000000000000 +CurvePt 0 -3.53553390593273860000 -3.53553390593273730000 0.00000000000000000000 +CurvePt 0 -1.84047354780936480000 -4.64894150531215190000 0.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000009 1 1 00000005 00000006 +CCtrl 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 0000000a 1 2 00000001 00000006 +CCtrl 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 4.99999999999999910000 -5.00000000000000090000 -10.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +CurvePt 0 1.84047354780936300000 -4.64894150531215190000 -10.00000000000000000000 +CurvePt 0 3.53553390593273730000 -3.53553390593273860000 -10.00000000000000000000 +CurvePt 0 4.64894150531215190000 -1.84047354780936500000 -10.00000000000000000000 +CurvePt 1 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 +AddCurve +Curve 0000000b 1 2 00000002 00000006 +CCtrl 0 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 4.99999999999999910000 -5.00000000000000090000 0.00000000000000000000 Weight 0.70710678118654757000 +CCtrl 2 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +CurvePt 0 1.84047354780936300000 -4.64894150531215190000 0.00000000000000000000 +CurvePt 0 3.53553390593273730000 -3.53553390593273860000 0.00000000000000000000 +CurvePt 0 4.64894150531215190000 -1.84047354780936500000 0.00000000000000000000 +CurvePt 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 +AddCurve +Curve 0000000c 1 1 00000006 00000003 +CCtrl 0 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 +CurvePt 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 +AddCurve diff --git a/test/constraint/pt_on_face/normal_v22.slvs b/test/constraint/pt_on_face/normal_v22.slvs new file mode 100644 index 0000000..03ee428 --- /dev/null +++ b/test/constraint/pt_on_face/normal_v22.slvs @@ -0,0 +1,687 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000003 +Group.type=5100 +Group.order=2 +Group.name=extrude +Group.activeWorkplane.v=00010000 +Group.opA.v=00000002 +Group.color=00646464 +Group.subtype=7000 +Group.skipFirst=0 +Group.predef.entityB.v=80020000 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00040000 1002 + 2 00040001 1002 + 3 00040020 1002 + 4 00040040 1002 + 5 00040000 1001 + 6 00040001 1001 + 7 00040020 1001 + 8 00040040 1001 + 9 00040001 1003 + 10 80020000 1002 + 11 80020000 1001 + 12 80020001 1002 + 13 80020002 1002 + 14 80020001 1001 + 15 80020002 1001 + 16 80020002 1003 + 17 00000000 1001 + 18 00000000 1002 +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=80030000 +AddParam + +Param.h.v.=80030001 +AddParam + +Param.h.v.=80030002 +Param.val=-5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.group.v=00000003 +Request.construction=1 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030001 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.normal.v=80030003 +Entity.distance.v=80030004 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030004 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.normal.v=80030007 +Entity.distance.v=80030008 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.z=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030007 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=4001 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.point[1].v=80030002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.z=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030010 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.point[1].v=8003000d +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.actPoint.z=-10.00000000000000000000 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003000d +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00010001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=43 +Constraint.group.v=00000003 +Constraint.ptA.v=00050000 +Constraint.entityA.v=80030012 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Surface 00000001 00646464 80030011 1 1 +SCtrl 0 0 -5.00000000000000000000 -5.00000000000000088818 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 5.00000000010000000827 -5.00000000000000088818 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -5.00000000000000000000 4.99999999999999911182 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 5.00000000010000000827 4.99999999999999911182 -10.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000a 0 -0.00000000000000177636 -5.00000000000000088818 -10.00000000000000000000 5.00000000000000000000 -0.00000000000000088818 -10.00000000000000000000 +TrimBy 00000001 0 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 0.00000000000000000000 4.99999999999999911182 -10.00000000000000000000 +TrimBy 00000004 0 0.00000000000000000000 4.99999999999999911182 -10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 +TrimBy 00000007 0 -5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 -0.00000000000000177636 -5.00000000000000088818 -10.00000000000000000000 +AddSurface +Surface 00000002 00646464 80030012 1 1 +SCtrl 0 0 5.00000000010000000827 -5.00000000000000088818 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -5.00000000000000000000 -5.00000000000000088818 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 5.00000000010000000827 4.99999999999999911182 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 -5.00000000000000000000 4.99999999999999911182 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000005 1 -5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 0.00000000000000000000 4.99999999999999911182 0.00000000000000000000 +TrimBy 00000002 1 0.00000000000000000000 4.99999999999999911182 0.00000000000000000000 5.00000000000000088818 -0.00000000000000000000 0.00000000000000000000 +TrimBy 0000000b 1 5.00000000000000088818 -0.00000000000000088818 0.00000000000000000000 -0.00000000000000088818 -5.00000000000000088818 0.00000000000000000000 +TrimBy 00000008 1 -0.00000000000000088818 -5.00000000000000088818 0.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000003 00646464 00000000 2 1 +SCtrl 0 0 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 5.00000000000000000000 5.00000000000000000000 -10.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000002 0 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +TrimBy 00000001 1 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 +TrimBy 0000000c 0 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 +TrimBy 00000003 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +AddSurface +Surface 00000004 00646464 00000000 2 1 +SCtrl 0 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -4.99999999999999911182 5.00000000000000000000 -10.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 -4.99999999999999911182 5.00000000000000000000 0.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000005 0 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +TrimBy 00000004 1 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +TrimBy 00000003 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +TrimBy 00000006 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +AddSurface +Surface 00000005 00646464 00000000 2 1 +SCtrl 0 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -5.00000000000000088818 -4.99999999999999911182 -10.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 -5.00000000000000088818 -4.99999999999999911182 0.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000008 0 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +TrimBy 00000007 1 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +TrimBy 00000006 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +TrimBy 00000009 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +AddSurface +Surface 00000006 00646464 00000000 2 1 +SCtrl 0 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 4.99999999999999911182 -5.00000000000000088818 -10.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 1 1 4.99999999999999911182 -5.00000000000000088818 0.00000000000000000000 Weight 0.70710678118654757274 +SCtrl 2 0 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 2 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000b 0 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 +TrimBy 0000000a 1 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +TrimBy 00000009 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000c 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 +AddSurface +Curve 00000001 1 2 00000001 00000003 +CCtrl 0 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 5.00000000000000000000 -10.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 -10.00000000000000000000 +CurvePt 0 4.64894150531215188948 1.84047354780936389673 -10.00000000000000000000 +CurvePt 0 4.18497755609325672310 2.73604876692571252761 -10.00000000000000000000 +CurvePt 0 3.53553390593273775266 3.53553390593273775266 -10.00000000000000000000 +CurvePt 0 2.73604876692571252761 4.18497755609325672310 -10.00000000000000000000 +CurvePt 0 1.84047354780936411878 4.64894150531215188948 -10.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +AddCurve +Curve 00000002 1 2 00000002 00000003 +CCtrl 0 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 0.00000000000000000000 +CurvePt 0 4.64894150531215188948 1.84047354780936389673 0.00000000000000000000 +CurvePt 0 4.18497755609325672310 2.73604876692571252761 0.00000000000000000000 +CurvePt 0 3.53553390593273775266 3.53553390593273775266 0.00000000000000000000 +CurvePt 0 2.73604876692571252761 4.18497755609325672310 0.00000000000000000000 +CurvePt 0 1.84047354780936411878 4.64894150531215188948 0.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000003 1 1 00000003 00000004 +CCtrl 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000004 1 2 00000001 00000004 +CCtrl 0 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -4.99999999999999911182 5.00000000000000000000 -10.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 -10.00000000000000000000 +CurvePt 0 -1.84047354780936323060 4.64894150531215188948 -10.00000000000000000000 +CurvePt 0 -2.73604876692571208352 4.18497755609325672310 -10.00000000000000000000 +CurvePt 0 -3.53553390593273775266 3.53553390593273775266 -10.00000000000000000000 +CurvePt 0 -4.18497755609325672310 2.73604876692571297170 -10.00000000000000000000 +CurvePt 0 -4.64894150531215188948 1.84047354780936434082 -10.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +AddCurve +Curve 00000005 1 2 00000002 00000004 +CCtrl 0 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -4.99999999999999911182 5.00000000000000000000 0.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 0.00000000000000030616 5.00000000000000000000 0.00000000000000000000 +CurvePt 0 -1.84047354780936323060 4.64894150531215188948 0.00000000000000000000 +CurvePt 0 -2.73604876692571208352 4.18497755609325672310 0.00000000000000000000 +CurvePt 0 -3.53553390593273775266 3.53553390593273775266 0.00000000000000000000 +CurvePt 0 -4.18497755609325672310 2.73604876692571297170 0.00000000000000000000 +CurvePt 0 -4.64894150531215188948 1.84047354780936434082 0.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +AddCurve +Curve 00000006 1 1 00000004 00000005 +CCtrl 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +AddCurve +Curve 00000007 1 2 00000001 00000005 +CCtrl 0 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000088818 -4.99999999999999911182 -10.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 -10.00000000000000000000 +CurvePt 0 -4.64894150531215188948 -1.84047354780936300855 -10.00000000000000000000 +CurvePt 0 -4.18497755609325672310 -2.73604876692571208352 -10.00000000000000000000 +CurvePt 0 -3.53553390593273864084 -3.53553390593273730858 -10.00000000000000000000 +CurvePt 0 -2.73604876692571297170 -4.18497755609325672310 -10.00000000000000000000 +CurvePt 0 -1.84047354780936478491 -4.64894150531215188948 -10.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +AddCurve +Curve 00000008 1 2 00000002 00000005 +CCtrl 0 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000088818 -4.99999999999999911182 0.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 0.00000000000000061232 0.00000000000000000000 +CurvePt 0 -4.64894150531215188948 -1.84047354780936300855 0.00000000000000000000 +CurvePt 0 -4.18497755609325672310 -2.73604876692571208352 0.00000000000000000000 +CurvePt 0 -3.53553390593273864084 -3.53553390593273730858 0.00000000000000000000 +CurvePt 0 -2.73604876692571297170 -4.18497755609325672310 0.00000000000000000000 +CurvePt 0 -1.84047354780936478491 -4.64894150531215188948 0.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000009 1 1 00000005 00000006 +CCtrl 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 0000000a 1 2 00000001 00000006 +CCtrl 0 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 4.99999999999999911182 -5.00000000000000088818 -10.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 -10.00000000000000000000 +CurvePt 0 1.84047354780936300855 -4.64894150531215188948 -10.00000000000000000000 +CurvePt 0 2.73604876692571163943 -4.18497755609325672310 -10.00000000000000000000 +CurvePt 0 3.53553390593273730858 -3.53553390593273864084 -10.00000000000000000000 +CurvePt 0 4.18497755609325583492 -2.73604876692571297170 -10.00000000000000000000 +CurvePt 0 4.64894150531215188948 -1.84047354780936500696 -10.00000000000000000000 +CurvePt 1 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 +AddCurve +Curve 0000000b 1 2 00000002 00000006 +CCtrl 0 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 4.99999999999999911182 -5.00000000000000088818 0.00000000000000000000 Weight 0.70710678118654757274 +CCtrl 2 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -0.00000000000000091849 -5.00000000000000000000 0.00000000000000000000 +CurvePt 0 1.84047354780936300855 -4.64894150531215188948 0.00000000000000000000 +CurvePt 0 2.73604876692571163943 -4.18497755609325672310 0.00000000000000000000 +CurvePt 0 3.53553390593273730858 -3.53553390593273864084 0.00000000000000000000 +CurvePt 0 4.18497755609325583492 -2.73604876692571297170 0.00000000000000000000 +CurvePt 0 4.64894150531215188948 -1.84047354780936500696 0.00000000000000000000 +CurvePt 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 +AddCurve +Curve 0000000c 1 1 00000006 00000003 +CCtrl 0 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 -0.00000000000000122465 -10.00000000000000000000 +CurvePt 1 5.00000000000000000000 -0.00000000000000122465 0.00000000000000000000 +AddCurve diff --git a/test/constraint/pt_on_face/test.cpp b/test/constraint/pt_on_face/test.cpp new file mode 100644 index 0000000..5e9db1b --- /dev/null +++ b/test/constraint/pt_on_face/test.cpp @@ -0,0 +1,17 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} diff --git a/test/constraint/pt_on_line/free_in_3d_v20.slvs b/test/constraint/pt_on_line/free_in_3d_v20.slvs new file mode 100644 index 0000000..bc5ecec --- /dev/null +++ b/test/constraint/pt_on_line/free_in_3d_v20.slvs @@ -0,0 +1,315 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-20.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-20.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=42 +Constraint.group.v=00000002 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/pt_on_line/free_in_3d_v22.slvs b/test/constraint/pt_on_line/free_in_3d_v22.slvs new file mode 100644 index 0000000..250f93c --- /dev/null +++ b/test/constraint/pt_on_line/free_in_3d_v22.slvs @@ -0,0 +1,315 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-20.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040015 +AddParam + +Param.h.v.=00050010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-20.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=42 +Constraint.group.v=00000002 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/pt_on_line/left_free_in_3d.png b/test/constraint/pt_on_line/left_free_in_3d.png new file mode 100644 index 0000000000000000000000000000000000000000..13b2a6af4d1d36cefbff76aea8430f6bc7e0248e GIT binary patch literal 4319 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 HhW7mm%p2UJ literal 0 HcmV?d00001 diff --git a/test/constraint/pt_on_line/normal.slvs b/test/constraint/pt_on_line/normal.slvs new file mode 100644 index 0000000..6bd8985 --- /dev/null +++ b/test/constraint/pt_on_line/normal.slvs @@ -0,0 +1,318 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=40000001 +Param.val=0.33333333333333331483 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=42 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valP.v=40000001 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/pt_on_line/normal_v20.slvs b/test/constraint/pt_on_line/normal_v20.slvs new file mode 100644 index 0000000..2c3eec5 --- /dev/null +++ b/test/constraint/pt_on_line/normal_v20.slvs @@ -0,0 +1,315 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=42 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/pt_on_line/normal_v22.slvs b/test/constraint/pt_on_line/normal_v22.slvs new file mode 100644 index 0000000..5a74c34 --- /dev/null +++ b/test/constraint/pt_on_line/normal_v22.slvs @@ -0,0 +1,313 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=42 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/pt_on_line/right_free_in_3d.png b/test/constraint/pt_on_line/right_free_in_3d.png new file mode 100644 index 0000000000000000000000000000000000000000..fca580fa96ba0cdef71493b8f3e7fdee37dd32ed GIT binary patch literal 4316 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 X-ZE6bB!|P_QNU)$Z4L$NiKqVuaAqb_ literal 0 HcmV?d00001 diff --git a/test/constraint/pt_pt_distance/free_in_3d.slvs b/test/constraint/pt_pt_distance/free_in_3d.slvs new file mode 100644 index 0000000..3da9edc --- /dev/null +++ b/test/constraint/pt_pt_distance/free_in_3d.slvs @@ -0,0 +1,289 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=30 +Constraint.group.v=00000002 +Constraint.valA=10.00000000000000000000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.y=-1.49454882168925862196 +AddConstraint + diff --git a/test/constraint/pt_pt_distance/free_in_3d_v20.slvs b/test/constraint/pt_pt_distance/free_in_3d_v20.slvs new file mode 100644 index 0000000..e9b6d25 --- /dev/null +++ b/test/constraint/pt_pt_distance/free_in_3d_v20.slvs @@ -0,0 +1,289 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=30 +Constraint.group.v=00000002 +Constraint.valA=10.00000000000000000000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.y=-1.49454882168925860000 +AddConstraint + diff --git a/test/constraint/pt_pt_distance/free_in_3d_v22.slvs b/test/constraint/pt_pt_distance/free_in_3d_v22.slvs new file mode 100644 index 0000000..c5b1af5 --- /dev/null +++ b/test/constraint/pt_pt_distance/free_in_3d_v22.slvs @@ -0,0 +1,289 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=30 +Constraint.group.v=00000002 +Constraint.valA=10.00000000000000000000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +Constraint.disp.offset.y=-1.49454882168925862196 +AddConstraint + diff --git a/test/constraint/pt_pt_distance/normal.png b/test/constraint/pt_pt_distance/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..b6524acec3e455fd5269d5b37649293ffc878ab9 GIT binary patch literal 4467 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 literal 0 HcmV?d00001 diff --git a/test/constraint/pt_pt_distance/reference.slvs b/test/constraint/pt_pt_distance/reference.slvs new file mode 100644 index 0000000..2cf72b5 --- /dev/null +++ b/test/constraint/pt_pt_distance/reference.slvs @@ -0,0 +1,289 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=30 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=10.00000000000000000000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.y=2.50000000000000000000 +AddConstraint + diff --git a/test/constraint/pt_pt_distance/reference_v20.slvs b/test/constraint/pt_pt_distance/reference_v20.slvs new file mode 100644 index 0000000..0888aa8 --- /dev/null +++ b/test/constraint/pt_pt_distance/reference_v20.slvs @@ -0,0 +1,289 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=30 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=10.00000000000000000000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.y=2.50000000000000000000 +AddConstraint + diff --git a/test/constraint/pt_pt_distance/reference_v22.slvs b/test/constraint/pt_pt_distance/reference_v22.slvs new file mode 100644 index 0000000..8a3b2a3 --- /dev/null +++ b/test/constraint/pt_pt_distance/reference_v22.slvs @@ -0,0 +1,289 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=30 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.valA=10.00000000000000000000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=1 +Constraint.disp.offset.y=2.50000000000000000000 +AddConstraint + diff --git a/test/constraint/pt_pt_distance/test.cpp b/test/constraint/pt_pt_distance/test.cpp new file mode 100644 index 0000000..97bef40 --- /dev/null +++ b/test/constraint/pt_pt_distance/test.cpp @@ -0,0 +1,49 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(free_in_3d_roundtrip) { + CHECK_LOAD("free_in_3d.slvs"); + CHECK_RENDER("free_in_3d.png"); + CHECK_SAVE("free_in_3d.slvs"); +} + +TEST_CASE(free_in_3d_migrate_from_v20) { + CHECK_LOAD("free_in_3d_v20.slvs"); + CHECK_SAVE("free_in_3d.slvs"); +} + +TEST_CASE(free_in_3d_migrate_from_v22) { + CHECK_LOAD("free_in_3d_v22.slvs"); + CHECK_SAVE("free_in_3d.slvs"); +} + +TEST_CASE(reference_roundtrip) { + CHECK_LOAD("reference.slvs"); + CHECK_RENDER("reference.png"); + CHECK_SAVE("reference.slvs"); +} + +TEST_CASE(reference_migrate_from_v20) { + CHECK_LOAD("reference_v20.slvs"); + CHECK_SAVE("reference.slvs"); +} + +TEST_CASE(reference_migrate_from_v22) { + CHECK_LOAD("reference_v22.slvs"); + CHECK_SAVE("reference.slvs"); +} diff --git a/test/constraint/same_orientation/normal.png b/test/constraint/same_orientation/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..7bcd4c59ea0425d118cf4ed2a1cd73861fdbc00a GIT binary patch literal 4472 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 b^jo<$rr0iEKi7l*Q32cBw!7wTCM5hDA_6I) literal 0 HcmV?d00001 diff --git a/test/constraint/same_orientation/normal.slvs b/test/constraint/same_orientation/normal.slvs new file mode 100644 index 0000000..fcadecd --- /dev/null +++ b/test/constraint/same_orientation/normal.slvs @@ -0,0 +1,309 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040020 +Param.val=0.70710678118654757274 +AddParam + +Param.h.v.=00040021 +Param.val=-0.70710678118654746172 +AddParam + +Param.h.v.=00040022 +AddParam + +Param.h.v.=00040023 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=40000002 +Param.val=1.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.actNormal.w=0.70710678118654757274 +Entity.actNormal.vx=-0.70710678118654746172 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000002 +Constraint.type=110 +Constraint.group.v=00000002 +Constraint.valP.v=40000002 +Constraint.entityA.v=00040020 +Constraint.entityB.v=00030020 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/same_orientation/normal_v20.slvs b/test/constraint/same_orientation/normal_v20.slvs new file mode 100644 index 0000000..99cbe1f --- /dev/null +++ b/test/constraint/same_orientation/normal_v20.slvs @@ -0,0 +1,302 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040020 +Param.val=0.70710678118654757000 +AddParam + +Param.h.v.=00040021 +Param.val=-0.70710678118654746000 +AddParam + +Param.h.v.=00040022 +AddParam + +Param.h.v.=00040023 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.actNormal.w=0.70710678118654757000 +Entity.actNormal.vx=-0.70710678118654746000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000002 +Constraint.type=110 +Constraint.group.v=00000002 +Constraint.entityA.v=00040020 +Constraint.entityB.v=00030020 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/same_orientation/normal_v22.slvs b/test/constraint/same_orientation/normal_v22.slvs new file mode 100644 index 0000000..c29b8d7 --- /dev/null +++ b/test/constraint/same_orientation/normal_v22.slvs @@ -0,0 +1,304 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040020 +Param.val=0.70710678118654757000 +AddParam + +Param.h.v.=00040021 +Param.val=-0.70710678118654746000 +AddParam + +Param.h.v.=00040022 +AddParam + +Param.h.v.=00040023 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.actNormal.w=0.70710678118654757000 +Entity.actNormal.vx=-0.70710678118654746000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000002 +Constraint.type=110 +Constraint.group.v=00000002 +Constraint.entityA.v=00040020 +Constraint.entityB.v=00030020 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/same_orientation/same_group.png b/test/constraint/same_orientation/same_group.png new file mode 100644 index 0000000000000000000000000000000000000000..ce3f77ba7366743776aa46ad410fb2377f579c11 GIT binary patch literal 4376 zcmeHL3p7;g9{)ThgG8KAbd*+f4>BT;lQX@P9Q1M~6Jd%t#duUi2E!4FLpSA>j_z`! zGbS_9%s3dfZYPRk@@UB9(Lqz5$zd=v=I#+KQ%UQrd(T>Tt-IFD>^@fW!S9;xuocm{wbk7@k7}hzLkvv=0F%mKV*qgG z(u!b>15OIW${PYADjES)^r!&blT`=XG9YPyRD*AQ^uH8D)xq1kw~+As{v1jef6T+` zCn2YD?j!nPz=%^iuHE8Y{9~C_K&v0!m610ZXCJ%hd>%CX;T;V@S@l{H^QPW(N1Mt4 zqKeu=D}^lCv~UE7N6rPXHL$yd0Q#rHY)Vj+JOgiui!Pio&1!lu1!y`ph3%9`Fa5hG z9ZV!3W@bnX&(HdUJB95Az|v+efLZ}<>XQR{$79}>hZwfm&Ezu+16k5a?zoFbri<;C_nYd6b_qsW& zFvC$?b)QY+>+jjqX?;7WLn1--&NQlEaM(kX!Z2c}RB*LK+$K@+3oi0TZFV%xUn9q} z$ht2*xf6eSV)p=DL=IamzfCJ0DfL#=T3geRqVlCB!{Hc=QKIv=RZ-%5&#$^>JOd@= z|Ky`U{k^Pw>FSN66Cl)jjszd*DQ=+_M_i+5vpUzjs9Hb*Pi7`bY&%aegrYVvd0G_>~oief*0iZ zeAnq$BnRWSm;vaUKSOeWqTqe4$nS_M7O+`@#|y|LkM=}RQomrT<{Mu`G_4RHzXX)% zs~Hk6<+Lk;y|9|c3P|ZSsxE=LGrF_wF=fi*dnuMZPU>0o33Y3WXhb$gCxD(ZO*mFL zEy%Bl;jW_+g9PRs1u32Go4#;)Z7r(~$z*s}ojy!D8DRD1Y|fKP{G`x>lP~tZ&M46^ zkLi!$-02pU_nMpWgL}||zKD=3LXN0-pz`^%$68pK>r12c0&;w5w~edD`grk_7q0I4 z&Xs84S8GT=TSQt5E`WV6edG;7^`sRwtH17O<}@p0ZFVzK!$Q9>nM*BOofI8zcZJCt z5>ZYD5XTJ2CK%ixjbdU!YLJ~u=z1|*kLb#NLLlIPDQRCf&N3wsxNo+kn(+@U0t?<( z)=xASFKBq9_!V=qJ`=dO9effdIBmU7==S?wx3Ecrj21dg`_P=x&IEpjLC;GJY({L_ z;9~%IUT@u*7?eSfVVwLr;9VE7i00zlIqXx|_mw}Krwf4hv02CeWJ3nG2QDr2oigBA zs{Grw?ZMGEO3z5I%Gb`x?jo%mF%0iodlVtj^UWwd02v9h*POTJkCgQPU=WMU{{|RZ zM-l7}Cfxjour#n3T}4n*z+DQryjxTys0g=UAB84soPLeM2sz<~04S3MU2uMvK89eI z(pRqnT|dn>3aDkN0bPgQ?{_3YO17Yu_pAaL`vY+JYcdR0er^BBGUBM zqFDH^XEH=Omq31);VlJaz?3LTX!<4--p59sG44X6?JxEAIVa&Lm2ny%@XOI7x`Z9M zwz{D1WTQM=zxXK* zs$%uM#9KA2z9+oxc70SJ+}AsHZEYdI9bxg&Sp5k7NuExMOnFdawGkA~(!#1mZZiXc z%iz74nkRCXk-z#o0^FCM+1SXFona^-mtzAqGq0loD*ZHq&6jVynb7EynwQJBoZ|7) ztf!rMS6y~;Bc2K)WQi8_E3me1rP;iOO8!7&XK9v8)gEj2=u{o13Wd#SkGDCYN zd*uLT^C=uNC2w8RE#86kNSxtxHL?WL6xOY+GcG`1K~I(0o1FP$QzvIlc+br$icPz1 ze;GZ8!5D07Il?c??I#QiOO4%%gpVRCOLKC099l%;Y2bf1$J@1qB_h14w0aZF7#MYD zaNAl4A+E`UcAx69vEhnSTUSp`uOH_>$+?0C-R`>Czxkw= z@>16}rBvN9+`$q(qmk{$&{y4WcH8rK`!5)WejfM}hf;TRge%z&qP~P=^v@?XUA+$A9S6V@hsMYj~IW|%K@R>M&D!G*W*@Qf!}xlyIp&23U}aQ{tfia`LzH5 literal 0 HcmV?d00001 diff --git a/test/constraint/same_orientation/same_group.slvs b/test/constraint/same_orientation/same_group.slvs new file mode 100644 index 0000000..7944b1e --- /dev/null +++ b/test/constraint/same_orientation/same_group.slvs @@ -0,0 +1,379 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-25.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040020 +Param.val=0.70710678118654757274 +AddParam + +Param.h.v.=00040021 +AddParam + +Param.h.v.=00040022 +Param.val=0.70710678118654746172 +AddParam + +Param.h.v.=00040023 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=00050020 +Param.val=0.70710678118654757274 +AddParam + +Param.h.v.=00050021 +AddParam + +Param.h.v.=00050022 +Param.val=-0.70710678118654757274 +AddParam + +Param.h.v.=00050023 +AddParam + +Param.h.v.=00050040 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=40000002 +Param.val=-1.00000000000000022204 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=400 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-25.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.actNormal.w=0.70710678118654757274 +Entity.actNormal.vy=0.70710678118654746172 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.normal.v=00050020 +Entity.distance.v=00050040 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.actNormal.w=0.70710678118654757274 +Entity.actNormal.vy=-0.70710678118654757274 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050040 +Entity.type=4000 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000002 +Constraint.type=110 +Constraint.group.v=00000002 +Constraint.valP.v=40000002 +Constraint.entityA.v=00050020 +Constraint.entityB.v=00040020 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/same_orientation/test.cpp b/test/constraint/same_orientation/test.cpp new file mode 100644 index 0000000..9377b28 --- /dev/null +++ b/test/constraint/same_orientation/test.cpp @@ -0,0 +1,23 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(same_group_roundtrip) { + CHECK_LOAD("same_group.slvs"); + CHECK_RENDER("same_group.png"); + CHECK_SAVE("same_group.slvs"); +} diff --git a/test/constraint/symmetric/free_in_3d.png b/test/constraint/symmetric/free_in_3d.png new file mode 100644 index 0000000000000000000000000000000000000000..58c2ecc2fff5fa2427a8f6192802cb3b8bd5dc32 GIT binary patch literal 4378 zcmeHLX;f2J9=}NltLzv+6s#T8QG@`pjDVpOM2o0^WkT3uWwC;yZNnCp1ausz5-S}9 zMZ{7?g#a?fU^MV33aDifAwiS`ijru6AP|tyKpzNbTuzyDW+FZbmB@BjX` z_tJK3b5~bgq6z>|-?G`&8vrDJ`lGA}->D4Cehh$C_ZHXBcE;xRcfL6IsNS%)`}VQZ z2Tb<&umx~f~BH?*2*#feo?>x=j{K{q&|;_IfCnq(D7j| zEg<=K_r~x2wB~jPyVbNN|K(FnU)ZL zpY*xhZfqHRoV605Xz6}vf6lnx>+wq9wDQ~pUw!;08G!P)&Nc#D@{>c@0{bMaE8i&w zLeF>0;BcOM0&w(}!iO5(Op7bwA)uA>E487syl?=!dam-LMZ%1n1)hoYidmZji1+!f zQ%mlYJ?RWayeCCSV~qCw&5 z1=`6Y$|qtUou>ex&2vqD7j3d^!SiJxa>X1R@qt7`2@0fI%~lRoqz_~-5ViRx_q^Gt zd^@&Q7(9Z%XjJVJ3(oK-M#}?1?g^FG z@_GO%;zvj@R+Bei;UMbD!85yVJ#?|ew(Ay^BGCZp;==UjiPW@rWxdz? zS^*%#lAt^u#71;s6)?{Av{8rhLztzTXUftVDUji=QigT#zyaHk@~ti&x+1%|fhUzv zWiR>3>1OsORP;zs>15@^OKH}*=9FPrFfE9u&;l#Cs1w%7qeaq_rd5*#HuR`Ok+^EI zzhk(iqr5+Xe>P72c2Z=VCQh2SFEmkfHdK}p@%cU?={rk>^nhe~o7I#?$@ftf{D#7S z3xCHAB=s6im8l{1L4~~UiRwXP@wP5tZ2)yAd zR!^uR>->|e^H!u{W>1xf2y8UPCx;MGauZu7syLP8dDsDAuc>Qh(BA*#?qAfpY+&dN zSTU^F$k=66bSj~$WGemgGj2#adJqYtWyCiCF}MM~7~bO&nvO2RQPHRlE4Gdwn9#;! zkJFioof{R}PeLhFN8N2J)QC6|)ut)5P!Y6e&hkaNYe?O(NXYtR&J$iol;F#Dpzn#G zEqQ99m&*^jsZYs#+v2KKwobkHR*9NP$U5;rbkh=iY`Q7tJ@zG)W4IZ28hI2(936oH?TRw%p$eoICBRZ z0Oifbyk^bJs4l;^Q`l=3Pcx?2wk+YE4Z!AiKm^PWXt1bo5_1l&b+jC&3th9Ab2rEl zK*kx`Fmq7TU%O_)iD}9Xam+~Ef8ix8-;XZ4HX}D77RnkSpWF8AtE%sY!95*?HqHqXJ zRFaXW{{=6mm#K2T#UxF8S|V#LliG*(t!7Ke;@i!fM+w}|M(_HknxwIqqhou{h`6J| z-NrH=Cy~eM93wL$apeQ<+=tRiCxU-2YVc}M5|7z+xC=%ScBJNI%v0vI`3?E}sly*ih@8^MNtC0910xucl z?bOGIza*s7H7%TK$Oy2iWsFM<+>XhR)*lwt$44b|OS_%gv`2a4xQRS5W1v7%#6fiF z!SEBiwRjag^J5}N7FT)XhBk3ckbpl-+BY6XrC;VJ16GTeOJqw(mZf=Cj^vHWTTswn zM~v{|xX=)%bQZ1eX-;A5aJK&;pl4sZ?w9b+8^=bUS1Frxay%Sy&&nIaIjl~Ps0UZw zOJ($?8nXD&zjeeoV53^vRv2%7nERl+n@tMPm@>Ctnz1e8#eQwyOWAn{aAYU>`$4bc z31P)d)96t=j>K!abxK0V4N22Pwe@0}gdQcM(T(88;sP`K5-(#e0{VK!ErL_!!{dh@ i58vkafA1~Agwoo9h=Lbv>tXnv2iW4a&9%gZnDPgg(dEJb literal 0 HcmV?d00001 diff --git a/test/constraint/symmetric/free_in_3d.slvs b/test/constraint/symmetric/free_in_3d.slvs new file mode 100644 index 0000000..863a794 --- /dev/null +++ b/test/constraint/symmetric/free_in_3d.slvs @@ -0,0 +1,289 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=00060010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060012 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=60 +Constraint.group.v=00000002 +Constraint.ptA.v=00050000 +Constraint.ptB.v=00060000 +Constraint.entityA.v=00030000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/symmetric/free_in_3d_v20.slvs b/test/constraint/symmetric/free_in_3d_v20.slvs new file mode 100644 index 0000000..a6a0cea --- /dev/null +++ b/test/constraint/symmetric/free_in_3d_v20.slvs @@ -0,0 +1,287 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=00060010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060012 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=60 +Constraint.group.v=00000002 +Constraint.ptA.v=00050000 +Constraint.ptB.v=00060000 +Constraint.entityA.v=00030000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/symmetric/free_in_3d_v22.slvs b/test/constraint/symmetric/free_in_3d_v22.slvs new file mode 100644 index 0000000..ff95075 --- /dev/null +++ b/test/constraint/symmetric/free_in_3d_v22.slvs @@ -0,0 +1,289 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050012 +AddParam + +Param.h.v.=00060010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060012 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=101 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=60 +Constraint.group.v=00000002 +Constraint.ptA.v=00050000 +Constraint.ptB.v=00060000 +Constraint.entityA.v=00030000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/symmetric/normal.png b/test/constraint/symmetric/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..d497e0f9c92c90575f962909c72011949f8a1c06 GIT binary patch literal 4362 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 literal 0 HcmV?d00001 diff --git a/test/constraint/symmetric_line/normal.slvs b/test/constraint/symmetric_line/normal.slvs new file mode 100644 index 0000000..22a436a --- /dev/null +++ b/test/constraint/symmetric_line/normal.slvs @@ -0,0 +1,338 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=63 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.ptB.v=00060000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/symmetric_line/normal_v20.slvs b/test/constraint/symmetric_line/normal_v20.slvs new file mode 100644 index 0000000..f1c4562 --- /dev/null +++ b/test/constraint/symmetric_line/normal_v20.slvs @@ -0,0 +1,336 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=63 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.ptB.v=00060000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/symmetric_line/normal_v22.slvs b/test/constraint/symmetric_line/normal_v22.slvs new file mode 100644 index 0000000..f0d4dca --- /dev/null +++ b/test/constraint/symmetric_line/normal_v22.slvs @@ -0,0 +1,338 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-15.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=-10.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-15.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=63 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050000 +Constraint.ptB.v=00060000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/symmetric_line/test.cpp b/test/constraint/symmetric_line/test.cpp new file mode 100644 index 0000000..5e9db1b --- /dev/null +++ b/test/constraint/symmetric_line/test.cpp @@ -0,0 +1,17 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} diff --git a/test/constraint/symmetric_vert/normal.png b/test/constraint/symmetric_vert/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..58c2ecc2fff5fa2427a8f6192802cb3b8bd5dc32 GIT binary patch literal 4378 zcmeHLX;f2J9=}NltLzv+6s#T8QG@`pjDVpOM2o0^WkT3uWwC;yZNnCp1ausz5-S}9 zMZ{7?g#a?fU^MV33aDifAwiS`ijru6AP|tyKpzNbTuzyDW+FZbmB@BjX` z_tJK3b5~bgq6z>|-?G`&8vrDJ`lGA}->D4Cehh$C_ZHXBcE;xRcfL6IsNS%)`}VQZ z2Tb<&umx~f~BH?*2*#feo?>x=j{K{q&|;_IfCnq(D7j| zEg<=K_r~x2wB~jPyVbNN|K(FnU)ZL zpY*xhZfqHRoV605Xz6}vf6lnx>+wq9wDQ~pUw!;08G!P)&Nc#D@{>c@0{bMaE8i&w zLeF>0;BcOM0&w(}!iO5(Op7bwA)uA>E487syl?=!dam-LMZ%1n1)hoYidmZji1+!f zQ%mlYJ?RWayeCCSV~qCw&5 z1=`6Y$|qtUou>ex&2vqD7j3d^!SiJxa>X1R@qt7`2@0fI%~lRoqz_~-5ViRx_q^Gt zd^@&Q7(9Z%XjJVJ3(oK-M#}?1?g^FG z@_GO%;zvj@R+Bei;UMbD!85yVJ#?|ew(Ay^BGCZp;==UjiPW@rWxdz? zS^*%#lAt^u#71;s6)?{Av{8rhLztzTXUftVDUji=QigT#zyaHk@~ti&x+1%|fhUzv zWiR>3>1OsORP;zs>15@^OKH}*=9FPrFfE9u&;l#Cs1w%7qeaq_rd5*#HuR`Ok+^EI zzhk(iqr5+Xe>P72c2Z=VCQh2SFEmkfHdK}p@%cU?={rk>^nhe~o7I#?$@ftf{D#7S z3xCHAB=s6im8l{1L4~~UiRwXP@wP5tZ2)yAd zR!^uR>->|e^H!u{W>1xf2y8UPCx;MGauZu7syLP8dDsDAuc>Qh(BA*#?qAfpY+&dN zSTU^F$k=66bSj~$WGemgGj2#adJqYtWyCiCF}MM~7~bO&nvO2RQPHRlE4Gdwn9#;! zkJFioof{R}PeLhFN8N2J)QC6|)ut)5P!Y6e&hkaNYe?O(NXYtR&J$iol;F#Dpzn#G zEqQ99m&*^jsZYs#+v2KKwobkHR*9NP$U5;rbkh=iY`Q7tJ@zG)W4IZ28hI2(936oH?TRw%p$eoICBRZ z0Oifbyk^bJs4l;^Q`l=3Pcx?2wk+YE4Z!AiKm^PWXt1bo5_1l&b+jC&3th9Ab2rEl zK*kx`Fmq7TU%O_)iD}9Xam+~Ef8ix8-;XZ4HX}D77RnkSpWF8AtE%sY!95*?HqHqXJ zRFaXW{{=6mm#K2T#UxF8S|V#LliG*(t!7Ke;@i!fM+w}|M(_HknxwIqqhou{h`6J| z-NrH=Cy~eM93wL$apeQ<+=tRiCxU-2YVc}M5|7z+xC=%ScBJNI%v0vI`3?E}sly*ih@8^MNtC0910xucl z?bOGIza*s7H7%TK$Oy2iWsFM<+>XhR)*lwt$44b|OS_%gv`2a4xQRS5W1v7%#6fiF z!SEBiwRjag^J5}N7FT)XhBk3ckbpl-+BY6XrC;VJ16GTeOJqw(mZf=Cj^vHWTTswn zM~v{|xX=)%bQZ1eX-;A5aJK&;pl4sZ?w9b+8^=bUS1Frxay%Sy&&nIaIjl~Ps0UZw zOJ($?8nXD&zjeeoV53^vRv2%7nERl+n@tMPm@>Ctnz1e8#eQwyOWAn{aAYU>`$4bc z31P)d)96t=j>K!abxK0V4N22Pwe@0}gdQcM(T(88;sP`K5-(#e0{VK!ErL_!!{dh@ i58vkafA1~Agwoo9h=Lbv>tXnv2iW4a&9%gZnDPgg(dEJb literal 0 HcmV?d00001 diff --git a/test/constraint/symmetric_vert/normal.slvs b/test/constraint/symmetric_vert/normal.slvs new file mode 100644 index 0000000..dc23f9e --- /dev/null +++ b/test/constraint/symmetric_vert/normal.slvs @@ -0,0 +1,287 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=-5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=62 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/symmetric_vert/normal_v20.slvs b/test/constraint/symmetric_vert/normal_v20.slvs new file mode 100644 index 0000000..c6f5a6d --- /dev/null +++ b/test/constraint/symmetric_vert/normal_v20.slvs @@ -0,0 +1,285 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=-5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=62 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/symmetric_vert/normal_v22.slvs b/test/constraint/symmetric_vert/normal_v22.slvs new file mode 100644 index 0000000..602bee1 --- /dev/null +++ b/test/constraint/symmetric_vert/normal_v22.slvs @@ -0,0 +1,287 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=-5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=62 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/symmetric_vert/test.cpp b/test/constraint/symmetric_vert/test.cpp new file mode 100644 index 0000000..5e9db1b --- /dev/null +++ b/test/constraint/symmetric_vert/test.cpp @@ -0,0 +1,17 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} diff --git a/test/constraint/vertical/line.png b/test/constraint/vertical/line.png new file mode 100644 index 0000000000000000000000000000000000000000..096ca416be9b9c37379affb409e5e33f63df89b4 GIT binary patch literal 4331 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 literal 0 HcmV?d00001 diff --git a/test/constraint/vertical/pt_pt.slvs b/test/constraint/vertical/pt_pt.slvs new file mode 100644 index 0000000..0381c60 --- /dev/null +++ b/test/constraint/vertical/pt_pt.slvs @@ -0,0 +1,287 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=-5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=81 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/vertical/pt_pt_v20.slvs b/test/constraint/vertical/pt_pt_v20.slvs new file mode 100644 index 0000000..648dbca --- /dev/null +++ b/test/constraint/vertical/pt_pt_v20.slvs @@ -0,0 +1,285 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=-5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=81 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/vertical/pt_pt_v22.slvs b/test/constraint/vertical/pt_pt_v22.slvs new file mode 100644 index 0000000..458c241 --- /dev/null +++ b/test/constraint/vertical/pt_pt_v22.slvs @@ -0,0 +1,287 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=-5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=81 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040000 +Constraint.ptB.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/constraint/vertical/test.cpp b/test/constraint/vertical/test.cpp new file mode 100644 index 0000000..c08b5e1 --- /dev/null +++ b/test/constraint/vertical/test.cpp @@ -0,0 +1,33 @@ +#include "harness.h" + +TEST_CASE(line_roundtrip) { + CHECK_LOAD("line.slvs"); + CHECK_RENDER("line.png"); + CHECK_SAVE("line.slvs"); +} + +TEST_CASE(line_migrate_from_v20) { + CHECK_LOAD("line_v20.slvs"); + CHECK_SAVE("line.slvs"); +} + +TEST_CASE(line_migrate_from_v22) { + CHECK_LOAD("line_v22.slvs"); + CHECK_SAVE("line.slvs"); +} + +TEST_CASE(pt_pt_roundtrip) { + CHECK_LOAD("pt_pt.slvs"); + CHECK_RENDER("pt_pt.png"); + CHECK_SAVE("pt_pt.slvs"); +} + +TEST_CASE(pt_pt_migrate_from_v20) { + CHECK_LOAD("pt_pt_v20.slvs"); + CHECK_SAVE("pt_pt.slvs"); +} + +TEST_CASE(pt_pt_migrate_from_v22) { + CHECK_LOAD("pt_pt_v22.slvs"); + CHECK_SAVE("pt_pt.slvs"); +} diff --git a/test/constraint/where_dragged/free_in_3d.png b/test/constraint/where_dragged/free_in_3d.png new file mode 100644 index 0000000000000000000000000000000000000000..7ee4884d2052ce8d658088ff381281a3e7c51422 GIT binary patch literal 4257 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, 3.1415926); +} + +TEST_CASE(literal) { + Expr *e; + CHECK_PARSE(e, "42"); + CHECK_TRUE(e->Eval() == 42); + CHECK_PARSE(e, "42.5"); + CHECK_TRUE(e->Eval() == 42.5); + CHECK_PARSE(e, "1_000_000"); + CHECK_TRUE(e->Eval() == 1000000); +} + +TEST_CASE(unary_ops) { + Expr *e; + CHECK_PARSE(e, "-10"); + CHECK_TRUE(e->Eval() == -10); +} + +TEST_CASE(binary_ops) { + Expr *e; + CHECK_PARSE(e, "1 + 2"); + CHECK_TRUE(e->Eval() == 3); + CHECK_PARSE(e, "1 - 2"); + CHECK_TRUE(e->Eval() == -1); + CHECK_PARSE(e, "3 * 4"); + CHECK_TRUE(e->Eval() == 12); + CHECK_PARSE(e, "3 / 4"); + CHECK_TRUE(e->Eval() == 0.75); +} + +TEST_CASE(parentheses) { + Expr *e; + CHECK_PARSE(e, "(1 + 2) * 3"); + CHECK_TRUE(e->Eval() == 9); + CHECK_PARSE(e, "1 + (2 * 3)"); + CHECK_TRUE(e->Eval() == 7); +} + +TEST_CASE(functions) { + Expr *e; + CHECK_PARSE(e, "sqrt(2)"); + CHECK_EQ_EPS(e->Eval(), 1.414213); + CHECK_PARSE(e, "square(3)"); + CHECK_EQ_EPS(e->Eval(), 9); + CHECK_PARSE(e, "sin(180)"); + CHECK_EQ_EPS(e->Eval(), 0); + CHECK_PARSE(e, "sin(90)"); + CHECK_EQ_EPS(e->Eval(), 1); + CHECK_PARSE(e, "cos(180)"); + CHECK_EQ_EPS(e->Eval(), -1); + CHECK_PARSE(e, "asin(1)"); + CHECK_EQ_EPS(e->Eval(), 90); + CHECK_PARSE(e, "acos(0)"); + CHECK_EQ_EPS(e->Eval(), 90); +} + +TEST_CASE(variable) { + Expr *e; + CHECK_PARSE(e, "Var"); + CHECK_TRUE(e->op == Expr::Op::VARIABLE); +} + +TEST_CASE(precedence) { + Expr *e; + CHECK_PARSE(e, "2 + 3 * 4"); + CHECK_TRUE(e->Eval() == 14); + CHECK_PARSE(e, "2 - 3 / 4"); + CHECK_TRUE(e->Eval() == 1.25); + CHECK_PARSE(e, "-3 + 2"); + CHECK_TRUE(e->Eval() == -1); + CHECK_PARSE(e, "2 + 3 - 4"); + CHECK_TRUE(e->Eval() == 1); +} + +TEST_CASE(errors) { + CHECK_PARSE_ERR("\x01", + "Unexpected character"); + CHECK_PARSE_ERR("notavar", + "'notavar' is not a valid variable, function or constant"); + CHECK_PARSE_ERR("1e2e3", + "'1e2e3' is not a valid number"); + CHECK_PARSE_ERR("_", + "'_' is not a valid operator"); + CHECK_PARSE_ERR("2 2", + "Expected an operator"); + CHECK_PARSE_ERR("2 + +", + "Expected an operand"); + CHECK_PARSE_ERR("( 2 + 2", + "Expected ')'"); + CHECK_PARSE_ERR("(", + "Expected ')'"); +} diff --git a/test/core/locale/test.cpp b/test/core/locale/test.cpp new file mode 100644 index 0000000..46ad9e1 --- /dev/null +++ b/test/core/locale/test.cpp @@ -0,0 +1,8 @@ +#include "harness.h" + +TEST_CASE(parseable) { + for(auto locale : Locales()) { + SetLocale(locale.Culture()); + } + CHECK_TRUE(true); // didn't crash +} diff --git a/test/core/path/test.cpp b/test/core/path/test.cpp new file mode 100644 index 0000000..86accf1 --- /dev/null +++ b/test/core/path/test.cpp @@ -0,0 +1,246 @@ +#include "harness.h" + +using Platform::Path; + +#if defined(WIN32) +#define S "\\" +#define R "C:" +#define U "\\\\?\\C:" +#else +#define S "/" +#define R "" +#define U "" +#endif + +TEST_CASE(from_raw) { + Path path = Path::From("/foo"); + CHECK_EQ_STR(path.raw, "/foo"); +} + +#if defined(WIN32) || defined(__APPLE__) +TEST_CASE(equals_win32_apple) { + CHECK_TRUE(Path::From(R S "foo").Equals(Path::From(R S "foo"))); + CHECK_TRUE(Path::From(R S "foo").Equals(Path::From(R S "FOO"))); + CHECK_FALSE(Path::From(R S "foo").Equals(Path::From(R S "bar"))); +} +#else +TEST_CASE(equals_unix) { + CHECK_TRUE(Path::From(R S "foo").Equals(Path::From(R S "foo"))); + CHECK_FALSE(Path::From(R S "foo").Equals(Path::From(R S "FOO"))); + CHECK_FALSE(Path::From(R S "foo").Equals(Path::From(R S "bar"))); +} +#endif + +#if defined(WIN32) +TEST_CASE(is_absolute_win32) { + CHECK_TRUE(Path::From("c:\\foo").IsAbsolute()); + CHECK_TRUE(Path::From("\\\\?\\c:\\").IsAbsolute()); + CHECK_TRUE(Path::From("\\\\server\\share\\").IsAbsolute()); + CHECK_FALSE(Path::From("c:/foo").IsAbsolute()); + CHECK_FALSE(Path::From("c:foo").IsAbsolute()); + CHECK_FALSE(Path::From("\\\\?").IsAbsolute()); + CHECK_FALSE(Path::From("\\\\server\\").IsAbsolute()); + CHECK_FALSE(Path::From("\\\\?\\c:").IsAbsolute()); + CHECK_FALSE(Path::From("\\\\server\\share").IsAbsolute()); + CHECK_FALSE(Path::From("foo").IsAbsolute()); + CHECK_FALSE(Path::From("/foo").IsAbsolute()); +} +#else +TEST_CASE(is_absolute_unix) { + CHECK_TRUE(Path::From("/foo").IsAbsolute()); + CHECK_FALSE(Path::From("c:/foo").IsAbsolute()); + CHECK_FALSE(Path::From("c:\\foo").IsAbsolute()); + CHECK_FALSE(Path::From("\\\\?\\foo").IsAbsolute()); + CHECK_FALSE(Path::From("c:foo").IsAbsolute()); + CHECK_FALSE(Path::From("foo").IsAbsolute()); +} +#endif + +TEST_CASE(has_extension) { + CHECK_TRUE(Path::From("foo.bar").HasExtension("bar")); + CHECK_TRUE(Path::From("foo.bar").HasExtension("BAR")); + CHECK_TRUE(Path::From("foo.bAr").HasExtension("BaR")); + CHECK_TRUE(Path::From("foo.bar").HasExtension("bar")); + CHECK_FALSE(Path::From("foo.bar").HasExtension("baz")); +} + +TEST_CASE(file_name) { + CHECK_EQ_STR(Path::From("foo").FileName(), "foo"); + CHECK_EQ_STR(Path::From("foo" S "bar").FileName(), "bar"); +} + +TEST_CASE(file_stem) { + CHECK_EQ_STR(Path::From("foo").FileStem(), "foo"); + CHECK_EQ_STR(Path::From("foo" S "bar").FileStem(), "bar"); + CHECK_EQ_STR(Path::From("foo.ext").FileStem(), "foo"); + CHECK_EQ_STR(Path::From("foo" S "bar.ext").FileStem(), "bar"); +} + +TEST_CASE(extension) { + CHECK_EQ_STR(Path::From("foo").Extension(), ""); + CHECK_EQ_STR(Path::From("foo.bar").Extension(), "bar"); + CHECK_EQ_STR(Path::From("foo.bar.baz").Extension(), "baz"); +} + +TEST_CASE(with_extension) { + CHECK_EQ_STR(Path::From("foo.bar").WithExtension("").raw, "foo"); + CHECK_EQ_STR(Path::From("foo.bar").WithExtension("baz").raw, "foo.baz"); + CHECK_EQ_STR(Path::From("foo").WithExtension("baz").raw, "foo.baz"); +} + +TEST_CASE(parent) { + Path path; + path = Path::From("foo" S "bar"); + CHECK_EQ_STR(path.Parent().raw, "foo" S); + path = Path::From("foo" S "bar" S); + CHECK_EQ_STR(path.Parent().raw, "foo" S); + path = Path::From(R S "foo" S "bar"); + CHECK_EQ_STR(path.Parent().raw, R S "foo" S); + path = Path::From(R S "foo"); + CHECK_EQ_STR(path.Parent().raw, R S); + + path = Path::From(""); + CHECK_TRUE(path.Parent().IsEmpty()); + path = Path::From("foo"); + CHECK_TRUE(path.Parent().IsEmpty()); + path = Path::From("foo" S); + CHECK_TRUE(path.Parent().IsEmpty()); + path = Path::From(R S); + CHECK_TRUE(path.Parent().IsEmpty()); +} + +#if defined(WIN32) +TEST_CASE(parent_win32) { + Path path; + path = Path::From(U S); + CHECK_TRUE(path.Parent().IsEmpty()); +} +#endif + +TEST_CASE(join) { + Path path; + path = Path::From("foo"); + CHECK_EQ_STR(path.Join(Path::From("bar")).raw, "foo" S "bar"); + path = Path::From("foo" S); + CHECK_EQ_STR(path.Join(Path::From("bar")).raw, "foo" S "bar"); + + path = Path::From(""); + CHECK_TRUE(path.Join(Path::From("bar")).IsEmpty()); + path = Path::From("foo"); + CHECK_TRUE(path.Join(Path::From("")).IsEmpty()); + path = Path::From("foo"); + CHECK_TRUE(path.Join(Path::From(R S "bar")).IsEmpty()); +} + +TEST_CASE(expand) { + Path path; + path = Path::From("foo"); + CHECK_EQ_STR(path.Expand().raw, "foo"); + path = Path::From("foo" S "bar"); + CHECK_EQ_STR(path.Expand().raw, "foo" S "bar"); + path = Path::From("foo" S); + CHECK_EQ_STR(path.Expand().raw, "foo"); + path = Path::From("foo" S "."); + CHECK_EQ_STR(path.Expand().raw, "foo"); + path = Path::From("foo" S "." S "bar"); + CHECK_EQ_STR(path.Expand().raw, "foo" S "bar"); + path = Path::From("foo" S ".." S "bar"); + CHECK_EQ_STR(path.Expand().raw, "bar"); + path = Path::From("foo" S ".."); + CHECK_EQ_STR(path.Expand().raw, "."); + path = Path::From(R S "foo" S ".."); + CHECK_EQ_STR(path.Expand().raw, U S); + path = Path::From(R S); + CHECK_EQ_STR(path.Expand().raw, U S); + + path = Path::From(R S ".."); + CHECK_TRUE(path.Expand().IsEmpty()); + path = Path::From(R S ".." S "foo"); + CHECK_TRUE(path.Expand().IsEmpty()); + path = Path::From(".."); + CHECK_TRUE(path.Expand().IsEmpty()); +} + +#if defined(WIN32) +TEST_CASE(expand_win32) { + Path path; + path = Path::From(R S "foo"); + CHECK_EQ_STR(path.Expand().raw, U S "foo"); + path = Path::From(U S "foo"); + CHECK_EQ_STR(path.Expand().raw, U S "foo"); +} +#endif + +TEST_CASE(expand_from_cwd) { + Path cwd = Path::CurrentDirectory().Expand(); + + Path path; + path = Path::From(R S "foo"); + CHECK_EQ_STR(path.Expand(/*fromCurrentDirectory=*/true).raw, + U S "foo"); + path = Path::From("foo" S "bar"); + CHECK_EQ_STR(path.Expand(/*fromCurrentDirectory=*/true).raw, + cwd.raw + S "foo" S "bar"); + path = Path::From(".." S "bar"); + CHECK_EQ_STR(path.Expand(/*fromCurrentDirectory=*/true).raw, + cwd.Parent().raw + "bar"); +} + +TEST_CASE(relative_to) { + Path base; + base = Path::From(R S "foo" S "bar"); + CHECK_EQ_STR(Path::From(R S "foo").RelativeTo(base).raw, + ".."); + base = Path::From(R S "foo" S "bar"); + CHECK_EQ_STR(Path::From(R S "foo" S "baz").RelativeTo(base).raw, + ".." S "baz"); + base = Path::From(R S "foo" S "bar"); + CHECK_EQ_STR(Path::From(R S "foo" S "bar" S "quux").RelativeTo(base).raw, + "quux"); + base = Path::From(R S "foo" S "bar"); + CHECK_EQ_STR(Path::From(R S "foo" S "bar").RelativeTo(base).raw, + "."); + + base = Path::From("foo"); + CHECK_TRUE(Path::From(R S "foo" S "bar").RelativeTo(base).IsEmpty()); + base = Path::From(R S "foo" S "bar"); + CHECK_TRUE(Path::From("foo").RelativeTo(base).IsEmpty()); +} + +#if defined(WIN32) +TEST_CASE(relative_to_win32) { + Path base; + base = Path::From("C:\\foo"); + CHECK_EQ_STR(Path::From("\\\\?\\C:\\bar").RelativeTo(base).raw, + "..\\bar"); + base = Path::From("C:\\foo"); + CHECK_EQ_STR(Path::From("c:\\FOO").RelativeTo(base).raw, + "."); + + base = Path::From("C:\\foo"); + CHECK_TRUE(Path::From("D:\\bar").RelativeTo(base).IsEmpty()); + CHECK_TRUE(Path::From("\\\\server\\share\\bar").RelativeTo(base).IsEmpty()); +} +#elif defined(__APPLE__) +TEST_CASE(relative_to_apple) { + Path base; + base = Path::From("/users/foo"); + CHECK_EQ_STR(Path::From("/Users/FOO").RelativeTo(base).raw, + "."); +} +#else +TEST_CASE(relative_to_unix) { + Path base; + base = Path::From("/users/foo"); + CHECK_EQ_STR(Path::From("/Users/FOO").RelativeTo(base).raw, + "../../Users/FOO"); +} +#endif + +TEST_CASE(from_portable) { + CHECK_EQ_STR(Path::FromPortable("foo/bar").raw, "foo" S "bar"); +} + +TEST_CASE(to_portable) { + CHECK_EQ_STR(Path::From("foo" S "bar").ToPortable(), "foo/bar"); +} diff --git a/test/debugtool.cpp b/test/debugtool.cpp new file mode 100644 index 0000000..aa66c1f --- /dev/null +++ b/test/debugtool.cpp @@ -0,0 +1,31 @@ +//----------------------------------------------------------------------------- +// Our entry point for exposing various internal mechanisms. +// +// Copyright 2017 whitequark +//----------------------------------------------------------------------------- +#include "solvespace.h" + +int main(int argc, char **argv) { + std::vector args = Platform::InitCli(argc, argv); + + if(args.size() == 3 && args[1] == "expr") { + std::string expr = args[2], err; + Expr *e = Expr::Parse(expr.c_str(), &err); + if(e == NULL) { + fprintf(stderr, "cannot parse: %s\n", err.c_str()); + } else { + fprintf(stderr, "%g\n", e->Eval()); + } + FreeAllTemporary(); + } else { + fprintf(stderr, "Usage: %s \n", args[0].c_str()); +//-----------------------------------------------------------------------------> 80 col */ + fprintf(stderr, R"( +Commands: + expr [expr] + Evaluate an expression. +)"); + } + + return 0; +} diff --git a/test/group/link/normal.png b/test/group/link/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..b3295bcfa81f43831cef8314582506fec98a01e0 GIT binary patch literal 4151 zcmeHLdr(t%7XIZn2?RDRf`E%!kWthL@+dM?il{t_7UZD>vY?PIiU{&hKpp`JYGrt6 z+FCI@1gljF2FSt&!Xx3bTBrglQUXXIp(!AQcjRS&>Y5Rt^Bv zc2#3QHA}_-4I?H1|3d44-E#O5OsL@1 zAv@hIbMz&yw-ONG(ls~xcjH_bL+rlQ8-C4Atj=(Lm<0isAJIw@q{hW!btXLaH{umn zHEW0lsuuMtt*tpAV@w+ya!|TlX36cG0L9uQCif>N1NerEva-<|xiO`HzQ66Hy+XVS zVtXq`6;Q9x6)yk2^aJLf&Z+?uLuFwB$-Aw^Tmcm(7oLK51G0yaGQgSx1U25E`SuWd zgF?LSqTy$LXaIkvH2Y=HC2MX{FhF;evao=0XJ}xJLU~F4g zU|SSlLm^%$F*?c=0_06fvzK#{8kf<^fvD-qY07Jlip)@;E5np&W2ON}-{6!nS<*R+ zfLwmuI!rNMMUi#2E($O;m1ZyB4X{naGd~pUC?`Q@!59YczX%UscsiIqU2(t`iEh8Iv1YxPQm{Qp5ZjmZqz3aE}*Z)P|>RbaYZ zlLQ#Y1xXH>k8dQy5c#ll$t|cJkBANLSoRMWk+aF{=zZ}m+M|)l^$rd?RuhF36mSW4 znaez8C|=5FotjBNh{Mm%PwERxT5PY?@H%=H1B;g|hT@KDGHFHoQtS-VLlDZV;a9!MPVK$|mCnXmzS|a_%lCRoffc zm~8%u0#tr*bxwwKBNLEv3bpYzw^7vSR6;hgi6s+PH|qC&V?Ye8Q$fHYU1s0->Nh?j z64sLr*t(6AqAzPgeI=iLKeZ@~SBmLNd}0&2wWybsOYi@7%L)C~HPY9t^ z=XKMU{@R%DglJ)!G~m<^tYxlLVb!m<&Ll>9M5heuR@u{+cN9(s-bO!gEqz?YJMb(< zt~(d36?CW5>%)^O%|AO6cOpU}Ok7b%R`fQp-p!+xf0Wc<>&t4uYDR0BFY@)dyX?G9L>*cO)}{y6 zCn6$Ll}MS29};O%=H}hL!ps(!GP571LR!)QuBf5y-~~JNu@t0Yc=^*^MZ-Z|l5tn& z%+9*S*^1-Rig2k_=TbR(e#V_8i%IggE$h{aXa6GWyX7w`{m>1u-|?eTd}DeqoV@^W ze7G&7c*esrZ=IE`Ai=V(-+aA(?}D*GQK6M>PXZ0ZJafho*qb4BdLuo2I5Zg3lKn6f zXDsCBm-wy<@2c=>7*N86(@DulKL-Hmus=E4&v`=`pc1O< z5Fv-Jyf#5FOA^DoihuJ;xh9;rL!pceh`ei9B@iIJGysJM-aL!EY|+eeZi_A`{0eCa z4>_ZN+}M|GR&ku6MvqdO!Y~Tm;<9nG3mZ#MhaAQLrrC;J;p;O}^hZuT-8ZLEW<~M$s{lv10v^t;!wr0 zggq58y8^IIi=Wg2sw5&U;_u~7hJX>=isP*j2F*>8OxJ<=ZV_;c zRZ%5tDj1>SSlC$wiRZUW8 zVbh60ZTh|3T&(C@SF-SBaizl;$rDH<_=cooH)n66cyGo#E8h+P*+~-)2gh1`vMt z$^izrSn&|cv*Zp0Tz_7dJngeF)d-O7B!1_nZMePh*S7!|-?Eley6SIWclnO@#H@oU zuA3p?X347e+LhN4K`AMPY#*F_4@p`MwwCxBnKKx3<^U_PyYkf${zMlUUeZq?FaC3< hV#Pso1xS{#P~G0xs?P;`kv{~$K1WxF51>gDwC7 literal 0 HcmV?d00001 diff --git a/test/group/link/normal.slvs b/test/group/link/normal.slvs new file mode 100644 index 0000000..97ba795 --- /dev/null +++ b/test/group/link/normal.slvs @@ -0,0 +1,465 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000003 +Group.type=5300 +Group.order=2 +Group.name=rect-v20 +Group.activeWorkplane.v=00010000 +Group.color=00646464 +Group.skipFirst=0 +Group.meshCombine=2 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00010000 0 + 2 00010001 0 + 3 00010020 0 + 4 00020000 0 + 5 00020001 0 + 6 00020020 0 + 7 00030000 0 + 8 00030001 0 + 9 00030020 0 + 10 00040000 0 + 11 00040001 0 + 12 00040002 0 + 13 00050000 0 + 14 00050001 0 + 15 00050002 0 + 16 00060000 0 + 17 00060001 0 + 18 00060002 0 + 19 00070000 0 + 20 00070001 0 + 21 00070002 0 + 22 80020000 0 + 23 80020001 0 + 24 80020002 0 +} +Group.impFile=/TESTROOT/rect_v20.slvs +Group.impFileRel=rect_v20.slvs +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=80030000 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=80030001 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=80030002 +AddParam + +Param.h.v.=80030003 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=80030004 +AddParam + +Param.h.v.=80030005 +AddParam + +Param.h.v.=80030006 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030005 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030008 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000b +Entity.point[1].v=8003000c +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000b +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000e +Entity.point[1].v=8003000f +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030010 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030011 +Entity.point[1].v=80030012 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030013 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030014 +Entity.point[1].v=80030015 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030014 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030015 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030017 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030018 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030018 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + diff --git a/test/group/link/normal_v20.slvs b/test/group/link/normal_v20.slvs new file mode 100644 index 0000000..f06c81d --- /dev/null +++ b/test/group/link/normal_v20.slvs @@ -0,0 +1,463 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000003 +Group.type=5300 +Group.order=2 +Group.name=rect-v20 +Group.activeWorkplane.v=00010000 +Group.opA.v=00000002 +Group.color=00646464 +Group.skipFirst=0 +Group.meshCombine=2 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00010000 0 + 2 00010001 0 + 3 00010020 0 + 4 00020000 0 + 5 00020001 0 + 6 00020020 0 + 7 00030000 0 + 8 00030001 0 + 9 00030020 0 + 10 00040000 0 + 11 00040001 0 + 12 00040002 0 + 13 00050000 0 + 14 00050001 0 + 15 00050002 0 + 16 00060000 0 + 17 00060001 0 + 18 00060002 0 + 19 00070000 0 + 20 00070001 0 + 21 00070002 0 + 22 80020000 0 + 23 80020001 0 + 24 80020002 0 +} +Group.impFile=Z:\TESTROOT\rect_v20.slvs +Group.impFileRel=rect_v20.slvs +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=80030000 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=80030001 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=80030002 +AddParam + +Param.h.v.=80030003 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=80030004 +AddParam + +Param.h.v.=80030005 +AddParam + +Param.h.v.=80030006 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030005 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030008 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000b +Entity.point[1].v=8003000c +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000b +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000e +Entity.point[1].v=8003000f +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030010 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030011 +Entity.point[1].v=80030012 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030013 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030014 +Entity.point[1].v=80030015 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030014 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030015 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030017 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030018 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030018 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + diff --git a/test/group/link/normal_v22.slvs b/test/group/link/normal_v22.slvs new file mode 100644 index 0000000..fb39ea2 --- /dev/null +++ b/test/group/link/normal_v22.slvs @@ -0,0 +1,465 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000003 +Group.type=5300 +Group.order=2 +Group.name=rect-v20 +Group.activeWorkplane.v=00010000 +Group.color=00646464 +Group.skipFirst=0 +Group.meshCombine=2 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00010000 0 + 2 00010001 0 + 3 00010020 0 + 4 00020000 0 + 5 00020001 0 + 6 00020020 0 + 7 00030000 0 + 8 00030001 0 + 9 00030020 0 + 10 00040000 0 + 11 00040001 0 + 12 00040002 0 + 13 00050000 0 + 14 00050001 0 + 15 00050002 0 + 16 00060000 0 + 17 00060001 0 + 18 00060002 0 + 19 00070000 0 + 20 00070001 0 + 21 00070002 0 + 22 80020000 0 + 23 80020001 0 + 24 80020002 0 +} +Group.impFile=/TESTROOT/rect_v20.slvs +Group.impFileRel=rect_v20.slvs +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=80030000 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=80030001 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=80030002 +AddParam + +Param.h.v.=80030003 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=80030004 +AddParam + +Param.h.v.=80030005 +AddParam + +Param.h.v.=80030006 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030005 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030008 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000b +Entity.point[1].v=8003000c +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000b +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000e +Entity.point[1].v=8003000f +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030010 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030011 +Entity.point[1].v=80030012 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030013 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030014 +Entity.point[1].v=80030015 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030014 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030015 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030017 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030018 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030018 +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + diff --git a/test/group/link/rect_v20.slvs b/test/group/link/rect_v20.slvs new file mode 100644 index 0000000..3bebad4 --- /dev/null +++ b/test/group/link/rect_v20.slvs @@ -0,0 +1,510 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00070010 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00070014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000007 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00070001 +Entity.point[1].v=00070002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040001 +Constraint.ptB.v=00050002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050001 +Constraint.ptB.v=00060002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00060001 +Constraint.ptB.v=00070002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000004 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00070001 +Constraint.ptB.v=00040002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000005 +Constraint.type=81 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000006 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000007 +Constraint.type=81 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00060000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000008 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00070000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/group/link/test.cpp b/test/group/link/test.cpp new file mode 100644 index 0000000..5e9db1b --- /dev/null +++ b/test/group/link/test.cpp @@ -0,0 +1,17 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} diff --git a/test/group/translate_asy/normal.png b/test/group/translate_asy/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..c9b4e4ec831e041d2e339d3a4d1cc6de6951bde5 GIT binary patch literal 8508 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 literal 0 HcmV?d00001 diff --git a/test/group/translate_asy/normal.slvs b/test/group/translate_asy/normal.slvs new file mode 100644 index 0000000..ec2bf7f --- /dev/null +++ b/test/group/translate_asy/normal.slvs @@ -0,0 +1,2088 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000003 +Group.type=5100 +Group.order=2 +Group.name=extrude +Group.opA.v=00000002 +Group.color=00646464 +Group.subtype=7000 +Group.skipFirst=0 +Group.meshCombine=2 +Group.predef.entityB.v=80020000 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00040000 1002 + 2 00040001 1002 + 3 00040002 1002 + 4 00040000 1001 + 5 00040001 1001 + 6 00040002 1001 + 7 00040000 1004 + 8 00040001 1003 + 9 00040002 1003 + 10 00050000 1002 + 11 00050001 1002 + 12 00050002 1002 + 13 00050000 1001 + 14 00050001 1001 + 15 00050002 1001 + 16 00050000 1004 + 17 00050001 1003 + 18 00050002 1003 + 19 00060000 1002 + 20 00060001 1002 + 21 00060002 1002 + 22 00060000 1001 + 23 00060001 1001 + 24 00060002 1001 + 25 00060000 1004 + 26 00060001 1003 + 27 00060002 1003 + 28 00070000 1002 + 29 00070001 1002 + 30 00070002 1002 + 31 00070000 1001 + 32 00070001 1001 + 33 00070002 1001 + 34 00070000 1004 + 35 00070001 1003 + 36 00070002 1003 + 37 80020000 1002 + 38 80020000 1001 + 39 80020001 1002 + 40 80020002 1002 + 41 80020001 1001 + 42 80020002 1001 + 43 80020002 1003 + 44 00000000 1001 + 45 00000000 1002 +} +AddGroup + +Group.h.v=00000004 +Group.type=5201 +Group.order=3 +Group.name=translate +Group.opA.v=00000003 +Group.valA=2.00000000000000000000 +Group.color=00646464 +Group.subtype=7000 +Group.skipFirst=0 +Group.meshCombine=2 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 80030001 0 + 2 80030002 0 + 3 80030003 0 + 4 80030004 0 + 5 80030005 0 + 6 80030006 0 + 7 80030007 0 + 8 80030008 0 + 9 80030009 0 + 10 8003000a 0 + 11 8003000b 0 + 12 8003000c 0 + 13 8003000d 0 + 14 8003000e 0 + 15 8003000f 0 + 16 80030010 0 + 17 80030011 0 + 18 80030012 0 + 19 80030013 0 + 20 80030014 0 + 21 80030015 0 + 22 80030016 0 + 23 80030017 0 + 24 80030018 0 + 25 80030019 0 + 26 8003001a 0 + 27 8003001b 0 + 28 8003001c 0 + 29 8003001d 0 + 30 8003001e 0 + 31 8003001f 0 + 32 80030020 0 + 33 80030021 0 + 34 80030022 0 + 35 80030023 0 + 36 80030024 0 + 37 80030027 0 + 38 80030028 0 + 39 80030029 0 + 40 8003002a 0 + 41 8003002b 0 + 42 8003002c 0 + 43 8003002d 0 + 44 80030001 1 + 45 80030002 1 + 46 80030003 1 + 47 80030004 1 + 48 80030005 1 + 49 80030006 1 + 50 80030007 1 + 51 80030008 1 + 52 80030009 1 + 53 8003000a 1 + 54 8003000b 1 + 55 8003000c 1 + 56 8003000d 1 + 57 8003000e 1 + 58 8003000f 1 + 59 80030010 1 + 60 80030011 1 + 61 80030012 1 + 62 80030013 1 + 63 80030014 1 + 64 80030015 1 + 65 80030016 1 + 66 80030017 1 + 67 80030018 1 + 68 80030019 1 + 69 8003001a 1 + 70 8003001b 1 + 71 8003001c 1 + 72 8003001d 1 + 73 8003001e 1 + 74 8003001f 1 + 75 80030020 1 + 76 80030021 1 + 77 80030022 1 + 78 80030023 1 + 79 80030024 1 + 80 80030027 1 + 81 80030028 1 + 82 80030029 1 + 83 8003002a 1 + 84 8003002b 1 + 85 8003002c 1 + 86 8003002d 1 + 87 80030001 1000 + 88 80030002 1000 + 89 80030003 1000 + 90 80030004 1000 + 91 80030005 1000 + 92 80030006 1000 + 93 80030007 1000 + 94 80030008 1000 + 95 80030009 1000 + 96 8003000a 1000 + 97 8003000b 1000 + 98 8003000c 1000 + 99 8003000d 1000 + 100 8003000e 1000 + 101 8003000f 1000 + 102 80030010 1000 + 103 80030011 1000 + 104 80030012 1000 + 105 80030013 1000 + 106 80030014 1000 + 107 80030015 1000 + 108 80030016 1000 + 109 80030017 1000 + 110 80030018 1000 + 111 80030019 1000 + 112 8003001a 1000 + 113 8003001b 1000 + 114 8003001c 1000 + 115 8003001d 1000 + 116 8003001e 1000 + 117 8003001f 1000 + 118 80030020 1000 + 119 80030021 1000 + 120 80030022 1000 + 121 80030023 1000 + 122 80030024 1000 + 123 80030027 1000 + 124 80030028 1000 + 125 80030029 1000 + 126 8003002a 1000 + 127 8003002b 1000 + 128 8003002c 1000 + 129 8003002d 1000 +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00070010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00070011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00070014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030000 +AddParam + +Param.h.v.=80030001 +AddParam + +Param.h.v.=80030002 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80040000 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80040001 +Param.val=2.50000000000000000000 +AddParam + +Param.h.v.=80040002 +Param.val=-2.50000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000007 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00070001 +Entity.point[1].v=00070002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030001 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.point[1].v=80030003 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030004 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030005 +Entity.point[1].v=80030006 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030007 +Entity.type=5001 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actNormal.vx=-1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030005 +Entity.point[1].v=80030002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.point[1].v=80030003 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000b +Entity.point[1].v=8003000c +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000b +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000e +Entity.point[1].v=8003000f +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030010 +Entity.type=5001 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actNormal.vy=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000e +Entity.point[1].v=8003000b +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.point[1].v=8003000c +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030013 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030014 +Entity.point[1].v=80030015 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030014 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030015 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030016 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030017 +Entity.point[1].v=80030018 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030017 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030018 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030019 +Entity.type=5001 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003001a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030017 +Entity.point[1].v=80030014 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003001b +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030018 +Entity.point[1].v=80030015 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003001c +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003001d +Entity.point[1].v=8003001e +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003001d +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003001e +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003001f +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030020 +Entity.point[1].v=80030021 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030020 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030021 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030022 +Entity.type=5001 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actNormal.vy=-1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030023 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030020 +Entity.point[1].v=8003001d +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030024 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030021 +Entity.point[1].v=8003001e +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030027 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030028 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030028 +Entity.type=2010 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030029 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003002a +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003002a +Entity.type=2010 +Entity.construction=1 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003002b +Entity.type=11000 +Entity.construction=1 +Entity.point[0].v=8003002a +Entity.point[1].v=80030028 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003002c +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003002a +Entity.actPoint.z=10.00000000000000000000 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003002d +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=80030028 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040001 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040002 +Entity.point[1].v=80040003 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040002 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040003 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040004 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040005 +Entity.point[1].v=80040006 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040005 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040006 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040007 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actNormal.vx=-1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040008 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040005 +Entity.point[1].v=80040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040009 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040006 +Entity.point[1].v=80040003 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004000a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004000b +Entity.point[1].v=8004000c +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004000b +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004000c +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004000d +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004000e +Entity.point[1].v=8004000f +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004000e +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004000f +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040010 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actNormal.vy=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040011 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004000e +Entity.point[1].v=8004000b +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040012 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004000f +Entity.point[1].v=8004000c +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040013 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040014 +Entity.point[1].v=80040015 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040014 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040015 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040016 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040017 +Entity.point[1].v=80040018 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040017 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040018 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040019 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004001a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040017 +Entity.point[1].v=80040014 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004001b +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040018 +Entity.point[1].v=80040015 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004001c +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004001d +Entity.point[1].v=8004001e +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004001d +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004001e +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004001f +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040020 +Entity.point[1].v=80040021 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040020 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040021 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040022 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actNormal.vy=-1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040023 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040020 +Entity.point[1].v=8004001d +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040024 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040021 +Entity.point[1].v=8004001e +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040025 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80040026 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040026 +Entity.type=2010 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040027 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80040028 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040028 +Entity.type=2010 +Entity.construction=1 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040029 +Entity.type=11000 +Entity.construction=1 +Entity.point[0].v=80040028 +Entity.point[1].v=80040026 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004002a +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.z=10.00000000000000000000 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004002b +Entity.type=5003 +Entity.construction=0 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040057 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040058 +Entity.point[1].v=80040059 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040058 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040059 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004005a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004005b +Entity.point[1].v=8004005c +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004005b +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004005c +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004005d +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actNormal.vx=-1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004005e +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004005b +Entity.point[1].v=80040058 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004005f +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004005c +Entity.point[1].v=80040059 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040060 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040061 +Entity.point[1].v=80040062 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040061 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040062 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040063 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040064 +Entity.point[1].v=80040065 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040064 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040065 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040066 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actNormal.vy=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040067 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040064 +Entity.point[1].v=80040061 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040068 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040065 +Entity.point[1].v=80040062 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040069 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004006a +Entity.point[1].v=8004006b +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004006a +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004006b +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004006c +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004006d +Entity.point[1].v=8004006e +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004006d +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004006e +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004006f +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040070 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004006d +Entity.point[1].v=8004006a +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040071 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004006e +Entity.point[1].v=8004006b +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040072 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040073 +Entity.point[1].v=80040074 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040073 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040074 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040075 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040076 +Entity.point[1].v=80040077 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040076 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040077 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040078 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actNormal.vy=-1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040079 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040076 +Entity.point[1].v=80040073 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004007a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040077 +Entity.point[1].v=80040074 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004007b +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8004007c +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004007c +Entity.type=2010 +Entity.construction=1 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004007d +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8004007e +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004007e +Entity.type=2010 +Entity.construction=1 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004007f +Entity.type=11000 +Entity.construction=1 +Entity.point[0].v=8004007e +Entity.point[1].v=8004007c +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040080 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040081 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040001 +Constraint.ptB.v=00050002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050001 +Constraint.ptB.v=00060002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00060001 +Constraint.ptB.v=00070002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000004 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00070001 +Constraint.ptB.v=00040002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000005 +Constraint.type=81 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000006 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000007 +Constraint.type=81 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00060000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000008 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00070000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Surface 00000001 00646464 8004002a 1 1 +SCtrl 0 0 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000010000000827 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -5.00000000000000000000 -5.00000000010000000827 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 10.00000000010000000827 -5.00000000010000000827 10.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000001 0 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +TrimBy 00000004 0 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +TrimBy 00000007 0 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +TrimBy 0000000a 0 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +AddSurface +Surface 00000002 00646464 8004002b 1 1 +SCtrl 0 0 10.00000000010000000827 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 10.00000000010000000827 -5.00000000010000000827 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 -5.00000000000000000000 -5.00000000010000000827 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000002 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +TrimBy 00000005 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +TrimBy 00000008 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000b 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000003 00646464 80040010 1 1 +SCtrl 0 0 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000001 1 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +TrimBy 00000002 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +TrimBy 00000003 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +TrimBy 0000000c 0 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000004 00646464 80040019 1 1 +SCtrl 0 0 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000004 1 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +TrimBy 00000005 0 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 00000006 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +TrimBy 00000003 0 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000005 00646464 80040022 1 1 +SCtrl 0 0 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000007 1 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +TrimBy 00000008 0 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 00000009 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +TrimBy 00000006 0 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000006 00646464 80040007 1 1 +SCtrl 0 0 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000a 1 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +TrimBy 0000000b 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000c 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +TrimBy 00000009 0 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000007 00646464 80040080 1 1 +SCtrl 0 0 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 20.00000000010000178463 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 5.00000000000000000000 -0.00000000010000000827 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 20.00000000010000178463 -0.00000000010000000827 5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000d 0 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000010 0 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +TrimBy 00000013 0 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +TrimBy 00000016 0 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +AddSurface +Surface 00000008 00646464 80040081 1 1 +SCtrl 0 0 20.00000000010000178463 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 20.00000000010000178463 -0.00000000010000000827 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 5.00000000000000000000 -0.00000000010000000827 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000e 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +TrimBy 00000011 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +TrimBy 00000014 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +TrimBy 00000017 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +AddSurface +Surface 00000009 00646464 80040066 1 1 +SCtrl 0 0 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000d 1 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 0000000e 0 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +TrimBy 0000000f 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000018 0 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +AddSurface +Surface 0000000a 00646464 8004006f 1 1 +SCtrl 0 0 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000010 1 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000011 0 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +TrimBy 00000012 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +TrimBy 0000000f 0 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +AddSurface +Surface 0000000b 00646464 80040078 1 1 +SCtrl 0 0 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000013 1 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +TrimBy 00000014 0 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +TrimBy 00000015 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +TrimBy 00000012 0 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +AddSurface +Surface 0000000c 00646464 8004005d 1 1 +SCtrl 0 0 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000016 1 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +TrimBy 00000017 0 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +TrimBy 00000018 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000015 0 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +AddSurface +Curve 00000001 1 1 00000001 00000003 +CCtrl 0 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +CurvePt 1 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +AddCurve +Curve 00000002 1 1 00000002 00000003 +CCtrl 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +CurvePt 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000003 1 1 00000003 00000004 +CCtrl 0 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +CurvePt 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000004 1 1 00000001 00000004 +CCtrl 0 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +CurvePt 1 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +AddCurve +Curve 00000005 1 1 00000002 00000004 +CCtrl 0 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +CurvePt 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000006 1 1 00000004 00000005 +CCtrl 0 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +CurvePt 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000007 1 1 00000001 00000005 +CCtrl 0 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +AddCurve +Curve 00000008 1 1 00000002 00000005 +CCtrl 0 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000009 1 1 00000005 00000006 +CCtrl 0 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 0000000a 1 1 00000001 00000006 +CCtrl 0 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +AddCurve +Curve 0000000b 1 1 00000002 00000006 +CCtrl 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 0000000c 1 1 00000006 00000003 +CCtrl 0 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 0000000d 1 1 00000007 00000009 +CCtrl 0 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +AddCurve +Curve 0000000e 1 1 00000008 00000009 +CCtrl 0 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +AddCurve +Curve 0000000f 1 1 00000009 0000000a +CCtrl 0 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +AddCurve +Curve 00000010 1 1 00000007 0000000a +CCtrl 0 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +CurvePt 1 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +AddCurve +Curve 00000011 1 1 00000008 0000000a +CCtrl 0 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +CurvePt 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +AddCurve +Curve 00000012 1 1 0000000a 0000000b +CCtrl 0 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +CurvePt 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +AddCurve +Curve 00000013 1 1 00000007 0000000b +CCtrl 0 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +CurvePt 1 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +AddCurve +Curve 00000014 1 1 00000008 0000000b +CCtrl 0 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +CurvePt 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +AddCurve +Curve 00000015 1 1 0000000b 0000000c +CCtrl 0 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +CurvePt 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +AddCurve +Curve 00000016 1 1 00000007 0000000c +CCtrl 0 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +CurvePt 1 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +AddCurve +Curve 00000017 1 1 00000008 0000000c +CCtrl 0 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +CurvePt 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +AddCurve +Curve 00000018 1 1 0000000c 00000009 +CCtrl 0 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +CurvePt 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +AddCurve diff --git a/test/group/translate_asy/normal_v22.slvs b/test/group/translate_asy/normal_v22.slvs new file mode 100644 index 0000000..2f013bc --- /dev/null +++ b/test/group/translate_asy/normal_v22.slvs @@ -0,0 +1,2088 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000003 +Group.type=5100 +Group.order=2 +Group.name=extrude +Group.opA.v=00000002 +Group.color=00646464 +Group.subtype=7000 +Group.skipFirst=0 +Group.meshCombine=2 +Group.predef.entityB.v=80020000 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00040000 1002 + 2 00040001 1002 + 3 00040002 1002 + 4 00040000 1001 + 5 00040001 1001 + 6 00040002 1001 + 7 00040000 1004 + 8 00040001 1003 + 9 00040002 1003 + 10 00050000 1002 + 11 00050001 1002 + 12 00050002 1002 + 13 00050000 1001 + 14 00050001 1001 + 15 00050002 1001 + 16 00050000 1004 + 17 00050001 1003 + 18 00050002 1003 + 19 00060000 1002 + 20 00060001 1002 + 21 00060002 1002 + 22 00060000 1001 + 23 00060001 1001 + 24 00060002 1001 + 25 00060000 1004 + 26 00060001 1003 + 27 00060002 1003 + 28 00070000 1002 + 29 00070001 1002 + 30 00070002 1002 + 31 00070000 1001 + 32 00070001 1001 + 33 00070002 1001 + 34 00070000 1004 + 35 00070001 1003 + 36 00070002 1003 + 37 80020000 1002 + 38 80020000 1001 + 39 80020001 1002 + 40 80020002 1002 + 41 80020001 1001 + 42 80020002 1001 + 43 80020002 1003 + 44 00000000 1001 + 45 00000000 1002 +} +AddGroup + +Group.h.v=00000004 +Group.type=5201 +Group.order=3 +Group.name=translate +Group.opA.v=00000003 +Group.valA=2.00000000000000000000 +Group.color=00646464 +Group.subtype=7000 +Group.skipFirst=0 +Group.meshCombine=2 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 80030001 0 + 2 80030002 0 + 3 80030003 0 + 4 80030004 0 + 5 80030005 0 + 6 80030006 0 + 7 80030007 0 + 8 80030008 0 + 9 80030009 0 + 10 8003000a 0 + 11 8003000b 0 + 12 8003000c 0 + 13 8003000d 0 + 14 8003000e 0 + 15 8003000f 0 + 16 80030010 0 + 17 80030011 0 + 18 80030012 0 + 19 80030013 0 + 20 80030014 0 + 21 80030015 0 + 22 80030016 0 + 23 80030017 0 + 24 80030018 0 + 25 80030019 0 + 26 8003001a 0 + 27 8003001b 0 + 28 8003001c 0 + 29 8003001d 0 + 30 8003001e 0 + 31 8003001f 0 + 32 80030020 0 + 33 80030021 0 + 34 80030022 0 + 35 80030023 0 + 36 80030024 0 + 37 80030027 0 + 38 80030028 0 + 39 80030029 0 + 40 8003002a 0 + 41 8003002b 0 + 42 8003002c 0 + 43 8003002d 0 + 44 80030001 1 + 45 80030002 1 + 46 80030003 1 + 47 80030004 1 + 48 80030005 1 + 49 80030006 1 + 50 80030007 1 + 51 80030008 1 + 52 80030009 1 + 53 8003000a 1 + 54 8003000b 1 + 55 8003000c 1 + 56 8003000d 1 + 57 8003000e 1 + 58 8003000f 1 + 59 80030010 1 + 60 80030011 1 + 61 80030012 1 + 62 80030013 1 + 63 80030014 1 + 64 80030015 1 + 65 80030016 1 + 66 80030017 1 + 67 80030018 1 + 68 80030019 1 + 69 8003001a 1 + 70 8003001b 1 + 71 8003001c 1 + 72 8003001d 1 + 73 8003001e 1 + 74 8003001f 1 + 75 80030020 1 + 76 80030021 1 + 77 80030022 1 + 78 80030023 1 + 79 80030024 1 + 80 80030027 1 + 81 80030028 1 + 82 80030029 1 + 83 8003002a 1 + 84 8003002b 1 + 85 8003002c 1 + 86 8003002d 1 + 87 80030001 1000 + 88 80030002 1000 + 89 80030003 1000 + 90 80030004 1000 + 91 80030005 1000 + 92 80030006 1000 + 93 80030007 1000 + 94 80030008 1000 + 95 80030009 1000 + 96 8003000a 1000 + 97 8003000b 1000 + 98 8003000c 1000 + 99 8003000d 1000 + 100 8003000e 1000 + 101 8003000f 1000 + 102 80030010 1000 + 103 80030011 1000 + 104 80030012 1000 + 105 80030013 1000 + 106 80030014 1000 + 107 80030015 1000 + 108 80030016 1000 + 109 80030017 1000 + 110 80030018 1000 + 111 80030019 1000 + 112 8003001a 1000 + 113 8003001b 1000 + 114 8003001c 1000 + 115 8003001d 1000 + 116 8003001e 1000 + 117 8003001f 1000 + 118 80030020 1000 + 119 80030021 1000 + 120 80030022 1000 + 121 80030023 1000 + 122 80030024 1000 + 123 80030027 1000 + 124 80030028 1000 + 125 80030029 1000 + 126 8003002a 1000 + 127 8003002b 1000 + 128 8003002c 1000 + 129 8003002d 1000 +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00050010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050011 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00050013 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00050014 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00060013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00060014 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00070010 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00070011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00070013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00070014 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030000 +AddParam + +Param.h.v.=80030001 +AddParam + +Param.h.v.=80030002 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80040000 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80040001 +Param.val=2.50000000000000000000 +AddParam + +Param.h.v.=80040002 +Param.val=-2.50000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000005 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000006 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Request.h.v=00000007 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00050001 +Entity.point[1].v=00050002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00050002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00060001 +Entity.point[1].v=00060002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00060002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00070001 +Entity.point[1].v=00070002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00070002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030001 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.point[1].v=80030003 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030004 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030005 +Entity.point[1].v=80030006 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030007 +Entity.type=5001 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actNormal.vx=-1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030005 +Entity.point[1].v=80030002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030006 +Entity.point[1].v=80030003 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000b +Entity.point[1].v=8003000c +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000b +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000e +Entity.point[1].v=8003000f +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030010 +Entity.type=5001 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actNormal.vy=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000e +Entity.point[1].v=8003000b +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003000f +Entity.point[1].v=8003000c +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030013 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030014 +Entity.point[1].v=80030015 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030014 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030015 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030016 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030017 +Entity.point[1].v=80030018 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030017 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030018 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030019 +Entity.type=5001 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003001a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030017 +Entity.point[1].v=80030014 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003001b +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030018 +Entity.point[1].v=80030015 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003001c +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003001d +Entity.point[1].v=8003001e +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003001d +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003001e +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003001f +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030020 +Entity.point[1].v=80030021 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030020 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030021 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030022 +Entity.type=5001 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actNormal.vy=-1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030023 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030020 +Entity.point[1].v=8003001d +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030024 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80030021 +Entity.point[1].v=8003001e +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030027 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80030028 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030028 +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030029 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8003002a +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003002a +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003002b +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8003002a +Entity.point[1].v=80030028 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003002c +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=8003002a +Entity.actPoint.z=10.00000000000000000000 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003002d +Entity.type=5000 +Entity.construction=0 +Entity.point[0].v=80030028 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040001 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040002 +Entity.point[1].v=80040003 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040002 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040003 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040004 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040005 +Entity.point[1].v=80040006 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040005 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040006 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040007 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actNormal.vx=-1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040008 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040005 +Entity.point[1].v=80040002 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040009 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040006 +Entity.point[1].v=80040003 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004000a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004000b +Entity.point[1].v=8004000c +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004000b +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004000c +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004000d +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004000e +Entity.point[1].v=8004000f +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004000e +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004000f +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040010 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actNormal.vy=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040011 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004000e +Entity.point[1].v=8004000b +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040012 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004000f +Entity.point[1].v=8004000c +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040013 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040014 +Entity.point[1].v=80040015 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040014 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040015 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040016 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040017 +Entity.point[1].v=80040018 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040017 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040018 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040019 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004001a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040017 +Entity.point[1].v=80040014 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004001b +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040018 +Entity.point[1].v=80040015 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004001c +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004001d +Entity.point[1].v=8004001e +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004001d +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004001e +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004001f +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040020 +Entity.point[1].v=80040021 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040020 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040021 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040022 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actNormal.vy=-1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040023 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040020 +Entity.point[1].v=8004001d +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040024 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040021 +Entity.point[1].v=8004001e +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040025 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80040026 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040026 +Entity.type=2010 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040027 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80040028 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040028 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.z=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040029 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040028 +Entity.point[1].v=80040026 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004002a +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.z=10.00000000000000000000 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004002b +Entity.type=5003 +Entity.construction=0 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040057 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040058 +Entity.point[1].v=80040059 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040058 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040059 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004005a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004005b +Entity.point[1].v=8004005c +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004005b +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004005c +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004005d +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actNormal.vx=-1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004005e +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004005b +Entity.point[1].v=80040058 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004005f +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004005c +Entity.point[1].v=80040059 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040060 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040061 +Entity.point[1].v=80040062 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040061 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040062 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040063 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040064 +Entity.point[1].v=80040065 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040064 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040065 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040066 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actNormal.vy=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040067 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040064 +Entity.point[1].v=80040061 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040068 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040065 +Entity.point[1].v=80040062 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040069 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004006a +Entity.point[1].v=8004006b +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004006a +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004006b +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004006c +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004006d +Entity.point[1].v=8004006e +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004006d +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004006e +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004006f +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actNormal.vx=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040070 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004006d +Entity.point[1].v=8004006a +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040071 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004006e +Entity.point[1].v=8004006b +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040072 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040073 +Entity.point[1].v=80040074 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040073 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040074 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040075 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040076 +Entity.point[1].v=80040077 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040076 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040077 +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040078 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actNormal.vy=-1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040079 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040076 +Entity.point[1].v=80040073 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004007a +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=80040077 +Entity.point[1].v=80040074 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004007b +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8004007c +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004007c +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004007d +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=8004007e +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004007e +Entity.type=2010 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8004007f +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=8004007e +Entity.point[1].v=8004007c +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040080 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=5.00000000000000000000 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80040081 +Entity.type=5003 +Entity.construction=0 +Entity.actPoint.x=10.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actPoint.z=-5.00000000000000000000 +Entity.actNormal.vz=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00040001 +Constraint.ptB.v=00050002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000002 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00050001 +Constraint.ptB.v=00060002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000003 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00060001 +Constraint.ptB.v=00070002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000004 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.ptA.v=00070001 +Constraint.ptB.v=00040002 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000005 +Constraint.type=81 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00040000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000006 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00050000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000007 +Constraint.type=81 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00060000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Constraint.h.v=00000008 +Constraint.type=80 +Constraint.group.v=00000002 +Constraint.workplane.v=80020000 +Constraint.entityA.v=00070000 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + +Surface 00000001 00646464 8004002a 1 1 +SCtrl 0 0 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000010000000827 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -5.00000000000000000000 -5.00000000010000000827 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 10.00000000010000000827 -5.00000000010000000827 10.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000001 0 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +TrimBy 00000004 0 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +TrimBy 00000007 0 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +TrimBy 0000000a 0 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +AddSurface +Surface 00000002 00646464 8004002b 1 1 +SCtrl 0 0 10.00000000010000000827 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 10.00000000010000000827 -5.00000000010000000827 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 -5.00000000000000000000 -5.00000000010000000827 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000002 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +TrimBy 00000005 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +TrimBy 00000008 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000b 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000003 00646464 80040010 1 1 +SCtrl 0 0 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000001 1 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +TrimBy 00000002 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +TrimBy 00000003 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +TrimBy 0000000c 0 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000004 00646464 80040019 1 1 +SCtrl 0 0 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000004 1 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +TrimBy 00000005 0 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 00000006 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +TrimBy 00000003 0 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000005 00646464 80040022 1 1 +SCtrl 0 0 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000007 1 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +TrimBy 00000008 0 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +TrimBy 00000009 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +TrimBy 00000006 0 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000006 00646464 80040007 1 1 +SCtrl 0 0 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000a 1 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +TrimBy 0000000b 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +TrimBy 0000000c 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +TrimBy 00000009 0 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddSurface +Surface 00000007 00646464 80040080 1 1 +SCtrl 0 0 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 20.00000000010000178463 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 5.00000000000000000000 -0.00000000010000000827 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 20.00000000010000178463 -0.00000000010000000827 5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000d 0 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000010 0 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +TrimBy 00000013 0 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +TrimBy 00000016 0 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +AddSurface +Surface 00000008 00646464 80040081 1 1 +SCtrl 0 0 20.00000000010000178463 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 20.00000000010000178463 -0.00000000010000000827 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 5.00000000000000000000 -0.00000000010000000827 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000e 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +TrimBy 00000011 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +TrimBy 00000014 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +TrimBy 00000017 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +AddSurface +Surface 00000009 00646464 80040066 1 1 +SCtrl 0 0 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 0000000d 1 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 0000000e 0 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +TrimBy 0000000f 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000018 0 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +AddSurface +Surface 0000000a 00646464 8004006f 1 1 +SCtrl 0 0 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000010 1 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000011 0 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +TrimBy 00000012 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +TrimBy 0000000f 0 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +AddSurface +Surface 0000000b 00646464 80040078 1 1 +SCtrl 0 0 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000013 1 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +TrimBy 00000014 0 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +TrimBy 00000015 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +TrimBy 00000012 0 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +AddSurface +Surface 0000000c 00646464 8004005d 1 1 +SCtrl 0 0 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 0 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 0 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +SCtrl 1 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +TrimBy 00000016 1 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +TrimBy 00000017 0 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +TrimBy 00000018 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +TrimBy 00000015 0 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +AddSurface +Curve 00000001 1 1 00000001 00000003 +CCtrl 0 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +CurvePt 1 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +AddCurve +Curve 00000002 1 1 00000002 00000003 +CCtrl 0 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +CurvePt 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000003 1 1 00000003 00000004 +CCtrl 0 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +CurvePt 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000004 1 1 00000001 00000004 +CCtrl 0 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +CurvePt 1 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +AddCurve +Curve 00000005 1 1 00000002 00000004 +CCtrl 0 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +CurvePt 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000006 1 1 00000004 00000005 +CCtrl 0 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +CurvePt 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000007 1 1 00000001 00000005 +CCtrl 0 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +AddCurve +Curve 00000008 1 1 00000002 00000005 +CCtrl 0 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 -5.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 00000009 1 1 00000005 00000006 +CCtrl 0 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 0000000a 1 1 00000001 00000006 +CCtrl 0 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 10.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +AddCurve +Curve 0000000b 1 1 00000002 00000006 +CCtrl 0 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 5.00000000000000000000 0.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 0000000c 1 1 00000006 00000003 +CCtrl 0 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 10.00000000000000000000 +CurvePt 1 10.00000000000000000000 -5.00000000000000000000 0.00000000000000000000 +AddCurve +Curve 0000000d 1 1 00000007 00000009 +CCtrl 0 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +AddCurve +Curve 0000000e 1 1 00000008 00000009 +CCtrl 0 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +AddCurve +Curve 0000000f 1 1 00000009 0000000a +CCtrl 0 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +AddCurve +Curve 00000010 1 1 00000007 0000000a +CCtrl 0 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +CurvePt 1 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +AddCurve +Curve 00000011 1 1 00000008 0000000a +CCtrl 0 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +CurvePt 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +AddCurve +Curve 00000012 1 1 0000000a 0000000b +CCtrl 0 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +CurvePt 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +AddCurve +Curve 00000013 1 1 00000007 0000000b +CCtrl 0 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +CurvePt 1 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +AddCurve +Curve 00000014 1 1 00000008 0000000b +CCtrl 0 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 5.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +CurvePt 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +AddCurve +Curve 00000015 1 1 0000000b 0000000c +CCtrl 0 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +CurvePt 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +AddCurve +Curve 00000016 1 1 00000007 0000000c +CCtrl 0 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 20.00000000000000000000 10.00000000000000000000 5.00000000000000000000 +CurvePt 1 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +AddCurve +Curve 00000017 1 1 00000008 0000000c +CCtrl 0 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 20.00000000000000000000 10.00000000000000000000 -5.00000000000000000000 +CurvePt 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +AddCurve +Curve 00000018 1 1 0000000c 00000009 +CCtrl 0 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 Weight 1.00000000000000000000 +CCtrl 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 Weight 1.00000000000000000000 +CurvePt 1 20.00000000000000000000 0.00000000000000000000 5.00000000000000000000 +CurvePt 1 20.00000000000000000000 0.00000000000000000000 -5.00000000000000000000 +AddCurve diff --git a/test/group/translate_asy/test.cpp b/test/group/translate_asy/test.cpp new file mode 100644 index 0000000..957dcce --- /dev/null +++ b/test/group/translate_asy/test.cpp @@ -0,0 +1,29 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER_ISO("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_inters) { + CHECK_LOAD("normal.slvs"); + + Group *g = SK.GetGroup(SS.GW.activeGroup); + g->GenerateDisplayItems(); + SMesh *m = &g->displayMesh; + + SEdgeList el = {}; + bool inters, leaks; + SKdNode::From(m)->MakeCertainEdgesInto(&el, + EdgeKind::SELF_INTER, /*coplanarIsInter=*/false, &inters, &leaks); + el.Clear(); + + // The assembly is supposed to interfere. + CHECK_TRUE(inters); +} diff --git a/test/group/translate_nd/normal.png b/test/group/translate_nd/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..4f5ee2c74ccb18e3990e448ba91446e4f0d2cfcc GIT binary patch literal 4983 zcmd5=dsx!<9{z%v<|S-d&AiaoN-HXxndH39Y|dk@i>8zYIF~0QGt0ZC*hN>CJnb~G zC^c)=6ctOfloT`Nlz6F*Xd#+0@j_~ah@isxfv!opX3u%{Jm-1fA1=S&=lglz&-=cg z->Gfix$5gI)&T(MyM61j0{}Qi`PQBdeNqva-Uh&Y2RE0my`nDl^E`GKKd4CVq#9FS z%>B)D=stGVakFSG)6ndOFZJpU)tu@vwd{kX5Zwlui!TND%mp~NvovDnP$4SA{1`JX zY^OJQMdd@(wJY?JAOP-Vwx2 zPQ!ri-r3XihZw)bQ>;yFH{4^R-poyeU{8B(KwP%&_#fSFLKOPzggMWk$C!fb?nZS~ znl;l}3^l;QhkDbYHlCi-HxJxhQFc&U4dNuuvz!HxzI&*A)!q^pvT?ZoHd7>H8W0)Tt@u6XT=w zJ+tP&KL8MI!NT7LP8J^B$h80tb6a>%zkG`)!)xwFt(@G-J(t4`0kT%ytcxpl8Nr+Q zQgUt$a#Y8pv~9d2%;R|De44BAFbsEzE~*w=4Q3 z$&v(lFh}S4`3!F@`AEP2a-pp7;Uil8l%D-DsJvH(`pmoq|MN@lcR|`r$Ohng z;1v3OSb|<=#{f$kAw^tOm|s!Qfc{AmY9e}p7VKTYs)~cATDI=2l3`XHzlo7s=8S$U z5arO3%~#Rwha9~So!2grqC*|JA_nGOr)3i=}&SQ1W>|4Oq*#;ae)t#?Eo`f&x}Oa3R)74NNNH4AS`HqJ$-8lkd`^SIo;&mgUnowQYx4$K~W^iSIX{t8=- zgEO$Yuz;h{yXDeC5alt^Bx=`G6HW*+4?k zya}Rs>J)I_AB$bTg>ETFM#h@Nny{p+2has(j-jREnzjEl)BCCqPEhL5O`ZmGhaYYy ziFhL?7`t)F>M*ufY(f*878uFqoX|z+} zm>$t6kzG*iIU-dk8iPH``5iKmJoG?Cg5!SVf}{k+=<^m1Sp+AZQB9>6{m_`Ey-3I%L<}m%$}>klEio;#2@u^8 zxOU}7zzJK)lJw%?5mIe+c(wFKCqxx&85v>;>2yrB$G`+vj)hBvA-xwSxN;b=u!$6j z;(JM3_{Q6=?W42x7QT$$Z8q|n-k7k^=B#>^+q10DDuD`xDQ%6e_VV_A#pmXG+ zp+x8sx?dp^#)fHLQR6;c`&uEU+{*~0%0(|CVeWya43>QB2g~2tfS2k!aXWLH2`bE zVkl*#u*`^>ZM_{3J#W1Ygn!ZL-(zjlS#j51u>rCDOu&PKnre9|JaK37avgAJ|Frhl zQ`Oo8TTh!eK9s0=7#vn*k29gc9xntC1RlNRFhXx`X*P0w zpJ13&>cNmm2P`t`8}dd4|LzwJ zEQU#}!!z_9t-N&Rv8DQwO}ItWa$JIYL~e-R|7~sf^*ne-J2owN&2w@n`3CWT9eqA+F#V{X+>7r+tuF}<7zZI&1b;q|Bq}qxuj$n3+w8X5x|HwMJ0z{!wH`D z0N{I7Qdvx2eiIP?C5uv?&ivgF;AG=nTBmAP+0v z)N7H}J0RVfP;M)<=xGxx2JSwrj(T3zI@IWMd}J7hXnPC|QFNo!vM3Y_PcccXnPakB z_DYhQ1R=Y2jeeO{-g)Nd-A;HqXDmw;A;;FIs3zw?^u^gwgjRtzt%#}O=J=y18SVm2Na(xKbIXcB77|XVWe38XGNG;euA!?HMH3vobHj`o z#5ljCdTr%ZElP67yvN*Y$fOeGlzzVy{U}4#f%G_&|cezUTv&3!({V2Ee_t)ATi=fHU o-FwPlX8X +#include + +#include "harness.h" + +#if defined(WIN32) +# include +#else +# include +#endif + +namespace SolveSpace { +namespace Platform { + // These are defined in headless.cpp, and aren't exposed in solvespace.h. + extern std::vector fontFiles; +} +} + + +#ifdef TEST_BUILD_ON_WINDOWS +static const char *VALID_BUILD_PATH_SEPS = "/\\"; +static char BUILD_PATH_SEP = '\\'; +#else +static const char *VALID_BUILD_PATH_SEPS = "/"; +static char BUILD_PATH_SEP = '/'; +#endif + +static std::string BuildRoot() { + static std::string rootDir; + if(!rootDir.empty()) return rootDir; + + rootDir = __FILE__; + rootDir.erase(rootDir.find_last_of(VALID_BUILD_PATH_SEPS) + 1); + return rootDir; +} + +static Platform::Path HostRoot() { + static Platform::Path rootDir; + if(!rootDir.IsEmpty()) return rootDir; + + // No especially good way to do this, so let's assume somewhere up from + // the current directory there's our repository, with CMakeLists.txt, and + // pivot from there. + rootDir = Platform::Path::CurrentDirectory(); + + // We're never more than four levels deep. + for(size_t i = 0; i < 4; i++) { + FILE *f = OpenFile(rootDir.Join("CMakeLists.txt"), "r"); + if(f) { + fclose(f); + rootDir = rootDir.Join("test"); + return rootDir; + } + rootDir = rootDir.Parent(); + } + + ssassert(false, "Couldn't locate repository root"); +} + +enum class Color { + Red, + Green, + DarkGreen +}; + +static std::string Colorize(Color color, std::string input) { +#if !defined(WIN32) + if(isatty(fileno(stdout))) { + switch(color) { + case Color::Red: + return "\e[1;31m" + input + "\e[0m"; + case Color::Green: + return "\e[1;32m" + input + "\e[0m"; + case Color::DarkGreen: + return "\e[36m" + input + "\e[0m"; + } + } +#endif + return input; +} + +// Normalizes a savefile. Different platforms have slightly different floating-point +// behavior, so if we want to compare savefiles byte-by-byte, we need to do something +// to get rid of irrelevant differences in LSB. +static std::string PrepareSavefile(std::string data) { + // Round everything to 2**30 ~ 1e9 + const double precision = pow(2, 30); + + size_t lineBegin = 0; + while(lineBegin < data.length()) { + size_t nextLineBegin = data.find('\n', lineBegin); + if(nextLineBegin == std::string::npos) { + nextLineBegin = data.length(); + } else { + nextLineBegin++; + } + + size_t eqPos = data.find('=', lineBegin); + if(eqPos < nextLineBegin) { + std::string key = data.substr(lineBegin, eqPos - lineBegin), + value = data.substr(eqPos + 1, nextLineBegin - eqPos - 2); + + for(int i = 0; SolveSpaceUI::SAVED[i].type != 0; i++) { + if(SolveSpaceUI::SAVED[i].fmt != 'f') continue; + if(SolveSpaceUI::SAVED[i].desc != key) continue; + double f = strtod(value.c_str(), NULL); + f = round(f * precision) / precision; + std::string newValue = ssprintf("%.20f", f); + ssassert(value.size() == newValue.size(), "Expected no change in value length"); + std::copy(newValue.begin(), newValue.end(), + data.begin() + eqPos + 1); + } + + if(key == "Group.impFile") { + data.erase(lineBegin, nextLineBegin - lineBegin); + nextLineBegin = lineBegin; + } + } + + size_t spPos = data.find(' ', lineBegin); + if(spPos < nextLineBegin) { + std::string cmd = data.substr(lineBegin, spPos - lineBegin); + if(!cmd.empty()) { + if(cmd == "Surface" || cmd == "SCtrl" || cmd == "TrimBy" || + cmd == "Curve" || cmd == "CCtrl" || cmd == "CurvePt") { + data.erase(lineBegin, nextLineBegin - lineBegin); + nextLineBegin = lineBegin; + } + } + } + + lineBegin = nextLineBegin; + } + return data; +} + +bool Test::Helper::RecordCheck(bool success) { + checkCount++; + if(!success) failCount++; + return success; +} + +void Test::Helper::PrintFailure(const char *file, int line, std::string msg) { + std::string shortFile = file; + shortFile.erase(0, BuildRoot().size()); + fprintf(stderr, "test%c%s:%d: FAILED: %s\n", + BUILD_PATH_SEP, shortFile.c_str(), line, msg.c_str()); +} + +Platform::Path Test::Helper::GetAssetPath(std::string testFile, std::string assetName, + std::string mangle) { + if(!mangle.empty()) { + assetName.insert(assetName.rfind('.'), "." + mangle); + } + testFile.erase(0, BuildRoot().size()); + testFile.erase(testFile.find_last_of(VALID_BUILD_PATH_SEPS) + 1); + return HostRoot().Join(Platform::Path::FromPortable(testFile + assetName)); +} + +bool Test::Helper::CheckBool(const char *file, int line, const char *expr, bool value, + bool reference) { + if(!RecordCheck(value == reference)) { + std::string msg = ssprintf("(%s) = %s ≠ %s", expr, + value ? "true" : "false", + reference ? "true" : "false"); + PrintFailure(file, line, msg); + return false; + } else { + return true; + } +} + +bool Test::Helper::CheckEqualString(const char *file, int line, const char *valueExpr, + const std::string &value, const std::string &reference) { + if(!RecordCheck(value == reference)) { + std::string msg = ssprintf("(%s) = \"%s\" ≠ \"%s\"", valueExpr, + value.c_str(), reference.c_str()); + PrintFailure(file, line, msg); + return false; + } else { + return true; + } +} + +bool Test::Helper::CheckEqualEpsilon(const char *file, int line, const char *valueExpr, + double value, double reference) { + bool result = fabs(value - reference) < LENGTH_EPS; + if(!RecordCheck(result)) { + std::string msg = ssprintf("(%s) = %.4g ≉ %.4g", valueExpr, + value, reference); + PrintFailure(file, line, msg); + return false; + } else { + return true; + } +} + +bool Test::Helper::CheckLoad(const char *file, int line, const char *fixture) { + Platform::Path fixturePath = GetAssetPath(file, fixture); + + FILE *f = OpenFile(fixturePath, "rb"); + bool fixtureExists = (f != NULL); + if(f) fclose(f); + + bool result = fixtureExists && SS.LoadFromFile(fixturePath); + if(!RecordCheck(result)) { + PrintFailure(file, line, + ssprintf("loading file '%s'", fixturePath.raw.c_str())); + return false; + } else { + SS.AfterNewFile(); + SS.GW.offset = {}; + SS.GW.scale = 10.0; + return true; + } +} + +bool Test::Helper::CheckSave(const char *file, int line, const char *reference) { + Platform::Path refPath = GetAssetPath(file, reference), + outPath = GetAssetPath(file, reference, "out"); + if(!RecordCheck(SS.SaveToFile(outPath))) { + PrintFailure(file, line, + ssprintf("saving file '%s'", refPath.raw.c_str())); + return false; + } else { + std::string refData, outData; + ReadFile(refPath, &refData); + ReadFile(outPath, &outData); + if(!RecordCheck(PrepareSavefile(refData) == PrepareSavefile(outData))) { + PrintFailure(file, line, "savefile doesn't match reference"); + return false; + } + + RemoveFile(outPath); + return true; + } +} + +bool Test::Helper::CheckRender(const char *file, int line, const char *reference) { + // First, render to a framebuffer. + Camera camera = {}; + camera.pixelRatio = 1; + camera.gridFit = true; + camera.width = 600; + camera.height = 600; + camera.projUp = SS.GW.projUp; + camera.projRight = SS.GW.projRight; + camera.scale = SS.GW.scale; + + CairoPixmapRenderer pixmapCanvas; + pixmapCanvas.SetLighting(SS.GW.GetLighting()); + pixmapCanvas.SetCamera(camera); + pixmapCanvas.Init(); + + pixmapCanvas.StartFrame(); + SS.GW.Draw(&pixmapCanvas); + pixmapCanvas.FlushFrame(); + pixmapCanvas.FinishFrame(); + std::shared_ptr frame = pixmapCanvas.ReadFrame(); + + pixmapCanvas.Clear(); + + // Now, diff framebuffer against reference render. + Platform::Path refPath = GetAssetPath(file, reference), + outPath = GetAssetPath(file, reference, "out"), + diffPath = GetAssetPath(file, reference, "diff"); + + std::shared_ptr refPixmap = Pixmap::ReadPng(refPath, /*flip=*/true); + if(!RecordCheck(refPixmap && refPixmap->Equals(*frame))) { + frame->WritePng(outPath, /*flip=*/true); + + if(!refPixmap) { + PrintFailure(file, line, "reference render not present"); + return false; + } + + ssassert(refPixmap->format == frame->format, "Expected buffer formats to match"); + if(refPixmap->width != frame->width || + refPixmap->height != frame->height) { + PrintFailure(file, line, "render doesn't match reference; dimensions differ"); + } else { + std::shared_ptr diffPixmap = + Pixmap::Create(refPixmap->format, refPixmap->width, refPixmap->height); + + int diffPixelCount = 0; + for(size_t j = 0; j < refPixmap->height; j++) { + for(size_t i = 0; i < refPixmap->width; i++) { + if(!refPixmap->GetPixel(i, j).Equals(frame->GetPixel(i, j))) { + diffPixelCount++; + diffPixmap->SetPixel(i, j, RgbaColor::From(255, 0, 0, 255)); + } + } + } + + diffPixmap->WritePng(diffPath, /*flip=*/true); + std::string message = + ssprintf("render doesn't match reference; %d (%.2f%%) pixels differ", + diffPixelCount, + 100.0 * diffPixelCount / (refPixmap->width * refPixmap->height)); + PrintFailure(file, line, message); + } + return false; + } else { + RemoveFile(outPath); + RemoveFile(diffPath); + return true; + } +} + +bool Test::Helper::CheckRenderXY(const char *file, int line, const char *fixture) { + SS.GW.projRight = Vector::From(1, 0, 0); + SS.GW.projUp = Vector::From(0, 1, 0); + return CheckRender(file, line, fixture); +} + +bool Test::Helper::CheckRenderIso(const char *file, int line, const char *fixture) { + SS.GW.projRight = Vector::From(0.707, 0.000, -0.707); + SS.GW.projUp = Vector::From(-0.408, 0.816, -0.408); + return CheckRender(file, line, fixture); +} + +// Avoid global constructors; using a global static vector instead of a local one +// breaks MinGW for some obscure reason. +static std::vector *testCasesPtr; +int Test::Case::Register(Test::Case testCase) { + static std::vector testCases; + testCases.push_back(testCase); + testCasesPtr = &testCases; + return 0; +} + +int main(int argc, char **argv) { + std::vector args = Platform::InitCli(argc, argv); + + std::regex filter(".*"); + if(args.size() == 1) { + } else if(args.size() == 2) { + filter = args[1]; + } else { + fprintf(stderr, "Usage: %s [test filter regex]\n", args[0].c_str()); + return 1; + } + + Platform::fontFiles.push_back(HostRoot().Join("Gentium-R.ttf")); + + // Wreck order dependencies between tests! + std::random_shuffle(testCasesPtr->begin(), testCasesPtr->end()); + + auto testStartTime = std::chrono::steady_clock::now(); + size_t ranTally = 0, skippedTally = 0, checkTally = 0, failTally = 0; + for(Test::Case &testCase : *testCasesPtr) { + std::string testCaseName = testCase.fileName; + testCaseName.erase(0, BuildRoot().size()); + testCaseName.erase(testCaseName.find_last_of(VALID_BUILD_PATH_SEPS)); + testCaseName += BUILD_PATH_SEP + testCase.caseName; + + std::smatch filterMatch; + if(!std::regex_search(testCaseName, filterMatch, filter)) { + skippedTally += 1; + continue; + } + + SS.Init(); + SS.showToolbar = false; + SS.checkClosedContour = false; + + Test::Helper helper = {}; + testCase.fn(&helper); + + SK.Clear(); + SS.Clear(); + + ranTally += 1; + checkTally += helper.checkCount; + failTally += helper.failCount; + if(helper.checkCount == 0) { + fprintf(stderr, " %s test %s (empty)\n", + Colorize(Color::Red, "??").c_str(), + Colorize(Color::DarkGreen, testCaseName).c_str()); + } else if(helper.failCount > 0) { + fprintf(stderr, " %s test %s\n", + Colorize(Color::Red, "NG").c_str(), + Colorize(Color::DarkGreen, testCaseName).c_str()); + } else { + fprintf(stderr, " %s test %s\n", + Colorize(Color::Green, "OK").c_str(), + Colorize(Color::DarkGreen, testCaseName).c_str()); + } + } + + auto testEndTime = std::chrono::steady_clock::now(); + std::chrono::duration testTime = testEndTime - testStartTime; + + if(failTally > 0) { + fprintf(stderr, "Failure! %u checks failed\n", + (unsigned)failTally); + } else { + fprintf(stderr, "Success! %u test cases (%u skipped), %u checks, %.3fs\n", + (unsigned)ranTally, (unsigned)skippedTally, + (unsigned)checkTally, testTime.count()); + } + + // At last, try to reset all caches we or our dependencies have, to make SNR + // of memory checking tools like valgrind higher. + cairo_debug_reset_static_data(); + + return (failTally > 0); +} diff --git a/test/harness.h b/test/harness.h new file mode 100644 index 0000000..fa95900 --- /dev/null +++ b/test/harness.h @@ -0,0 +1,75 @@ +//----------------------------------------------------------------------------- +// Our harness for running test cases, and reusable checks. +// +// Copyright 2016 whitequark +//----------------------------------------------------------------------------- +#include "solvespace.h" + +// Hack... we should rename the ones in ui.h instead. +#undef CHECK_TRUE +#undef CHECK_FALSE + +namespace SolveSpace { +namespace Test { + +class Helper { +public: + size_t checkCount; + size_t failCount; + + bool RecordCheck(bool success); + void PrintFailure(const char *file, int line, std::string msg); + Platform::Path GetAssetPath(std::string testFile, std::string assetName, + std::string mangle = ""); + + bool CheckBool(const char *file, int line, const char *expr, + bool value, bool reference); + bool CheckEqualString(const char *file, int line, const char *valueExpr, + const std::string &value, const std::string &reference); + bool CheckEqualEpsilon(const char *file, int line, const char *valueExpr, + double value, double reference); + bool CheckLoad(const char *file, int line, const char *fixture); + bool CheckSave(const char *file, int line, const char *reference); + bool CheckRender(const char *file, int line, const char *fixture); + bool CheckRenderXY(const char *file, int line, const char *fixture); + bool CheckRenderIso(const char *file, int line, const char *fixture); +}; + +class Case { +public: + std::string fileName; + std::string caseName; + std::function fn; + + static int Register(Case testCase); +}; + +} +} + +using namespace SolveSpace; + +#define TEST_CASE(name) \ + static void Test_##name(Test::Helper *); \ + static Test::Case TestCase_##name = { __FILE__, #name, Test_##name }; \ + static int TestReg_##name = Test::Case::Register(TestCase_##name); \ + static void Test_##name(Test::Helper *helper) // { ... } + +#define CHECK_TRUE(cond) \ + do { if(!helper->CheckBool(__FILE__, __LINE__, #cond, cond, true)) return; } while(0) +#define CHECK_FALSE(cond) \ + do { if(!helper->CheckBool(__FILE__, __LINE__, #cond, cond, false)) return; } while(0) +#define CHECK_EQ_STR(value, reference) \ + do { if(!helper->CheckEqualString(__FILE__, __LINE__, \ + #value, value, reference)) return; } while(0) +#define CHECK_EQ_EPS(value, reference) \ + do { if(!helper->CheckEqualEpsilon(__FILE__, __LINE__, \ + #value, value, reference)) return; } while(0) +#define CHECK_LOAD(fixture) \ + do { if(!helper->CheckLoad(__FILE__, __LINE__, fixture)) return; } while(0) +#define CHECK_SAVE(fixture) \ + do { if(!helper->CheckSave(__FILE__, __LINE__, fixture)) return; } while(0) +#define CHECK_RENDER(reference) \ + do { if(!helper->CheckRenderXY(__FILE__, __LINE__, reference)) return; } while(0) +#define CHECK_RENDER_ISO(reference) \ + do { if(!helper->CheckRenderIso(__FILE__, __LINE__, reference)) return; } while(0) diff --git a/test/request/arc_of_circle/normal.png b/test/request/arc_of_circle/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..2839007cc95fc697f1a43d21aae85094b3dc6524 GIT binary patch literal 4560 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 U!C812`=tiBIC<>gY=`6i1zXKwMF0Q* literal 0 HcmV?d00001 diff --git a/test/request/arc_of_circle/normal.slvs b/test/request/arc_of_circle/normal.slvs new file mode 100644 index 0000000..aaa6b8f --- /dev/null +++ b/test/request/arc_of_circle/normal.slvs @@ -0,0 +1,306 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040016 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040017 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=500 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=14000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.normal.v=00040020 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/arc_of_circle/normal_v20.slvs b/test/request/arc_of_circle/normal_v20.slvs new file mode 100644 index 0000000..78d983b --- /dev/null +++ b/test/request/arc_of_circle/normal_v20.slvs @@ -0,0 +1,306 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040016 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040017 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=500 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=14000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.normal.v=00040020 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/arc_of_circle/normal_v22.slvs b/test/request/arc_of_circle/normal_v22.slvs new file mode 100644 index 0000000..6f92e0e --- /dev/null +++ b/test/request/arc_of_circle/normal_v22.slvs @@ -0,0 +1,306 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040016 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040017 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=500 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=14000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.normal.v=00040020 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/arc_of_circle/test.cpp b/test/request/arc_of_circle/test.cpp new file mode 100644 index 0000000..5e9db1b --- /dev/null +++ b/test/request/arc_of_circle/test.cpp @@ -0,0 +1,17 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} diff --git a/test/request/circle/free_in_3d.png b/test/request/circle/free_in_3d.png new file mode 100644 index 0000000000000000000000000000000000000000..31e2499f9dd2402663bfd7a77611b323bf906d42 GIT binary patch literal 4796 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 literal 0 HcmV?d00001 diff --git a/test/request/circle/free_in_3d.slvs b/test/request/circle/free_in_3d.slvs new file mode 100644 index 0000000..41287aa --- /dev/null +++ b/test/request/circle/free_in_3d.slvs @@ -0,0 +1,294 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00040021 +AddParam + +Param.h.v.=00040022 +AddParam + +Param.h.v.=00040023 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/circle/free_in_3d_dof.png b/test/request/circle/free_in_3d_dof.png new file mode 100644 index 0000000000000000000000000000000000000000..2b5dff0e5ea948effb9fce02f99a9f59e235c707 GIT binary patch literal 7195 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 LW`_Ct* literal 0 HcmV?d00001 diff --git a/test/request/circle/free_in_3d_v20.slvs b/test/request/circle/free_in_3d_v20.slvs new file mode 100644 index 0000000..6966f95 --- /dev/null +++ b/test/request/circle/free_in_3d_v20.slvs @@ -0,0 +1,292 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00040021 +AddParam + +Param.h.v.=00040022 +AddParam + +Param.h.v.=00040023 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/circle/free_in_3d_v22.slvs b/test/request/circle/free_in_3d_v22.slvs new file mode 100644 index 0000000..ff35698 --- /dev/null +++ b/test/request/circle/free_in_3d_v22.slvs @@ -0,0 +1,294 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00040021 +AddParam + +Param.h.v.=00040022 +AddParam + +Param.h.v.=00040023 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/circle/normal.png b/test/request/circle/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..31e2499f9dd2402663bfd7a77611b323bf906d42 GIT binary patch literal 4796 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 literal 0 HcmV?d00001 diff --git a/test/request/circle/normal.slvs b/test/request/circle/normal.slvs new file mode 100644 index 0000000..1ea104f --- /dev/null +++ b/test/request/circle/normal.slvs @@ -0,0 +1,283 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/circle/normal_dof.png b/test/request/circle/normal_dof.png new file mode 100644 index 0000000000000000000000000000000000000000..0e62eba3dbcd8923d76338faf33196ccbd7ecc55 GIT binary patch literal 4830 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 literal 0 HcmV?d00001 diff --git a/test/request/circle/normal_v20.slvs b/test/request/circle/normal_v20.slvs new file mode 100644 index 0000000..cdd2810 --- /dev/null +++ b/test/request/circle/normal_v20.slvs @@ -0,0 +1,283 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/circle/normal_v22.slvs b/test/request/circle/normal_v22.slvs new file mode 100644 index 0000000..d245f28 --- /dev/null +++ b/test/request/circle/normal_v22.slvs @@ -0,0 +1,283 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040040 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=400 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=13000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.distance.v=00040040 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040040 +Entity.type=4000 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actDistance=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/circle/test.cpp b/test/request/circle/test.cpp new file mode 100644 index 0000000..82cd878 --- /dev/null +++ b/test/request/circle/test.cpp @@ -0,0 +1,45 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(free_in_3d_roundtrip) { + CHECK_LOAD("free_in_3d.slvs"); + CHECK_RENDER("free_in_3d.png"); + CHECK_SAVE("free_in_3d.slvs"); +} + +TEST_CASE(free_in_3d_migrate_from_v20) { + CHECK_LOAD("free_in_3d_v20.slvs"); + CHECK_SAVE("free_in_3d.slvs"); +} + +TEST_CASE(free_in_3d_migrate_from_v22) { + CHECK_LOAD("free_in_3d_v22.slvs"); + CHECK_SAVE("free_in_3d.slvs"); +} + +TEST_CASE(normal_dof) { + CHECK_LOAD("normal.slvs"); + SS.GenerateAll(SolveSpaceUI::Generate::ALL, /*andFindFree=*/true); + CHECK_RENDER("normal_dof.png"); +} + +TEST_CASE(free_in_3d_dof) { + CHECK_LOAD("free_in_3d.slvs"); + SS.GenerateAll(SolveSpaceUI::Generate::ALL, /*andFindFree=*/true); + CHECK_RENDER_ISO("free_in_3d_dof.png"); +} diff --git a/test/request/cubic/normal.png b/test/request/cubic/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..e7eb94d81a78bb0ccc1e5238b2b7fe99fb678396 GIT binary patch literal 4949 zcmcIo3piAH8~@K?#7v50h@|vY-?zqXV<{$5vTazq!nhwRDI?n4?=#X3o3@Lj#Mf@* zK9Wlsj8wyt(Z-nEH}+wR?B(+#hyrwEM`h&OIF`pFFx4s_*nYrew>- z%P;%}U%op!z2f17#IODnI}Mw2e%N&OK<3_u+?&~Z5BV0Ps{o)U$aM#Ren=7r%u?wP zkXAtc!4txQ^;R$n#LM6TS(kzaa+|3D-2ZCk7N1dAw)T=NC=P?3nT08tj{X|i?oc?=wqgW}0#{0&Nz6Bu~7McBIk$ zRnma`bLv8Lnd+0SRS?-;+)6B3Y9;+m2noQpn?*@ec6@U7$`Xz*?jL?JzD*NE*l}qa z#JcLLGbww>0)V6kqUh#Q2Zj_uzJ{2Uc(iTklyVmdaQw^Kh2EuCB!o0A;rQZaZb|me zaYwaWy)hsw*5d3|XJdOE2*CdkMaN;7I2Hj|QOrslE&1A1TDJ;Nz9=IC(j)sjUW8Y1P?Xgi|T0rxeh9p=bJx$&!%<@9cW4+BpvnvTXzyDJIWgGOpByQrn$c|j&j9FUNr0EIVgd2pN zK212$RvKwnKq!#sB+{X;+B$Jv`qmzsoeBAC*yWZ`Sj2ChdRPLTlBHS#$YNrKy_PTbD@Xy%8AqJmn3MT(w@PIdvOy?L#`gC*uFG6+$>zXt8K6wf{KcrQwHgY%a=(pV@D!DM#xqF}(RVah++hCU$ zjGW#Jqe9P|Y!9Q6w-(hx{;RM>lWF+Arb}HE9X}Z;Dg*g#!GpG`D?gwLkedSBT#bSd zs-h;;Lz1{Yo`b5K(@{SNyTZox2*V4*uva3cC-FTGJRjO>RooY5MeWOc(B{MbBHn8i z@u=DJp%Rm3+gpbiO~F)ne~rIj;Azc6`%6y;TeE8XO~zuQVzlUGlDM@^-1ZkbT*$Bv zqnx5;{=TBzenHB|gfOXXu6!vJGuGJFURPQV`yrr3$16tFe?R$3nS!>hPi~>;$>7Nv zSwvlJ?1oRqDABl09>}#LjMfv*{uICu2=*r+or^BPZJ0WZ}C&OZzRGN8`T-F zi=&{a8_Q%omkTdi6~k+TDF#gMY$?D#FN32uvp2`jBjZvu8DLA=3hblxR1i}C)dsHh z0#L~5#n#euA_9Z65expN1(?!Tgsb7+oAo=VoPUa07zk7^cg~9FRYHmlrr6)vf&o+m z1w1+Zjg2|y@*=W@2WS`M_!~c_Ns)(~6C}@_83-eo&*!@Xsw#wC|H5Zh&B+`a^6Mc6 z!T^$UegdpkUxg%&E@f5H$CkuV18TJW%VVm%Oa=4V^>O|32>9mPdhaFclrKMlTYHKQ zO@pU+qm-Odhe^BLHM6<%-VN%4XL`cH9Xs3ap&se(?7~VPXF87UD$XFStE(Aj4hBU; z5%NPbzU`e$Gpg>N3V9bdaI%9w#A%TG=dl^*JnwlmSD)CZD1+W(*WKr$rkw;_eJXi2 zA)=qbU`ih~i!E!f!w3WC>rEN*VnTh<@vBEuWbknB_D(6<0beu&$>x2l0&w{-kY43z zM!GbvA*tNt;1btkAw7qTcjGP8Ow%%HRLDrs8-gzP>%XNh_O{E1$n&jemdRyAB*FU- zh?_=vNd=k1sF90_N#Qy-vfAVdbIt`(MT}pd$65>*Q7+vkoMOz~2czbQ!uGBD zS458-;!HncW-2lZsUI%N46q|T#;d?vnmdm}SpLBUbpk>jaWVWYNF&|9x6E^`XbO*< z9^I*YoDLz4d0g0-?*&@O{kQ9re$l4Bx;xSeB7caKd*l^|=6dx7G+7nFcnF($Zcx!L zpQHL=93(tj7ynusK}Oj!PuGRZNrRR=i2T#Lh>2p;9c7s2!s>O|u^IDIz0m~N2r;2^ zFE=PAHQ_e=sTM!Q$wEZ7rI*iV*krS83TwEB2O7T&>-s}Ei{Ao z-D|c+yu@~a#kgfD@Y@B~?mUyv)UApW@&v3wa(Rw9yAQ6dJ%cBk=p0+-O!AOueDHGC zsz}(N6DM@1cO-9s6XmAwr~EN>S~Jstg6>*>yJuq|xulYwHgMZcg6Xy=r3DK6Nd|Yc zUEg{(?cnIN>ei>4edp=W^$z<3qvtB()HL~z5CG({zoc2aqROT5aB26EH8=%FIsw9l zT{)am0j*OY(p}DOe_WaL&5!6VgpdQa{jT4btN^k2$h63eE!QC30c&_Ms7^VeS<~r% zd;6kkb+`?3p=&e<0cr`FeQtK7f>&1puDiIToVSz62vl<<#3xXp>PFlKYR+(|%2@cY zEfMuE;h?bWJlUpKl3fbCtjBt+ZWST%gWwVR61gg=%(r=g=EZr z9nkl04<$jh>l{CMWf2w<2{S$20spbmV*Li2R^JRsZkO|U%cmzMM?hn&JUTP zSESs0ap%vx3Js|_r6IZQl7Rm82YI;U(uZstldd7YfUG6jdotBG_tNtgFA&D=FtWrT zntd#c(w0^afv2T;Jp37NI5Wez0o&~*UD z&I%;}MfkChrw5klpX(bjgYwcx2?E9}A9x1!1klg&)({J1Rh_a!?(7?upoj5g^I0c< z%4fwR%8!!~3hzQZjz<2u&VtoiJ)gQ8@oH|+lMsYhONG6wm+>{UCUP)H-6=xLPaJ8Ga89bVrqX@Wr;n8!#qcuF5Bs>QA z_KenO4(Ob$fXFdwQ`?EgRp;OFk{KxN5iV1UUfM6kBAc#P0qj%#QVt{yEMPw;_ohkn2FR+(g4UHW3Cm*C(ldnwtQ z*DepVM>MId%JTHk;Tl2*|EiCjCg+T4k=Yjh@_b8w0;)FwuaImKJA*PK6%5cT&t@4s zy)}Gmm1K)juQE!A2{vP8Wc7-hF6#G`c9F_ww2zNma5+A{ySso#Fm8Ss9r<<}b4OW7 zdV67ebU@?V^#1C|Yo*DZC0>bvz&)tr@saE50)Ef9(`0zj+Q7Wo$&tWy-IonArZ`bW zF(c`W!;jl_e(VYrc+51bw8x}(l~sjzb$4~SS0RrUxc4lK(kw4j4mX?|Z14$xhYI`7 z4OaW3bTvuGJtCd~ffc`wx5I8WxVI4vCmQQ3%c~n_kA52*-)$@iRi7+4J3BIM&p`Fb zy_F|UX&f$k!p$8fN33?98Vlt0Q`=_BX&$5=Jk^2MztYT+A1%u&XnzCUWpU-$z@M=%qjg*a-`}3??N+Urn$JV{r67& z(Pz;$yx@wdimESOPfOVTGI5u0+kW$C>~>nXUw5;iK&RsF-QZ)Y0g2Ra9&(oh_RS8h z`#wA0q!;(3v7bGk&Y6ta!dlz=+HyzC^Kh>h42JMIO|P*(yEP{HHe9pkuIn;z>it?z nllpr=exRt&;<5kP=&eU4D~QwXs-Z}#qBdR_&FeX`1R3?1Kh@_y7bGgveM6P z$Ni9r|IT&4QhUO+_#&FHz_uZucy8uR^xf8r*H88zHI+0a4>tgCZq{THnylKGBmjOD z!vYG93I_-b9e_tdD4bvDuS zwk^v$)O1sDvK2}wQfc9^xKOI)o1|r zn0<4ZU4*8At)SWH3I$OPiY?Bo6#me_TMe8a-}KfU@t(hnYwYMy}QW{Q6Ju z#>Km5wZTZ+jpij+MBe-t5r4!}2(ZllA0Y3s^?wr}iQJYyoL>yKv=scFy|%Buf1+jN zgiT^?A}H-)3`l|}Q*N@GHZhE{1@aIC){$sJzwTj=*HvZH<tM8Na5W`#Ah!ax`_Xqj4|Lk}$uRLd_j*|)*B#g#(fGZj3QBU~)!4Mn)h470 z;GsxS4C(#bRmurTsJ+3H%9YBl!W5IxF!5c=839qfk`ru`Zha~g6?>R{A6x#ake=IU zTl+gNbz8e`IfXN}n=rbeNy=9x<`%oRzR71qqmw#~B#av0jM<-LnKK^l5T^Jv6K`~) zfpcplWiE2nwD~5O4TgaDCGa;H%ZcaC;%ywGkTzR5lD%-`Lh9m?aLbPgM{Veb9(__Z4*gt5*3W6c(fegWHuU!Sr5TyyV4D2eJp}y4w2@AUl zG}H&R4%k)LL46tG*{8SKYWX0nahoqxN|@0VE*3@SPX6J`yDz*9?Muw>?hT2!XM~Zom+Wx2Q+*0J{V4r z3TM@tmG)m?-NgGPf;e+ho#b5+s&(_(S|s#n)Qs7Go^?~z?;@zau14qPpK1hv=Nw@q zZ-=jtc$d)zhD`gSSTNDqx-jF!+KBk&l^f`_INpGxlUT3-!TM~@xQWJuAv7`GBzJCn z$ZxnEKh;&vm$mWIfr%?r={=br>>9U>+9M8a4}lQMNfesxd7B*G{rsIfd)s`Q##VkA zJKQj#)pPbrH{boGExGk2-~V0tHs)l4$;jRtdPK6`lund|o(tZF*{u{f>j@n(Zf)D0 z?Uh<@Xy(`V|GgHQi!bN8+1lE2rq-2*hmalKYL(4-kCz0T2^9;sY*?3%#8M(>(#2G@ zWvK8tCq>TzcQ<%tOidz`;iC^ZM|$rHh?G2JHLQv^B?@n`SOxilXItZ#~6q!!37R3g2%5DJl2dAOIboADF*(~C8$zc2=&@06LI2zojQtIi5NO45bzu#MJtlJtR+?( zQ?F{gk**MBdB)4EGiK>;D)&2Rf6ArX5XtdBOH`>6wS~(EXNZVHiw zOZ&3_99AK+{fLW|e~gzs+v>%u#N*!25xX|$(o)EDTH@1)-6?4@vewo6N$UCIPi2Tm z-0b?)!JL^wNH(&L1@+>8xd7Lyas2z7YJ3MotzDCS za&JIQf7)ixa^Px4zaGfJ{)9L(Dv!i!cL4#8&ATptks3&3lN?&D?h~nSe2SwJ%%p3r z5k!d*DNJ)}h~f$KDQ%diD~#iP0dH44W+h=dKY1)bWW9^;Z0DP#UIt?e)jpAXHR;W0 z#5IwP3V-HDXZLF8Sda|P)gCiUWsI(eiMO$~Q&OY11n5!Wo|u9@YDNS{hA?VyEY@Po zE|Lfnj|rLnQCccO=kd7MoC^IqQtCII=RU%7o9NdqrBahiCZ80fB5ReX@JKI;ZhUZ> zOh>QeV%B^{@)EVhK_{T2M{kWDv#M$)uDgvh^0rqkmn5-!i-_>)Vg2ARFTa?3+k$U4 zafEx`JWf5T(sV~L_>TQ!Gv=e6?C^Rc4a=N>s{Z=zj1^2Hj)Z;oEKisjPpE)QLfY?=vVtUp(;K2 zb4|8M(!Z&ERm#(v-ox~BYXdRBF21idpxmRa5TD<$JdnQpL~ZY-KgF9CBABqH#Z&ZK z8ubfX^0C;TWGB%7Hv;oBH)bVI7$g?B0gAuIvQc1Zn=z>-a$ow16((nekHh7;tJ>tO z@N%b4=A>lqfB_QbqlEuQdzZC*v;h|WgVH9UKeEiXJi{06@$0qtZ-W2xWH!RN#fdp< zK}X65U5=Bw-Laz&nugG4}z5vC9R5TIq#PBR&>tyrtk`x%rOjLE?%f30X?B7DnJJm= zjts8Lb19S6IrHAUmoQ7C# z?!`}uEqO|pzP}GhI$a`GR+N>+);hq9&iaY3-1l9E@Pq)RXhM#VguKPW>}OyO1Sj2_9^@t3@gK1FyYKCGvRU*IqG*P~xeo0qH6>I0 z*SjVexp%B^GUa(JQ zdV+K?Q{pz+ab7KIDzyhMecvK=Z3t!{*S)>0JGq?^-0s682Q$Y1>h=rwe?E1kdv{54 zSwd^s@mL?Q-glsl z>!#l&ziJB}FDxl4(hX8=@r(&2{HkMd=M+e;@z6W{>- zw7H3tVu1<@WuF;;I_EK8!+Y$XxpAmuvV4wKPA-~Gbj(KssT&EbIkk&H=kJ)<3peD{ z&W-H0)|289`FLJasvfF2Yi>-0^nI5@b(h}HX1lL(zv{h&NCL(LELDU+P(rwxq$dbFn{B0RXLi~j{y68GIp>`@ z-}k=H`#jHkn7{M$&|kN49RNVzbMNl`03a!v3$q4((iqNq0)T;o=kA>clZwX0hhm4^ zO^$c9?A-dHcNA@3Zo#>2r=EM{6TWPz`(U9vpX|EUJUg#A%u^PgnSAcq)$&+0*wN1C zIst&+l!XQcmK*@?=$L>VEC>lO#_)#@A@zW{4;2A&b!`9x{}ToERoB^9NB7n#<-+_Y znJWK|h;(Vtz`UToQBkS>ZLDnzce+UUly)-pW~?(dFCzb%^oyX}|G2s4uBq@W2r8`F zq;&|+Rn_ZuEC9QF-g??0icq#0j9DxPP(rC26ew`kuIWu$poT&jYn2J1VnqTTit6Ai z)Yr;h-+pqv%ol+6dpd7RF+PtzECnLZT{_;O1491P&7zEQv8FZfNppRnq&hu@_cF0)_|~k2 zU$4bJi)1W!)W=)LeG48o!*szC3gmwyd`Al!CgQ+sF1`f%o+Xlb$KsHKgk_Fck<=Av z0k^JrBN*Ikxm0$Rf6r!nEuvaM3)-VafqvG@EV&pMR6Z);=`w;d{CmA;EW!KsOO&~y zlED0087(S9fV{)mXoJbysVL|O#)k3df_dYBU3z|hS!6j(N}2k&2`w0@Hwdl;&|;8! z&h`9>yqS#ju&rukX=}FBkODcYwn-9k0|R!y2&8R>BiFLRn`&*y^k^4(VrVZvW=?^t zJOYc0dR8$|#fv428s*B2=LCn;emOQn;Ua3A7w{j<>kGe-KpS6#VH|E{R`%AZbgTR` zm9w#p&*&+N$&m=eK40D|X-g-Dwv+EoX*!Rwp<<;;2jUJ`M+%PB!)iI4khzJ*DKKFL zHqmu$82AI$kjMe(Fs;8Tm*2)9EQcuQTW)iM!v2YV}1jRCMH z{Ahe=62>^nN<(!HPkTDV??0Ds>IrDxSv#gwiA&S!Mr7^LPyllrdL zN4US#!vEV%6C*h$sO<<^%UyYs#at%@z#IQ}-TDp;|F>Z1Qy`@R9s*DkgnAXfIgJL` z(Lxx0G;=KsYAEyHH7LEdUYwTxjkok8z+f)5-OBd6Vk<{bJN^g&k0mXEoP8RzBDMuP zt>EW55@^y^2%y{)RJ3Tf3BVVtf^seNfb#>mVe3eo^2hJH0?4q#5T*}f&F#=4U|+FA zaO2%vJwOdxmW{W~2z{)qXA!1IVC5K2okMg1hbYmtn&$dm#^7Cr3RrvPu6Mc<`a9kb|mnziw2TD`ig zA%k#lJvb@lPUO(L6VGHW3>{@`w^GLIy%f+<(RXkL`k?489d+I7Fan&onLs5oZGgGo zo5hRDGYSAZ{seJ_Qwj3``hCZGN}SbRobNfeOAh0~f0$^=zu>C&7kZ6fk>46qeT;;P zvx?Kt`1PnnG{C0Ia3XeR^3)C9LYj2E zk;MIM;XIws?T`$QcRl_)mSH9Ki?5Il^HneS{qp3_isVN_$x|+ui5G~MXZq(#lzsjs zrNmJFJ#MIyH(5-SDL;0}Bf3uf{KQZ{dxT4n+1}|-b1X~UzQK+-7f_N3N*szt~vff5w2FoR@@dK2903&;r4U~ zutx&oP@^>u=U)&KN$+_St6N)YhcBV0M>A9ivj;b;n^Gp|1QPMHr0F!(nKcY=GbfJQ zHtXe1+uv4~OkVo3`*? Y1<6ABkAArs{2Kvy?(y4QwTqhlPY<7wBme*a literal 0 HcmV?d00001 diff --git a/test/request/datum_point/normal.slvs b/test/request/datum_point/normal.slvs new file mode 100644 index 0000000..867c76b --- /dev/null +++ b/test/request/datum_point/normal.slvs @@ -0,0 +1,252 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/datum_point/normal_v20.slvs b/test/request/datum_point/normal_v20.slvs new file mode 100644 index 0000000..afec571 --- /dev/null +++ b/test/request/datum_point/normal_v20.slvs @@ -0,0 +1,250 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/datum_point/normal_v22.slvs b/test/request/datum_point/normal_v22.slvs new file mode 100644 index 0000000..50f8877 --- /dev/null +++ b/test/request/datum_point/normal_v22.slvs @@ -0,0 +1,252 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=101 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/datum_point/test.cpp b/test/request/datum_point/test.cpp new file mode 100644 index 0000000..5e9db1b --- /dev/null +++ b/test/request/datum_point/test.cpp @@ -0,0 +1,17 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} diff --git a/test/request/image/drawing.png b/test/request/image/drawing.png new file mode 100644 index 0000000000000000000000000000000000000000..56bedb7523f0a12bb142429e073d77ef8b58f8ac GIT binary patch literal 8565 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 literal 0 HcmV?d00001 diff --git a/test/request/image/linked.slvs b/test/request/image/linked.slvs new file mode 100644 index 0000000..4819058 --- /dev/null +++ b/test/request/image/linked.slvs @@ -0,0 +1,430 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000003 +Group.type=5300 +Group.order=2 +Group.name=normal +Group.activeWorkplane.v=00010000 +Group.color=00646464 +Group.skipFirst=0 +Group.meshCombine=2 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ + 1 00010000 0 + 2 00010001 0 + 3 00010020 0 + 4 00020000 0 + 5 00020001 0 + 6 00020020 0 + 7 00030000 0 + 8 00030001 0 + 9 00030020 0 + 10 00040000 0 + 11 00040001 0 + 12 00040002 0 + 13 00040003 0 + 14 00040004 0 + 15 00040020 0 + 16 80020000 0 + 17 80020001 0 + 18 80020002 0 +} +Group.impFileRel=normal.slvs +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=40000001 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=80030000 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030001 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=80030002 +AddParam + +Param.h.v.=80030003 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=80030004 +AddParam + +Param.h.v.=80030005 +AddParam + +Param.h.v.=80030006 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=0 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030002 +Entity.type=2011 +Entity.construction=1 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030003 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030005 +Entity.type=2011 +Entity.construction=1 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030006 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030005 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030008 +Entity.type=2011 +Entity.construction=1 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030009 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030008 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000a +Entity.type=16000 +Entity.construction=0 +Entity.file=drawing.png +Entity.point[0].v=8003000b +Entity.point[1].v=8003000c +Entity.point[2].v=8003000d +Entity.point[3].v=8003000e +Entity.normal.v=8003000f +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000b +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000c +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000d +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000e +Entity.type=2011 +Entity.construction=0 +Entity.actPoint.x=20.00000000000000000000 +Entity.actPoint.y=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=8003000f +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=8003000b +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030011 +Entity.type=3011 +Entity.construction=0 +Entity.point[0].v=80030012 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80030012 +Entity.type=2011 +Entity.construction=1 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=110 +Constraint.group.v=00000003 +Constraint.workplane.v=00010000 +Constraint.valP.v=40000001 +Constraint.entityA.v=80030006 +Constraint.entityB.v=00020020 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/request/image/normal.slvs b/test/request/image/normal.slvs new file mode 100644 index 0000000..dab1385 --- /dev/null +++ b/test/request/image/normal.slvs @@ -0,0 +1,319 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +AddParam + +Param.h.v.=00040011 +Param.val=10.00000000000000000000 +AddParam + +Param.h.v.=00040013 +AddParam + +Param.h.v.=00040014 +AddParam + +Param.h.v.=00040016 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=00040017 +AddParam + +Param.h.v.=00040019 +Param.val=15.00000000000000000000 +AddParam + +Param.h.v.=0004001a +Param.val=10.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=700 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +Request.file=drawing.png +Request.aspectRatio=1.50000000000000000000 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=16000 +Entity.construction=0 +Entity.file=drawing.png +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.point[3].v=00040004 +Entity.normal.v=00040020 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=15.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040004 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=15.00000000000000000000 +Entity.actPoint.y=10.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/image/test.cpp b/test/request/image/test.cpp new file mode 100644 index 0000000..da0954e --- /dev/null +++ b/test/request/image/test.cpp @@ -0,0 +1,14 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + // Can't render images through cairo for now. + // CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(linked_roundtrip) { + CHECK_LOAD("linked.slvs"); + // CHECK_RENDER("linked.png"); + CHECK_SAVE("linked.slvs"); +} diff --git a/test/request/line_segment/normal.png b/test/request/line_segment/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..a7b1c341a730deb665021f7bc262b0c9ddd0e48d GIT binary patch literal 4246 zcmeHLc~FyA0)K>?$RVtNngZ6!+A5NAugal9ks5Rr3E_@%%N3LW8jggex>^d0ju06m zV^J&+2q*y>Ncd0(umqw4Ndc2^XoExo%7zFS*+j)Dot4s=?H@biADK6k@6CMg{oe0- z-`T(K_te!{rvm`c_1f!x2mlyH`P0%+{KJYQKLWrY*voy_;k3&W{38j2XyenvcXp-N z1s{T(FLsqPs^5o)WWTJk=$?}Ro6<{z;ljs7#{tBxC za{( z<2JCQRf!qmtP6piwbjldyc1&7ta`oPnbH2zr;K6a4ZpWIVv-%x-vU`vCO*An6LIB2 zS6fX$G%)(mZXqWwouCPtv=%3DO)y`{0dx)Z4i+S>Y)9k@0Woc_$4>%N?;iY~CFs>3 z?yDjg0bu)O>xUrD4GV5c1vTHkUw#HDqE{cFeo}jP7SqQVVJkc;Vp3e7Opo}$F4%GD zx$g7jGaOX_(&!@`N}7L!V~OfN!ttlT;Tq7bgP5f0yUesVOk|s|%y6GuE}AUcYIh@f zuqDyAK@yzaT9TDAIpkB=QY5hg!VabI*=q1@k+X!gGLJsj%5guLrOVS&lOI)k-uQ@Z zYqtM)+pia2q-h47(>4Z3T72x^s@@xj(zD{qYlX)R8qXI9%TyZw@@mQA4K3rT;o4SC1#e8*V$4r&T}KofVt^*HD?8Q*1N|t+r#4H)M)Oi( z*14^XW+e68(a_Nh*>kzoo~!D-4K;v8iZKrAJmlL@XqzSVl@At%E<7k!CQyFpf^b# zzuRG-#8)q8Y+*t7IfiK5CK%kbeY>D{uve$po^PdG7+odyZ4o-^TAU9pV>yyw#00i#m8S(aIMu7N`LTwHUq2HWEcn ziw9DU0pi9>Z?hJQuoObKimTVJFsuQYS5Lo;{-Z(ttHOi{#a6`*maBlg@VAsECXv%s zImZ|Y@7u)hBsMl=kb68}iMD=LFjJutz`nbf{L5Cgk7Q7y_y0kL6eh&LCjvm`OJS8? zhpT`yj7SCj5PO$!P(hjhD$wAGc*jt)iH8h0z#d)n=4ETT7*55<@303@!8=7E^)4h1 z`FrzpmoRQ=@25J}q<7i_kjd{{>4SF(he+&f|2F_S``ubhrkfqW9Sze!_th2PD=V3F7r>5s z1XUC}+^onkZjO2AIth^!nhw)M_azt5dtI|o-*>=>&vVT&zC9l3z6H<1`!He>do{+l zWn-*OnLj|5v7q9(k>t;MwgS`6e2Fe%v{cRCEVE53LCTqef$p#?fjK62r#^#0R7(mr z139RC7{k=7SZ%Hff?BVU>`Uew4bcFX024n(Re>RRu^_??OCgu90l8jS%D9gH$0^H|EiDUU-J(hx)4UJH+4%_)4ScuLb<6^L+rsKU@6KpUz* z!T5d(2mdsBI~ZcD-Hn04r!^9LCdCCHi%zI>#o7-EM%VK#y$QUZ=bx8u;w<#j4-v-F zw>7oo0h}m^MCTD2rUi4U=KQ%pKc6k8XI*KKMcXQBeluPrbIVQC&KIwqXaZmR<5*^1 znRCw%yn~yxuv=fZYo(!k@S_OVXS4XtOlhs`X!K+}Yu;kMJMbSRXBiDMvS`YD`^?x0 zvy8Y&mrw$8QkKx48Oi5V-;$jq)YUs_4tX{7AjEUeX~Ox$nRJ0|teG^;ETh{qKY}C5 zNM=R3&Ri13aCp|WlBg_NdPF{r&^Y?E13y%-G+!PE7xy^L~0-Mjdb5P{^B57halEh?`WP#H*lGqx-sbF^MfwfnhOIog} z3>miRQf28;;m+q6oM%rirIw4nY|v7P#^nX(aOTDw22vM1UXIm=jL0v9aA$uCpvi0o z>?R(BWr@X8g6SFR-D!Qd{I*!>bwSbX(X~@kkG6;CwU{9E+AZ4C8?>5|Q5-<@8E1OD z+`N}%!yPo*;YlsoKIwO~YmQrTQhpa7_KT=pao2q<;_3#D%QnNiV+$L^V94gpC5`u6 i6IfA{|1T%KR_z%1g3@)6SE2ac0K7c*yI1eVX8#AbP?XXD literal 0 HcmV?d00001 diff --git a/test/request/line_segment/normal.slvs b/test/request/line_segment/normal.slvs new file mode 100644 index 0000000..4914fef --- /dev/null +++ b/test/request/line_segment/normal.slvs @@ -0,0 +1,278 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/line_segment/normal_v20.slvs b/test/request/line_segment/normal_v20.slvs new file mode 100644 index 0000000..fb26b9f --- /dev/null +++ b/test/request/line_segment/normal_v20.slvs @@ -0,0 +1,278 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/line_segment/normal_v22.slvs b/test/request/line_segment/normal_v22.slvs new file mode 100644 index 0000000..167a2c2 --- /dev/null +++ b/test/request/line_segment/normal_v22.slvs @@ -0,0 +1,278 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=200 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=11000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/line_segment/test.cpp b/test/request/line_segment/test.cpp new file mode 100644 index 0000000..5e9db1b --- /dev/null +++ b/test/request/line_segment/test.cpp @@ -0,0 +1,17 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} diff --git a/test/request/ttf_text/normal.png b/test/request/ttf_text/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..b023b8388bcb35bb4aed0b2fe7f0e9f88dc24cc0 GIT binary patch literal 6158 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 B@znqT literal 0 HcmV?d00001 diff --git a/test/request/ttf_text/normal.slvs b/test/request/ttf_text/normal.slvs new file mode 100644 index 0000000..229c63b --- /dev/null +++ b/test/request/ttf_text/normal.slvs @@ -0,0 +1,329 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040016 +Param.val=23.92131768269594616072 +AddParam + +Param.h.v.=00040017 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040019 +Param.val=23.92131768269594616072 +AddParam + +Param.h.v.=0004001a +Param.val=5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=600 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +Request.str=Text +Request.font=Gentium-R.ttf +Request.aspectRatio=2.89213176826959461607 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=15000 +Entity.construction=0 +Entity.str=Text +Entity.font=Gentium-R.ttf +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.point[2].v=00040003 +Entity.point[3].v=00040004 +Entity.normal.v=00040020 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040003 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=23.92131768269594616072 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040004 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=23.92131768269594616072 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/ttf_text/normal_v20.slvs b/test/request/ttf_text/normal_v20.slvs new file mode 100644 index 0000000..65bc54a --- /dev/null +++ b/test/request/ttf_text/normal_v20.slvs @@ -0,0 +1,290 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=-5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=600 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +Request.str=Text +Request.font=Gentium-R.ttf +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=15000 +Entity.construction=0 +Entity.str=Text +Entity.font=GOST.ttf +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.normal.v=00040020 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/ttf_text/normal_v22.slvs b/test/request/ttf_text/normal_v22.slvs new file mode 100644 index 0000000..3022dcf --- /dev/null +++ b/test/request/ttf_text/normal_v22.slvs @@ -0,0 +1,292 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.activeWorkplane.v=80020000 +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040011 +Param.val=5.00000000000000000000 +AddParam + +Param.h.v.=00040013 +Param.val=-5.00000000000000000000 +AddParam + +Param.h.v.=00040014 +Param.val=-5.00000000000000000000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=600 +Request.workplane.v=80020000 +Request.group.v=00000002 +Request.construction=0 +Request.str=Text +Request.font=Gentium-R.ttf +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=15000 +Entity.construction=0 +Entity.str=Text +Entity.font=Gentium-R.ttf +Entity.point[0].v=00040001 +Entity.point[1].v=00040002 +Entity.normal.v=00040020 +Entity.workplane.v=80020000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040002 +Entity.type=2001 +Entity.construction=0 +Entity.workplane.v=80020000 +Entity.actPoint.x=-5.00000000000000000000 +Entity.actPoint.y=-5.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3001 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.workplane.v=80020000 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + diff --git a/test/request/ttf_text/test.cpp b/test/request/ttf_text/test.cpp new file mode 100644 index 0000000..5e9db1b --- /dev/null +++ b/test/request/ttf_text/test.cpp @@ -0,0 +1,17 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} diff --git a/test/request/workplane/normal.png b/test/request/workplane/normal.png new file mode 100644 index 0000000000000000000000000000000000000000..30862b3ff1cd95fb5a817251fb9413f14d037231 GIT binary patch literal 5612 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 literal 0 HcmV?d00001 diff --git a/test/request/workplane/normal.slvs b/test/request/workplane/normal.slvs new file mode 100644 index 0000000..de433f9 --- /dev/null +++ b/test/request/workplane/normal.slvs @@ -0,0 +1,293 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040020 +Param.val=0.88047623921714945894 +AddParam + +Param.h.v.=00040021 +Param.val=-0.27984814233312144127 +AddParam + +Param.h.v.=00040022 +Param.val=-0.36470519963100095362 +AddParam + +Param.h.v.=00040023 +Param.val=-0.11591689595929521861 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=100 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.actNormal.w=0.88047623921714945894 +Entity.actNormal.vx=-0.27984814233312144127 +Entity.actNormal.vy=-0.36470519963100095362 +Entity.actNormal.vz=-0.11591689595929521861 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=1 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.ptA.v=00010001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/request/workplane/normal_v20.slvs b/test/request/workplane/normal_v20.slvs new file mode 100644 index 0000000..f239329 --- /dev/null +++ b/test/request/workplane/normal_v20.slvs @@ -0,0 +1,291 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allDimsReference=0 +Group.remap={ +} +Group.impFile= +Group.impFileRel= +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040020 +Param.val=0.88047623921714946000 +AddParam + +Param.h.v.=00040021 +Param.val=-0.27984814233312144000 +AddParam + +Param.h.v.=00040022 +Param.val=-0.36470519963100095000 +AddParam + +Param.h.v.=00040023 +Param.val=-0.11591689595929522000 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=100 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.actNormal.w=0.88047623921714946000 +Entity.actNormal.vx=-0.27984814233312144000 +Entity.actNormal.vy=-0.36470519963100095000 +Entity.actNormal.vz=-0.11591689595929522000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.ptA.v=00010001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/request/workplane/normal_v22.slvs b/test/request/workplane/normal_v22.slvs new file mode 100644 index 0000000..d79e899 --- /dev/null +++ b/test/request/workplane/normal_v22.slvs @@ -0,0 +1,293 @@ +±²³SolveSpaceREVa + + +Group.h.v=00000001 +Group.type=5000 +Group.name=#references +Group.color=ff000000 +Group.skipFirst=0 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Group.h.v=00000002 +Group.type=5001 +Group.order=1 +Group.name=sketch-in-plane +Group.color=ff000000 +Group.subtype=6000 +Group.skipFirst=0 +Group.predef.q.w=1.00000000000000000000 +Group.predef.origin.v=00010001 +Group.predef.swapUV=0 +Group.predef.negateU=0 +Group.predef.negateV=0 +Group.visible=1 +Group.suppress=0 +Group.relaxConstraints=0 +Group.allowRedundant=0 +Group.allDimsReference=0 +Group.scale=1.00000000000000000000 +Group.remap={ +} +AddGroup + +Param.h.v.=00010010 +AddParam + +Param.h.v.=00010011 +AddParam + +Param.h.v.=00010012 +AddParam + +Param.h.v.=00010020 +Param.val=1.00000000000000000000 +AddParam + +Param.h.v.=00010021 +AddParam + +Param.h.v.=00010022 +AddParam + +Param.h.v.=00010023 +AddParam + +Param.h.v.=00020010 +AddParam + +Param.h.v.=00020011 +AddParam + +Param.h.v.=00020012 +AddParam + +Param.h.v.=00020020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020021 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020022 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00020023 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030010 +AddParam + +Param.h.v.=00030011 +AddParam + +Param.h.v.=00030012 +AddParam + +Param.h.v.=00030020 +Param.val=0.50000000000000000000 +AddParam + +Param.h.v.=00030021 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030022 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00030023 +Param.val=-0.50000000000000000000 +AddParam + +Param.h.v.=00040010 +AddParam + +Param.h.v.=00040011 +AddParam + +Param.h.v.=00040012 +AddParam + +Param.h.v.=00040020 +Param.val=0.88047623921714945894 +AddParam + +Param.h.v.=00040021 +Param.val=-0.27984814233312144127 +AddParam + +Param.h.v.=00040022 +Param.val=-0.36470519963100095362 +AddParam + +Param.h.v.=00040023 +Param.val=-0.11591689595929521861 +AddParam + +Request.h.v=00000001 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000002 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000003 +Request.type=100 +Request.group.v=00000001 +Request.construction=0 +AddRequest + +Request.h.v=00000004 +Request.type=100 +Request.group.v=00000002 +Request.construction=0 +AddRequest + +Entity.h.v=00010000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.normal.v=00010020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00010020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00010001 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.normal.v=00020020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00020020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00020001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=0.50000000000000000000 +Entity.actNormal.vy=0.50000000000000000000 +Entity.actNormal.vz=0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.normal.v=00030020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00030020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00030001 +Entity.actNormal.w=0.50000000000000000000 +Entity.actNormal.vx=-0.50000000000000000000 +Entity.actNormal.vy=-0.50000000000000000000 +Entity.actNormal.vz=-0.50000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.normal.v=00040020 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040001 +Entity.type=2000 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Entity.h.v=00040020 +Entity.type=3000 +Entity.construction=0 +Entity.point[0].v=00040001 +Entity.actNormal.w=0.88047623921714945894 +Entity.actNormal.vx=-0.27984814233312144127 +Entity.actNormal.vy=-0.36470519963100095362 +Entity.actNormal.vz=-0.11591689595929521861 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020000 +Entity.type=10000 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.normal.v=80020001 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020001 +Entity.type=3010 +Entity.construction=0 +Entity.point[0].v=80020002 +Entity.actNormal.w=1.00000000000000000000 +Entity.actVisible=1 +AddEntity + +Entity.h.v=80020002 +Entity.type=2012 +Entity.construction=0 +Entity.actVisible=1 +AddEntity + +Constraint.h.v=00000001 +Constraint.type=20 +Constraint.group.v=00000002 +Constraint.ptA.v=00010001 +Constraint.ptB.v=00040001 +Constraint.other=0 +Constraint.other2=0 +Constraint.reference=0 +AddConstraint + diff --git a/test/request/workplane/test.cpp b/test/request/workplane/test.cpp new file mode 100644 index 0000000..5e9db1b --- /dev/null +++ b/test/request/workplane/test.cpp @@ -0,0 +1,17 @@ +#include "harness.h" + +TEST_CASE(normal_roundtrip) { + CHECK_LOAD("normal.slvs"); + CHECK_RENDER("normal.png"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v20) { + CHECK_LOAD("normal_v20.slvs"); + CHECK_SAVE("normal.slvs"); +} + +TEST_CASE(normal_migrate_from_v22) { + CHECK_LOAD("normal_v22.slvs"); + CHECK_SAVE("normal.slvs"); +} diff --git a/wishlist.txt b/wishlist.txt new file mode 100644 index 0000000..f9db34a --- /dev/null +++ b/wishlist.txt @@ -0,0 +1,19 @@ +O(n*log(n)) assembly of edges into contours +fix anti-aliased edge bug with filled contours +crude DXF, HPGL import +a request to import a plane thing +make export assemble only contours in same group +rotation of model view works about z of first point under cursor +a way to kill a slow operation + +----- +rounding, as a special group +associative entities from solid model, as a special group +better level of detail +some kind of import +faster triangulation +loop detection +IGES export +incremental regen of entities + + -- 2.30.2

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