From 02dbb7d69158571ef711030954888ec84ff1b834 Mon Sep 17 00:00:00 2001
From: Blake Miner
Date: Wed, 29 Jul 2026 14:26:24 -0400
Subject: [PATCH 1/2] Removed webui submodule
---
.gitmodules | 3 ---
v2/webui | 1 -
2 files changed, 4 deletions(-)
delete mode 160000 v2/webui
diff --git a/.gitmodules b/.gitmodules
index fdabc07..e69de29 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "v2/webui"]
- path = v2/webui
- url = https://github.com/webui-dev/webui.git
diff --git a/v2/webui b/v2/webui
deleted file mode 160000
index 94a8cfb..0000000
--- a/v2/webui
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 94a8cfbad041f44c576c62d9723cc0efa846330a
From 1b740a547185ed2fce0f56d5689c3e337b515614 Mon Sep 17 00:00:00 2001
From: Blake Miner
Date: Wed, 29 Jul 2026 14:33:49 -0400
Subject: [PATCH 2/2] Squashed 'v2/webui/' content from commit 94a8cfb
git-subtree-dir: v2/webui
git-subtree-split: 94a8cfbad041f44c576c62d9723cc0efa846330a
---
.github/workflows/ci.yml | 54 +
.github/workflows/linux.yml | 193 +
.github/workflows/linux_arch.yml | 111 +
.github/workflows/linux_arm.yml | 180 +
.github/workflows/linux_redhat.yml | 113 +
.github/workflows/macos.yml | 125 +
.github/workflows/windows.yml | 133 +
.github/workflows/zig.yml | 36 +
.gitignore | 141 +
CMakeLists.txt | 192 +
GNUmakefile | 218 +
LICENSE | 21 +
Makefile | 97 +
README.md | 317 +
bridge/.gitignore | 6 +
bridge/README.md | 47 +
bridge/build.bat | 29 +
bridge/build.sh | 21 +
bridge/js2c.js | 43 +
bridge/utils.ts | 56 +
bridge/webui.ts | 1025 +
bridge/webui_bridge.h | 1892 +
build.cmake.sh | 9 +
build.zig | 240 +
build.zig.zon | 14 +
conanfile.py | 33 +
examples/C++/README.md | 39 +
examples/C++/call_cpp_from_js/GNUmakefile | 138 +
examples/C++/call_cpp_from_js/Makefile | 65 +
examples/C++/call_cpp_from_js/main.cpp | 118 +
examples/C++/call_js_from_cpp/GNUmakefile | 138 +
examples/C++/call_js_from_cpp/Makefile | 65 +
examples/C++/call_js_from_cpp/main.cpp | 124 +
examples/C++/minimal/GNUmakefile | 138 +
examples/C++/minimal/Makefile | 65 +
examples/C++/minimal/main.cpp | 13 +
examples/C++/serve_a_folder/GNUmakefile | 138 +
examples/C++/serve_a_folder/Makefile | 65 +
examples/C++/serve_a_folder/index.html | 39 +
examples/C++/serve_a_folder/main.cpp | 100 +
examples/C++/serve_a_folder/second.html | 26 +
examples/C++/test_index_redirect/GNUmakefile | 138 +
examples/C++/test_index_redirect/Makefile | 65 +
examples/C++/test_index_redirect/main.cpp | 87 +
.../C++/test_index_redirect/ui/custom.html | 29 +
examples/C++/test_index_redirect/ui/index.css | 4 +
.../C++/test_index_redirect/ui/index.html | 29 +
examples/C++/test_index_redirect/ui/index.js | 4 +
.../test_index_redirect/ui/sub/custom.html | 29 +
.../ui/sub/foo/custom.html | 29 +
.../test_index_redirect/ui/sub/foo/index.css | 4 +
.../test_index_redirect/ui/sub/foo/index.html | 29 +
.../test_index_redirect/ui/sub/foo/index.js | 4 +
.../C++/test_index_redirect/ui/sub/index.css | 4 +
.../C++/test_index_redirect/ui/sub/index.html | 29 +
.../C++/test_index_redirect/ui/sub/index.js | 4 +
examples/C++/test_index_redirect/vfs.h | 131 +
examples/C++/test_index_redirect/vfs.py | 99 +
examples/C++/virtual_file_system/GNUmakefile | 138 +
examples/C++/virtual_file_system/Makefile | 65 +
examples/C++/virtual_file_system/main.cpp | 57 +
.../C++/virtual_file_system/ui/index.html | 135 +
.../C++/virtual_file_system/ui/sub/index.html | 64 +
.../C++/virtual_file_system/ui/svg/webui.svg | 1 +
examples/C++/virtual_file_system/vfs.h | 68 +
examples/C++/virtual_file_system/vfs.py | 99 +
examples/C/README.md | 51 +
examples/C/call_c_from_js/GNUmakefile | 138 +
examples/C/call_c_from_js/Makefile | 64 +
examples/C/call_c_from_js/main.c | 184 +
examples/C/call_js_from_c/GNUmakefile | 138 +
examples/C/call_js_from_c/Makefile | 64 +
examples/C/call_js_from_c/main.c | 143 +
examples/C/chatgpt_api/GNUmakefile | 138 +
examples/C/chatgpt_api/Makefile | 64 +
examples/C/chatgpt_api/main.c | 98 +
examples/C/custom_web_server/GNUmakefile | 138 +
examples/C/custom_web_server/Makefile | 64 +
examples/C/custom_web_server/index.html | 18 +
examples/C/custom_web_server/main.c | 74 +
examples/C/custom_web_server/second.html | 13 +
.../C/custom_web_server/simple_web_server.py | 10 +
examples/C/frameless/GNUmakefile | 138 +
examples/C/frameless/Makefile | 64 +
examples/C/frameless/main.c | 130 +
examples/C/frameless/webui_frameless.png | Bin 0 -> 297499 bytes
.../C/frameless/webui_frameless_linux.png | Bin 0 -> 433044 bytes
examples/C/minimal/GNUmakefile | 138 +
examples/C/minimal/Makefile | 64 +
examples/C/minimal/main.c | 15 +
examples/C/public_network_access/GNUmakefile | 138 +
examples/C/public_network_access/Makefile | 64 +
examples/C/public_network_access/main.c | 139 +
examples/C/react/GNUmakefile | 138 +
examples/C/react/Makefile | 64 +
examples/C/react/README.md | 23 +
examples/C/react/build_react.bat | 19 +
examples/C/react/build_react.sh | 19 +
examples/C/react/main.c | 59 +
examples/C/react/vfs.h | 145 +
examples/C/react/vfs.py | 99 +
.../C/react/webui-react-example/.gitignore | 23 +
.../webui-react-example/package-lock.json | 19039 ++++++
.../C/react/webui-react-example/package.json | 38 +
.../webui-react-example/public/favicon.ico | Bin 0 -> 3870 bytes
.../webui-react-example/public/index.html | 47 +
.../webui-react-example/public/logo192.png | Bin 0 -> 5347 bytes
.../webui-react-example/public/logo512.png | Bin 0 -> 9664 bytes
.../webui-react-example/public/manifest.json | 25 +
.../webui-react-example/public/robots.txt | 3 +
.../C/react/webui-react-example/src/App.css | 38 +
.../C/react/webui-react-example/src/App.js | 75 +
.../react/webui-react-example/src/App.test.js | 8 +
.../C/react/webui-react-example/src/index.css | 16 +
.../C/react/webui-react-example/src/index.js | 17 +
.../C/react/webui-react-example/src/logo.svg | 1 +
.../src/reportWebVitals.js | 13 +
.../webui-react-example/src/setupTests.js | 5 +
examples/C/react/webui_react.png | Bin 0 -> 20286 bytes
examples/C/serve_a_folder/GNUmakefile | 138 +
examples/C/serve_a_folder/Makefile | 64 +
examples/C/serve_a_folder/bun_test.ts | 26 +
examples/C/serve_a_folder/deno_test.ts | 29 +
examples/C/serve_a_folder/index.html | 193 +
examples/C/serve_a_folder/main.c | 166 +
examples/C/serve_a_folder/node_test.js | 26 +
examples/C/serve_a_folder/second.html | 48 +
examples/C/test_index_redirect/GNUmakefile | 138 +
examples/C/test_index_redirect/Makefile | 64 +
examples/C/test_index_redirect/main.c | 89 +
examples/C/test_index_redirect/ui/custom.html | 29 +
examples/C/test_index_redirect/ui/index.css | 4 +
examples/C/test_index_redirect/ui/index.html | 29 +
examples/C/test_index_redirect/ui/index.js | 4 +
.../C/test_index_redirect/ui/sub/custom.html | 29 +
.../ui/sub/foo/custom.html | 29 +
.../test_index_redirect/ui/sub/foo/index.css | 4 +
.../test_index_redirect/ui/sub/foo/index.html | 29 +
.../C/test_index_redirect/ui/sub/foo/index.js | 4 +
.../C/test_index_redirect/ui/sub/index.css | 4 +
.../C/test_index_redirect/ui/sub/index.html | 29 +
.../C/test_index_redirect/ui/sub/index.js | 4 +
examples/C/test_index_redirect/vfs.h | 131 +
examples/C/test_index_redirect/vfs.py | 99 +
examples/C/text-editor/GNUmakefile | 138 +
examples/C/text-editor/Makefile | 64 +
examples/C/text-editor/README.md | 29 +
examples/C/text-editor/main.c | 38 +
examples/C/text-editor/ui/css/all.min.css | 9 +
.../C/text-editor/ui/css/codemirror.min.css | 1 +
examples/C/text-editor/ui/css/lucario.css | 39 +
examples/C/text-editor/ui/css/style.css | 113 +
examples/C/text-editor/ui/img/icon.png | Bin 0 -> 1491 bytes
examples/C/text-editor/ui/index.html | 41 +
examples/C/text-editor/ui/js/clike.min.js | 1 +
.../C/text-editor/ui/js/codemirror.min.js | 1 +
examples/C/text-editor/ui/js/css.min.js | 1 +
.../C/text-editor/ui/js/javascript.min.js | 1 +
examples/C/text-editor/ui/js/python.min.js | 1 +
examples/C/text-editor/ui/js/ui.js | 124 +
examples/C/text-editor/ui/js/xml.min.js | 1 +
.../text-editor/ui/webfonts/fa-brands-400.eot | Bin 0 -> 134294 bytes
.../text-editor/ui/webfonts/fa-brands-400.svg | 3717 ++
.../text-editor/ui/webfonts/fa-brands-400.ttf | Bin 0 -> 133988 bytes
.../ui/webfonts/fa-brands-400.woff | Bin 0 -> 89988 bytes
.../ui/webfonts/fa-brands-400.woff2 | Bin 0 -> 76736 bytes
.../ui/webfonts/fa-regular-400.eot | Bin 0 -> 34034 bytes
.../ui/webfonts/fa-regular-400.svg | 801 +
.../ui/webfonts/fa-regular-400.ttf | Bin 0 -> 33736 bytes
.../ui/webfonts/fa-regular-400.woff | Bin 0 -> 16276 bytes
.../ui/webfonts/fa-regular-400.woff2 | Bin 0 -> 13224 bytes
.../text-editor/ui/webfonts/fa-solid-900.eot | Bin 0 -> 203030 bytes
.../text-editor/ui/webfonts/fa-solid-900.svg | 5034 ++
.../text-editor/ui/webfonts/fa-solid-900.ttf | Bin 0 -> 202744 bytes
.../text-editor/ui/webfonts/fa-solid-900.woff | Bin 0 -> 101648 bytes
.../ui/webfonts/fa-solid-900.woff2 | Bin 0 -> 78268 bytes
examples/C/virtual_file_system/GNUmakefile | 138 +
examples/C/virtual_file_system/Makefile | 64 +
examples/C/virtual_file_system/main.c | 47 +
examples/C/virtual_file_system/ui/index.html | 135 +
.../C/virtual_file_system/ui/sub/index.html | 64 +
.../C/virtual_file_system/ui/svg/webui.svg | 1 +
examples/C/virtual_file_system/vfs.h | 68 +
examples/C/virtual_file_system/vfs.py | 99 +
examples/C/web_app_multi_client/GNUmakefile | 138 +
examples/C/web_app_multi_client/Makefile | 64 +
examples/C/web_app_multi_client/index.html | 155 +
examples/C/web_app_multi_client/main.c | 132 +
include/webui.h | 1489 +
include/webui.hpp | 619 +
include/webui_extensions.h | 121 +
src/civetweb/CMakeLists.txt | 29 +
src/civetweb/README.md | 17 +
src/civetweb/civetweb.c | 23274 +++++++
src/civetweb/civetweb.h | 1844 +
src/civetweb/handle_form.inl | 1148 +
src/civetweb/match.inl | 262 +
src/civetweb/md5.inl | 472 +
src/civetweb/response.inl | 342 +
src/civetweb/sha1.inl | 323 +
src/civetweb/sort.inl | 48 +
src/webui.c | 13888 +++++
src/webview/EventToken.h | 69 +
src/webview/README.md | 17 +
src/webview/WebView2.h | 51977 ++++++++++++++++
src/webview/win32_wv2.cpp | 476 +
src/webview/win32_wv2.hpp | 58 +
src/webview/wkwebview.m | 539 +
vcpkg.json | 30 +
209 files changed, 139875 insertions(+)
create mode 100644 .github/workflows/ci.yml
create mode 100644 .github/workflows/linux.yml
create mode 100644 .github/workflows/linux_arch.yml
create mode 100644 .github/workflows/linux_arm.yml
create mode 100644 .github/workflows/linux_redhat.yml
create mode 100644 .github/workflows/macos.yml
create mode 100644 .github/workflows/windows.yml
create mode 100644 .github/workflows/zig.yml
create mode 100644 .gitignore
create mode 100644 CMakeLists.txt
create mode 100644 GNUmakefile
create mode 100644 LICENSE
create mode 100644 Makefile
create mode 100644 README.md
create mode 100644 bridge/.gitignore
create mode 100644 bridge/README.md
create mode 100644 bridge/build.bat
create mode 100755 bridge/build.sh
create mode 100644 bridge/js2c.js
create mode 100644 bridge/utils.ts
create mode 100644 bridge/webui.ts
create mode 100644 bridge/webui_bridge.h
create mode 100644 build.cmake.sh
create mode 100644 build.zig
create mode 100644 build.zig.zon
create mode 100644 conanfile.py
create mode 100644 examples/C++/README.md
create mode 100644 examples/C++/call_cpp_from_js/GNUmakefile
create mode 100644 examples/C++/call_cpp_from_js/Makefile
create mode 100644 examples/C++/call_cpp_from_js/main.cpp
create mode 100644 examples/C++/call_js_from_cpp/GNUmakefile
create mode 100644 examples/C++/call_js_from_cpp/Makefile
create mode 100644 examples/C++/call_js_from_cpp/main.cpp
create mode 100644 examples/C++/minimal/GNUmakefile
create mode 100644 examples/C++/minimal/Makefile
create mode 100644 examples/C++/minimal/main.cpp
create mode 100644 examples/C++/serve_a_folder/GNUmakefile
create mode 100644 examples/C++/serve_a_folder/Makefile
create mode 100644 examples/C++/serve_a_folder/index.html
create mode 100644 examples/C++/serve_a_folder/main.cpp
create mode 100644 examples/C++/serve_a_folder/second.html
create mode 100644 examples/C++/test_index_redirect/GNUmakefile
create mode 100644 examples/C++/test_index_redirect/Makefile
create mode 100644 examples/C++/test_index_redirect/main.cpp
create mode 100644 examples/C++/test_index_redirect/ui/custom.html
create mode 100644 examples/C++/test_index_redirect/ui/index.css
create mode 100644 examples/C++/test_index_redirect/ui/index.html
create mode 100644 examples/C++/test_index_redirect/ui/index.js
create mode 100644 examples/C++/test_index_redirect/ui/sub/custom.html
create mode 100644 examples/C++/test_index_redirect/ui/sub/foo/custom.html
create mode 100644 examples/C++/test_index_redirect/ui/sub/foo/index.css
create mode 100644 examples/C++/test_index_redirect/ui/sub/foo/index.html
create mode 100644 examples/C++/test_index_redirect/ui/sub/foo/index.js
create mode 100644 examples/C++/test_index_redirect/ui/sub/index.css
create mode 100644 examples/C++/test_index_redirect/ui/sub/index.html
create mode 100644 examples/C++/test_index_redirect/ui/sub/index.js
create mode 100644 examples/C++/test_index_redirect/vfs.h
create mode 100644 examples/C++/test_index_redirect/vfs.py
create mode 100644 examples/C++/virtual_file_system/GNUmakefile
create mode 100644 examples/C++/virtual_file_system/Makefile
create mode 100644 examples/C++/virtual_file_system/main.cpp
create mode 100644 examples/C++/virtual_file_system/ui/index.html
create mode 100644 examples/C++/virtual_file_system/ui/sub/index.html
create mode 100644 examples/C++/virtual_file_system/ui/svg/webui.svg
create mode 100644 examples/C++/virtual_file_system/vfs.h
create mode 100644 examples/C++/virtual_file_system/vfs.py
create mode 100644 examples/C/README.md
create mode 100644 examples/C/call_c_from_js/GNUmakefile
create mode 100644 examples/C/call_c_from_js/Makefile
create mode 100644 examples/C/call_c_from_js/main.c
create mode 100644 examples/C/call_js_from_c/GNUmakefile
create mode 100644 examples/C/call_js_from_c/Makefile
create mode 100644 examples/C/call_js_from_c/main.c
create mode 100644 examples/C/chatgpt_api/GNUmakefile
create mode 100644 examples/C/chatgpt_api/Makefile
create mode 100644 examples/C/chatgpt_api/main.c
create mode 100644 examples/C/custom_web_server/GNUmakefile
create mode 100644 examples/C/custom_web_server/Makefile
create mode 100644 examples/C/custom_web_server/index.html
create mode 100644 examples/C/custom_web_server/main.c
create mode 100644 examples/C/custom_web_server/second.html
create mode 100644 examples/C/custom_web_server/simple_web_server.py
create mode 100644 examples/C/frameless/GNUmakefile
create mode 100644 examples/C/frameless/Makefile
create mode 100644 examples/C/frameless/main.c
create mode 100644 examples/C/frameless/webui_frameless.png
create mode 100644 examples/C/frameless/webui_frameless_linux.png
create mode 100644 examples/C/minimal/GNUmakefile
create mode 100644 examples/C/minimal/Makefile
create mode 100644 examples/C/minimal/main.c
create mode 100644 examples/C/public_network_access/GNUmakefile
create mode 100644 examples/C/public_network_access/Makefile
create mode 100644 examples/C/public_network_access/main.c
create mode 100644 examples/C/react/GNUmakefile
create mode 100644 examples/C/react/Makefile
create mode 100644 examples/C/react/README.md
create mode 100644 examples/C/react/build_react.bat
create mode 100644 examples/C/react/build_react.sh
create mode 100644 examples/C/react/main.c
create mode 100644 examples/C/react/vfs.h
create mode 100644 examples/C/react/vfs.py
create mode 100644 examples/C/react/webui-react-example/.gitignore
create mode 100644 examples/C/react/webui-react-example/package-lock.json
create mode 100644 examples/C/react/webui-react-example/package.json
create mode 100644 examples/C/react/webui-react-example/public/favicon.ico
create mode 100644 examples/C/react/webui-react-example/public/index.html
create mode 100644 examples/C/react/webui-react-example/public/logo192.png
create mode 100644 examples/C/react/webui-react-example/public/logo512.png
create mode 100644 examples/C/react/webui-react-example/public/manifest.json
create mode 100644 examples/C/react/webui-react-example/public/robots.txt
create mode 100644 examples/C/react/webui-react-example/src/App.css
create mode 100644 examples/C/react/webui-react-example/src/App.js
create mode 100644 examples/C/react/webui-react-example/src/App.test.js
create mode 100644 examples/C/react/webui-react-example/src/index.css
create mode 100644 examples/C/react/webui-react-example/src/index.js
create mode 100644 examples/C/react/webui-react-example/src/logo.svg
create mode 100644 examples/C/react/webui-react-example/src/reportWebVitals.js
create mode 100644 examples/C/react/webui-react-example/src/setupTests.js
create mode 100644 examples/C/react/webui_react.png
create mode 100644 examples/C/serve_a_folder/GNUmakefile
create mode 100644 examples/C/serve_a_folder/Makefile
create mode 100644 examples/C/serve_a_folder/bun_test.ts
create mode 100644 examples/C/serve_a_folder/deno_test.ts
create mode 100644 examples/C/serve_a_folder/index.html
create mode 100644 examples/C/serve_a_folder/main.c
create mode 100644 examples/C/serve_a_folder/node_test.js
create mode 100644 examples/C/serve_a_folder/second.html
create mode 100644 examples/C/test_index_redirect/GNUmakefile
create mode 100644 examples/C/test_index_redirect/Makefile
create mode 100644 examples/C/test_index_redirect/main.c
create mode 100644 examples/C/test_index_redirect/ui/custom.html
create mode 100644 examples/C/test_index_redirect/ui/index.css
create mode 100644 examples/C/test_index_redirect/ui/index.html
create mode 100644 examples/C/test_index_redirect/ui/index.js
create mode 100644 examples/C/test_index_redirect/ui/sub/custom.html
create mode 100644 examples/C/test_index_redirect/ui/sub/foo/custom.html
create mode 100644 examples/C/test_index_redirect/ui/sub/foo/index.css
create mode 100644 examples/C/test_index_redirect/ui/sub/foo/index.html
create mode 100644 examples/C/test_index_redirect/ui/sub/foo/index.js
create mode 100644 examples/C/test_index_redirect/ui/sub/index.css
create mode 100644 examples/C/test_index_redirect/ui/sub/index.html
create mode 100644 examples/C/test_index_redirect/ui/sub/index.js
create mode 100644 examples/C/test_index_redirect/vfs.h
create mode 100644 examples/C/test_index_redirect/vfs.py
create mode 100644 examples/C/text-editor/GNUmakefile
create mode 100644 examples/C/text-editor/Makefile
create mode 100644 examples/C/text-editor/README.md
create mode 100644 examples/C/text-editor/main.c
create mode 100644 examples/C/text-editor/ui/css/all.min.css
create mode 100644 examples/C/text-editor/ui/css/codemirror.min.css
create mode 100644 examples/C/text-editor/ui/css/lucario.css
create mode 100644 examples/C/text-editor/ui/css/style.css
create mode 100644 examples/C/text-editor/ui/img/icon.png
create mode 100644 examples/C/text-editor/ui/index.html
create mode 100644 examples/C/text-editor/ui/js/clike.min.js
create mode 100644 examples/C/text-editor/ui/js/codemirror.min.js
create mode 100644 examples/C/text-editor/ui/js/css.min.js
create mode 100644 examples/C/text-editor/ui/js/javascript.min.js
create mode 100644 examples/C/text-editor/ui/js/python.min.js
create mode 100644 examples/C/text-editor/ui/js/ui.js
create mode 100644 examples/C/text-editor/ui/js/xml.min.js
create mode 100644 examples/C/text-editor/ui/webfonts/fa-brands-400.eot
create mode 100644 examples/C/text-editor/ui/webfonts/fa-brands-400.svg
create mode 100644 examples/C/text-editor/ui/webfonts/fa-brands-400.ttf
create mode 100644 examples/C/text-editor/ui/webfonts/fa-brands-400.woff
create mode 100644 examples/C/text-editor/ui/webfonts/fa-brands-400.woff2
create mode 100644 examples/C/text-editor/ui/webfonts/fa-regular-400.eot
create mode 100644 examples/C/text-editor/ui/webfonts/fa-regular-400.svg
create mode 100644 examples/C/text-editor/ui/webfonts/fa-regular-400.ttf
create mode 100644 examples/C/text-editor/ui/webfonts/fa-regular-400.woff
create mode 100644 examples/C/text-editor/ui/webfonts/fa-regular-400.woff2
create mode 100644 examples/C/text-editor/ui/webfonts/fa-solid-900.eot
create mode 100644 examples/C/text-editor/ui/webfonts/fa-solid-900.svg
create mode 100644 examples/C/text-editor/ui/webfonts/fa-solid-900.ttf
create mode 100644 examples/C/text-editor/ui/webfonts/fa-solid-900.woff
create mode 100644 examples/C/text-editor/ui/webfonts/fa-solid-900.woff2
create mode 100644 examples/C/virtual_file_system/GNUmakefile
create mode 100644 examples/C/virtual_file_system/Makefile
create mode 100644 examples/C/virtual_file_system/main.c
create mode 100644 examples/C/virtual_file_system/ui/index.html
create mode 100644 examples/C/virtual_file_system/ui/sub/index.html
create mode 100644 examples/C/virtual_file_system/ui/svg/webui.svg
create mode 100644 examples/C/virtual_file_system/vfs.h
create mode 100644 examples/C/virtual_file_system/vfs.py
create mode 100644 examples/C/web_app_multi_client/GNUmakefile
create mode 100644 examples/C/web_app_multi_client/Makefile
create mode 100644 examples/C/web_app_multi_client/index.html
create mode 100644 examples/C/web_app_multi_client/main.c
create mode 100644 include/webui.h
create mode 100644 include/webui.hpp
create mode 100644 include/webui_extensions.h
create mode 100644 src/civetweb/CMakeLists.txt
create mode 100644 src/civetweb/README.md
create mode 100644 src/civetweb/civetweb.c
create mode 100644 src/civetweb/civetweb.h
create mode 100644 src/civetweb/handle_form.inl
create mode 100644 src/civetweb/match.inl
create mode 100644 src/civetweb/md5.inl
create mode 100644 src/civetweb/response.inl
create mode 100644 src/civetweb/sha1.inl
create mode 100644 src/civetweb/sort.inl
create mode 100644 src/webui.c
create mode 100644 src/webview/EventToken.h
create mode 100644 src/webview/README.md
create mode 100644 src/webview/WebView2.h
create mode 100644 src/webview/win32_wv2.cpp
create mode 100644 src/webview/win32_wv2.hpp
create mode 100644 src/webview/wkwebview.m
create mode 100644 vcpkg.json
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..1bf92ea
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,54 @@
+# https://webui.me
+# https://github.com/webui-dev/webui
+# Copyright (c) 2020-2026 Hassan Draga.
+# Licensed under MIT License.
+# All rights reserved.
+# Canada.
+#
+# Special Thanks to Turiiya (https://github.com/ttytm)
+
+name: CI
+on:
+ push:
+ paths-ignore: ['**/*.md']
+ pull_request:
+ branches: [main]
+ paths-ignore: ['**/*.md']
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref_name == 'main' && github.sha || github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ windows:
+ uses: ./.github/workflows/windows.yml
+ permissions:
+ contents: write
+
+ macos:
+ uses: ./.github/workflows/macos.yml
+ permissions:
+ contents: write
+
+ linux:
+ uses: ./.github/workflows/linux.yml
+ permissions:
+ contents: write
+
+ linux_arm:
+ uses: ./.github/workflows/linux_arm.yml
+ permissions:
+ contents: write
+
+ linux_redhat:
+ uses: ./.github/workflows/linux_redhat.yml
+ permissions:
+ contents: write
+
+ linux_arch:
+ uses: ./.github/workflows/linux_arch.yml
+ permissions:
+ contents: write
+
+ zig:
+ uses: ./.github/workflows/zig.yml
diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
new file mode 100644
index 0000000..2726861
--- /dev/null
+++ b/.github/workflows/linux.yml
@@ -0,0 +1,193 @@
+# https://webui.me
+# https://github.com/webui-dev/webui
+# Copyright (c) 2020-2026 Hassan Draga.
+# Licensed under MIT License.
+# All rights reserved.
+# Canada.
+#
+# Special Thanks to Turiiya (https://github.com/ttytm)
+
+name: Linux
+on:
+ workflow_call:
+
+jobs:
+ setup:
+ runs-on: ubuntu-22.04
+ steps:
+ - uses: actions/checkout@v4
+ - name: Bundle WebUI Bridge
+ run: |
+ npm i -g esbuild
+ chmod +x bridge/build.sh
+ bridge/build.sh
+ - uses: actions/cache@v4
+ with:
+ path: bridge/webui_bridge.h
+ key: ${{ runner.os }}-${{ github.sha }}-bridge
+
+ build:
+ needs: setup
+ runs-on: ubuntu-22.04
+ permissions:
+ contents: write
+ strategy:
+ matrix:
+ include:
+ - cc: gcc
+ arch: x64
+ - cc: clang
+ arch: x64
+ fail-fast: false
+ env:
+ ARTIFACT: webui-linux-${{ matrix.cc }}-${{ matrix.arch }}
+ CC: ${{ matrix.cc }}
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/cache/restore@v4
+ with:
+ path: bridge/webui_bridge.h
+ key: ${{ runner.os }}-${{ github.sha }}-bridge
+ fail-on-cache-miss: true
+ - name: Setup
+ run: |
+ if [ "$CC" == "clang" ]; then
+ sudo ln -s llvm-ar-14 /usr/bin/llvm-ar
+ sudo ln -s llvm-ranlib-14 /usr/bin/llvm-ranlib
+ sudo ln -s llvm-strip-14 /usr/bin/llvm-strip
+ fi
+ - name: Build Debug Target
+ run: make debug
+ - name: Build Release Target
+ if: ${{ !cancelled() }}
+ run: make
+ - name: Build TLS Debug Target
+ run: make WEBUI_USE_TLS=1 debug
+ - name: Build TLS Release Target
+ run: make WEBUI_USE_TLS=1
+ - name: Build Examples
+ run: |
+ examples_base_dir=$(pwd)/examples/C
+ for example in $(find $examples_base_dir/* -maxdepth 0 -type d); do
+ echo "> $example"
+ cd $example || (exit_code=1 && continue)
+ if ! make; then
+ echo "Failed to build '$example'"
+ exit_code=1
+ continue
+ fi
+ if [[ ! -e "main" || ! -e "main-dyn" ]] ; then
+ echo "Failed to find executable for '$example'" && find .
+ exit_code=1
+ continue
+ fi
+ done
+ exit $exit_code
+ - name: Setup Browser
+ uses: browser-actions/setup-chrome@v1
+ - name: Prepare Artifact
+ run: |
+ cp -r include dist
+ mv dist/ "$ARTIFACT"
+ - name: Upload Artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ env.ARTIFACT }}
+ path: ${{ env.ARTIFACT }}
+ - name: Prepare Release
+ if: >
+ github.repository_owner == 'webui-dev'
+ && (github.ref_type == 'tag' || (github.ref_name == 'main' && github.event_name == 'push'))
+ run: |
+ zip -r "$ARTIFACT.zip" "$ARTIFACT"
+ if [ $GITHUB_REF_TYPE == tag ]; then
+ echo "TAG=$GITHUB_REF_NAME" >> $GITHUB_ENV
+ else
+ {
+ echo "IS_PRERELEASE=true";
+ echo "TAG=nightly";
+ echo "TITLE=WebUI Nightly Build $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
+ echo "BODY=Generated from commit $GITHUB_SHA."
+ } >> $GITHUB_ENV
+ fi
+ - name: Update Nightly Tag
+ if: env.IS_PRERELEASE
+ uses: richardsimko/update-tag@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: nightly
+ - name: Release
+ if: >
+ github.repository_owner == 'webui-dev'
+ && (github.ref_type == 'tag' || (github.ref_name == 'main' && github.event_name == 'push'))
+ uses: ncipollo/release-action@v1
+ with:
+ artifacts: ${{ env.ARTIFACT }}.zip
+ tag: ${{ env.TAG }}
+ body: ${{ env.BODY }}
+ name: ${{ env.TITLE }}
+ prerelease: ${{ env.IS_PRERELEASE }}
+ allowUpdates: true
+
+ build-ubuntu-22:
+ needs: setup
+ runs-on: ubuntu-22.04
+ permissions:
+ contents: write
+ strategy:
+ matrix:
+ include:
+ - cc: gcc
+ arch: x64
+ - cc: clang
+ arch: x64
+ fail-fast: false
+ env:
+ ARTIFACT: webui-linux-${{ matrix.cc }}-${{ matrix.arch }}
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/cache/restore@v4
+ with:
+ path: bridge/webui_bridge.h
+ key: ${{ runner.os }}-${{ github.sha }}-bridge
+ fail-on-cache-miss: true
+ - name: Setup
+ run: |
+ CC="${{ matrix.cc }}"
+ if [ "$CC" == "clang" ]; then
+ sudo ln -s llvm-ar-14 /usr/bin/llvm-ar
+ sudo ln -s llvm-ranlib-14 /usr/bin/llvm-ranlib
+ sudo ln -s llvm-strip-14 /usr/bin/llvm-strip
+ else
+ sudo apt -qq install gcc-11
+ CC+="-11"
+ fi
+ echo "CC=$CC" >> $GITHUB_ENV
+ - name: Build Debug Target
+ run: make debug
+ - name: Build Release Target
+ if: ${{ !cancelled() }}
+ run: make
+ - name: Build TLS Debug Target
+ run: make WEBUI_USE_TLS=1 debug
+ - name: Build TLS Release Target
+ run: make WEBUI_USE_TLS=1
+ - name: Build Examples
+ run: |
+ examples_base_dir=$(pwd)/examples/C
+ for example in $(find $examples_base_dir/* -maxdepth 0 -type d); do
+ echo "> $example"
+ cd $example || (exit_code=1 && continue)
+ if ! make; then
+ echo "Failed to build '$example'"
+ exit_code=1
+ continue
+ fi
+ if [[ ! -e "main" || ! -e "main-dyn" ]] ; then
+ echo "Failed to find executable for '$example'" && find .
+ exit_code=1
+ continue
+ fi
+ done
+ exit $exit_code
diff --git a/.github/workflows/linux_arch.yml b/.github/workflows/linux_arch.yml
new file mode 100644
index 0000000..98fec8a
--- /dev/null
+++ b/.github/workflows/linux_arch.yml
@@ -0,0 +1,111 @@
+# https://webui.me
+# https://github.com/webui-dev/webui
+# Copyright (c) 2020-2026 Hassan Draga.
+# Licensed under MIT License.
+# All rights reserved.
+# Canada.
+
+name: Linux-Arch
+on:
+ workflow_call:
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ include:
+ - cc: gcc
+ arch: x64
+ - cc: clang
+ arch: x64
+ fail-fast: false
+ env:
+ ARTIFACT: webui-linux-arch-${{ matrix.cc }}-${{ matrix.arch }}
+ CC: ${{ matrix.cc }}
+ steps:
+ - name: Check out the repository
+ uses: actions/checkout@v4
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v2
+
+ - name: Build Arch Linux Docker Image
+ run: |
+ docker build -t archlinux:latest - <
+ github.repository_owner == 'webui-dev'
+ && (github.ref_type == 'tag' || (github.ref_name == 'main' && github.event_name == 'push'))
+ run: |
+ zip -r "$ARTIFACT.zip" "$ARTIFACT"
+ if [ $GITHUB_REF_TYPE == tag ]; then
+ echo "TAG=$GITHUB_REF_NAME" >> $GITHUB_ENV
+ else
+ {
+ echo "IS_PRERELEASE=true";
+ echo "TAG=nightly";
+ echo "TITLE=WebUI Nightly Build $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
+ echo "BODY=Generated from commit $GITHUB_SHA."
+ } >> $GITHUB_ENV
+ fi
+
+ - name: Update Nightly Tag
+ if: env.IS_PRERELEASE
+ uses: richardsimko/update-tag@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: nightly
+
+ - name: Release
+ if: >
+ github.repository_owner == 'webui-dev'
+ && (github.ref_type == 'tag' || (github.ref_name == 'main' && github.event_name == 'push'))
+ uses: ncipollo/release-action@v1
+ with:
+ artifacts: ${{ env.ARTIFACT }}.zip
+ tag: ${{ env.TAG }}
+ body: ${{ env.BODY }}
+ name: ${{ env.TITLE }}
+ prerelease: ${{ env.IS_PRERELEASE }}
+ allowUpdates: true
diff --git a/.github/workflows/linux_arm.yml b/.github/workflows/linux_arm.yml
new file mode 100644
index 0000000..e8a2ad6
--- /dev/null
+++ b/.github/workflows/linux_arm.yml
@@ -0,0 +1,180 @@
+# https://webui.me
+# https://github.com/webui-dev/webui
+# Copyright (c) 2020-2026 Hassan Draga.
+# Licensed under MIT License.
+# All rights reserved.
+# Canada.
+#
+# Special Thanks to Turiiya (https://github.com/ttytm)
+
+name: Linux ARM
+on:
+ workflow_call:
+
+jobs:
+ setup:
+ runs-on: buildjet-32vcpu-ubuntu-2204-arm
+ steps:
+ - uses: actions/checkout@v4
+ - name: Check CPU Architecture
+ run: |
+ ARCH=$(uname -m)
+ if [[ "$ARCH" != "arm"* && "$ARCH" != "aarch64" ]]; then
+ echo "Expected ARM-based CPU architecture. Detected: $ARCH"
+ exit 1
+ else
+ echo "ARM CPU Detected: $ARCH"
+ fi
+ - name: Bundle WebUI Bridge
+ run: |
+ npm i -g esbuild
+ chmod +x bridge/build.sh
+ bridge/build.sh
+ - uses: actions/cache@v4
+ with:
+ path: bridge/webui_bridge.h
+ key: ${{ runner.os }}-${{ github.sha }}-bridge
+
+ build:
+ needs: setup
+ # Same as `buildjet-32vcpu-ubuntu-2204-arm`
+ runs-on: ubuntu-22.04
+ permissions:
+ contents: write
+ strategy:
+ matrix:
+ include:
+ - cc: gcc
+ arch: arm
+ - cc: gcc
+ arch: arm64
+ - cc: clang
+ arch: arm
+ - cc: clang
+ arch: arm64
+ fail-fast: false
+ env:
+ ARTIFACT: webui-linux-${{ matrix.cc }}-${{ matrix.arch }}
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/cache/restore@v4
+ with:
+ path: bridge/webui_bridge.h
+ key: ${{ runner.os }}-${{ github.sha }}-bridge
+ fail-on-cache-miss: true
+ - name: Setup
+ run: |
+ sudo apt update
+ if [ "${{ matrix.cc }}" == "clang" ]; then
+ sudo apt install -y clang lld
+ fi
+
+ CC=${{ matrix.cc }}
+ if [ "${{ matrix.arch }}" == "arm64" ]; then
+ sudo apt install -y gcc-aarch64-linux-gnu
+ if [ "$CC" = "clang" ]; then
+ CC="clang --target=aarch64-linux-gnu"
+ else
+ CC=aarch64-linux-gnu-gcc
+ fi
+ wget https://github.com/openssl/openssl/releases/download/openssl-3.3.1/openssl-3.3.1.tar.gz
+ tar -xzf openssl-3.3.1.tar.gz
+ cd openssl-3.3.1
+ ./Configure linux-generic64 --prefix=/usr/aarch64-linux-gnu --cross-compile-prefix=aarch64-linux-gnu- --release -latomic
+ make
+ sudo make install
+ elif [ "${{ matrix.arch }}" == "arm" ]; then
+ sudo apt install -y gcc-arm-linux-gnueabi
+ if [ "$CC" = "clang" ]; then
+ CC="clang --target=arm-linux-gnueabi"
+ else
+ CC=arm-linux-gnueabi-gcc
+ fi
+ wget https://github.com/openssl/openssl/releases/download/openssl-3.3.1/openssl-3.3.1.tar.gz
+ tar -xzf openssl-3.3.1.tar.gz
+ cd openssl-3.3.1
+ ./Configure linux-generic32 --prefix=/usr/arm-linux-gnueabi --cross-compile-prefix=arm-linux-gnueabi- --release -latomic
+ make
+ sudo make install
+ fi
+ echo "CC=$CC" >> $GITHUB_ENV
+ - name: Build Debug Target
+ run: make debug
+ - name: Build Release Target
+ if: ${{ !cancelled() }}
+ run: make
+ - name: Build TLS Debug ARM64 Target
+ if: matrix.arch == 'arm64'
+ run: make WEBUI_USE_TLS=1 debug WEBUI_TLS_INCLUDE="/usr/aarch64-linux-gnu/include" WEBUI_TLS_LIB="/usr/aarch64-linux-gnu/lib"
+ - name: Build TLS Debug ARM Target
+ if: matrix.arch == 'arm'
+ run: make WEBUI_USE_TLS=1 debug WEBUI_TLS_INCLUDE="/usr/arm-linux-gnueabi/include" WEBUI_TLS_LIB="/usr/arm-linux-gnueabi/lib"
+ - name: Build TLS Release ARM64 Target
+ if: matrix.arch == 'arm64'
+ run: make WEBUI_USE_TLS=1 WEBUI_TLS_INCLUDE="/usr/aarch64-linux-gnu/include" WEBUI_TLS_LIB="/usr/aarch64-linux-gnu/lib"
+ - name: Build TLS Release ARM Target
+ if: matrix.arch == 'arm'
+ run: make WEBUI_USE_TLS=1 WEBUI_TLS_INCLUDE="/usr/arm-linux-gnueabi/include" WEBUI_TLS_LIB="/usr/arm-linux-gnueabi/lib"
+ # - name: Build Examples
+ # if: matrix.arch == 'arm64'
+ # run: |
+ # examples_base_dir=$(pwd)/examples/C
+ # for example in $(find $examples_base_dir/* -maxdepth 0 -type d); do
+ # echo "> $example"
+ # cd $example || (exit_code=1 && continue)
+ # if ! make CC=aarch64-linux-gnu-gcc; then
+ # echo "Failed to build '$example'"
+ # exit_code=1
+ # continue
+ # fi
+ # if [[ ! -e "main" || ! -e "main-dyn" ]] ; then
+ # echo "Failed to find executable for '$example'" && find .
+ # exit_code=1
+ # continue
+ # fi
+ # done
+ # exit $exit_code
+ - name: Prepare Artifact
+ run: |
+ cp -r include dist
+ mv dist/ "$ARTIFACT"
+ - name: Upload Artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ env.ARTIFACT }}
+ path: ${{ env.ARTIFACT }}
+ - name: Prepare Release
+ if: >
+ github.repository_owner == 'webui-dev'
+ && (github.ref_type == 'tag' || (github.ref_name == 'main' && github.event_name == 'push'))
+ run: |
+ zip -r "$ARTIFACT.zip" "$ARTIFACT"
+ if [ $GITHUB_REF_TYPE == tag ]; then
+ echo "TAG=$GITHUB_REF_NAME" >> $GITHUB_ENV
+ else
+ {
+ echo "IS_PRERELEASE=true";
+ echo "TAG=nightly";
+ echo "TITLE=WebUI Nightly Build $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
+ echo "BODY=Generated from commit $GITHUB_SHA."
+ } >> $GITHUB_ENV
+ fi
+ - name: Update Nightly Tag
+ if: env.IS_PRERELEASE
+ uses: richardsimko/update-tag@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: nightly
+ - name: Release
+ if: >
+ github.repository_owner == 'webui-dev'
+ && (github.ref_type == 'tag' || (github.ref_name == 'main' && github.event_name == 'push'))
+ uses: ncipollo/release-action@v1
+ with:
+ artifacts: ${{ env.ARTIFACT }}.zip
+ tag: ${{ env.TAG }}
+ body: ${{ env.BODY }}
+ name: ${{ env.TITLE }}
+ prerelease: ${{ env.IS_PRERELEASE }}
+ allowUpdates: true
diff --git a/.github/workflows/linux_redhat.yml b/.github/workflows/linux_redhat.yml
new file mode 100644
index 0000000..7cc0424
--- /dev/null
+++ b/.github/workflows/linux_redhat.yml
@@ -0,0 +1,113 @@
+# https://webui.me
+# https://github.com/webui-dev/webui
+# Copyright (c) 2020-2026 Hassan Draga.
+# Licensed under MIT License.
+# All rights reserved.
+# Canada.
+
+name: Linux-RedHat
+on:
+ workflow_call:
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ include:
+ - cc: gcc
+ arch: x64
+ - cc: clang
+ arch: x64
+ fail-fast: false
+ env:
+ ARTIFACT: webui-linux-redhat-${{ matrix.cc }}-${{ matrix.arch }}
+ CC: ${{ matrix.cc }}
+ steps:
+ - name: Check out the repository
+ uses: actions/checkout@v4
+
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v2
+
+ - name: Build RedHat Docker Image
+ run: |
+ docker build -t redhat:latest - <
+ github.repository_owner == 'webui-dev'
+ && (github.ref_type == 'tag' || (github.ref_name == 'main' && github.event_name == 'push'))
+ run: |
+ zip -r "$ARTIFACT.zip" "$ARTIFACT"
+ if [ $GITHUB_REF_TYPE == tag ]; then
+ echo "TAG=$GITHUB_REF_NAME" >> $GITHUB_ENV
+ else
+ {
+ echo "IS_PRERELEASE=true";
+ echo "TAG=nightly";
+ echo "TITLE=WebUI Nightly Build $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
+ echo "BODY=Generated from commit $GITHUB_SHA."
+ } >> $GITHUB_ENV
+ fi
+
+ - name: Update Nightly Tag
+ if: env.IS_PRERELEASE
+ uses: richardsimko/update-tag@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: nightly
+
+ - name: Release
+ if: >
+ github.repository_owner == 'webui-dev'
+ && (github.ref_type == 'tag' || (github.ref_name == 'main' && github.event_name == 'push'))
+ uses: ncipollo/release-action@v1
+ with:
+ artifacts: ${{ env.ARTIFACT }}.zip
+ tag: ${{ env.TAG }}
+ body: ${{ env.BODY }}
+ name: ${{ env.TITLE }}
+ prerelease: ${{ env.IS_PRERELEASE }}
+ allowUpdates: true
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
new file mode 100644
index 0000000..dc32640
--- /dev/null
+++ b/.github/workflows/macos.yml
@@ -0,0 +1,125 @@
+# https://webui.me
+# https://github.com/webui-dev/webui
+# Copyright (c) 2020-2026 Hassan Draga.
+# Licensed under MIT License.
+# All rights reserved.
+# Canada.
+#
+# Special Thanks to Turiiya (https://github.com/ttytm)
+
+name: macOS
+on:
+ workflow_call:
+
+jobs:
+ setup:
+ runs-on: macos-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Bundle WebUI Bridge
+ run: |
+ npm i -g esbuild
+ chmod +x bridge/build.sh
+ bridge/build.sh
+ - uses: actions/cache@v4
+ with:
+ path: bridge/webui_bridge.h
+ key: ${{ runner.os }}-${{ github.sha }}-bridge
+
+ build:
+ needs: setup
+ runs-on: macos-latest
+ permissions:
+ contents: write
+ strategy:
+ matrix:
+ cc: [clang]
+ arch: [x64, arm64]
+ fail-fast: false
+ env:
+ ARTIFACT: webui-macos-${{ matrix.cc }}-${{ matrix.arch }}
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/cache/restore@v4
+ with:
+ path: bridge/webui_bridge.h
+ key: ${{ runner.os }}-${{ github.sha }}-bridge
+ fail-on-cache-miss: true
+ - name: Setup OpenSSL
+ run: |
+ echo "WEBUI_TLS_INCLUDE=$(brew --cellar)/openssl@1.1/1.1.1w/include/" >> $GITHUB_ENV
+ echo "WEBUI_TLS_LIB=$(brew --cellar)/openssl@1.1/1.1.1w/lib/" >> $GITHUB_ENV
+ - name: Build Debug Target
+ run: make ARCH_TARGET=${{ matrix.arch }} debug
+ - name: Build Release Target
+ if: ${{ !cancelled() }}
+ run: make ARCH_TARGET=${{ matrix.arch }}
+ - name: Build TLS Debug Target
+ if: ${{ matrix.arch != 'x64' }}
+ run: make ARCH_TARGET=${{ matrix.arch }} WEBUI_USE_TLS=1 debug
+ - name: Build TLS Release Target
+ if: ${{ matrix.arch != 'x64' }}
+ run: make ARCH_TARGET=${{ matrix.arch }} WEBUI_USE_TLS=1
+ - name: Build examples
+ if: ${{ matrix.arch != 'x64' }}
+ run: |
+ examples_base_dir=$(pwd)/examples/C
+ for example in $(find $examples_base_dir/* -maxdepth 0 -type d); do
+ echo "> $example"
+ cd $example || (exit_code=1 && continue)
+ if ! make ARCH_TARGET=${{ matrix.arch }}; then
+ echo "Failed to build '$example'"
+ exit_code=1
+ continue
+ fi
+ if [[ ! -e "main" || ! -e "main-dyn" ]] ; then
+ echo "Failed to find executable for '$example'" && find .
+ exit_code=1
+ continue
+ fi
+ done
+ exit $exit_code
+ - name: Prepare Artifacts
+ run: |
+ cp -r include dist
+ mv dist/ "$ARTIFACT"
+ - name: Upload Artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ env.ARTIFACT }}
+ path: ${{ env.ARTIFACT }}
+ - name: Prepare Release
+ if: >
+ github.repository_owner == 'webui-dev'
+ && (github.ref_type == 'tag' || (github.ref_name == 'main' && github.event_name == 'push'))
+ run: |
+ zip -r "$ARTIFACT.zip" "$ARTIFACT"
+ if [ $GITHUB_REF_TYPE == tag ]; then
+ echo "TAG=$GITHUB_REF_NAME" >> $GITHUB_ENV
+ else
+ {
+ echo "IS_PRERELEASE=true";
+ echo "TAG=nightly";
+ echo "TITLE=WebUI Nightly Build $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
+ echo "BODY=Generated from commit $GITHUB_SHA."
+ } >> $GITHUB_ENV
+ fi
+ - name: Update Nightly Tag
+ if: env.IS_PRERELEASE
+ uses: richardsimko/update-tag@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: nightly
+ - name: Release
+ if: >
+ github.repository_owner == 'webui-dev'
+ && (github.ref_type == 'tag' || (github.ref_name == 'main' && github.event_name == 'push'))
+ uses: ncipollo/release-action@v1
+ with:
+ artifacts: ${{ env.ARTIFACT }}.zip
+ tag: ${{ env.TAG }}
+ body: ${{ env.BODY }}
+ name: ${{ env.TITLE }}
+ prerelease: ${{ env.IS_PRERELEASE }}
+ allowUpdates: true
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
new file mode 100644
index 0000000..30df206
--- /dev/null
+++ b/.github/workflows/windows.yml
@@ -0,0 +1,133 @@
+# https://webui.me
+# https://github.com/webui-dev/webui
+# Copyright (c) 2020-2026 Hassan Draga.
+# Licensed under MIT License.
+# All rights reserved.
+# Canada.
+#
+# Special Thanks to Turiiya (https://github.com/ttytm)
+
+name: Windows
+on:
+ workflow_call:
+
+jobs:
+ setup:
+ runs-on: windows-2022
+ steps:
+ - uses: actions/checkout@v4
+ - name: Bundle WebUI Bridge
+ run: bridge/build.bat
+ - uses: actions/cache@v4
+ with:
+ path: bridge/webui_bridge.h
+ key: ${{ runner.os }}-${{ github.sha }}-bridge
+
+ build:
+ needs: setup
+ runs-on: windows-2022
+ permissions:
+ contents: write
+ strategy:
+ matrix:
+ cc: ['gcc', 'msvc']
+ include:
+ - cc: gcc
+ make: mingw32-make
+ - cc: msvc
+ make: nmake
+ fail-fast: false
+ env:
+ ARTIFACT: webui-windows-${{ matrix.cc }}-x64
+ WEBUI_TLS_INCLUDE: "C:\\Program Files\\OpenSSL\\include"
+ WEBUI_TLS_LIB: "C:\\Program Files\\OpenSSL\\lib\\VC\\x64\\MD"
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/cache/restore@v4
+ with:
+ path: bridge/webui_bridge.h
+ key: ${{ runner.os }}-${{ github.sha }}-bridge
+ fail-on-cache-miss: true
+ - uses: microsoft/setup-msbuild@v2
+ - uses: ilammy/msvc-dev-cmd@v1
+ if: matrix.cc == 'msvc'
+ - name: Build Debug Target
+ run: ${{ matrix.make }} debug
+ - name: Build Release Target
+ if: ${{ !cancelled() }}
+ run: ${{ matrix.make }}
+ - name: Build TLS Debug Target
+ run: ${{ matrix.make }} WEBUI_USE_TLS=1 debug
+ - name: Build TLS Release Target
+ run: ${{ matrix.make }} WEBUI_USE_TLS=1
+ - name: Build examples
+ run: |
+ $examples_base_dir = "$(Get-Location)/examples/C/"
+ foreach ($example in Get-ChildItem -Path $examples_base_dir -Directory) {
+ Write-Host "> $example"
+ Set-Location -Path $example.FullName
+ if (!$?) {
+ $exit_code = 1
+ continue
+ }
+ $make_output = Invoke-Expression ${{ matrix.make }}
+ if (!$?) {
+ Write-Host "Failed to build '$example': $make_output"
+ $exit_code = 1
+ continue
+ }
+ Write-Output $make_output
+ if (!(Test-Path "main.exe") -or !(Test-Path "main-dyn.exe")) {
+ Write-Host "Failed to find executable for '$example'"
+ Get-ChildItem
+ $exit_code = 1
+ continue
+ }
+ }
+ exit $exit_code
+ - name: Prepare Artifact
+ shell: bash
+ run: |
+ cp -r include dist
+ mv dist/ "$ARTIFACT"
+ - name: Upload Artifact
+ uses: actions/upload-artifact@v4
+ with:
+ name: ${{ env.ARTIFACT }}
+ path: ${{ env.ARTIFACT }}
+ - name: Prepare Release
+ if: >
+ github.repository_owner == 'webui-dev'
+ && (github.ref_type == 'tag' || (github.ref_name == 'main' && github.event_name == 'push'))
+ shell: bash
+ run: |
+ 7z a -tzip "$ARTIFACT.zip" "$ARTIFACT/*"
+ if [ $GITHUB_REF_TYPE == tag ]; then
+ echo "TAG=$GITHUB_REF_NAME" >> $GITHUB_ENV
+ else
+ {
+ echo "IS_PRERELEASE=true";
+ echo "TAG=nightly";
+ echo "TITLE=WebUI Nightly Build $(date -u +'%Y-%m-%d %H:%M:%S UTC')"
+ echo "BODY=Generated from commit $GITHUB_SHA."
+ } >> $GITHUB_ENV
+ fi
+ - name: Update Nightly Tag
+ if: env.IS_PRERELEASE
+ uses: richardsimko/update-tag@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: nightly
+ - name: Release
+ if: >
+ github.repository_owner == 'webui-dev'
+ && (github.ref_type == 'tag' || (github.ref_name == 'main' && github.event_name == 'push'))
+ uses: ncipollo/release-action@v1
+ with:
+ artifacts: ${{ env.ARTIFACT }}.zip
+ tag: ${{ env.TAG }}
+ body: ${{ env.BODY }}
+ name: ${{ env.TITLE }}
+ prerelease: ${{ env.IS_PRERELEASE }}
+ allowUpdates: true
diff --git a/.github/workflows/zig.yml b/.github/workflows/zig.yml
new file mode 100644
index 0000000..e563a39
--- /dev/null
+++ b/.github/workflows/zig.yml
@@ -0,0 +1,36 @@
+name: Zig Build
+
+on:
+ workflow_call:
+
+jobs:
+ build:
+ strategy:
+ matrix:
+ os: [ubuntu-latest, macos-latest, windows-latest]
+ version: [0.14.0, 0.15.1]
+ fail-fast: false
+ runs-on: ${{ matrix.os }}
+ steps:
+ - uses: maxim-lobanov/setup-xcode@v1
+ if: runner.os == 'macOS'
+ with:
+ xcode-version: latest-stable
+ - uses: actions/checkout@v4
+ - name: Setup Zig
+ uses: goto-bus-stop/setup-zig@v2
+ with:
+ version: ${{ matrix.version }}
+ - name: Build static library
+ run: zig build -Dverbose=debug
+ - name: Build dynamic library
+ if: ${{ !cancelled() }}
+ run: zig build -Ddynamic -Dverbose=debug
+ - name: Build static library with TLS support
+ if: runner.os == 'Linux'
+ run: zig build -Denable-tls -Dverbose=debug
+ - name: Build dynamic library with TLS support
+ if: runner.os == 'Linux'
+ run: zig build -Ddynamic -Denable-tls -Dverbose=debug
+ - name: Build examples
+ run: zig build examples
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b2b7c6c
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,141 @@
+# Build
+build/
+*.exe
+*.ilk
+*.pdb
+*.exp
+*.res
+*.out
+*.def
+
+# All sub-level build binaries
+*/**/*
+!*/**/*/
+!*/**/*.*
+!*makefile
+!Makefile
+*/**/*.exe
+
+# Compiled Object files
+*.slo
+*.lo
+*.o
+*.obj
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Compiled Static libraries
+*.lai
+*.la
+*.a
+*.lib
+
+# Logs
+*.log
+*.logs
+*.tlog
+
+# IDE
+.vscode/
+.vs/
+
+# Visual Studio
+.idea/
+*.recipe
+*.idb
+*.iobj
+*.pdb
+
+# Visual Studio for Mac
+.idea/
+
+# Visual Studio cache files
+ipch/
+*.dbmdl
+*.dbproj.schemaview
+
+# Others
+.builds
+*~*
+*.cache
+*.swp
+*.bak
+*.tmp
+*.swp
+*.userosscache
+*.err
+*.vspscc
+*.vssscc
+*.pidb
+*.svclog
+*.scc
+
+# NuGet
+packages/
+!packages/repositories.config
+*.nupkg
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# User-specific files
+*.suo
+*.user
+*.userprefs
+*.sln.docstates
+
+# Python
+__pycache__/
+dist/
+webui2.egg-info/
+
+# Rust
+target/
+*.lock
+
+# Broken NTFS
+nul
+
+# Zig
+zig-cache/
+zig-out/
+
+# macOS
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+ehthumbs.db
+Thumbs.db
+
+# User-specific private settings
+*.DotSettings.user
+
+# Compressed
+*.zip
+*.gz
+
+# CMake
+**/cmake_install.cmake
+**/CMakeCache.txt
+**/CMakeFiles/
+CMakeUserPresets.json
+.zig-cache
+
+# Conan
+**/compressor
+**/conan-*
+**/cmake-build-*
+**/deactivate_conanbuildenv*
+
+# vcpkg
+vcpkg-manifest-install.log
+vcpkg_installed/
+/.claude
+CLAUDE.md
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..f4378ee
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,192 @@
+cmake_minimum_required(VERSION 3.18)
+
+# Project name
+project(WebUILibrary
+ VERSION 2.5.0
+ DESCRIPTION "Use any web browser or WebView as GUI, with your preferred language in the backend and modern web technologies in the frontend, all in a lightweight portable library."
+ HOMEPAGE_URL "https://webui.me/")
+
+# Set C & C++ standard
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_C_STANDARD_REQUIRED ON)
+
+
+# In order to be able to link with other shared libraries on Linux we may need `-fPIC`.
+if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ # using Clang
+ add_compile_options(-fPIC)
+elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ # using GCC
+ add_compile_options(-fPIC)
+elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
+ # using Intel C++
+elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+ # using Visual Studio C++
+endif()
+
+# Variables for library names, source files, etc.
+set(WEBUI_DEFAULT_OUT_LIB_NAME "webui-2")
+
+# Conditional compilation for TLS
+option(WEBUI_USE_TLS "Enable TLS support" OFF)
+if (WEBUI_USE_TLS)
+ find_package(OpenSSL REQUIRED)
+ set(WEBUI_DEFAULT_OUT_LIB_NAME "webui-2-secure")
+endif()
+
+# Option to build example projects
+option(WEBUI_BUILD_EXAMPLES "Build WebUI examples" ON)
+
+if (NOT BUILD_SHARED_LIBS)
+ set(WEBUI_DEFAULT_OUT_LIB_NAME "${WEBUI_DEFAULT_OUT_LIB_NAME}-static")
+endif()
+
+# Output library name
+set(WEBUI_OUT_LIB_NAME "${WEBUI_DEFAULT_OUT_LIB_NAME}" CACHE STRING "Name of the output library")
+
+# Source files (already filled)
+set(SOURCE_FILES
+ src/civetweb/civetweb.c
+ src/webui.c
+)
+
+if (WIN32)
+ list(APPEND SOURCE_FILES src/webview/win32_wv2.cpp)
+endif()
+
+if (APPLE)
+ # enable macos webview
+ enable_language(OBJC)
+ set(CMAKE_OBJC_STANDARD 11)
+ list(APPEND SOURCE_FILES src/webview/wkwebview.m)
+endif()
+
+# Library targets
+add_library(webui ${SOURCE_FILES})
+target_include_directories(webui PUBLIC $ $)
+target_compile_definitions(webui PUBLIC NO_CACHING NO_CGI USE_WEBSOCKET
+ "$<$:WEBUI_LOG>" "$<$>:NDEBUG>")
+
+if (BUILD_SHARED_LIBS AND WIN32)
+ target_compile_definitions(webui PRIVATE CIVETWEB_DLL_EXPORTS PUBLIC CIVETWEB_DLL_IMPORTS)
+endif()
+
+if (WEBUI_USE_TLS)
+ target_compile_definitions(webui PUBLIC WEBUI_TLS NO_SSL_DL OPENSSL_API_1_1)
+ target_link_libraries(webui PRIVATE OpenSSL::SSL OpenSSL::Crypto)
+else()
+ target_compile_definitions(webui PUBLIC NO_SSL)
+endif()
+
+if (WIN32)
+ target_link_libraries(webui PRIVATE ws2_32 user32 shell32 ole32)
+elseif (APPLE)
+ # link required frameworks
+ find_library(COCOA_FRAMEWORK Cocoa REQUIRED)
+ find_library(WEBKIT_FRAMEWORK WebKit REQUIRED)
+
+ target_link_libraries(webui PRIVATE ${COCOA_FRAMEWORK} ${WEBKIT_FRAMEWORK})
+endif()
+
+set_target_properties(webui PROPERTIES
+ OUTPUT_NAME ${WEBUI_OUT_LIB_NAME})
+
+# Install headers
+install(FILES include/webui.h include/webui.hpp DESTINATION include)
+
+# Install targets
+install(TARGETS webui
+ EXPORT webui
+ ARCHIVE DESTINATION lib
+ LIBRARY DESTINATION lib
+ RUNTIME DESTINATION bin)
+
+install(EXPORT webui
+ FILE webui-config.cmake
+ NAMESPACE webui::
+ DESTINATION share/webui
+)
+
+
+#//////////////////////////
+# Build examples
+#//////////////////////////
+
+if (WEBUI_BUILD_EXAMPLES)
+ message(STATUS "WebUI Source directory is " ${CMAKE_CURRENT_SOURCE_DIR})
+ message(STATUS "WebUI Build directory is " ${CMAKE_BINARY_DIR})
+
+ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+
+ # C++ examples
+ add_executable(minimal_cpp ${CMAKE_CURRENT_SOURCE_DIR}/examples/C++/minimal/main.cpp)
+ add_executable(call_js_from_cpp ${CMAKE_CURRENT_SOURCE_DIR}/examples/C++/call_js_from_cpp/main.cpp)
+ add_executable(call_cpp_from_js ${CMAKE_CURRENT_SOURCE_DIR}/examples/C++/call_cpp_from_js/main.cpp)
+ add_executable(serve_a_folder_cpp ${CMAKE_CURRENT_SOURCE_DIR}/examples/C++/serve_a_folder/main.cpp)
+ add_executable(virtual_file_system_cpp ${CMAKE_CURRENT_SOURCE_DIR}/examples/C++/virtual_file_system/main.cpp)
+ add_executable(test_index_redirect_cpp ${CMAKE_CURRENT_SOURCE_DIR}/examples/C++/test_index_redirect/main.cpp)
+
+ # C examples
+ add_executable(minimal_c ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/minimal/main.c)
+ add_executable(call_js_from_c ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/call_js_from_c/main.c)
+ add_executable(call_c_from_js ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/call_c_from_js/main.c)
+ add_executable(serve_a_folder_c ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/serve_a_folder/main.c)
+ add_executable(virtual_file_system_c ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/virtual_file_system/main.c)
+ add_executable(test_index_redirect_c ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/test_index_redirect/main.c)
+ add_executable(public_network_access ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/public_network_access/main.c)
+ add_executable(web_app_multi_client ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/web_app_multi_client/main.c)
+ add_executable(chatgpt_api ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/chatgpt_api/main.c)
+ add_executable(custom_web_server ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/custom_web_server/main.c)
+ add_executable(react ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/react/main.c)
+ add_executable(frameless ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/frameless/main.c)
+ add_executable(text_editor ${CMAKE_CURRENT_SOURCE_DIR}/examples/C/text-editor/main.c)
+
+ target_link_libraries(minimal_cpp webui)
+ target_link_libraries(call_js_from_cpp webui)
+ target_link_libraries(call_cpp_from_js webui)
+ target_link_libraries(serve_a_folder_cpp webui)
+ target_link_libraries(virtual_file_system_cpp webui)
+ target_link_libraries(test_index_redirect_cpp webui)
+
+ target_link_libraries(minimal_c webui)
+ target_link_libraries(call_js_from_c webui)
+ target_link_libraries(call_c_from_js webui)
+ target_link_libraries(serve_a_folder_c webui)
+ target_link_libraries(virtual_file_system_c webui)
+ target_link_libraries(test_index_redirect_c webui)
+ target_link_libraries(public_network_access webui)
+ target_link_libraries(web_app_multi_client webui)
+ target_link_libraries(chatgpt_api webui)
+ target_link_libraries(custom_web_server webui)
+ target_link_libraries(react webui)
+ target_link_libraries(frameless webui)
+ target_link_libraries(text_editor webui)
+
+ if (MSVC)
+ set_target_properties(minimal_cpp PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(call_js_from_cpp PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(call_cpp_from_js PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(serve_a_folder_cpp PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(virtual_file_system_cpp PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(test_index_redirect_cpp PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(minimal_c PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(call_js_from_c PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(call_c_from_js PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(serve_a_folder_c PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(virtual_file_system_c PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(test_index_redirect_c PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(public_network_access PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(web_app_multi_client PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(chatgpt_api PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(custom_web_server PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(react PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(frameless PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ set_target_properties(text_editor PROPERTIES LINK_FLAGS "/SubSystem:\"Windows\"" VS_DPI_AWARE "ON")
+ endif()
+
+ if (MSVC)
+ set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT call_js_from_cpp)
+ endif()
+endif()
diff --git a/GNUmakefile b/GNUmakefile
new file mode 100644
index 0000000..daedcf7
--- /dev/null
+++ b/GNUmakefile
@@ -0,0 +1,218 @@
+# WebUI Library
+
+# == 1. VARIABLES =============================================================
+
+WEBUI_OUT_LIB_NAME = webui-2
+
+# Detect the OS once
+ifeq ($(OS),Windows_NT)
+DETECTED_OS := Windows
+else
+DETECTED_OS := $(shell uname -s)
+endif
+
+# TLS
+WEBUI_USE_TLS =
+WEBUI_TLS_INCLUDE ?= .
+WEBUI_TLS_LIB ?= .
+TLS_CFLAG = -DNO_SSL
+TLS_LDFLAG_DYNAMIC =
+ifeq ($(WEBUI_USE_TLS), 1)
+WEBUI_OUT_LIB_NAME = webui-2-secure
+TLS_CFLAG = -DWEBUI_TLS -DNO_SSL_DL -DOPENSSL_API_1_1
+ifeq ($(DETECTED_OS),Windows)
+TLS_LDFLAG_DYNAMIC = -lssl -lcrypto -lbcrypt
+else
+TLS_LDFLAG_DYNAMIC = -lssl -lcrypto
+endif
+endif
+
+MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
+MAKEFILE_DIR := $(dir $(MAKEFILE_PATH))
+BUILD_DIR := $(MAKEFILE_DIR)/dist
+
+# ARGS
+CC ?= gcc
+ifeq ($(CC), cc)
+ ifeq ($(DETECTED_OS),Darwin)
+ CC = clang
+ else
+ CC = gcc
+ endif
+endif
+
+# Allow to add arch-target for macOS CI cross compilation
+ARCH_TARGET ?=
+
+# BUILD FLAGS
+CIVETWEB_BUILD_FLAGS := -o civetweb.o -I"$(MAKEFILE_DIR)/include/" -c "$(MAKEFILE_DIR)/src/civetweb/civetweb.c" -I"$(WEBUI_TLS_INCLUDE)" $(TLS_CFLAG) -w
+CIVETWEB_DEFINE_FLAGS = -DNDEBUG -DNO_CACHING -DNO_CGI -DUSE_WEBSOCKET $(TLS_CFLAG)
+WEBUI_BUILD_FLAGS := -o webui.o -I"$(MAKEFILE_DIR)/include/" -c "$(MAKEFILE_DIR)/src/webui.c" -I"$(WEBUI_TLS_INCLUDE)" $(TLS_CFLAG)
+WIN32_WV2_BUILD_FLAGS := -o win32_wv2.o -I"$(MAKEFILE_DIR)/include/" -c "$(MAKEFILE_DIR)/src/webview/win32_wv2.cpp" -I"$(WEBUI_TLS_INCLUDE)" $(TLS_CFLAG)
+WARNING_RELEASE := -w
+WARNING_LOG := -Wall -Wno-unused
+
+# OUTPUT FILES
+# The static output is the same for all platforms
+# The dynamic output is platform dependent
+LIB_STATIC_OUT := lib$(WEBUI_OUT_LIB_NAME)-static.a
+
+# Platform defaults and dynamic library outputs
+ifeq ($(DETECTED_OS),Windows)
+ # Windows
+ SHELL := CMD
+ PLATFORM := windows
+ LIB_DYN_OUT := $(WEBUI_OUT_LIB_NAME).dll
+ LWS2_OPT := -lws2_32 -lole32
+ WIN32_WV2_OBJ := win32_wv2.o
+ CPP_FLAGS := -lstdc++ -luuid
+ CIVETWEB_DEFINE_FLAGS += -DMUST_IMPLEMENT_CLOCK_GETTIME
+ CXX ?= g++
+else ifeq ($(DETECTED_OS),Darwin)
+ # MacOS
+ PLATFORM := macos
+ CC = clang
+ LIB_DYN_OUT := lib$(WEBUI_OUT_LIB_NAME).dylib
+ WEBKIT_OBJ := wkwebview.o
+ CPP_FLAGS :=
+ WKWEBKIT_BUILD_FLAGS := -o wkwebview.o -c "$(MAKEFILE_DIR)/src/webview/wkwebview.m"
+ WKWEBKIT_LINK_FLAGS := -framework Cocoa -framework WebKit
+else
+ # Linux
+ PLATFORM := linux
+ LIB_DYN_OUT := lib$(WEBUI_OUT_LIB_NAME).so
+ CPP_FLAGS :=
+ ifeq ($(CC),clang)
+ LLVM_OPT := llvm-
+ endif
+endif
+
+# macOS can set `ARCH_TARGET=arm64` for cross-compilation.
+ifneq ($(ARCH_TARGET),)
+ ifneq ($(PLATFORM),macos)
+ $(error ARCH_TARGET is only available on macOS)
+ endif
+ ifeq ($(ARCH_TARGET),arm64)
+ TARGET := -target arm64-apple-darwin -arch arm64
+ else ifeq ($(ARCH_TARGET),x64)
+ TARGET := -target x86_64-apple-darwin -arch x86_64
+ else
+ $(error Unsupported ARCH_TARGET: $(ARCH_TARGET). Use 'arm64' or 'x64'.)
+ endif
+endif
+
+# == 2.TARGETS ================================================================
+
+all: release
+
+debug: --debug
+
+release: --release
+
+clean: --clean-$(PLATFORM)
+
+# == 2.1 INTERNAL TARGETS =====================================================
+
+--debug:
+# Create build directory
+ifeq ($(PLATFORM),windows)
+ @mkdir "$(BUILD_DIR)/debug" >nul 2>&1 ||:
+else
+ @mkdir -p "$(BUILD_DIR)/debug"
+endif
+# Build macOS WKWebView
+ifeq ($(DETECTED_OS),Darwin)
+ @cd "$(BUILD_DIR)/debug" \
+ && echo "Build WebUI Objective-C WKWebKit ($(CC) $(TARGET) debug)..." \
+ && $(CC) $(TARGET) $(WKWEBKIT_BUILD_FLAGS) -g -DWEBUI_LOG
+endif
+# Build Win32 WebView2 C++
+ifeq ($(DETECTED_OS),Windows)
+ @cd "$(BUILD_DIR)/debug" \
+ && echo "Build WebUI Win32 WebView2 ($(CXX) $(TARGET) debug)..." \
+ && $(CXX) $(TARGET) $(WIN32_WV2_BUILD_FLAGS) $(WARNING_LOG) -g -DWEBUI_LOG
+endif
+# Static with Debug info
+ @cd "$(BUILD_DIR)/debug" \
+ && echo "Build WebUI library ($(CC) $(TARGET) debug static)..." \
+ && $(CC) $(TARGET) $(CIVETWEB_BUILD_FLAGS) $(CIVETWEB_DEFINE_FLAGS) -g \
+ && $(CC) $(TARGET) $(WEBUI_BUILD_FLAGS) $(WARNING_LOG) -g -DWEBUI_LOG \
+ && $(LLVM_OPT)ar rc $(LIB_STATIC_OUT) webui.o civetweb.o $(WEBKIT_OBJ) $(WIN32_WV2_OBJ) \
+ && $(LLVM_OPT)ranlib $(LIB_STATIC_OUT)
+# Dynamic with Debug info
+ @cd "$(BUILD_DIR)/debug" \
+ && echo "Build WebUI library ($(CC) $(TARGET) debug dynamic)..." \
+ && $(CC) $(TARGET) $(CIVETWEB_BUILD_FLAGS) $(CIVETWEB_DEFINE_FLAGS) -g -fPIC \
+ && $(CC) $(TARGET) $(WEBUI_BUILD_FLAGS) $(WARNING_LOG) -g -fPIC -DWEBUI_LOG -DWEBUI_DYNAMIC \
+ && $(CC) $(TARGET) -shared -o $(LIB_DYN_OUT) webui.o civetweb.o $(WEBKIT_OBJ) $(WIN32_WV2_OBJ) -g -L"$(WEBUI_TLS_LIB)" $(TLS_LDFLAG_DYNAMIC) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) $(CPP_FLAGS)
+ifeq ($(PLATFORM),windows)
+ @cd "$(BUILD_DIR)/debug" && del *.o >nul 2>&1
+else
+ @rm -f $(BUILD_DIR)/debug/*.o
+endif
+ @echo "Done."
+
+--release:
+# Create build directory
+ifeq ($(PLATFORM),windows)
+ @mkdir "$(BUILD_DIR)" >nul 2>&1 ||:
+else
+ @mkdir -p "$(BUILD_DIR)"
+endif
+# Build macOS WKWebView
+ifeq ($(DETECTED_OS),Darwin)
+ @cd "$(BUILD_DIR)" \
+ && echo "Build WebUI Objective-C WKWebKit ($(CC) $(TARGET) release)..." \
+ && $(CC) $(TARGET) $(WKWEBKIT_BUILD_FLAGS) -Os
+endif
+# Build Win32 WebView2 C++
+ifeq ($(DETECTED_OS),Windows)
+ @cd "$(BUILD_DIR)" \
+ && echo "Build WebUI Win32 WebView2 ($(CXX) $(TARGET) release)..." \
+ && $(CXX) $(TARGET) $(WIN32_WV2_BUILD_FLAGS) $(WARNING_RELEASE) -Os
+endif
+# Static Release
+ @cd "$(BUILD_DIR)" \
+ && echo "Build WebUI library ($(CC) $(TARGET) release static)..." \
+ && $(CC) $(TARGET) $(CIVETWEB_BUILD_FLAGS) $(CIVETWEB_DEFINE_FLAGS) -Os \
+ && $(CC) $(TARGET) $(WEBUI_BUILD_FLAGS) $(WARNING_RELEASE) -Os \
+ && $(LLVM_OPT)ar rc $(LIB_STATIC_OUT) webui.o civetweb.o $(WEBKIT_OBJ) $(WIN32_WV2_OBJ) \
+ && $(LLVM_OPT)ranlib $(LIB_STATIC_OUT)
+# Dynamic Release
+ @cd "$(BUILD_DIR)" \
+ && echo "Build WebUI library ($(CC) $(TARGET) release dynamic)..." \
+ && $(CC) $(TARGET) $(CIVETWEB_BUILD_FLAGS) $(CIVETWEB_DEFINE_FLAGS) -Os -fPIC \
+ && $(CC) $(TARGET) $(WEBUI_BUILD_FLAGS) $(WARNING_RELEASE) -O3 -fPIC -DWEBUI_DYNAMIC \
+ && $(CC) $(TARGET) -shared -o $(LIB_DYN_OUT) webui.o civetweb.o $(WEBKIT_OBJ) $(WIN32_WV2_OBJ) -L"$(WEBUI_TLS_LIB)" $(TLS_LDFLAG_DYNAMIC) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) $(CPP_FLAGS)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @strip --strip-unneeded $(BUILD_DIR)/$(LIB_DYN_OUT)
+ @cd "$(BUILD_DIR)" && del *.o >nul 2>&1
+else
+ @rm -f $(BUILD_DIR)/*.o
+endif
+ @echo "Done."
+
+# PLATFROM CLEAN TARGETS
+
+--clean-linux: --clean-unix
+
+--clean-macos: --clean-unix
+
+--clean-unix:
+ @- cd "$(BUILD_DIR)" \
+ && rm -f *.o \
+ && rm -f *.so \
+ && rm -f *.dylib \
+ && rm -f *.a
+
+--clean-windows:
+ @- cd "$(BUILD_DIR)" \
+ && del *.a >nul 2>&1 \
+ && del *.o >nul 2>&1 \
+ && del *.dll >nul 2>&1 \
+ && del *.obj >nul 2>&1 \
+ && del *.ilk >nul 2>&1 \
+ && del *.pdb >nul 2>&1 \
+ && del *.lib >nul 2>&1 \
+ && del *.exp >nul 2>&1
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7b9eb01
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 Hassan Draga
+
+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/Makefile b/Makefile
new file mode 100644
index 0000000..5925b53
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,97 @@
+# WebUI Library
+# Windows - Microsoft Visual C
+
+# == 1. VARIABLES =============================================================
+
+WEBUI_OUT_LIB_NAME = webui-2
+TLS_CFLAG = /DNO_SSL
+
+# TLS Enabled
+!IF "$(WEBUI_USE_TLS)" == "1"
+
+WEBUI_OUT_LIB_NAME = webui-2-secure
+TLS_CFLAG = /DWEBUI_TLS /DNO_SSL_DL /DOPENSSL_API_1_1
+TLS_LDFLAG_DYNAMIC = libssl.lib libcrypto.lib
+
+!IF "$(WEBUI_TLS_INCLUDE)" != ""
+TLS_CFLAG = $(TLS_CFLAG) /I"$(WEBUI_TLS_INCLUDE)"
+!ELSE
+TLS_CFLAG = $(TLS_CFLAG) /I"."
+!ENDIF
+
+!IF "$(WEBUI_TLS_LIB)" != ""
+TLS_LDFLAG_DYNAMIC = $(TLS_LDFLAG_DYNAMIC) /LIBPATH:"$(WEBUI_TLS_LIB)"
+!ELSE
+TLS_LDFLAG_DYNAMIC += $(TLS_LDFLAG_DYNAMIC) /LIBPATH:"."
+!ENDIF
+
+!ENDIF
+
+# Build Flags
+CIVETWEB_BUILD_FLAGS = /Fo"civetweb.obj" /c /EHsc "$(MAKEDIR)/src/civetweb/civetweb.c" /I"$(MAKEDIR)/src/civetweb/" $(TLS_CFLAG)
+CIVETWEB_DEFINE_FLAGS = /D NDEBUG /D NO_CACHING /D NO_CGI /D USE_WEBSOCKET
+WEBUI_BUILD_FLAGS = /Fo"webui.obj" /c /EHsc "$(MAKEDIR)/src/webui.c" /I"$(MAKEDIR)/include" /I"$(MAKEDIR)/src/webview" /I"$(WEBUI_TLS_INCLUDE)" $(TLS_CFLAG)
+WIN32_WV2_BUILD_FLAGS = /Fo"win32_wv2.obj" /c /EHsc "$(MAKEDIR)/src/webview/win32_wv2.cpp" /I"$(MAKEDIR)/include" /I"$(MAKEDIR)/src/webview" /I"$(WEBUI_TLS_INCLUDE)" $(TLS_CFLAG)
+WARNING_RELEASE = /w
+WARNING_LOG = /W4
+
+# Output Commands
+LIB_STATIC_OUT = /OUT:"$(WEBUI_OUT_LIB_NAME)-static.lib" "webui.obj" "civetweb.obj" "win32_wv2.obj"
+LIB_DYN_OUT = /DLL /OUT:"$(WEBUI_OUT_LIB_NAME).dll" "webui.obj" "civetweb.obj" "win32_wv2.obj" user32.lib Advapi32.lib Shell32.lib Ole32.lib $(TLS_LDFLAG_DYNAMIC)
+
+# == 2.TARGETS ================================================================
+
+all: release
+
+debug:
+ @- mkdir dist\debug >nul 2>&1
+# Static with Debug info
+ @- cd $(MAKEDIR)/dist/debug
+ @echo Build WebUI Library (MSVC Debug Static)...
+ @cl /Zl /Zi $(CIVETWEB_BUILD_FLAGS) $(CIVETWEB_DEFINE_FLAGS)
+ @cl /Zl /Zi $(WEBUI_BUILD_FLAGS) $(WARNING_LOG) /D WEBUI_LOG
+ @cl /Zl /Zi $(WIN32_WV2_BUILD_FLAGS) $(WARNING_LOG) /D WEBUI_LOG
+ @lib $(LIB_STATIC_OUT)
+# Dynamic with Debug info
+ @echo Build WebUI Library (MSVC Debug Dynamic)...
+ @cl /Zi $(CIVETWEB_BUILD_FLAGS) $(CIVETWEB_DEFINE_FLAGS)
+ @cl /Zi $(WEBUI_BUILD_FLAGS) $(WARNING_LOG) /D WEBUI_LOG /D WEBUI_DYNAMIC
+ @cl /Zi $(WIN32_WV2_BUILD_FLAGS) $(WARNING_LOG) /D WEBUI_LOG /D WEBUI_DYNAMIC
+ @link $(LIB_DYN_OUT)
+# Clean
+ @- del *.obj >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.exp >nul 2>&1
+ @echo Done.
+
+release:
+ @- mkdir dist >nul 2>&1
+ @- cd $(MAKEDIR)/dist
+# Static Release
+ @echo Build WebUI Library (MSVC Release Static)...
+ @cl /Zl $(CIVETWEB_BUILD_FLAGS) $(CIVETWEB_DEFINE_FLAGS)
+ @cl /Zl $(WEBUI_BUILD_FLAGS) $(WARNING_RELEASE)
+ @cl /Zl $(WIN32_WV2_BUILD_FLAGS) $(WARNING_RELEASE)
+ @lib $(LIB_STATIC_OUT)
+# Dynamic Release
+ @echo Build WebUI Library (MSVC Release Dynamic)...
+ @cl $(CIVETWEB_BUILD_FLAGS) $(CIVETWEB_DEFINE_FLAGS)
+ @cl $(WEBUI_BUILD_FLAGS) $(WARNING_RELEASE) /D WEBUI_DYNAMIC
+ @cl $(WIN32_WV2_BUILD_FLAGS) $(WARNING_RELEASE) /D WEBUI_DYNAMIC
+ @link $(LIB_DYN_OUT)
+# Clean
+ @- del *.pdb >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.exp >nul 2>&1
+ @- echo Done.
+
+clean:
+ @- cd $(BUILD_DIR)
+ @- del *.pdb >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.exp >nul 2>&1
+ @- del *.dll >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- echo Done.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..d449444
--- /dev/null
+++ b/README.md
@@ -0,0 +1,317 @@
+
+
+
+
+# WebUI v2.5.0-beta.4
+
+[build-status]: https://img.shields.io/github/actions/workflow/status/webui-dev/webui/ci.yml?branch=main&style=for-the-badge&logo=githubactions&labelColor=414868&logoColor=C0CAF5
+[last-commit]: https://img.shields.io/github/last-commit/webui-dev/webui?style=for-the-badge&logo=github&logoColor=C0CAF5&labelColor=414868
+[release-version]: https://img.shields.io/github/v/tag/webui-dev/webui?style=for-the-badge&logo=webtrees&logoColor=C0CAF5&labelColor=414868&color=7664C6
+[license]: https://img.shields.io/github/license/webui-dev/webui?style=for-the-badge&logo=opensourcehardware&label=License&logoColor=C0CAF5&labelColor=414868&color=8c73cc
+
+[![][build-status]](https://github.com/webui-dev/webui/actions?query=branch%3Amain)
+[![][last-commit]](https://github.com/webui-dev/webui/pulse)
+[![][release-version]](https://github.com/webui-dev/webui/releases/latest)
+[![][license]](https://github.com/webui-dev/webui/blob/main/LICENSE)
+
+> Use any web browser or WebView as GUI, with your preferred language in the backend and modern web technologies in the frontend, all in a lightweight portable library.
+
+
+
+
+
+
+
+
+
+
+
+
+
+### _Ask AI Any Question About the WebUI_
+
+### [WebUI GPT - C/C++](https://chatgpt.com/g/g-685b01d42208819185a5a7c8ed74fa23-webui-c-c)
+
+
+
+## Download
+
+- [Latest Stable Release](https://github.com/webui-dev/webui/releases)
+- [Nightly Build](https://github.com/webui-dev/webui/releases/tag/nightly)
+
+## Contents
+
+- [Features](#features)
+- [Showcase](#showcase)
+- [UI & The Web Technologies](#ui--the-web-technologies)
+- [Documentation](#documentation)
+- [Build](#build)
+- [Examples](#examples)
+- [Wrappers](#wrappers)
+- [Supported Web Browsers](#supported-web-browsers)
+- [License](#license)
+
+## Features
+
+- Portable (*Needs only a web browser or a WebView at runtime*)
+- One header file
+- Lightweight (*Few Kb library*) & Small memory footprint
+- Fast binary communication protocol
+- Multi-platform & Multi-Browser
+- Using private profile for safety
+- Cross-platform WebView
+
+## UI & The Web Technologies
+
+[Borislav Stanimirov](https://ibob.bg/) discusses using HTML5 in the web browser as GUI at the [C++ Conference 2019 (_YouTube_)](https://www.youtube.com/watch?v=bbbcZd4cuxg).
+
+
+
+
+
+
+
+Web application UI design is not just about how a product looks but how it works. Using web technologies in your UI makes your product modern and professional, And a well-designed web application will help you make a solid first impression on potential customers. Great web application design also assists you in nurturing leads and increasing conversions. In addition, it makes navigating and using your web app easier for your users.
+
+### Why Use Web Browsers?
+
+Today's web browsers have everything a modern UI needs. Web browsers are very sophisticated and optimized. Therefore, using it as a GUI will be an excellent choice. While old legacy GUI lib is complex and outdated, a WebView-based app is still an option. However, a WebView needs a huge SDK to build and many dependencies to run, and it can only provide some features like a real web browser. That is why WebUI uses real web browsers to give you full features of comprehensive web technologies while keeping your software lightweight and portable.
+
+### How Does it Work?
+
+
+
+
+
+
+
+Think of WebUI like a WebView controller, but instead of embedding the WebView controller in your program, which makes the final program big in size, and non-portable as it needs the WebView runtimes. Instead, by using WebUI, you use a tiny static/dynamic library to run any installed web browser and use it as GUI, which makes your program small, fast, and portable. **All it needs is a web browser**.
+
+### Runtime Dependencies Comparison
+
+| | Tauri / WebView | Qt | WebUI |
+| ------------------------------- | ----------------- | -------------------------- | ------------------- |
+| Runtime Dependencies on Windows | _WebView2_ | _QtCore, QtGui, QtWidgets_ | **_A Web Browser_** |
+| Runtime Dependencies on Linux | _GTK3, WebKitGTK_ | _QtCore, QtGui, QtWidgets_ | **_A Web Browser_** |
+| Runtime Dependencies on macOS | _Cocoa, WebKit_ | _QtCore, QtGui, QtWidgets_ | **_A Web Browser_** |
+
+## Documentation
+
+> **Note**
+> We are currently writing documentation.
+
+- [Online Documentation](https://webui.me/docs/)
+
+## Build WebUI Library
+
+### Windows
+
+| Compiler | Command |
+|----------|---------|
+| GCC | `mingw32-make` |
+| MSVC | `nmake` |
+
+
+ Windows SSL/TLS (Optional)
+
+ Download and install the OpenSSL pre-compiled binaries for Windows:
+
+ - **MSVC**: [x64 OpenSSL v3.3.1](https://slproweb.com/download/Win64OpenSSL-3_3_1.msi) or [_32Bit_](https://slproweb.com/download/Win32OpenSSL-3_3_1.msi). See the [Wiki list](https://wiki.openssl.org/index.php/Binaries) for more info.
+ - **MinGW**: [Curl for Windows with OpenSSL](https://curl.se/windows/)
+
+ ```powershell
+ # GCC
+ mingw32-make WEBUI_USE_TLS=1 WEBUI_TLS_INCLUDE="C:\curl-xxx-xxx-mingw\curl-xxx-xxx-mingw\include" WEBUI_TLS_LIB="C:\curl-xxx-xxx-mingw\curl-xxx-xxx-mingw\lib"
+
+ # MSVC
+ nmake WEBUI_USE_TLS=1 WEBUI_TLS_INCLUDE="C:\Program Files\OpenSSL-xxx\include" WEBUI_TLS_LIB="C:\Program Files\OpenSSL-xxx\lib"
+ ```
+
+
+### Linux
+
+| Compiler | Command |
+|----------|---------|
+| GCC | `make` |
+| Clang | `make CC=clang` |
+
+
+ Linux SSL/TLS (Optional)
+
+ ```sh
+ sudo apt update
+ sudo apt install libssl-dev
+
+ # GCC
+ make WEBUI_USE_TLS=1
+
+ # Clang
+ make WEBUI_USE_TLS=1 CC=clang
+ ```
+
+
+### macOS
+
+| Compiler | Command |
+|----------|---------|
+| Default | `make` |
+
+
+ macOS SSL/TLS (Optional)
+
+ ```sh
+ brew install openssl
+ make WEBUI_USE_TLS=1
+ ```
+
+
+## Minimal WebUI Application
+
+- **C**
+
+ ```c
+ #include "webui.h"
+
+ int main() {
+ size_t my_window = webui_new_window();
+ webui_show(my_window, " Hello World ! ");
+ webui_wait();
+ return 0;
+ }
+ ```
+
+- **C++**
+
+ ```cpp
+ #include "webui.hpp"
+ #include
+
+ int main() {
+ webui::window my_window;
+ my_window.show(" C++ Hello World ! ");
+ webui::wait();
+ return 0;
+ }
+ ```
+
+- **More C/C++ Examples**
+
+ - [C](https://github.com/webui-dev/webui/tree/main/examples/C)
+ - [C++](https://github.com/webui-dev/webui/tree/main/examples/C++)
+
+- **Other Languages**
+
+ - [Wrappers List](#Wrappers)
+
+## Build WebUI Application
+
+### Windows
+
+| Compiler | Type | Command |
+|----------|--------|---------|
+| GCC | Static | `gcc -Os -Wl,-subsystem=windows my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" -lwebui-2-static -lws2_32 -Wall -luser32 -static -lole32 -lstdc++ -luuid -o my_application.exe` |
+| GCC | Dynamic | `gcc -Wl,-subsystem=windows my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" "webui-2.dll" -lws2_32 -Wall -luser32 -lole32 -o -lstdc++ -luuid my_application.exe` |
+| MSVC | Static | `cl my_application.c /I"_PATH_TO_WEBUI_INCLUDE_" /link /LIBPATH:"_PATH_TO_WEBUI_LIB_" /SUBSYSTEM:WINDOWS webui-2-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:my_application.exe` |
+| MSVC | Dynamic | `cl my_application.c /I"_PATH_TO_WEBUI_INCLUDE_" /link /LIBPATH:"_PATH_TO_WEBUI_LIB_" /SUBSYSTEM:WINDOWS webui-2.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:my_application.exe` |
+
+
+ Windows With SSL/TLS (Optional)
+
+ | Compiler | Type | Command |
+ |----------|--------|---------|
+ | GCC | Static | `gcc -Os -Wl,-subsystem=windows my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" -lwebui-2-secure-static -lws2_32 -Wall -luser32 -static -lole32 -lstdc++ -luuid -o my_application.exe` |
+ | GCC | Dynamic | `gcc -Wl,-subsystem=windows my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" "webui-2-secure.dll" -lws2_32 -Wall -luser32 -lole32 -lstdc++ -luuid -o my_application.exe` |
+ | MSVC | Static | `cl my_application.c /I"_PATH_TO_WEBUI_INCLUDE_" /link /LIBPATH:"_PATH_TO_WEBUI_LIB_" /SUBSYSTEM:WINDOWS webui-2-secure-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:my_application.exe` |
+ | MSVC | Dynamic | `cl my_application.c /I"_PATH_TO_WEBUI_INCLUDE_" /link /LIBPATH:"_PATH_TO_WEBUI_LIB_" /SUBSYSTEM:WINDOWS webui-2-secure.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:my_application.exe` |
+
+
+### Linux
+
+| Compiler | Type | Command |
+|----------|--------|---------|
+| GCC | Static | `gcc -Os my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" -lwebui-2-static -lpthread -lm -ldl -o my_application` |
+| GCC | Dynamic | `gcc my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" -lwebui-2 -lpthread -lm -ldl -o my_application` |
+| Clang | Static | `clang -Os my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" -lwebui-2-static -lpthread -lm -ldl -o my_application` |
+| Clang | Dynamic | `clang my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" -lwebui-2 -lpthread -lm -ldl -o my_application` |
+
+
+ Linux With SSL/TLS (Optional)
+
+ | Compiler | Type | Command |
+ |----------|--------|---------|
+ | GCC | Static | `gcc -Os my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" -lwebui-2-secure-static -lpthread -lm -ldl -o my_application` |
+ | GCC | Dynamic | `gcc my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" -lwebui-2-secure -lpthread -lm -ldl -o my_application` |
+ | Clang | Static | `clang -Os my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" -lwebui-2-secure-static -lpthread -lm -ldl -o my_application` |
+ | Clang | Dynamic | `clang my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" -lwebui-2-secure -lpthread -lm -ldl -o my_application` |
+
+
+### macOS
+
+| Compiler | Type | Command |
+|----------|--------|---------|
+| Clang | Static | `clang -Os my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" -lwebui-2-static -lpthread -lm -framework Cocoa -framework WebKit -o my_application` |
+| Clang | Dynamic | `clang my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" -lwebui-2 -lpthread -lm -framework Cocoa -framework WebKit -o my_application` |
+
+
+ macOS With SSL/TLS (Optional)
+
+ | Compiler | Type | Command |
+ |----------|--------|---------|
+ | Clang | Static | `clang -Os my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" -lwebui-2-secure-static -lpthread -lm -framework Cocoa -framework WebKit -o my_application` |
+ | Clang | Dynamic | `clang my_application.c -I"_PATH_TO_WEBUI_INCLUDE_" -L"_PATH_TO_WEBUI_LIB_" -lwebui-2-secure -lpthread -lm -framework Cocoa -framework WebKit -o my_application` |
+
+
+## Wrappers
+
+| Language | v2.4.0 API | v2.5.0 API | Link |
+| --------------- | --- | -------------- | --------------------------------------------------------- |
+| Python | ✔️ | _not complete_ | [Python-WebUI](https://github.com/webui-dev/python-webui) |
+| Go | ✔️ | _not complete_ | [Go-WebUI](https://github.com/webui-dev/go-webui) |
+| Zig | ✔️ | _not complete_ | [Zig-WebUI](https://github.com/webui-dev/zig-webui) |
+| Nim | ✔️ | _not complete_ | [Nim-WebUI](https://github.com/webui-dev/nim-webui) |
+| V | ✔️ | _not complete_ | [V-WebUI](https://github.com/webui-dev/v-webui) |
+| Rust | _not complete_ | _not complete_ | [Rust-WebUI](https://github.com/webui-dev/rust-webui) |
+| TS / JS (Deno) | ✔️ | _not complete_ | [Deno-WebUI](https://github.com/webui-dev/deno-webui) |
+| TS / JS (Bun) | _not complete_ | _not complete_ | [Bun-WebUI](https://github.com/webui-dev/bun-webui) |
+| Swift | _not complete_ | _not complete_ | [Swift-WebUI](https://github.com/webui-dev/swift-webui) |
+| Odin | _not complete_ | _not complete_ | [Odin-WebUI](https://github.com/webui-dev/odin-webui) |
+| Pascal | _not complete_ | _not complete_ | [Pascal-WebUI](https://github.com/webui-dev/pascal-webui) |
+| Purebasic | _not complete_ | _not complete_ | [Purebasic-WebUI](https://github.com/webui-dev/purebasic-webui)|
+| - | | |
+| Common Lisp | _not complete_ | _not complete_ | [cl-webui](https://github.com/garlic0x1/cl-webui) |
+| Delphi | _not complete_ | _not complete_ | [WebUI4Delphi](https://github.com/salvadordf/WebUI4Delphi) |
+| C# | _not complete_ | _not complete_ | [WebUI4CSharp](https://github.com/salvadordf/WebUI4CSharp) |
+| WebUI.NET | _not complete_ | _not complete_ | [WebUI.NET](https://github.com/Juff-Ma/WebUI.NET) |
+| QuickJS | _not complete_ | _not complete_ | [QuickUI](https://github.com/xland/QuickUI) |
+| PHP | _not complete_ | _not complete_ | [PHPWebUiComposer](https://github.com/KingBes/php-webui-composer) |
+
+## Supported Web Browsers
+
+| Browser | Windows | macOS | Linux |
+| --------------- | --------------- | ------------- | --------------- |
+| Mozilla Firefox | ✔️ | ✔️ | ✔️ |
+| Google Chrome | ✔️ | ✔️ | ✔️ |
+| Microsoft Edge | ✔️ | ✔️ | ✔️ |
+| Chromium | ✔️ | ✔️ | ✔️ |
+| Yandex | ✔️ | ✔️ | ✔️ |
+| Brave | ✔️ | ✔️ | ✔️ |
+| Vivaldi | ✔️ | ✔️ | ✔️ |
+| Epic | ✔️ | ✔️ | _not available_ |
+| Apple Safari | _not available_ | _coming soon_ | _not available_ |
+| Opera | _coming soon_ | _coming soon_ | _coming soon_ |
+
+## Supported WebView
+
+| WebView | Status |
+| --------------- | --------------- |
+| Windows WebView2 | ✔️ |
+| Linux GTK WebView | ✔️ |
+| macOS WKWebView | ✔️ |
+
+### License
+
+> Licensed under MIT License.
+
+### Stargazers
+
+[](https://github.com/webui-dev/webui/stargazers)
diff --git a/bridge/.gitignore b/bridge/.gitignore
new file mode 100644
index 0000000..7f8774d
--- /dev/null
+++ b/bridge/.gitignore
@@ -0,0 +1,6 @@
+# Do not track Nodejs output files
+node_modules/
+*.json
+
+# Do not track js2c.py output files
+webui.js
diff --git a/bridge/README.md b/bridge/README.md
new file mode 100644
index 0000000..03f2512
--- /dev/null
+++ b/bridge/README.md
@@ -0,0 +1,47 @@
+# WebUI Bridge
+
+The WebUI Bridge connects the UI (_Web Browser_) with the backend application through WebSocket. This bridge is written in TypeScript, and it needs to be transpiled to JavaScript using [ESBuild](https://esbuild.github.io/) to produce `webui.js`, then converted to C header using the Node script `js2c.js` to generate `webui_bridge.h`.
+
+### Windows
+
+- Install [Python](https://www.python.org/downloads/)
+- Install [Node.js](https://nodejs.org/en/download)
+- cd `webui\bridge`
+- `npm install esbuild`
+- `.\node_modules\.bin\esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --outdir=.\ .\webui.ts`
+- `node js2c.js`
+
+### Windows PowerShell
+
+- cd `webui\bridge`
+- `build.bat`
+- If you get _running scripts is disabled on this
+ system_ error. Then run `Set-ExecutionPolicy RemoteSigned` to enable script execution. After done, you can roll back by running `Set-ExecutionPolicy Restricted`
+
+### Linux
+
+- Install [Python](https://www.python.org/downloads/)
+- Install [Node.js](https://nodejs.org/en/download)
+- cd `webui/bridge`
+- `npm install esbuild`
+- `./node_modules/.bin/esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --outdir=./ ./webui.ts`
+- `node js2c.js`
+
+### Linux Bash
+
+- cd `webui\bridge`
+- sh `./build.sh`
+
+### macOS
+
+- Install [Python](https://www.python.org/downloads/)
+- Install [Node.js](https://nodejs.org/en/download)
+- cd `webui/bridge`
+- `npm install esbuild`
+- `./node_modules/.bin/esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --outdir=./ ./webui.ts`
+- `node js2c.js`
+
+### macOS Bash
+
+- cd `webui\bridge`
+- sh `./build.sh`
diff --git a/bridge/build.bat b/bridge/build.bat
new file mode 100644
index 0000000..dfd08e2
--- /dev/null
+++ b/bridge/build.bat
@@ -0,0 +1,29 @@
+@echo off
+SETLOCAL EnableDelayedExpansion
+
+REM Get current location and project root
+cd %~dp0
+FOR /F "tokens=*" %%i IN ('git rev-parse --show-toplevel') DO SET project_root=%%i
+cd %project_root%/bridge
+
+REM Check if node_modules\esbuild exists, if not, install using npm
+IF NOT EXIST "%project_root%\bridge\node_modules\esbuild\" (
+ where npm > NUL 2>&1
+ IF %errorlevel%==0 (
+ echo Installing esbuild...
+ npm install --prefix ./ esbuild
+ ) ELSE (
+ echo Error: Please install NPM.
+ cd %cd%
+ exit /b
+ )
+)
+
+REM Transpile WebUI-Bridge (TS to JS) & Convert WebUI-Bridge (JS to C)
+echo Transpile and bundle WebUI-Bridge from TypeScript to JavaScript...
+.\node_modules\.bin\esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --minify-syntax --minify-whitespace --outdir=. ./webui.ts & node js2c.js
+
+echo Done.
+cd %cd%
+
+ENDLOCAL
diff --git a/bridge/build.sh b/bridge/build.sh
new file mode 100755
index 0000000..1e266d0
--- /dev/null
+++ b/bridge/build.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+# https://webui.me
+# https://github.com/webui-dev/webui
+# Copyright (c) 2020-2026 Hassan Draga.
+# Licensed under MIT License.
+# All rights reserved.
+# Canada.
+#
+# Special Thanks to Turiiya (https://github.com/ttytm)
+
+project_root=$(git rev-parse --show-toplevel)
+cd $project_root/bridge
+
+echo "Transpile and bundle TS sources to webui.js"
+esbuild --bundle --target="chrome90,firefox90,safari15" --format=esm --tree-shaking=false --minify-syntax --minify-whitespace --outdir=. ./webui.ts
+
+echo "Convert JS source to C header"
+node js2c.js
+
+echo "Done."
diff --git a/bridge/js2c.js b/bridge/js2c.js
new file mode 100644
index 0000000..c21ad21
--- /dev/null
+++ b/bridge/js2c.js
@@ -0,0 +1,43 @@
+// WebUI v2.5.0-beta.4
+// https://webui.me
+// https://github.com/webui-dev/webui
+// Copyright (c) 2020-2026 Hassan Draga.
+// Licensed under MIT License.
+// All rights reserved.
+// Canada.
+
+async function jsToCHeader(inputFilename, outputFilename) {
+ try {
+ console.log(`Converting '${inputFilename}' to '${outputFilename}'...`);
+ // Comment block
+ const comment = `// WebUI v2.5.0-beta.4\n// https://webui.me\n// https://github.com/webui-dev/webui\n// Copyright (c) 2020-2026 Hassan Draga.\n// Licensed under MIT License.\n// All rights reserved.\n// Canada.\n\n`;
+ // Read JS file content
+ const fs = require('fs').promises;
+ let content = await fs.readFile(inputFilename, 'utf-8');
+ // Add comment to js
+ let newContent = comment + content;
+ await fs.writeFile(inputFilename, newContent);
+ // Convert each character in JS content to its hexadecimal value
+ const hexValues = [...newContent].map(char => `0x${char.charCodeAt(0).toString(16).padStart(2, '0')}`);
+ // Prepare the content for the C header file
+ let headerContent = `${comment}// --- PLEASE DO NOT EDIT THIS FILE -------\n// --- THIS FILE IS GENERATED BY JS2C.JS --\n\n`;
+ headerContent += `#ifndef WEBUI_BRIDGE_H\n#define WEBUI_BRIDGE_H\n`;
+ headerContent += `unsigned char webui_javascript_bridge[] = { `;
+ // Split the hexadecimal values to make the output more readable, adding a new line every 10 values
+ for (let i = 0; i < hexValues.length; i += 10) {
+ headerContent += "\n " + hexValues.slice(i, i + 10).join(', ') + ',';
+ }
+ headerContent += `\n 0x00\n};\n\n#endif // WEBUI_BRIDGE_H`;
+ // Write the header content to the output file
+ await fs.writeFile(outputFilename, headerContent);
+ } catch (error) {
+ if (error.code === 'ENOENT') {
+ console.error(`Error: File '${inputFilename}' not found.`);
+ } else {
+ console.error('An error occurred:', error);
+ }
+ }
+}
+
+// Main
+jsToCHeader('webui.js', 'webui_bridge.h');
diff --git a/bridge/utils.ts b/bridge/utils.ts
new file mode 100644
index 0000000..f60b013
--- /dev/null
+++ b/bridge/utils.ts
@@ -0,0 +1,56 @@
+/*
+ https://webui.me
+ https://github.com/webui-dev/webui
+ Copyright (c) 2020-2026 Hassan Draga.
+ Licensed under MIT License.
+ All rights reserved.
+ Canada.
+
+ File: WebUI Bridge Utils
+ Copyright (c) 2024 Oculi Julien.
+*/
+
+/**
+ * Allows you to automatically bind an event listener to newly added
+ * elements that match a specific selector within a given root element.
+ * Track dom update to rebind event listeners automatically.
+ *
+ * @param {HTMLElement} root - The root element to observe for changes.
+ * @param {string} targetSelector - Query selector matching elements that you want to bind the event listener to.
+ * @param {K} type - Type of event listener to bind (same as for addEventListener).
+ * @param listener - Event listener to bind (same as for addEventListener).
+ * @param {boolean | AddEventListenerOptions} [options] - Event listener options (same as for addEventListener).
+ * @returns the used observer to allow disconnect.
+ */
+export function addRefreshableEventListener(
+ root: HTMLElement,
+ targetSelector: string,
+ type: K,
+ listener: (this: HTMLElement, ev: HTMLElementEventMap[K]) => unknown,
+ options?: boolean | AddEventListenerOptions,
+) {
+ function rebindListener(mutations: MutationRecord[]) {
+ for (const mutation of mutations) {
+ for (const node of mutation.addedNodes) {
+ if (!(node instanceof HTMLElement)) return; // Target only html elements
+ if (node.matches(targetSelector)) {
+ // Bind event on added nodes
+ node.addEventListener(type, listener, options);
+ }
+ for (const child of node.querySelectorAll(targetSelector)) {
+ if (!(child instanceof HTMLElement)) continue; //Target only html elements
+ child.addEventListener(type, listener, options);
+ }
+ }
+ }
+ }
+
+ const observer = new MutationObserver(rebindListener); //Set mutation observer callback
+ observer.observe(root, { subtree: true, childList: true }); // Observe root element and all his children
+ return observer; // Allow user to stop observer for performance issues
+}
+
+/**
+ * Async function constructor
+ */
+export const AsyncFunction = async function () {}.constructor;
diff --git a/bridge/webui.ts b/bridge/webui.ts
new file mode 100644
index 0000000..804c849
--- /dev/null
+++ b/bridge/webui.ts
@@ -0,0 +1,1025 @@
+'use-strict'; // Force strict mode for transpiled
+
+/*
+ WebUI Bridge
+
+ https://webui.me
+ https://github.com/webui-dev/webui
+ Copyright (c) 2020-2026 Hassan Draga.
+ Licensed under MIT License.
+ All rights reserved.
+ Canada.
+
+ Converted from JavaScript to TypeScript
+ By Oculi Julien. Copyright (c) 2023.
+*/
+
+//@ts-ignore use *.ts import real extension
+import { AsyncFunction, addRefreshableEventListener } from './utils.ts';
+
+type DataTypes = string | number | boolean | Uint8Array;
+
+class WebuiBridge {
+ // WebUI Settings
+ #secure: boolean;
+ #token: number;
+ #port: number;
+ #log: boolean;
+ #winX: number;
+ #winY: number;
+ #winW: number;
+ #winH: number;
+ #customWindowDrag: boolean;
+ // Frameless Dragging
+ #enableCustomDragging: boolean = false;
+ #isDragging: boolean = false;
+ #initialMouseX: number = 0;
+ #initialMouseY: number = 0;
+ #initialWindowX: number = window.screenX || window.screenLeft;
+ #initialWindowY: number = window.screenY || window.screenTop;
+ #currentWindowX: number = window.screenX || window.screenLeft;
+ #currentWindowY: number = window.screenY || window.screenTop;
+ // Internals
+ #ws: WebSocket;
+ #wsStayAlive: boolean = true;
+ #wsStayAliveTimeout: number = 500;
+ #wsWasConnected: boolean = false;
+ #TokenAccepted: boolean = false;
+ #closeReason: number = 0;
+ #closeValue: string;
+ #AllEvents: boolean = false;
+ #callPromiseID: Uint16Array = new Uint16Array(1);
+ #callPromiseResolve: (((data: string) => unknown) | undefined)[] = [];
+ #allowNavigation: boolean = true;
+ #sendQueue: Uint8Array[] = [];
+ #isSending: boolean = false;
+ #bindsList: string[];
+ // WebUI Const
+ #WEBUI_SIGNATURE: number = 221;
+ #CMD_JS: number = 254;
+ #CMD_JS_QUICK: number = 253;
+ #CMD_CLICK: number = 252;
+ #CMD_NAVIGATION: number = 251;
+ #CMD_CLOSE: number = 250;
+ #CMD_CALL_FUNC: number = 249;
+ #CMD_SEND_RAW: number = 248;
+ #CMD_NEW_ID: number = 247;
+ #CMD_MULTI: number = 246;
+ #CMD_CHECK_TK: number = 245;
+ #CMD_WINDOW_DRAG: number = 244;
+ #CMD_WINDOW_RESIZED: number = 243;
+ #MULTI_CHUNK_SIZE: number = 65500;
+ #PROTOCOL_SIZE: number = 8; // Protocol header size in bytes
+ #PROTOCOL_SIGN: number = 0; // Protocol byte position: Signature (1 Byte)
+ #PROTOCOL_TOKEN: number = 1; // Protocol byte position: Token (4 Bytes)
+ #PROTOCOL_ID: number = 5; // Protocol byte position: ID (2 Bytes)
+ #PROTOCOL_CMD: number = 7; // Protocol byte position: Command (1 Byte)
+ #PROTOCOL_DATA: number = 8; // Protocol byte position: Data (n Byte)
+ #Token: Uint32Array = new Uint32Array(1);
+ #Ping: Boolean = true;
+ // Events
+ #eventsCallback: ((event: number) => void) | null = null;
+ #lastEvent: number = -1;
+ event = {
+ // TODO: Make `event` static and solve the ESBUILD `_WebuiBridge` issue.
+ CONNECTED: 0,
+ DISCONNECTED: 1,
+ };
+ // Constructor
+ constructor({
+ secure = false,
+ token = 0,
+ port = 0,
+ log = false,
+ winX = 0,
+ winY = 0,
+ winW = 0,
+ winH = 0,
+ customWindowDrag = false
+ }: {
+ secure: boolean;
+ token: number;
+ port: number;
+ log?: boolean;
+ winX: number;
+ winY: number;
+ winW: number;
+ winH: number;
+ customWindowDrag: boolean;
+ }) {
+ // Constructor arguments are injected by webui.c
+ this.#secure = secure;
+ this.#token = token;
+ this.#port = port;
+ this.#log = log;
+ this.#winX = winX;
+ this.#winY = winY;
+ this.#winW = winW;
+ this.#winH = winH;
+ this.#enableCustomDragging = customWindowDrag;
+ // Token
+ this.#Token[0] = this.#token;
+ // Instance
+ if ('webui' in globalThis) {
+ throw new Error('Sorry. WebUI is already defined, only one instance is allowed.');
+ }
+ // Positioning the current window
+ if (this.#winX !== undefined && this.#winY !== undefined) {
+ // window.moveTo(this.#winX, this.#winY);
+ }
+ // Resize the current window
+ if (this.#winW !== undefined && this.#winH !== undefined) {
+ // window.resizeTo(this.#winW, this.#winH);
+ }
+ // WebSocket
+ if (!('WebSocket' in window)) {
+ this.#showWarning('WebSocket is not supported by your web browser');
+ if (!this.#log) globalThis.close();
+ }
+ // Connect to the backend application
+ this.#start();
+ // Navigation event listener
+ if ('navigation' in globalThis) {
+ globalThis.navigation.addEventListener('navigate', (event) => {
+ if (!this.#allowNavigation) {
+ if (this.#AllEvents && (this.#wsIsConnected())) {
+ event.preventDefault();
+ const url = new URL(event.destination.url);
+ if (this.#log) console.log(`WebUI -> DOM -> Navigation Event [${url.href}]`);
+ this.#sendEventNavigation(url.href);
+ }
+ }
+ });
+ } else {
+ // Click navigation event listener
+ addRefreshableEventListener(document.body, 'a', 'click', (event) => {
+ if (!this.#allowNavigation) {
+ if (this.#AllEvents && (this.#wsIsConnected())) {
+ event.preventDefault();
+ const { href } = event.target as HTMLAnchorElement;
+ if (this.#log) console.log(`WebUI -> DOM -> Navigation Click Event [${href}]`);
+ this.#sendEventNavigation(href);
+ }
+ }
+ });
+ }
+ // Prevent F5 refresh
+ document.addEventListener('keydown', (event) => {
+ if (this.#log) return; // Allowed in debug mode
+ if (event.key === 'F5') event.preventDefault();
+ });
+ // Frameless Dragging
+ if (this.#enableCustomDragging) {
+ document.addEventListener("mousemove", (e) => {
+ // WebUI Webkit App-Region Custom Implementation
+ if (e.buttons !== 1) {
+ this.#isDragging = false;
+ return;
+ }
+ if (!this.#isDragging) {
+ let target = e.target;
+ while (target) {
+ let computedStyle = window.getComputedStyle(target);
+ let webuiComputed = computedStyle.getPropertyValue("--webui-app-region").trim();
+ if (webuiComputed === "drag") {
+ this.#initialMouseX = e.screenX;
+ this.#initialMouseY = e.screenY;
+ this.#initialWindowX = this.#currentWindowX;
+ this.#initialWindowY = this.#currentWindowY;
+ this.#isDragging = true;
+ break;
+ }
+ target = target.parentElement;
+ }
+ return;
+ }
+ // Calculate window position relative to cursor movement
+ const deltaX = e.screenX - this.#initialMouseX;
+ const deltaY = e.screenY - this.#initialMouseY;
+ let newX = this.#initialWindowX + deltaX;
+ let newY = this.#initialWindowY + deltaY;
+ // Fix out of screen
+ if (newX < 0) newX = 0;
+ if (newY < 0) newY = 0;
+ // Move the window
+ this.#sendDrag(newX, newY);
+ // Update the last window position
+ this.#currentWindowX = newX;
+ this.#currentWindowY = newY;
+ });
+ // Stop frameless dragging on mouse release
+ document.addEventListener("mouseup", () => {
+ this.#isDragging = false;
+ });
+ }
+ onbeforeunload = () => {
+ this.#close();
+ };
+ setTimeout(() => {
+ if (!this.#wsWasConnected) {
+ this.#showWarning('Failed to connect to the backend application');
+ }
+ }, 5000);
+ }
+ // Methods
+ #close(reason = 0, value = '') {
+ this.#closeReason = reason;
+ this.#closeValue = value;
+ if (this.#wsIsConnected()) {
+ this.#ws.close();
+ }
+ }
+ #showWarning(msg: string) {
+ setTimeout(() => {
+ if (!this.#wsIsConnected()) {
+ if (document.getElementById('webui-error-connection-lost')) return;
+ const div = document.createElement('div');
+ div.id = 'webui-error-connection-lost';
+ Object.assign(div.style, {
+ position: 'fixed',
+ top: '0',
+ left: '0',
+ width: '100%',
+ backgroundColor: 'rgb(191 125 30 / 84%)',
+ color: '#fff',
+ textAlign: 'center',
+ padding: '4px 0',
+ fontFamily: 'Arial, sans-serif',
+ fontSize: '16px',
+ zIndex: '9000',
+ lineHeight: '1'
+ });
+ div.innerHTML = 'Error: ' + msg + ' - WebUI 2.5.0-beta.4 ';
+ document.body.insertBefore(div, document.body.firstChild);
+ }
+ }, 1000);
+ }
+ #freezeUi() {
+ if (this.#eventsCallback == null) {
+ // Show default WebUI warning as we
+ // don't have a user event callback.
+ this.#showWarning('Connection with the backend is lost');
+ }
+ }
+ #unfreezeUI() {
+ const div = document.getElementById('webui-error-connection-lost');
+ if (div) {
+ div.remove();
+ }
+ }
+ #isTextBasedCommand(cmd: number): Boolean {
+ if (cmd !== this.#CMD_SEND_RAW) return true;
+ return false;
+ }
+ #parseDimensions(input: string): {x: number; y: number; width: number; height: number} {
+ try {
+ const parts = input.split(',');
+ if (parts.length !== 4) return {x: 0, y: 0, width: 0, height: 0};
+ const x = parseFloat(parts[0]),
+ y = parseFloat(parts[1]),
+ width = parseFloat(parts[2]),
+ height = parseFloat(parts[3]);
+ return [x, y, width, height].some(isNaN) ? {x: 0, y: 0, width: 0, height: 0} : {x, y, width, height};
+ } catch {
+ return {x: 0, y: 0, width: 0, height: 0};
+ }
+ }
+ #getDataStrFromPacket(buffer: Uint8Array, startIndex: number): string {
+ let stringBytes: number[] = [];
+ for (let i = startIndex; i < buffer.length; i++) {
+ if (buffer[i] === 0) {
+ // Check for null byte
+ break;
+ }
+ stringBytes.push(buffer[i]);
+ }
+ // Convert the array of bytes to a string
+ const stringText = new TextDecoder().decode(new Uint8Array(stringBytes));
+ return stringText;
+ }
+ #getID(buffer: Uint8Array, index: number): number {
+ if (index < 0 || index >= buffer.length - 1) {
+ throw new Error('Index out of bounds or insufficient data.');
+ }
+ const firstByte = buffer[index];
+ const secondByte = buffer[index + 1];
+ const combined = (secondByte << 8) | firstByte; // Works only for little-endian
+ return combined;
+ }
+ #addToken(buffer: Uint8Array, value: number, index: number): void {
+ if (value < 0 || value > 0xffffffff) {
+ throw new Error('Number is out of the range for 4 bytes representation.');
+ }
+ if (index < 0 || index > buffer.length - 4) {
+ throw new Error('Index out of bounds or insufficient space in buffer.');
+ }
+ // WebUI expect Little-endian (Work for Little/Big endian platforms)
+ buffer[index] = value & 0xff; // Least significant byte
+ buffer[index + 1] = (value >>> 8) & 0xff;
+ buffer[index + 2] = (value >>> 16) & 0xff;
+ buffer[index + 3] = (value >>> 24) & 0xff; // Most significant byte
+ }
+ #addID(buffer: Uint8Array, value: number, index: number): void {
+ if (value < 0 || value > 0xffff) {
+ throw new Error('Number is out of the range for 2 bytes representation.');
+ }
+ if (index < 0 || index > buffer.length - 2) {
+ throw new Error('Index out of bounds or insufficient space in buffer.');
+ }
+ // WebUI expect Little-endian (Work for Little/Big endian platforms)
+ buffer[index] = value & 0xff; // Least significant byte
+ buffer[index + 1] = (value >>> 8) & 0xff; // Most significant byte
+ }
+ #start() {
+ this.#keepAlive();
+ this.#callPromiseID[0] = 0;
+ // Connect to the backend application
+ this.#wsConnect();
+ }
+ #keepAlive = async () => {
+ while (true) {
+ if (this.#Ping) {
+ // Some web browsers may close the connection
+ // let's send a void message to keep WS open
+ this.#sendData(new TextEncoder().encode('ping'));
+ } else {
+ // There is an active communication
+ this.#Ping = true;
+ }
+ await new Promise((resolve) => setTimeout(resolve, 20000));
+ }
+ };
+ #clicksListener() {
+ document.querySelectorAll("[id]").forEach(e => {
+ if (this.#AllEvents || ((e.id !== '') && (this.#bindsList.includes(e.id)))) {
+ if (e.id && !e.dataset.webui_click_is_set) {
+ e.dataset.webui_click_is_set = "true";
+ e.addEventListener("click", () => this.#sendClick(e.id));
+ }
+ }
+ });
+ }
+ async #sendData(packet: Uint8Array) {
+ this.#Ping = false;
+ if ((!this.#wsIsConnected()) || packet === undefined) return;
+ // Enqueue the packet
+ this.#sendQueue.push(packet);
+ if (this.#isSending) return;
+ this.#isSending = true;
+ while (this.#sendQueue.length > 0) {
+ const currentPacket = this.#sendQueue.shift()!;
+ if (currentPacket.length < this.#MULTI_CHUNK_SIZE) {
+ this.#ws.send(currentPacket.buffer);
+ } else {
+ // Pre-packet to let WebUI be ready for multi packet
+ const pre_packet = Uint8Array.of(
+ this.#WEBUI_SIGNATURE,
+ 0,
+ 0,
+ 0,
+ 0, // Token (4 Bytes)
+ 0,
+ 0, // ID (2 Bytes)
+ this.#CMD_MULTI,
+ ...new TextEncoder().encode(currentPacket.length.toString()),
+ 0,
+ );
+ this.#ws.send(pre_packet.buffer);
+ // Send chunks
+ let offset = 0;
+ const sendChunk = async () => {
+ if (offset < currentPacket.length) {
+ const chunkSize = Math.min(this.#MULTI_CHUNK_SIZE, currentPacket.length - offset);
+ const chunk = currentPacket.subarray(offset, offset + chunkSize);
+ this.#ws.send(chunk);
+ offset += chunkSize;
+ await sendChunk();
+ }
+ };
+ await sendChunk();
+ }
+ }
+ this.#isSending = false;
+ }
+ #sendClick(elem: string) {
+ if (this.#wsIsConnected()) {
+ // Protocol
+ // 0: [SIGNATURE]
+ // 1: [TOKEN]
+ // 2: [ID]
+ // 3: [CMD]
+ // 4: [Element]
+ const packet =
+ elem !== ''
+ ? Uint8Array.of(
+ this.#WEBUI_SIGNATURE,
+ 0,
+ 0,
+ 0,
+ 0, // Token (4 Bytes)
+ 0,
+ 0, // ID (2 Bytes)
+ this.#CMD_CLICK,
+ ...new TextEncoder().encode(elem),
+ 0,
+ )
+ : Uint8Array.of(
+ this.#WEBUI_SIGNATURE,
+ 0,
+ 0,
+ 0,
+ 0, // Token (4 Bytes)
+ 0,
+ 0, // ID (2 Bytes)
+ this.#CMD_CLICK,
+ 0,
+ );
+ this.#addToken(packet, this.#token, this.#PROTOCOL_TOKEN);
+ // this.#addID(packet, 0, this.#PROTOCOL_ID)
+ this.#sendData(packet);
+ if (this.#log) console.log(`WebUI -> Send Click [${elem}]`);
+ }
+ }
+ #checkToken() {
+ if (this.#wsIsConnected()) {
+ // Protocol
+ // 0: [SIGNATURE]
+ // 1: [TOKEN]
+ // 2: [ID]
+ // 3: [CMD]
+ const packet =
+ Uint8Array.of(
+ this.#WEBUI_SIGNATURE,
+ 0,
+ 0,
+ 0,
+ 0, // Token (4 Bytes)
+ 0,
+ 0, // ID (2 Bytes)
+ this.#CMD_CHECK_TK,
+ 0,
+ );
+ this.#addToken(packet, this.#token, this.#PROTOCOL_TOKEN);
+ // this.#addID(packet, 0, this.#PROTOCOL_ID)
+ this.#sendData(packet);
+ if (this.#log) console.log(`WebUI -> Send Token [0x${this.#token.toString(16).padStart(8, '0')}]`);
+ }
+ }
+ #sendEventNavigation(url: string) {
+ if (url !== '') {
+ if (this.#wsIsConnected()) {
+ if (this.#log) console.log(`WebUI -> Send Navigation Event [${url}]`);
+ const packet = Uint8Array.of(
+ // Protocol
+ // 0: [SIGNATURE]
+ // 1: [TOKEN]
+ // 2: [ID]
+ // 3: [CMD]
+ // 4: [URL]
+ this.#WEBUI_SIGNATURE,
+ 0,
+ 0,
+ 0,
+ 0, // Token (4 Bytes)
+ 0,
+ 0, // ID (2 Bytes)
+ this.#CMD_NAVIGATION,
+ ...new TextEncoder().encode(url),
+ );
+ this.#addToken(packet, this.#token, this.#PROTOCOL_TOKEN);
+ // this.#addID(packet, 0, this.#PROTOCOL_ID)
+ this.#sendData(packet);
+ }
+ }
+ }
+ #sendDrag(x: number, y: number) {
+ if (this.#wsIsConnected()) {
+ if (this.#log) console.log(`WebUI -> Send Drag Event [${x}, ${y}]`);
+ const packet = Uint8Array.of(
+ // Protocol
+ // 0: [SIGNATURE]
+ // 1: [TOKEN]
+ // 2: [ID]
+ // 3: [CMD]
+ // 4: [X]
+ // 4: [Y]
+ this.#WEBUI_SIGNATURE,
+ 0,
+ 0,
+ 0,
+ 0, // Token (4 Bytes)
+ 0,
+ 0, // ID (2 Bytes)
+ this.#CMD_WINDOW_DRAG,
+ ...new Uint8Array(new Int32Array([x]).buffer), // X (4 Bytes)
+ ...new Uint8Array(new Int32Array([y]).buffer), // Y (4 Bytes)
+ );
+ this.#addToken(packet, this.#token, this.#PROTOCOL_TOKEN);
+ // this.#addID(packet, 0, this.#PROTOCOL_ID)
+ this.#sendData(packet);
+ }
+ }
+ #closeWindowTimer() {
+ setTimeout(function () {
+ globalThis.close();
+ }, 1000);
+ }
+ #updateBindsList() {
+ if (this.#bindsList.includes('')) {
+ this.#AllEvents = true;
+ this.#allowNavigation = false;
+ }
+ this.#generateCallObjects();
+ this.#clicksListener();
+ }
+ #toUint16(value: number): number {
+ return value & 0xffff;
+ }
+ #generateCallObjects() {
+ for (const bind of this.#bindsList) {
+ if (bind.trim()) {
+ const fn = bind;
+ if (fn.trim()) {
+ if (fn !== '__webui_core_api__') {
+ if (typeof (window as any)[fn] === 'undefined') {
+ this[fn] = (...args: DataTypes[]) => this.call(fn, ...args);
+ (window as any)[fn] = (...args: string[]) => this.call(fn, ...args);
+ if (this.#log) console.log(`WebUI -> Binding backend function [${fn}]`);
+ }
+ }
+ }
+ }
+ }
+ }
+ #getScriptUrl() {
+ const scripts = Array.from(document.scripts)
+ .filter(s => s.src !== null && s.src.startsWith('http') && s.src.endsWith('webui.js'))
+ .map(s => s.src);
+ return scripts.length === 0 ? null : new URL(scripts[0]);
+ }
+ #callPromise(fn: string, ...args: DataTypes[]) {
+ --this.#callPromiseID[0];
+ const callId = this.#toUint16(this.#callPromiseID[0]);
+ // Combine lengths
+ let argsLengths = args
+ .map((arg) => {
+ if (typeof arg === 'object') {
+ // Uint8Array
+ return arg.length;
+ } else {
+ // string, number, boolean
+ return new TextEncoder().encode(arg.toString()).length;
+ }
+ })
+ .join(';');
+ // Combine values
+ let argsValues: Uint8Array = new Uint8Array();
+ for (const arg of args) {
+ let buffer: Uint8Array;
+ if (typeof arg === 'object') {
+ buffer = arg; // Uint8Array
+ } else {
+ // string, number, boolean
+ buffer = new TextEncoder().encode(arg.toString());
+ }
+ const temp = new Uint8Array(argsValues.length + buffer.length + 1);
+ temp.set(argsValues, 0);
+ temp.set(buffer, argsValues.length);
+ temp[argsValues.length + buffer.length] = 0x00;
+ argsValues = temp;
+ }
+ // Protocol
+ // 0: [SIGNATURE]
+ // 1: [TOKEN]
+ // 2: [ID]
+ // 3: [CMD]
+ // 4: [Fn, Null, {LenLen...}, Null, {Data,Null,Data,Null...}]
+ let packet = new Uint8Array(0);
+ const packetPush = (data: Uint8Array) => {
+ const newPacket = new Uint8Array(packet.length + data.length);
+ newPacket.set(packet);
+ newPacket.set(data, packet.length);
+ packet = newPacket;
+ };
+ packetPush(new Uint8Array([this.#WEBUI_SIGNATURE]));
+ packetPush(new Uint8Array([0, 0, 0, 0])); // Token (4 Bytes)
+ packetPush(new Uint8Array([0, 0])); // ID (2 Bytes)
+ packetPush(new Uint8Array([this.#CMD_CALL_FUNC]));
+ packetPush(new TextEncoder().encode(fn));
+ packetPush(new Uint8Array([0]));
+ packetPush(new TextEncoder().encode(argsLengths));
+ packetPush(new Uint8Array([0]));
+ packetPush(new Uint8Array(argsValues));
+ this.#addToken(packet, this.#token, this.#PROTOCOL_TOKEN);
+ this.#addID(packet, callId, this.#PROTOCOL_ID);
+ return new Promise((resolve) => {
+ this.#callPromiseResolve[callId] = resolve;
+ this.#sendData(packet);
+ });
+ }
+ async callCore(fn: string, ...args: DataTypes[]): Promise {
+ return this.call('__webui_core_api__', fn, ...args);
+ }
+ // -- WebSocket ----------------------------
+ #wsIsConnected(): boolean {
+ return ((this.#ws) && (this.#ws.readyState === WebSocket.OPEN));
+ }
+ #wsConnect(): void {
+ if (this.#wsIsConnected()) {
+ this.#ws.close();
+ }
+ this.#TokenAccepted = false;
+ const scriptUrl = this.#getScriptUrl();
+ const host = scriptUrl !== null ? scriptUrl.hostname : window.location.hostname;
+ const url = this.#secure ? ('wss://' + host) : ('ws://' + host);
+ this.#ws = new WebSocket(`${url}:${this.#port}/_webui_ws_connect`);
+ this.#ws.binaryType = 'arraybuffer';
+ this.#ws.onopen = this.#wsOnOpen.bind(this);
+ this.#ws.onmessage = this.#wsOnMessage.bind(this);
+ this.#ws.onclose = this.#wsOnClose.bind(this);
+ this.#ws.onerror = this.#wsOnError.bind(this);
+ }
+ #wsOnOpen = (event: Event) => {
+ this.#wsWasConnected = true;
+ this.#unfreezeUI();
+ if (this.#log) console.log('WebUI -> Connected');
+ this.#checkToken();
+ };
+ #wsOnError = (event: Event) => {
+ if (this.#log) console.log(`WebUI -> Connection failed.`);
+ };
+ #wsOnClose = (event: CloseEvent) => {
+ if (this.#closeReason === this.#CMD_NAVIGATION) {
+ this.#closeReason = 0;
+ if (this.#log) console.log(`WebUI -> Connection lost. Navigation to [${this.#closeValue}]`);
+ this.#allowNavigation = true;
+ globalThis.location.replace(this.#closeValue);
+ } else {
+ if (this.#wsStayAlive) {
+ // Re-connect
+ if (this.#log) console.log(`WebUI -> Connection lost (${event.code}). Reconnecting...`);
+ this.#freezeUi();
+ setTimeout(() => this.#wsConnect(), this.#wsStayAliveTimeout);
+ }
+ else if (this.#log) {
+ // Debug close
+ console.log(`WebUI -> Connection lost (${event.code})`);
+ this.#freezeUi();
+ } else {
+ // Release close
+ this.#closeWindowTimer();
+ }
+ }
+ // Event Callback
+ this.#userEventCallback(this.event.DISCONNECTED);
+ };
+ #userEventCallback = (e: number) => {
+ if (this.#eventsCallback) {
+ if (e != this.#lastEvent) {
+ this.#lastEvent = e;
+ this.#eventsCallback(e);
+ }
+ }
+ }
+ #wsOnMessage = async (event: MessageEvent) => {
+ const buffer8 = new Uint8Array(event.data);
+ if (buffer8.length < this.#PROTOCOL_SIZE) return;
+ if (buffer8[this.#PROTOCOL_SIGN] !== this.#WEBUI_SIGNATURE) return;
+ if (this.#isTextBasedCommand(buffer8[this.#PROTOCOL_CMD])) {
+ // UTF8 Text based commands
+ const callId = this.#getID(buffer8, this.#PROTOCOL_ID);
+ // Process Command
+ switch (buffer8[this.#PROTOCOL_CMD]) {
+ case this.#CMD_JS_QUICK:
+ case this.#CMD_JS:
+ {
+ // Protocol
+ // 0: [SIGNATURE]
+ // 1: [TOKEN]
+ // 2: [ID]
+ // 3: [CMD]
+ // 4: [Script]
+ const script: string = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA);
+ const scriptSanitize = script.replace(/(?:\r\n|\r|\n)/g, '\n');
+ if (this.#log) console.log(`WebUI -> CMD -> JS [${scriptSanitize}]`);
+ // Get callback result
+ let FunReturn: string | Uint8Array = 'undefined';
+ let FunError = false;
+ let isBinaryReturn = false;
+ try {
+ const result = await AsyncFunction(scriptSanitize)();
+ if (result instanceof Uint8Array) {
+ FunReturn = result;
+ isBinaryReturn = true;
+ } else {
+ FunReturn = String(result);
+ }
+ } catch (e) {
+ FunError = true;
+ FunReturn = e.message;
+ }
+ // Stop if this is a quick call
+ if (buffer8[this.#PROTOCOL_CMD] === this.#CMD_JS_QUICK) return;
+ // Get the call return
+ if (FunReturn === undefined) {
+ FunReturn = 'undefined';
+ }
+ // Logging
+ if (this.#log && !FunError) {
+ if (isBinaryReturn) {
+ const binaryData = FunReturn as Uint8Array;
+ const hexPreview = Array.from(binaryData.slice(0, 64)).map(b => `0x${b.toString(16).padStart(2, '0')}`).join(', ');
+ console.log(`WebUI -> CMD -> JS -> Return Success (${binaryData.length} Bytes) [${hexPreview}${binaryData.length > 64 ? '...' : ''}]`);
+ } else {
+ const stringData = String(FunReturn);
+ console.log(`WebUI -> CMD -> JS -> Return Success (${new TextEncoder().encode(stringData).length} Bytes) [${stringData.substring(0, 64)}${stringData.length > 64 ? '...' : ''}]`);
+ }
+ }
+ else if (this.#log && FunError) {
+ const errorString = String(FunReturn);
+ console.log(`WebUI -> CMD -> JS -> Return Error [${errorString.substring(0, 64)}${errorString.length > 64 ? '...' : ''}]`);
+ }
+ // Protocol
+ // 0: [SIGNATURE]
+ // 1: [TOKEN]
+ // 2: [ID]
+ // 3: [CMD]
+ // 4: [Error, Script Response]
+ let packet = new Uint8Array(0);
+ const packetPush = (data: Uint8Array) => {
+ const newPacket = new Uint8Array(packet.length + data.length);
+ newPacket.set(packet);
+ newPacket.set(data, packet.length);
+ packet = newPacket;
+ };
+ const packetPushStr = (data: string) => {
+ const chunkSize = 1024 * 8;
+ if (data.length > chunkSize) {
+ const encoder = new TextEncoder();
+ for (let i = 0; i < data.length; i += chunkSize) {
+ const chunk = data.substring(i, Math.min(i + chunkSize, data.length));
+ const encodedChunk = encoder.encode(chunk);
+ packetPush(encodedChunk);
+ }
+ } else {
+ packetPush(new TextEncoder().encode(data));
+ }
+ };
+ packetPush(new Uint8Array([this.#WEBUI_SIGNATURE]));
+ packetPush(new Uint8Array([0, 0, 0, 0])); // Token (4 Bytes)
+ packetPush(new Uint8Array([0, 0])); // ID (2 Bytes)
+ packetPush(new Uint8Array([this.#CMD_JS]));
+ packetPush(new Uint8Array(FunError ? [1] : [0]));
+ if (isBinaryReturn) {
+ packetPush(FunReturn as Uint8Array);
+ } else {
+ packetPushStr(FunReturn as string);
+ }
+ packetPush(new Uint8Array([0]));
+ this.#addToken(packet, this.#token, this.#PROTOCOL_TOKEN);
+ this.#addID(packet, callId, this.#PROTOCOL_ID);
+ this.#sendData(packet);
+ }
+ break;
+ case this.#CMD_CALL_FUNC:
+ {
+ // Protocol
+ // 0: [SIGNATURE]
+ // 1: [TOKEN]
+ // 2: [ID]
+ // 3: [CMD]
+ // 4: [Call Response]
+ const callResponse: string = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA);
+ if (this.#log) {
+ console.log(`WebUI -> CMD -> Call Response [${callResponse}]`);
+ }
+ if (this.#callPromiseResolve[callId]) {
+ if (this.#log) {
+ console.log(`WebUI -> CMD -> Resolving Response #${callId}...`);
+ }
+ this.#callPromiseResolve[callId]?.(callResponse);
+ this.#callPromiseResolve[callId] = undefined;
+ }
+ }
+ break;
+ case this.#CMD_NAVIGATION:
+ // Protocol
+ // 0: [SIGNATURE]
+ // 1: [TOKEN]
+ // 2: [ID]
+ // 3: [CMD]
+ // 4: [URL]
+ const url: string = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA);
+ if (this.#log) console.log(`WebUI -> CMD -> Navigation [${url}]`);
+ this.#close(this.#CMD_NAVIGATION, url);
+ break;
+ case this.#CMD_WINDOW_RESIZED:
+ // Protocol
+ // 0: [SIGNATURE]
+ // 1: [TOKEN]
+ // 2: [ID]
+ // 3: [CMD]
+ // 4: [x,y,width,height]
+ const widthAndHeight: string = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA);
+ const { x, y, width, height } = this.#parseDimensions(widthAndHeight);
+ // Update drag positions
+ this.#currentWindowX = x;
+ this.#currentWindowY = y;
+ if (this.#log) console.log(`WebUI -> CMD -> Window Resized [x: ${x}, y: ${y}, width: ${width}, height: ${height}]`);
+ break;
+ case this.#CMD_NEW_ID:
+ // Protocol
+ // 0: [SIGNATURE]
+ // 1: [TOKEN]
+ // 2: [ID]
+ // 3: [CMD]
+ // 4: [New Element]
+ const newElement: string = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA);
+ if (this.#log) console.log(`WebUI -> CMD -> New Bind ID [${newElement}]`);
+ if (!this.#bindsList.includes(newElement)) this.#bindsList.push(newElement);
+ // Generate objects
+ this.#updateBindsList();
+ break;
+ case this.#CMD_CLOSE:
+ // Protocol
+ // 0: [SIGNATURE]
+ // 1: [TOKEN]
+ // 2: [ID]
+ // 3: [CMD]
+ if (this.#log) {
+ // Debug Close
+ console.log(`WebUI -> CMD -> Close`);
+ if (this.#wsIsConnected()) {
+ this.#wsStayAlive = false;
+ this.#ws.close();
+ }
+ }
+ else {
+ // Release Close
+ globalThis.close();
+ }
+ break;
+ case this.#CMD_CHECK_TK:
+ // Protocol
+ // 0: [SIGNATURE]
+ // 1: [TOKEN]
+ // 2: [ID]
+ // 3: [CMD]
+ // 4: [Status]
+ // 5: [BindsList]
+ const status = (buffer8[this.#PROTOCOL_DATA] == 0 ? false : true);
+ const tokenHex = `0x${this.#token.toString(16).padStart(8, '0')}`;
+ if (status) {
+ if (this.#log) console.log(`WebUI -> CMD -> Token [${tokenHex}] Accepted`);
+ this.#TokenAccepted = true;
+ // Get binds list (CSV)
+ let csv: string = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA + 1);
+ csv = csv.endsWith(',') ? csv.slice(0, -1) : csv;
+ this.#bindsList = csv.split(',');
+ // Generate objects
+ this.#updateBindsList();
+ // User event callback
+ this.#userEventCallback(this.event.CONNECTED);
+ }
+ else {
+ if (this.#log) console.log(`WebUI -> CMD -> Token [${tokenHex}] Not Accepted. Reload page...`);
+ // Refresh the page to get a new token
+ this.#allowNavigation = true;
+ this.#wsStayAlive = false;
+ globalThis.location.reload();
+ }
+ break;
+ }
+ } else {
+ // Raw-binary based commands
+ switch (buffer8[this.#PROTOCOL_CMD]) {
+ case this.#CMD_SEND_RAW:
+ // Protocol
+ // 0: [SIGNATURE]
+ // 1: [TOKEN]
+ // 2: [ID]
+ // 3: [CMD]
+ // 4: [Function,Null,Raw Data]
+ // Get function name
+ const functionName: string = this.#getDataStrFromPacket(buffer8, this.#PROTOCOL_DATA);
+ // Get the raw data
+ const rawDataIndex: number = this.#PROTOCOL_DATA + functionName.length + 1;
+ const rawDataSize: number = (buffer8.length - rawDataIndex) - 1;
+ const userRawData = buffer8.subarray(rawDataIndex, (rawDataIndex + rawDataSize));
+ if (this.#log) console.log(`WebUI -> CMD -> Received Raw ${rawDataSize} bytes for [${functionName}()]`);
+ // Call the user function, and pass the raw data
+ if (typeof window[functionName] === 'function') window[functionName](userRawData);
+ else await AsyncFunction(functionName + '(userRawData)')();
+ break;
+ }
+ }
+ };
+ // -- Public APIs --------------------------
+ /**
+ * Call a backend function
+ *
+ * @param fn - binding name
+ * @param data - data to be send to the backend function
+ * @return - Response of the backend callback string
+ * @example - const res = await webui.call("myID", 123, true, "Hi", new Uint8Array([0x42, 0x43, 0x44]))
+ */
+ async call(fn: string, ...args: DataTypes[]): Promise {
+ if (!fn) return Promise.reject(new SyntaxError('No binding name is provided'));
+
+ if (!this.#wsIsConnected()) return Promise.reject(new Error('WebSocket is not connected'));
+
+ // Check binding list
+ if (fn !== '__webui_core_api__') {
+ if (!this.#AllEvents && !this.#bindsList.includes(`${fn}`))
+ return Promise.reject(new ReferenceError(`No binding was found for "${fn}"`));
+ }
+
+ // Call backend and wait for response
+ if (this.#log) console.log(`WebUI -> Calling [${fn}(...)]`);
+ const response = (await this.#callPromise(fn, ...args)) as string;
+
+ // WebUI lib accept `DataTypes` but return only string
+ if (typeof response !== 'string') return '';
+
+ return response;
+ }
+ /**
+ * Active or deactivate webui debug logging
+ *
+ * @param status - log status to set
+ */
+ setLogging(status: boolean) {
+ if (status) {
+ console.log('WebUI -> Log Enabled.');
+ this.#log = true;
+ } else {
+ console.log('WebUI -> Log Disabled.');
+ this.#log = false;
+ }
+ }
+ /**
+ * Encode text into base64 string
+ *
+ * @param data - text string
+ */
+ encode(data: string): string {
+ return btoa(data);
+ }
+ /**
+ * Decode base64 string into text
+ *
+ * @param data - base64 string
+ */
+ decode(data: string): string {
+ return atob(data);
+ }
+ /**
+ * Set a callback to receive events like connect/disconnect
+ *
+ * @param callback - callback function `myCallback(e)`
+ * @example - webui.setEventCallback((e) => {if(e == webui.event.CONNECTED){ ... }});
+ */
+ setEventCallback(callback: (e: number) => void): void {
+ this.#eventsCallback = callback;
+ }
+ /**
+ * Check if UI is connected to the back-end. The connection
+ * is done by including `webui.js` virtual file in the HTML.
+ *
+ * @return - Boolean `true` if connected
+ */
+ isConnected(): boolean {
+ return ((this.#wsIsConnected()) && (this.#TokenAccepted));
+ }
+ /**
+ * Get OS high contrast preference.
+ *
+ * @return - Boolean `True` if OS is using high contrast theme
+ */
+ async isHighContrast(): Promise {
+ // Call a core function and wait for response
+ const response = await this.callCore("high_contrast") as boolean;
+ if (this.#log) console.log(`Core Response: [${response}]`);
+ return response;
+ }
+ /**
+ * When binding all events on the backend, WebUI blocks all navigation events
+ * and sends them to the backend. This API allows you to control that behavior.
+ *
+ * @param status - Boolean `True` means WebUI will allow navigations
+ * @example - webui.allowNavigation(true); // Allow navigation
+ * window.location.replace('www.test.com'); // This will now proceed as usual
+ */
+ allowNavigation(status: boolean): void {
+ this.#allowNavigation = status;
+ }
+}
+// Export
+type webui = WebuiBridge;
+export default webui;
+export type { WebuiBridge };
+// Wait for the html to be parsed
+addEventListener('load', () => {
+ document.body.addEventListener('contextmenu', (event) => event.preventDefault());
+ addRefreshableEventListener(document.body, 'input', 'contextmenu', (event) => event.stopPropagation());
+});
diff --git a/bridge/webui_bridge.h b/bridge/webui_bridge.h
new file mode 100644
index 0000000..adc2d24
--- /dev/null
+++ b/bridge/webui_bridge.h
@@ -0,0 +1,1892 @@
+// WebUI v2.5.0-beta.4
+// https://webui.me
+// https://github.com/webui-dev/webui
+// Copyright (c) 2020-2026 Hassan Draga.
+// Licensed under MIT License.
+// All rights reserved.
+// Canada.
+
+// --- PLEASE DO NOT EDIT THIS FILE -------
+// --- THIS FILE IS GENERATED BY JS2C.JS --
+
+#ifndef WEBUI_BRIDGE_H
+#define WEBUI_BRIDGE_H
+unsigned char webui_javascript_bridge[] = {
+ 0x2f, 0x2f, 0x20, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x76,
+ 0x32, 0x2e, 0x35, 0x2e, 0x30, 0x2d, 0x62, 0x65, 0x74, 0x61,
+ 0x2e, 0x34, 0x0a, 0x2f, 0x2f, 0x20, 0x68, 0x74, 0x74, 0x70,
+ 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x65, 0x62, 0x75, 0x69, 0x2e,
+ 0x6d, 0x65, 0x0a, 0x2f, 0x2f, 0x20, 0x68, 0x74, 0x74, 0x70,
+ 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
+ 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x77, 0x65, 0x62, 0x75, 0x69,
+ 0x2d, 0x64, 0x65, 0x76, 0x2f, 0x77, 0x65, 0x62, 0x75, 0x69,
+ 0x0a, 0x2f, 0x2f, 0x20, 0x43, 0x6f, 0x70, 0x79, 0x72, 0x69,
+ 0x67, 0x68, 0x74, 0x20, 0x28, 0x63, 0x29, 0x20, 0x32, 0x30,
+ 0x32, 0x30, 0x2d, 0x32, 0x30, 0x32, 0x35, 0x20, 0x48, 0x61,
+ 0x73, 0x73, 0x61, 0x6e, 0x20, 0x44, 0x72, 0x61, 0x67, 0x61,
+ 0x2e, 0x0a, 0x2f, 0x2f, 0x20, 0x4c, 0x69, 0x63, 0x65, 0x6e,
+ 0x73, 0x65, 0x64, 0x20, 0x75, 0x6e, 0x64, 0x65, 0x72, 0x20,
+ 0x4d, 0x49, 0x54, 0x20, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73,
+ 0x65, 0x2e, 0x0a, 0x2f, 0x2f, 0x20, 0x41, 0x6c, 0x6c, 0x20,
+ 0x72, 0x69, 0x67, 0x68, 0x74, 0x73, 0x20, 0x72, 0x65, 0x73,
+ 0x65, 0x72, 0x76, 0x65, 0x64, 0x2e, 0x0a, 0x2f, 0x2f, 0x20,
+ 0x43, 0x61, 0x6e, 0x61, 0x64, 0x61, 0x2e, 0x0a, 0x0a, 0x22,
+ 0x75, 0x73, 0x65, 0x2d, 0x73, 0x74, 0x72, 0x69, 0x63, 0x74,
+ 0x22, 0x3b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x61, 0x64, 0x64, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73,
+ 0x68, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74,
+ 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x72,
+ 0x6f, 0x6f, 0x74, 0x2c, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
+ 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2c, 0x74,
+ 0x79, 0x70, 0x65, 0x2c, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e,
+ 0x65, 0x72, 0x2c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73,
+ 0x29, 0x7b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x72, 0x65, 0x62, 0x69, 0x6e, 0x64, 0x4c, 0x69, 0x73,
+ 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x6d, 0x75, 0x74, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x7b, 0x66, 0x6f, 0x72,
+ 0x28, 0x6c, 0x65, 0x74, 0x20, 0x6d, 0x75, 0x74, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x20, 0x6f, 0x66, 0x20, 0x6d, 0x75, 0x74,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x66, 0x6f, 0x72,
+ 0x28, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x6f, 0x64, 0x65, 0x20,
+ 0x6f, 0x66, 0x20, 0x6d, 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x2e, 0x61, 0x64, 0x64, 0x65, 0x64, 0x4e, 0x6f, 0x64,
+ 0x65, 0x73, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x28, 0x6e,
+ 0x6f, 0x64, 0x65, 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e,
+ 0x63, 0x65, 0x6f, 0x66, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x45,
+ 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x29, 0x29, 0x72, 0x65,
+ 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
+ 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x28, 0x74, 0x61,
+ 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74,
+ 0x6f, 0x72, 0x29, 0x26, 0x26, 0x6e, 0x6f, 0x64, 0x65, 0x2e,
+ 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69,
+ 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x74, 0x79, 0x70,
+ 0x65, 0x2c, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72,
+ 0x2c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29, 0x3b,
+ 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x63, 0x68,
+ 0x69, 0x6c, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x6e, 0x6f, 0x64,
+ 0x65, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x6c,
+ 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c, 0x28, 0x74,
+ 0x61, 0x72, 0x67, 0x65, 0x74, 0x53, 0x65, 0x6c, 0x65, 0x63,
+ 0x74, 0x6f, 0x72, 0x29, 0x29, 0x63, 0x68, 0x69, 0x6c, 0x64,
+ 0x20, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f,
+ 0x66, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x45, 0x6c, 0x65, 0x6d,
+ 0x65, 0x6e, 0x74, 0x26, 0x26, 0x63, 0x68, 0x69, 0x6c, 0x64,
+ 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c,
+ 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x74, 0x79,
+ 0x70, 0x65, 0x2c, 0x6c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65,
+ 0x72, 0x2c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x29,
+ 0x7d, 0x7d, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x62, 0x73, 0x65,
+ 0x72, 0x76, 0x65, 0x72, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x4d,
+ 0x75, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x62, 0x73,
+ 0x65, 0x72, 0x76, 0x65, 0x72, 0x28, 0x72, 0x65, 0x62, 0x69,
+ 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72,
+ 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f,
+ 0x62, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x6f, 0x62,
+ 0x73, 0x65, 0x72, 0x76, 0x65, 0x28, 0x72, 0x6f, 0x6f, 0x74,
+ 0x2c, 0x7b, 0x73, 0x75, 0x62, 0x74, 0x72, 0x65, 0x65, 0x3a,
+ 0x21, 0x30, 0x2c, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x4c, 0x69,
+ 0x73, 0x74, 0x3a, 0x21, 0x30, 0x7d, 0x29, 0x2c, 0x6f, 0x62,
+ 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x7d, 0x76, 0x61, 0x72,
+ 0x20, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x75, 0x6e, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x28, 0x61, 0x73, 0x79, 0x6e,
+ 0x63, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x28, 0x29, 0x7b, 0x7d, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x73,
+ 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72, 0x3b, 0x76, 0x61,
+ 0x72, 0x20, 0x57, 0x65, 0x62, 0x75, 0x69, 0x42, 0x72, 0x69,
+ 0x64, 0x67, 0x65, 0x3d, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x7b,
+ 0x23, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x3b, 0x23, 0x74,
+ 0x6f, 0x6b, 0x65, 0x6e, 0x3b, 0x23, 0x70, 0x6f, 0x72, 0x74,
+ 0x3b, 0x23, 0x6c, 0x6f, 0x67, 0x3b, 0x23, 0x77, 0x69, 0x6e,
+ 0x58, 0x3b, 0x23, 0x77, 0x69, 0x6e, 0x59, 0x3b, 0x23, 0x77,
+ 0x69, 0x6e, 0x57, 0x3b, 0x23, 0x77, 0x69, 0x6e, 0x48, 0x3b,
+ 0x23, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x57, 0x69, 0x6e,
+ 0x64, 0x6f, 0x77, 0x44, 0x72, 0x61, 0x67, 0x3b, 0x23, 0x65,
+ 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x75, 0x73, 0x74, 0x6f,
+ 0x6d, 0x44, 0x72, 0x61, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x3d,
+ 0x21, 0x31, 0x3b, 0x23, 0x69, 0x73, 0x44, 0x72, 0x61, 0x67,
+ 0x67, 0x69, 0x6e, 0x67, 0x3d, 0x21, 0x31, 0x3b, 0x23, 0x69,
+ 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x4d, 0x6f, 0x75, 0x73,
+ 0x65, 0x58, 0x3d, 0x30, 0x3b, 0x23, 0x69, 0x6e, 0x69, 0x74,
+ 0x69, 0x61, 0x6c, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x59, 0x3d,
+ 0x30, 0x3b, 0x23, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c,
+ 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x58, 0x3d, 0x77, 0x69,
+ 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65,
+ 0x6e, 0x58, 0x7c, 0x7c, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77,
+ 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x4c, 0x65, 0x66,
+ 0x74, 0x3b, 0x23, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c,
+ 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x59, 0x3d, 0x77, 0x69,
+ 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65,
+ 0x6e, 0x59, 0x7c, 0x7c, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77,
+ 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x54, 0x6f, 0x70,
+ 0x3b, 0x23, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57,
+ 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x58, 0x3d, 0x77, 0x69, 0x6e,
+ 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e,
+ 0x58, 0x7c, 0x7c, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e,
+ 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x4c, 0x65, 0x66, 0x74,
+ 0x3b, 0x23, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57,
+ 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x59, 0x3d, 0x77, 0x69, 0x6e,
+ 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e,
+ 0x59, 0x7c, 0x7c, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e,
+ 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x54, 0x6f, 0x70, 0x3b,
+ 0x23, 0x77, 0x73, 0x3b, 0x23, 0x77, 0x73, 0x53, 0x74, 0x61,
+ 0x79, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x3d, 0x21, 0x30, 0x3b,
+ 0x23, 0x77, 0x73, 0x53, 0x74, 0x61, 0x79, 0x41, 0x6c, 0x69,
+ 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x3d,
+ 0x35, 0x30, 0x30, 0x3b, 0x23, 0x77, 0x73, 0x57, 0x61, 0x73,
+ 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x3d,
+ 0x21, 0x31, 0x3b, 0x23, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x41,
+ 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x3d, 0x21, 0x31,
+ 0x3b, 0x23, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x61,
+ 0x73, 0x6f, 0x6e, 0x3d, 0x30, 0x3b, 0x23, 0x63, 0x6c, 0x6f,
+ 0x73, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x3b, 0x23, 0x41,
+ 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x3d, 0x21,
+ 0x31, 0x3b, 0x23, 0x63, 0x61, 0x6c, 0x6c, 0x50, 0x72, 0x6f,
+ 0x6d, 0x69, 0x73, 0x65, 0x49, 0x44, 0x3d, 0x6e, 0x65, 0x77,
+ 0x20, 0x55, 0x69, 0x6e, 0x74, 0x31, 0x36, 0x41, 0x72, 0x72,
+ 0x61, 0x79, 0x28, 0x31, 0x29, 0x3b, 0x23, 0x63, 0x61, 0x6c,
+ 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x52, 0x65,
+ 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x3d, 0x5b, 0x5d, 0x3b, 0x23,
+ 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x4e, 0x61, 0x76, 0x69, 0x67,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x21, 0x30, 0x3b, 0x23,
+ 0x73, 0x65, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x75, 0x65, 0x3d,
+ 0x5b, 0x5d, 0x3b, 0x23, 0x69, 0x73, 0x53, 0x65, 0x6e, 0x64,
+ 0x69, 0x6e, 0x67, 0x3d, 0x21, 0x31, 0x3b, 0x23, 0x62, 0x69,
+ 0x6e, 0x64, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x3b, 0x23, 0x57,
+ 0x45, 0x42, 0x55, 0x49, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41,
+ 0x54, 0x55, 0x52, 0x45, 0x3d, 0x32, 0x32, 0x31, 0x3b, 0x23,
+ 0x43, 0x4d, 0x44, 0x5f, 0x4a, 0x53, 0x3d, 0x32, 0x35, 0x34,
+ 0x3b, 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x4a, 0x53, 0x5f, 0x51,
+ 0x55, 0x49, 0x43, 0x4b, 0x3d, 0x32, 0x35, 0x33, 0x3b, 0x23,
+ 0x43, 0x4d, 0x44, 0x5f, 0x43, 0x4c, 0x49, 0x43, 0x4b, 0x3d,
+ 0x32, 0x35, 0x32, 0x3b, 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x4e,
+ 0x41, 0x56, 0x49, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x3d,
+ 0x32, 0x35, 0x31, 0x3b, 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x43,
+ 0x4c, 0x4f, 0x53, 0x45, 0x3d, 0x32, 0x35, 0x30, 0x3b, 0x23,
+ 0x43, 0x4d, 0x44, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x5f, 0x46,
+ 0x55, 0x4e, 0x43, 0x3d, 0x32, 0x34, 0x39, 0x3b, 0x23, 0x43,
+ 0x4d, 0x44, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x52, 0x41,
+ 0x57, 0x3d, 0x32, 0x34, 0x38, 0x3b, 0x23, 0x43, 0x4d, 0x44,
+ 0x5f, 0x4e, 0x45, 0x57, 0x5f, 0x49, 0x44, 0x3d, 0x32, 0x34,
+ 0x37, 0x3b, 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x4d, 0x55, 0x4c,
+ 0x54, 0x49, 0x3d, 0x32, 0x34, 0x36, 0x3b, 0x23, 0x43, 0x4d,
+ 0x44, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x54, 0x4b,
+ 0x3d, 0x32, 0x34, 0x35, 0x3b, 0x23, 0x43, 0x4d, 0x44, 0x5f,
+ 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x5f, 0x44, 0x52, 0x41,
+ 0x47, 0x3d, 0x32, 0x34, 0x34, 0x3b, 0x23, 0x43, 0x4d, 0x44,
+ 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57, 0x5f, 0x52, 0x45,
+ 0x53, 0x49, 0x5a, 0x45, 0x44, 0x3d, 0x32, 0x34, 0x33, 0x3b,
+ 0x23, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x43, 0x48, 0x55,
+ 0x4e, 0x4b, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x3d, 0x36, 0x35,
+ 0x35, 0x30, 0x30, 0x3b, 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f,
+ 0x43, 0x4f, 0x4c, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x3d, 0x38,
+ 0x3b, 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c,
+ 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x3d, 0x30, 0x3b, 0x23, 0x50,
+ 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x54, 0x4f,
+ 0x4b, 0x45, 0x4e, 0x3d, 0x31, 0x3b, 0x23, 0x50, 0x52, 0x4f,
+ 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x49, 0x44, 0x3d, 0x35,
+ 0x3b, 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c,
+ 0x5f, 0x43, 0x4d, 0x44, 0x3d, 0x37, 0x3b, 0x23, 0x50, 0x52,
+ 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x44, 0x41, 0x54,
+ 0x41, 0x3d, 0x38, 0x3b, 0x23, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
+ 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x55, 0x69, 0x6e, 0x74, 0x33,
+ 0x32, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x31, 0x29, 0x3b,
+ 0x23, 0x50, 0x69, 0x6e, 0x67, 0x3d, 0x21, 0x30, 0x3b, 0x23,
+ 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x61, 0x6c, 0x6c,
+ 0x62, 0x61, 0x63, 0x6b, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3b,
+ 0x23, 0x6c, 0x61, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74,
+ 0x3d, 0x2d, 0x31, 0x3b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3d,
+ 0x7b, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44,
+ 0x3a, 0x30, 0x2c, 0x44, 0x49, 0x53, 0x43, 0x4f, 0x4e, 0x4e,
+ 0x45, 0x43, 0x54, 0x45, 0x44, 0x3a, 0x31, 0x7d, 0x3b, 0x63,
+ 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x75, 0x63, 0x74, 0x6f, 0x72,
+ 0x28, 0x7b, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x3d, 0x21,
+ 0x31, 0x2c, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3d, 0x30, 0x2c,
+ 0x70, 0x6f, 0x72, 0x74, 0x3d, 0x30, 0x2c, 0x6c, 0x6f, 0x67,
+ 0x3d, 0x21, 0x31, 0x2c, 0x77, 0x69, 0x6e, 0x58, 0x3d, 0x30,
+ 0x2c, 0x77, 0x69, 0x6e, 0x59, 0x3d, 0x30, 0x2c, 0x77, 0x69,
+ 0x6e, 0x57, 0x3d, 0x30, 0x2c, 0x77, 0x69, 0x6e, 0x48, 0x3d,
+ 0x30, 0x2c, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x57, 0x69,
+ 0x6e, 0x64, 0x6f, 0x77, 0x44, 0x72, 0x61, 0x67, 0x3d, 0x21,
+ 0x31, 0x7d, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x3d,
+ 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x2c, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3d, 0x74,
+ 0x6f, 0x6b, 0x65, 0x6e, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x70, 0x6f, 0x72, 0x74, 0x3d, 0x70, 0x6f, 0x72, 0x74,
+ 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67,
+ 0x3d, 0x6c, 0x6f, 0x67, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x77, 0x69, 0x6e, 0x58, 0x3d, 0x77, 0x69, 0x6e, 0x58,
+ 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x69, 0x6e,
+ 0x59, 0x3d, 0x77, 0x69, 0x6e, 0x59, 0x2c, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x77, 0x69, 0x6e, 0x57, 0x3d, 0x77, 0x69,
+ 0x6e, 0x57, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77,
+ 0x69, 0x6e, 0x48, 0x3d, 0x77, 0x69, 0x6e, 0x48, 0x2c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x65, 0x6e, 0x61, 0x62, 0x6c,
+ 0x65, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x44, 0x72, 0x61,
+ 0x67, 0x67, 0x69, 0x6e, 0x67, 0x3d, 0x63, 0x75, 0x73, 0x74,
+ 0x6f, 0x6d, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x44, 0x72,
+ 0x61, 0x67, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x54,
+ 0x6f, 0x6b, 0x65, 0x6e, 0x5b, 0x30, 0x5d, 0x3d, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2c,
+ 0x22, 0x77, 0x65, 0x62, 0x75, 0x69, 0x22, 0x69, 0x6e, 0x20,
+ 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x54, 0x68, 0x69, 0x73,
+ 0x29, 0x74, 0x68, 0x72, 0x6f, 0x77, 0x20, 0x6e, 0x65, 0x77,
+ 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x53, 0x6f,
+ 0x72, 0x72, 0x79, 0x2e, 0x20, 0x57, 0x65, 0x62, 0x55, 0x49,
+ 0x20, 0x69, 0x73, 0x20, 0x61, 0x6c, 0x72, 0x65, 0x61, 0x64,
+ 0x79, 0x20, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x2c,
+ 0x20, 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x65, 0x20,
+ 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x69,
+ 0x73, 0x20, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x2e,
+ 0x22, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77,
+ 0x69, 0x6e, 0x58, 0x21, 0x3d, 0x3d, 0x76, 0x6f, 0x69, 0x64,
+ 0x20, 0x30, 0x26, 0x26, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x77, 0x69, 0x6e, 0x59, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x77, 0x69, 0x6e, 0x57, 0x21, 0x3d, 0x3d, 0x76, 0x6f,
+ 0x69, 0x64, 0x20, 0x30, 0x26, 0x26, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x77, 0x69, 0x6e, 0x48, 0x2c, 0x22, 0x57, 0x65,
+ 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x22, 0x69, 0x6e,
+ 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x7c, 0x7c, 0x28,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x73, 0x68, 0x6f, 0x77,
+ 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x28, 0x22, 0x57,
+ 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x20, 0x69,
+ 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x73, 0x75, 0x70, 0x70,
+ 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x79,
+ 0x6f, 0x75, 0x72, 0x20, 0x77, 0x65, 0x62, 0x20, 0x62, 0x72,
+ 0x6f, 0x77, 0x73, 0x65, 0x72, 0x22, 0x29, 0x2c, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x7c, 0x7c, 0x67,
+ 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x54, 0x68, 0x69, 0x73, 0x2e,
+ 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x28, 0x29, 0x29, 0x2c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x73, 0x74, 0x61, 0x72, 0x74,
+ 0x28, 0x29, 0x2c, 0x22, 0x6e, 0x61, 0x76, 0x69, 0x67, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x69, 0x6e, 0x20, 0x67, 0x6c,
+ 0x6f, 0x62, 0x61, 0x6c, 0x54, 0x68, 0x69, 0x73, 0x3f, 0x67,
+ 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x54, 0x68, 0x69, 0x73, 0x2e,
+ 0x6e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c,
+ 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22, 0x6e,
+ 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x65, 0x22, 0x2c, 0x65,
+ 0x76, 0x65, 0x6e, 0x74, 0x3d, 0x3e, 0x7b, 0x69, 0x66, 0x28,
+ 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x61, 0x6c, 0x6c,
+ 0x6f, 0x77, 0x4e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x26, 0x26, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x41, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x26,
+ 0x26, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x49,
+ 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64,
+ 0x28, 0x29, 0x29, 0x7b, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e,
+ 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x44, 0x65, 0x66,
+ 0x61, 0x75, 0x6c, 0x74, 0x28, 0x29, 0x3b, 0x6c, 0x65, 0x74,
+ 0x20, 0x75, 0x72, 0x6c, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x55,
+ 0x52, 0x4c, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x64,
+ 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+ 0x2e, 0x75, 0x72, 0x6c, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x26, 0x26, 0x63, 0x6f, 0x6e,
+ 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x60,
+ 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x44,
+ 0x4f, 0x4d, 0x20, 0x2d, 0x3e, 0x20, 0x4e, 0x61, 0x76, 0x69,
+ 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45, 0x76, 0x65,
+ 0x6e, 0x74, 0x20, 0x5b, 0x24, 0x7b, 0x75, 0x72, 0x6c, 0x2e,
+ 0x68, 0x72, 0x65, 0x66, 0x7d, 0x5d, 0x60, 0x29, 0x2c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x73, 0x65, 0x6e, 0x64, 0x45,
+ 0x76, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x76, 0x69, 0x67, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x75, 0x72, 0x6c, 0x2e, 0x68,
+ 0x72, 0x65, 0x66, 0x29, 0x7d, 0x7d, 0x29, 0x3a, 0x61, 0x64,
+ 0x64, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x61, 0x62,
+ 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73,
+ 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x64, 0x6f, 0x63, 0x75,
+ 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2c,
+ 0x22, 0x61, 0x22, 0x2c, 0x22, 0x63, 0x6c, 0x69, 0x63, 0x6b,
+ 0x22, 0x2c, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3d, 0x3e, 0x7b,
+ 0x69, 0x66, 0x28, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x4e, 0x61, 0x76, 0x69, 0x67,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x26, 0x26, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x41, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e,
+ 0x74, 0x73, 0x26, 0x26, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x77, 0x73, 0x49, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
+ 0x74, 0x65, 0x64, 0x28, 0x29, 0x29, 0x7b, 0x65, 0x76, 0x65,
+ 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74,
+ 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x28, 0x29, 0x3b,
+ 0x6c, 0x65, 0x74, 0x7b, 0x68, 0x72, 0x65, 0x66, 0x7d, 0x3d,
+ 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x74, 0x61, 0x72, 0x67,
+ 0x65, 0x74, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c,
+ 0x6f, 0x67, 0x26, 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c,
+ 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x60, 0x57, 0x65, 0x62,
+ 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x44, 0x4f, 0x4d, 0x20,
+ 0x2d, 0x3e, 0x20, 0x4e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x20, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x20,
+ 0x45, 0x76, 0x65, 0x6e, 0x74, 0x20, 0x5b, 0x24, 0x7b, 0x68,
+ 0x72, 0x65, 0x66, 0x7d, 0x5d, 0x60, 0x29, 0x2c, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x73, 0x65, 0x6e, 0x64, 0x45, 0x76,
+ 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x76, 0x69, 0x67, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x28, 0x68, 0x72, 0x65, 0x66, 0x29, 0x7d,
+ 0x7d, 0x29, 0x2c, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e,
+ 0x74, 0x2e, 0x61, 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74,
+ 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22,
+ 0x6b, 0x65, 0x79, 0x64, 0x6f, 0x77, 0x6e, 0x22, 0x2c, 0x65,
+ 0x76, 0x65, 0x6e, 0x74, 0x3d, 0x3e, 0x7b, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x7c, 0x7c, 0x65, 0x76,
+ 0x65, 0x6e, 0x74, 0x2e, 0x6b, 0x65, 0x79, 0x3d, 0x3d, 0x3d,
+ 0x22, 0x46, 0x35, 0x22, 0x26, 0x26, 0x65, 0x76, 0x65, 0x6e,
+ 0x74, 0x2e, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x44,
+ 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x28, 0x29, 0x7d, 0x29,
+ 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x65, 0x6e, 0x61,
+ 0x62, 0x6c, 0x65, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x44,
+ 0x72, 0x61, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x26, 0x26, 0x28,
+ 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x61,
+ 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73,
+ 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22, 0x6d, 0x6f, 0x75,
+ 0x73, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x22, 0x2c, 0x65, 0x3d,
+ 0x3e, 0x7b, 0x69, 0x66, 0x28, 0x65, 0x2e, 0x62, 0x75, 0x74,
+ 0x74, 0x6f, 0x6e, 0x73, 0x21, 0x3d, 0x3d, 0x31, 0x29, 0x7b,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x69, 0x73, 0x44, 0x72,
+ 0x61, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x3d, 0x21, 0x31, 0x3b,
+ 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x69, 0x66, 0x28,
+ 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x69, 0x73, 0x44,
+ 0x72, 0x61, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x29, 0x7b, 0x6c,
+ 0x65, 0x74, 0x20, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3d,
+ 0x65, 0x2e, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x3b, 0x66,
+ 0x6f, 0x72, 0x28, 0x3b, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
+ 0x3b, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x77, 0x69, 0x6e, 0x64,
+ 0x6f, 0x77, 0x2e, 0x67, 0x65, 0x74, 0x43, 0x6f, 0x6d, 0x70,
+ 0x75, 0x74, 0x65, 0x64, 0x53, 0x74, 0x79, 0x6c, 0x65, 0x28,
+ 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x29, 0x2e, 0x67, 0x65,
+ 0x74, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x79, 0x56,
+ 0x61, 0x6c, 0x75, 0x65, 0x28, 0x22, 0x2d, 0x2d, 0x77, 0x65,
+ 0x62, 0x75, 0x69, 0x2d, 0x61, 0x70, 0x70, 0x2d, 0x72, 0x65,
+ 0x67, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x2e, 0x74, 0x72, 0x69,
+ 0x6d, 0x28, 0x29, 0x3d, 0x3d, 0x3d, 0x22, 0x64, 0x72, 0x61,
+ 0x67, 0x22, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x4d, 0x6f, 0x75,
+ 0x73, 0x65, 0x58, 0x3d, 0x65, 0x2e, 0x73, 0x63, 0x72, 0x65,
+ 0x65, 0x6e, 0x58, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x4d, 0x6f, 0x75,
+ 0x73, 0x65, 0x59, 0x3d, 0x65, 0x2e, 0x73, 0x63, 0x72, 0x65,
+ 0x65, 0x6e, 0x59, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x57, 0x69, 0x6e,
+ 0x64, 0x6f, 0x77, 0x58, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x69,
+ 0x6e, 0x64, 0x6f, 0x77, 0x58, 0x2c, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x57,
+ 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x59, 0x3d, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74,
+ 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x59, 0x2c, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x69, 0x73, 0x44, 0x72, 0x61, 0x67,
+ 0x67, 0x69, 0x6e, 0x67, 0x3d, 0x21, 0x30, 0x3b, 0x62, 0x72,
+ 0x65, 0x61, 0x6b, 0x7d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74,
+ 0x3d, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x2e, 0x70, 0x61,
+ 0x72, 0x65, 0x6e, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
+ 0x74, 0x7d, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7d, 0x6c,
+ 0x65, 0x74, 0x20, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x58, 0x3d,
+ 0x65, 0x2e, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x58, 0x2d,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x69, 0x6e, 0x69, 0x74,
+ 0x69, 0x61, 0x6c, 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x58, 0x2c,
+ 0x64, 0x65, 0x6c, 0x74, 0x61, 0x59, 0x3d, 0x65, 0x2e, 0x73,
+ 0x63, 0x72, 0x65, 0x65, 0x6e, 0x59, 0x2d, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c,
+ 0x4d, 0x6f, 0x75, 0x73, 0x65, 0x59, 0x2c, 0x6e, 0x65, 0x77,
+ 0x58, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x69, 0x6e,
+ 0x69, 0x74, 0x69, 0x61, 0x6c, 0x57, 0x69, 0x6e, 0x64, 0x6f,
+ 0x77, 0x58, 0x2b, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x58, 0x2c,
+ 0x6e, 0x65, 0x77, 0x59, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x57, 0x69,
+ 0x6e, 0x64, 0x6f, 0x77, 0x59, 0x2b, 0x64, 0x65, 0x6c, 0x74,
+ 0x61, 0x59, 0x3b, 0x6e, 0x65, 0x77, 0x58, 0x3c, 0x30, 0x26,
+ 0x26, 0x28, 0x6e, 0x65, 0x77, 0x58, 0x3d, 0x30, 0x29, 0x2c,
+ 0x6e, 0x65, 0x77, 0x59, 0x3c, 0x30, 0x26, 0x26, 0x28, 0x6e,
+ 0x65, 0x77, 0x59, 0x3d, 0x30, 0x29, 0x2c, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x73, 0x65, 0x6e, 0x64, 0x44, 0x72, 0x61,
+ 0x67, 0x28, 0x6e, 0x65, 0x77, 0x58, 0x2c, 0x6e, 0x65, 0x77,
+ 0x59, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63,
+ 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x69, 0x6e, 0x64,
+ 0x6f, 0x77, 0x58, 0x3d, 0x6e, 0x65, 0x77, 0x58, 0x2c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x75, 0x72, 0x72, 0x65,
+ 0x6e, 0x74, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x59, 0x3d,
+ 0x6e, 0x65, 0x77, 0x59, 0x7d, 0x29, 0x2c, 0x64, 0x6f, 0x63,
+ 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x61, 0x64, 0x64, 0x45,
+ 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e,
+ 0x65, 0x72, 0x28, 0x22, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x75,
+ 0x70, 0x22, 0x2c, 0x28, 0x29, 0x3d, 0x3e, 0x7b, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x69, 0x73, 0x44, 0x72, 0x61, 0x67,
+ 0x67, 0x69, 0x6e, 0x67, 0x3d, 0x21, 0x31, 0x7d, 0x29, 0x29,
+ 0x2c, 0x6f, 0x6e, 0x62, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x75,
+ 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x3d, 0x28, 0x29, 0x3d, 0x3e,
+ 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x6c, 0x6f,
+ 0x73, 0x65, 0x28, 0x29, 0x7d, 0x2c, 0x73, 0x65, 0x74, 0x54,
+ 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x28, 0x29, 0x3d,
+ 0x3e, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73,
+ 0x57, 0x61, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
+ 0x65, 0x64, 0x7c, 0x7c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x73, 0x68, 0x6f, 0x77, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e,
+ 0x67, 0x28, 0x22, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20,
+ 0x74, 0x6f, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
+ 0x20, 0x74, 0x6f, 0x20, 0x74, 0x68, 0x65, 0x20, 0x62, 0x61,
+ 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x20, 0x61, 0x70, 0x70, 0x6c,
+ 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x29, 0x7d,
+ 0x2c, 0x35, 0x65, 0x33, 0x29, 0x7d, 0x23, 0x63, 0x6c, 0x6f,
+ 0x73, 0x65, 0x28, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x3d,
+ 0x30, 0x2c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3d, 0x22, 0x22,
+ 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x6c,
+ 0x6f, 0x73, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x3d,
+ 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x2c, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x56, 0x61,
+ 0x6c, 0x75, 0x65, 0x3d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x49, 0x73,
+ 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x28,
+ 0x29, 0x26, 0x26, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77,
+ 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x28, 0x29, 0x7d,
+ 0x23, 0x73, 0x68, 0x6f, 0x77, 0x57, 0x61, 0x72, 0x6e, 0x69,
+ 0x6e, 0x67, 0x28, 0x6d, 0x73, 0x67, 0x29, 0x7b, 0x73, 0x65,
+ 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x28,
+ 0x29, 0x3d, 0x3e, 0x7b, 0x69, 0x66, 0x28, 0x21, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x49, 0x73, 0x43, 0x6f,
+ 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x28, 0x29, 0x29,
+ 0x7b, 0x69, 0x66, 0x28, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65,
+ 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d,
+ 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x77,
+ 0x65, 0x62, 0x75, 0x69, 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72,
+ 0x2d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x2d, 0x6c, 0x6f, 0x73, 0x74, 0x22, 0x29, 0x29, 0x72,
+ 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3b, 0x6c, 0x65, 0x74, 0x20,
+ 0x64, 0x69, 0x76, 0x3d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65,
+ 0x6e, 0x74, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45,
+ 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x28, 0x22, 0x64, 0x69,
+ 0x76, 0x22, 0x29, 0x3b, 0x64, 0x69, 0x76, 0x2e, 0x69, 0x64,
+ 0x3d, 0x22, 0x77, 0x65, 0x62, 0x75, 0x69, 0x2d, 0x65, 0x72,
+ 0x72, 0x6f, 0x72, 0x2d, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x6c, 0x6f, 0x73, 0x74, 0x22,
+ 0x2c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x2e, 0x61, 0x73,
+ 0x73, 0x69, 0x67, 0x6e, 0x28, 0x64, 0x69, 0x76, 0x2e, 0x73,
+ 0x74, 0x79, 0x6c, 0x65, 0x2c, 0x7b, 0x70, 0x6f, 0x73, 0x69,
+ 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x22, 0x66, 0x69, 0x78, 0x65,
+ 0x64, 0x22, 0x2c, 0x74, 0x6f, 0x70, 0x3a, 0x22, 0x30, 0x22,
+ 0x2c, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x22, 0x30, 0x22, 0x2c,
+ 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x22, 0x31, 0x30, 0x30,
+ 0x25, 0x22, 0x2c, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f,
+ 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x22,
+ 0x72, 0x67, 0x62, 0x28, 0x31, 0x39, 0x31, 0x20, 0x31, 0x32,
+ 0x35, 0x20, 0x33, 0x30, 0x20, 0x2f, 0x20, 0x38, 0x34, 0x25,
+ 0x29, 0x22, 0x2c, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x22,
+ 0x23, 0x66, 0x66, 0x66, 0x22, 0x2c, 0x74, 0x65, 0x78, 0x74,
+ 0x41, 0x6c, 0x69, 0x67, 0x6e, 0x3a, 0x22, 0x63, 0x65, 0x6e,
+ 0x74, 0x65, 0x72, 0x22, 0x2c, 0x70, 0x61, 0x64, 0x64, 0x69,
+ 0x6e, 0x67, 0x3a, 0x22, 0x34, 0x70, 0x78, 0x20, 0x30, 0x22,
+ 0x2c, 0x66, 0x6f, 0x6e, 0x74, 0x46, 0x61, 0x6d, 0x69, 0x6c,
+ 0x79, 0x3a, 0x22, 0x41, 0x72, 0x69, 0x61, 0x6c, 0x2c, 0x20,
+ 0x73, 0x61, 0x6e, 0x73, 0x2d, 0x73, 0x65, 0x72, 0x69, 0x66,
+ 0x22, 0x2c, 0x66, 0x6f, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65,
+ 0x3a, 0x22, 0x31, 0x36, 0x70, 0x78, 0x22, 0x2c, 0x7a, 0x49,
+ 0x6e, 0x64, 0x65, 0x78, 0x3a, 0x22, 0x39, 0x30, 0x30, 0x30,
+ 0x22, 0x2c, 0x6c, 0x69, 0x6e, 0x65, 0x48, 0x65, 0x69, 0x67,
+ 0x68, 0x74, 0x3a, 0x22, 0x31, 0x22, 0x7d, 0x29, 0x2c, 0x64,
+ 0x69, 0x76, 0x2e, 0x69, 0x6e, 0x6e, 0x65, 0x72, 0x48, 0x54,
+ 0x4d, 0x4c, 0x3d, 0x22, 0x3c, 0x73, 0x74, 0x72, 0x6f, 0x6e,
+ 0x67, 0x3e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x3c, 0x2f,
+ 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x3e, 0x20, 0x22, 0x2b,
+ 0x6d, 0x73, 0x67, 0x2b, 0x22, 0x20, 0x2d, 0x20, 0x3c, 0x65,
+ 0x6d, 0x3e, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x32, 0x2e,
+ 0x35, 0x2e, 0x30, 0x2d, 0x62, 0x65, 0x74, 0x61, 0x2e, 0x34,
+ 0x3c, 0x2f, 0x65, 0x6d, 0x3e, 0x22, 0x2c, 0x64, 0x6f, 0x63,
+ 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x62, 0x6f, 0x64, 0x79,
+ 0x2e, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x42, 0x65, 0x66,
+ 0x6f, 0x72, 0x65, 0x28, 0x64, 0x69, 0x76, 0x2c, 0x64, 0x6f,
+ 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x62, 0x6f, 0x64,
+ 0x79, 0x2e, 0x66, 0x69, 0x72, 0x73, 0x74, 0x43, 0x68, 0x69,
+ 0x6c, 0x64, 0x29, 0x7d, 0x7d, 0x2c, 0x31, 0x65, 0x33, 0x29,
+ 0x7d, 0x23, 0x66, 0x72, 0x65, 0x65, 0x7a, 0x65, 0x55, 0x69,
+ 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x65,
+ 0x76, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x61, 0x6c, 0x6c, 0x62,
+ 0x61, 0x63, 0x6b, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x26,
+ 0x26, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x73, 0x68, 0x6f,
+ 0x77, 0x57, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x28, 0x22,
+ 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+ 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x74, 0x68, 0x65, 0x20,
+ 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x20, 0x69, 0x73,
+ 0x20, 0x6c, 0x6f, 0x73, 0x74, 0x22, 0x29, 0x7d, 0x23, 0x75,
+ 0x6e, 0x66, 0x72, 0x65, 0x65, 0x7a, 0x65, 0x55, 0x49, 0x28,
+ 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x64, 0x69, 0x76, 0x3d,
+ 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67,
+ 0x65, 0x74, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42,
+ 0x79, 0x49, 0x64, 0x28, 0x22, 0x77, 0x65, 0x62, 0x75, 0x69,
+ 0x2d, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x2d, 0x63, 0x6f, 0x6e,
+ 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x6c, 0x6f,
+ 0x73, 0x74, 0x22, 0x29, 0x3b, 0x64, 0x69, 0x76, 0x26, 0x26,
+ 0x64, 0x69, 0x76, 0x2e, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65,
+ 0x28, 0x29, 0x7d, 0x23, 0x69, 0x73, 0x54, 0x65, 0x78, 0x74,
+ 0x42, 0x61, 0x73, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61,
+ 0x6e, 0x64, 0x28, 0x63, 0x6d, 0x64, 0x29, 0x7b, 0x72, 0x65,
+ 0x74, 0x75, 0x72, 0x6e, 0x20, 0x63, 0x6d, 0x64, 0x21, 0x3d,
+ 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x43, 0x4d, 0x44,
+ 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x52, 0x41, 0x57, 0x7d,
+ 0x23, 0x70, 0x61, 0x72, 0x73, 0x65, 0x44, 0x69, 0x6d, 0x65,
+ 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x28, 0x69, 0x6e, 0x70,
+ 0x75, 0x74, 0x29, 0x7b, 0x74, 0x72, 0x79, 0x7b, 0x6c, 0x65,
+ 0x74, 0x20, 0x70, 0x61, 0x72, 0x74, 0x73, 0x3d, 0x69, 0x6e,
+ 0x70, 0x75, 0x74, 0x2e, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28,
+ 0x22, 0x2c, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x70, 0x61,
+ 0x72, 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,
+ 0x21, 0x3d, 0x3d, 0x34, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72,
+ 0x6e, 0x7b, 0x78, 0x3a, 0x30, 0x2c, 0x79, 0x3a, 0x30, 0x2c,
+ 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x30, 0x2c, 0x68, 0x65,
+ 0x69, 0x67, 0x68, 0x74, 0x3a, 0x30, 0x7d, 0x3b, 0x6c, 0x65,
+ 0x74, 0x20, 0x78, 0x3d, 0x70, 0x61, 0x72, 0x73, 0x65, 0x46,
+ 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x70, 0x61, 0x72, 0x74, 0x73,
+ 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x79, 0x3d, 0x70, 0x61, 0x72,
+ 0x73, 0x65, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x70, 0x61,
+ 0x72, 0x74, 0x73, 0x5b, 0x31, 0x5d, 0x29, 0x2c, 0x77, 0x69,
+ 0x64, 0x74, 0x68, 0x3d, 0x70, 0x61, 0x72, 0x73, 0x65, 0x46,
+ 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x70, 0x61, 0x72, 0x74, 0x73,
+ 0x5b, 0x32, 0x5d, 0x29, 0x2c, 0x68, 0x65, 0x69, 0x67, 0x68,
+ 0x74, 0x3d, 0x70, 0x61, 0x72, 0x73, 0x65, 0x46, 0x6c, 0x6f,
+ 0x61, 0x74, 0x28, 0x70, 0x61, 0x72, 0x74, 0x73, 0x5b, 0x33,
+ 0x5d, 0x29, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5b,
+ 0x78, 0x2c, 0x79, 0x2c, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2c,
+ 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x5d, 0x2e, 0x73, 0x6f,
+ 0x6d, 0x65, 0x28, 0x69, 0x73, 0x4e, 0x61, 0x4e, 0x29, 0x3f,
+ 0x7b, 0x78, 0x3a, 0x30, 0x2c, 0x79, 0x3a, 0x30, 0x2c, 0x77,
+ 0x69, 0x64, 0x74, 0x68, 0x3a, 0x30, 0x2c, 0x68, 0x65, 0x69,
+ 0x67, 0x68, 0x74, 0x3a, 0x30, 0x7d, 0x3a, 0x7b, 0x78, 0x2c,
+ 0x79, 0x2c, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x68, 0x65,
+ 0x69, 0x67, 0x68, 0x74, 0x7d, 0x7d, 0x63, 0x61, 0x74, 0x63,
+ 0x68, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x7b, 0x78,
+ 0x3a, 0x30, 0x2c, 0x79, 0x3a, 0x30, 0x2c, 0x77, 0x69, 0x64,
+ 0x74, 0x68, 0x3a, 0x30, 0x2c, 0x68, 0x65, 0x69, 0x67, 0x68,
+ 0x74, 0x3a, 0x30, 0x7d, 0x7d, 0x7d, 0x23, 0x67, 0x65, 0x74,
+ 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x72, 0x46, 0x72, 0x6f,
+ 0x6d, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x28, 0x62, 0x75,
+ 0x66, 0x66, 0x65, 0x72, 0x2c, 0x73, 0x74, 0x61, 0x72, 0x74,
+ 0x49, 0x6e, 0x64, 0x65, 0x78, 0x29, 0x7b, 0x6c, 0x65, 0x74,
+ 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x79, 0x74,
+ 0x65, 0x73, 0x3d, 0x5b, 0x5d, 0x3b, 0x66, 0x6f, 0x72, 0x28,
+ 0x6c, 0x65, 0x74, 0x20, 0x69, 0x3d, 0x73, 0x74, 0x61, 0x72,
+ 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3b, 0x69, 0x3c, 0x62,
+ 0x75, 0x66, 0x66, 0x65, 0x72, 0x2e, 0x6c, 0x65, 0x6e, 0x67,
+ 0x74, 0x68, 0x26, 0x26, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72,
+ 0x5b, 0x69, 0x5d, 0x21, 0x3d, 0x3d, 0x30, 0x3b, 0x69, 0x2b,
+ 0x2b, 0x29, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x79,
+ 0x74, 0x65, 0x73, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28, 0x62,
+ 0x75, 0x66, 0x66, 0x65, 0x72, 0x5b, 0x69, 0x5d, 0x29, 0x3b,
+ 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x65, 0x77,
+ 0x20, 0x54, 0x65, 0x78, 0x74, 0x44, 0x65, 0x63, 0x6f, 0x64,
+ 0x65, 0x72, 0x28, 0x29, 0x2e, 0x64, 0x65, 0x63, 0x6f, 0x64,
+ 0x65, 0x28, 0x6e, 0x65, 0x77, 0x20, 0x55, 0x69, 0x6e, 0x74,
+ 0x38, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x73, 0x74, 0x72,
+ 0x69, 0x6e, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73, 0x29, 0x29,
+ 0x7d, 0x23, 0x67, 0x65, 0x74, 0x49, 0x44, 0x28, 0x62, 0x75,
+ 0x66, 0x66, 0x65, 0x72, 0x2c, 0x69, 0x6e, 0x64, 0x65, 0x78,
+ 0x29, 0x7b, 0x69, 0x66, 0x28, 0x69, 0x6e, 0x64, 0x65, 0x78,
+ 0x3c, 0x30, 0x7c, 0x7c, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3e,
+ 0x3d, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x2e, 0x6c, 0x65,
+ 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x31, 0x29, 0x74, 0x68, 0x72,
+ 0x6f, 0x77, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x45, 0x72, 0x72,
+ 0x6f, 0x72, 0x28, 0x22, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x20,
+ 0x6f, 0x75, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x62, 0x6f, 0x75,
+ 0x6e, 0x64, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x73,
+ 0x75, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x20,
+ 0x64, 0x61, 0x74, 0x61, 0x2e, 0x22, 0x29, 0x3b, 0x6c, 0x65,
+ 0x74, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x42, 0x79, 0x74,
+ 0x65, 0x3d, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5b, 0x69,
+ 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x3b, 0x72, 0x65, 0x74, 0x75,
+ 0x72, 0x6e, 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5b,
+ 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2b, 0x31, 0x5d, 0x3c, 0x3c,
+ 0x38, 0x7c, 0x66, 0x69, 0x72, 0x73, 0x74, 0x42, 0x79, 0x74,
+ 0x65, 0x7d, 0x23, 0x61, 0x64, 0x64, 0x54, 0x6f, 0x6b, 0x65,
+ 0x6e, 0x28, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x2c, 0x76,
+ 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x69, 0x6e, 0x64, 0x65, 0x78,
+ 0x29, 0x7b, 0x69, 0x66, 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x3c, 0x30, 0x7c, 0x7c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3e,
+ 0x34, 0x32, 0x39, 0x34, 0x39, 0x36, 0x37, 0x32, 0x39, 0x35,
+ 0x29, 0x74, 0x68, 0x72, 0x6f, 0x77, 0x20, 0x6e, 0x65, 0x77,
+ 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x4e, 0x75,
+ 0x6d, 0x62, 0x65, 0x72, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x75,
+ 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72,
+ 0x61, 0x6e, 0x67, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x34,
+ 0x20, 0x62, 0x79, 0x74, 0x65, 0x73, 0x20, 0x72, 0x65, 0x70,
+ 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x2e, 0x22, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x69, 0x6e,
+ 0x64, 0x65, 0x78, 0x3c, 0x30, 0x7c, 0x7c, 0x69, 0x6e, 0x64,
+ 0x65, 0x78, 0x3e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x2e,
+ 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x34, 0x29, 0x74,
+ 0x68, 0x72, 0x6f, 0x77, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x45,
+ 0x72, 0x72, 0x6f, 0x72, 0x28, 0x22, 0x49, 0x6e, 0x64, 0x65,
+ 0x78, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x62,
+ 0x6f, 0x75, 0x6e, 0x64, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x69,
+ 0x6e, 0x73, 0x75, 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e,
+ 0x74, 0x20, 0x73, 0x70, 0x61, 0x63, 0x65, 0x20, 0x69, 0x6e,
+ 0x20, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x2e, 0x22, 0x29,
+ 0x3b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5b, 0x69, 0x6e,
+ 0x64, 0x65, 0x78, 0x5d, 0x3d, 0x76, 0x61, 0x6c, 0x75, 0x65,
+ 0x26, 0x32, 0x35, 0x35, 0x2c, 0x62, 0x75, 0x66, 0x66, 0x65,
+ 0x72, 0x5b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2b, 0x31, 0x5d,
+ 0x3d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3e, 0x3e, 0x3e, 0x38,
+ 0x26, 0x32, 0x35, 0x35, 0x2c, 0x62, 0x75, 0x66, 0x66, 0x65,
+ 0x72, 0x5b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2b, 0x32, 0x5d,
+ 0x3d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3e, 0x3e, 0x3e, 0x31,
+ 0x36, 0x26, 0x32, 0x35, 0x35, 0x2c, 0x62, 0x75, 0x66, 0x66,
+ 0x65, 0x72, 0x5b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2b, 0x33,
+ 0x5d, 0x3d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3e, 0x3e, 0x3e,
+ 0x32, 0x34, 0x26, 0x32, 0x35, 0x35, 0x7d, 0x23, 0x61, 0x64,
+ 0x64, 0x49, 0x44, 0x28, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72,
+ 0x2c, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2c, 0x69, 0x6e, 0x64,
+ 0x65, 0x78, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x76, 0x61, 0x6c,
+ 0x75, 0x65, 0x3c, 0x30, 0x7c, 0x7c, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x3e, 0x36, 0x35, 0x35, 0x33, 0x35, 0x29, 0x74, 0x68,
+ 0x72, 0x6f, 0x77, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x45, 0x72,
+ 0x72, 0x6f, 0x72, 0x28, 0x22, 0x4e, 0x75, 0x6d, 0x62, 0x65,
+ 0x72, 0x20, 0x69, 0x73, 0x20, 0x6f, 0x75, 0x74, 0x20, 0x6f,
+ 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x72, 0x61, 0x6e, 0x67,
+ 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x32, 0x20, 0x62, 0x79,
+ 0x74, 0x65, 0x73, 0x20, 0x72, 0x65, 0x70, 0x72, 0x65, 0x73,
+ 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x22,
+ 0x29, 0x3b, 0x69, 0x66, 0x28, 0x69, 0x6e, 0x64, 0x65, 0x78,
+ 0x3c, 0x30, 0x7c, 0x7c, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x3e,
+ 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x2e, 0x6c, 0x65, 0x6e,
+ 0x67, 0x74, 0x68, 0x2d, 0x32, 0x29, 0x74, 0x68, 0x72, 0x6f,
+ 0x77, 0x20, 0x6e, 0x65, 0x77, 0x20, 0x45, 0x72, 0x72, 0x6f,
+ 0x72, 0x28, 0x22, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x6f,
+ 0x75, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x62, 0x6f, 0x75, 0x6e,
+ 0x64, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x69, 0x6e, 0x73, 0x75,
+ 0x66, 0x66, 0x69, 0x63, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x73,
+ 0x70, 0x61, 0x63, 0x65, 0x20, 0x69, 0x6e, 0x20, 0x62, 0x75,
+ 0x66, 0x66, 0x65, 0x72, 0x2e, 0x22, 0x29, 0x3b, 0x62, 0x75,
+ 0x66, 0x66, 0x65, 0x72, 0x5b, 0x69, 0x6e, 0x64, 0x65, 0x78,
+ 0x5d, 0x3d, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x26, 0x32, 0x35,
+ 0x35, 0x2c, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5b, 0x69,
+ 0x6e, 0x64, 0x65, 0x78, 0x2b, 0x31, 0x5d, 0x3d, 0x76, 0x61,
+ 0x6c, 0x75, 0x65, 0x3e, 0x3e, 0x3e, 0x38, 0x26, 0x32, 0x35,
+ 0x35, 0x7d, 0x23, 0x73, 0x74, 0x61, 0x72, 0x74, 0x28, 0x29,
+ 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6b, 0x65, 0x65,
+ 0x70, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x28, 0x29, 0x2c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x61, 0x6c, 0x6c, 0x50,
+ 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x49, 0x44, 0x5b, 0x30,
+ 0x5d, 0x3d, 0x30, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x77, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x28,
+ 0x29, 0x7d, 0x23, 0x6b, 0x65, 0x65, 0x70, 0x41, 0x6c, 0x69,
+ 0x76, 0x65, 0x3d, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x28, 0x29,
+ 0x3d, 0x3e, 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x3b, 0x3b, 0x29,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50, 0x69, 0x6e, 0x67,
+ 0x3f, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x73, 0x65, 0x6e,
+ 0x64, 0x44, 0x61, 0x74, 0x61, 0x28, 0x6e, 0x65, 0x77, 0x20,
+ 0x54, 0x65, 0x78, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65,
+ 0x72, 0x28, 0x29, 0x2e, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65,
+ 0x28, 0x22, 0x70, 0x69, 0x6e, 0x67, 0x22, 0x29, 0x29, 0x3a,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50, 0x69, 0x6e, 0x67,
+ 0x3d, 0x21, 0x30, 0x2c, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20,
+ 0x6e, 0x65, 0x77, 0x20, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73,
+ 0x65, 0x28, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x3d,
+ 0x3e, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75,
+ 0x74, 0x28, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x2c,
+ 0x32, 0x65, 0x34, 0x29, 0x29, 0x7d, 0x3b, 0x23, 0x63, 0x6c,
+ 0x69, 0x63, 0x6b, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e,
+ 0x65, 0x72, 0x28, 0x29, 0x7b, 0x64, 0x6f, 0x63, 0x75, 0x6d,
+ 0x65, 0x6e, 0x74, 0x2e, 0x71, 0x75, 0x65, 0x72, 0x79, 0x53,
+ 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x6c, 0x6c,
+ 0x28, 0x22, 0x5b, 0x69, 0x64, 0x5d, 0x22, 0x29, 0x2e, 0x66,
+ 0x6f, 0x72, 0x45, 0x61, 0x63, 0x68, 0x28, 0x65, 0x3d, 0x3e,
+ 0x7b, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x41, 0x6c,
+ 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x7c, 0x7c, 0x65,
+ 0x2e, 0x69, 0x64, 0x21, 0x3d, 0x3d, 0x22, 0x22, 0x26, 0x26,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x62, 0x69, 0x6e, 0x64,
+ 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x69, 0x6e, 0x63, 0x6c,
+ 0x75, 0x64, 0x65, 0x73, 0x28, 0x65, 0x2e, 0x69, 0x64, 0x29,
+ 0x29, 0x26, 0x26, 0x65, 0x2e, 0x69, 0x64, 0x26, 0x26, 0x21,
+ 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x73, 0x65, 0x74, 0x2e,
+ 0x77, 0x65, 0x62, 0x75, 0x69, 0x5f, 0x63, 0x6c, 0x69, 0x63,
+ 0x6b, 0x5f, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x74, 0x26, 0x26,
+ 0x28, 0x65, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x73, 0x65, 0x74,
+ 0x2e, 0x77, 0x65, 0x62, 0x75, 0x69, 0x5f, 0x63, 0x6c, 0x69,
+ 0x63, 0x6b, 0x5f, 0x69, 0x73, 0x5f, 0x73, 0x65, 0x74, 0x3d,
+ 0x22, 0x74, 0x72, 0x75, 0x65, 0x22, 0x2c, 0x65, 0x2e, 0x61,
+ 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73,
+ 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22, 0x63, 0x6c, 0x69,
+ 0x63, 0x6b, 0x22, 0x2c, 0x28, 0x29, 0x3d, 0x3e, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x73, 0x65, 0x6e, 0x64, 0x43, 0x6c,
+ 0x69, 0x63, 0x6b, 0x28, 0x65, 0x2e, 0x69, 0x64, 0x29, 0x29,
+ 0x29, 0x7d, 0x29, 0x7d, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x23,
+ 0x73, 0x65, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61, 0x28, 0x70,
+ 0x61, 0x63, 0x6b, 0x65, 0x74, 0x29, 0x7b, 0x69, 0x66, 0x28,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50, 0x69, 0x6e, 0x67,
+ 0x3d, 0x21, 0x31, 0x2c, 0x21, 0x28, 0x21, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x77, 0x73, 0x49, 0x73, 0x43, 0x6f, 0x6e,
+ 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x28, 0x29, 0x7c, 0x7c,
+ 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x3d, 0x3d, 0x3d, 0x76,
+ 0x6f, 0x69, 0x64, 0x20, 0x30, 0x29, 0x26, 0x26, 0x28, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x73, 0x65, 0x6e, 0x64, 0x51,
+ 0x75, 0x65, 0x75, 0x65, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28,
+ 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x29, 0x2c, 0x21, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x69, 0x73, 0x53, 0x65, 0x6e,
+ 0x64, 0x69, 0x6e, 0x67, 0x29, 0x29, 0x7b, 0x66, 0x6f, 0x72,
+ 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x69, 0x73, 0x53,
+ 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x3d, 0x21, 0x30, 0x3b,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x73, 0x65, 0x6e, 0x64,
+ 0x51, 0x75, 0x65, 0x75, 0x65, 0x2e, 0x6c, 0x65, 0x6e, 0x67,
+ 0x74, 0x68, 0x3e, 0x30, 0x3b, 0x29, 0x7b, 0x6c, 0x65, 0x74,
+ 0x20, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x61,
+ 0x63, 0x6b, 0x65, 0x74, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x73, 0x65, 0x6e, 0x64, 0x51, 0x75, 0x65, 0x75, 0x65,
+ 0x2e, 0x73, 0x68, 0x69, 0x66, 0x74, 0x28, 0x29, 0x3b, 0x69,
+ 0x66, 0x28, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x50,
+ 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6c, 0x65, 0x6e, 0x67,
+ 0x74, 0x68, 0x3c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x4d,
+ 0x55, 0x4c, 0x54, 0x49, 0x5f, 0x43, 0x48, 0x55, 0x4e, 0x4b,
+ 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x29, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x77, 0x73, 0x2e, 0x73, 0x65, 0x6e, 0x64, 0x28,
+ 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x63,
+ 0x6b, 0x65, 0x74, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72,
+ 0x29, 0x3b, 0x65, 0x6c, 0x73, 0x65, 0x7b, 0x6c, 0x65, 0x74,
+ 0x20, 0x70, 0x72, 0x65, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65,
+ 0x74, 0x3d, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72,
+ 0x61, 0x79, 0x2e, 0x6f, 0x66, 0x28, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x57, 0x45, 0x42, 0x55, 0x49, 0x5f, 0x53, 0x49,
+ 0x47, 0x4e, 0x41, 0x54, 0x55, 0x52, 0x45, 0x2c, 0x30, 0x2c,
+ 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x43, 0x4d, 0x44, 0x5f,
+ 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x2c, 0x2e, 0x2e, 0x2e, 0x6e,
+ 0x65, 0x77, 0x20, 0x54, 0x65, 0x78, 0x74, 0x45, 0x6e, 0x63,
+ 0x6f, 0x64, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x65, 0x6e, 0x63,
+ 0x6f, 0x64, 0x65, 0x28, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
+ 0x74, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6c, 0x65,
+ 0x6e, 0x67, 0x74, 0x68, 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72,
+ 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x2c, 0x30, 0x29, 0x3b,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x2e, 0x73,
+ 0x65, 0x6e, 0x64, 0x28, 0x70, 0x72, 0x65, 0x5f, 0x70, 0x61,
+ 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65,
+ 0x72, 0x29, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x66,
+ 0x73, 0x65, 0x74, 0x3d, 0x30, 0x2c, 0x73, 0x65, 0x6e, 0x64,
+ 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x3d, 0x61, 0x73, 0x79, 0x6e,
+ 0x63, 0x28, 0x29, 0x3d, 0x3e, 0x7b, 0x69, 0x66, 0x28, 0x6f,
+ 0x66, 0x66, 0x73, 0x65, 0x74, 0x3c, 0x63, 0x75, 0x72, 0x72,
+ 0x65, 0x6e, 0x74, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2e,
+ 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x7b, 0x6c, 0x65,
+ 0x74, 0x20, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x53, 0x69, 0x7a,
+ 0x65, 0x3d, 0x4d, 0x61, 0x74, 0x68, 0x2e, 0x6d, 0x69, 0x6e,
+ 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x4d, 0x55, 0x4c,
+ 0x54, 0x49, 0x5f, 0x43, 0x48, 0x55, 0x4e, 0x4b, 0x5f, 0x53,
+ 0x49, 0x5a, 0x45, 0x2c, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e,
+ 0x74, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6c, 0x65,
+ 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x6f, 0x66, 0x66, 0x73, 0x65,
+ 0x74, 0x29, 0x2c, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x3d, 0x63,
+ 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x63, 0x6b,
+ 0x65, 0x74, 0x2e, 0x73, 0x75, 0x62, 0x61, 0x72, 0x72, 0x61,
+ 0x79, 0x28, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2c, 0x6f,
+ 0x66, 0x66, 0x73, 0x65, 0x74, 0x2b, 0x63, 0x68, 0x75, 0x6e,
+ 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x29, 0x3b, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x77, 0x73, 0x2e, 0x73, 0x65, 0x6e, 0x64,
+ 0x28, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x29, 0x2c, 0x6f, 0x66,
+ 0x66, 0x73, 0x65, 0x74, 0x2b, 0x3d, 0x63, 0x68, 0x75, 0x6e,
+ 0x6b, 0x53, 0x69, 0x7a, 0x65, 0x2c, 0x61, 0x77, 0x61, 0x69,
+ 0x74, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x75, 0x6e,
+ 0x6b, 0x28, 0x29, 0x7d, 0x7d, 0x3b, 0x61, 0x77, 0x61, 0x69,
+ 0x74, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x43, 0x68, 0x75, 0x6e,
+ 0x6b, 0x28, 0x29, 0x7d, 0x7d, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x69, 0x73, 0x53, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67,
+ 0x3d, 0x21, 0x31, 0x7d, 0x7d, 0x23, 0x73, 0x65, 0x6e, 0x64,
+ 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x28, 0x65, 0x6c, 0x65, 0x6d,
+ 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x77, 0x73, 0x49, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
+ 0x63, 0x74, 0x65, 0x64, 0x28, 0x29, 0x29, 0x7b, 0x6c, 0x65,
+ 0x74, 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x3d, 0x65,
+ 0x6c, 0x65, 0x6d, 0x21, 0x3d, 0x3d, 0x22, 0x22, 0x3f, 0x55,
+ 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61, 0x79, 0x2e,
+ 0x6f, 0x66, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x57,
+ 0x45, 0x42, 0x55, 0x49, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41,
+ 0x54, 0x55, 0x52, 0x45, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30,
+ 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x43, 0x4c, 0x49,
+ 0x43, 0x4b, 0x2c, 0x2e, 0x2e, 0x2e, 0x6e, 0x65, 0x77, 0x20,
+ 0x54, 0x65, 0x78, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65,
+ 0x72, 0x28, 0x29, 0x2e, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65,
+ 0x28, 0x65, 0x6c, 0x65, 0x6d, 0x29, 0x2c, 0x30, 0x29, 0x3a,
+ 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61, 0x79,
+ 0x2e, 0x6f, 0x66, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x57, 0x45, 0x42, 0x55, 0x49, 0x5f, 0x53, 0x49, 0x47, 0x4e,
+ 0x41, 0x54, 0x55, 0x52, 0x45, 0x2c, 0x30, 0x2c, 0x30, 0x2c,
+ 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x43, 0x4c,
+ 0x49, 0x43, 0x4b, 0x2c, 0x30, 0x29, 0x3b, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x61, 0x64, 0x64, 0x54, 0x6f, 0x6b, 0x65,
+ 0x6e, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
+ 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50, 0x52, 0x4f,
+ 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x54, 0x4f, 0x4b, 0x45,
+ 0x4e, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x73,
+ 0x65, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61,
+ 0x63, 0x6b, 0x65, 0x74, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x26, 0x26, 0x63, 0x6f, 0x6e,
+ 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x60,
+ 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x53,
+ 0x65, 0x6e, 0x64, 0x20, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x20,
+ 0x5b, 0x24, 0x7b, 0x65, 0x6c, 0x65, 0x6d, 0x7d, 0x5d, 0x60,
+ 0x29, 0x7d, 0x7d, 0x23, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x54,
+ 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x29, 0x7b, 0x69, 0x66, 0x28,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x49, 0x73,
+ 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x28,
+ 0x29, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x70, 0x61, 0x63,
+ 0x6b, 0x65, 0x74, 0x3d, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41,
+ 0x72, 0x72, 0x61, 0x79, 0x2e, 0x6f, 0x66, 0x28, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x57, 0x45, 0x42, 0x55, 0x49, 0x5f,
+ 0x53, 0x49, 0x47, 0x4e, 0x41, 0x54, 0x55, 0x52, 0x45, 0x2c,
+ 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c,
+ 0x30, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x43, 0x4d,
+ 0x44, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b, 0x5f, 0x54, 0x4b,
+ 0x2c, 0x30, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x61, 0x64, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x70,
+ 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2c, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x2c, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43,
+ 0x4f, 0x4c, 0x5f, 0x54, 0x4f, 0x4b, 0x45, 0x4e, 0x29, 0x2c,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x73, 0x65, 0x6e, 0x64,
+ 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x65,
+ 0x74, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c,
+ 0x6f, 0x67, 0x26, 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c,
+ 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x60, 0x57, 0x65, 0x62,
+ 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x53, 0x65, 0x6e, 0x64,
+ 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x5b, 0x30, 0x78,
+ 0x24, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x74, 0x6f,
+ 0x6b, 0x65, 0x6e, 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69,
+ 0x6e, 0x67, 0x28, 0x31, 0x36, 0x29, 0x2e, 0x70, 0x61, 0x64,
+ 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x38, 0x2c, 0x22, 0x30,
+ 0x22, 0x29, 0x7d, 0x5d, 0x60, 0x29, 0x7d, 0x7d, 0x23, 0x73,
+ 0x65, 0x6e, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4e, 0x61,
+ 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x75,
+ 0x72, 0x6c, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x75, 0x72, 0x6c,
+ 0x21, 0x3d, 0x3d, 0x22, 0x22, 0x26, 0x26, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x77, 0x73, 0x49, 0x73, 0x43, 0x6f, 0x6e,
+ 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x28, 0x29, 0x29, 0x7b,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x26,
+ 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c,
+ 0x6f, 0x67, 0x28, 0x60, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20,
+ 0x2d, 0x3e, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x20, 0x4e, 0x61,
+ 0x76, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x45,
+ 0x76, 0x65, 0x6e, 0x74, 0x20, 0x5b, 0x24, 0x7b, 0x75, 0x72,
+ 0x6c, 0x7d, 0x5d, 0x60, 0x29, 0x3b, 0x6c, 0x65, 0x74, 0x20,
+ 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x3d, 0x55, 0x69, 0x6e,
+ 0x74, 0x38, 0x41, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x6f, 0x66,
+ 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x57, 0x45, 0x42,
+ 0x55, 0x49, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41, 0x54, 0x55,
+ 0x52, 0x45, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30,
+ 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x4e, 0x41, 0x56, 0x49, 0x47,
+ 0x41, 0x54, 0x49, 0x4f, 0x4e, 0x2c, 0x2e, 0x2e, 0x2e, 0x6e,
+ 0x65, 0x77, 0x20, 0x54, 0x65, 0x78, 0x74, 0x45, 0x6e, 0x63,
+ 0x6f, 0x64, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x65, 0x6e, 0x63,
+ 0x6f, 0x64, 0x65, 0x28, 0x75, 0x72, 0x6c, 0x29, 0x29, 0x3b,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x61, 0x64, 0x64, 0x54,
+ 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x65,
+ 0x74, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x74, 0x6f,
+ 0x6b, 0x65, 0x6e, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x54,
+ 0x4f, 0x4b, 0x45, 0x4e, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x73, 0x65, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61,
+ 0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x29, 0x7d, 0x7d,
+ 0x23, 0x73, 0x65, 0x6e, 0x64, 0x44, 0x72, 0x61, 0x67, 0x28,
+ 0x78, 0x2c, 0x79, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x49, 0x73, 0x43, 0x6f,
+ 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x28, 0x29, 0x29,
+ 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67,
+ 0x26, 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e,
+ 0x6c, 0x6f, 0x67, 0x28, 0x60, 0x57, 0x65, 0x62, 0x55, 0x49,
+ 0x20, 0x2d, 0x3e, 0x20, 0x53, 0x65, 0x6e, 0x64, 0x20, 0x44,
+ 0x72, 0x61, 0x67, 0x20, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x20,
+ 0x5b, 0x24, 0x7b, 0x78, 0x7d, 0x2c, 0x20, 0x24, 0x7b, 0x79,
+ 0x7d, 0x5d, 0x60, 0x29, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x70,
+ 0x61, 0x63, 0x6b, 0x65, 0x74, 0x3d, 0x55, 0x69, 0x6e, 0x74,
+ 0x38, 0x41, 0x72, 0x72, 0x61, 0x79, 0x2e, 0x6f, 0x66, 0x28,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x57, 0x45, 0x42, 0x55,
+ 0x49, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41, 0x54, 0x55, 0x52,
+ 0x45, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c,
+ 0x30, 0x2c, 0x30, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x43, 0x4d, 0x44, 0x5f, 0x57, 0x49, 0x4e, 0x44, 0x4f, 0x57,
+ 0x5f, 0x44, 0x52, 0x41, 0x47, 0x2c, 0x2e, 0x2e, 0x2e, 0x6e,
+ 0x65, 0x77, 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72,
+ 0x72, 0x61, 0x79, 0x28, 0x6e, 0x65, 0x77, 0x20, 0x49, 0x6e,
+ 0x74, 0x33, 0x32, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x5b,
+ 0x78, 0x5d, 0x29, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72,
+ 0x29, 0x2c, 0x2e, 0x2e, 0x2e, 0x6e, 0x65, 0x77, 0x20, 0x55,
+ 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28,
+ 0x6e, 0x65, 0x77, 0x20, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x41,
+ 0x72, 0x72, 0x61, 0x79, 0x28, 0x5b, 0x79, 0x5d, 0x29, 0x2e,
+ 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x29, 0x29, 0x3b, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x61, 0x64, 0x64, 0x54, 0x6f,
+ 0x6b, 0x65, 0x6e, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74,
+ 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x74, 0x6f, 0x6b,
+ 0x65, 0x6e, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50,
+ 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x54, 0x4f,
+ 0x4b, 0x45, 0x4e, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x73, 0x65, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61, 0x28,
+ 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x29, 0x7d, 0x7d, 0x23,
+ 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x57, 0x69, 0x6e, 0x64, 0x6f,
+ 0x77, 0x54, 0x69, 0x6d, 0x65, 0x72, 0x28, 0x29, 0x7b, 0x73,
+ 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28,
+ 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x29,
+ 0x7b, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x54, 0x68, 0x69,
+ 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x28, 0x29, 0x7d,
+ 0x2c, 0x31, 0x65, 0x33, 0x29, 0x7d, 0x23, 0x75, 0x70, 0x64,
+ 0x61, 0x74, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x73, 0x4c, 0x69,
+ 0x73, 0x74, 0x28, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x62, 0x69, 0x6e, 0x64, 0x73, 0x4c, 0x69, 0x73, 0x74,
+ 0x2e, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x73, 0x28,
+ 0x22, 0x22, 0x29, 0x26, 0x26, 0x28, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x41, 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74,
+ 0x73, 0x3d, 0x21, 0x30, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x4e, 0x61, 0x76, 0x69,
+ 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x21, 0x31, 0x29,
+ 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x67, 0x65, 0x6e,
+ 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c, 0x6c, 0x4f,
+ 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x28, 0x29, 0x2c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x6c, 0x69, 0x63, 0x6b,
+ 0x73, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28,
+ 0x29, 0x7d, 0x23, 0x74, 0x6f, 0x55, 0x69, 0x6e, 0x74, 0x31,
+ 0x36, 0x28, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x29, 0x7b, 0x72,
+ 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x26, 0x36, 0x35, 0x35, 0x33, 0x35, 0x7d, 0x23, 0x67,
+ 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6c,
+ 0x6c, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x28, 0x29,
+ 0x7b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20, 0x62,
+ 0x69, 0x6e, 0x64, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x62, 0x69, 0x6e, 0x64, 0x73, 0x4c, 0x69,
+ 0x73, 0x74, 0x29, 0x69, 0x66, 0x28, 0x62, 0x69, 0x6e, 0x64,
+ 0x2e, 0x74, 0x72, 0x69, 0x6d, 0x28, 0x29, 0x29, 0x7b, 0x6c,
+ 0x65, 0x74, 0x20, 0x66, 0x6e, 0x3d, 0x62, 0x69, 0x6e, 0x64,
+ 0x3b, 0x66, 0x6e, 0x2e, 0x74, 0x72, 0x69, 0x6d, 0x28, 0x29,
+ 0x26, 0x26, 0x66, 0x6e, 0x21, 0x3d, 0x3d, 0x22, 0x5f, 0x5f,
+ 0x77, 0x65, 0x62, 0x75, 0x69, 0x5f, 0x63, 0x6f, 0x72, 0x65,
+ 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x5f, 0x22, 0x26, 0x26, 0x74,
+ 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x77, 0x69, 0x6e, 0x64,
+ 0x6f, 0x77, 0x5b, 0x66, 0x6e, 0x5d, 0x3e, 0x22, 0x75, 0x22,
+ 0x26, 0x26, 0x28, 0x74, 0x68, 0x69, 0x73, 0x5b, 0x66, 0x6e,
+ 0x5d, 0x3d, 0x28, 0x2e, 0x2e, 0x2e, 0x61, 0x72, 0x67, 0x73,
+ 0x29, 0x3d, 0x3e, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x61,
+ 0x6c, 0x6c, 0x28, 0x66, 0x6e, 0x2c, 0x2e, 0x2e, 0x2e, 0x61,
+ 0x72, 0x67, 0x73, 0x29, 0x2c, 0x77, 0x69, 0x6e, 0x64, 0x6f,
+ 0x77, 0x5b, 0x66, 0x6e, 0x5d, 0x3d, 0x28, 0x2e, 0x2e, 0x2e,
+ 0x61, 0x72, 0x67, 0x73, 0x29, 0x3d, 0x3e, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x28, 0x66, 0x6e, 0x2c,
+ 0x2e, 0x2e, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x29, 0x2c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x26, 0x26,
+ 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f,
+ 0x67, 0x28, 0x60, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d,
+ 0x3e, 0x20, 0x42, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20,
+ 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x20, 0x66, 0x75,
+ 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x24, 0x7b,
+ 0x66, 0x6e, 0x7d, 0x5d, 0x60, 0x29, 0x29, 0x7d, 0x7d, 0x23,
+ 0x67, 0x65, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74, 0x55,
+ 0x72, 0x6c, 0x28, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x73,
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x73, 0x3d, 0x41, 0x72, 0x72,
+ 0x61, 0x79, 0x2e, 0x66, 0x72, 0x6f, 0x6d, 0x28, 0x64, 0x6f,
+ 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x63, 0x72,
+ 0x69, 0x70, 0x74, 0x73, 0x29, 0x2e, 0x66, 0x69, 0x6c, 0x74,
+ 0x65, 0x72, 0x28, 0x73, 0x3d, 0x3e, 0x73, 0x2e, 0x73, 0x72,
+ 0x63, 0x21, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x26, 0x26,
+ 0x73, 0x2e, 0x73, 0x72, 0x63, 0x2e, 0x73, 0x74, 0x61, 0x72,
+ 0x74, 0x73, 0x57, 0x69, 0x74, 0x68, 0x28, 0x22, 0x68, 0x74,
+ 0x74, 0x70, 0x22, 0x29, 0x26, 0x26, 0x73, 0x2e, 0x73, 0x72,
+ 0x63, 0x2e, 0x65, 0x6e, 0x64, 0x73, 0x57, 0x69, 0x74, 0x68,
+ 0x28, 0x22, 0x77, 0x65, 0x62, 0x75, 0x69, 0x2e, 0x6a, 0x73,
+ 0x22, 0x29, 0x29, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x73, 0x3d,
+ 0x3e, 0x73, 0x2e, 0x73, 0x72, 0x63, 0x29, 0x3b, 0x72, 0x65,
+ 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73, 0x63, 0x72, 0x69, 0x70,
+ 0x74, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3d,
+ 0x3d, 0x3d, 0x30, 0x3f, 0x6e, 0x75, 0x6c, 0x6c, 0x3a, 0x6e,
+ 0x65, 0x77, 0x20, 0x55, 0x52, 0x4c, 0x28, 0x73, 0x63, 0x72,
+ 0x69, 0x70, 0x74, 0x73, 0x5b, 0x30, 0x5d, 0x29, 0x7d, 0x23,
+ 0x63, 0x61, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73,
+ 0x65, 0x28, 0x66, 0x6e, 0x2c, 0x2e, 0x2e, 0x2e, 0x61, 0x72,
+ 0x67, 0x73, 0x29, 0x7b, 0x2d, 0x2d, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x63, 0x61, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d,
+ 0x69, 0x73, 0x65, 0x49, 0x44, 0x5b, 0x30, 0x5d, 0x3b, 0x6c,
+ 0x65, 0x74, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x3d,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x74, 0x6f, 0x55, 0x69,
+ 0x6e, 0x74, 0x31, 0x36, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x63, 0x61, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x69,
+ 0x73, 0x65, 0x49, 0x44, 0x5b, 0x30, 0x5d, 0x29, 0x2c, 0x61,
+ 0x72, 0x67, 0x73, 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x73,
+ 0x3d, 0x61, 0x72, 0x67, 0x73, 0x2e, 0x6d, 0x61, 0x70, 0x28,
+ 0x61, 0x72, 0x67, 0x3d, 0x3e, 0x74, 0x79, 0x70, 0x65, 0x6f,
+ 0x66, 0x20, 0x61, 0x72, 0x67, 0x3d, 0x3d, 0x22, 0x6f, 0x62,
+ 0x6a, 0x65, 0x63, 0x74, 0x22, 0x3f, 0x61, 0x72, 0x67, 0x2e,
+ 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x6e, 0x65, 0x77,
+ 0x20, 0x54, 0x65, 0x78, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64,
+ 0x65, 0x72, 0x28, 0x29, 0x2e, 0x65, 0x6e, 0x63, 0x6f, 0x64,
+ 0x65, 0x28, 0x61, 0x72, 0x67, 0x2e, 0x74, 0x6f, 0x53, 0x74,
+ 0x72, 0x69, 0x6e, 0x67, 0x28, 0x29, 0x29, 0x2e, 0x6c, 0x65,
+ 0x6e, 0x67, 0x74, 0x68, 0x29, 0x2e, 0x6a, 0x6f, 0x69, 0x6e,
+ 0x28, 0x22, 0x3b, 0x22, 0x29, 0x2c, 0x61, 0x72, 0x67, 0x73,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x3d, 0x6e, 0x65, 0x77,
+ 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61,
+ 0x79, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74, 0x20,
+ 0x61, 0x72, 0x67, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x72, 0x67,
+ 0x73, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x62, 0x75, 0x66,
+ 0x66, 0x65, 0x72, 0x3b, 0x74, 0x79, 0x70, 0x65, 0x6f, 0x66,
+ 0x20, 0x61, 0x72, 0x67, 0x3d, 0x3d, 0x22, 0x6f, 0x62, 0x6a,
+ 0x65, 0x63, 0x74, 0x22, 0x3f, 0x62, 0x75, 0x66, 0x66, 0x65,
+ 0x72, 0x3d, 0x61, 0x72, 0x67, 0x3a, 0x62, 0x75, 0x66, 0x66,
+ 0x65, 0x72, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x54, 0x65, 0x78,
+ 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x28, 0x29,
+ 0x2e, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x28, 0x61, 0x72,
+ 0x67, 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
+ 0x28, 0x29, 0x29, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x74, 0x65,
+ 0x6d, 0x70, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x55, 0x69, 0x6e,
+ 0x74, 0x38, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x61, 0x72,
+ 0x67, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x6c,
+ 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2b, 0x62, 0x75, 0x66, 0x66,
+ 0x65, 0x72, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2b,
+ 0x31, 0x29, 0x3b, 0x74, 0x65, 0x6d, 0x70, 0x2e, 0x73, 0x65,
+ 0x74, 0x28, 0x61, 0x72, 0x67, 0x73, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x73, 0x2c, 0x30, 0x29, 0x2c, 0x74, 0x65, 0x6d, 0x70,
+ 0x2e, 0x73, 0x65, 0x74, 0x28, 0x62, 0x75, 0x66, 0x66, 0x65,
+ 0x72, 0x2c, 0x61, 0x72, 0x67, 0x73, 0x56, 0x61, 0x6c, 0x75,
+ 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29,
+ 0x2c, 0x74, 0x65, 0x6d, 0x70, 0x5b, 0x61, 0x72, 0x67, 0x73,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2e, 0x6c, 0x65, 0x6e,
+ 0x67, 0x74, 0x68, 0x2b, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72,
+ 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x5d, 0x3d, 0x30,
+ 0x2c, 0x61, 0x72, 0x67, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65,
+ 0x73, 0x3d, 0x74, 0x65, 0x6d, 0x70, 0x7d, 0x6c, 0x65, 0x74,
+ 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x3d, 0x6e, 0x65,
+ 0x77, 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72,
+ 0x61, 0x79, 0x28, 0x30, 0x29, 0x2c, 0x70, 0x61, 0x63, 0x6b,
+ 0x65, 0x74, 0x50, 0x75, 0x73, 0x68, 0x3d, 0x64, 0x61, 0x74,
+ 0x61, 0x3d, 0x3e, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x65,
+ 0x77, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x3d, 0x6e, 0x65,
+ 0x77, 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72,
+ 0x61, 0x79, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2e,
+ 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2b, 0x64, 0x61, 0x74,
+ 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3b,
+ 0x6e, 0x65, 0x77, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2e,
+ 0x73, 0x65, 0x74, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74,
+ 0x29, 0x2c, 0x6e, 0x65, 0x77, 0x50, 0x61, 0x63, 0x6b, 0x65,
+ 0x74, 0x2e, 0x73, 0x65, 0x74, 0x28, 0x64, 0x61, 0x74, 0x61,
+ 0x2c, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6c, 0x65,
+ 0x6e, 0x67, 0x74, 0x68, 0x29, 0x2c, 0x70, 0x61, 0x63, 0x6b,
+ 0x65, 0x74, 0x3d, 0x6e, 0x65, 0x77, 0x50, 0x61, 0x63, 0x6b,
+ 0x65, 0x74, 0x7d, 0x3b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
+ 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x75, 0x73,
+ 0x68, 0x28, 0x6e, 0x65, 0x77, 0x20, 0x55, 0x69, 0x6e, 0x74,
+ 0x38, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x5b, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x57, 0x45, 0x42, 0x55, 0x49, 0x5f,
+ 0x53, 0x49, 0x47, 0x4e, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5d,
+ 0x29, 0x29, 0x2c, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x50,
+ 0x75, 0x73, 0x68, 0x28, 0x6e, 0x65, 0x77, 0x20, 0x55, 0x69,
+ 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x5b,
+ 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x5d, 0x29, 0x29,
+ 0x2c, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x75, 0x73,
+ 0x68, 0x28, 0x6e, 0x65, 0x77, 0x20, 0x55, 0x69, 0x6e, 0x74,
+ 0x38, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x5b, 0x30, 0x2c,
+ 0x30, 0x5d, 0x29, 0x29, 0x2c, 0x70, 0x61, 0x63, 0x6b, 0x65,
+ 0x74, 0x50, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x65, 0x77, 0x20,
+ 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61, 0x79,
+ 0x28, 0x5b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x43, 0x4d,
+ 0x44, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x5f, 0x46, 0x55, 0x4e,
+ 0x43, 0x5d, 0x29, 0x29, 0x2c, 0x70, 0x61, 0x63, 0x6b, 0x65,
+ 0x74, 0x50, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x65, 0x77, 0x20,
+ 0x54, 0x65, 0x78, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65,
+ 0x72, 0x28, 0x29, 0x2e, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65,
+ 0x28, 0x66, 0x6e, 0x29, 0x29, 0x2c, 0x70, 0x61, 0x63, 0x6b,
+ 0x65, 0x74, 0x50, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x65, 0x77,
+ 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61,
+ 0x79, 0x28, 0x5b, 0x30, 0x5d, 0x29, 0x29, 0x2c, 0x70, 0x61,
+ 0x63, 0x6b, 0x65, 0x74, 0x50, 0x75, 0x73, 0x68, 0x28, 0x6e,
+ 0x65, 0x77, 0x20, 0x54, 0x65, 0x78, 0x74, 0x45, 0x6e, 0x63,
+ 0x6f, 0x64, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x65, 0x6e, 0x63,
+ 0x6f, 0x64, 0x65, 0x28, 0x61, 0x72, 0x67, 0x73, 0x4c, 0x65,
+ 0x6e, 0x67, 0x74, 0x68, 0x73, 0x29, 0x29, 0x2c, 0x70, 0x61,
+ 0x63, 0x6b, 0x65, 0x74, 0x50, 0x75, 0x73, 0x68, 0x28, 0x6e,
+ 0x65, 0x77, 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72,
+ 0x72, 0x61, 0x79, 0x28, 0x5b, 0x30, 0x5d, 0x29, 0x29, 0x2c,
+ 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x75, 0x73, 0x68,
+ 0x28, 0x6e, 0x65, 0x77, 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38,
+ 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x61, 0x72, 0x67, 0x73,
+ 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x29, 0x29, 0x2c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x61, 0x64, 0x64, 0x54, 0x6f,
+ 0x6b, 0x65, 0x6e, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74,
+ 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x74, 0x6f, 0x6b,
+ 0x65, 0x6e, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50,
+ 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x54, 0x4f,
+ 0x4b, 0x45, 0x4e, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x61, 0x64, 0x64, 0x49, 0x44, 0x28, 0x70, 0x61, 0x63,
+ 0x6b, 0x65, 0x74, 0x2c, 0x63, 0x61, 0x6c, 0x6c, 0x49, 0x64,
+ 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50, 0x52, 0x4f,
+ 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x49, 0x44, 0x29, 0x2c,
+ 0x6e, 0x65, 0x77, 0x20, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73,
+ 0x65, 0x28, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x3d,
+ 0x3e, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x61,
+ 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x52,
+ 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x5b, 0x63, 0x61, 0x6c,
+ 0x6c, 0x49, 0x64, 0x5d, 0x3d, 0x72, 0x65, 0x73, 0x6f, 0x6c,
+ 0x76, 0x65, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x73,
+ 0x65, 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61,
+ 0x63, 0x6b, 0x65, 0x74, 0x29, 0x7d, 0x29, 0x7d, 0x61, 0x73,
+ 0x79, 0x6e, 0x63, 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x43, 0x6f,
+ 0x72, 0x65, 0x28, 0x66, 0x6e, 0x2c, 0x2e, 0x2e, 0x2e, 0x61,
+ 0x72, 0x67, 0x73, 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72,
+ 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x61, 0x6c,
+ 0x6c, 0x28, 0x22, 0x5f, 0x5f, 0x77, 0x65, 0x62, 0x75, 0x69,
+ 0x5f, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x5f,
+ 0x5f, 0x22, 0x2c, 0x66, 0x6e, 0x2c, 0x2e, 0x2e, 0x2e, 0x61,
+ 0x72, 0x67, 0x73, 0x29, 0x7d, 0x23, 0x77, 0x73, 0x49, 0x73,
+ 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x28,
+ 0x29, 0x7b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x26, 0x26, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x2e, 0x72, 0x65,
+ 0x61, 0x64, 0x79, 0x53, 0x74, 0x61, 0x74, 0x65, 0x3d, 0x3d,
+ 0x3d, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74,
+ 0x2e, 0x4f, 0x50, 0x45, 0x4e, 0x7d, 0x23, 0x77, 0x73, 0x43,
+ 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x28, 0x29, 0x7b, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x49, 0x73, 0x43,
+ 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x28, 0x29,
+ 0x26, 0x26, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73,
+ 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x28, 0x29, 0x2c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
+ 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x3d, 0x21,
+ 0x31, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x63, 0x72, 0x69,
+ 0x70, 0x74, 0x55, 0x72, 0x6c, 0x3d, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x67, 0x65, 0x74, 0x53, 0x63, 0x72, 0x69, 0x70,
+ 0x74, 0x55, 0x72, 0x6c, 0x28, 0x29, 0x2c, 0x68, 0x6f, 0x73,
+ 0x74, 0x3d, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x55, 0x72,
+ 0x6c, 0x21, 0x3d, 0x3d, 0x6e, 0x75, 0x6c, 0x6c, 0x3f, 0x73,
+ 0x63, 0x72, 0x69, 0x70, 0x74, 0x55, 0x72, 0x6c, 0x2e, 0x68,
+ 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x3a, 0x77, 0x69,
+ 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x2e, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61,
+ 0x6d, 0x65, 0x2c, 0x75, 0x72, 0x6c, 0x3d, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x3f,
+ 0x22, 0x77, 0x73, 0x73, 0x3a, 0x2f, 0x2f, 0x22, 0x2b, 0x68,
+ 0x6f, 0x73, 0x74, 0x3a, 0x22, 0x77, 0x73, 0x3a, 0x2f, 0x2f,
+ 0x22, 0x2b, 0x68, 0x6f, 0x73, 0x74, 0x3b, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x77, 0x73, 0x3d, 0x6e, 0x65, 0x77, 0x20,
+ 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x28,
+ 0x60, 0x24, 0x7b, 0x75, 0x72, 0x6c, 0x7d, 0x3a, 0x24, 0x7b,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x70, 0x6f, 0x72, 0x74,
+ 0x7d, 0x2f, 0x5f, 0x77, 0x65, 0x62, 0x75, 0x69, 0x5f, 0x77,
+ 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x60,
+ 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73,
+ 0x2e, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x54, 0x79, 0x70,
+ 0x65, 0x3d, 0x22, 0x61, 0x72, 0x72, 0x61, 0x79, 0x62, 0x75,
+ 0x66, 0x66, 0x65, 0x72, 0x22, 0x2c, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x77, 0x73, 0x2e, 0x6f, 0x6e, 0x6f, 0x70, 0x65,
+ 0x6e, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73,
+ 0x4f, 0x6e, 0x4f, 0x70, 0x65, 0x6e, 0x2e, 0x62, 0x69, 0x6e,
+ 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x2c, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x2e, 0x6f, 0x6e, 0x6d,
+ 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x3d, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x77, 0x73, 0x4f, 0x6e, 0x4d, 0x65, 0x73,
+ 0x73, 0x61, 0x67, 0x65, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28,
+ 0x74, 0x68, 0x69, 0x73, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x77, 0x73, 0x2e, 0x6f, 0x6e, 0x63, 0x6c, 0x6f,
+ 0x73, 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77,
+ 0x73, 0x4f, 0x6e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x2e, 0x62,
+ 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68, 0x69, 0x73, 0x29, 0x2c,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x2e, 0x6f,
+ 0x6e, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3d, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x77, 0x73, 0x4f, 0x6e, 0x45, 0x72, 0x72,
+ 0x6f, 0x72, 0x2e, 0x62, 0x69, 0x6e, 0x64, 0x28, 0x74, 0x68,
+ 0x69, 0x73, 0x29, 0x7d, 0x23, 0x77, 0x73, 0x4f, 0x6e, 0x4f,
+ 0x70, 0x65, 0x6e, 0x3d, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3d,
+ 0x3e, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73,
+ 0x57, 0x61, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
+ 0x65, 0x64, 0x3d, 0x21, 0x30, 0x2c, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x75, 0x6e, 0x66, 0x72, 0x65, 0x65, 0x7a, 0x65,
+ 0x55, 0x49, 0x28, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x6c, 0x6f, 0x67, 0x26, 0x26, 0x63, 0x6f, 0x6e, 0x73,
+ 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x22, 0x57,
+ 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x43, 0x6f,
+ 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x22, 0x29, 0x2c,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x68, 0x65, 0x63,
+ 0x6b, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x29, 0x7d, 0x3b,
+ 0x23, 0x77, 0x73, 0x4f, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72,
+ 0x3d, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3d, 0x3e, 0x7b, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x26, 0x26,
+ 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f,
+ 0x67, 0x28, 0x22, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d,
+ 0x3e, 0x20, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x20, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x2e,
+ 0x22, 0x29, 0x7d, 0x3b, 0x23, 0x77, 0x73, 0x4f, 0x6e, 0x43,
+ 0x6c, 0x6f, 0x73, 0x65, 0x3d, 0x65, 0x76, 0x65, 0x6e, 0x74,
+ 0x3d, 0x3e, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63,
+ 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e,
+ 0x3d, 0x3d, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x43,
+ 0x4d, 0x44, 0x5f, 0x4e, 0x41, 0x56, 0x49, 0x47, 0x41, 0x54,
+ 0x49, 0x4f, 0x4e, 0x3f, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x61, 0x73,
+ 0x6f, 0x6e, 0x3d, 0x30, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x6c, 0x6f, 0x67, 0x26, 0x26, 0x63, 0x6f, 0x6e, 0x73,
+ 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x60, 0x57,
+ 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x43, 0x6f,
+ 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c,
+ 0x6f, 0x73, 0x74, 0x2e, 0x20, 0x4e, 0x61, 0x76, 0x69, 0x67,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x6f, 0x20, 0x5b,
+ 0x24, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x6c,
+ 0x6f, 0x73, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x7d, 0x5d,
+ 0x60, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x61,
+ 0x6c, 0x6c, 0x6f, 0x77, 0x4e, 0x61, 0x76, 0x69, 0x67, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x21, 0x30, 0x2c, 0x67, 0x6c,
+ 0x6f, 0x62, 0x61, 0x6c, 0x54, 0x68, 0x69, 0x73, 0x2e, 0x6c,
+ 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x72, 0x65,
+ 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x56, 0x61, 0x6c,
+ 0x75, 0x65, 0x29, 0x29, 0x3a, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x77, 0x73, 0x53, 0x74, 0x61, 0x79, 0x41, 0x6c, 0x69,
+ 0x76, 0x65, 0x3f, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x6c, 0x6f, 0x67, 0x26, 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x6f,
+ 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x60, 0x57, 0x65,
+ 0x62, 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x43, 0x6f, 0x6e,
+ 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c, 0x6f,
+ 0x73, 0x74, 0x20, 0x28, 0x24, 0x7b, 0x65, 0x76, 0x65, 0x6e,
+ 0x74, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x7d, 0x29, 0x2e, 0x20,
+ 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69,
+ 0x6e, 0x67, 0x2e, 0x2e, 0x2e, 0x60, 0x29, 0x2c, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x66, 0x72, 0x65, 0x65, 0x7a, 0x65,
+ 0x55, 0x69, 0x28, 0x29, 0x2c, 0x73, 0x65, 0x74, 0x54, 0x69,
+ 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x28, 0x29, 0x3d, 0x3e,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x43, 0x6f,
+ 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x28, 0x29, 0x2c, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x53, 0x74, 0x61, 0x79,
+ 0x41, 0x6c, 0x69, 0x76, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x6f,
+ 0x75, 0x74, 0x29, 0x29, 0x3a, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x6c, 0x6f, 0x67, 0x3f, 0x28, 0x63, 0x6f, 0x6e, 0x73,
+ 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x60, 0x57,
+ 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x43, 0x6f,
+ 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6c,
+ 0x6f, 0x73, 0x74, 0x20, 0x28, 0x24, 0x7b, 0x65, 0x76, 0x65,
+ 0x6e, 0x74, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x7d, 0x29, 0x60,
+ 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x66, 0x72,
+ 0x65, 0x65, 0x7a, 0x65, 0x55, 0x69, 0x28, 0x29, 0x29, 0x3a,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x6c, 0x6f, 0x73,
+ 0x65, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x54, 0x69, 0x6d,
+ 0x65, 0x72, 0x28, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x75, 0x73, 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74,
+ 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e,
+ 0x44, 0x49, 0x53, 0x43, 0x4f, 0x4e, 0x4e, 0x45, 0x43, 0x54,
+ 0x45, 0x44, 0x29, 0x7d, 0x3b, 0x23, 0x75, 0x73, 0x65, 0x72,
+ 0x45, 0x76, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x6c, 0x62,
+ 0x61, 0x63, 0x6b, 0x3d, 0x65, 0x3d, 0x3e, 0x7b, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73,
+ 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x26, 0x26,
+ 0x65, 0x21, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c,
+ 0x61, 0x73, 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x26, 0x26,
+ 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x61, 0x73,
+ 0x74, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x3d, 0x65, 0x2c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x65, 0x76, 0x65, 0x6e, 0x74,
+ 0x73, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x28,
+ 0x65, 0x29, 0x29, 0x7d, 0x3b, 0x23, 0x77, 0x73, 0x4f, 0x6e,
+ 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x3d, 0x61, 0x73,
+ 0x79, 0x6e, 0x63, 0x20, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3d,
+ 0x3e, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x5f, 0x61, 0x2c, 0x5f,
+ 0x62, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x62, 0x75, 0x66, 0x66,
+ 0x65, 0x72, 0x38, 0x3d, 0x6e, 0x65, 0x77, 0x20, 0x55, 0x69,
+ 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x65,
+ 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x64, 0x61, 0x74, 0x61, 0x29,
+ 0x3b, 0x69, 0x66, 0x28, 0x21, 0x28, 0x62, 0x75, 0x66, 0x66,
+ 0x65, 0x72, 0x38, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,
+ 0x3c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50, 0x52, 0x4f,
+ 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x53, 0x49, 0x5a, 0x45,
+ 0x29, 0x26, 0x26, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x38,
+ 0x5b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50, 0x52, 0x4f,
+ 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x53, 0x49, 0x47, 0x4e,
+ 0x5d, 0x3d, 0x3d, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x57, 0x45, 0x42, 0x55, 0x49, 0x5f, 0x53, 0x49, 0x47, 0x4e,
+ 0x41, 0x54, 0x55, 0x52, 0x45, 0x29, 0x69, 0x66, 0x28, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x69, 0x73, 0x54, 0x65, 0x78,
+ 0x74, 0x42, 0x61, 0x73, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d,
+ 0x61, 0x6e, 0x64, 0x28, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72,
+ 0x38, 0x5b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50, 0x52,
+ 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x43, 0x4d, 0x44,
+ 0x5d, 0x29, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x63, 0x61,
+ 0x6c, 0x6c, 0x49, 0x64, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x67, 0x65, 0x74, 0x49, 0x44, 0x28, 0x62, 0x75, 0x66,
+ 0x66, 0x65, 0x72, 0x38, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f,
+ 0x49, 0x44, 0x29, 0x3b, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68,
+ 0x28, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x38, 0x5b, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f,
+ 0x43, 0x4f, 0x4c, 0x5f, 0x43, 0x4d, 0x44, 0x5d, 0x29, 0x7b,
+ 0x63, 0x61, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x4a, 0x53, 0x5f, 0x51, 0x55,
+ 0x49, 0x43, 0x4b, 0x3a, 0x63, 0x61, 0x73, 0x65, 0x20, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x4a,
+ 0x53, 0x3a, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x63, 0x72,
+ 0x69, 0x70, 0x74, 0x53, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a,
+ 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x67, 0x65,
+ 0x74, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x72, 0x46, 0x72,
+ 0x6f, 0x6d, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x28, 0x62,
+ 0x75, 0x66, 0x66, 0x65, 0x72, 0x38, 0x2c, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f,
+ 0x4c, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x29, 0x2e, 0x72, 0x65,
+ 0x70, 0x6c, 0x61, 0x63, 0x65, 0x28, 0x2f, 0x28, 0x3f, 0x3a,
+ 0x5c, 0x72, 0x5c, 0x6e, 0x7c, 0x5c, 0x72, 0x7c, 0x5c, 0x6e,
+ 0x29, 0x2f, 0x67, 0x2c, 0x60, 0x0a, 0x60, 0x29, 0x3b, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x26, 0x26,
+ 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f,
+ 0x67, 0x28, 0x60, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d,
+ 0x3e, 0x20, 0x43, 0x4d, 0x44, 0x20, 0x2d, 0x3e, 0x20, 0x4a,
+ 0x53, 0x20, 0x5b, 0x24, 0x7b, 0x73, 0x63, 0x72, 0x69, 0x70,
+ 0x74, 0x53, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x7d,
+ 0x5d, 0x60, 0x29, 0x3b, 0x6c, 0x65, 0x74, 0x20, 0x46, 0x75,
+ 0x6e, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3d, 0x22, 0x75,
+ 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x22, 0x2c,
+ 0x46, 0x75, 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3d, 0x21,
+ 0x31, 0x2c, 0x69, 0x73, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79,
+ 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3d, 0x21, 0x31, 0x3b,
+ 0x74, 0x72, 0x79, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x72, 0x65,
+ 0x73, 0x75, 0x6c, 0x74, 0x3d, 0x61, 0x77, 0x61, 0x69, 0x74,
+ 0x20, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x46, 0x75, 0x6e, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x63, 0x72, 0x69, 0x70,
+ 0x74, 0x53, 0x61, 0x6e, 0x69, 0x74, 0x69, 0x7a, 0x65, 0x29,
+ 0x28, 0x29, 0x3b, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x20,
+ 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x6f, 0x66,
+ 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61,
+ 0x79, 0x3f, 0x28, 0x46, 0x75, 0x6e, 0x52, 0x65, 0x74, 0x75,
+ 0x72, 0x6e, 0x3d, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2c,
+ 0x69, 0x73, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65,
+ 0x74, 0x75, 0x72, 0x6e, 0x3d, 0x21, 0x30, 0x29, 0x3a, 0x46,
+ 0x75, 0x6e, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3d, 0x53,
+ 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x72, 0x65, 0x73, 0x75,
+ 0x6c, 0x74, 0x29, 0x7d, 0x63, 0x61, 0x74, 0x63, 0x68, 0x28,
+ 0x65, 0x29, 0x7b, 0x46, 0x75, 0x6e, 0x45, 0x72, 0x72, 0x6f,
+ 0x72, 0x3d, 0x21, 0x30, 0x2c, 0x46, 0x75, 0x6e, 0x52, 0x65,
+ 0x74, 0x75, 0x72, 0x6e, 0x3d, 0x65, 0x2e, 0x6d, 0x65, 0x73,
+ 0x73, 0x61, 0x67, 0x65, 0x7d, 0x69, 0x66, 0x28, 0x62, 0x75,
+ 0x66, 0x66, 0x65, 0x72, 0x38, 0x5b, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c,
+ 0x5f, 0x43, 0x4d, 0x44, 0x5d, 0x3d, 0x3d, 0x3d, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x4a, 0x53,
+ 0x5f, 0x51, 0x55, 0x49, 0x43, 0x4b, 0x29, 0x72, 0x65, 0x74,
+ 0x75, 0x72, 0x6e, 0x3b, 0x69, 0x66, 0x28, 0x46, 0x75, 0x6e,
+ 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3d, 0x3d, 0x3d, 0x76,
+ 0x6f, 0x69, 0x64, 0x20, 0x30, 0x26, 0x26, 0x28, 0x46, 0x75,
+ 0x6e, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x3d, 0x22, 0x75,
+ 0x6e, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x22, 0x29,
+ 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67,
+ 0x26, 0x26, 0x21, 0x46, 0x75, 0x6e, 0x45, 0x72, 0x72, 0x6f,
+ 0x72, 0x29, 0x69, 0x66, 0x28, 0x69, 0x73, 0x42, 0x69, 0x6e,
+ 0x61, 0x72, 0x79, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x29,
+ 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72,
+ 0x79, 0x44, 0x61, 0x74, 0x61, 0x3d, 0x46, 0x75, 0x6e, 0x52,
+ 0x65, 0x74, 0x75, 0x72, 0x6e, 0x2c, 0x68, 0x65, 0x78, 0x50,
+ 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x3d, 0x41, 0x72, 0x72,
+ 0x61, 0x79, 0x2e, 0x66, 0x72, 0x6f, 0x6d, 0x28, 0x62, 0x69,
+ 0x6e, 0x61, 0x72, 0x79, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x73,
+ 0x6c, 0x69, 0x63, 0x65, 0x28, 0x30, 0x2c, 0x36, 0x34, 0x29,
+ 0x29, 0x2e, 0x6d, 0x61, 0x70, 0x28, 0x62, 0x3d, 0x3e, 0x60,
+ 0x30, 0x78, 0x24, 0x7b, 0x62, 0x2e, 0x74, 0x6f, 0x53, 0x74,
+ 0x72, 0x69, 0x6e, 0x67, 0x28, 0x31, 0x36, 0x29, 0x2e, 0x70,
+ 0x61, 0x64, 0x53, 0x74, 0x61, 0x72, 0x74, 0x28, 0x32, 0x2c,
+ 0x22, 0x30, 0x22, 0x29, 0x7d, 0x60, 0x29, 0x2e, 0x6a, 0x6f,
+ 0x69, 0x6e, 0x28, 0x22, 0x2c, 0x20, 0x22, 0x29, 0x3b, 0x63,
+ 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67,
+ 0x28, 0x60, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d, 0x3e,
+ 0x20, 0x43, 0x4d, 0x44, 0x20, 0x2d, 0x3e, 0x20, 0x4a, 0x53,
+ 0x20, 0x2d, 0x3e, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e,
+ 0x20, 0x53, 0x75, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x28,
+ 0x24, 0x7b, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x44, 0x61,
+ 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x7d,
+ 0x20, 0x42, 0x79, 0x74, 0x65, 0x73, 0x29, 0x20, 0x5b, 0x24,
+ 0x7b, 0x68, 0x65, 0x78, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65,
+ 0x77, 0x7d, 0x24, 0x7b, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79,
+ 0x44, 0x61, 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74,
+ 0x68, 0x3e, 0x36, 0x34, 0x3f, 0x22, 0x2e, 0x2e, 0x2e, 0x22,
+ 0x3a, 0x22, 0x22, 0x7d, 0x5d, 0x60, 0x29, 0x7d, 0x65, 0x6c,
+ 0x73, 0x65, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x74, 0x72,
+ 0x69, 0x6e, 0x67, 0x44, 0x61, 0x74, 0x61, 0x3d, 0x53, 0x74,
+ 0x72, 0x69, 0x6e, 0x67, 0x28, 0x46, 0x75, 0x6e, 0x52, 0x65,
+ 0x74, 0x75, 0x72, 0x6e, 0x29, 0x3b, 0x63, 0x6f, 0x6e, 0x73,
+ 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x60, 0x57,
+ 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x43, 0x4d,
+ 0x44, 0x20, 0x2d, 0x3e, 0x20, 0x4a, 0x53, 0x20, 0x2d, 0x3e,
+ 0x20, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x53, 0x75,
+ 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x28, 0x24, 0x7b, 0x6e,
+ 0x65, 0x77, 0x20, 0x54, 0x65, 0x78, 0x74, 0x45, 0x6e, 0x63,
+ 0x6f, 0x64, 0x65, 0x72, 0x28, 0x29, 0x2e, 0x65, 0x6e, 0x63,
+ 0x6f, 0x64, 0x65, 0x28, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
+ 0x44, 0x61, 0x74, 0x61, 0x29, 0x2e, 0x6c, 0x65, 0x6e, 0x67,
+ 0x74, 0x68, 0x7d, 0x20, 0x42, 0x79, 0x74, 0x65, 0x73, 0x29,
+ 0x20, 0x5b, 0x24, 0x7b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
+ 0x44, 0x61, 0x74, 0x61, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74,
+ 0x72, 0x69, 0x6e, 0x67, 0x28, 0x30, 0x2c, 0x36, 0x34, 0x29,
+ 0x7d, 0x24, 0x7b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x44,
+ 0x61, 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68,
+ 0x3e, 0x36, 0x34, 0x3f, 0x22, 0x2e, 0x2e, 0x2e, 0x22, 0x3a,
+ 0x22, 0x22, 0x7d, 0x5d, 0x60, 0x29, 0x7d, 0x65, 0x6c, 0x73,
+ 0x65, 0x20, 0x69, 0x66, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x6c, 0x6f, 0x67, 0x26, 0x26, 0x46, 0x75, 0x6e, 0x45,
+ 0x72, 0x72, 0x6f, 0x72, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20,
+ 0x65, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x74, 0x72, 0x69, 0x6e,
+ 0x67, 0x3d, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x28, 0x46,
+ 0x75, 0x6e, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x29, 0x3b,
+ 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f,
+ 0x67, 0x28, 0x60, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d,
+ 0x3e, 0x20, 0x43, 0x4d, 0x44, 0x20, 0x2d, 0x3e, 0x20, 0x4a,
+ 0x53, 0x20, 0x2d, 0x3e, 0x20, 0x52, 0x65, 0x74, 0x75, 0x72,
+ 0x6e, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x5b, 0x24,
+ 0x7b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x74, 0x72, 0x69,
+ 0x6e, 0x67, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69,
+ 0x6e, 0x67, 0x28, 0x30, 0x2c, 0x36, 0x34, 0x29, 0x7d, 0x24,
+ 0x7b, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x74, 0x72, 0x69,
+ 0x6e, 0x67, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e,
+ 0x36, 0x34, 0x3f, 0x22, 0x2e, 0x2e, 0x2e, 0x22, 0x3a, 0x22,
+ 0x22, 0x7d, 0x5d, 0x60, 0x29, 0x7d, 0x6c, 0x65, 0x74, 0x20,
+ 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x3d, 0x6e, 0x65, 0x77,
+ 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61,
+ 0x79, 0x28, 0x30, 0x29, 0x2c, 0x70, 0x61, 0x63, 0x6b, 0x65,
+ 0x74, 0x50, 0x75, 0x73, 0x68, 0x3d, 0x64, 0x61, 0x74, 0x61,
+ 0x3d, 0x3e, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x65, 0x77,
+ 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x3d, 0x6e, 0x65, 0x77,
+ 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61,
+ 0x79, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6c,
+ 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2b, 0x64, 0x61, 0x74, 0x61,
+ 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x29, 0x3b, 0x6e,
+ 0x65, 0x77, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x73,
+ 0x65, 0x74, 0x28, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x29,
+ 0x2c, 0x6e, 0x65, 0x77, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74,
+ 0x2e, 0x73, 0x65, 0x74, 0x28, 0x64, 0x61, 0x74, 0x61, 0x2c,
+ 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2e, 0x6c, 0x65, 0x6e,
+ 0x67, 0x74, 0x68, 0x29, 0x2c, 0x70, 0x61, 0x63, 0x6b, 0x65,
+ 0x74, 0x3d, 0x6e, 0x65, 0x77, 0x50, 0x61, 0x63, 0x6b, 0x65,
+ 0x74, 0x7d, 0x2c, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x50,
+ 0x75, 0x73, 0x68, 0x53, 0x74, 0x72, 0x3d, 0x64, 0x61, 0x74,
+ 0x61, 0x3d, 0x3e, 0x7b, 0x69, 0x66, 0x28, 0x64, 0x61, 0x74,
+ 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3e, 0x38,
+ 0x31, 0x39, 0x32, 0x29, 0x7b, 0x6c, 0x65, 0x74, 0x20, 0x65,
+ 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x3d, 0x6e, 0x65, 0x77,
+ 0x20, 0x54, 0x65, 0x78, 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64,
+ 0x65, 0x72, 0x3b, 0x66, 0x6f, 0x72, 0x28, 0x6c, 0x65, 0x74,
+ 0x20, 0x69, 0x3d, 0x30, 0x3b, 0x69, 0x3c, 0x64, 0x61, 0x74,
+ 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3b, 0x69,
+ 0x2b, 0x3d, 0x38, 0x31, 0x39, 0x32, 0x29, 0x7b, 0x6c, 0x65,
+ 0x74, 0x20, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x3d, 0x64, 0x61,
+ 0x74, 0x61, 0x2e, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 0x69,
+ 0x6e, 0x67, 0x28, 0x69, 0x2c, 0x4d, 0x61, 0x74, 0x68, 0x2e,
+ 0x6d, 0x69, 0x6e, 0x28, 0x69, 0x2b, 0x38, 0x31, 0x39, 0x32,
+ 0x2c, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x6c, 0x65, 0x6e, 0x67,
+ 0x74, 0x68, 0x29, 0x29, 0x2c, 0x65, 0x6e, 0x63, 0x6f, 0x64,
+ 0x65, 0x64, 0x43, 0x68, 0x75, 0x6e, 0x6b, 0x3d, 0x65, 0x6e,
+ 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x63, 0x6f,
+ 0x64, 0x65, 0x28, 0x63, 0x68, 0x75, 0x6e, 0x6b, 0x29, 0x3b,
+ 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x75, 0x73, 0x68,
+ 0x28, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x64, 0x43, 0x68,
+ 0x75, 0x6e, 0x6b, 0x29, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65,
+ 0x20, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x75, 0x73,
+ 0x68, 0x28, 0x6e, 0x65, 0x77, 0x20, 0x54, 0x65, 0x78, 0x74,
+ 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x28, 0x29, 0x2e,
+ 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x28, 0x64, 0x61, 0x74,
+ 0x61, 0x29, 0x29, 0x7d, 0x3b, 0x70, 0x61, 0x63, 0x6b, 0x65,
+ 0x74, 0x50, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x65, 0x77, 0x20,
+ 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61, 0x79,
+ 0x28, 0x5b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x57, 0x45,
+ 0x42, 0x55, 0x49, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41, 0x54,
+ 0x55, 0x52, 0x45, 0x5d, 0x29, 0x29, 0x2c, 0x70, 0x61, 0x63,
+ 0x6b, 0x65, 0x74, 0x50, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x65,
+ 0x77, 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72,
+ 0x61, 0x79, 0x28, 0x5b, 0x30, 0x2c, 0x30, 0x2c, 0x30, 0x2c,
+ 0x30, 0x5d, 0x29, 0x29, 0x2c, 0x70, 0x61, 0x63, 0x6b, 0x65,
+ 0x74, 0x50, 0x75, 0x73, 0x68, 0x28, 0x6e, 0x65, 0x77, 0x20,
+ 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41, 0x72, 0x72, 0x61, 0x79,
+ 0x28, 0x5b, 0x30, 0x2c, 0x30, 0x5d, 0x29, 0x29, 0x2c, 0x70,
+ 0x61, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x75, 0x73, 0x68, 0x28,
+ 0x6e, 0x65, 0x77, 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41,
+ 0x72, 0x72, 0x61, 0x79, 0x28, 0x5b, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x4a, 0x53, 0x5d, 0x29,
+ 0x29, 0x2c, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x75,
+ 0x73, 0x68, 0x28, 0x6e, 0x65, 0x77, 0x20, 0x55, 0x69, 0x6e,
+ 0x74, 0x38, 0x41, 0x72, 0x72, 0x61, 0x79, 0x28, 0x46, 0x75,
+ 0x6e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x3f, 0x5b, 0x31, 0x5d,
+ 0x3a, 0x5b, 0x30, 0x5d, 0x29, 0x29, 0x2c, 0x69, 0x73, 0x42,
+ 0x69, 0x6e, 0x61, 0x72, 0x79, 0x52, 0x65, 0x74, 0x75, 0x72,
+ 0x6e, 0x3f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x75,
+ 0x73, 0x68, 0x28, 0x46, 0x75, 0x6e, 0x52, 0x65, 0x74, 0x75,
+ 0x72, 0x6e, 0x29, 0x3a, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74,
+ 0x50, 0x75, 0x73, 0x68, 0x53, 0x74, 0x72, 0x28, 0x46, 0x75,
+ 0x6e, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x29, 0x2c, 0x70,
+ 0x61, 0x63, 0x6b, 0x65, 0x74, 0x50, 0x75, 0x73, 0x68, 0x28,
+ 0x6e, 0x65, 0x77, 0x20, 0x55, 0x69, 0x6e, 0x74, 0x38, 0x41,
+ 0x72, 0x72, 0x61, 0x79, 0x28, 0x5b, 0x30, 0x5d, 0x29, 0x29,
+ 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x61, 0x64, 0x64,
+ 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x28, 0x70, 0x61, 0x63, 0x6b,
+ 0x65, 0x74, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x74,
+ 0x6f, 0x6b, 0x65, 0x6e, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f,
+ 0x54, 0x4f, 0x4b, 0x45, 0x4e, 0x29, 0x2c, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x61, 0x64, 0x64, 0x49, 0x44, 0x28, 0x70,
+ 0x61, 0x63, 0x6b, 0x65, 0x74, 0x2c, 0x63, 0x61, 0x6c, 0x6c,
+ 0x49, 0x64, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50,
+ 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x49, 0x44,
+ 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x73, 0x65,
+ 0x6e, 0x64, 0x44, 0x61, 0x74, 0x61, 0x28, 0x70, 0x61, 0x63,
+ 0x6b, 0x65, 0x74, 0x29, 0x7d, 0x62, 0x72, 0x65, 0x61, 0x6b,
+ 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x43, 0x41, 0x4c, 0x4c,
+ 0x5f, 0x46, 0x55, 0x4e, 0x43, 0x3a, 0x7b, 0x6c, 0x65, 0x74,
+ 0x20, 0x63, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x67, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x72,
+ 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74,
+ 0x28, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x38, 0x2c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f,
+ 0x43, 0x4f, 0x4c, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x29, 0x3b,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x26,
+ 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c,
+ 0x6f, 0x67, 0x28, 0x60, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20,
+ 0x2d, 0x3e, 0x20, 0x43, 0x4d, 0x44, 0x20, 0x2d, 0x3e, 0x20,
+ 0x43, 0x61, 0x6c, 0x6c, 0x20, 0x52, 0x65, 0x73, 0x70, 0x6f,
+ 0x6e, 0x73, 0x65, 0x20, 0x5b, 0x24, 0x7b, 0x63, 0x61, 0x6c,
+ 0x6c, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x7d,
+ 0x5d, 0x60, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x63, 0x61, 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73,
+ 0x65, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x5b, 0x63,
+ 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x5d, 0x26, 0x26, 0x28, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x26, 0x26,
+ 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f,
+ 0x67, 0x28, 0x60, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d,
+ 0x3e, 0x20, 0x43, 0x4d, 0x44, 0x20, 0x2d, 0x3e, 0x20, 0x52,
+ 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x69, 0x6e, 0x67, 0x20, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x20, 0x23, 0x24,
+ 0x7b, 0x63, 0x61, 0x6c, 0x6c, 0x49, 0x64, 0x7d, 0x2e, 0x2e,
+ 0x2e, 0x60, 0x29, 0x2c, 0x28, 0x5f, 0x62, 0x3d, 0x28, 0x5f,
+ 0x61, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x61,
+ 0x6c, 0x6c, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x52,
+ 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x29, 0x5b, 0x63, 0x61,
+ 0x6c, 0x6c, 0x49, 0x64, 0x5d, 0x29, 0x3d, 0x3d, 0x6e, 0x75,
+ 0x6c, 0x6c, 0x7c, 0x7c, 0x5f, 0x62, 0x2e, 0x63, 0x61, 0x6c,
+ 0x6c, 0x28, 0x5f, 0x61, 0x2c, 0x63, 0x61, 0x6c, 0x6c, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x29, 0x2c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x63, 0x61, 0x6c, 0x6c, 0x50,
+ 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x52, 0x65, 0x73, 0x6f,
+ 0x6c, 0x76, 0x65, 0x5b, 0x63, 0x61, 0x6c, 0x6c, 0x49, 0x64,
+ 0x5d, 0x3d, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x30, 0x29, 0x7d,
+ 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x63, 0x61, 0x73, 0x65,
+ 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x43, 0x4d, 0x44,
+ 0x5f, 0x4e, 0x41, 0x56, 0x49, 0x47, 0x41, 0x54, 0x49, 0x4f,
+ 0x4e, 0x3a, 0x6c, 0x65, 0x74, 0x20, 0x75, 0x72, 0x6c, 0x3d,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x67, 0x65, 0x74, 0x44,
+ 0x61, 0x74, 0x61, 0x53, 0x74, 0x72, 0x46, 0x72, 0x6f, 0x6d,
+ 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x28, 0x62, 0x75, 0x66,
+ 0x66, 0x65, 0x72, 0x38, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f,
+ 0x44, 0x41, 0x54, 0x41, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x26, 0x26, 0x63, 0x6f, 0x6e,
+ 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x60,
+ 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x43,
+ 0x4d, 0x44, 0x20, 0x2d, 0x3e, 0x20, 0x4e, 0x61, 0x76, 0x69,
+ 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x5b, 0x24, 0x7b,
+ 0x75, 0x72, 0x6c, 0x7d, 0x5d, 0x60, 0x29, 0x2c, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x28,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x43, 0x4d, 0x44, 0x5f,
+ 0x4e, 0x41, 0x56, 0x49, 0x47, 0x41, 0x54, 0x49, 0x4f, 0x4e,
+ 0x2c, 0x75, 0x72, 0x6c, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61,
+ 0x6b, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x57, 0x49, 0x4e,
+ 0x44, 0x4f, 0x57, 0x5f, 0x52, 0x45, 0x53, 0x49, 0x5a, 0x45,
+ 0x44, 0x3a, 0x6c, 0x65, 0x74, 0x20, 0x77, 0x69, 0x64, 0x74,
+ 0x68, 0x41, 0x6e, 0x64, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74,
+ 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x67, 0x65, 0x74,
+ 0x44, 0x61, 0x74, 0x61, 0x53, 0x74, 0x72, 0x46, 0x72, 0x6f,
+ 0x6d, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x28, 0x62, 0x75,
+ 0x66, 0x66, 0x65, 0x72, 0x38, 0x2c, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c,
+ 0x5f, 0x44, 0x41, 0x54, 0x41, 0x29, 0x2c, 0x7b, 0x78, 0x2c,
+ 0x79, 0x2c, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x68, 0x65,
+ 0x69, 0x67, 0x68, 0x74, 0x7d, 0x3d, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x70, 0x61, 0x72, 0x73, 0x65, 0x44, 0x69, 0x6d,
+ 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x28, 0x77, 0x69,
+ 0x64, 0x74, 0x68, 0x41, 0x6e, 0x64, 0x48, 0x65, 0x69, 0x67,
+ 0x68, 0x74, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x57, 0x69, 0x6e,
+ 0x64, 0x6f, 0x77, 0x58, 0x3d, 0x78, 0x2c, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74,
+ 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x59, 0x3d, 0x79, 0x2c,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x26,
+ 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c,
+ 0x6f, 0x67, 0x28, 0x60, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20,
+ 0x2d, 0x3e, 0x20, 0x43, 0x4d, 0x44, 0x20, 0x2d, 0x3e, 0x20,
+ 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x52, 0x65, 0x73,
+ 0x69, 0x7a, 0x65, 0x64, 0x20, 0x5b, 0x78, 0x3a, 0x20, 0x24,
+ 0x7b, 0x78, 0x7d, 0x2c, 0x20, 0x79, 0x3a, 0x20, 0x24, 0x7b,
+ 0x79, 0x7d, 0x2c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a,
+ 0x20, 0x24, 0x7b, 0x77, 0x69, 0x64, 0x74, 0x68, 0x7d, 0x2c,
+ 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x24,
+ 0x7b, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x7d, 0x5d, 0x60,
+ 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x63, 0x61,
+ 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x43,
+ 0x4d, 0x44, 0x5f, 0x4e, 0x45, 0x57, 0x5f, 0x49, 0x44, 0x3a,
+ 0x6c, 0x65, 0x74, 0x20, 0x6e, 0x65, 0x77, 0x45, 0x6c, 0x65,
+ 0x6d, 0x65, 0x6e, 0x74, 0x3d, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x67, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x53, 0x74,
+ 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x63, 0x6b, 0x65,
+ 0x74, 0x28, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x38, 0x2c,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50, 0x52, 0x4f, 0x54,
+ 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x29,
+ 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67,
+ 0x26, 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e,
+ 0x6c, 0x6f, 0x67, 0x28, 0x60, 0x57, 0x65, 0x62, 0x55, 0x49,
+ 0x20, 0x2d, 0x3e, 0x20, 0x43, 0x4d, 0x44, 0x20, 0x2d, 0x3e,
+ 0x20, 0x4e, 0x65, 0x77, 0x20, 0x42, 0x69, 0x6e, 0x64, 0x20,
+ 0x49, 0x44, 0x20, 0x5b, 0x24, 0x7b, 0x6e, 0x65, 0x77, 0x45,
+ 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x7d, 0x5d, 0x60, 0x29,
+ 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x62, 0x69, 0x6e,
+ 0x64, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x69, 0x6e, 0x63,
+ 0x6c, 0x75, 0x64, 0x65, 0x73, 0x28, 0x6e, 0x65, 0x77, 0x45,
+ 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x29, 0x7c, 0x7c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x62, 0x69, 0x6e, 0x64, 0x73,
+ 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x70, 0x75, 0x73, 0x68, 0x28,
+ 0x6e, 0x65, 0x77, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+ 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x75, 0x70,
+ 0x64, 0x61, 0x74, 0x65, 0x42, 0x69, 0x6e, 0x64, 0x73, 0x4c,
+ 0x69, 0x73, 0x74, 0x28, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61,
+ 0x6b, 0x3b, 0x63, 0x61, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x43, 0x4c, 0x4f,
+ 0x53, 0x45, 0x3a, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c,
+ 0x6f, 0x67, 0x3f, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c,
+ 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x22, 0x57, 0x65, 0x62,
+ 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x43, 0x4d, 0x44, 0x20,
+ 0x2d, 0x3e, 0x20, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x22, 0x29,
+ 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x49,
+ 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64,
+ 0x28, 0x29, 0x26, 0x26, 0x28, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x77, 0x73, 0x53, 0x74, 0x61, 0x79, 0x41, 0x6c, 0x69,
+ 0x76, 0x65, 0x3d, 0x21, 0x31, 0x2c, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x77, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x73, 0x65,
+ 0x28, 0x29, 0x29, 0x29, 0x3a, 0x67, 0x6c, 0x6f, 0x62, 0x61,
+ 0x6c, 0x54, 0x68, 0x69, 0x73, 0x2e, 0x63, 0x6c, 0x6f, 0x73,
+ 0x65, 0x28, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b,
+ 0x63, 0x61, 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x43, 0x4d, 0x44, 0x5f, 0x43, 0x48, 0x45, 0x43, 0x4b,
+ 0x5f, 0x54, 0x4b, 0x3a, 0x6c, 0x65, 0x74, 0x20, 0x73, 0x74,
+ 0x61, 0x74, 0x75, 0x73, 0x3d, 0x62, 0x75, 0x66, 0x66, 0x65,
+ 0x72, 0x38, 0x5b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50,
+ 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x44, 0x41,
+ 0x54, 0x41, 0x5d, 0x21, 0x3d, 0x30, 0x2c, 0x74, 0x6f, 0x6b,
+ 0x65, 0x6e, 0x48, 0x65, 0x78, 0x3d, 0x60, 0x30, 0x78, 0x24,
+ 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x74, 0x6f, 0x6b,
+ 0x65, 0x6e, 0x2e, 0x74, 0x6f, 0x53, 0x74, 0x72, 0x69, 0x6e,
+ 0x67, 0x28, 0x31, 0x36, 0x29, 0x2e, 0x70, 0x61, 0x64, 0x53,
+ 0x74, 0x61, 0x72, 0x74, 0x28, 0x38, 0x2c, 0x22, 0x30, 0x22,
+ 0x29, 0x7d, 0x60, 0x3b, 0x69, 0x66, 0x28, 0x73, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x6c, 0x6f, 0x67, 0x26, 0x26, 0x63, 0x6f, 0x6e, 0x73,
+ 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x60, 0x57,
+ 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x43, 0x4d,
+ 0x44, 0x20, 0x2d, 0x3e, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
+ 0x20, 0x5b, 0x24, 0x7b, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x48,
+ 0x65, 0x78, 0x7d, 0x5d, 0x20, 0x41, 0x63, 0x63, 0x65, 0x70,
+ 0x74, 0x65, 0x64, 0x60, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x41, 0x63, 0x63,
+ 0x65, 0x70, 0x74, 0x65, 0x64, 0x3d, 0x21, 0x30, 0x3b, 0x6c,
+ 0x65, 0x74, 0x20, 0x63, 0x73, 0x76, 0x3d, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x67, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61,
+ 0x53, 0x74, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61, 0x63,
+ 0x6b, 0x65, 0x74, 0x28, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72,
+ 0x38, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50, 0x52,
+ 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x44, 0x41, 0x54,
+ 0x41, 0x2b, 0x31, 0x29, 0x3b, 0x63, 0x73, 0x76, 0x3d, 0x63,
+ 0x73, 0x76, 0x2e, 0x65, 0x6e, 0x64, 0x73, 0x57, 0x69, 0x74,
+ 0x68, 0x28, 0x22, 0x2c, 0x22, 0x29, 0x3f, 0x63, 0x73, 0x76,
+ 0x2e, 0x73, 0x6c, 0x69, 0x63, 0x65, 0x28, 0x30, 0x2c, 0x2d,
+ 0x31, 0x29, 0x3a, 0x63, 0x73, 0x76, 0x2c, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x62, 0x69, 0x6e, 0x64, 0x73, 0x4c, 0x69,
+ 0x73, 0x74, 0x3d, 0x63, 0x73, 0x76, 0x2e, 0x73, 0x70, 0x6c,
+ 0x69, 0x74, 0x28, 0x22, 0x2c, 0x22, 0x29, 0x2c, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
+ 0x42, 0x69, 0x6e, 0x64, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x28,
+ 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x75, 0x73,
+ 0x65, 0x72, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x6c,
+ 0x6c, 0x62, 0x61, 0x63, 0x6b, 0x28, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x4f, 0x4e,
+ 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x29, 0x7d, 0x65, 0x6c,
+ 0x73, 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c,
+ 0x6f, 0x67, 0x26, 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c,
+ 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x60, 0x57, 0x65, 0x62,
+ 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x43, 0x4d, 0x44, 0x20,
+ 0x2d, 0x3e, 0x20, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x20, 0x5b,
+ 0x24, 0x7b, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x48, 0x65, 0x78,
+ 0x7d, 0x5d, 0x20, 0x4e, 0x6f, 0x74, 0x20, 0x41, 0x63, 0x63,
+ 0x65, 0x70, 0x74, 0x65, 0x64, 0x2e, 0x20, 0x52, 0x65, 0x6c,
+ 0x6f, 0x61, 0x64, 0x20, 0x70, 0x61, 0x67, 0x65, 0x2e, 0x2e,
+ 0x2e, 0x60, 0x29, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x4e, 0x61, 0x76, 0x69, 0x67,
+ 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x21, 0x30, 0x2c, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x77, 0x73, 0x53, 0x74, 0x61,
+ 0x79, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x3d, 0x21, 0x31, 0x2c,
+ 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x54, 0x68, 0x69, 0x73,
+ 0x2e, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
+ 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x29, 0x3b, 0x62,
+ 0x72, 0x65, 0x61, 0x6b, 0x7d, 0x7d, 0x65, 0x6c, 0x73, 0x65,
+ 0x20, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x28, 0x62, 0x75,
+ 0x66, 0x66, 0x65, 0x72, 0x38, 0x5b, 0x74, 0x68, 0x69, 0x73,
+ 0x2e, 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c,
+ 0x5f, 0x43, 0x4d, 0x44, 0x5d, 0x29, 0x7b, 0x63, 0x61, 0x73,
+ 0x65, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x43, 0x4d,
+ 0x44, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x5f, 0x52, 0x41, 0x57,
+ 0x3a, 0x6c, 0x65, 0x74, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x3d, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x67, 0x65, 0x74, 0x44, 0x61, 0x74,
+ 0x61, 0x53, 0x74, 0x72, 0x46, 0x72, 0x6f, 0x6d, 0x50, 0x61,
+ 0x63, 0x6b, 0x65, 0x74, 0x28, 0x62, 0x75, 0x66, 0x66, 0x65,
+ 0x72, 0x38, 0x2c, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x50,
+ 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x44, 0x41,
+ 0x54, 0x41, 0x29, 0x2c, 0x72, 0x61, 0x77, 0x44, 0x61, 0x74,
+ 0x61, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x3d, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f,
+ 0x4c, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x2b, 0x66, 0x75, 0x6e,
+ 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x2e,
+ 0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2b, 0x31, 0x2c, 0x72,
+ 0x61, 0x77, 0x44, 0x61, 0x74, 0x61, 0x53, 0x69, 0x7a, 0x65,
+ 0x3d, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x38, 0x2e, 0x6c,
+ 0x65, 0x6e, 0x67, 0x74, 0x68, 0x2d, 0x72, 0x61, 0x77, 0x44,
+ 0x61, 0x74, 0x61, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x2d, 0x31,
+ 0x2c, 0x75, 0x73, 0x65, 0x72, 0x52, 0x61, 0x77, 0x44, 0x61,
+ 0x74, 0x61, 0x3d, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x38,
+ 0x2e, 0x73, 0x75, 0x62, 0x61, 0x72, 0x72, 0x61, 0x79, 0x28,
+ 0x72, 0x61, 0x77, 0x44, 0x61, 0x74, 0x61, 0x49, 0x6e, 0x64,
+ 0x65, 0x78, 0x2c, 0x72, 0x61, 0x77, 0x44, 0x61, 0x74, 0x61,
+ 0x49, 0x6e, 0x64, 0x65, 0x78, 0x2b, 0x72, 0x61, 0x77, 0x44,
+ 0x61, 0x74, 0x61, 0x53, 0x69, 0x7a, 0x65, 0x29, 0x3b, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x26, 0x26,
+ 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f,
+ 0x67, 0x28, 0x60, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d,
+ 0x3e, 0x20, 0x43, 0x4d, 0x44, 0x20, 0x2d, 0x3e, 0x20, 0x52,
+ 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x64, 0x20, 0x52, 0x61,
+ 0x77, 0x20, 0x24, 0x7b, 0x72, 0x61, 0x77, 0x44, 0x61, 0x74,
+ 0x61, 0x53, 0x69, 0x7a, 0x65, 0x7d, 0x20, 0x62, 0x79, 0x74,
+ 0x65, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x5b, 0x24, 0x7b,
+ 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61,
+ 0x6d, 0x65, 0x7d, 0x28, 0x29, 0x5d, 0x60, 0x29, 0x2c, 0x74,
+ 0x79, 0x70, 0x65, 0x6f, 0x66, 0x20, 0x77, 0x69, 0x6e, 0x64,
+ 0x6f, 0x77, 0x5b, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x5d, 0x3d, 0x3d, 0x22, 0x66,
+ 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3f, 0x77,
+ 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x5b, 0x66, 0x75, 0x6e, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x5d, 0x28,
+ 0x75, 0x73, 0x65, 0x72, 0x52, 0x61, 0x77, 0x44, 0x61, 0x74,
+ 0x61, 0x29, 0x3a, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x41,
+ 0x73, 0x79, 0x6e, 0x63, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x28, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x2b, 0x22, 0x28, 0x75, 0x73,
+ 0x65, 0x72, 0x52, 0x61, 0x77, 0x44, 0x61, 0x74, 0x61, 0x29,
+ 0x22, 0x29, 0x28, 0x29, 0x3b, 0x62, 0x72, 0x65, 0x61, 0x6b,
+ 0x7d, 0x7d, 0x3b, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x63,
+ 0x61, 0x6c, 0x6c, 0x28, 0x66, 0x6e, 0x2c, 0x2e, 0x2e, 0x2e,
+ 0x61, 0x72, 0x67, 0x73, 0x29, 0x7b, 0x69, 0x66, 0x28, 0x21,
+ 0x66, 0x6e, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
+ 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x2e, 0x72, 0x65,
+ 0x6a, 0x65, 0x63, 0x74, 0x28, 0x6e, 0x65, 0x77, 0x20, 0x53,
+ 0x79, 0x6e, 0x74, 0x61, 0x78, 0x45, 0x72, 0x72, 0x6f, 0x72,
+ 0x28, 0x22, 0x4e, 0x6f, 0x20, 0x62, 0x69, 0x6e, 0x64, 0x69,
+ 0x6e, 0x67, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x69, 0x73,
+ 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x22,
+ 0x29, 0x29, 0x3b, 0x69, 0x66, 0x28, 0x21, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x77, 0x73, 0x49, 0x73, 0x43, 0x6f, 0x6e,
+ 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x28, 0x29, 0x29, 0x72,
+ 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x50, 0x72, 0x6f, 0x6d,
+ 0x69, 0x73, 0x65, 0x2e, 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74,
+ 0x28, 0x6e, 0x65, 0x77, 0x20, 0x45, 0x72, 0x72, 0x6f, 0x72,
+ 0x28, 0x22, 0x57, 0x65, 0x62, 0x53, 0x6f, 0x63, 0x6b, 0x65,
+ 0x74, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x63,
+ 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, 0x64, 0x22, 0x29,
+ 0x29, 0x3b, 0x69, 0x66, 0x28, 0x66, 0x6e, 0x21, 0x3d, 0x3d,
+ 0x22, 0x5f, 0x5f, 0x77, 0x65, 0x62, 0x75, 0x69, 0x5f, 0x63,
+ 0x6f, 0x72, 0x65, 0x5f, 0x61, 0x70, 0x69, 0x5f, 0x5f, 0x22,
+ 0x26, 0x26, 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x41,
+ 0x6c, 0x6c, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x26, 0x26,
+ 0x21, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x62, 0x69, 0x6e,
+ 0x64, 0x73, 0x4c, 0x69, 0x73, 0x74, 0x2e, 0x69, 0x6e, 0x63,
+ 0x6c, 0x75, 0x64, 0x65, 0x73, 0x28, 0x60, 0x24, 0x7b, 0x66,
+ 0x6e, 0x7d, 0x60, 0x29, 0x29, 0x72, 0x65, 0x74, 0x75, 0x72,
+ 0x6e, 0x20, 0x50, 0x72, 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x2e,
+ 0x72, 0x65, 0x6a, 0x65, 0x63, 0x74, 0x28, 0x6e, 0x65, 0x77,
+ 0x20, 0x52, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65,
+ 0x45, 0x72, 0x72, 0x6f, 0x72, 0x28, 0x60, 0x4e, 0x6f, 0x20,
+ 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x20, 0x77, 0x61,
+ 0x73, 0x20, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x66, 0x6f,
+ 0x72, 0x20, 0x22, 0x24, 0x7b, 0x66, 0x6e, 0x7d, 0x22, 0x60,
+ 0x29, 0x29, 0x3b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c,
+ 0x6f, 0x67, 0x26, 0x26, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c,
+ 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28, 0x60, 0x57, 0x65, 0x62,
+ 0x55, 0x49, 0x20, 0x2d, 0x3e, 0x20, 0x43, 0x61, 0x6c, 0x6c,
+ 0x69, 0x6e, 0x67, 0x20, 0x5b, 0x24, 0x7b, 0x66, 0x6e, 0x7d,
+ 0x28, 0x2e, 0x2e, 0x2e, 0x29, 0x5d, 0x60, 0x29, 0x3b, 0x6c,
+ 0x65, 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x3d, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x74, 0x68,
+ 0x69, 0x73, 0x2e, 0x23, 0x63, 0x61, 0x6c, 0x6c, 0x50, 0x72,
+ 0x6f, 0x6d, 0x69, 0x73, 0x65, 0x28, 0x66, 0x6e, 0x2c, 0x2e,
+ 0x2e, 0x2e, 0x61, 0x72, 0x67, 0x73, 0x29, 0x3b, 0x72, 0x65,
+ 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x79, 0x70, 0x65, 0x6f,
+ 0x66, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+ 0x21, 0x3d, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22,
+ 0x3f, 0x22, 0x22, 0x3a, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x7d, 0x73, 0x65, 0x74, 0x4c, 0x6f, 0x67, 0x67,
+ 0x69, 0x6e, 0x67, 0x28, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
+ 0x29, 0x7b, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x3f, 0x28,
+ 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f,
+ 0x67, 0x28, 0x22, 0x57, 0x65, 0x62, 0x55, 0x49, 0x20, 0x2d,
+ 0x3e, 0x20, 0x4c, 0x6f, 0x67, 0x20, 0x45, 0x6e, 0x61, 0x62,
+ 0x6c, 0x65, 0x64, 0x2e, 0x22, 0x29, 0x2c, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x3d, 0x21, 0x30, 0x29,
+ 0x3a, 0x28, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e,
+ 0x6c, 0x6f, 0x67, 0x28, 0x22, 0x57, 0x65, 0x62, 0x55, 0x49,
+ 0x20, 0x2d, 0x3e, 0x20, 0x4c, 0x6f, 0x67, 0x20, 0x44, 0x69,
+ 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x2e, 0x22, 0x29, 0x2c,
+ 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x3d,
+ 0x21, 0x31, 0x29, 0x7d, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65,
+ 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x7b, 0x72, 0x65, 0x74,
+ 0x75, 0x72, 0x6e, 0x20, 0x62, 0x74, 0x6f, 0x61, 0x28, 0x64,
+ 0x61, 0x74, 0x61, 0x29, 0x7d, 0x64, 0x65, 0x63, 0x6f, 0x64,
+ 0x65, 0x28, 0x64, 0x61, 0x74, 0x61, 0x29, 0x7b, 0x72, 0x65,
+ 0x74, 0x75, 0x72, 0x6e, 0x20, 0x61, 0x74, 0x6f, 0x62, 0x28,
+ 0x64, 0x61, 0x74, 0x61, 0x29, 0x7d, 0x73, 0x65, 0x74, 0x45,
+ 0x76, 0x65, 0x6e, 0x74, 0x43, 0x61, 0x6c, 0x6c, 0x62, 0x61,
+ 0x63, 0x6b, 0x28, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61, 0x63,
+ 0x6b, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23, 0x65,
+ 0x76, 0x65, 0x6e, 0x74, 0x73, 0x43, 0x61, 0x6c, 0x6c, 0x62,
+ 0x61, 0x63, 0x6b, 0x3d, 0x63, 0x61, 0x6c, 0x6c, 0x62, 0x61,
+ 0x63, 0x6b, 0x7d, 0x69, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
+ 0x63, 0x74, 0x65, 0x64, 0x28, 0x29, 0x7b, 0x72, 0x65, 0x74,
+ 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69, 0x73, 0x2e, 0x23,
+ 0x77, 0x73, 0x49, 0x73, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
+ 0x74, 0x65, 0x64, 0x28, 0x29, 0x26, 0x26, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x41, 0x63,
+ 0x63, 0x65, 0x70, 0x74, 0x65, 0x64, 0x7d, 0x61, 0x73, 0x79,
+ 0x6e, 0x63, 0x20, 0x69, 0x73, 0x48, 0x69, 0x67, 0x68, 0x43,
+ 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x28, 0x29, 0x7b,
+ 0x6c, 0x65, 0x74, 0x20, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e,
+ 0x73, 0x65, 0x3d, 0x61, 0x77, 0x61, 0x69, 0x74, 0x20, 0x74,
+ 0x68, 0x69, 0x73, 0x2e, 0x63, 0x61, 0x6c, 0x6c, 0x43, 0x6f,
+ 0x72, 0x65, 0x28, 0x22, 0x68, 0x69, 0x67, 0x68, 0x5f, 0x63,
+ 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x73, 0x74, 0x22, 0x29, 0x3b,
+ 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x68, 0x69,
+ 0x73, 0x2e, 0x23, 0x6c, 0x6f, 0x67, 0x26, 0x26, 0x63, 0x6f,
+ 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2e, 0x6c, 0x6f, 0x67, 0x28,
+ 0x60, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x52, 0x65, 0x73, 0x70,
+ 0x6f, 0x6e, 0x73, 0x65, 0x3a, 0x20, 0x5b, 0x24, 0x7b, 0x72,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x7d, 0x5d, 0x60,
+ 0x29, 0x2c, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
+ 0x7d, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x4e, 0x61, 0x76, 0x69,
+ 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x73, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x29, 0x7b, 0x74, 0x68, 0x69, 0x73, 0x2e,
+ 0x23, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x4e, 0x61, 0x76, 0x69,
+ 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x73, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x7d, 0x7d, 0x3b, 0x61, 0x64, 0x64, 0x45,
+ 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e,
+ 0x65, 0x72, 0x28, 0x22, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x2c,
+ 0x28, 0x29, 0x3d, 0x3e, 0x7b, 0x64, 0x6f, 0x63, 0x75, 0x6d,
+ 0x65, 0x6e, 0x74, 0x2e, 0x62, 0x6f, 0x64, 0x79, 0x2e, 0x61,
+ 0x64, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x4c, 0x69, 0x73,
+ 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x22, 0x63, 0x6f, 0x6e,
+ 0x74, 0x65, 0x78, 0x74, 0x6d, 0x65, 0x6e, 0x75, 0x22, 0x2c,
+ 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3d, 0x3e, 0x65, 0x76, 0x65,
+ 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x65, 0x76, 0x65, 0x6e, 0x74,
+ 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x28, 0x29, 0x29,
+ 0x2c, 0x61, 0x64, 0x64, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73,
+ 0x68, 0x61, 0x62, 0x6c, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74,
+ 0x4c, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x65, 0x72, 0x28, 0x64,
+ 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x62, 0x6f,
+ 0x64, 0x79, 0x2c, 0x22, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x22,
+ 0x2c, 0x22, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x6d,
+ 0x65, 0x6e, 0x75, 0x22, 0x2c, 0x65, 0x76, 0x65, 0x6e, 0x74,
+ 0x3d, 0x3e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x73, 0x74,
+ 0x6f, 0x70, 0x50, 0x72, 0x6f, 0x70, 0x61, 0x67, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x28, 0x29, 0x29, 0x7d, 0x29, 0x3b, 0x0a,
+ 0x00
+};
+
+#endif // WEBUI_BRIDGE_H
\ No newline at end of file
diff --git a/build.cmake.sh b/build.cmake.sh
new file mode 100644
index 0000000..66b440b
--- /dev/null
+++ b/build.cmake.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+mkdir -p build
+
+# webui-2.5.0, examples
+pushd build
+cmake .. --fresh
+cmake --build . --config Debug
+popd
+
diff --git a/build.zig b/build.zig
new file mode 100644
index 0000000..1bc8dc5
--- /dev/null
+++ b/build.zig
@@ -0,0 +1,240 @@
+const std = @import("std");
+const Build = std.Build;
+const OptimizeMode = std.builtin.OptimizeMode;
+const Compile = Build.Step.Compile;
+const Module = Build.Module;
+const builtin = @import("builtin");
+
+const lib_name = "webui";
+var global_log_level: std.log.Level = .warn;
+
+/// Vendored dependencies of webui.
+pub const Dependency = enum {
+ civetweb,
+ // TODO: Check and add all vendored dependencies, e.g. "webview"
+};
+
+const DebugDependencies = std.EnumSet(Dependency);
+
+pub fn build(b: *Build) !void {
+ const target = b.standardTargetOptions(.{});
+ const optimize = b.standardOptimizeOption(.{});
+
+ const is_dynamic = b.option(bool, "dynamic", "build the dynamic library") orelse false;
+ const enable_tls = b.option(bool, "enable-tls", "enable TLS support") orelse false;
+ const enable_webui_log = b.option(bool, "enable-webui-log", "Enable WebUI log output") orelse false;
+ const verbose = b.option(std.log.Level, "verbose", "set verbose output") orelse .warn;
+ global_log_level = verbose;
+ // TODO: Support list of dependencies once support is limited to >0.13.0
+ const debug = b.option(Dependency, "debug", "enable dependency debug output");
+ const debug_dependencies = DebugDependencies.initMany(if (debug) |d| &.{d} else &.{});
+
+ if (enable_tls and !target.query.isNative()) {
+ log(.err, .WebUI, "cross compilation is not supported with TLS enabled", .{});
+ return error.InvalidBuildConfiguration;
+ }
+
+ log(.info, .WebUI, "Building {s} WebUI library{s}...", .{
+ if (is_dynamic) "dynamic" else "static",
+ if (enable_tls) " with TLS support" else "",
+ });
+ defer {
+ log(.info, .WebUI, "Done.", .{});
+ }
+
+ const webui = if (builtin.zig_version.minor == 14) (if (is_dynamic) b.addSharedLibrary(.{
+ .name = lib_name,
+ .target = target,
+ .optimize = optimize,
+ .pic = true,
+ }) else b.addStaticLibrary(.{
+ .name = lib_name,
+ .target = target,
+ .optimize = optimize,
+ })) else b.addLibrary(.{
+ .name = lib_name,
+ .linkage = if (is_dynamic) .dynamic else .static,
+ .root_module = b.createModule(.{
+ // not, pic enabled, zig will not allow to build a static library
+ // .pic = is_dynamic,
+ .pic = if (is_dynamic) is_dynamic else true,
+ .target = target,
+ .optimize = optimize,
+ }),
+ });
+
+ try addLinkerFlags(b, webui, enable_tls, debug_dependencies, enable_webui_log);
+
+ b.installArtifact(webui);
+
+ try build_examples(b, webui);
+}
+
+fn addLinkerFlags(
+ b: *Build,
+ webui: *Compile,
+ enable_tls: bool,
+ debug_dependencies: DebugDependencies,
+ enable_webui_log: bool,
+) !void {
+ const webui_target = webui.rootModuleTarget();
+ const is_windows = webui_target.os.tag == .windows;
+ const is_darwin = webui_target.os.tag == .macos;
+ const debug = webui.root_module.optimize.? == .Debug;
+
+ // Prepare compiler flags.
+ const no_tls_flags: []const []const u8 = &.{"-DNO_SSL"};
+ const tls_flags: []const []const u8 = &.{ "-DWEBUI_TLS", "-DNO_SSL_DL", "-DOPENSSL_API_1_1" };
+ const civetweb_flags: []const []const u8 = &.{
+ "-DNO_CACHING",
+ "-DNO_CGI",
+ "-DUSE_WEBSOCKET",
+ "-Wno-error=date-time",
+ };
+
+ if (debug and enable_webui_log) {
+ webui.root_module.addCMacro("WEBUI_LOG", "");
+ }
+ webui.addCSourceFile(.{
+ .file = b.path("src/webui.c"),
+ .flags = if (enable_tls) tls_flags else no_tls_flags,
+ });
+
+ // Add Win32 WebView2 C++ support on Windows
+ if (is_windows) {
+ webui.addCSourceFile(.{
+ .file = b.path("src/webview/win32_wv2.cpp"),
+ .flags = if (enable_tls) tls_flags else no_tls_flags,
+ });
+ webui.linkLibCpp();
+ }
+
+ const civetweb_debug = debug and debug_dependencies.contains(.civetweb);
+ webui.addCSourceFile(.{
+ .file = b.path("src/civetweb/civetweb.c"),
+ .flags = if (enable_tls and !civetweb_debug)
+ civetweb_flags ++ tls_flags ++ .{"-DNDEBUG"}
+ else if (enable_tls and civetweb_debug)
+ civetweb_flags ++ tls_flags
+ else if (!enable_tls and !civetweb_debug)
+ civetweb_flags ++ .{"-DUSE_WEBSOCKET"} ++ no_tls_flags ++ .{"-DNDEBUG"}
+ else
+ civetweb_flags ++ .{"-DUSE_WEBSOCKET"} ++ no_tls_flags,
+ });
+ webui.linkLibC();
+ webui.addIncludePath(b.path("include"));
+ webui.installHeader(b.path("include/webui.h"), "webui.h");
+ if (is_darwin) {
+ webui.addCSourceFile(.{
+ .file = b.path("src/webview/wkwebview.m"),
+ .flags = &.{},
+ });
+ webui.linkFramework("Cocoa");
+ webui.linkFramework("WebKit");
+ } else if (is_windows) {
+ webui.linkSystemLibrary("ws2_32");
+ webui.linkSystemLibrary("ole32");
+ if (webui_target.abi == .msvc) {
+ webui.linkSystemLibrary("Advapi32");
+ webui.linkSystemLibrary("Shell32");
+ webui.linkSystemLibrary("user32");
+ }
+ if (enable_tls) {
+ webui.linkSystemLibrary("bcrypt");
+ }
+ }
+ if (enable_tls) {
+ webui.linkSystemLibrary("ssl");
+ webui.linkSystemLibrary("crypto");
+ }
+
+ for (webui.root_module.link_objects.items) |lo| {
+ switch (lo) {
+ .c_source_file => |csf| {
+ log(.debug, .WebUI, "{s} linker flags:\n", .{
+ csf.file.src_path.sub_path,
+ });
+ for (csf.flags) |flag| {
+ log(.debug, .WebUI, " {s}", .{flag});
+ }
+ },
+ else => {},
+ }
+ }
+}
+
+fn build_examples(b: *Build, webui: *Compile) !void {
+ const build_examples_step = b.step("examples", "builds the library and its examples");
+ const target = webui.root_module.resolved_target.?;
+ const optimize = webui.root_module.optimize.?;
+
+ const examples_path = b.path("examples/C").getPath(b);
+ var examples_dir = std.fs.cwd().openDir(
+ examples_path,
+ .{ .iterate = true },
+ ) catch |e| switch (e) {
+ // Do not attempt building examples if directory does not exist.
+ error.FileNotFound => return,
+ else => return e,
+ };
+ defer examples_dir.close();
+
+ var paths = examples_dir.iterate();
+ while (try paths.next()) |val| {
+ if (val.kind != .directory) {
+ continue;
+ }
+ const example_name = val.name;
+
+ const exe = b.addExecutable(if (builtin.zig_version.minor == 14) .{
+ .name = example_name,
+ .target = target,
+ .optimize = optimize,
+ } else .{
+ .name = example_name,
+ .root_module = b.createModule(.{
+ .target = target,
+ .optimize = optimize,
+ .pic = true,
+ }),
+ });
+ const path = try std.fmt.allocPrint(b.allocator, "examples/C/{s}/main.c", .{example_name});
+ defer b.allocator.free(path);
+
+ exe.addCSourceFile(.{ .file = b.path(path), .flags = &.{} });
+ exe.linkLibrary(webui);
+
+ const exe_install = b.addInstallArtifact(exe, .{});
+ const exe_run = b.addRunArtifact(exe);
+ const step_name = try std.fmt.allocPrint(b.allocator, "run_{s}", .{example_name});
+ defer b.allocator.free(step_name);
+ const step_desc = try std.fmt.allocPrint(b.allocator, "run example {s}", .{example_name});
+ defer b.allocator.free(step_desc);
+
+ const cwd = try std.fmt.allocPrint(b.allocator, "src/examples/{s}", .{example_name});
+ defer b.allocator.free(cwd);
+ exe_run.setCwd(b.path(cwd));
+
+ exe_run.step.dependOn(&exe_install.step);
+ build_examples_step.dependOn(&exe_install.step);
+ b.step(step_name, step_desc).dependOn(&exe_run.step);
+ }
+}
+
+/// Function to runtime-scope log levels based on build flag, for all scopes.
+fn log(
+ comptime level: std.log.Level,
+ comptime scope: @TypeOf(.EnumLiteral),
+ comptime format: []const u8,
+ args: anytype,
+) void {
+ const should_print: bool = @intFromEnum(global_log_level) >= @intFromEnum(level);
+ if (should_print) {
+ switch (comptime level) {
+ .err => std.log.scoped(scope).err(format, args),
+ .warn => std.log.scoped(scope).warn(format, args),
+ .info => std.log.scoped(scope).info(format, args),
+ .debug => std.log.scoped(scope).debug(format, args),
+ }
+ }
+}
diff --git a/build.zig.zon b/build.zig.zon
new file mode 100644
index 0000000..0b80789
--- /dev/null
+++ b/build.zig.zon
@@ -0,0 +1,14 @@
+.{
+ .name = .webui,
+ .version = "2.5.0-beta.4",
+ .fingerprint = 0xac5d87f2e5831aa7,
+ .paths = .{
+ "src",
+ "include",
+ "bridge",
+ "build.zig",
+ "build.zig.zon",
+ "LICENSE",
+ "README.md",
+ },
+}
diff --git a/conanfile.py b/conanfile.py
new file mode 100644
index 0000000..f7e88b3
--- /dev/null
+++ b/conanfile.py
@@ -0,0 +1,33 @@
+from conan import ConanFile
+from conan.tools.cmake import CMake, CMakeToolchain
+
+class WebuiConan(ConanFile):
+ name = "webui"
+ version = "2.5.0-beta.4"
+ license = "MIT"
+ url = "https://github.com/webui-dev/webui"
+ homepage = "https://webui.me"
+ description = "Use any web browser or WebView as GUI, with your preferred language in the backend and modern web technologies in the frontend, all in a lightweight portable library."
+
+ settings = "os", "compiler", "build_type", "arch"
+ options = {"tls": [True, False], "shared": [True, False]}
+ default_options = {"tls": False, "shared": False}
+
+ generators = "CMakeDeps"
+
+ def generate(self):
+ tc = CMakeToolchain(self)
+ tc.variables["WEBUI_USE_TLS"] = self.options.tls
+ tc.variables["BUILD_SHARED_LIBS"] = self.options.shared
+ tc.generate()
+
+ def build(self):
+ cmake = CMake(self)
+ cmake.configure()
+ cmake.build()
+
+ def requirements(self):
+ self.tool_requires("cmake/[>=3.18.0]")
+
+ if self.options.tls:
+ self.requires("openssl/[>3.0.0]")
\ No newline at end of file
diff --git a/examples/C++/README.md b/examples/C++/README.md
new file mode 100644
index 0000000..cd7aab0
--- /dev/null
+++ b/examples/C++/README.md
@@ -0,0 +1,39 @@
+# WebUI C++ Examples
+
+Examples of how to create a WebUI application in C++.
+
+The only requirement to build the examples is a a C++11 compiler.
+
+- `minimal`: Creates a minimal WebUI application.
+- `call_cpp_from_js`: Calls C++ from JavaScript.
+- `call_js_from_cpp`: Calls JavaScript from C++ using class methods and member-function bind.
+- `serve_a_folder`: Uses WebUI to serve a folder with multiple files (class-based example using member-function bind).
+- `virtual_file_system`: Embeds files using a virtual file system.
+- `test_index_redirect`: Tests index fallback and custom entry behavior for `/`, `/sub`, and `/sub/foo`.
+
+To build an example, cd into its directory and run the make command.
+
+- **Windows**
+
+ ```sh
+ # G++
+ mingw32-make
+
+ # MSVC
+ nmake
+ ```
+
+- **Linux**
+
+ ```sh
+ # G++
+ make
+
+ # Clang
+ make CXX=clang
+ ```
+
+- **macOS**
+ ```sh
+ make
+ ```
diff --git a/examples/C++/call_cpp_from_js/GNUmakefile b/examples/C++/call_cpp_from_js/GNUmakefile
new file mode 100644
index 0000000..2b085f5
--- /dev/null
+++ b/examples/C++/call_cpp_from_js/GNUmakefile
@@ -0,0 +1,138 @@
+# WebUI C++ Example
+
+# == 1. VARIABLES =============================================================
+
+MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
+PROJECT_DIR := $(dir $(MAKEFILE_PATH))/../../../
+TARGET := $(firstword $(MAKECMDGOALS))
+LIB_DIR := $(PROJECT_DIR)/dist
+ifeq ($(TARGET), debug)
+LIB_DIR := $(LIB_DIR)/debug
+endif
+INCLUDE_DIR := $(PROJECT_DIR)/include
+WEBUI_LIB_NAME = webui-2
+ifeq ($(WEBUI_USE_TLS), 1)
+WEBUI_LIB_NAME = webui-2-secure
+endif
+
+# ARGS
+# Set a compiler when running on Linux via `make CC=g++` / `make CC=clang`
+CC = g++
+# Build the WebUI library if running via `make BUILD_LIB=true`
+BUILD_LIB ?=
+
+# BUILD FLAGS
+STATIC_BUILD_FLAGS = main.cpp -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+DYN_BUILD_FLAGS = main.cpp -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+
+# Platform conditions
+ifeq ($(OS),Windows_NT)
+ # Windows
+ PLATFORM := windows
+ SHELL := CMD
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lws2_32 -Wall -luser32 -lstdc++ -luuid -static
+ COPY_LIB_CMD := @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ DYN_BUILD_FLAGS += "$(WEBUI_LIB_NAME).dll" -lws2_32 -Wall -luser32 -lstdc++ -luuid
+ STATIC_OUT := main.exe
+ DYN_OUT := main-dyn.exe
+ LWS2_OPT := -lws2_32 -lole32
+ STRIP_OPT := --strip-all
+ CONSOLE_APP := -Wl,-subsystem=console
+ GUI_APP := -Wl,-subsystem=windows
+else
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lpthread -lm -ldl
+ DYN_BUILD_FLAGS += -l$(WEBUI_LIB_NAME) -lpthread -lm -ldl
+ STATIC_OUT := main
+ DYN_OUT := main-dyn
+ ifeq ($(shell uname),Darwin)
+ # MacOS
+ PLATFORM := macos
+ CC = clang
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).dylib" "lib$(WEBUI_LIB_NAME).dylib"
+ WKWEBKIT_LINK_FLAGS := -framework Cocoa -framework WebKit
+ else
+ # Linux
+ PLATFORM := linux
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).so" "lib$(WEBUI_LIB_NAME).so"
+ STRIP_OPT := --strip-all
+ ifeq ($(CC),clang)
+ LLVM_OPT := llvm-
+ endif
+ endif
+endif
+
+# == 2.TARGETS ================================================================
+
+all: release
+
+debug: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE) debug
+endif
+# Static with Debug info
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C++ Example ($(CC) debug static)..."
+ @$(CC) -g $(CONSOLE_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+endif
+# Dynamic with Debug info
+ @echo "Build C++ Example ($(CC) debug dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) -g $(CONSOLE_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+release: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE)
+endif
+# Static Release
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C++ Example ($(CC) release static)..."
+ @$(CC) -Os $(GUI_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(STATIC_OUT)
+endif
+# Dynamic Release
+ @echo "Build C++ Example ($(CC) release dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) $(GUI_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+clean: --clean-$(PLATFORM)
+
+# INTERNAL TARGETS
+
+--validate-args:
+ifneq ($(filter $(CC),g++ clang aarch64-linux-gnu-g++ arm-linux-gnueabihf-g++ musl-g++),$(CC))
+$(error Invalid compiler specified: `$(CC)`)
+endif
+
+--clean-linux: --clean-unix
+
+--clean-macos: --clean-unix
+
+--clean-unix:
+ - rm -f *.o
+ - rm -f *.a
+ - rm -f *.so
+ - rm -f *.dylib
+ - rm -rf *.dSYM
+
+--clean-windows:
+ - del *.o >nul 2>&1
+ - del *.dll >nul 2>&1
+ - del *.a >nul 2>&1
+ - del *.exe >nul 2>&1
diff --git a/examples/C++/call_cpp_from_js/Makefile b/examples/C++/call_cpp_from_js/Makefile
new file mode 100644
index 0000000..d056ecd
--- /dev/null
+++ b/examples/C++/call_cpp_from_js/Makefile
@@ -0,0 +1,65 @@
+# WebUI C++ Example
+# Windows - Microsoft Visual C++
+
+SHELL = CMD
+LIB_DIR = ../../../dist
+INCLUDE_DIR = ../../../include
+WEBUI_LIB_NAME = webui-2
+!IF "$(WEBUI_USE_TLS)" == "1"
+WEBUI_LIB_NAME = webui-2-secure
+!ENDIF
+
+# Build the WebUI library if running `nmake BUILD_LIB=true`
+BUILD_LIB =
+
+all: release
+
+debug:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE) debug
+!ENDIF
+# Static with Debug info
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C++ Example (Debug Static)...
+ @cl /Zi /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)/debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic with Debug info
+ @echo Build C++ Example (Debug Dynamic)...
+ @copy "$(LIB_DIR)\debug\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /Zi /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)/debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+release:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE)
+!ENDIF
+# Static Release
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C++ Example (Release Static)...
+ @cl /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic Release
+ @echo Build C++ Example (Release Dynamic)...
+ @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+clean:
+ - del *.obj >nul 2>&1
+ - del *.ilk >nul 2>&1
+ - del *.pdb >nul 2>&1
+ - del *.exp >nul 2>&1
+ - del *.exe >nul 2>&1
+ - del *.lib >nul 2>&1
diff --git a/examples/C++/call_cpp_from_js/main.cpp b/examples/C++/call_cpp_from_js/main.cpp
new file mode 100644
index 0000000..063862d
--- /dev/null
+++ b/examples/C++/call_cpp_from_js/main.cpp
@@ -0,0 +1,118 @@
+// Call C++ from JavaScript Example
+
+#include "webui.hpp"
+#include
+
+class CallCppFromJsApp {
+public:
+ CallCppFromJsApp() {
+ // Bind HTML element IDs with class methods
+ win.bind("my_function_string", this, &CallCppFromJsApp::my_function_string);
+ win.bind("my_function_integer", this, &CallCppFromJsApp::my_function_integer);
+ win.bind("my_function_boolean", this, &CallCppFromJsApp::my_function_boolean);
+ win.bind("my_function_with_response", this, &CallCppFromJsApp::my_function_with_response);
+ }
+
+ void run() {
+ const std::string html = R"V0G0N(
+
+
+
+
+ Call C++ from JavaScript Example
+
+
+
+ WebUI - Call C++ from JavaScript
+ Call C++ functions with arguments (See the logs in your terminal )
+ Call my_function_string()
+
+ Call my_function_integer()
+
+ Call my_function_boolean()
+
+ Call a C++ function that returns a response
+ Call my_function_with_response()
+ Double:
+
+
+
+ )V0G0N";
+
+ // Show the HTML page in the WebView/Browser window
+ win.show(html);
+ // win.show_browser(html, webui_browser::Chrome);
+ // win.show_wv(html);
+
+ // Wait until the window gets closed
+ webui::wait();
+ }
+
+private:
+ webui::window win;
+
+ void my_function_string(webui::window::event* e) {
+ // JavaScript: my_function_string('Hello', 'World');
+ std::string str_1 = e->get_string(); // Or e->get_string(0);
+ std::string str_2 = e->get_string(1);
+ std::cout << "my_function_string 1: " << str_1 << std::endl; // Hello
+ std::cout << "my_function_string 2: " << str_2 << std::endl; // World
+ }
+
+ void my_function_integer(webui::window::event* e) {
+ // JavaScript: my_function_integer(123, 456, 789);
+ long long number_1 = e->get_int(); // Or e->get_int(0);
+ long long number_2 = e->get_int(1);
+ long long number_3 = e->get_int(2);
+ std::cout << "my_function_integer 1: " << number_1 << std::endl; // 123
+ std::cout << "my_function_integer 2: " << number_2 << std::endl; // 456
+ std::cout << "my_function_integer 3: " << number_3 << std::endl; // 789
+ }
+
+ void my_function_boolean(webui::window::event* e) {
+ // JavaScript: my_function_boolean(true, false);
+ bool status_1 = e->get_bool(); // Or e->get_bool(0);
+ bool status_2 = e->get_bool(1);
+ std::cout << "my_function_boolean 1: " << (status_1 ? "True" : "False") << std::endl;
+ std::cout << "my_function_boolean 2: " << (status_2 ? "True" : "False") << std::endl;
+ }
+
+ void my_function_with_response(webui::window::event* e) {
+ // JavaScript: my_function_with_response(number, 2).then(...)
+ long long number = e->get_int(0);
+ long long times = e->get_int(1);
+ long long res = number * times;
+ std::cout << "my_function_with_response: " << number << " * " << times << " = " << res << std::endl;
+ // Send the response back to JavaScript
+ e->return_int(res);
+ }
+};
+
+int main() {
+ CallCppFromJsApp app;
+ app.run();
+ return 0;
+}
+
+#if defined(_MSC_VER)
+int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) { return main(); }
+#endif
diff --git a/examples/C++/call_js_from_cpp/GNUmakefile b/examples/C++/call_js_from_cpp/GNUmakefile
new file mode 100644
index 0000000..2b085f5
--- /dev/null
+++ b/examples/C++/call_js_from_cpp/GNUmakefile
@@ -0,0 +1,138 @@
+# WebUI C++ Example
+
+# == 1. VARIABLES =============================================================
+
+MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
+PROJECT_DIR := $(dir $(MAKEFILE_PATH))/../../../
+TARGET := $(firstword $(MAKECMDGOALS))
+LIB_DIR := $(PROJECT_DIR)/dist
+ifeq ($(TARGET), debug)
+LIB_DIR := $(LIB_DIR)/debug
+endif
+INCLUDE_DIR := $(PROJECT_DIR)/include
+WEBUI_LIB_NAME = webui-2
+ifeq ($(WEBUI_USE_TLS), 1)
+WEBUI_LIB_NAME = webui-2-secure
+endif
+
+# ARGS
+# Set a compiler when running on Linux via `make CC=g++` / `make CC=clang`
+CC = g++
+# Build the WebUI library if running via `make BUILD_LIB=true`
+BUILD_LIB ?=
+
+# BUILD FLAGS
+STATIC_BUILD_FLAGS = main.cpp -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+DYN_BUILD_FLAGS = main.cpp -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+
+# Platform conditions
+ifeq ($(OS),Windows_NT)
+ # Windows
+ PLATFORM := windows
+ SHELL := CMD
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lws2_32 -Wall -luser32 -lstdc++ -luuid -static
+ COPY_LIB_CMD := @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ DYN_BUILD_FLAGS += "$(WEBUI_LIB_NAME).dll" -lws2_32 -Wall -luser32 -lstdc++ -luuid
+ STATIC_OUT := main.exe
+ DYN_OUT := main-dyn.exe
+ LWS2_OPT := -lws2_32 -lole32
+ STRIP_OPT := --strip-all
+ CONSOLE_APP := -Wl,-subsystem=console
+ GUI_APP := -Wl,-subsystem=windows
+else
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lpthread -lm -ldl
+ DYN_BUILD_FLAGS += -l$(WEBUI_LIB_NAME) -lpthread -lm -ldl
+ STATIC_OUT := main
+ DYN_OUT := main-dyn
+ ifeq ($(shell uname),Darwin)
+ # MacOS
+ PLATFORM := macos
+ CC = clang
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).dylib" "lib$(WEBUI_LIB_NAME).dylib"
+ WKWEBKIT_LINK_FLAGS := -framework Cocoa -framework WebKit
+ else
+ # Linux
+ PLATFORM := linux
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).so" "lib$(WEBUI_LIB_NAME).so"
+ STRIP_OPT := --strip-all
+ ifeq ($(CC),clang)
+ LLVM_OPT := llvm-
+ endif
+ endif
+endif
+
+# == 2.TARGETS ================================================================
+
+all: release
+
+debug: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE) debug
+endif
+# Static with Debug info
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C++ Example ($(CC) debug static)..."
+ @$(CC) -g $(CONSOLE_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+endif
+# Dynamic with Debug info
+ @echo "Build C++ Example ($(CC) debug dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) -g $(CONSOLE_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+release: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE)
+endif
+# Static Release
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C++ Example ($(CC) release static)..."
+ @$(CC) -Os $(GUI_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(STATIC_OUT)
+endif
+# Dynamic Release
+ @echo "Build C++ Example ($(CC) release dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) $(GUI_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+clean: --clean-$(PLATFORM)
+
+# INTERNAL TARGETS
+
+--validate-args:
+ifneq ($(filter $(CC),g++ clang aarch64-linux-gnu-g++ arm-linux-gnueabihf-g++ musl-g++),$(CC))
+$(error Invalid compiler specified: `$(CC)`)
+endif
+
+--clean-linux: --clean-unix
+
+--clean-macos: --clean-unix
+
+--clean-unix:
+ - rm -f *.o
+ - rm -f *.a
+ - rm -f *.so
+ - rm -f *.dylib
+ - rm -rf *.dSYM
+
+--clean-windows:
+ - del *.o >nul 2>&1
+ - del *.dll >nul 2>&1
+ - del *.a >nul 2>&1
+ - del *.exe >nul 2>&1
diff --git a/examples/C++/call_js_from_cpp/Makefile b/examples/C++/call_js_from_cpp/Makefile
new file mode 100644
index 0000000..d056ecd
--- /dev/null
+++ b/examples/C++/call_js_from_cpp/Makefile
@@ -0,0 +1,65 @@
+# WebUI C++ Example
+# Windows - Microsoft Visual C++
+
+SHELL = CMD
+LIB_DIR = ../../../dist
+INCLUDE_DIR = ../../../include
+WEBUI_LIB_NAME = webui-2
+!IF "$(WEBUI_USE_TLS)" == "1"
+WEBUI_LIB_NAME = webui-2-secure
+!ENDIF
+
+# Build the WebUI library if running `nmake BUILD_LIB=true`
+BUILD_LIB =
+
+all: release
+
+debug:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE) debug
+!ENDIF
+# Static with Debug info
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C++ Example (Debug Static)...
+ @cl /Zi /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)/debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic with Debug info
+ @echo Build C++ Example (Debug Dynamic)...
+ @copy "$(LIB_DIR)\debug\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /Zi /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)/debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+release:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE)
+!ENDIF
+# Static Release
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C++ Example (Release Static)...
+ @cl /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic Release
+ @echo Build C++ Example (Release Dynamic)...
+ @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+clean:
+ - del *.obj >nul 2>&1
+ - del *.ilk >nul 2>&1
+ - del *.pdb >nul 2>&1
+ - del *.exp >nul 2>&1
+ - del *.exe >nul 2>&1
+ - del *.lib >nul 2>&1
diff --git a/examples/C++/call_js_from_cpp/main.cpp b/examples/C++/call_js_from_cpp/main.cpp
new file mode 100644
index 0000000..d089ade
--- /dev/null
+++ b/examples/C++/call_js_from_cpp/main.cpp
@@ -0,0 +1,124 @@
+// Call JavaScript from C++ Example
+
+#include "webui.hpp"
+#include
+#include
+#include
+
+class CounterApp {
+public:
+ CounterApp() {
+ // Bind HTML element IDs with class methods
+ win.bind("my_function_count", this, &CounterApp::my_function_count);
+ win.bind("Exit", this, &CounterApp::exit_app);
+ }
+
+ void run() {
+ const std::string html = R"V0G0N(
+
+
+
+
+ Call JavaScript from C++ Example
+
+
+
+ WebUI - Call JavaScript from C++
+
+ 0
+
+ Manual Count
+
+ Auto Count (Every 10ms)
+
+ Exit
+
+
+
+ )V0G0N";
+
+ // Set WebUI configuration to process UI events one at a time.
+ // This example calls C++ from JavaScript every 10ms, so it's
+ // recommended to set this to `true` to avoid race conditions.
+ webui::set_config(ui_event_blocking, true);
+
+ // Show the HTML page in the WebView/Browser window
+ win.show(html);
+ // win.show_browser(html, webui_browser::Chrome);
+ // win.show_wv(html);
+
+ // Wait until the window gets closed
+ webui::wait();
+ }
+
+private:
+ webui::window win;
+
+ void my_function_count(webui::window::event* e) {
+ // Create a buffer to hold the response
+ char response[64];
+
+ // Run JavaScript to get the current count value from the HTML page
+ if (!e->get_window().script("return GetCount();", 0, response, 64)) {
+ if (!e->get_window().is_shown())
+ std::cout << "Window closed." << std::endl;
+ else
+ std::cout << "JavaScript Error: " << response << std::endl;
+ return;
+ }
+
+ // Get the count, increment, and send it back
+ int count = std::stoi(response) + 1;
+ std::stringstream js;
+ js << "SetCount(" << count << ");";
+ // Run JavaScript (no response) to update the count in the HTML page
+ e->get_window().run(js.str());
+ }
+
+ void exit_app(webui::window::event* e) {
+ // Exit the application, and close all windows. `webui::wait()` will return (Break).
+ webui::exit();
+ }
+};
+
+int main() {
+ CounterApp app;
+ app.run();
+ return 0;
+}
+
+#if defined(_MSC_VER)
+int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) { return main(); }
+#endif
diff --git a/examples/C++/minimal/GNUmakefile b/examples/C++/minimal/GNUmakefile
new file mode 100644
index 0000000..2b085f5
--- /dev/null
+++ b/examples/C++/minimal/GNUmakefile
@@ -0,0 +1,138 @@
+# WebUI C++ Example
+
+# == 1. VARIABLES =============================================================
+
+MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
+PROJECT_DIR := $(dir $(MAKEFILE_PATH))/../../../
+TARGET := $(firstword $(MAKECMDGOALS))
+LIB_DIR := $(PROJECT_DIR)/dist
+ifeq ($(TARGET), debug)
+LIB_DIR := $(LIB_DIR)/debug
+endif
+INCLUDE_DIR := $(PROJECT_DIR)/include
+WEBUI_LIB_NAME = webui-2
+ifeq ($(WEBUI_USE_TLS), 1)
+WEBUI_LIB_NAME = webui-2-secure
+endif
+
+# ARGS
+# Set a compiler when running on Linux via `make CC=g++` / `make CC=clang`
+CC = g++
+# Build the WebUI library if running via `make BUILD_LIB=true`
+BUILD_LIB ?=
+
+# BUILD FLAGS
+STATIC_BUILD_FLAGS = main.cpp -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+DYN_BUILD_FLAGS = main.cpp -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+
+# Platform conditions
+ifeq ($(OS),Windows_NT)
+ # Windows
+ PLATFORM := windows
+ SHELL := CMD
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lws2_32 -Wall -luser32 -lstdc++ -luuid -static
+ COPY_LIB_CMD := @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ DYN_BUILD_FLAGS += "$(WEBUI_LIB_NAME).dll" -lws2_32 -Wall -luser32 -lstdc++ -luuid
+ STATIC_OUT := main.exe
+ DYN_OUT := main-dyn.exe
+ LWS2_OPT := -lws2_32 -lole32
+ STRIP_OPT := --strip-all
+ CONSOLE_APP := -Wl,-subsystem=console
+ GUI_APP := -Wl,-subsystem=windows
+else
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lpthread -lm -ldl
+ DYN_BUILD_FLAGS += -l$(WEBUI_LIB_NAME) -lpthread -lm -ldl
+ STATIC_OUT := main
+ DYN_OUT := main-dyn
+ ifeq ($(shell uname),Darwin)
+ # MacOS
+ PLATFORM := macos
+ CC = clang
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).dylib" "lib$(WEBUI_LIB_NAME).dylib"
+ WKWEBKIT_LINK_FLAGS := -framework Cocoa -framework WebKit
+ else
+ # Linux
+ PLATFORM := linux
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).so" "lib$(WEBUI_LIB_NAME).so"
+ STRIP_OPT := --strip-all
+ ifeq ($(CC),clang)
+ LLVM_OPT := llvm-
+ endif
+ endif
+endif
+
+# == 2.TARGETS ================================================================
+
+all: release
+
+debug: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE) debug
+endif
+# Static with Debug info
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C++ Example ($(CC) debug static)..."
+ @$(CC) -g $(CONSOLE_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+endif
+# Dynamic with Debug info
+ @echo "Build C++ Example ($(CC) debug dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) -g $(CONSOLE_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+release: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE)
+endif
+# Static Release
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C++ Example ($(CC) release static)..."
+ @$(CC) -Os $(GUI_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(STATIC_OUT)
+endif
+# Dynamic Release
+ @echo "Build C++ Example ($(CC) release dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) $(GUI_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+clean: --clean-$(PLATFORM)
+
+# INTERNAL TARGETS
+
+--validate-args:
+ifneq ($(filter $(CC),g++ clang aarch64-linux-gnu-g++ arm-linux-gnueabihf-g++ musl-g++),$(CC))
+$(error Invalid compiler specified: `$(CC)`)
+endif
+
+--clean-linux: --clean-unix
+
+--clean-macos: --clean-unix
+
+--clean-unix:
+ - rm -f *.o
+ - rm -f *.a
+ - rm -f *.so
+ - rm -f *.dylib
+ - rm -rf *.dSYM
+
+--clean-windows:
+ - del *.o >nul 2>&1
+ - del *.dll >nul 2>&1
+ - del *.a >nul 2>&1
+ - del *.exe >nul 2>&1
diff --git a/examples/C++/minimal/Makefile b/examples/C++/minimal/Makefile
new file mode 100644
index 0000000..d056ecd
--- /dev/null
+++ b/examples/C++/minimal/Makefile
@@ -0,0 +1,65 @@
+# WebUI C++ Example
+# Windows - Microsoft Visual C++
+
+SHELL = CMD
+LIB_DIR = ../../../dist
+INCLUDE_DIR = ../../../include
+WEBUI_LIB_NAME = webui-2
+!IF "$(WEBUI_USE_TLS)" == "1"
+WEBUI_LIB_NAME = webui-2-secure
+!ENDIF
+
+# Build the WebUI library if running `nmake BUILD_LIB=true`
+BUILD_LIB =
+
+all: release
+
+debug:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE) debug
+!ENDIF
+# Static with Debug info
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C++ Example (Debug Static)...
+ @cl /Zi /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)/debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic with Debug info
+ @echo Build C++ Example (Debug Dynamic)...
+ @copy "$(LIB_DIR)\debug\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /Zi /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)/debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+release:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE)
+!ENDIF
+# Static Release
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C++ Example (Release Static)...
+ @cl /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic Release
+ @echo Build C++ Example (Release Dynamic)...
+ @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+clean:
+ - del *.obj >nul 2>&1
+ - del *.ilk >nul 2>&1
+ - del *.pdb >nul 2>&1
+ - del *.exp >nul 2>&1
+ - del *.exe >nul 2>&1
+ - del *.lib >nul 2>&1
diff --git a/examples/C++/minimal/main.cpp b/examples/C++/minimal/main.cpp
new file mode 100644
index 0000000..34f159d
--- /dev/null
+++ b/examples/C++/minimal/main.cpp
@@ -0,0 +1,13 @@
+#include "webui.hpp"
+#include
+
+int main() {
+ webui::window my_window;
+ my_window.show(" C++ Hello World ! ");
+ webui::wait();
+ return 0;
+}
+
+#ifdef _WIN32
+int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) { return main(); }
+#endif
diff --git a/examples/C++/serve_a_folder/GNUmakefile b/examples/C++/serve_a_folder/GNUmakefile
new file mode 100644
index 0000000..2b085f5
--- /dev/null
+++ b/examples/C++/serve_a_folder/GNUmakefile
@@ -0,0 +1,138 @@
+# WebUI C++ Example
+
+# == 1. VARIABLES =============================================================
+
+MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
+PROJECT_DIR := $(dir $(MAKEFILE_PATH))/../../../
+TARGET := $(firstword $(MAKECMDGOALS))
+LIB_DIR := $(PROJECT_DIR)/dist
+ifeq ($(TARGET), debug)
+LIB_DIR := $(LIB_DIR)/debug
+endif
+INCLUDE_DIR := $(PROJECT_DIR)/include
+WEBUI_LIB_NAME = webui-2
+ifeq ($(WEBUI_USE_TLS), 1)
+WEBUI_LIB_NAME = webui-2-secure
+endif
+
+# ARGS
+# Set a compiler when running on Linux via `make CC=g++` / `make CC=clang`
+CC = g++
+# Build the WebUI library if running via `make BUILD_LIB=true`
+BUILD_LIB ?=
+
+# BUILD FLAGS
+STATIC_BUILD_FLAGS = main.cpp -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+DYN_BUILD_FLAGS = main.cpp -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+
+# Platform conditions
+ifeq ($(OS),Windows_NT)
+ # Windows
+ PLATFORM := windows
+ SHELL := CMD
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lws2_32 -Wall -luser32 -lstdc++ -luuid -static
+ COPY_LIB_CMD := @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ DYN_BUILD_FLAGS += "$(WEBUI_LIB_NAME).dll" -lws2_32 -Wall -luser32 -lstdc++ -luuid
+ STATIC_OUT := main.exe
+ DYN_OUT := main-dyn.exe
+ LWS2_OPT := -lws2_32 -lole32
+ STRIP_OPT := --strip-all
+ CONSOLE_APP := -Wl,-subsystem=console
+ GUI_APP := -Wl,-subsystem=windows
+else
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lpthread -lm -ldl
+ DYN_BUILD_FLAGS += -l$(WEBUI_LIB_NAME) -lpthread -lm -ldl
+ STATIC_OUT := main
+ DYN_OUT := main-dyn
+ ifeq ($(shell uname),Darwin)
+ # MacOS
+ PLATFORM := macos
+ CC = clang
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).dylib" "lib$(WEBUI_LIB_NAME).dylib"
+ WKWEBKIT_LINK_FLAGS := -framework Cocoa -framework WebKit
+ else
+ # Linux
+ PLATFORM := linux
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).so" "lib$(WEBUI_LIB_NAME).so"
+ STRIP_OPT := --strip-all
+ ifeq ($(CC),clang)
+ LLVM_OPT := llvm-
+ endif
+ endif
+endif
+
+# == 2.TARGETS ================================================================
+
+all: release
+
+debug: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE) debug
+endif
+# Static with Debug info
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C++ Example ($(CC) debug static)..."
+ @$(CC) -g $(CONSOLE_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+endif
+# Dynamic with Debug info
+ @echo "Build C++ Example ($(CC) debug dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) -g $(CONSOLE_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+release: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE)
+endif
+# Static Release
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C++ Example ($(CC) release static)..."
+ @$(CC) -Os $(GUI_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(STATIC_OUT)
+endif
+# Dynamic Release
+ @echo "Build C++ Example ($(CC) release dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) $(GUI_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+clean: --clean-$(PLATFORM)
+
+# INTERNAL TARGETS
+
+--validate-args:
+ifneq ($(filter $(CC),g++ clang aarch64-linux-gnu-g++ arm-linux-gnueabihf-g++ musl-g++),$(CC))
+$(error Invalid compiler specified: `$(CC)`)
+endif
+
+--clean-linux: --clean-unix
+
+--clean-macos: --clean-unix
+
+--clean-unix:
+ - rm -f *.o
+ - rm -f *.a
+ - rm -f *.so
+ - rm -f *.dylib
+ - rm -rf *.dSYM
+
+--clean-windows:
+ - del *.o >nul 2>&1
+ - del *.dll >nul 2>&1
+ - del *.a >nul 2>&1
+ - del *.exe >nul 2>&1
diff --git a/examples/C++/serve_a_folder/Makefile b/examples/C++/serve_a_folder/Makefile
new file mode 100644
index 0000000..d056ecd
--- /dev/null
+++ b/examples/C++/serve_a_folder/Makefile
@@ -0,0 +1,65 @@
+# WebUI C++ Example
+# Windows - Microsoft Visual C++
+
+SHELL = CMD
+LIB_DIR = ../../../dist
+INCLUDE_DIR = ../../../include
+WEBUI_LIB_NAME = webui-2
+!IF "$(WEBUI_USE_TLS)" == "1"
+WEBUI_LIB_NAME = webui-2-secure
+!ENDIF
+
+# Build the WebUI library if running `nmake BUILD_LIB=true`
+BUILD_LIB =
+
+all: release
+
+debug:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE) debug
+!ENDIF
+# Static with Debug info
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C++ Example (Debug Static)...
+ @cl /Zi /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)/debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic with Debug info
+ @echo Build C++ Example (Debug Dynamic)...
+ @copy "$(LIB_DIR)\debug\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /Zi /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)/debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+release:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE)
+!ENDIF
+# Static Release
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C++ Example (Release Static)...
+ @cl /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic Release
+ @echo Build C++ Example (Release Dynamic)...
+ @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+clean:
+ - del *.obj >nul 2>&1
+ - del *.ilk >nul 2>&1
+ - del *.pdb >nul 2>&1
+ - del *.exp >nul 2>&1
+ - del *.exe >nul 2>&1
+ - del *.lib >nul 2>&1
diff --git a/examples/C++/serve_a_folder/index.html b/examples/C++/serve_a_folder/index.html
new file mode 100644
index 0000000..8b1da8c
--- /dev/null
+++ b/examples/C++/serve_a_folder/index.html
@@ -0,0 +1,39 @@
+
+
+
+
+ WebUI - Serve a Folder Example (C++)
+
+
+
+ Serve a Folder Example (C++)
+
+
+ You can edit this HTML file as you need.
+ Also, you can config WebUI to use Deno or Nodejs runtime for your JS/TS files.
+
+ Please click on the link to switch to the second page
+ Or click on the button to switch to the second page programmatically.
+
+
+
+
+ Switch to The Second Page Programmatically
+
+
+ Open The Second Window
+
+
+
+
+
diff --git a/examples/C++/serve_a_folder/main.cpp b/examples/C++/serve_a_folder/main.cpp
new file mode 100644
index 0000000..a8e274e
--- /dev/null
+++ b/examples/C++/serve_a_folder/main.cpp
@@ -0,0 +1,100 @@
+// Serve A Folder C++ Example
+
+#include "webui.hpp"
+#include
+
+class ServeAFolderApp {
+public:
+ ServeAFolderApp() {
+ // Bind HTML element IDs with class methods
+ win.bind("SwitchToSecondPage", this, &ServeAFolderApp::switch_to_second_page);
+ win.bind("OpenNewWindow", this, &ServeAFolderApp::show_second_window);
+ win.bind("Exit", this, &ServeAFolderApp::exit_app);
+ my_second_window.bind("Exit", this, &ServeAFolderApp::exit_app);
+
+ // Bind all events
+ win.bind("", this, &ServeAFolderApp::events);
+ my_second_window.bind("", this, &ServeAFolderApp::events);
+ }
+
+ void run() {
+ // Print logs (debug build only)
+ std::cout << "Starting..." << std::endl;
+
+ // Show the HTML page in the WebView/Browser window
+ win.show("index.html");
+ // win.show_browser("index.html", webui_browser::Chrome);
+ // win.show_wv("index.html");
+
+ // Wait until all windows get closed
+ webui::wait();
+
+ // Print logs (debug build only)
+ std::cout << "Thank you." << std::endl;
+ }
+
+private:
+ webui::window win;
+ webui::window my_second_window;
+
+ const char* event_type_to_string(size_t type) const {
+ switch (type) {
+ case webui::DISCONNECTED: return "DISCONNECTED";
+ case webui::CONNECTED: return "CONNECTED";
+ case webui::MOUSE_CLICK: return "MOUSE_CLICK";
+ case webui::NAVIGATION: return "NAVIGATION";
+ case webui::CALLBACKS: return "CALLBACKS";
+ default: return "UNKNOWN";
+ }
+ }
+
+ // This method gets called every time the user clicks on "OpenNewWindow"
+ void show_second_window(webui::window::event* e) {
+ // Show a new window, and navigate to `/second.html`
+ // if the window is already opened, then switch in the same window
+ my_second_window.show("second.html");
+ }
+
+ // This method gets called every time the user clicks on "SwitchToSecondPage"
+ void switch_to_second_page(webui::window::event* e) {
+ // Switch to `/second.html` in the same opened window.
+ e->get_window().show("second.html");
+ }
+
+ // This method receives all events because it's bind with an empty HTML ID.
+ void events(webui::window::event* e) {
+ std::cout << "[events] window=" << e->window
+ << " type=" << e->get_type()
+ << " (" << event_type_to_string(e->get_type()) << ")"
+ << " element='" << e->get_element()
+ << "' event=" << e->get_number()
+ << std::endl;
+
+ if (e->event_type == webui::CONNECTED)
+ std::cout << "Window Connected." << std::endl;
+ else if (e->event_type == webui::DISCONNECTED)
+ std::cout << "Window Disconnected." << std::endl;
+ else if (e->event_type == webui::MOUSE_CLICK)
+ std::cout << "Click on element: " << e->element << std::endl;
+ else if (e->event_type == webui::NAVIGATION) {
+ std::string url = e->get_string();
+ std::cout << "Starting navigation to: " << url << std::endl;
+ e->get_window().navigate(url);
+ }
+ }
+
+ void exit_app(webui::window::event* e) {
+ // Close all opened windows
+ webui::exit();
+ }
+};
+
+int main() {
+ ServeAFolderApp app;
+ app.run();
+ return 0;
+}
+
+#if defined(_MSC_VER)
+int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) { return main(); }
+#endif
diff --git a/examples/C++/serve_a_folder/second.html b/examples/C++/serve_a_folder/second.html
new file mode 100644
index 0000000..3d18970
--- /dev/null
+++ b/examples/C++/serve_a_folder/second.html
@@ -0,0 +1,26 @@
+
+
+
+
+ WebUI - Second Page (C++)
+
+
+
+ This is the second page !
+
+ Call Exit()
+
+
+
+
+
diff --git a/examples/C++/test_index_redirect/GNUmakefile b/examples/C++/test_index_redirect/GNUmakefile
new file mode 100644
index 0000000..2b085f5
--- /dev/null
+++ b/examples/C++/test_index_redirect/GNUmakefile
@@ -0,0 +1,138 @@
+# WebUI C++ Example
+
+# == 1. VARIABLES =============================================================
+
+MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
+PROJECT_DIR := $(dir $(MAKEFILE_PATH))/../../../
+TARGET := $(firstword $(MAKECMDGOALS))
+LIB_DIR := $(PROJECT_DIR)/dist
+ifeq ($(TARGET), debug)
+LIB_DIR := $(LIB_DIR)/debug
+endif
+INCLUDE_DIR := $(PROJECT_DIR)/include
+WEBUI_LIB_NAME = webui-2
+ifeq ($(WEBUI_USE_TLS), 1)
+WEBUI_LIB_NAME = webui-2-secure
+endif
+
+# ARGS
+# Set a compiler when running on Linux via `make CC=g++` / `make CC=clang`
+CC = g++
+# Build the WebUI library if running via `make BUILD_LIB=true`
+BUILD_LIB ?=
+
+# BUILD FLAGS
+STATIC_BUILD_FLAGS = main.cpp -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+DYN_BUILD_FLAGS = main.cpp -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+
+# Platform conditions
+ifeq ($(OS),Windows_NT)
+ # Windows
+ PLATFORM := windows
+ SHELL := CMD
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lws2_32 -Wall -luser32 -lstdc++ -luuid -static
+ COPY_LIB_CMD := @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ DYN_BUILD_FLAGS += "$(WEBUI_LIB_NAME).dll" -lws2_32 -Wall -luser32 -lstdc++ -luuid
+ STATIC_OUT := main.exe
+ DYN_OUT := main-dyn.exe
+ LWS2_OPT := -lws2_32 -lole32
+ STRIP_OPT := --strip-all
+ CONSOLE_APP := -Wl,-subsystem=console
+ GUI_APP := -Wl,-subsystem=windows
+else
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lpthread -lm -ldl
+ DYN_BUILD_FLAGS += -l$(WEBUI_LIB_NAME) -lpthread -lm -ldl
+ STATIC_OUT := main
+ DYN_OUT := main-dyn
+ ifeq ($(shell uname),Darwin)
+ # MacOS
+ PLATFORM := macos
+ CC = clang
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).dylib" "lib$(WEBUI_LIB_NAME).dylib"
+ WKWEBKIT_LINK_FLAGS := -framework Cocoa -framework WebKit
+ else
+ # Linux
+ PLATFORM := linux
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).so" "lib$(WEBUI_LIB_NAME).so"
+ STRIP_OPT := --strip-all
+ ifeq ($(CC),clang)
+ LLVM_OPT := llvm-
+ endif
+ endif
+endif
+
+# == 2.TARGETS ================================================================
+
+all: release
+
+debug: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE) debug
+endif
+# Static with Debug info
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C++ Example ($(CC) debug static)..."
+ @$(CC) -g $(CONSOLE_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+endif
+# Dynamic with Debug info
+ @echo "Build C++ Example ($(CC) debug dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) -g $(CONSOLE_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+release: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE)
+endif
+# Static Release
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C++ Example ($(CC) release static)..."
+ @$(CC) -Os $(GUI_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(STATIC_OUT)
+endif
+# Dynamic Release
+ @echo "Build C++ Example ($(CC) release dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) $(GUI_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+clean: --clean-$(PLATFORM)
+
+# INTERNAL TARGETS
+
+--validate-args:
+ifneq ($(filter $(CC),g++ clang aarch64-linux-gnu-g++ arm-linux-gnueabihf-g++ musl-g++),$(CC))
+$(error Invalid compiler specified: `$(CC)`)
+endif
+
+--clean-linux: --clean-unix
+
+--clean-macos: --clean-unix
+
+--clean-unix:
+ - rm -f *.o
+ - rm -f *.a
+ - rm -f *.so
+ - rm -f *.dylib
+ - rm -rf *.dSYM
+
+--clean-windows:
+ - del *.o >nul 2>&1
+ - del *.dll >nul 2>&1
+ - del *.a >nul 2>&1
+ - del *.exe >nul 2>&1
diff --git a/examples/C++/test_index_redirect/Makefile b/examples/C++/test_index_redirect/Makefile
new file mode 100644
index 0000000..d056ecd
--- /dev/null
+++ b/examples/C++/test_index_redirect/Makefile
@@ -0,0 +1,65 @@
+# WebUI C++ Example
+# Windows - Microsoft Visual C++
+
+SHELL = CMD
+LIB_DIR = ../../../dist
+INCLUDE_DIR = ../../../include
+WEBUI_LIB_NAME = webui-2
+!IF "$(WEBUI_USE_TLS)" == "1"
+WEBUI_LIB_NAME = webui-2-secure
+!ENDIF
+
+# Build the WebUI library if running `nmake BUILD_LIB=true`
+BUILD_LIB =
+
+all: release
+
+debug:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE) debug
+!ENDIF
+# Static with Debug info
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C++ Example (Debug Static)...
+ @cl /Zi /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)/debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic with Debug info
+ @echo Build C++ Example (Debug Dynamic)...
+ @copy "$(LIB_DIR)\debug\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /Zi /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)/debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+release:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE)
+!ENDIF
+# Static Release
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C++ Example (Release Static)...
+ @cl /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic Release
+ @echo Build C++ Example (Release Dynamic)...
+ @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+clean:
+ - del *.obj >nul 2>&1
+ - del *.ilk >nul 2>&1
+ - del *.pdb >nul 2>&1
+ - del *.exp >nul 2>&1
+ - del *.exe >nul 2>&1
+ - del *.lib >nul 2>&1
diff --git a/examples/C++/test_index_redirect/main.cpp b/examples/C++/test_index_redirect/main.cpp
new file mode 100644
index 0000000..b305ba7
--- /dev/null
+++ b/examples/C++/test_index_redirect/main.cpp
@@ -0,0 +1,87 @@
+#include "webui.hpp"
+#include "vfs.h"
+
+// This example is used to verify redirect and fallback behavior for:
+// /, /sub, /sub/foo
+// in both storage modes:
+// 1) set_root_folder(...)
+// 2) set_file_handler(vfs)
+//
+// Server mode is the primary redirect test path because it exposes the raw
+// HTTP behavior (302 Location targets) without mixing in window lifecycle.
+//
+// The expected server behavior is:
+// - start_server("custom.html") prefers custom.html in every directory
+// - an explicit filename is strict; if it does not exist, the request fails
+// - start_server() or start_server("") means "fallback mode", which probes
+// index.html, index.htm, index.ts, then index.js
+//
+// Note: index.ts and index.js can still be valid fallback targets for
+// runtime/script-first scenarios, but they are not equivalent to an HTML GUI
+// entry page. For normal GUI testing, HTML/HTM are the page-like entries.
+int main(int argc, char *argv[])
+{
+ bool serverMode = false;
+ bool vfsEnabled = false;
+ for (int i = 1; i < argc; ++i)
+ {
+ if (std::string(argv[i]) == "--server")
+ {
+ serverMode = true;
+ }
+ else if (std::string(argv[i]) == "--vfs")
+ {
+ vfsEnabled = true;
+ }
+ }
+
+ webui::window window_;
+ webui::set_config(use_cookies, false);
+
+ if (vfsEnabled)
+ {
+ window_.set_file_handler(vfs);
+ }
+ else
+ {
+ window_.set_root_folder("/home/gordon/Dokumenty/PlatformIO/Projects/webui/examples/C++/test_index_redirect/ui/");
+
+ // Absolute paths:
+ // window_.set_root_folder("/path/to/ui/");
+ // window_.set_root_folder("/path/to/ui");
+
+ // Relative if ui folder is next to executable:
+ // window_.set_root_folder("ui/");
+ // window_.set_root_folder("ui");
+ }
+
+ if (serverMode)
+ {
+ window_.set_port(8080);
+
+ // Explicit custom entry file:
+ window_.start_server("custom.html");
+
+ // Redirect to the hardcoded index.* fallback list:
+ // window_.start_server();
+
+ }
+ else
+ {
+ // Explicit custom entry file:
+ window_.show("custom.html");
+ // window_.show_browser("custom.html"); // AnyBrowser is the default second argument in C++.
+
+ // Redirect to the hardcoded index.* fallback list:
+ // window_.show();
+ // window_.show_browser();
+ }
+
+ webui::wait();
+
+ return 0;
+}
+
+#if defined(_MSC_VER)
+int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) { return main(__argc, __argv); }
+#endif
diff --git a/examples/C++/test_index_redirect/ui/custom.html b/examples/C++/test_index_redirect/ui/custom.html
new file mode 100644
index 0000000..0abbe9c
--- /dev/null
+++ b/examples/C++/test_index_redirect/ui/custom.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+ ui/custom.html
+
+
+ ui/custom.html
+ IDENTIFIER: ui/custom.html
+ Directory routes: / | /sub | /sub/foo
+ All test files
+
+
+
+
diff --git a/examples/C++/test_index_redirect/ui/index.css b/examples/C++/test_index_redirect/ui/index.css
new file mode 100644
index 0000000..6bc789d
--- /dev/null
+++ b/examples/C++/test_index_redirect/ui/index.css
@@ -0,0 +1,4 @@
+/* IDENTIFIER: ui/index.css */
+/* Directory routes: / | /sub | /sub/foo */
+/* All files: /custom.html /index.html /index.css /index.js /sub/custom.html /sub/index.html /sub/index.css /sub/index.js /sub/foo/custom.html /sub/foo/index.html /sub/foo/index.css /sub/foo/index.js */
+body { font-family: monospace; }
diff --git a/examples/C++/test_index_redirect/ui/index.html b/examples/C++/test_index_redirect/ui/index.html
new file mode 100644
index 0000000..120a792
--- /dev/null
+++ b/examples/C++/test_index_redirect/ui/index.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+ ui/index.html
+
+
+ ui/index.html
+ IDENTIFIER: ui/index.html
+ Directory routes: / | /sub | /sub/foo
+ All test files
+
+
+
+
diff --git a/examples/C++/test_index_redirect/ui/index.js b/examples/C++/test_index_redirect/ui/index.js
new file mode 100644
index 0000000..4094538
--- /dev/null
+++ b/examples/C++/test_index_redirect/ui/index.js
@@ -0,0 +1,4 @@
+// IDENTIFIER: ui/index.js
+// Directory routes: / | /sub | /sub/foo
+// All files: /custom.html /index.html /index.css /index.js /sub/custom.html /sub/index.html /sub/index.css /sub/index.js /sub/foo/custom.html /sub/foo/index.html /sub/foo/index.css /sub/foo/index.js
+console.log('IDENTIFIER: ui/index.js');
diff --git a/examples/C++/test_index_redirect/ui/sub/custom.html b/examples/C++/test_index_redirect/ui/sub/custom.html
new file mode 100644
index 0000000..e90b2d5
--- /dev/null
+++ b/examples/C++/test_index_redirect/ui/sub/custom.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+ ui/sub/custom.html
+
+
+ ui/sub/custom.html
+ IDENTIFIER: ui/sub/custom.html
+ Directory routes: / | /sub | /sub/foo
+ All test files
+
+
+
+
diff --git a/examples/C++/test_index_redirect/ui/sub/foo/custom.html b/examples/C++/test_index_redirect/ui/sub/foo/custom.html
new file mode 100644
index 0000000..2b57d8b
--- /dev/null
+++ b/examples/C++/test_index_redirect/ui/sub/foo/custom.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+ ui/sub/foo/custom.html
+
+
+ ui/sub/foo/custom.html
+ IDENTIFIER: ui/sub/foo/custom.html
+ Directory routes: / | /sub | /sub/foo
+ All test files
+
+
+
+
diff --git a/examples/C++/test_index_redirect/ui/sub/foo/index.css b/examples/C++/test_index_redirect/ui/sub/foo/index.css
new file mode 100644
index 0000000..2ce12c5
--- /dev/null
+++ b/examples/C++/test_index_redirect/ui/sub/foo/index.css
@@ -0,0 +1,4 @@
+/* IDENTIFIER: ui/sub/foo/index.css */
+/* Directory routes: / | /sub | /sub/foo */
+/* All files: /custom.html /index.html /index.css /index.js /sub/custom.html /sub/index.html /sub/index.css /sub/index.js /sub/foo/custom.html /sub/foo/index.html /sub/foo/index.css /sub/foo/index.js */
+body { font-family: monospace; }
diff --git a/examples/C++/test_index_redirect/ui/sub/foo/index.html b/examples/C++/test_index_redirect/ui/sub/foo/index.html
new file mode 100644
index 0000000..86026d7
--- /dev/null
+++ b/examples/C++/test_index_redirect/ui/sub/foo/index.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+ ui/sub/foo/index.html
+
+
+ ui/sub/foo/index.html
+ IDENTIFIER: ui/sub/foo/index.html
+ Directory routes: / | /sub | /sub/foo
+ All test files
+
+
+
+
diff --git a/examples/C++/test_index_redirect/ui/sub/foo/index.js b/examples/C++/test_index_redirect/ui/sub/foo/index.js
new file mode 100644
index 0000000..e4cef1a
--- /dev/null
+++ b/examples/C++/test_index_redirect/ui/sub/foo/index.js
@@ -0,0 +1,4 @@
+// IDENTIFIER: ui/sub/foo/index.js
+// Directory routes: / | /sub | /sub/foo
+// All files: /custom.html /index.html /index.css /index.js /sub/custom.html /sub/index.html /sub/index.css /sub/index.js /sub/foo/custom.html /sub/foo/index.html /sub/foo/index.css /sub/foo/index.js
+console.log('IDENTIFIER: ui/sub/foo/index.js');
diff --git a/examples/C++/test_index_redirect/ui/sub/index.css b/examples/C++/test_index_redirect/ui/sub/index.css
new file mode 100644
index 0000000..68962cd
--- /dev/null
+++ b/examples/C++/test_index_redirect/ui/sub/index.css
@@ -0,0 +1,4 @@
+/* IDENTIFIER: ui/sub/index.css */
+/* Directory routes: / | /sub | /sub/foo */
+/* All files: /custom.html /index.html /index.css /index.js /sub/custom.html /sub/index.html /sub/index.css /sub/index.js /sub/foo/custom.html /sub/foo/index.html /sub/foo/index.css /sub/foo/index.js */
+body { font-family: monospace; }
diff --git a/examples/C++/test_index_redirect/ui/sub/index.html b/examples/C++/test_index_redirect/ui/sub/index.html
new file mode 100644
index 0000000..912a3a7
--- /dev/null
+++ b/examples/C++/test_index_redirect/ui/sub/index.html
@@ -0,0 +1,29 @@
+
+
+
+
+
+ ui/sub/index.html
+
+
+ ui/sub/index.html
+ IDENTIFIER: ui/sub/index.html
+ Directory routes: / | /sub | /sub/foo
+ All test files
+
+
+
+
diff --git a/examples/C++/test_index_redirect/ui/sub/index.js b/examples/C++/test_index_redirect/ui/sub/index.js
new file mode 100644
index 0000000..9fd0f34
--- /dev/null
+++ b/examples/C++/test_index_redirect/ui/sub/index.js
@@ -0,0 +1,4 @@
+// IDENTIFIER: ui/sub/index.js
+// Directory routes: / | /sub | /sub/foo
+// All files: /custom.html /index.html /index.css /index.js /sub/custom.html /sub/index.html /sub/index.css /sub/index.js /sub/foo/custom.html /sub/foo/index.html /sub/foo/index.css /sub/foo/index.js
+console.log('IDENTIFIER: ui/sub/index.js');
diff --git a/examples/C++/test_index_redirect/vfs.h b/examples/C++/test_index_redirect/vfs.h
new file mode 100644
index 0000000..8251df5
--- /dev/null
+++ b/examples/C++/test_index_redirect/vfs.h
@@ -0,0 +1,131 @@
+#ifndef VIRTUAL_FILE_SYSTEM_H
+#define VIRTUAL_FILE_SYSTEM_H
+
+typedef struct {
+ const char *path;
+ const unsigned char *data;
+ int length;
+} VirtualFile;
+
+static const unsigned char FILE_0[] = {0x2f,0x2a,0x20,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2a,0x2f,0x0a,0x2f,0x2a,0x20,0x44,0x69,0x72,0x65,0x63,0x74,0x6f,0x72,0x79,0x20,0x72,0x6f,0x75,0x74,0x65,0x73,0x3a,0x20,0x2f,0x20,0x7c,0x20,0x2f,0x73,0x75,0x62,0x20,0x7c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x20,0x2a,0x2f,0x0a,0x2f,0x2a,0x20,0x41,0x6c,0x6c,0x20,0x66,0x69,0x6c,0x65,0x73,0x3a,0x20,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2a,0x2f,0x0a,0x62,0x6f,0x64,0x79,0x20,0x7b,0x20,0x66,0x6f,0x6e,0x74,0x2d,0x66,0x61,0x6d,0x69,0x6c,0x79,0x3a,0x20,0x6d,0x6f,0x6e,0x6f,0x73,0x70,0x61,0x63,0x65,0x3b,0x20,0x7d,0x0a};
+
+static const unsigned char FILE_1[] = {0x3c,0x21,0x64,0x6f,0x63,0x74,0x79,0x70,0x65,0x20,0x68,0x74,0x6d,0x6c,0x3e,0x0a,0x3c,0x68,0x74,0x6d,0x6c,0x20,0x6c,0x61,0x6e,0x67,0x3d,0x22,0x65,0x6e,0x22,0x3e,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x0a,0x20,0x20,0x3c,0x6d,0x65,0x74,0x61,0x20,0x63,0x68,0x61,0x72,0x73,0x65,0x74,0x3d,0x22,0x75,0x74,0x66,0x2d,0x38,0x22,0x20,0x2f,0x3e,0x0a,0x20,0x20,0x3c,0x6d,0x65,0x74,0x61,0x20,0x6e,0x61,0x6d,0x65,0x3d,0x22,0x76,0x69,0x65,0x77,0x70,0x6f,0x72,0x74,0x22,0x20,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x3d,0x22,0x77,0x69,0x64,0x74,0x68,0x3d,0x64,0x65,0x76,0x69,0x63,0x65,0x2d,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x2d,0x73,0x63,0x61,0x6c,0x65,0x3d,0x31,0x22,0x20,0x2f,0x3e,0x0a,0x20,0x20,0x3c,0x74,0x69,0x74,0x6c,0x65,0x3e,0x75,0x69,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x0a,0x3c,0x2f,0x68,0x65,0x61,0x64,0x3e,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x20,0x20,0x3c,0x68,0x31,0x3e,0x75,0x69,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x68,0x31,0x3e,0x0a,0x20,0x20,0x3c,0x70,0x3e,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x70,0x3e,0x0a,0x20,0x20,0x3c,0x70,0x3e,0x44,0x69,0x72,0x65,0x63,0x74,0x6f,0x72,0x79,0x20,0x72,0x6f,0x75,0x74,0x65,0x73,0x3a,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x22,0x3e,0x2f,0x3c,0x2f,0x61,0x3e,0x20,0x7c,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x22,0x3e,0x2f,0x73,0x75,0x62,0x3c,0x2f,0x61,0x3e,0x20,0x7c,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x70,0x3e,0x0a,0x20,0x20,0x3c,0x68,0x32,0x3e,0x41,0x6c,0x6c,0x20,0x74,0x65,0x73,0x74,0x20,0x66,0x69,0x6c,0x65,0x73,0x3c,0x2f,0x68,0x32,0x3e,0x0a,0x20,0x20,0x3c,0x75,0x6c,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x3c,0x2f,0x75,0x6c,0x3e,0x0a,0x3c,0x73,0x63,0x72,0x69,0x70,0x74,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x77,0x65,0x62,0x75,0x69,0x2e,0x6a,0x73,0x22,0x3e,0x3c,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x3e,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0a};
+
+static const unsigned char FILE_2[] = {0x2f,0x2f,0x20,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x0a,0x2f,0x2f,0x20,0x44,0x69,0x72,0x65,0x63,0x74,0x6f,0x72,0x79,0x20,0x72,0x6f,0x75,0x74,0x65,0x73,0x3a,0x20,0x2f,0x20,0x7c,0x20,0x2f,0x73,0x75,0x62,0x20,0x7c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x0a,0x2f,0x2f,0x20,0x41,0x6c,0x6c,0x20,0x66,0x69,0x6c,0x65,0x73,0x3a,0x20,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x0a,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x6c,0x6f,0x67,0x28,0x27,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x27,0x29,0x3b,0x0a};
+
+static const unsigned char FILE_3[] = {0x3c,0x21,0x64,0x6f,0x63,0x74,0x79,0x70,0x65,0x20,0x68,0x74,0x6d,0x6c,0x3e,0x0a,0x3c,0x68,0x74,0x6d,0x6c,0x20,0x6c,0x61,0x6e,0x67,0x3d,0x22,0x65,0x6e,0x22,0x3e,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x0a,0x20,0x20,0x3c,0x6d,0x65,0x74,0x61,0x20,0x63,0x68,0x61,0x72,0x73,0x65,0x74,0x3d,0x22,0x75,0x74,0x66,0x2d,0x38,0x22,0x20,0x2f,0x3e,0x0a,0x20,0x20,0x3c,0x6d,0x65,0x74,0x61,0x20,0x6e,0x61,0x6d,0x65,0x3d,0x22,0x76,0x69,0x65,0x77,0x70,0x6f,0x72,0x74,0x22,0x20,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x3d,0x22,0x77,0x69,0x64,0x74,0x68,0x3d,0x64,0x65,0x76,0x69,0x63,0x65,0x2d,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x2d,0x73,0x63,0x61,0x6c,0x65,0x3d,0x31,0x22,0x20,0x2f,0x3e,0x0a,0x20,0x20,0x3c,0x74,0x69,0x74,0x6c,0x65,0x3e,0x75,0x69,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x0a,0x3c,0x2f,0x68,0x65,0x61,0x64,0x3e,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x20,0x20,0x3c,0x68,0x31,0x3e,0x75,0x69,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x68,0x31,0x3e,0x0a,0x20,0x20,0x3c,0x70,0x3e,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x70,0x3e,0x0a,0x20,0x20,0x3c,0x70,0x3e,0x44,0x69,0x72,0x65,0x63,0x74,0x6f,0x72,0x79,0x20,0x72,0x6f,0x75,0x74,0x65,0x73,0x3a,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x22,0x3e,0x2f,0x3c,0x2f,0x61,0x3e,0x20,0x7c,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x22,0x3e,0x2f,0x73,0x75,0x62,0x3c,0x2f,0x61,0x3e,0x20,0x7c,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x70,0x3e,0x0a,0x20,0x20,0x3c,0x68,0x32,0x3e,0x41,0x6c,0x6c,0x20,0x74,0x65,0x73,0x74,0x20,0x66,0x69,0x6c,0x65,0x73,0x3c,0x2f,0x68,0x32,0x3e,0x0a,0x20,0x20,0x3c,0x75,0x6c,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x3c,0x2f,0x75,0x6c,0x3e,0x0a,0x3c,0x73,0x63,0x72,0x69,0x70,0x74,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x77,0x65,0x62,0x75,0x69,0x2e,0x6a,0x73,0x22,0x3e,0x3c,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x3e,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0a};
+
+static const unsigned char FILE_4[] = {0x3c,0x21,0x64,0x6f,0x63,0x74,0x79,0x70,0x65,0x20,0x68,0x74,0x6d,0x6c,0x3e,0x0a,0x3c,0x68,0x74,0x6d,0x6c,0x20,0x6c,0x61,0x6e,0x67,0x3d,0x22,0x65,0x6e,0x22,0x3e,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x0a,0x20,0x20,0x3c,0x6d,0x65,0x74,0x61,0x20,0x63,0x68,0x61,0x72,0x73,0x65,0x74,0x3d,0x22,0x75,0x74,0x66,0x2d,0x38,0x22,0x20,0x2f,0x3e,0x0a,0x20,0x20,0x3c,0x6d,0x65,0x74,0x61,0x20,0x6e,0x61,0x6d,0x65,0x3d,0x22,0x76,0x69,0x65,0x77,0x70,0x6f,0x72,0x74,0x22,0x20,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x3d,0x22,0x77,0x69,0x64,0x74,0x68,0x3d,0x64,0x65,0x76,0x69,0x63,0x65,0x2d,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x2d,0x73,0x63,0x61,0x6c,0x65,0x3d,0x31,0x22,0x20,0x2f,0x3e,0x0a,0x20,0x20,0x3c,0x74,0x69,0x74,0x6c,0x65,0x3e,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x0a,0x3c,0x2f,0x68,0x65,0x61,0x64,0x3e,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x20,0x20,0x3c,0x68,0x31,0x3e,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x68,0x31,0x3e,0x0a,0x20,0x20,0x3c,0x70,0x3e,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x70,0x3e,0x0a,0x20,0x20,0x3c,0x70,0x3e,0x44,0x69,0x72,0x65,0x63,0x74,0x6f,0x72,0x79,0x20,0x72,0x6f,0x75,0x74,0x65,0x73,0x3a,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x22,0x3e,0x2f,0x3c,0x2f,0x61,0x3e,0x20,0x7c,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x22,0x3e,0x2f,0x73,0x75,0x62,0x3c,0x2f,0x61,0x3e,0x20,0x7c,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x70,0x3e,0x0a,0x20,0x20,0x3c,0x68,0x32,0x3e,0x41,0x6c,0x6c,0x20,0x74,0x65,0x73,0x74,0x20,0x66,0x69,0x6c,0x65,0x73,0x3c,0x2f,0x68,0x32,0x3e,0x0a,0x20,0x20,0x3c,0x75,0x6c,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x3c,0x2f,0x75,0x6c,0x3e,0x0a,0x3c,0x73,0x63,0x72,0x69,0x70,0x74,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x77,0x65,0x62,0x75,0x69,0x2e,0x6a,0x73,0x22,0x3e,0x3c,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x3e,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0a};
+
+static const unsigned char FILE_5[] = {0x2f,0x2a,0x20,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2a,0x2f,0x0a,0x2f,0x2a,0x20,0x44,0x69,0x72,0x65,0x63,0x74,0x6f,0x72,0x79,0x20,0x72,0x6f,0x75,0x74,0x65,0x73,0x3a,0x20,0x2f,0x20,0x7c,0x20,0x2f,0x73,0x75,0x62,0x20,0x7c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x20,0x2a,0x2f,0x0a,0x2f,0x2a,0x20,0x41,0x6c,0x6c,0x20,0x66,0x69,0x6c,0x65,0x73,0x3a,0x20,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2a,0x2f,0x0a,0x62,0x6f,0x64,0x79,0x20,0x7b,0x20,0x66,0x6f,0x6e,0x74,0x2d,0x66,0x61,0x6d,0x69,0x6c,0x79,0x3a,0x20,0x6d,0x6f,0x6e,0x6f,0x73,0x70,0x61,0x63,0x65,0x3b,0x20,0x7d,0x0a};
+
+static const unsigned char FILE_6[] = {0x3c,0x21,0x64,0x6f,0x63,0x74,0x79,0x70,0x65,0x20,0x68,0x74,0x6d,0x6c,0x3e,0x0a,0x3c,0x68,0x74,0x6d,0x6c,0x20,0x6c,0x61,0x6e,0x67,0x3d,0x22,0x65,0x6e,0x22,0x3e,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x0a,0x20,0x20,0x3c,0x6d,0x65,0x74,0x61,0x20,0x63,0x68,0x61,0x72,0x73,0x65,0x74,0x3d,0x22,0x75,0x74,0x66,0x2d,0x38,0x22,0x20,0x2f,0x3e,0x0a,0x20,0x20,0x3c,0x6d,0x65,0x74,0x61,0x20,0x6e,0x61,0x6d,0x65,0x3d,0x22,0x76,0x69,0x65,0x77,0x70,0x6f,0x72,0x74,0x22,0x20,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x3d,0x22,0x77,0x69,0x64,0x74,0x68,0x3d,0x64,0x65,0x76,0x69,0x63,0x65,0x2d,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x2d,0x73,0x63,0x61,0x6c,0x65,0x3d,0x31,0x22,0x20,0x2f,0x3e,0x0a,0x20,0x20,0x3c,0x74,0x69,0x74,0x6c,0x65,0x3e,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x0a,0x3c,0x2f,0x68,0x65,0x61,0x64,0x3e,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x20,0x20,0x3c,0x68,0x31,0x3e,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x68,0x31,0x3e,0x0a,0x20,0x20,0x3c,0x70,0x3e,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x70,0x3e,0x0a,0x20,0x20,0x3c,0x70,0x3e,0x44,0x69,0x72,0x65,0x63,0x74,0x6f,0x72,0x79,0x20,0x72,0x6f,0x75,0x74,0x65,0x73,0x3a,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x22,0x3e,0x2f,0x3c,0x2f,0x61,0x3e,0x20,0x7c,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x22,0x3e,0x2f,0x73,0x75,0x62,0x3c,0x2f,0x61,0x3e,0x20,0x7c,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x70,0x3e,0x0a,0x20,0x20,0x3c,0x68,0x32,0x3e,0x41,0x6c,0x6c,0x20,0x74,0x65,0x73,0x74,0x20,0x66,0x69,0x6c,0x65,0x73,0x3c,0x2f,0x68,0x32,0x3e,0x0a,0x20,0x20,0x3c,0x75,0x6c,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x3c,0x2f,0x75,0x6c,0x3e,0x0a,0x3c,0x73,0x63,0x72,0x69,0x70,0x74,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x77,0x65,0x62,0x75,0x69,0x2e,0x6a,0x73,0x22,0x3e,0x3c,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x3e,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0a};
+
+static const unsigned char FILE_7[] = {0x2f,0x2f,0x20,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x0a,0x2f,0x2f,0x20,0x44,0x69,0x72,0x65,0x63,0x74,0x6f,0x72,0x79,0x20,0x72,0x6f,0x75,0x74,0x65,0x73,0x3a,0x20,0x2f,0x20,0x7c,0x20,0x2f,0x73,0x75,0x62,0x20,0x7c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x0a,0x2f,0x2f,0x20,0x41,0x6c,0x6c,0x20,0x66,0x69,0x6c,0x65,0x73,0x3a,0x20,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x0a,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x6c,0x6f,0x67,0x28,0x27,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x27,0x29,0x3b,0x0a};
+
+static const unsigned char FILE_8[] = {0x3c,0x21,0x64,0x6f,0x63,0x74,0x79,0x70,0x65,0x20,0x68,0x74,0x6d,0x6c,0x3e,0x0a,0x3c,0x68,0x74,0x6d,0x6c,0x20,0x6c,0x61,0x6e,0x67,0x3d,0x22,0x65,0x6e,0x22,0x3e,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x0a,0x20,0x20,0x3c,0x6d,0x65,0x74,0x61,0x20,0x63,0x68,0x61,0x72,0x73,0x65,0x74,0x3d,0x22,0x75,0x74,0x66,0x2d,0x38,0x22,0x20,0x2f,0x3e,0x0a,0x20,0x20,0x3c,0x6d,0x65,0x74,0x61,0x20,0x6e,0x61,0x6d,0x65,0x3d,0x22,0x76,0x69,0x65,0x77,0x70,0x6f,0x72,0x74,0x22,0x20,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x3d,0x22,0x77,0x69,0x64,0x74,0x68,0x3d,0x64,0x65,0x76,0x69,0x63,0x65,0x2d,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x2d,0x73,0x63,0x61,0x6c,0x65,0x3d,0x31,0x22,0x20,0x2f,0x3e,0x0a,0x20,0x20,0x3c,0x74,0x69,0x74,0x6c,0x65,0x3e,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x0a,0x3c,0x2f,0x68,0x65,0x61,0x64,0x3e,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x20,0x20,0x3c,0x68,0x31,0x3e,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x68,0x31,0x3e,0x0a,0x20,0x20,0x3c,0x70,0x3e,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x70,0x3e,0x0a,0x20,0x20,0x3c,0x70,0x3e,0x44,0x69,0x72,0x65,0x63,0x74,0x6f,0x72,0x79,0x20,0x72,0x6f,0x75,0x74,0x65,0x73,0x3a,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x22,0x3e,0x2f,0x3c,0x2f,0x61,0x3e,0x20,0x7c,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x22,0x3e,0x2f,0x73,0x75,0x62,0x3c,0x2f,0x61,0x3e,0x20,0x7c,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x70,0x3e,0x0a,0x20,0x20,0x3c,0x68,0x32,0x3e,0x41,0x6c,0x6c,0x20,0x74,0x65,0x73,0x74,0x20,0x66,0x69,0x6c,0x65,0x73,0x3c,0x2f,0x68,0x32,0x3e,0x0a,0x20,0x20,0x3c,0x75,0x6c,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x3c,0x2f,0x75,0x6c,0x3e,0x0a,0x3c,0x73,0x63,0x72,0x69,0x70,0x74,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x77,0x65,0x62,0x75,0x69,0x2e,0x6a,0x73,0x22,0x3e,0x3c,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x3e,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0a};
+
+static const unsigned char FILE_9[] = {0x2f,0x2a,0x20,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2a,0x2f,0x0a,0x2f,0x2a,0x20,0x44,0x69,0x72,0x65,0x63,0x74,0x6f,0x72,0x79,0x20,0x72,0x6f,0x75,0x74,0x65,0x73,0x3a,0x20,0x2f,0x20,0x7c,0x20,0x2f,0x73,0x75,0x62,0x20,0x7c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x20,0x2a,0x2f,0x0a,0x2f,0x2a,0x20,0x41,0x6c,0x6c,0x20,0x66,0x69,0x6c,0x65,0x73,0x3a,0x20,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2a,0x2f,0x0a,0x62,0x6f,0x64,0x79,0x20,0x7b,0x20,0x66,0x6f,0x6e,0x74,0x2d,0x66,0x61,0x6d,0x69,0x6c,0x79,0x3a,0x20,0x6d,0x6f,0x6e,0x6f,0x73,0x70,0x61,0x63,0x65,0x3b,0x20,0x7d,0x0a};
+
+static const unsigned char FILE_10[] = {0x3c,0x21,0x64,0x6f,0x63,0x74,0x79,0x70,0x65,0x20,0x68,0x74,0x6d,0x6c,0x3e,0x0a,0x3c,0x68,0x74,0x6d,0x6c,0x20,0x6c,0x61,0x6e,0x67,0x3d,0x22,0x65,0x6e,0x22,0x3e,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x0a,0x20,0x20,0x3c,0x6d,0x65,0x74,0x61,0x20,0x63,0x68,0x61,0x72,0x73,0x65,0x74,0x3d,0x22,0x75,0x74,0x66,0x2d,0x38,0x22,0x20,0x2f,0x3e,0x0a,0x20,0x20,0x3c,0x6d,0x65,0x74,0x61,0x20,0x6e,0x61,0x6d,0x65,0x3d,0x22,0x76,0x69,0x65,0x77,0x70,0x6f,0x72,0x74,0x22,0x20,0x63,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x3d,0x22,0x77,0x69,0x64,0x74,0x68,0x3d,0x64,0x65,0x76,0x69,0x63,0x65,0x2d,0x77,0x69,0x64,0x74,0x68,0x2c,0x20,0x69,0x6e,0x69,0x74,0x69,0x61,0x6c,0x2d,0x73,0x63,0x61,0x6c,0x65,0x3d,0x31,0x22,0x20,0x2f,0x3e,0x0a,0x20,0x20,0x3c,0x74,0x69,0x74,0x6c,0x65,0x3e,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x0a,0x3c,0x2f,0x68,0x65,0x61,0x64,0x3e,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x20,0x20,0x3c,0x68,0x31,0x3e,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x68,0x31,0x3e,0x0a,0x20,0x20,0x3c,0x70,0x3e,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x70,0x3e,0x0a,0x20,0x20,0x3c,0x70,0x3e,0x44,0x69,0x72,0x65,0x63,0x74,0x6f,0x72,0x79,0x20,0x72,0x6f,0x75,0x74,0x65,0x73,0x3a,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x22,0x3e,0x2f,0x3c,0x2f,0x61,0x3e,0x20,0x7c,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x22,0x3e,0x2f,0x73,0x75,0x62,0x3c,0x2f,0x61,0x3e,0x20,0x7c,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x70,0x3e,0x0a,0x20,0x20,0x3c,0x68,0x32,0x3e,0x41,0x6c,0x6c,0x20,0x74,0x65,0x73,0x74,0x20,0x66,0x69,0x6c,0x65,0x73,0x3c,0x2f,0x68,0x32,0x3e,0x0a,0x20,0x20,0x3c,0x75,0x6c,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x20,0x20,0x3c,0x6c,0x69,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x22,0x3e,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x6c,0x69,0x3e,0x0a,0x20,0x20,0x3c,0x2f,0x75,0x6c,0x3e,0x0a,0x3c,0x73,0x63,0x72,0x69,0x70,0x74,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x77,0x65,0x62,0x75,0x69,0x2e,0x6a,0x73,0x22,0x3e,0x3c,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x3e,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0a};
+
+static const unsigned char FILE_11[] = {0x2f,0x2f,0x20,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x0a,0x2f,0x2f,0x20,0x44,0x69,0x72,0x65,0x63,0x74,0x6f,0x72,0x79,0x20,0x72,0x6f,0x75,0x74,0x65,0x73,0x3a,0x20,0x2f,0x20,0x7c,0x20,0x2f,0x73,0x75,0x62,0x20,0x7c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x0a,0x2f,0x2f,0x20,0x41,0x6c,0x6c,0x20,0x66,0x69,0x6c,0x65,0x73,0x3a,0x20,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x63,0x75,0x73,0x74,0x6f,0x6d,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x63,0x73,0x73,0x20,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x0a,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x6c,0x6f,0x67,0x28,0x27,0x49,0x44,0x45,0x4e,0x54,0x49,0x46,0x49,0x45,0x52,0x3a,0x20,0x75,0x69,0x2f,0x73,0x75,0x62,0x2f,0x66,0x6f,0x6f,0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x6a,0x73,0x27,0x29,0x3b,0x0a};
+
+
+static const VirtualFile virtual_files[] = {
+ {
+ "/index.css",
+ FILE_0,
+ 311
+ },
+ {
+ "/index.html",
+ FILE_1,
+ 1138
+ },
+ {
+ "/index.js",
+ FILE_2,
+ 308
+ },
+ {
+ "/custom.html",
+ FILE_3,
+ 1141
+ },
+ {
+ "/sub/custom.html",
+ FILE_4,
+ 1153
+ },
+ {
+ "/sub/index.css",
+ FILE_5,
+ 315
+ },
+ {
+ "/sub/index.html",
+ FILE_6,
+ 1150
+ },
+ {
+ "/sub/index.js",
+ FILE_7,
+ 316
+ },
+ {
+ "/sub/foo/custom.html",
+ FILE_8,
+ 1165
+ },
+ {
+ "/sub/foo/index.css",
+ FILE_9,
+ 319
+ },
+ {
+ "/sub/foo/index.html",
+ FILE_10,
+ 1162
+ },
+ {
+ "/sub/foo/index.js",
+ FILE_11,
+ 324
+ },
+};
+
+static const int virtual_files_count = sizeof(virtual_files) / sizeof(virtual_files[0]);
+
+bool virtual_file_system(const char* path, const unsigned char** file, int* length) {
+ for (int i = 0; i < virtual_files_count; ++i) {
+ if (strcmp(virtual_files[i].path, path) == 0) {
+ *file = virtual_files[i].data;
+ *length = virtual_files[i].length;
+ return true;
+ }
+ }
+ return false;
+}
+
+const void* vfs(const char* path, int* length) {
+ const unsigned char* file_data;
+ int file_length;
+
+ if (virtual_file_system(path, &file_data, &file_length)) {
+ const char* content_type = webui_get_mime_type(path);
+ const char* http_header_template = "HTTP/1.1 200 OK\r\n"
+ "Content-Type: %s\r\n"
+ "Content-Length: %d\r\n"
+ "Cache-Control: no-cache\r\n\r\n";
+ int header_length = snprintf(NULL, 0, http_header_template, content_type, file_length);
+ *length = header_length + file_length;
+ unsigned char* response = (unsigned char*) webui_malloc(*length);
+ snprintf((char*) response, header_length + 1, http_header_template, content_type, file_length);
+ memcpy(response + header_length, file_data, file_length);
+ return response;
+ }
+ return NULL;
+}
+
+#endif // VIRTUAL_FILE_SYSTEM_H
diff --git a/examples/C++/test_index_redirect/vfs.py b/examples/C++/test_index_redirect/vfs.py
new file mode 100644
index 0000000..57e4dfd
--- /dev/null
+++ b/examples/C++/test_index_redirect/vfs.py
@@ -0,0 +1,99 @@
+# WebUI Library
+# https://webui.me
+# https://github.com/webui-dev/webui
+# Copyright (c) 2020-2026 Hassan Draga.
+# Licensed under MIT License.
+# All rights reserved.
+# Canada.
+#
+# WebUI Virtual File System Generator
+# v2.0
+
+import os
+import sys
+
+def generate_vfs_header(directory, output_header):
+ files = []
+
+ for root, _, filenames in os.walk(directory):
+ for filename in filenames:
+ filepath = os.path.join(root, filename)
+ relative_path = os.path.relpath(filepath, directory)
+ # Ensure path starts with a slash
+ relative_path = '/' + relative_path.replace('\\', '/')
+ files.append((relative_path, filepath))
+
+ with open(output_header, 'w') as header:
+ header.write('#ifndef VIRTUAL_FILE_SYSTEM_H\n')
+ header.write('#define VIRTUAL_FILE_SYSTEM_H\n\n')
+
+ header.write('typedef struct {\n')
+ header.write(' const char *path;\n')
+ header.write(' const unsigned char *data;\n')
+ header.write(' int length;\n')
+ header.write('} VirtualFile;\n\n')
+
+ for i, (relative_path, filepath) in enumerate(files):
+ with open(filepath, 'rb') as f:
+ data = f.read()
+ header.write(f'static const unsigned char FILE_{i}[] = {{')
+ header.write(','.join(f'0x{byte:02x}' for byte in data))
+ header.write('};\n\n')
+
+ header.write('\nstatic const VirtualFile virtual_files[] = {\n')
+
+ for i, (relative_path, filepath) in enumerate(files):
+ with open(filepath, 'rb') as f:
+ data = f.read()
+ header.write(' {\n')
+ header.write(f' "{relative_path}",\n')
+ header.write(f' FILE_{i},\n')
+ header.write(f' {len(data)}\n')
+ header.write(' },\n')
+
+ header.write('};\n\n')
+
+ header.write('static const int virtual_files_count = sizeof(virtual_files) / sizeof(virtual_files[0]);\n\n')
+
+ header.write('bool virtual_file_system(const char* path, const unsigned char** file, int* length) {\n')
+ header.write(' for (int i = 0; i < virtual_files_count; ++i) {\n')
+ header.write(' if (strcmp(virtual_files[i].path, path) == 0) {\n')
+ header.write(' *file = virtual_files[i].data;\n')
+ header.write(' *length = virtual_files[i].length;\n')
+ header.write(' return true;\n')
+ header.write(' }\n')
+ header.write(' }\n')
+ header.write(' return false;\n')
+ header.write('}\n\n')
+
+ header.write('const void* vfs(const char* path, int* length) {\n')
+ header.write(' const unsigned char* file_data;\n')
+ header.write(' int file_length;\n\n')
+
+ header.write(' if (virtual_file_system(path, &file_data, &file_length)) {\n')
+ header.write(' const char* content_type = webui_get_mime_type(path);\n')
+ header.write(' const char* http_header_template = "HTTP/1.1 200 OK\\r\\n"\n')
+ header.write(' "Content-Type: %s\\r\\n"\n')
+ header.write(' "Content-Length: %d\\r\\n"\n')
+ header.write(' "Cache-Control: no-cache\\r\\n\\r\\n";\n')
+ header.write(' int header_length = snprintf(NULL, 0, http_header_template, content_type, file_length);\n')
+ header.write(' *length = header_length + file_length;\n')
+ header.write(' unsigned char* response = (unsigned char*) webui_malloc(*length);\n')
+ header.write(' snprintf((char*) response, header_length + 1, http_header_template, content_type, file_length);\n')
+ header.write(' memcpy(response + header_length, file_data, file_length);\n')
+ header.write(' return response;\n')
+ header.write(' }\n')
+ header.write(' return NULL;\n')
+ header.write('}\n\n')
+
+ header.write('#endif // VIRTUAL_FILE_SYSTEM_H\n')
+
+if __name__ == '__main__':
+ if len(sys.argv) != 3:
+ print(f'Usage: {sys.argv[0]} ')
+ sys.exit(1)
+
+ directory = sys.argv[1]
+ output_header = sys.argv[2]
+ generate_vfs_header(directory, output_header)
+ print(f'Generated {output_header} from {directory}')
diff --git a/examples/C++/virtual_file_system/GNUmakefile b/examples/C++/virtual_file_system/GNUmakefile
new file mode 100644
index 0000000..2b085f5
--- /dev/null
+++ b/examples/C++/virtual_file_system/GNUmakefile
@@ -0,0 +1,138 @@
+# WebUI C++ Example
+
+# == 1. VARIABLES =============================================================
+
+MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
+PROJECT_DIR := $(dir $(MAKEFILE_PATH))/../../../
+TARGET := $(firstword $(MAKECMDGOALS))
+LIB_DIR := $(PROJECT_DIR)/dist
+ifeq ($(TARGET), debug)
+LIB_DIR := $(LIB_DIR)/debug
+endif
+INCLUDE_DIR := $(PROJECT_DIR)/include
+WEBUI_LIB_NAME = webui-2
+ifeq ($(WEBUI_USE_TLS), 1)
+WEBUI_LIB_NAME = webui-2-secure
+endif
+
+# ARGS
+# Set a compiler when running on Linux via `make CC=g++` / `make CC=clang`
+CC = g++
+# Build the WebUI library if running via `make BUILD_LIB=true`
+BUILD_LIB ?=
+
+# BUILD FLAGS
+STATIC_BUILD_FLAGS = main.cpp -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+DYN_BUILD_FLAGS = main.cpp -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+
+# Platform conditions
+ifeq ($(OS),Windows_NT)
+ # Windows
+ PLATFORM := windows
+ SHELL := CMD
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lws2_32 -Wall -luser32 -lstdc++ -luuid -static
+ COPY_LIB_CMD := @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ DYN_BUILD_FLAGS += "$(WEBUI_LIB_NAME).dll" -lws2_32 -Wall -luser32 -lstdc++ -luuid
+ STATIC_OUT := main.exe
+ DYN_OUT := main-dyn.exe
+ LWS2_OPT := -lws2_32 -lole32
+ STRIP_OPT := --strip-all
+ CONSOLE_APP := -Wl,-subsystem=console
+ GUI_APP := -Wl,-subsystem=windows
+else
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lpthread -lm -ldl
+ DYN_BUILD_FLAGS += -l$(WEBUI_LIB_NAME) -lpthread -lm -ldl
+ STATIC_OUT := main
+ DYN_OUT := main-dyn
+ ifeq ($(shell uname),Darwin)
+ # MacOS
+ PLATFORM := macos
+ CC = clang
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).dylib" "lib$(WEBUI_LIB_NAME).dylib"
+ WKWEBKIT_LINK_FLAGS := -framework Cocoa -framework WebKit
+ else
+ # Linux
+ PLATFORM := linux
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).so" "lib$(WEBUI_LIB_NAME).so"
+ STRIP_OPT := --strip-all
+ ifeq ($(CC),clang)
+ LLVM_OPT := llvm-
+ endif
+ endif
+endif
+
+# == 2.TARGETS ================================================================
+
+all: release
+
+debug: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE) debug
+endif
+# Static with Debug info
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C++ Example ($(CC) debug static)..."
+ @$(CC) -g $(CONSOLE_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+endif
+# Dynamic with Debug info
+ @echo "Build C++ Example ($(CC) debug dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) -g $(CONSOLE_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+release: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE)
+endif
+# Static Release
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C++ Example ($(CC) release static)..."
+ @$(CC) -Os $(GUI_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(STATIC_OUT)
+endif
+# Dynamic Release
+ @echo "Build C++ Example ($(CC) release dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) $(GUI_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+clean: --clean-$(PLATFORM)
+
+# INTERNAL TARGETS
+
+--validate-args:
+ifneq ($(filter $(CC),g++ clang aarch64-linux-gnu-g++ arm-linux-gnueabihf-g++ musl-g++),$(CC))
+$(error Invalid compiler specified: `$(CC)`)
+endif
+
+--clean-linux: --clean-unix
+
+--clean-macos: --clean-unix
+
+--clean-unix:
+ - rm -f *.o
+ - rm -f *.a
+ - rm -f *.so
+ - rm -f *.dylib
+ - rm -rf *.dSYM
+
+--clean-windows:
+ - del *.o >nul 2>&1
+ - del *.dll >nul 2>&1
+ - del *.a >nul 2>&1
+ - del *.exe >nul 2>&1
diff --git a/examples/C++/virtual_file_system/Makefile b/examples/C++/virtual_file_system/Makefile
new file mode 100644
index 0000000..d056ecd
--- /dev/null
+++ b/examples/C++/virtual_file_system/Makefile
@@ -0,0 +1,65 @@
+# WebUI C++ Example
+# Windows - Microsoft Visual C++
+
+SHELL = CMD
+LIB_DIR = ../../../dist
+INCLUDE_DIR = ../../../include
+WEBUI_LIB_NAME = webui-2
+!IF "$(WEBUI_USE_TLS)" == "1"
+WEBUI_LIB_NAME = webui-2-secure
+!ENDIF
+
+# Build the WebUI library if running `nmake BUILD_LIB=true`
+BUILD_LIB =
+
+all: release
+
+debug:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE) debug
+!ENDIF
+# Static with Debug info
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C++ Example (Debug Static)...
+ @cl /Zi /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)/debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic with Debug info
+ @echo Build C++ Example (Debug Dynamic)...
+ @copy "$(LIB_DIR)\debug\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /Zi /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)/debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+release:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE)
+!ENDIF
+# Static Release
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C++ Example (Release Static)...
+ @cl /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic Release
+ @echo Build C++ Example (Release Dynamic)...
+ @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /EHsc /std:c++17 main.cpp /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+clean:
+ - del *.obj >nul 2>&1
+ - del *.ilk >nul 2>&1
+ - del *.pdb >nul 2>&1
+ - del *.exp >nul 2>&1
+ - del *.exe >nul 2>&1
+ - del *.lib >nul 2>&1
diff --git a/examples/C++/virtual_file_system/main.cpp b/examples/C++/virtual_file_system/main.cpp
new file mode 100644
index 0000000..a2ff9bf
--- /dev/null
+++ b/examples/C++/virtual_file_system/main.cpp
@@ -0,0 +1,57 @@
+// Virtual File System Example C++
+
+#include "webui.hpp"
+#include "vfs.h"
+
+class VirtualFileSystemApp {
+public:
+ VirtualFileSystemApp() {
+
+ // Bind the "Exit" button in the HTML to the exit_app() method in C++
+ win.bind("Exit", this, &VirtualFileSystemApp::exit_app);
+
+ // VSF (Virtual File System) C++ Example
+ //
+ // 1. Run Python script to generate header file of a folder
+ // python vfs.py "/path/to/folder" "vfs.h"
+ //
+ // 2. Include header file in your C++ project
+ // #include "vfs.h"
+ //
+ // 3. Use vfs in your custom files handler `webui::window::set_file_handler()`
+ // win.set_file_handler(vfs);
+
+ win.set_file_handler(vfs);
+ }
+
+ void run() {
+ // Show the main page (index.html) in the WebView/Browser window
+ win.show("index.html");
+ // win.show_browser("index.html", webui_browser::Chrome);
+ // win.show_wv("index.html");
+
+ // Wait until the window gets closed
+ webui::wait();
+
+ // Clean up WebUI resources. This is optional, but recommended.
+ webui::clean();
+ }
+
+private:
+ webui::window win;
+
+ void exit_app(webui::window::event* e) {
+ // Exit the application, and close all windows. `webui::wait()` will return (Break).
+ webui::exit();
+ }
+};
+
+int main() {
+ VirtualFileSystemApp app;
+ app.run();
+ return 0;
+}
+
+#if defined(_MSC_VER)
+int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) { return main(); }
+#endif
diff --git a/examples/C++/virtual_file_system/ui/index.html b/examples/C++/virtual_file_system/ui/index.html
new file mode 100644
index 0000000..7c04de4
--- /dev/null
+++ b/examples/C++/virtual_file_system/ui/index.html
@@ -0,0 +1,135 @@
+
+
+
+
+ WebUI - Virtual File System C++
+
+
+
+ Virtual File System C++ Example
+
+
+
+
+ This file is embedded in this C++ application.
+
+
+
+ Exit
+
+
+
+
+
+
+
diff --git a/examples/C++/virtual_file_system/ui/sub/index.html b/examples/C++/virtual_file_system/ui/sub/index.html
new file mode 100644
index 0000000..7fa3dc3
--- /dev/null
+++ b/examples/C++/virtual_file_system/ui/sub/index.html
@@ -0,0 +1,64 @@
+
+
+
+
+ WebUI - Virtual File System C++
+
+
+
+
+ This is another file embedded in this C++ application.
+
+
+ Exit
+
+
+
+
+
+
diff --git a/examples/C++/virtual_file_system/ui/svg/webui.svg b/examples/C++/virtual_file_system/ui/svg/webui.svg
new file mode 100644
index 0000000..5cf0cf7
--- /dev/null
+++ b/examples/C++/virtual_file_system/ui/svg/webui.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/examples/C++/virtual_file_system/vfs.h b/examples/C++/virtual_file_system/vfs.h
new file mode 100644
index 0000000..5910e4e
--- /dev/null
+++ b/examples/C++/virtual_file_system/vfs.h
@@ -0,0 +1,68 @@
+#ifndef VIRTUAL_FILE_SYSTEM_H
+#define VIRTUAL_FILE_SYSTEM_H
+
+typedef struct {
+ const char *path;
+ const unsigned char *data;
+ int length;
+} VirtualFile;
+
+static const unsigned char FILE_0[] = {0x3c,0x21,0x64,0x6f,0x63,0x74,0x79,0x70,0x65,0x20,0x68,0x74,0x6d,0x6c,0x3e,0x0a,0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0a,0x09,0x3c,0x68,0x65,0x61,0x64,0x3e,0x0a,0x09,0x09,0x3c,0x6d,0x65,0x74,0x61,0x20,0x63,0x68,0x61,0x72,0x73,0x65,0x74,0x3d,0x22,0x55,0x54,0x46,0x2d,0x38,0x22,0x20,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x74,0x69,0x74,0x6c,0x65,0x3e,0x57,0x65,0x62,0x55,0x49,0x20,0x2d,0x20,0x56,0x69,0x72,0x74,0x75,0x61,0x6c,0x20,0x46,0x69,0x6c,0x65,0x20,0x53,0x79,0x73,0x74,0x65,0x6d,0x20,0x43,0x2b,0x2b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x0a,0x09,0x09,0x3c,0x73,0x74,0x79,0x6c,0x65,0x3e,0x0a,0x09,0x09,0x09,0x62,0x6f,0x64,0x79,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x66,0x6f,0x6e,0x74,0x2d,0x66,0x61,0x6d,0x69,0x6c,0x79,0x3a,0x20,0x27,0x41,0x72,0x69,0x61,0x6c,0x27,0x2c,0x20,0x73,0x61,0x6e,0x73,0x2d,0x73,0x65,0x72,0x69,0x66,0x3b,0x0a,0x09,0x09,0x09,0x09,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x20,0x77,0x68,0x69,0x74,0x65,0x3b,0x0a,0x09,0x09,0x09,0x09,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3a,0x20,0x6c,0x69,0x6e,0x65,0x61,0x72,0x2d,0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x28,0x74,0x6f,0x20,0x72,0x69,0x67,0x68,0x74,0x2c,0x20,0x23,0x35,0x30,0x37,0x64,0x39,0x31,0x2c,0x20,0x23,0x31,0x63,0x35,0x39,0x36,0x66,0x2c,0x20,0x23,0x30,0x32,0x32,0x37,0x33,0x37,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x74,0x65,0x78,0x74,0x2d,0x61,0x6c,0x69,0x67,0x6e,0x3a,0x20,0x63,0x65,0x6e,0x74,0x65,0x72,0x3b,0x0a,0x09,0x09,0x09,0x09,0x66,0x6f,0x6e,0x74,0x2d,0x73,0x69,0x7a,0x65,0x3a,0x20,0x31,0x38,0x70,0x78,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x62,0x75,0x74,0x74,0x6f,0x6e,0x2c,0x0a,0x09,0x09,0x09,0x69,0x6e,0x70,0x75,0x74,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x20,0x31,0x30,0x70,0x78,0x3b,0x0a,0x09,0x09,0x09,0x09,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x72,0x61,0x64,0x69,0x75,0x73,0x3a,0x20,0x33,0x70,0x78,0x3b,0x0a,0x09,0x09,0x09,0x09,0x62,0x6f,0x72,0x64,0x65,0x72,0x3a,0x20,0x31,0x70,0x78,0x20,0x73,0x6f,0x6c,0x69,0x64,0x20,0x23,0x63,0x63,0x63,0x3b,0x0a,0x09,0x09,0x09,0x09,0x62,0x6f,0x78,0x2d,0x73,0x68,0x61,0x64,0x6f,0x77,0x3a,0x20,0x30,0x20,0x33,0x70,0x78,0x20,0x35,0x70,0x78,0x20,0x72,0x67,0x62,0x61,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2e,0x31,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x74,0x72,0x61,0x6e,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x30,0x2e,0x32,0x73,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x62,0x75,0x74,0x74,0x6f,0x6e,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3a,0x20,0x23,0x33,0x34,0x39,0x38,0x64,0x62,0x3b,0x0a,0x09,0x09,0x09,0x09,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x20,0x23,0x66,0x66,0x66,0x3b,0x0a,0x09,0x09,0x09,0x09,0x63,0x75,0x72,0x73,0x6f,0x72,0x3a,0x20,0x70,0x6f,0x69,0x6e,0x74,0x65,0x72,0x3b,0x0a,0x09,0x09,0x09,0x09,0x66,0x6f,0x6e,0x74,0x2d,0x73,0x69,0x7a,0x65,0x3a,0x20,0x31,0x36,0x70,0x78,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x68,0x31,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x74,0x65,0x78,0x74,0x2d,0x73,0x68,0x61,0x64,0x6f,0x77,0x3a,0x20,0x2d,0x37,0x70,0x78,0x20,0x31,0x30,0x70,0x78,0x20,0x37,0x70,0x78,0x20,0x72,0x67,0x62,0x28,0x36,0x37,0x20,0x35,0x37,0x20,0x35,0x37,0x20,0x2f,0x20,0x37,0x36,0x25,0x29,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x62,0x75,0x74,0x74,0x6f,0x6e,0x3a,0x68,0x6f,0x76,0x65,0x72,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3a,0x20,0x23,0x63,0x39,0x39,0x31,0x33,0x64,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x69,0x6e,0x70,0x75,0x74,0x3a,0x66,0x6f,0x63,0x75,0x73,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x6f,0x75,0x74,0x6c,0x69,0x6e,0x65,0x3a,0x20,0x6e,0x6f,0x6e,0x65,0x3b,0x0a,0x09,0x09,0x09,0x09,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x20,0x23,0x33,0x34,0x39,0x38,0x64,0x62,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x0a,0x09,0x09,0x09,0x61,0x3a,0x6c,0x69,0x6e,0x6b,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x20,0x23,0x66,0x64,0x35,0x37,0x32,0x33,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x61,0x3a,0x61,0x63,0x74,0x69,0x76,0x65,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x20,0x23,0x66,0x64,0x35,0x37,0x32,0x33,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x61,0x3a,0x76,0x69,0x73,0x69,0x74,0x65,0x64,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x20,0x23,0x66,0x64,0x35,0x37,0x32,0x33,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x61,0x3a,0x68,0x6f,0x76,0x65,0x72,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x20,0x23,0x66,0x30,0x62,0x63,0x61,0x63,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x3c,0x2f,0x73,0x74,0x79,0x6c,0x65,0x3e,0x0a,0x09,0x3c,0x2f,0x68,0x65,0x61,0x64,0x3e,0x0a,0x09,0x3c,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x09,0x09,0x3c,0x68,0x33,0x20,0x69,0x64,0x3d,0x22,0x74,0x69,0x74,0x6c,0x65,0x22,0x3e,0x56,0x69,0x72,0x74,0x75,0x61,0x6c,0x20,0x46,0x69,0x6c,0x65,0x20,0x53,0x79,0x73,0x74,0x65,0x6d,0x20,0x43,0x2b,0x2b,0x20,0x45,0x78,0x61,0x6d,0x70,0x6c,0x65,0x3c,0x2f,0x68,0x33,0x3e,0x0a,0x09,0x09,0x3c,0x62,0x72,0x20,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x73,0x76,0x67,0x2f,0x77,0x65,0x62,0x75,0x69,0x2e,0x73,0x76,0x67,0x22,0x3e,0x0a,0x09,0x09,0x3c,0x62,0x72,0x20,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x3e,0x0a,0x09,0x09,0x09,0x54,0x68,0x69,0x73,0x20,0x66,0x69,0x6c,0x65,0x20,0x69,0x73,0x20,0x65,0x6d,0x62,0x65,0x64,0x64,0x65,0x64,0x20,0x69,0x6e,0x20,0x74,0x68,0x69,0x73,0x20,0x43,0x2b,0x2b,0x20,0x61,0x70,0x70,0x6c,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2e,0x3c,0x62,0x72,0x20,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x2f,0x70,0x3e,0x0a,0x09,0x09,0x3c,0x68,0x34,0x3e,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x73,0x75,0x62,0x22,0x3e,0x2f,0x73,0x75,0x62,0x3c,0x2f,0x61,0x3e,0x3c,0x2f,0x68,0x34,0x3e,0x0a,0x09,0x09,0x3c,0x62,0x72,0x20,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x62,0x75,0x74,0x74,0x6f,0x6e,0x20,0x69,0x64,0x3d,0x22,0x45,0x78,0x69,0x74,0x22,0x3e,0x45,0x78,0x69,0x74,0x3c,0x2f,0x62,0x75,0x74,0x74,0x6f,0x6e,0x3e,0x0a,0x09,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x0a,0x09,0x3c,0x21,0x2d,0x2d,0x20,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x20,0x74,0x68,0x69,0x73,0x20,0x77,0x69,0x6e,0x64,0x6f,0x77,0x20,0x74,0x6f,0x20,0x74,0x68,0x65,0x20,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x20,0x61,0x70,0x70,0x20,0x2d,0x2d,0x3e,0x0a,0x09,0x3c,0x73,0x63,0x72,0x69,0x70,0x74,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x77,0x65,0x62,0x75,0x69,0x2e,0x6a,0x73,0x22,0x3e,0x3c,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x3e,0x0a,0x0a,0x09,0x3c,0x73,0x63,0x72,0x69,0x70,0x74,0x3e,0x0a,0x0a,0x09,0x09,0x2f,0x2f,0x20,0x4a,0x61,0x76,0x61,0x53,0x63,0x72,0x69,0x70,0x74,0x20,0x45,0x78,0x61,0x6d,0x70,0x6c,0x65,0x0a,0x09,0x09,0x2f,0x2a,0x0a,0x09,0x09,0x64,0x6f,0x63,0x75,0x6d,0x65,0x6e,0x74,0x2e,0x61,0x64,0x64,0x45,0x76,0x65,0x6e,0x74,0x4c,0x69,0x73,0x74,0x65,0x6e,0x65,0x72,0x28,0x27,0x44,0x4f,0x4d,0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x4c,0x6f,0x61,0x64,0x65,0x64,0x27,0x2c,0x20,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x29,0x20,0x7b,0x0a,0x09,0x09,0x09,0x2f,0x2f,0x20,0x44,0x4f,0x4d,0x20,0x69,0x73,0x20,0x6c,0x6f,0x61,0x64,0x65,0x64,0x2e,0x20,0x43,0x68,0x65,0x63,0x6b,0x20,0x69,0x66,0x20,0x60,0x77,0x65,0x62,0x75,0x69,0x60,0x20,0x6f,0x62,0x6a,0x65,0x63,0x74,0x20,0x69,0x73,0x20,0x61,0x76,0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x0a,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x74,0x79,0x70,0x65,0x6f,0x66,0x20,0x77,0x65,0x62,0x75,0x69,0x20,0x21,0x3d,0x3d,0x20,0x27,0x75,0x6e,0x64,0x65,0x66,0x69,0x6e,0x65,0x64,0x27,0x29,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x53,0x65,0x74,0x20,0x65,0x76,0x65,0x6e,0x74,0x73,0x20,0x63,0x61,0x6c,0x6c,0x62,0x61,0x63,0x6b,0x0a,0x09,0x09,0x09,0x09,0x77,0x65,0x62,0x75,0x69,0x2e,0x73,0x65,0x74,0x45,0x76,0x65,0x6e,0x74,0x43,0x61,0x6c,0x6c,0x62,0x61,0x63,0x6b,0x28,0x28,0x65,0x29,0x20,0x3d,0x3e,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x65,0x20,0x3d,0x3d,0x20,0x77,0x65,0x62,0x75,0x69,0x2e,0x65,0x76,0x65,0x6e,0x74,0x2e,0x43,0x4f,0x4e,0x4e,0x45,0x43,0x54,0x45,0x44,0x29,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x20,0x74,0x6f,0x20,0x74,0x68,0x65,0x20,0x62,0x61,0x63,0x6b,0x65,0x6e,0x64,0x20,0x69,0x73,0x20,0x65,0x73,0x74,0x61,0x62,0x6c,0x69,0x73,0x68,0x65,0x64,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x6c,0x6f,0x67,0x28,0x27,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x65,0x64,0x2e,0x27,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x77,0x65,0x62,0x75,0x69,0x54,0x65,0x73,0x74,0x28,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x69,0x66,0x20,0x28,0x65,0x20,0x3d,0x3d,0x20,0x77,0x65,0x62,0x75,0x69,0x2e,0x65,0x76,0x65,0x6e,0x74,0x2e,0x44,0x49,0x53,0x43,0x4f,0x4e,0x4e,0x45,0x43,0x54,0x45,0x44,0x29,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x69,0x6f,0x6e,0x20,0x74,0x6f,0x20,0x74,0x68,0x65,0x20,0x62,0x61,0x63,0x6b,0x65,0x6e,0x64,0x20,0x69,0x73,0x20,0x6c,0x6f,0x73,0x74,0x0a,0x09,0x09,0x09,0x09,0x09,0x09,0x63,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x2e,0x6c,0x6f,0x67,0x28,0x27,0x44,0x69,0x73,0x63,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x65,0x64,0x2e,0x27,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x09,0x7d,0x29,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x20,0x65,0x6c,0x73,0x65,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x54,0x68,0x65,0x20,0x76,0x69,0x72,0x74,0x75,0x61,0x6c,0x20,0x66,0x69,0x6c,0x65,0x20,0x60,0x77,0x65,0x62,0x75,0x69,0x2e,0x6a,0x73,0x60,0x20,0x69,0x73,0x20,0x6e,0x6f,0x74,0x20,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x64,0x0a,0x09,0x09,0x09,0x09,0x61,0x6c,0x65,0x72,0x74,0x28,0x27,0x50,0x6c,0x65,0x61,0x73,0x65,0x20,0x61,0x64,0x64,0x20,0x77,0x65,0x62,0x75,0x69,0x2e,0x6a,0x73,0x20,0x74,0x6f,0x20,0x79,0x6f,0x75,0x72,0x20,0x48,0x54,0x4d,0x4c,0x2e,0x27,0x29,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x7d,0x29,0x3b,0x0a,0x0a,0x09,0x09,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x20,0x77,0x65,0x62,0x75,0x69,0x54,0x65,0x73,0x74,0x28,0x29,0x20,0x7b,0x0a,0x09,0x09,0x09,0x2f,0x2f,0x20,0x43,0x61,0x6c,0x6c,0x20,0x61,0x20,0x62,0x61,0x63,0x6b,0x65,0x6e,0x64,0x20,0x66,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x0a,0x09,0x09,0x09,0x69,0x66,0x20,0x28,0x77,0x65,0x62,0x75,0x69,0x2e,0x69,0x73,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x65,0x64,0x28,0x29,0x29,0x20,0x7b,0x0a,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x57,0x68,0x65,0x6e,0x20,0x79,0x6f,0x75,0x20,0x62,0x69,0x6e,0x64,0x20,0x61,0x20,0x66,0x75,0x6e,0x63,0x20,0x69,0x6e,0x20,0x74,0x68,0x65,0x20,0x62,0x61,0x63,0x6b,0x65,0x6e,0x64,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x77,0x65,0x62,0x75,0x69,0x20,0x77,0x69,0x6c,0x6c,0x20,0x63,0x72,0x65,0x61,0x74,0x65,0x20,0x74,0x68,0x65,0x20,0x60,0x66,0x75,0x6e,0x63,0x60,0x20,0x6f,0x62,0x6a,0x65,0x63,0x74,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x69,0x6e,0x20,0x74,0x68,0x72,0x65,0x65,0x20,0x70,0x6c,0x61,0x63,0x65,0x73,0x3a,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x47,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x20,0x20,0x3a,0x20,0x66,0x75,0x6e,0x63,0x28,0x2e,0x2e,0x2e,0x29,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x50,0x72,0x6f,0x70,0x65,0x72,0x74,0x79,0x20,0x3a,0x20,0x77,0x65,0x62,0x75,0x69,0x2e,0x66,0x75,0x6e,0x63,0x28,0x2e,0x2e,0x2e,0x29,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x4d,0x65,0x74,0x68,0x6f,0x64,0x20,0x20,0x20,0x3a,0x20,0x77,0x65,0x62,0x75,0x69,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x27,0x66,0x75,0x6e,0x63,0x27,0x2c,0x20,0x2e,0x2e,0x2e,0x29,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x5b,0x21,0x5d,0x20,0x4e,0x6f,0x74,0x65,0x3a,0x20,0x4f,0x62,0x6a,0x65,0x63,0x74,0x73,0x20,0x63,0x72,0x65,0x61,0x74,0x69,0x6f,0x6e,0x20,0x66,0x61,0x69,0x6c,0x73,0x20,0x77,0x68,0x65,0x6e,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x61,0x20,0x73,0x69,0x6d,0x69,0x6c,0x61,0x72,0x20,0x6f,0x62,0x6a,0x65,0x63,0x74,0x20,0x61,0x6c,0x72,0x65,0x61,0x64,0x79,0x20,0x65,0x78,0x69,0x73,0x74,0x2e,0x0a,0x0a,0x09,0x09,0x09,0x09,0x63,0x6f,0x6e,0x73,0x74,0x20,0x66,0x6f,0x6f,0x20,0x3d,0x20,0x27,0x48,0x65,0x6c,0x6c,0x6f,0x27,0x3b,0x0a,0x09,0x09,0x09,0x09,0x63,0x6f,0x6e,0x73,0x74,0x20,0x62,0x61,0x72,0x20,0x3d,0x20,0x31,0x32,0x33,0x34,0x35,0x36,0x3b,0x0a,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x43,0x61,0x6c,0x6c,0x69,0x6e,0x67,0x20,0x61,0x73,0x20,0x67,0x6c,0x6f,0x62,0x61,0x6c,0x20,0x6f,0x62,0x6a,0x65,0x63,0x74,0x0a,0x09,0x09,0x09,0x09,0x6d,0x79,0x42,0x61,0x63,0x6b,0x65,0x6e,0x64,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x66,0x6f,0x6f,0x2c,0x20,0x62,0x61,0x72,0x29,0x2e,0x74,0x68,0x65,0x6e,0x28,0x28,0x72,0x65,0x73,0x70,0x6f,0x6e,0x73,0x65,0x29,0x20,0x3d,0x3e,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x44,0x6f,0x20,0x73,0x6f,0x6d,0x65,0x74,0x68,0x69,0x6e,0x67,0x20,0x77,0x69,0x74,0x68,0x20,0x60,0x72,0x65,0x73,0x70,0x6f,0x6e,0x73,0x65,0x60,0x0a,0x09,0x09,0x09,0x09,0x7d,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x43,0x61,0x6c,0x6c,0x69,0x6e,0x67,0x20,0x61,0x73,0x20,0x70,0x72,0x6f,0x70,0x65,0x72,0x74,0x79,0x20,0x6f,0x66,0x20,0x60,0x77,0x65,0x62,0x75,0x69,0x2e,0x60,0x20,0x6f,0x62,0x6a,0x65,0x63,0x74,0x0a,0x09,0x09,0x09,0x09,0x77,0x65,0x62,0x75,0x69,0x2e,0x6d,0x79,0x42,0x61,0x63,0x6b,0x65,0x6e,0x64,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x66,0x6f,0x6f,0x2c,0x20,0x62,0x61,0x72,0x29,0x2e,0x74,0x68,0x65,0x6e,0x28,0x28,0x72,0x65,0x73,0x70,0x6f,0x6e,0x73,0x65,0x29,0x20,0x3d,0x3e,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x44,0x6f,0x20,0x73,0x6f,0x6d,0x65,0x74,0x68,0x69,0x6e,0x67,0x20,0x77,0x69,0x74,0x68,0x20,0x60,0x72,0x65,0x73,0x70,0x6f,0x6e,0x73,0x65,0x60,0x0a,0x09,0x09,0x09,0x09,0x7d,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x43,0x61,0x6c,0x6c,0x69,0x6e,0x67,0x20,0x75,0x73,0x69,0x6e,0x67,0x20,0x74,0x68,0x65,0x20,0x6d,0x65,0x74,0x68,0x6f,0x64,0x20,0x60,0x77,0x65,0x62,0x75,0x69,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x29,0x60,0x0a,0x09,0x09,0x09,0x09,0x77,0x65,0x62,0x75,0x69,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x27,0x6d,0x79,0x42,0x61,0x63,0x6b,0x65,0x6e,0x64,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x27,0x2c,0x20,0x66,0x6f,0x6f,0x2c,0x20,0x62,0x61,0x72,0x29,0x2e,0x74,0x68,0x65,0x6e,0x28,0x28,0x72,0x65,0x73,0x70,0x6f,0x6e,0x73,0x65,0x29,0x20,0x3d,0x3e,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x44,0x6f,0x20,0x73,0x6f,0x6d,0x65,0x74,0x68,0x69,0x6e,0x67,0x20,0x77,0x69,0x74,0x68,0x20,0x60,0x72,0x65,0x73,0x70,0x6f,0x6e,0x73,0x65,0x60,0x0a,0x09,0x09,0x09,0x09,0x7d,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x55,0x73,0x69,0x6e,0x67,0x20,0x61,0x77,0x61,0x69,0x74,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x72,0x65,0x73,0x70,0x6f,0x6e,0x73,0x65,0x20,0x3d,0x20,0x61,0x77,0x61,0x69,0x74,0x20,0x6d,0x79,0x42,0x61,0x63,0x6b,0x65,0x6e,0x64,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x66,0x6f,0x6f,0x2c,0x20,0x62,0x61,0x72,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x72,0x65,0x73,0x70,0x6f,0x6e,0x73,0x65,0x20,0x3d,0x20,0x61,0x77,0x61,0x69,0x74,0x20,0x77,0x65,0x62,0x75,0x69,0x2e,0x6d,0x79,0x42,0x61,0x63,0x6b,0x65,0x6e,0x64,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x28,0x66,0x6f,0x6f,0x2c,0x20,0x62,0x61,0x72,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x2f,0x2f,0x20,0x63,0x6f,0x6e,0x73,0x74,0x20,0x72,0x65,0x73,0x70,0x6f,0x6e,0x73,0x65,0x20,0x3d,0x20,0x61,0x77,0x61,0x69,0x74,0x20,0x77,0x65,0x62,0x75,0x69,0x2e,0x63,0x61,0x6c,0x6c,0x28,0x27,0x6d,0x79,0x42,0x61,0x63,0x6b,0x65,0x6e,0x64,0x46,0x75,0x6e,0x63,0x74,0x69,0x6f,0x6e,0x27,0x2c,0x20,0x66,0x6f,0x6f,0x2c,0x20,0x62,0x61,0x72,0x29,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x7d,0x0a,0x09,0x09,0x2a,0x2f,0x0a,0x0a,0x09,0x3c,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x3e,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0a};
+
+static const unsigned char FILE_1[] = {0x3c,0x21,0x64,0x6f,0x63,0x74,0x79,0x70,0x65,0x20,0x68,0x74,0x6d,0x6c,0x3e,0x0a,0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0a,0x09,0x3c,0x68,0x65,0x61,0x64,0x3e,0x0a,0x09,0x09,0x3c,0x6d,0x65,0x74,0x61,0x20,0x63,0x68,0x61,0x72,0x73,0x65,0x74,0x3d,0x22,0x55,0x54,0x46,0x2d,0x38,0x22,0x20,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x74,0x69,0x74,0x6c,0x65,0x3e,0x57,0x65,0x62,0x55,0x49,0x20,0x2d,0x20,0x56,0x69,0x72,0x74,0x75,0x61,0x6c,0x20,0x46,0x69,0x6c,0x65,0x20,0x53,0x79,0x73,0x74,0x65,0x6d,0x20,0x43,0x2b,0x2b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x0a,0x09,0x09,0x3c,0x73,0x74,0x79,0x6c,0x65,0x3e,0x0a,0x09,0x09,0x09,0x62,0x6f,0x64,0x79,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x66,0x6f,0x6e,0x74,0x2d,0x66,0x61,0x6d,0x69,0x6c,0x79,0x3a,0x20,0x27,0x41,0x72,0x69,0x61,0x6c,0x27,0x2c,0x20,0x73,0x61,0x6e,0x73,0x2d,0x73,0x65,0x72,0x69,0x66,0x3b,0x0a,0x09,0x09,0x09,0x09,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x20,0x77,0x68,0x69,0x74,0x65,0x3b,0x0a,0x09,0x09,0x09,0x09,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3a,0x20,0x6c,0x69,0x6e,0x65,0x61,0x72,0x2d,0x67,0x72,0x61,0x64,0x69,0x65,0x6e,0x74,0x28,0x74,0x6f,0x20,0x72,0x69,0x67,0x68,0x74,0x2c,0x20,0x23,0x35,0x30,0x37,0x64,0x39,0x31,0x2c,0x20,0x23,0x31,0x63,0x35,0x39,0x36,0x66,0x2c,0x20,0x23,0x30,0x32,0x32,0x37,0x33,0x37,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x74,0x65,0x78,0x74,0x2d,0x61,0x6c,0x69,0x67,0x6e,0x3a,0x20,0x63,0x65,0x6e,0x74,0x65,0x72,0x3b,0x0a,0x09,0x09,0x09,0x09,0x66,0x6f,0x6e,0x74,0x2d,0x73,0x69,0x7a,0x65,0x3a,0x20,0x31,0x38,0x70,0x78,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x62,0x75,0x74,0x74,0x6f,0x6e,0x2c,0x0a,0x09,0x09,0x09,0x69,0x6e,0x70,0x75,0x74,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x70,0x61,0x64,0x64,0x69,0x6e,0x67,0x3a,0x20,0x31,0x30,0x70,0x78,0x3b,0x0a,0x09,0x09,0x09,0x09,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x72,0x61,0x64,0x69,0x75,0x73,0x3a,0x20,0x33,0x70,0x78,0x3b,0x0a,0x09,0x09,0x09,0x09,0x62,0x6f,0x72,0x64,0x65,0x72,0x3a,0x20,0x31,0x70,0x78,0x20,0x73,0x6f,0x6c,0x69,0x64,0x20,0x23,0x63,0x63,0x63,0x3b,0x0a,0x09,0x09,0x09,0x09,0x62,0x6f,0x78,0x2d,0x73,0x68,0x61,0x64,0x6f,0x77,0x3a,0x20,0x30,0x20,0x33,0x70,0x78,0x20,0x35,0x70,0x78,0x20,0x72,0x67,0x62,0x61,0x28,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2e,0x31,0x29,0x3b,0x0a,0x09,0x09,0x09,0x09,0x74,0x72,0x61,0x6e,0x73,0x69,0x74,0x69,0x6f,0x6e,0x3a,0x20,0x30,0x2e,0x32,0x73,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x62,0x75,0x74,0x74,0x6f,0x6e,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3a,0x20,0x23,0x33,0x34,0x39,0x38,0x64,0x62,0x3b,0x0a,0x09,0x09,0x09,0x09,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x20,0x23,0x66,0x66,0x66,0x3b,0x0a,0x09,0x09,0x09,0x09,0x63,0x75,0x72,0x73,0x6f,0x72,0x3a,0x20,0x70,0x6f,0x69,0x6e,0x74,0x65,0x72,0x3b,0x0a,0x09,0x09,0x09,0x09,0x66,0x6f,0x6e,0x74,0x2d,0x73,0x69,0x7a,0x65,0x3a,0x20,0x31,0x36,0x70,0x78,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x68,0x31,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x74,0x65,0x78,0x74,0x2d,0x73,0x68,0x61,0x64,0x6f,0x77,0x3a,0x20,0x2d,0x37,0x70,0x78,0x20,0x31,0x30,0x70,0x78,0x20,0x37,0x70,0x78,0x20,0x72,0x67,0x62,0x28,0x36,0x37,0x20,0x35,0x37,0x20,0x35,0x37,0x20,0x2f,0x20,0x37,0x36,0x25,0x29,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x62,0x75,0x74,0x74,0x6f,0x6e,0x3a,0x68,0x6f,0x76,0x65,0x72,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x3a,0x20,0x23,0x63,0x39,0x39,0x31,0x33,0x64,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x69,0x6e,0x70,0x75,0x74,0x3a,0x66,0x6f,0x63,0x75,0x73,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x6f,0x75,0x74,0x6c,0x69,0x6e,0x65,0x3a,0x20,0x6e,0x6f,0x6e,0x65,0x3b,0x0a,0x09,0x09,0x09,0x09,0x62,0x6f,0x72,0x64,0x65,0x72,0x2d,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x20,0x23,0x33,0x34,0x39,0x38,0x64,0x62,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x0a,0x09,0x09,0x09,0x61,0x3a,0x6c,0x69,0x6e,0x6b,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x20,0x23,0x66,0x64,0x35,0x37,0x32,0x33,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x61,0x3a,0x61,0x63,0x74,0x69,0x76,0x65,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x20,0x23,0x66,0x64,0x35,0x37,0x32,0x33,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x61,0x3a,0x76,0x69,0x73,0x69,0x74,0x65,0x64,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x20,0x23,0x66,0x64,0x35,0x37,0x32,0x33,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x09,0x61,0x3a,0x68,0x6f,0x76,0x65,0x72,0x20,0x7b,0x0a,0x09,0x09,0x09,0x09,0x63,0x6f,0x6c,0x6f,0x72,0x3a,0x20,0x23,0x66,0x30,0x62,0x63,0x61,0x63,0x3b,0x0a,0x09,0x09,0x09,0x7d,0x0a,0x09,0x09,0x3c,0x2f,0x73,0x74,0x79,0x6c,0x65,0x3e,0x0a,0x09,0x3c,0x2f,0x68,0x65,0x61,0x64,0x3e,0x0a,0x09,0x3c,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x09,0x09,0x3c,0x70,0x3e,0x0a,0x09,0x09,0x09,0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x61,0x6e,0x6f,0x74,0x68,0x65,0x72,0x20,0x66,0x69,0x6c,0x65,0x20,0x65,0x6d,0x62,0x65,0x64,0x64,0x65,0x64,0x20,0x69,0x6e,0x20,0x74,0x68,0x69,0x73,0x20,0x43,0x2b,0x2b,0x20,0x61,0x70,0x70,0x6c,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2e,0x3c,0x62,0x72,0x20,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x2f,0x70,0x3e,0x0a,0x09,0x09,0x3c,0x62,0x72,0x20,0x2f,0x3e,0x0a,0x09,0x09,0x3c,0x62,0x75,0x74,0x74,0x6f,0x6e,0x20,0x69,0x64,0x3d,0x22,0x45,0x78,0x69,0x74,0x22,0x3e,0x45,0x78,0x69,0x74,0x3c,0x2f,0x62,0x75,0x74,0x74,0x6f,0x6e,0x3e,0x0a,0x09,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0a,0x0a,0x09,0x3c,0x21,0x2d,0x2d,0x20,0x43,0x6f,0x6e,0x6e,0x65,0x63,0x74,0x20,0x74,0x68,0x69,0x73,0x20,0x77,0x69,0x6e,0x64,0x6f,0x77,0x20,0x74,0x6f,0x20,0x74,0x68,0x65,0x20,0x62,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x20,0x61,0x70,0x70,0x20,0x2d,0x2d,0x3e,0x0a,0x09,0x3c,0x73,0x63,0x72,0x69,0x70,0x74,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x77,0x65,0x62,0x75,0x69,0x2e,0x6a,0x73,0x22,0x3e,0x3c,0x2f,0x73,0x63,0x72,0x69,0x70,0x74,0x3e,0x0a,0x0a,0x3c,0x2f,0x68,0x74,0x6d,0x6c,0x3e,0x0a};
+
+static const unsigned char FILE_2[] = {0x3c,0x73,0x76,0x67,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x31,0x32,0x30,0x70,0x78,0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x31,0x32,0x30,0x70,0x78,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x77,0x33,0x2e,0x6f,0x72,0x67,0x2f,0x32,0x30,0x30,0x30,0x2f,0x73,0x76,0x67,0x22,0x20,0x78,0x6d,0x6c,0x6e,0x73,0x3a,0x62,0x78,0x3d,0x22,0x68,0x74,0x74,0x70,0x73,0x3a,0x2f,0x2f,0x62,0x6f,0x78,0x79,0x2d,0x73,0x76,0x67,0x2e,0x63,0x6f,0x6d,0x22,0x3e,0x20,0x3c,0x64,0x65,0x66,0x73,0x3e,0x20,0x3c,0x6d,0x61,0x73,0x6b,0x20,0x69,0x64,0x3d,0x22,0x63,0x69,0x72,0x63,0x6c,0x65,0x2d,0x6d,0x61,0x73,0x6b,0x22,0x3e,0x20,0x3c,0x72,0x65,0x63,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x31,0x32,0x30,0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x31,0x32,0x30,0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x2f,0x3e,0x20,0x3c,0x63,0x69,0x72,0x63,0x6c,0x65,0x20,0x63,0x78,0x3d,0x22,0x31,0x32,0x30,0x22,0x20,0x63,0x79,0x3d,0x22,0x36,0x30,0x22,0x20,0x72,0x3d,0x22,0x31,0x36,0x2e,0x38,0x22,0x2f,0x3e,0x20,0x3c,0x2f,0x6d,0x61,0x73,0x6b,0x3e,0x20,0x3c,0x62,0x78,0x3a,0x67,0x72,0x69,0x64,0x20,0x78,0x3d,0x22,0x30,0x22,0x20,0x79,0x3d,0x22,0x30,0x22,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x33,0x2e,0x33,0x36,0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x39,0x36,0x2e,0x37,0x35,0x33,0x22,0x2f,0x3e,0x20,0x3c,0x2f,0x64,0x65,0x66,0x73,0x3e,0x20,0x3c,0x72,0x65,0x63,0x74,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x31,0x32,0x30,0x22,0x20,0x68,0x65,0x69,0x67,0x68,0x74,0x3d,0x22,0x31,0x32,0x30,0x22,0x20,0x66,0x69,0x6c,0x6c,0x3d,0x22,0x23,0x32,0x61,0x36,0x36,0x39,0x39,0x22,0x20,0x6d,0x61,0x73,0x6b,0x3d,0x22,0x75,0x72,0x6c,0x28,0x23,0x63,0x69,0x72,0x63,0x6c,0x65,0x2d,0x6d,0x61,0x73,0x6b,0x29,0x22,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x22,0x2f,0x3e,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x20,0x33,0x39,0x31,0x2e,0x30,0x37,0x20,0x33,0x37,0x35,0x20,0x4c,0x20,0x33,0x38,0x36,0x2e,0x38,0x34,0x32,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x33,0x38,0x39,0x2e,0x30,0x32,0x36,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x33,0x39,0x32,0x2e,0x33,0x35,0x38,0x20,0x33,0x37,0x31,0x2e,0x35,0x38,0x34,0x20,0x4c,0x20,0x33,0x39,0x37,0x2e,0x32,0x30,0x32,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x33,0x39,0x39,0x2e,0x33,0x30,0x32,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x34,0x30,0x34,0x2e,0x31,0x34,0x36,0x20,0x33,0x37,0x31,0x2e,0x35,0x32,0x38,0x20,0x4c,0x20,0x34,0x30,0x37,0x2e,0x35,0x30,0x36,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x34,0x30,0x39,0x2e,0x36,0x30,0x36,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x34,0x30,0x35,0x2e,0x33,0x37,0x38,0x20,0x33,0x37,0x35,0x20,0x4c,0x20,0x34,0x30,0x33,0x2e,0x31,0x39,0x34,0x20,0x33,0x37,0x35,0x20,0x4c,0x20,0x33,0x39,0x38,0x2e,0x32,0x33,0x38,0x20,0x33,0x35,0x38,0x2e,0x33,0x39,0x36,0x20,0x4c,0x20,0x33,0x39,0x33,0x2e,0x32,0x35,0x34,0x20,0x33,0x37,0x35,0x20,0x5a,0x20,0x4d,0x20,0x34,0x31,0x32,0x2e,0x37,0x31,0x20,0x33,0x37,0x35,0x20,0x4c,0x20,0x34,0x31,0x32,0x2e,0x37,0x31,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x34,0x32,0x36,0x2e,0x37,0x33,0x38,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x34,0x32,0x36,0x2e,0x37,0x33,0x38,0x20,0x33,0x35,0x37,0x2e,0x33,0x30,0x34,0x20,0x4c,0x20,0x34,0x31,0x34,0x2e,0x38,0x36,0x36,0x20,0x33,0x35,0x37,0x2e,0x33,0x30,0x34,0x20,0x4c,0x20,0x34,0x31,0x34,0x2e,0x38,0x36,0x36,0x20,0x33,0x36,0x34,0x2e,0x31,0x36,0x34,0x20,0x4c,0x20,0x34,0x32,0x32,0x2e,0x36,0x32,0x32,0x20,0x33,0x36,0x34,0x2e,0x31,0x36,0x34,0x20,0x4c,0x20,0x34,0x32,0x32,0x2e,0x36,0x32,0x32,0x20,0x33,0x36,0x36,0x2e,0x30,0x34,0x20,0x4c,0x20,0x34,0x31,0x34,0x2e,0x38,0x36,0x36,0x20,0x33,0x36,0x36,0x2e,0x30,0x34,0x20,0x4c,0x20,0x34,0x31,0x34,0x2e,0x38,0x36,0x36,0x20,0x33,0x37,0x33,0x2e,0x30,0x39,0x36,0x20,0x4c,0x20,0x34,0x32,0x36,0x2e,0x38,0x35,0x20,0x33,0x37,0x33,0x2e,0x30,0x39,0x36,0x20,0x4c,0x20,0x34,0x32,0x36,0x2e,0x38,0x35,0x20,0x33,0x37,0x35,0x20,0x5a,0x20,0x4d,0x20,0x34,0x32,0x39,0x2e,0x39,0x35,0x39,0x20,0x33,0x37,0x35,0x20,0x4c,0x20,0x34,0x32,0x39,0x2e,0x39,0x35,0x39,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x34,0x33,0x37,0x2e,0x39,0x31,0x31,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x51,0x20,0x34,0x33,0x39,0x2e,0x38,0x31,0x35,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x34,0x34,0x31,0x2e,0x32,0x30,0x31,0x20,0x33,0x35,0x36,0x2e,0x30,0x31,0x36,0x20,0x51,0x20,0x34,0x34,0x32,0x2e,0x35,0x38,0x37,0x20,0x33,0x35,0x36,0x2e,0x36,0x33,0x32,0x20,0x34,0x34,0x33,0x2e,0x33,0x34,0x33,0x20,0x33,0x35,0x37,0x2e,0x37,0x36,0x36,0x20,0x51,0x20,0x34,0x34,0x34,0x2e,0x30,0x39,0x39,0x20,0x33,0x35,0x38,0x2e,0x39,0x20,0x34,0x34,0x34,0x2e,0x30,0x39,0x39,0x20,0x33,0x36,0x30,0x2e,0x34,0x34,0x20,0x51,0x20,0x34,0x34,0x34,0x2e,0x30,0x39,0x39,0x20,0x33,0x36,0x31,0x2e,0x39,0x35,0x32,0x20,0x34,0x34,0x33,0x2e,0x33,0x30,0x31,0x20,0x33,0x36,0x33,0x2e,0x30,0x37,0x32,0x20,0x51,0x20,0x34,0x34,0x32,0x2e,0x35,0x30,0x33,0x20,0x33,0x36,0x34,0x2e,0x31,0x39,0x32,0x20,0x34,0x34,0x31,0x2e,0x31,0x30,0x33,0x20,0x33,0x36,0x34,0x2e,0x37,0x38,0x20,0x51,0x20,0x34,0x34,0x32,0x2e,0x38,0x36,0x37,0x20,0x33,0x36,0x35,0x2e,0x33,0x31,0x32,0x20,0x34,0x34,0x33,0x2e,0x38,0x38,0x39,0x20,0x33,0x36,0x36,0x2e,0x35,0x34,0x34,0x20,0x51,0x20,0x34,0x34,0x34,0x2e,0x39,0x31,0x31,0x20,0x33,0x36,0x37,0x2e,0x37,0x37,0x36,0x20,0x34,0x34,0x34,0x2e,0x39,0x31,0x31,0x20,0x33,0x36,0x39,0x2e,0x34,0x38,0x34,0x20,0x51,0x20,0x34,0x34,0x34,0x2e,0x39,0x31,0x31,0x20,0x33,0x37,0x31,0x2e,0x31,0x36,0x34,0x20,0x34,0x34,0x34,0x2e,0x30,0x38,0x35,0x20,0x33,0x37,0x32,0x2e,0x34,0x31,0x20,0x51,0x20,0x34,0x34,0x33,0x2e,0x32,0x35,0x39,0x20,0x33,0x37,0x33,0x2e,0x36,0x35,0x36,0x20,0x34,0x34,0x31,0x2e,0x37,0x36,0x31,0x20,0x33,0x37,0x34,0x2e,0x33,0x32,0x38,0x20,0x51,0x20,0x34,0x34,0x30,0x2e,0x32,0x36,0x33,0x20,0x33,0x37,0x35,0x20,0x34,0x33,0x38,0x2e,0x32,0x34,0x37,0x20,0x33,0x37,0x35,0x20,0x5a,0x20,0x4d,0x20,0x34,0x33,0x32,0x2e,0x31,0x31,0x35,0x20,0x33,0x36,0x33,0x2e,0x39,0x34,0x20,0x4c,0x20,0x34,0x33,0x37,0x2e,0x37,0x39,0x39,0x20,0x33,0x36,0x33,0x2e,0x39,0x34,0x20,0x51,0x20,0x34,0x33,0x39,0x2e,0x37,0x30,0x33,0x20,0x33,0x36,0x33,0x2e,0x39,0x34,0x20,0x34,0x34,0x30,0x2e,0x38,0x33,0x37,0x20,0x33,0x36,0x33,0x2e,0x30,0x34,0x34,0x20,0x51,0x20,0x34,0x34,0x31,0x2e,0x39,0x37,0x31,0x20,0x33,0x36,0x32,0x2e,0x31,0x34,0x38,0x20,0x34,0x34,0x31,0x2e,0x39,0x37,0x31,0x20,0x33,0x36,0x30,0x2e,0x36,0x30,0x38,0x20,0x51,0x20,0x34,0x34,0x31,0x2e,0x39,0x37,0x31,0x20,0x33,0x35,0x39,0x2e,0x30,0x36,0x38,0x20,0x34,0x34,0x30,0x2e,0x38,0x33,0x37,0x20,0x33,0x35,0x38,0x2e,0x31,0x37,0x32,0x20,0x51,0x20,0x34,0x33,0x39,0x2e,0x37,0x30,0x33,0x20,0x33,0x35,0x37,0x2e,0x32,0x37,0x36,0x20,0x34,0x33,0x37,0x2e,0x37,0x39,0x39,0x20,0x33,0x35,0x37,0x2e,0x32,0x37,0x36,0x20,0x4c,0x20,0x34,0x33,0x32,0x2e,0x31,0x31,0x35,0x20,0x33,0x35,0x37,0x2e,0x32,0x37,0x36,0x20,0x5a,0x20,0x4d,0x20,0x34,0x33,0x32,0x2e,0x31,0x31,0x35,0x20,0x33,0x37,0x33,0x2e,0x31,0x32,0x34,0x20,0x4c,0x20,0x34,0x33,0x38,0x2e,0x30,0x37,0x39,0x20,0x33,0x37,0x33,0x2e,0x31,0x32,0x34,0x20,0x51,0x20,0x34,0x34,0x30,0x2e,0x32,0x30,0x37,0x20,0x33,0x37,0x33,0x2e,0x31,0x32,0x34,0x20,0x34,0x34,0x31,0x2e,0x34,0x36,0x37,0x20,0x33,0x37,0x32,0x2e,0x31,0x31,0x36,0x20,0x51,0x20,0x34,0x34,0x32,0x2e,0x37,0x32,0x37,0x20,0x33,0x37,0x31,0x2e,0x31,0x30,0x38,0x20,0x34,0x34,0x32,0x2e,0x37,0x32,0x37,0x20,0x33,0x36,0x39,0x2e,0x34,0x32,0x38,0x20,0x51,0x20,0x34,0x34,0x32,0x2e,0x37,0x32,0x37,0x20,0x33,0x36,0x37,0x2e,0x37,0x34,0x38,0x20,0x34,0x34,0x31,0x2e,0x34,0x36,0x37,0x20,0x33,0x36,0x36,0x2e,0x37,0x34,0x20,0x51,0x20,0x34,0x34,0x30,0x2e,0x32,0x30,0x37,0x20,0x33,0x36,0x35,0x2e,0x37,0x33,0x32,0x20,0x34,0x33,0x38,0x2e,0x30,0x37,0x39,0x20,0x33,0x36,0x35,0x2e,0x37,0x33,0x32,0x20,0x4c,0x20,0x34,0x33,0x32,0x2e,0x31,0x31,0x35,0x20,0x33,0x36,0x35,0x2e,0x37,0x33,0x32,0x20,0x5a,0x22,0x20,0x74,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d,0x22,0x6d,0x61,0x74,0x72,0x69,0x78,0x28,0x31,0x2e,0x32,0x36,0x34,0x35,0x39,0x32,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x31,0x2e,0x32,0x34,0x30,0x33,0x30,0x33,0x2c,0x20,0x2d,0x34,0x38,0x33,0x2e,0x38,0x39,0x39,0x33,0x35,0x33,0x2c,0x20,0x2d,0x33,0x35,0x35,0x2e,0x38,0x34,0x35,0x31,0x35,0x34,0x29,0x22,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x66,0x69,0x6c,0x6c,0x3a,0x20,0x72,0x67,0x62,0x28,0x32,0x35,0x35,0x2c,0x20,0x32,0x35,0x35,0x2c,0x20,0x32,0x35,0x35,0x29,0x3b,0x22,0x2f,0x3e,0x20,0x3c,0x70,0x61,0x74,0x68,0x20,0x64,0x3d,0x22,0x4d,0x20,0x34,0x35,0x36,0x2e,0x33,0x33,0x38,0x20,0x33,0x37,0x35,0x2e,0x32,0x38,0x20,0x51,0x20,0x34,0x35,0x33,0x2e,0x36,0x37,0x38,0x20,0x33,0x37,0x35,0x2e,0x32,0x38,0x20,0x34,0x35,0x31,0x2e,0x37,0x33,0x32,0x20,0x33,0x37,0x34,0x2e,0x32,0x31,0x36,0x20,0x51,0x20,0x34,0x34,0x39,0x2e,0x37,0x38,0x36,0x20,0x33,0x37,0x33,0x2e,0x31,0x35,0x32,0x20,0x34,0x34,0x38,0x2e,0x37,0x32,0x32,0x20,0x33,0x37,0x31,0x2e,0x31,0x37,0x38,0x20,0x51,0x20,0x34,0x34,0x37,0x2e,0x36,0x35,0x38,0x20,0x33,0x36,0x39,0x2e,0x32,0x30,0x34,0x20,0x34,0x34,0x37,0x2e,0x36,0x35,0x38,0x20,0x33,0x36,0x36,0x2e,0x35,0x34,0x34,0x20,0x4c,0x20,0x34,0x34,0x37,0x2e,0x36,0x35,0x38,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x34,0x35,0x31,0x2e,0x37,0x31,0x38,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x34,0x35,0x31,0x2e,0x37,0x31,0x38,0x20,0x33,0x36,0x36,0x2e,0x35,0x34,0x34,0x20,0x51,0x20,0x34,0x35,0x31,0x2e,0x37,0x31,0x38,0x20,0x33,0x36,0x38,0x2e,0x30,0x35,0x36,0x20,0x34,0x35,0x32,0x2e,0x32,0x39,0x32,0x20,0x33,0x36,0x39,0x2e,0x31,0x39,0x20,0x51,0x20,0x34,0x35,0x32,0x2e,0x38,0x36,0x36,0x20,0x33,0x37,0x30,0x2e,0x33,0x32,0x34,0x20,0x34,0x35,0x33,0x2e,0x39,0x31,0x36,0x20,0x33,0x37,0x30,0x2e,0x39,0x32,0x36,0x20,0x51,0x20,0x34,0x35,0x34,0x2e,0x39,0x36,0x36,0x20,0x33,0x37,0x31,0x2e,0x35,0x32,0x38,0x20,0x34,0x35,0x36,0x2e,0x33,0x36,0x36,0x20,0x33,0x37,0x31,0x2e,0x35,0x32,0x38,0x20,0x51,0x20,0x34,0x35,0x37,0x2e,0x37,0x36,0x36,0x20,0x33,0x37,0x31,0x2e,0x35,0x32,0x38,0x20,0x34,0x35,0x38,0x2e,0x38,0x30,0x32,0x20,0x33,0x37,0x30,0x2e,0x39,0x32,0x36,0x20,0x51,0x20,0x34,0x35,0x39,0x2e,0x38,0x33,0x38,0x20,0x33,0x37,0x30,0x2e,0x33,0x32,0x34,0x20,0x34,0x36,0x30,0x2e,0x34,0x31,0x32,0x20,0x33,0x36,0x39,0x2e,0x31,0x39,0x20,0x51,0x20,0x34,0x36,0x30,0x2e,0x39,0x38,0x36,0x20,0x33,0x36,0x38,0x2e,0x30,0x35,0x36,0x20,0x34,0x36,0x30,0x2e,0x39,0x38,0x36,0x20,0x33,0x36,0x36,0x2e,0x35,0x34,0x34,0x20,0x4c,0x20,0x34,0x36,0x30,0x2e,0x39,0x38,0x36,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x34,0x36,0x35,0x2e,0x30,0x31,0x38,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x34,0x36,0x35,0x2e,0x30,0x31,0x38,0x20,0x33,0x36,0x36,0x2e,0x35,0x34,0x34,0x20,0x51,0x20,0x34,0x36,0x35,0x2e,0x30,0x31,0x38,0x20,0x33,0x36,0x39,0x2e,0x31,0x37,0x36,0x20,0x34,0x36,0x33,0x2e,0x39,0x35,0x34,0x20,0x33,0x37,0x31,0x2e,0x31,0x35,0x20,0x51,0x20,0x34,0x36,0x32,0x2e,0x38,0x39,0x20,0x33,0x37,0x33,0x2e,0x31,0x32,0x34,0x20,0x34,0x36,0x30,0x2e,0x39,0x34,0x34,0x20,0x33,0x37,0x34,0x2e,0x32,0x30,0x32,0x20,0x51,0x20,0x34,0x35,0x38,0x2e,0x39,0x39,0x38,0x20,0x33,0x37,0x35,0x2e,0x32,0x38,0x20,0x34,0x35,0x36,0x2e,0x33,0x33,0x38,0x20,0x33,0x37,0x35,0x2e,0x32,0x38,0x20,0x5a,0x20,0x4d,0x20,0x34,0x36,0x38,0x2e,0x32,0x36,0x33,0x20,0x33,0x37,0x35,0x20,0x4c,0x20,0x34,0x36,0x38,0x2e,0x32,0x36,0x33,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x34,0x37,0x32,0x2e,0x33,0x32,0x33,0x20,0x33,0x35,0x35,0x2e,0x34,0x20,0x4c,0x20,0x34,0x37,0x32,0x2e,0x33,0x32,0x33,0x20,0x33,0x37,0x35,0x20,0x5a,0x22,0x20,0x74,0x72,0x61,0x6e,0x73,0x66,0x6f,0x72,0x6d,0x3d,0x22,0x6d,0x61,0x74,0x72,0x69,0x78,0x28,0x31,0x2e,0x32,0x36,0x34,0x35,0x39,0x32,0x2c,0x20,0x30,0x2c,0x20,0x30,0x2c,0x20,0x31,0x2e,0x32,0x34,0x30,0x33,0x30,0x33,0x2c,0x20,0x2d,0x34,0x38,0x33,0x2e,0x38,0x39,0x39,0x33,0x35,0x33,0x2c,0x20,0x2d,0x33,0x35,0x35,0x2e,0x38,0x34,0x35,0x31,0x35,0x34,0x29,0x22,0x20,0x73,0x74,0x79,0x6c,0x65,0x3d,0x22,0x66,0x69,0x6c,0x6c,0x3a,0x20,0x72,0x67,0x62,0x28,0x32,0x35,0x35,0x2c,0x20,0x32,0x35,0x35,0x2c,0x20,0x32,0x35,0x35,0x29,0x3b,0x22,0x2f,0x3e,0x3c,0x2f,0x73,0x76,0x67,0x3e};
+
+
+static const VirtualFile virtual_files[] = {
+ {
+ "/index.html",
+ FILE_0,
+ 3099
+ },
+ {
+ "/sub/index.html",
+ FILE_1,
+ 1160
+ },
+ {
+ "/svg/webui.svg",
+ FILE_2,
+ 2347
+ },
+};
+
+static const int virtual_files_count = sizeof(virtual_files) / sizeof(virtual_files[0]);
+
+bool virtual_file_system(const char* path, const unsigned char** file, int* length) {
+ for (int i = 0; i < virtual_files_count; ++i) {
+ if (strcmp(virtual_files[i].path, path) == 0) {
+ *file = virtual_files[i].data;
+ *length = virtual_files[i].length;
+ return true;
+ }
+ }
+ return false;
+}
+
+const void* vfs(const char* path, int* length) {
+ const unsigned char* file_data;
+ int file_length;
+
+ if (virtual_file_system(path, &file_data, &file_length)) {
+ const char* content_type = webui_get_mime_type(path);
+ const char* http_header_template = "HTTP/1.1 200 OK\r\n"
+ "Content-Type: %s\r\n"
+ "Content-Length: %d\r\n"
+ "Cache-Control: no-cache\r\n\r\n";
+ int header_length = snprintf(NULL, 0, http_header_template, content_type, file_length);
+ *length = header_length + file_length;
+ unsigned char* response = (unsigned char*) webui_malloc(*length);
+ snprintf((char*) response, header_length + 1, http_header_template, content_type, file_length);
+ memcpy(response + header_length, file_data, file_length);
+ return response;
+ }
+ return NULL;
+}
+
+#endif // VIRTUAL_FILE_SYSTEM_H
diff --git a/examples/C++/virtual_file_system/vfs.py b/examples/C++/virtual_file_system/vfs.py
new file mode 100644
index 0000000..57e4dfd
--- /dev/null
+++ b/examples/C++/virtual_file_system/vfs.py
@@ -0,0 +1,99 @@
+# WebUI Library
+# https://webui.me
+# https://github.com/webui-dev/webui
+# Copyright (c) 2020-2026 Hassan Draga.
+# Licensed under MIT License.
+# All rights reserved.
+# Canada.
+#
+# WebUI Virtual File System Generator
+# v2.0
+
+import os
+import sys
+
+def generate_vfs_header(directory, output_header):
+ files = []
+
+ for root, _, filenames in os.walk(directory):
+ for filename in filenames:
+ filepath = os.path.join(root, filename)
+ relative_path = os.path.relpath(filepath, directory)
+ # Ensure path starts with a slash
+ relative_path = '/' + relative_path.replace('\\', '/')
+ files.append((relative_path, filepath))
+
+ with open(output_header, 'w') as header:
+ header.write('#ifndef VIRTUAL_FILE_SYSTEM_H\n')
+ header.write('#define VIRTUAL_FILE_SYSTEM_H\n\n')
+
+ header.write('typedef struct {\n')
+ header.write(' const char *path;\n')
+ header.write(' const unsigned char *data;\n')
+ header.write(' int length;\n')
+ header.write('} VirtualFile;\n\n')
+
+ for i, (relative_path, filepath) in enumerate(files):
+ with open(filepath, 'rb') as f:
+ data = f.read()
+ header.write(f'static const unsigned char FILE_{i}[] = {{')
+ header.write(','.join(f'0x{byte:02x}' for byte in data))
+ header.write('};\n\n')
+
+ header.write('\nstatic const VirtualFile virtual_files[] = {\n')
+
+ for i, (relative_path, filepath) in enumerate(files):
+ with open(filepath, 'rb') as f:
+ data = f.read()
+ header.write(' {\n')
+ header.write(f' "{relative_path}",\n')
+ header.write(f' FILE_{i},\n')
+ header.write(f' {len(data)}\n')
+ header.write(' },\n')
+
+ header.write('};\n\n')
+
+ header.write('static const int virtual_files_count = sizeof(virtual_files) / sizeof(virtual_files[0]);\n\n')
+
+ header.write('bool virtual_file_system(const char* path, const unsigned char** file, int* length) {\n')
+ header.write(' for (int i = 0; i < virtual_files_count; ++i) {\n')
+ header.write(' if (strcmp(virtual_files[i].path, path) == 0) {\n')
+ header.write(' *file = virtual_files[i].data;\n')
+ header.write(' *length = virtual_files[i].length;\n')
+ header.write(' return true;\n')
+ header.write(' }\n')
+ header.write(' }\n')
+ header.write(' return false;\n')
+ header.write('}\n\n')
+
+ header.write('const void* vfs(const char* path, int* length) {\n')
+ header.write(' const unsigned char* file_data;\n')
+ header.write(' int file_length;\n\n')
+
+ header.write(' if (virtual_file_system(path, &file_data, &file_length)) {\n')
+ header.write(' const char* content_type = webui_get_mime_type(path);\n')
+ header.write(' const char* http_header_template = "HTTP/1.1 200 OK\\r\\n"\n')
+ header.write(' "Content-Type: %s\\r\\n"\n')
+ header.write(' "Content-Length: %d\\r\\n"\n')
+ header.write(' "Cache-Control: no-cache\\r\\n\\r\\n";\n')
+ header.write(' int header_length = snprintf(NULL, 0, http_header_template, content_type, file_length);\n')
+ header.write(' *length = header_length + file_length;\n')
+ header.write(' unsigned char* response = (unsigned char*) webui_malloc(*length);\n')
+ header.write(' snprintf((char*) response, header_length + 1, http_header_template, content_type, file_length);\n')
+ header.write(' memcpy(response + header_length, file_data, file_length);\n')
+ header.write(' return response;\n')
+ header.write(' }\n')
+ header.write(' return NULL;\n')
+ header.write('}\n\n')
+
+ header.write('#endif // VIRTUAL_FILE_SYSTEM_H\n')
+
+if __name__ == '__main__':
+ if len(sys.argv) != 3:
+ print(f'Usage: {sys.argv[0]} ')
+ sys.exit(1)
+
+ directory = sys.argv[1]
+ output_header = sys.argv[2]
+ generate_vfs_header(directory, output_header)
+ print(f'Generated {output_header} from {directory}')
diff --git a/examples/C/README.md b/examples/C/README.md
new file mode 100644
index 0000000..e3b1b42
--- /dev/null
+++ b/examples/C/README.md
@@ -0,0 +1,51 @@
+# WebUI C Examples
+
+Examples of how to create a WebUI application in C.
+
+## C Examples
+
+The only requirement to build the examples is a C compiler.
+
+- `minimal`: Creates a minimal WebUI application.
+- `call_c_from_js`: Calls C from JavaScript.
+- `call_js_from_c`: Calls JavaScript from C.
+- `serve_a_folder`: Use WebUI to serve a folder that contains `.html`, `.css`, `.js`, or `.ts` files.
+- `custom_web_server`: Use your preferred web server like NGINX/Apache... with WebUI to serve a folder.
+- `chatgpt_api`: Calls ChatGPT API from C.
+- `frameless`: Frameless window example.
+- `public_network_access`: Allows network access to external devices.
+- `react`: React + WebUI example.
+- `virtual_file_system`: Embeds files using a virtual file system.
+- `test_index_redirect`: Tests index fallback and custom entry behavior for `/`, `/sub`, and `/sub/foo`.
+- `web_app_multi_client`: Multiple clients example.
+
+To build an example, cd into its directory and run the make command.
+
+- **Windows**
+
+ ```sh
+ # GCC
+ mingw32-make
+
+ # MSVC
+ nmake
+ ```
+
+- **Linux**
+
+ ```sh
+ # GCC
+ make
+
+ # Clang
+ make CC=clang
+ ```
+
+- **macOS**
+ ```sh
+ make
+ ```
+
+## Additional Examples
+
+- [`text-editor`](https://github.com/webui-dev/webui/tree/main/examples/C/text-editor): A lightweight and portable text editor written in C using WebUI as the GUI library.
diff --git a/examples/C/call_c_from_js/GNUmakefile b/examples/C/call_c_from_js/GNUmakefile
new file mode 100644
index 0000000..6ba8eaa
--- /dev/null
+++ b/examples/C/call_c_from_js/GNUmakefile
@@ -0,0 +1,138 @@
+# WebUI C Example
+
+# == 1. VARIABLES =============================================================
+
+MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
+PROJECT_DIR := $(dir $(MAKEFILE_PATH))/../../../
+TARGET := $(firstword $(MAKECMDGOALS))
+LIB_DIR := $(PROJECT_DIR)/dist
+ifeq ($(TARGET), debug)
+LIB_DIR := $(LIB_DIR)/debug
+endif
+INCLUDE_DIR := $(PROJECT_DIR)/include
+WEBUI_LIB_NAME = webui-2
+ifeq ($(WEBUI_USE_TLS), 1)
+WEBUI_LIB_NAME = webui-2-secure
+endif
+
+# ARGS
+# Set a compiler when running on Linux via `make CC=gcc` / `make CC=clang`
+CC = gcc
+# Build the WebUI library if running via `make BUILD_LIB=true`
+BUILD_LIB ?=
+
+# BUILD FLAGS
+STATIC_BUILD_FLAGS = main.c -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+DYN_BUILD_FLAGS = main.c -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+
+# Platform conditions
+ifeq ($(OS),Windows_NT)
+ # Windows
+ PLATFORM := windows
+ SHELL := CMD
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lws2_32 -Wall -luser32 -lstdc++ -luuid -static
+ COPY_LIB_CMD := @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ DYN_BUILD_FLAGS += "$(WEBUI_LIB_NAME).dll" -lws2_32 -Wall -luser32 -lstdc++ -luuid
+ STATIC_OUT := main.exe
+ DYN_OUT := main-dyn.exe
+ LWS2_OPT := -lws2_32 -lole32
+ STRIP_OPT := --strip-all
+ CONSOLE_APP := -Wl,-subsystem=console
+ GUI_APP := -Wl,-subsystem=windows
+else
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lpthread -lm -ldl
+ DYN_BUILD_FLAGS += -l$(WEBUI_LIB_NAME) -lpthread -lm -ldl
+ STATIC_OUT := main
+ DYN_OUT := main-dyn
+ ifeq ($(shell uname),Darwin)
+ # MacOS
+ PLATFORM := macos
+ CC = clang
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).dylib" "lib$(WEBUI_LIB_NAME).dylib"
+ WKWEBKIT_LINK_FLAGS := -framework Cocoa -framework WebKit
+ else
+ # Linux
+ PLATFORM := linux
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).so" "lib$(WEBUI_LIB_NAME).so"
+ STRIP_OPT := --strip-all
+ ifeq ($(CC),clang)
+ LLVM_OPT := llvm-
+ endif
+ endif
+endif
+
+# == 2.TARGETS ================================================================
+
+all: release
+
+debug: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE) debug
+endif
+# Static with Debug info
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C Example ($(CC) debug static)..."
+ @$(CC) -g $(CONSOLE_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+endif
+# Dynamic with Debug info
+ @echo "Build C Example ($(CC) debug dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) -g $(CONSOLE_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+release: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE)
+endif
+# Static Release
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C Example ($(CC) release static)..."
+ @$(CC) -Os $(GUI_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(STATIC_OUT)
+endif
+# Dynamic Release
+ @echo "Build C Example ($(CC) release dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) $(GUI_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+clean: --clean-$(PLATFORM)
+
+# INTERNAL TARGETS
+
+--validate-args:
+ifneq ($(filter $(CC),gcc clang aarch64-linux-gnu-gcc arm-linux-gnueabihf-gcc musl-gcc),$(CC))
+$(error Invalid compiler specified: `$(CC)`)
+endif
+
+--clean-linux: --clean-unix
+
+--clean-macos: --clean-unix
+
+--clean-unix:
+ - rm -f *.o
+ - rm -f *.a
+ - rm -f *.so
+ - rm -f *.dylib
+ - rm -rf *.dSYM
+
+--clean-windows:
+ - del *.o >nul 2>&1
+ - del *.dll >nul 2>&1
+ - del *.a >nul 2>&1
+ - del *.exe >nul 2>&1
diff --git a/examples/C/call_c_from_js/Makefile b/examples/C/call_c_from_js/Makefile
new file mode 100644
index 0000000..7e72c60
--- /dev/null
+++ b/examples/C/call_c_from_js/Makefile
@@ -0,0 +1,64 @@
+# WebUI C Example
+# Windows - Microsoft Visual C
+
+SHELL = CMD
+LIB_DIR = ../../../dist
+INCLUDE_DIR = ../../../include
+WEBUI_LIB_NAME = webui-2
+!IF "$(WEBUI_USE_TLS)" == "1"
+WEBUI_LIB_NAME = webui-2-secure
+!ENDIF
+
+# Build the WebUI library if running `nmake BUILD_LIB=true`
+BUILD_LIB =
+
+all: release
+
+debug:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE) debug
+!ENDIF
+# Static with Debug info
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C Example (Static Debug)...
+ @cl /Zi main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)\debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic with Debug info
+ @echo Build C Example (Dynamic Debug)...
+ @copy "$(LIB_DIR)\debug\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /Zi main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)\debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @echo Done.
+
+release:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE)
+!ENDIF
+# Static Release
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C Example (Static Release)...
+ @cl main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic Release
+ @echo Build C Example (Dynamic Release)...
+ @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+clean:
+ - del *.obj >nul 2>&1
+ - del *.ilk >nul 2>&1
+ - del *.pdb >nul 2>&1
+ - del *.exp >nul 2>&1
+ - del *.exe >nul 2>&1
+ - del *.lib >nul 2>&1
diff --git a/examples/C/call_c_from_js/main.c b/examples/C/call_c_from_js/main.c
new file mode 100644
index 0000000..48a2775
--- /dev/null
+++ b/examples/C/call_c_from_js/main.c
@@ -0,0 +1,184 @@
+// Call C from JavaScript Example
+
+#include "webui.h"
+
+void my_function_string(webui_event_t* e) {
+
+ // JavaScript:
+ // my_function_string('Hello', 'World`);
+
+ const char* str_1 = webui_get_string(e); // Or webui_get_string_at(e, 0);
+ const char* str_2 = webui_get_string_at(e, 1);
+
+ printf("my_function_string 1: %s\n", str_1); // Hello
+ printf("my_function_string 2: %s\n", str_2); // World
+}
+
+void my_function_integer(webui_event_t* e) {
+
+ // JavaScript:
+ // my_function_integer(123, 456, 789, 12345.6789);
+
+ size_t count = webui_get_count(e);
+ printf("my_function_integer: There is %zu arguments in this event\n", count); // 4
+
+ long long number_1 = webui_get_int(e); // Or webui_get_int_at(e, 0);
+ long long number_2 = webui_get_int_at(e, 1);
+ long long number_3 = webui_get_int_at(e, 2);
+
+ printf("my_function_integer 1: %lld\n", number_1); // 123
+ printf("my_function_integer 2: %lld\n", number_2); // 456
+ printf("my_function_integer 3: %lld\n", number_3); // 789
+
+ double float_1 = webui_get_float_at(e, 3);
+
+ printf("my_function_integer 4: %f\n", float_1); // 12345.6789
+}
+
+void my_function_boolean(webui_event_t* e) {
+
+ // JavaScript:
+ // my_function_boolean(true, false);
+
+ bool status_1 = webui_get_bool(e); // Or webui_get_bool_at(e, 0);
+ bool status_2 = webui_get_bool_at(e, 1);
+
+ printf("my_function_boolean 1: %s\n", (status_1 ? "True" : "False")); // True
+ printf("my_function_boolean 2: %s\n", (status_2 ? "True" : "False")); // False
+}
+
+void my_function_raw_binary(webui_event_t* e) {
+
+ // JavaScript:
+ // my_function_raw_binary(new Uint8Array([0x41]), new Uint8Array([0x42, 0x43]));
+
+ const unsigned char* raw_1 = (const unsigned char*)webui_get_string(e); // Or webui_get_string_at(e, 0);
+ const unsigned char* raw_2 = (const unsigned char*)webui_get_string_at(e, 1);
+
+ int len_1 = (int)webui_get_size(e); // Or webui_get_size_at(e, 0);
+ int len_2 = (int)webui_get_size_at(e, 1);
+
+ // Print raw_1
+ printf("my_function_raw_binary 1 (%d bytes): ", len_1);
+ for (size_t i = 0; i < len_1; i++)
+ printf("0x%02x ", raw_1[i]);
+ printf("\n");
+
+ // Check raw_2 (Big)
+ // [0xA1, 0x00..., 0xA2]
+ bool valid = false;
+ if (raw_2[0] == 0xA1 && raw_2[len_2 - 1] == 0xA2)
+ valid = true;
+
+ // Print raw_2
+ printf("my_function_raw_binary 2 big (%d bytes): valid data? %s\n", len_2, (valid ? "Yes" : "No"));
+}
+
+void my_function_with_response(webui_event_t* e) {
+
+ // JavaScript:
+ // my_function_with_response(number, 2).then(...)
+
+ long long number = webui_get_int(e); // Or webui_get_int_at(e, 0);
+ long long times = webui_get_int_at(e, 1);
+
+ long long res = number * times;
+ printf("my_function_with_response: %lld * %lld = %lld\n", number, times, res);
+
+ // Send back the response to JavaScript
+ webui_return_int(e, res);
+}
+
+int main() {
+
+ // HTML
+ const char* my_html =
+ ""
+ ""
+ " "
+ " "
+ " "
+ " Call C from JavaScript Example "
+ " "
+ " "
+ " "
+ " WebUI - Call C from JavaScript "
+ " Call C functions with arguments (See the logs in your terminal )
"
+ " Call my_function_string() "
+ " "
+ " Call my_function_integer() "
+ " "
+ " Call my_function_boolean() "
+ " "
+ " "
+ " Call my_function_raw_binary() "
+ " "
+ " Call a C function that returns a response
"
+ " Call my_function_with_response() "
+ " Double:
"
+ " "
+ " "
+ "";
+
+ // Create a window
+ size_t my_window = webui_new_window();
+
+ // Bind HTML elements with C functions
+ webui_bind(my_window, "my_function_string", my_function_string);
+ webui_bind(my_window, "my_function_integer", my_function_integer);
+ webui_bind(my_window, "my_function_boolean", my_function_boolean);
+ webui_bind(my_window, "my_function_with_response", my_function_with_response);
+ webui_bind(my_window, "my_function_raw_binary", my_function_raw_binary);
+
+ // Show the window
+ webui_show(my_window, my_html); // webui_show_browser(my_window, my_html, Chrome);
+
+ // Wait until all windows get closed
+ webui_wait();
+
+ // Free all memory resources (Optional)
+ webui_clean();
+
+ return 0;
+}
+
+#if defined(_MSC_VER)
+int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) { return main(); }
+#endif
diff --git a/examples/C/call_js_from_c/GNUmakefile b/examples/C/call_js_from_c/GNUmakefile
new file mode 100644
index 0000000..6ba8eaa
--- /dev/null
+++ b/examples/C/call_js_from_c/GNUmakefile
@@ -0,0 +1,138 @@
+# WebUI C Example
+
+# == 1. VARIABLES =============================================================
+
+MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
+PROJECT_DIR := $(dir $(MAKEFILE_PATH))/../../../
+TARGET := $(firstword $(MAKECMDGOALS))
+LIB_DIR := $(PROJECT_DIR)/dist
+ifeq ($(TARGET), debug)
+LIB_DIR := $(LIB_DIR)/debug
+endif
+INCLUDE_DIR := $(PROJECT_DIR)/include
+WEBUI_LIB_NAME = webui-2
+ifeq ($(WEBUI_USE_TLS), 1)
+WEBUI_LIB_NAME = webui-2-secure
+endif
+
+# ARGS
+# Set a compiler when running on Linux via `make CC=gcc` / `make CC=clang`
+CC = gcc
+# Build the WebUI library if running via `make BUILD_LIB=true`
+BUILD_LIB ?=
+
+# BUILD FLAGS
+STATIC_BUILD_FLAGS = main.c -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+DYN_BUILD_FLAGS = main.c -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+
+# Platform conditions
+ifeq ($(OS),Windows_NT)
+ # Windows
+ PLATFORM := windows
+ SHELL := CMD
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lws2_32 -Wall -luser32 -lstdc++ -luuid -static
+ COPY_LIB_CMD := @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ DYN_BUILD_FLAGS += "$(WEBUI_LIB_NAME).dll" -lws2_32 -Wall -luser32 -lstdc++ -luuid
+ STATIC_OUT := main.exe
+ DYN_OUT := main-dyn.exe
+ LWS2_OPT := -lws2_32 -lole32
+ STRIP_OPT := --strip-all
+ CONSOLE_APP := -Wl,-subsystem=console
+ GUI_APP := -Wl,-subsystem=windows
+else
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lpthread -lm -ldl
+ DYN_BUILD_FLAGS += -l$(WEBUI_LIB_NAME) -lpthread -lm -ldl
+ STATIC_OUT := main
+ DYN_OUT := main-dyn
+ ifeq ($(shell uname),Darwin)
+ # MacOS
+ PLATFORM := macos
+ CC = clang
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).dylib" "lib$(WEBUI_LIB_NAME).dylib"
+ WKWEBKIT_LINK_FLAGS := -framework Cocoa -framework WebKit
+ else
+ # Linux
+ PLATFORM := linux
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).so" "lib$(WEBUI_LIB_NAME).so"
+ STRIP_OPT := --strip-all
+ ifeq ($(CC),clang)
+ LLVM_OPT := llvm-
+ endif
+ endif
+endif
+
+# == 2.TARGETS ================================================================
+
+all: release
+
+debug: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE) debug
+endif
+# Static with Debug info
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C Example ($(CC) debug static)..."
+ @$(CC) -g $(CONSOLE_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+endif
+# Dynamic with Debug info
+ @echo "Build C Example ($(CC) debug dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) -g $(CONSOLE_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+release: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE)
+endif
+# Static Release
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C Example ($(CC) release static)..."
+ @$(CC) -Os $(GUI_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(STATIC_OUT)
+endif
+# Dynamic Release
+ @echo "Build C Example ($(CC) release dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) $(GUI_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+clean: --clean-$(PLATFORM)
+
+# INTERNAL TARGETS
+
+--validate-args:
+ifneq ($(filter $(CC),gcc clang aarch64-linux-gnu-gcc arm-linux-gnueabihf-gcc musl-gcc),$(CC))
+$(error Invalid compiler specified: `$(CC)`)
+endif
+
+--clean-linux: --clean-unix
+
+--clean-macos: --clean-unix
+
+--clean-unix:
+ - rm -f *.o
+ - rm -f *.a
+ - rm -f *.so
+ - rm -f *.dylib
+ - rm -rf *.dSYM
+
+--clean-windows:
+ - del *.o >nul 2>&1
+ - del *.dll >nul 2>&1
+ - del *.a >nul 2>&1
+ - del *.exe >nul 2>&1
diff --git a/examples/C/call_js_from_c/Makefile b/examples/C/call_js_from_c/Makefile
new file mode 100644
index 0000000..7e72c60
--- /dev/null
+++ b/examples/C/call_js_from_c/Makefile
@@ -0,0 +1,64 @@
+# WebUI C Example
+# Windows - Microsoft Visual C
+
+SHELL = CMD
+LIB_DIR = ../../../dist
+INCLUDE_DIR = ../../../include
+WEBUI_LIB_NAME = webui-2
+!IF "$(WEBUI_USE_TLS)" == "1"
+WEBUI_LIB_NAME = webui-2-secure
+!ENDIF
+
+# Build the WebUI library if running `nmake BUILD_LIB=true`
+BUILD_LIB =
+
+all: release
+
+debug:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE) debug
+!ENDIF
+# Static with Debug info
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C Example (Static Debug)...
+ @cl /Zi main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)\debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic with Debug info
+ @echo Build C Example (Dynamic Debug)...
+ @copy "$(LIB_DIR)\debug\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /Zi main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)\debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @echo Done.
+
+release:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE)
+!ENDIF
+# Static Release
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C Example (Static Release)...
+ @cl main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic Release
+ @echo Build C Example (Dynamic Release)...
+ @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+clean:
+ - del *.obj >nul 2>&1
+ - del *.ilk >nul 2>&1
+ - del *.pdb >nul 2>&1
+ - del *.exp >nul 2>&1
+ - del *.exe >nul 2>&1
+ - del *.lib >nul 2>&1
diff --git a/examples/C/call_js_from_c/main.c b/examples/C/call_js_from_c/main.c
new file mode 100644
index 0000000..5b60593
--- /dev/null
+++ b/examples/C/call_js_from_c/main.c
@@ -0,0 +1,143 @@
+// Call JavaScript from C Example
+
+#include "webui.h"
+
+void my_function_exit(webui_event_t* e) {
+
+ // Close all opened windows
+ webui_exit();
+}
+
+void my_function_count(webui_event_t* e) {
+
+ // This function gets called every time the user clicks on "my_function_count"
+
+ // Create a buffer to hold the response
+ char response[64];
+
+ // Run JavaScript
+ if (!webui_script(e->window, "return GetCount();", 0, response, 64)) {
+
+ if (!webui_is_shown(e->window))
+ printf("Window closed.\n");
+ else
+ printf("JavaScript Error: %s\n", response);
+ return;
+ }
+
+ // Get the count
+ int count = atoi(response);
+
+ // Increment
+ count++;
+
+ // Generate a JavaScript
+ char js[64];
+ sprintf(js, "SetCount(%d);", count);
+
+ // Run JavaScript (Quick Way)
+ webui_run(e->window, js);
+
+ // Alternatively, Using `webui_extensions.h`
+ // webui_run_fmt(e->window, "SetCount(%d);", count);
+}
+
+int main() {
+
+ // HTML
+ const char* my_html = ""
+ ""
+ " "
+ " "
+ " "
+ " Call JavaScript from C Example "
+ " "
+ " "
+ " "
+ " WebUI - Call JavaScript from C "
+ " "
+ " 0 "
+ " "
+ " Manual Count "
+ " "
+ " Auto Count (Every 10ms) "
+ " "
+ " Exit "
+ " "
+ " "
+ "";
+
+ // Set WebUI configuration to proceess UI events one at a time
+ webui_set_config(ui_event_blocking, true);
+
+ // Create a window
+ size_t my_window = webui_new_window();
+
+ // Bind HTML elements with C functions
+ webui_bind(my_window, "my_function_count", my_function_count);
+ webui_bind(my_window, "my_function_exit", my_function_exit);
+
+ // Show the window
+ webui_show(my_window, my_html); // webui_show_browser(my_window, my_html, Chrome);
+
+ // Wait until all windows get closed
+ webui_wait();
+
+ // Free all memory resources (Optional)
+ webui_clean();
+
+ return 0;
+}
+
+#if defined(_MSC_VER)
+int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) { return main(); }
+#endif
diff --git a/examples/C/chatgpt_api/GNUmakefile b/examples/C/chatgpt_api/GNUmakefile
new file mode 100644
index 0000000..6ba8eaa
--- /dev/null
+++ b/examples/C/chatgpt_api/GNUmakefile
@@ -0,0 +1,138 @@
+# WebUI C Example
+
+# == 1. VARIABLES =============================================================
+
+MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
+PROJECT_DIR := $(dir $(MAKEFILE_PATH))/../../../
+TARGET := $(firstword $(MAKECMDGOALS))
+LIB_DIR := $(PROJECT_DIR)/dist
+ifeq ($(TARGET), debug)
+LIB_DIR := $(LIB_DIR)/debug
+endif
+INCLUDE_DIR := $(PROJECT_DIR)/include
+WEBUI_LIB_NAME = webui-2
+ifeq ($(WEBUI_USE_TLS), 1)
+WEBUI_LIB_NAME = webui-2-secure
+endif
+
+# ARGS
+# Set a compiler when running on Linux via `make CC=gcc` / `make CC=clang`
+CC = gcc
+# Build the WebUI library if running via `make BUILD_LIB=true`
+BUILD_LIB ?=
+
+# BUILD FLAGS
+STATIC_BUILD_FLAGS = main.c -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+DYN_BUILD_FLAGS = main.c -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+
+# Platform conditions
+ifeq ($(OS),Windows_NT)
+ # Windows
+ PLATFORM := windows
+ SHELL := CMD
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lws2_32 -Wall -luser32 -lstdc++ -luuid -static
+ COPY_LIB_CMD := @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ DYN_BUILD_FLAGS += "$(WEBUI_LIB_NAME).dll" -lws2_32 -Wall -luser32 -lstdc++ -luuid
+ STATIC_OUT := main.exe
+ DYN_OUT := main-dyn.exe
+ LWS2_OPT := -lws2_32 -lole32
+ STRIP_OPT := --strip-all
+ CONSOLE_APP := -Wl,-subsystem=console
+ GUI_APP := -Wl,-subsystem=windows
+else
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lpthread -lm -ldl
+ DYN_BUILD_FLAGS += -l$(WEBUI_LIB_NAME) -lpthread -lm -ldl
+ STATIC_OUT := main
+ DYN_OUT := main-dyn
+ ifeq ($(shell uname),Darwin)
+ # MacOS
+ PLATFORM := macos
+ CC = clang
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).dylib" "lib$(WEBUI_LIB_NAME).dylib"
+ WKWEBKIT_LINK_FLAGS := -framework Cocoa -framework WebKit
+ else
+ # Linux
+ PLATFORM := linux
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).so" "lib$(WEBUI_LIB_NAME).so"
+ STRIP_OPT := --strip-all
+ ifeq ($(CC),clang)
+ LLVM_OPT := llvm-
+ endif
+ endif
+endif
+
+# == 2.TARGETS ================================================================
+
+all: release
+
+debug: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE) debug
+endif
+# Static with Debug info
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C Example ($(CC) debug static)..."
+ @$(CC) -g $(CONSOLE_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+endif
+# Dynamic with Debug info
+ @echo "Build C Example ($(CC) debug dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) -g $(CONSOLE_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+release: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE)
+endif
+# Static Release
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C Example ($(CC) release static)..."
+ @$(CC) -Os $(GUI_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(STATIC_OUT)
+endif
+# Dynamic Release
+ @echo "Build C Example ($(CC) release dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) $(GUI_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+clean: --clean-$(PLATFORM)
+
+# INTERNAL TARGETS
+
+--validate-args:
+ifneq ($(filter $(CC),gcc clang aarch64-linux-gnu-gcc arm-linux-gnueabihf-gcc musl-gcc),$(CC))
+$(error Invalid compiler specified: `$(CC)`)
+endif
+
+--clean-linux: --clean-unix
+
+--clean-macos: --clean-unix
+
+--clean-unix:
+ - rm -f *.o
+ - rm -f *.a
+ - rm -f *.so
+ - rm -f *.dylib
+ - rm -rf *.dSYM
+
+--clean-windows:
+ - del *.o >nul 2>&1
+ - del *.dll >nul 2>&1
+ - del *.a >nul 2>&1
+ - del *.exe >nul 2>&1
diff --git a/examples/C/chatgpt_api/Makefile b/examples/C/chatgpt_api/Makefile
new file mode 100644
index 0000000..00c156b
--- /dev/null
+++ b/examples/C/chatgpt_api/Makefile
@@ -0,0 +1,64 @@
+# WebUI C Example
+# Windows - Microsoft Visual C
+
+SHELL = CMD
+LIB_DIR = ../../../dist
+INCLUDE_DIR = ../../../include
+WEBUI_LIB_NAME = webui-2
+!IF "$(WEBUI_USE_TLS)" == "1"
+WEBUI_LIB_NAME = webui-2-secure
+!ENDIF
+
+# Build the WebUI library if running `nmake BUILD_LIB=true`
+BUILD_LIB =
+
+all: release
+
+debug:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE) debug
+!ENDIF
+# Static with Debug info
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C Example (Static Debug)...
+ @cl /Zi main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)\debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic with Debug info
+ @echo Build C Example (Dynamic Debug)...
+ @copy "$(LIB_DIR)\debug\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /Zi main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)\debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @echo Done.
+
+release:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE)
+!ENDIF
+# Static Release
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C Example (Static Release)...
+ @cl main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic Release
+ @echo Build C Example (Dynamic Release)...
+ @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+clean:
+ - del *.obj >nul 2>&1
+ - del *.ilk >nul 2>&1
+ - del *.pdb >nul 2>&1
+ - del *.exp >nul 2>&1
+ - del *.exe >nul 2>&1
+ - del *.lib >nul 2>&1
diff --git a/examples/C/chatgpt_api/main.c b/examples/C/chatgpt_api/main.c
new file mode 100644
index 0000000..d928e4a
--- /dev/null
+++ b/examples/C/chatgpt_api/main.c
@@ -0,0 +1,98 @@
+// WebUI C - ChatGPT HTTPS API Example
+
+#include "webui.h"
+
+// ChatGPT Configuration
+#define USER_KEY "sk-proj-xxx-xxxxxxxxxxxxxxxxxxxxxxx_xxx"
+#define USER_MODEL "gpt-4o"
+#define USER_ASSISTANT "You are an assistant, answer with very short messages."
+
+#define BUF_SIZE (1024)
+size_t hiddenWindow = 0;
+
+// HTML
+const char* html = ""
+""
+" "
+" "
+" "
+" "
+" "
+" "
+"";
+
+bool run_ai_query(const char* user_query, char* ai_response) {
+
+ char js[BUF_SIZE];
+ memset(js, 0, BUF_SIZE);
+
+ // Generate JavaScript
+ sprintf(js,
+ "return run_gpt_api('%s', '%s', '%s', '%s');",
+ USER_KEY, USER_MODEL, USER_ASSISTANT, user_query
+ );
+
+ // Run HTTPS API
+ if (webui_script(hiddenWindow, js, 30, ai_response, BUF_SIZE)) {
+ return true;
+ }
+
+ return false;
+}
+
+int main(int argc, char *argv[]) {
+
+ if (argc < 2) {
+ printf("Please provide a query.\nExample: %s What is the capital of Canada?\n", argv[0]);
+ return 0;
+ }
+
+ // Initializing
+ char ai_response[BUF_SIZE];
+ char user_query[BUF_SIZE];
+ memset(ai_response, 0, BUF_SIZE);
+ memset(user_query, 0, BUF_SIZE);
+
+ // Get user query
+ for (int i = 1; i < argc; i++) {
+ strcat(user_query, argv[i]);
+ strcat(user_query, " ");
+ }
+
+ // Start WebUI server
+ hiddenWindow = webui_new_window();
+ webui_set_hide(hiddenWindow, true);
+ webui_show_browser(hiddenWindow, html, ChromiumBased);
+
+ // Run HTTPS API
+ if (run_ai_query(user_query, ai_response)) {
+ printf("AI Response: %s\n", ai_response);
+ } else {
+ printf("Error:\n%s\n", ai_response);
+ }
+
+ // Exit
+ webui_exit();
+ webui_clean();
+
+ return 0;
+}
diff --git a/examples/C/custom_web_server/GNUmakefile b/examples/C/custom_web_server/GNUmakefile
new file mode 100644
index 0000000..6ba8eaa
--- /dev/null
+++ b/examples/C/custom_web_server/GNUmakefile
@@ -0,0 +1,138 @@
+# WebUI C Example
+
+# == 1. VARIABLES =============================================================
+
+MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
+PROJECT_DIR := $(dir $(MAKEFILE_PATH))/../../../
+TARGET := $(firstword $(MAKECMDGOALS))
+LIB_DIR := $(PROJECT_DIR)/dist
+ifeq ($(TARGET), debug)
+LIB_DIR := $(LIB_DIR)/debug
+endif
+INCLUDE_DIR := $(PROJECT_DIR)/include
+WEBUI_LIB_NAME = webui-2
+ifeq ($(WEBUI_USE_TLS), 1)
+WEBUI_LIB_NAME = webui-2-secure
+endif
+
+# ARGS
+# Set a compiler when running on Linux via `make CC=gcc` / `make CC=clang`
+CC = gcc
+# Build the WebUI library if running via `make BUILD_LIB=true`
+BUILD_LIB ?=
+
+# BUILD FLAGS
+STATIC_BUILD_FLAGS = main.c -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+DYN_BUILD_FLAGS = main.c -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+
+# Platform conditions
+ifeq ($(OS),Windows_NT)
+ # Windows
+ PLATFORM := windows
+ SHELL := CMD
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lws2_32 -Wall -luser32 -lstdc++ -luuid -static
+ COPY_LIB_CMD := @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ DYN_BUILD_FLAGS += "$(WEBUI_LIB_NAME).dll" -lws2_32 -Wall -luser32 -lstdc++ -luuid
+ STATIC_OUT := main.exe
+ DYN_OUT := main-dyn.exe
+ LWS2_OPT := -lws2_32 -lole32
+ STRIP_OPT := --strip-all
+ CONSOLE_APP := -Wl,-subsystem=console
+ GUI_APP := -Wl,-subsystem=windows
+else
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lpthread -lm -ldl
+ DYN_BUILD_FLAGS += -l$(WEBUI_LIB_NAME) -lpthread -lm -ldl
+ STATIC_OUT := main
+ DYN_OUT := main-dyn
+ ifeq ($(shell uname),Darwin)
+ # MacOS
+ PLATFORM := macos
+ CC = clang
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).dylib" "lib$(WEBUI_LIB_NAME).dylib"
+ WKWEBKIT_LINK_FLAGS := -framework Cocoa -framework WebKit
+ else
+ # Linux
+ PLATFORM := linux
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).so" "lib$(WEBUI_LIB_NAME).so"
+ STRIP_OPT := --strip-all
+ ifeq ($(CC),clang)
+ LLVM_OPT := llvm-
+ endif
+ endif
+endif
+
+# == 2.TARGETS ================================================================
+
+all: release
+
+debug: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE) debug
+endif
+# Static with Debug info
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C Example ($(CC) debug static)..."
+ @$(CC) -g $(CONSOLE_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+endif
+# Dynamic with Debug info
+ @echo "Build C Example ($(CC) debug dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) -g $(CONSOLE_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+release: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE)
+endif
+# Static Release
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C Example ($(CC) release static)..."
+ @$(CC) -Os $(GUI_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(STATIC_OUT)
+endif
+# Dynamic Release
+ @echo "Build C Example ($(CC) release dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) $(GUI_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+clean: --clean-$(PLATFORM)
+
+# INTERNAL TARGETS
+
+--validate-args:
+ifneq ($(filter $(CC),gcc clang aarch64-linux-gnu-gcc arm-linux-gnueabihf-gcc musl-gcc),$(CC))
+$(error Invalid compiler specified: `$(CC)`)
+endif
+
+--clean-linux: --clean-unix
+
+--clean-macos: --clean-unix
+
+--clean-unix:
+ - rm -f *.o
+ - rm -f *.a
+ - rm -f *.so
+ - rm -f *.dylib
+ - rm -rf *.dSYM
+
+--clean-windows:
+ - del *.o >nul 2>&1
+ - del *.dll >nul 2>&1
+ - del *.a >nul 2>&1
+ - del *.exe >nul 2>&1
diff --git a/examples/C/custom_web_server/Makefile b/examples/C/custom_web_server/Makefile
new file mode 100644
index 0000000..7e72c60
--- /dev/null
+++ b/examples/C/custom_web_server/Makefile
@@ -0,0 +1,64 @@
+# WebUI C Example
+# Windows - Microsoft Visual C
+
+SHELL = CMD
+LIB_DIR = ../../../dist
+INCLUDE_DIR = ../../../include
+WEBUI_LIB_NAME = webui-2
+!IF "$(WEBUI_USE_TLS)" == "1"
+WEBUI_LIB_NAME = webui-2-secure
+!ENDIF
+
+# Build the WebUI library if running `nmake BUILD_LIB=true`
+BUILD_LIB =
+
+all: release
+
+debug:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE) debug
+!ENDIF
+# Static with Debug info
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C Example (Static Debug)...
+ @cl /Zi main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)\debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic with Debug info
+ @echo Build C Example (Dynamic Debug)...
+ @copy "$(LIB_DIR)\debug\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /Zi main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)\debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @echo Done.
+
+release:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE)
+!ENDIF
+# Static Release
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C Example (Static Release)...
+ @cl main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic Release
+ @echo Build C Example (Dynamic Release)...
+ @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+clean:
+ - del *.obj >nul 2>&1
+ - del *.ilk >nul 2>&1
+ - del *.pdb >nul 2>&1
+ - del *.exp >nul 2>&1
+ - del *.exe >nul 2>&1
+ - del *.lib >nul 2>&1
diff --git a/examples/C/custom_web_server/index.html b/examples/C/custom_web_server/index.html
new file mode 100644
index 0000000..b671d44
--- /dev/null
+++ b/examples/C/custom_web_server/index.html
@@ -0,0 +1,18 @@
+
+
+
+
+ WebUI - Custom Web-Server Example (C)
+
+
+
+
+ Custom Web-Server Example (C)
+
+ This HTML page is handled by a custom Web-Server other than WebUI.
+ This window is connected to the back-end because we used:
http://localhost:8081/webui.js
+
+
+ Call my_backend_func()
+
+
diff --git a/examples/C/custom_web_server/main.c b/examples/C/custom_web_server/main.c
new file mode 100644
index 0000000..909bb2e
--- /dev/null
+++ b/examples/C/custom_web_server/main.c
@@ -0,0 +1,74 @@
+// Serve a Folder Example
+
+#include "webui.h"
+
+void events(webui_event_t* e) {
+
+ // This function gets called every time
+ // there is an event
+
+ if (e->event_type == WEBUI_EVENT_CONNECTED)
+ printf("Connected. \n");
+ else if (e->event_type == WEBUI_EVENT_DISCONNECTED)
+ printf("Disconnected. \n");
+ else if (e->event_type == WEBUI_EVENT_MOUSE_CLICK)
+ printf("Click. \n");
+ else if (e->event_type == WEBUI_EVENT_NAVIGATION) {
+ const char* url = webui_get_string(e);
+ printf("Starting navigation to: %s \n", url);
+
+ // Because we used `webui_bind(MyWindow, "", events);`
+ // WebUI will block all `href` link clicks and sent here instead.
+ // We can then control the behaviour of links as needed.
+ webui_navigate(e->window, url);
+ }
+}
+
+void my_backend_func(webui_event_t* e) {
+
+ // JavaScript:
+ // my_backend_func(123, 456, 789);
+ // or webui.my_backend_func(...);
+
+ long long number_1 = webui_get_int_at(e, 0);
+ long long number_2 = webui_get_int_at(e, 1);
+ long long number_3 = webui_get_int_at(e, 2);
+
+ printf("my_backend_func 1: %lld\n", number_1); // 123
+ printf("my_backend_func 2: %lld\n", number_2); // 456
+ printf("my_backend_func 3: %lld\n", number_3); // 789
+}
+
+int main() {
+
+ // Create new windows
+ size_t window = webui_new_window();
+
+ // Bind all events
+ webui_bind(window, "", events);
+
+ // Bind HTML elements with C functions
+ webui_bind(window, "my_backend_func", my_backend_func);
+
+ // Set the web-server/WebSocket port that WebUI should
+ // use. This means `webui.js` will be available at:
+ // http://localhost:MY_PORT_NUMBER/webui.js
+ webui_set_port(window, 8081);
+
+ // Show a new window and show our custom web server
+ // Assuming the custom web server is running on port
+ // 8080...
+ webui_show(window, "http://localhost:8080/");
+
+ // Wait until all windows get closed
+ webui_wait();
+
+ // Free all memory resources (Optional)
+ webui_clean();
+
+ return 0;
+}
+
+#if defined(_MSC_VER)
+int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) { return main(); }
+#endif
diff --git a/examples/C/custom_web_server/second.html b/examples/C/custom_web_server/second.html
new file mode 100644
index 0000000..c8b77f9
--- /dev/null
+++ b/examples/C/custom_web_server/second.html
@@ -0,0 +1,13 @@
+
+
+
+
+ WebUI - Custom Web-Server second page (C)
+
+
+
+
+ This is the second page !
+
+
+
diff --git a/examples/C/custom_web_server/simple_web_server.py b/examples/C/custom_web_server/simple_web_server.py
new file mode 100644
index 0000000..dbb3c36
--- /dev/null
+++ b/examples/C/custom_web_server/simple_web_server.py
@@ -0,0 +1,10 @@
+import http.server
+import socketserver
+
+PORT = 8080
+
+Handler = http.server.SimpleHTTPRequestHandler
+
+with socketserver.TCPServer(("", PORT), Handler) as httpd:
+ print(f"Server started at http://localhost:{PORT}")
+ httpd.serve_forever()
diff --git a/examples/C/frameless/GNUmakefile b/examples/C/frameless/GNUmakefile
new file mode 100644
index 0000000..6ba8eaa
--- /dev/null
+++ b/examples/C/frameless/GNUmakefile
@@ -0,0 +1,138 @@
+# WebUI C Example
+
+# == 1. VARIABLES =============================================================
+
+MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
+PROJECT_DIR := $(dir $(MAKEFILE_PATH))/../../../
+TARGET := $(firstword $(MAKECMDGOALS))
+LIB_DIR := $(PROJECT_DIR)/dist
+ifeq ($(TARGET), debug)
+LIB_DIR := $(LIB_DIR)/debug
+endif
+INCLUDE_DIR := $(PROJECT_DIR)/include
+WEBUI_LIB_NAME = webui-2
+ifeq ($(WEBUI_USE_TLS), 1)
+WEBUI_LIB_NAME = webui-2-secure
+endif
+
+# ARGS
+# Set a compiler when running on Linux via `make CC=gcc` / `make CC=clang`
+CC = gcc
+# Build the WebUI library if running via `make BUILD_LIB=true`
+BUILD_LIB ?=
+
+# BUILD FLAGS
+STATIC_BUILD_FLAGS = main.c -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+DYN_BUILD_FLAGS = main.c -I"$(INCLUDE_DIR)" -L"$(LIB_DIR)"
+
+# Platform conditions
+ifeq ($(OS),Windows_NT)
+ # Windows
+ PLATFORM := windows
+ SHELL := CMD
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lws2_32 -Wall -luser32 -lstdc++ -luuid -static
+ COPY_LIB_CMD := @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ DYN_BUILD_FLAGS += "$(WEBUI_LIB_NAME).dll" -lws2_32 -Wall -luser32 -lstdc++ -luuid
+ STATIC_OUT := main.exe
+ DYN_OUT := main-dyn.exe
+ LWS2_OPT := -lws2_32 -lole32
+ STRIP_OPT := --strip-all
+ CONSOLE_APP := -Wl,-subsystem=console
+ GUI_APP := -Wl,-subsystem=windows
+else
+ STATIC_BUILD_FLAGS += -l$(WEBUI_LIB_NAME)-static -lpthread -lm -ldl
+ DYN_BUILD_FLAGS += -l$(WEBUI_LIB_NAME) -lpthread -lm -ldl
+ STATIC_OUT := main
+ DYN_OUT := main-dyn
+ ifeq ($(shell uname),Darwin)
+ # MacOS
+ PLATFORM := macos
+ CC = clang
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).dylib" "lib$(WEBUI_LIB_NAME).dylib"
+ WKWEBKIT_LINK_FLAGS := -framework Cocoa -framework WebKit
+ else
+ # Linux
+ PLATFORM := linux
+ COPY_LIB_CMD := @cp "$(LIB_DIR)/lib$(WEBUI_LIB_NAME).so" "lib$(WEBUI_LIB_NAME).so"
+ STRIP_OPT := --strip-all
+ ifeq ($(CC),clang)
+ LLVM_OPT := llvm-
+ endif
+ endif
+endif
+
+# == 2.TARGETS ================================================================
+
+all: release
+
+debug: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE) debug
+endif
+# Static with Debug info
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C Example ($(CC) debug static)..."
+ @$(CC) -g $(CONSOLE_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+endif
+# Dynamic with Debug info
+ @echo "Build C Example ($(CC) debug dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) -g $(CONSOLE_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+release: --validate-args
+ifeq ($(BUILD_LIB),true)
+ @cd "$(PROJECT_DIR)" && $(MAKE)
+endif
+# Static Release
+ifneq ($(WEBUI_USE_TLS), 1)
+ @echo "Build C Example ($(CC) release static)..."
+ @$(CC) -Os $(GUI_APP) $(STATIC_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(STATIC_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(STATIC_OUT)
+endif
+# Dynamic Release
+ @echo "Build C Example ($(CC) release dynamic)..."
+ $(COPY_LIB_CMD)
+ @$(CC) $(GUI_APP) $(DYN_BUILD_FLAGS) $(LWS2_OPT) $(WKWEBKIT_LINK_FLAGS) -o $(DYN_OUT)
+ @$(LLVM_OPT)strip $(STRIP_OPT) $(DYN_OUT)
+# Clean
+ifeq ($(PLATFORM),windows)
+ @- del *.o >nul 2>&1
+else
+ @- rm -f *.o
+ @- rm -rf *.dSYM # macOS
+endif
+ @echo "Done."
+
+clean: --clean-$(PLATFORM)
+
+# INTERNAL TARGETS
+
+--validate-args:
+ifneq ($(filter $(CC),gcc clang aarch64-linux-gnu-gcc arm-linux-gnueabihf-gcc musl-gcc),$(CC))
+$(error Invalid compiler specified: `$(CC)`)
+endif
+
+--clean-linux: --clean-unix
+
+--clean-macos: --clean-unix
+
+--clean-unix:
+ - rm -f *.o
+ - rm -f *.a
+ - rm -f *.so
+ - rm -f *.dylib
+ - rm -rf *.dSYM
+
+--clean-windows:
+ - del *.o >nul 2>&1
+ - del *.dll >nul 2>&1
+ - del *.a >nul 2>&1
+ - del *.exe >nul 2>&1
diff --git a/examples/C/frameless/Makefile b/examples/C/frameless/Makefile
new file mode 100644
index 0000000..7e72c60
--- /dev/null
+++ b/examples/C/frameless/Makefile
@@ -0,0 +1,64 @@
+# WebUI C Example
+# Windows - Microsoft Visual C
+
+SHELL = CMD
+LIB_DIR = ../../../dist
+INCLUDE_DIR = ../../../include
+WEBUI_LIB_NAME = webui-2
+!IF "$(WEBUI_USE_TLS)" == "1"
+WEBUI_LIB_NAME = webui-2-secure
+!ENDIF
+
+# Build the WebUI library if running `nmake BUILD_LIB=true`
+BUILD_LIB =
+
+all: release
+
+debug:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE) debug
+!ENDIF
+# Static with Debug info
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C Example (Static Debug)...
+ @cl /Zi main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)\debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic with Debug info
+ @echo Build C Example (Dynamic Debug)...
+ @copy "$(LIB_DIR)\debug\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl /Zi main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)\debug" /SUBSYSTEM:CONSOLE $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @echo Done.
+
+release:
+!IF "$(BUILD_LIB)" == "true"
+ @cd "$(LIB_DIR)" && cd .. && $(MAKE)
+!ENDIF
+# Static Release
+!IF "$(WEBUI_USE_TLS)" != "1"
+ @echo Build C Example (Static Release)...
+ @cl main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME)-static.lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main.exe 1>NUL 2>&1
+!ENDIF
+# Dynamic Release
+ @echo Build C Example (Dynamic Release)...
+ @copy "$(LIB_DIR)\$(WEBUI_LIB_NAME).dll" "$(WEBUI_LIB_NAME).dll"
+ @cl main.c /I"$(INCLUDE_DIR)" /link /LIBPATH:"$(LIB_DIR)" /SUBSYSTEM:WINDOWS $(WEBUI_LIB_NAME).lib user32.lib Advapi32.lib Shell32.lib Ole32.lib /OUT:main-dyn.exe 1>NUL 2>&1
+# Clean
+ @- del *.exp >nul 2>&1
+ @- del *.ilk >nul 2>&1
+ @- del *.lib >nul 2>&1
+ @- del *.obj >nul 2>&1
+ @- del *.pdb >nul 2>&1
+ @echo Done.
+
+clean:
+ - del *.obj >nul 2>&1
+ - del *.ilk >nul 2>&1
+ - del *.pdb >nul 2>&1
+ - del *.exp >nul 2>&1
+ - del *.exe >nul 2>&1
+ - del *.lib >nul 2>&1
diff --git a/examples/C/frameless/main.c b/examples/C/frameless/main.c
new file mode 100644
index 0000000..c90a1f1
--- /dev/null
+++ b/examples/C/frameless/main.c
@@ -0,0 +1,130 @@
+// WebUI C - Frameless Example
+
+#include "webui.h"
+
+const char* html =
+""
+" "
+" "
+" "
+" "
+" "
+" "
+" "
+"
"
+"
WebUI Frameless WebView Window "
+"
"
+" "
+" "
+"
"
+"
"
+"
"
+" Welcome to Your WebUI App "
+" This is a stylish, frameless WebUI WebView window. "
+"
"
+"
"
+" "
+"";
+
+void minimize(webui_event_t* e) {
+ webui_minimize(e->window);
+}
+
+void maximize(webui_event_t* e) {
+ webui_maximize(e->window);
+}
+
+void close_win(webui_event_t* e) {
+ webui_close(e->window);
+}
+
+int main() {
+
+ size_t my_window = webui_new_window();
+
+ webui_bind(my_window, "minimize", minimize);
+ webui_bind(my_window, "maximize", maximize);
+ webui_bind(my_window, "close_win", close_win);
+
+ webui_set_size(my_window, 800, 600);
+ webui_set_frameless(my_window, true);
+ webui_set_transparent(my_window, true);
+ webui_set_resizable(my_window, false);
+ webui_set_center(my_window);
+
+ webui_show_wv(my_window, html);
+ webui_wait();
+ return 0;
+}
+
+#if defined(_MSC_VER)
+int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) { return main(); }
+#endif
diff --git a/examples/C/frameless/webui_frameless.png b/examples/C/frameless/webui_frameless.png
new file mode 100644
index 0000000000000000000000000000000000000000..42fa0ad31958ea68cbf38caf430017fd4039bae5
GIT binary patch
literal 297499
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